GlimmerBlocker Logo


HTTP based ad blocker for Mac OS X

No hacks, no instability
Upgrade Safari whenever you like, no need to wait for an upgraded hack

GlimmerBlocker is no longer maintained and should no longer be used as web sites have migrated from using plain http to using https (i.e. encrypted) which prohibits modification by a proxy unless you resort to install custom SSL certiticates on the client.

You should use a browser extension instead.

It was made as a hobby project during 2007-2008 by Peter Speck. It features both a custom http server and http client and a Mac OS X control panel.

GlimmerBlocker did not only block requests but also allowed for adding custom css and javascript to the pages. It also allowed for modification of the page html before the browser receives the html, which made some modifications much easier than DOM based modifications.

This page is for old versions of GlimmerBlocker

Please go to the main page and install the latest version.

The current version of this page is Transformations.


The transform javascript is executed by GlimmerBlocker and not by Safari. The script is never sent to Safari but only the result of running the script inside the GlimmerBlocker proxy.

How the transformation works:

  1. GlimmerBlocker retrieves the html document from the server.
  2. The html is stored as a simple string in the global variable t.
  3. The transform script is executed. The script should modify the global variable to its liking by e.g. removing all <script> elements.
  4. The updated value of the t variable extracted and used for the following steps.
  5. Any css/js from the css/js tabs are added.
  6. GlimmerBlocker sends the result to Safari.

Please look at the html samples. Please look at the feedburner rule for an xml example.

To make detecting errors in transformation Javascripts much faster check the "Show transform javascript errors" option in the advanced/debugging section.

Global utility functions

replace(/regexp/, "some text");
// is a shorthand for:
t = t.replace(/regexp/, "some text");

Utility functions in the gb object

// removes all <script>..</script> elements from t.

// removes all <style>..</style> elements from t.

// removes all <iframe>..</iframe> elements from t.

// Adds a <script>contents</script> element in t just before the </body> tag
// (i.e. end of document).

// Adds a <style>contents</style> element in t just before the </head> tag
// (i.e. end of header so it overrides loaded stylesheets).

// Updates the <title>...</title> element with the new text.
// The argument is automatically html-encoded,
// so you don't need to care about <, > and &.

gb.log("I had %d birds and a %s dog", 42, "black");
// Logging to the console (use the "Open Log" button on the advanced tab).
// The first parameter is a format string just like console.log() in Firebug:
//   %s: string
//   %d: decimal (no formatting yet)
//   %f: floating point (no formatting yet)

var html = gb.htmlEncode("Paul & Allan. 1 < 2");
// Encodes some text as html. The example returns "Paul &amp; Allan. 1 &lt; 2"

var js = gb.jsEncode(s);
// encode a string to be a Javascript string token:
// gb. jsEncode(null) -> "null"
// gb. jsEncode("Hello, D'Angleterre") -> "'Hello, D\x27Angleterre'"
//           OBS: the result includes single quotes.

var ss = gb.urlEncode(s);
// encode a string with %-escapes.  Similar to escape() and encodeURIComponent() in browsers.
// gb.urlEncode("Hello, D'Angleterre") -> "Hello%2C%20D%27Angleterre"

// Inserts the contents just after the <head> tag.
// Useful for adding <meta..> tags.

// Inserts the contents just before the </head> tag.
// Useful for adding external stylesheets, scripts, etc.

// Inserts the contents just before the </body> tag.
// Useful for adding external scripts, etc.

var hostPrefix = gb.attachmentDownloadHostPrefix();
// returns a "download as attachment" servlet prefix.
// The servlet takes two parameters:
//   1) url:  the absolute URL of the file to download.
//   2) filename: the filename which Safari should use.
// The servlet fetches the content at the URL and forwards it to Safari, but adds
//  a "content-disposition" header so the file always is downloaded as an attachment.
// The servlet checks the content-type header sent by the server and changes the filename to match it.
// The reason for using a host prefix instead of a static domain such as 'glimmerblocker.test' is
// to have Safari send the cookies for the download domain.
// See YouTube download filter for example.
a.href = "http://" + hostPrefix + "" +
  "?url=" + escape("") +
  "&filename=" + escape("weird-movie.suffix");
// The prefix is unique for each GlimmerBlocker installation.

Global variables

The content is stored in the global variable t. The name is as short as possible to unweildly long lines.

GlimmerBlocker provides utility functions and information in the global gb variable.

Other considerations

Each rule uses its own global scope in Javascript, so a script is not able to see nor modify variables used by other rules. For performance reasons the last 25 executed scripts are cached: the compiled version of the script and the its scope (i.e. global variables). There is no support for persistence or network operations whatsoever.

GlimmerBlocker uses the Rhino Javascript runtime with the language level set to 1.7

The detailed execution steps are:

  1. GlimmerBlocker retrieves the html/css/xml document from the server.
  2. For each matching rule, it performs:
    1. The html/css/xml is stored as a simple string in the global variable t
    2. The transform script is executed, and the resulting value of t is used as input for the next step / rule script.
  3. For each matching rule, it then performs:
    1. Adds the specified css and js (from the two css/js tabs)
  4. GlimmerBlocker sends the contents of the variable to the browser when the script is done running.