Browser extensions vs your JavaScript



Browser extensions vs your JavaScript

0 0


browser-extensions-vs-your-js

A presentation I gave at MelbJS on 13/3/13

On Github bensmithett / browser-extensions-vs-your-js

Browser extensions vs your JavaScript

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 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');

Run

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

Run

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

Run

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