📄 wicket-ajax.js
字号:
result += "<![CDATA[" + thisNode.nodeValue + "]]>"; break; case 3: // TEXT_NODE case 2: // ATTRIBUTE_NODE result += thisNode.nodeValue; break; default: break; } } return result; }Wicket.DOM.serializeNode = function(node){ if (node == null) { return "" } var result = ""; result += '<' + node.nodeName; if (node.attributes && node.attributes.length > 0) { for (var i = 0; i < node.attributes.length; i++) { result += " " + node.attributes[i].name + "=\"" + node.attributes[i].value + "\""; } } result += '>'; result += Wicket.DOM.serializeNodeChildren(node); result += '</' + node.nodeName + '>'; return result;}// Utility function that determines whether given element is part of the current documentWicket.DOM.containsElement = function(element) { var id = element.getAttribute("id"); if (id != null) return Wicket.$(id) != null; else return false;}/** * Channel management * * Wicket Ajax requests are organized in channels. A channel maintain the order of * requests and determines, what should happen when a request is fired while another * one is being processed. The default behavior (stack) puts the all subsequent requests * in a queue, while the drop behavior limits queue size to one, so only the most * recent of subsequent requests is executed. * The name of channel determines the policy. E.g. channel with name foochannel|s is * a stack channel, while barchannel|d is a drop channel. * * The Channel class is supposed to be used through the ChannelManager. */Wicket.Channel = Wicket.Class.create();Wicket.Channel.prototype = { initialize: function(name) { var res = name.match(/^([^|]+)\|(d|s)$/) if (res == null) this.type ='s'; // default to stack else this.type = res[2]; this.callbacks = new Array(); this.busy = false; }, schedule: function(callback) { if (this.busy == false) { this.busy = true; return callback(); } else { Wicket.Log.info("Channel busy - postponing..."); if (this.type == 's') // stack this.callbacks.push(callback); else /* drop */ this.callbacks[0] = callback; return null; } }, done: function() { var c = null; if (this.callbacks.length > 0) { c = this.callbacks.shift(); } if (c != null && typeof(c) != "undefined") { Wicket.Log.info("Calling posponed function..."); // we can't call the callback from this call-stack // therefore we set it on timer event window.setTimeout(c, 1); } else { this.busy = false; } }};/** * Channel manager maintains a map of channels. */Wicket.ChannelManager = Wicket.Class.create();Wicket.ChannelManager.prototype = { initialize: function() { this.channels = new Array(); }, // Schedules the callback to channel with given name. schedule: function(channel, callback) { var c = this.channels[channel]; if (c == null) { c = new Wicket.Channel(channel); this.channels[channel] = c; } return c.schedule(callback); }, // Tells the ChannelManager that the current callback in channel with given name // has finished processing and another scheduled callback can be executed (if any). done: function(channel) { var c = this.channels[channel]; if (c != null) c.done(); }};// Default channel manager instanceWicket.channelManager = new Wicket.ChannelManager();/** * The Ajax class handles low level details of creating and pooling XmlHttpRequest objects, * as well as registering and execution of pre-call, post-call and failure handlers. */ Wicket.Ajax = { // Creates a new instance of a XmlHttpRequest createTransport: function() { var transport = null; if (window.ActiveXObject) { transport = new ActiveXObject("Microsoft.XMLHTTP"); } else if (window.XMLHttpRequest) { transport = new XMLHttpRequest(); } if (transport == null) { Wicket.Log.error("Could not locate ajax transport. Your browser does not support the required XMLHttpRequest object or wicket could not gain access to it."); } return transport; }, transports: [], // Returns a transport from pool if any of them is not being used, or creates new instance getTransport: function() { var t = Wicket.Ajax.transports; for (var i = 0; i < t.length; ++i) { if (t[i].readyState == 0) { return t[i]; } } t.push(Wicket.Ajax.createTransport()); return t[t.length-1]; }, preCallHandlers: [], postCallHandlers: [], failureHandlers: [], registerPreCallHandler: function(handler) { var h = Wicket.Ajax.preCallHandlers; h.push(handler); }, registerPostCallHandler: function(handler) { var h = Wicket.Ajax.postCallHandlers; h.push(handler); }, registerFailureHandler: function(handler) { var h = Wicket.Ajax.failureHandlers; h.push(handler); }, invokePreCallHandlers: function() { var h = Wicket.Ajax.preCallHandlers; if (h.length > 0) { Wicket.Log.info("Invoking pre-call handler(s)..."); } for (var i = 0; i < h.length; ++i) { h[i](); } }, invokePostCallHandlers: function() { var h = Wicket.Ajax.postCallHandlers; if (h.length > 0) { Wicket.Log.info("Invoking post-call handler(s)..."); } for (var i = 0; i < h.length; ++i) { h[i](); } }, invokeFailureHandlers: function() { var h = Wicket.Ajax.failureHandlers; if (h.length > 0) { Wicket.Log.info("Invoking failure handler(s)..."); } for (var i = 0; i < h.length; ++i) { h[i](); } }}/** * The Ajax.Request class encapsulates a XmlHttpRequest. */Wicket.Ajax.Request = Wicket.Class.create();Wicket.Ajax.Request.prototype = { // Creates a new request object. initialize: function(url, loadedCallback, parseResponse, randomURL, failureHandler, channel) { this.url = url; this.loadedCallback = loadedCallback; // whether we should give the loadedCallback parsed response (DOM tree) or the raw string this.parseResponse = parseResponse != null ? parseResponse : true; this.randomURL = randomURL != null ? randomURL : true; this.failureHandler = failureHandler != null ? failureHandler : function() { }; this.async = true; this.channel = channel; this.precondition = function() { return true; } // allow a condition to block request // when suppressDone is set, the loadedCallback is responsible for calling // Ajax.Request.done() to process possibly pendings requests in the channel. this.suppressDone = false; this.instance = Math.random(); this.debugContent = true; }, done: function() { Wicket.channelManager.done(this.channel); }, createUrl: function() { if (this.randomURL == false) return this.url; else return this.url + (this.url.indexOf("?")>-1 ? "&" : "?") + "random=" + Math.random(); }, log: function(method, url) { var log = Wicket.Log.info; log(""); log("Initiating Ajax "+method+" request on " + url); }, failure: function() { this.failureHandler(); Wicket.Ajax.invokePostCallHandlers(); Wicket.Ajax.invokeFailureHandlers(); }, // Executes a get request get: function() { if (Wicket.isPortlet()) { // first check if a query string is provided var qs = this.url.indexOf('?'); if (qs==-1) { qs = this.url.indexOf('&'); } if (qs>-1) { var query = this.url.substring(qs+1); // ensure the query is not empty if (query && query.length > 0) { // cut off query part from original url this.url = this.url.substring(0,qs); // ensure query ends with & if (query.charAt(query.length-1)!='&') { query += "&"; } // post the query string instead to support portlets // for which you cannot modify/append to the url return this.post(query); } } } if (this.channel != null) { var res = Wicket.channelManager.schedule(this.channel, this.doGet.bind(this)); return res != null ? res : true; } else { return this.doGet(); } }, // The actual get request implementation doGet: function() { if (this.precondition()) { this.transport = Wicket.Ajax.getTransport(); var url = this.createUrl(); this.log("GET", url); Wicket.Ajax.invokePreCallHandlers(); var t = this.transport; if (t != null) { t.open("GET", url, this.async); t.onreadystatechange = this.stateChangeCallback.bind(this); // set a special flag to allow server distinguish between ajax and non-ajax requests t.setRequestHeader("Wicket-Ajax", "true"); t.setRequestHeader("Wicket-FocusedElementId", Wicket.Focus.lastFocusId || ""); t.setRequestHeader("Accept", "text/xml"); t.send(null); return true; } else { this.failure(); return false; } } else { this.done(); return true; } }, // Posts the given string post: function(body) { if (this.channel != null) { var res = Wicket.channelManager.schedule(this.channel, function() { this.doPost(body); }.bind(this)); return res != null ? res: true; } else { return this.doPost(body); } }, // The actual post implementation doPost: function(body) { if (this.precondition()) { this.transport = Wicket.Ajax.getTransport(); var url = this.createUrl(); this.log("POST", url); Wicket.Ajax.invokePreCallHandlers(); var t = this.transport; if (t != null) { // we allow body to be a method - to lazily evaluate itself if (typeof(body) == "function") { body = body(); } t.open("POST", url, this.async); t.onreadystatechange = this.stateChangeCallback.bind(this); t.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); // set a special flag to allow server distinguish between ajax and non-ajax requests t.setRequestHeader("Wicket-Ajax", "true"); t.setRequestHeader("Wicket-FocusedElementId", Wicket.Focus.lastFocusId || ""); t.setRequestHeader("Accept", "text/xml"); t.send(body); return true; } else { this.failure(); return false; } } else { this.done(); return true; } }, // Method that processes the request states stateChangeCallback: function() { var t = this.transport; if (t != null && t.readyState == 4) { try { status = t.status; } catch (e) { Wicket.Log.error("Exception evaluating AJAX status: " + e); status = "unavailable"; } if (status == 200 || status == "") { // as stupid as it seems, IE7 sets status to "" on ok // response came without error var responseAsText = t.responseText; // first try to get the redirect header var redirectUrl; try { redirectUrl = t.getResponseHeader('Ajax-Location'); } catch (ignore) { // might happen in older mozilla } // the redirect header was set, go to new url if (typeof(redirectUrl) != "undefined" && redirectUrl != null && redirectUrl != "") { t.onreadystatechange = Wicket.emptyFunction; // support/check for non-relative redirectUrl like as provided and needed in a portlet context if (redirectUrl.charAt(0)==('/')||redirectUrl.match("^http://")=="http://"||redirectUrl.match("^https://")=="https://") { window.location = redirectUrl; } else { var urlDepth = 0; while (redirectUrl.substring(0, 3) == "../") { urlDepth++; redirectUrl = redirectUrl.substring(3); } // Make this a string. var calculatedRedirect = window.location.pathname; while (urlDepth > -1) { urlDepth--; i = calculatedRedirect.lastIndexOf("/"); if (i > -1) { calculatedRedirect = calculatedRedirect.substring(0, i); } } calculatedRedirect += "/" + redirectUrl; window.location = calculatedRedirect; } } else { // no redirect, just regular response var log = Wicket.Log.info; log("Received ajax response (" + responseAsText.length + " characters)"); if (this.debugContent != false) { log("\n" + responseAsText); } // parse the response if the callback needs a DOM tree if (this.parseResponse == true) { var xmldoc; if (typeof(window.XMLHttpRequest) != "undefined" && typeof(DOMParser) != "undefined") { var parser = new DOMParser(); xmldoc = parser.parseFromString(responseAsText, "text/xml"); } else if (window.ActiveXObject) { xmldoc = t.responseXML; } // invoke the loaded callback with an xml document this.loadedCallback(xmldoc); } else { // invoke the loaded callback with raw string this.loadedCallback(responseAsText); } if (this.suppressDone == false) this.done(); } } else { // when an error happened var log = Wicket.Log.error; log("Received Ajax response with code: " + status); if (status == 500) { log("500 error had text: " + t.responseText); } this.done(); this.failure(); } t.onreadystatechange = Wicket.emptyFunction; t.abort(); this.transport = null; } }};/** * Ajax call fires a Wicket Ajax request and processes the response. * The response can contain * - javascript that should be invoked * - body of components being replaced * - header contributions of components */Wicket.Ajax.Call = Wicket.Class.create();Wicket.Ajax.Call.prototype = { // Initializes the Call initialize: function(url, successHandler, failureHandler, channel) { this.successHandler = successHandler != null ? successHandler : function() { }; this.failureHandler = failureHandler != null ? failureHandler : function() { }; var c = channel != null ? channel : "0|s"; // set the default channel if not specified // initialize the internal Ajax request this.request = new Wicket.Ajax.Request(url, this.loadedCallback.bind(this), true, true, failureHandler, c); this.request.suppressDone = true; }, // On ajax request failure failure: function(message) { if (message != null) Wicket.Log.error("Error while parsing response: " + message); this.request.done(); this.failureHandler(); Wicket.Ajax.invokePostCallHandlers(); Wicket.Ajax.invokeFailureHandlers(); }, // Fires a get request call: function() { return this.request.get(); }, // Fires a post request post: function(body) { return this.request.post(body); }, // Submits a form using ajax. // This method serializes a form and sends it as POST body. submitForm: function(form, submitButton) { var body = function() { var s = Wicket.Form.serialize(form);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -