Merge remote-tracking branch 'origin/master' into custom

This commit is contained in:
Roy Tam 2020-02-27 07:37:41 +08:00
commit 55828393ce
2798 changed files with 8839 additions and 257595 deletions

View file

@ -625,16 +625,6 @@ function copyContentsToClipboard() {
let clipboard = Cc["@mozilla.org/widget/clipboard;1"]
.getService(Ci.nsIClipboard);
clipboard.setData(transferable, null, clipboard.kGlobalClipboard);
#ifdef MOZ_WIDGET_ANDROID
// Present a toast notification.
let message = {
type: "Toast:Show",
message: stringBundle().GetStringFromName("textCopied"),
duration: "short"
};
Services.androidBridge.handleGeckoMessage(message);
#endif
}
// Return the plain text representation of an element. Do a little bit

View file

@ -101,7 +101,6 @@
<td id="buildid-box"></td>
</tr>
#ifndef ANDROID
#ifdef MOZ_UPDATER
<tr class="no-copy">
<th class="column">
@ -115,7 +114,6 @@
</td>
</tr>
#endif
#endif
#ifdef MOZ_UPDATER
<tr>
@ -249,7 +247,6 @@
</td>
</tr>
#ifndef ANDROID
<tr class="no-copy">
<th class="column">
&aboutSupport.appBasicsProfiles;
@ -259,8 +256,6 @@
<a href="about:profiles">about:profiles</a>
</td>
</tr>
#endif
</tbody>
</table>

View file

@ -233,17 +233,9 @@ var Settings = {
let elements = document.getElementsByClassName("change-data-choices-link");
for (let el of elements) {
el.addEventListener("click", function() {
#ifdef MOZ_WIDGET_ANDROID
Cu.import("resource://gre/modules/Messaging.jsm");
Messaging.sendRequest({
type: "Settings:Show",
resource: "preferences_privacy",
});
#else
// Show the data choices preferences on desktop.
let mainWindow = getMainWindowWithPreferencesPane();
mainWindow.openAdvancedPreferences("dataChoicesTab");
#endif
}, false);
}
},

View file

@ -58,9 +58,5 @@
</table>
<h2>Configure options</h2>
<p>@MOZ_CONFIGURE_OPTIONS@</p>
#ifdef ANDROID
<h2>Package name</h2>
<p>@ANDROID_PACKAGE_NAME@</p>
#endif
</body>
</html>

View file

@ -1115,40 +1115,8 @@ function validateFileName(aFileName)
aFileName = aFileName.replace(/[\<]+/g, "(");
aFileName = aFileName.replace(/[\>]+/g, ")");
}
else if (navigator.appVersion.indexOf("Macintosh") != -1)
else if (navigator.appVersion.indexOf("Macintosh") != -1) {
re = /[\:\/]+/g;
else if (navigator.appVersion.indexOf("Android") != -1) {
// On mobile devices, the filesystem may be very limited in what
// it considers valid characters. To avoid errors, we sanitize
// conservatively.
const dangerousChars = "*?<>|\":/\\[];,+=";
var processed = "";
for (var i = 0; i < aFileName.length; i++)
processed += aFileName.charCodeAt(i) >= 32 &&
!(dangerousChars.indexOf(aFileName[i]) >= 0) ? aFileName[i]
: "_";
// Last character should not be a space
processed = processed.trim();
// If a large part of the filename has been sanitized, then we
// will use a default filename instead
if (processed.replace(/_/g, "").length <= processed.length/2) {
// We purposefully do not use a localized default filename,
// which we could have done using
// ContentAreaUtils.stringBundle.GetStringFromName("DefaultSaveFileName")
// since it may contain invalid characters.
var original = processed;
processed = "download";
// Preserve a suffix, if there is one
if (original.indexOf(".") >= 0) {
var suffix = original.split(".").slice(-1)[0];
if (suffix && suffix.indexOf("_") < 0)
processed += "." + suffix;
}
}
return processed;
}
return aFileName.replace(re, "_");

View file

@ -19,10 +19,8 @@ toolkit.jar:
#endif
content/global/aboutNetworking.js
content/global/aboutNetworking.xhtml
#ifndef ANDROID
* content/global/aboutProfiles.js
content/global/aboutProfiles.xhtml
#endif
content/global/aboutServiceWorkers.js
content/global/aboutServiceWorkers.xhtml
#ifdef MOZ_WEBRTC

View file

@ -4,28 +4,19 @@
# 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/.
TEST_DIRS += ['tests']
for var in ('target', 'MOZ_CONFIGURE_OPTIONS', 'CC', 'CC_VERSION', 'CXX'):
for var in ('target',
'MOZ_CONFIGURE_OPTIONS',
'CC',
'CC_VERSION',
'CXX'):
DEFINES[var] = CONFIG[var]
DEFINES['CFLAGS'] = CONFIG['OS_CFLAGS']
if CONFIG['OS_TARGET'] == 'Android':
DEFINES['ANDROID_PACKAGE_NAME'] = CONFIG['ANDROID_PACKAGE_NAME']
DEFINES['TOPOBJDIR'] = TOPOBJDIR
if CONFIG['MOZ_ANDROID_CXX_STL'] == 'libc++':
DEFINES['MOZ_USE_LIBCXX'] = True
JAR_MANIFESTS += ['jar.mn']
with Files('aboutTelemetry.*'):
BUG_COMPONENT = ('Toolkit', 'Telemetry')
with Files('customizeToolbar.*'):
BUG_COMPONENT = ('Toolkit', 'Toolbars and Toolbar Customization')
with Files('widgets/*'):
BUG_COMPONENT = ('Toolkit', 'XUL Widgets')
DEFINES['TOPOBJDIR'] = TOPOBJDIR

View file

@ -1,7 +0,0 @@
"use strict";
module.exports = {
"extends": [
"../../../../testing/mochitest/browser.eslintrc.js"
]
};

View file

@ -1,76 +0,0 @@
[DEFAULT]
support-files =
head.js
file_contentTitle.html
audio.ogg
[browser_audioCompeting.js]
tags = audiochannel
support-files =
file_multipleAudio.html
[browser_audioCompeting_onlyForActiveAgent.js]
tags = audiochannel
support-files =
file_multiplePlayingAudio.html
[browser_autoscroll_disabled.js]
[browser_block_autoplay_media.js]
tags = audiochannel
support-files =
file_multipleAudio.html
[browser_bug295977_autoscroll_overflow.js]
[browser_bug451286.js]
skip-if = !e10s
[browser_bug594509.js]
[browser_bug982298.js]
[browser_bug1198465.js]
[browser_contentTitle.js]
[browser_crash_previous_frameloader.js]
run-if = e10s && crashreporter
[browser_datetime_datepicker.js]
[browser_default_image_filename.js]
[browser_f7_caret_browsing.js]
[browser_findbar.js]
[browser_label_textlink.js]
[browser_isSynthetic.js]
support-files =
empty.png
[browser_keyevents_during_autoscrolling.js]
[browser_save_resend_postdata.js]
support-files =
common/mockTransfer.js
data/post_form_inner.sjs
data/post_form_outer.sjs
skip-if = e10s # Bug ?????? - test directly manipulates content (gBrowser.contentDocument.getElementById("postForm").submit();)
[browser_content_url_annotation.js]
skip-if = !e10s || !crashreporter
support-files =
file_redirect.html
file_redirect_to.html
[browser_bug1170531.js]
[browser_mediaPlayback.js]
tags = audiochannel
support-files =
file_mediaPlayback.html
file_mediaPlaybackFrame.html
[browser_mediaPlayback_mute.js]
tags = audiochannel
support-files =
file_mediaPlayback2.html
file_mediaPlaybackFrame2.html
[browser_mediaPlayback_suspended.js]
tags = audiochannel
support-files =
file_mediaPlayback2.html
[browser_mediaPlayback_suspended_multipleAudio.js]
tags = audiochannel
support-files =
file_multipleAudio.html
[browser_mute.js]
tags = audiochannel
[browser_mute2.js]
tags = audiochannel
[browser_quickfind_editable.js]
[browser_saveImageURL.js]
support-files =
image.jpg
image_page.html

View file

@ -1,115 +0,0 @@
const PAGE = "https://example.com/browser/toolkit/content/tests/browser/file_multipleAudio.html";
function* wait_for_tab_playing_event(tab, expectPlaying) {
if (tab.soundPlaying == expectPlaying) {
ok(true, "The tab should " + (expectPlaying ? "" : "not ") + "be playing");
} else {
yield BrowserTestUtils.waitForEvent(tab, "TabAttrModified", false, (event) => {
if (event.detail.changed.indexOf("soundplaying") >= 0) {
is(tab.soundPlaying, expectPlaying, "The tab should " + (expectPlaying ? "" : "not ") + "be playing");
return true;
}
return false;
});
}
}
function play_audio_from_invisible_tab () {
return new Promise(resolve => {
var autoPlay = content.document.getElementById('autoplay');
if (!autoPlay) {
ok(false, "Can't get the audio element!");
}
is(autoPlay.paused, true, "Audio in tab 1 was paused by audio competing.");
autoPlay.play();
autoPlay.onpause = function() {
autoPlay.onpause = null;
ok(true, "Audio in tab 1 can't playback when other tab is playing in foreground.");
resolve();
};
});
}
function audio_should_keep_playing_even_go_to_background () {
var autoPlay = content.document.getElementById('autoplay');
if (!autoPlay) {
ok(false, "Can't get the audio element!");
}
is(autoPlay.paused, false, "Audio in tab 2 is still playing in the background.");
}
function play_non_autoplay_audio () {
return new Promise(resolve => {
var autoPlay = content.document.getElementById('autoplay');
var nonAutoPlay = content.document.getElementById('nonautoplay');
if (!autoPlay || !nonAutoPlay) {
ok(false, "Can't get the audio element!");
}
is(nonAutoPlay.paused, true, "Non-autoplay audio isn't started playing yet.");
nonAutoPlay.play();
nonAutoPlay.onplay = function() {
nonAutoPlay.onplay = null;
is(nonAutoPlay.paused, false, "Start Non-autoplay audio.");
is(autoPlay.paused, false, "Autoplay audio is still playing.");
resolve();
};
});
}
add_task(function* setup_test_preference() {
yield new Promise(resolve => {
SpecialPowers.pushPrefEnv({"set": [
["dom.audiochannel.audioCompeting", true],
["dom.ipc.processCount", 1]
]}, resolve);
});
});
add_task(function* cross_tabs_audio_competing () {
info("- open tab 1 in foreground -");
let tab1 = yield BrowserTestUtils.openNewForegroundTab(window.gBrowser,
"about:blank");
tab1.linkedBrowser.loadURI(PAGE);
yield wait_for_tab_playing_event(tab1, true);
info("- open tab 2 in foreground -");
let tab2 = yield BrowserTestUtils.openNewForegroundTab(window.gBrowser,
"about:blank");
tab2.linkedBrowser.loadURI(PAGE);
yield wait_for_tab_playing_event(tab1, false);
info("- open tab 3 in foreground -");
let tab3 = yield BrowserTestUtils.openNewForegroundTab(window.gBrowser,
"about:blank");
yield ContentTask.spawn(tab2.linkedBrowser, null,
audio_should_keep_playing_even_go_to_background);
info("- play audio from background tab 1 -");
yield ContentTask.spawn(tab1.linkedBrowser, null,
play_audio_from_invisible_tab);
info("- remove tabs -");
yield BrowserTestUtils.removeTab(tab1);
yield BrowserTestUtils.removeTab(tab2);
yield BrowserTestUtils.removeTab(tab3);
});
add_task(function* within_one_tab_audio_competing () {
info("- open tab and play audio1 -");
let tab = yield BrowserTestUtils.openNewForegroundTab(window.gBrowser,
"about:blank");
tab.linkedBrowser.loadURI(PAGE);
yield wait_for_tab_playing_event(tab, true);
info("- play audio2 in the same tab -");
yield ContentTask.spawn(tab.linkedBrowser, null,
play_non_autoplay_audio);
info("- remove tab -");
yield BrowserTestUtils.removeTab(tab);
});

View file

@ -1,176 +0,0 @@
const PAGE = "https://example.com/browser/toolkit/content/tests/browser/file_multiplePlayingAudio.html";
var SuspendedType = {
NONE_SUSPENDED : 0,
SUSPENDED_PAUSE : 1,
SUSPENDED_BLOCK : 2,
SUSPENDED_PAUSE_DISPOSABLE : 3
};
function wait_for_event(browser, event) {
return BrowserTestUtils.waitForEvent(browser, event, false, (event) => {
is(event.originalTarget, browser, "Event must be dispatched to correct browser.");
return true;
});
}
function check_all_audio_suspended(suspendedType) {
var audio1 = content.document.getElementById("audio1");
var audio2 = content.document.getElementById("audio2");
if (!audio1 || !audio2) {
ok(false, "Can't get the audio element!");
}
is(audio1.computedSuspended, suspendedType,
"The suspeded state of audio1 is correct.");
is(audio2.computedSuspended, suspendedType,
"The suspeded state of audio2 is correct.");
}
function check_audio1_suspended(suspendedType) {
var audio1 = content.document.getElementById("audio1");
if (!audio1) {
ok(false, "Can't get the audio element!");
}
is(audio1.computedSuspended, suspendedType,
"The suspeded state of audio1 is correct.");
}
function check_audio2_suspended(suspendedType) {
var audio2 = content.document.getElementById("audio2");
if (!audio2) {
ok(false, "Can't get the audio element!");
}
is(audio2.computedSuspended, suspendedType,
"The suspeded state of audio2 is correct.");
}
function check_all_audio_pause_state(expectedPauseState) {
var audio1 = content.document.getElementById("audio1");
var audio2 = content.document.getElementById("audio2");
if (!audio1 | !audio2) {
ok(false, "Can't get the audio element!");
}
is(audio1.paused, expectedPauseState,
"The pause state of audio1 is correct.");
is(audio2.paused, expectedPauseState,
"The pause state of audio2 is correct.");
}
function check_audio1_pause_state(expectedPauseState) {
var audio1 = content.document.getElementById("audio1");
if (!audio1) {
ok(false, "Can't get the audio element!");
}
is(audio1.paused, expectedPauseState,
"The pause state of audio1 is correct.");
}
function check_audio2_pause_state(expectedPauseState) {
var audio2 = content.document.getElementById("audio2");
if (!audio2) {
ok(false, "Can't get the audio element!");
}
is(audio2.paused, expectedPauseState,
"The pause state of audio2 is correct.");
}
function play_audio1_from_page() {
var audio1 = content.document.getElementById("audio1");
if (!audio1) {
ok(false, "Can't get the audio element!");
}
is(audio1.paused, true, "Audio1 is paused.");
audio1.play();
return new Promise(resolve => {
audio1.onplay = function() {
audio1.onplay = null;
ok(true, "Audio1 started playing.");
resolve();
}
});
}
function stop_audio1_from_page() {
var audio1 = content.document.getElementById("audio1");
if (!audio1) {
ok(false, "Can't get the audio element!");
}
is(audio1.paused, false, "Audio1 is playing.");
audio1.pause();
return new Promise(resolve => {
audio1.onpause = function() {
audio1.onpause = null;
ok(true, "Audio1 stopped playing.");
resolve();
}
});
}
function* audio_competing_for_active_agent(url, browser) {
browser.loadURI(url);
info("- page should have playing audio -");
yield wait_for_event(browser, "DOMAudioPlaybackStarted");
info("- the default suspended state of all audio should be non-suspened -");
yield ContentTask.spawn(browser, SuspendedType.NONE_SUSPENDED,
check_all_audio_suspended);
info("- only pause playing audio in the page -");
browser.pauseMedia(true /* disposable */);
info("- page shouldn't have any playing audio -");
yield wait_for_event(browser, "DOMAudioPlaybackStopped");
yield ContentTask.spawn(browser, true /* expect for pause */,
check_all_audio_pause_state);
yield ContentTask.spawn(browser, SuspendedType.SUSPENDED_PAUSE_DISPOSABLE,
check_all_audio_suspended);
info("- resume audio1 from page -");
yield ContentTask.spawn(browser, null,
play_audio1_from_page);
yield ContentTask.spawn(browser, SuspendedType.NONE_SUSPENDED,
check_audio1_suspended);
info("- audio2 should still be suspended -");
yield ContentTask.spawn(browser, SuspendedType.SUSPENDED_PAUSE_DISPOSABLE,
check_audio2_suspended);
yield ContentTask.spawn(browser, true /* expect for pause */,
check_audio2_pause_state);
info("- stop audio1 from page -");
yield ContentTask.spawn(browser, null,
stop_audio1_from_page);
yield ContentTask.spawn(browser, SuspendedType.NONE_SUSPENDED,
check_audio1_suspended);
info("- audio2 should still be suspended -");
yield ContentTask.spawn(browser, SuspendedType.SUSPENDED_PAUSE_DISPOSABLE,
check_audio2_suspended);
yield ContentTask.spawn(browser, true /* expect for pause */,
check_audio2_pause_state);
}
add_task(function* setup_test_preference() {
yield SpecialPowers.pushPrefEnv({"set": [
["media.useAudioChannelService.testing", true],
["dom.audiochannel.audioCompeting", true],
["dom.audiochannel.audioCompeting.allAgents", true]
]});
});
add_task(function* test_suspended_pause_disposable() {
yield BrowserTestUtils.withNewTab({
gBrowser,
url: "about:blank"
}, audio_competing_for_active_agent.bind(this, PAGE));
});

View file

@ -1,67 +0,0 @@
add_task(function* ()
{
const kPrefName_AutoScroll = "general.autoScroll";
Services.prefs.setBoolPref(kPrefName_AutoScroll, false);
let dataUri = 'data:text/html,<html><body id="i" style="overflow-y: scroll"><div style="height: 2000px"></div>\
<iframe id="iframe" style="display: none;"></iframe>\
</body></html>';
let loadedPromise = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
gBrowser.loadURI(dataUri);
yield loadedPromise;
yield BrowserTestUtils.synthesizeMouse("#i", 50, 50, { button: 1 },
gBrowser.selectedBrowser);
yield ContentTask.spawn(gBrowser.selectedBrowser, { }, function* () {
var iframe = content.document.getElementById("iframe");
if (iframe) {
var e = new iframe.contentWindow.PageTransitionEvent("pagehide",
{ bubbles: true,
cancelable: true,
persisted: false });
iframe.contentDocument.dispatchEvent(e);
iframe.contentDocument.documentElement.dispatchEvent(e);
}
});
yield BrowserTestUtils.synthesizeMouse("#i", 100, 100,
{ type: "mousemove", clickCount: "0" },
gBrowser.selectedBrowser);
// If scrolling didn't work, we wouldn't do any redraws and thus time out, so
// request and force redraws to get the chance to check for scrolling at all.
yield new Promise(resolve => window.requestAnimationFrame(resolve));
let msg = yield ContentTask.spawn(gBrowser.selectedBrowser, { }, function* () {
// Skip the first animation frame callback as it's the same callback that
// the browser uses to kick off the scrolling.
return new Promise(resolve => {
function checkScroll() {
let msg = "";
let elem = content.document.getElementById('i');
if (elem.scrollTop != 0) {
msg += "element should not have scrolled vertically";
}
if (elem.scrollLeft != 0) {
msg += "element should not have scrolled horizontally";
}
resolve(msg);
}
content.requestAnimationFrame(checkScroll);
});
});
ok(!msg, "element scroll " + msg);
// restore the changed prefs
if (Services.prefs.prefHasUserValue(kPrefName_AutoScroll))
Services.prefs.clearUserPref(kPrefName_AutoScroll);
// wait for focus to fix a failure in the next test if the latter runs too soon.
yield SimpleTest.promiseFocus();
});

View file

@ -1,87 +0,0 @@
const PAGE = "https://example.com/browser/toolkit/content/tests/browser/file_multipleAudio.html";
var SuspendedType = {
NONE_SUSPENDED : 0,
SUSPENDED_PAUSE : 1,
SUSPENDED_BLOCK : 2,
SUSPENDED_PAUSE_DISPOSABLE : 3
};
function* wait_for_tab_playing_event(tab, expectPlaying) {
if (tab.soundPlaying == expectPlaying) {
ok(true, "The tab should " + (expectPlaying ? "" : "not ") + "be playing");
} else {
yield BrowserTestUtils.waitForEvent(tab, "TabAttrModified", false, (event) => {
if (event.detail.changed.indexOf("soundplaying") >= 0) {
is(tab.soundPlaying, expectPlaying, "The tab should " + (expectPlaying ? "" : "not ") + "be playing");
return true;
}
return false;
});
}
}
function check_audio_suspended(suspendedType) {
var autoPlay = content.document.getElementById('autoplay');
if (!autoPlay) {
ok(false, "Can't get the audio element!");
}
is(autoPlay.computedSuspended, suspendedType,
"The suspeded state of autoplay audio is correct.");
}
add_task(function* setup_test_preference() {
yield new Promise(resolve => {
SpecialPowers.pushPrefEnv({"set": [
["media.useAudioChannelService.testing", true],
["media.block-autoplay-until-in-foreground", true]
]}, resolve);
});
});
add_task(function* block_autoplay_media() {
info("- open new background tab1 -");
let tab1 = window.gBrowser.addTab("about:blank");
tab1.linkedBrowser.loadURI(PAGE);
yield BrowserTestUtils.browserLoaded(tab1.linkedBrowser);
info("- should block autoplay media for non-visited tab1 -");
yield ContentTask.spawn(tab1.linkedBrowser, SuspendedType.SUSPENDED_BLOCK,
check_audio_suspended);
info("- open new background tab2 -");
let tab2 = window.gBrowser.addTab("about:blank");
tab2.linkedBrowser.loadURI(PAGE);
yield BrowserTestUtils.browserLoaded(tab2.linkedBrowser);
info("- should block autoplay for non-visited tab2 -");
yield ContentTask.spawn(tab2.linkedBrowser, SuspendedType.SUSPENDED_BLOCK,
check_audio_suspended);
info("- select tab1 as foreground tab -");
yield BrowserTestUtils.switchTab(window.gBrowser, tab1);
info("- media should be unblocked because the tab was visited -");
yield wait_for_tab_playing_event(tab1, true);
yield ContentTask.spawn(tab1.linkedBrowser, SuspendedType.NONE_SUSPENDED,
check_audio_suspended);
info("- open another new foreground tab3 -");
let tab3 = yield BrowserTestUtils.openNewForegroundTab(window.gBrowser,
"about:blank");
info("- should still play media from tab1 -");
yield wait_for_tab_playing_event(tab1, true);
yield ContentTask.spawn(tab1.linkedBrowser, SuspendedType.NONE_SUSPENDED,
check_audio_suspended);
info("- should still block media from tab2 -");
yield wait_for_tab_playing_event(tab2, false);
yield ContentTask.spawn(tab2.linkedBrowser, SuspendedType.SUSPENDED_BLOCK,
check_audio_suspended);
info("- remove tabs -");
yield BrowserTestUtils.removeTab(tab1);
yield BrowserTestUtils.removeTab(tab2);
yield BrowserTestUtils.removeTab(tab3);
});

View file

@ -1,92 +0,0 @@
// Test for bug 1170531
// https://bugzilla.mozilla.org/show_bug.cgi?id=1170531
add_task(function* () {
// Get a bunch of DOM nodes
let winUtils = window.QueryInterface(Ci.nsIInterfaceRequestor).
getInterface(Ci.nsIDOMWindowUtils);
let editMenu = document.getElementById("edit-menu");
let menubar = editMenu.parentNode;
let menuPopup = editMenu.menupopup;
let editMenuIndex = -1;
for (let i = 0; i < menubar.children.length; i++) {
if (menubar.children[i] === editMenu) {
editMenuIndex = i;
break;
}
}
let closeMenu = function(aCallback) {
if (OS.Constants.Sys.Name == "Darwin") {
executeSoon(aCallback);
return;
}
menuPopup.addEventListener("popuphidden", function onPopupHidden() {
menuPopup.removeEventListener("popuphidden", onPopupHidden, false);
executeSoon(aCallback);
}, false);
executeSoon(function() {
editMenu.open = false;
});
};
let openMenu = function(aCallback) {
if (OS.Constants.Sys.Name == "Darwin") {
goUpdateGlobalEditMenuItems();
// On OSX, we have a native menu, so it has to be updated. In single process browsers,
// this happens synchronously, but in e10s, we have to wait for the main thread
// to deal with it for us. 1 second should be plenty of time.
setTimeout(aCallback, 1000);
return;
}
menuPopup.addEventListener("popupshown", function onPopupShown() {
menuPopup.removeEventListener("popupshown", onPopupShown, false);
executeSoon(aCallback);
}, false);
executeSoon(function() {
editMenu.open = true;
});
};
yield BrowserTestUtils.withNewTab({ gBrowser: gBrowser, url: "about:blank" }, function* (browser) {
let menu_cut_disabled, menu_copy_disabled;
yield BrowserTestUtils.loadURI(browser, "data:text/html,<div>hello!</div>");
yield BrowserTestUtils.browserLoaded(browser);
browser.focus();
yield new Promise(resolve => waitForFocus(resolve, window));
yield new Promise(openMenu);
menu_cut_disabled = menuPopup.querySelector("#menu_cut").getAttribute('disabled') == "true";
is(menu_cut_disabled, false, "menu_cut should be enabled");
menu_copy_disabled = menuPopup.querySelector("#menu_copy").getAttribute('disabled') == "true";
is(menu_copy_disabled, false, "menu_copy should be enabled");
yield new Promise(closeMenu);
yield BrowserTestUtils.loadURI(browser, "data:text/html,<div contentEditable='true'>hello!</div>");
yield BrowserTestUtils.browserLoaded(browser);
browser.focus();
yield new Promise(resolve => waitForFocus(resolve, window));
yield new Promise(openMenu);
menu_cut_disabled = menuPopup.querySelector("#menu_cut").getAttribute('disabled') == "true";
is(menu_cut_disabled, false, "menu_cut should be enabled");
menu_copy_disabled = menuPopup.querySelector("#menu_copy").getAttribute('disabled') == "true";
is(menu_copy_disabled, false, "menu_copy should be enabled");
yield new Promise(closeMenu);
yield BrowserTestUtils.loadURI(browser, "about:preferences");
yield BrowserTestUtils.browserLoaded(browser);
browser.focus();
yield new Promise(resolve => waitForFocus(resolve, window));
yield new Promise(openMenu);
menu_cut_disabled = menuPopup.querySelector("#menu_cut").getAttribute('disabled') == "true";
is(menu_cut_disabled, true, "menu_cut should be disabled");
menu_copy_disabled = menuPopup.querySelector("#menu_copy").getAttribute('disabled') == "true";
is(menu_copy_disabled, true, "menu_copy should be disabled");
yield new Promise(closeMenu);
});
});

View file

@ -1,75 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
var kPrefName = "accessibility.typeaheadfind.prefillwithselection";
var kEmptyURI = "data:text/html,";
// This pref is false by default in OSX; ensure the test still works there.
Services.prefs.setBoolPref(kPrefName, true);
registerCleanupFunction(function() {
Services.prefs.clearUserPref(kPrefName);
});
add_task(function* () {
let aTab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, kEmptyURI);
ok(!gFindBarInitialized, "findbar isn't initialized yet");
// Note: the use case here is when the user types directly in the findbar
// _before_ it's prefilled with a text selection in the page.
// So `yield BrowserTestUtils.sendChar()` can't be used here:
// - synthesizing a key in the browser won't actually send it to the
// findbar; the findbar isn't part of the browser content.
// - we need to _not_ wait for _startFindDeferred to be resolved; yielding
// a synthesized keypress on the browser implicitely happens after the
// browser has dispatched its return message with the prefill value for
// the findbar, which essentially nulls these tests.
let findBar = gFindBar;
is(findBar._findField.value, "", "findbar is empty");
// Test 1
// Any input in the findbar should erase a previous search.
findBar._findField.value = "xy";
findBar.startFind();
is(findBar._findField.value, "xy", "findbar should have xy initial query");
is(findBar._findField.mInputField,
document.activeElement,
"findbar is now focused");
EventUtils.sendChar("z", window);
is(findBar._findField.value, "z", "z erases xy");
findBar._findField.value = "";
ok(!findBar._findField.value, "erase findbar after first test");
// Test 2
// Prefilling the findbar should be ignored if a search has been run.
findBar.startFind();
ok(findBar._startFindDeferred, "prefilled value hasn't been fetched yet");
is(findBar._findField.mInputField,
document.activeElement,
"findbar is still focused");
EventUtils.sendChar("a", window);
EventUtils.sendChar("b", window);
is(findBar._findField.value, "ab", "initial ab typed in the findbar");
// This resolves _startFindDeferred if it's still pending; let's just skip
// over waiting for the browser's return message that should do this as it
// doesn't really matter.
findBar.onCurrentSelection("foo", true);
ok(!findBar._startFindDeferred, "prefilled value fetched");
is(findBar._findField.value, "ab", "ab kept instead of prefill value");
EventUtils.sendChar("c", window);
is(findBar._findField.value, "abc", "c is appended after ab");
// Clear the findField value to make the test run successfully
// for multiple runs in the same browser session.
findBar._findField.value = "";
yield BrowserTestUtils.removeTab(aTab);
});

View file

@ -1,214 +0,0 @@
requestLongerTimeout(2);
add_task(function* ()
{
function pushPref(name, value) {
return new Promise(resolve => SpecialPowers.pushPrefEnv({"set": [[name, value]]}, resolve));
}
yield pushPref("general.autoScroll", true);
const expectScrollNone = 0;
const expectScrollVert = 1;
const expectScrollHori = 2;
const expectScrollBoth = 3;
var allTests = [
{dataUri: 'data:text/html,<html><head><meta charset="utf-8"></head><body><style type="text/css">div { display: inline-block; }</style>\
<div id="a" style="width: 100px; height: 100px; overflow: hidden;"><div style="width: 200px; height: 200px;"></div></div>\
<div id="b" style="width: 100px; height: 100px; overflow: auto;"><div style="width: 200px; height: 200px;"></div></div>\
<div id="c" style="width: 100px; height: 100px; overflow-x: auto; overflow-y: hidden;"><div style="width: 200px; height: 200px;"></div></div>\
<div id="d" style="width: 100px; height: 100px; overflow-y: auto; overflow-x: hidden;"><div style="width: 200px; height: 200px;"></div></div>\
<select id="e" style="width: 100px; height: 100px;" multiple="multiple"><option>aaaaaaaaaaaaaaaaaaaaaaaa</option><option>a</option><option>a</option>\
<option>a</option><option>a</option><option>a</option><option>a</option><option>a</option><option>a</option><option>a</option>\
<option>a</option><option>a</option><option>a</option><option>a</option><option>a</option><option>a</option><option>a</option></select>\
<select id="f" style="width: 100px; height: 100px;"><option>a</option><option>aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</option><option>a</option>\
<option>a</option><option>a</option><option>a</option><option>a</option><option>a</option><option>a</option><option>a</option>\
<option>a</option><option>a</option><option>a</option><option>a</option><option>a</option><option>a</option><option>a</option></select>\
<div id="g" style="width: 99px; height: 99px; border: 10px solid black; margin: 10px; overflow: auto;"><div style="width: 100px; height: 100px;"></div></div>\
<div id="h" style="width: 100px; height: 100px; overflow: -moz-hidden-unscrollable;"><div style="width: 200px; height: 200px;"></div></div>\
<iframe id="iframe" style="display: none;"></iframe>\
</body></html>'},
{elem: 'a', expected: expectScrollNone},
{elem: 'b', expected: expectScrollBoth},
{elem: 'c', expected: expectScrollHori},
{elem: 'd', expected: expectScrollVert},
{elem: 'e', expected: expectScrollVert},
{elem: 'f', expected: expectScrollNone},
{elem: 'g', expected: expectScrollBoth},
{elem: 'h', expected: expectScrollNone},
{dataUri: 'data:text/html,<html><head><meta charset="utf-8"></head><body id="i" style="overflow-y: scroll"><div style="height: 2000px"></div>\
<iframe id="iframe" style="display: none;"></iframe>\
</body></html>'},
{elem: 'i', expected: expectScrollVert}, // bug 695121
{dataUri: 'data:text/html,<html><head><meta charset="utf-8"></head><style>html, body { width: 100%; height: 100%; overflow-x: hidden; overflow-y: scroll; }</style>\
<body id="j"><div style="height: 2000px"></div>\
<iframe id="iframe" style="display: none;"></iframe>\
</body></html>'},
{elem: 'j', expected: expectScrollVert}, // bug 914251
{dataUri: 'data:text/html,<html><head><meta charset="utf-8">\
<style>\
body > div {scroll-behavior: smooth;width: 300px;height: 300px;overflow: scroll;}\
body > div > div {width: 1000px;height: 1000px;}\
</style>\
</head><body><div id="t"><div></div></div></body></html>'},
{elem: 't', expected: expectScrollBoth}, // bug 1308775
{dataUri: 'data:text/html,<html><head><meta charset="utf-8"></head><body>\
<div id="k" style="height: 150px; width: 200px; overflow: scroll; border: 1px solid black;">\
<iframe style="height: 200px; width: 300px;"></iframe>\
</div>\
<div id="l" style="height: 150px; width: 300px; overflow: scroll; border: 1px dashed black;">\
<iframe style="height: 200px; width: 200px;" src="data:text/html,<div style=\'border: 5px solid blue; height: 200%; width: 200%;\'></div>"></iframe>\
</div>\
<iframe id="m"></iframe>\
<div style="height: 200%; border: 5px dashed black;">filler to make document overflow: scroll;</div>\
</body></html>'},
{elem: 'k', expected: expectScrollBoth},
{elem: 'k', expected: expectScrollNone, testwindow: true},
{elem: 'l', expected: expectScrollNone},
{elem: 'm', expected: expectScrollVert, testwindow: true},
{dataUri: 'data:text/html,<html><head><meta charset="utf-8"></head><body>\
<img width="100" height="100" alt="image map" usemap="%23planetmap">\
<map name="planetmap">\
<area id="n" shape="rect" coords="0,0,100,100" href="javascript:void(null)">\
</map>\
<a href="javascript:void(null)" id="o" style="width: 100px; height: 100px; border: 1px solid black; display: inline-block; vertical-align: top;">link</a>\
<input id="p" style="width: 100px; height: 100px; vertical-align: top;">\
<textarea id="q" style="width: 100px; height: 100px; vertical-align: top;"></textarea>\
<div style="height: 200%; border: 1px solid black;"></div>\
</body></html>'},
{elem: 'n', expected: expectScrollNone, testwindow: true},
{elem: 'o', expected: expectScrollNone, testwindow: true},
{elem: 'p', expected: expectScrollVert, testwindow: true, middlemousepastepref: false},
{elem: 'q', expected: expectScrollVert, testwindow: true, middlemousepastepref: false},
{dataUri: 'data:text/html,<html><head><meta charset="utf-8"></head><body>\
<input id="r" style="width: 100px; height: 100px; vertical-align: top;">\
<textarea id="s" style="width: 100px; height: 100px; vertical-align: top;"></textarea>\
<div style="height: 200%; border: 1px solid black;"></div>\
</body></html>'},
{elem: 'r', expected: expectScrollNone, testwindow: true, middlemousepastepref: true},
{elem: 's', expected: expectScrollNone, testwindow: true, middlemousepastepref: true}
];
for (let test of allTests) {
if (test.dataUri) {
let loadedPromise = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
gBrowser.loadURI(test.dataUri);
yield loadedPromise;
continue;
}
let prefsChanged = (test.middlemousepastepref == false || test.middlemousepastepref == true);
if (prefsChanged) {
yield pushPref("middlemouse.paste", test.middlemousepastepref);
}
yield BrowserTestUtils.synthesizeMouse("#" + test.elem, 50, 80, { button: 1 },
gBrowser.selectedBrowser);
// This ensures bug 605127 is fixed: pagehide in an unrelated document
// should not cancel the autoscroll.
yield ContentTask.spawn(gBrowser.selectedBrowser, { }, function* () {
var iframe = content.document.getElementById("iframe");
if (iframe) {
var e = new iframe.contentWindow.PageTransitionEvent("pagehide",
{ bubbles: true,
cancelable: true,
persisted: false });
iframe.contentDocument.dispatchEvent(e);
iframe.contentDocument.documentElement.dispatchEvent(e);
}
});
is(document.activeElement, gBrowser.selectedBrowser, "Browser still focused after autoscroll started");
yield BrowserTestUtils.synthesizeMouse("#" + test.elem, 100, 100,
{ type: "mousemove", clickCount: "0" },
gBrowser.selectedBrowser);
if (prefsChanged) {
yield new Promise(resolve => SpecialPowers.popPrefEnv(resolve));
}
// Start checking for the scroll.
let firstTimestamp = undefined;
let timeCompensation;
do {
let timestamp = yield new Promise(resolve => window.requestAnimationFrame(resolve));
if (firstTimestamp === undefined) {
firstTimestamp = timestamp;
}
// This value is calculated similarly to the value of the same name in
// ClickEventHandler.autoscrollLoop, except here it's cumulative across
// all frames after the first one instead of being based only on the
// current frame.
timeCompensation = (timestamp - firstTimestamp) / 20;
info("timestamp=" + timestamp + " firstTimestamp=" + firstTimestamp +
" timeCompensation=" + timeCompensation);
// Try to wait until enough time has passed to allow the scroll to happen.
// autoscrollLoop incrementally scrolls during each animation frame, but
// due to how its calculations work, when a frame is very close to the
// previous frame, no scrolling may actually occur during that frame.
// After 100ms's worth of frames, timeCompensation will be 1, making it
// more likely that the accumulated scroll in autoscrollLoop will be >= 1,
// although it also depends on acceleration, which here in this test
// should be > 1 due to how it synthesizes mouse events below.
} while (timeCompensation < 5);
// Close the autoscroll popup by synthesizing Esc.
EventUtils.synthesizeKey("VK_ESCAPE", {});
let scrollVert = test.expected & expectScrollVert;
let scrollHori = test.expected & expectScrollHori;
yield ContentTask.spawn(gBrowser.selectedBrowser,
{ scrollVert : scrollVert,
scrollHori: scrollHori,
elemid : test.elem,
checkWindow: test.testwindow },
function* (args) {
let msg = "";
if (args.checkWindow) {
if (!((args.scrollVert && content.scrollY > 0) ||
(!args.scrollVert && content.scrollY == 0))) {
msg += "Failed: ";
}
msg += 'Window for ' + args.elemid + ' should' + (args.scrollVert ? '' : ' not') + ' have scrolled vertically\n';
if (!((args.scrollHori && content.scrollX > 0) ||
(!args.scrollHori && content.scrollX == 0))) {
msg += "Failed: ";
}
msg += ' Window for ' + args.elemid + ' should' + (args.scrollHori ? '' : ' not') + ' have scrolled horizontally\n';
} else {
let elem = content.document.getElementById(args.elemid);
if (!((args.scrollVert && elem.scrollTop > 0) ||
(!args.scrollVert && elem.scrollTop == 0))) {
msg += "Failed: ";
}
msg += ' ' + args.elemid + ' should' + (args.scrollVert ? '' : ' not') + ' have scrolled vertically\n';
if (!((args.scrollHori && elem.scrollLeft > 0) ||
(!args.scrollHori && elem.scrollLeft == 0))) {
msg += "Failed: ";
}
msg += args.elemid + ' should' + (args.scrollHori ? '' : ' not') + ' have scrolled horizontally';
}
Assert.ok(msg.indexOf("Failed") == -1, msg);
}
);
// Before continuing the test, we need to ensure that the IPC
// message that stops autoscrolling has had time to arrive.
yield new Promise(resolve => executeSoon(resolve));
}
// remove 2 tabs that were opened by middle-click on links
while (gBrowser.visibleTabs.length > 1) {
gBrowser.removeTab(gBrowser.visibleTabs[gBrowser.visibleTabs.length - 1]);
}
// wait for focus to fix a failure in the next test if the latter runs too soon.
yield SimpleTest.promiseFocus();
});

View file

@ -1,152 +0,0 @@
Services.scriptloader.loadSubScript("chrome://mochikit/content/tests/SimpleTest/WindowSnapshot.js", this);
add_task(function*() {
const SEARCH_TEXT = "text";
const DATAURI = "data:text/html," + SEARCH_TEXT;
// Bug 451286. An iframe that should be highlighted
let visible = "<iframe id='visible' src='" + DATAURI + "'></iframe>";
// Bug 493658. An invisible iframe that shouldn't interfere with
// highlighting matches lying after it in the document
let invisible = "<iframe id='invisible' style='display: none;' " +
"src='" + DATAURI + "'></iframe>";
let uri = DATAURI + invisible + SEARCH_TEXT + visible + SEARCH_TEXT;
let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, uri);
let contentRect = tab.linkedBrowser.getBoundingClientRect();
let noHighlightSnapshot = snapshotRect(window, contentRect);
ok(noHighlightSnapshot, "Got noHighlightSnapshot");
yield openFindBarAndWait();
gFindBar._findField.value = SEARCH_TEXT;
yield findAgainAndWait();
var matchCase = gFindBar.getElement("find-case-sensitive");
if (matchCase.checked)
matchCase.doCommand();
// Turn on highlighting
yield toggleHighlightAndWait(true);
yield closeFindBarAndWait();
// Take snapshot of highlighting
let findSnapshot = snapshotRect(window, contentRect);
ok(findSnapshot, "Got findSnapshot");
// Now, remove the highlighting, and take a snapshot to compare
// to our original state
yield openFindBarAndWait();
yield toggleHighlightAndWait(false);
yield closeFindBarAndWait();
let unhighlightSnapshot = snapshotRect(window, contentRect);
ok(unhighlightSnapshot, "Got unhighlightSnapshot");
// Select the matches that should have been highlighted manually
yield ContentTask.spawn(tab.linkedBrowser, null, function*() {
let doc = content.document;
let win = doc.defaultView;
// Create a manual highlight in the visible iframe to test bug 451286
let iframe = doc.getElementById("visible");
let ifBody = iframe.contentDocument.body;
let range = iframe.contentDocument.createRange();
range.selectNodeContents(ifBody.childNodes[0]);
let ifWindow = iframe.contentWindow;
let ifDocShell = ifWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShell);
let ifController = ifDocShell.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsISelectionDisplay)
.QueryInterface(Ci.nsISelectionController);
let frameFindSelection =
ifController.getSelection(ifController.SELECTION_FIND);
frameFindSelection.addRange(range);
// Create manual highlights in the main document (the matches that lie
// before/after the iframes
let docShell = win.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShell);
let controller = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsISelectionDisplay)
.QueryInterface(Ci.nsISelectionController);
let docFindSelection =
controller.getSelection(ifController.SELECTION_FIND);
range = doc.createRange();
range.selectNodeContents(doc.body.childNodes[0]);
docFindSelection.addRange(range);
range = doc.createRange();
range.selectNodeContents(doc.body.childNodes[2]);
docFindSelection.addRange(range);
range = doc.createRange();
range.selectNodeContents(doc.body.childNodes[4]);
docFindSelection.addRange(range);
});
// Take snapshot of manual highlighting
let manualSnapshot = snapshotRect(window, contentRect);
ok(manualSnapshot, "Got manualSnapshot");
// Test 1: Were the matches in iframe correctly highlighted?
let res = compareSnapshots(findSnapshot, manualSnapshot, true);
ok(res[0], "Matches found in iframe correctly highlighted");
// Test 2: Were the matches in iframe correctly unhighlighted?
res = compareSnapshots(noHighlightSnapshot, unhighlightSnapshot, true);
ok(res[0], "Highlighting in iframe correctly removed");
yield BrowserTestUtils.removeTab(tab);
});
function toggleHighlightAndWait(shouldHighlight) {
return new Promise((resolve) => {
let listener = {
onFindResult() {},
onHighlightFinished() {
gFindBar.browser.finder.removeResultListener(listener);
resolve();
},
onMatchesCountResult() {}
};
gFindBar.browser.finder.addResultListener(listener);
gFindBar.toggleHighlight(shouldHighlight);
});
}
function findAgainAndWait() {
return new Promise(resolve => {
let listener = {
onFindResult() {
gFindBar.browser.finder.removeResultListener(listener);
resolve();
},
onHighlightFinished() {},
onMatchesCountResult() {}
};
gFindBar.browser.finder.addResultListener(listener);
gFindBar.onFindAgainCommand();
});
}
function* openFindBarAndWait() {
let awaitTransitionEnd = BrowserTestUtils.waitForEvent(gFindBar, "transitionend");
gFindBar.open();
yield awaitTransitionEnd;
}
// This test is comparing snapshots. It is necessary to wait for the gFindBar
// to close before taking the snapshot so the gFindBar does not take up space
// on the new snapshot.
function* closeFindBarAndWait() {
let awaitTransitionEnd = BrowserTestUtils.waitForEvent(gFindBar, "transitionend", false, event => {
return event.propertyName == "visibility";
});
gFindBar.close();
yield awaitTransitionEnd;
}

View file

@ -1,9 +0,0 @@
add_task(function* () {
let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:rights");
yield ContentTask.spawn(tab.linkedBrowser, null, function* () {
Assert.ok(content.document.getElementById("your-rights"), "about:rights content loaded");
});
yield BrowserTestUtils.removeTab(tab);
});

View file

@ -1,70 +0,0 @@
const scrollHtml =
"<textarea id=\"textarea1\" row=2>Firefox\n\nFirefox\n\n\n\n\n\n\n\n\n\n" +
"</textarea><a href=\"about:blank\">blank</a>";
add_task(function*() {
let url = "data:text/html;base64," + btoa(scrollHtml);
yield BrowserTestUtils.withNewTab({gBrowser, url}, function*(browser) {
let awaitFindResult = new Promise(resolve => {
let listener = {
onFindResult(aData) {
info("got find result");
browser.finder.removeResultListener(listener);
ok(aData.result == Ci.nsITypeAheadFind.FIND_FOUND, "should find string");
resolve();
},
onCurrentSelection() {},
onMatchesCountResult() {}
};
info("about to add results listener, open find bar, and send 'F' string");
browser.finder.addResultListener(listener);
});
gFindBar.onFindCommand();
EventUtils.sendString("F");
info("added result listener and sent string 'F'");
yield awaitFindResult;
let awaitScrollDone = BrowserTestUtils.waitForMessage(browser.messageManager, "ScrollDone");
// scroll textarea to bottom
const scrollTest =
"var textarea = content.document.getElementById(\"textarea1\");" +
"textarea.scrollTop = textarea.scrollHeight;" +
"sendAsyncMessage(\"ScrollDone\", { });"
browser.messageManager.loadFrameScript("data:text/javascript;base64," +
btoa(scrollTest), false);
yield awaitScrollDone;
info("got ScrollDone event");
yield BrowserTestUtils.loadURI(browser, "about:blank");
yield BrowserTestUtils.browserLoaded(browser);
ok(browser.currentURI.spec == "about:blank", "got load event for about:blank");
let awaitFindResult2 = new Promise(resolve => {
let listener = {
onFindResult(aData) {
info("got find result #2");
browser.finder.removeResultListener(listener);
resolve();
},
onCurrentSelection() {},
onMatchesCountResult() {}
};
browser.finder.addResultListener(listener);
info("added result listener");
});
// find again needs delay for crash test
setTimeout(function() {
// ignore exception if occured
try {
info("about to send find again command");
gFindBar.onFindAgainCommand(false);
info("sent find again command");
} catch (e) {
info("got exception from onFindAgainCommand: " + e);
}
}, 0);
yield awaitFindResult2;
});
});

View file

@ -1,16 +0,0 @@
var url = "https://example.com/browser/toolkit/content/tests/browser/file_contentTitle.html";
add_task(function*() {
let tab = gBrowser.selectedTab = gBrowser.addTab(url);
let browser = tab.linkedBrowser;
yield new Promise((resolve) => {
addEventListener("TestLocationChange", function listener() {
removeEventListener("TestLocationChange", listener);
resolve();
}, true, true);
});
is(gBrowser.contentTitle, "Test Page", "Should have the right title.");
gBrowser.removeTab(tab);
});

View file

@ -1,73 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
/* global Services, requestLongerTimeout, TestUtils, BrowserTestUtils,
ok, info, dump, is, Ci, Cu, Components, ctypes, privateNoteIntentionalCrash,
gBrowser, add_task, addEventListener, removeEventListener, ContentTask */
"use strict";
// Running this test in ASAN is slow.
requestLongerTimeout(2);
/**
* Removes a file from a directory. This is a no-op if the file does not
* exist.
*
* @param directory
* The nsIFile representing the directory to remove from.
* @param filename
* A string for the file to remove from the directory.
*/
function removeFile(directory, filename) {
let file = directory.clone();
file.append(filename);
if (file.exists()) {
file.remove(false);
}
}
/**
* Returns the directory where crash dumps are stored.
*
* @return nsIFile
*/
function getMinidumpDirectory() {
let dir = Services.dirsvc.get('ProfD', Ci.nsIFile);
dir.append("minidumps");
return dir;
}
/**
* Checks that the URL is correctly annotated on a content process crash.
*/
add_task(function* test_content_url_annotation() {
let url = "https://example.com/browser/toolkit/content/tests/browser/file_redirect.html";
let redirect_url = "https://example.com/browser/toolkit/content/tests/browser/file_redirect_to.html";
yield BrowserTestUtils.withNewTab({
gBrowser: gBrowser
}, function* (browser) {
ok(browser.isRemoteBrowser, "Should be a remote browser");
// file_redirect.html should send us to file_redirect_to.html
let promise = ContentTask.spawn(browser, {}, function* () {
dump('ContentTask starting...\n');
yield new Promise((resolve) => {
addEventListener("RedirectDone", function listener() {
dump('Got RedirectDone\n');
removeEventListener("RedirectDone", listener);
resolve();
}, true, true);
});
});
browser.loadURI(url);
yield promise;
// Crash the tab
let annotations = yield BrowserTestUtils.crashBrowser(browser);
ok("URL" in annotations, "annotated a URL");
is(annotations.URL, redirect_url,
"Should have annotated the URL after redirect");
});
});

View file

@ -1,108 +0,0 @@
"use strict";
/**
* Cleans up the .dmp and .extra file from a crash.
*
* @param subject (nsISupports)
* The subject passed through the ipc:content-shutdown
* observer notification when a content process crash has
* occurred.
*/
function cleanUpMinidump(subject) {
Assert.ok(subject instanceof Ci.nsIPropertyBag2,
"Subject needs to be a nsIPropertyBag2 to clean up properly");
let dumpID = subject.getPropertyAsAString("dumpID");
Assert.ok(dumpID, "There should be a dumpID");
if (dumpID) {
let dir = Services.dirsvc.get("ProfD", Ci.nsIFile);
dir.append("minidumps");
let file = dir.clone();
file.append(dumpID + ".dmp");
file.remove(true);
file = dir.clone();
file.append(dumpID + ".extra");
file.remove(true);
}
}
/**
* This test ensures that if a remote frameloader crashes after
* the frameloader owner swaps it out for a new frameloader,
* that a oop-browser-crashed event is not sent to the new
* frameloader's browser element.
*/
add_task(function* test_crash_in_previous_frameloader() {
// On debug builds, crashing tabs results in much thinking, which
// slows down the test and results in intermittent test timeouts,
// so we'll pump up the expected timeout for this test.
requestLongerTimeout(2);
if (!gMultiProcessBrowser) {
Assert.ok(false, "This test should only be run in multi-process mode.");
return;
}
yield BrowserTestUtils.withNewTab({
gBrowser,
url: "http://example.com",
}, function*(browser) {
// First, sanity check...
Assert.ok(browser.isRemoteBrowser,
"This browser needs to be remote if this test is going to " +
"work properly.");
// We will wait for the oop-browser-crashed event to have
// a chance to appear. That event is fired when TabParents
// are destroyed, and that occurs _before_ ContentParents
// are destroyed, so we'll wait on the ipc:content-shutdown
// observer notification, which is fired when a ContentParent
// goes away. After we see this notification, oop-browser-crashed
// events should have fired.
let contentProcessGone = TestUtils.topicObserved("ipc:content-shutdown");
let sawTabCrashed = false;
let onTabCrashed = () => {
sawTabCrashed = true;
};
browser.addEventListener("oop-browser-crashed", onTabCrashed);
// The name of the game is to cause a crash in a remote browser,
// and then immediately swap out the browser for a non-remote one.
yield ContentTask.spawn(browser, null, function() {
const Cu = Components.utils;
Cu.import("resource://gre/modules/ctypes.jsm");
Cu.import("resource://gre/modules/Timer.jsm");
let dies = function() {
privateNoteIntentionalCrash();
let zero = new ctypes.intptr_t(8);
let badptr = ctypes.cast(zero, ctypes.PointerType(ctypes.int32_t));
badptr.contents
};
// When the parent flips the remoteness of the browser, the
// page should receive the pagehide event, which we'll then
// use to crash the frameloader.
addEventListener("pagehide", function() {
dump("\nEt tu, Brute?\n");
dies();
});
});
gBrowser.updateBrowserRemoteness(browser, false);
info("Waiting for content process to go away.");
let [subject, data] = yield contentProcessGone;
// If we don't clean up the minidump, the harness will
// complain.
cleanUpMinidump(subject);
info("Content process is gone!");
Assert.ok(!sawTabCrashed,
"Should not have seen the oop-browser-crashed event.");
browser.removeEventListener("oop-browser-crashed", onTabCrashed);
});
});

View file

@ -1,284 +0,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/. */
"use strict";
const MONTH_YEAR = ".month-year",
DAYS_VIEW = ".days-view",
BTN_PREV_MONTH = ".prev",
BTN_NEXT_MONTH = ".next";
const DATE_FORMAT = new Intl.DateTimeFormat("en-US", { year: "numeric", month: "long", timeZone: "UTC" }).format;
// Create a list of abbreviations for calendar class names
const W = "weekend",
O = "outside",
S = "selection",
R = "out-of-range",
T = "today",
P = "off-step";
// Calendar classlist for 2016-12. Used to verify the classNames are correct.
const calendarClasslist_201612 = [
[W, O], [O], [O], [O], [], [], [W],
[W], [], [], [], [], [], [W],
[W], [], [], [], [S], [], [W],
[W], [], [], [], [], [], [W],
[W], [], [], [], [], [], [W],
[W, O], [O], [O], [O], [O], [O], [W, O],
];
function getCalendarText() {
return helper.getChildren(DAYS_VIEW).map(child => child.textContent);
}
function getCalendarClassList() {
return helper.getChildren(DAYS_VIEW).map(child => Array.from(child.classList));
}
function mergeArrays(a, b) {
return a.map((classlist, index) => classlist.concat(b[index]));
}
let helper = new DateTimeTestHelper();
registerCleanupFunction(() => {
helper.cleanup();
});
/**
* Test that date picker opens to today's date when input field is blank
*/
add_task(async function test_datepicker_today() {
const date = new Date();
await helper.openPicker("data:text/html, <input type='date'>");
Assert.equal(helper.getElement(MONTH_YEAR).textContent, DATE_FORMAT(date));
await helper.tearDown();
});
/**
* Test that date picker opens to the correct month, with calendar days
* displayed correctly, given a date value is set.
*/
add_task(async function test_datepicker_open() {
const inputValue = "2016-12-15";
await helper.openPicker(`data:text/html, <input type="date" value="${inputValue}">`);
Assert.equal(helper.getElement(MONTH_YEAR).textContent, DATE_FORMAT(new Date(inputValue)));
Assert.deepEqual(
getCalendarText(),
[
"27", "28", "29", "30", "1", "2", "3",
"4", "5", "6", "7", "8", "9", "10",
"11", "12", "13", "14", "15", "16", "17",
"18", "19", "20", "21", "22", "23", "24",
"25", "26", "27", "28", "29", "30", "31",
"1", "2", "3", "4", "5", "6", "7",
],
"2016-12",
);
Assert.deepEqual(
getCalendarClassList(),
calendarClasslist_201612,
"2016-12 classNames"
);
await helper.tearDown();
});
/**
* When the prev month button is clicked, calendar should display the dates for
* the previous month.
*/
add_task(async function test_datepicker_prev_month_btn() {
const inputValue = "2016-12-15";
const prevMonth = "2016-11-01";
await helper.openPicker(`data:text/html, <input type="date" value="${inputValue}">`);
helper.click(helper.getElement(BTN_PREV_MONTH));
Assert.equal(helper.getElement(MONTH_YEAR).textContent, DATE_FORMAT(new Date(prevMonth)));
Assert.deepEqual(
getCalendarText(),
[
"30", "31", "1", "2", "3", "4", "5",
"6", "7", "8", "9", "10", "11", "12",
"13", "14", "15", "16", "17", "18", "19",
"20", "21", "22", "23", "24", "25", "26",
"27", "28", "29", "30", "1", "2", "3",
"4", "5", "6", "7", "8", "9", "10",
],
"2016-11",
);
await helper.tearDown();
});
/**
* When the next month button is clicked, calendar should display the dates for
* the next month.
*/
add_task(async function test_datepicker_next_month_btn() {
const inputValue = "2016-12-15";
const nextMonth = "2017-01-01";
await helper.openPicker(`data:text/html, <input type="date" value="${inputValue}">`);
helper.click(helper.getElement(BTN_NEXT_MONTH));
Assert.equal(helper.getElement(MONTH_YEAR).textContent, DATE_FORMAT(new Date(nextMonth)));
Assert.deepEqual(
getCalendarText(),
[
"25", "26", "27", "28", "29", "30", "31",
"1", "2", "3", "4", "5", "6", "7",
"8", "9", "10", "11", "12", "13", "14",
"15", "16", "17", "18", "19", "20", "21",
"22", "23", "24", "25", "26", "27", "28",
"29", "30", "31", "1", "2", "3", "4",
],
"2017-01",
);
await helper.tearDown();
});
/**
* When a date on the calendar is clicked, date picker should close and set
* value to the input box.
*/
add_task(async function test_datepicker_clicked() {
const inputValue = "2016-12-15";
const firstDayOnCalendar = "2016-11-27";
await helper.openPicker(`data:text/html, <input type="date" value="${inputValue}">`);
// Click the first item (top-left corner) of the calendar
helper.click(helper.getElement(DAYS_VIEW).children[0]);
await ContentTask.spawn(helper.tab.linkedBrowser, {}, async function() {
let inputEl = content.document.querySelector("input");
await ContentTaskUtils.waitForEvent(inputEl, "input");
});
Assert.equal(content.document.querySelector("input").value, firstDayOnCalendar);
await helper.tearDown();
});
/**
* Make sure picker is in correct state when it is reopened.
*/
add_task(async function test_datepicker_reopen_state() {
const inputValue = "2016-12-15";
const nextMonth = "2017-01-01";
await helper.openPicker(`data:text/html, <input type="date" value="${inputValue}">`);
// Navigate to the next month but does not commit the change
Assert.equal(helper.getElement(MONTH_YEAR).textContent, DATE_FORMAT(new Date(inputValue)));
helper.click(helper.getElement(BTN_NEXT_MONTH));
Assert.equal(helper.getElement(MONTH_YEAR).textContent, DATE_FORMAT(new Date(nextMonth)));
EventUtils.synthesizeKey("VK_ESCAPE", {}, window);
// Ensures the picker opens to the month of the input value
await BrowserTestUtils.synthesizeMouseAtCenter("input", {}, gBrowser.selectedBrowser);
await helper.waitForPickerReady();
Assert.equal(helper.getElement(MONTH_YEAR).textContent, DATE_FORMAT(new Date(inputValue)));
await helper.tearDown();
});
/**
* When min and max attributes are set, calendar should show some dates as
* out-of-range.
*/
add_task(async function test_datepicker_min_max() {
const inputValue = "2016-12-15";
const inputMin = "2016-12-05";
const inputMax = "2016-12-25";
await helper.openPicker(`data:text/html, <input type="date" value="${inputValue}" min="${inputMin}" max="${inputMax}">`);
Assert.deepEqual(
getCalendarClassList(),
mergeArrays(calendarClasslist_201612, [
// R denotes out-of-range
[R], [R], [R], [R], [R], [R], [R],
[R], [], [], [], [], [], [],
[], [], [], [], [], [], [],
[], [], [], [], [], [], [],
[], [R], [R], [R], [R], [R], [R],
[R], [R], [R], [R], [R], [R], [R],
]),
"2016-12 with min & max",
);
await helper.tearDown();
});
/**
* When step attribute is set, calendar should show some dates as off-step.
*/
add_task(async function test_datepicker_step() {
const inputValue = "2016-12-15";
const inputStep = "5";
await helper.openPicker(`data:text/html, <input type="date" value="${inputValue}" step="${inputStep}">`);
Assert.deepEqual(
getCalendarClassList(),
mergeArrays(calendarClasslist_201612, [
// P denotes off-step
[P], [P], [P], [], [P], [P], [P],
[P], [], [P], [P], [P], [P], [],
[P], [P], [P], [P], [], [P], [P],
[P], [P], [], [P], [P], [P], [P],
[], [P], [P], [P], [P], [], [P],
[P], [P], [P], [], [P], [P], [P],
]),
"2016-12 with step",
);
await helper.tearDown();
});
add_task(async function test_datepicker_abs_min() {
const inputValue = "0001-01-01";
await helper.openPicker(`data:text/html, <input type="date" value="${inputValue}">`);
Assert.deepEqual(
getCalendarText(),
[
"", "1", "2", "3", "4", "5", "6",
"7", "8", "9", "10", "11", "12", "13",
"14", "15", "16", "17", "18", "19", "20",
"21", "22", "23", "24", "25", "26", "27",
"28", "29", "30", "31", "1", "2", "3",
"4", "5", "6", "7", "8", "9", "10",
],
"0001-01",
);
await helper.tearDown();
});
add_task(async function test_datepicker_abs_max() {
const inputValue = "275760-09-13";
await helper.openPicker(`data:text/html, <input type="date" value="${inputValue}">`);
Assert.deepEqual(
getCalendarText(),
[
"31", "1", "2", "3", "4", "5", "6",
"7", "8", "9", "10", "11", "12", "13",
"", "", "", "", "", "", "",
"", "", "", "", "", "", "",
"", "", "", "", "", "", "",
"", "", "", "", "", "", "",
],
"275760-09",
);
await helper.tearDown();
});

View file

@ -1,45 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
var MockFilePicker = SpecialPowers.MockFilePicker;
MockFilePicker.init(window);
/**
* TestCase for bug 564387
* <https://bugzilla.mozilla.org/show_bug.cgi?id=564387>
*/
add_task(function* () {
let loadPromise = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
gBrowser.loadURI("data:image/gif;base64,R0lGODlhEAAOALMAAOazToeHh0tLS/7LZv/0jvb29t/f3//Ub//ge8WSLf/rhf/3kdbW1mxsbP//mf///yH5BAAAAAAALAAAAAAQAA4AAARe8L1Ekyky67QZ1hLnjM5UUde0ECwLJoExKcppV0aCcGCmTIHEIUEqjgaORCMxIC6e0CcguWw6aFjsVMkkIr7g77ZKPJjPZqIyd7sJAgVGoEGv2xsBxqNgYPj/gAwXEQA7");
yield loadPromise;
let popupShownPromise = BrowserTestUtils.waitForEvent(document, "popupshown");
yield BrowserTestUtils.synthesizeMouseAtCenter("img",
{ type: "contextmenu", button: 2 },
gBrowser.selectedBrowser);
yield popupShownPromise;
let showFilePickerPromise = new Promise(resolve => {
MockFilePicker.showCallback = function(fp) {
is(fp.defaultString, "index.gif");
resolve();
}
});
registerCleanupFunction(function () {
MockFilePicker.cleanup();
});
// Select "Save Image As" option from context menu
var saveImageAsCommand = document.getElementById("context-saveimage");
saveImageAsCommand.doCommand();
yield showFilePickerPromise;
let contextMenu = document.getElementById("contentAreaContextMenu");
let popupHiddenPromise = BrowserTestUtils.waitForEvent(contextMenu, "popuphidden");
contextMenu.hidePopup();
yield popupHiddenPromise;
});

View file

@ -1,227 +0,0 @@
var gListener = null;
const kURL = "data:text/html;charset=utf-8,Caret browsing is fun.<input id='in'>";
const kPrefShortcutEnabled = "accessibility.browsewithcaret_shortcut.enabled";
const kPrefWarnOnEnable = "accessibility.warn_on_browsewithcaret";
const kPrefCaretBrowsingOn = "accessibility.browsewithcaret";
var oldPrefs = {};
for (let pref of [kPrefShortcutEnabled, kPrefWarnOnEnable, kPrefCaretBrowsingOn]) {
oldPrefs[pref] = Services.prefs.getBoolPref(pref);
}
Services.prefs.setBoolPref(kPrefShortcutEnabled, true);
Services.prefs.setBoolPref(kPrefWarnOnEnable, true);
Services.prefs.setBoolPref(kPrefCaretBrowsingOn, false);
registerCleanupFunction(function() {
for (let pref of [kPrefShortcutEnabled, kPrefWarnOnEnable, kPrefCaretBrowsingOn]) {
Services.prefs.setBoolPref(pref, oldPrefs[pref]);
}
});
// NB: not using BrowserTestUtils.domWindowOpened here because there's no way to
// undo waiting for a window open. If we don't want the window to be opened, and
// wait for it to verify that it indeed does not open, we need to be able to
// then "stop" waiting so that when we next *do* want it to open, our "old"
// listener doesn't fire and do things we don't want (like close the window...).
let gCaretPromptOpeningObserver;
function promiseCaretPromptOpened() {
return new Promise(resolve => {
function observer(subject, topic, data) {
if (topic == "domwindowopened") {
Services.ww.unregisterNotification(observer);
let win = subject.QueryInterface(Ci.nsIDOMWindow);
BrowserTestUtils.waitForEvent(win, "load", false, e => e.target.location.href != "about:blank").then(() => resolve(win));
gCaretPromptOpeningObserver = null;
}
}
Services.ww.registerNotification(observer);
gCaretPromptOpeningObserver = observer;
});
}
function hitF7(async = true) {
let f7 = () => EventUtils.sendKey("F7");
// Need to not stop execution inside this task:
if (async) {
executeSoon(f7);
} else {
f7();
}
}
function syncToggleCaretNoDialog(expected) {
let openedDialog = false;
promiseCaretPromptOpened().then(function(win) {
openedDialog = true;
win.close(); // This will eventually return focus here and allow the test to continue...
});
// Cause the dialog to appear sync, if it still does.
hitF7(false);
let expectedStr = expected ? "on." : "off.";
ok(!openedDialog, "Shouldn't open a dialog to turn caret browsing " + expectedStr);
// Need to clean up if the dialog wasn't opened, so the observer doesn't get
// re-triggered later on causing "issues".
if (!openedDialog) {
Services.ww.unregisterNotification(gCaretPromptOpeningObserver);
gCaretPromptOpeningObserver = null;
}
let prefVal = Services.prefs.getBoolPref(kPrefCaretBrowsingOn);
is(prefVal, expected, "Caret browsing should now be " + expectedStr);
}
function waitForFocusOnInput(browser)
{
return ContentTask.spawn(browser, null, function* () {
let textEl = content.document.getElementById("in");
return ContentTaskUtils.waitForCondition(() => {
return content.document.activeElement == textEl;
}, "Input should get focused.");
});
}
function focusInput(browser)
{
return ContentTask.spawn(browser, null, function* () {
let textEl = content.document.getElementById("in");
textEl.focus();
});
}
add_task(function* checkTogglingCaretBrowsing() {
let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, kURL);
yield focusInput(tab.linkedBrowser);
let promiseGotKey = promiseCaretPromptOpened();
hitF7();
let prompt = yield promiseGotKey;
let doc = prompt.document;
is(doc.documentElement.defaultButton, "cancel", "No button should be the default");
ok(!doc.getElementById("checkbox").checked, "Checkbox shouldn't be checked by default.");
let promiseDialogUnloaded = BrowserTestUtils.waitForEvent(prompt, "unload");
doc.documentElement.cancelDialog();
yield promiseDialogUnloaded;
info("Dialog unloaded");
yield waitForFocusOnInput(tab.linkedBrowser);
ok(!Services.prefs.getBoolPref(kPrefCaretBrowsingOn), "Caret browsing should still be off after cancelling the dialog.");
promiseGotKey = promiseCaretPromptOpened();
hitF7();
prompt = yield promiseGotKey;
doc = prompt.document;
is(doc.documentElement.defaultButton, "cancel", "No button should be the default");
ok(!doc.getElementById("checkbox").checked, "Checkbox shouldn't be checked by default.");
promiseDialogUnloaded = BrowserTestUtils.waitForEvent(prompt, "unload");
doc.documentElement.acceptDialog();
yield promiseDialogUnloaded;
info("Dialog unloaded");
yield waitForFocusOnInput(tab.linkedBrowser);
ok(Services.prefs.getBoolPref(kPrefCaretBrowsingOn), "Caret browsing should be on after accepting the dialog.");
syncToggleCaretNoDialog(false);
promiseGotKey = promiseCaretPromptOpened();
hitF7();
prompt = yield promiseGotKey;
doc = prompt.document;
is(doc.documentElement.defaultButton, "cancel", "No button should be the default");
ok(!doc.getElementById("checkbox").checked, "Checkbox shouldn't be checked by default.");
promiseDialogUnloaded = BrowserTestUtils.waitForEvent(prompt, "unload");
doc.documentElement.cancelDialog();
yield promiseDialogUnloaded;
info("Dialog unloaded");
yield waitForFocusOnInput(tab.linkedBrowser);
ok(!Services.prefs.getBoolPref(kPrefCaretBrowsingOn), "Caret browsing should still be off after cancelling the dialog.");
Services.prefs.setBoolPref(kPrefShortcutEnabled, true);
Services.prefs.setBoolPref(kPrefWarnOnEnable, true);
Services.prefs.setBoolPref(kPrefCaretBrowsingOn, false);
yield BrowserTestUtils.removeTab(tab);
});
add_task(function* toggleCheckboxNoCaretBrowsing() {
let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, kURL);
yield focusInput(tab.linkedBrowser);
let promiseGotKey = promiseCaretPromptOpened();
hitF7();
let prompt = yield promiseGotKey;
let doc = prompt.document;
is(doc.documentElement.defaultButton, "cancel", "No button should be the default");
let checkbox = doc.getElementById("checkbox");
ok(!checkbox.checked, "Checkbox shouldn't be checked by default.");
// Check the box:
checkbox.click();
let promiseDialogUnloaded = BrowserTestUtils.waitForEvent(prompt, "unload");
// Say no:
doc.documentElement.getButton("cancel").click();
yield promiseDialogUnloaded;
info("Dialog unloaded");
yield waitForFocusOnInput(tab.linkedBrowser);
ok(!Services.prefs.getBoolPref(kPrefCaretBrowsingOn), "Caret browsing should still be off.");
ok(!Services.prefs.getBoolPref(kPrefShortcutEnabled), "Shortcut should now be disabled.");
syncToggleCaretNoDialog(false);
ok(!Services.prefs.getBoolPref(kPrefShortcutEnabled), "Shortcut should still be disabled.");
Services.prefs.setBoolPref(kPrefShortcutEnabled, true);
Services.prefs.setBoolPref(kPrefWarnOnEnable, true);
Services.prefs.setBoolPref(kPrefCaretBrowsingOn, false);
yield BrowserTestUtils.removeTab(tab);
});
add_task(function* toggleCheckboxWantCaretBrowsing() {
let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, kURL);
yield focusInput(tab.linkedBrowser);
let promiseGotKey = promiseCaretPromptOpened();
hitF7();
let prompt = yield promiseGotKey;
let doc = prompt.document;
is(doc.documentElement.defaultButton, "cancel", "No button should be the default");
let checkbox = doc.getElementById("checkbox");
ok(!checkbox.checked, "Checkbox shouldn't be checked by default.");
// Check the box:
checkbox.click();
let promiseDialogUnloaded = BrowserTestUtils.waitForEvent(prompt, "unload");
// Say yes:
doc.documentElement.acceptDialog();
yield promiseDialogUnloaded;
info("Dialog unloaded");
yield waitForFocusOnInput(tab.linkedBrowser);
ok(Services.prefs.getBoolPref(kPrefCaretBrowsingOn), "Caret browsing should now be on.");
ok(Services.prefs.getBoolPref(kPrefShortcutEnabled), "Shortcut should still be enabled.");
ok(!Services.prefs.getBoolPref(kPrefWarnOnEnable), "Should no longer warn when enabling.");
syncToggleCaretNoDialog(false);
syncToggleCaretNoDialog(true);
syncToggleCaretNoDialog(false);
Services.prefs.setBoolPref(kPrefShortcutEnabled, true);
Services.prefs.setBoolPref(kPrefWarnOnEnable, true);
Services.prefs.setBoolPref(kPrefCaretBrowsingOn, false);
yield BrowserTestUtils.removeTab(tab);
});

View file

@ -1,249 +0,0 @@
XPCOMUtils.defineLazyModuleGetter(this, "Promise",
"resource://gre/modules/Promise.jsm");
Components.utils.import("resource://gre/modules/Timer.jsm", this);
const TEST_PAGE_URI = "data:text/html;charset=utf-8,The letter s.";
// Using 'javascript' schema to bypass E10SUtils.canLoadURIInProcess, because
// it does not allow 'data:' URI to be loaded in the parent process.
const E10S_PARENT_TEST_PAGE_URI = "javascript:document.write('The letter s.');";
/**
* Makes sure that the findbar hotkeys (' and /) event listeners
* are added to the system event group and do not get blocked
* by calling stopPropagation on a keypress event on a page.
*/
add_task(function* test_hotkey_event_propagation() {
info("Ensure hotkeys are not affected by stopPropagation.");
// Opening new tab
let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_PAGE_URI);
let browser = gBrowser.getBrowserForTab(tab);
let findbar = gBrowser.getFindBar();
// Pressing these keys open the findbar.
const HOTKEYS = ["/", "'"];
// Checking if findbar appears when any hotkey is pressed.
for (let key of HOTKEYS) {
is(findbar.hidden, true, "Findbar is hidden now.");
gBrowser.selectedTab = tab;
yield SimpleTest.promiseFocus(gBrowser.selectedBrowser);
yield BrowserTestUtils.sendChar(key, browser);
is(findbar.hidden, false, "Findbar should not be hidden.");
yield closeFindbarAndWait(findbar);
}
// Stop propagation for all keyboard events.
let frameScript = () => {
const stopPropagation = e => e.stopImmediatePropagation();
let window = content.document.defaultView;
window.removeEventListener("keydown", stopPropagation);
window.removeEventListener("keypress", stopPropagation);
window.removeEventListener("keyup", stopPropagation);
};
let mm = browser.messageManager;
mm.loadFrameScript("data:,(" + frameScript.toString() + ")();", false);
// Checking if findbar still appears when any hotkey is pressed.
for (let key of HOTKEYS) {
is(findbar.hidden, true, "Findbar is hidden now.");
gBrowser.selectedTab = tab;
yield SimpleTest.promiseFocus(gBrowser.selectedBrowser);
yield BrowserTestUtils.sendChar(key, browser);
is(findbar.hidden, false, "Findbar should not be hidden.");
yield closeFindbarAndWait(findbar);
}
gBrowser.removeTab(tab);
});
add_task(function* test_not_found() {
info("Check correct 'Phrase not found' on new tab");
let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_PAGE_URI);
// Search for the first word.
yield promiseFindFinished("--- THIS SHOULD NEVER MATCH ---", false);
let findbar = gBrowser.getFindBar();
is(findbar._findStatusDesc.textContent, findbar._notFoundStr,
"Findbar status text should be 'Phrase not found'");
gBrowser.removeTab(tab);
});
add_task(function* test_found() {
let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_PAGE_URI);
// Search for a string that WILL be found, with 'Highlight All' on
yield promiseFindFinished("S", true);
ok(!gBrowser.getFindBar()._findStatusDesc.textContent,
"Findbar status should be empty");
gBrowser.removeTab(tab);
});
// Setting first findbar to case-sensitive mode should not affect
// new tab find bar.
add_task(function* test_tabwise_case_sensitive() {
let tab1 = yield BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_PAGE_URI);
let findbar1 = gBrowser.getFindBar();
let tab2 = yield BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_PAGE_URI);
let findbar2 = gBrowser.getFindBar();
// Toggle case sensitivity for first findbar
findbar1.getElement("find-case-sensitive").click();
gBrowser.selectedTab = tab1;
// Not found for first tab.
yield promiseFindFinished("S", true);
is(findbar1._findStatusDesc.textContent, findbar1._notFoundStr,
"Findbar status text should be 'Phrase not found'");
gBrowser.selectedTab = tab2;
// But it didn't affect the second findbar.
yield promiseFindFinished("S", true);
ok(!findbar2._findStatusDesc.textContent, "Findbar status should be empty");
gBrowser.removeTab(tab1);
gBrowser.removeTab(tab2);
});
/**
* Navigating from a web page (for example mozilla.org) to an internal page
* (like about:addons) might trigger a change of browser's remoteness.
* 'Remoteness change' means that rendering page content moves from child
* process into the parent process or the other way around.
* This test ensures that findbar properly handles such a change.
*/
add_task(function* test_reinitialization_at_remoteness_change() {
// This test only makes sence in e10s evironment.
if (!gMultiProcessBrowser) {
info("Skipping this test because of non-e10s environment.");
return;
}
info("Ensure findbar re-initialization at remoteness change.");
// Load a remote page and trigger findbar construction.
let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_PAGE_URI);
let browser = gBrowser.getBrowserForTab(tab);
let findbar = gBrowser.getFindBar();
// Findbar should operate normally.
yield promiseFindFinished("z", false);
is(findbar._findStatusDesc.textContent, findbar._notFoundStr,
"Findbar status text should be 'Phrase not found'");
yield promiseFindFinished("s", false);
ok(!findbar._findStatusDesc.textContent, "Findbar status should be empty");
// Moving browser into the parent process and reloading sample data.
ok(browser.isRemoteBrowser, "Browser should be remote now.");
yield promiseRemotenessChange(tab, false);
yield BrowserTestUtils.loadURI(browser, E10S_PARENT_TEST_PAGE_URI);
ok(!browser.isRemoteBrowser, "Browser should not be remote any more.");
// Findbar should keep operating normally after remoteness change.
yield promiseFindFinished("z", false);
is(findbar._findStatusDesc.textContent, findbar._notFoundStr,
"Findbar status text should be 'Phrase not found'");
yield promiseFindFinished("s", false);
ok(!findbar._findStatusDesc.textContent, "Findbar status should be empty");
yield BrowserTestUtils.removeTab(tab);
});
/**
* Ensure that the initial typed characters aren't lost immediately after
* opening the find bar.
*/
add_task(function* () {
// This test only makes sence in e10s evironment.
if (!gMultiProcessBrowser) {
info("Skipping this test because of non-e10s environment.");
return;
}
let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_PAGE_URI);
let browser = tab.linkedBrowser;
ok(!gFindBarInitialized, "findbar isn't initialized yet");
let findBar = gFindBar;
let initialValue = findBar._findField.value;
EventUtils.synthesizeKey("f", { accelKey: true }, window);
let promises = [
BrowserTestUtils.sendChar("a", browser),
BrowserTestUtils.sendChar("b", browser),
BrowserTestUtils.sendChar("c", browser)
];
isnot(document.activeElement, findBar._findField.inputField,
"findbar is not yet focused");
is(findBar._findField.value, initialValue, "still has initial find query");
yield Promise.all(promises);
is(document.activeElement, findBar._findField.inputField,
"findbar is now focused");
is(findBar._findField.value, "abc", "abc fully entered as find query");
yield BrowserTestUtils.removeTab(tab);
});
function promiseFindFinished(searchText, highlightOn) {
let deferred = Promise.defer();
let findbar = gBrowser.getFindBar();
findbar.startFind(findbar.FIND_NORMAL);
let highlightElement = findbar.getElement("highlight");
if (highlightElement.checked != highlightOn)
highlightElement.click();
executeSoon(() => {
findbar._findField.value = searchText;
let resultListener;
// When highlighting is on the finder sends a second "FOUND" message after
// the search wraps. This causes timing problems with e10s. waitMore
// forces foundOrTimeout wait for the second "FOUND" message before
// resolving the promise.
let waitMore = highlightOn;
let findTimeout = setTimeout(() => foundOrTimedout(null), 2000);
let foundOrTimedout = function(aData) {
if (aData !== null && waitMore) {
waitMore = false;
return;
}
if (aData === null)
info("Result listener not called, timeout reached.");
clearTimeout(findTimeout);
findbar.browser.finder.removeResultListener(resultListener);
deferred.resolve();
}
resultListener = {
onFindResult: foundOrTimedout
};
findbar.browser.finder.addResultListener(resultListener);
findbar._find();
});
return deferred.promise;
}
function promiseRemotenessChange(tab, shouldBeRemote) {
return new Promise((resolve) => {
let browser = gBrowser.getBrowserForTab(tab);
tab.addEventListener("TabRemotenessChange", function listener() {
tab.removeEventListener("TabRemotenessChange", listener);
resolve();
});
gBrowser.updateBrowserRemoteness(browser, shouldBeRemote);
});
}

View file

@ -1,72 +0,0 @@
function LocationChangeListener(browser) {
this.browser = browser;
browser.addProgressListener(this);
}
LocationChangeListener.prototype = {
wasSynthetic: false,
browser: null,
destroy: function() {
this.browser.removeProgressListener(this);
},
onLocationChange: function(webProgress, request, location, flags) {
this.wasSynthetic = this.browser.isSyntheticDocument;
},
QueryInterface: XPCOMUtils.generateQI([Ci.nsIWebProgressListener,
Ci.nsISupportsWeakReference])
}
const FILES = gTestPath.replace("browser_isSynthetic.js", "")
.replace("chrome://mochitests/content/", "http://example.com/");
function waitForPageShow(browser) {
return ContentTask.spawn(browser, null, function*() {
Cu.import("resource://gre/modules/PromiseUtils.jsm");
yield new Promise(resolve => {
let listener = () => {
removeEventListener("pageshow", listener, true);
resolve();
}
addEventListener("pageshow", listener, true);
});
});
}
add_task(function*() {
let tab = gBrowser.addTab("about:blank");
let browser = tab.linkedBrowser;
yield BrowserTestUtils.browserLoaded(browser);
let listener = new LocationChangeListener(browser);
is(browser.isSyntheticDocument, false, "Should not be synthetic");
let loadPromise = waitForPageShow(browser);
browser.loadURI("data:text/html;charset=utf-8,<html/>");
yield loadPromise;
is(listener.wasSynthetic, false, "Should not be synthetic");
is(browser.isSyntheticDocument, false, "Should not be synthetic");
loadPromise = waitForPageShow(browser);
browser.loadURI(FILES + "empty.png");
yield loadPromise;
is(listener.wasSynthetic, true, "Should be synthetic");
is(browser.isSyntheticDocument, true, "Should be synthetic");
loadPromise = waitForPageShow(browser);
browser.goBack();
yield loadPromise;
is(listener.wasSynthetic, false, "Should not be synthetic");
is(browser.isSyntheticDocument, false, "Should not be synthetic");
loadPromise = waitForPageShow(browser);
browser.goForward();
yield loadPromise;
is(listener.wasSynthetic, true, "Should be synthetic");
is(browser.isSyntheticDocument, true, "Should be synthetic");
listener.destroy();
gBrowser.removeTab(tab);
});

View file

@ -1,120 +0,0 @@
add_task(function * ()
{
const kPrefName_AutoScroll = "general.autoScroll";
Services.prefs.setBoolPref(kPrefName_AutoScroll, true);
const kNoKeyEvents = 0;
const kKeyDownEvent = 1;
const kKeyPressEvent = 2;
const kKeyUpEvent = 4;
const kAllKeyEvents = 7;
var expectedKeyEvents;
var dispatchedKeyEvents;
var key;
var root;
/**
* Encapsulates EventUtils.sendChar().
*/
function sendChar(aChar)
{
key = aChar;
dispatchedKeyEvents = kNoKeyEvents;
EventUtils.sendChar(key);
is(dispatchedKeyEvents, expectedKeyEvents,
"unexpected key events were dispatched or not dispatched: " + key);
}
/**
* Encapsulates EventUtils.sendKey().
*/
function sendKey(aKey)
{
key = aKey;
dispatchedKeyEvents = kNoKeyEvents;
EventUtils.sendKey(key);
is(dispatchedKeyEvents, expectedKeyEvents,
"unexpected key events were dispatched or not dispatched: " + key);
}
function onKey(aEvent)
{
// if (aEvent.target != root && aEvent.target != root.ownerDocument.body) {
// ok(false, "unknown target: " + aEvent.target.tagName);
// return;
// }
var keyFlag;
switch (aEvent.type) {
case "keydown":
keyFlag = kKeyDownEvent;
break;
case "keypress":
keyFlag = kKeyPressEvent;
break;
case "keyup":
keyFlag = kKeyUpEvent;
break;
default:
ok(false, "Unknown events: " + aEvent.type);
return;
}
dispatchedKeyEvents |= keyFlag;
is(keyFlag, expectedKeyEvents & keyFlag, aEvent.type + " fired: " + key);
}
var dataUri = 'data:text/html,<body style="height:10000px;"></body>';
let loadedPromise = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
gBrowser.loadURI(dataUri);
yield loadedPromise;
yield SimpleTest.promiseFocus(gBrowser.selectedBrowser);
window.addEventListener("keydown", onKey, false);
window.addEventListener("keypress", onKey, false);
window.addEventListener("keyup", onKey, false);
// Test whether the key events are handled correctly under normal condition
expectedKeyEvents = kAllKeyEvents;
sendChar("A");
// Start autoscrolling by middle button click on the page
let shownPromise = BrowserTestUtils.waitForEvent(window, "popupshown", false,
event => event.originalTarget.className == "autoscroller");
yield BrowserTestUtils.synthesizeMouseAtPoint(10, 10, { button: 1 },
gBrowser.selectedBrowser);
yield shownPromise;
// Most key events should be eaten by the browser.
expectedKeyEvents = kNoKeyEvents;
sendChar("A");
sendKey("DOWN");
sendKey("RETURN");
sendKey("RETURN");
sendKey("HOME");
sendKey("END");
sendKey("TAB");
sendKey("RETURN");
// Finish autoscrolling by ESC key. Note that only keydown and keypress
// events are eaten because keyup event is fired *after* the autoscrolling
// is finished.
expectedKeyEvents = kKeyUpEvent;
sendKey("ESCAPE");
// Test whether the key events are handled correctly under normal condition
expectedKeyEvents = kAllKeyEvents;
sendChar("A");
window.removeEventListener("keydown", onKey, false);
window.removeEventListener("keypress", onKey, false);
window.removeEventListener("keyup", onKey, false);
// restore the changed prefs
if (Services.prefs.prefHasUserValue(kPrefName_AutoScroll))
Services.prefs.clearUserPref(kPrefName_AutoScroll);
finish();
});

View file

@ -1,38 +0,0 @@
add_task(function* () {
yield BrowserTestUtils.withNewTab({gBrowser, url: "about:config"}, function*(browser) {
let newTabURL = "http://www.example.com/";
yield ContentTask.spawn(browser, newTabURL, function*(newTabURL) {
let doc = content.document;
let label = doc.createElement("label");
label.href = newTabURL;
label.id = "textlink-test";
label.className = "text-link";
label.textContent = "click me";
doc.documentElement.append(label);
});
// Test that click will open tab in foreground.
let awaitNewTab = BrowserTestUtils.waitForNewTab(gBrowser, newTabURL);
yield BrowserTestUtils.synthesizeMouseAtCenter("#textlink-test", {}, browser);
let newTab = yield awaitNewTab;
is(newTab.linkedBrowser, gBrowser.selectedBrowser, "selected tab should be example page");
yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
// Test that ctrl+shift+click/meta+shift+click will open tab in background.
awaitNewTab = BrowserTestUtils.waitForNewTab(gBrowser, newTabURL);
yield BrowserTestUtils.synthesizeMouseAtCenter("#textlink-test",
{ctrlKey: true, metaKey: true, shiftKey: true},
browser);
yield awaitNewTab;
is(gBrowser.selectedBrowser, browser, "selected tab should be original tab");
yield BrowserTestUtils.removeTab(gBrowser.tabs[gBrowser.tabs.length - 1]);
// Middle-clicking should open tab in foreground.
awaitNewTab = BrowserTestUtils.waitForNewTab(gBrowser, newTabURL);
yield BrowserTestUtils.synthesizeMouseAtCenter("#textlink-test",
{button: 1}, browser);
newTab = yield awaitNewTab;
is(newTab.linkedBrowser, gBrowser.selectedBrowser, "selected tab should be example page");
yield BrowserTestUtils.removeTab(gBrowser.tabs[gBrowser.tabs.length - 1]);
});
});

View file

@ -1,30 +0,0 @@
const PAGE = "https://example.com/browser/toolkit/content/tests/browser/file_mediaPlayback.html";
const FRAME = "https://example.com/browser/toolkit/content/tests/browser/file_mediaPlaybackFrame.html";
function wait_for_event(browser, event) {
return BrowserTestUtils.waitForEvent(browser, event, false, (event) => {
is(event.originalTarget, browser, "Event must be dispatched to correct browser.");
ok(!event.cancelable, "The event should not be cancelable");
return true;
});
}
function* test_on_browser(url, browser) {
browser.loadURI(url);
yield wait_for_event(browser, "DOMAudioPlaybackStarted");
yield wait_for_event(browser, "DOMAudioPlaybackStopped");
}
add_task(function* test_page() {
yield BrowserTestUtils.withNewTab({
gBrowser,
url: "about:blank",
}, test_on_browser.bind(undefined, PAGE));
});
add_task(function* test_frame() {
yield BrowserTestUtils.withNewTab({
gBrowser,
url: "about:blank",
}, test_on_browser.bind(undefined, FRAME));
});

View file

@ -1,104 +0,0 @@
const PAGE = "https://example.com/browser/toolkit/content/tests/browser/file_mediaPlayback2.html";
const FRAME = "https://example.com/browser/toolkit/content/tests/browser/file_mediaPlaybackFrame2.html";
function wait_for_event(browser, event) {
return BrowserTestUtils.waitForEvent(browser, event, false, (event) => {
is(event.originalTarget, browser, "Event must be dispatched to correct browser.");
return true;
});
}
function* test_audio_in_browser() {
function get_audio_element() {
var doc = content.document;
var list = doc.getElementsByTagName('audio');
if (list.length == 1) {
return list[0];
}
// iframe?
list = doc.getElementsByTagName('iframe');
var iframe = list[0];
list = iframe.contentDocument.getElementsByTagName('audio');
return list[0];
}
var audio = get_audio_element();
return {
computedVolume: audio.computedVolume,
computedMuted: audio.computedMuted
}
}
function* test_on_browser(url, browser) {
browser.loadURI(url);
yield wait_for_event(browser, "DOMAudioPlaybackStarted");
var result = yield ContentTask.spawn(browser, null, test_audio_in_browser);
is(result.computedVolume, 1, "Audio volume is 1");
is(result.computedMuted, false, "Audio is not muted");
ok(!browser.audioMuted, "Audio should not be muted by default");
browser.mute();
ok(browser.audioMuted, "Audio should be muted now");
yield wait_for_event(browser, "DOMAudioPlaybackStopped");
result = yield ContentTask.spawn(browser, null, test_audio_in_browser);
is(result.computedVolume, 0, "Audio volume is 0 when muted");
is(result.computedMuted, true, "Audio is muted");
}
function* test_visibility(url, browser) {
browser.loadURI(url);
yield wait_for_event(browser, "DOMAudioPlaybackStarted");
var result = yield ContentTask.spawn(browser, null, test_audio_in_browser);
is(result.computedVolume, 1, "Audio volume is 1");
is(result.computedMuted, false, "Audio is not muted");
yield BrowserTestUtils.withNewTab({
gBrowser,
url: "about:blank",
}, function() {});
ok(!browser.audioMuted, "Audio should not be muted by default");
browser.mute();
ok(browser.audioMuted, "Audio should be muted now");
yield wait_for_event(browser, "DOMAudioPlaybackStopped");
result = yield ContentTask.spawn(browser, null, test_audio_in_browser);
is(result.computedVolume, 0, "Audio volume is 0 when muted");
is(result.computedMuted, true, "Audio is muted");
}
add_task(function*() {
yield new Promise((resolve) => {
SpecialPowers.pushPrefEnv({"set": [
["media.useAudioChannelService.testing", true]
]}, resolve);
});
});
add_task(function* test_page() {
yield BrowserTestUtils.withNewTab({
gBrowser,
url: "about:blank",
}, test_on_browser.bind(undefined, PAGE));
});
add_task(function* test_frame() {
yield BrowserTestUtils.withNewTab({
gBrowser,
url: "about:blank",
}, test_on_browser.bind(undefined, FRAME));
});
add_task(function* test_frame() {
yield BrowserTestUtils.withNewTab({
gBrowser,
url: "about:blank",
}, test_visibility.bind(undefined, PAGE));
});

View file

@ -1,191 +0,0 @@
const PAGE = "https://example.com/browser/toolkit/content/tests/browser/file_mediaPlayback2.html";
var SuspendedType = {
NONE_SUSPENDED : 0,
SUSPENDED_PAUSE : 1,
SUSPENDED_BLOCK : 2,
SUSPENDED_PAUSE_DISPOSABLE : 3
};
function wait_for_event(browser, event) {
return BrowserTestUtils.waitForEvent(browser, event, false, (event) => {
is(event.originalTarget, browser, "Event must be dispatched to correct browser.");
return true;
});
}
function check_audio_onplay() {
var list = content.document.getElementsByTagName('audio');
if (list.length != 1) {
ok(false, "There should be only one audio element in page!")
}
var audio = list[0];
return new Promise((resolve, reject) => {
audio.onplay = () => {
ok(needToReceiveOnPlay, "Should not receive play event!");
this.onplay = null;
reject();
};
audio.pause();
audio.play();
setTimeout(() => {
ok(true, "Doesn't receive play event when media was blocked.");
audio.onplay = null;
resolve();
}, 1000)
});
}
function check_audio_suspended(suspendedType) {
var list = content.document.getElementsByTagName('audio');
if (list.length != 1) {
ok(false, "There should be only one audio element in page!")
}
var audio = list[0];
is(audio.computedSuspended, suspendedType,
"The suspended state of MediaElement is correct.");
}
function check_audio_pause_state(expectedPauseState) {
var list = content.document.getElementsByTagName('audio');
if (list.length != 1) {
ok(false, "There should be only one audio element in page!")
}
var audio = list[0];
if (expectedPauseState) {
is(audio.paused, true, "Audio is paused correctly.");
} else {
is(audio.paused, false, "Audio is resumed correctly.");
}
}
function* suspended_pause(url, browser) {
info("### Start test for suspended-pause ###");
browser.loadURI(url);
info("- page should have playing audio -");
yield wait_for_event(browser, "DOMAudioPlaybackStarted");
info("- the suspended state of audio should be non-suspened -");
yield ContentTask.spawn(browser, SuspendedType.NONE_SUSPENDED,
check_audio_suspended);
info("- pause playing audio -");
browser.pauseMedia(false /* non-disposable */);
yield ContentTask.spawn(browser, true /* expect for pause */,
check_audio_pause_state);
yield ContentTask.spawn(browser, SuspendedType.SUSPENDED_PAUSE,
check_audio_suspended);
info("- resume paused audio -");
browser.resumeMedia();
yield ContentTask.spawn(browser, false /* expect for playing */,
check_audio_pause_state);
yield ContentTask.spawn(browser, SuspendedType.NONE_SUSPENDED,
check_audio_suspended);
}
function* suspended_pause_disposable(url, browser) {
info("### Start test for suspended-pause-disposable ###");
browser.loadURI(url);
info("- page should have playing audio -");
yield wait_for_event(browser, "DOMAudioPlaybackStarted");
info("- the suspended state of audio should be non-suspened -");
yield ContentTask.spawn(browser, SuspendedType.NONE_SUSPENDED,
check_audio_suspended);
info("- pause playing audio -");
browser.pauseMedia(true /* disposable */);
yield ContentTask.spawn(browser, true /* expect for pause */,
check_audio_pause_state);
yield ContentTask.spawn(browser, SuspendedType.SUSPENDED_PAUSE_DISPOSABLE,
check_audio_suspended);
info("- resume paused audio -");
browser.resumeMedia();
yield ContentTask.spawn(browser, false /* expect for playing */,
check_audio_pause_state);
yield ContentTask.spawn(browser, SuspendedType.NONE_SUSPENDED,
check_audio_suspended);
}
function* suspended_stop_disposable(url, browser) {
info("### Start test for suspended-stop-disposable ###");
browser.loadURI(url);
info("- page should have playing audio -");
yield wait_for_event(browser, "DOMAudioPlaybackStarted");
info("- the suspended state of audio should be non-suspened -");
yield ContentTask.spawn(browser, SuspendedType.NONE_SUSPENDED,
check_audio_suspended);
info("- stop playing audio -");
browser.stopMedia();
yield wait_for_event(browser, "DOMAudioPlaybackStopped");
yield ContentTask.spawn(browser, SuspendedType.NONE_SUSPENDED,
check_audio_suspended);
}
function* suspended_block(url, browser) {
info("### Start test for suspended-block ###");
browser.loadURI(url);
info("- page should have playing audio -");
yield wait_for_event(browser, "DOMAudioPlaybackStarted");
info("- block playing audio -");
browser.blockMedia();
yield ContentTask.spawn(browser, SuspendedType.SUSPENDED_BLOCK,
check_audio_suspended);
yield ContentTask.spawn(browser, null,
check_audio_onplay);
info("- resume blocked audio -");
browser.resumeMedia();
yield ContentTask.spawn(browser, SuspendedType.NONE_SUSPENDED,
check_audio_suspended);
}
add_task(function* setup_test_preference() {
yield new Promise(resolve => {
SpecialPowers.pushPrefEnv({"set": [
["media.useAudioChannelService.testing", true]
]}, resolve);
});
});
add_task(function* test_suspended_pause() {
yield BrowserTestUtils.withNewTab({
gBrowser,
url: "about:blank"
}, suspended_pause.bind(this, PAGE));
});
add_task(function* test_suspended_pause_disposable() {
yield BrowserTestUtils.withNewTab({
gBrowser,
url: "about:blank"
}, suspended_pause_disposable.bind(this, PAGE));
});
add_task(function* test_suspended_stop_disposable() {
yield BrowserTestUtils.withNewTab({
gBrowser,
url: "about:blank"
}, suspended_stop_disposable.bind(this, PAGE));
});
add_task(function* test_suspended_block() {
yield BrowserTestUtils.withNewTab({
gBrowser,
url: "about:blank"
}, suspended_block.bind(this, PAGE));
});

View file

@ -1,311 +0,0 @@
const PAGE = "https://example.com/browser/toolkit/content/tests/browser/file_multipleAudio.html";
var SuspendedType = {
NONE_SUSPENDED : 0,
SUSPENDED_PAUSE : 1,
SUSPENDED_BLOCK : 2,
SUSPENDED_PAUSE_DISPOSABLE : 3
};
function wait_for_event(browser, event) {
return BrowserTestUtils.waitForEvent(browser, event, false, (event) => {
is(event.originalTarget, browser, "Event must be dispatched to correct browser.");
return true;
});
}
function check_all_audio_suspended(suspendedType) {
var autoPlay = content.document.getElementById('autoplay');
var nonAutoPlay = content.document.getElementById('nonautoplay');
if (!autoPlay || !nonAutoPlay) {
ok(false, "Can't get the audio element!");
}
is(autoPlay.computedSuspended, suspendedType,
"The suspeded state of autoplay audio is correct.");
is(nonAutoPlay.computedSuspended, suspendedType,
"The suspeded state of non-autoplay audio is correct.");
}
function check_autoplay_audio_suspended(suspendedType) {
var autoPlay = content.document.getElementById('autoplay');
if (!autoPlay) {
ok(false, "Can't get the audio element!");
}
is(autoPlay.computedSuspended, suspendedType,
"The suspeded state of autoplay audio is correct.");
}
function check_nonautoplay_audio_suspended(suspendedType) {
var nonAutoPlay = content.document.getElementById('nonautoplay');
if (!nonAutoPlay) {
ok(false, "Can't get the audio element!");
}
is(nonAutoPlay.computedSuspended, suspendedType,
"The suspeded state of non-autoplay audio is correct.");
}
function check_autoplay_audio_pause_state(expectedPauseState) {
var autoPlay = content.document.getElementById('autoplay');
if (!autoPlay) {
ok(false, "Can't get the audio element!");
}
if (autoPlay.paused == expectedPauseState) {
if (expectedPauseState) {
ok(true, "Audio is paused correctly.");
} else {
ok(true, "Audio is resumed correctly.");
}
} else if (expectedPauseState) {
autoPlay.onpause = function () {
autoPlay.onpause = null;
ok(true, "Audio is paused correctly, checking from onpause.");
}
} else {
autoPlay.onplay = function () {
autoPlay.onplay = null;
ok(true, "Audio is resumed correctly, checking from onplay.");
}
}
}
function play_nonautoplay_audio_should_be_paused() {
var nonAutoPlay = content.document.getElementById('nonautoplay');
if (!nonAutoPlay) {
ok(false, "Can't get the audio element!");
}
nonAutoPlay.play();
return new Promise(resolve => {
nonAutoPlay.onpause = function () {
nonAutoPlay.onpause = null;
is(nonAutoPlay.ended, false, "Audio can't be playback.");
resolve();
}
});
}
function all_audio_onresume() {
var autoPlay = content.document.getElementById('autoplay');
var nonAutoPlay = content.document.getElementById('nonautoplay');
if (!autoPlay || !nonAutoPlay) {
ok(false, "Can't get the audio element!");
}
is(autoPlay.paused, false, "Autoplay audio is resumed.");
is(nonAutoPlay.paused, false, "Non-AutoPlay audio is resumed.");
}
function all_audio_onpause() {
var autoPlay = content.document.getElementById('autoplay');
var nonAutoPlay = content.document.getElementById('nonautoplay');
if (!autoPlay || !nonAutoPlay) {
ok(false, "Can't get the audio element!");
}
is(autoPlay.paused, true, "Autoplay audio is paused.");
is(nonAutoPlay.paused, true, "Non-AutoPlay audio is paused.");
}
function play_nonautoplay_audio_should_play_until_ended() {
var nonAutoPlay = content.document.getElementById('nonautoplay');
if (!nonAutoPlay) {
ok(false, "Can't get the audio element!");
}
nonAutoPlay.play();
return new Promise(resolve => {
nonAutoPlay.onended = function () {
nonAutoPlay.onended = null;
ok(true, "Audio can be playback until ended.");
resolve();
}
});
}
function no_audio_resumed() {
var autoPlay = content.document.getElementById('autoplay');
var nonAutoPlay = content.document.getElementById('nonautoplay');
if (!autoPlay || !nonAutoPlay) {
ok(false, "Can't get the audio element!");
}
is(autoPlay.paused && nonAutoPlay.paused, true, "No audio was resumed.");
}
function play_nonautoplay_audio_should_be_blocked(suspendedType) {
var nonAutoPlay = content.document.getElementById('nonautoplay');
if (!nonAutoPlay) {
ok(false, "Can't get the audio element!");
}
nonAutoPlay.play();
ok(nonAutoPlay.paused, "The blocked audio can't be playback.");
}
function* suspended_pause(url, browser) {
info("### Start test for suspended-pause ###");
browser.loadURI(url);
info("- page should have playing audio -");
yield wait_for_event(browser, "DOMAudioPlaybackStarted");
info("- the default suspended state of all audio should be non-suspened-");
yield ContentTask.spawn(browser, SuspendedType.NONE_SUSPENDED,
check_all_audio_suspended);
info("- pause all audio in the page -");
browser.pauseMedia(false /* non-disposable */);
yield ContentTask.spawn(browser, true /* expect for pause */,
check_autoplay_audio_pause_state);
yield ContentTask.spawn(browser, SuspendedType.SUSPENDED_PAUSE,
check_autoplay_audio_suspended);
yield ContentTask.spawn(browser, SuspendedType.NONE_SUSPENDED,
check_nonautoplay_audio_suspended);
info("- no audio can be playback during suspended-paused -");
yield ContentTask.spawn(browser, null,
play_nonautoplay_audio_should_be_paused);
yield ContentTask.spawn(browser, SuspendedType.SUSPENDED_PAUSE,
check_nonautoplay_audio_suspended);
info("- both audio should be resumed at the same time -");
browser.resumeMedia();
yield ContentTask.spawn(browser, null,
all_audio_onresume);
yield ContentTask.spawn(browser, SuspendedType.NONE_SUSPENDED,
check_all_audio_suspended);
info("- both audio should be paused at the same time -");
browser.pauseMedia(false /* non-disposable */);
yield ContentTask.spawn(browser, null, all_audio_onpause);
}
function* suspended_pause_disposable(url, browser) {
info("### Start test for suspended-pause-disposable ###");
browser.loadURI(url);
info("- page should have playing audio -");
yield wait_for_event(browser, "DOMAudioPlaybackStarted");
info("- the default suspended state of all audio should be non-suspened -");
yield ContentTask.spawn(browser, SuspendedType.NONE_SUSPENDED,
check_all_audio_suspended);
info("- only pause playing audio in the page -");
browser.pauseMedia(true /* non-disposable */);
yield ContentTask.spawn(browser, true /* expect for pause */,
check_autoplay_audio_pause_state);
yield ContentTask.spawn(browser, SuspendedType.SUSPENDED_PAUSE_DISPOSABLE,
check_autoplay_audio_suspended);
yield ContentTask.spawn(browser, SuspendedType.NONE_SUSPENDED,
check_nonautoplay_audio_suspended);
info("- new playing audio should be playback correctly -");
yield ContentTask.spawn(browser, null,
play_nonautoplay_audio_should_play_until_ended);
info("- should only resume one audio -");
browser.resumeMedia();
yield ContentTask.spawn(browser, false /* expect for playing */,
check_autoplay_audio_pause_state);
yield ContentTask.spawn(browser, SuspendedType.NONE_SUSPENDED,
check_all_audio_suspended);
}
function* suspended_stop_disposable(url, browser) {
info("### Start test for suspended-stop-disposable ###");
browser.loadURI(url);
info("- page should have playing audio -");
yield wait_for_event(browser, "DOMAudioPlaybackStarted");
info("- the default suspended state of all audio should be non-suspened -");
yield ContentTask.spawn(browser, SuspendedType.NONE_SUSPENDED,
check_all_audio_suspended);
info("- only stop playing audio in the page -");
browser.stopMedia();
yield wait_for_event(browser, "DOMAudioPlaybackStopped");
yield ContentTask.spawn(browser, true /* expect for pause */,
check_autoplay_audio_pause_state);
yield ContentTask.spawn(browser, SuspendedType.NONE_SUSPENDED,
check_all_audio_suspended);
info("- new playing audio should be playback correctly -");
yield ContentTask.spawn(browser, null,
play_nonautoplay_audio_should_play_until_ended);
info("- no any audio can be resumed by page -");
browser.resumeMedia();
yield ContentTask.spawn(browser, null, no_audio_resumed);
yield ContentTask.spawn(browser, SuspendedType.NONE_SUSPENDED,
check_all_audio_suspended);
}
function* suspended_block(url, browser) {
info("### Start test for suspended-block ###");
browser.loadURI(url);
info("- page should have playing audio -");
yield wait_for_event(browser, "DOMAudioPlaybackStarted");
info("- the default suspended state of all audio should be non-suspened-");
yield ContentTask.spawn(browser, SuspendedType.NONE_SUSPENDED,
check_all_audio_suspended);
info("- block autoplay audio -");
browser.blockMedia();
yield ContentTask.spawn(browser, SuspendedType.SUSPENDED_BLOCK,
check_autoplay_audio_suspended);
yield ContentTask.spawn(browser, SuspendedType.NONE_SUSPENDED,
check_nonautoplay_audio_suspended);
info("- no audio can be playback during suspended-block -");
yield ContentTask.spawn(browser, SuspendedType.SUSPENDED_BLOCK,
play_nonautoplay_audio_should_be_blocked);
info("- both audio should be resumed at the same time -");
browser.resumeMedia();
yield ContentTask.spawn(browser, SuspendedType.NONE_SUSPENDED,
check_all_audio_suspended);
}
add_task(function* setup_test_preference() {
yield new Promise(resolve => {
SpecialPowers.pushPrefEnv({"set": [
["media.useAudioChannelService.testing", true]
]}, resolve);
});
});
add_task(function* test_suspended_pause() {
yield BrowserTestUtils.withNewTab({
gBrowser,
url: "about:blank"
}, suspended_pause.bind(this, PAGE));
});
add_task(function* test_suspended_pause_disposable() {
yield BrowserTestUtils.withNewTab({
gBrowser,
url: "about:blank"
}, suspended_pause_disposable.bind(this, PAGE));
});
add_task(function* test_suspended_stop_disposable() {
yield BrowserTestUtils.withNewTab({
gBrowser,
url: "about:blank"
}, suspended_stop_disposable.bind(this, PAGE));
});
add_task(function* test_suspended_block() {
yield BrowserTestUtils.withNewTab({
gBrowser,
url: "about:blank"
}, suspended_block.bind(this, PAGE));
});

View file

@ -1,16 +0,0 @@
const PAGE = "data:text/html,page";
function* test_on_browser(browser) {
ok(!browser.audioMuted, "Audio should not be muted by default");
browser.mute();
ok(browser.audioMuted, "Audio should be muted now");
browser.unmute();
ok(!browser.audioMuted, "Audio should be unmuted now");
}
add_task(function*() {
yield BrowserTestUtils.withNewTab({
gBrowser,
url: PAGE,
}, test_on_browser);
});

View file

@ -1,26 +0,0 @@
const PAGE = "data:text/html,page";
function* test_on_browser(browser) {
ok(!browser.audioMuted, "Audio should not be muted by default");
browser.mute();
ok(browser.audioMuted, "Audio should be muted now");
yield BrowserTestUtils.withNewTab({
gBrowser,
url: PAGE,
}, test_on_browser2);
browser.unmute();
ok(!browser.audioMuted, "Audio should be unmuted now");
}
function* test_on_browser2(browser) {
ok(!browser.audioMuted, "Audio should not be muted by default");
}
add_task(function*() {
yield BrowserTestUtils.withNewTab({
gBrowser,
url: PAGE,
}, test_on_browser);
});

View file

@ -1,47 +0,0 @@
const PAGE = "data:text/html,<div contenteditable>foo</div><input><textarea></textarea>";
const DESIGNMODE_PAGE = "data:text/html,<body onload='document.designMode=\"on\";'>";
const HOTKEYS = ["/", "'"];
function* test_hotkeys(browser, expected) {
let findbar = gBrowser.getFindBar();
for (let key of HOTKEYS) {
is(findbar.hidden, true, "findbar is hidden");
yield BrowserTestUtils.sendChar(key, gBrowser.selectedBrowser);
is(findbar.hidden, expected, "findbar should" + (expected ? "" : " not") + " be hidden");
if (!expected) {
yield closeFindbarAndWait(findbar);
}
}
}
function* focus_element(browser, query) {
yield ContentTask.spawn(browser, query, function* focus(query) {
let element = content.document.querySelector(query);
element.focus();
});
}
add_task(function* test_hotkey_on_editable_element() {
yield BrowserTestUtils.withNewTab({
gBrowser,
url: PAGE
}, function* do_tests(browser) {
yield test_hotkeys(browser, false);
const ELEMENTS = ["div", "input", "textarea"];
for (let elem of ELEMENTS) {
yield focus_element(browser, elem);
yield test_hotkeys(browser, true);
yield focus_element(browser, ":root");
yield test_hotkeys(browser, false);
}
});
});
add_task(function* test_hotkey_on_designMode_document() {
yield BrowserTestUtils.withNewTab({
gBrowser,
url: DESIGNMODE_PAGE
}, function* do_tests(browser) {
yield test_hotkeys(browser, true);
});
});

View file

@ -1,68 +0,0 @@
"use strict";
const IMAGE_PAGE = "https://example.com/browser/toolkit/content/tests/browser/image_page.html";
const PREF_UNSAFE_FORBIDDEN = "dom.ipc.cpows.forbid-unsafe-from-browser";
MockFilePicker.init(window);
MockFilePicker.returnValue = MockFilePicker.returnCancel;
registerCleanupFunction(function() {
MockFilePicker.cleanup();
});
function waitForFilePicker() {
return new Promise((resolve) => {
MockFilePicker.showCallback = () => {
MockFilePicker.showCallback = null;
ok(true, "Saw the file picker");
resolve();
}
})
}
/**
* Test that saveImageURL works when we pass in the aIsContentWindowPrivate
* argument instead of a document. This is the preferred API.
*/
add_task(function* preferred_API() {
yield BrowserTestUtils.withNewTab({
gBrowser,
url: IMAGE_PAGE,
}, function*(browser) {
let url = yield ContentTask.spawn(browser, null, function*() {
let image = content.document.getElementById("image");
return image.href;
});
saveImageURL(url, "image.jpg", null, true, false, null, null, null, null, false);
yield waitForFilePicker();
});
});
/**
* Test that saveImageURL will still work when passed a document instead
* of the aIsContentWindowPrivate argument. This is the deprecated API, and
* will not work in apps using remote browsers having PREF_UNSAFE_FORBIDDEN
* set to true.
*/
add_task(function* deprecated_API() {
yield BrowserTestUtils.withNewTab({
gBrowser,
url: IMAGE_PAGE,
}, function*(browser) {
yield pushPrefs([PREF_UNSAFE_FORBIDDEN, false]);
let url = yield ContentTask.spawn(browser, null, function*() {
let image = content.document.getElementById("image");
return image.href;
});
// Now get the document directly from content. If we run this test with
// e10s-enabled, this will be a CPOW, which is forbidden. We'll just
// pass the XUL document instead to test this interface.
let doc = document;
saveImageURL(url, "image.jpg", null, true, false, null, doc, null, null);
yield waitForFilePicker();
});
});

View file

@ -1,145 +0,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/. */
var MockFilePicker = SpecialPowers.MockFilePicker;
MockFilePicker.init(window);
/**
* Test for bug 471962 <https://bugzilla.mozilla.org/show_bug.cgi?id=471962>:
* When saving an inner frame as file only, the POST data of the outer page is
* sent to the address of the inner page.
*
* Test for bug 485196 <https://bugzilla.mozilla.org/show_bug.cgi?id=485196>:
* Web page generated by POST is retried as GET when Save Frame As used, and the
* page is no longer in the cache.
*/
function test() {
waitForExplicitFinish();
gBrowser.loadURI("http://mochi.test:8888/browser/toolkit/content/tests/browser/data/post_form_outer.sjs");
gBrowser.addEventListener("pageshow", function pageShown(event) {
if (event.target.location == "about:blank")
return;
gBrowser.removeEventListener("pageshow", pageShown);
// Submit the form in the outer page, then wait for both the outer
// document and the inner frame to be loaded again.
gBrowser.addEventListener("DOMContentLoaded", handleOuterSubmit);
gBrowser.contentDocument.getElementById("postForm").submit();
});
var framesLoaded = 0;
var innerFrame;
function handleOuterSubmit() {
if (++framesLoaded < 2)
return;
gBrowser.removeEventListener("DOMContentLoaded", handleOuterSubmit);
innerFrame = gBrowser.contentDocument.getElementById("innerFrame");
// Submit the form in the inner page.
gBrowser.addEventListener("DOMContentLoaded", handleInnerSubmit);
innerFrame.contentDocument.getElementById("postForm").submit();
}
function handleInnerSubmit() {
gBrowser.removeEventListener("DOMContentLoaded", handleInnerSubmit);
// Create the folder the page will be saved into.
var destDir = createTemporarySaveDirectory();
var file = destDir.clone();
file.append("no_default_file_name");
MockFilePicker.returnFiles = [file];
MockFilePicker.showCallback = function(fp) {
MockFilePicker.filterIndex = 1; // kSaveAsType_URL
};
mockTransferCallback = onTransferComplete;
mockTransferRegisterer.register();
registerCleanupFunction(function () {
mockTransferRegisterer.unregister();
MockFilePicker.cleanup();
destDir.remove(true);
});
var docToSave = innerFrame.contentDocument;
// We call internalSave instead of saveDocument to bypass the history
// cache.
internalSave(docToSave.location.href, docToSave, null, null,
docToSave.contentType, false, null, null,
docToSave.referrer ? makeURI(docToSave.referrer) : null,
docToSave, false, null);
}
function onTransferComplete(downloadSuccess) {
ok(downloadSuccess, "The inner frame should have been downloaded successfully");
// Read the entire saved file.
var file = MockFilePicker.returnFiles[0];
var fileContents = readShortFile(file);
// Check if outer POST data is found (bug 471962).
is(fileContents.indexOf("inputfield=outer"), -1,
"The saved inner frame does not contain outer POST data");
// Check if inner POST data is found (bug 485196).
isnot(fileContents.indexOf("inputfield=inner"), -1,
"The saved inner frame was generated using the correct POST data");
finish();
}
}
Cc["@mozilla.org/moz/jssubscript-loader;1"]
.getService(Ci.mozIJSSubScriptLoader)
.loadSubScript("chrome://mochitests/content/browser/toolkit/content/tests/browser/common/mockTransfer.js",
this);
function createTemporarySaveDirectory() {
var saveDir = Cc["@mozilla.org/file/directory_service;1"]
.getService(Ci.nsIProperties)
.get("TmpD", Ci.nsIFile);
saveDir.append("testsavedir");
if (!saveDir.exists())
saveDir.create(Ci.nsIFile.DIRECTORY_TYPE, 0o755);
return saveDir;
}
/**
* Reads the contents of the provided short file (up to 1 MiB).
*
* @param aFile
* nsIFile object pointing to the file to be read.
*
* @return
* String containing the raw octets read from the file.
*/
function readShortFile(aFile) {
var inputStream = Cc["@mozilla.org/network/file-input-stream;1"]
.createInstance(Ci.nsIFileInputStream);
inputStream.init(aFile, -1, 0, 0);
try {
var scrInputStream = Cc["@mozilla.org/scriptableinputstream;1"]
.createInstance(Ci.nsIScriptableInputStream);
scrInputStream.init(inputStream);
try {
// Assume that the file is much shorter than 1 MiB.
return scrInputStream.read(1048576);
}
finally {
// Close the scriptable stream after reading, even if the operation
// failed.
scrInputStream.close();
}
}
finally {
// Close the stream after reading, if it is still open, even if the read
// operation failed.
inputStream.close();
}
}

View file

@ -1,67 +0,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/. */
Cc["@mozilla.org/moz/jssubscript-loader;1"]
.getService(Ci.mozIJSSubScriptLoader)
.loadSubScript("chrome://mochikit/content/tests/SimpleTest/MockObjects.js", this);
var mockTransferCallback;
/**
* This "transfer" object implementation continues the currently running test
* when the download is completed, reporting true for success or false for
* failure as the first argument of the testRunner.continueTest function.
*/
function MockTransfer() {
this._downloadIsSuccessful = true;
}
MockTransfer.prototype = {
QueryInterface: XPCOMUtils.generateQI([
Ci.nsIWebProgressListener,
Ci.nsIWebProgressListener2,
Ci.nsITransfer,
]),
/* nsIWebProgressListener */
onStateChange: function MTFC_onStateChange(aWebProgress, aRequest,
aStateFlags, aStatus) {
// If at least one notification reported an error, the download failed.
if (!Components.isSuccessCode(aStatus))
this._downloadIsSuccessful = false;
// If the download is finished
if ((aStateFlags & Ci.nsIWebProgressListener.STATE_STOP) &&
(aStateFlags & Ci.nsIWebProgressListener.STATE_IS_NETWORK))
// Continue the test, reporting the success or failure condition.
mockTransferCallback(this._downloadIsSuccessful);
},
onProgressChange: function () {},
onLocationChange: function () {},
onStatusChange: function MTFC_onStatusChange(aWebProgress, aRequest, aStatus,
aMessage) {
// If at least one notification reported an error, the download failed.
if (!Components.isSuccessCode(aStatus))
this._downloadIsSuccessful = false;
},
onSecurityChange: function () {},
/* nsIWebProgressListener2 */
onProgressChange64: function () {},
onRefreshAttempted: function () {},
/* nsITransfer */
init: function() {},
setSha256Hash: function() {},
setSignatureInfo: function() {}
};
// Create an instance of a MockObjectRegisterer whose methods can be used to
// temporarily replace the default "@mozilla.org/transfer;1" object factory with
// one that provides the mock implementation above. To activate the mock object
// factory, call the "register" method. Starting from that moment, all the
// transfer objects that are requested will be mock objects, until the
// "unregister" method is called.
var mockTransferRegisterer =
new MockObjectRegisterer("@mozilla.org/transfer;1", MockTransfer);

View file

@ -1,31 +0,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/. */
const CC = Components.Constructor;
const BinaryInputStream = CC("@mozilla.org/binaryinputstream;1",
"nsIBinaryInputStream",
"setInputStream");
function handleRequest(request, response)
{
var body =
'<html>\
<body>\
Inner POST data: ';
var bodyStream = new BinaryInputStream(request.bodyInputStream);
var bytes = [], avail = 0;
while ((avail = bodyStream.available()) > 0)
body += String.fromCharCode.apply(String, bodyStream.readByteArray(avail));
body +=
'<form id="postForm" action="post_form_inner.sjs" method="post">\
<input type="text" name="inputfield" value="inner">\
<input type="submit">\
</form>\
</body>\
</html>';
response.bodyOutputStream.write(body, body.length);
}

View file

@ -1,34 +0,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/. */
const CC = Components.Constructor;
const BinaryInputStream = CC("@mozilla.org/binaryinputstream;1",
"nsIBinaryInputStream",
"setInputStream");
function handleRequest(request, response)
{
var body =
'<html>\
<body>\
Outer POST data: ';
var bodyStream = new BinaryInputStream(request.bodyInputStream);
var bytes = [], avail = 0;
while ((avail = bodyStream.available()) > 0)
body += String.fromCharCode.apply(String, bodyStream.readByteArray(avail));
body +=
'<form id="postForm" action="post_form_outer.sjs" method="post">\
<input type="text" name="inputfield" value="outer">\
<input type="submit">\
</form>\
\
<iframe id="innerFrame" src="post_form_inner.sjs" width="400" height="200">\
\
</body>\
</html>';
response.bodyOutputStream.write(body, body.length);
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

View file

@ -1,14 +0,0 @@
<html>
<head><title>Test Page</title></head>
<body>
<script type="text/javascript">
dump("Script!\n");
addEventListener("load", () => {
// Trigger an onLocationChange event. We want to make sure the title is still correct afterwards.
location.hash = "#x2";
var event = new Event("TestLocationChange");
document.dispatchEvent(event);
}, false);
</script>
</body>
</html>

View file

@ -1,9 +0,0 @@
<!DOCTYPE html>
<script type="text/javascript">
var audio = new Audio();
audio.oncanplay = function() {
audio.oncanplay = null;
audio.play();
};
audio.src = "audio.ogg";
</script>

View file

@ -1,12 +0,0 @@
<!DOCTYPE html>
<body>
<script type="text/javascript">
var audio = new Audio();
audio.oncanplay = function() {
audio.oncanplay = null;
audio.play();
};
audio.src = "audio.ogg";
document.body.appendChild(audio);
</script>
</body>

View file

@ -1,2 +0,0 @@
<!DOCTYPE html>
<iframe src="file_mediaPlayback.html"></iframe>

View file

@ -1,2 +0,0 @@
<!DOCTYPE html>
<iframe src="file_mediaPlayback2.html"></iframe>

View file

@ -1,19 +0,0 @@
<!DOCTYPE html>
<head>
<meta content="text/html;charset=utf-8" http-equiv="Content-Type">
<meta content="utf-8" http-equiv="encoding">
</head>
<body>
<audio id="autoplay" src="audio.ogg"></audio>
<audio id="nonautoplay" src="audio.ogg"></audio>
<script type="text/javascript">
// In linux debug on try server, sometimes the download process would fail, so
// we can't activate the "auto-play" or playing after receving "oncanplay".
// Therefore, we just call play here.
var audio = document.getElementById("autoplay");
audio.loop = true;
audio.play();
</script>
</body>

View file

@ -1,23 +0,0 @@
<!DOCTYPE html>
<head>
<meta content="text/html;charset=utf-8" http-equiv="Content-Type">
<meta content="utf-8" http-equiv="encoding">
</head>
<body>
<audio id="audio1" src="audio.ogg" controls></audio>
<audio id="audio2" src="audio.ogg" controls></audio>
<script type="text/javascript">
// In linux debug on try server, sometimes the download process would fail, so
// we can't activate the "auto-play" or playing after receving "oncanplay".
// Therefore, we just call play here.
var audio1 = document.getElementById("audio1");
audio1.loop = true;
audio1.play();
var audio2 = document.getElementById("audio2");
audio2.loop = true;
audio2.play();
</script>
</body>

View file

@ -1,13 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>redirecting...</title>
<script>
window.addEventListener("load",
() => window.location = "file_redirect_to.html");
</script>
<body>
redirectin u bro
</body>
</html>

View file

@ -1,15 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>redirected!</title>
<script>
window.addEventListener("load", () => {
var event = new Event("RedirectDone");
document.dispatchEvent(event);
});
</script>
<body>
u got redirected, bro
</body>
</html>

View file

@ -1,123 +0,0 @@
"use strict";
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "Promise",
"resource://gre/modules/Promise.jsm");
/**
* A wrapper for the findbar's method "close", which is not synchronous
* because of animation.
*/
function closeFindbarAndWait(findbar) {
return new Promise((resolve) => {
if (findbar.hidden) {
resolve();
return;
}
findbar.addEventListener("transitionend", function cont(aEvent) {
if (aEvent.propertyName != "visibility") {
return;
}
findbar.removeEventListener("transitionend", cont);
resolve();
});
findbar.close();
});
}
function pushPrefs(...aPrefs) {
let deferred = Promise.defer();
SpecialPowers.pushPrefEnv({"set": aPrefs}, deferred.resolve);
return deferred.promise;
}
/**
* Helper class for testing datetime input picker widget
*/
class DateTimeTestHelper {
constructor() {
this.panel = document.getElementById("DateTimePickerPanel");
this.panel.setAttribute("animate", false);
this.tab = null;
this.frame = null;
}
/**
* Opens a new tab with the URL of the test page, and make sure the picker is
* ready for testing.
*
* @param {String} pageUrl
*/
async openPicker(pageUrl) {
this.tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, pageUrl);
await BrowserTestUtils.synthesizeMouseAtCenter("input", {}, gBrowser.selectedBrowser);
// If dateTimePopupFrame doesn't exist yet, wait for the binding to be attached
if (!this.panel.dateTimePopupFrame) {
await BrowserTestUtils.waitForEvent(this.panel, "DateTimePickerBindingReady")
}
this.frame = this.panel.dateTimePopupFrame;
await this.waitForPickerReady();
}
async waitForPickerReady() {
await BrowserTestUtils.waitForEvent(this.frame, "load", true);
// Wait for picker elements to be ready
await BrowserTestUtils.waitForEvent(this.frame.contentDocument, "PickerReady");
}
/**
* Find an element on the picker.
*
* @param {String} selector
* @return {DOMElement}
*/
getElement(selector) {
return this.frame.contentDocument.querySelector(selector);
}
/**
* Find the children of an element on the picker.
*
* @param {String} selector
* @return {Array<DOMElement>}
*/
getChildren(selector) {
return Array.from(this.getElement(selector).children);
}
/**
* Click on an element
*
* @param {DOMElement} element
*/
click(element) {
EventUtils.synthesizeMouseAtCenter(element, {}, this.frame.contentWindow);
}
/**
* Close the panel and the tab
*/
async tearDown() {
if (!this.panel.hidden) {
let pickerClosePromise = new Promise(resolve => {
this.panel.addEventListener("popuphidden", resolve, {once: true});
});
this.panel.hidePopup();
this.panel.closePicker();
await pickerClosePromise;
}
await BrowserTestUtils.removeTab(this.tab);
this.tab = null;
}
/**
* Clean up after tests. Remove the frame to prevent leak.
*/
cleanup() {
this.frame.remove();
this.frame = null;
this.panel.removeAttribute("animate");
this.panel = null;
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

View file

@ -1,9 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>OHAI</title>
<body>
<img id="image" src="image.jpg" />
</body>
</html>

View file

@ -1,7 +0,0 @@
"use strict";
module.exports = {
"extends": [
"../../../../testing/mochitest/chrome.eslintrc.js"
]
};

View file

@ -1,161 +0,0 @@
/* This code is mostly copied from chrome/test/unit/head_crtestutils.js */
const NS_CHROME_MANIFESTS_FILE_LIST = "ChromeML";
const XUL_CACHE_PREF = "nglayout.debug.disable_xul_cache";
var Cc = Components.classes;
var Ci = Components.interfaces;
var Cr = Components.results;
var gDirSvc = Cc["@mozilla.org/file/directory_service;1"].
getService(Ci.nsIDirectoryService).QueryInterface(Ci.nsIProperties);
var gChromeReg = Cc["@mozilla.org/chrome/chrome-registry;1"].
getService(Ci.nsIXULChromeRegistry);
var gPrefs = Cc["@mozilla.org/preferences-service;1"].
getService(Ci.nsIPrefBranch);
// Create the temporary file in the profile, instead of in TmpD, because
// we know the mochitest harness kills off the profile when it's done.
function copyToTemporaryFile(f)
{
let tmpd = gDirSvc.get("ProfD", Ci.nsIFile);
tmpf = tmpd.clone();
tmpf.append("temp.manifest");
tmpf.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0o600);
tmpf.remove(false);
f.copyTo(tmpd, tmpf.leafName);
return tmpf;
}
function* dirIter(directory)
{
var ioSvc = Cc["@mozilla.org/network/io-service;1"].
getService(Ci.nsIIOService);
var testsDir = ioSvc.newURI(directory, null, null)
.QueryInterface(Ci.nsIFileURL).file;
let en = testsDir.directoryEntries;
while (en.hasMoreElements()) {
let file = en.getNext();
yield file.QueryInterface(Ci.nsIFile);
}
}
function getParent(path) {
let lastSlash = path.lastIndexOf("/");
if (lastSlash == -1) {
lastSlash = path.lastIndexOf("\\");
if (lastSlash == -1) {
return "";
}
return '/' + path.substring(0, lastSlash).replace(/\\/g, '/');
}
return path.substring(0, lastSlash);
}
function copyDirToTempProfile(path, subdirname) {
if (subdirname === undefined) {
subdirname = "mochikit-tmp";
}
let tmpdir = gDirSvc.get("ProfD", Ci.nsIFile);
tmpdir.append(subdirname);
tmpdir.createUnique(Components.interfaces.nsIFile.DIRECTORY_TYPE, 0o777);
let rootDir = getParent(path);
if (rootDir == "") {
return tmpdir;
}
// The SimpleTest directory is hidden
var files = Array.from(dirIter('file://' + rootDir));
for (f in files) {
files[f].copyTo(tmpdir, "");
}
return tmpdir;
}
function convertChromeURI(chromeURI)
{
let uri = Cc["@mozilla.org/network/io-service;1"].
getService(Ci.nsIIOService).newURI(chromeURI, null, null);
return gChromeReg.convertChromeURL(uri);
}
function chromeURIToFile(chromeURI)
{
var jar = getJar(chromeURI);
if (jar) {
var tmpDir = extractJarToTmp(jar);
let parts = chromeURI.split('/');
if (parts[parts.length - 1] != '') {
tmpDir.append(parts[parts.length - 1]);
}
return tmpDir;
}
return convertChromeURI(chromeURI).
QueryInterface(Ci.nsIFileURL).file;
}
// Register a chrome manifest temporarily and return a function which un-does
// the registrarion when no longer needed.
function createManifestTemporarily(tempDir, manifestText)
{
gPrefs.setBoolPref(XUL_CACHE_PREF, true);
tempDir.append("temp.manifest");
let foStream = Cc["@mozilla.org/network/file-output-stream;1"]
.createInstance(Ci.nsIFileOutputStream);
foStream.init(tempDir,
0x02 | 0x08 | 0x20, 0o664, 0); // write, create, truncate
foStream.write(manifestText, manifestText.length);
foStream.close();
let tempfile = copyToTemporaryFile(tempDir);
Components.manager.QueryInterface(Ci.nsIComponentRegistrar).
autoRegister(tempfile);
gChromeReg.refreshSkins();
return function() {
tempfile.fileSize = 0; // truncate the manifest
gChromeReg.checkForNewChrome();
gChromeReg.refreshSkins();
gPrefs.clearUserPref(XUL_CACHE_PREF);
}
}
// Register a chrome manifest temporarily and return a function which un-does
// the registrarion when no longer needed.
function registerManifestTemporarily(manifestURI)
{
gPrefs.setBoolPref(XUL_CACHE_PREF, true);
let file = chromeURIToFile(manifestURI);
let tempfile = copyToTemporaryFile(file);
Components.manager.QueryInterface(Ci.nsIComponentRegistrar).
autoRegister(tempfile);
gChromeReg.refreshSkins();
return function() {
tempfile.fileSize = 0; // truncate the manifest
gChromeReg.checkForNewChrome();
gChromeReg.refreshSkins();
gPrefs.clearUserPref(XUL_CACHE_PREF);
}
}
function registerManifestPermanently(manifestURI)
{
var chromepath = chromeURIToFile(manifestURI);
Components.manager.QueryInterface(Ci.nsIComponentRegistrar).
autoRegister(chromepath);
return chromepath;
}

View file

@ -1,210 +0,0 @@
<?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="263683test"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
width="600"
height="600"
onload="SimpleTest.executeSoon(startTest);"
title="263683 test">
<script type="application/javascript"><![CDATA[
const {interfaces: Ci, classes: Cc, results: Cr, utils: Cu} = Components;
Cu.import("resource://gre/modules/AppConstants.jsm");
Cu.import("resource://gre/modules/Task.jsm");
Cu.import("resource://testing-common/BrowserTestUtils.jsm");
Cu.import("resource://testing-common/ContentTask.jsm");
ContentTask.setTestScope(window.opener.wrappedJSObject);
var gPrefsvc = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch);
var gFindBar = null;
var gBrowser;
var imports = ["SimpleTest", "ok", "info", "is"];
for (var name of imports) {
window[name] = window.opener.wrappedJSObject[name];
}
function startTest() {
Task.spawn(function* () {
gFindBar = document.getElementById("FindToolbar");
for (let browserId of ["content", "content-remote"]) {
yield startTestWithBrowser(browserId);
}
}).then(() => {
window.close();
SimpleTest.finish();
});
}
function* startTestWithBrowser(browserId) {
// We're bailing out when testing a remote browser on OSX 10.6, because it
// fails permanently.
if (browserId.endsWith("remote") && AppConstants.isPlatformAndVersionAtMost("macosx", 11)) {
return;
}
info("Starting test with browser '" + browserId + "'");
gBrowser = document.getElementById(browserId);
gFindBar.browser = gBrowser;
let promise = BrowserTestUtils.browserLoaded(gBrowser);
gBrowser.loadURI('data:text/html,<h2>Text mozilla</h2><input id="inp" type="text" />');
yield promise;
yield onDocumentLoaded();
}
function toggleHighlightAndWait(highlight) {
return new Promise(resolve => {
let listener = {
onHighlightFinished: function() {
gFindBar.browser.finder.removeResultListener(listener);
resolve();
}
};
gFindBar.browser.finder.addResultListener(listener);
gFindBar.toggleHighlight(highlight);
});
}
function* onDocumentLoaded() {
gFindBar.open();
var search = "mozilla";
gFindBar._findField.focus();
gFindBar._findField.value = search;
var matchCase = gFindBar.getElement("find-case-sensitive");
if (matchCase.checked) {
matchCase.doCommand();
}
yield toggleHighlightAndWait(true);
gFindBar._find();
yield ContentTask.spawn(gBrowser, { search }, function* (args) {
let controller = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsISelectionDisplay)
.QueryInterface(Ci.nsISelectionController);
Assert.ok("SELECTION_FIND" in controller, "Correctly detects new selection type");
let selection = controller.getSelection(controller.SELECTION_FIND);
Assert.equal(selection.rangeCount, 1,
"Correctly added a match to the selection type");
Assert.equal(selection.getRangeAt(0).toString().toLowerCase(),
args.search, "Added the correct match");
});
yield toggleHighlightAndWait(false);
yield ContentTask.spawn(gBrowser, { search }, function* (args) {
let controller = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsISelectionDisplay)
.QueryInterface(Ci.nsISelectionController);
let selection = controller.getSelection(controller.SELECTION_FIND);
Assert.equal(selection.rangeCount, 0, "Correctly removed the range");
let input = content.document.getElementById("inp");
input.value = args.search;
});
yield toggleHighlightAndWait(true);
yield ContentTask.spawn(gBrowser, { search }, function* (args) {
let input = content.document.getElementById("inp");
let inputController = input.editor.selectionController;
let inputSelection = inputController.getSelection(inputController.SELECTION_FIND);
Assert.equal(inputSelection.rangeCount, 1,
"Correctly added a match from input to the selection type");
Assert.equal(inputSelection.getRangeAt(0).toString().toLowerCase(),
args.search, "Added the correct match");
});
yield toggleHighlightAndWait(false);
yield ContentTask.spawn(gBrowser, null, function* () {
let input = content.document.getElementById("inp");
let inputController = input.editor.selectionController;
let inputSelection = inputController.getSelection(inputController.SELECTION_FIND);
Assert.equal(inputSelection.rangeCount, 0, "Correctly removed the range");
});
// For posterity, test iframes too.
let promise = BrowserTestUtils.browserLoaded(gBrowser);
gBrowser.loadURI('data:text/html,<h2>Text mozilla</h2><iframe id="leframe" ' +
'src="data:text/html,Text mozilla"></iframe>');
yield promise;
yield toggleHighlightAndWait(true);
yield ContentTask.spawn(gBrowser, { search }, function* (args) {
function getSelection(docShell) {
let controller = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsISelectionDisplay)
.QueryInterface(Ci.nsISelectionController);
return controller.getSelection(controller.SELECTION_FIND);
}
let selection = getSelection(docShell);
Assert.equal(selection.rangeCount, 1,
"Correctly added a match to the selection type");
Assert.equal(selection.getRangeAt(0).toString().toLowerCase(),
args.search, "Added the correct match");
// Check the iframe too:
let frame = content.document.getElementById("leframe");
// Hoops! Get the docShell first, then the selection.
selection = getSelection(frame.contentWindow
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShell));
Assert.equal(selection.rangeCount, 1,
"Correctly added a match to the selection type");
Assert.equal(selection.getRangeAt(0).toString().toLowerCase(),
args.search, "Added the correct match");
});
yield toggleHighlightAndWait(false);
let matches = gFindBar._foundMatches.value.match(/([\d]*)\sof\s([\d]*)/);
is(matches[1], "2", "Found correct amount of matches")
yield ContentTask.spawn(gBrowser, null, function* (args) {
function getSelection(docShell) {
let controller = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsISelectionDisplay)
.QueryInterface(Ci.nsISelectionController);
return controller.getSelection(controller.SELECTION_FIND);
}
let selection = getSelection(docShell);
Assert.equal(selection.rangeCount, 0, "Correctly removed the range");
// Check the iframe too:
let frame = content.document.getElementById("leframe");
// Hoops! Get the docShell first, then the selection.
selection = getSelection(frame.contentWindow
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShell));
Assert.equal(selection.rangeCount, 0, "Correctly removed the range");
content.document.documentElement.focus();
});
gFindBar.close(true);
}
]]></script>
<browser type="content-primary" flex="1" id="content" src="about:blank"/>
<browser type="content-primary" flex="1" id="content-remote" remote="true" src="about:blank"/>
<findbar id="FindToolbar" browserid="content"/>
</window>

View file

@ -1,94 +0,0 @@
<?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 xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
width="600"
height="600"
onload="onLoad();"
title="FindbarTest for bug 304188 -
find-menu appears in editor element which has had makeEditable() called but designMode not set">
<script type="application/javascript"><![CDATA[
const {interfaces: Ci, classes: Cc, results: Cr, utils: Cu} = Components;
Cu.import("resource://gre/modules/Task.jsm");
Cu.import("resource://testing-common/ContentTask.jsm");
ContentTask.setTestScope(window.opener.wrappedJSObject);
var gFindBar = null;
var gBrowser;
var imports = ["SimpleTest", "ok", "info"];
for (var name of imports) {
window[name] = window.opener.wrappedJSObject[name];
}
function onLoad() {
Task.spawn(function* () {
gFindBar = document.getElementById("FindToolbar");
for (let browserId of ["content", "content-remote"]) {
yield startTestWithBrowser(browserId);
}
}).then(() => {
window.close();
SimpleTest.finish();
});
}
function* startTestWithBrowser(browserId) {
info("Starting test with browser '" + browserId + "'");
gBrowser = document.getElementById(browserId);
gFindBar.browser = gBrowser;
let promise = ContentTask.spawn(gBrowser, null, function* () {
return new Promise(resolve => {
addEventListener("DOMContentLoaded", function listener() {
removeEventListener("DOMContentLoaded", listener);
resolve();
});
});
});
gBrowser.loadURI("data:text/html;charset=utf-8,some%20random%20text");
yield promise;
yield onDocumentLoaded();
}
function* onDocumentLoaded() {
yield ContentTask.spawn(gBrowser, null, function* () {
var edsession = content.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIEditingSession);
edsession.makeWindowEditable(content, "html", false, true, false);
content.focus();
});
yield enterStringIntoEditor("'");
yield enterStringIntoEditor("/");
ok(gFindBar.hidden,
"Findfield should have stayed hidden after entering editor test");
}
function* enterStringIntoEditor(aString) {
for (let i = 0; i < aString.length; i++) {
yield ContentTask.spawn(gBrowser, { charCode: aString.charCodeAt(i) }, function* (args) {
let event = content.document.createEvent("KeyboardEvent");
event.initKeyEvent("keypress", true, true, null, false, false,
false, false, 0, args.charCode);
content.document.body.dispatchEvent(event);
});
}
}
]]></script>
<browser id="content" flex="1" src="about:blank" type="content-primary"/>
<browser id="content-remote" remote="true" flex="1" src="about:blank" type="content-primary"/>
<findbar id="FindToolbar" browserid="content"/>
</window>

View file

@ -1,102 +0,0 @@
<?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="331215test"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
width="600"
height="600"
onload="SimpleTest.executeSoon(startTest);"
title="331215 test">
<script type="application/javascript"><![CDATA[
const {interfaces: Ci, classes: Cc, results: Cr, utils: Cu} = Components;
Cu.import("resource://gre/modules/Task.jsm");
Cu.import("resource://testing-common/BrowserTestUtils.jsm");
Cu.import("resource://testing-common/ContentTask.jsm");
ContentTask.setTestScope(window.opener.wrappedJSObject);
var gFindBar = null;
var gBrowser;
var imports = ["SimpleTest", "ok", "info"];
for (var name of imports) {
window[name] = window.opener.wrappedJSObject[name];
}
SimpleTest.requestLongerTimeout(2);
function startTest() {
Task.spawn(function* () {
gFindBar = document.getElementById("FindToolbar");
for (let browserId of ["content", "content-remote"]) {
yield startTestWithBrowser(browserId);
}
}).then(() => {
window.close();
SimpleTest.finish();
});
}
function* startTestWithBrowser(browserId) {
info("Starting test with browser '" + browserId + "'");
gBrowser = document.getElementById(browserId);
gFindBar.browser = gBrowser;
let promise = BrowserTestUtils.browserLoaded(gBrowser);
gBrowser.loadURI("data:text/plain,latest");
yield promise;
yield onDocumentLoaded();
}
function* onDocumentLoaded() {
document.getElementById("cmd_find").doCommand();
yield promiseEnterStringIntoFindField("test");
document.commandDispatcher
.getControllerForCommand("cmd_moveTop")
.doCommand("cmd_moveTop");
yield promiseEnterStringIntoFindField("l");
ok(gFindBar._findField.getAttribute("status") == "notfound",
"Findfield status attribute should have been 'notfound' after entering test");
yield promiseEnterStringIntoFindField("a");
ok(gFindBar._findField.getAttribute("status") != "notfound",
"Findfield status attribute should not have been 'notfound' after entering latest");
}
function promiseEnterStringIntoFindField(aString) {
return new Promise(resolve => {
let listener = {
onFindResult: function(result) {
if (result.result == Ci.nsITypeAheadFind.FIND_FOUND && result.searchString != aString)
return;
gFindBar.browser.finder.removeResultListener(listener);
resolve();
}
};
gFindBar.browser.finder.addResultListener(listener);
for (let c of aString) {
let code = c.charCodeAt(0);
let ev = new KeyboardEvent("keypress", {
keyCode: code,
charCode: code,
bubbles: true
});
gFindBar._findField.inputField.dispatchEvent(ev);
}
});
}
]]></script>
<commandset>
<command id="cmd_find" oncommand="document.getElementById('FindToolbar').onFindCommand();"/>
</commandset>
<browser type="content-primary" flex="1" id="content" src="about:blank"/>
<browser type="content-primary" flex="1" id="content-remote" remote="true" src="about:blank"/>
<findbar id="FindToolbar" browserid="content"/>
</window>

View file

@ -1,120 +0,0 @@
<?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="360437Test"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
width="600"
height="600"
onload="startTest();"
title="360437 test">
<script type="application/javascript"><![CDATA[
const {interfaces: Ci, classes: Cc, results: Cr, utils: Cu} = Components;
Cu.import("resource://gre/modules/Task.jsm");
Cu.import("resource://testing-common/ContentTask.jsm");
ContentTask.setTestScope(window.opener.wrappedJSObject);
var gFindBar = null;
var gBrowser;
var imports = ["SimpleTest", "ok", "is", "info"];
for (var name of imports) {
window[name] = window.opener.wrappedJSObject[name];
}
function startTest() {
Task.spawn(function* () {
gFindBar = document.getElementById("FindToolbar");
for (let browserId of ["content", "content-remote"]) {
yield startTestWithBrowser(browserId);
}
}).then(() => {
window.close();
SimpleTest.finish();
});
}
function* startTestWithBrowser(browserId) {
info("Starting test with browser '" + browserId + "'");
gBrowser = document.getElementById(browserId);
gFindBar.browser = gBrowser;
let promise = ContentTask.spawn(gBrowser, null, function* () {
return new Promise(resolve => {
addEventListener("DOMContentLoaded", function listener() {
removeEventListener("DOMContentLoaded", listener);
resolve();
});
});
});
gBrowser.loadURI("data:text/html,<form><input id='input' type='text' value='text inside an input element'></form>");
yield promise;
yield onDocumentLoaded();
}
function* onDocumentLoaded() {
gFindBar.onFindCommand();
// Make sure the findfield is correctly focused on open
var searchStr = "text inside an input element";
yield promiseEnterStringIntoFindField(searchStr);
is(document.commandDispatcher.focusedElement,
gFindBar._findField.inputField, "Find field isn't focused");
// Make sure "find again" correctly transfers focus to the content element
// when the find bar is closed.
gFindBar.close();
gFindBar.onFindAgainCommand(false);
yield ContentTask.spawn(gBrowser, null, function* () {
Assert.equal(content.document.activeElement,
content.document.getElementById("input"), "Input Element isn't focused");
});
// Make sure "find again" doesn't focus the content element if focus
// isn't in the content document.
var textbox = document.getElementById("textbox");
textbox.focus();
gFindBar.close();
gFindBar.onFindAgainCommand(false);
ok(textbox.hasAttribute("focused"),
"Focus was stolen from a chrome element");
}
function promiseFindResult(str = null) {
return new Promise(resolve => {
let listener = {
onFindResult: function({ searchString }) {
if (str !== null && str != searchString) {
return;
}
gFindBar.browser.finder.removeResultListener(listener);
resolve();
}
};
gFindBar.browser.finder.addResultListener(listener);
});
}
function promiseEnterStringIntoFindField(str) {
let promise = promiseFindResult(str);
for (let i = 0; i < str.length; i++) {
let event = document.createEvent("KeyboardEvent");
event.initKeyEvent("keypress", true, true, null, false, false,
false, false, 0, str.charCodeAt(i));
gFindBar._findField.inputField.dispatchEvent(event);
}
return promise;
}
]]></script>
<textbox id="textbox"/>
<browser type="content-primary" flex="1" id="content" src="about:blank"/>
<browser type="content-primary" flex="1" id="content-remote" remote="true" src="about:blank"/>
<findbar id="FindToolbar" browserid="content"/>
</window>

View file

@ -1,57 +0,0 @@
<?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"?>
<?xul-overlay href="chrome://global/content/editMenuOverlay.xul"?>
<window id="366992 test"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
onload="onLoad();"
width="600"
height="600"
title="366992 test">
<commandset id="editMenuCommands"/>
<script type="application/javascript"
src="chrome://global/content/globalOverlay.js"/>
<script type="application/javascript"><![CDATA[
// Without the fix for bug 366992, the delete command would be enabled
// for the textbox even though the textbox's controller for this command
// disables it.
var gShouldNotBeReachedController = {
supportsCommand: function(aCommand) {
return aCommand == "cmd_delete";
},
isCommandEnabled: function(aCommand) {
return aCommand == "cmd_delete";
},
doCommand: function(aCommand) { }
}
function ok(condition, message) {
window.opener.wrappedJSObject.SimpleTest.ok(condition, message);
}
function finish() {
window.controllers.removeController(gShouldNotBeReachedController);
window.close();
window.opener.wrappedJSObject.SimpleTest.finish();
}
function onLoad() {
document.getElementById("textbox").focus();
var deleteDisabled = document.getElementById("cmd_delete")
.getAttribute("disabled") == "true";
ok(deleteDisabled,
"cmd_delete should be disabled when the empty textbox is focused");
finish();
}
window.controllers.appendController(gShouldNotBeReachedController);
]]></script>
<textbox id="textbox"/>
</window>

View file

@ -1,98 +0,0 @@
<?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"?>
<window id="409624test"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
width="600"
height="600"
title="409624 test">
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/>
<script type="application/javascript"><![CDATA[
var gFindBar = null;
var gBrowser;
var imports = ["SimpleTest", "ok", "is"];
for (var name of imports) {
window[name] = window.opener.wrappedJSObject[name];
}
function finish() {
window.close();
SimpleTest.finish();
}
function startTest() {
gFindBar = document.getElementById("FindToolbar");
gBrowser = document.getElementById("content");
gBrowser.addEventListener("pageshow", onPageShow, false);
gBrowser.loadURI('data:text/html,<h2>Text mozilla</h2><input id="inp" type="text" />');
}
function onPageShow() {
gBrowser.removeEventListener("pageshow", onPageShow, false);
gFindBar.clear();
let textbox = gFindBar.getElement("findbar-textbox");
// Clear should work regardless of whether the editor has been lazily
// initialised yet
ok(!gFindBar.hasTransactions, "No transactions when findbar empty");
textbox.value = "mozilla";
ok(gFindBar.hasTransactions, "Has transactions when findbar value set without editor init");
gFindBar.clear();
is(textbox.value, '', "findbar input value cleared after clear() call without editor init");
ok(!gFindBar.hasTransactions, "No transactions after clear() call");
gFindBar.open();
let matchCaseCheckbox = gFindBar.getElement("find-case-sensitive");
if (!matchCaseCheckbox.hidden && matchCaseCheckbox.checked)
matchCaseCheckbox.click();
ok(!matchCaseCheckbox.checked, "case-insensitivity correctly set");
// Simulate typical input
textbox.focus();
gFindBar.clear();
sendChar("m");
ok(gFindBar.hasTransactions, "Has transactions after input");
let preSelection = gBrowser.contentWindow.getSelection();
ok(!preSelection.isCollapsed, "Found item and selected range");
gFindBar.clear();
is(textbox.value, '', "findbar input value cleared after clear() call");
let postSelection = gBrowser.contentWindow.getSelection();
ok(postSelection.isCollapsed, "item found deselected after clear() call");
let fp = gFindBar.getElement("find-previous");
ok(fp.disabled, "find-previous button disabled after clear() call");
let fn = gFindBar.getElement("find-next");
ok(fn.disabled, "find-next button disabled after clear() call");
// Test status updated after a search for text not in page
textbox.focus();
sendChar("x");
gFindBar.clear();
let ftext = gFindBar.getElement("find-status");
is(ftext.textContent, "", "status text disabled after clear() call");
// Test input empty with undo stack non-empty
textbox.focus();
sendChar("m");
sendKey("BACK_SPACE");
ok(gFindBar.hasTransactions, "Has transactions when undo available");
gFindBar.clear();
gFindBar.close();
finish();
}
SimpleTest.waitForFocus(startTest, window);
]]></script>
<browser type="content-primary" flex="1" id="content" src="about:blank"/>
<findbar id="FindToolbar" browserid="content"/>
</window>

View file

@ -1,84 +0,0 @@
<?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"?>
<window id="429723Test"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
width="600"
height="600"
onload="onLoad();"
title="429723 test">
<script type="application/javascript"><![CDATA[
var gFindBar = null;
var gBrowser;
function ok(condition, message) {
window.opener.wrappedJSObject.SimpleTest.ok(condition, message);
}
function finish() {
window.close();
window.opener.wrappedJSObject.SimpleTest.finish();
}
function onLoad() {
var _delayedOnLoad = function() {
gFindBar = document.getElementById("FindToolbar");
gBrowser = document.getElementById("content");
gBrowser.addEventListener("pageshow", onPageShow, false);
gBrowser.loadURI("data:text/html,<h2 id='h2'>mozilla</h2>");
}
setTimeout(_delayedOnLoad, 1000);
}
function enterStringIntoFindField(aString) {
for (var i=0; i < aString.length; i++) {
var event = document.createEvent("KeyboardEvent");
event.initKeyEvent("keypress", true, true, null, false, false,
false, false, 0, aString.charCodeAt(i));
gFindBar._findField.inputField.dispatchEvent(event);
}
}
function onPageShow() {
gBrowser.removeEventListener("pageshow", onPageShow, false);
var findField = gFindBar._findField;
document.getElementById("cmd_find").doCommand();
var matchCaseCheckbox = gFindBar.getElement("find-case-sensitive");
if (!matchCaseCheckbox.hidden & matchCaseCheckbox.checked)
matchCaseCheckbox.click();
// Perform search
var searchStr = "z";
enterStringIntoFindField(searchStr);
// Highlight search term
var highlight = gFindBar.getElement("highlight");
if (!highlight.checked)
highlight.click();
// Delete search term
var event = document.createEvent("KeyboardEvent");
event.initKeyEvent("keypress", true, true, null, false, false,
false, false, KeyEvent.DOM_VK_BACK_SPACE, 0);
gFindBar._findField.inputField.dispatchEvent(event);
var notRed = !findField.hasAttribute("status") ||
(findField.getAttribute("status") != "notfound");
ok(notRed, "Find Bar textbox is correct colour");
finish();
}
]]></script>
<commandset>
<command id="cmd_find" oncommand="document.getElementById('FindToolbar').onFindCommand();"/>
</commandset>
<browser type="content-primary" flex="1" id="content" src="about:blank"/>
<findbar id="FindToolbar" browserid="content"/>
</window>

View file

@ -1,248 +0,0 @@
<?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"?>
<window id="451540test"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
width="600"
height="600"
title="451540 test">
<script type="application/javascript"><![CDATA[
const {interfaces: Ci, classes: Cc, results: Cr, utils: Cu} = Components;
Cu.import("resource://gre/modules/Task.jsm");
Cu.import("resource://testing-common/BrowserTestUtils.jsm");
Cu.import("resource://testing-common/ContentTask.jsm");
ContentTask.setTestScope(window.opener.wrappedJSObject);
const SEARCH_TEXT = "minefield";
let gFindBar = null;
let gPrefsvc = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch);
let gBrowser;
let sendCtrl = true;
let sendMeta = false;
if (navigator.platform.indexOf("Mac") >= 0) {
sendCtrl = false;
sendMeta = true;
}
let imports = [ "SimpleTest", "ok", "is", "info"];
for (let name of imports) {
window[name] = window.opener.wrappedJSObject[name];
}
SimpleTest.requestLongerTimeout(2);
function startTest() {
gFindBar = document.getElementById("FindToolbar");
gBrowser = document.getElementById("content");
gBrowser.addEventListener("pageshow", onPageShow, false);
let data = `data:text/html,<input id="inp" type="text" />
<textarea id="tarea"/>`;
gBrowser.loadURI(data);
}
function promiseHighlightFinished() {
return new Promise(resolve => {
let listener = {
onHighlightFinished() {
gFindBar.browser.finder.removeResultListener(listener);
resolve();
}
};
gFindBar.browser.finder.addResultListener(listener);
});
}
function* resetForNextTest(elementId, aText) {
if (!aText)
aText = SEARCH_TEXT;
// Turn off highlighting
let highlightButton = gFindBar.getElement("highlight");
if (highlightButton.checked) {
highlightButton.click();
}
// Initialise input
info(`setting element value to ${aText}`);
yield ContentTask.spawn(gBrowser, {elementId, aText}, function*(args) {
let {elementId, aText} = args;
let doc = content.document;
let element = doc.getElementById(elementId);
element.value = aText;
element.focus();
});
info(`just set element value to ${aText}`);
gFindBar._findField.value = SEARCH_TEXT;
// Perform search and turn on highlighting
gFindBar._find();
highlightButton.click();
yield promiseHighlightFinished();
// Move caret to start of element
info(`focusing element`);
yield ContentTask.spawn(gBrowser, elementId, function*(elementId) {
let doc = content.document;
let element = doc.getElementById(elementId);
element.focus();
});
info(`focused element`);
if (navigator.platform.indexOf("Mac") >= 0) {
yield BrowserTestUtils.synthesizeKey("VK_LEFT", { metaKey: true }, gBrowser);
} else {
yield BrowserTestUtils.synthesizeKey("VK_HOME", {}, gBrowser);
}
}
function* testSelection(elementId, expectedRangeCount, message) {
yield ContentTask.spawn(gBrowser, {elementId, expectedRangeCount, message}, function*(args) {
let {elementId, expectedRangeCount, message} = args;
let doc = content.document;
let element = doc.getElementById(elementId);
let controller = element.editor.selectionController;
let selection = controller.getSelection(controller.SELECTION_FIND);
Assert.equal(selection.rangeCount, expectedRangeCount, message);
});
}
function* testInput(elementId, testTypeText) {
let isEditableElement = yield ContentTask.spawn(gBrowser, elementId, function*(elementId) {
let doc = content.document;
let element = doc.getElementById(elementId);
return element instanceof Ci.nsIDOMNSEditableElement;
});
if (!isEditableElement) {
return;
}
// Initialize the findbar
let matchCase = gFindBar.getElement("find-case-sensitive");
if (matchCase.checked) {
matchCase.doCommand();
}
// First check match has been correctly highlighted
yield resetForNextTest(elementId);
yield testSelection(elementId, 1, testTypeText + " correctly highlighted match");
// Test 2: check highlight removed when text added within the highlight
yield BrowserTestUtils.synthesizeKey("VK_RIGHT", {}, gBrowser);
yield BrowserTestUtils.synthesizeKey("a", {}, gBrowser);
yield testSelection(elementId, 0, testTypeText + " correctly removed highlight on text insertion");
// Test 3: check highlighting remains when text added before highlight
yield resetForNextTest(elementId);
yield BrowserTestUtils.synthesizeKey("a", {}, gBrowser);
yield testSelection(elementId, 1, testTypeText + " highlight correctly remained on text insertion at start");
// Test 4: check highlighting remains when text added after highlight
yield resetForNextTest(elementId);
for (let x = 0; x < SEARCH_TEXT.length; x++) {
yield BrowserTestUtils.synthesizeKey("VK_RIGHT", {}, gBrowser);
}
yield BrowserTestUtils.synthesizeKey("a", {}, gBrowser);
yield testSelection(elementId, 1, testTypeText + " highlight correctly remained on text insertion at end");
// Test 5: deleting text within the highlight
yield resetForNextTest(elementId);
yield BrowserTestUtils.synthesizeKey("VK_RIGHT", {}, gBrowser);
yield BrowserTestUtils.synthesizeKey("VK_BACK_SPACE", {}, gBrowser);
yield testSelection(elementId, 0, testTypeText + " correctly removed highlight on text deletion");
// Test 6: deleting text at end of highlight
yield resetForNextTest(elementId, SEARCH_TEXT + "A");
for (let x = 0; x < (SEARCH_TEXT + "A").length; x++) {
yield BrowserTestUtils.synthesizeKey("VK_RIGHT", {}, gBrowser);
}
yield BrowserTestUtils.synthesizeKey("VK_BACK_SPACE", {}, gBrowser);
yield testSelection(elementId, 1, testTypeText + " highlight correctly remained on text deletion at end");
// Test 7: deleting text at start of highlight
yield resetForNextTest(elementId, "A" + SEARCH_TEXT);
yield BrowserTestUtils.synthesizeKey("VK_RIGHT", {}, gBrowser);
yield BrowserTestUtils.synthesizeKey("VK_BACK_SPACE", {}, gBrowser);
yield testSelection(elementId, 1, testTypeText + " highlight correctly remained on text deletion at start");
// Test 8: deleting selection
yield resetForNextTest(elementId);
yield BrowserTestUtils.synthesizeKey("VK_RIGHT", { shiftKey: true }, gBrowser);
yield BrowserTestUtils.synthesizeKey("VK_RIGHT", { shiftKey: true }, gBrowser);
yield BrowserTestUtils.synthesizeKey("x", { ctrlKey: sendCtrl, metaKey: sendMeta }, gBrowser);
yield testSelection(elementId, 0, testTypeText + " correctly removed highlight on selection deletion");
// Test 9: Multiple matches within one editor (part 1)
// Check second match remains highlighted after inserting text into
// first match, and that its highlighting gets removed when the
// second match is edited
yield resetForNextTest(elementId, SEARCH_TEXT + " " + SEARCH_TEXT);
yield testSelection(elementId, 2, testTypeText + " correctly highlighted both matches");
yield BrowserTestUtils.synthesizeKey("VK_RIGHT", {}, gBrowser);
yield BrowserTestUtils.synthesizeKey("a", {}, gBrowser);
yield testSelection(elementId, 1, testTypeText + " correctly removed only the first highlight on text insertion");
yield BrowserTestUtils.synthesizeKey("VK_RIGHT", { ctrlKey: sendCtrl, metaKey: sendMeta }, gBrowser);
yield BrowserTestUtils.synthesizeKey("VK_RIGHT", { ctrlKey: sendCtrl, metaKey: sendMeta }, gBrowser);
yield BrowserTestUtils.synthesizeKey("VK_LEFT", {}, gBrowser);
yield BrowserTestUtils.synthesizeKey("a", {}, gBrowser);
yield testSelection(elementId, 0, testTypeText + " correctly removed second highlight on text insertion");
// Test 10: Multiple matches within one editor (part 2)
// Check second match remains highlighted after deleting text in
// first match, and that its highlighting gets removed when the
// second match is edited
yield resetForNextTest(elementId, SEARCH_TEXT + " " + SEARCH_TEXT);
yield testSelection(elementId, 2, testTypeText + " correctly highlighted both matches");
yield BrowserTestUtils.synthesizeKey("VK_RIGHT", {}, gBrowser);
yield BrowserTestUtils.synthesizeKey("VK_BACK_SPACE", {}, gBrowser);
yield testSelection(elementId, 1, testTypeText + " correctly removed only the first highlight on text deletion");
yield BrowserTestUtils.synthesizeKey("VK_RIGHT", { ctrlKey: sendCtrl, metaKey: sendMeta }, gBrowser);
yield BrowserTestUtils.synthesizeKey("VK_RIGHT", { ctrlKey: sendCtrl, metaKey: sendMeta }, gBrowser);
yield BrowserTestUtils.synthesizeKey("VK_LEFT", {}, gBrowser);
yield BrowserTestUtils.synthesizeKey("VK_BACK_SPACE", {}, gBrowser);
yield testSelection(elementId, 0, testTypeText + " correctly removed second highlight on text deletion");
// Test 11: Multiple matches within one editor (part 3)
// Check second match remains highlighted after deleting selection
// in first match, and that second match highlighting gets correctly
// removed when it has a selection deleted from it
yield resetForNextTest(elementId, SEARCH_TEXT + " " + SEARCH_TEXT);
yield BrowserTestUtils.synthesizeKey("VK_RIGHT", { shiftKey: true }, gBrowser);
yield BrowserTestUtils.synthesizeKey("VK_RIGHT", { shiftKey: true }, gBrowser);
yield BrowserTestUtils.synthesizeKey("x", { ctrlKey: sendCtrl, metaKey: sendMeta }, gBrowser);
yield testSelection(elementId, 1, testTypeText + " correctly removed only first highlight on selection deletion");
yield BrowserTestUtils.synthesizeKey("VK_RIGHT", { ctrlKey: sendCtrl, metaKey: sendMeta }, gBrowser);
yield BrowserTestUtils.synthesizeKey("VK_RIGHT", { ctrlKey: sendCtrl, metaKey: sendMeta }, gBrowser);
yield BrowserTestUtils.synthesizeKey("VK_LEFT", { shiftKey: true }, gBrowser);
yield BrowserTestUtils.synthesizeKey("VK_LEFT", { shiftKey: true }, gBrowser);
yield BrowserTestUtils.synthesizeKey("x", { ctrlKey: sendCtrl, metaKey: sendMeta }, gBrowser);
yield testSelection(elementId, 0, testTypeText + " correctly removed second highlight on selection deletion");
}
function onPageShow() {
gBrowser.removeEventListener("load", onPageShow, true);
Task.spawn(function*() {
gFindBar.open();
yield testInput("inp", "Input:");
yield testInput("tarea", "Textarea:");
}).then(() => {
window.close();
SimpleTest.finish();
});
}
SimpleTest.waitForFocus(startTest, window);
]]></script>
<browser type="content-primary" flex="1" id="content" src="about:blank"/>
<browser type="content-primary" flex="1" id="content-remote" remote="true" src="about:blank"/>
<findbar id="FindToolbar" browserid="content"/>
</window>

View file

@ -1,22 +0,0 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<window title="Test for bug 624329 context menu position"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
context="menu">
<script>
opener.SimpleTest.waitForFocus(opener.childFocused, window);
</script>
<menupopup id="menu">
<!-- The bug demonstrated only when the accesskey was presented separately
from the label.
e.g. because the accesskey is not a letter in the label.
The bug demonstrates only on the first show of the context menu
unless menu items are removed/added each time the menu is
constructed. -->
<menuitem label="Long label to ensure the popup would hit the right of the screen" accesskey="1"/>
</menupopup>
</window>

View file

@ -1,199 +0,0 @@
[DEFAULT]
skip-if = os == 'android'
support-files =
../widgets/popup_shared.js
../widgets/tree_shared.js
RegisterUnregisterChrome.js
bug263683_window.xul
bug304188_window.xul
bug331215_window.xul
bug360437_window.xul
bug366992_window.xul
bug409624_window.xul
bug429723_window.xul
bug624329_window.xul
dialog_dialogfocus.xul
file_about_networking_wsh.py
file_autocomplete_with_composition.js
findbar_entireword_window.xul
findbar_events_window.xul
findbar_window.xul
frame_popup_anchor.xul
frame_popupremoving_frame.xul
frame_subframe_origin_subframe1.xul
frame_subframe_origin_subframe2.xul
popup_childframe_node.xul
popup_trigger.js
sample_entireword_latin1.html
window_browser_drop.xul
window_keys.xul
window_largemenu.xul
window_panel.xul
window_popup_anchor.xul
window_popup_anchoratrect.xul
window_popup_attribute.xul
window_popup_button.xul
window_popup_preventdefault_chrome.xul
window_preferences.xul
window_preferences2.xul
window_preferences3.xul
window_preferences_commandretarget.xul
window_screenPosSize.xul
window_showcaret.xul
window_subframe_origin.xul
window_titlebar.xul
window_tooltip.xul
xul_selectcontrol.js
rtlchrome/rtl.css
rtlchrome/rtl.dtd
rtlchrome/rtl.manifest
rtltest/righttoleft.manifest
rtltest/content/dirtest.xul
[test_about_networking.html]
[test_arrowpanel.xul]
[test_autocomplete2.xul]
[test_autocomplete3.xul]
[test_autocomplete4.xul]
[test_autocomplete5.xul]
[test_autocomplete_delayOnPaste.xul]
subsuite = clipboard
[test_autocomplete_emphasis.xul]
[test_autocomplete_with_composition_on_input.html]
[test_autocomplete_with_composition_on_textbox.xul]
[test_autocomplete_placehold_last_complete.xul]
[test_browser_drop.xul]
[test_bug253481.xul]
subsuite = clipboard
[test_bug263683.xul]
[test_bug304188.xul]
[test_bug331215.xul]
[test_bug360220.xul]
[test_bug360437.xul]
skip-if = os == 'linux' # Bug 1264604
[test_bug365773.xul]
[test_bug366992.xul]
[test_bug382990.xul]
[test_bug409624.xul]
[test_bug418874.xul]
[test_bug429723.xul]
[test_bug437844.xul]
[test_bug457632.xul]
[test_bug460942.xul]
[test_bug471776.xul]
[test_bug509732.xul]
[test_bug554279.xul]
[test_bug557987.xul]
[test_bug562554.xul]
[test_bug570192.xul]
[test_bug585946.xul]
[test_bug624329.xul]
skip-if = (os == 'mac' && os_version == '10.10') # Unexpectedly perma-passes on OSX 10.10
[test_bug792324.xul]
[test_bug1048178.xul]
skip-if = toolkit == "cocoa"
[test_button.xul]
[test_closemenu_attribute.xul]
[test_colorpicker_popup.xul]
[test_contextmenu_list.xul]
[test_datepicker.xul]
[test_deck.xul]
[test_dialogfocus.xul]
[test_findbar.xul]
subsuite = clipboard
[test_findbar_entireword.xul]
[test_findbar_events.xul]
[test_focus_anons.xul]
[test_hiddenitems.xul]
[test_hiddenpaging.xul]
[test_keys.xul]
[test_labelcontrol.xul]
[test_largemenu.xul]
skip-if = os == 'linux' && !debug #Bug 1207174
[test_menu.xul]
[test_menu_anchored.xul]
[test_menu_hide.xul]
[test_menuchecks.xul]
[test_menuitem_blink.xul]
[test_menuitem_commands.xul]
[test_menulist.xul]
[test_menulist_keynav.xul]
[test_menulist_null_value.xul]
[test_menulist_paging.xul]
[test_menulist_position.xul]
[test_mousescroll.xul]
[test_notificationbox.xul]
[test_panel.xul]
[test_panelfrommenu.xul]
[test_popup_anchor.xul]
[test_popup_anchoratrect.xul]
skip-if = os == 'linux' # 1167694
[test_popup_attribute.xul]
skip-if = os == 'linux' && asan #Bug 1131634
[test_popup_button.xul]
skip-if = os == 'linux' && asan # Bug 1281360
[test_popup_coords.xul]
[test_popup_keys.xul]
[test_popup_moveToAnchor.xul]
[test_popup_preventdefault.xul]
[test_popup_preventdefault_chrome.xul]
[test_popup_recreate.xul]
[test_popup_scaled.xul]
[test_popup_tree.xul]
[test_popuphidden.xul]
[test_popupincontent.xul]
[test_popupremoving.xul]
[test_popupremoving_frame.xul]
[test_position.xul]
[test_preferences.xul]
[test_preferences_beforeaccept.xul]
support-files = window_preferences_beforeaccept.xul
[test_preferences_onsyncfrompreference.xul]
support-files = window_preferences_onsyncfrompreference.xul
[test_progressmeter.xul]
[test_props.xul]
[test_radio.xul]
[test_richlist_direction.xul]
[test_righttoleft.xul]
[test_scale.xul]
[test_scaledrag.xul]
[test_screenPersistence.xul]
[test_scrollbar.xul]
[test_showcaret.xul]
[test_sorttemplate.xul]
[test_statusbar.xul]
[test_subframe_origin.xul]
[test_tabbox.xul]
[test_tabindex.xul]
[test_textbox_dictionary.xul]
[test_textbox_emptytext.xul]
[test_textbox_number.xul]
[test_textbox_search.xul]
[test_timepicker.xul]
[test_titlebar.xul]
skip-if = os == "linux"
[test_toolbar.xul]
[test_tooltip.xul]
skip-if = (os == 'mac' && os_version == '10.10') # Bug 1141245, frequent timeouts on OSX 10.10
[test_tooltip_noautohide.xul]
[test_tree.xul]
[test_tree_hier.xul]
[test_tree_hier_cell.xul]
[test_tree_single.xul]
[test_tree_view.xul]
# test_panel_focus.xul won't work if the Full Keyboard Access preference is set to
# textboxes and lists only, so skip this test on Mac
[test_panel_focus.xul]
support-files = window_panel_focus.xul
skip-if = toolkit == "cocoa"
[test_chromemargin.xul]
support-files = window_chromemargin.xul
skip-if = toolkit == "cocoa"
[test_bug451540.xul]
support-files = bug451540_window.xul
[test_autocomplete_mac_caret.xul]
skip-if = toolkit != "cocoa"
[test_cursorsnap.xul]
disabled =
#skip-if = os != "win"
support-files = window_cursorsnap_dialog.xul window_cursorsnap_wizard.xul

View file

@ -1,57 +0,0 @@
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<dialog buttons="extra2,accept,cancel" onload="loaded()"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<tabbox id="tabbox" hidden="true">
<tabs>
<tab id="tab" label="Tab"/>
</tabs>
<tabpanels>
<tabpanel>
<button id="tabbutton" label="Tab Button"/>
<button id="tabbutton2" label="Tab Button 2"/>
</tabpanel>
</tabpanels>
</tabbox>
<textbox id="textbox-yes" value="textbox-yes" hidden="true"/>
<textbox id="textbox-no" value="textbox-no" noinitialfocus="true" hidden="true"/>
<button id="one" label="One"/>
<button id="two" label="Two" hidden="true"/>
<script>
function loaded()
{
if (window.arguments) {
var step = window.arguments[0];
switch (step) {
case 2:
document.getElementById("one").setAttribute("noinitialfocus", "true");
break;
case 3:
document.getElementById("one").hidden = true;
case 4:
document.getElementById("tabbutton2").setAttribute("noinitialfocus", "true");
case 5:
document.getElementById("tabbutton").setAttribute("noinitialfocus", "true");
case 6:
document.getElementById("tabbox").hidden = false;
break;
case 7:
var two = document.getElementById("two");
two.hidden = false;
two.focus();
break;
case 8:
document.getElementById("textbox-yes").hidden = false;
break;
case 9:
document.getElementById("textbox-no").hidden = false;
break;
}
}
}
</script>
</dialog>

View file

@ -1,9 +0,0 @@
from mod_pywebsocket import msgutil
def web_socket_do_extra_handshake(request):
pass
def web_socket_transfer_data(request):
while not request.client_terminated:
msgutil.receive_message(request)

View file

@ -1,540 +0,0 @@
// nsDoTestsForAutoCompleteWithComposition tests autocomplete with composition.
// Users must include SimpleTest.js and EventUtils.js.
function waitForCondition(condition, nextTest) {
var tries = 0;
var interval = setInterval(function() {
if (condition() || tries >= 30) {
moveOn();
}
tries++;
}, 100);
var moveOn = function() { clearInterval(interval); nextTest(); };
}
function nsDoTestsForAutoCompleteWithComposition(aDescription,
aWindow,
aTarget,
aAutoCompleteController,
aIsFunc,
aGetTargetValueFunc,
aOnFinishFunc)
{
this._description = aDescription;
this._window = aWindow;
this._target = aTarget;
this._controller = aAutoCompleteController;
this._is = aIsFunc;
this._getTargetValue = aGetTargetValueFunc;
this._onFinish = aOnFinishFunc;
this._target.focus();
this._DefaultCompleteDefaultIndex =
this._controller.input.completeDefaultIndex;
this._doTests();
}
nsDoTestsForAutoCompleteWithComposition.prototype = {
_window: null,
_target: null,
_controller: null,
_DefaultCompleteDefaultIndex: false,
_description: "",
_is: null,
_getTargetValue: function () { return "not initialized"; },
_onFinish: null,
_doTests: function ()
{
if (++this._testingIndex == this._tests.length) {
this._controller.input.completeDefaultIndex =
this._DefaultCompleteDefaultIndex;
this._onFinish();
return;
}
var test = this._tests[this._testingIndex];
if (this._controller.input.completeDefaultIndex != test.completeDefaultIndex) {
this._controller.input.completeDefaultIndex = test.completeDefaultIndex;
}
test.execute(this._window);
waitForCondition(() => {
return this._controller.searchStatus >=
Components.interfaces.nsIAutoCompleteController.STATUS_COMPLETE_NO_MATCH;
},
this._checkResult.bind(this));
},
_checkResult: function ()
{
var test = this._tests[this._testingIndex];
this._is(this._getTargetValue(), test.value,
this._description + ", " + test.description + ": value");
this._is(this._controller.searchString, test.searchString,
this._description + ", " + test.description +": searchString");
this._is(this._controller.input.popupOpen, test.popup,
this._description + ", " + test.description + ": popupOpen");
this._doTests();
},
_testingIndex: -1,
_tests: [
// Simple composition when popup hasn't been shown.
// The autocomplete popup should not be shown during composition, but
// after compositionend, the popup should be shown.
{ description: "compositionstart shouldn't open the popup",
completeDefaultIndex: false,
execute: function (aWindow) {
synthesizeCompositionChange(
{ "composition":
{ "string": "M",
"clauses":
[
{ "length": 1, "attr": COMPOSITION_ATTR_RAW_CLAUSE }
]
},
"caret": { "start": 1, "length": 0 },
"key": { key: "M", code: "KeyM", keyCode: KeyboardEvent.DOM_VK_M,
shiftKey: true },
}, aWindow);
}, popup: false, value: "M", searchString: ""
},
{ description: "modifying composition string shouldn't open the popup",
completeDefaultIndex: false,
execute: function (aWindow) {
synthesizeCompositionChange(
{ "composition":
{ "string": "Mo",
"clauses":
[
{ "length": 2, "attr": COMPOSITION_ATTR_RAW_CLAUSE }
]
},
"caret": { "start": 2, "length": 0 },
"key": { key: "o", code: "KeyO", keyCode: KeyboardEvent.DOM_VK_O },
}, aWindow);
}, popup: false, value: "Mo", searchString: ""
},
{ description: "compositionend should open the popup",
completeDefaultIndex: false,
execute: function (aWindow) {
synthesizeComposition({ type: "compositioncommitasis",
key: { key: "KEY_Enter", code: "Enter" } }, aWindow);
}, popup: true, value: "Mo", searchString: "Mo"
},
// If composition starts when popup is shown, the compositionstart event
// should cause closing the popup.
{ description: "compositionstart should close the popup",
completeDefaultIndex: false,
execute: function (aWindow) {
synthesizeCompositionChange(
{ "composition":
{ "string": "z",
"clauses":
[
{ "length": 1, "attr": COMPOSITION_ATTR_RAW_CLAUSE }
]
},
"caret": { "start": 1, "length": 0 },
"key": { key: "z", code: "KeyZ", keyCode: KeyboardEvent.DOM_VK_Z },
}, aWindow);
}, popup: false, value: "Moz", searchString: "Mo"
},
{ description: "modifying composition string shouldn't reopen the popup",
completeDefaultIndex: false,
execute: function (aWindow) {
synthesizeCompositionChange(
{ "composition":
{ "string": "zi",
"clauses":
[
{ "length": 2, "attr": COMPOSITION_ATTR_RAW_CLAUSE }
]
},
"caret": { "start": 2, "length": 0 },
"key": { key: "i", code: "KeyI", keyCode: KeyboardEvent.DOM_VK_I },
}, aWindow);
}, popup: false, value: "Mozi", searchString: "Mo"
},
{ description: "compositionend should research the result and open the popup",
completeDefaultIndex: false,
execute: function (aWindow) {
synthesizeComposition({ type: "compositioncommitasis",
key: { key: "KEY_Enter", code: "Enter" } }, aWindow);
}, popup: true, value: "Mozi", searchString: "Mozi"
},
// If composition is cancelled, the value shouldn't be changed.
{ description: "compositionstart should reclose the popup",
completeDefaultIndex: false,
execute: function (aWindow) {
synthesizeCompositionChange(
{ "composition":
{ "string": "l",
"clauses":
[
{ "length": 1, "attr": COMPOSITION_ATTR_RAW_CLAUSE }
]
},
"caret": { "start": 1, "length": 0 },
"key": { key: "l", code: "KeyL", keyCode: KeyboardEvent.DOM_VK_L },
}, aWindow);
}, popup: false, value: "Mozil", searchString: "Mozi"
},
{ description: "modifying composition string shouldn't reopen the popup",
completeDefaultIndex: false,
execute: function (aWindow) {
synthesizeCompositionChange(
{ "composition":
{ "string": "ll",
"clauses":
[
{ "length": 2, "attr": COMPOSITION_ATTR_RAW_CLAUSE }
]
},
"caret": { "start": 2, "length": 0 },
"key": { key: "l", code: "KeyL", keyCode: KeyboardEvent.DOM_VK_L },
}, aWindow);
}, popup: false, value: "Mozill", searchString: "Mozi"
},
{ description: "modifying composition string to empty string shouldn't reopen the popup",
completeDefaultIndex: false,
execute: function (aWindow) {
synthesizeCompositionChange(
{ "composition":
{ "string": "",
"clauses":
[
{ "length": 0, "attr": 0 }
]
},
"caret": { "start": 0, "length": 0 }
}, aWindow);
}, popup: false, value: "Mozi", searchString: "Mozi"
},
{ description: "cancled compositionend should reopen the popup",
completeDefaultIndex: false,
execute: function (aWindow) {
synthesizeComposition({ type: "compositioncommit", data: "",
key: { key: "KEY_Escape", code: "Escape" } }, aWindow);
}, popup: true, value: "Mozi", searchString: "Mozi"
},
// But if composition replaces some characters and canceled, the search
// string should be the latest value.
{ description: "compositionstart with selected string should close the popup",
completeDefaultIndex: false,
execute: function (aWindow) {
synthesizeKey("VK_LEFT", { shiftKey: true }, aWindow);
synthesizeKey("VK_LEFT", { shiftKey: true }, aWindow);
synthesizeCompositionChange(
{ "composition":
{ "string": "z",
"clauses":
[
{ "length": 1, "attr": COMPOSITION_ATTR_RAW_CLAUSE }
]
},
"caret": { "start": 1, "length": 0 },
"key": { key: "z", code: "KeyZ", keyCode: KeyboardEvent.DOM_VK_Z },
}, aWindow);
}, popup: false, value: "Moz", searchString: "Mozi"
},
{ description: "modifying composition string shouldn't reopen the popup",
completeDefaultIndex: false,
execute: function (aWindow) {
synthesizeCompositionChange(
{ "composition":
{ "string": "zi",
"clauses":
[
{ "length": 2, "attr": COMPOSITION_ATTR_RAW_CLAUSE }
]
},
"caret": { "start": 2, "length": 0 },
"key": { key: "i", code: "KeyI", keyCode: KeyboardEvent.DOM_VK_I },
}, aWindow);
}, popup: false, value: "Mozi", searchString: "Mozi"
},
{ description: "modifying composition string to empty string shouldn't reopen the popup",
completeDefaultIndex: false,
execute: function (aWindow) {
synthesizeCompositionChange(
{ "composition":
{ "string": "",
"clauses":
[
{ "length": 0, "attr": 0 }
]
},
"caret": { "start": 0, "length": 0 }
}, aWindow);
}, popup: false, value: "Mo", searchString: "Mozi"
},
{ description: "canceled compositionend should search the result with the latest value",
completeDefaultIndex: false,
execute: function (aWindow) {
synthesizeComposition({ type: "compositioncommitasis",
key: { key: "KEY_Escape", code: "Escape" } }, aWindow);
}, popup: true, value: "Mo", searchString: "Mo"
},
// If all characters are removed, the popup should be closed.
{ description: "the value becomes empty by backspace, the popup should be closed",
completeDefaultIndex: false,
execute: function (aWindow) {
synthesizeKey("VK_BACK_SPACE", {}, aWindow);
synthesizeKey("VK_BACK_SPACE", {}, aWindow);
}, popup: false, value: "", searchString: ""
},
// composition which is canceled shouldn't cause opening the popup.
{ description: "compositionstart shouldn't open the popup",
completeDefaultIndex: false,
execute: function (aWindow) {
synthesizeCompositionChange(
{ "composition":
{ "string": "M",
"clauses":
[
{ "length": 1, "attr": COMPOSITION_ATTR_RAW_CLAUSE }
]
},
"caret": { "start": 1, "length": 0 },
"key": { key: "m", code: "KeyM", keyCode: KeyboardEvent.DOM_VK_M,
shiftKey: true },
}, aWindow);
}, popup: false, value: "M", searchString: ""
},
{ description: "modifying composition string shouldn't open the popup",
completeDefaultIndex: false,
execute: function (aWindow) {
synthesizeCompositionChange(
{ "composition":
{ "string": "Mo",
"clauses":
[
{ "length": 2, "attr": COMPOSITION_ATTR_RAW_CLAUSE }
]
},
"caret": { "start": 2, "length": 0 },
"key": { key: "o", code: "KeyO", keyCode: KeyboardEvent.DOM_VK_O },
}, aWindow);
}, popup: false, value: "Mo", searchString: ""
},
{ description: "modifying composition string to empty string shouldn't open the popup",
completeDefaultIndex: false,
execute: function (aWindow) {
synthesizeCompositionChange(
{ "composition":
{ "string": "",
"clauses":
[
{ "length": 0, "attr": 0 }
]
},
"caret": { "start": 0, "length": 0 }
}, aWindow);
}, popup: false, value: "", searchString: ""
},
{ description: "canceled compositionend shouldn't open the popup if it was closed",
completeDefaultIndex: false,
execute: function (aWindow) {
synthesizeComposition({ type: "compositioncommitasis",
key: { key: "KEY_Escape", code: "Escape" } }, aWindow);
}, popup: false, value: "", searchString: ""
},
// Down key should open the popup even if the editor is empty.
{ description: "DOWN key should open the popup even if the value is empty",
completeDefaultIndex: false,
execute: function (aWindow) {
synthesizeKey("VK_DOWN", {}, aWindow);
}, popup: true, value: "", searchString: ""
},
// If popup is open at starting composition, the popup should be reopened
// after composition anyway.
{ description: "compositionstart shouldn't open the popup",
completeDefaultIndex: false,
execute: function (aWindow) {
synthesizeCompositionChange(
{ "composition":
{ "string": "M",
"clauses":
[
{ "length": 1, "attr": COMPOSITION_ATTR_RAW_CLAUSE }
]
},
"caret": { "start": 1, "length": 0 },
"key": { key: "M", code: "KeyM", keyCode: KeyboardEvent.DOM_VK_M,
shiftKey: true },
}, aWindow);
}, popup: false, value: "M", searchString: ""
},
{ description: "modifying composition string shouldn't open the popup",
completeDefaultIndex: false,
execute: function (aWindow) {
synthesizeCompositionChange(
{ "composition":
{ "string": "Mo",
"clauses":
[
{ "length": 2, "attr": COMPOSITION_ATTR_RAW_CLAUSE }
]
},
"caret": { "start": 2, "length": 0 },
"key": { key: "o", code: "KeyO", keyCode: KeyboardEvent.DOM_VK_O },
}, aWindow);
}, popup: false, value: "Mo", searchString: ""
},
{ description: "modifying composition string to empty string shouldn't open the popup",
completeDefaultIndex: false,
execute: function (aWindow) {
synthesizeCompositionChange(
{ "composition":
{ "string": "",
"clauses":
[
{ "length": 0, "attr": 0 }
]
},
"caret": { "start": 0, "length": 0 }
}, aWindow);
}, popup: false, value: "", searchString: ""
},
{ description: "canceled compositionend should open the popup if it was opened",
completeDefaultIndex: false,
execute: function (aWindow) {
synthesizeComposition({ type: "compositioncommitasis",
key: { key: "KEY_Escape", code: "Escape" } }, aWindow);
}, popup: true, value: "", searchString: ""
},
// Type normally, and hit escape, the popup should be closed.
{ description: "ESCAPE should close the popup after typing something",
completeDefaultIndex: false,
execute: function (aWindow) {
synthesizeKey("M", { shiftKey: true }, aWindow);
synthesizeKey("o", { shiftKey: true }, aWindow);
synthesizeKey("VK_ESCAPE", {}, aWindow);
}, popup: false, value: "Mo", searchString: "Mo"
},
// Even if the popup is closed, composition which is canceled should open
// the popup if the value isn't empty.
// XXX This might not be good behavior, but anyway, this is minor issue...
{ description: "compositionstart shouldn't open the popup",
completeDefaultIndex: false,
execute: function (aWindow) {
synthesizeCompositionChange(
{ "composition":
{ "string": "z",
"clauses":
[
{ "length": 1, "attr": COMPOSITION_ATTR_RAW_CLAUSE }
]
},
"caret": { "start": 1, "length": 0 },
"key": { key: "z", code: "KeyZ", keyCode: KeyboardEvent.DOM_VK_Z },
}, aWindow);
}, popup: false, value: "Moz", searchString: "Mo"
},
{ description: "modifying composition string shouldn't open the popup",
completeDefaultIndex: false,
execute: function (aWindow) {
synthesizeCompositionChange(
{ "composition":
{ "string": "zi",
"clauses":
[
{ "length": 2, "attr": COMPOSITION_ATTR_RAW_CLAUSE }
]
},
"caret": { "start": 2, "length": 0 },
"key": { key: "i", code: "KeyI", keyCode: KeyboardEvent.DOM_VK_I },
}, aWindow);
}, popup: false, value: "Mozi", searchString: "Mo"
},
{ description: "modifying composition string to empty string shouldn't open the popup",
completeDefaultIndex: false,
execute: function (aWindow) {
synthesizeCompositionChange(
{ "composition":
{ "string": "",
"clauses":
[
{ "length": 0, "attr": 0 }
]
},
"caret": { "start": 0, "length": 0 }
}, aWindow);
}, popup: false, value: "Mo", searchString: "Mo"
},
{ description: "canceled compositionend shouldn't open the popup if the popup was closed",
completeDefaultIndex: false,
execute: function (aWindow) {
synthesizeComposition({ type: "compositioncommitasis",
key: { key: "KEY_Escape", code: "Escape" } }, aWindow);
}, popup: true, value: "Mo", searchString: "Mo"
},
// House keeping...
{ description: "house keeping for next tests",
completeDefaultIndex: false,
execute: function (aWindow) {
synthesizeKey("VK_BACK_SPACE", {}, aWindow);
synthesizeKey("VK_BACK_SPACE", {}, aWindow);
}, popup: false, value: "", searchString: ""
},
// Testing for nsIAutoCompleteInput.completeDefaultIndex being true.
{ description: "compositionstart shouldn't open the popup (completeDefaultIndex is true)",
completeDefaultIndex: true,
execute: function (aWindow) {
synthesizeCompositionChange(
{ "composition":
{ "string": "M",
"clauses":
[
{ "length": 1, "attr": COMPOSITION_ATTR_RAW_CLAUSE }
]
},
"caret": { "start": 1, "length": 0 },
"key": { key: "M", code: "KeyM", keyCode: KeyboardEvent.DOM_VK_M,
shiftKey: true },
}, aWindow);
}, popup: false, value: "M", searchString: ""
},
{ description: "modifying composition string shouldn't open the popup (completeDefaultIndex is true)",
completeDefaultIndex: true,
execute: function (aWindow) {
synthesizeCompositionChange(
{ "composition":
{ "string": "Mo",
"clauses":
[
{ "length": 2, "attr": COMPOSITION_ATTR_RAW_CLAUSE }
]
},
"caret": { "start": 2, "length": 0 },
"key": { key: "o", code: "KeyO", keyCode: KeyboardEvent.DOM_VK_O },
}, aWindow);
}, popup: false, value: "Mo", searchString: ""
},
{ description: "compositionend should open the popup (completeDefaultIndex is true)",
completeDefaultIndex: true,
execute: function (aWindow) {
synthesizeComposition({ type: "compositioncommitasis",
key: { key: "KEY_Enter", code: "Enter" } }, aWindow);
}, popup: true, value: "Mozilla", searchString: "Mo"
},
// House keeping...
{ description: "house keeping for next tests",
completeDefaultIndex: false,
execute: function (aWindow) {
synthesizeKey("VK_BACK_SPACE", {}, aWindow);
synthesizeKey("VK_BACK_SPACE", {}, aWindow);
synthesizeKey("VK_BACK_SPACE", {}, aWindow);
synthesizeKey("VK_BACK_SPACE", {}, aWindow);
synthesizeKey("VK_BACK_SPACE", {}, aWindow);
synthesizeKey("VK_BACK_SPACE", {}, aWindow);
}, popup: false, value: "", searchString: ""
}
]
};

View file

@ -1,275 +0,0 @@
<?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"?>
<window id="FindbarEntireWordTest"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
width="600"
height="600"
onload="onLoad();"
title="findbar test - entire words only">
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/ChromeUtils.js"/>
<script type="application/javascript"><![CDATA[
const {interfaces: Ci, classes: Cc, results: Cr, utils: Cu} = Components;
Cu.import("resource://gre/modules/Task.jsm");
Cu.import("resource://testing-common/ContentTask.jsm");
ContentTask.setTestScope(window.opener.wrappedJSObject);
var gFindBar = null;
var gBrowser;
var imports = ["SimpleTest", "SpecialPowers", "ok", "is", "isnot", "info"];
for (var name of imports) {
window[name] = window.opener.wrappedJSObject[name];
}
SimpleTest.requestLongerTimeout(2);
const kBaseURL = "chrome://mochitests/content/chrome/toolkit/content/tests/chrome";
const kTests = {
latin1: {
testSimpleEntireWord: {
"and": results => {
isnot(results.find.result, Ci.nsITypeAheadFind.FIND_NOTFOUND, "'and' should've been found");
is(results.matches.total, 6, "should've found 6 matches");
},
"an": results => {
is(results.find.result, Ci.nsITypeAheadFind.FIND_NOTFOUND, "'an' shouldn't have been found");
is(results.matches.total, 0, "should've found 0 matches");
},
"darkness": results => {
isnot(results.find.result, Ci.nsITypeAheadFind.FIND_NOTFOUND, "'darkness' should've been found");
is(results.matches.total, 3, "should've found 3 matches");
},
"mammon": results => {
isnot(results.find.result, Ci.nsITypeAheadFind.FIND_NOTFOUND, "'mammon' should've been found");
is(results.matches.total, 1, "should've found 1 match");
}
},
testCaseSensitive: {
"And": results => {
isnot(results.find.result, Ci.nsITypeAheadFind.FIND_NOTFOUND, "'And' should've been found");
is(results.matches.total, 1, "should've found 1 match");
},
"and": results => {
isnot(results.find.result, Ci.nsITypeAheadFind.FIND_NOTFOUND, "'and' should've been found");
is(results.matches.total, 5, "should've found 5 matches");
},
"Mammon": results => {
isnot(results.find.result, Ci.nsITypeAheadFind.FIND_NOTFOUND, "'mammon' should've been found");
is(results.matches.total, 1, "should've found 1 match");
}
},
testWordBreakChars: {
"a": results => {
// 'a' is a common charactar, but there should only be one occurrence
// separated by word boundaries.
isnot(results.find.result, Ci.nsITypeAheadFind.FIND_NOTFOUND, "'a' should've been found");
is(results.matches.total, 1, "should've found 1 match");
},
"quarrelled": results => {
// 'quarrelled' is denoted as a word by a period char.
isnot(results.find.result, Ci.nsITypeAheadFind.FIND_NOTFOUND, "'quarrelled' should've been found");
is(results.matches.total, 1, "should've found 1 match");
}
},
testQuickfind: {
"and": results => {
isnot(results.find.result, Ci.nsITypeAheadFind.FIND_NOTFOUND, "'and' should've been found");
is(results.matches.total, 6, "should've found 6 matches");
},
"an": results => {
is(results.find.result, Ci.nsITypeAheadFind.FIND_NOTFOUND, "'an' shouldn't have been found");
is(results.matches.total, 0, "should've found 0 matches");
},
"darkness": results => {
isnot(results.find.result, Ci.nsITypeAheadFind.FIND_NOTFOUND, "'darkness' should've been found");
is(results.matches.total, 3, "should've found 3 matches");
},
"mammon": results => {
isnot(results.find.result, Ci.nsITypeAheadFind.FIND_NOTFOUND, "'mammon' should've been found");
is(results.matches.total, 1, "should've found 1 match");
}
}
}
};
function onLoad() {
Task.spawn(function* () {
yield new Promise(resolve => {
SpecialPowers.pushPrefEnv(
{ set: [["findbar.entireword", true]] }, resolve);
});
gFindBar = document.getElementById("FindToolbar");
for (let browserId of ["content", "content-remote"]) {
// XXXmikedeboer: when multiple test samples are available, make this
// a nested loop that iterates over them. For now, only
// latin is available.
yield startTestWithBrowser("latin1", browserId);
}
}).then(() => {
window.close();
SimpleTest.finish();
});
}
function* startTestWithBrowser(testName, browserId) {
info("Starting test with browser '" + browserId + "'");
gBrowser = document.getElementById(browserId);
gFindBar.browser = gBrowser;
let promise = ContentTask.spawn(gBrowser, null, function* () {
return new Promise(resolve => {
addEventListener("DOMContentLoaded", function listener() {
removeEventListener("DOMContentLoaded", listener);
resolve();
});
});
});
gBrowser.loadURI(kBaseURL + "/sample_entireword_" + testName + ".html");
yield promise;
yield onDocumentLoaded(testName);
}
function* onDocumentLoaded(testName) {
let suite = kTests[testName];
yield testSimpleEntireWord(suite.testSimpleEntireWord);
yield testCaseSensitive(suite.testCaseSensitive);
yield testWordBreakChars(suite.testWordBreakChars);
yield testQuickfind(suite.testQuickfind);
}
var enterStringIntoFindField = Task.async(function* (str, waitForResult = true) {
for (let promise, i = 0; i < str.length; i++) {
if (waitForResult) {
promise = promiseFindResult();
}
let event = document.createEvent("KeyboardEvent");
event.initKeyEvent("keypress", true, true, null, false, false,
false, false, 0, str.charCodeAt(i));
gFindBar._findField.inputField.dispatchEvent(event);
if (waitForResult) {
yield promise;
}
}
});
function openFindbar() {
document.getElementById("cmd_find").doCommand();
return gFindBar._startFindDeferred && gFindBar._startFindDeferred.promise;
}
function promiseFindResult(searchString) {
return new Promise(resolve => {
let data = {};
let listener = {
onFindResult: res => {
if (searchString && res.searchString != searchString)
return;
gFindBar.browser.finder.removeResultListener(listener);
data.find = res;
if (res.result == Ci.nsITypeAheadFind.FIND_NOTFOUND) {
data.matches = { total: 0, current: 0 };
resolve(data);
return;
}
listener = {
onMatchesCountResult: res => {
gFindBar.browser.finder.removeResultListener(listener);
data.matches = res;
resolve(data);
}
};
gFindBar.browser.finder.addResultListener(listener);
}
};
gFindBar.browser.finder.addResultListener(listener);
});
}
function* testIterator(tests) {
for (let searchString of Object.getOwnPropertyNames(tests)) {
gFindBar.clear();
let promise = promiseFindResult(searchString);
yield enterStringIntoFindField(searchString, false);
let result = yield promise;
tests[searchString](result);
}
}
function* testSimpleEntireWord(tests) {
yield openFindbar();
ok(!gFindBar.hidden, "testSimpleEntireWord: findbar should be open");
yield* testIterator(tests);
gFindBar.close();
}
function* testCaseSensitive(tests) {
yield openFindbar();
ok(!gFindBar.hidden, "testCaseSensitive: findbar should be open");
let matchCaseCheckbox = gFindBar.getElement("find-case-sensitive");
if (!matchCaseCheckbox.hidden && !matchCaseCheckbox.checked)
matchCaseCheckbox.click();
yield* testIterator(tests);
if (!matchCaseCheckbox.hidden)
matchCaseCheckbox.click();
gFindBar.close();
}
function* testWordBreakChars(tests) {
yield openFindbar();
ok(!gFindBar.hidden, "testWordBreakChars: findbar should be open");
yield* testIterator(tests);
gFindBar.close();
}
function* testQuickfind(tests) {
yield ContentTask.spawn(gBrowser, null, function* () {
let document = content.document;
let event = document.createEvent("KeyboardEvent");
event.initKeyEvent("keypress", true, true, null, false, false,
false, false, 0, "/".charCodeAt(0));
document.documentElement.dispatchEvent(event);
});
ok(!gFindBar.hidden, "testQuickfind: failed to open findbar");
ok(document.commandDispatcher.focusedElement == gFindBar._findField.inputField,
"testQuickfind: find field is not focused");
ok(!gFindBar.getElement("entire-word-status").hidden,
"testQuickfind: entire word mode status text should be visible");
yield* testIterator(tests);
gFindBar.close();
}
]]></script>
<commandset>
<command id="cmd_find" oncommand="document.getElementById('FindToolbar').onFindCommand();"/>
</commandset>
<browser type="content-primary" flex="1" id="content" src="about:blank"/>
<browser type="content-primary" flex="1" id="content-remote" remote="true" src="about:blank"/>
<findbar id="FindToolbar" browserid="content"/>
</window>

View file

@ -1,173 +0,0 @@
<?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="SimpleTest.executeSoon(startTest);"
title="findbar events test">
<script type="application/javascript"><![CDATA[
const {interfaces: Ci, classes: Cc, results: Cr, utils: Cu} = Components;
Cu.import("resource://gre/modules/Task.jsm");
Cu.import("resource://testing-common/BrowserTestUtils.jsm");
Cu.import("resource://testing-common/ContentTask.jsm");
ContentTask.setTestScope(window.opener.wrappedJSObject);
var gFindBar = null;
var gBrowser;
const kTimeout = 5000; // 5 seconds.
var imports = ["SimpleTest", "ok", "is", "info"];
for (var name of imports) {
window[name] = window.opener.wrappedJSObject[name];
}
SimpleTest.requestLongerTimeout(2);
function startTest() {
Task.spawn(function* () {
gFindBar = document.getElementById("FindToolbar");
for (let browserId of ["content", "content-remote"]) {
yield startTestWithBrowser(browserId);
}
}).then(() => {
window.close();
SimpleTest.finish();
});
}
function* startTestWithBrowser(browserId) {
info("Starting test with browser '" + browserId + "'");
gBrowser = document.getElementById(browserId);
gFindBar.browser = gBrowser;
let promise = BrowserTestUtils.browserLoaded(gBrowser);
gBrowser.loadURI("data:text/html,hello there");
yield promise;
yield onDocumentLoaded();
}
function* onDocumentLoaded() {
gFindBar.open();
gFindBar.onFindCommand();
yield testFind();
yield testFindAgain();
yield testCaseSensitivity();
yield testHighlight();
}
function checkSelection() {
return new Promise(resolve => {
SimpleTest.executeSoon(() => {
ContentTask.spawn(gBrowser, null, function* () {
let selected = content.getSelection();
Assert.equal(String(selected), "", "No text is selected");
let controller = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsISelectionDisplay)
.QueryInterface(Ci.nsISelectionController);
let selection = controller.getSelection(controller.SELECTION_FIND);
Assert.equal(selection.rangeCount, 0, "No text is highlighted");
}).then(resolve);
});
});
}
function once(node, eventName, preventDefault = true) {
return new Promise((resolve, reject) => {
let timeout = window.setTimeout(() => {
reject("Event wasn't fired within " + kTimeout + "ms for event '" +
eventName + "'.");
}, kTimeout);
node.addEventListener(eventName, function clb(e) {
window.clearTimeout(timeout);
node.removeEventListener(eventName, clb);
if (preventDefault)
e.preventDefault();
resolve(e);
});
});
}
function* testFind() {
info("Testing normal find.");
let query = "t";
let promise = once(gFindBar, "find");
// Put some text in the find box.
let event = document.createEvent("KeyboardEvent");
event.initKeyEvent("keypress", true, true, null, false, false,
false, false, 0, query.charCodeAt(0));
gFindBar._findField.inputField.dispatchEvent(event);
let e = yield promise;
ok(e.detail.query === query, "find event query should match '" + query + "'");
// Since we're preventing the default make sure nothing was selected.
yield checkSelection();
}
function testFindAgain() {
info("Testing repeating normal find.");
let promise = once(gFindBar, "findagain");
gFindBar.onFindAgainCommand();
yield promise;
// Since we're preventing the default make sure nothing was selected.
yield checkSelection();
}
function* testCaseSensitivity() {
info("Testing normal case sensitivity.");
let promise = once(gFindBar, "findcasesensitivitychange", false);
let matchCaseCheckbox = gFindBar.getElement("find-case-sensitive");
matchCaseCheckbox.click();
let e = yield promise;
ok(e.detail.caseSensitive, "find should be case sensitive");
// Toggle it back to the original setting.
matchCaseCheckbox.click();
// Changing case sensitivity does the search so clear the selected text
// before the next test.
yield ContentTask.spawn(gBrowser, null, () => content.getSelection().removeAllRanges());
}
function* testHighlight() {
info("Testing find with highlight all.");
// Update the find state so the highlight button is clickable.
gFindBar.updateControlState(Ci.nsITypeAheadFind.FIND_FOUND, false);
let promise = once(gFindBar, "findhighlightallchange");
let highlightButton = gFindBar.getElement("highlight");
if (!highlightButton.checked)
highlightButton.click();
let e = yield promise;
ok(e.detail.highlightAll, "find event should have highlight all set");
// Since we're preventing the default make sure nothing was highlighted.
yield checkSelection();
// Toggle it back to the original setting.
if (highlightButton.checked)
highlightButton.click();
}
]]></script>
<browser type="content-primary" flex="1" id="content" src="about:blank"/>
<browser type="content-primary" flex="1" id="content-remote" remote="true" src="about:blank"/>
<findbar id="FindToolbar" browserid="content"/>
</window>

View file

@ -1,756 +0,0 @@
<?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 type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/>
<script type="application/javascript"><![CDATA[
const {interfaces: Ci, classes: Cc, results: Cr, utils: Cu} = Components;
Cu.import("resource://gre/modules/AppConstants.jsm");
Cu.import("resource://gre/modules/Task.jsm");
Cu.import("resource://testing-common/BrowserTestUtils.jsm");
Cu.import("resource://testing-common/ContentTask.jsm");
ContentTask.setTestScope(window.opener.wrappedJSObject);
var gPrefsvc = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch);
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 = gPrefsvc.getIntPref("findbar.iteratorTimeout");
var gFindBar = null;
var gBrowser;
var gClipboard = Cc["@mozilla.org/widget/clipboard;1"].getService(Ci.nsIClipboard);
var gHasFindClipboard = gClipboard.supportsFindClipboard();
var gStatusText;
var gXULBrowserWindow = {
QueryInterface: function(aIID) {
if (aIID.Equals(Ci.nsIXULBrowserWindow) ||
aIID.Equals(Ci.nsISupports))
return this;
throw Cr.NS_NOINTERFACE;
},
setJSStatus: function() { },
setOverLink: function(aStatusText, aLink) {
gStatusText = aStatusText;
},
onBeforeLinkTraversal: function() { }
};
var imports = ["SimpleTest", "ok", "is", "info"];
for (var name of imports) {
window[name] = window.opener.wrappedJSObject[name];
}
SimpleTest.requestLongerTimeout(2);
function onLoad() {
Task.spawn(function* () {
window.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShellTreeItem)
.treeOwner
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIXULWindow)
.XULBrowserWindow = gXULBrowserWindow;
gFindBar = document.getElementById("FindToolbar");
for (let browserId of ["content", "content-remote"]) {
yield startTestWithBrowser(browserId);
}
}).then(() => {
window.close();
SimpleTest.finish();
});
}
function* startTestWithBrowser(browserId) {
info("Starting test with browser '" + browserId + "'");
gBrowser = document.getElementById(browserId);
gFindBar.browser = gBrowser;
// Tests delays the loading of a document for one second.
yield new Promise(resolve => setTimeout(resolve, 1000));
let promise = BrowserTestUtils.browserLoaded(gBrowser);
gBrowser.loadURI("data:text/html,<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'/>");
yield promise;
yield onDocumentLoaded();
}
function* onDocumentLoaded() {
yield testNormalFind();
gFindBar.close();
ok(gFindBar.hidden, "Failed to close findbar after testNormalFind");
yield openFindbar();
yield testNormalFindWithComposition();
gFindBar.close();
ok(gFindBar.hidden, "findbar should be hidden after testNormalFindWithComposition");
yield openFindbar();
yield testAutoCaseSensitivityUI();
yield 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) {
yield testFindWithHighlight();
gFindBar.close();
ok(gFindBar.hidden, "Failed to close findbar after testFindWithHighlight");
}
yield 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();
yield testQuickFindLink();
if (gHasFindClipboard) {
yield testStatusText();
}
if (!AppConstants.DEBUG) {
yield testFindCountUI();
gFindBar.close();
ok(gFindBar.hidden, "Failed to close findbar after testFindCountUI");
yield testFindCountUI(true);
gFindBar.close();
ok(gFindBar.hidden, "Failed to close findbar after testFindCountUI - linksOnly");
}
yield openFindbar();
yield testFindAfterCaseChanged();
gFindBar.close();
yield openFindbar();
yield testFailedStringReset();
gFindBar.close();
yield testQuickFindClose();
// TODO: This doesn't seem to work when the findbar is connected to a
// remote browser element.
if (!gBrowser.hasAttribute("remote"))
yield testFindAgainNotFound();
yield testToggleEntireWord();
}
function* testFindbarSelection() {
function checkFindbarState(aTestName, aExpSelection) {
ok(!gFindBar.hidden, "testFindbarSelection: failed to open findbar: " + aTestName);
ok(document.commandDispatcher.focusedElement == gFindBar._findField.inputField,
"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.
yield ContentTask.spawn(gBrowser, null, 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);
});
yield openFindbar();
checkFindbarState("plain text", SEARCH_TEXT);
// Test nsIDOMNSEditableElement with selection.
yield ContentTask.spawn(gBrowser, null, function* () {
let textInput = content.document.getElementById("text");
textInput.focus();
textInput.select();
});
yield openFindbar();
checkFindbarState("text input", SAMPLE_TEXT);
// Test non-editable nsIDOMNSEditableElement (button).
yield ContentTask.spawn(gBrowser, null, function* () {
content.document.getElementById("button").focus();
});
yield 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.inputField.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() {
return new Promise(resolve => {
let listener = {
onFindResult: function(result) {
gFindBar.browser.finder.removeResultListener(listener);
resolve(result);
}
};
gFindBar.browser.finder.addResultListener(listener);
});
}
function promiseMatchesCountResult() {
return new Promise(resolve => {
let listener = {
onMatchesCountResult: function() {
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() {
return new Promise(resolve => {
let listener = {
onHighlightFinished() {
gFindBar.browser.finder.removeResultListener(listener);
resolve();
}
};
gFindBar.browser.finder.addResultListener(listener);
});
}
var enterStringIntoFindField = Task.async(function* (str, waitForResult = true) {
for (let promise, i = 0; i < str.length; i++) {
if (waitForResult) {
promise = promiseFindResult();
}
let event = document.createEvent("KeyboardEvent");
event.initKeyEvent("keypress", true, true, null, false, false,
false, false, 0, str.charCodeAt(i));
gFindBar._findField.inputField.dispatchEvent(event);
if (waitForResult) {
yield promise;
}
}
});
function promiseExpectRangeCount(rangeCount) {
return ContentTask.spawn(gBrowser, { rangeCount }, 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
function* testNormalFind() {
document.getElementById("cmd_find").doCommand();
ok(!gFindBar.hidden, "testNormalFind: failed to open findbar");
ok(document.commandDispatcher.focusedElement == gFindBar._findField.inputField,
"testNormalFind: find field is not focused");
let promise;
let matchCaseCheckbox = gFindBar.getElement("find-case-sensitive");
if (!matchCaseCheckbox.hidden && matchCaseCheckbox.checked) {
promise = promiseFindResult();
matchCaseCheckbox.click();
yield promise;
}
var searchStr = "text tes";
yield enterStringIntoFindField(searchStr);
let sel = yield ContentTask.spawn(gBrowser, { searchStr }, 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();
yield promise;
enterStringIntoFindField("t");
yield ContentTask.spawn(gBrowser, { searchStr }, function* (args) {
Assert.notEqual(content.getSelection().toString(), args.searchStr,
"testNormalFind: Case-sensitivy is broken '" + args.searchStr + "'");
});
promise = promiseFindResult();
matchCaseCheckbox.click();
yield promise;
}
}
function openFindbar() {
document.getElementById("cmd_find").doCommand();
return gFindBar._startFindDeferred && gFindBar._startFindDeferred.promise;
}
function* testNormalFindWithComposition() {
ok(!gFindBar.hidden, "testNormalFindWithComposition: findbar should be open");
ok(document.commandDispatcher.focusedElement == gFindBar._findField.inputField,
"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.inputField.focus();
var searchStr = "text";
synthesizeCompositionChange(
{ "composition":
{ "string": searchStr,
"clauses":
[
{ "length": searchStr.length, "attr": COMPOSITION_ATTR_RAW_CLAUSE }
]
},
"caret": { "start": searchStr.length, "length": 0 }
});
yield ContentTask.spawn(gBrowser, { searchStr }, function* (args) {
Assert.notEqual(content.getSelection().toString().toLowerCase(), args.searchStr,
"testNormalFindWithComposition: text shouldn't be found during composition");
});
synthesizeComposition({ type: "compositioncommitasis" });
let sel = yield ContentTask.spawn(gBrowser, { searchStr }, 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();
}
}
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");
gPrefsvc.setIntPref("accessibility.typeaheadfind.casesensitive", 2);
ok(matchCaseCheckbox.hidden,
"match case box is visible in automatic mode");
ok(!matchCaseLabel.hidden,
"match case label is hidden in automatic mode");
yield enterStringIntoFindField("a");
var insensitiveLabel = matchCaseLabel.value;
yield enterStringIntoFindField("A");
var sensitiveLabel = matchCaseLabel.value;
ok(insensitiveLabel != sensitiveLabel,
"Case Sensitive label was not correctly updated");
// bug 365551
gFindBar.onFindAgainCommand();
ok(matchCaseCheckbox.hidden && !matchCaseLabel.hidden,
"bug 365551: case sensitivity UI is broken after find-again");
gPrefsvc.setIntPref("accessibility.typeaheadfind.casesensitive", 0);
gFindBar.close();
}
function* clearFocus() {
document.commandDispatcher.focusedElement = null;
document.commandDispatcher.focusedWindow = null;
yield ContentTask.spawn(gBrowser, null, function* () {
content.focus();
});
}
function* testQuickFindLink() {
yield clearFocus();
yield ContentTask.spawn(gBrowser, null, function* () {
let document = content.document;
let event = document.createEvent("KeyboardEvent");
event.initKeyEvent("keypress", true, true, null, false, false,
false, false, 0, "'".charCodeAt(0));
document.documentElement.dispatchEvent(event);
});
ok(!gFindBar.hidden, "testQuickFindLink: failed to open findbar");
ok(document.commandDispatcher.focusedElement == gFindBar._findField.inputField,
"testQuickFindLink: find field is not focused");
var searchStr = "Link Test";
yield enterStringIntoFindField(searchStr);
yield ContentTask.spawn(gBrowser, { searchStr }, 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.
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";
yield 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();
yield enterStringIntoFindField(searchStr);
yield promiseExpectRangeCount(0);
highlightButton.click();
ok(highlightButton.checked, "testFindWithHighlight: Highlight All should be checked.");
yield promiseHighlightFinished();
yield promiseExpectRangeCount(3);
synthesizeKey("VK_BACK_SPACE", {});
yield promiseExpectRangeCount(0);
// Regression test for bug 1316513.
highlightButton.click();
ok(!highlightButton.checked, "testFindWithHighlight - 1316513: Highlight All should be unchecked.");
yield enterStringIntoFindField(searchStr);
highlightButton.click();
ok(highlightButton.checked, "testFindWithHighlight - 1316513: Highlight All should be checked.");
yield promiseHighlightFinished();
yield promiseExpectRangeCount(3);
let promise = BrowserTestUtils.browserLoaded(gBrowser);
gBrowser.reload();
yield promise;
ok(highlightButton.checked, "testFindWithHighlight - 1316513: Highlight All " +
"should still be checked after a reload.");
synthesizeKey("VK_RETURN", {});
yield promiseHighlightFinished();
yield promiseExpectRangeCount(3);
// Uncheck at test end to not interfere with other test functions that are
// run after this one.
highlightButton.click();
}
function* testQuickFindText() {
yield clearFocus();
yield ContentTask.spawn(gBrowser, null, function* () {
let document = content.document;
let event = document.createEvent("KeyboardEvent");
event.initKeyEvent("keypress", true, true, null, false, false,
false, false, 0, "/".charCodeAt(0));
document.documentElement.dispatchEvent(event);
});
ok(!gFindBar.hidden, "testQuickFindText: failed to open findbar");
ok(document.commandDispatcher.focusedElement == gFindBar._findField.inputField,
"testQuickFindText: find field is not focused");
yield enterStringIntoFindField(SEARCH_TEXT);
yield ContentTask.spawn(gBrowser, { SEARCH_TEXT }, function* (args) {
Assert.equal(content.getSelection().toString(), args.SEARCH_TEXT,
"testQuickFindText: failed to find '" + args.SEARCH_TEXT + "'");
});
testClipboardSearchString(SEARCH_TEXT);
}
function* testFindCountUI(linksOnly = false) {
yield clearFocus();
if (linksOnly) {
yield ContentTask.spawn(gBrowser, null, function* () {
let document = content.document;
let event = document.createEvent("KeyboardEvent");
event.initKeyEvent("keypress", true, true, null, false, false,
false, false, 0, "'".charCodeAt(0));
document.documentElement.dispatchEvent(event);
});
} else {
document.getElementById("cmd_find").doCommand();
}
ok(!gFindBar.hidden, "testFindCountUI: failed to open findbar");
ok(document.commandDispatcher.focusedElement == gFindBar._findField.inputField,
"testFindCountUI: find field is not focused");
let promise;
let matchCase = gFindBar.getElement("find-case-sensitive");
if (matchCase.checked) {
promise = promiseFindResult();
matchCase.click();
yield new Promise(resolve => setTimeout(resolve, ITERATOR_TIMEOUT + 20));
yield 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
}];
let regex = /([\d]*)\sof\s([\d]*)/;
function assertMatches(aTest, aMatches) {
is(aMatches[1], String(aTest.current),
`${linksOnly ? "[Links-only] " : ""}Currently highlighted match should be at ${aTest.current} for '${aTest.text}'`);
is(aMatches[2], String(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;
yield new Promise(resolve => setTimeout(resolve, timeout));
yield enterStringIntoFindField(test.text, false);
yield promiseMatchesCountResult();
let matches = foundMatches.value.match(regex);
if (!test.total) {
ok(!matches, "No message should be shown when 0 matches are expected");
} else {
assertMatches(test, matches);
for (let i = 1; i < test.total; i++) {
yield new Promise(resolve => setTimeout(resolve, timeout));
gFindBar.onFindAgainCommand();
yield promiseMatchesCountResult();
// 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: current,
total: test.total
}, foundMatches.value.match(regex));
}
}
}
}
// See bug 1051187.
function* testFindAfterCaseChanged() {
// Search to set focus on "Text Test" so that searching for "t" selects first
// (upper case!) "T".
yield enterStringIntoFindField(SEARCH_TEXT);
gFindBar.clear();
gPrefsvc.setIntPref("accessibility.typeaheadfind.casesensitive", 0);
yield enterStringIntoFindField("t");
yield ContentTask.spawn(gBrowser, null, function* () {
Assert.equal(content.getSelection().toString(), "T", "First T should be selected.");
});
gPrefsvc.setIntPref("accessibility.typeaheadfind.casesensitive", 1);
yield ContentTask.spawn(gBrowser, null, 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.
function* testFailedStringReset() {
gPrefsvc.setIntPref("accessibility.typeaheadfind.casesensitive", 1);
yield enterStringIntoFindField(SEARCH_TEXT.toUpperCase(), false);
yield ContentTask.spawn(gBrowser, null, function* () {
Assert.equal(content.getSelection().toString(), "", "Not found.");
});
gPrefsvc.setIntPref("accessibility.typeaheadfind.casesensitive", 0);
yield ContentTask.spawn(gBrowser, { SEARCH_TEXT }, 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.
function* testFindAgainNotFound() {
yield openFindbar();
yield enterStringIntoFindField(NOT_FOUND_TEXT, false);
gFindBar.close();
ok(gFindBar.hidden, "The findbar is closed.");
let promise = promiseFindResult();
gFindBar.onFindAgainCommand();
yield promise;
ok(!gFindBar.hidden, "Unsuccessful Find Again opens the find bar.");
yield enterStringIntoFindField(SEARCH_TEXT);
gFindBar.close();
ok(gFindBar.hidden, "The findbar is closed.");
promise = promiseFindResult();
gFindBar.onFindAgainCommand();
yield promise;
ok(gFindBar.hidden, "Successful Find Again leaves the find bar closed.");
}
function* testToggleEntireWord() {
yield openFindbar();
let promise = promiseFindResult();
yield enterStringIntoFindField("Tex", false);
let result = yield promise;
is(result.result, Ci.nsITypeAheadFind.FIND_FOUND, "Text should be found");
yield new Promise(resolve => setTimeout(resolve, ITERATOR_TIMEOUT + 20));
promise = promiseFindResult();
let check = gFindBar.getElement("find-entire-word");
check.click();
result = yield promise;
is(result.result, Ci.nsITypeAheadFind.FIND_NOTFOUND, "Text should NOT be found");
check.click();
gFindBar.close(true);
}
]]></script>
<commandset>
<command id="cmd_find" oncommand="document.getElementById('FindToolbar').onFindCommand();"/>
</commandset>
<browser type="content-primary" flex="1" id="content" src="about:blank"/>
<browser type="content-primary" flex="1" id="content-remote" remote="true" src="about:blank"/>
<findbar id="FindToolbar" browserid="content"/>
</window>

View file

@ -1,82 +0,0 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<page xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/>
<menupopup id="popup" onpopupshowing="if (isSecondTest) popupShowing(event)" onpopupshown="popupShown()"
onpopuphidden="nextTest()">
<menuitem label="One"/>
<menuitem label="Two"/>
</menupopup>
<button id="button" label="OK" popup="popup"/>
<script class="testbody" type="application/javascript">
<![CDATA[
var isSecondTest = false;
function openPopup()
{
document.getElementById("popup").openPopup(parent.document.getElementById("outerbutton"), "after_start", 3, 1);
}
function popupShowing(event)
{
var buttonrect = document.getElementById("button").getBoundingClientRect();
parent.opener.wrappedJSObject.SimpleTest.is(event.clientX, buttonrect.left + 6, "popup clientX with mouse");
parent.opener.wrappedJSObject.SimpleTest.is(event.clientY, buttonrect.top + 6, "popup clientY with mouse");
}
function popupShown()
{
var left, top;
var popuprect = document.getElementById("popup").getBoundingClientRect();
if (isSecondTest) {
var buttonrect = document.getElementById("button").getBoundingClientRect();
left = buttonrect.left + 6;
top = buttonrect.top + 6;
}
else {
var iframerect = parent.document.getElementById("frame").getBoundingClientRect();
var buttonrect = parent.document.getElementById("outerbutton").getBoundingClientRect();
// The popup should appear anchored on the bottom left edge of the button, however
// the client rectangle is relative to the iframe's document. Thus the coordinates
// are:
// left = iframe's left - anchor button's left - 3 pixel offset passed to openPopup +
// iframe border (17px) + iframe padding (0)
// top = iframe's top - anchor button's bottom - 1 pixel offset passed to openPopup +
// iframe border (0) + iframe padding (3px);
left = -(Math.round(iframerect.left) - Math.round(buttonrect.left) + 14);
top = -(Math.round(iframerect.top) - Math.round(buttonrect.bottom) + 2);
}
var testid = isSecondTest ? "with mouse" : "anchored to parent frame";
parent.opener.wrappedJSObject.SimpleTest.is(Math.round(popuprect.left), left, "popup left " + testid);
parent.opener.wrappedJSObject.SimpleTest.is(Math.round(popuprect.top), top, "popup top " + testid);
document.getElementById("popup").hidePopup();
}
function nextTest()
{
if (isSecondTest) {
parent.opener.wrappedJSObject.SimpleTest.finish();
parent.close();
}
else {
// this second test ensures that the popupshowing coordinates when a popup in
// a frame is opened are correct
isSecondTest = true;
synthesizeMouse(document.getElementById("button"), 6, 6, { });
}
}
]]>
</script>
</page>

View file

@ -1,75 +0,0 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<window title="Popup Removing Frame Tests"
onload="setTimeout(init, 0)"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<hbox>
<menu id="separatemenu1" label="Menu">
<menupopup id="separatepopup1" onpopupshown="document.getElementById('separatemenu2').open = true">
<menuitem label="L1 One"/>
<menuitem label="L1 Two"/>
<menuitem label="L1 Three"/>
</menupopup>
</menu>
<menu id="separatemenu2" label="Menu">
<menupopup id="separatepopup2" onpopupshown="document.getElementById('separatemenu3').open = true">
<menuitem label="L2 One"/>
<menuitem label="L2 Two"/>
<menuitem label="L2 Three"/>
</menupopup>
</menu>
<menu id="separatemenu3" label="Menu" onpopupshown="document.getElementById('separatemenu4').open = true">
<menupopup id="separatepopup3">
<menuitem label="L3 One"/>
<menuitem label="L3 Two"/>
<menuitem label="L3 Three"/>
</menupopup>
</menu>
<menu id="separatemenu4" label="Menu" onpopupshown="document.getElementById('nestedmenu1').open = true">
<menupopup id="separatepopup3">
<menuitem label="L4 One"/>
<menuitem label="L4 Two"/>
<menuitem label="L4 Three"/>
</menupopup>
</menu>
</hbox>
<menu id="nestedmenu1" label="Menu">
<menupopup id="nestedpopup1" onpopupshown="if (event.target == this) this.firstChild.open = true">
<menu id="nestedmenu2" label="Menu">
<menupopup id="nestedpopup2" onpopupshown="if (event.target == this) this.firstChild.open = true">
<menu id="nestedmenu3" label="Menu">
<menupopup id="nestedpopup3" onpopupshown="if (event.target == this) this.firstChild.open = true">
<menu id="nestedmenu4" label="Menu" onpopupshown="parent.popupsOpened()">
<menupopup id="nestedpopup4">
<menuitem label="Nested One"/>
<menuitem label="Nested Two"/>
<menuitem label="Nested Three"/>
</menupopup>
</menu>
</menupopup>
</menu>
</menupopup>
</menu>
</menupopup>
</menu>
<script class="testbody" type="application/javascript">
<![CDATA[
function init()
{
document.getElementById("separatemenu1").open = true;
}
]]>
</script>
</window>

View file

@ -1,43 +0,0 @@
<?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"?>
<page id="frame1"
style="background-color:green;"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/>
<spacer height="10px"/>
<iframe
style="margin:10px; min-height:170px; max-width:200px; max-height:200px; border:solid 1px white;"
src="frame_subframe_origin_subframe2.xul"></iframe>
<spacer height="3px"/>
<caption id="cap1" style="min-width:200px; max-width:200px; background-color:white;" label=""/>
<script class="testbody" type="application/javascript">
// Fire a mouse move event aimed at this window, and check to be
// sure the client coords translate from widget to the dom correctly.
function runTests()
{
synthesizeMouse(document.getElementById("frame1"), 3, 4, { type: "mousemove" });
}
function mouseMove(e) {
e.stopPropagation();
var element = e.target;
var el = document.getElementById("cap1");
el.label = "client: (" + e.clientX + "," + e.clientY + ")";
parent.opener.wrappedJSObject.SimpleTest.is(e.clientX, 3, "mouse event clientX on sub frame 1");
parent.opener.wrappedJSObject.SimpleTest.is(e.clientY, 4, "mouse event clientY on sub frame 1");
// fire the next test on the sub frame
frames[0].runTests();
}
window.addEventListener("mousemove", mouseMove, false);
</script>
</page>

View file

@ -1,39 +0,0 @@
<?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"?>
<page id="frame2"
style="background-color:red;"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/>
<spacer height="10px"/>
<caption id="cap2" style="background-color:white;" label=""/>
<script class="testbody" type="application/javascript">
// Fire a mouse move event aimed at this window, and check to be
// sure the client coords translate from widget to the dom correctly.
function runTests()
{
synthesizeMouse(document.getElementById("frame2"), 6, 5, { type: "mousemove" });
}
function mouseMove(e) {
e.stopPropagation();
var element = e.target;
var el = document.getElementById("cap2");
el.label = "client: (" + e.clientX + "," + e.clientY + ")";
parent.parent.opener.wrappedJSObject.SimpleTest.is(e.clientX, 6, "mouse event clientX on sub frame 2");
parent.parent.opener.wrappedJSObject.SimpleTest.is(e.clientY, 5, "mouse event clientY on sub frame 2");
parent.parent.opener.wrappedJSObject.SimpleTest.finish();
parent.parent.close();
}
window.addEventListener("mousemove",mouseMove, false);
</script>
</page>

View file

@ -1,2 +0,0 @@
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" width="80" height="80"
onclick="document.documentElement.setAttribute('data', 'x' + document.popupNode)"/>

View file

@ -1,859 +0,0 @@
var gMenuPopup = null;
var gTrigger = null;
var gIsMenu = false;
var gScreenX = -1, gScreenY = -1;
var gCachedEvent = null;
var gCachedEvent2 = null;
function cacheEvent(modifiers)
{
var cachedEvent = null;
var mouseFn = function(event) {
cachedEvent = event;
}
window.addEventListener("mousedown", mouseFn, false);
synthesizeMouse(document.documentElement, 0, 0, modifiers);
window.removeEventListener("mousedown", mouseFn, false);
return cachedEvent;
}
function runTests()
{
if (screen.height < 768) {
ok(false, "popup tests are likely to fail for screen heights less than 768 pixels");
}
gMenuPopup = document.getElementById("thepopup");
gTrigger = document.getElementById("trigger");
gIsMenu = gTrigger.boxObject instanceof MenuBoxObject;
// a hacky way to get the screen position of the document. Cache the event
// so that we can use it in calls to openPopup.
gCachedEvent = cacheEvent({ shiftKey: true });
gScreenX = gCachedEvent.screenX;
gScreenY = gCachedEvent.screenY;
gCachedEvent2 = cacheEvent({ altKey: true, ctrlKey: true, shiftKey: true, metaKey: true });
startPopupTests(popupTests);
}
var popupTests = [
{
testname: "mouse click on trigger",
events: [ "popupshowing thepopup", "popupshown thepopup" ],
test: function() {
// for menus, no trigger will be set. For non-menus using the popup
// attribute, the trigger will be set to the node with the popup attribute
gExpectedTriggerNode = gIsMenu ? "notset" : gTrigger;
synthesizeMouse(gTrigger, 4, 4, { });
},
result: function (testname) {
gExpectedTriggerNode = null;
// menus are the anchor but non-menus are opened at screen coordinates
is(gMenuPopup.anchorNode, gIsMenu ? gTrigger : null, testname + " anchorNode");
// menus are opened internally, but non-menus have a mouse event which
// triggered them
is(gMenuPopup.triggerNode, gIsMenu ? null : gTrigger, testname + " triggerNode");
is(document.popupNode, gIsMenu ? null : gTrigger, testname + " document.popupNode");
is(document.tooltipNode, null, testname + " document.tooltipNode");
// check to ensure the popup node for a different document isn't used
if (window.opener)
is(window.opener.document.popupNode, null, testname + " opener.document.popupNode");
// this will be used in some tests to ensure the size doesn't change
var popuprect = gMenuPopup.getBoundingClientRect();
gPopupWidth = Math.round(popuprect.width);
gPopupHeight = Math.round(popuprect.height);
checkActive(gMenuPopup, "", testname);
checkOpen("trigger", testname);
// if a menu, the popup should be opened underneath the menu in the
// 'after_start' position, otherwise it is opened at the mouse position
if (gIsMenu)
compareEdge(gTrigger, gMenuPopup, "after_start", 0, 0, testname);
}
},
{
// check that pressing cursor down while there is no selection
// highlights the first item
testname: "cursor down no selection",
events: [ "DOMMenuItemActive item1" ],
test: function() { synthesizeKey("VK_DOWN", { }); },
result: function(testname) { checkActive(gMenuPopup, "item1", testname); }
},
{
// check that pressing cursor up wraps and highlights the last item
testname: "cursor up wrap",
events: [ "DOMMenuItemInactive item1", "DOMMenuItemActive last" ],
test: function() { synthesizeKey("VK_UP", { }); },
result: function(testname) {
checkActive(gMenuPopup, "last", testname);
}
},
{
// check that pressing cursor down wraps and highlights the first item
testname: "cursor down wrap",
events: [ "DOMMenuItemInactive last", "DOMMenuItemActive item1" ],
test: function() { synthesizeKey("VK_DOWN", { }); },
result: function(testname) { checkActive(gMenuPopup, "item1", testname); }
},
{
// check that pressing cursor down highlights the second item
testname: "cursor down",
events: [ "DOMMenuItemInactive item1", "DOMMenuItemActive item2" ],
test: function() { synthesizeKey("VK_DOWN", { }); },
result: function(testname) { checkActive(gMenuPopup, "item2", testname); }
},
{
// check that pressing cursor up highlights the second item
testname: "cursor up",
events: [ "DOMMenuItemInactive item2", "DOMMenuItemActive item1" ],
test: function() { synthesizeKey("VK_UP", { }); },
result: function(testname) { checkActive(gMenuPopup, "item1", testname); }
},
{
// cursor left should not do anything
testname: "cursor left",
test: function() { synthesizeKey("VK_LEFT", { }); },
result: function(testname) { checkActive(gMenuPopup, "item1", testname); }
},
{
// cursor right should not do anything
testname: "cursor right",
test: function() { synthesizeKey("VK_RIGHT", { }); },
result: function(testname) { checkActive(gMenuPopup, "item1", testname); }
},
{
// check cursor down when a disabled item exists in the menu
testname: "cursor down disabled",
events: function() {
// On Windows, disabled items are included when navigating, but on
// other platforms, disabled items are skipped over
if (navigator.platform.indexOf("Win") == 0) {
return [ "DOMMenuItemInactive item1", "DOMMenuItemActive item2" ];
}
return [ "DOMMenuItemInactive item1", "DOMMenuItemActive amenu" ];
},
test: function() {
document.getElementById("item2").disabled = true;
synthesizeKey("VK_DOWN", { });
}
},
{
// check cursor up when a disabled item exists in the menu
testname: "cursor up disabled",
events: function() {
if (navigator.platform.indexOf("Win") == 0) {
return [ "DOMMenuItemInactive item2", "DOMMenuItemActive amenu",
"DOMMenuItemInactive amenu", "DOMMenuItemActive item2",
"DOMMenuItemInactive item2", "DOMMenuItemActive item1" ];
}
return [ "DOMMenuItemInactive amenu", "DOMMenuItemActive item1" ];
},
test: function() {
if (navigator.platform.indexOf("Win") == 0)
synthesizeKey("VK_DOWN", { });
synthesizeKey("VK_UP", { });
if (navigator.platform.indexOf("Win") == 0)
synthesizeKey("VK_UP", { });
}
},
{
testname: "mouse click outside",
events: [ "popuphiding thepopup", "popuphidden thepopup",
"DOMMenuItemInactive item1", "DOMMenuInactive thepopup" ],
test: function() {
gMenuPopup.hidePopup();
// XXXndeakin event simulation fires events outside of the platform specific
// widget code so the popup capturing isn't handled. Thus, the menu won't
// rollup this way.
// synthesizeMouse(gTrigger, 0, -12, { });
},
result: function(testname, step) {
is(gMenuPopup.anchorNode, null, testname + " anchorNode");
is(gMenuPopup.triggerNode, null, testname + " triggerNode");
is(document.popupNode, null, testname + " document.popupNode");
checkClosed("trigger", testname);
}
},
{
// these tests check to ensure that passing an anchor and position
// puts the popup in the right place
testname: "open popup anchored",
events: [ "popupshowing thepopup", "popupshown thepopup" ],
autohide: "thepopup",
steps: ["before_start", "before_end", "after_start", "after_end",
"start_before", "start_after", "end_before", "end_after", "after_pointer", "overlap",
"topleft topleft", "topcenter topleft", "topright topleft",
"leftcenter topright", "rightcenter topright",
"bottomleft bottomleft", "bottomcenter bottomleft", "bottomright bottomleft",
"topleft bottomright", "bottomcenter bottomright", "rightcenter topright"],
test: function(testname, step) {
gExpectedTriggerNode = "notset";
gMenuPopup.openPopup(gTrigger, step, 0, 0, false, false);
},
result: function(testname, step) {
// no triggerNode because it was opened without passing an event
gExpectedTriggerNode = null;
is(gMenuPopup.anchorNode, gTrigger, testname + " anchorNode");
is(gMenuPopup.triggerNode, null, testname + " triggerNode");
is(document.popupNode, null, testname + " document.popupNode");
compareEdge(gTrigger, gMenuPopup, step, 0, 0, testname);
}
},
{
// these tests check the same but with a 10 pixel margin on the popup
testname: "open popup anchored with margin",
events: [ "popupshowing thepopup", "popupshown thepopup" ],
autohide: "thepopup",
steps: ["before_start", "before_end", "after_start", "after_end",
"start_before", "start_after", "end_before", "end_after", "after_pointer", "overlap",
"topleft topleft", "topcenter topleft", "topright topleft",
"leftcenter topright", "rightcenter topright",
"bottomleft bottomleft", "bottomcenter bottomleft", "bottomright bottomleft",
"topleft bottomright", "bottomcenter bottomright", "rightcenter topright"],
test: function(testname, step) {
gMenuPopup.setAttribute("style", "margin: 10px;");
gMenuPopup.openPopup(gTrigger, step, 0, 0, false, false);
},
result: function(testname, step) {
var rightmod = step == "before_end" || step == "after_end" ||
step == "start_before" || step == "start_after" ||
step.match(/topright$/) || step.match(/bottomright$/);
var bottommod = step == "before_start" || step == "before_end" ||
step == "start_after" || step == "end_after" ||
step.match(/bottomleft$/) || step.match(/bottomright$/);
compareEdge(gTrigger, gMenuPopup, step, rightmod ? -10 : 10, bottommod ? -10 : 10, testname);
gMenuPopup.removeAttribute("style");
}
},
{
// these tests check the same but with a -8 pixel margin on the popup
testname: "open popup anchored with negative margin",
events: [ "popupshowing thepopup", "popupshown thepopup" ],
autohide: "thepopup",
steps: ["before_start", "before_end", "after_start", "after_end",
"start_before", "start_after", "end_before", "end_after", "after_pointer", "overlap"],
test: function(testname, step) {
gMenuPopup.setAttribute("style", "margin: -8px;");
gMenuPopup.openPopup(gTrigger, step, 0, 0, false, false);
},
result: function(testname, step) {
var rightmod = step == "before_end" || step == "after_end" ||
step == "start_before" || step == "start_after";
var bottommod = step == "before_start" || step == "before_end" ||
step == "start_after" || step == "end_after";
compareEdge(gTrigger, gMenuPopup, step, rightmod ? 8 : -8, bottommod ? 8 : -8, testname);
gMenuPopup.removeAttribute("style");
}
},
{
testname: "open popup with large positive margin",
events: [ "popupshowing thepopup", "popupshown thepopup" ],
autohide: "thepopup",
steps: ["before_start", "before_end", "after_start", "after_end",
"start_before", "start_after", "end_before", "end_after", "after_pointer", "overlap"],
test: function(testname, step) {
gMenuPopup.setAttribute("style", "margin: 1000px;");
gMenuPopup.openPopup(gTrigger, step, 0, 0, false, false);
},
result: function(testname, step) {
var popuprect = gMenuPopup.getBoundingClientRect();
// as there is more room on the 'end' or 'after' side, popups will always
// appear on the right or bottom corners, depending on which side they are
// allowed to be flipped by.
var expectedleft = step == "before_end" || step == "after_end" ?
0 : Math.round(window.innerWidth - gPopupWidth);
var expectedtop = step == "start_after" || step == "end_after" ?
0 : Math.round(window.innerHeight - gPopupHeight);
is(Math.round(popuprect.left), expectedleft, testname + " x position " + step);
is(Math.round(popuprect.top), expectedtop, testname + " y position " + step);
gMenuPopup.removeAttribute("style");
}
},
{
testname: "open popup with large negative margin",
events: [ "popupshowing thepopup", "popupshown thepopup" ],
autohide: "thepopup",
steps: ["before_start", "before_end", "after_start", "after_end",
"start_before", "start_after", "end_before", "end_after", "after_pointer", "overlap"],
test: function(testname, step) {
gMenuPopup.setAttribute("style", "margin: -1000px;");
gMenuPopup.openPopup(gTrigger, step, 0, 0, false, false);
},
result: function(testname, step) {
var popuprect = gMenuPopup.getBoundingClientRect();
// using negative margins causes the reverse of positive margins, and
// popups will appear on the left or top corners.
var expectedleft = step == "before_end" || step == "after_end" ?
Math.round(window.innerWidth - gPopupWidth) : 0;
var expectedtop = step == "start_after" || step == "end_after" ?
Math.round(window.innerHeight - gPopupHeight) : 0;
is(Math.round(popuprect.left), expectedleft, testname + " x position " + step);
is(Math.round(popuprect.top), expectedtop, testname + " y position " + step);
gMenuPopup.removeAttribute("style");
}
},
{
testname: "popup with unknown step",
events: [ "popupshowing thepopup", "popupshown thepopup" ],
autohide: "thepopup",
test: function() {
gMenuPopup.openPopup(gTrigger, "other", 0, 0, false, false);
},
result: function (testname) {
var triggerrect = gMenuPopup.getBoundingClientRect();
var popuprect = gMenuPopup.getBoundingClientRect();
is(Math.round(popuprect.left), triggerrect.left, testname + " x position ");
is(Math.round(popuprect.top), triggerrect.top, testname + " y position ");
}
},
{
// these tests check to ensure that the position attribute can be used
// to set the position of a popup instead of passing it as an argument
testname: "open popup anchored with attribute",
events: [ "popupshowing thepopup", "popupshown thepopup" ],
autohide: "thepopup",
steps: ["before_start", "before_end", "after_start", "after_end",
"start_before", "start_after", "end_before", "end_after", "after_pointer", "overlap",
"topcenter topleft", "topright bottomright", "leftcenter topright"],
test: function(testname, step) {
gMenuPopup.setAttribute("position", step);
gMenuPopup.openPopup(gTrigger, "", 0, 0, false, false);
},
result: function(testname, step) { compareEdge(gTrigger, gMenuPopup, step, 0, 0, testname); }
},
{
// this test checks to ensure that the attributes override flag to openPopup
// can be used to override the popup's position. This test also passes an
// event to openPopup to check the trigger node.
testname: "open popup anchored with override",
events: [ "popupshowing thepopup 0010", "popupshown thepopup" ],
test: function(testname, step) {
// attribute overrides the position passed in
gMenuPopup.setAttribute("position", "end_after");
gExpectedTriggerNode = gCachedEvent.target;
gMenuPopup.openPopup(gTrigger, "before_start", 0, 0, false, true, gCachedEvent);
},
result: function(testname, step) {
gExpectedTriggerNode = null;
is(gMenuPopup.anchorNode, gTrigger, testname + " anchorNode");
is(gMenuPopup.triggerNode, gCachedEvent.target, testname + " triggerNode");
is(document.popupNode, gCachedEvent.target, testname + " document.popupNode");
compareEdge(gTrigger, gMenuPopup, "end_after", 0, 0, testname);
}
},
{
testname: "close popup with escape",
events: [ "popuphiding thepopup", "popuphidden thepopup",
"DOMMenuInactive thepopup", ],
test: function(testname, step) {
synthesizeKey("VK_ESCAPE", { });
checkClosed("trigger", testname);
}
},
{
// check that offsets may be supplied to the openPopup method
testname: "open popup anchored with offsets",
events: [ "popupshowing thepopup", "popupshown thepopup" ],
autohide: "thepopup",
test: function(testname, step) {
// attribute is empty so does not override
gMenuPopup.setAttribute("position", "");
gMenuPopup.openPopup(gTrigger, "before_start", 5, 10, true, true);
},
result: function(testname, step) { compareEdge(gTrigger, gMenuPopup, "before_start", 5, 10, testname); }
},
{
// these tests check to ensure that passing an anchor and position
// puts the popup in the right place
testname: "show popup anchored",
condition: function() {
// only perform this test for popups not in a menu, such as those using
// the popup attribute, as the showPopup implementation in popup.xml
// calls openMenu if the popup is inside a menu
return !gIsMenu;
},
events: [ "popupshowing thepopup", "popupshown thepopup" ],
autohide: "thepopup",
steps: [["topleft", "topleft"],
["topleft", "topright"], ["topleft", "bottomleft"],
["topright", "topleft"], ["topright", "bottomright"],
["bottomleft", "bottomright"], ["bottomleft", "topleft"],
["bottomright", "bottomleft"], ["bottomright", "topright"]],
test: function(testname, step) {
// the attributes should be ignored
gMenuPopup.setAttribute("popupanchor", "topright");
gMenuPopup.setAttribute("popupalign", "bottomright");
gMenuPopup.setAttribute("position", "end_after");
gMenuPopup.showPopup(gTrigger, -1, -1, "popup", step[0], step[1]);
},
result: function(testname, step) {
var pos = convertPosition(step[0], step[1]);
compareEdge(gTrigger, gMenuPopup, pos, 0, 0, testname);
gMenuPopup.removeAttribute("popupanchor");
gMenuPopup.removeAttribute("popupalign");
gMenuPopup.removeAttribute("position");
}
},
{
testname: "show popup with position",
condition: function() { return !gIsMenu; },
events: [ "popupshowing thepopup", "popupshown thepopup" ],
autohide: "thepopup",
test: function(testname, step) {
gMenuPopup.showPopup(gTrigger, gScreenX + 60, gScreenY + 15,
"context", "topleft", "bottomright");
},
result: function(testname, step) {
var rect = gMenuPopup.getBoundingClientRect();
ok(true, gScreenX + "," + gScreenY);
is(rect.left, 60, testname + " left");
is(rect.top, 15, testname + " top");
ok(rect.right, testname + " right is " + rect.right);
ok(rect.bottom, testname + " bottom is " + rect.bottom);
}
},
{
// if no anchor is supplied to openPopup, it should be opened relative
// to the viewport.
testname: "open popup unanchored",
events: [ "popupshowing thepopup", "popupshown thepopup" ],
test: function(testname, step) { gMenuPopup.openPopup(null, "after_start", 6, 8, false); },
result: function(testname, step) {
var rect = gMenuPopup.getBoundingClientRect();
ok(rect.left == 6 && rect.top == 8 && rect.right && rect.bottom, testname);
}
},
{
testname: "activate menuitem with mouse",
events: [ "DOMMenuInactive thepopup", "command item3",
"popuphiding thepopup", "popuphidden thepopup",
"DOMMenuItemInactive item3" ],
test: function(testname, step) {
var item3 = document.getElementById("item3");
synthesizeMouse(item3, 4, 4, { });
},
result: function(testname, step) { checkClosed("trigger", testname); }
},
{
testname: "close popup",
condition: function() { return false; },
events: [ "popuphiding thepopup", "popuphidden thepopup",
"DOMMenuInactive thepopup" ],
test: function(testname, step) { gMenuPopup.hidePopup(); }
},
{
testname: "open popup at screen",
events: [ "popupshowing thepopup", "popupshown thepopup" ],
test: function(testname, step) {
gExpectedTriggerNode = "notset";
gMenuPopup.openPopupAtScreen(gScreenX + 24, gScreenY + 20, false);
},
result: function(testname, step) {
gExpectedTriggerNode = null;
is(gMenuPopup.anchorNode, null, testname + " anchorNode");
is(gMenuPopup.triggerNode, null, testname + " triggerNode");
is(document.popupNode, null, testname + " document.popupNode");
var rect = gMenuPopup.getBoundingClientRect();
is(rect.left, 24, testname + " left");
is(rect.top, 20, testname + " top");
ok(rect.right, testname + " right is " + rect.right);
ok(rect.bottom, testname + " bottom is " + rect.bottom);
}
},
{
// check that pressing a menuitem's accelerator selects it. Note that
// the menuitem with the M accesskey overrides the earlier menuitem that
// begins with M.
testname: "menuitem accelerator",
events: [ "DOMMenuItemActive amenu", "DOMMenuItemInactive amenu",
"DOMMenuInactive thepopup",
"command amenu", "popuphiding thepopup", "popuphidden thepopup",
"DOMMenuItemInactive amenu"
],
test: function() { synthesizeKey("M", { }); },
result: function(testname) { checkClosed("trigger", testname); }
},
{
testname: "open context popup at screen",
events: [ "popupshowing thepopup 0010", "popupshown thepopup" ],
test: function(testname, step) {
gExpectedTriggerNode = gCachedEvent.target;
gMenuPopup.openPopupAtScreen(gScreenX + 8, gScreenY + 16, true, gCachedEvent);
},
result: function(testname, step) {
gExpectedTriggerNode = null;
is(gMenuPopup.anchorNode, null, testname + " anchorNode");
is(gMenuPopup.triggerNode, gCachedEvent.target, testname + " triggerNode");
is(document.popupNode, gCachedEvent.target, testname + " document.popupNode");
var childframe = document.getElementById("childframe");
if (childframe) {
for (var t = 0; t < 2; t++) {
var child = childframe.contentDocument;
var evt = child.createEvent("Event");
evt.initEvent("click", true, true);
child.documentElement.dispatchEvent(evt);
is(child.documentElement.getAttribute("data"), "xnull",
"cannot get popupNode from other document");
child.documentElement.setAttribute("data", "none");
// now try again with document.popupNode set explicitly
document.popupNode = gCachedEvent.target;
}
}
var openX = 8;
var openY = 16;
var rect = gMenuPopup.getBoundingClientRect();
is(rect.left, openX + (platformIsMac() ? 1 : 2), testname + " left");
is(rect.top, openY + (platformIsMac() ? -6 : 2), testname + " top");
ok(rect.right, testname + " right is " + rect.right);
ok(rect.bottom, testname + " bottom is " + rect.bottom);
}
},
{
// pressing a letter that doesn't correspond to an accelerator, but does
// correspond to the first letter in a menu's label. The menu should not
// close because there is more than one item corresponding to that letter
testname: "menuitem with non accelerator",
events: [ "DOMMenuItemActive one" ],
test: function() { synthesizeKey("O", { }); },
result: function(testname) {
checkOpen("trigger", testname);
checkActive(gMenuPopup, "one", testname);
}
},
{
// pressing the letter again should select the next one that starts with
// that letter
testname: "menuitem with non accelerator again",
events: [ "DOMMenuItemInactive one", "DOMMenuItemActive submenu" ],
test: function() { synthesizeKey("O", { }); },
result: function(testname) {
// 'submenu' is a menu but it should not be open
checkOpen("trigger", testname);
checkClosed("submenu", testname);
checkActive(gMenuPopup, "submenu", testname);
}
},
{
// open the submenu with the cursor right key
testname: "open submenu with cursor right",
events: [ "popupshowing submenupopup", "DOMMenuItemActive submenuitem",
"popupshown submenupopup" ],
test: function() { synthesizeKey("VK_RIGHT", { }); },
result: function(testname) {
checkOpen("trigger", testname);
checkOpen("submenu", testname);
checkActive(gMenuPopup, "submenu", testname);
checkActive(document.getElementById("submenupopup"), "submenuitem", testname);
}
},
{
// close the submenu with the cursor left key
testname: "close submenu with cursor left",
events: [ "popuphiding submenupopup", "popuphidden submenupopup",
"DOMMenuItemInactive submenuitem", "DOMMenuInactive submenupopup",
"DOMMenuItemActive submenu" ],
test: function() { synthesizeKey("VK_LEFT", { }); },
result: function(testname) {
checkOpen("trigger", testname);
checkClosed("submenu", testname);
checkActive(gMenuPopup, "submenu", testname);
checkActive(document.getElementById("submenupopup"), "", testname);
}
},
{
// open the submenu with the enter key
testname: "open submenu with enter",
events: [ "popupshowing submenupopup", "DOMMenuItemActive submenuitem",
"popupshown submenupopup" ],
test: function() { synthesizeKey("VK_RETURN", { }); },
result: function(testname) {
checkOpen("trigger", testname);
checkOpen("submenu", testname);
checkActive(gMenuPopup, "submenu", testname);
checkActive(document.getElementById("submenupopup"), "submenuitem", testname);
}
},
{
// close the submenu with the escape key
testname: "close submenu with escape",
events: [ "popuphiding submenupopup", "popuphidden submenupopup",
"DOMMenuItemInactive submenuitem", "DOMMenuInactive submenupopup",
"DOMMenuItemActive submenu" ],
test: function() { synthesizeKey("VK_ESCAPE", { }); },
result: function(testname) {
checkOpen("trigger", testname);
checkClosed("submenu", testname);
checkActive(gMenuPopup, "submenu", testname);
checkActive(document.getElementById("submenupopup"), "", testname);
}
},
{
// pressing the letter again when the next item is disabled should still
// select the disabled item on Windows, but select the next item on other
// platforms
testname: "menuitem with non accelerator disabled",
events: function() {
if (navigator.platform.indexOf("Win") == 0) {
return [ "DOMMenuItemInactive submenu", "DOMMenuItemActive other",
"DOMMenuItemInactive other", "DOMMenuItemActive item1" ];
}
return [ "DOMMenuItemInactive submenu", "DOMMenuItemActive last",
"DOMMenuItemInactive last", "DOMMenuItemActive item1" ];
},
test: function() { synthesizeKey("O", { }); synthesizeKey("F", { }); },
result: function(testname) {
checkActive(gMenuPopup, "item1", testname);
}
},
{
// pressing a letter that doesn't correspond to an accelerator nor the
// first letter of a menu. This should have no effect.
testname: "menuitem with keypress no accelerator found",
test: function() { synthesizeKey("G", { }); },
result: function(testname) {
checkOpen("trigger", testname);
checkActive(gMenuPopup, "item1", testname);
}
},
{
// when only one menuitem starting with that letter exists, it should be
// selected and the menu closed
testname: "menuitem with non accelerator single",
events: [ "DOMMenuItemInactive item1", "DOMMenuItemActive amenu",
"DOMMenuItemInactive amenu", "DOMMenuInactive thepopup",
"command amenu", "popuphiding thepopup", "popuphidden thepopup",
"DOMMenuItemInactive amenu",
],
test: function() { synthesizeKey("M", { }); },
result: function(testname) {
checkClosed("trigger", testname);
checkActive(gMenuPopup, "", testname);
}
},
{
testname: "open context popup at screen with all modifiers set",
events: [ "popupshowing thepopup 1111", "popupshown thepopup" ],
autohide: "thepopup",
test: function(testname, step) {
gMenuPopup.openPopupAtScreen(gScreenX + 8, gScreenY + 16, true, gCachedEvent2);
}
},
{
testname: "open popup with open property",
events: [ "popupshowing thepopup", "popupshown thepopup" ],
test: function(testname, step) { openMenu(gTrigger); },
result: function(testname, step) {
checkOpen("trigger", testname);
if (gIsMenu)
compareEdge(gTrigger, gMenuPopup, "after_start", 0, 0, testname);
}
},
{
testname: "open submenu with open property",
events: [ "popupshowing submenupopup", "DOMMenuItemActive submenu",
"popupshown submenupopup" ],
test: function(testname, step) { openMenu(document.getElementById("submenu")); },
result: function(testname, step) {
checkOpen("trigger", testname);
checkOpen("submenu", testname);
// XXXndeakin
// getBoundingClientRect doesn't seem to working right for submenus
// so disable this test for now
// compareEdge(document.getElementById("submenu"),
// document.getElementById("submenupopup"), "end_before", 0, 0, testname);
}
},
{
testname: "hidePopup hides entire chain",
events: [ "popuphiding submenupopup", "popuphidden submenupopup",
"popuphiding thepopup", "popuphidden thepopup",
"DOMMenuInactive submenupopup",
"DOMMenuItemInactive submenu", "DOMMenuItemInactive submenu",
"DOMMenuInactive thepopup", ],
test: function() { gMenuPopup.hidePopup(); },
result: function(testname, step) {
checkClosed("trigger", testname);
checkClosed("submenu", testname);
}
},
{
testname: "open submenu with open property without parent open",
test: function(testname, step) { openMenu(document.getElementById("submenu")); },
result: function(testname, step) {
checkClosed("trigger", testname);
checkClosed("submenu", testname);
}
},
{
testname: "open popup with open property and position",
condition: function() { return gIsMenu; },
events: [ "popupshowing thepopup", "popupshown thepopup" ],
test: function(testname, step) {
gMenuPopup.setAttribute("position", "before_start");
openMenu(gTrigger);
},
result: function(testname, step) {
compareEdge(gTrigger, gMenuPopup, "before_start", 0, 0, testname);
}
},
{
testname: "close popup with open property",
condition: function() { return gIsMenu; },
events: [ "popuphiding thepopup", "popuphidden thepopup",
"DOMMenuInactive thepopup" ],
test: function(testname, step) { closeMenu(gTrigger, gMenuPopup); },
result: function(testname, step) { checkClosed("trigger", testname); }
},
{
testname: "open popup with open property, position, anchor and alignment",
condition: function() { return gIsMenu; },
events: [ "popupshowing thepopup", "popupshown thepopup" ],
autohide: "thepopup",
test: function(testname, step) {
gMenuPopup.setAttribute("position", "start_after");
gMenuPopup.setAttribute("popupanchor", "topright");
gMenuPopup.setAttribute("popupalign", "bottomright");
openMenu(gTrigger);
},
result: function(testname, step) {
compareEdge(gTrigger, gMenuPopup, "start_after", 0, 0, testname);
}
},
{
testname: "open popup with open property, anchor and alignment",
condition: function() { return gIsMenu; },
events: [ "popupshowing thepopup", "popupshown thepopup" ],
autohide: "thepopup",
test: function(testname, step) {
gMenuPopup.removeAttribute("position");
gMenuPopup.setAttribute("popupanchor", "bottomright");
gMenuPopup.setAttribute("popupalign", "topright");
openMenu(gTrigger);
},
result: function(testname, step) {
compareEdge(gTrigger, gMenuPopup, "after_end", 0, 0, testname);
gMenuPopup.removeAttribute("popupanchor");
gMenuPopup.removeAttribute("popupalign");
}
},
{
testname: "focus and cursor down on trigger",
condition: function() { return gIsMenu; },
events: [ "popupshowing thepopup", "popupshown thepopup" ],
autohide: "thepopup",
test: function(testname, step) {
gTrigger.focus();
synthesizeKey("VK_DOWN", { altKey: !platformIsMac() });
},
result: function(testname, step) {
checkOpen("trigger", testname);
checkActive(gMenuPopup, "", testname);
}
},
{
testname: "focus and cursor up on trigger",
condition: function() { return gIsMenu; },
events: [ "popupshowing thepopup", "popupshown thepopup" ],
test: function(testname, step) {
gTrigger.focus();
synthesizeKey("VK_UP", { altKey: !platformIsMac() });
},
result: function(testname, step) {
checkOpen("trigger", testname);
checkActive(gMenuPopup, "", testname);
}
},
{
testname: "select and enter on menuitem",
condition: function() { return gIsMenu; },
events: [ "DOMMenuItemActive item1", "DOMMenuItemInactive item1",
"DOMMenuInactive thepopup", "command item1",
"popuphiding thepopup", "popuphidden thepopup",
"DOMMenuItemInactive item1" ],
test: function(testname, step) {
synthesizeKey("VK_DOWN", { });
synthesizeKey("VK_RETURN", { });
},
result: function(testname, step) { checkClosed("trigger", testname); }
},
{
testname: "focus trigger and key to open",
condition: function() { return gIsMenu; },
events: [ "popupshowing thepopup", "popupshown thepopup" ],
autohide: "thepopup",
test: function(testname, step) {
gTrigger.focus();
synthesizeKey(platformIsMac() ? " " : "VK_F4", { });
},
result: function(testname, step) {
checkOpen("trigger", testname);
checkActive(gMenuPopup, "", testname);
}
},
{
// the menu should only open when the meta or alt key is not pressed
testname: "focus trigger and key wrong modifier",
condition: function() { return gIsMenu; },
test: function(testname, step) {
gTrigger.focus();
if (platformIsMac())
synthesizeKey("VK_F4", { altKey: true });
else
synthesizeKey("", { metaKey: true });
},
result: function(testname, step) {
checkClosed("trigger", testname);
}
},
{
testname: "mouse click on disabled menu",
condition: function() { return gIsMenu; },
test: function(testname, step) {
gTrigger.setAttribute("disabled", "true");
synthesizeMouse(gTrigger, 4, 4, { });
},
result: function(testname, step) {
checkClosed("trigger", testname);
gTrigger.removeAttribute("disabled");
}
},
{
// openPopup should open the menu synchronously, however popupshown
// is fired asynchronously
testname: "openPopup synchronous",
events: [ "popupshowing thepopup", "popupshowing submenupopup",
"popupshown thepopup", "DOMMenuItemActive submenu",
"popupshown submenupopup" ],
test: function(testname, step) {
gMenuPopup.openPopup(gTrigger, "after_start", 0, 0, false, true);
document.getElementById("submenupopup").
openPopup(gTrigger, "end_before", 0, 0, false, true);
checkOpen("trigger", testname);
checkOpen("submenu", testname);
}
},
{
// remove the content nodes for the popup
testname: "remove content",
test: function(testname, step) {
var submenupopup = document.getElementById("submenupopup");
submenupopup.parentNode.removeChild(submenupopup);
var popup = document.getElementById("thepopup");
popup.parentNode.removeChild(popup);
}
}
];
function platformIsMac()
{
return navigator.platform.indexOf("Mac") > -1;
}

View file

@ -1,2 +0,0 @@
/* Imitate RTL UI */
window { direction: rtl; }

View file

@ -1 +0,0 @@
<!ENTITY locale.dir "rtl">

View file

@ -1,5 +0,0 @@
content rtlchrome /
# Override intl.css with our own CSS file
override chrome://global/locale/intl.css chrome://rtlchrome/rtl.css
override chrome://global/locale/global.dtd chrome://rtlchrome/rtl.dtd

View file

@ -1,25 +0,0 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<window xmlns:html="http://www.w3.org/1999/xhtml"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<html:style>
hbox, vbox { background-color: white; }
hbox:-moz-locale-dir(ltr) { background-color: yellow; }
vbox:-moz-locale-dir(rtl) { background-color: green; }
</html:style>
<hbox id="hbox">
<button label="One"/>
<button label="Two"/>
<button label="Three"/>
</hbox>
<vbox id="vbox">
<button label="One"/>
<button label="Two"/>
<button label="Three"/>
</vbox>
</window>

View file

@ -1,3 +0,0 @@
content ltrtest content/
content rtltest content/
locale rtltest ar-QA content/

View file

@ -1,11 +0,0 @@
<!DOCTYPE html>
<html>
<head><title>Latin entire-word find test page</title></head>
<body>
<!-- Feel free to extend the contents of this page with more comprehensive
- Latin punctuation and/ or word markers.
-->
<p>The twins of Mammon quarrelled. Their warring plunged the world into a new darkness, and the beast abhorred the darkness. So it began to move swiftly, and grew more powerful, and went forth and multiplied. And the beasts brought fire and light to the darkness.</p>
<p>from The Book of Mozilla, 15:1</p>
</body>
</html>

View file

@ -1,58 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=912103
-->
<head>
<meta charset="utf-8">
<title>Test for Bug </title>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
<script type="application/javascript">
SimpleTest.waitForExplicitFinish();
function runTest() {
const Cc = Components.classes;
const Ci = Components.interfaces;
var dashboard = Cc['@mozilla.org/network/dashboard;1']
.getService(Ci.nsIDashboard);
dashboard.enableLogging = true;
var wsURI = "ws://mochi.test:8888/chrome/toolkit/content/tests/chrome/file_about_networking";
var websocket = new WebSocket(wsURI);
websocket.addEventListener("open", function() {
dashboard.requestWebsocketConnections(function(data) {
var found = false;
for (var i = 0; i < data.websockets.length; i++) {
if (data.websockets[i].hostport == "mochi.test:8888") {
found = true;
break;
}
}
isnot(found, false, "tested websocket entry not found");
websocket.close();
SimpleTest.finish();
});
});
}
window.addEventListener("DOMContentLoaded", function run() {
window.removeEventListener("DOMContentLoaded", run);
runTest();
});
</script>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=912103">Mozilla Bug </a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
</pre>
</body>
</html>

View file

@ -1,327 +0,0 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<?xml-stylesheet href="/tests/SimpleTest/test.css" type="text/css"?>
<window title="Arrow Panels"
style="padding: 10px;"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/>
<stack flex="1">
<label id="topleft" value="Top Left Corner" left="15" top="15"/>
<label id="topright" value="Top Right" right="15" top="15"/>
<label id="bottomleft" value="Bottom Left Corner" left="15" bottom="15"/>
<label id="bottomright" value="Bottom Right" right="15" bottom="15"/>
<!-- Our SimpleTest/TestRunner.js runs tests inside an iframe which sizes are W=500 H=300.
'left' and 'top' values need to be set so that the panel (popup) has enough room to display on its 4 sides. -->
<label id="middle" value="+/- Centered" left="225" top="135"/>
<iframe id="frame" type="content"
src="data:text/html,&lt;input id='input'&gt;" width="100" height="100" left="225" top="120"/>
</stack>
<panel id="panel" type="arrow" animate="false"
onpopupshown="checkPanelPosition(this)" onpopuphidden="runNextTest.next()">
<box width="115" height="65"/>
</panel>
<panel id="bigpanel" type="arrow" animate="false"
onpopupshown="checkBigPanel(this)" onpopuphidden="runNextTest.next()">
<box width="125" height="3000"/>
</panel>
<panel id="animatepanel" type="arrow"
onpopupshown="animatedPopupShown = true;"
onpopuphidden="animatedPopupHidden = true; runNextTest.next();">
<label value="Animate Closed" height="40"/>
</panel>
<script type="application/javascript">
<![CDATA[
SimpleTest.waitForExplicitFinish();
const isOSXYosemite = navigator.userAgent.indexOf("Mac OS X 10.10") != -1;
var expectedAnchor = null;
var expectedSide = "", expectedAnchorEdge = "", expectedPack = "", expectedAlignment = "";
var zoomFactor = 1;
var animatedPopupShown = false;
var animatedPopupHidden = false;
var runNextTest;
function startTest()
{
runNextTest = nextTest();
runNextTest.next();
}
function nextTest()
{
var panel = $("panel");
function openPopup(position, anchor, expected, anchorEdge, pack, alignment)
{
expectedAnchor = anchor instanceof Node ? anchor : $(anchor);
expectedSide = expected;
expectedAnchorEdge = anchorEdge;
expectedPack = pack;
expectedAlignment = alignment == undefined ? position : alignment;
panel.removeAttribute("side");
panel.openPopup(expectedAnchor, position, 0, 0, false, false, null);
}
for (var iter = 0; iter < 2; iter++) {
openPopup("after_start", "topleft", "top", "left", "start");
yield;
openPopup("after_start", "bottomleft", "bottom", "left", "start", "before_start");
yield;
openPopup("before_start", "topleft", "top", "left", "start", "after_start");
yield;
openPopup("before_start", "bottomleft", "bottom", "left", "start");
yield;
openPopup("after_start", "middle", "top", "left", "start");
yield;
openPopup("before_start", "middle", "bottom", "left", "start");
yield;
openPopup("after_start", "topright", "top", "right", "end", "after_end");
yield;
openPopup("after_start", "bottomright", "bottom", "right", "end", "before_end");
yield;
openPopup("before_start", "topright", "top", "right", "end", "after_end");
yield;
openPopup("before_start", "bottomright", "bottom", "right", "end", "before_end");
yield;
openPopup("after_end", "middle", "top", "right", "end");
yield;
openPopup("before_end", "middle", "bottom", "right", "end");
yield;
openPopup("start_before", "topleft", "left", "top", "start", "end_before");
yield;
openPopup("start_before", "topright", "right", "top", "start");
yield;
openPopup("end_before", "topleft", "left", "top", "start");
yield;
openPopup("end_before", "topright", "right", "top", "start", "start_before");
yield;
openPopup("start_before", "middle", "right", "top", "start");
yield;
openPopup("end_before", "middle", "left", "top", "start");
yield;
openPopup("start_before", "bottomleft", "left", "bottom", "end", "end_after");
yield;
openPopup("start_before", "bottomright", "right", "bottom", "end", "start_after");
yield;
openPopup("end_before", "bottomleft", "left", "bottom", "end", "end_after");
yield;
openPopup("end_before", "bottomright", "right", "bottom", "end", "start_after");
yield;
openPopup("start_after", "middle", "right", "bottom", "end");
yield;
openPopup("end_after", "middle", "left", "bottom", "end");
yield;
openPopup("topcenter bottomleft", "bottomleft", "bottom", "center left", "start", "before_start");
yield;
openPopup("bottomcenter topleft", "topleft", "top", "center left", "start", "after_start");
yield;
openPopup("topcenter bottomright", "bottomright", "bottom", "center right", "end", "before_end");
yield;
openPopup("bottomcenter topright", "topright", "top", "center right", "end", "after_end");
yield;
openPopup("topcenter bottomleft", "middle", "bottom", "center left", "start", "before_start");
yield;
openPopup("bottomcenter topleft", "middle", "top", "center left", "start", "after_start");
yield;
openPopup("leftcenter topright", "middle", "right", "center top", "start", "start_before");
yield;
openPopup("rightcenter bottomleft", "middle", "left", "center bottom", "end", "end_after");
yield;
/*
XXXndeakin disable these parts of the test which often cause problems, see bug 626563
openPopup("after_start", frames[0].document.getElementById("input"), "top", "left", "start");
yield;
setScale(frames[0], 1.5);
openPopup("after_start", frames[0].document.getElementById("input"), "top", "left", "start");
yield;
setScale(frames[0], 2.5);
openPopup("before_start", frames[0].document.getElementById("input"), "bottom", "left", "start");
yield;
setScale(frames[0], 1);
*/
$("bigpanel").openPopup($("topleft"), "after_start", 0, 0, false, false, null, "start");
yield;
// switch to rtl mode
document.documentElement.style.direction = "rtl";
$("topleft").setAttribute("right", "15");
$("topright").setAttribute("left", "15");
$("bottomleft").setAttribute("right", "15");
$("bottomright").setAttribute("left", "15");
$("topleft").removeAttribute("left");
$("topright").removeAttribute("right");
$("bottomleft").removeAttribute("left");
$("bottomright").removeAttribute("right");
}
// Test that a transition occurs when opening or closing the popup. The transition is
// disabled on Linux.
if (navigator.platform.indexOf("Linux") == -1) {
function transitionEnded(event) {
if ($("animatepanel").state != "open") {
is($("animatepanel").state, "showing", "state is showing during transitionend");
ok(!animatedPopupShown, "popupshown not fired yet")
} else {
is($("animatepanel").state, "open", "state is open after transitionend");
ok(animatedPopupShown, "popupshown now fired")
SimpleTest.executeSoon(() => runNextTest.next());
}
}
// Check that the transition occurs for an arrow panel with animate="true"
window.addEventListener("transitionend", transitionEnded, false);
$("animatepanel").openPopup($("topleft"), "after_start", 0, 0, false, false, null, "start");
is($("animatepanel").state, "showing", "state is showing");
yield;
window.removeEventListener("transitionend", transitionEnded, false);
synthesizeKey("VK_ESCAPE", { });
ok(!animatedPopupHidden, "animated popup not hidden yet");
yield;
}
SimpleTest.finish()
yield;
}
function setScale(win, scale)
{
var wn = win.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIWebNavigation);
var shell = wn.QueryInterface(Components.interfaces.nsIDocShell);
var docViewer = shell.contentViewer;
docViewer.fullZoom = scale;
zoomFactor = scale;
}
function checkPanelPosition(panel)
{
let anchor = panel.anchorNode;
let adj = 0, hwinpos = 0, vwinpos = 0;
if (anchor.ownerDocument != document) {
var framerect = anchor.ownerDocument.defaultView.frameElement.getBoundingClientRect();
hwinpos = framerect.left;
vwinpos = framerect.top;
}
// Positions are reversed in rtl yet the coordinates used in the computations
// are not, so flip the expected label side and anchor edge.
var isRTL = (window.getComputedStyle(panel).direction == "rtl");
if (isRTL) {
var flipLeftRight = val => val == "left" ? "right" : "left";
expectedAnchorEdge = expectedAnchorEdge.replace(/(left|right)/, flipLeftRight);
expectedSide = expectedSide.replace(/(left|right)/, flipLeftRight);
}
var panelRect = panel.getBoundingClientRect();
var anchorRect = anchor.getBoundingClientRect();
var contentBO = panel.firstChild.boxObject;
var contentRect = { top: contentBO.y,
left: contentBO.x,
bottom: contentBO.y + contentBO.height,
right: contentBO.x + contentBO.width };
switch (expectedSide) {
case "top":
ok(contentRect.top > vwinpos + anchorRect.bottom * zoomFactor + 5, "panel content is below");
break;
case "bottom":
ok(contentRect.bottom < vwinpos + anchorRect.top * zoomFactor - 5, "panel content is above");
break;
case "left":
ok(contentRect.left > hwinpos + anchorRect.right * zoomFactor + 5, "panel content is right");
break;
case "right":
ok(contentRect.right < hwinpos + anchorRect.left * zoomFactor - 5, "panel content is left");
break;
}
let iscentered = false;
if (expectedAnchorEdge.indexOf("center ") == 0) {
expectedAnchorEdge = expectedAnchorEdge.substring(7);
iscentered = true;
}
switch (expectedAnchorEdge) {
case "top":
adj = vwinpos + parseInt(getComputedStyle(panel, "").marginTop);
if (iscentered)
adj += Math.round(anchorRect.height) / 2;
isWithinHalfPixel(panelRect.top, anchorRect.top * zoomFactor + adj, "anchored on top");
break;
case "bottom":
adj = vwinpos + parseInt(getComputedStyle(panel, "").marginBottom);
if (iscentered)
adj += Math.round(anchorRect.height) / 2;
isWithinHalfPixel(panelRect.bottom, anchorRect.bottom * zoomFactor - adj, "anchored on bottom");
break;
case "left":
adj = hwinpos + parseInt(getComputedStyle(panel, "").marginLeft);
if (iscentered)
adj += Math.round(anchorRect.width) / 2;
isWithinHalfPixel(panelRect.left, anchorRect.left * zoomFactor + adj, "anchored on left ");
break;
case "right":
adj = hwinpos + parseInt(getComputedStyle(panel, "").marginRight);
if (iscentered)
adj += Math.round(anchorRect.width) / 2;
if (!isOSXYosemite)
isWithinHalfPixel(panelRect.right, anchorRect.right * zoomFactor - adj, "anchored on right");
break;
}
is(anchor, expectedAnchor, "anchor");
var arrow = document.getAnonymousElementByAttribute(panel, "anonid", "arrow");
is(arrow.getAttribute("side"), expectedSide, "panel arrow side");
is(arrow.hidden, false, "panel hidden");
is(arrow.parentNode.pack, expectedPack, "panel arrow pack");
is(panel.alignmentPosition, expectedAlignment, "panel alignmentPosition");
panel.hidePopup();
}
function isWithinHalfPixel(a, b, desc)
{
ok(Math.abs(a - b) <= 0.5, desc);
}
function checkBigPanel(panel)
{
ok(panel.firstChild.getBoundingClientRect().height < 2800, "big panel height");
panel.hidePopup();
}
SimpleTest.waitForFocus(startTest);
]]>
</script>
<body xmlns="http://www.w3.org/1999/xhtml"/>
</window>

View file

@ -1,197 +0,0 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
<window title="Autocomplete Widget Test 2"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/>
<textbox id="autocomplete" type="autocomplete"
autocompletesearch="simple"
onsearchcomplete="checkResult();"/>
<script class="testbody" type="application/javascript">
<![CDATA[
// Set to indicate whether or not we want autoCompleteSimple to return a result
var returnResult = false;
const ACR = Components.interfaces.nsIAutoCompleteResult;
// This result can't be constructed in-line, because otherwise we leak memory.
function nsAutoCompleteSimpleResult(aString)
{
this.searchString = aString;
if (returnResult) {
this.searchResult = ACR.RESULT_SUCCESS;
this.matchCount = 1;
this._param = "SUCCESS";
}
}
nsAutoCompleteSimpleResult.prototype = {
_param: "",
searchString: null,
searchResult: ACR.RESULT_FAILURE,
defaultIndex: -1,
errorDescription: null,
matchCount: 0,
getValueAt: function() { return this._param; },
getCommentAt: function() { return null; },
getStyleAt: function() { return null; },
getImageAt: function() { return null; },
getFinalCompleteValueAt: function() { return this.getValueAt(); },
getLabelAt: function() { return null; },
removeValueAt: function() {}
};
// A basic autocomplete implementation that either returns one result or none
var autoCompleteSimpleID = Components.ID("0a2afbdb-f30e-47d1-9cb1-0cd160240aca");
var autoCompleteSimpleName = "@mozilla.org/autocomplete/search;1?name=simple"
var autoCompleteSimple = {
QueryInterface: function(iid) {
if (iid.equals(Components.interfaces.nsISupports) ||
iid.equals(Components.interfaces.nsIFactory) ||
iid.equals(Components.interfaces.nsIAutoCompleteSearch))
return this;
throw Components.results.NS_ERROR_NO_INTERFACE;
},
createInstance: function(outer, iid) {
return this.QueryInterface(iid);
},
startSearch: function(aString, aParam, aResult, aListener) {
var result = new nsAutoCompleteSimpleResult(aString);
aListener.onSearchResult(this, result);
},
stopSearch: function() {}
};
var componentManager = Components.manager
.QueryInterface(Components.interfaces.nsIComponentRegistrar);
componentManager.registerFactory(autoCompleteSimpleID, "Test Simple Autocomplete",
autoCompleteSimpleName, autoCompleteSimple);
// Test Bug 441530 - correctly setting "nomatch"
// Test Bug 441526 - correctly setting style with "highlightnonmatches"
SimpleTest.waitForExplicitFinish();
setTimeout(startTest, 0);
function startTest() {
var autocomplete = $("autocomplete");
// Ensure highlightNonMatches can be set correctly.
// This should not be set by default.
is(autocomplete.hasAttribute("highlightnonmatches"), false,
"highlight nonmatches not set by default");
autocomplete.highlightNonMatches = "true";
is(autocomplete.getAttribute("highlightnonmatches"), "true",
"highlight non matches attribute set correctly");
is(autocomplete.highlightNonMatches, true,
"highlight non matches getter returned correctly");
autocomplete.highlightNonMatches = "false";
is(autocomplete.getAttribute("highlightnonmatches"), "false",
"highlight non matches attribute set to false correctly");
is(autocomplete.highlightNonMatches, false,
"highlight non matches getter returned false correctly");
ok(!autocomplete.popup.hasAttribute("autocompleteinput"),
"autocompleteinput on popup not set by default");
check();
}
function check() {
var autocomplete = $("autocomplete");
// Toggle this value, so we can re-use the one function.
returnResult = !returnResult;
// blur the field to ensure that the popup is closed and that the previous
// search has stopped, then start a new search.
autocomplete.blur();
autocomplete.focus();
synthesizeKey("r", {});
}
function checkResult() {
var autocomplete = $("autocomplete");
var style = window.getComputedStyle(autocomplete, "");
if (returnResult) {
// Result was returned, so there should not be a nomatch attribute
is(autocomplete.hasAttribute("nomatch"), false,
"nomatch attribute shouldn't be present here");
// Ensure that the style is set correctly whichever way highlightNonMatches
// is set.
autocomplete.highlightNonMatches = "true";
isnot(style.getPropertyCSSValue("color").cssText, "rgb(255, 0, 0)",
"not nomatch and highlightNonMatches - should not be red");
autocomplete.highlightNonMatches = "false";
isnot(style.getPropertyCSSValue("color").cssText, "rgb(255, 0, 0)",
"not nomatch and not highlightNonMatches - should not be red");
is (autocomplete.popup.getAttribute("autocompleteinput"), "autocomplete",
"The popup's autocompleteinput attribute is set to the ID of the textbox");
setTimeout(check, 0);
}
else {
// No result was returned, so there should be nomatch attribute
is(autocomplete.getAttribute("nomatch"), "true",
"nomatch attribute not correctly set when expected");
// Ensure that the style is set correctly whichever way highlightNonMatches
// is set.
autocomplete.highlightNonMatches = "true";
is(style.getPropertyCSSValue("color").cssText, "rgb(255, 0, 0)",
"nomatch and highlightNonMatches - should be red");
autocomplete.highlightNonMatches = "false";
isnot(style.getPropertyCSSValue("color").cssText, "rgb(255, 0, 0)",
"nomatch and not highlightNonMatches - should not be red");
ok(!autocomplete.popup.hasAttribute("autocompleteinput"),
"autocompleteinput on popup not set when closed");
setTimeout(function() {
// Unregister the factory so that we don't get in the way of other tests
componentManager.unregisterFactory(autoCompleteSimpleID, autoCompleteSimple);
SimpleTest.finish();
}, 0);
}
}
]]>
</script>
<body xmlns="http://www.w3.org/1999/xhtml">
<p id="display">
</p>
<div id="content" style="display: none">
</div>
<pre id="test">
</pre>
</body>
</window>

View file

@ -1,188 +0,0 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
<window title="Autocomplete Widget Test 3"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/>
<textbox id="autocomplete" type="autocomplete"
autocompletesearch="simple"
onsearchcomplete="checkResult();"/>
<script class="testbody" type="application/javascript">
<![CDATA[
// Set to indicate whether or not we want autoCompleteSimple to return a result
var returnResult = true;
const ACR = Components.interfaces.nsIAutoCompleteResult;
// This result can't be constructed in-line, because otherwise we leak memory.
function nsAutoCompleteSimpleResult(aString)
{
this.searchString = aString;
if (returnResult) {
this.searchResult = ACR.RESULT_SUCCESS;
this.matchCount = 1;
this._param = "Result";
}
}
nsAutoCompleteSimpleResult.prototype = {
_param: "",
searchString: null,
searchResult: ACR.RESULT_FAILURE,
defaultIndex: 0,
errorDescription: null,
matchCount: 0,
getValueAt: function() { return this._param; },
getCommentAt: function() { return null; },
getStyleAt: function() { return null; },
getImageAt: function() { return null; },
getFinalCompleteValueAt: function() { return this.getValueAt(); },
getLabelAt: function() { return null; },
removeValueAt: function() {}
};
// A basic autocomplete implementation that either returns one result or none
var autoCompleteSimpleID = Components.ID("0a2afbdb-f30e-47d1-9cb1-0cd160240aca");
var autoCompleteSimpleName = "@mozilla.org/autocomplete/search;1?name=simple"
var autoCompleteSimple = {
QueryInterface: function(iid) {
if (iid.equals(Components.interfaces.nsISupports) ||
iid.equals(Components.interfaces.nsIFactory) ||
iid.equals(Components.interfaces.nsIAutoCompleteSearch))
return this;
throw Components.results.NS_ERROR_NO_INTERFACE;
},
createInstance: function(outer, iid) {
return this.QueryInterface(iid);
},
startSearch: function(aString, aParam, aResult, aListener) {
var result = new nsAutoCompleteSimpleResult(aString);
aListener.onSearchResult(this, result);
},
stopSearch: function() {}
};
var componentManager = Components.manager
.QueryInterface(Components.interfaces.nsIComponentRegistrar);
componentManager.registerFactory(autoCompleteSimpleID, "Test Simple Autocomplete",
autoCompleteSimpleName, autoCompleteSimple);
// Test Bug 325842 - completeDefaultIndex
SimpleTest.waitForExplicitFinish();
setTimeout(startTest, 0);
var currentTest = 0;
// Note the entries for these tests (key) are incremental.
const tests = [
{ completeDefaultIndex: "false", key: "r", result: "r",
start: 1, end: 1 },
{ completeDefaultIndex: "true", key: "e", result: "result",
start: 2, end: 6 },
{ completeDefaultIndex: "true", key: "t", result: "ret >> Result",
start: 3, end: 13 }
];
function startTest() {
var autocomplete = $("autocomplete");
// These should not be set by default.
is(autocomplete.hasAttribute("completedefaultindex"), false,
"completedefaultindex not set by default");
autocomplete.completeDefaultIndex = "true";
is(autocomplete.getAttribute("completedefaultindex"), "true",
"completedefaultindex attribute set correctly");
is(autocomplete.completeDefaultIndex, true,
"autoFill getter returned correctly");
autocomplete.completeDefaultIndex = "false";
is(autocomplete.getAttribute("completedefaultindex"), "false",
"completedefaultindex attribute set to false correctly");
is(autocomplete.completeDefaultIndex, false,
"completeDefaultIndex getter returned false correctly");
checkNext();
}
function checkNext() {
var autocomplete = $("autocomplete");
autocomplete.completeDefaultIndex = tests[currentTest].completeDefaultIndex;
autocomplete.focus();
synthesizeKey(tests[currentTest].key, {});
}
function checkResult() {
var autocomplete = $("autocomplete");
var style = window.getComputedStyle(autocomplete, "");
is(autocomplete.value, tests[currentTest].result,
"Test " + currentTest + ": autocomplete.value should equal '" +
tests[currentTest].result + "'");
is(autocomplete.selectionStart, tests[currentTest].start,
"Test " + currentTest + ": autocomplete selection should start at " +
tests[currentTest].start);
is(autocomplete.selectionEnd, tests[currentTest].end,
"Test " + currentTest + ": autocomplete selection should end at " +
tests[currentTest].end);
++currentTest;
if (currentTest < tests.length)
setTimeout(checkNext, 0);
else {
// TODO (bug 494809): Autocomplete-in-the-middle should take in count RTL
// and complete on VK_RIGHT or VK_LEFT based on that. It should also revert
// what user has typed to far if he moves in the opposite direction.
if (autocomplete.value.indexOf(">>") == -1) {
// Test result if user accepts autocomplete suggestion.
synthesizeKey("VK_RIGHT", {});
is(autocomplete.value, "Result",
"Test complete: autocomplete.value should equal 'Result'");
is(autocomplete.selectionStart, 6,
"Test complete: autocomplete selection should start at 6");
is(autocomplete.selectionEnd, 6,
"Test complete: autocomplete selection should end at 6");
}
setTimeout(function() {
// Unregister the factory so that we don't get in the way of other tests
componentManager.unregisterFactory(autoCompleteSimpleID, autoCompleteSimple);
SimpleTest.finish();
}, 0);
}
}
]]>
</script>
<body xmlns="http://www.w3.org/1999/xhtml">
<p id="display">
</p>
<div id="content" style="display: none">
</div>
<pre id="test">
</pre>
</body>
</window>

View file

@ -1,280 +0,0 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
<window title="Autocomplete Widget Test 4"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/>
<textbox id="autocomplete"
type="autocomplete"
completedefaultindex="true"
onsearchcomplete="searchComplete();"
autocompletesearch="simple"/>
<script class="testbody" type="application/javascript">
<![CDATA[
// Set to indicate whether or not we want autoCompleteSimple to return a result
var returnResult = true;
const ACR = Components.interfaces.nsIAutoCompleteResult;
// This result can't be constructed in-line, because otherwise we leak memory.
function nsAutoCompleteSimpleResult(aString)
{
this.searchString = aString;
if (returnResult) {
this.searchResult = ACR.RESULT_SUCCESS;
this.matchCount = 1;
this._param = "Result";
}
}
nsAutoCompleteSimpleResult.prototype = {
_param: "",
searchString: null,
searchResult: ACR.RESULT_FAILURE,
defaultIndex: 0,
errorDescription: null,
matchCount: 0,
getValueAt: function() { return this._param; },
getCommentAt: function() { return null; },
getStyleAt: function() { return null; },
getImageAt: function() { return null; },
getFinalCompleteValueAt: function() { return this.getValueAt(); },
getLabelAt: function() { return null; },
removeValueAt: function() {}
};
// A basic autocomplete implementation that either returns one result or none
var autoCompleteSimpleID = Components.ID("0a2afbdb-f30e-47d1-9cb1-0cd160240aca");
var autoCompleteSimpleName = "@mozilla.org/autocomplete/search;1?name=simple"
var autoCompleteSimple = {
QueryInterface: function(iid) {
if (iid.equals(Components.interfaces.nsISupports) ||
iid.equals(Components.interfaces.nsIFactory) ||
iid.equals(Components.interfaces.nsIAutoCompleteSearch))
return this;
throw Components.results.NS_ERROR_NO_INTERFACE;
},
createInstance: function(outer, iid) {
return this.QueryInterface(iid);
},
startSearch: function(aString, aParam, aResult, aListener) {
var result = new nsAutoCompleteSimpleResult(aString);
aListener.onSearchResult(this, result);
},
stopSearch: function() {}
};
var componentManager = Components.manager
.QueryInterface(Components.interfaces.nsIComponentRegistrar);
componentManager.registerFactory(autoCompleteSimpleID, "Test Simple Autocomplete",
autoCompleteSimpleName, autoCompleteSimple);
// Test Bug 325842 - completeDefaultIndex
SimpleTest.waitForExplicitFinish();
setTimeout(nextTest, 0);
var currentTest = null;
// Note the entries for these tests (key) are incremental.
const tests = [
{
desc: "HOME key remove selection",
key: "VK_HOME",
removeSelection: true,
result: "re",
start: 0, end: 0
},
{
desc: "LEFT key remove selection",
key: "VK_LEFT",
removeSelection: true,
result: "re",
start: 1, end: 1
},
{ desc: "RIGHT key remove selection",
key: "VK_RIGHT",
removeSelection: true,
result: "re",
start: 2, end: 2
},
{ desc: "ENTER key remove selection",
key: "VK_RETURN",
removeSelection: true,
result: "re",
start: 2, end: 2
},
{
desc: "HOME key",
key: "VK_HOME",
removeSelection: false,
result: "Result",
start: 0, end: 0
},
{
desc: "LEFT key",
key: "VK_LEFT",
removeSelection: false,
result: "Result",
start: 5, end: 5
},
{ desc: "RIGHT key",
key: "VK_RIGHT",
removeSelection: false,
result: "Result",
start: 6, end: 6
},
{ desc: "RETURN key",
key: "VK_RETURN",
removeSelection: false,
result: "Result",
start: 6, end: 6
},
{ desc: "TAB key should confirm suggestion when forcecomplete is set",
key: "VK_TAB",
removeSelection: false,
forceComplete: true,
result: "Result",
start: 6, end: 6
},
{ desc: "RIGHT key complete from middle",
key: "VK_RIGHT",
forceComplete: true,
completeFromMiddle: true,
result: "Result",
start: 6, end: 6
},
{
desc: "RIGHT key w/ minResultsForPopup=2",
key: "VK_RIGHT",
removeSelection: false,
minResultsForPopup: 2,
result: "Result",
start: 6, end: 6
},
];
function nextTest() {
if (!tests.length) {
// No more tests to run, finish.
setTimeout(function() {
// Unregister the factory so that we don't get in the way of other tests
componentManager.unregisterFactory(autoCompleteSimpleID, autoCompleteSimple);
SimpleTest.finish();
}, 0);
return;
}
var autocomplete = $("autocomplete");
autocomplete.value = "";
currentTest = tests.shift();
// HOME key works differently on Mac, so we skip tests using it.
if (currentTest.key == "VK_HOME" && navigator.platform.indexOf("Mac") != -1)
nextTest();
else
setTimeout(runCurrentTest, 0);
}
function runCurrentTest() {
var autocomplete = $("autocomplete");
if ("minResultsForPopup" in currentTest)
autocomplete.setAttribute("minresultsforpopup", currentTest.minResultsForPopup)
else
autocomplete.removeAttribute("minresultsforpopup");
autocomplete.focus();
if (!currentTest.completeFromMiddle) {
synthesizeKey("r", {});
synthesizeKey("e", {});
}
else {
synthesizeKey("l", {});
synthesizeKey("t", {});
}
}
function searchComplete() {
var autocomplete = $("autocomplete");
autocomplete.setAttribute("forcecomplete", currentTest.forceComplete ? true : false);
if (currentTest.completeFromMiddle) {
if (!currentTest.forceComplete) {
synthesizeKey(currentTest.key, {});
}
else if (!/ >> /.test(autocomplete.value)) {
// At this point we should have a value like "lt >> Result" showing.
throw new Error("Expected an middle-completed value, got " + autocomplete.value);
}
// For forceComplete a blur should cause a value from the results to get
// completed to. E.g. "lt >> Result" will turn into "Result".
if (currentTest.forceComplete)
autocomplete.blur();
checkResult();
return;
}
is(autocomplete.value, "result",
"Test '" + currentTest.desc + "': autocomplete.value should equal 'result'");
if (autocomplete.selectionStart == 2) { // Finished inserting "re" string.
if (currentTest.removeSelection) {
// remove current selection
synthesizeKey("VK_DELETE", {});
}
synthesizeKey(currentTest.key, {});
checkResult();
}
}
function checkResult() {
var autocomplete = $("autocomplete");
is(autocomplete.value, currentTest.result,
"Test '" + currentTest.desc + "': autocomplete.value should equal '" +
currentTest.result + "'");
is(autocomplete.selectionStart, currentTest.start,
"Test '" + currentTest.desc + "': autocomplete selection should start at " +
currentTest.start);
is(autocomplete.selectionEnd, currentTest.end,
"Test '" + currentTest.desc + "': autocomplete selection should end at " +
currentTest.end);
setTimeout(nextTest, 0);
}
]]>
</script>
<body xmlns="http://www.w3.org/1999/xhtml">
<p id="display">
</p>
<div id="content" style="display: none">
</div>
<pre id="test">
</pre>
</body>
</window>

View file

@ -1,152 +0,0 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
<window title="Autocomplete Widget Test 5"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/>
<textbox id="autocomplete" type="autocomplete"
autocompletesearch="simple"
ontextentered="checkTextEntered();"
ontextreverted="checkTextReverted();"
onsearchbegin="checkSearchBegin();"
onsearchcomplete="checkSearchCompleted();"/>
<script class="testbody" type="application/javascript">
<![CDATA[
const ACR = Components.interfaces.nsIAutoCompleteResult;
// This result can't be constructed in-line, because otherwise we leak memory.
function nsAutoCompleteSimpleResult(aString)
{
this.searchString = aString;
this.searchResult = ACR.RESULT_SUCCESS;
this.matchCount = 1;
this._param = "SUCCESS";
}
nsAutoCompleteSimpleResult.prototype = {
_param: "",
searchString: null,
searchResult: ACR.RESULT_FAILURE,
defaultIndex: -1,
errorDescription: null,
matchCount: 0,
getValueAt: function() { return this._param; },
getCommentAt: function() { return null; },
getStyleAt: function() { return null; },
getImageAt: function() { return null; },
getFinalCompleteValueAt: function() { return this.getValueAt(); },
getLabelAt: function() { return null; },
removeValueAt: function() {}
};
// A basic autocomplete implementation that either returns one result or none
var autoCompleteSimpleID = Components.ID("0a2afbdb-f30e-47d1-9cb1-0cd160240aca");
var autoCompleteSimpleName = "@mozilla.org/autocomplete/search;1?name=simple"
var autoCompleteSimple = {
QueryInterface: function(iid) {
if (iid.equals(Components.interfaces.nsISupports) ||
iid.equals(Components.interfaces.nsIFactory) ||
iid.equals(Components.interfaces.nsIAutoCompleteSearch))
return this;
throw Components.results.NS_ERROR_NO_INTERFACE;
},
createInstance: function(outer, iid) {
return this.QueryInterface(iid);
},
startSearch: function(aString, aParam, aResult, aListener) {
var result = new nsAutoCompleteSimpleResult(aString);
aListener.onSearchResult(this, result);
},
stopSearch: function() {}
};
var componentManager = Components.manager
.QueryInterface(Components.interfaces.nsIComponentRegistrar);
componentManager.registerFactory(autoCompleteSimpleID, "Test Simple Autocomplete",
autoCompleteSimpleName, autoCompleteSimple);
SimpleTest.waitForExplicitFinish();
setTimeout(startTest, 0);
function startTest() {
let autocomplete = $("autocomplete");
// blur the field to ensure that the popup is closed and that the previous
// search has stopped, then start a new search.
autocomplete.blur();
autocomplete.focus();
synthesizeKey("r", {});
}
let hasTextEntered = false;
let hasSearchBegun = false;
function checkSearchBegin() {
hasSearchBegun = true;
}
let test = 0;
function checkSearchCompleted() {
is(hasSearchBegun, true, "onsearchbegin handler has been correctly called.");
if (test == 0) {
hasSearchBegun = false;
synthesizeKey("VK_RETURN", { });
} else if (test == 1) {
hasSearchBegun = false;
synthesizeKey("VK_ESCAPE", { });
} else {
throw "checkSearchCompleted should only be called twice.";
}
}
function checkTextEntered() {
is(test, 0, "checkTextEntered should be reached from first test.");
is(hasSearchBegun, false, "onsearchbegin handler should not be called on text revert.");
// fire second test
test++;
let autocomplete = $("autocomplete");
autocomplete.textValue = "";
autocomplete.blur();
autocomplete.focus();
synthesizeKey("r", {});
}
function checkTextReverted() {
is(test, 1, "checkTextReverted should be the second test reached.");
is(hasSearchBegun, false, "onsearchbegin handler should not be called on text revert.");
setTimeout(function() {
// Unregister the factory so that we don't get in the way of other tests
componentManager.unregisterFactory(autoCompleteSimpleID, autoCompleteSimple);
SimpleTest.finish();
}, 0);
}
]]>
</script>
<body xmlns="http://www.w3.org/1999/xhtml">
<p id="display">
</p>
<div id="content" style="display: none">
</div>
<pre id="test">
</pre>
</body>
</window>

View file

@ -1,128 +0,0 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
<window title="Autocomplete Widget Test 4"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
onload="runTest();">
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/>
<script type="application/javascript"
src="chrome://global/content/globalOverlay.js"/>
<textbox id="autocomplete"
type="autocomplete"
completedefaultindex="true"
onsearchcomplete="searchComplete();"
timeout="0"
autocompletesearch="simple"/>
<script class="testbody" type="application/javascript">
<![CDATA[
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
function autoCompleteSimpleResult(aString) {
this.searchString = aString;
this.searchResult = Components.interfaces.nsIAutoCompleteResult.RESULT_SUCCESS;
this.matchCount = 1;
this._param = "Result";
}
autoCompleteSimpleResult.prototype = {
_param: "",
searchString: null,
searchResult: Components.interfaces.nsIAutoCompleteResult.RESULT_FAILURE,
defaultIndex: 0,
errorDescription: null,
matchCount: 0,
getValueAt: function() { return this._param; },
getCommentAt: function() { return null; },
getStyleAt: function() { return null; },
getImageAt: function() { return null; },
getFinalCompleteValueAt: function() { return this.getValueAt(); },
getLabelAt: function() { return null; },
removeValueAt: function() {}
};
// A basic autocomplete implementation that returns one result.
let autoCompleteSimple = {
classID: Components.ID("0a2afbdb-f30e-47d1-9cb1-0cd160240aca"),
contractID: "@mozilla.org/autocomplete/search;1?name=simple",
QueryInterface: XPCOMUtils.generateQI([
Components.interfaces.nsIFactory,
Components.interfaces.nsIAutoCompleteSearch
]),
createInstance: function (outer, iid) {
return this.QueryInterface(iid);
},
registerFactory: function () {
let registrar =
Components.manager.QueryInterface(Components.interfaces.nsIComponentRegistrar);
registrar.registerFactory(this.classID, "Test Simple Autocomplete",
this.contractID, this);
},
unregisterFactory: function () {
let registrar =
Components.manager.QueryInterface(Components.interfaces.nsIComponentRegistrar);
registrar.unregisterFactory(this.classID, this);
},
startSearch: function (aString, aParam, aResult, aListener) {
let result = new autoCompleteSimpleResult(aString);
aListener.onSearchResult(this, result);
},
stopSearch: function () {}
};
SimpleTest.waitForExplicitFinish();
// XPFE AutoComplete needs to register early.
autoCompleteSimple.registerFactory();
let gACTimer;
let gAutoComplete;
function searchComplete() {
is(gAutoComplete.value, "result", "Value should be autocompleted now");
ok(Date.now() - gACTimer > 500, "There should be a delay before autocomplete");
// Unregister the factory so that we don't get in the way of other tests
autoCompleteSimple.unregisterFactory();
SimpleTest.finish();
}
function runTest() {
gAutoComplete = $("autocomplete");
const SEARCH_STRING = "res";
function cbCallback() {
gAutoComplete.focus();
synthesizeKey("v", { accelKey: true });
is(gAutoComplete.value, SEARCH_STRING, "Value should not be autocompleted immediately");
}
SimpleTest.waitForClipboard(SEARCH_STRING, function () {
gACTimer = Date.now();
Components.classes["@mozilla.org/widget/clipboardhelper;1"]
.getService(Components.interfaces.nsIClipboardHelper)
.copyStringToClipboard(SEARCH_STRING, Components.interfaces.nsIClipboard.kGlobalClipboard);
}, cbCallback, cbCallback);
}
]]>
</script>
<body xmlns="http://www.w3.org/1999/xhtml">
<p id="display">
</p>
<div id="content" style="display: none">
</div>
<pre id="test">
</pre>
</body>
</window>

View file

@ -1,175 +0,0 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
<window title="Autocomplete emphasis test"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/>
<textbox id="richautocomplete" type="autocomplete"
autocompletesearch="simple"
onsearchcomplete="checkSearchCompleted();"
autocompletepopup="richpopup"/>
<panel id="richpopup" type="autocomplete-richlistbox" noautofocus="true"/>
<script class="testbody" type="application/javascript">
<![CDATA[
const ACR = Components.interfaces.nsIAutoCompleteResult;
// A global variable to hold the search result for the current search.
var resultText = "";
// This result can't be constructed in-line, because otherwise we leak memory.
function nsAutoCompleteSimpleResult(aString)
{
this.searchString = aString;
this.searchResult = ACR.RESULT_SUCCESS;
this.matchCount = 1;
}
nsAutoCompleteSimpleResult.prototype = {
searchString: null,
searchResult: ACR.RESULT_FAILURE,
defaultIndex: -1,
errorDescription: null,
matchCount: 0,
getValueAt: function() { return resultText; },
getCommentAt: function() { return this.getValueAt(); },
getStyleAt: function() { return null; },
getImageAt: function() { return null; },
getFinalCompleteValueAt: function() { return this.getValueAt(); },
getLabelAt: function() { return this.getValueAt(); },
removeValueAt: function() {}
};
// A basic autocomplete implementation that returns the string contained in 'resultText'.
var autoCompleteSimpleID = Components.ID("0a2afbdb-f30e-47d1-9cb1-0cd160240aca");
var autoCompleteSimpleName = "@mozilla.org/autocomplete/search;1?name=simple"
var autoCompleteSimple = {
QueryInterface: function(iid) {
if (iid.equals(Components.interfaces.nsISupports) ||
iid.equals(Components.interfaces.nsIFactory) ||
iid.equals(Components.interfaces.nsIAutoCompleteSearch))
return this;
throw Components.results.NS_ERROR_NO_INTERFACE;
},
createInstance: function(outer, iid) {
return this.QueryInterface(iid);
},
startSearch: function(aString, aParam, aResult, aListener) {
var result = new nsAutoCompleteSimpleResult(aString);
aListener.onSearchResult(this, result);
},
stopSearch: function() {}
};
var componentManager = Components.manager
.QueryInterface(Components.interfaces.nsIComponentRegistrar);
componentManager.registerFactory(autoCompleteSimpleID, "Test Simple Autocomplete",
autoCompleteSimpleName, autoCompleteSimple);
SimpleTest.waitForExplicitFinish();
setTimeout(nextTest, 0);
/* Test cases have the following attributes:
* - search: A search string, to be emphasized in the result.
* - result: A fixed result string, so we can hardcode the expected emphasis.
* - emphasis: A list of chunks that should be emphasized or not, in strict alternation.
* - emphasizeFirst: Whether the first element of 'emphasis' should be emphasized;
* The emphasis of the other elements is defined by the strict alternation rule.
*/
let testcases = [
{ search: "test",
result: "A test string",
emphasis: ["A ", "test", " string"],
emphasizeFirst: false
},
{ search: "tea two",
result: "Tea for two, and two for tea...",
emphasis: ["Tea", " for ", "two", ", and ", "two", " for ", "tea", "..."],
emphasizeFirst: true
},
{ search: "tat",
result: "tatatat",
emphasis: ["tatatat"],
emphasizeFirst: true
},
{ search: "cheval valise",
result: "chevalise",
emphasis: ["chevalise"],
emphasizeFirst: true
}
];
let test = -1;
let currentTest = null;
function nextTest() {
test++;
if (test >= testcases.length) {
// Unregister the factory so that we don't get in the way of other tests
componentManager.unregisterFactory(autoCompleteSimpleID, autoCompleteSimple);
SimpleTest.finish();
return;
}
// blur the field to ensure that the popup is closed and that the previous
// search has stopped, then start a new search.
let autocomplete = $("richautocomplete");
autocomplete.blur();
autocomplete.focus();
currentTest = testcases[test];
resultText = currentTest.result;
autocomplete.value = currentTest.search;
synthesizeKey("VK_DOWN", {});
}
function checkSearchCompleted() {
let autocomplete = $("richautocomplete");
let result = autocomplete.popup.richlistbox.firstChild;
for (let attribute of [result._titleText, result._urlText]) {
is(attribute.childNodes.length, currentTest.emphasis.length,
"The element should have the expected number of children.");
for (let i = 0; i < currentTest.emphasis.length; i++) {
let node = attribute.childNodes[i];
// Emphasized parts strictly alternate.
if ((i % 2 == 0) == currentTest.emphasizeFirst) {
// Check that this part is correctly emphasized.
is(node.nodeName, "span", ". That child should be a span node");
ok(node.classList.contains("ac-emphasize-text"), ". That child should be emphasized");
is(node.textContent, currentTest.emphasis[i], ". That emphasis should be as expected.");
} else {
// Check that this part is _not_ emphasized.
is(node.nodeName, "#text", ". That child should be a text node");
is(node.textContent, currentTest.emphasis[i], ". That text should be as expected.");
}
}
}
setTimeout(nextTest, 0);
}
]]>
</script>
<body xmlns="http://www.w3.org/1999/xhtml">
<p id="display">
</p>
<div id="content" style="display: none">
</div>
<pre id="test">
</pre>
</body>
</window>

View file

@ -1,74 +0,0 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
<window title="Autocomplete Widget Test"
onload="setTimeout(keyCaretTest, 0);"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/>
<textbox id="autocomplete" type="autocomplete"/>
<script class="testbody" type="application/javascript">
<![CDATA[
SimpleTest.waitForExplicitFinish();
function keyCaretTest()
{
var autocomplete = $("autocomplete");
autocomplete.focus();
checkKeyCaretTest("VK_UP", 0, 0, false, "no value up");
checkKeyCaretTest("VK_DOWN", 0, 0, false, "no value down");
autocomplete.value = "Sample";
autocomplete.selectionStart = 3;
autocomplete.selectionEnd = 3;
checkKeyCaretTest("VK_UP", 0, 0, true, "value up with caret in middle");
checkKeyCaretTest("VK_UP", 0, 0, false, "value up with caret in middle again");
autocomplete.selectionStart = 2;
autocomplete.selectionEnd = 2;
checkKeyCaretTest("VK_DOWN", 6, 6, true, "value down with caret in middle");
checkKeyCaretTest("VK_DOWN", 6, 6, false, "value down with caret in middle again");
autocomplete.selectionStart = 1;
autocomplete.selectionEnd = 4;
checkKeyCaretTest("VK_UP", 0, 0, true, "value up with selection");
autocomplete.selectionStart = 1;
autocomplete.selectionEnd = 4;
checkKeyCaretTest("VK_DOWN", 6, 6, true, "value down with selection");
SimpleTest.finish();
}
function checkKeyCaretTest(key, expectedStart, expectedEnd, result, testid)
{
var autocomplete = $("autocomplete");
var event = result ? "keypress" : "!keypress";
synthesizeKeyExpectEvent(key, { }, autocomplete.inputField, event, testid);
is(autocomplete.selectionStart, expectedStart, testid + " selectionStart");
is(autocomplete.selectionEnd, expectedEnd, testid + " selectionEnd");
}
]]>
</script>
<body xmlns="http://www.w3.org/1999/xhtml">
<p id="display">
</p>
<div id="content" style="display: none">
</div>
<pre id="test">
</pre>
</body>
</window>

View file

@ -1,309 +0,0 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
<window title="Autocomplete Widget Test"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
onload="runTest();">
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/>
<script type="application/javascript"
src="chrome://global/content/globalOverlay.js"/>
<textbox id="autocomplete"
type="autocomplete"
completedefaultindex="true"
timeout="0"
autocompletesearch="simple"/>
<script class="testbody" type="application/javascript">
<![CDATA[
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
function autoCompleteSimpleResult(aString, searchId) {
this.searchString = aString;
this.searchResult = Components.interfaces.nsIAutoCompleteResult.RESULT_SUCCESS;
this.matchCount = 1;
if (aString.startsWith('ret')) {
this._param = autoCompleteSimpleResult.retireCompletion;
} else {
this._param = "Result";
}
this._searchId = searchId;
}
autoCompleteSimpleResult.retireCompletion = "Retire";
autoCompleteSimpleResult.prototype = {
_param: "",
searchString: null,
searchResult: Components.interfaces.nsIAutoCompleteResult.RESULT_FAILURE,
defaultIndex: 0,
errorDescription: null,
matchCount: 0,
getValueAt: function() { return this._param; },
getCommentAt: function() { return null; },
getStyleAt: function() { return null; },
getImageAt: function() { return null; },
getLabelAt: function() { return null; },
removeValueAt: function() {}
};
var searchCounter = 0;
// A basic autocomplete implementation that returns one result.
let autoCompleteSimple = {
classID: Components.ID("0a2afbdb-f30e-47d1-9cb1-0cd160240aca"),
contractID: "@mozilla.org/autocomplete/search;1?name=simple",
searchAsync: false,
pendingSearch: null,
QueryInterface: XPCOMUtils.generateQI([
Components.interfaces.nsIFactory,
Components.interfaces.nsIAutoCompleteSearch
]),
createInstance: function (outer, iid) {
return this.QueryInterface(iid);
},
registerFactory: function () {
let registrar =
Components.manager.QueryInterface(Components.interfaces.nsIComponentRegistrar);
registrar.registerFactory(this.classID, "Test Simple Autocomplete",
this.contractID, this);
},
unregisterFactory: function () {
let registrar =
Components.manager.QueryInterface(Components.interfaces.nsIComponentRegistrar);
registrar.unregisterFactory(this.classID, this);
},
startSearch: function (aString, aParam, aResult, aListener) {
let result = new autoCompleteSimpleResult(aString);
if (this.searchAsync) {
// Simulate an async search by using a timeout before invoking the
// |onSearchResult| callback.
// Store the searchTimeout such that it can be canceled if stopSearch is called.
this.pendingSearch = setTimeout(() => {
this.pendingSearch = null;
aListener.onSearchResult(this, result);
// Move to the next step in the async test.
asyncTest.next();
}, 0);
} else {
aListener.onSearchResult(this, result);
}
},
stopSearch: function () {
clearTimeout(this.pendingSearch);
}
};
SimpleTest.waitForExplicitFinish();
// XPFE AutoComplete needs to register early.
autoCompleteSimple.registerFactory();
let gACTimer;
let gAutoComplete;
let asyncTest;
let searchCompleteTimeoutId = null;
function finishTest() {
// Unregister the factory so that we don't get in the way of other tests
autoCompleteSimple.unregisterFactory();
SimpleTest.finish();
}
function runTest() {
gAutoComplete = $("autocomplete");
gAutoComplete.focus();
// Return the search results synchronous, which also makes the completion
// happen synchronous.
autoCompleteSimple.searchAsync = false;
synthesizeKey("r", {});
is(gAutoComplete.value, "result", "Value should be autocompleted immediately");
synthesizeKey("e", {});
is(gAutoComplete.value, "result", "Value should be autocompleted immediately");
synthesizeKey("VK_DELETE", {});
is(gAutoComplete.value, "re", "Deletion should not complete value");
synthesizeKey("VK_BACK_SPACE", {});
is(gAutoComplete.value, "r", "Backspace should not complete value");
synthesizeKey("VK_LEFT", {});
is(gAutoComplete.value, "r", "Value should stay same when navigating with cursor");
runAsyncTest();
}
function* asyncTestGenerator() {
synthesizeKey("r", {});
synthesizeKey("e", {});
is(gAutoComplete.value, "re", "Value should not be autocompleted immediately");
// Calling |yield undefined| makes this generator function wait until
// |asyncTest.next();| is called. This happens from within the
// |autoCompleteSimple.startSearch()| function once the simulated async
// search has finished.
// Therefore, the effect of the |yield undefined;| here (and the ones) below
// is to wait until the async search result comes back.
yield undefined;
is(gAutoComplete.value, "result", "Value should be autocompleted");
// Test if typing the `s` character completes directly based on the last
// completion
synthesizeKey("s", {});
is(gAutoComplete.value, "result", "Value should be completed immediately");
yield undefined;
is(gAutoComplete.value, "result", "Value should be autocompleted to same value");
synthesizeKey("VK_DELETE", {});
is(gAutoComplete.value, "res", "Deletion should not complete value");
// No |yield undefined| needed here as no completion is triggered by the deletion.
is(gAutoComplete.value, "res", "Still no complete value after deletion");
synthesizeKey("VK_BACK_SPACE", {});
is(gAutoComplete.value, "re", "Backspace should not complete value");
yield undefined;
is(gAutoComplete.value, "re", "Value after search due to backspace should stay the same"); (3)
// Typing a character that is not like the previous match. In this case, the
// completion cannot happen directly and therefore the value will be completed
// only after the search has finished.
synthesizeKey("t", {});
is(gAutoComplete.value, "ret", "Value should not be autocompleted immediately");
yield undefined;
is(gAutoComplete.value, "retire", "Value should be autocompleted");
synthesizeKey("i", {});
is(gAutoComplete.value, "retire", "Value should be autocompleted immediately");
yield undefined;
is(gAutoComplete.value, "retire", "Value should be autocompleted to the same value");
// Setup the scene to test how the completion behaves once the placeholder
// completion and the result from the search do not agree with each other.
gAutoComplete.value = 'r';
// Need to type two characters as the input was reset and the autocomplete
// controller things, ther user hit the backspace button, in which case
// no completion is performed. But as a completion is desired, another
// character `t` is typed afterwards.
synthesizeKey("e", {});
yield undefined;
synthesizeKey("t", {});
is(gAutoComplete.value, "ret", "Value should not be autocompleted");
yield undefined;
is(gAutoComplete.value, "retire", "Value should be autocompleted");
// The placeholder string is now set to "retire". Changing the completion
// string to "retirement" and see what the completion will turn out like.
autoCompleteSimpleResult.retireCompletion = "Retirement";
synthesizeKey("i", {});
is(gAutoComplete.value, "retire", "Value should be autocompleted based on placeholder");
yield undefined;
is(gAutoComplete.value, "retirement", "Value should be autocompleted based on search result");
// Change the search result to `Retire` again and see if the new result is
// complited.
autoCompleteSimpleResult.retireCompletion = "Retire";
synthesizeKey("r", {});
is(gAutoComplete.value, "retirement", "Value should be autocompleted based on placeholder");
yield undefined;
is(gAutoComplete.value, "retire", "Value should be autocompleted based on search result");
// Complete the value
gAutoComplete.value = 're';
synthesizeKey("t", {});
yield undefined;
synthesizeKey("i", {});
is(gAutoComplete.value, "reti", "Value should not be autocompleted");
yield undefined;
is(gAutoComplete.value, "retire", "Value should be autocompleted");
// Remove the selected text "re" (1) and the "et" (2). Afterwards, add it again (3).
// This should not cause the completion to kick in.
synthesizeKey("VK_DELETE", {}); // (1)
is(gAutoComplete.value, "reti", "Value should not complete after deletion");
gAutoComplete.selectionStart = 1;
gAutoComplete.selectionEnd = 3;
synthesizeKey("VK_DELETE", {}); // (2)
is(gAutoComplete.value, "ri", "Value should stay unchanged after removing character in the middle");
yield undefined;
synthesizeKey("e", {}); // (3.1)
is(gAutoComplete.value, "rei", "Inserting a character in the middle should not complete the value");
yield undefined;
synthesizeKey("t", {}); // (3.2)
is(gAutoComplete.value, "reti", "Inserting a character in the middle should not complete the value");
yield undefined;
// Adding a new character at the end should not cause the completion to happen again
// as the completion failed before.
gAutoComplete.selectionStart = 4;
gAutoComplete.selectionEnd = 4;
synthesizeKey("r", {});
is(gAutoComplete.value, "retir", "Value should not be autocompleted immediately");
yield undefined;
is(gAutoComplete.value, "retire", "Value should be autocompleted");
finishTest();
yield undefined;
}
function runAsyncTest() {
gAutoComplete.value = '';
autoCompleteSimple.searchAsync = true;
asyncTest = asyncTestGenerator();
asyncTest.next();
}
]]>
</script>
<body xmlns="http://www.w3.org/1999/xhtml">
<p id="display">
</p>
<div id="content" style="display: none">
</div>
<pre id="test">
</pre>
</body>
</window>

View file

@ -1,64 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<title>autocomplete with composition tests on HTML input element</title>
<script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
<script type="text/javascript" src="file_autocomplete_with_composition.js"></script>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
</head>
<body>
<p id="display"></p>
<div id="content">
<iframe id="formTarget" name="formTarget"></iframe>
<form action="data:text/html," target="formTarget">
<input name="test" id="input"><input type="submit">
</form>
</div>
<pre id="test">
<script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
function runTests()
{
var formFillController =
SpecialPowers.getFormFillController()
.QueryInterface(Components.interfaces.nsIAutoCompleteInput);
var originalFormFillTimeout = formFillController.timeout;
SpecialPowers.attachFormFillControllerTo(window);
var target = document.getElementById("input");
// Register a word to the form history.
target.focus();
target.value = "Mozilla";
synthesizeKey("VK_RETURN", {});
target.value = "";
var test1 = new nsDoTestsForAutoCompleteWithComposition(
"Testing on HTML input (asynchronously search)",
window, target, formFillController.controller, is,
function () { return target.value; },
function () {
target.setAttribute("timeout", 0);
var test2 = new nsDoTestsForAutoCompleteWithComposition(
"Testing on HTML input (synchronously search)",
window, target, formFillController.controller, is,
function () { return target.value; },
function () {
formFillController.timeout = originalFormFillTimeout;
SpecialPowers.detachFormFillControllerFrom(window);
SimpleTest.finish();
});
});
}
SimpleTest.waitForFocus(runTests);
</script>
</pre>
</body>
</html>

View file

@ -1,124 +0,0 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
type="text/css"?>
<window title="Testing autocomplete with composition"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js" />
<script type="text/javascript"
src="file_autocomplete_with_composition.js" />
<textbox id="textbox" type="autocomplete"
autocompletesearch="simpleForComposition"/>
<body xmlns="http://www.w3.org/1999/xhtml">
<div id="content" style="display: none">
</div>
<pre id="test">
</pre>
</body>
<script class="testbody" type="application/javascript">
<![CDATA[
SimpleTest.waitForExplicitFinish();
const nsIAutoCompleteResult = Components.interfaces.nsIAutoCompleteResult;
// This result can't be constructed in-line, because otherwise we leak memory.
function nsAutoCompleteSimpleResult(aString)
{
this.searchString = aString;
if (aString == "" || aString == "Mozilla".substr(0, aString.length)) {
this.searchResult = nsIAutoCompleteResult.RESULT_SUCCESS;
this.matchCount = 1;
this._value = "Mozilla";
} else {
this.searchResult = nsIAutoCompleteResult.RESULT_NOMATCH;
this.matchCount = 0;
this._value = "";
}
}
nsAutoCompleteSimpleResult.prototype = {
_value: "",
searchString: null,
searchResult: nsIAutoCompleteResult.RESULT_FAILURE,
defaultIndex: 0,
errorDescription: null,
matchCount: 0,
getValueAt: function(aIndex) { return aIndex == 0 ? this._value : null; },
getCommentAt: function() { return null; },
getStyleAt: function() { return null; },
getImageAt: function() { return null; },
getFinalCompleteValueAt: function(aIndex) { return this.getValueAt(aIndex); },
getLabelAt: function() { return null; },
removeValueAt: function() {}
};
// A basic autocomplete implementation that either returns one result or none
var autoCompleteSimpleID =
Components.ID("0a2afbdb-f30e-47d1-9cb1-0cd160240aca");
var autoCompleteSimpleName =
"@mozilla.org/autocomplete/search;1?name=simpleForComposition"
var autoCompleteSimple = {
QueryInterface: function(iid) {
if (iid.equals(Components.interfaces.nsISupports) ||
iid.equals(Components.interfaces.nsIFactory) ||
iid.equals(Components.interfaces.nsIAutoCompleteSearch))
return this;
throw Components.results.NS_ERROR_NO_INTERFACE;
},
createInstance: function(outer, iid) {
return this.QueryInterface(iid);
},
startSearch: function(aString, aParam, aResult, aListener) {
var result = new nsAutoCompleteSimpleResult(aString);
aListener.onSearchResult(this, result);
},
stopSearch: function() {}
};
var componentManager =
Components.manager
.QueryInterface(Components.interfaces.nsIComponentRegistrar);
componentManager.registerFactory(autoCompleteSimpleID,
"Test Simple Autocomplete for composition",
autoCompleteSimpleName, autoCompleteSimple);
function runTests()
{
var target = document.getElementById("textbox");
target.setAttribute("timeout", 1);
var test1 = new nsDoTestsForAutoCompleteWithComposition(
"Testing on XUL textbox (asynchronously search)",
window, target, target.controller, is,
function () { return target.value; },
function () {
target.setAttribute("timeout", 0);
var test2 = new nsDoTestsForAutoCompleteWithComposition(
"Testing on XUL textbox (synchronously search)",
window, target, target.controller, is,
function () { return target.value; },
function () {
// Unregister the factory so that we don't get in the way of other
// tests
componentManager.unregisterFactory(autoCompleteSimpleID,
autoCompleteSimple);
SimpleTest.finish();
});
});
}
SimpleTest.waitForFocus(runTests);
]]>
</script>
</window>

View file

@ -1,38 +0,0 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
<window title="Browser Drop Test"
onload="setTimeout(runTest, 0);"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SpawnTask.js"/>
<script><![CDATA[
SimpleTest.waitForExplicitFinish();
function runTest() {
add_task(function*() {
let win = window.open("window_browser_drop.xul", "_blank", "chrome,width=200,height=200");
yield SimpleTest.promiseFocus(win);
for (let browserType of ["content", "remote-content"]) {
yield win.dropLinksOnBrowser(win.document.getElementById(browserType + "child"), browserType);
}
yield win.dropLinksOnBrowser(win.document.getElementById("chromechild"), "chrome");
});
}
//]]>
</script>
<body xmlns="http://www.w3.org/1999/xhtml">
<p id="display">
</p>
<div id="content" style="display: none">
</div>
<pre id="test">
</pre>
</body>
</window>

View file

@ -1,86 +0,0 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1048178
-->
<window title="Mozilla Bug 1048178"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/>
<!-- test results are displayed in the html:body -->
<body xmlns="http://www.w3.org/1999/xhtml"/>
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1048178"
target="_blank">Mozilla Bug 1048178</a>
<hbox>
<scrollbar id="scroller"
orient="horizontal"
curpos="0"
maxpos="500"
pageincrement="500"
width="500"
style="margin:0"/>
</hbox>
<!-- test code goes here -->
<script type="application/javascript"><![CDATA[
/** Test for Bug 1048178 **/
var scrollbarTester = {
scrollbar: null,
startTest: function() {
this.scrollbar = $("scroller");
this.setScrollToClick(false);
this.testThumbDragging();
SimpleTest.finish();
},
testThumbDragging: function() {
var x = 400; // on the right half of the scroolbar
var y = 5;
this.mousedown(x, y, 0);
this.mousedown(x, y, 2);
this.mouseup(x, y, 2);
this.mouseup(x, y, 0);
var newPos = this.getPos(); // sould be '500'
this.mousedown(x, y, 0);
this.mousemove(x-1, y, 0);
this.mouseup(x-1, y, 0);
var newPos2 = this.getPos();
ok(newPos2 < newPos,
"Scrollbar thumb should follow the mouse when dragged.");
},
setScrollToClick: function(value) {
var prefService = Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefService);
var uiBranch = prefService.getBranch("ui.");
uiBranch.setIntPref("scrollToClick", value ? 1 : 0);
},
getPos: function() {
return this.scrollbar.getAttribute("curpos");
},
mousedown: function(x, y, button) {
synthesizeMouse(this.scrollbar, x, y, { type: "mousedown", 'button': button });
},
mousemove: function(x, y, button) {
synthesizeMouse(this.scrollbar, x, y, { type: "mousemove", 'button': button });
},
mouseup: function(x, y, button) {
synthesizeMouse(this.scrollbar, x, y, { type: "mouseup", 'button': button });
}
}
function doTest() {
setTimeout(function() { scrollbarTester.startTest(); }, 0);
}
SimpleTest.waitForExplicitFinish();
addLoadEvent(doTest);
]]></script>
</window>

View file

@ -1,90 +0,0 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<?xml-stylesheet
href="chrome://mochikit/content/tests/SimpleTest/test.css"
type="text/css"?>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=253481
-->
<window title="Mozilla Bug 253481"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
<body xmlns="http://www.w3.org/1999/xhtml">
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=253481">Mozilla Bug 253481</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
</body>
<description>
Tests pasting of multi-line content into a single-line xul:textbox.
</description>
<vbox>
<textbox id="pasteintact" newlines="pasteintact"/>
<textbox id="pastetofirst" newlines="pastetofirst"/>
<textbox id="replacewithspaces" newlines="replacewithspaces"/>
<textbox id="strip" newlines="strip"/>
<textbox id="replacewithcommas" newlines="replacewithcommas"/>
<textbox id="stripsurroundingwhitespace" newlines="stripsurroundingwhitespace"/>
</vbox>
<script class="testbody" type="application/javascript;version=1.7">
<![CDATA[
/** Test for Bug 253481 **/
function testPaste(name, element, expected) {
element.value = "";
element.focus();
synthesizeKey("v", { accelKey: true });
is(element.value, expected, name);
}
SimpleTest.waitForExplicitFinish();
SimpleTest.waitForFocus(function() {
setTimeout(function() {
var testString = "\n hello hello \n world\nworld \n";
var expectedResults = {
// even "pasteintact" strips leading/trailing newlines
"pasteintact": testString.replace(/^\n/, '').replace(/\n$/, ''),
// "pastetofirst" strips leading newlines
"pastetofirst": testString.replace(/^\n/, '').split(/\n/)[0],
// "replacewithspaces" strips trailing newlines first - bug 432415
"replacewithspaces": testString.replace(/\n$/, '').replace(/\n/g,' '),
// "strip" is pretty straightforward
"strip": testString.replace(/\n/g,''),
// "replacewithcommas" strips leading and trailing newlines first
"replacewithcommas": testString.replace(/^\n/, '').replace(/\n$/, '').replace(/\n/g,','),
// "stripsurroundingwhitespace" strips all newlines and whitespace around them
"stripsurroundingwhitespace": testString.replace(/\s*\n\s*/g,'')
};
// Put a multi-line string in the clipboard
SimpleTest.waitForClipboard(testString, function() {
var clip = Components.classes["@mozilla.org/widget/clipboardhelper;1"]
.getService(Components.interfaces.nsIClipboardHelper);
clip.copyString(testString);
}, function() {
for (let [item, expected] of Object.entries(expectedResults)) {
testPaste(item, $(item), expected);
}
SimpleTest.finish();
}, function() {
ok(false, "Could not copy the string to clipboard, giving up");
SimpleTest.finish();
});
}, 0);
});
]]>
</script>
</window>

Some files were not shown because too many files have changed in this diff Show more