Skip to content

Commit

Permalink
Allow modification of existing attributes and text content. (#23)
Browse files Browse the repository at this point in the history
Moves the `setTextContent` and `setAttribute` methods to behave more like the DOM equivalents by replacing any existing content or attributes.
  • Loading branch information
cohenerickson authored Jan 15, 2024
1 parent c7a76aa commit b7481ff
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 12 deletions.
2 changes: 2 additions & 0 deletions src/attributes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import type {Element} from './nodeTypes.js';
* @return {void}
*/
export function setAttribute(node: Element, name: string, value: string): void {
removeAttribute(node, name);

node.attrs.push({
name,
value
Expand Down
16 changes: 16 additions & 0 deletions src/test/attributes_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,22 @@ test('setAttribute', async (t) => {

assert.deepStrictEqual(node.attrs, [{name: 'ping-pong', value: 'boing'}]);
});

await t.test('modifies existing attribute on element', () => {
const node: Element = {
nodeName: 'div',
parentNode: null,
tagName: 'div',
attrs: [{name: 'foo', value: 'bar'}],
namespaceURI: html.NS.HTML,
childNodes: []
};

main.setAttribute(node, 'foo', 'baz');

assert.strictEqual(node.attrs.length, 1);
assert.deepStrictEqual(node.attrs, [{name: 'foo', value: 'baz'}]);
});
});

test('getAttribute', async (t) => {
Expand Down
44 changes: 39 additions & 5 deletions src/test/text_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,28 @@ test('getTextContent', async (t) => {
assert.strictEqual(result, 'some text');
});

await t.test('returns value of comment node', () => {
const node: CommentNode = {
nodeName: '#comment',
parentNode: null,
data: 'some comment'
};

const result = main.getTextContent(node);

assert.strictEqual(result, 'some comment');
});

await t.test('concats all text-like children', () => {
const child1: TextNode = {
nodeName: '#text',
parentNode: null,
value: 'text node'
value: 'text node 1'
};
const child2: CommentNode = {
nodeName: '#comment',
const child2: TextNode = {
nodeName: '#text',
parentNode: null,
data: 'comment node'
value: 'text node 2'
};
const node: DocumentFragment = {
nodeName: '#document-fragment',
Expand All @@ -53,7 +65,7 @@ test('getTextContent', async (t) => {

const result = main.getTextContent(node);

assert.strictEqual(result, 'text nodecomment node');
assert.strictEqual(result, 'text node 1text node 2');
});

await t.test('ignores non-text children', () => {
Expand Down Expand Up @@ -164,6 +176,28 @@ test('setTextContent', async (t) => {
});
});

await t.test('sets text node for parent nodes', () => {
const node: DocumentFragment = {
nodeName: '#document-fragment',
childNodes: []
};

node.childNodes.push({
nodeName: '#text',
value: 'old text',
parentNode: node
});

main.setTextContent(node, 'new text');

assert.strictEqual(node.childNodes.length, 1);
assert.deepStrictEqual(node.childNodes[0], {
nodeName: '#text',
value: 'new text',
parentNode: node
});
});

await t.test('ignores document type nodes', () => {
const node: DocumentType = {
nodeName: '#documentType',
Expand Down
11 changes: 4 additions & 7 deletions src/text.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import type {Node} from './nodeTypes.js';
import {isCommentNode, isTextNode, isParentNode} from './typeGuards.js';
import {appendChild} from './treeMutation.js';
import {createTextNode} from './creation.js';
import {queryAll} from './traversal.js';
import {appendChild} from './treeMutation.js';

/**
* Computes the text content of a given node using a similar
Expand All @@ -21,10 +21,7 @@ export function getTextContent(node: Node): string {

let content = '';

const children = queryAll(
node,
(node) => isTextNode(node) || isCommentNode(node)
);
const children = queryAll(node, (node) => isTextNode(node));

for (const child of children) {
content += getTextContent(child);
Expand All @@ -45,7 +42,7 @@ export function setTextContent(node: Node, text: string): void {
} else if (isTextNode(node)) {
node.value = text;
} else if (isParentNode(node)) {
const textNode = createTextNode(text);
appendChild(node, textNode);
node.childNodes = [];
appendChild(node, createTextNode(text));
}
}

0 comments on commit b7481ff

Please sign in to comment.