/* * 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 */ var Class = { create: function() { return function() { this.initialize.apply(this, arguments); } } } if (Function.prototype.bind == null) { Function.prototype.bind = function(object) { var __method = this; return function() { return __method.apply(object, arguments); } } } // Wicket Namespace if (typeof(Wicket) == "undefined") Wicket = { }; Wicket.emptyFunction = function() { }; // Browser types Wicket.Browser = { isKHTML: function() { return /Konqueror|KHTML/.test(navigator.userAgent) && !/Apple/.test(navigator.userAgent); }, isSafari: function() { return /KHTML/.test(navigator.userAgent) && /Apple/.test(navigator.userAgent); }, isOpera: function() { return typeof(window.opera) != "undefined"; }, isIE: function() { return typeof(document.all) != "undefined" && typeof(window.opera) == "undefined"; }, isIEQuirks: function() { // is the browser internet explorer in quirks mode (we could use document.compatMode too) return Wicket.Browser.isIE() && document.documentElement.clientHeight == 0; }, isIE7: function() { var index = navigator.userAgent.indexOf("MSIE"); var version = parseFloat(navigator.userAgent.substring(index + 5)); return Wicket.Browser.isIE() && version >= 7; }, isGecko: function() { return /Gecko/.test(navigator.userAgent) && !Wicket.Browser.isSafari(); } }; /** * 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 functions 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 Wicket.FunctionsExecuter = 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(); } } /* Replaces the element's outer html with the given text. If it's needed (for all browsers except gecko based) it takes the newly created scripts elements and adds them to head (execute them) */ Wicket.replaceOuterHtml = function(element, text) { if (element.outerHTML) { // internet explorer or opera var parent = element.parentNode; // find out the element's index and next element (if any). we need to access // newly created elements to execute theirs "); var xmldoc; if (window.ActiveXObject) { xmldoc = new ActiveXObject("Microsoft.XMLDOM"); xmldoc.loadXML(text); } else { var parser = new DOMParser(); xmldoc = parser.parseFromString(text, "text/xml"); } return xmldoc; }, processContribution: function(steps, headerNode) { var xmldoc = this.parse(headerNode); var rootNode = xmldoc.documentElement; for (var i = 0; i < rootNode.childNodes.length; i++) { var node = rootNode.childNodes[i]; if (node.tagName != null) { var name = node.tagName.toLowerCase(); if (name == "wicket:link") { // it is a reference surrounded by wicket:link // try to find content node for (var j = 0; j < node.childNodes.length; ++j) { var childNode = node.childNodes[j]; // try to find a regular node inside wicket:link if (childNode.nodeType == 1) { node = childNode; name = node.tagName.toLowerCase(); break; } } } if (name == "link") { this.processLink(steps, node); } else if (name == "script") { this.processScript(steps, node); } else if (name == "style") { this.processStyle(steps, node); } } } }, processLink: function(steps, node) { steps.push(function(notify) { if (Wicket.Head.containsElement(node, "href")) { notify(); return; } var css = Wicket.Head.createElement("link"); css.id = node.getAttribute("id"); css.rel = node.getAttribute("rel"); css.href = node.getAttribute("href"); css.type = node.getAttribute("type"); Wicket.Head.addElement(css); notify(); }); }, processStyle: function(steps, node) { steps.push(function(notify) { if (Wicket.DOM.containsElement(node)) { notify(); return; } var content = Wicket.DOM.serializeNodeChildren(node); var style = Wicket.Head.createElement("style"); style.id = node.getAttribute("id"); if (Wicket.Browser.isIE()) { document.createStyleSheet().cssText = content; } else { var textNode = document.createTextNode(content); style.appendChild(textNode); } Wicket.Head.addElement(style); notify(); }); }, processScript: function(steps, node) { steps.push(function(notify) { if (Wicket.DOM.containsElement(node) || Wicket.Head.containsElement(node, "src")) { notify(); return; } var src = node.getAttribute("src"); if (src != null && src != "") { var onLoad = function(content) { Wicket.Head.addJavascript(content, null, src); Wicket.Ajax.invokePostCallHandlers(); notify(); } // we need to schedule the request as timeout // calling xml http request from another request call stack doesn't work window.setTimeout(function() { var req = new Wicket.Ajax.Request(src, onLoad, false, false); req.debugContent = false; if (Wicket.Browser.isKHTML()) req.async = false; req.get(); },1); } else { var text = Wicket.DOM.serializeNodeChildren(node); Wicket.Head.addJavascript(text, node.getAttribute("id")); notify(); } }); } }; Wicket.Head.createElement = function(name) { return document.createElement(name); } Wicket.Head.addElement = function(element) { var head = document.getElementsByTagName("head"); if (head[0]) { head[0].appendChild(element); } } Wicket.Head.containsElement = function(element, mandatoryAttribute) { var attr = element.getAttribute(mandatoryAttribute); if (attr == null || attr == "" || typeof(attr) == "undefined") return false; var head = document.getElementsByTagName("head")[0]; var nodes = head.getElementsByTagName(element.tagName); for (var i = 0; i < nodes.length; ++i) { var node = nodes[i]; if (node.tagName.toLowerCase() == element.tagName.toLowerCase() && (node.getAttribute(mandatoryAttribute) == attr || node.getAttribute(mandatoryAttribute+"_") == attr)) { return true; } } return false; } Wicket.Head.addJavascript = function(content, id, fakeSrc) { var script = Wicket.Head.createElement("script"); script.id = id; script.setAttribute("src_", fakeSrc); if (null == script.canHaveChildren || script.canHaveChildren) { var textNode = document.createTextNode(content); script.appendChild(textNode); } else { script.text = content; } Wicket.Head.addElement(script); } /* Goes through all script elements contained by the element and add them to head. */ Wicket.Head.addJavascripts = function(element) { function add(element) { var content = Wicket.DOM.serializeNodeChildren(element); if (content == null || content == "") content = element.text; Wicket.Head.addJavascript(content); } if (typeof(element) != "undefined" && typeof(element.tagName) != "undefined" && element.tagName.toLowerCase() == "script") { add(element); } else { // we need to check if there are any children, becase Safari // aborts when the element is a text node if (element.childNodes.length > 0) { var scripts = element.getElementsByTagName("script"); for (var i = 0; i < scripts.length; ++i) { add(scripts[i]); } } } } // Throttler Wicket.ThrottlerEntry = Class.create(); Wicket.ThrottlerEntry.prototype = { initialize: function(func) { this.func = func; this.timestamp = new Date().getTime(); }, getTimestamp: function() { return this.timestamp; }, getFunc: function() { return this.func; }, setFunc: function(func) { this.func = func; } }; Wicket.Throttler = Class.create(); Wicket.Throttler.prototype = { initialize: function() { this.entries = new Array(); }, throttle: function(id, millis, func) { var entry = this.entries[id]; var me = this; if (entry == undefined) { entry = new Wicket.ThrottlerEntry(func); this.entries[id] = entry; window.setTimeout(function() { me.execute(id); }, millis); } else { entry.setFunc(func); } }, execute: function(id) { var entry = this.entries[id]; if (entry != undefined) { var func = entry.getFunc(); var tmp = func(); } this.entries[id] = undefined; } }; Wicket.throttler = new Wicket.Throttler(); /* * Compatibility layer */ var wicketThrottler = Wicket.throttler; function wicketAjaxGet(url, successHandler, failureHandler, channel) { var call = new Wicket.Ajax.Call(url, successHandler, failureHandler, channel); return call.call(); } function wicketAjaxPost(url, body, successHandler, failureHandler, channel) { var call = new Wicket.Ajax.Call(url, successHandler, failureHandler, channel); return call.post(body); } function wicketSubmitForm(form, url, submitButton, successHandler, failureHandler, channel) { var call = new Wicket.Ajax.Call(url, successHandler, failureHandler, channel); return call.submitForm(form, submitButton); } function wicketSubmitFormById(formId, url, submitButton, successHandler, failureHandler, channel) { var call = new Wicket.Ajax.Call(url, successHandler, failureHandler, channel); return call.submitFormById(formId, submitButton); } wicketSerialize = Wicket.Form.serializeElement; wicketSerializeForm = Wicket.Form.serialize; wicketEncode = Wicket.Form.encode; wicketDecode = Wicket.decode; wicketAjaxGetTransport = Wicket.Ajax.getTransport; // Global handlers stubs Wicket.Ajax.registerPreCallHandler(function() { if (typeof(window.wicketGlobalPreCallHandler) != "undefined") { var global=wicketGlobalPreCallHandler; if (global!=null) { global(); } } }); Wicket.Ajax.registerPostCallHandler(function() { if (typeof(window.wicketGlobalPostCallHandler) != "undefined") { var global=wicketGlobalPostCallHandler; if (global!=null) { global(); } } }); Wicket.Ajax.registerFailureHandler(function() { if (typeof(window.wicketGlobalFailureHandler) != "undefined") { var global=wicketGlobalFailureHandler; if (global!=null) { global(); } } }); // DEBUG FUNCTIONS function wicketAjaxDebugEnabled() { if (typeof(wicketAjaxDebugEnable)=="undefined") { return false; } else { return wicketAjaxDebugEnable==true; } } // MISC FUNCTIONS function wicketKeyCode(event) { if (typeof(event.keyCode)=="undefined") { return event.which; } else { return event.keyCode; } } function wicketGet(id) { return document.getElementById(id); } function wicketShow(id) { var e=wicketGet(id); e.style.display = ""; } function wicketHide(id) { var e=wicketGet(id); e.style.display = "none"; }