Adding cross-browser XMLHttpRequest functionality and convenience methods around it in the OpenLayers.Request namespace. Deprecating OpenLayers.Ajax.Request. Full support sync/async requests using all HTTP verbs now. r=elemoine (closes #1565)
git-svn-id: http://svn.openlayers.org/trunk/openlayers@7335 dc9f47b5-9b13-0410-9fdd-eb0c1a62fdaf
This commit is contained in:
+15
-7
@@ -4,13 +4,21 @@
|
||||
<script type="text/javascript">
|
||||
|
||||
function test_Ajax_loadUrl(t) {
|
||||
t.plan(1);
|
||||
var req = OpenLayers.Ajax.Request;
|
||||
OpenLayers.ProxyHost = "/?url=";
|
||||
OpenLayers.Ajax.Request.prototype.request = function(uri) {
|
||||
t.eq(uri, "/?url=http%3A%2F%2Fexample.com%2F%3Fformat%3Dimage%2Bkml", "URI matches what we expect from loadurl");
|
||||
}
|
||||
OpenLayers.loadURL("http://example.com/?format=image+kml");
|
||||
t.plan(5);
|
||||
var _get = OpenLayers.Request.GET;
|
||||
var caller = {};
|
||||
var onComplete = function() {};
|
||||
var onFailure = function() {};
|
||||
var params = {};
|
||||
OpenLayers.Request.GET = function(config) {
|
||||
t.eq(config.url, "http://example.com/?format=image+kml", "correct url")
|
||||
t.eq(config.params, params, "correct params");
|
||||
t.eq(config.scope, caller, "correct scope");
|
||||
t.ok(config.success === onComplete, "correct success callback");
|
||||
t.ok(config.failure === onFailure, "correct failure callback");
|
||||
};
|
||||
OpenLayers.loadURL("http://example.com/?format=image+kml", params, caller, onComplete, onFailure);
|
||||
OpenLayers.Request.GET = _get;
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
|
||||
@@ -0,0 +1,205 @@
|
||||
<html>
|
||||
<head>
|
||||
<script src="../lib/OpenLayers.js"></script>
|
||||
<script type="text/javascript">
|
||||
function setup() {
|
||||
window._xhr = OpenLayers.Request.XMLHttpRequest;
|
||||
var anon = new Function();
|
||||
OpenLayers.Request.XMLHttpRequest = function() {};
|
||||
OpenLayers.Request.XMLHttpRequest.prototype = {
|
||||
open: anon,
|
||||
setRequestHeader: anon,
|
||||
send: anon
|
||||
};
|
||||
OpenLayers.Request.XMLHttpRequest.DONE = 4;
|
||||
}
|
||||
function teardown() {
|
||||
OpenLayers.Request.XMLHttpRequest = window._xhr;
|
||||
delete window._xhr;
|
||||
}
|
||||
|
||||
function test_issue(t) {
|
||||
setup();
|
||||
|
||||
t.plan(18);
|
||||
var request, config;
|
||||
var proto = OpenLayers.Request.XMLHttpRequest.prototype;
|
||||
var issue = OpenLayers.Function.bind(OpenLayers.Request.issue,
|
||||
OpenLayers.Request);
|
||||
|
||||
// test that issue returns a new XMLHttpRequest - 1 test
|
||||
request = issue();
|
||||
t.ok(request instanceof OpenLayers.Request.XMLHttpRequest,
|
||||
"returns an XMLHttpRequest instance");
|
||||
|
||||
// test that issue calls xhr.open with correct args from config - 5 tests
|
||||
var _open = proto.open;
|
||||
config = {
|
||||
method: "foo",
|
||||
url: "http://nowhere",
|
||||
async: "bar",
|
||||
user: "uncle",
|
||||
password: "sam"
|
||||
};
|
||||
proto.open = function(method, url, async, user, password) {
|
||||
t.eq(method, config.method, "open called with correct method");
|
||||
t.eq(url, config.url, "open called with correct url");
|
||||
t.eq(async, config.async, "open called with correct async");
|
||||
t.eq(user, config.user, "open called with correct user");
|
||||
t.eq(password, config.password, "open called with correct password");
|
||||
}
|
||||
request = issue(config);
|
||||
proto.open = _open;
|
||||
|
||||
// test that headers are correctly set - 4 tests
|
||||
var _setRequestHeader = proto.setRequestHeader;
|
||||
config = {
|
||||
headers: {
|
||||
foo: "bar",
|
||||
chicken: "soup"
|
||||
}
|
||||
};
|
||||
proto.setRequestHeader = function(key, value) {
|
||||
t.ok(key in config.headers, "setRequestHeader called with key: " + key);
|
||||
t.eq(value, config.headers[key], "setRequestHeader called with correct value: " + value);
|
||||
}
|
||||
request = issue(config);
|
||||
proto.setRequestHeader = _setRequestHeader;
|
||||
|
||||
// test that callback is called (no scope) - 1 test
|
||||
var unbound = function(request) {
|
||||
t.ok(request instanceof OpenLayers.Request.XMLHttpRequest,
|
||||
"unbound callback called with xhr instance");
|
||||
}
|
||||
config = {
|
||||
callback: unbound
|
||||
};
|
||||
request = issue(config);
|
||||
request.readyState = OpenLayers.Request.XMLHttpRequest.DONE;
|
||||
request.onreadystatechange();
|
||||
|
||||
// test that callback is called (with scope) - 2 tests
|
||||
var obj = {};
|
||||
var bound = function(request) {
|
||||
t.ok(this === obj, "bound callback has correct scope");
|
||||
t.ok(request instanceof OpenLayers.Request.XMLHttpRequest,
|
||||
"bound callback called with xhr instance");
|
||||
}
|
||||
config = {
|
||||
callback: bound,
|
||||
scope: obj
|
||||
};
|
||||
request = issue(config);
|
||||
request.readyState = 4;
|
||||
request.onreadystatechange();
|
||||
|
||||
// test that send is called with data - 1 test
|
||||
var _send = proto.send;
|
||||
config = {
|
||||
method: "PUT",
|
||||
data: "bling"
|
||||
};
|
||||
proto.send = function(data) {
|
||||
t.eq(data, config.data, "send called with correct data");
|
||||
}
|
||||
request = issue(config);
|
||||
proto.send = _send;
|
||||
|
||||
// test that optional success callback is only called with 200s and
|
||||
// failure is only called with non-200s
|
||||
var _send = proto.send;
|
||||
proto.send = function() {};
|
||||
|
||||
config = {
|
||||
success: function(req) {
|
||||
t.ok(req.status >= 200 && req.status < 300,
|
||||
"success callback called with " + req.status + " status");
|
||||
},
|
||||
failure: function(req) {
|
||||
t.ok(req.status < 200 || req.status >= 300,
|
||||
"failure callback called with " + req.status + " status");
|
||||
}
|
||||
};
|
||||
request = issue(config);
|
||||
request.readyState = 4;
|
||||
|
||||
// mock up status 200 (1 test)
|
||||
request.status = 200;
|
||||
request.onreadystatechange();
|
||||
|
||||
// mock up status 299 (1 test)
|
||||
request.status = 299;
|
||||
request.onreadystatechange();
|
||||
|
||||
// mock up status 100 (1 test)
|
||||
request.status = 100;
|
||||
request.onreadystatechange();
|
||||
|
||||
// mock up status 300 (1 test)
|
||||
request.status = 300;
|
||||
request.onreadystatechange();
|
||||
|
||||
proto.send = _send;
|
||||
|
||||
teardown();
|
||||
}
|
||||
|
||||
function test_GET(t) {
|
||||
t.plan(1);
|
||||
var _issue = OpenLayers.Request.issue;
|
||||
OpenLayers.Request.issue = function(config) {
|
||||
t.eq(config.method, "GET", "calls issue with correct method");
|
||||
}
|
||||
OpenLayers.Request.GET();
|
||||
OpenLayers.Request.issue = _issue;
|
||||
}
|
||||
function test_POST(t) {
|
||||
t.plan(1);
|
||||
var _issue = OpenLayers.Request.issue;
|
||||
OpenLayers.Request.issue = function(config) {
|
||||
t.eq(config.method, "POST", "calls issue with correct method");
|
||||
}
|
||||
OpenLayers.Request.POST();
|
||||
OpenLayers.Request.issue = _issue;
|
||||
}
|
||||
function test_PUT(t) {
|
||||
t.plan(1);
|
||||
var _issue = OpenLayers.Request.issue;
|
||||
OpenLayers.Request.issue = function(config) {
|
||||
t.eq(config.method, "PUT", "calls issue with correct method");
|
||||
}
|
||||
OpenLayers.Request.PUT();
|
||||
OpenLayers.Request.issue = _issue;
|
||||
}
|
||||
function test_DELETE(t) {
|
||||
t.plan(1);
|
||||
var _issue = OpenLayers.Request.issue;
|
||||
OpenLayers.Request.issue = function(config) {
|
||||
t.eq(config.method, "DELETE", "calls issue with correct method");
|
||||
}
|
||||
OpenLayers.Request.DELETE();
|
||||
OpenLayers.Request.issue = _issue;
|
||||
}
|
||||
function test_HEAD(t) {
|
||||
t.plan(1);
|
||||
var _issue = OpenLayers.Request.issue;
|
||||
OpenLayers.Request.issue = function(config) {
|
||||
t.eq(config.method, "HEAD", "calls issue with correct method");
|
||||
}
|
||||
OpenLayers.Request.HEAD();
|
||||
OpenLayers.Request.issue = _issue;
|
||||
}
|
||||
function test_OPTIONS(t) {
|
||||
t.plan(1);
|
||||
var _issue = OpenLayers.Request.issue;
|
||||
OpenLayers.Request.issue = function(config) {
|
||||
t.eq(config.method, "OPTIONS", "calls issue with correct method");
|
||||
}
|
||||
OpenLayers.Request.OPTIONS();
|
||||
OpenLayers.Request.issue = _issue;
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,14 @@
|
||||
<html>
|
||||
<head>
|
||||
<script src="../../lib/OpenLayers.js"></script>
|
||||
<script type="text/javascript">
|
||||
function test_constructor(t) {
|
||||
t.plan(1);
|
||||
t.ok(new OpenLayers.Request.XMLHttpRequest(),
|
||||
"constructor didn't fail and we trust the code is well tested in OpenLayers.Request methods");
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
+8
-8
@@ -64,12 +64,12 @@
|
||||
|
||||
var g_Success = {};
|
||||
|
||||
var tLoadURL = OpenLayers.loadURL;
|
||||
OpenLayers.loadURL = function(url, params, caller, onComplete) {
|
||||
t.ok(url == tile.url, "tile's url correctly passed as 1st param to loadURL");
|
||||
t.ok(params == null, "null passed as 2nd param to loadURL");
|
||||
t.ok(caller == tile, "tile passed as 3rd param to loadURL");
|
||||
t.ok(onComplete == g_Success, "success param from loadFeaturesForRegion() passed as 4th param to loadURL");
|
||||
var _get = OpenLayers.Request.GET;
|
||||
OpenLayers.Request.GET = function(config) {
|
||||
t.ok(config.url == tile.url, "tile's url correctly passed");
|
||||
t.ok(config.params == null, "null params");
|
||||
t.ok(config.scope == tile, "tile passed as scope");
|
||||
t.ok(config.success == g_Success, "success passed");
|
||||
};
|
||||
|
||||
//no running request -- 4 tests
|
||||
@@ -82,8 +82,8 @@
|
||||
}
|
||||
};
|
||||
OpenLayers.Tile.WFS.prototype.loadFeaturesForRegion.apply(tile, [g_Success]);
|
||||
|
||||
OpenLayers.loadURL = tLoadURL;
|
||||
|
||||
OpenLayers.Request.GET = _get;
|
||||
}
|
||||
|
||||
function test_Tile_WFS_destroy(t) {
|
||||
|
||||
@@ -57,6 +57,8 @@
|
||||
<li>Lang.html</li>
|
||||
<li>Layer.html</li>
|
||||
<li>Renderer.html</li>
|
||||
<li>Request.html</li>
|
||||
<li>Request/XMLHttpRequest.html</li>
|
||||
<li>Layer/EventPane.html</li>
|
||||
<li>Layer/FixedZoomLevels.html</li>
|
||||
<li>Layer/GeoRSS.html</li>
|
||||
|
||||
+22
-43
@@ -1,70 +1,49 @@
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>Ajax Acceptance Test</title>
|
||||
<style type="text/css">
|
||||
|
||||
body {
|
||||
font-size: 0.8em;
|
||||
}
|
||||
p {
|
||||
padding-top: 1em;
|
||||
}
|
||||
|
||||
.buttons {
|
||||
margin: 1em;
|
||||
float: left;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<title>XHR Acceptance Test</title>
|
||||
<script src="../../lib/OpenLayers.js"></script>
|
||||
<script type="text/javascript">
|
||||
var url = "ajax.txt";
|
||||
function sendSynchronous(){
|
||||
var request = new OpenLayers.Ajax.Request(url, {
|
||||
'asynchronous': false,
|
||||
onComplete: function() {
|
||||
var request = OpenLayers.Request.GET({
|
||||
url: url,
|
||||
async: false,
|
||||
callback: function() {
|
||||
document.getElementById('send_sync').value += 'request completed\n';
|
||||
}
|
||||
});
|
||||
document.getElementById('send_sync').value += 'other processing\n';
|
||||
}
|
||||
function sendAsynchronous(){
|
||||
var request = new OpenLayers.Ajax.Request(url, {
|
||||
onComplete: function() {
|
||||
var request = OpenLayers.Request.GET({
|
||||
url: url,
|
||||
callback: function() {
|
||||
document.getElementById('send_sync').value += 'request completed\n';
|
||||
}
|
||||
});
|
||||
document.getElementById('send_sync').value += 'other processing\n';
|
||||
}
|
||||
function sendAndAbort(){
|
||||
var request = new OpenLayers.Ajax.Request(url, {
|
||||
onComplete: function(request) {
|
||||
if (request.responseText == '') {
|
||||
document.getElementById('send_sync').value += 'request aborted\n';
|
||||
}
|
||||
var request = OpenLayers.Request.GET({
|
||||
url: url,
|
||||
callback: function() {
|
||||
document.getElementById('send_sync').value += 'never called\n';
|
||||
}
|
||||
});
|
||||
request.transport.abort();
|
||||
request.abort();
|
||||
document.getElementById('send_sync').value += 'other processing\n';
|
||||
}
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body >
|
||||
<div class="buttons">
|
||||
<button onclick="sendSynchronous()">Send an synchronous Ajax request</button><br />
|
||||
<button onclick="sendAsynchronous()">Send an asynchronous Ajax request</button><br />
|
||||
<button onclick="sendAndAbort()">Send a request and abort it</button><br />
|
||||
</script>
|
||||
</head>
|
||||
<body >
|
||||
<button onclick="sendSynchronous()">synchronous</button>
|
||||
expected output: "request completed" then "other processing"<br />
|
||||
<button onclick="sendAsynchronous()">asynchronous</button>
|
||||
expected output: "other processing" then "request completed"<br />
|
||||
<button onclick="sendAndAbort()">send and abort</button>
|
||||
expected output: "other processing" (and not "never called")<br />
|
||||
<textarea id="send_sync" rows="6"></textarea><br />
|
||||
<button onclick="document.getElementById('send_sync').value = ''">Clear</button>
|
||||
</div>
|
||||
<p><b></b></p>
|
||||
<p>Clicking on the different buttons should give the following results in the textarea below :</p>
|
||||
<ul>
|
||||
<li>synchronous: "request completed" then "other processing"</li>
|
||||
<li>asynchronous: "other processing" then "request completed"</li>
|
||||
<li>abort: "request aborted" then "other processing" (note that real XHR behavior would not call onComplete with abort - meaning "request aborted" would not be displayed here)</li>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user