1238 lines
No EOL
44 KiB
JavaScript
1238 lines
No EOL
44 KiB
JavaScript
/******/ (() => { // webpackBootstrap
|
|
/******/ "use strict";
|
|
/******/ var __webpack_modules__ = ({
|
|
|
|
/***/ 720:
|
|
/***/ ((__unused_webpack___webpack_module__, __unused_webpack___webpack_exports__, __webpack_require__) => {
|
|
|
|
|
|
// EXTERNAL MODULE: ./node_modules/react/index.js
|
|
var react = __webpack_require__(504);
|
|
// EXTERNAL MODULE: ./node_modules/react-dom/index.js
|
|
var react_dom = __webpack_require__(104);
|
|
;// CONCATENATED MODULE: ./content/panels/js/components/Header/Header.jsx
|
|
/* 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/. */
|
|
|
|
|
|
function Header(props) {
|
|
return /*#__PURE__*/react.createElement("h1", {
|
|
className: "stp_header"
|
|
}, /*#__PURE__*/react.createElement("div", {
|
|
className: "stp_header_logo"
|
|
}), props.children);
|
|
}
|
|
/* harmony default export */ const Header_Header = (Header);
|
|
;// CONCATENATED MODULE: ./content/panels/js/messages.mjs
|
|
/* global RPMRemoveMessageListener:false, RPMAddMessageListener:false, RPMSendAsyncMessage:false */
|
|
|
|
var pktPanelMessaging = {
|
|
removeMessageListener(messageId, callback) {
|
|
RPMRemoveMessageListener(messageId, callback);
|
|
},
|
|
|
|
addMessageListener(messageId, callback = () => {}) {
|
|
RPMAddMessageListener(messageId, callback);
|
|
},
|
|
|
|
sendMessage(messageId, payload = {}, callback) {
|
|
if (callback) {
|
|
// If we expect something back, we use RPMSendAsyncMessage and not RPMSendQuery.
|
|
// Even though RPMSendQuery returns something, our frame could be closed at any moment,
|
|
// and we don't want to close a RPMSendQuery promise loop unexpectedly.
|
|
// So instead we setup a response event.
|
|
const responseMessageId = `${messageId}_response`;
|
|
var responseListener = responsePayload => {
|
|
callback(responsePayload);
|
|
this.removeMessageListener(responseMessageId, responseListener);
|
|
};
|
|
|
|
this.addMessageListener(responseMessageId, responseListener);
|
|
}
|
|
|
|
// Send message
|
|
RPMSendAsyncMessage(messageId, payload);
|
|
},
|
|
|
|
// Click helper to reduce bugs caused by oversight
|
|
// from different implementations of similar code.
|
|
clickHelper(element, { source = "", position }) {
|
|
element?.addEventListener(`click`, event => {
|
|
event.preventDefault();
|
|
|
|
this.sendMessage("PKT_openTabWithUrl", {
|
|
url: event.currentTarget.getAttribute(`href`),
|
|
source,
|
|
position,
|
|
});
|
|
});
|
|
},
|
|
|
|
log() {
|
|
RPMSendAsyncMessage("PKT_log", arguments);
|
|
},
|
|
};
|
|
|
|
/* harmony default export */ const messages = (pktPanelMessaging);
|
|
|
|
;// CONCATENATED MODULE: ./content/panels/js/components/TelemetryLink/TelemetryLink.jsx
|
|
/* 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/. */
|
|
|
|
|
|
|
|
function TelemetryLink(props) {
|
|
function onClick(event) {
|
|
if (props.onClick) {
|
|
props.onClick(event);
|
|
} else {
|
|
event.preventDefault();
|
|
messages.sendMessage("PKT_openTabWithUrl", {
|
|
url: event.currentTarget.getAttribute(`href`),
|
|
source: props.source,
|
|
model: props.model,
|
|
position: props.position
|
|
});
|
|
}
|
|
}
|
|
return /*#__PURE__*/react.createElement("a", {
|
|
href: props.href,
|
|
onClick: onClick,
|
|
target: "_blank",
|
|
className: props.className
|
|
}, props.children);
|
|
}
|
|
/* harmony default export */ const TelemetryLink_TelemetryLink = (TelemetryLink);
|
|
;// CONCATENATED MODULE: ./content/panels/js/components/ArticleList/ArticleList.jsx
|
|
/* 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/. */
|
|
|
|
|
|
|
|
function ArticleUrl(props) {
|
|
// We turn off the link if we're either a saved article, or if the url doesn't exist.
|
|
if (props.savedArticle || !props.url) {
|
|
return /*#__PURE__*/react.createElement("div", {
|
|
className: "stp_article_list_saved_article"
|
|
}, props.children);
|
|
}
|
|
return /*#__PURE__*/react.createElement(TelemetryLink_TelemetryLink, {
|
|
className: "stp_article_list_link",
|
|
href: props.url,
|
|
source: props.source,
|
|
position: props.position,
|
|
model: props.model
|
|
}, props.children);
|
|
}
|
|
function Article(props) {
|
|
function encodeThumbnail(rawSource) {
|
|
return rawSource ? `https://img-getpocket.cdn.mozilla.net/80x80/filters:format(jpeg):quality(60):no_upscale():strip_exif()/${encodeURIComponent(rawSource)}` : null;
|
|
}
|
|
const [thumbnailLoaded, setThumbnailLoaded] = (0,react.useState)(false);
|
|
const [thumbnailLoadFailed, setThumbnailLoadFailed] = (0,react.useState)(false);
|
|
const {
|
|
article,
|
|
savedArticle,
|
|
position,
|
|
source,
|
|
model,
|
|
utmParams,
|
|
openInPocketReader
|
|
} = props;
|
|
if (!article.url && !article.resolved_url && !article.given_url) {
|
|
return null;
|
|
}
|
|
const url = new URL(article.url || article.resolved_url || article.given_url);
|
|
const urlSearchParams = new URLSearchParams(utmParams);
|
|
if (openInPocketReader && article.item_id && !url.href.match(/getpocket\.com\/read/)) {
|
|
url.href = `https://getpocket.com/read/${article.item_id}`;
|
|
}
|
|
for (let [key, val] of urlSearchParams.entries()) {
|
|
url.searchParams.set(key, val);
|
|
}
|
|
|
|
// Using array notation because there is a key titled `1` (`images` is an object)
|
|
const thumbnail = article.thumbnail || encodeThumbnail(article?.top_image_url || article?.images?.["1"]?.src);
|
|
const alt = article.alt || "thumbnail image";
|
|
const title = article.title || article.resolved_title || article.given_title;
|
|
// Sometimes domain_metadata is not there, depending on the source.
|
|
const publisher = article.publisher || article.domain_metadata?.name || article.resolved_domain;
|
|
return /*#__PURE__*/react.createElement("li", {
|
|
className: "stp_article_list_item"
|
|
}, /*#__PURE__*/react.createElement(ArticleUrl, {
|
|
url: url.href,
|
|
savedArticle: savedArticle,
|
|
position: position,
|
|
source: source,
|
|
model: model,
|
|
utmParams: utmParams
|
|
}, /*#__PURE__*/react.createElement(react.Fragment, null, thumbnail && !thumbnailLoadFailed ? /*#__PURE__*/react.createElement("img", {
|
|
className: "stp_article_list_thumb",
|
|
src: thumbnail,
|
|
alt: alt,
|
|
width: "40",
|
|
height: "40",
|
|
onLoad: () => {
|
|
setThumbnailLoaded(true);
|
|
},
|
|
onError: () => {
|
|
setThumbnailLoadFailed(true);
|
|
},
|
|
style: {
|
|
visibility: thumbnailLoaded ? `visible` : `hidden`
|
|
}
|
|
}) : /*#__PURE__*/react.createElement("div", {
|
|
className: "stp_article_list_thumb_placeholder"
|
|
}), /*#__PURE__*/react.createElement("div", {
|
|
className: "stp_article_list_meta"
|
|
}, /*#__PURE__*/react.createElement("header", {
|
|
className: "stp_article_list_header"
|
|
}, title), /*#__PURE__*/react.createElement("p", {
|
|
className: "stp_article_list_publisher"
|
|
}, publisher)))));
|
|
}
|
|
function ArticleList(props) {
|
|
return /*#__PURE__*/react.createElement("ul", {
|
|
className: "stp_article_list"
|
|
}, props.articles?.map((article, position) => /*#__PURE__*/react.createElement(Article, {
|
|
article: article,
|
|
savedArticle: props.savedArticle,
|
|
position: position,
|
|
source: props.source,
|
|
model: props.model,
|
|
utmParams: props.utmParams,
|
|
openInPocketReader: props.openInPocketReader
|
|
})));
|
|
}
|
|
/* harmony default export */ const ArticleList_ArticleList = (ArticleList);
|
|
;// CONCATENATED MODULE: ./content/panels/js/components/PopularTopics/PopularTopics.jsx
|
|
/* 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/. */
|
|
|
|
|
|
|
|
function PopularTopics(props) {
|
|
return /*#__PURE__*/react.createElement("ul", {
|
|
className: "stp_popular_topics"
|
|
}, props.topics?.map((topic, position) => /*#__PURE__*/react.createElement("li", {
|
|
key: `item-${topic.topic}`,
|
|
className: "stp_popular_topic"
|
|
}, /*#__PURE__*/react.createElement(TelemetryLink_TelemetryLink, {
|
|
className: "stp_popular_topic_link",
|
|
href: `https://${props.pockethost}/explore/${topic.topic}?${props.utmParams}`,
|
|
source: props.source,
|
|
position: position
|
|
}, topic.title))));
|
|
}
|
|
/* harmony default export */ const PopularTopics_PopularTopics = (PopularTopics);
|
|
;// CONCATENATED MODULE: ./content/panels/js/components/Button/Button.jsx
|
|
/* 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/. */
|
|
|
|
|
|
|
|
function Button(props) {
|
|
return /*#__PURE__*/react.createElement(TelemetryLink_TelemetryLink, {
|
|
href: props.url,
|
|
onClick: props.onClick,
|
|
className: `stp_button${props?.style && ` stp_button_${props.style}`}`,
|
|
source: props.source
|
|
}, props.children);
|
|
}
|
|
/* harmony default export */ const Button_Button = (Button);
|
|
;// CONCATENATED MODULE: ./content/panels/js/components/Home/Home.jsx
|
|
/* 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/. */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function Home(props) {
|
|
const {
|
|
locale,
|
|
topics,
|
|
pockethost,
|
|
hideRecentSaves,
|
|
utmSource,
|
|
utmCampaign,
|
|
utmContent
|
|
} = props;
|
|
const [{
|
|
articles,
|
|
status
|
|
}, setArticlesState] = (0,react.useState)({
|
|
articles: [],
|
|
// Can be success, loading, or error.
|
|
status: ""
|
|
});
|
|
const utmParams = `utm_source=${utmSource}${utmCampaign && utmContent ? `&utm_campaign=${utmCampaign}&utm_content=${utmContent}` : ``}`;
|
|
const loadingRecentSaves = (0,react.useCallback)(() => {
|
|
setArticlesState(prevState => ({
|
|
...prevState,
|
|
status: "loading"
|
|
}));
|
|
}, []);
|
|
const renderRecentSaves = (0,react.useCallback)(resp => {
|
|
const {
|
|
data
|
|
} = resp;
|
|
if (data.status === "error") {
|
|
setArticlesState(prevState => ({
|
|
...prevState,
|
|
status: "error"
|
|
}));
|
|
return;
|
|
}
|
|
setArticlesState({
|
|
articles: data,
|
|
status: "success"
|
|
});
|
|
}, []);
|
|
(0,react.useEffect)(() => {
|
|
if (!hideRecentSaves) {
|
|
// We don't display the loading message until instructed. This is because cache
|
|
// loads should be fast, so using the loading message for cache just adds loading jank.
|
|
messages.addMessageListener("PKT_loadingRecentSaves", loadingRecentSaves);
|
|
messages.addMessageListener("PKT_renderRecentSaves", renderRecentSaves);
|
|
}
|
|
}, [hideRecentSaves, loadingRecentSaves, renderRecentSaves]);
|
|
(0,react.useEffect)(() => {
|
|
// tell back end we're ready
|
|
messages.sendMessage("PKT_show_home");
|
|
}, []);
|
|
let recentSavesSection = null;
|
|
if (status === "error" || hideRecentSaves) {
|
|
recentSavesSection = /*#__PURE__*/react.createElement("h3", {
|
|
className: "header_medium",
|
|
"data-l10n-id": "pocket-panel-home-new-user-cta"
|
|
});
|
|
} else if (status === "loading") {
|
|
recentSavesSection = /*#__PURE__*/react.createElement("span", {
|
|
"data-l10n-id": "pocket-panel-home-most-recent-saves-loading"
|
|
});
|
|
} else if (status === "success") {
|
|
if (articles?.length) {
|
|
recentSavesSection = /*#__PURE__*/react.createElement(react.Fragment, null, /*#__PURE__*/react.createElement("h3", {
|
|
className: "header_medium",
|
|
"data-l10n-id": "pocket-panel-home-most-recent-saves"
|
|
}), articles.length > 3 ? /*#__PURE__*/react.createElement(react.Fragment, null, /*#__PURE__*/react.createElement(ArticleList_ArticleList, {
|
|
articles: articles.slice(0, 3),
|
|
source: "home_recent_save",
|
|
utmParams: utmParams,
|
|
openInPocketReader: true
|
|
}), /*#__PURE__*/react.createElement("span", {
|
|
className: "stp_button_wide"
|
|
}, /*#__PURE__*/react.createElement(Button_Button, {
|
|
style: "secondary",
|
|
url: `https://${pockethost}/a?${utmParams}`,
|
|
source: "home_view_list"
|
|
}, /*#__PURE__*/react.createElement("span", {
|
|
"data-l10n-id": "pocket-panel-button-show-all"
|
|
})))) : /*#__PURE__*/react.createElement(ArticleList_ArticleList, {
|
|
articles: articles,
|
|
source: "home_recent_save",
|
|
utmParams: utmParams
|
|
}));
|
|
} else {
|
|
recentSavesSection = /*#__PURE__*/react.createElement(react.Fragment, null, /*#__PURE__*/react.createElement("h3", {
|
|
className: "header_medium",
|
|
"data-l10n-id": "pocket-panel-home-new-user-cta"
|
|
}), /*#__PURE__*/react.createElement("h3", {
|
|
className: "header_medium",
|
|
"data-l10n-id": "pocket-panel-home-new-user-message"
|
|
}));
|
|
}
|
|
}
|
|
return /*#__PURE__*/react.createElement("div", {
|
|
className: "stp_panel_container"
|
|
}, /*#__PURE__*/react.createElement("div", {
|
|
className: "stp_panel stp_panel_home"
|
|
}, /*#__PURE__*/react.createElement(Header_Header, null, /*#__PURE__*/react.createElement(Button_Button, {
|
|
style: "primary",
|
|
url: `https://${pockethost}/a?${utmParams}`,
|
|
source: "home_view_list"
|
|
}, /*#__PURE__*/react.createElement("span", {
|
|
"data-l10n-id": "pocket-panel-header-my-saves"
|
|
}))), /*#__PURE__*/react.createElement("hr", null), recentSavesSection, /*#__PURE__*/react.createElement("hr", null), pockethost && locale?.startsWith("en") && topics?.length && /*#__PURE__*/react.createElement(react.Fragment, null, /*#__PURE__*/react.createElement("h3", {
|
|
className: "header_medium"
|
|
}, "Explore popular topics:"), /*#__PURE__*/react.createElement(PopularTopics_PopularTopics, {
|
|
topics: topics,
|
|
pockethost: pockethost,
|
|
utmParams: utmParams,
|
|
source: "home_popular_topic"
|
|
}))));
|
|
}
|
|
/* harmony default export */ const Home_Home = (Home);
|
|
;// CONCATENATED MODULE: ./content/panels/js/home/overlay.jsx
|
|
/*
|
|
HomeOverlay is the view itself and contains all of the methods to manipute the overlay and messaging.
|
|
It does not contain any logic for saving or communication with the extension or server.
|
|
*/
|
|
|
|
|
|
|
|
|
|
var HomeOverlay = function () {
|
|
this.inited = false;
|
|
this.active = false;
|
|
};
|
|
HomeOverlay.prototype = {
|
|
create({
|
|
pockethost
|
|
}) {
|
|
const {
|
|
searchParams
|
|
} = new URL(window.location.href);
|
|
const locale = searchParams.get(`locale`) || ``;
|
|
const hideRecentSaves = searchParams.get(`hiderecentsaves`) === `true`;
|
|
const utmSource = searchParams.get(`utmSource`);
|
|
const utmCampaign = searchParams.get(`utmCampaign`);
|
|
const utmContent = searchParams.get(`utmContent`);
|
|
if (this.active) {
|
|
return;
|
|
}
|
|
this.active = true;
|
|
react_dom.render( /*#__PURE__*/react.createElement(Home_Home, {
|
|
locale: locale,
|
|
hideRecentSaves: hideRecentSaves,
|
|
pockethost: pockethost,
|
|
utmSource: utmSource,
|
|
utmCampaign: utmCampaign,
|
|
utmContent: utmContent
|
|
}), document.querySelector(`body`));
|
|
if (window?.matchMedia(`(prefers-color-scheme: dark)`).matches) {
|
|
document.querySelector(`body`).classList.add(`theme_dark`);
|
|
}
|
|
}
|
|
};
|
|
/* harmony default export */ const overlay = (HomeOverlay);
|
|
;// CONCATENATED MODULE: ./content/panels/js/components/Signup/Signup.jsx
|
|
/* 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/. */
|
|
|
|
|
|
|
|
|
|
function Signup(props) {
|
|
const {
|
|
locale,
|
|
pockethost,
|
|
utmSource,
|
|
utmCampaign,
|
|
utmContent
|
|
} = props;
|
|
const utmParams = `utm_source=${utmSource}${utmCampaign && utmContent ? `&utm_campaign=${utmCampaign}&utm_content=${utmContent}` : ``}`;
|
|
return /*#__PURE__*/react.createElement("div", {
|
|
className: "stp_panel_container"
|
|
}, /*#__PURE__*/react.createElement("div", {
|
|
className: "stp_panel stp_panel_signup"
|
|
}, /*#__PURE__*/react.createElement(Header_Header, null, /*#__PURE__*/react.createElement(Button_Button, {
|
|
style: "secondary",
|
|
url: `https://${pockethost}/login?${utmParams}`,
|
|
source: "log_in"
|
|
}, /*#__PURE__*/react.createElement("span", {
|
|
"data-l10n-id": "pocket-panel-signup-login"
|
|
}))), /*#__PURE__*/react.createElement("hr", null), locale?.startsWith("en") ? /*#__PURE__*/react.createElement(react.Fragment, null, /*#__PURE__*/react.createElement("div", {
|
|
className: "stp_signup_content_wrapper"
|
|
}, /*#__PURE__*/react.createElement("h3", {
|
|
className: "header_medium",
|
|
"data-l10n-id": "pocket-panel-signup-cta-a-fix"
|
|
}), /*#__PURE__*/react.createElement("p", {
|
|
"data-l10n-id": "pocket-panel-signup-cta-b-updated"
|
|
})), /*#__PURE__*/react.createElement("div", {
|
|
className: "stp_signup_content_wrapper"
|
|
}, /*#__PURE__*/react.createElement("hr", null)), /*#__PURE__*/react.createElement("div", {
|
|
className: "stp_signup_content_wrapper"
|
|
}, /*#__PURE__*/react.createElement("div", {
|
|
className: "stp_signup_img_rainbow_reader"
|
|
}), /*#__PURE__*/react.createElement("h3", {
|
|
className: "header_medium"
|
|
}, "Get thought-provoking article recommendations"), /*#__PURE__*/react.createElement("p", null, "Find stories that go deep into a subject or offer a new perspective."))) : /*#__PURE__*/react.createElement("div", {
|
|
className: "stp_signup_content_wrapper"
|
|
}, /*#__PURE__*/react.createElement("h3", {
|
|
className: "header_large",
|
|
"data-l10n-id": "pocket-panel-signup-cta-a-fix"
|
|
}), /*#__PURE__*/react.createElement("p", {
|
|
"data-l10n-id": "pocket-panel-signup-cta-b-short"
|
|
}), /*#__PURE__*/react.createElement("strong", null, /*#__PURE__*/react.createElement("p", {
|
|
"data-l10n-id": "pocket-panel-signup-cta-c-updated"
|
|
}))), /*#__PURE__*/react.createElement("hr", null), /*#__PURE__*/react.createElement("span", {
|
|
className: "stp_button_wide"
|
|
}, /*#__PURE__*/react.createElement(Button_Button, {
|
|
style: "primary",
|
|
url: `https://${pockethost}/ff_signup?${utmParams}`,
|
|
source: "sign_up_1"
|
|
}, /*#__PURE__*/react.createElement("span", {
|
|
"data-l10n-id": "pocket-panel-button-activate"
|
|
})))));
|
|
}
|
|
/* harmony default export */ const Signup_Signup = (Signup);
|
|
;// CONCATENATED MODULE: ./content/panels/js/signup/overlay.jsx
|
|
/*
|
|
SignupOverlay is the view itself and contains all of the methods to manipute the overlay and messaging.
|
|
It does not contain any logic for saving or communication with the extension or server.
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
var SignupOverlay = function () {
|
|
this.inited = false;
|
|
this.active = false;
|
|
this.create = function ({
|
|
pockethost
|
|
}) {
|
|
// Extract local variables passed into template via URL query params
|
|
const {
|
|
searchParams
|
|
} = new URL(window.location.href);
|
|
const locale = searchParams.get(`locale`) || ``;
|
|
const utmSource = searchParams.get(`utmSource`);
|
|
const utmCampaign = searchParams.get(`utmCampaign`);
|
|
const utmContent = searchParams.get(`utmContent`);
|
|
if (this.active) {
|
|
return;
|
|
}
|
|
this.active = true;
|
|
|
|
// Create actual content
|
|
react_dom.render( /*#__PURE__*/react.createElement(Signup_Signup, {
|
|
pockethost: pockethost,
|
|
utmSource: utmSource,
|
|
utmCampaign: utmCampaign,
|
|
utmContent: utmContent,
|
|
locale: locale
|
|
}), document.querySelector(`body`));
|
|
if (window?.matchMedia(`(prefers-color-scheme: dark)`).matches) {
|
|
document.querySelector(`body`).classList.add(`theme_dark`);
|
|
}
|
|
|
|
// tell back end we're ready
|
|
messages.sendMessage("PKT_show_signup");
|
|
};
|
|
};
|
|
/* harmony default export */ const signup_overlay = (SignupOverlay);
|
|
;// CONCATENATED MODULE: ./content/panels/js/components/TagPicker/TagPicker.jsx
|
|
/* 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/. */
|
|
|
|
|
|
|
|
function TagPicker(props) {
|
|
const [tags, setTags] = (0,react.useState)(props.tags); // New tag group to store
|
|
const [allTags, setAllTags] = (0,react.useState)([]); // All tags ever used (in no particular order)
|
|
const [recentTags, setRecentTags] = (0,react.useState)([]); // Most recently used tags
|
|
const [duplicateTag, setDuplicateTag] = (0,react.useState)(null);
|
|
const [inputValue, setInputValue] = (0,react.useState)("");
|
|
|
|
// Status can be success, waiting, or error.
|
|
const [{
|
|
tagInputStatus,
|
|
tagInputErrorMessage
|
|
}, setTagInputStatus] = (0,react.useState)({
|
|
tagInputStatus: "",
|
|
tagInputErrorMessage: ""
|
|
});
|
|
let handleKeyDown = e => {
|
|
const enterKey = e.keyCode === 13;
|
|
const commaKey = e.keyCode === 188;
|
|
const tabKey = inputValue && e.keyCode === 9;
|
|
|
|
// Submit tags on enter with no input.
|
|
// Enter tag on comma, tab, or enter with input.
|
|
// Tab to next element with no input.
|
|
if (commaKey || enterKey || tabKey) {
|
|
e.preventDefault();
|
|
if (inputValue) {
|
|
addTag(inputValue.trim());
|
|
setInputValue(``); // Clear out input
|
|
} else if (enterKey) {
|
|
submitTags();
|
|
}
|
|
}
|
|
};
|
|
let addTag = tagToAdd => {
|
|
if (!tagToAdd?.length) {
|
|
return;
|
|
}
|
|
let newDuplicateTag = tags.find(item => item === tagToAdd);
|
|
if (!newDuplicateTag) {
|
|
setTags([...tags, tagToAdd]);
|
|
} else {
|
|
setDuplicateTag(newDuplicateTag);
|
|
setTimeout(() => {
|
|
setDuplicateTag(null);
|
|
}, 1000);
|
|
}
|
|
};
|
|
let removeTag = index => {
|
|
let updatedTags = tags.slice(0); // Shallow copied array
|
|
updatedTags.splice(index, 1);
|
|
setTags(updatedTags);
|
|
};
|
|
let submitTags = () => {
|
|
let tagsToSubmit = [];
|
|
if (tags?.length) {
|
|
tagsToSubmit = tags;
|
|
}
|
|
|
|
// Capture tags that have been typed in but not explicitly added to the tag collection
|
|
if (inputValue?.trim().length) {
|
|
tagsToSubmit.push(inputValue.trim());
|
|
}
|
|
if (!props.itemUrl || !tagsToSubmit?.length) {
|
|
return;
|
|
}
|
|
setTagInputStatus({
|
|
tagInputStatus: "waiting",
|
|
tagInputErrorMessage: ""
|
|
});
|
|
messages.sendMessage("PKT_addTags", {
|
|
url: props.itemUrl,
|
|
tags: tagsToSubmit
|
|
}, function (resp) {
|
|
const {
|
|
data
|
|
} = resp;
|
|
if (data.status === "success") {
|
|
setTagInputStatus({
|
|
tagInputStatus: "success",
|
|
tagInputErrorMessage: ""
|
|
});
|
|
} else if (data.status === "error") {
|
|
setTagInputStatus({
|
|
tagInputStatus: "error",
|
|
tagInputErrorMessage: data.error.message
|
|
});
|
|
}
|
|
});
|
|
};
|
|
(0,react.useEffect)(() => {
|
|
messages.sendMessage("PKT_getTags", {}, resp => {
|
|
setAllTags(resp?.data?.tags);
|
|
});
|
|
}, []);
|
|
(0,react.useEffect)(() => {
|
|
messages.sendMessage("PKT_getRecentTags", {}, resp => {
|
|
setRecentTags(resp?.data?.recentTags);
|
|
});
|
|
}, []);
|
|
return /*#__PURE__*/react.createElement("div", {
|
|
className: "stp_tag_picker"
|
|
}, !tagInputStatus && /*#__PURE__*/react.createElement(react.Fragment, null, /*#__PURE__*/react.createElement("h3", {
|
|
className: "header_small",
|
|
"data-l10n-id": "pocket-panel-signup-add-tags"
|
|
}), /*#__PURE__*/react.createElement("div", {
|
|
className: "stp_tag_picker_tags"
|
|
}, tags.map((tag, i) => /*#__PURE__*/react.createElement("div", {
|
|
className: `stp_tag_picker_tag${duplicateTag === tag ? ` stp_tag_picker_tag_duplicate` : ``}`
|
|
}, /*#__PURE__*/react.createElement("button", {
|
|
onClick: () => removeTag(i),
|
|
className: `stp_tag_picker_tag_remove`
|
|
}, "X"), tag)), /*#__PURE__*/react.createElement("div", {
|
|
className: "stp_tag_picker_input_wrapper"
|
|
}, /*#__PURE__*/react.createElement("input", {
|
|
className: "stp_tag_picker_input",
|
|
type: "text",
|
|
list: "tag-list",
|
|
value: inputValue,
|
|
onChange: e => setInputValue(e.target.value),
|
|
onKeyDown: e => handleKeyDown(e),
|
|
maxlength: "25"
|
|
}), /*#__PURE__*/react.createElement("datalist", {
|
|
id: "tag-list"
|
|
}, allTags.sort((a, b) => a.search(inputValue) - b.search(inputValue)).map(item => /*#__PURE__*/react.createElement("option", {
|
|
key: item,
|
|
value: item
|
|
}))), /*#__PURE__*/react.createElement("button", {
|
|
className: "stp_tag_picker_button",
|
|
disabled: !inputValue?.length && !tags.length,
|
|
"data-l10n-id": "pocket-panel-saved-save-tags",
|
|
onClick: () => submitTags()
|
|
}))), /*#__PURE__*/react.createElement("div", {
|
|
className: "recent_tags"
|
|
}, recentTags.slice(0, 3).filter(recentTag => {
|
|
return !tags.find(item => item === recentTag);
|
|
}).map(tag => /*#__PURE__*/react.createElement("div", {
|
|
className: "stp_tag_picker_tag"
|
|
}, /*#__PURE__*/react.createElement("button", {
|
|
className: "stp_tag_picker_tag_remove",
|
|
onClick: () => addTag(tag)
|
|
}, "+ ", tag))))), tagInputStatus === "waiting" && /*#__PURE__*/react.createElement("h3", {
|
|
className: "header_large",
|
|
"data-l10n-id": "pocket-panel-saved-processing-tags"
|
|
}), tagInputStatus === "success" && /*#__PURE__*/react.createElement("h3", {
|
|
className: "header_large",
|
|
"data-l10n-id": "pocket-panel-saved-tags-saved"
|
|
}), tagInputStatus === "error" && /*#__PURE__*/react.createElement("h3", {
|
|
className: "header_small"
|
|
}, tagInputErrorMessage));
|
|
}
|
|
/* harmony default export */ const TagPicker_TagPicker = (TagPicker);
|
|
;// CONCATENATED MODULE: ./content/panels/js/components/Saved/Saved.jsx
|
|
/* 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/. */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function Saved(props) {
|
|
const {
|
|
locale,
|
|
pockethost,
|
|
utmSource,
|
|
utmCampaign,
|
|
utmContent
|
|
} = props;
|
|
// savedStatus can be success, loading, or error.
|
|
const [{
|
|
savedStatus,
|
|
savedErrorId,
|
|
itemId,
|
|
itemUrl
|
|
}, setSavedStatusState] = (0,react.useState)({
|
|
savedStatus: "loading"
|
|
});
|
|
// removedStatus can be removed, removing, or error.
|
|
const [{
|
|
removedStatus,
|
|
removedErrorMessage
|
|
}, setRemovedStatusState] = (0,react.useState)({});
|
|
const [savedStory, setSavedStoryState] = (0,react.useState)();
|
|
const [articleInfoAttempted, setArticleInfoAttempted] = (0,react.useState)();
|
|
const utmParams = `utm_source=${utmSource}${utmCampaign && utmContent ? `&utm_campaign=${utmCampaign}&utm_content=${utmContent}` : ``}`;
|
|
function removeItem(event) {
|
|
event.preventDefault();
|
|
setRemovedStatusState({
|
|
removedStatus: "removing"
|
|
});
|
|
messages.sendMessage("PKT_deleteItem", {
|
|
itemId
|
|
}, function (resp) {
|
|
const {
|
|
data
|
|
} = resp;
|
|
if (data.status == "success") {
|
|
setRemovedStatusState({
|
|
removedStatus: "removed"
|
|
});
|
|
} else if (data.status == "error") {
|
|
let errorMessage = "";
|
|
// The server returns English error messages, so in the case of
|
|
// non English, we do our best with a generic translated error.
|
|
if (data.error.message && locale?.startsWith("en")) {
|
|
errorMessage = data.error.message;
|
|
}
|
|
setRemovedStatusState({
|
|
removedStatus: "error",
|
|
removedErrorMessage: errorMessage
|
|
});
|
|
}
|
|
});
|
|
}
|
|
(0,react.useEffect)(() => {
|
|
// Wait confirmation of save before flipping to final saved state
|
|
messages.addMessageListener("PKT_saveLink", function (resp) {
|
|
const {
|
|
data
|
|
} = resp;
|
|
if (data.status == "error") {
|
|
// Use localizedKey or fallback to a generic catch all error.
|
|
setSavedStatusState({
|
|
savedStatus: "error",
|
|
savedErrorId: data?.error?.localizedKey || "pocket-panel-saved-error-generic"
|
|
});
|
|
return;
|
|
}
|
|
|
|
// Success, so no localized error id needed.
|
|
setSavedStatusState({
|
|
savedStatus: "success",
|
|
itemId: data.item?.item_id,
|
|
itemUrl: data.item?.given_url,
|
|
savedErrorId: ""
|
|
});
|
|
});
|
|
messages.addMessageListener("PKT_articleInfoFetched", function (resp) {
|
|
setSavedStoryState(resp?.data?.item_preview);
|
|
});
|
|
messages.addMessageListener("PKT_getArticleInfoAttempted", function () {
|
|
setArticleInfoAttempted(true);
|
|
});
|
|
|
|
// tell back end we're ready
|
|
messages.sendMessage("PKT_show_saved");
|
|
}, []);
|
|
if (savedStatus === "error") {
|
|
return /*#__PURE__*/react.createElement("div", {
|
|
className: "stp_panel_container"
|
|
}, /*#__PURE__*/react.createElement("div", {
|
|
className: "stp_panel stp_panel_error"
|
|
}, /*#__PURE__*/react.createElement("div", {
|
|
className: "stp_panel_error_icon"
|
|
}), /*#__PURE__*/react.createElement("h3", {
|
|
className: "header_large",
|
|
"data-l10n-id": "pocket-panel-saved-error-not-saved"
|
|
}), /*#__PURE__*/react.createElement("p", {
|
|
"data-l10n-id": savedErrorId
|
|
})));
|
|
}
|
|
return /*#__PURE__*/react.createElement("div", {
|
|
className: "stp_panel_container"
|
|
}, /*#__PURE__*/react.createElement("div", {
|
|
className: "stp_panel stp_panel_saved"
|
|
}, /*#__PURE__*/react.createElement(Header_Header, null, /*#__PURE__*/react.createElement(Button_Button, {
|
|
style: "primary",
|
|
url: `https://${pockethost}/a?${utmParams}`,
|
|
source: "view_list"
|
|
}, /*#__PURE__*/react.createElement("span", {
|
|
"data-l10n-id": "pocket-panel-header-my-saves"
|
|
}))), /*#__PURE__*/react.createElement("hr", null), !removedStatus && savedStatus === "success" && /*#__PURE__*/react.createElement(react.Fragment, null, /*#__PURE__*/react.createElement("h3", {
|
|
className: "header_large header_flex"
|
|
}, /*#__PURE__*/react.createElement("span", {
|
|
"data-l10n-id": "pocket-panel-saved-page-saved-b"
|
|
}), /*#__PURE__*/react.createElement(Button_Button, {
|
|
style: "text",
|
|
onClick: removeItem
|
|
}, /*#__PURE__*/react.createElement("span", {
|
|
"data-l10n-id": "pocket-panel-button-remove"
|
|
}))), savedStory && /*#__PURE__*/react.createElement(ArticleList_ArticleList, {
|
|
articles: [savedStory],
|
|
openInPocketReader: true,
|
|
utmParams: utmParams
|
|
}), articleInfoAttempted && /*#__PURE__*/react.createElement(TagPicker_TagPicker, {
|
|
tags: [],
|
|
itemUrl: itemUrl
|
|
})), savedStatus === "loading" && /*#__PURE__*/react.createElement("h3", {
|
|
className: "header_large",
|
|
"data-l10n-id": "pocket-panel-saved-saving-tags"
|
|
}), removedStatus === "removing" && /*#__PURE__*/react.createElement("h3", {
|
|
className: "header_large header_center",
|
|
"data-l10n-id": "pocket-panel-saved-processing-remove"
|
|
}), removedStatus === "removed" && /*#__PURE__*/react.createElement("h3", {
|
|
className: "header_large header_center",
|
|
"data-l10n-id": "pocket-panel-saved-removed-updated"
|
|
}), removedStatus === "error" && /*#__PURE__*/react.createElement(react.Fragment, null, /*#__PURE__*/react.createElement("h3", {
|
|
className: "header_large",
|
|
"data-l10n-id": "pocket-panel-saved-error-remove"
|
|
}), removedErrorMessage && /*#__PURE__*/react.createElement("p", null, removedErrorMessage))));
|
|
}
|
|
/* harmony default export */ const Saved_Saved = (Saved);
|
|
;// CONCATENATED MODULE: ./content/panels/js/saved/overlay.jsx
|
|
/*
|
|
SavedOverlay is the view itself and contains all of the methods to manipute the overlay and messaging.
|
|
It does not contain any logic for saving or communication with the extension or server.
|
|
*/
|
|
|
|
|
|
|
|
|
|
var SavedOverlay = function () {
|
|
this.inited = false;
|
|
this.active = false;
|
|
};
|
|
SavedOverlay.prototype = {
|
|
create({
|
|
pockethost
|
|
}) {
|
|
if (this.active) {
|
|
return;
|
|
}
|
|
this.active = true;
|
|
const {
|
|
searchParams
|
|
} = new URL(window.location.href);
|
|
const locale = searchParams.get(`locale`) || ``;
|
|
const utmSource = searchParams.get(`utmSource`);
|
|
const utmCampaign = searchParams.get(`utmCampaign`);
|
|
const utmContent = searchParams.get(`utmContent`);
|
|
react_dom.render( /*#__PURE__*/react.createElement(Saved_Saved, {
|
|
locale: locale,
|
|
pockethost: pockethost,
|
|
utmSource: utmSource,
|
|
utmCampaign: utmCampaign,
|
|
utmContent: utmContent
|
|
}), document.querySelector(`body`));
|
|
if (window?.matchMedia(`(prefers-color-scheme: dark)`).matches) {
|
|
document.querySelector(`body`).classList.add(`theme_dark`);
|
|
}
|
|
}
|
|
};
|
|
/* harmony default export */ const saved_overlay = (SavedOverlay);
|
|
;// CONCATENATED MODULE: ./content/panels/js/style-guide/overlay.jsx
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var StyleGuideOverlay = function () {};
|
|
StyleGuideOverlay.prototype = {
|
|
create() {
|
|
// TODO: Wrap popular topics component in JSX to work without needing an explicit container hierarchy for styling
|
|
react_dom.render( /*#__PURE__*/react.createElement("div", null, /*#__PURE__*/react.createElement("h3", null, "JSX Components:"), /*#__PURE__*/react.createElement("h4", {
|
|
className: "stp_styleguide_h4"
|
|
}, "Buttons"), /*#__PURE__*/react.createElement("h5", {
|
|
className: "stp_styleguide_h5"
|
|
}, "text"), /*#__PURE__*/react.createElement(Button_Button, {
|
|
style: "text",
|
|
url: "https://example.org",
|
|
source: "styleguide"
|
|
}, "Text Button"), /*#__PURE__*/react.createElement("h5", {
|
|
className: "stp_styleguide_h5"
|
|
}, "primary"), /*#__PURE__*/react.createElement(Button_Button, {
|
|
style: "primary",
|
|
url: "https://example.org",
|
|
source: "styleguide"
|
|
}, "Primary Button"), /*#__PURE__*/react.createElement("h5", {
|
|
className: "stp_styleguide_h5"
|
|
}, "secondary"), /*#__PURE__*/react.createElement(Button_Button, {
|
|
style: "secondary",
|
|
url: "https://example.org",
|
|
source: "styleguide"
|
|
}, "Secondary Button"), /*#__PURE__*/react.createElement("h5", {
|
|
className: "stp_styleguide_h5"
|
|
}, "primary wide"), /*#__PURE__*/react.createElement("span", {
|
|
className: "stp_button_wide"
|
|
}, /*#__PURE__*/react.createElement(Button_Button, {
|
|
style: "primary",
|
|
url: "https://example.org",
|
|
source: "styleguide"
|
|
}, "Primary Wide Button")), /*#__PURE__*/react.createElement("h5", {
|
|
className: "stp_styleguide_h5"
|
|
}, "secondary wide"), /*#__PURE__*/react.createElement("span", {
|
|
className: "stp_button_wide"
|
|
}, /*#__PURE__*/react.createElement(Button_Button, {
|
|
style: "secondary",
|
|
url: "https://example.org",
|
|
source: "styleguide"
|
|
}, "Secondary Wide Button")), /*#__PURE__*/react.createElement("h4", {
|
|
className: "stp_styleguide_h4"
|
|
}, "Header"), /*#__PURE__*/react.createElement(Header_Header, null, /*#__PURE__*/react.createElement(Button_Button, {
|
|
style: "primary",
|
|
url: "https://example.org",
|
|
source: "styleguide"
|
|
}, "View My List")), /*#__PURE__*/react.createElement("h4", {
|
|
className: "stp_styleguide_h4"
|
|
}, "PopularTopics"), /*#__PURE__*/react.createElement(PopularTopics_PopularTopics, {
|
|
pockethost: `getpocket.com`,
|
|
source: `styleguide`,
|
|
utmParams: `utm_source=styleguide`,
|
|
topics: [{
|
|
title: "Self Improvement",
|
|
topic: "self-improvement"
|
|
}, {
|
|
title: "Food",
|
|
topic: "food"
|
|
}, {
|
|
title: "Entertainment",
|
|
topic: "entertainment"
|
|
}, {
|
|
title: "Science",
|
|
topic: "science"
|
|
}]
|
|
}), /*#__PURE__*/react.createElement("h4", {
|
|
className: "stp_styleguide_h4"
|
|
}, "ArticleList"), /*#__PURE__*/react.createElement(ArticleList_ArticleList, {
|
|
source: `styleguide`,
|
|
articles: [{
|
|
title: "Article Title",
|
|
publisher: "Publisher",
|
|
thumbnail: "https://img-getpocket.cdn.mozilla.net/80x80/https://www.raritanheadwaters.org/wp-content/uploads/2020/04/red-fox.jpg",
|
|
url: "https://example.org",
|
|
alt: "Alt Text"
|
|
}, {
|
|
title: "Article Title (No Publisher)",
|
|
thumbnail: "https://img-getpocket.cdn.mozilla.net/80x80/https://www.raritanheadwaters.org/wp-content/uploads/2020/04/red-fox.jpg",
|
|
url: "https://example.org",
|
|
alt: "Alt Text"
|
|
}, {
|
|
title: "Article Title (No Thumbnail)",
|
|
publisher: "Publisher",
|
|
url: "https://example.org",
|
|
alt: "Alt Text"
|
|
}]
|
|
}), /*#__PURE__*/react.createElement("h4", {
|
|
className: "stp_styleguide_h4"
|
|
}, "TagPicker"), /*#__PURE__*/react.createElement(TagPicker_TagPicker, {
|
|
tags: [`futurism`, `politics`, `mozilla`]
|
|
}), /*#__PURE__*/react.createElement("h3", null, "Typography:"), /*#__PURE__*/react.createElement("h2", {
|
|
className: "header_large"
|
|
}, ".header_large"), /*#__PURE__*/react.createElement("h3", {
|
|
className: "header_medium"
|
|
}, ".header_medium"), /*#__PURE__*/react.createElement("p", null, "paragraph"), /*#__PURE__*/react.createElement("h3", null, "Native Elements:"), /*#__PURE__*/react.createElement("h4", {
|
|
className: "stp_styleguide_h4"
|
|
}, "Horizontal Rule"), /*#__PURE__*/react.createElement("hr", null)), document.querySelector(`#stp_style_guide_components`));
|
|
}
|
|
};
|
|
/* harmony default export */ const style_guide_overlay = (StyleGuideOverlay);
|
|
;// CONCATENATED MODULE: ./content/panels/js/main.mjs
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
/* global RPMGetStringPref:false */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var PKT_PANEL = function () {};
|
|
|
|
PKT_PANEL.prototype = {
|
|
initHome() {
|
|
this.overlay = new overlay();
|
|
this.init();
|
|
},
|
|
|
|
initSignup() {
|
|
this.overlay = new signup_overlay();
|
|
this.init();
|
|
},
|
|
|
|
initSaved() {
|
|
this.overlay = new saved_overlay();
|
|
this.init();
|
|
},
|
|
|
|
initStyleGuide() {
|
|
this.overlay = new style_guide_overlay();
|
|
this.init();
|
|
},
|
|
|
|
setupObservers() {
|
|
this.setupMutationObserver();
|
|
// Mutation observer isn't always enough for fast loading, static pages.
|
|
// Sometimes the mutation observer fires before the page is totally visible.
|
|
// In this case, the resize tries to fire with 0 height,
|
|
// and because it's a static page, it only does one mutation.
|
|
// So in this case, we have a backup intersection observer that fires when
|
|
// the page is first visible, and thus, the page is going to guarantee a height.
|
|
this.setupIntersectionObserver();
|
|
},
|
|
|
|
init() {
|
|
if (this.inited) {
|
|
return;
|
|
}
|
|
this.setupObservers();
|
|
this.inited = true;
|
|
},
|
|
|
|
resizeParent() {
|
|
let clientHeight = document.body.clientHeight;
|
|
if (this.overlay.tagsDropdownOpen) {
|
|
clientHeight = Math.max(clientHeight, 252);
|
|
}
|
|
|
|
// We can ignore 0 height here.
|
|
// We rely on intersection observer to do the
|
|
// resize for 0 height loads.
|
|
if (clientHeight) {
|
|
messages.sendMessage("PKT_resizePanel", {
|
|
width: document.body.clientWidth,
|
|
height: clientHeight,
|
|
});
|
|
}
|
|
},
|
|
|
|
setupIntersectionObserver() {
|
|
const observer = new IntersectionObserver(entries => {
|
|
if (entries.find(e => e.isIntersecting)) {
|
|
this.resizeParent();
|
|
observer.unobserve(document.body);
|
|
}
|
|
});
|
|
observer.observe(document.body);
|
|
},
|
|
|
|
setupMutationObserver() {
|
|
// Select the node that will be observed for mutations
|
|
const targetNode = document.body;
|
|
|
|
// Options for the observer (which mutations to observe)
|
|
const config = { attributes: false, childList: true, subtree: true };
|
|
|
|
// Callback function to execute when mutations are observed
|
|
const callback = mutationList => {
|
|
mutationList.forEach(mutation => {
|
|
switch (mutation.type) {
|
|
case "childList": {
|
|
/* One or more children have been added to and/or removed
|
|
from the tree.
|
|
(See mutation.addedNodes and mutation.removedNodes.) */
|
|
this.resizeParent();
|
|
break;
|
|
}
|
|
}
|
|
});
|
|
};
|
|
|
|
// Create an observer instance linked to the callback function
|
|
const observer = new MutationObserver(callback);
|
|
|
|
// Start observing the target node for configured mutations
|
|
observer.observe(targetNode, config);
|
|
},
|
|
|
|
create() {
|
|
const pockethost =
|
|
RPMGetStringPref("extensions.pocket.site") || "getpocket.com";
|
|
this.overlay.create({ pockethost });
|
|
},
|
|
};
|
|
|
|
window.PKT_PANEL = PKT_PANEL;
|
|
window.pktPanelMessaging = messages;
|
|
|
|
|
|
/***/ })
|
|
|
|
/******/ });
|
|
/************************************************************************/
|
|
/******/ // The module cache
|
|
/******/ var __webpack_module_cache__ = {};
|
|
/******/
|
|
/******/ // The require function
|
|
/******/ function __webpack_require__(moduleId) {
|
|
/******/ // Check if module is in cache
|
|
/******/ var cachedModule = __webpack_module_cache__[moduleId];
|
|
/******/ if (cachedModule !== undefined) {
|
|
/******/ return cachedModule.exports;
|
|
/******/ }
|
|
/******/ // Create a new module (and put it into the cache)
|
|
/******/ var module = __webpack_module_cache__[moduleId] = {
|
|
/******/ // no module.id needed
|
|
/******/ // no module.loaded needed
|
|
/******/ exports: {}
|
|
/******/ };
|
|
/******/
|
|
/******/ // Execute the module function
|
|
/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
|
|
/******/
|
|
/******/ // Return the exports of the module
|
|
/******/ return module.exports;
|
|
/******/ }
|
|
/******/
|
|
/******/ // expose the modules object (__webpack_modules__)
|
|
/******/ __webpack_require__.m = __webpack_modules__;
|
|
/******/
|
|
/************************************************************************/
|
|
/******/ /* webpack/runtime/chunk loaded */
|
|
/******/ (() => {
|
|
/******/ var deferred = [];
|
|
/******/ __webpack_require__.O = (result, chunkIds, fn, priority) => {
|
|
/******/ if(chunkIds) {
|
|
/******/ priority = priority || 0;
|
|
/******/ for(var i = deferred.length; i > 0 && deferred[i - 1][2] > priority; i--) deferred[i] = deferred[i - 1];
|
|
/******/ deferred[i] = [chunkIds, fn, priority];
|
|
/******/ return;
|
|
/******/ }
|
|
/******/ var notFulfilled = Infinity;
|
|
/******/ for (var i = 0; i < deferred.length; i++) {
|
|
/******/ var [chunkIds, fn, priority] = deferred[i];
|
|
/******/ var fulfilled = true;
|
|
/******/ for (var j = 0; j < chunkIds.length; j++) {
|
|
/******/ if ((priority & 1 === 0 || notFulfilled >= priority) && Object.keys(__webpack_require__.O).every((key) => (__webpack_require__.O[key](chunkIds[j])))) {
|
|
/******/ chunkIds.splice(j--, 1);
|
|
/******/ } else {
|
|
/******/ fulfilled = false;
|
|
/******/ if(priority < notFulfilled) notFulfilled = priority;
|
|
/******/ }
|
|
/******/ }
|
|
/******/ if(fulfilled) {
|
|
/******/ deferred.splice(i--, 1)
|
|
/******/ var r = fn();
|
|
/******/ if (r !== undefined) result = r;
|
|
/******/ }
|
|
/******/ }
|
|
/******/ return result;
|
|
/******/ };
|
|
/******/ })();
|
|
/******/
|
|
/******/ /* webpack/runtime/hasOwnProperty shorthand */
|
|
/******/ (() => {
|
|
/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
|
|
/******/ })();
|
|
/******/
|
|
/******/ /* webpack/runtime/jsonp chunk loading */
|
|
/******/ (() => {
|
|
/******/ // no baseURI
|
|
/******/
|
|
/******/ // object to store loaded and loading chunks
|
|
/******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched
|
|
/******/ // [resolve, reject, Promise] = chunk loading, 0 = chunk loaded
|
|
/******/ var installedChunks = {
|
|
/******/ 590: 0
|
|
/******/ };
|
|
/******/
|
|
/******/ // no chunk on demand loading
|
|
/******/
|
|
/******/ // no prefetching
|
|
/******/
|
|
/******/ // no preloaded
|
|
/******/
|
|
/******/ // no HMR
|
|
/******/
|
|
/******/ // no HMR manifest
|
|
/******/
|
|
/******/ __webpack_require__.O.j = (chunkId) => (installedChunks[chunkId] === 0);
|
|
/******/
|
|
/******/ // install a JSONP callback for chunk loading
|
|
/******/ var webpackJsonpCallback = (parentChunkLoadingFunction, data) => {
|
|
/******/ var [chunkIds, moreModules, runtime] = data;
|
|
/******/ // add "moreModules" to the modules object,
|
|
/******/ // then flag all "chunkIds" as loaded and fire callback
|
|
/******/ var moduleId, chunkId, i = 0;
|
|
/******/ if(chunkIds.some((id) => (installedChunks[id] !== 0))) {
|
|
/******/ for(moduleId in moreModules) {
|
|
/******/ if(__webpack_require__.o(moreModules, moduleId)) {
|
|
/******/ __webpack_require__.m[moduleId] = moreModules[moduleId];
|
|
/******/ }
|
|
/******/ }
|
|
/******/ if(runtime) var result = runtime(__webpack_require__);
|
|
/******/ }
|
|
/******/ if(parentChunkLoadingFunction) parentChunkLoadingFunction(data);
|
|
/******/ for(;i < chunkIds.length; i++) {
|
|
/******/ chunkId = chunkIds[i];
|
|
/******/ if(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) {
|
|
/******/ installedChunks[chunkId][0]();
|
|
/******/ }
|
|
/******/ installedChunks[chunkId] = 0;
|
|
/******/ }
|
|
/******/ return __webpack_require__.O(result);
|
|
/******/ }
|
|
/******/
|
|
/******/ var chunkLoadingGlobal = self["webpackChunksave_to_pocket_ff"] = self["webpackChunksave_to_pocket_ff"] || [];
|
|
/******/ chunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0));
|
|
/******/ chunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal));
|
|
/******/ })();
|
|
/******/
|
|
/************************************************************************/
|
|
/******/
|
|
/******/ // startup
|
|
/******/ // Load entry module and return exports
|
|
/******/ // This entry module depends on other loaded chunks and execution need to be delayed
|
|
/******/ var __webpack_exports__ = __webpack_require__.O(undefined, [968], () => (__webpack_require__(720)))
|
|
/******/ __webpack_exports__ = __webpack_require__.O(__webpack_exports__);
|
|
/******/
|
|
/******/ })()
|
|
; |