Changeset 618

Show
Ignore:
Timestamp:
01/19/08 10:01:21 (11 months ago)
Author:
boo..@youngpup.net
Message:

Snap aa2 to trunk @617

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/aa2/src/chrome/chromeFiles/content/browser.js

    r548 r618  
    124124 */ 
    125125GM_BrowserUI.contentLoad = function(e) { 
     126  var safeWin; 
    126127  var unsafeWin; 
    127128  var href; 
     
    132133  } 
    133134 
    134   unsafeWin = e.target.defaultView.wrappedJSObject; 
    135   href = e.target.location.href; 
     135  safeWin = e.target.defaultView; 
     136  unsafeWin = safeWin.wrappedJSObject; 
     137  href = safeWin.location.href; 
    136138 
    137139  if (GM_isGreasemonkeyable(href)) { 
     
    149151  } 
    150152 
    151   if (!href.match(/\.user\.js$/)) { 
    152     return; 
    153   } 
    154  
    155   var browser = this.tabBrowser.getBrowserForDocument(e.target); 
     153  // Show the greasemonkey install banner if we are navigating to a .user.js 
     154  // file in a top-level tab. 
     155  if (href.match(/\.user\.js$/) && safeWin == safeWin.top) { 
     156    var browser = this.tabBrowser.getBrowserForDocument(safeWin.document); 
     157    this.showInstallBanner(browser); 
     158  } 
     159}; 
     160 
     161 
     162/** 
     163 * Shows the install banner across the top of the tab that is displayed when 
     164 * a user selects "show script source" in the install dialog. 
     165 */ 
     166GM_BrowserUI.showInstallBanner = function(browser) { 
    156167  var greeting = this.bundle.getString("greeting.msg"); 
    157168 
     
    565576}; 
    566577 
     578GM_BrowserUI.hideStatusImmediately = function() { 
     579  if (this.showAnimation) { 
     580    this.showAnimation.stop(); 
     581    this.showAnimation = null; 
     582  } 
     583 
     584  if (this.hideAnimation) { 
     585    this.hideAnimation.stop(); 
     586    this.hideAnimation = null; 
     587  } 
     588 
     589  if (this.autoHideTimer) { 
     590    window.clearTimeout(this.autoHideTimer); 
     591    this.autoHideTimer = null; 
     592  } 
     593 
     594  this.statusLabel.style.width = "0"; 
     595  this.statusLabel.collapsed = true; 
     596}; 
     597 
    567598GM_BrowserUI.hideStatus = function() { 
    568599  if (!this.hideAnimation) { 
  • branches/aa2/src/chrome/chromeFiles/content/menucommander.js

    r548 r618  
    2020GM_MenuCommander.prototype.registerMenuCommand = 
    2121  function(commandName, commandFunc, accelKey, accelModifiers, accessKey) { 
     22    GM_apiLeakCheck(); 
     23 
    2224    GM_log("> GM_MenuCommander.registerMenuCommand"); 
    2325 
  • branches/aa2/src/chrome/chromeFiles/content/miscapis.js

    r548 r618  
    88 
    99GM_ScriptStorage.prototype.setValue = function(name, val) { 
     10  GM_apiLeakCheck(); 
     11 
    1012  this.prefMan.setValue(name, val); 
    1113}; 
    1214 
    1315GM_ScriptStorage.prototype.getValue = function(name, defVal) { 
     16  GM_apiLeakCheck(); 
     17 
    1418  return this.prefMan.getValue(name, defVal); 
    1519}; 
     
    2024 
    2125GM_Resources.prototype.getResourceURL = function(name) { 
     26  GM_apiLeakCheck(); 
     27 
    2228  var dep = this.getDep_(name); 
    2329 
     
    4046 
    4147GM_Resources.prototype.getResourceText = function(name) { 
     48  GM_apiLeakCheck(); 
     49 
    4250  var dep = this.getDep_(name); 
    4351  return getContents(getDependencyFileURI(this.script, dep)); 
     
    6573 
    6674GM_ScriptLogger.prototype.log = function(message) { 
     75  GM_apiLeakCheck(); 
     76 
    6777  GM_log(this.prefix + message, true); 
    6878}; 
  • branches/aa2/src/chrome/chromeFiles/content/prefmanager.js

    r548 r618  
    11var GM_prefRoot = new GM_PrefManager(); 
     2 
     3GM_PrefManager.MIN_INT_32 = -0x80000000; 
     4GM_PrefManager.MAX_INT_32 = 0x7FFFFFFF; 
    25 
    36/** 
     
    5962  this.setValue = function(prefName, value) { 
    6063    var prefType = typeof(value); 
     64    var goodType = false; 
    6165 
    6266    switch (prefType) { 
    6367      case "string": 
    6468      case "boolean": 
     69        goodType = true; 
    6570        break; 
    6671      case "number": 
    67         if (value % 1 != 0) { 
    68           // NOTE: Non localised strings 
    69           throw new Error("Cannot set preference to non integral number"); 
     72        if (value % 1 == 0 && 
     73            value >= GM_PrefManager.MIN_INT_32 && 
     74            value <= GM_PrefManager.MAX_INT_32) { 
     75          goodType = true; 
    7076        } 
    7177        break; 
    72       default: 
    73         throw new Error("Cannot set preference with datatype: " + prefType); 
     78    } 
     79 
     80    if (!goodType) { 
     81      throw new Error("Unsupported type for GM_setValue. Supported types " + 
     82                      "are: string, bool, and 32 bit integers."); 
    7483    } 
    7584 
  • branches/aa2/src/chrome/chromeFiles/content/scriptdownloader.js

    r548 r618  
    3838 
    3939ScriptDownloader.prototype.handleScriptDownloadComplete = function() { 
     40  this.win_.GM_BrowserUI.refreshStatus(); 
     41  this.win_.GM_BrowserUI.hideStatusImmediately(); 
     42 
    4043  try { 
    4144    // If loading from file, status might be zero on success 
    4245    if (this.req_.status != 200 && this.req_.status != 0) { 
    43       this.win_.GM_BrowserUI.refreshStatus(); 
    44       this.win_.GM_BrowserUI.hideStatus(); 
    45  
    4646      // NOTE: Unlocalized string 
    4747      alert('Error loading user script:\n' + 
     
    8484    // NOTE: unlocalized string 
    8585    alert("Script could not be installed " + e); 
    86     this.win_.GM_BrowserUI.refreshStatus(); 
    87     this.win_.GM_BrowserUI.hideStatus(); 
    8886    throw e; 
    8987  } 
     
    219217    return; 
    220218  } 
    221   this.win_.GM_BrowserUI.hideStatus(); 
    222   this.win_.GM_BrowserUI.refreshStatus(); 
    223219  this.win_.openDialog("chrome://greasemonkey/content/install.xul", "", 
    224220                       "chrome,centerscreen,modal,dialog,titlebar,resizable", 
     
    227223 
    228224ScriptDownloader.prototype.showScriptView = function() { 
    229   this.win_.GM_BrowserUI.hideStatus(); 
    230   this.win_.GM_BrowserUI.refreshStatus(); 
    231225  this.win_.GM_BrowserUI.showScriptView(this); 
    232226}; 
  • branches/aa2/src/chrome/chromeFiles/content/utils.js

    r548 r618  
    66var GM_consoleService = Components.classes["@mozilla.org/consoleservice;1"] 
    77                        .getService(Components.interfaces.nsIConsoleService); 
     8 
     9function GM_apiLeakCheck() { 
     10  var stack = Components.stack; 
     11 
     12  do { 
     13    if (2 == stack.language) { 
     14      if ('file' != stack.filename.substr(0, 4) && 
     15          'chrome' != stack.filename.substr(0, 6)) { 
     16        throw new Error("Greasemonkey access violation"); 
     17      } 
     18    } 
     19 
     20    stack = stack.caller; 
     21  } while (stack); 
     22}; 
    823 
    924function GM_isDef(thing) { 
     
    7489 
    7590function openInEditor(aFile, promptTitle) { 
    76   var editor, editorPath; 
     91  var editor = getEditor(promptTitle); 
     92  if (!editor) { 
     93    // The user did not choose an editor. 
     94    return; 
     95  } 
     96 
    7797  try { 
    78     editorPath = GM_prefRoot.getValue("editor"); 
    79   } catch(e) { 
    80     GM_log( "Failed to get 'editor' value:" + e ); 
    81     if (GM_prefRoot.exists("editor")) { 
    82       GM_log("A value for 'editor' exists, so let's remove it because it's causing problems"); 
    83       GM_prefRoot.remove("editor"); 
    84     } 
    85     editorPath = false; 
    86   } 
     98    launchApplicationWithDoc(editor, aFile); 
     99  } catch (e) { 
     100    // Something may be wrong with the editor the user selected. Remove so that 
     101    // next time they can pick a different one. 
     102    alert("Could not launch editor:\n" + e); 
     103    GM_prefRoot.remove("editor"); 
     104    throw e; 
     105  } 
     106
     107 
     108function getEditor(promptTitle) { 
     109  var editorPath = GM_prefRoot.getValue("editor"); 
     110 
    87111  if (editorPath) { 
    88     // check whether the editor path is valid 
    89     GM_log("Try editor with path " + editorPath); 
    90     editor = Components.classes["@mozilla.org/file/local;1"] 
    91                        .createInstance(Components.interfaces.nsILocalFile); 
     112    GM_log("Found saved editor preference: " + editorPath); 
     113 
     114    var editor = Components.classes["@mozilla.org/file/local;1"] 
     115                 .createInstance(Components.interfaces.nsILocalFile); 
    92116    editor.followLinks = true; 
    93117    editor.initWithPath(editorPath); 
    94   } else { 
     118 
     119    // make sure the editor preference is still valid 
     120    if (editor.exists() && editor.isExecutable()) { 
     121      return editor; 
     122    } else { 
     123      GM_log("Editor preference either does not exist or is not executable"); 
     124      GM_prefRoot.remove("editor"); 
     125    } 
     126  } 
     127 
     128  // Ask the user to choose a new editor. Sometimes users get confused and 
     129  // pick a non-executable file, so we set this up in a loop so that if they do 
     130  // that we can give them an error and try again. 
     131  while (true) { 
     132    GM_log("Asking user to choose editor..."); 
    95133    var nsIFilePicker = Components.interfaces.nsIFilePicker; 
    96134    var filePicker = Components.classes["@mozilla.org/filepicker;1"] 
     
    102140 
    103141    if (filePicker.show() != nsIFilePicker.returnOK) { 
    104       return false; 
    105     } 
    106     editor = filePicker.file; 
    107     GM_log("User selected: " + editor.path); 
    108     GM_prefRoot.setValue("editor", editor.path); 
    109   } 
    110  
    111   if (editor.exists() && editor.isExecutable()) { 
    112     try { 
    113       GM_log("launching ..."); 
    114  
    115       var process = Components.classes["@mozilla.org/process/util;1"] 
    116                               .getService(Components.interfaces.nsIProcess); 
    117       process.init(editor); 
    118       process.run(false, // non-blocking 
    119                   [aFile.path], 
    120                   1); // number of arguments in second param 
    121       return true; 
    122     } catch (e) { 
    123       GM_log("Failed to launch editor: " + e, true); 
    124     } 
     142      // The user canceled, return null. 
     143      GM_log("User canceled file picker dialog"); 
     144      return null; 
     145    } 
     146 
     147    GM_log("User selected: " + filePicker.file.path); 
     148 
     149    if (filePicker.file.exists() && filePicker.file.isExecutable()) { 
     150      GM_prefRoot.setValue("editor", filePicker.file.path); 
     151      return filePicker.file; 
     152    } else { 
     153      // TODO: i18n 
     154      alert("Please pick an executable application to use to edit user " + 
     155            "scripts."); 
     156    } 
     157  } 
     158
     159 
     160function launchApplicationWithDoc(appFile, docFile) { 
     161  var xulRuntime = Components.classes["@mozilla.org/xre/app-info;1"] 
     162                             .getService(Components.interfaces.nsIXULRuntime); 
     163  // See Mozilla bug: https://bugzilla.mozilla.org/show_bug.cgi?id=411819 
     164  // TODO: remove this when nsIMIMEInfo works on windows again. 
     165  if (xulRuntime.OS.toLowerCase().substring(0, 3) == "win") { 
     166    var process = Components.classes["@mozilla.org/process/util;1"] 
     167                            .createInstance(Components.interfaces.nsIProcess); 
     168    process.init(appFile); 
     169    process.run(false, // blocking 
     170                [docFile.path], // args 
     171                1); // number of args 
    125172  } else { 
    126     GM_log("Editor '" + editorPath + "' does not exist or isn't executable. " + 
    127            "Put it back, check the permissions, or just give up and reset " + 
    128            "editor using about:config", true); 
    129   } 
    130   return false; 
    131 }; 
     173    var mimeInfoService = 
     174        Components.classes["@mozilla.org/uriloader/external-helper-app-service;1"] 
     175                  .getService(Components.interfaces.nsIMIMEService); 
     176    var mimeInfo = mimeInfoService.getFromTypeAndExtension( 
     177        "application/x-userscript+javascript", "user.js" ); 
     178    mimeInfo.preferredAction = mimeInfo.useHelperApp; 
     179    mimeInfo.preferredApplicationHandler = appFile; 
     180    mimeInfo.launchWithFile(docFile); 
     181  } 
     182
    132183 
    133184function parseScriptName(sourceUri) { 
  • branches/aa2/src/chrome/chromeFiles/content/xmlhttprequester.js

    r590 r618  
    1313// text/xml and we can't support that 
    1414GM_xmlhttpRequester.prototype.contentStartRequest = function(details) { 
     15  GM_apiLeakCheck(); 
     16 
    1517  // don't actually need the timer functionality, but this pops it 
    1618  // out into chromeWindow's thread so that we get that security 
  • branches/aa2/src/components/greasemonkey.js

    r548 r618  
    313313 
    314314  openInTab: function(unsafeContentWin, url) { 
     315    GM_apiLeakCheck(); 
     316 
    315317    var unsafeTop = new XPCNativeWrapper(unsafeContentWin, "top").top; 
    316318