зеркало из https://github.com/mozilla/gecko-dev.git
Merge m-c to inbound. a=merge
This commit is contained in:
Коммит
1144ba9c95
|
@ -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=Can’t 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 that’s 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}} doesn’t 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=We’re having technical difficulties…
|
||||
|
||||
generic_failure_no_reason2=Would you like to try again?
|
||||
|
||||
|
|
|
@ -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=Don’t show this message when pop-ups are blocked
|
||||
popupWarningDontShowFromLocationbar=Don’t 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=What’s 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=Don’t 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
Двоичные данные
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
Двоичные данные
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 doesn’t 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 isn’t 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 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’
|
||||
# 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 frame’s 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 don’t 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 snapshot’s 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 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.
|
||||
|
||||
# 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=Can’t 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=Can’t 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 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.
|
||||
|
||||
# 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 "Can’t 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=Can’t install project. Not fully connected.
|
||||
error_cantInstallValidationErrors=Can’t install project. Validation errors.
|
||||
error_listRunningApps=Can’t 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=Can’t connect to app: %1$S
|
||||
|
||||
# Variable: error message (in english)
|
||||
error_cantFetchAddonsJSON=Can't fetch the add-on list: %S
|
||||
error_cantFetchAddonsJSON=Can’t 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 you’ve 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 won’t 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=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)
|
||||
|
||||
# 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’ doesn’t 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=Can’t 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=Can’t convert “%S” to a number.
|
||||
typesNumberNotInt2=Can’t convert “%S” to an integer.
|
||||
typesDateNan=Can’t 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=Can’t 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=Can’t 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 page’s 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);
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче