1 /* See license.txt for terms of usage */ 2 3 // ************************************************************************************************ 4 // Globals 5 6 const Cc = Components.classes; 7 const Ci = Components.interfaces; 8 9 var item; 10 var FBL; 11 var internalFilefieldTextbox; 12 var browseButton; 13 14 // browsing for a new file modifies image and label only if they are autogenereted from filename 15 var origLabel = ""; 16 var origImage = null; 17 18 function onLoad() 19 { 20 var args = window.arguments[0]; 21 item = args.item; 22 FBL = args.FBL; 23 24 browseButton = document.getElementById("browse-button"); 25 26 document.getElementById("name").value = item.label; 27 if (item.executable) 28 { 29 origImage = FBL.getIconURLForFile(item.executable); 30 try 31 { 32 var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile); 33 file.initWithPath(item.executable); 34 document.getElementById("executable").file = file; 35 origLabel = file.leafName.replace(".exe",""); 36 } 37 catch(exc) {} 38 } 39 40 if (item.cmdline) 41 document.getElementById("cmdline").value = item.cmdline; 42 43 onChange(); 44 45 // Localization 46 internationalizeUI(document); 47 48 window.sizeToContent(); 49 50 if (document.getAnonymousElementByAttribute && !document.getElementById("executable").file) 51 { 52 setTimeout(function() 53 { 54 internalFilefieldTextbox = document.getAnonymousElementByAttribute( 55 document.getElementById("executable"), "class", "fileFieldLabel"); 56 57 if (internalFilefieldTextbox) 58 { 59 internalFilefieldTextbox.readOnly = false; 60 internalFilefieldTextbox.addEventListener("input", function(e) { 61 browseButton.disabled = (this.value != ""); 62 onChange(); 63 }, false); 64 } 65 }, 100); 66 } 67 } 68 69 function internationalizeUI(doc) 70 { 71 var elements = doc.getElementsByClassName("fbInternational"); 72 var attributes = ["title", "label", "value"]; 73 for (var i=0; i<elements.length; i++) 74 { 75 if (elements[i].nodeName == "description") 76 { 77 var localized = FBL.$STR(elements[i].textContent); 78 var parser = Cc["@mozilla.org/xmlextras/domparser;1"].createInstance(Ci.nsIDOMParser); 79 var doc = parser.parseFromString("<vbox>" + localized + "</vbox>", "text/xml"); 80 var root = doc.documentElement; 81 82 while(elements[i].firstChild) 83 elements[i].removeChild(elements[i].firstChild); 84 85 for(var j=0; j<root.childNodes.length; j++) 86 { 87 // ToDo: Show labels correctly 88 // Namespaces are not inherited from doc, so labels 89 // are not shown as links 90 node = doc.importNode(root.childNodes[j], true); 91 elements[i].appendChild(node); 92 } 93 } 94 else 95 { 96 for(var j=0; j<attributes.length; j++) 97 { 98 if (elements[i].hasAttribute(attributes[j])) 99 FBL.internationalize(elements[i], attributes[j]); 100 } 101 } 102 } 103 } 104 105 function onAccept() 106 { 107 item.label = document.getElementById("name").value; 108 if (!browseButton.disabled) 109 { 110 var file = document.getElementById("executable").file; 111 item.executable = ""; 112 if (file) 113 item.executable = file.path; 114 } 115 else 116 { 117 item.executable = internalFilefieldTextbox.value.replace(/^\s+|\s+$/g, ''); 118 } 119 120 item.cmdline = document.getElementById("cmdline").value; 121 if (item.image == origImage) 122 item.image = FBL.getIconURLForFile(item.executable); 123 124 try 125 { 126 var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile); 127 file.initWithPath(item.executable); 128 if (!file.isExecutable()) 129 throw "NotAnExecutable"; 130 131 window.arguments[1].saveChanges = true; 132 return true; 133 } 134 catch (exc) 135 { 136 if (FBTrace.DBG_ERRORS) 137 FBTrace.sysout("changeEditor.onAccept; EXCEPTION " + exc, exc); 138 139 var promptService = Cc["@mozilla.org/embedcomp/prompt-service;1"].createInstance( 140 Ci.nsIPromptService); 141 142 if (exc == "NotAnExecutable") 143 { 144 promptService.alert(null, FBL.$STR("changeEditor.Invalid_Application_Path"), 145 FBL.$STR("changeEditor.Path_is_not_an_executable")); 146 } 147 else 148 { 149 promptService.alert(null, FBL.$STR("changeEditor.Invalid_Application_Path"), 150 FBL.$STR("changeEditor.Application_does_not_exist")); 151 } 152 153 return false; 154 } 155 } 156 157 function onChange() 158 { 159 document.documentElement.getButton("accept").disabled = !( 160 document.getElementById("name").value && ( 161 (browseButton.disabled && internalFilefieldTextbox && 162 internalFilefieldTextbox.value && 163 internalFilefieldTextbox.value.replace(/^\s+|\s+$/g, '')) || 164 (!browseButton.disabled && document.getElementById("executable").file) 165 ) 166 ); 167 } 168 169 function onBrowse() 170 { 171 const Ci = Components.interfaces; 172 const nsIFilePicker = Ci.nsIFilePicker; 173 var picker = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker); 174 picker.init(window, "", nsIFilePicker.modeOpen); 175 picker.appendFilters(nsIFilePicker.filterApps); 176 177 if (picker.show() == nsIFilePicker.returnOK && picker.file) 178 { 179 var nameField = document.getElementById("name"); 180 var execField = document.getElementById("executable"); 181 execField.file = picker.file; 182 183 if (internalFilefieldTextbox) 184 internalFilefieldTextbox.readOnly = true; 185 186 if (nameField.value == origLabel || nameField.value == "") 187 origLabel = nameField.value = execField.file.leafName.replace(".exe",""); 188 189 onChange(); 190 return true; 191 } 192 193 return false; 194 } 195 196 function insertText(text, whole) 197 { 198 var textbox = document.getElementById("cmdline") 199 if(whole) 200 textbox.select(); 201 202 textbox.editor.QueryInterface(Components.interfaces.nsIPlaintextEditor).insertText(text); 203 textbox.focus() 204 } 205 206 // ************************************************************************************************ 207 208 // would be good to have autosuggest for popular editors 209 var defaultCommandLines = 210 { 211 "emacs/vim/gedit/nano/geany": "+%line %file", 212 "sublimetext": "%file:%line:%col", 213 "notepad++": "-n%line %file", 214 "emeditor": "/l %line %file", 215 "IntelliJ IDEA": "%{--line %line%} %file", 216 "browser": "%url", 217 "explorer": "/select,%file", 218 "wget/curl": "%url", 219 "firefox": "http://validator.w3.org/check?uri=%url" 220 } 221 222 function suggestionPopupShowing(popup) 223 { 224 FBL.eraseNode(popup); 225 226 for (var i in defaultCommandLines) 227 { 228 var box = document.createElement('hbox'); 229 var label = document.createElement('label'); 230 label.setAttribute('value', i + ': '); 231 box.appendChild(label); 232 233 var spacer = document.createElement('spacer'); 234 spacer.setAttribute('flex', 1); 235 box.appendChild(spacer); 236 237 label = document.createElement('label'); 238 label.setAttribute('value', defaultCommandLines[i]); 239 label.className = 'text-link' 240 box.appendChild(label); 241 242 popup.appendChild(box) 243 } 244 } 245 246 // ************************************************************************************************ 247 // TODO: suggestions for application? 248 /* 249 var paths = [] 250 var handlers = Cc["@mozilla.org/uriloader/external-helper-app-service;1"] 251 .getService(Ci.nsIMIMEService).getFromTypeAndExtension("", "js").possibleLocalHandlers; 252 for (var i = handlers.length - 1; i >= 0; i--) 253 paths.unshift(handlers.queryElementAt(i, Ci.nsILocalHandlerApp).executable.path); 254 255 paths 256 */ 257 258 // ************************************************************************************************ 259 var testEditor = function() 260 { 261 var tmpItem = {}; 262 var file = document.getElementById("executable").file; 263 if (file) 264 tmpItem.executable = file.path; 265 tmpItem.cmdline = document.getElementById("cmdline").value; 266 267 var Firebug = opener.opener.Firebug; 268 Firebug.ExternalEditors.open(Firebug.Firefox.getCurrentBrowser().currentURI.spec, 5, tmpItem); 269 } 270 271 272