/* 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/Request/XMLHttpRequest.js * @requires OpenLayers/Console.js */ OpenLayers.ProxyHost = ""; //OpenLayers.ProxyHost = "examples/proxy.cgi?url="; /** * Ajax reader for OpenLayers * * @uri url to do remote XML http get * @param {String} 'get' format params (x=y&a=b...) * @who object to handle callbacks for this request * @complete the function to be called on success * @failure the function to be called on failure * * example usage from a caller: * * caps: function(request) { * -blah- * }, * * OpenLayers.loadURL(url,params,this,caps); * * Notice the above example does not provide an error handler; a default empty * handler is provided which merely logs the error if a failure handler is not * supplied * */ /** * Function: OpenLayers.nullHandler * @param {} request */ OpenLayers.nullHandler = function(request) { OpenLayers.Console.userError(OpenLayers.i18n("unhandledRequest", {'statusText':request.statusText})); }; /** * APIFunction: OpenLayers.loadURL * Background load a document. For more flexibility in using XMLHttpRequest, * see the methods. * * Parameters: * uri - {String} URI of source doc * params - {String} or {Object} GET params. Either a string in the form * "?hello=world&foo=bar" (do not forget the leading question mark) * or an object in the form {'hello': 'world', 'foo': 'bar} * caller - {Object} object which gets callbacks * onComplete - {Function} Optional callback for success. The callback * will be called with this set to caller and will receive the request * object as an argument. Note that if you do not specify an onComplete * function, will be called (which pops up a * user friendly error message dialog). * onFailure - {Function} Optional callback for failure. In the event of * a failure, the callback will be called with this set to caller and will * receive the request object as an argument. Note that if you do not * specify an onComplete function, will be called * (which pops up a user friendly error message dialog). * * Returns: * {} The request object. To abort loading, * call request.abort(). */ OpenLayers.loadURL = function(uri, params, caller, onComplete, onFailure) { if(typeof params == 'string') { params = OpenLayers.Util.getParameters(params); } var success = (onComplete) ? onComplete : OpenLayers.nullHandler; var failure = (onFailure) ? onFailure : OpenLayers.nullHandler; return OpenLayers.Request.GET({ url: uri, params: params, success: success, failure: failure, scope: caller }); }; /** * Function: OpenLayers.parseXMLString * Parse XML into a doc structure * * Parameters: * text - {String} * * Returns: * {?} Parsed AJAX Responsev */ OpenLayers.parseXMLString = function(text) { //MS sucks, if the server is bad it dies var index = text.indexOf('<'); if (index > 0) { text = text.substring(index); } var ajaxResponse = OpenLayers.Util.Try( function() { var xmldom = new ActiveXObject('Microsoft.XMLDOM'); xmldom.loadXML(text); return xmldom; }, function() { return new DOMParser().parseFromString(text, 'text/xml'); }, function() { var req = new XMLHttpRequest(); req.open("GET", "data:" + "text/xml" + ";charset=utf-8," + encodeURIComponent(text), false); if (req.overrideMimeType) { req.overrideMimeType("text/xml"); } req.send(null); return req.responseXML; } ); return ajaxResponse; }; /** * Namespace: OpenLayers.Ajax */ OpenLayers.Ajax = { /** * Method: emptyFunction */ emptyFunction: function () {}, /** * Method: getTransport * * Returns: * {Object} Transport mechanism for whichever browser we're in, or false if * none available. */ getTransport: function() { return OpenLayers.Util.Try( function() {return new XMLHttpRequest();}, function() {return new ActiveXObject('Msxml2.XMLHTTP');}, function() {return new ActiveXObject('Microsoft.XMLHTTP');} ) || false; }, /** * Property: activeRequestCount * {Integer} */ activeRequestCount: 0 }; /** * Namespace: OpenLayers.Ajax.Responders * {Object} */ OpenLayers.Ajax.Responders = { /** * Property: responders * {Array} */ responders: [], /** * Method: register * * Parameters: * responderToAdd - {?} */ register: function(responderToAdd) { for (var i = 0; i < this.responders.length; i++){ if (responderToAdd == this.responders[i]){ return; } } this.responders.push(responderToAdd); }, /** * Method: unregister * * Parameters: * responderToRemove - {?} */ unregister: function(responderToRemove) { OpenLayers.Util.removeItem(this.reponders, responderToRemove); }, /** * Method: dispatch * * Parameters: * callback - {?} * request - {?} * transport - {?} */ dispatch: function(callback, request, transport) { var responder; for (var i = 0; i < this.responders.length; i++) { responder = this.responders[i]; if (responder[callback] && typeof responder[callback] == 'function') { try { responder[callback].apply(responder, [request, transport]); } catch (e) {} } } } }; OpenLayers.Ajax.Responders.register({ /** * Function: onCreate */ onCreate: function() { OpenLayers.Ajax.activeRequestCount++; }, /** * Function: onComplete */ onComplete: function() { OpenLayers.Ajax.activeRequestCount--; } }); /** * Class: OpenLayers.Ajax.Base */ OpenLayers.Ajax.Base = OpenLayers.Class({ /** * Constructor: OpenLayers.Ajax.Base * * Parameters: * options - {Object} */ initialize: function(options) { this.options = { method: 'post', asynchronous: true, contentType: 'application/xml', parameters: '' }; OpenLayers.Util.extend(this.options, options || {}); this.options.method = this.options.method.toLowerCase(); if (typeof this.options.parameters == 'string') { this.options.parameters = OpenLayers.Util.getParameters(this.options.parameters); } } }); /** * Class: OpenLayers.Ajax.Request * *Deprecated*. Use method instead. * * Inherit: * - */ OpenLayers.Ajax.Request = OpenLayers.Class(OpenLayers.Ajax.Base, { /** * Property: _complete * * {Boolean} */ _complete: false, /** * Constructor: OpenLayers.Ajax.Request * * Parameters: * url - {String} * options - {Object} */ initialize: function(url, options) { OpenLayers.Ajax.Base.prototype.initialize.apply(this, [options]); if (OpenLayers.ProxyHost && OpenLayers.String.startsWith(url, "http")) { url = OpenLayers.ProxyHost + encodeURIComponent(url); } this.transport = OpenLayers.Ajax.getTransport(); this.request(url); }, /** * Method: request * * Parameters: * url - {String} */ request: function(url) { this.url = url; this.method = this.options.method; var params = OpenLayers.Util.extend({}, this.options.parameters); if (this.method != 'get' && this.method != 'post') { // simulate other verbs over post params['_method'] = this.method; this.method = 'post'; } this.parameters = params; if (params = OpenLayers.Util.getParameterString(params)) { // when GET, append parameters to URL if (this.method == 'get') { this.url += ((this.url.indexOf('?') > -1) ? '&' : '?') + params; } else if (/Konqueror|Safari|KHTML/.test(navigator.userAgent)) { params += '&_='; } } try { var response = new OpenLayers.Ajax.Response(this); if (this.options.onCreate) { this.options.onCreate(response); } OpenLayers.Ajax.Responders.dispatch('onCreate', this, response); this.transport.open(this.method.toUpperCase(), this.url, this.options.asynchronous); if (this.options.asynchronous) { window.setTimeout( OpenLayers.Function.bind(this.respondToReadyState, this, 1), 10); } this.transport.onreadystatechange = OpenLayers.Function.bind(this.onStateChange, this); this.setRequestHeaders(); this.body = this.method == 'post' ? (this.options.postBody || params) : null; this.transport.send(this.body); // Force Firefox to handle ready state 4 for synchronous requests if (!this.options.asynchronous && this.transport.overrideMimeType) { this.onStateChange(); } } catch (e) { this.dispatchException(e); } }, /** * Method: onStateChange */ onStateChange: function() { var readyState = this.transport.readyState; if (readyState > 1 && !((readyState == 4) && this._complete)) { this.respondToReadyState(this.transport.readyState); } }, /** * Method: setRequestHeaders */ setRequestHeaders: function() { var headers = { 'X-Requested-With': 'XMLHttpRequest', 'Accept': 'text/javascript, text/html, application/xml, text/xml, */*', 'OpenLayers': true }; if (this.method == 'post') { headers['Content-type'] = this.options.contentType + (this.options.encoding ? '; charset=' + this.options.encoding : ''); /* Force "Connection: close" for older Mozilla browsers to work * around a bug where XMLHttpRequest sends an incorrect * Content-length header. See Mozilla Bugzilla #246651. */ if (this.transport.overrideMimeType && (navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005) { headers['Connection'] = 'close'; } } // user-defined headers if (typeof this.options.requestHeaders == 'object') { var extras = this.options.requestHeaders; if (typeof extras.push == 'function') { for (var i = 0, length = extras.length; i < length; i += 2) { headers[extras[i]] = extras[i+1]; } } else { for (var i in extras) { headers[i] = extras[i]; } } } for (var name in headers) { this.transport.setRequestHeader(name, headers[name]); } }, /** * Method: success * * Returns: * {Boolean} - */ success: function() { var status = this.getStatus(); return !status || (status >=200 && status < 300); }, /** * Method: getStatus * * Returns: * {Integer} - Status */ getStatus: function() { try { return this.transport.status || 0; } catch (e) { return 0; } }, /** * Method: respondToReadyState * * Parameters: * readyState - {?} */ respondToReadyState: function(readyState) { var state = OpenLayers.Ajax.Request.Events[readyState]; var response = new OpenLayers.Ajax.Response(this); if (state == 'Complete') { try { this._complete = true; (this.options['on' + response.status] || this.options['on' + (this.success() ? 'Success' : 'Failure')] || OpenLayers.Ajax.emptyFunction)(response); } catch (e) { this.dispatchException(e); } var contentType = response.getHeader('Content-type'); } try { (this.options['on' + state] || OpenLayers.Ajax.emptyFunction)(response); OpenLayers.Ajax.Responders.dispatch('on' + state, this, response); } catch (e) { this.dispatchException(e); } if (state == 'Complete') { // avoid memory leak in MSIE: clean up this.transport.onreadystatechange = OpenLayers.Ajax.emptyFunction; } }, /** * Method: getHeader * * Parameters: * name - {String} Header name * * Returns: * {?} - response header for the given name */ getHeader: function(name) { try { return this.transport.getResponseHeader(name); } catch (e) { return null; } }, /** * Method: dispatchException * If the optional onException function is set, execute it * and then dispatch the call to any other listener registered * for onException. * * If no optional onException function is set, we suspect that * the user may have also not used * OpenLayers.Ajax.Responders.register to register a listener * for the onException call. To make sure that something * gets done with this exception, only dispatch the call if there * are listeners. * * If you explicitly want to swallow exceptions, set * request.options.onException to an empty function (function(){}) * or register an empty function with * for onException. * * Parameters: * exception - {?} */ dispatchException: function(exception) { var handler = this.options.onException; if(handler) { // call options.onException and alert any other listeners handler(this, exception); OpenLayers.Ajax.Responders.dispatch('onException', this, exception); } else { // check if there are any other listeners var listener = false; var responders = OpenLayers.Ajax.Responders.responders; for (var i = 0; i < responders.length; i++) { if(responders[i].onException) { listener = true; break; } } if(listener) { // call all listeners OpenLayers.Ajax.Responders.dispatch('onException', this, exception); } else { // let the exception through throw exception; } } } }); /** * Property: Events * {Array(String)} */ OpenLayers.Ajax.Request.Events = ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete']; /** * Class: OpenLayers.Ajax.Response */ OpenLayers.Ajax.Response = OpenLayers.Class({ /** * Property: status * * {Integer} */ status: 0, /** * Property: statusText * * {String} */ statusText: '', /** * Constructor: OpenLayers.Ajax.Response * * Parameters: * request - {Object} */ initialize: function(request) { this.request = request; var transport = this.transport = request.transport, readyState = this.readyState = transport.readyState; if ((readyState > 2 && !(!!(window.attachEvent && !window.opera))) || readyState == 4) { this.status = this.getStatus(); this.statusText = this.getStatusText(); this.responseText = transport.responseText == null ? '' : String(transport.responseText); } if(readyState == 4) { var xml = transport.responseXML; this.responseXML = xml === undefined ? null : xml; } }, /** * Method: getStatus */ getStatus: OpenLayers.Ajax.Request.prototype.getStatus, /** * Method: getStatustext * * Returns: * {String} - statusText */ getStatusText: function() { try { return this.transport.statusText || ''; } catch (e) { return ''; } }, /** * Method: getHeader */ getHeader: OpenLayers.Ajax.Request.prototype.getHeader, /** * Method: getResponseHeader * * Returns: * {?} - response header for given name */ getResponseHeader: function(name) { return this.transport.getResponseHeader(name); } }); /** * Function: getElementsByTagNameNS * * Parameters: * parentnode - {?} * nsuri - {?} * nsprefix - {?} * tagname - {?} * * Returns: * {?} */ OpenLayers.Ajax.getElementsByTagNameNS = function(parentnode, nsuri, nsprefix, tagname) { var elem = null; if (parentnode.getElementsByTagNameNS) { elem = parentnode.getElementsByTagNameNS(nsuri, tagname); } else { elem = parentnode.getElementsByTagName(nsprefix + ':' + tagname); } return elem; }; /** * Function: serializeXMLToString * Wrapper function around XMLSerializer, which doesn't exist/work in * IE/Safari. We need to come up with a way to serialize in those browser: * for now, these browsers will just fail. #535, #536 * * Parameters: * xmldom {XMLNode} xml dom to serialize * * Returns: * {?} */ OpenLayers.Ajax.serializeXMLToString = function(xmldom) { var serializer = new XMLSerializer(); var data = serializer.serializeToString(xmldom); return data; };