Skip to content

Instantly share code, notes, and snippets.

@hermo
Created January 11, 2013 14:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hermo/4511221 to your computer and use it in GitHub Desktop.
Save hermo/4511221 to your computer and use it in GitHub Desktop.
_AttachNodesMixin, Enable data-dojo-attach-(point|event) on non-templated, nested dijit widgets. Very rough and almost nontested but basically works :)
/**
* Adds the ability to use data-dojo-attach-* properties on non-templated widgets.
*/
define([
'dojo/_base/declare',
'dojo/_base/lang',
'dojo/parser',
'dojo/touch',
'dijit/registry'
], function (declare, lang, parser, touch, registry) {
return declare(null, {
startup:function () {
this.inherited(arguments);
this._attachPoints = [];
this._attachEvents = [];
this._attachNodes(this.domNode, function (n, p) {
return n.getAttribute(p);
});
},
/**
* Attach data-dojo-attach-* nodes.
* Extracted from _TemplatedMixin.
*
* @param rootNode
* @param getAttrFunc
* @private
*/
_attachNodes:function (rootNode, getAttrFunc) {
var nodelist = lang.isArray(rootNode) ? rootNode : (rootNode.all || rootNode.getElementsByTagName("*"));
// First convert the nodelist to a real array
var nodes = [];
// FIXME: Not avoiding Nodelist#length
for (var i = nodelist.length; i--; nodes.unshift(nodelist[i]));
var baseWidget;
var x = lang.isArray(rootNode) ? 0 : -1;
for (; x < 0 || nodes[x]; x++) { // don't access nodes.length on IE, see #14346
var baseNode = (x == -1) ? rootNode : nodes[x];
if (baseNode != rootNode) {
baseWidget = registry.byNode(baseNode);
} else {
baseWidget = null;
}
// If we're dealing with a widget, it should handle it's internal attach point stuff.
// Therefore we should remove all it's child nodes from the node list.
if (baseWidget) {
var widgetNodes = baseNode.all || baseNode.getElementsByTagName('*');
// FIXME: Not avoiding Nodelist#length
if (widgetNodes && widgetNodes.length > 0) {
// We want to remove as many items as possible in one splice operation and must check if
// the widget child nodes would have been next up in the main node list
var allSame = true;
for (i = 0; i < widgetNodes.length; i++) {
if (nodes[x + i + 1] == widgetNodes[i]) {
}
else {
console.log('not same');
allSame = false;
}
}
// If all nodes were equal we can easily remove them with one splice op.
if (allSame) {
var removed = nodes.splice(x + 1, widgetNodes.length);
} else {
// Otherwise we just remove the ones we find at the correct position.
// FIXME: Maybe search the whole nodelist? (slowww)
for (i = 0; i < widgetNodes.length; i++) {
if (nodes[x + i + 1] == widgetNodes[i]) {
nodes.splice(x + i + 1, 1);
}
}
}
}
}
// Process data-dojo-attach-point
var attachPoint = getAttrFunc(baseNode, "dojoAttachPoint") || getAttrFunc(baseNode, "data-dojo-attach-point");
if (attachPoint) {
var point, points = attachPoint.split(/\s*,\s*/);
while ((point = points.shift())) {
if (lang.isArray(this[point])) {
this[point].push(baseWidget || baseNode);
} else {
this[point] = baseWidget || baseNode;
}
this._attachPoints.push(point);
}
}
// Process data-dojo-attach-event
var attachEvent = getAttrFunc(baseNode, "dojoAttachEvent") || getAttrFunc(baseNode, "data-dojo-attach-event");
if (rootNode != baseNode && attachEvent) {
// NOTE: we want to support attributes that have the form
// "domEvent: nativeEvent; ..."
var event, events = attachEvent.split(/\s*,\s*/);
var trim = lang.trim;
while ((event = events.shift())) {
if (event) {
var thisFunc = null;
if (event.indexOf(":") != -1) {
// oh, if only JS had tuple assignment
var funcNameArr = event.split(":");
event = trim(funcNameArr[0]);
thisFunc = trim(funcNameArr[1]);
} else {
event = trim(event);
}
if (!thisFunc) {
thisFunc = event;
}
// Map "press", "move" and "release" to keys.touch, keys.move, keys.release
this._attachEvents.push(this.connect(baseWidget || baseNode, touch[event] || event, thisFunc));
}
}
}
}
}
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment