notion-enhancer

an enhancer/customiser for the all-in-one productivity workspace notion.so

API

The notion-enhancer comes with a large set of helpers built-in. These are used internally by the modloader and are made available to simplify common tasks. Where possible, mods must depend on this API to improve mod quality and maintainability.

Type & usage details have been generated from JSDoc comments in the notion-enhancer/api repository and provided below.


components

shared notion-style elements

components.addTooltip {function}

add a tooltip to show extra information on hover @param {HTMLElement}

$ref

- the element that will trigger the tooltip when hovered @param {string|HTMLElement}

$content

- markdown or element content of the tooltip @param? {object}

options

- configuration of how the tooltip should be displayed @param? {number}

options.delay

- the amount of time in ms the element needs to be hovered over for the tooltip to be shown (default: 100) @param? {string}

options.offsetDirection

- which side of the element the tooltip should be shown on: 'top', 'bottom', 'left' or 'right' (default: 'bottom') @param? {number}

options.maxLines

- the max number of lines that the content may be wrapped to, used to position and size the tooltip correctly (default: 1)

components.feather {function}

generate an icon from the feather icons set @param {string}

name

- the name/id of the icon @param {object}

attrs

- an object of attributes to apply to the icon e.g. classes @return {string} an svg string

components.addCornerAction {function}

adds a button to notion's bottom right corner @param {string}

icon

- an svg string @param {function}

listener

- the function to call when the button is clicked @return {Element} the appended corner action element

components.addPanelView {function}

adds a view to the enhancer's side panel @param {object}

panel

- information used to construct and render the panel @param {string}

panel.id

- a uuid, used to restore the last open view on reload @param {string}

panel.icon

- an svg string @param {string}

panel.title

- the name of the view @param {Element}

panel.$content

- an element containing the content of the view @param {function}

panel.onBlur

- runs when the view is selected/focused @param {function}

panel.onFocus

- runs when the view is unfocused/closed

electron

access to electron renderer apis

electron.browser {BrowserWindow}

access to the electron BrowserWindow instance for the current window see https://www.electronjs.org/docs/latest/api/browser-window @process electron (renderer process)

electron.webFrame {webFrame}

access to the electron webFrame instance for the current page see https://www.electronjs.org/docs/latest/api/web-frame @process electron (renderer process)

electron.sendMessage {function}

send a message to the main electron process @param {string}

channel

- the message identifier @param {any}

data

- the data to pass along with the message @param? {string}

namespace

- a prefix for the message to categorise it as e.g. enhancer-related. this should not be changed unless replicating builtin ipc events. @process electron (renderer process)

electron.sendMessageToHost {function}

send a message to the webview's parent renderer process @param {string}

channel

- the message identifier @param {any}

data

- the data to pass along with the message @param? {string}

namespace

- a prefix for the message to categorise it as e.g. enhancer-related. this should not be changed unless replicating builtin ipc events. @process electron (renderer process)

electron.onMessage {function}

receive a message from either the main process or the webview's parent renderer process @param {string}

channel

- the message identifier to listen for @param {function}

callback

- the message handler, passed the args (event, data) @param? {string}

namespace

- a prefix for the message to categorise it as e.g. enhancer-related. this should not be changed unless replicating builtin ipc events. @process electron (renderer process)

electron.notionRequire {function}

require() notion app files @param {string}

path

- within notion/resources/app/ e.g. main/createWindow.js @process electron (main process)

electron.getNotionWindows {function}

get all available app windows excluding the menu @process electron (main process)

electron.getFocusedNotionWindow {function}

get the currently focused notion window @process electron (main process)

env

environment-specific methods and constants

env.name {string}

the environment/platform name code is currently being executed in @constant

env.version {string}

the current version of the enhancer @constant

env.focusMenu {function}

open the enhancer's menu

env.focusNotion {function}

focus an active notion tab

env.reload {function}

reload all notion and enhancer menu tabs to apply changes

fmt

helpers for formatting or parsing text

fmt.slugger {function}

transform a heading into a slug (a lowercase alphanumeric string separated by hyphens), e.g. for use as an anchor id @param {string}

