Skip to content

Commit

Permalink
Fixed HTML entities support
Browse files Browse the repository at this point in the history
  • Loading branch information
tbranyen committed Jan 8, 2016
1 parent c5b721b commit a1c0b07
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 45 deletions.
25 changes: 15 additions & 10 deletions dist/diffhtml.js
Original file line number Diff line number Diff line change
Expand Up @@ -1329,7 +1329,7 @@ function process(element, patches) {
if (descriptor.nodeName === '#text' || descriptor.nodeName === 'text') {
var textPromises = transition.makePromises('textChanged', [element], null, descriptor.nodeValue);

element.nodeValue = descriptor.nodeValue;
element.innerHTML = descriptor.nodeValue;

triggerTransition('textChanged', textPromises, function (promises) {});
}
Expand Down Expand Up @@ -1948,6 +1948,7 @@ var pools = _pools2.pools; // Code based off of:
// https://github.com/ashi009/node-fast-html-parser

var parser = makeParser();
var slice = Array.prototype.slice;

/**
* parseHTML
Expand All @@ -1974,15 +1975,6 @@ function makeParser() {

var reAttrPattern = /\b([a-z][a-z0-9\-]*)\s*(=\s*("([^"]+)"|'([^']+)'|(\S+)))?/ig;

var kBlockElements = {
div: true,
p: true,
li: true,
td: true,
section: true,
br: true
};

var kSelfClosingElements = {
meta: true,
img: true,
Expand Down Expand Up @@ -2049,6 +2041,15 @@ function makeParser() {
template: true
};

var escapeMap = {
'&': '&',
'<': '&lt;',
'>': '&gt;',
'"': '&quot;',
"'": '&#x27;',
'`': '&#x60;'
};

/**
* TextNode to contain a text element in DOM tree.
* @param {string} value [description]
Expand Down Expand Up @@ -2179,6 +2180,10 @@ function makeParser() {
var newText = data.slice(match.index + match[0].length, index);

if (newText.trim()) {
newText = slice.call(newText).map(function (ch) {
return escapeMap[ch] || ch;
}).join('');

currentParent.childNodes.push(TextNode(newText));
}
}
Expand Down
2 changes: 1 addition & 1 deletion lib/patches/process.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export default function process(element, patches) {
let textPromises = transition.makePromises('textChanged',
[element], null, descriptor.nodeValue);

element.nodeValue = descriptor.nodeValue;
element.innerHTML = descriptor.nodeValue;

triggerTransition('textChanged', textPromises, promises => {});
}
Expand Down
55 changes: 30 additions & 25 deletions lib/util/parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { pools as _pools } from './pools';

var pools = _pools;
var parser = makeParser();
var slice = Array.prototype.slice;

/**
* parseHTML
Expand All @@ -13,8 +14,8 @@ var parser = makeParser();
* @return
*/
export function parseHTML(newHTML, isInner) {
let documentElement = parser.parse(newHTML);
let nodes = documentElement.childNodes;
var documentElement = parser.parse(newHTML);
var nodes = documentElement.childNodes;

return isInner ? nodes : nodes[0];
}
Expand All @@ -25,24 +26,15 @@ export function parseHTML(newHTML, isInner) {
* @return
*/
export function makeParser() {
let kMarkupPattern =
var kMarkupPattern =
/<!--[^]*?(?=-->)-->|<(\/?)([a-z\-][a-z0-9\-]*)\s*([^>]*?)(\/?)>/ig;

let kAttributePattern = /\b(id|class)\s*(=\s*("([^"]+)"|'([^']+)'|(\S+)))?/ig;
var kAttributePattern = /\b(id|class)\s*(=\s*("([^"]+)"|'([^']+)'|(\S+)))?/ig;

let reAttrPattern =
var reAttrPattern =
/\b([a-z][a-z0-9\-]*)\s*(=\s*("([^"]+)"|'([^']+)'|(\S+)))?/ig;

let kBlockElements = {
div: true,
p: true,
li: true,
td: true,
section: true,
br: true
};

let kSelfClosingElements = {
var kSelfClosingElements = {
meta: true,
img: true,
link: true,
Expand All @@ -52,7 +44,7 @@ export function makeParser() {
hr: true
};

let kElementsClosedByOpening = {
var kElementsClosedByOpening = {
li: {
li: true
},
Expand All @@ -70,7 +62,7 @@ export function makeParser() {
}
};

let kElementsClosedByClosing = {
var kElementsClosedByClosing = {
li: {
ul: true, ol: true
},
Expand Down Expand Up @@ -108,12 +100,21 @@ export function makeParser() {
template: true
};

var escapeMap = {
'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
'"': '&quot;',
"'": '&#x27;',
'`': '&#x60;'
};

/**
* TextNode to contain a text element in DOM tree.
* @param {string} value [description]
*/
function TextNode(value) {
let instance = pools.elementObject.get();
var instance = pools.elementObject.get();

instance.nodeName = '#text';
instance.nodeValue = value;
Expand All @@ -135,7 +136,7 @@ export function makeParser() {
* @param {Object} rawAttrs attributes in string
*/
function HTMLElement(name, keyAttrs, rawAttrs) {
let instance = pools.elementObject.get();
var instance = pools.elementObject.get();

instance.nodeName = name;
instance.nodeValue = '';
Expand Down Expand Up @@ -163,18 +164,18 @@ export function makeParser() {
/**
* Parses HTML and returns a root element
*/
let htmlParser = {
var htmlParser = {
/**
* Parse a chuck of HTML source.
* @param {string} data html
* @return {HTMLElement} root element
*/
parse: function(data) {
let rootObject = {};
let root = HTMLElement(null, rootObject);
let currentParent = root;
let stack = [root];
let lastTextPos = -1;
var rootObject = {};
var root = HTMLElement(null, rootObject);
var currentParent = root;
var stack = [root];
var lastTextPos = -1;

if (data.indexOf('<') === -1 && data) {
currentParent.childNodes[currentParent.childNodes.length] = TextNode(data);
Expand Down Expand Up @@ -241,6 +242,10 @@ export function makeParser() {
let newText = data.slice(match.index + match[0].length, index);

if (newText.trim()) {
newText = slice.call(newText).map(ch => {
return escapeMap[ch] || ch;
}).join('');

currentParent.childNodes.push(TextNode(newText));
}

Expand Down
6 changes: 3 additions & 3 deletions test/integration/inner.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ describe('Integration: innerHTML', function() {
describe('Text', function() {
it('can decode HTML entities', function() {
diff.innerHTML(this.fixture, '<div>&lt;</div>');
assert.equal(this.fixture.innerText, '&lt;');
assert.equal(this.fixture.innerText, '<');
});

it('can be override existing content', function() {
Expand Down Expand Up @@ -79,10 +79,10 @@ describe('Integration: innerHTML', function() {
assert.equal(this.fixture.firstChild.firstChild, span, 'are the same element');
});

it('supports html5 entities', function() {
it('supports HTML5 entities', function() {
diff.innerHTML(this.fixture, '<div>&gla;</div>');

assert.equal(this.fixture.firstChild.innerText, '&gla;');
assert.equal(this.fixture.firstChild.innerText, '');
});
});

Expand Down
6 changes: 0 additions & 6 deletions test/integration/outer.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,12 +92,6 @@ describe('Integration: outerHTML', function() {
assert.equal(this.fixture.firstChild, span, 'are the same element');
});

it('supports HTML5 entities', function() {
diff.outerHTML(this.fixture, '<div>&gla;</div>');

assert.equal(this.fixture.innerText, '&gla;');
});

it('will properly escape markup being injected into script tags', function() {
diff.outerHTML(this.fixture, `
<div>
Expand Down

0 comments on commit a1c0b07

Please sign in to comment.