forked from mirrors/gecko-dev
		
	
		
			
				
	
	
		
			312 lines
		
	
	
	
		
			10 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			312 lines
		
	
	
	
		
			10 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
add_task(async function test_reserved_shortcuts() {
 | 
						|
  let keyset = document.createXULElement("keyset");
 | 
						|
  let key1 = document.createXULElement("key");
 | 
						|
  key1.setAttribute("id", "kt_reserved");
 | 
						|
  key1.setAttribute("modifiers", "shift");
 | 
						|
  key1.setAttribute("key", "O");
 | 
						|
  key1.setAttribute("reserved", "true");
 | 
						|
  key1.setAttribute("count", "0");
 | 
						|
  key1.addEventListener("command", () => {
 | 
						|
    let attribute = key1.getAttribute("count");
 | 
						|
    key1.setAttribute("count", Number(attribute) + 1);
 | 
						|
  });
 | 
						|
 | 
						|
  let key2 = document.createXULElement("key");
 | 
						|
  key2.setAttribute("id", "kt_notreserved");
 | 
						|
  key2.setAttribute("modifiers", "shift");
 | 
						|
  key2.setAttribute("key", "P");
 | 
						|
  key2.setAttribute("reserved", "false");
 | 
						|
  key2.setAttribute("count", "0");
 | 
						|
  key2.addEventListener("command", () => {
 | 
						|
    let attribute = key2.getAttribute("count");
 | 
						|
    key2.setAttribute("count", Number(attribute) + 1);
 | 
						|
  });
 | 
						|
 | 
						|
  let key3 = document.createXULElement("key");
 | 
						|
  key3.setAttribute("id", "kt_reserveddefault");
 | 
						|
  key3.setAttribute("modifiers", "shift");
 | 
						|
  key3.setAttribute("key", "Q");
 | 
						|
  key3.setAttribute("count", "0");
 | 
						|
  key3.addEventListener("command", () => {
 | 
						|
    let attribute = key3.getAttribute("count");
 | 
						|
    key3.setAttribute("count", Number(attribute) + 1);
 | 
						|
  });
 | 
						|
 | 
						|
  keyset.appendChild(key1);
 | 
						|
  keyset.appendChild(key2);
 | 
						|
  keyset.appendChild(key3);
 | 
						|
  let container = document.createXULElement("box");
 | 
						|
  container.appendChild(keyset);
 | 
						|
  document.documentElement.appendChild(container);
 | 
						|
 | 
						|
  const pageUrl =
 | 
						|
    "data:text/html,<body onload='document.body.firstElementChild.focus();'><div onkeydown='event.preventDefault();' tabindex=0>Test</div></body>";
 | 
						|
  let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, pageUrl);
 | 
						|
 | 
						|
  EventUtils.sendString("OPQ");
 | 
						|
 | 
						|
  is(
 | 
						|
    document.getElementById("kt_reserved").getAttribute("count"),
 | 
						|
    "1",
 | 
						|
    "reserved='true' with preference off"
 | 
						|
  );
 | 
						|
  is(
 | 
						|
    document.getElementById("kt_notreserved").getAttribute("count"),
 | 
						|
    "0",
 | 
						|
    "reserved='false' with preference off"
 | 
						|
  );
 | 
						|
  is(
 | 
						|
    document.getElementById("kt_reserveddefault").getAttribute("count"),
 | 
						|
    "0",
 | 
						|
    "default reserved with preference off"
 | 
						|
  );
 | 
						|
 | 
						|
  // Now try with reserved shortcut key handling enabled.
 | 
						|
  await new Promise(resolve => {
 | 
						|
    SpecialPowers.pushPrefEnv(
 | 
						|
      { set: [["permissions.default.shortcuts", 2]] },
 | 
						|
      resolve
 | 
						|
    );
 | 
						|
  });
 | 
						|
 | 
						|
  EventUtils.sendString("OPQ");
 | 
						|
 | 
						|
  is(
 | 
						|
    document.getElementById("kt_reserved").getAttribute("count"),
 | 
						|
    "2",
 | 
						|
    "reserved='true' with preference on"
 | 
						|
  );
 | 
						|
  is(
 | 
						|
    document.getElementById("kt_notreserved").getAttribute("count"),
 | 
						|
    "0",
 | 
						|
    "reserved='false' with preference on"
 | 
						|
  );
 | 
						|
  is(
 | 
						|
    document.getElementById("kt_reserveddefault").getAttribute("count"),
 | 
						|
    "1",
 | 
						|
    "default reserved with preference on"
 | 
						|
  );
 | 
						|
 | 
						|
  document.documentElement.removeChild(container);
 | 
						|
 | 
						|
  BrowserTestUtils.removeTab(tab);
 | 
						|
});
 | 
						|
 | 
						|
