nextwebgen.com

The Next Generation Web Now

Prototypify: Running Prototype code with legacy code

Filed under: Web 2.0 News, Front Page, JavaScript, Library, Prototype — Dion Almaer at 2:55 pm on Thursday, July 27, 2006

Aaron Newton, Product Manager at CNET sent us an email about his issues of using Prototype in production at a large company like CNET:

I've made a lot of use of Prototype but using it has been a bit of a controversy here at our network. Specifically, the extensions that are inherent in Prototype often create problems for (poorly written) legacy code and advertising javascript that we must include in our environment to make a buck.

Because it's not reasonable for our technical producers to regress every ad that runs on our site, I hired a good friend (and far more talented programmer) to help me find a solution. He, one Alex Cruikshank, authored a chunk of code (2.25K) for us that I think could be of great use to those out there who avoid Prototype because of the way it alters Arrays and Objects; specifically, those trying to use your library in an environment where they do not control 100% of the javascript included.

The code, all 3K of it, is a wrapper of sorts that removes all the extensions to Array and Object from Prototype. Then, when you want to make use of Prototype, you just apply this wrapper to your code.

We have put the code up for Prototypify along with the documentation.

JAVASCRIPT:
  1.  
  2. Prototypify = function() {
  3.  
  4. }
  5.  
  6. Prototypify.prototypified = false;
  7.  
  8. // store then remove functions from prototypes of native objects
  9. Prototypify.arrayFunctionHolder = new Object()
  10. for (x in Array.prototype)
  11. {
  12.   Prototypify.arrayFunctionHolder[x] = Array.prototype[x];
  13.   delete Array.prototype[x];
  14. }
  15.  
  16. Prototypify.stringFunctionHolder = new Object()
  17. for (x in String.prototype)
  18. {
  19.   Prototypify.stringFunctionHolder[x] = String.prototype[x];
  20.   delete String.prototype[x];
  21. }
  22.  
  23. Prototypify.numberFunctionHolder = new Object()
  24. for (x in Number.prototype)
  25. {
  26.   Prototypify.numberFunctionHolder[x] = Number.prototype[x];
  27.   delete Number.prototype[x];
  28. }
  29.  
  30.  
  31. Prototypify.proxy = function( f, proxyArguments )
  32. {
  33.   return function()
  34.     {
  35.       var needsPrototypes = ! Prototypify.prototypified;
  36.       if ( needsPrototypes )
  37.       {
  38.         Prototypify.prototypified = true;
  39.         for (x in Prototypify.arrayFunctionHolder)
  40.           Array.prototype[x] = Prototypify.arrayFunctionHolder[x];
  41.         for (x in Prototypify.stringFunctionHolder)
  42.           String.prototype[x] = Prototypify.stringFunctionHolder[x];
  43.         for (x in Prototypify.numberFunctionHolder)
  44.           Number.prototype[x] = Prototypify.numberFunctionHolder[x];
  45.       }
  46.  
  47.       if ( proxyArguments )
  48.       {
  49.         for ( var i=0; i <arguments.length; i++ )
  50.           if ( typeof arguments[i] == 'function' )
  51.             arguments[i] = Prototypify.proxy( arguments[i], proxyArguments );
  52.       }
  53.  
  54.       var out = f.apply( this, arguments );
  55.  
  56.       if ( needsPrototypes )
  57.       {
  58.         for ( x in Array.prototype )
  59.           delete Array.prototype[x];
  60.         for ( x in String.prototype )
  61.           delete String.prototype[x];
  62.         for ( x in Number.prototype )
  63.           delete Number.prototype[x];
  64.         Prototypify.prototypified = false;
  65.       }
  66.       return out
  67.     }
  68. }
  69.  
  70. Prototypify.instrument = function( clazz, proxyArguments )
  71. {
  72.   for ( prop in clazz.prototype )
  73.   {
  74.     if ( typeof clazz.prototype[prop] == 'function' )
  75.       clazz.prototype[ prop ] = Prototypify.proxy( clazz.prototype[ prop ], proxyArguments );
  76.   }
  77. }
  78.  
  79. Prototypify.instrumentStatic = function( clazz, proxyArguments )
  80. {
  81.   for ( prop in clazz )
  82.   {
  83.     if ( typeof clazz[prop] == 'function' )
  84.       clazz[ prop ] = Prototypify.proxy( clazz[ prop ], proxyArguments );
  85.   }
  86. }
  87.  

Copyright

Copyright (c) 2006 CNET Networks, Inc.

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Tuesday Morning Roundup

Filed under: Web 2.0 News, Front Page, JavaScript, Safari, Prototype, Ruby, Scriptaculous, RichTextWidget, Tip — Rob Sanheim at 9:00 am on Tuesday, July 11, 2006

