Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(725)

Unified Diff: pkg/polymer/lib/src/js/polymer/polymer.concat.js

Issue 182193002: [polymer] interop with polymer-element and polymer.js (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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
« no previous file with comments | « pkg/polymer/lib/src/js/polymer/polymer-body.html ('k') | pkg/polymer/lib/src/js/polymer/polymer.concat.js.map » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698