1
\$\begingroup\$

I have written the following JavaScript small script to do three things in a web browser:

  • Block all or most News websites (send your browser to google.com instead)
  • Block automatic playing of any video (use another browser to play the video)
  • Block specific websites (send your browser to google.com instead)

The axioms for creating this script are that many websites, especially news websites, can damage mental health at least of people addictive to them and that automatic playing of videos is problematic as it manipulates the mind of the user to concentrate in something that may be totally not on his agenda or control.

The script worked for me in Chrome 114.0.

The script contains the Hebrew words חדשות and החדשות which mean "news" and "the news" respectively.

How will you review this script?

// ==UserScript==
// @name        digital_wellbeing
// @run-at      document-start
// @match       *://*/*
// ==/UserScript==

//
// Block news websites as much as possible
//

if (
  document.querySelector('title')?.textContent.includes('News') ||
  document.querySelector('title')?.textContent.includes('news') ||
  document.querySelector('meta[name="title"]')?.content.includes('News') ||
  document.querySelector('meta[name="title"]')?.content.includes('news') ||
  document.querySelector('meta[name="description"]')?.content.includes('News') ||
  document.querySelector('meta[name="description"]')?.content.includes('news') ||
  document.querySelector('meta[name="tags"]')?.content.includes('News') ||
  document.querySelector('meta[name="tags"]')?.content.includes('news') ||
  document.querySelector('meta[name="title"]')?.content.includes('חדשות') ||
  document.querySelector('meta[name="title"]')?.content.includes('החדשות') ||
  document.querySelector('meta[name="description"]')?.content.includes('חדשות') ||
  document.querySelector('meta[name="description"]')?.content.includes('החדשות') ||
  document.querySelector('meta[name="tags"]')?.content.includes('חדשות') ||
  document.querySelector('meta[name="tags"]')?.content.includes('החדשות')
) {
  window.open("https://google.com/", "_self");
}

//
// Block videos autoplay
//

window.setInterval( () => {
  document.querySelectorAll('video').forEach(anyVideo => {
    anyVideo.pause();
  });
}, 1);

//
// Block specific website/s
//

window.setInterval( () => {
    const urlPatternToBlock = [
        'WEBSITE_URL'
    ];

    for (const element of urlPatternToBlock) {
        if (window.location.href.includes(urlPatternToBlock)) {
        window.open("https://google.com/", "_self");
        }
    }
}, 1);
\$\endgroup\$
5
  • 3
    \$\begingroup\$ Your snippet doesn't disable autoplay, it instead pauses every video on the DOM every 1ms. \$\endgroup\$ Commented Jun 15, 2023 at 19:31
  • \$\begingroup\$ You're duplicating multiple calls to the DOM, i.e. where you check the title, description, and tags. \$\endgroup\$ Commented Jun 15, 2023 at 19:38
  • \$\begingroup\$ @AriaHarper isn't that the only way to block video autoplay? I don't know any other solution. \$\endgroup\$
    – somo
    Commented Jun 16, 2023 at 1:48
  • \$\begingroup\$ Since your script runs a thousand times PER SECOND it has the potential to also open new windows thousands of times :). If you want to keep checking if new video elements were added to the DOM you could use the developer.mozilla.org/en-US/docs/Web/API/MutationObserver \$\endgroup\$
    – Kokodoko
    Commented Jun 19, 2023 at 8:28
  • \$\begingroup\$ Just a quick note that it seems some browsers have disabling autoplay in their settings; in Safari, for example, you can find the option in "Web sites" -tab. With some cursory testing, however, it didn't seem to work consistently in Instagram. \$\endgroup\$
    – morbusg
    Commented Aug 27, 2023 at 18:36

1 Answer 1

1
\$\begingroup\$

If and when new keywords to check for get added, your code becomes more and more unwieldy---which is probably what prompted you to ask this question.

When manually doing the same thing over and over again, it's usually a good idea to separate the changing parts from the static parts, and put the former into a data structure such as an array.

A source of further repetition comes from case-sensitivity handling. There are some options to alleviate those, such as using regular expressions, or CSS selectors.

An example rewrite containing examples of the above points (I haven't tested these):

const metas = ["title", "description", "tags"]
const keywords = ["news", "חדשות", "החדשות"]

const selectorList = metas.reduce((acc, meta) => {
  keywords.forEach(keyword =>
    acc.push(`meta[name="${meta}" content~="${keyword}" i]`))
  return acc
}, [])

if (document.head.querySelector(selectorList.toString())
    || document.title.match(/\bnews\b/i)) {
  // ...
}
\$\endgroup\$
3
  • \$\begingroup\$ Hi and thanks! I have tested the last part of the code on dailymotion.com --- it didn't work. I got Failed to execute 'querySelectorAll' on 'Document': ':playing' is not a valid selector. Besides that I actually do want to repetitively block any video from being played in case it was loaded after a timeout or after scrolling down event etc. \$\endgroup\$
    – somo
    Commented Jun 16, 2023 at 17:03
  • \$\begingroup\$ @somo was missing a star, fixed. I see now the rationale behind the setInterval, but still it feels a little... harsh tool for the job. \$\endgroup\$
    – morbusg
    Commented Jun 16, 2023 at 17:24
  • \$\begingroup\$ I have double tested the new code with the star but videos are still being played in dailymotion.com. With the harshness of algorithems nowdays, at least for myself I feel that I must be harsh :) \$\endgroup\$
    – somo
    Commented Jun 16, 2023 at 20:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.