Skip to content

Commit

Permalink
Added suppport for cdata sections. (#206)
Browse files Browse the repository at this point in the history
  • Loading branch information
jordandh authored Oct 22, 2023
1 parent 5f827a5 commit 9dccace
Show file tree
Hide file tree
Showing 39 changed files with 265 additions and 9 deletions.
22 changes: 22 additions & 0 deletions cjs/interface/cdata-section.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
'use strict';
const {CDATA_SECTION_NODE} = require('../shared/constants.js');
const {VALUE} = require('../shared/symbols.js');

const {CharacterData} = require('./character-data.js');

/**
* @implements globalThis.CDATASection
*/
class CDATASection extends CharacterData {
constructor(ownerDocument, data = '') {
super(ownerDocument, '#cdatasection', CDATA_SECTION_NODE, data);
}

cloneNode() {
const {ownerDocument, [VALUE]: data} = this;
return new CDATASection(ownerDocument, data);
}

toString() { return `<![CDATA[${this[VALUE]}]]>`; }
}
exports.CDATASection = CDATASection
2 changes: 2 additions & 0 deletions cjs/interface/document.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const {NonElementParentNode} = require('../mixin/non-element-parent-node.js');
const {SVGElement} = require('../svg/element.js');

const {Attr} = require('./attr.js');
const {CDATASection} = require('./cdata-section.js')
const {Comment} = require('./comment.js');
const {CustomElementRegistry} = require('./custom-element-registry.js');
const {CustomEvent} = require('./custom-event.js');
Expand Down Expand Up @@ -171,6 +172,7 @@ class Document extends NonElementParentNode {
}

createAttribute(name) { return new Attr(this, name); }
createCDATASection(data) { return new CDATASection(this, data); }
createComment(textContent) { return new Comment(this, textContent); }
createDocumentFragment() { return new DocumentFragment(this); }
createDocumentType(name, publicId, systemId) { return new DocumentType(this, name, publicId, systemId); }
Expand Down
3 changes: 3 additions & 0 deletions cjs/interface/element.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
const {
ATTRIBUTE_NODE,
BLOCK_ELEMENTS,
CDATA_SECTION_NODE,
COMMENT_NODE,
ELEMENT_NODE,
NODE_END,
Expand Down Expand Up @@ -405,6 +406,7 @@ class Element extends ParentNode {
}
case TEXT_NODE:
case COMMENT_NODE:
case CDATA_SECTION_NODE:
addNext(next.cloneNode(deep));
break;
}
Expand Down Expand Up @@ -465,6 +467,7 @@ class Element extends ParentNode {
break;
case TEXT_NODE:
case COMMENT_NODE:
case CDATA_SECTION_NODE:
out.push((isOpened ? '>' : '') + next);
isOpened = false;
break;
Expand Down
2 changes: 2 additions & 0 deletions cjs/interface/node-filter.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ const {
SHOW_ALL,
SHOW_ELEMENT,
SHOW_COMMENT,
SHOW_CDATA_SECTION,
SHOW_TEXT
} = require('../shared/constants.js');

class NodeFilter {
static get SHOW_ALL() { return SHOW_ALL; }
static get SHOW_ELEMENT() { return SHOW_ELEMENT; }
static get SHOW_COMMENT() { return SHOW_COMMENT; }
static get SHOW_CDATA_SECTION() { return SHOW_CDATA_SECTION; }
static get SHOW_TEXT() { return SHOW_TEXT; }
}
exports.NodeFilter = NodeFilter
3 changes: 3 additions & 0 deletions cjs/interface/node.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const {
ELEMENT_NODE,
ATTRIBUTE_NODE,
TEXT_NODE,
CDATA_SECTION_NODE,
COMMENT_NODE,
DOCUMENT_NODE,
DOCUMENT_FRAGMENT_NODE,
Expand Down Expand Up @@ -40,6 +41,7 @@ class Node extends EventTarget {
static get ELEMENT_NODE() { return ELEMENT_NODE; }
static get ATTRIBUTE_NODE() { return ATTRIBUTE_NODE; }
static get TEXT_NODE() { return TEXT_NODE; }
static get CDATA_SECTION_NODE() { return CDATA_SECTION_NODE; }
static get COMMENT_NODE() { return COMMENT_NODE; }
static get DOCUMENT_NODE() { return DOCUMENT_NODE; }
static get DOCUMENT_FRAGMENT_NODE() { return DOCUMENT_FRAGMENT_NODE; }
Expand All @@ -58,6 +60,7 @@ class Node extends EventTarget {
get ELEMENT_NODE() { return ELEMENT_NODE; }
get ATTRIBUTE_NODE() { return ATTRIBUTE_NODE; }
get TEXT_NODE() { return TEXT_NODE; }
get CDATA_SECTION_NODE() { return CDATA_SECTION_NODE; }
get COMMENT_NODE() { return COMMENT_NODE; }
get DOCUMENT_NODE() { return DOCUMENT_NODE; }
get DOCUMENT_FRAGMENT_NODE() { return DOCUMENT_FRAGMENT_NODE; }
Expand Down
4 changes: 4 additions & 0 deletions cjs/interface/tree-walker.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ const {
DOCUMENT_NODE,
ELEMENT_NODE,
TEXT_NODE,
CDATA_SECTION_NODE,
COMMENT_NODE,
SHOW_ALL,
SHOW_ELEMENT,
SHOW_CDATA_SECTION,
SHOW_COMMENT,
SHOW_TEXT
} = require('../shared/constants.js');
Expand All @@ -20,6 +22,8 @@ const isOK = ({nodeType}, mask) => {
return mask & SHOW_TEXT;
case COMMENT_NODE:
return mask & SHOW_COMMENT;
case CDATA_SECTION_NODE:
return mask & SHOW_CDATA_SECTION;
}
return 0;
};
Expand Down
4 changes: 3 additions & 1 deletion cjs/mixin/parent-node.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const {
ELEMENT_NODE,
TEXT_NODE,
NODE_END,
CDATA_SECTION_NODE,
COMMENT_NODE
} = require('../shared/constants.js');

Expand Down Expand Up @@ -41,7 +42,7 @@ const insert = (parentNode, child, nodes) => {
[typeof NEXT]: NodeStruct,
[typeof PREV]: NodeStruct,
[typeof START]: NodeStruct,
nodeType: typeof ATTRIBUTE_NODE | typeof DOCUMENT_FRAGMENT_NODE | typeof ELEMENT_NODE | typeof TEXT_NODE | typeof NODE_END | typeof COMMENT_NODE,
nodeType: typeof ATTRIBUTE_NODE | typeof DOCUMENT_FRAGMENT_NODE | typeof ELEMENT_NODE | typeof TEXT_NODE | typeof NODE_END | typeof COMMENT_NODE | typeof CDATA_SECTION_NODE,
ownerDocument: Document,
parentNode: ParentNode,
}} NodeStruct */
Expand Down Expand Up @@ -248,6 +249,7 @@ class ParentNode extends Node {
}
case TEXT_NODE:
case COMMENT_NODE:
case CDATA_SECTION_NODE:
node.remove();
/* eslint no-fallthrough:0 */
// this covers DOCUMENT_TYPE_NODE too
Expand Down
4 changes: 4 additions & 0 deletions cjs/shared/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ const ATTRIBUTE_NODE = 2;
exports.ATTRIBUTE_NODE = ATTRIBUTE_NODE;
const TEXT_NODE = 3;
exports.TEXT_NODE = TEXT_NODE;
const CDATA_SECTION_NODE = 4;
exports.CDATA_SECTION_NODE = CDATA_SECTION_NODE;
const COMMENT_NODE = 8;
exports.COMMENT_NODE = COMMENT_NODE;
const DOCUMENT_NODE = 9;
Expand All @@ -30,6 +32,8 @@ const SHOW_ELEMENT = 1;
exports.SHOW_ELEMENT = SHOW_ELEMENT;
const SHOW_TEXT = 4;
exports.SHOW_TEXT = SHOW_TEXT;
const SHOW_CDATA_SECTION = 8;
exports.SHOW_CDATA_SECTION = SHOW_CDATA_SECTION;
const SHOW_COMMENT = 128;
exports.SHOW_COMMENT = SHOW_COMMENT;

Expand Down
7 changes: 7 additions & 0 deletions cjs/shared/facades.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use strict';
const {Attr: _Attr} = require('../interface/attr.js');
const {CharacterData: _CharacterData} = require('../interface/character-data.js');
const {CDATASection: _CDATASection} = require('../interface/cdata-section');
const {Comment: _Comment} = require('../interface/comment.js');
const {DocumentFragment: _DocumentFragment} = require('../interface/document-fragment.js');
const {DocumentType: _DocumentType} = require('../interface/document-type.js');
Expand All @@ -23,6 +24,11 @@ exports.Attr = Attr
setPrototypeOf(Attr, _Attr);
Attr.prototype = _Attr.prototype;

function CDATASection() { illegalConstructor(); }
exports.CDATASection = CDATASection
setPrototypeOf(CDATASection, _CDATASection);
CDATASection.prototype = _CDATASection.prototype;

function CharacterData() { illegalConstructor(); }
exports.CharacterData = CharacterData
setPrototypeOf(CharacterData, _CharacterData);
Expand Down Expand Up @@ -71,6 +77,7 @@ SVGElement.prototype = _SVGElement.prototype;

const Facades = {
Attr,
CDATASection,
CharacterData,
Comment,
DocumentFragment,
Expand Down
2 changes: 2 additions & 0 deletions cjs/shared/jsdon.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
const {
NODE_END,
ATTRIBUTE_NODE,
CDATA_SECTION_NODE,
COMMENT_NODE,
DOCUMENT_TYPE_NODE,
ELEMENT_NODE,
Expand All @@ -20,6 +21,7 @@ const loopSegment = ({[NEXT]: next, [END]: end}, json) => {
break;
case TEXT_NODE:
case COMMENT_NODE:
case CDATA_SECTION_NODE:
characterDataAsJSON(next, json);
break;
case ELEMENT_NODE:
Expand Down
2 changes: 2 additions & 0 deletions cjs/shared/node.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
'use strict';
const {
CDATA_SECTION_NODE,
COMMENT_NODE,
DOCUMENT_NODE,
DOCUMENT_FRAGMENT_NODE,
Expand Down Expand Up @@ -38,6 +39,7 @@ const previousSibling = ({[PREV]: prev}) => {
return prev[START];
case TEXT_NODE:
case COMMENT_NODE:
case CDATA_SECTION_NODE:
return prev;
}
return null;
Expand Down
13 changes: 12 additions & 1 deletion cjs/shared/parse-from-string.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ const parseFromString = (document, isHTML, markupLanguage) => {

let node = document;
let ownerSVGElement = null;
let parsingCData = false;

notParsing = false;

Expand Down Expand Up @@ -90,7 +91,17 @@ const parseFromString = (document, isHTML, markupLanguage) => {

// #text, #comment
oncomment(data) { append(node, document.createComment(data), active); },
ontext(text) { append(node, document.createTextNode(text), active); },
ontext(text) {
if (parsingCData) {
append(node, document.createCDATASection(text), active);
} else {
append(node, document.createTextNode(text), active);
}
},

// #cdata
oncdatastart() { parsingCData = true; },
oncdataend() { parsingCData = false; },

// </tagName>
onclosetag() {
Expand Down
5 changes: 5 additions & 0 deletions cjs/shared/parse-json.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const {
ELEMENT_NODE,
ATTRIBUTE_NODE,
TEXT_NODE,
CDATA_SECTION_NODE,
COMMENT_NODE,
DOCUMENT_NODE,
DOCUMENT_TYPE_NODE,
Expand All @@ -16,6 +17,7 @@ const {htmlClasses} = require('./register-html-class.js');
const {knownBoundaries, knownSiblings} = require('./utils.js');

const {Attr} = require('../interface/attr.js');
const {CDATASection} = require('../interface/cdata-section.js');
const {Comment} = require('../interface/comment.js');
const {DocumentType} = require('../interface/document-type.js');
const {Text} = require('../interface/text.js');
Expand Down Expand Up @@ -84,6 +86,9 @@ const parseJSON = value => {
case COMMENT_NODE:
append(parentNode, new Comment(document, array[i++]), end);
break;
case CDATA_SECTION_NODE:
append(parentNode, new CDATASection(document, array[i++]), end);
break;
case DOCUMENT_TYPE_NODE: {
const args = [document];
while (typeof array[i] === 'string')
Expand Down
20 changes: 20 additions & 0 deletions esm/interface/cdata-section.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import {CDATA_SECTION_NODE} from '../shared/constants.js';
import {VALUE} from '../shared/symbols.js';

import {CharacterData} from './character-data.js';

/**
* @implements globalThis.CDATASection
*/
export class CDATASection extends CharacterData {
constructor(ownerDocument, data = '') {
super(ownerDocument, '#cdatasection', CDATA_SECTION_NODE, data);
}

cloneNode() {
const {ownerDocument, [VALUE]: data} = this;
return new CDATASection(ownerDocument, data);
}

toString() { return `<![CDATA[${this[VALUE]}]]>`; }
}
2 changes: 2 additions & 0 deletions esm/interface/document.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {NonElementParentNode} from '../mixin/non-element-parent-node.js';
import {SVGElement} from '../svg/element.js';

import {Attr} from './attr.js';
import {CDATASection} from './cdata-section.js'
import {Comment} from './comment.js';
import {CustomElementRegistry} from './custom-element-registry.js';
import {CustomEvent} from './custom-event.js';
Expand Down Expand Up @@ -171,6 +172,7 @@ export class Document extends NonElementParentNode {
}

createAttribute(name) { return new Attr(this, name); }
createCDATASection(data) { return new CDATASection(this, data); }
createComment(textContent) { return new Comment(this, textContent); }
createDocumentFragment() { return new DocumentFragment(this); }
createDocumentType(name, publicId, systemId) { return new DocumentType(this, name, publicId, systemId); }
Expand Down
3 changes: 3 additions & 0 deletions esm/interface/element.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import {
ATTRIBUTE_NODE,
BLOCK_ELEMENTS,
CDATA_SECTION_NODE,
COMMENT_NODE,
ELEMENT_NODE,
NODE_END,
Expand Down Expand Up @@ -407,6 +408,7 @@ export class Element extends ParentNode {
}
case TEXT_NODE:
case COMMENT_NODE:
case CDATA_SECTION_NODE:
addNext(next.cloneNode(deep));
break;
}
Expand Down Expand Up @@ -467,6 +469,7 @@ export class Element extends ParentNode {
break;
case TEXT_NODE:
case COMMENT_NODE:
case CDATA_SECTION_NODE:
out.push((isOpened ? '>' : '') + next);
isOpened = false;
break;
Expand Down
2 changes: 2 additions & 0 deletions esm/interface/node-filter.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ import {
SHOW_ALL,
SHOW_ELEMENT,
SHOW_COMMENT,
SHOW_CDATA_SECTION,
SHOW_TEXT
} from '../shared/constants.js';

export class NodeFilter {
static get SHOW_ALL() { return SHOW_ALL; }
static get SHOW_ELEMENT() { return SHOW_ELEMENT; }
static get SHOW_COMMENT() { return SHOW_COMMENT; }
static get SHOW_CDATA_SECTION() { return SHOW_CDATA_SECTION; }
static get SHOW_TEXT() { return SHOW_TEXT; }
}
3 changes: 3 additions & 0 deletions esm/interface/node.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
ELEMENT_NODE,
ATTRIBUTE_NODE,
TEXT_NODE,
CDATA_SECTION_NODE,
COMMENT_NODE,
DOCUMENT_NODE,
DOCUMENT_FRAGMENT_NODE,
Expand Down Expand Up @@ -39,6 +40,7 @@ export class Node extends EventTarget {
static get ELEMENT_NODE() { return ELEMENT_NODE; }
static get ATTRIBUTE_NODE() { return ATTRIBUTE_NODE; }
static get TEXT_NODE() { return TEXT_NODE; }
static get CDATA_SECTION_NODE() { return CDATA_SECTION_NODE; }
static get COMMENT_NODE() { return COMMENT_NODE; }
static get DOCUMENT_NODE() { return DOCUMENT_NODE; }
static get DOCUMENT_FRAGMENT_NODE() { return DOCUMENT_FRAGMENT_NODE; }
Expand All @@ -57,6 +59,7 @@ export class Node extends EventTarget {
get ELEMENT_NODE() { return ELEMENT_NODE; }
get ATTRIBUTE_NODE() { return ATTRIBUTE_NODE; }
get TEXT_NODE() { return TEXT_NODE; }
get CDATA_SECTION_NODE() { return CDATA_SECTION_NODE; }
get COMMENT_NODE() { return COMMENT_NODE; }
get DOCUMENT_NODE() { return DOCUMENT_NODE; }
get DOCUMENT_FRAGMENT_NODE() { return DOCUMENT_FRAGMENT_NODE; }
Expand Down
4 changes: 4 additions & 0 deletions esm/interface/tree-walker.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ import {
DOCUMENT_NODE,
ELEMENT_NODE,
TEXT_NODE,
CDATA_SECTION_NODE,
COMMENT_NODE,
SHOW_ALL,
SHOW_ELEMENT,
SHOW_CDATA_SECTION,
SHOW_COMMENT,
SHOW_TEXT
} from '../shared/constants.js';
Expand All @@ -19,6 +21,8 @@ const isOK = ({nodeType}, mask) => {
return mask & SHOW_TEXT;
case COMMENT_NODE:
return mask & SHOW_COMMENT;
case CDATA_SECTION_NODE:
return mask & SHOW_CDATA_SECTION;
}
return 0;
};
Expand Down
Loading

0 comments on commit 9dccace

Please sign in to comment.