Merge mozilla-central to mozilla-inbound

This commit is contained in:
Carsten "Tomcat" Book 2016-03-01 15:25:31 +01:00
commit 30e5302af8
240 changed files with 4159 additions and 3593 deletions

View File

@ -1328,12 +1328,6 @@ pref("services.sync.prefs.sync.signon.rememberSignons", true);
pref("services.sync.prefs.sync.spellchecker.dictionary", true);
pref("services.sync.prefs.sync.xpinstall.whitelist.required", true);
#ifdef NIGHTLY_BUILD
pref("services.sync.syncedTabsUIRefresh", true);
#else
pref("services.sync.syncedTabsUIRefresh", false);
#endif
// A preference that controls whether we should show the icon for a remote tab.
// This pref has no UI but exists because some people may be concerned that
// fetching these icons to show remote tabs may leak information about that

View File

@ -190,7 +190,6 @@
<broadcaster id="sync-reauth-state" hidden="true"/>
<broadcaster id="viewTabsSidebar" autoCheck="false" sidebartitle="&syncedTabs.sidebar.label;"
type="checkbox" group="sidebar"
hidden="true"
sidebarurl="chrome://browser/content/syncedtabs/sidebar.xhtml"
oncommand="SidebarUI.toggle('viewTabsSidebar');"/>
<broadcaster id="workOfflineMenuitemState"/>

View File

@ -81,12 +81,6 @@ var gSyncUI = {
let broadcaster = document.getElementById("sync-status");
broadcaster.setAttribute("label", this._stringBundle.GetStringFromName("syncnow.label"));
// Initialize the Synced Tabs Sidebar
if (Services.prefs.getBoolPref("services.sync.syncedTabsUIRefresh")) {
let sidebarBroadcaster = document.getElementById("viewTabsSidebar");
sidebarBroadcaster.removeAttribute("hidden");
}
this.maybeMoveSyncedTabsButton();
this.updateUI();

View File

@ -6452,11 +6452,7 @@ function checkEmptyPageOrigin(browser = gBrowser.selectedBrowser,
}
function BrowserOpenSyncTabs() {
if (Services.prefs.getBoolPref("services.sync.syncedTabsUIRefresh")) {
gSyncUI.openSyncedTabsPanel();
} else {
switchToTabHavingURI("about:sync-tabs", true);
}
gSyncUI.openSyncedTabsPanel();
}
/**

View File

@ -69,6 +69,8 @@
<script type="application/javascript" src="chrome://global/content/contentAreaUtils.js"/>
<script type="application/javascript" src="chrome://browser/content/downloads/downloads.js"/>
<script type="application/javascript" src="chrome://browser/content/downloads/indicator.js"/>
<script type="application/javascript" src="chrome://browser/content/places/editBookmarkOverlay.js"/>
# All sets except for popupsets (commands, keys, stringbundles and broadcasters) *must* go into the

View File

@ -7,8 +7,6 @@
<script type="application/javascript" src="chrome://global/content/viewZoomOverlay.js"/>
<script type="application/javascript" src="chrome://browser/content/places/browserPlacesViews.js"/>
<script type="application/javascript" src="chrome://browser/content/browser.js"/>
<script type="application/javascript" src="chrome://browser/content/downloads/downloads.js"/>
<script type="application/javascript" src="chrome://browser/content/downloads/indicator.js"/>
<script type="application/javascript" src="chrome://browser/content/customizableui/panelUI.js"/>
<script type="application/javascript" src="chrome://global/content/inlineSpellCheckUI.js"/>
<script type="application/javascript" src="chrome://global/content/viewSourceUtils.js"/>

View File

@ -295,7 +295,11 @@ Site.prototype = {
_speculativeConnect: function Site_speculativeConnect() {
let sc = Services.io.QueryInterface(Ci.nsISpeculativeConnect);
let uri = Services.io.newURI(this.url, null, null);
sc.speculativeConnect(uri, null);
try {
// This can throw for certain internal URLs, when they wind up in
// about:newtab. Be sure not to propagate the error.
sc.speculativeConnect(uri, null);
} catch (e) {}
},
/**

View File

@ -65,11 +65,6 @@ SocialErrorListener = {
},
receiveMessage(message) {
if (!content) {
Cu.reportError("Message received whilst `content` is null: " + message.name);
return;
}
let document = content.document;
switch (message.name) {

View File

@ -518,7 +518,6 @@ tags = mcb
[browser_bug1024133-switchtab-override-keynav.js]
[browser_bug1025195_switchToTabHavingURI_aOpenParams.js]
[browser_addCertException.js]
skip-if = e10s # Bug 1100687 - test directly manipulates content (content.document.getElementById)
[browser_bug1045809.js]
tags = mcb
[browser_bug1225194-remotetab.js]
@ -528,7 +527,6 @@ tags = mcb
[browser_e10s_javascript.js]
[browser_blockHPKP.js]
tags = psm
skip-if = e10s # bug 1100687 - test directly manipulates content (content.document.getElementById)
[browser_mcb_redirect.js]
tags = mcb
[browser_windowactivation.js]

View File

@ -16,34 +16,17 @@ function test() {
// Attempt to load https://expired.example.com (which has an expired cert).
function loadBadCertPage() {
gBrowser.addProgressListener(certErrorProgressListener);
gBrowser.selectedBrowser.loadURI("https://expired.example.com");
Services.obs.addObserver(certExceptionDialogObserver,
"cert-exception-ui-ready", false);
let startedLoad = BrowserTestUtils.loadURI(gBrowser.selectedBrowser,
"https://expired.example.com");
startedLoad.then(() => promiseErrorPageLoaded(gBrowser.selectedBrowser)).then(function() {
ContentTask.spawn(gBrowser.selectedBrowser, null, function*() {
content.document.getElementById("exceptionDialogButton").click();
});
});
}
// The browser should load about:certerror. When This happens, click the
// button to open the certificate exception dialog.
var certErrorProgressListener = {
buttonClicked: false,
onStateChange: function(aWebProgress, aRequest, aStateFlags, aStatus) {
if (aStateFlags & Ci.nsIWebProgressListener.STATE_STOP) {
let self = this;
// Can't directly call button.click() in onStateChange
executeSoon(function() {
let button = content.document.getElementById("exceptionDialogButton");
// If about:certerror hasn't fully loaded, the button won't be present.
// It will eventually be there, however.
if (button && !self.buttonClicked) {
gBrowser.removeProgressListener(self);
Services.obs.addObserver(certExceptionDialogObserver,
"cert-exception-ui-ready", false);
button.click();
}
});
}
}
};
// When the certificate exception dialog has opened, click the button to add
// an exception.
const EXCEPTION_DIALOG_URI = "chrome://pippki/content/exceptionDialog.xul";
@ -54,9 +37,7 @@ var certExceptionDialogObserver = {
let certExceptionDialog = getDialog(EXCEPTION_DIALOG_URI);
ok(certExceptionDialog, "found exception dialog");
executeSoon(function() {
gBrowser.selectedBrowser.addEventListener("load",
successfulLoadListener,
true);
BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(realPageLoaded);
certExceptionDialog.documentElement.getButton("extra1").click();
});
}
@ -64,16 +45,12 @@ var certExceptionDialogObserver = {
};
// Finally, we should successfully load https://expired.example.com.
var successfulLoadListener = {
handleEvent: function() {
gBrowser.selectedBrowser.removeEventListener("load", this, true);
checkControlPanelIcons();
let certOverrideService = Cc["@mozilla.org/security/certoverride;1"]
.getService(Ci.nsICertOverrideService);
certOverrideService.clearValidityOverride("expired.example.com", -1);
gBrowser.removeTab(gBrowser.selectedTab);
finish();
}
function realPageLoaded() {
checkControlPanelIcons();
let certOverrideService = Cc["@mozilla.org/security/certoverride;1"]
.getService(Ci.nsICertOverrideService);
certOverrideService.clearValidityOverride("expired.example.com", -1);
BrowserTestUtils.removeTab(gBrowser.selectedTab).then(finish);
};
// Check for the correct icons in the identity box and control center.
@ -82,7 +59,7 @@ function checkControlPanelIcons() {
gIdentityHandler._identityBox.click();
document.getElementById("identity-popup-security-expander").click();
is_element_visible(document.getElementById("connection-icon"));
is_element_visible(document.getElementById("connection-icon"), "Should see connection icon");
let connectionIconImage = gBrowser.ownerGlobal
.getComputedStyle(document.getElementById("connection-icon"), "")
.getPropertyValue("list-style-image");

View File

@ -49,11 +49,12 @@ function test() {
// Start by making a successful connection to a domain that will pin a site
function loadPinningPage() {
gBrowser.selectedBrowser.addEventListener("load",
successfulPinningPageListener,
true);
gBrowser.selectedBrowser.loadURI("https://" + kPinningDomain + kURLPath + "valid");
BrowserTestUtils.loadURI(gBrowser.selectedBrowser, "https://" + kPinningDomain + kURLPath + "valid").then(function() {
gBrowser.selectedBrowser.addEventListener("load",
successfulPinningPageListener,
true);
});
}
// After the site is pinned try to load with a subdomain site that should
@ -61,49 +62,40 @@ function loadPinningPage() {
var successfulPinningPageListener = {
handleEvent: function() {
gBrowser.selectedBrowser.removeEventListener("load", this, true);
gBrowser.addProgressListener(certErrorProgressListener);
gBrowser.selectedBrowser.loadURI("https://" + kBadPinningDomain);
BrowserTestUtils.loadURI(gBrowser.selectedBrowser, "https://" + kBadPinningDomain).then(function() {
return promiseErrorPageLoaded(gBrowser.selectedBrowser);
}).then(errorPageLoaded);
}
};
// The browser should load about:neterror, when this happens, proceed
// to load the pinning domain again, this time removing the pinning information
var certErrorProgressListener = {
onStateChange: function(aWebProgress, aRequest, aStateFlags, aStatus) {
if (aStateFlags & Ci.nsIWebProgressListener.STATE_STOP) {
let textElement = content.document.getElementById("errorShortDescText");
let text = textElement.innerHTML;
ok(text.indexOf("MOZILLA_PKIX_ERROR_KEY_PINNING_FAILURE") > 0,
"Got a pinning error page");
gBrowser.removeProgressListener(this);
gBrowser.selectedBrowser.addEventListener("load",
successfulPinningRemovalPageListener,
true);
gBrowser.selectedBrowser.loadURI("https://" + kPinningDomain + kURLPath + "zeromaxagevalid");
}
}
function errorPageLoaded() {
ContentTask.spawn(gBrowser.selectedBrowser, null, function*() {
let textElement = content.document.getElementById("errorShortDescText");
let text = textElement.innerHTML;
ok(text.indexOf("MOZILLA_PKIX_ERROR_KEY_PINNING_FAILURE") > 0,
"Got a pinning error page");
}).then(function() {
BrowserTestUtils.loadURI(gBrowser.selectedBrowser, "https://" + kPinningDomain + kURLPath + "zeromaxagevalid").then(function() {
return BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
}).then(pinningRemovalLoaded);
});
};
// After the pinning information has been removed (successful load) proceed
// to load again with the invalid pin domain.
var successfulPinningRemovalPageListener = {
handleEvent: function() {
gBrowser.selectedBrowser.removeEventListener("load", this, true);
gBrowser.selectedBrowser.addEventListener("load",
successfulLoadListener,
true);
gBrowser.selectedBrowser.loadURI("https://" + kBadPinningDomain);
}
function pinningRemovalLoaded() {
BrowserTestUtils.loadURI(gBrowser.selectedBrowser, "https://" + kBadPinningDomain).then(function() {
return BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
}).then(badPinningPageLoaded);
};
// Finally, we should successfully load
// https://bad.include-subdomains.pinning-dynamic.example.com.
var successfulLoadListener = {
handleEvent: function() {
gBrowser.selectedBrowser.removeEventListener("load", this, true);
gBrowser.removeTab(gBrowser.selectedTab);
function badPinningPageLoaded() {
BrowserTestUtils.removeTab(gBrowser.selectedTab).then(function() {
ok(true, "load complete");
finish();
}
});
};

View File

@ -9,6 +9,8 @@ const XPINSTALL_URL = "chrome://mozapps/content/xpinstall/xpinstallConfirm.xul";
const PREF_INSTALL_REQUIREBUILTINCERTS = "extensions.install.requireBuiltInCerts";
const PROGRESS_NOTIFICATION = "addon-progress";
const { REQUIRE_SIGNING } = Cu.import("resource://gre/modules/addons/AddonConstants.jsm", {});
var rootDir = getRootDirectory(gTestPath);
var path = rootDir.split('/');
var chromeName = path[0] + '//' + path[2];
@ -205,7 +207,7 @@ function test_disabled_install() {
});
var triggers = encodeURIComponent(JSON.stringify({
"XPI": "unsigned.xpi"
"XPI": "amosigned.xpi"
}));
gBrowser.selectedTab = gBrowser.addTab();
gBrowser.loadURI(TESTROOT + "installtrigger.html?" + triggers);
@ -254,7 +256,7 @@ function test_blocked_install() {
});
var triggers = encodeURIComponent(JSON.stringify({
"XPI": "unsigned.xpi"
"XPI": "amosigned.xpi"
}));
gBrowser.selectedTab = gBrowser.addTab();
gBrowser.loadURI(TESTROOT + "installtrigger.html?" + triggers);
@ -296,7 +298,7 @@ function test_whitelisted_install() {
pm.add(makeURI("http://example.com/"), "install", pm.ALLOW_ACTION);
var triggers = encodeURIComponent(JSON.stringify({
"XPI": "unsigned.xpi"
"XPI": "amosigned.xpi"
}));
let originalTab = gBrowser.selectedTab;
let tab = gBrowser.addTab();
@ -458,7 +460,7 @@ function test_multiple() {
pm.add(makeURI("http://example.com/"), "install", pm.ALLOW_ACTION);
var triggers = encodeURIComponent(JSON.stringify({
"Unsigned XPI": "unsigned.xpi",
"Unsigned XPI": "amosigned.xpi",
"Restartless XPI": "restartless.xpi"
}));
gBrowser.selectedTab = gBrowser.addTab();
@ -547,7 +549,8 @@ function test_someunverified() {
// This test is only relevant if using the new doorhanger UI and allowing
// unsigned add-ons
if (!Preferences.get("xpinstall.customConfirmationUI", false) ||
Preferences.get("xpinstall.signatures.required", true)) {
Preferences.get("xpinstall.signatures.required", true) ||
REQUIRE_SIGNING) {
runNextTest();
return;
}
@ -593,7 +596,7 @@ function test_someunverified() {
pm.add(makeURI("http://example.com/"), "install", pm.ALLOW_ACTION);
var triggers = encodeURIComponent(JSON.stringify({
"Extension XPI": "restartless.xpi",
"Extension XPI": "restartless-unsigned.xpi",
"Theme XPI": "theme.xpi"
}));
gBrowser.selectedTab = gBrowser.addTab();
@ -604,7 +607,8 @@ function test_allunverified() {
// This test is only relevant if using the new doorhanger UI and allowing
// unsigned add-ons
if (!Preferences.get("xpinstall.customConfirmationUI", false) ||
Preferences.get("xpinstall.signatures.required", true)) {
Preferences.get("xpinstall.signatures.required", true) ||
REQUIRE_SIGNING) {
runNextTest();
return;
}
@ -641,7 +645,7 @@ function test_allunverified() {
pm.add(makeURI("http://example.com/"), "install", pm.ALLOW_ACTION);
var triggers = encodeURIComponent(JSON.stringify({
"Extension XPI": "restartless.xpi"
"Extension XPI": "restartless-unsigned.xpi"
}));
gBrowser.selectedTab = gBrowser.addTab();
gBrowser.loadURI(TESTROOT + "installtrigger.html?" + triggers);
@ -675,7 +679,7 @@ function test_url() {
gBrowser.selectedTab = gBrowser.addTab("about:blank");
BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(() => {
gBrowser.loadURI(TESTROOT + "unsigned.xpi");
gBrowser.loadURI(TESTROOT + "amosigned.xpi");
});
},
@ -737,7 +741,7 @@ function test_tabclose() {
gBrowser.selectedTab = gBrowser.addTab("about:blank");
BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(() => {
gBrowser.loadURI(TESTROOT + "unsigned.xpi");
gBrowser.loadURI(TESTROOT + "amosigned.xpi");
});
},
@ -774,7 +778,7 @@ function test_tabnavigate() {
pm.add(makeURI("http://example.com/"), "install", pm.ALLOW_ACTION);
var triggers = encodeURIComponent(JSON.stringify({
"Extension XPI": "unsigned.xpi"
"Extension XPI": "amosigned.xpi"
}));
gBrowser.selectedTab = gBrowser.addTab();
gBrowser.loadURI(TESTROOT + "installtrigger.html?" + triggers);
@ -795,7 +799,7 @@ function test_urlbar() {
gBrowser.selectedTab = gBrowser.addTab("about:blank");
BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(() => {
gURLBar.value = TESTROOT + "unsigned.xpi";
gURLBar.value = TESTROOT + "amosigned.xpi";
gURLBar.focus();
EventUtils.synthesizeKey("VK_RETURN", {});
});
@ -869,7 +873,7 @@ function test_reload() {
pm.add(makeURI("http://example.com/"), "install", pm.ALLOW_ACTION);
var triggers = encodeURIComponent(JSON.stringify({
"Unsigned XPI": "unsigned.xpi"
"Unsigned XPI": "amosigned.xpi"
}));
gBrowser.selectedTab = gBrowser.addTab();
gBrowser.loadURI(TESTROOT + "installtrigger.html?" + triggers);
@ -951,7 +955,7 @@ function test_renotify_blocked() {
});
var triggers = encodeURIComponent(JSON.stringify({
"XPI": "unsigned.xpi"
"XPI": "amosigned.xpi"
}));
gBrowser.selectedTab = gBrowser.addTab();
gBrowser.loadURI(TESTROOT + "installtrigger.html?" + triggers);
@ -1006,7 +1010,7 @@ function test_renotify_installed() {
pm.add(makeURI("http://example.com/"), "install", pm.ALLOW_ACTION);
var triggers = encodeURIComponent(JSON.stringify({
"XPI": "unsigned.xpi"
"XPI": "amosigned.xpi"
}));
gBrowser.selectedTab = gBrowser.addTab();
gBrowser.loadURI(TESTROOT + "installtrigger.html?" + triggers);
@ -1064,7 +1068,7 @@ function test_cancel() {
pm.add(makeURI("http://example.com/"), "install", pm.ALLOW_ACTION);
var triggers = encodeURIComponent(JSON.stringify({
"XPI": "slowinstall.sjs?file=unsigned.xpi"
"XPI": "slowinstall.sjs?file=amosigned.xpi"
}));
gBrowser.selectedTab = gBrowser.addTab();
gBrowser.loadURI(TESTROOT + "installtrigger.html?" + triggers);
@ -1074,7 +1078,7 @@ function test_failed_security() {
Services.prefs.setBoolPref(PREF_INSTALL_REQUIREBUILTINCERTS, false);
setup_redirect({
"Location": TESTROOT + "unsigned.xpi"
"Location": TESTROOT + "amosigned.xpi"
});
// Wait for the blocked notification

View File

@ -165,15 +165,6 @@ function createReportResponseStatusPromise(expectedURI) {
});
}
function promiseErrorPageLoaded(browser) {
return new Promise(resolve => {
browser.addEventListener("DOMContentLoaded", function onLoad() {
browser.removeEventListener("DOMContentLoaded", onLoad, false, true);
resolve();
}, false, true);
});
}
function checkErrorPage(browser, suffix) {
return ContentTask.spawn(browser, null, function* () {
return content.document.documentURI;

View File

@ -77,16 +77,16 @@ var tests = [
// Test escaping
{
loadURL: "http://example.com/()%C3%A9",
expectedURL: "example.com/()\xe9",
copyExpected: "http://example.com/%28%29%C3%A9"
loadURL: "http://example.com/()%28%29%C3%A9",
expectedURL: "example.com/()()\xe9",
copyExpected: "http://example.com/()%28%29%C3%A9"
},
{
copyVal: "<example.com/(>)\xe9",
copyVal: "<example.com/(>)()\xe9",
copyExpected: "http://example.com/("
},
{
copyVal: "e<xample.com/(>)\xe9",
copyVal: "e<xample.com/(>)()\xe9",
copyExpected: "xample.com/("
},

View File

@ -958,12 +958,12 @@ function is_visible(element) {
function is_element_visible(element, msg) {
isnot(element, null, "Element should not be null, when checking visibility");
ok(is_visible(element), msg);
ok(is_visible(element), msg || "Element should be visible");
}
function is_element_hidden(element, msg) {
isnot(element, null, "Element should not be null, when checking visibility");
ok(is_hidden(element), msg);
ok(is_hidden(element), msg || "Element should be hidden");
}
function promisePopupEvent(popup, eventSuffix) {
@ -1215,3 +1215,12 @@ function promiseCrashReport(expectedExtra={}) {
}
});
}
function promiseErrorPageLoaded(browser) {
return new Promise(resolve => {
browser.addEventListener("DOMContentLoaded", function onLoad() {
browser.removeEventListener("DOMContentLoaded", onLoad, false, true);
resolve();
}, false, true);
});
}

View File

@ -601,11 +601,16 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
let uriFixup = Cc["@mozilla.org/docshell/urifixup;1"].getService(Ci.nsIURIFixup);
let uri;
try {
uri = uriFixup.createFixupURI(inputVal, Ci.nsIURIFixup.FIXUP_FLAG_NONE);
} catch (e) {}
if (!uri)
return selectedVal;
if (this.getAttribute("pageproxystate") == "valid") {
uri = gBrowser.currentURI;
} else {
// We're dealing with an autocompleted value, create a new URI from that.
try {
uri = uriFixup.createFixupURI(inputVal, Ci.nsIURIFixup.FIXUP_FLAG_NONE);
} catch (e) {}
if (!uri)
return selectedVal;
}
// Only copy exposable URIs
try {
@ -617,8 +622,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
// ... but only if isn't a javascript: or data: URI, since those
// are hard to read when encoded
if (!uri.schemeIs("javascript") && !uri.schemeIs("data")) {
// Parentheses are known to confuse third-party applications (bug 458565).
selectedVal = uri.spec.replace(/[()]/g, c => escape(c));
selectedVal = uri.spec;
}
return selectedVal;

View File

@ -31,10 +31,6 @@ pref("app.update.checkInstallTime.days", 2);
// button. default=4 days
pref("app.update.badgeWaitTime", 345600);
// code usage depends on contracts, please contact the Firefox module owner if you have questions
pref("browser.search.param.yahoo-fr", "moz35");
pref("browser.search.param.yahoo-fr-ja", "mozff");
// Number of usages of the web console or scratchpad.
// If this is less than 5, then pasting code into the web console or scratchpad is disabled
pref("devtools.selfxss.count", 5);

View File

@ -29,10 +29,6 @@ pref("app.update.checkInstallTime.days", 2);
// button. default=immediately
pref("app.update.badgeWaitTime", 0);
// code usage depends on contracts, please contact the Firefox module owner if you have questions
pref("browser.search.param.yahoo-fr", "moz35");
pref("browser.search.param.yahoo-fr-ja", "mozff");
// Number of usages of the web console or scratchpad.
// If this is less than 5, then pasting code into the web console or scratchpad is disabled
pref("devtools.selfxss.count", 5);

View File

@ -28,10 +28,6 @@ pref("app.update.checkInstallTime.days", 63);
// button. default=immediately
pref("app.update.badgeWaitTime", 0);
// code usage depends on contracts, please contact the Firefox module owner if you have questions
pref("browser.search.param.yahoo-fr", "moz35");
pref("browser.search.param.yahoo-fr-ja", "mozff");
// Number of usages of the web console or scratchpad.
// If this is less than 5, then pasting code into the web console or scratchpad is disabled
pref("devtools.selfxss.count", 0);

View File

@ -28,10 +28,6 @@ pref("app.update.checkInstallTime.days", 2);
// button. default=immediately
pref("app.update.badgeWaitTime", 0);
// code usage depends on contracts, please contact the Firefox module owner if you have questions
pref("browser.search.param.yahoo-fr", "moz35");
pref("browser.search.param.yahoo-fr-ja", "mozff");
// Number of usages of the web console or scratchpad.
// If this is less than 5, then pasting code into the web console or scratchpad is disabled
pref("devtools.selfxss.count", 0);

View File

@ -246,13 +246,6 @@ const CustomizableWidgets = [
recentlyClosedWindows.removeChild(recentlyClosedWindows.firstChild);
}
let tabsFromOtherComputers = doc.getElementById("sync-tabs-menuitem2");
if (PlacesUIUtils.shouldShowTabsFromOtherComputersMenuitem()) {
tabsFromOtherComputers.removeAttribute("hidden");
} else {
tabsFromOtherComputers.setAttribute("hidden", true);
}
let utils = RecentlyClosedTabsAndWindowsMenuUtils;
let tabsFragment = utils.getTabsFragment(doc.defaultView, "toolbarbutton", true,
"menuRestoreAllTabsSubview.label");

View File

@ -84,11 +84,6 @@
label="&appMenuHistory.clearRecent.label;"
class="subviewbutton"
command="Tools:Sanitize"/>
<toolbarbutton id="sync-tabs-menuitem2"
class="syncTabsMenuItem subviewbutton"
label="&syncTabsMenu3.label;"
oncommand="BrowserOpenSyncTabs();"
hidden="true"/>
<toolbarbutton id="appMenuRestoreLastSession"
label="&appMenuHistory.restoreSession.label;"
class="subviewbutton"

View File

@ -51,9 +51,6 @@ skip-if = os == "linux"
# Because this test is about the menubar, it can't be run on mac
skip-if = os == "mac"
[browser_946320_tabs_from_other_computers.js]
skip-if = os == "linux"
[browser_934951_zoom_in_toolbar.js]
[browser_938980_navbar_collapsed.js]
[browser_938995_indefaultstate_nonremovable.js]

View File

@ -1,144 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
var Preferences = Cu.import("resource://gre/modules/Preferences.jsm", {}).Preferences;
const {FxAccounts, AccountState} = Cu.import("resource://gre/modules/FxAccounts.jsm", {});
// FxA logs can be gotten at via this pref which helps debugging.
Preferences.set("services.sync.log.appender.dump", "Debug");
add_task(function*() {
yield PanelUI.show({type: "command"});
let historyButton = document.getElementById("history-panelmenu");
let historySubview = document.getElementById("PanelUI-history");
let subviewShownPromise = subviewShown(historySubview);
historyButton.click();
yield subviewShownPromise;
let tabsFromOtherComputers = document.getElementById("sync-tabs-menuitem2");
is(tabsFromOtherComputers.hidden, true, "The Tabs From Other Computers menuitem should be hidden when sync isn't enabled.");
let hiddenPanelPromise = promisePanelHidden(window);
PanelUI.hide();
yield hiddenPanelPromise;
// Part 2 - When Sync is enabled the menuitem should be shown.
yield configureIdentity();
yield PanelUI.show({type: "command"});
subviewShownPromise = subviewShown(historySubview);
historyButton.click();
yield subviewShownPromise;
is(tabsFromOtherComputers.hidden, false, "The Tabs From Other Computers menuitem should be shown when sync is enabled.");
let syncPrefBranch = new Preferences("services.sync.");
syncPrefBranch.resetBranch("");
Services.logins.removeAllLogins();
hiddenPanelPromise = promisePanelHidden(window);
PanelUI.toggle({type: "command"});
yield hiddenPanelPromise;
yield fxAccounts.signOut(/*localOnly = */true);
});
function configureIdentity() {
// do the FxAccounts thang and wait for Sync to initialize the identity.
configureFxAccountIdentity();
return Weave.Service.identity.initializeWithCurrentIdentity().then(() => {
// need to wait until this identity manager is readyToAuthenticate.
return Weave.Service.identity.whenReadyToAuthenticate.promise;
});
}
// Configure an instance of an FxAccount identity provider.
function configureFxAccountIdentity() {
// A mock "storage manager" for FxAccounts that doesn't actually write anywhere.
function MockFxaStorageManager() {
}
MockFxaStorageManager.prototype = {
promiseInitialized: Promise.resolve(),
initialize(accountData) {
this.accountData = accountData;
},
finalize() {
return Promise.resolve();
},
getAccountData() {
return Promise.resolve(this.accountData);
},
updateAccountData(updatedFields) {
for (let [name, value] of Iterator(updatedFields)) {
if (value == null) {
delete this.accountData[name];
} else {
this.accountData[name] = value;
}
}
return Promise.resolve();
},
deleteAccountData() {
this.accountData = null;
return Promise.resolve();
}
}
let user = {
assertion: "assertion",
email: "email",
kA: "kA",
kB: "kB",
sessionToken: "sessionToken",
uid: "user_uid",
verified: true,
};
let token = {
endpoint: null,
duration: 300,
id: "id",
key: "key",
// uid will be set to the username.
};
let MockInternal = {
newAccountState(credentials) {
isnot(credentials, "not expecting credentials");
let storageManager = new MockFxaStorageManager();
// and init storage with our user.
storageManager.initialize(user);
return new AccountState(storageManager);
},
_getAssertion(audience) {
return Promise.resolve("assertion");
},
getCertificateSigned() {
return Promise.resolve();
},
};
let mockTSC = { // TokenServerClient
getTokenFromBrowserIDAssertion: function(uri, assertion, cb) {
token.uid = "username";
cb(null, token);
},
};
let fxa = new FxAccounts(MockInternal);
Weave.Service.identity._fxaService = fxa;
Weave.Service.identity._tokenServerClient = mockTSC;
// Set the "account" of the browserId manager to be the "email" of the
// logged in user of the mockFXA service.
Weave.Service.identity._account = user.email;
}

