Changeset 634

Show
Ignore:
Timestamp:
01/20/08 05:17:25 (11 months ago)
Author:
oyasu..@gmail.com
Message:

Refactoring: disengaging http download code from the downloadNextDependency code path into a downloadFile method we can use independently. Brought GM_hitch closer to bind by accepting a function, not only a function name. Preparing parseScript to become reentrant. Still no functional changes.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/jhs1/chrome/chromeFiles/content/config.js

    r625 r634  
    287287  this.file = null; 
    288288  this.filename = null; 
     289  this.charset = null; 
    289290}; 
    290291 
     
    295296  this.filename = null; 
    296297  this.mimetype = null; 
    297 }; 
     298  this.charset = null; 
     299}; 
  • branches/jhs1/chrome/chromeFiles/content/scriptdownloader.js

    r625 r634  
    4444    // If loading from file, status might be zero on success 
    4545    if (this.req_.status != 200 && this.req_.status != 0) { 
    46       // NOTE: Unlocalized string 
    47       alert('Error loading user script:\n'
    48       this.req_.status + ": " + 
    49       this.req_.statusText); 
     46      // NOTE: i18n 
     47      alert("Error loading user script:\n"
     48            this.req_.status + ": " + 
     49            this.req_.statusText); 
    5050      return; 
    5151    } 
     
    7676    window.setTimeout(GM_hitch(this, "fetchDependencies"), 0); 
    7777 
    78     if(this.installing_)
     78    if (this.installing_)
    7979      this.showInstallDialog(); 
    80     }else
     80    } else
    8181      this.showScriptView(); 
    8282    } 
    8383  } catch (e) { 
    84     // NOTE: unlocalized string 
     84    // NOTE: i18n 
    8585    alert("Script could not be installed " + e); 
    8686    throw e; 
     
    104104}; 
    105105 
    106 ScriptDownloader.prototype.downloadNextDependency = function()
     106ScriptDownloader.prototype.downloadNextDependency = function()
    107107  if (this.depQueue_.length > 0) { 
    108108    var dep = this.depQueue_.pop(); 
    109     try { 
    110       var persist = Components.classes[ 
    111         "@mozilla.org/embedding/browser/nsWebBrowserPersist;1"] 
    112         .createInstance(Components.interfaces.nsIWebBrowserPersist); 
    113       persist.persistFlags = 
    114         persist.PERSIST_FLAGS_BYPASS_CACHE | 
    115         persist.PERSIST_FLAGS_REPLACE_EXISTING_FILES; //doesn't work? 
    116       var ioservice = 
    117         Components.classes["@mozilla.org/network/io-service;1"] 
    118         .getService(); 
    119       var sourceUri = ioservice.newURI(dep.url, null, null); 
    120       var sourceChannel = ioservice.newChannelFromURI(sourceUri); 
    121       sourceChannel.notificationCallbacks = new NotificationCallbacks(); 
    122  
    123       var file = getTempFile(); 
    124  
    125       var progressListener = new PersistProgressListener(persist); 
    126       progressListener.onFinish = GM_hitch(this, 
    127         "handleDependencyDownloadComplete", dep, file, sourceChannel); 
    128       persist.progressListener = progressListener; 
    129  
    130       persist.saveChannel(sourceChannel,  file); 
    131     } catch(e) { 
    132       GM_log("Download exception " + e); 
    133       this.errorInstallDependency(this.script, dep, e); 
    134     } 
     109    this.downloadFile(dep.url, "handleDependencyDownloadComplete", 
     110                      "errorInstallDependency", dep); 
    135111  } else { 
    136112    this.dependenciesLoaded_ = true; 
     
    140116 
    141117ScriptDownloader.prototype.handleDependencyDownloadComplete = 
    142 function(dep, file, channel) { 
     118function(file, channel, dep) { 
    143119  GM_log("Dependency Download complete " + dep.url); 
    144120  try { 
     
    152128    if (httpChannel.requestSucceeded) { 
    153129      dep.file = file; 
    154       dep.mimetype= channel.contentType; 
     130      if (dep.hasOwnProperty("mimetype")) 
     131        dep.mimetype = channel.contentType; 
    155132      if (channel.contentCharset) { 
    156133        dep.charset = channel.contentCharset; 
     
    158135      this.downloadNextDependency(); 
    159136    } else { 
    160       this.errorInstallDependency(this.script, dep, 
    161         "Error! Server Returned : " + httpChannel.responseStatus + ": " + 
    162         httpChannel.responseStatusText); 
     137      var error = new Error("Error! Server returned: " + 
     138                            httpChannel.responseStatus + ": " + 
     139                            httpChannel.responseStatusText); 
     140      this.errorInstallDependency(error, dep); 
    163141    } 
    164142  } else { 
     
    180158    case "file": 
    181159        var scriptScheme = ioService.extractScheme(this.uri_.spec); 
    182         return (scriptScheme == "file") 
     160        return (scriptScheme == "file"); 
    183161    default: 
    184162      return false; 
     
    192170}; 
    193171 
    194 ScriptDownloader.prototype.errorInstallDependency = function(script, dep, msg){ 
     172ScriptDownloader.prototype.errorInstallDependency = function(e, dep) { 
     173  var msg = e.message; 
    195174  GM_log("Error loading dependency " + dep.url + "\n" + msg) 
    196175  if (this.installOnCompletion_) { 
     
    226205}; 
    227206 
    228 ScriptDownloader.prototype.parseScript = function(source, uri) { 
     207ScriptDownloader.prototype.parseScript = function(source, uri, script, headers) { 
    229208  function resolveURL(url, baseurl) { 
    230209    url = ioservice.newURI(url, null, baseurl); 
     
    234213                            .getService(); 
    235214 
    236   var script = new Script(); 
    237   script.uri = uri; 
    238   script.enabled = true; 
    239   var headers = GM_parseScriptHeaders(source, { 
     215  headers = GM_parseScriptHeaders(source, { 
    240216    // verbatim string, last value only: 
    241217    name:1, 
     
    276252      return new ScriptResource(name, resolveURL(url, uri)); 
    277253    } 
    278   }); 
    279  
    280   script.name = headers.name || parseScriptName(uri); 
    281   script.namespace = headers.namespace || uri.host; 
    282   script.description = headers.description || ""; 
     254  }, headers); 
     255 
     256  if (!script) { 
     257    script = this.script = new Script(); 
     258    script.uri = uri; 
     259    script.enabled = true; 
     260    script.name = headers.name || parseScriptName(uri); 
     261    script.namespace = headers.namespace || uri.host; 
     262    script.description = headers.description || ""; 
     263  } 
    283264  script.includes = headers.include || ["*"]; 
    284265  script.excludes = headers.exclude || []; 
     
    286267  script.resources = headers.resource || []; 
    287268 
    288   this.script = script; 
    289 }; 
    290  
     269  return headers; 
     270}; 
     271 
     272/** 
     273 * Download and save url into a temporary file. On successful completion, call 
     274 * onOK(file, channel), otherwise onFail(exception). Additional arguments get 
     275 * passed on to either callback, and the this object is retained. 
     276 */ 
     277ScriptDownloader.prototype.downloadFile = function(url, onOK, onFail) { 
     278  var args = [].slice.call(arguments, 3); // trailing args for the callbacks 
     279  try { 
     280    var ioservice = 
     281      Components.classes["@mozilla.org/network/io-service;1"].getService(); 
     282    var uri = ioservice.newURI(url, null, null); 
     283 
     284    var channel = ioservice.newChannelFromURI(uri); 
     285    channel.notificationCallbacks = new NotificationCallbacks(); 
     286 
     287    var file = getTempFile(); 
     288 
     289    args.unshift(this, onOK, file, channel); 
     290    onOK = GM_hitch.apply(args); 
     291    var progressListener = new PersistProgressListener(onOK); 
     292    progressListener.persist.saveChannel(channel, file); 
     293  } catch(e) { 
     294    GM_log("Download exception " + e); 
     295    args.unshift(this, onFail, e); 
     296    onFail = GM_hitch.apply(args); 
     297    onFail(); 
     298  } 
     299
    291300 
    292301function NotificationCallbacks() { 
     
    310319 
    311320 
    312 function PersistProgressListener(persist){ 
     321function PersistProgressListener(doneCallback) { 
     322  var persist = Components.classes[ 
     323    "@mozilla.org/embedding/browser/nsWebBrowserPersist;1"] 
     324    .createInstance(Components.interfaces.nsIWebBrowserPersist); 
     325  persist.persistFlags = 
     326    persist.PERSIST_FLAGS_BYPASS_CACHE | 
     327    persist.PERSIST_FLAGS_REPLACE_EXISTING_FILES; //doesn't work? 
     328  persist.progressListener = this; 
     329 
     330  this.onFinish = doneCallback; 
    313331  this.persist = persist; 
    314   this.onFinish = function(){}; 
    315   this.persiststate = ""; 
    316332}; 
    317333 
  • branches/jhs1/chrome/chromeFiles/content/utils.js

    r625 r634  
    2727 
    2828function GM_hitch(obj, meth) { 
    29   if (!obj[meth]) { 
    30     throw "method '" + meth + "' does not exist on object '" + obj + "'"; 
     29  if (typeof meth != "function") { 
     30    if (!obj[meth]) { 
     31      throw "method '" + meth + "' does not exist on object '" + obj + "'"; 
     32    } 
     33    meth = obj[meth]; 
    3134  } 
    3235 
     
    4548    // invoke the original function with the correct this obj and the combined 
    4649    // list of static and dynamic arguments. 
    47     return obj[meth].apply(obj, args); 
     50    return meth.apply(obj, args); 
    4851  }; 
    4952}; 
     
    498501 * 
    499502 * If, instead of 1, a callback function is provided, the return value of that 
    500  * callback is becomes appended to the array instead. This callback is invoked 
     503 * callback becomes appended to the array instead. This callback is invoked 
    501504 * with two arguments: the raw header, and the array with all prior callback 
    502505 * results for this header (or the empty array).