diff --git a/src/nodes/html.ts b/src/nodes/html.ts index f6f4ea7..d0b69d1 100644 --- a/src/nodes/html.ts +++ b/src/nodes/html.ts @@ -1,5 +1,5 @@ import { is, selectAll, selectOne } from 'css-select'; -import { decodeHTML } from 'entities'; +import { decodeHTML, encode } from 'entities'; import arr_back from '../back'; import Matcher from '../matcher'; import VoidTag from '../void-tag'; @@ -271,7 +271,7 @@ export default class HTMLElement extends Node { return decode(this.rawText); } public set textContent(val: string) { - const content = [new TextNode(val, this)]; + const content = [new TextNode(encode(val), this)]; this.childNodes = content; } /** diff --git a/test/tests/textcontent-encode.js b/test/tests/textcontent-encode.js new file mode 100644 index 0000000..b0106b3 --- /dev/null +++ b/test/tests/textcontent-encode.js @@ -0,0 +1,19 @@ +const { parse } = require('@test/test-target'); + +describe('HTMLElement#textContent setter encodes special characters', function () { + it('escapes HTML metacharacters when serialized', function () { + const root = parse('
'); + const div = root.firstChild; + div.textContent = 'Tom & Jerry'; + div.innerHTML.should.eql('<b>Tom & Jerry</b>'); + div.textContent.should.eql('Tom & Jerry'); + }); + it('round-trips a text value that looks like markup', function () { + const root = parse(''); + const div = root.firstChild; + div.textContent = ''; + const reparsed = parse(div.toString()).firstChild; + reparsed.childNodes.should.have.length(1); + reparsed.textContent.should.eql(''); + }); +});