/* eslint-disable mozilla/no-arbitrary-setTimeout */ function testExpected(expected, msg) { is( document.getElementById("context-openlinkincurrent").hidden, expected, msg ); } function testLinkExpected(expected, msg) { is(gContextMenu.linkURL, expected, msg); } add_task(async function () { const url = "data:text/html;charset=UTF-8,Test For Non-Hyperlinked url selection"; await BrowserTestUtils.openNewForegroundTab(gBrowser, url); await SimpleTest.promiseFocus(gBrowser.selectedBrowser); // Initial setup of the content area. await SpecialPowers.spawn(gBrowser.selectedBrowser, [], async function (arg) { let doc = content.document; let range = doc.createRange(); let selection = content.getSelection(); let mainDiv = doc.createElement("div"); let div = doc.createElement("div"); let div2 = doc.createElement("div"); let span1 = doc.createElement("span"); let span2 = doc.createElement("span"); let span3 = doc.createElement("span"); let span4 = doc.createElement("span"); let p1 = doc.createElement("p"); let p2 = doc.createElement("p"); // eslint-disable-next-line @microsoft/sdl/no-insecure-url span1.textContent = "http://index."; span2.textContent = "example.com example.com"; span3.textContent = " - Test"; span4.innerHTML = "http://www.example.com/example"; p1.textContent = "mailto:test.com ftp.example.com"; p2.textContent = "example.com -"; div.appendChild(span1); div.appendChild(span2); div.appendChild(span3); div.appendChild(span4); div.appendChild(p1); div.appendChild(p2); let p3 = doc.createElement("p"); p3.textContent = "main.example.com"; div2.appendChild(p3); mainDiv.appendChild(div); mainDiv.appendChild(div2); doc.body.appendChild(mainDiv); function setSelection(el1, el2, index1, index2) { while (el1.nodeType != el1.TEXT_NODE) { el1 = el1.firstChild; } while (el2.nodeType != el1.TEXT_NODE) { el2 = el2.firstChild; } selection.removeAllRanges(); range.setStart(el1, index1); range.setEnd(el2, index2); selection.addRange(range); return range; } // Each of these tests creates a selection and returns a range within it. content.tests = [ () => setSelection(span1.firstChild, span2.firstChild, 0, 11), () => setSelection(span1.firstChild, span2.firstChild, 7, 11), () => setSelection(span1.firstChild, span2.firstChild, 8, 11), () => setSelection(span2.firstChild, span2.firstChild, 0, 11), () => setSelection(span2.firstChild, span2.firstChild, 11, 23), () => setSelection(span2.firstChild, span2.firstChild, 0, 10), () => setSelection(span2.firstChild, span3.firstChild, 12, 7), () => setSelection(span2.firstChild, span2.firstChild, 12, 19), () => setSelection(p1.firstChild, p1.firstChild, 0, 15), () => setSelection(p1.firstChild, p1.firstChild, 16, 31), () => setSelection(p2.firstChild, p2.firstChild, 0, 14), () => { selection.selectAllChildren(div2); return selection.getRangeAt(0); }, () => { selection.selectAllChildren(span4); return selection.getRangeAt(0); }, () => { mainDiv.innerHTML = "(open-suse.ru)"; return setSelection(mainDiv, mainDiv, 1, 13); }, () => setSelection(mainDiv, mainDiv, 1, 14), ]; }); let checks = [ () => testExpected( false, "The link context menu should show for http://www.example.com" ), () => testExpected( false, "The link context menu should show for www.example.com" ), () => testExpected( true, "The link context menu should not show for ww.example.com" ), () => { testExpected(false, "The link context menu should show for example.com"); testLinkExpected( // eslint-disable-next-line @microsoft/sdl/no-insecure-url "http://example.com/", "url for example.com selection should not prepend www" ); }, () => testExpected(false, "The link context menu should show for example.com"), () => testExpected( true, "Link options should not show for selection that's not at a word boundary" ), () => testExpected( true, "Link options should not show for selection that has whitespace" ), () => testExpected( true, "Link options should not show unless a url is selected" ), () => testExpected(true, "Link options should not show for mailto: links"), () => { testExpected(false, "Link options should show for ftp.example.com"); testLinkExpected( // eslint-disable-next-line @microsoft/sdl/no-insecure-url "http://ftp.example.com/", "ftp.example.com should be preceeded with http://" ); }, () => testExpected(false, "Link options should show for www.example.com "), () => testExpected( false, "Link options should show for triple-click selections" ), () => testLinkExpected( // eslint-disable-next-line @microsoft/sdl/no-insecure-url "http://www.example.com/", "Linkified text should open the correct link" ), () => { testExpected(false, "Link options should show for open-suse.ru"); testLinkExpected( // eslint-disable-next-line @microsoft/sdl/no-insecure-url "http://open-suse.ru/", "Linkified text should open the correct link" ); }, () => testExpected(true, "Link options should not show for 'open-suse.ru)'"), ]; let contentAreaContextMenu = document.getElementById( "contentAreaContextMenu" ); for (let testid = 0; testid < checks.length; testid++) { let menuPosition = await SpecialPowers.spawn( gBrowser.selectedBrowser, [{ testid }], async function (arg) { let range = content.tests[arg.testid](); // Get the range of the selection and determine its coordinates. These // coordinates will be returned to the parent process and the context menu // will be opened at that location. let rangeRect = range.getBoundingClientRect(); return [rangeRect.x + 3, rangeRect.y + 3]; } ); // Trigger a mouse event until we receive the popupshown event. let sawPopup = false; let popupShownPromise = BrowserTestUtils.waitForEvent( contentAreaContextMenu, "popupshown", false, () => { sawPopup = true; return true; } ); while (!sawPopup) { await BrowserTestUtils.synthesizeMouseAtPoint( menuPosition[0], menuPosition[1], { type: "contextmenu", button: 2 }, gBrowser.selectedBrowser ); if (!sawPopup) { await new Promise(r => setTimeout(r, 100)); } } await popupShownPromise; checks[testid](); // On Linux non-e10s it's possible the menu was closed by a focus-out event // on the window. Work around this by calling hidePopup only if the menu // hasn't been closed yet. See bug 1352709 comment 36. if (contentAreaContextMenu.state === "closed") { continue; } let popupHiddenPromise = BrowserTestUtils.waitForEvent( contentAreaContextMenu, "popuphidden" ); contentAreaContextMenu.hidePopup(); await popupHiddenPromise; } gBrowser.removeCurrentTab(); });