Skip to content

Commit 7d5a0a7

Browse files
authored
Merge pull request #63 from ember-fastboot/insert-adjacent-html
use insertAdjacentHTML instead of createRawHTMLSection
2 parents e36beb9 + f99cc77 commit 7d5a0a7

10 files changed

Lines changed: 100 additions & 78 deletions

File tree

packages/@simple-dom/document/src/clone.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
import {
22
ElementNamespace,
33
Namespace,
4+
NodeType,
45
SimpleAttr,
56
SimpleAttrs,
67
SimpleDocument,
78
SimpleNode,
8-
SimpleNodeType,
99
} from '@simple-dom/interface';
1010
import { EMPTY_ATTRS } from './attributes';
1111
import SimpleNodeImpl from './node';
1212

13-
export { Namespace, SimpleDocument, SimpleNodeType };
13+
export { Namespace, SimpleDocument, NodeType };
1414

1515
export function cloneNode(
1616
node: SimpleNode,
@@ -35,7 +35,7 @@ export function cloneNode(
3535
function nodeFrom(node: SimpleNode): SimpleNode {
3636

3737
let namespaceURI: ElementNamespace | undefined;
38-
if (node.nodeType === SimpleNodeType.ELEMENT_NODE) {
38+
if (node.nodeType === NodeType.ELEMENT_NODE) {
3939
namespaceURI = node.namespaceURI;
4040
}
4141

@@ -47,7 +47,7 @@ function nodeFrom(node: SimpleNode): SimpleNode {
4747
namespaceURI,
4848
);
4949

50-
if (node.nodeType === SimpleNodeType.ELEMENT_NODE) {
50+
if (node.nodeType === NodeType.ELEMENT_NODE) {
5151
clone.attributes = copyAttrs(node.attributes);
5252
}
5353

packages/@simple-dom/document/src/document.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
import {
22
Namespace,
3+
NodeType,
34
SimpleDocument,
4-
SimpleNodeType,
55
} from '@simple-dom/interface';
66
import SimpleNodeImpl from './node';
77

88
export function createHTMLDocument(): SimpleDocument {
9-
const document = new SimpleNodeImpl(null, SimpleNodeType.DOCUMENT_NODE, '#document', null, Namespace.HTML);
10-
const doctype = new SimpleNodeImpl(document, SimpleNodeType.DOCUMENT_TYPE_NODE, 'html', null, Namespace.HTML);
11-
const html = new SimpleNodeImpl(document, SimpleNodeType.ELEMENT_NODE, 'HTML', null, Namespace.HTML);
12-
const head = new SimpleNodeImpl(document, SimpleNodeType.ELEMENT_NODE, 'HEAD', null, Namespace.HTML);
13-
const body = new SimpleNodeImpl(document, SimpleNodeType.ELEMENT_NODE, 'BODY', null, Namespace.HTML);
9+
const document = new SimpleNodeImpl(null, NodeType.DOCUMENT_NODE, '#document', null, Namespace.HTML);
10+
const doctype = new SimpleNodeImpl(document, NodeType.DOCUMENT_TYPE_NODE, 'html', null, Namespace.HTML);
11+
const html = new SimpleNodeImpl(document, NodeType.ELEMENT_NODE, 'HTML', null, Namespace.HTML);
12+
const head = new SimpleNodeImpl(document, NodeType.ELEMENT_NODE, 'HEAD', null, Namespace.HTML);
13+
const body = new SimpleNodeImpl(document, NodeType.ELEMENT_NODE, 'BODY', null, Namespace.HTML);
1414
html.appendChild(head);
1515
html.appendChild(body);
1616
document.appendChild(doctype);

packages/@simple-dom/document/src/mutation.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { SimpleDocumentFragment, SimpleNode, SimpleNodeType } from '@simple-dom/interface';
1+
import { NodeType, SimpleDocumentFragment, SimpleNode } from '@simple-dom/interface';
22
import { SimpleElementImpl } from './node';
33

44
export function insertBefore(parentNode: SimpleNode, newChild: SimpleNode, refChild: SimpleNode | null): void {
@@ -30,7 +30,7 @@ function insertBetween(
3030
previousSibling: SimpleNode | null,
3131
nextSibling: SimpleNode | null,
3232
) {
33-
if (newChild.nodeType === SimpleNodeType.DOCUMENT_FRAGMENT_NODE) {
33+
if (newChild.nodeType === NodeType.DOCUMENT_FRAGMENT_NODE) {
3434
insertFragment(newChild, parentNode, previousSibling, nextSibling);
3535
return;
3636
}

packages/@simple-dom/document/src/node.ts

Lines changed: 44 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import {
22
AttrNamespace,
33
ElementNamespace,
4+
InsertPosition,
45
Namespace,
6+
NodeType,
57
SimpleAttr,
68
SimpleChildNodes,
79
SimpleComment,
@@ -10,7 +12,6 @@ import {
1012
SimpleDocumentType,
1113
SimpleElement,
1214
SimpleNode,
13-
SimpleNodeType,
1415
SimpleRawHTMLSection,
1516
SimpleText,
1617
} from '@simple-dom/interface';
@@ -31,11 +32,11 @@ import {
3132
parseQualifiedName,
3233
} from './qualified-name';
3334

34-
export type SimpleElementImpl = SimpleNodeImpl<SimpleNodeType.ELEMENT_NODE, SimpleDocument, null, ElementNamespace>;
35-
export type SimpleDocumentImpl = SimpleNodeImpl<SimpleNodeType.DOCUMENT_NODE, null, null, Namespace.HTML>;
35+
export type SimpleElementImpl = SimpleNodeImpl<NodeType.ELEMENT_NODE, SimpleDocument, null, ElementNamespace>;
36+
export type SimpleDocumentImpl = SimpleNodeImpl<NodeType.DOCUMENT_NODE, null, null, Namespace.HTML>;
3637

3738
export default class SimpleNodeImpl<
38-
T extends SimpleNodeType,
39+
T extends NodeType,
3940
O extends SimpleDocument | null,
4041
V extends string | null,
4142
N extends ElementNamespace | undefined
@@ -92,6 +93,35 @@ export default class SimpleNodeImpl<
9293
return oldChild;
9394
}
9495

96+
public insertAdjacentHTML(this: SimpleElementImpl, position: InsertPosition, html: string): void {
97+
const raw = new SimpleNodeImpl(this.ownerDocument, NodeType.RAW_NODE, '#raw', html, void 0);
98+
let parentNode: SimpleNode | null;
99+
let nextSibling: SimpleNode | null;
100+
switch (position) {
101+
case 'beforebegin':
102+
parentNode = this.parentNode;
103+
nextSibling = this;
104+
break;
105+
case 'afterbegin':
106+
parentNode = this;
107+
nextSibling = this.firstChild;
108+
break;
109+
case 'beforeend':
110+
parentNode = this;
111+
nextSibling = null;
112+
break;
113+
case 'afterend':
114+
parentNode = this.parentNode;
115+
nextSibling = this.nextSibling;
116+
break;
117+
default: throw new Error('invalid position');
118+
}
119+
if (parentNode === null) {
120+
throw new Error(`${position} requires a parentNode`);
121+
}
122+
insertBefore(parentNode, raw, nextSibling);
123+
}
124+
95125
public getAttribute(this: SimpleElementImpl, name: string): string | null {
96126
const localName = adjustAttrName(this.namespaceURI, name);
97127
return getAttribute(this.attributes, null, localName);
@@ -142,28 +172,32 @@ export default class SimpleNodeImpl<
142172
}
143173

144174
public createElement(this: SimpleDocumentImpl, name: string): SimpleElement {
145-
return new SimpleNodeImpl(this, SimpleNodeType.ELEMENT_NODE, name.toUpperCase(), null, Namespace.HTML);
175+
return new SimpleNodeImpl(this, NodeType.ELEMENT_NODE, name.toUpperCase(), null, Namespace.HTML);
146176
}
147177

148178
public createElementNS(this: SimpleDocumentImpl, namespace: ElementNamespace, qualifiedName: string): SimpleElement {
149179
// we don't care to parse the qualified name because we only support HTML documents
150180
// which don't support prefixed elements
151-
return new SimpleNodeImpl(this, SimpleNodeType.ELEMENT_NODE, qualifiedName, null, namespace);
181+
return new SimpleNodeImpl(this, NodeType.ELEMENT_NODE, qualifiedName, null, namespace);
152182
}
153183

154184
public createTextNode(this: SimpleDocumentImpl, text: string): SimpleText {
155-
return new SimpleNodeImpl(this, SimpleNodeType.TEXT_NODE, '#text', text, void 0);
185+
return new SimpleNodeImpl(this, NodeType.TEXT_NODE, '#text', text, void 0);
156186
}
157187

158188
public createComment(this: SimpleDocumentImpl, text: string): SimpleComment {
159-
return new SimpleNodeImpl(this, SimpleNodeType.COMMENT_NODE, '#comment', text, void 0);
189+
return new SimpleNodeImpl(this, NodeType.COMMENT_NODE, '#comment', text, void 0);
160190
}
161191

192+
/**
193+
* Backwards compat
194+
* @deprecated
195+
*/
162196
public createRawHTMLSection(this: SimpleDocumentImpl, text: string): SimpleRawHTMLSection {
163-
return new SimpleNodeImpl(this, SimpleNodeType.RAW, '#raw', text, void 0);
197+
return new SimpleNodeImpl(this, NodeType.RAW_NODE, '#raw', text, void 0);
164198
}
165199

166200
public createDocumentFragment(this: SimpleDocumentImpl): SimpleDocumentFragment {
167-
return new SimpleNodeImpl(this, SimpleNodeType.DOCUMENT_FRAGMENT_NODE, '#document-fragment', null, void 0);
201+
return new SimpleNodeImpl(this, NodeType.DOCUMENT_FRAGMENT_NODE, '#document-fragment', null, void 0);
168202
}
169203
}

packages/@simple-dom/document/test/document-test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import { moduleWithDocument } from '@simple-dom/dom-test-helper';
2-
import { Namespace, SimpleNodeType } from '@simple-dom/interface';
2+
import { Namespace, NodeType } from '@simple-dom/interface';
33

44
moduleWithDocument('Document', (helper) => {
55

66
QUnit.test('creating a document node', (assert) => {
77
const { document } = helper;
88

99
// https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType
10-
assert.strictEqual(document.nodeType, SimpleNodeType.DOCUMENT_NODE, 'document has node type of 9');
10+
assert.strictEqual(document.nodeType, NodeType.DOCUMENT_NODE, 'document has node type of 9');
1111
// https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeName
1212
assert.strictEqual(document.nodeName, '#document', 'document node has the name #document');
1313
// https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeValue
@@ -31,7 +31,7 @@ moduleWithDocument('Document', (helper) => {
3131
assert.ok(false, 'document has lastChild');
3232
} else {
3333
/* istanbul ignore else */
34-
if (document.lastChild.nodeType === SimpleNodeType.ELEMENT_NODE) {
34+
if (document.lastChild.nodeType === NodeType.ELEMENT_NODE) {
3535
assert.strictEqual(document.lastChild.namespaceURI, Namespace.HTML, 'documentElement is HTML namespace');
3636
}
3737
assert.strictEqual(document.lastChild.ownerDocument, document);

packages/@simple-dom/document/test/element-test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { moduleWithDocument } from '@simple-dom/dom-test-helper';
2-
import { Namespace, SimpleDocumentFragment } from '@simple-dom/interface';
2+
import { InsertPosition, Namespace, SimpleDocumentFragment } from '@simple-dom/interface';
33
import Serializer from '@simple-dom/serializer';
44
import voidMap from '@simple-dom/void-map';
55

@@ -178,7 +178,7 @@ moduleWithDocument('Element', (helper) => {
178178
});
179179

180180
QUnit.test('cloneNode(true) recursively clones nodes', (assert) => {
181-
const { document, insertAdjacentHTML } = helper;
181+
const { document } = helper;
182182

183183
const parent = document.createElement('div');
184184

@@ -189,7 +189,7 @@ moduleWithDocument('Element', (helper) => {
189189
const child31 = document.createComment('');
190190
child3.appendChild(child31);
191191

192-
insertAdjacentHTML(child3, 'beforeend', '<p data-attr="herp">derp</p>');
192+
child3.insertAdjacentHTML(InsertPosition.beforeend, '<p data-attr="herp">derp</p>');
193193

194194
parent.appendChild(child1);
195195
parent.appendChild(child2);

packages/@simple-dom/dom-test-helper/src/index.ts

Lines changed: 0 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,13 @@ export const BROWSER_DOCUMENT_TYPE = 'browser document';
1919

2020
export type DOCUMENT_TYPE = typeof SIMPLE_DOCUMENT_TYPE | typeof BROWSER_DOCUMENT_TYPE;
2121

22-
export type InsertPosition = 'beforebegin' | 'afterbegin' | 'beforeend' | 'afterend';
23-
2422
export interface ModuleWithDocumentHelper {
2523
type: DOCUMENT_TYPE;
2624
document: SimpleDocument;
2725
element(tagName: string, attrs?: Attrs, ...children: SimpleNode[]): SimpleElement;
2826
text(s: string): SimpleText;
2927
comment(s: string): SimpleComment;
3028
fragment(...children: SimpleNode[]): SimpleDocumentFragment;
31-
insertAdjacentHTML(element: SimpleElement, position: InsertPosition, text: string): SimpleElement;
3229
}
3330

3431
export type ModuleWithDocument = (name: string, callback: ModuleWithDocumentCallback) => void;
@@ -44,7 +41,6 @@ export const moduleWithDocument = (() => {
4441

4542
constructor() {
4643
// allow helpers to be destructured
47-
this.insertAdjacentHTML = this.insertAdjacentHTML.bind(this);
4844
this.text = this.text.bind(this);
4945
this.comment = this.comment.bind(this);
5046
this.fragment = this.fragment.bind(this);
@@ -53,8 +49,6 @@ export const moduleWithDocument = (() => {
5349

5450
public abstract setup(hooks: NestedHooks): void;
5551

56-
public abstract insertAdjacentHTML(element: SimpleElement, position: InsertPosition, text: string): SimpleElement;
57-
5852
public text(s: string): SimpleText {
5953
return this.document.createTextNode(s);
6054
}
@@ -102,26 +96,6 @@ export const moduleWithDocument = (() => {
10296
this.document = undefined as any;
10397
});
10498
}
105-
106-
public insertAdjacentHTML(element: SimpleElement, position: InsertPosition, text: string): SimpleElement {
107-
const raw = this.document.createRawHTMLSection!(text);
108-
switch (position) {
109-
case 'beforebegin':
110-
element.parentNode!.insertBefore(raw, element);
111-
break;
112-
case 'afterbegin':
113-
element.insertBefore(raw, element.firstChild);
114-
break;
115-
case 'beforeend':
116-
element.insertBefore(raw, null);
117-
break;
118-
case 'afterend':
119-
element.parentNode!.insertBefore(raw, element.nextSibling);
120-
break;
121-
default: throw Error('not implemented');
122-
}
123-
return element;
124-
}
12599
}
126100

127101
class RealHelper extends Helper {
@@ -136,11 +110,6 @@ export const moduleWithDocument = (() => {
136110
this.document = undefined as any;
137111
});
138112
}
139-
140-
public insertAdjacentHTML(element: SimpleElement, position: InsertPosition, text: string): SimpleElement {
141-
(element as any).insertAdjacentHTML(position, text);
142-
return element;
143-
}
144113
}
145114

146115
const helpers: Helper[] = [

0 commit comments

Comments
 (0)