// becomes:
// window.addEventListener("load", init);
function _asDeclaration($behaviorNode) {
switch (_getTagName($behaviorNode)) {
case "event":
var id = _getAttribute($behaviorNode, "id");
return (id) ? "var " + id + "={fire:function(event){element.fireEvent('" +
_getAttribute($behaviorNode, "name") + "',event)}}" : "";
case "property":
var $name = _getAttribute($behaviorNode, "name");
var $get = _getAttribute($behaviorNode, "get") || "function(){return getAttribute('" +
$name + "')}";
$get = "__defineGetter__('" + $name + "'," + $get + ")";
var $put = _getAttribute($behaviorNode, "put") || "";
if ($put) $put += ".call(element,value);";
$put = "function(value){" + $put + "setAttribute('" + $name + "',value)}";
$put = "__defineSetter__('" + $name + "'," + $put + ")";
return $get + $SEPARATOR + $put;
case "method":
return "element." + _getAttribute($behaviorNode, "name") + "=" + _getAttribute($behaviorNode, "name");
case "attach":
var $handler = _getAttribute($behaviorNode, "handler") || "";
$handler += ($handler) ? "()" : _getAttribute($behaviorNode, "onevent");
$handler = "function(event){window.event=event;return " + $handler + "}";
var $event = _getAttribute($behaviorNode, "event");
switch ($event) {
case "oncontentready": return "window.setTimeout(" + $handler + ",1)";
case "ondocumentready": return "document.behaviorUrns.__private.push(" + $handler + ")";
}
return (_getAttribute($behaviorNode, "for")||"element") + ".addEventListener('" + $event.slice(2) + "'," + $handler + ",false)";
case "defaults":
// not implemented
default:
return "";
}
};
function _asDefault($node) {
return (_getAttribute($node, "put")) ? ";var __tmp=getAttribute('" + _getAttribute($node, "name") + "')||" +
(_getAttribute($node, "value") || "null") +
";if(__tmp!=null)element['" + _getAttribute($node, "name") + "']=__tmp" : "";
};
// extract the body of a function
function _getFunctionBody($function) {
with (String($function)) return slice(indexOf("{") + 1, lastIndexOf("}"));
};
// behaviors are defined as xml documents, so we can use
// the http request object to load them and the dom parser
// object to parse them into a dom tree
var _httpRequest = new XMLHttpRequest;
function _loadFile($url) {
try {
// load the behavior
_httpRequest.open("GET", $url, false);
_httpRequest.send(null);
return _httpRequest.responseText;
} catch ($ignore) {
// ignore (but don't crash)
}};
// analyse the dom tree, build the interface and create the script
var _declarations = [];
var _defaults = "";
var _script = "";
function _load() {
// build a dom representation of the loaded xml document
var $dom = (new DOMParser).parseFromString(_loadFile(_url), "text/xml");
var $childNodes = $dom.documentElement.childNodes, $node;
for (var i = 0; ( $node = $childNodes[i]); i++) {
if ($node.nodeType == Node.ELEMENT_NODE) {
if (_getTagName($node) == "script") {
var $src = _getAttribute($node, "src");
if ($src) {
_script += _loadFile($src);
} else {
// build the script from the text nodes of the script element
for (var j = 0; j < $node.childNodes.length; j++)
_script += $node.childNodes[j].nodeValue;
}
} else {
// convert the dom node representation of a
// to a javascript statement
// and store it in our declarations collection
_declarations.push(_asDeclaration($node));
if (_getTagName($node) == "property") {
_defaults += _asDefault($node);
}
}
}
}
_defaults += ";delete __tmp";
};
_load();
// we've finished collecting interface declarations.
// they are now held as an array of strings.
// build a function from the script and extract the function body
// this has the effect of formatting the script (removing comments etc)
_script = _getFunctionBody(new Function(_script));
// support: new ActiveXObject
var $ACTIVEX = /\bnew\s+ActiveXObject\s*\(\s*(["'])\w\.XMLHTTP\1\s*\)/gi;
_script = _script.replace($ACTIVEX, "new XMLHttpRequest()");
// begin: annoying parse of script to "shuffle" declarations
// and inline code.
// microsoft dhtml behaviors add the interface first, then
// apply inline script.
// to achieve this, we have to strip out all of the inline
// code, leaving only function declarations. the inline code
// then gets appended to the script block for later
// execution.
// in between the function declarations and inline script, we
// sandwich the property getters and setters.
// this is a real nuisance actually...
// on the upside regular expressions are really quick...
// i'm using "#" as a placeholder, so i'll have to escape these out
_script = _script.replace(/#/g, "\\x23");
// parse out strings, regexps and program
// blocks - anything between curly braces {..}
var $ = [_declarations.join($SEPARATOR)];
var $BLOCKS_REGEXPS_STRINGS = /(\"[^\"\n]+\")|(\/[^\/\n]+\/)|(\{[^\{\}]*\})/g;
var _ENCODED = /#(\d+)\b/g;
// store a string and return a unique id
function _encode($match) {return "#" + $.push($match)};
function _decode($match, $index) {return $[$index - 1]};
while ($BLOCKS_REGEXPS_STRINGS.test(_script)) {
_script = _script.replace($BLOCKS_REGEXPS_STRINGS, _encode);
}
// we are now left with function declarations and inline statements
// remove function declarations and save them
var $FUNCTIONS = /\n\s*function[^\n]*\n/g;
var _functions = _script.match($FUNCTIONS) || [];
_script = _script.replace($FUNCTIONS, "");
// re-assemble the encoded script, in the following
// order: function declarations, interface definition
// (getters and setters), inline script
_script = _functions.concat("#1", _script).join($SEPARATOR);
// decode the script
var i = $.length;
do _script = _script.replace("#" + i, $[--i]); while (i);
// end: annoying parse of script
// build the final script
_script += _defaults;
// create an anonymous function in the global namespace.
// this function will add the interface defined by the dhtml behavior.
// after we've built this function we'll store it so that we don't
// have to go through this process again.
document.behaviorUrns[_url] = new Function("element", "with(this){" + _script + "}");
}
// because we loaded synchronously (or got it from the cache)
// we can apply the behavior immediately...
document.behaviorUrns[_url].call(this, this);
// this might mean somthing later
return _cookie;
} catch ($error) {
return 0;
}};
// implement the removeBehavior method for all elements
Element.prototype.removeBehavior = function($cookie) {
// mmm, not in a hurry to write this
};
// cache for previously loaded behaviors
// -also store some "default" behaviors
document.behaviorUrns = {
__private : []
};
// support multiple behaviors and ondocumentready
window.addEventListener("load", function() {
try {
var $handlers = document.behaviorUrns.__private;
var i = $handlers.length;
while (i) $handlers[--i]();
delete document.behaviorUrns.__private;
} catch ($ignore) {
}}, false);
}]]>
WebSVN
- websvn
- Blame
- Rev 2
- /templates/calm/star-light/src/moz-behaviors.xml