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