| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2013 The Polymer Authors. All rights reserved. | 2 * Copyright 2013 The Polymer Authors. All rights reserved. |
| 3 * Use of this source code is governed by a BSD-style | 3 * Use of this source code is governed by a BSD-style |
| 4 * license that can be found in the LICENSE file. | 4 * license that can be found in the LICENSE file. |
| 5 */ | 5 */ |
| 6 Polymer = {}; | 6 Polymer = {}; |
| 7 | 7 |
| 8 /* | 8 /* |
| 9 * Copyright 2013 The Polymer Authors. All rights reserved. | 9 * Copyright 2013 The Polymer Authors. All rights reserved. |
| 10 * Use of this source code is governed by a BSD-style | 10 * Use of this source code is governed by a BSD-style |
| (...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 400 // second argument to `apply` must be an array | 400 // second argument to `apply` must be an array |
| 401 args = (args && args.length) ? args : [args]; | 401 args = (args && args.length) ? args : [args]; |
| 402 // function to invoke | 402 // function to invoke |
| 403 var fn = function() { | 403 var fn = function() { |
| 404 (this[method] || method).apply(this, args); | 404 (this[method] || method).apply(this, args); |
| 405 }.bind(this); | 405 }.bind(this); |
| 406 // execute `fn` sooner or later | 406 // execute `fn` sooner or later |
| 407 var handle = timeout ? setTimeout(fn, timeout) : | 407 var handle = timeout ? setTimeout(fn, timeout) : |
| 408 requestAnimationFrame(fn); | 408 requestAnimationFrame(fn); |
| 409 // NOTE: switch on inverting handle to determine which time is used. | 409 // NOTE: switch on inverting handle to determine which time is used. |
| 410 return timeout ? handle : ~handle; | 410 return timeout ? handle : 1 / handle; |
| 411 }, | 411 }, |
| 412 cancelAsync: function(handle) { | 412 cancelAsync: function(handle) { |
| 413 if (handle < 0) { | 413 if (handle < 1) { |
| 414 cancelAnimationFrame(~handle); | 414 cancelAnimationFrame(Math.round(1 / handle)); |
| 415 } else { | 415 } else { |
| 416 clearTimeout(handle); | 416 clearTimeout(handle); |
| 417 } | 417 } |
| 418 }, | 418 }, |
| 419 /** | 419 /** |
| 420 * Fire an event. | 420 * Fire an event. |
| 421 * @method fire | 421 * @method fire |
| 422 * @returns {Object} event | 422 * @returns {Object} event |
| 423 * @param {string} type An event name. | 423 * @param {string} type An event name. |
| 424 * @param {any} detail | 424 * @param {any} detail |
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 657 // element api | 657 // element api |
| 658 | 658 |
| 659 var empty = []; | 659 var empty = []; |
| 660 | 660 |
| 661 var properties = { | 661 var properties = { |
| 662 observeProperties: function() { | 662 observeProperties: function() { |
| 663 var n$ = this._observeNames, pn$ = this._publishNames; | 663 var n$ = this._observeNames, pn$ = this._publishNames; |
| 664 if ((n$ && n$.length) || (pn$ && pn$.length)) { | 664 if ((n$ && n$.length) || (pn$ && pn$.length)) { |
| 665 var self = this; | 665 var self = this; |
| 666 var o = this._propertyObserver = new CompoundObserver(); | 666 var o = this._propertyObserver = new CompoundObserver(); |
| 667 // keep track of property observer so we can shut it down | |
| 668 this.registerObservers([o]); | |
| 669 for (var i=0, l=n$.length, n; (i<l) && (n=n$[i]); i++) { | 667 for (var i=0, l=n$.length, n; (i<l) && (n=n$[i]); i++) { |
| 670 o.addPath(this, n); | 668 o.addPath(this, n); |
| 671 // observer array properties | 669 // observer array properties |
| 672 var pd = Object.getOwnPropertyDescriptor(this.__proto__, n); | 670 var pd = Object.getOwnPropertyDescriptor(this.__proto__, n); |
| 673 if (pd && pd.value) { | 671 if (pd && pd.value) { |
| 674 this.observeArrayValue(n, pd.value, null); | 672 this.observeArrayValue(n, pd.value, null); |
| 675 } | 673 } |
| 676 } | 674 } |
| 677 for (var i=0, l=pn$.length, n; (i<l) && (n=pn$[i]); i++) { | 675 for (var i=0, l=pn$.length, n; (i<l) && (n=pn$[i]); i++) { |
| 678 if (!this.observe || (this.observe[n] === undefined)) { | 676 if (!this.observe || (this.observe[n] === undefined)) { |
| (...skipping 22 matching lines...) Expand all Loading... |
| 701 } | 699 } |
| 702 } | 700 } |
| 703 }, | 701 }, |
| 704 observeArrayValue: function(name, value, old) { | 702 observeArrayValue: function(name, value, old) { |
| 705 // we only care if there are registered side-effects | 703 // we only care if there are registered side-effects |
| 706 var callbackName = this.observe[name]; | 704 var callbackName = this.observe[name]; |
| 707 if (callbackName) { | 705 if (callbackName) { |
| 708 // if we are observing the previous value, stop | 706 // if we are observing the previous value, stop |
| 709 if (Array.isArray(old)) { | 707 if (Array.isArray(old)) { |
| 710 log.observe && console.log('[%s] observeArrayValue: unregister observe
r [%s]', this.localName, name); | 708 log.observe && console.log('[%s] observeArrayValue: unregister observe
r [%s]', this.localName, name); |
| 711 this.closeNamedObserver(name + '__array'); | 709 this.unregisterObserver(name + '__array'); |
| 712 } | 710 } |
| 713 // if the new value is an array, being observing it | 711 // if the new value is an array, being observing it |
| 714 if (Array.isArray(value)) { | 712 if (Array.isArray(value)) { |
| 715 log.observe && console.log('[%s] observeArrayValue: register observer
[%s]', this.localName, name, value); | 713 log.observe && console.log('[%s] observeArrayValue: register observer
[%s]', this.localName, name, value); |
| 716 var observer = new ArrayObserver(value); | 714 var observer = new ArrayObserver(value); |
| 717 observer.open(function(value, old) { | 715 observer.open(function(value, old) { |
| 718 this.invokeMethod(callbackName, [old]); | 716 this.invokeMethod(callbackName, [old]); |
| 719 }, this); | 717 }, this); |
| 720 this.registerNamedObserver(name + '__array', observer); | 718 this.registerObserver(name + '__array', observer); |
| 721 } | 719 } |
| 722 } | 720 } |
| 723 }, | 721 }, |
| 724 bindProperty: function(property, observable) { | 722 bindProperty: function(property, observable) { |
| 725 // apply Polymer two-way reference binding | 723 // apply Polymer two-way reference binding |
| 726 return bindProperties(this, property, observable); | 724 return bindProperties(this, property, observable); |
| 727 }, | 725 }, |
| 726 unbindAllProperties: function() { |
| 727 if (this._propertyObserver) { |
| 728 this._propertyObserver.close(); |
| 729 } |
| 730 this.unregisterObservers(); |
| 731 }, |
| 732 unbindProperty: function(name) { |
| 733 return this.unregisterObserver(name); |
| 734 }, |
| 728 invokeMethod: function(method, args) { | 735 invokeMethod: function(method, args) { |
| 729 var fn = this[method] || method; | 736 var fn = this[method] || method; |
| 730 if (typeof fn === 'function') { | 737 if (typeof fn === 'function') { |
| 731 fn.apply(this, args); | 738 fn.apply(this, args); |
| 732 } | 739 } |
| 733 }, | 740 }, |
| 734 registerObservers: function(observers) { | |
| 735 this._observers.push(observers); | |
| 736 }, | |
| 737 // observer array items are arrays of observers. | |
| 738 closeObservers: function() { | |
| 739 for (var i=0, l=this._observers.length; i<l; i++) { | |
| 740 this.closeObserverArray(this._observers[i]); | |
| 741 } | |
| 742 this._observers = []; | |
| 743 }, | |
| 744 closeObserverArray: function(observerArray) { | |
| 745 for (var i=0, l=observerArray.length, o; i<l; i++) { | |
| 746 o = observerArray[i]; | |
| 747 if (o && o.close) { | |
| 748 o.close(); | |
| 749 } | |
| 750 } | |
| 751 }, | |
| 752 // bookkeeping observers for memory management | 741 // bookkeeping observers for memory management |
| 753 registerNamedObserver: function(name, observer) { | 742 registerObserver: function(name, observer) { |
| 754 var o$ = this._namedObservers || (this._namedObservers = {}); | 743 var o$ = this._observers || (this._observers = {}); |
| 755 o$[name] = observer; | 744 o$[name] = observer; |
| 756 }, | 745 }, |
| 757 closeNamedObserver: function(name) { | 746 unregisterObserver: function(name) { |
| 758 var o$ = this._namedObservers; | 747 var o$ = this._observers; |
| 759 if (o$ && o$[name]) { | 748 if (o$ && o$[name]) { |
| 760 o$[name].close(); | 749 o$[name].close(); |
| 761 o$[name] = null; | 750 o$[name] = null; |
| 762 return true; | 751 return true; |
| 763 } | 752 } |
| 764 }, | 753 }, |
| 765 closeNamedObservers: function() { | 754 unregisterObservers: function() { |
| 766 if (this._namedObservers) { | 755 if (this._observers) { |
| 767 var keys=Object.keys(this._namedObservers); | 756 var keys=Object.keys(this._observers); |
| 768 for (var i=0, l=keys.length, k, o; (i < l) && (k=keys[i]); i++) { | 757 for (var i=0, l=keys.length, k, o; (i < l) && (k=keys[i]); i++) { |
| 769 o = this._namedObservers[k]; | 758 o = this._observers[k]; |
| 770 o.close(); | 759 o.close(); |
| 771 } | 760 } |
| 772 this._namedObservers = {}; | 761 this._observers = {}; |
| 773 } | 762 } |
| 774 } | 763 } |
| 775 }; | 764 }; |
| 776 | 765 |
| 777 // property binding | 766 // property binding |
| 778 // bind a property in A to a path in B by converting A[property] to a | 767 // bind a property in A to a path in B by converting A[property] to a |
| 779 // getter/setter pair that accesses B[...path...] | 768 // getter/setter pair that accesses B[...path...] |
| 780 function bindProperties(inA, inProperty, observable) { | 769 function bindProperties(inA, inProperty, observable) { |
| 781 log.bind && console.log(LOG_BIND_PROPS, inB.localName || 'object', inPath, i
nA.localName, inProperty); | 770 log.bind && console.log(LOG_BIND_PROPS, inB.localName || 'object', inPath, i
nA.localName, inProperty); |
| 782 // capture A's value if B's value is null or undefined, | 771 // capture A's value if B's value is null or undefined, |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 835 node = node.parentNode; | 824 node = node.parentNode; |
| 836 } | 825 } |
| 837 return node.host; | 826 return node.host; |
| 838 }; | 827 }; |
| 839 | 828 |
| 840 // element api supporting mdv | 829 // element api supporting mdv |
| 841 | 830 |
| 842 var mdv = { | 831 var mdv = { |
| 843 syntax: syntax, | 832 syntax: syntax, |
| 844 instanceTemplate: function(template) { | 833 instanceTemplate: function(template) { |
| 845 var dom = template.createInstance(this, this.syntax); | 834 return template.createInstance(this, this.syntax); |
| 846 this.registerObservers(dom.bindings_); | |
| 847 return dom; | |
| 848 }, | 835 }, |
| 849 bind: function(name, observable, oneTime) { | 836 bind: function(name, observable, oneTime) { |
| 837 // note: binding is a prepare signal. This allows us to be sure that any |
| 838 // property changes that occur as a result of binding will be observed. |
| 839 if (!this._elementPrepared) { |
| 840 this.prepareElement(); |
| 841 } |
| 850 var property = this.propertyForAttribute(name); | 842 var property = this.propertyForAttribute(name); |
| 851 if (!property) { | 843 if (!property) { |
| 852 // TODO(sjmiles): this mixin method must use the special form | 844 // TODO(sjmiles): this mixin method must use the special form |
| 853 // of `super` installed by `mixinMethod` in declaration/prototype.js | 845 // of `super` installed by `mixinMethod` in declaration/prototype.js |
| 854 return this.mixinSuper(arguments); | 846 return this.mixinSuper(arguments); |
| 855 } else { | 847 } else { |
| 848 // clean out the closets |
| 849 this.unbind(name); |
| 856 // use n-way Polymer binding | 850 // use n-way Polymer binding |
| 857 var observer = this.bindProperty(property, observable); | 851 var observer = this.bindProperty(property, observable); |
| 852 // stick path on observer so it's available via this.bindings |
| 853 observer.path = observable.path_; |
| 854 // reflect bound property to attribute when binding |
| 855 // to ensure binding is not left on attribute if property |
| 856 // does not update due to not changing. |
| 858 this.reflectPropertyToAttribute(property); | 857 this.reflectPropertyToAttribute(property); |
| 859 // NOTE: reflecting binding information is typically required only for | 858 return this.bindings[name] = observer; |
| 860 // tooling. It has a performance cost so it's opt-in in Node.bind. | |
| 861 if (Platform.enableBindingsReflection) { | |
| 862 observer.path = observable.path_; | |
| 863 this.bindings_ = this.bindings_ || {}; | |
| 864 this.bindings_[name] = observer; | |
| 865 } | |
| 866 return observer; | |
| 867 } | 859 } |
| 868 }, | 860 }, |
| 869 // TODO(sorvell): unbind/unbindAll has been removed, as public api, from | |
| 870 // TemplateBinding. We still need to close/dispose of observers but perhaps | |
| 871 // we should choose a more explicit name. | |
| 872 asyncUnbindAll: function() { | 861 asyncUnbindAll: function() { |
| 873 if (!this._unbound) { | 862 if (!this._unbound) { |
| 874 log.unbind && console.log('[%s] asyncUnbindAll', this.localName); | 863 log.unbind && console.log('[%s] asyncUnbindAll', this.localName); |
| 875 this._unbindAllJob = this.job(this._unbindAllJob, this.unbindAll, 0); | 864 this._unbindAllJob = this.job(this._unbindAllJob, this.unbindAll, 0); |
| 876 } | 865 } |
| 877 }, | 866 }, |
| 878 unbindAll: function() { | 867 unbindAll: function() { |
| 879 if (!this._unbound) { | 868 if (!this._unbound) { |
| 880 this.closeObservers(); | 869 this.unbindAllProperties(); |
| 881 this.closeNamedObservers(); | 870 this.super(); |
| 871 // unbind shadowRoot |
| 872 var root = this.shadowRoot; |
| 873 while (root) { |
| 874 unbindNodeTree(root); |
| 875 root = root.olderShadowRoot; |
| 876 } |
| 882 this._unbound = true; | 877 this._unbound = true; |
| 883 } | 878 } |
| 884 }, | 879 }, |
| 885 cancelUnbindAll: function() { | 880 cancelUnbindAll: function(preventCascade) { |
| 886 if (this._unbound) { | 881 if (this._unbound) { |
| 887 log.unbind && console.warn('[%s] already unbound, cannot cancel unbindAl
l', this.localName); | 882 log.unbind && console.warn('[%s] already unbound, cannot cancel unbindAl
l', this.localName); |
| 888 return; | 883 return; |
| 889 } | 884 } |
| 890 log.unbind && console.log('[%s] cancelUnbindAll', this.localName); | 885 log.unbind && console.log('[%s] cancelUnbindAll', this.localName); |
| 891 if (this._unbindAllJob) { | 886 if (this._unbindAllJob) { |
| 892 this._unbindAllJob = this._unbindAllJob.stop(); | 887 this._unbindAllJob = this._unbindAllJob.stop(); |
| 893 } | 888 } |
| 889 // cancel unbinding our shadow tree iff we're not in the process of |
| 890 // cascading our tree (as we do, for example, when the element is inserted
). |
| 891 if (!preventCascade) { |
| 892 forNodeTree(this.shadowRoot, function(n) { |
| 893 if (n.cancelUnbindAll) { |
| 894 n.cancelUnbindAll(); |
| 895 } |
| 896 }); |
| 897 } |
| 894 } | 898 } |
| 895 }; | 899 }; |
| 896 | 900 |
| 897 function unbindNodeTree(node) { | 901 function unbindNodeTree(node) { |
| 898 forNodeTree(node, _nodeUnbindAll); | 902 forNodeTree(node, _nodeUnbindAll); |
| 899 } | 903 } |
| 900 | 904 |
| 901 function _nodeUnbindAll(node) { | 905 function _nodeUnbindAll(node) { |
| 902 node.unbindAll(); | 906 node.unbindAll(); |
| 903 } | 907 } |
| (...skipping 15 matching lines...) Expand all Loading... |
| 919 scope.api.instance.mdv = mdv; | 923 scope.api.instance.mdv = mdv; |
| 920 | 924 |
| 921 })(Polymer); | 925 })(Polymer); |
| 922 | 926 |
| 923 /* | 927 /* |
| 924 * Copyright 2013 The Polymer Authors. All rights reserved. | 928 * Copyright 2013 The Polymer Authors. All rights reserved. |
| 925 * Use of this source code is governed by a BSD-style | 929 * Use of this source code is governed by a BSD-style |
| 926 * license that can be found in the LICENSE file. | 930 * license that can be found in the LICENSE file. |
| 927 */ | 931 */ |
| 928 (function(scope) { | 932 (function(scope) { |
| 933 var preparingElements = 0; |
| 929 | 934 |
| 930 var base = { | 935 var base = { |
| 931 PolymerBase: true, | 936 PolymerBase: true, |
| 932 job: function(job, callback, wait) { | 937 job: Polymer.job, |
| 933 if (typeof job === 'string') { | |
| 934 var n = '___' + job; | |
| 935 this[n] = Polymer.job.call(this, this[n], callback, wait); | |
| 936 } else { | |
| 937 return Polymer.job.call(this, job, callback, wait); | |
| 938 } | |
| 939 }, | |
| 940 super: Polymer.super, | 938 super: Polymer.super, |
| 941 // user entry point for element has had its createdCallback called | 939 // user entry point for element has had its createdCallback called |
| 942 created: function() { | 940 created: function() { |
| 943 }, | 941 }, |
| 944 // user entry point for element has shadowRoot and is ready for | 942 // user entry point for element has shadowRoot and is ready for |
| 945 // api interaction | 943 // api interaction |
| 946 ready: function() { | 944 ready: function() { |
| 947 }, | 945 }, |
| 948 createdCallback: function() { | 946 createdCallback: function() { |
| 949 if (this.templateInstance && this.templateInstance.model) { | 947 this.created(); |
| 950 console.warn('Attributes on ' + this.localName + ' were data bound ' + | 948 if (this.ownerDocument.defaultView || this.alwaysPrepare || |
| 951 'prior to Polymer upgrading the element. This may result in ' + | 949 preparingElements > 0) { |
| 952 'incorrect binding types.'); | 950 this.prepareElement(); |
| 953 } | 951 } |
| 954 this.created(); | |
| 955 this.prepareElement(); | |
| 956 }, | 952 }, |
| 957 // system entry point, do not override | 953 // system entry point, do not override |
| 958 prepareElement: function() { | 954 prepareElement: function() { |
| 959 this._elementPrepared = true; | 955 this._elementPrepared = true; |
| 960 // install shadowRoots storage | 956 // install shadowRoots storage |
| 961 this.shadowRoots = {}; | 957 this.shadowRoots = {}; |
| 962 // storage for closeable observers. | |
| 963 this._observers = []; | |
| 964 // install property observers | 958 // install property observers |
| 965 this.observeProperties(); | 959 this.observeProperties(); |
| 966 // install boilerplate attributes | 960 // install boilerplate attributes |
| 967 this.copyInstanceAttributes(); | 961 this.copyInstanceAttributes(); |
| 968 // process input attributes | 962 // process input attributes |
| 969 this.takeAttributes(); | 963 this.takeAttributes(); |
| 970 // add event listeners | 964 // add event listeners |
| 971 this.addHostListeners(); | 965 this.addHostListeners(); |
| 966 // guarantees that while preparing, any |
| 967 // sub-elements are also prepared |
| 968 preparingElements++; |
| 972 // process declarative resources | 969 // process declarative resources |
| 973 this.parseDeclarations(this.__proto__); | 970 this.parseDeclarations(this.__proto__); |
| 971 // decrement semaphore |
| 972 preparingElements--; |
| 974 // TODO(sorvell): CE polyfill uses unresolved attribute to simulate | 973 // TODO(sorvell): CE polyfill uses unresolved attribute to simulate |
| 975 // :unresolved; remove this attribute to be compatible with native | 974 // :unresolved; remove this attribute to be compatible with native |
| 976 // CE. | 975 // CE. |
| 977 this.removeAttribute('unresolved'); | 976 this.removeAttribute('unresolved'); |
| 978 // user entry point | 977 // user entry point |
| 979 this.ready(); | 978 this.ready(); |
| 980 }, | 979 }, |
| 981 attachedCallback: function() { | 980 attachedCallback: function() { |
| 982 this.cancelUnbindAll(); | 981 if (!this._elementPrepared) { |
| 982 this.prepareElement(); |
| 983 } |
| 984 this.cancelUnbindAll(true); |
| 983 // invoke user action | 985 // invoke user action |
| 984 if (this.attached) { | 986 if (this.attached) { |
| 985 this.attached(); | 987 this.attached(); |
| 986 } | 988 } |
| 987 // TODO(sorvell): bc | 989 // TODO(sorvell): bc |
| 988 if (this.enteredView) { | 990 if (this.enteredView) { |
| 989 this.enteredView(); | 991 this.enteredView(); |
| 990 } | 992 } |
| 991 // NOTE: domReady can be used to access elements in dom (descendants, | 993 // NOTE: domReady can be used to access elements in dom (descendants, |
| 992 // ancestors, siblings) such that the developer is enured to upgrade | 994 // ancestors, siblings) such that the developer is enured to upgrade |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1033 if (p && p.element) { | 1035 if (p && p.element) { |
| 1034 this.parseDeclarations(p.__proto__); | 1036 this.parseDeclarations(p.__proto__); |
| 1035 p.parseDeclaration.call(this, p.element); | 1037 p.parseDeclaration.call(this, p.element); |
| 1036 } | 1038 } |
| 1037 }, | 1039 }, |
| 1038 // parse input <element> as needed, override for custom behavior | 1040 // parse input <element> as needed, override for custom behavior |
| 1039 parseDeclaration: function(elementElement) { | 1041 parseDeclaration: function(elementElement) { |
| 1040 var template = this.fetchTemplate(elementElement); | 1042 var template = this.fetchTemplate(elementElement); |
| 1041 if (template) { | 1043 if (template) { |
| 1042 var root = this.shadowFromTemplate(template); | 1044 var root = this.shadowFromTemplate(template); |
| 1043 this.shadowRoots[elementElement.name] = root; | 1045 this.shadowRoots[elementElement.name] = root; |
| 1044 } | 1046 } |
| 1045 }, | 1047 }, |
| 1046 // return a shadow-root template (if desired), override for custom behavior | 1048 // return a shadow-root template (if desired), override for custom behavior |
| 1047 fetchTemplate: function(elementElement) { | 1049 fetchTemplate: function(elementElement) { |
| 1048 return elementElement.querySelector('template'); | 1050 return elementElement.querySelector('template'); |
| 1049 }, | 1051 }, |
| 1050 // utility function that creates a shadow root from a <template> | 1052 // utility function that creates a shadow root from a <template> |
| 1051 shadowFromTemplate: function(template) { | 1053 shadowFromTemplate: function(template) { |
| 1052 if (template) { | 1054 if (template) { |
| 1053 // make a shadow root | 1055 // make a shadow root |
| 1054 var root = this.createShadowRoot(); | 1056 var root = this.createShadowRoot(); |
| 1057 // migrate flag(s) |
| 1058 root.resetStyleInheritance = this.resetStyleInheritance; |
| 1055 // stamp template | 1059 // stamp template |
| 1056 // which includes parsing and applying MDV bindings before being | 1060 // which includes parsing and applying MDV bindings before being |
| 1057 // inserted (to avoid {{}} in attribute values) | 1061 // inserted (to avoid {{}} in attribute values) |
| 1058 // e.g. to prevent <img src="images/{{icon}}"> from generating a 404. | 1062 // e.g. to prevent <img src="images/{{icon}}"> from generating a 404. |
| 1059 var dom = this.instanceTemplate(template); | 1063 var dom = this.instanceTemplate(template); |
| 1060 // append to shadow dom | 1064 // append to shadow dom |
| 1061 root.appendChild(dom); | 1065 root.appendChild(dom); |
| 1062 // perform post-construction initialization tasks on shadow root | 1066 // perform post-construction initialization tasks on shadow root |
| 1063 this.shadowRootReady(root, template); | 1067 this.shadowRootReady(root, template); |
| 1064 // return the created shadow root | 1068 // return the created shadow root |
| 1065 return root; | 1069 return root; |
| 1066 } | 1070 } |
| 1067 }, | 1071 }, |
| 1068 // utility function that stamps a <template> into light-dom | 1072 // utility function that stamps a <template> into light-dom |
| 1069 lightFromTemplate: function(template, refNode) { | 1073 lightFromTemplate: function(template) { |
| 1070 if (template) { | 1074 if (template) { |
| 1071 // TODO(sorvell): mark this element as a lightDOMController so that | 1075 // TODO(sorvell): mark this element as a lightDOMController so that |
| 1072 // event listeners on bound nodes inside it will be called on it. | 1076 // event listeners on bound nodes inside it will be called on it. |
| 1073 // Note, the expectation here is that events on all descendants | 1077 // Note, the expectation here is that events on all descendants |
| 1074 // should be handled by this element. | 1078 // should be handled by this element. |
| 1075 this.lightDomController = true; | 1079 this.lightDomController = true; |
| 1076 // stamp template | 1080 // stamp template |
| 1077 // which includes parsing and applying MDV bindings before being | 1081 // which includes parsing and applying MDV bindings before being |
| 1078 // inserted (to avoid {{}} in attribute values) | 1082 // inserted (to avoid {{}} in attribute values) |
| 1079 // e.g. to prevent <img src="images/{{icon}}"> from generating a 404. | 1083 // e.g. to prevent <img src="images/{{icon}}"> from generating a 404. |
| 1080 var dom = this.instanceTemplate(template); | 1084 var dom = this.instanceTemplate(template); |
| 1081 // append to shadow dom | 1085 // append to shadow dom |
| 1082 if (refNode) { | 1086 this.appendChild(dom); |
| 1083 this.insertBefore(dom, refNode); | |
| 1084 } else { | |
| 1085 this.appendChild(dom); | |
| 1086 } | |
| 1087 // perform post-construction initialization tasks on ahem, light root | 1087 // perform post-construction initialization tasks on ahem, light root |
| 1088 this.shadowRootReady(this); | 1088 this.shadowRootReady(this, template); |
| 1089 // return the created shadow root | 1089 // return the created shadow root |
| 1090 return dom; | 1090 return dom; |
| 1091 } | 1091 } |
| 1092 }, | 1092 }, |
| 1093 shadowRootReady: function(root) { | 1093 shadowRootReady: function(root, template) { |
| 1094 // locate nodes with id and store references to them in this.$ hash | 1094 // locate nodes with id and store references to them in this.$ hash |
| 1095 this.marshalNodeReferences(root); | 1095 this.marshalNodeReferences(root); |
| 1096 // set up pointer gestures | 1096 // set up pointer gestures |
| 1097 PointerGestures.register(root); | 1097 PointerGestures.register(root); |
| 1098 }, | 1098 }, |
| 1099 // locate nodes with id and store references to them in this.$ hash | 1099 // locate nodes with id and store references to them in this.$ hash |
| 1100 marshalNodeReferences: function(root) { | 1100 marshalNodeReferences: function(root) { |
| 1101 // establish $ instance variable | 1101 // establish $ instance variable |
| 1102 var $ = this.$ = this.$ || {}; | 1102 var $ = this.$ = this.$ || {}; |
| 1103 // populate $ from nodes with ID from the LOCAL tree | 1103 // populate $ from nodes with ID from the LOCAL tree |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1159 // magic words | 1159 // magic words |
| 1160 | 1160 |
| 1161 var STYLE_SCOPE_ATTRIBUTE = 'element'; | 1161 var STYLE_SCOPE_ATTRIBUTE = 'element'; |
| 1162 var STYLE_CONTROLLER_SCOPE = 'controller'; | 1162 var STYLE_CONTROLLER_SCOPE = 'controller'; |
| 1163 | 1163 |
| 1164 var styles = { | 1164 var styles = { |
| 1165 STYLE_SCOPE_ATTRIBUTE: STYLE_SCOPE_ATTRIBUTE, | 1165 STYLE_SCOPE_ATTRIBUTE: STYLE_SCOPE_ATTRIBUTE, |
| 1166 /** | 1166 /** |
| 1167 * Installs external stylesheets and <style> elements with the attribute | 1167 * Installs external stylesheets and <style> elements with the attribute |
| 1168 * polymer-scope='controller' into the scope of element. This is intended | 1168 * polymer-scope='controller' into the scope of element. This is intended |
| 1169 * to be a called during custom element construction. | 1169 * to be a called during custom element construction. Note, this incurs a |
| 1170 * per instance cost and should be used sparingly. |
| 1171 * |
| 1172 * The need for this type of styling should go away when the shadowDOM spec |
| 1173 * addresses these issues: |
| 1174 * |
| 1175 * https://www.w3.org/Bugs/Public/show_bug.cgi?id=21391 |
| 1176 * https://www.w3.org/Bugs/Public/show_bug.cgi?id=21390 |
| 1177 * https://www.w3.org/Bugs/Public/show_bug.cgi?id=21389 |
| 1178 * |
| 1179 * @param element The custom element instance into whose controller (parent) |
| 1180 * scope styles will be installed. |
| 1181 * @param elementElement The <element> containing controller styles. |
| 1170 */ | 1182 */ |
| 1183 // TODO(sorvell): remove when spec issues are addressed |
| 1171 installControllerStyles: function() { | 1184 installControllerStyles: function() { |
| 1172 // apply controller styles, but only if they are not yet applied | 1185 // apply controller styles, but only if they are not yet applied |
| 1173 var scope = this.findStyleScope(); | 1186 var scope = this.findStyleController(); |
| 1174 if (scope && !this.scopeHasNamedStyle(scope, this.localName)) { | 1187 if (scope && !this.scopeHasElementStyle(scope, STYLE_CONTROLLER_SCOPE)) { |
| 1175 // allow inherited controller styles | 1188 // allow inherited controller styles |
| 1176 var proto = getPrototypeOf(this), cssText = ''; | 1189 var proto = getPrototypeOf(this), cssText = ''; |
| 1177 while (proto && proto.element) { | 1190 while (proto && proto.element) { |
| 1178 cssText += proto.element.cssTextForScope(STYLE_CONTROLLER_SCOPE); | 1191 cssText += proto.element.cssTextForScope(STYLE_CONTROLLER_SCOPE); |
| 1179 proto = getPrototypeOf(proto); | 1192 proto = getPrototypeOf(proto); |
| 1180 } | 1193 } |
| 1181 if (cssText) { | 1194 if (cssText) { |
| 1182 this.installScopeCssText(cssText, scope); | 1195 var style = this.element.cssTextToScopeStyle(cssText, |
| 1196 STYLE_CONTROLLER_SCOPE); |
| 1197 // TODO(sorvell): for now these styles are not shimmed |
| 1198 // but we may need to shim them |
| 1199 Polymer.applyStyleToScope(style, scope); |
| 1183 } | 1200 } |
| 1184 } | 1201 } |
| 1185 }, | 1202 }, |
| 1186 installScopeStyle: function(style, name, scope) { | 1203 findStyleController: function() { |
| 1187 var scope = scope || this.findStyleScope(), name = name || ''; | 1204 if (window.ShadowDOMPolyfill) { |
| 1188 if (scope && !this.scopeHasNamedStyle(scope, this.localName + name)) { | 1205 return wrap(document.head); |
| 1189 var cssText = ''; | 1206 } else { |
| 1190 if (style instanceof Array) { | 1207 // find the shadow root that contains this element |
| 1191 for (var i=0, l=style.length, s; (i<l) && (s=style[i]); i++) { | 1208 var n = this; |
| 1192 cssText += s.textContent + '\n\n'; | 1209 while (n.parentNode) { |
| 1193 } | 1210 n = n.parentNode; |
| 1194 } else { | |
| 1195 cssText = style.textContent; | |
| 1196 } | 1211 } |
| 1197 this.installScopeCssText(cssText, scope, name); | 1212 return n === document ? document.head : n; |
| 1198 } | 1213 } |
| 1199 }, | 1214 }, |
| 1200 installScopeCssText: function(cssText, scope, name) { | 1215 scopeHasElementStyle: function(scope, descriptor) { |
| 1201 scope = scope || this.findStyleScope(); | 1216 var rule = STYLE_SCOPE_ATTRIBUTE + '=' + this.localName + '-' + descriptor
; |
| 1202 name = name || ''; | 1217 return scope.querySelector('style[' + rule + ']'); |
| 1203 if (!scope) { | |
| 1204 return; | |
| 1205 } | |
| 1206 if (window.ShadowDOMPolyfill) { | |
| 1207 cssText = shimCssText(cssText, scope.host); | |
| 1208 } | |
| 1209 var style = this.element.cssTextToScopeStyle(cssText, | |
| 1210 STYLE_CONTROLLER_SCOPE); | |
| 1211 Polymer.applyStyleToScope(style, scope); | |
| 1212 // cache that this style has been applied | |
| 1213 scope._scopeStyles[this.localName + name] = true; | |
| 1214 }, | |
| 1215 findStyleScope: function(node) { | |
| 1216 // find the shadow root that contains this element | |
| 1217 var n = node || this; | |
| 1218 while (n.parentNode) { | |
| 1219 n = n.parentNode; | |
| 1220 } | |
| 1221 return n; | |
| 1222 }, | |
| 1223 scopeHasNamedStyle: function(scope, name) { | |
| 1224 scope._scopeStyles = scope._scopeStyles || {}; | |
| 1225 return scope._scopeStyles[name]; | |
| 1226 } | 1218 } |
| 1227 }; | 1219 }; |
| 1228 | 1220 |
| 1229 // NOTE: use raw prototype traversal so that we ensure correct traversal | 1221 // NOTE: use raw prototype traversal so that we ensure correct traversal |
| 1230 // on platforms where the protoype chain is simulated via __proto__ (IE10) | 1222 // on platforms where the protoype chain is simulated via __proto__ (IE10) |
| 1231 function getPrototypeOf(prototype) { | 1223 function getPrototypeOf(prototype) { |
| 1232 return prototype.__proto__; | 1224 return prototype.__proto__; |
| 1233 } | 1225 } |
| 1234 | 1226 |
| 1235 function shimCssText(cssText, host) { | |
| 1236 var name = '', is = false; | |
| 1237 if (host) { | |
| 1238 name = host.localName; | |
| 1239 is = host.hasAttribute('is'); | |
| 1240 } | |
| 1241 var selector = Platform.ShadowCSS.makeScopeSelector(name, is); | |
| 1242 return Platform.ShadowCSS.shimCssText(cssText, selector); | |
| 1243 } | |
| 1244 | |
| 1245 // exports | 1227 // exports |
| 1246 | 1228 |
| 1247 scope.api.instance.styles = styles; | 1229 scope.api.instance.styles = styles; |
| 1248 | 1230 |
| 1249 })(Polymer); | 1231 })(Polymer); |
| 1250 | 1232 |
| 1251 /* | 1233 /* |
| 1252 * Copyright 2013 The Polymer Authors. All rights reserved. | 1234 * Copyright 2013 The Polymer Authors. All rights reserved. |
| 1253 * Use of this source code is governed by a BSD-style | 1235 * Use of this source code is governed by a BSD-style |
| 1254 * license that can be found in the LICENSE file. | 1236 * license that can be found in the LICENSE file. |
| 1255 */ | 1237 */ |
| 1256 (function(scope) { | 1238 (function(scope) { |
| 1257 | 1239 |
| 1258 // imports | 1240 // imports |
| 1259 | 1241 |
| 1260 var extend = scope.extend; | 1242 var extend = scope.extend; |
| 1261 var api = scope.api; | 1243 var api = scope.api; |
| 1262 | 1244 |
| 1263 // imperative implementation: Polymer() | 1245 // imperative implementation: Polymer() |
| 1264 | 1246 |
| 1265 // specify an 'own' prototype for tag `name` | 1247 // specify an 'own' prototype for tag `name` |
| 1266 function element(name, prototype) { | 1248 function element(name, prototype) { |
| 1267 if (arguments.length === 1 && typeof arguments[0] !== 'string') { | |
| 1268 prototype = name; | |
| 1269 var script = document._currentScript; | |
| 1270 name = script && script.parentNode && script.parentNode.getAttribute ? | |
| 1271 script.parentNode.getAttribute('name') : ''; | |
| 1272 if (!name) { | |
| 1273 throw 'Element name could not be inferred.'; | |
| 1274 } | |
| 1275 } | |
| 1276 if (getRegisteredPrototype[name]) { | 1249 if (getRegisteredPrototype[name]) { |
| 1277 throw 'Already registered (Polymer) prototype for element ' + name; | 1250 throw 'Already registered (Polymer) prototype for element ' + name; |
| 1278 } | 1251 } |
| 1279 // cache the prototype | 1252 // cache the prototype |
| 1280 registerPrototype(name, prototype); | 1253 registerPrototype(name, prototype); |
| 1281 // notify the registrar waiting for 'name', if any | 1254 // notify the registrar waiting for 'name', if any |
| 1282 notifyPrototype(name); | 1255 notifyPrototype(name); |
| 1283 } | 1256 } |
| 1284 | 1257 |
| 1285 // async prototype source | 1258 // async prototype source |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1415 var s$ = root.querySelectorAll(SHEET_SELECTOR); | 1388 var s$ = root.querySelectorAll(SHEET_SELECTOR); |
| 1416 for (var i=0, l=s$.length, s, c; (i<l) && (s=s$[i]); i++) { | 1389 for (var i=0, l=s$.length, s, c; (i<l) && (s=s$[i]); i++) { |
| 1417 c = createStyleElement(importRuleForSheet(s, this.ownerDocument.baseURI)
, | 1390 c = createStyleElement(importRuleForSheet(s, this.ownerDocument.baseURI)
, |
| 1418 this.ownerDocument); | 1391 this.ownerDocument); |
| 1419 this.copySheetAttributes(c, s); | 1392 this.copySheetAttributes(c, s); |
| 1420 s.parentNode.replaceChild(c, s); | 1393 s.parentNode.replaceChild(c, s); |
| 1421 } | 1394 } |
| 1422 }, | 1395 }, |
| 1423 copySheetAttributes: function(style, link) { | 1396 copySheetAttributes: function(style, link) { |
| 1424 for (var i=0, a$=link.attributes, l=a$.length, a; (a=a$[i]) && i<l; i++) { | 1397 for (var i=0, a$=link.attributes, l=a$.length, a; (a=a$[i]) && i<l; i++) { |
| 1425 if (a.name !== 'rel' && a.name !== 'href') { | 1398 if (a.name !== 'rel' && a.name !== 'src') { |
| 1426 style.setAttribute(a.name, a.value); | 1399 style.setAttribute(a.name, a.value); |
| 1427 } | 1400 } |
| 1428 } | 1401 } |
| 1429 }, | 1402 }, |
| 1430 findLoadableStyles: function(root) { | 1403 findLoadableStyles: function(root) { |
| 1431 var loadables = []; | 1404 var loadables = []; |
| 1432 if (root) { | 1405 if (root) { |
| 1433 var s$ = root.querySelectorAll(STYLE_SELECTOR); | 1406 var s$ = root.querySelectorAll(STYLE_SELECTOR); |
| 1434 for (var i=0, l=s$.length, s; (i<l) && (s=s$[i]); i++) { | 1407 for (var i=0, l=s$.length, s; (i<l) && (s=s$[i]); i++) { |
| 1435 if (s.textContent.match(STYLE_LOADABLE_MATCH)) { | 1408 if (s.textContent.match(STYLE_LOADABLE_MATCH)) { |
| 1436 loadables.push(s); | 1409 loadables.push(s); |
| 1437 } | 1410 } |
| 1438 } | 1411 } |
| 1439 } | 1412 } |
| 1440 return loadables; | 1413 return loadables; |
| 1441 }, | 1414 }, |
| 1442 /** | 1415 /** |
| 1443 * Install external stylesheets loaded in <polymer-element> elements into th
e | 1416 * Install external stylesheets loaded in <polymer-element> elements into th
e |
| 1444 * element's template. | 1417 * element's template. |
| 1445 * @param elementElement The <element> element to style. | 1418 * @param elementElement The <element> element to style. |
| 1446 */ | 1419 */ |
| 1420 // TODO(sorvell): wip... caching and styles handling can probably be removed |
| 1421 // We need a scheme to ensure stylesheets are eagerly loaded without |
| 1422 // the creation of an element instance. Here are 2 options for handling this
: |
| 1423 // 1. create a dummy element with ShadowDOM in dom that includes ALL styles |
| 1424 // processed here. |
| 1425 // 2. place stylesheets outside the element template. This will allow |
| 1426 // imports to naturally load the sheets. Then at load time, we can remove |
| 1427 // the stylesheet from dom. |
| 1447 installSheets: function() { | 1428 installSheets: function() { |
| 1448 this.cacheSheets(); | 1429 this.cacheSheets(); |
| 1449 this.cacheStyles(); | 1430 this.cacheStyles(); |
| 1450 this.installLocalSheets(); | 1431 this.installLocalSheets(); |
| 1451 this.installGlobalStyles(); | 1432 this.installGlobalStyles(); |
| 1452 }, | 1433 }, |
| 1453 /** | 1434 /** |
| 1454 * Remove all sheets from element and store for later use. | 1435 * Remove all sheets from element and store for later use. |
| 1455 */ | 1436 */ |
| 1456 cacheSheets: function() { | 1437 cacheSheets: function() { |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1547 var style = createStyleElement(cssText); | 1528 var style = createStyleElement(cssText); |
| 1548 style.setAttribute(STYLE_SCOPE_ATTRIBUTE, this.getAttribute('name') + | 1529 style.setAttribute(STYLE_SCOPE_ATTRIBUTE, this.getAttribute('name') + |
| 1549 '-' + scopeDescriptor); | 1530 '-' + scopeDescriptor); |
| 1550 return style; | 1531 return style; |
| 1551 } | 1532 } |
| 1552 } | 1533 } |
| 1553 }; | 1534 }; |
| 1554 | 1535 |
| 1555 function importRuleForSheet(sheet, baseUrl) { | 1536 function importRuleForSheet(sheet, baseUrl) { |
| 1556 var href = new URL(sheet.getAttribute('href'), baseUrl).href; | 1537 var href = new URL(sheet.getAttribute('href'), baseUrl).href; |
| 1557 return '@import \'' + href + '\';'; | 1538 return '@import \'' + href + '\';' |
| 1558 } | 1539 } |
| 1559 | 1540 |
| 1560 function applyStyleToScope(style, scope) { | 1541 function applyStyleToScope(style, scope) { |
| 1561 if (style) { | 1542 if (style) { |
| 1562 if (scope === document) { | |
| 1563 scope = document.head; | |
| 1564 } | |
| 1565 if (window.ShadowDOMPolyfill) { | |
| 1566 scope = document.head; | |
| 1567 } | |
| 1568 // TODO(sorvell): necessary for IE | 1543 // TODO(sorvell): necessary for IE |
| 1569 // see https://connect.microsoft.com/IE/feedback/details/790212/ | 1544 // see https://connect.microsoft.com/IE/feedback/details/790212/ |
| 1570 // cloning-a-style-element-and-adding-to-document-produces | 1545 // cloning-a-style-element-and-adding-to-document-produces |
| 1571 // -unexpected-result#details | 1546 // -unexpected-result#details |
| 1572 // var clone = style.cloneNode(true); | 1547 // var clone = style.cloneNode(true); |
| 1573 var clone = createStyleElement(style.textContent); | 1548 var clone = createStyleElement(style.textContent); |
| 1574 var attr = style.getAttribute(STYLE_SCOPE_ATTRIBUTE); | 1549 var attr = style.getAttribute(STYLE_SCOPE_ATTRIBUTE); |
| 1575 if (attr) { | 1550 if (attr) { |
| 1576 clone.setAttribute(STYLE_SCOPE_ATTRIBUTE, attr); | 1551 clone.setAttribute(STYLE_SCOPE_ATTRIBUTE, attr); |
| 1577 } | 1552 } |
| 1578 // TODO(sorvell): probably too brittle; try to figure out | 1553 scope.appendChild(clone); |
| 1579 // where to put the element. | |
| 1580 var refNode = scope.firstElementChild; | |
| 1581 if (scope === document.head) { | |
| 1582 var selector = 'style[' + STYLE_SCOPE_ATTRIBUTE + ']'; | |
| 1583 var s$ = document.head.querySelectorAll(selector); | |
| 1584 if (s$.length) { | |
| 1585 refNode = s$[s$.length-1].nextElementSibling; | |
| 1586 } | |
| 1587 } | |
| 1588 scope.insertBefore(clone, refNode); | |
| 1589 } | 1554 } |
| 1590 } | 1555 } |
| 1591 | 1556 |
| 1592 function createStyleElement(cssText, scope) { | 1557 function createStyleElement(cssText, scope) { |
| 1593 scope = scope || document; | 1558 scope = scope || document; |
| 1594 scope = scope.createElement ? scope : scope.ownerDocument; | 1559 scope = scope.createElement ? scope : scope.ownerDocument; |
| 1595 var style = scope.createElement('style'); | 1560 var style = scope.createElement('style'); |
| 1596 style.textContent = cssText; | 1561 style.textContent = cssText; |
| 1597 return style; | 1562 return style; |
| 1598 } | 1563 } |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1704 }, | 1669 }, |
| 1705 optimizePropertyMaps: function(prototype) { | 1670 optimizePropertyMaps: function(prototype) { |
| 1706 if (prototype.observe) { | 1671 if (prototype.observe) { |
| 1707 // construct name list | 1672 // construct name list |
| 1708 var a = prototype._observeNames = []; | 1673 var a = prototype._observeNames = []; |
| 1709 for (var n in prototype.observe) { | 1674 for (var n in prototype.observe) { |
| 1710 var names = n.split(' '); | 1675 var names = n.split(' '); |
| 1711 for (var i=0, ni; ni=names[i]; i++) { | 1676 for (var i=0, ni; ni=names[i]; i++) { |
| 1712 a.push(ni); | 1677 a.push(ni); |
| 1713 } | 1678 } |
| 1679 //a.push(n); |
| 1714 } | 1680 } |
| 1715 } | 1681 } |
| 1716 if (prototype.publish) { | 1682 if (prototype.publish) { |
| 1717 // construct name list | 1683 // construct name list |
| 1718 var a = prototype._publishNames = []; | 1684 var a = prototype._publishNames = []; |
| 1719 for (var n in prototype.publish) { | 1685 for (var n in prototype.publish) { |
| 1720 a.push(n); | 1686 a.push(n); |
| 1721 } | 1687 } |
| 1722 } | 1688 } |
| 1723 }, | 1689 }, |
| (...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2090 } | 2056 } |
| 2091 return (this.indexOf(element) !== 0); | 2057 return (this.indexOf(element) !== 0); |
| 2092 }, | 2058 }, |
| 2093 add: function(element) { | 2059 add: function(element) { |
| 2094 //console.log('queueing', element.name); | 2060 //console.log('queueing', element.name); |
| 2095 queueForElement(element).push(element); | 2061 queueForElement(element).push(element); |
| 2096 }, | 2062 }, |
| 2097 indexOf: function(element) { | 2063 indexOf: function(element) { |
| 2098 var i = queueForElement(element).indexOf(element); | 2064 var i = queueForElement(element).indexOf(element); |
| 2099 if (i >= 0 && document.contains(element)) { | 2065 if (i >= 0 && document.contains(element)) { |
| 2100 i += (HTMLImports.useNative || HTMLImports.ready) ? | 2066 i += (HTMLImports.useNative || HTMLImports.ready) ? importQueue.length : |
| 2101 importQueue.length : 1e9; | 2067 1e9; |
| 2102 } | 2068 } |
| 2103 return i; | 2069 return i; |
| 2104 }, | 2070 }, |
| 2105 // tell the queue an element is ready to be registered | 2071 // tell the queue an element is ready to be registered |
| 2106 go: function(element) { | 2072 go: function(element) { |
| 2107 var readied = this.remove(element); | 2073 var readied = this.remove(element); |
| 2108 if (readied) { | 2074 if (readied) { |
| 2109 readied.__go.call(readied); | 2075 readied.__go.call(readied); |
| 2110 readied.__check = readied.__go = null; | 2076 readied.__check = readied.__go = null; |
| 2111 this.check(); | 2077 this.check(); |
| 2112 } | 2078 } |
| 2113 }, | 2079 }, |
| 2114 remove: function(element) { | 2080 remove: function(element) { |
| 2115 var i = this.indexOf(element); | 2081 var i = this.indexOf(element); |
| 2116 if (i !== 0) { | 2082 if (i !== 0) { |
| 2117 //console.warn('queue order wrong', i); | 2083 //console.warn('queue order wrong', i); |
| 2118 return; | 2084 return; |
| 2119 } | 2085 } |
| 2120 return queueForElement(element).shift(); | 2086 return queueForElement(element).shift(); |
| 2121 }, | 2087 }, |
| 2122 check: function() { | 2088 check: function() { |
| 2123 // next | 2089 // next |
| 2124 var element = this.nextElement(); | 2090 var element = this.nextElement(); |
| 2125 if (element) { | 2091 if (element) { |
| 2126 element.__check.call(element); | 2092 element.__check.call(element); |
| 2127 } | 2093 } |
| 2128 if (this.canReady()) { | 2094 if (this.canReady()) { |
| 2129 this.ready(); | 2095 this.ready(); |
| 2130 return true; | 2096 return true; |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2274 this.registerWhenReady(); | 2240 this.registerWhenReady(); |
| 2275 }, | 2241 }, |
| 2276 | 2242 |
| 2277 registerWhenReady: function() { | 2243 registerWhenReady: function() { |
| 2278 if (this.registered | 2244 if (this.registered |
| 2279 || this.waitingForPrototype(this.name) | 2245 || this.waitingForPrototype(this.name) |
| 2280 || this.waitingForQueue() | 2246 || this.waitingForQueue() |
| 2281 || this.waitingForResources()) { | 2247 || this.waitingForResources()) { |
| 2282 return; | 2248 return; |
| 2283 } | 2249 } |
| 2284 // TODO(sorvell): ends up calling '_register' by virtue | |
| 2285 // of `waitingForQueue` (see below) | |
| 2286 queue.go(this); | 2250 queue.go(this); |
| 2287 }, | 2251 }, |
| 2288 | 2252 |
| 2253 |
| 2289 // TODO(sorvell): refactor, this method is private-ish, but it's being | 2254 // TODO(sorvell): refactor, this method is private-ish, but it's being |
| 2290 // called by the queue object. | 2255 // called by the queue object. |
| 2291 _register: function() { | 2256 _register: function() { |
| 2292 //console.log('registering', this.name); | 2257 //console.log('registering', this.name); |
| 2293 //console.group('registering', this.name); | 2258 //console.group('registering', this.name); |
| 2294 // warn if extending from a custom element not registered via Polymer | 2259 // warn if extending from a custom element not registered via Polymer |
| 2295 if (isCustomTag(this.extends) && !isRegistered(this.extends)) { | 2260 if (isCustomTag(this.extends) && !isRegistered(this.extends)) { |
| 2296 console.warn('%s is attempting to extend %s, an unregistered element ' + | 2261 console.warn('%s is attempting to extend %s, an unregistered element ' + |
| 2297 'or one that was not registered with Polymer.', this.name, | 2262 'or one that was not registered with Polymer.', this.name, |
| 2298 this.extends); | 2263 this.extends); |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2383 ); | 2348 ); |
| 2384 }); | 2349 }); |
| 2385 | 2350 |
| 2386 // register polymer-element with document | 2351 // register polymer-element with document |
| 2387 | 2352 |
| 2388 document.registerElement('polymer-element', {prototype: prototype}); | 2353 document.registerElement('polymer-element', {prototype: prototype}); |
| 2389 | 2354 |
| 2390 })(Polymer); | 2355 })(Polymer); |
| 2391 | 2356 |
| 2392 //# sourceMappingURL=polymer.concat.js.map | 2357 //# sourceMappingURL=polymer.concat.js.map |
| OLD | NEW |