diff --git a/af.js b/af.js index e4b9f8a..606d77d 100755 --- a/af.js +++ b/af.js @@ -192,34 +192,36 @@ var items= { } }, 'new' : function(settings){ - var object = {}; - if(settings.hasOwnProperty('constructor')){ - object= new settings.constructor(engine); - }else if(settings.builder && settings.nameSpace){ - engine[settings.nameSpace]= {}; - object= function(){ - return settings.builder(engine[settings.nameSpace], this.arguments); - }; - }else if(settings.builder){ - object= settings.builder; - }else{ - object= settings.object; - } + engine.deviceReady.then(function(){ + var object = {}; + if(settings.hasOwnProperty('constructor')){ + object= new settings.constructor(engine); + }else if(settings.builder && settings.nameSpace){ + engine[settings.nameSpace]= {}; + object= function(){ + return settings.builder(engine[settings.nameSpace], this.arguments); + }; + }else if(settings.builder){ + object= settings.builder; + }else{ + object= settings.object; + } - if(settings.name && !items[settings.name]) - items[settings.name]= object; - else - $$.console.error("No or ilegall name!"); - if(settings._init){ - if(settings.nameSpace) - settings._init(engine[settings.nameSpace], settings.object); - else - settings._init(settings.object); - } - if(settings.nameSpace) - return engine[settings.nameSpace]; - return null; - }, + if(settings.name && !items[settings.name]) + items[settings.name]= object; + else + $$.console.error("No or ilegall name!"); + if(settings._init){ + if(settings.nameSpace) + settings._init(engine[settings.nameSpace], settings.object); + else + settings._init(settings.object); + } + if(settings.nameSpace) + return engine[settings.nameSpace]; + return null; + }); + }, queue : { push : function(object){ var push= function(){ @@ -353,13 +355,15 @@ var prepareScope= function(item){ 'module' : { value : function(name, dependencies, f){ var request= new $$.Promise(function(success, failure){ - if(dependencies.length > 0){ - scope.properties.modules.on('available', dependencies).then(function(){ - f(scope.properties, success, failure); - }); - }else{ - f(scope.properties, success, failure); - } + engine.deviceReady.then(function(){ + if(dependencies.length > 0){ + scope.properties.modules.on('available', dependencies).then(function(){ + f(scope.properties, success, failure); + }); + }else{ + f(scope.properties, success, failure); + } + }); }); scope.modules.push(request); request.then(function(value){ @@ -573,20 +577,22 @@ var engine = { push : function(scope){ if(!this.isRunning){ this.isRunning= true; - if(settings.renderMode == 'default'){ - if(scope.modules.length > 0){ - $$.Promise.all(scope.modules).then(function(){ + engine.deviceReady.then(function(){ + if(settings.renderMode == 'default'){ + if(scope.modules.length > 0){ + $$.Promise.all(scope.modules).then(function(){ + scope.thread.apply(scope.properties, [scope]); + }); + }else{ scope.thread.apply(scope.properties, [scope]); - }); - }else{ - scope.thread.apply(scope.properties, [scope]); + } } - } - if(this.queue.length > 0){ - var n= this.queue[0]; this.queue.shift(); - this.push(n); - } + if(this.queue.length > 0){ + var n= this.queue[0]; this.queue.shift(); + this.push(n); + } + }.bind(this)); this.isRunning= false; }else{ this.queue.push(scope); @@ -597,6 +603,13 @@ var engine = { lastAddonComId : 0, pushListeners : [], launchQueue : [], + deviceReady : new Promise(function(ready){ + if($$.cordova){ + $$.document.addEventListener('deviceready', ready, false); + }else{ + ready(); + } + }), exit : function(){} }; @@ -609,7 +622,7 @@ if ($$.navigator && !$$.importScripts){ // Mozilla platform= (((platform.indexOf('Gecko/') > -1) && 'Gecko '+platform.substring(platform.indexOf('rv:')+3, platform.indexOf(')')) ) || false) || // Google / Apple / Opera - (((platform.indexOf('AppleWebKit') > -1) && platform.substring(platform.indexOf('AppleWebKit'), platform.lastIndexOf('(')-1).replace(/\//, ' ')) || false) || + (((platform.indexOf('AppleWebKit') > -1) && (platform= platform.substring(platform.indexOf('AppleWebKit'))) && platform.substring(0, platform.indexOf('(')-1).replace(/\//, ' ')) || false) || // Microsoft (((platform.indexOf('Trident/') > -1) && platform.substring(platform.indexOf('Trident/'), platform.indexOf(';', platform.indexOf('Trident/'))).replace(/\//, ' ')) || false) || // Unknown @@ -623,7 +636,7 @@ if ($$.navigator && !$$.importScripts){ // Mozilla platform= (((platform.indexOf('Gecko/') > -1) && 'Gecko '+platform.substring(platform.indexOf('rv:')+3, platform.indexOf(')')) ) || false) || // Google / Apple / Opera - (((platform.indexOf('AppleWebKit') > -1) && platform.substring(platform.indexOf('AppleWebKit'), platform.lastIndexOf('(')-1).replace(/\//, ' ')) || false) || + (((platform.indexOf('AppleWebKit') > -1) && (platform= platform.substring(platform.indexOf('AppleWebKit'))) && platform.substring(0, platform.indexOf('(')-1).replace(/\//, ' ')) || false) || // Microsoft (((platform.indexOf('Trident/') > -1) && platform.substring(platform.indexOf('Trident/'), platform.indexOf(';', platform.indexOf('Trident/'))).replace(/\//, ' ')) || false) || // Unknown diff --git a/modules/classes.js b/modules/classes.js index 5a0bab8..9d23620 100755 --- a/modules/classes.js +++ b/modules/classes.js @@ -14,7 +14,17 @@ $('new')({ this.busy= false; this.step= 0; this.status= 'notstarted'; - } + }, + URL : function(urlString){ + this._h= ''; + this._p= ''; + this._pa= ''; + this._u= ''; + this._pat= ''; + this._hr= urlString; + + this.parse(urlString); + } }, _init : function(me){ "use strict"; @@ -60,7 +70,7 @@ $('new')({ } }; me.AsyncLoop.prototype= { - 'while' : function(condition, $){ + 'while' : function(condition){ this.busy= true; var loop= this; @@ -141,5 +151,99 @@ $('new')({ next(); } }; + + me.URL.prototype= { + parse : function(urlString){ +// parse URL + if(urlString.indexOf('//')){ + this._p= urlString.substring(0, urlString.indexOf('//')); + urlString.substr(urlString.indexOf('//')+2); + } + + var hostPart= urlString.substring(0, urlString.indexOf('/')); + urlString= urlString.substr(urlString.indexOf('/')); + if(hostPart.indexOf('@')){ + var userPart= hostPart.split('@')[0]; + this._h= hostPart.split('@')[1]; + this._u= userPart.split(':')[0]; + this._pa= userPart.split(':')[1] || ''; + } + this._h= hostPart; + this._pat= urlString; + }, + + asemble : function(){ + var path= ''; + if(this._p !== '') + path+= this._p+'//'; + + if(this._u !== ''){ + path+= this._u; + path+= (this._pa !== '') ? ':'+this._pa+'@' : '@'; + } + + if(this._h) + path+= this._h; + + if(this._pat) + path+= this._pat; + + this._hr= path; + }, + + get protocol(){ + return this._p; + }, + + set protocol(value){ + this._p=value; + this.asemble(); + }, + + get host(){ + return this._h; + }, + + set host(value){ + this._h= value; + this.asemble(); + }, + + get username(){ + return this._u; + }, + + set username(value){ + this._u= value; + this.asemble(); + }, + + get password(){ + return this._pa; + }, + + set password(value){ + this._pa= value; + this.asemble(); + }, + + get path(){ + return this._pat; + }, + + set path(value){ + this._pat= value; + this.asemble(); + }, + + get href(){ + return this._hr; + }, + + set href(value){ + this._hr= value; + this.parse(this._hr); + } + }; } }); diff --git a/modules/connections.js b/modules/connections.js index 9cd93a0..30a8783 100755 --- a/modules/connections.js +++ b/modules/connections.js @@ -65,6 +65,7 @@ $('new')({ }; var Promise = $('classes').Promise; + var URL= $('classes').URL; me.classes.Socket.prototype= { get url(){ return this._url; @@ -156,12 +157,13 @@ $('new')({ }); }, - download : function(url, notDefaultHost){ + download : function(url){ var self= this; return new $$.Promise(function(success, failed){ - var request= new OAuthRequest('GET', url, null, self, notDefaultHost); + var request= new OAuthRequest('GET', url, null, self); request.responseType= 'blob'; + request.addQuery= false; var response= request.send(); response.then(function(data){ @@ -170,7 +172,23 @@ $('new')({ response.catch(failed); }); }, - + + upload : function(url, blob, onprogress){ + var self= this; + + return new $$.Promise(function(success, failed){ + var data= new $$.FormData(); + data.append('media', blob); + var request= new OAuthRequest('POST', url, data, self); + request.useDataInSignature= false; + request.encodeData= false; + request.addQuery= false; + request.send(onprogress).then(function(data){ + success(data.responseText); + }, failed); + }); + }, + requestToken : function(url, callback_url){ var self= this; @@ -180,7 +198,7 @@ $('new')({ var response= request.send(); response.then(function(data){ - var data= data.responseText.split('&'); + data= data.responseText.split('&'); self._token= data[0].split('=')[1]; self._tokenSecred= data[1].split('=')[1]; @@ -200,7 +218,7 @@ $('new')({ var response= request.send(); response.then(function(data){ - var data= data.responseText.split('&'); + data= data.responseText.split('&'); self._token= data[0].split('=')[1]; self._tokenSecred= data[1].split('=')[1]; @@ -225,11 +243,14 @@ $('new')({ } }; - var OAuthRequest= function(method, url, data, client, notDefaultHost){ + var OAuthRequest= function(method, url, data, client){ this._client= client; this._data= data; this._method= method; this.responseType= ''; + this.useDataInSignature= true; + this.encodeData= true; + this.addQuery= true; this.oauthHeader= { 'oauth_consumer_key' : client._key, 'oauth_nonce' : createOAuthNonce(), @@ -237,43 +258,55 @@ $('new')({ 'oauth_timestamp' : $$.Date.now().toString().substr(0, 10), 'oauth_version' : '1.0' }; - - if(!notDefaultHost) - this._url= client._host + url; - else - this._url= url; - + this.headers= {}; + url= new URL(url); + if(url.host === ''){ + url.host= this._client._host; + } + this._url= url.href; if(client._token !== '') this.oauthHeader.oauth_token= client._token; }; OAuthRequest.prototype= { - send : function(){ + send : function(onUploadProgress, onDownloadProgress){ var self= this; var dataGet= ''; var dataPost= ''; var xhr= new $$.XMLHttpRequest(this._client._options); - this.oauthHeader.oauth_signature= createOAuthSignature(this.oauthHeader, this._data, this._method, this._url, this._client._secred, this._client._tokenSecred); + this.oauthHeader.oauth_signature= createOAuthSignature(this.oauthHeader, (this.useDataInSignature ? this._data : null), this._method, this._url, this._client._secred, this._client._tokenSecred); - if(this._data){ + if(this._data && !(this._data instanceof $$.FormData)){ $$.Object.keys(this._data).forEach(function(item){ if(dataGet.length > 0) dataGet+= '&'; if(dataPost.length > 0) dataPost+= '&'; dataPost+= item + '=' + self._data[item]; dataGet+= item + '=' + encode(self._data[item]); - }); - } + }); + }else if(this._data instanceof $$.FormData){ + dataPost= this._data; + } - if(dataGet !== '') + if(dataGet !== '' && this.addQuery) xhr.open(this._method, this._url + '?' + dataGet, true); else xhr.open(this._method, this._url, true); xhr.setRequestHeader('Authorization', createOAuthHeader(this.oauthHeader)); + Object.keys(this.headers).forEach(function(key){ + xhr.setRequestHeader(key, this.headers[key]); + }.bind(this)); + if(this.responseType !== '') xhr.responseType= this.responseType; + + if(onUploadProgress) + xhr.upload.onprogress= onUploadProgress; + + if(onDownloadProgress) + xhr.onprogress= onDownloadProgress; return new $$.Promise(function(success, failed){ xhr.onreadystatechange= function(){ @@ -290,9 +323,11 @@ $('new')({ } } }; + + console.log(self._url); if(self._method == 'POST') - xhr.send(dataGet); + xhr.send((this.encodeData ? dataGet : dataPost)); else xhr.send(); }); diff --git a/modules/hashController.js b/modules/hashController.js index 9cebd90..cedc0ea 100755 --- a/modules/hashController.js +++ b/modules/hashController.js @@ -12,31 +12,35 @@ $('new')({ }; // Classes - var HashEvent= function(type, path){ + var HashEvent= function(type, path, fullPath){ this.type= type; this.path= path; + this.fullPath= fullPath; this.trigger= function(count){ var path= this.path; + var fullPath= this.fullPath; if(this.type == HashEvent.ADD){ engine.hash.actions.forEach(function(item){ if(item.path == path && item.enter && (!item.persistent || !item.active)){ - item.enter(path); + item.enter(fullPath); if(item.persistent) item.active= true; } }); }else if(this.type == HashEvent.LOST){ + var old= ""; + engine.hash.actions.forEach(function(item){ if(item.path == path && item.exit){ if(!item.persistent || count == 1){ - item.exit(path); + item.exit(fullPath); if(item.persistent){ - var old= path.split('/'); + old= path.split('/'); old.pop(); delete engine.hash.overrides[old.join('/')]; item.active= false; } }else{ - var old= path.split('/'); + old= path.split('/'); old.pop(); engine.hash.overrides[old.join('/')]= path; } @@ -52,10 +56,12 @@ $('new')({ HashEvent.LOST= 1; $$.addEventListener('hashchange', function(){ + var hashPath= null; + if($$.location.hash === "") - var hashPath= ('#!/').split('/'); + hashPath= ('#!/').split('/'); else - var hashPath= $$.location.hash.split('/'); + hashPath= $$.location.hash.split('/'); // check hash path if(hashPath[0] != '#!'){ @@ -73,16 +79,17 @@ $('new')({ // find lost elements var difference= false; var path= ''; + var fullPath= '/' + engine.hash.path.join('/'); for(var i= 0; i < engine.hash.path.length; i++){ path+= '/' + engine.hash.path[i]; if(difference) - events_lost.push(new HashEvent(HashEvent.LOST, path)); + events_lost.push(new HashEvent(HashEvent.LOST, path, fullPath)); else if(engine.hash.path[i] == hashPath[i]) continue; else if(engine.hash.path[i] != hashPath[i]){ difference= true; - events_lost.push(new HashEvent(HashEvent.LOST, path)); + events_lost.push(new HashEvent(HashEvent.LOST, path, fullPath)); } } @@ -100,17 +107,18 @@ $('new')({ // find new elements path= ''; + fullPath= '/' + hashPath.join('/'); difference= false; - for(var i= 0; i < hashPath.length; i++){ + for(i= 0; i < hashPath.length; i++){ path+= '/' + hashPath[i]; if(difference) - events_add.push(new HashEvent(HashEvent.ADD, path)); + events_add.push(new HashEvent(HashEvent.ADD, path, fullPath)); else if(hashPath[i] == engine.hash.path[i]) continue; else if(hashPath[i] != engine.hash.path[i]){ difference= true; - events_add.push(new HashEvent(HashEvent.ADD, path)); + events_add.push(new HashEvent(HashEvent.ADD, path, fullPath)); } }