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
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