📄 wicket-ajax.js
字号:
/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* * Wicket Ajax Support * * @author Igor Vaynberg * @author Matej Knopp */if (Function.prototype.bind == null) { Function.prototype.bind = function(object) { var __method = this; return function() { return __method.apply(object, arguments); } }}// Wicket Namespaceif (typeof(Wicket) == "undefined") Wicket = { };Wicket.$ = function(arg) { if (arg == null || typeof(arg) == "undefined") { return null; } if (arguments.length > 1) { var e=[]; for (var i=0; i<arguments.length; i++) { e.push(Wicket.$(arguments[i])); } return e; } else if (typeof arg == 'string') { return document.getElementById(arg); } else { return arg; }}// returns if the element belongs to current document// if the argument is not element, function returns trueWicket.$$ = function(element) { if (typeof(element) == "string") { element = Wicket.$(element); } if (element == null || typeof(element) == "undefined" || element.tagName == null || typeof(element.tagName) == "undefined") { return true; } var id = element.getAttribute('id'); if (typeof(id) == "undefined" || id == null || id == "") return element.ownerDocument == document; else return document.getElementById(id) == element;}Wicket.isPortlet = function() { return Wicket.portlet == true;}Wicket.emptyFunction = function() { };Wicket.Class = { create: function() { return function() { this.initialize.apply(this, arguments); } }}/** * Add a check for old Safari. It should not be our responsibility to check the * browser's version, but it's a minor version that makes a difference here, * so we try to be at least user friendly. */if (typeof DOMParser == "undefined" && Wicket.Browser.isSafari()) { DOMParser = function () {} DOMParser.prototype.parseFromString = function (str, contentType) { alert('You are using an old version of Safari.\nTo be able to use this page you need at least version 2.0.1.'); }}/** * Logging functionality. */Wicket.Log = { enabled: function() { return wicketAjaxDebugEnabled(); }, info: function(msg) { if (Wicket.Log.enabled()) WicketAjaxDebug.logInfo(msg); }, error: function(msg) { if (Wicket.Log.enabled()) WicketAjaxDebug.logError(msg); }, log: function(msg) { if(Wicket.Log.enabled()) WicketAjaxDebug.log(msg); }},/** * Functions executer takes array of functions and executes them. Each function gets * the notify object, which needs to be called for the next function to be executed. * This way the functions can be executed synchronously. Each function has to call * the notify object at some point, otherwise the functions after it wont be executed. * After the FunctionExecuter is initiatialized, the start methods triggers the * first function. */Wicket.FunctionsExecuter = Wicket.Class.create();Wicket.FunctionsExecuter.prototype = { initialize: function(functions) { this.functions = functions; this.current = 0; this.depth = 0; // we need to limit call stack depth }, processNext: function() { if (this.current < this.functions.length) { var f = this.functions[this.current]; var run = function() { f(this.notify.bind(this)); }.bind(this); this.current++; if (this.depth > 50 || Wicket.Browser.isKHTML() || Wicket.Browser.isSafari()) { // to prevent khtml bug that crashes entire browser // or to prevent stack overflow (safari has small call stack) this.depth = 0; window.setTimeout(run, 1); } else { this.depth ++; run(); } } }, start: function() { this.processNext(); }, notify: function() { this.processNext(); }}Wicket.replaceOuterHtmlIE = function(element, text) { // replaces all <iframe references with <__WICKET_JS_REMOVE_X9F4A__iframe text var marker = "__WICKET_JS_REMOVE_X9F4A__"; function markIframe(text) { var t = text; var r = /<\s*iframe/i; while ((m = t.match(r)) != null) { t = Wicket.replaceAll(t, m[0], "<" + marker + m[0].substring(1)); } return t; } function removeIframeMark(text) { return Wicket.replaceAll(text, marker, ""); } if (element.tagName == "SCRIPT") { // we need to get the javascript content, so we create an invalid DOM structure, // (that is necessary for IE to let us see the innerHTML of the script tag var tempDiv = document.createElement("div"); tempDiv.innerHTML = "<table>" + text + "</table>"; var script = tempDiv.childNodes[0].childNodes[0].innerHTML; element.outerHtml = text; eval(script); return; } var parent = element.parentNode; var tn = element.tagName; var tempDiv = document.createElement("div"); var tempParent; // array for javascripts that were in the text var scripts = new Array(); if (window.parent == window || window.parent == null) { document.body.appendChild(tempDiv); } if (tn != 'TBODY' && tn != 'TR' && tn != "TD" && tn != "THEAD" && tn != "TFOOT" && tn != "TH") { // in case the element is not any of these // this is not exactly nice, but we need to get invalid markup inside innerHTML, // because otherwise IE just swallows the <script> tags (sometimes) tempDiv.innerHTML = '<table style="display:none">' + markIframe(text) + '</table>'; // now copy the script tags to array (needed later for script execution) var s = tempDiv.getElementsByTagName("script"); for (var i = 0; i < s.length; ++i) { scripts.push(s[i]); } // now use regular div so that we won't mess the DOM tempDiv.innerHTML = '<div style="display:none">' + text + '</div>'; // set the outer <div> as parent tempParent = tempDiv.childNodes[0]; tempParent.parentNode.removeChild(tempParent); } else { // same trick as with before, this time we need a div to to create invalid markup // (otherwise we wouldn't be able to get the script tags) tempDiv.innerHTML = '<div style="display:none">' + markIframe(text) + '</div>'; // now copy the script tags to array (needed later for script execution) var s = tempDiv.getElementsByTagName("script"); for (var i = 0; i < s.length; ++i) { scripts.push(s[i]); } // hack to get around the fact that IE doesn't allow to replace table elements tempDiv.innerHTML = '<table style="display: none">' + text + '</table>'; // get the parent element of new elements tempParent = tempDiv.getElementsByTagName(tn).item(0).parentNode; } // place all newly created elements before the old element while(tempParent.childNodes.length > 0) { var tempElement = tempParent.childNodes[0]; tempParent.removeChild(tempElement); parent.insertBefore(tempElement, element); tempElement = null; } // remove the original element parent.removeChild(element); element.outerHTML = ""; element = ""; if (window.parent == window || window.parent == null) { document.body.removeChild(tempDiv); } tempDiv.outerHTML = ""; parent = null; tempDiv = null; tempParent = null; for (i = 0; i < scripts.length; ++i) { Wicket.Head.addJavascripts(scripts[i], removeIframeMark); } }Wicket.replaceOuterHtmlSafari = function(element, text) { // if we are replacing a single <script> element if (element.tagName == "SCRIPT") { // create temporal div and add script as inner HTML var tempDiv = document.createElement("div"); tempDiv.innerHTML = text; // try to get script content var script = tempDiv.childNodes[0].innerHTML; if (typeof(script) != "string") { script = tempDiv.childNodes[0].text; } element.outerHTML = text; eval(script); return; } var parent = element.parentNode; var next = element.nextSibling; var index = 0; while (parent.childNodes[index] != element) { ++index; } element.outerHTML = text; element = parent.childNodes[index]; // go through newly added elements and try to find javascripts that // need to be executed while (element != next) { Wicket.Head.addJavascripts(element); element = element.nextSibling; }}/** * A cross-browser method that replaces the markup of an element. The behavior * is similar to calling element.outerHtml=text in internet explorer. However * this method also takes care of executing javascripts within the markup on * browsers that don't do that automatically. * Also this method takes care of replacing table elements (tbody, tr, td, thead) * on browser where it's not supported when using outerHTML (IE). */Wicket.replaceOuterHtml = function(element, text) { if (Wicket.Browser.isIE()) { Wicket.replaceOuterHtmlIE(element, text); } else if (Wicket.Browser.isSafari() || Wicket.Browser.isOpera()) { Wicket.replaceOuterHtmlSafari(element, text); } else /* GECKO */ { // create range and fragment var range = element.ownerDocument.createRange(); range.selectNode(element); var fragment = range.createContextualFragment(text); element.parentNode.replaceChild(fragment, element); } } /** * Decoding functionality * * Wicket sends rendered components and javascript as CDATA section of XML document. When the * component body itself contains a CDATA section, Wicket needs to escape it properly. */Wicket.decode = function(encoding, text) { if (encoding == "wicket1") { return Wicket.decode1(text); }}Wicket.decode1 = function(text) { return Wicket.replaceAll(text, "]^", "]");}Wicket.replaceAll = function(str, from, to) { var idx = str.indexOf(from); while (idx > -1) { str = str.replace(from, to); idx = str.indexOf(from); } return str;}/** * Form serialization * * To post a form using Ajax Wicket first needs to serialize it, which means composing a string * from form elments names and values. The string will then be set as body of POST request. */Wicket.Form = { }Wicket.Form.encode = function(text) { if (encodeURIComponent) { return encodeURIComponent(text); } else { return escape(text); }}Wicket.Form.serializeSelect = function(select){ // if it is a non-multiple select, iterating on each element is not required (WICKET-389) if (select.multiple == false){ return Wicket.Form.encode(select.name) + "=" + Wicket.Form.encode(select.value) + "&"; } //else var result = ""; for (var i = 0; i < select.options.length; ++i) { var option = select.options[i]; if (option.selected) { result += Wicket.Form.encode(select.name) + "=" + Wicket.Form.encode(option.value) + "&"; } } return result;}// this function intentionally ignores image and submit inputsWicket.Form.serializeInput = function(input) { var type = input.type.toLowerCase(); if ((type == "checkbox" || type == "radio") && input.checked) { return Wicket.Form.encode(input.name) + "=" + Wicket.Form.encode(input.value) + "&"; } else if (type == "text" || type == "password" || type == "hidden" || type == "textarea" || type == "search") { return Wicket.Form.encode(input.name) + "=" + Wicket.Form.encode(input.value) + "&"; } else { return ""; }}//list of item to exclude from serializationWicket.Form.excludeFromAjaxSerialization = {};// Returns url/post-body fragment representing element (e) Wicket.Form.serializeElement = function(e) { if (Wicket.Form.excludeFromAjaxSerialization && e.id && Wicket.Form.excludeFromAjaxSerialization[e.id] == "true") { return ""; } var tag = e.tagName.toLowerCase(); if (tag == "select") { return Wicket.Form.serializeSelect(e); } else if (tag == "input" || tag == "textarea") { return Wicket.Form.serializeInput(e); } else { return ""; }} Wicket.Form.doSerialize = function(form) { var result = ""; for (var i = 0; i < form.elements.length; ++i) { var e = form.elements[i]; if (e.name && e.name != "" && !e.disabled) { result += Wicket.Form.serializeElement(e); } } return result;}Wicket.Form.serialize = function(element, dontTryToFindRootForm) { if (element.tagName.toLowerCase() == "form") { return Wicket.Form.doSerialize(element); } else { // try to find a form in DOM parents var elementBck = element; if (dontTryToFindRootForm != true) { do { element = element.parentNode; } while(element.tagName.toLowerCase() != "form" && element.tagName.toLowerCase() != "body") } if (element.tagName.toLowerCase() == "form"){ // We found a form : serialize it return Wicket.Form.doSerialize(element); } else { // there is not form in dom hierarchy // simulate it var form = document.createElement("form"); parent = elementBck.parentNode; parent.replaceChild(form, elementBck); form.appendChild(elementBck); var result = Wicket.Form.doSerialize(form); parent.replaceChild(elementBck, form); return result } }}/** * DOM nodes serialization functionality * * The purpose of these methods is to return a string representation * of the DOM tree. */ Wicket.DOM = { }// Method for serializing DOM nodes to string// original taken from Tacos (http://tacoscomponents.jot.com)Wicket.DOM.serializeNodeChildren = function(node) { if (node == null) { return "" } var result = ""; for (var i = 0; i < node.childNodes.length; i++) { var thisNode = node.childNodes[i]; switch (thisNode.nodeType) { case 1: // ELEMENT_NODE case 5: // ENTITY_REFERENCE_NODE result += Wicket.DOM.serializeNode(thisNode); break; case 8: // COMMENT result += "<!--" + thisNode.nodeValue + "-->"; break; case 4: // CDATA_SECTION_NODE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -