/* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ "use strict"; const L10N = new LocalizationHelper( "devtools/client/locales/sourceeditor.properties" ); const { OS } = Services.appinfo; // On linux, getting immediately the selection's range here fails, returning const FIND_KEY = L10N.getStr("find.key"); const FINDNEXT_KEY = L10N.getStr("findNext.key"); const FINDPREV_KEY = L10N.getStr("findPrev.key"); // the replace's key with the appropriate modifiers based on OS const REPLACE_KEY = OS == "Darwin" ? L10N.getStr("replaceAllMac.key") : L10N.getStr("replaceAll.key"); // values like it's not selected – even if the selection is visible. // For the record, setting the selection's range immediately doesn't have // any effect. // It's like the is not ready yet. // Therefore, we trigger the UI focus event to the , waiting for the // response. // Using a timeout could also work, but that is more precise, ensuring also // the execution of the listeners added to the 's focus. const dispatchAndWaitForFocus = target => new Promise(resolve => { target.addEventListener( "focus", function () { resolve(target); }, { once: true } ); target.dispatchEvent(new UIEvent("focus")); }); function openSearchBox(ed) { const edDoc = ed.container.contentDocument; const edWin = edDoc.defaultView; let input = edDoc.querySelector("input[type=search]"); ok(!input, "search box closed"); // The editor needs the focus to properly receive the `synthesizeKey` ed.focus(); synthesizeKeyShortcut(FINDNEXT_KEY, edWin); input = edDoc.querySelector("input[type=search]"); ok(input, "find again command key opens the search box"); } function testFindAgain(ed, inputLine, expectCursor, isFindPrev = false) { const edDoc = ed.container.contentDocument; const edWin = edDoc.defaultView; const input = edDoc.querySelector("input[type=search]"); input.value = inputLine; // Ensure the input has the focus before send the key – necessary on Linux, // it seems that during the tests can be lost input.focus(); if (isFindPrev) { synthesizeKeyShortcut(FINDPREV_KEY, edWin); } else { synthesizeKeyShortcut(FINDNEXT_KEY, edWin); } ch( ed.getCursor(), expectCursor, "find: " + inputLine + " expects cursor: " + expectCursor.toSource() ); } const testSearchBoxTextIsSelected = async function (ed) { const edDoc = ed.container.contentDocument; const edWin = edDoc.defaultView; let input = edDoc.querySelector("input[type=search]"); ok(input, "search box is opened"); // Ensure the input has the focus before send the key – necessary on Linux, // it seems that during the tests can be lost input.focus(); // Close search box EventUtils.synthesizeKey("VK_ESCAPE", {}, edWin); input = edDoc.querySelector("input[type=search]"); ok(!input, "search box is closed"); // Re-open the search box synthesizeKeyShortcut(FIND_KEY, edWin); input = edDoc.querySelector("input[type=search]"); ok(input, "find command key opens the search box"); await dispatchAndWaitForFocus(input); let { selectionStart, selectionEnd, value } = input; ok( selectionStart === 0 && selectionEnd === value.length, "search box's text is selected when re-opened" ); // Removing selection input.setSelectionRange(0, 0); synthesizeKeyShortcut(FIND_KEY, edWin); ({ selectionStart, selectionEnd } = input); ok( selectionStart === 0 && selectionEnd === value.length, "search box's text is selected when find key is pressed" ); // Close search box EventUtils.synthesizeKey("VK_ESCAPE", {}, edWin); }; const testReplaceBoxTextIsSelected = async function (ed) { const edDoc = ed.container.contentDocument; const edWin = edDoc.defaultView; let input = edDoc.querySelector(".CodeMirror-dialog > input"); ok(!input, "dialog box with replace is closed"); // The editor needs the focus to properly receive the `synthesizeKey` ed.focus(); synthesizeKeyShortcut(REPLACE_KEY, edWin); input = edDoc.querySelector(".CodeMirror-dialog > input"); ok(input, "dialog box with replace is opened"); input.value = "line 5"; // Ensure the input has the focus before send the key – necessary on Linux, // it seems that during the tests can be lost input.focus(); await dispatchAndWaitForFocus(input); let { selectionStart, selectionEnd, value } = input; ok( !(selectionStart === 0 && selectionEnd === value.length), "Text in dialog box is not selected" ); synthesizeKeyShortcut(REPLACE_KEY, edWin); ({ selectionStart, selectionEnd } = input); ok( selectionStart === 0 && selectionEnd === value.length, "dialog box's text is selected when replace key is pressed" ); // Close dialog box EventUtils.synthesizeKey("VK_ESCAPE", {}, edWin); }; add_task(async function () { const { ed, win } = await setup(); ed.setText( [ "// line 1", "// line 2", "// line 3", "// line 4", "// line 5", ].join("\n") ); await promiseWaitForFocus(); openSearchBox(ed); const testVectors = [ // Starting here expect data needs to get updated for length changes to // "textLines" above. ["line", { line: 0, ch: 7 }], ["line", { line: 1, ch: 8 }], ["line", { line: 2, ch: 9 }], ["line", { line: 3, ch: 10 }], ["line", { line: 4, ch: 11 }], ["ne 3", { line: 2, ch: 11 }], ["line 1", { line: 0, ch: 9 }], // Testing find prev ["line", { line: 4, ch: 11 }, true], ["line", { line: 3, ch: 10 }, true], ["line", { line: 2, ch: 9 }, true], ["line", { line: 1, ch: 8 }, true], ["line", { line: 0, ch: 7 }, true], ]; for (const v of testVectors) { await testFindAgain(ed, ...v); } await testSearchBoxTextIsSelected(ed); await testReplaceBoxTextIsSelected(ed); teardown(ed, win); });