1 /* See license.txt for terms of usage */ 2 3 define([ 4 "firebug/lib/lib", 5 "firebug/lib/object", 6 "firebug/firebug", 7 "firebug/chrome/firefox", 8 ], 9 function(FBL, Obj, Firebug, Firefox) { 10 11 // ************************************************************************************************ 12 // Constants 13 14 Components.utils.import("resource://gre/modules/Services.jsm"); 15 16 var KeyEvent = window.KeyEvent; 17 18 // ************************************************************************************************ 19 20 /** 21 * ShortcutsModel object implements keyboard shortcuts logic. 22 */ 23 Firebug.ShortcutsModel = Obj.extend(Firebug.Module, 24 { 25 dispatchName: "shortcuts", 26 27 initializeUI: function() 28 { 29 if (FBTrace.DBG_SHORTCUTS) 30 FBTrace.sysout("shortcuts.initializeUI; Shortcuts module initialization."); 31 32 this.initShortcuts(); 33 }, 34 35 initShortcuts: function() 36 { 37 var branch = Services.prefs.getBranch("extensions.firebug.key.shortcut."); 38 var shortcutNames = branch.getChildList("", {}); 39 40 // We need to touch keyset to apply keychanges without restart 41 this.keysets = []; 42 this.disabledKeyElements = []; 43 shortcutNames.forEach(this.initShortcut, this); 44 45 this.keysets.forEach(function(keyset) { 46 keyset.parentNode.insertBefore(keyset, keyset.nextSibling); 47 }); 48 49 for (var i=0; i<this.disabledKeyElements.length; i++) 50 { 51 var elem = this.disabledKeyElements[i]; 52 elem.removeAttribute("disabled"); 53 } 54 55 this.keysets = this.disabledKeyElements = null; 56 }, 57 58 initShortcut: function(element, index, array) 59 { 60 var branch = Services.prefs.getBranch("extensions.firebug.key."); 61 var shortcut = branch.getCharPref("shortcut." + element); 62 var tokens = shortcut.split(" "); 63 var key = tokens.pop(); 64 var modifiers = tokens.join(","); 65 66 var keyElem = document.getElementById("key_firebug_" + element); 67 if (!keyElem) 68 { 69 // If key is not defined in xul, add it 70 keyElem = document.createElement("key"); 71 keyElem.className = "fbOnlyKey"; 72 keyElem.id = "key_firebug_" + element; 73 keyElem.command = "cmd_firebug_" + element; 74 document.getElementById("mainKeyset").appendChild(keyElem); 75 } 76 77 // invalidAttr needed in case default shortcut uses key rather than keycode 78 var attr = "key"; 79 var invalidAttr = "key"; 80 81 // Choose between key or keycode attribute 82 if (key.length <= 1) 83 { 84 invalidAttr = "keycode"; 85 } 86 else if (KeyEvent["DOM_"+key]) 87 { 88 attr = "keycode"; 89 } 90 else 91 { 92 // Only set valid keycodes 93 return; 94 } 95 96 keyElem.setAttribute("modifiers", modifiers); 97 keyElem.setAttribute(attr, key); 98 keyElem.removeAttribute(invalidAttr); 99 100 if (this.keysets.indexOf(keyElem.parentNode) == -1) 101 this.keysets.push(keyElem.parentNode); 102 103 // Modify shortcut for global key, if it exists 104 var keyElem = Firefox.getElementById("key_firebug_" + element); 105 if (!keyElem) 106 return; 107 108 if (FBTrace.DBG_SHORTCUTS) 109 { 110 FBTrace.sysout("Firebug.ShortcutsModel.initShortcut; global shortcut", 111 {key: key, modifiers: modifiers}); 112 } 113 114 // Disable existing global shortcuts 115 var selector = "key[" + attr + "='" + key + "'][modifiers='" + modifiers + "']" 116 + ":not([id='key_firebug_" + element + "']):not([disabled='true'])"; 117 118 var existingKeyElements = keyElem.ownerDocument.querySelectorAll(selector); 119 for (var i=existingKeyElements.length-1; i>=0; i--) 120 { 121 var existingKeyElement = existingKeyElements[i]; 122 existingKeyElement.setAttribute("disabled", "true"); 123 this.disabledKeyElements.push(existingKeyElement); 124 } 125 126 keyElem.setAttribute("modifiers", modifiers); 127 keyElem.setAttribute(attr, key); 128 keyElem.removeAttribute(invalidAttr); 129 130 if (this.keysets.indexOf(keyElem.parentNode) == -1) 131 this.keysets.push(keyElem.parentNode); 132 }, 133 134 // UI Commands 135 customizeShortcuts: function() 136 { 137 var args = { 138 FBL: FBL, 139 FBTrace: FBTrace 140 }; 141 142 // Open the "customize shortcuts" dialog. Pass FBL into the XUL window so that 143 // common APIs can be used (e.g. localization). 144 window.openDialog("chrome://firebug/content/firefox/customizeShortcuts.xul", "", 145 "chrome,centerscreen,dialog,modal,resizable=yes", args); 146 } 147 }); 148 149 // ************************************************************************************************ 150 // Registration 151 152 Firebug.registerModule(Firebug.ShortcutsModel); 153 154 return Firebug.ShortcutsModel; 155 156 // ************************************************************************************************ 157 }); 158