Home | History | Annotate | Download | only in platform

Lines Matching full:childlist

1    if (descriptor.writable || descriptor.set) {\n        if (isEvent)\n          setter = scope.getEventHandlerSetter(name);\n        else\n          setter = getSetter(name);\n      }\n\n      defineProperty(target, name, {\n        get: getter,\n        set: setter,\n        configurable: descriptor.configurable,\n        enumerable: descriptor.enumerable\n      });\n    }\n  }\n\n  /**\n   * @param {Function} nativeConstructor\n   * @param {Function} wrapperConstructor\n   * @param {Object=} opt_instance If present, this is used to extract\n   *     properties from an instance object.\n   */\n  function register(nativeConstructor, wrapperConstructor, opt_instance) {\n    var nativePrototype = nativeConstructor.prototype;\n    registerInternal(nativePrototype, wrapperConstructor, opt_instance);\n    mixinStatics(wrapperConstructor, nativeConstructor);\n  }\n\n  function registerInternal(nativePrototype, wrapperConstructor, opt_instance) {\n    var wrapperPrototype = wrapperConstructor.prototype;\n    assert(constructorTable.get(nativePrototype) === undefined);\n\n    constructorTable.set(nativePrototype, wrapperConstructor);\n    nativePrototypeTable.set(wrapperPrototype, nativePrototype);\n\n    addForwardingProperties(nativePrototype, wrapperPrototype);\n    if (opt_instance)\n      registerInstanceProperties(wrapperPrototype, opt_instance);\n\n    defineNonEnumerableDataProperty(\n        wrapperPrototype, 'constructor', wrapperConstructor);\n    // Set it again. Some VMs optimizes objects that are used as prototypes.\n    wrapperConstructor.prototype = wrapperPrototype;\n  }\n\n  function isWrapperFor(wrapperConstructor, nativeConstructor) {\n    return constructorTable.get(nativeConstructor.prototype) ===\n        wrapperConstructor;\n  }\n\n  /**\n   * Creates a generic wrapper constructor based on |object| and its\n   * constructor.\n   * @param {Node} object\n   * @return {Function} The generated constructor.\n   */\n  function registerObject(object) {\n    var nativePrototype = Object.getPrototypeOf(object);\n\n    var superWrapperConstructor = getWrapperConstructor(nativePrototype);\n    var GeneratedWrapper = createWrapperConstructor(superWrapperConstructor);\n    registerInternal(nativePrototype, GeneratedWrapper, object);\n\n    return GeneratedWrapper;\n  }\n\n  function createWrapperConstructor(superWrapperConstructor) {\n    function GeneratedWrapper(node) {\n      superWrapperConstructor.call(this, node);\n    }\n    var p = Object.create(superWrapperConstructor.prototype);\n    p.constructor = GeneratedWrapper;\n    GeneratedWrapper.prototype = p;\n\n    return GeneratedWrapper;\n  }\n\n  var OriginalDOMImplementation = window.DOMImplementation;\n  var OriginalEventTarget = window.EventTarget;\n  var OriginalEvent = window.Event;\n  var OriginalNode = window.Node;\n  var OriginalWindow = window.Window;\n  var OriginalRange = window.Range;\n  var OriginalCanvasRenderingContext2D = window.CanvasRenderingContext2D;\n  var OriginalWebGLRenderingContext = window.WebGLRenderingContext;\n  var OriginalSVGElementInstance = window.SVGElementInstance;\n  var OriginalFormData = window.FormData;\n  \n  function isWrapper(object) {\n    return object instanceof wrappers.EventTarget ||\n           object instanceof wrappers.Event ||\n           object instanceof wrappers.Range ||\n           object instanceof wrappers.DOMImplementation ||\n           object instanceof wrappers.CanvasRenderingContext2D ||\n           object instanceof wrappers.FormData ||\n           wrappers.WebGLRenderingContext &&\n               object instanceof wrappers.WebGLRenderingContext;\n  }\n\n  function isNative(object) {\n    return OriginalEventTarget && object instanceof OriginalEventTarget ||\n           object instanceof OriginalNode ||\n           object instanceof OriginalEvent ||\n           object instanceof OriginalWindow ||\n           object instanceof OriginalRange ||\n           object instanceof OriginalDOMImplementation ||\n           object instanceof OriginalCanvasRenderingContext2D ||\n           object instanceof OriginalFormData ||\n           OriginalWebGLRenderingContext &&\n               object instanceof OriginalWebGLRenderingContext ||\n           OriginalSVGElementInstance &&\n               object instanceof OriginalSVGElementInstance;\n  }\n\n  /**\n   * Wraps a node in a WrapperNode. If there already exists a wrapper for the\n   * |node| that wrapper is returned instead.\n   * @param {Node} node\n   * @return {WrapperNode}\n   */\n  function wrap(impl) {\n    if (impl === null)\n      return null;\n\n    assert(isNative(impl));\n    return impl.polymerWrapper_ ||\n        (impl.polymerWrapper_ = new (getWrapperConstructor(impl))(impl));\n  }\n\n  /**\n   * Unwraps a wrapper and returns the node it is wrapping.\n   * @param {WrapperNode} wrapper\n   * @return {Node}\n   */\n  function unwrap(wrapper) {\n    if (wrapper === null)\n      return null;\n    assert(isWrapper(wrapper));\n    return wrapper.impl;\n  }\n\n  /**\n   * Unwraps object if it is a wrapper.\n   * @param {Object} object\n   * @return {Object} The native implementation object.\n   */\n  function unwrapIfNeeded(object) {\n    return object && isWrapper(object) ? unwrap(object) : object;\n  }\n\n  /**\n   * Wraps object if it is not a wrapper.\n   * @param {Object} object\n   * @return {Object} The wrapper for object.\n   */\n  function wrapIfNeeded(object) {\n    return object && !isWrapper(object) ? wrap(object) : object;\n  }\n\n  /**\n   * Overrides the current wrapper (if any) for node.\n   * @param {Node} node\n   * @param {WrapperNode=} wrapper If left out the wrapper will be created as\n   *     needed next time someone wraps the node.\n   */\n  function rewrap(node, wrapper) {\n    if (wrapper === null)\n      return;\n    assert(isNative(node));\n    assert(wrapper === undefined || isWrapper(wrapper));\n    node.polymerWrapper_ = wrapper;\n  }\n\n  var getterDescriptor = {\n    get: undefined,\n    configurable: true,\n    enumerable: true\n  };\n\n  function defineGetter(constructor, name, getter) {\n    getterDescriptor.get = getter;\n    defineProperty(constructor.prototype, name, getterDescriptor);\n  }\n\n  function defineWrapGetter(constructor, name) {\n    defineGetter(constructor, name, function() {\n      return wrap(this.impl[name]);\n    });\n  }\n\n  /**\n   * Forwards existing methods on the native object to the wrapper methods.\n   * This does not wrap any of the arguments or the return value since the\n   * wrapper implementation already takes care of that.\n   * @param {Array.<Function>} constructors\n   * @parem {Array.<string>} names\n   */\n  function forwardMethodsToWrapper(constructors, names) {\n    constructors.forEach(function(constructor) {\n      names.forEach(function(name) {\n        constructor.prototype[name] = function() {\n          var w = wrapIfNeeded(this);\n          return w[name].apply(w, arguments);\n        };\n      });\n    });\n  }\n\n  scope.assert = assert;\n  scope.constructorTable = constructorTable;\n  scope.defineGetter = defineGetter;\n  scope.defineWrapGetter = defineWrapGetter;\n  scope.forwardMethodsToWrapper = forwardMethodsToWrapper;\n  scope.isWrapper = isWrapper;\n  scope.isWrapperFor = isWrapperFor;\n  scope.mixin = mixin;\n  scope.nativePrototypeTable = nativePrototypeTable;\n  scope.oneOf = oneOf;\n  scope.registerObject = registerObject;\n  scope.registerWrapper = register;\n  scope.rewrap = rewrap;\n  scope.unwrap = unwrap;\n  scope.unwrapIfNeeded = unwrapIfNeeded;\n  scope.wrap = wrap;\n  scope.wrapIfNeeded = wrapIfNeeded;\n  scope.wrappers = wrappers;\n\n})(window.ShadowDOMPolyfill);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is goverened by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n(function(context) {\n  'use strict';\n\n  var OriginalMutationObserver = window.MutationObserver;\n  var callbacks = [];\n  var pending = false;\n  var timerFunc;\n\n  function handle() {\n    pending = false;\n    var copies = callbacks.slice(0);\n    callbacks = [];\n    for (var i = 0; i < copies.length; i++) {\n      (0, copies[i])();\n    }\n  }\n\n  if (OriginalMutationObserver) {\n    var counter = 1;\n    var observer = new OriginalMutationObserver(handle);\n    var textNode = document.createTextNode(counter);\n    observer.observe(textNode, {characterData: true});\n\n    timerFunc = function() {\n      counter = (counter + 1) % 2;\n      textNode.data = counter;\n    };\n\n  } else {\n    timerFunc = window.setImmediate || window.setTimeout;\n  }\n\n  function setEndOfMicrotask(func) {\n    callbacks.push(func);\n    if (pending)\n      return;\n    pending = true;\n    timerFunc(handle, 0);\n  }\n\n  context.setEndOfMicrotask = setEndOfMicrotask;\n\n})(window.ShadowDOMPolyfill);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is goverened by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n(function(scope) {\n  'use strict';\n\n  var setEndOfMicrotask = scope.setEndOfMicrotask\n  var wrapIfNeeded = scope.wrapIfNeeded\n  var wrappers = scope.wrappers;\n\n  var registrationsTable = new WeakMap();\n  var globalMutationObservers = [];\n  var isScheduled = false;\n\n  function scheduleCallback(observer) {\n    if (isScheduled)\n      return;\n    setEndOfMicrotask(notifyObservers);\n    isScheduled = true;\n  }\n\n  // http://dom.spec.whatwg.org/#mutation-observers\n  function notifyObservers() {\n    isScheduled = false;\n\n    do {\n      var notifyList = globalMutationObservers.slice();\n      var anyNonEmpty = false;\n      for (var i = 0; i < notifyList.length; i++) {\n        var mo = notifyList[i];\n        var queue = mo.takeRecords();\n        removeTransientObserversFor(mo);\n        if (queue.length) {\n          mo.callback_(queue, mo);\n          anyNonEmpty = true;\n        }\n      }\n    } while (anyNonEmpty);\n  }\n\n  /**\n   * @param {string} type\n   * @param {Node} target\n   * @constructor\n   */\n  function MutationRecord(type, target) {\n    this.type = type;\n    this.target = target;\n    this.addedNodes = new wrappers.NodeList();\n    this.removedNodes = new wrappers.NodeList();\n    this.previousSibling = null;\n    this.nextSibling = null;\n    this.attributeName = null;\n    this.attributeNamespace = null;\n    this.oldValue = null;\n  }\n\n  /**\n   * Registers transient observers to ancestor and its ancesors for the node\n   * which was removed.\n   * @param {!Node} ancestor\n   * @param {!Node} node\n   */\n  function registerTransientObservers(ancestor, node) {\n    for (; ancestor; ancestor = ancestor.parentNode) {\n      var registrations = registrationsTable.get(ancestor);\n      if (!registrations)\n        continue;\n      for (var i = 0; i < registrations.length; i++) {\n        var registration = registrations[i];\n        if (registration.options.subtree)\n          registration.addTransientObserver(node);\n      }\n    }\n  }\n\n  function removeTransientObserversFor(observer) {\n    for (var i = 0; i < observer.nodes_.length; i++) {\n      var node = observer.nodes_[i];\n      var registrations = registrationsTable.get(node);\n      if (!registrations)\n        return;\n      for (var j = 0; j < registrations.length; j++) {\n        var registration = registrations[j];\n        if (registration.observer === observer)\n          registration.removeTransientObservers();\n      }\n    }\n  }\n\n  // http://dom.spec.whatwg.org/#queue-a-mutation-record\n  function enqueueMutation(target, type, data) {\n    // 1.\n    var interestedObservers = Object.create(null);\n    var associatedStrings = Object.create(null);\n\n    // 2.\n    for (var node = target; node; node = node.parentNode) {\n      // 3.\n      var registrations = registrationsTable.get(node);\n      if (!registrations)\n        continue;\n      for (var j = 0; j < registrations.length; j++) {\n        var registration = registrations[j];\n        var options = registration.options;\n        // 1.\n        if (node !== target && !options.subtree)\n          continue;\n\n        // 2.\n        if (type === 'attributes' && !options.attributes)\n          continue;\n\n        // 3. If type is \"attributes\", options's attributeFilter is present, and\n        // either options's attributeFilter does not contain name or namespace\n        // is non-null, continue.\n        if (type === 'attributes' && options.attributeFilter &&\n            (data.namespace !== null ||\n             options.attributeFilter.indexOf(data.name) === -1)) {\n          continue;\n        }\n\n        // 4.\n        if (type === 'characterData' && !options.characterData)\n          continue;\n\n        // 5.\n        if (type === 'childList' && !options.childList)\n          continue;\n\n        // 6.\n        var observer = registration.observer;\n        interestedObservers[observer.uid_] = observer;\n\n        // 7. If either type is \"attributes\" and options's attributeOldValue is\n        // true, or type is \"characterData\" and options's characterDataOldValue\n        // is true, set the paired string of registered observer's observer in\n        // interested observers to oldValue.\n        if (type === 'attributes' && options.attributeOldValue ||\n            type === 'characterData' && options.characterDataOldValue) {\n          associatedStrings[observer.uid_] = data.oldValue;\n        }\n      }\n    }\n\n    var anyRecordsEnqueued = false;\n\n    // 4.\n    for (var uid in interestedObservers) {\n      var observer = interestedObservers[uid];\n      var record = new MutationRecord(type, target);\n\n      // 2.\n      if ('name' in data && 'namespace' in data) {\n        record.attributeName = data.name;\n        record.attributeNamespace = data.namespace;\n      }\n\n      // 3.\n      if (data.addedNodes)\n        record.addedNodes = data.addedNodes;\n\n      // 4.\n      if (data.removedNodes)\n        record.removedNodes = data.removedNodes;\n\n      // 5.\n      if (data.previousSibling)\n        record.previousSibling = data.previousSibling;\n\n      // 6.\n      if (data.nextSibling)\n        record.nextSibling = data.nextSibling;\n\n      // 7.\n      if (associatedStrings[uid] !== undefined)\n        record.oldValue = associatedStrings[uid];\n\n      // 8.\n      observer.records_.push(record);\n\n      anyRecordsEnqueued = true;\n    }\n\n    if (anyRecordsEnqueued)\n      scheduleCallback();\n  }\n\n  var slice = Array.prototype.slice;\n\n  /**\n   * @param {!Object} options\n   * @constructor\n   */\n  function MutationObserverOptions(options) {\n    this.childList = !!options.childListchildList', {\n      removedNodes: nodes,\n      previousSibling: node.previousSibling,\n      nextSibling: node.nextSibling\n    });\n  }\n\n  function enqueueRemovalForInsertedDocumentFragment(df, nodes) {\n    enqueueMutation(df, 'childListchildList', {\n        addedNodes: nodes,\n        nextSibling: refWrapper,\n        previousSibling: previousNode\n      });\n\n      nodesWereAdded(nodes, this);\n\n      return childWrapper;\n    },\n\n    removeChild: function(childWrapper) {\n      assertIsNodeWrapper(childWrapper);\n      if (childWrapper.parentNode !== this) {\n        // IE has invalid DOM trees at times.\n        var found = false;\n        var childNodes = this.childNodes;\n        for (var ieChild = this.firstChild; ieChild;\n             ieChild = ieChild.nextSibling) {\n          if (ieChild === childWrapper) {\n            found = true;\n            break;\n          }\n        }\n        if (!found) {\n          // TODO(arv): DOMException\n          throw new Error('NotFoundError');\n        }\n      }\n\n      var childNode = unwrap(childWrapper);\n      var childWrapperNextSibling = childWrapper.nextSibling;\n      var childWrapperPreviousSibling = childWrapper.previousSibling;\n\n      if (this.invalidateShadowRenderer()) {\n        // We need to remove the real node from the DOM before updating the\n        // pointers. This is so that that mutation event is dispatched before\n        // the pointers have changed.\n        var thisFirstChild = this.firstChild;\n        var thisLastChild = this.lastChild;\n\n        var parentNode = childNode.parentNode;\n        if (parentNode)\n          removeChildOriginalHelper(parentNode, childNode);\n\n        if (thisFirstChild === childWrapper)\n          this.firstChild_ = childWrapperNextSibling;\n        if (thisLastChild === childWrapper)\n          this.lastChild_ = childWrapperPreviousSibling;\n        if (childWrapperPreviousSibling)\n          childWrapperPreviousSibling.nextSibling_ = childWrapperNextSibling;\n        if (childWrapperNextSibling) {\n          childWrapperNextSibling.previousSibling_ =\n              childWrapperPreviousSibling;\n        }\n\n        childWrapper.previousSibling_ = childWrapper.nextSibling_ =\n            childWrapper.parentNode_ = undefined;\n      } else {\n        clearChildNodes(this);\n        removeChildOriginalHelper(this.impl, childNode);\n      }\n\n      if (!surpressMutations) {\n        enqueueMutation(this, 'childList', {\n          removedNodes: createOneElementNodeList(childWrapper),\n          nextSibling: childWrapperNextSibling,\n          previousSibling: childWrapperPreviousSibling\n        });\n      }\n\n      registerTransientObservers(this, childWrapper);\n\n      return childWrapper;\n    },\n\n    replaceChild: function(newChildWrapper, oldChildWrapper) {\n      assertIsNodeWrapper(newChildWrapper);\n\n      var oldChildNode;\n      if (isWrapper(oldChildWrapper)) {\n        oldChildNode = unwrap(oldChildWrapper);\n      } else {\n        oldChildNode = oldChildWrapper;\n        oldChildWrapper = wrap(oldChildNode);\n      }\n\n      if (oldChildWrapper.parentNode !== this) {\n        // TODO(arv): DOMException\n        throw new Error('NotFoundError');\n      }\n\n      var nextNode = oldChildWrapper.nextSibling;\n      var previousNode = oldChildWrapper.previousSibling;\n      var nodes;\n\n      var useNative = !this.invalidateShadowRenderer() &&\n                      !invalidateParent(newChildWrapper);\n\n      if (useNative) {\n        nodes = collectNodesNative(newChildWrapper);\n      } else {\n        if (nextNode === newChildWrapper)\n          nextNode = newChildWrapper.nextSibling;\n        nodes = collectNodes(newChildWrapper, this, previousNode, nextNode);\n      }\n\n      if (!useNative) {\n        if (this.firstChild === oldChildWrapper)\n          this.firstChild_ = nodes[0];\n        if (this.lastChild === oldChildWrapper)\n          this.lastChild_ = nodes[nodes.length - 1];\n\n        oldChildWrapper.previousSibling_ = oldChildWrapper.nextSibling_ =\n            oldChildWrapper.parentNode_ = undefined;\n\n        // replaceChild no matter what the parent is?\n        if (oldChildNode.parentNode) {\n          originalReplaceChild.call(\n              oldChildNode.parentNode,\n              unwrapNodesForInsertion(this, nodes),\n              oldChildNode);\n        }\n      } else {\n        ensureSameOwnerDocument(this, newChildWrapper);\n        clearChildNodes(this);\n        originalReplaceChild.call(this.impl, unwrap(newChildWrapper),\n                                  oldChildNode);\n      }\n\n      enqueueMutation(this, 'childList', {\n        addedNodes: nodes,\n        removedNodes: createOneElementNodeList(oldChildWrapper),\n        nextSibling: nextNode,\n        previousSibling: previousNode\n      });\n\n      nodeWasRemoved(oldChildWrapper);\n      nodesWereAdded(nodes, this);\n\n      return oldChildWrapper;\n    },\n\n    /**\n     * Called after a node was inserted. Subclasses override this to invalidate\n     * the renderer as needed.\n     * @private\n     */\n    nodeIsInserted_: function() {\n      for (var child = this.firstChild; child; child = child.nextSibling) {\n        child.nodeIsInserted_();\n      }\n    },\n\n    hasChildNodes: function() {\n      return this.firstChild !== null;\n    },\n\n    /** @type {Node} */\n    get parentNode() {\n      // If the parentNode has not been overridden, use the original parentNode.\n      return this.parentNode_ !== undefined ?\n          this.parentNode_ : wrap(this.impl.parentNode);\n    },\n\n    /** @type {Node} */\n    get firstChild() {\n      return this.firstChild_ !== undefined ?\n          this.firstChild_ : wrap(this.impl.firstChild);\n    },\n\n    /** @type {Node} */\n    get lastChild() {\n      return this.lastChild_ !== undefined ?\n          this.lastChild_ : wrap(this.impl.lastChild);\n    },\n\n    /** @type {Node} */\n    get nextSibling() {\n      return this.nextSibling_ !== undefined ?\n          this.nextSibling_ : wrap(this.impl.nextSibling);\n    },\n\n    /** @type {Node} */\n    get previousSibling() {\n      return this.previousSibling_ !== undefined ?\n          this.previousSibling_ : wrap(this.impl.previousSibling);\n    },\n\n    get parentElement() {\n      var p = this.parentNode;\n      while (p && p.nodeType !== Node.ELEMENT_NODE) {\n        p = p.parentNode;\n      }\n      return p;\n    },\n\n    get textContent() {\n      // TODO(arv): This should fallback to this.impl.textContent if there\n      // are no shadow trees below or above the context node.\n      var s = '';\n      for (var child = this.firstChild; child; child = child.nextSibling) {\n        if (child.nodeType != Node.COMMENT_NODE) {\n          s += child.textContent;\n        }\n      }\n      return s;\n    },\n    set textContent(textContent) {\n      var removedNodes = snapshotNodeList(this.childNodes);\n\n      if (this.invalidateShadowRenderer()) {\n        removeAllChildNodes(this);\n        if (textContent !== '') {\n          var textNode = this.impl.ownerDocument.createTextNode(textContent);\n          this.appendChild(textNode);\n        }\n      } else {\n        clearChildNodes(this);\n        this.impl.textContent = textContent;\n      }\n\n      var addedNodes = snapshotNodeList(this.childNodes);\n\n      enqueueMutation(this, 'childListchildList, l = s.length - 1; i < l; i++) {\n    t.unshift('..');\n  }\n  return t.join('/') + targetUrl.search + targetUrl.hash;\n}\n\n// exports\nscope.urlResolver = urlResolver;\n\n})(Platform);\n","/*\n * Copyright 2012 The Polymer Authors. All rights reserved.\n * Use of this source code is goverened by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n(function(global) {\n\n  var registrationsTable = new WeakMap();\n\n  // We use setImmediate or postMessage for our future callback.\n  var setImmediate = window.msSetImmediate;\n\n  // Use post message to emulate setImmediate.\n  if (!setImmediate) {\n    var setImmediateQueue = [];\n    var sentinel = String(Math.random());\n    window.addEventListener('message', function(e) {\n      if (e.data === sentinel) {\n        var queue = setImmediateQueue;\n        setImmediateQueue = [];\n        queue.forEach(function(func) {\n          func();\n        });\n      }\n    });\n    setImmediate = function(func) {\n      setImmediateQueue.push(func);\n      window.postMessage(sentinel, '*');\n    };\n  }\n\n  // This is used to ensure that we never schedule 2 callas to setImmediate\n  var isScheduled = false;\n\n  // Keep track of observers that needs to be notified next time.\n  var scheduledObservers = [];\n\n  /**\n   * Schedules |dispatchCallback| to be called in the future.\n   * @param {MutationObserver} observer\n   */\n  function scheduleCallback(observer) {\n    scheduledObservers.push(observer);\n    if (!isScheduled) {\n      isScheduled = true;\n      setImmediate(dispatchCallbacks);\n    }\n  }\n\n  function wrapIfNeeded(node) {\n    return window.ShadowDOMPolyfill &&\n        window.ShadowDOMPolyfill.wrapIfNeeded(node) ||\n        node;\n  }\n\n  function dispatchCallbacks() {\n    // http://dom.spec.whatwg.org/#mutation-observers\n\n    isScheduled = false; // Used to allow a new setImmediate call above.\n\n    var observers = scheduledObservers;\n    scheduledObservers = [];\n    // Sort observers based on their creation UID (incremental).\n    observers.sort(function(o1, o2) {\n      return o1.uid_ - o2.uid_;\n    });\n\n    var anyNonEmpty = false;\n    observers.forEach(function(observer) {\n\n      // 2.1, 2.2\n      var queue = observer.takeRecords();\n      // 2.3. Remove all transient registered observers whose observer is mo.\n      removeTransientObserversFor(observer);\n\n      // 2.4\n      if (queue.length) {\n        observer.callback_(queue, observer);\n        anyNonEmpty = true;\n      }\n    });\n\n    // 3.\n    if (anyNonEmpty)\n      dispatchCallbacks();\n  }\n\n  function removeTransientObserversFor(observer) {\n    observer.nodes_.forEach(function(node) {\n      var registrations = registrationsTable.get(node);\n      if (!registrations)\n        return;\n      registrations.forEach(function(registration) {\n        if (registration.observer === observer)\n          registration.removeTransientObservers();\n      });\n    });\n  }\n\n  /**\n   * This function is used for the \"For each registered observer observer (with\n   * observer's options as options) in target's list of registered observers,\n   * run these substeps:\" and the \"For each ancestor ancestor of target, and for\n   * each registered observer observer (with options options) in ancestor's list\n   * of registered observers, run these substeps:\" part of the algorithms. The\n   * |options.subtree| is checked to ensure that the callback is called\n   * correctly.\n   *\n   * @param {Node} target\n   * @param {function(MutationObserverInit):MutationRecord} callback\n   */\n  function forEachAncestorAndObserverEnqueueRecord(target, callback) {\n    for (var node = target; node; node = node.parentNode) {\n      var registrations = registrationsTable.get(node);\n\n      if (registrations) {\n        for (var j = 0; j < registrations.length; j++) {\n          var registration = registrations[j];\n          var options = registration.options;\n\n          // Only target ignores subtree.\n          if (node !== target && !options.subtree)\n            continue;\n\n          var record = callback(options);\n          if (record)\n            registration.enqueue(record);\n        }\n      }\n    }\n  }\n\n  var uidCounter = 0;\n\n  /**\n   * The class that maps to the DOM MutationObserver interface.\n   * @param {Function} callback.\n   * @constructor\n   */\n  function JsMutationObserver(callback) {\n    this.callback_ = callback;\n    this.nodes_ = [];\n    this.records_ = [];\n    this.uid_ = ++uidCounter;\n  }\n\n  JsMutationObserver.prototype = {\n    observe: function(target, options) {\n      target = wrapIfNeeded(target);\n\n      // 1.1\n      if (!options.childList && !options.attributes && !options.characterData ||\n\n          // 1.2\n          options.attributeOldValue && !options.attributes ||\n\n          // 1.3\n          options.attributeFilter && options.attributeFilter.length &&\n              !options.attributes ||\n\n          // 1.4\n          options.characterDataOldValue && !options.characterData) {\n\n        throw new SyntaxError();\n      }\n\n      var registrations = registrationsTable.get(target);\n      if (!registrations)\n        registrationsTable.set(target, registrations = []);\n\n      // 2\n      // If target's list of registered observers already includes a registered\n      // observer associated with the context object, replace that registered\n      // observer's options with options.\n      var registration;\n      for (var i = 0; i < registrations.length; i++) {\n        if (registrations[i].observer === this) {\n          registration = registrations[i];\n          registration.removeListeners();\n          registration.options = options;\n          break;\n        }\n      }\n\n      // 3.\n      // Otherwise, add a new registered observer to target's list of registered\n      // observers with the context object as the observer and options as the\n      // options, and add target to context object's list of nodes on which it\n      // is registered.\n      if (!registration) {\n        registration = new Registration(this, target, options);\n        registrations.push(registration);\n        this.nodes_.push(target);\n      }\n\n      registration.addListeners();\n    },\n\n    disconnect: function() {\n      this.nodes_.forEach(function(node) {\n        var registrations = registrationsTable.get(node);\n        for (var i = 0; i < registrations.length; i++) {\n          var registration = registrations[i];\n          if (registration.observer === this) {\n            registration.removeListeners();\n            registrations.splice(i, 1);\n            // Each node can only have one registered observer associated with\n            // this observer.\n            break;\n          }\n        }\n      }, this);\n      this.records_ = [];\n    },\n\n    takeRecords: function() {\n      var copyOfRecords = this.records_;\n      this.records_ = [];\n      return copyOfRecords;\n    }\n  };\n\n  /**\n   * @param {string} type\n   * @param {Node} target\n   * @constructor\n   */\n  function MutationRecord(type, target) {\n    this.type = type;\n    this.target = target;\n    this.addedNodes = [];\n    this.removedNodes = [];\n    this.previousSibling = null;\n    this.nextSibling = null;\n    this.attributeName = null;\n    this.attributeNamespace = null;\n    this.oldValue = null;\n  }\n\n  function copyMutationRecord(original) {\n    var record = new MutationRecord(original.type, original.target);\n    record.addedNodes = original.addedNodes.slice();\n    record.removedNodes = original.removedNodes.slice();\n    record.previousSibling = original.previousSibling;\n    record.nextSibling = original.nextSibling;\n    record.attributeName = original.attributeName;\n    record.attributeNamespace = original.attributeNamespace;\n    record.oldValue = original.oldValue;\n    return record;\n  };\n\n  // We keep track of the two (possibly one) records used in a single mutation.\n  var currentRecord, recordWithOldValue;\n\n  /**\n   * Creates a record without |oldValue| and caches it as |currentRecord| for\n   * later use.\n   * @param {string} oldValue\n   * @return {MutationRecord}\n   */\n  function getRecord(type, target) {\n    return currentRecord = new MutationRecord(type, target);\n  }\n\n  /**\n   * Gets or creates a record with |oldValue| based in the |currentRecord|\n   * @param {string} oldValue\n   * @return {MutationRecord}\n   */\n  function getRecordWithOldValue(oldValue) {\n    if (recordWithOldValue)\n      return recordWithOldValue;\n    recordWithOldValue = copyMutationRecord(currentRecord);\n    recordWithOldValue.oldValue = oldValue;\n    return recordWithOldValue;\n  }\n\n  function clearRecords() {\n    currentRecord = recordWithOldValue = undefined;\n  }\n\n  /**\n   * @param {MutationRecord} record\n   * @return {boolean} Whether the record represents a record from the current\n   * mutation event.\n   */\n  function recordRepresentsCurrentMutation(record) {\n    return record === recordWithOldValue || record === currentRecord;\n  }\n\n  /**\n   * Selects which record, if any, to replace the last record in the queue.\n   * This returns |null| if no record should be replaced.\n   *\n   * @param {MutationRecord} lastRecord\n   * @param {MutationRecord} newRecord\n   * @param {MutationRecord}\n   */\n  function selectRecord(lastRecord, newRecord) {\n    if (lastRecord === newRecord)\n      return lastRecord;\n\n    // Check if the the record we are adding represents the same record. If\n    // so, we keep the one with the oldValue in it.\n    if (recordWithOldValue && recordRepresentsCurrentMutation(lastRecord))\n      return recordWithOldValue;\n\n    return null;\n  }\n\n  /**\n   * Class used to represent a registered observer.\n   * @param {MutationObserver} observer\n   * @param {Node} target\n   * @param {MutationObserverInit} options\n   * @constructor\n   */\n  function Registration(observer, target, options) {\n    this.observer = observer;\n    this.target = target;\n    this.options = options;\n    this.transientObservedNodes = [];\n  }\n\n  Registration.prototype = {\n    enqueue: function(record) {\n      var records = this.observer.records_;\n      var length = records.length;\n\n      // There are cases where we replace the last record with the new record.\n      // For example if the record represents the same mutation we need to use\n      // the one with the oldValue. If we get same record (this can happen as we\n      // walk up the tree) we ignore the new record.\n      if (records.length > 0) {\n        var lastRecord = records[length - 1];\n        var recordToReplaceLast = selectRecord(lastRecord, record);\n        if (recordToReplaceLast) {\n          records[length - 1] = recordToReplaceLast;\n          return;\n        }\n      } else {\n        scheduleCallback(this.observer);\n      }\n\n      records[length] = record;\n    },\n\n    addListeners: function() {\n      this.addListeners_(this.target);\n    },\n\n    addListeners_: function(node) {\n      var options = this.options;\n      if (options.attributes)\n        node.addEventListener('DOMAttrModified', this, true);\n\n      if (options.characterData)\n        node.addEventListener('DOMCharacterDataModified', this, true);\n\n      if (options.childList)\n        node.addEventListener('DOMNodeInserted', this, true);\n\n      if (options.childList || options.subtree)\n        node.addEventListener('DOMNodeRemoved', this, true);\n    },\n\n    removeListeners: function() {\n      this.removeListeners_(this.target);\n    },\n\n    removeListeners_: function(node) {\n      var options = this.options;\n      if (options.attributes)\n        node.removeEventListener('DOMAttrModified', this, true);\n\n      if (options.characterData)\n        node.removeEventListener('DOMCharacterDataModified', this, true);\n\n      if (options.childList)\n        node.removeEventListener('DOMNodeInserted', this, true);\n\n      if (options.childListchildlist\n          var target = e.relatedNode;\n          var changedNode = e.target;\n          var addedNodes, removedNodes;\n          if (e.type === 'DOMNodeInserted') {\n            addedNodes = [changedNode];\n            removedNodes = [];\n          } else {\n\n            addedNodes = [];\n            removedNodes = [changedNode];\n          }\n          var previousSibling = changedNode.previousSibling;\n          var nextSibling = changedNode.nextSibling;\n\n          // 1.\n          var record = getRecord('childList', target);\n          record.addedNodes = addedNodes;\n          record.removedNodes = removedNodes;\n          record.previousSibling = previousSibling;\n          record.nextSibling = nextSibling;\n\n          forEachAncestorAndObserverEnqueueRecord(target, function(options) {\n            // 2.1, 3.2\n            if (!options.childList.\nfunction cloneStyle(style) {\n  var clone = style.ownerDocument.createElement('style');\n  clone.textContent = style.textContent;\n  path.resolveUrlsInStyle(clone);\n  return clone;\n}\n\n// path fixup: style elements in imports must be made relative to the main \n// document. We fixup url's in url() and @import.\nvar CSS_URL_REGEXP = /(url\\()([^)]*)(\\))/g;\nvar CSS_IMPORT_REGEXP = /(@import[\\s]+(?!url\\())([^;]*)(;)/g;\n\nvar path = {\n  resolveUrlsInStyle: function(style) {\n    var doc = style.ownerDocument;\n    var resolver = doc.createElement('a');\n    style.textContent = this.resolveUrlsInCssText(style.textContent, resolver);\n    return style;  \n  },\n  resolveUrlsInCssText: function(cssText, urlObj) {\n    var r = this.replaceUrls(cssText, urlObj, CSS_URL_REGEXP);\n    r = this.replaceUrls(r, urlObj, CSS_IMPORT_REGEXP);\n    return r;\n  },\n  replaceUrls: function(text, urlObj, regexp) {\n    return text.replace(regexp, function(m, pre, url, post) {\n      var urlPath = url.replace(/[\"']/g, '');\n      urlObj.href = urlPath;\n      urlPath = urlObj.href;\n      return pre + '\\'' + urlPath + '\\'' + post;\n    });    \n  }\n}\n\n// exports\nscope.parser = importParser;\nscope.path = path;\nscope.isIE = isIe;\n\n})(HTMLImports);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n(function(scope) {\n\nvar hasNative = ('import' in document.createElement('link'));\nvar useNative = hasNative;\nvar flags = scope.flags;\nvar IMPORT_LINK_TYPE = 'import';\n\n// TODO(sorvell): SD polyfill intrusion\nvar mainDoc = window.ShadowDOMPolyfill ? \n    ShadowDOMPolyfill.wrapIfNeeded(document) : document;\n\nif (!useNative) {\n\n  // imports\n  var xhr = scope.xhr;\n  var Loader = scope.Loader;\n  var parser = scope.parser;\n\n  // importer\n  // highlander object to manage loading of imports\n\n  // for any document, importer:\n  // - loads any linked import documents (with deduping)\n\n  var importer = {\n    documents: {},\n    // nodes to load in the mian document\n    documentPreloadSelectors: 'link[rel=' + IMPORT_LINK_TYPE + ']',\n    // nodes to load in imports\n    importsPreloadSelectors: [\n      'link[rel=' + IMPORT_LINK_TYPE + ']'\n    ].join(','),\n    loadNode: function(node) {\n      importLoader.addNode(node);\n    },\n    // load all loadable elements within the parent element\n    loadSubtree: function(parent) {\n      var nodes = this.marshalNodes(parent);\n      // add these nodes to loader's queue\n      importLoader.addNodes(nodes);\n    },\n    marshalNodes: function(parent) {\n      // all preloadable nodes in inDocument\n      return parent.querySelectorAll(this.loadSelectorsForNode(parent));\n    },\n    // find the proper set of load selectors for a given node\n    loadSelectorsForNode: function(node) {\n      var doc = node.ownerDocument || node;\n      return doc === mainDoc ? this.documentPreloadSelectors :\n          this.importsPreloadSelectors;\n    },\n    loaded: function(url, elt, resource) {\n      flags.load && console.log('loaded', url, elt);\n      // store generic resource\n      // TODO(sorvell): fails for nodes inside <template>.content\n      // see https://code.google.com/p/chromium/issues/detail?id=249381.\n      elt.__resource = resource;\n      if (isDocumentLink(elt)) {\n        var doc = this.documents[url];\n        // if we've never seen a document at this url\n        if (!doc) {\n          // generate an HTMLDocument from data\n          doc = makeDocument(resource, url);\n          doc.__importLink = elt;\n          // TODO(sorvell): we cannot use MO to detect parsed nodes because\n          // SD polyfill does not report these as mutations.\n          this.bootDocument(doc);\n          // cache document\n          this.documents[url] = doc;\n        }\n        // don't store import record until we're actually loaded\n        // store document resource\n        elt.import = doc;\n      }\n      parser.parseNext();\n    },\n    bootDocument: function(doc) {\n      this.loadSubtree(doc);\n      this.observe(doc);\n      parser.parseNext();\n    },\n    loadedAll: function() {\n      parser.parseNext();\n    }\n  };\n\n  // loader singleton\n  var importLoader = new Loader(importer.loaded.bind(importer), \n      importer.loadedAll.bind(importer));\n\n  function isDocumentLink(elt) {\n    return isLinkRel(elt, IMPORT_LINK_TYPE);\n  }\n\n  function isLinkRel(elt, rel) {\n    return elt.localName === 'link' && elt.getAttribute('rel') === rel;\n  }\n\n  function isScript(elt) {\n    return elt.localName === 'script';\n  }\n\n  function makeDocument(resource, url) {\n    // create a new HTML document\n    var doc = resource;\n    if (!(doc instanceof Document)) {\n      doc = document.implementation.createHTMLDocument(IMPORT_LINK_TYPE);\n    }\n    // cache the new document's source url\n    doc._URL = url;\n    // establish a relative path via <base>\n    var base = doc.createElement('base');\n    base.setAttribute('href', url);\n    // add baseURI support to browsers (IE) that lack it.\n    if (!doc.baseURI) {\n      doc.baseURI = url;\n    }\n    // ensure UTF-8 charset\n    var meta = doc.createElement('meta');\n    meta.setAttribute('charset', 'utf-8');\n\n    doc.head.appendChild(meta);\n    doc.head.appendChild(base);\n    // install HTML last as it may trigger CustomElement upgrades\n    // TODO(sjmiles): problem wrt to template boostrapping below,\n    // template bootstrapping must (?) come before element upgrade\n    // but we cannot bootstrap templates until they are in a document\n    // which is too late\n    if (!(resource instanceof Document)) {\n      // install html\n      doc.body.innerHTML = resource;\n    }\n    // TODO(sorvell): ideally this code is not aware of Template polyfill,\n    // but for now the polyfill needs help to bootstrap these templates\n    if (window.HTMLTemplateElement && HTMLTemplateElement.bootstrap) {\n      HTMLTemplateElement.bootstrap(doc);\n    }\n    return doc;\n  }\n} else {\n  // do nothing if using native imports\n  var importer = {};\n}\n\n// NOTE: We cannot polyfill document.currentScript because it's not possible\n// both to override and maintain the ability to capture the native value;\n// therefore we choose to expose _currentScript both when native imports\n// and the polyfill are in use.\nvar currentScriptDescriptor = {\n  get: function() {\n    return HTMLImports.currentScript || document.currentScript;\n  },\n  configurable: true\n};\n\nObject.defineProperty(document, '_currentScript', currentScriptDescriptor);\nObject.defineProperty(mainDoc, '_currentScript', currentScriptDescriptor);\n\n// Polyfill document.baseURI for browsers without it.\nif (!document.baseURI) {\n  var baseURIDescriptor = {\n    get: function() {\n      return window.location.href;\n    },\n    configurable: true\n  };\n\n  Object.defineProperty(document, 'baseURI', baseURIDescriptor);\n  Object.defineProperty(mainDoc, 'baseURI', baseURIDescriptor);\n}\n\n// call a callback when all HTMLImports in the document at call (or at least\n//  document ready) time have loaded.\n// 1. ensure the document is in a ready state (has dom), then \n// 2. watch for loading of imports and call callback when done\nfunction whenImportsReady(callback, doc) {\n  doc = doc || mainDoc;\n  // if document is loading, wait and try again\n  whenDocumentReady(function() {\n    watchImportsLoad(callback, doc);\n  }, doc);\n}\n\n// call the callback when the document is in a ready state (has dom)\nvar requiredReadyState = HTMLImports.isIE ? 'complete' : 'interactive';\nvar READY_EVENT = 'readystatechange';\nfunction isDocumentReady(doc) {\n  return (doc.readyState === 'complete' ||\n      doc.readyState === requiredReadyState);\n}\n\n// call <callback> when we ensure the document is in a ready state\nfunction whenDocumentReady(callback, doc) {\n  if (!isDocumentReady(doc)) {\n    var checkReady = function() {\n      if (doc.readyState === 'complete' || \n          doc.readyState === requiredReadyState) {\n        doc.removeEventListener(READY_EVENT, checkReady);\n        whenDocumentReady(callback, doc);\n      }\n    }\n    doc.addEventListener(READY_EVENT, checkReady);\n  } else if (callback) {\n    callback();\n  }\n}\n\n// call <callback> when we ensure all imports have loaded\nfunction watchImportsLoad(callback, doc) {\n  var imports = doc.querySelectorAll('link[rel=import]');\n  var loaded = 0, l = imports.length;\n  function checkDone(d) { \n    if (loaded == l) {\n      callback && callback();\n    }\n  }\n  function loadedImport(e) {\n    loaded++;\n    checkDone();\n  }\n  if (l) {\n    for (var i=0, imp; (i<l) && (imp=imports[i]); i++) {\n      if (isImportLoaded(imp)) {\n        loadedImport.call(imp);\n      } else {\n        imp.addEventListener('load', loadedImport);\n        imp.addEventListener('error', loadedImport);\n      }\n    }\n  } else {\n    checkDone();\n  }\n}\n\nfunction isImportLoaded(link) {\n  return useNative ? (link.import && (link.import.readyState !== 'loading')) || link.__loaded :\n      link.__importParsed;\n}\n\n// TODO(sorvell): install a mutation observer to see if HTMLImports have loaded\n// this is a workaround for https://www.w3.org/Bugs/Public/show_bug.cgi?id=25007\n// and should be removed when this bug is addressed.\nif (useNative) {\n  new MutationObserver(function(mxns) {\n    for (var i=0, l=mxns.length, m; (i < l) && (m=mxns[i]); i++) {\n      if (m.addedNodes) {\n        handleImports(m.addedNodes);\n      }\n    }\n  }).observe(document.head, {childList: true});\n\n  function handleImports(nodes) {\n    for (var i=0, l=nodes.length, n; (i<l) && (n=nodes[i]); i++) {\n      if (isImport(n)) {\n        handleImport(n);  \n      }\n    }\n  }\n\n  function isImport(element) {\n    return element.localName === 'link' && element.rel === 'import';\n  }\n\n  function handleImport(element) {\n    var loaded = element.import;\n    if (loaded) {\n      markTargetLoaded({target: element});\n    } else {\n      element.addEventListener('load', markTargetLoaded);\n      element.addEventListener('error', markTargetLoaded);\n    }\n  }\n\n  function markTargetLoaded(event) {\n    event.target.__loaded = true;\n  }\n\n}\n\n// exports\nscope.hasNative = hasNative;\nscope.useNative = useNative;\nscope.importer = importer;\nscope.IMPORT_LINK_TYPE = IMPORT_LINK_TYPE;\nscope.isImportLoaded = isImportLoaded;\nscope.importLoader = importLoader;\nscope.whenReady = whenImportsReady;\n\n// deprecated\nscope.whenImportsReady = whenImportsReady;\n\n})(window.HTMLImports);\n"," /*\nCopyright 2013 The Polymer Authors. All rights reserved.\nUse of this source code is governed by a BSD-style\nlicense that can be found in the LICENSE file.\n*/\n\n(function(scope){\n\nvar IMPORT_LINK_TYPE = scope.IMPORT_LINK_TYPE;\nvar importSelector = 'link[rel=' + IMPORT_LINK_TYPE + ']';\nvar importer = scope.importer;\nvar parser = scope.parser;\n\n// we track mutations for addedNodes, looking for imports\nfunction handler(mutations) {\n  for (var i=0, l=mutations.length, m; (i<l) && (m=mutations[i]); i++) {\n    if (m.type === 'childListchildList: true, subtree: true});\n}\n\n// exports\n// TODO(sorvell): factor so can put on scope\nscope.observe = observe;\nimporter.observe = observe;\n\n})(HTMLImports);\n","/*\n * Copyright 2013 The Polymer Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n(function(){\n\n// bootstrap\n\n// IE shim for CustomEvent\nif (typeof window.CustomEvent !== 'function') {\n  window.CustomEvent = function(inType, dictionary) {\n     var e = document.createEvent('HTMLEvents');\n     e.initEvent(inType,\n        dictionary.bubbles === false ? false : true,\n        dictionary.cancelable === false ? false : true,\n        dictionary.detail);\n     return e;\n  };\n}\n\n// TODO(sorvell): SD polyfill intrusion\nvar doc = window.ShadowDOMPolyfill ? \n    window.ShadowDOMPolyfill.wrapIfNeeded(document) : document;\n\n// Fire the 'HTMLImportsLoaded' event when imports in document at load time \n// have loaded. This event is required to simulate the script blocking \n// behavior of native imports. A main document script that needs to be sure\n// imports have loaded should wait for this event.\nHTMLImports.whenImportsReady(function() {\n  HTMLImports.ready = true;\n  HTMLImports.readyTime = new Date().getTime();\n  doc.dispatchEvent(\n    new CustomEvent('HTMLImportsLoaded', {bubbles: true})\n  );\n});\n\n\n// no need to bootstrap the polyfill when native imports is available.\nif (!HTMLImports.useNative) {\n  function bootstrap() {\n    HTMLImports.importer.bootDocument(doc);\n  }\n    \n  // TODO(sorvell): SD polyfill does *not* generate mutations for nodes added\n  // by the parser. For this reason, we must wait until the dom exists to \n  // bootstrap.\n  if (document.readyState === 'complete' ||\n      (document.readyState === 'interactive' && !window.attachEvent)) {\n    bootstrap();\n  } else {\n    document.addEventListener('DOMContentLoaded', bootstrap);\n  }\n}\n\n})();\n","/*\n * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.\n * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt\n * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\n * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\n * Code distributed by Google as part of the polymer project is also\n * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n */\nwindow.CustomElements = window.CustomElements || {flags:{}};","/*\r\n * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.\r\n * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt\r\n * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\r\n * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\r\n * Code distributed by Google as part of the polymer project is also\r\n * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\r\n */\r\n\r\n(function(scope){\r\n\r\nvar logFlags = window.logFlags || {};\r\nvar IMPORT_LINK_TYPE = window.HTMLImports ? HTMLImports.IMPORT_LINK_TYPE : 'none';\r\n\r\n// walk the subtree rooted at node, applying 'find(element, data)' function\r\n// to each element\r\n// if 'find' returns true for 'element', do not search element's subtree\r\nfunction findAll(node, find, data) {\r\n  var e = node.firstElementChild;\r\n  if (!e) {\r\n    e = node.firstChild;\r\n    while (e && e.nodeType !== Node.ELEMENT_NODE) {\r\n      e = e.nextSibling;\r\n    }\r\n  }\r\n  while (e) {\r\n    if (find(e, data) !== true) {\r\n      findAll(e, find, data);\r\n    }\r\n    e = e.nextElementSibling;\r\n  }\r\n  return null;\r\n}\r\n\r\n// walk all shadowRoots on a given node.\r\nfunction forRoots(node, cb) {\r\n  var root = node.shadowRoot;\r\n  while(root) {\r\n    forSubtree(root, cb);\r\n    root = root.olderShadowRoot;\r\n  }\r\n}\r\n\r\n// walk the subtree rooted at node, including descent into shadow-roots,\r\n// applying 'cb' to each element\r\nfunction forSubtree(node, cb) {\r\n  //logFlags.dom && node.childNodes && node.childNodes.length && console.group('subTree: ', node);\r\n  findAll(node, function(e) {\r\n    if (cb(e)) {\r\n      return true;\r\n    }\r\n    forRoots(e, cb);\r\n  });\r\n  forRoots(node, cb);\r\n  //logFlags.dom && node.childNodes && node.childNodes.length && console.groupEnd();\r\n}\r\n\r\n// manage lifecycle on added node\r\nfunction added(node) {\r\n  if (upgrade(node)) {\r\n    insertedNode(node);\r\n    return true;\r\n  }\r\n  inserted(node);\r\n}\r\n\r\n// manage lifecycle on added node's subtree only\r\nfunction addedSubtree(node) {\r\n  forSubtree(node, function(e) {\r\n    if (added(e)) {\r\n      return true;\r\n    }\r\n  });\r\n}\r\n\r\n// manage lifecycle on added node and it's subtree\r\nfunction addedNode(node) {\r\n  return added(node) || addedSubtree(node);\r\n}\r\n\r\n// upgrade custom elements at node, if applicable\r\nfunction upgrade(node) {\r\n  if (!node.__upgraded__ && node.nodeType === Node.ELEMENT_NODE) {\r\n    var type = node.getAttribute('is') || node.localName;\r\n    var definition = scope.registry[type];\r\n    if (definition) {\r\n      logFlags.dom && console.group('upgrade:', node.localName);\r\n      scope.upgrade(node);\r\n      logFlags.dom && console.groupEnd();\r\n      return true;\r\n    }\r\n  }\r\n}\r\n\r\nfunction insertedNode(node) {\r\n  inserted(node);\r\n  if (inDocument(node)) {\r\n    forSubtree(node, function(e) {\r\n      inserted(e);\r\n    });\r\n  }\r\n}\r\n\r\n// TODO(sorvell): on platforms without MutationObserver, mutations may not be\r\n// reliable and therefore attached/detached are not reliable.\r\n// To make these callbacks less likely to fail, we defer all inserts and removes\r\n// to give a chance for elements to be inserted into dom.\r\n// This ensures attachedCallback fires for elements that are created and\r\n// immediately added to dom.\r\nvar hasPolyfillMutations = (!window.MutationObserver ||\r\n    (window.MutationObserver === window.JsMutationObserver));\r\nscope.hasPolyfillMutations = hasPolyfillMutations;\r\n\r\nvar isPendingMutations = false;\r\nvar pendingMutations = [];\r\nfunction deferMutation(fn) {\r\n  pendingMutations.push(fn);\r\n  if (!isPendingMutations) {\r\n    isPendingMutations = true;\r\n    var async = (window.Platform && window.Platform.endOfMicrotask) ||\r\n        setTimeout;\r\n    async(takeMutations);\r\n  }\r\n}\r\n\r\nfunction takeMutations() {\r\n  isPendingMutations = false;\r\n  var $p = pendingMutations;\r\n  for (var i=0, l=$p.length, p; (i<l) && (p=$p[i]); i++) {\r\n    p();\r\n  }\r\n  pendingMutations = [];\r\n}\r\n\r\nfunction inserted(element) {\r\n  if (hasPolyfillMutations) {\r\n    deferMutation(function() {\r\n      _inserted(element);\r\n    });\r\n  } else {\r\n    _inserted(element);\r\n  }\r\n}\r\n\r\n// TODO(sjmiles): if there are descents into trees that can never have inDocument(*) true, fix this\r\nfunction _inserted(element) {\r\n  // TODO(sjmiles): it's possible we were inserted and removed in the space\r\n  // of one microtask, in which case we won't be 'inDocument' here\r\n  // But there are other cases where we are testing for inserted without\r\n  // specific knowledge of mutations, and must test 'inDocument' to determine\r\n  // whether to call inserted\r\n  // If we can factor these cases into separate code paths we can have\r\n  // better diagnostics.\r\n  // TODO(sjmiles): when logging, do work on all custom elements so we can\r\n  // track behavior even when callbacks not defined\r\n  //console.log('inserted: ', element.localName);\r\n  if (element.attachedCallback || element.detachedCallback || (element.__upgraded__ && logFlags.dom)) {\r\n    logFlags.dom && console.group('inserted:', element.localName);\r\n    if (inDocument(element)) {\r\n      element.__inserted = (element.__inserted || 0) + 1;\r\n      // if we are in a 'removed' state, bluntly adjust to an 'inserted' state\r\n      if (element.__inserted < 1) {\r\n        element.__inserted = 1;\r\n      }\r\n      // if we are 'over inserted', squelch the callback\r\n      if (element.__inserted > 1) {\r\n        logFlags.dom && console.warn('inserted:', element.localName,\r\n          'insert/remove count:', element.__inserted)\r\n      } else if (element.attachedCallback) {\r\n        logFlags.dom && console.log('inserted:', element.localName);\r\n        element.attachedCallback();\r\n      }\r\n    }\r\n    logFlags.dom && console.groupEnd();\r\n  }\r\n}\r\n\r\nfunction removedNode(node) {\r\n  removed(node);\r\n  forSubtree(node, function(e) {\r\n    removed(e);\r\n  });\r\n}\r\n\r\nfunction removed(element) {\r\n  if (hasPolyfillMutations) {\r\n    deferMutation(function() {\r\n      _removed(element);\r\n    });\r\n  } else {\r\n    _removed(element);\r\n  }\r\n}\r\n\r\nfunction _removed(element) {\r\n  // TODO(sjmiles): temporary: do work on all custom elements so we can track\r\n  // behavior even when callbacks not defined\r\n  if (element.attachedCallback || element.detachedCallback || (element.__upgraded__ && logFlags.dom)) {\r\n    logFlags.dom && console.group('removed:', element.localName);\r\n    if (!inDocument(element)) {\r\n      element.__inserted = (element.__inserted || 0) - 1;\r\n      // if we are in a 'inserted' state, bluntly adjust to an 'removed' state\r\n      if (element.__inserted > 0) {\r\n        element.__inserted = 0;\r\n      }\r\n      // if we are 'over removed', squelch the callback\r\n      if (element.__inserted < 0) {\r\n        logFlags.dom && console.warn('removed:', element.localName,\r\n            'insert/remove count:', element.__inserted)\r\n      } else if (element.detachedCallback) {\r\n        element.detachedCallback();\r\n      }\r\n    }\r\n    logFlags.dom && console.groupEnd();\r\n  }\r\n}\r\n\r\n// SD polyfill intrustion due mainly to the fact that 'document'\r\n// is not entirely wrapped\r\nfunction wrapIfNeeded(node) {\r\n  return window.ShadowDOMPolyfill ? ShadowDOMPolyfill.wrapIfNeeded(node)\r\n      : node;\r\n}\r\n\r\nfunction inDocument(element) {\r\n  var p = element;\r\n  var doc = wrapIfNeeded(document);\r\n  while (p) {\r\n    if (p == doc) {\r\n      return true;\r\n    }\r\n    p = p.parentNode || p.host;\r\n  }\r\n}\r\n\r\nfunction watchShadow(node) {\r\n  if (node.shadowRoot && !node.shadowRoot.__watched) {\r\n    logFlags.dom && console.log('watching shadow-root for: ', node.localName);\r\n    // watch all unwatched roots...\r\n    var root = node.shadowRoot;\r\n    while (root) {\r\n      watchRoot(root);\r\n      root = root.olderShadowRoot;\r\n    }\r\n  }\r\n}\r\n\r\nfunction watchRoot(root) {\r\n  if (!root.__watched) {\r\n    observe(root);\r\n    root.__watched = true;\r\n  }\r\n}\r\n\r\nfunction handler(mutations) {\r\n  //\r\n  if (logFlags.dom) {\r\n    var mx = mutations[0];\r\n    if (mx && mx.type === 'childList' && mx.addedNodes) {\r\n        if (mx.addedNodes) {\r\n          var d = mx.addedNodes[0];\r\n          while (d && d !== document && !d.host) {\r\n            d = d.parentNode;\r\n          }\r\n          var u = d && (d.URL || d._URL || (d.host && d.host.localName)) || '';\r\n          u = u.split('/?').shift().split('/').pop();\r\n        }\r\n    }\r\n    console.group('mutations (%d) [%s]', mutations.length, u || '');\r\n  }\r\n  //\r\n  mutations.forEach(function(mx) {\r\n    //logFlags.dom && console.group('mutation');\r\n    if (mx.type === 'childList') {\r\n      forEach(mx.addedNodes, function(n) {\r\n        //logFlags.dom && console.log(n.localName);\r\n        if (!n.localName) {\r\n          return;\r\n        }\r\n        // nodes added may need lifecycle management\r\n        addedNode(n);\r\n      });\r\n      // removed nodes may need lifecycle management\r\n      forEach(mx.removedNodes, function(n) {\r\n        //logFlags.dom && console.log(n.localName);\r\n        if (!n.localName) {\r\n          return;\r\n        }\r\n        removedNode(n);\r\n      });\r\n    }\r\n    //logFlags.dom && console.groupEnd();\r\n  });\r\n  logFlags.dom && console.groupEnd();\r\n};\r\n\r\nvar observer = new MutationObserver(handler);\r\n\r\nfunction takeRecords() {\r\n  // TODO(sjmiles): ask Raf why we have to call handler ourselves\r\n  handler(observer.takeRecords());\r\n  takeMutations();\r\n}\r\n\r\nvar forEach = Array.prototype.forEach.call.bind(Array.prototype.forEach);\r\n\r\nfunction observe(inRoot) {\r\n  observer.observe(inRoot, {childList