Load XMLHttpRequest conditionally (< IE9)
parent
a1bec0e995
commit
59ce12a51b
1
NEWS
1
NEWS
|
@ -9,6 +9,7 @@ Enhancements
|
||||||
- we now automatically convert <img src=data...> into file attachments
|
- we now automatically convert <img src=data...> into file attachments
|
||||||
using CIDs. This prevents Outlook issues.
|
using CIDs. This prevents Outlook issues.
|
||||||
- updated Finnish translation
|
- updated Finnish translation
|
||||||
|
- XMLHttpRequest is now loaded conditionaly (< IE9)
|
||||||
|
|
||||||
Bug fixes
|
Bug fixes
|
||||||
-
|
-
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
/* SOGoIEConditional.h - this file is part of SOGo
|
/* SOGoIEConditional.h - this file is part of SOGo
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007 Inverse inc.
|
* Copyright (C) 2007-2013 Inverse inc.
|
||||||
*
|
*
|
||||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
* Author: Inverse <info@inverse.ca>
|
||||||
*
|
*
|
||||||
* This file is free software; you can redistribute it and/or modify
|
* This file is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -32,6 +32,7 @@
|
||||||
@interface SOGoIEConditional : WODynamicElement
|
@interface SOGoIEConditional : WODynamicElement
|
||||||
{
|
{
|
||||||
WOElement *template;
|
WOElement *template;
|
||||||
|
WOAssociation *lte; // int
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) appendToResponse: (WOResponse *) _response
|
- (void) appendToResponse: (WOResponse *) _response
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
/* SOGoIEConditional.m - this file is part of SOGo
|
/* SOGoIEConditional.m - this file is part of SOGo
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007 Inverse inc.
|
* Copyright (C) 2007-2013 Inverse inc.
|
||||||
*
|
*
|
||||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
* Author: Inverse <info@inverse.ca>
|
||||||
*
|
*
|
||||||
* This file is free software; you can redistribute it and/or modify
|
* This file is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -22,6 +22,7 @@
|
||||||
|
|
||||||
#import <NGObjWeb/WOContext.h>
|
#import <NGObjWeb/WOContext.h>
|
||||||
#import <NGObjWeb/WOResponse.h>
|
#import <NGObjWeb/WOResponse.h>
|
||||||
|
#import <NGObjWeb/WOAssociation.h>
|
||||||
|
|
||||||
#import "SOGoIEConditional.h"
|
#import "SOGoIEConditional.h"
|
||||||
|
|
||||||
|
@ -34,7 +35,10 @@
|
||||||
if ((self = [super initWithName: name
|
if ((self = [super initWithName: name
|
||||||
associations: associations
|
associations: associations
|
||||||
template: newTemplate]))
|
template: newTemplate]))
|
||||||
ASSIGN (template, newTemplate);
|
{
|
||||||
|
ASSIGN (template, newTemplate);
|
||||||
|
lte = OWGetProperty(associations, @"lte");
|
||||||
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
@ -42,13 +46,21 @@
|
||||||
- (void) dealloc
|
- (void) dealloc
|
||||||
{
|
{
|
||||||
[template release];
|
[template release];
|
||||||
|
[lte release];
|
||||||
[super dealloc];
|
[super dealloc];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) appendToResponse: (WOResponse *) response
|
- (void) appendToResponse: (WOResponse *) response
|
||||||
inContext: (WOContext *) context
|
inContext: (WOContext *) context
|
||||||
{
|
{
|
||||||
[response appendContentString: @"<!--[if IE]>"];
|
NSString *condition;
|
||||||
|
|
||||||
|
if (lte)
|
||||||
|
condition = [NSString stringWithFormat: @"<!--[if lte IE %d ]>", [lte intValueInComponent: [context component]]];
|
||||||
|
else
|
||||||
|
condition = @"<!--[if IE]>";
|
||||||
|
|
||||||
|
[response appendContentString: condition];
|
||||||
[template appendToResponse: response inContext: context];
|
[template appendToResponse: response inContext: context];
|
||||||
[response appendContentString: @"<![endif]-->"];
|
[response appendContentString: @"<![endif]-->"];
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,9 +34,10 @@
|
||||||
><link type="text/css" rel="stylesheet" var:href="item"
|
><link type="text/css" rel="stylesheet" var:href="item"
|
||||||
/>
|
/>
|
||||||
</var:foreach>
|
</var:foreach>
|
||||||
<var:if-ie
|
<var:if-ie const:lte="9"
|
||||||
><link type="text/css" rel="stylesheet" rsrc:href="iefixes.css"
|
><link type="text/css" rel="stylesheet" rsrc:href="iefixes.css"/>
|
||||||
/></var:if-ie>
|
<script type="text/javascript" rsrc:src="XMLHttpRequest.js"><!-- space --></script>
|
||||||
|
</var:if-ie>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body var:class="bodyClasses"
|
<body var:class="bodyClasses"
|
||||||
|
@ -154,7 +155,6 @@
|
||||||
<script type="text/javascript" rsrc:src="prototype.js"><!-- space --></script>
|
<script type="text/javascript" rsrc:src="prototype.js"><!-- space --></script>
|
||||||
<script type="text/javascript" rsrc:src="jquery.js"><!-- space --></script>
|
<script type="text/javascript" rsrc:src="jquery.js"><!-- space --></script>
|
||||||
<script>jQuery.noConflict();</script>
|
<script>jQuery.noConflict();</script>
|
||||||
<script type="text/javascript" rsrc:src="XMLHttpRequest.js"><!-- space --></script>
|
|
||||||
<script type="text/javascript" rsrc:src="tablekit.js"><!-- space --></script>
|
<script type="text/javascript" rsrc:src="tablekit.js"><!-- space --></script>
|
||||||
<script type="text/javascript" rsrc:src="tablekit-trueresize.js"><!-- space --></script>
|
<script type="text/javascript" rsrc:src="tablekit-trueresize.js"><!-- space --></script>
|
||||||
<script type="text/javascript" rsrc:src="tablekit-sogo.js"><!-- space --></script>
|
<script type="text/javascript" rsrc:src="tablekit-sogo.js"><!-- space --></script>
|
||||||
|
|
|
@ -1,80 +1,123 @@
|
||||||
// XMLHttpRequest.js Copyright (C) 2008 Sergey Ilinsky (http://www.ilinsky.com)
|
/**
|
||||||
//
|
* XMLHttpRequest.js Copyright (C) 2011 Sergey Ilinsky (http://www.ilinsky.com)
|
||||||
// This work is free software; you can redistribute it and/or modify
|
*
|
||||||
// it under the terms of the GNU Lesser General Public License as published by
|
* This work is free software; you can redistribute it and/or modify
|
||||||
// the Free Software Foundation; either version 2.1 of the License, or
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
// (at your option) any later version.
|
* the Free Software Foundation; either version 2.1 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
// This work is distributed in the hope that it will be useful,
|
*
|
||||||
// but without any warranty; without even the implied warranty of
|
* This work is distributed in the hope that it will be useful,
|
||||||
// merchantability or fitness for a particular purpose. See the
|
* but without any warranty; without even the implied warranty of
|
||||||
// GNU Lesser General Public License for more details.
|
* merchantability or fitness for a particular purpose. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
// You should have received a copy of the GNU Lesser General Public License
|
*
|
||||||
// along with this library; if not, write to the Free Software Foundation, Inc.,
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* along with this library; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
(function () {
|
(function () {
|
||||||
|
|
||||||
// Save reference to earlier defined object implementation (if any)
|
// Save reference to earlier defined object implementation (if any)
|
||||||
var oXMLHttpRequest = window.XMLHttpRequest;
|
var oXMLHttpRequest = window.XMLHttpRequest;
|
||||||
|
|
||||||
// Define on browser type
|
// Define on browser type
|
||||||
var bGecko = !!window.controllers,
|
var bGecko = !!window.controllers;
|
||||||
bIE = window.document.all && !window.opera;
|
var bIE = !!window.document.namespaces;
|
||||||
|
var bIE7 = bIE && window.navigator.userAgent.match(/MSIE 7.0/);
|
||||||
|
|
||||||
|
// Enables "XMLHttpRequest()" call next to "new XMLHttpRequest()"
|
||||||
|
function fXMLHttpRequest() {
|
||||||
|
if (!window.XMLHttpRequest || bIE7) {
|
||||||
|
this._object = new window.ActiveXObject("Microsoft.XMLHTTP");
|
||||||
|
} // only use initial XHR object internally if current reference to XHR is our normalized replacement
|
||||||
|
else if (window.XMLHttpRequest.isNormalizedObject) {
|
||||||
|
this._object = new oXMLHttpRequest();
|
||||||
|
} // otherwise use whatever is currently referenced by XMLHttpRequest
|
||||||
|
else {
|
||||||
|
this._object = new window.XMLHttpRequest();
|
||||||
|
}
|
||||||
|
this._listeners = [];
|
||||||
|
}
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
function cXMLHttpRequest() {
|
function cXMLHttpRequest() {
|
||||||
this._object = oXMLHttpRequest ? new oXMLHttpRequest : new window.ActiveXObject("Microsoft.XMLHTTP");
|
return new fXMLHttpRequest;
|
||||||
this._listeners = [];
|
}
|
||||||
};
|
cXMLHttpRequest.prototype = fXMLHttpRequest.prototype;
|
||||||
|
|
||||||
// BUGFIX: Firefox with Firebug installed would break pages if not executed
|
// BUGFIX: Firefox with Firebug installed would break pages if not executed
|
||||||
if (bGecko && oXMLHttpRequest.wrapped)
|
if (bGecko && oXMLHttpRequest.wrapped) {
|
||||||
cXMLHttpRequest.wrapped = oXMLHttpRequest.wrapped;
|
cXMLHttpRequest.wrapped = oXMLHttpRequest.wrapped;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Marker to be able to easily identify our object
|
||||||
|
cXMLHttpRequest.isNormalizedObject = true;
|
||||||
|
|
||||||
// Constants
|
// Constants
|
||||||
cXMLHttpRequest.UNSENT = 0;
|
cXMLHttpRequest.UNSENT = 0;
|
||||||
cXMLHttpRequest.OPENED = 1;
|
cXMLHttpRequest.OPENED = 1;
|
||||||
cXMLHttpRequest.HEADERS_RECEIVED = 2;
|
cXMLHttpRequest.HEADERS_RECEIVED = 2;
|
||||||
cXMLHttpRequest.LOADING = 3;
|
cXMLHttpRequest.LOADING = 3;
|
||||||
cXMLHttpRequest.DONE = 4;
|
cXMLHttpRequest.DONE = 4;
|
||||||
|
|
||||||
|
// Interface level constants
|
||||||
|
cXMLHttpRequest.prototype.UNSENT = cXMLHttpRequest.UNSENT;
|
||||||
|
cXMLHttpRequest.prototype.OPENED = cXMLHttpRequest.OPENED;
|
||||||
|
cXMLHttpRequest.prototype.HEADERS_RECEIVED = cXMLHttpRequest.HEADERS_RECEIVED;
|
||||||
|
cXMLHttpRequest.prototype.LOADING = cXMLHttpRequest.LOADING;
|
||||||
|
cXMLHttpRequest.prototype.DONE = cXMLHttpRequest.DONE;
|
||||||
|
|
||||||
// Public Properties
|
// Public Properties
|
||||||
cXMLHttpRequest.prototype.readyState = cXMLHttpRequest.UNSENT;
|
cXMLHttpRequest.prototype.readyState = cXMLHttpRequest.UNSENT;
|
||||||
cXMLHttpRequest.prototype.responseText = '';
|
cXMLHttpRequest.prototype.responseText = '';
|
||||||
cXMLHttpRequest.prototype.responseXML = null;
|
cXMLHttpRequest.prototype.responseXML = null;
|
||||||
cXMLHttpRequest.prototype.status = 0;
|
cXMLHttpRequest.prototype.status = 0;
|
||||||
cXMLHttpRequest.prototype.statusText = '';
|
cXMLHttpRequest.prototype.statusText = '';
|
||||||
|
|
||||||
|
// Priority proposal
|
||||||
|
cXMLHttpRequest.prototype.priority = "NORMAL";
|
||||||
|
|
||||||
// Instance-level Events Handlers
|
// Instance-level Events Handlers
|
||||||
cXMLHttpRequest.prototype.onreadystatechange = null;
|
cXMLHttpRequest.prototype.onreadystatechange = null;
|
||||||
|
|
||||||
// Class-level Events Handlers
|
// Class-level Events Handlers
|
||||||
cXMLHttpRequest.onreadystatechange = null;
|
cXMLHttpRequest.onreadystatechange = null;
|
||||||
cXMLHttpRequest.onopen = null;
|
cXMLHttpRequest.onopen = null;
|
||||||
cXMLHttpRequest.onsend = null;
|
cXMLHttpRequest.onsend = null;
|
||||||
cXMLHttpRequest.onabort = null;
|
cXMLHttpRequest.onabort = null;
|
||||||
|
|
||||||
// Public Methods
|
// Public Methods
|
||||||
cXMLHttpRequest.prototype.open = function(sMethod, sUrl, bAsync, sUser, sPassword) {
|
cXMLHttpRequest.prototype.open = function(sMethod, sUrl, bAsync, sUser, sPassword) {
|
||||||
|
// http://www.w3.org/TR/XMLHttpRequest/#the-open-method
|
||||||
|
var sLowerCaseMethod = sMethod.toLowerCase();
|
||||||
|
if (sLowerCaseMethod == "connect" || sLowerCaseMethod == "trace" || sLowerCaseMethod == "track") {
|
||||||
|
// Using a generic error and an int - not too sure all browsers support correctly
|
||||||
|
// http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#securityerror, so, this is safer
|
||||||
|
// XXX should do better than that, but this is OT to XHR.
|
||||||
|
throw new Error(18);
|
||||||
|
}
|
||||||
|
|
||||||
// When bAsync parameter value is ommited, use true as default
|
// Delete headers, required when object is reused
|
||||||
if (arguments.length < 3)
|
delete this._headers;
|
||||||
bAsync = true;
|
|
||||||
|
// When bAsync parameter value is omitted, use true as default
|
||||||
|
if (arguments.length < 3) {
|
||||||
|
bAsync = true;
|
||||||
|
}
|
||||||
|
|
||||||
// Save async parameter for fixing Gecko bug with missing readystatechange in synchronous requests
|
// Save async parameter for fixing Gecko bug with missing readystatechange in synchronous requests
|
||||||
this._async = bAsync;
|
this._async = bAsync;
|
||||||
|
|
||||||
// Set the onreadystatechange handler
|
// Set the onreadystatechange handler
|
||||||
var oRequest = this,
|
var oRequest = this;
|
||||||
nState = this.readyState,
|
var nState = this.readyState;
|
||||||
fOnUnload;
|
var fOnUnload = null;
|
||||||
|
|
||||||
// BUGFIX: IE - memory leak on page unload (inter-page leak)
|
// BUGFIX: IE - memory leak on page unload (inter-page leak)
|
||||||
if (bIE && bAsync) {
|
if (bIE && bAsync) {
|
||||||
fOnUnload = function() {
|
fOnUnload = function() {
|
||||||
if (oRequest._object.readyState != cXMLHttpRequest.DONE) {
|
if (nState != cXMLHttpRequest.DONE) {
|
||||||
fCleanTransport(oRequest);
|
fCleanTransport(oRequest);
|
||||||
// Safe to abort here since onreadystatechange handler removed
|
// Safe to abort here since onreadystatechange handler removed
|
||||||
oRequest.abort();
|
oRequest.abort();
|
||||||
|
@ -83,285 +126,411 @@
|
||||||
window.attachEvent("onunload", fOnUnload);
|
window.attachEvent("onunload", fOnUnload);
|
||||||
}
|
}
|
||||||
|
|
||||||
this._object.onreadystatechange = function() {
|
// Add method sniffer
|
||||||
if (bGecko && !bAsync)
|
if (cXMLHttpRequest.onopen) {
|
||||||
|
cXMLHttpRequest.onopen.apply(this, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (arguments.length > 4) {
|
||||||
|
this._object.open(sMethod, sUrl, bAsync, sUser, sPassword);
|
||||||
|
} else if (arguments.length > 3) {
|
||||||
|
this._object.open(sMethod, sUrl, bAsync, sUser);
|
||||||
|
} else {
|
||||||
|
this._object.open(sMethod, sUrl, bAsync);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.readyState = cXMLHttpRequest.OPENED;
|
||||||
|
fReadyStateChange(this);
|
||||||
|
|
||||||
|
this._object.onreadystatechange = function() {
|
||||||
|
if (bGecko && !bAsync) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Synchronize state
|
// Synchronize state
|
||||||
oRequest.readyState = oRequest._object.readyState;
|
oRequest.readyState = oRequest._object.readyState;
|
||||||
|
|
||||||
//
|
|
||||||
fSynchronizeValues(oRequest);
|
fSynchronizeValues(oRequest);
|
||||||
|
|
||||||
// BUGFIX: Firefox fires unneccesary DONE when aborting
|
// BUGFIX: Firefox fires unnecessary DONE when aborting
|
||||||
if (oRequest._aborted) {
|
if (oRequest._aborted) {
|
||||||
// Reset readyState to UNSENT
|
// Reset readyState to UNSENT
|
||||||
oRequest.readyState = cXMLHttpRequest.UNSENT;
|
oRequest.readyState = cXMLHttpRequest.UNSENT;
|
||||||
|
|
||||||
// Return now
|
// Return now
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (oRequest.readyState == cXMLHttpRequest.DONE) {
|
if (oRequest.readyState == cXMLHttpRequest.DONE) {
|
||||||
//
|
// Free up queue
|
||||||
|
delete oRequest._data;
|
||||||
|
|
||||||
|
// Uncomment these lines for bAsync
|
||||||
|
/**
|
||||||
|
* if (bAsync) {
|
||||||
|
* fQueue_remove(oRequest);
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
|
||||||
fCleanTransport(oRequest);
|
fCleanTransport(oRequest);
|
||||||
// Uncomment this block if you need a fix for IE cache
|
|
||||||
/*
|
|
||||||
// BUGFIX: IE - cache issue
|
|
||||||
if (!oRequest._object.getResponseHeader("Date")) {
|
|
||||||
// Save object to cache
|
|
||||||
oRequest._cached = oRequest._object;
|
|
||||||
|
|
||||||
// Instantiate a new transport object
|
// Uncomment this block if you need a fix for IE cache
|
||||||
cXMLHttpRequest.call(oRequest);
|
/**
|
||||||
|
* // BUGFIX: IE - cache issue
|
||||||
|
* if (!oRequest._object.getResponseHeader("Date")) {
|
||||||
|
* // Save object to cache
|
||||||
|
* oRequest._cached = oRequest._object;
|
||||||
|
*
|
||||||
|
* // Instantiate a new transport object
|
||||||
|
* cXMLHttpRequest.call(oRequest);
|
||||||
|
*
|
||||||
|
* // Re-send request
|
||||||
|
* if (sUser) {
|
||||||
|
* if (sPassword) {
|
||||||
|
* oRequest._object.open(sMethod, sUrl, bAsync, sUser, sPassword);
|
||||||
|
* } else {
|
||||||
|
* oRequest._object.open(sMethod, sUrl, bAsync);
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* oRequest._object.setRequestHeader("If-Modified-Since", oRequest._cached.getResponseHeader("Last-Modified") || new window.Date(0));
|
||||||
|
* // Copy headers set
|
||||||
|
* if (oRequest._headers) {
|
||||||
|
* for (var sHeader in oRequest._headers) {
|
||||||
|
* // Some frameworks prototype objects with functions
|
||||||
|
* if (typeof oRequest._headers[sHeader] == "string") {
|
||||||
|
* oRequest._object.setRequestHeader(sHeader, oRequest._headers[sHeader]);
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* oRequest._object.onreadystatechange = function() {
|
||||||
|
* // Synchronize state
|
||||||
|
* oRequest.readyState = oRequest._object.readyState;
|
||||||
|
*
|
||||||
|
* if (oRequest._aborted) {
|
||||||
|
* //
|
||||||
|
* oRequest.readyState = cXMLHttpRequest.UNSENT;
|
||||||
|
*
|
||||||
|
* // Return
|
||||||
|
* return;
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* if (oRequest.readyState == cXMLHttpRequest.DONE) {
|
||||||
|
* // Clean Object
|
||||||
|
* fCleanTransport(oRequest);
|
||||||
|
*
|
||||||
|
* // get cached request
|
||||||
|
* if (oRequest.status == 304) {
|
||||||
|
* oRequest._object = oRequest._cached;
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* //
|
||||||
|
* delete oRequest._cached;
|
||||||
|
*
|
||||||
|
* //
|
||||||
|
* fSynchronizeValues(oRequest);
|
||||||
|
*
|
||||||
|
* //
|
||||||
|
* fReadyStateChange(oRequest);
|
||||||
|
*
|
||||||
|
* // BUGFIX: IE - memory leak in interrupted
|
||||||
|
* if (bIE && bAsync) {
|
||||||
|
* window.detachEvent("onunload", fOnUnload);
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* }
|
||||||
|
* };
|
||||||
|
* oRequest._object.send(null);
|
||||||
|
*
|
||||||
|
* // Return now - wait until re-sent request is finished
|
||||||
|
* return;
|
||||||
|
* };
|
||||||
|
*/
|
||||||
|
|
||||||
// Re-send request
|
|
||||||
oRequest._object.open(sMethod, sUrl, bAsync, sUser, sPassword);
|
|
||||||
oRequest._object.setRequestHeader("If-Modified-Since", oRequest._cached.getResponseHeader("Last-Modified") || new window.Date(0));
|
|
||||||
// Copy headers set
|
|
||||||
if (oRequest._headers)
|
|
||||||
for (var sHeader in oRequest._headers)
|
|
||||||
if (typeof oRequest._headers[sHeader] == "string") // Some frameworks prototype objects with functions
|
|
||||||
oRequest._object.setRequestHeader(sHeader, oRequest._headers[sHeader]);
|
|
||||||
|
|
||||||
oRequest._object.onreadystatechange = function() {
|
|
||||||
// Synchronize state
|
|
||||||
oRequest.readyState = oRequest._object.readyState;
|
|
||||||
|
|
||||||
if (oRequest._aborted) {
|
|
||||||
//
|
|
||||||
oRequest.readyState = cXMLHttpRequest.UNSENT;
|
|
||||||
|
|
||||||
// Return
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (oRequest.readyState == cXMLHttpRequest.DONE) {
|
|
||||||
// Clean Object
|
|
||||||
fCleanTransport(oRequest);
|
|
||||||
|
|
||||||
// get cached request
|
|
||||||
if (oRequest.status == 304)
|
|
||||||
oRequest._object = oRequest._cached;
|
|
||||||
|
|
||||||
//
|
|
||||||
delete oRequest._cached;
|
|
||||||
|
|
||||||
//
|
|
||||||
fSynchronizeValues(oRequest);
|
|
||||||
|
|
||||||
//
|
|
||||||
fReadyStateChange(oRequest);
|
|
||||||
|
|
||||||
// BUGFIX: IE - memory leak in interrupted
|
|
||||||
if (bIE && bAsync)
|
|
||||||
window.detachEvent("onunload", fOnUnload);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
oRequest._object.send(null);
|
|
||||||
|
|
||||||
// Return now - wait untill re-sent request is finished
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
// BUGFIX: IE - memory leak in interrupted
|
// BUGFIX: IE - memory leak in interrupted
|
||||||
if (bIE && bAsync)
|
if (bIE && bAsync) {
|
||||||
window.detachEvent("onunload", fOnUnload);
|
window.detachEvent("onunload", fOnUnload);
|
||||||
|
}
|
||||||
|
|
||||||
|
// BUGFIX: Some browsers (Internet Explorer, Gecko) fire OPEN readystate twice
|
||||||
|
if (nState != oRequest.readyState) {
|
||||||
|
fReadyStateChange(oRequest);
|
||||||
|
}
|
||||||
|
|
||||||
|
nState = oRequest.readyState;
|
||||||
}
|
}
|
||||||
|
|
||||||
// BUGFIX: Some browsers (Internet Explorer, Gecko) fire OPEN readystate twice
|
|
||||||
if (nState != oRequest.readyState)
|
|
||||||
fReadyStateChange(oRequest);
|
|
||||||
|
|
||||||
nState = oRequest.readyState;
|
|
||||||
};
|
};
|
||||||
// Add method sniffer
|
|
||||||
if (cXMLHttpRequest.onopen)
|
|
||||||
cXMLHttpRequest.onopen.apply(this, arguments);
|
|
||||||
|
|
||||||
if (arguments.length > 4)
|
|
||||||
this._object.open(sMethod, sUrl, bAsync, sUser, sPassword);
|
|
||||||
else
|
|
||||||
if (arguments.length > 3)
|
|
||||||
this._object.open(sMethod, sUrl, bAsync, sUser);
|
|
||||||
else
|
|
||||||
this._object.open(sMethod, sUrl, bAsync);
|
|
||||||
|
|
||||||
// BUGFIX: Gecko - missing readystatechange calls in synchronous requests
|
|
||||||
if (!bAsync && bGecko) {
|
|
||||||
this.readyState = cXMLHttpRequest.OPENED;
|
|
||||||
|
|
||||||
fReadyStateChange(this);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
cXMLHttpRequest.prototype.send = function(vData) {
|
|
||||||
|
cXMLHttpRequest.prototype.send = function(vData) {
|
||||||
// Add method sniffer
|
// Add method sniffer
|
||||||
if (cXMLHttpRequest.onsend)
|
if (cXMLHttpRequest.onsend) {
|
||||||
cXMLHttpRequest.onsend.apply(this, arguments);
|
cXMLHttpRequest.onsend.apply(this, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!arguments.length) {
|
||||||
|
vData = null;
|
||||||
|
}
|
||||||
|
|
||||||
// BUGFIX: Safari - fails sending documents created/modified dynamically, so an explicit serialization required
|
// BUGFIX: Safari - fails sending documents created/modified dynamically, so an explicit serialization required
|
||||||
// BUGFIX: IE - rewrites any custom mime-type to "text/xml" in case an XMLNode is sent
|
// BUGFIX: IE - rewrites any custom mime-type to "text/xml" in case an XMLNode is sent
|
||||||
// BUGFIX: Gecko - fails sending Element (this is up to the implementation either to standard)
|
// BUGFIX: Gecko - fails sending Element (this is up to the implementation either to standard)
|
||||||
if (vData && vData.nodeType) {
|
if (vData && vData.nodeType) {
|
||||||
vData = window.XMLSerializer ? new window.XMLSerializer().serializeToString(vData) : vData.xml;
|
vData = window.XMLSerializer ? new window.XMLSerializer().serializeToString(vData) : vData.xml;
|
||||||
if (!this._headers["Content-Type"])
|
if (!this._headers["Content-Type"]) {
|
||||||
this._object.setRequestHeader("Content-Type", "application/xml");
|
this._object.setRequestHeader("Content-Type", "application/xml");
|
||||||
}
|
|
||||||
|
|
||||||
this._object.send(vData);
|
|
||||||
|
|
||||||
// BUGFIX: Gecko - missing readystatechange calls in synchronous requests
|
|
||||||
if (bGecko && !this._async) {
|
|
||||||
this.readyState = cXMLHttpRequest.OPENED;
|
|
||||||
|
|
||||||
// Synchronize state
|
|
||||||
fSynchronizeValues(this);
|
|
||||||
|
|
||||||
// Simulate missing states
|
|
||||||
while (this.readyState < cXMLHttpRequest.DONE) {
|
|
||||||
this.readyState++;
|
|
||||||
fReadyStateChange(this);
|
|
||||||
// Check if we are aborted
|
|
||||||
if (this._aborted)
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
cXMLHttpRequest.prototype.abort = function() {
|
|
||||||
// Add method sniffer
|
|
||||||
if (cXMLHttpRequest.onabort)
|
|
||||||
cXMLHttpRequest.onabort.apply(this, arguments);
|
|
||||||
|
|
||||||
// BUGFIX: Gecko - unneccesary DONE when aborting
|
this._data = vData;
|
||||||
if (this.readyState > cXMLHttpRequest.UNSENT)
|
|
||||||
this._aborted = true;
|
/**
|
||||||
|
* // Add to queue
|
||||||
|
* if (this._async) {
|
||||||
|
* fQueue_add(this);
|
||||||
|
* } else { */
|
||||||
|
fXMLHttpRequest_send(this);
|
||||||
|
/**
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
};
|
||||||
|
|
||||||
|
cXMLHttpRequest.prototype.abort = function() {
|
||||||
|
// Add method sniffer
|
||||||
|
if (cXMLHttpRequest.onabort) {
|
||||||
|
cXMLHttpRequest.onabort.apply(this, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
// BUGFIX: Gecko - unnecessary DONE when aborting
|
||||||
|
if (this.readyState > cXMLHttpRequest.UNSENT) {
|
||||||
|
this._aborted = true;
|
||||||
|
}
|
||||||
|
|
||||||
this._object.abort();
|
this._object.abort();
|
||||||
|
|
||||||
// BUGFIX: IE - memory leak
|
// BUGFIX: IE - memory leak
|
||||||
fCleanTransport(this);
|
fCleanTransport(this);
|
||||||
|
|
||||||
|
this.readyState = cXMLHttpRequest.UNSENT;
|
||||||
|
|
||||||
|
delete this._data;
|
||||||
|
|
||||||
|
/* if (this._async) {
|
||||||
|
* fQueue_remove(this);
|
||||||
|
* }
|
||||||
|
*/
|
||||||
};
|
};
|
||||||
cXMLHttpRequest.prototype.getAllResponseHeaders = function() {
|
|
||||||
|
cXMLHttpRequest.prototype.getAllResponseHeaders = function() {
|
||||||
return this._object.getAllResponseHeaders();
|
return this._object.getAllResponseHeaders();
|
||||||
};
|
};
|
||||||
cXMLHttpRequest.prototype.getResponseHeader = function(sName) {
|
|
||||||
|
cXMLHttpRequest.prototype.getResponseHeader = function(sName) {
|
||||||
return this._object.getResponseHeader(sName);
|
return this._object.getResponseHeader(sName);
|
||||||
};
|
};
|
||||||
cXMLHttpRequest.prototype.setRequestHeader = function(sName, sValue) {
|
|
||||||
|
cXMLHttpRequest.prototype.setRequestHeader = function(sName, sValue) {
|
||||||
// BUGFIX: IE - cache issue
|
// BUGFIX: IE - cache issue
|
||||||
if (!this._headers)
|
if (!this._headers) {
|
||||||
this._headers = {};
|
this._headers = {};
|
||||||
this._headers[sName] = sValue;
|
}
|
||||||
|
|
||||||
|
this._headers[sName] = sValue;
|
||||||
|
|
||||||
return this._object.setRequestHeader(sName, sValue);
|
return this._object.setRequestHeader(sName, sValue);
|
||||||
};
|
};
|
||||||
|
|
||||||
// EventTarget interface implementation
|
// EventTarget interface implementation
|
||||||
cXMLHttpRequest.prototype.addEventListener = function(sName, fHandler, bUseCapture) {
|
cXMLHttpRequest.prototype.addEventListener = function(sName, fHandler, bUseCapture) {
|
||||||
for (var nIndex = 0, oListener; oListener = this._listeners[nIndex]; nIndex++)
|
for (var nIndex = 0, oListener; oListener = this._listeners[nIndex]; nIndex++) {
|
||||||
if (oListener[0] == sName && oListener[1] == fHandler && oListener[2] == bUseCapture)
|
if (oListener[0] == sName && oListener[1] == fHandler && oListener[2] == bUseCapture) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Add listener
|
// Add listener
|
||||||
this._listeners.push([sName, fHandler, bUseCapture]);
|
this._listeners.push([sName, fHandler, bUseCapture]);
|
||||||
};
|
};
|
||||||
|
|
||||||
cXMLHttpRequest.prototype.removeEventListener = function(sName, fHandler, bUseCapture) {
|
cXMLHttpRequest.prototype.removeEventListener = function(sName, fHandler, bUseCapture) {
|
||||||
for (var nIndex = 0, oListener; oListener = this._listeners[nIndex]; nIndex++)
|
for (var nIndex = 0, oListener; oListener = this._listeners[nIndex]; nIndex++) {
|
||||||
if (oListener[0] == sName && oListener[1] == fHandler && oListener[2] == bUseCapture)
|
if (oListener[0] == sName && oListener[1] == fHandler && oListener[2] == bUseCapture) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Remove listener
|
// Remove listener
|
||||||
if (oListener)
|
if (oListener) {
|
||||||
this._listeners.splice(nIndex, 1);
|
this._listeners.splice(nIndex, 1);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
cXMLHttpRequest.prototype.dispatchEvent = function(oEvent) {
|
cXMLHttpRequest.prototype.dispatchEvent = function(oEvent) {
|
||||||
var oEvent = {
|
var oEventPseudo = {
|
||||||
'type': oEvent.type,
|
'type': oEvent.type,
|
||||||
'target': this,
|
'target': this,
|
||||||
'currentTarget':this,
|
'currentTarget': this,
|
||||||
'eventPhase': 2,
|
'eventPhase': 2,
|
||||||
'bubbles': oEvent.bubbles,
|
'bubbles': oEvent.bubbles,
|
||||||
'cancelable': oEvent.cancelable,
|
'cancelable': oEvent.cancelable,
|
||||||
'timeStamp': oEvent.timeStamp,
|
'timeStamp': oEvent.timeStamp,
|
||||||
'stopPropagation': function() {}, // There is no flow
|
'stopPropagation': function() {}, // There is no flow
|
||||||
'preventDefault': function() {}, // There is no default action
|
'preventDefault': function() {}, // There is no default action
|
||||||
'initEvent': function() {} // Original event object should be inited
|
'initEvent': function() {} // Original event object should be initialized
|
||||||
};
|
};
|
||||||
|
|
||||||
// Execute onreadystatechange
|
// Execute onreadystatechange
|
||||||
if (oEvent.type == "readystatechange" && this.onreadystatechange)
|
if (oEventPseudo.type == "readystatechange" && this.onreadystatechange) {
|
||||||
(this.onreadystatechange.handleEvent || this.onreadystatechange).apply(this, [oEvent]);
|
(this.onreadystatechange.handleEvent || this.onreadystatechange).apply(this, [oEventPseudo]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Execute listeners
|
// Execute listeners
|
||||||
for (var nIndex = 0, oListener; oListener = this._listeners[nIndex]; nIndex++)
|
for (var nIndex = 0, oListener; oListener = this._listeners[nIndex]; nIndex++) {
|
||||||
if (oListener[0] == oEvent.type && !oListener[2])
|
if (oListener[0] == oEventPseudo.type && !oListener[2]) {
|
||||||
(oListener[1].handleEvent || oListener[1]).apply(this, [oEvent]);
|
(oListener[1].handleEvent || oListener[1]).apply(this, [oEventPseudo]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
cXMLHttpRequest.prototype.toString = function() {
|
cXMLHttpRequest.prototype.toString = function() {
|
||||||
return '[' + "object" + ' ' + "XMLHttpRequest" + ']';
|
return '[' + "object" + ' ' + "XMLHttpRequest" + ']';
|
||||||
};
|
};
|
||||||
|
|
||||||
cXMLHttpRequest.toString = function() {
|
cXMLHttpRequest.toString = function() {
|
||||||
return '[' + "XMLHttpRequest" + ']';
|
return '[' + "XMLHttpRequest" + ']';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* // Queue manager
|
||||||
|
* var oQueuePending = {"CRITICAL":[],"HIGH":[],"NORMAL":[],"LOW":[],"LOWEST":[]},
|
||||||
|
* aQueueRunning = [];
|
||||||
|
* function fQueue_add(oRequest) {
|
||||||
|
* oQueuePending[oRequest.priority in oQueuePending ? oRequest.priority : "NORMAL"].push(oRequest);
|
||||||
|
* //
|
||||||
|
* setTimeout(fQueue_process);
|
||||||
|
* };
|
||||||
|
*
|
||||||
|
* function fQueue_remove(oRequest) {
|
||||||
|
* for (var nIndex = 0, bFound = false; nIndex < aQueueRunning.length; nIndex++)
|
||||||
|
* if (bFound) {
|
||||||
|
* aQueueRunning[nIndex - 1] = aQueueRunning[nIndex];
|
||||||
|
* } else {
|
||||||
|
* if (aQueueRunning[nIndex] == oRequest) {
|
||||||
|
* bFound = true;
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* if (bFound) {
|
||||||
|
* aQueueRunning.length--;
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* //
|
||||||
|
* setTimeout(fQueue_process);
|
||||||
|
* };
|
||||||
|
*
|
||||||
|
* function fQueue_process() {
|
||||||
|
* if (aQueueRunning.length < 6) {
|
||||||
|
* for (var sPriority in oQueuePending) {
|
||||||
|
* if (oQueuePending[sPriority].length) {
|
||||||
|
* var oRequest = oQueuePending[sPriority][0];
|
||||||
|
* oQueuePending[sPriority] = oQueuePending[sPriority].slice(1);
|
||||||
|
* //
|
||||||
|
* aQueueRunning.push(oRequest);
|
||||||
|
* // Send request
|
||||||
|
* fXMLHttpRequest_send(oRequest);
|
||||||
|
* break;
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* };
|
||||||
|
*/
|
||||||
|
|
||||||
// Helper function
|
// Helper function
|
||||||
|
function fXMLHttpRequest_send(oRequest) {
|
||||||
|
oRequest._object.send(oRequest._data);
|
||||||
|
|
||||||
|
// BUGFIX: Gecko - missing readystatechange calls in synchronous requests
|
||||||
|
if (bGecko && !oRequest._async) {
|
||||||
|
oRequest.readyState = cXMLHttpRequest.OPENED;
|
||||||
|
|
||||||
|
// Synchronize state
|
||||||
|
fSynchronizeValues(oRequest);
|
||||||
|
|
||||||
|
// Simulate missing states
|
||||||
|
while (oRequest.readyState < cXMLHttpRequest.DONE) {
|
||||||
|
oRequest.readyState++;
|
||||||
|
fReadyStateChange(oRequest);
|
||||||
|
// Check if we are aborted
|
||||||
|
if (oRequest._aborted) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function fReadyStateChange(oRequest) {
|
function fReadyStateChange(oRequest) {
|
||||||
// Sniffing code
|
// Sniffing code
|
||||||
if (cXMLHttpRequest.onreadystatechange)
|
if (cXMLHttpRequest.onreadystatechange){
|
||||||
cXMLHttpRequest.onreadystatechange.apply(oRequest);
|
cXMLHttpRequest.onreadystatechange.apply(oRequest);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Fake event
|
// Fake event
|
||||||
oRequest.dispatchEvent({
|
oRequest.dispatchEvent({
|
||||||
'type': "readystatechange",
|
'type': "readystatechange",
|
||||||
'bubbles': false,
|
'bubbles': false,
|
||||||
'cancelable': false,
|
'cancelable': false,
|
||||||
'timeStamp': new Date + 0
|
'timeStamp': new Date().getTime()
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
|
|
||||||
function fGetDocument(oRequest) {
|
function fGetDocument(oRequest) {
|
||||||
var oDocument = oRequest.responseXML;
|
var oDocument = oRequest.responseXML;
|
||||||
|
var sResponse = oRequest.responseText;
|
||||||
// Try parsing responseText
|
// Try parsing responseText
|
||||||
if (bIE && oDocument && !oDocument.documentElement && oRequest.getResponseHeader("Content-Type").match(/[^\/]+\/[^\+]+\+xml/)) {
|
if (bIE && sResponse && oDocument && !oDocument.documentElement && oRequest.getResponseHeader("Content-Type").match(/[^\/]+\/[^\+]+\+xml/)) {
|
||||||
oDocument = new window.ActiveXObject("Microsoft.XMLDOM");
|
oDocument = new window.ActiveXObject("Microsoft.XMLDOM");
|
||||||
oDocument.loadXML(oRequest.responseText);
|
oDocument.async = false;
|
||||||
|
oDocument.validateOnParse = false;
|
||||||
|
oDocument.loadXML(sResponse);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if there is no error in document
|
// Check if there is no error in document
|
||||||
if (oDocument)
|
if (oDocument){
|
||||||
if ((bIE && oDocument.parseError != 0) || !oDocument.documentElement || (oDocument.documentElement && oDocument.documentElement.tagName == "parsererror"))
|
if ((bIE && oDocument.parseError != 0) || !oDocument.documentElement || (oDocument.documentElement && oDocument.documentElement.tagName == "parsererror")) {
|
||||||
return null;
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
return oDocument;
|
return oDocument;
|
||||||
};
|
}
|
||||||
|
|
||||||
function fSynchronizeValues(oRequest) {
|
function fSynchronizeValues(oRequest) {
|
||||||
try { oRequest.responseText = oRequest._object.responseText; } catch (e) {}
|
try { oRequest.responseText = oRequest._object.responseText; } catch (e) {}
|
||||||
try { oRequest.responseXML = fGetDocument(oRequest._object); } catch (e) {}
|
try { oRequest.responseXML = fGetDocument(oRequest._object); } catch (e) {}
|
||||||
try { oRequest.status = oRequest._object.status; } catch (e) {}
|
try { oRequest.status = oRequest._object.status; } catch (e) {}
|
||||||
try { oRequest.statusText = oRequest._object.statusText; } catch (e) {}
|
try { oRequest.statusText = oRequest._object.statusText; } catch (e) {}
|
||||||
};
|
}
|
||||||
|
|
||||||
function fCleanTransport(oRequest) {
|
function fCleanTransport(oRequest) {
|
||||||
// BUGFIX: IE - memory leak (on-page leak)
|
// BUGFIX: IE - memory leak (on-page leak)
|
||||||
oRequest._object.onreadystatechange = new window.Function;
|
oRequest._object.onreadystatechange = new window.Function;
|
||||||
|
}
|
||||||
// Delete private properties
|
|
||||||
delete oRequest._headers;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Internet Explorer 5.0 (missing apply)
|
// Internet Explorer 5.0 (missing apply)
|
||||||
if (!window.Function.prototype.apply) {
|
if (!window.Function.prototype.apply) {
|
||||||
window.Function.prototype.apply = function(oRequest, oArguments) {
|
window.Function.prototype.apply = function(oRequest, oArguments) {
|
||||||
if (!oArguments)
|
if (!oArguments) {
|
||||||
oArguments = [];
|
oArguments = [];
|
||||||
oRequest.__func = this;
|
}
|
||||||
|
oRequest.__func = this;
|
||||||
oRequest.__func(oArguments[0], oArguments[1], oArguments[2], oArguments[3], oArguments[4]);
|
oRequest.__func(oArguments[0], oArguments[1], oArguments[2], oArguments[3], oArguments[4]);
|
||||||
delete oRequest.__func;
|
delete oRequest.__func;
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
// Register new object with window
|
// Register new object with window
|
||||||
window.XMLHttpRequest = cXMLHttpRequest;
|
window.XMLHttpRequest = cXMLHttpRequest;
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|
Loading…
Reference in New Issue