A Weird Imagination

Working around a broken ad-block block

The problem#

Slashdot recently made a change to their ad code that made the site completely fail to load for me, showing the message

Failed to load website properly since html-load.com is blocked. Please allow html-load.com

and then blaming ad blocking:

This page could not be loaded properly due to incorrect / bad filtering rule(s) of adblockers in use. Please disable all adblockers to continue using the website. (click OK if you'd like to learn more)

I could see the page loaded just fine behind those messages, so it was obviously a lie. But the page continually reloaded if I tried to dismiss those pop-ups, so the site was unusable.

(Actually, this appears to have been disabled in the time it took me to write this blog post, so I guess this is no longer needed. Although it may be applicable to other websites using the same or similar mechanisms.)

The solution#

Install this user script. I have only tested it with Greasemonkey on Firefox so it require modification to work on other user script managers or browsers.

The details#

Read more…

Monkey patching async functions in user scripts

The problem#

I was writing a user script where I wanted to be able to intercept the fetch() calls the web page made so my script could use the contents. I found a suggestion of simply reassigning window.fetch to my own function that internally called the real window.fetch while also doing whatever else I wanted. While it worked fine under Tampermonkey on Chromium, under Greasemonkey on Firefox, the script would just silently fail with no indication of why the code wasn't running.

(The script I was writing was this one for fixing the formatting on the Folklife 2024 schedule to reformat the schedule to display as a grid. I plan to write a devlog post on it in the future, but just writing about the most pernicious issue in this post.)

The solution#

The problem was that Firefox's security model special-cases function calls between web pages and extensions (and user scripts running inside Greasemonkey count as part of an extension for this purpose). And, furthermore, Promises can't pass the boundary, so you need to carefully define functions such that the implicit Promise created by declaring the function async lives on the right side of the boundary.

The following code combines all of that together to intercept fetch() on both Firefox and Chromium such that a userscript function intercept is called with the text of the response to every fetch():

const intercept = responseText => {
  // use responseText somehow ...
};

const w = window.wrappedJSObject;
if (w) {
  exportFunction(intercept, window,
                 { defineAs: "extIntercept" });
  w.eval("window.origFetch = window.fetch");

  w.eval(`window.fetch = ${async (...args) => {
    let [resource, config] = args;
    const response = await window.origFetch(resource,config);
    window.extIntercept(await response.clone().text())
    return response;
  }}`);
} else {
  const { fetch: origFetch } = window;

  window.fetch = async (...args) => {
    let [resource, config] = args;
    const response = await origFetch(resource, config);
    intercept(await response.clone().text());
    return response;
  };
}

The details#

Read more…

Relative links in feeds

The problem#

In an RSS/Atom feed, relative links are a bad idea because it's unclear what they're relative to. There are ways to specify a base for them to be relative to, but since feed readers do not consistently respect those mechanisms, it's safer to just always use absolute URLs in feeds. And Pelican recommends setting RELATIVE_URLS = False to always generate absolute URLs. But that setting does not apply to the anchor links generated by the Markdown toc extension to link to headers.

The solution#

I wrote a Pelican plugin, absolute_anchors which rewrites all link destinations starting with # in every article to add the absolute URL of the article at the beginning of the link.

The details#

Read more…

My first Pelican plugin

The problem#

My previous blog post has a footnote in the first sentence. Due to the way footnotes are handled, the footnote reference is a link to #fn:prg, which works fine if the footnote is actually on the page, but on the blog main page (or any other listing of multiple articles) the footnote is not present because it's after the Read more… link. The result is that on those pages, all footnote references are broken links. These broken links should either be repaired such that they point to the article page or removed.

First attempt#

Unable to find an existing solution, I decided to write my own plugin, summary_footnotes. I started by finding another plugin, clean_summary that modifies summary and based my code off of it. That plugin uses Beautiful Soup to parse the summary and rewrite it. A quick look at the docs and I was able to figure out how to select the footnote links and rewrite them, which got me this version of the plugin.

Read more…