Skip to content

Commit

Permalink
[:sparkles: FEATURE] Implement site-specific selector blacklist
Browse files Browse the repository at this point in the history
Fixes #10
  • Loading branch information
tomlutzenberger committed Oct 20, 2017
1 parent b7a2b29 commit 968992f
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 22 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "reading-duration-bookmarklet",
"version": "0.1.6",
"version": "0.1.7",
"description": "Dynamic Bookmarklet to detect the reading time of an article",
"main": "readingDurationBookmarklet.js",
"scripts": {
Expand Down
49 changes: 29 additions & 20 deletions readingDurationBookmarklet.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,11 @@ const readingDurationBookmarklet = () => {
const SEC_PER_HOUR = 3600;
const TWO_DIGIT_SEC = 10;

const defaultSite = { name: 'default', selector: ['article', '.article', '#article', '.post'] };
const defaultSite = {
name: 'default',
selector: ['article', '.article', '#article', '.post'],
elementBlacklist: []
};



Expand All @@ -39,22 +43,24 @@ const readingDurationBookmarklet = () => {
const getSite = () => {
return [{
name: 'dev.to',
selector: '#article-body'
selector: '#article-body',
elementBlacklist: []
}, {
name: 'medium.com',
selector: '.section-content'
selector: '.section-content',
elementBlacklist: ['.graf--trailing']
}];
};



/**
* @method getIgnoredTags
* @method getGlobalElementBlacklist
* @description Get an array with all elements that should be ignored (stripped) from content
*
* @returns {String[]}
*/
const getIgnoredTags = () => {
const getGlobalElementBlacklist = () => {
return [
'audio',
'aside',
Expand Down Expand Up @@ -119,14 +125,14 @@ const readingDurationBookmarklet = () => {
do { // Loop through selector fallbacks until an element is found
article = document.querySelector(selector[index]);
index++;
} while(article !== null && index < selector.length);
} while(article === null && index < selector.length);

} else {
article = document.querySelector(selector);
}

if (article !== null) {
return cleanupContent(stripIgnoredTags(article.cloneNode(true)));
return article.cloneNode(true);
}

return false;
Expand All @@ -135,23 +141,24 @@ const readingDurationBookmarklet = () => {


/**
* @method stripIgnoredTags
* @description Strip all ignored tags from content
* @method stripBlacklistedElements
* @description Strip all blacklisted elements from content
*
* @param {Element} content - (DOM-)Element with all the content
* @param {Element} contentNode - (DOM-)Element with all the content
* @param {Array} siteBlacklist - Array of site-specific blacklisted elements
* @returns {Element}
*/
const stripIgnoredTags = (content) => {
const tagSelectorList = getIgnoredTags().join(',');
const nodeList = content.querySelectorAll(tagSelectorList);
const stripBlacklistedElements = (contentNode, siteBlacklist) => {
let elementBlacklist = getGlobalElementBlacklist().concat(siteBlacklist);
const nodeList = contentNode.querySelectorAll(elementBlacklist.join(','));

if (nodeList.length > ZERO) {
nodeList.forEach((nodeElement) => {
nodeElement.remove();
});
}

return content;
return contentNode;
};


Expand All @@ -160,11 +167,11 @@ const readingDurationBookmarklet = () => {
* @method cleanupContent
* @description Remove all unnecessary whitespaces and HTML tags and return plain text
*
* @param {Element} content - (DOM-)Element with all the content
* @param {Element} contentNode - (DOM-)Element with all the content
* @returns {String}
*/
const cleanupContent = (content) => {
let cleanedContent = content.textContent.trim();
const cleanupContent = (contentNode) => {
let cleanedContent = contentNode.textContent.trim();
cleanedContent = cleanedContent.replace(/[^\w\s./-]/g, ' ');
cleanedContent = cleanedContent.replace(/\s+/g, ' ');

Expand Down Expand Up @@ -234,13 +241,15 @@ const readingDurationBookmarklet = () => {
*/
const execute = () => {
const site = detectSite();
const article = getArticleContent(site.selector);
const articleNode = getArticleContent(site.selector);
let articleContent = '';
let message = '';

if(!article) {
if(!articleNode) {
message = 'Article has not been found. Sorry!';
} else {
message = `${countWords(article)} Words, ${calculateReadDuration(article)}`;
articleContent = cleanupContent(stripBlacklistedElements(articleNode, site.elementBlacklist));
message = `${countWords(articleContent)} Words ${calculateReadDuration(articleContent)}`;
}

alert(message);
Expand Down
2 changes: 1 addition & 1 deletion readingDurationBookmarklet.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 968992f

Please sign in to comment.