This commit is contained in:
Ryan VanderMeulen 2016-04-02 13:55:51 -04:00
Родитель 16087a904d 1bb567e688
Коммит 1144ba9c95
76 изменённых файлов: 844 добавлений и 490 удалений

Просмотреть файл

@ -347,6 +347,7 @@ skip-if = os == "linux" # Linux: Intermittent failures, bug 917535
skip-if = os != "win" # The Fitts Law menu button is only supported on Windows (bug 969376)
[browser_middleMouse_noJSPaste.js]
[browser_minimize.js]
[browser_misused_characters_in_strings.js]
[browser_mixedcontent_securityflags.js]
tags = mcb
[browser_offlineQuotaNotification.js]

Просмотреть файл

@ -0,0 +1,147 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
/* This list allows pre-existing or 'unfixable' issues to remain, while we
* detect newly occurring issues in shipping files. It is a list of objects
* specifying conditions under which an error should be ignored.
*
* As each issue is found in the whitelist, it is removed from the list. At
* the end of the test, there is an assertion that all items have been
* removed from the whitelist, thus ensuring there are no stale entries. */
let gWhitelist = [{
file: "search.properties",
key: "searchForSomethingWith",
type: "single-quote"
}, {
file: "aboutCertError.dtd",
key: "certerror.introPara",
type: "single-quote"
}, {
file: "browser.dtd",
key: "social.activated.description",
type: "single-quote"
}, {
file: "netError.dtd",
key: "weakCryptoAdvanced.longDesc",
type: "single-quote"
}, {
file: "netError.dtd",
key: "weakCryptoAdvanced.override",
type: "single-quote"
}, {
file: "phishing-afterload-warning-message.dtd",
key: "safeb.blocked.malwarePage.shortDesc",
type: "single-quote"
}, {
file: "phishing-afterload-warning-message.dtd",
key: "safeb.blocked.unwantedPage.shortDesc",
type: "single-quote"
}, {
file: "phishing-afterload-warning-message.dtd",
key: "safeb.blocked.phishingPage.shortDesc2",
type: "single-quote"
}, {
file: "phishing-afterload-warning-message.dtd",
key: "safeb.blocked.forbiddenPage.shortDesc2",
type: "single-quote"
}
];
var moduleLocation = gTestPath.replace(/\/[^\/]*$/i, "/parsingTestHelpers.jsm");
var {generateURIsFromDirTree} = Cu.import(moduleLocation, {});
/**
* Check if an error should be ignored due to matching one of the whitelist
* objects defined in gWhitelist.
*
* @param filepath The URI spec of the locale file
* @param key The key of the entity that is being checked
* @param type The type of error that has been found
* @return true if the error should be ignored, false otherwise.
*/
function ignoredError(filepath, key, type) {
for (let index in gWhitelist) {
let whitelistItem = gWhitelist[index];
if (filepath.endsWith(whitelistItem.file) &&
key == whitelistItem.key &&
type == whitelistItem.type) {
gWhitelist.splice(index, 1);
return true;
}
}
return false;
}
function fetchFile(uri) {
return new Promise((resolve, reject) => {
let xhr = new XMLHttpRequest();
xhr.open("GET", uri, true);
xhr.onreadystatechange = function() {
if (this.readyState != this.DONE) {
return;
}
try {
resolve(this.responseText);
} catch (ex) {
ok(false, `Script error reading ${uri}: ${ex}`);
resolve("");
}
};
xhr.onerror = error => {
ok(false, `XHR error reading ${uri}: ${error}`);
resolve("");
};
xhr.send(null);
});
}
function testForError(filepath, key, str, pattern, type, helpText) {
if (str.match(pattern) &&
!ignoredError(filepath, key, type)) {
ok(false, `${filepath} with key=${key} has a misused ${type}. ${helpText}`);
}
}
function testForErrors(filepath, key, str) {
testForError(filepath, key, str, /\w'\w/, "apostrophe", "Strings with apostrophes should use foo\u2019s instead of foo's.");
testForError(filepath, key, str, /\w\u2018\w/, "incorrect-apostrophe", "Strings with apostrophes should use foo\u2019s instead of foo\u2018s.");
testForError(filepath, key, str, /'.+'/, "single-quote", "Single-quoted strings should use Unicode \u2018foo\u2019 instead of 'foo'.");
testForError(filepath, key, str, /"/, "double-quote", "Double-quoted strings should use Unicode \u201cfoo\u201d instead of \"foo\".");
testForError(filepath, key, str, /\.\.\./, "ellipsis", "Strings with an ellipsis should use the Unicode \u2026 character instead of three periods.");
}
add_task(function* checkAllTheProperties() {
let appDir = Services.dirsvc.get("XCurProcD", Ci.nsIFile);
// This asynchronously produces a list of URLs (sadly, mostly sync on our
// test infrastructure because it runs against jarfiles there, and
// our zipreader APIs are all sync)
let uris = yield generateURIsFromDirTree(appDir, [".properties"]);
ok(uris.length, `Found ${uris.length} .properties files to scan for misused characters`);
for (let uri of uris) {
let bundle = new StringBundle(uri.spec);
let entities = bundle.getAll();
for (let entity of entities) {
testForErrors(uri.spec, entity.key, entity.value);
}
}
});
add_task(function* checkAllTheDTDs() {
let appDir = Services.dirsvc.get("XCurProcD", Ci.nsIFile);
let uris = yield generateURIsFromDirTree(appDir, [".dtd"]);
ok(uris.length, `Found ${uris.length} .dtd files to scan for misused characters`);
for (let uri of uris) {
let rawContents = yield fetchFile(uri.spec);
let entities = rawContents.match(/ENTITY\s+([\w\.]*)\s+["'](.*)["']/g);
for (let entity of entities) {
let [, key, str] = entity.match(/ENTITY\s+([\w\.]*)\s+["'](.*)["']/);
testForErrors(uri.spec, key, str);
}
}
});
add_task(function* ensureWhiteListIsEmpty() {
is(gWhitelist.length, 0, "No remaining whitelist entries exist");
});

Просмотреть файл

@ -65,6 +65,7 @@ function closeGlobalTab() {
win.BrowserOpenTab();
}
win.gBrowser.removeTab(gTab);
gTab = null;
}
function unregisterGlobalTab() {
@ -210,7 +211,10 @@ CustomizeMode.prototype = {
return;
}
if (!gTab.selected) {
// This will force another .enter() to be called via the
// onlocationchange handler of the tabbrowser, so we return early.
gTab.ownerGlobal.gBrowser.selectedTab = gTab;
return;
}
gTab.ownerGlobal.focus();
if (gTab.ownerDocument != this.document) {

Просмотреть файл

@ -147,3 +147,4 @@ skip-if = os == "mac"
[browser_bootstrapped_custom_toolbar.js]
[browser_customizemode_contextmenu_menubuttonstate.js]
[browser_panel_toggle.js]
[browser_switch_to_customize_mode.js]

Просмотреть файл

@ -0,0 +1,34 @@
"use strict";
add_task(function*() {
yield startCustomizing();
is(gBrowser.tabs.length, 2, "Should have 2 tabs");
let paletteKidCount = document.getElementById("customization-palette").childElementCount;
let nonCustomizingTab = gBrowser.tabContainer.querySelector("tab:not([customizemode=true])");
let finishedCustomizing = BrowserTestUtils.waitForEvent(gNavToolbox, "aftercustomization");
yield BrowserTestUtils.switchTab(gBrowser, nonCustomizingTab);
yield finishedCustomizing;
let startedCount = 0;
let handler = e => startedCount++;
gNavToolbox.addEventListener("customizationstarting", handler);
yield startCustomizing();
CustomizableUI.removeWidgetFromArea("home-button");
yield gCustomizeMode.reset().catch(e => {
ok(false, "Threw an exception trying to reset after making modifications in customize mode: " + e);
});
let newKidCount = document.getElementById("customization-palette").childElementCount;
is(newKidCount, paletteKidCount, "Should have just as many items in the palette as before.");
yield endCustomizing();
is(startedCount, 1, "Should have only started once");
gNavToolbox.removeEventListener("customizationstarting", handler);
let customizableToolbars = document.querySelectorAll("toolbar[customizable=true]:not([autohide=true])");
for (let toolbar of customizableToolbars) {
ok(!toolbar.hasAttribute("customizing"), "Toolbar " + toolbar.id + " is no longer customizing");
}
let menuitem = document.getElementById("PanelUI-customize");
isnot(menuitem.getAttribute("label"), menuitem.getAttribute("exitLabel"), "Should have exited successfully");
});

Просмотреть файл

@ -191,27 +191,7 @@ function endCustomizing(aWindow=window) {
aWindow.gNavToolbox.addEventListener("aftercustomization", onCustomizationEnds);
aWindow.gCustomizeMode.exit();
return deferredEndCustomizing.promise.then(function() {
let deferredLoadNewTab = Promise.defer();
//XXXgijs so some tests depend on this tab being about:blank. Make it so.
let newTabBrowser = aWindow.gBrowser.selectedBrowser;
newTabBrowser.stop();
// If we stop early enough, this might actually be about:blank.
if (newTabBrowser.currentURI.spec == "about:blank") {
return null;
}
// Otherwise, make it be about:blank, and wait for that to be done.
function onNewTabLoaded(e) {
newTabBrowser.removeEventListener("load", onNewTabLoaded, true);
deferredLoadNewTab.resolve();
}
newTabBrowser.addEventListener("load", onNewTabLoaded, true);
newTabBrowser.loadURI("about:blank");
return deferredLoadNewTab.promise;
});
return deferredEndCustomizing.promise;
}
function startCustomizing(aWindow=window) {

Просмотреть файл

@ -710,8 +710,12 @@ function getTypedURLs(registryKeyPath) {
} catch (ex) {
Cu.reportError("Error reading typed URL history: " + ex);
} finally {
typedURLKey.close();
typedURLTimeKey.close();
if (typedURLKey) {
typedURLKey.close();
}
if (typedURLTimeKey) {
typedURLTimeKey.close();
}
cTypes.finalize();
}
return typedURLs;

Просмотреть файл

@ -1794,7 +1794,7 @@ BrowserGlue.prototype = {
},
_migrateUI: function BG__migrateUI() {
const UI_VERSION = 36;
const UI_VERSION = 37;
const BROWSER_DOCURL = "chrome://browser/content/browser.xul";
let currentUIVersion;
@ -2156,6 +2156,10 @@ BrowserGlue.prototype = {
"hidden");
}
if (currentUIVersion < 37) {
Services.prefs.clearUserPref("browser.sessionstore.restore_on_demand");
}
// Update the migration version.
Services.prefs.setIntPref("browser.migration.version", UI_VERSION);
},

Просмотреть файл

@ -374,11 +374,14 @@ var gSyncPane = {
return fxAccounts.getSignedInUserProfile();
}
}).then(data => {
let fxaLoginStatus = document.getElementById("fxaLoginStatus");
if (data && profileInfoEnabled) {
if (data.displayName) {
fxaEmailAddress1Label.hidden = true;
fxaLoginStatus.setAttribute("hasName", true);
displayNameLabel.hidden = false;
displayNameLabel.textContent = data.displayName;
} else {
fxaLoginStatus.removeAttribute("hasName");
}
if (data.avatar) {
let bgImage = "url(\"" + data.avatar + "\")";
@ -395,6 +398,8 @@ var gSyncPane = {
};
img.src = data.avatar;
}
} else {
fxaLoginStatus.removeAttribute("hasName");
}
}, err => {
FxAccountsCommon.log.error(err);

Просмотреть файл

@ -233,16 +233,16 @@
<!-- logged in and verified and all is good -->
<hbox id="fxaLoginVerified" class="fxaAccountBox">
<vbox>
<vbox align="center" pack="center">
<image id="fxaProfileImage" class="actionable"
role="button"
onclick="gSyncPane.openChangeProfileImage(event);" hidden="true"
onkeypress="gSyncPane.openChangeProfileImage(event);"
tooltiptext="&profilePicture.tooltip;"/>
</vbox>
<vbox flex="1">
<label id="fxaEmailAddress1"/>
<vbox flex="1" pack="center">
<label id="fxaDisplayName" hidden="true"/>
<label id="fxaEmailAddress1"/>
<hbox class="fxaAccountBoxButtons" align="center">
<button id="fxaUnlinkButton" label="&disconnect.label;"/>
<label id="verifiedManage" class="text-link"

Просмотреть файл

@ -76,7 +76,7 @@ add_task(function* () {
info("checkContextMenu");
var searchItem = contextMenu.getElementsByAttribute("id", "context-searchselect")[0];
ok(searchItem, "Got search context menu item");
is(searchItem.label, 'Search ' + ENGINE_NAME + ' for "test search"', "Check context menu label");
is(searchItem.label, 'Search ' + ENGINE_NAME + ' for \u201ctest search\u201d', "Check context menu label");
is(searchItem.disabled, false, "Check that search context menu item is enabled");
yield BrowserTestUtils.openNewForegroundTab(gBrowser, () => {

Просмотреть файл

@ -50,6 +50,9 @@
#include <mbstring.h>
#include <shlwapi.h>
#include <lm.h>
#undef ACCESS_READ
#ifndef MAX_BUF
#define MAX_BUF 4096
#endif
@ -642,9 +645,96 @@ nsWindowsShellService::LaunchControlPanelDefaultsSelectionUI()
return SUCCEEDED(hr) ? NS_OK : NS_ERROR_FAILURE;
}
nsresult
nsWindowsShellService::LaunchControlPanelDefaultPrograms()
{
// Default Programs is a Vista+ feature
if (!IsVistaOrLater()) {
return NS_ERROR_FAILURE;
}
// Build the path control.exe path safely
WCHAR controlEXEPath[MAX_PATH + 1] = { '\0' };
if (!GetSystemDirectoryW(controlEXEPath, MAX_PATH)) {
return NS_ERROR_FAILURE;
}
LPCWSTR controlEXE = L"control.exe";
if (wcslen(controlEXEPath) + wcslen(controlEXE) >= MAX_PATH) {
return NS_ERROR_FAILURE;
}
if (!PathAppendW(controlEXEPath, controlEXE)) {
return NS_ERROR_FAILURE;
}
WCHAR params[] = L"control.exe /name Microsoft.DefaultPrograms /page pageDefaultProgram";
STARTUPINFOW si = {sizeof(si), 0};
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = SW_SHOWDEFAULT;
PROCESS_INFORMATION pi = {0};
if (!CreateProcessW(controlEXEPath, params, nullptr, nullptr, FALSE,
0, nullptr, nullptr, &si, &pi)) {
return NS_ERROR_FAILURE;
}
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return NS_OK;
}
static bool
IsWindowsLogonConnected()
{
WCHAR userName[UNLEN + 1];
DWORD size = ArrayLength(userName);
if (!GetUserNameW(userName, &size)) {
return false;
}
LPUSER_INFO_24 info;
if (NetUserGetInfo(nullptr, userName, 24, (LPBYTE *)&info)
!= NERR_Success) {
return false;
}
bool connected = info->usri24_internet_identity;
NetApiBufferFree(info);
return connected;
}
static bool
SettingsAppBelievesConnected()
{
nsresult rv;
nsCOMPtr<nsIWindowsRegKey> regKey =
do_CreateInstance("@mozilla.org/windows-registry-key;1", &rv);
if (NS_FAILED(rv)) {
return false;
}
rv = regKey->Open(nsIWindowsRegKey::ROOT_KEY_CURRENT_USER,
NS_LITERAL_STRING("SOFTWARE\\Microsoft\\Windows\\Shell\\Associations"),
nsIWindowsRegKey::ACCESS_READ);
if (NS_FAILED(rv)) {
return false;
}
uint32_t value;
rv = regKey->ReadIntValue(NS_LITERAL_STRING("IsConnectedAtLogon"), &value);
if (NS_FAILED(rv)) {
return false;
}
return !!value;
}
nsresult
nsWindowsShellService::LaunchModernSettingsDialogDefaultApps()
{
if (!IsWindowsLogonConnected() && SettingsAppBelievesConnected()) {
// Use the classic Control Panel to work around a bug of Windows 10.
return LaunchControlPanelDefaultPrograms();
}
IApplicationActivationManager* pActivator;
HRESULT hr = CoCreateInstance(CLSID_ApplicationActivationManager,
nullptr,

Просмотреть файл

@ -28,6 +28,7 @@ public:
protected:
bool IsDefaultBrowserVista(bool aCheckAllTypes, bool* aIsDefaultBrowser);
nsresult LaunchControlPanelDefaultsSelectionUI();
nsresult LaunchControlPanelDefaultPrograms();
nsresult LaunchModernSettingsDialogDefaultApps();
nsresult InvokeHTTPOpenAsVerb();
nsresult LaunchHTTPHandlerPane();

Просмотреть файл

@ -156,7 +156,7 @@ call_timeout_notification_text=Your call did not go through.
cancel_button=Cancel
rejoin_button=Rejoin Conversation
cannot_start_call_session_not_ready=Can't start call, session is not ready.
cannot_start_call_session_not_ready=Cant start call, session is not ready.
network_disconnected=The network connection terminated abruptly.
connection_error_see_console_notification=Call failed; see console for details.
no_media_failure_message=No camera or microphone found.
@ -194,7 +194,7 @@ room_name_untitled_page=Untitled Page
## LOCALIZATION NOTE (door_hanger_return, door_hanger_prompt_name, door_hanger_button): Dialog message on leaving conversation
door_hanger_return=See you later! You can return to this shared session at any time through the Hello panel.
door_hanger_prompt_name=Would you like to give it a name that's easier to remember? Current name:
door_hanger_prompt_name=Would you like to give it a name thats easier to remember? Current name:
door_hanger_button=OK
# Infobar strings
@ -213,7 +213,7 @@ infobar_button_disconnect_accesskey=D
# E10s not supported strings
e10s_not_supported_button_label=Launch New Window
e10s_not_supported_subheading={{brandShortname}} doesn't work in a multi-process window.
e10s_not_supported_subheading={{brandShortname}} doesnt work in a multi-process window.
# 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/.
@ -228,7 +228,7 @@ chat_textbox_placeholder=Type here…
clientShortname2=Firefox Hello
conversation_has_ended=Your conversation has ended.
generic_failure_message=We're having technical difficulties…
generic_failure_message=Were having technical difficulties…
generic_failure_no_reason2=Would you like to try again?

10
browser/extensions/pocket/bootstrap.js поставляемый
Просмотреть файл

@ -383,12 +383,8 @@ var PocketOverlay = {
CreatePocketWidget(reason);
PocketContextMenu.init();
if (reason != APP_STARTUP) {
for (let win of allBrowserWindows()) {
this.setWindowScripts(win);
this.addStyles(win);
this.updateWindow(win);
}
for (let win of allBrowserWindows()) {
this.onWindowOpened(win);
}
},
shutdown: function(reason) {
@ -414,6 +410,8 @@ var PocketOverlay = {
PocketReader.shutdown();
},
onWindowOpened: function(window) {
if (window.hasOwnProperty("pktUI"))
return;
this.setWindowScripts(window);
this.addStyles(window);
this.updateWindow(window);

Просмотреть файл

@ -1 +1,6 @@
[DEFAULT]
support-files =
head.js
test.html
[browser_pocket_ui_check.js]

Просмотреть файл

@ -1,21 +1,54 @@
"use strict";
add_task(function*() {
let pocketAddon = yield new Promise(resolve => {
AddonManager.getAddonByID("firefox@getpocket.com", resolve);
});
if (!pocketAddon) {
ok(true, "Pocket is not installed");
return;
function checkWindowProperties(expectPresent, l) {
for (let name of l) {
is(!!window.hasOwnProperty(name), expectPresent, "property " + name + (expectPresent ? " is" : " is not") + " present");
}
if (!Services.prefs.getBoolPref("extensions.pocket.enabled")) {
ok(true, "Pocket add-on is not enabled");
return;
}
function checkElements(expectPresent, l) {
for (let id of l) {
is(!!document.getElementById(id), expectPresent, "element " + id + (expectPresent ? " is" : " is not") + " present");
}
}
for (let id of ["panelMenu_pocket", "menu_pocket", "BMB_pocket",
"panelMenu_pocketSeparator", "menu_pocketSeparator",
"BMB_pocketSeparator"]) {
ok(document.getElementById(id), "Should see element with id " + id);
}
add_task(function*() {
let enabledOnStartup = yield promisePocketEnabled();
registerCleanupFunction(() => {
// Extra insurance that this is disabled again, but it should have been set
// in promisePocketReset.
Services.prefs.setBoolPref("extensions.pocket.enabled", enabledOnStartup);
});
checkWindowProperties(true, ["Pocket", "pktUI", "pktUIMessaging"]);
checkElements(true, ["pocket-button", "panelMenu_pocket", "menu_pocket", "BMB_pocket",
"panelMenu_pocketSeparator", "menu_pocketSeparator",
"BMB_pocketSeparator"]);
// check context menu exists
info("checking content context menu");
let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "https://example.com/browser/browser/extensions/pocket/test/test.html");
let contextMenu = document.getElementById("contentAreaContextMenu");
let popupShown = BrowserTestUtils.waitForEvent(contextMenu, "popupshown");
let popupHidden = BrowserTestUtils.waitForEvent(contextMenu, "popuphidden");
yield BrowserTestUtils.synthesizeMouseAtCenter("body", {
type: "contextmenu",
button: 2
}, tab.linkedBrowser);
yield popupShown;
checkElements(true, ["context-pocket", "context-savelinktopocket"]);
contextMenu.hidePopup();
yield popupHidden;
yield BrowserTestUtils.removeTab(tab);
yield promisePocketDisabled();
checkWindowProperties(false, ["Pocket", "pktUI", "pktUIMessaging"]);
checkElements(false, ["pocket-button", "panelMenu_pocket", "menu_pocket", "BMB_pocket",
"panelMenu_pocketSeparator", "menu_pocketSeparator",
"BMB_pocketSeparator", "context-pocket", "context-savelinktopocket"]);
yield promisePocketReset();
});

Просмотреть файл

@ -0,0 +1,68 @@
// Currently Pocket is disabled in tests. We want these tests to work under
// either case that Pocket is disabled or enabled on startup of the browser,
// and that at the end we're reset to the correct state.
let enabledOnStartup = false;
// PocketEnabled/Disabled promises return true if it was already
// Enabled/Disabled, and false if it need to Enable/Disable.
function promisePocketEnabled() {
if (Services.prefs.getPrefType("extensions.pocket.enabled") != Services.prefs.PREF_INVALID &&
Services.prefs.getBoolPref("extensions.pocket.enabled")) {
info( "pocket was already enabled, assuming enabled by default for tests");
enabledOnStartup = true;
return Promise.resolve(true);
}
info( "pocket is not enabled");
return new Promise((resolve, reject) => {
let listener = {
onWidgetAfterCreation(widgetid) {
if (widgetid == "pocket-button") {
info("pocket-button created");
CustomizableUI.removeListener(listener);
resolve(false);
}
}
}
CustomizableUI.addListener(listener);
Services.prefs.setBoolPref("extensions.pocket.enabled", true);
});
}
function promisePocketDisabled() {
if (Services.prefs.getPrefType("extensions.pocket.enabled") == Services.prefs.PREF_INVALID ||
!Services.prefs.getBoolPref("extensions.pocket.enabled")) {
info("pocket-button already disabled");
return Promise.resolve(true);
}
return new Promise((resolve, reject) => {
let listener = {
onWidgetDestroyed: function(widgetid) {
if (widgetid == "pocket-button") {
CustomizableUI.removeListener(listener);
info( "pocket-button destroyed");
// wait for a full unload of pocket
BrowserTestUtils.waitForCondition(() => {
return !window.hasOwnProperty("pktUI");
}, "pocket properties removed from window").then(() => {
resolve(false);
})
}
}
}
CustomizableUI.addListener(listener);
info("reset pocket enabled pref");
// testing/profiles/prefs_general.js uses user_pref to disable pocket, set
// back to false.
Services.prefs.setBoolPref("extensions.pocket.enabled", false);
});
}
function promisePocketReset() {
if (enabledOnStartup) {
info("reset is enabling pocket addon");
return promisePocketEnabled();
} else {
info("reset is disabling pocket addon");
return promisePocketDisabled();
}
}

Просмотреть файл

@ -0,0 +1,11 @@
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
<meta charset="utf-8" />
</head>
<body>
</body>
</html>

Просмотреть файл

@ -12,7 +12,7 @@ droponhomemsg=Do you want this document to be your new home page?
# LOCALIZATION NOTE (contextMenuSearch): %1$S is the search engine,
# %2$S is the selection string.
contextMenuSearch=Search %1$S for "%2$S"
contextMenuSearch=Search %1$S for “%2$S”
contextMenuSearch.accesskey=S
# bookmark dialog strings
@ -135,7 +135,7 @@ popupAllow=Allow pop-ups for %S
popupBlock=Block pop-ups for %S
popupWarningDontShowFromMessage=Dont show this message when pop-ups are blocked
popupWarningDontShowFromLocationbar=Dont show info bar when pop-ups are blocked
popupShowPopupPrefix=Show '%S'
popupShowPopupPrefix=Show %S
# Bad Content Blocker Doorhanger Notification
# %S is brandShortName
@ -164,30 +164,30 @@ keywordURIFixup.dismiss.accesskey=N
# LOCALIZATION NOTE (pluginActivateNew.message): Used for newly-installed
# plugins which are not known to be unsafe. %1$S is the plugin name and %2$S
# is the site domain.
pluginActivateNew.message=Allow %2$S to run "%1$S"?
pluginActivateNew.message=Allow %2$S to run “%1$S”?
pluginActivateMultiple.message=Allow %S to run plugins?
pluginActivate.learnMore=Learn More…
# LOCALIZATION NOTE (pluginActivateOutdated.message, pluginActivateOutdated.label):
# These strings are used when an unsafe plugin has an update available.
# %1$S is the plugin name, %2$S is the domain, and %3$S is brandShortName.
pluginActivateOutdated.message=%3$S has prevented the outdated plugin "%1$S" from running on %2$S.
pluginActivateOutdated.message=%3$S has prevented the outdated plugin “%1$S” from running on %2$S.
pluginActivateOutdated.label=Outdated plugin
pluginActivate.updateLabel=Update now…
# LOCALIZATION NOTE (pluginActivateVulnerable.message, pluginActivateVulnerable.label):
# These strings are used when an unsafe plugin has no update available.
# %1$S is the plugin name, %2$S is the domain, and %3$S is brandShortName.
pluginActivateVulnerable.message=%3$S has prevented the unsafe plugin "%1$S" from running on %2$S.
pluginActivateVulnerable.message=%3$S has prevented the unsafe plugin “%1$S” from running on %2$S.
pluginActivateVulnerable.label=Vulnerable plugin!
pluginActivate.riskLabel=Whats the risk?
# LOCALIZATION NOTE (pluginActivateBlocked.message): %1$S is the plugin name, %2$S is brandShortName
pluginActivateBlocked.message=%2$S has blocked "%1$S" for your protection.
pluginActivateBlocked.message=%2$S has blocked “%1$S” for your protection.
pluginActivateBlocked.label=Blocked for your protection
pluginActivateDisabled.message="%S" is disabled.
pluginActivateDisabled.message=“%S” is disabled.
pluginActivateDisabled.label=Disabled
pluginActivateDisabled.manage=Manage plugins…
pluginEnabled.message="%S" is enabled on %S.
pluginEnabledOutdated.message=Outdated plugin "%S" is enabled on %S.
pluginEnabledVulnerable.message=Insecure plugin "%S" is enabled on %S.
pluginEnabled.message=“%S” is enabled on %S.
pluginEnabledOutdated.message=Outdated plugin “%S” is enabled on %S.
pluginEnabledVulnerable.message=Insecure plugin “%S” is enabled on %S.
pluginInfo.unknownPlugin=Unknown
# LOCALIZATION NOTE (pluginActivateNow.label, pluginActivateAlways.label, pluginBlockNow.label): These should be the same as the matching strings in browser.dtd

Просмотреть файл

@ -94,7 +94,7 @@ shortTimeLeftDays=%1$Sd
statusSeparator=%1$S \u2014 %2$S
statusSeparatorBeforeNumber=%1$S \u2014 %2$S
fileExecutableSecurityWarning="%S" is an executable file. Executable files may contain viruses or other malicious code that could harm your computer. Use caution when opening this file. Are you sure you want to launch "%S"?
fileExecutableSecurityWarning=“%S” is an executable file. Executable files may contain viruses or other malicious code that could harm your computer. Use caution when opening this file. Are you sure you want to launch “%S”?
fileExecutableSecurityWarningTitle=Open Executable File?
fileExecutableSecurityWarningDontAsk=Dont ask me this again

Просмотреть файл

@ -3,5 +3,5 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
duplicateTitle=Duplicate Keyword
duplicateEngineMsg=You have chosen a keyword that is currently in use by "%S". Please select another.
duplicateEngineMsg=You have chosen a keyword that is currently in use by “%S”. Please select another.
duplicateBookmarkMsg=You have chosen a keyword that is currently in use by a bookmark. Please select another.

Просмотреть файл

@ -3,10 +3,10 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
linkTitleTextFormat=Go to %S
addHandler=Add "%S" (%S) as a Feed Reader?
addHandler=Add “%S” (%S) as a Feed Reader?
addHandlerAddButton=Add Feed Reader
addHandlerAddButtonAccesskey=A
handlerRegistered="%S" is already registered as a Feed Reader
handlerRegistered=“%S” is already registered as a Feed Reader
liveBookmarks=Live Bookmarks
subscribeNow=Subscribe Now
chooseApplicationMenuItem=Choose Application…
@ -37,9 +37,9 @@ subscribeFeedUsing=Subscribe to this feed using
subscribeAudioPodcastUsing=Subscribe to this podcast using
subscribeVideoPodcastUsing=Subscribe to this video podcast using
feedSubscriptionFeed1=This is a "feed" of frequently changing content on this site.
feedSubscriptionAudioPodcast1=This is a "podcast" of frequently changing content on this site.
feedSubscriptionVideoPodcast1=This is a "video podcast" of frequently changing content on this site.
feedSubscriptionFeed1=This is a “feed” of frequently changing content on this site.
feedSubscriptionAudioPodcast1=This is a “podcast” of frequently changing content on this site.
feedSubscriptionVideoPodcast1=This is a “video podcast” of frequently changing content on this site.
feedSubscriptionFeed2=You can subscribe to this feed to receive updates when this content changes.
feedSubscriptionAudioPodcast2=You can subscribe to this podcast to receive updates when this content changes.

Просмотреть файл

@ -11,7 +11,7 @@ dialogTitleAddBookmark=New Bookmark
dialogTitleAddLivemark=Subscribe with Live Bookmark
dialogTitleAddFolder=New Folder
dialogTitleAddMulti=New Bookmarks
dialogTitleEdit=Properties for "%S"
dialogTitleEdit=Properties for “%S”
bookmarkAllTabsDefault=[Folder Name]
newFolderDefault=New Folder

Просмотреть файл

@ -20,9 +20,9 @@ bookmarksRestoreParseError=Unable to process the backup file.
bookmarksLivemarkLoading=Live Bookmark loading…
bookmarksLivemarkFailed=Live Bookmark feed failed to load.
menuOpenLivemarkOrigin.label=Open "%S"
menuOpenLivemarkOrigin.label=Open “%S”
sortByName=Sort '%S' by Name
sortByName=Sort %S by Name
sortByNameGeneric=Sort by Name
# LOCALIZATION NOTE (view.sortBy.1.name.label): sortBy properties are versioned.
# When any of these changes, all of the properties must be bumped, and the

Просмотреть файл

@ -26,7 +26,7 @@ cmd_showSuggestions_accesskey=S
# LOCALIZATION NOTE (cmd_addFoundEngine): %S is replaced by the name of
# a search engine offered by a web page. Each engine is displayed as a
# menuitem at the bottom of the search panel.
cmd_addFoundEngine=Add "%S"
cmd_addFoundEngine=Add “%S”
# LOCALIZATION NOTE (cmd_addFoundEngineMenu): When more than 5 engines
# are offered by a web page, instead of listing all of them in the
# search panel using the cmd_addFoundEngine string, they will be

Просмотреть файл

@ -23,12 +23,12 @@ webrtcIndicator.sharingBrowser.tooltip = A tab is being shared. Click to control
# LOCALIZATION NOTE (webrtcIndicator.sharing*With.menuitem):
# %S is the title of the tab using the share.
webrtcIndicator.sharingCameraWith.menuitem = Sharing Camera with "%S"
webrtcIndicator.sharingMicrophoneWith.menuitem = Sharing Microphone with "%S"
webrtcIndicator.sharingApplicationWith.menuitem = Sharing an Application with "%S"
webrtcIndicator.sharingScreenWith.menuitem = Sharing Screen with "%S"
webrtcIndicator.sharingWindowWith.menuitem = Sharing a Window with "%S"
webrtcIndicator.sharingBrowserWith.menuitem = Sharing a Tab with "%S"
webrtcIndicator.sharingCameraWith.menuitem = Sharing Camera with “%S”
webrtcIndicator.sharingMicrophoneWith.menuitem = Sharing Microphone with “%S”
webrtcIndicator.sharingApplicationWith.menuitem = Sharing an Application with “%S”
webrtcIndicator.sharingScreenWith.menuitem = Sharing Screen with “%S”
webrtcIndicator.sharingWindowWith.menuitem = Sharing a Window with “%S”
webrtcIndicator.sharingBrowserWith.menuitem = Sharing a Tab with “%S”
webrtcIndicator.controlSharing.menuitem = Control Sharing
# LOCALIZATION NOTE (webrtcIndicator.sharingCameraWithNTabs.menuitem):
# Semicolon-separated list of plural forms. See:
@ -58,4 +58,4 @@ webrtcIndicator.sharingWindowWithNTabs.menuitem = Sharing a Window with #1 tab;S
webrtcIndicator.sharingBrowserWithNTabs.menuitem = Sharing a Tab with #1 tab;Sharing Tabs with #1 tabs
# LOCALIZATION NOTE (webrtcIndicator.controlSharingOn.menuitem):
# %S is the title of the tab using the share.
webrtcIndicator.controlSharingOn.menuitem = Control Sharing on "%S"
webrtcIndicator.controlSharingOn.menuitem = Control Sharing on “%S”

Просмотреть файл

@ -170,4 +170,4 @@ password_cancel=Cancel
printing_not_supported=Warning: Printing is not fully supported by this browser.
printing_not_ready=Warning: The PDF is not fully loaded for printing.
web_fonts_disabled=Web fonts are disabled: unable to use embedded PDF fonts.
document_colors_not_allowed=PDF documents are not allowed to use their own colors: 'Allow pages to choose their own colors' is deactivated in the browser.
document_colors_not_allowed=PDF documents are not allowed to use their own colors: “Allow pages to choose their own colors” is deactivated in the browser.

Просмотреть файл

@ -825,7 +825,7 @@ toolbarpaletteitem[place="palette"] > toolbaritem > toolbarbutton {
}
#PanelUI-footer-fxa[fxaprofileimage="enabled"] > #PanelUI-fxa-status > #PanelUI-fxa-avatar {
list-style-image: url(chrome://browser/skin/fxa/default-avatar.png)
list-style-image: url(chrome://browser/skin/fxa/default-avatar.svg);
}
#PanelUI-customize:hover,
@ -1618,10 +1618,6 @@ menuitem[checked="true"].subviewbutton > .menu-iconic-left {
list-style-image: url(chrome://branding/content/icon32.png);
}
#PanelUI-footer-fxa[fxaprofileimage="enabled"] > #PanelUI-fxa-status > #PanelUI-fxa-avatar {
list-style-image: url(chrome://browser/skin/fxa/default-avatar@2x.png)
}
#PanelUI-fxa-label,
#PanelUI-fxa-icon {
list-style-image: url(chrome://browser/skin/sync-horizontalbar@2x.png);

Двоичные данные
browser/themes/shared/fxa/default-avatar.png

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 1.4 KiB

Просмотреть файл

@ -0,0 +1,8 @@
<!-- 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/. -->
<svg xmlns="http://www.w3.org/2000/svg" viewBox="194 -104 1000 1000" width="80" height="80">
<path fill="#c3cfd8" d="M694-104.3c276.1 0 500 223.9 500 500s-223.9 500-500 500-500-223.9-500-500c0-276.2 223.9-500 500-500z"/>
<path fill="#fff" fill-rule="evenodd" clip-rule="evenodd" d="M892.4 585.9c10 3.1 19.1 5.7 27.5 8.2 34.5 10 44.8 54.6 17.5 78.1-65.4 56.5-150.7 90.8-244 90.8-92.8 0-177.6-33.8-242.9-89.8-27.4-23.5-17.3-68.2 17.4-78.3 9.2-2.7 19.2-5.5 30.2-9 62.6-19.5 92.6-43.7 98.2-68.7 0-.1 0-.2.1-.2 3.6-16.1-2.8-32.9-15.5-43.5-26.4-22.1-37.1-59.8-44.1-87.5-.8-3.2-1.7-6.5-2.5-9.8-12.1-2.1-25.4-17.3-32.2-38.5-8.2-25.5-3.9-49.8 9.6-54.1 1.3-.4 2.6-.4 3.9-.5-3.1-18.2-6.9-45.4-7.3-69.3-.1-5.2-.2-10.9-.2-16.9 0-3 .1-6.1.1-9.3 0-1.6.1-3.2.2-4.8.1-1.6.2-3.2.3-4.9.9-13.1 2.9-26.8 7-40 7.4-23.7 21.6-45.4 47.4-57.3 5.8-2.7 11-6.4 15.1-11.3 22.4-26.4 49.1-39.6 74.2-45.4 6.9-1.6 13.6-2.6 20.1-3.2 3.2-.3 6.4-.5 9.5-.6 1.6-.1 3.1-.1 4.6-.1h4.5c11.7.3 22 1.8 29.6 3.7 50 12.3 89.2 38 116.4 69.5 13.5 15.8 23.9 33 30.7 50.7 3.4 8.9 5.9 17.9 7.4 26.9.8 4.5 1.3 9 1.6 13.5.3 4.5.3 8.9.1 13.4-1.5 27.1-4.4 45.9-7.3 60.1-2.3 11.1.1 22.2 5 32.4 4.9 10.3 5.3 26.7.2 43.9-6.1 20.3-18.3 35.3-29.8 38.7-2.2 8.1-3.8 13.5-3.9 13.5-3.8 29-10.7 59.8-35.3 82.9-10.5 9.8-15 24.5-13.1 38.7.5 3.5 1 6.6 1.6 9.2 5.6 25.1 35.5 49.3 98.1 68.8z"/>
</svg>

После

Ширина:  |  Высота:  |  Размер: 1.5 KiB

Двоичные данные
browser/themes/shared/fxa/default-avatar@2x.png

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 2.2 KiB

Просмотреть файл

@ -380,8 +380,13 @@ description > html|a {
#fxaProfileImage {
max-width: 60px;
border-radius: 50%;
list-style-image: url(chrome://browser/skin/fxa/default-avatar.png);
list-style-image: url(chrome://browser/skin/fxa/default-avatar.svg);
margin-inline-end: 15px;
image-rendering: -moz-crisp-edges;
}
#fxaLoginStatus[hasName] #fxaProfileImage {
max-width: 80px;
}
#fxaProfileImage.actionable {
@ -550,6 +555,10 @@ description > html|a {
list-style-image: url(chrome://browser/skin/fxa/sync-illustration.png)
}
#fxaLoginStatus[hasName] #fxaEmailAddress1 {
font-size: 1.1rem;
}
#fxaEmailAddress1,
#fxaEmailAddress2,
#fxaEmailAddress3 {
@ -613,7 +622,4 @@ description > html|a {
.fxaFirefoxLogo {
list-style-image: url(chrome://browser/skin/fxa/logo@2x.png);
}
#fxaProfileImage {
list-style-image: url(chrome://browser/skin/fxa/default-avatar@2x.png);
}
}

Просмотреть файл

@ -72,8 +72,7 @@
skin/classic/browser/preferences/in-content/favicon.ico (../shared/incontentprefs/favicon.ico)
skin/classic/browser/preferences/in-content/icons.svg (../shared/incontentprefs/icons.svg)
skin/classic/browser/preferences/in-content/search.css (../shared/incontentprefs/search.css)
skin/classic/browser/fxa/default-avatar.png (../shared/fxa/default-avatar.png)
skin/classic/browser/fxa/default-avatar@2x.png (../shared/fxa/default-avatar@2x.png)
skin/classic/browser/fxa/default-avatar.svg (../shared/fxa/default-avatar.svg)
skin/classic/browser/fxa/logo.png (../shared/fxa/logo.png)
skin/classic/browser/fxa/logo@2x.png (../shared/fxa/logo@2x.png)
skin/classic/browser/fxa/sync-illustration.png (../shared/fxa/sync-illustration.png)

Просмотреть файл

@ -15,8 +15,8 @@ function* spawnTest() {
let lines = [
'Manifest has a character encoding of ISO-8859-1. Manifests must have the ' +
'utf-8 character encoding.',
'The first line of the manifest must be "CACHE MANIFEST" at line 1.',
'"CACHE MANIFEST" is only valid on the first line but was found at line 3.',
'The first line of the manifest must be \u201cCACHE MANIFEST\u201d at line 1.',
'\u201cCACHE MANIFEST\u201d is only valid on the first line but was found at line 3.',
'images/sound-icon.png points to a resource that is not available at line 9.',
'images/background.png points to a resource that is not available at line 10.',
'/checking.cgi points to a resource that is not available at line 13.',
@ -61,7 +61,7 @@ function* spawnTest() {
'any URI not listed in the manifest will be treated as if the URI was ' +
'listed in the NETWORK section. Otherwise such URIs will be treated as ' +
'unavailable. Other uses of the * character are prohibited',
'The SETTINGS section may only contain a single value, "prefer-online" or "fast" at line 47.',
'The SETTINGS section may only contain a single value, \u201cprefer-online\u201d or \u201cfast\u201d at line 47.',
'FALLBACK section line 50 (/section1/ /offline1.html) prevents caching of ' +
'line 30 (/section1/blockedbyfallback.html) in the CACHE section.',
'/offline1.html points to a resource that is not available at line 50.',

Просмотреть файл

@ -130,7 +130,7 @@ function* spawnTest() {
},
exec: {
output: '101 nodes matched, but only 100 nodes highlighted. Use ' +
'\'--showall\' to show all'
'\u2018--showall\u2019 to show all'
}
},
{

Просмотреть файл

@ -74,7 +74,7 @@ function* spawnTest() {
status: 'ERROR'
},
exec: {
output: 'Error: Value required for \'region\'.'
output: 'Error: Value required for \u2018region\u2019.'
}
},
{
@ -98,7 +98,7 @@ function* spawnTest() {
status: 'ERROR'
},
exec: {
output: 'Error: Value required for \'fill\'.'
output: 'Error: Value required for \u2018fill\u2019.'
}
},
{

Просмотреть файл

@ -105,7 +105,7 @@ function* spawnTest() {
status: 'ERROR',
args: {
setting: { arg: ' devtools.netmonitor.enabled' },
value: { status: 'ERROR', message: 'Can\'t use \'4\'.' },
value: { status: 'ERROR', message: 'Can\u2019t use \u20184\u2019.' },
}
},
},

Просмотреть файл

@ -212,13 +212,13 @@ exports.testTsv = function(options) {
value: undefined,
arg: ' o',
status: 'INCOMPLETE',
message: 'Value required for \'optionType\'.'
message: 'Value required for \u2018optionType\u2019.'
},
optionValue: {
value: undefined,
arg: '',
status: 'INCOMPLETE',
message: 'Value required for \'optionValue\'.'
message: 'Value required for \u2018optionValue\u2019.'
}
}
}
@ -241,13 +241,13 @@ exports.testTsv = function(options) {
value: undefined,
arg: ' option',
status: 'INCOMPLETE',
message: 'Value required for \'optionType\'.'
message: 'Value required for \u2018optionType\u2019.'
},
optionValue: {
value: undefined,
arg: '',
status: 'INCOMPLETE',
message: 'Value required for \'optionValue\'.'
message: 'Value required for \u2018optionValue\u2019.'
}
}
}
@ -272,13 +272,13 @@ exports.testTsv = function(options) {
value: undefined,
arg: ' option',
status: 'INCOMPLETE',
message: 'Value required for \'optionType\'.'
message: 'Value required for \u2018optionType\u2019.'
},
optionValue: {
value: undefined,
arg: '',
status: 'INCOMPLETE',
message: 'Value required for \'optionValue\'.'
message: 'Value required for \u2018optionValue\u2019.'
}
}
}
@ -301,13 +301,13 @@ exports.testTsv = function(options) {
value: undefined,
arg: ' option ',
status: 'ERROR',
message: 'Can\'t use \'option\'.'
message: 'Can\u2019t use \u2018option\u2019.'
},
optionValue: {
value: undefined,
arg: '',
status: 'INCOMPLETE',
message: 'Value required for \'optionValue\'.'
message: 'Value required for \u2018optionValue\u2019.'
}
}
}
@ -336,7 +336,7 @@ exports.testTsv = function(options) {
value: undefined,
arg: '',
status: 'INCOMPLETE',
message: 'Value required for \'optionValue\'.'
message: 'Value required for \u2018optionValue\u2019.'
}
}
}
@ -364,7 +364,7 @@ exports.testTsv = function(options) {
value: undefined,
arg: '',
status: 'INCOMPLETE',
message: 'Value required for \'optionValue\'.'
message: 'Value required for \u2018optionValue\u2019.'
}
}
}
@ -393,7 +393,7 @@ exports.testTsv = function(options) {
value: undefined,
arg: '',
status: 'INCOMPLETE',
message: 'Value required for \'optionValue\'.'
message: 'Value required for \u2018optionValue\u2019.'
}
}
}

Просмотреть файл

@ -45,7 +45,7 @@ exports.testSingleString = function(options) {
value: undefined,
arg: '',
status: 'INCOMPLETE',
message: 'Value required for \'text\'.'
message: 'Value required for \u2018text\u2019.'
}
}
}
@ -67,7 +67,7 @@ exports.testSingleString = function(options) {
value: undefined,
arg: '',
status: 'INCOMPLETE',
message: 'Value required for \'text\'.'
message: 'Value required for \u2018text\u2019.'
}
}
}
@ -160,7 +160,7 @@ exports.testSingleNumber = function(options) {
value: undefined,
arg: '',
status: 'INCOMPLETE',
message: 'Value required for \'num\'.'
message: 'Value required for \u2018num\u2019.'
}
}
}
@ -182,7 +182,7 @@ exports.testSingleNumber = function(options) {
value: undefined,
arg: '',
status: 'INCOMPLETE',
message: 'Value required for \'num\'.'
message: 'Value required for \u2018num\u2019.'
}
}
}
@ -222,7 +222,7 @@ exports.testSingleNumber = function(options) {
value: undefined,
arg: ' x',
status: 'ERROR',
message: 'Can\'t convert "x" to a number.'
message: 'Can\u2019t convert \u201cx\u201d to a number.'
}
}
}
@ -244,7 +244,7 @@ exports.testSingleNumber = function(options) {
value: undefined,
arg: ' 1.5',
status: 'ERROR',
message: 'Can\'t convert "1.5" to an integer.'
message: 'Can\u2019t convert \u201c1.5\u201d to an integer.'
}
}
}
@ -271,7 +271,7 @@ exports.testSingleFloat = function(options) {
value: undefined,
arg: '',
status: 'INCOMPLETE',
message: 'Value required for \'num\'.'
message: 'Value required for \u2018num\u2019.'
}
}
}
@ -360,7 +360,7 @@ exports.testSingleFloat = function(options) {
cursor: 4,
current: 'num',
status: 'ERROR',
error: 'Can\'t convert "x" to a number.',
error: 'Can\u2019t convert \u201cx\u201d to a number.',
predictions: [ ],
unassigned: [ ],
args: {
@ -369,7 +369,7 @@ exports.testSingleFloat = function(options) {
value: undefined,
arg: ' x',
status: 'ERROR',
message: 'Can\'t convert "x" to a number.'
message: 'Can\u2019t convert \u201cx\u201d to a number.'
}
}
}
@ -598,7 +598,7 @@ exports.testNestedCommand = function(options) {
value: undefined,
arg: '',
status: 'INCOMPLETE',
message: 'Value required for \'text\'.'
message: 'Value required for \u2018text\u2019.'
}
}
}
@ -620,7 +620,7 @@ exports.testNestedCommand = function(options) {
value: undefined,
arg: '',
status: 'INCOMPLETE',
message: 'Value required for \'text\'.'
message: 'Value required for \u2018text\u2019.'
}
}
}
@ -659,7 +659,7 @@ exports.testNestedCommand = function(options) {
value: undefined,
arg: '',
status: 'INCOMPLETE',
message: 'Value required for \'text\'.'
message: 'Value required for \u2018text\u2019.'
}
}
}
@ -681,7 +681,7 @@ exports.testNestedCommand = function(options) {
value: undefined,
arg: '',
status: 'INCOMPLETE',
message: 'Value required for \'text\'.'
message: 'Value required for \u2018text\u2019.'
}
}
}
@ -703,7 +703,7 @@ exports.testNestedCommand = function(options) {
value: undefined,
arg: '',
status: 'INCOMPLETE',
message: 'Value required for \'text\'.'
message: 'Value required for \u2018text\u2019.'
}
}
}
@ -725,7 +725,7 @@ exports.testNestedCommand = function(options) {
value: undefined,
arg: '',
status: 'INCOMPLETE',
message: 'Value required for \'text\'.'
message: 'Value required for \u2018text\u2019.'
}
}
}

