@wordpress/interactivity
Version:
Package that provides a standard and simple way to handle the frontend interactivity of Gutenberg blocks.
61 lines (55 loc) • 2.19 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.initialVdom = exports.init = exports.getRegionRootFragment = void 0;
var _preact = require("preact");
var _vdom = require("./vdom");
var _utils = require("./utils");
var _constants = require("./constants");
/**
* External dependencies
*/
/**
* Internal dependencies
*/
// Keep the same root fragment for each interactive region node.
const regionRootFragments = new WeakMap();
const getRegionRootFragment = region => {
if (!region.parentElement) {
throw Error('The passed region should be an element with a parent.');
}
if (!regionRootFragments.has(region)) {
regionRootFragments.set(region, (0, _utils.createRootFragment)(region.parentElement, region));
}
return regionRootFragments.get(region);
};
// Initial vDOM regions associated with its DOM element.
exports.getRegionRootFragment = getRegionRootFragment;
const initialVdom = exports.initialVdom = new WeakMap();
// Initialize the router with the initial DOM.
const init = async () => {
const nodes = document.querySelectorAll(`[data-${_constants.directivePrefix}-interactive]`);
/*
* This `await` with setTimeout is required to apparently ensure that the interactive blocks have their stores
* fully initialized prior to hydrating the blocks. If this is not present, then an error occurs, for example:
* > view.js:46 Uncaught (in promise) ReferenceError: Cannot access 'state' before initialization
* This occurs when splitTask() is implemented with scheduler.yield() as opposed to setTimeout(), as with the former
* split tasks are added to the front of the task queue whereas with the latter they are added to the end of the queue.
*/
await new Promise(resolve => {
setTimeout(resolve, 0);
});
for (const node of nodes) {
if (!_vdom.hydratedIslands.has(node)) {
await (0, _utils.splitTask)();
const fragment = getRegionRootFragment(node);
const vdom = (0, _vdom.toVdom)(node);
initialVdom.set(node, vdom);
await (0, _utils.splitTask)();
(0, _preact.hydrate)(vdom, fragment);
}
}
};
exports.init = init;
//# sourceMappingURL=init.js.map