From a414046b7f3da21b74bab0c6bea2a89342ba644d Mon Sep 17 00:00:00 2001 From: Mihai Sucan Date: Mon, 27 Feb 2012 20:08:45 +0200 Subject: [PATCH] Bug 684445 - Orion source editor should have built-in context menu; r=rcampbell f=rcampbell --- browser/devtools/scratchpad/scratchpad.js | 38 +--------- browser/devtools/scratchpad/scratchpad.xul | 18 ++--- .../scratchpad/test/browser_scratchpad_ui.js | 2 - .../sourceeditor/source-editor-orion.jsm | 51 +++++++++++++- .../sourceeditor/source-editor-overlay.xul | 69 ++++++++++++++++++- .../sourceeditor/source-editor-ui.jsm | 45 ++++++++++++ .../devtools/sourceeditor/source-editor.jsm | 24 +++++++ browser/devtools/styleeditor/styleeditor.xul | 10 +++ .../chrome/browser/devtools/sourceeditor.dtd | 32 +++++++++ browser/locales/jar.mn | 1 + 10 files changed, 237 insertions(+), 53 deletions(-) create mode 100644 browser/locales/en-US/chrome/browser/devtools/sourceeditor.dtd diff --git a/browser/devtools/scratchpad/scratchpad.js b/browser/devtools/scratchpad/scratchpad.js index cc2c289aeb10..baf73c11f796 100644 --- a/browser/devtools/scratchpad/scratchpad.js +++ b/browser/devtools/scratchpad/scratchpad.js @@ -831,6 +831,7 @@ var Scratchpad = { mode: SourceEditor.MODES.JAVASCRIPT, showLineNumbers: true, initialText: initialText, + contextMenu: "scratchpad-text-popup", }; let editorPlaceholder = document.getElementById("scratchpad-editor"); @@ -848,8 +849,6 @@ var Scratchpad = { */ _onEditorLoad: function SP__onEditorLoad(aState) { - this.editor.addEventListener(SourceEditor.EVENTS.CONTEXT_MENU, - this.onContextMenu); this.editor.addEventListener(SourceEditor.EVENTS.DIRTY_CHANGED, this._onDirtyChanged); this.editor.focus(); @@ -876,22 +875,6 @@ var Scratchpad = { this.editor.setCaretOffset(caretOffset + aText.length); }, - /** - * The contextmenu event handler for the source editor. This method opens the - * Scratchpad context menu popup at the pointer location. - * - * @param object aEvent - * An event object coming from the SourceEditor. This object needs to - * hold the screenX and screenY properties. - */ - onContextMenu: function SP_onContextMenu(aEvent) - { - let menu = document.getElementById("scratchpad-text-popup"); - if (menu.state == "closed") { - menu.openPopupAtScreen(aEvent.screenX, aEvent.screenY, true); - } - }, - /** * The Source Editor DirtyChanged event handler. This function updates the * Scratchpad window title to show an asterisk when there are unsaved changes. @@ -906,23 +889,6 @@ var Scratchpad = { Scratchpad._updateTitle(); }, - /** - * The popupshowing event handler for the Edit menu. This method updates the - * enabled/disabled state of the Undo and Redo commands, based on the editor - * state such that the menu items render correctly for the user when the menu - * shows. - */ - onEditPopupShowing: function SP_onEditPopupShowing() - { - goUpdateGlobalEditMenuItems(); - - let undo = document.getElementById("sp-cmd-undo"); - undo.setAttribute("disabled", !this.editor.canUndo()); - - let redo = document.getElementById("sp-cmd-redo"); - redo.setAttribute("disabled", !this.editor.canRedo()); - }, - /** * Undo the last action of the user. */ @@ -954,8 +920,6 @@ var Scratchpad = { this.resetContext(); this.editor.removeEventListener(SourceEditor.EVENTS.DIRTY_CHANGED, this._onDirtyChanged); - this.editor.removeEventListener(SourceEditor.EVENTS.CONTEXT_MENU, - this.onContextMenu); this.editor.destroy(); this.editor = null; this.initialized = false; diff --git a/browser/devtools/scratchpad/scratchpad.xul b/browser/devtools/scratchpad/scratchpad.xul index b0dc59960bb6..7efe53bed14e 100644 --- a/browser/devtools/scratchpad/scratchpad.xul +++ b/browser/devtools/scratchpad/scratchpad.xul @@ -81,11 +81,11 @@ - - + + + command="se-cmd-undo"/> + command="se-cmd-redo"/> #endif - @@ -223,17 +219,17 @@ + onpopupshowing="goUpdateGlobalEditMenuItems()"> + command="se-cmd-undo"/> + command="se-cmd-redo"/> - + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/browser/devtools/sourceeditor/source-editor-ui.jsm b/browser/devtools/sourceeditor/source-editor-ui.jsm index 8833ac0e0ce4..c28c590685d7 100644 --- a/browser/devtools/sourceeditor/source-editor-ui.jsm +++ b/browser/devtools/sourceeditor/source-editor-ui.jsm @@ -50,6 +50,7 @@ var EXPORTED_SYMBOLS = ["SourceEditorUI"]; function SourceEditorUI(aEditor) { this.editor = aEditor; + this._onDirtyChanged = this._onDirtyChanged.bind(this); } SourceEditorUI.prototype = { @@ -72,6 +73,8 @@ SourceEditorUI.prototype = { if (this._ownerWindow.controllers) { this._controller = new SourceEditorController(this.editor); this._ownerWindow.controllers.insertControllerAt(0, this._controller); + this.editor.addEventListener(this.editor.EVENTS.DIRTY_CHANGED, + this._onDirtyChanged); } }, @@ -177,12 +180,40 @@ SourceEditorUI.prototype = { } }, + /** + * This is executed after each undo/redo operation. + * @private + */ + _onUndoRedo: function SEU__onUndoRedo() + { + if (this._ownerWindow.goUpdateCommand) { + this._ownerWindow.goUpdateCommand("se-cmd-undo"); + this._ownerWindow.goUpdateCommand("se-cmd-redo"); + } + }, + + /** + * The DirtyChanged event handler for the editor. This tracks the editor state + * changes to make sure the Source Editor overlay Undo/Redo commands are kept + * up to date. + * @private + */ + _onDirtyChanged: function SEU__onDirtyChanged() + { + this._onUndoRedo(); + }, + /** * Destroy the SourceEditorUI instance. This is called by the * SourceEditor.destroy() method. */ destroy: function SEU_destroy() { + if (this._ownerWindow.controllers) { + this.editor.removeEventListener(this.editor.EVENTS.DIRTY_CHANGED, + this._onDirtyChanged); + } + this._ownerWindow = null; this.editor = null; this._controller = null; @@ -220,6 +251,8 @@ SourceEditorController.prototype = { case "cmd_findAgain": case "cmd_findPrevious": case "cmd_gotoLine": + case "se-cmd-undo": + case "se-cmd-redo": result = true; break; default: @@ -251,6 +284,12 @@ SourceEditorController.prototype = { case "cmd_findPrevious": result = this._editor.lastFind && this._editor.lastFind.lastFound != -1; break; + case "se-cmd-undo": + result = this._editor.canUndo(); + break; + case "se-cmd-redo": + result = this._editor.canRedo(); + break; default: result = false; break; @@ -281,6 +320,12 @@ SourceEditorController.prototype = { case "cmd_gotoLine": this._editor.ui.gotoLine(); break; + case "se-cmd-undo": + this._editor.undo(); + break; + case "se-cmd-redo": + this._editor.redo(); + break; } }, diff --git a/browser/devtools/sourceeditor/source-editor.jsm b/browser/devtools/sourceeditor/source-editor.jsm index 31a81800d274..ae02faea5a54 100644 --- a/browser/devtools/sourceeditor/source-editor.jsm +++ b/browser/devtools/sourceeditor/source-editor.jsm @@ -199,6 +199,22 @@ SourceEditor.DEFAULTS = { * @type array */ keys: null, + + /** + * The editor context menu you want to display when the user right-clicks + * within the editor. This property can be: + * - a string that tells the ID of the xul:menupopup you want. This needs to + * be available within the editor parentElement.ownerDocument. + * - an nsIDOMElement object reference pointing to the xul:menupopup you + * want to open when the contextmenu event is fired. + * + * Set this property to a falsey value to disable the default context menu. + * + * @see SourceEditor.EVENTS.CONTEXT_MENU for more control over the contextmenu + * event. + * @type string|nsIDOMElement + */ + contextMenu: "sourceEditorContextMenu", }; /** @@ -216,6 +232,8 @@ SourceEditor.EVENTS = { * This value comes from the DOM contextmenu event.screenX property. * - screenY - the pointer location on the y axis, relative to the screen. * This value comes from the DOM contextmenu event.screenY property. + * + * @see SourceEditor.DEFAULTS.contextMenu */ CONTEXT_MENU: "ContextMenu", @@ -312,6 +330,12 @@ function extend(aDestination, aSource) * Add methods common to all components. */ extend(SourceEditor.prototype, { + // Expose the static constants on the SourceEditor instances. + EVENTS: SourceEditor.EVENTS, + MODES: SourceEditor.MODES, + THEMES: SourceEditor.THEMES, + DEFAULTS: SourceEditor.DEFAULTS, + _lastFind: null, /** diff --git a/browser/devtools/styleeditor/styleeditor.xul b/browser/devtools/styleeditor/styleeditor.xul index e84df003c0f0..d27b9db46e1f 100644 --- a/browser/devtools/styleeditor/styleeditor.xul +++ b/browser/devtools/styleeditor/styleeditor.xul @@ -45,6 +45,8 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/browser/locales/jar.mn b/browser/locales/jar.mn index 53e66a8a5efc..3f6ec78b0625 100644 --- a/browser/locales/jar.mn +++ b/browser/locales/jar.mn @@ -30,6 +30,7 @@ locale/browser/devtools/styleinspector.dtd (%chrome/browser/devtools/styleinspector.dtd) locale/browser/devtools/webConsole.dtd (%chrome/browser/devtools/webConsole.dtd) locale/browser/devtools/sourceeditor.properties (%chrome/browser/devtools/sourceeditor.properties) + locale/browser/devtools/sourceeditor.dtd (%chrome/browser/devtools/sourceeditor.dtd) locale/browser/newTab.dtd (%chrome/browser/newTab.dtd) locale/browser/newTab.properties (%chrome/browser/newTab.properties) locale/browser/openLocation.dtd (%chrome/browser/openLocation.dtd)