Skip to content

Commit

Permalink
closes #8
Browse files Browse the repository at this point in the history
  • Loading branch information
bunglegrind committed Dec 8, 2024
1 parent c6b9125 commit 661a9d5
Show file tree
Hide file tree
Showing 6 changed files with 5,531 additions and 118 deletions.
45 changes: 10 additions & 35 deletions web-extension/background.js
Original file line number Diff line number Diff line change
@@ -1,32 +1,3 @@

///////////////////
///////////////////
///////////////////
///////////////////
/// Only for testing

chrome.runtime.onInstalled.addListener(details => {
if (navigator.userAgent === 'PuppeteerTestingAgent') {
let TEST_TIMER = null
chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
if (TEST_TIMER) {
clearTimeout(TEST_TIMER)
}

TEST_TIMER = setTimeout(()=> {
executeCommand({type: 'save-page'})
}, 2000)
});
}
});



///////////////////
///////////////////
///////////////////
///////////////////

var isBusy = false;
var busyResetTimer = null

Expand Down Expand Up @@ -149,8 +120,12 @@ display: none;

];

chrome.commands.onCommand.addListener((command) => {
executeCommand({type: command})
chrome.commands.onCommand.addListener(function (command) {
fetch(chrome.runtime.getURL("./libs/aboutReader.css")).then(
(d) => d.text()
).then(function (css) {
executeCommand({type: command, readerCss: css})
});
});

function executeCommand(command) {
Expand All @@ -166,13 +141,13 @@ function executeCommand(command) {
return;
}
if (command.type === 'save-page') {
dispatch('extract-page', false, []);
dispatch('extract-page', false, [command.readerCss]);
} else if (command.type === 'save-selection') {
dispatch('extract-selection', false, []);
dispatch('extract-selection', false, [command.readerCss]);
} else if (command.type === 'add-page') {
dispatch('extract-page', true, []);
dispatch('extract-page', true, [command.readerCss]);
} else if (command.type === 'add-selection') {
dispatch('extract-selection', true, []);
dispatch('extract-selection', true, [command.readerCss]);
}

isBusy = true
Expand Down
174 changes: 92 additions & 82 deletions web-extension/extractHtml.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,17 @@ var webComponents = [
"readme-toc"
];

function makeHeader(article) {
const div = document.createElement("div");
const h1 = document.createElement("h1");
div.className = "header reader-header reader-show-element";
h1.className = "reader-title";
h1.append(article.title);
div.append(h1);

return div;
}

function getImageSrc(srcTxt) {
if (!srcTxt) {
return '';
Expand Down Expand Up @@ -256,94 +267,73 @@ function isVisible(elem) {
);
}

function extractCss(includeStyle, appliedStyles) {
if (includeStyle) {
document.querySelectorAll("body *").forEach(function (pre, i) {
if (
allowedTags.indexOf(pre.tagName.toLowerCase()) < 0
|| mathMLTags.indexOf(pre.tagName.toLowerCase()) > -1
) {
return;
}

if (!isVisible(pre)) {
//Workaround: I think I should clone the visible nodes in a new DOM-like structure
pre.innerHTML = "";
} else {
if (pre.tagName.toLowerCase() === "svg") return;

const elementId = pre.tagName + "-" + generateRandomNumber(true);
let tmpName = generateRandomTag(2) + i;
cssClassesToTmpIds[elementId] = tmpName;
const tmpNewCss = {};
const styles = window.getComputedStyle(pre);

for (let cssTagName of supportedCss.concat(inheritedCss)) {
let cssValue = styles.getPropertyValue(cssTagName);
if (cssValue && cssValue.length > 0) {
if (cssTagName === "font-size") {
const parentFontSize = parseInt(getComputedStyle(pre.parentElement).getPropertyValue("font-size"));
if (parentFontSize > 0) {
cssValue = (parseInt(cssValue)/parentFontSize).toFixed(1) + "em";
}
}
if (cssTagName === "line-height") {
const fontSize = parseInt(styles.getPropertyValue("font-size"));
const numCssValue = parseInt(cssValue);
if (numCssValue > 0) {
cssValue = (numCssValue / fontSize).toFixed(1);
}
}
if (["margin-left", "margin-right"].includes(cssTagName)) {
const parentWidth = parseInt(getComputedStyle(pre.parentElement).getPropertyValue("width"));
if (parentWidth > 0) {
cssValue = (100 * parseInt(cssValue)/parentWidth).toFixed(0) + "%";
}
}
tmpNewCss[cssTagName] = cssValue;
function extractCss() {
document.querySelectorAll("body *").forEach(function (pre, i) {
if (
allowedTags.indexOf(pre.tagName.toLowerCase()) < 0
|| mathMLTags.indexOf(pre.tagName.toLowerCase()) > -1
) {
return;
}
if (pre.tagName.toLowerCase() === "svg") return;

const elementId = pre.tagName + "-" + generateRandomNumber(true);
let tmpName = generateRandomTag(2) + i;
cssClassesToTmpIds[elementId] = tmpName;
const tmpNewCss = {};
const styles = window.getComputedStyle(pre);

for (let cssTagName of supportedCss.concat(inheritedCss)) {
let cssValue = styles.getPropertyValue(cssTagName);
if (cssValue && cssValue.length > 0) {
if (cssTagName === "font-size") {
const parentFontSize = parseInt(getComputedStyle(pre.parentElement).getPropertyValue("font-size"));
if (parentFontSize > 0) {
cssValue = (parseInt(cssValue)/parentFontSize).toFixed(1) + "em";
}
}

// Reuse CSS - if the same css code was generated for another element, reuse it's class name
let tcss = JSON.stringify(tmpNewCss)
let found = false

if (Object.keys(tmpIdsToNewCssSTRING).length === 0) {
tmpIdsToNewCssSTRING[tmpName] = tcss;
tmpIdsToNewCss[tmpName] = tmpNewCss;
} else {
for (const key in tmpIdsToNewCssSTRING) {
if (tmpIdsToNewCssSTRING[key] === tcss) {
tmpName = key
found = true
break
}
if (cssTagName === "line-height") {
const fontSize = parseInt(styles.getPropertyValue("font-size"));
const numCssValue = parseInt(cssValue);
if (numCssValue > 0) {
cssValue = (numCssValue / fontSize).toFixed(1);
}
if (!found) {
tmpIdsToNewCssSTRING[tmpName] = tcss;
tmpIdsToNewCss[tmpName] = tmpNewCss;
}
if (["margin-left", "margin-right"].includes(cssTagName)) {
const parentWidth = parseInt(getComputedStyle(pre.parentElement).getPropertyValue("width"));
if (parentWidth > 0) {
cssValue = (100 * parseInt(cssValue)/parentWidth).toFixed(0) + "%";
}
}
pre.setAttribute('data-class', tmpName);
tmpNewCss[cssTagName] = cssValue;
}
});
return jsonToCss(tmpIdsToNewCss);
} else {
// remove hidden elements when style is not included
document.querySelectorAll("body *").forEach(function ( pre) {
if (!isVisible(pre)) {
pre.outerHTML = "";
}

// Reuse CSS - if the same css code was generated for another element, reuse it's class name
let tcss = JSON.stringify(tmpNewCss)
let found = false

if (Object.keys(tmpIdsToNewCssSTRING).length === 0) {
tmpIdsToNewCssSTRING[tmpName] = tcss;
tmpIdsToNewCss[tmpName] = tmpNewCss;
} else {
for (const key in tmpIdsToNewCssSTRING) {
if (tmpIdsToNewCssSTRING[key] === tcss) {
tmpName = key
found = true
break
}
}
});
let mergedCss = "";
if (appliedStyles && appliedStyles.length > 0) {
for (let i = 0; i < appliedStyles.length; i++) {
mergedCss += appliedStyles[i].style;
if (!found) {
tmpIdsToNewCssSTRING[tmpName] = tcss;
tmpIdsToNewCss[tmpName] = tmpNewCss;
}
return mergedCss;
}
}
return null;
pre.setAttribute('data-class', tmpName);

});

return jsonToCss(tmpIdsToNewCss);
}

/////
Expand Down Expand Up @@ -473,15 +463,35 @@ chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
}
let imgsPromises = [];
let result = {};
let styleFile = null;
const content = document.createElement("div");

extractIFrames(Array.from(document.querySelectorAll("iframe")));

document.querySelectorAll("body *").forEach(function (pre) {
if (!isVisible(pre)) {

// Workaround: I think I should clone the visible nodes in a new DOM-like structure

pre.outerHTML = "";
}
});

//extract style and add data-class to every relevant node
styleFile = extractCss(request.includeStyle, request.appliedStyles);
const styleFile = (
request.includeStyle
? extractCss()
: request.appliedStyles[0]
);
if (request.type === "extract-page") {
Array.from(document.body.children).forEach((el) => content.appendChild(el.cloneNode(true)));
if (!request.includeStyle) {
const article = new Readability(document).parse();
const header = makeHeader(article);
content.innerHTML = header.outerHTML + DOMPurify.sanitize(article.content);
} else {
Array.from(document.body.children).forEach(
(el) => content.appendChild(el.cloneNode(true))
);
}
} else if (request.type === "extract-selection") {
getSelectedNodes().forEach((fg) => content.appendChild(fg.cloneNode(true)));
}
Expand Down
Loading

0 comments on commit 661a9d5

Please sign in to comment.