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 |