http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/e387fc92/JSLib/src/odata-net.js
----------------------------------------------------------------------
diff --git a/JSLib/src/odata-net.js b/JSLib/src/odata-net.js
index ad9b8dd..792e3fc 100644
--- a/JSLib/src/odata-net.js
+++ b/JSLib/src/odata-net.js
@@ -1,330 +1,331 @@
-// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
-// Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation
-// files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy,
-// modify, merge, publish, distribute, sublicense, and/or sell copies of the
Software, and to permit persons to whom the
-// Software is furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE
-// WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
-
-// odata-net.js
-
-(function (window, undefined) {
-
- var datajs = window.datajs || {};
- var odata = window.OData || {};
-
- // Imports.
-
- var defined = datajs.defined;
- var delay = datajs.delay;
-
- // CONTENT START
- var ticks = 0;
-
- var canUseJSONP = function (request) {
- /// <summary>
- /// Checks whether the specified request can be satisfied with a JSONP
request.
- /// </summary>
- /// <param name="request">Request object to check.</param>
- /// <returns type="Boolean">true if the request can be satisfied;
false otherwise.</returns>
-
- // Requests that 'degrade' without changing their meaning by going
through JSONP
- // are considered usable.
- //
- // We allow data to come in a different format, as the servers SHOULD
honor the Accept
- // request but may in practice return content with a different MIME
type.
- if (request.method && request.method !== "GET") {
- return false;
- }
-
- return true;
- };
-
- var createIFrame = function (url) {
- /// <summary>Creates an IFRAME tag for loading the JSONP
script</summary>
- /// <param name="url" type="String">The source URL of the
script</param>
- /// <returns type="HTMLElement">The IFRAME tag</returns>
- var iframe = window.document.createElement("IFRAME");
- iframe.style.display = "none";
-
- var attributeEncodedUrl = url.replace(/&/g, "&").replace(/"/g,
""").replace(/\</g, "<");
- var html = "<html><head><script type=\"text/javascript\" src=\"" +
attributeEncodedUrl + "\"><\/script><\/head><body><\/body><\/html>";
-
- var body = window.document.getElementsByTagName("BODY")[0];
- body.appendChild(iframe);
-
- writeHtmlToIFrame(iframe, html);
- return iframe;
- };
-
- var createXmlHttpRequest = function () {
- /// <summary>Creates a XmlHttpRequest object.</summary>
- /// <returns type="XmlHttpRequest">XmlHttpRequest object.</returns>
- if (window.XMLHttpRequest) {
- return new window.XMLHttpRequest();
- }
- var exception;
- if (window.ActiveXObject) {
- try {
- return new window.ActiveXObject("Msxml2.XMLHTTP.6.0");
- } catch (_) {
- try {
- return new window.ActiveXObject("Msxml2.XMLHTTP.3.0");
- } catch (e) {
- exception = e;
- }
- }
- } else {
- exception = { message: "XMLHttpRequest not supported" };
- }
- throw exception;
- };
-
- var isAbsoluteUrl = function (url) {
- /// <summary>Checks whether the specified URL is an absolute
URL.</summary>
- /// <param name="url" type="String">URL to check.</param>
- /// <returns type="Boolean">true if the url is an absolute URL; false
otherwise.</returns>
-
- return url.indexOf("http://") === 0 ||
- url.indexOf("https://") === 0 ||
- url.indexOf("file://") === 0;
- };
-
- var isLocalUrl = function (url) {
- /// <summary>Checks whether the specified URL is local to the current
context.</summary>
- /// <param name="url" type="String">URL to check.</param>
- /// <returns type="Boolean">true if the url is a local URL; false
otherwise.</returns>
-
- if (!isAbsoluteUrl(url)) {
- return true;
- }
-
- // URL-embedded username and password will not be recognized as
same-origin URLs.
- var location = window.location;
- var locationDomain = location.protocol + "//" + location.host + "/";
- return (url.indexOf(locationDomain) === 0);
- };
-
- var removeCallback = function (name, tick) {
- /// <summary>Removes a callback used for a JSONP request.</summary>
- /// <param name="name" type="String">Function name to remove.</param>
- /// <param name="tick" type="Number">Tick count used on the
callback.</param>
- try {
- delete window[name];
- } catch (err) {
- window[name] = undefined;
- if (tick === ticks - 1) {
- ticks -= 1;
- }
- }
- };
-
- var removeIFrame = function (iframe) {
- /// <summary>Removes an iframe.</summary>
- /// <param name="iframe" type="Object">The iframe to remove.</param>
- /// <returns type="Object">Null value to be assigned to iframe
reference.</returns>
- if (iframe) {
- writeHtmlToIFrame(iframe, "");
- iframe.parentNode.removeChild(iframe);
- }
-
- return null;
- };
-
- var readResponseHeaders = function (xhr, headers) {
- /// <summary>Reads response headers into array.</summary>
- /// <param name="xhr" type="XMLHttpRequest">HTTP request with response
available.</param>
- /// <param name="headers" type="Array">Target array to fill with
name/value pairs.</param>
-
- var responseHeaders = xhr.getAllResponseHeaders().split(/\r?\n/);
- var i, len;
- for (i = 0, len = responseHeaders.length; i < len; i++) {
- if (responseHeaders[i]) {
- var header = responseHeaders[i].split(": ");
- headers[header[0]] = header[1];
- }
- }
- };
-
- var writeHtmlToIFrame = function (iframe, html) {
- /// <summary>Writes HTML to an IFRAME document.</summary>
- /// <param name="iframe" type="HTMLElement">The IFRAME element to
write to.</param>
- /// <param name="html" type="String">The HTML to write.</param>
- var frameDocument = (iframe.contentWindow) ?
iframe.contentWindow.document : iframe.contentDocument.document;
- frameDocument.open();
- frameDocument.write(html);
- frameDocument.close();
- };
-
- odata.defaultHttpClient = {
- callbackParameterName: "$callback",
-
- formatQueryString: "$format=json",
-
- enableJsonpCallback: false,
-
- request: function (request, success, error) {
- /// <summary>Performs a network request.</summary>
- /// <param name="request" type="Object">Request
description.</request>
- /// <param name="success" type="Function">Success callback with
the response object.</param>
- /// <param name="error" type="Function">Error callback with an
error object.</param>
- /// <returns type="Object">Object with an 'abort' method for the
operation.</returns>
-
- var result = {};
- var xhr = null;
- var done = false;
- var iframe;
-
- result.abort = function () {
- iframe = removeIFrame(iframe);
- if (done) {
- return;
- }
-
- done = true;
- if (xhr) {
- xhr.abort();
- xhr = null;
- }
-
- error({ message: "Request aborted" });
- };
-
- var handleTimeout = function () {
- iframe = removeIFrame(iframe);
- if (!done) {
- done = true;
- xhr = null;
- error({ message: "Request timed out" });
- }
- };
-
- var name;
- var url = request.requestUri;
- var enableJsonpCallback = defined(request.enableJsonpCallback,
this.enableJsonpCallback);
- var callbackParameterName = defined(request.callbackParameterName,
this.callbackParameterName);
- var formatQueryString = defined(request.formatQueryString,
this.formatQueryString);
- if (!enableJsonpCallback || isLocalUrl(url)) {
-
- xhr = createXmlHttpRequest();
- xhr.onreadystatechange = function () {
- if (done || xhr === null || xhr.readyState !== 4) {
- return;
- }
-
- // Workaround for XHR behavior on IE.
- var statusText = xhr.statusText;
- var statusCode = xhr.status;
- if (statusCode === 1223) {
- statusCode = 204;
- statusText = "No Content";
- }
-
- var headers = [];
- readResponseHeaders(xhr, headers);
-
- var response = { requestUri: url, statusCode: statusCode,
statusText: statusText, headers: headers, body: xhr.responseText };
-
- done = true;
- xhr = null;
- if (statusCode >= 200 && statusCode <= 299) {
- success(response);
- } else {
- error({ message: "HTTP request failed", request:
request, response: response });
- }
- };
-
- xhr.open(request.method || "GET", url, true, request.user,
request.password);
-
- // Set the name/value pairs.
- if (request.headers) {
- for (name in request.headers) {
- xhr.setRequestHeader(name, request.headers[name]);
- }
- }
-
- // Set the timeout if available.
- if (request.timeoutMS) {
- xhr.timeout = request.timeoutMS;
- xhr.ontimeout = handleTimeout;
- }
-
- xhr.send(request.body);
- } else {
- if (!canUseJSONP(request)) {
- throw { message: "Request is not local and cannot be done
through JSONP." };
- }
-
- var tick = ticks;
- ticks += 1;
- var tickText = tick.toString();
- var succeeded = false;
- var timeoutId;
- name = "handleJSONP_" + tickText;
- window[name] = function (data) {
- iframe = removeIFrame(iframe);
- if (!done) {
- succeeded = true;
- window.clearTimeout(timeoutId);
- removeCallback(name, tick);
-
- // Workaround for IE8 and IE10 below where trying to
access data.constructor after the IFRAME has been removed
- // throws an "unknown exception"
- if (window.ActiveXObject) {
- data =
window.JSON.parse(window.JSON.stringify(data));
- }
-
-
- var headers;
- // Adding dataServiceVersion in case of json light (
data.d doesn't exist )
- if (data.d === undefined) {
- headers = { "Content-Type":
"application/json;odata=minimalmetadata", dataServiceVersion: "3.0" };
- } else {
- headers = { "Content-Type": "application/json" };
- }
- // Call the success callback in the context of the
parent window, instead of the IFRAME
- delay(function () {
- removeIFrame(iframe);
- success({ body: data, statusCode: 200, headers:
headers });
- });
- }
- };
-
- // Default to two minutes before timing out, 1000 ms * 60 * 2
= 120000.
- var timeoutMS = (request.timeoutMS) ? request.timeoutMS :
120000;
- timeoutId = window.setTimeout(handleTimeout, timeoutMS);
-
- var queryStringParams = callbackParameterName + "=parent." +
name;
- if (this.formatQueryString) {
- queryStringParams += "&" + formatQueryString;
- }
-
- var qIndex = url.indexOf("?");
- if (qIndex === -1) {
- url = url + "?" + queryStringParams;
- } else if (qIndex === url.length - 1) {
- url = url + queryStringParams;
- } else {
- url = url + "&" + queryStringParams;
- }
-
- iframe = createIFrame(url);
- }
-
- return result;
- }
- };
-
- // DATAJS INTERNAL START
- odata.canUseJSONP = canUseJSONP;
- odata.isAbsoluteUrl = isAbsoluteUrl;
- odata.isLocalUrl = isLocalUrl;
- // DATAJS INTERNAL END
-
- // CONTENT END
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
+// Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy,
+// modify, merge, publish, distribute, sublicense, and/or sell copies of the
Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+// WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
+
+// odata-net.js
+
+(function (window, undefined) {
+
+ var datajs = window.datajs || {};
+ var odata = window.OData || {};
+
+ // Imports.
+
+ var defined = datajs.defined;
+ var delay = datajs.delay;
+
+ // CONTENT START
+ var ticks = 0;
+
+ var canUseJSONP = function (request) {
+ /// <summary>
+ /// Checks whether the specified request can be satisfied with a JSONP
request.
+ /// </summary>
+ /// <param name="request">Request object to check.</param>
+ /// <returns type="Boolean">true if the request can be satisfied;
false otherwise.</returns>
+
+ // Requests that 'degrade' without changing their meaning by going
through JSONP
+ // are considered usable.
+ //
+ // We allow data to come in a different format, as the servers SHOULD
honor the Accept
+ // request but may in practice return content with a different MIME
type.
+ if (request.method && request.method !== "GET") {
+ return false;
+ }
+
+ return true;
+ };
+
+ var createIFrame = function (url) {
+ /// <summary>Creates an IFRAME tag for loading the JSONP
script</summary>
+ /// <param name="url" type="String">The source URL of the
script</param>
+ /// <returns type="HTMLElement">The IFRAME tag</returns>
+ var iframe = window.document.createElement("IFRAME");
+ iframe.style.display = "none";
+
+ var attributeEncodedUrl = url.replace(/&/g, "&").replace(/"/g,
""").replace(/\</g, "<");
+ var html = "<html><head><script type=\"text/javascript\" src=\"" +
attributeEncodedUrl + "\"><\/script><\/head><body><\/body><\/html>";
+
+ var body = window.document.getElementsByTagName("BODY")[0];
+ body.appendChild(iframe);
+
+ writeHtmlToIFrame(iframe, html);
+ return iframe;
+ };
+
+ var createXmlHttpRequest = function () {
+ /// <summary>Creates a XmlHttpRequest object.</summary>
+ /// <returns type="XmlHttpRequest">XmlHttpRequest object.</returns>
+ if (window.XMLHttpRequest) {
+ return new window.XMLHttpRequest();
+ }
+ var exception;
+ if (window.ActiveXObject) {
+ try {
+ return new window.ActiveXObject("Msxml2.XMLHTTP.6.0");
+ } catch (_) {
+ try {
+ return new window.ActiveXObject("Msxml2.XMLHTTP.3.0");
+ } catch (e) {
+ exception = e;
+ }
+ }
+ } else {
+ exception = { message: "XMLHttpRequest not supported" };
+ }
+ throw exception;
+ };
+
+ var isAbsoluteUrl = function (url) {
+ /// <summary>Checks whether the specified URL is an absolute
URL.</summary>
+ /// <param name="url" type="String">URL to check.</param>
+ /// <returns type="Boolean">true if the url is an absolute URL; false
otherwise.</returns>
+
+ return url.indexOf("http://") === 0 ||
+ url.indexOf("https://") === 0 ||
+ url.indexOf("file://") === 0;
+ };
+
+ var isLocalUrl = function (url) {
+ /// <summary>Checks whether the specified URL is local to the current
context.</summary>
+ /// <param name="url" type="String">URL to check.</param>
+ /// <returns type="Boolean">true if the url is a local URL; false
otherwise.</returns>
+
+ if (!isAbsoluteUrl(url)) {
+ return true;
+ }
+
+ // URL-embedded username and password will not be recognized as
same-origin URLs.
+ var location = window.location;
+ var locationDomain = location.protocol + "//" + location.host + "/";
+ return (url.indexOf(locationDomain) === 0);
+ };
+
+ var removeCallback = function (name, tick) {
+ /// <summary>Removes a callback used for a JSONP request.</summary>
+ /// <param name="name" type="String">Function name to remove.</param>
+ /// <param name="tick" type="Number">Tick count used on the
callback.</param>
+ try {
+ delete window[name];
+ } catch (err) {
+ window[name] = undefined;
+ if (tick === ticks - 1) {
+ ticks -= 1;
+ }
+ }
+ };
+
+ var removeIFrame = function (iframe) {
+ /// <summary>Removes an iframe.</summary>
+ /// <param name="iframe" type="Object">The iframe to remove.</param>
+ /// <returns type="Object">Null value to be assigned to iframe
reference.</returns>
+ if (iframe) {
+ writeHtmlToIFrame(iframe, "");
+ iframe.parentNode.removeChild(iframe);
+ }
+
+ return null;
+ };
+
+ var readResponseHeaders = function (xhr, headers) {
+ /// <summary>Reads response headers into array.</summary>
+ /// <param name="xhr" type="XMLHttpRequest">HTTP request with response
available.</param>
+ /// <param name="headers" type="Array">Target array to fill with
name/value pairs.</param>
+
+ var responseHeaders = xhr.getAllResponseHeaders().split(/\r?\n/);
+ var i, len;
+ for (i = 0, len = responseHeaders.length; i < len; i++) {
+ if (responseHeaders[i]) {
+ var header = responseHeaders[i].split(": ");
+ headers[header[0]] = header[1];
+ }
+ }
+ };
+
+ var writeHtmlToIFrame = function (iframe, html) {
+ /// <summary>Writes HTML to an IFRAME document.</summary>
+ /// <param name="iframe" type="HTMLElement">The IFRAME element to
write to.</param>
+ /// <param name="html" type="String">The HTML to write.</param>
+ var frameDocument = (iframe.contentWindow) ?
iframe.contentWindow.document : iframe.contentDocument.document;
+ frameDocument.open();
+ frameDocument.write(html);
+ frameDocument.close();
+ };
+
+ odata.defaultHttpClient = {
+ callbackParameterName: "$callback",
+
+ formatQueryString: "$format=json",
+
+ enableJsonpCallback: false,
+
+ request: function (request, success, error) {
+ /// <summary>Performs a network request.</summary>
+ /// <param name="request" type="Object">Request
description.</request>
+ /// <param name="success" type="Function">Success callback with
the response object.</param>
+ /// <param name="error" type="Function">Error callback with an
error object.</param>
+ /// <returns type="Object">Object with an 'abort' method for the
operation.</returns>
+
+ var result = {};
+ var xhr = null;
+ var done = false;
+ var iframe;
+
+ result.abort = function () {
+ iframe = removeIFrame(iframe);
+ if (done) {
+ return;
+ }
+
+ done = true;
+ if (xhr) {
+ xhr.abort();
+ xhr = null;
+ }
+
+ error({ message: "Request aborted" });
+ };
+
+ var handleTimeout = function () {
+ iframe = removeIFrame(iframe);
+ if (!done) {
+ done = true;
+ xhr = null;
+ error({ message: "Request timed out" });
+ }
+ };
+
+ var name;
+ var url = request.requestUri;
+ var enableJsonpCallback = defined(request.enableJsonpCallback,
this.enableJsonpCallback);
+ var callbackParameterName = defined(request.callbackParameterName,
this.callbackParameterName);
+ var formatQueryString = defined(request.formatQueryString,
this.formatQueryString);
+ if (!enableJsonpCallback || isLocalUrl(url)) {
+
+ xhr = createXmlHttpRequest();
+ xhr.onreadystatechange = function () {
+ if (done || xhr === null || xhr.readyState !== 4) {
+ return;
+ }
+
+ // Workaround for XHR behavior on IE.
+ var statusText = xhr.statusText;
+ var statusCode = xhr.status;
+ if (statusCode === 1223) {
+ statusCode = 204;
+ statusText = "No Content";
+ }
+
+ var headers = [];
+ readResponseHeaders(xhr, headers);
+
+ var response = { requestUri: url, statusCode: statusCode,
statusText: statusText, headers: headers, body: xhr.responseText };
+
+ done = true;
+ xhr = null;
+ if (statusCode >= 200 && statusCode <= 299) {
+ success(response);
+ } else {
+ error({ message: "HTTP request failed", request:
request, response: response });
+ }
+ };
+
+ xhr.open(request.method || "GET", url, true, request.user,
request.password);
+
+ // Set the name/value pairs.
+ if (request.headers) {
+ for (name in request.headers) {
+ xhr.setRequestHeader(name, request.headers[name]);
+ }
+ }
+
+ // Set the timeout if available.
+ if (request.timeoutMS) {
+ xhr.timeout = request.timeoutMS;
+ xhr.ontimeout = handleTimeout;
+ }
+
+ xhr.send(request.body);
+ } else {
+ if (!canUseJSONP(request)) {
+ throw { message: "Request is not local and cannot be done
through JSONP." };
+ }
+
+ var tick = ticks;
+ ticks += 1;
+ var tickText = tick.toString();
+ var succeeded = false;
+ var timeoutId;
+ name = "handleJSONP_" + tickText;
+ window[name] = function (data) {
+ iframe = removeIFrame(iframe);
+ if (!done) {
+ succeeded = true;
+ window.clearTimeout(timeoutId);
+ removeCallback(name, tick);
+
+ // Workaround for IE8 and IE10 below where trying to
access data.constructor after the IFRAME has been removed
+ // throws an "unknown exception"
+ if (window.ActiveXObject) {
+ data =
window.JSON.parse(window.JSON.stringify(data));
+ }
+
+ var headers;
+ if (!formatQueryString || formatQueryString ==
"$format=json") {
+ headers = { "Content-Type":
"application/json;odata.metadata=minimal", "OData-Version": "4.0" };
+ } else {
+ // the formatQueryString should be in the format
of "$format=xxx", xxx should be one of the
application/json;odata.metadata=minimal(none or full)
+ // set the content-type with the string xxx which
stars from index 8.
+ headers = { "Content-Type":
formatQueryString.substring(8), "OData-Version": "4.0" };
+ }
+
+ // Call the success callback in the context of the
parent window, instead of the IFRAME
+ delay(function () {
+ removeIFrame(iframe);
+ success({ body: data, statusCode: 200, headers:
headers });
+ });
+ }
+ };
+
+ // Default to two minutes before timing out, 1000 ms * 60 * 2
= 120000.
+ var timeoutMS = (request.timeoutMS) ? request.timeoutMS :
120000;
+ timeoutId = window.setTimeout(handleTimeout, timeoutMS);
+
+ var queryStringParams = callbackParameterName + "=parent." +
name;
+ if (formatQueryString) {
+ queryStringParams += "&" + formatQueryString;
+ }
+
+ var qIndex = url.indexOf("?");
+ if (qIndex === -1) {
+ url = url + "?" + queryStringParams;
+ } else if (qIndex === url.length - 1) {
+ url = url + queryStringParams;
+ } else {
+ url = url + "&" + queryStringParams;
+ }
+
+ iframe = createIFrame(url);
+ }
+
+ return result;
+ }
+ };
+
+ // DATAJS INTERNAL START
+ odata.canUseJSONP = canUseJSONP;
+ odata.isAbsoluteUrl = isAbsoluteUrl;
+ odata.isLocalUrl = isLocalUrl;
+ // DATAJS INTERNAL END
+
+ // CONTENT END
})(this);
\ No newline at end of file