--- a/devtools/client/framework/test/shared-head.js
+++ b/devtools/client/framework/test/shared-head.js
@@ -196,25 +196,28 @@ function synthesizeKeyFromKeyTag(key) {
* @param {String} key
* @param {DOMWindow} target
* Optional window where to fire the key event
*/
function synthesizeKeyShortcut(key, target) {
// parseElectronKey requires any window, just to access `KeyboardEvent`
let window = Services.appShell.hiddenDOMWindow;
let shortcut = KeyShortcuts.parseElectronKey(window, key);
-
- info("Synthesizing key shortcut: " + key);
- EventUtils.synthesizeKey(shortcut.key || "", {
- keyCode: shortcut.keyCode,
+ let keyEvent = {
altKey: shortcut.alt,
ctrlKey: shortcut.ctrl,
metaKey: shortcut.meta,
shiftKey: shortcut.shift
- }, target);
+ };
+ if (shortcut.keyCode) {
+ keyEvent.keyCode = shortcut.keyCode;
+ }
+
+ info("Synthesizing key shortcut: " + key);
+ EventUtils.synthesizeKey(shortcut.key || "", keyEvent, target);
}
/**
* Wait for eventName on target to be delivered a number of times.
*
* @param {Object} target
* An observable object that either supports on/off or
* addEventListener/removeEventListener
--- a/devtools/client/locales/en-US/sourceeditor.properties
+++ b/devtools/client/locales/en-US/sourceeditor.properties
@@ -103,17 +103,37 @@ moveLineDown.commandkey=Alt-Down
autocompletion.commandkey=Space
# LOCALIZATION NOTE (showInformation2.commandkey): This is the combination of
# keys used to display more information, like type inference.
# Do not localize "Shift", "Ctrl", "Space", or change the format of the string.
# These are key identifiers, not messages displayed to the user.
showInformation2.commandkey=Shift-Ctrl-Space
-# LOCALIZATION NOTE (find.commandkey): This is the key to use in
-# conjunction with accel (Command on Mac or Ctrl on other platforms) to find
-# the typed search
-find.commandkey=F
+# LOCALIZATION NOTE (find.key):
+# Key shortcut used to find the typed search
+# Do not localize "CmdOrCtrl", "F", or change the format of the string. These are
+# key identifiers, not messages displayed to the user.
+find.key=CmdOrCtrl+F
+
+# LOCALIZATION NOTE (replaceAll.key):
+# Key shortcut used to replace the content of the editor
+# Do not localize "Shift", "CmdOrCtrl", "F", or change the format of the string. These are
+# key identifiers, not messages displayed to the user.
+replaceAll.key=Shift+CmdOrCtrl+F
-# LOCALIZATION NOTE (findAgain.commandkey): This is the key to use in
-# conjunction with accel (Command on Mac or Ctrl on other platforms) to find
-# again the typed search
-findAgain.commandkey=G
+# LOCALIZATION NOTE (replaceAllMac.key):
+# Key shortcut used to replace the content of the editor on Mac
+# Do not localize "Alt", "CmdOrCtrl", "F", or change the format of the string. These are
+# key identifiers, not messages displayed to the user.
+replaceAllMac.key=Alt+CmdOrCtrl+F
+
+# LOCALIZATION NOTE (findNext.key):
+# Key shortcut used to find again the typed search
+# Do not localize "CmdOrCtrl", "G", or change the format of the string. These are
+# key identifiers, not messages displayed to the user.
+findNext.key=CmdOrCtrl+G
+
+# LOCALIZATION NOTE (findPrev.key):
+# Key shortcut used to find the previous typed search
+# Do not localize "Shift", "CmdOrCtrl", "G", or change the format of the string. These are
+# key identifiers, not messages displayed to the user.
+findPrev.key=Shift+CmdOrCtrl+G
--- a/devtools/client/scratchpad/test/browser_scratchpad_goto_line_ui.js
+++ b/devtools/client/scratchpad/test/browser_scratchpad_goto_line_ui.js
@@ -30,14 +30,14 @@ function runTests(aWindow, aScratchpad)
cb(desiredValue);
};
desiredValue = 3;
EventUtils.synthesizeKey("J", {accelKey: true}, aWindow);
is(editor.getCursor().line, 2, "line is correct");
desiredValue = 2;
- aWindow.goDoCommand("cmd_gotoLine");
+ EventUtils.synthesizeKey("J", {accelKey: true}, aWindow);
is(editor.getCursor().line, 1, "line is correct (again)");
editor.openDialog = oldPrompt;
finish();
}
--- a/devtools/client/sourceeditor/editor.js
+++ b/devtools/client/sourceeditor/editor.js
@@ -29,16 +29,17 @@ const MAX_VERTICAL_OFFSET = 3;
const RE_SCRATCHPAD_ERROR = /(?:@Scratchpad\/\d+:|\()(\d+):?(\d+)?(?:\)|\n)/;
const RE_JUMP_TO_LINE = /^(\d+):?(\d+)?/;
const Services = require("Services");
const promise = require("promise");
const events = require("devtools/shared/event-emitter");
const { PrefObserver } = require("devtools/client/styleeditor/utils");
const { getClientCssProperties } = require("devtools/shared/fronts/css-properties");
+const {KeyShortcuts} = require("devtools/client/shared/key-shortcuts");
const {LocalizationHelper} = require("devtools/shared/l10n");
const L10N = new LocalizationHelper("devtools/locale/sourceeditor.properties");
const { OS } = Services.appinfo;
// CM_STYLES, CM_SCRIPTS and CM_IFRAME represent the HTML,
// JavaScript and CSS that is injected into an iframe in
@@ -376,75 +377,16 @@ Editor.prototype = {
if (typeof popup == "string") {
popup = doc.getElementById(this.config.contextMenu);
}
this.emit("popupOpen", ev, popup);
popup.openPopupAtScreen(ev.screenX, ev.screenY, true);
}, false);
- // Intercept the find and find again keystroke on CodeMirror, to avoid
- // the browser's search
-
- let findKey = L10N.getStr("find.commandkey");
- let findAgainKey = L10N.getStr("findAgain.commandkey");
- let [accel, modifier] = OS === "Darwin"
- ? ["metaKey", "altKey"]
- : ["ctrlKey", "shiftKey"];
-
- cm.getWrapperElement().addEventListener("keydown", ev => {
- let key = ev.key.toUpperCase();
- let node = ev.originalTarget;
- let isInput = node.tagName === "INPUT";
- let isSearchInput = isInput && node.type === "search";
-
- // replace box is a different input instance than search, and it is
- // located in a code mirror dialog
- let isDialogInput = isInput &&
- node.parentNode &&
- node.parentNode.classList.contains("CodeMirror-dialog");
-
- if (!ev[accel] || !(isSearchInput || isDialogInput)) {
- return;
- }
-
- if (key === findKey) {
- ev.preventDefault();
-
- if (isSearchInput || ev[modifier]) {
- node.select();
- }
- } else if (key === findAgainKey) {
- ev.preventDefault();
-
- if (!isSearchInput) {
- return;
- }
-
- let query = node.value;
-
- // If there isn't a search state, or the text in the input does not
- // match with the current search state, we need to create a new one
- if (!cm.state.search || cm.state.search.query !== query) {
- cm.state.search = {
- posFrom: null,
- posTo: null,
- overlay: null,
- query
- };
- }
-
- if (ev.shiftKey) {
- cm.execCommand("findPrev");
- } else {
- cm.execCommand("findNext");
- }
- }
- });
-
cm.on("focus", () => this.emit("focus"));
cm.on("scroll", () => this.emit("scroll"));
cm.on("change", () => {
this.emit("change");
if (!this._lastDirty) {
this._lastDirty = true;
this.emit("dirty-change");
}
@@ -463,21 +405,17 @@ Editor.prototype = {
this.emit("gutterClick", line, ev.button);
});
win.CodeMirror.defineExtension("l10n", (name) => {
return L10N.getStr(name);
});
- try {
- cm.getInputField().controllers.insertControllerAt(0, controller(this));
- } catch (e) {
- console.warn("controller command is only supported in XUL");
- }
+ this._initShortcuts(win);
editors.set(this, cm);
this.reloadPreferences = this.reloadPreferences.bind(this);
this._prefObserver = new PrefObserver("devtools.editor.");
this._prefObserver.on(TAB_SIZE, this.reloadPreferences);
this._prefObserver.on(EXPAND_TAB, this.reloadPreferences);
this._prefObserver.on(KEYMAP, this.reloadPreferences);
@@ -995,18 +933,17 @@ Editor.prototype = {
/**
* This method opens an in-editor dialog asking for a line to
* jump to. Once given, it changes cursor to that line.
*/
jumpToLine: function () {
let doc = editors.get(this).getWrapperElement().ownerDocument;
let div = doc.createElement("div");
let inp = doc.createElement("input");
- let txt =
- doc.createTextNode(L10N.getStr("gotoLineCmd.promptTitle"));
+ let txt = doc.createTextNode(L10N.getStr("gotoLineCmd.promptTitle"));
inp.type = "text";
inp.style.width = "10em";
inp.style.marginInlineStart = "1em";
div.appendChild(txt);
div.appendChild(inp);
@@ -1091,16 +1028,75 @@ Editor.prototype = {
// value and maintain the selection of the text.
cm.replaceRange(value, { line: start.line, ch: 0 },
{ line: end.line + 1, ch: cm.getLine(end.line + 1).length});
cm.setSelection({ line: start.line + 1, ch: start.ch },
{ line: end.line + 1, ch: end.ch });
},
/**
+ * Intercept CodeMirror's Find and replace key shortcut to select the search input
+ */
+ findOrReplace: function (node, isReplaceAll) {
+ let cm = editors.get(this);
+ let isInput = node.tagName === "INPUT";
+ let isSearchInput = isInput && node.type === "search";
+ // replace box is a different input instance than search, and it is
+ // located in a code mirror dialog
+ let isDialogInput = isInput &&
+ node.parentNode &&
+ node.parentNode.classList.contains("CodeMirror-dialog");
+ if (!(isSearchInput || isDialogInput)) {
+ return;
+ }
+
+ if (isSearchInput || isReplaceAll) {
+ // select the search input
+ // it's the precise reason why we reimplement these key shortcuts
+ node.select();
+ }
+
+ // need to call it since we prevent the propagation of the event and
+ // cancel codemirror's key handling
+ cm.execCommand("find");
+ },
+
+ /**
+ * Intercept CodeMirror's findNext and findPrev key shortcut to allow
+ * immediately search for next occurance after typing a word to search.
+ */
+ findNextOrPrev: function (node, isFindPrev) {
+ let cm = editors.get(this);
+ let isInput = node.tagName === "INPUT";
+ let isSearchInput = isInput && node.type === "search";
+ if (!isSearchInput) {
+ return;
+ }
+ let query = node.value;
+ // cm.state.search allows to automatically start searching for the next occurance
+ // it's the precise reason why we reimplement these key shortcuts
+ if (!cm.state.search || cm.state.search.query !== query) {
+ cm.state.search = {
+ posFrom: null,
+ posTo: null,
+ overlay: null,
+ query
+ };
+ }
+
+ // need to call it since we prevent the propagation of the event and
+ // cancel codemirror's key handling
+ if (isFindPrev) {
+ cm.execCommand("findPrev");
+ } else {
+ cm.execCommand("findNext");
+ }
+ },
+
+ /**
* Returns current font size for the editor area, in pixels.
*/
getFontSize: function () {
let cm = editors.get(this);
let el = cm.getWrapperElement();
let win = el.ownerDocument.defaultView;
return parseInt(win.getComputedStyle(el).getPropertyValue("font-size"), 10);
@@ -1258,16 +1254,87 @@ Editor.prototype = {
if (foldGutterIndex !== -1) {
let gutters = this.config.gutters.slice();
gutters.splice(foldGutterIndex, 1);
this.setOption("gutters", gutters);
}
this.setOption("foldGutter", false);
}
+ },
+
+ /**
+ * Register all key shortcuts.
+ */
+ _initShortcuts: function (win) {
+ let shortcuts = new KeyShortcuts({
+ window: win
+ });
+ this._onShortcut = this._onShortcut.bind(this);
+ let keys = [
+ "find.key",
+ "findNext.key",
+ "findPrev.key"
+ ];
+
+ if (OS === "Darwin") {
+ keys.push("replaceAllMac.key");
+ } else {
+ keys.push("replaceAll.key");
+ }
+ // Process generic keys:
+ keys.forEach(name => {
+ let key = L10N.getStr(name);
+ shortcuts.on(key, (_, event) => this._onShortcut(name, event));
+ });
+ },
+ /**
+ * Key shortcut listener.
+ */
+ _onShortcut: function (name, event) {
+ if (!this._isInputOrTextarea(event.target)) {
+ return;
+ }
+ let cm = editors.get(this);
+ let node = event.originalTarget;
+
+ switch (name) {
+ // replaceAll.key is Alt + find.key
+ case "replaceAllMac.key":
+ this.findOrReplace(node, true);
+ break;
+ // replaceAll.key is Shift + find.key
+ case "replaceAll.key":
+ this.findOrReplace(node, true);
+ break;
+ case "find.key":
+ this.findOrReplace(node, false);
+ break;
+ // findPrev.key is Shift + findNext.key
+ case "findPrev.key":
+ this.findNextOrPrev(node, true);
+ break;
+ case "findNext.key":
+ this.findNextOrPrev(node, false);
+ break;
+ default:
+ console.error("Unexpected editor key shortcut", name);
+ return;
+ }
+ // Prevent default for this action
+ event.stopPropagation();
+ event.preventDefault();
+ },
+
+ /**
+ * Check if a node is an input or textarea
+ */
+ _isInputOrTextarea: function (element) {
+ let name = element.tagName.toLowerCase();
+ return name === "input" || name === "textarea";
}
};
// Since Editor is a thin layer over CodeMirror some methods
// are mapped directly—without any changes.
CM_MAPPING.forEach(name => {
Editor.prototype[name] = function (...args) {
@@ -1337,78 +1404,9 @@ function getCSSKeywords(cssProperties) {
return {
propertyKeywords: keySet(propertyKeywords),
colorKeywords: colorKeywords,
valueKeywords: valueKeywords
};
}
-/**
- * Returns a controller object that can be used for
- * editor-specific commands such as find, jump to line,
- * copy/paste, etc.
- */
-function controller(ed) {
- return {
- supportsCommand: function (cmd) {
- switch (cmd) {
- case "cmd_find":
- case "cmd_findAgain":
- case "cmd_findPrevious":
- case "cmd_gotoLine":
- case "cmd_undo":
- case "cmd_redo":
- case "cmd_delete":
- case "cmd_selectAll":
- return true;
- }
-
- return false;
- },
-
- isCommandEnabled: function (cmd) {
- let cm = editors.get(ed);
-
- switch (cmd) {
- case "cmd_find":
- case "cmd_gotoLine":
- case "cmd_selectAll":
- return true;
- case "cmd_findAgain":
- return cm.state.search != null && cm.state.search.query != null;
- case "cmd_undo":
- return ed.canUndo();
- case "cmd_redo":
- return ed.canRedo();
- case "cmd_delete":
- return ed.somethingSelected();
- }
-
- return false;
- },
-
- doCommand: function (cmd) {
- let cm = editors.get(ed);
- let map = {
- "cmd_selectAll": "selectAll",
- "cmd_find": "find",
- "cmd_undo": "undo",
- "cmd_redo": "redo",
- "cmd_delete": "delCharAfter",
- "cmd_findAgain": "findNext"
- };
-
- if (map[cmd]) {
- cm.execCommand(map[cmd]);
- return;
- }
-
- if (cmd == "cmd_gotoLine") {
- ed.jumpToLine();
- }
- },
-
- onEvent: function () {}
- };
-}
-
module.exports = Editor;
--- a/devtools/client/sourceeditor/test/browser.ini
+++ b/devtools/client/sourceeditor/test/browser.ini
@@ -18,16 +18,17 @@ support-files =
codemirror/mode/javascript/test.js
css_statemachine_testcases.css
css_statemachine_tests.json
css_autocompletion_tests.json
head.js
helper_codemirror_runner.js
cm_mode_ruby.js
cm_script_injection_test.js
+ !/devtools/client/framework/test/shared-head.js
[browser_editor_autocomplete_basic.js]
[browser_editor_autocomplete_events.js]
[browser_editor_autocomplete_js.js]
[browser_editor_basic.js]
[browser_editor_cursor.js]
[browser_editor_find_again.js]
[browser_editor_goto_line.js]
--- a/devtools/client/sourceeditor/test/browser_css_autocompletion.js
+++ b/devtools/client/sourceeditor/test/browser_css_autocompletion.js
@@ -1,18 +1,16 @@
/* 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";
const CSSCompleter = require("devtools/client/sourceeditor/css-autocompleter");
const {InspectorFront} = require("devtools/shared/fronts/inspector");
-const {TargetFactory} = require("devtools/client/framework/target");
-const { Cc, Ci } = require("chrome");
const CSS_URI = "http://mochi.test:8888/browser/devtools/client/sourceeditor" +
"/test/css_statemachine_testcases.css";
const TESTS_URI = "http://mochi.test:8888/browser/devtools/client" +
"/sourceeditor/test/css_autocompletion_tests.json";
const source = read(CSS_URI);
const tests = eval(read(TESTS_URI));
--- a/devtools/client/sourceeditor/test/browser_editor_autocomplete_events.js
+++ b/devtools/client/sourceeditor/test/browser_editor_autocomplete_events.js
@@ -1,24 +1,21 @@
/* 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";
const {InspectorFront} = require("devtools/shared/fronts/inspector");
-const {TargetFactory} = require("devtools/client/framework/target");
const AUTOCOMPLETION_PREF = "devtools.editor.autocomplete";
const TEST_URI = "data:text/html;charset=UTF-8,<html><body><bar></bar>" +
"<div id='baz'></div><body></html>";
-const wait = (delay) => new Promise(resolve => setTimeout(resolve, delay));
-
add_task(function* () {
- yield promiseTab(TEST_URI);
+ yield addTab(TEST_URI);
yield runTests();
});
function* runTests() {
let target = TargetFactory.forTab(gBrowser.selectedTab);
yield target.makeRemote();
let inspector = InspectorFront(target.client, target.form);
let walker = yield inspector.getWalker();
--- a/devtools/client/sourceeditor/test/browser_editor_find_again.js
+++ b/devtools/client/sourceeditor/test/browser_editor_find_again.js
@@ -3,22 +3,25 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
const {LocalizationHelper} = require("devtools/shared/l10n");
const L10N = new LocalizationHelper("devtools/locale/sourceeditor.properties");
-const FIND_KEY = L10N.getStr("find.commandkey");
-const FINDAGAIN_KEY = L10N.getStr("findAgain.commandkey");
-
const { OS } = Services.appinfo;
// On linux, getting immediately the selection's range here fails, returning
+const FIND_KEY = L10N.getStr("find.key");
+const FINDNEXT_KEY = L10N.getStr("findNext.key");
+const FINDPREV_KEY = L10N.getStr("findPrev.key");
+// the replace's key with the appropriate modifiers based on OS
+const REPLACE_KEY = OS == "Darwin" ? L10N.getStr("replaceAllMac.key") : L10N.getStr("replaceAll.key");
+
// values like it's not selected – even if the selection is visible.
// For the record, setting the selection's range immediately doesn't have
// any effect.
// It's like the <input> is not ready yet.
// Therefore, we trigger the UI focus event to the <input>, waiting for the
// response.
// Using a timeout could also work, but that is more precise, ensuring also
// the execution of the listeners added to the <input>'s focus.
@@ -36,34 +39,37 @@ function openSearchBox(ed) {
let edWin = edDoc.defaultView;
let input = edDoc.querySelector("input[type=search]");
ok(!input, "search box closed");
// The editor needs the focus to properly receive the `synthesizeKey`
ed.focus();
- EventUtils.synthesizeKey(FINDAGAIN_KEY, { accelKey: true }, edWin);
-
+ synthesizeKeyShortcut(FINDNEXT_KEY, edWin);
input = edDoc.querySelector("input[type=search]");
ok(input, "find again command key opens the search box");
}
-function testFindAgain(ed, inputLine, expectCursor, shiftKey = false) {
+function testFindAgain(ed, inputLine, expectCursor, isFindPrev = false) {
let edDoc = ed.container.contentDocument;
let edWin = edDoc.defaultView;
let input = edDoc.querySelector("input[type=search]");
input.value = inputLine;
// Ensure the input has the focus before send the key – necessary on Linux,
// it seems that during the tests can be lost
input.focus();
- EventUtils.synthesizeKey(FINDAGAIN_KEY, { accelKey: true, shiftKey }, edWin);
+ if (isFindPrev) {
+ synthesizeKeyShortcut(FINDPREV_KEY, edWin);
+ } else {
+ synthesizeKeyShortcut(FINDNEXT_KEY, edWin);
+ }
ch(ed.getCursor(), expectCursor,
"find: " + inputLine + " expects cursor: " + expectCursor.toSource());
}
const testSearchBoxTextIsSelected = Task.async(function* (ed) {
let edDoc = ed.container.contentDocument;
let edWin = edDoc.defaultView;
@@ -77,32 +83,32 @@ const testSearchBoxTextIsSelected = Task
// Close search box
EventUtils.synthesizeKey("VK_ESCAPE", {}, edWin);
input = edDoc.querySelector("input[type=search]");
ok(!input, "search box is closed");
// Re-open the search box
- EventUtils.synthesizeKey(FIND_KEY, { accelKey: true }, edWin);
+ synthesizeKeyShortcut(FIND_KEY, edWin);
input = edDoc.querySelector("input[type=search]");
ok(input, "find command key opens the search box");
yield dispatchAndWaitForFocus(input);
let { selectionStart, selectionEnd, value } = input;
ok(selectionStart === 0 && selectionEnd === value.length,
"search box's text is selected when re-opened");
// Removing selection
input.setSelectionRange(0, 0);
- EventUtils.synthesizeKey(FIND_KEY, { accelKey: true }, edWin);
+ synthesizeKeyShortcut(FIND_KEY, edWin);
({ selectionStart, selectionEnd } = input);
ok(selectionStart === 0 && selectionEnd === value.length,
"search box's text is selected when find key is pressed");
// Close search box
EventUtils.synthesizeKey("VK_ESCAPE", {}, edWin);
@@ -113,21 +119,17 @@ const testReplaceBoxTextIsSelected = Tas
let edWin = edDoc.defaultView;
let input = edDoc.querySelector(".CodeMirror-dialog > input");
ok(!input, "dialog box with replace is closed");
// The editor needs the focus to properly receive the `synthesizeKey`
ed.focus();
- // Send the replace's key with the appropriate modifiers based on OS
- let [altKey, shiftKey] = OS === "Darwin" ? [true, false] : [false, true];
-
- EventUtils.synthesizeKey(FIND_KEY,
- { accelKey: true, altKey, shiftKey }, edWin);
+ synthesizeKeyShortcut(REPLACE_KEY, edWin);
input = edDoc.querySelector(".CodeMirror-dialog > input");
ok(input, "dialog box with replace is opened");
input.value = "line 5";
// Ensure the input has the focus before send the key – necessary on Linux,
// it seems that during the tests can be lost
@@ -135,18 +137,17 @@ const testReplaceBoxTextIsSelected = Tas
yield dispatchAndWaitForFocus(input);
let { selectionStart, selectionEnd, value } = input;
ok(!(selectionStart === 0 && selectionEnd === value.length),
"Text in dialog box is not selected");
- EventUtils.synthesizeKey(FIND_KEY,
- { accelKey: true, altKey, shiftKey }, edWin);
+ synthesizeKeyShortcut(REPLACE_KEY, edWin);
({ selectionStart, selectionEnd } = input);
ok(selectionStart === 0 && selectionEnd === value.length,
"dialog box's text is selected when replace key is pressed");
// Close dialog box
EventUtils.synthesizeKey("VK_ESCAPE", {}, edWin);
--- a/devtools/client/sourceeditor/test/head.js
+++ b/devtools/client/sourceeditor/test/head.js
@@ -1,49 +1,28 @@
/* vim: set ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
-
+/* import-globals-from ../../framework/test/shared-head.js */
"use strict";
-const { require } = Cu.import("resource://devtools/shared/Loader.jsm", {});
+// shared-head.js handles imports, constants, and utility functions
+Services.scriptloader.loadSubScript(
+ "chrome://mochitests/content/browser/devtools/client/framework/test/shared-head.js",
+ this);
+
const { NetUtil } = require("resource://gre/modules/NetUtil.jsm");
const Editor = require("devtools/client/sourceeditor/editor");
-const promise = require("promise");
-const flags = require("devtools/shared/flags");
const {getClientCssProperties} = require("devtools/shared/fronts/css-properties");
flags.testing = true;
SimpleTest.registerCleanupFunction(() => {
flags.testing = false;
});
-/**
- * Open a new tab at a URL and call a callback on load
- */
-function addTab(url, callback) {
- waitForExplicitFinish();
-
- gBrowser.selectedTab = gBrowser.addTab(url);
- let tab = gBrowser.selectedTab;
- let browser = gBrowser.getBrowserForTab(tab);
-
- return BrowserTestUtils.browserLoaded(browser).then(function () {
- if (typeof(callback) == "function") {
- callback(browser, tab, browser.contentDocument);
- }
- return tab;
- });
-}
-
-function promiseTab(url) {
- return new Promise(resolve =>
- addTab(url, resolve));
-}
-
function promiseWaitForFocus() {
return new Promise(resolve =>
waitForFocus(resolve));
}
function setup(cb, additionalOpts = {}) {
cb = cb || function () {};
let def = promise.defer();