Skip to content

Commit

Permalink
Simplify handling value nodes (#20)
Browse files Browse the repository at this point in the history
* Simplify handling value nodes

* Improve naming
  • Loading branch information
joeldrapper authored Mar 8, 2024
1 parent 770a4c1 commit 16ff5af
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 55 deletions.
27 changes: 10 additions & 17 deletions dist/morphlex.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 13 additions & 13 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"test:watch": "npm run test -- --watch",
"lint": "prettier --check ./src ./dist ./test",
"minify": "terser dist/morphlex.js -o dist/morphlex.min.js --config-file terser-config.json",
"prepare": "npm update && npm run build && npm run minify",
"prepare": "npm run build && npm run minify",
"ship": "npm run prepare && npm run test && npm run lint && npm publish",
"format": "prettier --write ./src ./dist ./test",
"size": "npm run prepare && gzip-size ./dist/morphlex.min.js --raw --include-original"
Expand Down
33 changes: 10 additions & 23 deletions src/morphlex.ts
Original file line number Diff line number Diff line change
Expand Up @@ -179,19 +179,18 @@ class Morph {
if (isElement(node) && isElement(ref) && node.localName === ref.localName) {
if (node.hasAttributes() || ref.hasAttributes()) this.#morphAttributes(node, ref);
if (isHead(node) && isHead(ref)) {
const refChildNodes: Map<string, ReadonlyNode<Element>> = new Map();
for (const child of ref.children) refChildNodes.set(child.outerHTML, child);
const refChildNodesMap: Map<string, ReadonlyNode<Element>> = new Map();
for (const child of ref.children) refChildNodesMap.set(child.outerHTML, child);
for (const child of node.children) {
const key = child.outerHTML;
const refChild = refChildNodes.get(key);
refChild ? refChildNodes.delete(key) : this.#removeNode(child);
const refChild = refChildNodesMap.get(key);
refChild ? refChildNodesMap.delete(key) : this.#removeNode(child);
}
for (const refChild of refChildNodes.values()) this.#appendChild(node, refChild.cloneNode(true));
for (const refChild of refChildNodesMap.values()) this.#appendChild(node, refChild.cloneNode(true));
} else if (node.hasChildNodes() || ref.hasChildNodes()) this.#morphChildNodes(node, ref);
} else {
if (isText(node) && isText(ref)) {
this.#updateProperty(node, "textContent", ref.textContent);
} else if (isComment(node) && isComment(ref)) {
if (node.nodeType === ref.nodeType && node.nodeValue !== null && ref.nodeValue !== null) {
// Handle text nodes, comments, and CDATA sections.
this.#updateProperty(node, "nodeValue", ref.nodeValue);
} else this.#replaceNode(node, ref.cloneNode(true));
}
Expand Down Expand Up @@ -239,8 +238,8 @@ class Morph {
else if (isTextArea(element) && isTextArea(ref)) {
this.#updateProperty(element, "value", ref.value);

const text = element.firstChild;
if (text && isText(text)) this.#updateProperty(text, "textContent", ref.value);
const text = element.firstElementChild;
if (text) this.#updateProperty(text, "textContent", ref.value);
}
}

Expand All @@ -255,7 +254,7 @@ class Morph {

if (child && refChild) {
if (isElement(child) && isElement(refChild)) this.#morphChildElement(child, refChild, element);
else this.#morphNode(child, refChild);
else this.#morphNode(child, refChild); // TODO: performance optimization here
} else if (refChild) {
this.#appendChild(element, refChild.cloneNode(true));
} else if (child) {
Expand Down Expand Up @@ -383,18 +382,6 @@ class Morph {
// so we use type guards instead. This keeps TypeScript happy, while doing
// the necessary checks at runtime.

function isText(node: Node): node is Text;
function isText(node: ReadonlyNode<Node>): node is ReadonlyNode<Text>;
function isText(node: Node | ReadonlyNode<Node>): boolean {
return node.nodeType === 3;
}

function isComment(node: Node): node is Comment;
function isComment(node: ReadonlyNode<Node>): node is ReadonlyNode<Comment>;
function isComment(node: Node | ReadonlyNode<Node>): boolean {
return node.nodeType === 8;
}

function isElement(node: Node): node is Element;
function isElement(node: ReadonlyNode<Node>): node is ReadonlyNode<Element>;
function isElement(node: Node | ReadonlyNode<Node>): boolean {
Expand Down
2 changes: 1 addition & 1 deletion test/morphlex.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { fixture, html, expect } from "@open-wc/testing";
import { morph } from "../";

describe("morph", () => {
it.only("doesn't cause iframes to reload", async () => {
it("doesn't cause iframes to reload", async () => {
const original = await fixture(
`<div>
<h1></h1>
Expand Down

0 comments on commit 16ff5af

Please sign in to comment.