node.js revision 45f27cabd6196774234000850bbe9a5f70c64f9b
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix/**
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * The Node Utility provides a DOM-like interface for interacting with DOM nodes.
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * @module node
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * @submodule node-base
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix */
9dc68827cbd515262ecb8d5ae8547d9e82c72e00Jon A. Cruz
9dc68827cbd515262ecb8d5ae8547d9e82c72e00Jon A. Cruz/**
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * The Node class provides a wrapper for manipulating DOM Nodes.
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * Node properties can be accessed via the set/get methods.
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * Use Y.get() to retrieve Node instances.
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix *
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * <strong>NOTE:</strong> Node properties are accessed using
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * the <code>set</code> and <code>get</code> methods.
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix *
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * @class Node
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * @constructor
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * @for Node
47badd0035ae8c9135c51444f3770b17ae504ddaAlex Valavanis */
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix// "globals"
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilixvar g_nodes = {},
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix g_nodelists = {},
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix g_slice = Array.prototype.slice,
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix DOT = '.',
5a0c9c0d523287747d281c61c78cb529b1118778Alex Valavanis NODE_NAME = 'nodeName',
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix NODE_TYPE = 'nodeType',
9dc68827cbd515262ecb8d5ae8547d9e82c72e00Jon A. Cruz OWNER_DOCUMENT = 'ownerDocument',
9dc68827cbd515262ecb8d5ae8547d9e82c72e00Jon A. Cruz TAG_NAME = 'tagName',
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix UID = '_yuid',
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix
e711b02fbbe0b7d07102ebdd63b05027d6f8af47Maximilian Albert Node = function(node) {
e711b02fbbe0b7d07102ebdd63b05027d6f8af47Maximilian Albert var uid = node[UID];
e711b02fbbe0b7d07102ebdd63b05027d6f8af47Maximilian Albert
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix if (uid && g_nodes[uid] && g_nodes[uid] !== node) {
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix node[UID] = null; // unset existing uid to prevent collision (via clone or hack)
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert }
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert this._initPlugins();
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert uid = Y.stamp(node);
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert if (!uid) { // stamp failed; likely IE non-HTMLElement
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert uid = Y.guid();
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert }
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert
a2e796b608034e2c62290378d713058b8b58ef8fMarkus Engel this[UID] = uid;
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix this._conf = {};
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix g_nodes[uid] = node;
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix this._stateProxy = node;
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix Node._instances[uid] = this;
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix },
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix // used with previous/next/ancestor tests
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix _wrapFn = function(fn) {
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix var ret = null;
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix if (fn) {
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix ret = (typeof fn === 'string') ?
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix function(n) {
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix return Y.Selector.test(n, fn);
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix } :
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix function(n) {
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix return fn(Node.get(n));
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix };
f4dbc5a10ebf95900d1ef56d74aad0474e159370Markus Engel }
f4dbc5a10ebf95900d1ef56d74aad0474e159370Markus Engel
f4dbc5a10ebf95900d1ef56d74aad0474e159370Markus Engel return ret;
f4dbc5a10ebf95900d1ef56d74aad0474e159370Markus Engel };
f4dbc5a10ebf95900d1ef56d74aad0474e159370Markus Engel// end "globals"
f4dbc5a10ebf95900d1ef56d74aad0474e159370Markus Engel
f4dbc5a10ebf95900d1ef56d74aad0474e159370Markus EngelNode.NAME = 'Node';
a2e796b608034e2c62290378d713058b8b58ef8fMarkus Engel
a2e796b608034e2c62290378d713058b8b58ef8fMarkus EngelNode.re_aria = /^(?:role$|aria-)/;
a2e796b608034e2c62290378d713058b8b58ef8fMarkus Engel
f4dbc5a10ebf95900d1ef56d74aad0474e159370Markus EngelNode.DOM_EVENTS = {
54ad9fc9cd6da88557d0dcd6c17eb47c7bbb5551Markus Engel abort: true,
7ab987fc3c5f568cfe40eccfe8a4f4ecc8c0006cMarkus Engel beforeunload: true,
7ab987fc3c5f568cfe40eccfe8a4f4ecc8c0006cMarkus Engel blur: true,
f4dbc5a10ebf95900d1ef56d74aad0474e159370Markus Engel change: true,
f4dbc5a10ebf95900d1ef56d74aad0474e159370Markus Engel click: true,
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert close: true,
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix command: true,
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix contextmenu: true,
a2e796b608034e2c62290378d713058b8b58ef8fMarkus Engel drag: true,
a2e796b608034e2c62290378d713058b8b58ef8fMarkus Engel dragstart: true,
a2e796b608034e2c62290378d713058b8b58ef8fMarkus Engel dragenter: true,
a2e796b608034e2c62290378d713058b8b58ef8fMarkus Engel dragover: true,
a2e796b608034e2c62290378d713058b8b58ef8fMarkus Engel dragleave: true,
a2e796b608034e2c62290378d713058b8b58ef8fMarkus Engel dragend: true,
a2e796b608034e2c62290378d713058b8b58ef8fMarkus Engel drop: true,
a2e796b608034e2c62290378d713058b8b58ef8fMarkus Engel dblclick: true,
a2e796b608034e2c62290378d713058b8b58ef8fMarkus Engel error: true,
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix focus: true,
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix keydown: true,
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix keypress: true,
51dc158adbe2c9d1df3c941cbf78b90944d1afc2Markus Engel keyup: true,
51dc158adbe2c9d1df3c941cbf78b90944d1afc2Markus Engel load: true,
f4dbc5a10ebf95900d1ef56d74aad0474e159370Markus Engel mousedown: true,
f4dbc5a10ebf95900d1ef56d74aad0474e159370Markus Engel mousemove: true,
f4dbc5a10ebf95900d1ef56d74aad0474e159370Markus Engel mouseout: true,
9dc68827cbd515262ecb8d5ae8547d9e82c72e00Jon A. Cruz mouseover: true,
9dc68827cbd515262ecb8d5ae8547d9e82c72e00Jon A. Cruz mouseup: true,
9dc68827cbd515262ecb8d5ae8547d9e82c72e00Jon A. Cruz mousemultiwheel: true,
9dc68827cbd515262ecb8d5ae8547d9e82c72e00Jon A. Cruz mousewheel: true,
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix submit: true,
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix mouseenter: true,
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix mouseleave: true,
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix scroll: true,
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix reset: true,
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix resize: true,
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix select: true,
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix textInput: true,
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix unload: true
51dc158adbe2c9d1df3c941cbf78b90944d1afc2Markus Engel};
f4dbc5a10ebf95900d1ef56d74aad0474e159370Markus Engel
f4dbc5a10ebf95900d1ef56d74aad0474e159370Markus Engel// Add custom event adaptors to this list. This will make it so
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert// that delegate, key, available, contentready, etc all will
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert// be available through Node.on
60282e8335d7b6ae7020613bb22c7c69a6909fbbJon A. CruzY.mix(Node.DOM_EVENTS, Y.Env.evt.plugins);
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilixNode._instances = {};
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix/**
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * Registers plugins to be instantiated at the class level (plugins
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * which should be plugged into every instance of Node by default).
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix *
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * @method Node.plug
51dc158adbe2c9d1df3c941cbf78b90944d1afc2Markus Engel * @static
f4dbc5a10ebf95900d1ef56d74aad0474e159370Markus Engel *
f4dbc5a10ebf95900d1ef56d74aad0474e159370Markus Engel * @param {Function | Array} plugin Either the plugin class, an array of plugin classes or an array of objects (with fn and cfg properties defined)
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert * @param {Object} config (Optional) If plugin is the plugin class, the configuration for the plugin
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix */
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilixNode.plug = function() {
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix var args = g_slice.call(arguments, 0);
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix args.unshift(Node);
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix Y.Plugin.Host.plug.apply(Y.Base, args);
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert return Node;
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix};
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix/**
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * Unregisters any class level plugins which have been registered by the Node
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix *
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * @method Node.unplug
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert * @static
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix *
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * @param {Function | Array} plugin The plugin class, or an array of plugin classes
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix */
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilixNode.unplug = function() {
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix var args = g_slice.call(arguments, 0);
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix args.unshift(Node);
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert Y.Plugin.Host.unplug.apply(Y.Base, args);
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix return Node;
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix};
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix/**
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * Retrieves the DOM node bound to a Node instance
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * @method Node.getDOMNode
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert * @static
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix *
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * @param {Y.Node || HTMLNode} node The Node instance or an HTMLNode
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * @return {HTMLNode} The DOM node bound to the Node instance. If a DOM node is passed
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * as the node argument, it is simply returned.
51dc158adbe2c9d1df3c941cbf78b90944d1afc2Markus Engel */
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilixNode.getDOMNode = function(node) {
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix if (node) {
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix if (node instanceof Node) {
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix node = g_nodes[node[UID]];
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix } else if (!node[NODE_NAME] || Y.DOM.isWindow(node)) { // must already be a DOMNode
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix node = null;
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix }
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix }
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix return node || null;
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix};
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilixNode.scrubVal = function(val, node, depth) {
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix if (node && val) { // only truthy values are risky
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix if (typeof val === 'object' || typeof val === 'function') { // safari nodeList === function
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix if (NODE_TYPE in val || Y.DOM.isWindow(val)) {// node || window
51dc158adbe2c9d1df3c941cbf78b90944d1afc2Markus Engel val = Node.get(val);
ab026a45b1869d884ee3f0af690c3879b76425e8JucaBlues } else if (val.item || // dom collection or Node instance
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix (val[0] && val[0][NODE_TYPE])) { // array of DOM Nodes
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix val = Y.all(val);
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix } else {
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix depth = (depth === undefined) ? 4 : depth;
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix if (depth > 0) {
51dc158adbe2c9d1df3c941cbf78b90944d1afc2Markus Engel for (var i in val) { // TODO: test this and pull hasOwnProperty check if safe?
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix if (val.hasOwnProperty && val.hasOwnProperty(i)) {
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix val[i] = Node.scrubVal(val[i], node, --depth);
9dc68827cbd515262ecb8d5ae8547d9e82c72e00Jon A. Cruz }
07b7f1aaaf1087716e784a50cf574a059f7018d3Jon A. Cruz }
9dc68827cbd515262ecb8d5ae8547d9e82c72e00Jon A. Cruz }
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix }
aa90355b5205dca29912b439ac9fde6ffa4d8989cilix }
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert } else if (val === undefined) {
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert val = node; // for chaining
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert }
aa90355b5205dca29912b439ac9fde6ffa4d8989cilix
2b635337710b879262acf4906dd85ee99b69f474Abhishek Sharma Public return val;
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert};
2b635337710b879262acf4906dd85ee99b69f474Abhishek Sharma Public
2b635337710b879262acf4906dd85ee99b69f474Abhishek Sharma PublicNode.addMethod = function(name, fn, context) {
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert if (name && fn && typeof fn === 'function') {
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert Node.prototype[name] = function() {
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert context = context || this;
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert var args = g_slice.call(arguments),
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert ret;
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert if (args[0] && args[0] instanceof Node) {
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert args[0] = Node.getDOMNode(args[0]);
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert }
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert if (args[1] && args[1] instanceof Node) {
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert args[1] = Node.getDOMNode(args[1]);
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert }
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert args.unshift(g_nodes[this[UID]]);
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert ret = Node.scrubVal(fn.apply(context, args), this);
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert return ret;
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert };
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert } else {
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert Y.log('unable to add method: ' + name, 'warn', 'Node');
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert }
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert};
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilixNode.importMethod = function(host, name, altName) {
60282e8335d7b6ae7020613bb22c7c69a6909fbbJon A. Cruz if (typeof name === 'string') {
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix altName = altName || name;
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix Node.addMethod(altName, host[name], host);
60282e8335d7b6ae7020613bb22c7c69a6909fbbJon A. Cruz } else {
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix Y.each(name, function(n) {
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix Node.importMethod(host, n);
9dc68827cbd515262ecb8d5ae8547d9e82c72e00Jon A. Cruz });
9dc68827cbd515262ecb8d5ae8547d9e82c72e00Jon A. Cruz }
9dc68827cbd515262ecb8d5ae8547d9e82c72e00Jon A. Cruz};
07b7f1aaaf1087716e784a50cf574a059f7018d3Jon A. Cruz
793350428bfc8e69ecfe65fa638afe4acb1acdd9cilix/**
9dc68827cbd515262ecb8d5ae8547d9e82c72e00Jon A. Cruz * Returns a single Node instance bound to the node or the
793350428bfc8e69ecfe65fa638afe4acb1acdd9cilix * first element matching the given selector.
793350428bfc8e69ecfe65fa638afe4acb1acdd9cilix * @method Y.get
9dc68827cbd515262ecb8d5ae8547d9e82c72e00Jon A. Cruz * @static
793350428bfc8e69ecfe65fa638afe4acb1acdd9cilix * @param {String | HTMLElement} node a node or Selector
793350428bfc8e69ecfe65fa638afe4acb1acdd9cilix * @param {Y.Node || HTMLElement} doc an optional document to scan. Defaults to Y.config.doc.
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix */
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilixNode.get = function(node, doc) {
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix var instance = null,
51dc158adbe2c9d1df3c941cbf78b90944d1afc2Markus Engel cachedNode,
f4dbc5a10ebf95900d1ef56d74aad0474e159370Markus Engel uid;
f4dbc5a10ebf95900d1ef56d74aad0474e159370Markus Engel
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert if (node) {
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix if (typeof node === 'string') {
a46424e0405b8e0eb958a49328effd2327660e4ecilix if (node.indexOf('doc') === 0) { // doc OR document
850cbc29823aa92a03e97caba1e3102b53d7c833cilix node = Y.config.doc;
850cbc29823aa92a03e97caba1e3102b53d7c833cilix } else if (node.indexOf('win') === 0) { // win OR window
850cbc29823aa92a03e97caba1e3102b53d7c833cilix node = Y.config.win;
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix } else {
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix node = Y.Selector.query(node, doc, true);
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix }
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix if (!node) {
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert return null;
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix }
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix } else if (node instanceof Node) {
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert return node; // NOTE: return
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix }
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert uid = node._yuid;
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix cachedNode = g_nodes[uid];
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix instance = Node._instances[uid]; // reuse exising instances
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert if (!instance || (cachedNode && node !== cachedNode)) { // new Node when nodes don't match
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix instance = new Node(node);
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix }
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix }
51dc158adbe2c9d1df3c941cbf78b90944d1afc2Markus Engel return instance;
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix};
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix/**
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * Creates a new dom node using the provided markup string.
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * @method create
c4ae5c46c1d9c171f96e47e81f2f0f5f0e189547cilix * @static
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert * @param {String} html The markup used to create the element
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * @param {HTMLDocument} doc An optional document context
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix */
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilixNode.create = function() {
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix return Node.get(Y.DOM.create.apply(Y.DOM, arguments));
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix};
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix
c4ae5c46c1d9c171f96e47e81f2f0f5f0e189547cilixNode.ATTRS = {
c4ae5c46c1d9c171f96e47e81f2f0f5f0e189547cilix /**
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * Allows for getting and setting the text of an element.
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * Formatting is preserved and special characters are treated literally.
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * @config text
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * @type String
c4ae5c46c1d9c171f96e47e81f2f0f5f0e189547cilix */
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix text: {
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix getter: function() {
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix return Y.DOM.getText(g_nodes[this[UID]]);
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix },
c4ae5c46c1d9c171f96e47e81f2f0f5f0e189547cilix
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix setter: function(content) {
c4ae5c46c1d9c171f96e47e81f2f0f5f0e189547cilix Y.DOM.setText(g_nodes[this[UID]], content);
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix return content;
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix }
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix },
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert 'options': {
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix getter: function() {
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix return this.getElementsByTagName('option');
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix }
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert },
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix /**
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * Returns a NodeList instance of all HTMLElement children.
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * @readOnly
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * @config children
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert * @type NodeList
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix */
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix 'children': {
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix getter: function() {
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix var node = g_nodes[this[UID]],
60282e8335d7b6ae7020613bb22c7c69a6909fbbJon A. Cruz children = node.children,
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix childNodes, i, len;
9dc68827cbd515262ecb8d5ae8547d9e82c72e00Jon A. Cruz
9dc68827cbd515262ecb8d5ae8547d9e82c72e00Jon A. Cruz if (!children) {
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix childNodes = node.childNodes;
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix children = [];
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix for (i = 0, len = childNodes.length; i < len; ++i) {
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix if (childNodes[i][TAG_NAME]) {
71dea9c6fbd2fd6d73cce6f1ed96151d51ada58fcilix children[children.length] = childNodes[i];
71dea9c6fbd2fd6d73cce6f1ed96151d51ada58fcilix }
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix }
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix }
9dc68827cbd515262ecb8d5ae8547d9e82c72e00Jon A. Cruz return Y.all(children);
9dc68827cbd515262ecb8d5ae8547d9e82c72e00Jon A. Cruz }
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix },
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix value: {
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix getter: function() {
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert return Y.DOM.getValue(g_nodes[this[UID]]);
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix },
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix setter: function(val) {
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix Y.DOM.setValue(g_nodes[this[UID]], val);
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix return val;
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix }
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix },
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix getter: function() {
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix return this._data;
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix },
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert
c4ae5c46c1d9c171f96e47e81f2f0f5f0e189547cilix setter: function(val) {
c4ae5c46c1d9c171f96e47e81f2f0f5f0e189547cilix this._data = val;
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix return val;
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert }
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix};
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix
60282e8335d7b6ae7020613bb22c7c69a6909fbbJon A. Cruz// call with instance context
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilixNode.DEFAULT_SETTER = function(name, val) {
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix var node = this._stateProxy,
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix strPath;
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert if (name.indexOf(DOT) > -1) {
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix strPath = name;
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix name = name.split(DOT);
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix // only allow when defined on node
d37634d73670180f99a3e0ea583621373d90ec4fJohan Engelen Y.Object.setValue(node, name, val);
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert } else if (node[name] !== undefined) { // pass thru DOM properties
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix node[name] = val;
60282e8335d7b6ae7020613bb22c7c69a6909fbbJon A. Cruz }
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix return val;
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix};
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix// call with instance context
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian AlbertNode.DEFAULT_GETTER = function(name) {
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix var node = this._stateProxy,
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix val;
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix if (name.indexOf && name.indexOf(DOT) > -1) {
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert val = Y.Object.getValue(node, name.split(DOT));
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert } else if (node[name] !== undefined) { // pass thru from DOM
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix val = node[name];
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix }
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert return val ? Y.Node.scrubVal(val, this) : val;
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix};
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian AlbertY.augment(Node, Y.Event.Target);
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilixY.augment(Node, Y.Plugin.Host);
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilixY.mix(Node.prototype, {
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix toString: function() {
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert var str = '',
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert errorMsg = this[UID] + ': not bound to a node',
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert node = g_nodes[this[UID]];
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert if (node) {
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix str += node[NODE_NAME];
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix if (node.id) {
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix str += '#' + node.id;
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix }
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert if (node.className) {
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix str += '.' + node.className.replace(' ', '.');
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix }
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix // TODO: add yuid?
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix str += ' ' + this[UID];
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix }
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix return str || errorMsg;
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix },
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix get: function(attr) {
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix var attrConfig = Node.ATTRS[attr],
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix val;
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert if (attrConfig && attrConfig.getter) {
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert val = attrConfig.getter.call(this);
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix } else if (Node.re_aria.test(attr)) {
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert val = Y.Node.getDOMNode(this).getAttribute(attr, 2);
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix } else {
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix val = Node.DEFAULT_GETTER.apply(this, arguments);
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix }
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix return val;
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix },
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert set: function(attr, val) {
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix var attrConfig = Node.ATTRS[attr];
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert if (attrConfig && attrConfig.setter) {
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert attrConfig.setter.call(this, val);
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert } else if (Node.re_aria.test(attr)) {
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert Y.Node.getDOMNode(this).setAttribute(attr, val);
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert } else {
60282e8335d7b6ae7020613bb22c7c69a6909fbbJon A. Cruz Node.DEFAULT_SETTER.apply(this, arguments);
3f9c2aaadaf4dd5bb8f29d92098dcb6805ca9d97cilix }
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix return this;
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix },
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix /**
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert * Creates a new Node using the provided markup string.
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert * @method create
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert * @param {String} html The markup used to create the element
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * @param {HTMLDocument} doc An optional document context
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert */
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix create: Node.create,
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix /**
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * Compares nodes to determine if they match.
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * Node instances can be compared to each other and/or HTMLElements.
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * @method compareTo
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * @param {HTMLElement | Node} refNode The reference node to compare to the node.
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * @return {Boolean} True if the nodes match, false if they do not.
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix */
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert compareTo: function(refNode) {
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert var node = g_nodes[this[UID]];
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix if (refNode instanceof Y.Node) {
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert refNode = Y.Node.getDOMNode(refNode);
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix }
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix return node === refNode;
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix },
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix /**
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * Determines whether the node is appended to the document.
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * @method inDoc
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * @param {Node|HTMLElement} doc optional An optional document to check against.
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert * Defaults to current document.
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * @return {Boolean} Whether or not this node is appended to the document.
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix */
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix inDoc: function(doc) {
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix var node = g_nodes[this[UID]];
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix doc = (doc) ? Node.getDOMNode(doc) : node[OWNER_DOCUMENT];
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix if (doc.documentElement) {
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix return Y.DOM.contains(doc.documentElement, node);
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix }
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix },
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix getById: function(id) {
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix var node = g_nodes[this[UID]],
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix ret = Y.DOM.byId(id, node[OWNER_DOCUMENT]);
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix if (ret && Y.DOM.contains(node, ret)) {
e2d40573e3eece043a9e2607f851ed1d32251242cilix ret = Y.get(ret);
60282e8335d7b6ae7020613bb22c7c69a6909fbbJon A. Cruz } else {
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix ret = null;
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix }
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix return ret;
67f112a66b477fe7fb28c644a4deaf0793533838joncruz },
67f112a66b477fe7fb28c644a4deaf0793533838joncruz
67f112a66b477fe7fb28c644a4deaf0793533838joncruz /**
67f112a66b477fe7fb28c644a4deaf0793533838joncruz * Returns the nearest ancestor that passes the test applied by supplied boolean method.
67f112a66b477fe7fb28c644a4deaf0793533838joncruz * @method ancestor
67f112a66b477fe7fb28c644a4deaf0793533838joncruz * @param {String | Function} fn A selector string or boolean method for testing elements.
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * If a function is used, it receives the current node being tested as the only argument.
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * @return {Node} The matching Node instance or null if not found
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix */
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix ancestor: function(fn) {
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix return Node.get(Y.DOM.elementByAxis(g_nodes[this[UID]], 'parentNode', _wrapFn(fn)));
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix },
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix /**
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * Returns the previous matching sibling.
fa90912de6e92199e5fa5957d1d47fd485abc011cilix * Returns the nearest element node sibling if no method provided.
fa90912de6e92199e5fa5957d1d47fd485abc011cilix * @method previous
e711b02fbbe0b7d07102ebdd63b05027d6f8af47Maximilian Albert * @param {String | Function} fn A selector or boolean method for testing elements.
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert * If a function is used, it receives the current node being tested as the only argument.
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert * @return {Node} Node instance or null if not found
e711b02fbbe0b7d07102ebdd63b05027d6f8af47Maximilian Albert */
fa90912de6e92199e5fa5957d1d47fd485abc011cilix previous: function(fn, all) {
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert return Node.get(Y.DOM.elementByAxis(g_nodes[this[UID]], 'previousSibling', _wrapFn(fn), all));
71dea9c6fbd2fd6d73cce6f1ed96151d51ada58fcilix },
fa90912de6e92199e5fa5957d1d47fd485abc011cilix
fa90912de6e92199e5fa5957d1d47fd485abc011cilix /**
fa90912de6e92199e5fa5957d1d47fd485abc011cilix * Returns the next matching sibling.
fa90912de6e92199e5fa5957d1d47fd485abc011cilix * Returns the nearest element node sibling if no method provided.
fa90912de6e92199e5fa5957d1d47fd485abc011cilix * @method next
fa90912de6e92199e5fa5957d1d47fd485abc011cilix * @param {String | Function} fn A selector or boolean method for testing elements.
fa90912de6e92199e5fa5957d1d47fd485abc011cilix * If a function is used, it receives the current node being tested as the only argument.
3ca2560f1103677939f8b6e8de30865c3aef7fe0cilix * @return {Node} Node instance or null if not found
3ca2560f1103677939f8b6e8de30865c3aef7fe0cilix */
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix next: function(node, fn, all) {
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix return Node.get(Y.DOM.elementByAxis(g_nodes[this[UID]], 'nextSibling', _wrapFn(fn), all));
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert },
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix /**
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * Retrieves a Node instance of nodes based on the given CSS selector.
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * @method query
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix *
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * @param {string} selector The CSS selector to test against.
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * @return {Node} A Node instance for the matching HTMLElement.
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix */
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix query: function(selector) {
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix return Y.get(Y.Selector.query(selector, g_nodes[this[UID]], true));
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix },
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert /**
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert * Retrieves a nodeList based on the given CSS selector.
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * @method queryAll
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix *
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * @param {string} selector The CSS selector to test against.
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * @return {NodeList} A NodeList instance for the matching HTMLCollection/Array.
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix */
9dc68827cbd515262ecb8d5ae8547d9e82c72e00Jon A. Cruz queryAll: function(selector) {
9dc68827cbd515262ecb8d5ae8547d9e82c72e00Jon A. Cruz return Y.all(Y.Selector.query(selector, g_nodes[this[UID]]));
07b7f1aaaf1087716e784a50cf574a059f7018d3Jon A. Cruz },
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix // TODO: allow fn test
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix /**
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * Test if the supplied node matches the supplied selector.
13223d251a0eca100512280a15dc9b2213a28809cilix * @method test
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix *
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * @param {string} selector The CSS selector to test against.
13223d251a0eca100512280a15dc9b2213a28809cilix * @return {boolean} Whether or not the node matches the selector.
13223d251a0eca100512280a15dc9b2213a28809cilix */
13223d251a0eca100512280a15dc9b2213a28809cilix test: function(selector) {
13223d251a0eca100512280a15dc9b2213a28809cilix return Y.Selector.test(g_nodes[this[UID]], selector);
13223d251a0eca100512280a15dc9b2213a28809cilix },
71dea9c6fbd2fd6d73cce6f1ed96151d51ada58fcilix
13223d251a0eca100512280a15dc9b2213a28809cilix /**
71dea9c6fbd2fd6d73cce6f1ed96151d51ada58fcilix * Removes the node from its parent.
13223d251a0eca100512280a15dc9b2213a28809cilix * Shortcut for myNode.get('parentNode').removeChild(myNode);
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert * @method remove
60282e8335d7b6ae7020613bb22c7c69a6909fbbJon A. Cruz * @chainable
e711b02fbbe0b7d07102ebdd63b05027d6f8af47Maximilian Albert *
e711b02fbbe0b7d07102ebdd63b05027d6f8af47Maximilian Albert */
e711b02fbbe0b7d07102ebdd63b05027d6f8af47Maximilian Albert remove: function() {
13223d251a0eca100512280a15dc9b2213a28809cilix var node = g_nodes[this[UID]];
13223d251a0eca100512280a15dc9b2213a28809cilix node.parentNode.removeChild(node);
13223d251a0eca100512280a15dc9b2213a28809cilix return this;
13223d251a0eca100512280a15dc9b2213a28809cilix },
13223d251a0eca100512280a15dc9b2213a28809cilix
13223d251a0eca100512280a15dc9b2213a28809cilix /**
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert * Invokes a method on the Node instance
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert * @method invoke
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert * @param {String} method The name of the method to invoke
60282e8335d7b6ae7020613bb22c7c69a6909fbbJon A. Cruz * @param {Any} a, b, c, etc. Arguments to invoke the method with.
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert * @return Whatever the underly method returns.
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert * DOM Nodes and Collections return values
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * are converted to Node/NodeList instances.
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix *
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix */
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix invoke: function(method, a, b, c, d, e) {
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix var node = g_nodes[this[UID]],
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix ret;
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix if (a && a instanceof Y.Node) {
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix a = Node.getDOMNode(a);
a4030d5ca449e7e384bc699cd249ee704faaeab0Chris Morgan }
if (b && b instanceof Y.Node) {
b = Node.getDOMNode(b);
}
ret = node[method](a, b, c, d, e);
return Y.Node.scrubVal(ret, this);
},
destructor: function() {
// TODO: What about shared instances?
//var uid = this[UID];
//delete g_nodes[uid];
//delete Node._instances[uid];
},
/**
* Applies the given function to each Node in the NodeList.
* @method each
* @deprecated Use NodeList
* @param {Function} fn The function to apply
* @param {Object} context optional An optional context to apply the function with
* Default context is the NodeList instance
* @chainable
*/
each: function(fn, context) {
context = context || this;
Y.log('each is deprecated on Node', 'warn', 'Node');
return fn.call(context, this);
},
/**
* Retrieves the Node instance at the given index.
* @method item
* @deprecated Use NodeList
*
* @param {Number} index The index of the target Node.
* @return {Node} The Node instance at the given index.
*/
item: function(index) {
Y.log('item is deprecated on Node', 'warn', 'Node');
return this;
},
/**
* Returns the current number of items in the Node.
* @method size
* @deprecated Use NodeList
* @return {Int} The number of items in the Node.
*/
size: function() {
Y.log('size is deprecated on Node', 'warn', 'Node');
return g_nodes[this[UID]] ? 1 : 0;
},
/**
* Inserts the content before the reference node.
* @method insert
* @param {String | Y.Node | HTMLElement} content The content to insert
* @param {Int | Y.Node | HTMLElement | String} where The position to insert at.
* @chainable
*/
insert: function(content, where) {
if (content) {
if (typeof where === 'number') { // allow index
where = g_nodes[this[UID]].childNodes[where];
}
if (typeof content !== 'string') { // pass the DOM node
content = Y.Node.getDOMNode(content);
}
Y.DOM.addHTML(g_nodes[this[UID]], content, where);
}
return this;
},
/**
* Inserts the content as the firstChild of the node.
* @method prepend
* @param {String | Y.Node | HTMLElement} content The content to insert
* @chainable
*/
prepend: function(content) {
return this.insert(content, 0);
},
/**
* Inserts the content as the lastChild of the node.
* @method append
* @param {String | Y.Node | HTMLElement} content The content to insert
* @chainable
*/
append: function(content) {
return this.insert(content, null);
},
/**
* Replaces the node's current content with the content.
* @method setContent
* @param {String | Y.Node | HTMLElement} content The content to insert
* @chainable
*/
setContent: function(content) {
Y.DOM.addHTML(g_nodes[this[UID]], content, 'replace');
return this;
},
// TODO: need this?
hasMethod: function(method) {
var node = g_nodes[this[UID]];
return (node && (typeof node === 'function'));
}
}, true);
Y.Node = Node;
Y.get = Y.Node.get;
Y.first = Y.Node.get;