ScriptSheet.js Documentation

What It Does:

Cascading Style Sheets (CSS) allow for a highly elegant separation of content and presentation; you can specify multiple alternate style sheets to switch between, and even turn off all styles altogether. However, CSS is limited in the complexity of style it can handle; it can't can't manipulate the DOM, perform complex logic or calculations, or provide a high level of user interaction.

JavaScript in current-day browsers, however, has none of these limitations. But there is currently no standardized* mechanism for applying scripts as an independent presentation layer. The ScriptSheet framework is such a layer; it allows scripts to be used to style elements in complex ways, and perhaps more importantly for those same styles to be completely removed, allowing style switching. A page author can specify alternate ScriptSheet styles in the same manner he would specify alternate CSS styles.

Also included is a StyleChooser widget, which dynamically creates a selection field that allows the user to choose between alternate styles. The user's selection can be remembered between visits.

*MSIE and Mozilla both have their proprietary technologies: MSIE has behaviors and Mozilla has XBL, but neither are standardized or work in other browsers. Therefore they are not viable options for cross-browser development.

How To Use It:

Applying a ScriptSheet to an HTML document:

There are two steps required to apply a ScriptSheet script to an HTML document:

  1. Use a <script> element to import the external .js file containing the ScriptSheet script. This just makes the browser load and parse the script; the script isn't actually run yet.
  2. Use a <link rel="scriptsheet"> element to specify how the ScriptSheet is applied to the document. This follows the rules for applying CSS stylesheets to HTML documents, particularly in regards to specifying alternate styles with the title attribute. Since a JavaScript function does not have its own URL, use path/to/scriptfile.js#FunctionName for the href to specify the ScriptSheet function to apply. An example:
<html>
  <head>
    <script type="text/javascript" src="TheScript.js"></script>
    <link rel="scriptsheet" type="text/javascript" 
      href="TheScript.js#TheScript" title="Name of the Style" />
  </head>
  <body>
    ...
  </body>
</html>

Using the StyleChooser widget:

var chooser = new StyleChooser();
chooser.appendTo(parentElement); //or:
chooser.insertBefore(siblingElement);

This StyleChooser is similar to other widgets, except that it is designed to work with the ScriptSheet framework in addition to CSS stylesheets. You can use multiple StyleChooser widgets within a single document; a change in one will update the selection of the others.

Creating your own ScriptSheet script:

On the most basic level, a ScriptSheet is simply a Function object (JavaScript's version of a Class) with three characteristics:

  1. Its constructor takes an Element node reference as its first (and probably only) argument, and when instantiated it performs all the styling and DOM manipulation on that Element.
  2. It gives each of its instances a destroy() method which undoes everything that was done when the instance was created. This allows side-effect-free unassigning of the style and switching between styles.
  3. It has a scriptSheetSelector property which is set to a CSS selector string describing which elements to apply the style to (see the CSS selectors spec for details). The following selectors are supported: universal, element, id, class, attribute, descendant, child, and following-sibling selectors, and the comma separator for specifying multiple selectors.

Here is a simple example of a complete ScriptSheet script that shows any element with a "duplicate-me" class twice:

function Duplicated(elt) {
  this.element = elt;
  this.create();
}
Duplicated.prototype = {
  create : function() {  //apply the style:
    this.dupe = this.element.cloneNode(true);
    this.element.parentNode.insertBefore(this.dupe, this.element);
  },
  destroy : function() {  //undo everything:
    this.element.parentNode.removeChild(this.dupe);
	this.dupe = this.element = null;
  }
};
Duplicated.scriptSheetSelector = ".duplicate-me";

What It Depends On:

Compatibility:

Known to work in Mozilla (and derivatives) on any platform and MSIE 5.0+ on Windows.

Demonstration:

To Do:

Known Issues:

License:

The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/

Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License.

The Initial Developer of the Original Code is Jason Johnston (jj{at}lojjic[dot]net). Portions created by the Initial Developer are Copyright (C) 2004 the Initial Developer. All Rights Reserved.

This code is provided for you to use free of charge. If you find it useful please consider making a donation to help me continue to create tools like this one. You can find my contact info at http://lojjic.net.