HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptMinor

Chrome extension that marks Reddit entries with clickbait sources

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
clickbaitwithextensionchromethatmarksredditsourcesentries

Problem

So, I've created my first Chrome extension! What this does is it highlights every post on Reddit that comes from a source of dubious quality. It provides a few sources by default and allows the user to add or remove from this list. The user also has the choice between either highlighting the offending post or hiding it altogether.

All settings are stored in sync storage which allows them to be used across chrome instances.

Project site: https://github.com/Vannevelj/RedditCrap

Chrome Store: https://chrome.google.com/webstore/detail/redditcrap/kkbdfmnmdigakifakfglcokgohgolgan

Yes, it looks ugly. I take PRs.

redditcrap.js Github

```
// Register an event listener to check for crap when the stored sites change
chrome.storage.onChanged.addListener(function(changes, area) {
checkCrap();
})

// Finds all the appropriate domains in the DOM, checks whether they're blacklisted and acts accordingly
function checkCrap() {
var domains = document.getElementsByClassName('domain');
chrome.storage.sync.get(['crappySites', 'crappyAction'], function(data) {
for (var i = 0; i -1;
if (shouldBeColoured) {
if (data.crappyAction === 1) {
parentNode.style.backgroundColor = 'red';
}

if (data.crappyAction === 2) {
entryNode.style.display = 'none';
}

break;
}
}
}
});
}

function getParentByClass(currentNode, className) {
while (currentNode = currentNode.parentElement) {
if (currentNode.classList.contains(className)) {
return currentNode;
}
}
}

function getThingNode(parentNode) {
while (parentNode = parentNode.parentElement) {
if (parentNode.getAttribute('data-fullname')) {
return parentNode;
}
}
}

// In this section we perform crapchecks when the page has changed
// This is important in the ca

Solution

var domains = document.getElementsByClassName('domain');
for (var i = 0; i < domains.length; i++) {


You can covert document.get* results into real arrays by using array.slice. That way, you can take advantage of the handy array methods like forEach.

if (data.crappyAction === 1) {


1 and crappyAction doesn't really tell me anything about what the code block does. Suggesting you put 1 in a variable that is appropriately named (like DESIRED_ACTION_HIGHLIGHT and crappyAction (no matter how thematic the name is) be renamed to something more meaningful, like desiredAction.

The entire checkCrap operation could be simplified into something like this:

chrome.storage.sync.get(['crappySites', 'crappyAction'], flaggedDomains => {

  var domains = document.getElementsByClassName('domain');
  var domainElements = Array.prototype.slice(domains);

  domainElements.map(domainElement => ({

    // For each domain element, we grab essential data about it
    element: domainElement,
    url: getUrl(domainElement),
    parent: getParent(domainElement),
    otherStuff: getOtherStuff(domainElement),
    // and so on

  })).filter(domainData => {

    // Then we filter only those that are flagged
    return flaggedDomains.indexOf(domainData.url) > -1;

  }).forEach(domainData => {

    // What remains that run here are domains that match your list

  });
});


As for your element climbers, they can be simplified using recursion. getThingNode needs a better name.

function getParentByClass(currentNode, className) {
  return currentNode.classList.contains(className) ? currentNode : getParentByClass(currentNode.parent, title);
}

function getThingNode(parentNode) {
  return parentNode.getAttribute('data-fullname') ? parentNode : getThingNode(parentNode.parentElement);
}


To avoid having to loop through domains that already have been marked, suggesting you add an indicator that they have already been processed.

// Get all unprocessed domains
var domains = document.querySelectorAll('domain:not(.crap-processed)');


Adding a class can be one way to do it. In this case, let's use crap-processed You can then use querySelectorAll and the :not pseudo-class to get unprocessed domains.

var newSites = [];
for (var i = 0; i < sites.length; i++) {
    if (sites[i] !== value) {
        newSites.push(sites[i]);
    }
}


Can be simplified into:

var newSites = sites.filter(site => site !== value);

Code Snippets

var domains = document.getElementsByClassName('domain');
for (var i = 0; i < domains.length; i++) {
if (data.crappyAction === 1) {
chrome.storage.sync.get(['crappySites', 'crappyAction'], flaggedDomains => {

  var domains = document.getElementsByClassName('domain');
  var domainElements = Array.prototype.slice(domains);

  domainElements.map(domainElement => ({

    // For each domain element, we grab essential data about it
    element: domainElement,
    url: getUrl(domainElement),
    parent: getParent(domainElement),
    otherStuff: getOtherStuff(domainElement),
    // and so on

  })).filter(domainData => {

    // Then we filter only those that are flagged
    return flaggedDomains.indexOf(domainData.url) > -1;

  }).forEach(domainData => {

    // What remains that run here are domains that match your list

  });
});
function getParentByClass(currentNode, className) {
  return currentNode.classList.contains(className) ? currentNode : getParentByClass(currentNode.parent, title);
}

function getThingNode(parentNode) {
  return parentNode.getAttribute('data-fullname') ? parentNode : getThingNode(parentNode.parentElement);
}
// Get all unprocessed domains
var domains = document.querySelectorAll('domain:not(.crap-processed)');

Context

StackExchange Code Review Q#122502, answer score: 3

Revisions (0)

No revisions yet.