Browser extensions
vs
your JavaScript

Internet Explorer with a lot of browser plugins installed
What do browser extensions do?

From the Chrome Extension Docs...

Content scripts are JavaScript files that run in the context of web pages.

By using the standard DOM, they can read details of the web pages the browser visits, or make changes to them.

JS is running in your app that you didn't put there.

Show me proof!
DIY JS error logging

window.onerror = function( message, file, line ) { 
  var formattedMessage = '[' + file + ':' + line + '] ' + message;

  _gaq.push( [  '_trackEvent', 
                'Exceptions', 
                'Application', 
                formattedMessage, 
                null, 
                true ] );
}

  • [chrome://freecorder/content/js/content.js:9]
    TypeError: freecorder.extension is undefined
  • [chrome://afterthedeadline/content/atd.js:687]
    TypeError: can't access dead object
  • [chrome://ffvkbd/content/ikavvklistener.js:0]
    Script error.
  • [D:\Program Files (x86)\Kingsoft\PowerWordDict\
    plugin\firefox\resources\grabword.js:71]
    TypeError: event.target is undefined
  • [http://bens-awesome-app.com:1]
    ReferenceError: Can't find variable: Reader2
  • [http://bens-awesome-app.com:1]
    SyntaxError: Unexpected string '^^^'

Mostly harmless, except when they...

  • block resources
  • mess with your DOM

Blocking resources

adblock

AdBlock blocks ads (...duh)


yepnope({
  load: [ 'vendor.js', 
          'lib.js',
          'app.js', 
          'googleadservices.com/conversion.js' ],

  complete: function () {
    app.init();
  }
});

Browser extensions can block these resources:

  • Ads
  • Analytics/tracking scripts
  • All 3rd party resources (sucks if you use a CDN)
  • Flash (beware if you use it for HTML5 audio/video fallback)

Mess with your DOM

Google Screen Capture extension adds an attribute to body

  <body screen_capture_injected="true">

Meanwhile, at the other end of the spectrum...

Greasemonkey

(aka Tampermonkey aka UserScripts)

Lets users write & run any arbitrary JS


  var clippy = document.getElementById('clippy');
  clippy.classList.add('being-helpful');

Greasemonkey script:
  var wtfIHateClippySoMuch = document.getElementById('clippy');
  wtfIHateClippySoMuch.parentNode.removeChild( wtfIHateClippySoMuch );

Our app:
  var clippy = document.getElementById('clippy');
  clippy.classList.add('being-helpful');

Downsides

  • DOM your JS expects might not exist in the wild
  • Break existing userscripts whenever you update the HTML

Upsides

  • Users showing you what features they want
  • Force you to write durable code

How do I cope?!

1. Relax

You will never test your JS in every context in which it will run.

2. Progressive Enhancment

Don't care about <noscript> users?

Do it for <brokenscript> users!

3. Log JS errors

It's nice to know.

4. Bug reports

Unreproducible bugs
===
some browser extension (probably)

The End

Slides: github.com/bensmithett

Twitter: @bensmithett