// This test checks that Alt+<key> and F10 cannot be blocked when the preference is set.
 | 
						|
if (!navigator.platform.includes("Mac")) {
 | 
						|
  add_task(async function test_accesskeys_menus() {
 | 
						|
    await new Promise(resolve => {
 | 
						|
      SpecialPowers.pushPrefEnv(
 | 
						|
        { set: [["permissions.default.shortcuts", 2]] },
 | 
						|
        resolve
 | 
						|
      );
 | 
						|
    });
 | 
						|
 | 
						|
    const uri =
 | 
						|
      'data:text/html,<body onkeydown=\'if (event.key == "H" || event.key == "F10") event.preventDefault();\'>';
 | 
						|
    let tab1 = await BrowserTestUtils.openNewForegroundTab(gBrowser, uri);
 | 
						|
 | 
						|
    // Pressing Alt+H should open the Help menu.
 | 
						|
    let helpPopup = document.getElementById("menu_HelpPopup");
 | 
						|
    let popupShown = BrowserTestUtils.waitForEvent(helpPopup, "popupshown");
 | 
						|
    EventUtils.synthesizeKey("KEY_Alt", { type: "keydown" });
 | 
						|
    EventUtils.synthesizeKey("h", { altKey: true });
 | 
						|
    EventUtils.synthesizeKey("KEY_Alt", { type: "keyup" });
 | 
						|
    await popupShown;
 | 
						|
 | 
						|
    ok(true, "Help menu opened");
 | 
						|
 | 
						|
    let popupHidden = BrowserTestUtils.waitForEvent(helpPopup, "popuphidden");
 | 
						|
    helpPopup.hidePopup();
 | 
						|
    await popupHidden;
 | 
						|
 | 
						|
    // Pressing F10 should focus the menubar. On Linux, the file menu should open, but on Windows,
 | 
						|
    // pressing Down will open the file menu.
 | 
						|
    let menubar = document.getElementById("main-menubar");
 | 
						|
    let menubarActive = BrowserTestUtils.waitForEvent(
 | 
						|
      menubar,
 | 
						|
      "DOMMenuBarActive"
 | 
						|
    );
 | 
						|
    EventUtils.synthesizeKey("KEY_F10");
 | 
						|
    await menubarActive;
 | 
						|
 | 
						|
    let filePopup = document.getElementById("menu_FilePopup");
 | 
						|
    popupShown = BrowserTestUtils.waitForEvent(filePopup, "popupshown");
 | 
						|
    if (navigator.platform.includes("Win")) {
 | 
						|
      EventUtils.synthesizeKey("KEY_ArrowDown");
 | 
						|
    }
 | 
						|
    await popupShown;
 | 
						|
 | 
						|
    ok(true, "File menu opened");
 | 
						|
 | 
						|
    popupHidden = BrowserTestUtils.waitForEvent(filePopup, "popuphidden");
 | 
						|
    filePopup.hidePopup();
 | 
						|
    await popupHidden;
 | 
						|
 | 
						|
    BrowserTestUtils.removeTab(tab1);
 | 
						|
  });
 | 
						|
}
 | 
						|
 | 
						|
