home *** CD-ROM | disk | FTP | other *** search
- // This file contains the minimum set of scripts needed to boot Feedly. By boot we mean start, check version, if necessary
- // download and expand app and load the application. It is important to keep the boot to the very minimum because
- // we can not auto-update the boot.
-
- // ---------------------------------------------------------------------------------------------
- // OBSERVABLE
- // ---------------------------------------------------------------------------------------------
- function createObservable( id )
- {
- // private variables and methods ----------------------------
- var fObservers = []
-
- // public interface -----------------------------------------
- var that = {};
- that.id = id;
-
- that.registerObserver = function( obsObj )
- {
- if (fObservers.indexOf(obsObj) >= 0) {
- return
- }
- // BDH: that.$debug( "Registering observer for:" + id + " has " + fObservers.length + " observers. Hint: " + obsObj.id );
- fObservers.push(obsObj)
- }
-
- that.unregisterObserver = function( obsObj )
- {
- ///D that.$debug( "unregistering observer for:" + that.id + " -- channel: " + getChannelId(obsObj) );
- var idx = fObservers.indexOf(obsObj)
- if (idx < 0) {
- return
- }
- fObservers.splice(idx,1)
- }
-
- that.removeAllObservers = function ()
- {
- fObservers = []
- }
-
- that.fire = function ( aspect,a1,a2,a3,a4,a5,a6,a7,a8 ) // , arg1 , ..., argN
- {
- // Are there any observers?
- if( fObservers.length == 0 ) {
- return
- }
- // copy list of observers, so we don't mutate while we loop
- var observers = new Array()
- for(var oI in fObservers) {
- observers.push ( fObservers [oI] )
- }
-
- // The observer list may change as it fire notifications. Make sure that
- // we take this into account
- // Iterate through list of observers
- for( var i=0; i < observers.length; i++ )
- {
- try
- {
- // Notify each observer
- var obs = observers[i]
-
- if (fObservers.indexOf(obs) < 0) {
- continue
- }
-
- // 1. check if the aspect is a property of observer
- if( obs[aspect] != null )
- {
- // Call this method; here we don't pass aspect
- obs[aspect].call (obs,a1,a2,a3,a4,a5,a6,a7,a8);
- continue;
- }
-
- // 2. check generic onEvent method
- if (obs.onEvent != null)
- {
- // generic aspect: 'onChanged'
- obs.onChanged.call ( obs, aspect,a1,a2,a3,a4,a5,a6,a7,a8 )
- continue;
- }
- // 3. It's a function
- if ( typeof( obs ) == "function" )
- {
- obs.call ( obs, aspect,a1,a2,a3,a4,a5,a6,a7,a8 )
- continue;
- }
- }
- catch( e )
- {
- // ignore
- that.$debug( devhd.utils.ExceptionUtils.formatError( "notify observer", e ) + ". Hint about observer:" + observers[ i ].id + "." + aspect );
- // that.unregisterObserver( observers[i] );
- }
- }
- // done
- };
-
- that.toString = function ()
- {
- return "[service:" + this.id + "]"
- }
-
- that.$debug = function (msg)
- {
- $debug( "[" + this.id + "] " + msg)
- }
- return that;
- };
-
-
- function createNetworkStack( id )
- {
- var HTTP_MAX_TIMEOUT = 60 * 1000; // 60 seconds
-
- var that = createObservable (id)
-
- /////////////////////////////////////////////////
- // HTTP/XML COMMUNICATION FACILITIES
- /////////////////////////////////////////////////
- that.get = function( url, onCompleteFunction, onErrorFunction, contentType )
- {
- var timeoutTimer = null;
-
- function onCompleteHandler()
- {
- try
- {
- ///D that.$debug( "get completed:" + request.status )
-
- // has this request already timed out?
- if( timeoutTimer == null )
- return; // if so there is nothing to be done
-
- // cancel timeout timer
- that.clearTimeout( timeoutTimer );
- timeoutTimer = null;
-
- if( request.status < 200 || request.status >=300 )
- {
- onErrorFunction.call( this, request.status, request.statusMessage );
- }
- else
- {
- if( contentType == "text/xml" )
- {
- var responseXML = request.responseXML;
- onCompleteFunction.call( this, responseXML );
-
- }
- else
- {
- var responseText = request.responseText;
-
- // try to see if there is a "data-version" header associated with the response
- var dataVersion = request.getResponseHeader( "data-version" );
-
- onCompleteFunction.call( this, responseText, dataVersion );
- }
- }
- }
- catch( e )
- {
- that.$debug( "Javascript exception while completing get:" + e.name + " - " + e.message + " -- " + e.fileName + " -- " + e.lineNumber )
- onErrorFunction.call( this, -1, "Javascript Exception: " + e.name + " - " + e.message );
- }
- }
-
- function onErrorHandler()
- {
- ///D that.$debug( "get onErrorHandler:" + url + " -- " + timeoutTimer );
-
- // has this request already timed out?
- if( timeoutTimer == null )
- return; // if so there is nothing to be done
-
- // cancel timeout timer
- that.clearTimeout( timeoutTimer );
- timeoutTimer = null;
-
- var stat, statMsg;
-
- try
- {
- stat = request.status;
- statMsg = request.statusMessage;
- }
- catch( e )
- {
- stat = -3;
- statMsg = "data unavailable";
- }
-
- onErrorFunction.call( this, stat, statMsg );
- }
-
- try
- {
- var request = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance();
-
- // QI the object to nsIDOMEventTarget to set event handlers on it:
- request.QueryInterface(Components.interfaces.nsIDOMEventTarget);
- request.addEventListener( "load", onCompleteHandler, false );
- request.addEventListener( "error", onErrorHandler, false );
-
- // QI it to nsIXMLHttpRequest to open and send the request:
- request.QueryInterface(Components.interfaces.nsIXMLHttpRequest);
- request.open("GET", url, true);
- request.send(null);
-
- // set a timeout of 30 seconds
- timeoutTimer = that.setTimeout( function()
- {
- timeoutTimer = null;
- onErrorFunction.call( this, -2, "request timedout" );
- },
- HTTP_MAX_TIMEOUT
- );
- }
- catch( e )
- {
- that.$debug( "Javascript exception while executing get:" + e.name + " - " + e.message )
- onErrorFunction.call( this, -1, "Javascript Exception: " + e.name + " - " + e.message );
- }
- }
-
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////
- // Streets Timer Facility
- ///////////////////////////////////////////////////////////////////////////////////////////////////
- var nextTimerID = 1
- var timers = {}
-
- function addTimer ( aTimer, kind )
- {
- var id = kind + nextTimerID++
- timers [ id ] = aTimer
- // that.$debug("added " + id)
- return id
- }
-
- function clearTimer ( id )
- {
- var t = timers [id]
- if (t) {
- t.cancel()
- delete timers[id]
- // that.$debug("cleared " + id)
- return true
- }
- return false
- }
-
- var Timer = Components.classes["@mozilla.org/timer;1"];
- var nsITimer = Components.interfaces.nsITimer;
-
- that.setTimeout = function( callbackFunc, delay )
- {
- var aTimer = Timer.createInstance(nsITimer);
- var timerId = addTimer(aTimer,"timeout.oneshot.")
- aTimer.init( { observe: function() {
- clearTimer (timerId)
- callbackFunc.call( this );
- }
- },
- delay,
- nsITimer.TYPE_ONE_SHOT
- );
-
- return timerId;
- }
-
- that.clearTimeout = function( id )
- {
- return clearTimer( id );
- }
-
- that.setInterval = function( callbackFunc, delay )
- {
- var aTimer = Timer.createInstance(nsITimer);
- var timerId = addTimer ( aTimer,"interval.slack." )
-
- aTimer.init( { observe: function()
- {
- callbackFunc.call( this );
- } },
- delay,
- nsITimer.TYPE_REPEATING_SLACK
- );
- return timerId;
- }
-
- that.clearInterval = function( id )
- {
- return clearTimer( id );
- }
-
- that.setCookieString = function( uri, cookieString )
- {
- var cookieManager = Components.classes["@mozilla.org/cookiemanager;1"]
- .getService( Components.interfaces.nsICookieManager );
-
- var ioService = Components.classes["@mozilla.org/network/io-service;1"]
- .getService(Components.interfaces.nsIIOService);
-
- var cookieService = Components.classes["@mozilla.org/cookieService;1"]
- .getService(Components.interfaces.nsICookieService);
-
- if( ioService == null || cookieManager == null )
- return;
-
- var cookieURI = ioService.newURI( uri, null, null);
-
- cookieService.setCookieString( cookieURI, null, cookieString , null);
- }
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////
- // Content download capabilities
- ///////////////////////////////////////////////////////////////////////////////////////////////////
-
- /**
- * The download listener.
- *
- * @param {Object} completeFunc
- * @param {Object} errorFunc
- */
-
- function Downloader (persist, httpChannel, completeFunc, errorFunc ) {
- this.persist = persist
- this.persist.progressListener = this
- this.httpChannel = httpChannel
- this.completeFunc = completeFunc
- this.errorFunc = errorFunc;
- }
-
- Downloader.prototype = {
- saveTo: function ( localURI ) {
- this.persist.saveChannel(this.httpChannel,localURI);
- },
- cancelSave: function () {
- this.persist.cancelSave();
- },
- setTimeoutTimer: function (aTimer) {
- this.aTimer = aTimer
- },
- QueryInterface: function(aIID)
- {
- if( aIID.equals(Components.interfaces.nsIWebProgressListener) ||
- aIID.equals(Components.interfaces.nsISupportsWeakReference) ||
- aIID.equals(Components.interfaces.nsISupports))
- return this;
- throw Components.results.NS_NOINTERFACE;
- },
- onLocationChange: function (webProgress , request , location )
- {
- },
- onProgressChange: function ( webProgress , request , curSelfProgress , maxSelfProgress, curTotalProgress, maxTotalProgress )
- {
- },
- onSecurityChange: function ( webProgress , request , state )
- {
- },
- onStatusChange: function (webProgress, request, status, message )
- {
- },
- onStateChange: function(aProgress, aRequest, aFlag, aStatus)
- {
- if(aFlag & Components.interfaces.nsIWebProgressListener.STATE_START)
- {
- that.$debug("Start download of " + this.httpChannel.URI.spec)
- }
- else if (aFlag & Components.interfaces.nsIWebProgressListener.STATE_STOP)
- {
- var majorStatus = 0, status = 0
- // if stats != 0, then we don't have http status anyway
- if (aStatus == 0) {
- status = this.httpChannel.responseStatus
- majorStatus = Math.floor(status/100)
- }
- clearTimer ( this.aTimer );
-
- that.$debug("Finished download of " + this.httpChannel.URI.spec + " [" + status + "," + aStatus.toString(16) + "]")
-
- if ( (majorStatus == 2 || majorStatus == 3) && aStatus == 0) {
- if (this.completeFunc) {
- that.setTimeout(this.completeFunc,0)
- }
- } else {
- if (this.errorFunc) {
- that.setTimeout(this.errorFunc,0);
- }
- }
- }
- }
- }
-
- /**
- * The actual download hook.
- * @param {Object} remoteLocation
- * @param {Object} localLocation
- * @param {Object} onComplete
- * @param {Object} onError
- */
- that.download = function( remoteLocation, localLocation, onComplete, onError )
- {
- var ioService = Components.classes["@mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService);
- var persist = Components.classes['@mozilla.org/embedding/browser/nsWebBrowserPersist;1']
- .createInstance(Components.interfaces.nsIWebBrowserPersist);
-
- persist.persistFlags = Components.interfaces.nsIWebBrowserPersist.PERSIST_FLAGS_AUTODETECT_APPLY_CONVERSION
- | Components.interfaces.nsIWebBrowserPersist.PERSIST_FLAGS_REPLACE_EXISTING_FILES
- | Components.interfaces.nsIWebBrowserPersist.PERSIST_FLAGS_BYPASS_CACHE ;
-
- var remoteURI = ioService.newURI(remoteLocation, null, null);
- var localURI = ioService.newURI(localLocation, null, null);
- var channel = ioService.newChannelFromURI( remoteURI );
-
- var downloader = new Downloader ( persist, channel.QueryInterface(Components.interfaces.nsIHttpChannel),
- onComplete , onError )
- // note: for some reason doing this from inside the callbacks in the
- // Downloader does not work - the http channel always aborts !!
- downloader.setTimeoutTimer( that.setTimeout(function() { downloader.cancelSave() },HTTP_MAX_TIMEOUT ) )
- // start it
- downloader.saveTo( localURI )
- // this way you can save cancelSave
- return downloader;
- }
-
-
- // File helper
- var PERMS_DIRECTORY = 0755;
-
- that.getFile = function( path, relativePath )
- {
- var obj = Components.classes["@mozilla.org/file/local;1"].
- createInstance(Components.interfaces.nsILocalFile);
- obj.initWithPath( path );
- if( relativePath != null )
- {
- var parts = relativePath.split( "/" );
- for( var i = 0; i < parts.length; i++ )
- obj.append( parts[ i ] );
- }
-
- if( obj.exists() == false )
- obj.create( Components.interfaces.nsILocalFile.NORMAL_FILE_TYPE, PERMS_DIRECTORY );
-
- return obj;
- }
-
-
-
- that.getDir = function( path, relativePath )
- {
- var obj = Components.classes["@mozilla.org/file/local;1"].
- createInstance(Components.interfaces.nsILocalFile);
- obj.initWithPath( path );
- if( relativePath != null )
- {
- var parts = relativePath.split( "/" );
- for( var i = 0; i < parts.length; i++ )
- obj.append( parts[ i ] );
- }
-
- if( obj.exists() == false )
- obj.create( Components.interfaces.nsILocalFile.DIRECTORY_TYPE, PERMS_DIRECTORY );
-
- return obj;
- }
-
- that.removeDir = function( path, relativePath )
- {
- var obj = Components.classes["@mozilla.org/file/local;1"].
- createInstance(Components.interfaces.nsILocalFile);
- obj.initWithPath( path );
- if( relativePath != null )
- {
- var parts = relativePath.split( "/" );
- for( var i = 0; i < parts.length; i++ )
- obj.append( parts[ i ] );
- }
-
- if( obj.exists() == true )
- obj.remove( true );
- }
-
-
- that.extractZipFile = function( zipFile, targetLocation )
- {
- ///D that.$debug( "received request to extract zip file into: " + targetLocation );
-
- var zipReader = Components.classes["@mozilla.org/libjar/zip-reader;1"]
- .createInstance(Components.interfaces.nsIZipReader);
-
- if( zipReader.init != null ) // FF2
- {
- zipReader.init( zipFile );
- zipReader.open();
-
- // create directories first
- var entries = zipReader.findEntries("*/");
- while (entries.hasMoreElements())
- {
- var entry = entries.getNext().QueryInterface(Components.interfaces.nsIZipEntry);
-
- // getDir will create the directory if it does not exist
- var target = that.getDir( targetLocation, entry.name );
- }
-
- entries = zipReader.findEntries( "*" );
- while( entries.hasMoreElements() )
- {
- var entry = entries.getNext().QueryInterface( Components.interfaces.nsIZipEntry );
-
- var entryName = new String( entry.name );
- if( entryName.lastIndexOf( "/" ) == entryName.length - 1 )
- continue; // skip directories
-
- var targetFile = that.getFile( targetLocation, entry.name );
- zipReader.extract(entry.name, targetFile);
- }
- zipReader.close();
- }
- else //FF3
- {
- zipReader.open( zipFile );
-
- // create directories first
- var entryNames = zipReader.findEntries("*/");
- while (entryNames.hasMore())
- {
- // getDir will create the directory if it does not exist
- var target = that.getDir( targetLocation, entryNames.getNext() );
- }
-
- entryNames = zipReader.findEntries( "*" );
- while( entryNames.hasMore() )
- {
- var entryName = entryNames.getNext();
-
- if( entryName.lastIndexOf( "/" ) == entryName.length - 1 )
- continue; // skip directories
-
- var targetFile = that.getFile( targetLocation, entryName );
- zipReader.extract( entryName, targetFile);
- }
- zipReader.close();
- }
- }
-
- //
- return that;
- }
-
-