mirror of
https://github.com/Polymer/polymer.git
synced 2026-08-19 01:14:44 -05:00
Sync with changes made on master.
This commit is contained in:
@@ -9,6 +9,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
-->
|
||||
|
||||
<link rel="import" href="class.html">
|
||||
<link rel="import" href="../polymer.html">
|
||||
<link rel="import" href="../utils/mixin.html">
|
||||
|
||||
<script>
|
||||
@@ -16,15 +17,43 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
'use strict';
|
||||
|
||||
const UndefinedArgumentError = class extends Error {
|
||||
constructor(message) {
|
||||
constructor(message, arg) {
|
||||
super(message);
|
||||
this.arg = arg;
|
||||
this.name = this.constructor.name;
|
||||
// Affordances for ensuring instanceof works after babel ES5 compilation
|
||||
// TODO(kschaaf): Remove after polymer CLI updates to newer Babel that
|
||||
// sets the constructor/prototype correctly for subclassed builtins
|
||||
this.constructor = UndefinedArgumentError;
|
||||
this.__proto__ = UndefinedArgumentError.prototype;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
function wrapEffect(effect, fnName) {
|
||||
if (effect && effect.fn) {
|
||||
const fn = effect.fn;
|
||||
effect.fn = function() {
|
||||
try {
|
||||
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.`);
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
return effect;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mixin to selectively add back Polymer 1.x's `undefined` rules
|
||||
* governing when observers & computing functions run based
|
||||
@@ -38,6 +67,11 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
* 2.x+ by allowing legacy code to work while identifying observers and
|
||||
* computing functions that need undefined checks to work without
|
||||
* the mixin in Polymer 2.
|
||||
*
|
||||
* @mixinFunction
|
||||
* @polymer
|
||||
* @summary Mixin to selectively add back Polymer 1.x's `undefined` rules
|
||||
* governing when observers & computing functions run.
|
||||
*/
|
||||
Polymer.LegacyDataMixin = Polymer.dedupingMixin(superClass => {
|
||||
|
||||
@@ -59,12 +93,16 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
*/
|
||||
_marshalArgs(args, path, props) {
|
||||
const vals = super._marshalArgs(args, path, props);
|
||||
if (this._legacyUndefinedCheck && args.length > 1) {
|
||||
for (let i=0; i<args.length; i++) {
|
||||
// Per legacy data rules, single-property observers (whether in `properties`
|
||||
// and in `observers`) are called regardless of whether their argument is
|
||||
// undefined or not. Multi-property observers must have all arguments defined
|
||||
if (this._legacyUndefinedCheck && vals.length > 1) {
|
||||
for (let i=0; i<vals.length; i++) {
|
||||
if (vals[i] === undefined) {
|
||||
// Break out of effect's control flow; will be caught in
|
||||
// wrapped property effect function below
|
||||
throw new UndefinedArgumentError(`argument '${args[i].name}' is undefined; ensure it has an undefined check`);
|
||||
const name = args[i].name;
|
||||
throw new UndefinedArgumentError(`Argument '${name}' is undefined. Ensure it has an undefined check.`, name);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -81,22 +119,23 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
* @return {void}
|
||||
* @protected
|
||||
*/
|
||||
_addPropertyEffect(property, type, effect) {
|
||||
if (effect && effect.fn) {
|
||||
const fn = effect.fn;
|
||||
effect.fn = function() {
|
||||
try {
|
||||
fn.apply(this, arguments);
|
||||
} catch (e) {
|
||||
if (e instanceof UndefinedArgumentError) {
|
||||
console.warn(e.message);
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
return super._addPropertyEffect(property, type, effect);
|
||||
_addPropertyEffect(property, type, effect) {
|
||||
return super._addPropertyEffect(property, type,
|
||||
wrapEffect(effect, effect && effect.info && effect.info.methodName));
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides `Polyer.PropertyEffects` to wrap effect functions to
|
||||
* catch `UndefinedArgumentError`s and warn.
|
||||
*
|
||||
* @param {Object} templateInfo Template metadata to add effect to
|
||||
* @param {string} prop Property that should trigger the effect
|
||||
* @param {Object=} effect Effect metadata object
|
||||
* @return {void}
|
||||
* @protected
|
||||
*/
|
||||
static _addTemplatePropertyEffect(templateInfo, prop, effect) {
|
||||
return super._addTemplatePropertyEffect(templateInfo, prop, wrapEffect(effect));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -105,6 +144,9 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
|
||||
});
|
||||
|
||||
// LegacyDataMixin is applied to base class _before_ metaprogramming, to
|
||||
// ensure override of _addPropertyEffect et.al. are used by metaprogramming
|
||||
// performed in _finalizeClass
|
||||
const Class = Polymer.Class;
|
||||
Polymer.Class = (info, mixin) => Class(info,
|
||||
superClass => mixin ?
|
||||
|
||||
Reference in New Issue
Block a user