View File

@ -351,7 +351,7 @@ DistributionCustomizer.prototype = {
if (sections["Preferences"]) {
for (let key of enumerate(this._ini.getKeys("Preferences"))) {
try {
let value = eval(this._ini.getString("Preferences", key));
let value = parseValue(this._ini.getString("Preferences", key));
switch (typeof value) {
case "boolean":
defaults.setBoolPref(key, value);
@ -382,7 +382,7 @@ DistributionCustomizer.prototype = {
if (sections["LocalizablePreferences-" + this._locale]) {
for (let key of enumerate(this._ini.getKeys("LocalizablePreferences-" + this._locale))) {
try {
let value = eval(this._ini.getString("LocalizablePreferences-" + this._locale, key));
let value = parseValue(this._ini.getString("LocalizablePreferences-" + this._locale, key));
if (value !== undefined) {
localizedStr.data = "data:text/plain," + key + "=" + value;
defaults.setComplexValue(key, Ci.nsIPrefLocalizedString, localizedStr);
@ -398,7 +398,7 @@ DistributionCustomizer.prototype = {
continue;
}
try {
let value = eval(this._ini.getString("LocalizablePreferences-" + this._language, key));
let value = parseValue(this._ini.getString("LocalizablePreferences-" + this._language, key));
if (value !== undefined) {
localizedStr.data = "data:text/plain," + key + "=" + value;
defaults.setComplexValue(key, Ci.nsIPrefLocalizedString, localizedStr);
@ -414,7 +414,7 @@ DistributionCustomizer.prototype = {
continue;
}
try {
let value = eval(this._ini.getString("LocalizablePreferences", key));
let value = parseValue(this._ini.getString("LocalizablePreferences", key));
if (value !== undefined) {
value = value.replace(/%LOCALE%/g, this._locale);
value = value.replace(/%LANGUAGE%/g, this._language);
@ -458,6 +458,19 @@ DistributionCustomizer.prototype = {
}
};
function parseValue(value) {
try {
value = JSON.parse(value);
} catch (e) {
// JSON.parse catches numbers and booleans.
// Anything else, we assume is a string.
// Remove the quotes that aren't needed anymore.
value = value.replace(/^"/, "");
value = value.replace(/"$/, "");
}
return value;
}
function* enumerate(UTF8Enumerator) {
while (UTF8Enumerator.hasMore())
yield UTF8Enumerator.getNext();

View File

@ -24,7 +24,15 @@ XPCOMUtils.defineLazyModuleGetter(this, "DownloadsCommon",
XPCOMUtils.defineLazyModuleGetter(this, "OS",
"resource://gre/modules/osfile.jsm");
this.DownloadsViewUI = {};
this.DownloadsViewUI = {
/**
* Returns true if the given string is the name of a command that can be
* handled by the Downloads user interface, including standard commands.
*/
isCommandName(name) {
return name.startsWith("cmd_") || name.startsWith("downloadsCmd_");
},
};
/**
* A download element shell is responsible for handling the commands and the
@ -159,7 +167,6 @@ this.DownloadsViewUI.DownloadElementShell.prototype = {
* Derived objects may call this to get the status text.
*/
get rawStatusTextAndTip() {
const nsIDM = Ci.nsIDownloadManager;
let s = DownloadsCommon.strings;
let text = "";
@ -231,4 +238,73 @@ this.DownloadsViewUI.DownloadElementShell.prototype = {
return { text, tip: tip || text };
},
/**
* Returns the name of the default command to use for the current state of the
* download, when there is a double click or another default interaction. If
* there is no default command for the current state, returns an empty string.
* The commands are implemented as functions on this object or derived ones.
*/
get currentDefaultCommandName() {
switch (DownloadsCommon.stateOfDownload(this.download)) {
case Ci.nsIDownloadManager.DOWNLOAD_NOTSTARTED:
return "downloadsCmd_cancel";
case Ci.nsIDownloadManager.DOWNLOAD_FAILED:
case Ci.nsIDownloadManager.DOWNLOAD_CANCELED:
return "downloadsCmd_retry";
case Ci.nsIDownloadManager.DOWNLOAD_PAUSED:
return "downloadsCmd_pauseResume";
case Ci.nsIDownloadManager.DOWNLOAD_FINISHED:
return "downloadsCmd_open";
case Ci.nsIDownloadManager.DOWNLOAD_BLOCKED_PARENTAL:
case Ci.nsIDownloadManager.DOWNLOAD_DIRTY:
return "downloadsCmd_openReferrer";
}
return "";
},
/**
* Returns true if the specified command can be invoked on the current item.
* The commands are implemented as functions on this object or derived ones.
*
* @param aCommand
* Name of the command to check, for example "downloadsCmd_retry".
*/
isCommandEnabled(aCommand) {
switch (aCommand) {
case "downloadsCmd_retry":
return this.download.canceled || this.download.error;
case "downloadsCmd_pauseResume":
return this.download.hasPartialData && !this.download.error;
case "downloadsCmd_openReferrer":
return !!this.download.source.referrer;
case "downloadsCmd_confirmBlock":
case "downloadsCmd_unblock":
return this.download.hasBlockedData;
}
return false;
},
downloadsCmd_cancel() {
// This is the correct way to avoid race conditions when cancelling.
this.download.cancel().catch(() => {});
this.download.removePartialData().catch(Cu.reportError);
},
downloadsCmd_retry() {
// Errors when retrying are already reported as download failures.
this.download.start().catch(() => {});
},
downloadsCmd_pauseResume() {
if (this.download.stopped) {
this.download.start();
} else {
this.download.cancel();
}
},
downloadsCmd_confirmBlock() {
this.download.confirmBlock().catch(Cu.reportError);
},
};

View File

@ -1,53 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
* The downloads richlistbox may list thousands of items, and it turns out
* XBL binding attachment, and even more so detachment, is a performance hog.
* This hack makes sure we don't apply any binding to inactive items (inactive
* items are history downloads that haven't been in the visible area).
* We can do this because the richlistbox implementation does not interact
* much with the richlistitem binding. However, this may turn out to have
* some side effects (see bug 828111 for the details).
*
* We might be able to do away with this workaround once bug 653881 is fixed.
*/
richlistitem.download {
-moz-binding: none;
}
richlistitem.download[active] {
-moz-binding: url('chrome://browser/content/downloads/download.xml#download-full-ui');
}
.download-state:not( [state="0"] /* Downloading */)
.downloadPauseMenuItem,
.download-state:not( [state="4"] /* Paused */)
.downloadResumeMenuItem,
.download-state:not(:-moz-any([state="2"], /* Failed */
[state="4"]) /* Paused */)
.downloadCancelMenuItem,
/* Blocked (dirty) downloads that have not been confirmed and
have temporary data. */
.download-state:not( [state="8"] /* Blocked (dirty) */)
.downloadUnblockMenuItem,
.download-state[state="8"]:not(.temporary-block)
.downloadUnblockMenuItem,
.download-state[state]:not(:-moz-any([state="1"], /* Finished */
[state="2"], /* Failed */
[state="3"], /* Canceled */
[state="6"], /* Blocked (parental) */
[state="8"], /* Blocked (dirty) */
[state="9"]) /* Blocked (policy) */)
.downloadRemoveFromHistoryMenuItem,
.download-state:not(:-moz-any([state="-1"],/* Starting (initial) */
[state="0"], /* Downloading */
[state="1"], /* Finished */
[state="4"], /* Paused */
[state="5"]) /* Starting (queued) */)
.downloadShowMenuItem,
.download-state[state="7"] .downloadCommandsSeparator
{
display: none;
}

View File

@ -34,12 +34,6 @@ const nsIDM = Ci.nsIDownloadManager;
const DESTINATION_FILE_URI_ANNO = "downloads/destinationFileURI";
const DOWNLOAD_META_DATA_ANNO = "downloads/metaData";
const DOWNLOAD_VIEW_SUPPORTED_COMMANDS =
["cmd_delete", "cmd_copy", "cmd_paste", "cmd_selectAll",
"downloadsCmd_pauseResume", "downloadsCmd_cancel", "downloadsCmd_unblock",
"downloadsCmd_confirmBlock", "downloadsCmd_open", "downloadsCmd_show",
"downloadsCmd_retry", "downloadsCmd_openReferrer", "downloadsCmd_clearDownloads"];
/**
* Represents a download from the browser history. It implements part of the
* interface of the Download object.
@ -317,7 +311,6 @@ HistoryDownloadElementShell.prototype = {
this._updateProgress();
},
/* nsIController */
isCommandEnabled(aCommand) {
// The only valid command for inactive elements is cmd_delete.
if (!this.active && aCommand != "cmd_delete") {
@ -338,86 +331,55 @@ HistoryDownloadElementShell.prototype = {
// This property is false if the download did not succeed.
return this.download.target.exists;
case "downloadsCmd_pauseResume":
return this.download.hasPartialData && !this.download.error;
case "downloadsCmd_retry":
return this.download.canceled || this.download.error;
case "downloadsCmd_openReferrer":
return !!this.download.source.referrer;
case "cmd_delete":
// We don't want in-progress downloads to be removed accidentally.
return this.download.stopped;
case "downloadsCmd_cancel":
return !!this._sessionDownload;
case "downloadsCmd_confirmBlock":
case "downloadsCmd_unblock":
return this.download.hasBlockedData;
}
return false;
return DownloadsViewUI.DownloadElementShell.prototype
.isCommandEnabled.call(this, aCommand);
},
/* nsIController */
doCommand(aCommand) {
switch (aCommand) {
case "downloadsCmd_open": {
let file = new FileUtils.File(this.download.target.path);
DownloadsCommon.openDownloadedFile(file, null, window);
break;
}
case "downloadsCmd_show": {
let file = new FileUtils.File(this.download.target.path);
DownloadsCommon.showDownloadedFile(file);
break;
}
case "downloadsCmd_openReferrer": {
openURL(this.download.source.referrer);
break;
}
case "downloadsCmd_cancel": {
this.download.cancel().catch(() => {});
this.download.removePartialData().catch(Cu.reportError);
break;
}
case "cmd_delete": {
if (this._sessionDownload) {
DownloadsCommon.removeAndFinalizeDownload(this.download);
}
if (this._historyDownload) {
let uri = NetUtil.newURI(this.download.source.url);
PlacesUtils.bhistory.removePage(uri);
}
break;
}
case "downloadsCmd_retry": {
// Errors when retrying are already reported as download failures.
this.download.start().catch(() => {});
break;
}
case "downloadsCmd_pauseResume": {
// This command is only enabled for session downloads.
if (this.download.stopped) {
this.download.start();
} else {
this.download.cancel();
}
break;
}
case "downloadsCmd_unblock": {
DownloadsCommon.confirmUnblockDownload(DownloadsCommon.BLOCK_VERDICT_MALWARE,
window).then((confirmed) => {
if (confirmed) {
return this.download.unblock();
}
}).catch(Cu.reportError);
break;
}
case "downloadsCmd_confirmBlock": {
this.download.confirmBlock().catch(Cu.reportError);
break;
}
if (DownloadsViewUI.isCommandName(aCommand)) {
this[aCommand]();
}
},
downloadsCmd_open() {
let file = new FileUtils.File(this.download.target.path);
DownloadsCommon.openDownloadedFile(file, null, window);
},
downloadsCmd_show() {
let file = new FileUtils.File(this.download.target.path);
DownloadsCommon.showDownloadedFile(file);
},
downloadsCmd_openReferrer() {
openURL(this.download.source.referrer);
},
cmd_delete() {
if (this._sessionDownload) {
DownloadsCommon.removeAndFinalizeDownload(this.download);
}
if (this._historyDownload) {
let uri = NetUtil.newURI(this.download.source.url);
PlacesUtils.bhistory.removePage(uri);
}
},
downloadsCmd_unblock() {
DownloadsCommon.confirmUnblockDownload(DownloadsCommon.BLOCK_VERDICT_MALWARE,
window).then((confirmed) => {
if (confirmed) {
return this.download.unblock();
}
}).catch(Cu.reportError);
},
// Returns whether or not the download handled by this shell should
// show up in the search results for the given term. Both the display
// name for the download and the url are searched.
@ -433,29 +395,7 @@ HistoryDownloadElementShell.prototype = {
// Handles return keypress on the element (the keypress listener is
// set in the DownloadsPlacesView object).
doDefaultCommand() {
function getDefaultCommandForState(aState) {
switch (aState) {
case nsIDM.DOWNLOAD_FINISHED:
return "downloadsCmd_open";
case nsIDM.DOWNLOAD_PAUSED:
return "downloadsCmd_pauseResume";
case nsIDM.DOWNLOAD_NOTSTARTED:
case nsIDM.DOWNLOAD_QUEUED:
return "downloadsCmd_cancel";
case nsIDM.DOWNLOAD_FAILED:
case nsIDM.DOWNLOAD_CANCELED:
return "downloadsCmd_retry";
case nsIDM.DOWNLOAD_SCANNING:
return "downloadsCmd_show";
case nsIDM.DOWNLOAD_BLOCKED_PARENTAL:
case nsIDM.DOWNLOAD_DIRTY:
case nsIDM.DOWNLOAD_BLOCKED_POLICY:
return "downloadsCmd_openReferrer";
}
return "";
}
let state = DownloadsCommon.stateOfDownload(this.download);
let command = getDefaultCommandForState(state);
let command = this.currentDefaultCommandName;
if (command && this.isCommandEnabled(command)) {
this.doCommand(command);
}
@ -504,6 +444,17 @@ HistoryDownloadElementShell.prototype = {
}),
};
/**
* Relays commands from the download.xml binding to the selected items.
*/
const DownloadsView = {
onDownloadCommand(event, command) {
goDoCommand(command);
},
onDownloadClick() {},
};
/**
* A Downloads Places View is a places view designed to show a places query
* for history downloads alongside the session downloads.
@ -1175,24 +1126,28 @@ DownloadsPlacesView.prototype = {
this._removeSessionDownloadFromView(download);
},
// nsIController
supportsCommand(aCommand) {
if (DOWNLOAD_VIEW_SUPPORTED_COMMANDS.indexOf(aCommand) != -1) {
// The clear-downloads command may be performed by the toolbar-button,
// which can be focused on OS X. Thus enable this command even if the
// richlistbox is not focused.
// For other commands, be prudent and disable them unless the richlistview
// is focused. It's important to make the decision here rather than in
// isCommandEnabled. Otherwise our controller may "steal" commands from
// other controls in the window (see goUpdateCommand &
// getControllerForCommand).
if (document.activeElement == this._richlistbox ||
aCommand == "downloadsCmd_clearDownloads") {
return true;
}
// Firstly, determine if this is a command that we can handle.
if (!aCommand.startsWith("cmd_") &&
!aCommand.startsWith("downloadsCmd_")) {
return false;
}
return false;
if (!(aCommand in this) &&
!(aCommand in HistoryDownloadElementShell.prototype)) {
return false;
}
// If this function returns true, other controllers won't get a chance to
// process the command even if isCommandEnabled returns false, so it's
// important to check if the list is focused here to handle common commands
// like copy and paste correctly. The clear downloads command, instead, is
// specific to the downloads list but can be invoked from the toolbar, so we
// can just return true unconditionally.
return aCommand == "downloadsCmd_clearDownloads" ||
document.activeElement == this._richlistbox;
},
// nsIController
isCommandEnabled(aCommand) {
switch (aCommand) {
case "cmd_copy":
@ -1269,43 +1224,51 @@ DownloadsPlacesView.prototype = {
DownloadURL(url, name, initiatingDoc);
},
// nsIController
doCommand(aCommand) {
switch (aCommand) {
case "cmd_copy":
this._copySelectedDownloadsToClipboard();
break;
case "cmd_selectAll":
this._richlistbox.selectAll();
break;
case "cmd_paste":
this._downloadURLFromClipboard();
break;
case "downloadsCmd_clearDownloads":
this._downloadsData.removeFinished();
if (this.result) {
Cc["@mozilla.org/browser/download-history;1"]
.getService(Ci.nsIDownloadHistory)
.removeAllDownloads();
}
// There may be no selection or focus change as a result
// of these change, and we want the command updated immediately.
goUpdateCommand("downloadsCmd_clearDownloads");
break;
default: {
// Cloning the nodelist into an array to get a frozen list of selected items.
// Otherwise, the selectedItems nodelist is live and doCommand may alter the
// selection while we are trying to do one particular action, like removing
// items from history.
let selectedElements = [... this._richlistbox.selectedItems];
for (let element of selectedElements) {
element._shell.doCommand(aCommand);
}
}
// If this command is not selection-specific, execute it.
if (aCommand in this) {
this[aCommand]();
return;
}
// Cloning the nodelist into an array to get a frozen list of selected items.
// Otherwise, the selectedItems nodelist is live and doCommand may alter the
// selection while we are trying to do one particular action, like removing
// items from history.
let selectedElements = [...this._richlistbox.selectedItems];
for (let element of selectedElements) {
element._shell.doCommand(aCommand);
}
},
// nsIController
onEvent() {},
cmd_copy() {
this._copySelectedDownloadsToClipboard();
},
cmd_selectAll() {
this._richlistbox.selectAll();
},
cmd_paste() {
this._downloadURLFromClipboard();
},
downloadsCmd_clearDownloads() {
this._downloadsData.removeFinished();
if (this.result) {
Cc["@mozilla.org/browser/download-history;1"]
.getService(Ci.nsIDownloadHistory)
.removeAllDownloads();
}
// There may be no selection or focus change as a result
// of these change, and we want the command updated immediately.
goUpdateCommand("downloadsCmd_clearDownloads");
},
onContextMenu(aEvent) {
let element = this._richlistbox.selectedItem;
if (!element || !element._shell) {
@ -1446,7 +1409,13 @@ for (let methodName of ["load", "applyFilter", "selectNode", "selectItems"]) {
}
function goUpdateDownloadCommands() {
for (let command of DOWNLOAD_VIEW_SUPPORTED_COMMANDS) {
goUpdateCommand(command);
function updateCommandsForObject(object) {
for (let name in object) {
if (name.startsWith("cmd_") || name.startsWith("downloadsCmd_")) {
goUpdateCommand(name);
}
}
}
updateCommandsForObject(this);
updateCommandsForObject(HistoryDownloadElementShell.prototype);
}

View File

@ -4,7 +4,7 @@
# 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://browser/content/downloads/allDownloadsViewOverlay.css"?>
<?xml-stylesheet href="chrome://browser/content/downloads/downloads.css"?>
<?xml-stylesheet href="chrome://browser/skin/downloads/allDownloadsViewOverlay.css"?>
<!DOCTYPE overlay [

View File

@ -1,52 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
richlistitem.download button {
/* These buttons should never get focus, as that would "disable"
the downloads view controller (it's only used when the richlistbox
is focused). */
-moz-user-focus: none;
}
/*** Visibility of controls inside download items ***/
.download-state:-moz-any( [state="6"], /* Blocked (parental) */
[state="8"], /* Blocked (dirty) */
[state="9"]) /* Blocked (policy) */
> .downloadTypeIcon:not(.blockedIcon),
.download-state:not(:-moz-any([state="6"], /* Blocked (parental) */
[state="8"], /* Blocked (dirty) */
[state="9"]) /* Blocked (policy) */)
> .downloadTypeIcon.blockedIcon,
.download-state:not(:-moz-any([state="-1"],/* Starting (initial) */
[state="5"], /* Starting (queued) */
[state="0"], /* Downloading */
[state="4"], /* Paused */
[state="7"]) /* Scanning */)
> vbox > .downloadProgress,
.download-state:not(:-moz-any([state="-1"],/* Starting (initial) */
[state="5"], /* Starting (queued) */
[state="0"], /* Downloading */
[state="4"]) /* Paused */)
> .downloadCancel,
/* Blocked (dirty) downloads that have not been confirmed and
have temporary data. */
.download-state:not( [state="8"])
> .downloadConfirmBlock,
.download-state[state="8"]:not(.temporary-block)
> .downloadConfirmBlock,
.download-state[state]:not(:-moz-any([state="2"], /* Failed */
[state="3"]) /* Canceled */)
> .downloadRetry,
.download-state:not( [state="1"] /* Finished */)
> .downloadShow
{
display: none;
}

View File

@ -67,51 +67,6 @@
</content>
</binding>
<binding id="download-full-ui"
extends="chrome://global/content/bindings/richlistbox.xml#richlistitem">
<resources>
<stylesheet src="chrome://browser/content/downloads/download.css"/>
</resources>
<content orient="horizontal" align="center">
<xul:image class="downloadTypeIcon"
validate="always"
xbl:inherits="src=image"/>
<xul:image class="downloadTypeIcon blockedIcon"/>
<xul:vbox pack="center" flex="1">
<xul:description class="downloadTarget"
crop="center"
xbl:inherits="value=displayName,tooltiptext=displayName"/>
<xul:progressmeter anonid="progressmeter"
class="downloadProgress"
min="0"
max="100"
xbl:inherits="mode=progressmode,value=progress"/>
<xul:description class="downloadDetails"
style="width: &downloadDetails.width;"
crop="end"
xbl:inherits="value=status,tooltiptext=statusTip"/>
</xul:vbox>
<xul:button class="downloadButton downloadCancel"
tooltiptext="&cmd.cancel.label;"
oncommand="goDoCommand('downloadsCmd_cancel')"/>
<xul:button class="downloadButton downloadRetry"
tooltiptext="&cmd.retry.label;"
oncommand="goDoCommand('downloadsCmd_retry')"/>
<xul:button class="downloadButton downloadShow"
#ifdef XP_MACOSX
tooltiptext="&cmd.showMac.label;"
#else
tooltiptext="&cmd.show.label;"
#endif
oncommand="goDoCommand('downloadsCmd_show')"/>
<xul:button class="downloadButton downloadConfirmBlock"
tooltiptext="&cmd.removeFile.label;"
oncommand="goDoCommand('downloadsCmd_confirmBlock');"/>
</content>
</binding>
<binding id="download-toolbarbutton"
extends="chrome://global/content/bindings/toolbarbutton.xml#toolbarbutton">
<content>

View File

@ -2,7 +2,7 @@
* 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/. */
/*** Download items ***/
/*** Downloads Panel ***/
richlistitem[type="download"] {
-moz-binding: url('chrome://browser/content/downloads/download.xml#download');
@ -13,6 +13,45 @@ richlistitem[type="download"]:not([selected]) button {
-moz-user-focus: none;
}
richlistitem[type="download"].download-state[state="1"]:not([exists]) .downloadShow {
display: none;
}
#downloadsSummary:not([inprogress]) > vbox > #downloadsSummaryProgress,
#downloadsSummary:not([inprogress]) > vbox > #downloadsSummaryDetails,
#downloadsFooter[showingsummary] > #downloadsHistory,
#downloadsFooter:not([showingsummary]) > #downloadsSummary {
display: none;
}
/*** Downloads View ***/
/**
* The downloads richlistbox may list thousands of items, and it turns out
* XBL binding attachment, and even more so detachment, is a performance hog.
* This hack makes sure we don't apply any binding to inactive items (inactive
* items are history downloads that haven't been in the visible area).
* We can do this because the richlistbox implementation does not interact
* much with the richlistitem binding. However, this may turn out to have
* some side effects (see bug 828111 for the details).
*
* We might be able to do away with this workaround once bug 653881 is fixed.
*/
richlistitem.download {
-moz-binding: none;
}
richlistitem.download[active] {
-moz-binding: url("chrome://browser/content/downloads/download.xml#download");
}
richlistitem.download button {
/* These buttons should never get focus, as that would "disable"
the downloads view controller (it's only used when the richlistbox
is focused). */
-moz-user-focus: none;
}
/*** Visibility of controls inside download items ***/
.download-state:-moz-any( [state="6"], /* Blocked (parental) */
@ -95,16 +134,3 @@ richlistitem[type="download"]:not([selected]) button {
{
visibility: hidden;
}
.download-state[state="1"]:not([exists]) .downloadShow
{
display: none;
}
#downloadsSummary:not([inprogress]) > vbox > #downloadsSummaryProgress,
#downloadsSummary:not([inprogress]) > vbox > #downloadsSummaryDetails,
#downloadsFooter[showingsummary] > #downloadsHistory,
#downloadsFooter:not([showingsummary]) > #downloadsSummary
{
display: none;
}

View File

@ -23,16 +23,13 @@
*
* DownloadsViewItem
* Builds and updates a single item in the downloads list widget, responding to
* changes in the download state and real-time data.
* changes in the download state and real-time data, and handles the user
* interaction events related to a single item in the downloads list widgets.
*
* DownloadsViewController
* Handles part of the user interaction events raised by the downloads list
* widget, in particular the "commands" that apply to multiple items, and
* dispatches the commands that apply to individual items.
*
* DownloadsViewItemController
* Handles all the user interaction events, in particular the "commands",
* related to a single item in the downloads list widgets.
*/
/**
@ -846,12 +843,12 @@ const DownloadsView = {
/**
* Associates each richlistitem for a download with its corresponding
* DownloadsViewItemController object.
* DownloadsViewItem object.
*/
_controllersForElements: new Map(),
_itemsForElements: new Map(),
controllerForElement(element) {
return this._controllersForElements.get(element);
itemForElement(element) {
return this._itemsForElements.get(element);
},
/**
@ -866,8 +863,7 @@ const DownloadsView = {
let element = document.createElement("richlistitem");
let viewItem = new DownloadsViewItem(download, element);
this._visibleViewItems.set(download, viewItem);
let viewItemController = new DownloadsViewItemController(download);
this._controllersForElements.set(element, viewItemController);
this._itemsForElements.set(element, viewItem);
if (aNewest) {
this.richListBox.insertBefore(element, this.richListBox.firstChild);
} else {
@ -888,7 +884,7 @@ const DownloadsView = {
this.richListBox.itemCount - 1);
}
this._visibleViewItems.delete(download);
this._controllersForElements.delete(element);
this._itemsForElements.delete(element);
},
//////////////////////////////////////////////////////////////////////////////
@ -909,7 +905,7 @@ const DownloadsView = {
while (target.nodeName != "richlistitem") {
target = target.parentNode;
}
DownloadsView.controllerForElement(target).doCommand(aCommand);
DownloadsView.itemForElement(target).doCommand(aCommand);
},
onDownloadClick(aEvent) {
@ -986,7 +982,7 @@ const DownloadsView = {
}
// We must check for existence synchronously because this is a DOM event.
let file = new FileUtils.File(DownloadsView.controllerForElement(element)
let file = new FileUtils.File(DownloadsView.itemForElement(element)
.download.target.path);
if (!file.exists()) {
return;
@ -1011,7 +1007,8 @@ XPCOMUtils.defineConstant(this, "DownloadsView", DownloadsView);
/**
* Builds and updates a single item in the downloads list widget, responding to
* changes in the download state and real-time data.
* changes in the download state and real-time data, and handles the user
* interaction events related to a single item in the downloads list widgets.
*
* @param download
* Download object to be associated with the view item.
@ -1051,6 +1048,104 @@ DownloadsViewItem.prototype = {
!!this.download.hasBlockedData);
this._updateProgress();
},
isCommandEnabled(aCommand) {
switch (aCommand) {
case "downloadsCmd_open": {
if (!this.download.succeeded) {
return false;
}
let file = new FileUtils.File(this.download.target.path);
return file.exists();
}
case "downloadsCmd_show": {
let file = new FileUtils.File(this.download.target.path);
if (file.exists()) {
return true;
}
if (!this.download.target.partFilePath) {
return false;
}
let partFile = new FileUtils.File(this.download.target.partFilePath);
return partFile.exists();
}
case "cmd_delete":
case "downloadsCmd_cancel":
case "downloadsCmd_copyLocation":
case "downloadsCmd_doDefault":
return true;
}
return DownloadsViewUI.DownloadElementShell.prototype
.isCommandEnabled.call(this, aCommand);
},
doCommand(aCommand) {
if (this.isCommandEnabled(aCommand)) {
this[aCommand]();
}
},
//////////////////////////////////////////////////////////////////////////////
//// Item commands
cmd_delete() {
DownloadsCommon.removeAndFinalizeDownload(this.download);
PlacesUtils.bhistory.removePage(
NetUtil.newURI(this.download.source.url));
},
downloadsCmd_unblock() {
DownloadsPanel.hidePanel();
DownloadsCommon.confirmUnblockDownload(DownloadsCommon.BLOCK_VERDICT_MALWARE,
window).then((confirmed) => {
if (confirmed) {
return this.download.unblock();
}
}).catch(Cu.reportError);
},
downloadsCmd_open() {
this.download.launch().catch(Cu.reportError);
// We explicitly close the panel here to give the user the feedback that
// their click has been received, and we're handling the action.
// Otherwise, we'd have to wait for the file-type handler to execute
// before the panel would close. This also helps to prevent the user from
// accidentally opening a file several times.
DownloadsPanel.hidePanel();
},
downloadsCmd_show() {
let file = new FileUtils.File(this.download.target.path);
DownloadsCommon.showDownloadedFile(file);
// We explicitly close the panel here to give the user the feedback that
// their click has been received, and we're handling the action.
// Otherwise, we'd have to wait for the operating system file manager
// window to open before the panel closed. This also helps to prevent the
// user from opening the containing folder several times.
DownloadsPanel.hidePanel();
},
downloadsCmd_openReferrer() {
openURL(this.download.source.referrer);
},
downloadsCmd_copyLocation() {
let clipboard = Cc["@mozilla.org/widget/clipboardhelper;1"]
.getService(Ci.nsIClipboardHelper);
clipboard.copyString(this.download.source.url);
},
downloadsCmd_doDefault() {
let defaultCommand = this.currentDefaultCommandName;
if (defaultCommand && this.isCommandEnabled(defaultCommand)) {
this.doCommand(defaultCommand);
}
},
};
////////////////////////////////////////////////////////////////////////////////
@ -1078,8 +1173,11 @@ const DownloadsViewController = {
supportsCommand(aCommand) {
// Firstly, determine if this is a command that we can handle.
if (!(aCommand in this.commands) &&
!(aCommand in DownloadsViewItemController.prototype.commands)) {
if (!DownloadsViewUI.isCommandName(aCommand)) {
return false;
}
if (!(aCommand in this) &&
!(aCommand in DownloadsViewItem.prototype)) {
return false;
}
// Secondly, determine if focus is on a control in the downloads list.
@ -1100,14 +1198,14 @@ const DownloadsViewController = {
// Other commands are selection-specific.
let element = DownloadsView.richListBox.selectedItem;
return element && DownloadsView.controllerForElement(element)
return element && DownloadsView.itemForElement(element)
.isCommandEnabled(aCommand);
},
doCommand(aCommand) {
// If this command is not selection-specific, execute it.
if (aCommand in this.commands) {
this.commands[aCommand].apply(this);
if (aCommand in this) {
this[aCommand]();
return;
}
@ -1115,7 +1213,7 @@ const DownloadsViewController = {
let element = DownloadsView.richListBox.selectedItem;
if (element) {
// The doCommand function also checks if the command is enabled.
DownloadsView.controllerForElement(element).doCommand(aCommand);
DownloadsView.itemForElement(element).doCommand(aCommand);
}
},
@ -1125,192 +1223,27 @@ const DownloadsViewController = {
//// Other functions
updateCommands() {
Object.keys(this.commands).forEach(goUpdateCommand);
Object.keys(DownloadsViewItemController.prototype.commands)
.forEach(goUpdateCommand);
function updateCommandsForObject(object) {
for (let name in object) {
if (DownloadsViewUI.isCommandName(name)) {
goUpdateCommand(name);
}
}
}
updateCommandsForObject(this);
updateCommandsForObject(DownloadsViewItem.prototype);
},
//////////////////////////////////////////////////////////////////////////////
//// Selection-independent commands
/**
* This object contains one key for each command that operates regardless of
* the currently selected item in the list.
*/
commands: {
downloadsCmd_clearList() {
DownloadsCommon.getData(window).removeFinished();
}
}
downloadsCmd_clearList() {
DownloadsCommon.getData(window).removeFinished();
},
};
XPCOMUtils.defineConstant(this, "DownloadsViewController", DownloadsViewController);
////////////////////////////////////////////////////////////////////////////////
//// DownloadsViewItemController
/**
* Handles all the user interaction events, in particular the "commands",
* related to a single item in the downloads list widgets.
*/
function DownloadsViewItemController(download) {
this.download = download;
}
DownloadsViewItemController.prototype = {
isCommandEnabled(aCommand) {
switch (aCommand) {
case "downloadsCmd_open": {
if (!this.download.succeeded) {
return false;
}
let file = new FileUtils.File(this.download.target.path);
return file.exists();
}
case "downloadsCmd_show": {
let file = new FileUtils.File(this.download.target.path);
if (file.exists()) {
return true;
}
if (!this.download.target.partFilePath) {
return false;
}
let partFile = new FileUtils.File(this.download.target.partFilePath);
return partFile.exists();
}
case "downloadsCmd_pauseResume":
return this.download.hasPartialData && !this.download.error;
case "downloadsCmd_retry":
return this.download.canceled || this.download.error;
case "downloadsCmd_openReferrer":
return !!this.download.source.referrer;
case "cmd_delete":
case "downloadsCmd_cancel":
case "downloadsCmd_copyLocation":
case "downloadsCmd_doDefault":
return true;
case "downloadsCmd_unblock":
case "downloadsCmd_confirmBlock":
return this.download.hasBlockedData;
}
return false;
},
doCommand(aCommand) {
if (this.isCommandEnabled(aCommand)) {
this.commands[aCommand].apply(this);
}
},
//////////////////////////////////////////////////////////////////////////////
//// Item commands
/**
* This object contains one key for each command that operates on this item.
*
* In commands, the "this" identifier points to the controller item.
*/
commands: {
cmd_delete() {
DownloadsCommon.removeAndFinalizeDownload(this.download);
PlacesUtils.bhistory.removePage(
NetUtil.newURI(this.download.source.url));
},
downloadsCmd_cancel() {
this.download.cancel().catch(() => {});
this.download.removePartialData().catch(Cu.reportError);
},
downloadsCmd_unblock() {
DownloadsPanel.hidePanel();
DownloadsCommon.confirmUnblockDownload(DownloadsCommon.BLOCK_VERDICT_MALWARE,
window).then((confirmed) => {
if (confirmed) {
return this.download.unblock();
}
}).catch(Cu.reportError);
},
downloadsCmd_confirmBlock() {
this.download.confirmBlock().catch(Cu.reportError);
},
downloadsCmd_open() {
this.download.launch().catch(Cu.reportError);
// We explicitly close the panel here to give the user the feedback that
// their click has been received, and we're handling the action.
// Otherwise, we'd have to wait for the file-type handler to execute
// before the panel would close. This also helps to prevent the user from
// accidentally opening a file several times.
DownloadsPanel.hidePanel();
},
downloadsCmd_show() {
let file = new FileUtils.File(this.download.target.path);
DownloadsCommon.showDownloadedFile(file);
// We explicitly close the panel here to give the user the feedback that
// their click has been received, and we're handling the action.
// Otherwise, we'd have to wait for the operating system file manager
// window to open before the panel closed. This also helps to prevent the
// user from opening the containing folder several times.
DownloadsPanel.hidePanel();
},
downloadsCmd_pauseResume() {
if (this.download.stopped) {
this.download.start();
} else {
this.download.cancel();
}
},
downloadsCmd_retry() {
this.download.start().catch(() => {});
},
downloadsCmd_openReferrer() {
openURL(this.download.source.referrer);
},
downloadsCmd_copyLocation() {
let clipboard = Cc["@mozilla.org/widget/clipboardhelper;1"]
.getService(Ci.nsIClipboardHelper);
clipboard.copyString(this.download.source.url);
},
downloadsCmd_doDefault() {
const nsIDM = Ci.nsIDownloadManager;
// Determine the default command for the current item.
let defaultCommand = function () {
switch (DownloadsCommon.stateOfDownload(this.download)) {
case nsIDM.DOWNLOAD_NOTSTARTED: return "downloadsCmd_cancel";
case nsIDM.DOWNLOAD_FINISHED: return "downloadsCmd_open";
case nsIDM.DOWNLOAD_FAILED: return "downloadsCmd_retry";
case nsIDM.DOWNLOAD_CANCELED: return "downloadsCmd_retry";
case nsIDM.DOWNLOAD_PAUSED: return "downloadsCmd_pauseResume";
case nsIDM.DOWNLOAD_QUEUED: return "downloadsCmd_cancel";
case nsIDM.DOWNLOAD_BLOCKED_PARENTAL: return "downloadsCmd_openReferrer";
case nsIDM.DOWNLOAD_SCANNING: return "downloadsCmd_show";
case nsIDM.DOWNLOAD_DIRTY: return "downloadsCmd_openReferrer";
case nsIDM.DOWNLOAD_BLOCKED_POLICY: return "downloadsCmd_openReferrer";
}
return "";
}.apply(this);
if (defaultCommand && this.isCommandEnabled(defaultCommand)) {
this.doCommand(defaultCommand);
}
},
},
};
////////////////////////////////////////////////////////////////////////////////
//// DownloadsSummary

View File

@ -4,7 +4,6 @@
browser.jar:
* content/browser/downloads/download.xml (content/download.xml)
content/browser/downloads/download.css (content/download.css)
content/browser/downloads/downloads.css (content/downloads.css)
content/browser/downloads/downloads.js (content/downloads.js)
* content/browser/downloads/downloadsOverlay.xul (content/downloadsOverlay.xul)
@ -12,7 +11,6 @@ browser.jar:
content/browser/downloads/indicatorOverlay.xul (content/indicatorOverlay.xul)
* content/browser/downloads/allDownloadsViewOverlay.xul (content/allDownloadsViewOverlay.xul)
content/browser/downloads/allDownloadsViewOverlay.js (content/allDownloadsViewOverlay.js)
content/browser/downloads/allDownloadsViewOverlay.css (content/allDownloadsViewOverlay.css)
* content/browser/downloads/contentAreaDownloadsView.xul (content/contentAreaDownloadsView.xul)
content/browser/downloads/contentAreaDownloadsView.js (content/contentAreaDownloadsView.js)
content/browser/downloads/contentAreaDownloadsView.css (content/contentAreaDownloadsView.css)

View File

@ -49,7 +49,7 @@ add_task(function* test_basic_functionality() {
let itemCount = richlistbox.children.length;
for (let i = 0; i < itemCount; i++) {
let element = richlistbox.children[itemCount - i - 1];
let download = DownloadsView.controllerForElement(element).download;
let download = DownloadsView.itemForElement(element).download;
is(DownloadsCommon.stateOfDownload(download), DownloadData[i].state,
"Download states match up");
}

View File

@ -154,6 +154,19 @@ extensions.registerSchemaAPI("tabs", null, (extension, context) => {
};
}).api(),
/**
* Since multiple tabs currently can't be highlighted, onHighlighted
* essentially acts an alias for self.tabs.onActivated but returns
* the tabId in an array to match the API.
* @see https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/Tabs/onHighlighted
*/
onHighlighted: new WindowEventManager(context, "tabs.onHighlighted", "TabSelect", (fire, event) => {
let tab = event.originalTarget;
let tabIds = [TabManager.getId(tab)];
let windowId = WindowManager.getId(tab.ownerDocument.defaultView);
fire({tabIds, windowId});
}).api(),
onAttached: new EventManager(context, "tabs.onAttached", fire => {
let fireForTab = tab => {
let newWindowId = WindowManager.getId(tab.ownerDocument.defaultView);

View File

@ -44,6 +44,7 @@ support-files =
[browser_ext_tabs_sendMessage.js]
[browser_ext_tabs_move.js]
[browser_ext_tabs_move_window.js]
[browser_ext_tabs_onHighlighted.js]
[browser_ext_windows_create_tabId.js]
[browser_ext_windows_update.js]
[browser_ext_contentscript_connect.js]

View File

@ -0,0 +1,118 @@
/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set sts=2 sw=2 et tw=80: */
"use strict";
add_task(function* testTabEvents() {
function background() {
/** The list of active tab ID's */
let tabIds = [];
/**
* Stores the events that fire for each tab.
*
* events {
* tabId1: [event1, event2, ...],
* tabId2: [event1, event2, ...],
* }
*/
let events = {};
browser.tabs.onActivated.addListener((info) => {
if (info.tabId in events) {
events[info.tabId].push("onActivated");
} else {
events[info.tabId] = ["onActivated"];
}
});
browser.tabs.onHighlighted.addListener((info) => {
if (info.tabIds[0] in events) {
events[info.tabIds[0]].push("onHighlighted");
} else {
events[info.tabIds[0]] = ["onHighlighted"];
}
});
/**
* Asserts that the expected events are fired for the tab with id = tabId.
* The events associated to the specified tab are removed after this check is made.
*/
function expectEvents(tabId, expectedEvents) {
browser.test.log(`Expecting events: ${expectedEvents.join(", ")}`);
return new Promise(resolve => {
setTimeout(resolve, 0);
}).then(() => {
browser.test.assertEq(expectedEvents.length, events[tabId].length,
`Got expected number of events for ${tabId}`);
for (let [i, name] of expectedEvents.entries()) {
browser.test.assertEq(name, i in events[tabId] && events[tabId][i],
`Got expected ${name} event`);
}
delete events[tabId];
});
}
/**
* Opens a new tab and asserts that the correct events are fired.
*/
function openTab(windowId) {
return browser.tabs.create({windowId}).then(tab => {
tabIds.push(tab.id);
browser.test.log(`Opened tab ${tab.id}`);
return expectEvents(tab.id, [
"onActivated",
"onHighlighted",
]);
});
}
/**
* Highlights an existing tab and asserts that the correct events are fired.
*/
function highlightTab(tabId) {
browser.test.log(`Highlighting tab ${tabId}`);
return browser.tabs.update(tabId, {active: true}).then(tab => {
browser.test.assertEq(tab.id, tabId, `Tab ${tab.id} highlighted`);
return expectEvents(tab.id, [
"onActivated",
"onHighlighted",
]);
});
}
/**
* The main entry point to the tests.
*/
browser.tabs.query({active: true, currentWindow: true}, tabs => {
let activeWindow = tabs[0].windowId;
Promise.all([
openTab(activeWindow),
openTab(activeWindow),
openTab(activeWindow),
]).then(() => {
return Promise.all([
highlightTab(tabIds[0]),
highlightTab(tabIds[1]),
highlightTab(tabIds[2]),
]);
}).then(() => {
return Promise.all(tabIds.map(id => browser.tabs.remove(id)));
}).then(() => {
browser.test.notifyPass("tabs.highlight");
});
});
}
let extension = ExtensionTestUtils.loadExtension({
manifest: {
"permissions": ["tabs"],
},
background,
});
yield extension.startup();
yield extension.awaitFinish("tabs.highlight");
yield extension.unload();
});

View File

@ -3,7 +3,6 @@ support-files = head.js
[browser_forbidden.js]
[browser_bug400731.js]
skip-if = e10s
[browser_bug415846.js]
skip-if = os == "mac" || e10s
# Disabled on Mac because of its bizarre special-and-unique

View File

@ -1,76 +1,57 @@
/* Check for the intended visibility of the "Ignore this warning" text*/
/* Check presence of the "Ignore this warning" button */
function onDOMContentLoaded(callback) {
function complete({ data }) {
mm.removeMessageListener("Test:DOMContentLoaded", complete);
callback(data);
}
let mm = gBrowser.selectedBrowser.messageManager;
mm.addMessageListener("Test:DOMContentLoaded", complete);
function contentScript() {
let listener = function () {
removeEventListener("DOMContentLoaded", listener);
let button = content.document.getElementById("ignoreWarningButton");
sendAsyncMessage("Test:DOMContentLoaded", { buttonPresent: !!button });
};
addEventListener("DOMContentLoaded", listener);
}
mm.loadFrameScript("data:,(" + contentScript.toString() + ")();", true);
}
function test() {
waitForExplicitFinish();
gBrowser.selectedTab = gBrowser.addTab();
// Navigate to malware site. Can't use an onload listener here since
// error pages don't fire onload. Also can't register the DOMContentLoaded
// handler here because registering it too soon would mean that we might
// get it for about:blank, and not about:blocked.
gBrowser.addTabsProgressListener({
onLocationChange: function(aTab, aWebProgress, aRequest, aLocation, aFlags) {
if (aFlags & Ci.nsIWebProgressListener.LOCATION_CHANGE_ERROR_PAGE) {
gBrowser.removeTabsProgressListener(this);
window.addEventListener("DOMContentLoaded", testMalware, true);
}
}
});
content.location = "http://www.itisatrap.org/firefox/its-an-attack.html";
gBrowser.selectedTab = gBrowser.addTab("http://www.itisatrap.org/firefox/its-an-attack.html");
onDOMContentLoaded(testMalware);
}
function testMalware(event) {
if (event.target != gBrowser.selectedBrowser.contentDocument) {
return;
}
window.removeEventListener("DOMContentLoaded", testMalware, true);
// Confirm that "Ignore this warning" is visible - bug 422410
var el = content.document.getElementById("ignoreWarningButton");
ok(el, "Ignore warning button should be present for malware");
var style = content.getComputedStyle(el, null);
is(style.display, "inline-block", "Ignore Warning button should be display:inline-block for malware");
function testMalware(data) {
ok(data.buttonPresent, "Ignore warning button should be present for malware");
Services.prefs.setBoolPref("browser.safebrowsing.allowOverride", false);
// Now launch the unwanted software test
window.addEventListener("DOMContentLoaded", testUnwanted, true);
content.location = "http://www.itisatrap.org/firefox/unwanted.html";
onDOMContentLoaded(testUnwanted);
gBrowser.loadURI("http://www.itisatrap.org/firefox/unwanted.html");
}
function testUnwanted(event) {
if (event.target != gBrowser.selectedBrowser.contentDocument) {
return;
}
window.removeEventListener("DOMContentLoaded", testUnwanted, true);
function testUnwanted(data) {
// Confirm that "Ignore this warning" is visible - bug 422410
var el = content.document.getElementById("ignoreWarningButton");
ok(!el, "Ignore warning button should be missing for unwanted software");
ok(!data.buttonPresent, "Ignore warning button should be missing for unwanted software");
Services.prefs.setBoolPref("browser.safebrowsing.allowOverride", true);
// Now launch the phishing test
window.addEventListener("DOMContentLoaded", testPhishing, true);
content.location = "http://www.itisatrap.org/firefox/its-a-trap.html";
onDOMContentLoaded(testPhishing);
gBrowser.loadURI("http://www.itisatrap.org/firefox/its-a-trap.html");
}
function testPhishing(event) {
if (event.target != gBrowser.selectedBrowser.contentDocument) {
return;
}
window.removeEventListener("DOMContentLoaded", testPhishing, true);
var el = content.document.getElementById("ignoreWarningButton");
ok(el, "Ignore warning button should be present for phishing");
var style = content.getComputedStyle(el, null);
is(style.display, "inline-block", "Ignore Warning button should be display:inline-block for phishing");
function testPhishing(data) {
ok(data.buttonPresent, "Ignore warning button should be present for phishing");
gBrowser.removeCurrentTab();
finish();

View File

@ -188,12 +188,16 @@ Object.assign(SyncedTabsListStore.prototype, EventEmitter.prototype, {
focusInput() {
this.inputFocused = true;
this._change("update");
// A change type of "all" updates rather than rebuilds, which is what we
// want here - only the selection/focus has changed.
this._change("all");
},
blurInput() {
this.inputFocused = false;
this._change("update");
// A change type of "all" updates rather than rebuilds, which is what we
// want here - only the selection/focus has changed.
this._change("all");
},
clearFilter() {

View File

@ -63,7 +63,7 @@ add_task(function* () {
glue.observe(null, TOPIC_BROWSERGLUE_TEST, TOPICDATA_DISTRIBUTION_CUSTOMIZATION);
Assert.equal(Services.prefs.getCharPref("distribution.test.string"), "Test String");
Assert.throws(() => Services.prefs.getCharPref("distribution.test.string.noquotes"));
Assert.equal(Services.prefs.getCharPref("distribution.test.string.noquotes"), "Test String");
Assert.equal(Services.prefs.getIntPref("distribution.test.int"), 777);
Assert.equal(Services.prefs.getBoolPref("distribution.test.bool.true"), true);
Assert.equal(Services.prefs.getBoolPref("distribution.test.bool.false"), false);

View File

@ -593,7 +593,7 @@ var WindowListener = {
* }
*/
addRemoteCursor: function(cursorData) {
if (!this._listeningToTabSelect) {
if (this._browserSharePaused || !this._listeningToTabSelect) {
return;
}
@ -649,9 +649,6 @@ var WindowListener = {
* conversation.
*/
_maybeShowBrowserSharingInfoBar: function() {
this._hideBrowserSharingInfoBar();
let box = gBrowser.getNotificationBox();
// Pre-load strings
let pausedStrings = {
label: this._getString("infobar_button_restart_label2"),
@ -663,14 +660,18 @@ var WindowListener = {
accesskey: this._getString("infobar_button_stop_accesskey"),
message: this._getString("infobar_screenshare_browser_message2")
};
let initStrings = this._browserSharePaused ? pausedStrings : unpausedStrings;
let initStrings =
this._browserSharePaused ? pausedStrings : unpausedStrings;
this._hideBrowserSharingInfoBar();
let box = gBrowser.getNotificationBox();
let bar = box.appendNotification(
initStrings.message,
kBrowserSharingNotificationId,
// Icon is defined in browser theme CSS.
null,
box.PRIORITY_WARNING_LOW,
[{
initStrings.message, // label
kBrowserSharingNotificationId, // value
// Icon defined in browser theme CSS.
null, // image
box.PRIORITY_WARNING_LOW, // priority
[{ // buttons (Pause, Stop)
label: initStrings.label,
accessKey: initStrings.accessKey,
isDefault: false,
@ -684,6 +685,8 @@ var WindowListener = {
LoopUI.MozLoopService.toggleBrowserSharing(this._browserSharePaused);
if (this._browserSharePaused) {
this._pauseButtonClicked = true;
// if paused we stop sharing remote cursors
this.removeRemoteCursor();
} else {
this._resumeButtonClicked = true;
}
@ -696,6 +699,7 @@ var WindowListener = {
accessKey: this._getString("infobar_button_disconnect_accesskey"),
isDefault: true,
callback: () => {
this.removeRemoteCursor();
this._hideBrowserSharingInfoBar();
LoopUI.MozLoopService.hangupAllChatWindows();
},
@ -780,8 +784,8 @@ var WindowListener = {
* through the sdk.
*/
handleMousemove: function(event) {
// We want to stop sending events if sharing is paused.
if (this._browserSharePaused) {
// Won't send events if not sharing (paused or not started).
if (this._browserSharePaused || !this._listeningToTabSelect) {
return;
}

View File

@ -983,7 +983,13 @@ var MozLoopServiceInternal = {
if (kEventNamesMap[eventName]) {
eventName = kEventNamesMap[eventName];
UITour.clearAvailableTargetsCache();
// `clearAvailableTargetsCache` is new in Firefox 46. The else branch
// supports Firefox 45.
if ("clearAvailableTargetsCache" in UITour) {
UITour.clearAvailableTargetsCache();
} else {
UITour.availableTargetsCache.clear();
}
UITour.notify(eventName);
} else {
// When the chat box or messages are shown, resize the panel or window
@ -1971,6 +1977,7 @@ this.MozLoopService = {
// Notify the UI, which has the side effect of re-enabling panel opening
// and updating the toolbar.
xulWin.LoopUI.isSlideshowOpen = false;
xulWin.LoopUI.openPanel();
xulWin.removeEventListener("CloseSlideshow", removeSlideshow);

View File

@ -467,13 +467,10 @@ loop.panel = function (_, mozL10n) {
}));
// Open url if needed.
loop.requestMulti(
["getSelectedTabMetadata"],
["GettingStartedURL", null, {}]
).then(function(results) {
loop.requestMulti(["getSelectedTabMetadata"], ["GettingStartedURL", null, {}]).then(function (results) {
var contextURL = this.props.room.decryptedContext.urls && this.props.room.decryptedContext.urls[0].location;
contextURL = contextURL || (results[1] + "?noopenpanel=1");
contextURL = contextURL || results[1] + "?noopenpanel=1";
if (results[0].url !== contextURL) {
loop.request("OpenURL", contextURL);

View File

@ -141,6 +141,7 @@ loop.store.ActiveRoomStore = (function(mozL10n) {
localVideoDimensions: {},
remoteVideoDimensions: {},
screenSharingState: SCREEN_SHARE_STATES.INACTIVE,
sharingPaused: false,
receivingScreenShare: false,
// Any urls (aka context) associated with the room.
roomContextUrls: null,
@ -264,6 +265,7 @@ loop.store.ActiveRoomStore = (function(mozL10n) {
"videoDimensionsChanged",
"startBrowserShare",
"endScreenShare",
"toggleBrowserSharing",
"updateSocialShareInfo",
"connectionStatus",
"mediaConnected"
@ -924,10 +926,19 @@ loop.store.ActiveRoomStore = (function(mozL10n) {
console.error("Unexpectedly received windowId for browser sharing when pending");
}
// The browser being shared changed, so update to the new context
// Only update context if sharing is not paused and there's somebody.
if (!this.getStoreState().sharingPaused && this._hasParticipants()) {
this._checkTabContext();
}
},
/**
* Get the current tab context to update the room context.
*/
_checkTabContext: function() {
loop.request("GetSelectedTabMetadata").then(function(meta) {
// Avoid sending the event if there is no data nor participants nor url
if (!meta || !meta.url || !this._hasParticipants()) {
// Avoid sending the event if there is no data nor url.
if (!meta || !meta.url) {
return;
}
@ -989,6 +1000,22 @@ loop.store.ActiveRoomStore = (function(mozL10n) {
}
},
/**
* Handle browser sharing being enabled or disabled.
*
* @param {sharedActions.ToggleBrowserSharing} actionData
*/
toggleBrowserSharing: function(actionData) {
this.setStoreState({
sharingPaused: !actionData.enabled
});
// If unpausing, check the context as it might have changed.
if (actionData.enabled) {
this._checkTabContext();
}
},
/**
* Handles recording when a remote peer has connected to the servers.
*/

View File

@ -735,8 +735,12 @@ loop.shared.views = function (_, mozL10n) {
var storeState = this.props.cursorStore.getStoreState();
var deltaX = event.clientX - storeState.videoLetterboxing.left;
var deltaY = event.clientY - storeState.videoLetterboxing.top;
// video is not at the top, so we need to calculate the offset
var video = this.getDOMNode().querySelector("video");
var offset = video.getBoundingClientRect();
var deltaX = event.clientX - storeState.videoLetterboxing.left - offset.left;
var deltaY = event.clientY - storeState.videoLetterboxing.top - offset.top;
// Skip the update if cursor is out of bounds
if (deltaX < 0 || deltaX > storeState.streamVideoWidth || deltaY < 0 || deltaY > storeState.streamVideoHeight ||

View File

@ -1600,6 +1600,7 @@ describe("loop.store.ActiveRoomStore", function() {
it("should request the new metadata when the browser being shared change", function() {
store.startBrowserShare(new sharedActions.StartBrowserShare());
clock.tick(500);
sinon.assert.calledOnce(getSelectedTabMetadataStub);
sinon.assert.calledTwice(dispatcher.dispatch);
sinon.assert.calledWith(dispatcher.dispatch.getCall(1),
@ -1630,35 +1631,42 @@ describe("loop.store.ActiveRoomStore", function() {
});
it("should not process a request without url", function() {
clock.tick(500);
getSelectedTabMetadataStub.returns({
title: "fakeTitle",
favicon: "fakeFavicon"
});
store.startBrowserShare(new sharedActions.StartBrowserShare());
clock.tick(500);
sinon.assert.calledOnce(getSelectedTabMetadataStub);
sinon.assert.calledOnce(dispatcher.dispatch);
});
it("should not process a request if sharing is paused", function() {
store.setStoreState({
sharingPaused: true
});
store.startBrowserShare(new sharedActions.StartBrowserShare());
clock.tick(500);
sinon.assert.notCalled(getSelectedTabMetadataStub);
sinon.assert.calledOnce(dispatcher.dispatch);
});
it("should not process a request if no-one is in the room", function() {
store.setStoreState({
roomState: ROOM_STATES.JOINED,
roomToken: "fakeToken",
sessionToken: "1627384950",
participants: [{
displayName: "Owner",
owner: true
}]
});
clock.tick(500);
getSelectedTabMetadataStub.returns({
title: "fakeTitle",
favicon: "fakeFavicon"
});
store.startBrowserShare(new sharedActions.StartBrowserShare());
sinon.assert.calledOnce(getSelectedTabMetadataStub);
clock.tick(500);
sinon.assert.notCalled(getSelectedTabMetadataStub);
sinon.assert.calledOnce(dispatcher.dispatch);
});
});
@ -1731,6 +1739,54 @@ describe("loop.store.ActiveRoomStore", function() {
});
});
describe("#toggleBrowserSharing", function() {
it("should set paused to false when enabled", function() {
store.toggleBrowserSharing(new sharedActions.ToggleBrowserSharing({
enabled: true
}));
expect(store.getStoreState().sharingPaused).eql(false);
});
it("should set paused to true when not enabled", function() {
store.toggleBrowserSharing(new sharedActions.ToggleBrowserSharing({
enabled: false
}));
expect(store.getStoreState().sharingPaused).eql(true);
});
it("should update context when enabled", function() {
var getSelectedTabMetadataStub = sinon.stub();
LoopMochaUtils.stubLoopRequest({
GetSelectedTabMetadata: getSelectedTabMetadataStub.returns({
title: "fakeTitle",
favicon: "fakeFavicon",
url: "http://www.fakeurl.com"
})
});
store.setStoreState({
roomState: ROOM_STATES.JOINED,
roomToken: "fakeToken"
});
store.toggleBrowserSharing(new sharedActions.ToggleBrowserSharing({
enabled: true
}));
clock.tick(500);
sinon.assert.calledOnce(getSelectedTabMetadataStub);
sinon.assert.calledOnce(dispatcher.dispatch);
sinon.assert.calledWith(dispatcher.dispatch,
new sharedActions.UpdateRoomContext({
newRoomDescription: "fakeTitle",
newRoomThumbnail: "fakeFavicon",
newRoomURL: "http://www.fakeurl.com",
roomToken: "fakeToken"
}));
});
});
describe("#remotePeerConnected", function() {
it("should set the state to `HAS_PARTICIPANTS`", function() {
store.remotePeerConnected();

File diff suppressed because it is too large Load Diff

View File

@ -4,7 +4,7 @@
# Panel Strings
clientSuperShortname=হ্যালো
clientSuperShortname=Hello
## LOCALIZATION_NOTE(loopMenuItem_label): Label of the menu item that is placed
## inside the browser 'Tools' menu. Use the unicode ellipsis char, \u2026, or
@ -43,19 +43,24 @@ first_time_experience_button_label2=দেখুন এটা কিভাবে
fte_slide_1_title=বন্ধুর সাথে পাতাটি ব্রাউজ করুন
## LOCALIZATION_NOTE(fte_slide_1_copy): {{clientShortname2}}
## will be replaced by the short name 2.
fte_slide_1_copy=যখনই আপনি কোন উপহারের জন্য কেনাকাটা বা কোথায় বেড়ানোর পরিকল্পনা করছেন, {{clientShortname2}} আপনাকে দ্রুত সময়ের মধ্যে তাৎক্ষণিক সিদ্ধান্ত নিতে সাহায্য করবে।
fte_slide_2_title=একই পাতায় পেতে
fte_slide_2_copy=কোন আইডিয়া শেয়ার করতে, বিকল্পগুলো তুলনা করছে এবং একটি সিধান্তে আসতে বিল্ট-ইন টেক্সট অথবা ভিডিও চ্যাট ব্যবহার করুন।
fte_slide_3_title=লিঙ্ক শেয়ার করে বন্ধুদের আলাপে আমন্ত্রণ জানান
## LOCALIZATION_NOTE(fte_slide_3_copy): {{clientSuperShortname}}
## will be replaced by the super short brand name.
fte_slide_3_copy={{clientSuperShortname}} প্রায় সকল ডেস্কটপ ব্রাউজারের সাথে কাজ করে। কোন অ্যাকাউন্টের প্রয়োজন নেই এবং সকলেই বিনামুল্যে সংযুক্ত হতে পারেন।
## LOCALIZATION_NOTE(fte_slide_4_title): {{clientSuperShortname}}
## will be replaced by the super short brand name.
fte_slide_4_title=শুরু করতে {{clientSuperShortname}} আইকন খুঁজে নিন
## LOCALIZATION_NOTE(fte_slide_4_copy): {{brandShortname}}
## will be replaced by the brand short name.
fte_slide_4_copy=যখনই আপনি কোন পাতা পাবেন আলোচনা করার জন্যে, লিঙ্ক তৈরি করতে {{brandShortname}} এ ক্লিক করুন। তারপর সেই লিঙ্ক যেকোন ভাবে আপনার বন্ধুর কাছে পাঠিয়ে দিন।
invite_header_text_bold=আপনার সাথে এই পাতা ব্রাউজে যোগদানে কাউকে আমন্ত্রণ জানান!
invite_header_text_bold2=কাউকে আমন্ত্রণ জানান আপনার সাথে যোগ দিতে ।
invite_header_text3=ফায়ারফক্স হ্যালো ব্যবহার করতে দুজনের প্রয়োজন হয়, আপনার সাথে ওয়েব ব্রাউজ করতে আপনার বন্ধুকে লিঙ্ক পাঠান।
invite_header_text4=এই লিঙ্কটি শেয়ার করুন যেন আপনারা একসাথে ওয়েব ব্রাউজ করতে পারেন।
## LOCALIZATION_NOTE(invite_copy_link_button, invite_copied_link_button,
## invite_email_link_button, invite_facebook_button2): These labels appear under
## an iconic button for the invite view.
@ -195,7 +200,9 @@ door_hanger_button=ঠিক আছে
# Infobar strings
infobar_screenshare_no_guest_message=যখনই আপনার বন্ধু যোগ দেবে, তারা আপনি কি ট্যাব ক্লিক করছেন তা দেখতে পাবে।
infobar_screenshare_browser_message2=আপনি আপনার ট্যাব শেয়ার করছেন। যেকোনো ট্যাব ক্লিক করলে তা আপনার বন্ধু দেখতে পারবে।
infobar_screenshare_browser_message3=আপনি এখন আপনার ট্যাব শেয়ার করছেন। আপনে যেই ট্যাবেই ক্লিক করুন তা আপনার বন্ধু দেখতে পাবে।
infobar_screenshare_stop_sharing_message=আপনি আপনার ট্যাব আর শেয়ার করছেন না
infobar_button_restart_label2=শেয়ার করা পুনরায় শুরু করুন
infobar_button_restart_accesskey=R
@ -253,3 +260,5 @@ self_view_hidden_message=সেলফ-ভিউ লুকানো কিন্
## LOCALIZATION NOTE (tos_failure_message): Don't translate {{clientShortname}}
## as this will be replaced by clientShortname2.
tos_failure_message={{clientShortname}} আপনার দেশের বিদ্যমান নয়।
display_name_guest=অতিথি

View File

@ -36,20 +36,31 @@ first_time_experience_subheading_button_above=Klepněte na tlačítko výše a p
## LOCALIZATION_NOTE(first_time_experience_content, first_time_experience_content2): Message describing
## ways to use Hello project.
first_time_experience_content=Použijte jej pro společné plánování, práci i zábavu.
first_time_experience_content2=Použijte jej pro společné plánování, zábavu i práci.
first_time_experience_button_label2=Podívejte se, jak to funguje
## First Time Experience Slides
fte_slide_1_title=Prohlížejte si web spolu s přítelem
## LOCALIZATION_NOTE(fte_slide_1_copy): {{clientShortname2}}
## will be replaced by the short name 2.
fte_slide_1_copy=Ať už plánujete výlet nebo vybíráte dárek, {{clientShortname2}} vám pomůže urychlit společné rozhodování.
fte_slide_2_title=Buďte na stejné stránce
fte_slide_2_copy=Použijte vestavěný chat a video pro sdílení nápadů, srovnání možností a společnému rozhodnutí.
fte_slide_3_title=Pozvěte přátele posláním odkazu
## LOCALIZATION_NOTE(fte_slide_3_copy): {{clientSuperShortname}}
## will be replaced by the super short brand name.
fte_slide_3_copy={{clientSuperShortname}} funguje ve většině desktopových prohlížečů. Nepotřebujete žádný účet a každý se může připojit zdarma.
## LOCALIZATION_NOTE(fte_slide_4_title): {{clientSuperShortname}}
## will be replaced by the super short brand name.
fte_slide_4_title=Najděte ikonu {{clientSuperShortname}} a začněte
## LOCALIZATION_NOTE(fte_slide_4_copy): {{brandShortname}}
## will be replaced by the brand short name.
fte_slide_4_copy=Jakmile najdete stránku, o které chcete mluvit, klepněte na ikonu {{brandShortname}} a vytvořte odkaz. Ten pošlete svému příteli jakýmkoliv způsobem se vám zrovna hodí!
invite_header_text_bold=Pozvěte někoho, kdo bude prohlížet tuto stránku s vámi!
invite_header_text_bold2=Pozvěte přítele na hovor!
invite_header_text3=K používání Firefox Hello jsou potřeba dva, takže pošlete kamarádovi odkaz, aby si prohlížel web s vámi!
invite_header_text4=Sdílejte tento odkaz a můžete začít prohlížeč web společně.
## LOCALIZATION_NOTE(invite_copy_link_button, invite_copied_link_button,
## invite_email_link_button, invite_facebook_button2): These labels appear under
## an iconic button for the invite view.
@ -250,3 +261,5 @@ self_view_hidden_message=Váš obraz byl skryt, ale je nadále odesílán; pro j
## LOCALIZATION NOTE (tos_failure_message): Don't translate {{clientShortname}}
## as this will be replaced by clientShortname2.
tos_failure_message={{clientShortname}} není ve vaší zemi dostupný.
display_name_guest=Host

View File

@ -28,17 +28,39 @@ sign_in_again_use_as_guest_button2=Brug {{clientSuperShortname}} som gæst
panel_browse_with_friend_button=Besøg siden sammen med en ven
panel_disconnect_button=Afbryd forbindelse
## LOCALIZATION_NOTE(first_time_experience_subheading2): Message inviting the
## LOCALIZATION_NOTE(first_time_experience_subheading2, first_time_experience_subheading_button_above): Message inviting the
## user to create his or her first conversation.
first_time_experience_subheading2=Klik på Hello-knappen for at bruge nettet sammen med en ven.
first_time_experience_subheading_button_above=Klik på knappen ovenfor for at surfe på internettet sammen med en ven.
## LOCALIZATION_NOTE(first_time_experience_content): Message describing
## LOCALIZATION_NOTE(first_time_experience_content, first_time_experience_content2): Message describing
## ways to use Hello project.
first_time_experience_content=Brug det til at planlægge, arbejde og grine sammen.
first_time_experience_content2=Brug den til at få tingene gjort: planlæg sammen, le sammen, arbejd sammen.
first_time_experience_button_label2=Se, hvordan det fungerer
## First Time Experience Slides
fte_slide_1_title=Surf på internettet sammen med en ven
## LOCALIZATION_NOTE(fte_slide_1_copy): {{clientShortname2}}
## will be replaced by the short name 2.
fte_slide_1_copy=Med {{clientShortname2}} kan du tage hurtigere beslutninger i realtid, uanset om du planlægger en rejse eller indkøb af en gave.
fte_slide_2_title=Surf sammen
fte_slide_2_copy=Brug den indbyggede tekst- eller video-chat til at dele ideér, sammenligne muligheder og blive enige.
fte_slide_3_title=Invitér en ven ved at sende vedkommende et link
## LOCALIZATION_NOTE(fte_slide_3_copy): {{clientSuperShortname}}
## will be replaced by the super short brand name.
fte_slide_3_copy={{clientSuperShortname}} virker med de fleste computer-browsere. Det er ikke nødvendigt med en konto og alle forbinder gratis.
## LOCALIZATION_NOTE(fte_slide_4_title): {{clientSuperShortname}}
## will be replaced by the super short brand name.
fte_slide_4_title=Find ikonet {{clientSuperShortname}} for at komme i gang
## LOCALIZATION_NOTE(fte_slide_4_copy): {{brandShortname}}
## will be replaced by the brand short name.
fte_slide_4_copy=Når I har fundet en side, I vil diskutere, så klik på ikonet i {{brandShortname}} for at oprette et link. Send så linket til din ven.
invite_header_text_bold=Inviter nogen til at besøge siden sammen med dig.
invite_header_text_bold2=Invitèr en ven til at være med!
invite_header_text3=Det kræver selskab at bruge Firefox Hello, så send et link til én af dine venner sådan at I kan bruge nettet sammen.
invite_header_text4=Del dette link, så I kan begynde at surfe på internettet sammen.
## LOCALIZATION_NOTE(invite_copy_link_button, invite_copied_link_button,
## invite_email_link_button, invite_facebook_button2): These labels appear under
## an iconic button for the invite view.
@ -48,9 +70,6 @@ invite_email_link_button=Mail link
invite_facebook_button3=Facebook
invite_your_link=Dit link:
# Status text
display_name_guest=Gæst
# Error bars
## LOCALIZATION NOTE(session_expired_error_description,could_not_authenticate,password_changed_question,try_again_later,could_not_connect,check_internet_connection,login_expired,service_not_available,problem_accessing_account):
## These may be displayed at the top of the panel.
@ -148,8 +167,7 @@ ice_failure_message=Forbindelse mislykkedes. Din firewall blokerer muligvis opka
## parts between {{..}} because these will be replaced with links with the labels
## from legal_text_tos and legal_text_privacy. clientShortname will be replaced
## by the brand name.
legal_text_and_links3=Ved at bruge {{clientShortname}} accepterer du {{terms_of_use}} \
og {{privacy_notice}}.
legal_text_and_links3=Ved at bruge {{clientShortname}} accepterer du {{terms_of_use}} og {{privacy_notice}}.
legal_text_tos=betingelserne for brug
legal_text_privacy=privatlivspolitikken
@ -182,7 +200,9 @@ door_hanger_button=OK
# Infobar strings
infobar_screenshare_no_guest_message=Lige så snart din ven deltager, vil hun kunne se de faneblade, du klikker på.
infobar_screenshare_browser_message2=Du deler dine faneblade. Når du klikker på et faneblad kan dine venner se det
infobar_screenshare_browser_message3=Du deler nu dine faneblade. Din ven vil kunne se de faneblade, du klikker på.
infobar_screenshare_stop_sharing_message=Du deler ikke dine faneblade længere
infobar_button_restart_label2=Genstart deling
infobar_button_restart_accesskey=e

View File

@ -10,7 +10,7 @@ clientSuperShortname=Hello
## inside the browser 'Tools' menu. Use the unicode ellipsis char, \u2026, or
## use "..." if \u2026 doesn't suit traditions in your locale.
loopMenuItem_label=Gespräch beginnen…
loopMenuItem_accesskey=t
loopMenuItem_accesskey=G
## LOCALIZATION_NOTE(sign_in_again_title_line_one, sign_in_again_title_line_two2):
## These are displayed together at the top of the panel when a user is needed to
@ -43,7 +43,7 @@ first_time_experience_button_label2=Sehen Sie sich an, wie es funktioniert
fte_slide_1_title=Surfen Sie gemeinsam mit einem Freund
## LOCALIZATION_NOTE(fte_slide_1_copy): {{clientShortname2}}
## will be replaced by the short name 2.
fte_slide_1_copy=Egal ob Sie eine Reise planen oder ein Geschenk einkaufen, mit {{clientShortname2}} können Sie schnellere Entscheidungen in Echtzeit treffen.
fte_slide_1_copy=Egal, ob Sie eine Reise planen oder ein Geschenk einkaufen, mit {{clientShortname2}} können Sie schnellere Entscheidungen in Echtzeit treffen.
fte_slide_2_title=Rufen Sie die gleiche Seite auf
fte_slide_2_copy=Verwenden Sie den integrierten Text- oder Videochat, um Ideen auszutauschen, Optionen zu vergleichen und zu einer Einigung zu kommen.
fte_slide_3_title=Laden Sie einen Freund ein, indem Sie ihm einen Link senden
@ -206,9 +206,9 @@ infobar_screenshare_browser_message2=Sie geben Ihre Tabs weiter. Jeder von Ihnen
infobar_screenshare_browser_message3=Sie geben jetzt Ihre Tabs weiter. Ihr Freund kann alle Tabs sehen, die Sie anklicken.
infobar_screenshare_stop_sharing_message=Sie geben Ihre Tabs nicht mehr weiter.
infobar_button_restart_label2=Wieder weitergeben
infobar_button_restart_accesskey=s
infobar_button_restart_accesskey=W
infobar_button_stop_label2=Nicht mehr weitergeben
infobar_button_stop_accesskey=b
infobar_button_stop_accesskey=N
infobar_button_disconnect_label=Verbindung trennen
infobar_button_disconnect_accesskey=t

View File

@ -4,13 +4,13 @@
# Panel Strings
clientSuperShortname=Hola
clientSuperShortname=Hello
## LOCALIZATION_NOTE(loopMenuItem_label): Label of the menu item that is placed
## inside the browser 'Tools' menu. Use the unicode ellipsis char, \u2026, or
## use "..." if \u2026 doesn't suit traditions in your locale.
loopMenuItem_label=Iniciar una conversación…
loopMenuItem_accesskey=t
loopMenuItem_accesskey=I
## LOCALIZATION_NOTE(sign_in_again_title_line_one, sign_in_again_title_line_two2):
## These are displayed together at the top of the panel when a user is needed to
@ -23,7 +23,7 @@ sign_in_again_title_line_two2=para continuar utilizando {{clientShortname2}}
sign_in_again_button=Iniciar sesión
## LOCALIZATION_NOTE(sign_in_again_use_as_guest_button2): {{clientSuperShortname}}
## will be replaced by the super short brandname.
sign_in_again_use_as_guest_button2=Utiliza {{clientSuperShortname}} como Invitado
sign_in_again_use_as_guest_button2=Utiliza {{clientSuperShortname}} como invitado
panel_browse_with_friend_button=Navega por la página con un amigo
panel_disconnect_button=Desconectar
@ -31,36 +31,36 @@ panel_disconnect_button=Desconectar
## LOCALIZATION_NOTE(first_time_experience_subheading2, first_time_experience_subheading_button_above): Message inviting the
## user to create his or her first conversation.
first_time_experience_subheading2=Haz clic en el botón de Hello para navegar por la Web con un amigo.
first_time_experience_subheading_button_above=Pulse en el botón de arriba para navegar por páginas web con un amigo.
first_time_experience_subheading_button_above=Haz clic en el botón de arriba para navegar por páginas web con un amigo.
## LOCALIZATION_NOTE(first_time_experience_content, first_time_experience_content2): Message describing
## ways to use Hello project.
first_time_experience_content=Utilízalo para hacer planes, trabajar y reír juntos.
first_time_experience_content2=Úselo para llevar a cabo tareas; planear juntos, divertirse juntos, trabajar juntos.
first_time_experience_content=Úsalo para hacer planes juntos, divertirse juntos, trabajar juntos.
first_time_experience_content2=Úsalo para llevar a cabo tareas; hacer planes juntos, divertirse juntos, trabajar juntos.
first_time_experience_button_label2=Aprende cómo funciona
## First Time Experience Slides
fte_slide_1_title=Navegue por páginas web con un amigo
fte_slide_1_title=Navega por páginas web con un amigo
## LOCALIZATION_NOTE(fte_slide_1_copy): {{clientShortname2}}
## will be replaced by the short name 2.
fte_slide_1_copy=Tanto si está planeando un viaje o buscando un regalo para comprarlo, {{clientShortname2}} le permite tomar decisiones más rápidas en tiempo real.
fte_slide_2_title=Reúnanse en la misma página
fte_slide_2_copy=Use los chats incluidos de texto o vídeo para compartir ideas, comparar opciones o llegar a acuerdos.
fte_slide_3_title=Invite a un amigo enviando un enlace
fte_slide_1_copy=Tanto si estás planeando un viaje o buscando un regalo para comprarlo, {{clientShortname2}} te permite tomar decisiones más rápidas en tiempo real.
fte_slide_2_title=Reuníos en la misma página
fte_slide_2_copy=Usa los chats incluidos de texto o vídeo para compartir ideas, comparar opciones o llegar a acuerdos.
fte_slide_3_title=Invita a un amigo enviando un enlace
## LOCALIZATION_NOTE(fte_slide_3_copy): {{clientSuperShortname}}
## will be replaced by the super short brand name.
fte_slide_3_copy={{clientSuperShortnae}} funciona con la mayoría de los navegadores de escritorio. No es necesario tener cuenta y todo el mundo se conecta gratuitamente.
## LOCALIZATION_NOTE(fte_slide_4_title): {{clientSuperShortname}}
## will be replaced by the super short brand name.
fte_slide_4_title=Encuentre el icono de {{clientSuperShortname}} para comenzar
fte_slide_4_title=Busca el icono de {{clientSuperShortname}} para comenzar
## LOCALIZATION_NOTE(fte_slide_4_copy): {{brandShortname}}
## will be replaced by the brand short name.
fte_slide_4_copy=Cuando encuentre una página sobre la que conversar, pulse el icono en {{brandShortname}} para crear un enlace. ¡Luego envíela a su amigo como mejor le parezca!
fte_slide_4_copy=Cuando encuentres una página sobre la que conversar, pulsa el icono en {{brandShortname}} para crear un enlace. ¡Luego envíala a tu amigo como mejor te parezca!
invite_header_text_bold=¡Invita a alguien a navegar por la página contigo!
invite_header_text_bold2=¡Invite a un amigo a unirse a usted!
invite_header_text_bold2=¡Invita a un amigo a unirse a ti!
invite_header_text3=Se necesitan dos personas para utilizar Firefox Hello. ¡Envíale el enlace a un amigo y navegad juntos!
invite_header_text4=Comparta este enlace para que puedan comenzar a navegar juntos por la web.
invite_header_text4=Comparte este enlace para que podáis comenzar a navegar juntos por la web.
## LOCALIZATION_NOTE(invite_copy_link_button, invite_copied_link_button,
## invite_email_link_button, invite_facebook_button2): These labels appear under
## an iconic button for the invite view.
@ -73,13 +73,13 @@ invite_your_link=Tu enlace:
# Error bars
## LOCALIZATION NOTE(session_expired_error_description,could_not_authenticate,password_changed_question,try_again_later,could_not_connect,check_internet_connection,login_expired,service_not_available,problem_accessing_account):
## These may be displayed at the top of the panel.
session_expired_error_description=Ha expirado la sesión. Ya no te funcionarán las URLs que hayas creado o compartido antes.
session_expired_error_description=Ha caducado la sesión. Ya no te funcionarán las URL que hayas creado o compartido antes.
could_not_authenticate=No se pudo autenticar
password_changed_question=¿Has cambiado la contraseña?
try_again_later=Por favor, vuelve a intentarlo luego
could_not_connect=No se pudo conectar al servidor
check_internet_connection=Por favor, comprueba tu conexión a internet
login_expired=Tu sesión ha expirado
check_internet_connection=Por favor, comprueba tu conexión a Internet
login_expired=Tu sesión ha caducado
service_not_available=El servicio no está disponible en este momento
problem_accessing_account=Hubo un problema al acceder a tu cuenta
@ -95,13 +95,13 @@ share_email_body7=Un amigo te está esperando en Firefox Hello. Haz clic en el e
## the part between {{..}} and leave the \n\n part alone.
share_email_body_context3=Un amigo te está esperando en Firefox Hello. Haz clic en el enlace para conectarte y navegar juntos por {{title}}: {{callUrl}}
## LOCALIZATION NOTE (share_email_footer2): Common footer content for both email types
share_email_footer2=\n\n____________\n Firefox Hello te permite navegar por la Web con tus amigos. Utilízadlo cuando queráis para hacer planes, trabajar o reír juntos. Obtén más información en http://www.firefox.com/hello
share_email_footer2=\n\n____________\n Firefox Hello te permite navegar por la Web con tus amigos. Utilizadlo cuando queráis hacer planes, trabajar o reír juntos. Obtén más información en http://www.firefox.com/hello
## LOCALIZATION NOTE (share_tweeet): In this item, don't translate the part
## between {{..}}. Please keep the text below 117 characters to make sure it fits
## in a tweet.
share_tweet=¡Únete para que iniciemos una conversación con video en {{clientShortname2}}!
share_tweet=¡Únete para que iniciemos una conversación con vídeo en {{clientShortname2}}!
share_add_service_button=Agregar un servicio
share_add_service_button=Añadir un servicio
## LOCALIZATION NOTE (copy_link_menuitem, email_link_menuitem, delete_conversation_menuitem):
## These menu items are displayed from a panel's context menu for a conversation.
@ -117,7 +117,7 @@ settings_menu_item_signout=Cerrar sesión
settings_menu_item_signin=Iniciar sesión
settings_menu_item_turnnotificationson=Activar notificaciones
settings_menu_item_turnnotificationsoff=Desactivar notificaciones
settings_menu_item_feedback=Enviar compentario
settings_menu_item_feedback=Enviar comentario
settings_menu_button_tooltip=Configuración
@ -139,7 +139,7 @@ call_with_contact_title=Conversación con {{contactName}}
outgoing_call_title=¿Iniciar una conversación?
initiate_audio_video_call_button2=Iniciar
initiate_audio_video_call_tooltip2=Iniciar una conversación con video
initiate_audio_video_call_tooltip2=Iniciar una conversación con vídeo
initiate_audio_call_button2=Conversación de voz
peer_ended_conversation2=La persona a la que llamaste ha finalizado la conversación.
@ -157,11 +157,11 @@ call_timeout_notification_text=No se pudo realizar la llamada.
cancel_button=Cancelar
rejoin_button=Volver a unirse a la conversación
cannot_start_call_session_not_ready=No puedes hacer una llamara, la sesión no está lista.
cannot_start_call_session_not_ready=No puedes hacer una llamada, la sesión no está lista.
network_disconnected=La conexión de red se ha interrumpido de repente.
connection_error_see_console_notification=Llamada fallida; comprueba la consola para más detalles.
no_media_failure_message=No se encuentran cámara ni micrófono.
ice_failure_message=Ha fallado la conexión. Puede que el firewall esté bloqueando las llamadas.
no_media_failure_message=No se encuentra cámara ni micrófono.
ice_failure_message=Ha fallado la conexión. Puede que el cortafuegos esté bloqueando las llamadas.
## LOCALIZATION NOTE (legal_text_and_links3): In this item, don't translate the
## parts between {{..}} because these will be replaced with links with the labels
@ -179,14 +179,14 @@ powered_by_afterLogo=
## LOCALIZATION_NOTE (feedback_rejoin_button): Displayed on the feedback form after
## a signed-in to signed-in user call.
feedback_rejoin_button=Volver a unirse
feedback_rejoin_button=Volver a unirte
## LOCALIZATION NOTE (feedback_report_user_button): Used to report a user in the case of
## an abusive user.
feedback_report_user_button=Denunciar usuario
feedback_window_heading=¿Qué tal fue la conversación?
feedback_request_button=Dejar comentario
tour_label=Tour
tour_label=Visita guiada
rooms_list_recently_browsed2=Visitadas recientemente
rooms_list_currently_browsing2=Visitando actualmente
@ -200,9 +200,9 @@ door_hanger_button=Aceptar
# Infobar strings
infobar_screenshare_no_guest_message=Tan pronto se una su amigo, podrá ver cualquier pestaña en la que pulse usted.
infobar_screenshare_browser_message2=Estás compartiendo tus pestañas. Si haces clic en una de ellas, tus amigos también la verán
infobar_screenshare_browser_message3=Ahora está compartiendo sus pestañas. Su amigo verá cualquier pestaña en la que pulse usted.
infobar_screenshare_no_guest_message=Tan pronto se una tu amigo, podrá ver cualquier pestaña en la que pulses tú.
infobar_screenshare_browser_message2=Estás compartiendo tus pestañas. Cualquier pestaña en la que pulses puede ser vista por tus amigos
infobar_screenshare_browser_message3=Ahora estás compartiendo tus pestañas. Tu amigo verá cualquier pestaña en la que pulses.
infobar_screenshare_stop_sharing_message=Ya no compartes tus pestañas
infobar_button_restart_label2=Volver a compartir
infobar_button_restart_accesskey=e
@ -237,8 +237,8 @@ help_label=Ayuda
mute_local_audio_button_title=Silenciar sonido
unmute_local_audio_button_title=Activar sonido
mute_local_video_button_title2=Desactivar video
unmute_local_video_button_title2=Activar video
mute_local_video_button_title2=Desactivar vídeo
unmute_local_video_button_title2=Activar vídeo
## LOCALIZATION NOTE (retry_call_button):
## This button is displayed when a call has failed.

View File

@ -18,49 +18,49 @@ loopMenuItem_accesskey=t
## and this is displayed in slightly larger font. Please arrange as necessary for
## your locale.
## {{clientShortname2}} will be replaced by the brand name for either string.
sign_in_again_title_line_one=Por favor, inicia sesión de nuevo
sign_in_again_title_line_one=Vuelve a iniciar sesión
sign_in_again_title_line_two2=para continuar usando {{clientShortname2}}
sign_in_again_button=Iniciar sesión
## LOCALIZATION_NOTE(sign_in_again_use_as_guest_button2): {{clientSuperShortname}}
## will be replaced by the super short brandname.
sign_in_again_use_as_guest_button2=Usar {{clientSuperShortname}} como un Invitado
sign_in_again_use_as_guest_button2=Usar {{clientSuperShortname}} como invitado
panel_browse_with_friend_button=Navegar esta página con un amigo
panel_browse_with_friend_button=Explorar esta página con un amigo
panel_disconnect_button=Desconectar
## LOCALIZATION_NOTE(first_time_experience_subheading2, first_time_experience_subheading_button_above): Message inviting the
## user to create his or her first conversation.
first_time_experience_subheading2=Haz clic en el botón de Hello para para navegar las páginas Web con un amigo.
first_time_experience_subheading_button_above=Haz clic en el botón de arriba para navegar la Web con un amigo.
first_time_experience_subheading2=Haz clic en el botón Hello para explorar las páginas Web con un amigo.
first_time_experience_subheading_button_above=Haz clic en el botón de arriba para explorar la Web con un amigo.
## LOCALIZATION_NOTE(first_time_experience_content, first_time_experience_content2): Message describing
## ways to use Hello project.
first_time_experience_content=Úsalo para planear cosas juntos, trabajar juntos, reír juntos.
first_time_experience_content2=Úsalo para hacer las cosas bien: planear algo juntos, reír juntos, trabajar juntos.
first_time_experience_button_label2=Ver como trabaja
first_time_experience_content=Úsalo para hacer planes juntos, trabajar juntos, reír juntos.
first_time_experience_content2=Úsalo para hacer cosas: planear algo juntos, reír juntos, trabajar juntos.
first_time_experience_button_label2=Ver cómo funciona
## First Time Experience Slides
fte_slide_1_title=Navega páginas Web con un amigo
fte_slide_1_title=Explora páginas Web con un amigo
## LOCALIZATION_NOTE(fte_slide_1_copy): {{clientShortname2}}
## will be replaced by the short name 2.
fte_slide_1_copy=Ya sea que estés planeando un viaje o comprar un regalo, {{clientShortname2}} te permite tomar decisiones más rápido en tiempo real.
fte_slide_1_copy=Ya sea que estés planeando un viaje o comprando un regalo, {{clientShortname2}} te permite tomar decisiones más rápido en tiempo real.
fte_slide_2_title=Estar en la misma página
fte_slide_2_copy=Usa el texto incorporado o el videochat para compartir ideas, comparar opciones y llegar a acuerdos.
fte_slide_2_copy=Usa los chats incluidos de texto o video para compartir ideas, comparar opciones y lograr acuerdos.
fte_slide_3_title=Invita a un amigo enviándole un enlace
## LOCALIZATION_NOTE(fte_slide_3_copy): {{clientSuperShortname}}
## will be replaced by the super short brand name.
fte_slide_3_copy={{clientSuperShortname}} trabaja con la mayoría de los navegadores de escritorio. No se necesita cuentas y todos se pueden conectar gratis.
fte_slide_3_copy={{clientSuperShortname}} funciona con la mayoría de los navegadores de escritorio. No es necesario tener cuenta y todos se pueden conectar gratis.
## LOCALIZATION_NOTE(fte_slide_4_title): {{clientSuperShortname}}
## will be replaced by the super short brand name.
fte_slide_4_title=Encuentra el ícono de {{clientSuperShortname}} para comenzar
fte_slide_4_title=Busca el icono de {{clientSuperShortname}} para comenzar
## LOCALIZATION_NOTE(fte_slide_4_copy): {{brandShortname}}
## will be replaced by the brand short name.
fte_slide_4_copy=Una vez que encuentres una página que quieras discutir, haz clic en el ícono de {{brandShortname}} para crear un enlace. ¡Entonces envíalo al amigo que quieras!
fte_slide_4_copy=Una vez que encuentres una página que quieras discutir, haz clic en el icono de {{brandShortname}} para crear un enlace. ¡Luego envíaselo a tu amigo como mejor te parezca!
invite_header_text_bold=Invita a alguien para navegar esta página contigo.
invite_header_text_bold2=¡Invita a un amigo a unirse!
invite_header_text3=Es muy fácil usar Firefox Hello, ¡simplemente envía a tu amigo un enlace para navegar la Web contigo!
invite_header_text4=Compartir este enlace para que así puedan iniciar a navegar la Web juntos.
invite_header_text_bold=¡Invita a alguien para explorar esta página contigo!
invite_header_text_bold2=¡Invita a un amigo a unirse a ti!
invite_header_text3=Hacen falta dos para usar Firefox Hello, ¡así que envíale un enlace a tu amigo para navegar la Web juntos!
invite_header_text4=Comparte este enlace para que puedan iniciar a explorar juntos la Web.
## LOCALIZATION_NOTE(invite_copy_link_button, invite_copied_link_button,
## invite_email_link_button, invite_facebook_button2): These labels appear under
## an iconic button for the invite view.
@ -73,11 +73,11 @@ invite_your_link=Tu enlace:
# Error bars
## LOCALIZATION NOTE(session_expired_error_description,could_not_authenticate,password_changed_question,try_again_later,could_not_connect,check_internet_connection,login_expired,service_not_available,problem_accessing_account):
## These may be displayed at the top of the panel.
session_expired_error_description=La sesión ha expirado. Todas las URLs que creaste con anterioridad y compartiste no funcionarán más.
could_not_authenticate=No se puede autenticar
session_expired_error_description=La sesión ha expirado. Las URLs que creaste o compartiste antes ya no funcionarán.
could_not_authenticate=No se pudo autenticar
password_changed_question=¿Cambiaste tu contraseña?
try_again_later=Por favor, inténtalo de nuevo más tarde
could_not_connect=No se puede conectar al servidor
could_not_connect=No se pudo conectar al servidor
check_internet_connection=Por favor, revisa tu conexión a Internet
login_expired=Te sesión ha expirado
service_not_available=El servicio no está disponible por ahora
@ -87,13 +87,13 @@ problem_accessing_account=Hubo un problema accediendo a tu cuenta
## the appropriate action.
retry_button=Reintentar
share_email_subject7=Tu invitación para navegar la Web juntos
share_email_subject7=Tu invitación para explorar juntos la Web
## LOCALIZATION NOTE (share_email_body7): In this item, don't translate the
## part between {{..}} and leave the \n\n part alone
share_email_body7=Un amigo está esperando por ti en Firefox Hello. Haz clic en el enlace para conectarte y navegar la Web juntos: {{callUrl}}
share_email_body7=Un amigo está esperándote en Firefox Hello. Haz clic en el enlace para conectarte y explorar juntos la Web: {{callUrl}}
## LOCALIZATION NOTE (share_email_body_context3): In this item, don't translate
## the part between {{..}} and leave the \n\n part alone.
share_email_body_context3=Un amigo está esperando por ti en Firefox Hello. Haz clic en el enlace para conectarte y navegar {{title}} juntos: {{callUrl}}
share_email_body_context3=Un amigo está esperándote en Firefox Hello. Haz clic en el enlace para conectarte y explorar {{title}} juntos: {{callUrl}}
## LOCALIZATION NOTE (share_email_footer2): Common footer content for both email types
share_email_footer2=\n\n___\nFirefox Hello te permite navegar por la Web con tus amigos. Puedes usarlo cada vez que quieras hacer algo: planificar, trabajar juntos, reír juntos. Más información en http://www.firefox.com/hello
## LOCALIZATION NOTE (share_tweeet): In this item, don't translate the part
@ -207,14 +207,14 @@ infobar_screenshare_stop_sharing_message=Ya no estás compartiendo tus pestañas
infobar_button_restart_label2=Volver a compartir
infobar_button_restart_accesskey=e
infobar_button_stop_label2=Dejar de compartir
infobar_button_stop_accesskey=S
infobar_button_stop_accesskey=c
infobar_button_disconnect_label=Desconectar
infobar_button_disconnect_accesskey=D
# E10s not supported strings
e10s_not_supported_button_label=Ejecutar una nueva ventana
e10s_not_supported_subheading={{brandShortname}} no funciona en una ventana multiproceso.
e10s_not_supported_button_label=Abrir una nueva ventana
e10s_not_supported_subheading={{brandShortname}} no funciona en ventanas multiproceso.
# 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/.

View File

@ -19,26 +19,48 @@ loopMenuItem_accesskey=t
## your locale.
## {{clientShortname2}} will be replaced by the brand name for either string.
sign_in_again_title_line_one=Palun logi uuesti sisse,
sign_in_again_title_line_two2=et jätkata {{clientShortname2}}i kasutamist
sign_in_again_title_line_two2=et jätkata {{clientShortname2}} kasutamist
sign_in_again_button=Logi sisse
## LOCALIZATION_NOTE(sign_in_again_use_as_guest_button2): {{clientSuperShortname}}
## will be replaced by the super short brandname.
sign_in_again_use_as_guest_button2=Kasuta {{clientSuperShortname}}i külalisena
sign_in_again_use_as_guest_button2=Kasuta {{clientSuperShortname}}t külalisena
panel_browse_with_friend_button=Lehitse seda lehte koos sõbraga
panel_disconnect_button=Lõpeta ühendus
## LOCALIZATION_NOTE(first_time_experience_subheading2): Message inviting the
## LOCALIZATION_NOTE(first_time_experience_subheading2, first_time_experience_subheading_button_above): Message inviting the
## user to create his or her first conversation.
first_time_experience_subheading2=Veebilehtede sirvimiseks koos sõbraga klõpsa Hello nupul.
first_time_experience_subheading_button_above=Veebilehtede sirvimiseks koos sõbraga klõpsa ülal oleval nupul.
## LOCALIZATION_NOTE(first_time_experience_content): Message describing
## LOCALIZATION_NOTE(first_time_experience_content, first_time_experience_content2): Message describing
## ways to use Hello project.
first_time_experience_content=Kasuta seda ühiseks plaanimiseks, töötamiseks ja naermiseks.
first_time_experience_content2=Kasuta seda asjade ära tegemiseks: ühiseks plaanimiseks, töötamiseks ja naermiseks.
first_time_experience_button_label2=Vaata, kuidas see töötab
## First Time Experience Slides
fte_slide_1_title=Lehitse veebilehti koos sõbraga
## LOCALIZATION_NOTE(fte_slide_1_copy): {{clientShortname2}}
## will be replaced by the short name 2.
fte_slide_1_copy=Kui plaanid reisi või otsid kingitust, siis võimaldab {{clientShortname2}} sul kiiremini otsustada.
fte_slide_2_title=Olge samal veebilehel.
fte_slide_2_copy=Kasuta sisseehitatud teksti- või videovestlust ideede jagamiseks, valikute võrdlemiseks ning ühisele otsusele jõudmiseks.
fte_slide_3_title=Kutsu sõber, saates talle lingi.
## LOCALIZATION_NOTE(fte_slide_3_copy): {{clientSuperShortname}}
## will be replaced by the super short brand name.
fte_slide_3_copy={{clientSuperShortname}} töötab enamikus töölaua veebilehitsejates. Kontot pole vaja ning ühendumine on tasuta.
## LOCALIZATION_NOTE(fte_slide_4_title): {{clientSuperShortname}}
## will be replaced by the super short brand name.
fte_slide_4_title=Leia {{clientSuperShortname}} ikoon ning tee algust.
## LOCALIZATION_NOTE(fte_slide_4_copy): {{brandShortname}}
## will be replaced by the brand short name.
fte_slide_4_copy=Kui oled leidnud lehe, mida soovid arutada, siis klõpsa ikoonil {{brandShortname}}s ning loo link. Seejärel saada see sõbrale, kuidas iganes soovid!
invite_header_text_bold=Kutsu keegi teine seda lehte vaatama!
invite_header_text_bold2=Kutsu sõber endaga ühinema!
invite_header_text3=Firefox Hello kasutamiseks on vaja kahte kasutajat. Saada sõbrale link!
invite_header_text4=Jaga seda linki, et saaksite koos veebilehitsemist alustada.
## LOCALIZATION_NOTE(invite_copy_link_button, invite_copied_link_button,
## invite_email_link_button, invite_facebook_button2): These labels appear under
## an iconic button for the invite view.
@ -48,9 +70,6 @@ invite_email_link_button=Saada link e-postiga
invite_facebook_button3=Facebook
invite_your_link=Sinu link:
# Status text
display_name_guest=Külaline
# Error bars
## LOCALIZATION NOTE(session_expired_error_description,could_not_authenticate,password_changed_question,try_again_later,could_not_connect,check_internet_connection,login_expired,service_not_available,problem_accessing_account):
## These may be displayed at the top of the panel.
@ -182,7 +201,9 @@ door_hanger_button=Olgu
# Infobar strings
infobar_screenshare_no_guest_message=Niipea kui su sõber liitub, näeb ta sinu valitud kaarti.
infobar_screenshare_browser_message2=Jagad enda kaarte. Sinu sõbrad näevad kaarti, mille oled valinud.
infobar_screenshare_browser_message3=Jagad nüüd enda kaarte. Sinu sõber näeb kaarti, mille oled valinud.
infobar_screenshare_stop_sharing_message=Sa ei jaga enam kaarte.
infobar_button_restart_label2=Alusta jagamist uuesti
infobar_button_restart_accesskey=s
@ -240,3 +261,5 @@ self_view_hidden_message=Sinu pilti edastatakse, kuid see on praegu peidetud. Pi
## LOCALIZATION NOTE (tos_failure_message): Don't translate {{clientShortname}}
## as this will be replaced by clientShortname2.
tos_failure_message={{clientShortname}} pole sinu riigis saadaval.
display_name_guest=Külaline

View File

@ -28,17 +28,39 @@ sign_in_again_use_as_guest_button2=استفاده از {{clientSuperShortname}}
panel_browse_with_friend_button=این صفحه را با همراهی یک دوست مرور کنید
panel_disconnect_button=قطع ارتباط
## LOCALIZATION_NOTE(first_time_experience_subheading2): Message inviting the
## LOCALIZATION_NOTE(first_time_experience_subheading2, first_time_experience_subheading_button_above): Message inviting the
## user to create his or her first conversation.
first_time_experience_subheading2=بر روی دکمه Hello کلیک کنید تا با همراهی یک دوست صفحه را مرور کنید.
first_time_experience_subheading_button_above=بر روی دکمه بالا کلی کنید تا وب را با یک دوست مرور کنید.
## LOCALIZATION_NOTE(first_time_experience_content): Message describing
## LOCALIZATION_NOTE(first_time_experience_content, first_time_experience_content2): Message describing
## ways to use Hello project.
first_time_experience_content=برای برنامه‌ریزی گروهی، کار کردن گروهی و خندیدن با هم استفاده کنید.
first_time_experience_content2=برای به سرانجام رساندن کارها از آن استفاده کنید: با هم برنامه‌ریزی کنید، با هم بخندید، با هم کار کنید.
first_time_experience_button_label2=نحوه کار را یاد بگیرید
## First Time Experience Slides
fte_slide_1_title=صفحات وب را با یک دوست مرور کنید
## LOCALIZATION_NOTE(fte_slide_1_copy): {{clientShortname2}}
## will be replaced by the short name 2.
fte_slide_1_copy=اگر در حال برنامه‌ریزی برای یک سفر هستید یا قصد خرید یک هدیه را دارید، {{clientShortname2}} به شما اجازه می‌دهد تا زمانی کوتاه تصمیمات سریع‌تر بگیرید.
fte_slide_2_title=با هم هماهنگ باشید
fte_slide_2_copy=از سیستم گپ ویدئویی یا متنی برای به اشتراک گذاشتن ایده‌ها، مقایسه گزینه‌ها و رسیدن به تفاهم، استفاده کنید.
fte_slide_3_title=یک دوست را با ارسال یک پیوند دعوت کنید
## LOCALIZATION_NOTE(fte_slide_3_copy): {{clientSuperShortname}}
## will be replaced by the super short brand name.
fte_slide_3_copy={{clientSuperShortname}} با اکثر مرورگرهای رومیزی کار می‌کند. هیچ حسابی لازم نیست و هر کسی می‌تواند به رایگان متصل شود.
## LOCALIZATION_NOTE(fte_slide_4_title): {{clientSuperShortname}}
## will be replaced by the super short brand name.
fte_slide_4_title=شمایل {{clientSuperShortname}} را برای شروع پیدا کنید
## LOCALIZATION_NOTE(fte_slide_4_copy): {{brandShortname}}
## will be replaced by the brand short name.
fte_slide_4_copy=زمانی که صفحه‌ای پیدا کردید تا موردش بحث کنید، بر روی شمایل {{brandShortname}} کلیک کنید تا یک پیوند بسازید. سپس آن را هر طور که دوست دارید برای دوست خود ارسال کنید!
invite_header_text_bold=یک نفر را برای همراهی در مرور اینه صفحه دعوت کنید!
invite_header_text_bold2=از یک دوست برای پیوستن به شما دعوت کنید!
invite_header_text3=برای کار کردن با Firefox Hello باید دو نفر باشید، پس برای دوست خود یک پیوند بفرستید تا وب را با هم مرور کنید!
invite_header_text4=این پیوند را برای شروع مرور وب با هم به اشتراک بگذارید.
## LOCALIZATION_NOTE(invite_copy_link_button, invite_copied_link_button,
## invite_email_link_button, invite_facebook_button2): These labels appear under
## an iconic button for the invite view.
@ -48,9 +70,6 @@ invite_email_link_button=پست پیوند
invite_facebook_button3=فیس‌بوک
invite_your_link=پیوند شما:
# Status text
display_name_guest=مهمان
# Error bars
## LOCALIZATION NOTE(session_expired_error_description,could_not_authenticate,password_changed_question,try_again_later,could_not_connect,check_internet_connection,login_expired,service_not_available,problem_accessing_account):
## These may be displayed at the top of the panel.
@ -181,7 +200,9 @@ door_hanger_button=تایید
# Infobar strings
infobar_screenshare_no_guest_message=هر موقع دوستان شما متصل شوند، آنها قادر خواهند بود هر زبانه‌ای که روی‌اش کلیک می‌کنید را ببینند.
infobar_screenshare_browser_message2=شما در حال اشتراک‌گذاری زبانه‌های خود هستید. هر زبانه‌ای که بر روی‌اش کلیک کنید، توسط دوستانتان دید میشود
infobar_screenshare_browser_message3=شما هم‌اکنون در حال اشتراک‌گذاری زبانه‌های خود هستید. دوستان شما هر زبانه‌ای که روی‌اش کلیک کنید را خواهند دید.
infobar_screenshare_stop_sharing_message=شما دیگر در حال اشتراک‌گذاری زبانه‌های خود نیستید
infobar_button_restart_label2=راه‌اندازی مجدد اشتراک‌گذاری
infobar_button_restart_accesskey=e
@ -239,3 +260,5 @@ self_view_hidden_message=نمای فردی پنهان شده است ولی ار
## LOCALIZATION NOTE (tos_failure_message): Don't translate {{clientShortname}}
## as this will be replaced by clientShortname2.
tos_failure_message={{clientShortname}} در کشور شما در دسترس نیست.
display_name_guest=مهمان

View File

@ -40,7 +40,7 @@ first_time_experience_content2=Utilisez vous pour réaliser vos projets : vous o
first_time_experience_button_label2=Principe de fonctionnement
## First Time Experience Slides
fte_slide_1_title=Naviguer sur le Web avec une autre personne
fte_slide_1_title=Naviguez sur le Web avec une autre personne
## LOCALIZATION_NOTE(fte_slide_1_copy): {{clientShortname2}}
## will be replaced by the short name 2.
fte_slide_1_copy=Que ce soit pour planifier un voyage ou l'achat d'un cadeau, {{clientShortname2}} vous permet de prendre des décisions plus rapidement.

View File

@ -28,15 +28,28 @@ sign_in_again_use_as_guest_button2=Cleachd {{clientSuperShortname}} mar aoigh
panel_browse_with_friend_button=Rùraich an duilleag seo còmhla ri caraid
panel_disconnect_button=Dì-cheangail
## LOCALIZATION_NOTE(first_time_experience_subheading2): Message inviting the
## LOCALIZATION_NOTE(first_time_experience_subheading2, first_time_experience_subheading_button_above): Message inviting the
## user to create his or her first conversation.
first_time_experience_subheading2=Briog air putan Hello gus duilleagan-lìn a rùrachadh còmhla ri caraid.
first_time_experience_subheading_button_above=Briog air a phutan gu h-àrd gus duilleagan-lìn a bhrabhsadh còmhla ri caraid.
## LOCALIZATION_NOTE(first_time_experience_content): Message describing
## LOCALIZATION_NOTE(first_time_experience_content, first_time_experience_content2): Message describing
## ways to use Hello project.
first_time_experience_content=Bruidhinn ri chèile, dèan obair còmhla ri chèile, dèan gàire còmhla ri chèile.
first_time_experience_content2=Dèan rudan còmhla: planadh, gàire, obair.
first_time_experience_button_label2=Seo mar a dhobraicheas e
## First Time Experience Slides
fte_slide_1_title=Brabhsaich duilleagan-lìn còmhla ri caraid
## LOCALIZATION_NOTE(fte_slide_1_copy): {{clientShortname2}}
## will be replaced by the short name 2.
## LOCALIZATION_NOTE(fte_slide_3_copy): {{clientSuperShortname}}
## will be replaced by the super short brand name.
## LOCALIZATION_NOTE(fte_slide_4_title): {{clientSuperShortname}}
## will be replaced by the super short brand name.
## LOCALIZATION_NOTE(fte_slide_4_copy): {{brandShortname}}
## will be replaced by the brand short name.
invite_header_text_bold=Thoir cuireadh do chuideigin a rùrachadh na duilleige seo còmhla riut!
invite_header_text3=Feumaidh tu co-dhiù dithis mus obraich Firefox Hello, nach cuir thu ceangal gu caraid a rùraicheas an lìon còmhla riut?
## LOCALIZATION_NOTE(invite_copy_link_button, invite_copied_link_button,
@ -48,9 +61,6 @@ invite_email_link_button=Cuir an ceangal air a phost-d
invite_facebook_button3=Facebook
invite_your_link=An ceangal agad:
# Status text
display_name_guest=Aoigh
# Error bars
## LOCALIZATION NOTE(session_expired_error_description,could_not_authenticate,password_changed_question,try_again_later,could_not_connect,check_internet_connection,login_expired,service_not_available,problem_accessing_account):
## These may be displayed at the top of the panel.
@ -239,3 +249,5 @@ self_view_hidden_message=Tha do dhealbh fhèin am falach ach 'ga chur fhathast;
## LOCALIZATION NOTE (tos_failure_message): Don't translate {{clientShortname}}
## as this will be replaced by clientShortname2.
tos_failure_message=Chan eil {{clientShortname}} ri fhaighinn nad dhùthaich.
display_name_guest=Aoigh

View File

@ -28,17 +28,39 @@ sign_in_again_use_as_guest_button2=A {{clientSuperShortname}} használata vendé
panel_browse_with_friend_button=Oldal böngészése ismerősével
panel_disconnect_button=Bontás
## LOCALIZATION_NOTE(first_time_experience_subheading2): Message inviting the
## LOCALIZATION_NOTE(first_time_experience_subheading2, first_time_experience_subheading_button_above): Message inviting the
## user to create his or her first conversation.
first_time_experience_subheading2=Kattintson a Hello gombra weboldalak böngészéséhez egy ismerősével.
first_time_experience_subheading_button_above=Kattintson a fenti gombra weboldalak böngészéséhez egy ismerősével.
## LOCALIZATION_NOTE(first_time_experience_content): Message describing
## LOCALIZATION_NOTE(first_time_experience_content, first_time_experience_content2): Message describing
## ways to use Hello project.
first_time_experience_content=Használja közös tervezésre, munkára, nevetésre.
first_time_experience_content2=Használja feladatai elvégzéséhez: tervezzen, nevessen, dolgozzon közösen.
first_time_experience_button_label2=Hogyan működik?
## First Time Experience Slides
fte_slide_1_title=Weboldalak böngészése ismerősével
## LOCALIZATION_NOTE(fte_slide_1_copy): {{clientShortname2}}
## will be replaced by the short name 2.
fte_slide_1_copy=Ha utazást tervez vagy ajándékot vásárol, a {{clientShortname2}} segít gyorsabb döntést hozni valós időben.
fte_slide_2_title=Kerüljenek egy lapra
fte_slide_2_copy=Használja a beépített szöveges vagy videócsevegést ötletek megosztására, lehetőségek összehasonlítására és megegyezésre.
fte_slide_3_title=Hívja meg ismerősét egy hivatkozás küldésével
## LOCALIZATION_NOTE(fte_slide_3_copy): {{clientSuperShortname}}
## will be replaced by the super short brand name.
fte_slide_3_copy=A {{clientSuperShortname}} a legtöbb asztali böngészővel működik. Felhasználói fiók nem szükséges, és mindenki ingyenesen csatlakozhat.
## LOCALIZATION_NOTE(fte_slide_4_title): {{clientSuperShortname}}
## will be replaced by the super short brand name.
fte_slide_4_title=Keresse a {{clientSuperShortname}} ikont a kezdéshez
## LOCALIZATION_NOTE(fte_slide_4_copy): {{brandShortname}}
## will be replaced by the brand short name.
fte_slide_4_copy=Amint olyan oldalt talált, amit megosztana, hivatkozás létrehozásához kattintson a {{brandShortname}} ikonra. Majd küldje el ismerősének ahogy szeretné!
invite_header_text_bold=Hívjon meg valakit az oldal közös böngészésére!
invite_header_text_bold2=Hívja meg ismerősét, hogy csatlakozzon!
invite_header_text3=A Firefox Hello használatához két ember kell: küldjön egy hivatkozást ismerősének, hogy közösen böngésszék a webet!
invite_header_text4=Ossza meg ezt a hivatkozást, hogy együtt böngészhessék a webet.
## LOCALIZATION_NOTE(invite_copy_link_button, invite_copied_link_button,
## invite_email_link_button, invite_facebook_button2): These labels appear under
## an iconic button for the invite view.
@ -48,9 +70,6 @@ invite_email_link_button=Hivatkozás küldése
invite_facebook_button3=Facebook
invite_your_link=A hivatkozás:
# Status text
display_name_guest=Vendég
# Error bars
## LOCALIZATION NOTE(session_expired_error_description,could_not_authenticate,password_changed_question,try_again_later,could_not_connect,check_internet_connection,login_expired,service_not_available,problem_accessing_account):
## These may be displayed at the top of the panel.
@ -181,7 +200,9 @@ door_hanger_button=OK
# Infobar strings
infobar_screenshare_no_guest_message=Amint ismerőse bejelentkezik, máris láthatja azokat a lapjait, amelyekre kattint.
infobar_screenshare_browser_message2=Megosztja a lapjait. Ismerősei látni fogják bármely lap tartalmát, amelyre rákattint.
infobar_screenshare_browser_message3=Mostmár megosztja a lapjait. Ismerőse láthatja bármely lap tartalmát, amelyre rákattint.
infobar_screenshare_stop_sharing_message=Már nem osztja meg böngészőlapjait
infobar_button_restart_label2=Megosztás újrakezdése
infobar_button_restart_accesskey=r
@ -239,3 +260,5 @@ self_view_hidden_message=A saját kamera képe elrejtve, de elküldésre kerül.
## LOCALIZATION NOTE (tos_failure_message): Don't translate {{clientShortname}}
## as this will be replaced by clientShortname2.
tos_failure_message=A {{clientShortname}} nem érhető el ebben az országban.
display_name_guest=Vendég

View File

@ -4,7 +4,7 @@
# Panel Strings
clientSuperShortname=Halo
clientSuperShortname=Hello
## LOCALIZATION_NOTE(loopMenuItem_label): Label of the menu item that is placed
## inside the browser 'Tools' menu. Use the unicode ellipsis char, \u2026, or
@ -26,37 +26,56 @@ sign_in_again_button=Masuk
sign_in_again_use_as_guest_button2=Gunakan {{clientSuperShortname}} sebagai Tamu
panel_browse_with_friend_button=Jelajahi laman ini bersama teman
panel_stop_sharing_tabs_button=Berhenti membagikan tab Anda
panel_disconnect_button=Terputus
## LOCALIZATION_NOTE(first_time_experience_subheading2): Message inviting the
## LOCALIZATION_NOTE(first_time_experience_subheading2, first_time_experience_subheading_button_above): Message inviting the
## user to create his or her first conversation.
first_time_experience_subheading2=Klik tombol Hello untuk jelajahi laman Web bersama teman.
first_time_experience_subheading_button_above=Klik pada tombol di atas untuk menjelajahi Web bersama teman.
## LOCALIZATION_NOTE(first_time_experience_content): Message describing
## LOCALIZATION_NOTE(first_time_experience_content, first_time_experience_content2): Message describing
## ways to use Hello project.
first_time_experience_content=Gunakan ini untuk perencanaan bersama, pekerjaan bersama, dan tertawa bersama.
first_time_experience_content2=Pergunakanlah untuk menyelesaikan sesuatu: merencanakan bersama, tertawa bersama, bekerja bersama.
first_time_experience_button_label2=Lihat cara kerja
## First Time Experience Slides
fte_slide_1_title=Menjelajahi laman Web bersama teman
## LOCALIZATION_NOTE(fte_slide_1_copy): {{clientShortname2}}
## will be replaced by the short name 2.
fte_slide_1_copy=Baik merencanakan perjalanan atau berbelanja hadiah, {{clientShortname2}} memungkinkan anda membuat keputusan lebih cepat dalam waktu singkat.
fte_slide_2_title=Memiliki pemahaman yang sama
fte_slide_2_copy=Menggunakan teks atau percakapan video yang tersedia untuk berbagi gagasan, emmbandingkan pilihan dan bermufakat.
fte_slide_3_title=Mengundang teman dengan mengirimkan tautan
## LOCALIZATION_NOTE(fte_slide_3_copy): {{clientSuperShortname}}
## will be replaced by the super short brand name.
fte_slide_3_copy={{clientSuperShortname}} bekerja dengan hampir semua peramban. Tidak perlu membuat akun dan setiap orang terhubung secara gratis.
## LOCALIZATION_NOTE(fte_slide_4_title): {{clientSuperShortname}}
## will be replaced by the super short brand name.
fte_slide_4_title=Temukan ikon {{clientSuperShortname}} untuk memulai
## LOCALIZATION_NOTE(fte_slide_4_copy): {{brandShortname}}
## will be replaced by the brand short name.
fte_slide_4_copy=Saat Anda menemukan laman yang ingin didiskusikan, klik ikon {{brandShortname}} untuk membuat tautan. Lalu kirimkan ke teman seperti yang Anda inginkan!
invite_header_text_bold=Undang seseorang untuk jelajahi laman ini bersama Anda!
invite_header_text_bold2=Mengundang teman untuk bergabung!
invite_header_text3=Membutuhkan 2 orang untuk menggunakan Firefox Hello, jadi kirimkan tautan ke teman untuk menjelajah Web bersama Anda!
invite_header_text4=Bagikan tautan ini supaya anda bisa mulai menjelajahi Web bersama.
## LOCALIZATION_NOTE(invite_copy_link_button, invite_copied_link_button,
## invite_email_link_button, invite_facebook_button2): These labels appear under
## an iconic button for the invite view.
invite_copy_link_button=Salin Tautan
invite_copied_link_button=Tersalin!
invite_email_link_button=Email Tautan
invite_email_link_button=Kirim Tautan
invite_facebook_button3=Facebook
invite_your_link=Tautan Anda:
# Status text
display_name_guest=Tamu
# Error bars
## LOCALIZATION NOTE(session_expired_error_description,could_not_authenticate,password_changed_question,try_again_later,could_not_connect,check_internet_connection,login_expired,service_not_available,problem_accessing_account):
## These may be displayed at the top of the panel.
session_expired_error_description=Sesi habis. Semua URLs yang sebelumnya Anda buat dan bagikan akan tidak berfungsi lagi.
could_not_authenticate=Tidak Dapat Mengautentikasi
password_changed_question=Apakah Anda mengganti password Anda?
password_changed_question=Sudah ganti kata sandi Anda?
try_again_later=Silakan coba kembali nanti
could_not_connect=Tidak Dapat Terhubung Dengan Server
check_internet_connection=Silakan periksa koneksi internet Anda
@ -87,7 +106,7 @@ share_add_service_button=Tambah Layanan
## LOCALIZATION NOTE (copy_link_menuitem, email_link_menuitem, delete_conversation_menuitem):
## These menu items are displayed from a panel's context menu for a conversation.
copy_link_menuitem=Salin Tautan
email_link_menuitem=Email Tautan
email_link_menuitem=Kirim Tautan
delete_conversation_menuitem2=Hapus
panel_footer_signin_or_signup_link=Masuk atau Daftar
@ -128,7 +147,7 @@ restart_call=Gabung Kembali
## LOCALIZATION NOTE (contact_offline_title): Title which is displayed when the
## contact is offline.
contact_offline_title=Orang ini tidak luring
contact_offline_title=Orang ini tidak daring
## LOCALIZATION NOTE (call_timeout_notification_text): Title which is displayed
## when the call didn't go through.
call_timeout_notification_text=Panggilan tidak sampai.
@ -177,33 +196,20 @@ room_name_untitled_page=Halaman Tanpa Judul
## LOCALIZATION NOTE (door_hanger_return, door_hanger_prompt_name, door_hanger_button): Dialog message on leaving conversation
door_hanger_return=Sampai bertemu lagi! Anda dapat kembali ke sesi ini bersama setiap saat melalui panel Halo.
door_hanger_prompt_name=Apakah Anda ingin memberikannya nama yang lebih mudah diingat? Nama:
door_hanger_button=OK
door_hanger_button=Oke
# Infobar strings
infobar_screenshare_no_guest_message=Segera setelah seorang teman bergabung, mereka akan dapat melihat tab manapun yang anda klik.
infobar_screenshare_browser_message2=Anda membagikan tab Anda. Tab apapun yang diklik dapat terlihat oleh teman Anda
infobar_screenshare_paused_browser_message=Pembagian tab dihentikan sementara
infobar_button_gotit_label=Mengerti!
infobar_button_gotit_accesskey=G
infobar_button_pause_label=Tunda
infobar_button_pause_accesskey=P
infobar_button_restart_label=Mulai Ulang
infobar_button_restart_accesskey=e
infobar_button_resume_label=Lanjutkan
infobar_button_resume_accesskey=R
infobar_button_stop_label=Hentikan
infobar_screenshare_browser_message3=Anda kini berbagi tab. Teman anda akan melihat setiap tab yang anda klik.
infobar_screenshare_stop_sharing_message=Anda tidak lagi berbagi tab
infobar_button_restart_label2=Ulangi proses berbagi
infobar_button_restart_accesskey=R
infobar_button_stop_label2=Hentikan proses berbagi
infobar_button_stop_accesskey=S
infobar_menuitem_dontshowagain_label=Jangan tampilkan lagi
infobar_menuitem_dontshowagain_accesskey=D
# Context in conversation strings
## LOCALIZATION NOTE(no_conversations_message_heading2): Title shown when user
## has no conversations available.
no_conversations_message_heading2=Belum ada percakapan.
## LOCALIZATION NOTE(no_conversations_start_message2): Subheading inviting the
## user to start a new conversation.
no_conversations_start_message2=Mulai percakapan baru!
infobar_button_disconnect_label=Terputus
infobar_button_disconnect_accesskey=D
# E10s not supported strings
@ -246,10 +252,13 @@ rooms_room_full_call_to_action_label=Pelajari selengkapnya tentang {{clientShort
rooms_room_full_call_to_action_nonFx_label=Unduh {{brandShortname}} untuk memulai percakapan Anda sendiri
rooms_room_full_label=Sudah ada dua orang dalam percakapan ini.
rooms_room_join_label=Gabung ke dalam percakapan
rooms_room_joined_label=Seseorang bergabung ke dalam percakapan!
rooms_room_joined_owner_connected_label2=Kini teman Anda telah tersambung dan akan dapat melihat tab Anda.
rooms_room_joined_owner_not_connected_label=Teman Anda sedang menunggu untuk menjelajahi {{roomURLHostname}} bersama Anda.
self_view_hidden_message=Tampilan diri sedang tersembunyi tetapi tetap dikirim, ubah ukuran jendela untuk menampilkannya
## LOCALIZATION NOTE (tos_failure_message): Don't translate {{clientShortname}}
## as this will be replaced by clientShortname2.
tos_failure_message={{clientShortname}} tidak tersedia di negara Anda.
display_name_guest=Tamu

View File

@ -26,28 +26,41 @@ sign_in_again_button=Accedi
sign_in_again_use_as_guest_button2=Utilizza {{clientSuperShortname}} come ospite
panel_browse_with_friend_button=Naviga in questa pagina insieme a un amico
panel_disconnect_button=Disconnetti
## LOCALIZATION_NOTE(first_time_experience_subheading2, first_time_experience_subheading_button_above): Message inviting the
## user to create his or her first conversation.
first_time_experience_subheading2=Fai clic sul pulsante Hello per navigare sul Web con un amico.
first_time_experience_subheading_button_above=Fai clic sul pulsante Hello per navigare sul Web insieme a un altro utente.
## LOCALIZATION_NOTE(first_time_experience_content, first_time_experience_content2): Message describing
## ways to use Hello project.
first_time_experience_content=Utilizzalo per fare progetti, lavorare o semplicemente fare una risata in compagnia.
first_time_experience_content2=Utilizza questa funzione per organizzare eventi, collaborare a un lavoro o divertirti con gli amici.
first_time_experience_button_label2=Scopri come funziona
## First Time Experience Slides
fte_slide_1_title=Naviga sul Web insieme a un amico
## LOCALIZATION_NOTE(fte_slide_1_copy): {{clientShortname2}}
## will be replaced by the short name 2.
fte_slide_1_copy=Quando organizzi un viaggio o acquisti un regalo in comune con gli amici, {{clientShortname2}} vi aiuta a prendere decisioni più rapide in tempo reale.
fte_slide_2_title=Condividi le tue vedute
fte_slide_2_copy=Grazie alla chat e alla video chat integrate puoi condividere idee, confrontare opzioni e raggiungere un accordo facilmente.
fte_slide_3_title=Invita un link a un altro utente per invitarlo
## LOCALIZATION_NOTE(fte_slide_3_copy): {{clientSuperShortname}}
## will be replaced by the super short brand name.
fte_slide_3_copy={{clientSuperShortname}} è compatibile con la maggior parte dei browser per desktop. Il servizio è gratuito e non richiede la registrazione di alcun account.
## LOCALIZATION_NOTE(fte_slide_4_title): {{clientSuperShortname}}
## will be replaced by the super short brand name.
fte_slide_4_title=Per iniziare individua licona di {{clientSuperShortname}}
## LOCALIZATION_NOTE(fte_slide_4_copy): {{brandShortname}}
## will be replaced by the brand short name.
fte_slide_4_copy=Quando ti trovi su una pagina web che vuoi mostrare a qualcuno, genera un link facendo clic sullicona di {{brandShortname}}, poi invialo allinteressato con il metodo che preferisci.
invite_header_text_bold=Invita un amico e visita questa pagina insieme a lui.
invite_header_text_bold2=Invita chi vuoi tu a unirsi alla conversazione!
invite_header_text3=Servono due persone per utilizzare Firefox Hello: invita un amico e naviga sul Web insieme a lui!
invite_header_text4=Condividi questo link per navigare sul Web in compagnia.
## LOCALIZATION_NOTE(invite_copy_link_button, invite_copied_link_button,
## invite_email_link_button, invite_facebook_button2): These labels appear under
## an iconic button for the invite view.
@ -187,9 +200,16 @@ door_hanger_button=OK
# Infobar strings
infobar_screenshare_no_guest_message=Lutente che hai invitato sarà in grado di visualizzare ogni scheda che apri sul tuo browser dal momento in cui si unisce alla conversazione.
infobar_screenshare_browser_message2=Le schede sono attualmente condivise. Seleziona una qualsiasi delle schede per condividerla
infobar_screenshare_browser_message3=Stai condividendo le schede del tuo browser. Da questo momento il tuo interlocutore sarà in grado di visualizzare tutte le schede che apri.
infobar_screenshare_stop_sharing_message=La condivisione schede è disattivata
infobar_button_restart_label2=Riattiva condivisione
infobar_button_restart_accesskey=v
infobar_button_stop_label2=Termina condivisione
infobar_button_stop_accesskey=I
infobar_button_disconnect_label=Disconnetti
infobar_button_disconnect_accesskey=D
# E10s not supported strings
@ -232,10 +252,13 @@ rooms_room_full_call_to_action_label=Ulteriori informazioni su {{clientShortname
rooms_room_full_call_to_action_nonFx_label=Scarica {{brandShortname}} per avviare una nuova conversazione
rooms_room_full_label=Questa conversazione ha già due partecipanti.
rooms_room_join_label=Partecipa alla conversazione
rooms_room_joined_label=Qualcuno si è unito alla conversazione.
rooms_room_joined_owner_connected_label2=Lutente invitato si è collegato e da questo momento può vedere le schede aperte del tuo browser.
rooms_room_joined_owner_not_connected_label=Un utente ti sta aspettando su {{roomURLHostname}}.
self_view_hidden_message=Lanteprima della fotocamera è nascosta, ma linterlocutore può ugualmente vederti. Ridimensiona la finestra per visualizzarla nuovamente.
## LOCALIZATION NOTE (tos_failure_message): Don't translate {{clientShortname}}
## as this will be replaced by clientShortname2.
tos_failure_message={{clientShortname}} non è disponibile per questa nazione.
display_name_guest=Ospite

View File

@ -43,6 +43,8 @@ first_time_experience_button_label2=Бұл қалай жұмыс жасайты
fte_slide_1_title=Веб парақтарды досыңызбен бірге шолу
## LOCALIZATION_NOTE(fte_slide_1_copy): {{clientShortname2}}
## will be replaced by the short name 2.
fte_slide_2_title=Бір парақты ашыңыз
fte_slide_3_title=Досыңызды сөйлесуге оған сілтемені жіберу арқылы шақырыңыз
## LOCALIZATION_NOTE(fte_slide_3_copy): {{clientSuperShortname}}
## will be replaced by the super short brand name.
## LOCALIZATION_NOTE(fte_slide_4_title): {{clientSuperShortname}}
@ -68,18 +70,28 @@ session_expired_error_description=Сессия мерзімі аяқталған
could_not_authenticate=Аутентификация мүмкін емес
password_changed_question=Пароліңізді өзгерттіңіз бе?
try_again_later=Кейінірек қайталап көріңіз
could_not_connect=Сервермен байланысты орнату мүмкін емес
check_internet_connection=Интернетпен байланысыңызды тексеріңіз
login_expired=Логин мерзімі аяқталған
service_not_available=Қызмет ағымдағы уақытта қолжетерсіз
problem_accessing_account=Тіркелгіңізге қатынау кезінде қате орын алды
## LOCALIZATION NOTE(retry_button): Displayed when there is an error to retry
## the appropriate action.
retry_button=Қайталап көру
share_email_subject7=Интернетті бірге шолуға шақыруыңыз
## LOCALIZATION NOTE (share_email_body7): In this item, don't translate the
## part between {{..}} and leave the \n\n part alone
share_email_body7=Досыңыз сізді Firefox Hello-да күтіп тұр. Байланысты орнату және интернетті бірге шолу үшін сілтемені шертіңіз: {{callUrl}}
## LOCALIZATION NOTE (share_email_body_context3): In this item, don't translate
## the part between {{..}} and leave the \n\n part alone.
share_email_body_context3=Досыңыз сізді Firefox Hello-да күтіп тұр. Байланысты орнату және {{title}} бірге шолу үшін сілтемені шертіңіз: {{callUrl}}
## LOCALIZATION NOTE (share_email_footer2): Common footer content for both email types
## LOCALIZATION NOTE (share_tweeet): In this item, don't translate the part
## between {{..}}. Please keep the text below 117 characters to make sure it fits
## in a tweet.
share_tweet=Менімен {{clientShortname2}} видео сөйлесуіне қатысыңыз!
share_add_service_button=Қызметті қосу
@ -122,39 +134,76 @@ initiate_audio_video_call_button2=Бастау
initiate_audio_video_call_tooltip2=Видео сөйлесуін бастау
initiate_audio_call_button2=Дауыстық сөйлесу
peer_ended_conversation2=Сіз қоңырау шалған адам сөйлесуді аяқтады.
restart_call=Қайта кіру
## LOCALIZATION NOTE (contact_offline_title): Title which is displayed when the
## contact is offline.
contact_offline_title=Бұл адам желіде емес
## LOCALIZATION NOTE (call_timeout_notification_text): Title which is displayed
## when the call didn't go through.
call_timeout_notification_text=Сіздің қоңырауыңыз мақсатына жетпеді.
## LOCALIZATION NOTE (cancel_button):
## This button is displayed when a call has failed.
cancel_button=Бас тарту
rejoin_button=Сөйлесуге қайта қосылу
cannot_start_call_session_not_ready=Қоңырауды бастау мүмкін емес, сессия дайын емес.
network_disconnected=Желілік байланыс күтпегенде үзілді.
connection_error_see_console_notification=Қоңырау сәтсіз; көбірек білу үшін консольді қараңыз.
no_media_failure_message=Камера не микрофон табылмады.
ice_failure_message=Байланысу талабы сәтсіз аяқталды. Желілік экраныңыз қоңырауларды блоктауы мүмкін.
## LOCALIZATION NOTE (legal_text_and_links3): In this item, don't translate the
## parts between {{..}} because these will be replaced with links with the labels
## from legal_text_tos and legal_text_privacy. clientShortname will be replaced
## by the brand name.
legal_text_and_links3={{clientShortname}} қолдану арқылы сіз {{terms_of_use}} және {{privacy_notice}} шарттарымен келісесіз.
legal_text_tos=Қолдану шарттары
legal_text_privacy=Жекелік ескертуі
## LOCALIZATION NOTE (powered_by_beforeLogo, powered_by_afterLogo):
## These 2 strings are displayed before and after a 'Telefonica'
## logo.
powered_by_beforeLogo=Келесінің негізінде:
powered_by_afterLogo=
## LOCALIZATION_NOTE (feedback_rejoin_button): Displayed on the feedback form after
## a signed-in to signed-in user call.
feedback_rejoin_button=Қайта қосылу
## LOCALIZATION NOTE (feedback_report_user_button): Used to report a user in the case of
## an abusive user.
feedback_report_user_button=Пайдаланушы жөнінде арыз беру
feedback_window_heading=Сөйлесуіңіз қалай болды?
feedback_request_button=Кері байланыс хабарламасын жіберу
tour_label=Шолу
rooms_list_recently_browsed2=Жақында қаралған
rooms_list_currently_browsing2=Қазір қаралып жатқан
rooms_signout_alert=Ашық сөйлесулер жабылатын болады
room_name_untitled_page=Атаусыз парақ
## LOCALIZATION NOTE (door_hanger_return, door_hanger_prompt_name, door_hanger_button): Dialog message on leaving conversation
door_hanger_return=Жүздескенше! Осы бөлісу сессиясына кез-келген уақытта Hello панелі арқылы орала аласыз.
door_hanger_prompt_name=Оған есте сақтауға жеңілдеу атын беруді қалайсыз ба? Ағымдағы аты:
door_hanger_button=ОК
# Infobar strings
infobar_screenshare_browser_message2=Сіз браузер беттерімен бөлісудесіз. Сіз шерткен кез-келген бетті достарыңыз көре алады
infobar_button_restart_label2=Бөлісуді қайта бастау
infobar_button_restart_accesskey=й
infobar_button_stop_label2=Бөлісуді тоқтату
infobar_button_stop_accesskey=т
infobar_button_disconnect_label=Байланысты үзу
infobar_button_disconnect_accesskey=з
# E10s not supported strings
e10s_not_supported_button_label=Жаңа терезені ашу
e10s_not_supported_subheading={{brandShortname}} мультипроцесстік терезеде жұмыс істемейді.
# 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/.

View File

@ -4,10 +4,13 @@
# Panel Strings
clientSuperShortname=ਹੈਲੋ
## LOCALIZATION_NOTE(loopMenuItem_label): Label of the menu item that is placed
## inside the browser 'Tools' menu. Use the unicode ellipsis char, \u2026, or
## use "..." if \u2026 doesn't suit traditions in your locale.
loopMenuItem_label=ਗੱਲਬਾਤ ਸ਼ੁਰੂ ਕਰੋ...
loopMenuItem_accesskey=t
## LOCALIZATION_NOTE(sign_in_again_title_line_one, sign_in_again_title_line_two2):
## These are displayed together at the top of the panel when a user is needed to
@ -15,22 +18,36 @@
## and this is displayed in slightly larger font. Please arrange as necessary for
## your locale.
## {{clientShortname2}} will be replaced by the brand name for either string.
sign_in_again_title_line_one=ਮੁੜ ਸਾਈਨ ਇਨ ਕਰੋ ਜੀ
sign_in_again_title_line_two2={{clientShortname2}} ਤੋਂ ਲਗਾਤਾਰ ਵਰਤਿਆ ਜਾ ਰਿਹਾ ਹੈ
sign_in_again_button=ਸਾਈਨ ਇਨ ਕਰੋ
## LOCALIZATION_NOTE(sign_in_again_use_as_guest_button2): {{clientSuperShortname}}
## will be replaced by the super short brandname.
sign_in_again_use_as_guest_button2={{clientSuperShortname}} ਮਹਿਮਾਨ ਦੇ ਤੌਰ ਤੇ ਵਰਤੋ
panel_browse_with_friend_button=ਆਪਣੇ ਦੋਸਤ ਨਾਲ ਇਹ ਪੇਜ ਬਣਾਓ
panel_disconnect_button=ਡਿਸਕੁਨੈੱਕਟ
## LOCALIZATION_NOTE(first_time_experience_subheading2): Message inviting the
## LOCALIZATION_NOTE(first_time_experience_subheading2, first_time_experience_subheading_button_above): Message inviting the
## user to create his or her first conversation.
## LOCALIZATION_NOTE(first_time_experience_content): Message describing
## LOCALIZATION_NOTE(first_time_experience_content, first_time_experience_content2): Message describing
## ways to use Hello project.
## First Time Experience Slides
## LOCALIZATION_NOTE(fte_slide_1_copy): {{clientShortname2}}
## will be replaced by the short name 2.
## LOCALIZATION_NOTE(fte_slide_3_copy): {{clientSuperShortname}}
## will be replaced by the super short brand name.
## LOCALIZATION_NOTE(fte_slide_4_title): {{clientSuperShortname}}
## will be replaced by the super short brand name.
## LOCALIZATION_NOTE(fte_slide_4_copy): {{brandShortname}}
## will be replaced by the brand short name.
## LOCALIZATION_NOTE(invite_copy_link_button, invite_copied_link_button,
## invite_email_link_button, invite_facebook_button2): These labels appear under
## an iconic button for the invite view.
# Status text
# Error bars
## LOCALIZATION NOTE(session_expired_error_description,could_not_authenticate,password_changed_question,try_again_later,could_not_connect,check_internet_connection,login_expired,service_not_available,problem_accessing_account):
## These may be displayed at the top of the panel.
@ -98,13 +115,6 @@ hangup_button_caption2=ਬਾਹਰ
# Infobar strings
# Context in conversation strings
## LOCALIZATION NOTE(no_conversations_message_heading2): Title shown when user
## has no conversations available.
## LOCALIZATION NOTE(no_conversations_start_message2): Subheading inviting the
## user to start a new conversation.
# E10s not supported strings
# This Source Code Form is subject to the terms of the Mozilla Public

View File

@ -4,10 +4,13 @@
# Panel Strings
clientSuperShortname=ਹੈਲੋ
## LOCALIZATION_NOTE(loopMenuItem_label): Label of the menu item that is placed
## inside the browser 'Tools' menu. Use the unicode ellipsis char, \u2026, or
## use "..." if \u2026 doesn't suit traditions in your locale.
loopMenuItem_label=ਗੱਲਬਾਤ ਸ਼ੁਰੂ ਕਰੋ...
loopMenuItem_accesskey=t
## LOCALIZATION_NOTE(sign_in_again_title_line_one, sign_in_again_title_line_two2):
## These are displayed together at the top of the panel when a user is needed to
@ -15,22 +18,36 @@
## and this is displayed in slightly larger font. Please arrange as necessary for
## your locale.
## {{clientShortname2}} will be replaced by the brand name for either string.
sign_in_again_title_line_one=ਮੁੜ ਸਾਈਨ ਇਨ ਕਰੋ ਜੀ
sign_in_again_title_line_two2={{clientShortname2}} ਤੋਂ ਲਗਾਤਾਰ ਵਰਤਿਆ ਜਾ ਰਿਹਾ ਹੈ
sign_in_again_button=ਸਾਈਨ ਇਨ ਕਰੋ
## LOCALIZATION_NOTE(sign_in_again_use_as_guest_button2): {{clientSuperShortname}}
## will be replaced by the super short brandname.
sign_in_again_use_as_guest_button2={{clientSuperShortname}} ਮਹਿਮਾਨ ਦੇ ਤੌਰ ਤੇ ਵਰਤੋ
panel_browse_with_friend_button=ਆਪਣੇ ਦੋਸਤ ਨਾਲ ਇਹ ਪੇਜ ਬਣਾਓ
panel_disconnect_button=ਡਿਸਕੁਨੈੱਕਟ
## LOCALIZATION_NOTE(first_time_experience_subheading2): Message inviting the
## LOCALIZATION_NOTE(first_time_experience_subheading2, first_time_experience_subheading_button_above): Message inviting the
## user to create his or her first conversation.
## LOCALIZATION_NOTE(first_time_experience_content): Message describing
## LOCALIZATION_NOTE(first_time_experience_content, first_time_experience_content2): Message describing
## ways to use Hello project.
## First Time Experience Slides
## LOCALIZATION_NOTE(fte_slide_1_copy): {{clientShortname2}}
## will be replaced by the short name 2.
## LOCALIZATION_NOTE(fte_slide_3_copy): {{clientSuperShortname}}
## will be replaced by the super short brand name.
## LOCALIZATION_NOTE(fte_slide_4_title): {{clientSuperShortname}}
## will be replaced by the super short brand name.
## LOCALIZATION_NOTE(fte_slide_4_copy): {{brandShortname}}
## will be replaced by the brand short name.
## LOCALIZATION_NOTE(invite_copy_link_button, invite_copied_link_button,
## invite_email_link_button, invite_facebook_button2): These labels appear under
## an iconic button for the invite view.
# Status text
# Error bars
## LOCALIZATION NOTE(session_expired_error_description,could_not_authenticate,password_changed_question,try_again_later,could_not_connect,check_internet_connection,login_expired,service_not_available,problem_accessing_account):
## These may be displayed at the top of the panel.
@ -98,13 +115,6 @@ hangup_button_caption2=ਬਾਹਰ
# Infobar strings
# Context in conversation strings
## LOCALIZATION NOTE(no_conversations_message_heading2): Title shown when user
## has no conversations available.
## LOCALIZATION NOTE(no_conversations_start_message2): Subheading inviting the
## user to start a new conversation.
# E10s not supported strings
# This Source Code Form is subject to the terms of the Mozilla Public

View File

@ -44,15 +44,23 @@ fte_slide_1_title=Navegue na web com um amigo
## LOCALIZATION_NOTE(fte_slide_1_copy): {{clientShortname2}}
## will be replaced by the short name 2.
fte_slide_1_copy=Se está planejando uma viagem ou comprar um presente, {{clientShortname2}} te deixa tomar decisões mais rápidas em tempo real.
fte_slide_2_title=Use a mesma página
fte_slide_2_copy=Use o chat embutido de texto ou vídeo para compartilhar ideias, comparar opções e chegar a um acordo.
fte_slide_3_title=Convide um amigo enviando um link
## LOCALIZATION_NOTE(fte_slide_3_copy): {{clientSuperShortname}}
## will be replaced by the super short brand name.
fte_slide_3_copy=O {{clientSuperShortname}} funciona com a maioria dos navegadores desktop. Não são necessárias contas e todos se conectam de graça.
## LOCALIZATION_NOTE(fte_slide_4_title): {{clientSuperShortname}}
## will be replaced by the super short brand name.
fte_slide_4_title=Encontre o ícone {{clientSuperShortname}} para começar
## LOCALIZATION_NOTE(fte_slide_4_copy): {{brandShortname}}
## will be replaced by the brand short name.
fte_slide_4_copy=Assim que encontrar uma página que quer comentar, clique no ícone em {{brandShortname}} para criar um link. Então, envie-a para um amigo como quiser!
invite_header_text_bold=Convide alguém para navegar nessa página com você!
invite_header_text_bold2=Convide um amigo para juntar-se a você!
invite_header_text3=É preciso de dois para usar o Firefox Hello, então envie um link para um amigo navegar na web com você!
invite_header_text4=Compartilhe este link para poder iniciar a navegação em conjunto.
## LOCALIZATION_NOTE(invite_copy_link_button, invite_copied_link_button,
## invite_email_link_button, invite_facebook_button2): These labels appear under
## an iconic button for the invite view.
@ -192,7 +200,9 @@ door_hanger_button=OK
# Infobar strings
infobar_screenshare_no_guest_message=Assim que seus amigos entrarem, poderão ver qualquer aba que você clicar.
infobar_screenshare_browser_message2=Você está compartilhando suas abas. Qualquer aba que clicar pode ser vista pelos seus amigos
infobar_screenshare_browser_message3=Agora você está compartilhando suas abas. Seu amigo verá qualquer aba que você clicar.
infobar_screenshare_stop_sharing_message=Já não está compartilhando suas abas
infobar_button_restart_label2=Reiniciar compartilhamento
infobar_button_restart_accesskey=R

View File

@ -10,7 +10,6 @@ support-files =
[browser_LoopRooms_channel.js]
[browser_mozLoop_appVersionInfo.js]
[browser_mozLoop_chat.js]
skip-if = e10s # Bug 1245808 hangup all chat windows calls into nsAppShell::Exit()
[browser_mozLoop_context.js]
[browser_mozLoop_socialShare.js]
[browser_mozLoop_sharingListeners.js]

View File

@ -74,7 +74,7 @@ function promisePanelLoaded() {
function waitForCondition(condition, nextTest, errorMsg) {
var tries = 0;
var interval = setInterval(function() {
if (tries >= 100) {
if (tries >= 200) {
ok(false, errorMsg);
moveOn();
}

View File

@ -9,7 +9,7 @@
<Description about="urn:mozilla:install-manifest">
<em:id>loop@mozilla.org</em:id>
<em:bootstrap>true</em:bootstrap>
<em:version>1.1.2</em:version>
<em:version>1.1.9</em:version>
<em:type>2</em:type>
<!-- Target Application this extension can install into,
@ -17,7 +17,7 @@
<em:targetApplication>
<Description>
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
<em:minVersion>45.0a1</em:minVersion>
<em:minVersion>46.0a1</em:minVersion>
<em:maxVersion>@FIREFOX_VERSION@</em:maxVersion>
</Description>
</em:targetApplication>

View File

@ -19,7 +19,7 @@ from config import CONTENT_SERVER_PORT, LOOP_SERVER_PORT, LOOP_SERVER_URL, \
hanging_threads.start_monitoring()
CONTENT_SERVER_COMMAND = ["make", "runserver"]
CONTENT_SERVER_COMMAND = ["make", "runserver_nowatch"]
CONTENT_SERVER_ENV = os.environ.copy()
# Set PORT so that it does not interfere with any other
# development server that might be running
@ -27,7 +27,7 @@ CONTENT_SERVER_ENV.update({"PORT": str(CONTENT_SERVER_PORT),
"LOOP_SERVER_URL": LOOP_SERVER_URL})
ROOMS_WEB_APP_URL = "http://localhost:" + str(CONTENT_SERVER_PORT) + \
"/content/{token}"
"/{token}"
LOOP_SERVER_COMMAND = ["make", "runserver"]
LOOP_SERVER_ENV = os.environ.copy()

View File

@ -786,7 +786,7 @@ you can use these alternative items. Otherwise, their values should be empty. -
The word "toolbar" is appended automatically and should not be contained below! -->
<!ENTITY tabsToolbar.label "Browser tabs">
<!-- LOCALIZATION NOTE (syncTabsMenu3.label): This appears in the history menu and history panel -->
<!-- LOCALIZATION NOTE (syncTabsMenu3.label): This appears in the history menu -->
<!ENTITY syncTabsMenu3.label "Synced Tabs">
<!ENTITY syncedTabs.sidebar.label "Synced Tabs">

View File

@ -148,13 +148,6 @@ var AnimationsController = {
// Expose actor capabilities.
this.traits = yield getServerTraits(target);
// We want to handle animation mutation events synchronously to avoid race
// conditions when there are many rapid mutations. So when a mutation occurs
// and animations are removed, we don't release the corresponding actors
// in a blocking way, we just release asynchronously and don't wait for
// completion, but instead store the promise in this array.
this.nonBlockingPlayerReleases = [];
if (this.destroyed) {
console.warn("Could not fully initialize the AnimationsController");
return;
@ -184,12 +177,9 @@ var AnimationsController = {
this.destroyed = promise.defer();
this.stopListeners();
yield this.destroyAnimationPlayers();
this.destroyAnimationPlayers();
this.nodeFront = null;
// Finish releasing players that haven't been released yet.
yield promise.all(this.nonBlockingPlayerReleases);
if (this.animationsFront) {
this.animationsFront.destroy();
this.animationsFront = null;
@ -238,7 +228,7 @@ var AnimationsController = {
if (!gInspector.selection.isConnected() ||
!gInspector.selection.isElementNode()) {
yield this.destroyAnimationPlayers();
this.destroyAnimationPlayers();
this.emit(this.PLAYERS_UPDATED_EVENT);
done();
return;
@ -334,7 +324,7 @@ var AnimationsController = {
animationPlayers: [],
refreshAnimationPlayers: Task.async(function*(nodeFront) {
yield this.destroyAnimationPlayers();
this.destroyAnimationPlayers();
this.animationPlayers = yield this.animationsFront
.getAnimationPlayersForNode(nodeFront);
@ -356,8 +346,6 @@ var AnimationsController = {
}
if (type === "removed") {
// Don't wait for the release request to complete, we can do that later.
this.nonBlockingPlayerReleases.push(player.release());
let index = this.animationPlayers.indexOf(player);
this.animationPlayers.splice(index, 1);
}
@ -386,19 +374,9 @@ var AnimationsController = {
return time;
},
destroyAnimationPlayers: Task.async(function*() {
// Let the server know that we're not interested in receiving updates about
// players for the current node. We're either being destroyed or a new node
// has been selected.
if (this.traits.hasMutationEvents) {
yield this.animationsFront.stopAnimationPlayerUpdates();
}
for (let front of this.animationPlayers) {
yield front.release();
}
destroyAnimationPlayers: function() {
this.animationPlayers = [];
})
}
};
EventEmitter.decorate(AnimationsController);

View File

@ -154,6 +154,7 @@ AnimationsTimeline.prototype = {
for (let animation of this.animations) {
animation.off("changed", this.onAnimationStateChanged);
}
this.stopAnimatingScrubber();
TimeScale.reset();
this.destroySubComponents("targetNodes");
this.destroySubComponents("timeBlocks");

View File

@ -28,24 +28,9 @@ add_task(function*() {
is(controller.animationPlayers.length, 2,
"2 AnimationPlayerFronts have been created");
// Hold on to one of the AnimationPlayerFront objects and mock its release
// method to test that it is released correctly and that its auto-refresh is
// stopped.
let retainedFront = controller.animationPlayers[0];
let oldRelease = retainedFront.release;
let releaseCalled = false;
retainedFront.release = () => {
releaseCalled = true;
};
info("Selecting a node with no animations");
yield selectNode(".still", inspector);
is(controller.animationPlayers.length, 0,
"There are no more AnimationPlayerFront objects");
info("Checking the destroyed AnimationPlayerFront object");
ok(releaseCalled, "The AnimationPlayerFront has been released");
yield oldRelease.call(retainedFront);
});

View File

@ -90,7 +90,6 @@ function InspectorPanel(iframeWindow, toolbox) {
this.onNewSelection = this.onNewSelection.bind(this);
this.onBeforeNewSelection = this.onBeforeNewSelection.bind(this);
this.onDetached = this.onDetached.bind(this);
this.onToolboxHostChanged = this.onToolboxHostChanged.bind(this);
this.onPaneToggleButtonClicked = this.onPaneToggleButtonClicked.bind(this);
this._onMarkupFrameLoad = this._onMarkupFrameLoad.bind(this);
@ -167,8 +166,6 @@ InspectorPanel.prototype = {
this.breadcrumbs = new HTMLBreadcrumbs(this);
this._toolbox.on("host-changed", this.onToolboxHostChanged);
if (this.target.isLocalTab) {
// Show a warning when the debugger is paused.
// We show the warning only when the inspector
@ -386,7 +383,6 @@ InspectorPanel.prototype = {
this._paneToggleButton = this.panelDoc.getElementById("inspector-pane-toggle");
this._paneToggleButton.addEventListener("mousedown",
this.onPaneToggleButtonClicked);
this.updatePaneToggleButton();
},
/**
@ -582,7 +578,6 @@ InspectorPanel.prototype = {
this.target.off("thread-paused", this.updateDebuggerPausedWarning);
this.target.off("thread-resumed", this.updateDebuggerPausedWarning);
this._toolbox.off("select", this.updateDebuggerPausedWarning);
this._toolbox.off("host-changed", this.onToolboxHostChanged);
if (this.ruleview) {
this.ruleview.destroy();
@ -979,13 +974,6 @@ InspectorPanel.prototype = {
return destroyPromise;
},
/**
* When the type of toolbox host changes.
*/
onToolboxHostChanged: function() {
this.updatePaneToggleButton();
},
/**
* When the pane toggle button is clicked, toggle the pane, change the button
* state and tooltip.
@ -995,10 +983,16 @@ InspectorPanel.prototype = {
let button = this._paneToggleButton;
let isVisible = !button.hasAttribute("pane-collapsed");
// Make sure the sidebar has a width attribute before collapsing because
// ViewHelpers needs it.
if (isVisible && !sidePane.hasAttribute("width")) {
sidePane.setAttribute("width", sidePane.getBoundingClientRect().width);
// Make sure the sidebar has width and height attributes before collapsing
// because ViewHelpers needs it.
if (isVisible) {
let rect = sidePane.getBoundingClientRect();
if (!sidePane.hasAttribute("width")) {
sidePane.setAttribute("width", rect.width);
}
// always refresh the height attribute before collapsing, it could have
// been modified by resizing the container.
sidePane.setAttribute("height", rect.height);
}
ViewHelpers.togglePane({
@ -1016,14 +1010,6 @@ InspectorPanel.prototype = {
}
},
/**
* Update the pane toggle button visibility depending on the toolbox host type.
*/
updatePaneToggleButton: function() {
this._paneToggleButton.setAttribute("hidden",
this._toolbox.hostType === HostType.SIDE);
},
/**
* Toggle a pseudo class.
*/

View File

@ -54,29 +54,18 @@ skip-if = e10s && os == 'win'
[browser_markup_dragdrop_reorder.js]
[browser_markup_dragdrop_tooltip.js]
[browser_markup_events.js]
skip-if = e10s # Bug 1040751 - CodeMirror editor.destroy() isn't e10s compatible
[browser_markup_events_form.js]
# [browser_markup_events-overflow.js]
# skip-if = e10s # Bug 1040751 - CodeMirror editor.destroy() isn't e10s compatible
# disabled - See bug 1177550
[browser_markup_events_jquery_1.0.js]
skip-if = e10s # Bug 1040751 - CodeMirror editor.destroy() isn't e10s compatible
[browser_markup_events_jquery_1.1.js]
skip-if = e10s # Bug 1040751 - CodeMirror editor.destroy() isn't e10s compatible
[browser_markup_events_jquery_1.2.js]
skip-if = e10s # Bug 1040751 - CodeMirror editor.destroy() isn't e10s compatible
[browser_markup_events_jquery_1.3.js]
skip-if = e10s # Bug 1040751 - CodeMirror editor.destroy() isn't e10s compatible
[browser_markup_events_jquery_1.4.js]
skip-if = e10s # Bug 1040751 - CodeMirror editor.destroy() isn't e10s compatible
[browser_markup_events_jquery_1.6.js]
skip-if = e10s # Bug 1040751 - CodeMirror editor.destroy() isn't e10s compatible
[browser_markup_events_jquery_1.7.js]
skip-if = e10s # Bug 1040751 - CodeMirror editor.destroy() isn't e10s compatible
[browser_markup_events_jquery_1.11.1.js]
skip-if = e10s # Bug 1040751 - CodeMirror editor.destroy() isn't e10s compatible
[browser_markup_events_jquery_2.1.1.js]
skip-if = e10s # Bug 1040751 - CodeMirror editor.destroy() isn't e10s compatible
[browser_markup_links_01.js]
[browser_markup_links_02.js]
[browser_markup_links_03.js]

View File

@ -14,10 +14,10 @@ const server = createTestHTTPServer();
// a reload and the load event firing.
server.registerContentType("gif", "image/gif");
server.registerPathHandler("/slow.gif", function (metadata, response) {
info ("Image has been requested");
info("Image has been requested");
response.processAsync();
setTimeout(() => {
info ("Image is responding");
info("Image is responding");
response.finish();
}, 500);
});
@ -37,7 +37,7 @@ add_task(function*() {
let domContentLoaded = waitForLinkedBrowserEvent(tab, "DOMContentLoaded");
let pageLoaded = waitForLinkedBrowserEvent(tab, "load");
ok (inspector.markup, "There is a markup view");
ok(inspector.markup, "There is a markup view");
// Select an element while the tab is in the middle of a slow reload.
reloadTab(testActor);
@ -46,8 +46,10 @@ add_task(function*() {
yield pageLoaded;
yield inspector.once("markuploaded");
ok (inspector.markup, "There is a markup view");
is (inspector.markup._elt.children.length, 1, "The markup view is rendering");
yield waitForMultipleChildrenUpdates(inspector);
ok(inspector.markup, "There is a markup view");
is(inspector.markup._elt.children.length, 1, "The markup view is rendering");
});
function* chooseWithInspectElementContextMenu(selector, testActor) {

View File

@ -4,7 +4,7 @@
"use strict";
// Test that the inspector panel has a sidebar pane toggle button, and that
// this button is hidden when the toolbox is in SIDE mode.
// this button is visible both in BOTTOM and SIDE hosts.
add_task(function* () {
info("Open the inspector in a bottom toolbox host");
@ -19,5 +19,7 @@ add_task(function* () {
info("Switch the host to side type");
yield toolbox.switchHost("side");
ok(!button.getClientRects().length, "The button is hidden");
ok(!!button.getClientRects().length, "The button is still visible");
ok(!button.hasAttribute("pane-collapsed"),
"The button is still in expanded state");
});

View File

@ -3,22 +3,40 @@
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Test that the inspector panel has its toggle pane button hidden by default
// when it is opened in a "side" host, and that the button becomes visible when
// the toolbox is switched to a "bottom" host.
// Test that the inspector toggled panel is visible by default, is hidden after
// clicking on the toggle button and remains expanded/collapsed when switching
// hosts.
add_task(function* () {
info("Open the inspector in a side toolbox host");
let {toolbox, inspector} = yield openInspectorForURL("about:blank", "side");
let panel = inspector.panelDoc.querySelector("#inspector-sidebar");
let button = inspector.panelDoc.getElementById("inspector-pane-toggle");
ok(button, "The toggle button exists in the DOM");
is(button.parentNode.id, "inspector-toolbar", "The toggle button is in the toolbar");
ok(!button.hasAttribute("pane-collapsed"), "The button is in expanded state");
ok(!button.getClientRects().length, "The button is hidden");
ok(!panel.hasAttribute("pane-collapsed"), "The panel is in expanded state");
info("Listen to the end of the animation on the sidebar panel");
let onTransitionEnd = once(panel, "transitionend");
info("Click on the toggle button");
EventUtils.synthesizeMouseAtCenter(button, {type: "mousedown"},
inspector.panelDoc.defaultView);
yield onTransitionEnd;
ok(panel.hasAttribute("pane-collapsed"), "The panel is in collapsed state");
ok(!panel.hasAttribute("animated"),
"The collapsed panel will not perform unwanted animations");
info("Switch the host to bottom type");
yield toolbox.switchHost("bottom");
ok(panel.hasAttribute("pane-collapsed"), "The panel is in collapsed state");
ok(!!button.getClientRects().length, "The button is visible");
info("Click on the toggle button to expand the panel again");
onTransitionEnd = once(panel, "transitionend");
EventUtils.synthesizeMouseAtCenter(button, {type: "mousedown"},
inspector.panelDoc.defaultView);
yield onTransitionEnd;
ok(!panel.hasAttribute("pane-collapsed"), "The panel is in expanded state");
});

View File

@ -3,7 +3,8 @@
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Test that the sidebar panel toggle button actually works.
// Test that the toggle button can collapse and expand the inspector side/bottom
// panel, and that the appropriate attributes are updated in the process.
add_task(function* () {
let {inspector} = yield openInspectorForURL("about:blank");

View File

@ -231,10 +231,6 @@ devtools.jar:
skin/images/noise.png (themes/images/noise.png)
skin/images/dropmarker.svg (themes/images/dropmarker.svg)
skin/layout.css (themes/layout.css)
skin/images/debugger-collapse.png (themes/images/debugger-collapse.png)
skin/images/debugger-collapse@2x.png (themes/images/debugger-collapse@2x.png)
skin/images/debugger-expand.png (themes/images/debugger-expand.png)
skin/images/debugger-expand@2x.png (themes/images/debugger-expand@2x.png)
skin/images/debugger-pause.png (themes/images/debugger-pause.png)
skin/images/debugger-pause@2x.png (themes/images/debugger-pause@2x.png)
skin/images/debugger-play.png (themes/images/debugger-play.png)
@ -349,3 +345,5 @@ devtools.jar:
skin/images/security-state-secure.svg (themes/images/security-state-secure.svg)
skin/images/security-state-weak.svg (themes/images/security-state-weak.svg)
skin/images/diff.svg (themes/images/diff.svg)
skin/images/pane-collapse.svg (themes/images/pane-collapse.svg)
skin/images/pane-expand.svg (themes/images/pane-expand.svg)

View File

@ -126,7 +126,6 @@ var NetMonitorView = {
$("#request-menu-context-perf").hidden = true;
$("#notice-perf-message").hidden = true;
$("#requests-menu-network-summary-button").hidden = true;
$("#requests-menu-network-summary-label").hidden = true;
}
},
@ -367,8 +366,8 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
this.widget = new SideMenuWidget($("#requests-menu-contents"));
this._splitter = $("#network-inspector-view-splitter");
this._summary = $("#requests-menu-network-summary-label");
this._summary.setAttribute("value", L10N.getStr("networkMenu.empty"));
this._summary = $("#requests-menu-network-summary-button");
this._summary.setAttribute("label", L10N.getStr("networkMenu.empty"));
this.userInputTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
Prefs.filters.forEach(type => this.filterOn(type));
@ -409,7 +408,7 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
this.freetextFilterBox.addEventListener("command", this.requestsFreetextFilterEvent, false);
$("#toolbar-labels").addEventListener("click", this.requestsMenuSortEvent, false);
$("#requests-menu-footer").addEventListener("click", this.requestsMenuFilterEvent, false);
$("#requests-menu-filter-buttons").addEventListener("click", this.requestsMenuFilterEvent, false);
$("#requests-menu-clear-button").addEventListener("click", this.reqeustsMenuClearEvent, false);
$("#network-request-popup").addEventListener("popupshowing", this._onContextShowing, false);
$("#request-menu-context-newtab").addEventListener("command", this._onContextNewTabCommand, false);
@ -438,13 +437,11 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
$("#request-menu-context-perf").addEventListener("command", this._onContextPerfCommand, false);
$("#requests-menu-perf-notice-button").addEventListener("command", this._onContextPerfCommand, false);
$("#requests-menu-network-summary-button").addEventListener("command", this._onContextPerfCommand, false);
$("#requests-menu-network-summary-label").addEventListener("click", this._onContextPerfCommand, false);
$("#network-statistics-back-button").addEventListener("command", this._onContextPerfCommand, false);
} else {
$("#notice-perf-message").hidden = true;
$("#request-menu-context-perf").hidden = true;
$("#requests-menu-network-summary-button").hidden = true;
$("#requests-menu-network-summary-label").hidden = true;
}
if (!NetMonitorController.supportsTransferredResponseSize) {
@ -467,7 +464,7 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
window.removeEventListener("resize", this._onResize, false);
$("#toolbar-labels").removeEventListener("click", this.requestsMenuSortEvent, false);
$("#requests-menu-footer").removeEventListener("click", this.requestsMenuFilterEvent, false);
$("#requests-menu-filter-buttons").removeEventListener("click", this.requestsMenuFilterEvent, false);
$("#requests-menu-clear-button").removeEventListener("click", this.reqeustsMenuClearEvent, false);
this.freetextFilterBox.removeEventListener("input", this.requestsFreetextFilterEvent, false);
this.freetextFilterBox.removeEventListener("command", this.requestsFreetextFilterEvent, false);
@ -486,7 +483,6 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
$("#requests-menu-reload-notice-button").removeEventListener("command", this._onReloadCommand, false);
$("#requests-menu-perf-notice-button").removeEventListener("command", this._onContextPerfCommand, false);
$("#requests-menu-network-summary-button").removeEventListener("command", this._onContextPerfCommand, false);
$("#requests-menu-network-summary-label").removeEventListener("click", this._onContextPerfCommand, false);
$("#network-statistics-back-button").removeEventListener("command", this._onContextPerfCommand, false);
$("#custom-request-send-button").removeEventListener("click", this.sendCustomRequestEvent, false);
@ -1255,7 +1251,7 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
let visibleItems = this.visibleItems;
let visibleRequestsCount = visibleItems.length;
if (!visibleRequestsCount) {
this._summary.setAttribute("value", L10N.getStr("networkMenu.empty"));
this._summary.setAttribute("label", L10N.getStr("networkMenu.empty"));
return;
}
@ -1266,7 +1262,7 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
// https://developer.mozilla.org/en-US/docs/Localization_and_Plurals
let str = PluralForm.get(visibleRequestsCount, L10N.getStr("networkMenu.summary"));
this._summary.setAttribute("value", str
this._summary.setAttribute("label", str
.replace("#1", visibleRequestsCount)
.replace("#2", L10N.numberWithDecimals((totalBytes || 0) / 1024, CONTENT_SIZE_DECIMALS))
.replace("#3", L10N.numberWithDecimals((totalMillis || 0) / 1000, REQUEST_TIME_DECIMALS))
@ -2223,7 +2219,14 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
if (!aItemsArray.length) {
return 0;
}
return aItemsArray.reduce((prev, curr) => prev + curr.attachment.contentSize || 0, 0);
let result = 0;
aItemsArray.forEach(item => {
let size = item.attachment.contentSize;
result += (typeof size == "number") ? size : 0;
});
return result;
},
/**

View File

@ -8,8 +8,7 @@
}
#details-pane-toggle[disabled] {
/* Don't use display: none; to avoid collapsing #requests-menu-toolbar */
visibility: hidden;
display: none;
}
#custom-pane {
@ -39,7 +38,7 @@
#details-pane-toggle,
#details-pane[pane-collapsed],
.requests-menu-waterfall,
.requests-menu-footer-label {
#requests-menu-network-summary-button > .toolbarbutton-text {
display: none;
}
}

View File

@ -92,6 +92,79 @@
<deck id="body" class="theme-sidebar" flex="1">
<vbox id="network-inspector-view" flex="1">
<hbox id="netmonitor-toolbar" class="devtools-toolbar">
<toolbarbutton id="requests-menu-clear-button"
class="devtools-toolbarbutton devtools-clear-icon"
tooltip="&netmonitorUI.footer.clear;"/>
<hbox id="requests-menu-filter-buttons">
<button id="requests-menu-filter-all-button"
class="requests-menu-filter-button"
checked="true"
data-key="all"
label="&netmonitorUI.footer.filterAll;">
</button>
<button id="requests-menu-filter-html-button"
class="requests-menu-filter-button"
data-key="html"
label="&netmonitorUI.footer.filterHTML;">
</button>
<button id="requests-menu-filter-css-button"
class="requests-menu-filter-button"
data-key="css"
label="&netmonitorUI.footer.filterCSS;">
</button>
<button id="requests-menu-filter-js-button"
class="requests-menu-filter-button"
data-key="js"
label="&netmonitorUI.footer.filterJS;">
</button>
<button id="requests-menu-filter-xhr-button"
class="requests-menu-filter-button"
data-key="xhr"
label="&netmonitorUI.footer.filterXHR;">
</button>
<button id="requests-menu-filter-fonts-button"
class="requests-menu-filter-button"
data-key="fonts"
label="&netmonitorUI.footer.filterFonts;">
</button>
<button id="requests-menu-filter-images-button"
class="requests-menu-filter-button"
data-key="images"
label="&netmonitorUI.footer.filterImages;">
</button>
<button id="requests-menu-filter-media-button"
class="requests-menu-filter-button"
data-key="media"
label="&netmonitorUI.footer.filterMedia;">
</button>
<button id="requests-menu-filter-flash-button"
class="requests-menu-filter-button"
data-key="flash"
label="&netmonitorUI.footer.filterFlash;">
</button>
<button id="requests-menu-filter-other-button"
class="requests-menu-filter-button"
data-key="other"
label="&netmonitorUI.footer.filterOther;">
</button>
</hbox>
<spacer id="requests-menu-spacer"
flex="1"/>
<toolbarbutton id="requests-menu-network-summary-button"
class="devtools-toolbarbutton icon-and-text"
tooltiptext="&netmonitorUI.footer.perf;"/>
<textbox id="requests-menu-filter-freetext-text"
class="devtools-searchinput"
type="search"
required="true"
placeholder="&netmonitorUI.footer.filterFreetext.label;"/>
<toolbarbutton id="details-pane-toggle"
class="devtools-toolbarbutton"
tooltiptext="&netmonitorUI.panesButton.tooltip;"
disabled="true"
tabindex="0"/>
</hbox>
<hbox id="network-table-and-sidebar"
class="devtools-responsive-container"
flex="1">
@ -194,11 +267,6 @@
</button>
</hbox>
</hbox>
<toolbarbutton id="details-pane-toggle"
class="devtools-toolbarbutton"
tooltiptext="&netmonitorUI.panesButton.tooltip;"
disabled="true"
tabindex="0"/>
</toolbar>
<vbox id="requests-menu-empty-notice"
@ -758,81 +826,6 @@
</deck>
</hbox>
<hbox id="requests-menu-footer">
<button id="requests-menu-filter-all-button"
class="requests-menu-filter-button requests-menu-footer-button"
checked="true"
data-key="all"
label="&netmonitorUI.footer.filterAll;">
</button>
<button id="requests-menu-filter-html-button"
class="requests-menu-filter-button requests-menu-footer-button"
data-key="html"
label="&netmonitorUI.footer.filterHTML;">
</button>
<button id="requests-menu-filter-css-button"
class="requests-menu-filter-button requests-menu-footer-button"
data-key="css"
label="&netmonitorUI.footer.filterCSS;">
</button>
<button id="requests-menu-filter-js-button"
class="requests-menu-filter-button requests-menu-footer-button"
data-key="js"
label="&netmonitorUI.footer.filterJS;">
</button>
<button id="requests-menu-filter-xhr-button"
class="requests-menu-filter-button requests-menu-footer-button"
data-key="xhr"
label="&netmonitorUI.footer.filterXHR;">
</button>
<button id="requests-menu-filter-fonts-button"
class="requests-menu-filter-button requests-menu-footer-button"
data-key="fonts"
label="&netmonitorUI.footer.filterFonts;">
</button>
<button id="requests-menu-filter-images-button"
class="requests-menu-filter-button requests-menu-footer-button"
data-key="images"
label="&netmonitorUI.footer.filterImages;">
</button>
<button id="requests-menu-filter-media-button"
class="requests-menu-filter-button requests-menu-footer-button"
data-key="media"
label="&netmonitorUI.footer.filterMedia;">
</button>
<button id="requests-menu-filter-flash-button"
class="requests-menu-filter-button requests-menu-footer-button"
data-key="flash"
label="&netmonitorUI.footer.filterFlash;">
</button>
<button id="requests-menu-filter-other-button"
class="requests-menu-filter-button requests-menu-footer-button"
data-key="other"
label="&netmonitorUI.footer.filterOther;">
</button>
<spacer id="requests-menu-spacer-textbox"
class="requests-menu-footer-spacer"
flex="0"/>
<textbox id="requests-menu-filter-freetext-text"
class="requests-menu-footer-textbox devtools-searchinput"
type="search"
required="true"
placeholder="&netmonitorUI.footer.filterFreetext.label;"/>
<spacer id="requests-menu-spacer"
class="requests-menu-footer-spacer"
flex="100"/>
<button id="requests-menu-network-summary-button"
class="requests-menu-footer-button"
tooltiptext="&netmonitorUI.footer.perf;"/>
<label id="requests-menu-network-summary-label"
class="plain requests-menu-footer-label"
crop="end"
tooltiptext="&netmonitorUI.footer.perf;"/>
<button id="requests-menu-clear-button"
class="requests-menu-footer-button"
label="&netmonitorUI.footer.clear;"/>
</hbox>
</vbox>
<box id="network-statistics-view">

View File

@ -81,8 +81,8 @@ function test() {
})
function testStatus() {
let summary = $("#requests-menu-network-summary-label");
let value = summary.getAttribute("value");
let summary = $("#requests-menu-network-summary-button");
let value = summary.getAttribute("label");
info("Current summary: " + value);
let visibleItems = RequestsMenu.visibleItems;

View File

@ -425,7 +425,7 @@ function testFilterButtons(aMonitor, aFilterType) {
*/
function testFilterButtonsCustom(aMonitor, aIsChecked) {
let doc = aMonitor.panelWin.document;
let buttons = doc.querySelectorAll(".requests-menu-footer-button");
let buttons = doc.querySelectorAll(".requests-menu-filter-button");
for (let i = 0; i < aIsChecked.length; i++) {
let button = buttons[i];
if (aIsChecked[i]) {

View File

@ -225,7 +225,8 @@ this.ViewHelpers = {
},
/**
* Sets a side pane hidden or visible.
* Sets a toggled pane hidden or visible. The pane can either be displayed on
* the side (right or left depending on the locale) or at the bottom.
*
* @param object aFlags
* An object containing some of the following properties:
@ -246,9 +247,7 @@ this.ViewHelpers = {
aPane.removeAttribute("hidden");
// Add a class to the pane to handle min-widths, margins and animations.
if (!aPane.classList.contains("generic-toggled-side-pane")) {
aPane.classList.add("generic-toggled-side-pane");
}
aPane.classList.add("generic-toggled-pane");
// Avoid useless toggles.
if (aFlags.visible == !aPane.hasAttribute("pane-collapsed")) {
@ -265,29 +264,37 @@ this.ViewHelpers = {
// Computes and sets the pane margins in order to hide or show it.
let doToggle = () => {
// Negative margins are applied to "right" and "left" to support RTL and
// LTR directions, as well as to "bottom" to support vertical layouts.
// Unnecessary negative margins are forced to 0 via CSS in widgets.css.
if (aFlags.visible) {
aPane.style.marginLeft = "0";
aPane.style.marginRight = "0";
aPane.style.marginBottom = "0";
aPane.removeAttribute("pane-collapsed");
} else {
let margin = ~~(aPane.getAttribute("width")) + 1;
aPane.style.marginLeft = -margin + "px";
aPane.style.marginRight = -margin + "px";
let width = Math.floor(aPane.getAttribute("width")) + 1;
let height = Math.floor(aPane.getAttribute("height")) + 1;
aPane.style.marginLeft = -width + "px";
aPane.style.marginRight = -width + "px";
aPane.style.marginBottom = -height + "px";
aPane.setAttribute("pane-collapsed", "");
}
// Invoke the callback when the transition ended.
// Wait for the animation to end before calling afterToggle()
if (aFlags.animated) {
aPane.addEventListener("transitionend", function onEvent() {
aPane.removeEventListener("transitionend", onEvent, false);
// Prevent unwanted transitions: if the panel is hidden and the layout
// changes margins will be updated and the panel will pop out.
aPane.removeAttribute("animated");
if (aFlags.callback) aFlags.callback();
}, false);
}
// Invoke the callback immediately since there's no transition.
else {
} else {
// Invoke the callback immediately since there's no transition.
if (aFlags.callback) aFlags.callback();
}
}
};
// Sometimes it's useful delaying the toggle a few ticks to ensure
// a smoother slide in-out animation.

View File

@ -35,7 +35,7 @@ add_task(function*() {
table.scrollTop += cellHeight * 50;
yield onStoresUpdate;
is($$("#value .table-widget-cell").length, 200,
"Table should display all 200 items after scrolling");
is($$("#value .table-widget-cell").length, 160,
"Table should display all 160 items after scrolling");
yield finishTests();
});

View File

@ -14,9 +14,7 @@ window.clear = () => {
localStorage.clear();
};
let array = new Array(200);
for (let i = 0; i < array.length; i++) {
for (let i = 0; i < 160; i++) {
localStorage.setItem(`item-${i}`, `value-${i}`);
}
</script>

View File

@ -584,21 +584,11 @@
}
#instruments-pane-toggle {
list-style-image: url(images/debugger-collapse.png);
list-style-image: url(images/pane-collapse.svg);
}
#instruments-pane-toggle[pane-collapsed] {
list-style-image: url(images/debugger-expand.png);
}
@media (min-resolution: 1.1dppx) {
#instruments-pane-toggle {
list-style-image: url(images/debugger-collapse@2x.png);
}
#instruments-pane-toggle[pane-collapsed] {
list-style-image: url(images/debugger-expand@2x.png);
}
list-style-image: url(images/pane-expand.svg);
}
/* Horizontal vs. vertical layout */

Binary file not shown.

Before

Width:  |  Height:  |  Size: 192 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 216 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 201 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 223 B

View File

@ -0,0 +1,6 @@
<!-- 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 width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" fill="#babec3">
<path d="M2 2h12v12H2V2zm1 1h7v10H3V3zm6 5l-4 3V5l4 3z" fill-rule="evenodd"/>
</svg>

After

Width:  |  Height:  |  Size: 404 B

View File

@ -0,0 +1,6 @@
<!-- 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 width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" fill="#babec3">
<path d="M2 2h12v12H2V2zm1 1h7v10H3V3zm1 5l4 3V5L4 8z" fill-rule="evenodd"/>
</svg>

After

Width:  |  Height:  |  Size: 403 B

View File

@ -41,20 +41,17 @@
/* Expand/collapse panel toolbar button */
#inspector-pane-toggle {
list-style-image: url(images/debugger-collapse.png);
list-style-image: url(chrome://devtools/skin/images/pane-collapse.svg);
}
#inspector-pane-toggle[pane-collapsed] {
list-style-image: url(images/debugger-expand.png);
list-style-image: url(chrome://devtools/skin/images/pane-expand.svg);
}
@media (min-resolution: 1.1dppx) {
#inspector-pane-toggle {
list-style-image: url(images/debugger-collapse@2x.png);
}
@media (max-width: 700px) {
#inspector-pane-toggle,
#inspector-pane-toggle[pane-collapsed] {
list-style-image: url(images/debugger-expand@2x.png);
transform: rotate(90deg);
}
}

View File

@ -398,21 +398,11 @@
/* Network request details */
#details-pane-toggle {
list-style-image: url("chrome://devtools/skin/images/debugger-collapse.png");
list-style-image: url("chrome://devtools/skin/images/pane-collapse.svg");
}
#details-pane-toggle[pane-collapsed] {
list-style-image: url("chrome://devtools/skin/images/debugger-expand.png");
}
@media (min-resolution: 1.1dppx) {
#details-pane-toggle {
list-style-image: url("chrome://devtools/skin/images/debugger-collapse@2x.png");
}
#details-pane-toggle[pane-collapsed] {
list-style-image: url("chrome://devtools/skin/images/debugger-expand@2x.png");
}
list-style-image: url("chrome://devtools/skin/images/pane-expand.svg");
}
/* Network request details tabpanels */
@ -568,90 +558,31 @@
width: 4.5em;
}
/* Footer */
#requests-menu-footer {
background-color: var(--theme-toolbar-background);
border-top: 1px solid var(--table-splitter-color);
}
.requests-menu-footer-button,
.requests-menu-footer-label {
min-width: 1em;
margin: 0;
/* Main toolbar */
.requests-menu-filter-button {
-moz-appearance: none;
background: rgba(128,128,128,0.1);
border: none;
padding: 2px 1vw;
}
.theme-dark .requests-menu-footer-button,
.theme-dark .requests-menu-footer-label {
color: var(--theme-selection-color);
}
.theme-light .requests-menu-footer-button,
.theme-light .requests-menu-footer-label {
border-radius: 2px;
min-width: 0;
padding: 0 5px;
margin: 2px;
color: var(--theme-body-color);
}
.requests-menu-footer-spacer {
min-width: 2px;
.requests-menu-filter-button:hover {
background: rgba(128,128,128,0.2);
}
.theme-dark .requests-menu-footer-spacer:not(:first-child),
.theme-dark .requests-menu-footer-button:not(:first-child) {
-moz-border-start: 1px solid var(--table-splitter-color);
}
.theme-light .requests-menu-footer-spacer:not(:first-child),
.theme-light .requests-menu-footer-button:not(:first-child) {
-moz-border-start: 1px solid var(--table-splitter-color);
}
.requests-menu-footer-button {
-moz-appearance: none;
background: rgba(0,0,0,0.025);
}
.requests-menu-footer-button:hover {
background: rgba(0,0,0,0.10);
}
.requests-menu-footer-button:hover:active {
.requests-menu-filter-button:hover:active {
background-color: var(--theme-selection-background-semitransparent);
}
.requests-menu-footer-button:not(:active)[checked] {
.requests-menu-filter-button:not(:active)[checked] {
background-color: var(--theme-selection-background);
color: var(--theme-selection-color);
}
.requests-menu-footer-label {
padding-top: 3px;
font-weight: 600;
}
#requests-menu-filter-freetext-text {
transition-property: max-width, -moz-padding-end, -moz-padding-start;
transition-duration: 250ms;
transition-timing-function: ease;
}
#requests-menu-filter-freetext-text:not([focused]):not([filled]) > .textbox-input-box {
overflow: hidden;
}
#requests-menu-filter-freetext-text:not([focused]):not([filled]) {
max-width: 20px !important;
-moz-padding-end: 5px;
-moz-padding-start: 22px;
background-position: 8px center, top left, top left;
}
#requests-menu-filter-freetext-text[focused],
#requests-menu-filter-freetext-text[filled] {
max-width: 200px !important;
}
/* Performance analysis buttons */
#requests-menu-network-summary-button {
@ -661,15 +592,8 @@
list-style-image: url(images/profiler-stopwatch.svg);
-moz-padding-end: 0;
cursor: pointer;
}
#requests-menu-network-summary-label {
-moz-padding-start: 0;
cursor: pointer;
}
#requests-menu-network-summary-label:hover {
text-decoration: underline;
margin-inline-end: 1em;
min-width: 0;
}
/* Performance analysis view */
@ -835,20 +759,6 @@
font-size: 90%;
}
:root[platform="win"] .requests-menu-footer-button,
:root[platform="win"] .requests-menu-footer-label {
padding-top: 0px;
padding-bottom: 0px;
}
/* Responsive sidebar */
@media (max-width: 700px) {
:root[platform="win"] .requests-menu-footer-button,
:root[platform="win"] .requests-menu-footer-label {
padding-top: 0px;
padding-bottom: 0px;
}
}
:root[platform="linux"] #headers-summary-resend {
padding: 4px;
}

View File

@ -105,6 +105,10 @@
/* Sidebar & recording items */
#recordings-list {
border-inline-end: 1px solid var(--theme-splitter-color);
}
.recording-item {
padding: 4px;
}

View File

@ -4,14 +4,12 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
.theme-dark {
--smw-margin: #000;
--smw-item-top-border: rgba(0,0,0,0.2);
--smw-item-bottom-border: rgba(128,128,128,0.15);
--sidemenu-selected-arrow: url(images/itemArrow-dark-ltr.svg);
--sidemenu-selected-arrow-rtl: url(images/itemArrow-dark-rtl.svg);
}
.theme-light {
--smw-margin: #aaa;
--smw-item-top-border: rgba(128,128,128,0.15);
--smw-item-bottom-border: transparent;
--sidemenu-selected-arrow: url(images/itemArrow-ltr.svg);
--sidemenu-selected-arrow-rtl: url(images/itemArrow-rtl.svg);
}
.splitview-nav-container .devtools-throbber {
@ -23,40 +21,19 @@
display: block;
}
.theme-dark .splitview-nav-container {
background-color: var(--theme-toolbar-background);
}
.splitview-nav {
-moz-appearance: none;
list-style-image: none;
list-style: none;
padding: 0;
margin: 0;
box-shadow: inset -1px 0 0 var(--smw-margin);
}
.splitview-nav:-moz-locale-dir(rtl) {
box-shadow: inset 1px 0 0 var(--smw-margin);
background-color: var(--theme-sidebar-background);
}
.splitview-nav > li {
/* To compensate for the top and bottom borders */
margin-top: -1px;
margin-bottom: -1px;
-moz-padding-end: 8px;
padding-inline-end: 8px;
-moz-box-align: center;
outline: 0;
vertical-align: bottom;
}
.splitview-nav > li {
border-top: 1px solid var(--smw-item-top-border);
border-bottom: 1px solid var(--smw-item-bottom-border);
}
.splitview-nav > li:last-of-type {
box-shadow: inset 0 -1px 0 var(--smw-item-top-border);
border-bottom: 1px solid rgba(128,128,128,0.15);
}
.placeholder {
@ -65,38 +42,16 @@
}
.splitview-nav > li.splitview-active {
background-repeat: no-repeat, no-repeat, repeat-x;
background-position: center right, center right, top left;
background-size: auto, 1px, auto;
background-color: var(--theme-selection-background);
color: var(--theme-selection-color);
background-image: var(--sidemenu-selected-arrow);
background-repeat: no-repeat;
background-position: center right;
}
.splitview-nav > li.splitview-active:-moz-locale-dir(rtl) {
background-repeat: no-repeat, no-repeat, repeat-x;
background-position: center left, center left, top right;
}
.theme-dark .splitview-nav > li.splitview-active {
background-image: url(images/itemArrow-dark-ltr.svg),
linear-gradient(var(--smw-margin), var(--smw-margin)),
linear-gradient(#1d4f73, #1d4f73);
}
.theme-dark .splitview-nav > li.splitview-active:-moz-locale-dir(rtl) {
background-image: url(images/itemArrow-dark-rtl.svg),
linear-gradient(var(--smw-margin), var(--smw-margin)),
linear-gradient(#1d4f73, #1d4f73);
}
.theme-light .splitview-nav > li.splitview-active {
background-image: url(images/itemArrow-ltr.svg),
linear-gradient(var(--smw-margin), var(--smw-margin)),
linear-gradient(#4c9ed9, #4c9ed9);
}
.theme-light .splitview-nav > li.splitview-active:-moz-locale-dir(rtl) {
background-image: url(images/itemArrow-rtl.svg),
linear-gradient(var(--smw-margin), var(--smw-margin)),
linear-gradient(#4c9ed9, #4c9ed9);
background-image: var(--sidemenu-selected-arrow-rtl);
background-position: center left;
}
/* Toolbars */
@ -108,7 +63,7 @@
.splitview-main > toolbar,
.loading .splitview-nav-container {
-moz-border-end: 1px solid var(--smw-margin);
border-inline-end: 1px solid var(--theme-splitter-color);
}
.splitview-main > .devtools-toolbarbutton {

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