diff --git a/browser/base/content/test/favicons/browser_preferred_icons.js b/browser/base/content/test/favicons/browser_preferred_icons.js
index 455d260e893c..a26b6a891706 100644
--- a/browser/base/content/test/favicons/browser_preferred_icons.js
+++ b/browser/base/content/test/favicons/browser_preferred_icons.js
@@ -4,6 +4,9 @@
const ROOT = "http://mochi.test:8888/browser/browser/base/content/test/favicons/";
function waitIcon(url) {
+ // Make sure we don't miss out on an icon if it was previously used in a test
+ PlacesUtils.favicons.removeFailedFavicon(makeURI(url));
+
// Because there is debounce logic in ContentLinkHandler.jsm to reduce the
// favicon loads, we have to wait some time before checking that icon was
// stored properly.
@@ -24,7 +27,8 @@ function createLinks(linkInfos) {
let link = doc.createElement("link");
link.rel = "icon";
link.href = l.href;
- link.type = l.type;
+ if (l.type)
+ link.type = l.type;
if (l.size)
link.setAttribute("sizes", `${l.size}x${l.size}`);
head.appendChild(link);
@@ -78,7 +82,7 @@ add_task(async function prefer_sized() {
Assert.ok(true, "The expected icon has been set");
});
-add_task(async function prefer_ico() {
+add_task(async function prefer_last_ico() {
let promise = waitIcon(ROOT + "icon2.ico");
await createLinks([
{ href: ROOT + "icon.ico",
@@ -88,8 +92,73 @@ add_task(async function prefer_ico() {
type: "image/png",
},
{ href: ROOT + "icon2.ico",
- type: "image/x-icon"
- },
+ type: "image/x-icon"
+ },
+ ]);
+ await promise;
+ // Must have at least one test.
+ Assert.ok(true, "The expected icon has been set");
+});
+
+add_task(async function fuzzy_ico() {
+ let promise = waitIcon(ROOT + "microsoft.ico");
+ await createLinks([
+ { href: ROOT + "icon.ico",
+ type: "image/x-icon"
+ },
+ { href: ROOT + "icon.png",
+ type: "image/png",
+ },
+ { href: ROOT + "microsoft.ico",
+ type: "image/vnd.microsoft.icon"
+ },
+ ]);
+ await promise;
+ // Must have at least one test.
+ Assert.ok(true, "The expected icon has been set");
+});
+
+add_task(async function guess_svg() {
+ let promise = waitIcon(ROOT + "icon.svg");
+ await createLinks([
+ { href: ROOT + "icon.svg" },
+ { href: ROOT + "icon.png",
+ type: "image/png",
+ size: 16 * Math.ceil(window.devicePixelRatio)
+ },
+ { href: ROOT + "icon.ico",
+ type: "image/x-icon"
+ },
+ ]);
+ await promise;
+ // Must have at least one test.
+ Assert.ok(true, "The expected icon has been set");
+});
+
+add_task(async function guess_ico() {
+ let promise = waitIcon(ROOT + "icon.ico");
+ await createLinks([
+ { href: ROOT + "icon.ico" },
+ { href: ROOT + "icon.png",
+ type: "image/png",
+ },
+ ]);
+ await promise;
+ // Must have at least one test.
+ Assert.ok(true, "The expected icon has been set");
+});
+
+add_task(async function guess_invalid() {
+ let promise = waitIcon(ROOT + "icon.svg");
+ // Create strange links to make sure they don't break us
+ await createLinks([
+ { href: ROOT + "icon.svg" },
+ { href: ROOT + "icon" },
+ { href: ROOT + "icon?.svg" },
+ { href: ROOT + "icon#.svg" },
+ { href: "data:text/plain,icon" },
+ { href: "file:///icon" },
+ { href: "about:icon" },
]);
await promise;
// Must have at least one test.
diff --git a/browser/components/extensions/ext-tabs.js b/browser/components/extensions/ext-tabs.js
index 4c541dfd5a60..9abab56a7b4f 100644
--- a/browser/components/extensions/ext-tabs.js
+++ b/browser/components/extensions/ext-tabs.js
@@ -617,6 +617,12 @@ this.tabs = class extends ExtensionAPI {
let window = destinationWindow || nativeTab.ownerGlobal;
let gBrowser = window.gBrowser;
+ // If we are not moving the tab to a different window, and the window
+ // only has one tab, do nothing.
+ if (nativeTab.ownerGlobal == window && gBrowser.tabs.length === 1) {
+ continue;
+ }
+
let insertionPoint = indexMap.get(window) || moveProperties.index;
// If the index is -1 it should go to the end of the tabs.
if (insertionPoint == -1) {
diff --git a/browser/components/newtab/aboutNewTabService.js b/browser/components/newtab/aboutNewTabService.js
index 8128f70bbb15..96f6aefb8588 100644
--- a/browser/components/newtab/aboutNewTabService.js
+++ b/browser/components/newtab/aboutNewTabService.js
@@ -21,7 +21,7 @@ const TOPIC_LOCALES_CHANGE = "intl:requested-locales-changed";
// Automated tests ensure packaged locales are in this list. Copied output of:
// https://github.com/mozilla/activity-stream/blob/master/bin/render-activity-stream-html.js
-const ACTIVITY_STREAM_LOCALES = new Set("en-US ach ar ast az be bg bn-BD bn-IN br bs ca cak cs cy da de dsb el en-GB eo es-AR es-CL es-ES es-MX et eu fa ff fi fr fy-NL ga-IE gd gl gu-IN he hi-IN hr hsb hu hy-AM ia id it ja ka kab kk km kn ko lij lo lt ltg lv mk ml mr ms my nb-NO ne-NP nl nn-NO pa-IN pl pt-BR pt-PT rm ro ru sk sl sq sr sv-SE ta te th tl tr uk ur uz vi zh-CN zh-TW".split(" "));
+const ACTIVITY_STREAM_LOCALES = new Set("en-US ach ar ast az be bg bn-BD bn-IN br bs ca cak cs cy da de dsb el en-GB eo es-AR es-CL es-ES es-MX et eu fa ff fi fr fy-NL ga-IE gd gl gu-IN he hi-IN hr hsb hu hy-AM ia id it ja ka kab kk km kn ko lij lo lt ltg lv mk ml mr ms my nb-NO ne-NP nl nn-NO pa-IN pl pt-BR pt-PT rm ro ru si sk sl sq sr sv-SE ta te th tl tr uk ur uz vi zh-CN zh-TW".split(" "));
const ABOUT_URL = "about:newtab";
diff --git a/browser/components/places/content/controller.js b/browser/components/places/content/controller.js
index 2b96588009f3..3bc178bad857 100644
--- a/browser/components/places/content/controller.js
+++ b/browser/components/places/content/controller.js
@@ -10,19 +10,6 @@ XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils",
"resource://gre/modules/PrivateBrowsingUtils.jsm");
-// XXXmano: we should move most/all of these constants to PlacesUtils
-const ORGANIZER_ROOT_BOOKMARKS = "place:folder=BOOKMARKS_MENU&excludeItems=1&queryType=1";
-
-// No change to the view, preserve current selection
-const RELOAD_ACTION_NOTHING = 0;
-// Inserting items new to the view, select the inserted rows
-const RELOAD_ACTION_INSERT = 1;
-// Removing items from the view, select the first item after the last selected
-const RELOAD_ACTION_REMOVE = 2;
-// Moving items within a view, don't treat the dropped items as additional
-// rows.
-const RELOAD_ACTION_MOVE = 3;
-
/**
* Represents an insertion point within a container where we can insert
* items.
diff --git a/browser/extensions/activity-stream/bootstrap.js b/browser/extensions/activity-stream/bootstrap.js
index def9f193194c..9e1c538a9354 100644
--- a/browser/extensions/activity-stream/bootstrap.js
+++ b/browser/extensions/activity-stream/bootstrap.js
@@ -181,7 +181,7 @@ this.startup = function startup(data, reason) {
startupReason = reason;
// Only start Activity Stream up when the browser UI is ready
- if (Cc["@mozilla.org/toolkit/app-startup;1"].getService(Ci.nsIAppStartup).startingUp) {
+ if (Services.startup.startingUp) {
Services.obs.addObserver(observe, BROWSER_READY_NOTIFICATION);
} else {
// Handle manual install or automatic install after manual uninstall
diff --git a/browser/extensions/activity-stream/common/Actions.jsm b/browser/extensions/activity-stream/common/Actions.jsm
index 3ef773e67ed8..ee6d2b316bc7 100644
--- a/browser/extensions/activity-stream/common/Actions.jsm
+++ b/browser/extensions/activity-stream/common/Actions.jsm
@@ -69,8 +69,10 @@ for (const type of [
"SETTINGS_OPEN",
"SET_PREF",
"SHOW_FIREFOX_ACCOUNTS",
+ "SNIPPETS_BLOCKLIST_UPDATED",
"SNIPPETS_DATA",
"SNIPPETS_RESET",
+ "SNIPPET_BLOCKED",
"SYSTEM_TICK",
"TELEMETRY_IMPRESSION_STATS",
"TELEMETRY_PERFORMANCE_EVENT",
diff --git a/browser/extensions/activity-stream/css/activity-stream-linux.css b/browser/extensions/activity-stream/css/activity-stream-linux.css
index f67deb8bc67a..22cc02398b0f 100644
--- a/browser/extensions/activity-stream/css/activity-stream-linux.css
+++ b/browser/extensions/activity-stream/css/activity-stream-linux.css
@@ -23,15 +23,15 @@ input {
display: none !important; }
.icon {
- display: inline-block;
- width: 16px;
- height: 16px;
- background-size: 16px;
background-position: center center;
background-repeat: no-repeat;
- vertical-align: middle;
+ background-size: 16px;
+ -moz-context-properties: fill;
+ display: inline-block;
fill: rgba(12, 12, 13, 0.8);
- -moz-context-properties: fill; }
+ height: 16px;
+ vertical-align: middle;
+ width: 16px; }
.icon.icon-spacer {
margin-inline-end: 8px; }
.icon.icon-small-spacer {
@@ -44,9 +44,9 @@ input {
background-image: url("../data/content/assets/glyph-delete-16.svg"); }
.icon.icon-modal-delete {
background-image: url("../data/content/assets/glyph-modal-delete-32.svg");
- width: 32px;
+ background-size: 32px;
height: 32px;
- background-size: 32px; }
+ width: 32px; }
.icon.icon-dismiss {
background-image: url("../data/content/assets/glyph-dismiss-16.svg"); }
.icon.icon-info {
@@ -71,8 +71,7 @@ input {
background-image: url("../data/content/assets/glyph-historyItem-16.svg"); }
.icon.icon-trending {
background-image: url("../data/content/assets/glyph-trending-16.svg");
- transform: translateY(2px);
- /* trending bolt is visually top heavy */ }
+ transform: translateY(2px); }
.icon.icon-now {
background-image: url("chrome://browser/skin/history.svg"); }
.icon.icon-topsites {
@@ -125,24 +124,24 @@ a {
color: #008EA4; }
.sr-only {
- position: absolute;
- width: 1px;
+ border: 0;
+ clip: rect(0, 0, 0, 0);
height: 1px;
- padding: 0;
margin: -1px;
overflow: hidden;
- clip: rect(0, 0, 0, 0);
- border: 0; }
+ padding: 0;
+ position: absolute;
+ width: 1px; }
.inner-border {
border: 1px solid #D7D7DB;
border-radius: 3px;
+ height: 100%;
+ left: 0;
+ pointer-events: none;
position: absolute;
top: 0;
- left: 0;
width: 100%;
- height: 100%;
- pointer-events: none;
z-index: 100; }
@keyframes fadeIn {
@@ -155,25 +154,25 @@ a {
opacity: 0;
transition: opacity 0.2s ease-in; }
.show-on-init.on {
- opacity: 1;
- animation: fadeIn 0.2s; }
+ animation: fadeIn 0.2s;
+ opacity: 1; }
.actions {
border-top: 1px solid #D7D7DB;
display: flex;
flex-direction: row;
- margin: 0;
- padding: 15px 25px 0 25px;
+ flex-wrap: wrap;
justify-content: flex-start;
- flex-wrap: wrap; }
+ margin: 0;
+ padding: 15px 25px 0; }
.actions button {
background-color: #F9F9FA;
border: 1px solid #B1B1B3;
border-radius: 4px;
color: inherit;
cursor: pointer;
- padding: 10px 30px;
margin-bottom: 15px;
+ padding: 10px 30px;
white-space: nowrap; }
.actions button:hover:not(.dismiss) {
box-shadow: 0 0 0 5px #D7D7DB;
@@ -193,16 +192,16 @@ a {
.outer-wrapper {
display: flex;
- padding: 40px 32px 32px;
+ flex-grow: 1;
height: 100%;
- flex-grow: 1; }
+ padding: 40px 32px 32px; }
.outer-wrapper.fixed-to-top {
height: auto; }
main {
margin: auto;
- width: 224px;
- padding-bottom: 48px; }
+ padding-bottom: 48px;
+ width: 224px; }
@media (min-width: 416px) {
main {
width: 352px; } }
@@ -245,49 +244,50 @@ main {
list-style: none;
margin: 0;
margin-bottom: -18px;
- padding: 0;
- margin-inline-end: -32px; }
+ margin-inline-end: -32px;
+ padding: 0; }
@media (max-width: 416px) {
.top-sites-list :nth-child(2n+1) .context-menu {
- margin-inline-start: auto;
margin-inline-end: auto;
- offset-inline-start: -32px;
- offset-inline-end: auto; }
+ margin-inline-start: auto;
+ offset-inline-end: auto;
+ offset-inline-start: -32px; }
.top-sites-list :nth-child(2n) .context-menu {
- margin-inline-start: auto;
margin-inline-end: 5px;
- offset-inline-start: auto;
- offset-inline-end: 0; } }
+ margin-inline-start: auto;
+ offset-inline-end: 0;
+ offset-inline-start: auto; } }
@media (min-width: 416px) and (max-width: 544px) {
- .top-sites-list :nth-child(3n+2) .context-menu, .top-sites-list :nth-child(3n) .context-menu {
- margin-inline-start: auto;
+ .top-sites-list :nth-child(3n+2) .context-menu,
+ .top-sites-list :nth-child(3n) .context-menu {
margin-inline-end: 5px;
- offset-inline-start: auto;
- offset-inline-end: 0; } }
+ margin-inline-start: auto;
+ offset-inline-end: 0;
+ offset-inline-start: auto; } }
@media (min-width: 544px) and (max-width: 800px) {
.top-sites-list :nth-child(4n) .context-menu {
- margin-inline-start: auto;
margin-inline-end: 5px;
- offset-inline-start: auto;
- offset-inline-end: 0; } }
+ margin-inline-start: auto;
+ offset-inline-end: 0;
+ offset-inline-start: auto; } }
@media (min-width: 544px) and (max-width: 768px) {
.top-sites-list :nth-child(4n+3) .context-menu {
- margin-inline-start: auto;
margin-inline-end: 5px;
- offset-inline-start: auto;
- offset-inline-end: 0; } }
+ margin-inline-start: auto;
+ offset-inline-end: 0;
+ offset-inline-start: auto; } }
@media (min-width: 800px) and (max-width: 1248px) {
.top-sites-list :nth-child(6n) .context-menu {
- margin-inline-start: auto;
margin-inline-end: 5px;
- offset-inline-start: auto;
- offset-inline-end: 0; } }
+ margin-inline-start: auto;
+ offset-inline-end: 0;
+ offset-inline-start: auto; } }
@media (min-width: 800px) and (max-width: 1024px) {
.top-sites-list :nth-child(6n+5) .context-menu {
- margin-inline-start: auto;
margin-inline-end: 5px;
- offset-inline-start: auto;
- offset-inline-end: 0; } }
+ margin-inline-start: auto;
+ offset-inline-end: 0;
+ offset-inline-start: auto; } }
.top-sites-list li {
display: inline-block;
margin: 0 0 8px;
@@ -295,53 +295,56 @@ main {
.top-sites-list .top-site-outer {
position: relative; }
.top-sites-list .top-site-outer > a {
- display: block;
color: inherit;
+ display: block;
outline: none; }
- .top-sites-list .top-site-outer > a.active .tile, .top-sites-list .top-site-outer > a:focus .tile {
+ .top-sites-list .top-site-outer > a:-moz-any(.active, :focus) .tile {
box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.1), 0 0 0 5px #D7D7DB;
transition: box-shadow 150ms; }
.top-sites-list .top-site-outer .context-menu-button {
- cursor: pointer;
- position: absolute;
- top: -13.5px;
- offset-inline-end: -13.5px;
- width: 27px;
- height: 27px;
+ background-clip: padding-box;
background-color: #FFF;
background-image: url("chrome://browser/skin/page-action.svg");
background-position: 55%;
- background-clip: padding-box;
border: 1px solid #B1B1B3;
border-radius: 100%;
box-shadow: 0 2px rgba(12, 12, 13, 0.1);
+ cursor: pointer;
fill: rgba(12, 12, 13, 0.8);
- transform: scale(0.25);
+ height: 27px;
+ offset-inline-end: -13.5px;
opacity: 0;
+ position: absolute;
+ top: -13.5px;
+ transform: scale(0.25);
+ transition-duration: 200ms;
transition-property: transform, opacity;
- transition-duration: 200ms; }
- .top-sites-list .top-site-outer .context-menu-button:focus, .top-sites-list .top-site-outer .context-menu-button:active {
- transform: scale(1);
- opacity: 1; }
- .top-sites-list .top-site-outer:hover .tile, .top-sites-list .top-site-outer:focus .tile, .top-sites-list .top-site-outer.active .tile {
+ width: 27px; }
+ .top-sites-list .top-site-outer .context-menu-button:-moz-any(:active, :focus) {
+ opacity: 1;
+ transform: scale(1); }
+ .top-sites-list .top-site-outer:-moz-any(.active, :focus, :hover) .tile {
box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.1), 0 0 0 5px #D7D7DB;
transition: box-shadow 150ms; }
- .top-sites-list .top-site-outer:hover .context-menu-button, .top-sites-list .top-site-outer:focus .context-menu-button, .top-sites-list .top-site-outer.active .context-menu-button {
- transform: scale(1);
- opacity: 1; }
+ .top-sites-list .top-site-outer:-moz-any(.active, :focus, :hover) .edit-menu {
+ opacity: 1;
+ transform: scale(1); }
+ .top-sites-list .top-site-outer:-moz-any(.active, :focus, :hover) .context-menu-button {
+ opacity: 1;
+ transform: scale(1); }
.top-sites-list .top-site-outer .tile {
- position: relative;
- height: 96px;
- width: 96px;
border-radius: 6px;
box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.1), 0 1px 4px 0 rgba(12, 12, 13, 0.1);
- color: #737373;
- font-weight: 200;
- font-size: 32px;
- text-transform: uppercase;
- display: flex;
+ height: 96px;
+ position: relative;
+ width: 96px;
align-items: center;
- justify-content: center; }
+ color: #737373;
+ display: flex;
+ font-size: 32px;
+ font-weight: 200;
+ justify-content: center;
+ text-transform: uppercase; }
.top-sites-list .top-site-outer .tile::before {
content: attr(data-fallback); }
.top-sites-list .top-site-outer.placeholder .tile {
@@ -349,43 +352,43 @@ main {
.top-sites-list .top-site-outer.placeholder .screenshot {
display: none; }
.top-sites-list .top-site-outer .screenshot {
- position: absolute;
- top: 0;
- left: 0;
- height: 100%;
- width: 100%;
background-color: #FFF;
+ background-position: top left;
+ background-size: cover;
border-radius: 6px;
box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.1);
- background-size: cover;
- background-position: top left;
+ height: 100%;
+ left: 0;
+ opacity: 0;
+ position: absolute;
+ top: 0;
transition: opacity 1s;
- opacity: 0; }
+ width: 100%; }
.top-sites-list .top-site-outer .screenshot.active {
opacity: 1; }
.top-sites-list .top-site-outer .top-site-icon {
- position: absolute;
- border-radius: 6px;
- box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.1);
+ background-color: #F9F9FA;
background-position: center center;
background-repeat: no-repeat;
- background-color: #F9F9FA; }
+ border-radius: 6px;
+ box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.1);
+ position: absolute; }
.top-sites-list .top-site-outer .rich-icon {
- top: 0;
- offset-inline-start: 0;
+ background-size: 96px;
height: 100%;
- width: 100%;
- background-size: 96px; }
+ offset-inline-start: 0;
+ top: 0;
+ width: 100%; }
.top-sites-list .top-site-outer .default-icon {
+ background-size: 32px;
bottom: -6px;
height: 42px;
offset-inline-end: -6px;
width: 42px;
- background-size: 32px;
- display: flex;
align-items: center;
- justify-content: center;
- font-size: 20px; }
+ display: flex;
+ font-size: 20px;
+ justify-content: center; }
.top-sites-list .top-site-outer .default-icon[data-fallback]::before {
content: attr(data-fallback); }
.top-sites-list .top-site-outer .title {
@@ -423,7 +426,7 @@ main {
transition-property: transform, opacity;
transition-duration: 200ms;
z-index: 1000; }
- .top-sites-list .top-site-outer .edit-menu:focus, .top-sites-list .top-site-outer .edit-menu:active {
+ .top-sites-list .top-site-outer .edit-menu:-moz-any(:active, :focus) {
transform: scale(1);
opacity: 1; }
.top-sites-list .top-site-outer .edit-menu button {
@@ -443,9 +446,6 @@ main {
border-right: 0; }
.top-sites-list .top-site-outer .edit-menu button:first-child:dir(rtl) {
border-right: 0; }
- .top-sites-list .top-site-outer:hover .edit-menu, .top-sites-list .top-site-outer:focus .edit-menu, .top-sites-list .top-site-outer.active .edit-menu {
- transform: scale(1);
- opacity: 1; }
.edit-topsites-wrapper .edit-topsites-button {
border-right: 1px solid #D7D7DB;
@@ -460,7 +460,7 @@ main {
.edit-topsites-wrapper .edit-topsites-button:dir(rtl) {
border-left: 1px solid #D7D7DB;
border-right: 0; }
- .edit-topsites-wrapper .edit-topsites-button:focus, .edit-topsites-wrapper .edit-topsites-button:active {
+ .edit-topsites-wrapper .edit-topsites-button:-moz-any(:active, :focus) {
opacity: 1; }
.edit-topsites-wrapper .edit-topsites-button button {
background: none;
@@ -499,7 +499,7 @@ main {
.edit-topsites-wrapper .show-less span {
padding-inline-start: 3px; }
-section.top-sites:not(.collapsed):hover .edit-topsites-button {
+.top-sites:not(.collapsed):hover .edit-topsites-button {
opacity: 1;
pointer-events: auto; }
@@ -564,59 +564,59 @@ section.top-sites:not(.collapsed):hover .edit-topsites-button {
transform: translateY(0); } }
.sections-list .section-list {
- margin: 0;
display: grid;
+ grid-gap: 32px;
grid-template-columns: repeat(auto-fit, 224px);
- grid-gap: 32px; }
+ margin: 0; }
@media (max-width: 544px) {
.sections-list .section-list .context-menu {
- margin-inline-start: auto;
margin-inline-end: 5px;
- offset-inline-start: auto;
- offset-inline-end: 0; } }
+ margin-inline-start: auto;
+ offset-inline-end: 0;
+ offset-inline-start: auto; } }
@media (min-width: 544px) and (max-width: 800px) {
.sections-list .section-list :nth-child(2n) .context-menu {
- margin-inline-start: auto;
margin-inline-end: 5px;
- offset-inline-start: auto;
- offset-inline-end: 0; } }
+ margin-inline-start: auto;
+ offset-inline-end: 0;
+ offset-inline-start: auto; } }
@media (min-width: 800px) and (max-width: 1248px) {
.sections-list .section-list :nth-child(3n) .context-menu {
- margin-inline-start: auto;
margin-inline-end: 5px;
- offset-inline-start: auto;
- offset-inline-end: 0; } }
+ margin-inline-start: auto;
+ offset-inline-end: 0;
+ offset-inline-start: auto; } }
.sections-list .section-empty-state {
- width: 100%;
- height: 266px;
- display: flex;
border: 1px solid #D7D7DB;
- border-radius: 3px; }
+ border-radius: 3px;
+ display: flex;
+ height: 266px;
+ width: 100%; }
.sections-list .section-empty-state .empty-state {
margin: auto;
max-width: 350px; }
.sections-list .section-empty-state .empty-state .empty-state-icon {
- background-size: 50px 50px;
- background-repeat: no-repeat;
background-position: center;
- fill: rgba(12, 12, 13, 0.6);
+ background-repeat: no-repeat;
+ background-size: 50px 50px;
-moz-context-properties: fill;
+ display: block;
+ fill: rgba(12, 12, 13, 0.6);
height: 50px;
- width: 50px;
margin: 0 auto;
- display: block; }
+ width: 50px; }
.sections-list .section-empty-state .empty-state .empty-state-message {
- margin-bottom: 0;
- font-size: 13px;
color: #737373;
+ font-size: 13px;
+ margin-bottom: 0;
text-align: center; }
.topic {
- font-size: 12px;
color: #737373;
- margin-top: 12px;
- line-height: 1.6; }
+ font-size: 12px;
+ line-height: 1.6;
+ margin-top: 12px; }
@media (min-width: 800px) {
.topic {
line-height: 16px; } }
@@ -656,27 +656,27 @@ section.top-sites:not(.collapsed):hover .edit-topsites-button {
.topic .topic-read-more:dir(rtl)::after {
transform: scaleX(-1); }
.topic::after {
- content: "";
- display: table;
- clear: both; }
+ clear: both;
+ content: '';
+ display: table; }
.search-wrapper {
cursor: default;
display: flex;
- position: relative;
+ height: 35px;
margin: 1px 1px 40px;
- width: 100%;
- height: 35px; }
+ position: relative;
+ width: 100%; }
.search-wrapper input {
- border: none;
+ border: 0;
border-radius: 3px;
box-shadow: 0 1px 4px 0 rgba(12, 12, 13, 0.1), 0 0 0 1px rgba(0, 0, 0, 0.15);
color: inherit;
+ font-size: 15px;
padding: 0;
padding-inline-end: 36px;
padding-inline-start: 35px;
- width: 100%;
- font-size: 15px; }
+ width: 100%; }
.search-wrapper:hover input {
box-shadow: 0 1px 4px 0 rgba(12, 12, 13, 0.1), 0 0 0 1px rgba(0, 0, 0, 0.25); }
.search-wrapper:active input,
@@ -684,23 +684,23 @@ section.top-sites:not(.collapsed):hover .edit-topsites-button {
box-shadow: 0 0 0 3px #0A84FF; }
.search-wrapper .search-label {
background: url("chrome://browser/skin/search-glass.svg") no-repeat 12px center/16px;
- fill: rgba(12, 12, 13, 0.4);
-moz-context-properties: fill;
- position: absolute;
- offset-inline-start: 0;
+ fill: rgba(12, 12, 13, 0.4);
height: 100%;
+ offset-inline-start: 0;
+ position: absolute;
width: 35px; }
.search-wrapper .search-button {
background: url("chrome://browser/skin/forward.svg") no-repeat center center;
- border-radius: 0 3px 3px 0;
- border: 0;
- width: 36px;
- fill: rgba(12, 12, 13, 0.4);
- -moz-context-properties: fill;
background-size: 16px 16px;
+ border: 0;
+ border-radius: 0 3px 3px 0;
+ -moz-context-properties: fill;
+ fill: rgba(12, 12, 13, 0.4);
height: 100%;
offset-inline-end: 0;
- position: absolute; }
+ position: absolute;
+ width: 36px; }
.search-wrapper .search-button:focus, .search-wrapper .search-button:hover {
background-color: rgba(12, 12, 13, 0.1);
cursor: pointer; }
@@ -713,43 +713,43 @@ section.top-sites:not(.collapsed):hover .edit-topsites-button {
transform: translateY(2px); }
.context-menu {
- display: block;
- position: absolute;
- font-size: 14px;
- box-shadow: 0 5px 10px rgba(0, 0, 0, 0.3), 0 0 0 1px rgba(0, 0, 0, 0.2);
- top: 6.75px;
- offset-inline-start: 100%;
- margin-inline-start: 5px;
- z-index: 10000;
background: #F9F9FA;
- border-radius: 5px; }
+ border-radius: 5px;
+ box-shadow: 0 5px 10px rgba(0, 0, 0, 0.3), 0 0 0 1px rgba(0, 0, 0, 0.2);
+ display: block;
+ font-size: 14px;
+ margin-inline-start: 5px;
+ offset-inline-start: 100%;
+ position: absolute;
+ top: 6.75px;
+ z-index: 10000; }
.context-menu > ul {
+ list-style: none;
margin: 0;
- padding: 5px 0;
- list-style: none; }
+ padding: 5px 0; }
.context-menu > ul > li {
margin: 0;
width: 100%; }
.context-menu > ul > li.separator {
- margin: 5px 0;
- border-bottom: 1px solid rgba(0, 0, 0, 0.2); }
+ border-bottom: 1px solid rgba(0, 0, 0, 0.2);
+ margin: 5px 0; }
.context-menu > ul > li > a {
- outline: none;
- cursor: pointer;
+ align-items: center;
color: inherit;
- white-space: nowrap;
- padding: 3px 12px;
- line-height: 16px;
+ cursor: pointer;
display: flex;
- align-items: center; }
- .context-menu > ul > li > a:hover, .context-menu > ul > li > a:focus {
+ line-height: 16px;
+ outline: none;
+ padding: 3px 12px;
+ white-space: nowrap; }
+ .context-menu > ul > li > a:-moz-any(:focus, :hover) {
background: #0060DF;
color: #FFF; }
- .context-menu > ul > li > a:hover a, .context-menu > ul > li > a:focus a {
+ .context-menu > ul > li > a:-moz-any(:focus, :hover) a {
color: #0C0C0D; }
- .context-menu > ul > li > a:hover .icon, .context-menu > ul > li > a:focus .icon {
+ .context-menu > ul > li > a:-moz-any(:focus, :hover) .icon {
fill: #FFF; }
- .context-menu > ul > li > a:hover:hover, .context-menu > ul > li > a:hover:focus, .context-menu > ul > li > a:focus:hover, .context-menu > ul > li > a:focus:focus {
+ .context-menu > ul > li > a:-moz-any(:focus, :hover):-moz-any(:focus, :hover) {
color: #FFF; }
.prefs-pane {
@@ -859,14 +859,14 @@ section.top-sites:not(.collapsed):hover .edit-topsites-button {
.prefs-pane [type='checkbox']:checked + label::after {
background: url("chrome://global/skin/in-content/check.svg") no-repeat center center;
content: '';
+ -moz-context-properties: fill, stroke;
+ fill: #0060DF;
height: 21px;
offset-inline-start: 0;
position: absolute;
+ stroke: none;
top: 0;
- width: 21px;
- -moz-context-properties: fill, stroke;
- fill: #0060DF;
- stroke: none; }
+ width: 21px; }
.prefs-pane [type='checkbox']:not(:checked) + label::after {
opacity: 0; }
.prefs-pane [type='checkbox']:checked + label::after {
@@ -882,9 +882,9 @@ section.top-sites:not(.collapsed):hover .edit-topsites-button {
border: 0;
cursor: pointer;
fill: rgba(12, 12, 13, 0.6);
+ offset-inline-end: 15px;
padding: 15px;
position: fixed;
- offset-inline-end: 15px;
top: 15px;
z-index: 12001; }
.prefs-pane-button button:hover {
@@ -893,35 +893,35 @@ section.top-sites:not(.collapsed):hover .edit-topsites-button {
background-color: #F9F9FA; }
.confirmation-dialog .modal {
- position: fixed;
- width: 400px;
- top: 20%;
+ box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.1);
left: 50%;
margin-left: -200px;
- box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.08); }
+ position: fixed;
+ top: 20%;
+ width: 400px; }
.confirmation-dialog section {
margin: 0; }
.confirmation-dialog .modal-message {
+ display: flex;
padding: 16px;
- padding-bottom: 0;
- display: flex; }
+ padding-bottom: 0; }
.confirmation-dialog .modal-message p {
margin: 0;
margin-bottom: 16px; }
.confirmation-dialog .actions {
- padding: 0px 16px 0 16px;
- border: none;
+ border: 0;
+ display: flex;
flex-wrap: nowrap;
- display: flex; }
+ padding: 0 16px; }
.confirmation-dialog .actions button {
margin-inline-end: 16px;
width: 50%; }
.confirmation-dialog .actions button.done {
- margin-inline-start: 0;
- margin-inline-end: 0; }
+ margin-inline-end: 0;
+ margin-inline-start: 0; }
.confirmation-dialog .icon {
margin-inline-end: 16px; }
@@ -945,83 +945,83 @@ section.top-sites:not(.collapsed):hover .edit-topsites-button {
.card-outer {
background: #FFF;
- display: inline-block;
- margin-inline-end: 32px;
- width: 224px;
border-radius: 3px;
+ display: inline-block;
height: 266px;
- position: relative; }
+ margin-inline-end: 32px;
+ position: relative;
+ width: 224px; }
.card-outer .context-menu-button {
- cursor: pointer;
- position: absolute;
- top: -13.5px;
- offset-inline-end: -13.5px;
- width: 27px;
- height: 27px;
+ background-clip: padding-box;
background-color: #FFF;
background-image: url("chrome://browser/skin/page-action.svg");
background-position: 55%;
- background-clip: padding-box;
border: 1px solid #B1B1B3;
border-radius: 100%;
box-shadow: 0 2px rgba(12, 12, 13, 0.1);
+ cursor: pointer;
fill: rgba(12, 12, 13, 0.8);
- transform: scale(0.25);
+ height: 27px;
+ offset-inline-end: -13.5px;
opacity: 0;
+ position: absolute;
+ top: -13.5px;
+ transform: scale(0.25);
+ transition-duration: 200ms;
transition-property: transform, opacity;
- transition-duration: 200ms; }
- .card-outer .context-menu-button:focus, .card-outer .context-menu-button:active {
- transform: scale(1);
- opacity: 1; }
+ width: 27px; }
+ .card-outer .context-menu-button:-moz-any(:active, :focus) {
+ opacity: 1;
+ transform: scale(1); }
.card-outer.placeholder {
background: transparent; }
.card-outer.placeholder .card {
box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.1); }
.card-outer .card {
- height: 100%;
border-radius: 3px;
- box-shadow: 0 1px 4px 0 rgba(12, 12, 13, 0.1); }
+ box-shadow: 0 1px 4px 0 rgba(12, 12, 13, 0.1);
+ height: 100%; }
.card-outer > a {
- display: block;
color: inherit;
+ display: block;
height: 100%;
outline: none;
position: absolute;
width: 224px; }
- .card-outer > a.active .card, .card-outer > a:focus .card {
+ .card-outer > a:-moz-any(.active, :focus) .card {
box-shadow: 0 0 0 5px #D7D7DB;
transition: box-shadow 150ms; }
- .card-outer > a.active .card-title, .card-outer > a:focus .card-title {
+ .card-outer > a:-moz-any(.active, :focus) .card-title {
color: #0060DF; }
.card-outer:-moz-any(:hover, :focus, .active):not(.placeholder) {
- outline: none;
box-shadow: 0 0 0 5px #D7D7DB;
- transition: box-shadow 150ms; }
+ transition: box-shadow 150ms;
+ outline: none; }
.card-outer:-moz-any(:hover, :focus, .active):not(.placeholder) .context-menu-button {
- transform: scale(1);
- opacity: 1; }
+ opacity: 1;
+ transform: scale(1); }
.card-outer:-moz-any(:hover, :focus, .active):not(.placeholder) .card-title {
color: #0060DF; }
.card-outer .card-preview-image-outer {
background-color: #F9F9FA;
- position: relative;
- height: 122px;
border-radius: 3px 3px 0 0;
- overflow: hidden; }
+ height: 122px;
+ overflow: hidden;
+ position: relative; }
.card-outer .card-preview-image-outer::after {
border-bottom: 1px solid rgba(0, 0, 0, 0.05);
bottom: 0;
- content: " ";
+ content: '';
position: absolute;
width: 100%; }
.card-outer .card-preview-image-outer .card-preview-image {
- width: 100%;
- height: 100%;
- background-size: cover;
background-position: center;
background-repeat: no-repeat;
+ background-size: cover;
+ height: 100%;
opacity: 0;
- transition: opacity 1s cubic-bezier(0.07, 0.95, 0, 1); }
+ transition: opacity 1s cubic-bezier(0.07, 0.95, 0, 1);
+ width: 100%; }
.card-outer .card-preview-image-outer .card-preview-image.loaded {
opacity: 1; }
.card-outer .card-details {
@@ -1029,8 +1029,8 @@ section.top-sites:not(.collapsed):hover .edit-topsites-button {
.card-outer .card-details.no-image {
padding-top: 16px; }
.card-outer .card-text {
- overflow: hidden;
- max-height: 78px; }
+ max-height: 78px;
+ overflow: hidden; }
.card-outer .card-text.no-image {
max-height: 192px; }
.card-outer .card-text.no-host-name, .card-outer .card-text.no-context {
@@ -1047,30 +1047,30 @@ section.top-sites:not(.collapsed):hover .edit-topsites-button {
.card-outer .card-host-name {
color: #737373;
font-size: 10px;
- padding-bottom: 4px;
- text-transform: uppercase;
overflow: hidden;
- text-overflow: ellipsis; }
+ padding-bottom: 4px;
+ text-overflow: ellipsis;
+ text-transform: uppercase; }
.card-outer .card-title {
- margin: 0 0 2px;
font-size: 14px;
- word-wrap: break-word;
- line-height: 19px; }
+ line-height: 19px;
+ margin: 0 0 2px;
+ word-wrap: break-word; }
.card-outer .card-description {
font-size: 12px;
+ line-height: 19px;
margin: 0;
- word-wrap: break-word;
overflow: hidden;
- line-height: 19px; }
+ word-wrap: break-word; }
.card-outer .card-context {
+ bottom: 0;
+ color: #737373;
+ display: flex;
+ font-size: 11px;
+ left: 0;
padding: 12px 16px 12px 14px;
position: absolute;
- bottom: 0;
- left: 0;
- right: 0;
- color: #737373;
- font-size: 11px;
- display: flex; }
+ right: 0; }
.card-outer .card-context-icon {
fill: rgba(12, 12, 13, 0.6);
margin-inline-end: 6px; }
@@ -1103,13 +1103,13 @@ section.top-sites:not(.collapsed):hover .edit-topsites-button {
display: none; }
@media (min-width: 544px) {
.manual-migration-container .icon {
+ align-self: center;
display: block;
fill: rgba(12, 12, 13, 0.6);
- margin-inline-end: 6px;
- align-self: center; } }
+ margin-inline-end: 6px; } }
.manual-migration-actions {
- border: none;
+ border: 0;
display: block;
flex-wrap: nowrap; }
@media (min-width: 544px) {
@@ -1131,8 +1131,8 @@ section.top-sites:not(.collapsed):hover .edit-topsites-button {
.collapsible-section .section-title .icon-arrowhead-down,
.collapsible-section .section-title .icon-arrowhead-forward {
- margin-top: -1px;
- margin-inline-start: 8px; }
+ margin-inline-start: 8px;
+ margin-top: -1px; }
.collapsible-section .section-top-bar {
position: relative; }
@@ -1142,30 +1142,36 @@ section.top-sites:not(.collapsed):hover .edit-topsites-button {
top: 0; }
.collapsible-section .section-top-bar .info-option-icon {
background-image: url("../data/content/assets/glyph-info-option-12.svg");
- background-size: 12px 12px;
- background-repeat: no-repeat;
background-position: center;
- fill: rgba(12, 12, 13, 0.6);
+ background-repeat: no-repeat;
+ background-size: 12px 12px;
-moz-context-properties: fill;
- height: 16px;
- width: 16px;
display: inline-block;
+ fill: rgba(12, 12, 13, 0.6);
+ height: 16px;
margin-bottom: -2px;
opacity: 0;
- transition: opacity 0.2s cubic-bezier(0.07, 0.95, 0, 1); }
- .collapsible-section .section-top-bar .info-option-icon:focus, .collapsible-section .section-top-bar .info-option-icon:active {
+ transition: opacity 0.2s cubic-bezier(0.07, 0.95, 0, 1);
+ width: 16px; }
+ .collapsible-section .section-top-bar .info-option-icon[aria-expanded='true'] {
+ background-color: rgba(12, 12, 13, 0.1);
+ border-radius: 1px;
+ box-shadow: 0 0 0 5px rgba(12, 12, 13, 0.1);
+ fill: rgba(12, 12, 13, 0.8); }
+ .collapsible-section .section-top-bar .info-option-icon[aria-expanded='true'] + .info-option {
+ opacity: 1;
+ transition: visibility 0.2s, opacity 0.2s cubic-bezier(0.07, 0.95, 0, 1);
+ visibility: visible; }
+ .collapsible-section .section-top-bar .info-option-icon:not([aria-expanded='true']) + .info-option {
+ pointer-events: none; }
+ .collapsible-section .section-top-bar .info-option-icon:-moz-any(:active, :focus) {
opacity: 1; }
- .collapsible-section .section-top-bar .info-option-icon[aria-expanded="true"] {
- background-color: rgba(12, 12, 13, 0.1);
- border-radius: 1px;
- box-shadow: 0 0 0 5px rgba(12, 12, 13, 0.1);
- fill: rgba(12, 12, 13, 0.8); }
.collapsible-section .section-top-bar .section-info-option .info-option {
- visibility: hidden;
opacity: 0;
- transition: visibility 0.2s, opacity 0.2s cubic-bezier(0.07, 0.95, 0, 1); }
+ transition: visibility 0.2s, opacity 0.2s cubic-bezier(0.07, 0.95, 0, 1);
+ visibility: hidden; }
.collapsible-section .section-top-bar .section-info-option .info-option::after, .collapsible-section .section-top-bar .section-info-option .info-option::before {
- content: "";
+ content: '';
offset-inline-end: 0;
position: absolute; }
.collapsible-section .section-top-bar .section-info-option .info-option::before {
@@ -1182,27 +1188,21 @@ section.top-sites:not(.collapsed):hover .edit-topsites-button {
height: 10px;
offset-inline-start: 0;
top: -10px; }
- .collapsible-section .section-top-bar .info-option-icon[aria-expanded="true"] + .info-option {
- visibility: visible;
- opacity: 1;
- transition: visibility 0.2s, opacity 0.2s cubic-bezier(0.07, 0.95, 0, 1); }
- .collapsible-section .section-top-bar .info-option-icon:not([aria-expanded="true"]) + .info-option {
- pointer-events: none; }
.collapsible-section .section-top-bar .info-option {
- z-index: 9999;
- position: absolute;
background: #FFF;
border: 1px solid #D7D7DB;
border-radius: 3px;
+ box-shadow: 0 1px 4px 0 rgba(12, 12, 13, 0.1);
font-size: 13px;
line-height: 120%;
margin-inline-end: -9px;
offset-inline-end: 0;
- top: 26px;
- width: 320px;
padding: 24px;
- box-shadow: 0 1px 4px 0 rgba(12, 12, 13, 0.1);
- -moz-user-select: none; }
+ position: absolute;
+ top: 26px;
+ -moz-user-select: none;
+ width: 320px;
+ z-index: 9999; }
.collapsible-section .section-top-bar .info-option-header {
font-size: 15px;
font-weight: 600; }
@@ -1215,8 +1215,8 @@ section.top-sites:not(.collapsed):hover .edit-topsites-button {
.collapsible-section .section-top-bar .info-option-manage {
margin-top: 24px; }
.collapsible-section .section-top-bar .info-option-manage button {
- background: none;
- border: none;
+ background: 0;
+ border: 0;
color: #0060DF;
cursor: pointer;
margin: 0;
@@ -1256,14 +1256,14 @@ section.top-sites:not(.collapsed):hover .edit-topsites-button {
color: #008EA4;
padding-left: 3px; }
.collapsible-section .section-disclaimer button {
- margin-top: 2px;
- offset-inline-end: 0;
- min-height: 26px;
- max-width: 130px;
background: #F9F9FA;
border: 1px solid #B1B1B3;
border-radius: 4px;
- cursor: pointer; }
+ cursor: pointer;
+ margin-top: 2px;
+ max-width: 130px;
+ min-height: 26px;
+ offset-inline-end: 0; }
.collapsible-section .section-disclaimer button:hover:not(.dismiss) {
box-shadow: 0 0 0 5px #D7D7DB;
transition: box-shadow 150ms; }
diff --git a/browser/extensions/activity-stream/css/activity-stream-mac.css b/browser/extensions/activity-stream/css/activity-stream-mac.css
index 2c6af371c916..f3202a48a6a7 100644
--- a/browser/extensions/activity-stream/css/activity-stream-mac.css
+++ b/browser/extensions/activity-stream/css/activity-stream-mac.css
@@ -23,15 +23,15 @@ input {
display: none !important; }
.icon {
- display: inline-block;
- width: 16px;
- height: 16px;
- background-size: 16px;
background-position: center center;
background-repeat: no-repeat;
- vertical-align: middle;
+ background-size: 16px;
+ -moz-context-properties: fill;
+ display: inline-block;
fill: rgba(12, 12, 13, 0.8);
- -moz-context-properties: fill; }
+ height: 16px;
+ vertical-align: middle;
+ width: 16px; }
.icon.icon-spacer {
margin-inline-end: 8px; }
.icon.icon-small-spacer {
@@ -44,9 +44,9 @@ input {
background-image: url("../data/content/assets/glyph-delete-16.svg"); }
.icon.icon-modal-delete {
background-image: url("../data/content/assets/glyph-modal-delete-32.svg");
- width: 32px;
+ background-size: 32px;
height: 32px;
- background-size: 32px; }
+ width: 32px; }
.icon.icon-dismiss {
background-image: url("../data/content/assets/glyph-dismiss-16.svg"); }
.icon.icon-info {
@@ -71,8 +71,7 @@ input {
background-image: url("../data/content/assets/glyph-historyItem-16.svg"); }
.icon.icon-trending {
background-image: url("../data/content/assets/glyph-trending-16.svg");
- transform: translateY(2px);
- /* trending bolt is visually top heavy */ }
+ transform: translateY(2px); }
.icon.icon-now {
background-image: url("chrome://browser/skin/history.svg"); }
.icon.icon-topsites {
@@ -125,24 +124,24 @@ a {
color: #008EA4; }
.sr-only {
- position: absolute;
- width: 1px;
+ border: 0;
+ clip: rect(0, 0, 0, 0);
height: 1px;
- padding: 0;
margin: -1px;
overflow: hidden;
- clip: rect(0, 0, 0, 0);
- border: 0; }
+ padding: 0;
+ position: absolute;
+ width: 1px; }
.inner-border {
border: 1px solid #D7D7DB;
border-radius: 3px;
+ height: 100%;
+ left: 0;
+ pointer-events: none;
position: absolute;
top: 0;
- left: 0;
width: 100%;
- height: 100%;
- pointer-events: none;
z-index: 100; }
@keyframes fadeIn {
@@ -155,25 +154,25 @@ a {
opacity: 0;
transition: opacity 0.2s ease-in; }
.show-on-init.on {
- opacity: 1;
- animation: fadeIn 0.2s; }
+ animation: fadeIn 0.2s;
+ opacity: 1; }
.actions {
border-top: 1px solid #D7D7DB;
display: flex;
flex-direction: row;
- margin: 0;
- padding: 15px 25px 0 25px;
+ flex-wrap: wrap;
justify-content: flex-start;
- flex-wrap: wrap; }
+ margin: 0;
+ padding: 15px 25px 0; }
.actions button {
background-color: #F9F9FA;
border: 1px solid #B1B1B3;
border-radius: 4px;
color: inherit;
cursor: pointer;
- padding: 10px 30px;
margin-bottom: 15px;
+ padding: 10px 30px;
white-space: nowrap; }
.actions button:hover:not(.dismiss) {
box-shadow: 0 0 0 5px #D7D7DB;
@@ -193,16 +192,16 @@ a {
.outer-wrapper {
display: flex;
- padding: 40px 32px 32px;
+ flex-grow: 1;
height: 100%;
- flex-grow: 1; }
+ padding: 40px 32px 32px; }
.outer-wrapper.fixed-to-top {
height: auto; }
main {
margin: auto;
- width: 224px;
- padding-bottom: 48px; }
+ padding-bottom: 48px;
+ width: 224px; }
@media (min-width: 416px) {
main {
width: 352px; } }
@@ -245,49 +244,50 @@ main {
list-style: none;
margin: 0;
margin-bottom: -18px;
- padding: 0;
- margin-inline-end: -32px; }
+ margin-inline-end: -32px;
+ padding: 0; }
@media (max-width: 416px) {
.top-sites-list :nth-child(2n+1) .context-menu {
- margin-inline-start: auto;
margin-inline-end: auto;
- offset-inline-start: -32px;
- offset-inline-end: auto; }
+ margin-inline-start: auto;
+ offset-inline-end: auto;
+ offset-inline-start: -32px; }
.top-sites-list :nth-child(2n) .context-menu {
- margin-inline-start: auto;
margin-inline-end: 5px;
- offset-inline-start: auto;
- offset-inline-end: 0; } }
+ margin-inline-start: auto;
+ offset-inline-end: 0;
+ offset-inline-start: auto; } }
@media (min-width: 416px) and (max-width: 544px) {
- .top-sites-list :nth-child(3n+2) .context-menu, .top-sites-list :nth-child(3n) .context-menu {
- margin-inline-start: auto;
+ .top-sites-list :nth-child(3n+2) .context-menu,
+ .top-sites-list :nth-child(3n) .context-menu {
margin-inline-end: 5px;
- offset-inline-start: auto;
- offset-inline-end: 0; } }
+ margin-inline-start: auto;
+ offset-inline-end: 0;
+ offset-inline-start: auto; } }
@media (min-width: 544px) and (max-width: 800px) {
.top-sites-list :nth-child(4n) .context-menu {
- margin-inline-start: auto;
margin-inline-end: 5px;
- offset-inline-start: auto;
- offset-inline-end: 0; } }
+ margin-inline-start: auto;
+ offset-inline-end: 0;
+ offset-inline-start: auto; } }
@media (min-width: 544px) and (max-width: 768px) {
.top-sites-list :nth-child(4n+3) .context-menu {
- margin-inline-start: auto;
margin-inline-end: 5px;
- offset-inline-start: auto;
- offset-inline-end: 0; } }
+ margin-inline-start: auto;
+ offset-inline-end: 0;
+ offset-inline-start: auto; } }
@media (min-width: 800px) and (max-width: 1248px) {
.top-sites-list :nth-child(6n) .context-menu {
- margin-inline-start: auto;
margin-inline-end: 5px;
- offset-inline-start: auto;
- offset-inline-end: 0; } }
+ margin-inline-start: auto;
+ offset-inline-end: 0;
+ offset-inline-start: auto; } }
@media (min-width: 800px) and (max-width: 1024px) {
.top-sites-list :nth-child(6n+5) .context-menu {
- margin-inline-start: auto;
margin-inline-end: 5px;
- offset-inline-start: auto;
- offset-inline-end: 0; } }
+ margin-inline-start: auto;
+ offset-inline-end: 0;
+ offset-inline-start: auto; } }
.top-sites-list li {
display: inline-block;
margin: 0 0 8px;
@@ -295,53 +295,56 @@ main {
.top-sites-list .top-site-outer {
position: relative; }
.top-sites-list .top-site-outer > a {
- display: block;
color: inherit;
+ display: block;
outline: none; }
- .top-sites-list .top-site-outer > a.active .tile, .top-sites-list .top-site-outer > a:focus .tile {
+ .top-sites-list .top-site-outer > a:-moz-any(.active, :focus) .tile {
box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.1), 0 0 0 5px #D7D7DB;
transition: box-shadow 150ms; }
.top-sites-list .top-site-outer .context-menu-button {
- cursor: pointer;
- position: absolute;
- top: -13.5px;
- offset-inline-end: -13.5px;
- width: 27px;
- height: 27px;
+ background-clip: padding-box;
background-color: #FFF;
background-image: url("chrome://browser/skin/page-action.svg");
background-position: 55%;
- background-clip: padding-box;
border: 1px solid #B1B1B3;
border-radius: 100%;
box-shadow: 0 2px rgba(12, 12, 13, 0.1);
+ cursor: pointer;
fill: rgba(12, 12, 13, 0.8);
- transform: scale(0.25);
+ height: 27px;
+ offset-inline-end: -13.5px;
opacity: 0;
+ position: absolute;
+ top: -13.5px;
+ transform: scale(0.25);
+ transition-duration: 200ms;
transition-property: transform, opacity;
- transition-duration: 200ms; }
- .top-sites-list .top-site-outer .context-menu-button:focus, .top-sites-list .top-site-outer .context-menu-button:active {
- transform: scale(1);
- opacity: 1; }
- .top-sites-list .top-site-outer:hover .tile, .top-sites-list .top-site-outer:focus .tile, .top-sites-list .top-site-outer.active .tile {
+ width: 27px; }
+ .top-sites-list .top-site-outer .context-menu-button:-moz-any(:active, :focus) {
+ opacity: 1;
+ transform: scale(1); }
+ .top-sites-list .top-site-outer:-moz-any(.active, :focus, :hover) .tile {
box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.1), 0 0 0 5px #D7D7DB;
transition: box-shadow 150ms; }
- .top-sites-list .top-site-outer:hover .context-menu-button, .top-sites-list .top-site-outer:focus .context-menu-button, .top-sites-list .top-site-outer.active .context-menu-button {
- transform: scale(1);
- opacity: 1; }
+ .top-sites-list .top-site-outer:-moz-any(.active, :focus, :hover) .edit-menu {
+ opacity: 1;
+ transform: scale(1); }
+ .top-sites-list .top-site-outer:-moz-any(.active, :focus, :hover) .context-menu-button {
+ opacity: 1;
+ transform: scale(1); }
.top-sites-list .top-site-outer .tile {
- position: relative;
- height: 96px;
- width: 96px;
border-radius: 6px;
box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.1), 0 1px 4px 0 rgba(12, 12, 13, 0.1);
- color: #737373;
- font-weight: 200;
- font-size: 32px;
- text-transform: uppercase;
- display: flex;
+ height: 96px;
+ position: relative;
+ width: 96px;
align-items: center;
- justify-content: center; }
+ color: #737373;
+ display: flex;
+ font-size: 32px;
+ font-weight: 200;
+ justify-content: center;
+ text-transform: uppercase; }
.top-sites-list .top-site-outer .tile::before {
content: attr(data-fallback); }
.top-sites-list .top-site-outer.placeholder .tile {
@@ -349,43 +352,43 @@ main {
.top-sites-list .top-site-outer.placeholder .screenshot {
display: none; }
.top-sites-list .top-site-outer .screenshot {
- position: absolute;
- top: 0;
- left: 0;
- height: 100%;
- width: 100%;
background-color: #FFF;
+ background-position: top left;
+ background-size: cover;
border-radius: 6px;
box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.1);
- background-size: cover;
- background-position: top left;
+ height: 100%;
+ left: 0;
+ opacity: 0;
+ position: absolute;
+ top: 0;
transition: opacity 1s;
- opacity: 0; }
+ width: 100%; }
.top-sites-list .top-site-outer .screenshot.active {
opacity: 1; }
.top-sites-list .top-site-outer .top-site-icon {
- position: absolute;
- border-radius: 6px;
- box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.1);
+ background-color: #F9F9FA;
background-position: center center;
background-repeat: no-repeat;
- background-color: #F9F9FA; }
+ border-radius: 6px;
+ box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.1);
+ position: absolute; }
.top-sites-list .top-site-outer .rich-icon {
- top: 0;
- offset-inline-start: 0;
+ background-size: 96px;
height: 100%;
- width: 100%;
- background-size: 96px; }
+ offset-inline-start: 0;
+ top: 0;
+ width: 100%; }
.top-sites-list .top-site-outer .default-icon {
+ background-size: 32px;
bottom: -6px;
height: 42px;
offset-inline-end: -6px;
width: 42px;
- background-size: 32px;
- display: flex;
align-items: center;
- justify-content: center;
- font-size: 20px; }
+ display: flex;
+ font-size: 20px;
+ justify-content: center; }
.top-sites-list .top-site-outer .default-icon[data-fallback]::before {
content: attr(data-fallback); }
.top-sites-list .top-site-outer .title {
@@ -423,7 +426,7 @@ main {
transition-property: transform, opacity;
transition-duration: 200ms;
z-index: 1000; }
- .top-sites-list .top-site-outer .edit-menu:focus, .top-sites-list .top-site-outer .edit-menu:active {
+ .top-sites-list .top-site-outer .edit-menu:-moz-any(:active, :focus) {
transform: scale(1);
opacity: 1; }
.top-sites-list .top-site-outer .edit-menu button {
@@ -443,9 +446,6 @@ main {
border-right: 0; }
.top-sites-list .top-site-outer .edit-menu button:first-child:dir(rtl) {
border-right: 0; }
- .top-sites-list .top-site-outer:hover .edit-menu, .top-sites-list .top-site-outer:focus .edit-menu, .top-sites-list .top-site-outer.active .edit-menu {
- transform: scale(1);
- opacity: 1; }
.edit-topsites-wrapper .edit-topsites-button {
border-right: 1px solid #D7D7DB;
@@ -460,7 +460,7 @@ main {
.edit-topsites-wrapper .edit-topsites-button:dir(rtl) {
border-left: 1px solid #D7D7DB;
border-right: 0; }
- .edit-topsites-wrapper .edit-topsites-button:focus, .edit-topsites-wrapper .edit-topsites-button:active {
+ .edit-topsites-wrapper .edit-topsites-button:-moz-any(:active, :focus) {
opacity: 1; }
.edit-topsites-wrapper .edit-topsites-button button {
background: none;
@@ -499,7 +499,7 @@ main {
.edit-topsites-wrapper .show-less span {
padding-inline-start: 3px; }
-section.top-sites:not(.collapsed):hover .edit-topsites-button {
+.top-sites:not(.collapsed):hover .edit-topsites-button {
opacity: 1;
pointer-events: auto; }
@@ -564,59 +564,59 @@ section.top-sites:not(.collapsed):hover .edit-topsites-button {
transform: translateY(0); } }
.sections-list .section-list {
- margin: 0;
display: grid;
+ grid-gap: 32px;
grid-template-columns: repeat(auto-fit, 224px);
- grid-gap: 32px; }
+ margin: 0; }
@media (max-width: 544px) {
.sections-list .section-list .context-menu {
- margin-inline-start: auto;
margin-inline-end: 5px;
- offset-inline-start: auto;
- offset-inline-end: 0; } }
+ margin-inline-start: auto;
+ offset-inline-end: 0;
+ offset-inline-start: auto; } }
@media (min-width: 544px) and (max-width: 800px) {
.sections-list .section-list :nth-child(2n) .context-menu {
- margin-inline-start: auto;
margin-inline-end: 5px;
- offset-inline-start: auto;
- offset-inline-end: 0; } }
+ margin-inline-start: auto;
+ offset-inline-end: 0;
+ offset-inline-start: auto; } }
@media (min-width: 800px) and (max-width: 1248px) {
.sections-list .section-list :nth-child(3n) .context-menu {
- margin-inline-start: auto;
margin-inline-end: 5px;
- offset-inline-start: auto;
- offset-inline-end: 0; } }
+ margin-inline-start: auto;
+ offset-inline-end: 0;
+ offset-inline-start: auto; } }
.sections-list .section-empty-state {
- width: 100%;
- height: 266px;
- display: flex;
border: 1px solid #D7D7DB;
- border-radius: 3px; }
+ border-radius: 3px;
+ display: flex;
+ height: 266px;
+ width: 100%; }
.sections-list .section-empty-state .empty-state {
margin: auto;
max-width: 350px; }
.sections-list .section-empty-state .empty-state .empty-state-icon {
- background-size: 50px 50px;
- background-repeat: no-repeat;
background-position: center;
- fill: rgba(12, 12, 13, 0.6);
+ background-repeat: no-repeat;
+ background-size: 50px 50px;
-moz-context-properties: fill;
+ display: block;
+ fill: rgba(12, 12, 13, 0.6);
height: 50px;
- width: 50px;
margin: 0 auto;
- display: block; }
+ width: 50px; }
.sections-list .section-empty-state .empty-state .empty-state-message {
- margin-bottom: 0;
- font-size: 13px;
color: #737373;
+ font-size: 13px;
+ margin-bottom: 0;
text-align: center; }
.topic {
- font-size: 12px;
color: #737373;
- margin-top: 12px;
- line-height: 1.6; }
+ font-size: 12px;
+ line-height: 1.6;
+ margin-top: 12px; }
@media (min-width: 800px) {
.topic {
line-height: 16px; } }
@@ -656,27 +656,27 @@ section.top-sites:not(.collapsed):hover .edit-topsites-button {
.topic .topic-read-more:dir(rtl)::after {
transform: scaleX(-1); }
.topic::after {
- content: "";
- display: table;
- clear: both; }
+ clear: both;
+ content: '';
+ display: table; }
.search-wrapper {
cursor: default;
display: flex;
- position: relative;
+ height: 35px;
margin: 1px 1px 40px;
- width: 100%;
- height: 35px; }
+ position: relative;
+ width: 100%; }
.search-wrapper input {
- border: none;
+ border: 0;
border-radius: 3px;
box-shadow: 0 1px 4px 0 rgba(12, 12, 13, 0.1), 0 0 0 1px rgba(0, 0, 0, 0.15);
color: inherit;
+ font-size: 15px;
padding: 0;
padding-inline-end: 36px;
padding-inline-start: 35px;
- width: 100%;
- font-size: 15px; }
+ width: 100%; }
.search-wrapper:hover input {
box-shadow: 0 1px 4px 0 rgba(12, 12, 13, 0.1), 0 0 0 1px rgba(0, 0, 0, 0.25); }
.search-wrapper:active input,
@@ -684,23 +684,23 @@ section.top-sites:not(.collapsed):hover .edit-topsites-button {
box-shadow: 0 0 0 3px #0A84FF; }
.search-wrapper .search-label {
background: url("chrome://browser/skin/search-glass.svg") no-repeat 12px center/16px;
- fill: rgba(12, 12, 13, 0.4);
-moz-context-properties: fill;
- position: absolute;
- offset-inline-start: 0;
+ fill: rgba(12, 12, 13, 0.4);
height: 100%;
+ offset-inline-start: 0;
+ position: absolute;
width: 35px; }
.search-wrapper .search-button {
background: url("chrome://browser/skin/forward.svg") no-repeat center center;
- border-radius: 0 3px 3px 0;
- border: 0;
- width: 36px;
- fill: rgba(12, 12, 13, 0.4);
- -moz-context-properties: fill;
background-size: 16px 16px;
+ border: 0;
+ border-radius: 0 3px 3px 0;
+ -moz-context-properties: fill;
+ fill: rgba(12, 12, 13, 0.4);
height: 100%;
offset-inline-end: 0;
- position: absolute; }
+ position: absolute;
+ width: 36px; }
.search-wrapper .search-button:focus, .search-wrapper .search-button:hover {
background-color: rgba(12, 12, 13, 0.1);
cursor: pointer; }
@@ -713,43 +713,43 @@ section.top-sites:not(.collapsed):hover .edit-topsites-button {
transform: translateY(2px); }
.context-menu {
- display: block;
- position: absolute;
- font-size: 14px;
- box-shadow: 0 5px 10px rgba(0, 0, 0, 0.3), 0 0 0 1px rgba(0, 0, 0, 0.2);
- top: 6.75px;
- offset-inline-start: 100%;
- margin-inline-start: 5px;
- z-index: 10000;
background: #F9F9FA;
- border-radius: 5px; }
+ border-radius: 5px;
+ box-shadow: 0 5px 10px rgba(0, 0, 0, 0.3), 0 0 0 1px rgba(0, 0, 0, 0.2);
+ display: block;
+ font-size: 14px;
+ margin-inline-start: 5px;
+ offset-inline-start: 100%;
+ position: absolute;
+ top: 6.75px;
+ z-index: 10000; }
.context-menu > ul {
+ list-style: none;
margin: 0;
- padding: 5px 0;
- list-style: none; }
+ padding: 5px 0; }
.context-menu > ul > li {
margin: 0;
width: 100%; }
.context-menu > ul > li.separator {
- margin: 5px 0;
- border-bottom: 1px solid rgba(0, 0, 0, 0.2); }
+ border-bottom: 1px solid rgba(0, 0, 0, 0.2);
+ margin: 5px 0; }
.context-menu > ul > li > a {
- outline: none;
- cursor: pointer;
+ align-items: center;
color: inherit;
- white-space: nowrap;
- padding: 3px 12px;
- line-height: 16px;
+ cursor: pointer;
display: flex;
- align-items: center; }
- .context-menu > ul > li > a:hover, .context-menu > ul > li > a:focus {
+ line-height: 16px;
+ outline: none;
+ padding: 3px 12px;
+ white-space: nowrap; }
+ .context-menu > ul > li > a:-moz-any(:focus, :hover) {
background: #0060DF;
color: #FFF; }
- .context-menu > ul > li > a:hover a, .context-menu > ul > li > a:focus a {
+ .context-menu > ul > li > a:-moz-any(:focus, :hover) a {
color: #0C0C0D; }
- .context-menu > ul > li > a:hover .icon, .context-menu > ul > li > a:focus .icon {
+ .context-menu > ul > li > a:-moz-any(:focus, :hover) .icon {
fill: #FFF; }
- .context-menu > ul > li > a:hover:hover, .context-menu > ul > li > a:hover:focus, .context-menu > ul > li > a:focus:hover, .context-menu > ul > li > a:focus:focus {
+ .context-menu > ul > li > a:-moz-any(:focus, :hover):-moz-any(:focus, :hover) {
color: #FFF; }
.prefs-pane {
@@ -859,14 +859,14 @@ section.top-sites:not(.collapsed):hover .edit-topsites-button {
.prefs-pane [type='checkbox']:checked + label::after {
background: url("chrome://global/skin/in-content/check.svg") no-repeat center center;
content: '';
+ -moz-context-properties: fill, stroke;
+ fill: #0060DF;
height: 21px;
offset-inline-start: 0;
position: absolute;
+ stroke: none;
top: 0;
- width: 21px;
- -moz-context-properties: fill, stroke;
- fill: #0060DF;
- stroke: none; }
+ width: 21px; }
.prefs-pane [type='checkbox']:not(:checked) + label::after {
opacity: 0; }
.prefs-pane [type='checkbox']:checked + label::after {
@@ -882,9 +882,9 @@ section.top-sites:not(.collapsed):hover .edit-topsites-button {
border: 0;
cursor: pointer;
fill: rgba(12, 12, 13, 0.6);
+ offset-inline-end: 15px;
padding: 15px;
position: fixed;
- offset-inline-end: 15px;
top: 15px;
z-index: 12001; }
.prefs-pane-button button:hover {
@@ -893,35 +893,35 @@ section.top-sites:not(.collapsed):hover .edit-topsites-button {
background-color: #F9F9FA; }
.confirmation-dialog .modal {
- position: fixed;
- width: 400px;
- top: 20%;
+ box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.1);
left: 50%;
margin-left: -200px;
- box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.08); }
+ position: fixed;
+ top: 20%;
+ width: 400px; }
.confirmation-dialog section {
margin: 0; }
.confirmation-dialog .modal-message {
+ display: flex;
padding: 16px;
- padding-bottom: 0;
- display: flex; }
+ padding-bottom: 0; }
.confirmation-dialog .modal-message p {
margin: 0;
margin-bottom: 16px; }
.confirmation-dialog .actions {
- padding: 0px 16px 0 16px;
- border: none;
+ border: 0;
+ display: flex;
flex-wrap: nowrap;
- display: flex; }
+ padding: 0 16px; }
.confirmation-dialog .actions button {
margin-inline-end: 16px;
width: 50%; }
.confirmation-dialog .actions button.done {
- margin-inline-start: 0;
- margin-inline-end: 0; }
+ margin-inline-end: 0;
+ margin-inline-start: 0; }
.confirmation-dialog .icon {
margin-inline-end: 16px; }
@@ -945,83 +945,83 @@ section.top-sites:not(.collapsed):hover .edit-topsites-button {
.card-outer {
background: #FFF;
- display: inline-block;
- margin-inline-end: 32px;
- width: 224px;
border-radius: 3px;
+ display: inline-block;
height: 266px;
- position: relative; }
+ margin-inline-end: 32px;
+ position: relative;
+ width: 224px; }
.card-outer .context-menu-button {
- cursor: pointer;
- position: absolute;
- top: -13.5px;
- offset-inline-end: -13.5px;
- width: 27px;
- height: 27px;
+ background-clip: padding-box;
background-color: #FFF;
background-image: url("chrome://browser/skin/page-action.svg");
background-position: 55%;
- background-clip: padding-box;
border: 1px solid #B1B1B3;
border-radius: 100%;
box-shadow: 0 2px rgba(12, 12, 13, 0.1);
+ cursor: pointer;
fill: rgba(12, 12, 13, 0.8);
- transform: scale(0.25);
+ height: 27px;
+ offset-inline-end: -13.5px;
opacity: 0;
+ position: absolute;
+ top: -13.5px;
+ transform: scale(0.25);
+ transition-duration: 200ms;
transition-property: transform, opacity;
- transition-duration: 200ms; }
- .card-outer .context-menu-button:focus, .card-outer .context-menu-button:active {
- transform: scale(1);
- opacity: 1; }
+ width: 27px; }
+ .card-outer .context-menu-button:-moz-any(:active, :focus) {
+ opacity: 1;
+ transform: scale(1); }
.card-outer.placeholder {
background: transparent; }
.card-outer.placeholder .card {
box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.1); }
.card-outer .card {
- height: 100%;
border-radius: 3px;
- box-shadow: 0 1px 4px 0 rgba(12, 12, 13, 0.1); }
+ box-shadow: 0 1px 4px 0 rgba(12, 12, 13, 0.1);
+ height: 100%; }
.card-outer > a {
- display: block;
color: inherit;
+ display: block;
height: 100%;
outline: none;
position: absolute;
width: 224px; }
- .card-outer > a.active .card, .card-outer > a:focus .card {
+ .card-outer > a:-moz-any(.active, :focus) .card {
box-shadow: 0 0 0 5px #D7D7DB;
transition: box-shadow 150ms; }
- .card-outer > a.active .card-title, .card-outer > a:focus .card-title {
+ .card-outer > a:-moz-any(.active, :focus) .card-title {
color: #0060DF; }
.card-outer:-moz-any(:hover, :focus, .active):not(.placeholder) {
- outline: none;
box-shadow: 0 0 0 5px #D7D7DB;
- transition: box-shadow 150ms; }
+ transition: box-shadow 150ms;
+ outline: none; }
.card-outer:-moz-any(:hover, :focus, .active):not(.placeholder) .context-menu-button {
- transform: scale(1);
- opacity: 1; }
+ opacity: 1;
+ transform: scale(1); }
.card-outer:-moz-any(:hover, :focus, .active):not(.placeholder) .card-title {
color: #0060DF; }
.card-outer .card-preview-image-outer {
background-color: #F9F9FA;
- position: relative;
- height: 122px;
border-radius: 3px 3px 0 0;
- overflow: hidden; }
+ height: 122px;
+ overflow: hidden;
+ position: relative; }
.card-outer .card-preview-image-outer::after {
border-bottom: 1px solid rgba(0, 0, 0, 0.05);
bottom: 0;
- content: " ";
+ content: '';
position: absolute;
width: 100%; }
.card-outer .card-preview-image-outer .card-preview-image {
- width: 100%;
- height: 100%;
- background-size: cover;
background-position: center;
background-repeat: no-repeat;
+ background-size: cover;
+ height: 100%;
opacity: 0;
- transition: opacity 1s cubic-bezier(0.07, 0.95, 0, 1); }
+ transition: opacity 1s cubic-bezier(0.07, 0.95, 0, 1);
+ width: 100%; }
.card-outer .card-preview-image-outer .card-preview-image.loaded {
opacity: 1; }
.card-outer .card-details {
@@ -1029,8 +1029,8 @@ section.top-sites:not(.collapsed):hover .edit-topsites-button {
.card-outer .card-details.no-image {
padding-top: 16px; }
.card-outer .card-text {
- overflow: hidden;
- max-height: 78px; }
+ max-height: 78px;
+ overflow: hidden; }
.card-outer .card-text.no-image {
max-height: 192px; }
.card-outer .card-text.no-host-name, .card-outer .card-text.no-context {
@@ -1047,30 +1047,30 @@ section.top-sites:not(.collapsed):hover .edit-topsites-button {
.card-outer .card-host-name {
color: #737373;
font-size: 10px;
- padding-bottom: 4px;
- text-transform: uppercase;
overflow: hidden;
- text-overflow: ellipsis; }
+ padding-bottom: 4px;
+ text-overflow: ellipsis;
+ text-transform: uppercase; }
.card-outer .card-title {
- margin: 0 0 2px;
font-size: 14px;
- word-wrap: break-word;
- line-height: 19px; }
+ line-height: 19px;
+ margin: 0 0 2px;
+ word-wrap: break-word; }
.card-outer .card-description {
font-size: 12px;
+ line-height: 19px;
margin: 0;
- word-wrap: break-word;
overflow: hidden;
- line-height: 19px; }
+ word-wrap: break-word; }
.card-outer .card-context {
+ bottom: 0;
+ color: #737373;
+ display: flex;
+ font-size: 11px;
+ left: 0;
padding: 12px 16px 12px 14px;
position: absolute;
- bottom: 0;
- left: 0;
- right: 0;
- color: #737373;
- font-size: 11px;
- display: flex; }
+ right: 0; }
.card-outer .card-context-icon {
fill: rgba(12, 12, 13, 0.6);
margin-inline-end: 6px; }
@@ -1103,13 +1103,13 @@ section.top-sites:not(.collapsed):hover .edit-topsites-button {
display: none; }
@media (min-width: 544px) {
.manual-migration-container .icon {
+ align-self: center;
display: block;
fill: rgba(12, 12, 13, 0.6);
- margin-inline-end: 6px;
- align-self: center; } }
+ margin-inline-end: 6px; } }
.manual-migration-actions {
- border: none;
+ border: 0;
display: block;
flex-wrap: nowrap; }
@media (min-width: 544px) {
@@ -1131,8 +1131,8 @@ section.top-sites:not(.collapsed):hover .edit-topsites-button {
.collapsible-section .section-title .icon-arrowhead-down,
.collapsible-section .section-title .icon-arrowhead-forward {
- margin-top: -1px;
- margin-inline-start: 8px; }
+ margin-inline-start: 8px;
+ margin-top: -1px; }
.collapsible-section .section-top-bar {
position: relative; }
@@ -1142,30 +1142,36 @@ section.top-sites:not(.collapsed):hover .edit-topsites-button {
top: 0; }
.collapsible-section .section-top-bar .info-option-icon {
background-image: url("../data/content/assets/glyph-info-option-12.svg");
- background-size: 12px 12px;
- background-repeat: no-repeat;
background-position: center;
- fill: rgba(12, 12, 13, 0.6);
+ background-repeat: no-repeat;
+ background-size: 12px 12px;
-moz-context-properties: fill;
- height: 16px;
- width: 16px;
display: inline-block;
+ fill: rgba(12, 12, 13, 0.6);
+ height: 16px;
margin-bottom: -2px;
opacity: 0;
- transition: opacity 0.2s cubic-bezier(0.07, 0.95, 0, 1); }
- .collapsible-section .section-top-bar .info-option-icon:focus, .collapsible-section .section-top-bar .info-option-icon:active {
+ transition: opacity 0.2s cubic-bezier(0.07, 0.95, 0, 1);
+ width: 16px; }
+ .collapsible-section .section-top-bar .info-option-icon[aria-expanded='true'] {
+ background-color: rgba(12, 12, 13, 0.1);
+ border-radius: 1px;
+ box-shadow: 0 0 0 5px rgba(12, 12, 13, 0.1);
+ fill: rgba(12, 12, 13, 0.8); }
+ .collapsible-section .section-top-bar .info-option-icon[aria-expanded='true'] + .info-option {
+ opacity: 1;
+ transition: visibility 0.2s, opacity 0.2s cubic-bezier(0.07, 0.95, 0, 1);
+ visibility: visible; }
+ .collapsible-section .section-top-bar .info-option-icon:not([aria-expanded='true']) + .info-option {
+ pointer-events: none; }
+ .collapsible-section .section-top-bar .info-option-icon:-moz-any(:active, :focus) {
opacity: 1; }
- .collapsible-section .section-top-bar .info-option-icon[aria-expanded="true"] {
- background-color: rgba(12, 12, 13, 0.1);
- border-radius: 1px;
- box-shadow: 0 0 0 5px rgba(12, 12, 13, 0.1);
- fill: rgba(12, 12, 13, 0.8); }
.collapsible-section .section-top-bar .section-info-option .info-option {
- visibility: hidden;
opacity: 0;
- transition: visibility 0.2s, opacity 0.2s cubic-bezier(0.07, 0.95, 0, 1); }
+ transition: visibility 0.2s, opacity 0.2s cubic-bezier(0.07, 0.95, 0, 1);
+ visibility: hidden; }
.collapsible-section .section-top-bar .section-info-option .info-option::after, .collapsible-section .section-top-bar .section-info-option .info-option::before {
- content: "";
+ content: '';
offset-inline-end: 0;
position: absolute; }
.collapsible-section .section-top-bar .section-info-option .info-option::before {
@@ -1182,27 +1188,21 @@ section.top-sites:not(.collapsed):hover .edit-topsites-button {
height: 10px;
offset-inline-start: 0;
top: -10px; }
- .collapsible-section .section-top-bar .info-option-icon[aria-expanded="true"] + .info-option {
- visibility: visible;
- opacity: 1;
- transition: visibility 0.2s, opacity 0.2s cubic-bezier(0.07, 0.95, 0, 1); }
- .collapsible-section .section-top-bar .info-option-icon:not([aria-expanded="true"]) + .info-option {
- pointer-events: none; }
.collapsible-section .section-top-bar .info-option {
- z-index: 9999;
- position: absolute;
background: #FFF;
border: 1px solid #D7D7DB;
border-radius: 3px;
+ box-shadow: 0 1px 4px 0 rgba(12, 12, 13, 0.1);
font-size: 13px;
line-height: 120%;
margin-inline-end: -9px;
offset-inline-end: 0;
- top: 26px;
- width: 320px;
padding: 24px;
- box-shadow: 0 1px 4px 0 rgba(12, 12, 13, 0.1);
- -moz-user-select: none; }
+ position: absolute;
+ top: 26px;
+ -moz-user-select: none;
+ width: 320px;
+ z-index: 9999; }
.collapsible-section .section-top-bar .info-option-header {
font-size: 15px;
font-weight: 600; }
@@ -1215,8 +1215,8 @@ section.top-sites:not(.collapsed):hover .edit-topsites-button {
.collapsible-section .section-top-bar .info-option-manage {
margin-top: 24px; }
.collapsible-section .section-top-bar .info-option-manage button {
- background: none;
- border: none;
+ background: 0;
+ border: 0;
color: #0060DF;
cursor: pointer;
margin: 0;
@@ -1256,14 +1256,14 @@ section.top-sites:not(.collapsed):hover .edit-topsites-button {
color: #008EA4;
padding-left: 3px; }
.collapsible-section .section-disclaimer button {
- margin-top: 2px;
- offset-inline-end: 0;
- min-height: 26px;
- max-width: 130px;
background: #F9F9FA;
border: 1px solid #B1B1B3;
border-radius: 4px;
- cursor: pointer; }
+ cursor: pointer;
+ margin-top: 2px;
+ max-width: 130px;
+ min-height: 26px;
+ offset-inline-end: 0; }
.collapsible-section .section-disclaimer button:hover:not(.dismiss) {
box-shadow: 0 0 0 5px #D7D7DB;
transition: box-shadow 150ms; }
diff --git a/browser/extensions/activity-stream/css/activity-stream-windows.css b/browser/extensions/activity-stream/css/activity-stream-windows.css
index 0d7ef2799ef6..04a04888c215 100644
--- a/browser/extensions/activity-stream/css/activity-stream-windows.css
+++ b/browser/extensions/activity-stream/css/activity-stream-windows.css
@@ -23,15 +23,15 @@ input {
display: none !important; }
.icon {
- display: inline-block;
- width: 16px;
- height: 16px;
- background-size: 16px;
background-position: center center;
background-repeat: no-repeat;
- vertical-align: middle;
+ background-size: 16px;
+ -moz-context-properties: fill;
+ display: inline-block;
fill: rgba(12, 12, 13, 0.8);
- -moz-context-properties: fill; }
+ height: 16px;
+ vertical-align: middle;
+ width: 16px; }
.icon.icon-spacer {
margin-inline-end: 8px; }
.icon.icon-small-spacer {
@@ -44,9 +44,9 @@ input {
background-image: url("../data/content/assets/glyph-delete-16.svg"); }
.icon.icon-modal-delete {
background-image: url("../data/content/assets/glyph-modal-delete-32.svg");
- width: 32px;
+ background-size: 32px;
height: 32px;
- background-size: 32px; }
+ width: 32px; }
.icon.icon-dismiss {
background-image: url("../data/content/assets/glyph-dismiss-16.svg"); }
.icon.icon-info {
@@ -71,8 +71,7 @@ input {
background-image: url("../data/content/assets/glyph-historyItem-16.svg"); }
.icon.icon-trending {
background-image: url("../data/content/assets/glyph-trending-16.svg");
- transform: translateY(2px);
- /* trending bolt is visually top heavy */ }
+ transform: translateY(2px); }
.icon.icon-now {
background-image: url("chrome://browser/skin/history.svg"); }
.icon.icon-topsites {
@@ -125,24 +124,24 @@ a {
color: #008EA4; }
.sr-only {
- position: absolute;
- width: 1px;
+ border: 0;
+ clip: rect(0, 0, 0, 0);
height: 1px;
- padding: 0;
margin: -1px;
overflow: hidden;
- clip: rect(0, 0, 0, 0);
- border: 0; }
+ padding: 0;
+ position: absolute;
+ width: 1px; }
.inner-border {
border: 1px solid #D7D7DB;
border-radius: 3px;
+ height: 100%;
+ left: 0;
+ pointer-events: none;
position: absolute;
top: 0;
- left: 0;
width: 100%;
- height: 100%;
- pointer-events: none;
z-index: 100; }
@keyframes fadeIn {
@@ -155,25 +154,25 @@ a {
opacity: 0;
transition: opacity 0.2s ease-in; }
.show-on-init.on {
- opacity: 1;
- animation: fadeIn 0.2s; }
+ animation: fadeIn 0.2s;
+ opacity: 1; }
.actions {
border-top: 1px solid #D7D7DB;
display: flex;
flex-direction: row;
- margin: 0;
- padding: 15px 25px 0 25px;
+ flex-wrap: wrap;
justify-content: flex-start;
- flex-wrap: wrap; }
+ margin: 0;
+ padding: 15px 25px 0; }
.actions button {
background-color: #F9F9FA;
border: 1px solid #B1B1B3;
border-radius: 4px;
color: inherit;
cursor: pointer;
- padding: 10px 30px;
margin-bottom: 15px;
+ padding: 10px 30px;
white-space: nowrap; }
.actions button:hover:not(.dismiss) {
box-shadow: 0 0 0 5px #D7D7DB;
@@ -193,16 +192,16 @@ a {
.outer-wrapper {
display: flex;
- padding: 40px 32px 32px;
+ flex-grow: 1;
height: 100%;
- flex-grow: 1; }
+ padding: 40px 32px 32px; }
.outer-wrapper.fixed-to-top {
height: auto; }
main {
margin: auto;
- width: 224px;
- padding-bottom: 48px; }
+ padding-bottom: 48px;
+ width: 224px; }
@media (min-width: 416px) {
main {
width: 352px; } }
@@ -245,49 +244,50 @@ main {
list-style: none;
margin: 0;
margin-bottom: -18px;
- padding: 0;
- margin-inline-end: -32px; }
+ margin-inline-end: -32px;
+ padding: 0; }
@media (max-width: 416px) {
.top-sites-list :nth-child(2n+1) .context-menu {
- margin-inline-start: auto;
margin-inline-end: auto;
- offset-inline-start: -32px;
- offset-inline-end: auto; }
+ margin-inline-start: auto;
+ offset-inline-end: auto;
+ offset-inline-start: -32px; }
.top-sites-list :nth-child(2n) .context-menu {
- margin-inline-start: auto;
margin-inline-end: 5px;
- offset-inline-start: auto;
- offset-inline-end: 0; } }
+ margin-inline-start: auto;
+ offset-inline-end: 0;
+ offset-inline-start: auto; } }
@media (min-width: 416px) and (max-width: 544px) {
- .top-sites-list :nth-child(3n+2) .context-menu, .top-sites-list :nth-child(3n) .context-menu {
- margin-inline-start: auto;
+ .top-sites-list :nth-child(3n+2) .context-menu,
+ .top-sites-list :nth-child(3n) .context-menu {
margin-inline-end: 5px;
- offset-inline-start: auto;
- offset-inline-end: 0; } }
+ margin-inline-start: auto;
+ offset-inline-end: 0;
+ offset-inline-start: auto; } }
@media (min-width: 544px) and (max-width: 800px) {
.top-sites-list :nth-child(4n) .context-menu {
- margin-inline-start: auto;
margin-inline-end: 5px;
- offset-inline-start: auto;
- offset-inline-end: 0; } }
+ margin-inline-start: auto;
+ offset-inline-end: 0;
+ offset-inline-start: auto; } }
@media (min-width: 544px) and (max-width: 768px) {
.top-sites-list :nth-child(4n+3) .context-menu {
- margin-inline-start: auto;
margin-inline-end: 5px;
- offset-inline-start: auto;
- offset-inline-end: 0; } }
+ margin-inline-start: auto;
+ offset-inline-end: 0;
+ offset-inline-start: auto; } }
@media (min-width: 800px) and (max-width: 1248px) {
.top-sites-list :nth-child(6n) .context-menu {
- margin-inline-start: auto;
margin-inline-end: 5px;
- offset-inline-start: auto;
- offset-inline-end: 0; } }
+ margin-inline-start: auto;
+ offset-inline-end: 0;
+ offset-inline-start: auto; } }
@media (min-width: 800px) and (max-width: 1024px) {
.top-sites-list :nth-child(6n+5) .context-menu {
- margin-inline-start: auto;
margin-inline-end: 5px;
- offset-inline-start: auto;
- offset-inline-end: 0; } }
+ margin-inline-start: auto;
+ offset-inline-end: 0;
+ offset-inline-start: auto; } }
.top-sites-list li {
display: inline-block;
margin: 0 0 8px;
@@ -295,53 +295,56 @@ main {
.top-sites-list .top-site-outer {
position: relative; }
.top-sites-list .top-site-outer > a {
- display: block;
color: inherit;
+ display: block;
outline: none; }
- .top-sites-list .top-site-outer > a.active .tile, .top-sites-list .top-site-outer > a:focus .tile {
+ .top-sites-list .top-site-outer > a:-moz-any(.active, :focus) .tile {
box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.1), 0 0 0 5px #D7D7DB;
transition: box-shadow 150ms; }
.top-sites-list .top-site-outer .context-menu-button {
- cursor: pointer;
- position: absolute;
- top: -13.5px;
- offset-inline-end: -13.5px;
- width: 27px;
- height: 27px;
+ background-clip: padding-box;
background-color: #FFF;
background-image: url("chrome://browser/skin/page-action.svg");
background-position: 55%;
- background-clip: padding-box;
border: 1px solid #B1B1B3;
border-radius: 100%;
box-shadow: 0 2px rgba(12, 12, 13, 0.1);
+ cursor: pointer;
fill: rgba(12, 12, 13, 0.8);
- transform: scale(0.25);
+ height: 27px;
+ offset-inline-end: -13.5px;
opacity: 0;
+ position: absolute;
+ top: -13.5px;
+ transform: scale(0.25);
+ transition-duration: 200ms;
transition-property: transform, opacity;
- transition-duration: 200ms; }
- .top-sites-list .top-site-outer .context-menu-button:focus, .top-sites-list .top-site-outer .context-menu-button:active {
- transform: scale(1);
- opacity: 1; }
- .top-sites-list .top-site-outer:hover .tile, .top-sites-list .top-site-outer:focus .tile, .top-sites-list .top-site-outer.active .tile {
+ width: 27px; }
+ .top-sites-list .top-site-outer .context-menu-button:-moz-any(:active, :focus) {
+ opacity: 1;
+ transform: scale(1); }
+ .top-sites-list .top-site-outer:-moz-any(.active, :focus, :hover) .tile {
box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.1), 0 0 0 5px #D7D7DB;
transition: box-shadow 150ms; }
- .top-sites-list .top-site-outer:hover .context-menu-button, .top-sites-list .top-site-outer:focus .context-menu-button, .top-sites-list .top-site-outer.active .context-menu-button {
- transform: scale(1);
- opacity: 1; }
+ .top-sites-list .top-site-outer:-moz-any(.active, :focus, :hover) .edit-menu {
+ opacity: 1;
+ transform: scale(1); }
+ .top-sites-list .top-site-outer:-moz-any(.active, :focus, :hover) .context-menu-button {
+ opacity: 1;
+ transform: scale(1); }
.top-sites-list .top-site-outer .tile {
- position: relative;
- height: 96px;
- width: 96px;
border-radius: 6px;
box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.1), 0 1px 4px 0 rgba(12, 12, 13, 0.1);
- color: #737373;
- font-weight: 200;
- font-size: 32px;
- text-transform: uppercase;
- display: flex;
+ height: 96px;
+ position: relative;
+ width: 96px;
align-items: center;
- justify-content: center; }
+ color: #737373;
+ display: flex;
+ font-size: 32px;
+ font-weight: 200;
+ justify-content: center;
+ text-transform: uppercase; }
.top-sites-list .top-site-outer .tile::before {
content: attr(data-fallback); }
.top-sites-list .top-site-outer.placeholder .tile {
@@ -349,43 +352,43 @@ main {
.top-sites-list .top-site-outer.placeholder .screenshot {
display: none; }
.top-sites-list .top-site-outer .screenshot {
- position: absolute;
- top: 0;
- left: 0;
- height: 100%;
- width: 100%;
background-color: #FFF;
+ background-position: top left;
+ background-size: cover;
border-radius: 6px;
box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.1);
- background-size: cover;
- background-position: top left;
+ height: 100%;
+ left: 0;
+ opacity: 0;
+ position: absolute;
+ top: 0;
transition: opacity 1s;
- opacity: 0; }
+ width: 100%; }
.top-sites-list .top-site-outer .screenshot.active {
opacity: 1; }
.top-sites-list .top-site-outer .top-site-icon {
- position: absolute;
- border-radius: 6px;
- box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.1);
+ background-color: #F9F9FA;
background-position: center center;
background-repeat: no-repeat;
- background-color: #F9F9FA; }
+ border-radius: 6px;
+ box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.1);
+ position: absolute; }
.top-sites-list .top-site-outer .rich-icon {
- top: 0;
- offset-inline-start: 0;
+ background-size: 96px;
height: 100%;
- width: 100%;
- background-size: 96px; }
+ offset-inline-start: 0;
+ top: 0;
+ width: 100%; }
.top-sites-list .top-site-outer .default-icon {
+ background-size: 32px;
bottom: -6px;
height: 42px;
offset-inline-end: -6px;
width: 42px;
- background-size: 32px;
- display: flex;
align-items: center;
- justify-content: center;
- font-size: 20px; }
+ display: flex;
+ font-size: 20px;
+ justify-content: center; }
.top-sites-list .top-site-outer .default-icon[data-fallback]::before {
content: attr(data-fallback); }
.top-sites-list .top-site-outer .title {
@@ -423,7 +426,7 @@ main {
transition-property: transform, opacity;
transition-duration: 200ms;
z-index: 1000; }
- .top-sites-list .top-site-outer .edit-menu:focus, .top-sites-list .top-site-outer .edit-menu:active {
+ .top-sites-list .top-site-outer .edit-menu:-moz-any(:active, :focus) {
transform: scale(1);
opacity: 1; }
.top-sites-list .top-site-outer .edit-menu button {
@@ -443,9 +446,6 @@ main {
border-right: 0; }
.top-sites-list .top-site-outer .edit-menu button:first-child:dir(rtl) {
border-right: 0; }
- .top-sites-list .top-site-outer:hover .edit-menu, .top-sites-list .top-site-outer:focus .edit-menu, .top-sites-list .top-site-outer.active .edit-menu {
- transform: scale(1);
- opacity: 1; }
.edit-topsites-wrapper .edit-topsites-button {
border-right: 1px solid #D7D7DB;
@@ -460,7 +460,7 @@ main {
.edit-topsites-wrapper .edit-topsites-button:dir(rtl) {
border-left: 1px solid #D7D7DB;
border-right: 0; }
- .edit-topsites-wrapper .edit-topsites-button:focus, .edit-topsites-wrapper .edit-topsites-button:active {
+ .edit-topsites-wrapper .edit-topsites-button:-moz-any(:active, :focus) {
opacity: 1; }
.edit-topsites-wrapper .edit-topsites-button button {
background: none;
@@ -499,7 +499,7 @@ main {
.edit-topsites-wrapper .show-less span {
padding-inline-start: 3px; }
-section.top-sites:not(.collapsed):hover .edit-topsites-button {
+.top-sites:not(.collapsed):hover .edit-topsites-button {
opacity: 1;
pointer-events: auto; }
@@ -564,59 +564,59 @@ section.top-sites:not(.collapsed):hover .edit-topsites-button {
transform: translateY(0); } }
.sections-list .section-list {
- margin: 0;
display: grid;
+ grid-gap: 32px;
grid-template-columns: repeat(auto-fit, 224px);
- grid-gap: 32px; }
+ margin: 0; }
@media (max-width: 544px) {
.sections-list .section-list .context-menu {
- margin-inline-start: auto;
margin-inline-end: 5px;
- offset-inline-start: auto;
- offset-inline-end: 0; } }
+ margin-inline-start: auto;
+ offset-inline-end: 0;
+ offset-inline-start: auto; } }
@media (min-width: 544px) and (max-width: 800px) {
.sections-list .section-list :nth-child(2n) .context-menu {
- margin-inline-start: auto;
margin-inline-end: 5px;
- offset-inline-start: auto;
- offset-inline-end: 0; } }
+ margin-inline-start: auto;
+ offset-inline-end: 0;
+ offset-inline-start: auto; } }
@media (min-width: 800px) and (max-width: 1248px) {
.sections-list .section-list :nth-child(3n) .context-menu {
- margin-inline-start: auto;
margin-inline-end: 5px;
- offset-inline-start: auto;
- offset-inline-end: 0; } }
+ margin-inline-start: auto;
+ offset-inline-end: 0;
+ offset-inline-start: auto; } }
.sections-list .section-empty-state {
- width: 100%;
- height: 266px;
- display: flex;
border: 1px solid #D7D7DB;
- border-radius: 3px; }
+ border-radius: 3px;
+ display: flex;
+ height: 266px;
+ width: 100%; }
.sections-list .section-empty-state .empty-state {
margin: auto;
max-width: 350px; }
.sections-list .section-empty-state .empty-state .empty-state-icon {
- background-size: 50px 50px;
- background-repeat: no-repeat;
background-position: center;
- fill: rgba(12, 12, 13, 0.6);
+ background-repeat: no-repeat;
+ background-size: 50px 50px;
-moz-context-properties: fill;
+ display: block;
+ fill: rgba(12, 12, 13, 0.6);
height: 50px;
- width: 50px;
margin: 0 auto;
- display: block; }
+ width: 50px; }
.sections-list .section-empty-state .empty-state .empty-state-message {
- margin-bottom: 0;
- font-size: 13px;
color: #737373;
+ font-size: 13px;
+ margin-bottom: 0;
text-align: center; }
.topic {
- font-size: 12px;
color: #737373;
- margin-top: 12px;
- line-height: 1.6; }
+ font-size: 12px;
+ line-height: 1.6;
+ margin-top: 12px; }
@media (min-width: 800px) {
.topic {
line-height: 16px; } }
@@ -656,27 +656,27 @@ section.top-sites:not(.collapsed):hover .edit-topsites-button {
.topic .topic-read-more:dir(rtl)::after {
transform: scaleX(-1); }
.topic::after {
- content: "";
- display: table;
- clear: both; }
+ clear: both;
+ content: '';
+ display: table; }
.search-wrapper {
cursor: default;
display: flex;
- position: relative;
+ height: 35px;
margin: 1px 1px 40px;
- width: 100%;
- height: 35px; }
+ position: relative;
+ width: 100%; }
.search-wrapper input {
- border: none;
+ border: 0;
border-radius: 3px;
box-shadow: 0 1px 4px 0 rgba(12, 12, 13, 0.1), 0 0 0 1px rgba(0, 0, 0, 0.15);
color: inherit;
+ font-size: 15px;
padding: 0;
padding-inline-end: 36px;
padding-inline-start: 35px;
- width: 100%;
- font-size: 15px; }
+ width: 100%; }
.search-wrapper:hover input {
box-shadow: 0 1px 4px 0 rgba(12, 12, 13, 0.1), 0 0 0 1px rgba(0, 0, 0, 0.25); }
.search-wrapper:active input,
@@ -684,23 +684,23 @@ section.top-sites:not(.collapsed):hover .edit-topsites-button {
box-shadow: 0 0 0 1px #0A84FF; }
.search-wrapper .search-label {
background: url("chrome://browser/skin/search-glass.svg") no-repeat 12px center/16px;
- fill: rgba(12, 12, 13, 0.4);
-moz-context-properties: fill;
- position: absolute;
- offset-inline-start: 0;
+ fill: rgba(12, 12, 13, 0.4);
height: 100%;
+ offset-inline-start: 0;
+ position: absolute;
width: 35px; }
.search-wrapper .search-button {
background: url("chrome://browser/skin/forward.svg") no-repeat center center;
- border-radius: 0 3px 3px 0;
- border: 0;
- width: 36px;
- fill: rgba(12, 12, 13, 0.4);
- -moz-context-properties: fill;
background-size: 16px 16px;
+ border: 0;
+ border-radius: 0 3px 3px 0;
+ -moz-context-properties: fill;
+ fill: rgba(12, 12, 13, 0.4);
height: 100%;
offset-inline-end: 0;
- position: absolute; }
+ position: absolute;
+ width: 36px; }
.search-wrapper .search-button:focus, .search-wrapper .search-button:hover {
background-color: rgba(12, 12, 13, 0.1);
cursor: pointer; }
@@ -713,43 +713,43 @@ section.top-sites:not(.collapsed):hover .edit-topsites-button {
transform: translateY(2px); }
.context-menu {
- display: block;
- position: absolute;
- font-size: 14px;
- box-shadow: 0 5px 10px rgba(0, 0, 0, 0.3), 0 0 0 1px rgba(0, 0, 0, 0.2);
- top: 6.75px;
- offset-inline-start: 100%;
- margin-inline-start: 5px;
- z-index: 10000;
background: #F9F9FA;
- border-radius: 5px; }
+ border-radius: 5px;
+ box-shadow: 0 5px 10px rgba(0, 0, 0, 0.3), 0 0 0 1px rgba(0, 0, 0, 0.2);
+ display: block;
+ font-size: 14px;
+ margin-inline-start: 5px;
+ offset-inline-start: 100%;
+ position: absolute;
+ top: 6.75px;
+ z-index: 10000; }
.context-menu > ul {
+ list-style: none;
margin: 0;
- padding: 5px 0;
- list-style: none; }
+ padding: 5px 0; }
.context-menu > ul > li {
margin: 0;
width: 100%; }
.context-menu > ul > li.separator {
- margin: 5px 0;
- border-bottom: 1px solid rgba(0, 0, 0, 0.2); }
+ border-bottom: 1px solid rgba(0, 0, 0, 0.2);
+ margin: 5px 0; }
.context-menu > ul > li > a {
- outline: none;
- cursor: pointer;
+ align-items: center;
color: inherit;
- white-space: nowrap;
- padding: 3px 12px;
- line-height: 16px;
+ cursor: pointer;
display: flex;
- align-items: center; }
- .context-menu > ul > li > a:hover, .context-menu > ul > li > a:focus {
+ line-height: 16px;
+ outline: none;
+ padding: 3px 12px;
+ white-space: nowrap; }
+ .context-menu > ul > li > a:-moz-any(:focus, :hover) {
background: #0060DF;
color: #FFF; }
- .context-menu > ul > li > a:hover a, .context-menu > ul > li > a:focus a {
+ .context-menu > ul > li > a:-moz-any(:focus, :hover) a {
color: #0C0C0D; }
- .context-menu > ul > li > a:hover .icon, .context-menu > ul > li > a:focus .icon {
+ .context-menu > ul > li > a:-moz-any(:focus, :hover) .icon {
fill: #FFF; }
- .context-menu > ul > li > a:hover:hover, .context-menu > ul > li > a:hover:focus, .context-menu > ul > li > a:focus:hover, .context-menu > ul > li > a:focus:focus {
+ .context-menu > ul > li > a:-moz-any(:focus, :hover):-moz-any(:focus, :hover) {
color: #FFF; }
.prefs-pane {
@@ -859,14 +859,14 @@ section.top-sites:not(.collapsed):hover .edit-topsites-button {
.prefs-pane [type='checkbox']:checked + label::after {
background: url("chrome://global/skin/in-content/check.svg") no-repeat center center;
content: '';
+ -moz-context-properties: fill, stroke;
+ fill: #0060DF;
height: 21px;
offset-inline-start: 0;
position: absolute;
+ stroke: none;
top: 0;
- width: 21px;
- -moz-context-properties: fill, stroke;
- fill: #0060DF;
- stroke: none; }
+ width: 21px; }
.prefs-pane [type='checkbox']:not(:checked) + label::after {
opacity: 0; }
.prefs-pane [type='checkbox']:checked + label::after {
@@ -882,9 +882,9 @@ section.top-sites:not(.collapsed):hover .edit-topsites-button {
border: 0;
cursor: pointer;
fill: rgba(12, 12, 13, 0.6);
+ offset-inline-end: 15px;
padding: 15px;
position: fixed;
- offset-inline-end: 15px;
top: 15px;
z-index: 12001; }
.prefs-pane-button button:hover {
@@ -893,35 +893,35 @@ section.top-sites:not(.collapsed):hover .edit-topsites-button {
background-color: #F9F9FA; }
.confirmation-dialog .modal {
- position: fixed;
- width: 400px;
- top: 20%;
+ box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.1);
left: 50%;
margin-left: -200px;
- box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.08); }
+ position: fixed;
+ top: 20%;
+ width: 400px; }
.confirmation-dialog section {
margin: 0; }
.confirmation-dialog .modal-message {
+ display: flex;
padding: 16px;
- padding-bottom: 0;
- display: flex; }
+ padding-bottom: 0; }
.confirmation-dialog .modal-message p {
margin: 0;
margin-bottom: 16px; }
.confirmation-dialog .actions {
- padding: 0px 16px 0 16px;
- border: none;
+ border: 0;
+ display: flex;
flex-wrap: nowrap;
- display: flex; }
+ padding: 0 16px; }
.confirmation-dialog .actions button {
margin-inline-end: 16px;
width: 50%; }
.confirmation-dialog .actions button.done {
- margin-inline-start: 0;
- margin-inline-end: 0; }
+ margin-inline-end: 0;
+ margin-inline-start: 0; }
.confirmation-dialog .icon {
margin-inline-end: 16px; }
@@ -945,83 +945,83 @@ section.top-sites:not(.collapsed):hover .edit-topsites-button {
.card-outer {
background: #FFF;
- display: inline-block;
- margin-inline-end: 32px;
- width: 224px;
border-radius: 3px;
+ display: inline-block;
height: 266px;
- position: relative; }
+ margin-inline-end: 32px;
+ position: relative;
+ width: 224px; }
.card-outer .context-menu-button {
- cursor: pointer;
- position: absolute;
- top: -13.5px;
- offset-inline-end: -13.5px;
- width: 27px;
- height: 27px;
+ background-clip: padding-box;
background-color: #FFF;
background-image: url("chrome://browser/skin/page-action.svg");
background-position: 55%;
- background-clip: padding-box;
border: 1px solid #B1B1B3;
border-radius: 100%;
box-shadow: 0 2px rgba(12, 12, 13, 0.1);
+ cursor: pointer;
fill: rgba(12, 12, 13, 0.8);
- transform: scale(0.25);
+ height: 27px;
+ offset-inline-end: -13.5px;
opacity: 0;
+ position: absolute;
+ top: -13.5px;
+ transform: scale(0.25);
+ transition-duration: 200ms;
transition-property: transform, opacity;
- transition-duration: 200ms; }
- .card-outer .context-menu-button:focus, .card-outer .context-menu-button:active {
- transform: scale(1);
- opacity: 1; }
+ width: 27px; }
+ .card-outer .context-menu-button:-moz-any(:active, :focus) {
+ opacity: 1;
+ transform: scale(1); }
.card-outer.placeholder {
background: transparent; }
.card-outer.placeholder .card {
box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.1); }
.card-outer .card {
- height: 100%;
border-radius: 3px;
- box-shadow: 0 1px 4px 0 rgba(12, 12, 13, 0.1); }
+ box-shadow: 0 1px 4px 0 rgba(12, 12, 13, 0.1);
+ height: 100%; }
.card-outer > a {
- display: block;
color: inherit;
+ display: block;
height: 100%;
outline: none;
position: absolute;
width: 224px; }
- .card-outer > a.active .card, .card-outer > a:focus .card {
+ .card-outer > a:-moz-any(.active, :focus) .card {
box-shadow: 0 0 0 5px #D7D7DB;
transition: box-shadow 150ms; }
- .card-outer > a.active .card-title, .card-outer > a:focus .card-title {
+ .card-outer > a:-moz-any(.active, :focus) .card-title {
color: #0060DF; }
.card-outer:-moz-any(:hover, :focus, .active):not(.placeholder) {
- outline: none;
box-shadow: 0 0 0 5px #D7D7DB;
- transition: box-shadow 150ms; }
+ transition: box-shadow 150ms;
+ outline: none; }
.card-outer:-moz-any(:hover, :focus, .active):not(.placeholder) .context-menu-button {
- transform: scale(1);
- opacity: 1; }
+ opacity: 1;
+ transform: scale(1); }
.card-outer:-moz-any(:hover, :focus, .active):not(.placeholder) .card-title {
color: #0060DF; }
.card-outer .card-preview-image-outer {
background-color: #F9F9FA;
- position: relative;
- height: 122px;
border-radius: 3px 3px 0 0;
- overflow: hidden; }
+ height: 122px;
+ overflow: hidden;
+ position: relative; }
.card-outer .card-preview-image-outer::after {
border-bottom: 1px solid rgba(0, 0, 0, 0.05);
bottom: 0;
- content: " ";
+ content: '';
position: absolute;
width: 100%; }
.card-outer .card-preview-image-outer .card-preview-image {
- width: 100%;
- height: 100%;
- background-size: cover;
background-position: center;
background-repeat: no-repeat;
+ background-size: cover;
+ height: 100%;
opacity: 0;
- transition: opacity 1s cubic-bezier(0.07, 0.95, 0, 1); }
+ transition: opacity 1s cubic-bezier(0.07, 0.95, 0, 1);
+ width: 100%; }
.card-outer .card-preview-image-outer .card-preview-image.loaded {
opacity: 1; }
.card-outer .card-details {
@@ -1029,8 +1029,8 @@ section.top-sites:not(.collapsed):hover .edit-topsites-button {
.card-outer .card-details.no-image {
padding-top: 16px; }
.card-outer .card-text {
- overflow: hidden;
- max-height: 78px; }
+ max-height: 78px;
+ overflow: hidden; }
.card-outer .card-text.no-image {
max-height: 192px; }
.card-outer .card-text.no-host-name, .card-outer .card-text.no-context {
@@ -1047,30 +1047,30 @@ section.top-sites:not(.collapsed):hover .edit-topsites-button {
.card-outer .card-host-name {
color: #737373;
font-size: 10px;
- padding-bottom: 4px;
- text-transform: uppercase;
overflow: hidden;
- text-overflow: ellipsis; }
+ padding-bottom: 4px;
+ text-overflow: ellipsis;
+ text-transform: uppercase; }
.card-outer .card-title {
- margin: 0 0 2px;
font-size: 14px;
- word-wrap: break-word;
- line-height: 19px; }
+ line-height: 19px;
+ margin: 0 0 2px;
+ word-wrap: break-word; }
.card-outer .card-description {
font-size: 12px;
+ line-height: 19px;
margin: 0;
- word-wrap: break-word;
overflow: hidden;
- line-height: 19px; }
+ word-wrap: break-word; }
.card-outer .card-context {
+ bottom: 0;
+ color: #737373;
+ display: flex;
+ font-size: 11px;
+ left: 0;
padding: 12px 16px 12px 14px;
position: absolute;
- bottom: 0;
- left: 0;
- right: 0;
- color: #737373;
- font-size: 11px;
- display: flex; }
+ right: 0; }
.card-outer .card-context-icon {
fill: rgba(12, 12, 13, 0.6);
margin-inline-end: 6px; }
@@ -1103,13 +1103,13 @@ section.top-sites:not(.collapsed):hover .edit-topsites-button {
display: none; }
@media (min-width: 544px) {
.manual-migration-container .icon {
+ align-self: center;
display: block;
fill: rgba(12, 12, 13, 0.6);
- margin-inline-end: 6px;
- align-self: center; } }
+ margin-inline-end: 6px; } }
.manual-migration-actions {
- border: none;
+ border: 0;
display: block;
flex-wrap: nowrap; }
@media (min-width: 544px) {
@@ -1131,8 +1131,8 @@ section.top-sites:not(.collapsed):hover .edit-topsites-button {
.collapsible-section .section-title .icon-arrowhead-down,
.collapsible-section .section-title .icon-arrowhead-forward {
- margin-top: -1px;
- margin-inline-start: 8px; }
+ margin-inline-start: 8px;
+ margin-top: -1px; }
.collapsible-section .section-top-bar {
position: relative; }
@@ -1142,30 +1142,36 @@ section.top-sites:not(.collapsed):hover .edit-topsites-button {
top: 0; }
.collapsible-section .section-top-bar .info-option-icon {
background-image: url("../data/content/assets/glyph-info-option-12.svg");
- background-size: 12px 12px;
- background-repeat: no-repeat;
background-position: center;
- fill: rgba(12, 12, 13, 0.6);
+ background-repeat: no-repeat;
+ background-size: 12px 12px;
-moz-context-properties: fill;
- height: 16px;
- width: 16px;
display: inline-block;
+ fill: rgba(12, 12, 13, 0.6);
+ height: 16px;
margin-bottom: -2px;
opacity: 0;
- transition: opacity 0.2s cubic-bezier(0.07, 0.95, 0, 1); }
- .collapsible-section .section-top-bar .info-option-icon:focus, .collapsible-section .section-top-bar .info-option-icon:active {
+ transition: opacity 0.2s cubic-bezier(0.07, 0.95, 0, 1);
+ width: 16px; }
+ .collapsible-section .section-top-bar .info-option-icon[aria-expanded='true'] {
+ background-color: rgba(12, 12, 13, 0.1);
+ border-radius: 1px;
+ box-shadow: 0 0 0 5px rgba(12, 12, 13, 0.1);
+ fill: rgba(12, 12, 13, 0.8); }
+ .collapsible-section .section-top-bar .info-option-icon[aria-expanded='true'] + .info-option {
+ opacity: 1;
+ transition: visibility 0.2s, opacity 0.2s cubic-bezier(0.07, 0.95, 0, 1);
+ visibility: visible; }
+ .collapsible-section .section-top-bar .info-option-icon:not([aria-expanded='true']) + .info-option {
+ pointer-events: none; }
+ .collapsible-section .section-top-bar .info-option-icon:-moz-any(:active, :focus) {
opacity: 1; }
- .collapsible-section .section-top-bar .info-option-icon[aria-expanded="true"] {
- background-color: rgba(12, 12, 13, 0.1);
- border-radius: 1px;
- box-shadow: 0 0 0 5px rgba(12, 12, 13, 0.1);
- fill: rgba(12, 12, 13, 0.8); }
.collapsible-section .section-top-bar .section-info-option .info-option {
- visibility: hidden;
opacity: 0;
- transition: visibility 0.2s, opacity 0.2s cubic-bezier(0.07, 0.95, 0, 1); }
+ transition: visibility 0.2s, opacity 0.2s cubic-bezier(0.07, 0.95, 0, 1);
+ visibility: hidden; }
.collapsible-section .section-top-bar .section-info-option .info-option::after, .collapsible-section .section-top-bar .section-info-option .info-option::before {
- content: "";
+ content: '';
offset-inline-end: 0;
position: absolute; }
.collapsible-section .section-top-bar .section-info-option .info-option::before {
@@ -1182,27 +1188,21 @@ section.top-sites:not(.collapsed):hover .edit-topsites-button {
height: 10px;
offset-inline-start: 0;
top: -10px; }
- .collapsible-section .section-top-bar .info-option-icon[aria-expanded="true"] + .info-option {
- visibility: visible;
- opacity: 1;
- transition: visibility 0.2s, opacity 0.2s cubic-bezier(0.07, 0.95, 0, 1); }
- .collapsible-section .section-top-bar .info-option-icon:not([aria-expanded="true"]) + .info-option {
- pointer-events: none; }
.collapsible-section .section-top-bar .info-option {
- z-index: 9999;
- position: absolute;
background: #FFF;
border: 1px solid #D7D7DB;
border-radius: 3px;
+ box-shadow: 0 1px 4px 0 rgba(12, 12, 13, 0.1);
font-size: 13px;
line-height: 120%;
margin-inline-end: -9px;
offset-inline-end: 0;
- top: 26px;
- width: 320px;
padding: 24px;
- box-shadow: 0 1px 4px 0 rgba(12, 12, 13, 0.1);
- -moz-user-select: none; }
+ position: absolute;
+ top: 26px;
+ -moz-user-select: none;
+ width: 320px;
+ z-index: 9999; }
.collapsible-section .section-top-bar .info-option-header {
font-size: 15px;
font-weight: 600; }
@@ -1215,8 +1215,8 @@ section.top-sites:not(.collapsed):hover .edit-topsites-button {
.collapsible-section .section-top-bar .info-option-manage {
margin-top: 24px; }
.collapsible-section .section-top-bar .info-option-manage button {
- background: none;
- border: none;
+ background: 0;
+ border: 0;
color: #0060DF;
cursor: pointer;
margin: 0;
@@ -1256,14 +1256,14 @@ section.top-sites:not(.collapsed):hover .edit-topsites-button {
color: #008EA4;
padding-left: 3px; }
.collapsible-section .section-disclaimer button {
- margin-top: 2px;
- offset-inline-end: 0;
- min-height: 26px;
- max-width: 130px;
background: #F9F9FA;
border: 1px solid #B1B1B3;
border-radius: 4px;
- cursor: pointer; }
+ cursor: pointer;
+ margin-top: 2px;
+ max-width: 130px;
+ min-height: 26px;
+ offset-inline-end: 0; }
.collapsible-section .section-disclaimer button:hover:not(.dismiss) {
box-shadow: 0 0 0 5px #D7D7DB;
transition: box-shadow 150ms; }
diff --git a/browser/extensions/activity-stream/data/content/activity-stream.bundle.js b/browser/extensions/activity-stream/data/content/activity-stream.bundle.js
index 2922c6ea1eb1..14ec5eb5457a 100644
--- a/browser/extensions/activity-stream/data/content/activity-stream.bundle.js
+++ b/browser/extensions/activity-stream/data/content/activity-stream.bundle.js
@@ -94,7 +94,7 @@ const globalImportContext = typeof Window === "undefined" ? BACKGROUND_PROCESS :
// UNINIT: "UNINIT"
// }
const actionTypes = {};
-for (const type of ["BLOCK_URL", "BOOKMARK_URL", "DELETE_BOOKMARK_BY_ID", "DELETE_HISTORY_URL", "DELETE_HISTORY_URL_CONFIRM", "DIALOG_CANCEL", "DIALOG_OPEN", "DISABLE_ONBOARDING", "INIT", "MIGRATION_CANCEL", "MIGRATION_COMPLETED", "MIGRATION_START", "NEW_TAB_INIT", "NEW_TAB_INITIAL_STATE", "NEW_TAB_LOAD", "NEW_TAB_REHYDRATED", "NEW_TAB_STATE_REQUEST", "NEW_TAB_UNLOAD", "OPEN_LINK", "OPEN_NEW_WINDOW", "OPEN_PRIVATE_WINDOW", "PAGE_PRERENDERED", "PLACES_BOOKMARK_ADDED", "PLACES_BOOKMARK_CHANGED", "PLACES_BOOKMARK_REMOVED", "PLACES_HISTORY_CLEARED", "PLACES_LINKS_DELETED", "PLACES_LINK_BLOCKED", "PREFS_INITIAL_VALUES", "PREF_CHANGED", "RICH_ICON_MISSING", "SAVE_SESSION_PERF_DATA", "SAVE_TO_POCKET", "SCREENSHOT_UPDATED", "SECTION_DEREGISTER", "SECTION_DISABLE", "SECTION_ENABLE", "SECTION_OPTIONS_CHANGED", "SECTION_REGISTER", "SECTION_UPDATE", "SECTION_UPDATE_CARD", "SETTINGS_CLOSE", "SETTINGS_OPEN", "SET_PREF", "SHOW_FIREFOX_ACCOUNTS", "SNIPPETS_DATA", "SNIPPETS_RESET", "SYSTEM_TICK", "TELEMETRY_IMPRESSION_STATS", "TELEMETRY_PERFORMANCE_EVENT", "TELEMETRY_UNDESIRED_EVENT", "TELEMETRY_USER_EVENT", "TOP_SITES_ADD", "TOP_SITES_CANCEL_EDIT", "TOP_SITES_EDIT", "TOP_SITES_PIN", "TOP_SITES_UNPIN", "TOP_SITES_UPDATED", "UNINIT"]) {
+for (const type of ["BLOCK_URL", "BOOKMARK_URL", "DELETE_BOOKMARK_BY_ID", "DELETE_HISTORY_URL", "DELETE_HISTORY_URL_CONFIRM", "DIALOG_CANCEL", "DIALOG_OPEN", "DISABLE_ONBOARDING", "INIT", "MIGRATION_CANCEL", "MIGRATION_COMPLETED", "MIGRATION_START", "NEW_TAB_INIT", "NEW_TAB_INITIAL_STATE", "NEW_TAB_LOAD", "NEW_TAB_REHYDRATED", "NEW_TAB_STATE_REQUEST", "NEW_TAB_UNLOAD", "OPEN_LINK", "OPEN_NEW_WINDOW", "OPEN_PRIVATE_WINDOW", "PAGE_PRERENDERED", "PLACES_BOOKMARK_ADDED", "PLACES_BOOKMARK_CHANGED", "PLACES_BOOKMARK_REMOVED", "PLACES_HISTORY_CLEARED", "PLACES_LINKS_DELETED", "PLACES_LINK_BLOCKED", "PREFS_INITIAL_VALUES", "PREF_CHANGED", "RICH_ICON_MISSING", "SAVE_SESSION_PERF_DATA", "SAVE_TO_POCKET", "SCREENSHOT_UPDATED", "SECTION_DEREGISTER", "SECTION_DISABLE", "SECTION_ENABLE", "SECTION_OPTIONS_CHANGED", "SECTION_REGISTER", "SECTION_UPDATE", "SECTION_UPDATE_CARD", "SETTINGS_CLOSE", "SETTINGS_OPEN", "SET_PREF", "SHOW_FIREFOX_ACCOUNTS", "SNIPPETS_BLOCKLIST_UPDATED", "SNIPPETS_DATA", "SNIPPETS_RESET", "SNIPPET_BLOCKED", "SYSTEM_TICK", "TELEMETRY_IMPRESSION_STATS", "TELEMETRY_PERFORMANCE_EVENT", "TELEMETRY_UNDESIRED_EVENT", "TELEMETRY_USER_EVENT", "TOP_SITES_ADD", "TOP_SITES_CANCEL_EDIT", "TOP_SITES_EDIT", "TOP_SITES_PIN", "TOP_SITES_UNPIN", "TOP_SITES_UPDATED", "UNINIT"]) {
actionTypes[type] = type;
}
@@ -310,27 +310,27 @@ module.exports = ReactRedux;
/* 4 */
/***/ (function(module, exports) {
-var g;
-
-// This works in non-strict mode
-g = (function() {
- return this;
-})();
-
-try {
- // This works if eval is allowed (see CSP)
- g = g || Function("return this")() || (1,eval)("this");
-} catch(e) {
- // This works if the window reference is available
- if(typeof window === "object")
- g = window;
-}
-
-// g can still be undefined, but nothing to do about it...
-// We return undefined, instead of nothing here, so it's
-// easier to handle this case. if(!global) { ...}
-
-module.exports = g;
+var g;
+
+// This works in non-strict mode
+g = (function() {
+ return this;
+})();
+
+try {
+ // This works if eval is allowed (see CSP)
+ g = g || Function("return this")() || (1,eval)("this");
+} catch(e) {
+ // This works if the window reference is available
+ if(typeof window === "object")
+ g = window;
+}
+
+// g can still be undefined, but nothing to do about it...
+// We return undefined, instead of nothing here, so it's
+// easier to handle this case. if(!global) { ...}
+
+module.exports = g;
/***/ }),
@@ -2473,11 +2473,6 @@ class Search extends React.PureComponent {
// In the future, when activity stream is default about:home, this can be renamed
window.gContentSearchController = new ContentSearchUIController(input, input.parentNode, healthReportKey, searchSource);
addEventListener("ContentSearchClient", this);
-
- // Focus the search box if we are on about:home
- if (!IS_NEWTAB) {
- input.focus();
- }
} else {
window.gContentSearchController = null;
removeEventListener("ContentSearchClient", this);
@@ -3769,8 +3764,9 @@ class SnippetsMap extends Map {
let blockList = this.blockList;
if (!blockList.includes(id)) {
blockList.push(id);
+ this._dispatch(ac.SendToMain({ type: at.SNIPPETS_BLOCKLIST_UPDATED, data: blockList }));
+ await this.set("blockList", blockList);
}
- await this.set("blockList", blockList);
}
disableOnboarding() {
@@ -3893,6 +3889,7 @@ class SnippetsProvider {
// Initialize the Snippets Map and attaches it to a global so that
// the snippet payload can interact with it.
global.gSnippetsMap = new SnippetsMap(dispatch);
+ this._onAction = this._onAction.bind(this);
}
get snippetsMap() {
@@ -3958,6 +3955,7 @@ class SnippetsProvider {
}
// Note that injecting snippets can throw if they're invalid XML.
+ // eslint-disable-next-line no-unsanitized/property
snippetsEl.innerHTML = payload;
// Scripts injected by innerHTML are inactive, so we have to relocate them
@@ -3969,6 +3967,13 @@ class SnippetsProvider {
}
}
+ _onAction(msg) {
+ if (msg.data.type === at.SNIPPET_BLOCKED) {
+ this.snippetsMap.set("blockList", msg.data.data);
+ document.getElementById("snippets-container").style.display = "none";
+ }
+ }
+
/**
* init - Fetch the snippet payload and show snippets
*
@@ -3985,6 +3990,11 @@ class SnippetsProvider {
connect: true
}, options);
+ // Add listener so we know when snippets are blocked on other pages
+ if (global.addMessageListener) {
+ global.addMessageListener("ActivityStream:MainToContent", this._onAction);
+ }
+
// TODO: Requires enabling indexedDB on newtab
// Restore the snippets map from indexedDB
if (this.connect) {
@@ -4019,6 +4029,9 @@ class SnippetsProvider {
uninit() {
window.dispatchEvent(new Event(SNIPPETS_DISABLED_EVENT));
this._forceOnboardingVisibility(false);
+ if (global.removeMessageListener) {
+ global.removeMessageListener("ActivityStream:MainToContent", this._onAction);
+ }
this.initialized = false;
}
}
diff --git a/browser/extensions/activity-stream/install.rdf.in b/browser/extensions/activity-stream/install.rdf.in
index 0c93c864ae51..e03b98cb8c22 100644
--- a/browser/extensions/activity-stream/install.rdf.in
+++ b/browser/extensions/activity-stream/install.rdf.in
@@ -8,7 +8,7 @@
2
true
false
- 2017.11.16.1254-39442ee8
+ 2017.12.02.0024-b0532674
Activity Stream
A rich visual history feed and a reimagined home page make it easier than ever to find exactly what you're looking for in Firefox.
true
diff --git a/browser/extensions/activity-stream/lib/ActivityStream.jsm b/browser/extensions/activity-stream/lib/ActivityStream.jsm
index 1de3bee7220a..bcb6bf11293d 100644
--- a/browser/extensions/activity-stream/lib/ActivityStream.jsm
+++ b/browser/extensions/activity-stream/lib/ActivityStream.jsm
@@ -41,10 +41,6 @@ const REASON_ADDON_UNINSTALL = 6;
// Configure default Activity Stream prefs with a plain `value` or a `getValue`
// that computes a value. A `value_local_dev` is used for development defaults.
const PREFS_CONFIG = new Map([
- ["aboutHome.autoFocus", {
- title: "Focus the about:home search box on load",
- value: false
- }],
["default.sites", {
title: "Comma-separated list of default top sites to fill in behind visited sites",
getValue: ({geo}) => DEFAULT_SITES.get(DEFAULT_SITES.has(geo) ? geo : "")
diff --git a/browser/extensions/activity-stream/lib/NewTabInit.jsm b/browser/extensions/activity-stream/lib/NewTabInit.jsm
index 7e5d811b23b3..ba54105c699a 100644
--- a/browser/extensions/activity-stream/lib/NewTabInit.jsm
+++ b/browser/extensions/activity-stream/lib/NewTabInit.jsm
@@ -40,13 +40,6 @@ this.NewTabInit = class NewTabInit {
if (action.data.simulated) {
this._repliedEarlyTabs.set(action.data.portID, false);
}
-
- if (action.data.url === "about:home") {
- const prefs = this.store.getState().Prefs.values;
- if (prefs["aboutHome.autoFocus"] && prefs.showSearch) {
- action.data.browser.focus();
- }
- }
break;
case at.NEW_TAB_UNLOAD:
// Clean up for any tab (no-op if not an early tab)
diff --git a/browser/extensions/activity-stream/lib/SnippetsFeed.jsm b/browser/extensions/activity-stream/lib/SnippetsFeed.jsm
index f1ceb43d1100..01ebb3185e56 100644
--- a/browser/extensions/activity-stream/lib/SnippetsFeed.jsm
+++ b/browser/extensions/activity-stream/lib/SnippetsFeed.jsm
@@ -143,6 +143,9 @@ this.SnippetsFeed = class SnippetsFeed {
case at.SHOW_FIREFOX_ACCOUNTS:
this.showFirefoxAccounts(action._target.browser);
break;
+ case at.SNIPPETS_BLOCKLIST_UPDATED:
+ this.store.dispatch(ac.BroadcastToContent({type: at.SNIPPET_BLOCKED, data: action.data}));
+ break;
}
}
};
diff --git a/browser/extensions/activity-stream/prerendered/locales/ast/activity-stream-prerendered.html b/browser/extensions/activity-stream/prerendered/locales/ast/activity-stream-prerendered.html
index 5061d3a4c2db..f37338c9d97b 100644
--- a/browser/extensions/activity-stream/prerendered/locales/ast/activity-stream-prerendered.html
+++ b/browser/extensions/activity-stream/prerendered/locales/ast/activity-stream-prerendered.html
@@ -8,7 +8,7 @@
- Guetar na web Guetar
Sitios destacaos Access the websites you visit most.
New Tab Preferences
+ Guetar na web Guetar
Más visitaos Acceder a les webs que más visites.
Preferencies de Llingüeta nueva
diff --git a/browser/extensions/activity-stream/prerendered/locales/ast/activity-stream-strings.js b/browser/extensions/activity-stream/prerendered/locales/ast/activity-stream-strings.js
index c6c64b841228..23c15c855b05 100644
--- a/browser/extensions/activity-stream/prerendered/locales/ast/activity-stream-strings.js
+++ b/browser/extensions/activity-stream/prerendered/locales/ast/activity-stream-strings.js
@@ -2,12 +2,12 @@
window.gActivityStreamStrings = {
"newtab_page_title": "Llingüeta nueva",
"default_label_loading": "Cargando…",
- "header_top_sites": "Sitios destacaos",
+ "header_top_sites": "Más visitaos",
"header_stories": "Histories destacaes",
- "header_highlights": "Los destacaos",
+ "header_highlights": "Destacaos",
"header_visit_again": "Visitar de nueves",
"header_bookmarks": "Marcadores recientes",
- "header_recommended_by": "Recommended by {provider}",
+ "header_recommended_by": "Recomendáu por {provider}",
"header_bookmarks_placeholder": "Entá nun tienes dengún marcador.",
"header_stories_from": "de",
"type_label_visited": "Visitóse",
@@ -39,60 +39,60 @@ window.gActivityStreamStrings = {
"section_info_send_feedback": "Unviar comentarios",
"section_info_privacy_notice": "Nota de privacidá",
"section_disclaimer_topstories": "The most interesting stories on the web, selected based on what you read. From Pocket, now part of Mozilla.",
- "section_disclaimer_topstories_linktext": "Learn how it works.",
- "section_disclaimer_topstories_buttontext": "Okay, got it",
+ "section_disclaimer_topstories_linktext": "Deprendi cómo furrula.",
+ "section_disclaimer_topstories_buttontext": "Val, píllolo",
"welcome_title": "Afáyate na llingüeta nueva",
"welcome_body": "Firefox usará esti espaciu p'amosate los marcadores, artículos, vídeos y páxines más relevantes que visitares apocayá, asina pues volver a ellos de mou cenciellu.",
- "welcome_label": "Identifying your Highlights",
+ "welcome_label": "Identificando los tos destacaos",
"time_label_less_than_minute": "<1m",
"time_label_minute": "{number}m",
"time_label_hour": "{number}h",
"time_label_day": "{number}d",
- "settings_pane_button_label": "Customize your New Tab page",
- "settings_pane_header": "New Tab Preferences",
- "settings_pane_body2": "Choose what you see on this page.",
+ "settings_pane_button_label": "Personalizar páxina Llingüeta nueva",
+ "settings_pane_header": "Preferencies de Llingüeta nueva",
+ "settings_pane_body2": "Escueyi qué quies ver nesta páxina",
"settings_pane_search_header": "Search",
- "settings_pane_search_body": "Search the Web from your new tab.",
- "settings_pane_topsites_header": "Top Sites",
- "settings_pane_topsites_body": "Access the websites you visit most.",
- "settings_pane_topsites_options_showmore": "Show two rows",
- "settings_pane_bookmarks_header": "Recent Bookmarks",
- "settings_pane_bookmarks_body": "Your newly created bookmarks in one handy location.",
- "settings_pane_visit_again_header": "Visit Again",
- "settings_pane_visit_again_body": "Firefox will show you parts of your browsing history that you might want to remember or get back to.",
- "settings_pane_highlights_header": "Highlights",
- "settings_pane_highlights_body2": "Find your way back to interesting things you’ve recently visited or bookmarked.",
- "settings_pane_highlights_options_bookmarks": "Bookmarks",
- "settings_pane_highlights_options_visited": "Visited Sites",
- "settings_pane_snippets_header": "Snippets",
- "settings_pane_snippets_body": "Read short and sweet updates from Mozilla about Firefox, internet culture, and the occasional random meme.",
+ "settings_pane_search_body": "Restolar na Web dende la nueva llingüeta",
+ "settings_pane_topsites_header": "Más visitaos",
+ "settings_pane_topsites_body": "Acceder a les webs que más visites.",
+ "settings_pane_topsites_options_showmore": "Amosar dos fileres",
+ "settings_pane_bookmarks_header": "Marcadores recientes",
+ "settings_pane_bookmarks_body": "Los marcadores recién fechos, nun llugar accesible.",
+ "settings_pane_visit_again_header": "Visitar de nueves",
+ "settings_pane_visit_again_body": "Firefox va amosate partes del to historial de navegación que a lo meyor prestaríate remembrar o volver visitar.",
+ "settings_pane_highlights_header": "Destacaos",
+ "settings_pane_highlights_body2": "Atopa otra vegada les coses interesantes que yá visitaras o marcaras.",
+ "settings_pane_highlights_options_bookmarks": "Marcadores",
+ "settings_pane_highlights_options_visited": "Sitios visitaos",
+ "settings_pane_snippets_header": "Retayos",
+ "settings_pane_snippets_body": "Llei anovamientos curtios de Mozilla tocante a Firefox, la cultura d'internet y un meme de xemes en cuandu.",
"settings_pane_done_button": "Fecho",
- "settings_pane_topstories_options_sponsored": "Show Sponsored Stories",
- "edit_topsites_button_text": "Edit",
- "edit_topsites_button_label": "Customize your Top Sites section",
+ "settings_pane_topstories_options_sponsored": "Amosar hestories patrocinaes",
+ "edit_topsites_button_text": "Editar",
+ "edit_topsites_button_label": "Personalizar la seición de Más visitaos",
"edit_topsites_showmore_button": "Amosar más",
- "edit_topsites_showless_button": "Show Fewer",
+ "edit_topsites_showless_button": "Amosar menos",
"edit_topsites_done_button": "Fecho",
- "edit_topsites_pin_button": "Pin this site",
- "edit_topsites_unpin_button": "Unpin this site",
- "edit_topsites_edit_button": "Edit this site",
- "edit_topsites_dismiss_button": "Dismiss this site",
- "edit_topsites_add_button": "Add",
- "topsites_form_add_header": "New Top Site",
- "topsites_form_edit_header": "Edit Top Site",
- "topsites_form_title_placeholder": "Enter a title",
- "topsites_form_url_placeholder": "Type or paste a URL",
+ "edit_topsites_pin_button": "Fixar esti sitiu",
+ "edit_topsites_unpin_button": "Desfixar esti sitiu",
+ "edit_topsites_edit_button": "Editar esti sitiu",
+ "edit_topsites_dismiss_button": "Escartar esti sitiu",
+ "edit_topsites_add_button": "Amestar",
+ "topsites_form_add_header": "Nuevu Sitiu más visitáu",
+ "topsites_form_edit_header": "Editar Sitiu más visitáu",
+ "topsites_form_title_placeholder": "Introducir títulu",
+ "topsites_form_url_placeholder": "Escribi o apega una URL",
"topsites_form_add_button": "Amestar",
"topsites_form_save_button": "Guardar",
"topsites_form_cancel_button": "Encaboxar",
- "topsites_form_url_validation": "Valid URL required",
+ "topsites_form_url_validation": "Ríquese una URL válida",
"pocket_read_more": "Temes populares:",
"pocket_read_even_more": "Ver más histories",
"pocket_feedback_header": "The best of the web, curated by over 25 million people.",
"pocket_description": "Discover high-quality content you might otherwise miss, with help from Pocket, now part of Mozilla.",
"highlights_empty_state": "Start browsing, and we’ll show some of the great articles, videos, and other pages you’ve recently visited or bookmarked here.",
"topstories_empty_state": "You’ve caught up. Check back later for more top stories from {provider}. Can’t wait? Select a popular topic to find more great stories from around the web.",
- "manual_migration_explanation2": "Try Firefox with the bookmarks, history and passwords from another browser.",
- "manual_migration_cancel_button": "No Thanks",
- "manual_migration_import_button": "Import Now"
+ "manual_migration_explanation2": "Prueba Firefox colos marcadores, hestorial y contraseñes d'otru restolador.",
+ "manual_migration_cancel_button": "Non, gracies",
+ "manual_migration_import_button": "Importar agora"
};
diff --git a/browser/extensions/activity-stream/prerendered/locales/be/activity-stream-strings.js b/browser/extensions/activity-stream/prerendered/locales/be/activity-stream-strings.js
index 3fb2758837ab..616b6f31fed0 100644
--- a/browser/extensions/activity-stream/prerendered/locales/be/activity-stream-strings.js
+++ b/browser/extensions/activity-stream/prerendered/locales/be/activity-stream-strings.js
@@ -38,9 +38,9 @@ window.gActivityStreamStrings = {
"section_info_option": "Звесткі",
"section_info_send_feedback": "Даслаць водгук",
"section_info_privacy_notice": "Паведамленне аб прыватнасці",
- "section_disclaimer_topstories": "The most interesting stories on the web, selected based on what you read. From Pocket, now part of Mozilla.",
- "section_disclaimer_topstories_linktext": "Learn how it works.",
- "section_disclaimer_topstories_buttontext": "Okay, got it",
+ "section_disclaimer_topstories": "Самыя цікавыя гісторыі з інтэрнэту на аснове таго, што вы чытаеце. Падборка ад Pocket, які цяпер частка Mozilla.",
+ "section_disclaimer_topstories_linktext": "Даведайцеся, як гэта працуе.",
+ "section_disclaimer_topstories_buttontext": "Зразумела",
"welcome_title": "Калі ласка ў новую картку",
"welcome_body": "Firefox будзе выкарыстоўваць гэта месца, каб адлюстроўваць самыя актуальныя закладкі, артыкулы, відэа і старонкі, якія вы нядаўна наведалі, каб вы змаглі лёгка трапіць на іх зноў.",
"welcome_label": "Вызначэнне вашага выбранага",
@@ -67,7 +67,7 @@ window.gActivityStreamStrings = {
"settings_pane_snippets_header": "Урыўкі",
"settings_pane_snippets_body": "Чытайце кароткія і радасныя навіны ад Mozilla аб Firefox, інтэрнэт-культуру і выпадковыя мемы.",
"settings_pane_done_button": "Гатова",
- "settings_pane_topstories_options_sponsored": "Show Sponsored Stories",
+ "settings_pane_topstories_options_sponsored": "Паказаць артыкулы ад спонсараў",
"edit_topsites_button_text": "Правіць",
"edit_topsites_button_label": "Наладзіць раздзел папулярных сайтаў",
"edit_topsites_showmore_button": "Паказаць больш",
diff --git a/browser/extensions/activity-stream/prerendered/locales/bn-BD/activity-stream-strings.js b/browser/extensions/activity-stream/prerendered/locales/bn-BD/activity-stream-strings.js
index 7b87a2d5cdb0..6d4ec2e2727c 100644
--- a/browser/extensions/activity-stream/prerendered/locales/bn-BD/activity-stream-strings.js
+++ b/browser/extensions/activity-stream/prerendered/locales/bn-BD/activity-stream-strings.js
@@ -38,9 +38,9 @@ window.gActivityStreamStrings = {
"section_info_option": "তথ্য",
"section_info_send_feedback": "মতামত পাঠান",
"section_info_privacy_notice": "গোপনীয়তা বিজ্ঞপ্তি",
- "section_disclaimer_topstories": "The most interesting stories on the web, selected based on what you read. From Pocket, now part of Mozilla.",
- "section_disclaimer_topstories_linktext": "Learn how it works.",
- "section_disclaimer_topstories_buttontext": "Okay, got it",
+ "section_disclaimer_topstories": "মজার মজার সব গল্প নির্বাচিত হয়েছে, আপনি যেমনটা পড়েন। Pocket এখন থেকে Mozilla এর অংশ।",
+ "section_disclaimer_topstories_linktext": "কিভাবে কাজ করে জানুন।",
+ "section_disclaimer_topstories_buttontext": "ঠিক আছে, বুঝেছি",
"welcome_title": "নতুন ট্যাবে আপনাকে স্বাগতম",
"welcome_body": "আপনার সাথে মিলে এমন বুর্কমার্ক, নিবন্ধ, ভিডিও এবং পাতা যেগুলো আপনি সম্প্রতি ভ্রমণ করেছে তা Firefox এই জায়গায় দেখাবে, যাতে আপনি সেগুলো দ্রুত খুঁজে পান।",
"welcome_label": "আপনার হাইলাইট সমূহ চিহ্নিত করুন",
@@ -67,7 +67,7 @@ window.gActivityStreamStrings = {
"settings_pane_snippets_header": "টুকিটাকি",
"settings_pane_snippets_body": "Mozilla থেকে Firefox, ইন্টারনেট সংস্কৃতি, এবং মাঝে মাঝে উদ্দেশ্যহীন মেমে সম্পর্কে ছোট এবং মিষ্টি আপডেটগুলি পড়ুন।",
"settings_pane_done_button": "হয়েছে",
- "settings_pane_topstories_options_sponsored": "Show Sponsored Stories",
+ "settings_pane_topstories_options_sponsored": "বিজ্ঞাপনী গল্প দেখাও",
"edit_topsites_button_text": "সম্পাদনা",
"edit_topsites_button_label": "আপনার টপ সাইট সেকশন কাস্টমাইজ করুন",
"edit_topsites_showmore_button": "আরও দেখান",
diff --git a/browser/extensions/activity-stream/prerendered/locales/bn-IN/activity-stream-strings.js b/browser/extensions/activity-stream/prerendered/locales/bn-IN/activity-stream-strings.js
index 5707c1becb82..fd83b9a9c75f 100644
--- a/browser/extensions/activity-stream/prerendered/locales/bn-IN/activity-stream-strings.js
+++ b/browser/extensions/activity-stream/prerendered/locales/bn-IN/activity-stream-strings.js
@@ -38,9 +38,9 @@ window.gActivityStreamStrings = {
"section_info_option": "তথ্য",
"section_info_send_feedback": "মতামত পাঠান",
"section_info_privacy_notice": "গোপনীয়তা বিজ্ঞপ্তি",
- "section_disclaimer_topstories": "The most interesting stories on the web, selected based on what you read. From Pocket, now part of Mozilla.",
- "section_disclaimer_topstories_linktext": "Learn how it works.",
- "section_disclaimer_topstories_buttontext": "Okay, got it",
+ "section_disclaimer_topstories": "মজার মজার সব গল্প নির্বাচিত হয়েছে, আপনি যেমনটা পড়েন। Pocket এখন থেকে Mozilla এর অংশ।",
+ "section_disclaimer_topstories_linktext": "কিভাবে কাজ করে জানুন।",
+ "section_disclaimer_topstories_buttontext": "ঠিক আছে, বুঝেছি",
"welcome_title": "নতুন ট্যাবে স্বাগতম",
"welcome_body": "আপনার সাথে মিলে এমন বুর্কমার্ক, নিবন্ধ, ভিডিও এবং পাতা যেগুলো আপনি সম্প্রতি ভ্রমণ করেছে তা Firefox এই জায়গায় দেখাবে, যাতে আপনি সেগুলো দ্রুত খুঁজে পান।",
"welcome_label": "আপনার হাইলাইট সমূহ চিহ্নিত করা হচ্ছে",
@@ -67,7 +67,7 @@ window.gActivityStreamStrings = {
"settings_pane_snippets_header": "টুকিটাকি",
"settings_pane_snippets_body": "Mozilla থেকে Firefox, ইন্টারনেট সংস্কৃতি, এবং মাঝে মাঝে উদ্দেশ্যহীন মেমে সম্পর্কে ছোট এবং মিষ্টি আপডেটগুলি পড়ুন।",
"settings_pane_done_button": "হয়েছে",
- "settings_pane_topstories_options_sponsored": "Show Sponsored Stories",
+ "settings_pane_topstories_options_sponsored": "বিজ্ঞাপনী গল্প দেখাও",
"edit_topsites_button_text": "সম্পাদনা",
"edit_topsites_button_label": "আপনার শীর্ষ সাইট সেকশন কাস্টমাইজ করুন",
"edit_topsites_showmore_button": "আরও দেখান",
diff --git a/browser/extensions/activity-stream/prerendered/locales/es-AR/activity-stream-strings.js b/browser/extensions/activity-stream/prerendered/locales/es-AR/activity-stream-strings.js
index f0a78f75cbbb..d842f4e0d6c2 100644
--- a/browser/extensions/activity-stream/prerendered/locales/es-AR/activity-stream-strings.js
+++ b/browser/extensions/activity-stream/prerendered/locales/es-AR/activity-stream-strings.js
@@ -38,9 +38,9 @@ window.gActivityStreamStrings = {
"section_info_option": "Información",
"section_info_send_feedback": "Enviar opinión",
"section_info_privacy_notice": "Nota de privacidad",
- "section_disclaimer_topstories": "Las más interesantes historias en la web, seleccionadas basándonos en los que lees. Desde Pocket, ahora parte de Mozilla.",
- "section_disclaimer_topstories_linktext": "Saber como trabaja.",
- "section_disclaimer_topstories_buttontext": "Está bien, lo entiendo",
+ "section_disclaimer_topstories": "Las historias más interesantes en la web, seleccionadas en base a lo que lees. Gracias a Pocket, ahora parte de Mozilla.",
+ "section_disclaimer_topstories_linktext": "Aprendé cómo funciona.",
+ "section_disclaimer_topstories_buttontext": "Listo, lo entendí",
"welcome_title": "Bienvenido a una nueva pestaña",
"welcome_body": "Firefox usará este espacio para mostrar sus marcadores, artículos, videos y páginas más relevantes que se hayan visitado para poder volver más fácilmente.",
"welcome_label": "Identificar los destacados",
diff --git a/browser/extensions/activity-stream/prerendered/locales/et/activity-stream-strings.js b/browser/extensions/activity-stream/prerendered/locales/et/activity-stream-strings.js
index 6b3cf4458837..8ebfc9254838 100644
--- a/browser/extensions/activity-stream/prerendered/locales/et/activity-stream-strings.js
+++ b/browser/extensions/activity-stream/prerendered/locales/et/activity-stream-strings.js
@@ -39,8 +39,8 @@ window.gActivityStreamStrings = {
"section_info_send_feedback": "Saada tagasisidet",
"section_info_privacy_notice": "Privaatsusreeglid",
"section_disclaimer_topstories": "The most interesting stories on the web, selected based on what you read. From Pocket, now part of Mozilla.",
- "section_disclaimer_topstories_linktext": "Learn how it works.",
- "section_disclaimer_topstories_buttontext": "Okay, got it",
+ "section_disclaimer_topstories_linktext": "Vaata, kuidas see töötab.",
+ "section_disclaimer_topstories_buttontext": "Olgu, sain aru",
"welcome_title": "Tere tulemast uuele kaardile",
"welcome_body": "Firefox kasutab seda lehte, et kuvada sulle kõige olulisemaid järjehoidjaid, artikleid, videoid ja lehti, mida oled hiljuti külastanud, nii et pääseksid kergelt nende juurde tagasi.",
"welcome_label": "Esiletõstetava sisu tuvastamine",
diff --git a/browser/extensions/activity-stream/prerendered/locales/fi/activity-stream-strings.js b/browser/extensions/activity-stream/prerendered/locales/fi/activity-stream-strings.js
index 9655ea67da64..b4466959ba41 100644
--- a/browser/extensions/activity-stream/prerendered/locales/fi/activity-stream-strings.js
+++ b/browser/extensions/activity-stream/prerendered/locales/fi/activity-stream-strings.js
@@ -38,9 +38,9 @@ window.gActivityStreamStrings = {
"section_info_option": "Tietoa",
"section_info_send_feedback": "Anna palautetta",
"section_info_privacy_notice": "Tietosuojakäytäntö",
- "section_disclaimer_topstories": "The most interesting stories on the web, selected based on what you read. From Pocket, now part of Mozilla.",
- "section_disclaimer_topstories_linktext": "Learn how it works.",
- "section_disclaimer_topstories_buttontext": "Okay, got it",
+ "section_disclaimer_topstories": "Verkon kiinnostavimmat jutut, lukemasi perusteella valittuna. Pocketilta, joka on nyt osa Mozillaa.",
+ "section_disclaimer_topstories_linktext": "Lue, miten tämä toimii.",
+ "section_disclaimer_topstories_buttontext": "Selvä",
"welcome_title": "Tervetuloa uuteen välilehteen",
"welcome_body": "Firefox käyttää tätä tilaa näyttämään olennaisimmat kirjanmerkit, artikkelit, videot ja sivut, joita olet katsellut, jotta pääset niihin takaisin nopeasti.",
"welcome_label": "Tunnistetaan nostojasi",
@@ -64,10 +64,10 @@ window.gActivityStreamStrings = {
"settings_pane_highlights_body2": "Löydä tiesi takaisin kiinnostaviin juttuihin, joissa olet käynyt tai jotka olet lisännyt kirjanmerkkeihin viime aikoina.",
"settings_pane_highlights_options_bookmarks": "Kirjanmerkit",
"settings_pane_highlights_options_visited": "Vieraillut sivustot",
- "settings_pane_snippets_header": "Snippets",
- "settings_pane_snippets_body": "Read short and sweet updates from Mozilla about Firefox, internet culture, and the occasional random meme.",
+ "settings_pane_snippets_header": "Tiedonmuruset",
+ "settings_pane_snippets_body": "Lue Mozillan lyhyitä päivityksiä liittyen Firefoxiin, internetkulttuuriin ja satunnaisiin meemeihin.",
"settings_pane_done_button": "Valmis",
- "settings_pane_topstories_options_sponsored": "Show Sponsored Stories",
+ "settings_pane_topstories_options_sponsored": "Näytä sponsoroidut jutut",
"edit_topsites_button_text": "Muokkaa",
"edit_topsites_button_label": "Muokkaa Ykkössivustot-osiota",
"edit_topsites_showmore_button": "Näytä enemmän",
@@ -89,10 +89,10 @@ window.gActivityStreamStrings = {
"pocket_read_more": "Suositut aiheet:",
"pocket_read_even_more": "Katso lisää juttuja",
"pocket_feedback_header": "Netin parhaat palat, valikoitu yli 25 miljoonan ihmisen voimin.",
- "pocket_description": "Discover high-quality content you might otherwise miss, with help from Pocket, now part of Mozilla.",
- "highlights_empty_state": "Start browsing, and we’ll show some of the great articles, videos, and other pages you’ve recently visited or bookmarked here.",
+ "pocket_description": "Löydä laadukasta sisältöä, josta olisit muutoin ehkä jäänyt paitsi. Pocketilta, joka on nyt osa Mozillaa.",
+ "highlights_empty_state": "Ala selata, niin tässä alkaa näkyä hyviä juttuja, videoita ja muita sivuja, joilla olet käynyt hiljattain tai jotka olet lisännyt kirjanmerkkeihin.",
"topstories_empty_state": "Ei enempää suosituksia juuri nyt. Katso myöhemmin uudestaan lisää ykkösjuttuja lähteestä {provider}. Etkö malta odottaa? Valitse suosittu aihe ja löydä lisää hyviä juttuja ympäri verkkoa.",
- "manual_migration_explanation2": "Try Firefox with the bookmarks, history and passwords from another browser.",
+ "manual_migration_explanation2": "Kokeile Firefoxia toisesta selaimesta tuotujen kirjanmerkkien, historian ja salasanojen kanssa.",
"manual_migration_cancel_button": "Ei kiitos",
"manual_migration_import_button": "Tuo nyt"
};
diff --git a/browser/extensions/activity-stream/prerendered/locales/fy-NL/activity-stream-strings.js b/browser/extensions/activity-stream/prerendered/locales/fy-NL/activity-stream-strings.js
index f398d09d7d90..bfc0ac959d4f 100644
--- a/browser/extensions/activity-stream/prerendered/locales/fy-NL/activity-stream-strings.js
+++ b/browser/extensions/activity-stream/prerendered/locales/fy-NL/activity-stream-strings.js
@@ -38,9 +38,9 @@ window.gActivityStreamStrings = {
"section_info_option": "Ynfo",
"section_info_send_feedback": "Kommentaar ferstjoere",
"section_info_privacy_notice": "Privacyferklearring",
- "section_disclaimer_topstories": "The most interesting stories on the web, selected based on what you read. From Pocket, now part of Mozilla.",
- "section_disclaimer_topstories_linktext": "Learn how it works.",
- "section_disclaimer_topstories_buttontext": "Okay, got it",
+ "section_disclaimer_topstories": "De meast ynteressante ferhalen op it web, selektearre op basis fan wat jo lêzen hawwe. Fan Pocket, no ûnderdiel fan Mozilla.",
+ "section_disclaimer_topstories_linktext": "Lês hoe't it wurket.",
+ "section_disclaimer_topstories_buttontext": "Oké, begrepen",
"welcome_title": "Wolkom by it nije ljepblêd",
"welcome_body": "Firefox brûkt dizze romte om jo meast relevante blêdwizers, artikelen, fideo’s en siden dy't jo koartlyn besocht hawwe wer te jaan, sadat jo dizze ienfâldichwei weromfine kinne.",
"welcome_label": "Jo hichtepunten oantsjutte",
@@ -67,7 +67,7 @@ window.gActivityStreamStrings = {
"settings_pane_snippets_header": "Koarte ynformaasje",
"settings_pane_snippets_body": "Lês koart nijs fan Mozilla oer Firefox, ynternetkultuer en somtiden in meme.",
"settings_pane_done_button": "Dien",
- "settings_pane_topstories_options_sponsored": "Show Sponsored Stories",
+ "settings_pane_topstories_options_sponsored": "Sponsore ferhalen toane",
"edit_topsites_button_text": "Bewurkje",
"edit_topsites_button_label": "Jo seksje Topwebsites oanpasse",
"edit_topsites_showmore_button": "Mear toane",
diff --git a/browser/extensions/activity-stream/prerendered/locales/gu-IN/activity-stream-strings.js b/browser/extensions/activity-stream/prerendered/locales/gu-IN/activity-stream-strings.js
index cddf8ea1e3b4..0ddc6db992d1 100644
--- a/browser/extensions/activity-stream/prerendered/locales/gu-IN/activity-stream-strings.js
+++ b/browser/extensions/activity-stream/prerendered/locales/gu-IN/activity-stream-strings.js
@@ -38,9 +38,9 @@ window.gActivityStreamStrings = {
"section_info_option": "માહિતી",
"section_info_send_feedback": "પ્રતિસાદ મોકલ",
"section_info_privacy_notice": "ગોપનીયતા સૂચના",
- "section_disclaimer_topstories": "The most interesting stories on the web, selected based on what you read. From Pocket, now part of Mozilla.",
- "section_disclaimer_topstories_linktext": "Learn how it works.",
- "section_disclaimer_topstories_buttontext": "Okay, got it",
+ "section_disclaimer_topstories": "વેબ પરની સૌથી રસપ્રદ વાર્તાઓ, તમે જે વાંચો છો તેના આધારે પસંદ કરેલ છે. Pocket થી, હવે Mozilla નો ભાગ.",
+ "section_disclaimer_topstories_linktext": "તે કેવી રીતે કાર્ય કરે છે તે જાણો.",
+ "section_disclaimer_topstories_buttontext": "ઠીક છે, સમજાઇ ગયું",
"welcome_title": "નવી વિન્ડોમાં આપનું સ્વાગત છે",
"welcome_body": "ફાયરફોક્સ, તમારા સૌથી સંબંધિત બુકમાર્ક્સ, લેખો, વિડિઓઝ, અને પૃષ્ઠો જે તમે તાજેતરમાં મુલાકાત લીધી એ બતાવવા માટે આ જગ્યાનો ઉપયોગ કરશે જેથી તમે પાછા તેમને સરળતાથી મેળવી શકો છો.",
"welcome_label": "તમારા હાઇલાઇટ્સ ઓળખવા",
@@ -67,7 +67,7 @@ window.gActivityStreamStrings = {
"settings_pane_snippets_header": "જાણકારી આપનારા ઉતારા ક કાપલીઓ",
"settings_pane_snippets_body": "ટૂંકી અને મીઠી સુધારાઓ વાંચો મોઝિલ્લાથી ફાયરફોક્સ વિશે, ઇન્ટરનેટ સંસ્કૃતિ અને પ્રસંગોપાત ફાવે તેમ મેમે વિશે.",
"settings_pane_done_button": "પૂરું",
- "settings_pane_topstories_options_sponsored": "Show Sponsored Stories",
+ "settings_pane_topstories_options_sponsored": "પ્રાયોજિત વાર્તાઓ બતાવો",
"edit_topsites_button_text": "ફેરફાર કરો",
"edit_topsites_button_label": "તમારા ટોચના સાઇટ્સ વિભાગને કસ્ટમાઇઝ કરો",
"edit_topsites_showmore_button": "વધારે બતાવો",
diff --git a/browser/extensions/activity-stream/prerendered/locales/it/activity-stream-strings.js b/browser/extensions/activity-stream/prerendered/locales/it/activity-stream-strings.js
index 5ade5229486e..4a76c3d7ce30 100644
--- a/browser/extensions/activity-stream/prerendered/locales/it/activity-stream-strings.js
+++ b/browser/extensions/activity-stream/prerendered/locales/it/activity-stream-strings.js
@@ -38,9 +38,9 @@ window.gActivityStreamStrings = {
"section_info_option": "Info",
"section_info_send_feedback": "Invia feedback",
"section_info_privacy_notice": "Informativa sulla privacy",
- "section_disclaimer_topstories": "The most interesting stories on the web, selected based on what you read. From Pocket, now part of Mozilla.",
- "section_disclaimer_topstories_linktext": "Learn how it works.",
- "section_disclaimer_topstories_buttontext": "Okay, got it",
+ "section_disclaimer_topstories": "Le storie più interessanti del Web, selezionate in base alle tue letture. Direttamente da Pocket, ora parte del gruppo Mozilla.",
+ "section_disclaimer_topstories_linktext": "Scopri come funziona.",
+ "section_disclaimer_topstories_buttontext": "Ho capito.",
"welcome_title": "Benvenuto nella nuova scheda",
"welcome_body": "Firefox utilizzerà questo spazio per visualizzare gli elementi più significativi, come segnalibri, articoli, video e pagine visitate di recente, in modo che siano sempre facili da raggiungere.",
"welcome_label": "Identificazione elementi in evidenza…",
@@ -67,7 +67,7 @@ window.gActivityStreamStrings = {
"settings_pane_snippets_header": "Snippet",
"settings_pane_snippets_body": "Brevi notizie direttamente da Mozilla a proposito di Firefox, Internet, senza dimenticare qualche meme di tanto in tanto.",
"settings_pane_done_button": "Fatto",
- "settings_pane_topstories_options_sponsored": "Show Sponsored Stories",
+ "settings_pane_topstories_options_sponsored": "Visualizza articoli sponsorizzati",
"edit_topsites_button_text": "Modifica",
"edit_topsites_button_label": "Personalizza la sezione Siti principali",
"edit_topsites_showmore_button": "Visualizza altri",
diff --git a/browser/extensions/activity-stream/prerendered/locales/ka/activity-stream-strings.js b/browser/extensions/activity-stream/prerendered/locales/ka/activity-stream-strings.js
index d7707fb47e4c..5f718adb1fb2 100644
--- a/browser/extensions/activity-stream/prerendered/locales/ka/activity-stream-strings.js
+++ b/browser/extensions/activity-stream/prerendered/locales/ka/activity-stream-strings.js
@@ -8,7 +8,7 @@ window.gActivityStreamStrings = {
"header_visit_again": "ხელახლა ნახვა",
"header_bookmarks": "ბოლოს ჩანიშნულები",
"header_recommended_by": "რეკომენდებულია {provider}-ის მიერ",
- "header_bookmarks_placeholder": "სანიშნეები ჯერ არაა დამატებული.",
+ "header_bookmarks_placeholder": "სანიშნები ჯერ არაა დამატებული.",
"header_stories_from": "-იდან",
"type_label_visited": "მონახულებული",
"type_label_bookmarked": "ჩანიშნული",
@@ -18,12 +18,12 @@ window.gActivityStreamStrings = {
"type_label_topic": "თემა",
"type_label_now": "ახლა",
"menu_action_bookmark": "ჩანიშვნა",
- "menu_action_remove_bookmark": "სანიშნეებიდან ამოღება",
+ "menu_action_remove_bookmark": "სანიშნებიდან ამოღება",
"menu_action_copy_address": "მისამართის დაკოპირება",
"menu_action_email_link": "ბმულის გაგზავნა…",
"menu_action_open_new_window": "ახალ ფანჯარაში გახსნა",
"menu_action_open_private_window": "ახალ პირად ფანჯარაში გახსნა",
- "menu_action_dismiss": "დახურვა",
+ "menu_action_dismiss": "დამალვა",
"menu_action_delete": "ისტორიიდან ამოშლა",
"menu_action_pin": "მიმაგრება",
"menu_action_unpin": "მოხსნა",
@@ -42,7 +42,7 @@ window.gActivityStreamStrings = {
"section_disclaimer_topstories_linktext": "ნახეთ, როგორ მუშაობს.",
"section_disclaimer_topstories_buttontext": "კარგი, გასაგებია",
"welcome_title": "მოგესალმებით ახალ ჩანართზე",
- "welcome_body": "Firefox ამ სივრცეს გამოიყენებს თქვენთვის ყველაზე საჭირო სანიშნეების, სტატიების, ვიდეოებისა და ბოლოს მონახულებული გვერდებისთვის, რომ ადვილად შეძლოთ მათზე დაბრუნება.",
+ "welcome_body": "Firefox ამ სივრცეს გამოიყენებს თქვენთვის ყველაზე საჭირო სანიშნების, სტატიების, ვიდეოებისა და ბოლოს მონახულებული გვერდებისთვის, რომ ადვილად შეძლოთ მათზე დაბრუნება.",
"welcome_label": "მნიშვნელოვანი საიტების დადგენა",
"time_label_less_than_minute": "<1წთ",
"time_label_minute": "{number}წთ",
@@ -57,12 +57,12 @@ window.gActivityStreamStrings = {
"settings_pane_topsites_body": "წვდომა ხშირად მონახულებულ საიტებთან.",
"settings_pane_topsites_options_showmore": "ორ რიგად ჩვენება",
"settings_pane_bookmarks_header": "ბოლოს ჩანიშნულები",
- "settings_pane_bookmarks_body": "ახლად შექმნილი სანიშნეები, ერთი ხელის გაწვდენაზე.",
+ "settings_pane_bookmarks_body": "ახლად შექმნილი სანიშნები, ერთი ხელის გაწვდენაზე.",
"settings_pane_visit_again_header": "ხელახლა ნახვა",
"settings_pane_visit_again_body": "Firefox გაჩვენებთ მონახულებული გვერდების ისტორიიდან იმას, რისი გახსენებაც ან რაზე დაბრუნებაც გენდომებათ.",
"settings_pane_highlights_header": "მნიშვნელოვანი საიტები",
"settings_pane_highlights_body2": "მარტივად დაუბრუნდით ბოლოს მონახულებულ, ან ჩანიშნულ გვერდებს.",
- "settings_pane_highlights_options_bookmarks": "სანიშნეები",
+ "settings_pane_highlights_options_bookmarks": "სანიშნები",
"settings_pane_highlights_options_visited": "მონახულებული საიტები",
"settings_pane_snippets_header": "ცნობები",
"settings_pane_snippets_body": "გაეცანით მოკლე, საინტერესო სიახლეებს Mozilla-სგან, Firefox-ის, ინტერნეტ სამყაროს მიღწევებისა და სხვა დასამახსოვრებელი ფაქტების შესახებ.",
@@ -92,7 +92,7 @@ window.gActivityStreamStrings = {
"pocket_description": "გაეცანით ინტერნეტში არსებულ მაღალი ხარისხის მასალას Pocket-ის საშუალებით, რომელიც ახლა უკვე Mozilla-ს ნაწილს წარმოადგენს.",
"highlights_empty_state": "დაიწყეთ გვერდების დათვალიერება და აქ გამოჩნდება თქვენი რჩეული სტატიები, ვიდეოები და ბოლოს მონახულებული, ან ჩანიშნული საიტები.",
"topstories_empty_state": "უკვე ყველაფერი წაკითხული გაქვთ. {provider}-იდან ახალი რჩეული სტატიების მისაღებად, მოგვიანებით შემოიარეთ. თუ ვერ ითმენთ, აირჩიეთ რომელიმე მოთხოვნადი თემა, ახალი საინტერესო სტატიების მოსაძიებლად.",
- "manual_migration_explanation2": "გადმოიტანეთ სხვა ბრაუზერებიდან თქვენი სანიშნეები, ისტორია და პაროლები Firefox-ში.",
+ "manual_migration_explanation2": "გადმოიტანეთ სხვა ბრაუზერებიდან თქვენი სანიშნები, ისტორია და პაროლები Firefox-ში.",
"manual_migration_cancel_button": "არა, გმადლობთ",
"manual_migration_import_button": "ახლავე გადმოტანა"
};
diff --git a/browser/extensions/activity-stream/prerendered/locales/km/activity-stream-prerendered.html b/browser/extensions/activity-stream/prerendered/locales/km/activity-stream-prerendered.html
index 43f05edab8d7..fb7e24c75211 100644
--- a/browser/extensions/activity-stream/prerendered/locales/km/activity-stream-prerendered.html
+++ b/browser/extensions/activity-stream/prerendered/locales/km/activity-stream-prerendered.html
@@ -8,7 +8,7 @@
- ស្វែងរកបណ្ដាញ Search
វិបសាយលើគេ Access the websites you visit most.
New Tab Preferences
+ ស្វែងរកបណ្ដាញ ស្វែងរក
វិបសាយលើគេ ចូលវេបសាយដែលអ្នកទស្សនាច្រើនបំផុត។
ចំណង់ចំណូលចិត្ត ផ្ទាំងថ្មី
diff --git a/browser/extensions/activity-stream/prerendered/locales/km/activity-stream-strings.js b/browser/extensions/activity-stream/prerendered/locales/km/activity-stream-strings.js
index c05e1aabeb7e..ad65750c7bc6 100644
--- a/browser/extensions/activity-stream/prerendered/locales/km/activity-stream-strings.js
+++ b/browser/extensions/activity-stream/prerendered/locales/km/activity-stream-strings.js
@@ -3,20 +3,20 @@ window.gActivityStreamStrings = {
"newtab_page_title": "ផ្ទាំងថ្មី",
"default_label_loading": "កំពុងផ្ទុក...",
"header_top_sites": "វិបសាយលើគេ",
- "header_stories": "Top Stories",
- "header_highlights": "ការរំលេច",
- "header_visit_again": "Visit Again",
- "header_bookmarks": "Recent Bookmarks",
- "header_recommended_by": "Recommended by {provider}",
- "header_bookmarks_placeholder": "You don’t have any bookmarks yet.",
- "header_stories_from": "from",
+ "header_stories": "រឿងរ៉ាវកំពូល",
+ "header_highlights": "រឿងសំខាន់ៗ",
+ "header_visit_again": "ទស្សនាម្តងទៀត",
+ "header_bookmarks": "ចំណាំថ្មីៗ",
+ "header_recommended_by": "បានណែនាំដោយ {provider}",
+ "header_bookmarks_placeholder": "អ្នកមិនមានចំណាំណាមួយនៅឡើយទេ ។",
+ "header_stories_from": "មកពី",
"type_label_visited": "បានចូលមើល",
"type_label_bookmarked": "បានចំណាំ",
"type_label_synced": "បានធ្វើសមកាលកម្មពីឧបករណ៍ផ្សេងទៀត",
- "type_label_recommended": "Trending",
+ "type_label_recommended": "និន្នាការ",
"type_label_open": "បើក",
"type_label_topic": "ប្រធានបទ",
- "type_label_now": "Now",
+ "type_label_now": "ឥឡូវនេះ",
"menu_action_bookmark": "ចំណាំ",
"menu_action_remove_bookmark": "លុបចំណាំចេញ",
"menu_action_copy_address": "ចម្លងអាសយដ្ឋាន",
@@ -25,22 +25,22 @@ window.gActivityStreamStrings = {
"menu_action_open_private_window": "បើកនៅក្នុងបង្អួចឯកជនថ្មី",
"menu_action_dismiss": "បោះបង់ចោល",
"menu_action_delete": "លុបពីប្រវត្តិ",
- "menu_action_pin": "Pin",
- "menu_action_unpin": "Unpin",
- "confirm_history_delete_p1": "Are you sure you want to delete every instance of this page from your history?",
- "confirm_history_delete_notice_p2": "This action cannot be undone.",
- "menu_action_save_to_pocket": "Save to Pocket",
+ "menu_action_pin": "ខ្ទាស់",
+ "menu_action_unpin": "ដកខ្ទាស់",
+ "confirm_history_delete_p1": "តើអ្នកប្រាកដថាអ្នកចង់លុបគ្រប់វត្ថុនៃទំព័រនេះពីប្រវត្តិរបស់អ្នកឬ?",
+ "confirm_history_delete_notice_p2": "សកម្មភាពនេះមិនអាចមិនធ្វើឡើងវិញបានទេ។",
+ "menu_action_save_to_pocket": "រក្សាទុកទៅ Pocket",
"search_for_something_with": "ស្វែងរក {search_term} ជាមួយ៖",
- "search_button": "Search",
+ "search_button": "ស្វែងរក",
"search_header": "{search_engine_name} ស្វែងរក",
"search_web_placeholder": "ស្វែងរកបណ្ដាញ",
"search_settings": "ផ្លាស់ប្ដូរការកំណត់ស្វែងរក",
- "section_info_option": "Info",
- "section_info_send_feedback": "Send Feedback",
- "section_info_privacy_notice": "Privacy Notice",
+ "section_info_option": "ព័ត៌មាន",
+ "section_info_send_feedback": "ផ្ញើមតិត្រឡប់",
+ "section_info_privacy_notice": "សេចក្តីជូនដំណឹងអំពីភាពឯកជន",
"section_disclaimer_topstories": "The most interesting stories on the web, selected based on what you read. From Pocket, now part of Mozilla.",
"section_disclaimer_topstories_linktext": "Learn how it works.",
- "section_disclaimer_topstories_buttontext": "Okay, got it",
+ "section_disclaimer_topstories_buttontext": "យល់ហើយ",
"welcome_title": "ស្វាគមន៍មកកាន់ផ្ទាំងថ្មី",
"welcome_body": "Firefox នឹងប្រើប្រាស់កន្លែងទំនេរនេះ ដើម្បីបង្ហាញចំណាំ អត្ថបទ វីដេអូ និងទំព័រដែលទាក់ទងអ្នកបំផុត ដែលអ្នកបានចូលមើលថ្មីៗនេះ ដូច្នេះអ្នកអាចត្រឡប់ទៅកាន់វាវិញបានយ៉ាងងាយស្រួល។",
"welcome_label": "កំពុងបញ្ជាក់ការរំលេចរបស់អ្នក",
@@ -49,50 +49,50 @@ window.gActivityStreamStrings = {
"time_label_hour": "{number} ម៉ោង",
"time_label_day": "{number} ថ្ងៃ",
"settings_pane_button_label": "Customize your New Tab page",
- "settings_pane_header": "New Tab Preferences",
- "settings_pane_body2": "Choose what you see on this page.",
- "settings_pane_search_header": "Search",
- "settings_pane_search_body": "Search the Web from your new tab.",
- "settings_pane_topsites_header": "Top Sites",
- "settings_pane_topsites_body": "Access the websites you visit most.",
- "settings_pane_topsites_options_showmore": "Show two rows",
- "settings_pane_bookmarks_header": "Recent Bookmarks",
- "settings_pane_bookmarks_body": "Your newly created bookmarks in one handy location.",
- "settings_pane_visit_again_header": "Visit Again",
+ "settings_pane_header": "ចំណង់ចំណូលចិត្ត ផ្ទាំងថ្មី",
+ "settings_pane_body2": "ជ្រើសរើសអ្វីដែលអ្នកឃើញនៅលើទំព័រនេះ។",
+ "settings_pane_search_header": "ស្វែងរក",
+ "settings_pane_search_body": "ស្វែងរកបណ្តាញពីផ្ទាំងថ្មីរបស់អ្នក។",
+ "settings_pane_topsites_header": "សាយកំពូល",
+ "settings_pane_topsites_body": "ចូលវេបសាយដែលអ្នកទស្សនាច្រើនបំផុត។",
+ "settings_pane_topsites_options_showmore": "បង្ហាញជួរដេកពីរ",
+ "settings_pane_bookmarks_header": "ចំណាំថ្មីៗ",
+ "settings_pane_bookmarks_body": "ចំណាំថ្មីៗ ដែលបានបង្កើតរបស់អ្នកនៅក្នុងទីតាំងដែលងាយស្រួល។",
+ "settings_pane_visit_again_header": "ទស្សនាម្ដងទៀត",
"settings_pane_visit_again_body": "Firefox will show you parts of your browsing history that you might want to remember or get back to.",
- "settings_pane_highlights_header": "Highlights",
+ "settings_pane_highlights_header": "រឿងសំខាន់ៗ",
"settings_pane_highlights_body2": "Find your way back to interesting things you’ve recently visited or bookmarked.",
- "settings_pane_highlights_options_bookmarks": "Bookmarks",
- "settings_pane_highlights_options_visited": "Visited Sites",
- "settings_pane_snippets_header": "Snippets",
+ "settings_pane_highlights_options_bookmarks": "ចំណាំ",
+ "settings_pane_highlights_options_visited": "សាយដែលបានទស្សនា",
+ "settings_pane_snippets_header": "អត្ថបទសង្ខេប",
"settings_pane_snippets_body": "Read short and sweet updates from Mozilla about Firefox, internet culture, and the occasional random meme.",
- "settings_pane_done_button": "Done",
+ "settings_pane_done_button": "ធ្វើរួច",
"settings_pane_topstories_options_sponsored": "Show Sponsored Stories",
- "edit_topsites_button_text": "Edit",
+ "edit_topsites_button_text": "កែសម្រួល",
"edit_topsites_button_label": "Customize your Top Sites section",
- "edit_topsites_showmore_button": "Show More",
- "edit_topsites_showless_button": "Show Fewer",
- "edit_topsites_done_button": "Done",
- "edit_topsites_pin_button": "Pin this site",
- "edit_topsites_unpin_button": "Unpin this site",
- "edit_topsites_edit_button": "Edit this site",
- "edit_topsites_dismiss_button": "Dismiss this site",
- "edit_topsites_add_button": "Add",
- "topsites_form_add_header": "New Top Site",
- "topsites_form_edit_header": "Edit Top Site",
- "topsites_form_title_placeholder": "Enter a title",
- "topsites_form_url_placeholder": "Type or paste a URL",
- "topsites_form_add_button": "Add",
- "topsites_form_save_button": "Save",
- "topsites_form_cancel_button": "Cancel",
- "topsites_form_url_validation": "Valid URL required",
- "pocket_read_more": "Popular Topics:",
- "pocket_read_even_more": "View More Stories",
- "pocket_feedback_header": "The best of the web, curated by over 25 million people.",
+ "edit_topsites_showmore_button": "បង្ហាញច្រើនទៀត",
+ "edit_topsites_showless_button": "បង្ហាញតិចជាងនេះ",
+ "edit_topsites_done_button": "ធ្វើរួច",
+ "edit_topsites_pin_button": "ខ្ទាស់សាយនេះ",
+ "edit_topsites_unpin_button": "ដកខ្ទាស់សាយនេះ",
+ "edit_topsites_edit_button": "កែសម្រួលសាយនេះ",
+ "edit_topsites_dismiss_button": "ច្រានចោលសាយនេះ",
+ "edit_topsites_add_button": "បន្ថែម",
+ "topsites_form_add_header": "សាយកំពូលថ្មី",
+ "topsites_form_edit_header": "កែសម្រួលសាយកំពូល",
+ "topsites_form_title_placeholder": "បញ្ចូលចំណងជើង",
+ "topsites_form_url_placeholder": "វាយបញ្ចូល ឬបិទភ្ជាប់ URL",
+ "topsites_form_add_button": "បន្ថែម",
+ "topsites_form_save_button": "រក្សាទុក",
+ "topsites_form_cancel_button": "បោះបង់",
+ "topsites_form_url_validation": "ត្រូវការ URL ដែលត្រឹមត្រូវ",
+ "pocket_read_more": "ប្រធានបទកំពុងពេញនិយម៖",
+ "pocket_read_even_more": "មើលរឿងរ៉ាវច្រើនទៀត",
+ "pocket_feedback_header": "បណ្តាញល្អបំផុត ដែលបានវាយតម្លៃដោយមនុស្សជាង 25 លាននាក់។",
"pocket_description": "Discover high-quality content you might otherwise miss, with help from Pocket, now part of Mozilla.",
"highlights_empty_state": "Start browsing, and we’ll show some of the great articles, videos, and other pages you’ve recently visited or bookmarked here.",
"topstories_empty_state": "You’ve caught up. Check back later for more top stories from {provider}. Can’t wait? Select a popular topic to find more great stories from around the web.",
- "manual_migration_explanation2": "Try Firefox with the bookmarks, history and passwords from another browser.",
- "manual_migration_cancel_button": "No Thanks",
- "manual_migration_import_button": "Import Now"
+ "manual_migration_explanation2": "សាកល្បងប្រើ Firefox ជាមួយចំណាំ ប្រវត្តិ និងពាក្យសម្ងាត់ពីកម្មវិធីរុករកផ្សេងទៀត។",
+ "manual_migration_cancel_button": "ទេ អរគុណ",
+ "manual_migration_import_button": "នាំចូលឥឡូវនេះ"
};
diff --git a/browser/extensions/activity-stream/prerendered/locales/ko/activity-stream-strings.js b/browser/extensions/activity-stream/prerendered/locales/ko/activity-stream-strings.js
index d256a3ef86cc..f5c013f5c5d1 100644
--- a/browser/extensions/activity-stream/prerendered/locales/ko/activity-stream-strings.js
+++ b/browser/extensions/activity-stream/prerendered/locales/ko/activity-stream-strings.js
@@ -39,8 +39,8 @@ window.gActivityStreamStrings = {
"section_info_send_feedback": "의견 보내기",
"section_info_privacy_notice": "개인 정보 보호 정책",
"section_disclaimer_topstories": "The most interesting stories on the web, selected based on what you read. From Pocket, now part of Mozilla.",
- "section_disclaimer_topstories_linktext": "Learn how it works.",
- "section_disclaimer_topstories_buttontext": "Okay, got it",
+ "section_disclaimer_topstories_linktext": "어떻게 작동 하는지 알아봅시다.",
+ "section_disclaimer_topstories_buttontext": "알겠습니다.",
"welcome_title": "새 탭을 소개합니다",
"welcome_body": "최근에 방문한 관련있는 즐겨찾기나 글, 동영상, 페이지를 Firefox가 여기에 표시해서 쉽게 다시 찾아볼 수 있게 할 것입니다.",
"welcome_label": "하이라이트 확인",
@@ -62,12 +62,12 @@ window.gActivityStreamStrings = {
"settings_pane_visit_again_body": "Firefox will show you parts of your browsing history that you might want to remember or get back to.",
"settings_pane_highlights_header": "하이라이트",
"settings_pane_highlights_body2": "Find your way back to interesting things you’ve recently visited or bookmarked.",
- "settings_pane_highlights_options_bookmarks": "Bookmarks",
- "settings_pane_highlights_options_visited": "Visited Sites",
+ "settings_pane_highlights_options_bookmarks": "즐겨찾기",
+ "settings_pane_highlights_options_visited": "방문한 사이트",
"settings_pane_snippets_header": "Snippets",
"settings_pane_snippets_body": "Read short and sweet updates from Mozilla about Firefox, internet culture, and the occasional random meme.",
"settings_pane_done_button": "완료",
- "settings_pane_topstories_options_sponsored": "Show Sponsored Stories",
+ "settings_pane_topstories_options_sponsored": "후원된 스토리",
"edit_topsites_button_text": "수정",
"edit_topsites_button_label": "상위 사이트 영역 꾸미기",
"edit_topsites_showmore_button": "더보기",
@@ -90,7 +90,7 @@ window.gActivityStreamStrings = {
"pocket_read_even_more": "더 많은 이야기 보기",
"pocket_feedback_header": "2천 5백만 명에 의해 추천되는 최고의 웹입니다.",
"pocket_description": "Mozilla와 하나가 된 Pocket의 도움으로 놓칠지도 모르는 고품질의 컨텐츠를 접해보세요.",
- "highlights_empty_state": "Start browsing, and we’ll show some of the great articles, videos, and other pages you’ve recently visited or bookmarked here.",
+ "highlights_empty_state": "브라우징을 시작하면 최근 방문하거나 북마크한 좋은 글이나 영상, 페이지를 여기에 보여줍니다.",
"topstories_empty_state": "You’ve caught up. Check back later for more top stories from {provider}. Can’t wait? Select a popular topic to find more great stories from around the web.",
"manual_migration_explanation2": "다른 브라우저에 있는 북마크, 기록, 비밀번호를 사용해 Firefox를 이용해 보세요.",
"manual_migration_cancel_button": "괜찮습니다",
diff --git a/browser/extensions/activity-stream/prerendered/locales/lo/activity-stream-prerendered.html b/browser/extensions/activity-stream/prerendered/locales/lo/activity-stream-prerendered.html
index c6d2fc2f597d..f9966385f771 100644
--- a/browser/extensions/activity-stream/prerendered/locales/lo/activity-stream-prerendered.html
+++ b/browser/extensions/activity-stream/prerendered/locales/lo/activity-stream-prerendered.html
@@ -8,7 +8,7 @@
- ຄົ້ນຫາເວັບ ຊອກຫາ
ເວັບໄຊຕ໌ຍອດນິຍົມ ເຂົ້າເວັບໄຊທ໌ທີ່ທ່ານໄດ້ເຂົ້າໄປຫລາຍທີ່ສຸດ.
ການຕັ້ງຄ່າແທັບໃຫມ່
+ ຄົ້ນຫາເວັບ ຊອກຫາ
ເວັບໄຊຕ໌ຍອດນິຍົມ ເຂົ້າເວັບໄຊທ໌ທີ່ທ່ານໄດ້ເຂົ້າໄປຫລາຍທີ່ສຸດ.
ການຕັ້ງຄ່າແທັບໃຫມ່
diff --git a/browser/extensions/activity-stream/prerendered/locales/lo/activity-stream-strings.js b/browser/extensions/activity-stream/prerendered/locales/lo/activity-stream-strings.js
index 41433c13b36a..72425d179554 100644
--- a/browser/extensions/activity-stream/prerendered/locales/lo/activity-stream-strings.js
+++ b/browser/extensions/activity-stream/prerendered/locales/lo/activity-stream-strings.js
@@ -4,7 +4,7 @@ window.gActivityStreamStrings = {
"default_label_loading": "ກຳລັງໂຫລດ…",
"header_top_sites": "ເວັບໄຊຕ໌ຍອດນິຍົມ",
"header_stories": "Top Stories",
- "header_highlights": "ຈຸດເດັ່ນ",
+ "header_highlights": "ລາຍການເດັ່ນ",
"header_visit_again": "Visit Again",
"header_bookmarks": "Recent Bookmarks",
"header_recommended_by": "Recommended by {provider}",
@@ -29,7 +29,7 @@ window.gActivityStreamStrings = {
"menu_action_unpin": "Unpin",
"confirm_history_delete_p1": "Are you sure you want to delete every instance of this page from your history?",
"confirm_history_delete_notice_p2": "This action cannot be undone.",
- "menu_action_save_to_pocket": "Save to Pocket",
+ "menu_action_save_to_pocket": "ບັນທືກໄປທີ່ Pocket",
"search_for_something_with": "ຄົ້ນຫາສໍາລັບ {search_term} ດ້ວຍ:",
"search_button": "ຊອກຫາ",
"search_header": "ຄົ້ນຫາ {search_engine_name}",
@@ -64,7 +64,7 @@ window.gActivityStreamStrings = {
"settings_pane_highlights_body2": "Find your way back to interesting things you’ve recently visited or bookmarked.",
"settings_pane_highlights_options_bookmarks": "Bookmarks",
"settings_pane_highlights_options_visited": "Visited Sites",
- "settings_pane_snippets_header": "Snippets",
+ "settings_pane_snippets_header": "ສ່ວນຍ່ອຍ",
"settings_pane_snippets_body": "Read short and sweet updates from Mozilla about Firefox, internet culture, and the occasional random meme.",
"settings_pane_done_button": "ສຳເລັດ",
"settings_pane_topstories_options_sponsored": "Show Sponsored Stories",
@@ -80,13 +80,13 @@ window.gActivityStreamStrings = {
"edit_topsites_add_button": "Add",
"topsites_form_add_header": "New Top Site",
"topsites_form_edit_header": "Edit Top Site",
- "topsites_form_title_placeholder": "Enter a title",
+ "topsites_form_title_placeholder": "ປ້ອນຊື່ເລື່ອງ",
"topsites_form_url_placeholder": "Type or paste a URL",
"topsites_form_add_button": "Add",
"topsites_form_save_button": "Save",
"topsites_form_cancel_button": "Cancel",
"topsites_form_url_validation": "Valid URL required",
- "pocket_read_more": "Popular Topics:",
+ "pocket_read_more": "ຫົວຂໍ້ຍອດນິຍົມ:",
"pocket_read_even_more": "View More Stories",
"pocket_feedback_header": "The best of the web, curated by over 25 million people.",
"pocket_description": "Discover high-quality content you might otherwise miss, with help from Pocket, now part of Mozilla.",
@@ -94,7 +94,5 @@ window.gActivityStreamStrings = {
"topstories_empty_state": "You’ve caught up. Check back later for more top stories from {provider}. Can’t wait? Select a popular topic to find more great stories from around the web.",
"manual_migration_explanation2": "Try Firefox with the bookmarks, history and passwords from another browser.",
"manual_migration_cancel_button": "No Thanks",
- "manual_migration_import_button": "Import Now",
- "settings_pane_body": "ເລືອກສິ່ງທີ່ທ່ານເຫັນເມື່ອທ່ານເປີດແທັບໃຫມ່.",
- "settings_pane_highlights_body": "ຍ້ອນຄືນກັບໄປເບິງປະຫວັດການທ່ອງເວັບທີ່ຫາກາເຂົ້າໄປ ແລະ ບຸກມາກທີ່ໄດ້ຮັບການສ້າງຂື້ນມາໃຫມ່ຂອງທ່ານ."
+ "manual_migration_import_button": "ນຳເຂົ້າຕອນນີ້"
};
diff --git a/browser/extensions/activity-stream/prerendered/locales/lt/activity-stream-strings.js b/browser/extensions/activity-stream/prerendered/locales/lt/activity-stream-strings.js
index 4203f29f50a5..bc93a72d6a28 100644
--- a/browser/extensions/activity-stream/prerendered/locales/lt/activity-stream-strings.js
+++ b/browser/extensions/activity-stream/prerendered/locales/lt/activity-stream-strings.js
@@ -38,9 +38,9 @@ window.gActivityStreamStrings = {
"section_info_option": "Informacija",
"section_info_send_feedback": "Siųsti atsiliepimą",
"section_info_privacy_notice": "Privatumo nuostatai",
- "section_disclaimer_topstories": "The most interesting stories on the web, selected based on what you read. From Pocket, now part of Mozilla.",
- "section_disclaimer_topstories_linktext": "Learn how it works.",
- "section_disclaimer_topstories_buttontext": "Okay, got it",
+ "section_disclaimer_topstories": "Įdomiausi saityno straipsniai, parinkti pagal jūsų skaitymo įpročius. Iš „Pocket“, kuri dabar priklauso „Mozillai“.",
+ "section_disclaimer_topstories_linktext": "Sužinokite, kaip tai veikia.",
+ "section_disclaimer_topstories_buttontext": "Gerai, supratau",
"welcome_title": "Sveiki, čia nauja kortelė",
"welcome_body": "„Firefox“ naudos šią vietą jums aktualiausių adresyno įrašų, straipsnių, vaizdo įrašų bei neseniai lankytų tinklalapių rodymui, kad galėtumėte lengvai į juos sugrįžti.",
"welcome_label": "Nustatomi jūsų akcentai",
@@ -67,7 +67,7 @@ window.gActivityStreamStrings = {
"settings_pane_snippets_header": "Iškarpos",
"settings_pane_snippets_body": "Skaitykite trumpas ir mielas naujienas iš „Mozillos“ apie „Firefox“, interneto kultūrą bei atsitiktinį memą.",
"settings_pane_done_button": "Atlikta",
- "settings_pane_topstories_options_sponsored": "Show Sponsored Stories",
+ "settings_pane_topstories_options_sponsored": "Rodyti rėmėjų straipsnius",
"edit_topsites_button_text": "Keisti",
"edit_topsites_button_label": "Tinkinkite savo lankomiausių svetainių skiltį",
"edit_topsites_showmore_button": "Rodyti daugiau",
diff --git a/browser/extensions/activity-stream/prerendered/locales/ml/activity-stream-strings.js b/browser/extensions/activity-stream/prerendered/locales/ml/activity-stream-strings.js
index 53e2dc99f0d1..56634ad7f10a 100644
--- a/browser/extensions/activity-stream/prerendered/locales/ml/activity-stream-strings.js
+++ b/browser/extensions/activity-stream/prerendered/locales/ml/activity-stream-strings.js
@@ -38,9 +38,9 @@ window.gActivityStreamStrings = {
"section_info_option": "വിവരം",
"section_info_send_feedback": "ഫീഡ്ബാക്ക് അയയ്ക്കുക",
"section_info_privacy_notice": "സ്വകാര്യതാ അറിയിപ്പ്",
- "section_disclaimer_topstories": "The most interesting stories on the web, selected based on what you read. From Pocket, now part of Mozilla.",
- "section_disclaimer_topstories_linktext": "Learn how it works.",
- "section_disclaimer_topstories_buttontext": "Okay, got it",
+ "section_disclaimer_topstories": "വെബിലെ ഏറ്റവും രസകരമായ അറിവുകൾ, നിങ്ങൾ വായിച്ചവ അടിസ്ഥാനമാക്കി തിരഞ്ഞെടുത്തത്. ഇപ്പോൾ മോസില്ലയുടെ ഭാഗമായ പോക്കറ്റിൽ നിന്നും.",
+ "section_disclaimer_topstories_linktext": "എങ്ങനെ പ്രവര്ത്തിക്കുന്നു എന്ന് കാണുക.",
+ "section_disclaimer_topstories_buttontext": "ശരി, മനസ്സിലായി",
"welcome_title": "പുതിയ ജാലകത്തിലേക്കു സ്വാഗതം",
"welcome_body": "നിങ്ങളുടെ ഏറ്റവും ശ്രദ്ധേയമായ അടയാളങ്ങൾ, ലേഖനങ്ങൾ, വീഡിയോകൾ, കൂടാതെ നിങ്ങൾ സമീപകാലത്ത് സന്ദർശിച്ച താളുകൾ എന്നിവ കാണിക്കുന്നതിനായി ഫയർഫോക്സ് ഈ ഇടം ഉപയോഗിക്കും, അതിനാൽ നിങ്ങൾക്ക് എളുപ്പത്തിൽ അവയിലേക്ക് തിരിച്ചു പോകാം.",
"welcome_label": "താങ്കളുടെ ഹൈലൈറ്റ്സ് തിരിച്ചറിയുന്നു",
@@ -67,7 +67,7 @@ window.gActivityStreamStrings = {
"settings_pane_snippets_header": "ലഘു കുറിപ്പുകൾ",
"settings_pane_snippets_body": "മോസില്ലയിൽ നിന്നും ഫയർഫോക്സ്, ഇന്റർനെറ്റ് സംസ്കാരം, വല്ലപ്പോഴുമുള്ള ക്രമമില്ലാത്ത മെമെ, എന്നിവയിൽ ചെറുതും മധുരവുമായ പരിഷ്കരണങ്ങൾ വായിക്കുക.",
"settings_pane_done_button": "തീർന്നു",
- "settings_pane_topstories_options_sponsored": "Show Sponsored Stories",
+ "settings_pane_topstories_options_sponsored": "സ്പോൺസർ ചെയ്തവ കാണിക്കുക",
"edit_topsites_button_text": "തിരുത്തുക",
"edit_topsites_button_label": "നിങ്ങളുടെ മുന്നേറിയ സൈറ്റുകളുടെ വിഭാഗം ഇഷ്ടാനുസൃതമാക്കുക",
"edit_topsites_showmore_button": "കൂടുതൽ കാണിക്കുക",
diff --git a/browser/extensions/activity-stream/prerendered/locales/pt-BR/activity-stream-strings.js b/browser/extensions/activity-stream/prerendered/locales/pt-BR/activity-stream-strings.js
index 7aa50614e4d7..d748fa38d0df 100644
--- a/browser/extensions/activity-stream/prerendered/locales/pt-BR/activity-stream-strings.js
+++ b/browser/extensions/activity-stream/prerendered/locales/pt-BR/activity-stream-strings.js
@@ -27,7 +27,7 @@ window.gActivityStreamStrings = {
"menu_action_delete": "Excluir do histórico",
"menu_action_pin": "Fixar",
"menu_action_unpin": "Desafixar",
- "confirm_history_delete_p1": "Você tem certeza que deseja deletar todas as ocorrências dessa página do seu histórico?",
+ "confirm_history_delete_p1": "Você tem certeza que deseja excluir todas as instâncias desta página do seu histórico?",
"confirm_history_delete_notice_p2": "Essa ação não pode ser desfeita.",
"menu_action_save_to_pocket": "Salvar no Pocket",
"search_for_something_with": "Pesquisar por {search_term} com:",
@@ -36,7 +36,7 @@ window.gActivityStreamStrings = {
"search_web_placeholder": "Pesquisar na Web",
"search_settings": "Alterar configurações de pesquisa",
"section_info_option": "Info",
- "section_info_send_feedback": "Enviar opinião",
+ "section_info_send_feedback": "Enviar feedback",
"section_info_privacy_notice": "Política de Privacidade",
"section_disclaimer_topstories": "As histórias mais interessantes na web, selecionadas baseadas no que você lê. Do Pocket, agora parte da Mozilla.",
"section_disclaimer_topstories_linktext": "Saiba como funciona.",
diff --git a/browser/extensions/activity-stream/prerendered/locales/pt-PT/activity-stream-strings.js b/browser/extensions/activity-stream/prerendered/locales/pt-PT/activity-stream-strings.js
index 77d612902447..230440c275a5 100644
--- a/browser/extensions/activity-stream/prerendered/locales/pt-PT/activity-stream-strings.js
+++ b/browser/extensions/activity-stream/prerendered/locales/pt-PT/activity-stream-strings.js
@@ -41,7 +41,7 @@ window.gActivityStreamStrings = {
"section_disclaimer_topstories": "As histórias mais interessantes na web, selecionadas baseadas no que você lê. Do Pocket, agora parte da Mozilla.",
"section_disclaimer_topstories_linktext": "Saiba como funciona.",
"section_disclaimer_topstories_buttontext": "Ok, entendi",
- "welcome_title": "Bem-vindo ao novo separador",
+ "welcome_title": "Bem-vindo(a) ao novo separador",
"welcome_body": "O Firefox irá utilizar este espaço para lhe mostrar os seus marcadores, artigos, vídeos, e páginas mais relevantes que visitou recentemente, para que possa regressar a estes mais facilmente.",
"welcome_label": "A identificar os seus destaques",
"time_label_less_than_minute": "<1m",
@@ -52,7 +52,7 @@ window.gActivityStreamStrings = {
"settings_pane_header": "Preferências de novo separador",
"settings_pane_body2": "Escolha o que vê nesta página.",
"settings_pane_search_header": "Pesquisa",
- "settings_pane_search_body": "Pesquise na Web a partir do seu novo separador.",
+ "settings_pane_search_body": "Pesquise na Web a partir do seu 'Novo separador'.",
"settings_pane_topsites_header": "Sites mais visitados",
"settings_pane_topsites_body": "Aceda aos websites que mais visita.",
"settings_pane_topsites_options_showmore": "Mostrar duas linhas",
@@ -93,6 +93,6 @@ window.gActivityStreamStrings = {
"highlights_empty_state": "Comece a navegar, e iremos mostrar-lhe alguns dos ótimos artigos, vídeos, e outras páginas que visitou recentemente ou adicionou aos marcadores aqui.",
"topstories_empty_state": "Já apanhou tudo. Verifique mais tarde para mais histórias principais de {provider}. Não pode esperar? Selecione um tópico popular para encontrar mais boas histórias de toda a web.",
"manual_migration_explanation2": "Experimente o Firefox com marcadores, histórico e palavras-passe de outro navegador.",
- "manual_migration_cancel_button": "Não obrigado",
+ "manual_migration_cancel_button": "Não, obrigado",
"manual_migration_import_button": "Importar agora"
};
diff --git a/browser/extensions/activity-stream/prerendered/locales/ro/activity-stream-strings.js b/browser/extensions/activity-stream/prerendered/locales/ro/activity-stream-strings.js
index 23b46a180adb..ce6f6970191f 100644
--- a/browser/extensions/activity-stream/prerendered/locales/ro/activity-stream-strings.js
+++ b/browser/extensions/activity-stream/prerendered/locales/ro/activity-stream-strings.js
@@ -38,9 +38,9 @@ window.gActivityStreamStrings = {
"section_info_option": "Informații",
"section_info_send_feedback": "Trimite feedback",
"section_info_privacy_notice": "Politica de confidențialitate",
- "section_disclaimer_topstories": "The most interesting stories on the web, selected based on what you read. From Pocket, now part of Mozilla.",
- "section_disclaimer_topstories_linktext": "Learn how it works.",
- "section_disclaimer_topstories_buttontext": "Okay, got it",
+ "section_disclaimer_topstories": "Cele mai interesante articole de pe web, alese pe baza lucrurilor pe care le citești. De la Pocket, acum parte din Mozilla.",
+ "section_disclaimer_topstories_linktext": "Află cum funcționează.",
+ "section_disclaimer_topstories_buttontext": "Ok, am înțeles",
"welcome_title": "Bun venit în noua filă",
"welcome_body": "Firefox va folosi acest spațiu pentru a arăta cele mai relevante semne de carte, articole, videouri și pagini vizitate recent pentru a reveni la acestea ușor.",
"welcome_label": "Se identifică evidențierile tale",
@@ -61,13 +61,13 @@ window.gActivityStreamStrings = {
"settings_pane_visit_again_header": "Vizitează din nou",
"settings_pane_visit_again_body": "Firefox îți va arăta părți din istoricul navigării tale la care ai vrea să revii mai târziu.",
"settings_pane_highlights_header": "Evidențieri",
- "settings_pane_highlights_body2": "Find your way back to interesting things you’ve recently visited or bookmarked.",
+ "settings_pane_highlights_body2": "Regăsește lucrurile interesante pe care le-ai vizitat sau marcat recent.",
"settings_pane_highlights_options_bookmarks": "Marcaje",
"settings_pane_highlights_options_visited": "Site-uri vizitate",
- "settings_pane_snippets_header": "Snippets",
- "settings_pane_snippets_body": "Read short and sweet updates from Mozilla about Firefox, internet culture, and the occasional random meme.",
+ "settings_pane_snippets_header": "Fragmente",
+ "settings_pane_snippets_body": "Citește actualizări scurte de la Mozilla despre Firefox, cultura internetului și meme-ul ocazional.",
"settings_pane_done_button": "Gata",
- "settings_pane_topstories_options_sponsored": "Show Sponsored Stories",
+ "settings_pane_topstories_options_sponsored": "Arată articolele sponsorizate",
"edit_topsites_button_text": "Editează",
"edit_topsites_button_label": "Particularizează secțiunea site-urilor de top",
"edit_topsites_showmore_button": "Arată mai mult",
@@ -89,9 +89,9 @@ window.gActivityStreamStrings = {
"pocket_read_more": "Subiecte populare:",
"pocket_read_even_more": "Vezi mai multe articole",
"pocket_feedback_header": "Cel mai bun de pe web, întreţinut de peste 25 de milioane de oameni.",
- "pocket_description": "Discover high-quality content you might otherwise miss, with help from Pocket, now part of Mozilla.",
- "highlights_empty_state": "Start browsing, and we’ll show some of the great articles, videos, and other pages you’ve recently visited or bookmarked here.",
- "topstories_empty_state": "You’ve caught up. Check back later for more top stories from {provider}. Can’t wait? Select a popular topic to find more great stories from around the web.",
+ "pocket_description": "Descoperă conținut de calitate pe care l-ai putea rata, cu ajutorul Pocket, acum parte din Mozilla.",
+ "highlights_empty_state": "Începe să navighezi și noi îți vom arăta articole interesante, videouri sau alte pagini pe care le-ai vizitat sau marcat recent.",
+ "topstories_empty_state": "Ai ajuns la capăt. Revino mai târziu pentru alte articole de la {provider}. Nu mai vrei să aștepți? Alege un subiect popular și găsește alte articole interesante de pe web.",
"manual_migration_explanation2": "Încearcă Firefox cu marcajele, istoricul și parolele din alt navigator.",
"manual_migration_cancel_button": "Nu, mulțumesc",
"manual_migration_import_button": "Importă acum"
diff --git a/browser/extensions/activity-stream/prerendered/locales/si/activity-stream-prerendered.html b/browser/extensions/activity-stream/prerendered/locales/si/activity-stream-prerendered.html
new file mode 100644
index 000000000000..35e7ec576138
--- /dev/null
+++ b/browser/extensions/activity-stream/prerendered/locales/si/activity-stream-prerendered.html
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+
+ ජාලය තුළ සොයන්න සොයන්න
ප්රමුඛ අඩවි ඔබ නිරතුරුව පිවිසෙන වෙබ් අඩවි වෙත ප්රවේශය.
නව ටැබ අභිප්රේත
Pocket විසින් නිර්දේශිතයි
+
+
+
+
diff --git a/browser/extensions/activity-stream/prerendered/locales/si/activity-stream-strings.js b/browser/extensions/activity-stream/prerendered/locales/si/activity-stream-strings.js
new file mode 100644
index 000000000000..58fe3b49cc28
--- /dev/null
+++ b/browser/extensions/activity-stream/prerendered/locales/si/activity-stream-strings.js
@@ -0,0 +1,98 @@
+// Note - this is a generated file.
+window.gActivityStreamStrings = {
+ "newtab_page_title": "නව ටැබය",
+ "default_label_loading": "පූරණය වෙමින්…",
+ "header_top_sites": "ප්රමුඛ අඩවි",
+ "header_stories": "ප්රමුඛ පුවත්",
+ "header_highlights": "ඉස්මතු කිරීම්",
+ "header_visit_again": "යළි පිවිසෙන්න",
+ "header_bookmarks": "නැවුම් පිටු සලකුණු",
+ "header_recommended_by": "{provider} විසින් නිර්දේශිතයි",
+ "header_bookmarks_placeholder": "ඔබ සතුව තවම පිටුසලකුණු නැත.",
+ "header_stories_from": "සිට",
+ "type_label_visited": "ප්රවේශිත",
+ "type_label_bookmarked": "පිටු සලකුණු තැබූ",
+ "type_label_synced": "වෙනත් උපාංගයක් වෙතින් සමකාලීන කර ඇත",
+ "type_label_recommended": "Trending",
+ "type_label_open": "විවෘත",
+ "type_label_topic": "මාතෘකාව",
+ "type_label_now": "දැන්",
+ "menu_action_bookmark": "පිටු සලකුණ",
+ "menu_action_remove_bookmark": "පිටු සලකුණ ඉවත් කරන්න",
+ "menu_action_copy_address": "ලිපිනය පිටපත් කරන්න",
+ "menu_action_email_link": "විද්යුත් තැපැල් සබැඳි…",
+ "menu_action_open_new_window": "නව කවුළුවක විවෘත කරන්න",
+ "menu_action_open_private_window": "නව පුද්ගලික කවුළුවක විවෘත කරන්න",
+ "menu_action_dismiss": "ඉවත් කරන්න",
+ "menu_action_delete": "අතිතයෙන් මකන්න කරන්න",
+ "menu_action_pin": "ඇමිණීම",
+ "menu_action_unpin": "ඇමුණුම ඉවත් කරන්න",
+ "confirm_history_delete_p1": "ඔබට මෙම පිටුවට අදාල සියලුම සිදුවීම් ඔබේ අතීතයන් මැකීමට අවශ්ය ද?",
+ "confirm_history_delete_notice_p2": "මෙම ක්රියාව අහෝසි කළ නොහැක.",
+ "menu_action_save_to_pocket": "Save to Pocket",
+ "search_for_something_with": "{search_term} සදහා සෙවීමට භාවිත කළ යුත්තේ:",
+ "search_button": "සොයන්න",
+ "search_header": "{search_engine_name} ෙසවුම",
+ "search_web_placeholder": "ජාලය තුළ සොයන්න",
+ "search_settings": "සෙවුම් සැකසුම් වෙනස් කරන්න",
+ "section_info_option": "තොරතුරු",
+ "section_info_send_feedback": "ප්රතිචාරය යවන්න",
+ "section_info_privacy_notice": "පෞද්ගලිකත්ව දැනුම්දීම්",
+ "section_disclaimer_topstories": "The most interesting stories on the web, selected based on what you read. From Pocket, now part of Mozilla.",
+ "section_disclaimer_topstories_linktext": "එය ක්රියාකරන්නේ කෙසේදැයි අධ්යපනය කරන්න.",
+ "section_disclaimer_topstories_buttontext": "හරි, තේරුණා",
+ "welcome_title": "නව ටැබයට සාදරයෙන් පිළිගනිමු",
+ "welcome_body": "ඔබට පහසුවෙන් යළි භාවිතයට පහසු කරවීමට, Firefox මෙම ඉඩ ඔබට වඩාත් අදාල පිටු සළකුණු, ලිපි, විඩියෝ සහ ඔබ මෑතකදී පිවිසි පිටු පෙන්වීම සදහා භාවිත කරයි.",
+ "welcome_label": "ඔබේ ඉස්මතු කිරීම් හදුනාගනිමින්",
+ "time_label_less_than_minute": "<1m",
+ "time_label_minute": "{number} මිනිත්තු",
+ "time_label_hour": "{number}පැය",
+ "time_label_day": "{number}දින",
+ "settings_pane_button_label": "ඔබේ නව ටැබ පිටුව රුචිකරණය කරන්න",
+ "settings_pane_header": "නව ටැබ අභිප්රේත",
+ "settings_pane_body2": "මෙම පිටුවේ ඔබ දැකිය යුතු දේ තෝරන්න.",
+ "settings_pane_search_header": "සොයන්න",
+ "settings_pane_search_body": "ඔබේ නව ටැබයෙන් වෙබ් සෙවීම.",
+ "settings_pane_topsites_header": "ප්රමුඛ අඩවි",
+ "settings_pane_topsites_body": "ඔබ නිරතුරුව පිවිසෙන වෙබ් අඩවි වෙත ප්රවේශය.",
+ "settings_pane_topsites_options_showmore": "පේළි දෙකක් පෙන්වන්න",
+ "settings_pane_bookmarks_header": "නැවුම් පිටු සලකුණු",
+ "settings_pane_bookmarks_body": "ඔබේ නැවුම් පිටු සලකුණු එක් ස්ථානයක.",
+ "settings_pane_visit_again_header": "යළි පිවිසෙන්න",
+ "settings_pane_visit_again_body": "Firefox will show you parts of your browsing history that you might want to remember or get back to.",
+ "settings_pane_highlights_header": "ඉස්මතු කිරීම්",
+ "settings_pane_highlights_body2": "Find your way back to interesting things you’ve recently visited or bookmarked.",
+ "settings_pane_highlights_options_bookmarks": "පිටු සලකුණු",
+ "settings_pane_highlights_options_visited": "පිවිසුණු අඩවි",
+ "settings_pane_snippets_header": "Snippets",
+ "settings_pane_snippets_body": "Read short and sweet updates from Mozilla about Firefox, internet culture, and the occasional random meme.",
+ "settings_pane_done_button": "",
+ "settings_pane_topstories_options_sponsored": "අනුග්රහක පුවත් පෙන්වන්න",
+ "edit_topsites_button_text": "සැකසුම්",
+ "edit_topsites_button_label": "Customize your Top Sites section",
+ "edit_topsites_showmore_button": "තවත් පෙන්වන්න",
+ "edit_topsites_showless_button": "අඩුවෙන් පෙන්වන්න",
+ "edit_topsites_done_button": "කළා",
+ "edit_topsites_pin_button": "Pin this site",
+ "edit_topsites_unpin_button": "Unpin this site",
+ "edit_topsites_edit_button": "මෙම අඩවිය සකසන්න",
+ "edit_topsites_dismiss_button": "මෙම අඩවිය ඉවත ලන්න",
+ "edit_topsites_add_button": "එක් කරන්න",
+ "topsites_form_add_header": "නව ප්රමුඛ අඩවියක්",
+ "topsites_form_edit_header": "ප්රමුඛ අඩවිය සකසන්න",
+ "topsites_form_title_placeholder": "සිරස්තල එක් කරන්න",
+ "topsites_form_url_placeholder": "URL එකක් ඇතුළත් කරන්න",
+ "topsites_form_add_button": "එක් කරන්න",
+ "topsites_form_save_button": "සුරකින්න",
+ "topsites_form_cancel_button": "අවලංගු කරන්න",
+ "topsites_form_url_validation": "වලංගු URL එකක් අවශ්ය වේ",
+ "pocket_read_more": "ජනප්රිය මාතෘකා:",
+ "pocket_read_even_more": "තවත් බොහෝ දැ",
+ "pocket_feedback_header": "The best of the web, curated by over 25 million people.",
+ "pocket_description": "Discover high-quality content you might otherwise miss, with help from Pocket, now part of Mozilla.",
+ "highlights_empty_state": "Start browsing, and we’ll show some of the great articles, videos, and other pages you’ve recently visited or bookmarked here.",
+ "topstories_empty_state": "You’ve caught up. Check back later for more top stories from {provider}. Can’t wait? Select a popular topic to find more great stories from around the web.",
+ "manual_migration_explanation2": "Firefox වෙනත් ගවේශයකය පිටය සලකුණු, අතීතය සහ මුරපද සමග උත්සාහ කර බලන්න.",
+ "manual_migration_cancel_button": "එපා, ස්තුතියි",
+ "manual_migration_import_button": "දැන් ආයාත කරන්න"
+};
diff --git a/browser/extensions/activity-stream/prerendered/locales/si/activity-stream.html b/browser/extensions/activity-stream/prerendered/locales/si/activity-stream.html
new file mode 100644
index 000000000000..1ff15a123ccf
--- /dev/null
+++ b/browser/extensions/activity-stream/prerendered/locales/si/activity-stream.html
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/browser/extensions/activity-stream/prerendered/locales/ta/activity-stream-prerendered.html b/browser/extensions/activity-stream/prerendered/locales/ta/activity-stream-prerendered.html
index 8da0124eb13a..08de0ad74d93 100644
--- a/browser/extensions/activity-stream/prerendered/locales/ta/activity-stream-prerendered.html
+++ b/browser/extensions/activity-stream/prerendered/locales/ta/activity-stream-prerendered.html
@@ -8,7 +8,7 @@
- இணையத்தில் தேடு தேடு
சிறந்த தளங்கள் நீங்கள் அடிக்கடி பார்க்கும் தளங்களை அணுகவும்.
புதிய கீற்றின் முன்னுரிமைகள்
Pocket என்பவரால் பரிந்துரைக்கப்பட்டது
+ இணையத்தில் தேடு தேடு
சிறந்த தளங்கள் நீங்கள் அடிக்கடி பார்க்கும் தளங்களை அணுகவும்.
புதிய கீற்றின் முன்னுரிமைகள்
Pocket என்பவரால் பரிந்துரைக்கப்பட்டது
diff --git a/browser/extensions/activity-stream/prerendered/locales/ta/activity-stream-strings.js b/browser/extensions/activity-stream/prerendered/locales/ta/activity-stream-strings.js
index d57ded84be36..1f1585656e6b 100644
--- a/browser/extensions/activity-stream/prerendered/locales/ta/activity-stream-strings.js
+++ b/browser/extensions/activity-stream/prerendered/locales/ta/activity-stream-strings.js
@@ -4,7 +4,7 @@ window.gActivityStreamStrings = {
"default_label_loading": "ஏற்றுகிறது…",
"header_top_sites": "சிறந்த தளங்கள்",
"header_stories": "முக்கிய கதைகள்",
- "header_highlights": "Highlights",
+ "header_highlights": "மிளிர்ப்புகள்",
"header_visit_again": "மீண்டும் வருக",
"header_bookmarks": "சமீபத்திய புத்தகக்குறிகள்",
"header_recommended_by": "{provider} என்பவரால் பரிந்துரைக்கப்பட்டது",
@@ -36,8 +36,8 @@ window.gActivityStreamStrings = {
"search_web_placeholder": "இணையத்தில் தேடு",
"search_settings": "தேடல் அமைவுகளை மாற்று",
"section_info_option": "தகவல்",
- "section_info_send_feedback": "Send Feedback",
- "section_info_privacy_notice": "Privacy Notice",
+ "section_info_send_feedback": "பின்னூட்டம் அனுப்பு",
+ "section_info_privacy_notice": "தனியுரிம கொள்கை",
"section_disclaimer_topstories": "The most interesting stories on the web, selected based on what you read. From Pocket, now part of Mozilla.",
"section_disclaimer_topstories_linktext": "Learn how it works.",
"section_disclaimer_topstories_buttontext": "Okay, got it",
@@ -60,10 +60,10 @@ window.gActivityStreamStrings = {
"settings_pane_bookmarks_body": "ஒரு வசதியான இடத்தில் உங்கள் புதிதாக உருவாக்கப்பட்ட புத்தகக்குறிகள்.",
"settings_pane_visit_again_header": "மீண்டும் வருக",
"settings_pane_visit_again_body": "பயர்பாக்ஸ் நீங்கள் நினைவுப்படுத்த (அ) திரும்பப் பெற விரும்பும் உங்கள் உலாவல் வரலாற்றின் சில பகுதிகளைக் காட்டும்.",
- "settings_pane_highlights_header": "Highlights",
+ "settings_pane_highlights_header": "மிளிர்ப்புகள்",
"settings_pane_highlights_body2": "Find your way back to interesting things you’ve recently visited or bookmarked.",
- "settings_pane_highlights_options_bookmarks": "Bookmarks",
- "settings_pane_highlights_options_visited": "Visited Sites",
+ "settings_pane_highlights_options_bookmarks": "புத்தகக்குறிகள்",
+ "settings_pane_highlights_options_visited": "பார்வையிடப்பட்ட தளம்",
"settings_pane_snippets_header": "Snippets",
"settings_pane_snippets_body": "Read short and sweet updates from Mozilla about Firefox, internet culture, and the occasional random meme.",
"settings_pane_done_button": "முடிந்தது",
@@ -94,10 +94,5 @@ window.gActivityStreamStrings = {
"topstories_empty_state": "You’ve caught up. Check back later for more top stories from {provider}. Can’t wait? Select a popular topic to find more great stories from around the web.",
"manual_migration_explanation2": "Try Firefox with the bookmarks, history and passwords from another browser.",
"manual_migration_cancel_button": "பரவாயில்லை",
- "manual_migration_import_button": "இப்போது இறக்கு",
- "settings_pane_body": "ஒரு புதிய கீற்றைத் திறக்கும்போது நீங்கள் பார்ப்பதை தேர்க.",
- "settings_pane_pocketstories_header": "முக்கிய கதைகள்",
- "settings_pane_pocketstories_body": "Pocket, ஒரு மொசில்லா குடும்ப உறுப்பினராக, உயர்தர உள்ளடக்கங்களுடன் இணைய உதவுகிறது, இது இல்லையேல் அது சாத்தியமாகது.",
- "pocket_feedback_body": "Pocket, ஒரு மொசில்லா குடும்ப உறுப்பினராக, உயர்தர உள்ளடக்கங்களுடன் இணைய உதவுகிறது, இது இல்லையேல் அது சாத்தியமாகது.",
- "pocket_send_feedback": "கருத்துகளைத் தெறிவிக்கவும்"
+ "manual_migration_import_button": "இப்போது இறக்கு"
};
diff --git a/browser/extensions/activity-stream/prerendered/locales/th/activity-stream-strings.js b/browser/extensions/activity-stream/prerendered/locales/th/activity-stream-strings.js
index cbc4cc05d739..c30b6f721d34 100644
--- a/browser/extensions/activity-stream/prerendered/locales/th/activity-stream-strings.js
+++ b/browser/extensions/activity-stream/prerendered/locales/th/activity-stream-strings.js
@@ -67,7 +67,7 @@ window.gActivityStreamStrings = {
"settings_pane_snippets_header": "ส่วนย่อย",
"settings_pane_snippets_body": "อ่านข้อมูลอัปเดตที่สั้นและไพเราะจาก Mozilla เกี่ยวกับ Firefox, วัฒนธรรมอินเทอร์เน็ต และมีมแบบสุ่มเป็นครั้งคราว",
"settings_pane_done_button": "เสร็จสิ้น",
- "settings_pane_topstories_options_sponsored": "Show Sponsored Stories",
+ "settings_pane_topstories_options_sponsored": "แสดงเรื่องราวที่ได้รับการสนับสนุน",
"edit_topsites_button_text": "แก้ไข",
"edit_topsites_button_label": "ปรับแต่งส่วนไซต์เด่นของคุณ",
"edit_topsites_showmore_button": "แสดงเพิ่มเติม",
diff --git a/browser/extensions/activity-stream/prerendered/locales/tl/activity-stream-strings.js b/browser/extensions/activity-stream/prerendered/locales/tl/activity-stream-strings.js
index 3755eccc73f2..b65ea4741d29 100644
--- a/browser/extensions/activity-stream/prerendered/locales/tl/activity-stream-strings.js
+++ b/browser/extensions/activity-stream/prerendered/locales/tl/activity-stream-strings.js
@@ -38,9 +38,9 @@ window.gActivityStreamStrings = {
"section_info_option": "Impormasyon",
"section_info_send_feedback": "Magbigay ng Feedback",
"section_info_privacy_notice": "Abiso sa Privacy",
- "section_disclaimer_topstories": "The most interesting stories on the web, selected based on what you read. From Pocket, now part of Mozilla.",
- "section_disclaimer_topstories_linktext": "Learn how it works.",
- "section_disclaimer_topstories_buttontext": "Okay, got it",
+ "section_disclaimer_topstories": "Ang pinaka-kagiliw-giliw na mga kwento sa web, pinili batay sa kung ano ang iyong nabasa. Mula sa Pocket, bahagi na ngayon ng Mozilla.",
+ "section_disclaimer_topstories_linktext": "Alamin kung paano ito gumagana.",
+ "section_disclaimer_topstories_buttontext": "Sige, nakuha ko",
"welcome_title": "Maligayang pagdating sa bagong tab",
"welcome_body": "Firefox ay gagamit ng puwang upang ipakita ang iyong mga pinaka-kaugnay na bookmark, artikulo, video, at mga pahina ng kamakailan na iyong binisita, kaya maaari kang bumalik sa mga ito ng madali.",
"welcome_label": "Ang pagkilala sa iyong Highlights",
@@ -67,7 +67,7 @@ window.gActivityStreamStrings = {
"settings_pane_snippets_header": "Mga snippet",
"settings_pane_snippets_body": "Magbasa ng maikli at matamis na mga update mula sa Mozilla tungkol sa Firefox, kultura sa internet, at paminsan-minsang random na meme.",
"settings_pane_done_button": "Tapos",
- "settings_pane_topstories_options_sponsored": "Show Sponsored Stories",
+ "settings_pane_topstories_options_sponsored": "Ipakita ang Mga Na-sponsor na Kuwento",
"edit_topsites_button_text": "I-edit",
"edit_topsites_button_label": "I-customize ang iyong Tuktok na mga seksyon ng Sites",
"edit_topsites_showmore_button": "Magpakita ng higit pa",
diff --git a/browser/extensions/activity-stream/test/unit/lib/NewTabInit.test.js b/browser/extensions/activity-stream/test/unit/lib/NewTabInit.test.js
index 51ba91a891fd..8a17b8d87940 100644
--- a/browser/extensions/activity-stream/test/unit/lib/NewTabInit.test.js
+++ b/browser/extensions/activity-stream/test/unit/lib/NewTabInit.test.js
@@ -19,50 +19,6 @@ describe("NewTabInit", () => {
const resp = ac.SendToContent({type: at.NEW_TAB_INITIAL_STATE, data: STATE}, 123);
assert.calledWith(store.dispatch, resp);
});
- describe("about:home search auto focus", () => {
- let action;
- beforeEach(() => {
- STATE.Prefs = {
- values: {
- "aboutHome.autoFocus": true,
- "showSearch": true
- }
- };
- action = {
- type: at.NEW_TAB_INIT,
- data: {
- url: "about:home",
- browser: {focus: sinon.spy()}
- }
- };
- });
- it("should focus the content browser when NEW_TAB_INIT", () => {
- instance.onAction(action);
-
- assert.calledOnce(action.data.browser.focus);
- });
- it("should NOT focus the content browser when NEW_TAB_INIT for about:newtab", () => {
- action.data.url = "about:newtab";
-
- instance.onAction(action);
-
- assert.notCalled(action.data.browser.focus);
- });
- it("should NOT focus the content browser when NEW_TAB_INIT when autoFocus pref is off", () => {
- STATE.Prefs.values["aboutHome.autoFocus"] = false;
-
- instance.onAction(action);
-
- assert.notCalled(action.data.browser.focus);
- });
- it("should NOT focus the content browser when NEW_TAB_INIT when there's no search", () => {
- STATE.Prefs.values.showSearch = false;
-
- instance.onAction(action);
-
- assert.notCalled(action.data.browser.focus);
- });
- });
describe("early / simulated new tabs", () => {
const simulateTabInit = portID => instance.onAction({
type: at.NEW_TAB_INIT,
diff --git a/browser/extensions/activity-stream/test/unit/lib/SnippetsFeed.test.js b/browser/extensions/activity-stream/test/unit/lib/SnippetsFeed.test.js
index c892ea4d9262..4a3632359916 100644
--- a/browser/extensions/activity-stream/test/unit/lib/SnippetsFeed.test.js
+++ b/browser/extensions/activity-stream/test/unit/lib/SnippetsFeed.test.js
@@ -88,6 +88,15 @@ describe("SnippetsFeed", () => {
assert.calledWith(feed.store.dispatch, ac.BroadcastToContent({type: at.SNIPPETS_RESET}));
});
+ it("should broadcast a SNIPPET_BLOCKED when a SNIPPETS_BLOCKLIST_UPDATED is received", () => {
+ const feed = new SnippetsFeed();
+ feed.store = {dispatch: sandbox.stub()};
+ const blockList = ["foo", "bar", "baz"];
+
+ feed.onAction({type: at.SNIPPETS_BLOCKLIST_UPDATED, data: blockList});
+
+ assert.calledWith(feed.store.dispatch, ac.BroadcastToContent({type: at.SNIPPET_BLOCKED, data: blockList}));
+ });
it("should dispatch an update event when the Search observer is called", async () => {
const feed = new SnippetsFeed();
feed.store = {dispatch: sandbox.stub()};
diff --git a/browser/extensions/activity-stream/test/unit/lib/TelemetryFeed.test.js b/browser/extensions/activity-stream/test/unit/lib/TelemetryFeed.test.js
index 156925062104..493bbd3afcfa 100644
--- a/browser/extensions/activity-stream/test/unit/lib/TelemetryFeed.test.js
+++ b/browser/extensions/activity-stream/test/unit/lib/TelemetryFeed.test.js
@@ -132,7 +132,7 @@ describe("TelemetryFeed", () => {
const session2 = instance.addSession("foo", "about:home");
- assert.propertyNotVal(session2.perf, "load_trigger_type",
+ assert.notPropertyVal(session2.perf, "load_trigger_type",
"first_window_opened");
});
it("should set load_trigger_ts to the value of perfService.timeOrigin", () => {
diff --git a/browser/extensions/formautofill/FormAutofillHandler.jsm b/browser/extensions/formautofill/FormAutofillHandler.jsm
index 9787c693475f..2b1490952645 100644
--- a/browser/extensions/formautofill/FormAutofillHandler.jsm
+++ b/browser/extensions/formautofill/FormAutofillHandler.jsm
@@ -411,7 +411,7 @@ class FormAutofillSection {
this.changeFieldState(fieldDetail, FIELD_STATES.AUTO_FILLED);
}
if (fieldDetail.state == FIELD_STATES.AUTO_FILLED) {
- element.addEventListener("input", this);
+ element.addEventListener("input", this, {mozSystemGroup: true});
}
}
}
@@ -513,8 +513,8 @@ class FormAutofillSection {
element instanceof Ci.nsIDOMHTMLInputElement) {
element.setUserInput("");
}
- this.changeFieldState(fieldDetail, FIELD_STATES.NORMAL);
}
+ this.resetFieldStates();
}
/**
@@ -557,7 +557,7 @@ class FormAutofillSection {
resetFieldStates() {
for (let fieldDetail of this._validDetails) {
const element = fieldDetail.elementWeakRef.get();
- element.removeEventListener("input", this);
+ element.removeEventListener("input", this, {mozSystemGroup: true});
this.changeFieldState(fieldDetail, FIELD_STATES.NORMAL);
}
this.address.filledRecordGUID = null;
@@ -750,7 +750,7 @@ class FormAutofillSection {
if (!targetSet.fieldDetails.some(detail => detail.state == FIELD_STATES.AUTO_FILLED)) {
targetSet.filledRecordGUID = null;
}
- target.removeEventListener("input", this);
+ target.removeEventListener("input", this, {mozSystemGroup: true});
break;
}
}
@@ -876,7 +876,7 @@ class FormAutofillHandler {
if (!input) {
continue;
}
- input.addEventListener("input", this);
+ input.addEventListener("input", this, {mozSystemGroup: true});
}
this.fieldDetails = allValidDetails;
@@ -954,16 +954,16 @@ class FormAutofillHandler {
}
// Unregister listeners once no field is in AUTO_FILLED state.
if (!this.hasFilledSection()) {
- this.form.rootElement.removeEventListener("input", onChangeHandler);
- this.form.rootElement.removeEventListener("reset", onChangeHandler);
+ this.form.rootElement.removeEventListener("input", onChangeHandler, {mozSystemGroup: true});
+ this.form.rootElement.removeEventListener("reset", onChangeHandler, {mozSystemGroup: true});
}
};
if (noFilledSectionsPreviously) {
// Handle the highlight style resetting caused by user's correction afterward.
log.debug("register change handler for filled form:", this.form);
- this.form.rootElement.addEventListener("input", onChangeHandler);
- this.form.rootElement.addEventListener("reset", onChangeHandler);
+ this.form.rootElement.addEventListener("input", onChangeHandler, {mozSystemGroup: true});
+ this.form.rootElement.addEventListener("reset", onChangeHandler, {mozSystemGroup: true});
}
}
@@ -979,7 +979,7 @@ class FormAutofillHandler {
if (!input) {
continue;
}
- input.removeEventListener("input", this);
+ input.removeEventListener("input", this, {mozSystemGroup: true});
}
this.timeStartedFillingMS = Date.now();
break;
diff --git a/browser/modules/ContentLinkHandler.jsm b/browser/modules/ContentLinkHandler.jsm
index 97c67cd05b28..5e889d6a1737 100644
--- a/browser/modules/ContentLinkHandler.jsm
+++ b/browser/modules/ContentLinkHandler.jsm
@@ -28,6 +28,9 @@ const SIZES_TELEMETRY_ENUM = {
const FAVICON_PARSING_TIMEOUT = 100;
const FAVICON_RICH_ICON_MIN_WIDTH = 96;
+const TYPE_ICO = "image/x-icon";
+const TYPE_SVG = "image/svg+xml";
+
/*
* Create a nsITimer.
*
@@ -120,10 +123,27 @@ function setIconForLink(aIconInfo, aChromeGlobal) {
}
/**
- * Checks whether the icon info represents an ICO image.
+ * Guess a type for an icon based on its declared type or file extension.
*/
-function isICO(icon) {
- return icon.type == "image/x-icon" || icon.type == "image/vnd.microsoft.icon";
+function guessType(icon) {
+ // No type with no icon
+ if (!icon) {
+ return "";
+ }
+
+ // Use the file extension to guess at a type we're interested in
+ if (!icon.type) {
+ let extension = icon.iconUri.filePath.split(".").pop();
+ switch (extension) {
+ case "ico":
+ return TYPE_ICO;
+ case "svg":
+ return TYPE_SVG;
+ }
+ }
+
+ // Fuzzily prefer the type or fall back to the declared type
+ return icon.type == "image/vnd.microsoft.icon" ? TYPE_ICO : icon.type || "";
}
/*
@@ -142,9 +162,7 @@ function faviconTimeoutCallback(aFaviconLoads, aPageUrl, aChromeGlobal) {
if (!load)
return;
- let preferredIcon = {
- type: null
- };
+ let preferredIcon;
let preferredWidth = 16 * Math.ceil(aChromeGlobal.content.devicePixelRatio);
// Other links with the "icon" tag are the default icons
let defaultIcon;
@@ -157,11 +175,11 @@ function faviconTimeoutCallback(aFaviconLoads, aPageUrl, aChromeGlobal) {
// First check for svg. If it's not available check for an icon with a
// size adapt to the current resolution. If both are not available, prefer
// ico files. When multiple icons are in the same set, the latest wins.
- if (icon.type == "image/svg+xml") {
+ if (guessType(icon) == TYPE_SVG) {
preferredIcon = icon;
- } else if (icon.width == preferredWidth && preferredIcon.type != "image/svg+xml") {
+ } else if (icon.width == preferredWidth && guessType(preferredIcon) != TYPE_SVG) {
preferredIcon = icon;
- } else if (isICO(icon) && (preferredIcon.type == null || isICO(preferredIcon))) {
+ } else if (guessType(icon) == TYPE_ICO && (!preferredIcon || guessType(preferredIcon) == TYPE_ICO)) {
preferredIcon = icon;
}
}
@@ -185,7 +203,7 @@ function faviconTimeoutCallback(aFaviconLoads, aPageUrl, aChromeGlobal) {
if (largestRichIcon) {
setIconForLink(largestRichIcon, aChromeGlobal);
}
- if (preferredIcon.type) {
+ if (preferredIcon) {
setIconForLink(preferredIcon, aChromeGlobal);
} else if (defaultIcon) {
setIconForLink(defaultIcon, aChromeGlobal);
diff --git a/devtools/client/framework/devtools-browser.js b/devtools/client/framework/devtools-browser.js
index 0d73a0b72803..286780a50e32 100644
--- a/devtools/client/framework/devtools-browser.js
+++ b/devtools/client/framework/devtools-browser.js
@@ -376,9 +376,8 @@ var gDevToolsBrowser = exports.gDevToolsBrowser = {
if (processId) {
return this._getContentProcessTarget(processId)
.then(target => {
- // Display a new toolbox, in a new window, with debugger by default
- return gDevTools.showToolbox(target, "jsdebugger",
- Toolbox.HostType.WINDOW);
+ // Display a new toolbox in a new window
+ return gDevTools.showToolbox(target, null, Toolbox.HostType.WINDOW);
});
}
diff --git a/dom/animation/test/css-animations/file_animations-dynamic-changes.html b/dom/animation/test/css-animations/file_animations-dynamic-changes.html
index 8f16536ae98d..4075ad2978ad 100644
--- a/dom/animation/test/css-animations/file_animations-dynamic-changes.html
+++ b/dom/animation/test/css-animations/file_animations-dynamic-changes.html
@@ -26,7 +26,7 @@ promise_test(function(t) {
// Wait a moment so we can confirm the startTime doesn't change (and
// doesn't simply reflect the current time).
- return waitForFrame();
+ return waitForNextFrame();
}).then(function() {
div.style.animationDuration = '200s';
var animation = div.getAnimations()[0];
diff --git a/dom/base/CustomElementRegistry.cpp b/dom/base/CustomElementRegistry.cpp
index adf0be83bcc5..f22fa97cc7af 100644
--- a/dom/base/CustomElementRegistry.cpp
+++ b/dom/base/CustomElementRegistry.cpp
@@ -18,6 +18,57 @@
namespace mozilla {
namespace dom {
+//-----------------------------------------------------
+// CustomElementUpgradeReaction
+
+class CustomElementUpgradeReaction final : public CustomElementReaction
+{
+public:
+ explicit CustomElementUpgradeReaction(CustomElementDefinition* aDefinition)
+ : mDefinition(aDefinition)
+ {
+#if DEBUG
+ mIsUpgradeReaction = true;
+#endif
+ }
+
+private:
+ virtual void Invoke(Element* aElement, ErrorResult& aRv) override
+ {
+ CustomElementRegistry::Upgrade(aElement, mDefinition, aRv);
+ }
+
+ CustomElementDefinition* mDefinition;
+};
+
+//-----------------------------------------------------
+// CustomElementCallbackReaction
+
+class CustomElementCallbackReaction final : public CustomElementReaction
+{
+ public:
+ explicit CustomElementCallbackReaction(UniquePtr aCustomElementCallback)
+ : mCustomElementCallback(Move(aCustomElementCallback))
+ {
+ }
+
+ virtual void Traverse(nsCycleCollectionTraversalCallback& aCb) const override
+ {
+ mCustomElementCallback->Traverse(aCb);
+ }
+
+ private:
+ virtual void Invoke(Element* aElement, ErrorResult& aRv) override
+ {
+ mCustomElementCallback->Call();
+ }
+
+ UniquePtr mCustomElementCallback;
+};
+
+//-----------------------------------------------------
+// CustomElementCallback
+
void
CustomElementCallback::Call()
{
@@ -88,6 +139,7 @@ CustomElementConstructor::Construct(const char* aExecutionReason,
return element.forget();
}
+
//-----------------------------------------------------
// CustomElementData
@@ -1120,24 +1172,5 @@ CustomElementDefinition::CustomElementDefinition(nsAtom* aType,
{
}
-
-//-----------------------------------------------------
-// CustomElementUpgradeReaction
-
-/* virtual */ void
-CustomElementUpgradeReaction::Invoke(Element* aElement, ErrorResult& aRv)
-{
- CustomElementRegistry::Upgrade(aElement, mDefinition, aRv);
-}
-
-//-----------------------------------------------------
-// CustomElementCallbackReaction
-
-/* virtual */ void
-CustomElementCallbackReaction::Invoke(Element* aElement, ErrorResult& aRv)
-{
- mCustomElementCallback->Call();
-}
-
} // namespace dom
} // namespace mozilla
diff --git a/dom/base/CustomElementRegistry.h b/dom/base/CustomElementRegistry.h
index a5aaa1305ffb..d91485fc1f6b 100644
--- a/dom/base/CustomElementRegistry.h
+++ b/dom/base/CustomElementRegistry.h
@@ -209,41 +209,6 @@ protected:
#endif
};
-class CustomElementUpgradeReaction final : public CustomElementReaction
-{
-public:
- explicit CustomElementUpgradeReaction(CustomElementDefinition* aDefinition)
- : mDefinition(aDefinition)
- {
-#if DEBUG
- mIsUpgradeReaction = true;
-#endif
- }
-
-private:
- virtual void Invoke(Element* aElement, ErrorResult& aRv) override;
-
- CustomElementDefinition* mDefinition;
-};
-
-class CustomElementCallbackReaction final : public CustomElementReaction
-{
- public:
- explicit CustomElementCallbackReaction(UniquePtr aCustomElementCallback)
- : mCustomElementCallback(Move(aCustomElementCallback))
- {
- }
-
- virtual void Traverse(nsCycleCollectionTraversalCallback& aCb) const override
- {
- mCustomElementCallback->Traverse(aCb);
- }
-
- private:
- virtual void Invoke(Element* aElement, ErrorResult& aRv) override;
- UniquePtr mCustomElementCallback;
-};
-
// https://html.spec.whatwg.org/multipage/scripting.html#custom-element-reactions-stack
class CustomElementReactionsStack
{
diff --git a/dom/base/nsRange.cpp b/dom/base/nsRange.cpp
index 29e742164b0a..02ac0772baf1 100644
--- a/dom/base/nsRange.cpp
+++ b/dom/base/nsRange.cpp
@@ -200,9 +200,9 @@ nsRange::IsNodeSelected(nsINode* aNode, uint32_t aStartOffset,
NS_ASSERTION(n || !aNode->IsSelectionDescendant(),
"orphan selection descendant");
- // Collect the potential ranges and their selection objects.
- RangeHashTable ancestorSelectionRanges;
+ // Collect the selection objects for potential ranges.
nsTHashtable> ancestorSelections;
+ Selection* prevSelection = nullptr;
uint32_t maxRangeCount = 0;
for (; n; n = GetNextRangeCommonAncestor(n->GetParentNode())) {
LinkedList* ranges = n->GetExistingCommonAncestorRanges();
@@ -213,35 +213,64 @@ nsRange::IsNodeSelected(nsINode* aNode, uint32_t aStartOffset,
MOZ_ASSERT(range->IsInSelection(),
"Why is this range registeed with a node?");
// Looks like that IsInSelection() assert fails sometimes...
- if (!range->Collapsed() && range->IsInSelection()) {
- ancestorSelectionRanges.PutEntry(range);
+ if (range->IsInSelection()) {
Selection* selection = range->mSelection;
- ancestorSelections.PutEntry(selection);
+ if (prevSelection != selection) {
+ prevSelection = selection;
+ ancestorSelections.PutEntry(selection);
+ }
maxRangeCount = std::max(maxRangeCount, selection->RangeCount());
}
}
}
- if (!ancestorSelectionRanges.IsEmpty()) {
- nsTArray sortedRanges(maxRangeCount);
+ IsItemInRangeComparator comparator = { aNode, aStartOffset, aEndOffset };
+ if (!ancestorSelections.IsEmpty()) {
for (auto iter = ancestorSelections.ConstIter(); !iter.Done(); iter.Next()) {
Selection* selection = iter.Get()->GetKey();
- // Sort the found ranges for |selection| in document order
+ // Binary search the sorted ranges in this selection.
// (Selection::GetRangeAt returns its ranges ordered).
- for (uint32_t i = 0, len = selection->RangeCount(); i < len; ++i) {
- nsRange* range = selection->GetRangeAt(i);
- if (ancestorSelectionRanges.Contains(range)) {
- sortedRanges.AppendElement(range);
+ size_t low = 0;
+ size_t high = selection->RangeCount();
+
+ while (high != low) {
+ size_t middle = low + (high - low) / 2;
+
+ const nsRange* const range = selection->GetRangeAt(middle);
+ int result = comparator(range);
+ if (result == 0) {
+ if (!range->Collapsed())
+ return true;
+
+ const nsRange* middlePlus1;
+ const nsRange* middleMinus1;
+ // if node end > start of middle+1, result = 1
+ if (middle + 1 < high &&
+ (middlePlus1 = selection->GetRangeAt(middle + 1)) &&
+ nsContentUtils::ComparePoints(
+ aNode, static_cast(aEndOffset),
+ middlePlus1->GetStartContainer(),
+ static_cast(middlePlus1->StartOffset())) > 0) {
+ result = 1;
+ // if node start < end of middle - 1, result = -1
+ } else if (middle >= 1 &&
+ (middleMinus1 = selection->GetRangeAt(middle - 1)) &&
+ nsContentUtils::ComparePoints(
+ aNode, static_cast(aStartOffset),
+ middleMinus1->GetEndContainer(),
+ static_cast(middleMinus1->EndOffset())) < 0) {
+ result = -1;
+ } else {
+ return false;
+ }
+ }
+
+ if (result < 0) {
+ high = middle;
+ } else {
+ low = middle + 1;
}
}
- MOZ_ASSERT(!sortedRanges.IsEmpty());
- // Binary search the now sorted ranges.
- IsItemInRangeComparator comparator = { aNode, aStartOffset, aEndOffset };
- size_t unused;
- if (mozilla::BinarySearchIf(sortedRanges, 0, sortedRanges.Length(), comparator, &unused)) {
- return true;
- }
- sortedRanges.ClearAndRetainStorage();
}
}
return false;
diff --git a/dom/encoding/FallbackEncoding.cpp b/dom/encoding/FallbackEncoding.cpp
index ece9d9d20106..18df6ed84048 100644
--- a/dom/encoding/FallbackEncoding.cpp
+++ b/dom/encoding/FallbackEncoding.cpp
@@ -34,6 +34,7 @@ NS_IMPL_ISUPPORTS(FallbackEncoding, nsIObserver)
FallbackEncoding* FallbackEncoding::sInstance = nullptr;
bool FallbackEncoding::sGuessFallbackFromTopLevelDomain = true;
+bool FallbackEncoding::sFallbackToUTF8ForFile = false;
FallbackEncoding::FallbackEncoding()
: mFallback(nullptr)
@@ -139,6 +140,8 @@ FallbackEncoding::Initialize()
nullptr);
Preferences::AddBoolVarCache(&sGuessFallbackFromTopLevelDomain,
"intl.charset.fallback.tld");
+ Preferences::AddBoolVarCache(&sFallbackToUTF8ForFile,
+ "intl.charset.fallback.utf8_for_file");
nsCOMPtr obs = mozilla::services::GetObserverService();
if (obs) {
diff --git a/dom/encoding/FallbackEncoding.h b/dom/encoding/FallbackEncoding.h
index 355524699572..bca12bd8d1a8 100644
--- a/dom/encoding/FallbackEncoding.h
+++ b/dom/encoding/FallbackEncoding.h
@@ -26,6 +26,11 @@ public:
*/
static bool sGuessFallbackFromTopLevelDomain;
+ /**
+ * Whether UTF-8 should be used for file URLs.
+ */
+ static bool sFallbackToUTF8ForFile;
+
/**
* Gets the locale-dependent fallback encoding for legacy HTML and plain
* text content.
diff --git a/dom/html/nsHTMLDocument.cpp b/dom/html/nsHTMLDocument.cpp
index effe2a27d8c7..5ad609c0802b 100644
--- a/dom/html/nsHTMLDocument.cpp
+++ b/dom/html/nsHTMLDocument.cpp
@@ -486,6 +486,12 @@ nsHTMLDocument::TryFallback(int32_t& aCharsetSource,
return;
aCharsetSource = kCharsetFromFallback;
+ bool isFile = false;
+ if (FallbackEncoding::sFallbackToUTF8ForFile && mDocumentURI &&
+ NS_SUCCEEDED(mDocumentURI->SchemeIs("file", &isFile)) && isFile) {
+ aEncoding = UTF_8_ENCODING;
+ return;
+ }
aEncoding = FallbackEncoding::FromLocale();
}
diff --git a/dom/html/nsHTMLDocument.h b/dom/html/nsHTMLDocument.h
index 6b58e57d68d8..e4f5becdd67d 100644
--- a/dom/html/nsHTMLDocument.h
+++ b/dom/html/nsHTMLDocument.h
@@ -362,8 +362,8 @@ protected:
int32_t& charsetSource,
NotNull& aEncoding);
void TryTLD(int32_t& aCharsetSource, NotNull& aCharset);
- static void TryFallback(int32_t& aCharsetSource,
- NotNull& aEncoding);
+ void TryFallback(int32_t& aCharsetSource,
+ NotNull& aEncoding);
// Override so we can munge the charset on our wyciwyg channel as needed.
virtual void
diff --git a/dom/media/MediaManager.cpp b/dom/media/MediaManager.cpp
index f661e6df5b29..fe050b0123aa 100644
--- a/dom/media/MediaManager.cpp
+++ b/dom/media/MediaManager.cpp
@@ -1702,20 +1702,22 @@ MediaManager::EnumerateRawDevices(uint64_t aWindowId,
}
}
+ bool hasVideo = aVideoType != MediaSourceEnum::Other;
+ bool hasAudio = aAudioType != MediaSourceEnum::Other;
+ bool fakeCams = aFake && aVideoType == MediaSourceEnum::Camera;
+ bool fakeMics = aFake && aAudioType == MediaSourceEnum::Microphone;
+ bool realDevicesRequested = (!fakeCams && hasVideo) || (!fakeMics && hasAudio);
+
RefPtr task = NewTaskFrom([id, aWindowId, audioLoopDev,
videoLoopDev, aVideoType,
- aAudioType, aFake]() mutable {
+ aAudioType, hasVideo, hasAudio,
+ fakeCams, fakeMics, realDevicesRequested]() {
// Only enumerate what's asked for, and only fake cams and mics.
- bool hasVideo = aVideoType != MediaSourceEnum::Other;
- bool hasAudio = aAudioType != MediaSourceEnum::Other;
- bool fakeCams = aFake && aVideoType == MediaSourceEnum::Camera;
- bool fakeMics = aFake && aAudioType == MediaSourceEnum::Microphone;
-
RefPtr fakeBackend, realBackend;
if (fakeCams || fakeMics) {
fakeBackend = new MediaEngineDefault();
}
- if ((!fakeCams && hasVideo) || (!fakeMics && hasAudio)) {
+ if (realDevicesRequested) {
MediaManager* manager = MediaManager::GetIfExists();
MOZ_RELEASE_ASSERT(manager); // Must exist while media thread is alive
realBackend = manager->GetBackend(aWindowId);
@@ -1758,9 +1760,7 @@ MediaManager::EnumerateRawDevices(uint64_t aWindowId,
}));
});
- if (!aFake &&
- (aVideoType == MediaSourceEnum::Camera ||
- aAudioType == MediaSourceEnum::Microphone) &&
+ if (realDevicesRequested &&
Preferences::GetBool("media.navigator.permission.device", false)) {
// Need to ask permission to retrieve list of all devices;
// notify frontend observer and wait for callback notification to post task.
@@ -2511,9 +2511,15 @@ MediaManager::GetUserMedia(nsPIDOMWindowInner* aWindow,
bool fake = c.mFake.WasPassed()? c.mFake.Value() :
Preferences::GetBool("media.navigator.streams.fake");
+ bool hasVideo = videoType != MediaSourceEnum::Other;
+ bool hasAudio = audioType != MediaSourceEnum::Other;
+ bool fakeCams = fake && videoType == MediaSourceEnum::Camera;
+ bool fakeMics = fake && audioType == MediaSourceEnum::Microphone;
+ bool realDevicesRequested = (!fakeCams && hasVideo) || (!fakeMics && hasAudio);
+
bool askPermission =
(!privileged || Preferences::GetBool("media.navigator.permission.force")) &&
- (!fake || Preferences::GetBool("media.navigator.permission.fake"));
+ (realDevicesRequested || Preferences::GetBool("media.navigator.permission.fake"));
RefPtr p = EnumerateDevicesImpl(windowID, videoType,
audioType, fake);
diff --git a/dom/media/webaudio/test/test_mediaElementAudioSourceNodeFidelity.html b/dom/media/webaudio/test/test_mediaElementAudioSourceNodeFidelity.html
index f893eb19339a..7ad053123b24 100644
--- a/dom/media/webaudio/test/test_mediaElementAudioSourceNodeFidelity.html
+++ b/dom/media/webaudio/test/test_mediaElementAudioSourceNodeFidelity.html
@@ -46,23 +46,28 @@ function checkFrequency(an) {
// We should have no energy when checking the data largely outside the index
// for 440Hz (the frequency of the sine wave), start checking an octave above,
// the Opus compression can add some harmonics to the pure since wave.
- var index = binIndexForFrequency(880, an);
- var underTreshold = true;
- for (var i = index; i < frequencyArray.length; i++) {
- // Let some slack, there might be some noise here because of int -> float
- // conversion or the Opus encoding.
- if (frequencyArray[i] > an.minDecibels + 40) {
- return false;
+ var maxNoiseIndex = binIndexForFrequency(880, an);
+ for (var i = maxNoiseIndex + 1; i < frequencyArray.length; i++) {
+ if (frequencyArray[i] > frequencyArray[maxNoiseIndex]) {
+ maxNoiseIndex = i;
}
}
// On the other hand, we should find a peak at 440Hz. Our sine wave is not
// attenuated, we're expecting the peak to reach 0dBFs.
- index = binIndexForFrequency(440, an);
- info("energy at 440: " + frequencyArray[index] + ", threshold " + (an.maxDecibels - 10));
+ var index = binIndexForFrequency(440, an);
+ info("energy at 440: " + frequencyArray[index] +
+ ", threshold " + (an.maxDecibels - 10) +
+ "; max noise at index " + maxNoiseIndex +
+ ": " + frequencyArray[maxNoiseIndex] );
if (frequencyArray[index] < (an.maxDecibels - 10)) {
return false;
}
+ // Let some slack, there might be some noise here because of int -> float
+ // conversion or the Opus encoding.
+ if (frequencyArray[maxNoiseIndex] > an.minDecibels + 40) {
+ return false;
+ }
return true;
}
@@ -73,6 +78,10 @@ audioElement.loop = true;
var ac = new AudioContext();
var mediaElementSource = ac.createMediaElementSource(audioElement);
var an = ac.createAnalyser();
+// Use no smoothing as this would just average with previous
+// getFloatFrequencyData() calls. Non-seamless looping would introduce noise,
+// and smoothing would spread this into calls after the loop point.
+an.smoothingTimeConstant = 0;
frequencyArray = new Float32Array(an.frequencyBinCount);
// Uncomment this to check what the analyser is doing.
diff --git a/gfx/layers/apz/src/AsyncPanZoomController.cpp b/gfx/layers/apz/src/AsyncPanZoomController.cpp
index 07a4ff4f2398..36e05f61246f 100644
--- a/gfx/layers/apz/src/AsyncPanZoomController.cpp
+++ b/gfx/layers/apz/src/AsyncPanZoomController.cpp
@@ -907,7 +907,12 @@ nsEventStatus AsyncPanZoomController::HandleDragEvent(const MouseInput& aEvent,
return nsEventStatus_eConsumeNoDefault;
}
+ if (aEvent.mType == MouseInput::MouseType::MOUSE_DOWN) {
+ SetState(SCROLLBAR_DRAG);
+ }
+
if (aEvent.mType == MouseInput::MouseType::MOUSE_UP) {
+ SetState(NOTHING);
ScrollSnap();
}
@@ -1148,6 +1153,7 @@ nsEventStatus AsyncPanZoomController::OnTouchStart(const MultiTouchInput& aEvent
MOZ_ASSERT(GetCurrentTouchBlock());
GetCurrentTouchBlock()->GetOverscrollHandoffChain()->CancelAnimations(ExcludeOverscroll);
MOZ_FALLTHROUGH;
+ case SCROLLBAR_DRAG:
case NOTHING: {
mX.StartTouch(point.x, aEvent.mTime);
mY.StartTouch(point.y, aEvent.mTime);
@@ -1222,6 +1228,7 @@ nsEventStatus AsyncPanZoomController::OnTouchMove(const MultiTouchInput& aEvent)
case KEYBOARD_SCROLL:
case OVERSCROLL_ANIMATION:
case AUTOSCROLL:
+ case SCROLLBAR_DRAG:
// Should not receive a touch-move in the OVERSCROLL_ANIMATION state
// as touch blocks that begin in an overscrolled state cancel the
// animation. The same is true for wheel scroll animations.
@@ -1304,6 +1311,7 @@ nsEventStatus AsyncPanZoomController::OnTouchEnd(const MultiTouchInput& aEvent)
case KEYBOARD_SCROLL:
case OVERSCROLL_ANIMATION:
case AUTOSCROLL:
+ case SCROLLBAR_DRAG:
// Should not receive a touch-end in the OVERSCROLL_ANIMATION state
// as touch blocks that begin in an overscrolled state cancel the
// animation. The same is true for WHEEL_SCROLL.
diff --git a/gfx/layers/apz/src/AsyncPanZoomController.h b/gfx/layers/apz/src/AsyncPanZoomController.h
index cb581e290e16..dc6fe79a4f43 100644
--- a/gfx/layers/apz/src/AsyncPanZoomController.h
+++ b/gfx/layers/apz/src/AsyncPanZoomController.h
@@ -928,7 +928,8 @@ protected:
CSSOM-View smooth scroll-behavior */
WHEEL_SCROLL, /* Smooth scrolling to a destination for a wheel event. */
KEYBOARD_SCROLL, /* Smooth scrolling to a destination for a keyboard event. */
- AUTOSCROLL /* Autoscroll animation. */
+ AUTOSCROLL, /* Autoscroll animation. */
+ SCROLLBAR_DRAG /* Async scrollbar drag. */
};
// This is in theory protected by |mRecursiveMutex|; that is, it should be held whenever
// this is updated. In practice though... see bug 897017.
diff --git a/js/xpconnect/src/nsXPConnect.cpp b/js/xpconnect/src/nsXPConnect.cpp
index 93a7dcefc1fb..b30bb72d10ec 100644
--- a/js/xpconnect/src/nsXPConnect.cpp
+++ b/js/xpconnect/src/nsXPConnect.cpp
@@ -1132,13 +1132,6 @@ JS_EXPORT_API(void) DumpJSStack()
xpc_DumpJSStack(true, true, false);
}
-JS_EXPORT_API(const char*) PrintJSStack()
-{
- if (JSContext* cx = nsContentUtils::GetCurrentJSContext())
- return xpc_PrintJSStack(cx, true, true, false).release();
- return "There is no JSContext on the stack.\n";
-}
-
JS_EXPORT_API(void) DumpCompleteHeap()
{
nsCOMPtr listener =
diff --git a/layout/generic/nsGfxScrollFrame.cpp b/layout/generic/nsGfxScrollFrame.cpp
index 030a1fc49cd8..4ec60b42f4dc 100644
--- a/layout/generic/nsGfxScrollFrame.cpp
+++ b/layout/generic/nsGfxScrollFrame.cpp
@@ -3650,8 +3650,8 @@ ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder* aBuilder,
CompositorHitTestInfo info = CompositorHitTestInfo::eVisibleToHitTest
| CompositorHitTestInfo::eDispatchToContent;
nsDisplayCompositorHitTestInfo* hitInfo =
- new (aBuilder) nsDisplayCompositorHitTestInfo(aBuilder, mScrolledFrame, info, 1);
- hitInfo->SetArea(mScrollPort + aBuilder->ToReferenceFrame(mOuter));
+ new (aBuilder) nsDisplayCompositorHitTestInfo(aBuilder, mScrolledFrame, info, 1,
+ Some(mScrollPort + aBuilder->ToReferenceFrame(mOuter)));
AppendInternalItemToTop(scrolledContent, hitInfo, zIndex);
}
if (aBuilder->IsBuildingLayerEventRegions()) {
diff --git a/layout/painting/nsDisplayList.cpp b/layout/painting/nsDisplayList.cpp
index 6c3f41fd60a8..03d45c391476 100644
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -4944,7 +4944,8 @@ nsDisplayEventReceiver::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder&
nsDisplayCompositorHitTestInfo::nsDisplayCompositorHitTestInfo(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame,
mozilla::gfx::CompositorHitTestInfo aHitTestInfo,
- uint32_t aIndex)
+ uint32_t aIndex,
+ const mozilla::Maybe& aArea)
: nsDisplayEventReceiver(aBuilder, aFrame)
, mHitTestInfo(aHitTestInfo)
, mIndex(aIndex)
@@ -4962,12 +4963,29 @@ nsDisplayCompositorHitTestInfo::nsDisplayCompositorHitTestInfo(nsDisplayListBuil
MOZ_ASSERT(mHitTestInfo & CompositorHitTestInfo::eScrollbar);
mScrollTarget = Some(aBuilder->GetCurrentScrollbarTarget());
}
-}
-void
-nsDisplayCompositorHitTestInfo::SetArea(const nsRect& aArea)
-{
- mArea = Some(aArea);
+ if (aArea.isSome()) {
+ mArea = *aArea;
+ } else {
+ nsIScrollableFrame* scrollFrame = nsLayoutUtils::GetScrollableFrameFor(mFrame);
+ if (scrollFrame) {
+ // If the frame is content of a scrollframe, then we need to pick up the
+ // area corresponding to the overflow rect as well. Otherwise the parts of
+ // the overflow that are not occupied by descendants get skipped and the
+ // APZ code sends touch events to the content underneath instead.
+ // See https://bugzilla.mozilla.org/show_bug.cgi?id=1127773#c15.
+ mArea = mFrame->GetScrollableOverflowRect();
+ } else {
+ mArea = nsRect(nsPoint(0, 0), mFrame->GetSize());
+ }
+
+ // Note that it's important to do this call to ToReferenceFrame here in the
+ // nsDisplayCompositorHitTestInfo constructor, because then we'll hit the good
+ // fast path (because aBuilder will already have the info we want cached).
+ // This is as opposed to, say, calling it in CreateWebRenderCommands where
+ // we would not hit the fast path.
+ mArea += aBuilder->ToReferenceFrame(mFrame);
+ }
}
bool
@@ -4977,31 +4995,13 @@ nsDisplayCompositorHitTestInfo::CreateWebRenderCommands(mozilla::wr::DisplayList
mozilla::layers::WebRenderLayerManager* aManager,
nsDisplayListBuilder* aDisplayListBuilder)
{
- if (mArea.isNothing()) {
- nsRect borderBox;
- nsIScrollableFrame* scrollFrame = nsLayoutUtils::GetScrollableFrameFor(mFrame);
- if (scrollFrame) {
- // If the frame is content of a scrollframe, then we need to pick up the
- // area corresponding to the overflow rect as well. Otherwise the parts of
- // the overflow that are not occupied by descendants get skipped and the
- // APZ code sends touch events to the content underneath instead.
- // See https://bugzilla.mozilla.org/show_bug.cgi?id=1127773#c15.
- borderBox = mFrame->GetScrollableOverflowRect();
- } else {
- borderBox = nsRect(nsPoint(0, 0), mFrame->GetSize());
- }
-
- if (borderBox.IsEmpty()) {
- return true;
- }
-
- mArea = Some(borderBox + aDisplayListBuilder->ToReferenceFrame(mFrame));
+ if (mArea.IsEmpty()) {
+ return true;
}
- MOZ_ASSERT(mArea.isSome());
wr::LayoutRect rect = aSc.ToRelativeLayoutRect(
LayoutDeviceRect::FromAppUnits(
- *mArea,
+ mArea,
mFrame->PresContext()->AppUnitsPerDevPixel()));
// XXX: eventually this scrollId computation and the SetHitTestInfo
diff --git a/layout/painting/nsDisplayList.h b/layout/painting/nsDisplayList.h
index 69f939680095..13653ee87f6a 100644
--- a/layout/painting/nsDisplayList.h
+++ b/layout/painting/nsDisplayList.h
@@ -4358,7 +4358,8 @@ class nsDisplayCompositorHitTestInfo : public nsDisplayEventReceiver {
public:
nsDisplayCompositorHitTestInfo(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
mozilla::gfx::CompositorHitTestInfo aHitTestInfo,
- uint32_t aIndex = 0);
+ uint32_t aIndex = 0,
+ const mozilla::Maybe& aArea = mozilla::Nothing());
#ifdef NS_BUILD_REFCNT_LOGGING
virtual ~nsDisplayCompositorHitTestInfo()
@@ -4368,7 +4369,6 @@ public:
#endif
mozilla::gfx::CompositorHitTestInfo HitTestInfo() const { return mHitTestInfo; }
- void SetArea(const nsRect& aArea);
bool CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
mozilla::wr::IpcResourceUpdateQueue& aResources,
@@ -4385,7 +4385,7 @@ public:
private:
mozilla::gfx::CompositorHitTestInfo mHitTestInfo;
mozilla::Maybe mScrollTarget;
- mozilla::Maybe mArea;
+ nsRect mArea;
uint32_t mIndex;
mozilla::Maybe mOverrideZIndex;
};
diff --git a/layout/printing/DrawEventRecorder.cpp b/layout/printing/DrawEventRecorder.cpp
index b552d747617d..9915527d02b1 100644
--- a/layout/printing/DrawEventRecorder.cpp
+++ b/layout/printing/DrawEventRecorder.cpp
@@ -19,12 +19,6 @@ DrawEventRecorderPRFileDesc::RecordEvent(const gfx::RecordedEvent& aEvent)
Flush();
}
-DrawEventRecorderPRFileDesc::DrawEventRecorderPRFileDesc(const char* aFilename)
-{
- mOutputStream.Open(aFilename);
- WriteHeader(mOutputStream);
-}
-
DrawEventRecorderPRFileDesc::~DrawEventRecorderPRFileDesc()
{
if (IsOpen()) {
@@ -45,11 +39,11 @@ DrawEventRecorderPRFileDesc::IsOpen()
}
void
-DrawEventRecorderPRFileDesc::OpenNew(const char* aFilename)
+DrawEventRecorderPRFileDesc::OpenFD(PRFileDesc* aFd)
{
MOZ_ASSERT(!IsOpen());
- mOutputStream.Open(aFilename);
+ mOutputStream.OpenFD(aFd);
WriteHeader(mOutputStream);
}
diff --git a/layout/printing/DrawEventRecorder.h b/layout/printing/DrawEventRecorder.h
index 3672c843d67f..fd46d28906ba 100644
--- a/layout/printing/DrawEventRecorder.h
+++ b/layout/printing/DrawEventRecorder.h
@@ -25,9 +25,10 @@ public:
PRFileDescStream() : mFd(nullptr), mBuffer(nullptr), mBufferPos(0),
mGood(true) {}
- void Open(const char* aFilename) {
+ void OpenFD(PRFileDesc* aFd)
+ {
MOZ_ASSERT(!IsOpen());
- mFd = PR_Open(aFilename, PR_RDWR | PR_CREATE_FILE, PR_IRUSR | PR_IWUSR);
+ mFd = aFd;
mGood = true;
mBuffer.reset(new uint8_t[kBufferSize]);
mBufferPos = 0;
@@ -118,7 +119,7 @@ class DrawEventRecorderPRFileDesc : public gfx::DrawEventRecorderPrivate
{
public:
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawEventRecorderPRFileDesc, override)
- explicit DrawEventRecorderPRFileDesc(const char* aFilename);
+ explicit DrawEventRecorderPRFileDesc(){};
~DrawEventRecorderPRFileDesc();
void RecordEvent(const gfx::RecordedEvent& aEvent) override;
@@ -129,11 +130,9 @@ public:
bool IsOpen();
/**
- * Opens new file with the provided name. The recorder does NOT forget which
- * objects it has recorded. This can be used with Close, so that a recording
- * can be processed in chunks. The file must not already be open.
+ * Opens the recorder with the provided PRFileDesc *.
*/
- void OpenNew(const char* aFilename);
+ void OpenFD(PRFileDesc* aFd);
/**
* Closes the file so that it can be processed. The recorder does NOT forget
diff --git a/layout/printing/ipc/PRemotePrintJob.ipdl b/layout/printing/ipc/PRemotePrintJob.ipdl
index f6c1de89573a..9c9b6aa0c212 100644
--- a/layout/printing/ipc/PRemotePrintJob.ipdl
+++ b/layout/printing/ipc/PRemotePrintJob.ipdl
@@ -22,9 +22,9 @@ parent:
async InitializePrint(nsString aDocumentTitle, nsString aPrintToFile,
int32_t aStartPage, int32_t aEndPage);
- // Translate the stored page recording and play back the events to the real
- // print device.
- async ProcessPage(nsCString aPageFileName);
+ // Translate the page recording writen into |fd| and play back the events to
+ // the real print device.
+ async ProcessPage();
// This informs the real print device that we've finished, so it can trigger
// the actual print.
@@ -45,11 +45,13 @@ parent:
child:
// Inform the child that the print has been initialized in the parent or has
- // failed with result aRv.
- async PrintInitializationResult(nsresult aRv);
+ // failed with result aRv. Includes a file descriptor which the first page
+ // can be written to.
+ async PrintInitializationResult(nsresult aRv, FileDescriptor aFd);
- // Inform the child that the latest page has been processed remotely.
- async PageProcessed();
+ // Inform the child that the latest page has been processed remotely. Includes
+ // a file descriptor which the next page can be written to.
+ async PageProcessed(FileDescriptor aFd);
async __delete__();
};
diff --git a/layout/printing/ipc/RemotePrintJobChild.cpp b/layout/printing/ipc/RemotePrintJobChild.cpp
index 46cab20666c6..3d3dd5c33b59 100644
--- a/layout/printing/ipc/RemotePrintJobChild.cpp
+++ b/layout/printing/ipc/RemotePrintJobChild.cpp
@@ -9,6 +9,7 @@
#include "mozilla/Unused.h"
#include "nsPagePrintTimer.h"
#include "nsPrintEngine.h"
+#include "private/pprio.h"
namespace mozilla {
namespace layout {
@@ -36,26 +37,48 @@ RemotePrintJobChild::InitializePrint(const nsString& aDocumentTitle,
}
mozilla::ipc::IPCResult
-RemotePrintJobChild::RecvPrintInitializationResult(const nsresult& aRv)
+RemotePrintJobChild::RecvPrintInitializationResult(
+ const nsresult& aRv,
+ const mozilla::ipc::FileDescriptor& aFd)
{
mPrintInitialized = true;
mInitializationResult = aRv;
+ if (NS_SUCCEEDED(aRv)) {
+ SetNextPageFD(aFd);
+ }
return IPC_OK();
}
+PRFileDesc*
+RemotePrintJobChild::GetNextPageFD()
+{
+ MOZ_ASSERT(mNextPageFD);
+ PRFileDesc* fd = mNextPageFD;
+ mNextPageFD = nullptr;
+ return fd;
+}
+
void
-RemotePrintJobChild::ProcessPage(const nsCString& aPageFileName)
+RemotePrintJobChild::SetNextPageFD(const mozilla::ipc::FileDescriptor& aFd)
+{
+ auto handle = aFd.ClonePlatformHandle();
+ mNextPageFD = PR_ImportFile(PROsfd(handle.release()));
+}
+
+void
+RemotePrintJobChild::ProcessPage()
{
MOZ_ASSERT(mPagePrintTimer);
mPagePrintTimer->WaitForRemotePrint();
- Unused << SendProcessPage(aPageFileName);
+ Unused << SendProcessPage();
}
mozilla::ipc::IPCResult
-RemotePrintJobChild::RecvPageProcessed()
+RemotePrintJobChild::RecvPageProcessed(const mozilla::ipc::FileDescriptor& aFd)
{
MOZ_ASSERT(mPagePrintTimer);
+ SetNextPageFD(aFd);
mPagePrintTimer->RemotePrintFinished();
return IPC_OK();
diff --git a/layout/printing/ipc/RemotePrintJobChild.h b/layout/printing/ipc/RemotePrintJobChild.h
index 10bf8de9a26b..a45198c2cd56 100644
--- a/layout/printing/ipc/RemotePrintJobChild.h
+++ b/layout/printing/ipc/RemotePrintJobChild.h
@@ -34,11 +34,13 @@ public:
const int32_t& aStartPage,
const int32_t& aEndPage);
- mozilla::ipc::IPCResult RecvPrintInitializationResult(const nsresult& aRv) final;
+ mozilla::ipc::IPCResult RecvPrintInitializationResult(
+ const nsresult& aRv,
+ const FileDescriptor& aFd) final;
- void ProcessPage(const nsCString& aPageFileName);
+ void ProcessPage();
- mozilla::ipc::IPCResult RecvPageProcessed() final;
+ mozilla::ipc::IPCResult RecvPageProcessed(const FileDescriptor& aFd) final;
mozilla::ipc::IPCResult RecvAbortPrint(const nsresult& aRv) final;
@@ -46,13 +48,17 @@ public:
void SetPrintEngine(nsPrintEngine* aPrintEngine);
+ PRFileDesc* GetNextPageFD();
+
private:
~RemotePrintJobChild() final;
+ void SetNextPageFD(const mozilla::ipc::FileDescriptor& aFd);
bool mPrintInitialized = false;
nsresult mInitializationResult = NS_OK;
RefPtr mPagePrintTimer;
RefPtr mPrintEngine;
+ PRFileDesc* mNextPageFD = nullptr;
};
} // namespace layout
diff --git a/layout/printing/ipc/RemotePrintJobParent.cpp b/layout/printing/ipc/RemotePrintJobParent.cpp
index 73a349302636..d28daf44493a 100644
--- a/layout/printing/ipc/RemotePrintJobParent.cpp
+++ b/layout/printing/ipc/RemotePrintJobParent.cpp
@@ -19,6 +19,8 @@
#include "nsIPrintSettings.h"
#include "nsIWebProgressListener.h"
#include "PrintTranslator.h"
+#include "private/pprio.h"
+#include "nsAnonymousTemporaryFile.h"
namespace mozilla {
namespace layout {
@@ -38,14 +40,21 @@ RemotePrintJobParent::RecvInitializePrint(const nsString& aDocumentTitle,
nsresult rv = InitializePrintDevice(aDocumentTitle, aPrintToFile, aStartPage,
aEndPage);
if (NS_FAILED(rv)) {
- Unused << SendPrintInitializationResult(rv);
+ Unused << SendPrintInitializationResult(rv, FileDescriptor());
Unused << Send__delete__(this);
return IPC_OK();
}
mPrintTranslator.reset(new PrintTranslator(mPrintDeviceContext));
- Unused << SendPrintInitializationResult(NS_OK);
+ FileDescriptor fd;
+ rv = PrepareNextPageFD(&fd);
+ if (NS_FAILED(rv)) {
+ Unused << SendPrintInitializationResult(rv, FileDescriptor());
+ Unused << Send__delete__(this);
+ return IPC_OK();
+ }
+ Unused << SendPrintInitializationResult(NS_OK, fd);
return IPC_OK();
}
@@ -82,22 +91,49 @@ RemotePrintJobParent::InitializePrintDevice(const nsString& aDocumentTitle,
return NS_OK;
}
-mozilla::ipc::IPCResult
-RemotePrintJobParent::RecvProcessPage(const nsCString& aPageFileName)
+nsresult
+RemotePrintJobParent::PrepareNextPageFD(FileDescriptor* aFd)
{
- nsresult rv = PrintPage(aPageFileName);
+ PRFileDesc* prFd = nullptr;
+ nsresult rv = NS_OpenAnonymousTemporaryFile(&prFd);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+ *aFd = FileDescriptor(
+ FileDescriptor::PlatformHandleType(PR_FileDesc2NativeHandle(prFd)));
+ mCurrentPageStream.OpenFD(prFd);
+ return NS_OK;
+}
+
+mozilla::ipc::IPCResult
+RemotePrintJobParent::RecvProcessPage()
+{
+ if (!mCurrentPageStream.IsOpen()) {
+ Unused << SendAbortPrint(NS_ERROR_FAILURE);
+ return IPC_OK();
+ }
+ mCurrentPageStream.Seek(0, PR_SEEK_SET);
+ nsresult rv = PrintPage(mCurrentPageStream);
+ mCurrentPageStream.Close();
if (NS_FAILED(rv)) {
Unused << SendAbortPrint(rv);
- } else {
- Unused << SendPageProcessed();
+ return IPC_OK();
}
+ FileDescriptor fd;
+ rv = PrepareNextPageFD(&fd);
+ if (NS_FAILED(rv)) {
+ Unused << SendAbortPrint(rv);
+ return IPC_OK();
+ }
+
+ Unused << SendPageProcessed(fd);
return IPC_OK();
}
nsresult
-RemotePrintJobParent::PrintPage(const nsCString& aPageFileName)
+RemotePrintJobParent::PrintPage(PRFileDescStream& aRecording)
{
MOZ_ASSERT(mPrintDeviceContext);
@@ -105,29 +141,7 @@ RemotePrintJobParent::PrintPage(const nsCString& aPageFileName)
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
-
- nsCOMPtr recordingFile;
- rv = NS_GetSpecialDirectory(NS_APP_CONTENT_PROCESS_TEMP_DIR,
- getter_AddRefs(recordingFile));
- if (NS_WARN_IF(NS_FAILED(rv))) {
- return rv;
- }
-
- rv = recordingFile->AppendNative(aPageFileName);
- if (NS_WARN_IF(NS_FAILED(rv))) {
- return rv;
- }
-
- nsAutoCString recordingPath;
- rv = recordingFile->GetNativePath(recordingPath);
- if (NS_WARN_IF(NS_FAILED(rv))) {
- return rv;
- }
-
- PRFileDescStream recording;
- recording.Open(recordingPath.get());
- MOZ_ASSERT(recording.IsOpen());
- if (!mPrintTranslator->TranslateRecording(recording)) {
+ if (!mPrintTranslator->TranslateRecording(aRecording)) {
return NS_ERROR_FAILURE;
}
@@ -136,12 +150,6 @@ RemotePrintJobParent::PrintPage(const nsCString& aPageFileName)
return rv;
}
- recording.Close();
- rv = recordingFile->Remove(/* recursive= */ false);
- if (NS_WARN_IF(NS_FAILED(rv))) {
- return rv;
- }
-
return NS_OK;
}
diff --git a/layout/printing/ipc/RemotePrintJobParent.h b/layout/printing/ipc/RemotePrintJobParent.h
index 0aa88bef1f55..6013374ac63b 100644
--- a/layout/printing/ipc/RemotePrintJobParent.h
+++ b/layout/printing/ipc/RemotePrintJobParent.h
@@ -8,11 +8,13 @@
#define mozilla_layout_RemotePrintJobParent_h
#include "mozilla/layout/PRemotePrintJobParent.h"
+#include "mozilla/layout/printing/DrawEventRecorder.h"
#include "nsCOMArray.h"
#include "nsCOMPtr.h"
#include "mozilla/RefPtr.h"
#include "mozilla/UniquePtr.h"
+#include "mozilla/gfx/RecordedEvent.h"
class nsDeviceContext;
class nsIPrintSettings;
@@ -34,7 +36,7 @@ public:
const int32_t& aStartPage,
const int32_t& aEndPage) final;
- mozilla::ipc::IPCResult RecvProcessPage(const nsCString& aPageFileName) final;
+ mozilla::ipc::IPCResult RecvProcessPage() final;
mozilla::ipc::IPCResult RecvFinalizePrint() final;
@@ -70,12 +72,15 @@ private:
const int32_t& aStartPage,
const int32_t& aEndPage);
- nsresult PrintPage(const nsCString& aPageFileName);
+ nsresult PrepareNextPageFD(FileDescriptor* aFd);
+
+ nsresult PrintPage(PRFileDescStream& aRecording);
nsCOMPtr mPrintSettings;
RefPtr mPrintDeviceContext;
UniquePtr mPrintTranslator;
nsCOMArray mPrintProgressListeners;
+ PRFileDescStream mCurrentPageStream;
};
} // namespace layout
diff --git a/layout/printing/nsPagePrintTimer.cpp b/layout/printing/nsPagePrintTimer.cpp
index 2a29bc85111c..eff9c78f82c6 100644
--- a/layout/printing/nsPagePrintTimer.cpp
+++ b/layout/printing/nsPagePrintTimer.cpp
@@ -145,7 +145,8 @@ nsPagePrintTimer::Notify(nsITimer *timer)
if (mDocViewerPrint) {
bool donePrePrint = true;
- if (mPrintEngine) {
+ // Don't start to pre-print if we're waiting on the parent still.
+ if (mPrintEngine && !mWaitingForRemotePrint) {
donePrePrint = mPrintEngine->PrePrintPage();
}
diff --git a/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.cpp b/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.cpp
index e6e42dae4a40..0e3285430e53 100644
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.cpp
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.cpp
@@ -50,13 +50,6 @@ static const char* pcmLogTag = "PeerConnectionMedia";
#endif
#define LOGTAG pcmLogTag
-//XXX(pkerr) What about bitrate settings? Going with the defaults for now.
-RefPtr
-CreateCall()
-{
- return WebRtcCallWrapper::Create();
-}
-
NS_IMETHODIMP PeerConnectionMedia::ProtocolProxyQueryHandler::
OnProxyAvailable(nsICancelable *request,
nsIChannel *aChannel,
@@ -294,9 +287,6 @@ nsresult PeerConnectionMedia::Init(const std::vector& stun_serv
}
ConnectSignals(mIceCtxHdlr->ctx().get());
- // This webrtc:Call instance will be shared by audio and video media conduits.
- mCall = CreateCall();
-
return NS_OK;
}
@@ -1145,6 +1135,10 @@ PeerConnectionMedia::AddTransceiver(
dom::MediaStreamTrack* aSendTrack,
RefPtr* aTransceiverImpl)
{
+ if (!mCall) {
+ mCall = WebRtcCallWrapper::Create();
+ }
+
RefPtr transceiver = new TransceiverImpl(
mParent->GetHandle(),
aJsepTransceiver,
diff --git a/mobile/android/app/src/main/res/values-v21/integers.xml b/mobile/android/app/src/main/res/values-v21/integers.xml
new file mode 100644
index 000000000000..35d830569431
--- /dev/null
+++ b/mobile/android/app/src/main/res/values-v21/integers.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+ @drawable/icon
+
+
diff --git a/mobile/android/app/src/main/res/values/integers.xml b/mobile/android/app/src/main/res/values/integers.xml
index 867fdfacc201..9fbae2af5eb1 100644
--- a/mobile/android/app/src/main/res/values/integers.xml
+++ b/mobile/android/app/src/main/res/values/integers.xml
@@ -13,5 +13,6 @@
2
2
500
+ 0
diff --git a/mobile/android/base/AndroidManifest.xml.in b/mobile/android/base/AndroidManifest.xml.in
index e365eda611e5..5801ce4da2f0 100644
--- a/mobile/android/base/AndroidManifest.xml.in
+++ b/mobile/android/base/AndroidManifest.xml.in
@@ -142,6 +142,22 @@
+
+
+
+
+
+
+
+
diff --git a/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java b/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java
index d7031ddab1a0..21bbe0d2703a 100644
--- a/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java
+++ b/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java
@@ -435,7 +435,6 @@ public class BrowserApp extends GeckoApp
case PAGE_SHOW:
tab.loadFavicon();
break;
-
case UNSELECTED:
// We receive UNSELECTED immediately after the SELECTED listeners run
// so we are ensured that the unselectedTabEditingText has not changed.
@@ -444,6 +443,9 @@ public class BrowserApp extends GeckoApp
tab.getEditingState().copyFrom(mLastTabEditingState);
}
break;
+ case START_EDITING:
+ enterEditingMode();
+ break;
}
if (HardwareUtils.isTablet() && msg == TabEvents.SELECTED) {
diff --git a/mobile/android/base/java/org/mozilla/gecko/GeckoApp.java b/mobile/android/base/java/org/mozilla/gecko/GeckoApp.java
index 376a864f7ec7..b4dd07afd110 100644
--- a/mobile/android/base/java/org/mozilla/gecko/GeckoApp.java
+++ b/mobile/android/base/java/org/mozilla/gecko/GeckoApp.java
@@ -1411,8 +1411,10 @@ public abstract class GeckoApp extends GeckoActivity
final String passedUri = getIntentURI(intent);
- final boolean isExternalURL = passedUri != null;
- final boolean isAboutHomeURL = isExternalURL && AboutPages.isAboutHome(passedUri);
+ final boolean intentHasURL = passedUri != null;
+ final boolean isAboutHomeURL = intentHasURL && AboutPages.isAboutHome(passedUri);
+ final boolean isAssistIntent = Intent.ACTION_ASSIST.equals(action);
+ final boolean needsNewForegroundTab = intentHasURL || isAssistIntent;
// Start migrating as early as possible, can do this in
// parallel with Gecko load.
@@ -1438,14 +1440,16 @@ public abstract class GeckoApp extends GeckoActivity
handleSelectTabIntent(intent);
// External URLs and new tab from widget should always be loaded regardless of whether Gecko is
// already running.
- } else if (isExternalURL) {
+ } else if (needsNewForegroundTab) {
// Restore tabs before opening an external URL so that the new tab
// is animated properly.
Tabs.getInstance().notifyListeners(null, Tabs.TabEvents.RESTORED);
processActionViewIntent(new Runnable() {
@Override
public void run() {
- if (isAboutHomeURL) {
+ if (isAssistIntent) {
+ Tabs.getInstance().addTab(Tabs.LOADURL_START_EDITING | Tabs.LOADURL_EXTERNAL);
+ } else if (isAboutHomeURL) {
// respect the user preferences for about:home from external intent calls
loadStartupTab(Tabs.LOADURL_NEW_TAB, action);
} else {
@@ -1780,6 +1784,8 @@ public abstract class GeckoApp extends GeckoActivity
Tabs.getInstance().loadUrlWithIntentExtras(url, intent, flags);
}
});
+ } else if (Intent.ACTION_ASSIST.equals(action)) {
+ Tabs.getInstance().addTab(Tabs.LOADURL_START_EDITING | Tabs.LOADURL_EXTERNAL);
} else if (ACTION_HOMESCREEN_SHORTCUT.equals(action)) {
final GeckoBundle data = new GeckoBundle(2);
data.putString("uri", uri);
diff --git a/mobile/android/base/java/org/mozilla/gecko/Tabs.java b/mobile/android/base/java/org/mozilla/gecko/Tabs.java
index d167c0c3b89e..9607b2d63093 100644
--- a/mobile/android/base/java/org/mozilla/gecko/Tabs.java
+++ b/mobile/android/base/java/org/mozilla/gecko/Tabs.java
@@ -84,6 +84,8 @@ public class Tabs implements BundleEventListener {
public static final int LOADURL_EXTERNAL = 1 << 7;
/** Indicates the tab is the first shown after Firefox is hidden and restored. */
public static final int LOADURL_FIRST_AFTER_ACTIVITY_UNHIDDEN = 1 << 8;
+ /** Indicates that we should enter editing mode after opening the tab. */
+ public static final int LOADURL_START_EDITING = 1 << 9;
private static final long PERSIST_TABS_AFTER_MILLISECONDS = 1000 * 2;
@@ -758,7 +760,8 @@ public class Tabs implements BundleEventListener {
AUDIO_PLAYING_CHANGE,
OPENED_FROM_TABS_TRAY,
MEDIA_PLAYING_CHANGE,
- MEDIA_PLAYING_RESUME
+ MEDIA_PLAYING_RESUME,
+ START_EDITING,
}
public void notifyListeners(Tab tab, TabEvents msg) {
@@ -987,6 +990,7 @@ public class Tabs implements BundleEventListener {
boolean desktopMode = (flags & LOADURL_DESKTOP) != 0;
boolean external = (flags & LOADURL_EXTERNAL) != 0;
final boolean isFirstShownAfterActivityUnhidden = (flags & LOADURL_FIRST_AFTER_ACTIVITY_UNHIDDEN) != 0;
+ final boolean startEditing = (flags & LOADURL_START_EDITING) != 0;
data.putString("url", url);
data.putString("engine", searchEngine);
@@ -1065,26 +1069,40 @@ public class Tabs implements BundleEventListener {
selectTab(tabToSelect.getId());
}
+ if (startEditing) {
+ notifyListeners(tabToSelect, TabEvents.START_EDITING);
+ }
+
// Load favicon instantly for about:home page because it's already cached
if (AboutPages.isBuiltinIconPage(url)) {
tabToSelect.loadFavicon();
}
-
return tabToSelect;
}
/**
- * Opens a new tab and loads either about:home or, if PREFS_HOMEPAGE_FOR_EVERY_NEW_TAB is set,
- * the user's homepage.
+ * Opens a new tab and loads a page according to the user's preferences (by default about:home).
*/
@RobocopTarget
public Tab addTab() {
- return loadUrl(getHomepageForNewTab(mAppContext), Tabs.LOADURL_NEW_TAB);
+ return addTab(Tabs.LOADURL_NONE);
}
+ /**
+ * Opens a new tab and loads a page according to the user's preferences (by default about:home).
+ */
public Tab addPrivateTab() {
- return loadUrl(getHomepageForNewTab(mAppContext), Tabs.LOADURL_NEW_TAB | Tabs.LOADURL_PRIVATE);
+ return addTab(Tabs.LOADURL_PRIVATE);
+ }
+
+ /**
+ * Opens a new tab and loads a page according to the user's preferences (by default about:home).
+ *
+ * @param flags additional flags used when opening the tab
+ */
+ public Tab addTab(int flags) {
+ return loadUrl(getHomepageForNewTab(mAppContext), flags | Tabs.LOADURL_NEW_TAB);
}
/**
diff --git a/mobile/android/base/java/org/mozilla/gecko/restrictions/RestrictionProvider.java b/mobile/android/base/java/org/mozilla/gecko/restrictions/RestrictionProvider.java
index 26b9a446f2f9..e7faa3a89be5 100644
--- a/mobile/android/base/java/org/mozilla/gecko/restrictions/RestrictionProvider.java
+++ b/mobile/android/base/java/org/mozilla/gecko/restrictions/RestrictionProvider.java
@@ -38,12 +38,12 @@ public class RestrictionProvider extends BroadcastReceiver {
@Override
public void run() {
final Bundle oldRestrictions = intent.getBundleExtra(Intent.EXTRA_RESTRICTIONS_BUNDLE);
- RestrictionCache.migrateRestrictionsIfNeeded(oldRestrictions);
-
final Bundle extras = new Bundle();
-
- ArrayList entries = initRestrictions(context, oldRestrictions);
- extras.putParcelableArrayList(Intent.EXTRA_RESTRICTIONS_LIST, entries);
+ if (oldRestrictions != null) {
+ RestrictionCache.migrateRestrictionsIfNeeded(oldRestrictions);
+ ArrayList entries = initRestrictions(context, oldRestrictions);
+ extras.putParcelableArrayList(Intent.EXTRA_RESTRICTIONS_LIST, entries);
+ }
result.setResult(Activity.RESULT_OK, null, extras);
result.finish();
diff --git a/mobile/android/components/NSSDialogService.js b/mobile/android/components/NSSDialogService.js
index f71a617659cb..9e0f8e777ea1 100644
--- a/mobile/android/components/NSSDialogService.js
+++ b/mobile/android/components/NSSDialogService.js
@@ -92,8 +92,7 @@ NSSDialogs.prototype = {
], aCtx);
prompt.addCheckbox({ id: "trustSSL", label: this.getString("downloadCert.trustSSL"), checked: false })
- .addCheckbox({ id: "trustEmail", label: this.getString("downloadCert.trustEmail"), checked: false })
- .addCheckbox({ id: "trustSign", label: this.getString("downloadCert.trustObjSign"), checked: false });
+ .addCheckbox({ id: "trustEmail", label: this.getString("downloadCert.trustEmail"), checked: false });
let response = this.showPrompt(prompt);
// they hit the "view cert" button, so show the cert and try again
@@ -107,7 +106,6 @@ NSSDialogs.prototype = {
aTrust.value = Ci.nsIX509CertDB.UNTRUSTED;
if (response.trustSSL) aTrust.value |= Ci.nsIX509CertDB.TRUSTED_SSL;
if (response.trustEmail) aTrust.value |= Ci.nsIX509CertDB.TRUSTED_EMAIL;
- if (response.trustSign) aTrust.value |= Ci.nsIX509CertDB.TRUSTED_OBJSIGN;
return true;
}
},
diff --git a/mobile/android/locales/en-US/chrome/pippki.properties b/mobile/android/locales/en-US/chrome/pippki.properties
index 1102f0b00a3f..edd8a890f7e8 100644
--- a/mobile/android/locales/en-US/chrome/pippki.properties
+++ b/mobile/android/locales/en-US/chrome/pippki.properties
@@ -11,7 +11,6 @@ downloadCert.message1=You have been asked to trust a new Certificate Authority (
downloadCert.viewCert.label=View
downloadCert.trustSSL=Trust to identify websites.
downloadCert.trustEmail=Trust to identify email users.
-downloadCert.trustObjSign=Trust to identify software developers.
pkcs12.getpassword.title=Password Entry Dialog
pkcs12.getpassword.message=Please enter the password that was used to encrypt this certificate backup.
clientAuthAsk.title=User Identification Request
diff --git a/mobile/android/tests/browser/robocop/robocop.ini b/mobile/android/tests/browser/robocop/robocop.ini
index d9946dd77b2e..f5a478748d18 100644
--- a/mobile/android/tests/browser/robocop/robocop.ini
+++ b/mobile/android/tests/browser/robocop/robocop.ini
@@ -11,6 +11,8 @@ skip-if = android_version == "18"
# disabled on 4.3, bug 1120759
skip-if = android_version == "18"
[src/org/mozilla/gecko/tests/testANRReporter.java]
+[src/org/mozilla/gecko/tests/testAssistIntentNewIntent.java]
+[src/org/mozilla/gecko/tests/testAssistIntentStartup.java]
[src/org/mozilla/gecko/tests/testAudioFocus.java]
[src/org/mozilla/gecko/tests/testMediaControl.java]
skip-if = android_version < "23"
diff --git a/mobile/android/tests/browser/robocop/src/org/mozilla/gecko/tests/AssistIntentTest.java b/mobile/android/tests/browser/robocop/src/org/mozilla/gecko/tests/AssistIntentTest.java
new file mode 100644
index 000000000000..d86354cd015f
--- /dev/null
+++ b/mobile/android/tests/browser/robocop/src/org/mozilla/gecko/tests/AssistIntentTest.java
@@ -0,0 +1,29 @@
+package org.mozilla.gecko.tests;
+
+import android.content.Intent;
+
+import org.mozilla.gecko.tests.helpers.GeckoHelper;
+
+public class AssistIntentTest extends SessionTest {
+ @Override
+ public void setActivityIntent(Intent intent) {
+ // We want to make sure that we have opened a new tab, so we're creating a session
+ // where the default selected tab will *not* be about:home.
+ Session session = createTestSession(/*selected tab*/ 1);
+ injectSessionToRestore(intent, session);
+
+ super.setActivityIntent(intent);
+ }
+
+ protected void verifyAssistIntentHandling() {
+ // After an ACTION_ASSIST intent, we should be in editing mode...
+ mToolbar.assertIsEditing();
+
+ // ... the input field should be empty in readiness for the user to type...
+ mToolbar.assertUrl("");
+
+ // ... and we should have opened a new tab in addition to those from the "restored" session.
+ mToolbar.dismissEditingMode();
+ mToolbar.assertTitle(mStringHelper.ABOUT_HOME_URL);
+ }
+}
diff --git a/mobile/android/tests/browser/robocop/src/org/mozilla/gecko/tests/components/ToolbarComponent.java b/mobile/android/tests/browser/robocop/src/org/mozilla/gecko/tests/components/ToolbarComponent.java
index d4c226e9128d..2c5f559d83b9 100644
--- a/mobile/android/tests/browser/robocop/src/org/mozilla/gecko/tests/components/ToolbarComponent.java
+++ b/mobile/android/tests/browser/robocop/src/org/mozilla/gecko/tests/components/ToolbarComponent.java
@@ -75,7 +75,7 @@ public class ToolbarComponent extends BaseComponent {
public ToolbarComponent assertUrl(final String expected) {
assertIsEditing();
- fAssertEquals("The Toolbar url is " + expected, expected, getUrlEditText().getText());
+ fAssertEquals("The Toolbar url is " + expected, expected, getUrlEditText().getText().toString());
return this;
}
diff --git a/mobile/android/tests/browser/robocop/src/org/mozilla/gecko/tests/testAssistIntentNewIntent.java b/mobile/android/tests/browser/robocop/src/org/mozilla/gecko/tests/testAssistIntentNewIntent.java
new file mode 100644
index 000000000000..c3740f022849
--- /dev/null
+++ b/mobile/android/tests/browser/robocop/src/org/mozilla/gecko/tests/testAssistIntentNewIntent.java
@@ -0,0 +1,28 @@
+package org.mozilla.gecko.tests;
+
+import android.content.Context;
+import android.content.Intent;
+
+import org.mozilla.gecko.AppConstants;
+import org.mozilla.gecko.tests.helpers.GeckoHelper;
+import org.mozilla.gecko.tests.helpers.WaitHelper;
+
+public class testAssistIntentNewIntent extends AssistIntentTest {
+ public void testAssistIntentNewIntent() {
+ GeckoHelper.blockForReady();
+
+ final Context testContext = getInstrumentation().getContext();
+ final Intent assistIntent = new Intent(Intent.ACTION_ASSIST);
+ assistIntent.setPackage(AppConstants.ANDROID_PACKAGE_NAME);
+ assistIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+
+ WaitHelper.waitForPageLoad(new Runnable() {
+ @Override
+ public void run() {
+ testContext.startActivity(assistIntent);
+ }
+ });
+
+ verifyAssistIntentHandling();
+ }
+}
diff --git a/mobile/android/tests/browser/robocop/src/org/mozilla/gecko/tests/testAssistIntentStartup.java b/mobile/android/tests/browser/robocop/src/org/mozilla/gecko/tests/testAssistIntentStartup.java
new file mode 100644
index 000000000000..cbcd27b5e3fd
--- /dev/null
+++ b/mobile/android/tests/browser/robocop/src/org/mozilla/gecko/tests/testAssistIntentStartup.java
@@ -0,0 +1,20 @@
+package org.mozilla.gecko.tests;
+
+import android.content.Intent;
+
+import org.mozilla.gecko.tests.helpers.GeckoHelper;
+
+public class testAssistIntentStartup extends AssistIntentTest {
+ @Override
+ public void setActivityIntent(Intent intent) {
+ intent.setAction(Intent.ACTION_ASSIST);
+
+ super.setActivityIntent(intent);
+ }
+
+ public void testAssistIntentStartup() {
+ GeckoHelper.blockForReady();
+
+ verifyAssistIntentHandling();
+ }
+}
diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js
index 6952304dc101..271910a6ea09 100644
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -2291,6 +2291,7 @@ pref("intl.menuitems.insertseparatorbeforeaccesskeys","chrome://global/locale/in
pref("intl.charset.detector", "chrome://global/locale/intl.properties");
pref("intl.charset.fallback.override", "");
pref("intl.charset.fallback.tld", true);
+pref("intl.charset.fallback.utf8_for_file", false);
pref("intl.ellipsis", "chrome://global-platform/locale/intl.properties");
pref("intl.locale.matchOS", false);
// this pref allows user to request that all internationalization formatters
diff --git a/security/manager/locales/en-US/chrome/pippki/certManager.dtd b/security/manager/locales/en-US/chrome/pippki/certManager.dtd
index 880321cd444f..e6318e1ce096 100644
--- a/security/manager/locales/en-US/chrome/pippki/certManager.dtd
+++ b/security/manager/locales/en-US/chrome/pippki/certManager.dtd
@@ -38,7 +38,6 @@
-
diff --git a/security/manager/locales/en-US/chrome/pippki/pippki.dtd b/security/manager/locales/en-US/chrome/pippki/pippki.dtd
index 3bc3c1f85957..00e1f6a30a4e 100644
--- a/security/manager/locales/en-US/chrome/pippki/pippki.dtd
+++ b/security/manager/locales/en-US/chrome/pippki/pippki.dtd
@@ -20,7 +20,6 @@
-
diff --git a/security/manager/pki/nsNSSDialogs.cpp b/security/manager/pki/nsNSSDialogs.cpp
index 8e41d4f778ad..fcba770c1d97 100644
--- a/security/manager/pki/nsNSSDialogs.cpp
+++ b/security/manager/pki/nsNSSDialogs.cpp
@@ -153,16 +153,9 @@ nsNSSDialogs::ConfirmDownloadCACert(nsIInterfaceRequestor* ctx,
if (NS_FAILED(rv)) {
return rv;
}
- bool trustForObjSign = false;
- rv = retVals->GetPropertyAsBool(NS_LITERAL_STRING("trustForObjSign"),
- &trustForObjSign);
- if (NS_FAILED(rv)) {
- return rv;
- }
*trust |= trustForSSL ? nsIX509CertDB::TRUSTED_SSL : 0;
*trust |= trustForEmail ? nsIX509CertDB::TRUSTED_EMAIL : 0;
- *trust |= trustForObjSign ? nsIX509CertDB::TRUSTED_OBJSIGN : 0;
return NS_OK;
}
diff --git a/security/manager/pki/resources/content/downloadcert.js b/security/manager/pki/resources/content/downloadcert.js
index 892e34be081c..c5cda01a1831 100644
--- a/security/manager/pki/resources/content/downloadcert.js
+++ b/security/manager/pki/resources/content/downloadcert.js
@@ -27,9 +27,6 @@
* @property {Boolean} trustForEmail
* Set to true if the cert should be trusted for e-mail, false
* otherwise. Undefined value if |importConfirmed| is not true.
- * @property {Boolean} trustForObjSign
- * Set to true if the cert should be trusted for object signing, false
- * otherwise. Undefined value if |importConfirmed| is not true.
*/
const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
@@ -70,13 +67,11 @@ function viewCert() {
function onDialogAccept() {
let checkSSL = document.getElementById("trustSSL");
let checkEmail = document.getElementById("trustEmail");
- let checkObjSign = document.getElementById("trustObjSign");
let retVals = window.arguments[1].QueryInterface(Ci.nsIWritablePropertyBag2);
retVals.setPropertyAsBool("importConfirmed", true);
retVals.setPropertyAsBool("trustForSSL", checkSSL.checked);
retVals.setPropertyAsBool("trustForEmail", checkEmail.checked);
- retVals.setPropertyAsBool("trustForObjSign", checkObjSign.checked);
return true;
}
diff --git a/security/manager/pki/resources/content/downloadcert.xul b/security/manager/pki/resources/content/downloadcert.xul
index 9ddc88a17ce8..7e19de2c88d0 100644
--- a/security/manager/pki/resources/content/downloadcert.xul
+++ b/security/manager/pki/resources/content/downloadcert.xul
@@ -33,7 +33,6 @@
- "do you want to?"
- * trust for SSL
- * trust for email
- - * trust for object signing
-->
@@ -41,8 +40,6 @@
id="trustSSL"/>
-
diff --git a/security/manager/pki/resources/content/editcacert.js b/security/manager/pki/resources/content/editcacert.js
index 405d5281a42c..1414ac653cac 100644
--- a/security/manager/pki/resources/content/editcacert.js
+++ b/security/manager/pki/resources/content/editcacert.js
@@ -31,11 +31,6 @@ function onLoad() {
let emailCheckbox = document.getElementById("trustEmail");
emailCheckbox.checked = gCertDB.isCertTrusted(gCert, Ci.nsIX509Cert.CA_CERT,
Ci.nsIX509CertDB.TRUSTED_EMAIL);
-
- let objSignCheckbox = document.getElementById("trustObjSign");
- objSignCheckbox.checked =
- gCertDB.isCertTrusted(gCert, Ci.nsIX509Cert.CA_CERT,
- Ci.nsIX509CertDB.TRUSTED_OBJSIGN);
}
/**
@@ -46,13 +41,9 @@ function onLoad() {
function onDialogAccept() {
let sslCheckbox = document.getElementById("trustSSL");
let emailCheckbox = document.getElementById("trustEmail");
- let objSignCheckbox = document.getElementById("trustObjSign");
let trustSSL = sslCheckbox.checked ? Ci.nsIX509CertDB.TRUSTED_SSL : 0;
let trustEmail = emailCheckbox.checked ? Ci.nsIX509CertDB.TRUSTED_EMAIL : 0;
- let trustObjSign = objSignCheckbox.checked ? Ci.nsIX509CertDB.TRUSTED_OBJSIGN
- : 0;
- gCertDB.setCertTrust(gCert, Ci.nsIX509Cert.CA_CERT,
- trustSSL | trustEmail | trustObjSign);
+ gCertDB.setCertTrust(gCert, Ci.nsIX509Cert.CA_CERT, trustSSL | trustEmail);
return true;
}
diff --git a/security/manager/pki/resources/content/editcacert.xul b/security/manager/pki/resources/content/editcacert.xul
index 46ea4f1f928d..0cba6d6d3cb6 100644
--- a/security/manager/pki/resources/content/editcacert.xul
+++ b/security/manager/pki/resources/content/editcacert.xul
@@ -29,8 +29,6 @@
id="trustSSL"/>
-
diff --git a/security/manager/ssl/nsIX509CertDB.idl b/security/manager/ssl/nsIX509CertDB.idl
index d3c795c03c84..d7983be77230 100644
--- a/security/manager/ssl/nsIX509CertDB.idl
+++ b/security/manager/ssl/nsIX509CertDB.idl
@@ -67,7 +67,6 @@ interface nsIX509CertDB : nsISupports {
const unsigned long UNTRUSTED = 0;
const unsigned long TRUSTED_SSL = 1 << 0;
const unsigned long TRUSTED_EMAIL = 1 << 1;
- const unsigned long TRUSTED_OBJSIGN = 1 << 2;
/**
* Will find a certificate based on its dbkey
@@ -155,8 +154,11 @@ interface nsIX509CertDB : nsISupports {
/**
* @param cert The certificate for which to modify trust.
* @param trustString decoded by CERT_DecodeTrustString. 3 comma separated
- * characters, indicating SSL, Email, and Obj signing
- * trust.
+ * characters, indicating SSL, Email, and Object signing
+ * trust. The object signing trust flags are effectively
+ * ignored by gecko, but they still must be specified (at
+ * least by a final trailing comma) because this argument
+ * is passed to CERT_DecodeTrustString.
*/
[must_use]
void setCertTrustFromString(in nsIX509Cert cert, in ACString trustString);
@@ -284,7 +286,10 @@ interface nsIX509CertDB : nsISupports {
* @param trust String describing the trust settings to assign the
* certificate. Decoded by CERT_DecodeTrustString. Consists of 3
* comma separated sets of characters, indicating SSL, Email, and
- * Object signing trust.
+ * Object signing trust. The object signing trust flags are
+ * effectively ignored by gecko, but they still must be specified
+ * (at least by a final trailing comma) because this argument is
+ * passed to CERT_DecodeTrustString.
* @return nsIX509Cert the resulting certificate
*/
[must_use]
@@ -359,7 +364,10 @@ interface nsIX509CertDB : nsISupports {
* @param trust String describing the trust settings to assign the
* certificate. Decoded by CERT_DecodeTrustString. Consists of 3
* comma separated sets of characters, indicating SSL, Email, and
- * Object signing trust.
+ * Object signing trust. The object signing trust flags are
+ * effectively ignored by gecko, but they still must be specified
+ * (at least by a final trailing comma) because this argument is
+ * passed to CERT_DecodeTrustString.
* @return nsIX509Cert the resulting certificate
*/
[must_use]
diff --git a/security/manager/ssl/nsNSSCertHelper.cpp b/security/manager/ssl/nsNSSCertHelper.cpp
index 1ede4d242577..4735606bbdc5 100644
--- a/security/manager/ssl/nsNSSCertHelper.cpp
+++ b/security/manager/ssl/nsNSSCertHelper.cpp
@@ -2039,9 +2039,9 @@ getCertType(CERTCertificate* cert)
return nsIX509Cert::USER_CERT;
if (trust.HasAnyCA())
return nsIX509Cert::CA_CERT;
- if (trust.HasPeer(true, false, false))
+ if (trust.HasPeer(true, false))
return nsIX509Cert::SERVER_CERT;
- if (trust.HasPeer(false, true, false) && cert->emailAddr)
+ if (trust.HasPeer(false, true) && cert->emailAddr)
return nsIX509Cert::EMAIL_CERT;
if (CERT_IsCACert(cert, nullptr))
return nsIX509Cert::CA_CERT;
diff --git a/security/manager/ssl/nsNSSCertTrust.cpp b/security/manager/ssl/nsNSSCertTrust.cpp
index d7dd266691b7..46dd005f201d 100644
--- a/security/manager/ssl/nsNSSCertTrust.cpp
+++ b/security/manager/ssl/nsNSSCertTrust.cpp
@@ -5,7 +5,7 @@
#include "nsNSSCertTrust.h"
void
-nsNSSCertTrust::AddCATrust(bool ssl, bool email, bool objSign)
+nsNSSCertTrust::AddCATrust(bool ssl, bool email)
{
if (ssl) {
addTrust(&mTrust.sslFlags, CERTDB_TRUSTED_CA);
@@ -15,21 +15,15 @@ nsNSSCertTrust::AddCATrust(bool ssl, bool email, bool objSign)
addTrust(&mTrust.emailFlags, CERTDB_TRUSTED_CA);
addTrust(&mTrust.emailFlags, CERTDB_TRUSTED_CLIENT_CA);
}
- if (objSign) {
- addTrust(&mTrust.objectSigningFlags, CERTDB_TRUSTED_CA);
- addTrust(&mTrust.objectSigningFlags, CERTDB_TRUSTED_CLIENT_CA);
- }
}
void
-nsNSSCertTrust::AddPeerTrust(bool ssl, bool email, bool objSign)
+nsNSSCertTrust::AddPeerTrust(bool ssl, bool email)
{
if (ssl)
addTrust(&mTrust.sslFlags, CERTDB_TRUSTED);
if (email)
addTrust(&mTrust.emailFlags, CERTDB_TRUSTED);
- if (objSign)
- addTrust(&mTrust.objectSigningFlags, CERTDB_TRUSTED);
}
nsNSSCertTrust::nsNSSCertTrust()
@@ -37,14 +31,11 @@ nsNSSCertTrust::nsNSSCertTrust()
memset(&mTrust, 0, sizeof(CERTCertTrust));
}
-nsNSSCertTrust::nsNSSCertTrust(unsigned int ssl,
- unsigned int email,
- unsigned int objsign)
+nsNSSCertTrust::nsNSSCertTrust(unsigned int ssl, unsigned int email)
{
memset(&mTrust, 0, sizeof(CERTCertTrust));
addTrust(&mTrust.sslFlags, ssl);
addTrust(&mTrust.emailFlags, email);
- addTrust(&mTrust.objectSigningFlags, objsign);
}
nsNSSCertTrust::nsNSSCertTrust(CERTCertTrust *t)
@@ -103,28 +94,6 @@ nsNSSCertTrust::SetEmailTrust(bool peer, bool tPeer,
addTrust(&mTrust.emailFlags, CERTDB_SEND_WARN);
}
-void
-nsNSSCertTrust::SetObjSignTrust(bool peer, bool tPeer,
- bool ca, bool tCA, bool tClientCA,
- bool user, bool warn)
-{
- mTrust.objectSigningFlags = 0;
- if (peer || tPeer)
- addTrust(&mTrust.objectSigningFlags, CERTDB_TERMINAL_RECORD);
- if (tPeer)
- addTrust(&mTrust.objectSigningFlags, CERTDB_TRUSTED);
- if (ca || tCA)
- addTrust(&mTrust.objectSigningFlags, CERTDB_VALID_CA);
- if (tClientCA)
- addTrust(&mTrust.objectSigningFlags, CERTDB_TRUSTED_CLIENT_CA);
- if (tCA)
- addTrust(&mTrust.objectSigningFlags, CERTDB_TRUSTED_CA);
- if (user)
- addTrust(&mTrust.objectSigningFlags, CERTDB_USER);
- if (warn)
- addTrust(&mTrust.objectSigningFlags, CERTDB_SEND_WARN);
-}
-
void
nsNSSCertTrust::SetValidCA()
{
@@ -134,9 +103,6 @@ nsNSSCertTrust::SetValidCA()
SetEmailTrust(false, false,
true, false, false,
false, false);
- SetObjSignTrust(false, false,
- true, false, false,
- false, false);
}
void
@@ -148,9 +114,6 @@ nsNSSCertTrust::SetValidPeer()
SetEmailTrust(true, false,
false, false, false,
false, false);
- SetObjSignTrust(true, false,
- false, false, false,
- false, false);
}
bool
@@ -164,16 +127,12 @@ nsNSSCertTrust::HasAnyCA()
}
bool
-nsNSSCertTrust::HasPeer(bool checkSSL,
- bool checkEmail,
- bool checkObjSign)
+nsNSSCertTrust::HasPeer(bool checkSSL, bool checkEmail)
{
if (checkSSL && !hasTrust(mTrust.sslFlags, CERTDB_TERMINAL_RECORD))
return false;
if (checkEmail && !hasTrust(mTrust.emailFlags, CERTDB_TERMINAL_RECORD))
return false;
- if (checkObjSign && !hasTrust(mTrust.objectSigningFlags, CERTDB_TERMINAL_RECORD))
- return false;
return true;
}
@@ -188,9 +147,7 @@ nsNSSCertTrust::HasAnyUser()
}
bool
-nsNSSCertTrust::HasTrustedCA(bool checkSSL,
- bool checkEmail,
- bool checkObjSign)
+nsNSSCertTrust::HasTrustedCA(bool checkSSL, bool checkEmail)
{
if (checkSSL && !(hasTrust(mTrust.sslFlags, CERTDB_TRUSTED_CA) ||
hasTrust(mTrust.sslFlags, CERTDB_TRUSTED_CLIENT_CA)))
@@ -198,25 +155,16 @@ nsNSSCertTrust::HasTrustedCA(bool checkSSL,
if (checkEmail && !(hasTrust(mTrust.emailFlags, CERTDB_TRUSTED_CA) ||
hasTrust(mTrust.emailFlags, CERTDB_TRUSTED_CLIENT_CA)))
return false;
- if (checkObjSign &&
- !(hasTrust(mTrust.objectSigningFlags, CERTDB_TRUSTED_CA) ||
- hasTrust(mTrust.objectSigningFlags, CERTDB_TRUSTED_CLIENT_CA)))
- return false;
return true;
}
bool
-nsNSSCertTrust::HasTrustedPeer(bool checkSSL,
- bool checkEmail,
- bool checkObjSign)
+nsNSSCertTrust::HasTrustedPeer(bool checkSSL, bool checkEmail)
{
if (checkSSL && !(hasTrust(mTrust.sslFlags, CERTDB_TRUSTED)))
return false;
if (checkEmail && !(hasTrust(mTrust.emailFlags, CERTDB_TRUSTED)))
return false;
- if (checkObjSign &&
- !(hasTrust(mTrust.objectSigningFlags, CERTDB_TRUSTED)))
- return false;
return true;
}
diff --git a/security/manager/ssl/nsNSSCertTrust.h b/security/manager/ssl/nsNSSCertTrust.h
index 26617dcb1d93..8f546376346b 100644
--- a/security/manager/ssl/nsNSSCertTrust.h
+++ b/security/manager/ssl/nsNSSCertTrust.h
@@ -15,22 +15,16 @@ class nsNSSCertTrust
{
public:
nsNSSCertTrust();
- nsNSSCertTrust(unsigned int ssl, unsigned int email, unsigned int objsign);
+ nsNSSCertTrust(unsigned int ssl, unsigned int email);
explicit nsNSSCertTrust(CERTCertTrust *t);
virtual ~nsNSSCertTrust();
/* query */
bool HasAnyCA();
bool HasAnyUser();
- bool HasPeer(bool checkSSL = true,
- bool checkEmail = true,
- bool checkObjSign = true);
- bool HasTrustedCA(bool checkSSL = true,
- bool checkEmail = true,
- bool checkObjSign = true);
- bool HasTrustedPeer(bool checkSSL = true,
- bool checkEmail = true,
- bool checkObjSign = true);
+ bool HasPeer(bool checkSSL = true, bool checkEmail = true);
+ bool HasTrustedCA(bool checkSSL = true, bool checkEmail = true);
+ bool HasTrustedPeer(bool checkSSL = true, bool checkEmail = true);
/* common defaults */
/* equivalent to "c,c,c" */
@@ -48,14 +42,10 @@ public:
bool ca, bool tCA, bool tClientCA,
bool user, bool warn);
- void SetObjSignTrust(bool peer, bool tPeer,
- bool ca, bool tCA, bool tClientCA,
- bool user, bool warn);
-
/* set c <--> CT */
- void AddCATrust(bool ssl, bool email, bool objSign);
+ void AddCATrust(bool ssl, bool email);
/* set p <--> P */
- void AddPeerTrust(bool ssl, bool email, bool objSign);
+ void AddPeerTrust(bool ssl, bool email);
CERTCertTrust& GetTrust() { return mTrust; }
diff --git a/security/manager/ssl/nsNSSCertificateDB.cpp b/security/manager/ssl/nsNSSCertificateDB.cpp
index d5cda5499861..46e77e660add 100644
--- a/security/manager/ssl/nsNSSCertificateDB.cpp
+++ b/security/manager/ssl/nsNSSCertificateDB.cpp
@@ -382,8 +382,7 @@ nsNSSCertificateDB::handleCACertDownload(NotNull x509Certs,
nsNSSCertTrust trust;
trust.SetValidCA();
trust.AddCATrust(!!(trustBits & nsIX509CertDB::TRUSTED_SSL),
- !!(trustBits & nsIX509CertDB::TRUSTED_EMAIL),
- !!(trustBits & nsIX509CertDB::TRUSTED_OBJSIGN));
+ !!(trustBits & nsIX509CertDB::TRUSTED_EMAIL));
UniquePK11SlotInfo slot(PK11_GetInternalKeySlot());
SECStatus srv = PK11_ImportCert(slot.get(), tmpCert.get(), CK_INVALID_HANDLE,
@@ -737,7 +736,7 @@ nsNSSCertificateDB::DeleteCertificate(nsIX509Cert *aCert)
// want to do that with user certs, because a user may re-store
// the cert onto the card again at which point we *will* want to
// trust that cert if it chains up properly.
- nsNSSCertTrust trust(0, 0, 0);
+ nsNSSCertTrust trust(0, 0);
srv = ChangeCertTrustWithPossibleAuthentication(cert, trust.GetTrust(),
nullptr);
}
@@ -768,17 +767,15 @@ nsNSSCertificateDB::SetCertTrust(nsIX509Cert *cert,
case nsIX509Cert::CA_CERT:
trust.SetValidCA();
trust.AddCATrust(!!(trusted & nsIX509CertDB::TRUSTED_SSL),
- !!(trusted & nsIX509CertDB::TRUSTED_EMAIL),
- !!(trusted & nsIX509CertDB::TRUSTED_OBJSIGN));
+ !!(trusted & nsIX509CertDB::TRUSTED_EMAIL));
break;
case nsIX509Cert::SERVER_CERT:
trust.SetValidPeer();
- trust.AddPeerTrust(trusted & nsIX509CertDB::TRUSTED_SSL, false, false);
+ trust.AddPeerTrust(trusted & nsIX509CertDB::TRUSTED_SSL, false);
break;
case nsIX509Cert::EMAIL_CERT:
trust.SetValidPeer();
- trust.AddPeerTrust(false, !!(trusted & nsIX509CertDB::TRUSTED_EMAIL),
- false);
+ trust.AddPeerTrust(false, !!(trusted & nsIX509CertDB::TRUSTED_EMAIL));
break;
default:
// Ignore any other type of certificate (including invalid types).
@@ -821,31 +818,25 @@ nsNSSCertificateDB::IsCertTrusted(nsIX509Cert *cert,
nsNSSCertTrust trust(&nsstrust);
if (certType == nsIX509Cert::CA_CERT) {
if (trustType & nsIX509CertDB::TRUSTED_SSL) {
- *_isTrusted = trust.HasTrustedCA(true, false, false);
+ *_isTrusted = trust.HasTrustedCA(true, false);
} else if (trustType & nsIX509CertDB::TRUSTED_EMAIL) {
- *_isTrusted = trust.HasTrustedCA(false, true, false);
- } else if (trustType & nsIX509CertDB::TRUSTED_OBJSIGN) {
- *_isTrusted = trust.HasTrustedCA(false, false, true);
+ *_isTrusted = trust.HasTrustedCA(false, true);
} else {
return NS_ERROR_FAILURE;
}
} else if (certType == nsIX509Cert::SERVER_CERT) {
if (trustType & nsIX509CertDB::TRUSTED_SSL) {
- *_isTrusted = trust.HasTrustedPeer(true, false, false);
+ *_isTrusted = trust.HasTrustedPeer(true, false);
} else if (trustType & nsIX509CertDB::TRUSTED_EMAIL) {
- *_isTrusted = trust.HasTrustedPeer(false, true, false);
- } else if (trustType & nsIX509CertDB::TRUSTED_OBJSIGN) {
- *_isTrusted = trust.HasTrustedPeer(false, false, true);
+ *_isTrusted = trust.HasTrustedPeer(false, true);
} else {
return NS_ERROR_FAILURE;
}
} else if (certType == nsIX509Cert::EMAIL_CERT) {
if (trustType & nsIX509CertDB::TRUSTED_SSL) {
- *_isTrusted = trust.HasTrustedPeer(true, false, false);
+ *_isTrusted = trust.HasTrustedPeer(true, false);
} else if (trustType & nsIX509CertDB::TRUSTED_EMAIL) {
- *_isTrusted = trust.HasTrustedPeer(false, true, false);
- } else if (trustType & nsIX509CertDB::TRUSTED_OBJSIGN) {
- *_isTrusted = trust.HasTrustedPeer(false, false, true);
+ *_isTrusted = trust.HasTrustedPeer(false, true);
} else {
return NS_ERROR_FAILURE;
}
diff --git a/security/manager/ssl/tests/mochitest/browser/browser_downloadCert_ui.js b/security/manager/ssl/tests/mochitest/browser/browser_downloadCert_ui.js
index c1e466f9aefc..f63a58331843 100644
--- a/security/manager/ssl/tests/mochitest/browser/browser_downloadCert_ui.js
+++ b/security/manager/ssl/tests/mochitest/browser/browser_downloadCert_ui.js
@@ -122,7 +122,6 @@ add_task(async function testAcceptDialogReturnValues() {
let [win, retVals] = await openCertDownloadDialog(TEST_CASES[0].cert);
win.document.getElementById("trustSSL").checked = true;
win.document.getElementById("trustEmail").checked = false;
- win.document.getElementById("trustObjSign").checked = true;
info("Accepting dialog");
win.document.getElementById("download_cert").acceptDialog();
await BrowserTestUtils.windowClosed(win);
@@ -133,8 +132,6 @@ add_task(async function testAcceptDialogReturnValues() {
"Return value should signal SSL trust checkbox was checked");
Assert.ok(!retVals.get("trustForEmail"),
"Return value should signal E-mail trust checkbox was unchecked");
- Assert.ok(retVals.get("trustForObjSign"),
- "Return value should signal Obj Sign trust checkbox was checked");
});
// Test that the right values are returned when the dialog is canceled.
diff --git a/security/manager/ssl/tests/mochitest/browser/browser_editCACertTrust.js b/security/manager/ssl/tests/mochitest/browser/browser_editCACertTrust.js
index bebc9ba2b305..cb2490c14273 100644
--- a/security/manager/ssl/tests/mochitest/browser/browser_editCACertTrust.js
+++ b/security/manager/ssl/tests/mochitest/browser/browser_editCACertTrust.js
@@ -33,7 +33,7 @@ function openEditCertTrustDialog() {
}
add_task(async function setup() {
- // Initially trust ca.pem for SSL, but not e-mail or object signing.
+ // Initially trust ca.pem for SSL but not e-mail.
gCert = await readCertificate("ca.pem", "CT,,");
Assert.ok(gCertDB.isCertTrusted(gCert, Ci.nsIX509Cert.CA_CERT,
Ci.nsIX509CertDB.TRUSTED_SSL),
@@ -41,9 +41,6 @@ add_task(async function setup() {
Assert.ok(!gCertDB.isCertTrusted(gCert, Ci.nsIX509Cert.CA_CERT,
Ci.nsIX509CertDB.TRUSTED_EMAIL),
"Sanity check: ca.pem should not be trusted for e-mail");
- Assert.ok(!gCertDB.isCertTrusted(gCert, Ci.nsIX509Cert.CA_CERT,
- Ci.nsIX509CertDB.TRUSTED_OBJSIGN),
- "Sanity check: ca.pem should not be trusted for object signing");
});
// Tests the following:
@@ -55,13 +52,10 @@ add_task(async function testAcceptDialog() {
let sslCheckbox = win.document.getElementById("trustSSL");
let emailCheckbox = win.document.getElementById("trustEmail");
- let objSignCheckbox = win.document.getElementById("trustObjSign");
Assert.ok(sslCheckbox.checked,
"Cert should be trusted for SSL in UI");
Assert.ok(!emailCheckbox.checked,
"Cert should not be trusted for e-mail in UI");
- Assert.ok(!objSignCheckbox.checked,
- "Cert should not be trusted for object signing in UI");
sslCheckbox.checked = false;
emailCheckbox.checked = true;
@@ -76,9 +70,6 @@ add_task(async function testAcceptDialog() {
Assert.ok(gCertDB.isCertTrusted(gCert, Ci.nsIX509Cert.CA_CERT,
Ci.nsIX509CertDB.TRUSTED_EMAIL),
"Cert should now be trusted for e-mail");
- Assert.ok(!gCertDB.isCertTrusted(gCert, Ci.nsIX509Cert.CA_CERT,
- Ci.nsIX509CertDB.TRUSTED_OBJSIGN),
- "Cert should still not be trusted for object signing");
});
// Tests the following:
@@ -90,17 +81,13 @@ add_task(async function testCancelDialog() {
let sslCheckbox = win.document.getElementById("trustSSL");
let emailCheckbox = win.document.getElementById("trustEmail");
- let objSignCheckbox = win.document.getElementById("trustObjSign");
Assert.ok(!sslCheckbox.checked,
"Cert should not be trusted for SSL in UI");
Assert.ok(emailCheckbox.checked,
"Cert should be trusted for e-mail in UI");
- Assert.ok(!objSignCheckbox.checked,
- "Cert should not be trusted for object signing in UI");
sslCheckbox.checked = true;
emailCheckbox.checked = false;
- objSignCheckbox.checked = true;
info("Canceling dialog");
win.document.getElementById("editCaCert").cancelDialog();
@@ -112,7 +99,4 @@ add_task(async function testCancelDialog() {
Assert.ok(gCertDB.isCertTrusted(gCert, Ci.nsIX509Cert.CA_CERT,
Ci.nsIX509CertDB.TRUSTED_EMAIL),
"Cert should still be trusted for e-mail");
- Assert.ok(!gCertDB.isCertTrusted(gCert, Ci.nsIX509Cert.CA_CERT,
- Ci.nsIX509CertDB.TRUSTED_OBJSIGN),
- "Cert should still not be trusted for object signing");
});
diff --git a/security/manager/ssl/tests/unit/test_cert_trust.js b/security/manager/ssl/tests/unit/test_cert_trust.js
index 560b1a3f702c..8bd3e32fb70b 100644
--- a/security/manager/ssl/tests/unit/test_cert_trust.js
+++ b/security/manager/ssl/tests/unit/test_cert_trust.js
@@ -18,8 +18,7 @@ function load_cert(cert_name, trust_string) {
function setup_basic_trusts(ca_cert, int_cert) {
certdb.setCertTrust(ca_cert, Ci.nsIX509Cert.CA_CERT,
Ci.nsIX509CertDB.TRUSTED_SSL |
- Ci.nsIX509CertDB.TRUSTED_EMAIL |
- Ci.nsIX509CertDB.TRUSTED_OBJSIGN);
+ Ci.nsIX509CertDB.TRUSTED_EMAIL);
certdb.setCertTrust(int_cert, Ci.nsIX509Cert.CA_CERT, 0);
}
diff --git a/servo/components/script/dom/bindings/str.rs b/servo/components/script/dom/bindings/str.rs
index 3667dddf92d4..596b2db14b2e 100644
--- a/servo/components/script/dom/bindings/str.rs
+++ b/servo/components/script/dom/bindings/str.rs
@@ -208,6 +208,91 @@ impl DOMString {
self.0.truncate(last_non_whitespace);
let _ = self.0.splice(0..first_non_whitespace, "");
}
+
+ /// Validates this `DOMString` is a time string according to
+ /// .
+ pub fn is_valid_time_string(&self) -> bool {
+ enum State {
+ HourHigh,
+ HourLow09,
+ HourLow03,
+ MinuteColon,
+ MinuteHigh,
+ MinuteLow,
+ SecondColon,
+ SecondHigh,
+ SecondLow,
+ MilliStop,
+ MilliHigh,
+ MilliMiddle,
+ MilliLow,
+ Done,
+ Error,
+ }
+ let next_state = |valid: bool, next: State| -> State { if valid { next } else { State::Error } };
+
+ let state = self.chars().fold(State::HourHigh, |state, c| {
+ match state {
+ // Step 1 "HH"
+ State::HourHigh => {
+ match c {
+ '0' | '1' => State::HourLow09,
+ '2' => State::HourLow03,
+ _ => State::Error,
+ }
+ },
+ State::HourLow09 => next_state(c.is_digit(10), State::MinuteColon),
+ State::HourLow03 => next_state(c.is_digit(4), State::MinuteColon),
+
+ // Step 2 ":"
+ State::MinuteColon => next_state(c == ':', State::MinuteHigh),
+
+ // Step 3 "mm"
+ State::MinuteHigh => next_state(c.is_digit(6), State::MinuteLow),
+ State::MinuteLow => next_state(c.is_digit(10), State::SecondColon),
+
+ // Step 4.1 ":"
+ State::SecondColon => next_state(c == ':', State::SecondHigh),
+ // Step 4.2 "ss"
+ State::SecondHigh => next_state(c.is_digit(6), State::SecondLow),
+ State::SecondLow => next_state(c.is_digit(10), State::MilliStop),
+
+ // Step 4.3.1 "."
+ State::MilliStop => next_state(c == '.', State::MilliHigh),
+ // Step 4.3.2 "SSS"
+ State::MilliHigh => next_state(c.is_digit(6), State::MilliMiddle),
+ State::MilliMiddle => next_state(c.is_digit(10), State::MilliLow),
+ State::MilliLow => next_state(c.is_digit(10), State::Done),
+
+ _ => State::Error,
+ }
+ });
+
+ match state {
+ State::Done |
+ // Step 4 (optional)
+ State::SecondColon |
+ // Step 4.3 (optional)
+ State::MilliStop |
+ // Step 4.3.2 (only 1 digit required)
+ State::MilliMiddle | State::MilliLow => true,
+ _ => false
+ }
+ }
+
+ /// A valid date string should be "YYYY-MM-DD"
+ /// YYYY must be four or more digits, MM and DD both must be two digits
+ /// https://html.spec.whatwg.org/multipage/#valid-date-string
+ pub fn is_valid_date_string(&self) -> bool {
+ parse_date_string(&*self.0).is_ok()
+ }
+
+ /// A valid month string should be "YYYY-MM"
+ /// YYYY must be four or more digits, MM both must be two digits
+ /// https://html.spec.whatwg.org/multipage/#valid-month-string
+ pub fn is_valid_month_string(&self) -> bool {
+ parse_month_string(&*self.0).is_ok()
+ }
}
impl Borrow for DOMString {
@@ -332,3 +417,90 @@ impl Extend for DOMString {
self.0.extend(iterable)
}
}
+
+/// https://html.spec.whatwg.org/multipage/#parse-a-month-string
+fn parse_month_string(value: &str) -> Result<(u32, u32), ()> {
+ // Step 1, 2, 3
+ let (year_int, month_int) = parse_month_component(value)?;
+
+ // Step 4
+ if value.split("-").nth(2).is_some() {
+ return Err(());
+ }
+ // Step 5
+ Ok((year_int, month_int))
+}
+
+/// https://html.spec.whatwg.org/multipage/#parse-a-date-string
+fn parse_date_string(value: &str) -> Result<(u32, u32, u32), ()> {
+ // Step 1, 2, 3
+ let (year_int, month_int, day_int) = parse_date_component(value)?;
+
+ // Step 4
+ if value.split('-').nth(3).is_some() {
+ return Err(());
+ }
+
+ // Step 5, 6
+ Ok((year_int, month_int, day_int))
+}
+
+/// https://html.spec.whatwg.org/multipage/#parse-a-month-component
+fn parse_month_component(value: &str) -> Result<(u32, u32), ()> {
+ // Step 3
+ let mut iterator = value.split('-');
+ let year = iterator.next().ok_or(())?;
+ let month = iterator.next().ok_or(())?;
+
+ // Step 1, 2
+ let year_int = year.parse::().map_err(|_| ())?;
+ if year.len() < 4 || year_int == 0 {
+ return Err(());
+ }
+
+ // Step 4, 5
+ let month_int = month.parse::().map_err(|_| ())?;
+ if month.len() != 2 || month_int > 12 || month_int < 1 {
+ return Err(());
+ }
+
+ // Step 6
+ Ok((year_int, month_int))
+}
+
+/// https://html.spec.whatwg.org/multipage/#parse-a-date-component
+fn parse_date_component(value: &str) -> Result<(u32, u32, u32), ()> {
+ // Step 1
+ let (year_int, month_int) = parse_month_component(value)?;
+
+ // Step 3, 4
+ let day = value.split('-').nth(2).ok_or(())?;
+ let day_int = day.parse::().map_err(|_| ())?;
+ if day.len() != 2 {
+ return Err(());
+ }
+
+ // Step 2, 5
+ let max_day = max_day_in_month(year_int, month_int)?;
+ if day_int == 0 || day_int > max_day {
+ return Err(());
+ }
+
+ // Step 6
+ Ok((year_int, month_int, day_int))
+}
+
+fn max_day_in_month(year_num: u32, month_num: u32) -> Result {
+ match month_num {
+ 1|3|5|7|8|10|12 => Ok(31),
+ 4|6|9|11 => Ok(30),
+ 2 => {
+ if year_num % 400 == 0 || (year_num % 4 == 0 && year_num % 100 != 0) {
+ Ok(29)
+ } else {
+ Ok(28)
+ }
+ },
+ _ => Err(())
+ }
+}
diff --git a/servo/components/script/dom/htmlinputelement.rs b/servo/components/script/dom/htmlinputelement.rs
index 7f995671d8dd..cbf4f483e0c8 100755
--- a/servo/components/script/dom/htmlinputelement.rs
+++ b/servo/components/script/dom/htmlinputelement.rs
@@ -875,6 +875,18 @@ impl HTMLInputElement {
content.strip_newlines();
content.strip_leading_and_trailing_ascii_whitespace();
}
+ atom!("date") => {
+ let mut textinput = self.textinput.borrow_mut();
+ if !textinput.single_line_content().is_valid_date_string() {
+ *textinput.single_line_content_mut() = "".into();
+ }
+ }
+ atom!("month") => {
+ let mut textinput = self.textinput.borrow_mut();
+ if !textinput.single_line_content().is_valid_month_string() {
+ *textinput.single_line_content_mut() = "".into();
+ }
+ }
atom!("color") => {
let mut textinput = self.textinput.borrow_mut();
@@ -895,6 +907,13 @@ impl HTMLInputElement {
textinput.set_content("#000000".into());
}
}
+ atom!("time") => {
+ let mut textinput = self.textinput.borrow_mut();
+
+ if ! textinput.single_line_content().is_valid_time_string() {
+ *textinput.single_line_content_mut() = "".into();
+ }
+ }
// TODO: Implement more value sanitization algorithms for different types of inputs
_ => ()
}
@@ -1035,6 +1054,7 @@ impl VirtualMethods for HTMLInputElement {
let value = mutation.new_value(attr).map(|value| (**value).to_owned());
self.textinput.borrow_mut().set_content(
value.map_or(DOMString::new(), DOMString::from));
+ self.sanitize_value();
self.update_placeholder_shown_state();
},
&local_name!("name") if self.input_type.get() == InputType::InputRadio => {
@@ -1110,7 +1130,6 @@ impl VirtualMethods for HTMLInputElement {
if let Some(ref s) = self.super_type() {
s.bind_to_tree(tree_in_doc);
}
-
self.upcast::().check_ancestors_disabled_state_for_form_control();
}
diff --git a/servo/etc/ci/performance/test_all.sh b/servo/etc/ci/performance/test_all.sh
index d62ddd5abeca..738fbc2204f6 100755
--- a/servo/etc/ci/performance/test_all.sh
+++ b/servo/etc/ci/performance/test_all.sh
@@ -43,6 +43,9 @@ fi
echo "Starting the local server"
python3 -m http.server > /dev/null 2>&1 &
+# Stop the local server no matter how we exit the script
+trap 'kill $(jobs -pr)' SIGINT SIGTERM EXIT
+
# TODO: enable the full manifest when #11087 is fixed
# https://github.com/servo/servo/issues/11087
# MANIFEST="page_load_test/tp5n/20160509.manifest"
@@ -61,5 +64,3 @@ then
python3 submit_to_s3.py "${PERF_FILE}" "${PERF_KEY}"
fi
-echo "Stopping the local server"
-trap 'kill $(jobs -pr)' SIGINT SIGTERM EXIT
diff --git a/storage/mozIStorageAsyncConnection.idl b/storage/mozIStorageAsyncConnection.idl
index 933ed3426dad..c3663be6e077 100644
--- a/storage/mozIStorageAsyncConnection.idl
+++ b/storage/mozIStorageAsyncConnection.idl
@@ -95,6 +95,11 @@ interface mozIStorageAsyncConnection : nsISupports {
* - journal_size_limit
* - synchronous
* - wal_autocheckpoint
+ * All SQL functions are copied over to read-only and writeable clones.
+ * Additionally, all temporary tables, triggers, and views, as well as
+ * any indexes on temporary tables, are copied over to writeable clones.
+ * For temporary tables, only the schemas are copied, not their
+ * contents.
*/
void asyncClone(in boolean aReadOnly,
in mozIStorageCompletionCallback aCallback);
diff --git a/storage/mozIStorageConnection.idl b/storage/mozIStorageConnection.idl
index 11d8aa5acdd1..bdc7305216c0 100644
--- a/storage/mozIStorageConnection.idl
+++ b/storage/mozIStorageConnection.idl
@@ -82,6 +82,11 @@ interface mozIStorageConnection : mozIStorageAsyncConnection {
* - journal_size_limit
* - synchronous
* - wal_autocheckpoint
+ * All SQL functions are copied over to read-only and writeable clones.
+ * Additionally, all temporary tables, triggers, and views, as well as
+ * any indexes on temporary tables, are copied over to writeable clones.
+ * For temporary tables, only the schemas are copied, not their
+ * contents.
*
*/
mozIStorageConnection clone([optional] in boolean aReadOnly);
diff --git a/storage/mozStorageConnection.cpp b/storage/mozStorageConnection.cpp
index 69785dc5b583..dd415c652ebd 100644
--- a/storage/mozStorageConnection.cpp
+++ b/storage/mozStorageConnection.cpp
@@ -1526,6 +1526,39 @@ Connection::initializeClone(Connection* aClone, bool aReadOnly)
return rv;
}
+ // Copy over temporary tables, triggers, and views from the original
+ // connections. Entities in `sqlite_temp_master` are only visible to the
+ // connection that created them.
+ if (!aReadOnly) {
+ nsCOMPtr stmt;
+ rv = CreateStatement(NS_LITERAL_CSTRING("SELECT sql FROM sqlite_temp_master "
+ "WHERE type IN ('table', 'view', "
+ "'index', 'trigger')"),
+ getter_AddRefs(stmt));
+ // Propagate errors, because failing to copy triggers might cause schema
+ // coherency issues when writing to the database from the cloned connection.
+ NS_ENSURE_SUCCESS(rv, rv);
+ bool hasResult = false;
+ while (stmt && NS_SUCCEEDED(stmt->ExecuteStep(&hasResult)) && hasResult) {
+ nsAutoCString query;
+ rv = stmt->GetUTF8String(0, query);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // The `CREATE` SQL statements in `sqlite_temp_master` omit the `TEMP`
+ // keyword. We need to add it back, or we'll recreate temporary entities
+ // as persistent ones. `sqlite_temp_master` also holds `CREATE INDEX`
+ // statements, but those don't need `TEMP` keywords.
+ if (StringBeginsWith(query, NS_LITERAL_CSTRING("CREATE TABLE ")) ||
+ StringBeginsWith(query, NS_LITERAL_CSTRING("CREATE TRIGGER ")) ||
+ StringBeginsWith(query, NS_LITERAL_CSTRING("CREATE VIEW "))) {
+ query.Replace(0, 6, "CREATE TEMP");
+ }
+
+ rv = aClone->ExecuteSimpleSQL(query);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+ }
+
// Re-attach on-disk databases that were attached to the original connection.
{
nsCOMPtr stmt;
diff --git a/storage/test/unit/test_storage_connection.js b/storage/test/unit/test_storage_connection.js
index bf831828f0bf..0938c4a72d94 100644
--- a/storage/test/unit/test_storage_connection.js
+++ b/storage/test/unit/test_storage_connection.js
@@ -753,6 +753,148 @@ add_task(async function test_clone_attach_database() {
db3.close();
});
+add_task(async function test_async_clone_with_temp_trigger_and_table() {
+ do_print("Open connection");
+ let db = getService().openDatabase(getTestDB());
+ do_check_true(db instanceof Ci.mozIStorageAsyncConnection);
+
+ do_print("Set up tables on original connection");
+ let createQueries = [
+ `CREATE TEMP TABLE test_temp(name TEXT)`,
+ `CREATE INDEX test_temp_idx ON test_temp(name)`,
+ `CREATE TEMP TRIGGER test_temp_afterdelete_trigger
+ AFTER DELETE ON test_temp FOR EACH ROW
+ BEGIN
+ INSERT INTO test(name) VALUES(OLD.name);
+ END`];
+ for (let query of createQueries) {
+ let stmt = db.createAsyncStatement(query);
+ await executeAsync(stmt);
+ stmt.finalize();
+ }
+
+ do_print("Create read-write clone with temp tables");
+ let readWriteClone = await asyncClone(db, false);
+ do_check_true(readWriteClone instanceof Ci.mozIStorageAsyncConnection);
+
+ do_print("Insert into temp table on read-write clone");
+ let insertStmt = readWriteClone.createAsyncStatement(`
+ INSERT INTO test_temp(name) VALUES('mak'), ('standard8'), ('markh')`);
+ await executeAsync(insertStmt);
+ insertStmt.finalize();
+
+ do_print("Fire temp trigger on read-write clone");
+ let deleteStmt = readWriteClone.createAsyncStatement(`
+ DELETE FROM test_temp`);
+ await executeAsync(deleteStmt);
+ deleteStmt.finalize();
+
+ do_print("Read from original connection");
+ let names = [];
+ let readStmt = db.createStatement(`SELECT name FROM test`);
+ while (readStmt.executeStep()) {
+ names.push(readStmt.getUTF8String(0));
+ }
+ readStmt.finalize();
+ do_check_true(names.includes("mak"));
+ do_check_true(names.includes("standard8"));
+ do_check_true(names.includes("markh"));
+
+ do_print("Create read-only clone");
+ let readOnlyClone = await asyncClone(db, true);
+ do_check_true(readOnlyClone instanceof Ci.mozIStorageAsyncConnection);
+
+ do_print("Read-only clone shouldn't have temp entities");
+ let badStmt = readOnlyClone.createAsyncStatement(`SELECT 1 FROM test_temp`);
+ await Assert.rejects(executeAsync(badStmt));
+ badStmt.finalize();
+
+ do_print("Clean up");
+ for (let conn of [db, readWriteClone, readOnlyClone]) {
+ await asyncClose(conn);
+ }
+});
+
+add_task(async function test_sync_clone_in_transaction() {
+ do_print("Open connection");
+ let db = getService().openDatabase(getTestDB());
+ do_check_true(db instanceof Ci.mozIStorageAsyncConnection);
+
+ do_print("Begin transaction on main connection");
+ db.beginTransaction();
+
+ do_print("Create temp table and trigger in transaction");
+ let createQueries = [
+ `CREATE TEMP TABLE test_temp(name TEXT)`,
+ `CREATE TEMP TRIGGER test_temp_afterdelete_trigger
+ AFTER DELETE ON test_temp FOR EACH ROW
+ BEGIN
+ INSERT INTO test(name) VALUES(OLD.name);
+ END`,
+ ];
+ for (let query of createQueries) {
+ db.executeSimpleSQL(query);
+ }
+
+ do_print("Clone main connection while transaction is in progress");
+ let clone = db.clone(/* aReadOnly */ false);
+
+ // Dropping the table also drops `test_temp_afterdelete_trigger`.
+ do_print("Drop temp table on main connection");
+ db.executeSimpleSQL(`DROP TABLE test_temp`);
+
+ do_print("Commit transaction");
+ db.commitTransaction();
+
+ do_print("Clone connection should still have temp entities");
+ let readTempStmt = clone.createStatement(`SELECT 1 FROM test_temp`);
+ readTempStmt.execute();
+ readTempStmt.finalize();
+
+ do_print("Clean up");
+
+ db.close();
+ clone.close();
+});
+
+add_task(async function test_sync_clone_with_function() {
+ do_print("Open connection");
+ let db = getService().openDatabase(getTestDB());
+ do_check_true(db instanceof Ci.mozIStorageAsyncConnection);
+
+ do_print("Create SQL function");
+ function storeLastInsertedNameFunc() {
+ this.name = null;
+ }
+ storeLastInsertedNameFunc.prototype = {
+ onFunctionCall(args) {
+ this.name = args.getUTF8String(0);
+ },
+ };
+ let func = new storeLastInsertedNameFunc();
+ db.createFunction("store_last_inserted_name", 1, func);
+
+ do_print("Create temp trigger on main connection");
+ db.executeSimpleSQL(`
+ CREATE TEMP TRIGGER test_afterinsert_trigger
+ AFTER INSERT ON test FOR EACH ROW
+ BEGIN
+ SELECT store_last_inserted_name(NEW.name);
+ END`);
+
+ do_print("Clone main connection");
+ let clone = db.clone(/* aReadOnly */ false);
+
+ do_print("Write to clone");
+ clone.executeSimpleSQL(`INSERT INTO test(name) VALUES('kit')`);
+
+ do_check_eq(func.name, "kit");
+
+ do_print("Clean up");
+ db.close();
+ clone.close();
+});
+
add_task(async function test_getInterface() {
let db = getOpenedDatabase();
let target = db.QueryInterface(Ci.nsIInterfaceRequestor)
diff --git a/taskcluster/docs/taskgraph.rst b/taskcluster/docs/taskgraph.rst
index e211a5dc4c52..f219ceba4c7e 100644
--- a/taskcluster/docs/taskgraph.rst
+++ b/taskcluster/docs/taskgraph.rst
@@ -145,9 +145,16 @@ So for instance, if you had already requested a build task in the ``try`` comman
and you wish to add a test which depends on this build, the original build task
is re-used.
-Action Tasks are currently scheduled by
-[pulse_actions](https://github.com/mozilla/pulse_actions). This feature is only
-present on ``try`` pushes for now.
+
+Runnable jobs
+-------------
+As part of the execution of the Gecko decision task we generate a
+``public/runnable-jobs.json.gz`` file. It contains a subset of all the data
+contained within the ``full-task-graph.json``.
+
+This file has the minimum ammount of data needed by Treeherder to show all
+tasks that can be scheduled on a push.
+
Task Parameterization
---------------------
diff --git a/taskcluster/taskgraph/decision.py b/taskcluster/taskgraph/decision.py
index b7fd1fef0afd..de1396689fab 100644
--- a/taskcluster/taskgraph/decision.py
+++ b/taskcluster/taskgraph/decision.py
@@ -89,6 +89,25 @@ PER_PROJECT_PARAMETERS = {
}
+def full_task_graph_to_runnable_jobs(full_task_json):
+ runnable_jobs = {}
+ for label, node in full_task_json.iteritems():
+ if not ('extra' in node['task'] and 'treeherder' in node['task']['extra']):
+ continue
+
+ th = node['task']['extra']['treeherder']
+ runnable_jobs[label] = {
+ 'symbol': th['symbol']
+ }
+
+ for i in ('groupName', 'groupSymbol', 'collection'):
+ if i in th:
+ runnable_jobs[label][i] = th[i]
+ if th.get('machine', {}).get('platform'):
+ runnable_jobs[label]['platform'] = th['machine']['platform']
+ return runnable_jobs
+
+
def taskgraph_decision(options, parameters=None):
"""
Run the decision task. This function implements `mach taskgraph decision`,
@@ -118,6 +137,9 @@ def taskgraph_decision(options, parameters=None):
full_task_json = tgg.full_task_graph.to_json()
write_artifact('full-task-graph.json', full_task_json)
+ # write out the public/runnable-jobs.json.gz file
+ write_artifact('runnable-jobs.json.gz', full_task_graph_to_runnable_jobs(full_task_json))
+
# this is just a test to check whether the from_json() function is working
_, _ = TaskGraph.from_json(full_task_json)
@@ -259,5 +281,9 @@ def write_artifact(filename, data):
elif filename.endswith('.json'):
with open(path, 'w') as f:
json.dump(data, f, sort_keys=True, indent=2, separators=(',', ': '))
+ elif filename.endswith('.gz'):
+ import gzip
+ with gzip.open(path, 'wb') as f:
+ f.write(json.dumps(data))
else:
raise TypeError("Don't know how to write to {}".format(filename))
diff --git a/taskcluster/taskgraph/test/python.ini b/taskcluster/taskgraph/test/python.ini
index 2e046977e664..5fac582e51cd 100644
--- a/taskcluster/taskgraph/test/python.ini
+++ b/taskcluster/taskgraph/test/python.ini
@@ -18,6 +18,7 @@ subsuite = taskgraph
[test_util_docker.py]
[test_util_parameterization.py]
[test_util_python_path.py]
+[test_util_runnable_jobs.py]
[test_util_schema.py]
[test_util_templates.py]
[test_util_time.py]
diff --git a/taskcluster/taskgraph/test/test_util_runnable_jobs.py b/taskcluster/taskgraph/test/test_util_runnable_jobs.py
new file mode 100644
index 000000000000..3559ad396f4d
--- /dev/null
+++ b/taskcluster/taskgraph/test/test_util_runnable_jobs.py
@@ -0,0 +1,83 @@
+# 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/.
+
+from __future__ import absolute_import
+
+import unittest
+
+from taskgraph.decision import full_task_graph_to_runnable_jobs
+from taskgraph.graph import Graph
+from taskgraph.taskgraph import TaskGraph
+from taskgraph.task import Task
+from mozunit import main
+
+
+class TestRunnableJobs(unittest.TestCase):
+
+ tasks = [
+ {
+ 'kind': 'build',
+ 'label': 'a',
+ 'attributes': {},
+ 'task': {
+ 'extra': {
+ 'treeherder': {
+ 'symbol': 'B'
+ }
+ },
+ }
+ },
+ {
+ 'kind': 'test',
+ 'label': 'b',
+ 'attributes': {},
+ 'task': {
+ 'extra': {
+ 'treeherder': {
+ 'collection': {
+ 'opt': True
+ },
+ 'groupName': 'Some group',
+ 'groupSymbol': 'GS',
+ 'machine': {
+ 'platform': 'linux64'
+ },
+ 'symbol': 't'
+ }
+ },
+ }
+ },
+ ]
+
+ def make_taskgraph(self, tasks):
+ label_to_taskid = {k: k + '-tid' for k in tasks}
+ for label, task_id in label_to_taskid.iteritems():
+ tasks[label].task_id = task_id
+ graph = Graph(nodes=set(tasks), edges=set())
+ taskgraph = TaskGraph(tasks, graph)
+ return taskgraph, label_to_taskid
+
+ def test_taskgraph_to_runnable_jobs(self):
+ tg, label_to_taskid = self.make_taskgraph({
+ t['label']: Task(**t) for t in self.tasks[:]
+ })
+
+ res = full_task_graph_to_runnable_jobs(tg.to_json())
+
+ self.assertEqual(res, {
+ 'a': {
+ 'symbol': 'B'
+ },
+ 'b': {
+ 'collection': {'opt': True},
+ 'groupName': 'Some group',
+ 'groupSymbol': 'GS',
+ 'symbol': 't',
+ 'platform': 'linux64'
+ }
+ })
+
+
+if __name__ == '__main__':
+ main()
diff --git a/toolkit/components/payments/jar.mn b/toolkit/components/payments/jar.mn
index d577756f2caa..044272304894 100644
--- a/toolkit/components/payments/jar.mn
+++ b/toolkit/components/payments/jar.mn
@@ -11,6 +11,7 @@ toolkit.jar:
% resource payments %res/payments/
res/payments (res/paymentRequest.*)
res/payments/components/ (res/components/*.js)
+ res/payments/containers/ (res/containers/*.js)
res/payments/debugging.html (res/debugging.html)
res/payments/debugging.js (res/debugging.js)
res/payments/mixins/ (res/mixins/*.js)
diff --git a/toolkit/components/payments/res/components/currency-amount.js b/toolkit/components/payments/res/components/currency-amount.js
index 1cc0bd62f84b..a7024f2e006f 100644
--- a/toolkit/components/payments/res/components/currency-amount.js
+++ b/toolkit/components/payments/res/components/currency-amount.js
@@ -2,6 +2,8 @@
* 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";
+
/**
*
*/
diff --git a/toolkit/components/payments/res/containers/payment-dialog.js b/toolkit/components/payments/res/containers/payment-dialog.js
new file mode 100644
index 000000000000..dcafbca84225
--- /dev/null
+++ b/toolkit/components/payments/res/containers/payment-dialog.js
@@ -0,0 +1,55 @@
+/* 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/. */
+
+/* global PaymentStateSubscriberMixin, PaymentRequest */
+
+"use strict";
+
+/**
+ *
+ */
+
+class PaymentDialog extends PaymentStateSubscriberMixin(HTMLElement) {
+ constructor() {
+ super();
+ this._template = document.getElementById("payment-dialog-template");
+ }
+
+ connectedCallback() {
+ let contents = document.importNode(this._template.content, true);
+ this._hostNameEl = contents.querySelector("#host-name");
+
+ this._cancelButton = contents.querySelector("#cancel");
+ this._cancelButton.addEventListener("click", this.cancelRequest);
+
+ this.appendChild(contents);
+
+ super.connectedCallback();
+ }
+
+ disconnectedCallback() {
+ this._cancelButtonEl.removeEventListener("click", this.cancelRequest);
+ super.disconnectedCallback();
+ }
+
+ cancelRequest() {
+ PaymentRequest.cancel();
+ }
+
+ setLoadingState(state) {
+ this.requestStore.setState(state);
+ }
+
+ render(state) {
+ let request = state.request;
+ this._hostNameEl.textContent = request.topLevelPrincipal.URI.displayHost;
+
+ let totalItem = request.paymentDetails.totalItem;
+ let totalAmountEl = this.querySelector("#total > currency-amount");
+ totalAmountEl.value = totalItem.amount.value;
+ totalAmountEl.currency = totalItem.amount.currency;
+ }
+}
+
+customElements.define("payment-dialog", PaymentDialog);
diff --git a/toolkit/components/payments/res/debugging.html b/toolkit/components/payments/res/debugging.html
index 0c044220a5f8..f42976ca7b9b 100644
--- a/toolkit/components/payments/res/debugging.html
+++ b/toolkit/components/payments/res/debugging.html
@@ -11,6 +11,9 @@
Refresh
+ Log state
+ Set Request 1
+ Set Request 2
diff --git a/toolkit/components/payments/res/debugging.js b/toolkit/components/payments/res/debugging.js
index 6d5ace18a310..19979b783e6c 100644
--- a/toolkit/components/payments/res/debugging.js
+++ b/toolkit/components/payments/res/debugging.js
@@ -2,10 +2,133 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+const requestStore = window.parent.document.querySelector("payment-dialog").requestStore;
+
+let REQUEST_1 = {
+ tabId: 9,
+ topLevelPrincipal: {URI: {displayHost: "tschaeff.github.io"}},
+ requestId: "3797081f-a96b-c34b-a58b-1083c6e66e25",
+ paymentMethods: [],
+ paymentDetails: {
+ id: "",
+ totalItem: {label: "Demo total", amount: {currency: "EUR", value: "1.00"}, pending: false},
+ displayItems: [
+ {
+ label: "Square",
+ amount: {
+ currency: "USD",
+ value: "5",
+ },
+ },
+ ],
+ shippingOptions: [
+ {
+ id: "123",
+ label: "Fast",
+ amount: {
+ currency: "USD",
+ value: 10,
+ },
+ selected: false,
+ },
+ {
+ id: "456",
+ label: "Faster (default)",
+ amount: {
+ currency: "USD",
+ value: 20,
+ },
+ selected: true,
+ },
+ ],
+ modifiers: null,
+ error: "",
+ },
+ paymentOptions: {
+ requestPayerName: false,
+ requestPayerEmail: false,
+ requestPayerPhone: false,
+ requestShipping: false,
+ shippingType: "shipping",
+ },
+};
+
+let REQUEST_2 = {
+ tabId: 9,
+ topLevelPrincipal: {URI: {displayHost: "example.com"}},
+ requestId: "3797081f-a96b-c34b-a58b-1083c6e66e25",
+ paymentMethods: [],
+ paymentDetails: {
+ id: "",
+ totalItem: {label: "Demo total", amount: {currency: "CAD", value: "25.75"}, pending: false},
+ displayItems: [
+ {
+ label: "Triangle",
+ amount: {
+ currency: "CAD",
+ value: "3",
+ },
+ },
+ {
+ label: "Circle",
+ amount: {
+ currency: "EUR",
+ value: "10.50",
+ },
+ },
+ ],
+ shippingOptions: [
+ {
+ id: "123",
+ label: "Fast (default)",
+ amount: {
+ currency: "USD",
+ value: 10,
+ },
+ selected: true,
+ },
+ {
+ id: "947",
+ label: "Slow",
+ amount: {
+ currency: "USD",
+ value: 10,
+ },
+ selected: false,
+ },
+ ],
+ modifiers: null,
+ error: "",
+ },
+ paymentOptions: {
+ requestPayerName: false,
+ requestPayerEmail: false,
+ requestPayerPhone: false,
+ requestShipping: false,
+ shippingType: "shipping",
+ },
+};
+
+
let buttonActions = {
+ logState() {
+ let state = requestStore.getState();
+ // eslint-disable-next-line no-console
+ console.log(state);
+ dump(`${JSON.stringify(state, null, 2)}\n`);
+ },
+
refresh() {
window.parent.location.reload(true);
},
+
+ setRequest1() {
+ requestStore.setState({request: REQUEST_1});
+ },
+
+ setRequest2() {
+ requestStore.setState({request: REQUEST_2});
+ },
};
window.addEventListener("click", function onButtonClick(evt) {
diff --git a/toolkit/components/payments/res/mixins/ObservedPropertiesMixin.js b/toolkit/components/payments/res/mixins/ObservedPropertiesMixin.js
index a7fb6892127f..e065a24e355b 100644
--- a/toolkit/components/payments/res/mixins/ObservedPropertiesMixin.js
+++ b/toolkit/components/payments/res/mixins/ObservedPropertiesMixin.js
@@ -57,6 +57,9 @@ function ObservedPropertiesMixin(superClass) {
}
attributeChangedCallback(attr, oldValue, newValue) {
+ if (super.attributeChangedCallback) {
+ super.attributeChangedCallback(attr, oldValue, newValue);
+ }
if (oldValue === newValue) {
return;
}
diff --git a/toolkit/components/payments/res/mixins/PaymentStateSubscriberMixin.js b/toolkit/components/payments/res/mixins/PaymentStateSubscriberMixin.js
new file mode 100644
index 000000000000..44ce9e0b1076
--- /dev/null
+++ b/toolkit/components/payments/res/mixins/PaymentStateSubscriberMixin.js
@@ -0,0 +1,82 @@
+/* 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";
+
+/* global PaymentsStore */
+
+/**
+ * A mixin for a custom element to observe store changes to information about a payment request.
+ */
+
+/**
+ * State of the payment request dialog.
+ */
+let requestStore = new PaymentsStore({
+ request: {
+ tabId: null,
+ topLevelPrincipal: {URI: {displayHost: null}},
+ requestId: null,
+ paymentMethods: [],
+ paymentDetails: {
+ id: null,
+ totalItem: {label: null, amount: {currency: null, value: null}},
+ displayItems: [],
+ shippingOptions: [],
+ modifiers: null,
+ error: "",
+ },
+ paymentOptions: {
+ requestPayerName: false,
+ requestPayerEmail: false,
+ requestPayerPhone: false,
+ requestShipping: false,
+ shippingType: "shipping",
+ },
+ },
+ savedAddresses: [],
+ savedBasicCards: [],
+});
+
+
+/* exported PaymentStateSubscriberMixin */
+
+/**
+ * A mixin to render UI based upon the requestStore and get updated when that store changes.
+ *
+ * Attaches `requestStore` to the element to give access to the store.
+ * @param {class} superClass The class to extend
+ * @returns {class}
+ */
+function PaymentStateSubscriberMixin(superClass) {
+ return class PaymentStateSubscriber extends superClass {
+ constructor() {
+ super();
+ this.requestStore = requestStore;
+ }
+
+ connectedCallback() {
+ this.requestStore.subscribe(this);
+ this.render(this.requestStore.getState());
+ if (super.connectedCallback) {
+ super.connectedCallback();
+ }
+ }
+
+ disconnectedCallback() {
+ this.requestStore.unsubscribe(this);
+ if (super.disconnectedCallback) {
+ super.disconnectedCallback();
+ }
+ }
+
+ /**
+ * Called by the store upon state changes.
+ * @param {object} state The current state
+ */
+ stateChangeCallback(state) {
+ this.render(state);
+ }
+ };
+}
diff --git a/toolkit/components/payments/res/paymentRequest.js b/toolkit/components/payments/res/paymentRequest.js
index 9979c89f847e..67245748884f 100644
--- a/toolkit/components/payments/res/paymentRequest.js
+++ b/toolkit/components/payments/res/paymentRequest.js
@@ -11,7 +11,6 @@
"use strict";
let PaymentRequest = {
- request: null,
domReadyPromise: null,
init() {
@@ -34,15 +33,6 @@ let PaymentRequest = {
this.onPaymentRequestLoad();
break;
}
- case "click": {
- switch (event.target.id) {
- case "cancel": {
- this.onCancel();
- break;
- }
- }
- break;
- }
case "keypress": {
if (event.code != "KeyD" || !event.altKey || !event.ctrlKey) {
break;
@@ -80,37 +70,29 @@ let PaymentRequest = {
switch (messageType) {
case "showPaymentRequest": {
- this.request = detail.request;
- this.onShowPaymentRequest();
+ this.onShowPaymentRequest(detail);
break;
}
}
},
onPaymentRequestLoad(requestId) {
- let cancelBtn = document.getElementById("cancel");
- cancelBtn.addEventListener("click", this, {once: true});
-
window.addEventListener("unload", this, {once: true});
this.sendMessageToChrome("paymentDialogReady");
},
- async onShowPaymentRequest() {
+ async onShowPaymentRequest(detail) {
// Handle getting called before the DOM is ready.
await this.domReadyPromise;
- let hostNameEl = document.getElementById("host-name");
- hostNameEl.textContent = this.request.topLevelPrincipal.URI.displayHost;
-
- let totalItem = this.request.paymentDetails.totalItem;
- let totalEl = document.getElementById("total");
- let currencyEl = totalEl.querySelector("currency-amount");
- currencyEl.value = totalItem.amount.value;
- currencyEl.currency = totalItem.amount.currency;
- totalEl.querySelector(".label").textContent = totalItem.label;
+ document.querySelector("payment-dialog").setLoadingState({
+ request: detail.request,
+ savedAddresses: detail.savedAddresses,
+ savedBasicCards: detail.savedBasicCards,
+ });
},
- onCancel() {
+ cancel() {
this.sendMessageToChrome("paymentCancel");
},
diff --git a/toolkit/components/payments/res/paymentRequest.xhtml b/toolkit/components/payments/res/paymentRequest.xhtml
index 0453be74a153..ceb861e1222e 100644
--- a/toolkit/components/payments/res/paymentRequest.xhtml
+++ b/toolkit/components/payments/res/paymentRequest.xhtml
@@ -9,20 +9,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Cancel payment
+
+
-
-
-
-
-
-
- Cancel payment
-
+