tidy: remove stale functions / todos from datasette JS plugin proposal

pull/2052/head
Cameron Yick 2023-04-02 16:54:09 -04:00
rodzic c2e7218377
commit 3d48754b90
2 zmienionych plików z 30 dodań i 33 usunięć

Wyświetl plik

@ -1,13 +1,9 @@
// Local dev
// datasette/static/datasette-manager.js
// use quokka run on current file for JS debugging
// Custom events for use with the native CustomEvent API
const DATASETTE_EVENTS = {
INIT: "InitDatasette", // returns datasette manager instance in evt.detail
}
// Datasette "core" -> Methods/APIs that are core
// Datasette "core" -> Methods/APIs that are foundational
// Plugins will have greater stability if they use the functional hooks- but if they do decide to hook into
// literal DOM selectors, they'll have an easier time using these addresses.
const DOM_SELECTORS = {
@ -37,17 +33,13 @@ const DOM_SELECTORS = {
const datasetteManager = {
VERSION: 'TODO_INJECT_VERSION_OR_ENDPOINT_FROM_SERVER_OR_AT_BUILD_TIME',
// Let plugins register. TODO... what should unique identifiers be?
// Name, etc. Should this be a MAP instead of a list?
// Does order of registration matter?
// TODO: Should order of registration matter?
// Should plugins be allowed to clobber others or is it last-in takes priority?
// Does pluginMetadata need to be serializable, or can we let it be stateful / have functions?
// Should we notify plugins that have dependencies
// when all dependencies were fulfilled? (leaflet, codemirror, etc)
// https://github.com/simonw/datasette-leaflet -> this way
// multiple plugins can all request the same copy of leaflet.
plugins: new Map(),
registerPlugin: (name, pluginMetadata) => {
if (datasetteManager.plugins.get(name)) {
console.warn(`Warning -> plugin ${name} was redefined`);
@ -95,7 +87,7 @@ const datasetteManager = {
* Currently, we never destroy any panels, we just hide them.
*
* TODO: nicer panel css, show panel selection state.
* TODO: does this hook need to have any arguments inside?
* TODO: does this hook need to take any arguments?
*/
renderAboveTablePanel: () => {
@ -123,17 +115,18 @@ const datasetteManager = {
const { getAboveTablePanelConfigs: getPanelConfigs } = plugin;
if (getPanelConfigs) {
// TODO: prevent repeats - as backup, select
const controls = aboveTablePanel.querySelector('.tab-controls');
const contents = aboveTablePanel.querySelector('.tab-contents');
// Each plugin could register multiple plugins...
// Each plugin can make multiple panels
const configs = getPanelConfigs();
configs.forEach((config, i) => {
const nodeContentId = `${pluginName}_${config.id}_panel-content`;
// quit if we've already registerd this plugin
// quit if we've already registered this plugin
// TODO: look into whether plugins should be allowed to ask
// parent to re-render, or if they should manage that internally.
if (document.getElementById(nodeContentId)) {
return;
}
@ -179,23 +172,31 @@ const datasetteManager = {
// Provide knowledge of what datasette JS or server-side via traditional console autocomplete
// State helpers: URL params https://github.com/simonw/datasette/issues/1144 and localstorage
// UI Hooks: command + k, tab manager hook
// Should we notify plugins that have dependencies
// when all dependencies were fulfilled? (leaflet, codemirror, etc)
// https://github.com/simonw/datasette-leaflet -> this way
// multiple plugins can all request the same copy of leaflet.
};
/**
* Fire AFTER the document has been parsed
* Initialization... TODO how to make sure this exists BEFORE datasette manager is loaded? */
const initializeDatasette = () => {
// Make Manager available to other plugins
// Hide the global behind __ prefix. Ideally they should be listening for the
// DATASETTE_EVENTS.INIT event to avoid the habit of reading from the window.
window.__DATASETTE__ = datasetteManager;
console.log("Datasette Manager Created!");
console.debug("Datasette Manager Created!");
const initDatasetteEvent = new CustomEvent(DATASETTE_EVENTS.INIT, {
detail: datasetteManager
});
document.dispatchEvent(initDatasetteEvent)
}
// Main function
/**
* Main function
* Fires AFTER the document has been parsed
*/
document.addEventListener("DOMContentLoaded", function () {
initializeDatasette();
});

Wyświetl plik

@ -17,7 +17,7 @@ var DROPDOWN_ICON_SVG = `<svg xmlns="http://www.w3.org/2000/svg" width="14" heig
<path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"></path>
</svg>`;
/** Initialize the Datasette startup! */
/** Main initialization function for Datasette Table interactions */
const initDatasetteTable = function (manager) {
// Feature detection
if (!window.URLSearchParams) {
@ -85,7 +85,6 @@ const initDatasetteTable = function (manager) {
}
});
/** Table header */
function onTableHeaderClick(ev) {
ev.preventDefault();
ev.stopPropagation();
@ -191,8 +190,6 @@ const initDatasetteTable = function (manager) {
// Plugin hook: allow adding JS-based additional menu items
const menuList = menu.querySelector('ul');
// Pass datasette column configs! Record<string,string>
const columnItemConfigs = manager.getColumnHeaderItems({ ...th.dataset });
columnItemConfigs.forEach(itemConfig => {
@ -202,7 +199,6 @@ const initDatasetteTable = function (manager) {
node.remove();
});
// Create new items for each config.
const newLink = document.createElement('a');
newLink.textContent = itemConfig.label;
newLink.href = itemConfig.href ?? '#';
@ -218,10 +214,10 @@ const initDatasetteTable = function (manager) {
}
var dropdownIcon = document.createElement("div");
dropdownIcon.innerHTML = DROPDOWN_ICON_SVG;
dropdownIcon = dropdownIcon.querySelector("*");
dropdownIcon.classList.add("dropdown-menu-icon");
var svg = document.createElement("div");
svg.innerHTML = DROPDOWN_ICON_SVG;
svg = svg.querySelector("*");
svg.classList.add("dropdown-menu-icon");
var menu = document.createElement("div");
menu.innerHTML = DROPDOWN_HTML;
menu = menu.querySelector("*");
@ -234,7 +230,7 @@ const initDatasetteTable = function (manager) {
if (!th.querySelector("a")) {
return;
}
var icon = dropdownIcon.cloneNode(true);
var icon = svg.cloneNode(true);
icon.addEventListener("click", onTableHeaderClick);
th.appendChild(icon);
});
@ -305,7 +301,7 @@ function initAutocompleteForFilterValues(manager) {
});
};
// Main function: registers everything after datasette-manager is done
// Ensures Table UI is initialized only after the Manager is ready.
document.addEventListener("InitDatasette", function (evt) {
const { detail: manager } = evt;