From f611b7caca8fd1b3a6cba7484800118e05f70bee Mon Sep 17 00:00:00 2001 From: Mihai Sucan Date: Fri, 11 Nov 2011 19:36:26 +0200 Subject: [PATCH] Bug 583041 - Style Editor integration; part 4 - orion fixes; r=rcampbell --- browser/devtools/sourceeditor/orion/README | 2 + browser/devtools/sourceeditor/orion/orion.js | 4 +- .../sourceeditor/source-editor-orion.jsm | 22 +++++ browser/devtools/styleeditor/SplitView.jsm | 5 +- browser/devtools/styleeditor/StyleEditor.jsm | 90 ++++++++++++++----- .../styleeditor/StyleEditorChrome.jsm | 7 +- browser/devtools/styleeditor/styleeditor.xul | 2 +- .../browser/devtools/styleeditor.properties | 11 +++ 8 files changed, 113 insertions(+), 30 deletions(-) diff --git a/browser/devtools/sourceeditor/orion/README b/browser/devtools/sourceeditor/orion/README index 7459f63fc7e..c8703c947f4 100644 --- a/browser/devtools/sourceeditor/orion/README +++ b/browser/devtools/sourceeditor/orion/README @@ -25,6 +25,8 @@ Orion version: git clone from 2011-10-26 + patch for Eclipse Bug 362835 - Pasted HTML shows twice: https://github.com/mihaisucan/orion.client/tree/bug-362835 see https://bugs.eclipse.org/bugs/show_bug.cgi?id=362835 + + patch for Eclipse Bug 363508 - Selection is broken after TextView hide/unhide + see https://bugs.eclipse.org/bugs/show_bug.cgi?id=363508 # License diff --git a/browser/devtools/sourceeditor/orion/orion.js b/browser/devtools/sourceeditor/orion/orion.js index 1a304615b0d..7b73fb1f02f 100644 --- a/browser/devtools/sourceeditor/orion/orion.js +++ b/browser/devtools/sourceeditor/orion/orion.js @@ -1952,7 +1952,7 @@ if (typeof window !== "undefined" && typeof window.define !== "undefined") { * Contributors: * Felipe Heidrich (IBM Corporation) - initial API and implementation * Silenio Quarti (IBM Corporation) - initial API and implementation - * Mihai Sucan (Mozilla Foundation) - fix for Bug#334583 Bug#348471 Bug#349485 Bug#350595 Bug#360726 Bug#361180 Bug#358623 Bug#362286 Bug#362107 Bug#362428 Bug#362835 + * Mihai Sucan (Mozilla Foundation) - fix for Bug#334583 Bug#348471 Bug#349485 Bug#350595 Bug#360726 Bug#361180 Bug#358623 Bug#362286 Bug#362107 Bug#362428 Bug#362835 Bug#363508 ******************************************************************************/ /*global window document navigator setTimeout clearTimeout XMLHttpRequest define */ @@ -3864,6 +3864,8 @@ orion.textview.TextView = (function() { if (!this._hasFocus) { this.focus(); } + } + if (e.preventDefault) { e.preventDefault(); } } diff --git a/browser/devtools/sourceeditor/source-editor-orion.jsm b/browser/devtools/sourceeditor/source-editor-orion.jsm index 183ec25fb2f..b78b1c04e78 100644 --- a/browser/devtools/sourceeditor/source-editor-orion.jsm +++ b/browser/devtools/sourceeditor/source-editor-orion.jsm @@ -557,6 +557,28 @@ SourceEditor.prototype = { this._view.focus(); }, + /** + * Get the first visible line number. + * + * @return number + * The line number, counting from 0. + */ + getTopIndex: function SE_getTopIndex() + { + return this._view.getTopIndex(); + }, + + /** + * Set the first visible line number. + * + * @param number aTopIndex + * The line number, counting from 0. + */ + setTopIndex: function SE_setTopIndex(aTopIndex) + { + this._view.setTopIndex(aTopIndex); + }, + /** * Check if the editor has focus. * diff --git a/browser/devtools/styleeditor/SplitView.jsm b/browser/devtools/styleeditor/SplitView.jsm index 2b083ba1bbb..6edf5a81781 100644 --- a/browser/devtools/styleeditor/SplitView.jsm +++ b/browser/devtools/styleeditor/SplitView.jsm @@ -160,12 +160,13 @@ SplitView.prototype = { if (this._activeSummary) { let binding = this._activeSummary.getUserData(BINDING_USERDATA); - this._activeSummary.classList.remove("splitview-active"); - binding._details.classList.remove("splitview-active"); if (binding.onHide) { binding.onHide(this._activeSummary, binding._details, binding.data); } + + this._activeSummary.classList.remove("splitview-active"); + binding._details.classList.remove("splitview-active"); } if (!aSummary) { diff --git a/browser/devtools/styleeditor/StyleEditor.jsm b/browser/devtools/styleeditor/StyleEditor.jsm index ed04c5fe946..de4dab0bdc0 100644 --- a/browser/devtools/styleeditor/StyleEditor.jsm +++ b/browser/devtools/styleeditor/StyleEditor.jsm @@ -88,7 +88,8 @@ function StyleEditor(aDocument, aStyleSheet) this._state = { // state to handle inputElement attach/detach text: "", // seamlessly selection: {start: 0, end: 0}, - readOnly: false + readOnly: false, + topIndex: 0, // the first visible line }; this._styleSheet = aStyleSheet; @@ -106,8 +107,6 @@ function StyleEditor(aDocument, aStyleSheet) // this is to perform pending updates before editor closing this._onWindowUnloadBinding = this._onWindowUnload.bind(this); - // this is to proxy the focus event to underlying SourceEditor - this._onInputElementFocusBinding = this._onInputElementFocus.bind(this); this._focusOnSourceEditorReady = false; } @@ -177,7 +176,8 @@ StyleEditor.prototype = { this._state = { text: this._sourceEditor.getText(), selection: this._sourceEditor.getSelection(), - readOnly: this._sourceEditor.readOnly + readOnly: this._sourceEditor.readOnly, + topIndex: this._sourceEditor.getTopIndex(), }; this._sourceEditor.destroy(); this._sourceEditor = null; @@ -185,8 +185,6 @@ StyleEditor.prototype = { this.window.removeEventListener("unload", this._onWindowUnloadBinding, false); - this._inputElement.removeEventListener("focus", - this._onInputElementFocusBinding, true); this._triggerAction("Detach"); } @@ -198,7 +196,6 @@ StyleEditor.prototype = { // attach to new input element this.window.addEventListener("unload", this._onWindowUnloadBinding, false); this._focusOnSourceEditorReady = false; - aElement.addEventListener("focus", this._onInputElementFocusBinding, true); this._sourceEditor = null; // set it only when ready (safe to use) @@ -212,19 +209,22 @@ StyleEditor.prototype = { }; sourceEditor.init(aElement, config, function onSourceEditorReady() { - sourceEditor.setSelection(this._state.selection.start, - this._state.selection.end); - - if (this._focusOnSourceEditorReady) { - sourceEditor.focus(); - } - sourceEditor.addEventListener(SourceEditor.EVENTS.TEXT_CHANGED, function onTextChanged(aEvent) { this.updateStyleSheet(); }.bind(this)); this._sourceEditor = sourceEditor; + + if (this._focusOnSourceEditorReady) { + this._focusOnSourceEditorReady = false; + sourceEditor.focus(); + } + + sourceEditor.setTopIndex(this._state.topIndex); + sourceEditor.setSelection(this._state.selection.start, + this._state.selection.end); + this._triggerAction("Attach"); }.bind(this)); }, @@ -913,13 +913,9 @@ StyleEditor.prototype = { }, /** - * Focus event handler to automatically proxy inputElement's focus event to - * SourceEditor whenever it is ready. - * SourceEditor should probably have a command buffer so that timing issues - * related to iframe implementation details are handled by itself rather than - * by all its users. - */ - _onInputElementFocus: function SE__onInputElementFocus(aEvent) + * Focus the Style Editor input. + */ + focus: function SE_focus() { if (this._sourceEditor) { this._sourceEditor.focus(); @@ -928,6 +924,29 @@ StyleEditor.prototype = { } }, + /** + * Event handler for when the editor is shown. Call this after the editor is + * shown. + */ + onShow: function SE_onShow() + { + if (this._sourceEditor) { + this._sourceEditor.setTopIndex(this._state.topIndex); + } + this.focus(); + }, + + /** + * Event handler for when the editor is hidden. Call this before the editor is + * hidden. + */ + onHide: function SE_onHide() + { + if (this._sourceEditor) { + this._state.topIndex = this._sourceEditor.getTopIndex(); + } + }, + /** * Persist StyleEditor extra data to the attached DOM stylesheet expando. * The expando on the DOM stylesheet is used to restore user-facing state @@ -935,7 +954,8 @@ StyleEditor.prototype = { * * @see styleSheet */ - _persistExpando: function SE__persistExpando() { + _persistExpando: function SE__persistExpando() + { if (!this._styleSheet) { return; // not loaded } @@ -954,7 +974,8 @@ StyleEditor.prototype = { * * @see styleSheet */ - _restoreExpando: function SE__restoreExpando() { + _restoreExpando: function SE__restoreExpando() + { if (!this._styleSheet) { return; // not loaded } @@ -972,7 +993,8 @@ StyleEditor.prototype = { * * @return Array */ - _getKeyBindings: function () { + _getKeyBindings: function SE__getKeyBindings() + { let bindings = []; bindings.push({ @@ -983,6 +1005,7 @@ StyleEditor.prototype = { this.saveToFile(this._savedFile); }.bind(this) }); + bindings.push({ action: "StyleEditor.saveAs", code: _("saveStyleSheet.commandkey"), @@ -993,6 +1016,25 @@ StyleEditor.prototype = { }.bind(this) }); + bindings.push({ + action: "undo", + code: _("undo.commandkey"), + accel: true, + callback: function undo() { + this._sourceEditor.undo(); + }.bind(this) + }); + + bindings.push({ + action: "redo", + code: _("redo.commandkey"), + accel: true, + shift: true, + callback: function redo() { + this._sourceEditor.redo(); + }.bind(this) + }); + return bindings; } }; diff --git a/browser/devtools/styleeditor/StyleEditorChrome.jsm b/browser/devtools/styleeditor/StyleEditorChrome.jsm index 700964678e4..f6d10f70e26 100644 --- a/browser/devtools/styleeditor/StyleEditorChrome.jsm +++ b/browser/devtools/styleeditor/StyleEditorChrome.jsm @@ -452,13 +452,16 @@ StyleEditorChrome.prototype = { this._triggerChromeListeners("EditorAdded", [editor]); }.bind(this), + onHide: function ASV_onItemShow(aSummary, aDetails, aData) { + aData.editor.onHide(); + }, onShow: function ASV_onItemShow(aSummary, aDetails, aData) { let editor = aData.editor; if (!editor.inputElement) { // attach editor to input element the first time it is shown editor.inputElement = aDetails.querySelector(".stylesheet-editor-input"); } - editor.inputElement.focus(); + editor.onShow(); } }); }, @@ -476,7 +479,7 @@ StyleEditorChrome.prototype = { }, /** - * Called when when changes have been committed/applied to the live DOM + * Called when when changes have been committed/applied to the live DOM * stylesheet. * * @param StyleEditor aEditor diff --git a/browser/devtools/styleeditor/styleeditor.xul b/browser/devtools/styleeditor/styleeditor.xul index 9c0d01b5574..82618ee8312 100644 --- a/browser/devtools/styleeditor/styleeditor.xul +++ b/browser/devtools/styleeditor/styleeditor.xul @@ -114,7 +114,7 @@ -
diff --git a/browser/locales/en-US/chrome/browser/devtools/styleeditor.properties b/browser/locales/en-US/chrome/browser/devtools/styleeditor.properties index e2599780736..a9357f24ab4 100644 --- a/browser/locales/en-US/chrome/browser/devtools/styleeditor.properties +++ b/browser/locales/en-US/chrome/browser/devtools/styleeditor.properties @@ -51,3 +51,14 @@ saveStyleSheet.filter=CSS files # LOCALIZATION NOTE (saveStyleSheet.commandkey): This the key to use in # conjunction with accel (Command on Mac or Ctrl on other platforms) to Save saveStyleSheet.commandkey=S + +# LOCALIZATION NOTE (undo.commandkey): This the key to use in +# conjunction with accel (Command on Mac or Ctrl on other platforms) to Undo a +# change in the editor. +undo.commandkey=Z + +# LOCALIZATION NOTE (redo.commandkey): This the key to use in +# conjunction with accel+shift (accel is Command on Mac or Ctrl on other +# platforms) to Redo a change in the editor. +redo.commandkey=Z +