Skip to content

Commit

Permalink
Add dangerouslyOpenRealms and dangerouslyCloseRealms methods for …
Browse files Browse the repository at this point in the history
…interoperability.
  • Loading branch information
edoardocavazza committed Nov 20, 2023
1 parent dfe7ae2 commit 48c4b21
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 21 deletions.
5 changes: 5 additions & 0 deletions .changeset/tender-socks-admire.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@chialab/quantum': minor
---

Add `dangerouslyOpenRealms` and `dangerouslyCloseRealms` methods for interoperability.
16 changes: 8 additions & 8 deletions src/Element.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export function extendElement(Element) {
* @param {(ChildNode | string)[]} nodes
*/
value(...nodes) {
const realm = getRealm(this);
const realm = getRealm(this, true);
if (!realm) {
return /** @type {import('./utils.js').ValueDescriptor} */ (append).value.apply(this, nodes);
}
Expand All @@ -43,7 +43,7 @@ export function extendElement(Element) {
* @param {(ChildNode | string)[]} nodes
*/
value(...nodes) {
const realm = getRealm(this);
const realm = getRealm(this, true);
if (!realm) {
return /** @type {import('./utils.js').ValueDescriptor} */ (prepend).value.apply(this, nodes);
}
Expand All @@ -56,7 +56,7 @@ export function extendElement(Element) {
* @this {Element}
*/
value() {
const parentRealm = getParentRealm(this);
const parentRealm = getParentRealm(this, true);
if (!parentRealm) {
return /** @type {import('./utils.js').ValueDescriptor} */ (remove).value.call(this);
}
Expand Down Expand Up @@ -171,7 +171,7 @@ export function extendElement(Element) {
* @param {(ChildNode | string)[]} nodes
*/
value(...nodes) {
const parentRealm = getParentRealm(this);
const parentRealm = getParentRealm(this, true);
if (!parentRealm) {
return /** @type {import('./utils.js').ValueDescriptor} */ (after).value.apply(this, nodes);
}
Expand All @@ -189,7 +189,7 @@ export function extendElement(Element) {
* @param {(ChildNode | string)[]} nodes
*/
value(...nodes) {
const parentRealm = getParentRealm(this);
const parentRealm = getParentRealm(this, true);
if (!parentRealm) {
return /** @type {import('./utils.js').ValueDescriptor} */ (before).value.apply(this, nodes);
}
Expand All @@ -203,7 +203,7 @@ export function extendElement(Element) {
* @param {(ChildNode | string)[]} nodes
*/
value(...nodes) {
const parentRealm = getParentRealm(this);
const parentRealm = getParentRealm(this, true);
if (!parentRealm) {
return /** @type {import('./utils.js').ValueDescriptor} */ (replaceWith).value.apply(this, nodes);
}
Expand All @@ -218,8 +218,8 @@ export function extendElement(Element) {
* @param {ChildNode} node
*/
value(position, node) {
const realm = getRealm(this);
const parentRealm = getParentRealm(this);
const realm = getRealm(this, true);
const parentRealm = getParentRealm(this, true);
switch (position) {
case 'beforebegin':
if (!parentRealm) {
Expand Down
8 changes: 4 additions & 4 deletions src/Node.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export function extendNode(Node) {
* @param {ChildNode} node
*/
value(node) {
const realm = getRealm(this);
const realm = getRealm(this, true);
if (!realm) {
return /** @type {import('./utils.js').ValueDescriptor} */ (appendChild).value.call(this, node);
}
Expand All @@ -43,7 +43,7 @@ export function extendNode(Node) {
* @param {ChildNode} node
*/
value(node) {
const realm = getRealm(this);
const realm = getRealm(this, true);
if (!realm) {
return /** @type {import('./utils.js').ValueDescriptor} */ (removeChild).value.call(this, node);
}
Expand All @@ -58,7 +58,7 @@ export function extendNode(Node) {
* @param {ChildNode} child
*/
value(node, child) {
const realm = getRealm(this);
const realm = getRealm(this, true);
if (!realm) {
return /** @type {import('./utils.js').ValueDescriptor} */ (replaceChild).value.call(this, node, child);
}
Expand All @@ -73,7 +73,7 @@ export function extendNode(Node) {
* @param {ChildNode | null} child
*/
value(node, child) {
const realm = getRealm(this);
const realm = getRealm(this, true);
if (!realm) {
return /** @type {import('./utils.js').ValueDescriptor} */ (insertBefore).value.call(this, node, child);
}
Expand Down
37 changes: 35 additions & 2 deletions src/Realm.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,25 @@
const REALM_SYMBOL = Symbol();
const REALM_PARENT_SYMBOL = Symbol();

/**
* Whether all realms are open.
*/
let opened = false;

/**
* Open all realms.
*/
export function dangerouslyOpenRealms() {
opened = true;
}

/**
* Close all realms.
*/
export function dangerouslyCloseRealms() {
opened = false;
}

/**
* Create and attach a realm for a node.
* @param {HTMLElement & { [REALM_SYMBOL]?: Realm }} node The root node.
Expand All @@ -25,9 +44,16 @@ export function attachRealm(node) {
/**
* Get the realm instance for a node.
* @param {Node & { [REALM_SYMBOL]?: Realm }} node The root node.
* @param {boolean} editMode Whether to return a realm in edit mode.
* @returns {Realm|null} The realm instance or null.
*/
export function getRealm(node) {
export function getRealm(node, editMode = false) {
if (opened) {
if (editMode) {
throw new Error('Cannot get realm in edit mode when all realms are open');
}
return null;
}
const realm = node[REALM_SYMBOL] ?? null;
if (realm && !realm.open) {
return realm;
Expand All @@ -38,9 +64,16 @@ export function getRealm(node) {
/**
* Get the parent realm instance for a node.
* @param {Node & { [REALM_PARENT_SYMBOL]?: Realm }} node The child node.
* @param {boolean} editMode Whether to return a realm in edit mode.
* @returns The parent realm instance or null.
*/
export function getParentRealm(node) {
export function getParentRealm(node, editMode = false) {
if (opened) {
if (editMode) {
throw new Error('Cannot get realm in edit mode when all realms are open');
}
return null;
}
const realm = node[REALM_PARENT_SYMBOL] ?? null;
if (realm && !realm.open) {
return realm;
Expand Down
2 changes: 1 addition & 1 deletion src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ export { extend };
export { extendNode } from './Node.js';
export { extendElement } from './Element.js';
export { extendTreeWalker } from './TreeWalker.js';
export { Realm, attachRealm, getRealm } from './Realm.js';
export { Realm, attachRealm, getRealm, dangerouslyOpenRealms, dangerouslyCloseRealms } from './Realm.js';

if (typeof window !== 'undefined') {
extend(window);
Expand Down
12 changes: 6 additions & 6 deletions tests/react.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ describe('React', () => {
const container = document.createElement('div');
const root = ReactDOM.createRoot(container);
root.render(Template('Text'));
await new Promise((resolve) => setTimeout(resolve, 1));
await new Promise((resolve) => setTimeout(resolve, 10));

const element = container.children[0];
const textNode = element.childNodes[0];
Expand All @@ -25,7 +25,7 @@ describe('React', () => {
);

root.render(Template('Update'));
await new Promise((resolve) => setTimeout(resolve, 1));
await new Promise((resolve) => setTimeout(resolve, 10));

expect(container.childNodes.length).toBe(1);
expect(container.children[0]).toBe(element);
Expand All @@ -41,7 +41,7 @@ describe('React', () => {
const container = document.createElement('div');
const root = ReactDOM.createRoot(container);
root.render(Template('Text'));
await new Promise((resolve) => setTimeout(resolve, 1));
await new Promise((resolve) => setTimeout(resolve, 10));

const element = container.children[0];
const textNode = element.childNodes[0];
Expand All @@ -57,7 +57,7 @@ describe('React', () => {
);

root.render(Template('Update'));
await new Promise((resolve) => setTimeout(resolve, 1));
await new Promise((resolve) => setTimeout(resolve, 10));

expect(container.childNodes.length).toBe(1);
expect(container.children[0]).toBe(element);
Expand All @@ -80,7 +80,7 @@ describe('React', () => {
const container = document.createElement('div');
const root = ReactDOM.createRoot(container);
root.render(Template(true));
await new Promise((resolve) => setTimeout(resolve, 1));
await new Promise((resolve) => setTimeout(resolve, 10));

const element = container.children[0];
const textNode = element.childNodes[0];
Expand All @@ -93,7 +93,7 @@ describe('React', () => {
);

root.render(Template(false));
await new Promise((resolve) => setTimeout(resolve, 1));
await new Promise((resolve) => setTimeout(resolve, 10));

expect(element.childNodes.length).toBe(3);
expect(element.childNodes[0]).toBe(textNode);
Expand Down

0 comments on commit 48c4b21

Please sign in to comment.