Update On Fri Sep 24 14:42:52 CEST 2021

This commit is contained in:
github-action[bot] 2021-09-24 14:42:52 +02:00
parent 5d18fcba10
commit 7d77582284
69 changed files with 1596 additions and 530 deletions

View file

@ -622,6 +622,10 @@ AtkRole getRoleCB(AtkObject* aAtkObj) {
aAtkObj->role = ATK_ROLE_SECTION;
} else if (aAtkObj->role == ATK_ROLE_COMMENT && !IsAtkVersionAtLeast(2, 36)) {
aAtkObj->role = ATK_ROLE_SECTION;
} else if ((aAtkObj->role == ATK_ROLE_CONTENT_DELETION ||
aAtkObj->role == ATK_ROLE_CONTENT_INSERTION) &&
!IsAtkVersionAtLeast(2, 34)) {
aAtkObj->role = ATK_ROLE_SECTION;
}
return aAtkObj->role;

View file

@ -35,7 +35,7 @@ void AccAttributes::StringFromValueAndName(nsAtom* aAttrName,
[&aValueString](const RefPtr<nsAtom>& val) {
val->ToString(aValueString);
},
[&aValueString](const CopyableTArray<int32_t>& val) {
[&aValueString](const nsTArray<int32_t>& val) {
for (size_t i = 0; i < val.Length() - 1; i++) {
aValueString.AppendInt(val[i]);
aValueString.Append(u", ");
@ -59,12 +59,12 @@ void AccAttributes::StringFromValueAndName(nsAtom* aAttrName,
}
void AccAttributes::Update(AccAttributes* aOther) {
for (auto entry : *aOther) {
if (entry.mValue->is<DeleteEntry>()) {
mData.Remove(entry.mName);
continue;
for (auto iter = aOther->mData.Iter(); !iter.Done(); iter.Next()) {
if (iter.Data().is<DeleteEntry>()) {
mData.Remove(iter.Key());
} else {
mData.InsertOrUpdate(iter.Key(), std::move(iter.Data()));
}
mData.InsertOrUpdate(entry.mName, *entry.mValue);
iter.Remove();
}
}

View file

@ -45,8 +45,8 @@ struct DeleteEntry {
class AccAttributes {
friend struct IPC::ParamTraits<AccAttributes*>;
using AttrValueType =
Variant<bool, float, double, int32_t, RefPtr<nsAtom>,
CopyableTArray<int32_t>, CSSCoord, FontSize, Color, DeleteEntry>;
Variant<bool, float, double, int32_t, RefPtr<nsAtom>, nsTArray<int32_t>,
CSSCoord, FontSize, Color, DeleteEntry>;
static_assert(sizeof(AttrValueType) <= 16);
using AtomVariantMap = nsTHashMap<nsRefPtrHashKey<nsAtom>, AttrValueType>;
@ -62,30 +62,29 @@ class AccAttributes {
NS_INLINE_DECL_REFCOUNTING(mozilla::a11y::AccAttributes)
template <typename T>
void SetAttribute(nsAtom* aAttrName, const T& aAttrValue) {
if constexpr (std::is_base_of_v<nsAtom, std::remove_pointer_t<T>>) {
mData.InsertOrUpdate(aAttrName, AsVariant(RefPtr<nsAtom>(aAttrValue)));
} else if constexpr (std::is_base_of_v<nsAString, T> ||
std::is_base_of_v<nsLiteralString, T>) {
RefPtr<nsAtom> atomValue = NS_Atomize(aAttrValue);
mData.InsertOrUpdate(aAttrName, AsVariant(atomValue));
} else {
mData.InsertOrUpdate(aAttrName, AsVariant(aAttrValue));
}
template <typename T,
typename std::enable_if<!std::is_convertible_v<T, nsString> &&
!std::is_convertible_v<T, nsAtom*>,
bool>::type = true>
void SetAttribute(nsAtom* aAttrName, T&& aAttrValue) {
mData.InsertOrUpdate(aAttrName, AsVariant(std::forward<T>(aAttrValue)));
}
void SetAttribute(nsAtom* aAttrName, const nsAString& aAttrValue) {
RefPtr<nsAtom> atomValue = NS_Atomize(aAttrValue);
mData.InsertOrUpdate(aAttrName, AsVariant(atomValue));
}
void SetAttribute(nsAtom* aAttrName, nsAtom* aAttrValue) {
mData.InsertOrUpdate(aAttrName, AsVariant(RefPtr<nsAtom>(aAttrValue)));
}
template <typename T>
Maybe<T> GetAttribute(nsAtom* aAttrName) {
Maybe<const T&> GetAttribute(nsAtom* aAttrName) {
if (auto value = mData.Lookup(aAttrName)) {
if constexpr (std::is_base_of_v<nsAtom, std::remove_pointer_t<T>>) {
if (value->is<RefPtr<nsAtom>>()) {
return Some(value->as<RefPtr<nsAtom>>().get());
}
} else {
if (value->is<T>()) {
return Some(value->as<T>());
}
if (value->is<T>()) {
const T& val = value->as<T>();
return SomeRef(val);
}
}
return Nothing();
@ -98,6 +97,8 @@ class AccAttributes {
uint32_t Count() const { return mData.Count(); }
// Update one instance with the entries in another. The supplied AccAttributes
// will be emptied.
void Update(AccAttributes* aOther);
// An entry class for our iterator.
@ -109,15 +110,10 @@ class AccAttributes {
nsAtom* Name() { return mName; }
template <typename T>
Maybe<T> Value() {
if constexpr (std::is_base_of_v<nsAtom, std::remove_pointer_t<T>>) {
if (mValue->is<RefPtr<nsAtom>>()) {
return Some(mValue->as<RefPtr<nsAtom>>().get());
}
} else {
if (mValue->is<T>()) {
return Some(mValue->as<T>());
}
Maybe<const T&> Value() {
if (mValue->is<T>()) {
const T& val = mValue->as<T>();
return SomeRef(val);
}
return Nothing();
}

View file

@ -1789,7 +1789,7 @@ ROLE(BLOCKQUOTE,
ROLE(CONTENT_DELETION,
"content deletion",
ATK_ROLE_SECTION,
ATK_ROLE_CONTENT_DELETION,
NSAccessibilityGroupRole,
@"AXDeleteStyleGroup",
USE_ROLE_STRING,
@ -1799,7 +1799,7 @@ ROLE(CONTENT_DELETION,
ROLE(CONTENT_INSERTION,
"content insertion",
ATK_ROLE_SECTION,
ATK_ROLE_CONTENT_INSERTION,
NSAccessibilityGroupRole,
@"AXInsertStyleGroup",
USE_ROLE_STRING,

View file

@ -133,7 +133,7 @@ struct ParamTraits<mozilla::a11y::AccAttributes*> {
if (!ReadParam(aMsg, aIter, &val)) {
return false;
}
(*aResult)->mData.InsertOrUpdate(key, val);
(*aResult)->mData.InsertOrUpdate(key, std::move(val));
}
return true;
}

View file

@ -450,7 +450,7 @@ static NSDictionary* StringAttributesFromAttributes(AccAttributes* aAttributes,
}
} else if (iter.Name() == nsGkAtoms::invalid) {
// XXX: There is currently no attribute for grammar
if (Maybe<nsAtom*> value = iter.Value<nsAtom*>()) {
if (auto value = iter.Value<RefPtr<nsAtom>>()) {
if (*value == nsGkAtoms::spelling) {
[attrDict setObject:@YES
forKey:NSAccessibilityMarkedMisspelledTextAttribute];

View file

@ -1476,6 +1476,7 @@ pref("browser.newtabpage.activity-stream.discoverystream.hardcoded-basic-layout"
pref("browser.newtabpage.activity-stream.discoverystream.compactLayout.enabled", false);
pref("browser.newtabpage.activity-stream.discoverystream.loadMore.enabled", false);
pref("browser.newtabpage.activity-stream.discoverystream.lastCardMessage.enabled", false);
pref("browser.newtabpage.activity-stream.discoverystream.newFooterSection.enabled", false);
pref("browser.newtabpage.activity-stream.discoverystream.spoc-positions", "2,4,11,20");
pref("browser.newtabpage.activity-stream.discoverystream.spocs-endpoint", "");
pref("browser.newtabpage.activity-stream.discoverystream.spocs-endpoint-query", "");

View file

@ -24,6 +24,7 @@ https_first_disabled = true
https_first_disabled = true
[browser_protectionsUI_cryptominers.js]
https_first_disabled = true
[browser_protectionsUI_dfpi_rollout.js]
[browser_protectionsUI_fetch.js]
https_first_disabled = true
support-files =

View file

@ -0,0 +1,31 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
const PREF_DFPI_ENABLED_BY_DEFAULT =
"privacy.restrict3rdpartystorage.rollout.enabledByDefault";
const COOKIE_BEHAVIOR_PREF = "network.cookie.cookieBehavior";
const defaultPrefs = Services.prefs.getDefaultBranch("");
const previousDefaultCB = defaultPrefs.getIntPref(COOKIE_BEHAVIOR_PREF);
registerCleanupFunction(function() {
defaultPrefs.setIntPref(COOKIE_BEHAVIOR_PREF, previousDefaultCB);
});
// Tests that the dFPI rollout pref updates the default cookieBehavior to 5
add_task(async function testdFPIRolloutPref() {
defaultPrefs.setIntPref(
COOKIE_BEHAVIOR_PREF,
Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER
);
Services.prefs.setBoolPref(PREF_DFPI_ENABLED_BY_DEFAULT, false);
is(
defaultPrefs.getIntPref(COOKIE_BEHAVIOR_PREF),
Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER
);
Services.prefs.setBoolPref(PREF_DFPI_ENABLED_BY_DEFAULT, true);
is(
defaultPrefs.getIntPref(COOKIE_BEHAVIOR_PREF),
Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN
);
});

View file

@ -123,6 +123,8 @@ XPCOMUtils.defineLazyServiceGetters(this, {
});
const PREF_PDFJS_ISDEFAULT_CACHE_STATE = "pdfjs.enabledCache.state";
const PREF_DFPI_ENABLED_BY_DEFAULT =
"privacy.restrict3rdpartystorage.rollout.enabledByDefault";
/**
* Fission-compatible JSProcess implementations.
@ -1337,6 +1339,10 @@ BrowserGlue.prototype = {
"browser.contentblocking.features.strict",
this._setPrefExpectationsAndUpdate
);
Services.prefs.removeObserver(
PREF_DFPI_ENABLED_BY_DEFAULT,
this._setDefaultCookieBehavior
);
},
// runs on startup, before the first command line handler is invoked
@ -1855,6 +1861,9 @@ BrowserGlue.prototype = {
PlacesUtils.favicons.setDefaultIconURIPreferredSize(
16 * aWindow.devicePixelRatio
);
// _setDefaultCookieBehavior needs to run before other functions that modify
// privacy preferences such as _setPrefExpectationsAndUpdate and _matchCBCategory
this._setDefaultCookieBehavior();
this._setPrefExpectationsAndUpdate();
this._matchCBCategory();
@ -1895,6 +1904,10 @@ BrowserGlue.prototype = {
"browser.contentblocking.features.strict",
this._setPrefExpectationsAndUpdate
);
Services.prefs.addObserver(
PREF_DFPI_ENABLED_BY_DEFAULT,
this._setDefaultCookieBehavior
);
},
_updateAutoplayPref() {
@ -1908,6 +1921,20 @@ BrowserGlue.prototype = {
}
},
// For the initial rollout of dFPI, set the default cookieBehavior based on the pref
// set during onboarding when the user chooses to enable protections or not.
_setDefaultCookieBehavior() {
if (!Services.prefs.getBoolPref(PREF_DFPI_ENABLED_BY_DEFAULT, false)) {
return;
}
let defaultPrefs = Services.prefs.getDefaultBranch("");
defaultPrefs.setIntPref(
"network.cookie.cookieBehavior",
Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN
);
},
_setPrefExpectations() {
ContentBlockingCategoriesPrefs.setPrefExpectations();
},

View file

@ -15,6 +15,7 @@ import { Highlights } from "content-src/components/DiscoveryStreamComponents/Hig
import { HorizontalRule } from "content-src/components/DiscoveryStreamComponents/HorizontalRule/HorizontalRule";
import { List } from "content-src/components/DiscoveryStreamComponents/List/List";
import { Navigation } from "content-src/components/DiscoveryStreamComponents/Navigation/Navigation";
import { PrivacyLink } from "content-src/components/DiscoveryStreamComponents/PrivacyLink/PrivacyLink";
import React from "react";
import { SectionTitle } from "content-src/components/DiscoveryStreamComponents/SectionTitle/SectionTitle";
import { selectLayoutRender } from "content-src/lib/selectLayoutRender";
@ -168,11 +169,13 @@ export class _DiscoveryStreamBase extends React.PureComponent {
<Navigation
dispatch={this.props.dispatch}
links={component.properties.links}
extraLinks={component.properties.extraLinks}
alignment={component.properties.alignment}
display_variant={component.properties.display_variant}
explore_topics={component.properties.explore_topics}
header={component.header}
locale={this.props.App.locale}
newFooterSection={component.newFooterSection}
privacyNoticeURL={component.properties.privacyNoticeURL}
/>
);
@ -244,6 +247,8 @@ export class _DiscoveryStreamBase extends React.PureComponent {
header={component.header}
/>
);
case "PrivacyLink":
return <PrivacyLink properties={component.properties} />;
default:
return <div>{component.type}</div>;
}
@ -305,6 +310,7 @@ export class _DiscoveryStreamBase extends React.PureComponent {
title: topStories.title,
},
};
const privacyLinkComponent = extractComponent("PrivacyLink");
// Render a DS-style TopSites then the rest if any in a collapsible section
return (
@ -353,6 +359,13 @@ export class _DiscoveryStreamBase extends React.PureComponent {
components: [{ type: "Highlights" }],
},
])}
{privacyLinkComponent &&
this.renderLayout([
{
width: 12,
components: [privacyLinkComponent],
},
])}
</React.Fragment>
);
}

View file

@ -56,7 +56,7 @@ $ds-width: 936px;
.section-top-bar {
.learn-more-link a {
color: var(--newtab-primary-action-background);
font-weight: normal;
font-weight: 500;
&:is(:focus, :hover) {
text-decoration: underline;

View file

@ -225,7 +225,7 @@ $col4-header-font-size: 14;
.ds-layout {
.ds-card-grid-load-more-button {
display: block;
margin: 33px auto;
margin: 32px auto 0;
font-size: 13px;
line-height: 16px;
border-radius: 4px;

View file

@ -45,16 +45,31 @@ export class Topic extends React.PureComponent {
export class Navigation extends React.PureComponent {
render() {
const links = this.props.links || [];
let links = this.props.links || [];
const alignment = this.props.alignment || "centered";
const header = this.props.header || {};
const english = this.props.locale.startsWith("en-");
const privacyNotice = this.props.privacyNoticeURL || {};
const { newFooterSection } = this.props;
const className = `ds-navigation ds-navigation-${alignment} ${
newFooterSection ? `ds-navigation-new-topics` : ``
}`;
let { title } = header;
if (newFooterSection) {
title = { id: "newtab-pocket-new-topics-title" };
if (this.props.extraLinks) {
links = [
...links.slice(0, links.length - 1),
...this.props.extraLinks,
links[links.length - 1],
];
}
}
return (
<div className={`ds-navigation ds-navigation-${alignment}`}>
{header.title && english ? (
<FluentOrText message={header.title}>
<div className={className}>
{title && english ? (
<FluentOrText message={title}>
<span className="ds-navigation-header" />
</FluentOrText>
) : null}
@ -74,13 +89,23 @@ export class Navigation extends React.PureComponent {
</ul>
) : null}
<SafeAnchor
onLinkClick={this.onLinkClick}
className="ds-navigation-privacy"
url={privacyNotice.url}
>
<FluentOrText message={privacyNotice.title} />
</SafeAnchor>
{!newFooterSection ? (
<SafeAnchor className="ds-navigation-privacy" url={privacyNotice.url}>
<FluentOrText message={privacyNotice.title} />
</SafeAnchor>
) : null}
{newFooterSection ? (
<div className="ds-navigation-family">
<span className="icon firefox-logo" />
<span>|</span>
<span className="icon pocket-logo" />
<span
className="ds-navigation-family-message"
data-l10n-id="newtab-pocket-pocket-firefox-family"
/>
</div>
) : null}
</div>
);
}

View file

@ -60,4 +60,102 @@
text-decoration: underline;
}
}
&.ds-navigation-new-topics {
display: block;
padding-top: 32px;
.ds-navigation-header {
font-size: 14px;
line-height: 20px;
font-weight: 700;
display: inline-block;
margin-bottom: 8px;
}
.ds-navigation-family {
text-align: center;
font-size: 14px;
line-height: 20px;
margin: 16px auto 28px;
span {
margin: 0 6px;
}
.firefox-logo,
.pocket-logo {
height: 20px;
width: 20px;
background-size: cover;
}
.firefox-logo {
background-image: url('chrome://activity-stream/content/data/content/assets/firefox.svg');
}
.pocket-logo {
background-image: url('chrome://global/skin/icons/pocket.svg');
fill: $pocket-icon-fill;
}
.ds-navigation-family-message {
font-weight: 400;
display: block;
@media (min-width: $break-point-medium) {
display: inline;
}
}
@media (min-width: $break-point-medium) {
margin-top: 43px;
}
}
ul {
display: grid;
grid-gap: 0 24px;
grid-auto-flow: column;
grid-template: repeat(8, 1fr) / repeat(1, 1fr);
li {
border-top: $border-primary;
border-bottom: $border-primary;
margin-bottom: -1px;
line-height: 24px;
font-size: 13px;
font-weight: 500;
&::after {
content: '';
padding: 0;
}
&:nth-last-child(2),
&:nth-last-child(3) {
display: none;
}
}
@media (min-width: $break-point-medium) {
grid-template: repeat(3, 1fr) / repeat(2, 1fr);
}
@media (min-width: $break-point-large) {
grid-template: repeat(2, 1fr) / repeat(3, 1fr);
}
@media (min-width: $break-point-widest) {
grid-template: repeat(2, 1fr) / repeat(4, 1fr);
li {
&:nth-last-child(2),
&:nth-last-child(3) {
display: block;
}
}
}
}
}
}

View file

@ -0,0 +1,20 @@
/* 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/. */
import React from "react";
import { SafeAnchor } from "../SafeAnchor/SafeAnchor";
import { FluentOrText } from "content-src/components/FluentOrText/FluentOrText";
export class PrivacyLink extends React.PureComponent {
render() {
const { properties } = this.props;
return (
<div className="ds-privacy-link">
<SafeAnchor url={properties.url}>
<FluentOrText message={properties.title} />
</SafeAnchor>
</div>
);
}
}

View file

@ -0,0 +1,10 @@
.ds-privacy-link {
text-align: center;
font-size: 13px;
font-weight: 500;
line-height: 24px;
a:hover {
text-decoration: underline;
}
}

View file

@ -60,6 +60,7 @@ export const selectLayoutRender = ({ state = {}, prefs = {}, locale = "" }) => {
"Hero",
"HorizontalRule",
"List",
"PrivacyLink",
];
const filterArray = [];

View file

@ -168,6 +168,7 @@ input {
@import '../components/DiscoveryStreamComponents/DSTextPromo/DSTextPromo';
@import '../components/DiscoveryStreamComponents/DSSignup/DSSignup';
@import '../components/DiscoveryStreamComponents/DSPrivacyModal/DSPrivacyModal';
@import '../components/DiscoveryStreamComponents/PrivacyLink/PrivacyLink';
// AS Router
@import '../asrouter/components/Button/Button';

View file

@ -35,7 +35,7 @@ $status-green: #058B00;
$status-dark-green: #7C6;
$bookmark-icon-fill: #0A84FF;
$download-icon-fill: #12BC00;
$pocket-icon-fill: #D70022;
$pocket-icon-fill: #EF4056;
$email-input-invalid: rgba($red-60, 0.3);
$newtab-wordmark-default-color: #20123A;

View file

@ -2135,7 +2135,7 @@ main.has-snippet {
fill: #12BC00;
}
.compact-cards .card-outer .card-context .card-context-icon.icon-pocket {
fill: #D70022;
fill: #EF4056;
}
.compact-cards .card-outer .card-context .card-context-label {
display: none;
@ -2574,7 +2574,7 @@ main.has-snippet {
}
.collapsible-section.ds-layout .section-top-bar .learn-more-link a {
color: var(--newtab-primary-action-background);
font-weight: normal;
font-weight: 500;
}
.collapsible-section.ds-layout .section-top-bar .learn-more-link a:is(:focus, :hover) {
text-decoration: underline;
@ -2758,7 +2758,7 @@ main.has-snippet {
.ds-layout .ds-card-grid-load-more-button {
display: block;
margin: 33px auto;
margin: 32px auto 0;
font-size: 13px;
line-height: 16px;
border-radius: 4px;
@ -3290,6 +3290,92 @@ main.has-snippet {
.ds-navigation .ds-navigation-privacy:hover {
text-decoration: underline;
}
.ds-navigation.ds-navigation-new-topics {
display: block;
padding-top: 32px;
}
.ds-navigation.ds-navigation-new-topics .ds-navigation-header {
font-size: 14px;
line-height: 20px;
font-weight: 700;
display: inline-block;
margin-bottom: 8px;
}
.ds-navigation.ds-navigation-new-topics .ds-navigation-family {
text-align: center;
font-size: 14px;
line-height: 20px;
margin: 16px auto 28px;
}
.ds-navigation.ds-navigation-new-topics .ds-navigation-family span {
margin: 0 6px;
}
.ds-navigation.ds-navigation-new-topics .ds-navigation-family .firefox-logo,
.ds-navigation.ds-navigation-new-topics .ds-navigation-family .pocket-logo {
height: 20px;
width: 20px;
background-size: cover;
}
.ds-navigation.ds-navigation-new-topics .ds-navigation-family .firefox-logo {
background-image: url("chrome://activity-stream/content/data/content/assets/firefox.svg");
}
.ds-navigation.ds-navigation-new-topics .ds-navigation-family .pocket-logo {
background-image: url("chrome://global/skin/icons/pocket.svg");
fill: #EF4056;
}
.ds-navigation.ds-navigation-new-topics .ds-navigation-family .ds-navigation-family-message {
font-weight: 400;
display: block;
}
@media (min-width: 610px) {
.ds-navigation.ds-navigation-new-topics .ds-navigation-family .ds-navigation-family-message {
display: inline;
}
}
@media (min-width: 610px) {
.ds-navigation.ds-navigation-new-topics .ds-navigation-family {
margin-top: 43px;
}
}
.ds-navigation.ds-navigation-new-topics ul {
display: grid;
grid-gap: 0 24px;
grid-auto-flow: column;
grid-template: repeat(8, 1fr)/repeat(1, 1fr);
}
.ds-navigation.ds-navigation-new-topics ul li {
border-top: 1px solid var(--newtab-border-color);
border-bottom: 1px solid var(--newtab-border-color);
margin-bottom: -1px;
line-height: 24px;
font-size: 13px;
font-weight: 500;
}
.ds-navigation.ds-navigation-new-topics ul li::after {
content: "";
padding: 0;
}
.ds-navigation.ds-navigation-new-topics ul li:nth-last-child(2), .ds-navigation.ds-navigation-new-topics ul li:nth-last-child(3) {
display: none;
}
@media (min-width: 610px) {
.ds-navigation.ds-navigation-new-topics ul {
grid-template: repeat(3, 1fr)/repeat(2, 1fr);
}
}
@media (min-width: 866px) {
.ds-navigation.ds-navigation-new-topics ul {
grid-template: repeat(2, 1fr)/repeat(3, 1fr);
}
}
@media (min-width: 1122px) {
.ds-navigation.ds-navigation-new-topics ul {
grid-template: repeat(2, 1fr)/repeat(4, 1fr);
}
.ds-navigation.ds-navigation-new-topics ul li:nth-last-child(2), .ds-navigation.ds-navigation-new-topics ul li:nth-last-child(3) {
display: block;
}
}
.ds-section-title {
text-align: center;
@ -4054,6 +4140,16 @@ main.has-snippet {
margin: auto;
}
.ds-privacy-link {
text-align: center;
font-size: 13px;
font-weight: 500;
line-height: 24px;
}
.ds-privacy-link a:hover {
text-decoration: underline;
}
.ASRouterButton {
font-weight: 600;
font-size: 14px;

View file

@ -2139,7 +2139,7 @@ main.has-snippet {
fill: #12BC00;
}
.compact-cards .card-outer .card-context .card-context-icon.icon-pocket {
fill: #D70022;
fill: #EF4056;
}
.compact-cards .card-outer .card-context .card-context-label {
display: none;
@ -2578,7 +2578,7 @@ main.has-snippet {
}
.collapsible-section.ds-layout .section-top-bar .learn-more-link a {
color: var(--newtab-primary-action-background);
font-weight: normal;
font-weight: 500;
}
.collapsible-section.ds-layout .section-top-bar .learn-more-link a:is(:focus, :hover) {
text-decoration: underline;
@ -2762,7 +2762,7 @@ main.has-snippet {
.ds-layout .ds-card-grid-load-more-button {
display: block;
margin: 33px auto;
margin: 32px auto 0;
font-size: 13px;
line-height: 16px;
border-radius: 4px;
@ -3294,6 +3294,92 @@ main.has-snippet {
.ds-navigation .ds-navigation-privacy:hover {
text-decoration: underline;
}
.ds-navigation.ds-navigation-new-topics {
display: block;
padding-top: 32px;
}
.ds-navigation.ds-navigation-new-topics .ds-navigation-header {
font-size: 14px;
line-height: 20px;
font-weight: 700;
display: inline-block;
margin-bottom: 8px;
}
.ds-navigation.ds-navigation-new-topics .ds-navigation-family {
text-align: center;
font-size: 14px;
line-height: 20px;
margin: 16px auto 28px;
}
.ds-navigation.ds-navigation-new-topics .ds-navigation-family span {
margin: 0 6px;
}
.ds-navigation.ds-navigation-new-topics .ds-navigation-family .firefox-logo,
.ds-navigation.ds-navigation-new-topics .ds-navigation-family .pocket-logo {
height: 20px;
width: 20px;
background-size: cover;
}
.ds-navigation.ds-navigation-new-topics .ds-navigation-family .firefox-logo {
background-image: url("chrome://activity-stream/content/data/content/assets/firefox.svg");
}
.ds-navigation.ds-navigation-new-topics .ds-navigation-family .pocket-logo {
background-image: url("chrome://global/skin/icons/pocket.svg");
fill: #EF4056;
}
.ds-navigation.ds-navigation-new-topics .ds-navigation-family .ds-navigation-family-message {
font-weight: 400;
display: block;
}
@media (min-width: 610px) {
.ds-navigation.ds-navigation-new-topics .ds-navigation-family .ds-navigation-family-message {
display: inline;
}
}
@media (min-width: 610px) {
.ds-navigation.ds-navigation-new-topics .ds-navigation-family {
margin-top: 43px;
}
}
.ds-navigation.ds-navigation-new-topics ul {
display: grid;
grid-gap: 0 24px;
grid-auto-flow: column;
grid-template: repeat(8, 1fr)/repeat(1, 1fr);
}
.ds-navigation.ds-navigation-new-topics ul li {
border-top: 1px solid var(--newtab-border-color);
border-bottom: 1px solid var(--newtab-border-color);
margin-bottom: -1px;
line-height: 24px;
font-size: 13px;
font-weight: 500;
}
.ds-navigation.ds-navigation-new-topics ul li::after {
content: "";
padding: 0;
}
.ds-navigation.ds-navigation-new-topics ul li:nth-last-child(2), .ds-navigation.ds-navigation-new-topics ul li:nth-last-child(3) {
display: none;
}
@media (min-width: 610px) {
.ds-navigation.ds-navigation-new-topics ul {
grid-template: repeat(3, 1fr)/repeat(2, 1fr);
}
}
@media (min-width: 866px) {
.ds-navigation.ds-navigation-new-topics ul {
grid-template: repeat(2, 1fr)/repeat(3, 1fr);
}
}
@media (min-width: 1122px) {
.ds-navigation.ds-navigation-new-topics ul {
grid-template: repeat(2, 1fr)/repeat(4, 1fr);
}
.ds-navigation.ds-navigation-new-topics ul li:nth-last-child(2), .ds-navigation.ds-navigation-new-topics ul li:nth-last-child(3) {
display: block;
}
}
.ds-section-title {
text-align: center;
@ -4058,6 +4144,16 @@ main.has-snippet {
margin: auto;
}
.ds-privacy-link {
text-align: center;
font-size: 13px;
font-weight: 500;
line-height: 24px;
}
.ds-privacy-link a:hover {
text-decoration: underline;
}
.ASRouterButton {
font-weight: 600;
font-size: 14px;

View file

@ -2135,7 +2135,7 @@ main.has-snippet {
fill: #12BC00;
}
.compact-cards .card-outer .card-context .card-context-icon.icon-pocket {
fill: #D70022;
fill: #EF4056;
}
.compact-cards .card-outer .card-context .card-context-label {
display: none;
@ -2574,7 +2574,7 @@ main.has-snippet {
}
.collapsible-section.ds-layout .section-top-bar .learn-more-link a {
color: var(--newtab-primary-action-background);
font-weight: normal;
font-weight: 500;
}
.collapsible-section.ds-layout .section-top-bar .learn-more-link a:is(:focus, :hover) {
text-decoration: underline;
@ -2758,7 +2758,7 @@ main.has-snippet {
.ds-layout .ds-card-grid-load-more-button {
display: block;
margin: 33px auto;
margin: 32px auto 0;
font-size: 13px;
line-height: 16px;
border-radius: 4px;
@ -3290,6 +3290,92 @@ main.has-snippet {
.ds-navigation .ds-navigation-privacy:hover {
text-decoration: underline;
}
.ds-navigation.ds-navigation-new-topics {
display: block;
padding-top: 32px;
}
.ds-navigation.ds-navigation-new-topics .ds-navigation-header {
font-size: 14px;
line-height: 20px;
font-weight: 700;
display: inline-block;
margin-bottom: 8px;
}
.ds-navigation.ds-navigation-new-topics .ds-navigation-family {
text-align: center;
font-size: 14px;
line-height: 20px;
margin: 16px auto 28px;
}
.ds-navigation.ds-navigation-new-topics .ds-navigation-family span {
margin: 0 6px;
}
.ds-navigation.ds-navigation-new-topics .ds-navigation-family .firefox-logo,
.ds-navigation.ds-navigation-new-topics .ds-navigation-family .pocket-logo {
height: 20px;
width: 20px;
background-size: cover;
}
.ds-navigation.ds-navigation-new-topics .ds-navigation-family .firefox-logo {
background-image: url("chrome://activity-stream/content/data/content/assets/firefox.svg");
}
.ds-navigation.ds-navigation-new-topics .ds-navigation-family .pocket-logo {
background-image: url("chrome://global/skin/icons/pocket.svg");
fill: #EF4056;
}
.ds-navigation.ds-navigation-new-topics .ds-navigation-family .ds-navigation-family-message {
font-weight: 400;
display: block;
}
@media (min-width: 610px) {
.ds-navigation.ds-navigation-new-topics .ds-navigation-family .ds-navigation-family-message {
display: inline;
}
}
@media (min-width: 610px) {
.ds-navigation.ds-navigation-new-topics .ds-navigation-family {
margin-top: 43px;
}
}
.ds-navigation.ds-navigation-new-topics ul {
display: grid;
grid-gap: 0 24px;
grid-auto-flow: column;
grid-template: repeat(8, 1fr)/repeat(1, 1fr);
}
.ds-navigation.ds-navigation-new-topics ul li {
border-top: 1px solid var(--newtab-border-color);
border-bottom: 1px solid var(--newtab-border-color);
margin-bottom: -1px;
line-height: 24px;
font-size: 13px;
font-weight: 500;
}
.ds-navigation.ds-navigation-new-topics ul li::after {
content: "";
padding: 0;
}
.ds-navigation.ds-navigation-new-topics ul li:nth-last-child(2), .ds-navigation.ds-navigation-new-topics ul li:nth-last-child(3) {
display: none;
}
@media (min-width: 610px) {
.ds-navigation.ds-navigation-new-topics ul {
grid-template: repeat(3, 1fr)/repeat(2, 1fr);
}
}
@media (min-width: 866px) {
.ds-navigation.ds-navigation-new-topics ul {
grid-template: repeat(2, 1fr)/repeat(3, 1fr);
}
}
@media (min-width: 1122px) {
.ds-navigation.ds-navigation-new-topics ul {
grid-template: repeat(2, 1fr)/repeat(4, 1fr);
}
.ds-navigation.ds-navigation-new-topics ul li:nth-last-child(2), .ds-navigation.ds-navigation-new-topics ul li:nth-last-child(3) {
display: block;
}
}
.ds-section-title {
text-align: center;
@ -4054,6 +4140,16 @@ main.has-snippet {
margin: auto;
}
.ds-privacy-link {
text-align: center;
font-size: 13px;
font-weight: 500;
line-height: 24px;
}
.ds-privacy-link a:hover {
text-decoration: underline;
}
.ASRouterButton {
font-weight: 600;
font-size: 14px;

View file

@ -97,15 +97,15 @@ __webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "renderCache", function() { return renderCache; });
/* harmony import */ var common_Actions_jsm__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1);
/* harmony import */ var content_src_components_Base_Base__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2);
/* harmony import */ var content_src_lib_detect_user_session_start__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(64);
/* harmony import */ var content_src_lib_init_store__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(65);
/* harmony import */ var content_src_lib_detect_user_session_start__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(65);
/* harmony import */ var content_src_lib_init_store__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(66);
/* harmony import */ var react_redux__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(7);
/* harmony import */ var react_redux__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(react_redux__WEBPACK_IMPORTED_MODULE_4__);
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(8);
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_5__);
/* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(14);
/* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(react_dom__WEBPACK_IMPORTED_MODULE_6__);
/* harmony import */ var common_Reducers_jsm__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(71);
/* harmony import */ var common_Reducers_jsm__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(72);
/* 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/. */
@ -520,10 +520,10 @@ __webpack_require__.r(__webpack_exports__);
/* harmony import */ var react_redux__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(react_redux__WEBPACK_IMPORTED_MODULE_4__);
/* harmony import */ var content_src_components_DiscoveryStreamBase_DiscoveryStreamBase__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(16);
/* harmony import */ var content_src_components_ErrorBoundary_ErrorBoundary__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(35);
/* harmony import */ var content_src_components_CustomizeMenu_CustomizeMenu__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(70);
/* harmony import */ var content_src_components_CustomizeMenu_CustomizeMenu__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(71);
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(8);
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_8___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_8__);
/* harmony import */ var content_src_components_Search_Search__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(63);
/* harmony import */ var content_src_components_Search_Search__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(64);
/* harmony import */ var content_src_components_Sections_Sections__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(45);
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
@ -2441,15 +2441,15 @@ __webpack_require__.r(__webpack_exports__);
/* harmony import */ var common_ActorConstants_jsm__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6);
/* harmony import */ var common_Actions_jsm__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(1);
/* harmony import */ var _asrouter_utils__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(5);
/* harmony import */ var _rich_text_strings__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(69);
/* harmony import */ var _rich_text_strings__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(70);
/* harmony import */ var _components_ImpressionsWrapper_ImpressionsWrapper__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(11);
/* harmony import */ var fluent_react__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(67);
/* harmony import */ var fluent_react__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(68);
/* harmony import */ var content_src_lib_constants__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(13);
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(8);
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_7___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_7__);
/* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(14);
/* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_8___default = /*#__PURE__*/__webpack_require__.n(react_dom__WEBPACK_IMPORTED_MODULE_8__);
/* harmony import */ var _templates_template_manifest__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(68);
/* harmony import */ var _templates_template_manifest__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(69);
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
/* This Source Code Form is subject to the terms of the Mozilla Public
@ -3102,11 +3102,12 @@ __webpack_require__.r(__webpack_exports__);
/* harmony import */ var content_src_components_DiscoveryStreamComponents_HorizontalRule_HorizontalRule__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(58);
/* harmony import */ var content_src_components_DiscoveryStreamComponents_List_List__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(43);
/* harmony import */ var content_src_components_DiscoveryStreamComponents_Navigation_Navigation__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(59);
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(8);
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_13___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_13__);
/* harmony import */ var content_src_components_DiscoveryStreamComponents_SectionTitle_SectionTitle__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(60);
/* harmony import */ var content_src_lib_selectLayoutRender__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(61);
/* harmony import */ var content_src_components_DiscoveryStreamComponents_TopSites_TopSites__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(62);
/* harmony import */ var content_src_components_DiscoveryStreamComponents_PrivacyLink_PrivacyLink__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(60);
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(8);
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_14___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_14__);
/* harmony import */ var content_src_components_DiscoveryStreamComponents_SectionTitle_SectionTitle__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(61);
/* harmony import */ var content_src_lib_selectLayoutRender__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(62);
/* harmony import */ var content_src_components_DiscoveryStreamComponents_TopSites_TopSites__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(63);
/* 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/. */
@ -3127,6 +3128,7 @@ __webpack_require__.r(__webpack_exports__);
const ALLOWED_CSS_URL_PREFIXES = ["chrome://", "resource://", "https://img-getpocket.cdn.mozilla.net/"];
const DUMMY_CSS_SELECTOR = "DUMMY#CSS.SELECTOR";
/**
@ -3145,7 +3147,7 @@ function isAllowedCSS(property, value) {
const urls = value.match(/url\("[^"]+"\)/g);
return !urls || urls.every(url => ALLOWED_CSS_URL_PREFIXES.some(prefix => url.slice(5).startsWith(prefix)));
}
class _DiscoveryStreamBase extends react__WEBPACK_IMPORTED_MODULE_13___default.a.PureComponent {
class _DiscoveryStreamBase extends react__WEBPACK_IMPORTED_MODULE_14___default.a.PureComponent {
constructor(props) {
super(props);
this.onStyleMount = this.onStyleMount.bind(this);
@ -3203,7 +3205,7 @@ class _DiscoveryStreamBase extends react__WEBPACK_IMPORTED_MODULE_13___default.a
switch (component.type) {
case "Highlights":
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_13___default.a.createElement(content_src_components_DiscoveryStreamComponents_Highlights_Highlights__WEBPACK_IMPORTED_MODULE_9__["Highlights"], null);
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_14___default.a.createElement(content_src_components_DiscoveryStreamComponents_Highlights_Highlights__WEBPACK_IMPORTED_MODULE_9__["Highlights"], null);
case "TopSites":
let promoAlignment;
@ -3212,28 +3214,28 @@ class _DiscoveryStreamBase extends react__WEBPACK_IMPORTED_MODULE_13___default.a
promoAlignment = component.spocs.positions[0].index === 0 ? "left" : "right";
}
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_13___default.a.createElement(content_src_components_DiscoveryStreamComponents_TopSites_TopSites__WEBPACK_IMPORTED_MODULE_16__["TopSites"], {
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_14___default.a.createElement(content_src_components_DiscoveryStreamComponents_TopSites_TopSites__WEBPACK_IMPORTED_MODULE_17__["TopSites"], {
header: component.header,
data: component.data,
promoAlignment: promoAlignment
});
case "TextPromo":
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_13___default.a.createElement(content_src_components_DiscoveryStreamComponents_DSTextPromo_DSTextPromo__WEBPACK_IMPORTED_MODULE_7__["DSTextPromo"], {
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_14___default.a.createElement(content_src_components_DiscoveryStreamComponents_DSTextPromo_DSTextPromo__WEBPACK_IMPORTED_MODULE_7__["DSTextPromo"], {
dispatch: this.props.dispatch,
type: component.type,
data: component.data
});
case "Signup":
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_13___default.a.createElement(content_src_components_DiscoveryStreamComponents_DSSignup_DSSignup__WEBPACK_IMPORTED_MODULE_6__["DSSignup"], {
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_14___default.a.createElement(content_src_components_DiscoveryStreamComponents_DSSignup_DSSignup__WEBPACK_IMPORTED_MODULE_6__["DSSignup"], {
dispatch: this.props.dispatch,
type: component.type,
data: component.data
});
case "Message":
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_13___default.a.createElement(content_src_components_DiscoveryStreamComponents_DSMessage_DSMessage__WEBPACK_IMPORTED_MODULE_4__["DSMessage"], {
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_14___default.a.createElement(content_src_components_DiscoveryStreamComponents_DSMessage_DSMessage__WEBPACK_IMPORTED_MODULE_4__["DSMessage"], {
title: component.header && component.header.title,
subtitle: component.header && component.header.subtitle,
link_text: component.header && component.header.link_text,
@ -3242,19 +3244,21 @@ class _DiscoveryStreamBase extends react__WEBPACK_IMPORTED_MODULE_13___default.a
});
case "SectionTitle":
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_13___default.a.createElement(content_src_components_DiscoveryStreamComponents_SectionTitle_SectionTitle__WEBPACK_IMPORTED_MODULE_14__["SectionTitle"], {
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_14___default.a.createElement(content_src_components_DiscoveryStreamComponents_SectionTitle_SectionTitle__WEBPACK_IMPORTED_MODULE_15__["SectionTitle"], {
header: component.header
});
case "Navigation":
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_13___default.a.createElement(content_src_components_DiscoveryStreamComponents_Navigation_Navigation__WEBPACK_IMPORTED_MODULE_12__["Navigation"], {
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_14___default.a.createElement(content_src_components_DiscoveryStreamComponents_Navigation_Navigation__WEBPACK_IMPORTED_MODULE_12__["Navigation"], {
dispatch: this.props.dispatch,
links: component.properties.links,
extraLinks: component.properties.extraLinks,
alignment: component.properties.alignment,
display_variant: component.properties.display_variant,
explore_topics: component.properties.explore_topics,
header: component.header,
locale: this.props.App.locale,
newFooterSection: component.newFooterSection,
privacyNoticeURL: component.properties.privacyNoticeURL
});
@ -3262,7 +3266,7 @@ class _DiscoveryStreamBase extends react__WEBPACK_IMPORTED_MODULE_13___default.a
const {
DiscoveryStream
} = this.props;
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_13___default.a.createElement(content_src_components_DiscoveryStreamComponents_CollectionCardGrid_CollectionCardGrid__WEBPACK_IMPORTED_MODULE_1__["CollectionCardGrid"], {
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_14___default.a.createElement(content_src_components_DiscoveryStreamComponents_CollectionCardGrid_CollectionCardGrid__WEBPACK_IMPORTED_MODULE_1__["CollectionCardGrid"], {
data: component.data,
feed: component.feed,
spocs: DiscoveryStream.spocs,
@ -3277,7 +3281,7 @@ class _DiscoveryStreamBase extends react__WEBPACK_IMPORTED_MODULE_13___default.a
});
case "CardGrid":
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_13___default.a.createElement(content_src_components_DiscoveryStreamComponents_CardGrid_CardGrid__WEBPACK_IMPORTED_MODULE_0__["CardGrid"], {
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_14___default.a.createElement(content_src_components_DiscoveryStreamComponents_CardGrid_CardGrid__WEBPACK_IMPORTED_MODULE_0__["CardGrid"], {
enable_video_playheads: !!component.properties.enable_video_playheads,
title: component.header && component.header.title,
display_variant: component.properties.display_variant,
@ -3296,7 +3300,7 @@ class _DiscoveryStreamBase extends react__WEBPACK_IMPORTED_MODULE_13___default.a
});
case "Hero":
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_13___default.a.createElement(content_src_components_DiscoveryStreamComponents_Hero_Hero__WEBPACK_IMPORTED_MODULE_8__["Hero"], {
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_14___default.a.createElement(content_src_components_DiscoveryStreamComponents_Hero_Hero__WEBPACK_IMPORTED_MODULE_8__["Hero"], {
subComponentType: embedWidth >= 9 ? `cards` : `list`,
feed: component.feed,
title: component.header && component.header.title,
@ -3308,10 +3312,10 @@ class _DiscoveryStreamBase extends react__WEBPACK_IMPORTED_MODULE_13___default.a
});
case "HorizontalRule":
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_13___default.a.createElement(content_src_components_DiscoveryStreamComponents_HorizontalRule_HorizontalRule__WEBPACK_IMPORTED_MODULE_10__["HorizontalRule"], null);
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_14___default.a.createElement(content_src_components_DiscoveryStreamComponents_HorizontalRule_HorizontalRule__WEBPACK_IMPORTED_MODULE_10__["HorizontalRule"], null);
case "List":
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_13___default.a.createElement(content_src_components_DiscoveryStreamComponents_List_List__WEBPACK_IMPORTED_MODULE_11__["List"], {
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_14___default.a.createElement(content_src_components_DiscoveryStreamComponents_List_List__WEBPACK_IMPORTED_MODULE_11__["List"], {
data: component.data,
feed: component.feed,
fullWidth: component.properties.full_width,
@ -3323,8 +3327,13 @@ class _DiscoveryStreamBase extends react__WEBPACK_IMPORTED_MODULE_13___default.a
header: component.header
});
case "PrivacyLink":
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_14___default.a.createElement(content_src_components_DiscoveryStreamComponents_PrivacyLink_PrivacyLink__WEBPACK_IMPORTED_MODULE_13__["PrivacyLink"], {
properties: component.properties
});
default:
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_13___default.a.createElement("div", null, component.type);
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_14___default.a.createElement("div", null, component.type);
}
}
@ -3332,7 +3341,7 @@ class _DiscoveryStreamBase extends react__WEBPACK_IMPORTED_MODULE_13___default.a
// Use json string as both the key and styles to render so React knows when
// to unmount and mount a new instance for new styles.
const json = JSON.stringify(styles);
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_13___default.a.createElement("style", {
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_14___default.a.createElement("style", {
key: json,
"data-styles": json,
ref: this.onStyleMount
@ -3343,7 +3352,7 @@ class _DiscoveryStreamBase extends react__WEBPACK_IMPORTED_MODULE_13___default.a
// Select layout render data by adding spocs and position to recommendations
const {
layoutRender
} = Object(content_src_lib_selectLayoutRender__WEBPACK_IMPORTED_MODULE_15__["selectLayoutRender"])({
} = Object(content_src_lib_selectLayoutRender__WEBPACK_IMPORTED_MODULE_16__["selectLayoutRender"])({
state: this.props.DiscoveryStream,
prefs: this.props.Prefs.values,
locale: this.props.locale
@ -3392,9 +3401,10 @@ class _DiscoveryStreamBase extends react__WEBPACK_IMPORTED_MODULE_13___default.a
link_url: topStories.learnMore.link.href,
title: topStories.title
}
}; // Render a DS-style TopSites then the rest if any in a collapsible section
};
const privacyLinkComponent = extractComponent("PrivacyLink"); // Render a DS-style TopSites then the rest if any in a collapsible section
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_13___default.a.createElement(react__WEBPACK_IMPORTED_MODULE_13___default.a.Fragment, null, this.props.DiscoveryStream.isPrivacyInfoModalVisible && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_13___default.a.createElement(content_src_components_DiscoveryStreamComponents_DSPrivacyModal_DSPrivacyModal__WEBPACK_IMPORTED_MODULE_5__["DSPrivacyModal"], {
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_14___default.a.createElement(react__WEBPACK_IMPORTED_MODULE_14___default.a.Fragment, null, this.props.DiscoveryStream.isPrivacyInfoModalVisible && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_14___default.a.createElement(content_src_components_DiscoveryStreamComponents_DSPrivacyModal_DSPrivacyModal__WEBPACK_IMPORTED_MODULE_5__["DSPrivacyModal"], {
dispatch: this.props.dispatch
}), topSites && this.renderLayout([{
width: 12,
@ -3402,7 +3412,7 @@ class _DiscoveryStreamBase extends react__WEBPACK_IMPORTED_MODULE_13___default.a
}]), sponsoredCollection && this.renderLayout([{
width: 12,
components: [sponsoredCollection]
}]), !!layoutRender.length && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_13___default.a.createElement(content_src_components_CollapsibleSection_CollapsibleSection__WEBPACK_IMPORTED_MODULE_2__["CollapsibleSection"], {
}]), !!layoutRender.length && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_14___default.a.createElement(content_src_components_CollapsibleSection_CollapsibleSection__WEBPACK_IMPORTED_MODULE_2__["CollapsibleSection"], {
className: "ds-layout",
collapsed: topStories.pref.collapsed,
dispatch: this.props.dispatch,
@ -3423,17 +3433,20 @@ class _DiscoveryStreamBase extends react__WEBPACK_IMPORTED_MODULE_13___default.a
components: [{
type: "Highlights"
}]
}]), privacyLinkComponent && this.renderLayout([{
width: 12,
components: [privacyLinkComponent]
}]));
}
renderLayout(layoutRender) {
const styles = [];
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_13___default.a.createElement("div", {
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_14___default.a.createElement("div", {
className: "discovery-stream ds-layout"
}, layoutRender.map((row, rowIndex) => /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_13___default.a.createElement("div", {
}, layoutRender.map((row, rowIndex) => /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_14___default.a.createElement("div", {
key: `row-${rowIndex}`,
className: `ds-column ds-column-${row.width}`
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_13___default.a.createElement("div", {
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_14___default.a.createElement("div", {
className: "ds-column-grid"
}, row.components.map((component, componentIndex) => {
if (!component) {
@ -3441,7 +3454,7 @@ class _DiscoveryStreamBase extends react__WEBPACK_IMPORTED_MODULE_13___default.a
}
styles[rowIndex] = [...(styles[rowIndex] || []), component.styles];
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_13___default.a.createElement("div", {
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_14___default.a.createElement("div", {
key: `component-${componentIndex}`
}, this.renderComponent(component, row.width));
})))), this.renderStyles(styles));
@ -8190,8 +8203,8 @@ __webpack_require__.r(__webpack_exports__);
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(8);
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_6__);
/* harmony import */ var _SearchShortcutsForm__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(55);
/* harmony import */ var common_Reducers_jsm__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(71);
/* harmony import */ var _TopSiteForm__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(72);
/* harmony import */ var common_Reducers_jsm__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(72);
/* harmony import */ var _TopSiteForm__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(73);
/* harmony import */ var _TopSite__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(56);
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
@ -8631,7 +8644,7 @@ __webpack_require__.r(__webpack_exports__);
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(8);
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_4__);
/* harmony import */ var content_src_lib_screenshot_utils__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(47);
/* harmony import */ var common_Reducers_jsm__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(71);
/* harmony import */ var common_Reducers_jsm__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(72);
/* harmony import */ var content_src_components_ContextMenu_ContextMenuButton__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(24);
/* harmony import */ var _TopSiteImpressionWrapper__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(57);
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
@ -9615,15 +9628,33 @@ class Topic extends react__WEBPACK_IMPORTED_MODULE_1___default.a.PureComponent {
}
class Navigation extends react__WEBPACK_IMPORTED_MODULE_1___default.a.PureComponent {
render() {
const links = this.props.links || [];
let links = this.props.links || [];
const alignment = this.props.alignment || "centered";
const header = this.props.header || {};
const english = this.props.locale.startsWith("en-");
const privacyNotice = this.props.privacyNoticeURL || {};
const {
newFooterSection
} = this.props;
const className = `ds-navigation ds-navigation-${alignment} ${newFooterSection ? `ds-navigation-new-topics` : ``}`;
let {
title
} = header;
if (newFooterSection) {
title = {
id: "newtab-pocket-new-topics-title"
};
if (this.props.extraLinks) {
links = [...links.slice(0, links.length - 1), ...this.props.extraLinks, links[links.length - 1]];
}
}
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default.a.createElement("div", {
className: `ds-navigation ds-navigation-${alignment}`
}, header.title && english ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default.a.createElement(content_src_components_FluentOrText_FluentOrText__WEBPACK_IMPORTED_MODULE_3__["FluentOrText"], {
message: header.title
className: className
}, title && english ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default.a.createElement(content_src_components_FluentOrText_FluentOrText__WEBPACK_IMPORTED_MODULE_3__["FluentOrText"], {
message: title
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default.a.createElement("span", {
className: "ds-navigation-header"
})) : null, english ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default.a.createElement("ul", null, links && links.map(t => /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default.a.createElement("li", {
@ -9632,13 +9663,21 @@ class Navigation extends react__WEBPACK_IMPORTED_MODULE_1___default.a.PureCompon
url: t.url,
name: t.name,
dispatch: this.props.dispatch
})))) : null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default.a.createElement(_SafeAnchor_SafeAnchor__WEBPACK_IMPORTED_MODULE_2__["SafeAnchor"], {
onLinkClick: this.onLinkClick,
})))) : null, !newFooterSection ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default.a.createElement(_SafeAnchor_SafeAnchor__WEBPACK_IMPORTED_MODULE_2__["SafeAnchor"], {
className: "ds-navigation-privacy",
url: privacyNotice.url
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default.a.createElement(content_src_components_FluentOrText_FluentOrText__WEBPACK_IMPORTED_MODULE_3__["FluentOrText"], {
message: privacyNotice.title
})));
})) : null, newFooterSection ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default.a.createElement("div", {
className: "ds-navigation-family"
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default.a.createElement("span", {
className: "icon firefox-logo"
}), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default.a.createElement("span", null, "|"), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default.a.createElement("span", {
className: "icon pocket-logo"
}), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default.a.createElement("span", {
className: "ds-navigation-family-message",
"data-l10n-id": "newtab-pocket-pocket-firefox-family"
})) : null);
}
}
@ -9647,6 +9686,39 @@ class Navigation extends react__WEBPACK_IMPORTED_MODULE_1___default.a.PureCompon
/* 60 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PrivacyLink", function() { return PrivacyLink; });
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(8);
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var _SafeAnchor_SafeAnchor__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(26);
/* harmony import */ var content_src_components_FluentOrText_FluentOrText__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(30);
/* 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/. */
class PrivacyLink extends react__WEBPACK_IMPORTED_MODULE_0___default.a.PureComponent {
render() {
const {
properties
} = this.props;
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", {
className: "ds-privacy-link"
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_SafeAnchor_SafeAnchor__WEBPACK_IMPORTED_MODULE_1__["SafeAnchor"], {
url: properties.url
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(content_src_components_FluentOrText_FluentOrText__WEBPACK_IMPORTED_MODULE_2__["FluentOrText"], {
message: properties.title
})));
}
}
/***/ }),
/* 61 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SectionTitle", function() { return SectionTitle; });
@ -9676,7 +9748,7 @@ class SectionTitle extends react__WEBPACK_IMPORTED_MODULE_0___default.a.PureComp
}
/***/ }),
/* 61 */
/* 62 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
@ -9733,7 +9805,7 @@ const selectLayoutRender = ({
}
const positions = {};
const DS_COMPONENTS = ["Message", "TextPromo", "SectionTitle", "Signup", "Navigation", "CardGrid", "CollectionCardGrid", "Hero", "HorizontalRule", "List"];
const DS_COMPONENTS = ["Message", "TextPromo", "SectionTitle", "Signup", "Navigation", "CardGrid", "CollectionCardGrid", "Hero", "HorizontalRule", "List", "PrivacyLink"];
const filterArray = [];
if (!prefs["feeds.topsites"]) {
@ -9899,7 +9971,7 @@ const selectLayoutRender = ({
};
/***/ }),
/* 62 */
/* 63 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
@ -9909,7 +9981,7 @@ __webpack_require__.r(__webpack_exports__);
/* harmony import */ var react_redux__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7);
/* harmony import */ var react_redux__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react_redux__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var content_src_components_TopSites_TopSites__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(53);
/* harmony import */ var common_Reducers_jsm__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(71);
/* harmony import */ var common_Reducers_jsm__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(72);
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(8);
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_3__);
/* This Source Code Form is subject to the terms of the Mozilla Public
@ -10050,7 +10122,7 @@ const TopSites = Object(react_redux__WEBPACK_IMPORTED_MODULE_0__["connect"])(sta
}))(_TopSites);
/***/ }),
/* 63 */
/* 64 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
@ -10270,7 +10342,7 @@ const Search = Object(react_redux__WEBPACK_IMPORTED_MODULE_1__["connect"])(state
}))(_Search);
/***/ }),
/* 64 */
/* 65 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
@ -10352,7 +10424,7 @@ class DetectUserSessionStart {
/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(3)))
/***/ }),
/* 65 */
/* 66 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
@ -10365,7 +10437,7 @@ __webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "queueEarlyMessageMiddleware", function() { return queueEarlyMessageMiddleware; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "initStore", function() { return initStore; });
/* harmony import */ var common_Actions_jsm__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1);
/* harmony import */ var redux__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(66);
/* harmony import */ var redux__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(67);
/* harmony import */ var redux__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(redux__WEBPACK_IMPORTED_MODULE_1__);
/* 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,
@ -10531,13 +10603,13 @@ function initStore(reducers, initialState) {
/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(3)))
/***/ }),
/* 66 */
/* 67 */
/***/ (function(module, exports) {
module.exports = Redux;
/***/ }),
/* 67 */
/* 68 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
@ -11334,7 +11406,7 @@ localized_Localized.propTypes = {
/***/ }),
/* 68 */
/* 69 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
@ -11383,10 +11455,10 @@ const ConditionalWrapper = ({
/* harmony default export */ var ConditionalWrapper_ConditionalWrapper = (ConditionalWrapper);
// EXTERNAL MODULE: ./node_modules/fluent-react/src/index.js + 14 modules
var src = __webpack_require__(67);
var src = __webpack_require__(68);
// EXTERNAL MODULE: ./content-src/asrouter/rich-text-strings.js + 7 modules
var rich_text_strings = __webpack_require__(69);
var rich_text_strings = __webpack_require__(70);
// CONCATENATED MODULE: ./content-src/asrouter/template-utils.js
/* This Source Code Form is subject to the terms of the Mozilla Public
@ -12669,7 +12741,7 @@ const SnippetsTemplates = {
};
/***/ }),
/* 69 */
/* 70 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
@ -14089,7 +14161,7 @@ function generateBundles(content) {
}
/***/ }),
/* 70 */
/* 71 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
@ -14415,7 +14487,7 @@ const CustomizeMenu = Object(external_ReactRedux_["connect"])(state => ({
}))(CustomizeMenu_CustomizeMenu);
/***/ }),
/* 71 */
/* 72 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
@ -15379,7 +15451,7 @@ var reducers = {
};
/***/ }),
/* 72 */
/* 73 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";

View file

@ -0,0 +1,168 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<!-- Generator: Adobe Illustrator 23.0.4, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 1856 1847.5" style="enable-background:new 0 0 1856 1847.5;" xml:space="preserve">
<style type="text/css">
.st0{display:none;}
.st1{fill:url(#SVGID_1_);}
.st2{opacity:0.67;}
.st3{fill:url(#SVGID_2_);}
.st4{fill:url(#SVGID_3_);}
.st5{fill:url(#SVGID_4_);}
.st6{fill:url(#SVGID_5_);}
.st7{fill:url(#SVGID_6_);}
.st8{fill:url(#SVGID_7_);}
.st9{fill:url(#SVGID_8_);}
.st10{opacity:0.53;fill:url(#SVGID_9_);enable-background:new ;}
.st11{opacity:0.53;fill:url(#SVGID_10_);enable-background:new ;}
.st12{fill:url(#SVGID_11_);}
.st13{fill:url(#SVGID_12_);}
.st14{fill:url(#SVGID_13_);}
.st15{fill:url(#SVGID_14_);}
.st16{fill:none;}
</style>
<g id="LiveType" class="st0">
</g>
<g id="Outlined">
<g>
<g>
<radialGradient id="SVGID_1_" cx="321.9653" cy="2631.8848" r="1876.7874" fx="389.093" fy="2598.7063" gradientTransform="matrix(1 0 0 -1 1258.4413 3044.8896)" gradientUnits="userSpaceOnUse">
<stop offset="0" style="stop-color:#FFF44F"/>
<stop offset="0.2949" style="stop-color:#FF980E"/>
<stop offset="0.4315" style="stop-color:#FF5D36"/>
<stop offset="0.5302" style="stop-color:#FF3750"/>
<stop offset="0.7493" style="stop-color:#F5156C"/>
<stop offset="0.7648" style="stop-color:#F1136E"/>
<stop offset="0.8801" style="stop-color:#DA057A"/>
<stop offset="0.9528" style="stop-color:#D2007F"/>
</radialGradient>
<path class="st1" d="M1588.9,424.3c-149.5-196.4-382.5-318.8-627.6-323.6c-192-3.8-324.7,53.7-399.7,100 c100.4-58.1,245.7-91.1,373-89.4c327.3,4.2,678.8,226.5,731,627.3c59.9,460.1-261.3,844-713.1,845.2 C455.4,1585,153,1145.8,232,751.4c3.9-19.7,2-38.9,8.6-57.5c3.8-69.4,30-178.1,86.7-289.1c-57.2,29.5-130.1,123-166.1,209.6 c-51.9,124.8-70.2,274.1-53.7,416.1c1.2,10.7,2.4,21.3,3.8,31.9c66.6,390.6,406.6,688,816.2,688c457.3,0,828.1-370.7,828.1-828.1 C1755.5,735.4,1693.5,562.9,1588.9,424.3z M278.3,496.2L278.3,496.2L278.3,496.2z"/>
<g class="st2">
<radialGradient id="SVGID_2_" cx="-1019.8155" cy="2554.2456" r="1110.733" fx="-980.0875" fy="2534.6096" gradientTransform="matrix(1 0 0 -1 1258.4413 3044.8896)" gradientUnits="userSpaceOnUse">
<stop offset="0" style="stop-color:#B5007F"/>
<stop offset="1" style="stop-color:#F5156C;stop-opacity:0"/>
</radialGradient>
<path class="st3" d="M1588.9,424.3c-149.5-196.4-382.5-318.8-627.6-323.6c-192-3.8-324.7,53.7-399.7,100 c100.4-58.1,245.7-91.1,373-89.4c327.3,4.2,678.8,226.5,731,627.3c59.9,460.1-261.3,844-713.1,845.2 C455.4,1585,153,1145.8,232,751.4c3.9-19.7,2-38.9,8.6-57.5c3.8-69.4,30-178.1,86.7-289.1c-57.2,29.5-130.1,123-166.1,209.6 c-51.9,124.8-70.2,274.1-53.7,416.1c1.2,10.7,2.4,21.3,3.8,31.9c66.6,390.6,406.6,688,816.2,688 c457.3,0,828.1-370.7,828.1-828.1C1755.5,735.4,1693.5,562.9,1588.9,424.3z M278.3,496.2L278.3,496.2L278.3,496.2z"/>
</g>
<radialGradient id="SVGID_3_" cx="482.4009" cy="2738.6748" r="2203.8347" fx="561.2262" fy="2699.7146" gradientTransform="matrix(1 0 0 -1 1258.4413 3044.8896)" gradientUnits="userSpaceOnUse">
<stop offset="0" style="stop-color:#FFDD00;stop-opacity:0.6"/>
<stop offset="8.366719e-02" style="stop-color:#FFD801;stop-opacity:0.5244"/>
<stop offset="0.1822" style="stop-color:#FECA05;stop-opacity:0.4353"/>
<stop offset="0.2884" style="stop-color:#FEB20C;stop-opacity:0.3394"/>
<stop offset="0.3998" style="stop-color:#FD9115;stop-opacity:0.2388"/>
<stop offset="0.5154" style="stop-color:#FB6621;stop-opacity:0.1343"/>
<stop offset="0.6329" style="stop-color:#F9332F;stop-opacity:2.816400e-02"/>
<stop offset="0.664" style="stop-color:#F92433;stop-opacity:0"/>
</radialGradient>
<path class="st4" d="M1588.9,424.3c-149.5-196.4-382.5-318.8-627.6-323.6c-192-3.8-324.7,53.7-399.7,100 c100.4-58.1,245.7-91.1,373-89.4c327.3,4.2,678.8,226.5,731,627.3c59.9,460.1-261.3,844-713.1,845.2 C455.4,1585,153,1145.8,232,751.4c3.9-19.7,2-38.9,8.6-57.5c3.8-69.4,30-178.1,86.7-289.1c-57.2,29.5-130.1,123-166.1,209.6 c-51.9,124.8-70.2,274.1-53.7,416.1c1.2,10.7,2.4,21.3,3.8,31.9c66.6,390.6,406.6,688,816.2,688c457.3,0,828.1-370.7,828.1-828.1 C1755.5,735.4,1693.5,562.9,1588.9,424.3z M278.3,496.2L278.3,496.2L278.3,496.2z"/>
</g>
<g>
<radialGradient id="SVGID_4_" cx="975.7665" cy="1493.5381" r="2843.1211" gradientTransform="matrix(1 0 0 -1 0 2512)" gradientUnits="userSpaceOnUse">
<stop offset="0.1528" style="stop-color:#960E18"/>
<stop offset="0.2061" style="stop-color:#CC2335;stop-opacity:0.5541"/>
<stop offset="0.2495" style="stop-color:#F13148;stop-opacity:0.1914"/>
<stop offset="0.2724" style="stop-color:#FF3750;stop-opacity:0"/>
</radialGradient>
<path class="st5" d="M1588.9,424.3c-149.5-196.4-382.5-318.8-627.6-323.6c-192-3.8-324.7,53.7-399.7,100 c100.4-58.1,245.7-91.1,373-89.4c327.3,4.2,678.8,226.5,731,627.3c59.9,460.1-261.3,844-713.1,845.2 C455.4,1585,153,1145.8,232,751.4c3.9-19.7,2-38.9,8.6-57.5c3.8-69.4,30-178.1,86.7-289.1c-57.2,29.5-130.1,123-166.1,209.6 c-51.9,124.8-70.2,274.1-53.7,416.1c1.2,10.7,2.4,21.3,3.8,31.9c66.6,390.6,406.6,688,816.2,688c457.3,0,828.1-370.7,828.1-828.1 C1755.5,735.4,1693.5,562.9,1588.9,424.3z M278.3,496.2L278.3,496.2L278.3,496.2z"/>
<radialGradient id="SVGID_5_" cx="760.6194" cy="1529.2881" r="2843.1211" gradientTransform="matrix(1 0 0 -1 0 2512)" gradientUnits="userSpaceOnUse">
<stop offset="0.1129" style="stop-color:#960E18"/>
<stop offset="0.1893" style="stop-color:#CC2335;stop-opacity:0.5541"/>
<stop offset="0.2515" style="stop-color:#F13148;stop-opacity:0.1914"/>
<stop offset="0.2843" style="stop-color:#FF3750;stop-opacity:0"/>
</radialGradient>
<path class="st6" d="M1588.9,424.3c-149.5-196.4-382.5-318.8-627.6-323.6c-192-3.8-324.7,53.7-399.7,100 c100.4-58.1,245.7-91.1,373-89.4c327.3,4.2,678.8,226.5,731,627.3c59.9,460.1-261.3,844-713.1,845.2 C455.4,1585,153,1145.8,232,751.4c3.9-19.7,2-38.9,8.6-57.5c3.8-69.4,30-178.1,86.7-289.1c-57.2,29.5-130.1,123-166.1,209.6 c-51.9,124.8-70.2,274.1-53.7,416.1c1.2,10.7,2.4,21.3,3.8,31.9c66.6,390.6,406.6,688,816.2,688c457.3,0,828.1-370.7,828.1-828.1 C1755.5,735.4,1693.5,562.9,1588.9,424.3z M278.3,496.2L278.3,496.2L278.3,496.2z"/>
</g>
<linearGradient id="SVGID_6_" gradientUnits="userSpaceOnUse" x1="-209.3687" y1="2784.0808" x2="277.0962" y2="1941.499" gradientTransform="matrix(1 0 0 -1 1258.4413 3044.8896)">
<stop offset="0" style="stop-color:#FFBC04"/>
<stop offset="0.2597" style="stop-color:#FFA202;stop-opacity:0.4886"/>
<stop offset="0.5078" style="stop-color:#FF8E00;stop-opacity:0"/>
</linearGradient>
<path class="st7" d="M1665.6,738.5c6.6,50.8,8.6,100.8,6.2,149.5c27.4-4.1,54.9-7.7,82.4-10.9c-9.2-169.5-69.2-325.4-165.3-452.8 c-149.5-196.4-382.5-318.8-627.6-323.6c-192-3.8-324.7,53.7-399.7,100c100.4-58.1,245.7-91.1,373-89.4 C1261.9,115.4,1613.4,337.7,1665.6,738.5z"/>
<g>
<radialGradient id="SVGID_7_" cx="244.0767" cy="2202.7847" r="1837.1556" fx="309.7869" fy="2170.3069" gradientTransform="matrix(0.9589 0 0 -0.9589 1306.9894 2461.7681)" gradientUnits="userSpaceOnUse">
<stop offset="0" style="stop-color:#FF980E"/>
<stop offset="0.295" style="stop-color:#FF7139"/>
<stop offset="0.4846" style="stop-color:#FF5B51"/>
<stop offset="0.626" style="stop-color:#FF4F5E"/>
<stop offset="0.7365" style="stop-color:#FF4055"/>
<stop offset="0.8428" style="stop-color:#FF3750"/>
</radialGradient>
<path class="st8" d="M1685.7,715.6c-46.5-418.8-421-607.1-751.1-604.4c-127.2,1-272.5,31.3-373,89.4 c-46.9,28.9-71.3,53.4-73.6,55.8c2.7-2.2,10.6-8.7,23.8-17.8c0.4-0.3,0.9-0.6,1.3-0.9c0.4-0.3,0.8-0.5,1.2-0.8 c47.9-33,101.9-57,159-73.7c87.3-25.5,181.7-34.1,272.6-31.8c373.4,21.5,636.9,330.7,646.1,659.8 c7.6,272.4-215.9,489.6-473.5,502.2c-187.3,9.1-363.8-81.3-450.1-262.2c-19.2-40.3-33.3-81.2-40.6-130.6 C587,625.2,772.3,390.4,942.3,332.3c-91.7-79.9-321.4-74.5-492.4,51c-123.1,90.4-203,227.9-229.5,391.9 c-20.2,125.1-1.2,255.2,48.4,371.3c50.5,118.4,132.6,222.7,235.8,299.6c112.1,83.4,247.1,132,386.2,142.6 c20.5,1.6,41.1,2.3,61.7,2.3C1499.6,1591,1736.9,1176.7,1685.7,715.6z"/>
<radialGradient id="SVGID_8_" cx="244.0767" cy="2202.7847" r="1837.1556" fx="309.7869" fy="2170.3069" gradientTransform="matrix(0.9589 0 0 -0.9589 1306.9894 2461.7681)" gradientUnits="userSpaceOnUse">
<stop offset="8.407450e-02" style="stop-color:#FFDE08"/>
<stop offset="0.2081" style="stop-color:#FFD609;stop-opacity:0.832"/>
<stop offset="0.4033" style="stop-color:#FFBF0B;stop-opacity:0.5677"/>
<stop offset="0.6437" style="stop-color:#FF9B0F;stop-opacity:0.242"/>
<stop offset="0.8224" style="stop-color:#FF7B12;stop-opacity:0"/>
</radialGradient>
<path class="st9" d="M1685.7,715.6c-46.5-418.8-421-607.1-751.1-604.4c-127.2,1-272.5,31.3-373,89.4 c-46.9,28.9-71.3,53.4-73.6,55.8c2.7-2.2,10.6-8.7,23.8-17.8c0.4-0.3,0.9-0.6,1.3-0.9c0.4-0.3,0.8-0.5,1.2-0.8 c47.9-33,101.9-57,159-73.7c87.3-25.5,181.7-34.1,272.6-31.8c373.4,21.5,636.9,330.7,646.1,659.8 c7.6,272.4-215.9,489.6-473.5,502.2c-187.3,9.1-363.8-81.3-450.1-262.2c-19.2-40.3-33.3-81.2-40.6-130.6 C587,625.2,772.3,390.4,942.3,332.3c-91.7-79.9-321.4-74.5-492.4,51c-123.1,90.4-203,227.9-229.5,391.9 c-20.2,125.1-1.2,255.2,48.4,371.3c50.5,118.4,132.6,222.7,235.8,299.6c112.1,83.4,247.1,132,386.2,142.6 c20.5,1.6,41.1,2.3,61.7,2.3C1499.6,1591,1736.9,1176.7,1685.7,715.6z"/>
</g>
<g>
<radialGradient id="SVGID_9_" cx="538.6154" cy="664.721" r="863.9618" gradientTransform="matrix(0.2472 0.969 1.0112 -0.258 328.7156 547.2202)" gradientUnits="userSpaceOnUse">
<stop offset="0.3634" style="stop-color:#FF3750"/>
<stop offset="0.4111" style="stop-color:#FF444B;stop-opacity:0.7895"/>
<stop offset="0.5902" style="stop-color:#FF7139;stop-opacity:0"/>
</radialGradient>
<path class="st10" d="M1685.7,715.6c-46.5-418.8-421-607.1-751.1-604.4c-127.2,1-272.5,31.3-373,89.4 c-46.9,28.9-71.3,53.4-73.6,55.8c2.7-2.2,10.6-8.7,23.8-17.8c0.4-0.3,0.9-0.6,1.3-0.9c0.4-0.3,0.8-0.5,1.2-0.8 c47.9-33,101.9-57,159-73.7c87.3-25.5,181.7-34.1,272.6-31.8c373.4,21.5,636.9,330.7,646.1,659.8 c7.6,272.4-215.9,489.6-473.5,502.2c-187.3,9.1-363.8-81.3-450.1-262.2c-19.2-40.3-33.3-81.2-40.6-130.6 C587,625.2,772.3,390.4,942.3,332.3c-91.7-79.9-321.4-74.5-492.4,51c-123.1,90.4-203,227.9-229.5,391.9 c-20.2,125.1-1.2,255.2,48.4,371.3c50.5,118.4,132.6,222.7,235.8,299.6c112.1,83.4,247.1,132,386.2,142.6 c20.5,1.6,41.1,2.3,61.7,2.3C1499.6,1591,1736.9,1176.7,1685.7,715.6z"/>
<radialGradient id="SVGID_10_" cx="389.6962" cy="589.2068" r="862.9537" gradientTransform="matrix(0.2472 0.969 0.9698 -0.2474 318.7961 738.6102)" gradientUnits="userSpaceOnUse">
<stop offset="0.2159" style="stop-color:#FF3750;stop-opacity:0.8"/>
<stop offset="0.2702" style="stop-color:#FF444B;stop-opacity:0.6316"/>
<stop offset="0.4739" style="stop-color:#FF7139;stop-opacity:0"/>
</radialGradient>
<path class="st11" d="M1685.7,715.6c-46.5-418.8-421-607.1-751.1-604.4c-127.2,1-272.5,31.3-373,89.4 c-46.9,28.9-71.3,53.4-73.6,55.8c2.7-2.2,10.6-8.7,23.8-17.8c0.4-0.3,0.9-0.6,1.3-0.9c0.4-0.3,0.8-0.5,1.2-0.8 c47.9-33,101.9-57,159-73.7c87.3-25.5,181.7-34.1,272.6-31.8c373.4,21.5,636.9,330.7,646.1,659.8 c7.6,272.4-215.9,489.6-473.5,502.2c-187.3,9.1-363.8-81.3-450.1-262.2c-19.2-40.3-33.3-81.2-40.6-130.6 C587,625.2,772.3,390.4,942.3,332.3c-91.7-79.9-321.4-74.5-492.4,51c-123.1,90.4-203,227.9-229.5,391.9 c-20.2,125.1-1.2,255.2,48.4,371.3c50.5,118.4,132.6,222.7,235.8,299.6c112.1,83.4,247.1,132,386.2,142.6 c20.5,1.6,41.1,2.3,61.7,2.3C1499.6,1591,1736.9,1176.7,1685.7,715.6z"/>
</g>
<g>
<radialGradient id="SVGID_11_" cx="610.7241" cy="2410.3098" r="3105.1294" gradientTransform="matrix(0.9589 0 0 -0.9589 1306.9894 2461.7681)" gradientUnits="userSpaceOnUse">
<stop offset="5.356570e-02" style="stop-color:#FFF44F"/>
<stop offset="0.4573" style="stop-color:#FF980E"/>
<stop offset="0.5211" style="stop-color:#FF8424"/>
<stop offset="0.5871" style="stop-color:#FF7634"/>
<stop offset="0.6393" style="stop-color:#FF7139"/>
</radialGradient>
<path class="st12" d="M1118.5,1293.4c353.6-21.5,504.9-313.4,514.3-520.7c14.8-323.7-177.7-672.7-686.9-641.2 c-90.8-2.3-185.3,6.3-272.6,31.8c-76.5,23.3-129.6,53.8-159,73.7c-0.4,0.3-0.8,0.5-1.2,0.8c-0.5,0.3-0.9,0.6-1.3,0.9 c-7.9,5.5-15.7,11.3-23.2,17.4c14.2-9.7,189.8-113.1,433.8-81.2C1214.7,213.1,1482,440,1482,739.4 c0,230.4-178.4,406.2-387.4,393.7C784.2,1114.4,706,796.8,867.4,659.6c-43.5-9.4-125.4,9-182.3,93.9 c-51.1,76.3-48.2,194.1-16.7,277.6C754.7,1212.1,931.3,1304.8,1118.5,1293.4z"/>
</g>
<g>
<linearGradient id="SVGID_12_" gradientUnits="userSpaceOnUse" x1="1321.7657" y1="2265.9978" x2="477.6807" y2="803.9998" gradientTransform="matrix(1 0 0 -1 0 2512)">
<stop offset="0" style="stop-color:#FFF44F;stop-opacity:0.8"/>
<stop offset="0.75" style="stop-color:#FFF44F;stop-opacity:0"/>
</linearGradient>
<path class="st13" d="M1588.9,424.3c-22.2-29.1-46.4-56.4-72-82.1c-20.5-21.7-42.6-41.8-65.7-60.3c13.3,11.6,26.1,23.9,38.2,36.9 c44.8,48.3,80.2,105.4,100.9,168c43.2,130.5,40.4,293.9-42.1,422.2c-98.3,152.9-258.2,228.4-431.2,224.7c-7.5,0-15-0.1-22.6-0.6 C784.2,1114.4,706,796.8,867.5,659.6c-43.5-9.4-125.4,9-182.4,93.9c-51.1,76.3-48.2,194.1-16.7,277.6 c-19.2-40.2-33.3-81.2-40.6-130.6C587,625.2,772.3,390.4,942.3,332.3c-91.7-79.9-321.4-74.5-492.4,51 c-99.6,73.1-170.9,177.1-208.5,301.1c5.5-69.5,31.9-173.4,86-279.5c-57.2,29.5-130.1,123-166.1,209.6 c-51.9,124.8-70.2,274.1-53.7,416.1c1.2,10.7,2.4,21.3,3.8,31.9c66.6,390.6,406.6,688,816.2,688c457.3,0,828.1-370.7,828.1-828.1 C1755.5,735.4,1693.5,562.9,1588.9,424.3z"/>
</g>
<linearGradient id="SVGID_13_" gradientUnits="userSpaceOnUse" x1="-205.4111" y1="1906.6858" x2="-205.4111" y2="2933.979" gradientTransform="matrix(1 0 0 -1 1258.4413 3044.8896)">
<stop offset="0" style="stop-color:#3A8EE6"/>
<stop offset="0.2359" style="stop-color:#5C79F0"/>
<stop offset="0.6293" style="stop-color:#9059FF"/>
<stop offset="1" style="stop-color:#C139E6"/>
</linearGradient>
<path class="st14" d="M1590.4,486.7c-20.7-62.5-56.1-119.6-100.9-168c-52.8-56.9-118.5-100.2-188-133.9 c-59.2-28.7-121-51.3-184.8-65.4c-114.4-25.2-234.4-24.7-342.5-2C656.7,142.2,553.4,192.9,488,256.3c49-29.7,117.3-53.8,166-66.1 c226-57,474.8,4.7,644.5,167.1c34.1,32.6,64.7,69.1,89.5,109.4c101.2,164.2,91.6,370.5,12.7,492.2 c-58.6,90.4-184.1,175.2-301.3,174.3c179.7,9.4,347.2-66.2,448.9-224.3C1630.8,780.6,1633.6,617.2,1590.4,486.7z"/>
<linearGradient id="SVGID_14_" gradientUnits="userSpaceOnUse" x1="-583.4494" y1="2938.6887" x2="250.1202" y2="2105.1191" gradientTransform="matrix(1 0 0 -1 1258.4413 3044.8896)">
<stop offset="0.8054" style="stop-color:#9059FF;stop-opacity:0"/>
<stop offset="1" style="stop-color:#6E008B;stop-opacity:0.5"/>
</linearGradient>
<path class="st15" d="M1590.4,486.7c-20.7-62.5-56.1-119.6-100.9-168c-52.8-56.9-118.5-100.2-188-133.9 c-59.2-28.7-121-51.3-184.8-65.4c-114.4-25.2-234.4-24.7-342.5-2C656.7,142.2,553.4,192.9,488,256.3c49-29.7,117.3-53.8,166-66.1 c226-57,474.8,4.7,644.5,167.1c34.1,32.6,64.7,69.1,89.5,109.4c101.2,164.2,91.6,370.5,12.7,492.2 c-58.6,90.4-184.1,175.2-301.3,174.3c179.7,9.4,347.2-66.2,448.9-224.3C1630.8,780.6,1633.6,617.2,1590.4,486.7z"/>
</g>
<rect x="745.5" y="50.5" class="st16" width="50" height="50"/>
</g>
<g id="Layer_3">
</g>
<g id="Layer_4">
</g>
<g id="Layer_5">
</g>
</svg>

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 5.3 KiB

Before After
Before After

View file

@ -476,6 +476,9 @@ this.DiscoveryStreamFeed = class DiscoveryStreamFeed {
items = isBasicLayout ? 4 : 24;
}
const newFooterSection = this.store.getState().Prefs.values?.pocketConfig
?.newFooterSection;
// Set a hardcoded layout if one is needed.
// Changing values in this layout in memory object is unnecessary.
layoutResp = getHardcodedLayout({
@ -485,6 +488,7 @@ this.DiscoveryStreamFeed = class DiscoveryStreamFeed {
compactLayout,
loadMoreEnabled,
lastCardMessageEnabled,
newFooterSection,
});
}
@ -1860,7 +1864,9 @@ this.DiscoveryStreamFeed = class DiscoveryStreamFeed {
// `spocPositions` Changes the position of spoc cards.
// `sponsoredCollectionsEnabled` Tuns on and off the sponsored collection section.
// `compactLayout` Changes cards to smaller more compact cards.
// `loadMoreEnabled` Hide half the Pocket stories behind a load more button.
// `lastCardMessageEnabled` Shows a message card at the end of the feed.
// `newFooterSection` Changes the layout of the topics section.
getHardcodedLayout = ({
items = 21,
spocPositions = [2, 4, 11, 20],
@ -1868,6 +1874,7 @@ getHardcodedLayout = ({
compactLayout = false,
loadMoreEnabled = false,
lastCardMessageEnabled = false,
newFooterSection = false,
}) => ({
lastUpdate: Date.now(),
spocs: {
@ -1968,11 +1975,12 @@ getHardcodedLayout = ({
},
{
type: "Navigation",
newFooterSection,
properties: {
alignment: "left-align",
links: [
{
name: "Self Improvement",
name: "Self improvement",
url:
"https://getpocket.com/explore/self-improvement?utm_source=pocket-newtab",
},
@ -1997,10 +2005,22 @@ getHardcodedLayout = ({
"https://getpocket.com/explore/science?utm_source=pocket-newtab",
},
{
name: "More Recommendations ",
name: "More recommendations ",
url: "https://getpocket.com/explore?utm_source=pocket-newtab",
},
],
extraLinks: [
{
name: "Career",
url:
"https://getpocket.com/explore/career?utm_source=pocket-newtab",
},
{
name: "Technology",
url:
"https://getpocket.com/explore/technology?utm_source=pocket-newtab",
},
],
privacyNoticeURL: {
url:
"https://www.mozilla.org/privacy/firefox/#suggest-relevant-content",
@ -2018,6 +2038,20 @@ getHardcodedLayout = ({
".ds-navigation": "margin-top: -10px;",
},
},
...(newFooterSection
? [
{
type: "PrivacyLink",
properties: {
url:
"https://www.mozilla.org/privacy/firefox/#suggest-relevant-content",
title: {
id: "newtab-section-menu-privacy-notice",
},
},
},
]
: []),
],
},
],

View file

@ -73,6 +73,22 @@ describe("<Navigation>", () => {
assert.lengthOf(wrapper.find("ul").children(), 2);
});
it("should render 2 extra Topics", () => {
wrapper.setProps({
newFooterSection: true,
links: [
{ url: "https://foo.com", name: "foo" },
{ url: "https://bar.com", name: "bar" },
],
extraLinks: [
{ url: "https://foo.com", name: "foo" },
{ url: "https://bar.com", name: "bar" },
],
});
assert.lengthOf(wrapper.find("ul").children(), 4);
});
});
describe("<Topic>", () => {

View file

@ -0,0 +1,29 @@
import { PrivacyLink } from "content-src/components/DiscoveryStreamComponents/PrivacyLink/PrivacyLink";
import React from "react";
import { shallow } from "enzyme";
describe("<PrivacyLink>", () => {
let wrapper;
let sandbox;
beforeEach(() => {
sandbox = sinon.createSandbox();
wrapper = shallow(
<PrivacyLink
properties={{
url: "url",
title: "Privacy Link",
}}
/>
);
});
afterEach(() => {
sandbox.restore();
});
it("should render", () => {
assert.ok(wrapper.exists());
assert.ok(wrapper.find(".ds-privacy-link").exists());
});
});

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 5.3 KiB

Before After
Before After

View file

@ -229,10 +229,12 @@ newtab-discovery-empty-section-topstories-timed-out = Oops! We almost loaded thi
# This is shown at the bottom of the trending stories section and precedes a list of links to popular topics.
newtab-pocket-read-more = Popular Topics:
newtab-pocket-new-topics-title = Want even more stories? See these popular topics from { -pocket-brand-name }
newtab-pocket-more-recommendations = More Recommendations
newtab-pocket-learn-more = Learn more
newtab-pocket-cta-button = Get { -pocket-brand-name }
newtab-pocket-cta-text = Save the stories you love in { -pocket-brand-name }, and fuel your mind with fascinating reads.
newtab-pocket-pocket-firefox-family = { -pocket-brand-name } is part of the { -brand-product-name } family
# This is a button shown at the bottom of the Pocket section that loads more stories when clicked.
newtab-pocket-load-more-stories-button = Load more stories

View file

@ -814,6 +814,13 @@ void BrowsingContext::Detach(bool aFromIPC) {
MOZ_DIAGNOSTIC_ASSERT(mEverAttached);
MOZ_DIAGNOSTIC_ASSERT(!mIsDiscarded);
auto callListeners =
MakeScopeExit([listeners = std::move(mDiscardListeners), id = Id()] {
for (const auto& listener : listeners) {
listener(id);
}
});
nsCOMPtr<nsIRequestContextService> rcsvc =
net::RequestContextService::GetOrCreate();
if (rcsvc) {
@ -823,6 +830,7 @@ void BrowsingContext::Detach(bool aFromIPC) {
// This will only ever be null if the cycle-collector has unlinked us. Don't
// try to detach ourselves in that case.
if (NS_WARN_IF(!mGroup)) {
MOZ_ASSERT_UNREACHABLE();
return;
}
@ -833,6 +841,7 @@ void BrowsingContext::Detach(bool aFromIPC) {
}
if (XRE_IsParentProcess()) {
RefPtr<CanonicalBrowsingContext> self{Canonical()};
Group()->EachParent([&](ContentParent* aParent) {
// Only the embedder process is allowed to initiate a BrowsingContext
// detach, so if we've gotten here, the host process already knows we've
@ -841,30 +850,32 @@ void BrowsingContext::Detach(bool aFromIPC) {
// If the owner process is not the same as the embedder process, its
// BrowsingContext will be detached when its nsWebBrowser instance is
// destroyed.
if (!Canonical()->IsEmbeddedInProcess(aParent->ChildID()) &&
!Canonical()->IsOwnedByProcess(aParent->ChildID())) {
// Hold a strong reference to ourself, and keep our BrowsingContextGroup
// alive, until the responses comes back to ensure we don't die while
// messages relating to this context are in-flight.
//
// When the callback is called, the keepalive on our group will be
// destroyed, and the reference to the BrowsingContext will be dropped,
// which may cause it to be fully destroyed.
mGroup->AddKeepAlive();
auto callback = [self = RefPtr{this}](auto) {
self->mGroup->RemoveKeepAlive();
};
bool doDiscard = !Canonical()->IsEmbeddedInProcess(aParent->ChildID()) &&
!Canonical()->IsOwnedByProcess(aParent->ChildID());
aParent->SendDiscardBrowsingContext(this, callback, callback);
}
// Hold a strong reference to ourself, and keep our BrowsingContextGroup
// alive, until the responses comes back to ensure we don't die while
// messages relating to this context are in-flight.
//
// When the callback is called, the keepalive on our group will be
// destroyed, and the reference to the BrowsingContext will be dropped,
// which may cause it to be fully destroyed.
mGroup->AddKeepAlive();
self->AddPendingDiscard();
auto callback = [self](auto) {
self->mGroup->RemoveKeepAlive();
self->RemovePendingDiscard();
};
aParent->SendDiscardBrowsingContext(this, doDiscard, callback, callback);
});
} else if (!aFromIPC) {
} else {
// Hold a strong reference to ourself until the responses come back to
// ensure the BrowsingContext isn't cleaned up before the parent process
// acknowledges the discard request.
auto callback = [self = RefPtr{this}](auto) {};
ContentChild::GetSingleton()->SendDiscardBrowsingContext(this, callback,
callback);
ContentChild::GetSingleton()->SendDiscardBrowsingContext(
this, !aFromIPC, callback, callback);
}
mGroup->Unregister(this);
@ -907,6 +918,15 @@ void BrowsingContext::Detach(bool aFromIPC) {
}
}
void BrowsingContext::AddDiscardListener(
std::function<void(uint64_t)>&& aListener) {
if (mIsDiscarded) {
aListener(Id());
return;
}
mDiscardListeners.AppendElement(std::move(aListener));
}
void BrowsingContext::PrepareForProcessChange() {
MOZ_LOG(GetLog(), LogLevel::Debug,
("%s: Preparing 0x%08" PRIx64 " for a process change",

View file

@ -872,6 +872,8 @@ class BrowsingContext : public nsILoadContext, public nsWrapperCache {
void RequestForPageAwake();
void RevokeForPageAwake();
void AddDiscardListener(std::function<void(uint64_t)>&& aListener);
protected:
virtual ~BrowsingContext();
BrowsingContext(WindowContext* aParentWindow, BrowsingContextGroup* aGroup,
@ -1263,6 +1265,8 @@ class BrowsingContext : public nsILoadContext, public nsWrapperCache {
RefPtr<SessionStorageManager> mSessionStorageManager;
RefPtr<ChildSHistory> mChildSessionHistory;
nsTArray<std::function<void(uint64_t)>> mDiscardListeners;
// Counter and time span for rate limiting Location and History API calls.
// Used by CheckLocationChangeRateLimit. Do not apply cross-process.
uint32_t mLocationChangeRateLimitCount;

View file

@ -1152,6 +1152,31 @@ void CanonicalBrowsingContext::CanonicalAttach() {
}
}
void CanonicalBrowsingContext::AddPendingDiscard() {
MOZ_ASSERT(!mFullyDiscarded);
mPendingDiscards++;
}
void CanonicalBrowsingContext::RemovePendingDiscard() {
mPendingDiscards--;
if (!mPendingDiscards) {
mFullyDiscarded = true;
auto listeners = std::move(mFullyDiscardedListeners);
for (const auto& listener : listeners) {
listener(Id());
}
}
}
void CanonicalBrowsingContext::AddFinalDiscardListener(
std::function<void(uint64_t)>&& aListener) {
if (mFullyDiscarded) {
aListener(Id());
return;
}
mFullyDiscardedListeners.AppendElement(std::move(aListener));
}
void CanonicalBrowsingContext::AdjustPrivateBrowsingCount(
bool aPrivateBrowsing) {
if (IsDiscarded() || !EverAttached() || IsChrome()) {

View file

@ -348,6 +348,8 @@ class CanonicalBrowsingContext final : public BrowsingContext {
uint32_t aPresShellId);
void StopApzAutoscroll(nsViewID aScrollId, uint32_t aPresShellId);
void AddFinalDiscardListener(std::function<void(uint64_t)>&& aListener);
protected:
// Called when the browsing context is being discarded.
void CanonicalDiscard();
@ -453,6 +455,10 @@ class CanonicalBrowsingContext final : public BrowsingContext {
void CancelSessionStoreUpdate();
void AddPendingDiscard();
void RemovePendingDiscard();
// XXX(farre): Store a ContentParent pointer here rather than mProcessId?
// Indicates which process owns the docshell.
uint64_t mProcessId;
@ -517,6 +523,12 @@ class CanonicalBrowsingContext final : public BrowsingContext {
RefPtr<GenericNonExclusivePromise> mClonePromise;
JS::Heap<JS::Value> mPermanentKey;
uint32_t mPendingDiscards = 0;
bool mFullyDiscarded = false;
nsTArray<std::function<void(uint64_t)>> mFullyDiscardedListeners;
};
} // namespace dom

View file

@ -3703,10 +3703,14 @@ mozilla::ipc::IPCResult ContentChild::RecvCreateBrowsingContext(
}
mozilla::ipc::IPCResult ContentChild::RecvDiscardBrowsingContext(
const MaybeDiscarded<BrowsingContext>& aContext,
const MaybeDiscarded<BrowsingContext>& aContext, bool aDoDiscard,
DiscardBrowsingContextResolver&& aResolve) {
if (!aContext.IsNullOrDiscarded()) {
aContext.get()->Detach(/* aFromIPC */ true);
if (BrowsingContext* context = aContext.GetMaybeDiscarded()) {
if (aDoDiscard && !context->IsDiscarded()) {
context->Detach(/* aFromIPC */ true);
}
context->AddDiscardListener(aResolve);
return IPC_OK();
}
// Immediately resolve the promise, as we've received the message. This will

View file

@ -686,7 +686,7 @@ class ContentChild final : public PContentChild,
uint64_t aGroupId, BrowsingContext::IPCInitializer&& aInit);
mozilla::ipc::IPCResult RecvDiscardBrowsingContext(
const MaybeDiscarded<BrowsingContext>& aContext,
const MaybeDiscarded<BrowsingContext>& aContext, bool aDoDiscard,
DiscardBrowsingContextResolver&& aResolve);
mozilla::ipc::IPCResult RecvRegisterBrowsingContextGroup(

View file

@ -6663,15 +6663,19 @@ bool ContentParent::CheckBrowsingContextEmbedder(CanonicalBrowsingContext* aBC,
}
mozilla::ipc::IPCResult ContentParent::RecvDiscardBrowsingContext(
const MaybeDiscarded<BrowsingContext>& aContext,
const MaybeDiscarded<BrowsingContext>& aContext, bool aDoDiscard,
DiscardBrowsingContextResolver&& aResolve) {
if (!aContext.IsNullOrDiscarded()) {
RefPtr<CanonicalBrowsingContext> context = aContext.get_canonical();
if (!CheckBrowsingContextEmbedder(context, "discard")) {
return IPC_FAIL(this, "Illegal Discard attempt");
}
if (CanonicalBrowsingContext* context =
CanonicalBrowsingContext::Cast(aContext.GetMaybeDiscarded())) {
if (aDoDiscard && !context->IsDiscarded()) {
if (!CheckBrowsingContextEmbedder(context, "discard")) {
return IPC_FAIL(this, "Illegal Discard attempt");
}
context->Detach(/* aFromIPC */ true);
context->Detach(/* aFromIPC */ true);
}
context->AddFinalDiscardListener(aResolve);
return IPC_OK();
}
// Resolve the promise, as we've received and handled the message. This will

View file

@ -654,7 +654,7 @@ class ContentParent final
uint64_t aGroupId, BrowsingContext::IPCInitializer&& aInit);
mozilla::ipc::IPCResult RecvDiscardBrowsingContext(
const MaybeDiscarded<BrowsingContext>& aContext,
const MaybeDiscarded<BrowsingContext>& aContext, bool aDoDiscard,
DiscardBrowsingContextResolver&& aResolve);
mozilla::ipc::IPCResult RecvWindowClose(

View file

@ -1790,13 +1790,15 @@ both:
async CreateBrowsingContext(uint64_t aGroupId, BrowsingContextInitializer aInit);
/**
* Discards the passed-in BrowsingContext. If the BrowsingContext has
* already been discarded, this message does nothing.
* The response promise is fulfilled when the process has flagged the
* BrowsingContext as discarded.
* If aDoDiscard is true, discards the passed-in BrowsingContext. If the
* BrowsingContext has already been discarded, this message does nothing.
* If the receiver is the parent process, resolves when all content
* processes have flagged the BrowsingContext as discarded, and if the
* receiver is a child process, resolves when that child process has flagged
* the BrowsingContext as discarded.
*/
async DiscardBrowsingContext(MaybeDiscardedBrowsingContext aContext)
returns (bool unused);
async DiscardBrowsingContext(MaybeDiscardedBrowsingContext aContext, bool aDoDiscard)
returns (uint64_t unused);
async AdjustWindowFocus(MaybeDiscardedBrowsingContext aContext,
bool aIsVisible, uint64_t aActionId);

View file

@ -36,8 +36,7 @@ std::ostream& operator<<(std::ostream& aStream, const FrameMetrics& aMetrics) {
.get()
<< " cr=" << aMetrics.GetCumulativeResolution()
<< " z=" << aMetrics.GetZoom()
<< " t=" << aMetrics.GetTransformToAncestorScale()
<< " er=" << aMetrics.GetExtraResolution() << " )] [u=("
<< " t=" << aMetrics.GetTransformToAncestorScale() << " )] [u=("
<< (int)aMetrics.GetVisualScrollUpdateType() << " "
<< aMetrics.GetScrollGeneration()
<< ")] scrollId=" << aMetrics.GetScrollId();

View file

@ -96,7 +96,6 @@ struct FrameMetrics {
mBoundingCompositionSize(0, 0),
mPresShellId(-1),
mLayoutViewport(0, 0, 0, 0),
mExtraResolution(),
mTransformToAncestorScale(),
mPaintRequestTime(),
mVisualDestination(0, 0),
@ -127,7 +126,6 @@ struct FrameMetrics {
mBoundingCompositionSize == aOther.mBoundingCompositionSize &&
mPresShellId == aOther.mPresShellId &&
mLayoutViewport.IsEqualEdges(aOther.mLayoutViewport) &&
mExtraResolution == aOther.mExtraResolution &&
mTransformToAncestorScale == aOther.mTransformToAncestorScale &&
mPaintRequestTime == aOther.mPaintRequestTime &&
mVisualDestination == aOther.mVisualDestination &&
@ -401,14 +399,6 @@ struct FrameMetrics {
CalculateCompositedSizeInCssPixels());
}
void SetExtraResolution(const ScreenToLayerScale2D& aExtraResolution) {
mExtraResolution = aExtraResolution;
}
const ScreenToLayerScale2D& GetExtraResolution() const {
return mExtraResolution;
}
void SetTransformToAncestorScale(const Scale2D& aTransformToAncestorScale) {
mTransformToAncestorScale = aTransformToAncestorScale;
}
@ -645,10 +635,6 @@ struct FrameMetrics {
// invalid.
CSSRect mLayoutViewport;
// The extra resolution at which content in this scroll frame is drawn beyond
// that necessary to draw one Layer pixel per Screen pixel.
ScreenToLayerScale2D mExtraResolution;
// The scale on this scroll frame induced by enclosing CSS transforms.
Scale2D mTransformToAncestorScale;

View file

@ -1114,22 +1114,31 @@ bool NativeLayerCA::Representation::EnqueueSurface(IOSurfaceRef aSurfaceRef) {
CVReturn cvValue =
CVPixelBufferCreateWithIOSurface(kCFAllocatorDefault, aSurfaceRef, nullptr, &pixelBuffer);
if (cvValue != kCVReturnSuccess) {
MOZ_ASSERT(pixelBuffer == nullptr, "Failed call shouldn't allocate memory.");
return false;
}
CFTypeRefPtr<CVPixelBufferRef> pixelBufferDeallocator =
CFTypeRefPtr<CVPixelBufferRef>::WrapUnderCreateRule(pixelBuffer);
CMVideoFormatDescriptionRef formatDescription;
CMVideoFormatDescriptionRef formatDescription = nullptr;
OSStatus osValue = CMVideoFormatDescriptionCreateForImageBuffer(kCFAllocatorDefault, pixelBuffer,
&formatDescription);
if (osValue != noErr) {
MOZ_ASSERT(formatDescription == nullptr, "Failed call shouldn't allocate memory.");
return false;
}
CFTypeRefPtr<CMVideoFormatDescriptionRef> formatDescriptionDeallocator =
CFTypeRefPtr<CMVideoFormatDescriptionRef>::WrapUnderCreateRule(formatDescription);
CMSampleBufferRef sampleBuffer = nullptr;
osValue = CMSampleBufferCreateReadyWithImageBuffer(
kCFAllocatorDefault, pixelBuffer, formatDescription, &kCMTimingInfoInvalid, &sampleBuffer);
if (osValue != noErr) {
MOZ_ASSERT(sampleBuffer == nullptr, "Failed call shouldn't allocate memory.");
return false;
}
CFTypeRefPtr<CMSampleBufferRef> sampleBufferDeallocator =
CFTypeRefPtr<CMSampleBufferRef>::WrapUnderCreateRule(sampleBuffer);
// Since we don't have timing information for the sample, before we enqueue it, we
// attach an attribute that specifies that the sample should be played immediately.
@ -1138,8 +1147,8 @@ bool NativeLayerCA::Representation::EnqueueSurface(IOSurfaceRef aSurfaceRef) {
// No dictionary to alter.
return false;
}
CFMutableDictionaryRef sample0Dictionary = reinterpret_cast<CFMutableDictionaryRef>(
const_cast<void*>(CFArrayGetValueAtIndex(attachmentsArray, 0)));
CFMutableDictionaryRef sample0Dictionary =
(__bridge CFMutableDictionaryRef)CFArrayGetValueAtIndex(attachmentsArray, 0);
CFDictionarySetValue(sample0Dictionary, kCMSampleAttachmentKey_DisplayImmediately,
kCFBooleanTrue);

View file

@ -54,7 +54,6 @@ struct RepaintRequest {
mDisplayPortMargins(0, 0, 0, 0),
mPresShellId(-1),
mLayoutViewport(0, 0, 0, 0),
mExtraResolution(),
mTransformToAncestorScale(),
mPaintRequestTime(),
mScrollUpdateType(eNone),
@ -77,7 +76,6 @@ struct RepaintRequest {
mDisplayPortMargins(aDisplayportMargins),
mPresShellId(aOther.GetPresShellId()),
mLayoutViewport(aOther.GetLayoutViewport()),
mExtraResolution(aOther.GetExtraResolution()),
mTransformToAncestorScale(aOther.GetTransformToAncestorScale()),
mPaintRequestTime(aOther.GetPaintRequestTime()),
mScrollUpdateType(aScrollUpdateType),
@ -100,7 +98,6 @@ struct RepaintRequest {
mDisplayPortMargins == aOther.mDisplayPortMargins &&
mPresShellId == aOther.mPresShellId &&
mLayoutViewport.IsEqualEdges(aOther.mLayoutViewport) &&
mExtraResolution == aOther.mExtraResolution &&
mTransformToAncestorScale == aOther.mTransformToAncestorScale &&
mPaintRequestTime == aOther.mPaintRequestTime &&
mScrollUpdateType == aOther.mScrollUpdateType &&
@ -182,10 +179,6 @@ struct RepaintRequest {
const CSSRect& GetLayoutViewport() const { return mLayoutViewport; }
const ScreenToLayerScale2D& GetExtraResolution() const {
return mExtraResolution;
}
const Scale2D& GetTransformToAncestorScale() const {
return mTransformToAncestorScale;
}
@ -286,10 +279,6 @@ struct RepaintRequest {
// invalid.
CSSRect mLayoutViewport;
// The extra resolution at which content in this scroll frame is drawn beyond
// that necessary to draw one Layer pixel per Screen pixel.
ScreenToLayerScale2D mExtraResolution;
// The scale on this scroll frame induced by enclosing CSS transforms.
Scale2D mTransformToAncestorScale;

View file

@ -84,9 +84,9 @@ bool AboutToCheckerboard(const FrameMetrics& aPaintedMetrics,
CSSRect visible =
CSSRect(aCompositorMetrics.GetVisualScrollOffset(),
aCompositorMetrics.CalculateBoundedCompositedSizeInCssPixels());
visible.Inflate(LayerSize(StaticPrefs::apz_danger_zone_x(),
StaticPrefs::apz_danger_zone_y()) /
aCompositorMetrics.LayersPixelsPerCSSPixel());
visible.Inflate(ScreenSize(StaticPrefs::apz_danger_zone_x(),
StaticPrefs::apz_danger_zone_y()) /
aCompositorMetrics.DisplayportPixelsPerCSSPixel());
// Clamp both rects to the scrollable rect, because having either of those
// exceed the scrollable rect doesn't make sense, and could lead to false

View file

@ -207,7 +207,7 @@ typedef PlatformSpecificStateBase
* a state where we can't keep up with scrolling. The danger zone prefs specify
* how wide this margin is; in the above example a y-axis danger zone of 10
* pixels would make us drop to low-res at y=490...990.\n
* This value is in layer pixels.
* This value is in screen pixels.
*
* \li\b apz.disable_for_scroll_linked_effects
* Setting this pref to true will disable APZ scrolling on documents where
@ -4066,11 +4066,11 @@ static CSSSize CalculateDisplayPortSize(
static CSSSize ExpandDisplayPortToDangerZone(
const CSSSize& aDisplayPortSize, const FrameMetrics& aFrameMetrics) {
CSSSize dangerZone(0.0f, 0.0f);
if (aFrameMetrics.LayersPixelsPerCSSPixel().xScale != 0 &&
aFrameMetrics.LayersPixelsPerCSSPixel().yScale != 0) {
dangerZone = LayerSize(StaticPrefs::apz_danger_zone_x(),
StaticPrefs::apz_danger_zone_y()) /
aFrameMetrics.LayersPixelsPerCSSPixel();
if (aFrameMetrics.DisplayportPixelsPerCSSPixel().xScale != 0 &&
aFrameMetrics.DisplayportPixelsPerCSSPixel().yScale != 0) {
dangerZone = ScreenSize(StaticPrefs::apz_danger_zone_x(),
StaticPrefs::apz_danger_zone_y()) /
aFrameMetrics.DisplayportPixelsPerCSSPixel();
}
const CSSSize compositionSize =
aFrameMetrics.CalculateBoundedCompositedSizeInCssPixels();

View file

@ -227,7 +227,6 @@ struct ParamTraits<mozilla::layers::FrameMetrics>
WriteParam(aMsg, aParam.mBoundingCompositionSize);
WriteParam(aMsg, aParam.mPresShellId);
WriteParam(aMsg, aParam.mLayoutViewport);
WriteParam(aMsg, aParam.mExtraResolution);
WriteParam(aMsg, aParam.mTransformToAncestorScale);
WriteParam(aMsg, aParam.mPaintRequestTime);
WriteParam(aMsg, aParam.mVisualDestination);
@ -258,7 +257,6 @@ struct ParamTraits<mozilla::layers::FrameMetrics>
ReadParam(aMsg, aIter, &aResult->mBoundingCompositionSize) &&
ReadParam(aMsg, aIter, &aResult->mPresShellId) &&
ReadParam(aMsg, aIter, &aResult->mLayoutViewport) &&
ReadParam(aMsg, aIter, &aResult->mExtraResolution) &&
ReadParam(aMsg, aIter, &aResult->mTransformToAncestorScale) &&
ReadParam(aMsg, aIter, &aResult->mPaintRequestTime) &&
ReadParam(aMsg, aIter, &aResult->mVisualDestination) &&
@ -294,7 +292,6 @@ struct ParamTraits<mozilla::layers::RepaintRequest>
WriteParam(aMsg, aParam.mDisplayPortMargins);
WriteParam(aMsg, aParam.mPresShellId);
WriteParam(aMsg, aParam.mLayoutViewport);
WriteParam(aMsg, aParam.mExtraResolution);
WriteParam(aMsg, aParam.mTransformToAncestorScale);
WriteParam(aMsg, aParam.mPaintRequestTime);
WriteParam(aMsg, aParam.mScrollUpdateType);
@ -316,7 +313,6 @@ struct ParamTraits<mozilla::layers::RepaintRequest>
ReadParam(aMsg, aIter, &aResult->mDisplayPortMargins) &&
ReadParam(aMsg, aIter, &aResult->mPresShellId) &&
ReadParam(aMsg, aIter, &aResult->mLayoutViewport) &&
ReadParam(aMsg, aIter, &aResult->mExtraResolution) &&
ReadParam(aMsg, aIter, &aResult->mTransformToAncestorScale) &&
ReadParam(aMsg, aIter, &aResult->mPaintRequestTime) &&
ReadParam(aMsg, aIter, &aResult->mScrollUpdateType) &&

View file

@ -879,9 +879,8 @@ void ScriptPreloader::FillCompileOptionsForCachedStencil(
options.setSourceIsLazy(true);
// ScriptPreloader's XDR buffer is alive during the entire browser lifetime.
// The decoded stencil's data and the bytecode can be borrowed from it.
// The decoded stencil can borrow from it.
options.borrowBuffer = true;
options.usePinnedBytecode = true;
}
already_AddRefed<JS::Stencil> ScriptPreloader::GetCachedStencil(

View file

@ -2808,11 +2808,6 @@ FrameMetrics nsLayoutUtils::CalculateBasicFrameMetrics(
Scale2D(nsLayoutUtils::GetTransformToAncestorScale(frame)));
metrics.SetCumulativeResolution(cumulativeResolution);
metrics.SetZoom(deviceScale * cumulativeResolution * layerToParentLayerScale);
LayoutDeviceToScreenScale2D resolutionToScreen(
presShell->GetCumulativeResolution() *
nsLayoutUtils::GetTransformToAncestorScale(frame));
metrics.SetExtraResolution(metrics.GetCumulativeResolution() /
resolutionToScreen);
// Only the size of the composition bounds is relevant to the
// displayport calculation, not its origin.
@ -8771,11 +8766,6 @@ ScrollMetadata nsLayoutUtils::ComputeScrollMetadata(
gfxSize transformToAncestorScale = nsLayoutUtils::GetTransformToAncestorScale(
aScrollFrame ? aScrollFrame : aForFrame);
LayoutDeviceToScreenScale2D resolutionToScreen(
presShell->GetCumulativeResolution() * transformToAncestorScale);
metrics.SetExtraResolution(metrics.GetCumulativeResolution() /
resolutionToScreen);
metrics.SetTransformToAncestorScale(Scale2D(transformToAncestorScale));
metrics.SetDevPixelsPerCSSPixel(presContext->CSSToDevPixelScale());

View file

@ -1,12 +1,11 @@
<!DOCTYPE html>
<html>
<style>
:-moz-any(input, textarea)::placeholder {
:is(input, textarea)::placeholder {
visibility: hidden;
padding: 20px;
float: right;
overflow: visible;
white-space: pre;
/*
* This list could be endless given that all non-whitelisted properties

View file

@ -218,11 +218,6 @@ textarea::-moz-text-control-editing-root {
opacity: 0.54;
}
textarea::placeholder,
textarea::-moz-text-control-preview {
white-space: pre-wrap !important;
}
input:read-write,
textarea:read-write {
-moz-user-modify: read-write !important;

View file

@ -41,8 +41,7 @@ for (let prop in gCSSProperties) {
#test::placeholder { ${prop}: ${info.other_values[0]}; ${prereqs} }
`;
// line-height does apply to ::placeholder, but only on <textarea>. We could
// switch the test to use a <textarea> but then we'd need the same special-case
// for white-space.
// switch the test to use a <textarea>.
if (info.applies_to_placeholder && prop != "line-height") {
isnot(get_computed_value(test, prop),
get_computed_value(control, prop),

View file

@ -93,7 +93,7 @@ class MOZ_STACK_CLASS ScopeExit {
public:
explicit ScopeExit(ExitFunction&& cleanup)
: mExitFunction(cleanup), mExecuteOnDestruction(true) {}
: mExitFunction(std::move(cleanup)), mExecuteOnDestruction(true) {}
ScopeExit(ScopeExit&& rhs)
: mExitFunction(std::move(rhs.mExitFunction)),

View file

@ -1146,7 +1146,7 @@
# Whether pressing Esc will exit fullscreen.
- name: browser.fullscreen.exit_on_escape
type: bool
value: false
value: true
mirror: always
#endif

View file

@ -579,6 +579,94 @@ Result GetEarliestSCTTimestamp(Input sctExtension,
return Success;
}
Result NSSCertDBTrustDomain::CheckCRLiteStash(
const nsTArray<uint8_t>& issuerSubjectPublicKeyInfoBytes,
const nsTArray<uint8_t>& serialNumberBytes) {
// This information is deterministic and has already been validated by our
// infrastructure (it comes from signed CRLs), so if the stash says a
// certificate is revoked, it is.
bool isRevokedByStash = false;
nsresult rv = mCertStorage->IsCertRevokedByStash(
issuerSubjectPublicKeyInfoBytes, serialNumberBytes, &isRevokedByStash);
if (NS_FAILED(rv)) {
MOZ_LOG(gCertVerifierLog, LogLevel::Debug,
("NSSCertDBTrustDomain::CheckCRLiteStash: IsCertRevokedByStash "
"failed"));
return Result::FATAL_ERROR_LIBRARY_FAILURE;
}
if (isRevokedByStash) {
MOZ_LOG(gCertVerifierLog, LogLevel::Debug,
("NSSCertDBTrustDomain::CheckCRLiteStash: IsCertRevokedByStash "
"returned true"));
return Result::ERROR_REVOKED_CERTIFICATE;
}
return Success;
}
Result NSSCertDBTrustDomain::CheckCRLite(
const nsTArray<uint8_t>& issuerBytes,
const nsTArray<uint8_t>& issuerSubjectPublicKeyInfoBytes,
const nsTArray<uint8_t>& serialNumberBytes, uint64_t earliestSCTTimestamp,
bool& filterCoversCertificate) {
filterCoversCertificate = false;
uint64_t filterTimestamp;
int16_t crliteRevocationState;
nsresult rv = mCertStorage->GetCRLiteRevocationState(
issuerBytes, issuerSubjectPublicKeyInfoBytes, serialNumberBytes,
&filterTimestamp, &crliteRevocationState);
if (NS_FAILED(rv)) {
MOZ_LOG(gCertVerifierLog, LogLevel::Debug,
("NSSCertDBTrustDomain::CheckCRLite: CRLite call failed"));
return Result::FATAL_ERROR_LIBRARY_FAILURE;
}
MOZ_LOG(gCertVerifierLog, LogLevel::Debug,
("NSSCertDBTrustDomain::CheckCRLite: CRLite check returned "
"state=%hd filter timestamp=%llu",
crliteRevocationState,
// The cast is to silence warnings on compilers where uint64_t is
// an unsigned long as opposed to an unsigned long long.
static_cast<unsigned long long>(filterTimestamp)));
Time filterTimestampTime(TimeFromEpochInSeconds(filterTimestamp));
// We can only use this result if the earliest embedded signed
// certificate timestamp from the certificate is older than what cert
// storage returned for its CRLite timestamp. Otherwise, the CRLite
// filter cascade may have been created before this certificate existed,
// and if it would create a false positive, it hasn't been accounted for.
// SCT timestamps are milliseconds since the epoch.
Time earliestCertificateTimestamp(
TimeFromEpochInSeconds(earliestSCTTimestamp / 1000));
Result result =
earliestCertificateTimestamp.AddSeconds(mCRLiteCTMergeDelaySeconds);
if (result != Success) {
// This shouldn't happen - the merge delay is at most a year in seconds,
// and the SCT timestamp is supposed to be in the past.
MOZ_LOG(gCertVerifierLog, LogLevel::Debug,
("NSSCertDBTrustDomain::CheckRevocation: integer overflow "
"calculating sct timestamp + merge delay (%llu + %llu)",
static_cast<unsigned long long>(earliestSCTTimestamp / 1000),
static_cast<unsigned long long>(mCRLiteCTMergeDelaySeconds)));
// While we do have control over the possible values of the CT merge
// delay parameter, we don't have control over the SCT timestamp.
// Thus, if we've reached this point, the CA has probably made a
// mistake and we should treat this certificate as revoked.
return Result::ERROR_REVOKED_CERTIFICATE;
}
if (filterTimestamp != 0 &&
earliestCertificateTimestamp <= filterTimestampTime &&
crliteRevocationState != nsICertStorage::STATE_NOT_ENROLLED) {
filterCoversCertificate = true;
}
if (filterCoversCertificate &&
crliteRevocationState == nsICertStorage::STATE_ENFORCE) {
MOZ_LOG(gCertVerifierLog, LogLevel::Debug,
("NSSCertDBTrustDomain::CheckRevocation: certificate revoked via "
"CRLite"));
return Result::ERROR_REVOKED_CERTIFICATE;
}
return Success;
}
Result NSSCertDBTrustDomain::CheckRevocation(
EndEntityOrCA endEntityOrCA, const CertID& certID, Time time,
Duration validityDuration,
@ -604,13 +692,12 @@ Result NSSCertDBTrustDomain::CheckRevocation(
}
}
bool crliteFilterCoversCertificate = false;
Result crliteResult = Success;
if (endEntityOrCA == EndEntityOrCA::MustBeEndEntity &&
mCRLiteMode != CRLiteMode::Disabled && earliestSCTTimestamp.isSome()) {
MOZ_LOG(gCertVerifierLog, LogLevel::Debug,
("NSSCertDBTrustDomain::CheckRevocation: checking CRLite"));
nsTArray<uint8_t> issuerBytes;
issuerBytes.AppendElements(certID.issuer.UnsafeGetData(),
certID.issuer.GetLength());
nsTArray<uint8_t> issuerSubjectPublicKeyInfoBytes;
issuerSubjectPublicKeyInfoBytes.AppendElements(
certID.issuerSubjectPublicKeyInfo.UnsafeGetData(),
@ -618,113 +705,29 @@ Result NSSCertDBTrustDomain::CheckRevocation(
nsTArray<uint8_t> serialNumberBytes;
serialNumberBytes.AppendElements(certID.serialNumber.UnsafeGetData(),
certID.serialNumber.GetLength());
uint64_t filterTimestamp;
int16_t crliteRevocationState;
nsresult rv = mCertStorage->GetCRLiteRevocationState(
issuerBytes, issuerSubjectPublicKeyInfoBytes, serialNumberBytes,
&filterTimestamp, &crliteRevocationState);
bool certificateFoundValidInCRLiteFilter = false;
if (NS_FAILED(rv)) {
MOZ_LOG(gCertVerifierLog, LogLevel::Debug,
("NSSCertDBTrustDomain::CheckRevocation: CRLite call failed"));
if (mCRLiteMode == CRLiteMode::Enforce) {
return Result::FATAL_ERROR_LIBRARY_FAILURE;
}
} else {
MOZ_LOG(gCertVerifierLog, LogLevel::Debug,
("NSSCertDBTrustDomain::CheckRevocation: CRLite check returned "
"state=%hd filter timestamp=%llu",
crliteRevocationState,
// The cast is to silence warnings on compilers where uint64_t is
// an unsigned long as opposed to an unsigned long long.
static_cast<unsigned long long>(filterTimestamp)));
Time filterTimestampTime(TimeFromEpochInSeconds(filterTimestamp));
// We can only use this result if the earliest embedded signed
// certificate timestamp from the certificate is older than what cert
// storage returned for its CRLite timestamp. Otherwise, the CRLite
// filter cascade may have been created before this certificate existed,
// and if it would create a false positive, it hasn't been accounted for.
// SCT timestamps are milliseconds since the epoch.
Time earliestCertificateTimestamp(
TimeFromEpochInSeconds(*earliestSCTTimestamp / 1000));
Result result =
earliestCertificateTimestamp.AddSeconds(mCRLiteCTMergeDelaySeconds);
if (result != Success) {
// This shouldn't happen - the merge delay is at most a year in seconds,
// and the SCT timestamp is supposed to be in the past.
MOZ_LOG(gCertVerifierLog, LogLevel::Debug,
("NSSCertDBTrustDomain::CheckRevocation: integer overflow "
"calculating sct timestamp + merge delay (%llu + %llu)",
static_cast<unsigned long long>(*earliestSCTTimestamp / 1000),
static_cast<unsigned long long>(mCRLiteCTMergeDelaySeconds)));
if (mCRLiteMode == CRLiteMode::Enforce) {
// While we do have control over the possible values of the CT merge
// delay parameter, we don't have control over the SCT timestamp.
// Thus, if we've reached this point, the CA has probably made a
// mistake and we should treat this certificate as revoked.
return Result::ERROR_REVOKED_CERTIFICATE;
}
// If Time::AddSeconds fails, the original value is unchanged. Since in
// this case `earliestCertificateTimestamp` must represent a value far
// in the future, any CRLite result will be discarded.
}
if (earliestCertificateTimestamp <= filterTimestampTime &&
crliteRevocationState == nsICertStorage::STATE_ENFORCE) {
if (mCRLiteMode == CRLiteMode::Enforce) {
MOZ_LOG(
gCertVerifierLog, LogLevel::Debug,
("NSSCertDBTrustDomain::CheckRevocation: certificate revoked via "
"CRLite"));
return Result::ERROR_REVOKED_CERTIFICATE;
}
MOZ_LOG(
gCertVerifierLog, LogLevel::Debug,
("NSSCertDBTrustDomain::CheckRevocation: certificate revoked via "
"CRLite (not enforced - telemetry only)"));
}
if (crliteRevocationState == nsICertStorage::STATE_NOT_ENROLLED) {
MOZ_LOG(gCertVerifierLog, LogLevel::Debug,
("NSSCertDBTrustDomain::CheckRevocation: issuer not enrolled"));
}
if (filterTimestamp == 0) {
MOZ_LOG(gCertVerifierLog, LogLevel::Debug,
("NSSCertDBTrustDomain::CheckRevocation: no timestamp"));
} else if (earliestCertificateTimestamp > filterTimestampTime) {
MOZ_LOG(gCertVerifierLog, LogLevel::Debug,
("NSSCertDBTrustDomain::CheckRevocation: cert too new"));
} else if (crliteRevocationState == nsICertStorage::STATE_UNSET) {
certificateFoundValidInCRLiteFilter = true;
}
// The CRLite stash is essentially a subset of a collection of CRLs, so if
// it says a certificate is revoked, it is.
Result rv =
CheckCRLiteStash(issuerSubjectPublicKeyInfoBytes, serialNumberBytes);
if (rv != Success) {
return rv;
}
// Also check stashed CRLite revocations. This information is
// deterministic and has already been validated by our infrastructure (it
// comes from signed CRLs), so if the stash says a certificate is revoked,
// it is.
bool isRevokedByStash = false;
rv = mCertStorage->IsCertRevokedByStash(
issuerSubjectPublicKeyInfoBytes, serialNumberBytes, &isRevokedByStash);
if (NS_FAILED(rv)) {
MOZ_LOG(gCertVerifierLog, LogLevel::Debug,
("NSSCertDBTrustDomain::CheckRevocation: IsCertRevokedByStash "
"failed"));
if (mCRLiteMode == CRLiteMode::Enforce) {
return Result::FATAL_ERROR_LIBRARY_FAILURE;
}
} else if (isRevokedByStash) {
MOZ_LOG(gCertVerifierLog, LogLevel::Debug,
("NSSCertDBTrustDomain::CheckRevocation: IsCertRevokedByStash "
"returned true"));
if (mCRLiteMode == CRLiteMode::Enforce) {
return Result::ERROR_REVOKED_CERTIFICATE;
}
} else if (certificateFoundValidInCRLiteFilter &&
mCRLiteMode == CRLiteMode::Enforce) {
MOZ_LOG(gCertVerifierLog, LogLevel::Debug,
("NSSCertDBTrustDomain::CheckRevocation: certificate covered by "
"CRLite, found to be valid -> skipping OCSP processing"));
return Success;
nsTArray<uint8_t> issuerBytes;
issuerBytes.AppendElements(certID.issuer.UnsafeGetData(),
certID.issuer.GetLength());
crliteResult = CheckCRLite(issuerBytes, issuerSubjectPublicKeyInfoBytes,
serialNumberBytes, *earliestSCTTimestamp,
crliteFilterCoversCertificate);
// If CheckCRLite returned an error other than "revoked certificate",
// propagate that error.
if (crliteResult != Success &&
crliteResult != Result::ERROR_REVOKED_CERTIFICATE) {
return crliteResult;
}
// Always return the result of CheckCRLite if CRLite is being enforced and
// the certificate is covered by the CRLite filter.
if (mCRLiteMode == CRLiteMode::Enforce && crliteFilterCoversCertificate) {
return crliteResult;
}
}
@ -921,7 +924,7 @@ Result NSSCertDBTrustDomain::CheckRevocation(
// responses from a failing server.
return SynchronousCheckRevocationWithServer(
certID, aiaLocation, time, maxOCSPLifetimeInDays, cachedResponseResult,
stapledOCSPResponseResult);
stapledOCSPResponseResult, crliteFilterCoversCertificate, crliteResult);
}
return HandleOCSPFailure(cachedResponseResult, stapledOCSPResponseResult,
@ -931,7 +934,8 @@ Result NSSCertDBTrustDomain::CheckRevocation(
Result NSSCertDBTrustDomain::SynchronousCheckRevocationWithServer(
const CertID& certID, const nsCString& aiaLocation, Time time,
uint16_t maxOCSPLifetimeInDays, const Result cachedResponseResult,
const Result stapledOCSPResponseResult) {
const Result stapledOCSPResponseResult,
const bool crliteFilterCoversCertificate, const Result crliteResult) {
uint8_t ocspRequestBytes[OCSP_REQUEST_MAX_LENGTH];
size_t ocspRequestLength;
@ -962,6 +966,18 @@ Result NSSCertDBTrustDomain::SynchronousCheckRevocationWithServer(
return cacheRV;
}
if (crliteFilterCoversCertificate) {
if (crliteResult == Success) {
// CRLite says the certificate is OK, but OCSP fetching failed.
Telemetry::AccumulateCategorical(
Telemetry::LABELS_CRLITE_VS_OCSP_RESULT::CRLiteOkOCSPFail);
} else {
// CRLite says the certificate is revoked, but OCSP fetching failed.
Telemetry::AccumulateCategorical(
Telemetry::LABELS_CRLITE_VS_OCSP_RESULT::CRLiteRevOCSPFail);
}
}
return HandleOCSPFailure(cachedResponseResult, stapledOCSPResponseResult,
rv);
}
@ -973,6 +989,61 @@ Result NSSCertDBTrustDomain::SynchronousCheckRevocationWithServer(
rv = VerifyAndMaybeCacheEncodedOCSPResponse(certID, time,
maxOCSPLifetimeInDays, response,
ResponseIsFromNetwork, expired);
// If the CRLite filter covers the certificate, compare the CRLite result
// with the OCSP fetching result. OCSP may have succeeded, said the
// certificate is revoked, said the certificate doesn't exist, or it may have
// failed for a reason that results in a "soft fail" (i.e. there is no
// indication that the certificate is either definitely revoked or definitely
// not revoked, so for usability, revocation checking says the certificate is
// valid by default).
if (crliteFilterCoversCertificate) {
if (rv == Success) {
if (crliteResult == Success) {
// CRLite and OCSP fetching agree the certificate is OK.
Telemetry::AccumulateCategorical(
Telemetry::LABELS_CRLITE_VS_OCSP_RESULT::CRLiteOkOCSPOk);
} else {
// CRLite says the certificate is revoked, but OCSP says it is OK.
Telemetry::AccumulateCategorical(
Telemetry::LABELS_CRLITE_VS_OCSP_RESULT::CRLiteRevOCSPOk);
}
} else if (rv == Result::ERROR_REVOKED_CERTIFICATE) {
if (crliteResult == Success) {
// CRLite says the certificate is OK, but OCSP says it is revoked.
Telemetry::AccumulateCategorical(
Telemetry::LABELS_CRLITE_VS_OCSP_RESULT::CRLiteOkOCSPRev);
} else {
// CRLite and OCSP fetching agree the certificate is revoked.
Telemetry::AccumulateCategorical(
Telemetry::LABELS_CRLITE_VS_OCSP_RESULT::CRLiteRevOCSPRev);
}
} else if (rv == Result::ERROR_OCSP_UNKNOWN_CERT) {
if (crliteResult == Success) {
// CRLite says the certificate is OK, but OCSP says it doesn't exist.
Telemetry::AccumulateCategorical(
Telemetry::LABELS_CRLITE_VS_OCSP_RESULT::CRLiteOkOCSPUnk);
} else {
// CRLite says the certificate is revoked, but OCSP says it doesn't
// exist.
Telemetry::AccumulateCategorical(
Telemetry::LABELS_CRLITE_VS_OCSP_RESULT::CRLiteRevOCSPUnk);
}
} else {
if (crliteResult == Success) {
// CRLite says the certificate is OK, but OCSP encountered a soft-fail
// error.
Telemetry::AccumulateCategorical(
Telemetry::LABELS_CRLITE_VS_OCSP_RESULT::CRLiteOkOCSPSoft);
} else {
// CRLite says the certificate is revoked, but OCSP encountered a
// soft-fail error.
Telemetry::AccumulateCategorical(
Telemetry::LABELS_CRLITE_VS_OCSP_RESULT::CRLiteRevOCSPSoft);
}
}
}
if (rv == Success || mOCSPFetching != FetchOCSPForDVSoftFail) {
MOZ_LOG(gCertVerifierLog, LogLevel::Debug,
("NSSCertDBTrustDomain: returning after "

View file

@ -215,6 +215,15 @@ class NSSCertDBTrustDomain : public mozilla::pkix::TrustDomain {
bool GetIsErrorDueToDistrustedCAPolicy() const;
private:
Result CheckCRLiteStash(
const nsTArray<uint8_t>& issuerSubjectPublicKeyInfoBytes,
const nsTArray<uint8_t>& serialNumberBytes);
Result CheckCRLite(const nsTArray<uint8_t>& issuerBytes,
const nsTArray<uint8_t>& issuerSubjectPublicKeyInfoBytes,
const nsTArray<uint8_t>& serialNumberBytes,
uint64_t earliestSCTTimestamp,
bool& filterCoversCertificate);
enum EncodedResponseSource {
ResponseIsFromNetwork = 1,
ResponseWasStapled = 2
@ -228,8 +237,8 @@ class NSSCertDBTrustDomain : public mozilla::pkix::TrustDomain {
Result SynchronousCheckRevocationWithServer(
const mozilla::pkix::CertID& certID, const nsCString& aiaLocation,
mozilla::pkix::Time time, uint16_t maxOCSPLifetimeInDays,
const Result cachedResponseResult,
const Result stapledOCSPResponseResult);
const Result cachedResponseResult, const Result stapledOCSPResponseResult,
const bool crliteFilterCoversCertificate, const Result crliteResult);
Result HandleOCSPFailure(const Result cachedResponseResult,
const Result stapledOCSPResponseResult,
const Result error);

View file

@ -0,0 +1,8 @@
<!doctype html>
<title>CSS Test Reference</title>
<style>
textarea {
max-width: 100px;
}
</style>
<textarea placeholder="This is a really long string that needs to be truncated"></textarea>

View file

@ -0,0 +1,15 @@
<!doctype html>
<meta charset=utf-8>
<title>Textarea placeholder honors textarea's text-overflow</title>
<link rel=author href="mailto:emilio@crisal.io" title="Emilio Cobos Álvarez">
<link rel=author href="https://mozilla.com" title="Mozilla">
<link rel=mismatch href="placeholder-white-space-notref.html">
<link rel=help href="https://github.com/w3c/csswg-drafts/issues/6669">
<style>
textarea {
white-space: nowrap;
text-overflow: ellipsis;
max-width: 100px;
}
</style>
<textarea placeholder="This is a really long string that needs to be truncated"></textarea>

View file

@ -172,6 +172,12 @@ const FeatureManifest = {
description:
"The last card in the Pocket section is a message that they are currently at the end of the list of stories.",
},
newFooterSection: {
type: "boolean",
fallbackPref:
"browser.newtabpage.activity-stream.discoverystream.newFooterSection.enabled",
description: "Enable an updated Pocket section topics footer",
},
},
},
"password-autocomplete": {

View file

@ -1,5 +1,5 @@
This is the PDF.js project output, https://github.com/mozilla/pdf.js
Current extension version is: 2.11.283
Current extension version is: 2.11.298
Taken from upstream commit: 638115885
Taken from upstream commit: d370a281c

View file

@ -62,7 +62,12 @@ exports.DEFAULT_LINK_REL = DEFAULT_LINK_REL;
const SVG_NS = "http://www.w3.org/2000/svg";
const PixelsPerInch = {
CSS: 96.0,
PDF: 72.0
PDF: 72.0,
get PDF_TO_CSS_UNITS() {
return (0, _util.shadow)(this, "PDF_TO_CSS_UNITS", this.CSS / this.PDF);
}
};
exports.PixelsPerInch = PixelsPerInch;
@ -1907,7 +1912,7 @@ async function _fetchDocument(worker, source, pdfDataRangeTransport, docId) {
const workerId = await worker.messageHandler.sendWithPromise("GetDocRequest", {
docId,
apiVersion: '2.11.283',
apiVersion: '2.11.298',
source: {
data: source.data,
url: source.url,
@ -3203,6 +3208,7 @@ class WorkerTransport {
Promise.all(waitOn).then(() => {
this.commonObjs.clear();
this.fontLoader.clear();
this._getFieldObjectsPromise = null;
this._hasJSActionsPromise = null;
if (this._networkStream) {
@ -3607,7 +3613,7 @@ class WorkerTransport {
}
getFieldObjects() {
return this.messageHandler.sendWithPromise("GetFieldObjects", null);
return this._getFieldObjectsPromise ||= this.messageHandler.sendWithPromise("GetFieldObjects", null);
}
hasJSActions() {
@ -3736,13 +3742,15 @@ class WorkerTransport {
this.fontLoader.clear();
}
this._getFieldObjectsPromise = null;
this._hasJSActionsPromise = null;
}
get loadingParams() {
const params = this._params;
return (0, _util.shadow)(this, "loadingParams", {
disableAutoFetch: params.disableAutoFetch
disableAutoFetch: params.disableAutoFetch,
enableXfa: params.enableXfa
});
}
@ -3988,9 +3996,9 @@ class InternalRenderTask {
}
const version = '2.11.283';
const version = '2.11.298';
exports.version = version;
const build = '638115885';
const build = 'd370a281c';
exports.build = build;
/***/ }),
@ -5163,7 +5171,7 @@ function getImageSmoothingEnabled(transform, interpolate) {
scale[0] = Math.fround(scale[0]);
scale[1] = Math.fround(scale[1]);
const actualScale = Math.fround((globalThis.devicePixelRatio || 1) * _display_utils.PixelsPerInch.CSS / _display_utils.PixelsPerInch.PDF);
const actualScale = Math.fround((globalThis.devicePixelRatio || 1) * _display_utils.PixelsPerInch.PDF_TO_CSS_UNITS);
if (interpolate !== undefined) {
return interpolate;
@ -8605,6 +8613,7 @@ var _annotation_storage = __w_pdfjs_require__(9);
var _scripting_utils = __w_pdfjs_require__(19);
const DEFAULT_TAB_INDEX = 1000;
const GetElementsByNameSet = new WeakSet();
class AnnotationElementFactory {
static create(parameters) {
@ -8710,6 +8719,7 @@ class AnnotationElement {
this.annotationStorage = parameters.annotationStorage;
this.enableScripting = parameters.enableScripting;
this.hasJSActions = parameters.hasJSActions;
this._fieldObjects = parameters.fieldObjects;
this._mouseState = parameters.mouseState;
if (isRenderable) {
@ -8848,6 +8858,69 @@ class AnnotationElement {
(0, _util.unreachable)("Abstract method `AnnotationElement.render` called");
}
_getElementsByName(name, skipId = null) {
const fields = [];
if (this._fieldObjects) {
const fieldObj = this._fieldObjects[name];
if (fieldObj) {
for (const {
page,
id,
exportValues
} of fieldObj) {
if (page === -1) {
continue;
}
if (id === skipId) {
continue;
}
const exportValue = typeof exportValues === "string" ? exportValues : null;
const domElement = document.getElementById(id);
if (domElement && !GetElementsByNameSet.has(domElement)) {
(0, _util.warn)(`_getElementsByName - element not allowed: ${id}`);
continue;
}
fields.push({
id,
exportValue,
domElement
});
}
}
return fields;
}
for (const domElement of document.getElementsByName(name)) {
const {
id,
exportValue
} = domElement;
if (id === skipId) {
continue;
}
if (!GetElementsByNameSet.has(domElement)) {
continue;
}
fields.push({
id,
exportValue,
domElement
});
}
return fields;
}
static get platform() {
const platform = typeof navigator !== "undefined" ? navigator.platform : "";
return (0, _util.shadow)(this, "platform", {
@ -9136,13 +9209,14 @@ class TextWidgetAnnotationElement extends WidgetAnnotationElement {
setPropertyOnSiblings(base, key, value, keyInStorage) {
const storage = this.annotationStorage;
for (const element of document.getElementsByName(base.name)) {
if (element !== base) {
element[key] = value;
const data = Object.create(null);
data[keyInStorage] = value;
storage.setValue(element.getAttribute("id"), data);
for (const element of this._getElementsByName(base.name, base.id)) {
if (element.domElement) {
element.domElement[key] = value;
}
storage.setValue(element.id, {
[keyInStorage]: value
});
}
}
@ -9174,6 +9248,9 @@ class TextWidgetAnnotationElement extends WidgetAnnotationElement {
element.setAttribute("value", textContent);
}
GetElementsByNameSet.add(element);
element.disabled = this.data.readOnly;
element.name = this.data.fieldName;
element.tabIndex = DEFAULT_TAB_INDEX;
elementData.userValue = textContent;
element.setAttribute("id", id);
@ -9331,9 +9408,6 @@ class TextWidgetAnnotationElement extends WidgetAnnotationElement {
element.addEventListener("blur", blurListener);
}
element.disabled = this.data.readOnly;
element.name = this.data.fieldName;
if (this.data.maxLen !== null) {
element.maxLength = this.data.maxLen;
}
@ -9402,6 +9476,7 @@ class CheckboxWidgetAnnotationElement extends WidgetAnnotationElement {
this.container.className = "buttonWidgetAnnotation checkBox";
const element = document.createElement("input");
GetElementsByNameSet.add(element);
element.disabled = data.readOnly;
element.type = "checkbox";
element.name = data.fieldName;
@ -9413,17 +9488,22 @@ class CheckboxWidgetAnnotationElement extends WidgetAnnotationElement {
element.setAttribute("id", id);
element.setAttribute("exportValue", data.exportValue);
element.tabIndex = DEFAULT_TAB_INDEX;
element.addEventListener("change", function (event) {
const name = event.target.name;
const checked = event.target.checked;
element.addEventListener("change", event => {
const {
name,
checked
} = event.target;
for (const checkbox of document.getElementsByName(name)) {
if (checkbox !== event.target) {
checkbox.checked = checked && checkbox.getAttribute("exportValue") === data.exportValue;
storage.setValue(checkbox.parentNode.getAttribute("data-annotation-id"), {
value: false
});
for (const checkbox of this._getElementsByName(name, id)) {
const curChecked = checked && checkbox.exportValue === data.exportValue;
if (checkbox.domElement) {
checkbox.domElement.checked = curChecked;
}
storage.setValue(checkbox.id, {
value: curChecked
});
}
storage.setValue(id, {
@ -9479,6 +9559,7 @@ class RadioButtonWidgetAnnotationElement extends WidgetAnnotationElement {
}
const element = document.createElement("input");
GetElementsByNameSet.add(element);
element.disabled = data.readOnly;
element.type = "radio";
element.name = data.fieldName;
@ -9489,21 +9570,20 @@ class RadioButtonWidgetAnnotationElement extends WidgetAnnotationElement {
element.setAttribute("id", id);
element.tabIndex = DEFAULT_TAB_INDEX;
element.addEventListener("change", function (event) {
element.addEventListener("change", event => {
const {
target
} = event;
name,
checked
} = event.target;
for (const radio of document.getElementsByName(target.name)) {
if (radio !== target) {
storage.setValue(radio.getAttribute("id"), {
value: false
});
}
for (const radio of this._getElementsByName(name, id)) {
storage.setValue(radio.id, {
value: false
});
}
storage.setValue(id, {
value: target.checked
value: checked
});
});
@ -9511,18 +9591,21 @@ class RadioButtonWidgetAnnotationElement extends WidgetAnnotationElement {
const pdfButtonValue = data.buttonValue;
element.addEventListener("updatefromsandbox", jsEvent => {
const actions = {
value(event) {
value: event => {
const checked = pdfButtonValue === event.detail.value;
for (const radio of document.getElementsByName(event.target.name)) {
const radioId = radio.getAttribute("id");
radio.checked = radioId === id && checked;
storage.setValue(radioId, {
value: radio.checked
for (const radio of this._getElementsByName(event.target.name)) {
const curChecked = checked && radio.id === id;
if (radio.domElement) {
radio.domElement.checked = curChecked;
}
storage.setValue(radio.id, {
value: curChecked
});
}
}
};
this._dispatchEventFromSandbox(actions, jsEvent);
@ -9575,6 +9658,7 @@ class ChoiceWidgetAnnotationElement extends WidgetAnnotationElement {
const fontSizeStyle = `calc(${fontSize}px * var(--zoom-factor))`;
const selectElement = document.createElement("select");
GetElementsByNameSet.add(selectElement);
selectElement.disabled = this.data.readOnly;
selectElement.name = this.data.fieldName;
selectElement.setAttribute("id", id);
@ -10369,6 +10453,7 @@ class AnnotationLayer {
annotationStorage: parameters.annotationStorage || new _annotation_storage.AnnotationStorage(),
enableScripting: parameters.enableScripting,
hasJSActions: parameters.hasJSActions,
fieldObjects: parameters.fieldObjects,
mouseState: parameters.mouseState || {
isDown: false
}
@ -11782,8 +11867,8 @@ var _svg = __w_pdfjs_require__(21);
var _xfa_layer = __w_pdfjs_require__(22);
const pdfjsVersion = '2.11.283';
const pdfjsBuild = '638115885';
const pdfjsVersion = '2.11.298';
const pdfjsBuild = 'd370a281c';
;
})();

View file

@ -4932,8 +4932,8 @@ Object.defineProperty(exports, "initSandbox", ({
var _initialization = __w_pdfjs_require__(1);
const pdfjsVersion = '2.11.283';
const pdfjsBuild = '638115885';
const pdfjsVersion = '2.11.298';
const pdfjsBuild = 'd370a281c';
})();
/******/ return __webpack_exports__;

View file

@ -125,7 +125,7 @@ class WorkerMessageHandler {
const WorkerTasks = [];
const verbosity = (0, _util.getVerbosityLevel)();
const apiVersion = docParams.apiVersion;
const workerVersion = '2.11.283';
const workerVersion = '2.11.298';
if (apiVersion !== workerVersion) {
throw new Error(`The API version "${apiVersion}" does not match ` + `the Worker version "${workerVersion}".`);
@ -517,20 +517,20 @@ class WorkerMessageHandler {
}
const xfa = acroForm instanceof _primitives.Dict && acroForm.get("XFA") || null;
let xfaDatasets = null;
let hasDatasets = false;
let xfaDatasetsRef = null;
let hasXfaDatasetsEntry = false;
if (Array.isArray(xfa)) {
for (let i = 0, ii = xfa.length; i < ii; i += 2) {
if (xfa[i] === "datasets") {
xfaDatasets = xfa[i + 1];
xfaDatasetsRef = xfa[i + 1];
acroFormRef = null;
hasDatasets = true;
hasXfaDatasetsEntry = true;
}
}
if (xfaDatasets === null) {
xfaDatasets = xref.getNewRef();
if (xfaDatasetsRef === null) {
xfaDatasetsRef = xref.getNewRef();
}
} else if (xfa) {
acroFormRef = null;
@ -569,8 +569,9 @@ class WorkerMessageHandler {
xrefInfo: newXrefInfo,
newRefs,
xref,
datasetsRef: xfaDatasets,
hasDatasets,
hasXfa: !!xfa,
xfaDatasetsRef,
hasXfaDatasetsEntry,
acroFormRef,
acroForm,
xfaData
@ -43696,8 +43697,8 @@ function writeXFADataForAcroform(str, newRefs) {
function updateXFA({
xfaData,
datasetsRef,
hasDatasets,
xfaDatasetsRef,
hasXfaDatasetsEntry,
acroFormRef,
acroForm,
newRefs,
@ -43708,7 +43709,7 @@ function updateXFA({
return;
}
if (!hasDatasets) {
if (!hasXfaDatasetsEntry) {
if (!acroFormRef) {
(0, _util.warn)("XFA - Cannot save it");
return;
@ -43717,7 +43718,7 @@ function updateXFA({
const oldXfa = acroForm.get("XFA");
const newXfa = oldXfa.slice();
newXfa.splice(2, 0, "datasets");
newXfa.splice(3, 0, datasetsRef);
newXfa.splice(3, 0, xfaDatasetsRef);
acroForm.set("XFA", newXfa);
const encrypt = xref.encrypt;
let transform = null;
@ -43737,20 +43738,20 @@ function updateXFA({
}
if (xfaData === null) {
const datasets = xref.fetchIfRef(datasetsRef);
const datasets = xref.fetchIfRef(xfaDatasetsRef);
xfaData = writeXFADataForAcroform(datasets.getString(), newRefs);
}
const encrypt = xref.encrypt;
if (encrypt) {
const transform = encrypt.createCipherTransform(datasetsRef.num, datasetsRef.gen);
const transform = encrypt.createCipherTransform(xfaDatasetsRef.num, xfaDatasetsRef.gen);
xfaData = transform.encryptString(xfaData);
}
const data = `${datasetsRef.num} ${datasetsRef.gen} obj\n` + `<< /Type /EmbeddedFile /Length ${xfaData.length}>>\nstream\n` + xfaData + "\nendstream\nendobj\n";
const data = `${xfaDatasetsRef.num} ${xfaDatasetsRef.gen} obj\n` + `<< /Type /EmbeddedFile /Length ${xfaData.length}>>\nstream\n` + xfaData + "\nendstream\nendobj\n";
newRefs.push({
ref: datasetsRef,
ref: xfaDatasetsRef,
data
});
}
@ -43760,22 +43761,26 @@ function incrementalUpdate({
xrefInfo,
newRefs,
xref = null,
datasetsRef = null,
hasDatasets = false,
hasXfa = false,
xfaDatasetsRef = null,
hasXfaDatasetsEntry = false,
acroFormRef = null,
acroForm = null,
xfaData = null
}) {
updateXFA({
xfaData,
datasetsRef,
hasDatasets,
acroFormRef,
acroForm,
newRefs,
xref,
xrefInfo
});
if (hasXfa) {
updateXFA({
xfaData,
xfaDatasetsRef,
hasXfaDatasetsEntry,
acroFormRef,
acroForm,
newRefs,
xref,
xrefInfo
});
}
const newXref = new _primitives.Dict(null);
const refForXrefTable = xrefInfo.newRef;
let buffer, baseOffset;
@ -60758,8 +60763,8 @@ Object.defineProperty(exports, "WorkerMessageHandler", ({
var _worker = __w_pdfjs_require__(1);
const pdfjsVersion = '2.11.283';
const pdfjsBuild = '638115885';
const pdfjsVersion = '2.11.298';
const pdfjsBuild = 'd370a281c';
})();
/******/ return __webpack_exports__;

View file

@ -279,6 +279,10 @@ class AppOptions {
delete userOptions[name];
}
static _hasUserOptions() {
return Object.keys(userOptions).length > 0;
}
}
exports.AppOptions = AppOptions;
@ -1095,6 +1099,7 @@ const PDFViewerApplication = {
});
await this.downloadManager.download(blob, url, filename, sourceEventType);
} catch (reason) {
console.error(`Error when saving the document: ${reason.message}`);
await this.download({
sourceEventType
});
@ -1511,7 +1516,12 @@ const PDFViewerApplication = {
}
if (info.IsXFAPresent && !info.IsAcroFormPresent && !pdfDocument.isPureXfa) {
console.warn("Warning: XFA support is not enabled");
if (pdfDocument.loadingParams.enableXfa) {
console.warn("Warning: XFA Foreground documents are not supported");
} else {
console.warn("Warning: XFA support is not enabled");
}
this.fallback(_pdfjsLib.UNSUPPORTED_FEATURES.forms);
} else if ((info.IsAcroFormPresent || info.IsXFAPresent) && !this.pdfViewer.renderForms) {
console.warn("Warning: Interactive form support is not enabled");
@ -2916,7 +2926,7 @@ exports.PDFPrintServiceFactory = PDFPrintServiceFactory;
/***/ }),
/* 3 */
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
/***/ ((__unused_webpack_module, exports) => {
@ -2945,12 +2955,7 @@ exports.roundToDivide = roundToDivide;
exports.scrollIntoView = scrollIntoView;
exports.waitOnEventOrTimeout = waitOnEventOrTimeout;
exports.watchScroll = watchScroll;
exports.WaitOnType = exports.VERTICAL_PADDING = exports.UNKNOWN_SCALE = exports.TextLayerMode = exports.SpreadMode = exports.SidebarView = exports.ScrollMode = exports.SCROLLBAR_PADDING = exports.RendererType = exports.ProgressBar = exports.PresentationModeState = exports.MIN_SCALE = exports.MAX_SCALE = exports.MAX_AUTO_SCALE = exports.EventBus = exports.DEFAULT_SCALE_VALUE = exports.DEFAULT_SCALE_DELTA = exports.DEFAULT_SCALE = exports.CSS_UNITS = exports.AutoPrintRegExp = exports.AutomationEventBus = exports.animationStarted = void 0;
var _pdfjsLib = __webpack_require__(4);
const CSS_UNITS = _pdfjsLib.PixelsPerInch.CSS / _pdfjsLib.PixelsPerInch.PDF;
exports.CSS_UNITS = CSS_UNITS;
exports.WaitOnType = exports.VERTICAL_PADDING = exports.UNKNOWN_SCALE = exports.TextLayerMode = exports.SpreadMode = exports.SidebarView = exports.ScrollMode = exports.SCROLLBAR_PADDING = exports.RendererType = exports.ProgressBar = exports.PresentationModeState = exports.MIN_SCALE = exports.MAX_SCALE = exports.MAX_AUTO_SCALE = exports.EventBus = exports.DEFAULT_SCALE_VALUE = exports.DEFAULT_SCALE_DELTA = exports.DEFAULT_SCALE = exports.AutoPrintRegExp = exports.AutomationEventBus = exports.animationStarted = void 0;
const DEFAULT_SCALE_VALUE = "auto";
exports.DEFAULT_SCALE_VALUE = DEFAULT_SCALE_VALUE;
const DEFAULT_SCALE = 1.0;
@ -3441,14 +3446,13 @@ class EventBus {
});
}
dispatch(eventName) {
dispatch(eventName, data) {
const eventListeners = this._listeners[eventName];
if (!eventListeners || eventListeners.length === 0) {
return;
}
const args = Array.prototype.slice.call(arguments, 1);
let externalListeners;
for (const {
@ -3465,12 +3469,12 @@ class EventBus {
continue;
}
listener.apply(null, args);
listener(data);
}
if (externalListeners) {
for (const listener of externalListeners) {
listener.apply(null, args);
listener(data);
}
externalListeners = null;
@ -3506,15 +3510,13 @@ class EventBus {
exports.EventBus = EventBus;
class AutomationEventBus extends EventBus {
dispatch(eventName) {
super.dispatch(...arguments);
dispatch(eventName, data) {
super.dispatch(eventName, data);
const details = Object.create(null);
if (arguments.length > 1) {
const obj = arguments[1];
for (const key in obj) {
const value = obj[key];
if (data) {
for (const key in data) {
const value = data[key];
if (key === "source") {
if (value === window || value === document) {
@ -9680,7 +9682,7 @@ class BaseViewer {
throw new Error("Cannot initialize BaseViewer.");
}
const viewerVersion = '2.11.283';
const viewerVersion = '2.11.298';
if (_pdfjsLib.version !== viewerVersion) {
throw new Error(`The API version "${_pdfjsLib.version}" does not match the Viewer version "${viewerVersion}".`);
@ -9995,7 +9997,7 @@ class BaseViewer {
this._optionalContentConfigPromise = optionalContentConfigPromise;
const scale = this.currentScale;
const viewport = firstPdfPage.getViewport({
scale: scale * _ui_utils.CSS_UNITS
scale: scale * _pdfjsLib.PixelsPerInch.PDF_TO_CSS_UNITS
});
const textLayerFactory = this.textLayerMode !== _ui_utils.TextLayerMode.DISABLE && !isPureXfa ? this : null;
const annotationLayerFactory = this._annotationMode !== _pdfjsLib.AnnotationMode.DISABLE ? this : null;
@ -10339,8 +10341,8 @@ class BaseViewer {
widthScale,
heightScale;
const changeOrientation = pageView.rotation % 180 !== 0;
const pageWidth = (changeOrientation ? pageView.height : pageView.width) / pageView.scale / _ui_utils.CSS_UNITS;
const pageHeight = (changeOrientation ? pageView.width : pageView.height) / pageView.scale / _ui_utils.CSS_UNITS;
const pageWidth = (changeOrientation ? pageView.height : pageView.width) / pageView.scale / _pdfjsLib.PixelsPerInch.PDF_TO_CSS_UNITS;
const pageHeight = (changeOrientation ? pageView.width : pageView.height) / pageView.scale / _pdfjsLib.PixelsPerInch.PDF_TO_CSS_UNITS;
let scale = 0;
switch (destArray[1].name) {
@ -10386,8 +10388,8 @@ class BaseViewer {
height = destArray[5] - y;
const hPadding = this.removePageBorders ? 0 : _ui_utils.SCROLLBAR_PADDING;
const vPadding = this.removePageBorders ? 0 : _ui_utils.VERTICAL_PADDING;
widthScale = (this.container.clientWidth - hPadding) / width / _ui_utils.CSS_UNITS;
heightScale = (this.container.clientHeight - vPadding) / height / _ui_utils.CSS_UNITS;
widthScale = (this.container.clientWidth - hPadding) / width / _pdfjsLib.PixelsPerInch.PDF_TO_CSS_UNITS;
heightScale = (this.container.clientHeight - vPadding) / height / _pdfjsLib.PixelsPerInch.PDF_TO_CSS_UNITS;
scale = Math.min(Math.abs(widthScale), Math.abs(heightScale));
break;
@ -10663,7 +10665,7 @@ class BaseViewer {
});
}
createAnnotationLayerBuilder(pageDiv, pdfPage, annotationStorage = null, imageResourcesPath = "", renderForms = true, l10n = _l10n_utils.NullL10n, enableScripting = null, hasJSActionsPromise = null, mouseState = null) {
createAnnotationLayerBuilder(pageDiv, pdfPage, annotationStorage = null, imageResourcesPath = "", renderForms = true, l10n = _l10n_utils.NullL10n, enableScripting = null, hasJSActionsPromise = null, mouseState = null, fieldObjectsPromise = null) {
return new _annotation_layer_builder.AnnotationLayerBuilder({
pageDiv,
pdfPage,
@ -10675,6 +10677,7 @@ class BaseViewer {
l10n,
enableScripting: enableScripting ?? this.enableScripting,
hasJSActionsPromise: hasJSActionsPromise || this.pdfDocument?.hasJSActions(),
fieldObjectsPromise: fieldObjectsPromise || this.pdfDocument?.getFieldObjects(),
mouseState: mouseState || this._scriptingManager?.mouseState
});
}
@ -11091,6 +11094,7 @@ class AnnotationLayerBuilder {
l10n = _l10n_utils.NullL10n,
enableScripting = false,
hasJSActionsPromise = null,
fieldObjectsPromise = null,
mouseState = null
}) {
this.pageDiv = pageDiv;
@ -11103,49 +11107,51 @@ class AnnotationLayerBuilder {
this.annotationStorage = annotationStorage;
this.enableScripting = enableScripting;
this._hasJSActionsPromise = hasJSActionsPromise;
this._fieldObjectsPromise = fieldObjectsPromise;
this._mouseState = mouseState;
this.div = null;
this._cancelled = false;
}
render(viewport, intent = "display") {
return Promise.all([this.pdfPage.getAnnotations({
async render(viewport, intent = "display") {
const [annotations, hasJSActions = false, fieldObjects = null] = await Promise.all([this.pdfPage.getAnnotations({
intent
}), this._hasJSActionsPromise]).then(([annotations, hasJSActions = false]) => {
if (this._cancelled || annotations.length === 0) {
return;
}
}), this._hasJSActionsPromise, this._fieldObjectsPromise]);
const parameters = {
viewport: viewport.clone({
dontFlip: true
}),
div: this.div,
annotations,
page: this.pdfPage,
imageResourcesPath: this.imageResourcesPath,
renderForms: this.renderForms,
linkService: this.linkService,
downloadManager: this.downloadManager,
annotationStorage: this.annotationStorage,
enableScripting: this.enableScripting,
hasJSActions,
mouseState: this._mouseState
};
if (this._cancelled || annotations.length === 0) {
return;
}
if (this.div) {
_pdfjsLib.AnnotationLayer.update(parameters);
} else {
this.div = document.createElement("div");
this.div.className = "annotationLayer";
this.pageDiv.appendChild(this.div);
parameters.div = this.div;
const parameters = {
viewport: viewport.clone({
dontFlip: true
}),
div: this.div,
annotations,
page: this.pdfPage,
imageResourcesPath: this.imageResourcesPath,
renderForms: this.renderForms,
linkService: this.linkService,
downloadManager: this.downloadManager,
annotationStorage: this.annotationStorage,
enableScripting: this.enableScripting,
hasJSActions,
fieldObjects,
mouseState: this._mouseState
};
_pdfjsLib.AnnotationLayer.render(parameters);
if (this.div) {
_pdfjsLib.AnnotationLayer.update(parameters);
} else {
this.div = document.createElement("div");
this.div.className = "annotationLayer";
this.pageDiv.appendChild(this.div);
parameters.div = this.div;
this.l10n.translate(this.div);
}
});
_pdfjsLib.AnnotationLayer.render(parameters);
this.l10n.translate(this.div);
}
}
cancel() {
@ -11165,7 +11171,7 @@ class AnnotationLayerBuilder {
exports.AnnotationLayerBuilder = AnnotationLayerBuilder;
class DefaultAnnotationLayerFactory {
createAnnotationLayerBuilder(pageDiv, pdfPage, annotationStorage = null, imageResourcesPath = "", renderForms = true, l10n = _l10n_utils.NullL10n, enableScripting = false, hasJSActionsPromise = null, mouseState = null) {
createAnnotationLayerBuilder(pageDiv, pdfPage, annotationStorage = null, imageResourcesPath = "", renderForms = true, l10n = _l10n_utils.NullL10n, enableScripting = false, hasJSActionsPromise = null, mouseState = null, fieldObjectsPromise = null) {
return new AnnotationLayerBuilder({
pageDiv,
pdfPage,
@ -11176,6 +11182,7 @@ class DefaultAnnotationLayerFactory {
annotationStorage,
enableScripting,
hasJSActionsPromise,
fieldObjectsPromise,
mouseState
});
}
@ -11394,7 +11401,7 @@ class PDFPageView {
this.pdfPageRotate = pdfPage.rotate;
const totalRotation = (this.rotation + this.pdfPageRotate) % 360;
this.viewport = pdfPage.getViewport({
scale: this.scale * _ui_utils.CSS_UNITS,
scale: this.scale * _pdfjsLib.PixelsPerInch.PDF_TO_CSS_UNITS,
rotation: totalRotation
});
this.reset();
@ -11561,7 +11568,7 @@ class PDFPageView {
const totalRotation = (this.rotation + this.pdfPageRotate) % 360;
this.viewport = this.viewport.clone({
scale: this.scale * _ui_utils.CSS_UNITS,
scale: this.scale * _pdfjsLib.PixelsPerInch.PDF_TO_CSS_UNITS,
rotation: totalRotation
});
@ -11875,7 +11882,7 @@ class PDFPageView {
if (this._annotationMode !== _pdfjsLib.AnnotationMode.DISABLE && this.annotationLayerFactory) {
if (!this.annotationLayer) {
this.annotationLayer = this.annotationLayerFactory.createAnnotationLayerBuilder(div, pdfPage, null, this.imageResourcesPath, this._annotationMode === _pdfjsLib.AnnotationMode.ENABLE_FORMS, this.l10n, null, null, null);
this.annotationLayer = this.annotationLayerFactory.createAnnotationLayerBuilder(div, pdfPage, null, this.imageResourcesPath, this._annotationMode === _pdfjsLib.AnnotationMode.ENABLE_FORMS, this.l10n, null, null, null, null);
}
this._renderAnnotationLayer();
@ -11968,7 +11975,7 @@ class PDFPageView {
if (this.useOnlyCssZoom) {
const actualSizeViewport = viewport.clone({
scale: _ui_utils.CSS_UNITS
scale: _pdfjsLib.PixelsPerInch.PDF_TO_CSS_UNITS
});
outputScale.sx *= actualSizeViewport.width / viewport.width;
outputScale.sy *= actualSizeViewport.height / viewport.height;
@ -14347,16 +14354,14 @@ Object.defineProperty(exports, "__esModule", ({
}));
exports.getXfaHtmlForPrinting = getXfaHtmlForPrinting;
var _ui_utils = __webpack_require__(3);
var _pdfjsLib = __webpack_require__(4);
var _xfa_layer_builder = __webpack_require__(34);
var _pdfjsLib = __webpack_require__(4);
function getXfaHtmlForPrinting(printContainer, pdfDocument) {
const xfaHtml = pdfDocument.allXfaHtml;
const factory = new _xfa_layer_builder.DefaultXfaLayerFactory();
const scale = Math.round(_ui_utils.CSS_UNITS * 100) / 100;
const scale = Math.round(_pdfjsLib.PixelsPerInch.PDF_TO_CSS_UNITS * 100) / 100;
for (const xfaPage of xfaHtml.children) {
const page = document.createElement("div");
@ -14424,8 +14429,8 @@ var _app_options = __webpack_require__(1);
var _app = __webpack_require__(2);
const pdfjsVersion = '2.11.283';
const pdfjsBuild = '638115885';
const pdfjsVersion = '2.11.298';
const pdfjsBuild = 'd370a281c';
window.PDFViewerApplication = _app.PDFViewerApplication;
window.PDFViewerApplicationOptions = _app_options.AppOptions;
;

View file

@ -20,7 +20,7 @@ origin:
# Human-readable identifier for this version/release
# Generally "version NNN", "tag SSS", "bookmark SSS"
release: version 2.11.283
release: version 2.11.298
# The package's license, where possible using the mnemonic from
# https://spdx.org/licenses/

View file

@ -417,11 +417,11 @@ blocklist:
This field is documented in more detail in the definition of the blocklist.mlbf_source scalar.
Possible values are "dump_match", "cache_match", "remote_match", "dump_fallback", "cache_fallback", "unknown".
notification_emails: ["addons-dev-internal@mozilla.com", "rwu@mozilla.com"]
expiry_version: "95"
expiry_version: "102"
products:
- "firefox"
record_in_processes: ["main"]
bug_numbers: [1662857]
bug_numbers: [1662857, 1730037]
release_channel_collection: opt-out
downloads:

View file

@ -3108,6 +3108,17 @@
"description": "ms elapsed time scanning for client certificates",
"bug_numbers": [1711154]
},
"CRLITE_VS_OCSP_RESULT": {
"record_in_processes": ["main", "socket"],
"products": ["firefox", "fennec"],
"alert_emails": ["seceng-telemetry@mozilla.com", "dkeeler@mozilla.com"],
"bug_numbers": [1675655],
"expires_in_version": "101",
"kind": "categorical",
"releaseChannelCollection": "opt-out",
"description": "Does CRLite and OCSP fetching agree when a certificate is revoked?",
"labels": ["CRLiteOkOCSPFail", "CRLiteRevOCSPFail", "CRLiteOkOCSPOk", "CRLiteOkOCSPRev", "CRLiteRevOCSPOk", "CRLiteRevOCSPRev", "CRLiteOkOCSPUnk", "CRLiteRevOCSPUnk", "CRLiteOkOCSPSoft", "CRLiteRevOCSPSoft" ]
},
"WEBSOCKETS_HANDSHAKE_TYPE": {
"record_in_processes": ["main", "content"],
"products": ["firefox", "fennec"],

View file

@ -5953,11 +5953,12 @@ blocklist:
- 1607744
- 1649960
- 1689274
- 1730037
description: >
Keep track of the last time the "addons" remotesetting blocklist has been successfully
updated (as a datetime string in UTC format), set to "Missing Date" when the timestamp
couldn't be retrieved.
expires: "95"
expires: "102"
kind: string
release_channel_collection: opt-out
notification_emails:
@ -5977,11 +5978,12 @@ blocklist:
- 1633466
- 1649960
- 1689274
- 1730037
description: >
Keep track of the last time the "addons-bloomfilters" remotesetting blocklist has been successfully
updated (as a datetime string in UTC format), set to "Missing Date" when the timestamp
couldn't be retrieved.
expires: "95"
expires: "102"
kind: string
release_channel_collection: opt-out
notification_emails:
@ -5994,39 +5996,16 @@ blocklist:
record_in_processes:
- main
lastModified_rs_plugins:
bug_numbers:
- 1572711
- 1607744
- 1649960
- 1689274
description: >
Keep track of the last time the "plugins" remotesetting blocklist has been successfully
updated (as a datetime string in UTC format), set to "Missing Date" when the timestamp
couldn't be retrieved.
expires: "95"
kind: string
release_channel_collection: opt-out
notification_emails:
- addons-dev-internal@mozilla.com
- lgreco@mozilla.com
- awagner@mozilla.com
- rwu@mozilla.com
products:
- 'firefox'
- 'thunderbird'
record_in_processes:
- main
mlbf_enabled:
bug_numbers:
- 1633466
- 1649960
- 1689274
- 1730037
description: >
Keep track of whether the addons blocklist engine uses bloom filters (blocklist v3).
If false, the blocklist v2 is used instead.
expires: "95"
expires: "102"
kind: boolean
release_channel_collection: opt-out
notification_emails:
@ -6042,6 +6021,7 @@ blocklist:
mlbf_source:
bug_numbers:
- 1662857
- 1730037
description: >
The source of the RemoteSettings attachment that holds the bloom filter.
Possible values are "dump_match", "cache_match", "remote_match", "dump_fallback", "cache_fallback", "unknown".
@ -6054,7 +6034,7 @@ blocklist:
(e.g. because the latest version cannot be downloaded).
"unknown" means that the bloomfilter cannot be loaded at all. This can happen if the blocklist is disabled
via preferences or enterprise policies.
expires: "95"
expires: "102"
kind: string
release_channel_collection: opt-out
notification_emails:
@ -6070,12 +6050,13 @@ blocklist:
- 1633466
- 1649960
- 1689274
- 1730037
description: >
Keep track of the generation time of the addon blocklist's bloom filter. This marks the
point in time until which signed add-ons are recognized by the selected bloom filter from the
addons-bloomfilters collection.
The value is a datetime string in UTC format, or "Missing Date" when unavailable.
expires: "95"
expires: "102"
kind: string
release_channel_collection: opt-out
notification_emails:
@ -6093,11 +6074,12 @@ blocklist:
- 1633466
- 1649960
- 1689274
- 1730037
description: >
Keep track of the timestamp of the oldest stash of the addons blocklist.
Only meaningful when mlbf_enabled is true.
The value is a datetime string in UTC format, or "Missing Date" when unavailable.
expires: "95"
expires: "102"
kind: string
release_channel_collection: opt-out
notification_emails:
@ -6115,11 +6097,12 @@ blocklist:
- 1633466
- 1649960
- 1689274
- 1730037
description: >
Keep track of the timestamp of the most recent stash of the addons blocklist.
Only meaningful when mlbf_enabled is true.
The value is a datetime string in UTC format, or "Missing Date" when unavailable.
expires: "95"
expires: "102"
kind: string
release_channel_collection: opt-out
notification_emails:

View file

@ -168,8 +168,7 @@ const BlocklistTelemetry = {
* to retrieve a valid timestamp).
*
* @param {string} blocklistType
* The blocklist type that has been updated (one of "addons" or "plugins",
* or "addons_mlbf";
* The blocklist type that has been updated ("addons" or "addons_mlbf");
* the "gfx" blocklist is not covered by this telemetry).
* @param {RemoteSettingsClient} remoteSettingsClient
* The RemoteSettings client to retrieve the lastModified timestamp from.