Commit 88aba243 authored by Shane Hughes's avatar Shane Hughes
Browse files

Bug 1743878 - Avoid opening caret browsing dialogs when already open. r=dholbert

parent 36e8371c
Loading
Loading
Loading
Loading
+25 −15
Original line number Original line Diff line number Diff line
@@ -104,6 +104,8 @@


    _isBusy: false,
    _isBusy: false,


    _awaitingToggleCaretBrowsingPrompt: false,

    arrowKeysShouldWrap: AppConstants == "macosx",
    arrowKeysShouldWrap: AppConstants == "macosx",


    _dateTimePicker: null,
    _dateTimePicker: null,
@@ -5428,7 +5430,7 @@
      const kPrefCaretBrowsingOn = "accessibility.browsewithcaret";
      const kPrefCaretBrowsingOn = "accessibility.browsewithcaret";


      var isEnabled = Services.prefs.getBoolPref(kPrefShortcutEnabled);
      var isEnabled = Services.prefs.getBoolPref(kPrefShortcutEnabled);
      if (!isEnabled) {
      if (!isEnabled || this._awaitingToggleCaretBrowsingPrompt) {
        return;
        return;
      }
      }


@@ -5442,6 +5444,8 @@
        var checkValue = { value: false };
        var checkValue = { value: false };
        var promptService = Services.prompt;
        var promptService = Services.prompt;


        try {
          this._awaitingToggleCaretBrowsingPrompt = true;
          var buttonPressed = promptService.confirmEx(
          var buttonPressed = promptService.confirmEx(
            window,
            window,
            gTabBrowserBundle.GetStringFromName(
            gTabBrowserBundle.GetStringFromName(
@@ -5449,13 +5453,19 @@
            ),
            ),
            gTabBrowserBundle.GetStringFromName("browsewithcaret.checkLabel"),
            gTabBrowserBundle.GetStringFromName("browsewithcaret.checkLabel"),
            // Make "No" the default:
            // Make "No" the default:
          promptService.STD_YES_NO_BUTTONS | promptService.BUTTON_POS_1_DEFAULT,
            promptService.STD_YES_NO_BUTTONS |
              promptService.BUTTON_POS_1_DEFAULT,
            null,
            null,
            null,
            null,
            null,
            null,
            gTabBrowserBundle.GetStringFromName("browsewithcaret.checkMsg"),
            gTabBrowserBundle.GetStringFromName("browsewithcaret.checkMsg"),
            checkValue
            checkValue
          );
          );
        } catch (ex) {
          return;
        } finally {
          this._awaitingToggleCaretBrowsingPrompt = false;
        }
        if (buttonPressed != 0) {
        if (buttonPressed != 0) {
          if (checkValue.value) {
          if (checkValue.value) {
            try {
            try {
+67 −0
Original line number Original line Diff line number Diff line
@@ -298,3 +298,70 @@ add_task(async function toggleCheckboxWantCaretBrowsing() {


  BrowserTestUtils.removeTab(tab);
  BrowserTestUtils.removeTab(tab);
});
});

// Test for bug 1743878: Many repeated modal caret-browsing dialogs, if you
// accidentally hold down F7 for a few seconds
add_task(async function testF7SpamDoesNotOpenDialogs() {
  let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser);
  registerCleanupFunction(() => BrowserTestUtils.removeTab(tab));

  let promiseGotKey = promiseCaretPromptOpened();
  hitF7();
  let prompt = await promiseGotKey;
  let doc = prompt.document;
  let dialog = doc.getElementById("commonDialog");

  let promiseDialogUnloaded = BrowserTestUtils.waitForEvent(prompt, "unload");

  // Listen for an additional prompt to open, which should not happen.
  let promiseDialogOrTimeout = () =>
    Promise.race([
      promiseCaretPromptOpened(),
      // eslint-disable-next-line mozilla/no-arbitrary-setTimeout
      new Promise(resolve => setTimeout(resolve, 100)),
    ]);

  let openedPromise = promiseDialogOrTimeout();

  // Hit F7 two more times: once to test that _awaitingToggleCaretBrowsingPrompt
  // is applied, and again to test that its value isn't somehow reset by
  // pressing F7 while the dialog is open.
  for (let i = 0; i < 2; i++) {
    await new Promise(resolve =>
      SimpleTest.executeSoon(() => {
        hitF7();
        resolve();
      })
    );
  }

  // Say no:
  dialog.cancelDialog();
  await promiseDialogUnloaded;
  info("Dialog unloaded");

  let openedDialog = await openedPromise;
  ok(!openedDialog, "No additional dialog should have opened.");

  // If the test fails, clean up any dialogs we erroneously opened so they don't
  // interfere with other tests.
  let extraDialogs = 0;
  while (openedDialog) {
    extraDialogs += 1;
    let doc = openedDialog.document;
    let dialog = doc.getElementById("commonDialog");
    openedPromise = promiseDialogOrTimeout();
    dialog.cancelDialog();
    openedDialog = await openedPromise;
  }
  if (extraDialogs) {
    info(`Closed ${extraDialogs} extra dialogs.`);
  }

  // Either way, we now have an extra observer, so clean it up.
  gCaretPromptOpeningObserver();

  Services.prefs.setBoolPref(kPrefShortcutEnabled, true);
  Services.prefs.setBoolPref(kPrefWarnOnEnable, true);
  Services.prefs.setBoolPref(kPrefCaretBrowsingOn, false);
});