helma/modules/helma/Aspects.js
2012-03-27 11:46:35 +02:00

145 lines
4.4 KiB
JavaScript

/*
* Helma License Notice
*
* The contents of this file are subject to the Helma License
* Version 2.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://adele.helma.org/download/helma/license.txt
*
* Copyright 1998-2008 Helma Software. All Rights Reserved.
*
* $RCSfile: Aspects.js,v $
* $Author$
* $Revision$
* $Date$
*/
/**
* @fileoverview Methods of the helma.Aspects module.
* <br /><br />
* To use this optional module, its repository needs to be added to the
* application, for example by calling app.addRepository('modules/helma/Aspects.js')
*/
/**
* Define the global namespace if not existing
*/
if (!global.helma) {
global.helma = {};
}
/**
* Library for adding Aspects
* <br /><br />
* Provides static methods to wrap existing functions
* inside a javascript closure in order to add additional
* behavior without overriding the existing one.
* <br /><br />
* Based on code by roman porotnikov,
* http://www.jroller.com/page/deep/20030701
* <br /><br />
* Note: Each prototype that uses aspects must implement a method
* onCodeUpdate() to prevent aspects being lost when the prototype
* is re-compiled
*
* @constructor
*/
helma.Aspects = function() {
return this;
};
/** @ignore */
helma.Aspects.toString = function() {
return "[helma.Aspects]";
};
/** @ignore */
helma.Aspects.prototype.toString = function() {
return "[helma.Aspects Object]";
};
/**
* Adds a function to be called before the orginal function.
* <br /><br />
* The return value of the added function needs to provide the
* array of arguments that is passed to the original function.
* The added function receives an array of the original arguments,
* the original function and the scope object of the original
* function as its parameters.
*
* @param {Object} obj The object of which the original function is a property
* @param {String} fname The property name of the original function
* @param {Function} before The function to be called before the original function
* @returns Function A new function, wrapping the original function
* @type Function
*/
helma.Aspects.prototype.addBefore = function(obj, fname, before) {
var oldFunc = obj[fname];
obj[fname] = function() {
return oldFunc.apply(this, before(arguments, oldFunc, this));
}
return;
};
/**
* Adds a function to be called after an existing function.
* <br /><br />
* The return value of the original function is passed to the
* added function as its first argument. In addition, the added
* function also receives an array of the original arguments,
* the original function and the scope object of the original
* function as additional parameters.
*
* @param {Object} obj as Object, the object of which the original function is a property
* @param {String} fname as String, the property name of the original function
* @param {Function} after as Function, the function to be called after the original function
* @returns Function A new function, wrapping the original function
* @type Function
*/
helma.Aspects.prototype.addAfter = function(obj, fname, after) {
var oldFunc = obj[fname];
obj[fname] = function() {
return after(oldFunc.apply(this, arguments), arguments, oldFunc, this);
}
return;
};
/**
* Wraps an additional function around the original function.
* <br /><br />
* The added function receives as its arguments an array of the original
* arguments, the original function and the scope object of the original
* function. The original function is not called directly and needs
* to be invoked by the added function.
*
* @param {Object} obj as Object, the object of which the original function is a property
* @param {String} fname as String, the property name of the original function
* @param {Function} around as Function, the function to be called inside the original function
* @returns Function A new function, wrapping the original function
* @type Function
*/
helma.Aspects.prototype.addAround = function(obj, fname, around) {
var oldFunc = obj[fname];
obj[fname] = function() {
return around(arguments, oldFunc, this);
}
return;
};
helma.lib = "Aspects";
helma.dontEnum(helma.lib);
for (var i in helma[helma.lib])
helma[helma.lib].dontEnum(i);
for (var i in helma[helma.lib].prototype)
helma[helma.lib].prototype.dontEnum(i);
delete helma.lib;
helma.aspects = new helma.Aspects();
helma.dontEnum("aspects");