Changeset 697

Show
Ignore:
Timestamp:
03/17/08 05:56:58 (9 months ago)
Author:
ma..@jesperkristensen.dk
Message:

create branch for extension manager like manage UI

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/manage-ui/src/chrome.manifest

    r492 r697  
    11content    greasemonkey    chrome/chromeFiles/content/ 
     2skin       greasemonkey    classic/1.0  chrome/chromeFiles/skin/ 
    23overlay    chrome://browser/content/browser.xul    chrome://greasemonkey/content/browser.xul 
    34overlay    chrome://songbird/content/xul/mainScriptsOverlay.xul    chrome://greasemonkey/content/browser.xul 
  • branches/manage-ui/src/chrome/chromeFiles/content/browser.js

    r694 r697  
    541541 
    542542GM_BrowserUI.newUserScript = function() { 
    543   var windowWatcher = Components 
    544     .classes["@mozilla.org/embedcomp/window-watcher;1"] 
    545     .getService(Components.interfaces.nsIWindowWatcher); 
    546   windowWatcher.openWindow( 
    547     window, "chrome://greasemonkey/content/newscript.xul", null, 
    548     "chrome,dependent,centerscreen,resizable,dialog", null 
    549   ); 
     543  GM_openNewUserScriptDialog(); 
    550544}; 
    551545 
  • branches/manage-ui/src/chrome/chromeFiles/content/config.js

    r695 r697  
    1414 
    1515Config.prototype = { 
    16   addObserver: function(observer, script) { 
    17     var observers = script ? script._observers : this._observers; 
    18     observers.push(observer); 
    19   }, 
    20  
    21   removeObserver: function(observer, script) { 
    22     var observers = script ? script._observers : this._observers; 
    23     var index = observers.indexOf(observer); 
     16  addObserver: function(observer) { 
     17    this._observers.push(observer); 
     18  }, 
     19 
     20  removeObserver: function(observer) { 
     21    var index = this._observers.indexOf(observer); 
    2422    if (index == -1) throw new Error("Observer not found"); 
    25     observers.splice(index, 1); 
     23    this._observers.splice(index, 1); 
    2624  }, 
    2725 
     
    267265    var existingIndex = this._find(script); 
    268266    if (existingIndex > -1) { 
    269       this.uninstall(this._scripts[existingIndex], false); 
     267      this.uninstall(this._scripts[existingIndex]); 
    270268    } 
    271269 
     
    287285  }, 
    288286 
    289   uninstall: function(script, uninstallPrefs) { 
     287  uninstall: function(script) { 
    290288    var idx = this._find(script); 
    291289    this._scripts.splice(idx, 1); 
     
    299297      // if script is in the root, just remove the file 
    300298      script._file.remove(false); 
    301     } 
    302  
    303     if (uninstallPrefs) { 
    304       // Remove saved preferences 
    305       GM_prefRoot.remove("scriptvals." + script._namespace + "/" + script._name + "."); 
    306299    } 
    307300  }, 
     
    399392 
    400393Script.prototype = { 
     394  addObserver: Config.prototype.addObserver, 
     395  removeObserver: Config.prototype.removeObserver, 
     396 
    401397  matchesURL: function(url) { 
    402398    function test(page) { 
     
    409405  _changed: function(event, data) { this._config._changed(this, event, data); }, 
    410406 
     407  get id() { return [this._name, this._namespace].toSource(); }, 
    411408  get name() { return this._name; }, 
    412409  get namespace() { return this._namespace; }, 
     
    414411  get enabled() { return this._enabled; }, 
    415412  set enabled(enabled) { this._enabled = enabled; this._changed("edit-enabled", enabled); }, 
     413  get prefBranch() { return "scriptvals." + this._namespace + "/" + this._name + "."; }, 
    416414 
    417415  get includes() { return this._includes.concat(); }, 
  • branches/manage-ui/src/chrome/chromeFiles/content/manage.css

    r688 r697  
    1 /* 
    2 These dummy values are "flexed".  Having a set value, though, keeps the 
    3 columns from shifting size, as their content does.  They also influence 
    4 the original starting size of the elements before flexing. 
    5 */ 
    6 window { 
    7   width: 600px; 
    8   height: 500px; 
    9   padding: 10px; 
    10 
    11 #col_left { 
    12   width: 200px 
    13 
    14 #col_right { 
    15   width: 400px 
     1#scriptsView { 
     2  -moz-binding: url("chrome://greasemonkey/content/manage.xml#scripts"); 
    163} 
    174 
    18 #lstScripts { 
    19   min-width:140px; 
    20   margin-top:0 
     5richlistitem { 
     6  -moz-binding: url("chrome://greasemonkey/content/manage.xml#script"); 
    217} 
    228 
    23 #ctlHeader { 
    24   margin: 0px 5px 5px 5px; 
    25   border: 2px solid; 
    26   -moz-border-top-colors: ThreeDShadow ThreeDDarkShadow; 
    27   -moz-border-right-colors: ThreeDHighlight ThreeDDarkShadow; 
    28   -moz-border-bottom-colors: ThreeDHighlight ThreeDDarkShadow; 
    29   -moz-border-left-colors: ThreeDShadow ThreeDDarkShadow; 
    30   padding: 5px 8px; 
    31   background-color: Highlight; 
    32   color: HighlightText; 
    33   font-size: 1.5em; 
    34   height: 2em 
     9richlistitem[selected="true"] { 
     10  -moz-binding: url("chrome://greasemonkey/content/manage.xml#script-selected"); 
    3511} 
    3612 
    37 #ctlDescription { 
    38   margin:.5em; 
    39   height:3em; 
    40   max-height:3em 
     13richlistitem[isDisabled="true"] .disableButton, 
     14richlistitem[isDisabled="false"] .enableButton, 
     15#commandBarBottom[gm-enabled="true"] #globalEnableButton, 
     16#commandBarBottom[gm-enabled="false"] #globalDisableButton { 
     17  display: none; 
    4118} 
    42  
    43 #pages-control listbox { 
    44   overflow: auto 
    45 } 
    46  
    47 #pages-control > groupbox > hbox { 
    48   margin-bottom: 0.5em 
    49 } 
    50  
    51 /* border for indicator where drag-and-drop will go */ 
    52 listbox#lstScripts listitem { 
    53   border-top: 1px solid -moz-field; 
    54   border-bottom: 1px solid -moz-field 
    55 } 
    56 listbox#lstScripts listitem[dragover="top"] { 
    57   border-top-color: black 
    58 } 
    59 listbox#lstScripts listitem[dragover="bottom"] { 
    60   border-bottom-color: black 
    61 } 
  • branches/manage-ui/src/chrome/chromeFiles/content/manage.js

    r695 r697  
    11var config = GM_getConfig(); 
    2  
    3 window.addEventListener("load", function(ev) { 
    4   loadControls(); 
    5  
    6   if (!config.scripts.length == 0) { 
    7     populateChooser(); 
    8     chooseScript(0); 
    9   } 
    10  
     2var gScriptsView = null; 
     3 
     4function Startup() { 
     5  gScriptsView = document.getElementById("scriptsView"); 
     6 
     7  updateGlobalEnabledButton(); 
     8  GM_prefRoot.watch("enabled", updateGlobalEnabledButton); 
     9 
     10  populateChooser(); 
    1111  config.addObserver(observer); 
    12 }, false); 
    13  
    14 window.addEventListener("unload", function(ev) { 
    15   pagesControl.clear(); 
     12 
     13  restoreSelection(); 
     14 
     15  gScriptsView.controllers.appendController(gScriptsViewController); 
     16  gScriptsViewController.onCommandUpdate(); 
     17 
     18  gScriptsView.focus(); 
     19
     20 
     21function Shutdown() { 
    1622  config.removeObserver(observer); 
    17 }, false); 
     23 
     24  GM_prefRoot.unwatch("enabled", updateGlobalEnabledButton); 
     25
     26 
     27function restoreSelection() { 
     28  var selected = null; 
     29  var id = gScriptsView.getAttribute("selected-script-id"); 
     30  var nodes = gScriptsView.children; 
     31  if (id) { 
     32    for (var i = 0, node; node = nodes[i]; i++) { 
     33      if (node.script.id == id) { 
     34        selected = node; 
     35        break; 
     36      } 
     37    } 
     38  } 
     39  gScriptsView.selectedItem = selected || nodes[0]; 
     40  registerSelection(); 
     41
     42 
     43function registerSelection() { 
     44  if (gScriptsView.selectedItem) 
     45    gScriptsView.setAttribute("selected-script-id", gScriptsView.selectedItem.script.id); 
     46
     47 
     48function updateGlobalEnabledButton() { 
     49  document.getElementById("commandBarBottom") 
     50    .setAttribute("gm-enabled", GM_prefRoot.getValue("enabled", true)); 
     51
     52 
     53function onViewDoubleClick(aEvent) { 
     54  if (aEvent.button == 0 && gScriptsView.selectedItem) 
     55    gScriptsViewController.doCommand("cmd_pages"); 
     56
     57 
     58var gScriptsViewController = { 
     59  supportsCommand: function (aCommand) { 
     60    var commandNode = document.getElementById(aCommand); 
     61    return commandNode && (commandNode.parentNode == document.getElementById("scriptsCommands")); 
     62  }, 
     63 
     64  isCommandEnabled: function (aCommand) { 
     65    var selectedItem = gScriptsView.selectedItem; 
     66 
     67    if (!selectedItem) return false; 
     68 
     69    switch (aCommand) { 
     70    case "cmd_edit": 
     71    case "cmd_pages": 
     72    case "cmd_uninstall": 
     73      return true; 
     74    case "cmd_disable": 
     75      return selectedItem.script.enabled; 
     76    case "cmd_enable": 
     77      return !selectedItem.script.enabled; 
     78    case "cmd_moveup": 
     79      return selectedItem != gScriptsView.children[0]; 
     80    case "cmd_movedown": 
     81      return selectedItem != gScriptsView.children[gScriptsView.children.length-1]; 
     82    default: 
     83      return false; 
     84    } 
     85  }, 
     86 
     87  doCommand: function (aCommand) { 
     88    if (this.isCommandEnabled(aCommand)) 
     89      this.commands[aCommand](gScriptsView.selectedItem); 
     90  }, 
     91 
     92  onCommandUpdate: function () { 
     93    var scriptsCommands = document.getElementById("scriptsCommands"); 
     94    for (var i = 0; i < scriptsCommands.childNodes.length; ++i) 
     95      this.updateCommand(scriptsCommands.childNodes[i]); 
     96  }, 
     97 
     98  updateCommand: function (command) { 
     99    if (this.isCommandEnabled(command.id)) 
     100      command.removeAttribute("disabled"); 
     101    else 
     102      command.setAttribute("disabled", "true"); 
     103  }, 
     104 
     105  commands: { 
     106    cmd_edit: function (aSelectedItem) { 
     107      openInEditor(aSelectedItem.script); 
     108      gScriptsView.focus(); 
     109    }, 
     110 
     111    cmd_pages: function (aSelectedItem) { 
     112      var win = Components.classes["@mozilla.org/appshell/window-mediator;1"] 
     113                          .getService(Components.interfaces.nsIWindowMediator) 
     114                          .getMostRecentWindow("Greasemonkey:Pages"); 
     115      if (win) { 
     116        win.initWithScript(aSelectedItem.script); 
     117        win.focus(); 
     118      } else { 
     119        var parentWindow = (!window.opener || window.opener.closed) ? 
     120          window : window.opener; 
     121        parentWindow.openDialog("chrome://greasemonkey/content/pages-overlay.xul", 
     122          "_blank", "resizable,dialog=no,centerscreen", aSelectedItem.script); 
     123      } 
     124      gScriptsView.focus(); 
     125    }, 
     126 
     127    cmd_uninstall: function (aSelectedItem) { 
     128      var bundle = Components 
     129        .classes["@mozilla.org/intl/stringbundle;1"] 
     130        .getService(Components.interfaces.nsIStringBundleService) 
     131        .createBundle("chrome://greasemonkey/locale/uninstall.properties"); 
     132 
     133      var promptService = Components 
     134        .classes["@mozilla.org/embedcomp/prompt-service;1"] 
     135        .getService(Components.interfaces.nsIPromptService); 
     136 
     137      var hasPrefs = GM_prefRoot.existsBranch(aSelectedItem.script.prefBranch); 
     138      var buttonChoice = promptService.confirmEx( 
     139        window, 
     140        bundle.GetStringFromName("dialogTitle"), 
     141        bundle.formatStringFromName(hasPrefs ? "textWithPrefs" : 
     142          "textWithoutPrefs", [aSelectedItem.script.name], 1), 
     143        promptService.BUTTON_POS_0_DEFAULT + 
     144        promptService.BUTTON_TITLE_IS_STRING * ( 
     145          promptService.BUTTON_POS_0 + promptService.BUTTON_POS_1 + 
     146          (hasPrefs ? promptService.BUTTON_POS_2 : 0) 
     147        ), 
     148        bundle.GetStringFromName("removeScript"), 
     149        bundle.GetStringFromName("cancel"), 
     150        bundle.GetStringFromName("removeScriptAndPrefs"), 
     151        null, {} 
     152      ); 
     153 
     154      if (buttonChoice == 2) 
     155        GM_prefRoot.remove(aSelectedItem.script.prefBranch); 
     156 
     157      if (buttonChoice != 1) 
     158        config.uninstall(aSelectedItem.script); 
     159 
     160      gScriptsView.focus(); 
     161    }, 
     162 
     163    cmd_disable: function (aSelectedItem) { 
     164      aSelectedItem.script.enabled = false; 
     165      gScriptsView.focus(); 
     166    }, 
     167 
     168    cmd_enable: function (aSelectedItem) { 
     169      aSelectedItem.script.enabled = true; 
     170      gScriptsView.focus(); 
     171    }, 
     172 
     173    cmd_moveup: function (aSelectedItem) { 
     174      config.move(aSelectedItem.script, -1); 
     175      gScriptsView.focus(); 
     176    }, 
     177 
     178    cmd_movedown: function (aSelectedItem) { 
     179      config.move(aSelectedItem.script, 1); 
     180      gScriptsView.focus(); 
     181    } 
     182  } 
     183}; 
     184 
     185function populateChooser() { 
     186  config.scripts.forEach(createScriptNode); 
     187
     188 
     189function createScriptNode(script) { 
     190    var node = document.createElement("richlistitem"); 
     191    node.setAttribute("name", script.name); 
     192    node.setAttribute("description", script.description); 
     193    node.setAttribute("isDisabled", !script.enabled); 
     194    node.script = script; 
     195    gScriptsView.appendChild(node); 
     196
     197 
     198function getNodeForScript(script) { 
     199  for (var i = 0, nodes = gScriptsView.children, node; node = nodes[i]; i++) 
     200    if (node.script == script) 
     201      return node; 
     202 
     203  throw new Error("Node not found"); 
     204
    18205 
    19206var observer = { 
    20207  notifyEvent: function(script, event, data) { 
    21     var node = null; 
    22     for (var i = 0; node = listbox.childNodes[i]; i++) 
    23       if (node.script == script) 
    24         break; 
    25  
     208    var node = getNodeForScript(script); 
    26209    switch (event) { 
    27210    case "edit-enabled": 
    28       node.style.color = data ? "" : "gray"; 
    29       if (script == selectedScript) 
    30         chkEnabled.checked = data; 
     211      node.setAttribute("isDisabled", !script.enabled); 
     212      gScriptsViewController.onCommandUpdate(); 
    31213      break; 
    32214    case "install": 
    33       addListitem(script, -1); 
     215      createScriptNode(script); 
    34216      break; 
    35217    case "uninstall": 
    36       var selected = listbox.selectedItem == node; 
    37       listbox.removeChild(node); 
    38  
    39       if (selected && listbox.childNodes.length > 0) { 
    40         chooseScript(Math.max(Math.min(listbox.selectedIndex, listbox.childNodes.length - 1), 0)); 
    41       } 
     218      gScriptsView.removeChild(node); 
    42219      break; 
    43220    case "move": 
    44       listbox.removeChild(node); 
    45       listbox.insertBefore(node, listbox.childNodes[data]); 
    46       // then re-select the dropped script 
    47       listbox.selectedIndex = data; 
    48       break; 
    49     } 
    50  
    51     // fix the listbox indexes 
    52     for (var i = 0, n = null; n = listbox.childNodes[i]; i++) n.index=i; 
    53   } 
    54 }; 
    55  
    56 var listbox, header, description, chkEnabled, btnEdit, btnUninstall; 
    57 var selectedScript; 
    58 var pagesControl; 
    59  
    60 function loadControls() { 
    61   listbox = document.getElementById("lstScripts"); 
    62   header = document.getElementById("ctlHeader"); 
    63   description = document.getElementById("ctlDescription"); 
    64   btnEdit = document.getElementById("btnEdit"); 
    65   btnUninstall = document.getElementById("btnUninstall"); 
    66   pagesControl = new PagesControl(document.getElementById("pages-control")); 
    67   chkEnabled = document.getElementById("chkEnabled"); 
    68  
    69   listbox.addEventListener("select", function() { updateDetails(); }, false); 
    70   btnEdit.addEventListener("command", function() { handleEditButton(); }, false); 
    71   btnUninstall.addEventListener("command", function() { handleUninstallButton(); }, false); 
    72   chkEnabled.addEventListener("command", function() { 
    73      if (selectedScript) 
    74        selectedScript.enabled = chkEnabled.checked; 
    75   }, false); 
    76 
    77  
    78 function updateDetails() { 
    79   if (listbox.selectedCount == 0) { 
    80     selectedScript = null; 
    81     header.textContent = " "; 
    82     description.textContent = " "; 
    83     chkEnabled.checked = true; 
    84     pagesControl.clear(); 
    85   } else { 
    86     selectedScript = listbox.getSelectedItem(0).script; 
    87  
    88     // make sure one word isn't too long to fit ... a too-long word 
    89     // will bump the interface out wider than the window 
    90     var wordLen = 50; 
    91     var desc = selectedScript.description.split(/\s+/); 
    92     for (var i = 0; i < desc.length; i++) { 
    93       if (desc[i].length > wordLen) { 
    94         for (var j = desc[i].length; j > 0; j -= wordLen) { 
    95           desc[i] = desc[i].substr(0,j) + "\u200B" + desc[i].substr(j); 
    96         } 
    97       } 
    98     } 
    99     desc = desc.join(" "); 
    100  
    101     header.textContent = selectedScript.name; 
    102     description.textContent = desc; 
    103     chkEnabled.checked = selectedScript.enabled; 
    104     pagesControl.populate(selectedScript); 
    105   } 
    106 
    107  
    108 function handleEditButton() { 
    109   openInEditor(selectedScript); 
    110 
    111  
    112 function handleUninstallButton() { 
    113   var uninstallPrefs = document.getElementById("chkUninstallPrefs").checked; 
    114   config.uninstall(selectedScript, uninstallPrefs); 
    115 
    116  
    117 function populateChooser() { 
    118   var scripts = config.scripts; 
    119   for (var i = 0, script = null; (script = scripts[i]); i++) 
    120     addListitem(script, i); 
    121 
    122  
    123 function addListitem(script, i) { 
    124   var listitem = document.createElement("listitem"); 
    125  
    126   listitem.setAttribute("label", script.name); 
    127   listitem.setAttribute("crop", "end"); 
    128   listitem.script = script; 
    129   listitem.index = i; 
    130  
    131   if (!script.enabled) { 
    132     listitem.style.color = "gray"; 
    133   } 
    134  
    135   listbox.appendChild(listitem); 
    136 
    137  
    138 function chooseScript(index) { 
    139   listbox.selectedIndex = index; 
    140   listbox.focus(); 
    141 
    142  
    143 // allow reordering scripts with keyboard (alt- up and down) 
    144 function listboxKeypress(event) { 
    145   if (0 == listbox.selectedCount) return; 
    146   if (!event.altKey) return; 
    147  
    148   var index = listbox.selectedIndex; 
    149  
    150   var move = null; 
    151   if (KeyEvent.DOM_VK_UP == event.keyCode) 
    152     move = config.move(listbox.selectedItem.script, -1); 
    153   else if (KeyEvent.DOM_VK_DOWN == event.keyCode) 
    154     move = config.move(listbox.selectedItem.script, 1); 
     221      gScriptsView.removeChild(node); 
     222      if (data == gScriptsView.children.length) 
     223        gScriptsView.appendChild(node); 
     224      else 
     225        gScriptsView.insertBefore(node, gScriptsView.children[data]); 
     226      gScriptsViewController.onCommandUpdate(); 
     227      break; 
     228    } 
     229  } 
     230
     231 
     232function onScriptContextMenuShowing() { 
     233  if (!gScriptsView.selectedItem) return false; 
     234  var enabled = gScriptsView.selectedItem.script.enabled; 
     235  document.getElementById("contextEnable").hidden = enabled; 
     236  document.getElementById("contextDisable").hidden = !enabled; 
    155237} 
    156238 
    157239// allow reordering scripts with drag-and-drop 
    158240var dndObserver = { 
    159   lastFeedbackIndex: null, 
     241  draggedScript: null, 
    160242 
    161243  getSupportedFlavours: function () { 
    162244    var flavours = new FlavourSet(); 
    163     flavours.appendFlavour("text/unicode"); 
     245    flavours.appendFlavour("gm-user-script"); 
    164246    return flavours; 
    165247  }, 
    166248 
    167249  onDragStart: function (event, transferData, action) { 
    168     if ("listitem" != event.target.tagName ) return false; 
    169  
     250    if ("richlistitem" != event.target.tagName) return false; 
     251 
     252    this.draggedScript = event.target.script; 
    170253    transferData.data = new TransferData(); 
    171     transferData.data.addDataForFlavour("text/unicode", event.target.index); 
     254    transferData.data.addDataForFlavour("gm-user-script", "gm-reorder-script"); 
    172255 
    173256    return true; 
     
    175258 
    176259  onDragOver: function (event, flavour, session) { 
    177     if (listbox.selectedIndex == event.target.index) { 
    178       this.clearFeedback(); 
    179       return false; 
    180     } 
    181  
    182     return this.setFeedback(event); 
     260    if (gScriptsView == event.target.parentNode) 
     261      event.target.setAttribute("droptarget", true); 
     262  }, 
     263 
     264  onDragExit: function(event, session) { 
     265    if (gScriptsView == event.target.parentNode) 
     266      event.target.removeAttribute("droptarget"); 
    183267  }, 
    184268 
    185269  onDrop: function (event, dropdata, session) { 
    186     // clean up the feedback 
    187     this.lastFeedbackIndex = null; 
    188     this.clearFeedback(); 
    189  
    190     // figure out how to move 
    191     var newIndex = this.findNewIndex(event); 
    192     if (null === newIndex) return; 
    193     var index = parseInt(dropdata.data); 
    194     if (newIndex > index) newIndex--; 
    195  
    196     // do the move 
    197     var move = config.move(config.scripts[index], config.scripts[newIndex]); 
    198   }, 
    199  
    200   ////////////////////////////////////////////////////////////////////////////// 
    201  
    202   setFeedback: function(event) { 
    203     var newIndex = this.findNewIndex(event); 
    204  
    205     // don't do anything if we haven't changed 
    206     if (newIndex === this.lastFeedbackIndex) return false; // NOTE: possible incongruent logic 
    207     this.lastFeedbackIndex = newIndex; 
    208  
    209     // clear any previous feedback 
    210     this.clearFeedback(); 
    211  
    212     // and set the current feedback 
    213     if (null === newIndex) { 
    214       return false; 
    215     } else if (listbox.selectedIndex == newIndex) { 
    216       return false; 
    217     } else { 
    218       if (0 == newIndex) { 
    219         listbox.firstChild.setAttribute("dragover", "top"); 
    220       } else if (newIndex >= listbox.childNodes.length) { 
    221         listbox.lastChild.setAttribute("dragover", "bottom"); 
    222       } else { 
    223         listbox.childNodes[newIndex - 1].setAttribute("dragover", "bottom"); 
    224       } 
    225     } 
    226  
    227     return true; 
    228   }, 
    229  
    230   clearFeedback: function() { 
    231     var box = document.getElementById("lstScripts"); 
    232     for (var i = 0, el; el = box.childNodes[i]; i++) { 
    233       el.removeAttribute("dragover"); 
    234     } 
    235   }, 
    236  
    237   findNewIndex: function(event) { 
    238     var target = event.target; 
    239  
    240     // not in the list box? forget it! 
    241     if (listbox != target && listbox != target.parentNode) return null; 
    242  
    243     var targetBox = target.boxObject 
    244       .QueryInterface(Components.interfaces.nsIBoxObject); 
    245  
    246     if (listbox == target) { 
    247       // here, we are hovering over the listbox, not a particular listitem 
    248       // check if we are very near the top (y + 4), return zero, else return end 
    249       if (event.clientY < targetBox.y + 4) { 
    250         return 0; 
    251       } else { 
    252         return listbox.childNodes.length; 
    253       } 
    254     } else { 
    255       var targetMid = targetBox.y + (targetBox.height / 2); 
    256  
    257       if (event.clientY >= targetMid) { 
    258         return target.index + 1; 
    259       } else { 
    260         return target.index; 
    261       } 
    262     } 
    263  
    264     // should never get here, but in case 
    265     return null; 
     270    if (gScriptsView == event.target.parentNode && 
     271      dropdata.data == "gm-reorder-script") { 
     272      var source = this.draggedScript; 
     273      var target = event.target.script; 
     274      if (source && target) config.move(source, target); 
     275    } 
    266276  } 
    267277}; 
  • branches/manage-ui/src/chrome/chromeFiles/content/manage.xul

    r688 r697  
    22<?xml-stylesheet href="chrome://global/skin/" type="text/css"?> 
    33<?xml-stylesheet href="chrome://greasemonkey/content/manage.css" type="text/css"?> 
    4 <?xul-overlay href="chrome://greasemonkey/content/pages-overlay.xul"?> 
     4<?xml-stylesheet href="chrome://greasemonkey/skin/manage.css" type="text/css"?> 
    55 
    66<!DOCTYPE dialog SYSTEM "chrome://greasemonkey/locale/greasemonkey.dtd"> 
     
    1010  xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" 
    1111  title="&manage.title;" 
    12   orient="vertical"> 
     12  orient="vertical" 
     13  onload="Startup();" 
     14  onunload="Shutdown();" 
     15  width="&manage.width;" height="&manage.height;" 
     16  persist="width height screenX screenY sizemode"> 
    1317 
     18  <script type="application/javascript" src="chrome://global/content/globalOverlay.js"/> 
    1419  <script type="application/x-javascript" src="chrome://global/content/nsDragAndDrop.js" /> 
    1520  <script type="application/x-javascript" src="chrome://global/content/nsTransferable.js" /> 
     
    1722  <script type="application/x-javascript" src="chrome://greasemonkey/content/prefmanager.js" /> 
    1823  <script type="application/x-javascript" src="chrome://greasemonkey/content/manage.js" /> 
     24  <script type="application/javascript" src="chrome://global/content/contentAreaUtils.js"/> 
    1925 
    20   <stringbundle id="gm-manage-bundle" src="chrome://greasemonkey/locale/gm-manage.properties" /> 
     26  <commandset id="scriptsCommands" 
     27              events="richlistbox-select" 
     28              commandupdater="true" 
     29              oncommandupdate="gScriptsViewController.onCommandUpdate();" 
     30              oncommand="gScriptsViewController.doCommand(event.target.id);"> 
     31    <command id="cmd_edit"/> 
     32    <command id="cmd_pages"/> 
     33    <command id="cmd_uninstall"/> 
     34    <command id="cmd_enable"/> 
     35    <command id="cmd_disable"/> 
     36    <command id="cmd_moveup"/> 
     37    <command id="cmd_movedown"/> 
     38  </commandset> 
    2139 
    22   <grid flex="1" orient="vertical"> 
    23     <columns> 
    24       <column id="col_left" 
    25         flex="1" /> 
    26       <column id="col_right" 
    27         flex="3" /> 
    28     </columns> 
     40  <keyset> 
     41    <key id="moveUpKey" keycode="VK_UP" modifiers="alt" oncommand="gScriptsViewController.doCommand('cmd_moveup');"/> 
     42    <key id="moveDownKey" keycode="VK_DOWN" modifiers="alt" oncommand="gScriptsViewController.doCommand('cmd_movedown');"/> 
     43  </keyset> 
    2944 
    30     <rows> 
    31       <row flex="1" orient="horizontal"> 
    32         <vbox flex="1"> 
    33           <listbox id="lstScripts" 
    34             flex="10" 
    35             onkeypress="return listboxKeypress(event);" 
    36             ondraggesture="nsDragAndDrop.startDrag(event, dndObserver);" 
    37             ondragover="nsDragAndDrop.dragOver(event, dndObserver);" 
    38             ondragdrop="nsDragAndDrop.drop(event, dndObserver);" /> 
    39           <description flex="1">&manage.reorderHelp;</description> 
    40         </vbox> 
    41         <vbox> 
    42           <description id="ctlHeader" /> 
    43           <description id="ctlDescription" /> 
    44           <vbox id="pages-control" 
    45             flex="1" /> 
    46         </vbox> 
    47       </row> 
    48       <row> 
    49         <hbox> 
    50           <checkbox id="chkEnabled" 
    51             label="&manage.label.chkEnabled;" 
    52             checked="true" /> 
    53           <button id="btnEdit" 
    54             label="&manage.label.btnEdit;" /> 
    55         </hbox> 
    56         <vbox> 
    57           <hbox flex="1" /> 
    58           <hbox> 
    59             <button id="btnUninstall" 
    60               label="&manage.label.btnUninstall;" /> 
    61             <checkbox id="chkUninstallPrefs" 
    62               label="&manage.label.chkUninstall;" 
    63               checked="false" /> 
    64           </hbox> 
    65         </vbox> 
    66       </row> 
    67     </rows> 
    68   </grid> 
     45  <menupopup id="scriptContextMenu" onpopupshowing="onScriptContextMenuShowing();"> 
     46    <menuitem label="&manage.cmd.pages.label;" accesskey="&manage.cmd.pages.accesskey;" command="cmd_pages"/> 
     47    <menuitem label="&manage.cmd.edit.label;" accesskey="&manage.cmd.edit.accesskey;" command="cmd_edit"/> 
     48    <menuseparator/> 
     49    <menuitem id="contextEnable" label="&manage.cmd.enable.label;" accesskey="&manage.cmd.enable.accesskey;" command="cmd_enable"/> 
     50    <menuitem id="contextDisable" label="&manage.cmd.disable.label;" accesskey="&manage.cmd.disable.accesskey;" command="cmd_disable"/> 
     51    <menuitem label="&manage.cmd.uninstall.label;" accesskey="&manage.cmd.uninstall.accesskey;" command="cmd_uninstall"/> 
     52    <menuseparator/> 
     53    <menuitem label="&manage.cmd.moveup.label;" accesskey="&manage.cmd.moveup.accesskey;" command="cmd_moveup" key="moveUpKey"/> 
     54    <menuitem label="&manage.cmd.movedown.label;" accesskey="&manage.cmd.movedown.accesskey;" command="cmd_movedown" key="moveDownKey"/> 
     55  </menupopup> 
    6956 
     57  <hbox id="manage-content" flex="1"> 
     58    <richlistbox id="scriptsView" flex="1" persist="selected-script-id" 
     59                 ondblclick="onViewDoubleClick(event);" context="scriptContextMenu" 
     60                 ondraggesture="nsDragAndDrop.startDrag(event, dndObserver);" 
     61                 ondragover="nsDragAndDrop.dragOver(event, dndObserver);" 
     62                 ondragexit="nsDragAndDrop.dragExit(event, dndObserver);" 
     63                 ondragdrop="nsDragAndDrop.drop(event, dndObserver);" 
     64                 onselect="registerSelection();"/> 
     65  </hbox> 
     66  <vbox> 
     67    <hbox id="commandBarBottom" align="center"> 
     68      <button id="globalEnableButton" label="&manage.globalEnable.label;" 
     69              accesskey="&manage.globalEnable.accesskey;" 
     70              tooltiptext="&manage.globalEnable.tooltip;" 
     71              oncommand="GM_setEnabled(true);"/> 
     72      <button id="globalDisableButton" label="&manage.globalDisable.label;" 
     73              accesskey="&manage.globalDisable.accesskey;" 
     74              tooltiptext="&manage.globalDisable.tooltip;" 
     75              oncommand="GM_setEnabled(false);"/> 
     76      <spacer flex="1"/> 
     77      <label id="getMore" class="text-link" 
     78             onclick="openURL('http://userscripts.org');" 
     79             value="&manage.getMore.label;"/> 
     80      <spacer flex="1"/> 
     81      <button id="createButton" label="&manage.newscript.label;" 
     82              accesskey="&manage.newscript.accesskey;" 
     83              tooltiptext="&manage.newscript.tooltip;" 
     84              oncommand="GM_openNewUserScriptDialog();"/> 
     85    </hbox> 
     86    <hbox id="resizerBox" style="min-width:1px;"> 
     87      <spacer flex="1"/> 
     88      <resizer dir="bottomright"/> 
     89    </hbox> 
     90  </vbox> 
    7091</window> 
  • branches/manage-ui/src/chrome/chromeFiles/content/miscapis.js

    r694 r697  
    11function GM_ScriptStorage(script) { 
    2   this.prefMan = new GM_PrefManager(["scriptvals.", 
    3                                      script.namespace, 
    4                                      "/", 
    5                                      script.name, 
    6                                      "."].join("")); 
     2  this.prefMan = new GM_PrefManager(script.prefBranch); 
    73} 
    84 
  • branches/manage-ui/src/chrome/chromeFiles/content/newscript.js

    r692 r697  
    1111 
    1212  // default the includes with the current page's url 
    13   document.getElementById("includes").value = 
    14       window.opener.document.getElementById("content").selectedBrowser 
    15       .contentWindow.location.href; 
     13  var win = Components.classes["@mozilla.org/appshell/window-mediator;1"] 
     14                      .getService(Components.interfaces.nsIWindowMediator) 
     15                      .getMostRecentWindow("navigator:browser"); 
     16  if (win) { 
     17    document.getElementById("includes").value = win.content.location.href; 
     18  } 
    1619}, false); 
    1720 
  • branches/manage-ui/src/chrome/chromeFiles/content/pages-overlay.js

    r695 r697  
    1 function PagesControl(ctlPages) { 
    2   var includesBox = new PagesBox(document.getElementById("grpIncluded")); 
    3   var excludesBox = new PagesBox(document.getElementById("grpExcluded")); 
     1var gPagesControl = { 
     2  excludes: [], 
     3  includes: [], 
     4  _tree: null, 
     5  _script: null, 
    46 
    5   this.notifyEvent = function(script, event, data) { 
    6     switch (event) { 
    7     case "edit-include-add": includesBox.pageAdded(data); break; 
    8     case "edit-include-remove": includesBox.pageRemoved(data); break; 
    9     case "edit-exclude-add": excludesBox.pageAdded(data); break; 
    10     case "edit-exclude-remove": excludesBox.pageRemoved(data); break; 
    11     } 
    12   }; 
    13  
    14   this.script = null; 
    15   this.populate = function(script) { 
    16     this.clear(); 
    17     includesBox.populate(script, "includes", script.includes); 
    18     excludesBox.populate(script, "excludes", script.excludes); 
    19     this.script = script; 
    20     GM_getConfig().addObserver(this, this.script); 
    21   }; 
    22  
    23   this.clear = function() { 
    24     if (this.script == null) return; 
    25     GM_getConfig().removeObserver(this, this.script); 
    26     includesBox.clear(); 
    27     excludesBox.clear(); 
    28     this.script = null; 
    29   }; 
    30  
    31   function PagesBox(grpBox) { 
    32     var buttons = grpBox.getElementsByTagName("button"); 
    33     var self = this; 
    34     var selectedPage = null; 
    35  
    36     this.script = null; 
    37     this.type = null; 
    38     this.groupbox = grpBox; 
    39     this.listbox = grpBox.getElementsByTagName("listbox")[0]; 
    40     this.btnAdd = buttons[0]; 
    41     this.btnRemove = buttons[1]; 
    42  
    43     this.listbox.addEventListener("select", updatePagesBox, true); 
    44     this.btnAdd.addEventListener("command", promptForNewPage, true); 
    45     this.btnRemove.addEventListener("command", remove, true); 
    46  
    47     this.populate = function(script, type, pages) { 
    48       this.clear(); 
    49       this.script = script; 
    50       this.type = type; 
    51  
    52       for (var i = 0, page = null; (page = pages[i]); i++) { 
    53         addPage(page); 
    54       } 
    55     }; 
    56  
    57     this.clear = function() { 
    58       this.script = null; 
    59       this.type = null; 
    60  
    61       while (this.listbox.hasChildNodes()) { 
    62         this.listbox.removeChild(this.listbox.childNodes[0]); 
    63       } 
    64     }; 
    65  
    66     function updatePagesBox(ev) { 
    67       selectedPage = self.listbox.getSelectedItem(0); 
    68       self.btnRemove.disabled = selectedPage == null; 
     7  setScript: function(script) { 
     8    if (this._script) { 
     9      this._script.removeObserver(this); 
    6910    } 
    7011 
    71     function promptForNewPage(ev) { 
    72       var gmManageBundle = document.getElementById("gm-manage-bundle"); 
    73       var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"] 
    74                   .getService(); 
    75       var wmi = wm.QueryInterface(Components.interfaces.nsIWindowMediator); 
    76       var win = wmi.getMostRecentWindow("navigator:browser"); 
    77       var currentSite = GM_isGreasemonkeyable(win.content.location.href) 
    78                         ? win.content.location.protocol + "//" + 
    79                           win.content.location.hostname + "/*" 
    80                         : gmManageBundle.getString("promptForNewPage.defVal"); 
    81       var val = gmPrompt( 
    82         gmManageBundle.getString("promptForNewPage.msg"), 
    83         currentSite, 
    84         gmManageBundle.getString("promptForNewPage.title")); 
     12    this._script = script; 
    8513 
    86       if (val && val != "") { 
    87         self.type == "includes" ? 
    88           self.script.addInclude(val): 
    89           self.script.addExclude(val); 
    90         dirty = true; 
     14    if (this._script == null) { 
     15      this.excludes = []; 
     16      this.includes = []; 
     17    } else { 
     18      this.excludes = this._script.excludes; 
     19      this.includes = this._script.includes; 
     20      this._script.addObserver(this); 
     21    } 
     22 
     23    var url = document.getElementById("url"); 
     24    url.value = "http://" + url.getAttribute("defaultHost") + "/*"; 
     25 
     26    var win = Components.classes["@mozilla.org/appshell/window-mediator;1"] 
     27                        .getService(Components.interfaces.nsIWindowMediator) 
     28                        .getMostRecentWindow("navigator:browser"); 
     29    if (win) { 
     30      var location = win.content.location; 
     31 
     32      if (GM_isGreasemonkeyable(location.href)) { 
     33        url.value = location.protocol + "//" + location.hostname + "/*"; 
    9134      } 
    9235    } 
    9336 
    94     this.pageAdded = function(val) { 
    95       addPage(val); 
     37    this._tree = document.getElementById("pagesTree"); 
     38    this._tree.view = treeView; 
     39    this.onUrlInput(); 
     40    this.onPageSelect(); 
     41  }, 
     42 
     43  notifyEvent: function(script, event, data) { 
     44    if (script != this._script) return; 
     45    switch (event) { 
     46    case "edit-include-add": 
     47      this.includes.push(data); 
     48      this._tree.treeBoxObject.rowCountChanged(this.excludes.length + this.includes.length - 1, 1); 
     49      break; 
     50    case "edit-include-remove": 
     51      this.includes.splice(data, 1); 
     52      this._tree.treeBoxObject.rowCountChanged(this.excludes.length + data, -1); 
     53      break; 
     54    case "edit-exclude-add": 
     55      this.excludes.push(data); 
     56      this._tree.treeBoxObject.rowCountChanged(this.excludes.length - 1, 1); 
     57      break; 
     58    case "edit-exclude-remove": 
     59      this.excludes.splice(data, 1); 
     60      this._tree.treeBoxObject.rowCountChanged(data, -1); 
     61      break; 
     62    case "remove": 
     63      window.close(); 
     64      break; 
     65    } 
     66    this.onPageSelect(); 
     67  }, 
     68 
     69  onUrlInput: function() { 
     70    document.getElementById("btnExclude").disabled = 
     71    document.getElementById("btnInclude").disabled = 
     72      !document.getElementById("url").value || !this._script; 
     73  }, 
     74 
     75  onUrlKeypress: function(event) { 
     76    if (event.keyCode == KeyEvent.DOM_VK_RETURN) { 
     77      document.getElementById("btnInclude").click(); 
     78      return false; 
     79    } 
     80    return true; 
     81  }, 
     82 
     83  addPage: function(type) { 
     84    var url = document.getElementById("url").value; 
     85    switch (type) { 
     86    case "exclude": 
     87      this._script.addExclude(url); 
     88      break; 
     89    case "include": 
     90      this._script.addInclude(url); 
     91      break; 
    9692    }; 
     93  }, 
    9794 
    98     function remove(ev) { 
    99       self.type == "includes" ? 
    100         self.script.removeIncludeAt(self.listbox.selectedIndex): 
    101         self.script.removeExcludeAt(self.listbox.selectedIndex); 
    102  
    103       // it's sorta wierd that the button stays focused when it is disabled because nothing is selected 
    104       if (self.listbox.length == 0) { 
    105         self.listbox.focus(); 
    106         dirty = true; 
     95  removeSelectedPages: function() { 
     96    var selection = this._tree.view.selection; 
     97    selection.selectEventsSuppressed = true; 
     98     
     99    var rc = selection.getRangeCount(); 
     100    var url = ""; 
     101    for (var i = rc - 1; i >= 0; i--) { 
     102      var min = {}; var max = {}; 
     103      selection.getRangeAt(i, min, max); 
     104      for (var rowIndex = max.value; rowIndex >= min.value; rowIndex--) { 
     105        var page = this.getPageFromRowIndex(rowIndex); 
     106        switch (page.type) { 
     107        case "exclude": 
     108          url = page.value; 
     109          this._script.removeExcludeAt(page.index); 
     110          break; 
     111        case "include": 
     112          url = page.value; 
     113&