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

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

Issue 221653004: "Reverting 34633" (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 : ~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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « pkg/polymer/lib/src/js/polymer/polymer.js ('k') | pkg/polymer/lib/src/js/polymer/polymer.concat.js.map » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698