mirror of
https://github.com/notion-enhancer/notion-enhancer.git
synced 2025-04-07 22:19:02 +00:00
replace hook with pseudo-mod, env folder = simpler documentation
This commit is contained in:
parent
a7549cd9db
commit
33e8907d4f
extension
api
env.mjsenv
launcher.jsmanifest.jsonrepo
components@36a2ffc9-27ff-480e-84a7-c7700a7d232d
menu@a6621988-551d-495a-97d8-3c568bca2e9e
@ -9,18 +9,17 @@
|
||||
/** @module notion-enhancer/api */
|
||||
|
||||
/** environment-specific methods and constants */
|
||||
import * as env from './env.mjs';
|
||||
|
||||
export * as env from './env.mjs';
|
||||
/** environment-specific filesystem reading */
|
||||
const fs = env.name === 'extension' ? await import('./extension-fs.mjs') : {};
|
||||
export * as fs from './fs.mjs';
|
||||
/** environment-specific data persistence */
|
||||
const storage = env.name === 'extension' ? await import('./extension-storage.mjs') : {};
|
||||
export * as storage from './storage.mjs';
|
||||
|
||||
/** helpers for formatting, validating and parsing values */
|
||||
import * as fmt from './fmt.mjs';
|
||||
export * as fmt from './fmt.mjs';
|
||||
/** interactions with the enhancer's repository of mods */
|
||||
import * as registry from './registry.mjs';
|
||||
export * as registry from './registry.mjs';
|
||||
/** helpers for manipulation of a webpage */
|
||||
import * as web from './web.mjs';
|
||||
|
||||
export { env, fs, storage, fmt, registry, web };
|
||||
export * as web from './web.mjs';
|
||||
/** notion-style elements inc. the sidebar */
|
||||
export * as components from './components/_.mjs';
|
||||
|
21
extension/api/components/_.mjs
Normal file
21
extension/api/components/_.mjs
Normal file
@ -0,0 +1,21 @@
|
||||
/*
|
||||
* notion-enhancer: api
|
||||
* (c) 2021 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
|
||||
* (https://notion-enhancer.github.io/) under the MIT license
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* notion-style elements inc. the sidebar
|
||||
* @module notion-enhancer/api/components
|
||||
*/
|
||||
|
||||
/**
|
||||
* add a tooltip to show extra information on hover
|
||||
* @param {HTMLElement} $ref - the element that will trigger the tooltip when hovered
|
||||
* @param {string} text - the markdown content of the tooltip
|
||||
*/
|
||||
export { tooltip } from './tooltip.mjs';
|
||||
|
||||
export { side } from './tooltip.mjs';
|
24
extension/api/components/sidebar.mjs
Normal file
24
extension/api/components/sidebar.mjs
Normal file
@ -0,0 +1,24 @@
|
||||
/*
|
||||
* notion-enhancer: api
|
||||
* (c) 2021 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
|
||||
* (https://notion-enhancer.github.io/) under the MIT license
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* notion-style elements inc. the sidebar
|
||||
* @module notion-enhancer/api/components/side-panel
|
||||
*/
|
||||
|
||||
import { web } from '../_.mjs';
|
||||
|
||||
let _$sidebar;
|
||||
|
||||
export const sidebar = (icon, name, loader = ($panel) => {}) => {
|
||||
if (!_$sidebar) {
|
||||
web.loadStylesheet('api/components/sidebar.css');
|
||||
_$sidebar = web.html`<div id="enhancer--sidebar"></div>`;
|
||||
web.render(document.body, _$sidebar);
|
||||
}
|
||||
};
|
41
extension/api/components/tooltip.mjs
Normal file
41
extension/api/components/tooltip.mjs
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* notion-enhancer: api
|
||||
* (c) 2021 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
|
||||
* (https://notion-enhancer.github.io/) under the MIT license
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* notion-style elements inc. the sidebar
|
||||
* @module notion-enhancer/api/components/tooltip
|
||||
*/
|
||||
|
||||
import { fmt, web } from '../_.mjs';
|
||||
|
||||
let _$tooltip;
|
||||
|
||||
/**
|
||||
* add a tooltip to show extra information on hover
|
||||
* @param {HTMLElement} $ref - the element that will trigger the tooltip when hovered
|
||||
* @param {string} text - the markdown content of the tooltip
|
||||
*/
|
||||
export const tooltip = ($ref, text) => {
|
||||
if (!_$tooltip) {
|
||||
web.loadStylesheet('api/components/tooltip.css');
|
||||
_$tooltip = web.html`<div id="enhancer--tooltip"></div>`;
|
||||
web.render(document.body, _$tooltip);
|
||||
}
|
||||
text = fmt.md.render(text);
|
||||
$ref.addEventListener('mouseover', (event) => {
|
||||
_$tooltip.innerHTML = text;
|
||||
_$tooltip.style.display = 'block';
|
||||
});
|
||||
$ref.addEventListener('mousemove', (event) => {
|
||||
_$tooltip.style.top = event.clientY - _$tooltip.clientHeight + 'px';
|
||||
_$tooltip.style.left = event.clientX - _$tooltip.clientWidth + 'px';
|
||||
});
|
||||
$ref.addEventListener('mouseout', (event) => {
|
||||
_$tooltip.style.display = '';
|
||||
});
|
||||
};
|
@ -11,7 +11,7 @@
|
||||
* @module notion-enhancer/api/env
|
||||
*/
|
||||
|
||||
import env from '../env.mjs';
|
||||
import * as env from '../env/env.mjs';
|
||||
|
||||
/**
|
||||
* the environment/platform name code is currently being executed in
|
||||
|
46
extension/api/fs.mjs
Normal file
46
extension/api/fs.mjs
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* notion-enhancer: api
|
||||
* (c) 2021 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
|
||||
* (https://notion-enhancer.github.io/) under the MIT license
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* environment-specific filesystem reading
|
||||
* @module notion-enhancer/api/fs
|
||||
*/
|
||||
|
||||
import * as fs from '../env/fs.mjs';
|
||||
|
||||
/**
|
||||
* transform a path relative to the enhancer root directory into an absolute path
|
||||
* @type {function}
|
||||
* @param {string} path - a url or within-the-enhancer filepath
|
||||
* @returns {string} an absolute filepath
|
||||
*/
|
||||
export const localPath = fs.localPath;
|
||||
|
||||
/**
|
||||
* fetch and parse a json file's contents
|
||||
* @type {function}
|
||||
* @param {string} path - a url or within-the-enhancer filepath
|
||||
* @returns {object} the json value of the requested file as a js object
|
||||
*/
|
||||
export const getJSON = fs.getJSON;
|
||||
|
||||
/**
|
||||
* fetch a text file's contents
|
||||
* @type {function}
|
||||
* @param {string} path - a url or within-the-enhancer filepath
|
||||
* @returns {string} the text content of the requested file
|
||||
*/
|
||||
export const getText = fs.getText;
|
||||
|
||||
/**
|
||||
* check if a file exists
|
||||
* @type {function}
|
||||
* @param {string} path - a url or within-the-enhancer filepath
|
||||
* @returns {boolean} whether or not the file exists
|
||||
*/
|
||||
export const isFile = fs.isFile;
|
@ -148,22 +148,6 @@ const check = async (
|
||||
});
|
||||
tests.push(test);
|
||||
}
|
||||
if (mod.js.hook) {
|
||||
if (mod.tags.includes('core')) {
|
||||
const test = check(mod, 'js.hook', mod.js.hook, 'file', {
|
||||
extension: '.mjs',
|
||||
});
|
||||
tests.push(test);
|
||||
} else {
|
||||
registry._errors.push({
|
||||
source: mod._dir,
|
||||
message: `js.hook (only core mods can register hooks): ${JSON.stringify(
|
||||
mod.tags
|
||||
)}`,
|
||||
});
|
||||
tests.push(false);
|
||||
}
|
||||
}
|
||||
return tests;
|
||||
});
|
||||
},
|
||||
|
67
extension/api/storage.mjs
Normal file
67
extension/api/storage.mjs
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* notion-enhancer: api
|
||||
* (c) 2021 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
|
||||
* (https://notion-enhancer.github.io/) under the MIT license
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* environment-specific data persistence
|
||||
* @module notion-enhancer/api/storage
|
||||
*/
|
||||
|
||||
import * as storage from '../env/storage.mjs';
|
||||
|
||||
/**
|
||||
* get persisted data
|
||||
* @type {function}
|
||||
* @param {array<string>} path - the path of keys to the value being fetched
|
||||
* @param {*} [fallback] - a default value if the path is not matched
|
||||
* @returns {Promise} value ?? fallback
|
||||
*/
|
||||
export const get = storage.get;
|
||||
|
||||
/**
|
||||
* persist data
|
||||
* @type {function}
|
||||
* @param {array<string>} path - the path of keys to the value being set
|
||||
* @param {*} value - the data to save
|
||||
* @returns {Promise} resolves when data has been saved
|
||||
*/
|
||||
export const set = storage.set;
|
||||
|
||||
/**
|
||||
* create a wrapper for accessing a partition of the storage
|
||||
* @type {function}
|
||||
* @param {array<string>} namespace - the path of keys to prefix all storage requests with
|
||||
* @param {function} [get] - the storage get function to be wrapped
|
||||
* @param {function} [set] - the storage set function to be wrapped
|
||||
* @returns {object} an object with the wrapped get/set functions
|
||||
*/
|
||||
export const db = storage.db;
|
||||
|
||||
/**
|
||||
* add an event listener for changes in storage
|
||||
* @type {function}
|
||||
* @param {onStorageChangeCallback} callback - called whenever a change in
|
||||
* storage is initiated from the current process
|
||||
*/
|
||||
export const addChangeListener = storage.addChangeListener;
|
||||
|
||||
/**
|
||||
* remove a listener added with storage.addChangeListener
|
||||
* @type {function}
|
||||
* @param {onStorageChangeCallback} callback
|
||||
*/
|
||||
export const removeChangeListener = storage.removeChangeListener;
|
||||
|
||||
/**
|
||||
* @callback onStorageChangeCallback
|
||||
* @param {object} event
|
||||
* @param {string} event.type - 'set' or 'reset'
|
||||
* @param {string} event.namespace- the name of the store, e.g. a mod id
|
||||
* @param {string} [event.key] - the key associated with the changed value
|
||||
* @param {string} [event.new] - the new value being persisted to the store
|
||||
* @param {string} [event.old] - the previous value associated with the key
|
||||
*/
|
@ -1,24 +0,0 @@
|
||||
/*
|
||||
* notion-enhancer: api
|
||||
* (c) 2021 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
|
||||
* (https://notion-enhancer.github.io/) under the MIT license
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* environment-specific methods and constants
|
||||
* @module notion-enhancer/api/env
|
||||
*/
|
||||
|
||||
const focusMenu = () => chrome.runtime.sendMessage({ action: 'focusMenu' }),
|
||||
focusNotion = () => chrome.runtime.sendMessage({ action: 'focusNotion' }),
|
||||
reload = () => chrome.runtime.sendMessage({ action: 'reload' });
|
||||
|
||||
export default {
|
||||
name: 'extension',
|
||||
version: chrome.runtime.getManifest().version,
|
||||
focusMenu,
|
||||
focusNotion,
|
||||
reload,
|
||||
};
|
44
extension/env/env.mjs
vendored
Normal file
44
extension/env/env.mjs
vendored
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* notion-enhancer: api
|
||||
* (c) 2021 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
|
||||
* (https://notion-enhancer.github.io/) under the MIT license
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* environment-specific methods and constants
|
||||
* @module notion-enhancer/api/env
|
||||
*/
|
||||
|
||||
/**
|
||||
* the environment/platform name code is currently being executed in
|
||||
* @constant
|
||||
* @type {string}
|
||||
*/
|
||||
export const name = 'extension';
|
||||
|
||||
/**
|
||||
* the current version of the enhancer
|
||||
* @constant
|
||||
* @type {string}
|
||||
*/
|
||||
export const version = chrome.runtime.getManifest().version;
|
||||
|
||||
/**
|
||||
* open the enhancer's menu
|
||||
* @type {function}
|
||||
*/
|
||||
export const focusMenu = () => chrome.runtime.sendMessage({ action: 'focusMenu' });
|
||||
|
||||
/**
|
||||
* focus an active notion tab
|
||||
* @type {function}
|
||||
*/
|
||||
export const focusNotion = () => chrome.runtime.sendMessage({ action: 'focusNotion' });
|
||||
|
||||
/**
|
||||
* reload all notion and enhancer menu tabs to apply changes
|
||||
* @type {function}
|
||||
*/
|
||||
export const reload = () => chrome.runtime.sendMessage({ action: 'reload' });
|
@ -13,28 +13,16 @@
|
||||
page = location.pathname.split(/[/-]/g).reverse()[0].length === 32;
|
||||
|
||||
if (site || page) {
|
||||
import(chrome.runtime.getURL('api/_.mjs')).then(async ({ ...api }) => {
|
||||
const { fs, registry, web } = api,
|
||||
insert = async (mod) => {
|
||||
for (const sheet of mod.css?.client || []) {
|
||||
web.loadStylesheet(`repo/${mod._dir}/${sheet}`);
|
||||
}
|
||||
for (let script of mod.js?.client || []) {
|
||||
script = await import(fs.localPath(`repo/${mod._dir}/${script}`));
|
||||
script.default(api, await registry.db(mod.id));
|
||||
}
|
||||
return true;
|
||||
};
|
||||
for (const mod of await registry.list((mod) => registry.core.includes(mod.id))) {
|
||||
if (mod.js?.hook) {
|
||||
let script = mod.js.hook;
|
||||
script = await import(fs.localPath(`repo/${mod._dir}/${script}`));
|
||||
api[mod.name] = await script.default(api, await registry.db(mod.id));
|
||||
}
|
||||
await insert(mod);
|
||||
}
|
||||
import(chrome.runtime.getURL('api/_.mjs')).then(async (api) => {
|
||||
const { fs, registry, web } = api;
|
||||
for (const mod of await registry.list((mod) => registry.enabled(mod.id))) {
|
||||
if (!registry.core.includes(mod.id)) await insert(mod);
|
||||
for (const sheet of mod.css?.client || []) {
|
||||
web.loadStylesheet(`repo/${mod._dir}/${sheet}`);
|
||||
}
|
||||
for (let script of mod.js?.client || []) {
|
||||
script = await import(fs.localPath(`repo/${mod._dir}/${script}`));
|
||||
script.default(api, await registry.db(mod.id));
|
||||
}
|
||||
}
|
||||
const errors = await registry.errors();
|
||||
if (errors.length) {
|
||||
|
@ -19,7 +19,7 @@
|
||||
"page": "repo/menu@a6621988-551d-495a-97d8-3c568bca2e9e/menu.html",
|
||||
"open_in_tab": true
|
||||
},
|
||||
"web_accessible_resources": ["env.mjs", "api/*", "dep/*", "icon/*", "repo/*"],
|
||||
"web_accessible_resources": ["env/*", "api/*", "dep/*", "icon/*", "repo/*"],
|
||||
"content_scripts": [
|
||||
{
|
||||
"matches": ["https://*.notion.so/*", "https://*.notion.site/*"],
|
||||
|
@ -1,38 +0,0 @@
|
||||
/*
|
||||
* notion-enhancer core: components
|
||||
* (c) 2021 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
|
||||
* (c) 2021 CloudHill <rl.cloudhill@gmail.com> (https://github.com/CloudHill)
|
||||
* (https://notion-enhancer.github.io/) under the MIT license
|
||||
*/
|
||||
|
||||
let _$tooltip;
|
||||
|
||||
export default function (api, db) {
|
||||
const { web, fmt } = api;
|
||||
|
||||
return {
|
||||
/**
|
||||
* add a tooltip to show extra information on hover
|
||||
* @param {HTMLElement} $ref - the element that will trigger the tooltip when hovered
|
||||
* @param {string} text - the markdown content of the tooltip
|
||||
*/
|
||||
tooltip: ($ref, text) => {
|
||||
if (!_$tooltip) {
|
||||
_$tooltip = web.html`<div id="enhancer--tooltip"></div>`;
|
||||
web.render(document.body, _$tooltip);
|
||||
}
|
||||
text = fmt.md.render(text);
|
||||
$ref.addEventListener('mouseover', (event) => {
|
||||
_$tooltip.innerHTML = text;
|
||||
_$tooltip.style.display = 'block';
|
||||
});
|
||||
$ref.addEventListener('mousemove', (event) => {
|
||||
_$tooltip.style.top = event.clientY - _$tooltip.clientHeight + 'px';
|
||||
_$tooltip.style.left = event.clientX - _$tooltip.clientWidth + 'px';
|
||||
});
|
||||
$ref.addEventListener('mouseout', (event) => {
|
||||
_$tooltip.style.display = '';
|
||||
});
|
||||
},
|
||||
};
|
||||
}
|
@ -1,8 +1,9 @@
|
||||
{
|
||||
"__comment": "pseudo-mod to allow configuration of API-provided components",
|
||||
"name": "components",
|
||||
"id": "36a2ffc9-27ff-480e-84a7-c7700a7d232d",
|
||||
"version": "0.2.0",
|
||||
"description": "notion-style elements reuseable by other mods, inc. tooltips and the side panel.",
|
||||
"description": "notion-style elements reused by other mods, inc. the sidebar.",
|
||||
"tags": ["core"],
|
||||
"authors": [
|
||||
{
|
||||
@ -18,21 +19,15 @@
|
||||
"avatar": "https://avatars.githubusercontent.com/u/54142180"
|
||||
}
|
||||
],
|
||||
"js": {
|
||||
"hook": "hook.mjs"
|
||||
},
|
||||
"css": {
|
||||
"client": ["tooltip.css", "sidebar.css"],
|
||||
"menu": ["tooltip.css"],
|
||||
"frame": ["tooltip.css"]
|
||||
},
|
||||
"js": {},
|
||||
"css": {},
|
||||
"options": [
|
||||
{
|
||||
"type": "hotkey",
|
||||
"key": "side-panel-hotkey",
|
||||
"label": "toggle side panel hotkey",
|
||||
"label": "toggle enhancer sidebar hotkey",
|
||||
"value": "Ctrl+Alt+\\",
|
||||
"tooltip": "opens the side panel in notion - will only work if a mod is making use of it."
|
||||
"tooltip": "opens/closes the extra sidebar in notion - will only work if a mod is making use of it."
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -6,9 +6,9 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
import { api, profileDB } from './loader.mjs';
|
||||
import { fmt, web, registry, components } from '../../api/_.mjs';
|
||||
import { notifications } from './notifications.mjs';
|
||||
const { fmt, web, components } = api;
|
||||
const profileDB = await registry.profileDB();
|
||||
|
||||
export const blocks = {
|
||||
preview: (url) => web.html`<img
|
||||
|
@ -1,32 +0,0 @@
|
||||
/*
|
||||
* notion-enhancer core: menu
|
||||
* (c) 2021 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
|
||||
* (https://notion-enhancer.github.io/) under the MIT license
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import * as _api from '../../api/_.mjs';
|
||||
export const api = { ..._api },
|
||||
{ fs, registry, web } = api;
|
||||
|
||||
export const db = await registry.db('a6621988-551d-495a-97d8-3c568bca2e9e'),
|
||||
profileName = await registry.profileName(),
|
||||
profileDB = await registry.profileDB();
|
||||
|
||||
const insert = (mod) => {
|
||||
for (const sheet of mod.css?.menu || []) {
|
||||
web.loadStylesheet(`repo/${mod._dir}/${sheet}`);
|
||||
}
|
||||
};
|
||||
for (const mod of await registry.list((mod) => registry.core.includes(mod.id))) {
|
||||
if (mod.js?.hook) {
|
||||
let script = mod.js.hook;
|
||||
script = await import(fs.localPath(`repo/${mod._dir}/${script}`));
|
||||
api[mod.name] = await script.default(api, await registry.db(mod.id));
|
||||
}
|
||||
await insert(mod);
|
||||
}
|
||||
for (const mod of await registry.list((mod) => registry.enabled(mod.id))) {
|
||||
if (!registry.core.includes(mod.id)) await insert(mod);
|
||||
}
|
@ -6,11 +6,20 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
import { api, db, profileName, profileDB } from './loader.mjs';
|
||||
import './styles.mjs';
|
||||
import { env, fs, storage, registry, web } from '../../api/_.mjs';
|
||||
import { notifications } from './notifications.mjs';
|
||||
import { blocks, options } from './blocks.mjs';
|
||||
const { env, fs, storage, registry, web } = api;
|
||||
import './styles.mjs';
|
||||
|
||||
const db = await registry.db('a6621988-551d-495a-97d8-3c568bca2e9e'),
|
||||
profileName = await registry.profileName(),
|
||||
profileDB = await registry.profileDB();
|
||||
|
||||
for (const mod of await registry.list((mod) => registry.enabled(mod.id))) {
|
||||
for (const sheet of mod.css?.menu || []) {
|
||||
web.loadStylesheet(`repo/${mod._dir}/${sheet}`);
|
||||
}
|
||||
}
|
||||
|
||||
web.addHotkeyListener(await db.get(['hotkey']), env.focusNotion);
|
||||
|
||||
|
@ -6,9 +6,8 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
import { api } from './loader.mjs';
|
||||
import { env, fs, storage, fmt, registry, web } from '../../api/_.mjs';
|
||||
import { tw } from './styles.mjs';
|
||||
const { env, fs, storage, fmt, registry, web } = api;
|
||||
|
||||
export const notifications = {
|
||||
$container: web.html`<div class="notifications-container"></div>`,
|
||||
|
@ -6,8 +6,7 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
import { api } from './loader.mjs';
|
||||
const { web } = api;
|
||||
import { web } from '../../api/_.mjs';
|
||||
|
||||
let _defaultView = '';
|
||||
const _views = new Map();
|
||||
|
Loading…
Reference in New Issue
Block a user