/** * @license * Copyright (c) 2016 The Polymer Project Authors. All rights reserved. * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt * Code distributed by Google as part of the polymer project is also * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt */ // minimal template polyfill (function() { 'use strict'; var needsTemplate = (typeof HTMLTemplateElement === 'undefined'); var brokenDocFragment = !(document.createDocumentFragment().cloneNode() instanceof DocumentFragment); var needsDocFrag = false; // NOTE: Replace DocumentFragment to work around IE11 bug that // causes children of a document fragment modified while // there is a mutation observer to not have a parentNode, or // have a broken parentNode (!?!) if (/Trident/.test(navigator.userAgent)) { (function() { needsDocFrag = true; var origCloneNode = Node.prototype.cloneNode; Node.prototype.cloneNode = function cloneNode(deep) { var newDom = origCloneNode.call(this, deep); if (this instanceof DocumentFragment) { newDom.__proto__ = DocumentFragment.prototype; } return newDom; }; // IE's DocumentFragment querySelector code doesn't work when // called on an element instance DocumentFragment.prototype.querySelectorAll = HTMLElement.prototype.querySelectorAll; DocumentFragment.prototype.querySelector = HTMLElement.prototype.querySelector; Object.defineProperties(DocumentFragment.prototype, { 'nodeType': { get: function () { return Node.DOCUMENT_FRAGMENT_NODE; }, configurable: true }, 'localName': { get: function () { return undefined; }, configurable: true }, 'nodeName': { get: function () { return '#document-fragment'; }, configurable: true } }); var origInsertBefore = Node.prototype.insertBefore; function insertBefore(newNode, refNode) { if (newNode instanceof DocumentFragment) { var child; while ((child = newNode.firstChild)) { origInsertBefore.call(this, child, refNode); } } else { origInsertBefore.call(this, newNode, refNode); } return newNode; } Node.prototype.insertBefore = insertBefore; var origAppendChild = Node.prototype.appendChild; Node.prototype.appendChild = function appendChild(child) { if (child instanceof DocumentFragment) { insertBefore.call(this, child, null); } else { origAppendChild.call(this, child); } return child; }; var origRemoveChild = Node.prototype.removeChild; var origReplaceChild = Node.prototype.replaceChild; Node.prototype.replaceChild = function replaceChild(newChild, oldChild) { if (newChild instanceof DocumentFragment) { insertBefore.call(this, newChild, oldChild); origRemoveChild.call(this, oldChild); } else { origReplaceChild.call(this, newChild, oldChild); } return oldChild; }; Document.prototype.createDocumentFragment = function createDocumentFragment() { var frag = this.createElement('df'); frag.__proto__ = DocumentFragment.prototype; return frag; }; var origImportNode = Document.prototype.importNode; Document.prototype.importNode = function importNode(impNode, deep) { deep = deep || false; var newNode = origImportNode.call(this, impNode, deep); if (impNode instanceof DocumentFragment) { newNode.__proto__ = DocumentFragment.prototype; } return newNode; }; })(); } // NOTE: we rely on this cloneNode not causing element upgrade. // This means this polyfill must load before the CE polyfill and // this would need to be re-worked if a browser supports native CE // but not