heading

- the original heading to be slugified @param? {Set<string>}

slugs

- a list of pre-generated slugs to avoid duplicates @return {string} the generated slug

fmt.uuidv4 {function}

generate a reasonably random uuidv4 string. uses crypto implementation if available (from https://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid) @return {string} a uuidv4

fmt.rgbLogShade {function}

log-based shading of an rgb color, from https://stackoverflow.com/questions/5560248/programmatically-lighten-or-darken-a-hex-color-or-rgb-and-blend-colors @param {number}

shade

- a decimal amount to shade the color. 1 = white, 0 = the original color, -1 = black @param {string}

color

- the rgb color @return {string} the shaded color

fmt.rgbContrast {function}

pick a contrasting color e.g. for text on a variable color background using the hsp (perceived brightness) constants from http://alienryderflex.com/hsp.html @param {number}

r

- red (0-255) @param {number}

g

- green (0-255) @param {number}

b

- blue (0-255) @return {string} the contrasting rgb color, white or black

fmt.is {function}

test the type of a value. unifies builtin, regex, and environment/api checks @param {unknown}

value

- the value to check @param {string|string[]}

type

- the type the value should be or a list of allowed values @return {boolean} whether or not the value matches the type

fs

environment-specific file reading

fs.notionPath {function}

get an absolute path to files within notion @param {string}

path

- relative to the root notion/resources/app/ e.g. renderer/search.js @process electron

fs.localPath {function}

transform a path relative to the enhancer root directory into an absolute path @param {string}

path

- a url or within-the-enhancer filepath @return {string} an absolute filepath

fs.getJSON {function}

fetch and parse a json file's contents @param {string}

path

- a url or within-the-enhancer filepath @param? {FetchOptions}

opts

- the second argument of a fetch() request @return {unknown} the json value of the requested file as a js object

fs.getText {function}

fetch a text file's contents @param {string}

path

- a url or within-the-enhancer filepath @param? {FetchOptions}

opts

- the second argument of a fetch() request @return {string} the text content of the requested file

fs.isFile {function}

check if a file exists @param {string}

path

- a url or within-the-enhancer filepath @return {boolean} whether or not the file exists

notion

a basic wrapper around notion's content apis

notion.get {function}

unofficial content api: get a block by id (requires user to be signed in or content to be public). why not use the official api? 1. cors blocking prevents use on the client 2. the majority of blocks are still 'unsupported' @param {string}

id

- uuidv4 record id @param? {string}

table

- record type (default: 'block'). may also be 'collection', 'collection_view', 'space', 'notion_user', 'discussion', or 'comment' @return {Promise<object>} record data. type definitions can be found here: https://github.com/NotionX/react-notion-x/tree/master/packages/notion-types/src

notion.getUserID {function}

get the id of the current user (requires user to be signed in) @return {string} uuidv4 user id

notion.getPageID {function}

get the id of the currently open page @return {string} uuidv4 page id

notion.getSpaceID {function}

get the id of the currently open workspace (requires user to be signed in) @return {string} uuidv4 space id

notion.search {function}

unofficial content api: search all blocks in a space (requires user to be signed in or content to be public). why not use the official api? 1. cors blocking prevents use on the client 2. the majority of blocks are still 'unsupported' @param? {string}

query

- query to search blocks in the space for @param? {number}

limit

- the max number of results to return (default: 20) @param? {string}

spaceID

- uuidv4 workspace id @return {object} the number of total results, the list of matches, and related record values. type definitions can be found here: https://github.com/NotionX/react-notion-x/blob/master/packages/notion-types/src/api.ts

notion.set {function}

unofficial content api: update a property/the content of an existing record (requires user to be signed in or content to be public). TEST THIS THOROUGHLY. misuse can corrupt a record, leading the notion client to be unable to parse and render content properly and throw errors. why not use the official api? 1. cors blocking prevents use on the client 2. the majority of blocks are still 'unsupported' @param {object}

pointer

- the record being updated @param {object}

recordValue

- the new raw data values to set to the record. for examples, use notion.get to fetch an existing block record. to use this to update content, set pointer.path to ['properties', 'title] and recordValue to an array of rich text segments. a segment is an array where the first value is the displayed text and the second value is an array of decorations. a decoration is an array where the first value is a modifier and the second value specifies it. e.g. [ ['bold text', [['b']]], [' '], ['an italicised link', [['i'], ['a', 'https://github.com']]], [' '], ['highlighted text', [['h', 'pink_background']]], ] more examples can be creating a block with the desired content/formatting, then find the value of blockRecord.properties.title using notion.get. type definitions can be found here: https://github.com/NotionX/react-notion-x/blob/master/packages/notion-types/src/core.ts @param {string}

pointer.recordID

- uuidv4 record id @param? {string}

pointer.recordTable

- record type (default: 'block'). may also be 'collection', 'collection_view', 'space', 'notion_user', 'discussion', or 'comment' @param? {string}

pointer.property

- the record property to update. for record content, it will be the default: 'title'. for page properties, it will be the property id (the key used in pageRecord.properties). other possible values are unknown/untested @param? {string}

pointer.spaceID

- uuidv4 workspace id @param? {string}

pointer.path

- the path to the key to be set within the record (default: [], the root of the record's values) @return {boolean|object} true if success, else an error object

notion.create {function}

unofficial content api: create and add a new block to a page (requires user to be signed in or content to be public). TEST THIS THOROUGHLY. misuse can corrupt a record, leading the notion client to be unable to parse and render content properly and throw errors. why not use the official api? 1. cors blocking prevents use on the client 2. the majority of blocks are still 'unsupported' @param {object}

insert

- the new record. @param {object}

pointer

- where to insert the new block for examples, use notion.get to fetch an existing block record. type definitions can be found here: https://github.com/NotionX/react-notion-x/blob/master/packages/notion-types/src/block.ts may also be 'collection', 'collection_view', 'space', 'notion_user', 'discussion', or 'comment' @param? {object}

insert.recordValue

- the new raw data values to set to the record. @param? {object}

insert.recordTable

- record type (default: 'block'). may also be 'collection', 'collection_view', 'space', 'notion_user', 'discussion', or 'comment' @param? {string}

pointer.prepend

- insert before pointer.siblingID. if false, will be appended after @param? {string}

pointer.siblingID

- uuidv4 sibling id. if unset, the record will be inserted at the end of the page start (or the start if pointer.prepend is true) @param? {string}

pointer.parentID

- uuidv4 parent id @param? {string}

pointer.parentTable

- parent record type (default: 'block'). @param? {string}

pointer.spaceID

- uuidv4 space id @param? {string}

pointer.userID

- uuidv4 user id instead of the end @return {string|object} error object or uuidv4 of the new record

notion.upload {function}

unofficial content api: upload a file to notion's aws servers (requires user to be signed in or content to be public). TEST THIS THOROUGHLY. misuse can corrupt a record, leading the notion client to be unable to parse and render content properly and throw errors. why not use the official api? 1. cors blocking prevents use on the client 2. the majority of blocks are still 'unsupported' @param {File}

file

- the file to upload @param? {object}

pointer

- where the file should be accessible from @param? {string}

pointer.pageID

- uuidv4 page id @param? {string}

pointer.spaceID

- uuidv4 space id @return {string|object} error object or the url of the uploaded file

notion.sign {function}

redirect through notion to a resource's signed aws url for display outside of notion (requires user to be signed in or content to be public) @param

src

source url for file @param {string}

recordID

uuidv4 record/block/file id @param? {string}

recordTable

record type (default: 'block'). may also be 'collection', 'collection_view', 'space', 'notion_user', 'discussion', or 'comment' @return {string} url signed if necessary, else string as-is

registry

interactions with the enhancer's repository of mods

registry.core {string[]}

mod ids whitelisted as part of the enhancer's core, permanently enabled @constant

registry.supportedEnvs {string[]}

all environments/platforms currently supported by the enhancer @constant

registry.optionTypes {string[]}

all available configuration types @constant

registry.profileName {function}

the name of the active configuration profile @return {string}

registry.profileDB {function}

the root database for the current profile @return {object} the get/set functions for the profile's storage

registry.list {function}

list all available mods in the repo @param {function}

filter

- a function to filter out mods @return {array} a validated list of mod.json objects

registry.errors {function}

list validation errors encountered when loading the repo @return {{ source: string, message: string }

registry.get {function}

get a single mod from the repo @param {string}

id

- the uuid of the mod @return {object} the mod's mod.json

registry.enabled {function}

checks if a mod is enabled: affected by the core whitelist, environment and menu configuration @param {string}

id

- the uuid of the mod @return {boolean} whether or not the mod is enabled

registry.optionDefault {function}

get a default value of a mod's option according to its mod.json @param {string}

id

- the uuid of the mod @param {string}

key

- the key of the option @return {string|number|boolean|undefined} the option's default value

registry.db {function}

access the storage partition of a mod in the current profile @param {string}

id

- the uuid of the mod @return {object} an object with the wrapped get/set functions

storage

environment-specific data persistence

storage.get {function}

get persisted data @param {string[]}

path

- the path of keys to the value being fetched @param? {unknown}

fallback

- a default value if the path is not matched @return {Promise} value ?? fallback

storage.set {function}

persist data @param {string[]}

path

- the path of keys to the value being set @param {unknown}

value

- the data to save @return {Promise} resolves when data has been saved

storage.db {function}

create a wrapper for accessing a partition of the storage @param {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 @return {object} an object with the wrapped get/set functions

storage.addChangeListener {function}

add an event listener for changes in storage @param {onStorageChangeCallback}

callback

- called whenever a change in storage is initiated from the current process

storage.removeChangeListener {function}

remove a listener added with storage.addChangeListener @param {onStorageChangeCallback}

callback

web

helpers for manipulation of a webpage

web.whenReady {function}

wait until a page is loaded and ready for modification @param? {array}

selectors

- wait for the existence of elements that match these css selectors @return {Promise} a promise that will resolve when the page is ready

web.queryParams {function}

parse the current location search params into a usable form @return {Map<string, string>} a map of the url search params

web.escape {function}

replace special html characters with escaped versions @param {string}

str

@return {string} escaped string

web.raw {function}

a tagged template processor for raw html: stringifies, minifies, and syntax highlights @example web.raw`<p>hello</p>` @return {string} the processed html

web.html {function}

create a single html element inc. attributes and children from a string @example web.html`<p>hello</p>` @return {Element} the constructed html element

web.render {function}

appends a list of html elements to a parent @param

$container

- the parent element @param

$elems

- the elements to be appended @return {Element} the updated $container

web.empty {function}

removes all children from an element without deleting them/their behaviours @param

$container

- the parent element @return {Element} the updated $container

web.loadStylesheet {function}

loads/applies a css stylesheet to the page @param {string}

path

- a url or within-the-enhancer filepath

web.copyToClipboard {function}

copy text to the clipboard @param {string}

str

- the string to copy @return {Promise<void>}

web.readFromClipboard {function}

read text from the clipboard @return {Promise<string>}

web.addHotkeyListener {function}

register a hotkey listener to the page @param {array|string}

keys

- the combination of keys that will trigger the hotkey. key codes can be tested at http://keycode.info/ and are case-insensitive. available modifiers are 'alt', 'ctrl', 'meta', and 'shift'. can be provided as a + separated string. @param {function}

callback

- called whenever the keys are pressed @param? {object}

opts

- fine-tuned control over when the hotkey should be triggered @param? {boolean}

opts.listenInInput

- whether the hotkey callback should be triggered when an input is focused @param? {boolean}

opts.keydown

- whether to listen for the hotkey on keydown. by default, hotkeys are triggered by the keyup event.

web.removeHotkeyListener {function}

remove a listener added with web.addHotkeyListener @param {function}

callback

web.addDocumentObserver {function}

add a listener to watch for changes to the dom @param {onDocumentObservedCallback}

callback

@param? {string[]}

selectors

web.removeDocumentObserver {function}

remove a listener added with web.addDocumentObserver @param {onDocumentObservedCallback}

callback

Edit this page