// There is a <key> element for Backspace and delete with reserved="false",
 | 
						|
// so make sure that it is not treated as a blocked shortcut key.
 | 
						|
add_task(async function test_backspace_delete() {
 | 
						|
  await new Promise(resolve => {
 | 
						|
    SpecialPowers.pushPrefEnv(
 | 
						|
      { set: [["permissions.default.shortcuts", 2]] },
 | 
						|
      resolve
 | 
						|
    );
 | 
						|
  });
 | 
						|
 | 
						|
  // The input field is autofocused. If this test fails, backspace can go back
 | 
						|
  // in history so cancel the beforeunload event and adjust the field to make the test fail.
 | 
						|
  const uri =
 | 
						|
    'data:text/html,<body onbeforeunload=\'document.getElementById("field").value = "failed";\'>' +
 | 
						|
    "<input id='field' value='something'></body>";
 | 
						|
  let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, uri);
 | 
						|
 | 
						|
  await SpecialPowers.spawn(tab.linkedBrowser, [], async function () {
 | 
						|
    content.document.getElementById("field").focus();
 | 
						|
 | 
						|
    // Add a promise that resolves when the backspace key gets received
 | 
						|
    // so we can ensure the key gets received before checking the result.
 | 
						|
    content.keysPromise = new Promise(resolve => {
 | 
						|
      content.addEventListener("keyup", event => {
 | 
						|
        if (event.code == "Backspace") {
 | 
						|
          resolve(content.document.getElementById("field").value);
 | 
						|
        }
 | 
						|
      });
 | 
						|
    });
 | 
						|
  });
 | 
						|
 | 
						|
  // Move the caret so backspace will delete the first character.
 | 
						|
  EventUtils.synthesizeKey("KEY_ArrowRight", {});
 | 
						|
  EventUtils.synthesizeKey("KEY_Backspace", {});
 | 
						|
 | 
						|
  let fieldValue = await SpecialPowers.spawn(
 | 
						|
    tab.linkedBrowser,
 | 
						|
    [],
 | 
						|
    async function () {
 | 
						|
      return content.keysPromise;
 | 
						|
    }
 | 
						|
  );
 | 
						|
  is(fieldValue, "omething", "backspace not prevented");
 | 
						|
 | 
						|
  // now do the same thing for the delete key:
 | 
						|
  await SpecialPowers.spawn(tab.linkedBrowser, [], async function () {
 | 
						|
    content.document.getElementById("field").focus();
 | 
						|
 | 
						|
    // Add a promise that resolves when the backspace key gets received
 | 
						|
    // so we can ensure the key gets received before checking the result.
 | 
						|
    content.keysPromise = new Promise(resolve => {
 | 
						|
      content.addEventListener("keyup", event => {
 | 
						|
        if (event.code == "Delete") {
 | 
						|
          resolve(content.document.getElementById("field").value);
 | 
						|
        }
 | 
						|
      });
 | 
						|
    });
 | 
						|
  });
 | 
						|
 | 
						|
  // Move the caret so backspace will delete the first character.
 | 
						|
  EventUtils.synthesizeKey("KEY_Delete", {});
 | 
						|
 | 
						|
  fieldValue = await SpecialPowers.spawn(
 | 
						|
    tab.linkedBrowser,
 | 
						|
    [],
 | 
						|
    async function () {
 | 
						|
      return content.keysPromise;
 | 
						|
    }
 | 
						|
  );
 | 
						|
  is(fieldValue, "mething", "delete not prevented");
 | 
						|
 | 
						|
  BrowserTestUtils.removeTab(tab);
 | 
						|
});
 | 
						|
 | 
						|
// TODO: Make this to run on Windows too to have automated tests also there.
 | 
						|
