Update On Fri Sep 24 14:42:52 CEST 2021
This commit is contained in:
parent
5d18fcba10
commit
7d77582284
69 changed files with 1596 additions and 530 deletions
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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", "");
|
||||
|
|
|
@ -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 =
|
||||
|
|
|
@ -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
|
||||
);
|
||||
});
|
|
@ -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();
|
||||
},
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
.ds-privacy-link {
|
||||
text-align: center;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
line-height: 24px;
|
||||
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
|
@ -60,6 +60,7 @@ export const selectLayoutRender = ({ state = {}, prefs = {}, locale = "" }) => {
|
|||
"Hero",
|
||||
"HorizontalRule",
|
||||
"List",
|
||||
"PrivacyLink",
|
||||
];
|
||||
|
||||
const filterArray = [];
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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";
|
||||
|
|
168
browser/components/newtab/data/content/assets/firefox.svg
Normal file
168
browser/components/newtab/data/content/assets/firefox.svg
Normal 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 |
|
@ -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",
|
||||
},
|
||||
},
|
||||
},
|
||||
]
|
||||
: []),
|
||||
],
|
||||
},
|
||||
],
|
||||
|
|
|
@ -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>", () => {
|
||||
|
|
|
@ -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 |
|
@ -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
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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) &&
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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)),
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 "
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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>
|
|
@ -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>
|
|
@ -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": {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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';
|
||||
;
|
||||
})();
|
||||
|
||||
|
|
|
@ -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__;
|
||||
|
|
|
@ -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__;
|
||||
|
|
|
@ -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;
|
||||
;
|
||||
|
|
|
@ -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/
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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"],
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue