root / dojo / trunk / _base / NodeList.js @ 16796

Revision 16796, 22.6 kB (checked in by jburke, 19 months ago)

Fixes #8282, applying Eugene's patch with expanded unit tests for NodeList?.addContent

  • Property svn:eol-style set to native
Line 
1dojo.provide("dojo._base.NodeList");
2dojo.require("dojo._base.lang");
3dojo.require("dojo._base.array");
4
5//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
6(function(){
7
8        var d = dojo;
9//>>excludeEnd("webkitMobile");
10
11        var ap = Array.prototype, aps = ap.slice, apc = ap.concat;
12       
13        var tnl = function(a){
14                // decorate an array to make it look like a NodeList
15                a.constructor = d.NodeList;
16                dojo._mixin(a, d.NodeList.prototype);
17                return a;
18        };
19
20        var loopBody = function(f, a, o){
21                a = [0].concat(aps.call(a, 0));
22                o = o || d.global;
23                return function(node){
24                        a[0] = node;
25                        return f.apply(o, a);
26                };
27        };
28       
29        // adapters
30
31        var adaptAsForEach = function(f, o){
32                // summary: adapts a single node function to be used in the forEach-type actions
33                // f: Function: a function to adapt
34                // o: Object?: an optional context for f
35                return function(){
36                        this.forEach(loopBody(f, arguments, o));
37                        return this;    // self
38                };
39        };
40
41        var adaptAsMap = function(f, o){
42                // summary: adapts a single node function to be used in the map-type actions
43                // f: Function: a function to adapt
44                // o: Object?: an optional context for f
45                return function(){
46                        return this.map(loopBody(f, arguments, o));
47                };
48        };
49       
50        var adaptAsFilter = function(f, o){
51                // summary: adapts a single node function to be used in the filter-type actions
52                // f: Function: a function to adapt
53                // o: Object?: an optional context for f
54                return function(){
55                        return this.filter(loopBody(f, arguments, o));
56                };
57        };
58       
59        var adaptWithCondition = function(f, g, o){
60                // summary: adapts a single node function to be used in the map-type actions,
61                //              behaves like forEach() or map() depending on arguments
62                // f: Function: a function to adapt
63                // g: Function: a condition function, if true runs as map(), otherwise runs as forEach()
64                // o: Object?: an optional context for f and g
65                return function(){
66                        var a = arguments, body = loopBody(f, a, o);
67                        if(g.call(o || d.global, a)){
68                                return this.map(body);  // self
69                        }
70                        this.forEach(body);
71                        return this;    // self
72                };
73        };
74       
75        // the guard function for dojo.attr() and dojo.style()
76        var magicGuard = function(a){
77                return a.length == 1 && d.isString(a[0])
78        };
79       
80        // function to orphan nodes
81        var orphan = function(node){
82                var p = node.parentNode;
83                if(p){
84                        p.removeChild(node);
85                }
86        };
87        // FIXME: should we move orphan() to dojo.html?
88
89        dojo.NodeList = function(){
90                //      summary:
91                //              dojo.NodeList is as pseudo-subclass of Array which adds syntactic
92                //              sugar for chaining, common iteration operations, animation, and
93                //              node manipulation. NodeLists are most often returned as the result
94                //              of dojo.query() calls.
95                //      example:
96                //              create a node list from a node
97                //              |       new dojo.NodeList(dojo.byId("foo"));
98
99                return tnl(Array.apply(null, arguments));
100        };
101
102        var nl = d.NodeList, nlp = nl.prototype;
103       
104        // expose adapters and the wrapper as private functions
105       
106        nl._wrap = tnl;
107        nl._adaptAsMap = adaptAsMap;
108        nl._adaptAsForEach = adaptAsForEach;
109        nl._adaptAsFilter  = adaptAsFilter;
110        nl._adaptWithCondition = adaptWithCondition;
111       
112        // mass assignment
113       
114        // add array redirectors
115        d.forEach(["slice", "splice"], function(name){
116                var f = ap[name];
117                nlp[name] = function(){ return tnl(f.apply(this, arguments)); };
118        });
119        // concat should be here but some browsers with native NodeList have problems with it
120       
121        // add array.js redirectors
122        d.forEach(["indexOf", "lastIndexOf", "every", "some"], function(name){
123                var f = d[name];
124                nlp[name] = function(){ return f.apply(d, [this].concat(aps.call(arguments, 0))); };
125        });
126       
127        // add conditional methods
128        d.forEach(["attr", "style"], function(name){
129                nlp[name] = adaptWithCondition(d[name], magicGuard);
130        });
131       
132        // add forEach actions
133        d.forEach(["connect", "addClass", "removeClass", "toggleClass", "empty"], function(name){
134                nlp[name] = adaptAsForEach(d[name]);
135        });
136
137        dojo.extend(dojo.NodeList, {
138                // http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array#Methods
139
140                // FIXME: handle return values for #3244
141                //              http://trac.dojotoolkit.org/ticket/3244
142               
143                // FIXME:
144                //              need to wrap or implement:
145                //                      join (perhaps w/ innerHTML/outerHTML overload for toString() of items?)
146                //                      reduce
147                //                      reduceRight
148
149                /*=====
150                slice: function(begin, end){
151                        // summary:
152                        //              Returns a new NodeList, maintaining this one in place
153                        // description:
154                        //              This method behaves exactly like the Array.slice method
155                        //              with the caveat that it returns a dojo.NodeList and not a
156                        //              raw Array. For more details, see:
157                        //                      http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:slice
158                        // begin: Integer
159                        //              Can be a positive or negative integer, with positive
160                        //              integers noting the offset to begin at, and negative
161                        //              integers denoting an offset from the end (i.e., to the left
162                        //              of the end)
163                        // end: Integer?
164                        //              Optional parameter to describe what position relative to
165                        //              the NodeList's zero index to end the slice at. Like begin,
166                        //              can be positive or negative.
167                        return tnl(a.slice.apply(this, arguments));
168                },
169
170                splice: function(index, howmany, item){
171                        // summary:
172                        //              Returns a new NodeList, manipulating this NodeList based on
173                        //              the arguments passed, potentially splicing in new elements
174                        //              at an offset, optionally deleting elements
175                        // description:
176                        //              This method behaves exactly like the Array.splice method
177                        //              with the caveat that it returns a dojo.NodeList and not a
178                        //              raw Array. For more details, see:
179                        //                      <http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:splice>
180                        // index: Integer
181                        //              begin can be a positive or negative integer, with positive
182                        //              integers noting the offset to begin at, and negative
183                        //              integers denoting an offset from the end (i.e., to the left
184                        //              of the end)
185                        // howmany: Integer?
186                        //              Optional parameter to describe what position relative to
187                        //              the NodeList's zero index to end the slice at. Like begin,
188                        //              can be positive or negative.
189                        // item: Object...?
190                        //              Any number of optional parameters may be passed in to be
191                        //              spliced into the NodeList
192                        // returns:
193                        //              dojo.NodeList
194                        return tnl(a.splice.apply(this, arguments));
195                },
196
197                indexOf: function(value, fromIndex){
198                        //      summary:
199                        //              see dojo.indexOf(). The primary difference is that the acted-on
200                        //              array is implicitly this NodeList
201                        // value: Object:
202                        //              The value to search for.
203                        // fromIndex: Integer?:
204                        //              The loction to start searching from. Optional. Defaults to 0.
205                        //      description:
206                        //              For more details on the behavior of indexOf, see:
207                        //                      <http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:indexOf>
208                        //      returns:
209                        //              Positive Integer or 0 for a match, -1 of not found.
210                        return d.indexOf(this, value, fromIndex); // Integer
211                },
212
213                lastIndexOf: function(value, fromIndex){
214                        // summary:
215                        //              see dojo.lastIndexOf(). The primary difference is that the
216                        //              acted-on array is implicitly this NodeList
217                        //      description:
218                        //              For more details on the behavior of lastIndexOf, see:
219                        //                      <http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:lastIndexOf>
220                        // value: Object:
221                        //              The value to search for.
222                        // fromIndex: Integer?:
223                        //              The loction to start searching from. Optional. Defaults to 0.
224                        // returns:
225                        //              Positive Integer or 0 for a match, -1 of not found.
226                        return d.lastIndexOf(this, value, fromIndex); // Integer
227                },
228
229                every: function(callback, thisObject){
230                        //      summary:
231                        //              see `dojo.every()` and:
232                        //                      <http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:every>
233                        //              Takes the same structure of arguments and returns as
234                        //              dojo.every() with the caveat that the passed array is
235                        //              implicitly this NodeList
236                        // callback: Function: the callback
237                        // thisObject: Object?: the context
238                        return d.every(this, callback, thisObject); // Boolean
239                },
240
241                some: function(callback, thisObject){
242                        //      summary:
243                        //              see dojo.some() and:
244                        //                      http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:some
245                        //              Takes the same structure of arguments and returns as
246                        //              dojo.some() with the caveat that the passed array is
247                        //              implicitly this NodeList
248                        // callback: Function: the callback
249                        // thisObject: Object?: the context
250                        return d.some(this, callback, thisObject); // Boolean
251                },
252                =====*/
253
254                concat: function(item){
255                        // summary:
256                        //              Returns a new NodeList comprised of items in this NodeList
257                        //              as well as items passed in as parameters
258                        // description:
259                        //              This method behaves exactly like the Array.concat method
260                        //              with the caveat that it returns a dojo.NodeList and not a
261                        //              raw Array. For more details, see:
262                        //                      <http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:concat>
263                        // item: Object...?
264                        //              Any number of optional parameters may be passed in to be
265                        //              spliced into the NodeList
266                        // returns:
267                        //              dojo.NodeList
268                       
269                        //return tnl(apc.apply(this, arguments));
270                        // the line above won't work for the native NodeList :-(
271                       
272                        // implementation notes:
273                        // 1) Native NodeList is not an array, and cannot be used directly
274                        // in concat() --- the latter doesn't recognize it as an array, and
275                        // does not inline it, but append as a single entity.
276                        // 2) On some browsers (e.g., Safari) the "constructor" property is
277                        // read-only and cannot be changed. So we have to test for both
278                        // native NodeList and dojo.NodeList in this property to recognize
279                        // the node list.
280                       
281                        var t = d.isArray(this) ? this : aps.call(this, 0),
282                                m = d.map(arguments, function(a){
283                                        return a && !d.isArray(a) &&
284                                                (a.constructor === NodeList || a.constructor == nl) ?
285                                                        aps.call(a, 0) : a;
286                                });
287                        return tnl(apc.apply(t, m));    // dojo.NodeList
288                },
289
290                map: function(/*Function*/ func, /*Function?*/ obj){
291                        //      summary:
292                        //              see dojo.map(). The primary difference is that the acted-on
293                        //              array is implicitly this NodeList and the return is a
294                        //              dojo.NodeList (a subclass of Array)
295                        ///return d.map(this, func, obj, d.NodeList); // dojo.NodeList
296                        return tnl(d.map(this, func, obj)); // dojo.NodeList
297                },
298
299                forEach: function(callback, thisObj){
300                        //      summary:
301                        //              see dojo.forEach(). The primary difference is that the acted-on
302                        //              array is implicitly this NodeList
303                        d.forEach(this, callback, thisObj);
304                        // non-standard return to allow easier chaining
305                        return this; // dojo.NodeList
306                },
307
308
309                /*=====
310                coords: function(){
311                        //      summary:
312                        //              Returns the box objects all elements in a node list as
313                        //              an Array (*not* a NodeList)
314                       
315                        return d.map(this, d.coords); // Array
316                },
317
318                attr: function(property, value){
319                        //      summary:
320                        //              gets or sets the DOM attribute for every element in the
321                        //              NodeList
322                        //      property: String
323                        //              the attribute to get/set
324                        //      value: String?
325                        //              optional. The value to set the property to
326                        //      returns:
327                        //              if no value is passed, the result is an array of attribute values
328                        //              If a value is passed, the return is this NodeList
329                        return; // dojo.NodeList
330                        return; // Array
331                },
332
333                style: function(property, value){
334                        //      summary:
335                        //              gets or sets the CSS property for every element in the NodeList
336                        //      property: String
337                        //              the CSS property to get/set, in JavaScript notation
338                        //              ("lineHieght" instead of "line-height")
339                        //      value: String?
340                        //              optional. The value to set the property to
341                        //      returns:
342                        //              if no value is passed, the result is an array of strings.
343                        //              If a value is passed, the return is this NodeList
344                        return; // dojo.NodeList
345                        return; // Array
346                },
347
348                addClass: function(className){
349                        //      summary:
350                        //              adds the specified class to every node in the list
351                        //      className: String
352                        //              the CSS class to add
353                        return; // dojo.NodeList
354                },
355
356                removeClass: function(className){
357                        //      summary:
358                        //              removes the specified class from every node in the list
359                        //      className: String
360                        //              the CSS class to add
361                        //      returns:
362                        //              dojo.NodeList, this list
363                        return; // dojo.NodeList
364                },
365
366                toggleClass: function(className, condition){
367                        //      summary:
368                        //              Adds a class to node if not present, or removes if present.
369                        //              Pass a boolean condition if you want to explicitly add or remove.
370                        //      condition: Boolean?
371                        //              If passed, true means to add the class, false means to remove.
372                        //      className: String
373                        //              the CSS class to add
374                        return; // dojo.NodeList
375                },
376
377                connect: function(methodName, objOrFunc, funcName){
378                        //      summary:
379                        //              attach event handlers to every item of the NodeList. Uses dojo.connect()
380                        //              so event properties are normalized
381                        //      methodName: String
382                        //              the name of the method to attach to. For DOM events, this should be
383                        //              the lower-case name of the event
384                        //      objOrFunc: Object|Function|String
385                        //              if 2 arguments are passed (methodName, objOrFunc), objOrFunc should
386                        //              reference a function or be the name of the function in the global
387                        //              namespace to attach. If 3 arguments are provided
388                        //              (methodName, objOrFunc, funcName), objOrFunc must be the scope to
389                        //              locate the bound function in
390                        //      funcName: String?
391                        //              optional. A string naming the function in objOrFunc to bind to the
392                        //              event. May also be a function reference.
393                        //      example:
394                        //              add an onclick handler to every button on the page
395                        //              |       dojo.query("div:nth-child(odd)").connect("onclick", function(e){
396                        //              |               console.log("clicked!");
397                        //              |       });
398                        // example:
399                        //              attach foo.bar() to every odd div's onmouseover
400                        //              |       dojo.query("div:nth-child(odd)").connect("onmouseover", foo, "bar");
401                },
402
403                empty: function(){
404                        //      summary:
405                        //              clears all content from each node in the list. Effectively
406                        //              equivalent to removing all child nodes from every item in
407                        //              the list.
408                        return this.forEach("item.innerHTML='';"); // dojo.NodeList
409                        // FIXME: should we be checking for and/or disposing of widgets below these nodes?
410                },
411                =====*/
412               
413                // useful html methods
414                coords: adaptAsMap(d.coords),
415
416                // FIXME: connectPublisher()? connectRunOnce()?
417
418                /*
419                destroy: function(){
420                        //      summary:
421                        //              destroys every item in  the list.
422                        this.forEach(d.destroy);
423                        // FIXME: should we be checking for and/or disposing of widgets below these nodes?
424                },
425                */
426
427                place: function(/*String||Node*/ queryOrNode, /*String*/ position){
428                        //      summary:
429                        //              places elements of this node list relative to the first element matched
430                        //              by queryOrNode. Returns the original NodeList. See: `dojo.place`
431                        //      queryOrNode:
432                        //              may be a string representing any valid CSS3 selector or a DOM node.
433                        //              In the selector case, only the first matching element will be used
434                        //              for relative positioning.
435                        //      position:
436                        //              can be one of:
437                        //              |       * "last" (default)
438                        //              |       * "first"
439                        //              |       * "before"
440                        //              |       * "after"
441                        //              |       * "only"
442                        //              |       * "replace"
443                        //              or an offset in the childNodes property
444                        var item = d.query(queryOrNode)[0];
445                        return this.forEach(function(node){ d.place(node, item, position); }); // dojo.NodeList
446                },
447
448                orphan: function(/*String?*/ simpleFilter){
449                        //      summary:
450                        //              removes elements in this list that match the simple
451                        //              filter from their parents and returns them as a new
452                        //              NodeList.
453                        //      simpleFilter:
454                        //              single-expression CSS rule. For example, ".thinger" or
455                        //              "#someId[attrName='value']" but not "div > span". In short,
456                        //              anything which does not invoke a descent to evaluate but
457                        //              can instead be used to test a single node is acceptable.
458                        //      returns:
459                        //              `dojo.NodeList` containing the orpahned elements
460                        return (simpleFilter ? d._filterQueryResult(this, simpleFilter) : this).forEach(orphan); // dojo.NodeList
461                },
462
463                adopt: function(/*String||Array||DomNode*/ queryOrListOrNode, /*String?*/ position){
464                        //      summary:
465                        //              places any/all elements in queryOrListOrNode at a
466                        //              position relative to the first element in this list.
467                        //              Returns a dojo.NodeList of the adopted elements.
468                        //      queryOrListOrNode:
469                        //              a DOM node or a query string or a query result.
470                        //              Represents the nodes to be adopted relative to the
471                        //              first element of this NodeList.
472                        //      position:
473                        //              can be one of:
474                        //              |       * "last" (default)
475                        //              |       * "first"
476                        //              |       * "before"
477                        //              |       * "after"
478                        //              |       * "only"
479                        //              |       * "replace"
480                        //              or an offset in the childNodes property
481                        return d.query(queryOrListOrNode).place(item[0], position);     // dojo.NodeList
482                },
483
484                // FIXME: do we need this?
485                query: function(/*String*/ queryStr){
486                        //      summary:
487                        //              Returns a new list whose memebers match the passed query,
488                        //              assuming elements of the current NodeList as the root for
489                        //              each search.
490                        //      example:
491                        //              assume a DOM created by this markup:
492                        //      |       <div id="foo">
493                        //      |               <p>
494                        //      |                       bacon is tasty, <span>dontcha think?</span>
495                        //      |               </p>
496                        //      |       </div>
497                        //      |       <div id="bar">
498                        //      |               <p>great commedians may not be funny <span>in person</span></p>
499                        //      |       </div>
500                        //              If we are presented with the following defintion for a NodeList:
501                        //      |       var l = new dojo.NodeList(dojo.byId("foo"), dojo.byId("bar"));
502                        //              it's possible to find all span elements under paragraphs
503                        //              contained by these elements with this sub-query:
504                        //      |       var spans = l.query("p span");
505
506                        // FIXME: probably slow
507                        if(!queryStr){ return this; }
508                        var ret = this.map(function(node){
509                                // FIXME: why would we ever get undefined here?
510                                return d.query(queryStr, node).filter(function(subNode){ return subNode !== undefined; });
511                        });
512                        return tnl(apc.apply([], ret)); // dojo.NodeList
513                },
514
515                filter: function(/*String|Function*/ simpleFilter){
516                        //      summary:
517                        //              "masks" the built-in javascript filter() method (supported
518                        //              in Dojo via `dojo.filter`) to support passing a simple
519                        //              string filter in addition to supporting filtering function
520                        //              objects.
521                        //      simpleFilter:
522                        //              If a string, a single-expression CSS rule. For example, ".thinger" or
523                        //              "#someId[attrName='value']" but not "div > span". In short,
524                        //              anything which does not invoke a descent to evaluate but
525                        //              can instead be used to test a single node is acceptable.
526                        //      example:
527                        //              "regular" JS filter syntax as exposed in dojo.filter:
528                        //              |       dojo.query("*").filter(function(item){
529                        //              |               // highlight every paragraph
530                        //              |               return (item.nodeName == "p");
531                        //              |       }).style("backgroundColor", "yellow");
532                        // example:
533                        //              the same filtering using a CSS selector
534                        //              |       dojo.query("*").filter("p").styles("backgroundColor", "yellow");
535
536                        var a = arguments, items = this, start = 0;
537                        if(d.isString(simpleFilter)){
538                                items = d._filterQueryResult(this, a[0]);
539                                if(a.length == 1){
540                                        // if we only got a string query, pass back the filtered results
541                                        return items; // dojo.NodeList
542                                }
543                                // if we got a callback, run it over the filtered items
544                                start = 1;
545                        }
546                        return tnl(d.filter(items, a[start], a[start + 1]));    // dojo.NodeList
547                },
548               
549                /*
550                // FIXME: should this be "copyTo" and include parenting info?
551                clone: function(){
552                        // summary:
553                        //              creates node clones of each element of this list
554                        //              and returns a new list containing the clones
555                },
556                */
557
558                addContent: function(/*String|DomNode*/ content, /*String||Integer?*/ position){
559                        //      summary:
560                        //              add a node or some HTML as a string to every item in the list.
561                        //              Returns the original list.
562                        //      description:
563                        //              a copy of the HTML content is added to each item in the
564                        //              list, with an optional position argument. If no position
565                        //              argument is provided, the content is appended to the end of
566                        //              each item.
567                        //      content:
568                        //              DOM node or HTML in string format to add at position to
569                        //              every item
570                        //      position:
571                        //              can be one of:
572                        //                      * "last"||"end" (default)
573                        //                      * "first||"start"
574                        //                      * "before"
575                        //                      * "after"
576                        //              or an offset in the childNodes property
577                        //      example:
578                        //              appends content to the end if the position is ommitted
579                        //      |       dojo.query("h3 > p").addContent("hey there!");
580                        //      example:
581                        //              add something to the front of each element that has a "thinger" property:
582                        //      |       dojo.query("[thinger]").addContent("...", "first");
583                        //      example:
584                        //              adds a header before each element of the list
585                        //      |       dojo.query(".note").addContent("<h4>NOTE:</h4>", "before");
586                        //      example:
587                        //              add a clone of a DOM node to the end of every element in
588                        //              the list, removing it from its existing parent.
589                        //      |       dojo.query(".note").addContent(dojo.byId("foo"));
590                        var c = d.isString(content) ? d._toDom(content, this[0] && this[0].ownerDocument) : content, i, l = this.length - 1;
591                        for(i = 0; i < l; ++i){
592                                d.place(c.cloneNode(true), this[i], position);
593                        }
594                        if(l >= 0){
595                                d.place(c, this[l], position);
596                        }
597                        return this;    // dojo.NodeList
598                },
599
600                instantiate: function(/*String|Object*/ declaredClass, /*Object?*/ properties){
601                        //      summary:
602                        //              Create a new instance of a specified class, using the
603                        //              specified properties and each node in the nodeList as a
604                        //              srcNodeRef
605                        //
606                        var c = d.isFunction(declaredClass) ? declaredClass : d.getObject(declaredClass);
607                        properties = properties || {};
608                        return this.forEach(function(node){ new c(properties, node); });        // dojo.NodeList
609                },
610
611                at: function(/*===== index =====*/){
612                        //      summary:
613                        //              Returns a new NodeList comprised of items in this NodeList
614                        //              at the given index or indices.
615                        //      index: Integer...
616                        //              One or more 0-based indices of items in the current NodeList.
617                        //      returns:
618                        //              dojo.NodeList
619                        var t = new dojo.NodeList();
620                        d.forEach(arguments, function(i){ if(this[i]){ t.push(this[i]); }}, this);
621                        return t; // dojo.NodeList
622                }
623
624        });
625
626        // syntactic sugar for DOM events
627        d.forEach([
628                "blur", "focus", "change", "click", "error", "keydown", "keypress", "keyup", "load", "mousedown",
629                "mouseenter", "mouseleave", "mousemove", "mouseout", "mouseover", "mouseup", "submit" 
630                ], function(evt){
631                        var _oe = "on"+evt;
632                        nlp[_oe] = function(a, b){
633                                return this.connect(_oe, a, b);
634                        }
635                                // FIXME: should these events trigger publishes?
636                                /*
637                                return (a ? this.connect(_oe, a, b) :
638                                                        this.forEach(function(n){ 
639                                                                // FIXME:
640                                                                //              listeners get buried by
641                                                                //              addEventListener and can't be dug back
642                                                                //              out to be triggered externally.
643                                                                // see:
644                                                                //              http://developer.mozilla.org/en/docs/DOM:element
645
646                                                                console.log(n, evt, _oe);
647
648                                                                // FIXME: need synthetic event support!
649                                                                var _e = { target: n, faux: true, type: evt };
650                                                                // dojo._event_listener._synthesizeEvent({}, { target: n, faux: true, type: evt });
651                                                                try{ n[evt](_e); }catch(e){ console.log(e); }
652                                                                try{ n[_oe](_e); }catch(e){ console.log(e); }
653                                                        })
654                                );
655                        }
656                        */
657                }
658        );
659
660//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
661})();
662//>>excludeEnd("webkitMobile");
Note: See TracBrowser for help on using the browser.