Created
February 20, 2010 17:50
-
-
Save jboesch/309803 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/********************************************************************************** | |
* | |
* @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