Apply listeners in constructor rather than ready

Fixes #4394. This change allows elements to have "first crack" at their own events (via the `listeners` object) before handlers registered via `on-*` see events. This is both more expected and fixes an inconsistency with 1.x.
This commit is contained in:
Steven Orvell
2017-12-11 17:43:49 -08:00
parent 81964830ef
commit 35e3c54b9b
4 changed files with 43 additions and 2 deletions
+5 -1
View File
@@ -81,6 +81,11 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
/** @type {Object<string, Function>} */
this._debouncers;
this.created();
// Ensure listeners are applied immediately so that they are
// added before declarative event listeners. This allows an element to
// decorate itself via an event prior to any declarative listeners
// seeing the event. Note, this ensures compatibility with 1.x ordering.
this._applyListeners();
}
/**
@@ -180,7 +185,6 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
*/
ready() {
this._ensureAttributes();
this._applyListeners();
super.ready();
}
+6
View File
@@ -579,7 +579,13 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
*/
setTouchAction: function(node, value) {
if (HAS_NATIVE_TA) {
// NOTE: add touchAction async so that events can be added in
// custom element constructors. Otherwise we run afoult of custom
// elements restriction against settings attributes (style) in the
// constructor.
Polymer.Async.microTask.run(() => {
node.style.touchAction = value;
});
}
node[TOUCH_ACTION] = value;
},
+14
View File
@@ -17,6 +17,8 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
this._removed = [];
},
handle: function(e) {
const order = e._handleOrder = e._handleOrder || [];
order.push(this.localName);
this._handled[e.currentTarget.localName] = e.type;
},
unlisten: function(node, eventName, handler) {
@@ -51,6 +53,18 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
</script>
</dom-module>
<dom-module id="x-order">
<template>
<x-listeners id="inner" on-foo="handle"></x-listeners>
</template>
<script>
Polymer({
is: 'x-order',
behaviors: [EventLoggerImpl]
});
</script>
</dom-module>
<dom-module id="x-dynamic">
<template>
<div id="inner"></div>
+17
View File
@@ -78,6 +78,23 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
});
suite('listeners + on-*', function() {
suiteSetup(function() {
el = document.createElement('x-order');
document.body.appendChild(el);
});
suiteTeardown(function() {
document.body.removeChild(el);
});
test('listeners handled before on-* events', function() {
const e = el.$.inner.fire('foo', {});
assert.deepEqual(e._handleOrder, ['x-listeners', 'x-order']);
});
});
suite('dynamic', function() {
var options;