mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 725618 - Source Editor: keyboard shortcut for moving lines up/down; r=msucan
This commit is contained in:
parent
6bbad53cec
commit
a8eb63c0a8
@ -23,6 +23,7 @@
|
|||||||
* Mihai Sucan <mihai.sucan@gmail.com> (original author)
|
* Mihai Sucan <mihai.sucan@gmail.com> (original author)
|
||||||
* Kenny Heaton <kennyheaton@gmail.com>
|
* Kenny Heaton <kennyheaton@gmail.com>
|
||||||
* Spyros Livathinos <livathinos.spyros@gmail.com>
|
* Spyros Livathinos <livathinos.spyros@gmail.com>
|
||||||
|
* Allen Eubank <adeubank@gmail.com>
|
||||||
*
|
*
|
||||||
* Alternatively, the contents of this file may be used under the terms of
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||||
@ -124,6 +125,18 @@ const DEFAULT_KEYBINDINGS = [
|
|||||||
code: Ci.nsIDOMKeyEvent.DOM_VK_TAB,
|
code: Ci.nsIDOMKeyEvent.DOM_VK_TAB,
|
||||||
shift: true,
|
shift: true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
action: "Move Lines Up",
|
||||||
|
code: Ci.nsIDOMKeyEvent.DOM_VK_UP,
|
||||||
|
ctrl: Services.appinfo.OS == "Darwin",
|
||||||
|
alt: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
action: "Move Lines Down",
|
||||||
|
code: Ci.nsIDOMKeyEvent.DOM_VK_DOWN,
|
||||||
|
ctrl: Services.appinfo.OS == "Darwin",
|
||||||
|
alt: true,
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
var EXPORTED_SYMBOLS = ["SourceEditor"];
|
var EXPORTED_SYMBOLS = ["SourceEditor"];
|
||||||
@ -367,6 +380,7 @@ SourceEditor.prototype = {
|
|||||||
"Find Next Occurrence": [this.ui.findNext, this.ui],
|
"Find Next Occurrence": [this.ui.findNext, this.ui],
|
||||||
"Find Previous Occurrence": [this.ui.findPrevious, this.ui],
|
"Find Previous Occurrence": [this.ui.findPrevious, this.ui],
|
||||||
"Goto Line...": [this.ui.gotoLine, this.ui],
|
"Goto Line...": [this.ui.gotoLine, this.ui],
|
||||||
|
"Move Lines Down": [this._moveLines, this],
|
||||||
};
|
};
|
||||||
|
|
||||||
for (let name in actions) {
|
for (let name in actions) {
|
||||||
@ -374,9 +388,17 @@ SourceEditor.prototype = {
|
|||||||
this._view.setAction(name, action[0].bind(action[1]));
|
this._view.setAction(name, action[0].bind(action[1]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this._view.setAction("Move Lines Up", this._moveLines.bind(this, true));
|
||||||
|
|
||||||
let keys = (config.keys || []).concat(DEFAULT_KEYBINDINGS);
|
let keys = (config.keys || []).concat(DEFAULT_KEYBINDINGS);
|
||||||
keys.forEach(function(aKey) {
|
keys.forEach(function(aKey) {
|
||||||
let binding = new KeyBinding(aKey.code, aKey.accel, aKey.shift, aKey.alt);
|
// In Orion mod1 refers to Cmd on Macs and Ctrl on Windows and Linux.
|
||||||
|
// So, if ctrl is in aKey we use it on Windows and Linux, otherwise
|
||||||
|
// we use aKey.accel for mod1.
|
||||||
|
let mod1 = Services.appinfo.OS != "Darwin" &&
|
||||||
|
"ctrl" in aKey ? aKey.ctrl : aKey.accel;
|
||||||
|
let binding = new KeyBinding(aKey.code, mod1, aKey.shift, aKey.alt,
|
||||||
|
aKey.ctrl);
|
||||||
this._view.setKeyBinding(binding, aKey.action);
|
this._view.setKeyBinding(binding, aKey.action);
|
||||||
|
|
||||||
if (aKey.callback) {
|
if (aKey.callback) {
|
||||||
@ -578,6 +600,78 @@ SourceEditor.prototype = {
|
|||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Move lines upwards or downwards, relative to the current caret location.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param boolean aLineAbove
|
||||||
|
* True if moving lines up, false to move lines down.
|
||||||
|
*/
|
||||||
|
_moveLines: function SE__moveLines(aLineAbove)
|
||||||
|
{
|
||||||
|
if (this.readOnly) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
let model = this._model;
|
||||||
|
let selection = this.getSelection();
|
||||||
|
let firstLine = model.getLineAtOffset(selection.start);
|
||||||
|
if (firstLine == 0 && aLineAbove) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
let lastLine = model.getLineAtOffset(selection.end);
|
||||||
|
let firstLineStart = model.getLineStart(firstLine);
|
||||||
|
let lastLineStart = model.getLineStart(lastLine);
|
||||||
|
if (selection.start != selection.end && lastLineStart == selection.end) {
|
||||||
|
lastLine--;
|
||||||
|
}
|
||||||
|
if (!aLineAbove && (lastLine + 1) == this.getLineCount()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
let lastLineEnd = model.getLineEnd(lastLine, true);
|
||||||
|
let text = this.getText(firstLineStart, lastLineEnd);
|
||||||
|
|
||||||
|
if (aLineAbove) {
|
||||||
|
let aboveLine = firstLine - 1;
|
||||||
|
let aboveLineStart = model.getLineStart(aboveLine);
|
||||||
|
|
||||||
|
this.startCompoundChange();
|
||||||
|
if (lastLine == (this.getLineCount() - 1)) {
|
||||||
|
let delimiterStart = model.getLineEnd(aboveLine);
|
||||||
|
let delimiterEnd = model.getLineEnd(aboveLine, true);
|
||||||
|
let lineDelimiter = this.getText(delimiterStart, delimiterEnd);
|
||||||
|
text += lineDelimiter;
|
||||||
|
this.setText("", firstLineStart - lineDelimiter.length, lastLineEnd);
|
||||||
|
} else {
|
||||||
|
this.setText("", firstLineStart, lastLineEnd);
|
||||||
|
}
|
||||||
|
this.setText(text, aboveLineStart, aboveLineStart);
|
||||||
|
this.endCompoundChange();
|
||||||
|
this.setSelection(aboveLineStart, aboveLineStart + text.length);
|
||||||
|
} else {
|
||||||
|
let belowLine = lastLine + 1;
|
||||||
|
let belowLineEnd = model.getLineEnd(belowLine, true);
|
||||||
|
|
||||||
|
let insertAt = belowLineEnd - lastLineEnd + firstLineStart;
|
||||||
|
let lineDelimiter = "";
|
||||||
|
if (belowLine == this.getLineCount() - 1) {
|
||||||
|
let delimiterStart = model.getLineEnd(lastLine);
|
||||||
|
lineDelimiter = this.getText(delimiterStart, lastLineEnd);
|
||||||
|
text = lineDelimiter + text.substr(0, text.length -
|
||||||
|
lineDelimiter.length);
|
||||||
|
}
|
||||||
|
this.startCompoundChange();
|
||||||
|
this.setText("", firstLineStart, lastLineEnd);
|
||||||
|
this.setText(text, insertAt, insertAt);
|
||||||
|
this.endCompoundChange();
|
||||||
|
this.setSelection(insertAt + lineDelimiter.length,
|
||||||
|
insertAt + text.length);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Orion Selection event handler. The current caret line is
|
* The Orion Selection event handler. The current caret line is
|
||||||
* highlighted and for Linux users the selected text is copied into the X11
|
* highlighted and for Linux users the selected text is copied into the X11
|
||||||
|
@ -192,6 +192,7 @@ SourceEditor.DEFAULTS = {
|
|||||||
* - action - name of the editor action to invoke.
|
* - action - name of the editor action to invoke.
|
||||||
* - code - keyCode for the shortcut.
|
* - code - keyCode for the shortcut.
|
||||||
* - accel - boolean for the Accel key (Cmd on Macs, Ctrl on Linux/Windows).
|
* - accel - boolean for the Accel key (Cmd on Macs, Ctrl on Linux/Windows).
|
||||||
|
* - ctrl - boolean for the Control key
|
||||||
* - shift - boolean for the Shift key.
|
* - shift - boolean for the Shift key.
|
||||||
* - alt - boolean for the Alt key.
|
* - alt - boolean for the Alt key.
|
||||||
* - callback - optional function to invoke, if the action is not predefined
|
* - callback - optional function to invoke, if the action is not predefined
|
||||||
|
@ -58,6 +58,7 @@ _BROWSER_TEST_FILES = \
|
|||||||
browser_bug725388_mouse_events.js \
|
browser_bug725388_mouse_events.js \
|
||||||
browser_bug707987_debugger_breakpoints.js \
|
browser_bug707987_debugger_breakpoints.js \
|
||||||
browser_bug712982_line_ruler_click.js \
|
browser_bug712982_line_ruler_click.js \
|
||||||
|
browser_bug725618_moveLines_shortcut.js \
|
||||||
browser_bug700893_dirty_state.js \
|
browser_bug700893_dirty_state.js \
|
||||||
head.js \
|
head.js \
|
||||||
|
|
||||||
|
@ -0,0 +1,117 @@
|
|||||||
|
/* vim: set ts=2 et sw=2 tw=80: */
|
||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
let tempScope = {};
|
||||||
|
Cu.import("resource:///modules/source-editor.jsm", tempScope);
|
||||||
|
let SourceEditor = tempScope.SourceEditor;
|
||||||
|
|
||||||
|
let editor;
|
||||||
|
let testWin;
|
||||||
|
|
||||||
|
function test()
|
||||||
|
{
|
||||||
|
waitForExplicitFinish();
|
||||||
|
|
||||||
|
const windowUrl = "data:application/vnd.mozilla.xul+xml,<?xml version='1.0'?>" +
|
||||||
|
"<window xmlns='http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul'" +
|
||||||
|
" title='test for bug 725618 - moveLines shortcut' width='300' height='500'>" +
|
||||||
|
"<box flex='1'/></window>";
|
||||||
|
const windowFeatures = "chrome,titlebar,toolbar,centerscreen,resizable,dialog=no";
|
||||||
|
|
||||||
|
testWin = Services.ww.openWindow(null, windowUrl, "_blank", windowFeatures, null);
|
||||||
|
testWin.addEventListener("load", function onWindowLoad() {
|
||||||
|
testWin.removeEventListener("load", onWindowLoad, false);
|
||||||
|
waitForFocus(initEditor, testWin);
|
||||||
|
}, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
function initEditor()
|
||||||
|
{
|
||||||
|
let box = testWin.document.querySelector("box");
|
||||||
|
|
||||||
|
let text = "target\nfoo\nbar"
|
||||||
|
let config = {
|
||||||
|
initialText: text,
|
||||||
|
};
|
||||||
|
|
||||||
|
editor = new SourceEditor();
|
||||||
|
editor.init(box, config, editorLoaded);
|
||||||
|
}
|
||||||
|
|
||||||
|
function editorLoaded()
|
||||||
|
{
|
||||||
|
editor.focus();
|
||||||
|
|
||||||
|
editor.setCaretOffset(0);
|
||||||
|
|
||||||
|
let modifiers = {altKey: true, ctrlKey: Services.appinfo.OS == "Darwin"};
|
||||||
|
|
||||||
|
EventUtils.synthesizeKey("VK_DOWN", modifiers, testWin);
|
||||||
|
is(editor.getText(), "foo\ntarget\nbar", "Move lines down works");
|
||||||
|
is(editor.getSelectedText(), "target\n", "selection is correct");
|
||||||
|
|
||||||
|
EventUtils.synthesizeKey("VK_DOWN", modifiers, testWin);
|
||||||
|
is(editor.getText(), "foo\nbar\ntarget", "Move lines down works");
|
||||||
|
is(editor.getSelectedText(), "target", "selection is correct");
|
||||||
|
|
||||||
|
EventUtils.synthesizeKey("VK_DOWN", modifiers, testWin);
|
||||||
|
is(editor.getText(), "foo\nbar\ntarget", "Check for bottom of editor works");
|
||||||
|
is(editor.getSelectedText(), "target", "selection is correct");
|
||||||
|
|
||||||
|
EventUtils.synthesizeKey("VK_UP", modifiers, testWin);
|
||||||
|
is(editor.getText(), "foo\ntarget\nbar", "Move lines up works");
|
||||||
|
is(editor.getSelectedText(), "target\n", "selection is correct");
|
||||||
|
|
||||||
|
EventUtils.synthesizeKey("VK_UP", modifiers, testWin);
|
||||||
|
is(editor.getText(), "target\nfoo\nbar", "Move lines up works");
|
||||||
|
is(editor.getSelectedText(), "target\n", "selection is correct");
|
||||||
|
|
||||||
|
EventUtils.synthesizeKey("VK_UP", modifiers, testWin);
|
||||||
|
is(editor.getText(), "target\nfoo\nbar", "Check for top of editor works");
|
||||||
|
is(editor.getSelectedText(), "target\n", "selection is correct");
|
||||||
|
|
||||||
|
editor.setSelection(0, 10);
|
||||||
|
info("text within selection =" + editor.getSelectedText());
|
||||||
|
|
||||||
|
EventUtils.synthesizeKey("VK_DOWN", modifiers, testWin);
|
||||||
|
is(editor.getText(), "bar\ntarget\nfoo", "Multiple line move down works");
|
||||||
|
is(editor.getSelectedText(), "target\nfoo", "selection is correct");
|
||||||
|
|
||||||
|
EventUtils.synthesizeKey("VK_DOWN", modifiers, testWin);
|
||||||
|
is(editor.getText(), "bar\ntarget\nfoo",
|
||||||
|
"Check for bottom of editor works with multiple line selection");
|
||||||
|
is(editor.getSelectedText(), "target\nfoo", "selection is correct");
|
||||||
|
|
||||||
|
EventUtils.synthesizeKey("VK_UP", modifiers, testWin);
|
||||||
|
is(editor.getText(), "target\nfoo\nbar", "Multiple line move up works");
|
||||||
|
is(editor.getSelectedText(), "target\nfoo\n", "selection is correct");
|
||||||
|
|
||||||
|
EventUtils.synthesizeKey("VK_UP", modifiers, testWin);
|
||||||
|
is(editor.getText(), "target\nfoo\nbar",
|
||||||
|
"Check for top of editor works with multiple line selection");
|
||||||
|
is(editor.getSelectedText(), "target\nfoo\n", "selection is correct");
|
||||||
|
|
||||||
|
editor.readOnly = true;
|
||||||
|
|
||||||
|
editor.setCaretOffset(0);
|
||||||
|
|
||||||
|
EventUtils.synthesizeKey("VK_UP", modifiers, testWin);
|
||||||
|
is(editor.getText(), "target\nfoo\nbar",
|
||||||
|
"Check for readOnly mode works with move lines up");
|
||||||
|
|
||||||
|
EventUtils.synthesizeKey("VK_DOWN", modifiers, testWin);
|
||||||
|
is(editor.getText(), "target\nfoo\nbar",
|
||||||
|
"Check for readOnly mode works with move lines down");
|
||||||
|
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
registerCleanupFunction(function()
|
||||||
|
{
|
||||||
|
editor.destroy();
|
||||||
|
testWin.close();
|
||||||
|
testWin = editor = null;
|
||||||
|
});
|
Loading…
Reference in New Issue
Block a user