Labs/Jetpack/Reboot/JEP/107

From MozillaWiki
< Labs‎ | Jetpack‎ | Reboot‎ | JEP
Jump to: navigation, search

JEP 107 - Page Mods

  • Champion: Daniel Buchner - daniel@mozilla.com
  • Status: Accepted/Pre-Production
  • Bug Ticket: 546739
  • Type: API
  • Difficulty: 4

Proposal

Page Mods is chiefly aimed at modifying and manipulating content documents within Firefox. Pages Mods should perform this functionality in a seamless fashion where the end result is the only change visible to the user.

Key Issues

When documents load that are represented in the "matches" white-list, we must ensure that script and styles injected into the page are evaluated by the parser in the normal load cycle. Perhaps we achieve this by dynamically creating resource (or custom protocol) URIs that contain the style and script blocks entered similar to the Background Page mechanisms. These URIs would be dynamically created CSS/JS files that would then be injected in the appropriate places withing the matched documents (CSS files in the doc head, JS files just after the close of the body tag).

Dependencies & Requirements

  • Requires JEP 104 - Simple Storage
  • Ability to dynamically create a resource, such a method would require JEP 106 - Registered Jetpack URLs
  • Capturing the page pre-render and injecting resources, for example: linked style sheets in the header and script tags after the body
  • Ability to access extension specific resources

Internal Methods

API Methods

Page Mods Initialization

var myMod = new pageMod({
  'include': ['*.google.com', 'jetpack.mozillalabs.com'],
  'exclude': ['https://mail.google.com/*'],
  'style': [
    'http://yui.yahooapis.com/3.0.0/build/cssbase/base-min.css',
    'body { background: #ffffff; font-family: Trebuchet MS; } span.details { font-size: 7px; }'
  ],
  'script': [
    'http://ajax.googleapis.com/ajax/libs/mootools/1.2.4/mootools.js',
    function(){
      $('container').addEvents({
          'click:relay(ul li)': function(){ this.setStyles('background','#000') },
          'mousenter:relay(ul li)': function(){ this.tween('background','#000') },
          'mouseleave:relay(ul li)': function(){ this.tween('background','#fff') }
      });
    }
  ]
});

Page Mods Method: add

Arguments:

  1. type - (string) The type of modifier being added. Can be 'include', 'exclude', 'style', or 'script'
  2. data -
    • include: (array) an array of URL strings to apply mods to
    • exclude: (array) an array of URL strings to skip when modding
    • style: (array) an array of style or resource strings
    • script: (function) an array of functions or resource strings

Returns:

The Page Mods instance

Notes:

Modifications passed to the Page Mods instance with this method will be added, and persist, on open and future documents matching all of the URL(s) currently on the 'include' white-list.

Examples:

myMods.add('include', ['*.digg.com']);

myMods.add('exclude', ['http://labs.digg.com/*']);

myMods.add('style', ['body: { background: #ffffff; font-family: Trebuchet MS; } span.details { font-size: 7px; }']);

// Creating a function reference

var pageLog = function(){
  console.log('I just logged a message with Page Mods!');
}

myMods.add('script', pageLog);

FUTURE ADDITION: Page Mods Method: remove

Arguments:

  1. type - (string) The type of modifier being added. Can be 'include', 'exclude', 'style', or 'script'
  2. data -
    • include: (array) an array of URL strings to apply mods to
    • exclude: (array) an array of URL strings to skip when modding
    • style: (array) an array of style or resource strings
    • script: (function) an array of functions or resource strings

Returns:

The Page Mods instance

Examples:


myMods.remove('include', '*.google.com');

myMods.remove('exclude', 'http://labs.digg.com/*');

myMods.remove('style', [
  'body { background; font-family; } span.details{}'  //This would remove all styles for the selector
]);

myMods.remove('script', pageLog);

FUTURE ADDITION: Page Mods Method: empty

Arguments:

  1. type - (string) The type of modifier being added. Can be 'include', 'exclude', 'style', or 'script'

Returns:

The Page Mods instance

Examples:

myMods.empty('include');

Use Cases

  1. Creation of CSS-based add-ons like Stylish, EditCSS, etc...
  2. Creation of JS-based add-ons like Execute JS, JS Exec etc...
  3. In General: Any Greasemonkey-style add-on, with the advantage that this API would allow for far greater flexibility - turning on and off only certain parts of a mod, automatically flashing a new url/web-page with the active parts of a mod by using the add method to include a new match to the matches white-list
  4. Adding methods and properties to the global window. For example, window.geolocation could have been implemented as a jetpack, and we could implement window.camera or window.microphone as a jetpack in the future. (via bsmedberg)

Common Actions

The API, if done in this fashion, give the developer the ability to dramatically simplify application actions such as:

  • Creating an instance of Page Mods that adds script or styles to a set of matched urls
  • Further extending and existing instance of Page Mods with additional styles and script
  • Toggling on and off specific styles or script within a Page Mods instance
  • Adding new matches to a Page Mods instance, which in turn instantly applies active styles and script within that instance to the newly added matches.
  • Multiple instances of Page Mods can be instantiated, which enables a whole cadre of functionality that the object-bound 'singleton' implementation neglects.