You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by pu...@apache.org on 2012/04/13 01:25:21 UTC
[3/6] git commit: added XHR patch and DOMStorage patch,
both are conditionally polyfil'n expected APIs
added XHR patch and DOMStorage patch, both are conditionally polyfil'n expected APIs
Project: http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/commit/0c5d9179
Tree: http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/tree/0c5d9179
Diff: http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/diff/0c5d9179
Branch: refs/heads/master
Commit: 0c5d9179dacf9107d93b5a0971f6a47a5ba8fa74
Parents: 7e1461b
Author: Jesse MacFadyen <pu...@gmail.com>
Authored: Tue Apr 10 15:46:58 2012 -0700
Committer: Jesse MacFadyen <pu...@gmail.com>
Committed: Thu Apr 12 16:22:02 2012 -0700
----------------------------------------------------------------------
lib/wp7/platform.js | 211 ++-------------------------------
lib/wp7/plugin/wp7/DOMStorage.js | 198 ++++++++++++++++++++++++++++++
lib/wp7/plugin/wp7/XHRPatch.js | 212 +++++++++++++++++++++++++++++++++
3 files changed, 420 insertions(+), 201 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/0c5d9179/lib/wp7/platform.js
----------------------------------------------------------------------
diff --git a/lib/wp7/platform.js b/lib/wp7/platform.js
index ff61830..4a89e27 100644
--- a/lib/wp7/platform.js
+++ b/lib/wp7/platform.js
@@ -1,214 +1,23 @@
var cordova = require('cordova'),
exec = require('cordova/exec');
+// specifically require the following patches
+// localStorage+SessionStorage APIs
+require("cordova/plugin/wp7/DOMStorage");
+// Fix XHR calls to local file-system
+require("cordova/plugin/wp7/XHRPatch");
+
+
module.exports = {
id: "wp7",
initialize:function() {
-console.log("window.CordovaMediaonStatus = " + window.CordovaMediaonStatus);
-
-if(!window.localStorage)
-{(function()
-{
-
-
-
- var DOMStorage = function(type)
- {
- // default type is local
- if(type == "sessionStorage")
- {
- this._type = type;
- }
- Object.defineProperty( this, "length",
- {
- configurable: true,
- get: function(){ return this.getLength() }
- });
-
- };
-
- DOMStorage.prototype =
- {
- _type:"localStorage",
- _result:null,
- keys:null,
-
- onResult:function(key,valueStr)
- {
- if(!this.keys)
- {
- this.keys = [];
- }
- this._result = valueStr;
- },
-
- onKeysChanged:function(jsonKeys)
- {
- this.keys = JSON.parse(jsonKeys);
-
- var key;
- for(var n = 0,len =this.keys.length; n < len; n++)
- {
- key = this.keys[n];
- if(!this.hasOwnProperty(key))
- {
- Object.defineProperty( this, key,
- {
-
- configurable: true,
- get: function(){ return this.getItem(key); },
- set: function(val){ return this.setItem(key,val); }
- });
- }
- }
-
- },
-
- initialize:function()
- {
- window.external.Notify("DOMStorage/" + this._type + "/load/keys");
- },
-
- /*
- The length attribute must return the number of key/value pairs currently present in the list associated with the object.
- */
- getLength:function()
- {
- if(!this.keys)
- {
- this.initialize();
- }
- return this.keys.length;
- },
-
- /*
- The key(n) method must return the name of the nth key in the list.
- The order of keys is user-agent defined, but must be consistent within an object so long as the number of keys doesn't change.
- (Thus, adding or removing a key may change the order of the keys, but merely changing the value of an existing key must not.)
- If n is greater than or equal to the number of key/value pairs in the object, then this method must return null.
- */
- key:function(n)
- {
- if(!this.keys)
- {
- this.initialize();
- }
-
- if(n >= this.keys.length)
- {
- return null;
- }
- else
- {
- return this.keys[n];
- }
- },
-
- /*
- The getItem(key) method must return the current value associated with the given key.
- If the given key does not exist in the list associated with the object then this method must return null.
- */
- getItem:function(key)
- {
- if(!this.keys)
- {
- this.initialize();
- }
-
- var retVal = null;
- if(this.keys.indexOf(key) > -1)
- {
- window.external.Notify("DOMStorage/" + this._type + "/get/" + key);
- retVal = this._result;
- this._result = null;
- }
- return retVal;
- },
- /*
- The setItem(key, value) method must first check if a key/value pair with the given key already exists
- in the list associated with the object.
- If it does not, then a new key/value pair must be added to the list, with the given key and with its value set to value.
- If the given key does exist in the list, then it must have its value updated to value.
- If it couldn't set the new value, the method must raise an QUOTA_EXCEEDED_ERR exception.
- (Setting could fail if, e.g., the user has disabled storage for the site, or if the quota has been exceeded.)
- */
- setItem:function(key,value)
- {
- if(!this.keys)
- {
- this.initialize();
- }
- window.external.Notify("DOMStorage/" + this._type + "/set/" + key + "/" + value);
- },
-
- /*
- The removeItem(key) method must cause the key/value pair with the given key to be removed from the list
- associated with the object, if it exists.
- If no item with that key exists, the method must do nothing.
- */
- removeItem:function(key)
- {
- if(!this.keys)
- {
- this.initialize();
- }
- var index = this.keys.indexOf(key);
- if(index > -1)
- {
- this.keys.splice(index,1);
- // TODO: need sanity check for keys ? like 'clear','setItem', ...
- window.external.Notify("DOMStorage/" + this._type + "/remove/" + key);
- delete this[key];
- }
-
- },
-
- /*
- The clear() method must atomically cause the list associated with the object to be emptied of all
- key/value pairs, if there are any.
- If there are none, then the method must do nothing.
- */
- clear:function()
- {
- if(!this.keys)
- {
- this.initialize();
- }
-
- for(var n=0,len=this.keys.length; n < len;n++)
- {
- // TODO: do we need a sanity check for keys ? like 'clear','setItem', ...
- delete this[this.keys[n]];
- }
- this.keys = [];
- window.external.Notify("DOMStorage/" + this._type + "/clear/");
- }
- };
-
- // initialize DOMStorage
-
- Object.defineProperty( window, "localStorage",
- {
- writable: false,
- configurable: false,
- value:new DOMStorage("localStorage")
- });
- window.localStorage.initialize();
-
- Object.defineProperty( window, "sessionStorage",
- {
- writable: false,
- configurable: false,
- value:new DOMStorage("sessionStorage")
- });
- window.sessionStorage.initialize();
-
+ console.log("window.CordovaMediaonStatus = " + window.CordovaMediaonStatus);
+ console.log("window.localStorage = " + window.localStorage);
-})();};
- // INject a lsitener for the backbutton, and tell native to override the flag (true/false) when we have 1 or more, or 0, listeners
+ // INject a lsitener for the backbutton, and tell native to override the flag (true/false) when we have 1 or more, or 0, listeners
var backButtonChannel = cordova.addDocumentEventHandler('backbutton', {
onSubscribe:function() {
if (this.numHandlers === 1) {
http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/0c5d9179/lib/wp7/plugin/wp7/DOMStorage.js
----------------------------------------------------------------------
diff --git a/lib/wp7/plugin/wp7/DOMStorage.js b/lib/wp7/plugin/wp7/DOMStorage.js
new file mode 100644
index 0000000..db61f4c
--- /dev/null
+++ b/lib/wp7/plugin/wp7/DOMStorage.js
@@ -0,0 +1,198 @@
+(function()
+{
+
+ var DOMStorage = function(type)
+ {
+ // default type is local
+ if(type == "sessionStorage")
+ {
+ this._type = type;
+ }
+ Object.defineProperty( this, "length",
+ {
+ configurable: true,
+ get: function(){ return this.getLength() }
+ });
+
+ };
+
+ DOMStorage.prototype =
+ {
+ _type:"localStorage",
+ _result:null,
+ keys:null,
+
+ onResult:function(key,valueStr)
+ {
+ if(!this.keys)
+ {
+ this.keys = [];
+ }
+ this._result = valueStr;
+ },
+
+ onKeysChanged:function(jsonKeys)
+ {
+ this.keys = JSON.parse(jsonKeys);
+
+ var key;
+ for(var n = 0,len =this.keys.length; n < len; n++)
+ {
+ key = this.keys[n];
+ if(!this.hasOwnProperty(key))
+ {
+ Object.defineProperty( this, key,
+ {
+
+ configurable: true,
+ get: function(){ return this.getItem(key); },
+ set: function(val){ return this.setItem(key,val); }
+ });
+ }
+ }
+
+ },
+
+ initialize:function()
+ {
+ window.external.Notify("DOMStorage/" + this._type + "/load/keys");
+ },
+
+ /*
+ The length attribute must return the number of key/value pairs currently present in the list associated with the object.
+ */
+ getLength:function()
+ {
+ if(!this.keys)
+ {
+ this.initialize();
+ }
+ return this.keys.length;
+ },
+
+ /*
+ The key(n) method must return the name of the nth key in the list.
+ The order of keys is user-agent defined, but must be consistent within an object so long as the number of keys doesn't change.
+ (Thus, adding or removing a key may change the order of the keys, but merely changing the value of an existing key must not.)
+ If n is greater than or equal to the number of key/value pairs in the object, then this method must return null.
+ */
+ key:function(n)
+ {
+ if(!this.keys)
+ {
+ this.initialize();
+ }
+
+ if(n >= this.keys.length)
+ {
+ return null;
+ }
+ else
+ {
+ return this.keys[n];
+ }
+ },
+
+ /*
+ The getItem(key) method must return the current value associated with the given key.
+ If the given key does not exist in the list associated with the object then this method must return null.
+ */
+ getItem:function(key)
+ {
+ if(!this.keys)
+ {
+ this.initialize();
+ }
+
+ var retVal = null;
+ if(this.keys.indexOf(key) > -1)
+ {
+ window.external.Notify("DOMStorage/" + this._type + "/get/" + key);
+ retVal = this._result;
+ this._result = null;
+ }
+ return retVal;
+ },
+ /*
+ The setItem(key, value) method must first check if a key/value pair with the given key already exists
+ in the list associated with the object.
+ If it does not, then a new key/value pair must be added to the list, with the given key and with its value set to value.
+ If the given key does exist in the list, then it must have its value updated to value.
+ If it couldn't set the new value, the method must raise an QUOTA_EXCEEDED_ERR exception.
+ (Setting could fail if, e.g., the user has disabled storage for the site, or if the quota has been exceeded.)
+ */
+ setItem:function(key,value)
+ {
+ if(!this.keys)
+ {
+ this.initialize();
+ }
+ window.external.Notify("DOMStorage/" + this._type + "/set/" + key + "/" + value);
+ },
+
+ /*
+ The removeItem(key) method must cause the key/value pair with the given key to be removed from the list
+ associated with the object, if it exists.
+ If no item with that key exists, the method must do nothing.
+ */
+ removeItem:function(key)
+ {
+ if(!this.keys)
+ {
+ this.initialize();
+ }
+ var index = this.keys.indexOf(key);
+ if(index > -1)
+ {
+ this.keys.splice(index,1);
+ // TODO: need sanity check for keys ? like 'clear','setItem', ...
+ window.external.Notify("DOMStorage/" + this._type + "/remove/" + key);
+ delete this[key];
+ }
+
+ },
+
+ /*
+ The clear() method must atomically cause the list associated with the object to be emptied of all
+ key/value pairs, if there are any.
+ If there are none, then the method must do nothing.
+ */
+ clear:function()
+ {
+ if(!this.keys)
+ {
+ this.initialize();
+ }
+
+ for(var n=0,len=this.keys.length; n < len;n++)
+ {
+ // TODO: do we need a sanity check for keys ? like 'clear','setItem', ...
+ delete this[this.keys[n]];
+ }
+ this.keys = [];
+ window.external.Notify("DOMStorage/" + this._type + "/clear/");
+ }
+ };
+
+ // initialize DOMStorage
+
+ Object.defineProperty( window, "localStorage",
+ {
+ writable: false,
+ configurable: false,
+ value:new DOMStorage("localStorage")
+ });
+ window.localStorage.initialize();
+
+ Object.defineProperty( window, "sessionStorage",
+ {
+ writable: false,
+ configurable: false,
+ value:new DOMStorage("sessionStorage")
+ });
+ window.sessionStorage.initialize();
+
+
+})();
+
+module.exports = null;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/0c5d9179/lib/wp7/plugin/wp7/XHRPatch.js
----------------------------------------------------------------------
diff --git a/lib/wp7/plugin/wp7/XHRPatch.js b/lib/wp7/plugin/wp7/XHRPatch.js
new file mode 100644
index 0000000..2133c93
--- /dev/null
+++ b/lib/wp7/plugin/wp7/XHRPatch.js
@@ -0,0 +1,212 @@
+
+
+(function (win, doc) {
+
+var docDomain = null;
+try {
+ docDomain = doc.domain;
+}
+catch (err)
+{
+ //console.log("caught exception trying to access document.domain");
+}
+
+if (!docDomain || docDomain.length == 0) {
+
+ var aliasXHR = win.XMLHttpRequest;
+
+ win.XMLHttpRequest = function () { };
+ win.XMLHttpRequest.noConflict = aliasXHR;
+ win.XMLHttpRequest.UNSENT = 0;
+ win.XMLHttpRequest.OPENED = 1;
+ win.XMLHttpRequest.HEADERS_RECEIVED = 2;
+ win.XMLHttpRequest.LOADING = 3;
+ win.XMLHttpRequest.DONE = 4;
+
+ win.XMLHttpRequest.prototype =
+ {
+ UNSENT: 0,
+ OPENED: 1,
+ HEADERS_RECEIVED: 2,
+ LOADING: 3,
+ DONE: 4,
+
+ isAsync: false,
+ onreadystatechange: null,
+ readyState: 0,
+ _url: "",
+ timeout: 0,
+ withCredentials: false,
+ _requestHeaders: null,
+ open: function (reqType, uri, isAsync, user, password) {
+ console.log("XMLHttpRequest.open ::: " + uri);
+
+ if (uri && uri.indexOf("http") == 0) {
+ if (!this.wrappedXHR) {
+ this.wrappedXHR = new aliasXHR();
+ var self = this;
+
+ // timeout
+ if (this.timeout > 0) {
+ this.wrappedXHR.timeout = this.timeout;
+ }
+ Object.defineProperty(this, "timeout", {
+ set: function (val) {
+ this.wrappedXHR.timeout = val;
+ },
+ get: function () {
+ return this.wrappedXHR.timeout;
+ }
+ });
+
+
+
+ if (this.withCredentials) {
+ this.wrappedXHR.withCredentials = this.withCredentials;
+ }
+ Object.defineProperty(this, "withCredentials", {
+ set: function (val) {
+ this.wrappedXHR.withCredentials = val;
+ },
+ get: function () {
+ return this.wrappedXHR.withCredentials;
+ }
+ });
+
+
+ Object.defineProperty(this, "status", { get: function () {
+ return this.wrappedXHR.status;
+ }
+ });
+ Object.defineProperty(this, "responseText", { get: function () {
+ return this.wrappedXHR.responseText;
+ }
+ });
+ Object.defineProperty(this, "statusText", { get: function () {
+ return this.wrappedXHR.statusText;
+ }
+ });
+
+ Object.defineProperty(this, "responseXML", { get: function () {
+ return this.wrappedXHR.responseXML;
+ }
+ });
+
+ this.getResponseHeader = function (header) {
+ return this.wrappedXHR.getResponseHeader(header);
+ };
+ this.getAllResponseHeaders = function () {
+ return this.wrappedXHR.getAllResponseHeaders();
+ };
+
+ this.wrappedXHR.onreadystatechange = function () {
+ self.changeReadyState(self.wrappedXHR.readyState);
+ };
+ }
+ return this.wrappedXHR.open(reqType, uri, isAsync, user, password);
+ }
+ else {
+ // x-wmapp1://app/www/page2.html
+ // need to work some magic on the actual url/filepath
+ var newUrl = uri;
+ if (newUrl.indexOf(":/") > -1) {
+ newUrl = newUrl.split(":/")[1];
+ }
+
+ if (newUrl.lastIndexOf("/") === newUrl.length - 1) {
+ newUrl += "index.html"; // default page is index.html, when call is to a dir/ ( why not ...? )
+ }
+ this._url = newUrl;
+ }
+ },
+ statusText: "",
+ changeReadyState: function (newState) {
+ this.readyState = newState;
+ if (this.onreadystatechange) {
+ this.onreadystatechange();
+ }
+ },
+ setRequestHeader: function (header, value) {
+ if (this.wrappedXHR) {
+ this.wrappedXHR.setRequestHeader(header, value);
+ }
+ },
+ getResponseHeader: function (header) {
+ return this.wrappedXHR ? this.wrappedXHR.getResponseHeader(header) : "";
+ },
+ getAllResponseHeaders: function () {
+ return this.wrappedXHR ? this.wrappedXHR.getAllResponseHeaders() : "";
+ },
+ responseText: "",
+ responseXML: "",
+ onResult: function (res) {
+ this.status = 200;
+ this.responseText = res;
+
+ Object.defineProperty(this, "responseXML", { get: function () {
+ var parser = new DOMParser();
+ return parser.parseFromString(this.responseText, "text/xml");
+ }
+ });
+ this.changeReadyState(this.DONE);
+ },
+ onError: function (err) {
+ console.log("Wrapped XHR received Error from FileAPI :: " + err);
+ this.status = 404;
+ this.changeReadyState(this.DONE);
+ },
+
+ abort: function () {
+ if (this.wrappedXHR) {
+ return this.wrappedXHR.abort();
+ }
+ },
+
+ send: function (data) {
+ if (this.wrappedXHR) {
+ return this.wrappedXHR.send(data);
+ }
+ else {
+ this.changeReadyState(this.OPENED);
+
+ var alias = this;
+
+ function fail(evt) {
+ console.log("fail :: " + JSON.stringify(evt));
+
+ alias.onError(evt.code);
+ }
+
+ function gotFile(file) {
+ console.log("got file");
+ var reader = new FileReader();
+ reader.onloadend = function (evt) {
+ console.log("Read as text");
+ alias.onResult(evt.target.result);
+ };
+ reader.readAsText(file);
+ }
+
+ function gotEntry(entry) {
+ console.log("got entry");
+ entry.file(gotFile, fail);
+ }
+
+ function gotFS(fs) {
+ console.log("got filesystem");
+ fs.root.getFile(alias._url, null, gotEntry, fail);
+ }
+
+ window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, gotFS, fail);
+
+ }
+ },
+ status: 404
+ };
+} // if doc domain
+
+// end closure wrap
+})(window, document);
+
+module.exports = null;
+