Tuesday morning roundup!

  • Lesserwiki - a very light Ruby on Rails wiki very similiar to TiddlyWiki, with all updates done continuously on one page, double click to edit, etc.
  • Article on Writing Custom Iterators for Prototype from Encytemedia
  • A Prototype solution to the DOM Ready issue (see Dean's post for background info)
  • Javascript object < -> Rails object marshalling capability has been integrated into Protowidget - demo here, detailed explanation here - looks cool and could also function on its own.
  • An Ajax-ready slide transition library (demo) based on the popular Prototype/scriptaculous combo.
  • Reducing the perceived responsiveness of your app with the "W AJAX" design pattern - using background threads on the server to load complex data while the browser continues to load the easy stuff.
  • Safari hates trailing commas like this:
    new Effect.Highlight('foo', {duration:0.5,startcolor:'#ff99ff',});
    while FF and IE don't care. Bruce Williams has a quick and dirty Ruby test case to find offending scripts so you can catch it early in your build.

Sifl n Olly's Chester on his love skills. (mp3, probably NSFW)

updated: made title less stupid

Ajax Activity Indicators Examples

Filed under: Web 2.0 News, Front Page, Prototype, Examples, Component — Dion Almaer at 11:50 am on Monday, July 10, 2006

Ian Selby has written a thorough article on ajax activity indicators - make them globel and unobtrusive.

Ian details his solution:

So, what can we do about these problems? Well, if you’re using prototype as a part of your framework, you can register global indicator functions. These get executed when there are active requests, and when the requests complete. However, there’s another dilemma with this method too: Where do you place a indicator that can potentially appear often and keep it from being obtrusive, or, even worse, not being seen as it’s placed outside of the content that’s currently in view? I had to tackle that issue this week while starting development on a new project at work. I wanted to create an indicator that would be in the same place on every page, and that I never had to write extra code to use.

Check out the demo:

Ajax Indicator Demo

Code Example

Ajax.Responders.register({
        onCreate: function() {
                if($('notification') && Ajax.activeRequestCount> 0)
                        Effect.Appear('notification',{duration: 0.25, queue: 'end'});
        },
        onComplete: function() {
                if($('notification') && Ajax.activeRequestCount == 0)
                        Effect.Fade('notification',{duration: 0.25, queue: 'end'});
        }
});
 

Speeding up Prototype’s $$ Selector

Filed under: Web 2.0 News, Front Page, Programming, Prototype — Rob Sanheim at 10:35 am on Wednesday, June 28, 2006

Sylvain Zimmer has written a performance upgrade for Prototype’s $$ function that he claims is up to twenty times faster.

Sylvain’s ideas behind the patch are as follows:

  • Forwarding the call to the old $$ if the selector expression is too complicated (currently : if it uses attributes)
  • Replacing regular expressions with a simple parser
  • Minimizing the number of operations done on each iteration.
  • Trying to use getDocumentById() instead of getDocumentByTagName() when possible.
  • Avoiding recursive functions with return values.
  • Not being afraid of some “old-style” code if it speeds up the execution ;-)

Now, lets see if Sam applies it…

RailsConf 2006: Rails on Ajax by Justin Gehtland

Filed under: Web 2.0 News, Front Page, Ajax, Prototype, Conference, Ruby, Presentation — Rob Sanheim at 2:09 pm on Saturday, June 24, 2006

(Note From Rob: This session write up comes courtesy of Jim Halberg. Jim is not an official Ajaxian, though he dreams about being one when he grows up. Thanks, Jim!)

Are we still at the point where a talk on ajax must start with the "What is ajax?" question? Well, at least the explanations seem to be getting shorter =) (Rob: note to conference speakers - can we please just assume basic Ajax knowledge at this point?!)

Justin spent the majority of the presentation showing uncluttered examples of various Rails/Ajax/Prototype capabilities. Auto-complete search, drag-drop, and the like. These were delivered in a "if you haven't played with this yet" sort of way but he also managed to keep it quick enough - and drop in enough 'even if you've done this before you may not know about this' tidbits to keep the more experienced portion of the audience interested.

There was some talk on RJS and he spent some time on the always requested ajax topics… How do you deal with JavaScript disabled? What if a user has an old browser? How do you handle the introduction of new idioms?

The presentation ended with a bang as he demo'd creating an application with the soon to be released Streamlined. Streamlined is an open source framework, developed by Relevance LLC, to bring the simplicity of ActiveRecord to the view layer (coincidentally, this is #2 of the "3 Unsolved Problems" posed in Dave Thomas keynote yesterday). This is really slick - a lot of functionality - good looking (although they are looking for a designer to contribute some improvements) - and best of all: _very_ quick and powerful. I'm definitely looking forward to this being released at OSCON.

Script.aculo.us Datagrid

Filed under: Web 2.0 News, Front Page, JavaScript, Library, Prototype — Dion Almaer at 2:14 am on Thursday, June 22, 2006

Finetooth has created a Reorganizable DataGrid built on Ajax / Smarty / Prototype / Scriptaculous.

The online test allows you to build a datagrid on the fly and play around with moving headers, sorting, and the usual.

There is a README but you need to download the puppy and play around to work out how to use this yourself.

It doesn't seem to be as simple as a Dojo widget.

Script.aculo.us DataGrid