From b99bcddf656e489c88ee634f9411a62171aad03a Mon Sep 17 00:00:00 2001 From: nightwing Date: Wed, 22 Mar 2017 23:01:35 +0400 Subject: [PATCH] fix hotkey support --- plugins/c9.ide.ace/ace.js | 2 +- plugins/c9.ide.editors/tabmanager.js | 2 +- plugins/c9.ide.guide/guide.js | 5 +- plugins/c9.ide.language.core/quickfix.js | 4 +- plugins/c9.ide.panels/panel.js | 21 +-- plugins/c9.ide.preferences/preferences.js | 2 +- plugins/c9.ide.preview/preview.js | 4 +- plugins/c9.ide.run/gui.js | 2 +- plugins/c9.ide.terminal/terminal.js | 2 +- plugins/c9.ide.ui/forms.js | 85 ++++------ plugins/c9.ide.ui/lib/dropdown.js | 15 +- plugins/c9.ide.ui/lib/menu/menu.js | 46 +----- plugins/c9.ide.ui/lib_apf.js | 193 ++-------------------- plugins/c9.ide.ui/menus.js | 57 +++++-- plugins/c9.ide.ui/ui.js | 18 -- 15 files changed, 115 insertions(+), 343 deletions(-) diff --git a/plugins/c9.ide.ace/ace.js b/plugins/c9.ide.ace/ace.js index 64f38961..90399c4c 100644 --- a/plugins/c9.ide.ace/ace.js +++ b/plugins/c9.ide.ace/ace.js @@ -240,7 +240,7 @@ define(function(require, exports, module) { // detected from document value ["newLineMode", "unix", STRING, "newlinemode", 1], // Per document - ["tabSize", "4", NUMBER, "tabsize", 1], + ["tabSize", 4, NUMBER, "tabsize", 1], ["useSoftTabs", true, BOOL, "softtabs", 1], ["guessTabSize", true, BOOL, "guesstabsize", 1], ["useWrapMode", false, BOOL, "wrapmode"], diff --git a/plugins/c9.ide.editors/tabmanager.js b/plugins/c9.ide.editors/tabmanager.js index d6aab982..c65346e2 100644 --- a/plugins/c9.ide.editors/tabmanager.js +++ b/plugins/c9.ide.editors/tabmanager.js @@ -364,7 +364,7 @@ define(function(require, module, exports) { new ui.item({ caption: "New File", // TODO - // hotkey: "{commands.commandManager.newfile}", + hotkey: "commands.newfile", onclick: function(e) { e.pane = this.parentNode.pane; plusNewFile(e, true); diff --git a/plugins/c9.ide.guide/guide.js b/plugins/c9.ide.guide/guide.js index 1e8ae298..eb50fed3 100644 --- a/plugins/c9.ide.guide/guide.js +++ b/plugins/c9.ide.guide/guide.js @@ -178,10 +178,7 @@ define(function(require, exports, module) { thingy.onclick = function() { togglePopup(def); }; def.body = def.body.replace(/\$\{key:([a-zA-Z]+)\}/g, function(match, name) { - var key = commands.getHotkey(name); - if (commands.platform == "mac") - key = apf.hotkeys.toMacNotation(key); - return key; + return commands.getPrettyHotkey(name); }); def.el = el; diff --git a/plugins/c9.ide.language.core/quickfix.js b/plugins/c9.ide.language.core/quickfix.js index d4cb7228..45f1d3c0 100644 --- a/plugins/c9.ide.language.core/quickfix.js +++ b/plugins/c9.ide.language.core/quickfix.js @@ -25,9 +25,7 @@ define(function(require, exports, module) { loaded = true; commands.on("update", function() { - var key = commands.getHotkey("quickfix"); - if (commands.platform == "mac") - key = apf.hotkeys.toMacNotation(key); + var key = commands.getPrettyHotkey("quickfix"); language.getWorker(function(err, result) { if (err) return console.error(err); diff --git a/plugins/c9.ide.panels/panel.js b/plugins/c9.ide.panels/panel.js index 8853cb8e..f5f28bbd 100644 --- a/plugins/c9.ide.panels/panel.js +++ b/plugins/c9.ide.panels/panel.js @@ -144,18 +144,12 @@ define(function(require, module, exports) { options.extra.apply(this, arguments); } }, plugin); - - // TODO - // mnuItem.setAttribute("hotkey", - // "{commands.commandManager." + options.name + "}"); - - - if (button && button.setAttribute) { - var key = commands.getPrettyHotkey(options.name); - button.setAttribute("tooltip", options.name - + (key ? " (" + key + ")" : "")); + if (mnuItem) + mnuItem.setAttribute("hotkey", "commands." + options.name); + if (button) { + button.setAttribute("hotkey", "commands." + options.name); + button.setAttribute("tooltip", options.name); } - return command; } @@ -211,13 +205,16 @@ define(function(require, module, exports) { var container = area.draw(); if (!button) { + var hotkey = mnuItem && mnuItem.getAttribute("hotkey") || ""; // Insert button button = new ui.button({ skinset: "panels", state: true, caption: caption, auto: false, - "class": buttonCSSClass || "", + class: buttonCSSClass || "", + hotkey: hotkey, + tooltip: hotkey.slice(9), onmousedown: function(e) { if (e.htmlEvent && e.htmlEvent.button) return; panels.areas[where].toggle(plugin.name, autohide, true); diff --git a/plugins/c9.ide.preferences/preferences.js b/plugins/c9.ide.preferences/preferences.js index 998d0391..60226c42 100644 --- a/plugins/c9.ide.preferences/preferences.js +++ b/plugins/c9.ide.preferences/preferences.js @@ -90,7 +90,7 @@ define(function(require, exports, module) { menus.addItemToMenu(menu, new ui.item({ caption: "Open Preferences", - // hotkey: "{commands.commandManager.openpreferences}", + hotkey: "commands.openpreferences", onclick: function(e) { if (focusOpenPrefs()) return; diff --git a/plugins/c9.ide.preview/preview.js b/plugins/c9.ide.preview/preview.js index d7c866f5..698341d1 100644 --- a/plugins/c9.ide.preview/preview.js +++ b/plugins/c9.ide.preview/preview.js @@ -230,9 +230,7 @@ define(function(require, exports, module) { menu = new Menu({}, handle); // Preferences - var key = commands.getHotkey("reloadpreview"); - if (commands.platform == "mac") - key = apf.hotkeys.toMacNotation(key); + var key = commands.getPrettyHotkey("reloadpreview"); prefs.add({ "Project": { diff --git a/plugins/c9.ide.run/gui.js b/plugins/c9.ide.run/gui.js index 8671d19a..33f9f0fb 100644 --- a/plugins/c9.ide.run/gui.js +++ b/plugins/c9.ide.run/gui.js @@ -360,7 +360,7 @@ define(function(require, module, exports) { menus.addItemToMenu(tabs.getElement("mnuEditors"), new ui.item({ caption: "New Run Configuration", - // hotkey: "{commands.commandManager.showoutput}", + hotkey: "commands.showoutput", onclick: function(e) { commands.exec("showoutput", null, { pane: this.parentNode.pane diff --git a/plugins/c9.ide.terminal/terminal.js b/plugins/c9.ide.terminal/terminal.js index a4355d09..6fcbcda4 100644 --- a/plugins/c9.ide.terminal/terminal.js +++ b/plugins/c9.ide.terminal/terminal.js @@ -174,7 +174,7 @@ define(function(require, exports, module) { var ctxItem = menus.addItemToMenu(menu, new ui.item({ caption: "New Terminal", - // hotkey: "{commands.commandManager.openterminal}", + hotkey: "commands.openterminal", onclick: function(e) { tabs.open({ active: true, diff --git a/plugins/c9.ide.ui/forms.js b/plugins/c9.ide.ui/forms.js index 772a4baf..bf0628be 100644 --- a/plugins/c9.ide.ui/forms.js +++ b/plugins/c9.ide.ui/forms.js @@ -26,11 +26,6 @@ define(function(require, exports, module) { var debug = location.href.indexOf('menus=1') > -1; var headings = {}; - - if (!Form.proxy) { - Form.proxy = new apf.Class().$init(); - apf.nameserver.register("all", "Form", Form); - } var loaded; function load() { @@ -155,19 +150,6 @@ define(function(require, exports, module) { name = name.replace(/@(.*)/, "$1Attribute"); return name; } - - function createBind(path) { - var name = getName(path); - Form.proxy.setProperty(name, settings.get(path)); - Form.proxy.on("prop." + name, function(e) { - settings.set(path, e.value); - }); - settings.on(path, function(value) { - if (Form.proxy[name] != value) - Form.proxy.setProperty(name, value); - }, plugin); - return name //"{Form.proxy." + name + "}"; - } function createItem(heading, name, options, foreign) { if (!foreign) foreign = plugin; @@ -187,11 +169,14 @@ define(function(require, exports, module) { new ui.label({ width: width, maxwidth: maxwidth, caption: name + ":" }), new ui.checkbox({ value: options.path - ? createBind(options.path) + ? settings.get(options.path) : (options.defaultValue || ""), values: options.values, skin: "cboffline", onafterchange: function(e) { + if (options.path) + settings.set(options.path, e.value); + if (options.onchange) options.onchange({ value: e.value }); } @@ -199,15 +184,11 @@ define(function(require, exports, module) { ]; break; case "dropdown": - var model = options.model || new ui.model(); - var data = options.items; - if (data) model.load(data); - var dd; childNodes = [ new ui.label({ width: width, maxwidth: maxwidth, caption: name + ":" }), dd = new ui.dropdown({ - model: model, + items: options.items, width: options.width || widths.dropdown, skin: "black_dropdown", margin: "-1 0 0 0", @@ -239,12 +220,14 @@ define(function(require, exports, module) { new ui.spinner({ width: options.width || widths.spinner, value: options.path - ? createBind(options.path) + ? settings.get(options.path) : (options.defaultValue || ""), min: options.min || 0, max: options.max || 10, realtime: typeof options.realtime !== "undefined" ? options.realtime : 1, onafterchange: function(e) { + if (options.path) + settings.set(options.path, e.value); if (options.onchange) options.onchange({ value: e.value }); }, @@ -255,12 +238,14 @@ define(function(require, exports, module) { childNodes = [ new ui.checkbox({ value: options.checkboxPath - ? createBind(options.checkboxPath) + ? settings.get(options.checkboxPath) : (options.defaultCheckboxValue || ""), width: width, maxwidth: maxwidth, label: name + ":", skin: "checkbox_black", onafterchange: function(e) { + if (options.path) + settings.set(options.path, e.value); if (options.onchange) options.onchange({ value: e.value, type: "checkbox" }); }, @@ -268,12 +253,14 @@ define(function(require, exports, module) { new ui.spinner({ width: options.width || widths["checked-spinner"], value: options.path - ? createBind(options.path) + ? settings.get(options.path) : (options.defaultValue || ""), min: options.min || 0, max: options.max || 10, realtime: typeof options.realtime !== "undefined" ? options.realtime : 1, onafterchange: function(e) { + if (options.path) + settings.set(options.path, e.value); if (options.onchange) options.onchange({ value: e.value, type: "spinner" }); }, @@ -284,12 +271,14 @@ define(function(require, exports, module) { childNodes = [ new ui.checkbox({ value: options.path - ? createBind(options.path) + ? settings.get(options.path) : (options.defaultValue || ""), width: options.width || widths["checked-single"], label: name, skin: "checkbox_black", onafterchange: function(e) { + if (options.path) + settings.set(options.path, e.value); if (options.onchange) options.onchange({ value: e.value }); } @@ -305,10 +294,12 @@ define(function(require, exports, module) { "initial-message": options.message || "", width: options.width || widths.textbox, value: options.path - ? createBind(options.path) + ? settings.get(options.path) : (options.defaultValue || ""), realtime: typeof options.realtime !== "undefined" ? options.realtime : 1, onafterchange: function(e) { + if (options.path) + settings.set(options.path, e.value); if (options.onchange) options.onchange({ value: e.value }); }, @@ -322,7 +313,7 @@ define(function(require, exports, module) { skin: skins.password || "forminput", width: options.width || widths.password, value: options.path - ? createBind(options.path) + ? settings.get(options.path) : (options.defaultValue || ""), realtime: typeof options.realtime !== "undefined" ? options.realtime : 1 }) @@ -334,9 +325,15 @@ define(function(require, exports, module) { new ui.colorbox({ width: options.width || widths.colorbox, value: options.path - ? createBind(options.path) + ? settings.get(options.path) : (options.defaultValue || ""), - realtime: typeof options.realtime !== "undefined" ? options.realtime : 1 + realtime: typeof options.realtime !== "undefined" ? options.realtime : 1, + onafterchange: function(e) { + if (options.path) + settings.set(options.path, e.value); + if (options.onchange) + options.onchange({ value: e.value }); + }, }) ]; break; @@ -395,7 +392,7 @@ define(function(require, exports, module) { width: options.width || widths.textarea, height: options.height || 200, value: options.path - ? createBind(options.path) + ? settings.get(options.path) : (options.defaultValue || ""), realtime: typeof options.realtime !== "undefined" ? options.realtime : 1 }) @@ -417,7 +414,7 @@ define(function(require, exports, module) { ? "font-family: Monaco, Menlo, 'Ubuntu Mono', Consolas, source-code-pro, monospace; font-size: 10px" : "", value: options.path - ? createBind(options.path) + ? settings.get(options.path) : (options.defaultValue || ""), realtime: typeof options.realtime !== "undefined" ? options.realtime : 1 }) @@ -462,21 +459,11 @@ define(function(require, exports, module) { var dropdown = el.lastChild; if (item.items) { - var data = item.items.map(function(item) { - return ""; - }).join(""); - if (data) { - setTimeout(function() { - dropdown.$model.load("" + data + ""); - - setTimeout(function() { - var value = item.value || dropdown.value; - dropdown.value = -999; - dropdown.setAttribute("value", value); - }); - }); - } + dropdown.setChildren(item.items); + + var value = item.value || dropdown.value; + dropdown.value = -999; + dropdown.setAttribute("value", value); } else if (item.value) { dropdown.setAttribute("value", item.value); diff --git a/plugins/c9.ide.ui/lib/dropdown.js b/plugins/c9.ide.ui/lib/dropdown.js index 5a7fd182..d1a29866 100644 --- a/plugins/c9.ide.ui/lib/dropdown.js +++ b/plugins/c9.ide.ui/lib/dropdown.js @@ -104,10 +104,6 @@ apf.ChildValue = function(){ this.$norecur = true; - if (v.indexOf("{") > -1 || v.indexOf("[") > -1) - this.$setDynamicProperty(this.$childProperty, v); - else - if (this[this.$childProperty] != v) this.setProperty(this.$childProperty, v); @@ -144,13 +140,8 @@ apf.ChildValue = function(){ v = m && m[2] || ""; if (m && m[1]) v = "{" + v + "}"; - - if (v.indexOf("{") > -1 || v.indexOf("[") > -1) - this.$setDynamicProperty(this.$childProperty, v); - else - - this.setProperty(this.$childProperty, apf.html_entity_decode(v)); //@todo should be xml entity decode + this.setProperty(this.$childProperty, apf.html_entity_decode(v)); //@todo should be xml entity decode } else if (hasNoProp) this.$propHandlers[this.$childProperty].call(this, ""); @@ -491,6 +482,10 @@ apf.dropdown = function(struct, tagName) { this.addEventListener("popuphide", this.slideUp); + this.setChildren = function(data) { + + }; + // *** Keyboard Support *** // diff --git a/plugins/c9.ide.ui/lib/menu/menu.js b/plugins/c9.ide.ui/lib/menu/menu.js index f902c4c2..b8363083 100644 --- a/plugins/c9.ide.ui/lib/menu/menu.js +++ b/plugins/c9.ide.ui/lib/menu/menu.js @@ -1298,51 +1298,7 @@ apf.item = function(struct, tagName) { * ``` */ this.$propHandlers["hotkey"] = function(value) { - if (!this.$amlLoaded) { - var _self = this; - this.addEventListener("DOMNodeInsertedIntoDocument", function(e) { - if (_self.$hotkey && _self.hotkey) - apf.setNodeValue(this.$hotkey, apf.isMac - ? apf.hotkeys.toMacNotation(_self.hotkey) : _self.hotkey); - }); - } - else if (this.$hotkey) - apf.setNodeValue(this.$hotkey, apf.isMac ? apf.hotkeys.toMacNotation(value) : value); - - if (this.$lastHotkey) { - apf.hotkeys.remove(this.$lastHotkey[0], this.$lastHotkey[1]); - delete this.$lastHotkey[0]; - } - - if (value) { - this.$lastHotkey = [value]; - var _self = this; - apf.hotkeys.register(value, this.$lastHotkey[1] = function() { - if (_self.disabled || !_self.visible) - return; - - //hmm not very scalable... - if (_self.parentNode) { - var buttons = apf.document.getElementsByTagNameNS(apf.ns.aml, "button"); - for (var i = 0; i < buttons.length; i++) { - if (buttons[i].submenu == _self.parentNode.name) { - var btn = buttons[i]; - btn.$setState("Over", {}); - - $setTimeout(function() { - btn.$setState("Out", {}); - }, 200); - - break; - } - } - } - - _self.$down(); - _self.$up(); - _self.$click(); - }); - } + }; /** diff --git a/plugins/c9.ide.ui/lib_apf.js b/plugins/c9.ide.ui/lib_apf.js index d83c308d..f2a21420 100644 --- a/plugins/c9.ide.ui/lib_apf.js +++ b/plugins/c9.ide.ui/lib_apf.js @@ -1009,14 +1009,9 @@ apf.Class.prototype = new (function(){ //Check if property has changed if (isChanged) { - if (setAttr && !this.$funcHandlers[prop]) - this.setAttribute(prop, value, true); - if (this.$handlePropSet(prop, value, forceOnMe) === false) return; - - value = this[prop]; } @@ -1342,17 +1337,13 @@ apf.Class.prototype = new (function(){ //Remove dynamic properties - /*var f, i, l, h; - for (prop in this.$funcHandlers) { - h = this.$funcHandlers[prop]; - + for (var prop in this.$funcHandlers) { + var f = this.$funcHandlers[prop]; //Remove any bounds if relevant - if (h && typeof h != FUN) { - for (i = 0, l = h.length; i < l; i++) { - (f = h[i]).amlNode.removeEventListener(PROP + f.prop, f.handler); - } + if (f && f.amlNode) { + f.amlNode.removeEventListener(PROP + f.prop, f.handler); } - }*/ + } if (this.attributes) { @@ -1372,9 +1363,9 @@ apf.Class.prototype = new (function(){ } catch (ex) {} - for (var prop in this.$captureStack) this.$captureStack[prop] = null; - for (var prop in this.$eventsStack) this.$eventsStack[prop] = null; - for (var prop in this.$funcHandlers) this.$funcHandlers[prop] = null; + this.$eventsStack = {}; + this.$captureStack = {}; + this.$funcHandlers = {}; if (this.$bufferEvents) { for (var i = this.$bufferEvents.length - 1; i >= 0; i--) @@ -4192,106 +4183,6 @@ apf.getInheritedAttribute = function(xml, attr, func) { : result; }; - -/** - * Creates an XML node based on an xpath statement. - * - * @param {DOMNode} contextNode The DOM node that is subject to the query - * @param {String} xPath The xpath query - * @param {Array} [addedNodes] An array that is filled with the added nodes - * @param {Boolean} [forceNew] Defines whether a new node is always created - * @return {DOMNode} The last element found - */ -apf.createNodeFromXpath = function(contextNode, xPath, addedNodes, forceNew) { - // @todo generalize this to include attributes in if format [] - var xmlNode, foundpath = "", paths = xPath.replace(/('.*?')|(".*?")|\|/g, function(m, m1, m2) { - if (m1 || m2) return m1 || m2; - return "-%-|-%-"; - }).split("-%-|-%-")[0].replace(/('.*?')|(".*?")|\/(?!\/)/g, function(m, m1, m2) { - if (m1 || m2) return m1 || m2; - return "-%-|-%-"; - }).split("-%-|-%-"); - - if (!forceNew && (xmlNode = contextNode.selectSingleNode(xPath))) - return xmlNode; - - var len = paths.length - 1; - if (forceNew) { - if (paths[len].trim().match(/^\@(.*)$|^text\(\)$/)) - len--; - } - - //Directly forwarding to the document element because of a bug in the o3 xml lib - if (!paths[0]) { - contextNode = contextNode.ownerDocument.documentElement; - paths.shift();paths.shift(); - len--;len--; - } - - for (var addedNode, isAdding = false, i = 0; i < len; i++) { - if (!isAdding && contextNode.selectSingleNode(foundpath - + (i != 0 ? "/" : "") + paths[i])) { - foundpath += (i != 0 ? "/" : "") + paths[i];// + "/"; - continue; - } - - //Temp hack - var isAddId = paths[i].match(/(\w+)\[@([\w-]+)=(\w+)\]/); - - - if (isAddId) - paths[i] = isAddId[1]; - - isAdding = true; - addedNode = contextNode.selectSingleNode(foundpath || ".") - .appendChild(contextNode.ownerDocument.createElement(paths[i])); - - if (isAddId) { - addedNode.setAttribute(isAddId[2], isAddId[3]); - foundpath += (foundpath ? "/" : "") + isAddId[0];// + "/"; - } - else - foundpath += (foundpath ? "/" : "") + paths[i];// + "/"; - - if (addedNodes) - addedNodes.push(addedNode); - } - - if (!foundpath) - foundpath = "."; - if (addedNodes) - addedNodes.foundpath = foundpath; - - var newNode, lastpath = paths[len], - doc = contextNode.nodeType == 9 ? contextNode : contextNode.ownerDocument; - do { - if (lastpath.match(/^\@(.*)$/)) { - (newNode || contextNode.selectSingleNode(foundpath)) - .setAttributeNode(newNode = doc.createAttribute(RegExp.$1)); - } - else if (lastpath.trim() == "text()") { - newNode = (newNode || contextNode.selectSingleNode(foundpath)) - .appendChild(doc.createTextNode("")); - } - else { - var hasId = lastpath.match(/(\w+)\[@([\w-]+)=(\w+)\]/); - if (hasId) lastpath = hasId[1]; - newNode = (newNode || contextNode.selectSingleNode(foundpath)) - .appendChild(doc.createElement(lastpath)); - if (hasId) - newNode.setAttribute(hasId[2], hasId[3]); - } - - if (addedNodes) - addedNodes.push(newNode); - - foundpath += (foundpath ? "/" : "") + paths[len]; - } while ((lastpath = paths[++len])); - - return newNode; -}; - - /** * Returns the first text or cdata child of a [[term.datanode data node]]. * @@ -8981,14 +8872,7 @@ apf.AmlElement = function(struct, tagName) { this.$inheritProperties[prop] = 2; if (value) { - - if (typeof value == "string" - && (value.indexOf("{") > -1 || value.indexOf("[") > -1)) { - this.$setDynamicProperty(prop, value); - } - else - - this.setProperty(prop, value, false, false, 2); + this.setProperty(prop, value, false, false, 2); } return value; @@ -9263,15 +9147,7 @@ apf.AmlAttr = function(ownerElement, name, value) { return; } - if (host.localName != "page" && typeof value == "string" && ( - (value.indexOf("{") > -1 || value.indexOf("[") > -1))) - host.$setDynamicProperty(name, value); - else - - { - host.setProperty(name, value); //@todo apf3.0 is this a lot slower? - } - //host.$handlePropSet(name, value); + host.setProperty(name, value); //@todo apf3.0 is this a lot slower? if (this.specified) { //@todo apf3.0 domattr - slow? @@ -17190,51 +17066,6 @@ apf.button = function(struct, tagName) { }; - /** - * @attribute {String} hotkey Sets or gets the key combination a user can press - * to active the function of this element. Use any combination of - * [[keys: Ctrl]], [[keys: Shift]], [[keys: Alt]], [[keys: F1]]-[[keys: F12]], and alphanumerical characters. Use a - * space, a minus or plus sign as a seperator. - * - * #### Example - * - * ```xml - * Undo - * ``` - */ - this.$propHandlers["hotkey"] = function(value) { - if (this.$hotkey) - apf.setNodeValue(this.$hotkey, value); - - if (this.$lastHotkey) { - apf.hotkeys.remove(this.$lastHotkey[0], this.$lastHotkey[1]); - delete this.$lastHotkey[0]; - } - - if (value) { - this.$lastHotkey = [value]; - var _self = this; - apf.hotkeys.register(value, this.$lastHotkey[1] = function(){ - //hmm not very scalable... - _self.$setState("Over", {}); - - $setTimeout(function(){ - _self.$setState("Out", {}); - }, 200); - - if (_self.$clickHandler && _self.$clickHandler()) - _self.$updateState(e || event, "click"); - else - _self.dispatchEvent("click"); - }); - } - - if (this.tooltip) - apf.GuiElement.propHandlers.tooltip.call(this, this.tooltip); - } - - - //@todo move this to menu.js function menuKeyHandler(e) { @@ -17729,6 +17560,7 @@ apf.checkbox = function(struct, tagName) { this.change = this.setValue = function(value) { this.setProperty("value", value, false, true); + this.dispatchEvent("afterchange", { value: value }); }; /** @@ -20868,7 +20700,8 @@ apf.spinner = function(struct, tagName) { */ this.change = this.setValue = function(value) { - this.setProperty("value", value, false, true); + this.setProperty("value", value, false, true); + this.dispatchEvent("afterchange", { value: value }); }; /** diff --git a/plugins/c9.ide.ui/menus.js b/plugins/c9.ide.ui/menus.js index 6f7b4042..7f247501 100644 --- a/plugins/c9.ide.ui/menus.js +++ b/plugins/c9.ide.ui/menus.js @@ -1,3 +1,4 @@ +/*global apf*/ define(function(require, exports, module) { main.consumes = ["Plugin", "settings", "commands", "layout", "anims", "ui", "c9"]; main.provides = ["menus", "Menu", "MenuItem", "Divider"]; @@ -48,13 +49,44 @@ define(function(require, exports, module) { // Hook deep into APF to make hotkeys work as we want + function formatHotkey(value) { + if (value && /^commands./.test(value)) + value = commands.getHotkey(value.slice(9)); + if (apf.isMac && value) + value = apf.hotkeys.toMacNotation(value); + return value; + } + + function addHotkeyListener(amlNode, value) { + var oldHandler = amlNode.$funcHandlers.hotkey; + if (oldHandler && oldHandler.value != value) { + commands.commandManager.off("prop." + oldHandler.prop, oldHandler.handler); + } + if (value && /^commands./.test(value)) { + // TODO replace this with the mechanism from events + oldHandler = amlNode.$funcHandlers.hotkey = oldHandler || { + handler: function(e) { + amlNode.$propHandlers["hotkey"].call(amlNode, amlNode.hotkey); + } + }; + oldHandler.prop = value.slice(9); + oldHandler.amlNode = commands.commandManager; + commands.commandManager.on("prop." + oldHandler.prop, oldHandler.handler); + } + } + apf.button.prototype.$propHandlers["hotkey"] = function(value) { if (this.$hotkey) - apf.setNodeValue(this.$hotkey, apf.isMac - ? apf.hotkeys.toMacNotation(this.hotkey) : this.hotkey); - - if (this.tooltip) - apf.GuiElement.propHandlers.tooltip.call(this, this.tooltip); + apf.setNodeValue(this.$hotkey, formatHotkey(value)); + this.$propHandlers["tooltip"].call(this, this.tooltip); + addHotkeyListener(this, value); + }; + apf.button.prototype.$propHandlers["tooltip"] = function(value) { + if (this.$ext) { + var hotkey = formatHotkey(this.hotkey); + this.$ext.setAttribute("title", (this.tooltip || "") + + (hotkey ? " (" + hotkey + ")" : "")); + } }; apf.item.prototype.$propHandlers["hotkey"] = function(value) { @@ -62,13 +94,12 @@ define(function(require, exports, module) { var _self = this; this.addEventListener("DOMNodeInsertedIntoDocument", function(e) { if (_self.$hotkey && _self.hotkey) - apf.setNodeValue(this.$hotkey, apf.isMac - ? apf.hotkeys.toMacNotation(this.hotkey) : this.hotkey); + apf.setNodeValue(this.$hotkey, formatHotkey(_self.hotkey)); }); } else if (this.$hotkey) - apf.setNodeValue(this.$hotkey, - apf.isMac ? apf.hotkeys.toMacNotation(value || "") : value); + apf.setNodeValue(this.$hotkey, formatHotkey(value)); + addHotkeyListener(this, value); }; apf.splitbutton.prototype.$propHandlers["command"] = @@ -80,9 +111,7 @@ define(function(require, exports, module) { return; } - // TODO - // this.setAttribute("hotkey", - // value && "{commands.commandManager." + value + "}" || ""); + this.setAttribute("hotkey", value && "commands." + value || ""); this.onclick = function(e) { if (e && e.htmlEvent && e.htmlEvent.button) return; @@ -90,7 +119,7 @@ define(function(require, exports, module) { var command = commands.commands[value]; if (command && command.focusContext) emit("focusEditor"); - } || null; + }; }; settings.on("read", function(e) { @@ -395,7 +424,7 @@ define(function(require, exports, module) { if (itemName != "~") { if (debug) itemName = "(" + index + ") " + itemName; - item.setAttribute("caption", itemName.replace(/[\[\]]/, "\\$&")); + item.setAttribute("caption", itemName); } } diff --git a/plugins/c9.ide.ui/ui.js b/plugins/c9.ide.ui/ui.js index 397485ae..e74bc598 100644 --- a/plugins/c9.ide.ui/ui.js +++ b/plugins/c9.ide.ui/ui.js @@ -597,15 +597,6 @@ define(function(require, module, exports) { */ insertByIndex: insertByIndex, - /** - * @ignore - */ - n: apf.n, - - /** - * @ignore - */ - b: apf.b, /** * Escapes "&", greater than, less than signs, quotation marks, @@ -741,11 +732,6 @@ define(function(require, module, exports) { */ removeClass: removeClass, - /** - * @ignore - */ - createNodeFromXpath: apf.createNodeFromXpath, - /** * Determines whether a string is true (in the HTML attribute sense). * @param {Mixed} value The variable to check. Possible truth values include: @@ -774,10 +760,6 @@ define(function(require, module, exports) { */ isFalse: apf.isFalse, - /** - * @ignore - */ - getCleanCopy: apf.getCleanCopy, /** * This method retrieves the current value of a CSS property on an