What's new? | Help | Directory | Sign in
Google
protosafe
Turning Prototype into a 3rd-party animal :P
  
  
  
  
    
Show all Featured Wiki Pages:
CompilePacker
Join project
Project owners:
  John.David.Dalton
/**
 *   ________                _____  ____  ________        ________
 *   ___  __ \______________ __  /____(_) __/ ___/______ ____  __/_____
 *   __  /_/ /__  ___/_  __ \_  __/_  __ \_____ \ _  __ `/__  /_  _  _ \
 *   _  ____/ _  /    / /_/ // /_  / /_/ /____/ / / /_/ / _  __/  /  __/
 *   /_/      /_/     \____/ \__/  \____/ /____/  \__,_/  /_/     \___/
 *                                 _(_)                  
 *                                                        version v1.1.5
 *
 * Encapsulates/modifies Prototype and all included files.
 * Increases compatibility with 3rd party scripts by keeping Prototype
 * out of the global namespace, as much as possible, and by subclassing
 * the Array object to avoid for-in loop pollution.
 *
 *
 * IMPORTANT:
 *   
 *   ProtoSafe <strong>should</strong> be compatible with Prototype
 *   versions 1.4 - 1.6.0.2. Script order is not important. You may place
 *   ProtoSafe's script element before or after any other JavaScript framework.
 *   
 *   For production use <strong>all</strong> files, including Prototype, must
 *   be pre-modified by the Modify tool (./tools/modify.html). A pre-modified
 *   version of Prototype 1.6.0.2 is included with ProtoSafe.
 *   
 *   The prototype.js file available at www.prototypejs.org has a javascript
 *   comment on line 2696 containing a non-ascii encoded apostrophe. This may
 *   cause an issue with ProtoSafe. You may use the Prototype versions within
 *   ProtoPack (version 2.19b or higher) at:
 *   
 *   http://groups.google.com/group/prototype-core/files <protopack_vx.xx.zip> or
 *   http://code.google.com/p/protosafe/downloads/list <protopack_vx.xx.zip>
 *
 *
 * Modification Utility:
 *   
 *   What it DOES:
 *     
 *     The Modification Utility (MU) replaces any array
 *     with $Array. It also performs Prototype/Scriptaculous
 *     specific modifications such as removing window
 *     references from core Prototype objects, removing
 *     support for extending the native Event and Element
 *     objects, wrapping Element.extend() to automatically
 *     clean MooTool extensions and removing the
 *     Scriptaculous.load() method call.
 *
 *     The MU also supports compressing Prototype 1.6/Scriptaculous 1.8
 *     or higher. It uses a customized Packer3 that ignores the $super
 *     variable when packing with the "shrink variables" option. Read the
 *     Packer3.js source to learn how to compile your own version of Packer.
 *   
 *   What it DOESN'T:
 *     
 *     The MU does not replace window.<variable name> references.
 *     Make sure you consistently use/not use the window reference
 *     with a given variable (preferably not use).
 *     
 *     Remove any method call that dynamically loads additional files
 *     based on the url of the external file. This may conflict with ProtoSafe's
 *     own load functionality.
 *  
 *     Avoid the use of the following syntax:
 *     var foo = [,,,'4']; //although valid when converted -> new $Array(,,,'4') throws a syntax error.
 *   
 *   How To:
 *     
 *     Before modifing/compiling your code you may want to test it under ProtoSafe's debug mode to ensure
 *     it will work with ProtoSafe's modifications. To do this place protosafe.js and the "tools" folder
 *     in the same directory as prototype.js. Include in page:
 *     <script type="text/javascript" src="protosafe.js?debug=1&load=effects,site"></script>
 *     This will concat prototype.js, effects.js, and site.js into a single script and modify/encapsulate
 *     it at runtime.
 *     
 *     Compile AJAX Loaded Files:
 *       
 *       1) Click "Options" panel.
 *       2) Choose ProtoSafe AJAX Loader mode.
 *       3) Choose compression options.
 *       4) Click "Input" panel.
 *       5) Click "Insert File" and select the file you wish to include. (ex: effects.js or site.js)
 *       6) Click "Modify" button.
 *       7) Modified code will appear in the "Output" panel.
 *       8) Copy text from "Output" panel and re-save file.
 *       9) Repeat steps 4-8 for additional files. 
 *      10) Include in page: <script type="text/javascript" src="protosafe.js?load=effects,site"></script>
 *     
 *     Compile Standalone File:
 *       
 *       1) Click "Options" panel
 *       2) Choose ProtoSafe Standalone mode.
 *       3) Choose compression options.
 *       4) Click "Input" panel.
 *       5) Click "Insert File" and select prototype.js first.
 *       6) Click "Insert File" again to append another file. (ex: effects.js or site.js)
 *       7) Repeat step 6 until all files have been added.
 *       8) Click "Modify" button.
 *       9) Modified code will appear in the "Output" panel.
 *      10) Copy text from "Output" panel and save as a single js file. (ex: standalone.js)
 *      11) Include in page: <script type="text/javascript" src="standalone.js"></script>
 *
 *     Using XML Files:
 *       
 *       At "Step 5" of the Ajax Loaded/Standalone instructions above, you may select
 *       a specifically created xml file to automate the file concatenation process.
 *       An example file can be found in the root folder (./example.build.xml).
 *       
 *       <?xml version="1.0" encoding="utf-8"?>
 *       <project>
 *         <filelist prototypesrc="prototype.js">
 *           <file src="demos/scripts/debug/builder.js" />
 *           <file src="demos/scripts/debug/effects.js" />
 *           <file src="demos/scripts/debug/reflection.js" />
 *           <file src="demos/scripts/main.js" />
 *         </filelist>
 *       </project>
 *       
 *       Relative paths are relative to the xml file's location.
 *       The "prototypesrc" attribute of the "filelist" node contains
 *       the filepath to prototype.js. The "file" nodes  "src"
 *       attribute contains the filepath to the included files. You
 *       may specify urls for the file sources. ProtoSafe concats the
 *       files by child node order.
 *
 *
 *  Tested successfully on:
 *    
 *    Win: 
 *      Opera 9.50 Alpha
 *      Firefox 2.0.0.12
 *      IE 7.0
 *      IE 6.0.2
 *      IE 5.5
 *      Safari 3 (XP Beta)
 *
 *    Mac:
 *      Firefox 2.0.0.2
 *      Firefox 2.0.0.12
 *      Camino 1.0.4
 *      Opera 9.10
 *      Opera 9.26
 *      Omniweb 5.6
 *      Safari 2.0.4
 *      Safari 3 (OSX 10.4.9 Beta)
 *
 *
 * Caveats/Gotchas:
 *   
 *   Synchronous Requests:
 *     
 *     Synchronous requests are enabled by default as an attempt
 *     to preserve the firing of dom:loaded and window onload event
 *     observers. Loading large files may cause the web page to
 *     temporarily lock up or become unresponsive.
 *   
 *   
 *   Asynchronous Requests:
 *     
 *     Asynchronous requests will avoid the caveats of synchronous
 *     requests, at the expense of consistently firing the dom:loaded
 *     and window onload event observers. This happens because one or
 *     all of the scripts may finish loading after the dom:loaded or
 *     window onload events have fired.
 *   
 *   
 *   Inline JavaScript calls:
 *     
 *     Because Prototype and all included files are encapsulated, inline
 *     JavaScript calls to Prototype/included methods will not work.
 *   
 *   
 *   Element Sugar Cross-Contamination:
 *     
 *     Although Prototype is encapsulated, it and other frameworks
 *     like MooTools, can still extend DOM elements which can lead to
 *     instances of sugar cross-contamination. Any Prototype method that
 *     uses Element.extend will automatically remove MooTools extensions
 *     without the need to call ProtoSafe.
 *     
 *     For example in Firefox:
 *       
 *       //if MooTools exists it will auto extend all elements:
 *       var element = document.createElement('DIV'); //auto extends elements
 *       element.setText('Happy cows come from California.');
 *       
 *       element = ProtoSafe(example); //removes MooTools extensions
 *         //OR simply
 *       element = $(element); // $ uses Element.extend so it's good to go
 *       
 *       console.log(typeof element.setText);  // -> undefined
 *       console.log(typeof element.identify); // -> function
 *   
 *   
 *   Arrays:
 *     
 *     Because the Array object is subclassed you no longer get the native
 *     sugar from standard arrays. However, all arrays returned from Prototype
 *     methods should be pre-sweetened. You may use the Modify tool (./tools/modify.html),
 *     included with ProtoSafe, to assist you in the modification process.
 *     
 *     Use the following syntax for manually creating a sweetened array:
 *       new $Array(10) //makes a new $Array with a length of 10
 *         //OR
 *       $Array('andrew','jd','juriy ','justin','mislav','sam','tobie');
 *     
 *     Use new string $split() method to return an $Array:
 *       'apples,oranges,bananas'.$split(',').each(function(fruit){ ... });
 *   
 *   
 *   ASCII Encoded Files:
 *     
 *     When this file is loaded by ajax from your local filesystem the special characters below
 *     will not render properly because this file, like most javascript files, is ASCII encoded.
 *     ASCII only supports 128 character codes. The characters below are composed of character codes
 *     greater than 128. Normally a server would specify which encoding to impose on a file. However,
 *     on your local filesystem the file's actual encoding is used. To fix this issue with other files
 *     use Notepad, or any other text editor capable of saving UTF-8 encoded files, to re-save the file
 *     and change the "Encoding" option from "ANSI" to "UTF-8".
 *     
 *     ASCII Test:
 *     Ã ž Ÿ Â £ ¤ ¥
 *     
 *     References:
 *     http://en.wikipedia.org/wiki/ASCII
 *     http://en.wikipedia.org/wiki/UTF-8
 *   
 *   
 *   Obfuscated JavaScript:
 *     
 *     ProtoSafe <strong>works</strong> with minified, variable shrunk, and
 *     Dean Edwards Packer 3 base62 encoded files. However, obfuscated files are
 *     impossible to accurately pattern match and modify. When ProtoSafe encounters
 *     an obfuscated file it will "error out", failing to modify the file's source
 *     correctly. To assist developers, in debug mode, ProtoSafe will throw a warning
 *     if it detects commonly used js obfuscators. If you still wish to use obfuscated
 *     files you must manually modify the original unobfuscated file. Then re-obfuscate
 *     the modified file with the obfuscator of your choice. You may use the Modify
 *     tool (./tools/modify.html), included with ProtoSafe, to assist you
 *     in the modification process.
 *   
 *   
 *   Debug Runtime File Modifications & Performance:
 *     
 *     While in debug mode ProtoSafe will auto-modify all files at runtime.
 *     Although convenient for developers it does add to the scripts overall
 *     startup delay. Use pre-modified copies of your files to avoid this
 *     process and the delay associated with it. You may use the Modify
 *     tool (./tools/modify.html) included with ProtoSafe to streamline the
 *     manual conversion of your files.
 *     
 *     File source modifications are done with regular expressions. If you
 *     have any regular expression optimizations/tweaks please email me.
 *   
 *   
 *   Safari 2.0.4 Status Bar Loading Indicator:
 *     
 *     The iframes in Safari seem to keep the status bar loading indicator busy
 *     after the page has finished loading. I have tried setting the src attribute
 *     to "javascript:false" as well as using document.open()/document.close().
 *     If you know of a way to fix this please email me.
 *
 *
 * Usage examples:
 *   
 *   Basic usage: (Requires all files to be pre-modified)
 *     <script type="text/javascript" src="protosafe.js?load=effects,site"></script>
 *   
 *   Debug mode: (Allows unmodified files, will modify at runtime)
 *     <script type="text/javascript" src="protosafe.js?debug=1&load=effects,site"></script>
 *   
 *   Disable auto-modifying files in debug mode:
 *     <script type="text/javascript" src="protosafe.js?debug=1&nomod=1&load=effects,site"></script>
 *   
 *   Asynchronous requests:
 *     <script type="text/javascript" src="protosafe.js?async=1&load=effects,site"></script>
 *   
 *   Alias ProtoSafe as Prototype/Protoculous: (renaming prototype.js -> lib.js and protosafe.js -> prototype.js)
 *     <script type="text/javascript" src="prototype.js?load=effects,site"></script>
 *       OR
 *     <script type="text/javascript" src="protoculous.js?load=effects,site"></script>
 *
 *   Standalone usage: (It's a regular javascript file, name it whatever you want)
 *     <script type="text/javascript" src="standalone.js"></script>
 *
 *
 * @author John-David Dalton <john.david.dalton[at]gmail[dot]com>
 * @version 1.1.5
 * @license http://creativecommons.org/licenses/by-sa/3.0/
 * @thanks Juriy Zaytsev (kangax), for helping me brainstorm and naming ProtoSafe.
 * @link http://groups.google.com/group/rubyonrails-spinoffs/browse_thread/thread/ae0c3f99d46e5462/98cc71dc5a5b758d
 */