<?xml version="1.0"?> <!-- This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> <?xml-stylesheet href="chrome://global/skin" type="text/css"?> <?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?> <window id="FindbarTest" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" width="600" height="600" onload="onLoad();" title="findbar test"> <script src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/> <script type="application/javascript"><![CDATA[ const {AppConstants} = ChromeUtils.import("resource://gre/modules/AppConstants.jsm"); const {BrowserTestUtils} = ChromeUtils.import("resource://testing-common/BrowserTestUtils.jsm"); const SAMPLE_URL = "http://www.mozilla.org/"; const SAMPLE_TEXT = "Some text in a text field."; const SEARCH_TEXT = "Text Test (δοκιμή)"; const NOT_FOUND_TEXT = "This text is not on the page." const ITERATOR_TIMEOUT = Services.prefs.getIntPref("findbar.iteratorTimeout"); var gFindBar = null; var gBrowser; var gHasFindClipboard = Services.clipboard.isClipboardTypeSupported(Services.clipboard.kFindClipboard); var gStatusText; var gXULBrowserWindow = { QueryInterface: ChromeUtils.generateQI(["nsIXULBrowserWindow"]), setOverLink(aStatusText) { gStatusText = aStatusText; }, onBeforeLinkTraversal() { } }; var SimpleTest = window.arguments[0].SimpleTest; var ok = window.arguments[0].ok; var is = window.arguments[0].is; var info = window.arguments[0].info; SimpleTest.requestLongerTimeout(2); function onLoad() { (async function() { window.docShell .treeOwner .QueryInterface(Ci.nsIInterfaceRequestor) .getInterface(Ci.nsIAppWindow) .XULBrowserWindow = gXULBrowserWindow; gFindBar = document.getElementById("FindToolbar"); for (let browserId of ["content", "content-remote"]) { await startTestWithBrowser(browserId); } })().then(() => { window.close(); SimpleTest.finish(); }); } async function startTestWithBrowser(browserId) { info("Starting test with browser '" + browserId + "'"); gBrowser = document.getElementById(browserId); // Tests delays the loading of a document for one second. await new Promise(resolve => setTimeout(resolve, 1000)); let promise = BrowserTestUtils.browserLoaded(gBrowser); BrowserTestUtils.loadURIString(gBrowser, "data:text/html;charset=utf-8,<h2 id='h2'>" + SEARCH_TEXT + "</h2><h2><a href='" + SAMPLE_URL + "'>Link Test</a></h2><input id='text' type='text' value='" + SAMPLE_TEXT + "'></input><input id='button' type='button'></input><img id='img' width='50' height='50'/>", { triggeringPrincipal: window.document.nodePrincipal }); await promise; gFindBar.browser = gBrowser; await onDocumentLoaded(); } async function onDocumentLoaded() { await testNormalFind(); gFindBar.close(); ok(gFindBar.hidden, "Failed to close findbar after testNormalFind"); await openFindbar(); await testNormalFindWithComposition(); gFindBar.close(); ok(gFindBar.hidden, "findbar should be hidden after testNormalFindWithComposition"); await openFindbar(); await testAutoCaseSensitivityUI(); await testQuickFindText(); gFindBar.close(); ok(gFindBar.hidden, "Failed to close findbar after testQuickFindText"); // TODO: `testFindWithHighlight` tests fastFind integrity, which can not // be accessed with RemoteFinder. We're skipping it for now. if (gFindBar._browser.finder._fastFind) { await testFindWithHighlight(); gFindBar.close(); ok(gFindBar.hidden, "Failed to close findbar after testFindWithHighlight"); } await testFindbarSelection(); ok(gFindBar.hidden, "Failed to close findbar after testFindbarSelection"); // TODO: I don't know how to drop a content element on a chrome input. if (!gBrowser.hasAttribute("remote")) testDrop(); await testQuickFindLink(); if (gHasFindClipboard) { await testStatusText(); } if (!AppConstants.DEBUG) { await testFindCountUI(); gFindBar.close(); ok(gFindBar.hidden, "Failed to close findbar after testFindCountUI"); await testFindCountUI(true); gFindBar.close(); ok(gFindBar.hidden, "Failed to close findbar after testFindCountUI - linksOnly"); } await openFindbar(); await testFindAfterCaseChanged(); gFindBar.close(); await openFindbar(); await testFailedStringReset(); gFindBar.close(); await testQuickFindClose(); // TODO: This doesn't seem to work when the findbar is connected to a // remote browser element. if (!gBrowser.hasAttribute("remote")) await testFindAgainNotFound(); await testToggleEntireWord(); } async function testFindbarSelection() { function checkFindbarState(aTestName, aExpSelection) { ok(!gFindBar.hidden, "testFindbarSelection: failed to open findbar: " + aTestName); ok(document.commandDispatcher.focusedElement == gFindBar._findField, "testFindbarSelection: find field is not focused: " + aTestName); if (!gHasFindClipboard) { ok(gFindBar._findField.value == aExpSelection, "Incorrect selection in testFindbarSelection: " + aTestName + ". Selection: " + gFindBar._findField.value); } // Clear the value, close the findbar. gFindBar._findField.value = ""; gFindBar.close(); } // Test normal selected text. await SpecialPowers.spawn(gBrowser, [], async function() { let document = content.document; let cH2 = document.getElementById("h2"); let cSelection = content.getSelection(); let cRange = document.createRange(); cRange.setStart(cH2, 0); cRange.setEnd(cH2, 1); cSelection.removeAllRanges(); cSelection.addRange(cRange); }); await openFindbar(); checkFindbarState("plain text", SEARCH_TEXT); // Test editable element with selection. await SpecialPowers.spawn(gBrowser, [], async function() { let textInput = content.document.getElementById("text"); textInput.focus(); textInput.select(); }); await openFindbar(); checkFindbarState("text input", SAMPLE_TEXT); // Test non-editable input element (type="button"). await SpecialPowers.spawn(gBrowser, [], async function() { content.document.getElementById("button").focus(); }); await openFindbar(); checkFindbarState("button", ""); } function testDrop() { gFindBar.open(); // use an dummy image to start the drag so it doesn't get interrupted by a selection var img = gBrowser.contentDocument.getElementById("img"); synthesizeDrop(img, gFindBar._findField, [[ {type: "text/plain", data: "Rabbits" } ]], "copy", window); is(gFindBar._findField.value, "Rabbits", "drop on findbar"); gFindBar.close(); } function testQuickFindClose() { return new Promise(resolve => { var _isClosedCallback = function() { ok(gFindBar.hidden, "_isClosedCallback: Failed to auto-close quick find bar after " + gFindBar._quickFindTimeoutLength + "ms"); resolve(); }; setTimeout(_isClosedCallback, gFindBar._quickFindTimeoutLength + 100); }); } function testStatusText() { return new Promise(resolve => { var _delayedCheckStatusText = function() { ok(gStatusText == SAMPLE_URL, "testStatusText: Failed to set status text of found link"); resolve(); }; setTimeout(_delayedCheckStatusText, 100); }); } function promiseFindResult(expectedString) { return new Promise(resolve => { let listener = { onFindResult(result) { if (expectedString && result.searchString != expectedString) { return; } gFindBar.browser.finder.removeResultListener(listener); resolve(result); }, }; gFindBar.browser.finder.addResultListener(listener); }); } function promiseMatchesCountResult(expectedString) { return new Promise(resolve => { let listener = { onMatchesCountResult(result) { if (expectedString && result.searchString != expectedString) return; gFindBar.browser.finder.removeResultListener(listener); resolve(); }, }; gFindBar.browser.finder.addResultListener(listener); // Make sure we resolve _at least_ after five times the find iterator timeout. setTimeout(resolve, (ITERATOR_TIMEOUT * 5) + 20); }); } function promiseHighlightFinished(expectedString) { return new Promise(resolve => { let listener = { onHighlightFinished(result) { if (expectedString && result.searchString != expectedString) return; gFindBar.browser.finder.removeResultListener(listener); resolve(); } }; gFindBar.browser.finder.addResultListener(listener); }); } var enterStringIntoFindField = async function(str, waitForResult = true) { for (let promise, i = 0; i < str.length; i++) { if (waitForResult) { promise = promiseFindResult(); } let event = new KeyboardEvent("keypress", { bubbles: true, cancelable: true, view: null, keyCode: 0, charCode: str.charCodeAt(i), }); gFindBar._findField.dispatchEvent(event); if (waitForResult) { await promise; } } }; function promiseExpectRangeCount(rangeCount) { return SpecialPowers.spawn(gBrowser, [{ rangeCount }], async function(args) { let controller = docShell.QueryInterface(Ci.nsIInterfaceRequestor) .getInterface(Ci.nsISelectionDisplay) .QueryInterface(Ci.nsISelectionController); let sel = controller.getSelection(Ci.nsISelectionController.SELECTION_FIND); Assert.equal(sel.rangeCount, args.rangeCount, "Expected the correct amount of ranges inside the Find selection"); }); } // also test match-case async function testNormalFind() { document.getElementById("cmd_find").doCommand(); ok(!gFindBar.hidden, "testNormalFind: failed to open findbar"); ok(document.commandDispatcher.focusedElement == gFindBar._findField, "testNormalFind: find field is not focused"); let promise; let matchCaseCheckbox = gFindBar.getElement("find-case-sensitive"); if (!matchCaseCheckbox.hidden && matchCaseCheckbox.checked) { promise = promiseFindResult(); matchCaseCheckbox.click(); await promise; } var searchStr = "text tes"; await enterStringIntoFindField(searchStr); let sel = await SpecialPowers.spawn(gBrowser, [{ searchStr }], async function(args) { let sel = content.getSelection().toString(); Assert.equal(sel.toLowerCase(), args.searchStr, "testNormalFind: failed to find '" + args.searchStr + "'"); return sel; }); testClipboardSearchString(sel); if (!matchCaseCheckbox.hidden) { promise = promiseFindResult(); matchCaseCheckbox.click(); await promise; enterStringIntoFindField("t"); await SpecialPowers.spawn(gBrowser, [{ searchStr }], async function(args) { Assert.notEqual(content.getSelection().toString(), args.searchStr, "testNormalFind: Case-sensitivy is broken '" + args.searchStr + "'"); }); promise = promiseFindResult(); matchCaseCheckbox.click(); await promise; } } function openFindbar() { document.getElementById("cmd_find").doCommand(); return gFindBar._startFindDeferred && gFindBar._startFindDeferred.promise; } async function testNormalFindWithComposition() { ok(!gFindBar.hidden, "testNormalFindWithComposition: findbar should be open"); ok(document.commandDispatcher.focusedElement == gFindBar._findField, "testNormalFindWithComposition: find field should be focused"); var matchCaseCheckbox = gFindBar.getElement("find-case-sensitive"); var clicked = false; if (!matchCaseCheckbox.hidden & matchCaseCheckbox.checked) { matchCaseCheckbox.click(); clicked = true; } gFindBar._findField.focus(); var searchStr = "text"; synthesizeCompositionChange( { "composition": { "string": searchStr, "clauses": [ { "length": searchStr.length, "attr": COMPOSITION_ATTR_RAW_CLAUSE } ] }, "caret": { "start": searchStr.length, "length": 0 } }); await SpecialPowers.spawn(gBrowser, [{ searchStr }], async function(args) { Assert.notEqual(content.getSelection().toString().toLowerCase(), args.searchStr, "testNormalFindWithComposition: text shouldn't be found during composition"); }); synthesizeComposition({ type: "compositioncommitasis" }); let sel = await SpecialPowers.spawn(gBrowser, [{ searchStr }], async function(args) { let sel = content.getSelection().toString(); Assert.equal(sel.toLowerCase(), args.searchStr, "testNormalFindWithComposition: text should be found after committing composition"); return sel; }); testClipboardSearchString(sel); if (clicked) { matchCaseCheckbox.click(); } } async function testAutoCaseSensitivityUI() { var matchCaseCheckbox = gFindBar.getElement("find-case-sensitive"); var matchCaseLabel = gFindBar.getElement("match-case-status"); ok(!matchCaseCheckbox.hidden, "match case box is hidden in manual mode"); ok(matchCaseLabel.hidden, "match case label is visible in manual mode"); await changeCase(2); ok(matchCaseCheckbox.hidden, "match case box is visible in automatic mode"); ok(!matchCaseLabel.hidden, "match case label is hidden in automatic mode"); await enterStringIntoFindField("a"); ok(matchCaseLabel.hidden, "match case label is hidden in automatic mode with lower-case input"); await enterStringIntoFindField("A"); ok(!matchCaseLabel.hidden, "match case label is visible in automatic mode with upper-case input"); // bug 365551 gFindBar.onFindAgainCommand(); ok(matchCaseCheckbox.hidden && !matchCaseLabel.hidden, "bug 365551: case sensitivity UI is broken after find-again"); await changeCase(0); gFindBar.close(); } async function clearFocus() { document.commandDispatcher.focusedElement = null; document.commandDispatcher.focusedWindow = null; await SpecialPowers.spawn(gBrowser, [], async function() { content.focus(); }); } async function testQuickFindLink() { await clearFocus(); await SpecialPowers.spawn(gBrowser, [], async function() { let event = new content.window.KeyboardEvent("keypress", { bubbles: true, cancelable: true, view: null, keyCode: 0, charCode: "'".charCodeAt(0), }); content.document.documentElement.dispatchEvent(event); }); ok(!gFindBar.hidden, "testQuickFindLink: failed to open findbar"); ok(document.commandDispatcher.focusedElement == gFindBar._findField, "testQuickFindLink: find field is not focused"); var searchStr = "Link Test"; await enterStringIntoFindField(searchStr); await SpecialPowers.spawn(gBrowser, [{ searchStr }], async function(args) { Assert.equal(content.getSelection().toString(), args.searchStr, "testQuickFindLink: failed to find sample link"); }); testClipboardSearchString(searchStr); } // See bug 963925 for more details on this test. async function testFindWithHighlight() { gFindBar._findField.value = ""; // For this test, we want to closely control the selection. The easiest // way to do so is to replace the implementation of // Finder.getInitialSelection with a no-op and call the findbar's callback // (onCurrentSelection(..., true)) ourselves with our hand-picked // selection. let oldGetInitialSelection = gFindBar.browser.finder.getInitialSelection; let searchStr; gFindBar.browser.finder.getInitialSelection = function(){}; let findCommand = document.getElementById("cmd_find"); findCommand.doCommand(); gFindBar.onCurrentSelection("", true); searchStr = "e"; await enterStringIntoFindField(searchStr); let a = gFindBar._findField.value; let b = gFindBar._browser.finder._fastFind.searchString; let c = gFindBar._browser.finder.searchString; ok(a == b && b == c, "testFindWithHighlight 1: " + a + ", " + b + ", " + c + "."); searchStr = "t"; findCommand.doCommand(); gFindBar.onCurrentSelection(searchStr, true); gFindBar.browser.finder.getInitialSelection = oldGetInitialSelection; a = gFindBar._findField.value; b = gFindBar._browser.finder._fastFind.searchString; c = gFindBar._browser.finder.searchString; ok(a == searchStr && b == c, "testFindWithHighlight 2: " + searchStr + ", " + a + ", " + b + ", " + c + "."); let highlightButton = gFindBar.getElement("highlight"); highlightButton.click(); ok(highlightButton.checked, "testFindWithHighlight 3: Highlight All should be checked."); a = gFindBar._findField.value; b = gFindBar._browser.finder._fastFind.searchString; c = gFindBar._browser.finder.searchString; ok(a == searchStr && b == c, "testFindWithHighlight 4: " + a + ", " + b + ", " + c + "."); gFindBar.onFindAgainCommand(); a = gFindBar._findField.value; b = gFindBar._browser.finder._fastFind.searchString; c = gFindBar._browser.finder.searchString; ok(a == b && b == c, "testFindWithHighlight 5: " + a + ", " + b + ", " + c + "."); highlightButton.click(); ok(!highlightButton.checked, "testFindWithHighlight: Highlight All should be unchecked."); // Regression test for bug 1316515. searchStr = "e"; gFindBar.clear(); await enterStringIntoFindField(searchStr); await promiseExpectRangeCount(0); highlightButton.click(); ok(highlightButton.checked, "testFindWithHighlight: Highlight All should be checked."); await promiseHighlightFinished(searchStr); await promiseExpectRangeCount(3); synthesizeKey("KEY_Backspace"); await promiseExpectRangeCount(0); // Regression test for bug 1316513. highlightButton.click(); ok(!highlightButton.checked, "testFindWithHighlight - 1316513: Highlight All should be unchecked."); await enterStringIntoFindField(searchStr); highlightButton.click(); ok(highlightButton.checked, "testFindWithHighlight - 1316513: Highlight All should be checked."); await promiseHighlightFinished(searchStr); await promiseExpectRangeCount(3); let promise = BrowserTestUtils.browserLoaded(gBrowser); gBrowser.reload(); await promise; ok(highlightButton.checked, "testFindWithHighlight - 1316513: Highlight All " + "should still be checked after a reload."); synthesizeKey("KEY_Enter"); await promiseHighlightFinished(searchStr); await promiseExpectRangeCount(3); // Uncheck at test end to not interfere with other test functions that are // run after this one. highlightButton.click(); } async function testQuickFindText() { await clearFocus(); await SpecialPowers.spawn(gBrowser, [], async function() { let event = new content.window.KeyboardEvent("keypress", { bubbles: true, cancelable: true, view: null, keyCode: 0, charCode: "/".charCodeAt(0), }); content.document.documentElement.dispatchEvent(event); }); ok(!gFindBar.hidden, "testQuickFindText: failed to open findbar"); ok(document.commandDispatcher.focusedElement == gFindBar._findField, "testQuickFindText: find field is not focused"); await enterStringIntoFindField(SEARCH_TEXT); await SpecialPowers.spawn(gBrowser, [{ SEARCH_TEXT }], async function(args) { Assert.equal(content.getSelection().toString(), args.SEARCH_TEXT, "testQuickFindText: failed to find '" + args.SEARCH_TEXT + "'"); }); testClipboardSearchString(SEARCH_TEXT); } async function testFindCountUI(linksOnly = false) { await clearFocus(); if (linksOnly) { await SpecialPowers.spawn(gBrowser, [], async function() { let event = new content.window.KeyboardEvent("keypress", { bubbles: true, cancelable: true, view: null, keyCode: 0, charCode: "'".charCodeAt(0), }); content.document.documentElement.dispatchEvent(event); }); } else { document.getElementById("cmd_find").doCommand(); } ok(!gFindBar.hidden, "testFindCountUI: failed to open findbar"); ok(document.commandDispatcher.focusedElement == gFindBar._findField, "testFindCountUI: find field is not focused"); let promise; let matchCase = gFindBar.getElement("find-case-sensitive"); if (matchCase.checked) { promise = promiseFindResult(); matchCase.click(); await new Promise(resolve => setTimeout(resolve, ITERATOR_TIMEOUT + 20)); await promise; } let foundMatches = gFindBar._foundMatches; let tests = [{ text: "t", current: linksOnly ? 1 : 5, total: linksOnly ? 2 : 10, }, { text: "te", current: linksOnly ? 1 : 3, total: linksOnly ? 1 : 5, }, { text: "tes", current: 1, total: linksOnly ? 1 : 2, }, { text: "texxx", current: 0, total: 0 }]; function assertMatches(aTest) { const matches = JSON.parse(foundMatches.dataset.l10nArgs); is(matches.current, aTest.current, `${linksOnly ? "[Links-only] " : ""}Currently highlighted match should be at ${aTest.current} for '${aTest.text}'`); is(matches.total, aTest.total, `${linksOnly ? "[Links-only] " : ""}Total amount of matches should be ${aTest.total} for '${aTest.text}'`); } for (let test of tests) { gFindBar._findField.select(); gFindBar._findField.focus(); let timeout = ITERATOR_TIMEOUT; if (test.text.length == 1) timeout *= 4; else if (test.text.length == 2) timeout *= 2; timeout += 20; await new Promise(resolve => setTimeout(resolve, timeout)); await enterStringIntoFindField(test.text, false); await promiseMatchesCountResult(test.text); if (!test.total) { ok(!foundMatches.dataset.l10nId, "No message should be shown when 0 matches are expected"); } else { assertMatches(test); for (let i = 1; i < test.total; i++) { await new Promise(resolve => setTimeout(resolve, timeout)); gFindBar.onFindAgainCommand(); await promiseMatchesCountResult(test.text); // test.current + 1, test.current + 2, ..., test.total, 1, ..., test.current let current = (test.current + i - 1) % test.total + 1; assertMatches({ text: test.text, current, total: test.total }); } } } } // See bug 1051187. async function testFindAfterCaseChanged() { // Search to set focus on "Text Test" so that searching for "t" selects first // (upper case!) "T". await enterStringIntoFindField(SEARCH_TEXT); gFindBar.clear(); // Case-insensitive should already be the current value. Services.prefs.setIntPref("accessibility.typeaheadfind.casesensitive", 0); await enterStringIntoFindField("t"); await SpecialPowers.spawn(gBrowser, [], async function() { Assert.equal(content.getSelection().toString(), "T", "First T should be selected."); }); await changeCase(1); await SpecialPowers.spawn(gBrowser, [], async function() { Assert.equal(content.getSelection().toString(), "t", "First t should be selected."); }); } // Make sure that _findFailedString is cleared: // 1. Do a search that fails with case sensitivity but matches with no case sensitivity. // 2. Uncheck case sensitivity button to match the string. async function testFailedStringReset() { Services.prefs.setIntPref("accessibility.typeaheadfind.casesensitive", 1); let promise = promiseFindResult(gBrowser.hasAttribute("remote") ? SEARCH_TEXT.toUpperCase() : ""); await enterStringIntoFindField(SEARCH_TEXT.toUpperCase(), false); await promise; await SpecialPowers.spawn(gBrowser, [], async function() { Assert.equal(content.getSelection().toString(), "", "Not found."); }); await changeCase(0); await SpecialPowers.spawn(gBrowser, [{ SEARCH_TEXT }], async function(args) { Assert.equal(content.getSelection().toString(), args.SEARCH_TEXT, "Search text should be selected."); }); } function testClipboardSearchString(aExpected) { if (!gHasFindClipboard) return; if (!aExpected) aExpected = ""; var searchStr = gFindBar.browser.finder.clipboardSearchString; ok(searchStr.toLowerCase() == aExpected.toLowerCase(), "testClipboardSearchString: search string not set to '" + aExpected + "', instead found '" + searchStr + "'"); } // See bug 967982. async function testFindAgainNotFound() { await openFindbar(); await enterStringIntoFindField(NOT_FOUND_TEXT, false); gFindBar.close(); ok(gFindBar.hidden, "The findbar is closed."); let promise = promiseFindResult(); gFindBar.onFindAgainCommand(); await promise; ok(!gFindBar.hidden, "Unsuccessful Find Again opens the find bar."); await enterStringIntoFindField(SEARCH_TEXT); gFindBar.close(); ok(gFindBar.hidden, "The findbar is closed."); promise = promiseFindResult(); gFindBar.onFindAgainCommand(); await promise; ok(gFindBar.hidden, "Successful Find Again leaves the find bar closed."); } async function testToggleDiacriticMatching() { await openFindbar(); let promise = promiseFindResult(); await enterStringIntoFindField("δοκιμη", false); let result = await promise; is(result.result, Ci.nsITypeAheadFind.FIND_FOUND, "Text should be found"); await new Promise(resolve => setTimeout(resolve, ITERATOR_TIMEOUT + 20)); promise = promiseFindResult(); let check = gFindBar.getElement("find-match-diacritics"); check.click(); result = await promise; is(result.result, Ci.nsITypeAheadFind.FIND_NOTFOUND, "Text should NOT be found"); check.click(); gFindBar.close(true); } async function testToggleEntireWord() { await openFindbar(); let promise = promiseFindResult(); await enterStringIntoFindField("Tex", false); let result = await promise; is(result.result, Ci.nsITypeAheadFind.FIND_FOUND, "Text should be found"); await new Promise(resolve => setTimeout(resolve, ITERATOR_TIMEOUT + 20)); promise = promiseFindResult(); let check = gFindBar.getElement("find-entire-word"); check.click(); result = await promise; is(result.result, Ci.nsITypeAheadFind.FIND_NOTFOUND, "Text should NOT be found"); check.click(); gFindBar.close(true); } function changeCase(value) { let promise = gBrowser.hasAttribute("remote") ? promiseFindResult() : Promise.resolve(); Services.prefs.setIntPref("accessibility.typeaheadfind.casesensitive", value); return promise; } ]]></script> <commandset> <command id="cmd_find" oncommand="document.getElementById('FindToolbar').onFindCommand();"/> </commandset> <browser type="content" primary="true" flex="1" id="content" messagemanagergroup="test" src="about:blank"/> <browser type="content" primary="true" flex="1" id="content-remote" remote="true" messagemanagergroup="test" src="about:blank"/> <findbar id="FindToolbar" browserid="content"/> </window>