mirror of
https://github.com/Polymer/polymer.git
synced 2025-02-25 18:55:30 -06:00
Merge pull request #20 from sjmiles/e334f1293f394165dd1e53e7527bc624f99ec4f7
use MutationObserver to maintain custom event bindings, bug fixes
This commit is contained in:
@@ -16,8 +16,8 @@ license that can be found in the LICENSE file.
|
||||
PROPERTY_CHANGED_SUFFIX: "Changed",
|
||||
CUSTOM_EVENT_PREFIX: "at"
|
||||
};
|
||||
|
||||
// polyfill for DOMTokenList features: list of classes in add/remove;
|
||||
|
||||
// polyfill for DOMTokenList features: list of classes in add/remove;
|
||||
// enable method.
|
||||
(function() {
|
||||
'use strict';
|
||||
@@ -37,11 +37,11 @@ license that can be found in the LICENSE file.
|
||||
value ? this.add(name) : this.remove(name);
|
||||
};
|
||||
})();
|
||||
|
||||
|
||||
(function(){
|
||||
|
||||
|
||||
// attribute bindings
|
||||
|
||||
|
||||
var bindAttrs = function(inAttributes) {
|
||||
var attrs = this.boundAttributes = [];
|
||||
if (inAttributes) {
|
||||
@@ -53,9 +53,9 @@ license that can be found in the LICENSE file.
|
||||
}, this);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// event bindings
|
||||
|
||||
|
||||
var bindEvents = function(inEvents) {
|
||||
if (inEvents) {
|
||||
var bindables = inEvents.value.split(",");
|
||||
@@ -70,7 +70,7 @@ license that can be found in the LICENSE file.
|
||||
}, this);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// property bindings
|
||||
|
||||
var propertyChanged = function(inName, inOld) {
|
||||
@@ -88,7 +88,7 @@ license that can be found in the LICENSE file.
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
var squelchSideEffects = false;
|
||||
|
||||
var setPropertySilently = function(inName, inValue) {
|
||||
@@ -105,6 +105,7 @@ license that can be found in the LICENSE file.
|
||||
// set default value in a property already bound via attrs
|
||||
setPropertySilently.call(this, inName, value);
|
||||
} else {
|
||||
console.log('binding', inName, this)
|
||||
var value = inValue;
|
||||
var sideEffect = sideEffectFactory(inName);
|
||||
Object.defineProperty(this, inName, {
|
||||
@@ -121,7 +122,7 @@ license that can be found in the LICENSE file.
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
var bindProperties = function(inProperties) {
|
||||
if (inProperties) {
|
||||
Object.keys(inProperties).forEach(function(n) {
|
||||
@@ -129,7 +130,7 @@ license that can be found in the LICENSE file.
|
||||
}, this);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
var deref = function(inNode) {
|
||||
return inNode && (inNode.baby || inNode);
|
||||
};
|
||||
@@ -137,14 +138,16 @@ license that can be found in the LICENSE file.
|
||||
var establishNodeReferences = function(inRoot) {
|
||||
this.$ = this.$ || {};
|
||||
// search the LOCAL tree
|
||||
var nodes = ShadowDOM.localQueryAll(inRoot, "[id]");
|
||||
Array.prototype.forEach.call(nodes, function(n) {
|
||||
this.$[n.id] = deref(n);
|
||||
}, this);
|
||||
if (inRoot) {
|
||||
var nodes = ShadowDOM.localQueryAll(inRoot, "[id]");
|
||||
Array.prototype.forEach.call(nodes, function(n) {
|
||||
this.$[n.id] = deref(n);
|
||||
}, this);
|
||||
}
|
||||
};
|
||||
|
||||
// attribute mutations
|
||||
|
||||
|
||||
var deserializeValue = function(inValue) {
|
||||
switch (inValue) {
|
||||
case "":
|
||||
@@ -180,7 +183,7 @@ license that can be found in the LICENSE file.
|
||||
propertyChanged.call(this, c.name, c.old);
|
||||
}, this);
|
||||
};
|
||||
|
||||
|
||||
var attributeChanged = function(inName) {
|
||||
var value = this.getAttribute(inName);
|
||||
this[inName] = deserializeValue(value);
|
||||
@@ -189,7 +192,7 @@ license that can be found in the LICENSE file.
|
||||
var handleMutations = function(inMxns) {
|
||||
inMxns.forEach(function(inMxn) {
|
||||
var name = inMxn.attributeName;
|
||||
if (this.boundAttributes[name]) {
|
||||
if (this.boundAttributes.indexOf(name) >= 0) {
|
||||
attributeChanged.call(this, name);
|
||||
}
|
||||
}, this);
|
||||
@@ -221,7 +224,7 @@ license that can be found in the LICENSE file.
|
||||
};
|
||||
|
||||
// decorate HTMLElementElement with toolkit API
|
||||
|
||||
|
||||
HTMLElementElement.prototype.component = function(inUber) {
|
||||
var attributes = this.element.attributes;
|
||||
this.lifecycle({
|
||||
@@ -238,7 +241,7 @@ license that can be found in the LICENSE file.
|
||||
this.attrObserver = new AttrObserver(this);
|
||||
}
|
||||
});
|
||||
var p = inUber.prototype;
|
||||
var p = inUber.prototype || {};
|
||||
// attach some API
|
||||
// TODO(sjmiles): this is probably not the best way to do this;
|
||||
// probably better to insert another link in the prototype chain
|
||||
@@ -247,11 +250,11 @@ license that can be found in the LICENSE file.
|
||||
// install our prototype
|
||||
this.generatedConstructor.prototype = p;
|
||||
};
|
||||
|
||||
|
||||
// utility methods
|
||||
|
||||
|
||||
// job
|
||||
|
||||
|
||||
var job = function(inJobName, inJob, inWait) {
|
||||
var name = inJobName || ("__" + Math.random());
|
||||
job.stop(name);
|
||||
@@ -270,8 +273,8 @@ license that can be found in the LICENSE file.
|
||||
job._jobs = {};
|
||||
|
||||
// target finding
|
||||
|
||||
findDistributedTarget = function(inTarget, inItems) {
|
||||
|
||||
var findDistributedTarget = function(inTarget, inItems) {
|
||||
// find ancestor of target (including himself) that
|
||||
// is in our item list, if any
|
||||
var n = inTarget;
|
||||
@@ -283,19 +286,19 @@ license that can be found in the LICENSE file.
|
||||
n = n.parentNode;
|
||||
}
|
||||
};
|
||||
|
||||
// collect utils
|
||||
|
||||
|
||||
// collect utils
|
||||
|
||||
var utils = {
|
||||
job: job,
|
||||
findDistributedTarget: findDistributedTarget
|
||||
};
|
||||
|
||||
|
||||
// code below provides a shim for declarative event handlers
|
||||
// (aka 'x', as in onclick="x('click')")
|
||||
// it's only really for evaluating syntax, and not
|
||||
// it's only really for evaluating syntax, and not
|
||||
// a real solution
|
||||
|
||||
|
||||
var nodeIterator = function(inNodes, inFn) {
|
||||
if (inNodes) {
|
||||
for (var i=0, n; (n=inNodes[i]); i++) {
|
||||
@@ -336,7 +339,7 @@ license that can be found in the LICENSE file.
|
||||
// experimental event handler for mapping events to component instances
|
||||
// publish handler globally, make name as small as possible since
|
||||
// this is ideally an invisible helper API
|
||||
|
||||
|
||||
x = function(inHandler) {
|
||||
var owner = findOwner(event.currentTarget);
|
||||
//console.log(inHandler, owner, event);
|
||||
@@ -344,7 +347,7 @@ license that can be found in the LICENSE file.
|
||||
owner[inHandler](event);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// newer experimental event handler
|
||||
|
||||
var findController = function(inNode) {
|
||||
@@ -357,7 +360,7 @@ license that can be found in the LICENSE file.
|
||||
n = n.parentNode || n.host;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
_ = function(inHandlerName) {
|
||||
var controller = findController(event.currentTarget);
|
||||
//console.log(inHandler, owner, event);
|
||||
@@ -365,14 +368,18 @@ license that can be found in the LICENSE file.
|
||||
controller[inHandlerName](event);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// automagic event mapping
|
||||
|
||||
var bindCustomEvent = function(inNode, inEventName, inHandler) {
|
||||
//console.log(inEventName, inHandler);
|
||||
inNode.addEventListener(inEventName, function() {
|
||||
_(inHandler);
|
||||
});
|
||||
var h = inNode.__athandlers = inNode.__athandlers || {};
|
||||
if (!h[inEventName]) {
|
||||
console.log("bindCustomEvent:", inEventName, inHandler, inNode);
|
||||
h[inEventName] = function() {
|
||||
_(inHandler);
|
||||
};
|
||||
inNode.addEventListener(inEventName, h[inEventName]);
|
||||
}
|
||||
};
|
||||
|
||||
var bindCustomEvents = function(inNode) {
|
||||
@@ -385,9 +392,9 @@ license that can be found in the LICENSE file.
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// TODO(sjmiles): improper tree walking (?)
|
||||
var bindAllCustomEvents = function(inNode) {
|
||||
var _bindAllCustomEvents = function(inNode) {
|
||||
bindCustomEvents(inNode);
|
||||
if (inNode.childNodes) {
|
||||
for (var i=0, c; c=deref(inNode.childNodes[i]); i++) {
|
||||
@@ -398,6 +405,25 @@ license that can be found in the LICENSE file.
|
||||
}
|
||||
};
|
||||
|
||||
var __bindAllCustomEvents = function(inNode) {
|
||||
_bindAllCustomEvents(inNode);
|
||||
};
|
||||
|
||||
var eventsObserver = function(inNode) {
|
||||
new WebKitMutationObserver(__bindAllCustomEvents.bind(this, inNode))
|
||||
.observe(inNode, {
|
||||
childList: true,
|
||||
subTree: true
|
||||
});
|
||||
};
|
||||
|
||||
var bindAllCustomEvents = function(inNode) {
|
||||
if (inNode) {
|
||||
_bindAllCustomEvents(inNode);
|
||||
eventsObserver(inNode);
|
||||
}
|
||||
};
|
||||
|
||||
})();
|
||||
</script>
|
||||
</element>
|
||||
|
||||
Reference in New Issue
Block a user