--- a/devtools/client/inspector/markup/test/helper_style_attr_test_runner.js
+++ b/devtools/client/inspector/markup/test/helper_style_attr_test_runner.js
@@ -115,27 +115,18 @@ function sendKey(key, editor, inspector)
* Verify that the inplace editor is in the expected state for the provided
* test data.
*/
function* checkData(data, editor, inspector) {
let [, completion, selStart, selEnd, popupOpen] = data;
if (selEnd != -1) {
is(editor.input.value, completion, "Completed value is correct");
- is(editor.input.selectionStart, selStart,
- "Selection start position is correct");
+ is(editor.input.selectionStart, selStart, "Selection start position is correct");
is(editor.input.selectionEnd, selEnd, "Selection end position is correct");
- if (popupOpen) {
- ok(editor.popup.isOpen, "Popup is open");
- } else {
- ok(editor.popup._panel.state != "open" &&
- editor.popup._panel.state != "showing",
- "Popup is closed");
- }
+ is(editor.popup.isOpen, popupOpen, "Popup is " + (popupOpen ? "open" : "closed"));
} else {
let nodeFront = yield getNodeFront("#node14", inspector);
let container = getContainerForNodeFront(nodeFront, inspector);
- let attr = container.editor.attrElements.get("style")
- .querySelector(".editable");
- is(attr.textContent, completion,
- "Correct value is persisted after pressing Enter");
+ let attr = container.editor.attrElements.get("style").querySelector(".editable");
+ is(attr.textContent, completion, "Correct value is persisted after pressing Enter");
}
}
--- a/devtools/client/inspector/rules/test/browser_rules_completion-existing-property_01.js
+++ b/devtools/client/inspector/rules/test/browser_rules_completion-existing-property_01.js
@@ -80,31 +80,27 @@ add_task(function* () {
yield runAutocompletionTest(toolbox, inspector, view);
});
function* runAutocompletionTest(toolbox, inspector, view) {
info("Selecting the test node");
yield selectNode("h1", inspector);
info("Focusing the css property editable field");
- let propertyName = view.styleDocument
- .querySelectorAll(".ruleview-propertyname")[0];
+ let propertyName = view.styleDocument.querySelectorAll(".ruleview-propertyname")[0];
let editor = yield focusEditableField(view, propertyName);
info("Starting to test for css property completion");
- let previousPopupSize = 0;
for (let i = 0; i < testData.length; i++) {
- let expectPopupHiddenEvent = previousPopupSize > 0 && testData[3] === 0;
- yield testCompletion(testData[i], expectPopupHiddenEvent, editor, view);
- previousPopupSize = testData[3];
+ yield testCompletion(testData[i], editor, view);
}
}
function* testCompletion([key, completion, open, selected],
- expectPopupHiddenEvent, editor, view) {
+ editor, view) {
info("Pressing key " + key);
info("Expecting " + completion);
info("Is popup opened: " + open);
info("Is item selected: " + selected);
// Listening for the right event that will tell us when the key has been
// entered and processed.
let onSuggest;
@@ -112,31 +108,29 @@ function* testCompletion([key, completio
info("Adding event listener for " +
"left|right|back_space|escape|home|end|page_up|page_down keys");
onSuggest = once(editor.input, "keypress");
} else {
info("Waiting for after-suggest event on the editor");
onSuggest = editor.once("after-suggest");
}
- // Also listening for popup hiding if needed.
- let onMaybePopupHidden = expectPopupHiddenEvent
- ? once(editor.popup._panel, "hidden")
- : null;
+ // Also listening for popup opened/closed events if needed.
+ let popupEvent = open ? "popup-opened" : "popup-closed";
+ let onPopupEvent = editor.popup.isOpen !== open ? once(editor.popup, popupEvent) : null;
info("Synthesizing key " + key);
EventUtils.synthesizeKey(key, {}, view.styleWindow);
yield onSuggest;
- yield onMaybePopupHidden;
+ yield onPopupEvent;
info("Checking the state");
- if (completion != null) {
+ if (completion !== null) {
is(editor.input.value, completion, "Correct value is autocompleted");
}
if (!open) {
ok(!(editor.popup && editor.popup.isOpen), "Popup is closed");
} else {
- ok(editor.popup._panel.state == "open" ||
- editor.popup._panel.state == "showing", "Popup is open");
- is(editor.popup.selectedIndex != -1, selected, "An item is selected");
+ ok(editor.popup.isOpen, "Popup is open");
+ is(editor.popup.selectedIndex !== -1, selected, "An item is selected");
}
}
--- a/devtools/client/inspector/rules/test/browser_rules_completion-existing-property_02.js
+++ b/devtools/client/inspector/rules/test/browser_rules_completion-existing-property_02.js
@@ -87,28 +87,33 @@ function* testCompletion([key, modifiers
// Otherwise, expect an after-suggest event (except if the popup gets
// closed).
onDone = key !== "VK_RIGHT" && key !== "VK_BACK_SPACE"
? editor.once("after-suggest")
: null;
}
info("Synthesizing key " + key + ", modifiers: " + Object.keys(modifiers));
+
+ // Also listening for popup opened/closed events if needed.
+ let popupEvent = open ? "popup-opened" : "popup-closed";
+ let onPopupEvent = editor.popup.isOpen !== open ? once(editor.popup, popupEvent) : null;
+
EventUtils.synthesizeKey(key, modifiers, view.styleWindow);
yield onDone;
+ yield onPopupEvent;
// The key might have been a TAB or shift-TAB, in which case the editor will
// be a new one
editor = inplaceEditor(view.styleDocument.activeElement);
info("Checking the state");
- if (completion != null) {
+ if (completion !== null) {
is(editor.input.value, completion, "Correct value is autocompleted");
}
if (!open) {
ok(!(editor.popup && editor.popup.isOpen), "Popup is closed");
} else {
- ok(editor.popup._panel.state == "open" ||
- editor.popup._panel.state == "showing", "Popup is open");
- is(editor.popup.selectedIndex != -1, selected, "An item is selected");
+ ok(editor.popup.isOpen, "Popup is open");
+ is(editor.popup.selectedIndex !== -1, selected, "An item is selected");
}
}
--- a/devtools/client/inspector/rules/test/browser_rules_completion-new-property_01.js
+++ b/devtools/client/inspector/rules/test/browser_rules_completion-new-property_01.js
@@ -58,42 +58,45 @@ function* runAutocompletionTest(toolbox,
let editor = yield focusNewRuleViewProperty(ruleEditor);
info("Starting to test for css property completion");
for (let i = 0; i < testData.length; i++) {
yield testCompletion(testData[i], editor, view);
}
}
-function* testCompletion([key, completion, isOpen, isSelected], editor, view) {
+function* testCompletion([key, completion, open, isSelected], editor, view) {
info("Pressing key " + key);
info("Expecting " + completion);
- info("Is popup opened: " + isOpen);
+ info("Is popup opened: " + open);
info("Is item selected: " + isSelected);
let onSuggest;
if (/(right|back_space|escape)/ig.test(key)) {
info("Adding event listener for right|back_space|escape keys");
onSuggest = once(editor.input, "keypress");
} else {
info("Waiting for after-suggest event on the editor");
onSuggest = editor.once("after-suggest");
}
+ // Also listening for popup opened/closed events if needed.
+ let popupEvent = open ? "popup-opened" : "popup-closed";
+ let onPopupEvent = editor.popup.isOpen !== open ? once(editor.popup, popupEvent) : null;
+
info("Synthesizing key " + key);
EventUtils.synthesizeKey(key, {}, view.styleWindow);
yield onSuggest;
- yield waitForTick();
+ yield onPopupEvent;
info("Checking the state");
- if (completion != null) {
+ if (completion !== null) {
is(editor.input.value, completion, "Correct value is autocompleted");
}
- if (!isOpen) {
+ if (!open) {
ok(!(editor.popup && editor.popup.isOpen), "Popup is closed");
} else {
- ok(editor.popup._panel.state == "open" ||
- editor.popup._panel.state == "showing", "Popup is open");
- is(editor.popup.selectedIndex != -1, isSelected, "An item is selected");
+ ok(editor.popup.isOpen, "Popup is open");
+ is(editor.popup.selectedIndex !== -1, isSelected, "An item is selected");
}
}
--- a/devtools/client/inspector/rules/test/browser_rules_completion-new-property_02.js
+++ b/devtools/client/inspector/rules/test/browser_rules_completion-new-property_02.js
@@ -95,27 +95,31 @@ function* testCompletion([key, modifiers
} else {
// Otherwise, expect an after-suggest event (except if the popup gets
// closed).
onDone = key !== "VK_RIGHT" && key !== "VK_BACK_SPACE"
? editor.once("after-suggest")
: null;
}
+ // Also listening for popup opened/closed events if needed.
+ let popupEvent = open ? "popup-opened" : "popup-closed";
+ let onPopupEvent = editor.popup.isOpen !== open ? once(editor.popup, popupEvent) : null;
+
info("Synthesizing key " + key + ", modifiers: " + Object.keys(modifiers));
EventUtils.synthesizeKey(key, modifiers, view.styleWindow);
yield onDone;
+ yield onPopupEvent;
info("Checking the state");
- if (completion != null) {
+ if (completion !== null) {
// The key might have been a TAB or shift-TAB, in which case the editor will
// be a new one
editor = inplaceEditor(view.styleDocument.activeElement);
is(editor.input.value, completion, "Correct value is autocompleted");
}
if (!open) {
ok(!(editor.popup && editor.popup.isOpen), "Popup is closed");
} else {
- ok(editor.popup._panel.state == "open" ||
- editor.popup._panel.state == "showing", "Popup is open");
- is(editor.popup.selectedIndex != -1, selected, "An item is selected");
+ ok(editor.popup.isOpen, "Popup is open");
+ is(editor.popup.selectedIndex !== -1, selected, "An item is selected");
}
}
--- a/devtools/client/inspector/rules/test/browser_rules_completion-new-property_03.js
+++ b/devtools/client/inspector/rules/test/browser_rules_completion-new-property_03.js
@@ -36,12 +36,12 @@ function* runAutocompletionTest(toolbox,
let bgcItem = editor.popup.getItemAtIndex(itemIndex);
is(bgcItem.label, "background-color",
"check the expected completion element");
editor.popup.selectedIndex = itemIndex;
let node = editor.popup._list.childNodes[itemIndex];
- EventUtils.synthesizeMouseAtCenter(node, {}, view.styleWindow);
+ EventUtils.synthesizeMouseAtCenter(node, {}, editor.popup._window);
is(editor.input.value, "background-color", "Correct value is autocompleted");
}
--- a/devtools/client/inspector/rules/test/browser_rules_completion-new-property_04.js
+++ b/devtools/client/inspector/rules/test/browser_rules_completion-new-property_04.js
@@ -34,18 +34,18 @@ add_task(function* () {
const itemIndex = 4;
let bgcItem = editor.popup.getItemAtIndex(itemIndex);
is(bgcItem.label, "background-color",
"Check the expected completion element is background-color.");
editor.popup.selectedIndex = itemIndex;
info("Select the background-color suggestion with a mouse click.");
let onSuggest = editor.once("after-suggest");
- let node = editor.popup._list.childNodes[itemIndex];
- EventUtils.synthesizeMouseAtCenter(node, {}, view.styleWindow);
+ let node = editor.popup.elements.get(bgcItem);
+ EventUtils.synthesizeMouseAtCenter(node, {}, editor.popup._window);
yield onSuggest;
is(editor.input.value, "background-color", "Correct value is autocompleted");
info("Press RETURN to move the focus to a property value editor.");
let onModifications = waitForNEvents(view, "ruleview-changed", 2);
EventUtils.synthesizeKey("VK_RETURN", {}, view.styleWindow);
yield onModifications;
--- a/devtools/client/inspector/rules/test/browser_rules_completion-new-property_multiline.js
+++ b/devtools/client/inspector/rules/test/browser_rules_completion-new-property_multiline.js
@@ -55,17 +55,17 @@ add_task(function* () {
info("Moving the caret next to a number");
let pos = editor.input.value.indexOf("0deg") + 1;
editor.input.setSelectionRange(pos, pos);
is(editor.input.value[editor.input.selectionStart - 1], "0",
"Input caret is after a 0");
info("Check that UP/DOWN navigates in the input, even when next to a number");
EventUtils.synthesizeKey("VK_DOWN", {}, view.styleWindow);
- ok(editor.input.selectionStart != pos, "Input caret moved");
+ ok(editor.input.selectionStart !== pos, "Input caret moved");
is(editor.input.value, LONG_CSS_VALUE, "Input value was not decremented.");
info("Move the caret to the end of the gradient definition.");
pos = editor.input.value.indexOf("95%") + 3;
editor.input.setSelectionRange(pos, pos);
info("Sending \", re\" to the editable field.");
for (let key of ", re") {
@@ -90,18 +90,20 @@ add_task(function* () {
yield synthesizeKeyForAutocomplete("VK_UP", editor, view.styleWindow);
is(editor.popup.selectedIndex, 1, "Using UP cycles autocomplete values.");
item = editor.popup.getItemAtIndex(editor.popup.selectedIndex);
is(item.label, "red", "Check autocomplete displays expected value.");
info("Select the background-color suggestion with a mouse click.");
let onRuleviewChanged = view.once("ruleview-changed");
let onSuggest = editor.once("after-suggest");
+
let node = editor.popup._list.childNodes[editor.popup.selectedIndex];
- EventUtils.synthesizeMouseAtCenter(node, {}, view.styleWindow);
+ EventUtils.synthesizeMouseAtCenter(node, {}, editor.popup._window);
+
yield onSuggest;
yield onRuleviewChanged;
is(editor.input.value, EXPECTED_CSS_VALUE,
"Input value correctly autocompleted");
info("Press ESCAPE to leave the input.");
onRuleviewChanged = view.once("ruleview-changed");
--- a/devtools/client/inspector/rules/test/browser_rules_completion-popup-hidden-after-navigation.js
+++ b/devtools/client/inspector/rules/test/browser_rules_completion-popup-hidden-after-navigation.js
@@ -19,21 +19,23 @@ add_task(function* () {
info("Focusing the css property editable field");
let propertyName = view.styleDocument
.querySelectorAll(".ruleview-propertyname")[0];
let editor = yield focusEditableField(view, propertyName);
info("Pressing key VK_DOWN");
let onSuggest = once(editor.input, "keypress");
+ let onPopupOpened = once(editor.popup, "popup-opened");
+
EventUtils.synthesizeKey("VK_DOWN", {}, view.styleWindow);
info("Waiting for autocomplete popup to be displayed");
yield onSuggest;
- yield waitForTick();
+ yield onPopupOpened;
ok(view.popup && view.popup.isOpen, "Popup should be opened");
info("Reloading the page");
yield reloadPage(inspector, testActor);
ok(!(view.popup && view.popup.isOpen), "Popup should be closed");
});
--- a/devtools/client/inspector/test/browser_inspector_search-navigation.js
+++ b/devtools/client/inspector/test/browser_inspector_search-navigation.js
@@ -9,43 +9,43 @@
// Test data as pairs of [key to press, expected content of searchbox].
const KEY_STATES = [
["d", "d"],
["i", "di"],
["v", "div"],
[".", "div."],
["VK_UP", "div.c1"],
["VK_DOWN", "div.l1"],
- ["VK_DOWN", "div.l1"],
["VK_BACK_SPACE", "div.l"],
["VK_TAB", "div.l1"],
[" ", "div.l1 "],
["VK_UP", "div.l1 div"],
+ ["VK_UP", "div.l1 span"],
["VK_UP", "div.l1 div"],
[".", "div.l1 div."],
["VK_TAB", "div.l1 div.c1"],
["VK_BACK_SPACE", "div.l1 div.c"],
["VK_BACK_SPACE", "div.l1 div."],
["VK_BACK_SPACE", "div.l1 div"],
["VK_BACK_SPACE", "div.l1 di"],
["VK_BACK_SPACE", "div.l1 d"],
["VK_BACK_SPACE", "div.l1 "],
["VK_UP", "div.l1 div"],
["VK_BACK_SPACE", "div.l1 di"],
["VK_BACK_SPACE", "div.l1 d"],
["VK_BACK_SPACE", "div.l1 "],
["VK_UP", "div.l1 div"],
+ ["VK_UP", "div.l1 span"],
["VK_UP", "div.l1 div"],
["VK_TAB", "div.l1 div"],
["VK_BACK_SPACE", "div.l1 di"],
["VK_BACK_SPACE", "div.l1 d"],
["VK_BACK_SPACE", "div.l1 "],
["VK_DOWN", "div.l1 div"],
["VK_DOWN", "div.l1 span"],
- ["VK_DOWN", "div.l1 span"],
["VK_BACK_SPACE", "div.l1 spa"],
["VK_BACK_SPACE", "div.l1 sp"],
["VK_BACK_SPACE", "div.l1 s"],
["VK_BACK_SPACE", "div.l1 "],
["VK_BACK_SPACE", "div.l1"],
["VK_BACK_SPACE", "div.l"],
["VK_BACK_SPACE", "div."],
["VK_BACK_SPACE", "div"],
@@ -63,11 +63,14 @@ add_task(function* () {
for (let [key, query] of KEY_STATES) {
info("Pressing key " + key + " to get searchbox value as " + query);
let done = inspector.searchSuggestions.once("processing-done");
EventUtils.synthesizeKey(key, {}, inspector.panelWin);
yield done;
- is(inspector.searchBox.value, query, "The searchbox value is correct.");
+ info("Waiting for search query to complete");
+ yield inspector.searchSuggestions._lastQuery;
+
+ is(inspector.searchBox.value, query, "The searchbox value is correct");
}
});
--- a/devtools/client/shared/test/browser_inplace-editor_autocomplete_01.js
+++ b/devtools/client/shared/test/browser_inplace-editor_autocomplete_01.js
@@ -43,26 +43,27 @@ const mockGetCSSPropertyList = function
};
add_task(function* () {
yield addTab("data:text/html;charset=utf-8," +
"inplace editor CSS property autocomplete");
let [host, win, doc] = yield createHost();
let xulDocument = win.top.document;
- let popup = new AutocompletePopup(xulDocument, { autoSelect: true });
+ let popup = new AutocompletePopup({ doc: xulDocument }, { autoSelect: true });
yield new Promise(resolve => {
createInplaceEditorAndClick({
start: runPropertyAutocompletionTest,
contentType: InplaceEditor.CONTENT_TYPES.CSS_PROPERTY,
done: resolve,
popup: popup
}, doc);
});
+ popup.destroy();
host.destroy();
gBrowser.removeCurrentTab();
});
let runPropertyAutocompletionTest = Task.async(function* (editor) {
info("Starting to test for css property completion");
editor._getCSSPropertyList = mockGetCSSPropertyList;
--- a/devtools/client/shared/test/browser_inplace-editor_autocomplete_02.js
+++ b/devtools/client/shared/test/browser_inplace-editor_autocomplete_02.js
@@ -44,30 +44,31 @@ const mockGetCSSValuesForPropertyName =
};
add_task(function* () {
yield addTab("data:text/html;charset=utf-8," +
"inplace editor CSS value autocomplete");
let [host, win, doc] = yield createHost();
let xulDocument = win.top.document;
- let popup = new AutocompletePopup(xulDocument, { autoSelect: true });
+ let popup = new AutocompletePopup({ doc: xulDocument }, { autoSelect: true });
yield new Promise(resolve => {
createInplaceEditorAndClick({
start: runAutocompletionTest,
contentType: InplaceEditor.CONTENT_TYPES.CSS_VALUE,
property: {
name: "display"
},
done: resolve,
popup: popup
}, doc);
});
+ popup.destroy();
host.destroy();
gBrowser.removeCurrentTab();
});
let runAutocompletionTest = Task.async(function* (editor) {
info("Starting to test for css property completion");
editor._getCSSValuesForPropertyName = mockGetCSSValuesForPropertyName;
--- a/devtools/client/shared/test/browser_inplace-editor_autocomplete_offset.js
+++ b/devtools/client/shared/test/browser_inplace-editor_autocomplete_offset.js
@@ -4,16 +4,24 @@
/* import-globals-from helper_inplace_editor.js */
"use strict";
const { InplaceEditor } = require("devtools/client/shared/inplace-editor");
const { AutocompletePopup } = require("devtools/client/shared/autocomplete-popup");
loadHelperScript("helper_inplace_editor.js");
+const TEST_URI = `data:text/xml;charset=UTF-8,<?xml version="1.0"?>
+ <?xml-stylesheet href="chrome://global/skin/global.css"?>
+ <?xml-stylesheet href="chrome://devtools/skin/common.css"?>
+ <?xml-stylesheet href="chrome://devtools/skin/tooltips.css"?>
+ <window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ title="Tooltip test">
+ </window>`;
+
// Test the inplace-editor autocomplete popup is aligned with the completed query.
// Which means when completing "style=display:flex; color:" the popup will aim to be
// aligned with the ":" next to "color".
// format :
// [
// what key to press,
// expected input box value after keypress,
@@ -54,32 +62,32 @@ const mockGetCSSValuesForPropertyName =
"color": ["blue", "red"],
"display": ["block", "flex", "none"]
};
return values[propertyName] || [];
};
add_task(function* () {
yield addTab("data:text/html;charset=utf-8,inplace editor CSS value autocomplete");
- let [host, win, doc] = yield createHost();
+ let [host,, doc] = yield createHost("bottom", TEST_URI);
- let xulDocument = win.top.document;
- let popup = new AutocompletePopup(xulDocument, { autoSelect: true });
+ let popup = new AutocompletePopup({ doc }, { autoSelect: true });
info("Create a CSS_MIXED type autocomplete");
yield new Promise(resolve => {
createInplaceEditorAndClick({
initial: "style=",
start: runAutocompletionTest,
contentType: InplaceEditor.CONTENT_TYPES.CSS_MIXED,
done: resolve,
popup: popup
}, doc);
});
+ popup.destroy();
host.destroy();
gBrowser.removeCurrentTab();
});
let runAutocompletionTest = Task.async(function* (editor) {
info("Starting autocomplete test for inplace-editor popup offset");
editor._getCSSPropertyList = mockGetCSSPropertyList;
editor._getCSSValuesForPropertyName = mockGetCSSValuesForPropertyName;
--- a/devtools/client/shared/test/helper_inplace_editor.js
+++ b/devtools/client/shared/test/helper_inplace_editor.js
@@ -1,59 +1,70 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/* eslint no-unused-vars: [2, {"vars": "local", "args": "none"}] */
+/* import-globals-from head.js */
"use strict";
/**
* Helper methods for the HTMLTooltip integration tests.
*/
+const HTML_NS = "http://www.w3.org/1999/xhtml";
const { editableField } = require("devtools/client/shared/inplace-editor");
/**
* Create an inplace editor linked to a span element and click on the span to
* to turn to edit mode.
*
* @param {Object} options
* Options passed to the InplaceEditor/editableField constructor.
* @param {Document} doc
* Document where the span element will be created.
* @param {String} textContent
* (optional) String that will be used as the text content of the span.
*/
-function createInplaceEditorAndClick(options, doc, textContent) {
- doc.body.innerHTML = "";
+const createInplaceEditorAndClick = Task.async(function* (options, doc, textContent) {
let span = options.element = createSpan(doc);
if (textContent) {
span.textContent = textContent;
}
info("Creating an inplace-editor field");
editableField(options);
info("Clicking on the inplace-editor field to turn to edit mode");
span.click();
-}
+});
/**
* Helper to create a span in the provided document.
*
* @param {Document} doc
* Document where the span element will be created.
* @return {Element} the created span element.
*/
function createSpan(doc) {
info("Creating a new span element");
- let span = doc.createElement("span");
+ let div = doc.createElementNS(HTML_NS, "div");
+ let span = doc.createElementNS(HTML_NS, "span");
span.setAttribute("tabindex", "0");
span.style.fontSize = "11px";
+ span.style.display = "inline-block";
+ span.style.width = "100px";
+ span.style.border = "1px solid red";
span.style.fontFamily = "monospace";
- doc.body.appendChild(span);
+
+ div.style.height = "100%";
+ div.style.position = "absolute";
+ div.appendChild(span);
+
+ let parent = doc.querySelector("window") || doc.body;
+ parent.appendChild(div);
return span;
}
/**
* Test helper simulating a key event in an InplaceEditor and checking that the
* autocompletion works as expected.
*
* @param {Array} testData
@@ -63,37 +74,42 @@ function createSpan(doc) {
* - {Number} total, the total number of suggestions in the popup
* @param {InplaceEditor} editor
* The InplaceEditor instance being tested
*/
function* testCompletion([key, completion, index, total], editor) {
info("Pressing key " + key);
info("Expecting " + completion);
+ let onVisibilityChange = null;
+ let open = total > 0;
+ if (editor.popup.isOpen != open) {
+ onVisibilityChange = editor.popup.once(open ? "popup-opened" : "popup-closed");
+ }
+
let onSuggest;
-
if (/(left|right|back_space|escape)/ig.test(key)) {
info("Adding event listener for right|back_space|escape keys");
onSuggest = once(editor.input, "keypress");
} else {
info("Waiting for after-suggest event on the editor");
onSuggest = editor.once("after-suggest");
}
info("Synthesizing key " + key);
EventUtils.synthesizeKey(key, {}, editor.input.defaultView);
yield onSuggest;
+ yield onVisibilityChange;
yield waitForTick();
info("Checking the state");
- if (completion != null) {
+ if (completion !== null) {
is(editor.input.value, completion, "Correct value is autocompleted");
}
if (total === 0) {
ok(!(editor.popup && editor.popup.isOpen), "Popup is closed");
} else {
- ok(editor.popup._panel.state == "open" ||
- editor.popup._panel.state == "showing", "Popup is open");
+ ok(editor.popup.isOpen, "Popup is open");
is(editor.popup.getItems().length, total, "Number of suggestions match");
is(editor.popup.selectedIndex, index, "Expected item is selected");
}
}
--- a/devtools/client/webconsole/test/browser_webconsole_autocomplete_popup_close_on_tab_switch.js
+++ b/devtools/client/webconsole/test/browser_webconsole_autocomplete_popup_close_on_tab_switch.js
@@ -9,17 +9,17 @@
const TEST_URI = "data:text/html;charset=utf-8,<p>bug 900448 - autocomplete " +
"popup closes on tab switch";
add_task(function* () {
yield loadTab(TEST_URI);
let hud = yield openConsole();
let popup = hud.jsterm.autocompletePopup;
- let popupShown = once(popup._panel, "popupshown");
+ let popupShown = once(popup, "popup-opened");
hud.jsterm.setInputValue("sc");
EventUtils.synthesizeKey("r", {});
yield popupShown;
yield loadTab("data:text/html;charset=utf-8,<p>testing autocomplete closes");
--- a/devtools/client/webconsole/test/browser_webconsole_bug_585991_autocomplete_keys.js
+++ b/devtools/client/webconsole/test/browser_webconsole_bug_585991_autocomplete_keys.js
@@ -25,19 +25,19 @@ add_task(function* () {
yield popupHideAfterReturnWithNoSelection();
yield testCompletionInText();
yield popupHideAfterCompletionInText();
HUD = popup = jsterm = inputNode = completeNode = null;
Services.prefs.setBoolPref(PREF_AUTO_MULTILINE, true);
});
-var consoleOpened = Task.async(function* (aHud) {
+var consoleOpened = Task.async(function* (hud) {
let deferred = promise.defer();
- HUD = aHud;
+ HUD = hud;
info("web console opened");
jsterm = HUD.jsterm;
yield jsterm.execute("window.foobarBug585991={" +
"'item0': 'value0'," +
"'item1': 'value1'," +
"'item2': 'value2'," +
@@ -46,30 +46,29 @@ var consoleOpened = Task.async(function*
yield jsterm.execute("window.testBug873250a = 'hello world';"
+ "window.testBug873250b = 'hello world 2';");
popup = jsterm.autocompletePopup;
completeNode = jsterm.completeNode;
inputNode = jsterm.inputNode;
ok(!popup.isOpen, "popup is not open");
- popup._panel.addEventListener("popupshown", function onShown() {
- popup._panel.removeEventListener("popupshown", onShown, false);
-
+ popup.once("popup-opened", () => {
ok(popup.isOpen, "popup is open");
// 4 values, and the following properties:
// __defineGetter__ __defineSetter__ __lookupGetter__ __lookupSetter__
// __proto__ hasOwnProperty isPrototypeOf propertyIsEnumerable
// toLocaleString toString toSource unwatch valueOf watch constructor.
is(popup.itemCount, 19, "popup.itemCount is correct");
let sameItems = popup.getItems().reverse().map(function (e) {
return e.label;
});
+
ok(sameItems.every(function (prop, index) {
return [
"__defineGetter__",
"__defineSetter__",
"__lookupGetter__",
"__lookupSetter__",
"__proto__",
"constructor",
@@ -129,24 +128,22 @@ var consoleOpened = Task.async(function*
EventUtils.synthesizeKey("VK_END", {});
is(popup.selectedIndex, 18, "index is last after End");
EventUtils.synthesizeKey("VK_HOME", {});
is(popup.selectedIndex, 0, "index is first after Home");
info("press Tab and wait for popup to hide");
- popup._panel.addEventListener("popuphidden", function popupHidden() {
- popup._panel.removeEventListener("popuphidden", popupHidden, false);
+ popup.once("popup-closed", () => {
deferred.resolve();
- }, false);
+ });
EventUtils.synthesizeKey("VK_TAB", {});
- }, false);
+ });
- info("wait for completion: window.foobarBug585991.");
jsterm.setInputValue("window.foobarBug585991");
EventUtils.synthesizeKey(".", {});
return deferred.promise;
});
function popupHideAfterTab() {
let deferred = promise.defer();
@@ -154,36 +151,32 @@ function popupHideAfterTab() {
// At this point the completion suggestion should be accepted.
ok(!popup.isOpen, "popup is not open");
is(jsterm.getInputValue(), "window.foobarBug585991.watch",
"completion was successful after VK_TAB");
ok(!completeNode.value, "completeNode is empty");
- popup._panel.addEventListener("popupshown", function onShown() {
- popup._panel.removeEventListener("popupshown", onShown, false);
-
+ popup.once("popup-opened", function onShown() {
ok(popup.isOpen, "popup is open");
is(popup.itemCount, 19, "popup.itemCount is correct");
is(popup.selectedIndex, 18, "First index from bottom is selected");
EventUtils.synthesizeKey("VK_DOWN", {});
let prefix = jsterm.getInputValue().replace(/[\S]/g, " ");
is(popup.selectedIndex, 0, "index 0 is selected");
is(popup.selectedItem.label, "watch", "watch is selected");
is(completeNode.value, prefix + "watch",
"completeNode.value holds watch");
- popup._panel.addEventListener("popuphidden", function onHidden() {
- popup._panel.removeEventListener("popuphidden", onHidden, false);
-
+ popup.once("popup-closed", function onHidden() {
ok(!popup.isOpen, "popup is not open after VK_ESCAPE");
is(jsterm.getInputValue(), "window.foobarBug585991.",
"completion was cancelled");
ok(!completeNode.value, "completeNode is empty");
deferred.resolve();
@@ -202,19 +195,17 @@ function popupHideAfterTab() {
});
return deferred.promise;
}
function testReturnKey() {
let deferred = promise.defer();
- popup._panel.addEventListener("popupshown", function onShown() {
- popup._panel.removeEventListener("popupshown", onShown, false);
-
+ popup.once("popup-opened", function onShown() {
ok(popup.isOpen, "popup is open");
is(popup.itemCount, 19, "popup.itemCount is correct");
is(popup.selectedIndex, 18, "First index from bottom is selected");
EventUtils.synthesizeKey("VK_DOWN", {});
let prefix = jsterm.getInputValue().replace(/[\S]/g, " ");
@@ -226,19 +217,17 @@ function testReturnKey() {
EventUtils.synthesizeKey("VK_DOWN", {});
is(popup.selectedIndex, 1, "index 1 is selected");
is(popup.selectedItem.label, "valueOf", "valueOf is selected");
is(completeNode.value, prefix + "valueOf",
"completeNode.value holds valueOf");
- popup._panel.addEventListener("popuphidden", function onHidden() {
- popup._panel.removeEventListener("popuphidden", onHidden, false);
-
+ popup.once("popup-closed", function onHidden() {
ok(!popup.isOpen, "popup is not open after VK_RETURN");
is(jsterm.getInputValue(), "window.foobarBug585991.valueOf",
"completion was successful after VK_RETURN");
ok(!completeNode.value, "completeNode is empty");
deferred.resolve();
@@ -266,28 +255,25 @@ function* dontShowArrayNumbers() {
info("dontShowArrayNumbers");
yield ContentTask.spawn(gBrowser.selectedBrowser, {}, function* () {
content.wrappedJSObject.foobarBug585991 = ["Sherlock Holmes"];
});
jsterm = HUD.jsterm;
popup = jsterm.autocompletePopup;
- popup._panel.addEventListener("popupshown", function onShown() {
- popup._panel.removeEventListener("popupshown", onShown, false);
-
+ popup.once("popup-opened", function onShown() {
let sameItems = popup.getItems().map(function (e) {
return e.label;
});
ok(!sameItems.some(function (prop) {
prop === "0";
}), "Completing on an array doesn't show numbers.");
- popup._panel.addEventListener("popuphidden", function popupHidden() {
- popup._panel.removeEventListener("popuphidden", popupHidden, false);
+ popup.once("popup-closed", function popupHidden() {
deferred.resolve();
}, false);
info("wait for popup to hide");
executeSoon(() => EventUtils.synthesizeKey("VK_ESCAPE", {}));
}, false);
info("wait for popup to show");
@@ -299,26 +285,23 @@ function* dontShowArrayNumbers() {
return deferred.promise;
}
function testReturnWithNoSelection() {
let deferred = promise.defer();
info("test pressing return with open popup, but no selection, see bug 873250");
- popup._panel.addEventListener("popupshown", function onShown() {
- popup._panel.removeEventListener("popupshown", onShown);
-
+ popup.once("popup-opened", function onShown() {
ok(popup.isOpen, "popup is open");
is(popup.itemCount, 2, "popup.itemCount is correct");
isnot(popup.selectedIndex, -1, "popup.selectedIndex is correct");
info("press Return and wait for popup to hide");
- popup._panel.addEventListener("popuphidden", function popupHidden() {
- popup._panel.removeEventListener("popuphidden", popupHidden);
+ popup.once("popup-closed", function popupHidden() {
deferred.resolve();
});
executeSoon(() => EventUtils.synthesizeKey("VK_RETURN", {}));
});
executeSoon(() => {
info("wait for popup to show");
jsterm.setInputValue("window.testBu");
@@ -339,34 +322,31 @@ function popupHideAfterReturnWithNoSelec
return promise.resolve();
}
function testCompletionInText() {
info("test that completion works inside text, see bug 812618");
let deferred = promise.defer();
- popup._panel.addEventListener("popupshown", function onShown() {
- popup._panel.removeEventListener("popupshown", onShown);
-
+ popup.once("popup-opened", function onShown() {
ok(popup.isOpen, "popup is open");
is(popup.itemCount, 2, "popup.itemCount is correct");
EventUtils.synthesizeKey("VK_DOWN", {});
is(popup.selectedIndex, 0, "popup.selectedIndex is correct");
ok(!completeNode.value, "completeNode.value is empty");
let items = popup.getItems().reverse().map(e => e.label);
let sameItems = items.every((prop, index) =>
["testBug873250a", "testBug873250b"][index] === prop);
ok(sameItems, "getItems returns the items we expect");
info("press Tab and wait for popup to hide");
- popup._panel.addEventListener("popuphidden", function popupHidden() {
- popup._panel.removeEventListener("popuphidden", popupHidden);
+ popup.once("popup-closed", function popupHidden() {
deferred.resolve();
});
EventUtils.synthesizeKey("VK_TAB", {});
});
jsterm.setInputValue("dump(window.testBu)");
inputNode.selectionStart = inputNode.selectionEnd = 18;
EventUtils.synthesizeKey("g", {});
--- a/devtools/client/webconsole/test/browser_webconsole_bug_585991_autocomplete_popup.js
+++ b/devtools/client/webconsole/test/browser_webconsole_bug_585991_autocomplete_popup.js
@@ -21,99 +21,104 @@ function consoleOpened(HUD) {
let items = [
{label: "item0", value: "value0"},
{label: "item1", value: "value1"},
{label: "item2", value: "value2"},
];
let popup = HUD.jsterm.autocompletePopup;
- let input = popup._document.activeElement;
+ let input = popup._findActiveElement();
function getActiveDescendant() {
- return input.ownerDocument.getElementById(
- input.getAttribute("aria-activedescendant"));
+ let descendantId = input.getAttribute("aria-activedescendant");
+ return popup._tooltip.panel.querySelector("#" + descendantId);
}
ok(!popup.isOpen, "popup is not open");
ok(!input.hasAttribute("aria-activedescendant"), "no aria-activedescendant");
- popup._panel.addEventListener("popupshown", function onPopupPanel() {
- popup._panel.removeEventListener("popupshown", onPopupPanel, false);
-
+ popup.once("popup-opened", () => {
ok(popup.isOpen, "popup is open");
is(popup.itemCount, 0, "no items");
- ok(!input.hasAttribute("aria-activedescendant"),
- "no aria-activedescendant");
+ ok(!input.hasAttribute("aria-activedescendant"), "no aria-activedescendant");
popup.setItems(items);
is(popup.itemCount, items.length, "items added");
let sameItems = popup.getItems();
- is(sameItems.every(function (aItem, aIndex) {
- return aItem === items[aIndex];
+ is(sameItems.every(function (item, index) {
+ return item === items[index];
}), true, "getItems returns back the same items");
- is(popup.selectedIndex, 2,
- "Index of the first item from bottom is selected.");
+ is(popup.selectedIndex, 2, "Index of the first item from bottom is selected.");
is(popup.selectedItem, items[2], "First item from bottom is selected");
- ok(getActiveDescendant().selected, "aria-activedescendant is correct");
+ ok(getActiveDescendant().classList.contains("autocomplete-selected"),
+ "aria-activedescendant is correct");
popup.selectedIndex = 1;
is(popup.selectedIndex, 1, "index 1 is selected");
is(popup.selectedItem, items[1], "item1 is selected");
- ok(getActiveDescendant().selected, "aria-activedescendant is correct");
+ ok(getActiveDescendant().classList.contains("autocomplete-selected"),
+ "aria-activedescendant is correct");
popup.selectedItem = items[2];
is(popup.selectedIndex, 2, "index 2 is selected");
is(popup.selectedItem, items[2], "item2 is selected");
- ok(getActiveDescendant().selected, "aria-activedescendant is correct");
+ ok(getActiveDescendant().classList.contains("autocomplete-selected"),
+ "aria-activedescendant is correct");
is(popup.selectPreviousItem(), items[1], "selectPreviousItem() works");
is(popup.selectedIndex, 1, "index 1 is selected");
is(popup.selectedItem, items[1], "item1 is selected");
- ok(getActiveDescendant().selected, "aria-activedescendant is correct");
+ ok(getActiveDescendant().classList.contains("autocomplete-selected"),
+ "aria-activedescendant is correct");
- is(popup.selectNextItem(), items[2], "selectPreviousItem() works");
+ is(popup.selectNextItem(), items[2], "selectNextItem() works");
is(popup.selectedIndex, 2, "index 2 is selected");
is(popup.selectedItem, items[2], "item2 is selected");
- ok(getActiveDescendant().selected, "aria-activedescendant is correct");
+ ok(getActiveDescendant().classList.contains("autocomplete-selected"),
+ "aria-activedescendant is correct");
- ok(popup.selectNextItem(), "selectPreviousItem() works");
+ ok(popup.selectNextItem(), "selectNextItem() works");
is(popup.selectedIndex, 0, "index 0 is selected");
is(popup.selectedItem, items[0], "item0 is selected");
- ok(getActiveDescendant().selected, "aria-activedescendant is correct");
+ ok(getActiveDescendant().classList.contains("autocomplete-selected"),
+ "aria-activedescendant is correct");
items.push({label: "label3", value: "value3"});
popup.appendItem(items[3]);
is(popup.itemCount, items.length, "item3 appended");
popup.selectedIndex = 3;
is(popup.selectedItem, items[3], "item3 is selected");
- ok(getActiveDescendant().selected, "aria-activedescendant is correct");
+ ok(getActiveDescendant().classList.contains("autocomplete-selected"),
+ "aria-activedescendant is correct");
popup.removeItem(items[2]);
is(popup.selectedIndex, 2, "index2 is selected");
is(popup.selectedItem, items[3], "item3 is still selected");
- ok(getActiveDescendant().selected, "aria-activedescendant is correct");
+ ok(getActiveDescendant().classList.contains("autocomplete-selected"),
+ "aria-activedescendant is correct");
is(popup.itemCount, items.length - 1, "item2 removed");
popup.clearItems();
is(popup.itemCount, 0, "items cleared");
- ok(!input.hasAttribute("aria-activedescendant"),
- "no aria-activedescendant");
+ ok(!input.hasAttribute("aria-activedescendant"), "no aria-activedescendant");
+ popup.once("popup-closed", () => {
+ deferred.resolve();
+ });
popup.hidePopup();
- deferred.resolve();
- }, false);
+ });
- popup.openPopup();
+ popup.openPopup(input);
return deferred.promise;
}
--- a/devtools/client/webconsole/test/browser_webconsole_bug_651501_document_body_autocomplete.js
+++ b/devtools/client/webconsole/test/browser_webconsole_bug_651501_document_body_autocomplete.js
@@ -28,51 +28,47 @@ add_task(function* () {
function consoleOpened() {
let deferred = promise.defer();
let jsterm = gHUD.jsterm;
let popup = jsterm.autocompletePopup;
ok(!popup.isOpen, "popup is not open");
- popup._panel.addEventListener("popupshown", function onShown() {
- popup._panel.removeEventListener("popupshown", onShown, false);
-
+ popup.once("popup-opened", () => {
ok(popup.isOpen, "popup is open");
is(popup.itemCount, jsterm._autocompleteCache.length,
"popup.itemCount is correct");
isnot(jsterm._autocompleteCache.indexOf("addEventListener"), -1,
"addEventListener is in the list of suggestions");
isnot(jsterm._autocompleteCache.indexOf("bgColor"), -1,
"bgColor is in the list of suggestions");
isnot(jsterm._autocompleteCache.indexOf("ATTRIBUTE_NODE"), -1,
"ATTRIBUTE_NODE is in the list of suggestions");
- popup._panel.addEventListener("popuphidden", deferred.resolve, false);
-
+ popup.once("popup-closed", () => {
+ deferred.resolve();
+ });
EventUtils.synthesizeKey("VK_ESCAPE", {});
- }, false);
+ });
jsterm.setInputValue("document.body");
EventUtils.synthesizeKey(".", {});
return deferred.promise;
}
function autocompletePopupHidden() {
let deferred = promise.defer();
let jsterm = gHUD.jsterm;
let popup = jsterm.autocompletePopup;
let completeNode = jsterm.completeNode;
- popup._panel.removeEventListener("popuphidden", autocompletePopupHidden,
- false);
-
ok(!popup.isOpen, "popup is not open");
jsterm.once("autocomplete-updated", function () {
is(completeNode.value, testStr + "dy", "autocomplete shows document.body");
deferred.resolve();
});
let inputStr = "document.b";
@@ -84,18 +80,18 @@ function autocompletePopupHidden() {
}
function testPropertyPanel() {
let deferred = promise.defer();
let jsterm = gHUD.jsterm;
jsterm.clearOutput();
jsterm.execute("document", (msg) => {
- jsterm.once("variablesview-fetched", (aEvent, aView) => {
- deferred.resolve(aView);
+ jsterm.once("variablesview-fetched", (evt, view) => {
+ deferred.resolve(view);
});
let anchor = msg.querySelector(".message-body a");
EventUtils.synthesizeMouse(anchor, 2, 2, {}, gHUD.iframeWindow);
});
return deferred.promise;
}
--- a/devtools/client/webconsole/test/browser_webconsole_bug_660806_history_nav.js
+++ b/devtools/client/webconsole/test/browser_webconsole_bug_660806_history_nav.js
@@ -20,35 +20,35 @@ function consoleOpened(HUD) {
let deferred = promise.defer();
let jsterm = HUD.jsterm;
let popup = jsterm.autocompletePopup;
let onShown = function () {
ok(false, "popup shown");
};
- jsterm.execute("window.foobarBug660806 = {\
- 'location': 'value0',\
- 'locationbar': 'value1'\
- }");
+ jsterm.execute(`window.foobarBug660806 = {
+ 'location': 'value0',
+ 'locationbar': 'value1'
+ }`);
- popup._panel.addEventListener("popupshown", onShown, false);
+ popup.on("popup-opened", onShown);
ok(!popup.isOpen, "popup is not open");
ok(!jsterm.lastInputValue, "no lastInputValue");
jsterm.setInputValue("window.foobarBug660806.location");
is(jsterm.lastInputValue, "window.foobarBug660806.location",
"lastInputValue is correct");
EventUtils.synthesizeKey("VK_RETURN", {});
EventUtils.synthesizeKey("VK_UP", {});
is(jsterm.lastInputValue, "window.foobarBug660806.location",
"lastInputValue is correct, again");
executeSoon(function () {
ok(!popup.isOpen, "popup is not open");
- popup._panel.removeEventListener("popupshown", onShown, false);
+ popup.off("popup-opened", onShown);
executeSoon(deferred.resolve);
});
return deferred.promise;
}
--- a/devtools/client/webconsole/test/browser_webconsole_split_escape_key.js
+++ b/devtools/client/webconsole/test/browser_webconsole_split_escape_key.js
@@ -76,25 +76,24 @@
return result;
}
function testHideAutoCompletePopupAfterEscape() {
let deferred = promise.defer();
let popup = jsterm.autocompletePopup;
- popup._panel.addEventListener("popuphidden", function popupHidden() {
- popup._panel.removeEventListener("popuphidden", popupHidden, false);
+ popup.once("popup-closed", () => {
ok(!popup.isOpen,
"Auto complete popup is hidden.");
ok(toolbox.splitConsole,
"Split console is open after hiding the autocomplete popup.");
deferred.resolve();
- }, false);
+ });
EventUtils.sendKey("ESCAPE", toolbox.win);
return deferred.promise;
}
function testCancelPropertyEditorAfterEscape() {
EventUtils.sendKey("ESCAPE", variablesView.window);
@@ -131,29 +130,23 @@
let results = yield findVariableViewProperties(variablesView, [
{name: "bar", value: "baz"}
], {webconsole: hud});
results[0].matchedProp.focus();
EventUtils.synthesizeKey("VK_RETURN", variablesView.window);
}
function showAutoCompletePopoup() {
- let deferred = promise.defer();
- let popupPanel = jsterm.autocompletePopup._panel;
-
- popupPanel.addEventListener("popupshown", function popupShown() {
- popupPanel.removeEventListener("popupshown", popupShown, false);
- deferred.resolve();
- }, false);
+ let onPopupShown = jsterm.autocompletePopup.once("popup-opened");
jsterm.focus();
jsterm.setInputValue("document.location.");
EventUtils.sendKey("TAB", hud.iframeWindow);
- return deferred.promise;
+ return onPopupShown;
}
function finish() {
toolbox.destroy().then(() => {
toolbox = null;
hud = null;
jsterm = null;
hudMessages = null;