From 83834aff18eb13d9e67a487542515daf11de65e1 Mon Sep 17 00:00:00 2001 From: Kevin Schaaf Date: Tue, 28 Aug 2018 14:48:13 -0400 Subject: [PATCH 1/7] Upstream changes to externs --- externs/polymer-externs.js | 17 ++++++++++++++++- externs/webcomponents-externs.js | 16 ++++++++-------- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/externs/polymer-externs.js b/externs/polymer-externs.js index 7c0ede16aa..45d21181d0 100644 --- a/externs/polymer-externs.js +++ b/externs/polymer-externs.js @@ -78,6 +78,21 @@ function Polymer(init){} */ Polymer.sanitizeDOMValue; +/** + * @type {boolean} + */ +Polymer.passiveTouchGestures; + +/** + * @type {boolean} + */ +Polymer.strictTemplatePolicy; + +/** + * @type {boolean} + */ +Polymer.allowTemplateFromDomModule; + /** * @param {string} string * @param {Object} obj @@ -172,7 +187,7 @@ var PolymerDeepPropertyChange; * @constructor * @template T */ -let DomRepeatEvent = function() {}; +var DomRepeatEvent = function() {}; /** * @type {{ diff --git a/externs/webcomponents-externs.js b/externs/webcomponents-externs.js index 8bcf4cede5..029cf4fea4 100644 --- a/externs/webcomponents-externs.js +++ b/externs/webcomponents-externs.js @@ -12,37 +12,37 @@ */ /* eslint-disable */ -let HTMLImports = { +var HTMLImports = { /** * @param {function()} callback */ - whenReady(callback){}, + whenReady(callback) {}, /** * @param {Element} element * @returns {Document} document */ - importForElement(element){} + importForElement(element) {} }; window.HTMLImports = HTMLImports; -let ShadyDOM = { +var ShadyDOM = { inUse: false, - flush(){}, + flush() {}, /** * @param {!Node} target * @param {function(Array, MutationObserver)} callback * @return {MutationObserver} */ - observeChildren(target, callback){}, + observeChildren(target, callback) {}, /** * @param {MutationObserver} observer */ - unobserveChildren(observer){}, + unobserveChildren(observer) {}, /** * @param {Node} node */ - patch(node){} + patch(node) {} }; window.ShadyDOM = ShadyDOM; From b4d6e70a1168d81781a455d19b748cfd73d22246 Mon Sep 17 00:00:00 2001 From: Kevin Schaaf Date: Tue, 28 Aug 2018 17:53:27 -0400 Subject: [PATCH 2/7] Upstream warning text. --- lib/legacy/legacy-data-mixin.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/legacy/legacy-data-mixin.js b/lib/legacy/legacy-data-mixin.js index 5aee1e0209..2d18397d6a 100644 --- a/lib/legacy/legacy-data-mixin.js +++ b/lib/legacy/legacy-data-mixin.js @@ -40,7 +40,7 @@ function wrapEffect(effect, fnName) { fn.apply(this, arguments); } catch (e) { if (e instanceof UndefinedArgumentError) { - console.warn(`Argument '${e.arg}'${fnName ?` for method '${fnName}'` : ''} was undefined. Ensure it has an undefined check.`); + console.warn(`Argument '${e.arg}'${fnName ?` for method '${fnName}'` : ''} was undefined. Ensure it has a default value, or else ensure the method handles the argument being undefined.`); } else { throw e; } @@ -98,7 +98,7 @@ export const LegacyDataMixin = dedupingMixin(superClass => { // Break out of effect's control flow; will be caught in // wrapped property effect function below const name = args[i].name; - throw new UndefinedArgumentError(`Argument '${name}' is undefined. Ensure it has an undefined check.`, name); + throw new UndefinedArgumentError(`Argument '${name}' is undefined.`, name); } } } From e69c8b3c6e2bc58800f35a83089da806a6d8aa7c Mon Sep 17 00:00:00 2001 From: Kevin Schaaf Date: Tue, 28 Aug 2018 20:23:59 -0400 Subject: [PATCH 3/7] Fix jsdoc comment --- lib/legacy/legacy-data-mixin.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/legacy/legacy-data-mixin.js b/lib/legacy/legacy-data-mixin.js index 2d18397d6a..3c61115f25 100644 --- a/lib/legacy/legacy-data-mixin.js +++ b/lib/legacy/legacy-data-mixin.js @@ -75,7 +75,8 @@ export const LegacyDataMixin = dedupingMixin(superClass => { * @constructor * @extends {superClass} * @unrestricted - * @private */ + * @private + */ class LegacyDataMixin extends superClass { /** * Overrides `Polymer.PropertyEffects` to add `undefined` argument From 566dcfaefe60cd560fa77250d6301b71fc551aa7 Mon Sep 17 00:00:00 2001 From: Peter Burns Date: Sun, 4 Nov 2018 13:29:04 -0800 Subject: [PATCH 4/7] Get Polymer compiling clean under closure recommended flags With these changes we have zero errors and zero warnings with `RECOMMENDED_FLAGS`! Most of the changes were adding `@override` for methods and properties in mixins. Apparently if you implement an interface you need to say `@override` for each method or property on the interface. This combines with our mixin strategy to the tune of needing to add `@override` on every non-private method and property. I'm not sure this is intended behavior of the compiler. Filed https://github.com/google/closure-compiler/issues/3137 to see if it is. --- externs/polymer-externs.js | 23 +++- lib/elements/array-selector.js | 26 ++--- lib/legacy/legacy-data-mixin.js | 25 ++-- lib/legacy/legacy-element-mixin.js | 121 +++++++++++++++----- lib/mixins/dir-mixin.js | 15 ++- lib/mixins/disable-upgrade-mixin.js | 18 ++- lib/mixins/element-mixin.js | 39 ++++--- lib/mixins/properties-changed.js | 3 +- lib/mixins/property-accessors.js | 37 +++--- lib/mixins/property-effects.js | 171 ++++++++++++++++++---------- lib/utils/style-gather.js | 5 +- lib/utils/templatize.js | 24 +++- 12 files changed, 337 insertions(+), 170 deletions(-) diff --git a/externs/polymer-externs.js b/externs/polymer-externs.js index 0a4aa90272..8c426f3703 100644 --- a/externs/polymer-externs.js +++ b/externs/polymer-externs.js @@ -48,6 +48,7 @@ PolymerInit.prototype.hostAttributes; /** @type {(!Object | undefined)} */ PolymerInit.prototype.listeners; +/** @record */ let PolymerElementConstructor = function () {}; /** @type {(string | undefined)} */ PolymerElementConstructor.is; @@ -78,6 +79,26 @@ function Polymer(init){} */ Polymer.sanitizeDOMValue; +/** + * @type {boolean} + */ +Polymer.passiveTouchGestures; + +/** + * @type {boolean} + */ +Polymer.strictTemplatePolicy; + +/** + * @type {boolean} + */ +Polymer.allowTemplateFromDomModule; + +/** + * @type {string} + */ +Polymer.rootPath; + /** * @param {string} string * @param {Object} obj @@ -174,7 +195,7 @@ var PolymerDeepPropertyChange; * @constructor * @template T */ -let DomRepeatEvent = function() {}; +var DomRepeatEvent = function() {}; /** * @type {{ diff --git a/lib/elements/array-selector.js b/lib/elements/array-selector.js index 51a553c670..c4a9816749 100644 --- a/lib/elements/array-selector.js +++ b/lib/elements/array-selector.js @@ -37,7 +37,6 @@ let ArraySelectorMixin = dedupingMixin(superClass => { /** * @constructor - * @extends {superClass} * @implements {Polymer_ElementMixin} * @private */ @@ -52,7 +51,6 @@ let ArraySelectorMixin = dedupingMixin(superClass => { class ArraySelectorMixin extends elementBase { static get properties() { - return { /** @@ -76,31 +74,22 @@ let ArraySelectorMixin = dedupingMixin(superClass => { * When `multi` is true, this is an array that contains any selected. * When `multi` is false, this is the currently selected item, or `null` * if no item is selected. - * @type {?(Object|Array)} + * @type {?Object|?Array} */ - selected: { - type: Object, - notify: true - }, + selected: {type: Object, notify: true}, /** * When `multi` is false, this is the currently selected item, or `null` * if no item is selected. * @type {?Object} */ - selectedItem: { - type: Object, - notify: true - }, + selectedItem: {type: Object, notify: true}, /** * When `true`, calling `select` on an item that is already selected * will deselect the item. */ - toggle: { - type: Boolean, - value: false - } + toggle: {type: Boolean, value: false} }; } @@ -208,6 +197,7 @@ let ArraySelectorMixin = dedupingMixin(superClass => { /** * Clears the selection state. + * @override * @return {void} */ clearSelection() { @@ -226,6 +216,7 @@ let ArraySelectorMixin = dedupingMixin(superClass => { /** * Returns whether the item is currently selected. * + * @override * @param {*} item Item from `items` array to test * @return {boolean} Whether the item is selected */ @@ -236,6 +227,7 @@ let ArraySelectorMixin = dedupingMixin(superClass => { /** * Returns whether the item is currently selected. * + * @override * @param {number} idx Index from `items` array to test * @return {boolean} Whether the item is selected */ @@ -265,6 +257,7 @@ let ArraySelectorMixin = dedupingMixin(superClass => { /** * Deselects the given item if it is already selected. * + * @override * @param {*} item Item from `items` array to deselect * @return {void} */ @@ -288,6 +281,7 @@ let ArraySelectorMixin = dedupingMixin(superClass => { /** * Deselects the given index if it is already selected. * + * @override * @param {number} idx Index from `items` array to deselect * @return {void} */ @@ -299,6 +293,7 @@ let ArraySelectorMixin = dedupingMixin(superClass => { * Selects the given item. When `toggle` is true, this will automatically * deselect the item if already selected. * + * @override * @param {*} item Item from `items` array to select * @return {void} */ @@ -310,6 +305,7 @@ let ArraySelectorMixin = dedupingMixin(superClass => { * Selects the given index. When `toggle` is true, this will automatically * deselect the item if already selected. * + * @override * @param {number} idx Index from `items` array to select * @return {void} */ diff --git a/lib/legacy/legacy-data-mixin.js b/lib/legacy/legacy-data-mixin.js index 5aee1e0209..9f8fbe0049 100644 --- a/lib/legacy/legacy-data-mixin.js +++ b/lib/legacy/legacy-data-mixin.js @@ -27,10 +27,10 @@ const UndefinedArgumentError = class extends Error { /** * Wraps effect functions to catch `UndefinedArgumentError`s and warn. - * + * * @param {Object=} effect Effect metadata object * @param {Object=} fnName Name of user function, if known - * @return {?Object} Effect metadata object + * @return {?Object|undefined} Effect metadata object */ function wrapEffect(effect, fnName) { if (effect && effect.fn) { @@ -54,11 +54,11 @@ function wrapEffect(effect, fnName) { * Mixin to selectively add back Polymer 1.x's `undefined` rules * governing when observers & computing functions run based * on all arguments being defined (reference https://www.polymer-project.org/1.0/docs/devguide/observers#multi-property-observers). - * + * * When loaded, all legacy elements (defined with `Polymer({...})`) * will have the mixin applied. The mixin only restores legacy data handling * if `_legacyUndefinedCheck: true` is set on the element's prototype. - * + * * This mixin is intended for use to help migration from Polymer 1.x to * 2.x+ by allowing legacy code to work while identifying observers and * computing functions that need undefined checks to work without @@ -72,15 +72,14 @@ function wrapEffect(effect, fnName) { export const LegacyDataMixin = dedupingMixin(superClass => { /** - * @constructor - * @extends {superClass} * @unrestricted - * @private */ + * @private + */ class LegacyDataMixin extends superClass { /** * Overrides `Polymer.PropertyEffects` to add `undefined` argument * checking to match Polymer 1.x style rules - * + * * @param {!Array} args Array of argument metadata * @param {string} path Property/path name that triggered the method effect * @param {Object} props Bag of current property changes @@ -98,7 +97,7 @@ export const LegacyDataMixin = dedupingMixin(superClass => { // Break out of effect's control flow; will be caught in // wrapped property effect function below const name = args[i].name; - throw new UndefinedArgumentError(`Argument '${name}' is undefined. Ensure it has an undefined check.`, name); + throw new UndefinedArgumentError(`Argument '${name}' is undefined.`, name); } } } @@ -108,7 +107,7 @@ export const LegacyDataMixin = dedupingMixin(superClass => { /** * Overrides `Polyer.PropertyEffects` to wrap effect functions to * catch `UndefinedArgumentError`s and warn. - * + * * @param {string} property Property that should trigger the effect * @param {string} type Effect type, from this.PROPERTY_EFFECT_TYPES * @param {Object=} effect Effect metadata object @@ -143,9 +142,9 @@ export const LegacyDataMixin = dedupingMixin(superClass => { // LegacyDataMixin is applied to base class _before_ metaprogramming, to // ensure override of _addPropertyEffect et.al. are used by metaprogramming // performed in _finalizeClass -Polymer.Class = (info, mixin) => Class(info, - superClass => mixin ? - mixin(LegacyDataMixin(superClass)) : +Polymer.Class = (info, mixin) => Class(info, + superClass => mixin ? + mixin(LegacyDataMixin(superClass)) : LegacyDataMixin(superClass) ); diff --git a/lib/legacy/legacy-element-mixin.js b/lib/legacy/legacy-element-mixin.js index a6d00c1671..91f7edcf26 100644 --- a/lib/legacy/legacy-element-mixin.js +++ b/lib/legacy/legacy-element-mixin.js @@ -38,13 +38,12 @@ let styleInterface = window.ShadyCSS; * @summary Element class mixin that provides Polymer's "legacy" API */ export const LegacyElementMixin = dedupingMixin((base) => { - /** * @constructor - * @extends {base} * @implements {Polymer_ElementMixin} * @implements {Polymer_GestureEventListeners} * @implements {Polymer_DirMixin} + * @extends {HTMLElement} * @private */ const legacyElementBase = DirMixin(GestureEventListeners(ElementMixin(base))); @@ -73,9 +72,9 @@ export const LegacyElementMixin = dedupingMixin((base) => { super(); /** @type {boolean} */ this.isAttached; - /** @type {WeakMap>} */ + /** @type {?WeakMap>} */ this.__boundListeners; - /** @type {Object} */ + /** @type {?Object} */ this._debouncers; // Ensure listeners are applied immediately so that they are // added before declarative event listeners. This allows an element to @@ -99,6 +98,7 @@ export const LegacyElementMixin = dedupingMixin((base) => { /** * Legacy callback called during the `constructor`, for overriding * by the user. + * @override * @return {void} */ created() {} @@ -118,6 +118,7 @@ export const LegacyElementMixin = dedupingMixin((base) => { /** * Legacy callback called during `connectedCallback`, for overriding * by the user. + * @override * @return {void} */ attached() {} @@ -137,6 +138,7 @@ export const LegacyElementMixin = dedupingMixin((base) => { /** * Legacy callback called during `disconnectedCallback`, for overriding * by the user. + * @override * @return {void} */ detached() {} @@ -165,6 +167,7 @@ export const LegacyElementMixin = dedupingMixin((base) => { * @param {?string} old Old value of attribute. * @param {?string} value Current value of attribute. * @return {void} + * @override */ attributeChanged(name, old, value) {} // eslint-disable-line no-unused-vars @@ -195,6 +198,7 @@ export const LegacyElementMixin = dedupingMixin((base) => { * only once for the class. * @protected * @return {void} + * @override */ _registered() {} @@ -220,6 +224,7 @@ export const LegacyElementMixin = dedupingMixin((base) => { * setting aria roles and focusability. * @protected * @return {void} + * @override */ _ensureAttributes() {} @@ -233,6 +238,7 @@ export const LegacyElementMixin = dedupingMixin((base) => { * block render. * @protected * @return {void} + * @override */ _applyListeners() {} @@ -247,6 +253,7 @@ export const LegacyElementMixin = dedupingMixin((base) => { * * @param {*} value Value to deserialize * @return {string | undefined} Serialized value + * @override */ serialize(value) { return this._serializeValue(value); @@ -264,6 +271,7 @@ export const LegacyElementMixin = dedupingMixin((base) => { * @param {string} value String to deserialize * @param {*} type Type to deserialize the string to * @return {*} Returns the deserialized value in the `type` given. + * @override */ deserialize(value, type) { return this._deserializeValue(value, type); @@ -279,6 +287,7 @@ export const LegacyElementMixin = dedupingMixin((base) => { * @param {string=} attribute Attribute name to reflect. * @param {*=} value Property value to reflect. * @return {void} + * @override */ reflectPropertyToAttribute(property, attribute, value) { this._propertyToAttribute(property, attribute, value); @@ -294,6 +303,7 @@ export const LegacyElementMixin = dedupingMixin((base) => { * @param {string} attribute Attribute name to serialize to. * @param {Element} node Element to set attribute to. * @return {void} + * @override */ serializeValueToAttribute(value, attribute, node) { this._valueToNodeAttribute(/** @type {Element} */ (node || this), value, attribute); @@ -306,6 +316,7 @@ export const LegacyElementMixin = dedupingMixin((base) => { * @param {Object} prototype Target object to copy properties to. * @param {Object} api Source object to copy properties from. * @return {Object} prototype object that was passed as first argument. + * @override */ extend(prototype, api) { if (!(prototype && api)) { @@ -331,6 +342,7 @@ export const LegacyElementMixin = dedupingMixin((base) => { * @param {!Object} target Target object to copy properties to. * @param {!Object} source Source object to copy properties from. * @return {!Object} Target object that was passed as first argument. + * @override */ mixin(target, source) { for (let i in source) { @@ -349,6 +361,7 @@ export const LegacyElementMixin = dedupingMixin((base) => { * `object`. * @return {Object} Returns the given `object` with its prototype set * to the given `prototype` object. + * @override */ chainObject(object, prototype) { if (object && prototype && object !== prototype) { @@ -366,7 +379,8 @@ export const LegacyElementMixin = dedupingMixin((base) => { * @param {HTMLTemplateElement} template HTML template element to instance. * @return {!DocumentFragment} Document fragment containing the imported * template content. - */ + * @override + */ instanceTemplate(template) { let content = this.constructor._contentForTemplate(template); let dom = /** @type {!DocumentFragment} */ @@ -384,12 +398,14 @@ export const LegacyElementMixin = dedupingMixin((base) => { * @param {string} type Name of event type. * @param {*=} detail Detail value containing event-specific * payload. - * @param {{ bubbles: (boolean|undefined), cancelable: (boolean|undefined), composed: (boolean|undefined) }=} + * @param {{ bubbles: (boolean|undefined), cancelable: (boolean|undefined), + * composed: (boolean|undefined) }=} * options Object specifying options. These may include: * `bubbles` (boolean, defaults to `true`), * `cancelable` (boolean, defaults to false), and * `node` on which to fire the event (HTMLElement, defaults to `this`). * @return {!Event} The new event that was fired. + * @override */ fire(type, detail, options) { options = options || {}; @@ -413,6 +429,7 @@ export const LegacyElementMixin = dedupingMixin((base) => { * @param {string} eventName Name of event to listen for. * @param {string} methodName Name of handler method on `this` to call. * @return {void} + * @override */ listen(node, eventName, methodName) { node = /** @type {!EventTarget} */ (node || this); @@ -426,7 +443,7 @@ export const LegacyElementMixin = dedupingMixin((base) => { let key = eventName + methodName; if (!bl[key]) { bl[key] = this._addMethodEventListenerToNode( - node, eventName, methodName, this); + /** @type {!Node} */ (node), eventName, methodName, this); } } @@ -439,15 +456,18 @@ export const LegacyElementMixin = dedupingMixin((base) => { * @param {string} methodName Name of handler method on `this` to not call anymore. * @return {void} + * @override */ unlisten(node, eventName, methodName) { node = /** @type {!EventTarget} */ (node || this); - let bl = this.__boundListeners && this.__boundListeners.get(node); + let bl = this.__boundListeners && + this.__boundListeners.get(/** @type {!Element} */ (node)); let key = eventName + methodName; let handler = bl && bl[key]; if (handler) { - this._removeEventListenerFromNode(node, eventName, handler); - bl[key] = null; + this._removeEventListenerFromNode( + /** @type {!Node} */ (node), eventName, handler); + bl[key] = /** @type {?} */ (null); } } @@ -465,9 +485,12 @@ export const LegacyElementMixin = dedupingMixin((base) => { * @param {Element=} node Element to apply scroll direction setting. * Defaults to `this`. * @return {void} + * @override */ setScrollDirection(direction, node) { - setTouchAction(/** @type {Element} */ (node || this), DIRECTION_MAP[direction] || 'auto'); + setTouchAction( + /** @type {!Element} */ (node || this), + DIRECTION_MAP[direction] || 'auto'); } /* **** End Events **** */ @@ -478,6 +501,7 @@ export const LegacyElementMixin = dedupingMixin((base) => { * * @param {string} slctr Selector to run on this local DOM scope * @return {Element} Element found by the selector, or null if not found. + * @override */ $$(slctr) { return this.root.querySelector(slctr); @@ -499,6 +523,7 @@ export const LegacyElementMixin = dedupingMixin((base) => { * This should not be necessary as of Polymer 2.0.2 and is provided only * for backwards compatibility. * @return {void} + * @override */ distributeContent() { if (window.ShadyDOM && this.shadowRoot) { @@ -512,11 +537,13 @@ export const LegacyElementMixin = dedupingMixin((base) => { * any `` elements are replaced with the list of nodes distributed * to the ``, the result of its `getDistributedNodes` method. * @return {!Array} List of effective child nodes. - * @suppress {invalidCasts} LegacyElementMixin must be applied to an HTMLElement + * @suppress {invalidCasts} LegacyElementMixin must be applied to an + * HTMLElement + * @override */ getEffectiveChildNodes() { const thisEl = /** @type {Element} */ (this); - const domApi = /** @type {DomApi} */(dom(thisEl)); + const domApi = /** @type {PolymerDomApi} */ (dom(thisEl)); return domApi.getEffectiveChildNodes(); } @@ -526,11 +553,13 @@ export const LegacyElementMixin = dedupingMixin((base) => { * children that are insertion points. * @param {string} selector Selector to run. * @return {!Array} List of distributed elements that match selector. - * @suppress {invalidCasts} LegacyElementMixin must be applied to an HTMLElement + * @suppress {invalidCasts} LegacyElementMixin must be applied to an + * HTMLElement + * @override */ queryDistributedElements(selector) { const thisEl = /** @type {Element} */ (this); - const domApi = /** @type {DomApi} */(dom(thisEl)); + const domApi = /** @type {PolymerDomApi} */ (dom(thisEl)); return domApi.queryDistributedElements(selector); } @@ -541,6 +570,7 @@ export const LegacyElementMixin = dedupingMixin((base) => { * distributed to the ``. * * @return {!Array} List of effective children. + * @override */ getEffectiveChildren() { let list = this.getEffectiveChildNodes(); @@ -555,6 +585,7 @@ export const LegacyElementMixin = dedupingMixin((base) => { * returned by { /** * @constructor - * @extends {base} * @implements {Polymer_PropertyAccessors} * @private */ @@ -134,7 +133,9 @@ export const DirMixin = dedupingMixin((base) => { } /** - * @suppress {invalidCasts} Closure doesn't understand that `this` is an HTMLElement + * @override + * @suppress {invalidCasts} Closure doesn't understand that `this` is an + * HTMLElement * @return {void} */ ready() { @@ -143,7 +144,9 @@ export const DirMixin = dedupingMixin((base) => { } /** - * @suppress {missingProperties} If it exists on elementBase, it can be super'd + * @override + * @suppress {missingProperties} If it exists on elementBase, it can be + * super'd * @return {void} */ connectedCallback() { @@ -158,7 +161,9 @@ export const DirMixin = dedupingMixin((base) => { } /** - * @suppress {missingProperties} If it exists on elementBase, it can be super'd + * @override + * @suppress {missingProperties} If it exists on elementBase, it can be + * super'd * @return {void} */ disconnectedCallback() { diff --git a/lib/mixins/disable-upgrade-mixin.js b/lib/mixins/disable-upgrade-mixin.js index b7f46486e2..d63f63bafa 100644 --- a/lib/mixins/disable-upgrade-mixin.js +++ b/lib/mixins/disable-upgrade-mixin.js @@ -38,11 +38,10 @@ const DISABLED_ATTR = 'disable-upgrade'; * @appliesMixin ElementMixin */ export const DisableUpgradeMixin = dedupingMixin((base) => { - /** * @constructor - * @extends {base} * @implements {Polymer_ElementMixin} + * @extends {HTMLElement} * @private */ const superClass = ElementMixin(base); @@ -59,14 +58,22 @@ export const DisableUpgradeMixin = dedupingMixin((base) => { return super.observedAttributes.concat(DISABLED_ATTR); } - /** @override */ + /** + * @override + * @param {string} name + * @param {?string} old + * @param {?string} value + * @param {?string=} namespace + * @return {undefined} + */ attributeChangedCallback(name, old, value, namespace) { if (name == DISABLED_ATTR) { if (!this.__dataEnabled && value == null && this.isConnected) { super.connectedCallback(); } } else { - super.attributeChangedCallback(name, old, value, namespace); + super.attributeChangedCallback( + name, old, value, /** @type {null|string} */ (namespace)); } } @@ -75,7 +82,7 @@ export const DisableUpgradeMixin = dedupingMixin((base) => { attributes are delivered. Therefore, we stub this out and call `super._initializeProperties()` manually. */ - /** @override */ + /** @override */ _initializeProperties() {} // prevent user code in connected from running @@ -108,5 +115,4 @@ export const DisableUpgradeMixin = dedupingMixin((base) => { } return DisableUpgradeClass; - }); diff --git a/lib/mixins/element-mixin.js b/lib/mixins/element-mixin.js index b6e49a7364..a0dfbccaa3 100644 --- a/lib/mixins/element-mixin.js +++ b/lib/mixins/element-mixin.js @@ -92,12 +92,11 @@ export const version = '3.0.5'; * meta-programming features. */ export const ElementMixin = dedupingMixin(base => { - /** * @constructor - * @extends {base} * @implements {Polymer_PropertyEffects} * @implements {Polymer_PropertiesMixin} + * @extends {HTMLElement} * @private */ const polymerElementBase = PropertiesMixin(PropertyEffects(base)); @@ -138,9 +137,11 @@ export const ElementMixin = dedupingMixin(base => { function ownObservers(constructor) { if (!constructor.hasOwnProperty( JSCompiler_renameProperty('__ownObservers', constructor))) { - constructor.__ownObservers = - constructor.hasOwnProperty(JSCompiler_renameProperty('observers', constructor)) ? - /** @type {PolymerElementConstructor} */ (constructor).observers : null; + constructor.__ownObservers = + constructor.hasOwnProperty( + JSCompiler_renameProperty('observers', constructor)) ? + /** @type {PolymerElementConstructor} */ (constructor).observers : + null; } return constructor.__ownObservers; } @@ -279,8 +280,8 @@ export const ElementMixin = dedupingMixin(base => { /** * Look up template from dom-module for element * - * @param {!string} is Element name to look up - * @return {!HTMLTemplateElement} Template found in dom module, or + * @param {string} is Element name to look up + * @return {?HTMLTemplateElement|undefined} Template found in dom module, or * undefined if not found * @protected */ @@ -289,7 +290,8 @@ export const ElementMixin = dedupingMixin(base => { // Under strictTemplatePolicy in 3.x+, dom-module lookup is only allowed // when opted-in via allowTemplateFromDomModule if (is && (!strictTemplatePolicy || allowTemplateFromDomModule)) { - template = DomModule.import(is, 'template'); + template = /** @type {?HTMLTemplateElement} */ ( + DomModule.import(is, 'template')); // Under strictTemplatePolicy, require any element with an `is` // specified to have a dom-module if (strictTemplatePolicy && !template) { @@ -304,10 +306,11 @@ export const ElementMixin = dedupingMixin(base => { * @mixinClass * @unrestricted * @implements {Polymer_ElementMixin} + * @extends {polymerElementBase} */ class PolymerElement extends polymerElementBase { - /** + /** * Current Polymer version in Semver notation. * @type {string} Semver notation of the current version of Polymer. */ @@ -323,7 +326,7 @@ export const ElementMixin = dedupingMixin(base => { * @override * @suppress {missingProperties} Interfaces in closure do not inherit statics, but classes do */ - static _finalizeClass() { + static _finalizeClass() { super._finalizeClass(); if (this.hasOwnProperty( JSCompiler_renameProperty('is', this)) && this.is) { @@ -354,7 +357,7 @@ export const ElementMixin = dedupingMixin(base => { * @protected * @override */ - static createProperties(props) { + static createProperties(props) { for (let p in props) { createPropertyFromConfig(this.prototype, p, props[p], props); } @@ -590,7 +593,9 @@ export const ElementMixin = dedupingMixin(base => { * flushes any pending properties, and updates shimmed CSS properties * when using the ShadyCSS scoping/custom properties polyfill. * - * @suppress {missingProperties, invalidCasts} Super may or may not implement the callback + * @override + * @suppress {missingProperties, invalidCasts} Super may or may not + * implement the callback * @return {void} */ connectedCallback() { @@ -642,6 +647,7 @@ export const ElementMixin = dedupingMixin(base => { * However, this method may be overridden to allow an element * to put its dom in another location. * + * @override * @throws {Error} * @suppress {missingReturn} * @param {StampedTemplate} dom to attach to the element. @@ -681,6 +687,7 @@ export const ElementMixin = dedupingMixin(base => { * Note: This function does not support updating CSS mixins. * You can not dynamically change the value of an `@apply`. * + * @override * @param {Object=} properties Bag of custom property key/values to * apply to this element. * @return {void} @@ -702,6 +709,7 @@ export const ElementMixin = dedupingMixin(base => { * with `/` (absolute URLs) or `#` (hash identifiers). For general purpose * URL resolution, use `window.URL`. * + * @override * @param {string} url URL to resolve. * @param {string=} base Optional base URL to resolve against, defaults * to the element's `importPath` @@ -741,13 +749,12 @@ export let instanceCount = 0; /** * Array of Polymer element classes that have been finalized. - * @type {Array} + * @type {!Array} */ export const registrations = []; /** * @param {!PolymerElementConstructor} prototype Element prototype to log - * @this {this} * @private */ function _regLog(prototype) { @@ -756,8 +763,7 @@ function _regLog(prototype) { /** * Registers a class prototype for telemetry purposes. - * @param {HTMLElement} prototype Element prototype to register - * @this {this} + * @param {!PolymerElementConstructor} prototype Element prototype to register * @protected */ export function register(prototype) { @@ -767,7 +773,6 @@ export function register(prototype) { /** * Logs all elements registered with an `is` to the console. * @public - * @this {this} */ export function dumpRegistrations() { registrations.forEach(_regLog); diff --git a/lib/mixins/properties-changed.js b/lib/mixins/properties-changed.js index 7400d73863..d3a04620f2 100644 --- a/lib/mixins/properties-changed.js +++ b/lib/mixins/properties-changed.js @@ -157,6 +157,7 @@ export const PropertiesChanged = dedupingMixin( constructor() { super(); + /** @protected {boolean} */ this.__dataEnabled = false; this.__dataReady = false; this.__dataInvalid = false; @@ -421,7 +422,7 @@ export const PropertiesChanged = dedupingMixin( * @param {string} name Name of attribute that changed * @param {?string} old Old attribute value * @param {?string} value New attribute value - * @param {?string} namespace Attribute namespace. + * @param {?string=} namespace Attribute namespace. * @return {void} * @suppress {missingProperties} Super may or may not implement the callback * @override diff --git a/lib/mixins/property-accessors.js b/lib/mixins/property-accessors.js index 002939ad59..074abdea74 100644 --- a/lib/mixins/property-accessors.js +++ b/lib/mixins/property-accessors.js @@ -69,16 +69,18 @@ function saveAccessorValue(model, property) { * * For basic usage of this mixin: * - * - Declare attributes to observe via the standard `static get observedAttributes()`. Use - * `dash-case` attribute names to represent `camelCase` property names. + * - Declare attributes to observe via the standard `static get + * observedAttributes()`. Use `dash-case` attribute names to represent + * `camelCase` property names. * - Implement the `_propertiesChanged` callback on the class. - * - Call `MyClass.createPropertiesForAttributes()` **once** on the class to generate - * property accessors for each observed attribute. This must be called before the first - * instance is created, for example, by calling it before calling `customElements.define`. - * It can also be called lazily from the element's `constructor`, as long as it's guarded so - * that the call is only made once, when the first instance is created. - * - Call `this._enableProperties()` in the element's `connectedCallback` to enable - * the accessors. + * - Call `MyClass.createPropertiesForAttributes()` **once** on the class to + * generate property accessors for each observed attribute. This must be + * called before the first instance is created, for example, by calling it + * before calling `customElements.define`. It can also be called lazily from + * the element's `constructor`, as long as it's guarded so that the call is + * only made once, when the first instance is created. + * - Call `this._enableProperties()` in the element's `connectedCallback` to + * enable the accessors. * * Any `observedAttributes` will automatically be * deserialized via `attributeChangedCallback` and set to the associated @@ -94,7 +96,6 @@ export const PropertyAccessors = dedupingMixin(superClass => { /** * @constructor - * @extends {superClass} * @implements {Polymer_PropertiesChanged} * @unrestricted * @private @@ -145,6 +146,7 @@ export const PropertyAccessors = dedupingMixin(superClass => { * * @return {void} * @protected + * @override */ _initializeProperties() { if (this.__dataProto) { @@ -162,10 +164,11 @@ export const PropertyAccessors = dedupingMixin(superClass => { * setter at instance time. This method is provided as an override * point for customizing or providing more efficient initialization. * - * @param {Object} props Bag of property values that were overwritten + * @param {!Object} props Bag of property values that were overwritten * when creating property accessors. * @return {void} * @protected + * @override */ _initializeProtoProperties(props) { for (let p in props) { @@ -177,11 +180,13 @@ export const PropertyAccessors = dedupingMixin(superClass => { * Ensures the element has the given attribute. If it does not, * assigns the given value to the attribute. * - * @suppress {invalidCasts} Closure can't figure out `this` is infact an element + * @suppress {invalidCasts} Closure can't figure out `this` is infact an + * element * * @param {string} attribute Name of attribute to ensure is set. * @param {string} value of the attribute. * @return {void} + * @override */ _ensureAttribute(attribute, value) { const el = /** @type {!HTMLElement} */(this); @@ -194,7 +199,9 @@ export const PropertyAccessors = dedupingMixin(superClass => { * Overrides PropertiesChanged implemention to serialize objects as JSON. * * @param {*} value Property value to serialize. - * @return {string | undefined} String serialized from the provided property value. + * @return {string | undefined} String serialized from the provided property + * value. + * @override */ _serializeValue(value) { /* eslint-disable no-fallthrough */ @@ -229,6 +236,7 @@ export const PropertyAccessors = dedupingMixin(superClass => { * @param {?string} value Attribute value to deserialize. * @param {*=} type Type to deserialize the string to. * @return {*} Typed value deserialized from the provided string. + * @override */ _deserializeValue(value, type) { /** @@ -278,6 +286,7 @@ export const PropertyAccessors = dedupingMixin(superClass => { * for the values to take effect. * @protected * @return {void} + * @override */ _definePropertyAccessor(property, readOnly) { saveAccessorValue(this, property); @@ -289,6 +298,7 @@ export const PropertyAccessors = dedupingMixin(superClass => { * * @param {string} property Property name * @return {boolean} True if an accessor was created + * @override */ _hasAccessor(property) { return this.__dataHasAccessor && this.__dataHasAccessor[property]; @@ -300,6 +310,7 @@ export const PropertyAccessors = dedupingMixin(superClass => { * @param {string} prop Property name * @return {boolean} True if property has a pending change * @protected + * @override */ _isPropertyPending(prop) { return Boolean(this.__dataPending && (prop in this.__dataPending)); diff --git a/lib/mixins/property-effects.js b/lib/mixins/property-effects.js index b36c620f87..33a2d17d30 100644 --- a/lib/mixins/property-effects.js +++ b/lib/mixins/property-effects.js @@ -36,7 +36,7 @@ const TYPES = { READ_ONLY: '__readOnly' }; -/** @const {RegExp} */ +/** @const {!RegExp} */ const capitalAttributeRegex = /[A-Z]/; /** @@ -57,8 +57,6 @@ let DataTrigger; //eslint-disable-line no-unused-vars */ let DataEffect; //eslint-disable-line no-unused-vars -let PropertyEffectsType; //eslint-disable-line no-unused-vars - /** * Ensures that the model has an own-property map of effects for the given type. * The model may be a prototype or an instance. @@ -104,10 +102,10 @@ function ensureOwnEffectMap(model, type) { * Runs all effects of a given type for the given set of property changes * on an instance. * - * @param {!PropertyEffectsType} inst The instance with effects to run - * @param {Object} effects Object map of property-to-Array of effects - * @param {Object} props Bag of current property changes - * @param {Object=} oldProps Bag of previous values for changed properties + * @param {!Polymer_PropertyEffects} inst The instance with effects to run + * @param {?Object} effects Object map of property-to-Array of effects + * @param {?Object} props Bag of current property changes + * @param {?Object=} oldProps Bag of previous values for changed properties * @param {boolean=} hasPaths True with `props` contains one or more paths * @param {*=} extraArgs Additional metadata to pass to effect function * @return {boolean} True if an effect ran for this property @@ -118,7 +116,9 @@ function runEffects(inst, effects, props, oldProps, hasPaths, extraArgs) { let ran = false; let id = dedupeId++; for (let prop in props) { - if (runEffectsForProperty(inst, effects, id, prop, props, oldProps, hasPaths, extraArgs)) { + if (runEffectsForProperty( + inst, /** @type {!Object} */ (effects), id, prop, props, oldProps, + hasPaths, extraArgs)) { ran = true; } } @@ -130,8 +130,8 @@ function runEffects(inst, effects, props, oldProps, hasPaths, extraArgs) { /** * Runs a list of effects for a given property. * - * @param {!PropertyEffectsType} inst The instance with effects to run - * @param {Object} effects Object map of property-to-Array of effects + * @param {!Polymer_PropertyEffects} inst The instance with effects to run + * @param {!Object} effects Object map of property-to-Array of effects * @param {number} dedupeId Counter used for de-duping effects * @param {string} prop Name of changed property * @param {*} props Changed properties @@ -175,15 +175,15 @@ function runEffectsForProperty(inst, effects, dedupeId, prop, props, oldProps, h * If no trigger is given, the path is deemed to match. * * @param {string} path Path or property that changed - * @param {DataTrigger} trigger Descriptor + * @param {?DataTrigger} trigger Descriptor * @return {boolean} Whether the path matched the trigger */ function pathMatchesTrigger(path, trigger) { if (trigger) { - let triggerPath = trigger.name; + let triggerPath = /** @type {string} */ (trigger.name); return (triggerPath == path) || - (trigger.structured && isAncestor(triggerPath, path)) || - (trigger.wildcard && isDescendant(triggerPath, path)); + !!(trigger.structured && isAncestor(triggerPath, path)) || + !!(trigger.wildcard && isDescendant(triggerPath, path)); } else { return true; } @@ -195,7 +195,7 @@ function pathMatchesTrigger(path, trigger) { * Calls the method with `info.methodName` on the instance, passing the * new and old values. * - * @param {!PropertyEffectsType} inst The instance the effect will be run on + * @param {!Polymer_PropertyEffects} inst The instance the effect will be run on * @param {string} property Name of property * @param {Object} props Bag of current property changes * @param {Object} oldProps Bag of previous values for changed properties @@ -223,7 +223,7 @@ function runObserverEffect(inst, property, props, oldProps, info) { * `notify: true` to ensure object sub-property notifications were * sent. * - * @param {!PropertyEffectsType} inst The instance with effects to run + * @param {!Polymer_PropertyEffects} inst The instance with effects to run * @param {Object} notifyProps Bag of properties to notify * @param {Object} props Bag of current property changes * @param {Object} oldProps Bag of previous values for changed properties @@ -259,7 +259,8 @@ function runNotifyEffects(inst, notifyProps, props, oldProps, hasPaths) { * Dispatches {property}-changed events with path information in the detail * object to indicate a sub-path of the property was changed. * - * @param {!PropertyEffectsType} inst The element from which to fire the event + * @param {!Polymer_PropertyEffects} inst The element from which to fire the + * event * @param {string} path The path that was changed * @param {Object} props Bag of current property changes * @return {boolean} Returns true if the path was notified @@ -279,11 +280,13 @@ function notifyPath(inst, path, props) { * Dispatches {property}-changed events to indicate a property (or path) * changed. * - * @param {!PropertyEffectsType} inst The element from which to fire the event - * @param {string} eventName The name of the event to send ('{property}-changed') + * @param {!Polymer_PropertyEffects} inst The element from which to fire the + * event + * @param {string} eventName The name of the event to send + * ('{property}-changed') * @param {*} value The value of the changed property - * @param {string | null | undefined} path If a sub-path of this property changed, the path - * that changed (optional). + * @param {string | null | undefined} path If a sub-path of this property + * changed, the path that changed (optional). * @return {void} * @private * @suppress {invalidCasts} @@ -305,7 +308,7 @@ function dispatchNotifyEvent(inst, eventName, value, path) { * Dispatches a non-bubbling event named `info.eventName` on the instance * with a detail object containing the new `value`. * - * @param {!PropertyEffectsType} inst The instance the effect will be run on + * @param {!Polymer_PropertyEffects} inst The instance the effect will be run on * @param {string} property Name of property * @param {Object} props Bag of current property changes * @param {Object} oldProps Bag of previous values for changed properties @@ -334,7 +337,8 @@ function runNotifyEffect(inst, property, props, oldProps, info, hasPaths) { * scope's name for that path first. * * @param {CustomEvent} event Notification event (e.g. '-changed') - * @param {!PropertyEffectsType} inst Host element instance handling the notification event + * @param {!Polymer_PropertyEffects} inst Host element instance handling the + * notification event * @param {string} fromProp Child element property that was bound * @param {string} toPath Host property/path that was bound * @param {boolean} negate Whether the binding was negated @@ -365,7 +369,7 @@ function handleNotification(event, inst, fromProp, toPath, negate) { * * Sets the attribute named `info.attrName` to the given property value. * - * @param {!PropertyEffectsType} inst The instance the effect will be run on + * @param {!Polymer_PropertyEffects} inst The instance the effect will be run on * @param {string} property Name of property * @param {Object} props Bag of current property changes * @param {Object} oldProps Bag of previous values for changed properties @@ -391,9 +395,9 @@ function runReflectEffect(inst, property, props, oldProps, info) { * computed before other effects (binding propagation, observers, and notify) * run. * - * @param {!PropertyEffectsType} inst The instance the effect will be run on - * @param {!Object} changedProps Bag of changed properties - * @param {!Object} oldProps Bag of previous values for changed properties + * @param {!Polymer_PropertyEffects} inst The instance the effect will be run on + * @param {?Object} changedProps Bag of changed properties + * @param {?Object} oldProps Bag of previous values for changed properties * @param {boolean} hasPaths True with `props` contains one or more paths * @return {void} * @private @@ -403,8 +407,8 @@ function runComputedEffects(inst, changedProps, oldProps, hasPaths) { if (computeEffects) { let inputProps = changedProps; while (runEffects(inst, computeEffects, inputProps, oldProps, hasPaths)) { - Object.assign(oldProps, inst.__dataOld); - Object.assign(changedProps, inst.__dataPending); + Object.assign(/** @type {!Object} */ (oldProps), inst.__dataOld); + Object.assign(/** @type {!Object} */ (changedProps), inst.__dataPending); inputProps = inst.__dataPending; inst.__dataPending = null; } @@ -416,10 +420,10 @@ function runComputedEffects(inst, changedProps, oldProps, hasPaths) { * values of the arguments specified in the `info` object and setting the * return value to the computed property specified. * - * @param {!PropertyEffectsType} inst The instance the effect will be run on + * @param {!Polymer_PropertyEffects} inst The instance the effect will be run on * @param {string} property Name of property - * @param {Object} props Bag of current property changes - * @param {Object} oldProps Bag of previous values for changed properties + * @param {?Object} props Bag of current property changes + * @param {?Object} oldProps Bag of previous values for changed properties * @param {?} info Effect metadata * @return {void} * @private @@ -438,8 +442,8 @@ function runComputedEffect(inst, property, props, oldProps, info) { * Computes path changes based on path links set up using the `linkPaths` * API. * - * @param {!PropertyEffectsType} inst The instance whose props are changing - * @param {string | !Array<(string|number)>} path Path that has changed + * @param {!Polymer_PropertyEffects} inst The instance whose props are changing + * @param {string} path Path that has changed * @param {*} value Value of changed path * @return {void} * @private @@ -544,7 +548,7 @@ function addEffectForBindingPart(constructor, templateInfo, binding, part, index * there is no support for _path_ bindings via custom binding parts, * as this is specific to Polymer's path binding syntax. * - * @param {!PropertyEffectsType} inst The instance the effect will be run on + * @param {!Polymer_PropertyEffects} inst The instance the effect will be run on * @param {string} path Name of property * @param {Object} props Bag of current property changes * @param {Object} oldProps Bag of previous values for changed properties @@ -581,7 +585,7 @@ function runBindingEffect(inst, path, props, oldProps, info, hasPaths, nodeList) * Sets the value for an "binding" (binding) effect to a node, * either as a property or attribute. * - * @param {!PropertyEffectsType} inst The instance owning the binding effect + * @param {!Polymer_PropertyEffects} inst The instance owning the binding effect * @param {Node} node Target node for binding * @param {!Binding} binding Binding metadata * @param {!BindingPart} part Binding part metadata @@ -666,7 +670,8 @@ function shouldAddListener(binding) { * Setup compound binding storage structures, notify listeners, and dataHost * references onto the bound nodeList. * - * @param {!PropertyEffectsType} inst Instance that bas been previously bound + * @param {!Polymer_PropertyEffects} inst Instance that bas been previously + * bound * @param {TemplateInfo} templateInfo Template metadata * @return {void} * @private @@ -729,7 +734,8 @@ function setupCompoundStorage(node, binding) { * Adds a 2-way binding notification event listener to the node specified * * @param {Object} node Child element to add listener to - * @param {!PropertyEffectsType} inst Host element instance to handle notification event + * @param {!Polymer_PropertyEffects} inst Host element instance to handle + * notification event * @param {Binding} binding Binding metadata * @return {void} * @private @@ -793,7 +799,7 @@ function createMethodEffect(model, sig, type, effectFn, methodInfo, dynamicFn) { * functions call this function to invoke the method, then use the return * value accordingly. * - * @param {!PropertyEffectsType} inst The instance the effect will be run on + * @param {!Polymer_PropertyEffects} inst The instance the effect will be run on * @param {string} property Name of property * @param {Object} props Bag of current property changes * @param {Object} oldProps Bag of previous values for changed properties @@ -970,7 +976,7 @@ function parseArg(rawArg) { * * Note: this implementation only accepts normalized paths * - * @param {!PropertyEffectsType} inst Instance to send notifications to + * @param {!Polymer_PropertyEffects} inst Instance to send notifications to * @param {Array} array The array the mutations occurred on * @param {string} path The path to the array that was mutated * @param {Array} splices Array of splice records @@ -991,7 +997,7 @@ function notifySplices(inst, array, path, splices) { * * Note: this implementation only accepts normalized paths * - * @param {!PropertyEffectsType} inst Instance to send notifications to + * @param {!Polymer_PropertyEffects} inst Instance to send notifications to * @param {Array} array The array the mutations occurred on * @param {string} path The path to the array that was mutated * @param {number} index Index at which the array mutation occurred @@ -1060,7 +1066,6 @@ export const PropertyEffects = dedupingMixin(superClass => { /** * @constructor - * @extends {superClass} * @implements {Polymer_PropertyAccessors} * @implements {Polymer_TemplateStamp} * @unrestricted @@ -1107,7 +1112,7 @@ export const PropertyEffects = dedupingMixin(superClass => { this.__dataClientsInitialized; /** @type {!Object} */ this.__data; - /** @type {!Object} */ + /** @type {!Object|null} */ this.__dataPending; /** @type {!Object} */ this.__dataOld; @@ -1132,6 +1137,7 @@ export const PropertyEffects = dedupingMixin(superClass => { } /** + * @override * @return {void} */ _initializeProperties() { @@ -1190,6 +1196,7 @@ export const PropertyEffects = dedupingMixin(superClass => { * an instance to add effects at runtime. See that method for * full API docs. * + * @override * @param {string} property Property that should trigger the effect * @param {string} type Effect type, from this.PROPERTY_EFFECT_TYPES * @param {Object=} effect Effect metadata object @@ -1209,6 +1216,7 @@ export const PropertyEffects = dedupingMixin(superClass => { /** * Removes the given property effect. * + * @override * @param {string} property Property the effect was associated with * @param {string} type Effect type, from this.PROPERTY_EFFECT_TYPES * @param {Object=} effect Effect metadata object to remove @@ -1226,9 +1234,11 @@ export const PropertyEffects = dedupingMixin(superClass => { * Returns whether the current prototype/instance has a property effect * of a certain type. * + * @override * @param {string} property Property name * @param {string=} type Effect type, from this.PROPERTY_EFFECT_TYPES - * @return {boolean} True if the prototype/instance has an effect of this type + * @return {boolean} True if the prototype/instance has an effect of this + * type * @protected */ _hasPropertyEffect(property, type) { @@ -1240,8 +1250,10 @@ export const PropertyEffects = dedupingMixin(superClass => { * Returns whether the current prototype/instance has a "read only" * accessor for the given property. * + * @override * @param {string} property Property name - * @return {boolean} True if the prototype/instance has an effect of this type + * @return {boolean} True if the prototype/instance has an effect of this + * type * @protected */ _hasReadOnlyEffect(property) { @@ -1252,8 +1264,10 @@ export const PropertyEffects = dedupingMixin(superClass => { * Returns whether the current prototype/instance has a "notify" * property effect for the given property. * + * @override * @param {string} property Property name - * @return {boolean} True if the prototype/instance has an effect of this type + * @return {boolean} True if the prototype/instance has an effect of this + * type * @protected */ _hasNotifyEffect(property) { @@ -1261,11 +1275,13 @@ export const PropertyEffects = dedupingMixin(superClass => { } /** - * Returns whether the current prototype/instance has a "reflect to attribute" - * property effect for the given property. + * Returns whether the current prototype/instance has a "reflect to + * attribute" property effect for the given property. * + * @override * @param {string} property Property name - * @return {boolean} True if the prototype/instance has an effect of this type + * @return {boolean} True if the prototype/instance has an effect of this + * type * @protected */ _hasReflectEffect(property) { @@ -1276,8 +1292,10 @@ export const PropertyEffects = dedupingMixin(superClass => { * Returns whether the current prototype/instance has a "computed" * property effect for the given property. * + * @override * @param {string} property Property name - * @return {boolean} True if the prototype/instance has an effect of this type + * @return {boolean} True if the prototype/instance has an effect of this + * type * @protected */ _hasComputedEffect(property) { @@ -1301,6 +1319,7 @@ export const PropertyEffects = dedupingMixin(superClass => { * `path` can be a path string or array of path parts as accepted by the * public API. * + * @override * @param {string | !Array} path Path to set * @param {*} value Value to set * @param {boolean=} shouldNotify Set to true if this change should @@ -1335,7 +1354,7 @@ export const PropertyEffects = dedupingMixin(superClass => { } this.__dataHasPaths = true; if (this._setPendingProperty(/**@type{string}*/(path), value, shouldNotify)) { - computeLinkedPaths(this, path, value); + computeLinkedPaths(this, /**@type{string}*/ (path), value); return true; } } else { @@ -1363,6 +1382,7 @@ export const PropertyEffects = dedupingMixin(superClass => { * * Users may override this method to provide alternate approaches. * + * @override * @param {!Node} node The node to set a property on * @param {string} prop The property to set * @param {*} value The value to set @@ -1480,6 +1500,7 @@ export const PropertyEffects = dedupingMixin(superClass => { * pending property changes can later be flushed via a call to * `_flushClients`. * + * @override * @param {Object} client PropertyEffects client to enqueue * @return {void} * @protected @@ -1494,6 +1515,7 @@ export const PropertyEffects = dedupingMixin(superClass => { /** * Overrides superclass implementation. * + * @override * @return {void} * @protected */ @@ -1507,6 +1529,7 @@ export const PropertyEffects = dedupingMixin(superClass => { * Flushes any clients previously enqueued via `_enqueueClient`, causing * their `_flushProperties` method to run. * + * @override * @return {void} * @protected */ @@ -1555,6 +1578,7 @@ export const PropertyEffects = dedupingMixin(superClass => { * `_flushProperties` call on client dom and before any element * observers are called. * + * @override * @return {void} * @protected */ @@ -1569,6 +1593,7 @@ export const PropertyEffects = dedupingMixin(superClass => { * Property names must be simple properties, not paths. Batched * path propagation is not supported. * + * @override * @param {Object} props Bag of one or more key-value pairs whose key is * a property and value is the new value to set for that property. * @param {boolean=} setReadOnly When true, any private values set in @@ -1623,6 +1648,7 @@ export const PropertyEffects = dedupingMixin(superClass => { * Runs each class of effects for the batch of changed properties in * a specific order (compute, propagate, reflect, observe, notify). * + * @override * @param {!Object} currentProps Bag of all current accessor values * @param {?Object} changedProps Bag of properties changed since the last * call to `_propertiesChanged` @@ -1669,6 +1695,7 @@ export const PropertyEffects = dedupingMixin(superClass => { * Called to propagate any property changes to stamped template nodes * managed by this element. * + * @override * @param {Object} changedProps Bag of changed properties * @param {Object} oldProps Bag of previous values for changed properties * @param {boolean} hasPaths True with `props` contains one or more paths @@ -1691,6 +1718,7 @@ export const PropertyEffects = dedupingMixin(superClass => { * Aliases one data path as another, such that path notifications from one * are routed to the other. * + * @override * @param {string | !Array} to Target path to link. * @param {string | !Array} from Source path to link. * @return {void} @@ -1709,6 +1737,7 @@ export const PropertyEffects = dedupingMixin(superClass => { * Note, the path to unlink should be the target (`to`) used when * linking the paths. * + * @override * @param {string | !Array} path Target path to unlink. * @return {void} * @public @@ -1730,8 +1759,10 @@ export const PropertyEffects = dedupingMixin(superClass => { * this.items.splice(1, 1, {name: 'Sam'}); * this.items.push({name: 'Bob'}); * this.notifySplices('items', [ - * { index: 1, removed: [{name: 'Todd'}], addedCount: 1, object: this.items, type: 'splice' }, - * { index: 3, removed: [], addedCount: 1, object: this.items, type: 'splice'} + * { index: 1, removed: [{name: 'Todd'}], addedCount: 1, + * object: this.items, type: 'splice' }, + * { index: 3, removed: [], addedCount: 1, + * object: this.items, type: 'splice'} * ]); * * @param {string} path Path that should be notified. @@ -1747,9 +1778,11 @@ export const PropertyEffects = dedupingMixin(superClass => { * Note that splice records _must_ be normalized such that they are * reported in index order (raw results from `Object.observe` are not * ordered and must be normalized/merged before notifying). + * + * @override * @return {void} * @public - */ + */ notifySplices(path, splices) { let info = {path: ''}; let array = /** @type {Array} */(get(this, path, info)); @@ -1763,6 +1796,7 @@ export const PropertyEffects = dedupingMixin(superClass => { * `undefined` (this method does not throw when dereferencing undefined * paths). * + * @override * @param {(string|!Array<(string|number)>)} path Path to the value * to read. The path may be specified as a string (e.g. `foo.bar.baz`) * or an array of path parts (e.g. `['foo.bar', 'baz']`). Note that @@ -1787,6 +1821,7 @@ export const PropertyEffects = dedupingMixin(superClass => { * this method does nothing (this method does not throw when * dereferencing undefined paths). * + * @override * @param {(string|!Array<(string|number)>)} path Path to the value * to write. The path may be specified as a string (e.g. `'foo.bar.baz'`) * or an array of path parts (e.g. `['foo.bar', 'baz']`). Note that @@ -1799,7 +1834,7 @@ export const PropertyEffects = dedupingMixin(superClass => { * When specified, no notification will occur. * @return {void} * @public - */ + */ set(path, value, root) { if (root) { set(root, path, value); @@ -1821,6 +1856,7 @@ export const PropertyEffects = dedupingMixin(superClass => { * This method notifies other paths to the same array that a * splice occurred to the array. * + * @override * @param {string | !Array} path Path to array. * @param {...*} items Items to push onto array * @return {number} New length of the array. @@ -1846,6 +1882,7 @@ export const PropertyEffects = dedupingMixin(superClass => { * This method notifies other paths to the same array that a * splice occurred to the array. * + * @override * @param {string | !Array} path Path to array. * @return {*} Item that was removed. * @public @@ -1871,6 +1908,7 @@ export const PropertyEffects = dedupingMixin(superClass => { * This method notifies other paths to the same array that a * splice occurred to the array. * + * @override * @param {string | !Array} path Path to array. * @param {number} start Index from which to start removing/inserting. * @param {number=} deleteCount Number of items to remove. @@ -1926,6 +1964,7 @@ export const PropertyEffects = dedupingMixin(superClass => { * This method notifies other paths to the same array that a * splice occurred to the array. * + * @override * @param {string | !Array} path Path to array. * @return {*} Item that was removed. * @public @@ -1950,6 +1989,7 @@ export const PropertyEffects = dedupingMixin(superClass => { * This method notifies other paths to the same array that a * splice occurred to the array. * + * @override * @param {string | !Array} path Path to array. * @param {...*} items Items to insert info array * @return {number} New length of the array. @@ -1973,11 +2013,12 @@ export const PropertyEffects = dedupingMixin(superClass => { * this.item.user.name = 'Bob'; * this.notifyPath('item.user.name'); * + * @override * @param {string} path Path that should be notified. * @param {*=} value Value at the path (optional). * @return {void} * @public - */ + */ notifyPath(path, value) { /** @type {string} */ let propPath; @@ -2002,6 +2043,7 @@ export const PropertyEffects = dedupingMixin(superClass => { * an instance to add effects at runtime. See that method for * full API docs. * + * @override * @param {string} property Property name * @param {boolean=} protectedSetter Creates a custom protected setter * when `true`. @@ -2022,8 +2064,10 @@ export const PropertyEffects = dedupingMixin(superClass => { * an instance to add effects at runtime. See that method for * full API docs. * + * @override * @param {string} property Property name - * @param {string|function(*,*)} method Function or name of observer method to call + * @param {string|function(*,*)} method Function or name of observer method + * to call * @param {boolean=} dynamicFn Whether the method name should be included as * a dependency to the effect. * @return {void} @@ -2046,6 +2090,7 @@ export const PropertyEffects = dedupingMixin(superClass => { * an instance to add effects at runtime. See that method for * full API docs. * + * @override * @param {string} expression Method expression * @param {boolean|Object=} dynamicFn Boolean or object map indicating * whether method names should be included as a dependency to the effect. @@ -2065,6 +2110,7 @@ export const PropertyEffects = dedupingMixin(superClass => { * an instance to add effects at runtime. See that method for * full API docs. * + * @override * @param {string} property Property name * @return {void} * @protected @@ -2084,6 +2130,7 @@ export const PropertyEffects = dedupingMixin(superClass => { * an instance to add effects at runtime. See that method for * full API docs. * + * @override * @param {string} property Property name * @return {void} * @protected @@ -2108,6 +2155,7 @@ export const PropertyEffects = dedupingMixin(superClass => { * an instance to add effects at runtime. See that method for * full API docs. * + * @override * @param {string} property Name of computed property to set * @param {string} expression Method expression * @param {boolean|Object=} dynamicFn Boolean or object map indicating @@ -2337,6 +2385,7 @@ export const PropertyEffects = dedupingMixin(superClass => { * create and link an instance of the template metadata associated with a * particular stamping. * + * @override * @param {!HTMLTemplateElement} template Template containing binding * bindings * @param {boolean=} instanceBinding When false (default), performs @@ -2445,6 +2494,7 @@ export const PropertyEffects = dedupingMixin(superClass => { * Removes and unbinds the nodes previously contained in the provided * DocumentFragment returned from `_stampTemplate`. * + * @override * @param {!StampedTemplate} dom DocumentFragment previously returned * from `_stampTemplate` associated with the nodes to be removed * @return {void} @@ -2709,8 +2759,8 @@ export const PropertyEffects = dedupingMixin(superClass => { * Called to evaluate a previously parsed binding part based on a set of * one or more changed dependencies. * - * @param {this} inst Element that should be used as scope for - * binding dependencies + * @param {!Polymer_PropertyEffects} inst Element that should be used as + * scope for binding dependencies * @param {BindingPart} part Binding part metadata * @param {string} path Property/path that triggered this effect * @param {Object} props Bag of current property changes @@ -2740,9 +2790,6 @@ export const PropertyEffects = dedupingMixin(superClass => { } - // make a typing for closure :P - PropertyEffectsType = PropertyEffects; - return PropertyEffects; }); diff --git a/lib/utils/style-gather.js b/lib/utils/style-gather.js index 985802b70e..b67fcafd90 100644 --- a/lib/utils/style-gather.js +++ b/lib/utils/style-gather.js @@ -102,7 +102,7 @@ export function stylesFromModule(moduleId) { * Returns the `