Skip to content

Instantly share code, notes, and snippets.

@jboesch
Created February 20, 2010 17:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jboesch/309803 to your computer and use it in GitHub Desktop.
Save jboesch/309803 to your computer and use it in GitHub Desktop.
/**********************************************************************************
*
* @author Jordan Boesch
* @version 1.2
* @link http://boedesign.com/blog/2010/02/13/hijacking-javascriptjquery-methods/
* @date Feb 20, 2010
*
* Hijack is a little snippet of code that allows you to hijack arguments passed to
* functions/methods. Not only can you alter arguments, but you call the old method
* from within the hijacked function (2nd param) and 'return false' if you want to call the
* function yourself.
*
* Be aware that this was more-so a proof of concept. I don't
* fully recommend hijacking and overwriting methods but it does have its uses.
* I thought I would attempt it by making it easy to do... It's still "eval" ;)
*
* USAGE:
*
* Here is how you could hijack the css method in jQuery:
*
----------------------------------------------------------------------------------
var hijackedjQueryCSS = new Hijack('jQuery.fn.css', function(user_args, old_method){
var args = user_args;
if(args[1] == 'dark-violet'){
args[1] = '#6B238E';
}
return args;
});
----------------------------------------------------------------------------------
*
* Now if you run this:
*
----------------------------------------------------------------------------------
$('body').css('color', 'dark-violet')
----------------------------------------------------------------------------------
*
* it will change the color to the hex value you set in your hijacked method.
*
* You can also restore the original method by calling destroy() like so:
*
*
----------------------------------------------------------------------------------
hijackedjQueryCSS.destroy();
----------------------------------------------------------------------------------
*
* Now when you run the code that sets the color to dark-violet, nothing will happen.
*
* If you're interested in over-writing the MooTools css method, then you would use
* this string: Element.prototype.setStyle as the first parameter.
*/
/**
* Allows you to alter with arguments before the method is actually called
* @param {Function} method A method/function to call after doing some tampering
* @param {Function} cb A callback that is passed the arguments for you to play with
* @constructor
*/
function Hijack(method_name, cb){
// A function needs to be passed or there will be hell to pay
if(Object.prototype.toString.call(cb) !== "[object Function]"){
throw new Error('An anonymous function must be passed as the second parameter!');
}
var self = this,
method_old = eval(method_name); // Keep track of the old one to call
// Make sure this is the first time we create an instance for this method
if(!Hijack._inArray(method_name, Hijack._methodInstances)){
// Store it, just in case we need to restore it for "destroy"
self._orig = { method_name: method_name, method_old: method_old };
Hijack._methodInstances.push(method_name);
// Evil, I know..
eval(method_name + " = function(){var args = Array.prototype.slice.call(arguments);if(a = cb.call(this, args, method_old)){return method_old.apply(this, a)}};");
}
// F off.
else {
throw new Error('You cannot create multiple instances of a specific method (yet), sorry!');
}
}
Hijack.prototype = {
/**
* Bring it back to the original method (before it was hijacked)
* @public
*/
destroy: function(){
var self = this;
eval(self._orig.method_name + " = function(){ return self._orig.method_old.apply(this, arguments); }");
}
}
/**
* Keep track of methods being hijacked, you can only hijack a method once!
* @private (but not really)
*/
Hijack._methodInstances = [];
/**
* Searches an array for a specific value
* @param {String} needle What you're searching for
* @param {Array} haystack What you're searching in
* @private (but not really)
*/
Hijack._inArray = function(needle, haystack){
for(var i = 0, length = haystack.length; i < length; i++) {
if(haystack[i] == needle) return true;
}
return false;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment