~ted/lazr-js/annoying-debug-message

« back to all changes in this revision

Viewing changes to src-js/lazrjs/yui/node/node.js

  • Committer: Launchpad Patch Queue Manager
  • Date: 2010-09-09 14:20:30 UTC
  • mfrom: (182.1.3 yui-3.2)
  • Revision ID: launchpad@pqm.canonical.com-20100909142030-13w6vo0ixfysxc15
[r=beuno] Update lazr-js to yui-3.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
3
3
Code licensed under the BSD License:
4
4
http://developer.yahoo.com/yui/license.html
5
 
version: 3.1.2
6
 
build: 56
 
5
version: 3.2.0
 
6
build: 2676
7
7
*/
8
8
YUI.add('node-base', function(Y) {
9
9
 
38
38
    Y_DOM = Y.DOM,
39
39
 
40
40
    Y_Node = function(node) {
41
 
        var uid = node[UID];
 
41
        var uid = (node.nodeType !== 9) ? node.uniqueID : node[UID];
42
42
 
43
43
        if (uid && Y_Node._instances[uid] && Y_Node._instances[uid]._node !== node) {
44
44
            node[UID] = null; // unset existing uid to prevent collision (via clone or hack)
45
45
        }
46
46
 
47
 
        uid = Y.stamp(node);
 
47
        uid = uid || Y.stamp(node);
48
48
        if (!uid) { // stamp failed; likely IE non-HTMLElement
49
49
            uid = Y.guid();
50
50
        }
61
61
 
62
62
        this._stateProxy = node; // when augmented with Attribute
63
63
 
 
64
        Y.EventTarget.call(this, {emitFacade:true});
 
65
 
64
66
        if (this._initPlugins) { // when augmented with Plugin.Host
65
67
            this._initPlugins();
66
68
        }
106
108
    beforeunload: 1,
107
109
    blur: 1,
108
110
    change: 1,
109
 
    changedTouches: 1, // iphone
110
111
    click: 1,
111
112
    close: 1,
112
113
    command: 1,
122
123
    drop: 1,
123
124
    error: 1,
124
125
    focus: 1,
125
 
    identifier: 1, // iphone
126
126
    key: 1,
127
127
    keydown: 1,
128
128
    keypress: 1,
140
140
    mousewheel: 1,
141
141
    reset: 1,
142
142
    resize: 1,
143
 
    rotation: 1, // iphone
144
 
    scale: 1, // iphone
145
143
    select: 1,
 
144
    selectstart: 1,
146
145
    submit: 1,
147
146
    scroll: 1,
148
 
    targetTouches: 1, // iphone
149
147
    textInput: 1,
150
 
    touches: 1, // iphone
151
148
    unload: 1
152
149
};
153
150
 
194
191
 */
195
192
Y_Node.scrubVal = function(val, node) {
196
193
    if (node && val) { // only truthy values are risky
197
 
        if (typeof val === 'object' || typeof val === 'function') { // safari nodeList === function
 
194
         if (typeof val === 'object' || typeof val === 'function') { // safari nodeList === function
198
195
            if (NODE_TYPE in val || Y_DOM.isWindow(val)) {// node || window
199
196
                val = Y.one(val);
200
197
            } else if ((val.item && !val._nodes) || // dom collection or Node instance
204
201
        }
205
202
    } else if (val === undefined) {
206
203
        val = node; // for chaining
 
204
    } else if (val === null) {
 
205
        val = null; // IE: DOM null not the same as null
207
206
    }
208
207
 
209
208
    return val;
294
293
            return node; // NOTE: return
295
294
        }
296
295
 
297
 
        uid = node._yuid;
298
 
        instance = Y_Node._instances[uid]; // reuse exising instances
299
 
        cachedNode = instance ? instance._node : null;
300
 
        if (!instance || (cachedNode && node !== cachedNode)) { // new Node when nodes don't match
301
 
            instance = new Y_Node(node);
 
296
        if (node.nodeType || Y.DOM.isWindow(node)) { // avoid bad input (numbers, boolean, etc)
 
297
            uid = (node.uniqueID && node.nodeType !== 9) ? node.uniqueID : node._yuid;
 
298
            instance = Y_Node._instances[uid]; // reuse exising instances
 
299
            cachedNode = instance ? instance._node : null;
 
300
            if (!instance || (cachedNode && node !== cachedNode)) { // new Node when nodes don't match
 
301
                instance = new Y_Node(node);
 
302
            }
302
303
        }
303
304
    }
304
305
    return instance;
359
360
        }
360
361
    },
361
362
 
362
 
     // IE: elements collection is also FORM node which trips up scrubVal.
363
 
     // preconverting to NodeList
364
 
     // TODO: break out for IE only
365
 
    'elements': {
366
 
        getter: function() {
367
 
            return Y.all(this._node.elements);
368
 
        }
369
 
    },
370
 
 
371
363
    /**
372
364
     * Returns a NodeList instance of all HTMLElement children.
373
365
     * @readOnly
470
462
    return val;
471
463
};
472
464
 
473
 
Y.augment(Y_Node, Y.Event.Target);
 
465
// Basic prototype augment - no lazy constructor invocation.
 
466
Y.mix(Y_Node, Y.EventTarget, false, null, 1);
474
467
 
475
468
Y.mix(Y_Node.prototype, {
476
469
/**
479
472
 * @return {String} A string representation of the Node instance 
480
473
 */
481
474
    toString: function() {
482
 
        var str = '',
483
 
            errorMsg = this[UID] + ': not bound to a node',
 
475
        var str = this[UID] + ': not bound to a node',
484
476
            node = this._node,
485
 
            id = node.getAttribute('id'); // form.id may be a field name
 
477
            attrs, id, className;
486
478
 
487
479
        if (node) {
488
 
            str += node[NODE_NAME];
 
480
            attrs = node.attributes;
 
481
            id = (attrs && attrs.id) ? node.getAttribute('id') : null;
 
482
            className = (attrs && attrs.className) ? node.getAttribute('className') : null;
 
483
            str = node[NODE_NAME];
 
484
 
489
485
            if (id) {
490
486
                str += '#' + id; 
491
487
            }
492
488
 
493
 
            if (node.className) {
494
 
                str += '.' + node.className.replace(' ', '.'); 
 
489
            if (className) {
 
490
                str += '.' + className.replace(' ', '.'); 
495
491
            }
496
492
 
497
493
            // TODO: add yuid?
498
494
            str += ' ' + this[UID];
499
495
        }
500
 
        return str || errorMsg;
 
496
        return str;
501
497
    },
502
498
 
503
499
    /**
520
516
 
521
517
        if (val) {
522
518
            val = Y_Node.scrubVal(val, this);
 
519
        } else if (val === null) {
 
520
            val = null; // IE: DOM null is not true null (even though they ===)
523
521
        }
524
522
        return val;
525
523
    },
630
628
     */
631
629
    compareTo: function(refNode) {
632
630
        var node = this._node;
 
631
 
633
632
        if (refNode instanceof Y_Node) { 
634
633
            refNode = refNode._node;
635
634
        }
907
906
     * @method insert
908
907
     * @param {String | Y.Node | HTMLElement} content The content to insert 
909
908
     * @param {Int | Y.Node | HTMLElement | String} where The position to insert at.
 
909
     * Possible "where" arguments
 
910
     * <dl>
 
911
     * <dt>Y.Node</dt>
 
912
     * <dd>The Node to insert before</dd>
 
913
     * <dt>HTMLElement</dt>
 
914
     * <dd>The element to insert before</dd>
 
915
     * <dt>Int</dt>
 
916
     * <dd>The index of the child element to insert before</dd>
 
917
     * <dt>"replace"</dt>
 
918
     * <dd>Replaces the existing HTML</dd>
 
919
     * <dt>"before"</dt>
 
920
     * <dd>Inserts before the existing HTML</dd>
 
921
     * <dt>"before"</dt>
 
922
     * <dd>Inserts content before the node</dd>
 
923
     * <dt>"after"</dt>
 
924
     * <dd>Inserts content after the node</dd>
 
925
     * </dl>
910
926
     * @chainable
911
927
     */
912
928
    insert: function(content, where) {
968
984
            if (content._node) { // map to DOMNode
969
985
                content = content._node;
970
986
            } else if (content._nodes) { // convert DOMNodeList to documentFragment
971
 
                content = Y_DOM._nl2Frag(content._nodes);
 
987
                content = Y_DOM._nl2frag(content._nodes);
972
988
            }
973
989
 
974
990
        }
984
1000
    * @param {Node} otherNode The node to swap with
985
1001
     * @chainable
986
1002
    */
987
 
    swap: document.documentElement.swapNode ? 
 
1003
    swap: Y.config.doc.documentElement.swapNode ? 
988
1004
        function(otherNode) {
989
1005
            this._node.swapNode(Y_Node.getDOMNode(otherNode));
990
1006
        } :
1056
1072
    * @chainable
1057
1073
    */
1058
1074
    clearData: function(name) {
1059
 
        if (arguments.length) {
 
1075
        if (this._data && arguments.length) {
1060
1076
            delete this._data[name];
1061
1077
        } else {
1062
1078
            this._data = {};
1067
1083
 
1068
1084
    hasMethod: function(method) {
1069
1085
        var node = this._node;
1070
 
        return (node && node[method] && (typeof node[method] === 'function'));
 
1086
        return !!(node && method in node &&
 
1087
                typeof node[method] !== 'unknown' &&
 
1088
            (typeof node[method] === 'function' ||
 
1089
                String(node[method]).indexOf('function') === 1)); // IE reports as object, prepends space
1071
1090
    }
1072
1091
}, true);
1073
1092
 
1094
1113
    if (typeof nodes === 'string') { // selector query
1095
1114
        this._query = nodes;
1096
1115
        nodes = Y.Selector.query(nodes);
1097
 
    } else if (nodes.nodeType) { // domNode
 
1116
    } else if (nodes.nodeType || Y_DOM.isWindow(nodes)) { // domNode || window
1098
1117
        nodes = [nodes];
1099
1118
    } else if (nodes instanceof Y.Node) {
1100
1119
        nodes = [nodes._node];
1109
1128
        nodes = Y.Array(nodes, 0, true);
1110
1129
    }
1111
1130
 
1112
 
    NodeList._instances[Y.stamp(this)] = this;
1113
1131
    /**
1114
1132
     * The underlying array of DOM nodes bound to the Y.NodeList instance
1115
1133
     * @property _nodes
1132
1150
    return nodeList._nodes;
1133
1151
};
1134
1152
 
1135
 
NodeList._instances = [];
1136
 
 
1137
1153
NodeList.each = function(instance, fn, context) {
1138
1154
    var nodes = instance._nodes;
1139
1155
    if (nodes && nodes.length) {
1149
1165
                args = arguments;
1150
1166
 
1151
1167
            Y.Array.each(this._nodes, function(node) {
1152
 
                var UID = '_yuid',
 
1168
                var UID = (node.uniqueID && node.nodeType !== 9 ) ? 'uniqueID' : '_yuid',
1153
1169
                    instance = Y.Node._instances[node[UID]],
1154
1170
                    ctx,
1155
1171
                    result;
1330
1346
    },
1331
1347
 
1332
1348
    destructor: function() {
1333
 
        delete NodeList._instances[this[UID]];
1334
1349
    },
1335
1350
 
1336
1351
    /**
1357
1372
        return this;
1358
1373
    },
1359
1374
 
 
1375
    _prepEvtArgs: function(type, fn, context) {
 
1376
        // map to Y.on/after signature (type, fn, nodes, context, arg1, arg2, etc)
 
1377
        var args = Y.Array(arguments, 0, true);
 
1378
 
 
1379
        if (args.length < 2) { // type only (event hash) just add nodes
 
1380
            args[2] = this._nodes;
 
1381
        } else {
 
1382
            args.splice(2, 0, this._nodes);
 
1383
        }
 
1384
 
 
1385
        args[3] = context || this; // default to NodeList instance as context
 
1386
 
 
1387
        return args;
 
1388
    },
 
1389
 
1360
1390
    /**
1361
1391
     * Applies an event listener to each Node bound to the NodeList. 
1362
1392
     * @method on
1368
1398
     * @see Event.on
1369
1399
     */
1370
1400
    on: function(type, fn, context) {
1371
 
        var args = Y.Array(arguments, 0, true);
1372
 
        args.splice(2, 0, this._nodes);
1373
 
        args[3] = context || this;
1374
 
        return Y.on.apply(Y, args);
 
1401
        return Y.on.apply(Y, this._prepEvtArgs.apply(this, arguments));
1375
1402
    },
1376
1403
 
1377
1404
    /**
1387
1414
     * @see Event.on
1388
1415
     */
1389
1416
    after: function(type, fn, context) {
1390
 
        var args = Y.Array(arguments, 0, true);
1391
 
        args.splice(2, 0, this._nodes);
1392
 
        args[3] = context || this;
1393
 
        return Y.after.apply(Y, args);
 
1417
        return Y.after.apply(Y, this._prepEvtArgs.apply(this, arguments));
1394
1418
    },
1395
1419
 
1396
1420
    /**
1478
1502
    'remove',
1479
1503
 
1480
1504
    /** Called on each Node instance
1481
 
      * @method removeAttribute
1482
 
      * @see Node.removeAttribute
1483
 
      */
1484
 
    'removeAttribute',
1485
 
 
1486
 
    /** Called on each Node instance
1487
1505
      * @method set
1488
1506
      * @see Node.set
1489
1507
      */
1721
1739
 * @param {string} name The attribute name 
1722
1740
 * @return {string} The attribute value 
1723
1741
 */
 
1742
 
 
1743
/**
 
1744
 * Allows for removing attributes on DOM nodes.
 
1745
 * This passes through to the DOM node, allowing for custom attributes.
 
1746
 * @method removeAttribute
 
1747
 * @see Node
 
1748
 * @for NodeList
 
1749
 * @param {string} name The attribute to remove 
 
1750
 */
1724
1751
Y.NodeList.importMethod(Y.Node.prototype, ['getAttribute', 'setAttribute', 'removeAttribute']);
1725
1752
(function(Y) {
1726
1753
    var methods = [
1814
1841
    Y.NodeList.importMethod(Y.Node.prototype, methods);
1815
1842
})(Y);
1816
1843
 
1817
 
if (!document.documentElement.hasAttribute) { // IE < 8
 
1844
if (!Y.config.doc.documentElement.hasAttribute) { // IE < 8
1818
1845
    Y.Node.prototype.hasAttribute = function(attr) {
 
1846
        if (attr === 'value') {
 
1847
            if (this.get('value') !== "") { // IE < 8 fails to populate specified when set in HTML
 
1848
                return true;
 
1849
            }
 
1850
        }
1819
1851
        return !!(this._node.attributes[attr] &&
1820
1852
                this._node.attributes[attr].specified);
1821
1853
    };
1848
1880
    _bypassProxy: true // don't update DOM when using with Attribute
1849
1881
};
1850
1882
 
1851
 
 
1852
 
}, '3.1.2' ,{requires:['dom-base', 'selector-css2', 'event-base']});
 
1883
if (Y.config.doc.createElement('form').elements.nodeType) {
 
1884
    // IE: elements collection is also FORM node which trips up scrubVal.
 
1885
    Y.Node.ATTRS.elements = {
 
1886
            getter: function() {
 
1887
                return this.all('input, textarea, button, select');
 
1888
            }
 
1889
    };
 
1890
}
 
1891
 
 
1892
Y.mix(Y.Node.ATTRS, {
 
1893
    offsetHeight: {
 
1894
        setter: function(h) {
 
1895
            Y.DOM.setHeight(this._node, h);
 
1896
            return h;
 
1897
        },
 
1898
 
 
1899
        getter: function() {
 
1900
            return this._node.offsetHeight;
 
1901
        }
 
1902
    },
 
1903
 
 
1904
    offsetWidth: {
 
1905
        setter: function(w) {
 
1906
            Y.DOM.setWidth(this._node, w);
 
1907
            return w;
 
1908
        },
 
1909
 
 
1910
        getter: function() {
 
1911
            return this._node.offsetWidth;
 
1912
        }
 
1913
    }
 
1914
});
 
1915
 
 
1916
Y.mix(Y.Node.prototype, {
 
1917
    sizeTo: function(w, h) {
 
1918
        var node;
 
1919
        if (arguments.length < 2) {
 
1920
            node = Y.one(w);
 
1921
            w = node.get('offsetWidth');
 
1922
            h = node.get('offsetHeight');
 
1923
        }
 
1924
 
 
1925
        this.setAttrs({
 
1926
            offsetWidth: w,
 
1927
            offsetHeight: h
 
1928
        });
 
1929
    }
 
1930
});
 
1931
 
 
1932
 
 
1933
}, '3.2.0' ,{requires:['dom-base', 'selector-css2', 'event-base']});
1853
1934
YUI.add('node-style', function(Y) {
1854
1935
 
1855
1936
(function(Y) {
1930
2011
 */
1931
2012
Y.NodeList.importMethod(Y.Node.prototype, methods);
1932
2013
})(Y);
1933
 
Y.mix(Y.Node.ATTRS, {
1934
 
    offsetHeight: {
1935
 
        setter: function(h) {
1936
 
            Y.DOM.setHeight(this._node, h);
1937
 
            return h;
1938
 
        },
1939
 
 
1940
 
        getter: function() {
1941
 
            return this._node.offsetHeight;
1942
 
        }
1943
 
    },
1944
 
 
1945
 
    offsetWidth: {
1946
 
        setter: function(w) {
1947
 
            Y.DOM.setWidth(this._node, w);
1948
 
            return w;
1949
 
        },
1950
 
 
1951
 
        getter: function() {
1952
 
            return this._node.offsetWidth;
1953
 
        }
1954
 
    }
1955
 
});
1956
 
 
1957
 
Y.mix(Y.Node.prototype, {
1958
 
    sizeTo: function(w, h) {
1959
 
        var node;
1960
 
        if (arguments.length < 2) {
1961
 
            node = Y.one(w);
1962
 
            w = node.get('offsetWidth');
1963
 
            h = node.get('offsetHeight');
1964
 
        }
1965
 
 
1966
 
        this.setAttrs({
1967
 
            offsetWidth: w,
1968
 
            offsetHeight: h
1969
 
        });
1970
 
    }
1971
 
});
1972
 
 
1973
 
 
1974
 
}, '3.1.2' ,{requires:['dom-style', 'node-base']});
 
2014
 
 
2015
 
 
2016
}, '3.2.0' ,{requires:['dom-style', 'node-base']});
1975
2017
YUI.add('node-screen', function(Y) {
1976
2018
 
1977
2019
/**
2204
2246
};
2205
2247
 
2206
2248
 
2207
 
}, '3.1.2' ,{requires:['dom-screen']});
 
2249
}, '3.2.0' ,{requires:['dom-screen']});
2208
2250
YUI.add('node-pluginhost', function(Y) {
2209
2251
 
2210
2252
/**
2258
2300
};
2259
2301
 
2260
2302
 
2261
 
}, '3.1.2' ,{requires:['node-base', 'pluginhost']});
 
2303
}, '3.2.0' ,{requires:['node-base', 'pluginhost']});
2262
2304
YUI.add('node-event-delegate', function(Y) {
2263
2305
 
2264
2306
/**
2268
2310
 */
2269
2311
 
2270
2312
/**
2271
 
 * Functionality to make the node a delegated event container
 
2313
 * <p>Sets up a delegation listener for an event occurring inside the Node.
 
2314
 * The delegated event will be verified against a supplied selector or
 
2315
 * filtering function to test if the event references at least one node that
 
2316
 * should trigger the subscription callback.</p>
 
2317
 *
 
2318
 * <p>Selector string filters will trigger the callback if the event originated
 
2319
 * from a node that matches it or is contained in a node that matches it.
 
2320
 * Function filters are called for each Node up the parent axis to the
 
2321
 * subscribing container node, and receive at each level the Node and the event
 
2322
 * object.  The function should return true (or a truthy value) if that Node
 
2323
 * should trigger the subscription callback.  Note, it is possible for filters
 
2324
 * to match multiple Nodes for a single event.  In this case, the delegate
 
2325
 * callback will be executed for each matching Node.</p>
 
2326
 *
 
2327
 * <p>For each matching Node, the callback will be executed with its 'this'
 
2328
 * object set to the Node matched by the filter (unless a specific context was
 
2329
 * provided during subscription), and the provided event's
 
2330
 * <code>currentTarget</code> will also be set to the matching Node.  The
 
2331
 * containing Node from which the subscription was originally made can be
 
2332
 * referenced as <code>e.container</code>.
 
2333
 *
2272
2334
 * @method delegate
2273
2335
 * @param type {String} the event type to delegate
2274
 
 * @param fn {Function} the function to execute
2275
 
 * @param selector {String} a selector that must match the target of the event.
2276
 
 * @return {Event.Handle} the detach handle
 
2336
 * @param fn {Function} the callback function to execute.  This function
 
2337
 *              will be provided the event object for the delegated event.
 
2338
 * @param spec {String|Function} a selector that must match the target of the
 
2339
 *              event or a function to test target and its parents for a match
 
2340
 * @param context {Object} optional argument that specifies what 'this' refers to.
 
2341
 * @param args* {any} 0..n additional arguments to pass on to the callback function.
 
2342
 *              These arguments will be added after the event object.
 
2343
 * @return {EventHandle} the detach handle
2277
2344
 * @for Node
2278
2345
 */
2279
2346
Y.Node.prototype.delegate = function(type, fn, selector) {
2280
2347
 
2281
 
    var args = Array.prototype.slice.call(arguments, 3),
2282
 
        a = [type, fn, Y.Node.getDOMNode(this), selector];
2283
 
    a = a.concat(args);
2284
 
 
2285
 
    return Y.delegate.apply(Y, a);
 
2348
    var args = Y.Array(arguments, 0, true);
 
2349
 
 
2350
    args.splice(2, 0, this._node);
 
2351
 
 
2352
    return Y.delegate.apply(Y, args);
2286
2353
};
2287
2354
 
2288
2355
 
2289
 
}, '3.1.2' ,{requires:['node-base', 'event-delegate', 'pluginhost']});
2290
 
 
2291
 
 
2292
 
YUI.add('node', function(Y){}, '3.1.2' ,{requires:['dom', 'event-base', 'event-delegate', 'pluginhost'], skinnable:false, use:['node-base', 'node-style', 'node-screen', 'node-pluginhost', 'node-event-delegate']});
 
2356
}, '3.2.0' ,{requires:['node-base', 'event-delegate']});
 
2357
 
 
2358
 
 
2359
YUI.add('node', function(Y){}, '3.2.0' ,{requires:['dom', 'event-base', 'event-delegate', 'pluginhost'], use:['node-base', 'node-style', 'node-screen', 'node-pluginhost', 'node-event-delegate'], skinnable:false});
2293
2360