: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
* @param name Directive name, without the `data-wp-` prefix.
* @param callback Function that runs the directive logic.
* @param options Options object.
* @param options.priority Option to control the directive execution order. The
* lesser, the highest priority. Default is `10`.
const directive = (name, callback, {
directiveCallbacks[name] = callback;
directivePriorities[name] = priority;
// Resolve the path to some property of the store object.
const resolve = (path, namespace) => {
warn(`Namespace missing for "${path}". The value for that path won't be resolved.`);
let resolvedStore = stores.get(namespace);
if (typeof resolvedStore === 'undefined') {
resolvedStore = store(namespace, undefined, {
context: getScope().context[namespace]
// TODO: Support lazy/dynamically initialized stores
return path.split('.').reduce((acc, key) => acc[key], current);
// Generate the evaluate function.
}) => (entry, ...args) => {
if (typeof path !== 'string') {
throw new Error('The `value` prop should be a string path');
// If path starts with !, remove it and save a flag.
const hasNegationOperator = path[0] === '!' && !!(path = path.slice(1));
const value = resolve(path, namespace);
const result = typeof value === 'function' ? value(...args) : value;
return hasNegationOperator ? !result : result;
// Separate directives by priority. The resulting array contains objects
// of directives grouped by same priority, and sorted in ascending order.
const getPriorityLevels = directives => {
const byPriority = Object.keys(directives).reduce((obj, name) => {
if (directiveCallbacks[name]) {
const priority = directivePriorities[name];
(obj[priority] = obj[priority] || []).push(name);
return Object.entries(byPriority).sort(([p1], [p2]) => parseInt(p1) - parseInt(p2)).map(([, arr]) => arr);
// Component that wraps each priority level of directives of an element.
priorityLevels: [currentPriorityLevel, ...nextPriorityLevels],
// Initialize the scope of this element. These scopes are different per each
// level because each level has a different context, but they share the same
// element ref, state and props.
const scope = hooks_module_F({}).current;
scope.evaluate = hooks_module_x(getEvaluate({
scope.context = hooks_module_P(context);
/* eslint-disable react-hooks/rules-of-hooks */
scope.ref = previousScope?.ref || hooks_module_F(null);
/* eslint-enable react-hooks/rules-of-hooks */
// Create a fresh copy of the vnode element and add the props to the scope,
// named as attributes (HTML Attributes).
scope.attributes = element.props;
// Recursively render the wrapper for the next priority level.
const children = nextPriorityLevels.length > 0 ? _(Directives, {
priorityLevels: nextPriorityLevels,
for (const directiveName of currentPriorityLevel) {
const wrapper = directiveCallbacks[directiveName]?.(directiveArgs);
if (wrapper !== undefined) {
props.children = wrapper;
// Preact Options Hook called each time a vnode is created.
const old = preact_module_l.vnode;
preact_module_l.vnode = vnode => {
if (vnode.props.__directives) {
const props = vnode.props;
const directives = props.__directives;
vnode.key = directives.key.find(({
}) => suffix === 'default').value;
delete props.__directives;
const priorityLevels = getPriorityLevels(directives);
if (priorityLevels.length > 0) {
element: _(vnode.type, props),
;// CONCATENATED MODULE: ./node_modules/@wordpress/interactivity/build-module/utils.js
* Executes a callback function after the next frame is rendered.
* @param callback The callback function to be executed.
* @return A promise that resolves after the callback function is executed.
const afterNextFrame = callback => {
return new Promise(resolve => {
window.cancelAnimationFrame(raf);
const timeout = setTimeout(done, 100);
const raf = window.requestAnimationFrame(done);
* Returns a promise that resolves after yielding to main.
const splitTask = () => {
return new Promise(resolve => {
// TODO: Use scheduler.yield() when available.
* Creates a Flusher object that can be used to flush computed values and notify listeners.
* Using the mangled properties:
* https://github.com/preactjs/signals/blob/main/mangle.json
* @param compute The function that computes the value to be flushed.
* @param notify The function that notifies listeners when the value is flushed.
* @return The Flusher object with `flush` and `dispose` properties.
function createFlusher(compute, notify) {
let flush = () => undefined;
const dispose = signals_core_module_E(function () {
flush = this.c.bind(this);
* Custom hook that executes a callback function whenever a signal is triggered.
* Version of `useSignalEffect` with a `useEffect`-like execution. This hook
* implementation comes from this PR, but we added short-cirtuiting to avoid
* infinite loops: https://github.com/preactjs/signals/pull/290
* @param callback The callback function to be executed.
function utils_useSignalEffect(callback) {
const notify = async () => {
if (eff && !isExecuting) {
await afterNextFrame(eff.flush);
eff = createFlusher(callback, notify);
* Returns the passed function wrapped with the current scope so it is
* accessible whenever the function runs. This is primarily to make the scope
* available inside hook callbacks.
* Asyncronous functions should use generators that yield promises instead of awaiting them.
* See the documentation for details: https://developer.wordpress.org/block-editor/reference-guides/packages/packages-interactivity/packages-interactivity-api-reference/#the-store
* @param func The passed function.
* @return The wrapped function.
function withScope(func) {
const scope = getScope();
const ns = getNamespace();
if (func?.constructor?.name === 'GeneratorFunction') {
return async (...args) => {
const gen = func(...args);
* Accepts a function that contains imperative code which runs whenever any of
* the accessed _reactive_ properties (e.g., values from the global state or the
* This hook makes the element's scope available so functions like
* `getElement()` and `getContext()` can be used inside the passed callback.
* @param callback The hook callback.
function useWatch(callback) {
utils_useSignalEffect(withScope(callback));
* Accepts a function that contains imperative code which runs only after the
* element's first render, mainly useful for intialization logic.
* This hook makes the element's scope available so functions like
* `getElement()` and `getContext()` can be used inside the passed callback.
* @param callback The hook callback.
function useInit(callback) {
hooks_module_(withScope(callback), []);
* Accepts a function that contains imperative, possibly effectful code. The
* effects run after browser paint, without blocking it.
* This hook is equivalent to Preact's `useEffect` and makes the element's scope
* available so functions like `getElement()` and `getContext()` can be used
* inside the passed callback.
* @param callback Imperative function that can return a cleanup
* @param inputs If present, effect will only activate if the
* values in the list change (using `===`).
function useEffect(callback, inputs) {
hooks_module_(withScope(callback), inputs);
* Accepts a function that contains imperative, possibly effectful code. Use
* this to read layout from the DOM and synchronously re-render.
* This hook is equivalent to Preact's `useLayoutEffect` and makes the element's
* scope available so functions like `getElement()` and `getContext()` can be
* used inside the passed callback.
* @param callback Imperative function that can return a cleanup
* @param inputs If present, effect will only activate if the
* values in the list change (using `===`).
function useLayoutEffect(callback, inputs) {
hooks_module_A(withScope(callback), inputs);
* Returns a memoized version of the callback that only changes if one of the
* inputs has changed (using `===`).
* This hook is equivalent to Preact's `useCallback` and makes the element's
* scope available so functions like `getElement()` and `getContext()` can be
* used inside the passed callback.
* @param callback Callback function.
* @param inputs If present, the callback will only be updated if the
* values in the list change (using `===`).
* @return The callback function.
function useCallback(callback, inputs) {
return hooks_module_x(withScope(callback), inputs);
* Pass a factory function and an array of inputs. `useMemo` will only recompute
* the memoized value when one of the inputs has changed.
* This hook is equivalent to Preact's `useMemo` and makes the element's scope
* available so functions like `getElement()` and `getContext()` can be used
* inside the passed factory function.
* @param factory Factory function that returns that value for memoization.
* @param inputs If present, the factory will only be run to recompute if
* the values in the list change (using `===`).
* @return The memoized value.
function useMemo(factory, inputs) {
return hooks_module_q(withScope(factory), inputs);
* Creates a root fragment by replacing a node or an array of nodes in a parent element.
* For wrapperless hydration.
* See https://gist.github.com/developit/f4c67a2ede71dc2fab7f357f39cff28c
* @param parent The parent element where the nodes will be replaced.
* @param replaceNode The node or array of nodes to replace in the parent element.
* @return The created root fragment.
const createRootFragment = (parent, replaceNode) => {
replaceNode = [].concat(replaceNode);
const sibling = replaceNode[replaceNode.length - 1].nextSibling;
function insert(child, root) {
parent.insertBefore(child, root || sibling);
firstChild: replaceNode[0],
* Transforms a kebab-case string to camelCase.
* @param str The kebab-case string to transform to camelCase.
* @return The transformed camelCase string.
function kebabToCamelCase(str) {
return str.replace(/^-+|-+$/g, '').toLowerCase().replace(/-([a-z])/g, function (_match, group1) {
return group1.toUpperCase();
const logged = new Set();
* Shows a warning with `message` if environment is not `production`.
* Based on the `@wordpress/warning` package.
* @param message Message to show in the warning.
const warn = message => {
if (logged.has(message)) {
// eslint-disable-next-line no-console
// Throwing an error and catching it immediately to improve debugging
// A consumer can use 'pause on caught exceptions'
;// CONCATENATED MODULE: ./node_modules/@wordpress/interactivity/build-module/directives.js
// eslint-disable-next-line eslint-comments/disable-enable-pair
/* eslint-disable react-hooks/exhaustive-deps */
// Assigned objects should be ignored during proxification.
const contextAssignedObjects = new WeakMap();
// Store the context proxy and fallback for each object in the context.
const contextObjectToProxy = new WeakMap();
const contextProxyToObject = new WeakMap();
const contextObjectToFallback = new WeakMap();
const isPlainObject = item => Boolean(item && typeof item === 'object' && item.constructor === Object);
const descriptor = Reflect.getOwnPropertyDescriptor;
* Wrap a context object with a proxy to reproduce the context stack. The proxy
* uses the passed `inherited` context as a fallback to look up for properties
* that don't exist in the given context. Also, updated properties are modified