From fd5331f8cd82b9f5d9d19b2a0024e9eb4afa0229 Mon Sep 17 00:00:00 2001 From: StrahilKazlachev Date: Fri, 13 Oct 2017 15:02:29 +0300 Subject: [PATCH] fix(html-template-element): fix template.content.cloneNode where native support is missing fix aurelia/templating#569 --- karma.conf.js | 2 +- package.json | 3 +++ src/html-template-element.js | 44 ++++++++++++++++++++++++++++++++---- test/dom.spec.js | 40 ++++++++++++++++++++++++++++++++ test/setup.js | 1 + 5 files changed, 85 insertions(+), 5 deletions(-) diff --git a/karma.conf.js b/karma.conf.js index 1facd78..c94a3cf 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -14,7 +14,7 @@ module.exports = function(config) { jspm: { // Edit this to your needs - loadFiles: ['src/**/*.js', 'test/**/*.js'] + loadFiles: ['src/**/*.js', 'test/**/*.js', 'jspm_packages/system-polyfills.js'] }, diff --git a/package.json b/package.json index c5628b2..b19c685 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ "aurelia-pal": "^1.4.0" }, "devDependencies": { + "aurelia-polyfills": "^1.1.1", "babel": "babel-core@^5.8.22", "babel-runtime": "^5.8.20", "core-js": "^2.0.3" @@ -42,6 +43,7 @@ "aurelia-pal": "^1.4.0" }, "devDependencies": { + "aurelia-polyfills": "^1.1.1", "aurelia-tools": "^0.2.4", "babel-dts-generator": "^0.6.1", "babel-eslint": "^6.1.2", @@ -74,6 +76,7 @@ "karma-babel-preprocessor": "^6.0.1", "karma-chrome-launcher": "^1.0.1", "karma-coverage": "^1.1.1", + "karma-ie-launcher": "^1.0.0", "karma-jasmine": "^1.0.2", "karma-jspm": "^2.2.0", "merge2": "^1.0.2", diff --git a/src/html-template-element.js b/src/html-template-element.js index b3977a0..3a504e8 100644 --- a/src/html-template-element.js +++ b/src/html-template-element.js @@ -3,7 +3,7 @@ import {_FEATURE} from './feature'; if (typeof FEATURE_NO_IE === 'undefined') { function isSVGTemplate(el) { return el.tagName === 'template' && - el.namespaceURI === 'http://www.w3.org/2000/svg'; + el.namespaceURI === 'http://www.w3.org/2000/svg'; } function fixSVGTemplateElement(el) { @@ -36,9 +36,42 @@ if (typeof FEATURE_NO_IE === 'undefined') { return template; } + // replaces a #document-fragment .cloneNode + function __safeCloneNode(deep) { + const clone = this.standardCloneNode(deep); + if (deep) { + if (!this.__templates) { + // cache child templates on first call + // fix child templates on first call + this.__templates = this.querySelectorAll('template'); + let i = this.__templates.length; + while (i--) { + installSafeCloneNode(this.__templates.item(i)); + } + } + if (this.__templates.length) { + const clonedTemplates = clone.querySelectorAll('template'); + let i = clonedTemplates.length; + while (i--) { + clonedTemplates.item(i).content = this.__templates.item(i).content; + } + } + } + return clone; + } + + function installSafeCloneNode(template) { + if (!template.content.__safeToCloneNode) { + template.content.standardCloneNode = template.content.cloneNode; + template.content.cloneNode = __safeCloneNode; + template.content.__safeToCloneNode = true; + } + return template; + } + function fixHTMLTemplateElementRoot(template) { - let content = fixHTMLTemplateElement(template).content; - let childTemplates = content.querySelectorAll('template'); + const content = fixHTMLTemplateElement(template).content; + const childTemplates = content.querySelectorAll('template'); for (let i = 0, ii = childTemplates.length; i < ii; ++i) { let child = childTemplates[i]; @@ -48,12 +81,15 @@ if (typeof FEATURE_NO_IE === 'undefined') { } else { fixHTMLTemplateElement(child); } + // installSafeCloneNode(child); } + installSafeCloneNode(template); + return template; } - if (!_FEATURE.htmlTemplateElement) { + if (!_FEATURE.htmlTemplateElement) { _FEATURE.ensureHTMLTemplateElement = fixHTMLTemplateElementRoot; } } diff --git a/test/dom.spec.js b/test/dom.spec.js index 90ef088..edac74b 100644 --- a/test/dom.spec.js +++ b/test/dom.spec.js @@ -1,4 +1,5 @@ import {_DOM} from '../src/dom'; +import {_FEATURE} from '../src/feature'; describe('dom', () => { describe('createTemplateFromMarkup', () => { @@ -13,6 +14,12 @@ describe('dom', () => { it('should throw an error when creating a template from markup where