| Index: pkg/polymer/lib/src/js/polymer/polymer.concat.js
|
| diff --git a/pkg/polymer/lib/src/js/polymer/polymer.concat.js b/pkg/polymer/lib/src/js/polymer/polymer.concat.js
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..44c0afbcf74e49b9951b0903a12fe5bcc5529a2a
|
| --- /dev/null
|
| +++ b/pkg/polymer/lib/src/js/polymer/polymer.concat.js
|
| @@ -0,0 +1,2357 @@
|
| +/*
|
| + * Copyright 2013 The Polymer Authors. All rights reserved.
|
| + * Use of this source code is governed by a BSD-style
|
| + * license that can be found in the LICENSE file.
|
| + */
|
| +Polymer = {};
|
| +
|
| +/*
|
| + * Copyright 2013 The Polymer Authors. All rights reserved.
|
| + * Use of this source code is governed by a BSD-style
|
| + * license that can be found in the LICENSE file.
|
| + */
|
| +
|
| +// TODO(sorvell): this ensures Polymer is an object and not a function
|
| +// Platform is currently defining it as a function to allow for async loading
|
| +// of polymer; once we refine the loading process this likely goes away.
|
| +if (typeof window.Polymer === 'function') {
|
| + Polymer = {};
|
| +}
|
| +
|
| +
|
| +/*
|
| + * Copyright 2013 The Polymer Authors. All rights reserved.
|
| + * Use of this source code is governed by a BSD-style
|
| + * license that can be found in the LICENSE file.
|
| + */
|
| +(function(scope) {
|
| +
|
| + // copy own properties from 'api' to 'prototype, with name hinting for 'super'
|
| + function extend(prototype, api) {
|
| + if (prototype && api) {
|
| + // use only own properties of 'api'
|
| + Object.getOwnPropertyNames(api).forEach(function(n) {
|
| + // acquire property descriptor
|
| + var pd = Object.getOwnPropertyDescriptor(api, n);
|
| + if (pd) {
|
| + // clone property via descriptor
|
| + Object.defineProperty(prototype, n, pd);
|
| + // cache name-of-method for 'super' engine
|
| + if (typeof pd.value == 'function') {
|
| + // hint the 'super' engine
|
| + pd.value.nom = n;
|
| + }
|
| + }
|
| + });
|
| + }
|
| + return prototype;
|
| + }
|
| +
|
| + // exports
|
| +
|
| + scope.extend = extend;
|
| +
|
| +})(Polymer);
|
| +
|
| +/*
|
| + * Copyright 2013 The Polymer Authors. All rights reserved.
|
| + * Use of this source code is governed by a BSD-style
|
| + * license that can be found in the LICENSE file.
|
| + */
|
| +
|
| +(function(scope) {
|
| +
|
| + // usage
|
| +
|
| + // invoke cb.call(this) in 100ms, unless the job is re-registered,
|
| + // which resets the timer
|
| + //
|
| + // this.myJob = this.job(this.myJob, cb, 100)
|
| + //
|
| + // returns a job handle which can be used to re-register a job
|
| +
|
| + var Job = function(inContext) {
|
| + this.context = inContext;
|
| + this.boundComplete = this.complete.bind(this)
|
| + };
|
| + Job.prototype = {
|
| + go: function(callback, wait) {
|
| + this.callback = callback;
|
| + var h;
|
| + if (!wait) {
|
| + h = requestAnimationFrame(this.boundComplete);
|
| + this.handle = function() {
|
| + cancelAnimationFrame(h);
|
| + }
|
| + } else {
|
| + h = setTimeout(this.boundComplete, wait);
|
| + this.handle = function() {
|
| + clearTimeout(h);
|
| + }
|
| + }
|
| + },
|
| + stop: function() {
|
| + if (this.handle) {
|
| + this.handle();
|
| + this.handle = null;
|
| + }
|
| + },
|
| + complete: function() {
|
| + if (this.handle) {
|
| + this.stop();
|
| + this.callback.call(this.context);
|
| + }
|
| + }
|
| + };
|
| +
|
| + function job(job, callback, wait) {
|
| + if (job) {
|
| + job.stop();
|
| + } else {
|
| + job = new Job(this);
|
| + }
|
| + job.go(callback, wait);
|
| + return job;
|
| + }
|
| +
|
| + // exports
|
| +
|
| + scope.job = job;
|
| +
|
| +})(Polymer);
|
| +
|
| +/*
|
| + * Copyright 2013 The Polymer Authors. All rights reserved.
|
| + * Use of this source code is governed by a BSD-style
|
| + * license that can be found in the LICENSE file.
|
| + */
|
| +(function(scope) {
|
| +
|
| + var registry = {};
|
| +
|
| + HTMLElement.register = function(tag, prototype) {
|
| + registry[tag] = prototype;
|
| + }
|
| +
|
| + // get prototype mapped to node <tag>
|
| + HTMLElement.getPrototypeForTag = function(tag) {
|
| + var prototype = !tag ? HTMLElement.prototype : registry[tag];
|
| + // TODO(sjmiles): creating <tag> is likely to have wasteful side-effects
|
| + return prototype || Object.getPrototypeOf(document.createElement(tag));
|
| + };
|
| +
|
| + // we have to flag propagation stoppage for the event dispatcher
|
| + var originalStopPropagation = Event.prototype.stopPropagation;
|
| + Event.prototype.stopPropagation = function() {
|
| + this.cancelBubble = true;
|
| + originalStopPropagation.apply(this, arguments);
|
| + };
|
| +
|
| + // TODO(sorvell): remove when we're sure imports does not need
|
| + // to load stylesheets
|
| + /*
|
| + HTMLImports.importer.preloadSelectors +=
|
| + ', polymer-element link[rel=stylesheet]';
|
| + */
|
| +})(Polymer);
|
| +
|
| +/*
|
| + * Copyright 2013 The Polymer Authors. All rights reserved.
|
| + * Use of this source code is governed by a BSD-style
|
| + * license that can be found in the LICENSE file.
|
| + */
|
| + (function(scope) {
|
| + // super
|
| +
|
| + // `arrayOfArgs` is an optional array of args like one might pass
|
| + // to `Function.apply`
|
| +
|
| + // TODO(sjmiles):
|
| + // $super must be installed on an instance or prototype chain
|
| + // as `super`, and invoked via `this`, e.g.
|
| + // `this.super();`
|
| +
|
| + // will not work if function objects are not unique, for example,
|
| + // when using mixins.
|
| + // The memoization strategy assumes each function exists on only one
|
| + // prototype chain i.e. we use the function object for memoizing)
|
| + // perhaps we can bookkeep on the prototype itself instead
|
| + function $super(arrayOfArgs) {
|
| + // since we are thunking a method call, performance is important here:
|
| + // memoize all lookups, once memoized the fast path calls no other
|
| + // functions
|
| + //
|
| + // find the caller (cannot be `strict` because of 'caller')
|
| + var caller = $super.caller;
|
| + // memoized 'name of method'
|
| + var nom = caller.nom;
|
| + // memoized next implementation prototype
|
| + var _super = caller._super;
|
| + if (!_super) {
|
| + if (!nom) {
|
| + nom = caller.nom = nameInThis.call(this, caller);
|
| + }
|
| + if (!nom) {
|
| + console.warn('called super() on a method not installed declaratively (has no .nom property)');
|
| + }
|
| + // super prototype is either cached or we have to find it
|
| + // by searching __proto__ (at the 'top')
|
| + _super = memoizeSuper(caller, nom, getPrototypeOf(this));
|
| + }
|
| + if (!_super) {
|
| + // if _super is falsey, there is no super implementation
|
| + //console.warn('called $super(' + nom + ') where there is no super implementation');
|
| + } else {
|
| + // our super function
|
| + var fn = _super[nom];
|
| + // memoize information so 'fn' can call 'super'
|
| + if (!fn._super) {
|
| + memoizeSuper(fn, nom, _super);
|
| + }
|
| + // invoke the inherited method
|
| + // if 'fn' is not function valued, this will throw
|
| + return fn.apply(this, arrayOfArgs || []);
|
| + }
|
| + }
|
| +
|
| + function nextSuper(proto, name, caller) {
|
| + // look for an inherited prototype that implements name
|
| + while (proto) {
|
| + if ((proto[name] !== caller) && proto[name]) {
|
| + return proto;
|
| + }
|
| + proto = getPrototypeOf(proto);
|
| + }
|
| + }
|
| +
|
| + function memoizeSuper(method, name, proto) {
|
| + // find and cache next prototype containing `name`
|
| + // we need the prototype so we can do another lookup
|
| + // from here
|
| + method._super = nextSuper(proto, name, method);
|
| + if (method._super) {
|
| + // _super is a prototype, the actual method is _super[name]
|
| + // tag super method with it's name for further lookups
|
| + method._super[name].nom = name;
|
| + }
|
| + return method._super;
|
| + }
|
| +
|
| + function nameInThis(value) {
|
| + var p = this.__proto__;
|
| + while (p && p !== HTMLElement.prototype) {
|
| + // TODO(sjmiles): getOwnPropertyNames is absurdly expensive
|
| + var n$ = Object.getOwnPropertyNames(p);
|
| + for (var i=0, l=n$.length, n; i<l && (n=n$[i]); i++) {
|
| + var d = Object.getOwnPropertyDescriptor(p, n);
|
| + if (typeof d.value === 'function' && d.value === value) {
|
| + return n;
|
| + }
|
| + }
|
| + p = p.__proto__;
|
| + }
|
| + }
|
| +
|
| + // NOTE: In some platforms (IE10) the prototype chain is faked via
|
| + // __proto__. Therefore, always get prototype via __proto__ instead of
|
| + // the more standard Object.getPrototypeOf.
|
| + function getPrototypeOf(prototype) {
|
| + return prototype.__proto__;
|
| + }
|
| +
|
| + // utility function to precompute name tags for functions
|
| + // in a (unchained) prototype
|
| + function hintSuper(prototype) {
|
| + // tag functions with their prototype name to optimize
|
| + // super call invocations
|
| + for (var n in prototype) {
|
| + var pd = Object.getOwnPropertyDescriptor(prototype, n);
|
| + if (pd && typeof pd.value === 'function') {
|
| + pd.value.nom = n;
|
| + }
|
| + }
|
| + }
|
| +
|
| + // exports
|
| +
|
| + scope.super = $super;
|
| +
|
| +})(Polymer);
|
| +
|
| +/*
|
| + * Copyright 2013 The Polymer Authors. All rights reserved.
|
| + * Use of this source code is governed by a BSD-style
|
| + * license that can be found in the LICENSE file.
|
| + */
|
| +
|
| +(function(scope) {
|
| +
|
| + var typeHandlers = {
|
| + string: function(value) {
|
| + return value;
|
| + },
|
| + date: function(value) {
|
| + return new Date(Date.parse(value) || Date.now());
|
| + },
|
| + boolean: function(value) {
|
| + if (value === '') {
|
| + return true;
|
| + }
|
| + return value === 'false' ? false : !!value;
|
| + },
|
| + number: function(value) {
|
| + var n = parseFloat(value);
|
| + // hex values like "0xFFFF" parseFloat as 0
|
| + if (n === 0) {
|
| + n = parseInt(value);
|
| + }
|
| + return isNaN(n) ? value : n;
|
| + // this code disabled because encoded values (like "0xFFFF")
|
| + // do not round trip to their original format
|
| + //return (String(floatVal) === value) ? floatVal : value;
|
| + },
|
| + object: function(value, currentValue) {
|
| + if (currentValue === null) {
|
| + return value;
|
| + }
|
| + try {
|
| + // If the string is an object, we can parse is with the JSON library.
|
| + // include convenience replace for single-quotes. If the author omits
|
| + // quotes altogether, parse will fail.
|
| + return JSON.parse(value.replace(/'/g, '"'));
|
| + } catch(e) {
|
| + // The object isn't valid JSON, return the raw value
|
| + return value;
|
| + }
|
| + },
|
| + // avoid deserialization of functions
|
| + 'function': function(value, currentValue) {
|
| + return currentValue;
|
| + }
|
| + };
|
| +
|
| + function deserializeValue(value, currentValue) {
|
| + // attempt to infer type from default value
|
| + var inferredType = typeof currentValue;
|
| + // invent 'date' type value for Date
|
| + if (currentValue instanceof Date) {
|
| + inferredType = 'date';
|
| + }
|
| + // delegate deserialization via type string
|
| + return typeHandlers[inferredType](value, currentValue);
|
| + }
|
| +
|
| + // exports
|
| +
|
| + scope.deserializeValue = deserializeValue;
|
| +
|
| +})(Polymer);
|
| +
|
| +/*
|
| + * Copyright 2013 The Polymer Authors. All rights reserved.
|
| + * Use of this source code is governed by a BSD-style
|
| + * license that can be found in the LICENSE file.
|
| + */
|
| +(function(scope) {
|
| +
|
| + // imports
|
| +
|
| + var extend = scope.extend;
|
| +
|
| + // module
|
| +
|
| + var api = {};
|
| +
|
| + api.declaration = {};
|
| + api.instance = {};
|
| +
|
| + api.publish = function(apis, prototype) {
|
| + for (var n in apis) {
|
| + extend(prototype, apis[n]);
|
| + }
|
| + }
|
| +
|
| + // exports
|
| +
|
| + scope.api = api;
|
| +
|
| +})(Polymer);
|
| +
|
| +/*
|
| + * Copyright 2013 The Polymer Authors. All rights reserved.
|
| + * Use of this source code is governed by a BSD-style
|
| + * license that can be found in the LICENSE file.
|
| + */
|
| +(function(scope) {
|
| +
|
| + var utils = {
|
| + /**
|
| + * Invokes a function asynchronously. The context of the callback
|
| + * function is bound to 'this' automatically.
|
| + * @method async
|
| + * @param {Function|String} method
|
| + * @param {any|Array} args
|
| + * @param {number} timeout
|
| + */
|
| + async: function(method, args, timeout) {
|
| + // when polyfilling Object.observe, ensure changes
|
| + // propagate before executing the async method
|
| + Platform.flush();
|
| + // second argument to `apply` must be an array
|
| + args = (args && args.length) ? args : [args];
|
| + // function to invoke
|
| + var fn = function() {
|
| + (this[method] || method).apply(this, args);
|
| + }.bind(this);
|
| + // execute `fn` sooner or later
|
| + var handle = timeout ? setTimeout(fn, timeout) :
|
| + requestAnimationFrame(fn);
|
| + // NOTE: switch on inverting handle to determine which time is used.
|
| + return timeout ? handle : 1 / handle;
|
| + },
|
| + cancelAsync: function(handle) {
|
| + if (handle < 1) {
|
| + cancelAnimationFrame(Math.round(1 / handle));
|
| + } else {
|
| + clearTimeout(handle);
|
| + }
|
| + },
|
| + /**
|
| + * Fire an event.
|
| + * @method fire
|
| + * @returns {Object} event
|
| + * @param {string} type An event name.
|
| + * @param {any} detail
|
| + * @param {Node} onNode Target node.
|
| + */
|
| + fire: function(type, detail, onNode, bubbles, cancelable) {
|
| + var node = onNode || this;
|
| + var detail = detail || {};
|
| + var event = new CustomEvent(type, {
|
| + bubbles: (bubbles !== undefined ? bubbles : true),
|
| + cancelable: (cancelable !== undefined ? cancelable : true),
|
| + detail: detail
|
| + });
|
| + node.dispatchEvent(event);
|
| + return event;
|
| + },
|
| + /**
|
| + * Fire an event asynchronously.
|
| + * @method asyncFire
|
| + * @param {string} type An event name.
|
| + * @param detail
|
| + * @param {Node} toNode Target node.
|
| + */
|
| + asyncFire: function(/*inType, inDetail*/) {
|
| + this.async("fire", arguments);
|
| + },
|
| + /**
|
| + * Remove class from old, add class to anew, if they exist
|
| + * @param classFollows
|
| + * @param anew A node.
|
| + * @param old A node
|
| + * @param className
|
| + */
|
| + classFollows: function(anew, old, className) {
|
| + if (old) {
|
| + old.classList.remove(className);
|
| + }
|
| + if (anew) {
|
| + anew.classList.add(className);
|
| + }
|
| + }
|
| + };
|
| +
|
| + // no-operation function for handy stubs
|
| + var nop = function() {};
|
| +
|
| + // null-object for handy stubs
|
| + var nob = {};
|
| +
|
| + // deprecated
|
| +
|
| + utils.asyncMethod = utils.async;
|
| +
|
| + // exports
|
| +
|
| + scope.api.instance.utils = utils;
|
| + scope.nop = nop;
|
| + scope.nob = nob;
|
| +
|
| +})(Polymer);
|
| +
|
| +/*
|
| + * Copyright 2013 The Polymer Authors. All rights reserved.
|
| + * Use of this source code is governed by a BSD-style
|
| + * license that can be found in the LICENSE file.
|
| + */
|
| +
|
| +(function(scope) {
|
| +
|
| + // imports
|
| +
|
| + var log = window.logFlags || {};
|
| + var EVENT_PREFIX = 'on-';
|
| +
|
| + // instance events api
|
| + var events = {
|
| + // read-only
|
| + EVENT_PREFIX: EVENT_PREFIX,
|
| + // event listeners on host
|
| + addHostListeners: function() {
|
| + var events = this.eventDelegates;
|
| + log.events && (Object.keys(events).length > 0) && console.log('[%s] addHostListeners:', this.localName, events);
|
| + // NOTE: host events look like bindings but really are not;
|
| + // (1) we don't want the attribute to be set and (2) we want to support
|
| + // multiple event listeners ('host' and 'instance') and Node.bind
|
| + // by default supports 1 thing being bound.
|
| + // We do, however, leverage the event hookup code in PolymerExpressions
|
| + // so that we have a common code path for handling declarative events.
|
| + var self = this, bindable, eventName;
|
| + for (var n in events) {
|
| + eventName = EVENT_PREFIX + n;
|
| + bindable = PolymerExpressions.prepareEventBinding(
|
| + Path.get(events[n]),
|
| + eventName,
|
| + {
|
| + resolveEventHandler: function(model, path, node) {
|
| + var fn = path.getValueFrom(self);
|
| + if (fn) {
|
| + return fn.bind(self);
|
| + }
|
| + }
|
| + }
|
| + );
|
| + bindable(this, this, false);
|
| + }
|
| + },
|
| + // call 'method' or function method on 'obj' with 'args', if the method exists
|
| + dispatchMethod: function(obj, method, args) {
|
| + if (obj) {
|
| + log.events && console.group('[%s] dispatch [%s]', obj.localName, method);
|
| + var fn = typeof method === 'function' ? method : obj[method];
|
| + if (fn) {
|
| + fn[args ? 'apply' : 'call'](obj, args);
|
| + }
|
| + log.events && console.groupEnd();
|
| + Platform.flush();
|
| + }
|
| + }
|
| + };
|
| +
|
| + // exports
|
| +
|
| + scope.api.instance.events = events;
|
| +
|
| +})(Polymer);
|
| +
|
| +/*
|
| + * Copyright 2013 The Polymer Authors. All rights reserved.
|
| + * Use of this source code is governed by a BSD-style
|
| + * license that can be found in the LICENSE file.
|
| + */
|
| +(function(scope) {
|
| +
|
| + // instance api for attributes
|
| +
|
| + var attributes = {
|
| + copyInstanceAttributes: function () {
|
| + var a$ = this._instanceAttributes;
|
| + for (var k in a$) {
|
| + if (!this.hasAttribute(k)) {
|
| + this.setAttribute(k, a$[k]);
|
| + }
|
| + }
|
| + },
|
| + // for each attribute on this, deserialize value to property as needed
|
| + takeAttributes: function() {
|
| + // if we have no publish lookup table, we have no attributes to take
|
| + // TODO(sjmiles): ad hoc
|
| + if (this._publishLC) {
|
| + for (var i=0, a$=this.attributes, l=a$.length, a; (a=a$[i]) && i<l; i++) {
|
| + this.attributeToProperty(a.name, a.value);
|
| + }
|
| + }
|
| + },
|
| + // if attribute 'name' is mapped to a property, deserialize
|
| + // 'value' into that property
|
| + attributeToProperty: function(name, value) {
|
| + // try to match this attribute to a property (attributes are
|
| + // all lower-case, so this is case-insensitive search)
|
| + var name = this.propertyForAttribute(name);
|
| + if (name) {
|
| + // filter out 'mustached' values, these are to be
|
| + // replaced with bound-data and are not yet values
|
| + // themselves
|
| + if (value && value.search(scope.bindPattern) >= 0) {
|
| + return;
|
| + }
|
| + // get original value
|
| + var currentValue = this[name];
|
| + // deserialize Boolean or Number values from attribute
|
| + var value = this.deserializeValue(value, currentValue);
|
| + // only act if the value has changed
|
| + if (value !== currentValue) {
|
| + // install new value (has side-effects)
|
| + this[name] = value;
|
| + }
|
| + }
|
| + },
|
| + // return the published property matching name, or undefined
|
| + propertyForAttribute: function(name) {
|
| + var match = this._publishLC && this._publishLC[name];
|
| + //console.log('propertyForAttribute:', name, 'matches', match);
|
| + return match;
|
| + },
|
| + // convert representation of 'stringValue' based on type of 'currentValue'
|
| + deserializeValue: function(stringValue, currentValue) {
|
| + return scope.deserializeValue(stringValue, currentValue);
|
| + },
|
| + serializeValue: function(value, inferredType) {
|
| + if (inferredType === 'boolean') {
|
| + return value ? '' : undefined;
|
| + } else if (inferredType !== 'object' && inferredType !== 'function'
|
| + && value !== undefined) {
|
| + return value;
|
| + }
|
| + },
|
| + reflectPropertyToAttribute: function(name) {
|
| + var inferredType = typeof this[name];
|
| + // try to intelligently serialize property value
|
| + var serializedValue = this.serializeValue(this[name], inferredType);
|
| + // boolean properties must reflect as boolean attributes
|
| + if (serializedValue !== undefined) {
|
| + this.setAttribute(name, serializedValue);
|
| + // TODO(sorvell): we should remove attr for all properties
|
| + // that have undefined serialization; however, we will need to
|
| + // refine the attr reflection system to achieve this; pica, for example,
|
| + // relies on having inferredType object properties not removed as
|
| + // attrs.
|
| + } else if (inferredType === 'boolean') {
|
| + this.removeAttribute(name);
|
| + }
|
| + }
|
| + };
|
| +
|
| + // exports
|
| +
|
| + scope.api.instance.attributes = attributes;
|
| +
|
| +})(Polymer);
|
| +
|
| +/*
|
| + * Copyright 2013 The Polymer Authors. All rights reserved.
|
| + * Use of this source code is governed by a BSD-style
|
| + * license that can be found in the LICENSE file.
|
| + */
|
| +(function(scope) {
|
| +
|
| + // imports
|
| +
|
| + var log = window.logFlags || {};
|
| +
|
| + // magic words
|
| +
|
| + var OBSERVE_SUFFIX = 'Changed';
|
| +
|
| + // element api
|
| +
|
| + var empty = [];
|
| +
|
| + var properties = {
|
| + observeProperties: function() {
|
| + var n$ = this._observeNames, pn$ = this._publishNames;
|
| + if ((n$ && n$.length) || (pn$ && pn$.length)) {
|
| + var self = this;
|
| + var o = this._propertyObserver = new CompoundObserver();
|
| + for (var i=0, l=n$.length, n; (i<l) && (n=n$[i]); i++) {
|
| + o.addPath(this, n);
|
| + // observer array properties
|
| + var pd = Object.getOwnPropertyDescriptor(this.__proto__, n);
|
| + if (pd && pd.value) {
|
| + this.observeArrayValue(n, pd.value, null);
|
| + }
|
| + }
|
| + for (var i=0, l=pn$.length, n; (i<l) && (n=pn$[i]); i++) {
|
| + if (!this.observe || (this.observe[n] === undefined)) {
|
| + o.addPath(this, n);
|
| + }
|
| + }
|
| + o.open(this.notifyPropertyChanges, this);
|
| + }
|
| + },
|
| + notifyPropertyChanges: function(newValues, oldValues, paths) {
|
| + var name, method, called = {};
|
| + for (var i in oldValues) {
|
| + // note: paths is of form [object, path, object, path]
|
| + name = paths[2 * i + 1];
|
| + if (this.publish[name] !== undefined) {
|
| + this.reflectPropertyToAttribute(name);
|
| + }
|
| + method = this.observe[name];
|
| + if (method) {
|
| + this.observeArrayValue(name, newValues[i], oldValues[i]);
|
| + if (!called[method]) {
|
| + called[method] = true;
|
| + // observes the value if it is an array
|
| + this.invokeMethod(method, [oldValues[i], newValues[i], arguments]);
|
| + }
|
| + }
|
| + }
|
| + },
|
| + observeArrayValue: function(name, value, old) {
|
| + // we only care if there are registered side-effects
|
| + var callbackName = this.observe[name];
|
| + if (callbackName) {
|
| + // if we are observing the previous value, stop
|
| + if (Array.isArray(old)) {
|
| + log.observe && console.log('[%s] observeArrayValue: unregister observer [%s]', this.localName, name);
|
| + this.unregisterObserver(name + '__array');
|
| + }
|
| + // if the new value is an array, being observing it
|
| + if (Array.isArray(value)) {
|
| + log.observe && console.log('[%s] observeArrayValue: register observer [%s]', this.localName, name, value);
|
| + var observer = new ArrayObserver(value);
|
| + observer.open(function(value, old) {
|
| + this.invokeMethod(callbackName, [old]);
|
| + }, this);
|
| + this.registerObserver(name + '__array', observer);
|
| + }
|
| + }
|
| + },
|
| + bindProperty: function(property, observable) {
|
| + // apply Polymer two-way reference binding
|
| + return bindProperties(this, property, observable);
|
| + },
|
| + unbindAllProperties: function() {
|
| + if (this._propertyObserver) {
|
| + this._propertyObserver.close();
|
| + }
|
| + this.unregisterObservers();
|
| + },
|
| + unbindProperty: function(name) {
|
| + return this.unregisterObserver(name);
|
| + },
|
| + invokeMethod: function(method, args) {
|
| + var fn = this[method] || method;
|
| + if (typeof fn === 'function') {
|
| + fn.apply(this, args);
|
| + }
|
| + },
|
| + // bookkeeping observers for memory management
|
| + registerObserver: function(name, observer) {
|
| + var o$ = this._observers || (this._observers = {});
|
| + o$[name] = observer;
|
| + },
|
| + unregisterObserver: function(name) {
|
| + var o$ = this._observers;
|
| + if (o$ && o$[name]) {
|
| + o$[name].close();
|
| + o$[name] = null;
|
| + return true;
|
| + }
|
| + },
|
| + unregisterObservers: function() {
|
| + if (this._observers) {
|
| + var keys=Object.keys(this._observers);
|
| + for (var i=0, l=keys.length, k, o; (i < l) && (k=keys[i]); i++) {
|
| + o = this._observers[k];
|
| + o.close();
|
| + }
|
| + this._observers = {};
|
| + }
|
| + }
|
| + };
|
| +
|
| + // property binding
|
| + // bind a property in A to a path in B by converting A[property] to a
|
| + // getter/setter pair that accesses B[...path...]
|
| + function bindProperties(inA, inProperty, observable) {
|
| + log.bind && console.log(LOG_BIND_PROPS, inB.localName || 'object', inPath, inA.localName, inProperty);
|
| + // capture A's value if B's value is null or undefined,
|
| + // otherwise use B's value
|
| + // TODO(sorvell): need to review, can do with ObserverTransform
|
| + var v = observable.discardChanges();
|
| + if (v === null || v === undefined) {
|
| + observable.setValue(inA[inProperty]);
|
| + }
|
| + return Observer.defineComputedProperty(inA, inProperty, observable);
|
| + }
|
| +
|
| + // logging
|
| + var LOG_OBSERVE = '[%s] watching [%s]';
|
| + var LOG_OBSERVED = '[%s#%s] watch: [%s] now [%s] was [%s]';
|
| + var LOG_CHANGED = '[%s#%s] propertyChanged: [%s] now [%s] was [%s]';
|
| + var LOG_BIND_PROPS = "[%s]: bindProperties: [%s] to [%s].[%s]";
|
| +
|
| + // exports
|
| +
|
| + scope.api.instance.properties = properties;
|
| +
|
| +})(Polymer);
|
| +
|
| +/*
|
| + * Copyright 2013 The Polymer Authors. All rights reserved.
|
| + * Use of this source code is governed by a BSD-style
|
| + * license that can be found in the LICENSE file.
|
| + */
|
| +(function(scope) {
|
| +
|
| + // imports
|
| +
|
| + var log = window.logFlags || 0;
|
| + var events = scope.api.instance.events;
|
| +
|
| + var syntax = new PolymerExpressions();
|
| + syntax.resolveEventHandler = function(model, path, node) {
|
| + var ctlr = findEventController(node);
|
| + if (ctlr) {
|
| + var fn = path.getValueFrom(ctlr);
|
| + if (fn) {
|
| + return fn.bind(ctlr);
|
| + }
|
| + }
|
| + }
|
| +
|
| + // An event controller is the host element for the shadowRoot in which
|
| + // the node exists, or the first ancestor with a 'lightDomController'
|
| + // property.
|
| + function findEventController(node) {
|
| + while (node.parentNode) {
|
| + if (node.lightDomController) {
|
| + return node;
|
| + }
|
| + node = node.parentNode;
|
| + }
|
| + return node.host;
|
| + };
|
| +
|
| + // element api supporting mdv
|
| +
|
| + var mdv = {
|
| + syntax: syntax,
|
| + instanceTemplate: function(template) {
|
| + return template.createInstance(this, this.syntax);
|
| + },
|
| + bind: function(name, observable, oneTime) {
|
| + // note: binding is a prepare signal. This allows us to be sure that any
|
| + // property changes that occur as a result of binding will be observed.
|
| + if (!this._elementPrepared) {
|
| + this.prepareElement();
|
| + }
|
| + var property = this.propertyForAttribute(name);
|
| + if (!property) {
|
| + // TODO(sjmiles): this mixin method must use the special form
|
| + // of `super` installed by `mixinMethod` in declaration/prototype.js
|
| + return this.mixinSuper(arguments);
|
| + } else {
|
| + // clean out the closets
|
| + this.unbind(name);
|
| + // use n-way Polymer binding
|
| + var observer = this.bindProperty(property, observable);
|
| + // stick path on observer so it's available via this.bindings
|
| + observer.path = observable.path_;
|
| + // reflect bound property to attribute when binding
|
| + // to ensure binding is not left on attribute if property
|
| + // does not update due to not changing.
|
| + this.reflectPropertyToAttribute(property);
|
| + return this.bindings[name] = observer;
|
| + }
|
| + },
|
| + asyncUnbindAll: function() {
|
| + if (!this._unbound) {
|
| + log.unbind && console.log('[%s] asyncUnbindAll', this.localName);
|
| + this._unbindAllJob = this.job(this._unbindAllJob, this.unbindAll, 0);
|
| + }
|
| + },
|
| + unbindAll: function() {
|
| + if (!this._unbound) {
|
| + this.unbindAllProperties();
|
| + this.super();
|
| + // unbind shadowRoot
|
| + var root = this.shadowRoot;
|
| + while (root) {
|
| + unbindNodeTree(root);
|
| + root = root.olderShadowRoot;
|
| + }
|
| + this._unbound = true;
|
| + }
|
| + },
|
| + cancelUnbindAll: function(preventCascade) {
|
| + if (this._unbound) {
|
| + log.unbind && console.warn('[%s] already unbound, cannot cancel unbindAll', this.localName);
|
| + return;
|
| + }
|
| + log.unbind && console.log('[%s] cancelUnbindAll', this.localName);
|
| + if (this._unbindAllJob) {
|
| + this._unbindAllJob = this._unbindAllJob.stop();
|
| + }
|
| + // cancel unbinding our shadow tree iff we're not in the process of
|
| + // cascading our tree (as we do, for example, when the element is inserted).
|
| + if (!preventCascade) {
|
| + forNodeTree(this.shadowRoot, function(n) {
|
| + if (n.cancelUnbindAll) {
|
| + n.cancelUnbindAll();
|
| + }
|
| + });
|
| + }
|
| + }
|
| + };
|
| +
|
| + function unbindNodeTree(node) {
|
| + forNodeTree(node, _nodeUnbindAll);
|
| + }
|
| +
|
| + function _nodeUnbindAll(node) {
|
| + node.unbindAll();
|
| + }
|
| +
|
| + function forNodeTree(node, callback) {
|
| + if (node) {
|
| + callback(node);
|
| + for (var child = node.firstChild; child; child = child.nextSibling) {
|
| + forNodeTree(child, callback);
|
| + }
|
| + }
|
| + }
|
| +
|
| + var mustachePattern = /\{\{([^{}]*)}}/;
|
| +
|
| + // exports
|
| +
|
| + scope.bindPattern = mustachePattern;
|
| + scope.api.instance.mdv = mdv;
|
| +
|
| +})(Polymer);
|
| +
|
| +/*
|
| + * Copyright 2013 The Polymer Authors. All rights reserved.
|
| + * Use of this source code is governed by a BSD-style
|
| + * license that can be found in the LICENSE file.
|
| + */
|
| +(function(scope) {
|
| + var preparingElements = 0;
|
| +
|
| + var base = {
|
| + PolymerBase: true,
|
| + job: Polymer.job,
|
| + super: Polymer.super,
|
| + // user entry point for element has had its createdCallback called
|
| + created: function() {
|
| + },
|
| + // user entry point for element has shadowRoot and is ready for
|
| + // api interaction
|
| + ready: function() {
|
| + },
|
| + createdCallback: function() {
|
| + this.created();
|
| + if (this.ownerDocument.defaultView || this.alwaysPrepare ||
|
| + preparingElements > 0) {
|
| + this.prepareElement();
|
| + }
|
| + },
|
| + // system entry point, do not override
|
| + prepareElement: function() {
|
| + this._elementPrepared = true;
|
| + // install shadowRoots storage
|
| + this.shadowRoots = {};
|
| + // install property observers
|
| + this.observeProperties();
|
| + // install boilerplate attributes
|
| + this.copyInstanceAttributes();
|
| + // process input attributes
|
| + this.takeAttributes();
|
| + // add event listeners
|
| + this.addHostListeners();
|
| + // guarantees that while preparing, any
|
| + // sub-elements are also prepared
|
| + preparingElements++;
|
| + // process declarative resources
|
| + this.parseDeclarations(this.__proto__);
|
| + // decrement semaphore
|
| + preparingElements--;
|
| + // TODO(sorvell): CE polyfill uses unresolved attribute to simulate
|
| + // :unresolved; remove this attribute to be compatible with native
|
| + // CE.
|
| + this.removeAttribute('unresolved');
|
| + // user entry point
|
| + this.ready();
|
| + },
|
| + attachedCallback: function() {
|
| + if (!this._elementPrepared) {
|
| + this.prepareElement();
|
| + }
|
| + this.cancelUnbindAll(true);
|
| + // invoke user action
|
| + if (this.attached) {
|
| + this.attached();
|
| + }
|
| + // TODO(sorvell): bc
|
| + if (this.enteredView) {
|
| + this.enteredView();
|
| + }
|
| + // NOTE: domReady can be used to access elements in dom (descendants,
|
| + // ancestors, siblings) such that the developer is enured to upgrade
|
| + // ordering. If the element definitions have loaded, domReady
|
| + // can be used to access upgraded elements.
|
| + if (!this.hasBeenAttached) {
|
| + this.hasBeenAttached = true;
|
| + if (this.domReady) {
|
| + this.async('domReady');
|
| + }
|
| + }
|
| + },
|
| + detachedCallback: function() {
|
| + if (!this.preventDispose) {
|
| + this.asyncUnbindAll();
|
| + }
|
| + // invoke user action
|
| + if (this.detached) {
|
| + this.detached();
|
| + }
|
| + // TODO(sorvell): bc
|
| + if (this.leftView) {
|
| + this.leftView();
|
| + }
|
| + },
|
| + // TODO(sorvell): bc
|
| + enteredViewCallback: function() {
|
| + this.attachedCallback();
|
| + },
|
| + // TODO(sorvell): bc
|
| + leftViewCallback: function() {
|
| + this.detachedCallback();
|
| + },
|
| + // TODO(sorvell): bc
|
| + enteredDocumentCallback: function() {
|
| + this.attachedCallback();
|
| + },
|
| + // TODO(sorvell): bc
|
| + leftDocumentCallback: function() {
|
| + this.detachedCallback();
|
| + },
|
| + // recursive ancestral <element> initialization, oldest first
|
| + parseDeclarations: function(p) {
|
| + if (p && p.element) {
|
| + this.parseDeclarations(p.__proto__);
|
| + p.parseDeclaration.call(this, p.element);
|
| + }
|
| + },
|
| + // parse input <element> as needed, override for custom behavior
|
| + parseDeclaration: function(elementElement) {
|
| + var template = this.fetchTemplate(elementElement);
|
| + if (template) {
|
| + var root = this.shadowFromTemplate(template);
|
| + this.shadowRoots[elementElement.name] = root;
|
| + }
|
| + },
|
| + // return a shadow-root template (if desired), override for custom behavior
|
| + fetchTemplate: function(elementElement) {
|
| + return elementElement.querySelector('template');
|
| + },
|
| + // utility function that creates a shadow root from a <template>
|
| + shadowFromTemplate: function(template) {
|
| + if (template) {
|
| + // make a shadow root
|
| + var root = this.createShadowRoot();
|
| + // migrate flag(s)
|
| + root.resetStyleInheritance = this.resetStyleInheritance;
|
| + // stamp template
|
| + // which includes parsing and applying MDV bindings before being
|
| + // inserted (to avoid {{}} in attribute values)
|
| + // e.g. to prevent <img src="images/{{icon}}"> from generating a 404.
|
| + var dom = this.instanceTemplate(template);
|
| + // append to shadow dom
|
| + root.appendChild(dom);
|
| + // perform post-construction initialization tasks on shadow root
|
| + this.shadowRootReady(root, template);
|
| + // return the created shadow root
|
| + return root;
|
| + }
|
| + },
|
| + // utility function that stamps a <template> into light-dom
|
| + lightFromTemplate: function(template) {
|
| + if (template) {
|
| + // TODO(sorvell): mark this element as a lightDOMController so that
|
| + // event listeners on bound nodes inside it will be called on it.
|
| + // Note, the expectation here is that events on all descendants
|
| + // should be handled by this element.
|
| + this.lightDomController = true;
|
| + // stamp template
|
| + // which includes parsing and applying MDV bindings before being
|
| + // inserted (to avoid {{}} in attribute values)
|
| + // e.g. to prevent <img src="images/{{icon}}"> from generating a 404.
|
| + var dom = this.instanceTemplate(template);
|
| + // append to shadow dom
|
| + this.appendChild(dom);
|
| + // perform post-construction initialization tasks on ahem, light root
|
| + this.shadowRootReady(this, template);
|
| + // return the created shadow root
|
| + return dom;
|
| + }
|
| + },
|
| + shadowRootReady: function(root, template) {
|
| + // locate nodes with id and store references to them in this.$ hash
|
| + this.marshalNodeReferences(root);
|
| + // set up pointer gestures
|
| + PointerGestures.register(root);
|
| + },
|
| + // locate nodes with id and store references to them in this.$ hash
|
| + marshalNodeReferences: function(root) {
|
| + // establish $ instance variable
|
| + var $ = this.$ = this.$ || {};
|
| + // populate $ from nodes with ID from the LOCAL tree
|
| + if (root) {
|
| + var n$ = root.querySelectorAll("[id]");
|
| + for (var i=0, l=n$.length, n; (i<l) && (n=n$[i]); i++) {
|
| + $[n.id] = n;
|
| + };
|
| + }
|
| + },
|
| + attributeChangedCallback: function(name, oldValue) {
|
| + // TODO(sjmiles): adhoc filter
|
| + if (name !== 'class' && name !== 'style') {
|
| + this.attributeToProperty(name, this.getAttribute(name));
|
| + }
|
| + if (this.attributeChanged) {
|
| + this.attributeChanged.apply(this, arguments);
|
| + }
|
| + },
|
| + onMutation: function(node, listener) {
|
| + var observer = new MutationObserver(function(mutations) {
|
| + listener.call(this, observer, mutations);
|
| + observer.disconnect();
|
| + }.bind(this));
|
| + observer.observe(node, {childList: true, subtree: true});
|
| + }
|
| + };
|
| +
|
| + // true if object has own PolymerBase api
|
| + function isBase(object) {
|
| + return object.hasOwnProperty('PolymerBase')
|
| + }
|
| +
|
| + // name a base constructor for dev tools
|
| +
|
| + function PolymerBase() {};
|
| + PolymerBase.prototype = base;
|
| + base.constructor = PolymerBase;
|
| +
|
| + // exports
|
| +
|
| + scope.Base = PolymerBase;
|
| + scope.isBase = isBase;
|
| + scope.api.instance.base = base;
|
| +
|
| +})(Polymer);
|
| +
|
| +/*
|
| + * Copyright 2013 The Polymer Authors. All rights reserved.
|
| + * Use of this source code is governed by a BSD-style
|
| + * license that can be found in the LICENSE file.
|
| + */
|
| +(function(scope) {
|
| +
|
| + // imports
|
| +
|
| + var log = window.logFlags || {};
|
| +
|
| + // magic words
|
| +
|
| + var STYLE_SCOPE_ATTRIBUTE = 'element';
|
| + var STYLE_CONTROLLER_SCOPE = 'controller';
|
| +
|
| + var styles = {
|
| + STYLE_SCOPE_ATTRIBUTE: STYLE_SCOPE_ATTRIBUTE,
|
| + /**
|
| + * Installs external stylesheets and <style> elements with the attribute
|
| + * polymer-scope='controller' into the scope of element. This is intended
|
| + * to be a called during custom element construction. Note, this incurs a
|
| + * per instance cost and should be used sparingly.
|
| + *
|
| + * The need for this type of styling should go away when the shadowDOM spec
|
| + * addresses these issues:
|
| + *
|
| + * https://www.w3.org/Bugs/Public/show_bug.cgi?id=21391
|
| + * https://www.w3.org/Bugs/Public/show_bug.cgi?id=21390
|
| + * https://www.w3.org/Bugs/Public/show_bug.cgi?id=21389
|
| + *
|
| + * @param element The custom element instance into whose controller (parent)
|
| + * scope styles will be installed.
|
| + * @param elementElement The <element> containing controller styles.
|
| + */
|
| + // TODO(sorvell): remove when spec issues are addressed
|
| + installControllerStyles: function() {
|
| + // apply controller styles, but only if they are not yet applied
|
| + var scope = this.findStyleController();
|
| + if (scope && !this.scopeHasElementStyle(scope, STYLE_CONTROLLER_SCOPE)) {
|
| + // allow inherited controller styles
|
| + var proto = getPrototypeOf(this), cssText = '';
|
| + while (proto && proto.element) {
|
| + cssText += proto.element.cssTextForScope(STYLE_CONTROLLER_SCOPE);
|
| + proto = getPrototypeOf(proto);
|
| + }
|
| + if (cssText) {
|
| + var style = this.element.cssTextToScopeStyle(cssText,
|
| + STYLE_CONTROLLER_SCOPE);
|
| + // TODO(sorvell): for now these styles are not shimmed
|
| + // but we may need to shim them
|
| + Polymer.applyStyleToScope(style, scope);
|
| + }
|
| + }
|
| + },
|
| + findStyleController: function() {
|
| + if (window.ShadowDOMPolyfill) {
|
| + return wrap(document.head);
|
| + } else {
|
| + // find the shadow root that contains this element
|
| + var n = this;
|
| + while (n.parentNode) {
|
| + n = n.parentNode;
|
| + }
|
| + return n === document ? document.head : n;
|
| + }
|
| + },
|
| + scopeHasElementStyle: function(scope, descriptor) {
|
| + var rule = STYLE_SCOPE_ATTRIBUTE + '=' + this.localName + '-' + descriptor;
|
| + return scope.querySelector('style[' + rule + ']');
|
| + }
|
| + };
|
| +
|
| + // NOTE: use raw prototype traversal so that we ensure correct traversal
|
| + // on platforms where the protoype chain is simulated via __proto__ (IE10)
|
| + function getPrototypeOf(prototype) {
|
| + return prototype.__proto__;
|
| + }
|
| +
|
| + // exports
|
| +
|
| + scope.api.instance.styles = styles;
|
| +
|
| +})(Polymer);
|
| +
|
| +/*
|
| + * Copyright 2013 The Polymer Authors. All rights reserved.
|
| + * Use of this source code is governed by a BSD-style
|
| + * license that can be found in the LICENSE file.
|
| + */
|
| +(function(scope) {
|
| +
|
| + // imports
|
| +
|
| + var extend = scope.extend;
|
| + var api = scope.api;
|
| +
|
| + // imperative implementation: Polymer()
|
| +
|
| + // specify an 'own' prototype for tag `name`
|
| + function element(name, prototype) {
|
| + if (getRegisteredPrototype[name]) {
|
| + throw 'Already registered (Polymer) prototype for element ' + name;
|
| + }
|
| + // cache the prototype
|
| + registerPrototype(name, prototype);
|
| + // notify the registrar waiting for 'name', if any
|
| + notifyPrototype(name);
|
| + }
|
| +
|
| + // async prototype source
|
| +
|
| + function waitingForPrototype(name, client) {
|
| + waitPrototype[name] = client;
|
| + }
|
| +
|
| + var waitPrototype = {};
|
| +
|
| + function notifyPrototype(name) {
|
| + if (waitPrototype[name]) {
|
| + waitPrototype[name].registerWhenReady();
|
| + delete waitPrototype[name];
|
| + }
|
| + }
|
| +
|
| + // utility and bookkeeping
|
| +
|
| + // maps tag names to prototypes, as registered with
|
| + // Polymer. Prototypes associated with a tag name
|
| + // using document.registerElement are available from
|
| + // HTMLElement.getPrototypeForTag().
|
| + // If an element was fully registered by Polymer, then
|
| + // Polymer.getRegisteredPrototype(name) ===
|
| + // HTMLElement.getPrototypeForTag(name)
|
| +
|
| + var prototypesByName = {};
|
| +
|
| + function registerPrototype(name, prototype) {
|
| + return prototypesByName[name] = prototype || {};
|
| + }
|
| +
|
| + function getRegisteredPrototype(name) {
|
| + return prototypesByName[name];
|
| + }
|
| +
|
| + // exports
|
| +
|
| + scope.getRegisteredPrototype = getRegisteredPrototype;
|
| + scope.waitingForPrototype = waitingForPrototype;
|
| +
|
| + // namespace shenanigans so we can expose our scope on the registration
|
| + // function
|
| +
|
| + // make window.Polymer reference `element()`
|
| +
|
| + window.Polymer = element;
|
| +
|
| + // TODO(sjmiles): find a way to do this that is less terrible
|
| + // copy window.Polymer properties onto `element()`
|
| +
|
| + extend(Polymer, scope);
|
| +
|
| + // Under the HTMLImports polyfill, scripts in the main document
|
| + // do not block on imports; we want to allow calls to Polymer in the main
|
| + // document. Platform collects those calls until we can process them, which
|
| + // we do here.
|
| +
|
| + var declarations = Platform.deliverDeclarations();
|
| + if (declarations) {
|
| + for (var i=0, l=declarations.length, d; (i<l) && (d=declarations[i]); i++) {
|
| + element.apply(null, d);
|
| + }
|
| + }
|
| +
|
| +})(Polymer);
|
| +
|
| +/*
|
| + * Copyright 2013 The Polymer Authors. All rights reserved.
|
| + * Use of this source code is governed by a BSD-style
|
| + * license that can be found in the LICENSE file.
|
| + */
|
| +
|
| +(function(scope) {
|
| +
|
| +var path = {
|
| + resolveElementPaths: function(node) {
|
| + Platform.urlResolver.resolveDom(node);
|
| + },
|
| + addResolvePathApi: function() {
|
| + // let assetpath attribute modify the resolve path
|
| + var assetPath = this.getAttribute('assetpath') || '';
|
| + var root = new URL(assetPath, this.ownerDocument.baseURI);
|
| + this.prototype.resolvePath = function(urlPath, base) {
|
| + var u = new URL(urlPath, base || root);
|
| + return u.href;
|
| + };
|
| + }
|
| +};
|
| +
|
| +// exports
|
| +scope.api.declaration.path = path;
|
| +
|
| +})(Polymer);
|
| +
|
| +/*
|
| + * Copyright 2013 The Polymer Authors. All rights reserved.
|
| + * Use of this source code is governed by a BSD-style
|
| + * license that can be found in the LICENSE file.
|
| + */
|
| +(function(scope) {
|
| +
|
| + // imports
|
| +
|
| + var log = window.logFlags || {};
|
| + var api = scope.api.instance.styles;
|
| + var STYLE_SCOPE_ATTRIBUTE = api.STYLE_SCOPE_ATTRIBUTE;
|
| +
|
| + // magic words
|
| +
|
| + var STYLE_SELECTOR = 'style';
|
| + var STYLE_LOADABLE_MATCH = '@import';
|
| + var SHEET_SELECTOR = 'link[rel=stylesheet]';
|
| + var STYLE_GLOBAL_SCOPE = 'global';
|
| + var SCOPE_ATTR = 'polymer-scope';
|
| +
|
| + var styles = {
|
| + // returns true if resources are loading
|
| + loadStyles: function(callback) {
|
| + var content = this.templateContent();
|
| + if (content) {
|
| + this.convertSheetsToStyles(content);
|
| + }
|
| + var styles = this.findLoadableStyles(content);
|
| + if (styles.length) {
|
| + Platform.styleResolver.loadStyles(styles, callback);
|
| + } else if (callback) {
|
| + callback();
|
| + }
|
| + },
|
| + convertSheetsToStyles: function(root) {
|
| + var s$ = root.querySelectorAll(SHEET_SELECTOR);
|
| + for (var i=0, l=s$.length, s, c; (i<l) && (s=s$[i]); i++) {
|
| + c = createStyleElement(importRuleForSheet(s, this.ownerDocument.baseURI),
|
| + this.ownerDocument);
|
| + this.copySheetAttributes(c, s);
|
| + s.parentNode.replaceChild(c, s);
|
| + }
|
| + },
|
| + copySheetAttributes: function(style, link) {
|
| + for (var i=0, a$=link.attributes, l=a$.length, a; (a=a$[i]) && i<l; i++) {
|
| + if (a.name !== 'rel' && a.name !== 'src') {
|
| + style.setAttribute(a.name, a.value);
|
| + }
|
| + }
|
| + },
|
| + findLoadableStyles: function(root) {
|
| + var loadables = [];
|
| + if (root) {
|
| + var s$ = root.querySelectorAll(STYLE_SELECTOR);
|
| + for (var i=0, l=s$.length, s; (i<l) && (s=s$[i]); i++) {
|
| + if (s.textContent.match(STYLE_LOADABLE_MATCH)) {
|
| + loadables.push(s);
|
| + }
|
| + }
|
| + }
|
| + return loadables;
|
| + },
|
| + /**
|
| + * Install external stylesheets loaded in <polymer-element> elements into the
|
| + * element's template.
|
| + * @param elementElement The <element> element to style.
|
| + */
|
| + // TODO(sorvell): wip... caching and styles handling can probably be removed
|
| + // We need a scheme to ensure stylesheets are eagerly loaded without
|
| + // the creation of an element instance. Here are 2 options for handling this:
|
| + // 1. create a dummy element with ShadowDOM in dom that includes ALL styles
|
| + // processed here.
|
| + // 2. place stylesheets outside the element template. This will allow
|
| + // imports to naturally load the sheets. Then at load time, we can remove
|
| + // the stylesheet from dom.
|
| + installSheets: function() {
|
| + this.cacheSheets();
|
| + this.cacheStyles();
|
| + this.installLocalSheets();
|
| + this.installGlobalStyles();
|
| + },
|
| + /**
|
| + * Remove all sheets from element and store for later use.
|
| + */
|
| + cacheSheets: function() {
|
| + this.sheets = this.findNodes(SHEET_SELECTOR);
|
| + this.sheets.forEach(function(s) {
|
| + if (s.parentNode) {
|
| + s.parentNode.removeChild(s);
|
| + }
|
| + });
|
| + },
|
| + cacheStyles: function() {
|
| + this.styles = this.findNodes(STYLE_SELECTOR + '[' + SCOPE_ATTR + ']');
|
| + this.styles.forEach(function(s) {
|
| + if (s.parentNode) {
|
| + s.parentNode.removeChild(s);
|
| + }
|
| + });
|
| + },
|
| + /**
|
| + * Takes external stylesheets loaded in an <element> element and moves
|
| + * their content into a <style> element inside the <element>'s template.
|
| + * The sheet is then removed from the <element>. This is done only so
|
| + * that if the element is loaded in the main document, the sheet does
|
| + * not become active.
|
| + * Note, ignores sheets with the attribute 'polymer-scope'.
|
| + * @param elementElement The <element> element to style.
|
| + */
|
| + installLocalSheets: function () {
|
| + var sheets = this.sheets.filter(function(s) {
|
| + return !s.hasAttribute(SCOPE_ATTR);
|
| + });
|
| + var content = this.templateContent();
|
| + if (content) {
|
| + var cssText = '';
|
| + sheets.forEach(function(sheet) {
|
| + cssText += cssTextFromSheet(sheet) + '\n';
|
| + });
|
| + if (cssText) {
|
| + var style = createStyleElement(cssText, this.ownerDocument);
|
| + content.insertBefore(style, content.firstChild);
|
| + }
|
| + }
|
| + },
|
| + findNodes: function(selector, matcher) {
|
| + var nodes = this.querySelectorAll(selector).array();
|
| + var content = this.templateContent();
|
| + if (content) {
|
| + var templateNodes = content.querySelectorAll(selector).array();
|
| + nodes = nodes.concat(templateNodes);
|
| + }
|
| + return matcher ? nodes.filter(matcher) : nodes;
|
| + },
|
| + templateContent: function() {
|
| + var template = this.querySelector('template');
|
| + return template && templateContent(template);
|
| + },
|
| + /**
|
| + * Promotes external stylesheets and <style> elements with the attribute
|
| + * polymer-scope='global' into global scope.
|
| + * This is particularly useful for defining @keyframe rules which
|
| + * currently do not function in scoped or shadow style elements.
|
| + * (See wkb.ug/72462)
|
| + * @param elementElement The <element> element to style.
|
| + */
|
| + // TODO(sorvell): remove when wkb.ug/72462 is addressed.
|
| + installGlobalStyles: function() {
|
| + var style = this.styleForScope(STYLE_GLOBAL_SCOPE);
|
| + applyStyleToScope(style, document.head);
|
| + },
|
| + cssTextForScope: function(scopeDescriptor) {
|
| + var cssText = '';
|
| + // handle stylesheets
|
| + var selector = '[' + SCOPE_ATTR + '=' + scopeDescriptor + ']';
|
| + var matcher = function(s) {
|
| + return matchesSelector(s, selector);
|
| + };
|
| + var sheets = this.sheets.filter(matcher);
|
| + sheets.forEach(function(sheet) {
|
| + cssText += cssTextFromSheet(sheet) + '\n\n';
|
| + });
|
| + // handle cached style elements
|
| + var styles = this.styles.filter(matcher);
|
| + styles.forEach(function(style) {
|
| + cssText += style.textContent + '\n\n';
|
| + });
|
| + return cssText;
|
| + },
|
| + styleForScope: function(scopeDescriptor) {
|
| + var cssText = this.cssTextForScope(scopeDescriptor);
|
| + return this.cssTextToScopeStyle(cssText, scopeDescriptor);
|
| + },
|
| + cssTextToScopeStyle: function(cssText, scopeDescriptor) {
|
| + if (cssText) {
|
| + var style = createStyleElement(cssText);
|
| + style.setAttribute(STYLE_SCOPE_ATTRIBUTE, this.getAttribute('name') +
|
| + '-' + scopeDescriptor);
|
| + return style;
|
| + }
|
| + }
|
| + };
|
| +
|
| + function importRuleForSheet(sheet, baseUrl) {
|
| + var href = new URL(sheet.getAttribute('href'), baseUrl).href;
|
| + return '@import \'' + href + '\';'
|
| + }
|
| +
|
| + function applyStyleToScope(style, scope) {
|
| + if (style) {
|
| + // TODO(sorvell): necessary for IE
|
| + // see https://connect.microsoft.com/IE/feedback/details/790212/
|
| + // cloning-a-style-element-and-adding-to-document-produces
|
| + // -unexpected-result#details
|
| + // var clone = style.cloneNode(true);
|
| + var clone = createStyleElement(style.textContent);
|
| + var attr = style.getAttribute(STYLE_SCOPE_ATTRIBUTE);
|
| + if (attr) {
|
| + clone.setAttribute(STYLE_SCOPE_ATTRIBUTE, attr);
|
| + }
|
| + scope.appendChild(clone);
|
| + }
|
| + }
|
| +
|
| + function createStyleElement(cssText, scope) {
|
| + scope = scope || document;
|
| + scope = scope.createElement ? scope : scope.ownerDocument;
|
| + var style = scope.createElement('style');
|
| + style.textContent = cssText;
|
| + return style;
|
| + }
|
| +
|
| + function cssTextFromSheet(sheet) {
|
| + return (sheet && sheet.__resource) || '';
|
| + }
|
| +
|
| + function matchesSelector(node, inSelector) {
|
| + if (matches) {
|
| + return matches.call(node, inSelector);
|
| + }
|
| + }
|
| + var p = HTMLElement.prototype;
|
| + var matches = p.matches || p.matchesSelector || p.webkitMatchesSelector
|
| + || p.mozMatchesSelector;
|
| +
|
| + // exports
|
| +
|
| + scope.api.declaration.styles = styles;
|
| + scope.applyStyleToScope = applyStyleToScope;
|
| +
|
| +})(Polymer);
|
| +
|
| +/*
|
| + * Copyright 2013 The Polymer Authors. All rights reserved.
|
| + * Use of this source code is governed by a BSD-style
|
| + * license that can be found in the LICENSE file.
|
| + */
|
| +
|
| +(function(scope) {
|
| +
|
| + // imports
|
| +
|
| + var log = window.logFlags || {};
|
| + var api = scope.api.instance.events;
|
| + var EVENT_PREFIX = api.EVENT_PREFIX;
|
| + // polymer-element declarative api: events feature
|
| +
|
| + var events = {
|
| + parseHostEvents: function() {
|
| + // our delegates map
|
| + var delegates = this.prototype.eventDelegates;
|
| + // extract data from attributes into delegates
|
| + this.addAttributeDelegates(delegates);
|
| + },
|
| + addAttributeDelegates: function(delegates) {
|
| + // for each attribute
|
| + for (var i=0, a; a=this.attributes[i]; i++) {
|
| + // does it have magic marker identifying it as an event delegate?
|
| + if (this.hasEventPrefix(a.name)) {
|
| + // if so, add the info to delegates
|
| + delegates[this.removeEventPrefix(a.name)] = a.value.replace('{{', '')
|
| + .replace('}}', '').trim();
|
| + }
|
| + }
|
| + },
|
| + // starts with 'on-'
|
| + hasEventPrefix: function (n) {
|
| + return n && (n[0] === 'o') && (n[1] === 'n') && (n[2] === '-');
|
| + },
|
| + removeEventPrefix: function(n) {
|
| + return n.slice(prefixLength);
|
| + }
|
| + };
|
| +
|
| + var prefixLength = EVENT_PREFIX.length;
|
| +
|
| + // exports
|
| + scope.api.declaration.events = events;
|
| +
|
| +})(Polymer);
|
| +/*
|
| + * Copyright 2013 The Polymer Authors. All rights reserved.
|
| + * Use of this source code is governed by a BSD-style
|
| + * license that can be found in the LICENSE file.
|
| + */
|
| +(function(scope) {
|
| +
|
| + // element api
|
| +
|
| + var properties = {
|
| + inferObservers: function(prototype) {
|
| + // called before prototype.observe is chained to inherited object
|
| + var observe = prototype.observe, property;
|
| + for (var n in prototype) {
|
| + if (n.slice(-7) === 'Changed') {
|
| + if (!observe) {
|
| + observe = (prototype.observe = {});
|
| + }
|
| + property = n.slice(0, -7)
|
| + observe[property] = observe[property] || n;
|
| + }
|
| + }
|
| + },
|
| + explodeObservers: function(prototype) {
|
| + // called before prototype.observe is chained to inherited object
|
| + var o = prototype.observe;
|
| + if (o) {
|
| + var exploded = {};
|
| + for (var n in o) {
|
| + var names = n.split(' ');
|
| + for (var i=0, ni; ni=names[i]; i++) {
|
| + exploded[ni] = o[n];
|
| + }
|
| + }
|
| + prototype.observe = exploded;
|
| + }
|
| + },
|
| + optimizePropertyMaps: function(prototype) {
|
| + if (prototype.observe) {
|
| + // construct name list
|
| + var a = prototype._observeNames = [];
|
| + for (var n in prototype.observe) {
|
| + var names = n.split(' ');
|
| + for (var i=0, ni; ni=names[i]; i++) {
|
| + a.push(ni);
|
| + }
|
| + //a.push(n);
|
| + }
|
| + }
|
| + if (prototype.publish) {
|
| + // construct name list
|
| + var a = prototype._publishNames = [];
|
| + for (var n in prototype.publish) {
|
| + a.push(n);
|
| + }
|
| + }
|
| + },
|
| + publishProperties: function(prototype, base) {
|
| + // if we have any properties to publish
|
| + var publish = prototype.publish;
|
| + if (publish) {
|
| + // transcribe `publish` entries onto own prototype
|
| + this.requireProperties(publish, prototype, base);
|
| + // construct map of lower-cased property names
|
| + prototype._publishLC = this.lowerCaseMap(publish);
|
| + }
|
| + },
|
| + requireProperties: function(properties, prototype, base) {
|
| + // ensure a prototype value for each property
|
| + for (var n in properties) {
|
| + if (prototype[n] === undefined && base[n] === undefined) {
|
| + prototype[n] = properties[n];
|
| + }
|
| + }
|
| + },
|
| + lowerCaseMap: function(properties) {
|
| + var map = {};
|
| + for (var n in properties) {
|
| + map[n.toLowerCase()] = n;
|
| + }
|
| + return map;
|
| + }
|
| + };
|
| +
|
| + // exports
|
| +
|
| + scope.api.declaration.properties = properties;
|
| +
|
| +})(Polymer);
|
| +
|
| +/*
|
| + * Copyright 2013 The Polymer Authors. All rights reserved.
|
| + * Use of this source code is governed by a BSD-style
|
| + * license that can be found in the LICENSE file.
|
| + */
|
| +(function(scope) {
|
| +
|
| + // magic words
|
| +
|
| + var ATTRIBUTES_ATTRIBUTE = 'attributes';
|
| + var ATTRIBUTES_REGEX = /\s|,/;
|
| +
|
| + // attributes api
|
| +
|
| + var attributes = {
|
| + inheritAttributesObjects: function(prototype) {
|
| + // chain our lower-cased publish map to the inherited version
|
| + this.inheritObject(prototype, 'publishLC');
|
| + // chain our instance attributes map to the inherited version
|
| + this.inheritObject(prototype, '_instanceAttributes');
|
| + },
|
| + publishAttributes: function(prototype, base) {
|
| + // merge names from 'attributes' attribute
|
| + var attributes = this.getAttribute(ATTRIBUTES_ATTRIBUTE);
|
| + if (attributes) {
|
| + // get properties to publish
|
| + var publish = prototype.publish || (prototype.publish = {});
|
| + // names='a b c' or names='a,b,c'
|
| + var names = attributes.split(ATTRIBUTES_REGEX);
|
| + // record each name for publishing
|
| + for (var i=0, l=names.length, n; i<l; i++) {
|
| + // remove excess ws
|
| + n = names[i].trim();
|
| + // do not override explicit entries
|
| + if (n && publish[n] === undefined && base[n] === undefined) {
|
| + publish[n] = null;
|
| + }
|
| + }
|
| + }
|
| + },
|
| + // record clonable attributes from <element>
|
| + accumulateInstanceAttributes: function() {
|
| + // inherit instance attributes
|
| + var clonable = this.prototype._instanceAttributes;
|
| + // merge attributes from element
|
| + var a$ = this.attributes;
|
| + for (var i=0, l=a$.length, a; (i<l) && (a=a$[i]); i++) {
|
| + if (this.isInstanceAttribute(a.name)) {
|
| + clonable[a.name] = a.value;
|
| + }
|
| + }
|
| + },
|
| + isInstanceAttribute: function(name) {
|
| + return !this.blackList[name] && name.slice(0,3) !== 'on-';
|
| + },
|
| + // do not clone these attributes onto instances
|
| + blackList: {
|
| + name: 1,
|
| + 'extends': 1,
|
| + constructor: 1,
|
| + noscript: 1,
|
| + assetpath: 1,
|
| + 'cache-csstext': 1
|
| + }
|
| + };
|
| +
|
| + // add ATTRIBUTES_ATTRIBUTE to the blacklist
|
| + attributes.blackList[ATTRIBUTES_ATTRIBUTE] = 1;
|
| +
|
| + // exports
|
| +
|
| + scope.api.declaration.attributes = attributes;
|
| +
|
| +})(Polymer);
|
| +
|
| +/*
|
| + * Copyright 2013 The Polymer Authors. All rights reserved.
|
| + * Use of this source code is governed by a BSD-style
|
| + * license that can be found in the LICENSE file.
|
| + */
|
| +(function(scope) {
|
| +
|
| + // imports
|
| +
|
| + var api = scope.api;
|
| + var isBase = scope.isBase;
|
| + var extend = scope.extend;
|
| +
|
| + // prototype api
|
| +
|
| + var prototype = {
|
| +
|
| + register: function(name, extendeeName) {
|
| + // build prototype combining extendee, Polymer base, and named api
|
| + this.buildPrototype(name, extendeeName);
|
| + // register our custom element with the platform
|
| + this.registerPrototype(name, extendeeName);
|
| + // reference constructor in a global named by 'constructor' attribute
|
| + this.publishConstructor();
|
| + },
|
| +
|
| + buildPrototype: function(name, extendeeName) {
|
| + // get our custom prototype (before chaining)
|
| + var extension = scope.getRegisteredPrototype(name);
|
| + // get basal prototype
|
| + var base = this.generateBasePrototype(extendeeName);
|
| + // implement declarative features
|
| + this.desugarBeforeChaining(extension, base);
|
| + // join prototypes
|
| + this.prototype = this.chainPrototypes(extension, base);
|
| + // more declarative features
|
| + this.desugarAfterChaining(name, extendeeName);
|
| + },
|
| +
|
| + desugarBeforeChaining: function(prototype, base) {
|
| + // back reference declaration element
|
| + // TODO(sjmiles): replace `element` with `elementElement` or `declaration`
|
| + prototype.element = this;
|
| + // transcribe `attributes` declarations onto own prototype's `publish`
|
| + this.publishAttributes(prototype, base);
|
| + // `publish` properties to the prototype and to attribute watch
|
| + this.publishProperties(prototype, base);
|
| + // infer observers for `observe` list based on method names
|
| + this.inferObservers(prototype);
|
| + // desugar compound observer syntax, e.g. 'a b c'
|
| + this.explodeObservers(prototype);
|
| + },
|
| +
|
| + chainPrototypes: function(prototype, base) {
|
| + // chain various meta-data objects to inherited versions
|
| + this.inheritMetaData(prototype, base);
|
| + // chain custom api to inherited
|
| + var chained = this.chainObject(prototype, base);
|
| + // x-platform fixup
|
| + ensurePrototypeTraversal(chained);
|
| + return chained;
|
| + },
|
| +
|
| + inheritMetaData: function(prototype, base) {
|
| + // chain observe object to inherited
|
| + this.inheritObject('observe', prototype, base);
|
| + // chain publish object to inherited
|
| + this.inheritObject('publish', prototype, base);
|
| + // chain our lower-cased publish map to the inherited version
|
| + this.inheritObject('_publishLC', prototype, base);
|
| + // chain our instance attributes map to the inherited version
|
| + this.inheritObject('_instanceAttributes', prototype, base);
|
| + // chain our event delegates map to the inherited version
|
| + this.inheritObject('eventDelegates', prototype, base);
|
| + },
|
| +
|
| + // implement various declarative features
|
| + desugarAfterChaining: function(name, extendee) {
|
| + // build side-chained lists to optimize iterations
|
| + this.optimizePropertyMaps(this.prototype);
|
| + // install external stylesheets as if they are inline
|
| + this.installSheets();
|
| + // adjust any paths in dom from imports
|
| + this.resolveElementPaths(this);
|
| + // compile list of attributes to copy to instances
|
| + this.accumulateInstanceAttributes();
|
| + // parse on-* delegates declared on `this` element
|
| + this.parseHostEvents();
|
| + //
|
| + // install a helper method this.resolvePath to aid in
|
| + // setting resource urls. e.g.
|
| + // this.$.image.src = this.resolvePath('images/foo.png')
|
| + this.addResolvePathApi();
|
| + // under ShadowDOMPolyfill, transforms to approximate missing CSS features
|
| + if (window.ShadowDOMPolyfill) {
|
| + Platform.ShadowCSS.shimStyling(this.templateContent(), name, extendee);
|
| + }
|
| + // allow custom element access to the declarative context
|
| + if (this.prototype.registerCallback) {
|
| + this.prototype.registerCallback(this);
|
| + }
|
| + },
|
| +
|
| + // if a named constructor is requested in element, map a reference
|
| + // to the constructor to the given symbol
|
| + publishConstructor: function() {
|
| + var symbol = this.getAttribute('constructor');
|
| + if (symbol) {
|
| + window[symbol] = this.ctor;
|
| + }
|
| + },
|
| +
|
| + // build prototype combining extendee, Polymer base, and named api
|
| + generateBasePrototype: function(extnds) {
|
| + var prototype = this.findBasePrototype(extnds);
|
| + if (!prototype) {
|
| + // create a prototype based on tag-name extension
|
| + var prototype = HTMLElement.getPrototypeForTag(extnds);
|
| + // insert base api in inheritance chain (if needed)
|
| + prototype = this.ensureBaseApi(prototype);
|
| + // memoize this base
|
| + memoizedBases[extnds] = prototype;
|
| + }
|
| + return prototype;
|
| + },
|
| +
|
| + findBasePrototype: function(name) {
|
| + return memoizedBases[name];
|
| + },
|
| +
|
| + // install Polymer instance api into prototype chain, as needed
|
| + ensureBaseApi: function(prototype) {
|
| + if (prototype.PolymerBase) {
|
| + return prototype;
|
| + }
|
| + var extended = Object.create(prototype);
|
| + // we need a unique copy of base api for each base prototype
|
| + // therefore we 'extend' here instead of simply chaining
|
| + api.publish(api.instance, extended);
|
| + // TODO(sjmiles): sharing methods across prototype chains is
|
| + // not supported by 'super' implementation which optimizes
|
| + // by memoizing prototype relationships.
|
| + // Probably we should have a version of 'extend' that is
|
| + // share-aware: it could study the text of each function,
|
| + // look for usage of 'super', and wrap those functions in
|
| + // closures.
|
| + // As of now, there is only one problematic method, so
|
| + // we just patch it manually.
|
| + // To avoid re-entrancy problems, the special super method
|
| + // installed is called `mixinSuper` and the mixin method
|
| + // must use this method instead of the default `super`.
|
| + this.mixinMethod(extended, prototype, api.instance.mdv, 'bind');
|
| + // return buffed-up prototype
|
| + return extended;
|
| + },
|
| +
|
| + mixinMethod: function(extended, prototype, api, name) {
|
| + var $super = function(args) {
|
| + return prototype[name].apply(this, args);
|
| + };
|
| + extended[name] = function() {
|
| + this.mixinSuper = $super;
|
| + return api[name].apply(this, arguments);
|
| + }
|
| + },
|
| +
|
| + // ensure prototype[name] inherits from a prototype.prototype[name]
|
| + inheritObject: function(name, prototype, base) {
|
| + // require an object
|
| + var source = prototype[name] || {};
|
| + // chain inherited properties onto a new object
|
| + prototype[name] = this.chainObject(source, base[name]);
|
| + },
|
| +
|
| + // register 'prototype' to custom element 'name', store constructor
|
| + registerPrototype: function(name, extendee) {
|
| + var info = {
|
| + prototype: this.prototype
|
| + }
|
| + // native element must be specified in extends
|
| + var typeExtension = this.findTypeExtension(extendee);
|
| + if (typeExtension) {
|
| + info.extends = typeExtension;
|
| + }
|
| + // register the prototype with HTMLElement for name lookup
|
| + HTMLElement.register(name, this.prototype);
|
| + // register the custom type
|
| + this.ctor = document.registerElement(name, info);
|
| + },
|
| +
|
| + findTypeExtension: function(name) {
|
| + if (name && name.indexOf('-') < 0) {
|
| + return name;
|
| + } else {
|
| + var p = this.findBasePrototype(name);
|
| + if (p.element) {
|
| + return this.findTypeExtension(p.element.extends);
|
| + }
|
| + }
|
| + }
|
| +
|
| + };
|
| +
|
| + // memoize base prototypes
|
| + var memoizedBases = {};
|
| +
|
| + // implementation of 'chainObject' depends on support for __proto__
|
| + if (Object.__proto__) {
|
| + prototype.chainObject = function(object, inherited) {
|
| + if (object && inherited && object !== inherited) {
|
| + object.__proto__ = inherited;
|
| + }
|
| + return object;
|
| + }
|
| + } else {
|
| + prototype.chainObject = function(object, inherited) {
|
| + if (object && inherited && object !== inherited) {
|
| + var chained = Object.create(inherited);
|
| + object = extend(chained, object);
|
| + }
|
| + return object;
|
| + }
|
| + }
|
| +
|
| + // On platforms that do not support __proto__ (versions of IE), the prototype
|
| + // chain of a custom element is simulated via installation of __proto__.
|
| + // Although custom elements manages this, we install it here so it's
|
| + // available during desugaring.
|
| + function ensurePrototypeTraversal(prototype) {
|
| + if (!Object.__proto__) {
|
| + var ancestor = Object.getPrototypeOf(prototype);
|
| + prototype.__proto__ = ancestor;
|
| + if (isBase(ancestor)) {
|
| + ancestor.__proto__ = Object.getPrototypeOf(ancestor);
|
| + }
|
| + }
|
| + }
|
| +
|
| + // exports
|
| +
|
| + api.declaration.prototype = prototype;
|
| +
|
| +})(Polymer);
|
| +
|
| +/*
|
| + * Copyright 2013 The Polymer Authors. All rights reserved.
|
| + * Use of this source code is governed by a BSD-style
|
| + * license that can be found in the LICENSE file.
|
| + */
|
| +(function(scope) {
|
| +
|
| + var queue = {
|
| + // tell the queue to wait for an element to be ready
|
| + wait: function(element, check, go) {
|
| + if (this.indexOf(element) === -1) {
|
| + this.add(element);
|
| + element.__check = check;
|
| + element.__go = go;
|
| + }
|
| + return (this.indexOf(element) !== 0);
|
| + },
|
| + add: function(element) {
|
| + //console.log('queueing', element.name);
|
| + queueForElement(element).push(element);
|
| + },
|
| + indexOf: function(element) {
|
| + var i = queueForElement(element).indexOf(element);
|
| + if (i >= 0 && document.contains(element)) {
|
| + i += (HTMLImports.useNative || HTMLImports.ready) ? importQueue.length :
|
| + 1e9;
|
| + }
|
| + return i;
|
| + },
|
| + // tell the queue an element is ready to be registered
|
| + go: function(element) {
|
| + var readied = this.remove(element);
|
| + if (readied) {
|
| + readied.__go.call(readied);
|
| + readied.__check = readied.__go = null;
|
| + this.check();
|
| + }
|
| + },
|
| + remove: function(element) {
|
| + var i = this.indexOf(element);
|
| + if (i !== 0) {
|
| + //console.warn('queue order wrong', i);
|
| + return;
|
| + }
|
| + return queueForElement(element).shift();
|
| + },
|
| + check: function() {
|
| + // next
|
| + var element = this.nextElement();
|
| + if (element) {
|
| + element.__check.call(element);
|
| + }
|
| + if (this.canReady()) {
|
| + this.ready();
|
| + return true;
|
| + }
|
| + },
|
| + nextElement: function() {
|
| + return nextQueued();
|
| + },
|
| + canReady: function() {
|
| + return !this.waitToReady && this.isEmpty();
|
| + },
|
| + isEmpty: function() {
|
| + return !importQueue.length && !mainQueue.length;
|
| + },
|
| + ready: function() {
|
| + // TODO(sorvell): As an optimization, turn off CE polyfill upgrading
|
| + // while registering. This way we avoid having to upgrade each document
|
| + // piecemeal per registration and can instead register all elements
|
| + // and upgrade once in a batch. Without this optimization, upgrade time
|
| + // degrades significantly when SD polyfill is used. This is mainly because
|
| + // querying the document tree for elements is slow under the SD polyfill.
|
| + if (CustomElements.ready === false) {
|
| + CustomElements.upgradeDocumentTree(document);
|
| + CustomElements.ready = true;
|
| + }
|
| + if (readyCallbacks) {
|
| + var fn;
|
| + while (readyCallbacks.length) {
|
| + fn = readyCallbacks.shift();
|
| + fn();
|
| + }
|
| + }
|
| + },
|
| + addReadyCallback: function(callback) {
|
| + if (callback) {
|
| + readyCallbacks.push(callback);
|
| + }
|
| + },
|
| + waitToReady: true
|
| + };
|
| +
|
| + var importQueue = [];
|
| + var mainQueue = [];
|
| + var readyCallbacks = [];
|
| +
|
| + function queueForElement(element) {
|
| + return document.contains(element) ? mainQueue : importQueue;
|
| + }
|
| +
|
| + function nextQueued() {
|
| + return importQueue.length ? importQueue[0] : mainQueue[0];
|
| + }
|
| +
|
| + var polymerReadied = false;
|
| +
|
| + document.addEventListener('WebComponentsReady', function() {
|
| + CustomElements.ready = false;
|
| + });
|
| +
|
| + function whenPolymerReady(callback) {
|
| + queue.waitToReady = true;
|
| + CustomElements.ready = false;
|
| + HTMLImports.whenImportsReady(function() {
|
| + queue.addReadyCallback(callback);
|
| + queue.waitToReady = false;
|
| + queue.check();
|
| + });
|
| + }
|
| +
|
| + // exports
|
| + scope.queue = queue;
|
| + scope.whenPolymerReady = whenPolymerReady;
|
| +})(Polymer);
|
| +
|
| +/*
|
| + * Copyright 2013 The Polymer Authors. All rights reserved.
|
| + * Use of this source code is governed by a BSD-style
|
| + * license that can be found in the LICENSE file.
|
| + */
|
| +(function(scope) {
|
| +
|
| + var whenPolymerReady = scope.whenPolymerReady;
|
| +
|
| + function importElements(elementOrFragment, callback) {
|
| + if (elementOrFragment) {
|
| + document.head.appendChild(elementOrFragment);
|
| + whenPolymerReady(callback);
|
| + } else if (callback) {
|
| + callback();
|
| + }
|
| + }
|
| +
|
| + function importUrls(urls, callback) {
|
| + if (urls && urls.length) {
|
| + var frag = document.createDocumentFragment();
|
| + for (var i=0, l=urls.length, url, link; (i<l) && (url=urls[i]); i++) {
|
| + link = document.createElement('link');
|
| + link.rel = 'import';
|
| + link.href = url;
|
| + frag.appendChild(link);
|
| + }
|
| + importElements(frag, callback);
|
| + } else if (callback) {
|
| + callback();
|
| + }
|
| + }
|
| +
|
| + // exports
|
| + scope.import = importUrls;
|
| + scope.importElements = importElements;
|
| +
|
| +})(Polymer);
|
| +
|
| +/*
|
| + * Copyright 2013 The Polymer Authors. All rights reserved.
|
| + * Use of this source code is governed by a BSD-style
|
| + * license that can be found in the LICENSE file.
|
| + */
|
| +(function(scope) {
|
| +
|
| + // imports
|
| +
|
| + var extend = scope.extend;
|
| + var api = scope.api;
|
| + var queue = scope.queue;
|
| + var whenPolymerReady = scope.whenPolymerReady;
|
| + var getRegisteredPrototype = scope.getRegisteredPrototype;
|
| + var waitingForPrototype = scope.waitingForPrototype;
|
| +
|
| + // declarative implementation: <polymer-element>
|
| +
|
| + var prototype = extend(Object.create(HTMLElement.prototype), {
|
| +
|
| + createdCallback: function() {
|
| + if (this.getAttribute('name')) {
|
| + this.init();
|
| + }
|
| + },
|
| +
|
| + init: function() {
|
| + // fetch declared values
|
| + this.name = this.getAttribute('name');
|
| + this.extends = this.getAttribute('extends');
|
| + // initiate any async resource fetches
|
| + this.loadResources();
|
| + // register when all constraints are met
|
| + this.registerWhenReady();
|
| + },
|
| +
|
| + registerWhenReady: function() {
|
| + if (this.registered
|
| + || this.waitingForPrototype(this.name)
|
| + || this.waitingForQueue()
|
| + || this.waitingForResources()) {
|
| + return;
|
| + }
|
| + queue.go(this);
|
| + },
|
| +
|
| +
|
| + // TODO(sorvell): refactor, this method is private-ish, but it's being
|
| + // called by the queue object.
|
| + _register: function() {
|
| + //console.log('registering', this.name);
|
| + //console.group('registering', this.name);
|
| + // warn if extending from a custom element not registered via Polymer
|
| + if (isCustomTag(this.extends) && !isRegistered(this.extends)) {
|
| + console.warn('%s is attempting to extend %s, an unregistered element ' +
|
| + 'or one that was not registered with Polymer.', this.name,
|
| + this.extends);
|
| + }
|
| + this.register(this.name, this.extends);
|
| + this.registered = true;
|
| + //console.groupEnd();
|
| + },
|
| +
|
| + waitingForPrototype: function(name) {
|
| + if (!getRegisteredPrototype(name)) {
|
| + // then wait for a prototype
|
| + waitingForPrototype(name, this);
|
| + // emulate script if user is not supplying one
|
| + this.handleNoScript(name);
|
| + // prototype not ready yet
|
| + return true;
|
| + }
|
| + },
|
| +
|
| + handleNoScript: function(name) {
|
| + // if explicitly marked as 'noscript'
|
| + if (this.hasAttribute('noscript') && !this.noscript) {
|
| + this.noscript = true;
|
| + // TODO(sorvell): CustomElements polyfill awareness:
|
| + // noscript elements should upgrade in logical order
|
| + // script injection ensures this under native custom elements;
|
| + // under imports + ce polyfills, scripts run before upgrades.
|
| + // dependencies should be ready at upgrade time so register
|
| + // prototype at this time.
|
| + if (window.CustomElements && !CustomElements.useNative) {
|
| + Polymer(name);
|
| + } else {
|
| + var script = document.createElement('script');
|
| + script.textContent = 'Polymer(\'' + name + '\');';
|
| + this.appendChild(script);
|
| + }
|
| + }
|
| + },
|
| +
|
| + waitingForResources: function() {
|
| + return this._needsResources;
|
| + },
|
| +
|
| + // NOTE: Elements must be queued in proper order for inheritance/composition
|
| + // dependency resolution. Previously this was enforced for inheritance,
|
| + // and by rule for composition. It's now entirely by rule.
|
| + waitingForQueue: function() {
|
| + return queue.wait(this, this.registerWhenReady, this._register);
|
| + },
|
| +
|
| + loadResources: function() {
|
| + this._needsResources = true;
|
| + this.loadStyles(function() {
|
| + this._needsResources = false;
|
| + this.registerWhenReady();
|
| + }.bind(this));
|
| + }
|
| +
|
| + });
|
| +
|
| + // semi-pluggable APIs
|
| +
|
| + // TODO(sjmiles): should be fully pluggable (aka decoupled, currently
|
| + // the various plugins are allowed to depend on each other directly)
|
| + api.publish(api.declaration, prototype);
|
| +
|
| + // utility and bookkeeping
|
| +
|
| + function isRegistered(name) {
|
| + return Boolean(HTMLElement.getPrototypeForTag(name));
|
| + }
|
| +
|
| + function isCustomTag(name) {
|
| + return (name && name.indexOf('-') >= 0);
|
| + }
|
| +
|
| + // exports
|
| +
|
| + scope.getRegisteredPrototype = getRegisteredPrototype;
|
| +
|
| + // boot tasks
|
| +
|
| + whenPolymerReady(function() {
|
| + document.body.removeAttribute('unresolved');
|
| + document.dispatchEvent(
|
| + new CustomEvent('polymer-ready', {bubbles: true})
|
| + );
|
| + });
|
| +
|
| + // register polymer-element with document
|
| +
|
| + document.registerElement('polymer-element', {prototype: prototype});
|
| +
|
| +})(Polymer);
|
| +
|
| +//# sourceMappingURL=polymer.concat.js.map
|
|
|