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

Side by Side Diff: pkg/polymer/lib/src/js/polymer/polymer.concat.js

Issue 221813011: [web_components] update web_components and polymer.js (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698