| <!-- |
| @license |
| Copyright (c) 2015 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 |
| --><!-- |
| @license |
| Copyright (c) 2014 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 |
| --><link rel="import" href="polymer-mini.html"><script>(function () { |
| Polymer.nar = []; |
| var disableUpgradeEnabled = Polymer.Settings.disableUpgradeEnabled; |
| Polymer.Annotations = { |
| parseAnnotations: function (template, stripWhiteSpace) { |
| var list = []; |
| var content = template._content || template.content; |
| this._parseNodeAnnotations(content, list, stripWhiteSpace || template.hasAttribute('strip-whitespace')); |
| return list; |
| }, |
| _parseNodeAnnotations: function (node, list, stripWhiteSpace) { |
| return node.nodeType === Node.TEXT_NODE ? this._parseTextNodeAnnotation(node, list) : this._parseElementAnnotations(node, list, stripWhiteSpace); |
| }, |
| _bindingRegex: function () { |
| var IDENT = '(?:' + '[a-zA-Z_$][\\w.:$\\-*]*' + ')'; |
| var NUMBER = '(?:' + '[-+]?[0-9]*\\.?[0-9]+(?:[eE][-+]?[0-9]+)?' + ')'; |
| var SQUOTE_STRING = '(?:' + '\'(?:[^\'\\\\]|\\\\.)*\'' + ')'; |
| var DQUOTE_STRING = '(?:' + '"(?:[^"\\\\]|\\\\.)*"' + ')'; |
| var STRING = '(?:' + SQUOTE_STRING + '|' + DQUOTE_STRING + ')'; |
| var ARGUMENT = '(?:' + IDENT + '|' + NUMBER + '|' + STRING + '\\s*' + ')'; |
| var ARGUMENTS = '(?:' + ARGUMENT + '(?:,\\s*' + ARGUMENT + ')*' + ')'; |
| var ARGUMENT_LIST = '(?:' + '\\(\\s*' + '(?:' + ARGUMENTS + '?' + ')' + '\\)\\s*' + ')'; |
| var BINDING = '(' + IDENT + '\\s*' + ARGUMENT_LIST + '?' + ')'; |
| var OPEN_BRACKET = '(\\[\\[|{{)' + '\\s*'; |
| var CLOSE_BRACKET = '(?:]]|}})'; |
| var NEGATE = '(?:(!)\\s*)?'; |
| var EXPRESSION = OPEN_BRACKET + NEGATE + BINDING + CLOSE_BRACKET; |
| return new RegExp(EXPRESSION, 'g'); |
| }(), |
| _parseBindings: function (text) { |
| var re = this._bindingRegex; |
| var parts = []; |
| var lastIndex = 0; |
| var m; |
| while ((m = re.exec(text)) !== null) { |
| if (m.index > lastIndex) { |
| parts.push({ literal: text.slice(lastIndex, m.index) }); |
| } |
| var mode = m[1][0]; |
| var negate = Boolean(m[2]); |
| var value = m[3].trim(); |
| var customEvent, notifyEvent, colon; |
| if (mode == '{' && (colon = value.indexOf('::')) > 0) { |
| notifyEvent = value.substring(colon + 2); |
| value = value.substring(0, colon); |
| customEvent = true; |
| } |
| parts.push({ |
| compoundIndex: parts.length, |
| value: value, |
| mode: mode, |
| negate: negate, |
| event: notifyEvent, |
| customEvent: customEvent |
| }); |
| lastIndex = re.lastIndex; |
| } |
| if (lastIndex && lastIndex < text.length) { |
| var literal = text.substring(lastIndex); |
| if (literal) { |
| parts.push({ literal: literal }); |
| } |
| } |
| if (parts.length) { |
| return parts; |
| } |
| }, |
| _literalFromParts: function (parts) { |
| var s = ''; |
| for (var i = 0; i < parts.length; i++) { |
| var literal = parts[i].literal; |
| s += literal || ''; |
| } |
| return s; |
| }, |
| _parseTextNodeAnnotation: function (node, list) { |
| var parts = this._parseBindings(node.textContent); |
| if (parts) { |
| node.textContent = this._literalFromParts(parts) || ' '; |
| var annote = { |
| bindings: [{ |
| kind: 'text', |
| name: 'textContent', |
| parts: parts, |
| isCompound: parts.length !== 1 |
| }] |
| }; |
| list.push(annote); |
| return annote; |
| } |
| }, |
| _parseElementAnnotations: function (element, list, stripWhiteSpace) { |
| var annote = { |
| bindings: [], |
| events: [] |
| }; |
| if (element.localName === 'content') { |
| list._hasContent = true; |
| } |
| this._parseChildNodesAnnotations(element, annote, list, stripWhiteSpace); |
| if (element.attributes) { |
| this._parseNodeAttributeAnnotations(element, annote, list); |
| if (this.prepElement) { |
| this.prepElement(element); |
| } |
| } |
| if (annote.bindings.length || annote.events.length || annote.id) { |
| list.push(annote); |
| } |
| return annote; |
| }, |
| _parseChildNodesAnnotations: function (root, annote, list, stripWhiteSpace) { |
| if (root.firstChild) { |
| var node = root.firstChild; |
| var i = 0; |
| while (node) { |
| var next = node.nextSibling; |
| if (node.localName === 'template' && !node.hasAttribute('preserve-content')) { |
| this._parseTemplate(node, i, list, annote, stripWhiteSpace); |
| } |
| if (node.localName == 'slot') { |
| node = this._replaceSlotWithContent(node); |
| } |
| if (node.nodeType === Node.TEXT_NODE) { |
| var n = next; |
| while (n && n.nodeType === Node.TEXT_NODE) { |
| node.textContent += n.textContent; |
| next = n.nextSibling; |
| root.removeChild(n); |
| n = next; |
| } |
| if (stripWhiteSpace && !node.textContent.trim()) { |
| root.removeChild(node); |
| i--; |
| } |
| } |
| if (node.parentNode) { |
| var childAnnotation = this._parseNodeAnnotations(node, list, stripWhiteSpace); |
| if (childAnnotation) { |
| childAnnotation.parent = annote; |
| childAnnotation.index = i; |
| } |
| } |
| node = next; |
| i++; |
| } |
| } |
| }, |
| _replaceSlotWithContent: function (slot) { |
| var content = slot.ownerDocument.createElement('content'); |
| while (slot.firstChild) { |
| content.appendChild(slot.firstChild); |
| } |
| var attrs = slot.attributes; |
| for (var i = 0; i < attrs.length; i++) { |
| var attr = attrs[i]; |
| content.setAttribute(attr.name, attr.value); |
| } |
| var name = slot.getAttribute('name'); |
| if (name) { |
| content.setAttribute('select', '[slot=\'' + name + '\']'); |
| } |
| slot.parentNode.replaceChild(content, slot); |
| return content; |
| }, |
| _parseTemplate: function (node, index, list, parent, stripWhiteSpace) { |
| var content = document.createDocumentFragment(); |
| content._notes = this.parseAnnotations(node, stripWhiteSpace); |
| content.appendChild(node.content); |
| list.push({ |
| bindings: Polymer.nar, |
| events: Polymer.nar, |
| templateContent: content, |
| parent: parent, |
| index: index |
| }); |
| }, |
| _parseNodeAttributeAnnotations: function (node, annotation) { |
| var attrs = Array.prototype.slice.call(node.attributes); |
| for (var i = attrs.length - 1, a; a = attrs[i]; i--) { |
| var n = a.name; |
| var v = a.value; |
| var b; |
| if (n.slice(0, 3) === 'on-') { |
| node.removeAttribute(n); |
| annotation.events.push({ |
| name: n.slice(3), |
| value: v |
| }); |
| } else if (b = this._parseNodeAttributeAnnotation(node, n, v)) { |
| annotation.bindings.push(b); |
| } else if (n === 'id') { |
| annotation.id = v; |
| } |
| } |
| }, |
| _parseNodeAttributeAnnotation: function (node, name, value) { |
| var parts = this._parseBindings(value); |
| if (parts) { |
| var origName = name; |
| var kind = 'property'; |
| if (name[name.length - 1] == '$') { |
| name = name.slice(0, -1); |
| kind = 'attribute'; |
| } |
| var literal = this._literalFromParts(parts); |
| if (literal && kind == 'attribute') { |
| node.setAttribute(name, literal); |
| } |
| if (node.localName === 'input' && origName === 'value') { |
| node.setAttribute(origName, ''); |
| } |
| if (disableUpgradeEnabled && origName === 'disable-upgrade$') { |
| node.setAttribute(name, ''); |
| } |
| node.removeAttribute(origName); |
| var propertyName = Polymer.CaseMap.dashToCamelCase(name); |
| if (kind === 'property') { |
| name = propertyName; |
| } |
| return { |
| kind: kind, |
| name: name, |
| propertyName: propertyName, |
| parts: parts, |
| literal: literal, |
| isCompound: parts.length !== 1 |
| }; |
| } |
| }, |
| findAnnotatedNode: function (root, annote) { |
| var parent = annote.parent && Polymer.Annotations.findAnnotatedNode(root, annote.parent); |
| if (parent) { |
| for (var n = parent.firstChild, i = 0; n; n = n.nextSibling) { |
| if (annote.index === i++) { |
| return n; |
| } |
| } |
| } else { |
| return root; |
| } |
| } |
| }; |
| }());Polymer.Path = { |
| root: function (path) { |
| var dotIndex = path.indexOf('.'); |
| if (dotIndex === -1) { |
| return path; |
| } |
| return path.slice(0, dotIndex); |
| }, |
| isDeep: function (path) { |
| return path.indexOf('.') !== -1; |
| }, |
| isAncestor: function (base, path) { |
| return base.indexOf(path + '.') === 0; |
| }, |
| isDescendant: function (base, path) { |
| return path.indexOf(base + '.') === 0; |
| }, |
| translate: function (base, newBase, path) { |
| return newBase + path.slice(base.length); |
| }, |
| matches: function (base, wildcard, path) { |
| return base === path || this.isAncestor(base, path) || Boolean(wildcard) && this.isDescendant(base, path); |
| } |
| };Polymer.Base._addFeature({ |
| _prepAnnotations: function () { |
| if (!this._template) { |
| this._notes = []; |
| } else { |
| var self = this; |
| Polymer.Annotations.prepElement = function (element) { |
| self._prepElement(element); |
| }; |
| if (this._template._content && this._template._content._notes) { |
| this._notes = this._template._content._notes; |
| } else { |
| this._notes = Polymer.Annotations.parseAnnotations(this._template); |
| this._processAnnotations(this._notes); |
| } |
| Polymer.Annotations.prepElement = null; |
| } |
| }, |
| _processAnnotations: function (notes) { |
| for (var i = 0; i < notes.length; i++) { |
| var note = notes[i]; |
| for (var j = 0; j < note.bindings.length; j++) { |
| var b = note.bindings[j]; |
| for (var k = 0; k < b.parts.length; k++) { |
| var p = b.parts[k]; |
| if (!p.literal) { |
| var signature = this._parseMethod(p.value); |
| if (signature) { |
| p.signature = signature; |
| } else { |
| p.model = Polymer.Path.root(p.value); |
| } |
| } |
| } |
| } |
| if (note.templateContent) { |
| this._processAnnotations(note.templateContent._notes); |
| var pp = note.templateContent._parentProps = this._discoverTemplateParentProps(note.templateContent._notes); |
| var bindings = []; |
| for (var prop in pp) { |
| var name = '_parent_' + prop; |
| bindings.push({ |
| index: note.index, |
| kind: 'property', |
| name: name, |
| propertyName: name, |
| parts: [{ |
| mode: '{', |
| model: prop, |
| value: prop |
| }] |
| }); |
| } |
| note.bindings = note.bindings.concat(bindings); |
| } |
| } |
| }, |
| _discoverTemplateParentProps: function (notes) { |
| var pp = {}; |
| for (var i = 0, n; i < notes.length && (n = notes[i]); i++) { |
| for (var j = 0, b$ = n.bindings, b; j < b$.length && (b = b$[j]); j++) { |
| for (var k = 0, p$ = b.parts, p; k < p$.length && (p = p$[k]); k++) { |
| if (p.signature) { |
| var args = p.signature.args; |
| for (var kk = 0; kk < args.length; kk++) { |
| var model = args[kk].model; |
| if (model) { |
| pp[model] = true; |
| } |
| } |
| if (p.signature.dynamicFn) { |
| pp[p.signature.method] = true; |
| } |
| } else { |
| if (p.model) { |
| pp[p.model] = true; |
| } |
| } |
| } |
| } |
| if (n.templateContent) { |
| var tpp = n.templateContent._parentProps; |
| Polymer.Base.mixin(pp, tpp); |
| } |
| } |
| return pp; |
| }, |
| _prepElement: function (element) { |
| Polymer.ResolveUrl.resolveAttrs(element, this._template.ownerDocument); |
| }, |
| _findAnnotatedNode: Polymer.Annotations.findAnnotatedNode, |
| _marshalAnnotationReferences: function () { |
| if (this._template) { |
| this._marshalIdNodes(); |
| this._marshalAnnotatedNodes(); |
| this._marshalAnnotatedListeners(); |
| } |
| }, |
| _configureAnnotationReferences: function () { |
| var notes = this._notes; |
| var nodes = this._nodes; |
| for (var i = 0; i < notes.length; i++) { |
| var note = notes[i]; |
| var node = nodes[i]; |
| this._configureTemplateContent(note, node); |
| this._configureCompoundBindings(note, node); |
| } |
| }, |
| _configureTemplateContent: function (note, node) { |
| if (note.templateContent) { |
| node._content = note.templateContent; |
| } |
| }, |
| _configureCompoundBindings: function (note, node) { |
| var bindings = note.bindings; |
| for (var i = 0; i < bindings.length; i++) { |
| var binding = bindings[i]; |
| if (binding.isCompound) { |
| var storage = node.__compoundStorage__ || (node.__compoundStorage__ = {}); |
| var parts = binding.parts; |
| var literals = new Array(parts.length); |
| for (var j = 0; j < parts.length; j++) { |
| literals[j] = parts[j].literal; |
| } |
| var name = binding.name; |
| storage[name] = literals; |
| if (binding.literal && binding.kind == 'property') { |
| if (node._configValue) { |
| node._configValue(name, binding.literal); |
| } else { |
| node[name] = binding.literal; |
| } |
| } |
| } |
| } |
| }, |
| _marshalIdNodes: function () { |
| this.$ = {}; |
| for (var i = 0, l = this._notes.length, a; i < l && (a = this._notes[i]); i++) { |
| if (a.id) { |
| this.$[a.id] = this._findAnnotatedNode(this.root, a); |
| } |
| } |
| }, |
| _marshalAnnotatedNodes: function () { |
| if (this._notes && this._notes.length) { |
| var r = new Array(this._notes.length); |
| for (var i = 0; i < this._notes.length; i++) { |
| r[i] = this._findAnnotatedNode(this.root, this._notes[i]); |
| } |
| this._nodes = r; |
| } |
| }, |
| _marshalAnnotatedListeners: function () { |
| for (var i = 0, l = this._notes.length, a; i < l && (a = this._notes[i]); i++) { |
| if (a.events && a.events.length) { |
| var node = this._findAnnotatedNode(this.root, a); |
| for (var j = 0, e$ = a.events, e; j < e$.length && (e = e$[j]); j++) { |
| this.listen(node, e.name, e.value); |
| } |
| } |
| } |
| } |
| });Polymer.Base._addFeature({ |
| listeners: {}, |
| _listenListeners: function (listeners) { |
| var node, name, eventName; |
| for (eventName in listeners) { |
| if (eventName.indexOf('.') < 0) { |
| node = this; |
| name = eventName; |
| } else { |
| name = eventName.split('.'); |
| node = this.$[name[0]]; |
| name = name[1]; |
| } |
| this.listen(node, name, listeners[eventName]); |
| } |
| }, |
| listen: function (node, eventName, methodName) { |
| var handler = this._recallEventHandler(this, eventName, node, methodName); |
| if (!handler) { |
| handler = this._createEventHandler(node, eventName, methodName); |
| } |
| if (handler._listening) { |
| return; |
| } |
| this._listen(node, eventName, handler); |
| handler._listening = true; |
| }, |
| _boundListenerKey: function (eventName, methodName) { |
| return eventName + ':' + methodName; |
| }, |
| _recordEventHandler: function (host, eventName, target, methodName, handler) { |
| var hbl = host.__boundListeners; |
| if (!hbl) { |
| hbl = host.__boundListeners = new WeakMap(); |
| } |
| var bl = hbl.get(target); |
| if (!bl) { |
| bl = {}; |
| if (!Polymer.Settings.isIE || target != window) { |
| hbl.set(target, bl); |
| } |
| } |
| var key = this._boundListenerKey(eventName, methodName); |
| bl[key] = handler; |
| }, |
| _recallEventHandler: function (host, eventName, target, methodName) { |
| var hbl = host.__boundListeners; |
| if (!hbl) { |
| return; |
| } |
| var bl = hbl.get(target); |
| if (!bl) { |
| return; |
| } |
| var key = this._boundListenerKey(eventName, methodName); |
| return bl[key]; |
| }, |
| _createEventHandler: function (node, eventName, methodName) { |
| var host = this; |
| var handler = function (e) { |
| if (host[methodName]) { |
| host[methodName](e, e.detail); |
| } else { |
| host._warn(host._logf('_createEventHandler', 'listener method `' + methodName + '` not defined')); |
| } |
| }; |
| handler._listening = false; |
| this._recordEventHandler(host, eventName, node, methodName, handler); |
| return handler; |
| }, |
| unlisten: function (node, eventName, methodName) { |
| var handler = this._recallEventHandler(this, eventName, node, methodName); |
| if (handler) { |
| this._unlisten(node, eventName, handler); |
| handler._listening = false; |
| } |
| }, |
| _listen: function (node, eventName, handler) { |
| node.addEventListener(eventName, handler); |
| }, |
| _unlisten: function (node, eventName, handler) { |
| node.removeEventListener(eventName, handler); |
| } |
| });(function () { |
| 'use strict'; |
| var wrap = Polymer.DomApi.wrap; |
| var HAS_NATIVE_TA = typeof document.head.style.touchAction === 'string'; |
| var GESTURE_KEY = '__polymerGestures'; |
| var HANDLED_OBJ = '__polymerGesturesHandled'; |
| var TOUCH_ACTION = '__polymerGesturesTouchAction'; |
| var TAP_DISTANCE = 25; |
| var TRACK_DISTANCE = 5; |
| var TRACK_LENGTH = 2; |
| var MOUSE_TIMEOUT = 2500; |
| var MOUSE_EVENTS = [ |
| 'mousedown', |
| 'mousemove', |
| 'mouseup', |
| 'click' |
| ]; |
| var MOUSE_WHICH_TO_BUTTONS = [ |
| 0, |
| 1, |
| 4, |
| 2 |
| ]; |
| var MOUSE_HAS_BUTTONS = function () { |
| try { |
| return new MouseEvent('test', { buttons: 1 }).buttons === 1; |
| } catch (e) { |
| return false; |
| } |
| }(); |
| function isMouseEvent(name) { |
| return MOUSE_EVENTS.indexOf(name) > -1; |
| } |
| var SUPPORTS_PASSIVE = false; |
| (function () { |
| try { |
| var opts = Object.defineProperty({}, 'passive', { |
| get: function () { |
| SUPPORTS_PASSIVE = true; |
| } |
| }); |
| window.addEventListener('test', null, opts); |
| window.removeEventListener('test', null, opts); |
| } catch (e) { |
| } |
| }()); |
| function PASSIVE_TOUCH(eventName) { |
| if (isMouseEvent(eventName) || eventName === 'touchend') { |
| return; |
| } |
| if (HAS_NATIVE_TA && SUPPORTS_PASSIVE && Polymer.Settings.passiveTouchGestures) { |
| return { passive: true }; |
| } |
| } |
| var IS_TOUCH_ONLY = navigator.userAgent.match(/iP(?:[oa]d|hone)|Android/); |
| var mouseCanceller = function (mouseEvent) { |
| var sc = mouseEvent.sourceCapabilities; |
| if (sc && !sc.firesTouchEvents) { |
| return; |
| } |
| mouseEvent[HANDLED_OBJ] = { skip: true }; |
| if (mouseEvent.type === 'click') { |
| var path = Polymer.dom(mouseEvent).path; |
| if (path) { |
| for (var i = 0; i < path.length; i++) { |
| if (path[i] === POINTERSTATE.mouse.target) { |
| return; |
| } |
| } |
| } |
| mouseEvent.preventDefault(); |
| mouseEvent.stopPropagation(); |
| } |
| }; |
| function setupTeardownMouseCanceller(setup) { |
| var events = IS_TOUCH_ONLY ? ['click'] : MOUSE_EVENTS; |
| for (var i = 0, en; i < events.length; i++) { |
| en = events[i]; |
| if (setup) { |
| document.addEventListener(en, mouseCanceller, true); |
| } else { |
| document.removeEventListener(en, mouseCanceller, true); |
| } |
| } |
| } |
| function ignoreMouse(ev) { |
| if (!POINTERSTATE.mouse.mouseIgnoreJob) { |
| setupTeardownMouseCanceller(true); |
| } |
| var unset = function () { |
| setupTeardownMouseCanceller(); |
| POINTERSTATE.mouse.target = null; |
| POINTERSTATE.mouse.mouseIgnoreJob = null; |
| }; |
| POINTERSTATE.mouse.target = Polymer.dom(ev).rootTarget; |
| POINTERSTATE.mouse.mouseIgnoreJob = Polymer.Debounce(POINTERSTATE.mouse.mouseIgnoreJob, unset, MOUSE_TIMEOUT); |
| } |
| function hasLeftMouseButton(ev) { |
| var type = ev.type; |
| if (!isMouseEvent(type)) { |
| return false; |
| } |
| if (type === 'mousemove') { |
| var buttons = ev.buttons === undefined ? 1 : ev.buttons; |
| if (ev instanceof window.MouseEvent && !MOUSE_HAS_BUTTONS) { |
| buttons = MOUSE_WHICH_TO_BUTTONS[ev.which] || 0; |
| } |
| return Boolean(buttons & 1); |
| } else { |
| var button = ev.button === undefined ? 0 : ev.button; |
| return button === 0; |
| } |
| } |
| function isSyntheticClick(ev) { |
| if (ev.type === 'click') { |
| if (ev.detail === 0) { |
| return true; |
| } |
| var t = Gestures.findOriginalTarget(ev); |
| var bcr = t.getBoundingClientRect(); |
| var x = ev.pageX, y = ev.pageY; |
| return !(x >= bcr.left && x <= bcr.right && (y >= bcr.top && y <= bcr.bottom)); |
| } |
| return false; |
| } |
| var POINTERSTATE = { |
| mouse: { |
| target: null, |
| mouseIgnoreJob: null |
| }, |
| touch: { |
| x: 0, |
| y: 0, |
| id: -1, |
| scrollDecided: false |
| } |
| }; |
| function firstTouchAction(ev) { |
| var path = Polymer.dom(ev).path; |
| var ta = 'auto'; |
| for (var i = 0, n; i < path.length; i++) { |
| n = path[i]; |
| if (n[TOUCH_ACTION]) { |
| ta = n[TOUCH_ACTION]; |
| break; |
| } |
| } |
| return ta; |
| } |
| function trackDocument(stateObj, movefn, upfn) { |
| stateObj.movefn = movefn; |
| stateObj.upfn = upfn; |
| document.addEventListener('mousemove', movefn); |
| document.addEventListener('mouseup', upfn); |
| } |
| function untrackDocument(stateObj) { |
| document.removeEventListener('mousemove', stateObj.movefn); |
| document.removeEventListener('mouseup', stateObj.upfn); |
| stateObj.movefn = null; |
| stateObj.upfn = null; |
| } |
| document.addEventListener('touchend', ignoreMouse, SUPPORTS_PASSIVE ? { passive: true } : false); |
| var Gestures = { |
| gestures: {}, |
| recognizers: [], |
| deepTargetFind: function (x, y) { |
| var node = document.elementFromPoint(x, y); |
| var next = node; |
| while (next && next.shadowRoot) { |
| next = next.shadowRoot.elementFromPoint(x, y); |
| if (next) { |
| node = next; |
| } |
| } |
| return node; |
| }, |
| findOriginalTarget: function (ev) { |
| if (ev.path) { |
| return ev.path[0]; |
| } |
| return ev.target; |
| }, |
| handleNative: function (ev) { |
| var handled; |
| var type = ev.type; |
| var node = wrap(ev.currentTarget); |
| var gobj = node[GESTURE_KEY]; |
| if (!gobj) { |
| return; |
| } |
| var gs = gobj[type]; |
| if (!gs) { |
| return; |
| } |
| if (!ev[HANDLED_OBJ]) { |
| ev[HANDLED_OBJ] = {}; |
| if (type.slice(0, 5) === 'touch') { |
| var t = ev.changedTouches[0]; |
| if (type === 'touchstart') { |
| if (ev.touches.length === 1) { |
| POINTERSTATE.touch.id = t.identifier; |
| } |
| } |
| if (POINTERSTATE.touch.id !== t.identifier) { |
| return; |
| } |
| if (!HAS_NATIVE_TA) { |
| if (type === 'touchstart' || type === 'touchmove') { |
| Gestures.handleTouchAction(ev); |
| } |
| } |
| } |
| } |
| handled = ev[HANDLED_OBJ]; |
| if (handled.skip) { |
| return; |
| } |
| var recognizers = Gestures.recognizers; |
| for (var i = 0, r; i < recognizers.length; i++) { |
| r = recognizers[i]; |
| if (gs[r.name] && !handled[r.name]) { |
| if (r.flow && r.flow.start.indexOf(ev.type) > -1 && r.reset) { |
| r.reset(); |
| } |
| } |
| } |
| for (i = 0, r; i < recognizers.length; i++) { |
| r = recognizers[i]; |
| if (gs[r.name] && !handled[r.name]) { |
| handled[r.name] = true; |
| r[type](ev); |
| } |
| } |
| }, |
| handleTouchAction: function (ev) { |
| var t = ev.changedTouches[0]; |
| var type = ev.type; |
| if (type === 'touchstart') { |
| POINTERSTATE.touch.x = t.clientX; |
| POINTERSTATE.touch.y = t.clientY; |
| POINTERSTATE.touch.scrollDecided = false; |
| } else if (type === 'touchmove') { |
| if (POINTERSTATE.touch.scrollDecided) { |
| return; |
| } |
| POINTERSTATE.touch.scrollDecided = true; |
| var ta = firstTouchAction(ev); |
| var prevent = false; |
| var dx = Math.abs(POINTERSTATE.touch.x - t.clientX); |
| var dy = Math.abs(POINTERSTATE.touch.y - t.clientY); |
| if (!ev.cancelable) { |
| } else if (ta === 'none') { |
| prevent = true; |
| } else if (ta === 'pan-x') { |
| prevent = dy > dx; |
| } else if (ta === 'pan-y') { |
| prevent = dx > dy; |
| } |
| if (prevent) { |
| ev.preventDefault(); |
| } else { |
| Gestures.prevent('track'); |
| } |
| } |
| }, |
| add: function (node, evType, handler) { |
| node = wrap(node); |
| var recognizer = this.gestures[evType]; |
| var deps = recognizer.deps; |
| var name = recognizer.name; |
| var gobj = node[GESTURE_KEY]; |
| if (!gobj) { |
| node[GESTURE_KEY] = gobj = {}; |
| } |
| for (var i = 0, dep, gd; i < deps.length; i++) { |
| dep = deps[i]; |
| if (IS_TOUCH_ONLY && isMouseEvent(dep) && dep !== 'click') { |
| continue; |
| } |
| gd = gobj[dep]; |
| if (!gd) { |
| gobj[dep] = gd = { _count: 0 }; |
| } |
| if (gd._count === 0) { |
| node.addEventListener(dep, this.handleNative, PASSIVE_TOUCH(dep)); |
| } |
| gd[name] = (gd[name] || 0) + 1; |
| gd._count = (gd._count || 0) + 1; |
| } |
| node.addEventListener(evType, handler); |
| if (recognizer.touchAction) { |
| this.setTouchAction(node, recognizer.touchAction); |
| } |
| }, |
| remove: function (node, evType, handler) { |
| node = wrap(node); |
| var recognizer = this.gestures[evType]; |
| var deps = recognizer.deps; |
| var name = recognizer.name; |
| var gobj = node[GESTURE_KEY]; |
| if (gobj) { |
| for (var i = 0, dep, gd; i < deps.length; i++) { |
| dep = deps[i]; |
| gd = gobj[dep]; |
| if (gd && gd[name]) { |
| gd[name] = (gd[name] || 1) - 1; |
| gd._count = (gd._count || 1) - 1; |
| if (gd._count === 0) { |
| node.removeEventListener(dep, this.handleNative, PASSIVE_TOUCH(dep)); |
| } |
| } |
| } |
| } |
| node.removeEventListener(evType, handler); |
| }, |
| register: function (recog) { |
| this.recognizers.push(recog); |
| for (var i = 0; i < recog.emits.length; i++) { |
| this.gestures[recog.emits[i]] = recog; |
| } |
| }, |
| findRecognizerByEvent: function (evName) { |
| for (var i = 0, r; i < this.recognizers.length; i++) { |
| r = this.recognizers[i]; |
| for (var j = 0, n; j < r.emits.length; j++) { |
| n = r.emits[j]; |
| if (n === evName) { |
| return r; |
| } |
| } |
| } |
| return null; |
| }, |
| setTouchAction: function (node, value) { |
| if (HAS_NATIVE_TA) { |
| node.style.touchAction = value; |
| } |
| node[TOUCH_ACTION] = value; |
| }, |
| fire: function (target, type, detail) { |
| var ev = Polymer.Base.fire(type, detail, { |
| node: target, |
| bubbles: true, |
| cancelable: true |
| }); |
| if (ev.defaultPrevented) { |
| var preventer = detail.preventer || detail.sourceEvent; |
| if (preventer && preventer.preventDefault) { |
| preventer.preventDefault(); |
| } |
| } |
| }, |
| prevent: function (evName) { |
| var recognizer = this.findRecognizerByEvent(evName); |
| if (recognizer.info) { |
| recognizer.info.prevent = true; |
| } |
| }, |
| resetMouseCanceller: function () { |
| if (POINTERSTATE.mouse.mouseIgnoreJob) { |
| POINTERSTATE.mouse.mouseIgnoreJob.complete(); |
| } |
| } |
| }; |
| Gestures.register({ |
| name: 'downup', |
| deps: [ |
| 'mousedown', |
| 'touchstart', |
| 'touchend' |
| ], |
| flow: { |
| start: [ |
| 'mousedown', |
| 'touchstart' |
| ], |
| end: [ |
| 'mouseup', |
| 'touchend' |
| ] |
| }, |
| emits: [ |
| 'down', |
| 'up' |
| ], |
| info: { |
| movefn: null, |
| upfn: null |
| }, |
| reset: function () { |
| untrackDocument(this.info); |
| }, |
| mousedown: function (e) { |
| if (!hasLeftMouseButton(e)) { |
| return; |
| } |
| var t = Gestures.findOriginalTarget(e); |
| var self = this; |
| var movefn = function movefn(e) { |
| if (!hasLeftMouseButton(e)) { |
| self.fire('up', t, e); |
| untrackDocument(self.info); |
| } |
| }; |
| var upfn = function upfn(e) { |
| if (hasLeftMouseButton(e)) { |
| self.fire('up', t, e); |
| } |
| untrackDocument(self.info); |
| }; |
| trackDocument(this.info, movefn, upfn); |
| this.fire('down', t, e); |
| }, |
| touchstart: function (e) { |
| this.fire('down', Gestures.findOriginalTarget(e), e.changedTouches[0], e); |
| }, |
| touchend: function (e) { |
| this.fire('up', Gestures.findOriginalTarget(e), e.changedTouches[0], e); |
| }, |
| fire: function (type, target, event, preventer) { |
| Gestures.fire(target, type, { |
| x: event.clientX, |
| y: event.clientY, |
| sourceEvent: event, |
| preventer: preventer, |
| prevent: function (e) { |
| return Gestures.prevent(e); |
| } |
| }); |
| } |
| }); |
| Gestures.register({ |
| name: 'track', |
| touchAction: 'none', |
| deps: [ |
| 'mousedown', |
| 'touchstart', |
| 'touchmove', |
| 'touchend' |
| ], |
| flow: { |
| start: [ |
| 'mousedown', |
| 'touchstart' |
| ], |
| end: [ |
| 'mouseup', |
| 'touchend' |
| ] |
| }, |
| emits: ['track'], |
| info: { |
| x: 0, |
| y: 0, |
| state: 'start', |
| started: false, |
| moves: [], |
| addMove: function (move) { |
| if (this.moves.length > TRACK_LENGTH) { |
| this.moves.shift(); |
| } |
| this.moves.push(move); |
| }, |
| movefn: null, |
| upfn: null, |
| prevent: false |
| }, |
| reset: function () { |
| this.info.state = 'start'; |
| this.info.started = false; |
| this.info.moves = []; |
| this.info.x = 0; |
| this.info.y = 0; |
| this.info.prevent = false; |
| untrackDocument(this.info); |
| }, |
| hasMovedEnough: function (x, y) { |
| if (this.info.prevent) { |
| return false; |
| } |
| if (this.info.started) { |
| return true; |
| } |
| var dx = Math.abs(this.info.x - x); |
| var dy = Math.abs(this.info.y - y); |
| return dx >= TRACK_DISTANCE || dy >= TRACK_DISTANCE; |
| }, |
| mousedown: function (e) { |
| if (!hasLeftMouseButton(e)) { |
| return; |
| } |
| var t = Gestures.findOriginalTarget(e); |
| var self = this; |
| var movefn = function movefn(e) { |
| var x = e.clientX, y = e.clientY; |
| if (self.hasMovedEnough(x, y)) { |
| self.info.state = self.info.started ? e.type === 'mouseup' ? 'end' : 'track' : 'start'; |
| if (self.info.state === 'start') { |
| Gestures.prevent('tap'); |
| } |
| self.info.addMove({ |
| x: x, |
| y: y |
| }); |
| if (!hasLeftMouseButton(e)) { |
| self.info.state = 'end'; |
| untrackDocument(self.info); |
| } |
| self.fire(t, e); |
| self.info.started = true; |
| } |
| }; |
| var upfn = function upfn(e) { |
| if (self.info.started) { |
| movefn(e); |
| } |
| untrackDocument(self.info); |
| }; |
| trackDocument(this.info, movefn, upfn); |
| this.info.x = e.clientX; |
| this.info.y = e.clientY; |
| }, |
| touchstart: function (e) { |
| var ct = e.changedTouches[0]; |
| this.info.x = ct.clientX; |
| this.info.y = ct.clientY; |
| }, |
| touchmove: function (e) { |
| var t = Gestures.findOriginalTarget(e); |
| var ct = e.changedTouches[0]; |
| var x = ct.clientX, y = ct.clientY; |
| if (this.hasMovedEnough(x, y)) { |
| if (this.info.state === 'start') { |
| Gestures.prevent('tap'); |
| } |
| this.info.addMove({ |
| x: x, |
| y: y |
| }); |
| this.fire(t, ct); |
| this.info.state = 'track'; |
| this.info.started = true; |
| } |
| }, |
| touchend: function (e) { |
| var t = Gestures.findOriginalTarget(e); |
| var ct = e.changedTouches[0]; |
| if (this.info.started) { |
| this.info.state = 'end'; |
| this.info.addMove({ |
| x: ct.clientX, |
| y: ct.clientY |
| }); |
| this.fire(t, ct, e); |
| } |
| }, |
| fire: function (target, touch, preventer) { |
| var secondlast = this.info.moves[this.info.moves.length - 2]; |
| var lastmove = this.info.moves[this.info.moves.length - 1]; |
| var dx = lastmove.x - this.info.x; |
| var dy = lastmove.y - this.info.y; |
| var ddx, ddy = 0; |
| if (secondlast) { |
| ddx = lastmove.x - secondlast.x; |
| ddy = lastmove.y - secondlast.y; |
| } |
| return Gestures.fire(target, 'track', { |
| state: this.info.state, |
| x: touch.clientX, |
| y: touch.clientY, |
| dx: dx, |
| dy: dy, |
| ddx: ddx, |
| ddy: ddy, |
| sourceEvent: touch, |
| preventer: preventer, |
| hover: function () { |
| return Gestures.deepTargetFind(touch.clientX, touch.clientY); |
| } |
| }); |
| } |
| }); |
| Gestures.register({ |
| name: 'tap', |
| deps: [ |
| 'mousedown', |
| 'click', |
| 'touchstart', |
| 'touchend' |
| ], |
| flow: { |
| start: [ |
| 'mousedown', |
| 'touchstart' |
| ], |
| end: [ |
| 'click', |
| 'touchend' |
| ] |
| }, |
| emits: ['tap'], |
| info: { |
| x: NaN, |
| y: NaN, |
| prevent: false |
| }, |
| reset: function () { |
| this.info.x = NaN; |
| this.info.y = NaN; |
| this.info.prevent = false; |
| }, |
| save: function (e) { |
| this.info.x = e.clientX; |
| this.info.y = e.clientY; |
| }, |
| mousedown: function (e) { |
| if (hasLeftMouseButton(e)) { |
| this.save(e); |
| } |
| }, |
| click: function (e) { |
| if (hasLeftMouseButton(e)) { |
| this.forward(e); |
| } |
| }, |
| touchstart: function (e) { |
| this.save(e.changedTouches[0], e); |
| }, |
| touchend: function (e) { |
| this.forward(e.changedTouches[0], e); |
| }, |
| forward: function (e, preventer) { |
| var dx = Math.abs(e.clientX - this.info.x); |
| var dy = Math.abs(e.clientY - this.info.y); |
| var t = Gestures.findOriginalTarget(e); |
| if (isNaN(dx) || isNaN(dy) || dx <= TAP_DISTANCE && dy <= TAP_DISTANCE || isSyntheticClick(e)) { |
| if (!this.info.prevent) { |
| Gestures.fire(t, 'tap', { |
| x: e.clientX, |
| y: e.clientY, |
| sourceEvent: e, |
| preventer: preventer |
| }); |
| } |
| } |
| } |
| }); |
| var DIRECTION_MAP = { |
| x: 'pan-x', |
| y: 'pan-y', |
| none: 'none', |
| all: 'auto' |
| }; |
| Polymer.Base._addFeature({ |
| _setupGestures: function () { |
| this.__polymerGestures = null; |
| }, |
| _listen: function (node, eventName, handler) { |
| if (Gestures.gestures[eventName]) { |
| Gestures.add(node, eventName, handler); |
| } else { |
| node.addEventListener(eventName, handler); |
| } |
| }, |
| _unlisten: function (node, eventName, handler) { |
| if (Gestures.gestures[eventName]) { |
| Gestures.remove(node, eventName, handler); |
| } else { |
| node.removeEventListener(eventName, handler); |
| } |
| }, |
| setScrollDirection: function (direction, node) { |
| node = node || this; |
| Gestures.setTouchAction(node, DIRECTION_MAP[direction] || 'auto'); |
| } |
| }); |
| Polymer.Gestures = Gestures; |
| }());(function () { |
| 'use strict'; |
| Polymer.Base._addFeature({ |
| $$: function (slctr) { |
| return Polymer.dom(this.root).querySelector(slctr); |
| }, |
| toggleClass: function (name, bool, node) { |
| node = node || this; |
| if (arguments.length == 1) { |
| bool = !node.classList.contains(name); |
| } |
| if (bool) { |
| Polymer.dom(node).classList.add(name); |
| } else { |
| Polymer.dom(node).classList.remove(name); |
| } |
| }, |
| toggleAttribute: function (name, bool, node) { |
| node = node || this; |
| if (arguments.length == 1) { |
| bool = !node.hasAttribute(name); |
| } |
| if (bool) { |
| Polymer.dom(node).setAttribute(name, ''); |
| } else { |
| Polymer.dom(node).removeAttribute(name); |
| } |
| }, |
| classFollows: function (name, toElement, fromElement) { |
| if (fromElement) { |
| Polymer.dom(fromElement).classList.remove(name); |
| } |
| if (toElement) { |
| Polymer.dom(toElement).classList.add(name); |
| } |
| }, |
| attributeFollows: function (name, toElement, fromElement) { |
| if (fromElement) { |
| Polymer.dom(fromElement).removeAttribute(name); |
| } |
| if (toElement) { |
| Polymer.dom(toElement).setAttribute(name, ''); |
| } |
| }, |
| getEffectiveChildNodes: function () { |
| return Polymer.dom(this).getEffectiveChildNodes(); |
| }, |
| getEffectiveChildren: function () { |
| var list = Polymer.dom(this).getEffectiveChildNodes(); |
| return list.filter(function (n) { |
| return n.nodeType === Node.ELEMENT_NODE; |
| }); |
| }, |
| getEffectiveTextContent: function () { |
| var cn = this.getEffectiveChildNodes(); |
| var tc = []; |
| for (var i = 0, c; c = cn[i]; i++) { |
| if (c.nodeType !== Node.COMMENT_NODE) { |
| tc.push(Polymer.dom(c).textContent); |
| } |
| } |
| return tc.join(''); |
| }, |
| queryEffectiveChildren: function (slctr) { |
| var e$ = Polymer.dom(this).queryDistributedElements(slctr); |
| return e$ && e$[0]; |
| }, |
| queryAllEffectiveChildren: function (slctr) { |
| return Polymer.dom(this).queryDistributedElements(slctr); |
| }, |
| getContentChildNodes: function (slctr) { |
| var content = Polymer.dom(this.root).querySelector(slctr || 'content'); |
| return content ? Polymer.dom(content).getDistributedNodes() : []; |
| }, |
| getContentChildren: function (slctr) { |
| return this.getContentChildNodes(slctr).filter(function (n) { |
| return n.nodeType === Node.ELEMENT_NODE; |
| }); |
| }, |
| fire: function (type, detail, options) { |
| options = options || Polymer.nob; |
| var node = options.node || this; |
| detail = detail === null || detail === undefined ? {} : detail; |
| var bubbles = options.bubbles === undefined ? true : options.bubbles; |
| var cancelable = Boolean(options.cancelable); |
| var useCache = options._useCache; |
| var event = this._getEvent(type, bubbles, cancelable, useCache); |
| event.detail = detail; |
| if (useCache) { |
| this.__eventCache[type] = null; |
| } |
| node.dispatchEvent(event); |
| if (useCache) { |
| this.__eventCache[type] = event; |
| } |
| return event; |
| }, |
| __eventCache: {}, |
| _getEvent: function (type, bubbles, cancelable, useCache) { |
| var event = useCache && this.__eventCache[type]; |
| if (!event || (event.bubbles != bubbles || event.cancelable != cancelable)) { |
| event = new Event(type, { |
| bubbles: Boolean(bubbles), |
| cancelable: cancelable |
| }); |
| } |
| return event; |
| }, |
| async: function (callback, waitTime) { |
| var self = this; |
| return Polymer.Async.run(function () { |
| callback.call(self); |
| }, waitTime); |
| }, |
| cancelAsync: function (handle) { |
| Polymer.Async.cancel(handle); |
| }, |
| arrayDelete: function (path, item) { |
| var index; |
| if (Array.isArray(path)) { |
| index = path.indexOf(item); |
| if (index >= 0) { |
| return path.splice(index, 1); |
| } |
| } else { |
| var arr = this._get(path); |
| index = arr.indexOf(item); |
| if (index >= 0) { |
| return this.splice(path, index, 1); |
| } |
| } |
| }, |
| transform: function (transform, node) { |
| node = node || this; |
| node.style.webkitTransform = transform; |
| node.style.transform = transform; |
| }, |
| translate3d: function (x, y, z, node) { |
| node = node || this; |
| this.transform('translate3d(' + x + ',' + y + ',' + z + ')', node); |
| }, |
| importHref: function (href, onload, onerror, optAsync) { |
| var link = document.createElement('link'); |
| link.rel = 'import'; |
| link.href = href; |
| var list = Polymer.Base.importHref.imported = Polymer.Base.importHref.imported || {}; |
| var cached = list[link.href]; |
| var imprt = cached || link; |
| var self = this; |
| var loadListener = function (e) { |
| e.target.__firedLoad = true; |
| e.target.removeEventListener('load', loadListener); |
| e.target.removeEventListener('error', errorListener); |
| return onload.call(self, e); |
| }; |
| var errorListener = function (e) { |
| e.target.__firedError = true; |
| e.target.removeEventListener('load', loadListener); |
| e.target.removeEventListener('error', errorListener); |
| return onerror.call(self, e); |
| }; |
| if (onload) { |
| imprt.addEventListener('load', loadListener); |
| } |
| if (onerror) { |
| imprt.addEventListener('error', errorListener); |
| } |
| if (cached) { |
| if (cached.__firedLoad) { |
| cached.dispatchEvent(new Event('load')); |
| } |
| if (cached.__firedError) { |
| cached.dispatchEvent(new Event('error')); |
| } |
| } else { |
| list[link.href] = link; |
| optAsync = Boolean(optAsync); |
| if (optAsync) { |
| link.setAttribute('async', ''); |
| } |
| document.head.appendChild(link); |
| } |
| return imprt; |
| }, |
| create: function (tag, props) { |
| var elt = document.createElement(tag); |
| if (props) { |
| for (var n in props) { |
| elt[n] = props[n]; |
| } |
| } |
| return elt; |
| }, |
| isLightDescendant: function (node) { |
| return this !== node && this.contains(node) && Polymer.dom(this).getOwnerRoot() === Polymer.dom(node).getOwnerRoot(); |
| }, |
| isLocalDescendant: function (node) { |
| return this.root === Polymer.dom(node).getOwnerRoot(); |
| } |
| }); |
| if (!Polymer.Settings.useNativeCustomElements) { |
| var importHref = Polymer.Base.importHref; |
| Polymer.Base.importHref = function (href, onload, onerror, optAsync) { |
| CustomElements.ready = false; |
| var loadFn = function (e) { |
| CustomElements.upgradeDocumentTree(document); |
| CustomElements.ready = true; |
| if (onload) { |
| return onload.call(this, e); |
| } |
| }; |
| return importHref.call(this, href, loadFn, onerror, optAsync); |
| }; |
| } |
| }());Polymer.Bind = { |
| prepareModel: function (model) { |
| Polymer.Base.mixin(model, this._modelApi); |
| }, |
| _modelApi: { |
| _notifyChange: function (source, event, value) { |
| value = value === undefined ? this[source] : value; |
| event = event || Polymer.CaseMap.camelToDashCase(source) + '-changed'; |
| this.fire(event, { value: value }, { |
| bubbles: false, |
| cancelable: false, |
| _useCache: Polymer.Settings.eventDataCache || !Polymer.Settings.isIE |
| }); |
| }, |
| _propertySetter: function (property, value, effects, fromAbove) { |
| var old = this.__data__[property]; |
| if (old !== value && (old === old || value === value)) { |
| this.__data__[property] = value; |
| if (typeof value == 'object') { |
| this._clearPath(property); |
| } |
| if (this._propertyChanged) { |
| this._propertyChanged(property, value, old); |
| } |
| if (effects) { |
| this._effectEffects(property, value, effects, old, fromAbove); |
| } |
| } |
| return old; |
| }, |
| __setProperty: function (property, value, quiet, node) { |
| node = node || this; |
| var effects = node._propertyEffects && node._propertyEffects[property]; |
| if (effects) { |
| node._propertySetter(property, value, effects, quiet); |
| } else if (node[property] !== value) { |
| node[property] = value; |
| } |
| }, |
| _effectEffects: function (property, value, effects, old, fromAbove) { |
| for (var i = 0, l = effects.length, fx; i < l && (fx = effects[i]); i++) { |
| fx.fn.call(this, property, this[property], fx.effect, old, fromAbove); |
| } |
| }, |
| _clearPath: function (path) { |
| for (var prop in this.__data__) { |
| if (Polymer.Path.isDescendant(path, prop)) { |
| this.__data__[prop] = undefined; |
| } |
| } |
| } |
| }, |
| ensurePropertyEffects: function (model, property) { |
| if (!model._propertyEffects) { |
| model._propertyEffects = {}; |
| } |
| var fx = model._propertyEffects[property]; |
| if (!fx) { |
| fx = model._propertyEffects[property] = []; |
| } |
| return fx; |
| }, |
| addPropertyEffect: function (model, property, kind, effect) { |
| var fx = this.ensurePropertyEffects(model, property); |
| var propEffect = { |
| kind: kind, |
| effect: effect, |
| fn: Polymer.Bind['_' + kind + 'Effect'] |
| }; |
| fx.push(propEffect); |
| return propEffect; |
| }, |
| createBindings: function (model) { |
| var fx$ = model._propertyEffects; |
| if (fx$) { |
| for (var n in fx$) { |
| var fx = fx$[n]; |
| fx.sort(this._sortPropertyEffects); |
| this._createAccessors(model, n, fx); |
| } |
| } |
| }, |
| _sortPropertyEffects: function () { |
| var EFFECT_ORDER = { |
| 'compute': 0, |
| 'annotation': 1, |
| 'annotatedComputation': 2, |
| 'reflect': 3, |
| 'notify': 4, |
| 'observer': 5, |
| 'complexObserver': 6, |
| 'function': 7 |
| }; |
| return function (a, b) { |
| return EFFECT_ORDER[a.kind] - EFFECT_ORDER[b.kind]; |
| }; |
| }(), |
| _createAccessors: function (model, property, effects) { |
| var defun = { |
| get: function () { |
| return this.__data__[property]; |
| } |
| }; |
| var setter = function (value) { |
| this._propertySetter(property, value, effects); |
| }; |
| var info = model.getPropertyInfo && model.getPropertyInfo(property); |
| if (info && info.readOnly) { |
| if (!info.computed) { |
| model['_set' + this.upper(property)] = setter; |
| } |
| } else { |
| defun.set = setter; |
| } |
| Object.defineProperty(model, property, defun); |
| }, |
| upper: function (name) { |
| return name[0].toUpperCase() + name.substring(1); |
| }, |
| _addAnnotatedListener: function (model, index, property, path, event, negated) { |
| if (!model._bindListeners) { |
| model._bindListeners = []; |
| } |
| var fn = this._notedListenerFactory(property, path, Polymer.Path.isDeep(path), negated); |
| var eventName = event || Polymer.CaseMap.camelToDashCase(property) + '-changed'; |
| model._bindListeners.push({ |
| index: index, |
| property: property, |
| path: path, |
| changedFn: fn, |
| event: eventName |
| }); |
| }, |
| _isEventBogus: function (e, target) { |
| return e.path && e.path[0] !== target; |
| }, |
| _notedListenerFactory: function (property, path, isStructured, negated) { |
| return function (target, value, targetPath) { |
| if (targetPath) { |
| var newPath = Polymer.Path.translate(property, path, targetPath); |
| this._notifyPath(newPath, value); |
| } else { |
| value = target[property]; |
| if (negated) { |
| value = !value; |
| } |
| if (!isStructured) { |
| this[path] = value; |
| } else { |
| if (this.__data__[path] != value) { |
| this.set(path, value); |
| } |
| } |
| } |
| }; |
| }, |
| prepareInstance: function (inst) { |
| inst.__data__ = Object.create(null); |
| }, |
| setupBindListeners: function (inst) { |
| var b$ = inst._bindListeners; |
| for (var i = 0, l = b$.length, info; i < l && (info = b$[i]); i++) { |
| var node = inst._nodes[info.index]; |
| this._addNotifyListener(node, inst, info.event, info.changedFn); |
| } |
| }, |
| _addNotifyListener: function (element, context, event, changedFn) { |
| element.addEventListener(event, function (e) { |
| return context._notifyListener(changedFn, e); |
| }); |
| } |
| };Polymer.Base.mixin(Polymer.Bind, { |
| _shouldAddListener: function (effect) { |
| return effect.name && effect.kind != 'attribute' && effect.kind != 'text' && !effect.isCompound && effect.parts[0].mode === '{'; |
| }, |
| _annotationEffect: function (source, value, effect) { |
| if (source != effect.value) { |
| value = this._get(effect.value); |
| this.__data__[effect.value] = value; |
| } |
| this._applyEffectValue(effect, value); |
| }, |
| _reflectEffect: function (source, value, effect) { |
| this.reflectPropertyToAttribute(source, effect.attribute, value); |
| }, |
| _notifyEffect: function (source, value, effect, old, fromAbove) { |
| if (!fromAbove) { |
| this._notifyChange(source, effect.event, value); |
| } |
| }, |
| _functionEffect: function (source, value, fn, old, fromAbove) { |
| fn.call(this, source, value, old, fromAbove); |
| }, |
| _observerEffect: function (source, value, effect, old) { |
| var fn = this[effect.method]; |
| if (fn) { |
| fn.call(this, value, old); |
| } else { |
| this._warn(this._logf('_observerEffect', 'observer method `' + effect.method + '` not defined')); |
| } |
| }, |
| _complexObserverEffect: function (source, value, effect) { |
| var fn = this[effect.method]; |
| if (fn) { |
| var args = Polymer.Bind._marshalArgs(this.__data__, effect, source, value); |
| if (args) { |
| fn.apply(this, args); |
| } |
| } else if (effect.dynamicFn) { |
| } else { |
| this._warn(this._logf('_complexObserverEffect', 'observer method `' + effect.method + '` not defined')); |
| } |
| }, |
| _computeEffect: function (source, value, effect) { |
| var fn = this[effect.method]; |
| if (fn) { |
| var args = Polymer.Bind._marshalArgs(this.__data__, effect, source, value); |
| if (args) { |
| var computedvalue = fn.apply(this, args); |
| this.__setProperty(effect.name, computedvalue); |
| } |
| } else if (effect.dynamicFn) { |
| } else { |
| this._warn(this._logf('_computeEffect', 'compute method `' + effect.method + '` not defined')); |
| } |
| }, |
| _annotatedComputationEffect: function (source, value, effect) { |
| var computedHost = this._rootDataHost || this; |
| var fn = computedHost[effect.method]; |
| if (fn) { |
| var args = Polymer.Bind._marshalArgs(this.__data__, effect, source, value); |
| if (args) { |
| var computedvalue = fn.apply(computedHost, args); |
| this._applyEffectValue(effect, computedvalue); |
| } |
| } else if (effect.dynamicFn) { |
| } else { |
| computedHost._warn(computedHost._logf('_annotatedComputationEffect', 'compute method `' + effect.method + '` not defined')); |
| } |
| }, |
| _marshalArgs: function (model, effect, path, value) { |
| var values = []; |
| var args = effect.args; |
| var bailoutEarly = args.length > 1 || effect.dynamicFn; |
| for (var i = 0, l = args.length; i < l; i++) { |
| var arg = args[i]; |
| var name = arg.name; |
| var v; |
| if (arg.literal) { |
| v = arg.value; |
| } else if (path === name) { |
| v = value; |
| } else { |
| v = model[name]; |
| if (v === undefined && arg.structured) { |
| v = Polymer.Base._get(name, model); |
| } |
| } |
| if (bailoutEarly && v === undefined) { |
| return; |
| } |
| if (arg.wildcard) { |
| var matches = Polymer.Path.isAncestor(path, name); |
| values[i] = { |
| path: matches ? path : name, |
| value: matches ? value : v, |
| base: v |
| }; |
| } else { |
| values[i] = v; |
| } |
| } |
| return values; |
| } |
| });Polymer.Base._addFeature({ |
| _addPropertyEffect: function (property, kind, effect) { |
| var prop = Polymer.Bind.addPropertyEffect(this, property, kind, effect); |
| prop.pathFn = this['_' + prop.kind + 'PathEffect']; |
| }, |
| _prepEffects: function () { |
| Polymer.Bind.prepareModel(this); |
| this._addAnnotationEffects(this._notes); |
| }, |
| _prepBindings: function () { |
| Polymer.Bind.createBindings(this); |
| }, |
| _addPropertyEffects: function (properties) { |
| if (properties) { |
| for (var p in properties) { |
| var prop = properties[p]; |
| if (prop.observer) { |
| this._addObserverEffect(p, prop.observer); |
| } |
| if (prop.computed) { |
| prop.readOnly = true; |
| this._addComputedEffect(p, prop.computed); |
| } |
| if (prop.notify) { |
| this._addPropertyEffect(p, 'notify', { event: Polymer.CaseMap.camelToDashCase(p) + '-changed' }); |
| } |
| if (prop.reflectToAttribute) { |
| var attr = Polymer.CaseMap.camelToDashCase(p); |
| if (attr[0] === '-') { |
| this._warn(this._logf('_addPropertyEffects', 'Property ' + p + ' cannot be reflected to attribute ' + attr + ' because "-" is not a valid starting attribute name. Use a lowercase first letter for the property instead.')); |
| } else { |
| this._addPropertyEffect(p, 'reflect', { attribute: attr }); |
| } |
| } |
| if (prop.readOnly) { |
| Polymer.Bind.ensurePropertyEffects(this, p); |
| } |
| } |
| } |
| }, |
| _addComputedEffect: function (name, expression) { |
| var sig = this._parseMethod(expression); |
| var dynamicFn = sig.dynamicFn; |
| for (var i = 0, arg; i < sig.args.length && (arg = sig.args[i]); i++) { |
| this._addPropertyEffect(arg.model, 'compute', { |
| method: sig.method, |
| args: sig.args, |
| trigger: arg, |
| name: name, |
| dynamicFn: dynamicFn |
| }); |
| } |
| if (dynamicFn) { |
| this._addPropertyEffect(sig.method, 'compute', { |
| method: sig.method, |
| args: sig.args, |
| trigger: null, |
| name: name, |
| dynamicFn: dynamicFn |
| }); |
| } |
| }, |
| _addObserverEffect: function (property, observer) { |
| this._addPropertyEffect(property, 'observer', { |
| method: observer, |
| property: property |
| }); |
| }, |
| _addComplexObserverEffects: function (observers) { |
| if (observers) { |
| for (var i = 0, o; i < observers.length && (o = observers[i]); i++) { |
| this._addComplexObserverEffect(o); |
| } |
| } |
| }, |
| _addComplexObserverEffect: function (observer) { |
| var sig = this._parseMethod(observer); |
| if (!sig) { |
| throw new Error('Malformed observer expression \'' + observer + '\''); |
| } |
| var dynamicFn = sig.dynamicFn; |
| for (var i = 0, arg; i < sig.args.length && (arg = sig.args[i]); i++) { |
| this._addPropertyEffect(arg.model, 'complexObserver', { |
| method: sig.method, |
| args: sig.args, |
| trigger: arg, |
| dynamicFn: dynamicFn |
| }); |
| } |
| if (dynamicFn) { |
| this._addPropertyEffect(sig.method, 'complexObserver', { |
| method: sig.method, |
| args: sig.args, |
| trigger: null, |
| dynamicFn: dynamicFn |
| }); |
| } |
| }, |
| _addAnnotationEffects: function (notes) { |
| for (var i = 0, note; i < notes.length && (note = notes[i]); i++) { |
| var b$ = note.bindings; |
| for (var j = 0, binding; j < b$.length && (binding = b$[j]); j++) { |
| this._addAnnotationEffect(binding, i); |
| } |
| } |
| }, |
| _addAnnotationEffect: function (note, index) { |
| if (Polymer.Bind._shouldAddListener(note)) { |
| Polymer.Bind._addAnnotatedListener(this, index, note.name, note.parts[0].value, note.parts[0].event, note.parts[0].negate); |
| } |
| for (var i = 0; i < note.parts.length; i++) { |
| var part = note.parts[i]; |
| if (part.signature) { |
| this._addAnnotatedComputationEffect(note, part, index); |
| } else if (!part.literal) { |
| if (note.kind === 'attribute' && note.name[0] === '-') { |
| this._warn(this._logf('_addAnnotationEffect', 'Cannot set attribute ' + note.name + ' because "-" is not a valid attribute starting character')); |
| } else { |
| this._addPropertyEffect(part.model, 'annotation', { |
| kind: note.kind, |
| index: index, |
| name: note.name, |
| propertyName: note.propertyName, |
| value: part.value, |
| isCompound: note.isCompound, |
| compoundIndex: part.compoundIndex, |
| event: part.event, |
| customEvent: part.customEvent, |
| negate: part.negate |
| }); |
| } |
| } |
| } |
| }, |
| _addAnnotatedComputationEffect: function (note, part, index) { |
| var sig = part.signature; |
| if (sig.static) { |
| this.__addAnnotatedComputationEffect('__static__', index, note, part, null); |
| } else { |
| for (var i = 0, arg; i < sig.args.length && (arg = sig.args[i]); i++) { |
| if (!arg.literal) { |
| this.__addAnnotatedComputationEffect(arg.model, index, note, part, arg); |
| } |
| } |
| if (sig.dynamicFn) { |
| this.__addAnnotatedComputationEffect(sig.method, index, note, part, null); |
| } |
| } |
| }, |
| __addAnnotatedComputationEffect: function (property, index, note, part, trigger) { |
| this._addPropertyEffect(property, 'annotatedComputation', { |
| index: index, |
| isCompound: note.isCompound, |
| compoundIndex: part.compoundIndex, |
| kind: note.kind, |
| name: note.name, |
| negate: part.negate, |
| method: part.signature.method, |
| args: part.signature.args, |
| trigger: trigger, |
| dynamicFn: part.signature.dynamicFn |
| }); |
| }, |
| _parseMethod: function (expression) { |
| var m = expression.match(/([^\s]+?)\(([\s\S]*)\)/); |
| if (m) { |
| var sig = { |
| method: m[1], |
| static: true |
| }; |
| if (this.getPropertyInfo(sig.method) !== Polymer.nob) { |
| sig.static = false; |
| sig.dynamicFn = true; |
| } |
| if (m[2].trim()) { |
| var args = m[2].replace(/\\,/g, ',').split(','); |
| return this._parseArgs(args, sig); |
| } else { |
| sig.args = Polymer.nar; |
| return sig; |
| } |
| } |
| }, |
| _parseArgs: function (argList, sig) { |
| sig.args = argList.map(function (rawArg) { |
| var arg = this._parseArg(rawArg); |
| if (!arg.literal) { |
| sig.static = false; |
| } |
| return arg; |
| }, this); |
| return sig; |
| }, |
| _parseArg: function (rawArg) { |
| var arg = rawArg.trim().replace(/,/g, ',').replace(/\\(.)/g, '$1'); |
| var a = { name: arg }; |
| var fc = arg[0]; |
| if (fc === '-') { |
| fc = arg[1]; |
| } |
| if (fc >= '0' && fc <= '9') { |
| fc = '#'; |
| } |
| switch (fc) { |
| case '\'': |
| case '"': |
| a.value = arg.slice(1, -1); |
| a.literal = true; |
| break; |
| case '#': |
| a.value = Number(arg); |
| a.literal = true; |
| break; |
| } |
| if (!a.literal) { |
| a.model = Polymer.Path.root(arg); |
| a.structured = Polymer.Path.isDeep(arg); |
| if (a.structured) { |
| a.wildcard = arg.slice(-2) == '.*'; |
| if (a.wildcard) { |
| a.name = arg.slice(0, -2); |
| } |
| } |
| } |
| return a; |
| }, |
| _marshalInstanceEffects: function () { |
| Polymer.Bind.prepareInstance(this); |
| if (this._bindListeners) { |
| Polymer.Bind.setupBindListeners(this); |
| } |
| }, |
| _applyEffectValue: function (info, value) { |
| var node = this._nodes[info.index]; |
| var property = info.name; |
| value = this._computeFinalAnnotationValue(node, property, value, info); |
| if (info.kind == 'attribute') { |
| this.serializeValueToAttribute(value, property, node); |
| } else { |
| var pinfo = node._propertyInfo && node._propertyInfo[property]; |
| if (pinfo && pinfo.readOnly) { |
| return; |
| } |
| this.__setProperty(property, value, Polymer.Settings.suppressBindingNotifications, node); |
| } |
| }, |
| _computeFinalAnnotationValue: function (node, property, value, info) { |
| if (info.negate) { |
| value = !value; |
| } |
| if (info.isCompound) { |
| var storage = node.__compoundStorage__[property]; |
| storage[info.compoundIndex] = value; |
| value = storage.join(''); |
| } |
| if (info.kind !== 'attribute') { |
| if (property === 'className') { |
| value = this._scopeElementClass(node, value); |
| } |
| if (property === 'textContent' || node.localName == 'input' && property == 'value') { |
| value = value == undefined ? '' : value; |
| } |
| } |
| return value; |
| }, |
| _executeStaticEffects: function () { |
| if (this._propertyEffects && this._propertyEffects.__static__) { |
| this._effectEffects('__static__', null, this._propertyEffects.__static__); |
| } |
| } |
| });(function () { |
| var usePolyfillProto = Polymer.Settings.usePolyfillProto; |
| var avoidInstanceProperties = Boolean(Object.getOwnPropertyDescriptor(document.documentElement, 'properties')); |
| Polymer.Base._addFeature({ |
| _setupConfigure: function (initialConfig) { |
| this._config = {}; |
| this._handlers = []; |
| this._aboveConfig = null; |
| if (initialConfig) { |
| for (var i in initialConfig) { |
| if (initialConfig[i] !== undefined) { |
| this._config[i] = initialConfig[i]; |
| } |
| } |
| } |
| }, |
| _marshalAttributes: function () { |
| this._takeAttributesToModel(this._config); |
| }, |
| _attributeChangedImpl: function (name) { |
| var model = this._clientsReadied ? this : this._config; |
| this._setAttributeToProperty(model, name); |
| }, |
| _configValue: function (name, value) { |
| var info = this._propertyInfo[name]; |
| if (!info || !info.readOnly) { |
| this._config[name] = value; |
| } |
| }, |
| _beforeClientsReady: function () { |
| this._configure(); |
| }, |
| _configure: function () { |
| this._configureAnnotationReferences(); |
| this._configureInstanceProperties(); |
| this._aboveConfig = this.mixin({}, this._config); |
| var config = {}; |
| for (var i = 0; i < this.behaviors.length; i++) { |
| this._configureProperties(this.behaviors[i].properties, config); |
| } |
| this._configureProperties(avoidInstanceProperties ? this.__proto__.properties : this.properties, config); |
| this.mixin(config, this._aboveConfig); |
| this._config = config; |
| if (this._clients && this._clients.length) { |
| this._distributeConfig(this._config); |
| } |
| }, |
| _configureInstanceProperties: function () { |
| for (var i in this._propertyEffects) { |
| if (!usePolyfillProto && this.hasOwnProperty(i)) { |
| this._configValue(i, this[i]); |
| delete this[i]; |
| } |
| } |
| }, |
| _configureProperties: function (properties, config) { |
| for (var i in properties) { |
| var c = properties[i]; |
| if (c.value !== undefined) { |
| var value = c.value; |
| if (typeof value == 'function') { |
| value = value.call(this, this._config); |
| } |
| config[i] = value; |
| } |
| } |
| }, |
| _distributeConfig: function (config) { |
| var fx$ = this._propertyEffects; |
| if (fx$) { |
| for (var p in config) { |
| var fx = fx$[p]; |
| if (fx) { |
| for (var i = 0, l = fx.length, x; i < l && (x = fx[i]); i++) { |
| if (x.kind === 'annotation') { |
| var node = this._nodes[x.effect.index]; |
| var name = x.effect.propertyName; |
| var isAttr = x.effect.kind == 'attribute'; |
| var hasEffect = node._propertyEffects && node._propertyEffects[name]; |
| if (node._configValue && (hasEffect || !isAttr)) { |
| var value = p === x.effect.value ? config[p] : this._get(x.effect.value, config); |
| value = this._computeFinalAnnotationValue(node, name, value, x.effect); |
| if (isAttr) { |
| value = node.deserialize(this.serialize(value), node._propertyInfo[name].type); |
| } |
| node._configValue(name, value); |
| } |
| } |
| } |
| } |
| } |
| } |
| }, |
| _afterClientsReady: function () { |
| this.importPath = this._importPath; |
| this.rootPath = Polymer.rootPath; |
| this._executeStaticEffects(); |
| this._applyConfig(this._config, this._aboveConfig); |
| this._flushHandlers(); |
| }, |
| _applyConfig: function (config, aboveConfig) { |
| for (var n in config) { |
| if (this[n] === undefined) { |
| this.__setProperty(n, config[n], n in aboveConfig); |
| } |
| } |
| }, |
| _notifyListener: function (fn, e) { |
| if (!Polymer.Bind._isEventBogus(e, e.target)) { |
| var value, path; |
| if (e.detail) { |
| value = e.detail.value; |
| path = e.detail.path; |
| } |
| if (!this._clientsReadied) { |
| this._queueHandler([ |
| fn, |
| e.target, |
| value, |
| path |
| ]); |
| } else { |
| return fn.call(this, e.target, value, path); |
| } |
| } |
| }, |
| _queueHandler: function (args) { |
| this._handlers.push(args); |
| }, |
| _flushHandlers: function () { |
| var h$ = this._handlers; |
| for (var i = 0, l = h$.length, h; i < l && (h = h$[i]); i++) { |
| h[0].call(this, h[1], h[2], h[3]); |
| } |
| this._handlers = []; |
| } |
| }); |
| }());(function () { |
| 'use strict'; |
| var Path = Polymer.Path; |
| Polymer.Base._addFeature({ |
| notifyPath: function (path, value, fromAbove) { |
| var info = {}; |
| var v = this._get(path, this, info); |
| if (arguments.length === 1) { |
| value = v; |
| } |
| if (info.path) { |
| this._notifyPath(info.path, value, fromAbove); |
| } |
| }, |
| _notifyPath: function (path, value, fromAbove) { |
| var old = this._propertySetter(path, value); |
| if (old !== value && (old === old || value === value)) { |
| this._pathEffector(path, value); |
| if (!fromAbove) { |
| this._notifyPathUp(path, value); |
| } |
| return true; |
| } |
| }, |
| _getPathParts: function (path) { |
| if (Array.isArray(path)) { |
| var parts = []; |
| for (var i = 0; i < path.length; i++) { |
| var args = path[i].toString().split('.'); |
| for (var j = 0; j < args.length; j++) { |
| parts.push(args[j]); |
| } |
| } |
| return parts; |
| } else { |
| return path.toString().split('.'); |
| } |
| }, |
| set: function (path, value, root) { |
| var prop = root || this; |
| var parts = this._getPathParts(path); |
| var array; |
| var last = parts[parts.length - 1]; |
| if (parts.length > 1) { |
| for (var i = 0; i < parts.length - 1; i++) { |
| var part = parts[i]; |
| if (array && part[0] == '#') { |
| prop = Polymer.Collection.get(array).getItem(part); |
| } else { |
| prop = prop[part]; |
| if (array && parseInt(part, 10) == part) { |
| parts[i] = Polymer.Collection.get(array).getKey(prop); |
| } |
| } |
| if (!prop) { |
| return; |
| } |
| array = Array.isArray(prop) ? prop : null; |
| } |
| if (array) { |
| var coll = Polymer.Collection.get(array); |
| var old, key; |
| if (last[0] == '#') { |
| key = last; |
| old = coll.getItem(key); |
| last = array.indexOf(old); |
| coll.setItem(key, value); |
| } else if (parseInt(last, 10) == last) { |
| old = prop[last]; |
| key = coll.getKey(old); |
| parts[i] = key; |
| coll.setItem(key, value); |
| } |
| } |
| prop[last] = value; |
| if (!root) { |
| this._notifyPath(parts.join('.'), value); |
| } |
| } else { |
| prop[path] = value; |
| } |
| }, |
| get: function (path, root) { |
| return this._get(path, root); |
| }, |
| _get: function (path, root, info) { |
| var prop = root || this; |
| var parts = this._getPathParts(path); |
| var array; |
| for (var i = 0; i < parts.length; i++) { |
| if (!prop) { |
| return; |
| } |
| var part = parts[i]; |
| if (array && part[0] == '#') { |
| prop = Polymer.Collection.get(array).getItem(part); |
| } else { |
| prop = prop[part]; |
| if (info && array && parseInt(part, 10) == part) { |
| parts[i] = Polymer.Collection.get(array).getKey(prop); |
| } |
| } |
| array = Array.isArray(prop) ? prop : null; |
| } |
| if (info) { |
| info.path = parts.join('.'); |
| } |
| return prop; |
| }, |
| _pathEffector: function (path, value) { |
| var model = Path.root(path); |
| var fx$ = this._propertyEffects && this._propertyEffects[model]; |
| if (fx$) { |
| for (var i = 0, fx; i < fx$.length && (fx = fx$[i]); i++) { |
| var fxFn = fx.pathFn; |
| if (fxFn) { |
| fxFn.call(this, path, value, fx.effect); |
| } |
| } |
| } |
| if (this._boundPaths) { |
| this._notifyBoundPaths(path, value); |
| } |
| }, |
| _annotationPathEffect: function (path, value, effect) { |
| if (Path.matches(effect.value, false, path)) { |
| Polymer.Bind._annotationEffect.call(this, path, value, effect); |
| } else if (!effect.negate && Path.isDescendant(effect.value, path)) { |
| var node = this._nodes[effect.index]; |
| if (node && node._notifyPath) { |
| var newPath = Path.translate(effect.value, effect.name, path); |
| node._notifyPath(newPath, value, true); |
| } |
| } |
| }, |
| _complexObserverPathEffect: function (path, value, effect) { |
| if (Path.matches(effect.trigger.name, effect.trigger.wildcard, path)) { |
| Polymer.Bind._complexObserverEffect.call(this, path, value, effect); |
| } |
| }, |
| _computePathEffect: function (path, value, effect) { |
| if (Path.matches(effect.trigger.name, effect.trigger.wildcard, path)) { |
| Polymer.Bind._computeEffect.call(this, path, value, effect); |
| } |
| }, |
| _annotatedComputationPathEffect: function (path, value, effect) { |
| if (Path.matches(effect.trigger.name, effect.trigger.wildcard, path)) { |
| Polymer.Bind._annotatedComputationEffect.call(this, path, value, effect); |
| } |
| }, |
| linkPaths: function (to, from) { |
| this._boundPaths = this._boundPaths || {}; |
| if (from) { |
| this._boundPaths[to] = from; |
| } else { |
| this.unlinkPaths(to); |
| } |
| }, |
| unlinkPaths: function (path) { |
| if (this._boundPaths) { |
| delete this._boundPaths[path]; |
| } |
| }, |
| _notifyBoundPaths: function (path, value) { |
| for (var a in this._boundPaths) { |
| var b = this._boundPaths[a]; |
| if (Path.isDescendant(a, path)) { |
| this._notifyPath(Path.translate(a, b, path), value); |
| } else if (Path.isDescendant(b, path)) { |
| this._notifyPath(Path.translate(b, a, path), value); |
| } |
| } |
| }, |
| _notifyPathUp: function (path, value) { |
| var rootName = Path.root(path); |
| var dashCaseName = Polymer.CaseMap.camelToDashCase(rootName); |
| var eventName = dashCaseName + this._EVENT_CHANGED; |
| this.fire(eventName, { |
| path: path, |
| value: value |
| }, { |
| bubbles: false, |
| _useCache: Polymer.Settings.eventDataCache || !Polymer.Settings.isIE |
| }); |
| }, |
| _EVENT_CHANGED: '-changed', |
| notifySplices: function (path, splices) { |
| var info = {}; |
| var array = this._get(path, this, info); |
| this._notifySplices(array, info.path, splices); |
| }, |
| _notifySplices: function (array, path, splices) { |
| var change = { |
| keySplices: Polymer.Collection.applySplices(array, splices), |
| indexSplices: splices |
| }; |
| var splicesPath = path + '.splices'; |
| this._notifyPath(splicesPath, change); |
| this._notifyPath(path + '.length', array.length); |
| this.__data__[splicesPath] = { |
| keySplices: null, |
| indexSplices: null |
| }; |
| }, |
| _notifySplice: function (array, path, index, added, removed) { |
| this._notifySplices(array, path, [{ |
| index: index, |
| addedCount: added, |
| removed: removed, |
| object: array, |
| type: 'splice' |
| }]); |
| }, |
| push: function (path) { |
| var info = {}; |
| var array = this._get(path, this, info); |
| var args = Array.prototype.slice.call(arguments, 1); |
| var len = array.length; |
| var ret = array.push.apply(array, args); |
| if (args.length) { |
| this._notifySplice(array, info.path, len, args.length, []); |
| } |
| return ret; |
| }, |
| pop: function (path) { |
| var info = {}; |
| var array = this._get(path, this, info); |
| var hadLength = Boolean(array.length); |
| var args = Array.prototype.slice.call(arguments, 1); |
| var ret = array.pop.apply(array, args); |
| if (hadLength) { |
| this._notifySplice(array, info.path, array.length, 0, [ret]); |
| } |
| return ret; |
| }, |
| splice: function (path, start) { |
| var info = {}; |
| var array = this._get(path, this, info); |
| if (start < 0) { |
| start = array.length - Math.floor(-start); |
| } else { |
| start = Math.floor(start); |
| } |
| if (!start) { |
| start = 0; |
| } |
| var args = Array.prototype.slice.call(arguments, 1); |
| var ret = array.splice.apply(array, args); |
| var addedCount = Math.max(args.length - 2, 0); |
| if (addedCount || ret.length) { |
| this._notifySplice(array, info.path, start, addedCount, ret); |
| } |
| return ret; |
| }, |
| shift: function (path) { |
| var info = {}; |
| var array = this._get(path, this, info); |
| var hadLength = Boolean(array.length); |
| var args = Array.prototype.slice.call(arguments, 1); |
| var ret = array.shift.apply(array, args); |
| if (hadLength) { |
| this._notifySplice(array, info.path, 0, 0, [ret]); |
| } |
| return ret; |
| }, |
| unshift: function (path) { |
| var info = {}; |
| var array = this._get(path, this, info); |
| var args = Array.prototype.slice.call(arguments, 1); |
| var ret = array.unshift.apply(array, args); |
| if (args.length) { |
| this._notifySplice(array, info.path, 0, args.length, []); |
| } |
| return ret; |
| }, |
| prepareModelNotifyPath: function (model) { |
| this.mixin(model, { |
| fire: Polymer.Base.fire, |
| _getEvent: Polymer.Base._getEvent, |
| __eventCache: Polymer.Base.__eventCache, |
| notifyPath: Polymer.Base.notifyPath, |
| _get: Polymer.Base._get, |
| _EVENT_CHANGED: Polymer.Base._EVENT_CHANGED, |
| _notifyPath: Polymer.Base._notifyPath, |
| _notifyPathUp: Polymer.Base._notifyPathUp, |
| _pathEffector: Polymer.Base._pathEffector, |
| _annotationPathEffect: Polymer.Base._annotationPathEffect, |
| _complexObserverPathEffect: Polymer.Base._complexObserverPathEffect, |
| _annotatedComputationPathEffect: Polymer.Base._annotatedComputationPathEffect, |
| _computePathEffect: Polymer.Base._computePathEffect, |
| _notifyBoundPaths: Polymer.Base._notifyBoundPaths, |
| _getPathParts: Polymer.Base._getPathParts |
| }); |
| } |
| }); |
| }());Polymer.Base._addFeature({ |
| resolveUrl: function (url) { |
| return Polymer.ResolveUrl.resolveUrl(url, this._importPath); |
| } |
| });Polymer.CssParse = function () { |
| return { |
| parse: function (text) { |
| text = this._clean(text); |
| return this._parseCss(this._lex(text), text); |
| }, |
| _clean: function (cssText) { |
| return cssText.replace(this._rx.comments, '').replace(this._rx.port, ''); |
| }, |
| _lex: function (text) { |
| var root = { |
| start: 0, |
| end: text.length |
| }; |
| var n = root; |
| for (var i = 0, l = text.length; i < l; i++) { |
| switch (text[i]) { |
| case this.OPEN_BRACE: |
| if (!n.rules) { |
| n.rules = []; |
| } |
| var p = n; |
| var previous = p.rules[p.rules.length - 1]; |
| n = { |
| start: i + 1, |
| parent: p, |
| previous: previous |
| }; |
| p.rules.push(n); |
| break; |
| case this.CLOSE_BRACE: |
| n.end = i + 1; |
| n = n.parent || root; |
| break; |
| } |
| } |
| return root; |
| }, |
| _parseCss: function (node, text) { |
| var t = text.substring(node.start, node.end - 1); |
| node.parsedCssText = node.cssText = t.trim(); |
| if (node.parent) { |
| var ss = node.previous ? node.previous.end : node.parent.start; |
| t = text.substring(ss, node.start - 1); |
| t = this._expandUnicodeEscapes(t); |
| t = t.replace(this._rx.multipleSpaces, ' '); |
| t = t.substring(t.lastIndexOf(';') + 1); |
| var s = node.parsedSelector = node.selector = t.trim(); |
| node.atRule = s.indexOf(this.AT_START) === 0; |
| if (node.atRule) { |
| if (s.indexOf(this.MEDIA_START) === 0) { |
| node.type = this.types.MEDIA_RULE; |
| } else if (s.match(this._rx.keyframesRule)) { |
| node.type = this.types.KEYFRAMES_RULE; |
| node.keyframesName = node.selector.split(this._rx.multipleSpaces).pop(); |
| } |
| } else { |
| if (s.indexOf(this.VAR_START) === 0) { |
| node.type = this.types.MIXIN_RULE; |
| } else { |
| node.type = this.types.STYLE_RULE; |
| } |
| } |
| } |
| var r$ = node.rules; |
| if (r$) { |
| for (var i = 0, l = r$.length, r; i < l && (r = r$[i]); i++) { |
| this._parseCss(r, text); |
| } |
| } |
| return node; |
| }, |
| _expandUnicodeEscapes: function (s) { |
| return s.replace(/\\([0-9a-f]{1,6})\s/gi, function () { |
| var code = arguments[1], repeat = 6 - code.length; |
| while (repeat--) { |
| code = '0' + code; |
| } |
| return '\\' + code; |
| }); |
| }, |
| stringify: function (node, preserveProperties, text) { |
| text = text || ''; |
| var cssText = ''; |
| if (node.cssText || node.rules) { |
| var r$ = node.rules; |
| if (r$ && !this._hasMixinRules(r$)) { |
| for (var i = 0, l = r$.length, r; i < l && (r = r$[i]); i++) { |
| cssText = this.stringify(r, preserveProperties, cssText); |
| } |
| } else { |
| cssText = preserveProperties ? node.cssText : this.removeCustomProps(node.cssText); |
| cssText = cssText.trim(); |
| if (cssText) { |
| cssText = ' ' + cssText + '\n'; |
| } |
| } |
| } |
| if (cssText) { |
| if (node.selector) { |
| text += node.selector + ' ' + this.OPEN_BRACE + '\n'; |
| } |
| text += cssText; |
| if (node.selector) { |
| text += this.CLOSE_BRACE + '\n\n'; |
| } |
| } |
| return text; |
| }, |
| _hasMixinRules: function (rules) { |
| return rules[0].selector.indexOf(this.VAR_START) === 0; |
| }, |
| removeCustomProps: function (cssText) { |
| cssText = this.removeCustomPropAssignment(cssText); |
| return this.removeCustomPropApply(cssText); |
| }, |
| removeCustomPropAssignment: function (cssText) { |
| return cssText.replace(this._rx.customProp, '').replace(this._rx.mixinProp, ''); |
| }, |
| removeCustomPropApply: function (cssText) { |
| return cssText.replace(this._rx.mixinApply, '').replace(this._rx.varApply, ''); |
| }, |
| types: { |
| STYLE_RULE: 1, |
| KEYFRAMES_RULE: 7, |
| MEDIA_RULE: 4, |
| MIXIN_RULE: 1000 |
| }, |
| OPEN_BRACE: '{', |
| CLOSE_BRACE: '}', |
| _rx: { |
| comments: /\/\*[^*]*\*+([^\/*][^*]*\*+)*\//gim, |
| port: /@import[^;]*;/gim, |
| customProp: /(?:^[^;\-\s}]+)?--[^;{}]*?:[^{};]*?(?:[;\n]|$)/gim, |
| mixinProp: /(?:^[^;\-\s}]+)?--[^;{}]*?:[^{};]*?{[^}]*?}(?:[;\n]|$)?/gim, |
| mixinApply: /@apply\s*\(?[^);]*\)?\s*(?:[;\n]|$)?/gim, |
| varApply: /[^;:]*?:[^;]*?var\([^;]*\)(?:[;\n]|$)?/gim, |
| keyframesRule: /^@[^\s]*keyframes/, |
| multipleSpaces: /\s+/g |
| }, |
| VAR_START: '--', |
| MEDIA_START: '@media', |
| AT_START: '@' |
| }; |
| }();Polymer.StyleUtil = function () { |
| var settings = Polymer.Settings; |
| return { |
| unscopedStyleImports: new WeakMap(), |
| SHADY_UNSCOPED_ATTR: 'shady-unscoped', |
| NATIVE_VARIABLES: Polymer.Settings.useNativeCSSProperties, |
| MODULE_STYLES_SELECTOR: 'style, link[rel=import][type~=css], template', |
| INCLUDE_ATTR: 'include', |
| toCssText: function (rules, callback) { |
| if (typeof rules === 'string') { |
| rules = this.parser.parse(rules); |
| } |
| if (callback) { |
| this.forEachRule(rules, callback); |
| } |
| return this.parser.stringify(rules, this.NATIVE_VARIABLES); |
| }, |
| forRulesInStyles: function (styles, styleRuleCallback, keyframesRuleCallback) { |
| if (styles) { |
| for (var i = 0, l = styles.length, s; i < l && (s = styles[i]); i++) { |
| this.forEachRuleInStyle(s, styleRuleCallback, keyframesRuleCallback); |
| } |
| } |
| }, |
| forActiveRulesInStyles: function (styles, styleRuleCallback, keyframesRuleCallback) { |
| if (styles) { |
| for (var i = 0, l = styles.length, s; i < l && (s = styles[i]); i++) { |
| this.forEachRuleInStyle(s, styleRuleCallback, keyframesRuleCallback, true); |
| } |
| } |
| }, |
| rulesForStyle: function (style) { |
| if (!style.__cssRules && style.textContent) { |
| style.__cssRules = this.parser.parse(style.textContent); |
| } |
| return style.__cssRules; |
| }, |
| isKeyframesSelector: function (rule) { |
| return rule.parent && rule.parent.type === this.ruleTypes.KEYFRAMES_RULE; |
| }, |
| forEachRuleInStyle: function (style, styleRuleCallback, keyframesRuleCallback, onlyActiveRules) { |
| var rules = this.rulesForStyle(style); |
| var styleCallback, keyframeCallback; |
| if (styleRuleCallback) { |
| styleCallback = function (rule) { |
| styleRuleCallback(rule, style); |
| }; |
| } |
| if (keyframesRuleCallback) { |
| keyframeCallback = function (rule) { |
| keyframesRuleCallback(rule, style); |
| }; |
| } |
| this.forEachRule(rules, styleCallback, keyframeCallback, onlyActiveRules); |
| }, |
| forEachRule: function (node, styleRuleCallback, keyframesRuleCallback, onlyActiveRules) { |
| if (!node) { |
| return; |
| } |
| var skipRules = false; |
| if (onlyActiveRules) { |
| if (node.type === this.ruleTypes.MEDIA_RULE) { |
| var matchMedia = node.selector.match(this.rx.MEDIA_MATCH); |
| if (matchMedia) { |
| if (!window.matchMedia(matchMedia[1]).matches) { |
| skipRules = true; |
| } |
| } |
| } |
| } |
| if (node.type === this.ruleTypes.STYLE_RULE) { |
| styleRuleCallback(node); |
| } else if (keyframesRuleCallback && node.type === this.ruleTypes.KEYFRAMES_RULE) { |
| keyframesRuleCallback(node); |
| } else if (node.type === this.ruleTypes.MIXIN_RULE) { |
| skipRules = true; |
| } |
| var r$ = node.rules; |
| if (r$ && !skipRules) { |
| for (var i = 0, l = r$.length, r; i < l && (r = r$[i]); i++) { |
| this.forEachRule(r, styleRuleCallback, keyframesRuleCallback, onlyActiveRules); |
| } |
| } |
| }, |
| applyCss: function (cssText, moniker, target, contextNode) { |
| var style = this.createScopeStyle(cssText, moniker); |
| return this.applyStyle(style, target, contextNode); |
| }, |
| applyStyle: function (style, target, contextNode) { |
| target = target || document.head; |
| var after = contextNode && contextNode.nextSibling || target.firstChild; |
| this.__lastHeadApplyNode = style; |
| return target.insertBefore(style, after); |
| }, |
| createScopeStyle: function (cssText, moniker) { |
| var style = document.createElement('style'); |
| if (moniker) { |
| style.setAttribute('scope', moniker); |
| } |
| style.textContent = cssText; |
| return style; |
| }, |
| __lastHeadApplyNode: null, |
| applyStylePlaceHolder: function (moniker) { |
| var placeHolder = document.createComment(' Shady DOM styles for ' + moniker + ' '); |
| var after = this.__lastHeadApplyNode ? this.__lastHeadApplyNode.nextSibling : null; |
| var scope = document.head; |
| scope.insertBefore(placeHolder, after || scope.firstChild); |
| this.__lastHeadApplyNode = placeHolder; |
| return placeHolder; |
| }, |
| cssFromModules: function (moduleIds, warnIfNotFound) { |
| var modules = moduleIds.trim().split(/\s+/); |
| var cssText = ''; |
| for (var i = 0; i < modules.length; i++) { |
| cssText += this.cssFromModule(modules[i], warnIfNotFound); |
| } |
| return cssText; |
| }, |
| cssFromModule: function (moduleId, warnIfNotFound) { |
| var m = Polymer.DomModule.import(moduleId); |
| if (m && !m._cssText) { |
| m._cssText = this.cssFromElement(m); |
| } |
| if (!m && warnIfNotFound) { |
| console.warn('Could not find style data in module named', moduleId); |
| } |
| return m && m._cssText || ''; |
| }, |
| cssFromElement: function (element) { |
| var cssText = ''; |
| var content = element.content || element; |
| var e$ = Polymer.TreeApi.arrayCopy(content.querySelectorAll(this.MODULE_STYLES_SELECTOR)); |
| for (var i = 0, e; i < e$.length; i++) { |
| e = e$[i]; |
| if (e.localName === 'template') { |
| if (!e.hasAttribute('preserve-content')) { |
| cssText += this.cssFromElement(e); |
| } |
| } else { |
| if (e.localName === 'style') { |
| var include = e.getAttribute(this.INCLUDE_ATTR); |
| if (include) { |
| cssText += this.cssFromModules(include, true); |
| } |
| e = e.__appliedElement || e; |
| e.parentNode.removeChild(e); |
| var css = this.resolveCss(e.textContent, element.ownerDocument); |
| if (!settings.useNativeShadow && e.hasAttribute(this.SHADY_UNSCOPED_ATTR)) { |
| e.textContent = css; |
| document.head.insertBefore(e, document.head.firstChild); |
| } else { |
| cssText += css; |
| } |
| } else if (e.import && e.import.body) { |
| var importCss = this.resolveCss(e.import.body.textContent, e.import); |
| if (!settings.useNativeShadow && e.hasAttribute(this.SHADY_UNSCOPED_ATTR)) { |
| if (!this.unscopedStyleImports.has(e.import)) { |
| this.unscopedStyleImports.set(e.import, true); |
| var importStyle = document.createElement('style'); |
| importStyle.setAttribute(this.SHADY_UNSCOPED_ATTR, ''); |
| importStyle.textContent = importCss; |
| document.head.insertBefore(importStyle, document.head.firstChild); |
| } |
| } else { |
| cssText += importCss; |
| } |
| } |
| } |
| } |
| return cssText; |
| }, |
| styleIncludesToTemplate: function (targetTemplate) { |
| var styles = targetTemplate.content.querySelectorAll('style[include]'); |
| for (var i = 0, s; i < styles.length; i++) { |
| s = styles[i]; |
| s.parentNode.insertBefore(this._includesToFragment(s.getAttribute('include')), s); |
| } |
| }, |
| _includesToFragment: function (styleIncludes) { |
| var includeArray = styleIncludes.trim().split(' '); |
| var frag = document.createDocumentFragment(); |
| for (var i = 0; i < includeArray.length; i++) { |
| var t = Polymer.DomModule.import(includeArray[i], 'template'); |
| if (t) { |
| this._addStylesToFragment(frag, t.content); |
| } |
| } |
| return frag; |
| }, |
| _addStylesToFragment: function (frag, source) { |
| var s$ = source.querySelectorAll('style'); |
| for (var i = 0, s; i < s$.length; i++) { |
| s = s$[i]; |
| var include = s.getAttribute('include'); |
| if (include) { |
| frag.appendChild(this._includesToFragment(include)); |
| } |
| if (s.textContent) { |
| frag.appendChild(s.cloneNode(true)); |
| } |
| } |
| }, |
| isTargetedBuild: function (buildType) { |
| return settings.useNativeShadow ? buildType === 'shadow' : buildType === 'shady'; |
| }, |
| cssBuildTypeForModule: function (module) { |
| var dm = Polymer.DomModule.import(module); |
| if (dm) { |
| return this.getCssBuildType(dm); |
| } |
| }, |
| getCssBuildType: function (element) { |
| return element.getAttribute('css-build'); |
| }, |
| _findMatchingParen: function (text, start) { |
| var level = 0; |
| for (var i = start, l = text.length; i < l; i++) { |
| switch (text[i]) { |
| case '(': |
| level++; |
| break; |
| case ')': |
| if (--level === 0) { |
| return i; |
| } |
| break; |
| } |
| } |
| return -1; |
| }, |
| processVariableAndFallback: function (str, callback) { |
| var start = str.indexOf('var('); |
| if (start === -1) { |
| return callback(str, '', '', ''); |
| } |
| var end = this._findMatchingParen(str, start + 3); |
| var inner = str.substring(start + 4, end); |
| var prefix = str.substring(0, start); |
| var suffix = this.processVariableAndFallback(str.substring(end + 1), callback); |
| var comma = inner.indexOf(','); |
| if (comma === -1) { |
| return callback(prefix, inner.trim(), '', suffix); |
| } |
| var value = inner.substring(0, comma).trim(); |
| var fallback = inner.substring(comma + 1).trim(); |
| return callback(prefix, value, fallback, suffix); |
| }, |
| rx: { |
| VAR_ASSIGN: /(?:^|[;\s{]\s*)(--[\w-]*?)\s*:\s*(?:([^;{]*)|{([^}]*)})(?:(?=[;\s}])|$)/gi, |
| MIXIN_MATCH: /(?:^|\W+)@apply\s*\(?([^);\n]*)\)?/gi, |
| VAR_CONSUMED: /(--[\w-]+)\s*([:,;)]|$)/gi, |
| ANIMATION_MATCH: /(animation\s*:)|(animation-name\s*:)/, |
| MEDIA_MATCH: /@media[^(]*(\([^)]*\))/, |
| IS_VAR: /^--/, |
| BRACKETED: /\{[^}]*\}/g, |
| HOST_PREFIX: '(?:^|[^.#[:])', |
| HOST_SUFFIX: '($|[.:[\\s>+~])' |
| }, |
| resolveCss: Polymer.ResolveUrl.resolveCss, |
| parser: Polymer.CssParse, |
| ruleTypes: Polymer.CssParse.types |
| }; |
| }();Polymer.StyleTransformer = function () { |
| var styleUtil = Polymer.StyleUtil; |
| var settings = Polymer.Settings; |
| var api = { |
| dom: function (node, scope, useAttr, shouldRemoveScope) { |
| this._transformDom(node, scope || '', useAttr, shouldRemoveScope); |
| }, |
| _transformDom: function (node, selector, useAttr, shouldRemoveScope) { |
| if (node.setAttribute) { |
| this.element(node, selector, useAttr, shouldRemoveScope); |
| } |
| var c$ = Polymer.dom(node).childNodes; |
| for (var i = 0; i < c$.length; i++) { |
| this._transformDom(c$[i], selector, useAttr, shouldRemoveScope); |
| } |
| }, |
| element: function (element, scope, useAttr, shouldRemoveScope) { |
| if (useAttr) { |
| if (shouldRemoveScope) { |
| element.removeAttribute(SCOPE_NAME); |
| } else { |
| element.setAttribute(SCOPE_NAME, scope); |
| } |
| } else { |
| if (scope) { |
| if (element.classList) { |
| if (shouldRemoveScope) { |
| element.classList.remove(SCOPE_NAME); |
| element.classList.remove(scope); |
| } else { |
| element.classList.add(SCOPE_NAME); |
| element.classList.add(scope); |
| } |
| } else if (element.getAttribute) { |
| var c = element.getAttribute(CLASS); |
| if (shouldRemoveScope) { |
| if (c) { |
| element.setAttribute(CLASS, c.replace(SCOPE_NAME, '').replace(scope, '')); |
| } |
| } else { |
| element.setAttribute(CLASS, (c ? c + ' ' : '') + SCOPE_NAME + ' ' + scope); |
| } |
| } |
| } |
| } |
| }, |
| elementStyles: function (element, callback) { |
| var styles = element._styles; |
| var cssText = ''; |
| var cssBuildType = element.__cssBuild; |
| var passthrough = settings.useNativeShadow || cssBuildType === 'shady'; |
| var cb; |
| if (passthrough) { |
| var self = this; |
| cb = function (rule) { |
| rule.selector = self._slottedToContent(rule.selector); |
| rule.selector = rule.selector.replace(ROOT, ':host > *'); |
| rule.selector = self._dirShadowTransform(rule.selector); |
| if (callback) { |
| callback(rule); |
| } |
| }; |
| } |
| for (var i = 0, l = styles.length, s; i < l && (s = styles[i]); i++) { |
| var rules = styleUtil.rulesForStyle(s); |
| cssText += passthrough ? styleUtil.toCssText(rules, cb) : this.css(rules, element.is, element.extends, callback, element._scopeCssViaAttr) + '\n\n'; |
| } |
| return cssText.trim(); |
| }, |
| css: function (rules, scope, ext, callback, useAttr) { |
| var hostScope = this._calcHostScope(scope, ext); |
| scope = this._calcElementScope(scope, useAttr); |
| var self = this; |
| return styleUtil.toCssText(rules, function (rule) { |
| if (!rule.isScoped) { |
| self.rule(rule, scope, hostScope); |
| rule.isScoped = true; |
| } |
| if (callback) { |
| callback(rule, scope, hostScope); |
| } |
| }); |
| }, |
| _calcElementScope: function (scope, useAttr) { |
| if (scope) { |
| return useAttr ? CSS_ATTR_PREFIX + scope + CSS_ATTR_SUFFIX : CSS_CLASS_PREFIX + scope; |
| } else { |
| return ''; |
| } |
| }, |
| _calcHostScope: function (scope, ext) { |
| return ext ? '[is=' + scope + ']' : scope; |
| }, |
| rule: function (rule, scope, hostScope) { |
| this._transformRule(rule, this._transformComplexSelector, scope, hostScope); |
| }, |
| _transformRule: function (rule, transformer, scope, hostScope) { |
| rule.selector = rule.transformedSelector = this._transformRuleCss(rule, transformer, scope, hostScope); |
| }, |
| _splitSelectorList: function (selector) { |
| var parts = []; |
| var part = ''; |
| for (var i = 0; i >= 0 && i < selector.length; i++) { |
| if (selector[i] === '(') { |
| var end = styleUtil._findMatchingParen(selector, i); |
| part += selector.slice(i, end + 1); |
| i = end; |
| } else if (selector[i] === COMPLEX_SELECTOR_SEP) { |
| parts.push(part); |
| part = ''; |
| } else { |
| part += selector[i]; |
| } |
| } |
| if (part) { |
| parts.push(part); |
| } |
| if (parts.length === 0) { |
| parts.push(selector); |
| } |
| return parts; |
| }, |
| _transformRuleCss: function (rule, transformer, scope, hostScope) { |
| var p$ = this._splitSelectorList(rule.selector); |
| if (!styleUtil.isKeyframesSelector(rule)) { |
| for (var i = 0, l = p$.length, p; i < l && (p = p$[i]); i++) { |
| p$[i] = transformer.call(this, p, scope, hostScope); |
| } |
| } |
| return p$.join(COMPLEX_SELECTOR_SEP); |
| }, |
| _ensureScopedDir: function (s) { |
| var m = s.match(DIR_PAREN); |
| if (m && m[1] === '' && m[0].length === s.length) { |
| s = '*' + s; |
| } |
| return s; |
| }, |
| _additionalDirSelectors: function (dir, after, prefix) { |
| if (!dir || !after) { |
| return ''; |
| } |
| prefix = prefix || ''; |
| return COMPLEX_SELECTOR_SEP + prefix + ' ' + dir + ' ' + after; |
| }, |
| _transformComplexSelector: function (selector, scope, hostScope) { |
| var stop = false; |
| var hostContext = false; |
| var dir = false; |
| var self = this; |
| selector = selector.trim(); |
| selector = this._slottedToContent(selector); |
| selector = selector.replace(ROOT, ':host > *'); |
| selector = selector.replace(CONTENT_START, HOST + ' $1'); |
| selector = this._ensureScopedDir(selector); |
| selector = selector.replace(SIMPLE_SELECTOR_SEP, function (m, c, s) { |
| if (!stop) { |
| var info = self._transformCompoundSelector(s, c, scope, hostScope); |
| stop = stop || info.stop; |
| hostContext = hostContext || info.hostContext; |
| dir = dir || info.dir; |
| c = info.combinator; |
| s = info.value; |
| } else { |
| s = s.replace(SCOPE_JUMP, ' '); |
| } |
| return c + s; |
| }); |
| if (hostContext) { |
| selector = selector.replace(HOST_CONTEXT_PAREN, function (m, pre, paren, post) { |
| var replacement = pre + paren + ' ' + hostScope + post + COMPLEX_SELECTOR_SEP + ' ' + pre + hostScope + paren + post; |
| if (dir) { |
| replacement += self._additionalDirSelectors(paren, post, hostScope); |
| } |
| return replacement; |
| }); |
| } |
| return selector; |
| }, |
| _transformDir: function (s) { |
| s = s.replace(HOST_DIR, HOST_DIR_REPLACE); |
| s = s.replace(DIR_PAREN, DIR_REPLACE); |
| return s; |
| }, |
| _transformCompoundSelector: function (selector, combinator, scope, hostScope) { |
| var jumpIndex = selector.search(SCOPE_JUMP); |
| var hostContext = false; |
| var dir = false; |
| if (selector.match(DIR_PAREN)) { |
| selector = this._transformDir(selector); |
| dir = true; |
| } |
| if (selector.indexOf(HOST_CONTEXT) >= 0) { |
| hostContext = true; |
| } else if (selector.indexOf(HOST) >= 0) { |
| selector = this._transformHostSelector(selector, hostScope); |
| } else if (jumpIndex !== 0) { |
| selector = scope ? this._transformSimpleSelector(selector, scope) : selector; |
| } |
| if (selector.indexOf(CONTENT) >= 0) { |
| combinator = ''; |
| } |
| var stop; |
| if (jumpIndex >= 0) { |
| selector = selector.replace(SCOPE_JUMP, ' '); |
| stop = true; |
| } |
| return { |
| value: selector, |
| combinator: combinator, |
| stop: stop, |
| hostContext: hostContext, |
| dir: dir |
| }; |
| }, |
| _transformSimpleSelector: function (selector, scope) { |
| var p$ = selector.split(PSEUDO_PREFIX); |
| p$[0] += scope; |
| return p$.join(PSEUDO_PREFIX); |
| }, |
| _transformHostSelector: function (selector, hostScope) { |
| var m = selector.match(HOST_PAREN); |
| var paren = m && m[2].trim() || ''; |
| if (paren) { |
| if (!paren[0].match(SIMPLE_SELECTOR_PREFIX)) { |
| var typeSelector = paren.split(SIMPLE_SELECTOR_PREFIX)[0]; |
| if (typeSelector === hostScope) { |
| return paren; |
| } else { |
| return SELECTOR_NO_MATCH; |
| } |
| } else { |
| return selector.replace(HOST_PAREN, function (m, host, paren) { |
| return hostScope + paren; |
| }); |
| } |
| } else { |
| return selector.replace(HOST, hostScope); |
| } |
| }, |
| documentRule: function (rule) { |
| rule.selector = rule.parsedSelector; |
| this.normalizeRootSelector(rule); |
| if (!settings.useNativeShadow) { |
| this._transformRule(rule, this._transformDocumentSelector); |
| } |
| }, |
| normalizeRootSelector: function (rule) { |
| rule.selector = rule.selector.replace(ROOT, 'html'); |
| var parts = this._splitSelectorList(rule.selector); |
| parts = parts.filter(function (part) { |
| return !part.match(HOST_OR_HOST_GT_STAR); |
| }); |
| rule.selector = parts.join(COMPLEX_SELECTOR_SEP); |
| }, |
| _transformDocumentSelector: function (selector) { |
| return this._transformComplexSelector(selector, SCOPE_DOC_SELECTOR); |
| }, |
| _slottedToContent: function (cssText) { |
| return cssText.replace(SLOTTED_PAREN, CONTENT + '> $1'); |
| }, |
| _dirShadowTransform: function (selector) { |
| if (!selector.match(/:dir\(/)) { |
| return selector; |
| } |
| return this._splitSelectorList(selector).map(function (s) { |
| s = this._ensureScopedDir(s); |
| s = this._transformDir(s); |
| var m = HOST_CONTEXT_PAREN.exec(s); |
| if (m) { |
| s += this._additionalDirSelectors(m[2], m[3], ''); |
| } |
| return s; |
| }, this).join(COMPLEX_SELECTOR_SEP); |
| }, |
| SCOPE_NAME: 'style-scope' |
| }; |
| var SCOPE_NAME = api.SCOPE_NAME; |
| var SCOPE_DOC_SELECTOR = ':not([' + SCOPE_NAME + '])' + ':not(.' + SCOPE_NAME + ')'; |
| var COMPLEX_SELECTOR_SEP = ','; |
| var SIMPLE_SELECTOR_SEP = /(^|[\s>+~]+)((?:\[.+?\]|[^\s>+~=\[])+)/g; |
| var SIMPLE_SELECTOR_PREFIX = /[[.:#*]/; |
| var HOST = ':host'; |
| var ROOT = ':root'; |
| var HOST_PAREN = /(:host)(?:\(((?:\([^)(]*\)|[^)(]*)+?)\))/; |
| var HOST_CONTEXT = ':host-context'; |
| var HOST_CONTEXT_PAREN = /(.*)(?::host-context)(?:\(((?:\([^)(]*\)|[^)(]*)+?)\))(.*)/; |
| var CONTENT = '::content'; |
| var SCOPE_JUMP = /::content|::shadow|\/deep\//; |
| var CSS_CLASS_PREFIX = '.'; |
| var CSS_ATTR_PREFIX = '[' + SCOPE_NAME + '~='; |
| var CSS_ATTR_SUFFIX = ']'; |
| var PSEUDO_PREFIX = ':'; |
| var CLASS = 'class'; |
| var CONTENT_START = new RegExp('^(' + CONTENT + ')'); |
| var SELECTOR_NO_MATCH = 'should_not_match'; |
| var SLOTTED_PAREN = /(?:::slotted)(?:\(((?:\([^)(]*\)|[^)(]*)+?)\))/g; |
| var HOST_OR_HOST_GT_STAR = /:host(?:\s*>\s*\*)?/; |
| var DIR_PAREN = /(.*):dir\((ltr|rtl)\)/; |
| var DIR_REPLACE = ':host-context([dir="$2"]) $1'; |
| var HOST_DIR = /:host\(:dir\((rtl|ltr)\)\)/g; |
| var HOST_DIR_REPLACE = ':host-context([dir="$1"])'; |
| return api; |
| }();Polymer.StyleExtends = function () { |
| var styleUtil = Polymer.StyleUtil; |
| return { |
| hasExtends: function (cssText) { |
| return Boolean(cssText.match(this.rx.EXTEND)); |
| }, |
| transform: function (style) { |
| var rules = styleUtil.rulesForStyle(style); |
| var self = this; |
| styleUtil.forEachRule(rules, function (rule) { |
| self._mapRuleOntoParent(rule); |
| if (rule.parent) { |
| var m; |
| while (m = self.rx.EXTEND.exec(rule.cssText)) { |
| var extend = m[1]; |
| var extendor = self._findExtendor(extend, rule); |
| if (extendor) { |
| self._extendRule(rule, extendor); |
| } |
| } |
| } |
| rule.cssText = rule.cssText.replace(self.rx.EXTEND, ''); |
| }); |
| return styleUtil.toCssText(rules, function (rule) { |
| if (rule.selector.match(self.rx.STRIP)) { |
| rule.cssText = ''; |
| } |
| }, true); |
| }, |
| _mapRuleOntoParent: function (rule) { |
| if (rule.parent) { |
| var map = rule.parent.map || (rule.parent.map = {}); |
| var parts = rule.selector.split(','); |
| for (var i = 0, p; i < parts.length; i++) { |
| p = parts[i]; |
| map[p.trim()] = rule; |
| } |
| return map; |
| } |
| }, |
| _findExtendor: function (extend, rule) { |
| return rule.parent && rule.parent.map && rule.parent.map[extend] || this._findExtendor(extend, rule.parent); |
| }, |
| _extendRule: function (target, source) { |
| if (target.parent !== source.parent) { |
| this._cloneAndAddRuleToParent(source, target.parent); |
| } |
| target.extends = target.extends || []; |
| target.extends.push(source); |
| source.selector = source.selector.replace(this.rx.STRIP, ''); |
| source.selector = (source.selector && source.selector + ',\n') + target.selector; |
| if (source.extends) { |
| source.extends.forEach(function (e) { |
| this._extendRule(target, e); |
| }, this); |
| } |
| }, |
| _cloneAndAddRuleToParent: function (rule, parent) { |
| rule = Object.create(rule); |
| rule.parent = parent; |
| if (rule.extends) { |
| rule.extends = rule.extends.slice(); |
| } |
| parent.rules.push(rule); |
| }, |
| rx: { |
| EXTEND: /@extends\(([^)]*)\)\s*?;/gim, |
| STRIP: /%[^,]*$/ |
| } |
| }; |
| }();Polymer.ApplyShim = function () { |
| 'use strict'; |
| var styleUtil = Polymer.StyleUtil; |
| var MIXIN_MATCH = styleUtil.rx.MIXIN_MATCH; |
| var VAR_ASSIGN = styleUtil.rx.VAR_ASSIGN; |
| var BAD_VAR = /var\(\s*(--[^,]*),\s*(--[^)]*)\)/g; |
| var APPLY_NAME_CLEAN = /;\s*/m; |
| var INITIAL_INHERIT = /^\s*(initial)|(inherit)\s*$/; |
| var MIXIN_VAR_SEP = '_-_'; |
| var mixinMap = {}; |
| function mapSet(name, props) { |
| name = name.trim(); |
| mixinMap[name] = { |
| properties: props, |
| dependants: {} |
| }; |
| } |
| function mapGet(name) { |
| name = name.trim(); |
| return mixinMap[name]; |
| } |
| function replaceInitialOrInherit(property, value) { |
| var match = INITIAL_INHERIT.exec(value); |
| if (match) { |
| if (match[1]) { |
| value = ApplyShim._getInitialValueForProperty(property); |
| } else { |
| value = 'apply-shim-inherit'; |
| } |
| } |
| return value; |
| } |
| function cssTextToMap(text) { |
| var props = text.split(';'); |
| var property, value; |
| var out = {}; |
| for (var i = 0, p, sp; i < props.length; i++) { |
| p = props[i]; |
| if (p) { |
| sp = p.split(':'); |
| if (sp.length > 1) { |
| property = sp[0].trim(); |
| value = replaceInitialOrInherit(property, sp.slice(1).join(':')); |
| out[property] = value; |
| } |
| } |
| } |
| return out; |
| } |
| function invalidateMixinEntry(mixinEntry) { |
| var currentProto = ApplyShim.__currentElementProto; |
| var currentElementName = currentProto && currentProto.is; |
| for (var elementName in mixinEntry.dependants) { |
| if (elementName !== currentElementName) { |
| mixinEntry.dependants[elementName].__applyShimInvalid = true; |
| } |
| } |
| } |
| function produceCssProperties(matchText, propertyName, valueProperty, valueMixin) { |
| if (valueProperty) { |
| styleUtil.processVariableAndFallback(valueProperty, function (prefix, value) { |
| if (value && mapGet(value)) { |
| valueMixin = '@apply ' + value + ';'; |
| } |
| }); |
| } |
| if (!valueMixin) { |
| return matchText; |
| } |
| var mixinAsProperties = consumeCssProperties(valueMixin); |
| var prefix = matchText.slice(0, matchText.indexOf('--')); |
| var mixinValues = cssTextToMap(mixinAsProperties); |
| var combinedProps = mixinValues; |
| var mixinEntry = mapGet(propertyName); |
| var oldProps = mixinEntry && mixinEntry.properties; |
| if (oldProps) { |
| combinedProps = Object.create(oldProps); |
| combinedProps = Polymer.Base.mixin(combinedProps, mixinValues); |
| } else { |
| mapSet(propertyName, combinedProps); |
| } |
| var out = []; |
| var p, v; |
| var needToInvalidate = false; |
| for (p in combinedProps) { |
| v = mixinValues[p]; |
| if (v === undefined) { |
| v = 'initial'; |
| } |
| if (oldProps && !(p in oldProps)) { |
| needToInvalidate = true; |
| } |
| out.push(propertyName + MIXIN_VAR_SEP + p + ': ' + v); |
| } |
| if (needToInvalidate) { |
| invalidateMixinEntry(mixinEntry); |
| } |
| if (mixinEntry) { |
| mixinEntry.properties = combinedProps; |
| } |
| if (valueProperty) { |
| prefix = matchText + ';' + prefix; |
| } |
| return prefix + out.join('; ') + ';'; |
| } |
| function fixVars(matchText, varA, varB) { |
| return 'var(' + varA + ',' + 'var(' + varB + '))'; |
| } |
| function atApplyToCssProperties(mixinName, fallbacks) { |
| mixinName = mixinName.replace(APPLY_NAME_CLEAN, ''); |
| var vars = []; |
| var mixinEntry = mapGet(mixinName); |
| if (!mixinEntry) { |
| mapSet(mixinName, {}); |
| mixinEntry = mapGet(mixinName); |
| } |
| if (mixinEntry) { |
| var currentProto = ApplyShim.__currentElementProto; |
| if (currentProto) { |
| mixinEntry.dependants[currentProto.is] = currentProto; |
| } |
| var p, parts, f; |
| for (p in mixinEntry.properties) { |
| f = fallbacks && fallbacks[p]; |
| parts = [ |
| p, |
| ': var(', |
| mixinName, |
| MIXIN_VAR_SEP, |
| p |
| ]; |
| if (f) { |
| parts.push(',', f); |
| } |
| parts.push(')'); |
| vars.push(parts.join('')); |
| } |
| } |
| return vars.join('; '); |
| } |
| function consumeCssProperties(text) { |
| var m; |
| while (m = MIXIN_MATCH.exec(text)) { |
| var matchText = m[0]; |
| var mixinName = m[1]; |
| var idx = m.index; |
| var applyPos = idx + matchText.indexOf('@apply'); |
| var afterApplyPos = idx + matchText.length; |
| var textBeforeApply = text.slice(0, applyPos); |
| var textAfterApply = text.slice(afterApplyPos); |
| var defaults = cssTextToMap(textBeforeApply); |
| var replacement = atApplyToCssProperties(mixinName, defaults); |
| text = [ |
| textBeforeApply, |
| replacement, |
| textAfterApply |
| ].join(''); |
| MIXIN_MATCH.lastIndex = idx + replacement.length; |
| } |
| return text; |
| } |
| var ApplyShim = { |
| _measureElement: null, |
| _map: mixinMap, |
| _separator: MIXIN_VAR_SEP, |
| transform: function (styles, elementProto) { |
| this.__currentElementProto = elementProto; |
| styleUtil.forRulesInStyles(styles, this._boundFindDefinitions); |
| styleUtil.forRulesInStyles(styles, this._boundFindApplications); |
| if (elementProto) { |
| elementProto.__applyShimInvalid = false; |
| } |
| this.__currentElementProto = null; |
| }, |
| _findDefinitions: function (rule) { |
| var cssText = rule.parsedCssText; |
| cssText = cssText.replace(BAD_VAR, fixVars); |
| cssText = cssText.replace(VAR_ASSIGN, produceCssProperties); |
| rule.cssText = cssText; |
| if (rule.selector === ':root') { |
| rule.selector = ':host > *'; |
| } |
| }, |
| _findApplications: function (rule) { |
| rule.cssText = consumeCssProperties(rule.cssText); |
| }, |
| transformRule: function (rule) { |
| this._findDefinitions(rule); |
| this._findApplications(rule); |
| }, |
| _getInitialValueForProperty: function (property) { |
| if (!this._measureElement) { |
| this._measureElement = document.createElement('meta'); |
| this._measureElement.style.all = 'initial'; |
| document.head.appendChild(this._measureElement); |
| } |
| return window.getComputedStyle(this._measureElement).getPropertyValue(property); |
| } |
| }; |
| ApplyShim._boundTransformRule = ApplyShim.transformRule.bind(ApplyShim); |
| ApplyShim._boundFindDefinitions = ApplyShim._findDefinitions.bind(ApplyShim); |
| ApplyShim._boundFindApplications = ApplyShim._findApplications.bind(ApplyShim); |
| return ApplyShim; |
| }();(function () { |
| var prepElement = Polymer.Base._prepElement; |
| var nativeShadow = Polymer.Settings.useNativeShadow; |
| var styleUtil = Polymer.StyleUtil; |
| var styleTransformer = Polymer.StyleTransformer; |
| var styleExtends = Polymer.StyleExtends; |
| var applyShim = Polymer.ApplyShim; |
| var settings = Polymer.Settings; |
| Polymer.Base._addFeature({ |
| _prepElement: function (element) { |
| if (this._encapsulateStyle && this.__cssBuild !== 'shady') { |
| styleTransformer.element(element, this.is, this._scopeCssViaAttr); |
| } |
| prepElement.call(this, element); |
| }, |
| _prepStyles: function () { |
| if (this._encapsulateStyle === undefined) { |
| this._encapsulateStyle = !nativeShadow; |
| } |
| if (!nativeShadow) { |
| this._scopeStyle = styleUtil.applyStylePlaceHolder(this.is); |
| } |
| this.__cssBuild = styleUtil.cssBuildTypeForModule(this.is); |
| }, |
| _prepShimStyles: function () { |
| if (this._template) { |
| var hasTargetedCssBuild = styleUtil.isTargetedBuild(this.__cssBuild); |
| if (settings.useNativeCSSProperties && this.__cssBuild === 'shadow' && hasTargetedCssBuild) { |
| if (settings.preserveStyleIncludes) { |
| styleUtil.styleIncludesToTemplate(this._template); |
| } |
| return; |
| } |
| this._styles = this._styles || this._collectStyles(); |
| if (settings.useNativeCSSProperties && !this.__cssBuild) { |
| applyShim.transform(this._styles, this); |
| } |
| var cssText = settings.useNativeCSSProperties && hasTargetedCssBuild ? this._styles.length && this._styles[0].textContent.trim() : styleTransformer.elementStyles(this); |
| this._prepStyleProperties(); |
| if (!this._needsStyleProperties() && cssText) { |
| styleUtil.applyCss(cssText, this.is, nativeShadow ? this._template.content : null, this._scopeStyle); |
| } |
| } else { |
| this._styles = []; |
| } |
| }, |
| _collectStyles: function () { |
| var styles = []; |
| var cssText = '', m$ = this.styleModules; |
| if (m$) { |
| for (var i = 0, l = m$.length, m; i < l && (m = m$[i]); i++) { |
| cssText += styleUtil.cssFromModule(m); |
| } |
| } |
| cssText += styleUtil.cssFromModule(this.is); |
| var p = this._template && this._template.parentNode; |
| if (this._template && (!p || p.id.toLowerCase() !== this.is)) { |
| cssText += styleUtil.cssFromElement(this._template); |
| } |
| if (cssText) { |
| var style = document.createElement('style'); |
| style.textContent = cssText; |
| if (styleExtends.hasExtends(style.textContent)) { |
| cssText = styleExtends.transform(style); |
| } |
| styles.push(style); |
| } |
| return styles; |
| }, |
| _elementAdd: function (node) { |
| if (this._encapsulateStyle) { |
| if (node.__styleScoped) { |
| node.__styleScoped = false; |
| } else { |
| styleTransformer.dom(node, this.is, this._scopeCssViaAttr); |
| } |
| } |
| }, |
| _elementRemove: function (node) { |
| if (this._encapsulateStyle) { |
| styleTransformer.dom(node, this.is, this._scopeCssViaAttr, true); |
| } |
| }, |
| scopeSubtree: function (container, shouldObserve) { |
| if (nativeShadow) { |
| return; |
| } |
| var self = this; |
| var scopify = function (node) { |
| if (node.nodeType === Node.ELEMENT_NODE) { |
| var className = node.getAttribute('class'); |
| node.setAttribute('class', self._scopeElementClass(node, className)); |
| var n$ = node.querySelectorAll('*'); |
| for (var i = 0, n; i < n$.length && (n = n$[i]); i++) { |
| className = n.getAttribute('class'); |
| n.setAttribute('class', self._scopeElementClass(n, className)); |
| } |
| } |
| }; |
| scopify(container); |
| if (shouldObserve) { |
| var mo = new MutationObserver(function (mxns) { |
| for (var i = 0, m; i < mxns.length && (m = mxns[i]); i++) { |
| if (m.addedNodes) { |
| for (var j = 0; j < m.addedNodes.length; j++) { |
| scopify(m.addedNodes[j]); |
| } |
| } |
| } |
| }); |
| mo.observe(container, { |
| childList: true, |
| subtree: true |
| }); |
| return mo; |
| } |
| } |
| }); |
| }());Polymer.StyleProperties = function () { |
| 'use strict'; |
| var matchesSelector = Polymer.DomApi.matchesSelector; |
| var styleUtil = Polymer.StyleUtil; |
| var styleTransformer = Polymer.StyleTransformer; |
| var IS_IE = navigator.userAgent.match('Trident'); |
| var settings = Polymer.Settings; |
| return { |
| decorateStyles: function (styles, scope) { |
| var self = this, props = {}, keyframes = [], ruleIndex = 0; |
| var scopeSelector = styleTransformer._calcHostScope(scope.is, scope.extends); |
| styleUtil.forRulesInStyles(styles, function (rule, style) { |
| self.decorateRule(rule); |
| rule.index = ruleIndex++; |
| self.whenHostOrRootRule(scope, rule, style, function (info) { |
| if (rule.parent.type === styleUtil.ruleTypes.MEDIA_RULE) { |
| scope.__notStyleScopeCacheable = true; |
| } |
| if (info.isHost) { |
| var hostContextOrFunction = info.selector.split(' ').some(function (s) { |
| return s.indexOf(scopeSelector) === 0 && s.length !== scopeSelector.length; |
| }); |
| scope.__notStyleScopeCacheable = scope.__notStyleScopeCacheable || hostContextOrFunction; |
| } |
| }); |
| self.collectPropertiesInCssText(rule.propertyInfo.cssText, props); |
| }, function onKeyframesRule(rule) { |
| keyframes.push(rule); |
| }); |
| styles._keyframes = keyframes; |
| var names = []; |
| for (var i in props) { |
| names.push(i); |
| } |
| return names; |
| }, |
| decorateRule: function (rule) { |
| if (rule.propertyInfo) { |
| return rule.propertyInfo; |
| } |
| var info = {}, properties = {}; |
| var hasProperties = this.collectProperties(rule, properties); |
| if (hasProperties) { |
| info.properties = properties; |
| rule.rules = null; |
| } |
| info.cssText = this.collectCssText(rule); |
| rule.propertyInfo = info; |
| return info; |
| }, |
| collectProperties: function (rule, properties) { |
| var info = rule.propertyInfo; |
| if (info) { |
| if (info.properties) { |
| Polymer.Base.mixin(properties, info.properties); |
| return true; |
| } |
| } else { |
| var m, rx = this.rx.VAR_ASSIGN; |
| var cssText = rule.parsedCssText; |
| var value; |
| var any; |
| while (m = rx.exec(cssText)) { |
| value = (m[2] || m[3]).trim(); |
| if (value !== 'inherit') { |
| properties[m[1].trim()] = value; |
| } |
| any = true; |
| } |
| return any; |
| } |
| }, |
| collectCssText: function (rule) { |
| return this.collectConsumingCssText(rule.parsedCssText); |
| }, |
| collectConsumingCssText: function (cssText) { |
| return cssText.replace(this.rx.BRACKETED, '').replace(this.rx.VAR_ASSIGN, ''); |
| }, |
| collectPropertiesInCssText: function (cssText, props) { |
| var m; |
| while (m = this.rx.VAR_CONSUMED.exec(cssText)) { |
| var name = m[1]; |
| if (m[2] !== ':') { |
| props[name] = true; |
| } |
| } |
| }, |
| reify: function (props) { |
| var names = Object.getOwnPropertyNames(props); |
| for (var i = 0, n; i < names.length; i++) { |
| n = names[i]; |
| props[n] = this.valueForProperty(props[n], props); |
| } |
| }, |
| valueForProperty: function (property, props) { |
| if (property) { |
| if (property.indexOf(';') >= 0) { |
| property = this.valueForProperties(property, props); |
| } else { |
| var self = this; |
| var fn = function (prefix, value, fallback, suffix) { |
| var propertyValue = self.valueForProperty(props[value], props); |
| if (!propertyValue || propertyValue === 'initial') { |
| propertyValue = self.valueForProperty(props[fallback] || fallback, props) || fallback; |
| } else if (propertyValue === 'apply-shim-inherit') { |
| propertyValue = 'inherit'; |
| } |
| return prefix + (propertyValue || '') + suffix; |
| }; |
| property = styleUtil.processVariableAndFallback(property, fn); |
| } |
| } |
| return property && property.trim() || ''; |
| }, |
| valueForProperties: function (property, props) { |
| var parts = property.split(';'); |
| for (var i = 0, p, m; i < parts.length; i++) { |
| if (p = parts[i]) { |
| this.rx.MIXIN_MATCH.lastIndex = 0; |
| m = this.rx.MIXIN_MATCH.exec(p); |
| if (m) { |
| p = this.valueForProperty(props[m[1]], props); |
| } else { |
| var colon = p.indexOf(':'); |
| if (colon !== -1) { |
| var pp = p.substring(colon); |
| pp = pp.trim(); |
| pp = this.valueForProperty(pp, props) || pp; |
| p = p.substring(0, colon) + pp; |
| } |
| } |
| parts[i] = p && p.lastIndexOf(';') === p.length - 1 ? p.slice(0, -1) : p || ''; |
| } |
| } |
| return parts.join(';'); |
| }, |
| applyProperties: function (rule, props) { |
| var output = ''; |
| if (!rule.propertyInfo) { |
| this.decorateRule(rule); |
| } |
| if (rule.propertyInfo.cssText) { |
| output = this.valueForProperties(rule.propertyInfo.cssText, props); |
| } |
| rule.cssText = output; |
| }, |
| applyKeyframeTransforms: function (rule, keyframeTransforms) { |
| var input = rule.cssText; |
| var output = rule.cssText; |
| if (rule.hasAnimations == null) { |
| rule.hasAnimations = this.rx.ANIMATION_MATCH.test(input); |
| } |
| if (rule.hasAnimations) { |
| var transform; |
| if (rule.keyframeNamesToTransform == null) { |
| rule.keyframeNamesToTransform = []; |
| for (var keyframe in keyframeTransforms) { |
| transform = keyframeTransforms[keyframe]; |
| output = transform(input); |
| if (input !== output) { |
| input = output; |
| rule.keyframeNamesToTransform.push(keyframe); |
| } |
| } |
| } else { |
| for (var i = 0; i < rule.keyframeNamesToTransform.length; ++i) { |
| transform = keyframeTransforms[rule.keyframeNamesToTransform[i]]; |
| input = transform(input); |
| } |
| output = input; |
| } |
| } |
| rule.cssText = output; |
| }, |
| propertyDataFromStyles: function (styles, element) { |
| var props = {}, self = this; |
| var o = []; |
| styleUtil.forActiveRulesInStyles(styles, function (rule) { |
| if (!rule.propertyInfo) { |
| self.decorateRule(rule); |
| } |
| var selectorToMatch = rule.transformedSelector || rule.parsedSelector; |
| if (element && rule.propertyInfo.properties && selectorToMatch) { |
| if (matchesSelector.call(element, selectorToMatch)) { |
| self.collectProperties(rule, props); |
| addToBitMask(rule.index, o); |
| } |
| } |
| }); |
| return { |
| properties: props, |
| key: o |
| }; |
| }, |
| _rootSelector: /:root|:host\s*>\s*\*/, |
| _checkRoot: function (hostScope, selector) { |
| return Boolean(selector.match(this._rootSelector)) || hostScope === 'html' && selector.indexOf('html') > -1; |
| }, |
| whenHostOrRootRule: function (scope, rule, style, callback) { |
| if (!rule.propertyInfo) { |
| self.decorateRule(rule); |
| } |
| if (!rule.propertyInfo.properties) { |
| return; |
| } |
| var hostScope = scope.is ? styleTransformer._calcHostScope(scope.is, scope.extends) : 'html'; |
| var parsedSelector = rule.parsedSelector; |
| var isRoot = this._checkRoot(hostScope, parsedSelector); |
| var isHost = !isRoot && parsedSelector.indexOf(':host') === 0; |
| var cssBuild = scope.__cssBuild || style.__cssBuild; |
| if (cssBuild === 'shady') { |
| isRoot = parsedSelector === hostScope + ' > *.' + hostScope || parsedSelector.indexOf('html') > -1; |
| isHost = !isRoot && parsedSelector.indexOf(hostScope) === 0; |
| } |
| if (!isRoot && !isHost) { |
| return; |
| } |
| var selectorToMatch = hostScope; |
| if (isHost) { |
| if (settings.useNativeShadow && !rule.transformedSelector) { |
| rule.transformedSelector = styleTransformer._transformRuleCss(rule, styleTransformer._transformComplexSelector, scope.is, hostScope); |
| } |
| selectorToMatch = rule.transformedSelector || rule.parsedSelector; |
| } |
| if (isRoot && hostScope === 'html') { |
| selectorToMatch = rule.transformedSelector || rule.parsedSelector; |
| } |
| callback({ |
| selector: selectorToMatch, |
| isHost: isHost, |
| isRoot: isRoot |
| }); |
| }, |
| hostAndRootPropertiesForScope: function (scope) { |
| var hostProps = {}, rootProps = {}, self = this; |
| styleUtil.forActiveRulesInStyles(scope._styles, function (rule, style) { |
| self.whenHostOrRootRule(scope, rule, style, function (info) { |
| var element = scope._element || scope; |
| if (matchesSelector.call(element, info.selector)) { |
| if (info.isHost) { |
| self.collectProperties(rule, hostProps); |
| } else { |
| self.collectProperties(rule, rootProps); |
| } |
| } |
| }); |
| }); |
| return { |
| rootProps: rootProps, |
| hostProps: hostProps |
| }; |
| }, |
| transformStyles: function (element, properties, scopeSelector) { |
| var self = this; |
| var hostSelector = styleTransformer._calcHostScope(element.is, element.extends); |
| var rxHostSelector = element.extends ? '\\' + hostSelector.slice(0, -1) + '\\]' : hostSelector; |
| var hostRx = new RegExp(this.rx.HOST_PREFIX + rxHostSelector + this.rx.HOST_SUFFIX); |
| var keyframeTransforms = this._elementKeyframeTransforms(element, scopeSelector); |
| return styleTransformer.elementStyles(element, function (rule) { |
| self.applyProperties(rule, properties); |
| if (!settings.useNativeShadow && !Polymer.StyleUtil.isKeyframesSelector(rule) && rule.cssText) { |
| self.applyKeyframeTransforms(rule, keyframeTransforms); |
| self._scopeSelector(rule, hostRx, hostSelector, element._scopeCssViaAttr, scopeSelector); |
| } |
| }); |
| }, |
| _elementKeyframeTransforms: function (element, scopeSelector) { |
| var keyframesRules = element._styles._keyframes; |
| var keyframeTransforms = {}; |
| if (!settings.useNativeShadow && keyframesRules) { |
| for (var i = 0, keyframesRule = keyframesRules[i]; i < keyframesRules.length; keyframesRule = keyframesRules[++i]) { |
| this._scopeKeyframes(keyframesRule, scopeSelector); |
| keyframeTransforms[keyframesRule.keyframesName] = this._keyframesRuleTransformer(keyframesRule); |
| } |
| } |
| return keyframeTransforms; |
| }, |
| _keyframesRuleTransformer: function (keyframesRule) { |
| return function (cssText) { |
| return cssText.replace(keyframesRule.keyframesNameRx, keyframesRule.transformedKeyframesName); |
| }; |
| }, |
| _scopeKeyframes: function (rule, scopeId) { |
| rule.keyframesNameRx = new RegExp('\\b' + rule.keyframesName + '(?!\\B|-)', 'g'); |
| rule.transformedKeyframesName = rule.keyframesName + '-' + scopeId; |
| rule.transformedSelector = rule.transformedSelector || rule.selector; |
| rule.selector = rule.transformedSelector.replace(rule.keyframesName, rule.transformedKeyframesName); |
| }, |
| _hasDirOrHostContext: function (parsedSelector) { |
| return /:host-context|:dir/.test(parsedSelector); |
| }, |
| _scopeSelector: function (rule, hostRx, hostSelector, viaAttr, scopeId) { |
| rule.transformedSelector = rule.transformedSelector || rule.selector; |
| var selector = rule.transformedSelector; |
| var scope = styleTransformer._calcElementScope(scopeId, viaAttr); |
| var hostScope = styleTransformer._calcElementScope(hostSelector, viaAttr); |
| var parts = selector.split(','); |
| var isDirOrHostContextSelector = this._hasDirOrHostContext(rule.parsedSelector); |
| for (var i = 0, l = parts.length, p; i < l && (p = parts[i]); i++) { |
| parts[i] = p.match(hostRx) ? p.replace(hostSelector, scope) : isDirOrHostContextSelector ? p.replace(hostScope, scope + ' ' + hostScope) : scope + ' ' + p; |
| } |
| rule.selector = parts.join(','); |
| }, |
| applyElementScopeSelector: function (element, selector, old, viaAttr) { |
| var c = viaAttr ? element.getAttribute(styleTransformer.SCOPE_NAME) : element.getAttribute('class') || ''; |
| var v = old ? c.replace(old, selector) : (c ? c + ' ' : '') + this.XSCOPE_NAME + ' ' + selector; |
| if (c !== v) { |
| if (viaAttr) { |
| element.setAttribute(styleTransformer.SCOPE_NAME, v); |
| } else { |
| element.setAttribute('class', v); |
| } |
| } |
| }, |
| applyElementStyle: function (element, properties, selector, style) { |
| var cssText = style ? style.textContent || '' : this.transformStyles(element, properties, selector); |
| var s = element._customStyle; |
| if (s && !settings.useNativeShadow && s !== style) { |
| s._useCount--; |
| if (s._useCount <= 0 && s.parentNode) { |
| s.parentNode.removeChild(s); |
| } |
| } |
| if (settings.useNativeShadow) { |
| if (element._customStyle) { |
| element._customStyle.textContent = cssText; |
| style = element._customStyle; |
| } else if (cssText) { |
| style = styleUtil.applyCss(cssText, selector, element.root, element._scopeStyle); |
| } |
| } else { |
| if (!style) { |
| if (cssText) { |
| style = styleUtil.applyCss(cssText, selector, null, element._scopeStyle); |
| } |
| } else if (!style.parentNode) { |
| if (IS_IE && cssText.indexOf('@media') > -1) { |
| style.textContent = cssText; |
| } |
| styleUtil.applyStyle(style, null, element._scopeStyle); |
| } |
| } |
| if (style) { |
| style._useCount = style._useCount || 0; |
| if (element._customStyle != style) { |
| style._useCount++; |
| } |
| element._customStyle = style; |
| } |
| return style; |
| }, |
| mixinCustomStyle: function (props, customStyle) { |
| var v; |
| for (var i in customStyle) { |
| v = customStyle[i]; |
| if (v || v === 0) { |
| props[i] = v; |
| } |
| } |
| }, |
| updateNativeStyleProperties: function (element, properties) { |
| var oldPropertyNames = element.__customStyleProperties; |
| if (oldPropertyNames) { |
| for (var i = 0; i < oldPropertyNames.length; i++) { |
| element.style.removeProperty(oldPropertyNames[i]); |
| } |
| } |
| var propertyNames = []; |
| for (var p in properties) { |
| if (properties[p] !== null) { |
| element.style.setProperty(p, properties[p]); |
| propertyNames.push(p); |
| } |
| } |
| element.__customStyleProperties = propertyNames; |
| }, |
| rx: styleUtil.rx, |
| XSCOPE_NAME: 'x-scope' |
| }; |
| function addToBitMask(n, bits) { |
| var o = parseInt(n / 32); |
| var v = 1 << n % 32; |
| bits[o] = (bits[o] || 0) | v; |
| } |
| }();(function () { |
| Polymer.StyleCache = function () { |
| this.cache = {}; |
| }; |
| Polymer.StyleCache.prototype = { |
| MAX: 100, |
| store: function (is, data, keyValues, keyStyles) { |
| data.keyValues = keyValues; |
| data.styles = keyStyles; |
| var s$ = this.cache[is] = this.cache[is] || []; |
| s$.push(data); |
| if (s$.length > this.MAX) { |
| s$.shift(); |
| } |
| }, |
| retrieve: function (is, keyValues, keyStyles) { |
| var cache = this.cache[is]; |
| if (cache) { |
| for (var i = cache.length - 1, data; i >= 0; i--) { |
| data = cache[i]; |
| if (keyStyles === data.styles && this._objectsEqual(keyValues, data.keyValues)) { |
| return data; |
| } |
| } |
| } |
| }, |
| clear: function () { |
| this.cache = {}; |
| }, |
| _objectsEqual: function (target, source) { |
| var t, s; |
| for (var i in target) { |
| t = target[i], s = source[i]; |
| if (!(typeof t === 'object' && t ? this._objectsStrictlyEqual(t, s) : t === s)) { |
| return false; |
| } |
| } |
| if (Array.isArray(target)) { |
| return target.length === source.length; |
| } |
| return true; |
| }, |
| _objectsStrictlyEqual: function (target, source) { |
| return this._objectsEqual(target, source) && this._objectsEqual(source, target); |
| } |
| }; |
| }());Polymer.StyleDefaults = function () { |
| var styleProperties = Polymer.StyleProperties; |
| var StyleCache = Polymer.StyleCache; |
| var nativeVariables = Polymer.Settings.useNativeCSSProperties; |
| var api = { |
| _styles: [], |
| _properties: null, |
| customStyle: {}, |
| _styleCache: new StyleCache(), |
| _element: Polymer.DomApi.wrap(document.documentElement), |
| addStyle: function (style) { |
| this._styles.push(style); |
| this._properties = null; |
| }, |
| get _styleProperties() { |
| if (!this._properties) { |
| styleProperties.decorateStyles(this._styles, this); |
| this._styles._scopeStyleProperties = null; |
| this._properties = styleProperties.hostAndRootPropertiesForScope(this).rootProps; |
| styleProperties.mixinCustomStyle(this._properties, this.customStyle); |
| styleProperties.reify(this._properties); |
| } |
| return this._properties; |
| }, |
| hasStyleProperties: function () { |
| return Boolean(this._properties); |
| }, |
| _needsStyleProperties: function () { |
| }, |
| _computeStyleProperties: function () { |
| return this._styleProperties; |
| }, |
| updateStyles: function (properties) { |
| this._properties = null; |
| if (properties) { |
| Polymer.Base.mixin(this.customStyle, properties); |
| } |
| this._styleCache.clear(); |
| for (var i = 0, s; i < this._styles.length; i++) { |
| s = this._styles[i]; |
| s = s.__importElement || s; |
| s._apply(); |
| } |
| if (nativeVariables) { |
| styleProperties.updateNativeStyleProperties(document.documentElement, this.customStyle); |
| } |
| } |
| }; |
| return api; |
| }();(function () { |
| 'use strict'; |
| var serializeValueToAttribute = Polymer.Base.serializeValueToAttribute; |
| var propertyUtils = Polymer.StyleProperties; |
| var styleTransformer = Polymer.StyleTransformer; |
| var styleDefaults = Polymer.StyleDefaults; |
| var nativeShadow = Polymer.Settings.useNativeShadow; |
| var nativeVariables = Polymer.Settings.useNativeCSSProperties; |
| Polymer.Base._addFeature({ |
| _prepStyleProperties: function () { |
| if (!nativeVariables) { |
| this._ownStylePropertyNames = this._styles && this._styles.length ? propertyUtils.decorateStyles(this._styles, this) : null; |
| } |
| }, |
| customStyle: null, |
| getComputedStyleValue: function (property) { |
| if (!nativeVariables && !this._styleProperties) { |
| this._computeStyleProperties(); |
| } |
| return !nativeVariables && this._styleProperties && this._styleProperties[property] || getComputedStyle(this).getPropertyValue(property); |
| }, |
| _setupStyleProperties: function () { |
| this.customStyle = {}; |
| this._styleCache = null; |
| this._styleProperties = null; |
| this._scopeSelector = null; |
| this._ownStyleProperties = null; |
| this._customStyle = null; |
| }, |
| _needsStyleProperties: function () { |
| return Boolean(!nativeVariables && this._ownStylePropertyNames && this._ownStylePropertyNames.length); |
| }, |
| _validateApplyShim: function () { |
| if (this.__applyShimInvalid) { |
| Polymer.ApplyShim.transform(this._styles, this.__proto__); |
| var cssText = styleTransformer.elementStyles(this); |
| if (nativeShadow) { |
| var templateStyle = this._template.content.querySelector('style'); |
| if (templateStyle) { |
| templateStyle.textContent = cssText; |
| } |
| } else { |
| var shadyStyle = this._scopeStyle && this._scopeStyle.nextSibling; |
| if (shadyStyle) { |
| shadyStyle.textContent = cssText; |
| } |
| } |
| } |
| }, |
| _beforeAttached: function () { |
| if ((!this._scopeSelector || this.__stylePropertiesInvalid) && this._needsStyleProperties()) { |
| this.__stylePropertiesInvalid = false; |
| this._updateStyleProperties(); |
| } |
| }, |
| _findStyleHost: function () { |
| var e = this, root; |
| while (root = Polymer.dom(e).getOwnerRoot()) { |
| if (Polymer.isInstance(root.host)) { |
| return root.host; |
| } |
| e = root.host; |
| } |
| return styleDefaults; |
| }, |
| _updateStyleProperties: function () { |
| var info, scope = this._findStyleHost(); |
| if (!scope._styleProperties) { |
| scope._computeStyleProperties(); |
| } |
| if (!scope._styleCache) { |
| scope._styleCache = new Polymer.StyleCache(); |
| } |
| var scopeData = propertyUtils.propertyDataFromStyles(scope._styles, this); |
| var scopeCacheable = !this.__notStyleScopeCacheable; |
| if (scopeCacheable) { |
| scopeData.key.customStyle = this.customStyle; |
| info = scope._styleCache.retrieve(this.is, scopeData.key, this._styles); |
| } |
| var scopeCached = Boolean(info); |
| if (scopeCached) { |
| this._styleProperties = info._styleProperties; |
| } else { |
| this._computeStyleProperties(scopeData.properties); |
| } |
| this._computeOwnStyleProperties(); |
| if (!scopeCached) { |
| info = styleCache.retrieve(this.is, this._ownStyleProperties, this._styles); |
| } |
| var globalCached = Boolean(info) && !scopeCached; |
| var style = this._applyStyleProperties(info); |
| if (!scopeCached) { |
| style = style && nativeShadow ? style.cloneNode(true) : style; |
| info = { |
| style: style, |
| _scopeSelector: this._scopeSelector, |
| _styleProperties: this._styleProperties |
| }; |
| if (scopeCacheable) { |
| scopeData.key.customStyle = {}; |
| this.mixin(scopeData.key.customStyle, this.customStyle); |
| scope._styleCache.store(this.is, info, scopeData.key, this._styles); |
| } |
| if (!globalCached) { |
| styleCache.store(this.is, Object.create(info), this._ownStyleProperties, this._styles); |
| } |
| } |
| }, |
| _computeStyleProperties: function (scopeProps) { |
| var scope = this._findStyleHost(); |
| if (!scope._styleProperties) { |
| scope._computeStyleProperties(); |
| } |
| var props = Object.create(scope._styleProperties); |
| var hostAndRootProps = propertyUtils.hostAndRootPropertiesForScope(this); |
| this.mixin(props, hostAndRootProps.hostProps); |
| scopeProps = scopeProps || propertyUtils.propertyDataFromStyles(scope._styles, this).properties; |
| this.mixin(props, scopeProps); |
| this.mixin(props, hostAndRootProps.rootProps); |
| propertyUtils.mixinCustomStyle(props, this.customStyle); |
| propertyUtils.reify(props); |
| this._styleProperties = props; |
| }, |
| _computeOwnStyleProperties: function () { |
| var props = {}; |
| for (var i = 0, n; i < this._ownStylePropertyNames.length; i++) { |
| n = this._ownStylePropertyNames[i]; |
| props[n] = this._styleProperties[n]; |
| } |
| this._ownStyleProperties = props; |
| }, |
| _scopeCount: 0, |
| _applyStyleProperties: function (info) { |
| var oldScopeSelector = this._scopeSelector; |
| this._scopeSelector = info ? info._scopeSelector : this.is + '-' + this.__proto__._scopeCount++; |
| var style = propertyUtils.applyElementStyle(this, this._styleProperties, this._scopeSelector, info && info.style); |
| if (!nativeShadow) { |
| propertyUtils.applyElementScopeSelector(this, this._scopeSelector, oldScopeSelector, this._scopeCssViaAttr); |
| } |
| return style; |
| }, |
| serializeValueToAttribute: function (value, attribute, node) { |
| node = node || this; |
| if (attribute === 'class' && !nativeShadow) { |
| var host = node === this ? this.domHost || this.dataHost : this; |
| if (host) { |
| value = host._scopeElementClass(node, value); |
| } |
| } |
| node = this.shadyRoot && this.shadyRoot._hasDistributed ? Polymer.dom(node) : node; |
| serializeValueToAttribute.call(this, value, attribute, node); |
| }, |
| _scopeElementClass: function (element, selector) { |
| if (!nativeShadow && !this._scopeCssViaAttr) { |
| selector = (selector ? selector + ' ' : '') + SCOPE_NAME + ' ' + this.is + (element._scopeSelector ? ' ' + XSCOPE_NAME + ' ' + element._scopeSelector : ''); |
| } |
| return selector; |
| }, |
| updateStyles: function (properties) { |
| if (properties) { |
| this.mixin(this.customStyle, properties); |
| } |
| if (nativeVariables) { |
| propertyUtils.updateNativeStyleProperties(this, this.customStyle); |
| } else { |
| if (this.isAttached) { |
| if (this._needsStyleProperties()) { |
| this._updateStyleProperties(); |
| } else { |
| this._styleProperties = null; |
| } |
| } else { |
| this.__stylePropertiesInvalid = true; |
| } |
| if (this._styleCache) { |
| this._styleCache.clear(); |
| } |
| this._updateRootStyles(); |
| } |
| }, |
| _updateRootStyles: function (root) { |
| root = root || this.root; |
| var c$ = Polymer.dom(root)._query(function (e) { |
| return e.shadyRoot || e.shadowRoot; |
| }); |
| for (var i = 0, l = c$.length, c; i < l && (c = c$[i]); i++) { |
| if (c.updateStyles) { |
| c.updateStyles(); |
| } |
| } |
| } |
| }); |
| Polymer.updateStyles = function (properties) { |
| styleDefaults.updateStyles(properties); |
| Polymer.Base._updateRootStyles(document); |
| }; |
| var styleCache = new Polymer.StyleCache(); |
| Polymer.customStyleCache = styleCache; |
| var SCOPE_NAME = styleTransformer.SCOPE_NAME; |
| var XSCOPE_NAME = propertyUtils.XSCOPE_NAME; |
| }());Polymer.Base._addFeature({ |
| _registerFeatures: function () { |
| this._prepIs(); |
| if (this.factoryImpl) { |
| this._prepConstructor(); |
| } |
| this._prepStyles(); |
| }, |
| _finishRegisterFeatures: function () { |
| this._prepTemplate(); |
| this._prepShimStyles(); |
| this._prepAnnotations(); |
| this._prepEffects(); |
| this._prepBehaviors(); |
| this._prepPropertyInfo(); |
| this._prepBindings(); |
| this._prepShady(); |
| }, |
| _prepBehavior: function (b) { |
| this._addPropertyEffects(b.properties); |
| this._addComplexObserverEffects(b.observers); |
| this._addHostAttributes(b.hostAttributes); |
| }, |
| _initFeatures: function () { |
| this._setupGestures(); |
| this._setupConfigure(this.__data__); |
| this._setupStyleProperties(); |
| this._setupDebouncers(); |
| this._setupShady(); |
| this._registerHost(); |
| if (this._template) { |
| this._validateApplyShim(); |
| this._poolContent(); |
| this._beginHosting(); |
| this._stampTemplate(); |
| this._endHosting(); |
| this._marshalAnnotationReferences(); |
| } |
| this._marshalInstanceEffects(); |
| this._marshalBehaviors(); |
| this._marshalHostAttributes(); |
| this._marshalAttributes(); |
| this._tryReady(); |
| }, |
| _marshalBehavior: function (b) { |
| if (b.listeners) { |
| this._listenListeners(b.listeners); |
| } |
| } |
| });(function () { |
| var propertyUtils = Polymer.StyleProperties; |
| var styleUtil = Polymer.StyleUtil; |
| var cssParse = Polymer.CssParse; |
| var styleDefaults = Polymer.StyleDefaults; |
| var styleTransformer = Polymer.StyleTransformer; |
| var applyShim = Polymer.ApplyShim; |
| var debounce = Polymer.Debounce; |
| var settings = Polymer.Settings; |
| var updateDebouncer; |
| Polymer({ |
| is: 'custom-style', |
| extends: 'style', |
| _template: null, |
| properties: { include: String }, |
| ready: function () { |
| this.__appliedElement = this.__appliedElement || this; |
| this.__cssBuild = styleUtil.getCssBuildType(this); |
| if (this.__appliedElement !== this) { |
| this.__appliedElement.__cssBuild = this.__cssBuild; |
| } |
| if (this.ownerDocument !== window.document && this.__appliedElement === this) { |
| document.head.appendChild(this); |
| } |
| this._tryApply(); |
| }, |
| attached: function () { |
| this._tryApply(); |
| }, |
| _tryApply: function () { |
| if (!this._appliesToDocument) { |
| if (this.parentNode && this.parentNode.localName !== 'dom-module') { |
| this._appliesToDocument = true; |
| var e = this.__appliedElement; |
| if (!settings.useNativeCSSProperties) { |
| this.__needsUpdateStyles = styleDefaults.hasStyleProperties(); |
| styleDefaults.addStyle(e); |
| } |
| if (e.textContent || this.include) { |
| this._apply(true); |
| } else { |
| var self = this; |
| var observer = new MutationObserver(function () { |
| observer.disconnect(); |
| self._apply(true); |
| }); |
| observer.observe(e, { childList: true }); |
| } |
| } |
| } |
| }, |
| _updateStyles: function () { |
| Polymer.updateStyles(); |
| }, |
| _apply: function (initialApply) { |
| var e = this.__appliedElement; |
| if (this.include) { |
| e.textContent = styleUtil.cssFromModules(this.include, true) + e.textContent; |
| } |
| if (!e.textContent) { |
| return; |
| } |
| var buildType = this.__cssBuild; |
| var targetedBuild = styleUtil.isTargetedBuild(buildType); |
| if (settings.useNativeCSSProperties && targetedBuild) { |
| return; |
| } |
| var styleRules = styleUtil.rulesForStyle(e); |
| if (!targetedBuild) { |
| styleUtil.forEachRule(styleRules, function (rule) { |
| styleTransformer.documentRule(rule); |
| }); |
| if (settings.useNativeCSSProperties && !buildType) { |
| applyShim.transform([e]); |
| } |
| } |
| if (settings.useNativeCSSProperties) { |
| e.textContent = styleUtil.toCssText(styleRules); |
| } else { |
| var self = this; |
| var fn = function fn() { |
| self._flushCustomProperties(); |
| }; |
| if (initialApply) { |
| Polymer.RenderStatus.whenReady(fn); |
| } else { |
| fn(); |
| } |
| } |
| }, |
| _flushCustomProperties: function () { |
| if (this.__needsUpdateStyles) { |
| this.__needsUpdateStyles = false; |
| updateDebouncer = debounce(updateDebouncer, this._updateStyles); |
| } else { |
| this._applyCustomProperties(); |
| } |
| }, |
| _applyCustomProperties: function () { |
| var element = this.__appliedElement; |
| this._computeStyleProperties(); |
| var props = this._styleProperties; |
| var rules = styleUtil.rulesForStyle(element); |
| if (!rules) { |
| return; |
| } |
| element.textContent = styleUtil.toCssText(rules, function (rule) { |
| var css = rule.cssText = rule.parsedCssText; |
| if (rule.propertyInfo && rule.propertyInfo.cssText) { |
| css = cssParse.removeCustomPropAssignment(css); |
| rule.cssText = propertyUtils.valueForProperties(css, props); |
| } |
| }); |
| } |
| }); |
| }());Polymer.Templatizer = { |
| properties: { __hideTemplateChildren__: { observer: '_showHideChildren' } }, |
| _instanceProps: Polymer.nob, |
| _parentPropPrefix: '_parent_', |
| templatize: function (template) { |
| this._templatized = template; |
| if (!template._content) { |
| template._content = template.content; |
| } |
| if (template._content._ctor) { |
| this.ctor = template._content._ctor; |
| this._prepParentProperties(this.ctor.prototype, template); |
| return; |
| } |
| var archetype = Object.create(Polymer.Base); |
| this._customPrepAnnotations(archetype, template); |
| this._prepParentProperties(archetype, template); |
| archetype._prepEffects(); |
| this._customPrepEffects(archetype); |
| archetype._prepBehaviors(); |
| archetype._prepPropertyInfo(); |
| archetype._prepBindings(); |
| archetype._notifyPathUp = this._notifyPathUpImpl; |
| archetype._scopeElementClass = this._scopeElementClassImpl; |
| archetype.listen = this._listenImpl; |
| archetype._showHideChildren = this._showHideChildrenImpl; |
| archetype.__setPropertyOrig = this.__setProperty; |
| archetype.__setProperty = this.__setPropertyImpl; |
| var _constructor = this._constructorImpl; |
| var ctor = function TemplateInstance(model, host) { |
| _constructor.call(this, model, host); |
| }; |
| ctor.prototype = archetype; |
| archetype.constructor = ctor; |
| template._content._ctor = ctor; |
| this.ctor = ctor; |
| }, |
| _getRootDataHost: function () { |
| return this.dataHost && this.dataHost._rootDataHost || this.dataHost; |
| }, |
| _showHideChildrenImpl: function (hide) { |
| var c = this._children; |
| for (var i = 0; i < c.length; i++) { |
| var n = c[i]; |
| if (Boolean(hide) != Boolean(n.__hideTemplateChildren__)) { |
| if (n.nodeType === Node.TEXT_NODE) { |
| if (hide) { |
| n.__polymerTextContent__ = n.textContent; |
| n.textContent = ''; |
| } else { |
| n.textContent = n.__polymerTextContent__; |
| } |
| } else if (n.style) { |
| if (hide) { |
| n.__polymerDisplay__ = n.style.display; |
| n.style.display = 'none'; |
| } else { |
| n.style.display = n.__polymerDisplay__; |
| } |
| } |
| } |
| n.__hideTemplateChildren__ = hide; |
| } |
| }, |
| __setPropertyImpl: function (property, value, fromAbove, node) { |
| if (node && node.__hideTemplateChildren__ && property == 'textContent') { |
| property = '__polymerTextContent__'; |
| } |
| this.__setPropertyOrig(property, value, fromAbove, node); |
| }, |
| _debounceTemplate: function (fn) { |
| Polymer.dom.addDebouncer(this.debounce('_debounceTemplate', fn)); |
| }, |
| _flushTemplates: function () { |
| Polymer.dom.flush(); |
| }, |
| _customPrepEffects: function (archetype) { |
| var parentProps = archetype._parentProps; |
| for (var prop in parentProps) { |
| archetype._addPropertyEffect(prop, 'function', this._createHostPropEffector(prop)); |
| } |
| for (prop in this._instanceProps) { |
| archetype._addPropertyEffect(prop, 'function', this._createInstancePropEffector(prop)); |
| } |
| }, |
| _customPrepAnnotations: function (archetype, template) { |
| var t = archetype._template = document.createElement('template'); |
| var c = t._content = template._content; |
| if (!c._notes) { |
| var rootDataHost = archetype._rootDataHost; |
| if (rootDataHost) { |
| Polymer.Annotations.prepElement = function () { |
| rootDataHost._prepElement(); |
| }; |
| } |
| c._notes = Polymer.Annotations.parseAnnotations(template); |
| Polymer.Annotations.prepElement = null; |
| this._processAnnotations(c._notes); |
| } |
| archetype._notes = c._notes; |
| archetype._parentProps = c._parentProps; |
| }, |
| _prepParentProperties: function (archetype, template) { |
| var parentProps = this._parentProps = archetype._parentProps; |
| if (this._forwardParentProp && parentProps) { |
| var proto = archetype._parentPropProto; |
| var prop; |
| if (!proto) { |
| for (prop in this._instanceProps) { |
| delete parentProps[prop]; |
| } |
| proto = archetype._parentPropProto = Object.create(null); |
| if (template != this) { |
| Polymer.Bind.prepareModel(proto); |
| Polymer.Base.prepareModelNotifyPath(proto); |
| } |
| for (prop in parentProps) { |
| var parentProp = this._parentPropPrefix + prop; |
| var effects = [ |
| { |
| kind: 'function', |
| effect: this._createForwardPropEffector(prop), |
| fn: Polymer.Bind._functionEffect |
| }, |
| { |
| kind: 'notify', |
| fn: Polymer.Bind._notifyEffect, |
| effect: { event: Polymer.CaseMap.camelToDashCase(parentProp) + '-changed' } |
| } |
| ]; |
| proto._propertyEffects = proto._propertyEffects || {}; |
| proto._propertyEffects[parentProp] = effects; |
| Polymer.Bind._createAccessors(proto, parentProp, effects); |
| } |
| } |
| var self = this; |
| if (template != this) { |
| Polymer.Bind.prepareInstance(template); |
| template._forwardParentProp = function (source, value) { |
| self._forwardParentProp(source, value); |
| }; |
| } |
| this._extendTemplate(template, proto); |
| template._pathEffector = function (path, value, fromAbove) { |
| return self._pathEffectorImpl(path, value, fromAbove); |
| }; |
| } |
| }, |
| _createForwardPropEffector: function (prop) { |
| return function (source, value) { |
| this._forwardParentProp(prop, value); |
| }; |
| }, |
| _createHostPropEffector: function (prop) { |
| var prefix = this._parentPropPrefix; |
| return function (source, value) { |
| this.dataHost._templatized[prefix + prop] = value; |
| }; |
| }, |
| _createInstancePropEffector: function (prop) { |
| return function (source, value, old, fromAbove) { |
| if (!fromAbove) { |
| this.dataHost._forwardInstanceProp(this, prop, value); |
| } |
| }; |
| }, |
| _extendTemplate: function (template, proto) { |
| var n$ = Object.getOwnPropertyNames(proto); |
| if (proto._propertySetter) { |
| template._propertySetter = proto._propertySetter; |
| } |
| for (var i = 0, n; i < n$.length && (n = n$[i]); i++) { |
| var val = template[n]; |
| if (val && n == '_propertyEffects') { |
| var pe = Polymer.Base.mixin({}, val); |
| template._propertyEffects = Polymer.Base.mixin(pe, proto._propertyEffects); |
| } else { |
| var pd = Object.getOwnPropertyDescriptor(proto, n); |
| Object.defineProperty(template, n, pd); |
| if (val !== undefined) { |
| template._propertySetter(n, val); |
| } |
| } |
| } |
| }, |
| _showHideChildren: function (hidden) { |
| }, |
| _forwardInstancePath: function (inst, path, value) { |
| }, |
| _forwardInstanceProp: function (inst, prop, value) { |
| }, |
| _notifyPathUpImpl: function (path, value) { |
| var dataHost = this.dataHost; |
| var root = Polymer.Path.root(path); |
| dataHost._forwardInstancePath.call(dataHost, this, path, value); |
| if (root in dataHost._parentProps) { |
| dataHost._templatized._notifyPath(dataHost._parentPropPrefix + path, value); |
| } |
| }, |
| _pathEffectorImpl: function (path, value, fromAbove) { |
| if (this._forwardParentPath) { |
| if (path.indexOf(this._parentPropPrefix) === 0) { |
| var subPath = path.substring(this._parentPropPrefix.length); |
| var model = Polymer.Path.root(subPath); |
| if (model in this._parentProps) { |
| this._forwardParentPath(subPath, value); |
| } |
| } |
| } |
| Polymer.Base._pathEffector.call(this._templatized, path, value, fromAbove); |
| }, |
| _constructorImpl: function (model, host) { |
| this._rootDataHost = host._getRootDataHost(); |
| this._setupConfigure(model); |
| this._registerHost(host); |
| this._beginHosting(); |
| this.root = this.instanceTemplate(this._template); |
| this.root.__noContent = !this._notes._hasContent; |
| this.root.__styleScoped = true; |
| this._endHosting(); |
| this._marshalAnnotatedNodes(); |
| this._marshalInstanceEffects(); |
| this._marshalAnnotatedListeners(); |
| var children = []; |
| for (var n = this.root.firstChild; n; n = n.nextSibling) { |
| children.push(n); |
| n._templateInstance = this; |
| } |
| this._children = children; |
| if (host.__hideTemplateChildren__) { |
| this._showHideChildren(true); |
| } |
| this._tryReady(); |
| }, |
| _listenImpl: function (node, eventName, methodName) { |
| var model = this; |
| var host = this._rootDataHost; |
| var handler = host._createEventHandler(node, eventName, methodName); |
| var decorated = function (e) { |
| e.model = model; |
| handler(e); |
| }; |
| host._listen(node, eventName, decorated); |
| }, |
| _scopeElementClassImpl: function (node, value) { |
| var host = this._rootDataHost; |
| if (host) { |
| return host._scopeElementClass(node, value); |
| } |
| return value; |
| }, |
| stamp: function (model) { |
| model = model || {}; |
| if (this._parentProps) { |
| var templatized = this._templatized; |
| for (var prop in this._parentProps) { |
| if (model[prop] === undefined) { |
| model[prop] = templatized[this._parentPropPrefix + prop]; |
| } |
| } |
| } |
| return new this.ctor(model, this); |
| }, |
| modelForElement: function (el) { |
| var model; |
| while (el) { |
| if (model = el._templateInstance) { |
| if (model.dataHost != this) { |
| el = model.dataHost; |
| } else { |
| return model; |
| } |
| } else { |
| el = el.parentNode; |
| } |
| } |
| } |
| };Polymer({ |
| is: 'dom-template', |
| extends: 'template', |
| _template: null, |
| behaviors: [Polymer.Templatizer], |
| ready: function () { |
| this.templatize(this); |
| } |
| });Polymer._collections = new WeakMap(); |
| Polymer.Collection = function (userArray) { |
| Polymer._collections.set(userArray, this); |
| this.userArray = userArray; |
| this.store = userArray.slice(); |
| this.initMap(); |
| }; |
| Polymer.Collection.prototype = { |
| constructor: Polymer.Collection, |
| initMap: function () { |
| var omap = this.omap = new WeakMap(); |
| var pmap = this.pmap = {}; |
| var s = this.store; |
| for (var i = 0; i < s.length; i++) { |
| var item = s[i]; |
| if (item && typeof item == 'object') { |
| omap.set(item, i); |
| } else { |
| pmap[item] = i; |
| } |
| } |
| }, |
| add: function (item) { |
| var key = this.store.push(item) - 1; |
| if (item && typeof item == 'object') { |
| this.omap.set(item, key); |
| } else { |
| this.pmap[item] = key; |
| } |
| return '#' + key; |
| }, |
| removeKey: function (key) { |
| if (key = this._parseKey(key)) { |
| this._removeFromMap(this.store[key]); |
| delete this.store[key]; |
| } |
| }, |
| _removeFromMap: function (item) { |
| if (item && typeof item == 'object') { |
| this.omap.delete(item); |
| } else { |
| delete this.pmap[item]; |
| } |
| }, |
| remove: function (item) { |
| var key = this.getKey(item); |
| this.removeKey(key); |
| return key; |
| }, |
| getKey: function (item) { |
| var key; |
| if (item && typeof item == 'object') { |
| key = this.omap.get(item); |
| } else { |
| key = this.pmap[item]; |
| } |
| if (key != undefined) { |
| return '#' + key; |
| } |
| }, |
| getKeys: function () { |
| return Object.keys(this.store).map(function (key) { |
| return '#' + key; |
| }); |
| }, |
| _parseKey: function (key) { |
| if (key && key[0] == '#') { |
| return key.slice(1); |
| } |
| }, |
| setItem: function (key, item) { |
| if (key = this._parseKey(key)) { |
| var old = this.store[key]; |
| if (old) { |
| this._removeFromMap(old); |
| } |
| if (item && typeof item == 'object') { |
| this.omap.set(item, key); |
| } else { |
| this.pmap[item] = key; |
| } |
| this.store[key] = item; |
| } |
| }, |
| getItem: function (key) { |
| if (key = this._parseKey(key)) { |
| return this.store[key]; |
| } |
| }, |
| getItems: function () { |
| var items = [], store = this.store; |
| for (var key in store) { |
| items.push(store[key]); |
| } |
| return items; |
| }, |
| _applySplices: function (splices) { |
| var keyMap = {}, key; |
| for (var i = 0, s; i < splices.length && (s = splices[i]); i++) { |
| s.addedKeys = []; |
| for (var j = 0; j < s.removed.length; j++) { |
| key = this.getKey(s.removed[j]); |
| keyMap[key] = keyMap[key] ? null : -1; |
| } |
| for (j = 0; j < s.addedCount; j++) { |
| var item = this.userArray[s.index + j]; |
| key = this.getKey(item); |
| key = key === undefined ? this.add(item) : key; |
| keyMap[key] = keyMap[key] ? null : 1; |
| s.addedKeys.push(key); |
| } |
| } |
| var removed = []; |
| var added = []; |
| for (key in keyMap) { |
| if (keyMap[key] < 0) { |
| this.removeKey(key); |
| removed.push(key); |
| } |
| if (keyMap[key] > 0) { |
| added.push(key); |
| } |
| } |
| return [{ |
| removed: removed, |
| added: added |
| }]; |
| } |
| }; |
| Polymer.Collection.get = function (userArray) { |
| return Polymer._collections.get(userArray) || new Polymer.Collection(userArray); |
| }; |
| Polymer.Collection.applySplices = function (userArray, splices) { |
| var coll = Polymer._collections.get(userArray); |
| return coll ? coll._applySplices(splices) : null; |
| };Polymer({ |
| is: 'dom-repeat', |
| extends: 'template', |
| _template: null, |
| properties: { |
| items: { type: Array }, |
| as: { |
| type: String, |
| value: 'item' |
| }, |
| indexAs: { |
| type: String, |
| value: 'index' |
| }, |
| sort: { |
| type: Function, |
| observer: '_sortChanged' |
| }, |
| filter: { |
| type: Function, |
| observer: '_filterChanged' |
| }, |
| observe: { |
| type: String, |
| observer: '_observeChanged' |
| }, |
| delay: Number, |
| renderedItemCount: { |
| type: Number, |
| notify: !Polymer.Settings.suppressTemplateNotifications, |
| readOnly: true |
| }, |
| initialCount: { |
| type: Number, |
| observer: '_initializeChunking' |
| }, |
| targetFramerate: { |
| type: Number, |
| value: 20 |
| }, |
| notifyDomChange: { type: Boolean }, |
| _targetFrameTime: { |
| type: Number, |
| computed: '_computeFrameTime(targetFramerate)' |
| } |
| }, |
| behaviors: [Polymer.Templatizer], |
| observers: ['_itemsChanged(items.*)'], |
| created: function () { |
| this._instances = []; |
| this._pool = []; |
| this._limit = Infinity; |
| var self = this; |
| this._boundRenderChunk = function () { |
| self._renderChunk(); |
| }; |
| }, |
| detached: function () { |
| this.__isDetached = true; |
| for (var i = 0; i < this._instances.length; i++) { |
| this._detachInstance(i); |
| } |
| }, |
| attached: function () { |
| if (this.__isDetached) { |
| this.__isDetached = false; |
| var refNode; |
| var parentNode = Polymer.dom(this).parentNode; |
| if (parentNode.localName == this.is) { |
| refNode = parentNode; |
| parentNode = Polymer.dom(parentNode).parentNode; |
| } else { |
| refNode = this; |
| } |
| var parent = Polymer.dom(parentNode); |
| for (var i = 0; i < this._instances.length; i++) { |
| this._attachInstance(i, parent, refNode); |
| } |
| } |
| }, |
| ready: function () { |
| this._instanceProps = { __key__: true }; |
| this._instanceProps[this.as] = true; |
| this._instanceProps[this.indexAs] = true; |
| if (!this.ctor) { |
| this.templatize(this); |
| } |
| }, |
| _sortChanged: function (sort) { |
| var dataHost = this._getRootDataHost(); |
| this._sortFn = sort && (typeof sort == 'function' ? sort : function () { |
| return dataHost[sort].apply(dataHost, arguments); |
| }); |
| this._needFullRefresh = true; |
| if (this.items) { |
| this._debounceTemplate(this._render); |
| } |
| }, |
| _filterChanged: function (filter) { |
| var dataHost = this._getRootDataHost(); |
| this._filterFn = filter && (typeof filter == 'function' ? filter : function () { |
| return dataHost[filter].apply(dataHost, arguments); |
| }); |
| this._needFullRefresh = true; |
| if (this.items) { |
| this._debounceTemplate(this._render); |
| } |
| }, |
| _computeFrameTime: function (rate) { |
| return Math.ceil(1000 / rate); |
| }, |
| _initializeChunking: function () { |
| if (this.initialCount) { |
| this._limit = this.initialCount; |
| this._chunkCount = this.initialCount; |
| this._lastChunkTime = performance.now(); |
| } |
| }, |
| _tryRenderChunk: function () { |
| if (this.items && this._limit < this.items.length) { |
| this.debounce('renderChunk', this._requestRenderChunk); |
| } |
| }, |
| _requestRenderChunk: function () { |
| requestAnimationFrame(this._boundRenderChunk); |
| }, |
| _renderChunk: function () { |
| var currChunkTime = performance.now(); |
| var ratio = this._targetFrameTime / (currChunkTime - this._lastChunkTime); |
| this._chunkCount = Math.round(this._chunkCount * ratio) || 1; |
| this._limit += this._chunkCount; |
| this._lastChunkTime = currChunkTime; |
| this._debounceTemplate(this._render); |
| }, |
| _observeChanged: function () { |
| this._observePaths = this.observe && this.observe.replace('.*', '.').split(' '); |
| }, |
| _itemsChanged: function (change) { |
| if (change.path == 'items') { |
| if (Array.isArray(this.items)) { |
| this.collection = Polymer.Collection.get(this.items); |
| } else if (!this.items) { |
| this.collection = null; |
| } else { |
| this._error(this._logf('dom-repeat', 'expected array for `items`,' + ' found', this.items)); |
| } |
| this._keySplices = []; |
| this._indexSplices = []; |
| this._needFullRefresh = true; |
| this._initializeChunking(); |
| this._debounceTemplate(this._render); |
| } else if (change.path == 'items.splices') { |
| this._keySplices = this._keySplices.concat(change.value.keySplices); |
| this._indexSplices = this._indexSplices.concat(change.value.indexSplices); |
| this._debounceTemplate(this._render); |
| } else { |
| var subpath = change.path.slice(6); |
| this._forwardItemPath(subpath, change.value); |
| this._checkObservedPaths(subpath); |
| } |
| }, |
| _checkObservedPaths: function (path) { |
| if (this._observePaths) { |
| path = path.substring(path.indexOf('.') + 1); |
| var paths = this._observePaths; |
| for (var i = 0; i < paths.length; i++) { |
| if (path.indexOf(paths[i]) === 0) { |
| this._needFullRefresh = true; |
| if (this.delay) { |
| this.debounce('render', this._render, this.delay); |
| } else { |
| this._debounceTemplate(this._render); |
| } |
| return; |
| } |
| } |
| } |
| }, |
| render: function () { |
| this._needFullRefresh = true; |
| this._debounceTemplate(this._render); |
| this._flushTemplates(); |
| }, |
| _render: function () { |
| if (this._needFullRefresh) { |
| this._applyFullRefresh(); |
| this._needFullRefresh = false; |
| } else if (this._keySplices.length) { |
| if (this._sortFn) { |
| this._applySplicesUserSort(this._keySplices); |
| } else { |
| if (this._filterFn) { |
| this._applyFullRefresh(); |
| } else { |
| this._applySplicesArrayOrder(this._indexSplices); |
| } |
| } |
| } else { |
| } |
| this._keySplices = []; |
| this._indexSplices = []; |
| var keyToIdx = this._keyToInstIdx = {}; |
| for (var i = this._instances.length - 1; i >= 0; i--) { |
| var inst = this._instances[i]; |
| if (inst.isPlaceholder && i < this._limit) { |
| inst = this._insertInstance(i, inst.__key__); |
| } else if (!inst.isPlaceholder && i >= this._limit) { |
| inst = this._downgradeInstance(i, inst.__key__); |
| } |
| keyToIdx[inst.__key__] = i; |
| if (!inst.isPlaceholder) { |
| inst.__setProperty(this.indexAs, i, true); |
| } |
| } |
| this._pool.length = 0; |
| this._setRenderedItemCount(this._instances.length); |
| if (!Polymer.Settings.suppressTemplateNotifications || this.notifyDomChange) { |
| this.fire('dom-change'); |
| } |
| this._tryRenderChunk(); |
| }, |
| _applyFullRefresh: function () { |
| var c = this.collection; |
| var keys; |
| if (this._sortFn) { |
| keys = c ? c.getKeys() : []; |
| } else { |
| keys = []; |
| var items = this.items; |
| if (items) { |
| for (var i = 0; i < items.length; i++) { |
| keys.push(c.getKey(items[i])); |
| } |
| } |
| } |
| var self = this; |
| if (this._filterFn) { |
| keys = keys.filter(function (a) { |
| return self._filterFn(c.getItem(a)); |
| }); |
| } |
| if (this._sortFn) { |
| keys.sort(function (a, b) { |
| return self._sortFn(c.getItem(a), c.getItem(b)); |
| }); |
| } |
| for (i = 0; i < keys.length; i++) { |
| var key = keys[i]; |
| var inst = this._instances[i]; |
| if (inst) { |
| inst.__key__ = key; |
| if (!inst.isPlaceholder && i < this._limit) { |
| inst.__setProperty(this.as, c.getItem(key), true); |
| } |
| } else if (i < this._limit) { |
| this._insertInstance(i, key); |
| } else { |
| this._insertPlaceholder(i, key); |
| } |
| } |
| for (var j = this._instances.length - 1; j >= i; j--) { |
| this._detachAndRemoveInstance(j); |
| } |
| }, |
| _numericSort: function (a, b) { |
| return a - b; |
| }, |
| _applySplicesUserSort: function (splices) { |
| var c = this.collection; |
| var keyMap = {}; |
| var key; |
| for (var i = 0, s; i < splices.length && (s = splices[i]); i++) { |
| for (var j = 0; j < s.removed.length; j++) { |
| key = s.removed[j]; |
| keyMap[key] = keyMap[key] ? null : -1; |
| } |
| for (j = 0; j < s.added.length; j++) { |
| key = s.added[j]; |
| keyMap[key] = keyMap[key] ? null : 1; |
| } |
| } |
| var removedIdxs = []; |
| var addedKeys = []; |
| for (key in keyMap) { |
| if (keyMap[key] === -1) { |
| removedIdxs.push(this._keyToInstIdx[key]); |
| } |
| if (keyMap[key] === 1) { |
| addedKeys.push(key); |
| } |
| } |
| if (removedIdxs.length) { |
| removedIdxs.sort(this._numericSort); |
| for (i = removedIdxs.length - 1; i >= 0; i--) { |
| var idx = removedIdxs[i]; |
| if (idx !== undefined) { |
| this._detachAndRemoveInstance(idx); |
| } |
| } |
| } |
| var self = this; |
| if (addedKeys.length) { |
| if (this._filterFn) { |
| addedKeys = addedKeys.filter(function (a) { |
| return self._filterFn(c.getItem(a)); |
| }); |
| } |
| addedKeys.sort(function (a, b) { |
| return self._sortFn(c.getItem(a), c.getItem(b)); |
| }); |
| var start = 0; |
| for (i = 0; i < addedKeys.length; i++) { |
| start = this._insertRowUserSort(start, addedKeys[i]); |
| } |
| } |
| }, |
| _insertRowUserSort: function (start, key) { |
| var c = this.collection; |
| var item = c.getItem(key); |
| var end = this._instances.length - 1; |
| var idx = -1; |
| while (start <= end) { |
| var mid = start + end >> 1; |
| var midKey = this._instances[mid].__key__; |
| var cmp = this._sortFn(c.getItem(midKey), item); |
| if (cmp < 0) { |
| start = mid + 1; |
| } else if (cmp > 0) { |
| end = mid - 1; |
| } else { |
| idx = mid; |
| break; |
| } |
| } |
| if (idx < 0) { |
| idx = end + 1; |
| } |
| this._insertPlaceholder(idx, key); |
| return idx; |
| }, |
| _applySplicesArrayOrder: function (splices) { |
| for (var i = 0, s; i < splices.length && (s = splices[i]); i++) { |
| for (var j = 0; j < s.removed.length; j++) { |
| this._detachAndRemoveInstance(s.index); |
| } |
| for (j = 0; j < s.addedKeys.length; j++) { |
| this._insertPlaceholder(s.index + j, s.addedKeys[j]); |
| } |
| } |
| }, |
| _detachInstance: function (idx) { |
| var inst = this._instances[idx]; |
| if (!inst.isPlaceholder) { |
| for (var i = 0; i < inst._children.length; i++) { |
| var el = inst._children[i]; |
| Polymer.dom(inst.root).appendChild(el); |
| } |
| return inst; |
| } |
| }, |
| _attachInstance: function (idx, parent, refNode) { |
| var inst = this._instances[idx]; |
| if (!inst.isPlaceholder) { |
| parent.insertBefore(inst.root, refNode); |
| } |
| }, |
| _detachAndRemoveInstance: function (idx) { |
| var inst = this._detachInstance(idx); |
| if (inst) { |
| this._pool.push(inst); |
| } |
| this._instances.splice(idx, 1); |
| }, |
| _insertPlaceholder: function (idx, key) { |
| this._instances.splice(idx, 0, { |
| isPlaceholder: true, |
| __key__: key |
| }); |
| }, |
| _stampInstance: function (idx, key) { |
| var model = { __key__: key }; |
| model[this.as] = this.collection.getItem(key); |
| model[this.indexAs] = idx; |
| return this.stamp(model); |
| }, |
| _insertInstance: function (idx, key) { |
| var inst = this._pool.pop(); |
| if (inst) { |
| inst.__setProperty(this.as, this.collection.getItem(key), true); |
| inst.__setProperty('__key__', key, true); |
| } else { |
| inst = this._stampInstance(idx, key); |
| } |
| var beforeRow = this._instances[idx + 1]; |
| var beforeNode = beforeRow && !beforeRow.isPlaceholder ? beforeRow._children[0] : this; |
| var parentNode = Polymer.dom(this).parentNode; |
| if (parentNode.localName == this.is) { |
| if (beforeNode == this) { |
| beforeNode = parentNode; |
| } |
| parentNode = Polymer.dom(parentNode).parentNode; |
| } |
| Polymer.dom(parentNode).insertBefore(inst.root, beforeNode); |
| this._instances[idx] = inst; |
| return inst; |
| }, |
| _downgradeInstance: function (idx, key) { |
| var inst = this._detachInstance(idx); |
| if (inst) { |
| this._pool.push(inst); |
| } |
| inst = { |
| isPlaceholder: true, |
| __key__: key |
| }; |
| this._instances[idx] = inst; |
| return inst; |
| }, |
| _showHideChildren: function (hidden) { |
| for (var i = 0; i < this._instances.length; i++) { |
| if (!this._instances[i].isPlaceholder) |
| this._instances[i]._showHideChildren(hidden); |
| } |
| }, |
| _forwardInstanceProp: function (inst, prop, value) { |
| if (prop == this.as) { |
| var idx; |
| if (this._sortFn || this._filterFn) { |
| idx = this.items.indexOf(this.collection.getItem(inst.__key__)); |
| } else { |
| idx = inst[this.indexAs]; |
| } |
| this.set('items.' + idx, value); |
| } |
| }, |
| _forwardInstancePath: function (inst, path, value) { |
| if (path.indexOf(this.as + '.') === 0) { |
| this._notifyPath('items.' + inst.__key__ + '.' + path.slice(this.as.length + 1), value); |
| } |
| }, |
| _forwardParentProp: function (prop, value) { |
| var i$ = this._instances; |
| for (var i = 0, inst; i < i$.length && (inst = i$[i]); i++) { |
| if (!inst.isPlaceholder) { |
| inst.__setProperty(prop, value, true); |
| } |
| } |
| }, |
| _forwardParentPath: function (path, value) { |
| var i$ = this._instances; |
| for (var i = 0, inst; i < i$.length && (inst = i$[i]); i++) { |
| if (!inst.isPlaceholder) { |
| inst._notifyPath(path, value, true); |
| } |
| } |
| }, |
| _forwardItemPath: function (path, value) { |
| if (this._keyToInstIdx) { |
| var dot = path.indexOf('.'); |
| var key = path.substring(0, dot < 0 ? path.length : dot); |
| var idx = this._keyToInstIdx[key]; |
| var inst = this._instances[idx]; |
| if (inst && !inst.isPlaceholder) { |
| if (dot >= 0) { |
| path = this.as + '.' + path.substring(dot + 1); |
| inst._notifyPath(path, value, true); |
| } else { |
| inst.__setProperty(this.as, value, true); |
| } |
| } |
| } |
| }, |
| itemForElement: function (el) { |
| var instance = this.modelForElement(el); |
| return instance && instance[this.as]; |
| }, |
| keyForElement: function (el) { |
| var instance = this.modelForElement(el); |
| return instance && instance.__key__; |
| }, |
| indexForElement: function (el) { |
| var instance = this.modelForElement(el); |
| return instance && instance[this.indexAs]; |
| } |
| });Polymer({ |
| is: 'array-selector', |
| _template: null, |
| properties: { |
| items: { |
| type: Array, |
| observer: 'clearSelection' |
| }, |
| multi: { |
| type: Boolean, |
| value: false, |
| observer: 'clearSelection' |
| }, |
| selected: { |
| type: Object, |
| notify: true |
| }, |
| selectedItem: { |
| type: Object, |
| notify: true |
| }, |
| toggle: { |
| type: Boolean, |
| value: false |
| } |
| }, |
| clearSelection: function () { |
| if (Array.isArray(this.selected)) { |
| for (var i = 0; i < this.selected.length; i++) { |
| this.unlinkPaths('selected.' + i); |
| } |
| } else { |
| this.unlinkPaths('selected'); |
| this.unlinkPaths('selectedItem'); |
| } |
| if (this.multi) { |
| if (!this.selected || this.selected.length) { |
| this.selected = []; |
| this._selectedColl = Polymer.Collection.get(this.selected); |
| } |
| } else { |
| this.selected = null; |
| this._selectedColl = null; |
| } |
| this.selectedItem = null; |
| }, |
| isSelected: function (item) { |
| if (this.multi) { |
| return this._selectedColl.getKey(item) !== undefined; |
| } else { |
| return this.selected == item; |
| } |
| }, |
| deselect: function (item) { |
| if (this.multi) { |
| if (this.isSelected(item)) { |
| var skey = this._selectedColl.getKey(item); |
| this.arrayDelete('selected', item); |
| this.unlinkPaths('selected.' + skey); |
| } |
| } else { |
| this.selected = null; |
| this.selectedItem = null; |
| this.unlinkPaths('selected'); |
| this.unlinkPaths('selectedItem'); |
| } |
| }, |
| select: function (item) { |
| var icol = Polymer.Collection.get(this.items); |
| var key = icol.getKey(item); |
| if (this.multi) { |
| if (this.isSelected(item)) { |
| if (this.toggle) { |
| this.deselect(item); |
| } |
| } else { |
| this.push('selected', item); |
| var skey = this._selectedColl.getKey(item); |
| this.linkPaths('selected.' + skey, 'items.' + key); |
| } |
| } else { |
| if (this.toggle && item == this.selected) { |
| this.deselect(); |
| } else { |
| this.selected = item; |
| this.selectedItem = item; |
| this.linkPaths('selected', 'items.' + key); |
| this.linkPaths('selectedItem', 'items.' + key); |
| } |
| } |
| } |
| });Polymer({ |
| is: 'dom-if', |
| extends: 'template', |
| _template: null, |
| properties: { |
| 'if': { |
| type: Boolean, |
| value: false, |
| observer: '_queueRender' |
| }, |
| restamp: { |
| type: Boolean, |
| value: false, |
| observer: '_queueRender' |
| }, |
| notifyDomChange: { type: Boolean } |
| }, |
| behaviors: [Polymer.Templatizer], |
| _queueRender: function () { |
| this._debounceTemplate(this._render); |
| }, |
| detached: function () { |
| var parentNode = this.parentNode; |
| if (parentNode && parentNode.localName == this.is) { |
| parentNode = Polymer.dom(parentNode).parentNode; |
| } |
| if (!parentNode || parentNode.nodeType == Node.DOCUMENT_FRAGMENT_NODE && (!Polymer.Settings.hasShadow || !(parentNode instanceof ShadowRoot))) { |
| this._teardownInstance(); |
| } |
| }, |
| attached: function () { |
| if (this.if && this.ctor) { |
| this.async(this._ensureInstance); |
| } |
| }, |
| render: function () { |
| this._flushTemplates(); |
| }, |
| _render: function () { |
| if (this.if) { |
| if (!this.ctor) { |
| this.templatize(this); |
| } |
| this._ensureInstance(); |
| this._showHideChildren(); |
| } else if (this.restamp) { |
| this._teardownInstance(); |
| } |
| if (!this.restamp && this._instance) { |
| this._showHideChildren(); |
| } |
| if (this.if != this._lastIf) { |
| if (!Polymer.Settings.suppressTemplateNotifications || this.notifyDomChange) { |
| this.fire('dom-change'); |
| } |
| this._lastIf = this.if; |
| } |
| }, |
| _ensureInstance: function () { |
| var refNode; |
| var parentNode = Polymer.dom(this).parentNode; |
| if (parentNode && parentNode.localName == this.is) { |
| refNode = parentNode; |
| parentNode = Polymer.dom(parentNode).parentNode; |
| } else { |
| refNode = this; |
| } |
| if (parentNode) { |
| if (!this._instance) { |
| this._instance = this.stamp(); |
| var root = this._instance.root; |
| Polymer.dom(parentNode).insertBefore(root, refNode); |
| } else { |
| var c$ = this._instance._children; |
| if (c$ && c$.length) { |
| var lastChild = Polymer.dom(refNode).previousSibling; |
| if (lastChild !== c$[c$.length - 1]) { |
| for (var i = 0, n; i < c$.length && (n = c$[i]); i++) { |
| Polymer.dom(parentNode).insertBefore(n, refNode); |
| } |
| } |
| } |
| } |
| } |
| }, |
| _teardownInstance: function () { |
| if (this._instance) { |
| var c$ = this._instance._children; |
| if (c$ && c$.length) { |
| var parent = Polymer.dom(Polymer.dom(c$[0]).parentNode); |
| for (var i = 0, n; i < c$.length && (n = c$[i]); i++) { |
| parent.removeChild(n); |
| } |
| } |
| this._instance = null; |
| } |
| }, |
| _showHideChildren: function () { |
| var hidden = this.__hideTemplateChildren__ || !this.if; |
| if (this._instance) { |
| this._instance._showHideChildren(hidden); |
| } |
| }, |
| _forwardParentProp: function (prop, value) { |
| if (this._instance) { |
| this._instance.__setProperty(prop, value, true); |
| } |
| }, |
| _forwardParentPath: function (path, value) { |
| if (this._instance) { |
| this._instance._notifyPath(path, value, true); |
| } |
| } |
| });Polymer({ |
| is: 'dom-bind', |
| properties: { notifyDomChange: { type: Boolean } }, |
| extends: 'template', |
| _template: null, |
| created: function () { |
| var self = this; |
| Polymer.RenderStatus.whenReady(function () { |
| if (document.readyState == 'loading') { |
| document.addEventListener('DOMContentLoaded', function () { |
| self._markImportsReady(); |
| }); |
| } else { |
| self._markImportsReady(); |
| } |
| }); |
| }, |
| _ensureReady: function () { |
| if (!this._readied) { |
| this._readySelf(); |
| } |
| }, |
| _markImportsReady: function () { |
| this._importsReady = true; |
| this._ensureReady(); |
| }, |
| _registerFeatures: function () { |
| this._prepConstructor(); |
| }, |
| _insertChildren: function () { |
| var refNode; |
| var parentNode = Polymer.dom(this).parentNode; |
| if (parentNode.localName == this.is) { |
| refNode = parentNode; |
| parentNode = Polymer.dom(parentNode).parentNode; |
| } else { |
| refNode = this; |
| } |
| Polymer.dom(parentNode).insertBefore(this.root, refNode); |
| }, |
| _removeChildren: function () { |
| if (this._children) { |
| for (var i = 0; i < this._children.length; i++) { |
| this.root.appendChild(this._children[i]); |
| } |
| } |
| }, |
| _initFeatures: function () { |
| }, |
| _scopeElementClass: function (element, selector) { |
| if (this.dataHost) { |
| return this.dataHost._scopeElementClass(element, selector); |
| } else { |
| return selector; |
| } |
| }, |
| _configureInstanceProperties: function () { |
| }, |
| _prepConfigure: function () { |
| var config = {}; |
| for (var prop in this._propertyEffects) { |
| config[prop] = this[prop]; |
| } |
| var setupConfigure = this._setupConfigure; |
| this._setupConfigure = function () { |
| setupConfigure.call(this, config); |
| }; |
| }, |
| attached: function () { |
| if (this._importsReady) { |
| this.render(); |
| } |
| }, |
| detached: function () { |
| this._removeChildren(); |
| }, |
| render: function () { |
| this._ensureReady(); |
| if (!this._children) { |
| this._template = this; |
| this._prepAnnotations(); |
| this._prepEffects(); |
| this._prepBehaviors(); |
| this._prepConfigure(); |
| this._prepBindings(); |
| this._prepPropertyInfo(); |
| Polymer.Base._initFeatures.call(this); |
| this._children = Polymer.TreeApi.arrayCopyChildNodes(this.root); |
| } |
| this._insertChildren(); |
| if (!Polymer.Settings.suppressTemplateNotifications || this.notifyDomChange) { |
| this.fire('dom-change'); |
| } |
| } |
| });</script> |
| |
| |
| |
| |
| |
| |
| |
| |
| |