Created
January 11, 2013 14:52
-
-
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 :)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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