@wordpress/interactivity
Version:
Package that provides a standard and simple way to handle the frontend interactivity of Gutenberg blocks.
8 lines (7 loc) • 5.68 kB
Source Map (JSON)
{
"version": 3,
"sources": ["../src/scopes.ts"],
"sourcesContent": ["/**\n * External dependencies\n */\nimport type { h as createElement, RefObject } from 'preact';\nimport { signal } from '@preact/signals';\n\n/**\n * Internal dependencies\n */\nimport { getNamespace } from './namespaces';\nimport { deepReadOnly, deepClone } from './utils';\nimport type { Evaluate } from './hooks';\n\nexport interface Scope {\n\tevaluate: Evaluate;\n\tcontext: object;\n\tserverContext: object;\n\tref: RefObject< HTMLElement >;\n\tattributes: createElement.JSX.HTMLAttributes;\n}\n\n// Store stacks for the current scope and the default namespaces and export APIs\n// to interact with them.\nconst scopeStack: Scope[] = [];\n\nexport const getScope = () => scopeStack.slice( -1 )[ 0 ];\n\nexport const setScope = ( scope: Scope ) => {\n\tscopeStack.push( scope );\n};\nexport const resetScope = () => {\n\tscopeStack.pop();\n};\n\nconst throwNotInScope = ( method: string ) => {\n\tthrow Error(\n\t\t`Cannot call \\`${ method }()\\` when there is no scope. If you are using an async function, please consider using a generator instead. If you are using some sort of async callbacks, like \\`setTimeout\\`, please wrap the callback with \\`withScope(callback)\\`.`\n\t);\n};\n\n/**\n * Retrieves the context inherited by the element evaluating a function from the\n * store. The returned value depends on the element and the namespace where the\n * function calling `getContext()` exists.\n *\n * @param namespace Store namespace. By default, the namespace where the calling\n * function exists is used.\n * @return The context content.\n */\nexport const getContext = < T extends object >( namespace?: string ): T => {\n\tconst scope = getScope();\n\tif ( globalThis.SCRIPT_DEBUG ) {\n\t\tif ( ! scope ) {\n\t\t\tthrowNotInScope( 'getContext' );\n\t\t}\n\t}\n\treturn scope.context[ namespace || getNamespace() ];\n};\n\n/**\n * Retrieves a representation of the element where a function from the store\n * is being evaluated. Such representation is read-only, and contains a\n * reference to the DOM element, its props and a local reactive state.\n *\n * @return Element representation.\n */\nexport const getElement = () => {\n\tconst scope = getScope();\n\tlet deepReadOnlyOptions = {};\n\tif ( globalThis.SCRIPT_DEBUG ) {\n\t\tif ( ! scope ) {\n\t\t\tthrowNotInScope( 'getElement' );\n\t\t}\n\t\tdeepReadOnlyOptions = {\n\t\t\terrorMessage:\n\t\t\t\t\"Don't mutate the attributes from `getElement`, use `data-wp-bind` to modify the attributes of an element instead.\",\n\t\t};\n\t}\n\tconst { ref, attributes } = scope;\n\treturn Object.freeze( {\n\t\tref: ref.current,\n\t\tattributes: deepReadOnly( attributes, deepReadOnlyOptions ),\n\t} );\n};\n\nexport const navigationContextSignal = signal( 0 );\n\n/**\n * Gets the context defined and updated from the server.\n *\n * The object returned is a deep clone of the context defined in PHP with\n * `data-wp-context` directives, including the corresponding inherited\n * properties. When `actions.navigate()` is called, this object is updated to\n * reflect the changes in the new visited page, without affecting the context\n * returned by `getContext()`. Directives can subscribe to those changes to\n * update the context if needed.\n *\n * @example\n * ```js\n * store( 'myPlugin', {\n * callbacks: {\n * updateServerContext() {\n * const context = getContext();\n * const serverContext = getServerContext();\n * // Override some property with the new value that came from the server.\n * context.overridableProp = serverContext.overridableProp;\n * },\n * },\n * } );\n * ```\n *\n * @param namespace Store namespace. By default, it inherits the namespace of\n * the store where it is defined.\n * @return The server context content for the given namespace.\n */\nexport function getServerContext(\n\tnamespace?: string\n): Record< string, unknown >;\nexport function getServerContext< T extends object >( namespace?: string ): T;\nexport function getServerContext< T extends object >( namespace?: string ): T {\n\tconst scope = getScope();\n\n\tif ( globalThis.SCRIPT_DEBUG ) {\n\t\tif ( ! scope ) {\n\t\t\tthrowNotInScope( 'getServerContext' );\n\t\t}\n\t}\n\n\t// Accesses the signal to make this reactive. It assigns it to `subscribe`\n\t// to prevent the JavaScript minifier from removing this line.\n\tgetServerContext.subscribe = navigationContextSignal.value;\n\n\treturn deepClone( scope.serverContext[ namespace || getNamespace() ] );\n}\ngetServerContext.subscribe = 0;\n"],
"mappings": ";AAIA,SAAS,cAAc;AAKvB,SAAS,oBAAoB;AAC7B,SAAS,cAAc,iBAAiB;AAaxC,IAAM,aAAsB,CAAC;AAEtB,IAAM,WAAW,MAAM,WAAW,MAAO,EAAG,EAAG,CAAE;AAEjD,IAAM,WAAW,CAAE,UAAkB;AAC3C,aAAW,KAAM,KAAM;AACxB;AACO,IAAM,aAAa,MAAM;AAC/B,aAAW,IAAI;AAChB;AAEA,IAAM,kBAAkB,CAAE,WAAoB;AAC7C,QAAM;AAAA,IACL,iBAAkB,MAAO;AAAA,EAC1B;AACD;AAWO,IAAM,aAAa,CAAsB,cAA2B;AAC1E,QAAM,QAAQ,SAAS;AACvB,MAAK,WAAW,cAAe;AAC9B,QAAK,CAAE,OAAQ;AACd,sBAAiB,YAAa;AAAA,IAC/B;AAAA,EACD;AACA,SAAO,MAAM,QAAS,aAAa,aAAa,CAAE;AACnD;AASO,IAAM,aAAa,MAAM;AAC/B,QAAM,QAAQ,SAAS;AACvB,MAAI,sBAAsB,CAAC;AAC3B,MAAK,WAAW,cAAe;AAC9B,QAAK,CAAE,OAAQ;AACd,sBAAiB,YAAa;AAAA,IAC/B;AACA,0BAAsB;AAAA,MACrB,cACC;AAAA,IACF;AAAA,EACD;AACA,QAAM,EAAE,KAAK,WAAW,IAAI;AAC5B,SAAO,OAAO,OAAQ;AAAA,IACrB,KAAK,IAAI;AAAA,IACT,YAAY,aAAc,YAAY,mBAAoB;AAAA,EAC3D,CAAE;AACH;AAEO,IAAM,0BAA0B,OAAQ,CAAE;AAkC1C,SAAS,iBAAsC,WAAwB;AAC7E,QAAM,QAAQ,SAAS;AAEvB,MAAK,WAAW,cAAe;AAC9B,QAAK,CAAE,OAAQ;AACd,sBAAiB,kBAAmB;AAAA,IACrC;AAAA,EACD;AAIA,mBAAiB,YAAY,wBAAwB;AAErD,SAAO,UAAW,MAAM,cAAe,aAAa,aAAa,CAAE,CAAE;AACtE;AACA,iBAAiB,YAAY;",
"names": []
}