[OpenLayers-Commits] r11691 - in trunk/openlayers: examples lib
lib/OpenLayers/Protocol tests tests/Protocol
commits-20090109 at openlayers.org
commits-20090109 at openlayers.org
Thu Mar 10 15:51:09 EST 2011
Author: tschaub
Date: 2011-03-10 12:51:03 -0800 (Thu, 10 Mar 2011)
New Revision: 11691
Added:
trunk/openlayers/examples/cross-origin.html
trunk/openlayers/examples/cross-origin.js
trunk/openlayers/lib/OpenLayers/Protocol/Script.js
trunk/openlayers/tests/Protocol/Script.html
Modified:
trunk/openlayers/lib/OpenLayers.js
trunk/openlayers/tests/list-tests.html
Log:
Adding a protocol for reading features cross-origin from services that support JSON with a callback. r=erilem (closes #2956)
Added: trunk/openlayers/examples/cross-origin.html
===================================================================
--- trunk/openlayers/examples/cross-origin.html (rev 0)
+++ trunk/openlayers/examples/cross-origin.html 2011-03-10 20:51:03 UTC (rev 11691)
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>OpenLayers Script Protocol Example</title>
+ <link rel="stylesheet" href="../theme/default/style.css" type="text/css">
+ <link rel="stylesheet" href="style.css" type="text/css">
+ <meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;" />
+ <meta name="apple-mobile-web-app-capable" content="yes" />
+ <script src="../lib/OpenLayers.js"></script>
+ </head>
+ <body>
+ <h1 id="title">Script Protocol</h1>
+ <div id="tags">
+ protocol, script, cross origin, advanced
+ </div>
+ <p id="shortdesc">
+ Demonstrates the use of a script protocol for making feature requests
+ cross origin.
+ </p>
+ <div id="map" class="smallmap"></div>
+ <div id="docs">
+ <p>
+ In cases where a service returns serialized features and accepts
+ a named callback (e.g. http://example.com/features.json?callback=foo),
+ the script protocol can be used to read features without being
+ restricted by the same origin policy.
+ </p>
+ <p>
+ View the <a href="cross-origin.js" target="_blank">cross-origin.js</a>
+ source to see how this is done
+ </p>
+ </div>
+ <script src="cross-origin.js"></script>
+ </body>
+</html>
Added: trunk/openlayers/examples/cross-origin.js
===================================================================
--- trunk/openlayers/examples/cross-origin.js (rev 0)
+++ trunk/openlayers/examples/cross-origin.js 2011-03-10 20:51:03 UTC (rev 11691)
@@ -0,0 +1,39 @@
+var map = new OpenLayers.Map({
+ div: "map",
+ layers: [
+ new OpenLayers.Layer.WMS(
+ "World Map",
+ "http://maps.opengeo.org/geowebcache/service/wms",
+ {layers: "bluemarble"}
+ ),
+ new OpenLayers.Layer.Vector("States", {
+ strategies: [new OpenLayers.Strategy.BBOX()],
+ protocol: new OpenLayers.Protocol.Script({
+ url: "http://suite.opengeo.org/geoserver/wfs",
+ callbackKey: "format_options",
+ callbackPrefix: "callback:",
+ params: {
+ service: "WFS",
+ version: "1.1.0",
+ srsName: "EPSG:4326",
+ request: "GetFeature",
+ typeName: "world:cities",
+ outputFormat: "json"
+ },
+ filterToParams: function(filter, params) {
+ // example to demonstrate BBOX serialization
+ if (filter.type === OpenLayers.Filter.Spatial.BBOX) {
+ params.bbox = filter.value.toArray();
+ if (filter.projection) {
+ params.bbox.push(filter.projection.getCode());
+ }
+ }
+ return params;
+ }
+ })
+ })
+ ],
+ center: new OpenLayers.LonLat(0, 0),
+ zoom: 1
+});
+
Added: trunk/openlayers/lib/OpenLayers/Protocol/Script.js
===================================================================
--- trunk/openlayers/lib/OpenLayers/Protocol/Script.js (rev 0)
+++ trunk/openlayers/lib/OpenLayers/Protocol/Script.js 2011-03-10 20:51:03 UTC (rev 11691)
@@ -0,0 +1,363 @@
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+ * full text of the license. */
+
+/**
+ * @requires OpenLayers/Protocol.js
+ * @requires OpenLayers/Feature/Vector.js
+ * @requires OpenLayers/Format/GeoJSON.js
+ */
+
+/**
+ * Class: OpenLayers.Protocol.Script
+ * A basic Script protocol for vector layers. Create a new instance with the
+ * <OpenLayers.Protocol.Script> constructor. A script protocol is used to
+ * get around the same origin policy. It works with services that return
+ * JSONP - that is, JSON wrapped in a client-specified callback. The
+ * protocol handles fetching and parsing of feature data and sends parsed
+ * features to the <callback> configured with the protocol. The protocol
+ * expects features serialized as GeoJSON by default, but can be configured
+ * to work with other formats by setting the <format> property.
+ *
+ * Inherits from:
+ * - <OpenLayers.Protocol>
+ */
+OpenLayers.Protocol.Script = OpenLayers.Class(OpenLayers.Protocol, {
+
+ /**
+ * APIProperty: url
+ * {String} Service URL. The service is expected to return serialized
+ * features wrapped in a named callback (where the callback name is
+ * generated by this protocol).
+ * Read-only, set through the options passed to the constructor.
+ */
+ url: null,
+
+ /**
+ * APIProperty: params
+ * {Object} Query string parameters to be appended to the URL.
+ * Read-only, set through the options passed to the constructor.
+ * Example: {maxFeatures: 50}
+ */
+ params: null,
+
+ /**
+ * APIProperty: callback
+ * {Object} Function to be called when the <read> operation completes.
+ */
+ callback: null,
+
+ /**
+ * APIProperty: scope
+ * {Object} Optional ``this`` object for the callback. Read-only, set
+ * through the options passed to the constructor.
+ */
+ scope: null,
+
+ /**
+ * APIProperty: format
+ * {<OpenLayers.Format>} Format for parsing features. Default is an
+ * <OpenLayers.Format.GeoJSON> format. If an alternative is provided,
+ * the format's read method must take an object and return an array
+ * of features.
+ */
+ format: null,
+
+ /**
+ * APIProperty: callbackKey
+ * {String} The name of the query string parameter that the service
+ * recognizes as the callback identifier. Default is "callback".
+ * This key is used to generate the URL for the script. For example
+ * setting <callbackKey> to "myCallback" would result in a URL like
+ * http://example.com/?myCallback=...
+ */
+ callbackKey: "callback",
+
+ /**
+ * APIProperty: callbackPrefix
+ * {String} Where a service requires that the callback query string
+ * parameter value is prefixed by some string, this value may be set.
+ * For example, setting <callbackPrefix> to "foo:" would result in a
+ * URL like http://example.com/?callback=foo:... Default is "".
+ */
+ callbackPrefix: "",
+
+ /**
+ * Property: pendingRequests
+ * {Object} References all pending requests. Property names are script
+ * identifiers and property values are script elements.
+ */
+ pendingRequests: null,
+
+ /**
+ * Constructor: OpenLayers.Protocol.Script
+ * A class for giving layers generic Script protocol.
+ *
+ * Parameters:
+ * options - {Object} Optional object whose properties will be set on the
+ * instance.
+ *
+ * Valid options include:
+ * url - {String}
+ * params - {Object}
+ * callback - {Function}
+ * scope - {Object}
+ */
+ initialize: function(options) {
+ options = options || {};
+ this.params = {};
+ this.pendingRequests = {};
+ OpenLayers.Protocol.prototype.initialize.apply(this, arguments);
+ if (!this.format) {
+ this.format = new OpenLayers.Format.GeoJSON();
+ }
+
+ if (!this.filterToParams && OpenLayers.Protocol.simpleFilterSerializer) {
+ this.filterToParams = OpenLayers.Function.bind(
+ OpenLayers.Protocol.simpleFilterSerializer, this
+ );
+ }
+ },
+
+ /**
+ * APIMethod: read
+ * Construct a request for reading new features.
+ *
+ * Parameters:
+ * options - {Object} Optional object for configuring the request.
+ * This object is modified and should not be reused.
+ *
+ * Valid options:
+ * url - {String} Url for the request.
+ * params - {Object} Parameters to get serialized as a query string.
+ * filter - {<OpenLayers.Filter>} Filter to get serialized as a
+ * query string.
+ *
+ * Returns:
+ * {<OpenLayers.Protocol.Response>} A response object, whose "priv" property
+ * references the injected script. This object is also passed to the
+ * callback function when the request completes, its "features" property
+ * is then populated with the features received from the server.
+ */
+ read: function(options) {
+ OpenLayers.Protocol.prototype.read.apply(this, arguments);
+ options = OpenLayers.Util.applyDefaults(options, this.options);
+ options.params = OpenLayers.Util.applyDefaults(
+ options.params, this.options.params
+ );
+ if (options.filter && this.filterToParams) {
+ options.params = this.filterToParams(
+ options.filter, options.params
+ );
+ }
+ var response = new OpenLayers.Protocol.Response({requestType: "read"});
+ var request = this.createRequest(
+ options.url,
+ options.params,
+ OpenLayers.Function.bind(function(data) {
+ response.data = data;
+ this.handleRead(response, options);
+ }, this)
+ );
+ response.priv = request;
+ return response;
+ },
+
+ /**
+ * APIMethod: filterToParams
+ * Optional method to translate an <OpenLayers.Filter> object into an object
+ * that can be serialized as request query string provided. If a custom
+ * method is not provided, any filter will not be serialized.
+ *
+ * Parameters:
+ * filter - {<OpenLayers.Filter>} filter to convert.
+ * params - {Object} The parameters object.
+ *
+ * Returns:
+ * {Object} The resulting parameters object.
+ */
+
+ /**
+ * Method: createRequest
+ * Issues a request for features by creating injecting a script in the
+ * document head.
+ *
+ * Parameters:
+ * url - {String} Service URL.
+ * params - {Object} Query string parameters.
+ * callback - {Function} Callback to be called with resulting data.
+ *
+ * Returns:
+ * {HTMLScriptElement} The script pending execution.
+ */
+ createRequest: function(url, params, callback) {
+ var id = OpenLayers.Protocol.Script.register(callback);
+ var name = "OpenLayers.Protocol.Script.getCallback(" + id + ")";
+ params = OpenLayers.Util.extend({}, params);
+ params[this.callbackKey] = this.callbackPrefix + name;
+ url = OpenLayers.Util.urlAppend(
+ url, OpenLayers.Util.getParameterString(params)
+ );
+ var script = document.createElement("script");
+ script.type = "text/javascript";
+ script.src = url;
+ script.id = "OpenLayers_Protocol_Script_" + id;
+ this.pendingRequests[script.id] = script;
+ var head = document.getElementsByTagName("head")[0];
+ head.appendChild(script);
+ return script;
+ },
+
+ /**
+ * Method: destroyRequest
+ * Remove a script node associated with a response from the document. Also
+ * unregisters the callback and removes the script from the
+ * <pendingRequests> object.
+ *
+ * Parameters:
+ * script - {HTMLScriptElement}
+ */
+ destroyRequest: function(script) {
+ OpenLayers.Protocol.Script.unregister(script.id.split("_").pop());
+ delete this.pendingRequests[script.id];
+ if (script.parentNode) {
+ script.parentNode.removeChild(script);
+ }
+ },
+
+ /**
+ * Method: handleRead
+ * Individual callbacks are created for read, create and update, should
+ * a subclass need to override each one separately.
+ *
+ * Parameters:
+ * response - {<OpenLayers.Protocol.Response>} The response object to pass to
+ * the user callback.
+ * options - {Object} The user options passed to the read call.
+ */
+ handleRead: function(response, options) {
+ this.handleResponse(response, options);
+ },
+
+ /**
+ * Method: handleResponse
+ * Called by CRUD specific handlers.
+ *
+ * Parameters:
+ * response - {<OpenLayers.Protocol.Response>} The response object to pass to
+ * any user callback.
+ * options - {Object} The user options passed to the create, read, update,
+ * or delete call.
+ */
+ handleResponse: function(response, options) {
+ if (options.callback) {
+ if (response.data) {
+ response.features = this.parseFeatures(response.data);
+ response.code = OpenLayers.Protocol.Response.SUCCESS;
+ } else {
+ response.code = OpenLayers.Protocol.Response.FAILURE;
+ }
+ this.destroyRequest(response.priv);
+ options.callback.call(options.scope, response);
+ }
+ },
+
+ /**
+ * Method: parseFeatures
+ * Read Script response body and return features.
+ *
+ * Parameters:
+ * data - {Object} The data sent to the callback function by the server.
+ *
+ * Returns:
+ * {Array({<OpenLayers.Feature.Vector>})} or
+ * {<OpenLayers.Feature.Vector>} Array of features or a single feature.
+ */
+ parseFeatures: function(data) {
+ return this.format.read(data);
+ },
+
+ /**
+ * APIMethod: abort
+ * Abort an ongoing request. If no response is provided, all pending
+ * requests will be aborted.
+ *
+ * Parameters:
+ * response - {<OpenLayers.Protocol.Response>} The response object returned
+ * from a <read> request.
+ */
+ abort: function(response) {
+ if (response) {
+ this.destroyRequest(response.priv);
+ } else {
+ for (var key in this.pendingRequests) {
+ this.destroyRequest(this.pendingRequests[key]);
+ }
+ }
+ },
+
+ /**
+ * APIMethod: destroy
+ * Clean up the protocol.
+ */
+ destroy: function() {
+ this.abort();
+ delete this.params;
+ delete this.format;
+ OpenLayers.Protocol.prototype.destroy.apply(this);
+ },
+
+ CLASS_NAME: "OpenLayers.Protocol.Script"
+});
+
+(function() {
+ var o = OpenLayers.Protocol.Script;
+ var counter = 0;
+ var registry = {};
+
+ /**
+ * Function: OpenLayers.Protocol.Script.register
+ * Register a callback for a newly created script.
+ *
+ * Parameters:
+ * callback: {Function} The callback to be executed when the newly added
+ * script loads. This callback will be called with a single argument
+ * that is the JSON returned by the service.
+ *
+ * Returns:
+ * {Number} An identifier for retreiving the registered callback.
+ */
+ o.register = function(callback) {
+ var id = ++counter;
+ registry[id] = callback;
+ return id;
+ };
+
+ /**
+ * Function: OpenLayers.Protocol.Script.unregister
+ * Unregister a callback previously registered with the register function.
+ *
+ * Parameters:
+ * id: {Number} The identifer returned by the register function.
+ */
+ o.unregister = function(id) {
+ delete registry[id];
+ };
+
+ /**
+ * Function: OpenLayers.Protocol.Script.getCallback
+ * Retreive and unregister a callback. A call to this function is the "P"
+ * in JSONP. For example, a script may be added with a src attribute
+ * http://example.com/features.json?callback=OpenLayers.Protocol.Script.getCallback(1)
+ *
+ * Parameters:
+ * id: {Number} The identifer returned by the register function.
+ */
+ o.getCallback = function(id) {
+ var callback = registry[id];
+ o.unregister(id);
+ return callback;
+ };
+})();
+
Modified: trunk/openlayers/lib/OpenLayers.js
===================================================================
--- trunk/openlayers/lib/OpenLayers.js 2011-03-10 20:14:49 UTC (rev 11690)
+++ trunk/openlayers/lib/OpenLayers.js 2011-03-10 20:51:03 UTC (rev 11691)
@@ -252,6 +252,7 @@
"OpenLayers/Protocol/WFS/v1.js",
"OpenLayers/Protocol/WFS/v1_0_0.js",
"OpenLayers/Protocol/WFS/v1_1_0.js",
+ "OpenLayers/Protocol/Script.js",
"OpenLayers/Protocol/SOS.js",
"OpenLayers/Protocol/SOS/v1_0_0.js",
"OpenLayers/Layer/PointTrack.js",
Added: trunk/openlayers/tests/Protocol/Script.html
===================================================================
--- trunk/openlayers/tests/Protocol/Script.html (rev 0)
+++ trunk/openlayers/tests/Protocol/Script.html 2011-03-10 20:51:03 UTC (rev 11691)
@@ -0,0 +1,271 @@
+<html>
+<head>
+ <script src="../../lib/OpenLayers.js"></script>
+ <script type="text/javascript">
+
+ function test_constructor(t) {
+ t.plan(11);
+ var a = new OpenLayers.Protocol.Script({
+ url: "foo"
+ });
+
+ // 7 tests
+ t.eq(a.url, "foo", "constructor sets url");
+ t.eq(a.options.url, a.url, "constructor copies url to options.url");
+ t.eq(a.params, {}, "constructor sets params");
+ t.eq(a.options.params, undefined, "constructor does not copy params to options.params");
+ t.ok(a.format instanceof OpenLayers.Format.GeoJSON,
+ "constructor sets a GeoJSON format by default");
+ t.eq(a.callbackKey, 'callback',
+ "callbackKey is set to 'callback' by default");
+ t.eq(a.callbackPrefix, '',
+ "callbackPrefix is set to '' by default");
+
+ var params = {hello: "world"};
+ var b = new OpenLayers.Protocol.Script({
+ url: "bar",
+ params: params,
+ callbackKey: 'cb_key',
+ callbackPrefix: 'cb_prefix'
+ });
+
+ // 6 tests
+ t.eq(b.params, params, "constructor sets params");
+ t.eq(b.options.params, b.params, "constructor copies params to options.params");
+ t.eq(b.callbackKey, 'cb_key',
+ "callbackKey is set to 'cb_key'");
+ t.eq(b.callbackPrefix, 'cb_prefix',
+ "callbackPrefix is set to 'cb_prefix'");
+ }
+
+ function test_destroy(t) {
+ t.plan(3);
+ var aborted = false;
+ var protocol = new OpenLayers.Protocol.Script({
+ url: "bar",
+ params: {hello: "world"},
+ abort: function() {
+ aborted = true;
+ }
+ });
+ protocol.destroy();
+ t.ok(aborted, "destroy aborts request");
+ t.eq(protocol.params, null, "destroy nullifies params");
+ t.eq(protocol.format, null, "destroy nullifies format");
+ }
+
+ function test_read(t) {
+ t.plan(5);
+ var protocol = new OpenLayers.Protocol.Script({
+ 'url': 'foo_url',
+ 'params': {'k': 'foo_param'}
+ });
+
+ // fake XHR request object
+ var request = {'status': 200};
+
+ // options to pass to read
+ var readOptions = {
+ 'url': 'bar_url',
+ 'params': {'k': 'bar_param'}
+ };
+
+ var response;
+
+ protocol.createRequest = function(url, params, callback) {
+ // 4 tests
+ t.ok(this == protocol,
+ 'createRequest called with correct scope');
+ t.ok(url == readOptions.url,
+ 'createRequest called with correct url');
+ t.ok(params == readOptions.params,
+ 'createRequest called with correct params');
+ t.ok(callback instanceof Function,
+ 'createRequest called with a function as callback');
+
+ return 'foo_request';
+ };
+
+ var resp = protocol.read(readOptions);
+
+ t.eq(resp.priv, 'foo_request',
+ 'response priv property set to what the createRequest method returns');
+ }
+
+ function test_read_bbox(t) {
+ t.plan(6);
+
+ var _createRequest = OpenLayers.Protocol.Script.prototype.createRequest;
+
+ var bounds = new OpenLayers.Bounds(1, 2, 3, 4);
+ var filter = new OpenLayers.Filter.Spatial({
+ type: OpenLayers.Filter.Spatial.BBOX,
+ value: bounds,
+ projection: new OpenLayers.Projection("foo")
+ });
+
+ // log requests
+ var log, exp;
+ OpenLayers.Protocol.Script.prototype.createRequest = function(url, params,
+ callback) {
+ log.push(params.bbox);
+ return null;
+ };
+
+ // 1) issue request with default protocol
+ log = [];
+ new OpenLayers.Protocol.Script().read({filter: filter});
+
+ t.eq(log.length, 1, "1) createRequest called once");
+ t.ok(log[0] instanceof Array, "1) bbox param is array");
+ exp = bounds.toArray();
+ t.eq(log[0], exp, "1) bbox param doesn't include SRS id by default");
+
+ // 2) issue request with default protocol
+ log = [];
+ new OpenLayers.Protocol.Script({srsInBBOX: true}).read({filter: filter});
+
+ t.eq(log.length, 1, "2) createRequest called once");
+ t.ok(log[0] instanceof Array, "2) bbox param is array");
+ exp = bounds.toArray();
+ exp.push("foo");
+ t.eq(log[0], exp, "2) bbox param includes SRS id if srsInBBOX is true");
+
+ OpenLayers.Protocol.Script.prototype.createRequest = _createRequest;
+ }
+
+ function test_createRequest(t) {
+ t.plan(3);
+ var protocol = new OpenLayers.Protocol.Script({
+ callbackKey: 'cb_key',
+ callbackPrefix: 'cb_prefix:'
+ });
+
+ var _register = OpenLayers.Protocol.Script.register;
+ OpenLayers.Protocol.Script.register = function() {
+ return 'bar';
+ };
+
+ var script = protocol.createRequest('http://bar_url/', {'k': 'bar_param'}, 'bar_callback');
+
+ t.eq(script.type, 'text/javascript',
+ 'created script has a correct type');
+ t.eq(script.src, 'http://bar_url/?k=bar_param&cb_key=cb_prefix%3AOpenLayers.Protocol.Script.getCallback(bar)',
+ 'created script has a correct url');
+ t.eq(script.id, 'OpenLayers_Protocol_Script_bar',
+ 'created script has a correct id');
+
+ OpenLayers.Protocol.Script.register = _register;
+ }
+
+ function test_destroyRequest(t) {
+ t.plan(2);
+
+ var protocol = new OpenLayers.Protocol.Script({});
+
+ var _unregister = OpenLayers.Protocol.Script.unregister;
+ OpenLayers.Protocol.Script.unregister = function(id) {
+ t.eq(id, 'foo', "destroyRequest calls unregister with correct id");
+ };
+ var script = {
+ id: 'script_foo'
+ };
+ protocol.destroyRequest(script);
+ t.eq(protocol.pendingRequests[script.id], null,
+ "destroyRequest nullifies the pending request");
+
+ OpenLayers.Protocol.Script.unregister = _unregister;
+ }
+
+ function test_handleResponse(t) {
+ t.plan(8);
+
+ var protocol = new OpenLayers.Protocol.Script();
+
+ // 2 tests (should be called only twive)
+ protocol.destroyRequest = function(priv) {
+ t.eq(priv, 'foo_priv', 'destroyRequest called with correct argument');
+ }
+
+ // 1 test (should be called only once)
+ protocol.parseFeatures = function(data) {
+ t.eq(data, 'foo_data', 'parseFeatures called with correct argument');
+ return 'foo_features';
+ }
+
+ var response = {
+ priv: 'foo_priv',
+ data: 'foo_data'
+ }
+ var options = {
+ // 2 tests (should be called twice)
+ scope: 'foo_scope',
+ callback: function(resp) {
+ t.eq(this, 'foo_scope', 'callback called with correct scope');
+ }
+ }
+ protocol.handleResponse(response, options);
+ // 2 tests
+ t.eq(response.code, OpenLayers.Protocol.Response.SUCCESS,
+ 'response code correctly set');
+ t.eq(response.features, 'foo_features',
+ 'response features takes a correct value');
+
+ response = {
+ priv: 'foo_priv'
+ }
+ protocol.handleResponse(response, options);
+ // 1 test
+ t.eq(response.code, OpenLayers.Protocol.Response.FAILURE,
+ 'response code correctly set');
+ }
+
+ function test_parseFeatures(t) {
+ t.plan(1);
+
+ var protocol = new OpenLayers.Protocol.Script();
+
+ protocol.format = {
+ 'read': function(data) {
+ t.ok(true, 'format.read called');
+ }
+ };
+
+ var ret = protocol.parseFeatures({foo: 'bar'});
+ }
+
+ function test_abort(t) {
+ t.plan(2);
+
+ var protocol = new OpenLayers.Protocol.Script();
+
+ // 1 test
+ protocol.destroyRequest = function(priv) {
+ t.eq(priv, 'foo_priv', 'destroyRequest called with correct argument');
+ }
+
+ var response = {
+ priv: 'foo_priv'
+ }
+
+ protocol.abort(response);
+
+ var calls = [];
+ protocol.pendingRequests = {
+ 'foo': 'foo_request',
+ 'bar': 'bar_request'
+ }
+ protocol.destroyRequest = function(priv) {
+ calls.push(priv);
+ }
+ protocol.abort();
+ // 1 test
+ t.eq(calls, ['foo_request', 'bar_request'],
+ 'destroyRequest called for each pending requests');
+ }
+
+ </script>
+</head>
+<body>
+</body>
+</html>
Modified: trunk/openlayers/tests/list-tests.html
===================================================================
--- trunk/openlayers/tests/list-tests.html 2011-03-10 20:14:49 UTC (rev 11690)
+++ trunk/openlayers/tests/list-tests.html 2011-03-10 20:51:03 UTC (rev 11691)
@@ -177,6 +177,7 @@
<li>Projection.html</li>
<li>Protocol.html</li>
<li>Protocol/HTTP.html</li>
+ <li>Protocol/Script.html</li>
<li>Protocol/SimpleFilterSerializer.html</li>
<li>Protocol/SQL.html</li>
<li>Protocol/SQL/Gears.html</li>
More information about the Commits
mailing list