if (
 | 
						|
  navigator.platform.includes("Mac") ||
 | 
						|
  navigator.platform.includes("Linux")
 | 
						|
) {
 | 
						|
  add_task(
 | 
						|
    async function test_reserved_shortcuts_conflict_with_user_settings() {
 | 
						|
      await new Promise(resolve => {
 | 
						|
        SpecialPowers.pushPrefEnv(
 | 
						|
          { set: [["test.events.async.enabled", true]] },
 | 
						|
          resolve
 | 
						|
        );
 | 
						|
      });
 | 
						|
 | 
						|
      const keyset = document.createXULElement("keyset");
 | 
						|
      const key = document.createXULElement("key");
 | 
						|
      key.setAttribute("id", "conflict_with_known_native_key_binding");
 | 
						|
      if (navigator.platform.includes("Mac")) {
 | 
						|
        // Select to end of the paragraph
 | 
						|
        key.setAttribute("modifiers", "ctrl,shift");
 | 
						|
        key.setAttribute("key", "E");
 | 
						|
      } else {
 | 
						|
        // Select All
 | 
						|
        key.setAttribute("modifiers", "ctrl");
 | 
						|
        key.setAttribute("key", "a");
 | 
						|
      }
 | 
						|
      key.setAttribute("reserved", "true");
 | 
						|
      key.setAttribute("count", "0");
 | 
						|
      key.addEventListener("command", () => {
 | 
						|
        const attribute = key.getAttribute("count");
 | 
						|
        key.setAttribute("count", Number(attribute) + 1);
 | 
						|
      });
 | 
						|
 | 
						|
      keyset.appendChild(key);
 | 
						|
      const container = document.createXULElement("box");
 | 
						|
      container.appendChild(keyset);
 | 
						|
      document.documentElement.appendChild(container);
 | 
						|
 | 
						|
      const pageUrl =
 | 
						|
        "data:text/html,<body onload='document.body.firstChild.focus(); getSelection().collapse(document.body.firstChild, 0)'><div contenteditable>Test</div></body>";
 | 
						|
      const tab = await BrowserTestUtils.openNewForegroundTab(
 | 
						|
        gBrowser,
 | 
						|
        pageUrl
 | 
						|
      );
 | 
						|
 | 
						|
      await SpecialPowers.spawn(
 | 
						|
        tab.linkedBrowser,
 | 
						|
        [key.getAttribute("key")],
 | 
						|
        async function (aExpectedKeyValue) {
 | 
						|
          content.promiseTestResult = new Promise(resolve => {
 | 
						|
            content.addEventListener("keyup", event => {
 | 
						|
              if (event.key.toLowerCase() == aExpectedKeyValue.toLowerCase()) {
 | 
						|
                resolve(content.getSelection().getRangeAt(0).toString());
 | 
						|
              }
 | 
						|
            });
 | 
						|
          });
 | 
						|
        }
 | 
						|
      );
 | 
						|
 | 
						|
      EventUtils.synthesizeKey(key.getAttribute("key"), {
 | 
						|
        ctrlKey: key.getAttribute("modifiers").includes("ctrl"),
 | 
						|
        shiftKey: key.getAttribute("modifiers").includes("shift"),
 | 
						|
      });
 | 
						|
 | 
						|
      const selectedText = await SpecialPowers.spawn(
 | 
						|
        tab.linkedBrowser,
 | 
						|
        [],
 | 
						|
        async function () {
 | 
						|
          return content.promiseTestResult;
 | 
						|
        }
 | 
						|
      );
 | 
						|
      is(
 | 
						|
        selectedText,
 | 
						|
        "Test",
 | 
						|
        "The shortcut key should select all text in the editor"
 | 
						|
      );
 | 
						|
 | 
						|
      is(
 | 
						|
        key.getAttribute("count"),
 | 
						|
        "0",
 | 
						|
        "The reserved shortcut key should be consumed by the focused editor instead"
 | 
						|
      );
 | 
						|
 | 
						|
      document.documentElement.removeChild(container);
 | 
						|
 | 
						|
      BrowserTestUtils.removeTab(tab);
 | 
						|
    }
 | 
						|
  );
 | 
						|
}
 |