Просмотреть файл

@ -164,7 +164,7 @@ exports.testDefault = function(options) {
value: undefined,
arg: ' on',
status: 'INCOMPLETE',
message: 'Can\'t use \'on\'.'
message: 'Can\u2019t use \u2018on\u2019.'
},
}
}

Просмотреть файл

@ -149,7 +149,7 @@ function test() {
args: {
breakpoint: {
status: 'INCOMPLETE',
message: 'Value required for \'breakpoint\'.'
message: 'Value required for \u2018breakpoint\u2019.'
}
}
}

Просмотреть файл

@ -8,6 +8,7 @@
// in a Firefox tab or a custom html iframe in browser.html
const { Ci, Cu, Cm, components } = require("chrome");
const registrar = Cm.QueryInterface(Ci.nsIComponentRegistrar);
const Services = require("Services");
const { XPCOMUtils } = Cu.import("resource://gre/modules/XPCOMUtils.jsm", {});
const { nsIAboutModule } = Ci;
@ -42,11 +43,11 @@ AboutURL.createInstance = function(outer, iid) {
};
exports.register = function () {
if (Cm.isCIDRegistered(AboutURL.prototype.classID)) {
if (registrar.isCIDRegistered(AboutURL.prototype.classID)) {
console.error("Trying to register " + AboutURL.prototype.classDescription +
" more than once.");
} else {
Cm.registerFactory(AboutURL.prototype.classID,
registrar.registerFactory(AboutURL.prototype.classID,
AboutURL.prototype.classDescription,
AboutURL.prototype.contractID,
AboutURL);
@ -54,7 +55,7 @@ exports.register = function () {
}
exports.unregister = function () {
if (Cm.isCIDRegistered(AboutURL.prototype.classID)) {
Cm.unregisterFactory(AboutURL.prototype.classID, AboutURL);
if (registrar.isCIDRegistered(AboutURL.prototype.classID)) {
registrar.unregisterFactory(AboutURL.prototype.classID, AboutURL);
}
}

Просмотреть файл

@ -19,7 +19,7 @@ add_task(function* () {
status: 'ERROR',
args: {
selector: {
message: 'Value required for \'selector\'.'
message: 'Value required for \u2018selector\u2019.'
},
}
},

Просмотреть файл

@ -2,28 +2,28 @@
# 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/.
validator.nonExistingFolder=The project folder doesn't exists
validator.nonExistingFolder=The project folder doesnt exists
validator.expectProjectFolder=The project folder ends up being a file
validator.noManifestFile=A manifest file is required at project root folder, named either 'manifest.webapp' for packaged apps or 'manifest.json' for add-ons.
validator.invalidManifestURL=Invalid manifest URL '%S'
validator.noManifestFile=A manifest file is required at project root folder, named either manifest.webapp for packaged apps or manifest.json for add-ons.
validator.invalidManifestURL=Invalid manifest URL %S
# LOCALIZATION NOTE (validator.invalidManifestJSON, validator.noAccessManifestURL):
# %1$S is the error message, %2$S is the URI of the manifest.
validator.invalidManifestJSON=The webapp manifest isn't a valid JSON file: %1$S at: %2$S
validator.invalidManifestJSON=The webapp manifest isnt a valid JSON file: %1$S at: %2$S
validator.noAccessManifestURL=Unable to read manifest file: %1$S at: %2$S
# LOCALIZATION NOTE (validator.invalidHostedManifestURL): %1$S is the URI of
# the manifest, %2$S is the error message.
validator.invalidHostedManifestURL=Invalid hosted manifest URL '%1$S': %2$S
validator.invalidProjectType=Unknown project type '%S'
validator.invalidHostedManifestURL=Invalid hosted manifest URL %1$S: %2$S
validator.invalidProjectType=Unknown project type %S
# LOCALIZATION NOTE (validator.missNameManifestProperty, validator.missIconsManifestProperty):
# don't translate 'icons' and 'name'.
validator.missNameManifestProperty=Missing mandatory 'name' in Manifest.
validator.missIconsManifestProperty=Missing 'icons' in Manifest.
validator.missNameManifestProperty=Missing mandatory name in Manifest.
validator.missIconsManifestProperty=Missing icons in Manifest.
validator.missIconMarketplace2=app submission to the Marketplace requires a 128px icon
validator.invalidAppType=Unknown app type: '%S'.
validator.invalidHostedPriviledges=Hosted App can't be type '%S'.
validator.noCertifiedSupport='certified' apps are not fully supported on the App manager.
validator.nonAbsoluteLaunchPath=Launch path has to be an absolute path starting with '/': '%S'
validator.accessFailedLaunchPath=Unable to access the app starting document '%S'
validator.invalidAppType=Unknown app type: %S.
validator.invalidHostedPriviledges=Hosted App cant be type %S.
validator.noCertifiedSupport=certified apps are not fully supported on the App manager.
validator.nonAbsoluteLaunchPath=Launch path has to be an absolute path starting with /: %S
validator.accessFailedLaunchPath=Unable to access the app starting document %S
# LOCALIZATION NOTE (validator.accessFailedLaunchPathBadHttpCode): %1$S is the URI of
# the launch document, %2$S is the http error code.
validator.accessFailedLaunchPathBadHttpCode=Unable to access the app starting document '%1$S', got HTTP code %2$S
validator.accessFailedLaunchPathBadHttpCode=Unable to access the app starting document %1$S, got HTTP code %2$S

Просмотреть файл

@ -68,12 +68,12 @@ cacheDisabled=Your disk cache is disabled. Please set browser.cache.disk.enable
# LOCALIZATION NOTE (firstLineMustBeCacheManifest): the associated cache
# manifest has a first line that is not "CACHE MANIFEST". Parameters: %S is
# the line number.
firstLineMustBeCacheManifest=The first line of the manifest must be "CACHE MANIFEST" at line %S.
firstLineMustBeCacheManifest=The first line of the manifest must be “CACHE MANIFEST” at line %S.
# LOCALIZATION NOTE (cacheManifestOnlyFirstLine2): the associated cache
# manifest has "CACHE MANIFEST" on a line other than the first line.
# Parameters: %S is the line number where "CACHE MANIFEST" appears.
cacheManifestOnlyFirstLine2="CACHE MANIFEST" is only valid on the first line but was found at line %S.
cacheManifestOnlyFirstLine2=“CACHE MANIFEST” is only valid on the first line but was found at line %S.
# LOCALIZATION NOTE (asteriskInWrongSection2): the associated cache manifest
# has an asterisk (*) in a section other than the NETWORK section. Parameters:
@ -111,7 +111,7 @@ fallbackAsterisk2=Asterisk (*) incorrectly used in the FALLBACK section at line
# LOCALIZATION NOTE (settingsBadValue): the associated cache manifest has a
# SETTINGS section containing something other than the valid "prefer-online"
# or "fast". Parameters: %S is the line number where this error occurs.
settingsBadValue=The SETTINGS section may only contain a single value, "prefer-online" or "fast" at line %S.
settingsBadValue=The SETTINGS section may only contain a single value, “prefer-online” or “fast” at line %S.
# LOCALIZATION NOTE (invalidSectionName): the associated cache manifest
# contains an invalid section name. Parameters: %1$S is the section name, %2$S

Просмотреть файл

@ -22,7 +22,7 @@
<!-- LOCALIZATION NOTE (canvasDebuggerUI.emptyNotice1/2): This is the label shown
- in the call list view when empty. -->
<!ENTITY canvasDebuggerUI.emptyNotice1 "Click on the">
<!ENTITY canvasDebuggerUI.emptyNotice2 "button to record an animation frame's call stack.">
<!ENTITY canvasDebuggerUI.emptyNotice2 "button to record an animation frames call stack.">
<!-- LOCALIZATION NOTE (canvasDebuggerUI.waitingNotice): This is the label shown
- in the call list view while recording a snapshot. -->

Просмотреть файл

@ -24,7 +24,7 @@
<!-- LOCALIZATION NOTE (remoteHelp, remoteDocumentation, remoteHelpSuffix):
these strings will be concatenated in a single label, remoteDocumentation will
be used as text for a link to MDN. -->
<!ENTITY remoteHelp "Firefox Developer Tools can debug remote devices (Firefox for Android and Firefox OS, for example). Make sure that you have turned on the 'Remote debugging' option in the remote device. For more, see the ">
<!ENTITY remoteHelp "Firefox Developer Tools can debug remote devices (Firefox for Android and Firefox OS, for example). Make sure that you have turned on the Remote debugging option in the remote device. For more, see the ">
<!ENTITY remoteDocumentation "documentation">
<!ENTITY remoteHelpSuffix ".">

Просмотреть файл

@ -13,7 +13,7 @@ emptyFilterList=No filter specified
# LOCALIZATION NOTE (emptyPresetList):
# This string is displayed when preset's list is empty
emptyPresetList=You don't have any saved presets. \
emptyPresetList=You dont have any saved presets. \
You can store filter presets by choosing a name and saving them. \
Presets are quickly accessible and you can re-use them with ease.

Просмотреть файл

@ -35,7 +35,7 @@ jsonViewer.PrettyPrint=Pretty Print
# LOCALIZATION NOTE (jsonViewer.reps.more): Label used in arrays
# that have more items than displayed.
jsonViewer.reps.more=more...
jsonViewer.reps.more=more
# LOCALIZATION NOTE (jsonViewer.filterJSON): Label used in search box
# at the top right cornder of the JSON Viewer.

Просмотреть файл

@ -119,7 +119,7 @@ toolbar.view.census=Aggregate
# LOCALIZATION NOTE (toolbar.view.census.tooltip): The tooltip for the label for
# the census view option in the toolbar.
toolbar.view.census.tooltip=View a summary of the heap snapshot's contents by aggregating objects into groups
toolbar.view.census.tooltip=View a summary of the heap snapshots contents by aggregating objects into groups
# LOCALIZATION NOTE (toolbar.view.dominators): The label for the dominators view
# option in the toolbar.

Просмотреть файл

@ -117,7 +117,7 @@ scratchpad.tooltip=Scratchpad
# LOCALIZATION NOTE (selfxss.msg): the text that is displayed when
# a new user of the developer tools pastes code into the console
# %1 is the text of selfxss.okstring
selfxss.msg=Scam Warning: Take care when pasting things you don't understand. This could allow attackers to steal your identity or take control of your computer. Please type '%S' in the scratchpad below to allow pasting.
selfxss.msg=Scam Warning: Take care when pasting things you dont understand. This could allow attackers to steal your identity or take control of your computer. Please type %S in the scratchpad below to allow pasting.
# LOCALIZATION NOTE (selfxss.msg): the string to be typed
# in by a new user of the developer tools when they receive the sefxss.msg prompt.

Просмотреть файл

@ -40,7 +40,7 @@ error-save=Style sheet could not be saved.
# LOCALIZATION NOTE (error-compressed): This is shown when we can't show
# coverage information because the css source is compressed.
error-compressed=Can't show coverage information for compressed stylesheets
error-compressed=Cant show coverage information for compressed stylesheets
# LOCALIZATION NOTE (importStyleSheet.title): This is the file picker title,
# when you import a style sheet into the Style Editor.

Просмотреть файл

@ -39,7 +39,7 @@ webConsoleCmd.accesskey=W
# %2$02S = minutes, %3$02S = seconds, %4$03S = milliseconds.
timestampFormat=%02S:%02S:%02S.%03S
helperFuncUnsupportedTypeError=Can't call pprint on this type of object.
helperFuncUnsupportedTypeError=Cant call pprint on this type of object.
# LOCALIZATION NOTE (NetworkPanel.deltaDurationMS): this string is used to
# show the duration between two network events (e.g request and response
@ -219,7 +219,7 @@ cdFunctionInvalidArgument=Cannot cd() to the given window. Invalid argument.
# LOCALIZATION NOTE (selfxss.msg): the text that is displayed when
# a new user of the developer tools pastes code into the console
# %1 is the text of selfxss.okstring
selfxss.msg=Scam Warning: Take care when pasting things you don't understand. This could allow attackers to steal your identity or take control of your computer. Please type '%S' below (no need to press enter) to allow pasting.
selfxss.msg=Scam Warning: Take care when pasting things you dont understand. This could allow attackers to steal your identity or take control of your computer. Please type %S below (no need to press enter) to allow pasting.
# LOCALIZATION NOTE (selfxss.msg): the string to be typed
# in by a new user of the developer tools when they receive the sefxss.msg prompt.

Просмотреть файл

@ -85,7 +85,7 @@
<!ENTITY runtimePanel_other "Other">
<!ENTITY runtimePanel_installsimulator "Install Simulator">
<!ENTITY runtimePanel_noadbhelper "Install ADB Helper">
<!ENTITY runtimePanel_nousbdevice "Can't see your device?">
<!ENTITY runtimePanel_nousbdevice "Cant see your device?">
<!ENTITY runtimePanel_refreshDevices_label "Refresh Devices">
<!-- Lense -->

Просмотреть файл

@ -31,21 +31,21 @@ project_tab_loading=Loading…
# These messages appear in a notification box when an error occur.
error_cantInstallNotFullyConnected=Can't install project. Not fully connected.
error_cantInstallValidationErrors=Can't install project. Validation errors.
error_listRunningApps=Can't get app list from device
error_cantInstallNotFullyConnected=Cant install project. Not fully connected.
error_cantInstallValidationErrors=Cant install project. Validation errors.
error_listRunningApps=Cant get app list from device
# Variable: name of the operation (in english)
error_operationTimeout=Operation timed out: %1$S
error_operationFail=Operation failed: %1$S
# Variable: app name
error_cantConnectToApp=Can't connect to app: %1$S
error_cantConnectToApp=Cant connect to app: %1$S
# Variable: error message (in english)
error_cantFetchAddonsJSON=Can't fetch the add-on list: %S
error_cantFetchAddonsJSON=Cant fetch the add-on list: %S
error_appProjectsLoadFailed=Unable to load project list. This can occur if you've used this profile with a newer version of Firefox.
error_appProjectsLoadFailed=Unable to load project list. This can occur if youve used this profile with a newer version of Firefox.
error_folderCreationFailed=Unable to create project folder in the selected directory.
# Variable: runtime app build ID (looks like this %Y%M%D format) and firefox build ID (same format)
@ -62,7 +62,7 @@ addons_install_button=install
addons_uninstall_button=uninstall
addons_adb_label=ADB Helper Add-on
addons_adapters_label=Tools Adapters Add-on
addons_adb_warning=USB devices won't be detected without this add-on
addons_adb_warning=USB devices wont be detected without this add-on
addons_status_unknown=?
addons_status_installed=Installed
addons_status_uninstalled=Not Installed

Просмотреть файл

@ -379,7 +379,7 @@ const Tree = module.exports = createClass({
*
* @param {Object} item
*/
_focus: function (item) {
_focus(item) {
if (this.props.onFocus) {
this.props.onFocus(item);
}
@ -388,7 +388,7 @@ const Tree = module.exports = createClass({
/**
* Sets the state to have no focused item.
*/
_onBlur: function () {
_onBlur() {
this._focus(undefined);
},

Просмотреть файл

@ -70,7 +70,7 @@ add_task(function* () {
resource: {
arg: " http",
status: "INCOMPLETE",
message: "Value required for \'resource\'."
message: "Value required for \u2018resource\u2019."
},
line: { status: "VALID" },
}
@ -88,7 +88,7 @@ add_task(function* () {
resource: {
arg: " page1",
status: "INCOMPLETE",
message: "Value required for \'resource\'."
message: "Value required for \u2018resource\u2019."
},
line: { status: "VALID" },
}
@ -106,7 +106,7 @@ add_task(function* () {
resource: {
arg: " page2",
status: "INCOMPLETE",
message: "Value required for \'resource\'."
message: "Value required for \u2018resource\u2019."
},
line: { status: "VALID" },
}
@ -122,7 +122,7 @@ add_task(function* () {
args: {
resource: {
arg: " stylez",
status: "ERROR", message: "Can\'t use \'stylez\'." },
status: "ERROR", message: "Can\u2019t use \u2018stylez\u2019." },
line: { status: "VALID" },
}
},

Просмотреть файл

@ -149,7 +149,7 @@ exports.items = [
runAt: "client",
name: "cmd setdir",
description: l10n.lookup("cmdSetdirDesc"),
manual: l10n.lookup("cmdSetdirManual2"),
manual: l10n.lookup("cmdSetdirManual3"),
params: [
{
name: "directory",

Просмотреть файл

@ -31,7 +31,7 @@
- <style> tag -->
<!ENTITY csscoverage.optimize.body1 "You can sometimes speed up loading by moving">
<!ENTITY csscoverage.optimize.body2 "tags to the bottom of the page and creating a new inline">
<!ENTITY csscoverage.optimize.body3 "element with the styles needed before the 'load' event to the top. Here are the style blocks you need:">
<!ENTITY csscoverage.optimize.body3 "element with the styles needed before the load event to the top. Here are the style blocks you need:">
<!-- LOCALIZATION NOTE (csscoverage.optimize.bodyX):
- This is what we say when we have no optimization suggestions -->

Просмотреть файл

@ -14,8 +14,8 @@ csscoverageStopDesc2=Stop collecting CSS coverage data
csscoverageOneShotDesc2=Collect instantaneous CSS coverage data
csscoverageToggleDesc2=Toggle collecting CSS coverage data
csscoverageReportDesc2=Show CSS coverage report
csscoverageStartNoReloadDesc=Don't start with a page reload
csscoverageStartNoReloadManual=It's best if we start by reloading the current page because that starts the test at a known point, but there could be reasons why we don't want to do that (e.g. the page contains state that will be lost across a reload)
csscoverageStartNoReloadDesc=Dont start with a page reload
csscoverageStartNoReloadManual=Its best if we start by reloading the current page because that starts the test at a known point, but there could be reasons why we dont want to do that (e.g. the page contains state that will be lost across a reload)
# LOCALIZATION NOTE (csscoverageRunningReply, csscoverageDoneReply): Text that
# describes the current state of the css coverage system
@ -29,4 +29,4 @@ csscoverageRunningError=CSS coverage analysis already running
csscoverageNotRunningError=CSS coverage analysis not running
csscoverageNotRunError=CSS coverage analysis has not been run
csscoverageNoRemoteError=Target does not support CSS Coverage
csscoverageOneShotReportError=CSS coverage report is not available for 'oneshot' data. Please use start/stop.
csscoverageOneShotReportError=CSS coverage report is not available for oneshot data. Please use start/stop.

Просмотреть файл

@ -35,7 +35,7 @@ canonProxyManual=A set of commands that are executed on a remote system. The rem
# LOCALIZATION NOTE: This error message is displayed when we try to add a new
# command (using a proxy) where one already exists with the same name.
canonProxyExists=There is already a command called '%S'
canonProxyExists=There is already a command called %S
# LOCALIZATION NOTE: This message describes the '{' command, which allows
# entry of JavaScript like traditional developer tool command lines.
@ -51,34 +51,34 @@ cliOptions=Available Options
# LOCALIZATION NOTE: The error message when the user types a command that
# isn't registered
cliUnknownCommand2=Invalid Command: '%1$S'.
cliUnknownCommand2=Invalid Command: %1$S.
# LOCALIZATION NOTE: A parameter should have a value, but doesn't
cliIncompleteParam=Value required for '%1$S'.
cliIncompleteParam=Value required for %1$S.
# LOCALIZATION NOTE: Error message given when a file argument points to a file
# that does not exist, but should (e.g. for use with File->Open) %1$S is a
# filename
fileErrNotExists='%1$S' doesn't exist
fileErrNotExists=%1$S doesnt exist
# LOCALIZATION NOTE: Error message given when a file argument points to a file
# that exists, but should not (e.g. for use with File->Save As) %1$S is a
# filename
fileErrExists='%1$S' already exists
fileErrExists=%1$S already exists
# LOCALIZATION NOTE: Error message given when a file argument points to a
# non-file, when a file is needed. %1$S is a filename
fileErrIsNotFile='%1$S' is not a file
fileErrIsNotFile=%1$S is not a file
# LOCALIZATION NOTE: Error message given when a file argument points to a
# non-directory, when a directory is needed (e.g. for use with 'cd') %1$S is a
# filename
fileErrIsNotDirectory='%1$S' is not a directory
fileErrIsNotDirectory=%1$S is not a directory
# LOCALIZATION NOTE: Error message given when a file argument does not match
# the specified regular expression %1$S is a filename %2$S is a regular
# expression
fileErrDoesntMatch='%1$S' does not match '%2$S'
fileErrDoesntMatch=%1$S does not match %2$S
# LOCALIZATION NOTE: When the menu has displayed all the matches that it
# should (i.e. about 10 items) then we display this to alert the user that
@ -93,7 +93,7 @@ jstypeParseScope=Scope lost
# LOCALIZATION NOTE (jstypeParseMissing, jstypeBeginSyntax,
# jstypeBeginUnterm): These error messages are displayed when the command line
# is doing JavaScript completion and encounters errors.
jstypeParseMissing=Can't find property '%S'
jstypeParseMissing=Cant find property %S
jstypeBeginSyntax=Syntax error
jstypeBeginUnterm=Unterminated string literal
@ -105,9 +105,9 @@ jstypeParseError=Error
# error messages are displayed when the command line is passed a variable
# which has the wrong format and can't be converted. Parameters: %S is the
# passed variable.
typesNumberNan=Can't convert "%S" to a number.
typesNumberNotInt2=Can't convert "%S" to an integer.
typesDateNan=Can't convert "%S" to a date.
typesNumberNan=Cant convert “%S” to a number.
typesNumberNotInt2=Cant convert “%S” to an integer.
typesDateNan=Cant convert “%S” to a date.
# LOCALIZATION NOTE (typesNumberMax, typesNumberMin, typesDateMax,
# typesDateMin): These error messages are displayed when the command line is
@ -121,7 +121,7 @@ typesDateMin=%1$S is earlier than minimum allowed: %2$S.
# LOCALIZATION NOTE: This error message is displayed when the command line is
# passed an option with a limited number of correct values, but the passed
# value is not one of them.
typesSelectionNomatch=Can't use '%S'.
typesSelectionNomatch=Cant use %S.
# LOCALIZATION NOTE: This error message is displayed when the command line is
# expecting a CSS query string, however the passed string is not valid.
@ -157,8 +157,8 @@ helpListAll=Available Commands:
# displayed in response to the 'help <search>' command (i.e. with a search
# string), just above the list of matching commands. Parameters: %S is the
# search string.
helpListPrefix=Commands starting with '%S':
helpListNone=No commands starting with '%S'
helpListPrefix=Commands starting with %S:
helpListNone=No commands starting with %S
# LOCALIZATION NOTE (helpManRequired, helpManOptional, helpManDefault): When
# the 'help x' command wants to show the manual for the 'x' command, it needs
@ -186,12 +186,12 @@ commandParseError=Command line parsing error
# parameter. See localization comment for 'connect' for an explanation about
# 'prefix'.
contextDesc=Concentrate on a group of commands
contextManual=Setup a default prefix to future commands. For example 'context git' would allow you to type 'commit' rather than 'git commit'.
contextManual=Setup a default prefix to future commands. For example context git would allow you to type commit rather than git commit.
contextPrefixDesc=The command prefix
# LOCALIZATION NOTE: This message message displayed during the processing of
# the 'context' command, when the found command is not a parent command.
contextNotParentError=Can't use '%S' as a prefix because it is not a parent command.
contextNotParentError=Cant use %S as a prefix because it is not a parent command.
# LOCALIZATION NOTE (contextReply, contextEmptyReply): These messages are
# displayed during the processing of the 'context' command, to indicate
@ -251,7 +251,7 @@ langOutput=You are now using %S
prefDesc=Commands to control settings
prefManual=Commands to display and alter preferences both for GCLI and the surrounding environment
prefListDesc=Display available settings
prefListManual=Display a list of preferences, optionally filtered when using the 'search' parameter
prefListManual=Display a list of preferences, optionally filtered when using the search parameter
prefListSearchDesc=Filter the list of settings displayed
prefListSearchManual=Search for the given string in the list of available preferences
prefShowDesc=Display setting value
@ -296,7 +296,7 @@ prefOutputValue=Value
# 'intro' command. The localization of 'Got it!' should be the same used in
# introTextGo.
introDesc=Show the opening message
introManual=Redisplay the message that is shown to new users until they click the 'Got it!' button
introManual=Redisplay the message that is shown to new users until they click the Got it! button
# LOCALIZATION NOTE (introTextOpening3, introTextCommands, introTextKeys2,
# introTextF1Escape, introTextGo): These strings are displayed when the user

Просмотреть файл

@ -22,7 +22,7 @@ helpAvailable=Available Commands
# LOCALIZATION NOTE (notAvailableInE10S) Used in the output of any command that
# is not compatible with multiprocess mode (E10S).
notAvailableInE10S=The command '%1$S' is not available in multiprocess mode (E10S)
notAvailableInE10S=The command %1$S is not available in multiprocess mode (E10S)
# LOCALIZATION NOTE (consoleDesc) A very short string used to describe the
# function of the console command.
@ -54,7 +54,7 @@ screenshotFilenameDesc=Destination filename
# LOCALIZATION NOTE (screenshotFilenameManual) A fuller description of the
# 'filename' parameter to the 'screenshot' command, displayed when the user
# asks for help on what it does.
screenshotFilenameManual=The name of the file (should have a '.png' extension) to which we write the screenshot.
screenshotFilenameManual=The name of the file (should have a .png extension) to which we write the screenshot.
# LOCALIZATION NOTE (screenshotClipboardDesc) A very short string to describe
# the 'clipboard' parameter to the 'screenshot' command, which is displayed in
@ -76,7 +76,7 @@ screenshotChromeDesc2=Capture %1$S chrome window? (true/false)
# 'chrome' parameter to the 'screenshot' command, displayed when the user
# asks for help on what it does.
# The argument (%1$S) is the browser name.
screenshotChromeManual2=True if you want to take the screenshot of the %1$S window rather than the web page's content window.
screenshotChromeManual2=True if you want to take the screenshot of the %1$S window rather than the web pages content window.
# LOCALIZATION NOTE (screenshotGroupOptions) A label for the optional options of
# the screenshot command.
@ -227,7 +227,7 @@ highlightRegionDesc=Box model region
# LOCALIZATION NOTE (highlightRegionManual) A fuller description of the 'region'
# option parameter to the 'highlight' command, displayed when the user asks for
# help on what it does.
highlightRegionManual=Which box model region should be highlighted: 'content', 'padding', 'border' or 'margin'
highlightRegionManual=Which box model region should be highlighted: content, padding, border or margin
# LOCALIZATION NOTE (highlightFillDesc) A very short string to describe the
# 'fill' option parameter to the 'highlight' command, which is displayed in a
@ -260,7 +260,7 @@ highlightOutputConfirm2=%1$S node highlighted;%1$S nodes highlighted
# informing the user how many nodes have been highlighted successfully and that
# some nodes could not be highlighted due to the maximum number of nodes being
# reached, and how to turn highlighting off
highlightOutputMaxReached=%1$S nodes matched, but only %2$S nodes highlighted. Use '--showall' to show all
highlightOutputMaxReached=%1$S nodes matched, but only %2$S nodes highlighted. Use --showall to show all
# LOCALIZATION NOTE (unhighlightDesc) A very short description of the
# 'unhighlight' command. See unhighlightManual for a fuller description of what
@ -270,7 +270,7 @@ unhighlightDesc=Unhighlight all nodes
# LOCALIZATION NOTE (unhighlightManual) A fuller description of the 'unhighlight'
# command, displayed when the user asks for help on what it does.
unhighlightManual=Unhighlight all nodes previously highlighted with the 'highlight' command
unhighlightManual=Unhighlight all nodes previously highlighted with the highlight command
# LOCALIZATION NOTE (restartBrowserDesc) A very short description of the
# 'restart' command. This string is designed to be shown in a menu alongside the
@ -461,7 +461,7 @@ dbgBlackBoxSourceDesc=A specific source to black box
# LOCALIZATION NOTE (dbgBlackBoxGlobDesc) A very short string used to describe the
# 'glob' parameter to the 'dbg blackbox' command.
dbgBlackBoxGlobDesc=Black box all sources that match this glob (for example: "*.min.js")
dbgBlackBoxGlobDesc=Black box all sources that match this glob (for example: “*.min.js”)
# LOCALIZATION NOTE (dbgBlackBoxInvertDesc) A very short string used to describe the
# 'invert' parameter to the 'dbg blackbox' command.
@ -490,7 +490,7 @@ dbgUnBlackBoxSourceDesc=A specific source to stop black boxing
# LOCALIZATION NOTE (dbgUnBlackBoxGlobDesc) A very short string used to describe the
# 'glob' parameter to the 'dbg blackbox' command.
dbgUnBlackBoxGlobDesc=Stop black boxing all sources that match this glob (for example: "*.min.js")
dbgUnBlackBoxGlobDesc=Stop black boxing all sources that match this glob (for example: “*.min.js”)
# LOCALIZATION NOTE (dbgUnBlackBoxEmptyDesc) A very short string used to let the
# user know that we did not stop black boxing any sources.
@ -600,16 +600,16 @@ cmdRefreshDesc=Re-read mozcmd directory
# LOCALIZATION NOTE (cmdStatus3) When the we load new commands from mozcmd
# directory, we report where we loaded from using %1$S.
cmdStatus3=Loaded commands from '%1$S'
cmdStatus3=Loaded commands from %1$S
# LOCALIZATION NOTE (cmdSetdirDesc) A very short description of the 'cmd setdir'
# command. This string is designed to be shown in a menu alongside the command
# name, which is why it should be as short as possible.
cmdSetdirDesc=Setup a mozcmd directory
# LOCALIZATION NOTE (cmdSetdirManual2) A fuller description of the 'cmd setdir'
# LOCALIZATION NOTE (cmdSetdirManual3) A fuller description of the 'cmd setdir'
# command, displayed when the user asks for help on what it does.
cmdSetdirManual2=A 'mozcmd' directory is an easy way to create new custom commands. For more information see the <a href="https://developer.mozilla.org/docs/Tools/GCLI/Customization">MDN documentation</a>.
cmdSetdirManual3=A mozcmd directory is an easy way to create new custom commands. For more information see https://developer.mozilla.org/docs/Tools/GCLI/Customization
# LOCALIZATION NOTE (cmdSetdirDirectoryDesc) The description of the directory
# parameter to the 'cmd setdir' command.
@ -1219,7 +1219,7 @@ callLogChromeEvalException=Evaluated JavaScript threw the following exception
# LOCALIZATION NOTE (callLogChromeEvalNeedsObject) A string displayed as the
# result of passing a non-JavaScript object creating source via the
# 'calllog chromestart javascript' command.
callLogChromeEvalNeedsObject=The JavaScript source must evaluate to an object whose method calls are to be logged e.g. "({a1: function() {this.a2()},a2: function() {}});"
callLogChromeEvalNeedsObject=The JavaScript source must evaluate to an object whose method calls are to be logged e.g. “({a1: function() {this.a2()},a2: function() {}});”
# LOCALIZATION NOTE (scratchpadOpenTooltip) A string displayed as the
# tooltip of button in devtools toolbox which opens Scratchpad.
@ -1388,7 +1388,7 @@ profilerNotFound=Profile not found
# an operation cannot be completed because the profile in question has not been
# started yet. It also contains a hint to use the 'profile start' command to
# start the profiler.
profilerNotStarted3=Profiler has not been started yet. Use 'profile start' to start profiling
profilerNotStarted3=Profiler has not been started yet. Use profile start to start profiling
# LOCALIZATION NOTE (profilerStarted2) A very short string that indicates that
# we have started recording.
@ -1491,7 +1491,7 @@ mdnCssProp=Property name
# the result of the 'mdn css' command. Errors occur when a given CSS property
# wasn't found on MDN. The %1$S parameter will be replaced with the name of the
# CSS property.
mdnCssPropertyNotFound=MDN documentation for the CSS property '%1$S' was not found.
mdnCssPropertyNotFound=MDN documentation for the CSS property %1$S was not found.
# LOCALIZATION NOTE (mdnCssVisitPage) String used as the label of a link to the
# MDN page for a given CSS property.
mdnCssVisitPage=Visit MDN page

Просмотреть файл

@ -12,6 +12,10 @@ function snapshotWindow(win, withCaret) {
return SpecialPowers.snapshotWindow(win, withCaret);
}
function snapshotRect(win, rect) {
return SpecialPowers.snapshotRect(win, rect);
}
// If the two snapshots don't compare as expected (true for equal, false for
// unequal), returns their serializations as data URIs. In all cases, returns
// whether the comparison was as expected.

Просмотреть файл

@ -0,0 +1,44 @@
Components.utils.import("resource://gre/modules/Services.jsm");
Components.utils.import("resource://gre/modules/Timer.jsm");
// Define these to make EventUtils happy.
let window = this;
let parent = {};
let EventUtils = {};
Services.scriptloader.loadSubScript(
"chrome://mochikit/content/tests/SimpleTest/EventUtils.js",
EventUtils
);
addMessageListener("cancelPrompt", message => {
cancelPromptWhenItAppears();
});
function cancelPromptWhenItAppears() {
let interval = setInterval(() => {
if (cancelPrompt()) {
clearInterval(interval);
}
}, 100);
}
function cancelPrompt() {
let browserWin = Services.wm.getMostRecentWindow("navigator:browser");
let gBrowser = browserWin.gBrowser;
let promptManager = gBrowser.getTabModalPromptBox(gBrowser.selectedBrowser);
let prompts = promptManager.listPrompts();
if (!prompts.length) {
return false;
}
sendAsyncMessage("promptCanceled", {
ui: {
infoTitle: {
hidden: prompts[0].ui.infoTitle.getAttribute("hidden") == "true",
},
},
});
EventUtils.synthesizeKey("KEY_Escape", { code: "Escape" }, browserWin);
return true;
}

Просмотреть файл

@ -1,9 +1,10 @@
[DEFAULT]
skip-if = buildapp == 'mulet' || buildapp == 'b2g' || e10s
skip-if = buildapp == 'mulet' || buildapp == 'b2g'
support-files =
bug619644_inner.html
bug625187_iframe.html
prompt_common.js
chromeScript.js
[test_bug619644.html]
[test_bug620145.html]
@ -11,6 +12,6 @@ skip-if = toolkit == 'android' #TIMED_OUT
[test_bug625187.html]
[test_bug861605.html]
[test_modal_prompts.html]
skip-if = toolkit == 'android' || (os == 'linux' && (debug || asan)) #TIMED_OUT (For Linux : 950636)
skip-if = toolkit == 'android' || (os == 'linux' && (debug || asan)) || e10s #android: TIMED_OUT (For Linux : 950636)
[test_modal_select.html]
skip-if = toolkit == 'android' #TIMED_OUT
skip-if = toolkit == 'android' || e10s #android: TIMED_OUT

Просмотреть файл

@ -31,16 +31,22 @@ SimpleTest.waitForExplicitFinish();
const expectedFinalDoc =
"<head><\/head><body><p>Original content<\/p>\n<script>\n window.opener.postMessage(\"\", \"*\");\n confirm (\"Message\");\n document.write (\"Extra content\");\n window.opener.postMessage(document.documentElement.innerHTML, \"*\");\n<\/script>Extra content<\/body>";
let gChromeMessageManager;
function runtest(e)
{
window.removeEventListener("message", runtest, false);
window.addEventListener("message", checktest, false);
synthesizeKey("VK_ESCAPE", {}, e.source);
let url = SimpleTest.getTestFileURL("chromeScript.js");
gChromeMessageManager = SpecialPowers.loadChromeScript(url);
gChromeMessageManager.sendAsyncMessage("cancelPrompt");
}
function checktest(e) {
is(e.data, expectedFinalDoc, "ESC press should not abort document load");
e.source.close();
gChromeMessageManager.destroy();
SimpleTest.finish();
}

Просмотреть файл

@ -4,7 +4,6 @@
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
<script type="text/javascript" src="prompt_common.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body onload="runtest()">
@ -53,20 +52,32 @@ function runtest()
todo(false, "Test is run with tab modal prompts disabled.");
else
ok(true, "Test is run with tab modal prompts enabled.");
startCallbackTimer();
selectionTest = isTabModal;
let url = SimpleTest.getTestFileURL("chromeScript.js");
let chrome = SpecialPowers.loadChromeScript(url);
chrome.sendAsyncMessage("cancelPrompt");
var button = $("button");
dispatchMouseEvent(button, "mousedown");
dispatchMouseEvent(button, "mouseup");
selectionTest = isTabModal;
// alert appears at this point, to be closed by the chrome script.
startCallbackTimer();
checkSelection();
chrome.sendAsyncMessage("cancelPrompt");
var text = $("text");
dispatchMouseEvent(text, "mousedown");
dispatchMouseEvent(text, "mouseup");
// alert appears at this point, to be closed by the chrome script.
checkSelection();
chrome.destroy();
SimpleTest.finish();
}
@ -81,7 +92,7 @@ function dispatchMouseEvent(target, type)
ok(true, type + " sent to " + target.id);
}
function handleDialog(ui, testNum)
function checkSelection()
{
if (!selectionTest) {
todo(false, "Selection test is disabled when tab modal prompts are not enabled.");
@ -89,9 +100,6 @@ function handleDialog(ui, testNum)
synthesizeMouse($("text"), 25, 55, { type: "mousemove" });
is(window.getSelection().toString(), "", "selection not made");
}
ok(true, "handleDialog sending mouseclick to dialog...");
synthesizeMouse(ui.button0, 5, 5, { }, SpecialPowers.unwrap(ui.button0.ownerDocument.defaultView));
}
</script>

Просмотреть файл

@ -4,7 +4,6 @@
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
<script type="text/javascript" src="prompt_common.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css">
<!--
- Any copyright is dedicated to the Public Domain.
@ -49,42 +48,48 @@ function runtest()
return;
}
startCallbackTimer();
let url = SimpleTest.getTestFileURL("chromeScript.js");
let chrome = SpecialPowers.loadChromeScript(url);
chrome.addMessageListener("promptCanceled", msg => {
checkSelection(msg.ui);
});
chrome.sendAsyncMessage("cancelPrompt");
var button = document.querySelector("button");
dispatchMouseEvent(button, "click");
startCallbackTimer();
chrome.sendAsyncMessage("cancelPrompt");
var iframe = document.getElementById("iframe_diff_origin");
button = SpecialPowers.wrap(iframe.contentWindow).document.getElementById("btn1");
dispatchMouseEvent(button, "click");
startCallbackTimer();
chrome.sendAsyncMessage("cancelPrompt");
iframe = document.getElementById("iframe_same_origin");
button = iframe.contentWindow.document.getElementById("btn1");
dispatchMouseEvent(button, "click");
startCallbackTimer();
chrome.sendAsyncMessage("cancelPrompt");
button = iframe.contentWindow.document.getElementById("btn2");
dispatchMouseEvent(button, "click");
chrome.destroy();
SimpleTest.finish();
}
function handleDialog(ui)
function checkSelection(ui)
{
dialogNum++;
if (dialogNum == 1 || dialogNum == 3 || dialogNum == 4)
is(ui.infoTitle.getAttribute("hidden"), "true",
ok(ui.infoTitle.hidden,
"dialog #" + dialogNum + ": the tabprompt infoTitle element is hidden");
else if (dialogNum == 2)
ok(!ui.infoTitle.hasAttribute("hidden"),
ok(!ui.infoTitle.hidden,
"dialog #" + dialogNum + ": the tabprompt infoTitle element is not hidden");
synthesizeMouse(ui.button0, 2, 2, {}, SpecialPowers.unwrap(ui.button0.ownerDocument.defaultView));
}
function dispatchMouseEvent(target, type)

Просмотреть файл

@ -4,7 +4,6 @@
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
<script type="text/javascript" src="prompt_common.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body onload="runtest()">
@ -38,7 +37,9 @@ function runtest()
ok(true, "Test is run with tab modal prompts enabled.");
startCallbackTimer();
let url = SimpleTest.getTestFileURL("chromeScript.js");
let chrome = SpecialPowers.loadChromeScript(url);
chrome.sendAsyncMessage("cancelPrompt");
try {
alert();
@ -47,7 +48,7 @@ function runtest()
ok(false, "alert() without arguments should not throw!");
}
startCallbackTimer();
chrome.sendAsyncMessage("cancelPrompt");
try {
confirm();
@ -56,6 +57,7 @@ function runtest()
ok(false, "confirm() without arguments should not throw!");
}
chrome.destroy();
SimpleTest.finish();
}

Просмотреть файл

@ -5,6 +5,7 @@ support-files =
audio.ogg
[browser_autoscroll_disabled.js]
[browser_bug295977_autoscroll_overflow.js]
[browser_bug451286.js]
[browser_bug594509.js]
[browser_bug982298.js]
[browser_bug1198465.js]

Просмотреть файл

@ -0,0 +1,136 @@
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;
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* 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;
}

Просмотреть файл

@ -1,193 +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="451286test"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
width="600"
height="600"
onload="SimpleTest.executeSoon(startTest);"
title="451286 test (also tests bug 493658)">
<script type="application/javascript"><![CDATA[
const Ci = Components.interfaces;
const Cc = Components.classes;
const Cr = Components.results;
const SEARCH_TEXT = "text";
const DATAURI = "data:text/html," + SEARCH_TEXT;
let {Task} = Components.utils.import("resource://gre/modules/Task.jsm", {});
var gFindBar = null;
var gBrowser;
var gWin;
var noHighlightSnapshot;
var findSnapshot;
var imports = ["SimpleTest", "ok", "snapshotWindow", "compareSnapshots",
"parentFinish"];
for (var name of imports) {
window[name] = window.opener.wrappedJSObject[name];
}
function finish() {
window.close();
parentFinish();
}
function startTest() {
gFindBar = document.getElementById("FindToolbar");
gBrowser = document.getElementById("content");
gBrowser.addEventListener("pageshow", onPageShow, false);
// Bug 451286. An iframe that should be highlighted
var 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
var invisible = "<iframe id='invisible' style='display: none;' " +
"src='" + DATAURI + "'></iframe>";
var uri = DATAURI + invisible + SEARCH_TEXT + visible + SEARCH_TEXT;
gBrowser.loadURI(uri);
}
// This test is comparing snapshots. It is necessary to wait for the findbar
// to close before taking the snapshot so the findbar does not take up space
// on the new snapshot.
function closeFindbarAndWait() {
return new Promise((resolve) => {
gFindBar.addEventListener("transitionend", function cont(aEvent) {
if (aEvent.propertyName != "visibility") {
return;
}
gFindBar.removeEventListener("transitionend", cont);
resolve();
});
gFindBar.close();
});
}
function toggleHighlightAndWait(aHighlight) {
return new Promise((resolve) => {
let listener = {
onHighlightFinished: function() {
gFindBar.browser.finder.removeResultListener(listener);
resolve();
}
};
gFindBar.browser.finder.addResultListener(listener);
gFindBar.toggleHighlight(aHighlight);
});
}
let onPageShow = Task.async(function* (aEvent) {
// Don't respond to pageshow events coming from the <iframes>
if (aEvent.target != gBrowser.contentDocument)
return;
gBrowser.removeEventListener("pageshow", onPageShow, false);
// First, take a snapshot of the window without highlighting
// to be used later to test the unhighlighting case
gWin = gBrowser.contentWindow;
noHighlightSnapshot = snapshotWindow(gWin);
yield part1();
yield part2();
yield part3();
finish();
});
let part1 = Task.async(function* () {
gFindBar.open();
gFindBar._findField.value = SEARCH_TEXT;
var matchCase = gFindBar.getElement("find-case-sensitive");
if (matchCase.checked)
matchCase.doCommand();
// Turn on highlighting
yield toggleHighlightAndWait(true);
yield closeFindbarAndWait();
});
let part2 = Task.async(function* () {
// Take snapshot of highlighting
findSnapshot = snapshotWindow(gWin);
// Now, remove the highlighting, and take a snapshot to compare
// to our original state
gFindBar.open();
yield toggleHighlightAndWait(false);
yield closeFindbarAndWait();
});
let part3 = Task.async(function* () {
var unhighlightSnapshot = snapshotWindow(gWin);
// Select the matches that should have been highlighted manually
var doc = gBrowser.contentDocument;
// Create a manual highlight in the visible iframe to test bug 451286
var iframe = doc.getElementById("visible");
var ifBody = iframe.contentDocument.body;
var range = iframe.contentDocument.createRange();
range.selectNodeContents(ifBody.childNodes[0]);
var ifWindow = iframe.contentWindow;
var ifDocShell = ifWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShell);
var ifController = ifDocShell.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsISelectionDisplay)
.QueryInterface(Ci.nsISelectionController);
var frameFindSelection =
ifController.getSelection(ifController.SELECTION_FIND);
frameFindSelection.addRange(range);
// Create manual highlights in the main document (the matches that lie
// before/after the iframes
var docShell = gWin.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShell);
var controller = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsISelectionDisplay)
.QueryInterface(Ci.nsISelectionController);
var 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
var manualSnapshot = snapshotWindow(gBrowser.contentWindow);
// Test 1: Were the matches in iframe correctly highlighted?
var 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");
});
]]></script>
<browser type="content-primary" flex="1" id="content" src="about:blank"/>
<findbar id="FindToolbar" browserid="content"/>
</window>

Просмотреть файл

@ -11,7 +11,6 @@ support-files =
bug366992_window.xul
bug409624_window.xul
bug429723_window.xul
bug451286_window.xul
bug624329_window.xul
dialog_dialogfocus.xul
file_about_networking_wsh.py
@ -76,7 +75,6 @@ skip-if = buildapp == 'mulet'
[test_bug418874.xul]
[test_bug429723.xul]
[test_bug437844.xul]
[test_bug451286.xul]
[test_bug457632.xul]
[test_bug460942.xul]
[test_bug471776.xul]

Просмотреть файл

@ -1,56 +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=451286
-->
<window title="Mozilla Bug 451286"
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/WindowSnapshot.js"></script>
<body xmlns="http://www.w3.org/1999/xhtml">
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=451286">
Mozilla Bug 451286
</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
</pre>
</body>
<script class="testbody" type="application/javascript">
<![CDATA[
// To be called by the window we open.
function parentFinish() {
// This is called with JS code from the window we open on the
// stack. We need to GC everything in that window, so do that
// from a timeout and then call SimpleTest.finish().
setTimeout(doFinish, 0);
}
function doFinish() {
// Garbage collect objects created in this test can cause
// assertions, so GC now to blame those assertions to this test.
SpecialPowers.gc();
SimpleTest.finish();
}
/** Test for Bug 451286 **/
SimpleTest.waitForExplicitFinish();
window.open("bug451286_window.xul", "451286test",
"chrome,width=600,height=600");
]]>
</script>
</window>

Просмотреть файл

@ -89,8 +89,10 @@ RemoteFinder.prototype = {
// Don't let one callback throwing stop us calling the rest
try {
l[callback].apply(l, params);
}
catch (e) {
} catch (e) {
if (!l[callback]) {
Cu.reportError(`Missing ${callback} callback on RemoteFinderListener`);
}
Cu.reportError(e);
}
}