Refactoring method that was previously injected with implement

Greetings, I'm trying to override or extend the Element.show() and .hide() methods in mootools in order to add some WAI-Aria toggling. I was trying to use the Class.Refactor() method like this:

 Element = Class.refactor(Element, {

 show: function(displayString) {
   result = this.previous(displayString);
   // Do my thing
   return result;
 },

 hide: function() {
   result = this.previous();
   // Do my thing
   return result;
 }

});

however, this is not working, previous is null and I think the reason is that Mootools injects those methods through Element.implement. So the methods are not native?

I have figured out how to completely replace .show and .hide but I would like to retain all of their existing functionality and just add to it. Any ideas?

Answers


not a refactor guy myself, but you can always do it 'old school' and save the previous function in a variable (_prev_show and _prev_hide for example), then do your override and call those functions from your new methods.

second option would be to try extending Element into itself and call this.parent(), this is the 'unsafe' version of Class.Refactor. [reference]


I got the answer from a coworker. He's not on SO so I'm posting on his behalf and will buy him a beer the next time we are in the same city:

Class.refactor doesn't work on Natives (Element, Array, String, etc.) because they aren't Classes nor can they be overrided to be; MooTools just adds some cool prototypes to make them more Class-like and fun and easy to work with.

The way to extend natives is to use the implement() method; The only problem is that this.parent() and this.previous() don't exist, so you have to get a bit trickier to extend existing methods without rewriting them:


(function(){ // Keeps the window namespace clean

   var old_hide = Element.prototype.hide;
   var old_show = Element.prototype.show;

   Element.implement({
       hide: function() {
           result = old_hide.run(arguments, this); // Calls old method
           alert("Hiding " + this.get('tag') );
           return result;
       },
       show: function(display) {
           result = old_show.run(arguments, this); // Calls old method
           alert("Showing " + this.get('tag') );
           return result;
       }
   });

})(); // Closes the private function and executes it immediately

The key concepts here are:

1 - Encapsulate the whole shebang in a private, self-executing function so the global namespace isn't polluted by our variable assignments for the original methods (e.g. old_hide and old_show);

2 - Use the Native object's implement() method to override each function, much like you had done as the second argument to Class.refactor;

3 - Instead of calling this.parent() or this.previous() in each method, you call the old prototypes using MooTools' run() method, which passes the arguments with a binding to the function and executes it.

As before, make sure to gather the result of the function.run() call and return it to maintain API consistency.


About the last comment by ryber, I'm confused because I made up an example is jsFiddle refactoring the Element class (Sample). The trick is that, when I tried to use that example in a real application it didn't work and I ended up here looking for a reason.


Need Your Help

page appears differently without www subdomain in google chrome

javascript html css google-chrome web

I am not sure what it is but page renders very differently without www subdomain i think it has something to do with my hidden div jQuery layout. Any ideas?

Using JavaScript to fix badly encoded Unicode characters?

javascript unicode character-encoding

I'm working on a web site with a content management system that does a bad job of displaying any text with non-ASCII characters. For example, right single-quotes show up as on the following web page (