diff options
Diffstat (limited to 'js/dojo/dojox/jq.js')
| -rw-r--r-- | js/dojo/dojox/jq.js | 1930 |
1 files changed, 1930 insertions, 0 deletions
diff --git a/js/dojo/dojox/jq.js b/js/dojo/dojox/jq.js new file mode 100644 index 0000000..c550b65 --- /dev/null +++ b/js/dojo/dojox/jq.js @@ -0,0 +1,1930 @@ +//>>built +// wrapped by build app +define("dojox/jq", ["dijit","dojo","dojox","dojo/require!dojo/NodeList-traverse,dojo/NodeList-manipulate,dojo/io/script"], function(dijit,dojo,dojox){ +//For jQuery 1.3.2 + +dojo.provide("dojox.jq"); +dojo.require("dojo.NodeList-traverse"); +dojo.require("dojo.NodeList-manipulate"); +dojo.require("dojo.io.script"); + +/* +To get jquery tests to pass: +- add spaces between span>form selectors, other ones like one,two +- .last() instead of :last +- $("<div>").find("#foo") does not work unless the div is attached to the body. + +- trigger .test not work +- No jquery.Event thing. + +- jQuery.ajax() modifies incoming arguments? +- test framework not good for our io methods, async, poll. +- Dojo ajax is async: we fire ajaxStop more than jquery. + +- jquery makes assumptions of a value to set for an element +by inserting an element and checking display. Does not seem to +account for nested styles, only captures generic tag name style off +of body. Why can't we just set display to empty? + + + + + +OK for failures: +- test("jQuery.ajax - beforeSend, cancel request (#2688)" + We cancel the deferred which triggers error and complete callbacks. + + +Looked at jquery code for: +- how it handled text(): did not use textContent/innerText, but use recursive look over childNodes and nodeValue, +so it may have impact on how <br> is serialized, but it has uniform behavior across browsers. +- Looked at trigger: how it triggered actions on dom nodes. This seemed unsafe. +*/ + +/* +dojo.query differences that cause some tests to fail: +- does not support XML queries +- $("#sap>form") does not find a match but $("#sap > form") does. Similar issue with comma instead of > (see is() tests) +- "$("form:last") should return the last form object, not if that particular form is that last related + to its siblings? Same issue with :first? +- $("p").filter("#ap, #sndp"): filter does not work. +- dojo.NodeList uses d.NodeList a few places in the code. Would be nice to use a ctor that can be configured. + That would make the filter function operate better. +- filterQueryResult, cannot handle queries like "p, div"? See andSelf test with parents(). +- adjacent "p + p" not supported? += a:only-child not supported? +- nth(1) +- even/odd +- eq/gt/lt +- #form :radio:checked does not run the first :radio psuedo selector? Seems to be a general issue where only the last pseud + is run. For example, "#form :checked:radio" does only the radio pseudo. +*/ + +(function(){ + //Enable io topic publishing + dojo.config.ioPublish = true; + + //Support stuff for toDom + var selfClosedTags = "|img|meta|hr|br|input|"; + + function toDom(/*String*/html, /*Document?*/doc){ + //summary converts HTML string into DOM nodes. + //Make sure html is a string. + html += ""; + + //Convert <tag/> into <tag></tag> + html = html.replace(/<\s*(\w+)([^\/\>]*)\/\s*>/g, function(tag, name, contents){ + if(selfClosedTags.indexOf("|" + name + "|") == -1){ + return "<" + name + contents + "></" + name + ">"; + }else{ + return tag; + } + }); + + return dojo._toDom(html, doc); + } + + function cssNameToJs(name){ + var index = name.indexOf("-"); + if(index != -1){ + //Strip off beginning dash + if(index == 0){ + name = name.substring(1); + } + name = name.replace(/-(\w)/g, function(match, match1){ + return match1.toUpperCase(); + }); + } + return name; + } + + var _old$ = dojo.global.$; + var _oldJQuery = dojo.global.jQuery; + + var $ = dojo.global.$ = dojo.global.jQuery = function(){ + var arg = arguments[0]; + if(!arg){ + return $._wrap([], null, $); + }else if(dojo.isString(arg)){ + if(arg.charAt(0) == "<"){ + //String of html that needs nodes created. + arg = toDom(arg); + //If a DocumentFragment, convert to use its children + //since we want to treat all top level nodes as elements + //in the NodeList array. + if(arg.nodeType == 11){ + arg = arg.childNodes; + }else{ + return $._wrap([arg], null, $); + } + //Use end case of nodelist to finish work. + }else{ + //Normal dojo.query selector. + //Switch out query's NodeList constructor to be our specialized + //NodeList constructor. + var listCtor = dojo._NodeListCtor; + dojo._NodeListCtor = $; + + //If the second arg is one of our fake NodeLists then + //use the first parent for the call. + var arg2 = arguments[1]; + if(arg2 && arg2._is$){ + arg2 = arg2[0]; + }else if(dojo.isString(arg2)){ + arg2 = dojo.query(arg2)[0]; + } + + var nl = dojo.query.call(this, arg, arg2); + dojo._NodeListCtor = listCtor; + return nl; + } + }else if(dojo.isFunction(arg)){ + //The addOnLoad case + $.ready(arg); + return $; + }else if(arg == document || arg == window){ + //If the arg is the document or window, + //then just use it directly. + return $._wrap([arg], null, $); + }else if(dojo.isArray(arg)){ + //Input is a plain array. + //Filter out duplicates. + var ary = []; + for(var i = 0; i < arg.length; i++){ + if(dojo.indexOf(ary, arg[i]) == -1){ + ary.push(arg[i]); + } + } + return $._wrap(arg, null, $); + }else if("nodeType" in arg){ + //A DOM Node + return $._wrap([arg], null, $); + } + + //A native NodeList that does not conform to dojo.isArray(). + //Convert it to a workable array and create new NodeList. + return $._wrap(dojo._toArray(arg), null, $); + + }; + + //Set up plugin extension point. + var nlProto = dojo.NodeList.prototype; + + //Need a delegate, because at least one method conflicts with jquery + //API: attr(name) in jQuery only returns a single, first value, where + //dojo.attr will return an array. + var f = $.fn = $.prototype = dojo.delegate(nlProto); + + //_wrap is required for proper use in dojo.query, but the _adaptAs* methods + //do not have to placed on $ -- they can be used directly off dojo.NodeList. + $._wrap = dojo.NodeList._wrap; + + //Add in some pseudos selectors + var headerRegExp = /^H\d/i; + var pseudos = dojo.query.pseudos; + dojo.mixin(pseudos, { + has: function(name, condition){ + return function(elem){ + return $(condition, elem).length; + } + }, + visible: function(name, condition){ + return function(elem){ + return dojo.style(elem, "visible") != "hidden" && dojo.style(elem, "display") != "none"; + } + }, + hidden: function(name, condition){ + return function(elem){ + return elem.type == "hidden" || dojo.style(elem, "visible") == "hidden" || dojo.style(elem, "display") == "none"; + } + }, + selected: function(name, condition){ + return function(elem){ + return elem.selected; + } + }, + checked: function(name, condition){ + return function(elem){ + return elem.nodeName.toUpperCase() == "INPUT" && elem.checked; + } + }, + disabled: function(name, condition){ + return function(elem){ + return elem.getAttribute("disabled"); + } + }, + enabled: function(name, condition){ + return function(elem){ + return !elem.getAttribute("disabled"); + } + }, + input: function(name, condition){ + return function(elem){ + var n = elem.nodeName.toUpperCase(); + return n == "INPUT" || n == "SELECT" || n == "TEXTAREA" || n == "BUTTON"; + } + }, + button: function(name, condition){ + return function(elem){ + return (elem.nodeName.toUpperCase() == "INPUT" && elem.type == "button") || elem.nodeName.toUpperCase() == "BUTTON"; + } + }, + header: function(name, condition){ + return function(elem){ + return elem.nodeName.match(headerRegExp); + } + } + //TODO: implement :animated + }); + + + //Add the input type selectors to pseudos + var inputPseudos = {}; + dojo.forEach([ + "text", "password", "radio", "checkbox", "submit", "image", "reset", "file" + ], function(type) { + inputPseudos[type] = function(name, condition){ + return function(elem){ + return elem.nodeName.toUpperCase() == "INPUT" && elem.type == type; + } + }; + }); + dojo.mixin(pseudos, inputPseudos); + + //Set up browser sniff. + $.browser = { + mozilla: dojo.isMoz, + msie: dojo.isIE, + opera: dojo.isOpera, + safari: dojo.isSafari + }; + $.browser.version = dojo.isIE || dojo.isMoz || dojo.isOpera || dojo.isSafari || dojo.isWebKit; + + //Map back into dojo + //Hmm maybe this is not so good. Dojo + //modules may still be holding on to old + //dojo (example: the d._NodeListCtor in query.js) + //dojo = dojo.mixin($, dojo); + + // Add $.ready + $.ready = $.fn.ready = function(callback){ + dojo.addOnLoad(dojo.hitch(null, callback, $)); + return this; + } + + //START jquery Core API methods + //http://docs.jquery.com/Core + f._is$ = true; + f.size = function(){return this.length; }; + + $.prop = function(node, propCheck){ + //TODO: not sure about this one, could not find the docs? + if(dojo.isFunction(propCheck)){ + return propCheck.call(node); + }else{ + return propCheck; + } + } + + $.className = { + add: dojo.addClass, + remove: dojo.removeClass, + has: dojo.hasClass + }; + + $.makeArray = function(thing){ + if(typeof thing == "undefined"){ + return []; + }else if(thing.length && !dojo.isString(thing) && !("location" in thing)){ + //Location check was for excluding window objects that have a length. + return dojo._toArray(thing); + }else{ + return [thing]; + } + } + + $.merge = function(ary1, ary2){ + //Alters first array by adding in the element. + var args = [ary1.length, 0]; + args = args.concat(ary2); + ary1.splice.apply(ary1, args); + return ary1; + } + + $.each = function(/*Array||ArrayLike*/list, /*Function*/cb){ + //each differs from dojo.NodeList.forEach in that + //"this" is the current cycled node. Breaking + //the loop is also possible. Also, index is first arg + //to the callback. + if(dojo.isArrayLike(list)){ + for(var i = 0; i < list.length; i++){ + if(cb.call(list[i], i, list[i]) === false){ + break; + } + } + }else if(dojo.isObject(list)){ + for(var param in list){ + if(cb.call(list[param], param, list[param]) === false){ + break; + } + } + } + return this; + }; + f.each = function(/*Function*/cb){ + return $.each.call(this, this, cb); + }; + //f.length already implemented by NodeList + f.eq = function(){ + //Direct copy of dojo.NodeList.at, but want + //to use our NodeList class. + var nl = $(); + dojo.forEach(arguments, function(i) { if(this[i]) { nl.push(this[i]); } }, this); + return nl; // dojo.NodeList + }; + f.get = function(/*Number*/index){ + if(index || index == 0){ + return this[index]; + } + return this; + }; + f.index = function(arg){ + //Hmm, allows passing in a $ nodelist. Apparently in that + //case take the first item in that array and match + if(arg._is$){ + arg = arg[0]; + } + return this.indexOf(arg); + } + + //.data implementation + var dataStore = []; + var dataId = 0; + var dataAttr = dojo._scopeName + "DataId"; + + var getDataId = function(node){ + var id = node.getAttribute(dataAttr); + if(!id){ + id = dataId++; + node.setAttribute(dataAttr, id); + } + } + + var getData = function(node){ + var data = {}; + if(node.nodeType == 1){ + var id = getDataId(node); + data = dataStore[id]; + if(!data){ + data = dataStore[id] = {}; + } + } + return data; + } + + $.data = function(/*DOMNode*/node, /*String*/name, /*String*/value){ + var result = null; + if(name == "events"){ + //Special case "events", since jquery tests seem to use it to + //get the event handler storage for jquery. So for jquery apps + //"events" is probably a reserved word anyway. + result = listeners[node.getAttribute(eventAttr)]; + var isEmpty = true; + if(result){ + for(var param in result){ + isEmpty = false; + break; + } + } + return isEmpty ? null : result; + } + + var data = getData(node); + if(typeof value != "undefined"){ + data[name] = value; + }else{ + result = data[name]; + } + return value ? this : result; + } + + $.removeData = function(/*DOMNode*/node, /*String*/name){ + var data = getData(node); + delete data[name]; + if(node.nodeType == 1){ + var isEmpty = true; + for(var param in data){ + isEmpty = false; + break; + } + if(isEmpty){ + node.removeAttribute(dataAttr); + } + } + return this; + } + + f.data = function(/*String*/name, /*String*/value){ + var result = null; + this.forEach(function(node){ + result = $.data(node, name, value); + }); + + return value ? this : result; + } + + f.removeData = function(/*String*/name){ + this.forEach(function(node){ + $.removeData(node, name); + }); + return this; + } + + function jqMix(obj, props){ + //summary: an attempt at a mixin that follows + //jquery's .extend rules. Seems odd. Not sure how + //to resolve this with dojo.mixin and what the use + //cases are for the jquery version. + //Copying some code from dojo._mixin. + if(obj == props){ + return obj; + } + var tobj = {}; + for(var x in props){ + // the "tobj" condition avoid copying properties in "props" + // inherited from Object.prototype. For example, if obj has a custom + // toString() method, don't overwrite it with the toString() method + // that props inherited from Object.prototype + if((tobj[x] === undefined || tobj[x] != props[x]) && props[x] !== undefined && obj != props[x]){ + if(dojo.isObject(obj[x]) && dojo.isObject(props[x])){ + if(dojo.isArray(props[x])){ + obj[x] = props[x]; + }else{ + obj[x] = jqMix(obj[x], props[x]); + } + }else{ + obj[x] = props[x]; + } + } + } + // IE doesn't recognize custom toStrings in for..in + if(dojo.isIE && props){ + var p = props.toString; + if(typeof p == "function" && p != obj.toString && p != tobj.toString && + p != "\nfunction toString() {\n [native code]\n}\n"){ + obj.toString = props.toString; + } + } + return obj; // Object + } + + f.extend = function(){ + var args = [this]; + args = args.concat(arguments); + return $.extend.apply($, args); + } + + $.extend = function(){ + //Could have multiple args to mix in. Similar to dojo.mixin, + //but has some different rules, and the mixins all get applied + //to the first arg. + var args = arguments, finalObj; + for(var i = 0; i < args.length; i++){ + var obj = args[i]; + if(obj && dojo.isObject(obj)){ + if(!finalObj){ + finalObj = obj; + }else{ + jqMix(finalObj, obj); + } + } + } + return finalObj; + } + + $.noConflict = function(/*Boolean*/extreme){ + var me = $; + dojo.global.$ = _old$; + if(extreme){ + dojo.global.jQuery = _oldJQuery; + } + return me; + } + //END jquery Core API methods + + //START jquery Attribute API methods + //http://docs.jquery.com/Attributes + f.attr = function(name, value){ + //The isObject tests below are to weed out where something + //like a form node has an input called "action" but we really + //want to get the attribute "action". But in general, favor + //a property value over a DOM attribute value. + if(arguments.length == 1 && dojo.isString(arguments[0])){ + //The get case, return first match. + var first = this[0]; + + //Weed out empty nodes + if(!first){ + return null; + } + + var arg = arguments[0]; + //favor properties over attributes. + var attr = dojo.attr(first, arg); + var prop = first[arg]; + if((arg in first) && !dojo.isObject(prop) && name != "href"){ + return prop; + }else{ + return attr || prop; + } + }else if(dojo.isObject(name)){ + //A setter, using an object. + for(var param in name){ + this.attr(param, name[param]); + } + return this; + }else{ + //The setter case. Figure out if value is a function. + var isFunc = dojo.isFunction(value); + this.forEach(function(node, index){ + var prop = node[name]; + if((name in node) && !dojo.isObject(prop) && name != "href"){ + node[name] = (isFunc ? value.call(node, index) : value); + }else if(node.nodeType == 1){ + dojo.attr(node, name, (isFunc ? value.call(node, index) : value)); + } + }); + return this; + } + } + + f.removeAttr = function(name){ + this.forEach(function(node, index){ + var prop = node[name]; + if((name in node) && !dojo.isObject(prop) && name != "href"){ + delete node[name]; + }else if(node.nodeType == 1){ + if(name == "class"){ + //TODO: push this fix into dojo.removeAttr + node.removeAttribute(name); + }else{ + dojo.removeAttr(node, name); + } + } + }); + return this; + } + + //addClass, removeClass exist in dojo.NodeList. toggleClass in jQuery case + //just means add/remove the classname if it missing/exists. So need custom override. + f.toggleClass = function(/*String*/name, /*Expression?*/condition){ + var hasCondition = arguments.length > 1; + this.forEach(function(node){ + dojo.toggleClass(node, name, hasCondition ? condition : !dojo.hasClass(node, name)); + }); + return this; + } + + //Action depends on arguments: if an array of functions do one thing, + //If no args, do a display toggle, + //If an expression, something that evaluates to true or false, + //then toggle display accordingly. + //If first arg is a String/Number, then do animation. Second arg + //is an optional callback. + f.toggle = function(){ + //If more than two args and we have a function as first arg, then + //probably the onclick toggle variant: takes variable args that are + //functions and cycles through them on click actions. + var args = arguments; + if(arguments.length > 1 && dojo.isFunction(arguments[0])){ + var index = 0; + var func = function(){ + var result = args[index].apply(this, arguments); + index += 1; + if(index > args.length - 1){ + index = 0; + } + }; + return this.bind("click", func); + }else{ + //The display/hide/show case. + var condition = arguments.length == 1 ? arguments[0] : undefined; + this.forEach(function(node){ + var result = typeof condition == "undefined" ? dojo.style(node, "display") == "none" : condition; + var action = (result ? "show" : "hide"); + var nl = $(node); + nl[action].apply(nl, args); + }); + return this; + } + } + + //hasClass just returns true if any of the nodes has the class. + f.hasClass = function(/*String*/name){ + return this.some(function(node){ + return dojo.hasClass(node, name); + }); + } + + //use the html method from dojo.NodeList-manipulate. + f.html = f.innerHTML; + + //END jquery Attribute API methods + + + //START jquery Traversing API methods + //http://docs.jquery.com/Traversing + dojo.forEach(["filter", "slice"], function(item){ + f[item] = function(){ + //Convert the "this" value for functions passed in: + var nl; + if(dojo.isFunction(arguments[0])){ + var origFunc = arguments[0]; + arguments[0] = function(item, index){ + return origFunc.call(item, item, index); + } + } + + if(item == "filter" && dojo.isString(arguments[0])){ + var nl = this._filterQueryResult(this, arguments[0]); + }else{ + var oldCtor = dojo._NodeListCtor; + dojo._NodeListCtor = f; + //Need to wrap in a $() call since internally some + //dojo.NodeList functions reference dojo.NodeList directly. + //Need to get a configurable constructor for dojo.NodeList. + nl = $(nlProto[item].apply(this, arguments)); + dojo._NodeListCtor = oldCtor; + } + + return nl._stash(this); + } + }); + + f.map = function(/*Function*/callback){ + //Hmm, this is not like array map/dojo.map where you get one item back for + //each input. + return this._buildArrayFromCallback(callback); + } + $.map = function(/*Array*/ary, /*Function*/callback){ + //Hmm, this is not like array map/dojo.map where you get one item back for + //each input. + return f._buildArrayFromCallback.call(ary, callback); + } + + $.inArray = function(value, /*Array*/ary){ + return dojo.indexOf(ary, value); + } + + f.is = function(query){ + return (query ? !!this.filter(query).length : false); + } + + //TODO: probably a better way to do this. + f.not = function(){ + var notList = $.apply($, arguments); + //TODO: another place where if dojo.NodeList can configure a constructor, + //then we could avoid the $() wrapper below. + var nl = $(nlProto.filter.call(this, function(node){ + return notList.indexOf(node) == -1; + })); + return nl._stash(this); + } + + f.add = function(){ + return this.concat.apply(this, arguments); + } + + function iframeDoc(/*DOMNode*/iframeNode){ + //summary: Returns the document object associated with the iframe DOM Node argument. + //Taken from dojo.io.iframe.doc(). Needed for contents() function below. + var doc = iframeNode.contentDocument || // W3 + ( + ( + (iframeNode.name) && (iframeNode.document) && + (document.getElementsByTagName("iframe")[iframeNode.name].contentWindow) && + (document.getElementsByTagName("iframe")[iframeNode.name].contentWindow.document) + ) + ) || // IE + ( + (iframeNode.name)&&(document.frames[iframeNode.name])&& + (document.frames[iframeNode.name].document) + ) || null; + return doc; + } + + f.contents = function(){ + var ary = []; + this.forEach(function(node){ + if(node.nodeName.toUpperCase() == "IFRAME"){ + var doc = iframeDoc(node); + if(doc){ + ary.push(doc); + } + }else{ + //TODO: code similar to children() function. Refactor? + var children = node.childNodes; + //Using for loop for better speed. + for(var i = 0; i < children.length; i++){ + ary.push(children[i]); + } + } + }); + return this._wrap(ary)._stash(this); + } + + f.find = function(/*String*/query){ + var ary = []; + this.forEach(function(node){ + if(node.nodeType == 1){ + ary = ary.concat(dojo._toArray($(query, node))); + } + }); + return this._getUniqueAsNodeList(ary)._stash(this); + } + + f.andSelf = function(){ + return this.add(this._parent); + } + + //END jquery Traversing API methods + + //START jquery Manipulation API methods + //http://docs.jquery.com/Manipulation + + f.remove = function(/*String?*/query){ + //Override NodeList-manipulate's remove so we can remove data. + var nl = (query ? this._filterQueryResult(this, query) : this); + + //Remove data + nl.removeData(); + + //Remove event listeners. + //TODO! do this, once event stuff is built out. + + //Remove the items from the DOM, but keep them in this + //node list. + nl.forEach(function(node){ + node.parentNode.removeChild(node); + }); + + return this; + } + + //START jquery CSS API methods + //http://docs.jquery.com/CSS + $.css = function(/*DOMNode*/node, /*String|Object*/name, /*String|Number?*/value){ + name = cssNameToJs(name); + + //Hmm, dojo.style does an arguments. length check. + var result = (value ? dojo.style(node, name, value) : dojo.style(node, name)); + return result; + } + + f.css = function(/*String|Object*/name, /*String|Number?*/value){ + if(dojo.isString(name)){ + //Convert name to JS name if needed. + name = cssNameToJs(name); + if(arguments.length == 2){ + //set the value. Cannot directly delegate to + //this.style, since non-element nodes may be in the mix? + //this.contents() in particular will return some funky stuff. + + //Need to be sure to add "px" if appropriate. + if(!dojo.isString(value) && name != "zIndex"){ + value = value + "px"; + } + + this.forEach(function(node){ + if(node.nodeType == 1){ + dojo.style(node, name, value); + } + }); + return this; + }else{ + //return the value + value = dojo.style(this[0], name); + //Need to be sure to add "px" if appropriate. + if(!dojo.isString(value) && name != "zIndex"){ + value = value + "px"; + } + return value; + } + }else{ + for(var param in name){ + this.css(param, name[param]); + } + return this; + } + } + + function doBox(/*NodeList*/nl, /*String*/boxType, /*String*/prop, /*String||Number*/value){; + if(value){ + //Set height for all elements. + var mod = {}; + mod[prop] = value; + nl.forEach(function(node){ + dojo[boxType](node, mod); + }); + return nl; + }else{ + //Just get first node's height. + //Hmm. width is negative when element is display none in FF3? + return Math.abs(Math.round(dojo[boxType](nl[0])[prop])); + } + } + + f.height = function(value){ + return doBox(this, "contentBox", "h", value); + } + + f.width = function(value){ + return doBox(this, "contentBox", "w", value); + } + + function getDimensions(/*DOMNode*/node, /*String*/type, /*Boolean*/usePadding, /*Boolean*/useBorder, /*Boolean*/useMargin){ + //summary: sums up the different parts of the width/height based on arguments. + //If hidden, temporarily show it, do measurements then close. + var rehide = false; + if((rehide = node.style.display == "none")){ + node.style.display = "block"; + } + + var cs = dojo.getComputedStyle(node); + var content = Math.abs(Math.round(dojo._getContentBox(node, cs)[type])); + var pad = usePadding ? Math.abs(Math.round(dojo._getPadExtents(node, cs)[type])) : 0; + var border = useBorder ? Math.abs(Math.round(dojo._getBorderExtents(node, cs)[type])) : 0; + var margin = useMargin ? Math.abs(Math.round(dojo._getMarginExtents(node, cs)[type])) : 0; + + if(rehide){ + node.style.display = "none"; + } + + return pad + content + border + margin; + } + + f.innerHeight = function(){ + return getDimensions(this[0], "h", true); + } + + f.innerWidth = function(){ + return getDimensions(this[0], "w", true); + } + + f.outerHeight = function(useMargin){ + return getDimensions(this[0], "h", true, true, useMargin); + } + + f.outerWidth = function(useMargin){ + return getDimensions(this[0], "w", true, true, useMargin); + } + + //END jquery CSS API methods + + + //START jquery Events API methods + //http://docs.jquery.com/Events + + //ready() already defined above. + + //Event plumbing. + var listeners = []; + var listenId = 1; + var eventAttr = dojo._scopeName + "eventid"; + var currentEvtData; + + function getNonNamespacedName(/*String*/evtName){ + //summary: gets name of the event before the first ".". + //The $$ stuff is special ids used to create unique names + //for bound functions that did not have a unique namespace name. + evtName = evtName.split("$$")[0]; + var dotIndex = evtName.indexOf("."); + if(dotIndex != -1){ + evtName = evtName.substring(0, dotIndex); + } + return evtName; + } + + function domConnect(/*DOMNode*/node, /*String*/evtName){ + //summary: handles creating the connection with a real DOM event. + //This work should only be done one time per evName type. + //If the event if an ajax event, use dojo.subscribe instead. + if(evtName.indexOf("ajax") == 0){ + return dojo.subscribe(topics[evtName], function(dfd, res){ + var fakeEvt = new $.Event(evtName); + if("ajaxComplete|ajaxSend|ajaxSuccess".indexOf(evtName) != -1){ + triggerHandlers(node, [fakeEvt, dfd.ioArgs.xhr, dfd.ioArgs.args]); + }else if(evtName == "ajaxError"){ + triggerHandlers(node, [fakeEvt, dfd.ioArgs.xhr, dfd.ioArgs.args, res]); + }else{ + //ajaxStart|ajaxStop + triggerHandlers(node, [fakeEvt]); + } + }); + }else{ + return dojo.connect(node, "on" + evtName, function(e){ + triggerHandlers(node, arguments); + }); //Object + } + } + + //Event object for compatibility for some tests. + $.Event = function(/*String*/type){ + //Allow for calling function without "new" + if(this == $){ + return new $.Event(type); + } + if(typeof type == "string"){ + this.type = type.replace(/!/, ""); + }else{ + dojo.mixin(this, type); + } + this.timeStamp = (new Date()).getTime(); + this._isFake = true; + this._isStrict = (this.type.indexOf("!") != -1); + + } + + var ep = $.Event.prototype = { + preventDefault: function(){ + this.isDefaultPrevented = this._true; + }, + stopPropagation: function(){ + this.isPropagationStopped = this._true; + }, + stopImmediatePropagation: function(){ + this.isPropagationStopped = this._true; + this.isImmediatePropagationStopped = this._true; + }, + _true: function(){ return true; }, + _false: function(){ return false; } + } + dojo.mixin(ep, { + isPropagationStopped: ep._false, + isImmediatePropagationStopped: ep._false, + isDefaultPrevented: ep._false + }); + + function makeTriggerData(data, type){ + //summary: makes sure that the data array is copied + //and has an event as the first arg. If this function generates + //a fake event (known by the data[0]._isFake property being true) + //then the data[0].target needs to be set by the consumer of this function. + + data = data || []; + data = [].concat(data); + + //If first data item is not an event, make one up. + //Need to set up target: prop in the consumers of this + //function. + var evt = data[0]; + if(!evt || !evt.preventDefault){ + evt = type && type.preventDefault ? type : new $.Event(type); + data.unshift(evt); + } + return data; + } + + var triggerHandlersCalled = false; + + function triggerHandlers(/*DOMNode*/node, /*Array*/data, /*Function?*/extraFunc){ + //summary: handles the actual callbacks to the handlers. + + //Indicate triggerHandlers was called. + triggerHandlersCalled = true; + + //Uses currentEvtData if this is a simulated event. + data = data || currentEvtData; + extraFunc = extraFunc; + + //Normalize on a real element if dealing with a document. + if(node.nodeType == 9){ + node = node.documentElement; + } + + var nodeId = node.getAttribute(eventAttr); + if(!nodeId){ + return; + } + + var evt = data[0]; + var evtFullName = evt.type; + var evtName = getNonNamespacedName(evtFullName); + + var cbs = listeners[nodeId][evtName]; + + var result; + //Apply the extra function. What is that about? Not mentioned in the + //public APIs? + if(extraFunc){ + result = extraFunc.apply(node, data); + } + + if (result !== false){ + for(var param in cbs){ + if(param != "_connectId" && (!evt._isStrict && (param.indexOf(evtFullName) == 0) || (evt._isStrict && param == evtFullName))){ + //Store the callback ID in case unbind is called with this event + //so we can only unbind that one callback. + evt[dojo._scopeName + "callbackId"] = param; + + var cb = cbs[param]; + if(typeof cb.data != "undefined"){ + evt.data = cb.data; + }else{ + evt.data = null; + } + + //Do the actual callback. + if ((result = cb.fn.apply(evt.target, data)) === false && !evt._isFake){ + dojo.stopEvent(evt); + } + evt.result = result; + } + } + } + + return result; + } + + f.triggerHandler = function(/*String*/type, /*Array?*/data, /*Function?*/extraFunc){ + //Only triggers handlers on the first node. Huh. + var node = this[0]; + if(node && node.nodeType != 3 && node.nodeType != 8){ + data = makeTriggerData(data, type); + return triggerHandlers(node, data, extraFunc); + }else{ + return undefined; + } + } + + f.trigger = function(/*String*/type, /*Array?*/data, /*Function?*/extraFunc){ + //Copy data since we may need to modify by adding a + data = makeTriggerData(data, type); + var evt = data[0]; + var type = getNonNamespacedName(evt.type); + + //Store the current event data in case handlers need + //to reference it because of a simulated event. + currentEvtData = data; + currentExtraFunc = extraFunc; + + var result = null; + var needTarget = !evt.target; + this.forEach(function(node){ + //Only handle non text/comment nodes. + if(node.nodeType != 3 && node.nodeType != 8){ + + //Normalize on a real element if dealing with a document. + if(node.nodeType == 9){ + node = node.documentElement; + } + + //Set the node target appropriately for fake events. + if(evt._isFake){ + evt.currentTarget = node; + if(needTarget){ + evt.target = node; + } + } + + //Bizarre extra function thing. Not really demonstrated in public + //API docs. + if(extraFunc){ + var funcData = data.slice(1); + result = extraFunc.apply(node, (result = null ? funcData : funcData.concat(result))); + } + + if(result !== false){ + //Trigger DOM event. onclick is handled differently than + //others. + /* + if(type == 'click' && node.onclick && node.nodeName.toUpperCase() == "A"){ + result = node.onclick.apply(node, data); + } + */ + + //Set the "global" flag that indicates if triggerHandlers was called. + //If the direct node.event/onevent does not trigger the handlers, do so + //manually at the end. + triggerHandlersCalled = false; + + //Trigger functions registered directly on the DOM node. + if(node[type]){ + try{ + result = node[type](); + }catch(e){ + //Apparently IE throws on some hidden elements. Just eat it. + } + }else if(node["on" + type]){ + try{ + result = node["on" + type](); + }catch(e){ + //Apparently IE throws on some hidden elements. Just eat it. + } + } + + if(!triggerHandlersCalled){ + //Finally triggerHandlers directly if the above code did not trigger it yet. + result = triggerHandlers(node, data); + } + + //Bubble the event up. + //TODO: optimize this path so we don't have to do forEach and NodeList work. + var parentNode = node.parentNode; + if(result !== false && !evt.isImmediatePropagationStopped() && !evt.isPropagationStopped() && parentNode && parentNode.nodeType == 1){ + $(parentNode).trigger(type, data, extraFunc); + } + } + } + }); + + //Clear current event data. + currentEvtData = null; + currentExtraFunc = null; + + return this; + } + + var bindIdCounter = 0; + + f.bind = function(/*String*/type, /*Array||Function?*/data, /*Function*/fn){ + //Type can be space separated values. + type = type.split(" "); + + //May not have data argument. + if(!fn){ + fn = data; + data = null; + } + + this.forEach(function(node){ + //Only handle non text/comment nodes. + if(node.nodeType != 3 && node.nodeType != 8){ + + //If document, bind to documentElement + if(node.nodeType == 9){ + node = node.documentElement; + } + + //If no nodeId, then create one and attach it to the DOM node. + var nodeId = node.getAttribute(eventAttr); + if(!nodeId){ + nodeId = listenId++; + node.setAttribute(eventAttr, nodeId); + listeners[nodeId] = {}; + } + + //Process each event type. + for(var i = 0; i < type.length; i++){ + //Get event name, if have a dot on it, it is namespaced, + //be sure to get the core event name. + var evtFullName = type[i]; + var evtName = getNonNamespacedName(evtFullName); + if(evtName == evtFullName){ + //Generate a unique ID for this function binding + evtFullName = evtName + "$$" + (bindIdCounter++); + } + + //Get the event listeners for the event name, the complete name. + var lls = listeners[nodeId]; + if(!lls[evtName]){ + lls[evtName] = { + _connectId: domConnect(node, evtName) + }; + } + + //Add the callback to the list of listeners. + lls[evtName][evtFullName] = { + fn: fn, + data: data + }; + } + } + }); + + return this; + } + + function copyEventHandlers(/*DOMNode*/ src, /*DOMNode*/ target){ + // summary: + // copies the event handlers from onne src *element* node to + // another target *element* node. Assumes that target had + // no previous events on it, and is a clone of the src node. + + //Get src listeners. + var srcNodeId = target.getAttribute(eventAttr); + var sls = listeners[srcNodeId]; + if(!sls){ + return; + } + + //Generate listeners area for target. + var nodeId = nodeId = listenId++; + target.setAttribute(eventAttr, nodeId); + var tls = listeners[nodeId] = {}; + + //Loope through events in source. Protect against bad + //code modifying Object.prototype. + var empty = {}; + for (var evtName in sls){ + var tEvtData = tls[evtName] = { + _connectId: domConnect(target, evtName) + }; + var sEvtData = sls[evtName]; + + for (var evtFullName in sEvtData){ + tEvtData[evtFullName] = { + fn: sEvtData[evtFullName].fn, + data: sEvtData[evtFullName].data + }; + } + } + } + + function listenerUnbind(lls, evtName, evtFullName, callbackId, fn){ + //Handles the real remove of an event and dojo.disconnects DOM handler if necessary. + //This has to be broken out of the main unbind function because we have to support + //things like unbind(".test") that go across major event names. Yuck. + var handles = lls[evtName]; + if(handles){ + var hasDot = evtFullName.indexOf(".") != -1; + var forceDelete = false; + + if(callbackId){ + //Only need to unbind that one callback + delete handles[callbackId]; + }else if(!hasDot && !fn){ + forceDelete = true; + }else if(hasDot){ + //A namespaced event. + //Problem is the namespaced event could be something like + //".test" which means remove all that end in .test. Yuck. + if(evtFullName.charAt(0) == "."){ + for(var param in handles){ + if(param.indexOf(evtFullName) == param.length - evtFullName.length){ + delete handles[param]; + } + } + }else{ + delete handles[evtFullName]; + } + }else{ + //Not a namespaced event. Cycle through the $$ names + //to find a function match. + for(var param in handles){ + if(param.indexOf("$$") != -1 && handles[param].fn == fn){ + delete handles[param]; + break; + } + } + } + + //Remove handles/disconnect dom if no other params. + var allDone = true; + for(var param in handles){ + if(param != "_connectId"){ + allDone = false; + break; + } + } + if(forceDelete || allDone){ + if(evtName.indexOf("ajax") != -1){ + dojo.unsubscribe(handles._connectId); + }else{ + dojo.disconnect(handles._connectId); + } + delete lls[evtName]; + } + } + } + + f.unbind = function(/*String*/type, /*Function*/fn){ + + //See if event has a callbackId, if so, then we only unbind + //that one callback. + var callbackId = type ? type[dojo._scopeName + "callbackId"] : null; + + //Type can be space separated values. + type = type && type.type ? type.type : type; + type = type ? type.split(" ") : type; + + this.forEach(function(node){ + //Only handle non text/comment nodes. + if(node.nodeType != 3 && node.nodeType != 8){ + //If document, bind to documentElement + if(node.nodeType == 9){ + node = node.documentElement; + } + + //If no nodeId, then create one and attach it to the DOM node. + var nodeId = node.getAttribute(eventAttr); + + if(nodeId){ + //Get the event listeners for the event name, the complete name. + var lls = listeners[nodeId]; + if(lls){ + //If no type, then it means do all bound types. Make a list of them. + var etypes = type; + if(!etypes){ + etypes = []; + for(var param in lls){ + etypes.push(param); + } + } + + //Process each event type. + for(var i = 0; i < etypes.length; i++){ + //Get event name, if have a dot on it, it is namespaced, + //be sure to get the core event name. + var evtFullName = etypes[i]; + var evtName = getNonNamespacedName(evtFullName); + + //Problem is the namespaced event could be something like + //".test" which means remove all that end in .test. Yuck. + if(evtFullName.charAt(0) == "."){ + for(var param in lls) { + listenerUnbind(lls, param, evtFullName, callbackId, fn); + } + }else{ + listenerUnbind(lls, evtName, evtFullName, callbackId, fn); + } + } + } + } + } + }); + + return this; + } + + f.one = function(/*String*/evtName, /*Function*/func){ + var oneFunc = function(){ + $(this).unbind(evtName, arguments.callee); + return func.apply(this, arguments); + } + + return this.bind(evtName, oneFunc); + }; + + f._cloneNode = function(/*DOMNode*/ src){ + // summary: + // private utiltity to clone a node. Copies event handlers too. + var target = src.cloneNode(true); + + if(src.nodeType == 1){ + //Look for event handlers in target. + var evNodes = dojo.query("[" + eventAttr + "]", target); + for(var i = 0, newNode; newNode = evNodes[i]; i++){ + var oldNode = dojo.query('[' + eventAttr + '="' + newNode.getAttribute(eventAttr) + '"]', src)[0]; + if(oldNode){ + copyEventHandlers(oldNode, newNode); + } + } + } + return target; + }; + + //Temporary testing shim to get past jquery test setup errors. + dojo.getObject("$.event.global", true); + + //Set up event handlers + dojo.forEach([ + "blur", "focus", "dblclick", "click", "error", "keydown", "keypress", "keyup", "load", "mousedown", + "mouseenter", "mouseleave", "mousemove", "mouseout", "mouseover", "mouseup", "submit", + "ajaxStart", "ajaxSend", "ajaxSuccess", "ajaxError", "ajaxComplete", "ajaxStop" + ], function(evt){ + f[evt] = function(callback){ + if(callback){ + this.bind(evt, callback); + }else{ + this.trigger(evt); + } + return this; + } + } + ); + + //END jquery Events API methods + + + //START jquery Effects API methods + //http://docs.jquery.com/Effects + function speedInt(speed){ + //Fix speed setting, translate string values to numbers. + if(dojo.isString(speed)){ + if(speed == "slow"){ + speed = 700; + }else if(speed = "fast"){ + speed = 300; + }else{ + //Everything else is considered normal speed. + speed = 500; + } + } + return speed; + } + + f.hide = function(/*String||Number*/speed, /*Function?*/callback){ + //Fix speed setting, translate string values to numbers. + speed = speedInt(speed); + + this.forEach(function(node){ + var style = node.style; + + //Skip if already hidden + var cs = dojo.getComputedStyle(node); + if(cs.display == "none"){ + return; + } + + style.overflow = "hidden"; + style.display = "block"; + + if(speed){ + //It is alive! + dojo.anim( + node, + { + width: 0, + height: 0, + opacity: 0 + }, + speed, + null, + function(){ + style.width = ""; + style.height = ""; + style.display = "none"; + return callback && callback.call(node); + } + ); + }else{ + //No need for animation, fast path it. + dojo.style(node, "display", "none"); + if(callback){ + callback.call(node); + } + } + }); + return this; + } + + f.show = function(/*String||Number*/speed, /*Function?*/callback){ + //Fix speed setting, translate string values to numbers. + speed = speedInt(speed); + + this.forEach(function(node){ + var style = node.style; + //Skip if the node is already showing. + var cs = dojo.getComputedStyle(node); + if(cs.display != "none"){ + return; + } + + if(speed){ + //Figure out size of element + //so we know when to stop animation. + //Try the easy path first. + var width = parseFloat(style.width); + var height = parseFloat(style.height); + if(!width || !height){ + //temporarily show the element to get + //dimensions + style.display = "block"; + var box = dojo.marginBox(node); + width = box.w; + height = box.h; + } + + //Make sure values are set to hidden state. + style.width = 0; + style.height = 0; + style.overflow = "hidden"; + dojo.attr(node, "opacity", 0); + style.display = "block"; + + //It is alive! + dojo.anim( + node, + { + width: width, + height: height, + opacity: 1 + }, + speed, + null, + callback ? dojo.hitch(node, callback) : undefined + ); + }else{ + dojo.style(node, "display", "block"); + if(callback){ + callback.call(node); + } + } + }); + return this; + } + + + //END jquery Effects API methods + + + //START jquery Ajax API methods + //http://docs.jquery.com/Ajax + + $.ajaxSettings = { + }; + + $.ajaxSetup = function(/*Object*/args){ + dojo.mixin($.ajaxSettings, args); + } + + var topics = { + "ajaxStart": "/dojo/io/start", + "ajaxSend": "/dojo/io/send", + "ajaxSuccess": "/dojo/io/load", + "ajaxError": "/dojo/io/error", + "ajaxComplete": "/dojo/io/done", + "ajaxStop": "/dojo/io/stop" + }; + + for(var fnName in topics){ + //Make sure we are dealing with properties + //we care about and not something another toolkit added. + if(fnName.indexOf("ajax") == 0){ + ;(function(fnName){ + f[fnName] = function(callback){ + this.forEach(function(node){ + dojo.subscribe(topics[fnName], function(){ + var fakeEvt = new $.Event(fnName); + var ioArgs = arguments[0] && arguments[0].ioArgs; + var xhr = ioArgs && ioArgs.xhr; + var args = ioArgs && ioArgs.args; + var res = arguments[1]; + if("ajaxComplete|ajaxSend|ajaxSuccess".indexOf(fnName) != -1){ + return callback.call(node, fakeEvt, xhr, args); + }else if(fnName == "ajaxError"){ + return callback.call(node, fakeEvt, xhr, args, res); + }else{ + //ajaxStart|ajaxStop + return callback.call(node, fakeEvt); + } + }); + }); + return this; + } + })(fnName); + } + }; + + //Override dojo._xhrObj(dfd.ioArgs.args) to support beforeSend + //Do not understand the reason for beforeSend, particularly + //returning false stops the request. + //WARNING: even with this code, the error and complete callbacks + //will be fired because the deferred is cancelled. I feel this is + //correct behavior for dojo, and not sure why beforeSend is needed. + var _oldXhrObj = dojo._xhrObj; + dojo._xhrObj = function(args){ + var xhr = _oldXhrObj.apply(dojo, arguments); + if(args && args.beforeSend){ + if(args.beforeSend(xhr) === false){ + return false; + } + } + return xhr; + } + + $.ajax = function(/*Object*/args){ + //Not sure if the args are considered mutable. + //Copy them to be safe. + var temp = dojo.delegate($.ajaxSettings); + for(var param in args){ + //For data objects merge the data do not overwrite. + if(param == "data" && dojo.isObject(args[param]) && dojo.isObject(temp.data)){ + for(var prop in args[param]){ + temp.data[prop] = args[param][prop]; + } + }else{ + temp[param] = args[param]; + } + } + args = temp; + var url = args.url; + + if("async" in args){ + args.sync = !args.async; + } + + //Turn off topic publications + if(args.global === false){ + args.ioPublish = false; + } + + if(args.data){ + var data = args.data; + if(dojo.isString(data)){ + //convert to an object. + args.content = dojo.queryToObject(data); + }else{ + //data property values could be a function, be sure to call them if so. + //Hmm, this seems to be of dubious value. + for(var param in data){ + if(dojo.isFunction(data[param])){ + data[param] = data[param](); + } + } + args.content = data; + } + } + + //dataType + var dataType = args.dataType; + if("dataType" in args){ + if(dataType == "script"){ + dataType = "javascript"; + }else if(dataType == "html"){ + dataType = "text"; + } + args.handleAs = dataType; + }else{ + //Make a guess based on the URL. + dataType = args.handleAs = "text"; + args.guessedType = true; + } + + //cache: + if("cache" in args){ + args.preventCache = !args.cache; + }else{ + if(args.dataType == "script" || args.dataType == "jsonp"){ + args.preventCache = true; + } + } + + //Hide error since dojo treats it different. + if(args.error){ + args._jqueryError = args.error; + delete args.error; + } + + //TODO: dataFilter + + //Set up callbacks. + args.handle = function(result, ioArgs){ + var textStatus = "success"; + if(result instanceof Error){ + textStatus = (result.dojoType == "timeout" ? "timeout" : "error"); + if(args._jqueryError){ + args._jqueryError(ioArgs.xhr, textStatus, result); + } + }else{ + //If we guessed the type, see if it should be XML. + var xml = (ioArgs.args.guessedType && ioArgs.xhr && ioArgs.xhr.responseXML); + if(xml){ + result = xml; + } + + if(args.success){ + args.success(result, textStatus, ioArgs.xhr); + } + } + if(args.complete){ + args.complete(result, textStatus, ioArgs.xhr); + } + + return result; + }; + + //Use a script tag if the request is xdomain or a jsonp thing. + var useScript = (dataType == "jsonp"); + if(dataType == "javascript"){ + //Get protocol and domain. + var colonIndex = url.indexOf(":"); + var slashIndex = url.indexOf("/"); + if(colonIndex > 0 && colonIndex < slashIndex){ + //Possibly xdomain. Peel off protocol and hostname to find out. + var lastSlash = url.indexOf("/", slashIndex + 2); + if(lastSlash == -1){ + lastSlash = url.length; + } + if(location.protocol != url.substring(0, colonIndex + 1) || + location.hostname != url.substring(slashIndex + 2, lastSlash)){ + useScript = true; + } + } + } + + if(useScript){ + if(dataType == "jsonp"){ + //Look for callback param + var cb = args.jsonp; + if(!cb){ + //Look in the URL + var params = args.url.split("?")[1]; + if(params && (params = dojo.queryToObject(params))){ + cb = findJsonpCallback(params); + if(cb){ + //Remove the cb from the url. + var regex = new RegExp("([&\\?])?" + cb + "=?"); + args.url = args.url.replace(regex + "=?"); + } + } + //Look in the content. + if(!cb){ + cb = findJsonpCallback(args.content); + if(cb){ + delete args.content[cb]; + } + } + } + args.jsonp = cb || "callback"; + } + var dfd = dojo.io.script.get(args); + return dfd; + }else{ + var dfd = dojo.xhr(args.type || "GET", args); + //If the XHR object is false, it means beforeSend canceled the request. + return dfd.ioArgs.xhr === false ? false : dfd.ioArgs.xhr; + } + } + + function findJsonpCallback(obj){ + for(var prop in obj){ + if(prop.indexOf("callback") == prop.length - 8){ + return prop; + } + } + return null; + } + + $.getpost = function(httpType, url, data, callback, dataType){ + var args = { + url: url, + type: httpType + }; + + //Normalize data, considering it may be the real + //callback. + if(data){ + if(dojo.isFunction(data) && !callback){ + args.complete = data; + }else{ + args.data = data; + } + } + + //Normalize callback, considering it may be + //the datatype. + if(callback){ + if(dojo.isString(callback) && !dataType){ + dataType = callback; + }else{ + args.complete = callback; + } + } + + if(dataType){ + args.dataType = dataType; + } + + return $.ajax(args); + }; + + $.get = dojo.hitch($, "getpost", "GET"); + $.post = dojo.hitch($, "getpost", "POST"); + $.getJSON = function(url, data, callback){ + return $.getpost("GET", url, data, callback, "json"); + } + $.getScript = function(url, callback){ + return $.ajax({ + url: url, + success: callback, + dataType: "script" + }); + } + + f.load = function(url, data, callback){ + + //See if this is a window or document. If so, then want to + //register onload handler. + var node = this[0]; + if(!node || !node.nodeType || node.nodeType == 9){ + dojo.addOnLoad(url); + return this; + } + + //The rest of this function is the ajax HTML load case. + //Pull off selector if it is on the url. + var parts = url.split(/\s+/); + url = parts[0]; + var query = parts[1]; + + var finalCb = callback || data; + + var cb = dojo.hitch(this, function(result, textStatus, xhr){ + //Try to find all the body content. + var match = result.match(/\<\s*body[^>]+>.*<\/body\s*>/i); + if(match){ + result = match; + } + + //Convert to DOM nodes. + var nodes = dojo._toDom(result); + + //Apply query, using a temp div to do the filtering. + if(query){ + var temp = $(dojo.create("div")); + temp.append(nodes); + nodes = temp.find(query); + }else{ + nodes = $(nodes.nodeType == 11 ? nodes.childNodes : nodes); + } + + //Add the HTML to all nodes in this node list. + this.html(nodes); + + //Call the user's callback. + //Use a timeout to allow any embedded scripts that + //were just inserted to run. + if(finalCb){ + setTimeout(dojo.hitch(this, function(){ + this.forEach(function(node){ + finalCb.call(node, result, textStatus, xhr); + }); + }), 10); + } + }); + + //Adjust parameters since they are variable. + if(!callback){ + data = cb; + }else{ + callback = cb; + } + + //Set HTTP method. If the data is a string, use get, if it is an object, + //use post. + var method = "GET"; + if(data && dojo.isObject(data)){ + method = "POST"; + } + + $.getpost(method, url, data, callback, "html"); + return this; + } + + var serializeExclude = "file|submit|image|reset|button|"; + f.serialize = function(){ + var ret = ""; + var strs = this.map(function(node){ + if(node.nodeName.toUpperCase() == "FORM"){ + return dojo.formToQuery(node); + }else{ + var type = (node.type||"").toLowerCase(); + if(serializeExclude.indexOf(type) == -1){ + var val = dojo.fieldToObject(node); + if(node.name && val != null){ + var q = {}; + q[node.name] = val; + return dojo.objectToQuery(q); + } + } + } + }); + return ret + strs.join("&"); + } + + $.param = function(obj){ + if(obj._is$ && obj.serialize){ + return obj.serialize(); + }else if(dojo.isArray(obj)){ + return dojo.map(obj, function(item){ + return $.param(item); + }).join("&"); + }else{ + return dojo.objectToQuery(obj); + } + } + + //END jquery Ajax API methods + + //START jquery Utilities API methods + //http://docs.jquery.com/Utilities + //TODO: + + $.isFunction = function(){ + var result = dojo.isFunction.apply(dojo, arguments); + //Make sure Object does not return true + if(result){ + result = (typeof(arguments[0]) != "object"); + } + return result; + } + + //END jquery Utilities API methods + + +})(); + + +}); |
