paperweb/web/ajax.js

198 lines
5.9 KiB
JavaScript

// PAPERWEB - GPLv3 licence
// Copyright 2006-2016 Yves Gablin
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// = Credits =
// Tutorial: http://robloche.free.fr/javascript/tuto_xhr/tuto_xhr.html
var ajax = {
XML: 1,
TXT: 2,
// public class Connection
// + start()
// - xmlhttp
Connection: function() {
var xh;
try {
xh = new XMLHttpRequest();
} catch (e1) { // IE
try {
xh = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e2) {
try {
xh = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e3) {
xh = null;
}
}
}
this.xmlhttp = xh;
},
// private class Link
// - connection: Connection
// - urlBuilder: user-provided function
// - resultHandler: user-provided function
// - resultType: XML|TXT
// - preventDefault : true|false = prevent default event consequence
Link: function(pSource, pEvent, pUrlBuilder, pResultHandler, pType, pPreventDefault) {
this.connection = new ajax.Connection();
this.urlBuilder = pUrlBuilder;
this.resultHandler = pResultHandler;
this.resultType = pType;
this.preventDefault = pPreventDefault;
if (!pSource.ajaxLinks) {
pSource.ajaxLinks = new Array();
pSource.addEventListener(pEvent, this.evhSourceTrigger);
}
pSource.ajaxLinks[pSource.ajaxLinks.length] = this;
if (pEvent != 'click') {
this.evhSourceTrigger.call(pSource, null);
}
},
// public static function link()
link: function(pSource, pUrlBuilder, pDestHandler, pType, pPreventDefault) {
var event;
switch (pSource.tagName) {
case 'SELECT':
case 'TEXTAREA':
event = 'change';
break;
case 'BUTTON':
event = 'click';
break;
case 'INPUT':
switch (pSource.type) {
case 'text':
case 'password':
case 'file':
case 'hidden':
event = 'change';
break;
case 'checkbox':
case 'radio':
case 'submit':
case 'reset':
case 'image':
case 'button':
event = 'click';
break;
}
break;
}
new ajax.Link(pSource, event, pUrlBuilder, pDestHandler, pType, pPreventDefault);
},
// public static function importNode()
importNode: function(pSourceNode, pDestDoc) {
var destNode;
switch (pSourceNode.nodeType) {
case 1: // Element
destNode = pDestDoc.createElement(pSourceNode.tagName);
break;
case 3: // TextNode
destNode = pDestDoc.createTextNode(pSourceNode.data);
break;
case 4: // CDATASection
destNode = pDestDoc.createCDATASection(pSourceNode.data);
break;
case 5: // EntityReference
destNode = pDestDoc.createEntityReference(pSourceNode.nodeName);
break;
case 7: // ProcessingInstruction
destNode = pDestDoc.createProcessingInstruction(pSourceNode.nodeName, pSourceNode.nodeValue);
break;
case 8: // Comment
destNode = pDestDoc.createComment(pSourceNode.data);
break;
case 9: // Document
return ajax.importNode(pSourceNode.documentElement, pDestDoc);
default:
return null;
}
if (pSourceNode.attributes) {
var att;
for (var numAtt = 0; numAtt < pSourceNode.attributes.length; numAtt++) {
att = pSourceNode.attributes[numAtt];
destNode.setAttribute(att.name, att.value);
}
}
if (pSourceNode.childNodes) {
var child;
for (var numCh = 0; numCh < pSourceNode.childNodes.length; numCh++) {
child = ajax.importNode(pSourceNode.childNodes[numCh], pDestDoc);
if (child != null) destNode.appendChild(child);
}
}
return destNode;
}
}
// public method Connection.start()
ajax.Connection.prototype.start = function(pUrl, pPostParams, pCallback, pType) {
if (!this.xmlhttp || !pCallback) return;
var xh = this.xmlhttp;
var async = true;
if (xh.ajaxConnectionConnected == true) {
xh.abort();
}
if (pPostParams) {
xh.open("POST", pUrl, async);
} else {
xh.open("GET", pUrl, async);
}
xh.onreadystatechange = function() {
if (xh.readyState == 4) {
var status = -1;
try { status = xh.status; } catch (unreachable) { }
if (xh.ajaxConnectionNotice) {
xh.ajaxConnectionNotice.parentNode.removeChild(xh.ajaxConnectionNotice);
xh.ajaxConnectionNotice = null;
}
var result = null;
if (status == 200) {
if (pType == ajax.XML) {
result = xh.responseXML;
} else {
result = xh.responseText;
}
}
xh.ajaxConnectionConnected = false;
pCallback(result);
}
};
var notice = document.createElement('div');
notice.appendChild(document.createTextNode('...'));
notice.className = 'ajax-connection-wait';
xh.ajaxConnectionNotice = document.getElementsByTagName('body').item(0).appendChild(notice);
if (pType == ajax.XML)
xh.overrideMimeType("text/xml");
xh.ajaxConnectionConnected = true;
xh.send(pPostParams);
};
// public method Link.evhSourceTrigger()
ajax.Link.prototype.evhSourceTrigger = function(pEvt) {
var link, prevent = false;
for (var i = 0; i < this.ajaxLinks.length; i++) {
link = this.ajaxLinks[i];
link.connection.start(link.urlBuilder(this), null, link.resultHandler, link.resultType);
prevent = prevent || link.preventDefault;
}
if (prevent) {
pEvt.preventDefault();
}
};