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)
|
||||
* Kenny Heaton <kennyheaton@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
|
||||
* 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,
|
||||
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"];
|
||||
@ -367,6 +380,7 @@ SourceEditor.prototype = {
|
||||
"Find Next Occurrence": [this.ui.findNext, this.ui],
|
||||
"Find Previous Occurrence": [this.ui.findPrevious, this.ui],
|
||||
"Goto Line...": [this.ui.gotoLine, this.ui],
|
||||
"Move Lines Down": [this._moveLines, this],
|
||||
};
|
||||
|
||||
for (let name in actions) {
|
||||
@ -374,9 +388,17 @@ SourceEditor.prototype = {
|
||||
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);
|
||||
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);
|
||||
|
||||
if (aKey.callback) {
|
||||
@ -578,6 +600,78 @@ SourceEditor.prototype = {
|
||||
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
|
||||
* 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.
|
||||
* - code - keyCode for the shortcut.
|
||||
* - 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.
|
||||
* - alt - boolean for the Alt key.
|
||||
* - callback - optional function to invoke, if the action is not predefined
|
||||
|
@ -58,6 +58,7 @@ _BROWSER_TEST_FILES = \
|
||||
browser_bug725388_mouse_events.js \
|
||||
browser_bug707987_debugger_breakpoints.js \
|
||||
browser_bug712982_line_ruler_click.js \
|
||||
browser_bug725618_moveLines_shortcut.js \
|
||||
browser_bug700893_dirty_state.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