зеркало из https://github.com/mozilla/gecko-dev.git
Backed out changeset d75769547bb8 (bug 1635106) for failures on browser_contextmenu_input.js. CLOSED TREE
This commit is contained in:
Родитель
a1455719e6
Коммит
cf7c236c65
|
@ -1227,20 +1227,4 @@ class ContextMenuChild extends JSWindowActorChild {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
_destructionObservers = new Set();
|
||||
registerDestructionObserver(obj) {
|
||||
this._destructionObservers.add(obj);
|
||||
}
|
||||
|
||||
unregisterDestructionObserver(obj) {
|
||||
this._destructionObservers.delete(obj);
|
||||
}
|
||||
|
||||
didDestroy() {
|
||||
for (let obs of this._destructionObservers) {
|
||||
obs.actorDestroyed(this);
|
||||
}
|
||||
this._destructionObservers = null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,6 @@ support-files =
|
|||
|
||||
[browser_contextmenu_loadblobinnewtab.js]
|
||||
support-files = browser_contextmenu_loadblobinnewtab.html
|
||||
[browser_contextmenu_spellcheck.js]
|
||||
[browser_view_image.js]
|
||||
support-files =
|
||||
test_view_image_revoked_cached_blob.html
|
||||
|
|
|
@ -45,6 +45,146 @@ add_task(async function test_text_input() {
|
|||
]);
|
||||
});
|
||||
|
||||
add_task(async function test_text_input_spellcheck() {
|
||||
await test_contextmenu(
|
||||
"#input_spellcheck_no_value",
|
||||
[
|
||||
"context-undo",
|
||||
false,
|
||||
"---",
|
||||
null,
|
||||
"context-cut",
|
||||
true,
|
||||
"context-copy",
|
||||
true,
|
||||
"context-paste",
|
||||
null, // ignore clipboard state
|
||||
"context-delete",
|
||||
false,
|
||||
"---",
|
||||
null,
|
||||
"context-selectall",
|
||||
false,
|
||||
"---",
|
||||
null,
|
||||
"spell-check-enabled",
|
||||
true,
|
||||
"spell-dictionaries",
|
||||
true,
|
||||
[
|
||||
"spell-check-dictionary-en-US",
|
||||
true,
|
||||
"---",
|
||||
null,
|
||||
"spell-add-dictionaries",
|
||||
true,
|
||||
],
|
||||
null,
|
||||
],
|
||||
{
|
||||
waitForSpellCheck: true,
|
||||
async preCheckContextMenuFn() {
|
||||
await SpecialPowers.spawn(
|
||||
gBrowser.selectedBrowser,
|
||||
[],
|
||||
async function() {
|
||||
let doc = content.document;
|
||||
let input = doc.getElementById("input_spellcheck_no_value");
|
||||
input.setAttribute("spellcheck", "true");
|
||||
input.clientTop; // force layout flush
|
||||
}
|
||||
);
|
||||
},
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
add_task(async function test_text_input_spellcheckwrong() {
|
||||
await test_contextmenu(
|
||||
"#input_spellcheck_incorrect",
|
||||
[
|
||||
"*prodigality",
|
||||
true, // spelling suggestion
|
||||
"spell-add-to-dictionary",
|
||||
true,
|
||||
"---",
|
||||
null,
|
||||
"context-undo",
|
||||
false,
|
||||
"---",
|
||||
null,
|
||||
"context-cut",
|
||||
true,
|
||||
"context-copy",
|
||||
true,
|
||||
"context-paste",
|
||||
null, // ignore clipboard state
|
||||
"context-delete",
|
||||
false,
|
||||
"---",
|
||||
null,
|
||||
"context-selectall",
|
||||
true,
|
||||
"---",
|
||||
null,
|
||||
"spell-check-enabled",
|
||||
true,
|
||||
"spell-dictionaries",
|
||||
true,
|
||||
[
|
||||
"spell-check-dictionary-en-US",
|
||||
true,
|
||||
"---",
|
||||
null,
|
||||
"spell-add-dictionaries",
|
||||
true,
|
||||
],
|
||||
null,
|
||||
],
|
||||
{ waitForSpellCheck: true }
|
||||
);
|
||||
});
|
||||
|
||||
add_task(async function test_text_input_spellcheckcorrect() {
|
||||
await test_contextmenu(
|
||||
"#input_spellcheck_correct",
|
||||
[
|
||||
"context-undo",
|
||||
false,
|
||||
"---",
|
||||
null,
|
||||
"context-cut",
|
||||
true,
|
||||
"context-copy",
|
||||
true,
|
||||
"context-paste",
|
||||
null, // ignore clipboard state
|
||||
"context-delete",
|
||||
false,
|
||||
"---",
|
||||
null,
|
||||
"context-selectall",
|
||||
true,
|
||||
"---",
|
||||
null,
|
||||
"spell-check-enabled",
|
||||
true,
|
||||
"spell-dictionaries",
|
||||
true,
|
||||
[
|
||||
"spell-check-dictionary-en-US",
|
||||
true,
|
||||
"---",
|
||||
null,
|
||||
"spell-add-dictionaries",
|
||||
true,
|
||||
],
|
||||
null,
|
||||
],
|
||||
{ waitForSpellCheck: true }
|
||||
);
|
||||
});
|
||||
|
||||
add_task(async function test_text_input_disabled() {
|
||||
await test_contextmenu(
|
||||
"#input_disabled",
|
||||
|
|
|
@ -1,250 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
let contextMenu;
|
||||
|
||||
const example_base =
|
||||
"http://example.com/browser/browser/base/content/test/contextMenu/";
|
||||
const MAIN_URL = example_base + "subtst_contextmenu_input.html";
|
||||
|
||||
add_task(async function test_setup() {
|
||||
await BrowserTestUtils.openNewForegroundTab(gBrowser, MAIN_URL);
|
||||
|
||||
const chrome_base =
|
||||
"chrome://mochitests/content/browser/browser/base/content/test/contextMenu/";
|
||||
const contextmenu_common = chrome_base + "contextmenu_common.js";
|
||||
/* import-globals-from contextmenu_common.js */
|
||||
Services.scriptloader.loadSubScript(contextmenu_common, this);
|
||||
|
||||
// Ensure screenshots is really disabled (bug 1498738)
|
||||
const addon = await AddonManager.getAddonByID("screenshots@mozilla.org");
|
||||
await addon.disable({ allowSystemAddons: true });
|
||||
});
|
||||
|
||||
add_task(async function test_text_input_spellcheck() {
|
||||
await test_contextmenu(
|
||||
"#input_spellcheck_no_value",
|
||||
[
|
||||
"context-undo",
|
||||
false,
|
||||
"---",
|
||||
null,
|
||||
"context-cut",
|
||||
true,
|
||||
"context-copy",
|
||||
true,
|
||||
"context-paste",
|
||||
null, // ignore clipboard state
|
||||
"context-delete",
|
||||
false,
|
||||
"---",
|
||||
null,
|
||||
"context-selectall",
|
||||
false,
|
||||
"---",
|
||||
null,
|
||||
"spell-check-enabled",
|
||||
true,
|
||||
"spell-dictionaries",
|
||||
true,
|
||||
[
|
||||
"spell-check-dictionary-en-US",
|
||||
true,
|
||||
"---",
|
||||
null,
|
||||
"spell-add-dictionaries",
|
||||
true,
|
||||
],
|
||||
null,
|
||||
],
|
||||
{
|
||||
waitForSpellCheck: true,
|
||||
async preCheckContextMenuFn() {
|
||||
await SpecialPowers.spawn(
|
||||
gBrowser.selectedBrowser,
|
||||
[],
|
||||
async function() {
|
||||
let doc = content.document;
|
||||
let input = doc.getElementById("input_spellcheck_no_value");
|
||||
input.setAttribute("spellcheck", "true");
|
||||
input.clientTop; // force layout flush
|
||||
}
|
||||
);
|
||||
},
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
add_task(async function test_text_input_spellcheckwrong() {
|
||||
await test_contextmenu(
|
||||
"#input_spellcheck_incorrect",
|
||||
[
|
||||
"*prodigality",
|
||||
true, // spelling suggestion
|
||||
"spell-add-to-dictionary",
|
||||
true,
|
||||
"---",
|
||||
null,
|
||||
"context-undo",
|
||||
false,
|
||||
"---",
|
||||
null,
|
||||
"context-cut",
|
||||
true,
|
||||
"context-copy",
|
||||
true,
|
||||
"context-paste",
|
||||
null, // ignore clipboard state
|
||||
"context-delete",
|
||||
false,
|
||||
"---",
|
||||
null,
|
||||
"context-selectall",
|
||||
true,
|
||||
"---",
|
||||
null,
|
||||
"spell-check-enabled",
|
||||
true,
|
||||
"spell-dictionaries",
|
||||
true,
|
||||
[
|
||||
"spell-check-dictionary-en-US",
|
||||
true,
|
||||
"---",
|
||||
null,
|
||||
"spell-add-dictionaries",
|
||||
true,
|
||||
],
|
||||
null,
|
||||
],
|
||||
{ waitForSpellCheck: true }
|
||||
);
|
||||
});
|
||||
|
||||
const kCorrectItems = [
|
||||
"context-undo",
|
||||
false,
|
||||
"---",
|
||||
null,
|
||||
"context-cut",
|
||||
true,
|
||||
"context-copy",
|
||||
true,
|
||||
"context-paste",
|
||||
null, // ignore clipboard state
|
||||
"context-delete",
|
||||
false,
|
||||
"---",
|
||||
null,
|
||||
"context-selectall",
|
||||
true,
|
||||
"---",
|
||||
null,
|
||||
"spell-check-enabled",
|
||||
true,
|
||||
"spell-dictionaries",
|
||||
true,
|
||||
[
|
||||
"spell-check-dictionary-en-US",
|
||||
true,
|
||||
"---",
|
||||
null,
|
||||
"spell-add-dictionaries",
|
||||
true,
|
||||
],
|
||||
null,
|
||||
];
|
||||
|
||||
add_task(async function test_text_input_spellcheckcorrect() {
|
||||
await test_contextmenu("#input_spellcheck_correct", kCorrectItems, {
|
||||
waitForSpellCheck: true,
|
||||
});
|
||||
});
|
||||
|
||||
add_task(async function test_text_input_spellcheck_deadactor() {
|
||||
await test_contextmenu("#input_spellcheck_correct", kCorrectItems, {
|
||||
waitForSpellCheck: true,
|
||||
keepMenuOpen: true,
|
||||
});
|
||||
let wgp = gBrowser.selectedBrowser.browsingContext.currentWindowGlobal;
|
||||
|
||||
// Now the menu is open, and spellcheck is running, switch to another tab and
|
||||
// close the original:
|
||||
let tab = gBrowser.selectedTab;
|
||||
await BrowserTestUtils.openNewForegroundTab(gBrowser, "https://example.org");
|
||||
BrowserTestUtils.removeTab(tab);
|
||||
// Ensure we've invalidated the actor
|
||||
await TestUtils.waitForCondition(
|
||||
() => wgp.isClosed,
|
||||
"Waiting for actor to be dead after tab closes"
|
||||
);
|
||||
contextMenu.hidePopup();
|
||||
|
||||
// Now go back to the input testcase:
|
||||
BrowserTestUtils.loadURI(gBrowser.selectedBrowser, MAIN_URL);
|
||||
await BrowserTestUtils.browserLoaded(
|
||||
gBrowser.selectedBrowser,
|
||||
false,
|
||||
MAIN_URL
|
||||
);
|
||||
|
||||
// Check the menu still looks the same, keep it open again:
|
||||
await test_contextmenu("#input_spellcheck_correct", kCorrectItems, {
|
||||
waitForSpellCheck: true,
|
||||
keepMenuOpen: true,
|
||||
});
|
||||
|
||||
// Now navigate the tab, after ensuring there's an unload listener, so
|
||||
// we don't end up in bfcache:
|
||||
await SpecialPowers.spawn(gBrowser.selectedBrowser, [], async function() {
|
||||
content.document.body.setAttribute("onunload", "");
|
||||
});
|
||||
wgp = gBrowser.selectedBrowser.browsingContext.currentWindowGlobal;
|
||||
|
||||
const NEW_URL = MAIN_URL.replace(".com", ".org");
|
||||
BrowserTestUtils.loadURI(gBrowser.selectedBrowser, NEW_URL);
|
||||
await BrowserTestUtils.browserLoaded(
|
||||
gBrowser.selectedBrowser,
|
||||
false,
|
||||
NEW_URL
|
||||
);
|
||||
// Ensure we've invalidated the actor
|
||||
await TestUtils.waitForCondition(
|
||||
() => wgp.isClosed,
|
||||
"Waiting for actor to be dead after onunload"
|
||||
);
|
||||
contextMenu.hidePopup();
|
||||
|
||||
// Check the menu *still* looks the same (and keep it open again):
|
||||
await test_contextmenu("#input_spellcheck_correct", kCorrectItems, {
|
||||
waitForSpellCheck: true,
|
||||
keepMenuOpen: true,
|
||||
});
|
||||
|
||||
// Check what happens if the actor stays alive by loading the same page
|
||||
// again; now the context menu stuff should be destroyed by the menu
|
||||
// hiding, nothing else.
|
||||
wgp = gBrowser.selectedBrowser.browsingContext.currentWindowGlobal;
|
||||
BrowserTestUtils.loadURI(gBrowser.selectedBrowser, NEW_URL);
|
||||
await BrowserTestUtils.browserLoaded(
|
||||
gBrowser.selectedBrowser,
|
||||
false,
|
||||
NEW_URL
|
||||
);
|
||||
contextMenu.hidePopup();
|
||||
|
||||
// Check the menu still looks the same:
|
||||
await test_contextmenu("#input_spellcheck_correct", kCorrectItems, {
|
||||
waitForSpellCheck: true,
|
||||
});
|
||||
// And test it a last time without any navigation:
|
||||
await test_contextmenu("#input_spellcheck_correct", kCorrectItems, {
|
||||
waitForSpellCheck: true,
|
||||
});
|
||||
});
|
||||
|
||||
add_task(async function test_cleanup() {
|
||||
BrowserTestUtils.removeTab(gBrowser.selectedTab);
|
||||
});
|
|
@ -352,8 +352,6 @@ let lastElementSelector = null;
|
|||
* preCheckContextMenuFn: callback to run before opening menu
|
||||
* onContextMenuShown: callback to run when the context menu is shown
|
||||
* postCheckContextMenuFn: callback to run after opening menu
|
||||
* keepMenuOpen: if true, we do not call hidePopup, the consumer is
|
||||
* responsible for calling it.
|
||||
* @return {Promise} resolved after the test finishes
|
||||
*/
|
||||
async function test_contextmenu(selector, menuItems, options = {}) {
|
||||
|
@ -474,8 +472,6 @@ async function test_contextmenu(selector, menuItems, options = {}) {
|
|||
info("Completed postCheckContextMenuFn");
|
||||
}
|
||||
|
||||
if (!options.keepMenuOpen) {
|
||||
contextMenu.hidePopup();
|
||||
await awaitPopupHidden;
|
||||
}
|
||||
contextMenu.hidePopup();
|
||||
await awaitPopupHidden;
|
||||
}
|
||||
|
|
|
@ -28,25 +28,6 @@ class InlineSpellCheckerParent extends JSWindowActorParent {
|
|||
}
|
||||
|
||||
uninit() {
|
||||
// This method gets called by InlineSpellChecker when the context menu
|
||||
// goes away and the InlineSpellChecker instance is still alive.
|
||||
// Stop referencing it and tidy the child end of us.
|
||||
this.sendAsyncMessage("InlineSpellChecker:uninit", {});
|
||||
}
|
||||
|
||||
_destructionObservers = new Set();
|
||||
registerDestructionObserver(obj) {
|
||||
this._destructionObservers.add(obj);
|
||||
}
|
||||
|
||||
unregisterDestructionObserver(obj) {
|
||||
this._destructionObservers.delete(obj);
|
||||
}
|
||||
|
||||
didDestroy() {
|
||||
for (let obs of this._destructionObservers) {
|
||||
obs.actorDestroyed(this);
|
||||
}
|
||||
this._destructionObservers = null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,15 +27,7 @@ InlineSpellChecker.prototype = {
|
|||
|
||||
initFromRemote(aSpellInfo, aWindowGlobalParent) {
|
||||
if (this.mRemote) {
|
||||
// We shouldn't get here, but let's just recover instead of bricking the
|
||||
// menu by throwing exceptions:
|
||||
Cu.reportError(new Error("Unexpected remote spellchecker present!"));
|
||||
try {
|
||||
this.mRemote.uninit();
|
||||
} catch (ex) {
|
||||
Cu.reportError(ex);
|
||||
}
|
||||
this.mRemote = null;
|
||||
throw new Error("Unexpected state");
|
||||
}
|
||||
this.uninit();
|
||||
|
||||
|
@ -498,7 +490,6 @@ function RemoteSpellChecker(aSpellInfo, aWindowGlobalParent) {
|
|||
this._spellInfo = aSpellInfo;
|
||||
this._suggestionGenerator = null;
|
||||
this._actor = aWindowGlobalParent.getActor("InlineSpellChecker");
|
||||
this._actor.registerDestructionObserver(this);
|
||||
}
|
||||
|
||||
RemoteSpellChecker.prototype = {
|
||||
|
@ -580,15 +571,6 @@ RemoteSpellChecker.prototype = {
|
|||
this._actor.recheckSpelling();
|
||||
},
|
||||
uninit() {
|
||||
if (this._actor) {
|
||||
this._actor.uninit();
|
||||
this._actor.unregisterDestructionObserver(this);
|
||||
}
|
||||
},
|
||||
|
||||
actorDestroyed() {
|
||||
// The actor lets us know if it gets destroyed, so we don't
|
||||
// later try to call `.uninit()` on it.
|
||||
this._actor = null;
|
||||
this._actor.uninit();
|
||||
},
|
||||
};
|
||||
|
|
|
@ -17,7 +17,6 @@ var InlineSpellCheckerContent = {
|
|||
|
||||
initContextMenu(event, editFlags, actor) {
|
||||
this._actor = actor;
|
||||
this._actor.registerDestructionObserver(this);
|
||||
|
||||
let spellChecker;
|
||||
if (!(editFlags & (SpellCheckHelper.TEXTAREA | SpellCheckHelper.INPUT))) {
|
||||
|
@ -76,17 +75,10 @@ var InlineSpellCheckerContent = {
|
|||
},
|
||||
|
||||
uninitContextMenu() {
|
||||
if (this._actor) {
|
||||
this._actor.unregisterDestructionObserver(this);
|
||||
}
|
||||
this._actor = null;
|
||||
this._spellChecker = null;
|
||||
},
|
||||
|
||||
actorDestroyed() {
|
||||
this.uninitContextMenu();
|
||||
},
|
||||
|
||||
_generateSpellSuggestions() {
|
||||
let spellChecker = this._spellChecker.mInlineSpellChecker.spellChecker;
|
||||
try {
|
||||
|
|
Загрузка…
Ссылка в новой задаче