diff --git a/lib/mixins/property-effects.js b/lib/mixins/property-effects.js index 114568cc99..83bca57070 100644 --- a/lib/mixins/property-effects.js +++ b/lib/mixins/property-effects.js @@ -19,7 +19,7 @@ import { camelToDashCase, dashToCamelCase } from '../utils/case-map.js'; import { PropertyAccessors } from './property-accessors.js'; /* for annotated effects */ import { TemplateStamp } from './template-stamp.js'; -import { sanitizeDOMValue, legacyUndefined, legacyNoBatch } from '../utils/settings.js'; +import { sanitizeDOMValue, legacyUndefined, legacyNoBatch, legacyNotifyOrder } from '../utils/settings.js'; // Monotonically increasing unique ID used for de-duping effects triggered // from multiple properties in the same turn @@ -1495,6 +1495,9 @@ export const PropertyEffects = dedupingMixin(superClass => { } if (legacyNoBatch) { this._invalidateProperties(); + // Returning false here means "the change was already handled, no need + // to invalidate" + return false; } return true; } @@ -1561,7 +1564,9 @@ export const PropertyEffects = dedupingMixin(superClass => { // The first time this element is being flushed, propagate pending // data down the tree first; this approximates 1.x's distributeConfig this._propagatePropertyChanges(this.__dataPending, {}, false); - // Flushing clients causes this element to become __dataReady + // Flushing clients recurses, running the initial call to + // `_flushProperties` down the tree. It also causes this element to + // become __dataReady, enabling effects to run. this._flushClients(); // Capture element data and flush properties one-by one to defeat // Polymer 2.x's batched _propertiesChanged scheme; this approximates @@ -1744,10 +1749,14 @@ export const PropertyEffects = dedupingMixin(superClass => { this._flushClients(); // Reflect properties runEffects(this, this[TYPES.REFLECT], changedProps, oldProps, hasPaths); + // Notify properties to host (1.x order) + if (notifyProps && legacyNotifyOrder) { + runNotifyEffects(this, notifyProps, changedProps, oldProps, hasPaths); + } // Observe properties runEffects(this, this[TYPES.OBSERVE], changedProps, oldProps, hasPaths); - // Notify properties to host - if (notifyProps) { + // Notify properties to host (2.x order) + if (notifyProps && !legacyNotifyOrder) { runNotifyEffects(this, notifyProps, changedProps, oldProps, hasPaths); } // Clear temporary cache at end of turn diff --git a/lib/utils/settings.js b/lib/utils/settings.js index 1f37b9e354..bd7af22eb0 100644 --- a/lib/utils/settings.js +++ b/lib/utils/settings.js @@ -195,3 +195,21 @@ export let legacyNoBatch = false; export const setLegacyNoBatch = function(useLegacyNoBatch) { legacyNoBatch = useLegacyNoBatch; }; + +/** + * Setting to revert to the legacy Polymer 1 order for when notifying properties + * fire change events with respect to other effects. In Polymer 1.x they fire + * before observers; in 2.x they fire after all other effect types. + */ +export let legacyNotifyOrder = false; + +/** + * Sets `legacyNotifyOrder` globally for all elements to enable legacy + * notify order. + * + * @param {boolean} useLegacyNotifyOrder enable or disable legacy notify order + * @return {void} + */ +export const setLegacyNotifyOrder = function(useLegacyNotifyOrder) { + legacyNotifyOrder = useLegacyNotifyOrder; +}; diff --git a/test/unit/property-effects.html b/test/unit/property-effects.html index 37b211b85a..464fbda156 100644 --- a/test/unit/property-effects.html +++ b/test/unit/property-effects.html @@ -26,12 +26,12 @@