Labs/Jetpack/Reboot/JEP/107: Difference between revisions

From MozillaWiki
< Labs‎ | Jetpack‎ | Reboot‎ | JEP
Jump to navigation Jump to search
 
(35 intermediate revisions by 2 users not shown)
Line 2: Line 2:


* Champion: Daniel Buchner - daniel@mozilla.com
* Champion: Daniel Buchner - daniel@mozilla.com
* Status: Accepted/In-Queue
* Status: Accepted/Pre-Production
* Bug Ticket:
* Bug Ticket: [https://bugzilla.mozilla.org/show_bug.cgi?id=546739 546739]
* Type: API
* Type: API
* Difficulty: 4
* Difficulty: 4
Line 14: Line 14:


=== Dependencies & Requirements ===
=== Dependencies & Requirements ===
* I am not sure, please add to this list if anyone else knows of any
* Requires [[Labs/Jetpack/Reboot/JEP/104|JEP 104 - Simple Storage]]
* Ability to dynamically create a resource, such a method would require [[Labs/Jetpack/Reboot/JEP/106|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 ==
== Internal Methods ==
Line 25: Line 28:


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


#type - (<i>string</i>) The type of modifier being added. Can be 'matches', 'includes', 'styles', or 'script'. If the only argument passed in is an object, Page Mods assumes multiple modifiers will be passed in.
#<b>type</b> - (<i>string</i>) The type of modifier being added. Can be 'include', 'exclude', 'style', or 'script'
#data -
#<b>data</b> -
#* matches: (<i>array</i>) an array of web site resource strings
#* include: (<i>array</i>) an array of URL strings to apply mods to
#* includes: (<i>object</i>) 'script' or 'style' keyed nodes whose values are arrays of asset resource strings
#* exclude: (<i>array</i>) an array of URL strings to skip when modding
#* styles: (<i>object</i>) an object whose keys are CSS selectors and whose values are objects composed of CSS property keys and values
#* style: (<i>array</i>) an array of style or resource strings
#* script: (<i>function</i>) a function that will be injected into the page and called. By default, the function is bound with the target document's window object
#* script: (<i>function</i>) an array of functions or resource strings


<b>Returns:</b>
<b>Returns:</b>
Line 64: Line 65:
<b>Notes:</b>
<b>Notes:</b>


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 'matches' white-list.
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.


<b>Examples:</b>
<b>Examples:</b>


<pre class="brush:js;">
<pre class="brush:js;">
myMods.add('matches', ['*.digg.com']);
myMods.add('include', ['*.digg.com']);


myMods.add('includes', {
myMods.add('exclude', ['http://labs.digg.com/*']);
  'script': ['http://ajax.googleapis.com/ajax/libs/mootools/1.2.4/mootools.js'],
  'styles': ['http://yui.yahooapis.com/3.0.0/build/cssbase/base-min.css']
});


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


// Creating a function reference
// Creating a function reference
Line 91: Line 81:
   console.log('I just logged a message with Page Mods!');
   console.log('I just logged a message with Page Mods!');
}
}
// Using a function reference enables removal of the script later, see
// the <i>remove</i> method below for more info.


myMods.add('script', pageLog);
myMods.add('script', pageLog);
</pre>
</pre>


==== Page Mods Method: <i>remove</i> ====
==== FUTURE ADDITION: Page Mods Method: <i>remove</i> ====


<b>Arguments:</b>
<b>Arguments:</b>


#type - (<i>string</i>) The type of modifier being added. Can be 'matches', 'includes', 'styles', or 'script'. NOTE: If the only argument is an object, Page Mods assumes multiple modifiers will be passed in.
#<b>type</b> - (<i>string</i>) The type of modifier being added. Can be 'include', 'exclude', 'style', or 'script'
#data -
#<b>data</b> -
#* matches: (<i>array</i>) an array of web site resource strings
#* include: (<i>array</i>) an array of URL strings to apply mods to
#* includes: (<i>object</i>) 'script' or 'style' keyed nodes whose values are arrays of asset resource strings. Passing string of 'all' for the value of either 'include' key of 'styles' or 'script' will remove all includes of that type.
#* exclude: (<i>array</i>) an array of URL strings to skip when modding
#* styles: (<i>object</i>) expects object nodes keyed with CSS selector strings, whose values are arrays of the CSS property strings you would like to remove
#* style: (<i>array</i>) an array of style or resource strings
#* script: (<i>function reference</i>) removes the script associated with a function reference
#* script: (<i>function</i>) an array of functions or resource strings


<b>Returns:</b>
<b>Returns:</b>


The Page Mods instance
The Page Mods instance
<b>Notes:</b>
NEEDS FEEDBACK: Removal of any 'matches', 'script', or 'includes' of the keyed node type 'script' will reload any documents that contain, or are affected by, the modification's removal.


<b>Examples:</b>
<b>Examples:</b>
Line 121: Line 104:
<pre class="brush:js;">
<pre class="brush:js;">


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


myMods.remove('includes', {
myMods.remove('exclude', 'http://labs.digg.com/*');
  'script': 'all',
  'styles': ['http://yui.yahooapis.com/3.0.0/build/cssbase/base-min.css']
});


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


myMods.remove('script', pageLog);
myMods.remove('script', pageLog);
Line 137: Line 116:
</pre>
</pre>


==== Page Mods Method: <i>empty</i> ====
==== FUTURE ADDITION: Page Mods Method: <i>empty</i> ====


<b>Arguments:</b>
<b>Arguments:</b>


# type - (<i>string</i>) The type of modifier being added. Can be 'matches', 'includes', 'styles', or 'script'. NOTE: If the only argument is an object, Page Mods assumes multiple modifiers will be passed in.
#<b>type</b> - (<i>string</i>) The type of modifier being added. Can be 'include', 'exclude', 'style', or 'script'


<b>Returns:</b>
<b>Returns:</b>


The attached Page Mods instance
The Page Mods instance
 
<b>Notes:</b>
 
NEEDS FEEDBACK: Emptying of 'matches', 'script', or 'includes' will reload any documents that contain, or are affected by, the modification's removal.


<b>Examples:</b>
<b>Examples:</b>


<pre class="brush:js;">
<pre class="brush:js;">
myMods.empty('includes');
myMods.empty('include');
</pre>
</pre>
== Use Cases ==
# Creation of CSS-based add-ons like Stylish, EditCSS, etc...
# Creation of JS-based add-ons like Execute JS, JS Exec etc...
# 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 <i>add</i> method to include a new match to the matches white-list
# 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.

Latest revision as of 21:47, 28 April 2010

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.