From 54ad041d0fa9f7d1d012a2ced0e1758d092fd024 Mon Sep 17 00:00:00 2001 From: Tim van der Lippe Date: Sat, 7 Apr 2018 14:44:14 +0200 Subject: [PATCH 1/5] Fix table element parsing in ie11 --- template.js | 36 ++++++++++++++++++++++++++++++++---- tests/basic.html | 26 +++++++++++++++++++++++--- 2 files changed, 55 insertions(+), 7 deletions(-) diff --git a/template.js b/template.js index 896af7e..d1ae823 100644 --- a/template.js +++ b/template.js @@ -194,7 +194,7 @@ */ PolyfilledHTMLTemplateElement.decorate = function(template) { // if the template is decorated or not in HTML namespace, return fast - if (template.content || + if (template.content || template.namespaceURI !== document.documentElement.namespaceURI) { return; } @@ -227,19 +227,47 @@ PolyfilledHTMLTemplateElement.bootstrap(template.content); }; + // Taken from https://github.com/jquery/jquery/blob/73d7e6259c63ac45f42c6593da8c2796c6ce9281/src/manipulation/wrapMap.js + var topLevelWrappingMap = { + thead: ['table'], + col: ['colgroup', 'table'], + tr: ['tbody', 'table'], + th: ['tr', 'tbody', 'table'], + td: ['tr', 'tbody', 'table'] + }; + + var getTagName = function(text) { + // Taken from https://github.com/jquery/jquery/blob/73d7e6259c63ac45f42c6593da8c2796c6ce9281/src/manipulation/var/rtagName.js + return ( /<([a-z][^/\0>\x20\t\r\n\f]+)/i.exec(text) || ['', ''])[1].toLowerCase(); + }; + var defineInnerHTML = function defineInnerHTML(obj) { Object.defineProperty(obj, 'innerHTML', { get: function() { return getInnerHTML(this); }, set: function(text) { + // For IE11, wrap the text in the correct (table) context + var wrap = topLevelWrappingMap[getTagName(text)]; + if (wrap) { + for (var i = 0; i < wrap.length; i++) { + text = '<' + wrap[i] + '>' + text + ''; + } + } contentDoc.body.innerHTML = text; PolyfilledHTMLTemplateElement.bootstrap(contentDoc); while (this.content.firstChild) { capturedRemoveChild.call(this.content, this.content.firstChild); } - while (contentDoc.body.firstChild) { - capturedAppendChild.call(this.content, contentDoc.body.firstChild); + var body = contentDoc.body; + // If we had wrapped, get back to the original node + if (wrap) { + for (var j = 0; j < wrap.length; j++) { + body = body.lastChild; + } + } + while (body.firstChild) { + capturedAppendChild.call(this.content, body.firstChild); } }, configurable: true @@ -486,7 +514,7 @@ } else { dom = importNode.call(this.ownerDocument, this, true); } - } else if (this.nodeType === Node.ELEMENT_NODE && + } else if (this.nodeType === Node.ELEMENT_NODE && this.localName === TEMPLATE_TAG && this.namespaceURI == document.documentElement.namespaceURI) { dom = PolyfilledHTMLTemplateElement._cloneNode(this, deep); diff --git a/tests/basic.html b/tests/basic.html index efe90aa..7a299d2 100644 --- a/tests/basic.html +++ b/tests/basic.html @@ -132,9 +132,7 @@ assert.equal(imp.innerHTML, s); }); - // Not yet working, as the setter of `innerHTML` moves the table elements - // into a non-table context, which are removed by the parser - test.skip('innerHTML (table elements)', function() { + test('innerHTML (tr element)', function() { if (!canInnerHTML) { this.skip(); } @@ -145,6 +143,28 @@ assert.equal(imp.innerHTML, s); }); + test('innerHTML (td element)', function() { + if (!canInnerHTML) { + this.skip(); + } + var imp = document.createElement('template'); + assert.equal(imp.innerHTML, ''); + var s = 'nothing'; + imp.innerHTML = s; + assert.equal(imp.innerHTML, s); + }); + + test('innerHTML (th element)', function() { + if (!canInnerHTML) { + this.skip(); + } + var imp = document.createElement('template'); + assert.equal(imp.innerHTML, ''); + var s = 'nothing'; + imp.innerHTML = s; + assert.equal(imp.innerHTML, s); + }); + test('clone', function() { var imp = document.createElement('template'); var s = '
Hi
'; From 683087f8262978fe0233285b5521d2b2cc58e24d Mon Sep 17 00:00:00 2001 From: Tim van der Lippe Date: Wed, 11 Apr 2018 11:44:32 +0200 Subject: [PATCH 2/5] Add missing tests --- tests/basic.html | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/tests/basic.html b/tests/basic.html index 7a299d2..eb8e4ff 100644 --- a/tests/basic.html +++ b/tests/basic.html @@ -165,6 +165,29 @@ assert.equal(imp.innerHTML, s); }); + test('innerHTML (col element)', function() { + if (!canInnerHTML) { + this.skip(); + } + var imp = document.createElement('template'); + assert.equal(imp.innerHTML, ''); + var s = ''; + imp.innerHTML = s; + assert.equal(imp.innerHTML, s); + }); + + test('innerHTML (thead element)', function() { + if (!canInnerHTML) { + this.skip(); + } + var imp = document.createElement('template'); + assert.equal(imp.innerHTML, ''); + var s = 'Header content 1Header content 2'; + imp.innerHTML = s; + assert.equal(imp.innerHTML, s); + }); + + test('clone', function() { var imp = document.createElement('template'); var s = '
Hi
'; From 3a3d5f6284fb4e9c720aafbceaf8b3b8027cb88c Mon Sep 17 00:00:00 2001 From: Tim van der Lippe Date: Tue, 17 Apr 2018 12:23:58 +0200 Subject: [PATCH 3/5] Fix parsing of option in select --- template.js | 1 + tests/basic.html | 10 ++++++++++ 2 files changed, 11 insertions(+) diff --git a/template.js b/template.js index d1ae823..b3d6ba2 100644 --- a/template.js +++ b/template.js @@ -229,6 +229,7 @@ // Taken from https://github.com/jquery/jquery/blob/73d7e6259c63ac45f42c6593da8c2796c6ce9281/src/manipulation/wrapMap.js var topLevelWrappingMap = { + option: ['select'], thead: ['table'], col: ['colgroup', 'table'], tr: ['tbody', 'table'], diff --git a/tests/basic.html b/tests/basic.html index eb8e4ff..a511e77 100644 --- a/tests/basic.html +++ b/tests/basic.html @@ -187,6 +187,16 @@ assert.equal(imp.innerHTML, s); }); + test('innerHTML (option element)', function() { + if (!canInnerHTML) { + this.skip(); + } + var imp = document.createElement('template'); + assert.equal(imp.innerHTML, ''); + var s = ''; + imp.innerHTML = s; + assert.equal(imp.innerHTML, s); + }); test('clone', function() { var imp = document.createElement('template'); From 5c302aa987c6b8a9576ae40efa86ddbefc3d0274 Mon Sep 17 00:00:00 2001 From: Tim van der Lippe Date: Tue, 17 Apr 2018 12:52:32 +0200 Subject: [PATCH 4/5] Fix compilation with Closure --- template.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/template.js b/template.js index b3d6ba2..b115d59 100644 --- a/template.js +++ b/template.js @@ -229,12 +229,12 @@ // Taken from https://github.com/jquery/jquery/blob/73d7e6259c63ac45f42c6593da8c2796c6ce9281/src/manipulation/wrapMap.js var topLevelWrappingMap = { - option: ['select'], - thead: ['table'], - col: ['colgroup', 'table'], - tr: ['tbody', 'table'], - th: ['tr', 'tbody', 'table'], - td: ['tr', 'tbody', 'table'] + ['option']: ['select'], + ['thead']: ['table'], + ['col']: ['colgroup', 'table'], + ['tr']: ['tbody', 'table'], + ['th']: ['tr', 'tbody', 'table'], + ['td']: ['tr', 'tbody', 'table'] }; var getTagName = function(text) { From a690841cad12c465f2f7826978b00d55c1f3a796 Mon Sep 17 00:00:00 2001 From: Tim van der Lippe Date: Tue, 17 Apr 2018 14:18:30 +0200 Subject: [PATCH 5/5] Fix eslint error on computed key --- template.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/template.js b/template.js index b115d59..a835251 100644 --- a/template.js +++ b/template.js @@ -229,12 +229,12 @@ // Taken from https://github.com/jquery/jquery/blob/73d7e6259c63ac45f42c6593da8c2796c6ce9281/src/manipulation/wrapMap.js var topLevelWrappingMap = { - ['option']: ['select'], - ['thead']: ['table'], - ['col']: ['colgroup', 'table'], - ['tr']: ['tbody', 'table'], - ['th']: ['tr', 'tbody', 'table'], - ['td']: ['tr', 'tbody', 'table'] + 'option': ['select'], + 'thead': ['table'], + 'col': ['colgroup', 'table'], + 'tr': ['tbody', 'table'], + 'th': ['tr', 'tbody', 'table'], + 'td': ['tr', 'tbody', 'table'] }; var getTagName = function(text) {