aboutsummaryrefslogtreecommitdiff
path: root/p/scripts/main.js
diff options
context:
space:
mode:
Diffstat (limited to 'p/scripts/main.js')
-rw-r--r--p/scripts/main.js88
1 files changed, 75 insertions, 13 deletions
diff --git a/p/scripts/main.js b/p/scripts/main.js
index d1752624e..1e35c84fa 100644
--- a/p/scripts/main.js
+++ b/p/scripts/main.js
@@ -37,6 +37,7 @@ function xmlHttpRequestJson(req) {
// <Global context>
/* eslint-disable no-var */
var context;
+var prevTitle;
/* eslint-enable no-var */
(function parseJsonVars() {
@@ -155,9 +156,10 @@ function incUnreadsFeed(article, feed_id, nb) {
}
}
- let isCurrentView = false;
// Update unread: title
- document.title = document.title.replace(/^((?:\([\s0-9]+\) )?)/, function (m, p1) {
+ let isCurrentView = false;
+ const currentTitle = prevTitle || document.title;
+ const newTitle = currentTitle.replace(/^((?:\([\s0-9]+\) )?)/, function (m, p1) {
const feed = document.getElementById(feed_id);
if (article || (feed && feed.closest('.active'))) {
isCurrentView = true;
@@ -169,6 +171,11 @@ function incUnreadsFeed(article, feed_id, nb) {
return p1;
}
});
+ if (prevTitle) {
+ prevTitle = newTitle;
+ } else {
+ document.title = newTitle;
+ }
return isCurrentView;
}
@@ -1235,24 +1242,79 @@ function init_stream(stream) {
el = ev.target.closest('.item.share > button[data-type="print"]');
if (el) { // Print
- const tmp_window = window.open();
- for (let i = 0; i < document.styleSheets.length; i++) {
- tmp_window.document.writeln('<link href="' + document.styleSheets[i].href + '" rel="stylesheet" type="text/css" />');
- }
+ const html = document.documentElement;
+ const head = document.head.cloneNode(true);
+ head.querySelectorAll('script').forEach(js => js.remove());
+
const flux_content = el.closest('.flux_content');
let content_el = null;
if (flux_content) {
- content_el = el.closest('.flux_content').querySelector('.content');
+ content_el = el.closest('.flux_content').querySelector('.content').cloneNode(true);
}
if (content_el === null) {
- content_el = el.closest('.flux').querySelector('.flux_content .content');
+ content_el = el.closest('.flux').querySelector('.flux_content .content').cloneNode(true);
}
+
+ content_el.querySelectorAll('a').forEach(link => {
+ // Avoid leaking the instance URL in PDFs
+ if (link.href.startsWith(location.origin)) {
+ link.removeAttribute('href');
+ }
+ });
+
+ content_el.querySelectorAll('details').forEach(el => el.setAttribute('open', 'open'));
+
+ const articleTitle = content_el.querySelector('.title a').innerText;
+ prevTitle = document.title;
+
+ // Chrome uses the parent's title to get the PDF save filename
+ document.title = articleTitle;
+
+ // Firefox uses the iframe's title to get the PDF save filename
+ // Note: Firefox Mobile saves PDFs with a filename that looks like: `temp[19 random digits].PDF` regardless of title
+ head.querySelector('title').innerText = articleTitle;
+
loadLazyImages(content_el);
- tmp_window.document.writeln(content_el.innerHTML);
- tmp_window.document.close();
- tmp_window.focus();
- tmp_window.print();
- tmp_window.close();
+
+ const print_frame = document.createElement('iframe');
+ print_frame.style.display = 'none';
+ print_frame.srcdoc = `
+ <!DOCTYPE html>
+ <html class="${html.getAttribute('class')}">
+ <head>
+ ${head.innerHTML}
+ </head>
+ <body>
+ ${content_el.outerHTML}
+ </body>
+ </html>
+ `;
+ document.body.prepend(print_frame);
+
+ function afterPrint() {
+ print_frame.remove();
+ document.title = prevTitle;
+ prevTitle = '';
+
+ window.removeEventListener('focus', afterPrint);
+ }
+
+ print_frame.onload = () => {
+ const tmp_window = print_frame.contentWindow;
+
+ // Needed for Chrome
+ tmp_window.matchMedia('print').onchange = (e) => {
+ // UA check is needed to not trigger on Chrome Mobile
+ if (!e.matches && !navigator.userAgent.includes('Mobi')) {
+ afterPrint();
+ }
+ };
+ tmp_window.print();
+ };
+
+ // Needed for Firefox and Chrome Mobile
+ window.addEventListener('focus', afterPrint);
+
return false;
}