diff --git a/.gitignore b/.gitignore index 496ee2c..c3c5eb9 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -.DS_Store \ No newline at end of file +.DS_Store +dist/ \ No newline at end of file diff --git a/CHANGELOG b/CHANGELOG deleted file mode 100644 index d112a95..0000000 --- a/CHANGELOG +++ /dev/null @@ -1,1197 +0,0 @@ -*V1.8.3* (October 8, 2009) - -* Update to Prototype 1.6.1 - -* Effect.toggle to return effect (to be able to do Effect.toggle(element, 'appear', {sync: true});) [RStankov] - -* Use element.identify() for fetching element.id in Sortable.create [RStankov] - -* Fix deprecated usage of Position.cumulativeOffset. [#182 state:resolved] [James Wheare] - -* Make loader work for application/xhtml+xml served documents. Closes #95. [Pavel Sedek] - -* Check for Windows Media plugin and RealPlayer plugin in Firefox on Windows to allow sound playback. Closes #36, #86. [Alexander Gavazov et al.] - -* Remove dead code in effects.js. Closes #125. [Confusioner] - -*V1.8.2* (November 18, 2008) - -* Update to Prototype 1.6.0.3 - -* Make sure InPlaceEditor converts HTML entities to text. [Sean Kirby] - -* Fix that Builder.node did not return extended elements on IE. Closes #71 and #77. - -* Fix a bug in Sortable.destroy to make sure it's called on the referenced Sortable only, which allows for the correct intialization of nested Sortables. Closes Trac #8615. [Leon Chevalier] - -* Change Effect.Base#render not to use eval(), so certain JavaScript runtime environments (like Adobe AIR) that do not support eval() work. [King Maxemilian, John-David Dalton] - -* Fixed a calculation error in Effect.Transitions.pulse that could lead to flickering, add easing and change it to be a normal 0 to 1 transition that can be used with any effects; Effect.Pulsate now uses its own implementation. [Thomas Fuchs] - -* Fixed Effect.ScrollTo. Changeset 8686 had a typo, document.viewport.getScrollOffsets[0] is always undefined. Removed the max check as it is not a cross-browser way to get scroll height and breaks the effect. Depending on scrollTo to do the right thing. Closes #11306. [Nick Stakenburg] - -* Update version check so all Prototype versions can be required, not just x.x.x. Closes #10966. [Nick Stakenburg] - -* Using $$ in the loader instead of getElementsByTagName to prevent limitations. Closes #9032. [Nick Stakenburg] - -* Fix some missing semicolons. [jdalton] - -* Fix an issue with Effect.ScrollTo that caused Firefox to scroll to the wrong offset in some situations. Closes #10245. [nik.wakelin] - -* Fixes an issue with IE ghosting on non-absolute elements. Closes #10423. [Tanrikut, tdd] - -*V1.8.1* (January 3, 2008) - -* Fix Element#getStyles in IE. Closes #10563. [Tobie Langel] - -* Update to Prototype 1.6.0.1 as of 8551. - -* Fix a regression with autocompleters not responding correctly to cursor keys on both Safari and IE. Closes #10107. [thx Zman771] - -*V1.8.0* (November 6, 2007) - -* Update to Prototype 1.6.0 final - -* Ajax.InPlaceEditor now can deal with callbacks that return an object. Closes #10064. [tdd] - -* Fix a potential problem with the loader and Firefox 2.0 on the Mac. Closes #9951. [awaters] - -* Add duration and distance options to Effect.Shake. Closes #8637. [amiel, rmm5t] - -* Update code to use new Hash implemention in Prototype 1.6. Update InPlaceEditor to use new Class.create syntax. [tdd] - -*V1.8.0 preview 0* (October 12, 2007) - -* Update to new Class.create syntax in Prototype 1.6; update to latest Prototype 1.6 trunk. - -* Fix bottom CSS property reassignment and initialization in queues for Effect#SlideUp. Closes #7412, #7761. - -* Fix an issue with String#parseStyle that could sometimes cause errors on Safari 2. - -* Refactoring to use Prototype 1.6. Remove dependency of Effect.tagifyText from builder. Use Prototype code style rules more consistently. - -* Remove the deprecated Effect2 namespace. - -* Update to Prototype 1.6.0_rc0. - -* Some effect code refactoring to take advantage of new Prototype 1.6 features. - -* Effect.ScrollTo is now no longer a core effect (returns a Effect.Tween instance now). - -* Add Effect.Tween, a new core effect. This effect tweens between two values and sets a property or calls a method on an object (including DOM elements); or allows for a callback method, which will be automatically bound to the object. - Examples: - var whatever = { blech: 0 }; - new Effect.Tween(whatever, 5, 0, 'blech'); // sets property on the object - new Effect.Tween('foo', 10, 20, 'innerHTML'); // sets property on the 'foo' DOM element - new Effect.Tween('foo', 10, 20, 'update'); // method call on 'foo' DOM element - new Effect.Tween('foo', 50, 0, { duration: 2.0 }, function(p){ - this.setStyle({border:p.toFixed(3)+'px solid red'}); - }); - new Effect.Tween(null, 0, 100, function(p){ scrollTo(0,p) }); // scrolls the window - -* Revert the workaround for the Firefox issue that makes autocompleter input field values be remembered correctly when the back button is hit to return to a page that contains autocompleted values, as this can cause "Are you sure you want to navigate away?" popups. Closes #8411. [okada] - -* Improve the way deactivating the active droppable is handled. Closes #9072. [Karsten Sperling] - -* Next version will be 1.8.0. Update to Prototype 1.6.0_pre1. - -* Make draggable initialization faster. Closes #8697. [ssinghi] - -* Make BDD-style testing compatible with IE6 and IE7. Closes #8972. [steveluscher] - -* Add BDD methods to booleans. Closes #9147. [steveluscher] - -* Add support for full CSS inheritance in Effect.Morph. Closes #9054. [Tobie] - IMPORTANT: Note that this could potentially change the outcome of classname-based morphs, so be sure to check your morph effects if you use this feature. - For this feature, the new method Element#getStyles is introduced, which returns an objects which properties correspond to the CSS properties found in Element.CSS_PROPERTIES. Note that this method doesn't work seemlessly across browsers for certain non-measurable CSS properties, such as float. - -* Add the externalControlOnly option to the in-place editors to allow for external controls to exclusively trigger the in-place editing. Closes #9024. [tdd] - -* Complete rewrite of Ajax.InPlaceEditor and Ajax.InPlaceCollectionEditor. [tdd] - THIS UPDATE MIGHT AFFECT BACKWARDS COMPATIBILITY. - Be sure to properly test, especially if you're using multi-line editing and/or monkeypatching. - Read more about all the added goodness in this article: - http://mir.aculo.us/2007/7/17/in-place-editing-the-summer-2007-rewrite - -* Update to Prototype 1.5.2_rc0 r7076: - - Works around bugs in Safari 1 and Safari 2 Regexp engines that could cause crashes - - Fixes a rendering issue with opacity-based effects and floating elements on Safari - -* Mild refactoring of sound.js to take advantage of new Prototype features. - -* Add highlight element method as a shortcut to Effect.Highlight. - Example: - $('message').highlight({startcolor:'#ff0000'}).update('KTHXBYE'); - -* Improve performance of String.prototype.parseStyle by caching the dummy element used. - -* Add combined effects as element methods. - Examples: - $('message').appear().update('Oh noes!'); - $('login').shake({ duration: 2 }); - -* Add Effect.Transitions.spring, which simulates a spring which oscillates while coming to rest. This transition is specifically targeted towards use with Effect.Move, for example as a reverteffect when using Draggables, as it will have return values >1 and cause temporary "overshooting" of the effect. Closes #8474. [edg2s] - -* Fix effects initialization if no options are given. Fixes #7809. [thx Kroc Camen] - -* Fix incorrect placement on drop for absolute ghosting elements. Update to Prototype 1.5.2_rc0 r6955 (required for #8581). Closes #8581. [tdd] - -* Make sure the autocompletion happens on the token where the cursor is, not the last token when using tokenized autocompleting text fields. Closes #8588. [tdd] - -* Fix that non-Mozilla browsers would display messages with the autocompleter back-button fix introduced in 1.7.1 beta 2. Fixes #7752, #8411. [josh, stetz] - -*V1.7.1 beta 3* (May 19, 2007) - -* Update to Prototype 1.5.1 final - -* New elements and handles options for Sortable.create which take arrays of elements or element ids. These overrule the normal handle and elements finding options on initialization of the sortable, and can yield huge performance increases in situations where these elements or ids are known at call time. [Thomas Fuchs] - -* Major performance improvement of Sortable.create when using the handle option. [Tobie Langel] - -* Fix Builder.node double quote escaping in attributes, fixes #8125. [Aa!] - -*V1.7.1 beta 2* (April 28, 2007) - -* Update to Prototype 1.5.1_rc4 - - Various optimizations and fixes - - http://dev.rubyonrails.org/browser/spinoffs/prototype/trunk/CHANGELOG?rev=6604 - -* Fix autocompleter indicator not appearing when calling activate() directly. Don't show indicator for local autocompleting. Fixes #7770. [pyro8019] - -* Don't clear out autocompleting fields in Mozilla-based browsers when navigating back to a page with the Back button, fixes #7752. [seanc] - -*V1.7.1 beta 1* (March 12, 2007) - -* Update to Prototype 1.5.1 r6386 - - Fixes SlideUp/SlideDown on IE - - Fixes an opacity problem with IE - - Performance optimizations - - See http://dev.rubyonrails.org/browser/spinoffs/prototype/trunk/CHANGELOG?rev=6381 for more information - -* Make builder unit tests work on IE - -* Fix id assignment for sounds on Firefox/Windows, fixes #7709 [Robert Wallis] - -* Add Sound.enable() and Sound.disable() to globally turn off Sound.play() - -* Added Sound.play(url,options) in new sound.js file. scriptaculous.js automatically includes this file. - Based on code by Jules Gravinese, used with permission. - - The sound player uses native sound support on IE, and falls back to using on other browsers, - which means it uses QuickTime for most cases. The recommended format to use is MP3. - - Examples: - Sound.play('blah.mp3'); - // --> plays sound immediately in 'global' track - Sound.play('blah.mp3',{replace:true}); - // --> stop playing all sounds in 'global' track, and play new sound - Sound.play('blah.mp3',{track:'mytrack'}); - // --> places the sound in the 'mytrack' track - Sound.play('blah.mp3',{track:'mytrack',replace:true}); - // --> stop playing all sounds in 'mytrack' track, and play new sound - - The sound effect used in the functional test is "Sword being drawn" by James Greever, released as freeware. - -* Various effects engine optimizations [Tobie Langel, Thomas Fuchs] - -* Make Ajax.InPlaceEditor more customizable: [thx godlie] - - Add an okLink option to Ajax.InPlaceEditor so you can have a link instead of a button. Uses the 'editor_ok_link' CSS class for styling, fixes #6455 - - Add an cancelButton option to Ajax.InPlaceEditor, uses the 'editor_cancel_button' CSS class - - Add textBefore-, textBetween- and textAfterControls (which default to empty strings) - - For consistency, cancel link now also gets 'editor_cancel_link' CSS class - -* Add an onDropped callback to Draggables, that fires at the end of a drag when the Draggable was dropped on a Droppable - -* Add revert: 'failure' option to Draggables to only revert if not dropped on a valid drop target, fixes #6909 [davidw] - -* Update to new Prototype Browser detection - -* Fix a memory leak with Effect.Morph in Firefox, fixes #7558 [Malard] - -* Add ability to nest single nodes in Builder.node in addition to arrays of nodes. - Examples: - var element = Builder.node('div', Builder.node('span','blah')); - - Builder.dump(); - var element = DIV(SPAN('blah')); - -*V1.7.0* (January 19, 2007) - -* Cleanups for Effect.Morph - -* Monkeypatch Prototype 1.5.0 to incorporate [6002], fixes setStyle({opacity:0}) for IE - -* Fix Effect.inspect() for Prototype 1.5.0 final hash changes - -* Update to Prototype 1.5.0 final - -* New option keepBackgroundImage: true for Effect.Highlight, fixes #5037 [docwhat, tomg] - -* Minor tweaks for issues with application/xhtml+xml documents on Firefox, fixes #6836 [sjinks] - -* Fix a possible exception with Sortables, fixes #6828 [craiggwilson] - -* Update to Prototype 1.5.0_rc2 revision [5844] (as of Rails 1.2 RC 2) - -*V1.7.0 beta 2* (December 18, 2006) - -* Change the default setting for effects to support up to 60fps, if renderable by the browser. Add performance info to effects unit test. - -* Change get/setOpacity to use Prototype's new support for cross-browser opacity. - -* Update to Prototype 1.5.0_rc2 revision [5741], which fixes some of the reported issues with beta 1 (see Prototype's CHANGELOG for more): - * Opera 9, while not officially supported, should work now with Prototype and script.aculo.us - * Fixes issue with Safari when using Prototype's Ajax helpers with HTTP authorization - -* Add hash and CSS className support to Effect.Morph, fixes #6674 [Tobie] - Examples: - $(element).morph('myClass') - // will morph to all the properties specified - // in .className (in your external stylesheet). - // All properties which cannot be morphed (such as font-style) - // will be applied AfterFinish - $(element).morph('font-size: 10px') // or - $(element).morph({fontSize: '10px'}) // will morph the font-size to 10px - -*V1.7.0 beta 1* (November 21, 2006) - -* Add Element.morph() and Element.Methods.morph() as a shortcut to Effect.Morph - Example: - // basic Effect.Morph - $('error_message').morph('color:#f00;font-size:17px'); - // fade out after a while - $('error_message').show().morph('font-size:17px').morph('opacity:0',{delay:4}); - -* Update to Prototype 1.5.0_rc2 revision [5580] - -* Add a paramName option to the inplace editor for overriding the default parameter name of "value" - -* Add Effect.Transform that generates parallel executing Effect.Morph sets - Example: - // set up transformation - var transformation = new Effect.Transform([ - { 'div.morphing': 'font-size:20px;padding-left:40em' }, - { 'blah' : 'width:480px;border-width:10px;border-right-width:20px;margin:200px;margin-bottom:-20px;font-size:30px' } - ],{ duration: 0.5 }); - // play transformation (can be called more than once) - transformation.play(); - -* Add Effect.Morph core effect that morphs to a given CSS style rule. Effect.Morph does take orginal styles given by CSS style rules or the style attribute into consideration when calculating the transforms. It works with all length and color based CSS properties, including margins, paddings, borders, opacity and text/background colors. - Example: - new Effect.Morph('mydiv',{ - style: 'font-size:3em;color:#f00;border-width:2em', - duration: 2.0 - }); - -*V1.6.5* (November 8, 2006) - -* Update to Prototype 1.5.0_rc1 revision [5462] - -* Support the HTML 'for' attribute in Builder by using 'htmlFor', fixes #6472 [gjones, tdd] - - var node = Builder.node('label', { htmlFor: 'myinput' }); - -* Add support to run a specific failing unit test by clicking on the corresponding test result, fixes #6290 [leeo] - -* Add modifier key support to Event.simulateMouse, fixes #6391 [savetheclocktower] - -* Add rails-trunk update task, clean up references to MIT license - -* Add new 'with-last' queue position option to queue effects to occur in parallel with the last effect to start in the queue - -* Add new special core effect Effect.Event for one-shot events that follow timelines defined by effect queues - - new Effect.Event({ afterFinish:function(){ - // do some code here - }, position: 'end' }); - -* Do some refactoring to make use of Prototype 1.5 functionalities and save LOC - -* Fix an possible crash of IE on Effect.SlideUp, fixes #3192 [thx nel] - -* Add Builder.build() to create nodes from strings containing HTML, [DHH] - - var node = Builder.build("

this is neat!

"); - -* Add a pulses parameter to Effect.Pulsate to control the amount of pulses, fixes #6245 [leeo] - - For example, Effect.Pulsate('d8', {pulses: 2}) would pulsate twice. If the option is not given, it defaults to five pulses. - -* Fix an issue with clicking on a slider span resulting in an exception, fixes #4707 [thx sergeykojin] - -* Fix an issue with Draggables when no options are supplied, fixes #6045 [thx tdd] - -*V1.6.4* (September 6, 2006) - -* Hotfix IE issues with patched Prototype V1.5.0_rc1 - -*V1.6.3* (September 5, 2006) - -* Update Prototype to V1.5.0_rc1 - -* Merge assertElementsMatch and assertElementMatches from Prototype's [4986] unittest.js [Sam Stephenson] - -* Update Prototype to revision [4930] - -* Fix various issues with IE detection and Opera, and setOpacity, fixes #3886, #5973 - -* Make Sortable.serialize handle DOM IDs like "some_element_1" correctly, fixes #5324 - -* Add assertRespondsTo and shouldRespondTo assertions - -* Add experimental alternate syntax for unit tests (Behaviour Driven Development-style) - -* Add support for onStart, onDrag and onEnd events directly on Draggables (invoked from the Draggables.notify), fixes #4747 [thx scriptkitchen] - -* Add element shortcuts to Builder that can be activated by calling Builder.dump() (see the unit test), fixes #4260 [thx napalm] - -* Fix selection of correct option in SELECT element generated by InPlaceCollectionEditor for indexed option arrays, fixes #4789 [thx steve] - -* Add autoSelect option to Autocompleters to auto select an entry if only one is returned, fixes #5183 [thx cassiano dandrea] - -* Added delay option to Draggables and Sortables, see test/functional/dragdrop_delay_test.html for usage, implements #3325 [thx lsimon, tomg] - -* Remove revert cache code obsoleted by #4706, fixes #3436 (again) [thx tomg] - -* Fix autoscrolling inside scrollable containers when window is scrolled too, fixes #5200 [thx wseitz] - -* Make Effect.Puff work correctly for floating elements, fixes #3777 [thx michael hartl] - -* Add version and timestamp to indvidual library files for easier identification (the files are preprocessed by the Rake fresh_scriptaculous task), fixes #3015 [thx Tobie] - -* Add assertIndentical and assertNotIdentical unit test assertions, which test for equality and common type, fixes #5822 [thx glazedginger] - -* Add integration test for Ajax autocompleter for results with no linebreaks, #4149 - -* Fix an issue with redrawing ghosted draggables that are inside a scrolled container, fixes #3860 [thx gkupps, tsukue] - -* Added a custom exception to all base effects when used on non-existing DOM elements, added a assertRaise method to unit tests - -* Fix autoscrolling when dragging an element unto a scrollable container, fixes #5017 [thx tomg] - -* Fix a condition where overriding the endeffect on Draggables without overriding the starteffect too leads to a Javascript error [thx Javier Martinez] - -* Fix a possible error with the drag/drop logic (affects the solution to #4706) - -*V1.6.2* - -* Fix a problem in the drag and drop logic if an reverting/drag ending draggable was initialized for a new drag (for example by clicking repeatedly) for all cases where the default start/revert/end-effects are used, fixes #4706 [thx tecM0] - -* Fix possible memory leaks with Draggables, fixes #3436 [thx aal] - -* Throw nicer errors when requires script.aculo.us libraries are not loaded, fixes #5339 - -* Make slider handles work when not displayed initially by using CSS width/height, fixes #4011 [thx foysavas] - -* Update sortable functional test with onUpdate counter - -* Make more Element extensions unit tests work on Safari - -* Add the assertMatch unit test assertion for asserts with RegExps [thx Ian Tyndall] - -* Fix a problem with Effect.Move causing "jumping" elements because of very low float numbers in some situations - -* Fix a missing semicolon in dragdrop.js, fixes #5569 [thx mackalicious] - -* Fix a slight inaccuracy with Effect.Scale that could lead the scaling to be one pixel off - -* Be more prototypish with Effect.Transitions.linear - -* Make Effect.Scale recognize font sizes that use the pt unit, fixes #4136 [thx aljoscha] - -* Fix IE hack in Effect.Opacity, fixes #5444 [thx nicholas] - -* Fix IFRAME layout fix for IE and Autocompleter, fixes #5192 [thx tommy skaue] - -* Fix only option in onEmptyHover, fiex #5348 [thx glenn nilsson] - -* Fix Effect.BlindDown and SwitchOff handling of supplied callbacks, fixes #5089 [thx martinstrom] - -* Fix a problem with field focus on Ajax.InPlaceEditor and loading external text, fixes #4988, #5244 [thx rob] - -* Do not attempt to scroll if scrollspeed is 0/0, fixes #5035 [thx tomg] - -* Fix a problem with Sortable Tree serialization, fixes #4939, #4688, #4767 [thx Sammi Williams] - -* Fix an endless loop with sliders, fixes #3226, #4051, #4765 [thx jeff] - -* Make autocompleter work with update DIVs that have scrollbars, fixes #4782 [thx Tommy Skaue] - -* Corrected options parsing on switchoff effect, fixes #4710 [thx haldini] - -*V1.6.1* - -* Update to Prototype 1.5.0_rc0 - -* Add Draggable object as third parameter to snap, fixes #4074 [thx mdaines] - -* Fix an IE flicker with SlideUp/SlideDown, fixes #3774, [thx sbbowers] - -* Add parsing/setting of any currently set opacity CSS rule to default opacity effect on draggables, fixes #3682 [thx Mike A. Owens] - -* Added prototype $() performance patch from #4477 and updated effects.js to new Element.addMethods() syntax - -* Sortable trees [thx Sammi Williams, sammi@oriontransfer.co.nz] - - Added functional test (test/functional/sortable_tree_test.html) - - removed greedy option - - modified the way Droppables.show works - added affected list - - added Droppables.findDeepestChild - - modified Sortable.options to work for trees - - modified Sortable.onEmptyHover with additional logic to insert - the element at a certain place according to the overlap - - modified Sortable.onHover to avoid DOM Exceptions - - modified Sortable.create to support the creation of Sortable trees - - added two convenience functions - Sortable.findElements and - Sortable.findTreeElements - - Added Sortable.tree (and a number of private functions to facilitate it) - Returns a tree structure: - var root = { - id: null, - parent: null, - children: , - container: , - } - var child = { - parent: , - children: , - id: (as per options.format), - element: , - container: , - position: - } - This is intended to become part of the public API, and can be used to manipulate - the tree programatically. - - Modified Sortable.serialize to use Sortable.tree when set in the options. - -* Fix a problem with window scrolling on draggables [thx Gregory Hill] - -* Let the benchmark method return the time taken in ms, so it can be used for time-based assertions - -* Fix problem with id-based handle names and draggables - -* More Element.childrenWithClassName optimization - -* Added benchmark method to unittest.js; some cleaning up of unit tests - -* Add fix for IE memory leaks in included prototype.js from [4094] - -*V1.6.0* - -* Major speedup for sortable with handles initialization [thx Jamis Buck] - -* Update to latest Prototype 1.5.0_pre1 trunk - -* Add functional "random effects" test, also for browser compatibility testing - -* Fix two typos introduced with the 1.5 Methods syntax update - -* Add functional test for $$-triggered effects with .visualEffect - -* Fix shift-tab for autocompleter in Safari, fixes #4423 [thx matt] - -* Prepare for script.aculo.us 1.6, add Prototype 1.5 requirement and check that Element.Methods is available in the scriptaculous loader - -* Refactor effects.js to use the new Prototype 1.5 Element Methods syntax - -* Update to latest Prototype 1.5.0_pre0 trunk - -* Fix a problem with the draggable window scrolling code and scrolling inside overflow containers - -* Add passing through of scroll options from Sortable to Draggable [thx Gregory Hill] - -* Make it possible to scroll window on dragging, #3921 [thx rdmiller] - -* Make Element.forceRerendering give up on any exception (this fixes various problems with IE) - -* added visualEffect method for the Element Mixin, fixed so you can chain multiple calls. [Rick Olson] - -* Fix only option on Sortable.create to accept multiple class names, fixes #3427 [thx glenn nilsson] - -* Added workaround for a rendering bug in Safari when using floating elements with Effect.Appear - -* Update lib/prototype.js to Prototype 1.5.0_pre0 - -*V1.5.3* - -* Change version number to V1.5.3, prepare Rakefile - -* Remove unneeded height restoring in Effect.BlindDown as that is handled internally by the restoreAfterFinish option to Effect.Scale, fixes #3667 [thx Ross Lawley] - -* Added Ajax.InPlaceCollectionEditor which uses a SELECT element instead of a text field (see test/functional/ajax_inplacecollectioneditor_test.html for usage), #3491 [thx anna] - -* Enable in place editor to use RJS (implements a new evalScripts option for the in place editor), #3490 [thx Richard Livsey] - -* Added Sortable.setSequence to programmatically reorder a Sortable, #3711 [thx Mike A. Owens] - -* Added unit test for #3732 (currently fails due to Prototype #3877) [thx michal] - -* Fix span positioning for sliders with ranges not starting at 0, fixes #3731 [thx michal] - -* Make name option on Sortable.serialize work again, fixes #3873 - -* Make dragging cancel only on ESC key, not on any key, fixes #3817 - -* Fix Rakefile for V1.5.2 - -*V1.5.2* - -* Change version number to V1.5.2 - -* Fix a wrong parameter in dragdrop.js, fixes #3555 - -* Fix two typos in effects.js, fixes #3481 [thx jtolds] - -* Add assertEnumEqual for unit testing (from Prototype SVN trunk) [Sam Stephenson] - -* Add Sortable.sequence method to extract the current sequence of a Sortable as an array, fixes #3675 [thx sphivo] - -* Add limit option to effect queues to limit the maximum number of effects in a queue, new unit tests for scoped effect queues, fixes #3498 [thx Abdur-Rahman Advany] - -* Fix Element.collectTextNodesIgnoreClass to correctly filter child nodes, fixes #3380 [thx lam] - -* Fix a condition where OPTION elements could cause unwanted dragging on Draggables, fixes #3441 [thx tom] - -* Fix a crash because of an IE bug in Effect.SlideDown, fixes #3192 [thx Rob Mayhew] - -* Added experimental auto-scroll option to Draggables and Sortables, activate with scroll: 'id_of_scroll_container_element'. - Note: needs testing, call syntax might change - See test/functional/dragdrop3_test.html for usage/demo - -* Added activate method to Autocompleter that allows you to trigger the suggestions through other means than user input [DHH] - -*V1.5.1* - -* Add select option to Autocompleter to optionally use textnodes from elements with a specific CSS class (see test/functional/ajax_autocompleter_test.html for usage) - -* In-place editor: add ok/cancel visibility options and onblur() submission, fixes #3233 [thx pulsation] - Note: currently, blur form submission breaks the cancel link functionality, if enabled - -* Added Effect.toggle for slide, blind and appear/fade effects, fixes #2704 [thx Azad] - -* Added selective component loading to scriptaculous.js, see test/unit/loading_test.html for usage [thx David Zülke] - -* Added local/scoped effect queues [thx David Zülke] - -* New core effect Effect.Move that can do absolute/relative movement [thx David Zülke] - -* Make default effects options modifyable globally by setting Effect.DefaultOptions - -* Make Draggables recognize top/left CSS properties defined in an external stylesheet, fixes #3205 [thx ansonparker] - -* Fixed draggables starting to drag even if mouse button was released with no movement, [thx topfunky] - -* Updated the README to reflect final status - -*V1.5.0* - -* Prepared for V1.5.0 final - -* Update lib/prototype.js to Prototype 1.4.0 final - -*V1.5.0_rc6* - -* Update lib/prototype.js to Prototype 1.4.0_rc4 - -* Fix Effect.SlideDown/SlideUp on Internet Explorer, includes a change to Effect.Scale, (should) fix #2962 and others, [thx wyldeone] - -* Make Draggables that are reverting cancel the default revert effect when they are dragged again while reverting, fixes #3188, [thx maverick] - -* Fix a problem with a wrong reference in Effect.Pulsate, fixes #3184, [thx cyx_] - -* Fix Sortable.findElements for XHTML in Gecko, fixes #3081, [thx fgnass] - -* Fix a problem with the slider getting NaN results when clicking directly on the track, fixes #3020, [thx rectalogic] - -* Fix a problem with Safari not doing sub-pixel rendering when setting opacity to 1 with Element.setOpacity - -* Fix slider to make handle width/height count for track length, fixes #3040, fixes #3017, [thx buggedcom] - -* Added Basic unit test for Effect.inspect - -* Fix Effect.multiple to deal correctly with delays - -* Safeguard Effect.Base.render to only do updates when Effect is in running state, fixes #2912 - -* Added inspect method to Effect.Base - -* Added functional test for DOM-based UL sortables #3016 - -* Added offset option to Effect.ScrollTo - -* More effects.js/dragdrop.js refactoring - -* Refactoring and optimizations for effects (not complete yet) - -* Refactoring and optimizations for Draggables/Droppables/Sortables (not complete yet) - -*V1.5.0_rc5* - -* Make Droppables.remove accept DOM IDs in addition to elements - -* Added some unit tests for drag and drop - -* Update lib/prototype.js to Prototype 1.4.0_rc3 - -* Make 'contents' a synonym for 'content' on Effect.Scale scaleMode option - -* Fix some possible exceptions in slider.js - -* Support for various snapping options on Draggables, adresses #2826, [thx saimonmoore] - -* Support horizontal ghostable Sortables, fixes #2794, [thx johnm] - -* Prevent an exception on IE with a functional test, see #2706 - -* Add functional testing of hoverclasses for sortables - -* Add an assert for correct UTF-8 return chars in Autocompleter - -* Correct IE detection in Autocompleter for Opera, fixes #2558 [thx gary] - -* Add onDrag callback to Draggable observers, #2827 [thx saimonmoore] - -* Added Form.Element.DelayedObserver to controls.js for live-search fields - -* Remove Element.Class in favour of Prototype Element.ClassNames, new function Element.childrenWithClassName() - -* Update Copyright notice in slider.js - -* Fix slider firing onChange events to eagerly on dragging a handle [thx wombert] - -* Fix a problem with Start/End spans and single handles - -* Add event property to Slider object so that callbacks can determine if setValue originated from a UI event or from script - -* Fix Builder.node() throwing unresolved errors in IE6, #2707 [thx flwombat] - -* Give currently active handle on slider the "selected" CSS class - -* Add start and end spans to slider - -* Make track clickable for sliders (moves last active handle [or first handle] to nearest possible position) - -* Make initial values on slider work for single and multiple handle sliders - -*V1.5.0_rc4* - -* Abort Effect.Highlight on elements which have display:none set (prevents problem with Safari) - -* Make Effect.Queue an Enumerable, fix a problem with Effect.Grow, more unit tests - -* Added restricted option to prevent moved of handles prior/after adjacent handles on Sliders with multiple handles - -* Update lib/prototype.js to Prototype 1.4.0_rc2 - -* Fix a bug with wrongly scrolling to the page top in Ajax.InPlaceEditor (circumvents various browser bugs) [Jon Tirsen], #2616 - -* major slider refactoring, changed slider range to default to [0,1]. Slider Range can be set with range:$R(from,to) option. The increment option is not active for now. - -* Added spans support for Control.Slider to mark spans bordered by slider handles, see unit test [thx to www.bartenbach.de for sponsoring this functionality] - -* Added preliminary support for optional multiple handles to Control.Slider [thx to www.bartenbach.de for sponsoring this functionality] - -* Fixed wrong inclusion of libs in inplace editor functional test - -* Fixed Effect.SlideDown/SlideUp to honor refactoring of Effect.Scale, fixes #2523 [thx obiwanki] - -* Reset the zIndex on Draggables correctly, #2483 [thx Jon Whitcraft] - -* Fix onChange callback on Sortables when dragging between sortables, #2488 [thx Dylan Greene] - -* Removed Builder code from effects.js, removed Object.debug (implemented as Test.Unit.inspect) - -* Added slider unit tests, fixed handling of values to autocalculate min/max, fixed upper/lower boundaries on setting the value programmatically - -* Synced to Rails 1.0 release candidate, update to Prototype 1.4.0_rc1, removed util.js, merged rests of util.js into effects.js to prepare for refactoring - -* Give Builder it's own file - -* Fix a logic issue with Autocompleter [thx tshinnic], #2457 - -*V1.5.0_rc3* - -* Make Effect position available to callbacks - -* Droppables.fire: send event to onDrop callback [François Beausoleil], #2389 - -* InPlaceEditor: Add disabling the field while loadTextURL loads and add a class while loading, plus fix various bugs with Internet Explorer and InPlaceEditor, [Jon Tirsen] #2302, #2303 - -* Made Droppables.remove work again [thx Mindaugas Pelionis], #2409 - -* Fixed that IE6 would incorrectly render the "fix-windowed-elements-overlapping" IFRAME on autocompletion [thx tshinnic], #2403 - -* Fixed Element.getOpacity throwing an error on Safari in some situations (this caused the autocompleter not to work) - -* Added format option to Sortable.create and Sortable.serialize to allow custom id formats. The format option takes a regular expression where the first grouping that matches is used for building the parameters. The default format is /^[^_]*_(.*)$/ which matches the string_identifier format. If you want to use the full id of the elements, use "format: /(.*)/". More examples are available in the sortable unit test file. - -* Started refactorings to use the new Prototype features and general code-cleanup - -* Update lib/prototype.js to Prototype 1.4.0_pre11 - -* Fixed a typo breaking the up arrow key for autocompletion [thx tshinnic], #2406 - -* Changed the handle option on Draggbles to accept classnames, or ids or elements [thx to Andrew West], #2274 - -* Force indicator to be hidden on hiding autocompletion update element, #2342 - -* Make Draggables honor external CSS positioning [thx to Mark Shawkey], #2359 - -* Make zindex handling for Draggables honor external CSS styles - -* Fix two Sortable.serialize issues, [thx Avi, Gorou], #2339, #2357 - -* Make Element.getOpacity work with IE, added unit tests [thx to Greg Hill] - -* Make Element.setOpacity honor non-alpha filters on IE (it now works with filters for alpha PNGs) - -* Fixed that Element.class.remove wrongly deleted spaces between class names, fixes #2311, #2313 - -* Fixed Builder for OPTION and OPTGROUP tags on Firefox < 1.5 and Internet Explorer 6, completely fixes #2325 - -* Improved Builder implementation to deal with Firefox-specific requirements and innerHTML parsing, partly fixes #2325 - -*V1.5.0_rc2* - -* Update lib/prototype.js to corrected Prototype 1.4.0_pre7 (fixed a problem with IE) - -* Update lib/prototype.js to Prototype 1.4.0_pre7 - -* Reverted to patched version of Prototype 1.4.0_pre4 for the time being (getResponseHeader problem on Mozilla) - -* Attempt to fix crashes in Safari 2.0.1, probably related to the event registering und unregistering in Draggables, possibly fixes #2310 - -* Update lib/prototype.js to Prototype 1.4.0_pre6 - -* Changed effects_test.html functional test to incoporate Firefox anti-flicker overflow:hidden CSS property - -*V1.5.0_rc1* - -* Prepared Rakefile and README for V1.5.0_rc1 release - -* Droppables w/greedy and hoverclass are now reverted when dragged item is no longer over them, fixes #2184 - -* Let Effect.Highlight correctly parse IE colors, add String.prototype.parseColor() for this, fixes #2037 - -* Fix Effect.Highlight to restore background image only if there was one - -* Made Effect.tagifyText work again on IE - -* Added String.prototype.toArray because Strings aren't iterable on IE - -* Fixed Element.getOpacity falsely returning 0 on IE - -* Some cleaning up in util.js - -* Cleaned up Effect.Opacity - -* Removed useless line in Position.page - -* Make scriptaculous.js work if a query strings are used when calling it - -* Fixed typos in slider.js and the functional test - -* Fixed a bug with Safari and the InPlaceEditor with form submission. Add support for interpreting simple
s into linebreaks. [Jon Tirsen] - -* New Control.Slider() for horizontal and vertical sliders [Marty Haught] - -* Fixed autoapplying a 'layout' on IE with Effect.Opacity not working for elements given as id string - -* Make Effect.Parallel render final frames and call beforeFinish/afterFinish on included effects - -* Make Element.setOpacity work correctly again (browser-specific extensions, except for IE, are disabled at this time) - -* Added focusing the text field or text area created when using Ajax.InPlaceEditor #2126 [thx to Lee Mallabone] - -* Fixed Element.Class.childrenWith not returning the correct elements #2120 [cmees AT rogers DOT com] - -* Added MIT-LICENSE header to scriptaculous.js, cut back on license info in other libs to keep files smaller - -* Fix issues with form elements inside draggables not clickable with Firefox #2129 - -* Fixed an error in dragdrop.js with Draggables when no Droppables are defined - -* Fixed an issue with Element.makePositioned causing Effect.SlideDown to fail on Safari - -* Make effects "stateless" by cleaning up element.style after finish of effect #2133 [agr30 AT uni-koeln DOT de] - -* Add "internal" events to effects, to make them more easily extendable [Martin Bialasinski] - -* Set container element height to auto on finishing Effect.BlindDown und Effect.SlideDown #2123 [Tony Arnold] - -* Fixed a weird char in dragdrop.js - -* Controls.js Autocompleter.Base.updateElement() hook #2116 [Rob Wills] - -* Refactoring to use the Prototype enumerable extensions - -* Update to Prototype 1.4.0_pre4 - -*V1.5.0_pre4* - -* Added a queue option to effects for easy stacking and simple timeline building. Valid values are "front", "end" and "parallel" (default), see for test/functional/effects_queue_test.html for usage - -* Added a setup function to the core effects that gets called by Effect.Base when first entering into running state, which allows them to query the current state of an element or other page properties when queuing and/or delays are used - -* Added a state instance variable to Effect.Base that indicates whether a effect that uses the queue is idle, running or finished - -* Fixed a flicker with Effect.Puff - -* General code cleaning to get rid of (legitimate) Mozilla strict javascript warnings - -* Changes to assertVisible in unittest.js - -* Slight refactoring of Effect.Text, now known as Effect.multiple(), change first parameter to also accept an array of strings or elements, or a NodeList of elements (if a single element or a string is given, defaults to $('element').childNodes) - -* Made tagifyText work with IE. defaults to a style of "position: relative; zoom:1;" for the created SPAN wrappers. It also replaces spaces with non-breakable spaces. These sit-ups are required to work around problems with rendering elements with the proprietary IE "layout" and non-quirksmode documents. - -* Add a break to scriptaculous.js when the includes are done [thx to Danilo Celic] - -* Fixed a problem with the Autocompleter when hitting ESC would select the entry in IE and redisplay the entries box in Safari - -* Fixed that the onDrop callback on Droppables didn't receive the dopped element as second parameter - -* Make check for correct Prototype version on loading script.aculo.us - -* Changed implementation of Builder to an innerHTML-based approach to make it work with IE6 (note: removed special "style" handling for now) - -* Changed non-sync Effects to use a common setInterval call for better timing and page update speeds. See the new Effect.Queue object. - -* Fixed a problem with setting opacity in Effect.Opacity to very small values - -* Changed the implemention of Effect.Base to use setInterval - -* Set version number to 1.5_pre4_trunk - -* Added experimental Effect.Text function that allows to start delayed text effects, see test/functional/texteffects_test.html. - -* Added experimental Effect.tagifyText(element) which wraps an elements text nodes characters in relatively positioned span elements - -* Added "delay" option to Effect.Base to start an effect only after a specified delay - -* Finetuning unittest.js + even more unit tests - -* Added support for Firefox and Konqueror automatic unit testing on Linux [Michael Schuerig] - -* Added basic unit test files for Effects, updated unit testing tests - -* Fix typo in lib/prototype.js fix in R2069 (whoops) - -* Added unit test for Position.clone - -* Made the Postition.cumulative override recognize KHTML and AppleWebKit - -* Fix the "hide form controls" iframe fix on the Autocompleter on Internet Explorer - -*V1.5.0_pre3* - -* More positioning fixes, expanded Element.clone [thx to Michael Schuerig] - -* Fixed some JavaScript warnings about redeclared vars [Courtenay] - -* Fixed a problem with autocompleting update divs not correctly positioned inside positioned elements [thx to Jonathan Feinberg] - -* Workaround for a Safari bug on absolutely positioned children of the BODY element - -* Added test/run_functional_test.html to more easily find your way around in the functional tests - -* Fixed some missing var declarations in effects.js - -* Support for automatic unit testing on IE/Win [Jon Tirsen] - -* Added loading the text for the Ajax.InPlaceEditor from the server, more CSS support [Richard Livsey, Jon Tirsen] - -* Made builder_test.html unit test work with Safari, fixed (one of two) caching issues with javascripttest.rb, added ajax_autocompleter_test.html to Rakefile unittests - -* Fixed Element.Class getting false matches on class names like classA-foobar, added unit tests [Martin Bialasinski] - -* Added a test to evluate the Fade/Appear effects across browsers and elements (test/functional/effects6_test.html) - -* Framework for completely self-running in-browser unit tests on Mac OS X (try "rake unittest") [Jon Tirsen] - -* Updates to Ajax.InPlaceEditor (Highlighting, Ajax options, more) [Jon Tirsen] - -* Made event registering on Draggables happen per drag for improved performance [thx to Cathy] - -* Moved Element.collectTextNodesIgnoreClass to util.js (preparation for refactoring) - -* Made sortable onChange option work again - -* Fixed a bug with Sortables resulting in wrong result when using Sortable.serialize with onUpdate on ghostly Sortables [thx Richard Livsey, Caleb Buxton] - -* Changed version number in scriptaculous.js to 1.5_pre3 - -* Moved setting focus in Autocompleter to updateElement function to make it overridable [Brian Palmer] - -* Added special handling for style attributes to Builder [Michael Schuerig] - -* Changed opacity=1.0 check back to be inline with its original (pre 1.5) implementation to prevent flickering in Firefox < 1.1 on opacity-based effects (this also fixes flickering with drag-and-drop, sortable lists and autocompleting text fields). Note that this potentially breaks correct colors in some situations. [thx to David Zülke] - -* Automatically deactivate browser built-in autocompletion on autocompleting textfields, fixes part of Rails #1824. - -* Fixed a problem with Ajax.InPlaceEditor causing a JavaScript exception on Safari [thx to Patrick Lenz] - -*V1.5.0_pre2* - -* Fixed a weird character in dragdrop.js, added check to allow empty containers on Sortables (useful with dropOnEmpty option) [thx to Dave Strus] - -* Added unit test runner file test/run_unit_tests.html, new unit test files must be listed in test/unit/index.html - -* Added unit tests for Prototype string functions - -*V1.5.0_pre1* - -* Prepared README for V1.5.0_pre1 - -* Added a main scriptaculous.js file to load in the other libraries transparently: - - - - - in the HEAD section of an HTML file is now all that's needed to include all of the script.aculo.us libraries, - given that they all can be accessed by the same path as scriptaculous.js is. - -* Fixed possible problem with greedy Droppables when using the dropOnEmpty option on Sortable.create - -* Added new CSS/background color features to Ajax.InPlaceEditor [Jon Tirsen] - -* Added unit test for Autocompleter, first Version - -* Added Event.simulateKey/s to unittest.js. Note that due to a bug in Firefox this will only work with Firefox up to v1.0.4 (see https://bugzilla.mozilla.org/show_bug.cgi?id=289940) - -* Fixed a condition where standard a href=xxx links wouldn't work in autocomplete results. These do now, the onclick event is not cancelled. [thx to Jasper Slits] - -* Fix showing ghosting marker only on ghosting Sortables - -* Some more Builder stuff, expanded builder unit tests - -* Moved stuff that didn't belong into specific libs into util.js; util.js is now required for all script.aculo.us libs - -* Corrected weirdness in unittest.js - -* Added dropOnEmpty option to Sortables to allow dropping on empty lists (see test/functional/sortable3_test.html) - -* Changed algoritm for drag/drop position setting - -* Changed workaround for class attributes (fixes a Firefox 1.0 error) from klass to className to be more Javascriptesque [thx to Martin Bialasinski] - -* Fixed a typo in ajax_inplaceeditor_test.html - -* Updated Rakefile to add unittest.js and util.js to the package - -* Added util.js which contains various utlity functions and extensions to Prototype - -* Major restructuring - -* Added TEXTAREA support to Ajax.InPlaceEditor [Sanford Barr] - -* Added Ghost Train alpha 0.1.0. See ghosttrain/test.html. - -* More features for Ajax.InPlaceEditor [Jon Tirsen] - -* Tweaks to unittest.css [Thomas Fuchs] - -* Refactoring and new features in unittest.js [Thomas Fuchs] [Jon Tirsen] - -* Fixed a wrong variable reference in Effect.Scale - -* Fix Element.makePositioned to recognize the 'static' position - -* Allow to choose the parameter name for Ajax.Autocompleter [Cameron Braid] - -* Changed resolving indicator DOM element more flexibility [Cameron Braid] - -* Fixed a reference in Ajax.InPlaceEditor - -* Added contributors to unittest.js - -* Souped-up Ajax.InPlaceEditor, added support for a form id and specifying all the texts through options [Jon Tirsen] - -* Make unit testing look good [Michael Schuerig] - -* Changed default revert duration for Draggables to distance-dependent algorithm [suggested by San] - -* Fix double unescaping in Autocompleter - -* Refactoring auf Autocompleter classes to use camelCase (note: changes the syntax of some of the options) - -* Add updateElement option to Autocompleter [Rob Sharp] - -* Updated Ajax.InPlaceEditor, refactoring of unit testing [Jon Tirsen] - -* Added preliminary version of Ajax.InPlaceEditor to controls.js; added experimental Firefox only functional testing for it (inplaceeditor_result.html) [Jon Tirsen] - -* Added some addtional test files. - -* Fixes a bug with Droppables not recognizing a drop if no hoverclass is given [thanks drewie] - -* Fixes to ghosting marker, allow a predefined marker (element with id "dropmarker"). - -* Changed Effect.Opacity to better handle 100% opacity - -* Various fixes to ghosting, improves compatiblity with Safari and IE. [thanks to David Zülke] - -* Added experimental ghosting option to Sortables. See sortable_functional_ghosting.html for usage. - -* Renamed the clone option on Draggables to "ghosting". - -* Added experimental "clone" option to Draggable to so that a "clone" stays in place while dragging a translucent version of the draggable element. Currently, this requires relatively positioned elements, and doesn't work with sortable lists (but should after some tweaking). See dragdrop_function_4.html test file for details. - -* Added Element.getStyle to find computed CSS styles of an element. Note: doesn't work in all cases in Safari, see my bug report at http://bugzilla.opendarwin.org/show_bug.cgi?id=4125 - -*1.1beta1* - -* Fixed rendering of last frame of animation when from/to is not 0.0/1.0. [thanks to David Zülke] - -* Updated internal Prototype JavaScript framework to version 1.4.0_pre2 (patched w/ workaround for Ajax.Updater init bug) - -* Some refactoring of controls.js to get rid of "dirty" implementation detail (dont' ask) - -* Added returning the generated combined effects to allow for .cancel() on all effects - -* Updated internal Prototype JavaScript framework to version 1.4.0_pre2 - -*Rails 0.13.1* - -* Updated Ajax.Autocompleter to deal with parameters options correctly [Martin Marinschek] - -* Updated controls.js to allow multple matches in local localcompletion [Ivan Krstic] - -* Make version of prototype.js in lib have a nicer Event object [David Zülke] - -* Added incremental and local autocompleting and loads of documentation to controls.js [Ivan Krstic] - -* Experimental: make version of prototype.js in lib destroy events on page unload to prevent browser memory leaks - -* Fixed a possible memory leak in dragdrop.js - -* Make version of prototype.js in lib compatible with some 3rd-party JavaScript libraries (like IE7) by refactoring to use Object.extend() for testing [David Zülke] - -* Make effects.js, dragdrop.js and controls.js compatible with some 3rd-party JavaScript libraries (like IE7) by refactoring to use Object.extend() [David Zülke] - -* Changed some tests to work better - -* Always reset background color on Effect.Highlight; this make change backwards-compatibility, to be sure include style="background-color:(target-color)" on your elements or else elements will fall back to their CSS rules (which is a good thing in most circumstances) - -* Removed a possible memory leaks with IE with sortables and droppables (removed references from elements) - -* Changes to class extension in effects.js - -* Make Effect.Highlight restore any previously set background color when finishing (makes effect work with set CSS classes) - -* Added capability to remove draggables/droppables and redeclare sortables in dragdrop.js - -* Added Effect.ScrollTo to smoothly scroll the page to an element - -* Better Firefox flickering handling on SlideUp/SlideDown - -* Some cleaning up in effects.js - -* Removed a possible memory leak in IE with draggables - -* Added support for cancelling dragging my hitting ESC - -* Changed logic of drag-and-drop to only include the last referenced droppable when firing a drop event. This change also offers slight performance gains. [Dominik Wagner] - -* Added addtional effects test page, added tests for scriptfragment matching - -*1.0.0* - -* Changed auto-hiding update div in Ajax.Autocompleter - -* Changed default serialization on Ajax.Autocompleter to use Form.Element.serialize - -* Added test file for drag/drop inside scrolled elements - -* Fixed dragging of unpositioned elements in Internet Explorer - -* Change default behaviour of Ajax.Autocompleter to do automatic overlapping, sizing and appear/fade effects - -* Fixed Internet Explorer hide-windowed-controls iframe handling - -* Changed Ajax.Autocompleter event handling - -* Added onShow/onHide callbacks to Ajax.Autocompleter to allow for customized handling/effects - -* Fixed SlideUp/SlideDown to restore the overflow CSS property (note: Firefox 1.0.X is buggy, set overflow:hidden as a workaround) - -* Fixed BlindUp/BlindDown to restore the overflow CSS property (note: Firefox 1.0.X is buggy, set overflow:hidden as a workaround) - -* Fixed draggables with revert:false on repeated drags behaving badly - -* Expanded the revert option on draggables to optionally take a function and revert only if it returns true - -* Added the dragged element as a parameter to the Draggables.notify callbacks [Michael Sokolov] - -* Removed a deprecated reference to Effect2 om Effect.Fold - -* Make the percentage on Element.setContentZoom absolute - -* Corrected rendering of Ajax.AutoCompleter when focus is lost while updating - -* Added (crude) functional tests - -* Some slight refactoring in controls.js - -* Changed dragdrop.js to use the Effect namespace for its effects - -* Updated to Prototype 1.3.0: removal of prototype-ext.js; refactoring. - -* Fixed behaviour of cursor keys in Safari on autocomplete script - -* Fixed Position.within_including_scrolloffsets - -* Fixed sortables that are absolutely positioned - -* Fixed unhandled whitespace in Ajax.Autocompleter - -* Updated prototype-ext.js to include additions for Ajax.Autocompleter - -* Added controls.js, contains AJAX autocompleting text fields from #960 - -* Refactored Event object - -* Renamed effects2.js to effects.js - -* Fixed draggables on pages with no droppables - -* Moved Event, Position and Element.Class to prototype-ext.js in preparation to Rails 0.13 - -* Added Effect.Transitions.pulse - -* Added Effect.Pulsate and Effect.Fold effect by Justin Palmer - -* Added transitions by Mark Pilgrim: .full, .none - -* Added effects by Mark Pilgrim: Effect.Grow, Effect.Shrink - -* Changed effects namespace to Effect. (Effect2 is deprecated, but works too) - -* Changed old Effect.ContentZoom class to Element.setContentZoom() function - -* Greatly expanded Effect.Highlight to have user-defined colors and autodetecting the background color - -* Converted remaining effects (Squish, Highlight) to new format - -* Sortable.create now passes the zindex, starteffect, reverteffect and endeffect options to the underlying Draggables - -* Sortable.serialize now honors the only option on Sortable.create - -* New overridable options on Draggables: zindex, starteffect, reverteffect, endeffect - -* Fix a Gecko engine flicker on Sortables in dragdrop.js - -* Fixed event.isLeftClick - -* Some small changes in effects2.js - -* Refactoring of dragdrop.js - -* Added an Object.prototype.inspect() and more verbose messages for js unit testing - -* Added test/unittest.js and initial tests in test/html. - -* Cleaning up of effects2.js (convert tabs to spaces) - -* Added Rakefile for distribution packaging (default task = make distribution, rake clean for cleaning up) - -* Initial check-in and directory layout for the script.aculo.us JavaScripts diff --git a/MIT-LICENSE b/MIT-LICENSE deleted file mode 100644 index da26ff0..0000000 --- a/MIT-LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -Copyright (c) 2005-2010 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) - -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. \ No newline at end of file diff --git a/README.rdoc b/README.rdoc deleted file mode 100644 index 21f8c8c..0000000 --- a/README.rdoc +++ /dev/null @@ -1,59 +0,0 @@ -== script.aculo.us web 2.0 javascript - -The Web is changing. The 30-year-old terminal-like technology it was originally -is gradually giving way to new ways of doing things. The power of AJAX allows -for rich user interaction without the trouble that has bugged traditional -web applications. - -Building upon the wonderful Prototype JavaScript library, script.aculo.us -provides you with some great additional ingredients to mix in. - -For more information, see http://script.aculo.us/ - -== What's new in this release? - -See the CHANGELOG file for information on what's new. - -You can follow http://twitter.com/scriptaculous if you want -to be updated as we fix bugs and add new features. - -== Installation/Usage - -script.aculo.us includes the Prototype JavaScript Framework -V1.6.0. You can use later versions, as they become available -(see http://prototypejs.org/). - -Put prototype.js, and the six files scriptaculous.js, -builder.js, effects.js, dragdrop.js, controls.js and slider.js -in a directory of your website, e.g. /javascripts. - -(The sound.js and unittest.js files are optional) - -Now, you can include the scripts by adding the following -tags to the HEAD section of your HTML pages: - - - - -scriptaculous.js will automatically load the other files of the -script.aculo.us distribution in, provided they are accessible -via the same path. - -See http://wiki.script.aculo.us/scriptaculous/show/Usage for detailed -usage instructions. - -== The distribution - -Besides the script.aculo.us files in src, there's a complete -test tree included which holds functional and unit tests for -script.aculo.us. - -If you need examples on how to implement things, the best place to -start is by opening test/run_functional_tests.html or -test/run_unit_tests.html in your browser, and looking at -the sources of the examples provided. - -== License - -script.aculo.us is licensed under the terms of the MIT License, -see the included MIT-LICENSE file. \ No newline at end of file diff --git a/README.textile b/README.textile new file mode 100644 index 0000000..be38005 --- /dev/null +++ b/README.textile @@ -0,0 +1,11 @@ +h2. Scriptaculous Documentation on GitHub Pages + +Since the new GitHub wikis do not support inline JavaScript, script.aculo.us is moving its documentation to "GitHub Pages":http://pages.github.com/ as the old GitHub wiki is being phased out. This makes collaboration on documentation the same workflow as collaboration the script.aculo.us source code. + +h3. Contributing to the documentation + +All documentation is under the @gh-pages@ branch. To edit the documentation, fork "the script.aculo.us project":http://wiki.github.com/madrobby/scriptaculous/ and edit the documentation under the @gh-pages@ branch in your fork. When you are finished editing your documentation, please send a pull request from your repository explaining the changes you wish to pull. The primary project collaborators will be notified. + +h3. Getting started with GitHub Pages + +New documentation can be written in Textile or HTML. For more on what GitHub pages supports, "visit the GitHub pages overview":http://pages.github.com/ and read about pages. For more on contributing to script.aculo.us, "read the Contribute page":http://madrobby.github.com/scriptaculous/contribute/ to learn how you can help. diff --git a/Rakefile b/Rakefile deleted file mode 100644 index d1e91d6..0000000 --- a/Rakefile +++ /dev/null @@ -1,107 +0,0 @@ -#mostly borrowed from the rails Rakefile - -require 'rake' - -PKG_NAME = 'scriptaculous-js' -PKG_BUILD = ENV['PKG_BUILD'] ? '.' + ENV['PKG_BUILD'] : '' -PKG_TIMESTAMP = Time.new.to_s -PKG_VERSION = '1.8.3' + PKG_BUILD -PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}" -PKG_DESTINATION = ENV["PKG_DESTINATION"] || "dist" - -RAILS_RAILTIES = (ENV["RAILS_ROOT"] || '../rails-trunk') + '/railties/html/javascripts' -RAILS_ACTIONVIEW = (ENV["RAILS_ROOT"] || '../rails-trunk') + '/actionpack/lib/action_view/helpers/javascripts' - -desc "Default Task" -task :default => [ :clean, :fresh_scriptaculous, :package ] - -task :clean do - rm_rf PKG_DESTINATION -end - -PKG_FILES = FileList[ - 'CHANGELOG', - 'README.rdoc', - 'MIT-LICENSE', - 'lib/prototype.js', - 'test/**/*.html', - 'test/**/*.css', - 'test/**/*.png', - 'test/**/*.mp3' -] - -SRC_FILES = FileList[ - 'src/scriptaculous.js', - 'src/dragdrop.js', - 'src/effects.js', - 'src/controls.js', - 'src/unittest.js', - 'src/builder.js', - 'src/slider.js', - 'src/sound.js', - 'src/unittest.js' -] - -RAILS_FILES = FileList[ - 'src/effects.js', - 'src/dragdrop.js', - 'src/controls.js' -] - -DIRS = %w( src lib test test/functional test/unit ) - -desc "Make a ready-for-packaging distribution dir" -task :fresh_scriptaculous do - mkdir PKG_DESTINATION - mkdir File.join(PKG_DESTINATION, PKG_FILE_NAME) - mkdir_p DIRS.map { |dir| File.join(PKG_DESTINATION, PKG_FILE_NAME, dir) } - PKG_FILES.each { |file| cp file, File.join(PKG_DESTINATION, PKG_FILE_NAME, file) } - SRC_FILES.each do |file| - File.open(File.join(PKG_DESTINATION, PKG_FILE_NAME, file), 'w+') do |dist| - dist << ('// script.aculo.us '+File.basename(file)+' v'+PKG_VERSION+", "+PKG_TIMESTAMP+"\n\n") - dist << File.read(file) - end - end -end - -desc "Packages the fresh script.aculo.us scripts" -task :package do - system %{cd #{PKG_DESTINATION}; tar -czvf #{PKG_FILE_NAME}.tar.gz #{PKG_FILE_NAME}} - system %{cd #{PKG_DESTINATION}; zip -r #{PKG_FILE_NAME}.zip #{PKG_FILE_NAME}} - system %{cd #{PKG_DESTINATION}; tar -c #{PKG_FILE_NAME} | bzip2 --best > #{PKG_FILE_NAME}.tar.bz2 } -end - -desc "Update rails trunk to latest script.aculo.us" -task :update_rails do - RAILS_FILES.each do |file| - cp file, File.join(RAILS_RAILTIES, File.basename(file)) - cp file, File.join(RAILS_ACTIONVIEW, File.basename(file)) - end -end - -require 'src/javascripttest' -desc "Runs all the JavaScript unit tests and collects the results" -JavaScriptTestTask.new(:unittest) do |t| - t.mount("/lib") - t.mount("/src") - t.mount("/test") - - t.run("/test/unit/loading_test.html") - t.run("/test/unit/unittest_test.html") - t.run("/test/unit/bdd_test.html") - t.run("/test/unit/effects_test.html") - t.run("/test/unit/ajax_autocompleter_test.html") - t.run("/test/unit/ajax_inplaceeditor_test.html") - t.run("/test/unit/slider_test.html") - t.run("/test/unit/string_test.html") - t.run("/test/unit/builder_test.html") - t.run("/test/unit/element_test.html") - t.run("/test/unit/dragdrop_test.html") - t.run("/test/unit/sortable_test.html") - t.run("/test/unit/position_clone_test.html") - - t.browser(:safari) - t.browser(:firefox) - t.browser(:ie) - t.browser(:konqueror) -end \ No newline at end of file diff --git a/_config.yml b/_config.yml new file mode 100644 index 0000000..b77c36f --- /dev/null +++ b/_config.yml @@ -0,0 +1,3 @@ +permalink: /:title +auto: true +server: true \ No newline at end of file diff --git a/_layouts/default.html b/_layouts/default.html new file mode 100644 index 0000000..c3c2a89 --- /dev/null +++ b/_layouts/default.html @@ -0,0 +1,53 @@ + + + + {{ page.title }} — Scriptaculous Documentation + + + + + + + + +
+

{{ page.title }}

+
+ {{ content }} +
+ + + +
+ + + + + + \ No newline at end of file diff --git a/_posts/2009-01-01-ajax-autocompleter.html b/_posts/2009-01-01-ajax-autocompleter.html new file mode 100644 index 0000000..ee64243 --- /dev/null +++ b/_posts/2009-01-01-ajax-autocompleter.html @@ -0,0 +1,166 @@ +--- +layout: default +title: Ajax.Autocompleter +category: Controls +--- + +
+ +

Controls > Ajax.Autocompleter

+

Introduction

+

Ajax.Autocompleter allows for server-powered autocompleting text fields.

+

Syntax

+
new Ajax.Autocompleter(id_of_text_field, id_of_div_to_populate, url, options);
+
+

Options (Inherited from Autocompleter.Base, as well as all options for Prototype’s Ajax.Request )

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
OptionDefault ValueDescription
paramNamethe ‘name’ of the elementName of the parameter for the string typed by the user on the autocompletion field
tokens[] Tokenized incremental autocompletion is enabled automatically when an autocompleter is instantiated with the ‘tokens’ option in the options parameter: See Also Autocompleter.Base
frequency0.4How frequently (in seconds) the input field should be polled for changes before firing an Ajax request.
minChars1The minimum number of characters that must be entered in the input field before an Ajax request is made.
selectnullThe class name of the element that contains the text to be placed into the input box. By default all text will be used.
indicatornullThe HTML id of an element to display (using Element.show) while the Ajax request is in progress. This element will be hidden with Element.hide when the request is completed. This is useful for displaying an animated spinner during processing. See Ajaxload for some image examples.
updateElementnullHook for a custom function to replace the built-in function that adds the list item text to the input field. The custom function is called after the element has been updated (i.e. when the user has selected an entry). The function receives one parameter only: the selected item (the <li> item selected)
afterUpdateElementnullHook for a custom function that’s called following the execution of the built-in function that adds the list item text to the input field, which happens after a user has selected an entry. (The difference between updateElement and afterUpdateElement is that updateElement replaces the built-in Autocompleter function; afterUpdateElement supplements that built-in function.) The function receives two parameters, the input field specified for autocompletion, and the selected item (the <li> item selected)
callbacknullThis function is called just before the Request is actually made, allowing you to modify the querystring that is sent to the server. The function receives the completer’s input field and the default querystring (‘value=XXX’) as parameters. You should return the querystring you want used, including the default part.
parametersnullTo send additional parameters to the server, add them here in the format: 'field=value&another=value'. Errata/bug: The hash format {field: 'value',another: 'value'} was noted in this wiki to work, but it does not, as the Ruby on Rails project has separately documented and fixed in their codebase.
+

Example

+

HTML
+

<input type="text" id="autocomplete" name="autocomplete_parameter"/>
+<div id="autocomplete_choices" class="autocomplete"></div>
+

+

Javascript
+

new Ajax.Autocompleter("autocomplete", "autocomplete_choices", "/url/on/server", {});
+

+

HTML with indicator
+

<input type="text" id="autocomplete" name="autocomplete_parameter"/>
+<span id="indicator1" style="display: none">
+  <img src="/images/spinner.gif" alt="Working..." />
+</span>
+<div id="autocomplete_choices" class="autocomplete"></div>
+

+

(As with any element destined to work with Prototype’s Element.toggle/show/hide, your indicator element should use an inline style attribute with a display property, here initially set to none. If you need to assign it CSS rules, put the class attribute before the style attribute to avoid override.)

+

Javascript with options
+

new Ajax.Autocompleter("autocomplete", "autocomplete_choices", "/url/on/server", {
+  paramName: "value", 
+  minChars: 2, 
+  indicator: 'indicator1'
+});
+

+

CSS
+The styling of the div and the returned UL are important.
+Applying a visual cue that an item is selected allows the user to take advantage of the keyboard navigation of the dropdown and adding background colors, borders, positioning, etc to the div (as the demo does) allows the UI element to stand out. The CSS from the demo applied to the examples would be:

+
div.autocomplete {
+  position:absolute;
+  width:250px;
+  background-color:white;
+  border:1px solid #888;
+  margin:0;
+  padding:0;
+}
+div.autocomplete ul {
+  list-style-type:none;
+  margin:0;
+  padding:0;
+}
+div.autocomplete ul li.selected { background-color: #ffb;}
+div.autocomplete ul li {
+  list-style-type:none;
+  display:block;
+  margin:0;
+  padding:2px;
+  height:32px;
+  cursor:pointer;
+}
+
+

Tokenized autocompletion

+

Tokenized incremental autocompletion is enabled automatically when an autocompleter is instantiated with the ‘tokens’ option in the options parameter:

+
new Ajax.Autocompleter('id','upd', 'url', { tokens: ',' });
+

will incrementally autocomplete with a comma as the token.

+

Additionally, ’,’ in the above example can be replaced with a token array, e.g. tokens: [',', '\n'] which enables autocompletion on multiple tokens. This is most useful when one of the tokens is \n (a newline), as it allows smart autocompletion after linebreaks.

+

Server Return

+

Look through your POST environment variable for the current entry in the text-box.

+

The server-side will receive the typed string as a parameter with the same name as the name of the text field element of the autocompletion (its name attribute). You can override it by setting the option paramName.

+

The server must return an unordered list.
+For instance, this list might be returned after the user typed the letter “y”

+
<ul>
+    <li>your mom</li>
+    <li>yodel</li>
+</ul>
+
+

If your search returns no results, it is critical that your server immediately return an empty list, rather than nothing. You will only notice this need if you use an indicator to show server activity — the indicator will never go away if your server doesn’t return an empty list.

+

If you wish to display additional information in the autocomplete dropdown that you don’t want inserted into the field when you choose an item, surround it in a <span> (could work with others but not tested) with the class of “informal”.

+

For instance, the following shows a list of companies and their addresses, but only the company name will get inserted:

+
<ul>
+    <li>ACME Inc <span class="informal"> 5012 East 5th Street</span></li>
+    <li>Scriptaculous <span class="informal"> 1066 West Redlands Parkway</span></li>
+</ul>
+
+

Another way to get additional information is to encode an ID into each list item, and redefine the afterUpdate Element to handle that ID:

+
<ul>
+    <li id="1">your mom</li>
+    <li id="2">yodel</li>
+</ul>
+
+
new Ajax.Autocompleter("autocomplete", "autocomplete_choices", "/url/on/server", {
+  afterUpdateElement : getSelectionId
+});
+
+function getSelectionId(text, li) {
+    alert (li.id);
+}
+
+

Notes

+

When a choice is highlighted, the Autocompleter applies a class of “selected” to the li element. This allows the use of CSS to style the selected element.

+

Tutorials

+

A short tutorial on using Autocompleter, together with Ruby and WEBrick, prepared for the Linux Users Group, Villafranca, Verona, Italy.

+ +
\ No newline at end of file diff --git a/_posts/2009-01-01-ajax-inplacecollectioneditor.html b/_posts/2009-01-01-ajax-inplacecollectioneditor.html new file mode 100644 index 0000000..a5a67a5 --- /dev/null +++ b/_posts/2009-01-01-ajax-inplacecollectioneditor.html @@ -0,0 +1,137 @@ +--- +layout: default +title: Ajax.InPlaceCollectionEditor +category: Controls +--- + +
+ + +

Controls > Ajax.InPlaceCollectionEditor

+

Introduction

+

This constructor generates a Flickr-style AJAX-based “on-the-fly” fields with a select box instead of Ajax.InPlaceEditor text fields.

+

Syntax

+
new Ajax.InPlaceCollectionEditor( element, url, { collection: [array], [moreOptions] } );
+

The constructor takes three parameters. The first is the element that should support in-place editing. The second is the url to submit the changed value to. The server should respond with the updated value (the server might have post-processed it or validation might have prevented it from changing). The third is a hash of options. Within that hash of options should be a field called collection that is an array of values to place inside your select box.

+

The server side component gets the new value as the parameter ‘value’ (POST method), and should send the new value as the body of the response.

+

If the collection parameter (or the result of the loadCollectionURL) is a one-dimensional array, the option tag’s value attribute will be the same as the label. For explicit value attributes, use a two dimensional array for the collection where the second dimension is a key value pair such as [['key', 'value'], ['key', 'value']].

+

Options

+

The Ajax.InplaceCollectionEditor takes all the options as Ajax.InPlaceEditor plus:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NamesincedefaultDescription
collection V?? none Array of static elements to be displayed as options (in JSON format)
loadCollectionURL V1.5 null Loads values and tag texts for the <option> tags
loadingCollectionText V?? null Text to be displayed while the collection is loading
loadingClassName V?? null Class applied to form while the collection is loading
+

Static Collection

+

The values for the collection of options are specified as an array when you invoke the Ajax.InPlaceCollectionEditor. Each element in the array will be rendered as an <option> in a <select> element for the user to choose from.

+
+
+new Ajax.InPlaceCollectionEditor( element_1, '/url_to_validate_and_save_selection/', { 
+  collection: ['value one', 'value two', 'value three'] 
+});
+
+new Ajax.InPlaceCollectionEditor( element_2, '/url_to_validate_and_save_selection/', { 
+  collection: [['key_1', 'value one'], ['key_2', 'value two'], ['key_3', 'value three']] 
+});
+
+
+

Dynamic Collection

+

The collection is loaded in the same format but is loaded as the response from a URL in the loadCollectionURL parameter. The response from that URL should be an array in JSON format.

+

In Rails, it can be done like this:
+


+

+
    +
  1. /url_to_load_collection /
    +def my_collection
    + @collection = SomeModel.all
    + respond_to do |format|
    + format.json { render :json => @collection.map{ |c| [c.id, c.title] } }
    + end
    +end
    +
    +
  2. +
+
+
+new Ajax.InPlaceCollectionEditor( element_3, '/url_to_validate_and_save_selection/', { 
+  loadCollectionURL: '/url_to_load_collection/' 
+});
+
+
+

Demo

+
+
+<p id="editme">Click me, click me!</p>
+<script type="text/javascript">
+ new Ajax.InPlaceCollectionEditor(
+   'editme', 
+   '/demoajaxreturn.html', 
+   { collection: ['one','two','three'],
+     ajaxOptions: {method: 'get'} }
+  );
+</script>
+
+
+
+

three

+

(should autoselect “three”)

+ +
+

Examples

+

You may want to send the Ajax request directly to update method in Rails to be RESTful. You can do it like this, using the callback option:

+
+
+<script>
+new Ajax.InPlaceCollectionEditor(
+  '<%= dom_id(person) %>_role_title',
+  '<%= person_path(person, :authenticity_token => form_authenticity_token) %>',
+  { loadCollectionURL: '<%= formatted_roles_people_path(:json,  
+                            :authenticity_token => form_authenticity_token) %>',
+    callback: function(form, value) {
+      return 'value=' + encodeURIComponent(value) +
+             '&person[role_id]=' + encodeURIComponent(value) +
+             '&_method=PUT' // Fix the HTTP METHOD for the update action!!!
+    },
+    ajaxOptions: { method: 'post' } 
+  }
+);
+</script>
+
+
+
\ No newline at end of file diff --git a/_posts/2009-01-01-ajax-inplaceeditor.html b/_posts/2009-01-01-ajax-inplaceeditor.html new file mode 100644 index 0000000..b244129 --- /dev/null +++ b/_posts/2009-01-01-ajax-inplaceeditor.html @@ -0,0 +1,639 @@ +--- +layout: default +title: Ajax.InPlaceEditor +category: Controls +--- + +
+ +

Controls > Ajax.InPlaceEditor

+ +

Introduction

+

The in-place “text edit” testing allows for Flickr-style AJAX-backed “on-the-fly” textfields.
+See the documentation on Ajax.InPlaceEditor and Ajax.InPlaceCollectionEditor

+

Syntax

+
new Ajax.InPlaceEditor( element, url, {options});
+

The constructor takes three parameters. The first is the element that should support in-place editing. The second is the url to submit the changed value to. The server should respond with the updated value (the server might have post-processed it or validation might have prevented it from changing). The third is a hash of options.
+The server side component gets the new value as the parameter ‘value’ (POST method), and should send the new value as the body of the response.

+

Options

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NamesincedefaultDescription
okControl V?? “button” What type of ok button to use in edit mode, or none at all (button, link, false)
cancelControl V?? “link” What type of cancel button to use in edit mode, or none at all (button, link, false)
okText V1.5 “ok” The text of the submit button that submits the changed value to the server
cancelText V1.5 “cancel” The text of the link that cancels editing
savingText V1.5 “Savingâ€Ĥ” The text shown while the text is sent to the server
clickToEditText V1.6 “Click to edit” The text shown during mouseover the editable text
formId V1.5 id of the element to edit plus ‘InPlaceForm’ The id given to the element
externalControl V1.5 null ID of an element that acts as an external control used to enter edit mode. The external control will be hidden when entering edit mode and shown again when leaving edit mode.
externalControlOnly V1.5 false Whether or not to disable onclick editing so that only an external control can activate editable mode
rows V1.5 1 The row height of the input field (anything greater than 1 uses a multiline textarea for input)
onComplete V1.6 “function(transport, element) {new Effect.Highlight(element, {startcolor: this.options.highlightColor});}” Code run if update successful with server. Also if user cancels the form. See bug.
onFailure V1.6 “function(transport) {alert(“Error communicating with the server: ” + transport.responseText.stripTags());}” Code run if update failed with server
cols V1.5 none The number of columns the text area should span (works for both single line or multi line)
size V1.5 none Synonym for ‘cols’ when using single-line (rows=1) input
highlightColor ? Ajax.InPlaceEditor.defaultHighlightColor The highlight color. Must be six hex digits, not 3.
highlightEndColor ? ”#FFFFFF” The color which the highlight fades to. Must be six hex digits, not 3.
savingClassName V1.5 “inplaceeditor-saving” CSS class added to the element while displaying “Savingâ€Ĥ” (removed when server responds)
formClassName V1.5 “inplaceeditor-form” CSS class used for the in place edit form
hoverClassName ? ? ?
loadTextURL V1.5 null Will cause the text to be loaded from the server (useful if your text is actually textile and formatted on the server)
loadingText V1.5 “Loadingâ€Ĥ” If the loadText URL option is specified then this text is displayed while the text is being loaded from the server
callback V1.5 function(form) {Form.serialize(form)} A function that will get executed just before the request is sent to the server, should return the parameters to be sent in the URL. Will get two parameters, the entire form and the value of the text control.
submitOnBlur V1.6 “false” This option if true will submit the in_place_edit form when the input tag loses focus.
ajaxOptions V1.5 {} Options specified to all AJAX calls (loading and saving text), these options are passed through to the prototype AJAX classes.
+

The server side component gets the new value as the parameter ‘value’ (POST method), and should send the new value as the body of the response.

+

Character encoding

+

The form data is sent encoded in UTF-8 regardless of the page encoding. This is as of the prototype function Form.serialize. More info on here.

+

If this doesn’t work, you can use iconv as outlined here. Link Dead!

+

Removing the behavior

+

To disable the InPlaceEditor behavior later on, store it in a variable like:

+

+ var editor = new Ajax.InPlaceEditor('product_1',...);
+ (... do stuff ..)
+ editor.dispose();
+
+

This way, you can enable and disable " In Place Editing ":http://madrobby.github.com/scriptaculous/in-place-editing at will.

+

You can also arbitrarily force it into edit mode like so:

+

+editor.enterEditMode('click');
+
+

Demo1 (Single Line Edit Mode)

+

note: the demo doesn’t actually save its changes, as demoajaxreturn.html is not a valid url.

+

+<p id="editme">Click me, click me!</p>
+<script type="text/javascript">
+ new Ajax.InPlaceEditor('editme', '/demoajaxreturn.html');
+</script>
+
+
+

Click me, click me!

+ +
+

Demo2 (Multi Line Edit Mode)

+

+<p id="editme2">Click me to edit this nice long text.</p>
+<script type="text/javascript">
+ new Ajax.InPlaceEditor('editme2', '/demoajaxreturn.html', {rows:15,cols:40});
+</script>
+
+
+

Click me to edit this nice long text.

+ +
+

How to specify a different name for the parameter sent to the server

+

Add a callback function which is supposed to return the parameters that is sent to the server. Like this:

+

+new Ajax.InPlaceEditor('id', 'url', {
+callback: function(form, value) { return 'myparam=' + encodeURIComponent(value) }
+})
+
+

The encodeURIComponent() makes sure values containing special characters like “&” or “=” don’t cause problems. Use encodeURIComponent() instead of escape() from previous examples to get UTF-8 encoded data (and not “malformed URI” errors in Firefox). This function can also be used to pass additional parameters, such as what item or field to edit:

+

+new Ajax.InPlaceEditor('id', 'url', { 
+callback: function(form, value) { return 'item=123&field=description&myparam='+encodeURIComponent(value) }
+})
+
+

Note: this parameters name may change (to “parameters” or “with”) before the final release of 1.5.

+

How to execute custom code using the InPlaceEditor’s callbacks.

+

+new Ajax.InPlaceEditor(id, url, {
+callback: function(form, value) { return 'item=123&field=description&myparam='+encodeURIComponent(value) },
+onEnterEditMode: function(form, value) { // custom code goes here... },
+onLeaveEditMode: function(form, value) { // custom code goes here... }
+});
+
+

You can find all the possible callbacks by looking for lines in the source like this:

+

+this.triggerCallback('onEnterEditMode');
+
+

(Should these callback options be documented in the Options list above?)

+

How to add a spinning in progress indicator

+

Get an animated .gif that shows progress (the spinning image used on the Macintosh for example). Add a CSS class for ‘inplaceeditor-saving’ with the spinning image as background. The class will be added to the element during communication with the server and removed afterwards.

+

+<style type="text/css" media="screen">
+  .inplaceeditor-saving { background: url(/images/wait.gif) bottom right no-repeat; }
+</style>
+
+<p id="editme3">Click me, click me!</p>
+<script type="text/javascript">
+ new Ajax.InPlaceEditor('editme3', '/demoajaxreturn.html');
+</script>
+
+
+

How to customize the look and feel of the form

+

Use the id or class (‘inplaceeditor-form’) of the form in a CSS selector to apply the desired style. The text field is always named ‘value’, the ok button is an input with type ‘submit’ and the cancel link is a normal anchor (‘a’) element.

+

+form.inplaceeditor-form { /* The form */
+}
+
+form.inplaceeditor-form input[type="text"] { /* Input box */
+}
+
+form.inplaceeditor-form textarea { /* Textarea, if multiple rows */
+}
+
+form.inplaceeditor-form input[type="submit"] { /* The submit button */
+  margin-left:1em;
+}
+
+form.inplaceeditor-form a { /* The cancel link */
+  margin-left:1em;
+}
+
+

How to edit server side formatted text (formatted with eg. textile)

+

Format the text on the server when the initial page is rendered. Add a new server side action that returns the unformatted text in the reponse and specify the load Text URL? option as a URL to this action. The control will load the text from the server instead of using the text on the page. The action that receives the updated text should save it and return the formatted text as an HTML snippet in the reponse.

+

Example using Ruby on Rails
+

+

#controller
+def my_action
+ #get the text to display initially
+ @fancy_text = “Some fancy bold and emphasized text.”
+end

+

def update_text
+ #save your text here, and return the saved value
+ @fancy_text = params[:value]
+ render :layout => false, :inline => “<%= textilize( @fancy_text ) %>”
+end

+

def return_unformatted_text
+ #get your text and return it without the formatting
+ @fancy_text = “Some fancy edited, bold and emphasized text.”
+ render :layout => false, :inline => “<%= @fancy_text %>”
+end

+

#view ( of my_action.rhtml )

+

<%= textilize( @fancy_text ) %>

+

+

In-Place edits with select lists

+

In my (java) application, I have a need for in-place editing in the form of select lists. Given a server-side ajax helper that provides the necessary options for the current user, I was able to write the following:

+

+function setupCategoryEditor(el, url) {
+    var editor=new Ajax.InPlaceEditor(el, url);
+    Object.extend(editor, {
+        createEditField: function() {
+            var text=this.getText();
+
+            var field=document.createElement("select");
+            field.name="value";
+
+            this.editField=field;
+            this.form.appendChild(this.editField);
+
+            new Ajax.Request('/url/to/option/list', {
+                onSuccess: function(req) {
+                    // Get the text from an XML tag.
+                    var getData=function(el, which) {
+                        stuff=el.getElementsByTagName(which);
+                        return stuff[0].firstChild.nodeValue;
+                    };
+                    var cats=req.responseXML.getElementsByTagName("cat");
+                    $A(cats).each( function(cat, idx) {
+                        var op=document.createElement("option");
+                        op.value=getData(cat, "value");
+                        op.text=getData(cat, "key");
+                        if(window.ActiveXObject) {
+                            field.options.add(op);
+                        } else {
+                            field.appendChild(op);
+                        }
+
+                        // Select the current item
+                        if(op.text == text) {
+                            field.selectedIndex=idx;
+                        }
+                    });
+                }
+                });
+        }
+    });
+}
+
+

Obviously, one could write something smaller with JSON or innerHTML if you’re into that kind of thing.

+

There is another implementation of " In Place Editor “:http://madrobby.github.com/scriptaculous/in-place-editor for select lists called Ajax. ”color:#aaa"> In Place Select? available here.

+

You can change getText like so:

+
getText: function() {
+  return this.element.childNodes[0] ? this.element.childNodes[0].nodeValue : '';
+},
+

to avoid e.g. “Me & Myself” being represented in the input box as “Me & amp; Myself” (use nodeValue because innerText does not work with Safari when the element is hidden).

+

- – -
+I just added inplace editor inside a sortable list array. I can drag and after, the editor appears, but ideally I would not want that to happen and instead activate the editor specifically, not as a result of dragging my list items. What is suggested here?
+I tried using a drag handle, which seemed like an obvious solution, except the editor then shows the span class code as well, which is a caveat I suppose.
+Unless I can use a drag handle without the method in example, then that won’t be a good solution.

+

How else can I drag or how else can I activate the editor besides writing redundant for each instance?
+-ms

+

I found a workaround to use draggable and Ajax.InPlaceEditor at same time. I faced also this problem mentioned above (the ‘mousup’ action at the end of the draggable activates the editor). The solution that I found is to modify control.js to activate InPlaceEditor only on dbclick instead of click. The drawback is that you should deal with navigator compatibilty… So It consists in replacing:
+


+ Listeners: {
+    click: 'enterEditMode',
+    keydown: 'checkForEscapeOrReturn',
+    mouseover: 'enterHover',
+    mouseout: 'leaveHover'
+  }
+
+
by
+

+ Listeners: {
+    dblclick: 'enterEditMode',
+    keydown: 'checkForEscapeOrReturn',
+    mouseover: 'enterHover',
+    mouseout: 'leaveHover'
+  }
+
+

+

-Tonio
+- – -

+

I just spent a good deal of time figuring that out myself so I’ll share my result:

+

+<style>
+div.handle {
+    display: none;
+    float: left;
+    width: 25px;
+    height: 11px;
+    margin-top: 2px;
+    padding-right: 3px;
+    background: url('/images/drag.gif');
+    background-repeat: no-repeat;
+    clear: both;
+}
+</style>
+<ul id="field">
+    <li id="field_1">
+
+        <div class="handle"></div><div class="delete"></div>
+        <span class="data" id="field_name_1">Brand</span></li>
+    <li id="field_3">
+        <div class="handle"></div><div class="delete"></div>
+
+        <span class="data" id="field_name_3">SKU Number</span></li>
+    <li id="field_5">
+        <div class="handle"></div><div class="delete"></div>
+        <span class="data" id="field_name_5">Color</span></li>
+
+</ul>
+<a id="field_sort" href="javascript:;" onclick="makeSortable('field');">Reorder</a>
+<a id="field_donesort" href="javascript:;" onclick="doneSorting('field');" style="display:none;">Done Reordering</a>
+<script>
+function makeSortable(myid,mytag){
+    Sortable.create(myid,{ tag: mytag || 'li', handle:'handle'});
+    setDisplayByClass('handle','inline',$(myid));
+    $(myid+'_sort').style.display = 'none';
+    $(myid+'_donesort').style.display = '';
+    $(myid).setAttribute('reordering','yes');
+    return false;
+}
+function doneSorting(myid){
+    new Ajax.Updater('reply',page,{parameters:'a=reorder&table='+myid+'&'+Sortable.serialize(myid)});
+    Sortable.destroy(myid);
+    setDisplayByClass('handle','none',$(myid));
+    $(myid+'_sort').style.display = '';
+    $(myid+'_donesort').style.display = 'none';
+    $(myid).setAttribute('reordering','no');
+    return false;
+}
+var list = getElementsByClass('data',$('fields'));
+var ipeOptionsStd = {
+        callback:    function(form,value){
+                        var id=form.id;
+                        id = id.substring(0,id.indexOf('-inplaceeditor'));
+                        var t = id.substring(0,id.indexOf('_'));
+                        var c = id.substring(0,id.lastIndexOf('_'));
+                        var i = id.substring(id.lastIndexOf('_')+1,id.length);
+                        return 'a=update&table='+t+'&column='+c+'&id='+i+'&value='+encodeURIComponent(value);
+                    }
+        };
+for(var i=0;i<list.length;i++){
+    new Ajax.InPlaceEditor(list[i], page, ipeOptionsStd );
+}
+
+</script>
+
+

Hope that helps, that is a much simplified version. I’ve also done this with tables where each cell is an " In Place Editor ":http://madrobby.github.com/scriptaculous/in-place-editor and the rows are Sortable.

+

- Colin

+

Using HTML within the In Place Editor

+

If you are using Markdown or Textile, you can include HTML within your text. And if you follow the instructions above, you will be able to load this text in from your database with loadTextURL. But the stripTags function is invoked by the In Place Editor, and that strips out all the code before it can be displayed in the editor field.

+

To get around this, add the following two extensions anywhere after the rest of the library has loaded. I use the extensions.js method noted elsewhere on this site.

+

+Object.extend(Ajax.InPlaceEditor.prototype, {
+    onLoadedExternalText: function(transport) {
+        Element.removeClassName(this.form, this.options.loadingClassName);
+        this.editField.disabled = false;
+        this.editField.value = transport.responseText;
+        Field.scrollFreeActivate(this.editField);
+    }
+});
+
+Object.extend(Ajax.InPlaceEditor.prototype, {
+    getText: function() {
+        return this.element.childNodes[0] ? this.element.childNodes[0].nodeValue : '';
+    }
+});
+
+

If you do this, make sure that your loadTextURL does not return entity-encoded text (using htmlentities() for example) or you will end up with double-encoded text.

+

In-Place edits only by externalControl

+

i searched for a way to allow editing of certain fields only by clicking the external control field. currently its implemented to allow a user to click either on the element itself or on the external control element.

+

to only allow editing by clicking on the external control, simply change a few lines:

+

+Event.observe(this.element, 'click', this.onclickListener);
+Event.observe(this.element, 'mouseover', this.mouseoverListener);
+Event.observe(this.element, 'mouseout', this.mouseoutListener);
+
+if (this.options.externalControl) {
+  Event.observe(this.options.externalControl, 'click', this.onclickListener);
+  Event.observe(this.options.externalControl, 'mouseover', this.mouseoverListener);
+  Event.observe(this.options.externalControl, 'mouseout', this.mouseoutListener);
+}
+
+change to:
+
+if (this.options.externalControl) {
+  Event.observe(this.options.externalControl, 'click', this.onclickListener);
+  Event.observe(this.options.externalControl, 'mouseover', this.mouseoverListener);
+  Event.observe(this.options.externalControl, 'mouseout', this.mouseoutListener);
+} else {
+  Event.observe(this.element, 'click', this.onclickListener);
+  Event.observe(this.element, 'mouseover', this.mouseoverListener);
+  Event.observe(this.element, 'mouseout', this.mouseoutListener);
+}
+
+

maybe someone can add a flag like ‘only External Control ? to add this to the trunk ..

+

Small extension to editor to add a text in case field is empty.

+

+/*
+ * InPlaceEditor extension that adds a 'click to edit' text when the field is 
+ * empty.
+ */
+Ajax.InPlaceEditor.prototype.__initialize = Ajax.InPlaceEditor.prototype.initialize;
+Ajax.InPlaceEditor.prototype.__getText = Ajax.InPlaceEditor.prototype.getText;
+Ajax.InPlaceEditor.prototype.__onComplete = Ajax.InPlaceEditor.prototype.onComplete;
+Ajax.InPlaceEditor.prototype = Object.extend(Ajax.InPlaceEditor.prototype, {
+
+    initialize: function(element, url, options){
+        this.__initialize(element,url,options)
+        this.setOptions(options);
+        this._checkEmpty();
+    },
+
+    setOptions: function(options){
+        this.options = Object.extend(Object.extend(this.options,{
+            emptyText: 'click to edit...',
+            emptyClassName: 'inplaceeditor-empty'
+        }),options||{});
+    },
+
+    _checkEmpty: function(){
+        if( this.element.innerHTML.length == 0 ){
+            this.element.appendChild(
+                Builder.node('span',{className:this.options.emptyClassName},this.options.emptyText));
+        }
+    },
+
+    getText: function(){
+        document.getElementsByClassName(this.options.emptyClassName,this.element).each(function(child){
+            this.element.removeChild(child);
+        }.bind(this));
+        return this.__getText();
+    },
+
+    onComplete: function(transport){
+        this._checkEmpty();
+        this.__onComplete(transport);
+    }
+});
+
+
+

To use, copy this into a extensions.js and load it in your app after the other scriptaculous stuff.

+

Here is the style I use with this:

+

+
+/* ----  InPlaceEditor style --------------------------------------------- */
+
+.inplaceeditor-empty {
+    font-style: italic;
+    color: #999;
+}
+
+

- Pedro

+

This doesn’t seem to work for me in Prototype 1.6, so I wrote an updated version. (Blog Post).

+

+
+Ajax.InPlaceEditorWithEmptyText = Class.create(Ajax.InPlaceEditor, {
+
+  initialize : function($super, element, url, options) {
+
+    if (!options.emptyText)        options.emptyText      = “click to editâ€Ĥ“;
+    if (!options.emptyClassName)   options.emptyClassName = “inplaceeditor-empty“;
+
+    $super(element, url, options);
+
+    this.checkEmpty();
+  },
+
+  checkEmpty : function() {
+
+    if (this.element.innerHTML.length == 0 && this.options.emptyText) {
+
+      this.element.appendChild(
+          new Element(“span“, { className : this.options.emptyClassName }).update(this.options.emptyText)
+        );
+    }
+
+  },
+
+  getText : function($super) {
+
+    if (empty_span = this.element.select(“.“ + this.options.emptyClassName).first()) {
+      empty_span.remove();
+    }
+
+    return $super();
+
+  },
+
+  onComplete : function($super, transport) {
+
+    this.checkEmpty();
+    return $super(transport);
+
+  }
+
+});
+
+
+

- Nik

+

Create your own Callback

+

I wanted to have a custom callback that would fire after the InPlaceEditor form was added to the DOM. onEnterEditMode fires as soon as you click, but the form doesn’t exist yet.

+

This works by copying an existing method enterEditMode(), which builds the form and writes it to the page, into a new method name so that I can edit the real one. In mine, the original is called via __enterEditMode() and then my custom code is run:

+

+Ajax.InPlaceEditor.prototype.__enterEditMode = Ajax.InPlaceEditor.prototype.enterEditMode;
+Object.extend(Ajax.InPlaceEditor.prototype, {
+  enterEditMode:function(e) {
+    this.__enterEditMode(e);
+    this.triggerCallback('onFormReady',this._form);
+  }
+});
+
+

Now when I create my InPlaceEditor I just add a the onFormReady callback as an option:

+

+new Ajax.InPlaceEditor('location', '/change_location',
+  { 
+    onFormReady: function(obj,form) {
+      form.getInputs().first().value = '';
+    }
+  });
+
+

In my case I wanted to clear out the value in the text box so that the user had to type something from scratch. If they cancel it will switch back to the original text.

+

- Rob

+
+

Validation.

+

Information for implementing validation with ajax." In Place Editor ":http://madrobby.github.com/scriptaculous/in-place-editor can be found here. Link Dead!

+

suggest

+

If “cancel control” type was ‘button’ then… javascript error occurs.

+

+  new Ajax.InPlaceEditor(node, 'items.aspx', {
+	cancelControl: 'button'
+  });
+
+

So, I suggest the method modification of ‘handleFormCancellation’.

+

+  handleFormCancellation: function(e) {
+    this.wrapUp();
+    if (e) Event.stop(e);
+    return false;
+  },
+
+
\ No newline at end of file diff --git a/_posts/2009-01-01-autocompleter-base.html b/_posts/2009-01-01-autocompleter-base.html new file mode 100644 index 0000000..ade42c6 --- /dev/null +++ b/_posts/2009-01-01-autocompleter-base.html @@ -0,0 +1,18 @@ +--- +layout: default +title: Autocompleter.Base +category: Controls +--- + +
+

Autocompleter.Base handles all the autocompletion functionality that’s independent of the data source for autocompletion. This includes drawing the autocompletion menu, observing keyboard and mouse events, and similar.

+

Availability

+

script.aculo.us V1.1b1

+

Extending

+

Specific autocompleters need to provide, at the very least, a getUpdatedChoices function that will be invoked every time the text inside the monitored textbox changes. This method should get the text for which to provide autocompletion by invoking this.getToken(), NOT by directly accessing this.element.value. This is to allow incremental tokenized autocompletion. Specific auto-completion logic (AJAX, etc) belongs in getUpdatedChoices.

+

Tokenized autocompletion

+

Tokenized incremental autocompletion is enabled automatically when an autocompleter is instantiated with the ‘tokens’ option in the options parameter:

+

new Ajax.Autocompleter('id','upd', '/url/', { tokens: ',' });

+

will incrementally autocomplete with a comma as the token.

+

Additionally, ’,’ in the above example can be replaced with a token array, e.g. tokens: [',', '\n'] } which enables autocompletion on multiple tokens. This is most useful when one of the tokens is \n (a newline), as it allows smart autocompletion after linebreaks.

+
\ No newline at end of file diff --git a/_posts/2009-01-01-autocompleter-local.html b/_posts/2009-01-01-autocompleter-local.html new file mode 100644 index 0000000..8cd124d --- /dev/null +++ b/_posts/2009-01-01-autocompleter-local.html @@ -0,0 +1,156 @@ +--- +layout: default +title: Autocompleter.Local +category: Controls +--- + +
+ +

Controls > Autocompleter.Local

+

Introduction

+

The local array autocompleter. Used when you’d prefer to inject an array of autocompletion options into the page, rather than sending out Ajax queries.

+

Syntax

+
new Autocompleter.Local(id_of_text_field, id_of_div_to_populate, array_of_strings, options);
+
+

The constructor takes four parameters. The first two are, as usual, the id of the monitored textbox, and id of the autocompletion menu. The third is an array of strings that you want to autocomplete from, and the fourth is the options block.

+

Extra local autocompletion options

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
OptionDefault ValueDescription
choices10How many autocompletion choices to offer
partialSearchtrueIf false, the autocompleter will match entered text only at the beginning of strings in the autocomplete array. Defaults to true, which will match text at the beginning of any word in the strings in the autocomplete array. If you want to search anywhere in the string, additionally set the option fullSearch to true
fullSearchfalseSearch anywhere in autocomplete array strings.
partialChars2How many characters to enter before triggering a partial match (unlike minChars, which defines how many characters are required to do any match at all).
ignoreCasetrueWhether to ignore case when autocompleting
+

It’s possible to pass in a custom function as the ‘selector’ option, if you prefer to write your own autocompletion logic. In that case, the other options above will not apply unless you support them.

+

Example

+

HTML

+

+<p>
+  <label for="bands_from_the_70s">Your favorite rock  band from the 70's:</label>
+  <br />
+  <input id="bands_from_the_70s" autocomplete="off" size="40" type="text" value="" />
+</p>
+
+<div class="autocomplete" id="band_list" style="display:none"></div>
+
+

Javascript

+

+var bandsList = [
+  'ABBA',
+  'AC/DC',
+  'Aerosmith',
+  'America',
+  'Bay City Rollers',
+  'Black Sabbath',
+  'Boston',
+  'David Bowie',
+  'Can',
+  'The Carpenters',
+  'Chicago',
+  'The Commodores',
+  'Crass',
+  'Deep Purple',
+  'The Doobie Brothers',
+  'Eagles',
+  'Fleetwood Mac',
+  'Haciendo Punto en Otro Son',
+  'Heart',
+  'Iggy Pop and the Stooges',
+  'Journey',
+  'Judas Priest',
+  'KC and the Sunshine Band',
+  'Kiss',
+  'Kraftwerk',
+  'Led Zeppelin',
+  'Lindisfarne (band)',
+  'Lipps, Inc',
+  'Lynyrd Skynyrd',
+  'Pink Floyd',
+  'Queen',
+  'Ramones',
+  'REO Speedwagon',
+  'Rhythm Heritage',
+  'Rush',
+  'Sex Pistols',
+  'Slade',
+  'Steely Dan',
+  'Stillwater',
+  'Styx',
+  'Supertramp',
+  'Sweet',
+  'Three Dog Night',
+  'The Village People',
+  'Wings (fronted by former Beatle Paul McCartney)',
+  'Yes'
+];
+
+new Autocompleter.Local('bands_from_the_70s', 'band_list', bandsList, { });
+
+

CSS

+

Styling the div and the returned ul is very important:
+Applying a visual cue that an item is selected allows the user to take advantage of the keyboard navigation of the dropdown and adding background colors, borders, positioning, etc to the div (as the demo does) allows the user interface elements to stand out. The CSS from the demo applied to the examples would be:

+

+div.autocomplete {
+  margin:0px;  
+  padding:0px;  
+  width:250px;
+  background:#fff;
+  border:1px solid #888;
+  position:absolute;
+}
+
+div.autocomplete ul {
+  margin:0px;
+  padding:0px;
+  list-style-type:none;
+}
+
+div.autocomplete ul li.selected { 
+  background-color:#ffb;
+}
+
+div.autocomplete ul li {
+  margin:0;
+  padding:2px;
+  height:32px;
+  display:block;
+  list-style-type:none;
+  cursor:pointer;
+}
+
+

Notes

+

You can also have your options provided via Ajax callbacks. For more information regarding this implementation, see Ajax.Autocompleter.

+

Advance extended version that mimics Facebook to: field.

+ +
\ No newline at end of file diff --git a/_posts/2009-01-01-behaviours.html b/_posts/2009-01-01-behaviours.html new file mode 100644 index 0000000..d69b973 --- /dev/null +++ b/_posts/2009-01-01-behaviours.html @@ -0,0 +1,14 @@ +--- +layout: default +title: Behaviours Overview +category: Behaviours +--- + +
+

The classes below let you add special behaviors to elements in the document

+ +
\ No newline at end of file diff --git a/_posts/2009-01-01-builder.html b/_posts/2009-01-01-builder.html new file mode 100644 index 0000000..438941a --- /dev/null +++ b/_posts/2009-01-01-builder.html @@ -0,0 +1,113 @@ +--- +layout: default +title: Builder +--- + +
+ +

Introduction

+

Use Builder to easily create DOM elements dynamically.

+

Syntax

+

+Builder.node( elementName )
+Builder.node( elementName, attributes )
+Builder.node( elementName, children )
+Builder.node( elementName, attributes, children )
+
+ + + + + + + + + + + + + + + + + +
Arguments Description
elementName String, The tag name for the element
attributes Object, Typical attributes are id, className, style, onclick, etc.
children Array, List of other nodes to be appended as children
+

If an element of the children Array is a String or Number, it will be automatically appended as a text node. Instead of an array, children can also be a JavaScript String or Number, to ease usage.

+

Special cases

+
    +
  • class: When specifying the class attribute for the node, use className to circumvent a Firefox bug.
  • +
  • for: To set a for attribute (in labels) use htmlFor, since ‘for’ is a reserved word in javascript.
  • +
+

Examples

+

Creating TR and TD elements

+

+var table = Builder.node('table', {
+  width: '100%',
+  cellpadding: '2',
+  cellspacing: '0',
+  border: '0'
+});
+
+var tbody = Builder.node('tbody'),
+    tr = Builder.node('tr', { className: 'header' }),
+    td = Builder.node('td', [Builder.node('strong', 'Category')]);
+
+tr.appendChild(td);
+tbody.appendChild(tr);
+table.appendChild(tbody);
+$('divCat').appendChild(table);
+
+

You can also combine them but you need to make sure you create the tbody tag or it will not work in IE. I have tested this in FF 1.5 and IE 6. I don’t have access to other browsers. The one problem that I have found is that with TR and TD elements you can not put a style tag on them as it just makes IE stop doing the Builder Function.

+

Simple Example

+

+var element = Builder.node('p', { className:'error' }, 'An error has occurred');
+
+

creates following element:

+

+<p class="error">An error has occured</p>
+
+

Complex Example

+

+var element = Builder.node('div', { id: 'ghosttrain' }, [
+  Builder.node('div',{ className: 'controls', style: 'font-size:11px;' }, [
+    Builder.node('h1', 'Ghost Train'),
+    'testtext', 2, 3, 4,
+    Builder.node('ul', [
+      Builder.node('li', { className: 'active', onclick: 'test()' }, 'Record')
+    ]),
+  ]),
+]);
+
+

creates (without newlines):

+

+<div id="ghosttrain">
+  <div class="controls" style="font-size:11px">
+    <h1>Ghost Train</h1>
+    testtext234
+    <ul>
+      <li class="active" onclick="test()">Record</li>
+    </ul>
+  </div>
+</div>
+
+

Usage

+

In JavaScript code, if you want to use your new element, you can add it to an existing DOM element by using the browsers native appendChild function:

+

+$('myExistingDomElement').appendChild(element);
+
+

â€Ĥ or by using Protoypes built-in Element#insert method which allows you to specify a position the new node gets inserted into:

+

+$('myExistingDomElement').insert(element); // appends the new node to @myExistingDomElement@-element
+$('myExistingDomElement').insert({ after: element }); // inserts the new node right after the @myExistingDomElement@-element
+$('myExistingDomElement').insert({ top: element }); // inserts the new node as the first element in @myExistingDomElement@
+
+

If you want to be able to call any of Prototype’s extension-methods on the created node, then you need to pass it through the $ function:

+

+var div = Builder.node('div', { id: 'some_id' });
+div = $(div);
+div.hide();
+

+ +
\ No newline at end of file diff --git a/_posts/2009-01-01-combination-effects-demo.html b/_posts/2009-01-01-combination-effects-demo.html new file mode 100644 index 0000000..20b2b40 --- /dev/null +++ b/_posts/2009-01-01-combination-effects-demo.html @@ -0,0 +1,138 @@ +--- +layout: default +title: Combination Effects Demo +category: Demos +--- + +
+ + + +

These are the combination effects which are included in script.aculo.us:

+ +

Note: This page is basically a duplicate of Combination Effects but was created to fix an invalid link on the script.aculo.us home page.

+

Demo

+
+
+
+ +Click for Effect.Appear demo +
+
+
+
+ +Click for Effect.Fade demo +
+
+
+
+ +Click for Effect.Puff demo +
+
+
+
+
+ +Click for Effect.BlindDown demo +
+
+
+
+
+ +Click for Effect.BlindUp demo +
+
+
+
+ +Click for Effect.SwitchOff demo +
+
+
+

+
+Click for Effect.SlideDown demo
+
+
+
+ +Click for Effect.SlideUp demo +
+
+
+
+ +Click for Effect.DropOut demo +
+
+
+
+ +Click for Effect.Shake demo +
+
+
+
+ +Click for Effect.Pulsate demo +
+
+
+
+ +Click for Effect.Squish demo +
+
+
+
+ +Click for Effect.Fold demo +
+
+
+
+ +Click for Effect.Grow demo +
+
+
+
+ +Click for Effect.Shrink demo +
+
+
+
+ +Click for Effect.Highlight demo +
+
+
+
\ No newline at end of file diff --git a/_posts/2009-01-01-combination-effects.html b/_posts/2009-01-01-combination-effects.html new file mode 100644 index 0000000..55964c9 --- /dev/null +++ b/_posts/2009-01-01-combination-effects.html @@ -0,0 +1,27 @@ +--- +layout: default +title: Combination Effects +category: Combination Effects +--- + +
+

All the combination effects are based on the Core Effects, and are thought of as examples to allow you to write your own effects.
+These are the combination effects which are included in script.aculo.us:

+ +

Additionally, there’s the Effect.toggle utility method for elements you want to show temporarily with a Appear/Fade, Slide or Blind animation.

+

Demos

+

You can see a demo of a specific combination effect on the effects site itself or get an overview of all effects by playing with the Combination Effects Demo.

+
\ No newline at end of file diff --git a/_posts/2009-01-01-contribute.html b/_posts/2009-01-01-contribute.html new file mode 100644 index 0000000..bbf0346 --- /dev/null +++ b/_posts/2009-01-01-contribute.html @@ -0,0 +1,23 @@ +--- +layout: default +title: Contribute +category: Contribute +--- + +
+

Want to help make script.aculo.us better? You can!

+

Found a bug?

+

script.aculo.us uses Lighthouse for bug tracking:
+http://prototype.lighthouseapp.com/projects/8887-script-aculo-us

+

(First, be sure that there isn’t a ticket already, then file a new bug!)

+

If you found a bug

+

When creating a bug report, be sure to include as much relevant information as possible. Post an example that shows off the problem. Preferably, alter the unit tests and show through either changed or added tests how the expected behavior is not occuring.

+

Source code repository

+

script.aculo.us uses Git to manage development. Check out the current development trunk with:

+

+git clone git://github.com/madrobby/scriptaculous.git
+
+

As script.aculo.us 1.xx is feature-frozen, this development trunk is for bugfixes only (new features will only happen for script.aculo.us 2).

+

JavaScript is not your thing?

+

You may also contribute by writing documentation, making tutorials and general pimping of scriptaculous! :)

+
\ No newline at end of file diff --git a/_posts/2009-01-01-controls.html b/_posts/2009-01-01-controls.html new file mode 100644 index 0000000..1c0d313 --- /dev/null +++ b/_posts/2009-01-01-controls.html @@ -0,0 +1,25 @@ +--- +layout: default +title: Controls Overview +category: Controls +--- + +
+ +

The in-place “text edit” testing allows for Flickr-style AJAX-backed “on-the-fly” textfields. See the documentation

+ +

The Autocompleter controls allow for Google-Suggest style local and server-powered autocompleting text input fields

+ + + +
\ No newline at end of file diff --git a/_posts/2009-01-01-core-effects.html b/_posts/2009-01-01-core-effects.html new file mode 100644 index 0000000..509c415 --- /dev/null +++ b/_posts/2009-01-01-core-effects.html @@ -0,0 +1,175 @@ +--- +layout: default +title: Core Effects Overview +category: Core Effects +--- + +
+ +

The seven core effects Effect.Opacity, Effect.Scale, Effect.Morph, Effect.Move, Effect.Highlight, Effect.Parallel, Effect.Tween are the foundation of the script.aculo.us Visual Effects JavaScript library.

+

Availability

+

script.aculo.us V1.0 and later.

+

Syntax

+

The basic syntax to start an effect is:
+


+new Effect.EffectName(element, required-params, [options]);
+

+element can be either a string containing the id of the element, or a Java Script DOM element object.

+

required-params depend on the effect being called and may not be needed. Most effects do not have required parameters. See the documentation for the core effects to learn if the effect has required parameters or if this parameter should be omitted.

+

The options parameter is used to give any additional customization parameters to the effect. There are general and effect-specific options. It’s called like this:
+


+new Effect.Opacity('my_element', { 
+  duration: 2.0,
+  transition: Effect.Transitions.linear,
+  from: 1.0, 
+  to: 0.5
+});
+

+

Common Parameters

+

All core effects support following settings in their options parameter:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Option Description
duration duration of the effect in seconds, given as a float. Defaults to 1.0.
fps Target this many frames per second. Default to 25. Can’t be higher than 100.
transition Sets a function that modifies the current point of the animation, which is between 0 and 1. Following transitions are supplied: Effect.Transitions.sinoidal (default), Effect.Transitions.linear, Effect.Transitions.reverse, Effect.Transitions.wobble, Effect.Transitions.flicker, Effect.Transitions.pulse, Effect.Transitions.spring, Effect.Transitions.none and Effect.Transitions.full.
from Sets the starting point of the transition, a float between 0.0 and 1.0. Defaults to 0.0.
to Sets the end point of the transition, a float between 0.0 and 1.0. Defaults to 1.0.
sync Sets whether the effect should render new frames automatically (which it does by default). If true, you can render frames manually by calling the render() instance method of an effect. This is used by Effect.Parallel().
queue Sets queuing options. When used with a string, can be ‘front’ or ‘end’ to queue the effect in the global effects queue at the beginning or end, or a queue parameter object that can have { position: ’front/end’, scope: ’scope’, limit: 1 }. For more info on this, see Effect Queues.
delay Sets the number of seconds to wait before the effect actually starts. Defaults to 0.0.
+

Additionally, the options parameter also can be supplied with callback methods, so you can have JavaScript executed at various events while the effect is running. The callbacks are supplied with a reference to the effect object as a parameter.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Callback Description
beforeStart Called before the effects rendering loop is started, or as soon as it is added to a queue.
beforeSetup Called before the effect is setup.
afterSetup Called after the effect is setup and immediately before the main effects rendering loop is started.
beforeUpdate Called on each iteration of the effects rendering loop, before the redraw takes place.
afterUpdate Called on each iteration of the effects rendering loop, after the redraw takes place.
afterFinish Called after the last redraw of the effect was made.
+

Effect instances have the following useful properties and methods:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Variable Description
effect.element The element the effect is applied to.
effect.options Holds the options you gave to the effect.
effect.currentFrame The number of the last frame rendered.
effect.startOn, effect.finishOn The times (in ms) when the effect was started, and when it will be finished.
effect.effects[] On an Effect.Parallel effect, there’s an effects[] array containing the individual effects the parallel effect is composed of.
effect.cancel() Stop the effect as is.
effect.inspect() Get basic debugging information about the instance.
+

+var myEffect = new Effect.Opacity('my_element', { 
+  duration: 2.0,
+  transition: Effect.Transitions.linear,
+  from: 1.0, 
+  to: 0.5
+});
+//...
+// example instance properties
+myEffect.element; // $('my_element')
+myEffect.currentFrame; // 12
+myEffect.cancel(); // stop animation
+
+

Transitions Demo

+ +

Reset demo

+ +

+new Effect.Move(this, {
+   x: 200, 
+   transition: Effect.Transitions.spring 
+});
+
+ +
\ No newline at end of file diff --git a/_posts/2009-01-01-demos.html b/_posts/2009-01-01-demos.html new file mode 100644 index 0000000..86b090b --- /dev/null +++ b/_posts/2009-01-01-demos.html @@ -0,0 +1,24 @@ +--- +layout: default +title: Demos +category: Demos +--- + +
+

See what’s possible with script.aculo.us! All demos come with the complete source code and explanations.

+

Interactive Demos

+ +

Backend Integration

+

(Demos currently offline)

+

These Ruby on Rails based demonstrations show how easy it is to integrate script.aculo.us controls with server-side logic. Of course, all this stuff also works with any other server-side technology (links open an external site).

+ +
\ No newline at end of file diff --git a/_posts/2009-01-01-draggable.html b/_posts/2009-01-01-draggable.html new file mode 100644 index 0000000..c746fe1 --- /dev/null +++ b/_posts/2009-01-01-draggable.html @@ -0,0 +1,178 @@ +--- +layout: default +title: Draggable +category: Behaviours +--- + +
+ +

Behaviours > Draggable

+

To make an element draggable, create a new instance of class Draggable.
+For additional built-in functionality, make a Sortable instead.

+

There is also a class named Draggables that exposes functions for observing drag actions.

+

Draggables become much more useful when you use them with droppables, which are the areas that you can drag draggables to.

+

Syntax

+

+new Draggable('id_of_element', [options]);
+
+

Options

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Option Since Description
handle 1.0 string or DOM reference, not set by default. Sets whether the element should only be draggable by an embedded handle. The value must be an element reference or element id.
handle 1.5. string or DOM reference, not set by default. As above, except now the value may be a string referencing a CSS class value. The first child/grandchild/etc. element found within the element that has this CSS class value will be used as the handle.
revert 1.0 boolean, defaults to false. If set to true, the element returns to its original position when the drags ends.
revert 1.5 boolean or function reference, defaults to false. Revert can also be an arbitrary function reference, called when the drag ends. Specifying 'failure' will instruct the draggable not to revert if successfully dropped in a droppable.
snap 1.5 If set to false no snapping occurs. Otherwise takes one of the following forms – Δi: one delta value for both horizontal and vertical snap, [Δx, Δy]: delta values for horizontal and vertical snap, function(x, y, draggable_object) { return [x, y]; }: a function that receives the proposed new top left coordinate pair and returns the coordinate pair to actually be used.
zindex 1.5 integer value, defaults to 1000. The css z-index of the draggable item.
constraint 1.0 string, not set by default. If set to 'horizontal' or 'vertical' the drag will be constrained to take place only horizontally or vertically.
ghosting ?? boolean, defaults to false. Clones the element and drags the clone, leaving the original in place until the clone is dropped.
starteffect ?? Effect, defaults to Effect.Opacity. Defines the effect to use when the draggable starts being dragged.
reverteffect ?? Effect, default to Effect.Move. Defines the effect to use when the draggable reverts back to its starting position.
endeffect ?? Effect, defaults to Effect.Opacity. Defines the effect to use when the draggable stops being dragged.
scroll ?? string or DOM reference, not set by default. Specifies the element which will scroll when you get to the boundary. By default this is turned off.
scrollSensitivity ?? integer value, defaults to 20 pixels. Minimum distance from the element boundary to start scrolling.
+

Additionally, the options parameter accepts any of the following callback functions:

+ + + + + + + + + + + + + + + + + + + + + +
Callback Description
onStart Called when a drag is initiated.
onDrag Called repeatedly as the mouse moves, before the draggable position is updated if mouse position changed from previous call.
change Called just as onDrag, but after the draggable position is updated. Gets the Draggable instance as its parameter.
onEnd Called when a drag is ended.
+

Except for the change callback, each of these callbacks accepts two parameters: the Draggable object, and the mouse event object.

+

Examples

+

+// revert
+new Draggable('product_1', { revert: true });
+
+// constrain direction and give a handle
+new Draggable('my_div', { constraint: 'horizontal', handle: 'handle' });
+
+
•ħ¸Ñ‚µ żÑ€ÑÑ‚¸Ñ‚утş ş°ş хт¸Ñ‚µ. ŸÑ€ÑÑ‚¸Ñ‚утş¸ š¸µ²° ² ’°Ñˆµĵ żğ½ĵ р°ÑżÑ€Ñĥµ½¸¸.
+

To disable draggables later on, store it in a variable like:
+


+var mydrag = new Draggable('product_1', { revert: true });
+// then destroy it when you don't need it anymore
+mydrag.destroy();
+

+

This way, you can enable and disable dragging at will.

+

Demo

+

A demo with the default options

+
+
+ +
+

A demo with { revert: true, snap: [40, 40] } set as options

+
+
+ +
+

A demo with { scroll: window } set as options

+
+
+ +
+

Source code of the demo

+

Demo 1 (default options)
+


+<div id="drag_demo_1" style="width:100px; height:100px; background:#7baaed; border:1px solid #333;"></div>
+  <script type="text/javascript">
+    new Draggable('drag_demo_1');
+  </script>
+

+

Demo 2 (with revert and snap set)
+


+<div id="drag_demo_2" style="width:100px; height:100px; background:#fff85d; border:1px solid #333;"></div>
+  <script type="text/javascript">
+    new Draggable('drag_demo_2', { revert: true, snap: [40, 40] });
+  </script>
+

+

Demo 3 (with scroll set)
+


+<div id="drag_demo_3" style="width:80px; height:80px; cursor:move; background:#88da5d; border:1px solid #333;"></div>
+  <script type="text/javascript">
+    new Draggable('drag_demo_3', { scroll: window });
+  </script>
+

+ +
\ No newline at end of file diff --git a/_posts/2009-01-01-draggables-object.html b/_posts/2009-01-01-draggables-object.html new file mode 100644 index 0000000..c1590a8 --- /dev/null +++ b/_posts/2009-01-01-draggables-object.html @@ -0,0 +1,87 @@ +--- +layout: default +title: Draggables Object +category: Behaviours +--- + +
+

Are you looking for how to make an element draggable?

+

Draggables Object

+

The Draggables object is a global helper object. In most cases you will not need to use or modify the Draggables object, except when adding/removing custom drag observers.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Property/Method Description
drags Array of all Draggables on the page
observers Array of drag observers. Use Draggables.addObserver() and Draggables.removeObserver() to add/remove observers, respectively.
register() function(draggable). Called when you create a new Draggable?. If this is the first Draggable on the page, starts observing mouse events necessary for dragging.
unregister() function(draggable). Called by Draggable.destroy()?. Stops observing window mouse events if Draggable.drag is empty.
activate() Marks a particular Draggable as the activeDraggable
deactivate() Sets Draggables.activeDraggable to @null
updateDrag() Passes the window mousemove event to the @activeDraggable@’s updateDrag function.
endDrag() Caught by the window’s mouseup, stops dragging the activeDraggable, if any, via its endDrag function.
keyPress() Passes the window keypress event to the @activeDraggable@’s keyPress function.
addObserver() Adds an observer to Draggables.observers
removeObserver() Removes an observer from Draggables.observers. Takes the observer’s element property as a parameter
notify() Calls the observers’ onStart(), onEnd(), and onDrag() functions as necessary
+

Draggable Observers

+

A draggable observer, as used in Draggables.addObserver(), is an object with an element property defined, and one or more of the following functions defined:

+ + + + + + + + + + + + + +
onStart() called after drag begins
onDrag() called on each mousemove during a drag
onEnd() called when drag is finished
+

The parameters passed to these three events are

+
    +
  • eventName, one of 'onStart', 'onEnd', 'onDrag'
  • +
  • draggable, a reference to the Draggable?. The draggable.element property is a reference to the DOM element being dragged.
  • +
  • event, the DOM Event object
  • +
+
\ No newline at end of file diff --git a/_posts/2009-01-01-droppables.html b/_posts/2009-01-01-droppables.html new file mode 100644 index 0000000..b24fc35 --- /dev/null +++ b/_posts/2009-01-01-droppables.html @@ -0,0 +1,181 @@ +--- +layout: default +title: Droppables +category: Behaviours +--- + +
+ +
›ÑŽħ¸Ñ‚µ şÑ€°Ñ¸²Ñ‹Ñ… ´µ²Ñ‡µş? ŸÑ€ÑÑ‚¸Ñ‚утş¸ Ÿ¸Ñ‚µÑ€° эт т чт ’°ĵ ½Ñƒĥ½.
+

Behaviours > Droppables

+

To make an element react when a Draggable is dropped onto it, you’ll add it to the Droppables of the page with the Droppables.add class method.

+

Syntax

+

+Droppables.add('id_of_element',[options]);
+
+

Options

+ + + + + + + + + + + + + + + + + + + + + + + + + +
Options Description
accept Set accept to a string or an array of strings describing CSS classes. The Droppable will only accept Draggables that have one or more of these CSS classes.
containment The droppable will only accept the Draggable if the Draggable is contained in the given elements (or element ids). Can be a single element or an array of elements. This option is used by Sortables to control Drag-and-Drop between Sortables.
hoverclass if set, the Droppable will have this additional CSS class when an accepted Draggable is hovered over it.
overlap If set to ‘horizontal’ or ‘vertical’ the droppable will only react to a Draggable if its overlapping by more than 50% in the given direction. Used by Sortables.
greedy OBSOLETE starting at v1.6.1 (mid-2006) boolean, defaults to true, stops processing hovering (don’t look for other Droppables that are under the Draggable)
+

Callbacks

+ + + + + + + + + + + + + +
Callback Description
onHover Called whenever a Draggable is moved over the Droppable and the Droppable is affected (would accept it). The callback gets three parameters: the Draggable, the Droppable element, and the percentage of overlapping as defined by the overlap option. Used by Sortables.
onDrop Called whenever a Draggable is released over the Droppable and the Droppable accepts it. The callback gets three parameters: the Draggable element, the Droppable element and the Event. You can extract additional information about the drop – like if the Ctrl or Shift keys were pressed – from the Event object.
+

Examples

+

+Droppables.add('shopping_cart', {
+  accept: 'products',
+  onDrop: function(element) {
+    $('shopping_cart_text').update('Dropped the ' + element.alt + ' on me.');
+  }
+});
+
+

+Droppables.add('shopping_cart', {
+  accept: 'products',
+  onDrop: function(dragged, dropped, event) {
+    alert('Dragged: ' + dragged.id);
+    alert('Dropped onto: ' + dropped.id);
+    alert('Held ctrl key: ' + event.ctrlKey);
+  }
+});
+
+

Removing Droppables

+

When you delete a Node in the HTML Code that was droppable you will not be able to use any draggable Element. Before you delete a droppable element be sure to remove it first from the Droppables list:

+

+Droppables.remove(element);
+
+

Notes

+

Nested Droppables

+

If you’re adding droppable elements that have other droppable elements inside of them, make sure that you add the droppables in reverse order of the nesting (i.e. most inner droppable first, then second most inner droppable second).
+For example you have a nested list:

+

+<ul>
+  <li>Parent
+    <ul>
+      <li>Child 1</li>
+      <li>Child 2</li>
+      <li>Child 3</li>
+    </ul>
+  </li>
+</ul>
+
+

Make sure that the children get defined as droppables before the parent is.

+

Demo

+ +
+
+ Drag me! +
+
+ Drop here! +
+
+ +

Source code of this demo

+

+<style type="text/css">
+  div#droppable_container {
+    height: 140px;
+    width: 400px; }
+  div#draggable_demo {
+    width: 60px;
+    height: 60px;
+    cursor: move;
+    background: #9fcfba;
+    border: 1px solid #666;
+    text-align: center;
+    position: relative;
+    top: 30px;
+    line-height: 50px; }
+  div#droppable_demo {
+    width: 160px;
+    height: 120px;
+    background: #fff;
+    border: 5px solid #ccc;
+    text-align: center;
+    position: relative;
+    top: -60px;
+    left: 140px;
+    line-height: 100px; }
+  div#droppable_demo.hover {
+    border: 5px dashed #aaa;
+    background:#efefef; }
+</style>
+
+<div class="demo" id="droppable_container">
+  <div id="draggable_demo" class="draggable">
+    Drag me!
+  </div>
+  
+  <div id="droppable_demo">
+    Drop here!
+  </div>
+</div>
+
+<script type="text/javascript">
+  new Draggable('draggable_demo', { 
+    revert: true 
+  });
+  
+  Droppables.add('droppable_demo', { 
+    accept: 'draggable',
+    hoverclass: 'hover',
+    onDrop: function() { $('droppable_demo').highlight(); }
+  });
+</script>
+
+

Restrictions

+

- Can’t drop into a position:fixed styled element.

+
\ No newline at end of file diff --git a/_posts/2009-01-01-effect-appear.html b/_posts/2009-01-01-effect-appear.html new file mode 100644 index 0000000..5b7cda9 --- /dev/null +++ b/_posts/2009-01-01-effect-appear.html @@ -0,0 +1,95 @@ +--- +layout: default +title: Effect.Appear +category: Combination Effects +--- + +
+ +

Combination Effects > Effect.Appear

+

Make an element appear. If the element was previously set to display:none inside the style attribute of the element, the effect will automatically show the element. This means that display must be set within the style attribute of an object, and not in the CSS in the head of the document or a linked file. In other words, this Effect will not work if display:none is set within style tag or linked CSS file. Alternatively, display:none can be set using a document.getElementById script even if no style is set in the style attribute.

+

Examples

+

+Effect.Appear('id_of_element');
+Effect.Appear('id_of_element', { duration: 3.0 });
+
+

There’s also a shortcut method offered which you can call on the element itself. Note, that this will only work on Prototype-extended elements (elements you extended at least once via calling $(element)).

+

+$('id_of_element').appear();
+$('id_of_element').appear({ duration: 3.0 });
+
+

Options

+ + + + + + + + + + + + + + + + + +
Options Description
duration float value, in seconds, defaults to 1.0
from float value, defaults to 0.0, percent of opacity to start
to float value, defaults to 1.0, percent of opacity to end
+

Notes

+

Can take an options parameter, to control the underlying Effect.Opacity effect.
+Works safely with most HTML elements, except table rows, table bodies and table heads.

+

On Microsoft Internet Explorer, this effect may display a bold/ghosting artifact on elements that don’t have a defined background. It’s unclear if this is a feature or a bug.

+

Microsoft Internet Explorer can only set opacity on elements that have a ‘layout’. To let an element have a layout, you must set some CSS positional properties, like width or height. See Giving Elements Layout. (Note: This is fixed in V1.5_rc1.)

+

The opposite of Effect.Appear is Effect.Fade.

+

Demo

+ +

Source code of this demo

+

+<div id="appear_demo" style="display:none; width:80px; height:80px; background:#c2defb; border:1px solid #333;"></div>
+<ul>
+  <li><a href="#" onclick="$('appear_demo').appear(); return false;">Click here for a demo!</a></li>
+  <li><a href="#" onclick="$('appear_demo').hide(); return false;">Reset</a></li>
+</ul>
+
+

Applying Appear to invisible elements

+

Recall that display:none and visibility:hidden both make an element invisible, but elements with visibility:hidden are not collapsed. You cannot apply Effect.Appear to elements with style=“visibility: hidden” because this function only alters “display”. Below is a workaround. I don’t know what’s going on with the demo, but it looks flawlessly when I use it on my website…

+

+$('myBox').setOpacity(0);
+$('myBox').setStyle({visibility: 'visible'});
+new Effect.Opacity(
+   'myBox', { 
+      from: 0.0, 
+      to: 1.0,
+      duration: 1.0
+   }
+);
+ +
\ No newline at end of file diff --git a/_posts/2009-01-01-effect-blinddown.html b/_posts/2009-01-01-effect-blinddown.html new file mode 100644 index 0000000..dab068a --- /dev/null +++ b/_posts/2009-01-01-effect-blinddown.html @@ -0,0 +1,61 @@ +--- +layout: default +title: Effect.BlindDown +category: Combination Effects +--- + +
+ +

Combination Effects > Effect.BlindDown

+

This effect simulates a window blind, where the contents of the affected elements stay in place.

+

Examples

+

+Effect.BlindDown('id_of_element');
+Effect.BlindDown('id_of_element', { duration: 3.0 });
+
+

Options

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Option Description
scaleX boolean, defaults to false
scaleY boolean, defaults to true
scaleContent boolean, defaults to true
scaleFromCenter boolean, defaults to false
scaleMode string, defaults to ‘box', can also be ‘contents‘
scaleFrom integer value, percentage (0%–100%), defaults to 100
scaleTo integer value, percentage (0%–100%), defaults to 0
duration float value, in seconds, defaults to 1.0
+

Notes

+

Works safely with most Block Elements, except table rows, table bodies and table heads.

+

Also, if you would like the block hidden when someone first lands on your page, you must use the display: none property within the style attribute of the div/block tag, and not in the CSS class for the div.
+Example:
+

<div style="display: none" id = "id_of_element">
+Blind content

+

\ No newline at end of file diff --git a/_posts/2009-01-01-effect-blindup.html b/_posts/2009-01-01-effect-blindup.html new file mode 100644 index 0000000..1d6243e --- /dev/null +++ b/_posts/2009-01-01-effect-blindup.html @@ -0,0 +1,105 @@ +--- +layout: default +title: Effect.BlindUp +category: Combination Effects +--- + +
+ +

Combination Effects > Effect.BlindUp

+

This effect simulates a window blind, where the contents of the affected elements stay in place.

+

Examples

+

+Effect.BlindUp('id_of_element');
+Effect.BlindUp('id_of_element', { duration: 3.0 });
+
+

Options

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Option Description
scaleX boolean, defaults to false
scaleY boolean, defaults to true
scaleContent boolean, defaults to true
scaleFromCenter boolean, defaults to false
scaleMode string, defaults to ‘box', can also be ‘contents‘
scaleFrom integer value, percentage (0%–100%), defaults to 100
scaleTo integer value, percentage (0%–100%), defaults to 0
duration float value, in seconds, defaults to 1.0
+

Notes

+

Works safely with most Block Elements, except table rows, table bodies and table heads.

+

The opposite of Effect.BlindUp is Effect.BlindDown.

+

Demo

+
+
+This is some test content. This is some test content. +
+ +
+

Source code of this demo

+

+<div id="blindup_demo" style="width:80px; height:80px; background:#ccc;">
+  This is some test content. This is some test content.
+</div>
+<ul>
+  <li><a href="#" onclick="Effect.BlindUp('blindup_demo'); return false;">Click here for a demo!</a></li>
+  <li><a href="#" onclick="$('blindup_demo').show(); return false;">Reset</a></li>
+</ul>
+
+

Effect.BlindLeft

+

For horizontal scrolling action try this snippet:

+

+Effect.BlindLeft = function(element) {
+  element = $(element);
+  element.makeClipping();
+  return new Effect.Scale(element, 0,
+    Object.extend({ scaleContent: false,
+      scaleY: false,
+      scaleMode: 'box',
+      scaleContent: false,
+      restoreAfterFinish: true,
+      afterSetup: function(effect) {
+        effect.element.makeClipping().setStyle({
+          height: effect.dims[0] + 'px'
+        }).show();
+      },
+      afterFinishInternal: function(effect) {
+        effect.element.hide().undoClipping();
+      }
+    }, arguments[1] || { })
+  );
+};
+
+ +
\ No newline at end of file diff --git a/_posts/2009-01-01-effect-dropout.html b/_posts/2009-01-01-effect-dropout.html new file mode 100644 index 0000000..f61a039 --- /dev/null +++ b/_posts/2009-01-01-effect-dropout.html @@ -0,0 +1,28 @@ +--- +layout: default +title: Effect.DropOut +category: Combination Effects +--- + +
+ +

Combination Effects > Effect.DropOut

+

Makes an element drop and fade out at the same time.

+

Examples

+

+Effect.DropOut('id_of_element');
+
+

Notes

+

Works safely with most Block Elements, except tables.

+

Demo

+ + +
\ No newline at end of file diff --git a/_posts/2009-01-01-effect-fade.html b/_posts/2009-01-01-effect-fade.html new file mode 100644 index 0000000..9192253 --- /dev/null +++ b/_posts/2009-01-01-effect-fade.html @@ -0,0 +1,64 @@ +--- +layout: default +title: Effect.Fade +category: Core Effects +--- + +
+ +

Combination Effects > Effect.Fade

+

Makes an element fade away and takes it out of the document flow when the effect is complete by setting the CSS display property to none. Opposite of Effect.Appear.

+

Examples

+

+Effect.Fade('id_of_element');
+Effect.Fade('id_of_element', { duration: 3.0 });
+
+

There’s also a shortcut method offered which you can call on the element itself. Note, that this will only work on Prototype-extended elements (elements you extended at least once via calling $(element)).

+

+$('id_of_element').fade();
+$('id_of_element').fade({ duration: 3.0, from: 0, to: 1 });
+
+

Options

+ + + + + + + + + + + + + + + + + +
Options Description
duration float value, in seconds, defaults to 1.0
from float value, defaults to 1.0, percent of opacity to start
to float value, defaults to 0.0, percent of opacity to end
+

Notes

+

Can take an options parameter, to control the underlying Effect.Opacity effect.
+Works safely with most HTML elements, except table rows, table bodies and table heads.

+

On Microsoft Internet Explorer, this effect may display a bold/ghosting artifact on elements that don’t have a defined background. It’s unclear if this is a feature or a bug.

+

Microsoft Internet Explorer can only set opacity on elements that have a ‘layout’. To let an element have a layout, you must set some CSS positional properties, like width or height. See Giving Elements Layout. (Note: This is fixed in V1.5_rc1.

+

Demo

+ +

Source code of this demo

+

+<div id="fade_demo" style="width:80px; height:80px; background:#c2defb; border:1px solid #333;"></div>
+<ul>
+  <li><a href="#" onclick="$('fade_demo').fade(); return false;">Click here for a demo!</a></li>
+  <li><a href="#" onclick="$('fade_demo').show(); return false;">Reset</a></li>
+</ul>
+
+ +
\ No newline at end of file diff --git a/_posts/2009-01-01-effect-fold.html b/_posts/2009-01-01-effect-fold.html new file mode 100644 index 0000000..e573bbd --- /dev/null +++ b/_posts/2009-01-01-effect-fold.html @@ -0,0 +1,36 @@ +--- +layout: default +title: Effect.Fold +category: Combination Effects +--- + +
+ +

Combination Effects > Effect.Fold

+

Reduce the element to its top then to left to make it disappear.

+

Examples

+

+Effect.Fold('id_of_element');
+
+

Notes

+

Works safely with most Block Elements, except tables.

+

Demo

+ +

Source code of this demo

+

+<div id="fold_demo" style="width:80px; height:80px; background:#ccc;"></div>
+<ul>
+  <li><a href="#" onclick="Effect.Fold('fold_demo'); return false;">Click me for a demo!</a></li>
+  <li><a href="#" onclick="$('fold_demo').show(); return false;">Reset</a></li>
+</ul>
+
+ +
\ No newline at end of file diff --git a/_posts/2009-01-01-effect-grow.html b/_posts/2009-01-01-effect-grow.html new file mode 100644 index 0000000..bc15014 --- /dev/null +++ b/_posts/2009-01-01-effect-grow.html @@ -0,0 +1,52 @@ +--- +layout: default +title: Effect.Grow +category: Combination Effects +--- + +
+ +

Combination Effects > Effect.Grow

+

“Grows” an element into a specific direction (see demo for better understanding).

+

Examples

+

+Effect.Grow('id_of_element');
+
+

Options

+ + + + + + + + + + + + + +
Option Description
direction string, defaults to 'center', can also be: 'top-left', 'top-right', 'bottom-left', 'bottom-right', specifying the origin from which to “grow” the element
duration float value, in seconds, defaults to 1.0
+

Notes

+

Works safely with most Block Elements, except tables.
+You can define different durations for several div elements, and place them in a row in order to make them appear one after another.

+

Demo

+ +

Source code of this demo

+

+<div id="grow_demo" style="display:none; width:80px; height:80px; background:#ccc;"></div>
+<ul>
+  <li><a href="#" onclick="Effect.Grow('grow_demo'); return false;">Click me for a demo!</a></li>
+  <li><a href="#" onclick="$('grow_demo').hide(); return false;">Reset</a></li>
+</ul>
+
+ +
\ No newline at end of file diff --git a/_posts/2009-01-01-effect-highlight.html b/_posts/2009-01-01-effect-highlight.html new file mode 100644 index 0000000..6901a8f --- /dev/null +++ b/_posts/2009-01-01-effect-highlight.html @@ -0,0 +1,68 @@ +--- +layout: default +title: Effect.Highlight +category: Core Effects +--- + +
+ +

Core Effects > Effect.Highlight

+

This effect flashes a color as the background of an element. It is mostly used to draw attention to a part of the page that has been updated via JavaScript or AJAX, when the update would not otherwise be obvious.

+

Syntax

+

+new Effect.Highlight('id_of_element', [options]);
+new Effect.Highlight(element, [options]);
+
+

Options

+ + + + + + + + + + + + + + + + + + + + + +
Option Description
startcolor Sets the color of first frame of the highlight. Defaults to ”#ffff99” (a light yellow).
endcolor Sets the color of the last frame of the highlight. This is best set to the background color of the highlighted element. Defaults to ”#ffffff” (white).
restorecolor Sets the background-color of the element after the highlight has finished. Defaults to the current background-color of the highlighted element (see Note).
keepBackgroundImage Unless this is set to true, any background image on the element will not be preserved.
+

Notes

+

If the restorecolor option is not given, Effect.Highlight tries to find out the current background color of the element, which will only work reliably across browsers if the color is given with a CSS rgb triplet, like rgb(0, 255, 0).

+

Be aware of the syntax: this effect strictly requires a new in front, otherwise you will get a javascript error.

+

If you specify the startcolor or endcolor using short-form notation, as in #ccf, the effect will fail silently. Use the long-form, as in #ccccff.

+

Also be aware that applying an effect (without setting a restorecolor), to an element that already has an highlight effect in progress, will cause the restorecolor to be set to the elements background-color at the time of the new effect, and not the original background-color. For example, click the example below 4-5 times in quick succession, and the paragraph will stay yellow as opposed to the original white.

+

Demo

+
+

+This paragraph exists for demo purposes. Click the link below and it will make your day bright!
+ +Highlight me! + +

+
+

Source code of this demo

+

+<p id="highlight_demo" style="padding:10px; border:1px solid #ccc; background:#ffffff;">
+  This paragraph exists for demo purposes. Click the above link and it will make your day 
+bright!<br/>
+  
+  <a href="#" onclick="new Effect.Highlight(this.parentNode, { startcolor: '#ffff99',
+endcolor: '#ffffff' }); return false;">
+    Highlight me!
+  </a>
+</p>
+
+ +
\ No newline at end of file diff --git a/_posts/2009-01-01-effect-methods.html b/_posts/2009-01-01-effect-methods.html new file mode 100644 index 0000000..f087670 --- /dev/null +++ b/_posts/2009-01-01-effect-methods.html @@ -0,0 +1,135 @@ +--- +layout: default +title: Effect.Methods +category: Effect Helpers +--- + +
+ +

Effect.Methods is a mixin of various effects and helper functions for DOM elements.
+These methods can be accessed through the $() function or through any Element object.

+

Syntax

+

+$(element).methodName(arguments);
+
+

The following methods are included within Effect.Methods and can be used as a shortcut for effects, helpers, etc you might want to call on an element:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Method Name Description
morph(element, style, options) starts an Effect.Morph on the element, takes style (the styles string or hash for the effect) as the first parameter, takes an optional second parameter which is the options hash for the effect
visualEffect(element, effect, options) specify any of the supported effects and pass options
getInlineOpacity a shortcut for Element#getInlineOpacity?
forceRerendering a shortcut for Element#forceRerendering?
setContentZoom a shortcut for Element#setContentZoom?
collectTextNodes a shortcut for Element#collectTextNodes?
collectTextNodesIgnoreClass a shortcut for Element#collectTextNodesIgnoreClass?
getStyles a shortcut for Element.getStyles?
+

Additional to this set of helper function, also all of scriptaculous’ Combination Effects and Core Effects are available within Effect.Methods and take the an options hash as an optional parameter:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Method Name Description
fade a shortcut for Effect.Fade
appear a shortcut for Effect.Appear
grow a shortcut for Effect.Grow
shrink a shortcut for Effect.Shrink
fold a shortcut for Effect.Fold
blindUp a shortcut for Effect.BlindUp
blindDown a shortcut for Effect.BlindDown
slideUp a shortcut for Effect.SlideUp
slideDown a shortcut for Effect.SlideDown
pulsate a shortcut for Effect.Pulsate
shake a shortcut for Effect.Shake
puff a shortcut for Effect.Puff
squish a shortcut for Effect.Squish
switchOff a shortcut for Effect.SwitchOff
dropOut a shortcut for Effect.DropOut
highlight a shortcut for Effect.Highlight
+

Examples

+

+$('id_of_element').highlight();
+$('id_of_element').visualEffect('Opacity', { from: 1.0, to: 0.7, duration: 0.5 });
+$('id_of_element').morph({ height: '50px', width: '200px' }, { duration: 0.5 });
+$('id_of_element').fade({ delay: 0.3, duration: 0.8 });
+
+ +
\ No newline at end of file diff --git a/_posts/2009-01-01-effect-morph.html b/_posts/2009-01-01-effect-morph.html new file mode 100644 index 0000000..9f53e16 --- /dev/null +++ b/_posts/2009-01-01-effect-morph.html @@ -0,0 +1,72 @@ +--- +layout: default +title: Effect.Morph +category: Core Effects +--- + +
+ +

Core Effects > Effect.Morph

+

This effect changes the CSS properties of an element.

+

Availability

+

script.aculo.us V1.7 and later.

+

Syntax

+

Simple:
+


+$('morph_example').morph('background:#080; color:#fff;');
+

+

Complex:
+


+new Effect.Morph('error_message', {
+  style: 'background:#f00; color: #fff;', // CSS Properties
+  duration: 0.8 // Core Effect properties
+});

+

new Effect.Morph(‘error_message’, {
+ style: {
+ background: ‘#f00’,
+ color: ‘#fff’
+ }, // CSS Properties
+ duration: 0.8 // Core Effect properties
+});

+

new Effect.Morph(‘message’, {
+ style: ‘error’, // CSS class name
+ duration: 0.8 // Core Effect properties
+});
+

+

Style as a hash (keys should be javascript names (camel-cased), rather than CSS ones i.e. backgroundColor rather than background-color):

+

Options

+ + + + + + + + + +
Option Description
style the target style of your element, as a string written with the standard CSS syntax, a hash, or a CSS class name.
+

Demo

+ +

Source code of this demo

+

+<div id="morph_demo" style="background:#cccccc; width:100px; height:100px;"></div>
+<ul>
+  <li><a href="#" onclick="$('morph_demo').morph('background:#00ff00; width:300px;'); return false;">Click me for a demo!</a></li>
+  <li><a href="#" onclick="$('morph_demo').morph('background:#cccccc; width:100px;'); return false;" >Reset the demo!</a></li>
+</ul>
+
+

Details

+

Effect.Morph takes orginal styles given by CSS style rules or inline style attributes into consideration when calculating the transforms. It works with all length and color based CSS properties, including margins, paddings, borders, opacity and text/background colors.

+

Implementation Details

+

Because Effect.Morph queries the original values with Prototype’s Element.getStyle API, it doesn’t matter whether these styles are set inline or in an external stylesheet definition. Of course the effect supports all usual options, like duration or transition.
+
+

+
\ No newline at end of file diff --git a/_posts/2009-01-01-effect-move.html b/_posts/2009-01-01-effect-move.html new file mode 100644 index 0000000..b4ceada --- /dev/null +++ b/_posts/2009-01-01-effect-move.html @@ -0,0 +1,60 @@ +--- +layout: default +title: Effect.Move +category: Core Effects +--- + +
+ +

Core Effects > Effect.Move

+

This effect moves an element by modifying its position attributes.

+

Syntax

+

This will move the object to the top left corner of the window (x=0; y=0):
+


+new Effect.Move('object', { x: 0, y: 0, mode: 'absolute' });
+

+

This will move the object 30px up and 20px to the right relative to its current position:
+


+new Effect.Move('object', { x: 20, y: -30, mode: 'relative' });
+

+

Options

+ + + + + + + + + + + + + + + + + +
Options Description
x integer value, either the new absolute target of the effect elements left value or the modifier of its current left value, depending on the mode option
y integer value, either the new absolute target of the effect elements top value or the modifier of its current top value, depending on the mode option
mode string, defaults to 'relative', can also be 'absolute', specifies if the element is moved absolutely or relative to its own position.
+

Demo

+ + +

Source code of this demo

+

+<style type="text/css">
+  a#move_demo { background:#fa0000; color:#fff; padding:5px; border:1px solid #000; }
+</style>
+
+<div class="demo">
+  <a href="#" id="move_demo" onclick="new Effect.Move(this, { x: 60, y: -30 }); return
+false;">Click me for a demo!</a>
+</div>
+
+ +
\ No newline at end of file diff --git a/_posts/2009-01-01-effect-multiple.html b/_posts/2009-01-01-effect-multiple.html new file mode 100644 index 0000000..7b9cc5b --- /dev/null +++ b/_posts/2009-01-01-effect-multiple.html @@ -0,0 +1,114 @@ +--- +layout: default +title: Effect.multiple +category: Effect Helpers +--- + +
+ +

Effect multiple takes an array of elements and performs a given effect for each element. If one specific element is passed instead of an array of elements, the specific elements child nodes will be used for the effect. Each subsequent effect will start by default with a slight delay depending on the speed option.

+

Syntax

+

+Effect.multiple([element1, element2, element3, â€Ĥ], Effect); // takes an array of elements
+Effect.multiple(element, Effect); // also takes a specific element and will use its childNodes
+
+

Options

+

Additional to a typical effects options, Effect.multiple also takes these options:

+ + + + + + + + + + + + + +
Option Description
speed float value, defaults to 0.1, a delay offset for each subsequent effect
delay float value, defaults to 0.0, the effects start delay
+

Examples

+

+Effect.multiple('id_of_element', Effect.Fade); // performs an Effect.Fade for each childNode of the given element
+Effect.multiple(['id_one', 'id_two'], Effect.Puff); // performs an Effect.Puff for each element in the given array
+Effect.multiple('id_of_element', Effect.Fade, { speed: 0 }); // instantely performs an Effect.Fade for each childNode of the given element
+
+

If you want to use the toggle effect:

+

+Effect.multiple(['id_one','id_two'],function(el){Effect.toggle(el,'appear');});
+
+
+

In this case we selected the appear effect. Thanks to Richard.

+

Demo

+ +
+ Click somewhere on the list for a demo. Reset the demo. +
    +
  • This is
  • +
  • what you
  • +
  • can do
  • +
  • with
  • +
  • Effect.multiple
  • +
+
+ +

Source code of this demo

+

+<style type="text/css">
+  ul#multiple_demo { cursor:pointer; }
+  ul#multiple_demo li { font-size:16px; }
+</style>
+
+<div class="demo">
+  Click somewhere on the list for a demo. <a href="#" id="reset_link">Reset the demo</a>.
+  <ul id="multiple_demo" class="on">
+    <li>This is</li>
+    <li>what you</li>
+    <li>can do</li>
+    <li>with</li>
+    <li>Effect.multiple</li>
+  </ul>
+</div>
+
+<script type="text/javascript">
+  (function() {
+    $('multiple_demo').observe('click', fadeListItems);
+    $('reset_link').observe('click', reset);
+    
+    var listItems = $('multiple_demo').select('li');
+    
+    function fadeListItems() {
+      Effect.multiple(listItems, Effect.Fade);
+    }
+    
+    function reset(event) {
+      event.stop();
+      Effect.multiple(listItems, Effect.Appear);
+    }
+  })();
+</script>
+
+ +
\ No newline at end of file diff --git a/_posts/2009-01-01-effect-opacity.html b/_posts/2009-01-01-effect-opacity.html new file mode 100644 index 0000000..48e98c8 --- /dev/null +++ b/_posts/2009-01-01-effect-opacity.html @@ -0,0 +1,43 @@ +--- +layout: default +title: Effect.Opacity +category: Core Effects +--- + +
+ +

Core Effects > Effect.Opacity

+

This effect changes an element’s opacity (transparency).

+

Syntax

+

+new Effect.Opacity('id_of_element', [options]);
+new Effect.Opacity(element, [options]);
+
+

Examples

+

A simple example
+


+new Effect.Opacity('id_of_element', { from: 1.0, to: 0.7, duration: 0.5 });
+

+This will fade the element from 100% to 70% over the space of 1/2 second.

+

Notes

+

Microsoft Internet Explorer can only set opacity on elements that have a ‘layout’ (see IE Element Layout).

+

Demo

+ +

Source code of this demo

+

+<div id="opacity_demo" style="width:100px; height:100px; background:#ccc;"></div>
+<ul>
+  <li><a href="#" onclick="new Effect.Opacity('opacity_demo', { from: 1, to: 0 }); return false;">Hide this box</a></li>
+  <li><a href="#" onclick="new Effect.Opacity('opacity_demo', { from: 0, to: 1 }); return false;">Show this box</a></li>
+</ul>
+
+ +
\ No newline at end of file diff --git a/_posts/2009-01-01-effect-parallel.html b/_posts/2009-01-01-effect-parallel.html new file mode 100644 index 0000000..7883063 --- /dev/null +++ b/_posts/2009-01-01-effect-parallel.html @@ -0,0 +1,106 @@ +--- +layout: default +title: Effect.Parallel +category: Core Effects +--- + +
+ +

Core Effects > Effect.Parallel

+

This is a special effect which allows to combine more than one core effect into a parallel effect. It’s the only effect that doesn’t take an element as first parameter, but an array of subeffects.

+

Syntax

+

+ new Effect.Parallel([array of subeffects], [options]);
+
+

Examples

+

+new Effect.Parallel([
+  new Effect.Move(element, { sync: true, x: 20, y: -30, mode: 'relative' }), 
+  new Effect.Opacity(element, { sync: true, from: 1, to: 0 }) 
+], { 
+  duration: 0.8,
+  delay: 0.5
+});
+
+

Options

+ + + + + + + + + +
Option Description
sync boolean, has to be true in order to prevent the subeffects from being started as soon as they get instantiated.
+

Notes

+

Don’t forget to set the sync option to true for all of the subeffects or else all the effects will start immediately after they were instantiated.

+

For IE7 and IE8 don’t put an extra comma at the end of the array of effects.
+i.e. new Effect.Parallel([new Effect.Fade(), new Effect.Appear(), ]);
+The extra comma at the end will cause the effect to fail in IE7-IE8 on the first pass.

+

Demo

+ + +

Source code of the demo

+

+<div id="parallel_demo" style="width:150px; height:40px; background:#ccc;"></div>
+<ul>
+  <li><a href="#" id="animate_parallel_demo">Click here for a demo!</a></li>
+  <li><a href="#" id="reset_parallel_demo">Reset</a></li>
+</ul>
+</div>
+
+<script type="text/javascript">
+$('animate_parallel_demo').observe('click', function(event) {
+  event.stop();
+  
+  new Effect.Parallel([
+    new Effect.Move('parallel_demo', { sync: true, x: 400, y: 0, mode: 'relative' }), 
+    new Effect.Opacity('parallel_demo', { sync: true, from: 1, to: 0 })
+  ], { 
+    duration: 1.5
+  });
+});
+
+$('reset_parallel_demo').observe('click', function(event) {
+  event.stop();
+  
+  $('parallel_demo').setStyle({
+    top: 0,
+    left: 0,
+    opacity: 1
+  });
+});
+</script>
+
+ +
\ No newline at end of file diff --git a/_posts/2009-01-01-effect-puff.html b/_posts/2009-01-01-effect-puff.html new file mode 100644 index 0000000..a256183 --- /dev/null +++ b/_posts/2009-01-01-effect-puff.html @@ -0,0 +1,60 @@ +--- +layout: default +title: Effect.Puff +category: Combination Effects +--- + +
+ +

Combination Effects > Effect.Puff

+

Gives the illusion of the element puffing away (like a in a cloud of smoke).

+

Examples

+

+Effect.Puff('id_of_element');
+Effect.Puff('id_of_element', { duration: 3 });
+
+

+$('id_of_element').puff();
+$('id_of_element').puff({ duration: 3 });
+
+

Options

+ + + + + + + + + + + + + + + + + +
Options Description
duration float value, in seconds, defaults to 1.0
from float value, defaults to 0.0, percent of animation to start
to float value, defaults to 1.0, percent of animation to end
+

Notes

+

Works safely with most block elements, except tables.

+

Demo

+ +

Source code of the demo

+

+<div id="puff_demo" style="width:80px; height:80px; background:#c2defb; border:1px solid #333;"></div>
+<ul>
+  <li><a href="#" onclick="new Effect.Puff('puff_demo'); return false;">Click here for a demo!</a></li>
+  <li><a href="#" onclick="$('puff_demo').setStyle({ display: 'block', opacity:1, width:'80px', height:'80px' }); return false;">Reset</a></li>
+</ul>
+
+ +
\ No newline at end of file diff --git a/_posts/2009-01-01-effect-pulsate.html b/_posts/2009-01-01-effect-pulsate.html new file mode 100644 index 0000000..6eae882 --- /dev/null +++ b/_posts/2009-01-01-effect-pulsate.html @@ -0,0 +1,54 @@ +--- +layout: default +title: Effect.Pulsate +category: Combination Effects +--- + +
+ +

Combination Effects > Effect.Pulsate

+

Pulsates the element, loops over five times over fading out and in.

+

Examples

+

+Effect.Pulsate('id_of_element');
+Effect.Pulsate('id_of_element', { pulses: 5, duration: 1.5 });
+
+

Options

+ + + + + + + + + + + + + + + + + +
Option Description
duration float value, in seconds, defaults to 2.0
from float value, defaults to 0.0, the minimal opacity during the pulsate, in a value between 0.0 and 1.0. For example, use 0.7 for a mild pulsate
pulses integer value, defaults to 5, the amount of pulses within the duration time
+

Notes

+

Works safely with most HTML elements, except table rows, table bodies and table heads.

+

Microsoft Internet Explorer can only set opacity on elements that have ‘layout’. To let an element have layout, you must set some CSS positional properties, like width or height. See Giving Elements Layout.

+

In Firefox, at least, if the element that you Pulsate has a :hover CSS psuedo class and you mouse over it while it’s pulsating, the effect will stop.

+

Demo

+ +

Source code of this demo

+

+<div id="pulsate_demo" style="width:150px; height:40px; background:#ccc; text-align:center;">
+  <a href="#" onclick="Effect.Pulsate('pulsate_demo'); return false;" style="line-height:40px;">Click me to pulsate!</a>
+</div>
+
+ +
\ No newline at end of file diff --git a/_posts/2009-01-01-effect-queues.html b/_posts/2009-01-01-effect-queues.html new file mode 100644 index 0000000..8d6417d --- /dev/null +++ b/_posts/2009-01-01-effect-queues.html @@ -0,0 +1,98 @@ +--- +layout: default +title: Effect Queues +category: Effect Helpers +--- + +
+ +

What is a Queue

+

Let’s examine how events in a queue occur: For a programmer a queue is an Array with events that are stacked on each other to be handled one by one. For example, a user hovers over a button with his cursor and then after half a second leaves the button area again. Two events have taken place, the mouseover and the mouseout. If you would handle the mouseover and the mouseout event takes place, it could disturb your current process. However you can’t just ignore the event, because then you will be stuck in the status that is established by the actions you have performed for mouseover. In this situation you could add the event to a queue and every time you’re done with processing an event, just check the queue for unprocessed events (and act accordingly).

+

How do Effects work and why do you need a Queue

+

The same happens when you are dealing with Effects and you face the situation where two effects can be called, both of which manipulate the same DOM object(s). script.aculo.us comes to the rescue with several techniques to manage your effects. To explain this further, we will show you how things work by example.

+

Let’s start creating two effects

+

I created a page, with a div[id=”test1”] and some content, on the following page called Example 1 . This page has an onload handler that executes two effects:
+


+new Effect.SlideDown('test1');
+new Effect.SlideUp('test1');
+

+
+ +
+
LAST
+
FIRST
+
+
+

These effects are executed in parallel and thus one effects tries to slide the div down and the other to slide it up. It doesn’t work and you only see some flickering. However a similar thing occurs when you call new Effect.Slide Down(‘test1’); with an onclick and then new Effect.SlideUp(‘test1’); with an onclick to during the first effect. When you do this several times (quickly), you will see that the effects don’t work anymore. The same problem also occurs in many other situations. That’s why we need Effect.Queue.

+

Effect.Queue

+

The previous examples gave you an idea of the situations you could be facing without Queues. This must give you some motivation to find how Effect.Queue could improve your live and help you to manage your Effects.

+

Effect.Queue is an improved array of Effects (called Enumerable) that is global for the entire page. It gets created by extracting the global queue from Effect.Queues (we will discuss this later). So all effects you want to queue will be added to the global queue. You might be wondering how to add an effect to the queue? Well it’s quite easy.

+

When you are creating an effect, you can pass several arguments. Let’s look at How effects are created. The first argument is the DOM element you wish to manipulate, but you already know that. The second argument is actually an array of options that you can pass along, let’s examine that for Effect.Queue. We will use Effect.SlideDown and Effect.SlideUp like in the previous examples.
+


+new Effect.SlideDown('test1');
+new Effect.SlideUp('test1', { queue: 'end' });
+

+So you see I have added an array containing an entry queue: with the value end. This means that the Effect will be inserted at the end of the “global” Queue. All effects are always added to the queue, however without a position like ‘end’ they are always executed parallel to the other effects.

+

Let’s take a look at the improved example 1. You see that first the element slides down and then it slides back up again. There is also an option to insert the Effect at the front of the queue. You would use front instead of end in that case.
+


+new Effect.SlideUp('test1', { queue: 'end' });
+new Effect.SlideDown('test1', { queue: 'front' });
+

+This would place the SlideDown before the SlideUp effect (same as the previous examples). The argument you pass as queue: is called a position and it can be used with a different syntax, but we will go into that later.

+

Remember that JavaScript is not multi-threaded, so blocks of code are executed together when they get parsed. This causes the effects to start in parallel if no queue is defined.

+

This works nicely, doesn’t it? But what happens when you queue all kinds of effects in different places? You could have lots of effects that you would like to queue but they don’t all relate to each other. This is where Effect.ScopedQueue? comes in.

+

Basic Effect.ScopedQueue

+

As explained before, the default Queue is ‘global’. All effects are placed in the ‘global’ Queue unless you define a different scope. A scope is nothing more than grouping a set of Effects together in their own Queue. To do this, you need to pass an array instead of a string to the “queue:” option (so you have an array inside the outer array). This can only be done by using a different syntax to define the Queue position.
+Small and easy syntax:
+


+new Effect.SlideUp('test1', { queue: 'end' });
+

+

Syntax that allows for more tuning:
+


+new Effect.SlideUp('test1', { queue: { position: 'end' } });
+

+

The two examples are identical produce identical behaviour. However, the second syntax allows you to define a scope (a different queue) with the following syntax:
+


+new Effect.SlideUp('menu', { queue: { position: 'end', scope: 'menuxscope' } });
+new Effect.SlideUp('bannerbig', { queue: { position: 'end', scope: 'bannerscope' } });
+new Effect.SlideDown('menu', { queue: { position: 'end', scope: 'menuxscope' } });
+

+The scope: argument has defined a separate queue named ‘menuxscope’. This queue could for example contain all menu-related effects. A second scope named “bannerscope” is defined, it could contain all banner-related effects. In what order are these separate queues executed? First both 1 and 2 get executed, and when 1 is done 3 is executed. Check example 3 for a preview

+

Just remember, if you don’t define a scope, the effect is added to the default “global” scope, which can be accessed from Effect.Queue.

+

Limit

+

Sometimes too many effects get queued, for example when a user presses a button twice, or repeatedly enters and leaves a button hover area (and each time two effects are queued). This can cause a lot of distracting activity. To prevent this, we can add a “limit: n” option to the queue so no more than n effects are added to that ScopedQueue.
+


+new Effect.SlideDown('menu', { queue: { position: 'end', scope: 'menuxscope',
+limit: 2 } }); // #1

+

new Effect.Highlight(‘menu’, { queue: { position: ‘end’, scope: ‘menuxscope’,
+limit: 2 } }); // #2

+

new Effect.SlideUp(‘menu’, { queue: { position: ‘end’, scope: ‘menuxscope’,
+limit: 2 } }); // #3
+

+
    +
  1. and #2 will be added to the queue but #3 will not.
  2. +
+

This covers the queue for Effects, so let’s move on to Effect.Queues.

+

Effect.Queues

+

So what is Effect.Queues and why do we need it? Well, for each scope an instance of Effect.Scoped Queue is created. That instance is stored in Effect.Queues. You can access it by using Effect.Queues.get(‘global’) which is the same as Effect.Queue because the default ‘global’ queue is saved into Effect.Queue by script.aculo.us. However when you need to access a scope other than ‘global, you need to fetch it using Effect.Queues.get(‘myscope’) before you can manipulate it.
+


+var queue = Effect.Queues.get('myscope');
+

+

ScopedQueue manages the ‘effects’, this is an internal system accessed by the Effect object. However you can, if you wish, add effects to the queue and remove them by yourself. Note that this requires some knowledge about the internal workings of the system.

+

ScopedQueue is just an Enumerable object. You can retrieve the effects one by one and manipulate them. Let’s look at how we can ‘empty a queue’.
+


+var queue = Effect.Queues.get('myscope');
+queue.each(function(effect) { effect.cancel(); });
+

+which can also be written as:
+

+Effect.Queues.get('myscope').invoke('cancel');
+

+Or maybe you want to change the interval between the effects in a queue:
+

+Effect.Queues.get('myscope').interval = 100;
+

+ +
\ No newline at end of file diff --git a/_posts/2009-01-01-effect-scale.html b/_posts/2009-01-01-effect-scale.html new file mode 100644 index 0000000..d549c63 --- /dev/null +++ b/_posts/2009-01-01-effect-scale.html @@ -0,0 +1,57 @@ +--- +layout: default +title: Effect.Scale +category: Core Effects +--- + +
+ +

Core Effects > Effect.Scale

+

This effect changes an elements width and height dimensions and the base for em units. This allows for smooth, automatic relative scaling of elements contained within the scaled element.

+

Syntax

+

+new Effect.Scale('id_of_element', percent, [options]);
+new Effect.Scale(element, percent, [options]);
+
+

Effect Options

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Option Description
scaleX Sets whether the element should be scaled horizontally, defaults to true.
scaleY Sets whether the element should be scaled vertically, defaults to true.
scaleContent Sets whether content scaling should be enabled, defaults to true.
scaleFromCenter If true, scale the element in a way that the center of the element stays on the same position on the screen, defaults to false.
scaleMode Either ‘box’ (default, scales the visible area of the element) or ‘contents’ (scales the complete element, that is parts normally only visible byscrolling are taken into account). You can also precisely control the size the element will become by assigning the originalHeight and originalWidth variables to scaleMode. Example: scaleMode: { originalHeight: 900, originalWidth: 900 }
scaleFrom Sets the starting percentage for scaling, defaults to 100.0.
+

Demo

+

Click me for Demo!

+

Source code of this demo

+

+<a href='#' onclick="new Effect.Scale(this.parentNode, 200); return false;">Click me for 
+Demo!</a>
+
+ +
\ No newline at end of file diff --git a/_posts/2009-01-01-effect-scrollto.html b/_posts/2009-01-01-effect-scrollto.html new file mode 100644 index 0000000..ae2ec80 --- /dev/null +++ b/_posts/2009-01-01-effect-scrollto.html @@ -0,0 +1,43 @@ +--- +layout: default +title: Effect.ScrollTo +category: Combination Effects +--- + +
+

+ +

Combination Effects > Effect.ScrollTo

+

Scrolls to a specific place in the page.

+

Examples

+

+Effect.ScrollTo( 'li:eq(15)', 1000, {axis:'x'} ); // hmm, is this right?
+Effect.ScrollTo('element_id', { duration:'0.2', offset:-20 }); // works in v1.8.2
+
+

Options

+ + + + + + + + + + + + + +
Option Description
duration float value, in seconds, defaults to 1.0
offset integer value, vertical offset of the target element, in pixels, defaults to 0
+

Notes

+

The offset option must be a numeric value in your code, i.e. not in quotes.

+

Demo

+

Click me to scroll to the top of the article

+

Source code of this demo

+

+<a href="#" onclick="Effect.ScrollTo('article_top'); return false;">Click me to scroll to the top of the article</a>
+
+ +
\ No newline at end of file diff --git a/_posts/2009-01-01-effect-shake.html b/_posts/2009-01-01-effect-shake.html new file mode 100644 index 0000000..415f4ba --- /dev/null +++ b/_posts/2009-01-01-effect-shake.html @@ -0,0 +1,47 @@ +--- +layout: default +title: Effect.Shake +category: Combination Effects +--- + +
+ +

Combination Effects > Effect.Shake

+

Moves the element slightly to the left, then to the right, repeatedly.

+

Examples

+

+Effect.Shake('id_of_element');
+
+

Options

+ + + + + + + + + + + + + +
Option Description
duration float value, in seconds, defaults to 0.5
distance integer value, defaults to 20, the number of pixels to move horizontally
+

Notes

+

Works safely with most Block Elements, except tables.

+

Demo

+ +

Source code of this demo

+

+<div id="shake_demo" style="width:150px; height:40px; background:#ccc; text-align:center;>
+  <a href="#" onclick="new Effect.Shake('shake_demo'); return false;" style="line-height:40px;">Click me to shake!</a>
+</div>
+
+ +
\ No newline at end of file diff --git a/_posts/2009-01-01-effect-shrink.html b/_posts/2009-01-01-effect-shrink.html new file mode 100644 index 0000000..01ca895 --- /dev/null +++ b/_posts/2009-01-01-effect-shrink.html @@ -0,0 +1,52 @@ +--- +layout: default +title: Effect.Shrink +category: Combination Effects +--- + +
+ +

Combination Effects > Effect.Shrink

+

“Shrinks” an element into a specific direction (see demo for better understanding), hides it when the effect is complete.

+

Examples

+

+Effect.Shrink('id_of_element');
+
+

Options

+ + + + + + + + + + + + + +
Option Description
direction string, defaults to 'center', can also be: 'top-left', 'top-right', 'bottom-left', 'bottom-right', the direction to “shrink” the element to
duration float value, in seconds, defaults to 1.0
+

Notes

+

Works safely with most Block Elements, except tables.
+You can define different durations for several div elements, and place them in a row in order to make them disappear one after another.

+

Demo

+ +

Source code of this demo

+

+<div id="shrink_demo" style="width:80px; height:80px; background:#ccc;"></div>
+<ul>
+  <li><a href="#" onclick="Effect.Shrink('shrink_demo'); return false;">Click me for a demo!</a></li>
+  <li><a href="#" onclick="$('shrink_demo').show(); return false;">Reset</a></li>
+</ul>
+
+ +
\ No newline at end of file diff --git a/_posts/2009-01-01-effect-slidedown.html b/_posts/2009-01-01-effect-slidedown.html new file mode 100644 index 0000000..083904b --- /dev/null +++ b/_posts/2009-01-01-effect-slidedown.html @@ -0,0 +1,101 @@ +--- +layout: default +title: Effect.SlideDown +category: Combination Effects +--- + +
+ +

Combination Effects > Effect.SlideDown

+

This effect simulates a window blind, where the contents of the affected elements scroll up and down accordingly.

+

Examples

+
Effect.SlideDown('id_of_element');
+Effect.SlideDown('id_of_element', { duration: 3.0 });
+
+

Options

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Option Description
scaleX boolean, defaults to false
scaleY boolean, defaults to true
scaleContent boolean, defaults to true
scaleFromCenter boolean, defaults to false
scaleMode string, defaults to ‘box', can also be ‘contents‘
scaleFrom integer value, percentage (0%–100%), defaults to 100
scaleTo integer value, percentage (0%–100%), defaults to 0
duration float value, in seconds, defaults to 1.0
+

Notes

+

Include a second div element, wrapping the contents of the outer div. So, if you call new Effect.SlideDown('x');, your element must look like this:

+
<div id="x">
+  <div>
+    contents
+  </div>
+</div>
+
+

The target element should not have padding set, otherwise you’ll see the effect “bouncing”. (See discussion)

+

Because of a bug in Internet Explorer 6 (overflow not correctly hidden), an additional wrapper div is needed if you want to use these effects on absolutely positioned elements (wrapper is the absolutely positioned element, x has position:relative set):

+
<div id="wrapper">
+  <div id="x">
+    <div>
+      contents
+    </div>
+  </div>
+</div>
+
+

Works only on block elements.

+

In Internet Explorer 6.0 there’s a problem where floated block level elements don’t animate. If you add a position: relative to the element it all works though.

+

The opposite of Effect.SlideDown is Effect.SlideUp.

+

Demo

+
+ + +
+

Source code of this demo

+
<div id="slidedown_demo" style="display:none; width:80px; height:80px; background:#ccc; text-align:center;">
+  <div>
+    This is some test content. This is some test content.
+  </div>
+</div>
+<ul>
+  <li><a href="#" onclick="Effect.SlideDown('slidedown_demo'); return false;">Click here for a demo!</a></li>
+  <li><a href="#" onclick="$('slidedown_demo').hide(); return false;">Reset</a></li>
+</ul>
+
+ +
\ No newline at end of file diff --git a/_posts/2009-01-01-effect-slideup.html b/_posts/2009-01-01-effect-slideup.html new file mode 100644 index 0000000..d8bb46d --- /dev/null +++ b/_posts/2009-01-01-effect-slideup.html @@ -0,0 +1,104 @@ +--- +layout: default +title: Effect.SlideUp +category: Combination Effects +--- + +
+ +

Combination Effects > Effect.SlideUp

+

This effect simulates a window blind, where the contents of the affected elements scroll up accordingly.

+

Examples

+

+Effect.SlideUp('id_of_element');
+Effect.SlideUp('id_of_element', { duration: 3.0 });
+
+

Options

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Option Description
scaleX boolean, defaults to false
scaleY boolean, defaults to true
scaleContent boolean, defaults to true
scaleFromCenter boolean, defaults to false
scaleMode string, defaults to ‘box', can also be ‘contents‘
scaleFrom integer value, percentage (0%–100%), defaults to 100
scaleTo integer value, percentage (0%–100%), defaults to 0
duration float value, in seconds, defaults to 1.0
+

Notes

+

Include a second div element, wrapping the contents of the outer div. So, if you call new Effect.SlideUp('x');, your element must look like this:

+

+<div id="x">
+  <div>
+    contents
+  </div>
+</div>
+
+

Because of a bug in Internet Explorer 6 (overflow not correctly hidden), an additional wrapper div is needed if you want to use these effects on absolutely positioned elements (wrapper is the absolutely positioned element, x has position:relative set):

+

+<div id="wrapper">
+  <div id="x">
+    <div>
+      contents
+    </div>
+  </div>
+</div>
+
+

Works only on block elements.

+

In Internet Explorer 6.0 there’s a problem where floated block level elements don’t animate. If you add a position: relative to the element it all works though.

+

The opposite of Effect.SlideUp is Effect.SlideDown.

+

Demo

+
+
+
+This is some test content. This is some test content. +
+
+ +
+

Source code of this demo

+

+<div id="slideup_demo" style="width:80px; height:80px; background:#ccc; text-align:center;">
+  <div>
+    This is some test content. This is some test content.
+  </div>
+</div>
+<ul>
+  <li><a href="#" onclick="Effect.SlideUp('slideup_demo'); return false;">Click here for a demo!</a></li>
+  <li><a href="#" onclick="$('slideup_demo').show(); return false;">Reset</a></li>
+</ul>
+
+ +
\ No newline at end of file diff --git a/_posts/2009-01-01-effect-squish.html b/_posts/2009-01-01-effect-squish.html new file mode 100644 index 0000000..d60d676 --- /dev/null +++ b/_posts/2009-01-01-effect-squish.html @@ -0,0 +1,36 @@ +--- +layout: default +title: Effect.Squish +category: Combination Effects +--- + +
+ +

Combination Effects > Effect.Squish

+

Reduce the element to its top-left corner.

+

Examples

+

+Effect.Squish('id_of_element');
+
+

Notes

+

Works safely with most Block Elements, except tables.

+

Demo

+ +

Source code of this demo

+

+<div id="squish_demo" style="width:80px; height:80px; background:#ccc;"></div>
+<ul>
+  <li><a href="#" onclick="Effect.Squish('squish_demo'); return false;">Click me for a demo!</a></li>
+  <li><a href="#" onclick="$('squish_demo').show(); return false;">Reset</a></li>
+</ul>
+
+ +
\ No newline at end of file diff --git a/_posts/2009-01-01-effect-switchoff.html b/_posts/2009-01-01-effect-switchoff.html new file mode 100644 index 0000000..344e515 --- /dev/null +++ b/_posts/2009-01-01-effect-switchoff.html @@ -0,0 +1,36 @@ +--- +layout: default +title: Effect.SwitchOff +category: Combination Effects +--- + +
+ +

Combination Effects > Effect.SwitchOff

+

Gives the illusion of a TV-style switch off.

+

Examples

+

+Effect.SwitchOff('id_of_element');
+
+

Notes

+

Works safely with most Block Elements, except tables.

+

Demo

+ +

Source code of this demo

+

+<div id="switchoff_demo" style="width:80px; height:80px; background:#ccc;"></div>
+<ul>
+  <li><a href="#" onclick="Effect.SwitchOff('switchoff_demo'); return false;">Click here for a demo!</a></li>
+  <li><a href="#" onclick="$('switchoff_demo').show(); return false;">Reset</a></li>
+</ul>
+
+ +
\ No newline at end of file diff --git a/_posts/2009-01-01-effect-tagifytext.html b/_posts/2009-01-01-effect-tagifytext.html new file mode 100644 index 0000000..345b9ae --- /dev/null +++ b/_posts/2009-01-01-effect-tagifytext.html @@ -0,0 +1,42 @@ +--- +layout: default +title: Effect.tagifyText +category: Effect Helpers +--- + +
+ +

Effect.tagifyText transforms any text string contained in a specific element into a chain of span elements, each containing one character of the string.

+

Syntax

+

+Effect.tagifyText(element);
+
+

Demo

+ +
+ which is contained in the following div. +
Go! Click on the button! Tagify me!
+
+

Source code of this demo

+

+<style type="text/css">
+  div#tagify_demo { padding:10px 0; }
+  button#tagify_button { padding:3px; }
+  div#tagify_element { border:1px solid #3071cc; padding:10px; margin-top:10px;}
+  div#tagify_element span { border:1px solid #df7418; padding:5px; }
+</style>
+
+<div class="demo" id="tagify_demo">
+  <button id="tagify_button" onclick="Effect.tagifyText('tagify_element'); return false;">Tagify the text</button> which is contained in the following <code>div</code>.
+  <div id="tagify_element">Go! Click on the button! Tagify me!</div>
+</div>
+
+ +
\ No newline at end of file diff --git a/_posts/2009-01-01-effect-toggle.html b/_posts/2009-01-01-effect-toggle.html new file mode 100644 index 0000000..ff26b72 --- /dev/null +++ b/_posts/2009-01-01-effect-toggle.html @@ -0,0 +1,71 @@ +--- +layout: default +title: Effect.toggle +category: Effect Helpers +--- + +
+ +

Effect.toggle allows for easily toggling elements with an animation.

+

Syntax

+

+Effect.toggle(element, ['appear' | 'slide' | 'blind'], [options] );
+
+

element can be either a string containing the id of the element, or a JavaScript DOM element object.

+

The options parameter is used to give any additional customization parameters to the effect. There are general and effect-specific options. See the individual effects for more information.

+

Examples

+

+Effect.toggle('id_of_element', 'appear');
+Effect.toggle('id_of_element', 'slide', { delay: 0.5 });
+Effect.toggle('id_of_element', 'blind', { duration: 2.0 });
+
+

Notes

+

Keep in mind, like individual Effects, you must include a second DIV element, wrapping the contents of the outer DIV. So, if you call new Effect.Slide Down(‘x’), your element must look like this:

+

+<div id="x">
+  <div>
+    contents
+  </div>
+</div>
+
+

Demo

+

Toggle via 'blind'

+
+Toggle the following paragraph with a ‘blind’-effect +
+
+Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. +
+
+
+

Toggle via 'slide'

+
+Toggle the following paragraph with a ‘slide’-effect +
+
+Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. +
+
+
+

Toggle via 'appear'

+
+Toggle the following paragraph with an ‘appear’-effect +
+
+Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. +
+
+
+

Source code of the demo

+

+<a href="#" onclick="Effect.toggle('toggle_appear', 'appear'); return false;">Toggle the following paragraph with an 'appear'-effect</a>
+<div id="toggle_appear" style="background:#ccc;">
+  <div>
+    Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
+  </div>
+</div>
+
+ +
\ No newline at end of file diff --git a/_posts/2009-01-01-effect-transitions.html b/_posts/2009-01-01-effect-transitions.html new file mode 100644 index 0000000..5d7eca8 --- /dev/null +++ b/_posts/2009-01-01-effect-transitions.html @@ -0,0 +1,94 @@ +--- +layout: default +title: Effect.Transitions +category: Core Effects +--- + +
+ +

Put simply, a transition in script.aculo.us is a function which transforms an input value to another value and returns it.
+Effect.Transitions is a collection of 8 of those functions which can be used to achieve interesting variations on any effect.

+

Example

+

A transition can be specified by using an effects transition option.

+

+new Effect.Move('id_of_element', {
+  x: 200, y: 0, mode: 'relative',
+  transition: Effect.Transitions.spring
+});
+
+

Demo

+

To get a better understanding of how each of script.aculo.us’ included transitions work, play around with the following demo.

+ +
+
+ Choose a transition: + + and the demo! +
+
+

+
+ + +
\ No newline at end of file diff --git a/_posts/2009-01-01-effect-tween.html b/_posts/2009-01-01-effect-tween.html new file mode 100644 index 0000000..ad62af0 --- /dev/null +++ b/_posts/2009-01-01-effect-tween.html @@ -0,0 +1,28 @@ +--- +layout: default +title: Effect.Tween +category: Core Effects +--- + +
+ +

Core Effects > Effect.Tween

+

This effect tweens between two values and sets a property or calls a method on an object (including DOM elements); or allows for a callback method, which will be automatically bound to the object.

+

Availability

+

script.aculo.us V1.8 and later.

+

Syntax

+

+ new Effect.Tween(element, startVal, endVal, [options], propertyName);
+ new Effect.Tween(element, startVal, endVal, [options], callbackFunction);
+
+

Options

+

No custom options.

+

Examples

+

+    new Effect.Tween(whatever, 5, 0, 'blech'); // sets property on the object
+    new Effect.Tween('foo', 10, 20, 'innerHTML'); // sets property on the 'foo' DOM element
+    new Effect.Tween('foo', 10, 20, 'update'); // method call on 'foo' DOM element
+    new Effect.Tween('foo', 50, 0, { duration: 2.0, afterFinish: function(){ /* do something else */} }, function(p){});
+    new Effect.Tween(null, 0, 100, function(p){ scrollTo(0,p) }); // scrolls the window
+
+
\ No newline at end of file diff --git a/_posts/2009-01-01-effects.html b/_posts/2009-01-01-effects.html new file mode 100644 index 0000000..9910024 --- /dev/null +++ b/_posts/2009-01-01-effects.html @@ -0,0 +1,31 @@ +--- +layout: default +title: Effects Overview +category: Core Effects +--- + +
+ +

The Visual Effects library (effects.js) includes all you need to add advanced JavaScript animation to your web site or application.
+All animation is time-based, not frame based. So, if you tell an effect to last exactly one second, it will do so, regardless of the rendering speed of the browser. And it’s compatible, meaning all this stuff works on Firefox, Internet Explorer, Safari, the iPhone and many other browsers.

+

The library’s Core Effects, Combination Effects (a combination of core effects) and Effect queues (a representation of timelines to create series of effects) are powerful tools to create appealing animations.

+

Quick Demo

+ +

Source code of this demo

+

+<div id="morph_demo" style="background:#cccccc; width:100px; height:100px;"></div>
+<ul>
+  <li><a href="#" onclick="$('morph_demo').morph('background:#00ff00; width:300px;'); return false;">Click me for a demo!</a></li>
+  <li><a href="#" onclick="$('morph_demo').morph('background:#cccccc; width:100px;'); return false;" >Reset the demo!</a></li>
+</ul>
+
+ +
\ No newline at end of file diff --git a/_posts/2009-01-01-faq.html b/_posts/2009-01-01-faq.html new file mode 100644 index 0000000..5cc6d48 --- /dev/null +++ b/_posts/2009-01-01-faq.html @@ -0,0 +1,62 @@ +--- +layout: default +title: FAQ +--- + +
+

If you have questions, look here first! If you feel like you’re having a questions (and maybe an answer) that will interested many people, please add it here.

+

General questions

+

1.1 Where to ask for help if I can’t find an answer here?

+

First, use the search function. If that won’t help, subscribe to the Mailing List and ask there.

+

1.2 Which browsers are supported?

+

See Supported Browsers.

+

1.3 Where can I see this in action?

+

See Demos.

+

1.4 Cool. So how to get startedâ€Ĥ?

+

See Usage.

+

1.5 So can I use this in my commercial app?

+

Yes. See License.

+

1.6 How do I extend/override without modifying the library code?

+

See HowtoExtendAndOverride.

+

1.7 How much overhead does script.aculo.us add to a page?

+

The complete library is about 228KB (including Prototype). Unofficially released compressed versions are available that can bring the files size down below 100KB, try looking on the mailing lists and support groups listed on the MailingList page for sources.

+

1.8 How do I convert a color to hex string for use in the effects?

+

String#parseColor() will convert to hex string format.
+For example:

+

“rgb(1,2,3)”.parseColor() == “#010203”;
+“#123”.parseColor() == “#102030”;
+“#112233”.parseColor() == “#112233”;

+

Effects

+

2.1 On Internet Explorer, opacity-based effects don’t work!

+

Please see GivingElementsLayout. Starting with Vh2. 1.5_rc1 this issue should be automatically handled by script.aculo.us.

+

2.2 On Internet Explorer (yes, there’s a pattern here!), Effect.SlideUp/Effect.SlideDown are brokenâ€Ĥ?

+

That’s an Internet Explorer CSS bug, see Effect.SlideDown for a workaround. See http://css.nu/pointers/bugs-ie.html for more on this.

+

2.3 Some effects cause Firefox to flicker once

+

That’s a bug with the Gecko rendering engine in Firefox h2. 1.0.×. Starting with Firefox h2. 1.5b1 the flicker is gone. You can set the ‘overflow:hidden’ CSS style on the element you run the effect on as a workaround.

+

2.4 Effect.* doesn’t work when object’s display is none!

+

The problem lies with class / id definitions. use the inline property style=”display:none;” instead

+

2.4.1 Why?

+

script.aculo.us is based off of prototype.js, and calls the ‘show’ function to make an element visible. This works by setting the element’s style.display = ’’ (undef). This is intended to set it to the default, which is visible. However, if you have a style for display defined higher up in the CSS than the inline element level (which prototype is overwriting), it will look at the undefined style on your element and cascade up. Your stylesheet probably has display=’none’, so it looks like nothing is happening.

+

2.5 Effect.Appear doesn’t work from onload. Any Ideas?

+

See question 2.4.

+

2.6 Effect.* (Effect.Move, Effect.Morph) causes “this.initialize is not defined” error. Why?

+

You may ignore the “new” keyword. Use “new Effect.Move(…)” instead of “Effect.Move”.

+

Controls

+

3.1 I get weird Java Script errors, what do I do?

+

The most common cause of this is that you don’t include all script.aculo.us libraries. If you use anything from controls.js you must include effects.js, too. Otherwise, double check if you have typos regarding your id attribute names.

+

Drag and drop

+

4.1 Dragging/Dropping doesn’t work?

+

You may run in a browser limitation here if you specify CSS properties that are needed by the libraries in an external CSS file. Please try specifying properties in the inline style attribute of the affected element(s) instead.

+

4.2 Why can’t I make sortable TABLE elements?

+

Because of technical restrictions. See Sortable.create for more info on this.

+

4.3 The onUpdate callback on Sortable.create doesn’t seem to work!

+

You’re probably missing the requirements for naming the id attributes in the elements contained in your sortable element. See Sortable.serialize for more on this.

+

Also, when you call Sortable.create incorrectly, the elements may still be sortable yet the onUpdate and/or onChange events may not fire. For example, this may occur if you pass an element reference rather than an ID string as the first parameter.

+

4.4 How do I tell a Sortable that I added new elements to it?

+

Call Sortable.create again.

+

Autocompletion

+

5.1 Why does my input box show a blank result after selecting something from the autocompletion drop down list?

+

The value selected is everything not inside an element with a class=”informal”. Remove any whitespace from the result of your auto complete responder, to prevent this from being selected.

+

5.2 Nothing happens when I type something in?

+

See question h2. 3.1 for a possible solution.

+
\ No newline at end of file diff --git a/_posts/2009-01-01-form-element-delayedobserver.html b/_posts/2009-01-01-form-element-delayedobserver.html new file mode 100644 index 0000000..8ee904c --- /dev/null +++ b/_posts/2009-01-01-form-element-delayedobserver.html @@ -0,0 +1,20 @@ +--- +layout: default +title: Form.Element.DelayedObserver +--- + +
+ +

A delayed observer works like a normal observer, but the triggered callback is delayed. Every time the observed event is observed the internal timer is reset. Once the internal timer reaches the time set in the second parameter the callback is fired.

+

Syntax

+
Form.Element.DelayedObserver(element, time, callback)
+

element: the form element to observe
+time: the internal timer after which the callback is fired (in seconds)
+callback: the callback function.

+

Example code

+

+new Form.Element.DelayedObserver($('inputbox'), 0.5, function(){
+     //do your stuff here, like an ajax request
+});
+
+
\ No newline at end of file diff --git a/_posts/2009-01-01-in-place-editing.html b/_posts/2009-01-01-in-place-editing.html new file mode 100644 index 0000000..6f8ed2a --- /dev/null +++ b/_posts/2009-01-01-in-place-editing.html @@ -0,0 +1,9 @@ +--- +layout: default +title: In Place Editing +--- + +
+

?Shahzad
+web designer planetcomnet

+
\ No newline at end of file diff --git a/_posts/2009-01-01-license.html b/_posts/2009-01-01-license.html new file mode 100644 index 0000000..ccecea1 --- /dev/null +++ b/_posts/2009-01-01-license.html @@ -0,0 +1,24 @@ +--- +layout: default +title: License +--- + +
+

Copyright © 2005-2008 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)

+

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.

+
\ No newline at end of file diff --git a/_posts/2009-01-01-list-morph-demo.html b/_posts/2009-01-01-list-morph-demo.html new file mode 100644 index 0000000..1f6d21f --- /dev/null +++ b/_posts/2009-01-01-list-morph-demo.html @@ -0,0 +1,64 @@ +--- +layout: default +title: List Morph Demo +category: Demos +--- + +
+ +

Demos > List Morph Demo

+

This is a demonstration of how Effect.Morph can be used to indicate a list reordering to the user. Click anywhere on the list to initiate a random reorder.

+ +
+
Lorem
+
ipsum
+
dolor
+
sit
+
amet
+
+ +

Source code of this demo

+

+Array.prototype.shuffle = function() {
+  return this.sortBy(Math.random);
+};
+
+(function() {
+  function foo() {
+    $('scripty_morph_demo').select('div').shuffle().each(function(e, i) {
+      e.morph('top:' + i*e.getHeight() + 'px', { duration: 0.4 }); 
+    });
+  }
+  $('scripty_morph_demo').observe('click', foo);
+  foo();
+})();
+
+ +
\ No newline at end of file diff --git a/_posts/2009-01-01-puzzle-demo.html b/_posts/2009-01-01-puzzle-demo.html new file mode 100644 index 0000000..4fc606a --- /dev/null +++ b/_posts/2009-01-01-puzzle-demo.html @@ -0,0 +1,59 @@ +--- +layout: default +title: Puzzle Demo +--- + +
+ +

Demos > Puzzle Demo

+

This is an example showing how to implement a simple puzzle game with Sortables.

+ +
+ + + + + + + + + +
+

+(no move made yet) +

+

Source code

+

+(function() { 
+  var p = $('puzzle'), info = $('puzzleinfo'), moves = 0;
+  
+  Sortable.create('puzzle', {
+    tag: 'img', overlap: 'horizontal', constraint: false,
+    onUpdate: function() {
+      info.update('You\'ve made ' + (++moves) + ' move' + (moves > 1 ? 's' : ''));
+      if (Sortable.sequence('puzzle').join('') == '123456789')
+         info.update('You\'ve solved the puzzle in ' + moves + ' moves!').morph('congrats');
+    }
+  });
+})();
+
+ +
\ No newline at end of file diff --git a/_posts/2009-01-01-ruby-on-rails.html b/_posts/2009-01-01-ruby-on-rails.html new file mode 100644 index 0000000..317d81b --- /dev/null +++ b/_posts/2009-01-01-ruby-on-rails.html @@ -0,0 +1,23 @@ +--- +layout: default +title: Ruby on Rails +category: Demos +--- + +
+

Ruby On Rails features complete Prototype, and script.aculo.us integration.

+

Demo site and example code

+

Visit the Rails/script.aculo.us demo site for live demos and example code.

+

Usage

+

First, you need to include the libraries in your app, which is easy, as Prototype and script.aculo.us come prepackaged with Rails.

+

In your layout or view add this to the <head> section of your layout:

+

+<%= javascript_include_tag :defaults %>
+
+

You can now use the Rails JavaScript helpers or use do-it-yourself <script> tags and inline events as documented in this Wiki.

+

As of Rails 2.0, for certain functionality, like autocompleting text fields and in place editing, you’ll need to install the correspoding plugins.

+

Related Articles

+ +
\ No newline at end of file diff --git a/_posts/2009-01-01-slider.html b/_posts/2009-01-01-slider.html new file mode 100644 index 0000000..8d277c2 --- /dev/null +++ b/_posts/2009-01-01-slider.html @@ -0,0 +1,312 @@ +--- +layout: default +title: Slider +--- + +
+ +

Controls > Slider

+

Introduction

+

A slider control which can be used to select a single or multiple values from a given range, or even set of values.

+

Syntax

+

To make a slider element, you create a new instance of class Control.Slider.

+

+new Control.Slider('handles','track', [options]);
+
+

handles can either be a single id (or element) or, if you want more than one handle, an array of ids (or elements). track is either id or element.

+

Options

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Option Since Default Description
axisV1.5 horizontal Sets the direction that the slider will move in. It should either be horizontal or vertical.
increment V1.5 1 Defines the relationship of value to pixels. Setting this to 1 will mean each movement of 1 pixel equates to 1 value.
maximum V1.5 (none) Length of track in pixels adjusted by increment. The maximum value that the slider will move to. For horizontal this is to the right while vertical it is down.
minimum V1.5 0 The minimum value that the slider can move to. For horizontal this is to the left while vertical it is up. Note: this also sets the beginning of the slider (zeroes it out).
range 0 (none) Use the $R(min,max)
alignX V1.5 0 This will move the starting point on the x-axis for the handle in relation to the track. It is often used to move the ‘point’ of the handle to where 0 should be. It can also be used to set a different starting point on the track.
alignY V1.5 0 This will move the starting point on the y-axis for the handle in relation to the track. It is often used to move the ‘point’ of the handle to where 0 should be. It can also be used to set a different starting point on the track.
sliderValue V1.5 0 Will set the initial slider value. The handle will be set to this value, assuming it is within the minimum and maxium values.
disabled V1.5 (none) This will lock the slider so that it will not move and thus is disabled.
handleImage V1.5 (none) The id of the image that represents the handle. This is used to swap out the image src with disabled image src when the slider is enabled.
handleDisabled V1.5 (none) The id of the image that represents the disabled handle. This is used to change the image src when the slider is disabled.
values V1.5 (none) Accepts an array of integers. If set these will be the only legal values for the slider to be at. Thus you can set specific slider values that the user can move the slider to.
spans ?? (none) An array of ids or elements which are positioned between handles. This is used only when slider has more than one handle.
restricted ?? false Used only for multiple handles, when restricted is true, handle(s) with greater indexes are not allowed to have values less than handles with smaller indexes. When restricted is false, handles can be moved independently from others.
+

The slider control offers some functions to let javascript update its state:

+ + + + + + + + + + + + + + + + + + + + + +
Function Parameters Description
setValue value, handleIndex Will update the slider’s value and thus move the slider handle to the appropriate position. handleIndex is optional, when it is not passed then ‘active’ (last-dragged/used) handle is used. NOTE: when using setValue, the onChange callback function is called.
setDisabled (none) Will set the slider to the disabled state (disabled = true).
setEnabled (none) Will set the slider to the enabled state (disabled = false).
+

Additionally, the options parameter can take the following callback function:

+ + + + + + + + + + + + + +
Callback Description
onSlide Called whenever the Slider is moved by dragging. The called function gets the slider value (or array if slider has multiple handles) as its parameter.
onChange Called whenever the Slider has finished moving or has had its value changed via the setSlider Value function. The called function gets the slider value (or array if slider has multiple handles) as its parameter.
+

With both of the above, using multiple handles causes an array of their respective values to be passed to the callback. Both receive the Slider object as a second paramater.

+

Examples

+

Single handle

+

+// from the author's first demo of a vertical slider.  It begins disabled.
+var s2 = new Control.Slider('slider_2', 'track_2', {
+  axis:'vertical',
+  minimum: 60,
+  maximum: 288,
+  alignX: -28,
+  alignY: -5,
+  disabled: true, 
+  handleImage: 'slider_2handle',
+  handleDisabled: 'images/vsliderhandle_gray.gif'
+});
+
+// example of a horizontal slider that allows only 4 possible values
+var sliderLimited = new Control.Slider('slider_Limited', 'track_Limited', {
+  minimum: 2,
+  maximum: 30,
+  increment: 9,
+  alignX: -5,
+  alignY: -5,
+  values: [2, 10, 15, 30]
+});
+
+// Setting the callbacks later on
+s2.options.onChange = function(value) {
+  // ...
+  $('height_value').update(value);
+};
+
+s2.options.onSlide = function(value) {
+  // ...
+  $('height_value').update(value);
+};
+
+

Multiple handles

+

+<div id="square_slider" class="slider">
+  <div id="square_slider_handle_min" class="handle left"></div>
+  <div id="square_slider_handle_max" class="handle right"></div>
+
+  <div id="square_slider_span" class="span"></div>
+</div>
+
+

+var handles = ['square_slider_handle_min', 'square_slider_handle_max'];
+var square_slider = new Control.Slider(handles, 'square_slider', {
+    range: $R(0, 100),
+    values: $R(0, 100),
+    sliderValue: [20, 80],
+    spans: ["square_slider_span"],
+    restricted: true
+});
+
+

Demo

+ +
+

Use the slider to resize the box

+
+
+
+

And this to change its color

+
+
+
+
+
+
+
+ +

Source Code of the Demo

+

+
+<style type="text/css">
+  div.slider { width:256px; margin:10px 0; background-color:#ccc; height:10px; position: relative; }
+  div.slider div.handle { width:10px; height:15px; background-color:#f00; cursor:move; position: absolute; }
+
+  div#zoom_element { width:50px; height:50px; background:#2d86bd; position:relative; }
+</style>
+
+<div class="demo">
+  <p>Use the slider to resize the box</p>
+  <div id="zoom_slider" class="slider">
+    <div class="handle"></div>
+  </div>
+
+  <p>And this to change its color</p>
+  <div id="rgb_slider" class="slider">
+    <div class="handle" style="background-color: #f00;"></div>
+    <div class="handle" style="background-color: #0f0;"></div>
+    <div class="handle" style="background-color: #00f;"></div>
+  </div>
+
+  <div id="zoom_element"></div>
+</div>
+
+<script type="text/javascript">
+  (function() {
+    var zoom_slider = $('zoom_slider'),
+        rgb_slider = $('rgb_slider'),
+        box = $('zoom_element');
+
+    new Control.Slider(zoom_slider.down('.handle'), zoom_slider, {
+      range: $R(40, 160),
+      sliderValue: 50,
+      onSlide: function(value) {
+        box.setStyle({ width: value + 'px', height: value + 'px' });
+      },
+      onChange: function(value) { 
+        box.setStyle({ width: value + 'px', height: value + 'px' });
+      }
+    });
+
+    new Control.Slider(rgb_slider.select('.handle'), rgb_slider, {
+      range: $R(0, 255),
+      sliderValue: [45, 134, 189],
+      onSlide: function(values) {
+        box.setStyle({ backgroundColor: "rgb("+ values.map(Math.round).join(',') +")" });
+      },
+      onChange: function(values) { 
+        box.setStyle({ backgroundColor: "rgb("+ values.map(Math.round).join(',') +")" });
+      }
+    });
+  })();
+</script>
+
+ +
\ No newline at end of file diff --git a/_posts/2009-01-01-sortable-create.html b/_posts/2009-01-01-sortable-create.html new file mode 100644 index 0000000..ce82f0a --- /dev/null +++ b/_posts/2009-01-01-sortable-create.html @@ -0,0 +1,158 @@ +--- +layout: default +title: Sortable.create +--- + +
+ +

Behaviours > Sortable > create

+

Use Sortable.create to initialize a sortable element.

+

Syntax

+

Use Sortable.create('id_of_container',[options]); to create new Sortables.

+

Options

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
OptionSinceDescription
tagv1.0Default: ‘li’
+The kind of tag (of the child elements of the container) that will be made sortable. For UL and OL containers, this is ‘LI’, you have to provide the tag kind for other sorts of child tags.
onlyv1.0Default: (none)
+Further restricts the selection of child elements to only encompass elements with the given CSS class (or, if you provide an array of strings, on any of the classes).
overlapv1.0Default: ‘vertical’
+Either ‘vertical’ or ‘horizontal’. For floating sortables or horizontal lists, choose ‘horizontal’. Vertical lists should use ‘vertical’.
constraintv1.0Default: ‘vertical’
+Restricts the movement of Draggables, see the constraint option of Draggables.
containmentv1.0Default: (only within container)
+Enables dragging and dropping between Sortables. Takes an array of elements or element-ids (of the containers). Important note: To ensure that two way dragging between containers is possible, place all Sortable.create calls after the container elements.
formatv?Default:
/^[^_\-](?:[A-Za-z0-9\-\_]*)[_](.*)$/

The format that the id is computed from each item-id
handlev1.0Default: (none)
+Makes the created Draggables use handles, see the handle option on Draggables.
hoverclassv1.1b1Default: (none)
+Gives the created Droppables a hoverclass (see there).
ghostingv1.5Default: false
+If set to true, dragged elements of the Sortable will be cloned and appear as “ghost”, i.e. a representation of their original element, instead of directly dragging the original element. See below for more details.
dropOnEmptyv1.5Default: false
+If set to true, the Sortable container will be made into a Droppable, that can receive a Draggable (as according to the containment rules) as a child element when there are no more elements inside.
scrollv1.5.2Default: none
+When the sortable is contained in an element with style overflow:scroll, this value can be set to the ID of that container (or the container’s DOM object). The scroll position of the container will now move along when the sortable is dragged out of the viewable area. The container must have overflow:scroll set to include scroll bars. Does not yet work for scrolling the entire document. To get this to work correctly, include this line in your code before creating the sortable: Position.includeScrollOffsets = true; Update: Scrolling the whole document does work (at least on Safari 3.2 (Mac), IE7 and Firefox). Use scroll: window
scrollSensitivityv?Default: 20
+Will start scrolling when element is x pixels from the bottom, where x is the scrollSensitivity.
scrollSpeedv?Default: 15
+Will scroll the element in increments of scrollSpeed pixels.
treev1.6.1Default: false
+If true, sets sortable functionality to elements listed in treeTag
treeTagv1.6.1Default: ul
+The element type tree nodes are contained in.
+

Callbacks

+ + + + + + + + + + + + + + + + +
CallbackSinceDescription
onChangev1.0Called whenever the sort order changes while dragging. When dragging from one Sortable to another, the callback is called once on each Sortable. Gets the affected element as its parameter.
onUpdatev1.0Called when the drag ends and the Sortable’s order is changed in any way. When dragging from one Sortable to another, the callback is called once on each Sortable. Gets the container as its parameter. Note that the id attributes of the elements contained in the Sortable must be named as described in Sortable.serialize
+

On FF3.+ for onUpdate to work each child element in container must have id with format “string_identifier”, otherwise onUpdate will fail to init and wont run. Although you can have different format rule set using format option.

+

Update: This issue occurs in onHover as well (using 1.6 RC3, tried only on FF3). Unique ids are essential for both the container ul as well as the lis it contains. Otherwise Sortable.options(dropon) in onHover barfs with a null pointer.

+

Example that will work with default settings:
+


+<ul id="elements">
+    <li id="element_1">some kind of text</li>
+    <li id="element_2">some kind of text</li>
+    <li id="element_3">some kind of text</li>

+ +



+Example that will NOT work with default settings:
+


+<ul id="elements">
+    <li id="element1">some kind of text</li>
+    <li id="element2">some kind of text</li>
+    <li id="element3">some kind of text</li>

+ +

+

Notes

+

Important: You can use Sortable.create on any container element that contains Block Elements, with the exception of TABLE, THEAD, TBODY and TR. This is a technical restriction with current browsers.
+A sortable nested somewhere inside a table won’t work well under IE unless the table has a “position:relative” style. If you use the css display: table property, sortable lists will work a little, but doesn’t allow true drag and drop of the elements.

+

If you want your sortable list to be scrollable, wrap the list in a div and set the div to scrollable as opposed to making the ul element scrollable. Also, in IE you must set “position:relative” on the scrollable div.

+

Got it working using tbody as container and TR as the sortables (IE6 (pc) and Firefox (mac/pc).

+

A call to Sortable.create implicitly calls on Sortable.destroy if the referenced element was already a Sortable.

+

Patches

+

Marking the Drop Zone : Having a marker in the empty place where you will drop
+(for versions: 1.6.x, 1.7.0, 1.8.0 and 1.8.1)

+

Have a look at this page for the patch and how to modify scriptaculous to have a drop zone marker.

+

Tankut Koray

+
\ No newline at end of file diff --git a/_posts/2009-01-01-sortable-lists-demo.html b/_posts/2009-01-01-sortable-lists-demo.html new file mode 100644 index 0000000..a427d45 --- /dev/null +++ b/_posts/2009-01-01-sortable-lists-demo.html @@ -0,0 +1,38 @@ +--- +layout: default +title: Sortable Lists Demo +category: Demos +--- + +
+ +

Basic unordered list, drag any list item to reorder

+
    +
  • works
  • +
  • this
  • +
  • Yay
  • +
  • now
  • +
+
Sortable.create("list");
+

Unordered list with draggable handles, drag the link to reorder

+ +
Sortable.create("list-2", {handles:$$('#list-2 a')});
+

A collection of paragraphs that are reorderable with draggable handles, drag the link to reorder

+
+

This is a reorderable paragraph. move

+

This is another reorderable paragraph. move

+

This is yet another reorderable paragraph. move

+

And can you believe it? Another reorderable paragraph. move

+
+
Sortable.create("list-3", {elements:$$('#list-3 p'), handles:$$('#list-3 a')});
+ +
\ No newline at end of file diff --git a/_posts/2009-01-01-sortable-sequence.html b/_posts/2009-01-01-sortable-sequence.html new file mode 100644 index 0000000..e13c0aa --- /dev/null +++ b/_posts/2009-01-01-sortable-sequence.html @@ -0,0 +1,34 @@ +--- +layout: default +title: Sortable.sequence +category: Behaviours +--- + +
+ +

Behaviours > Sortable > sequence

+

The Sortable object also provides a function to get a sequence array of the id’s.

+

Syntax

+

+id_array = Sortable.sequence('id_of_container');
+
+

Example

+

Taken from the Puzzle Demo

+

+(function() { 
+  var p = $('puzzle'), info = $('puzzleinfo'), moves = 0;
+
+  Sortable.create('puzzle', {
+    tag: 'img', overlap: 'horizontal', constraint: false,
+    onUpdate: function() {
+      info.update('You\'ve made ' + (++moves) + ' move' + (moves > 1 ? 's' : ''));
+      if (Sortable.sequence('puzzle').join('') == '123456789')
+         info.update('You\'ve solved the puzzle in ' + moves + ' moves!').morph('congrats');
+    }
+  });
+})();
+
+ +
\ No newline at end of file diff --git a/_posts/2009-01-01-sortable-serialize.html b/_posts/2009-01-01-sortable-serialize.html new file mode 100644 index 0000000..425021b --- /dev/null +++ b/_posts/2009-01-01-sortable-serialize.html @@ -0,0 +1,91 @@ +--- +layout: default +title: Sortable.serialize +category: Behaviours +--- + +
+

Behaviours > Sortable > serialize

+

The Sortable object also provides a function to serialize the Sortable in a format suitable for HTTP GET or POST requests. This can be used to submit the order of the Sortable via an Ajax call:

+

+poststring = Sortable.serialize('id_of_container',[options]);
+// poststring now contains key[]=value pairs separated by &
+
+

Important: For this to work, the elements contained in your Sortable must have id attributes in the following form:

+

+id="string_identifier" 
+
+//Example
+<ol id="container_id">
+  <li id="image_1">Item 1</li>
+  <li id="image_2">Item 1</li>
+  <li id="image_3">Item 1</li>
+</ol>
+
+

Only the identifier part of the id attribute will be serialized. If you want to use an other form of id attributes, you need to implement your own serialization.

+

Options

+ + + + + + + + + + + + + + + + +
OptionSinceDescription
tagv1.0The kind of tag (of the child elements of the container) that will be serialized.
namev1.0The name of the key that will be used to create the key/value pairs for serializing in HTTP GET/POST format (that is, key[]=value&key[]=value â€Ĥ)
+

Example (from the Sortable Ghosted example)

+

+<style>
+  #content #testlist { 
+      list-style-type:none;
+      margin:0;
+      padding:0;
+   }
+   #content #testlist li {
+     width:200px;
+     font:13px Verdana;
+     margin:0;
+     margin-left:20px;
+     padding-left:20px;
+     padding:4px;
+     cursor:move;
+   }
+  div.dropmarker {
+      height:6px;
+      width:200px;
+      background: url(/images/dropmarker.png) left top;
+      margin-top:-3px;
+      margin-left:-5px;
+      z-index:1000;
+      overflow: hidden;
+   }
+</style>
+
+<ol id="testlist">
+  <li id="image_1">Lorem ipsum dolor</li>
+  <li id="image_2">sit amet</li>
+  <li id="image_3">consectetur adipisicing</li>
+  <li id="image_4">elit</li>
+  <li id="image_5">sed do eiusmod</li>
+  <li id="image_7">ut labore et dolore</li>
+  <li id="image_6">tempor incididunt</li>
+  <li id="image_8">magna aliqua</li>
+</ol>
+
+<script type="text/javascript" language="javascript">
+  Sortable.create('testlist',{ghosting:true,constraint:false})
+  alert(Sortable.serialize('testlist'));
+</script>
+
+

Clarification: In this example, the output of the serialization will only give the numbers after the underscore in the list item IDs.

+

Tutorials

+

A short tutorial on using Sortables.serialize

+
\ No newline at end of file diff --git a/_posts/2009-01-01-sortable.html b/_posts/2009-01-01-sortable.html new file mode 100644 index 0000000..00f5bd7 --- /dev/null +++ b/_posts/2009-01-01-sortable.html @@ -0,0 +1,102 @@ +--- +layout: default +title: Sortable +category: Behaviours +--- + +
+

Behaviours > Sortable

+

A Sortable is a quick way to initialize many Draggable elements in a container element. When you create a new Sortable, it takes care of the creation of the corresponding draggable Droppables.

+

Syntax

+

Use Sortable.create('id_of_container',[options]); to create new Sortables. See Sortable.create. Furthermore, there are special requirements to get sortables to work in FF3 which are also covered in Sortable.create.

+

Object

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Property/Method Description
SERIALIZE_RULE
(RegExp) /^[^_\-](?:[A-Za-z0-9\-\_]*)[_](.*)$/
sortables(Object) { }
options (element)Internal function
destroy (element)Destroys sortable
create (element, options)Creates sortable
findElements (element, options)Internal function
onHover (element, dropon, overlap)Internal function, which may be overridden through the options parameter on creation
onEmptyHover (element, dropon, overlap) Internal function
unmark()Internal function
mark()Internal function
tree (element)
sequence (element)
setSequence (element, new_sequence)
serialize (element)
+

Demos

+

See Sortable Lists Demo.

+

Creating sortables

+

See Sortable.create.

+

Disabling sortables

+

+  Sortable.destroy( element );
+
+

A call to Sortable.create implicitly calls Sortable.destroy if the referenced element was already a Sortable.

+

Functions

+ + + + + + + + + + + + + +
FunctionDescription
Sortable.serializeThe Sortable object also provides a function to serialize the Sortable in a format suitable for HTTP GET or POST requests. This can be used to submit the order of the Sortable via an Ajax call. See Sortable.serialize
Sortable.sequenceThe Sortable object also provides a function to get the values in an sequence array object. See Sortable.sequence
+

Tutorials

+

Use PHP and Ajax call to interact with Sortable

+

A short tutorial on using Sortables prepared for the Linux Users Group, Villafranca, Italy.

+
\ No newline at end of file diff --git a/_posts/2009-01-01-sortables-create.html b/_posts/2009-01-01-sortables-create.html new file mode 100644 index 0000000..c80b5e0 --- /dev/null +++ b/_posts/2009-01-01-sortables-create.html @@ -0,0 +1,9 @@ +--- +layout: default +title: Sortables.create +category: Behaviours +--- + + \ No newline at end of file diff --git a/_posts/2009-01-01-sortables.html b/_posts/2009-01-01-sortables.html new file mode 100644 index 0000000..5bc0d0b --- /dev/null +++ b/_posts/2009-01-01-sortables.html @@ -0,0 +1,137 @@ +--- +layout: default +title: Sortables +category: Behaviours +--- + +
+ +

Behaviours > Sortable

+

A Sortable consists of item elements in a container element. When you create a new Sortable, it takes care of the creation of the corresponding Draggables and Droppables.

+

Creating Sortables

+

Syntax

+

+Sortable.create('id_of_container',[options]);
+
+

Options

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Option Description
tag string, represents a tagname, defaults to 'li', sets the kind of tag (of the child elements of the container) that will be made sortable. For UL and OL containers, this is ‘li’, you have to provide the tag kind for other sorts of child tags.
only Further restricts the selection of child elements to only encompass elements with the given CSS class (or, if you provide an array of strings, on any of the classes).
overlap string, defaults to 'vertical', can also be ‘horizontal’. For floating sortables or horizontal lists, choose ‘horizontal’. Vertical lists should use ‘vertical’.
constraint string, defaults to 'vertical', restricts the movement of Draggables, see the constraint option of Draggable.
containment Enables dragging and dropping between Sortables. Takes an array of elements or element-ids (of the containers). Important note: To ensure that two way dragging between containers is possible, place all Sortable.create calls after the container elements.
handle Makes the created Draggables use handles, see the handle option on Draggable.
hoverclass Gives the created Droppables a hoverclass (see Droppables).
ghosting boolean, defaults to false, if set to true, dragged elements of the Sortable will be cloned and appear as “ghost”, i.e. a representation of their original element, instead of directly dragging the original element.
dropOnEmpty boolean, defaults to false, if set to true, the Sortable container will be made into a Droppable, that can receive a Draggable (as according to the containment rules) as a child element when there are no more elements inside.
scroll When the sortable is contained in an element with style overflow:scroll, this value can be set to the ID of that container (or the container’s DOM object). The scroll position of the container will now move along when the sortable is dragged out of the viewable area. The container must have overflow:scroll set to include scroll bars.
scrollSensitivity Will start scrolling when element is x pixels from the bottom, where x is the scrollSensitivity.
scrollSpeed Will scroll the element in increments of scrollSpeed pixels.
tree boolean, defaults to false, if true, sets sortable functionality to elements listed in treeTag
treeTag string, defaults to 'ul', the element type tree nodes are contained in.
+

Callbacks

+ + + + + + + + + + + + + +
Callback Description
onChange Called whenever the sort order changes while dragging. When dragging from one Sortable to another, the callback is called once on each Sortable. Gets the affected element as its parameter.
onUpdate Called when the drag ends and the Sortable’s order is changed in any way. When dragging from one Sortable to another, the callback is called once on each Sortable. Gets the container as its parameter. Note that the id attributes of the elements contained in the Sortable must be named as described in Sortable.serialize
+

Notes

+

You can use Sortable.create on any container element that contains Block Elements, with the exception of TABLE, THEAD, TBODY and TR. This is a technical restriction with current browsers.
+A sortable nested somewhere inside a table won’t work well under IE unless the table has a position:relative style. If you use the CSS display: table property, sortable lists will work a little, but doesn’t allow true drag and drop of the elements.

+

If you want your sortable list to be scrollable, wrap the list in a div and set the div to scrollable as apposed to making the ul element scrollable. Also, in IE you must set position:relative on the scrollable div.

+

Serializing Sortables

+

The Sortable object also provides a function to serialize the Sortable in a format suitable for HTTP GET or POST requests. This can be used to submit the order of the Sortable via an Ajax call.

+

Syntax

+

+var poststring = Sortable.serialize('id_of_container',[options]);
+// poststring now contains key[]=value pairs separated by &
+
+

Important: For this to work, the elements contained in your Sortable must have id attributes in the following form:
+


+id="string_identifier" 
+// example: id="image_1"
+

+

Only the identifier part of the id attribute will be serialized. If you want to use an other form of id attributes, you need to implement your own serialization.

+

Options

+ + + + + + + + + + + + + +
Option Description
tag string, defaults to the tag originally used when calling Sortable.create, Sets the kind of tag (of the child elements of the container) that will be serialized.
name string, defaults to id of the container, sets the name of the key that will be used to create the key/value pairs for serializing in HTTP GET/POST format (that is, key[]=value&key[]=value â€Ĥ)
+

Disabling Sortables

+

Use Sortable.destroy to completely remove all event handlers and references to a Sortable created by Sortable.create. It does not remove or alter the referenced element in any other way.

+

Syntax

+

+Sortable.destroy(element);
+
+

Notes

+

A call to Sortable.create implicitly calls on Sortable.destroy if the referenced element was already a Sortable.

+ +
\ No newline at end of file diff --git a/_posts/2009-01-01-sound.html b/_posts/2009-01-01-sound.html new file mode 100644 index 0000000..4be91a5 --- /dev/null +++ b/_posts/2009-01-01-sound.html @@ -0,0 +1,121 @@ +--- +layout: default +title: Sound +--- + +
+ +

Introduction

+

Use Sound to play audio directly from the browser.

+

Syntax

+
Sound.play( url, [ options ])
+Sound.enable() 
+Sound.disable()
+
+

Play Options

+ + + + + + + + + +
Option Description
replace replace the current active track, defauts to false
+

Notes

+
    +
  • Sound.disable does not disable the playback immediately, it just prevents the next tracks from being played.
    +Watch the demo to see how to stop the sound immediately.
  • +
  • Sound.enable does not resume the playback, just allows the next track to be played.
  • +
  • In Firefox 3, Sound does not work from local files, but works if served (even from localhost). As an alternative, you can change the template within sound.js from “object” to “embed” and from “data” to “src”.
  • +
+

Demo

+
+ URL: +
+ Sound: On + +
+ +

Source code of the demo

+

+<div>
+    URL: <input type = "text" id = "sound_demo_track_url" style = "width:400px;" 
+    value = "http://www.joshwoodward.com/mp3/TheSimpleLife/JoshWoodward-TheSimpleLife-101-HeritagePlace.mp3"/>
+    <br/>
+    Sound: <span id = "sound_status">On</span>
+    <ul class = "sound_controls">
+      <li><a href="javascript:void(0)" id="sound_demo_play">Play</a></li>
+      <li><a href="javascript:void(0)" id="sound_demo_disable">Disable sound</a></li>
+      <li><a href="javascript:void(0)" id="sound_demo_disable_now">Disable now</a></li>
+      <li><a href="javascript:void(0)" id="sound_demo_enable">Enable sound</a></li>
+    </ul>
+</div>
+
+

+
+<script type="text/javascript">
+  $('sound_demo_play').observe('click', function(event) {
+       event.stop();
+       Sound.play($('sound_demo_track_url').value,{replace:true});
+   });
+  
+  $('sound_demo_enable').observe('click', function(event) {
+       event.stop();
+       Sound.enable();
+     $('sound_status').innerHTML = 'On';
+   });
+
+  $('sound_demo_disable').observe('click', function(event) {
+       event.stop();
+       Sound.disable();
+     $('sound_status').innerHTML = 'Pending Off';
+   });
+
+  $('sound_demo_disable_now').observe('click', function(event) {
+       event.stop();
+       Sound.enable();
+       Sound.play('',{replace:true});
+       Sound.disable();
+     $('sound_status').innerHTML = 'Off';
+   });
+
+</script>
+
+
+ +
\ No newline at end of file diff --git a/_posts/2009-01-01-style-guide.html b/_posts/2009-01-01-style-guide.html new file mode 100644 index 0000000..0ae653b --- /dev/null +++ b/_posts/2009-01-01-style-guide.html @@ -0,0 +1,80 @@ +--- +layout: default +title: Style Guide +--- + +
+ +

When porting documents from the old wiki over to the new one or if you’re generally writing new content for the script.aculo.us wiki,
+this style guide might be helpful for structuring your document.

+

Document includes

+

Syntax Highlighting

+

In order to make syntax highlighting work for documents which contain code examples, be sure to put this line to the very beginning of your document:
+


+<link rel="stylesheet" title="Sunburst" href="http://script.aculo.us/github/styles/sunburst.css"/>
+

+

and the following code-block to the very end of the document:
+


+<script type="text/javascript" src="http://script.aculo.us/github/highlight.js"></script>
+<script type="text/javascript">
+  hljs.initHighlightingOnLoad.apply(null, hljs.ALL_LANGUAGES);
+</script>
+

+

Javascript Includes

+

In documents where you show demos of script.aculo.us’ features, include the following code at the beginning of
+your document:
+


+<script type="text/javascript" src="http://script.aculo.us/prototype.js"></script>
+<script type="text/javascript" src="http://script.aculo.us/scriptaculous.js"></script>
+

+

Mind that these files are the latest versions from the master branch, and may contain bugfixes that make them work slightly different from the latest official release.

+

Document Structure

+

Documents which show the usage of an effect, a control or other related topics should be structured as following:

+
    +
  • h2. Introduction — A short paragraph describing what the document is about.
  • +
  • h2. Syntax — A description of the usage of the topic (e.g. how to instantiate an effect, the order of parameters, etc.).
  • +
  • h2. Options — A table which shows all available options and a corresponding description.
  • +
  • h2. Examples — Practical usage examples of the topic.
  • +
  • h2. Demo — A playable demo of the topic. +
      +
    • h3. Source Code of the Demo — All the code which is needed to rebuild the demo, an optional description.
    • +
  • +
+

Including a Path

+

When a document belongs to a specific category, include a path in the beginning of your document.
+An example:
+Effect.Morph belongs to the Core Effects category. The path for the Effect.Morph document will look like:

+

Core Effects > Effect.Morph

+

The textile snippet for the above example looks like this:
+


+p{background:#eee; border-bottom:1px solid #bbb; padding:4px 2px 2px 2px;}. [[Core Effects]] > *Effect.Morph*
+
+

+

Document Linking

+

The syntax for linking to other documents looks like:
+


+[[Title of another document]]
+

+

Be sure to not use the camelcased style (CoreEffects) as often seen in other wikis, but instead the real, space-seperated title of the document you want to link to (Core Effects).

+

Here an example on how to link from your document to other documents of the wiki:
+


+[[Core Effects]] => links to the document with the title "Core Effects"
+[[Combination Effects]] => links to the document with the title "Combination Effects"
+

+

Code Examples

+

When giving examples, wrap your example code into code tag with the programming language the example is written in as its class-attribute which is again wrapped in a pre-tag. An example of this would look like this:

+

+<pre><code class="javascript">
+  Example code here
+  â€Ĥ
+
+

+

Demos

+

1. Include all the necessary JS files as described in Javascript Includes in your document.

+

2. Wrap all your demo code in a notextile-tag.

+

3. Wrap all your HTML demo code into a div[class="demo"].

+

4. In order to prevent an overriding of Githubs own Javascript code, be sure to add a prefix (e.g. scriptyGetValue()) when defining custom functions for your demo.

+ +
\ No newline at end of file diff --git a/_posts/2009-01-01-tabs.html b/_posts/2009-01-01-tabs.html new file mode 100644 index 0000000..0c33aff --- /dev/null +++ b/_posts/2009-01-01-tabs.html @@ -0,0 +1,305 @@ +--- +layout: default +title: Tabs +category: Demos +--- + +
+ +

Updated incorrect tags entry. Here is the right example to set multiple tabs and to make a tab active.

+

About

+

This script will allow you to create interactive tabs for use in an application.

+

The CSS and HTML:

+

+<style>
+    #tabs{
+        margin-left: 4px;
+        padding: 0;
+        background: transparent;
+        voice-family: "\"}\"";
+        voice-family: inherit;
+        padding-left: 5px;
+    }
+    #tabs ul{
+        font: bold 11px Arial, Verdana, sans-serif;
+        margin:0;
+        padding:0;
+        list-style:none;
+    }
+    #tabs li{
+        display:inline;
+        margin:0 2px 0 0;
+        padding:0;
+        text-transform:uppercase;
+    }
+    #tabs a{
+        float:left;
+        background:#A3BBE6 url(images/tabs_left.gif) no-repeat left top;
+        margin:0 2px 0 0;
+        padding:0 0 1px 3px;
+        text-decoration:none;
+    }
+    #tabs a span{
+        float:left;
+        display:block;
+        background: transparent url(images/tabs_right.gif) no-repeat right top;
+        padding:4px 9px 2px 6px;
+    }
+    #tabs a span{float:none;}
+    #tabs a:hover{background-color: #7E94B9;color: white;}
+    #tabs a:hover span{background-color: #7E94B9;}
+    #tabHeaderActive span, #tabHeaderActive a { background-color: #42577B; color:#fff;}
+    .tabContent {
+        clear:both;
+        border:2px solid #42577B;
+        padding-top:2px;
+        background-color:#FFF;
+    }
+</style>
+
+<div id="tabs">
+    <ul>
+        <li style="margin-left: 1px" id="tabHeaderActive"><a href="javascript:void(0)" onClick="toggleTab(1,6)"><span>Tab 1</span></a></li>
+        <li id="tabHeader2"><a href="javascript:void(0)" onClick="toggleTab(2,6)" ><span>Tab 2</span></a></li>
+        <li id="tabHeader3"><a href="javascript:void(0)" onclick="toggleTab(3,6)"><span>Tab 3</span></a></li>
+        <li id="tabHeader4"><a href="javascript:void(0)" onClick="toggleTab(4,6)"><span>Tab 4</span></a></li>
+        <li id="tabHeader5"><a href="javascript:void(0)" onclick="toggleTab(5,6);"><span>Tab 5</span></a></li>
+        <li id="tabHeader6"><a href="javascript:void(0)" onclick="toggleTab(6,6);"><span>Tab 6</span></a></li>
+    </ul>
+    </div>
+    <div id="tabscontent">
+        <div id="tabContent1" class="tabContent" style="display:yes;">
+            <br /><div>First Tab Content goes here</div>
+        </div>
+
+        <div id="tabContent2" class="tabContent" style="display:none;">
+            <br /><div>Second Tab Content goes here</div>
+        </div>
+
+        <div id="tabContent3" class="tabContent" style="display:none;">
+            <br /><div>Third Tab Content goes here</div>
+        </div>
+
+        <div id="tabContent4" class="tabContent" style="display:none;">
+            <br /><div>Fourth Tab Content goes here</div>
+        </div>
+
+        <div id="tabContent5" class="tabContent" style="display:none;">
+            <br /><div>Fifth Tab Content goes here</div>
+        </div>
+
+        <div id="tabContent6" class="tabContent" style="display:none;">
+            <br /><div>Sixth Tab Content goes here</div>
+        </div>
+    </div><!--End of tabscontent-->
+</div><!--End of tabs-->
+
+

The Javascript:

+

+/*-----------------------------------------------------------
+    Toggles element's display value
+    Input: any number of element id's
+    Output: none 
+    ---------------------------------------------------------*/
+function toggleDisp() {
+    for (var i=0;i<arguments.length;i++){
+        var d = $(arguments[i]);
+        if (d.style.display == 'none')
+            d.style.display = 'block';
+        else
+            d.style.display = 'none';
+    }
+}
+/*-----------------------------------------------------------
+    Toggles tabs - Closes any open tabs, and then opens current tab
+    Input:     1.The number of the current tab
+                    2.The number of tabs
+                    3.(optional)The number of the tab to leave open
+                    4.(optional)Pass in true or false whether or not to animate the open/close of the tabs
+    Output: none 
+    ---------------------------------------------------------*/
+function toggleTab(num,numelems,opennum,animate) {
+    if ($('tabContent'+num).style.display == 'none'){
+        for (var i=1;i<=numelems;i++){
+            if ((opennum == null) || (opennum != i)){
+                var temph = 'tabHeader'+i;
+                var h = $(temph);
+                if (!h){
+                    var h = $('tabHeaderActive');
+                    h.id = temph;
+                }
+                var tempc = 'tabContent'+i;
+                var c = $(tempc);
+                if(c.style.display != 'none'){
+                    if (animate || typeof animate == 'undefined')
+                        Effect.toggle(tempc,'blind',{duration:0.5, queue:{scope:'menus', limit: 3}});
+                    else
+                        toggleDisp(tempc);
+                }
+            }
+        }
+        var h = $('tabHeader'+num);
+        if (h)
+            h.id = 'tabHeaderActive';
+        h.blur();
+        var c = $('tabContent'+num);
+        c.style.marginTop = '2px';
+        if (animate || typeof animate == 'undefined'){
+            Effect.toggle('tabContent'+num,'blind',{duration:0.5, queue:{scope:'menus', position:'end', limit: 3}});
+        }else{
+            toggleDisp('tabContent'+num);
+        }
+    }
+}
+
+

Example:

+
+ + + +
+
+
+ First Tab Content goes here +
+
+ + + + + +
+
+ +
\ No newline at end of file diff --git a/_posts/2009-01-01-test-unit-assertions.html b/_posts/2009-01-01-test-unit-assertions.html new file mode 100644 index 0000000..b1ba269 --- /dev/null +++ b/_posts/2009-01-01-test-unit-assertions.html @@ -0,0 +1,52 @@ +--- +layout: default +title: Test.Unit.Assertions +--- + +
+

Signature

+

Methods:

+

initialize: function() constructor
+summary: function(): String Returns a concatenated string which represents the assertions, errors, failures, and messages properties.
+pass: function() This code increases the number of assertions without risking a failure or error
+fail: function( message (converted to string) )Adds a failure message to messages property and increments failures property
+info: function( message (converted to string) )Adds an info message to messages property
+error: function(error:Error)Adds an error message to messages property and increments error property
+status: function()Returns ‘failed’, ‘error’, or ‘passed’ based on the error and failure count. If there are errors and failures, only ‘failure’ will be returned..
+assertElementsMatch: function( ...args )Do all objects in the arguments array match the first item in that array? ie: Does assertElementsMatch([‘a’,‘b’,‘c’], ‘a’, ‘b’, ‘c’ ) should be true?
+assertElementMatches: function(element, expression)assertElementsMatch([element], expression)
+benchmark: function(operation: Function, iterations: Number = 1):NumberCalls operation iteration number of times and returns how long it took to call all of them.
+-———————————————————————————————————————————————————————————-
+NOTE: In all of the below functions, there is a third parameter message:String. If this is used, then that message will be appended to the string sent into the fail function in case the assertion does not succeed.
+-———————————————————————————————————————————————————————————-
+assert: function(expression)If expression evaluates to true, this will call pass(), otherwise it will call fail()
+assertInspect: function(expected:Object, actual:Object)Does expected == actual.inspect()
+assertEnumEqual: function(expected:Object, actual:Object)Goes through two dynamic objects and compares them point for point
+assertRespondsTo: function(method:String, obj:Object) Does obj have a method by the name given?
+assertRaise: function(exceptionName:String, method:Function)Does this method raise the error of the correct exceptionName?
+assertHidden: function(element)Shortcut for assertEqual(“none”, element.style.display)
+assertMatch: function(expression:String (regular expression), actual:String)Does the string match the regular expressions?

+

The next series of functions come in pairs, those which include the word “Not” means that the

+

assertEqual: function(expected, actual)Does expected == actual?
+assertNotEqual: function(expected, actual)
+assertIdentical: function(expected, actual)Does expected = actual?
+assertNotIdentical: function(expected, actual)
+assertNull: function(obj)Does obj = null
+assertNotNull: function(object)
+assertType: function(expected:Class, actual:Object)Is the actual item a member of the expected Class (does not work on descendant classes)
+assertNotOfType: function(expected:Class, actual:Object)
+assertInstanceOf: function(expected:Class, actual:Object)Is the actual item an instance of the expected Class or its descendants
+assertNotInstanceOf: function(expected, actual)
+assertReturnsTrue: function(method, obj)Does the function return true?
+assertReturnsFalse: function(method, obj)
+assertVisible: function(element:Element) _isVisible will return true for element
+assertNotVisible: function(element)
+<!— Private!
+_isVisible: function(element) Returns whether an element is visible. It calls itself recursively until it gets to the document root.
+—>
+

Properties


+assertions: Number
+failures: Number
+errors: Number
+messages: Array( Strings )

+
\ No newline at end of file diff --git a/_posts/2009-01-01-test-unit-logger.html b/_posts/2009-01-01-test-unit-logger.html new file mode 100644 index 0000000..ce36fda --- /dev/null +++ b/_posts/2009-01-01-test-unit-logger.html @@ -0,0 +1,28 @@ +--- +layout: default +title: Test.Unit.Logger +--- + +
+

Signature

+

Methods

+

initialize: function(log (string which refers to a div ID))
+start: function(testName)
+finish: function(status, summary)
+message: function(message)
+summary: function(summary)
+addLinksToResults: function()
+<— These may be private
+    _createLogTable: function()
+    _toHTML: function(txt)
+—>
+

Properties


+log: Element
+testName: String
+lastLogLine: Element (tr)
+statusCell: Element (td)
+nameCell: Element (td)
+messageCell: Element (td)
+logsummary: Element (id = "logsummary")
+loglines: Element (id = "loglines")

+
\ No newline at end of file diff --git a/_posts/2009-01-01-test-unit-runner.html b/_posts/2009-01-01-test-unit-runner.html new file mode 100644 index 0000000..c7dfb87 --- /dev/null +++ b/_posts/2009-01-01-test-unit-runner.html @@ -0,0 +1,81 @@ +--- +layout: default +title: Test.Unit.Runner +--- + +
+ +

Unit Testing > Test.Unit.Runner

+

Introduction

+

Test.Unit.Runner is a utility class for writing unit test cases with an easy to use syntax.

+

Syntax

+

+new Test.Unit.Runner(functions [, options] );
+

The functions and options parameters are both {key: value} collections.

+

Examples

+

Using Test.Unit.Runner requires you to use a specific XHTML page template, that looks as follows:

+

+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
+        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+  <title>Page title</title>
+  <script src="path/to/prototype.js" type="text/javascript"></script>
+  <script src="path/to/util.js" type="text/javascript"></script>
+  <script src="path/to/unittest.js" type="text/javascript"></script>
+  <!-- other JavaScript includes -->
+  <link rel="stylesheet" href="path/to/test.css" type="text/css" />
+</head>
+<body>
+
+<!-- Log output -->
+<div id="testlog"> </div>
+
+<!-- here go any elements you do the testing on -->
+
+<!-- Tests -->
+<script type="text/javascript" language="javascript">
+// <![CDATA[
+  new Test.Unit.Runner({
+    // optional setup function, run before each individual test case
+    setup: function() { with(this) {
+      // code
+    }},
+    // optional teardown function, run after each individual test case
+    teardown: function() { with(this) {
+      // code
+    }},
+
+    // test cases follow, each method which starts 
+    // with "test" is considered a test case
+    testATest: function() { with(this) {
+      // code
+    }},
+    testAnotherTest: function() { with(this) {
+      // code
+    }}
+  }, { options });
+// ]]>
+</script>
+</body>
+</html>
+
+

Notice how the with(this) { ... } syntax allows for easily calling on methods of the Test.Unit.Testcase class, which includes the assertions, as defined in Test.Unit.Assertions.

+

More Examples

+

Probably the best examples of Test.Unit.Runner are the actual tests used by script.aculo.us. Don’t be afraid to dive in to the code! See the test folder in the repository root.

+

Signature

+

Methods

+

initialize: function(testcases [, options])
+parseResultsURLQueryParameter: function()
+parseTestsQueryParameter: function()
+getResult: function()
+postResults: function()
+runTests: function()
+

Properties


+options: object (This is an object which is a modification of the options object passed into the initialize function
т¸Ñ‚µ şÑ€°Ñ¸² т´Ñ…½ÑƒÑ‚ÑŒ? ŸÑ€ÑÑ‚¸Ñ‚утş¸ œÑş²° – ğучш¸ı т´Ñ‹Ñ… ´ğя ĵуĥч¸½.

+tests: Array of Testcases
+currentTest: Number
+logger: Test.Unit.Logger

+
\ No newline at end of file diff --git a/_posts/2009-01-01-test-unit-testcase.html b/_posts/2009-01-01-test-unit-testcase.html new file mode 100644 index 0000000..e8eb7fd --- /dev/null +++ b/_posts/2009-01-01-test-unit-testcase.html @@ -0,0 +1,19 @@ +--- +layout: default +title: Test.Unit.Testcase +--- + +
+

In addition to the methods and properties listed below, it should be noted that this class’s prototype is an extension of the Test.Unit.Assertions class.

+

Signature

+

Methods:

+

initialize: function(name, test, setup, teardown)
+wait: function(time, nextPart)
+run: function()
+

Properties


+name: String
+isWaiting: Boolean
+timeToWait: Number (refers to milliseconds)
+setup: Function
+teardown: Function

+
\ No newline at end of file diff --git a/_posts/2009-01-01-test-unit.html b/_posts/2009-01-01-test-unit.html new file mode 100644 index 0000000..41f9af8 --- /dev/null +++ b/_posts/2009-01-01-test-unit.html @@ -0,0 +1,15 @@ +--- +layout: default +title: Test.Unit +--- + +
+

The basics

+

Test.Unit is effectively the equivalent of a package which contains four classes:

+

Test.Unit.Logger
+Test.Unit.Runner
+Test.Unit.Assertions
+Test.Unit.Testcase

+

It also has a quick reference to Object.inspect:
+Test.Unit.inspect

+
\ No newline at end of file diff --git a/_posts/2009-01-01-unit-testing.html b/_posts/2009-01-01-unit-testing.html new file mode 100644 index 0000000..814b6bb --- /dev/null +++ b/_posts/2009-01-01-unit-testing.html @@ -0,0 +1,26 @@ +--- +layout: default +title: Unit Testing +--- + +
+ +

Introduction

+

script.aculo.us provides a complete set of classes and methods for Javascript unit testing.

+

To use the unit test library, you must include unittest.js in your HTML file. See Test.Unit.Runner for a complete example on how this works.

+

script.aculo.us “eats its own dog food,” and includes unit and functional tests for itself, inside the test folder of the repository.

+

Note that as of August 2005 some of the tests will fail in browsers other than Firefox (due to implementation differences and some of the DOM functions used not implemented in some browsers).

+

Classes

+ +

Examples

+

A short tutorial (second half of the page) demonstrating the use of the script.aculo.us test harness for Javascript, prepared for the Linux Users Group, Villafranca, Verona, Italy.

+ +
\ No newline at end of file diff --git a/css/docs.css b/css/docs.css new file mode 100644 index 0000000..bce20ea --- /dev/null +++ b/css/docs.css @@ -0,0 +1,359 @@ +/* + Scriptaculous Wiki->GitHub Pages CSS + Not much here for now. +*/ + +/* + template.css + Wiki content formatting + Keeping this file separate so it can be easily swapped out if you + want to format your wiki content differently from the default. +*/ + +/* @section core */ +body, html { + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 10px; /* -> 1em */ + margin: 0; + padding: 0; +} + +#content { + margin: 0 auto; + overflow: visible; + width: 80%; +} + +a:link { + color: #4183c4; + text-decoration: none; +} + +a:hover, a:visited { + color: #4183c4; + text-decoration: underline; +} + + +/* @section head */ +#header { + background: #9dc569; + border-bottom: 1px solid #799851; + margin: 0 0 3.0em 0; + overflow: hidden; + padding: 0.8em 1em; + + filter:progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#aacd7e', endColorstr='#9dc569'); + background: -webkit-gradient(linear, left top, left bottom, from(#aacd7e), to(#9dc569)); + background: -moz-linear-gradient(top, #aacd7e, #9dc569); +} + + #header #internal { + margin: 0 auto; + overflow: visible; + width: 80%; + height: 1%; + } + + h2#logo { + background: transparent url(/scriptaculous/images/logo.png) top left no-repeat; + display: block; + float: left; + height: 45px; + margin: 0 0 0 -0.5em; + overflow: hidden; + padding: 0; + text-indent: -5000px; + width: 238px; + } + + #header #navbar { + float: right; + list-style-type: none; + margin: 0; + overflow: hidden; + padding: 1.3em 0 0; + } + + #header #navbar li { + float: left; + font-size: 1.2em; + line-height: 1.6em; + list-style-position: inside; + margin-left: 1.0em; + } + + #header #navbar li a:link, + #header #navbar li a:hover, + #header #navbar li a:visited { + color: #fff; + text-shadow: 0 1px 0 #627b41; + } + + + +h1#page-title { + border-bottom: 1px solid #ddd; + font-size: 3.3em; + line-height: normal; + margin: 0 0 0.2em 0; + padding: 0 0 0.2em 0; +} + + +/* @section content */ +#content { + height: 1%; + overflow: visible; +} + + /* @section body */ + #wiki { + float: left; + margin-right: 3%; + width: 70%; + } + + /* @section rightbar */ + #sidebar { + float: right; + overflow: hidden; + width: 23%; + margin-bottom: 4em; + } + + #sidebar { + background-color: #f7f7f7; + border: 1px solid #ddd; + margin-top: 1.5em; + padding: 1em; + + border-radius: 0.5em; + -moz-border-radius: 0.5em; + -webkit-border-radius: 0.5em; + } + + #sidebar { + font-size: 1.2em; + line-height: 1.5em; + } + + #sidebar h3 { + font-size: 1.2em; + color: #333; + margin: 0; + padding: 0; + text-shadow: 0 1px 0 #fff; + } + + #sidebar ul { + margin: 0.5em 0 1em; + overflow: hidden; + padding: 0; + } + + #sidebar ul li { + color: #bbb; + list-style-position: outside; + list-style-type: none; + margin: 0 0 0 1em; + padding: 0; + line-height: 1.75em; + } + + #sidebar ul li:hover { + list-style-type: square; + } + + #sidebar ul li a { + font-weight: bold; + text-shadow: 0 1px 0 #fff; + } + + /* @section footer */ + #footer { + clear: both; + border-top: 1px solid #ccc; + margin: 2em 0 7em; + } + + #footer p { + font-size: 1.2em; + line-height: 1.6em; + color: #999; + margin: 0.9em 0; + } + + +/* @section nav-chiclet */ +#wiki p.upper-chiclet { + border: 1px solid #ddd; + background-color: #f7f7f7; + color: #333; + font-weight: bold; + margin: 1.3em 0 1em; + padding: 0.5em 1em; + text-shadow: 0 1px 0 #fff; + + border-radius: 0.5em; + -moz-border-radius: 0.5em; + -webkit-border-radius: 0.5em; +} + + +/* @section wiki */ +#wiki { + padding-bottom: 3em; +} + +#wiki p { + font-size: 1.4em; + line-height: 1.6em; + margin: 0 0 1.0em; +} + +#wiki a:link { + color: #4183c4; + text-decoration: none; +} + +#wiki a:hover, #wiki a:visited { + text-decoration: underline; +} + +#wiki ul, #wiki ol { + margin: 1em 0 1em 2.0em; + list-style-position: outside; + padding: 0; + +} + +#wiki p + ul, #wiki p + ol, +#wiki ul li > ul, #wiki ol li > ol { + margin-top: 0; +} + +#wiki ul li > ul, #wiki ol li > ol { + margin-left: 0; +} + + #wiki ul { + list-style-type: square; + } + + #wiki ol li > ol li { + font-size: 1.0em !important; + list-style-type: lower-roman; + list-style-position: inside; + } + + #wiki ol li > ol li > ol li { + list-style-type: lower-alpha; + } + + #wiki ol li > ol li > ol li > ol li { + list-style-type: lower-greek; + } + +#wiki ul li, #wiki ol li { + font-size: 1.4em; + line-height: 1.6em; + padding-top: 0.1em; /* Line up ordinals */ +} + +#wiki blockquote { + margin: 0 4.0em 0 2.0em; + padding: 0; +} + + #wiki blockquote p { + color: #888; + font-style: italic; + } + + +/* Headings */ +#wiki h1, #wiki h2, #wiki h3, +#wiki h4, #wiki h5, #wiki h6 { + margin: 0; + padding: 0.5em 0 0.2em; +} + +#wiki h1 { + font-size: 2.6em; + font-weight: bold; +} + +#wiki h2 { + font-size: 2.2em; + font-weight: bold; +} + +#wiki h3 { + font-size: 2.0em; + font-weight: bold; +} + +#wiki h4 { + font-size: 1.8em; + font-weight: bold; +} + +#wiki h5 { + font-size: 1.6em; + font-weight: bold; + +} + +#wiki h6 { + font-size: 1.4em; + font-weight: bold; + margin-top: 1.0em; + text-transform: uppercase; /* all caps */ +} + +/* Code-related */ +#wiki p code { + background-color: #f7f7f7; + border: 1px solid #ddd; + color: #222; /* This is a little heavy when #000 */ + font-size: 0.9em; + font-family: Consolas, Monaco, "Courier New", monospace; + padding: 0.15em 0.3em; +} + +#wiki table, #wiki table tbody { + border-collapse: collapse; + margin: 1em 0; + width: 100%; +} + +#wiki table tbody tr th { + color: #666; + font-size: 1.2em; + font-weight: bold; + line-height: 1.6em; + padding: 0.3em 0.5em; + text-align: left; +} + +#wiki table tbody tr td { + border: 1px solid #ddd; + padding: 0.3em 0.5em; + font-size: 1.2em; + line-height: 1.6em; +} + +#wiki table tbody tr:nth-child(2n) { + background-color: #f7f7f7; +} + +#wiki pre { + padding: 1.2em; +} + +#wiki pre code { + font-size: 1.2em; + line-height: 1.6em; + overflow: hidden; /* keep it within the bounds */ +} \ No newline at end of file diff --git a/images/logo.png b/images/logo.png new file mode 100644 index 0000000..d4c3bcd Binary files /dev/null and b/images/logo.png differ diff --git a/index.html b/index.html new file mode 100644 index 0000000..4d2b5e2 --- /dev/null +++ b/index.html @@ -0,0 +1,72 @@ +--- +layout: default +title: Home +--- + +
+ +

script.aculo.us Web 2.0 JavaScript

+

script.aculo.us is a set of JavaScript libraries to enhance the user interface of web sites. It provides an visual effects engine, a drag and drop library (including sortable lists), a couple of controls (Ajax-based autocompletion, in-place editing, sliders) and more. Be sure to have a look at the demos!

+

API Documentation and Reference

+

This wiki details Version 1.8.1 of the library, which is the most current version of the 1.x trunk of script.aculo.us.

+ + + +
+

Miscellaneous: Builder, Sound, Unit Testing

+
+

script.aculo.us is open source. Read up on how to contribute by finding bugs, making bug reports and helping fixing them.

+

Help port the old, dead wiki to github and earn BIG BROWNIE POINTS! You can find a copy of the old wiki contents at http://script.aculo.us/docs. See some helpful hints for porting, and please follow the style guide!

+

Quick start

+

1. Download & install

+

Using script.aculo.us is easy! First, go to the script.aculo.us downloads page to grab yourself the latest version in a convenient package. Follow the instructions there, then return here.

+

Next, put prototype.js, scriptaculous.js, builder.js, effects.js, dragdrop.js, slider.js and controls.js in a directory of your website, e.g. /javascripts.

+

Third, load script.aculo.us in your web page. This is done by linking to the scripts in the head of your document.

+
<script src="javascripts/prototype.js" type="text/javascript"></script>
+<script src="javascripts/scriptaculous.js" type="text/javascript"></script>
+
+
+

The scriptaculous.js loader script will automatically load in the other libraries.

+

By default, scriptaculous.js loads all of the other javascript files necessary for effects, drag-and-drop, sliders, and all of the other script.aculo.us features. If you don’t need all of the features, you can limit the additional scripts that get loaded by specifying them in a comma-separated list, e.g.:
+

<script src="scriptaculous.js?load=effects,dragdrop" type="text/javascript"></script>
+

+The scripts that can be specified are: builder, effects, dragdrop, controls, and slider

+

Note that some of the scripts require that others be loaded in order to function properly.

+

2. Use it!

+

To call upon the functions, use HTML script tags.
+The best way is to define them like this:

+
<script type="text/javascript" language="javascript">
+  // <![CDATA[
+  $('element_id').appear();
+  // ]]>
+</script>
+
+

This way, you won’t have to worry about using characters like < and > in your Java Script code.

+

You can also use effects inside event handlers:

+
<div onclick="$(this).switchOff()">
+  Click here if you've seen enough.
+</div>
+

+

If you want to get tricky with it, you can pass extra options to the effect like duration, fps (frames per second), and delay.

+
<div onclick="$(this).blindUp({ duration: 16 })">
+  Click here if you want this to go slooooow.
+</div>
+

+

Next steps

+

Have a look at the demos to catch a glimpse of what you can achieve. Read the documentation. Create the next killer application!

+ +
diff --git a/lib/prototype.js b/lib/prototype.js deleted file mode 100644 index 845ab7f..0000000 --- a/lib/prototype.js +++ /dev/null @@ -1,4874 +0,0 @@ -/* Prototype JavaScript framework, version 1.6.1 - * (c) 2005-2009 Sam Stephenson - * - * Prototype is freely distributable under the terms of an MIT-style license. - * For details, see the Prototype web site: http://www.prototypejs.org/ - * - *--------------------------------------------------------------------------*/ - -var Prototype = { - Version: '1.6.1', - - Browser: (function(){ - var ua = navigator.userAgent; - var isOpera = Object.prototype.toString.call(window.opera) == '[object Opera]'; - return { - IE: !!window.attachEvent && !isOpera, - Opera: isOpera, - WebKit: ua.indexOf('AppleWebKit/') > -1, - Gecko: ua.indexOf('Gecko') > -1 && ua.indexOf('KHTML') === -1, - MobileSafari: /Apple.*Mobile.*Safari/.test(ua) - } - })(), - - BrowserFeatures: { - XPath: !!document.evaluate, - SelectorsAPI: !!document.querySelector, - ElementExtensions: (function() { - var constructor = window.Element || window.HTMLElement; - return !!(constructor && constructor.prototype); - })(), - SpecificElementExtensions: (function() { - if (typeof window.HTMLDivElement !== 'undefined') - return true; - - var div = document.createElement('div'); - var form = document.createElement('form'); - var isSupported = false; - - if (div['__proto__'] && (div['__proto__'] !== form['__proto__'])) { - isSupported = true; - } - - div = form = null; - - return isSupported; - })() - }, - - ScriptFragment: ']*>([\\S\\s]*?)<\/script>', - JSONFilter: /^\/\*-secure-([\s\S]*)\*\/\s*$/, - - emptyFunction: function() { }, - K: function(x) { return x } -}; - -if (Prototype.Browser.MobileSafari) - Prototype.BrowserFeatures.SpecificElementExtensions = false; - - -var Abstract = { }; - - -var Try = { - these: function() { - var returnValue; - - for (var i = 0, length = arguments.length; i < length; i++) { - var lambda = arguments[i]; - try { - returnValue = lambda(); - break; - } catch (e) { } - } - - return returnValue; - } -}; - -/* Based on Alex Arnell's inheritance implementation. */ - -var Class = (function() { - function subclass() {}; - function create() { - var parent = null, properties = $A(arguments); - if (Object.isFunction(properties[0])) - parent = properties.shift(); - - function klass() { - this.initialize.apply(this, arguments); - } - - Object.extend(klass, Class.Methods); - klass.superclass = parent; - klass.subclasses = []; - - if (parent) { - subclass.prototype = parent.prototype; - klass.prototype = new subclass; - parent.subclasses.push(klass); - } - - for (var i = 0; i < properties.length; i++) - klass.addMethods(properties[i]); - - if (!klass.prototype.initialize) - klass.prototype.initialize = Prototype.emptyFunction; - - klass.prototype.constructor = klass; - return klass; - } - - function addMethods(source) { - var ancestor = this.superclass && this.superclass.prototype; - var properties = Object.keys(source); - - if (!Object.keys({ toString: true }).length) { - if (source.toString != Object.prototype.toString) - properties.push("toString"); - if (source.valueOf != Object.prototype.valueOf) - properties.push("valueOf"); - } - - for (var i = 0, length = properties.length; i < length; i++) { - var property = properties[i], value = source[property]; - if (ancestor && Object.isFunction(value) && - value.argumentNames().first() == "$super") { - var method = value; - value = (function(m) { - return function() { return ancestor[m].apply(this, arguments); }; - })(property).wrap(method); - - value.valueOf = method.valueOf.bind(method); - value.toString = method.toString.bind(method); - } - this.prototype[property] = value; - } - - return this; - } - - return { - create: create, - Methods: { - addMethods: addMethods - } - }; -})(); -(function() { - - var _toString = Object.prototype.toString; - - function extend(destination, source) { - for (var property in source) - destination[property] = source[property]; - return destination; - } - - function inspect(object) { - try { - if (isUndefined(object)) return 'undefined'; - if (object === null) return 'null'; - return object.inspect ? object.inspect() : String(object); - } catch (e) { - if (e instanceof RangeError) return '...'; - throw e; - } - } - - function toJSON(object) { - var type = typeof object; - switch (type) { - case 'undefined': - case 'function': - case 'unknown': return; - case 'boolean': return object.toString(); - } - - if (object === null) return 'null'; - if (object.toJSON) return object.toJSON(); - if (isElement(object)) return; - - var results = []; - for (var property in object) { - var value = toJSON(object[property]); - if (!isUndefined(value)) - results.push(property.toJSON() + ': ' + value); - } - - return '{' + results.join(', ') + '}'; - } - - function toQueryString(object) { - return $H(object).toQueryString(); - } - - function toHTML(object) { - return object && object.toHTML ? object.toHTML() : String.interpret(object); - } - - function keys(object) { - var results = []; - for (var property in object) - results.push(property); - return results; - } - - function values(object) { - var results = []; - for (var property in object) - results.push(object[property]); - return results; - } - - function clone(object) { - return extend({ }, object); - } - - function isElement(object) { - return !!(object && object.nodeType == 1); - } - - function isArray(object) { - return _toString.call(object) == "[object Array]"; - } - - - function isHash(object) { - return object instanceof Hash; - } - - function isFunction(object) { - return typeof object === "function"; - } - - function isString(object) { - return _toString.call(object) == "[object String]"; - } - - function isNumber(object) { - return _toString.call(object) == "[object Number]"; - } - - function isUndefined(object) { - return typeof object === "undefined"; - } - - extend(Object, { - extend: extend, - inspect: inspect, - toJSON: toJSON, - toQueryString: toQueryString, - toHTML: toHTML, - keys: keys, - values: values, - clone: clone, - isElement: isElement, - isArray: isArray, - isHash: isHash, - isFunction: isFunction, - isString: isString, - isNumber: isNumber, - isUndefined: isUndefined - }); -})(); -Object.extend(Function.prototype, (function() { - var slice = Array.prototype.slice; - - function update(array, args) { - var arrayLength = array.length, length = args.length; - while (length--) array[arrayLength + length] = args[length]; - return array; - } - - function merge(array, args) { - array = slice.call(array, 0); - return update(array, args); - } - - function argumentNames() { - var names = this.toString().match(/^[\s\(]*function[^(]*\(([^)]*)\)/)[1] - .replace(/\/\/.*?[\r\n]|\/\*(?:.|[\r\n])*?\*\//g, '') - .replace(/\s+/g, '').split(','); - return names.length == 1 && !names[0] ? [] : names; - } - - function bind(context) { - if (arguments.length < 2 && Object.isUndefined(arguments[0])) return this; - var __method = this, args = slice.call(arguments, 1); - return function() { - var a = merge(args, arguments); - return __method.apply(context, a); - } - } - - function bindAsEventListener(context) { - var __method = this, args = slice.call(arguments, 1); - return function(event) { - var a = update([event || window.event], args); - return __method.apply(context, a); - } - } - - function curry() { - if (!arguments.length) return this; - var __method = this, args = slice.call(arguments, 0); - return function() { - var a = merge(args, arguments); - return __method.apply(this, a); - } - } - - function delay(timeout) { - var __method = this, args = slice.call(arguments, 1); - timeout = timeout * 1000 - return window.setTimeout(function() { - return __method.apply(__method, args); - }, timeout); - } - - function defer() { - var args = update([0.01], arguments); - return this.delay.apply(this, args); - } - - function wrap(wrapper) { - var __method = this; - return function() { - var a = update([__method.bind(this)], arguments); - return wrapper.apply(this, a); - } - } - - function methodize() { - if (this._methodized) return this._methodized; - var __method = this; - return this._methodized = function() { - var a = update([this], arguments); - return __method.apply(null, a); - }; - } - - return { - argumentNames: argumentNames, - bind: bind, - bindAsEventListener: bindAsEventListener, - curry: curry, - delay: delay, - defer: defer, - wrap: wrap, - methodize: methodize - } -})()); - - -Date.prototype.toJSON = function() { - return '"' + this.getUTCFullYear() + '-' + - (this.getUTCMonth() + 1).toPaddedString(2) + '-' + - this.getUTCDate().toPaddedString(2) + 'T' + - this.getUTCHours().toPaddedString(2) + ':' + - this.getUTCMinutes().toPaddedString(2) + ':' + - this.getUTCSeconds().toPaddedString(2) + 'Z"'; -}; - - -RegExp.prototype.match = RegExp.prototype.test; - -RegExp.escape = function(str) { - return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1'); -}; -var PeriodicalExecuter = Class.create({ - initialize: function(callback, frequency) { - this.callback = callback; - this.frequency = frequency; - this.currentlyExecuting = false; - - this.registerCallback(); - }, - - registerCallback: function() { - this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000); - }, - - execute: function() { - this.callback(this); - }, - - stop: function() { - if (!this.timer) return; - clearInterval(this.timer); - this.timer = null; - }, - - onTimerEvent: function() { - if (!this.currentlyExecuting) { - try { - this.currentlyExecuting = true; - this.execute(); - this.currentlyExecuting = false; - } catch(e) { - this.currentlyExecuting = false; - throw e; - } - } - } -}); -Object.extend(String, { - interpret: function(value) { - return value == null ? '' : String(value); - }, - specialChar: { - '\b': '\\b', - '\t': '\\t', - '\n': '\\n', - '\f': '\\f', - '\r': '\\r', - '\\': '\\\\' - } -}); - -Object.extend(String.prototype, (function() { - - function prepareReplacement(replacement) { - if (Object.isFunction(replacement)) return replacement; - var template = new Template(replacement); - return function(match) { return template.evaluate(match) }; - } - - function gsub(pattern, replacement) { - var result = '', source = this, match; - replacement = prepareReplacement(replacement); - - if (Object.isString(pattern)) - pattern = RegExp.escape(pattern); - - if (!(pattern.length || pattern.source)) { - replacement = replacement(''); - return replacement + source.split('').join(replacement) + replacement; - } - - while (source.length > 0) { - if (match = source.match(pattern)) { - result += source.slice(0, match.index); - result += String.interpret(replacement(match)); - source = source.slice(match.index + match[0].length); - } else { - result += source, source = ''; - } - } - return result; - } - - function sub(pattern, replacement, count) { - replacement = prepareReplacement(replacement); - count = Object.isUndefined(count) ? 1 : count; - - return this.gsub(pattern, function(match) { - if (--count < 0) return match[0]; - return replacement(match); - }); - } - - function scan(pattern, iterator) { - this.gsub(pattern, iterator); - return String(this); - } - - function truncate(length, truncation) { - length = length || 30; - truncation = Object.isUndefined(truncation) ? '...' : truncation; - return this.length > length ? - this.slice(0, length - truncation.length) + truncation : String(this); - } - - function strip() { - return this.replace(/^\s+/, '').replace(/\s+$/, ''); - } - - function stripTags() { - return this.replace(/<\w+(\s+("[^"]*"|'[^']*'|[^>])+)?>|<\/\w+>/gi, ''); - } - - function stripScripts() { - return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), ''); - } - - function extractScripts() { - var matchAll = new RegExp(Prototype.ScriptFragment, 'img'); - var matchOne = new RegExp(Prototype.ScriptFragment, 'im'); - return (this.match(matchAll) || []).map(function(scriptTag) { - return (scriptTag.match(matchOne) || ['', ''])[1]; - }); - } - - function evalScripts() { - return this.extractScripts().map(function(script) { return eval(script) }); - } - - function escapeHTML() { - return this.replace(/&/g,'&').replace(//g,'>'); - } - - function unescapeHTML() { - return this.stripTags().replace(/</g,'<').replace(/>/g,'>').replace(/&/g,'&'); - } - - - function toQueryParams(separator) { - var match = this.strip().match(/([^?#]*)(#.*)?$/); - if (!match) return { }; - - return match[1].split(separator || '&').inject({ }, function(hash, pair) { - if ((pair = pair.split('='))[0]) { - var key = decodeURIComponent(pair.shift()); - var value = pair.length > 1 ? pair.join('=') : pair[0]; - if (value != undefined) value = decodeURIComponent(value); - - if (key in hash) { - if (!Object.isArray(hash[key])) hash[key] = [hash[key]]; - hash[key].push(value); - } - else hash[key] = value; - } - return hash; - }); - } - - function toArray() { - return this.split(''); - } - - function succ() { - return this.slice(0, this.length - 1) + - String.fromCharCode(this.charCodeAt(this.length - 1) + 1); - } - - function times(count) { - return count < 1 ? '' : new Array(count + 1).join(this); - } - - function camelize() { - var parts = this.split('-'), len = parts.length; - if (len == 1) return parts[0]; - - var camelized = this.charAt(0) == '-' - ? parts[0].charAt(0).toUpperCase() + parts[0].substring(1) - : parts[0]; - - for (var i = 1; i < len; i++) - camelized += parts[i].charAt(0).toUpperCase() + parts[i].substring(1); - - return camelized; - } - - function capitalize() { - return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase(); - } - - function underscore() { - return this.replace(/::/g, '/') - .replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2') - .replace(/([a-z\d])([A-Z])/g, '$1_$2') - .replace(/-/g, '_') - .toLowerCase(); - } - - function dasherize() { - return this.replace(/_/g, '-'); - } - - function inspect(useDoubleQuotes) { - var escapedString = this.replace(/[\x00-\x1f\\]/g, function(character) { - if (character in String.specialChar) { - return String.specialChar[character]; - } - return '\\u00' + character.charCodeAt().toPaddedString(2, 16); - }); - if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"'; - return "'" + escapedString.replace(/'/g, '\\\'') + "'"; - } - - function toJSON() { - return this.inspect(true); - } - - function unfilterJSON(filter) { - return this.replace(filter || Prototype.JSONFilter, '$1'); - } - - function isJSON() { - var str = this; - if (str.blank()) return false; - str = this.replace(/\\./g, '@').replace(/"[^"\\\n\r]*"/g, ''); - return (/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(str); - } - - function evalJSON(sanitize) { - var json = this.unfilterJSON(); - try { - if (!sanitize || json.isJSON()) return eval('(' + json + ')'); - } catch (e) { } - throw new SyntaxError('Badly formed JSON string: ' + this.inspect()); - } - - function include(pattern) { - return this.indexOf(pattern) > -1; - } - - function startsWith(pattern) { - return this.indexOf(pattern) === 0; - } - - function endsWith(pattern) { - var d = this.length - pattern.length; - return d >= 0 && this.lastIndexOf(pattern) === d; - } - - function empty() { - return this == ''; - } - - function blank() { - return /^\s*$/.test(this); - } - - function interpolate(object, pattern) { - return new Template(this, pattern).evaluate(object); - } - - return { - gsub: gsub, - sub: sub, - scan: scan, - truncate: truncate, - strip: String.prototype.trim ? String.prototype.trim : strip, - stripTags: stripTags, - stripScripts: stripScripts, - extractScripts: extractScripts, - evalScripts: evalScripts, - escapeHTML: escapeHTML, - unescapeHTML: unescapeHTML, - toQueryParams: toQueryParams, - parseQuery: toQueryParams, - toArray: toArray, - succ: succ, - times: times, - camelize: camelize, - capitalize: capitalize, - underscore: underscore, - dasherize: dasherize, - inspect: inspect, - toJSON: toJSON, - unfilterJSON: unfilterJSON, - isJSON: isJSON, - evalJSON: evalJSON, - include: include, - startsWith: startsWith, - endsWith: endsWith, - empty: empty, - blank: blank, - interpolate: interpolate - }; -})()); - -var Template = Class.create({ - initialize: function(template, pattern) { - this.template = template.toString(); - this.pattern = pattern || Template.Pattern; - }, - - evaluate: function(object) { - if (object && Object.isFunction(object.toTemplateReplacements)) - object = object.toTemplateReplacements(); - - return this.template.gsub(this.pattern, function(match) { - if (object == null) return (match[1] + ''); - - var before = match[1] || ''; - if (before == '\\') return match[2]; - - var ctx = object, expr = match[3]; - var pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/; - match = pattern.exec(expr); - if (match == null) return before; - - while (match != null) { - var comp = match[1].startsWith('[') ? match[2].replace(/\\\\]/g, ']') : match[1]; - ctx = ctx[comp]; - if (null == ctx || '' == match[3]) break; - expr = expr.substring('[' == match[3] ? match[1].length : match[0].length); - match = pattern.exec(expr); - } - - return before + String.interpret(ctx); - }); - } -}); -Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/; - -var $break = { }; - -var Enumerable = (function() { - function each(iterator, context) { - var index = 0; - try { - this._each(function(value) { - iterator.call(context, value, index++); - }); - } catch (e) { - if (e != $break) throw e; - } - return this; - } - - function eachSlice(number, iterator, context) { - var index = -number, slices = [], array = this.toArray(); - if (number < 1) return array; - while ((index += number) < array.length) - slices.push(array.slice(index, index+number)); - return slices.collect(iterator, context); - } - - function all(iterator, context) { - iterator = iterator || Prototype.K; - var result = true; - this.each(function(value, index) { - result = result && !!iterator.call(context, value, index); - if (!result) throw $break; - }); - return result; - } - - function any(iterator, context) { - iterator = iterator || Prototype.K; - var result = false; - this.each(function(value, index) { - if (result = !!iterator.call(context, value, index)) - throw $break; - }); - return result; - } - - function collect(iterator, context) { - iterator = iterator || Prototype.K; - var results = []; - this.each(function(value, index) { - results.push(iterator.call(context, value, index)); - }); - return results; - } - - function detect(iterator, context) { - var result; - this.each(function(value, index) { - if (iterator.call(context, value, index)) { - result = value; - throw $break; - } - }); - return result; - } - - function findAll(iterator, context) { - var results = []; - this.each(function(value, index) { - if (iterator.call(context, value, index)) - results.push(value); - }); - return results; - } - - function grep(filter, iterator, context) { - iterator = iterator || Prototype.K; - var results = []; - - if (Object.isString(filter)) - filter = new RegExp(RegExp.escape(filter)); - - this.each(function(value, index) { - if (filter.match(value)) - results.push(iterator.call(context, value, index)); - }); - return results; - } - - function include(object) { - if (Object.isFunction(this.indexOf)) - if (this.indexOf(object) != -1) return true; - - var found = false; - this.each(function(value) { - if (value == object) { - found = true; - throw $break; - } - }); - return found; - } - - function inGroupsOf(number, fillWith) { - fillWith = Object.isUndefined(fillWith) ? null : fillWith; - return this.eachSlice(number, function(slice) { - while(slice.length < number) slice.push(fillWith); - return slice; - }); - } - - function inject(memo, iterator, context) { - this.each(function(value, index) { - memo = iterator.call(context, memo, value, index); - }); - return memo; - } - - function invoke(method) { - var args = $A(arguments).slice(1); - return this.map(function(value) { - return value[method].apply(value, args); - }); - } - - function max(iterator, context) { - iterator = iterator || Prototype.K; - var result; - this.each(function(value, index) { - value = iterator.call(context, value, index); - if (result == null || value >= result) - result = value; - }); - return result; - } - - function min(iterator, context) { - iterator = iterator || Prototype.K; - var result; - this.each(function(value, index) { - value = iterator.call(context, value, index); - if (result == null || value < result) - result = value; - }); - return result; - } - - function partition(iterator, context) { - iterator = iterator || Prototype.K; - var trues = [], falses = []; - this.each(function(value, index) { - (iterator.call(context, value, index) ? - trues : falses).push(value); - }); - return [trues, falses]; - } - - function pluck(property) { - var results = []; - this.each(function(value) { - results.push(value[property]); - }); - return results; - } - - function reject(iterator, context) { - var results = []; - this.each(function(value, index) { - if (!iterator.call(context, value, index)) - results.push(value); - }); - return results; - } - - function sortBy(iterator, context) { - return this.map(function(value, index) { - return { - value: value, - criteria: iterator.call(context, value, index) - }; - }).sort(function(left, right) { - var a = left.criteria, b = right.criteria; - return a < b ? -1 : a > b ? 1 : 0; - }).pluck('value'); - } - - function toArray() { - return this.map(); - } - - function zip() { - var iterator = Prototype.K, args = $A(arguments); - if (Object.isFunction(args.last())) - iterator = args.pop(); - - var collections = [this].concat(args).map($A); - return this.map(function(value, index) { - return iterator(collections.pluck(index)); - }); - } - - function size() { - return this.toArray().length; - } - - function inspect() { - return '#'; - } - - - - - - - - - - return { - each: each, - eachSlice: eachSlice, - all: all, - every: all, - any: any, - some: any, - collect: collect, - map: collect, - detect: detect, - findAll: findAll, - select: findAll, - filter: findAll, - grep: grep, - include: include, - member: include, - inGroupsOf: inGroupsOf, - inject: inject, - invoke: invoke, - max: max, - min: min, - partition: partition, - pluck: pluck, - reject: reject, - sortBy: sortBy, - toArray: toArray, - entries: toArray, - zip: zip, - size: size, - inspect: inspect, - find: detect - }; -})(); -function $A(iterable) { - if (!iterable) return []; - if ('toArray' in Object(iterable)) return iterable.toArray(); - var length = iterable.length || 0, results = new Array(length); - while (length--) results[length] = iterable[length]; - return results; -} - -function $w(string) { - if (!Object.isString(string)) return []; - string = string.strip(); - return string ? string.split(/\s+/) : []; -} - -Array.from = $A; - - -(function() { - var arrayProto = Array.prototype, - slice = arrayProto.slice, - _each = arrayProto.forEach; // use native browser JS 1.6 implementation if available - - function each(iterator) { - for (var i = 0, length = this.length; i < length; i++) - iterator(this[i]); - } - if (!_each) _each = each; - - function clear() { - this.length = 0; - return this; - } - - function first() { - return this[0]; - } - - function last() { - return this[this.length - 1]; - } - - function compact() { - return this.select(function(value) { - return value != null; - }); - } - - function flatten() { - return this.inject([], function(array, value) { - if (Object.isArray(value)) - return array.concat(value.flatten()); - array.push(value); - return array; - }); - } - - function without() { - var values = slice.call(arguments, 0); - return this.select(function(value) { - return !values.include(value); - }); - } - - function reverse(inline) { - return (inline !== false ? this : this.toArray())._reverse(); - } - - function uniq(sorted) { - return this.inject([], function(array, value, index) { - if (0 == index || (sorted ? array.last() != value : !array.include(value))) - array.push(value); - return array; - }); - } - - function intersect(array) { - return this.uniq().findAll(function(item) { - return array.detect(function(value) { return item === value }); - }); - } - - - function clone() { - return slice.call(this, 0); - } - - function size() { - return this.length; - } - - function inspect() { - return '[' + this.map(Object.inspect).join(', ') + ']'; - } - - function toJSON() { - var results = []; - this.each(function(object) { - var value = Object.toJSON(object); - if (!Object.isUndefined(value)) results.push(value); - }); - return '[' + results.join(', ') + ']'; - } - - function indexOf(item, i) { - i || (i = 0); - var length = this.length; - if (i < 0) i = length + i; - for (; i < length; i++) - if (this[i] === item) return i; - return -1; - } - - function lastIndexOf(item, i) { - i = isNaN(i) ? this.length : (i < 0 ? this.length + i : i) + 1; - var n = this.slice(0, i).reverse().indexOf(item); - return (n < 0) ? n : i - n - 1; - } - - function concat() { - var array = slice.call(this, 0), item; - for (var i = 0, length = arguments.length; i < length; i++) { - item = arguments[i]; - if (Object.isArray(item) && !('callee' in item)) { - for (var j = 0, arrayLength = item.length; j < arrayLength; j++) - array.push(item[j]); - } else { - array.push(item); - } - } - return array; - } - - Object.extend(arrayProto, Enumerable); - - if (!arrayProto._reverse) - arrayProto._reverse = arrayProto.reverse; - - Object.extend(arrayProto, { - _each: _each, - clear: clear, - first: first, - last: last, - compact: compact, - flatten: flatten, - without: without, - reverse: reverse, - uniq: uniq, - intersect: intersect, - clone: clone, - toArray: clone, - size: size, - inspect: inspect, - toJSON: toJSON - }); - - var CONCAT_ARGUMENTS_BUGGY = (function() { - return [].concat(arguments)[0][0] !== 1; - })(1,2) - - if (CONCAT_ARGUMENTS_BUGGY) arrayProto.concat = concat; - - if (!arrayProto.indexOf) arrayProto.indexOf = indexOf; - if (!arrayProto.lastIndexOf) arrayProto.lastIndexOf = lastIndexOf; -})(); -function $H(object) { - return new Hash(object); -}; - -var Hash = Class.create(Enumerable, (function() { - function initialize(object) { - this._object = Object.isHash(object) ? object.toObject() : Object.clone(object); - } - - function _each(iterator) { - for (var key in this._object) { - var value = this._object[key], pair = [key, value]; - pair.key = key; - pair.value = value; - iterator(pair); - } - } - - function set(key, value) { - return this._object[key] = value; - } - - function get(key) { - if (this._object[key] !== Object.prototype[key]) - return this._object[key]; - } - - function unset(key) { - var value = this._object[key]; - delete this._object[key]; - return value; - } - - function toObject() { - return Object.clone(this._object); - } - - function keys() { - return this.pluck('key'); - } - - function values() { - return this.pluck('value'); - } - - function index(value) { - var match = this.detect(function(pair) { - return pair.value === value; - }); - return match && match.key; - } - - function merge(object) { - return this.clone().update(object); - } - - function update(object) { - return new Hash(object).inject(this, function(result, pair) { - result.set(pair.key, pair.value); - return result; - }); - } - - function toQueryPair(key, value) { - if (Object.isUndefined(value)) return key; - return key + '=' + encodeURIComponent(String.interpret(value)); - } - - function toQueryString() { - return this.inject([], function(results, pair) { - var key = encodeURIComponent(pair.key), values = pair.value; - - if (values && typeof values == 'object') { - if (Object.isArray(values)) - return results.concat(values.map(toQueryPair.curry(key))); - } else results.push(toQueryPair(key, values)); - return results; - }).join('&'); - } - - function inspect() { - return '#'; - } - - function toJSON() { - return Object.toJSON(this.toObject()); - } - - function clone() { - return new Hash(this); - } - - return { - initialize: initialize, - _each: _each, - set: set, - get: get, - unset: unset, - toObject: toObject, - toTemplateReplacements: toObject, - keys: keys, - values: values, - index: index, - merge: merge, - update: update, - toQueryString: toQueryString, - inspect: inspect, - toJSON: toJSON, - clone: clone - }; -})()); - -Hash.from = $H; -Object.extend(Number.prototype, (function() { - function toColorPart() { - return this.toPaddedString(2, 16); - } - - function succ() { - return this + 1; - } - - function times(iterator, context) { - $R(0, this, true).each(iterator, context); - return this; - } - - function toPaddedString(length, radix) { - var string = this.toString(radix || 10); - return '0'.times(length - string.length) + string; - } - - function toJSON() { - return isFinite(this) ? this.toString() : 'null'; - } - - function abs() { - return Math.abs(this); - } - - function round() { - return Math.round(this); - } - - function ceil() { - return Math.ceil(this); - } - - function floor() { - return Math.floor(this); - } - - return { - toColorPart: toColorPart, - succ: succ, - times: times, - toPaddedString: toPaddedString, - toJSON: toJSON, - abs: abs, - round: round, - ceil: ceil, - floor: floor - }; -})()); - -function $R(start, end, exclusive) { - return new ObjectRange(start, end, exclusive); -} - -var ObjectRange = Class.create(Enumerable, (function() { - function initialize(start, end, exclusive) { - this.start = start; - this.end = end; - this.exclusive = exclusive; - } - - function _each(iterator) { - var value = this.start; - while (this.include(value)) { - iterator(value); - value = value.succ(); - } - } - - function include(value) { - if (value < this.start) - return false; - if (this.exclusive) - return value < this.end; - return value <= this.end; - } - - return { - initialize: initialize, - _each: _each, - include: include - }; -})()); - - - -var Ajax = { - getTransport: function() { - return Try.these( - function() {return new XMLHttpRequest()}, - function() {return new ActiveXObject('Msxml2.XMLHTTP')}, - function() {return new ActiveXObject('Microsoft.XMLHTTP')} - ) || false; - }, - - activeRequestCount: 0 -}; - -Ajax.Responders = { - responders: [], - - _each: function(iterator) { - this.responders._each(iterator); - }, - - register: function(responder) { - if (!this.include(responder)) - this.responders.push(responder); - }, - - unregister: function(responder) { - this.responders = this.responders.without(responder); - }, - - dispatch: function(callback, request, transport, json) { - this.each(function(responder) { - if (Object.isFunction(responder[callback])) { - try { - responder[callback].apply(responder, [request, transport, json]); - } catch (e) { } - } - }); - } -}; - -Object.extend(Ajax.Responders, Enumerable); - -Ajax.Responders.register({ - onCreate: function() { Ajax.activeRequestCount++ }, - onComplete: function() { Ajax.activeRequestCount-- } -}); -Ajax.Base = Class.create({ - initialize: function(options) { - this.options = { - method: 'post', - asynchronous: true, - contentType: 'application/x-www-form-urlencoded', - encoding: 'UTF-8', - parameters: '', - evalJSON: true, - evalJS: true - }; - Object.extend(this.options, options || { }); - - this.options.method = this.options.method.toLowerCase(); - - if (Object.isString(this.options.parameters)) - this.options.parameters = this.options.parameters.toQueryParams(); - else if (Object.isHash(this.options.parameters)) - this.options.parameters = this.options.parameters.toObject(); - } -}); -Ajax.Request = Class.create(Ajax.Base, { - _complete: false, - - initialize: function($super, url, options) { - $super(options); - this.transport = Ajax.getTransport(); - this.request(url); - }, - - request: function(url) { - this.url = url; - this.method = this.options.method; - var params = Object.clone(this.options.parameters); - - if (!['get', 'post'].include(this.method)) { - params['_method'] = this.method; - this.method = 'post'; - } - - this.parameters = params; - - if (params = Object.toQueryString(params)) { - if (this.method == 'get') - this.url += (this.url.include('?') ? '&' : '?') + params; - else if (/Konqueror|Safari|KHTML/.test(navigator.userAgent)) - params += '&_='; - } - - try { - var response = new Ajax.Response(this); - if (this.options.onCreate) this.options.onCreate(response); - Ajax.Responders.dispatch('onCreate', this, response); - - this.transport.open(this.method.toUpperCase(), this.url, - this.options.asynchronous); - - if (this.options.asynchronous) this.respondToReadyState.bind(this).defer(1); - - this.transport.onreadystatechange = this.onStateChange.bind(this); - this.setRequestHeaders(); - - this.body = this.method == 'post' ? (this.options.postBody || params) : null; - this.transport.send(this.body); - - /* Force Firefox to handle ready state 4 for synchronous requests */ - if (!this.options.asynchronous && this.transport.overrideMimeType) - this.onStateChange(); - - } - catch (e) { - this.dispatchException(e); - } - }, - - onStateChange: function() { - var readyState = this.transport.readyState; - if (readyState > 1 && !((readyState == 4) && this._complete)) - this.respondToReadyState(this.transport.readyState); - }, - - setRequestHeaders: function() { - var headers = { - 'X-Requested-With': 'XMLHttpRequest', - 'X-Prototype-Version': Prototype.Version, - 'Accept': 'text/javascript, text/html, application/xml, text/xml, */*' - }; - - if (this.method == 'post') { - headers['Content-type'] = this.options.contentType + - (this.options.encoding ? '; charset=' + this.options.encoding : ''); - - /* Force "Connection: close" for older Mozilla browsers to work - * around a bug where XMLHttpRequest sends an incorrect - * Content-length header. See Mozilla Bugzilla #246651. - */ - if (this.transport.overrideMimeType && - (navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005) - headers['Connection'] = 'close'; - } - - if (typeof this.options.requestHeaders == 'object') { - var extras = this.options.requestHeaders; - - if (Object.isFunction(extras.push)) - for (var i = 0, length = extras.length; i < length; i += 2) - headers[extras[i]] = extras[i+1]; - else - $H(extras).each(function(pair) { headers[pair.key] = pair.value }); - } - - for (var name in headers) - this.transport.setRequestHeader(name, headers[name]); - }, - - success: function() { - var status = this.getStatus(); - return !status || (status >= 200 && status < 300); - }, - - getStatus: function() { - try { - return this.transport.status || 0; - } catch (e) { return 0 } - }, - - respondToReadyState: function(readyState) { - var state = Ajax.Request.Events[readyState], response = new Ajax.Response(this); - - if (state == 'Complete') { - try { - this._complete = true; - (this.options['on' + response.status] - || this.options['on' + (this.success() ? 'Success' : 'Failure')] - || Prototype.emptyFunction)(response, response.headerJSON); - } catch (e) { - this.dispatchException(e); - } - - var contentType = response.getHeader('Content-type'); - if (this.options.evalJS == 'force' - || (this.options.evalJS && this.isSameOrigin() && contentType - && contentType.match(/^\s*(text|application)\/(x-)?(java|ecma)script(;.*)?\s*$/i))) - this.evalResponse(); - } - - try { - (this.options['on' + state] || Prototype.emptyFunction)(response, response.headerJSON); - Ajax.Responders.dispatch('on' + state, this, response, response.headerJSON); - } catch (e) { - this.dispatchException(e); - } - - if (state == 'Complete') { - this.transport.onreadystatechange = Prototype.emptyFunction; - } - }, - - isSameOrigin: function() { - var m = this.url.match(/^\s*https?:\/\/[^\/]*/); - return !m || (m[0] == '#{protocol}//#{domain}#{port}'.interpolate({ - protocol: location.protocol, - domain: document.domain, - port: location.port ? ':' + location.port : '' - })); - }, - - getHeader: function(name) { - try { - return this.transport.getResponseHeader(name) || null; - } catch (e) { return null; } - }, - - evalResponse: function() { - try { - return eval((this.transport.responseText || '').unfilterJSON()); - } catch (e) { - this.dispatchException(e); - } - }, - - dispatchException: function(exception) { - (this.options.onException || Prototype.emptyFunction)(this, exception); - Ajax.Responders.dispatch('onException', this, exception); - } -}); - -Ajax.Request.Events = - ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete']; - - - - - - - - -Ajax.Response = Class.create({ - initialize: function(request){ - this.request = request; - var transport = this.transport = request.transport, - readyState = this.readyState = transport.readyState; - - if((readyState > 2 && !Prototype.Browser.IE) || readyState == 4) { - this.status = this.getStatus(); - this.statusText = this.getStatusText(); - this.responseText = String.interpret(transport.responseText); - this.headerJSON = this._getHeaderJSON(); - } - - if(readyState == 4) { - var xml = transport.responseXML; - this.responseXML = Object.isUndefined(xml) ? null : xml; - this.responseJSON = this._getResponseJSON(); - } - }, - - status: 0, - - statusText: '', - - getStatus: Ajax.Request.prototype.getStatus, - - getStatusText: function() { - try { - return this.transport.statusText || ''; - } catch (e) { return '' } - }, - - getHeader: Ajax.Request.prototype.getHeader, - - getAllHeaders: function() { - try { - return this.getAllResponseHeaders(); - } catch (e) { return null } - }, - - getResponseHeader: function(name) { - return this.transport.getResponseHeader(name); - }, - - getAllResponseHeaders: function() { - return this.transport.getAllResponseHeaders(); - }, - - _getHeaderJSON: function() { - var json = this.getHeader('X-JSON'); - if (!json) return null; - json = decodeURIComponent(escape(json)); - try { - return json.evalJSON(this.request.options.sanitizeJSON || - !this.request.isSameOrigin()); - } catch (e) { - this.request.dispatchException(e); - } - }, - - _getResponseJSON: function() { - var options = this.request.options; - if (!options.evalJSON || (options.evalJSON != 'force' && - !(this.getHeader('Content-type') || '').include('application/json')) || - this.responseText.blank()) - return null; - try { - return this.responseText.evalJSON(options.sanitizeJSON || - !this.request.isSameOrigin()); - } catch (e) { - this.request.dispatchException(e); - } - } -}); - -Ajax.Updater = Class.create(Ajax.Request, { - initialize: function($super, container, url, options) { - this.container = { - success: (container.success || container), - failure: (container.failure || (container.success ? null : container)) - }; - - options = Object.clone(options); - var onComplete = options.onComplete; - options.onComplete = (function(response, json) { - this.updateContent(response.responseText); - if (Object.isFunction(onComplete)) onComplete(response, json); - }).bind(this); - - $super(url, options); - }, - - updateContent: function(responseText) { - var receiver = this.container[this.success() ? 'success' : 'failure'], - options = this.options; - - if (!options.evalScripts) responseText = responseText.stripScripts(); - - if (receiver = $(receiver)) { - if (options.insertion) { - if (Object.isString(options.insertion)) { - var insertion = { }; insertion[options.insertion] = responseText; - receiver.insert(insertion); - } - else options.insertion(receiver, responseText); - } - else receiver.update(responseText); - } - } -}); - -Ajax.PeriodicalUpdater = Class.create(Ajax.Base, { - initialize: function($super, container, url, options) { - $super(options); - this.onComplete = this.options.onComplete; - - this.frequency = (this.options.frequency || 2); - this.decay = (this.options.decay || 1); - - this.updater = { }; - this.container = container; - this.url = url; - - this.start(); - }, - - start: function() { - this.options.onComplete = this.updateComplete.bind(this); - this.onTimerEvent(); - }, - - stop: function() { - this.updater.options.onComplete = undefined; - clearTimeout(this.timer); - (this.onComplete || Prototype.emptyFunction).apply(this, arguments); - }, - - updateComplete: function(response) { - if (this.options.decay) { - this.decay = (response.responseText == this.lastText ? - this.decay * this.options.decay : 1); - - this.lastText = response.responseText; - } - this.timer = this.onTimerEvent.bind(this).delay(this.decay * this.frequency); - }, - - onTimerEvent: function() { - this.updater = new Ajax.Updater(this.container, this.url, this.options); - } -}); - - - -function $(element) { - if (arguments.length > 1) { - for (var i = 0, elements = [], length = arguments.length; i < length; i++) - elements.push($(arguments[i])); - return elements; - } - if (Object.isString(element)) - element = document.getElementById(element); - return Element.extend(element); -} - -if (Prototype.BrowserFeatures.XPath) { - document._getElementsByXPath = function(expression, parentElement) { - var results = []; - var query = document.evaluate(expression, $(parentElement) || document, - null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); - for (var i = 0, length = query.snapshotLength; i < length; i++) - results.push(Element.extend(query.snapshotItem(i))); - return results; - }; -} - -/*--------------------------------------------------------------------------*/ - -if (!window.Node) var Node = { }; - -if (!Node.ELEMENT_NODE) { - Object.extend(Node, { - ELEMENT_NODE: 1, - ATTRIBUTE_NODE: 2, - TEXT_NODE: 3, - CDATA_SECTION_NODE: 4, - ENTITY_REFERENCE_NODE: 5, - ENTITY_NODE: 6, - PROCESSING_INSTRUCTION_NODE: 7, - COMMENT_NODE: 8, - DOCUMENT_NODE: 9, - DOCUMENT_TYPE_NODE: 10, - DOCUMENT_FRAGMENT_NODE: 11, - NOTATION_NODE: 12 - }); -} - - -(function(global) { - - var SETATTRIBUTE_IGNORES_NAME = (function(){ - var elForm = document.createElement("form"); - var elInput = document.createElement("input"); - var root = document.documentElement; - elInput.setAttribute("name", "test"); - elForm.appendChild(elInput); - root.appendChild(elForm); - var isBuggy = elForm.elements - ? (typeof elForm.elements.test == "undefined") - : null; - root.removeChild(elForm); - elForm = elInput = null; - return isBuggy; - })(); - - var element = global.Element; - global.Element = function(tagName, attributes) { - attributes = attributes || { }; - tagName = tagName.toLowerCase(); - var cache = Element.cache; - if (SETATTRIBUTE_IGNORES_NAME && attributes.name) { - tagName = '<' + tagName + ' name="' + attributes.name + '">'; - delete attributes.name; - return Element.writeAttribute(document.createElement(tagName), attributes); - } - if (!cache[tagName]) cache[tagName] = Element.extend(document.createElement(tagName)); - return Element.writeAttribute(cache[tagName].cloneNode(false), attributes); - }; - Object.extend(global.Element, element || { }); - if (element) global.Element.prototype = element.prototype; -})(this); - -Element.cache = { }; -Element.idCounter = 1; - -Element.Methods = { - visible: function(element) { - return $(element).style.display != 'none'; - }, - - toggle: function(element) { - element = $(element); - Element[Element.visible(element) ? 'hide' : 'show'](element); - return element; - }, - - - hide: function(element) { - element = $(element); - element.style.display = 'none'; - return element; - }, - - show: function(element) { - element = $(element); - element.style.display = ''; - return element; - }, - - remove: function(element) { - element = $(element); - element.parentNode.removeChild(element); - return element; - }, - - update: (function(){ - - var SELECT_ELEMENT_INNERHTML_BUGGY = (function(){ - var el = document.createElement("select"), - isBuggy = true; - el.innerHTML = ""; - if (el.options && el.options[0]) { - isBuggy = el.options[0].nodeName.toUpperCase() !== "OPTION"; - } - el = null; - return isBuggy; - })(); - - var TABLE_ELEMENT_INNERHTML_BUGGY = (function(){ - try { - var el = document.createElement("table"); - if (el && el.tBodies) { - el.innerHTML = "test"; - var isBuggy = typeof el.tBodies[0] == "undefined"; - el = null; - return isBuggy; - } - } catch (e) { - return true; - } - })(); - - var SCRIPT_ELEMENT_REJECTS_TEXTNODE_APPENDING = (function () { - var s = document.createElement("script"), - isBuggy = false; - try { - s.appendChild(document.createTextNode("")); - isBuggy = !s.firstChild || - s.firstChild && s.firstChild.nodeType !== 3; - } catch (e) { - isBuggy = true; - } - s = null; - return isBuggy; - })(); - - function update(element, content) { - element = $(element); - - if (content && content.toElement) - content = content.toElement(); - - if (Object.isElement(content)) - return element.update().insert(content); - - content = Object.toHTML(content); - - var tagName = element.tagName.toUpperCase(); - - if (tagName === 'SCRIPT' && SCRIPT_ELEMENT_REJECTS_TEXTNODE_APPENDING) { - element.text = content; - return element; - } - - if (SELECT_ELEMENT_INNERHTML_BUGGY || TABLE_ELEMENT_INNERHTML_BUGGY) { - if (tagName in Element._insertionTranslations.tags) { - while (element.firstChild) { - element.removeChild(element.firstChild); - } - Element._getContentFromAnonymousElement(tagName, content.stripScripts()) - .each(function(node) { - element.appendChild(node) - }); - } - else { - element.innerHTML = content.stripScripts(); - } - } - else { - element.innerHTML = content.stripScripts(); - } - - content.evalScripts.bind(content).defer(); - return element; - } - - return update; - })(), - - replace: function(element, content) { - element = $(element); - if (content && content.toElement) content = content.toElement(); - else if (!Object.isElement(content)) { - content = Object.toHTML(content); - var range = element.ownerDocument.createRange(); - range.selectNode(element); - content.evalScripts.bind(content).defer(); - content = range.createContextualFragment(content.stripScripts()); - } - element.parentNode.replaceChild(content, element); - return element; - }, - - insert: function(element, insertions) { - element = $(element); - - if (Object.isString(insertions) || Object.isNumber(insertions) || - Object.isElement(insertions) || (insertions && (insertions.toElement || insertions.toHTML))) - insertions = {bottom:insertions}; - - var content, insert, tagName, childNodes; - - for (var position in insertions) { - content = insertions[position]; - position = position.toLowerCase(); - insert = Element._insertionTranslations[position]; - - if (content && content.toElement) content = content.toElement(); - if (Object.isElement(content)) { - insert(element, content); - continue; - } - - content = Object.toHTML(content); - - tagName = ((position == 'before' || position == 'after') - ? element.parentNode : element).tagName.toUpperCase(); - - childNodes = Element._getContentFromAnonymousElement(tagName, content.stripScripts()); - - if (position == 'top' || position == 'after') childNodes.reverse(); - childNodes.each(insert.curry(element)); - - content.evalScripts.bind(content).defer(); - } - - return element; - }, - - wrap: function(element, wrapper, attributes) { - element = $(element); - if (Object.isElement(wrapper)) - $(wrapper).writeAttribute(attributes || { }); - else if (Object.isString(wrapper)) wrapper = new Element(wrapper, attributes); - else wrapper = new Element('div', wrapper); - if (element.parentNode) - element.parentNode.replaceChild(wrapper, element); - wrapper.appendChild(element); - return wrapper; - }, - - inspect: function(element) { - element = $(element); - var result = '<' + element.tagName.toLowerCase(); - $H({'id': 'id', 'className': 'class'}).each(function(pair) { - var property = pair.first(), attribute = pair.last(); - var value = (element[property] || '').toString(); - if (value) result += ' ' + attribute + '=' + value.inspect(true); - }); - return result + '>'; - }, - - recursivelyCollect: function(element, property) { - element = $(element); - var elements = []; - while (element = element[property]) - if (element.nodeType == 1) - elements.push(Element.extend(element)); - return elements; - }, - - ancestors: function(element) { - return Element.recursivelyCollect(element, 'parentNode'); - }, - - descendants: function(element) { - return Element.select(element, "*"); - }, - - firstDescendant: function(element) { - element = $(element).firstChild; - while (element && element.nodeType != 1) element = element.nextSibling; - return $(element); - }, - - immediateDescendants: function(element) { - if (!(element = $(element).firstChild)) return []; - while (element && element.nodeType != 1) element = element.nextSibling; - if (element) return [element].concat($(element).nextSiblings()); - return []; - }, - - previousSiblings: function(element) { - return Element.recursivelyCollect(element, 'previousSibling'); - }, - - nextSiblings: function(element) { - return Element.recursivelyCollect(element, 'nextSibling'); - }, - - siblings: function(element) { - element = $(element); - return Element.previousSiblings(element).reverse() - .concat(Element.nextSiblings(element)); - }, - - match: function(element, selector) { - if (Object.isString(selector)) - selector = new Selector(selector); - return selector.match($(element)); - }, - - up: function(element, expression, index) { - element = $(element); - if (arguments.length == 1) return $(element.parentNode); - var ancestors = Element.ancestors(element); - return Object.isNumber(expression) ? ancestors[expression] : - Selector.findElement(ancestors, expression, index); - }, - - down: function(element, expression, index) { - element = $(element); - if (arguments.length == 1) return Element.firstDescendant(element); - return Object.isNumber(expression) ? Element.descendants(element)[expression] : - Element.select(element, expression)[index || 0]; - }, - - previous: function(element, expression, index) { - element = $(element); - if (arguments.length == 1) return $(Selector.handlers.previousElementSibling(element)); - var previousSiblings = Element.previousSiblings(element); - return Object.isNumber(expression) ? previousSiblings[expression] : - Selector.findElement(previousSiblings, expression, index); - }, - - next: function(element, expression, index) { - element = $(element); - if (arguments.length == 1) return $(Selector.handlers.nextElementSibling(element)); - var nextSiblings = Element.nextSiblings(element); - return Object.isNumber(expression) ? nextSiblings[expression] : - Selector.findElement(nextSiblings, expression, index); - }, - - - select: function(element) { - var args = Array.prototype.slice.call(arguments, 1); - return Selector.findChildElements(element, args); - }, - - adjacent: function(element) { - var args = Array.prototype.slice.call(arguments, 1); - return Selector.findChildElements(element.parentNode, args).without(element); - }, - - identify: function(element) { - element = $(element); - var id = Element.readAttribute(element, 'id'); - if (id) return id; - do { id = 'anonymous_element_' + Element.idCounter++ } while ($(id)); - Element.writeAttribute(element, 'id', id); - return id; - }, - - readAttribute: function(element, name) { - element = $(element); - if (Prototype.Browser.IE) { - var t = Element._attributeTranslations.read; - if (t.values[name]) return t.values[name](element, name); - if (t.names[name]) name = t.names[name]; - if (name.include(':')) { - return (!element.attributes || !element.attributes[name]) ? null : - element.attributes[name].value; - } - } - return element.getAttribute(name); - }, - - writeAttribute: function(element, name, value) { - element = $(element); - var attributes = { }, t = Element._attributeTranslations.write; - - if (typeof name == 'object') attributes = name; - else attributes[name] = Object.isUndefined(value) ? true : value; - - for (var attr in attributes) { - name = t.names[attr] || attr; - value = attributes[attr]; - if (t.values[attr]) name = t.values[attr](element, value); - if (value === false || value === null) - element.removeAttribute(name); - else if (value === true) - element.setAttribute(name, name); - else element.setAttribute(name, value); - } - return element; - }, - - getHeight: function(element) { - return Element.getDimensions(element).height; - }, - - getWidth: function(element) { - return Element.getDimensions(element).width; - }, - - classNames: function(element) { - return new Element.ClassNames(element); - }, - - hasClassName: function(element, className) { - if (!(element = $(element))) return; - var elementClassName = element.className; - return (elementClassName.length > 0 && (elementClassName == className || - new RegExp("(^|\\s)" + className + "(\\s|$)").test(elementClassName))); - }, - - addClassName: function(element, className) { - if (!(element = $(element))) return; - if (!Element.hasClassName(element, className)) - element.className += (element.className ? ' ' : '') + className; - return element; - }, - - removeClassName: function(element, className) { - if (!(element = $(element))) return; - element.className = element.className.replace( - new RegExp("(^|\\s+)" + className + "(\\s+|$)"), ' ').strip(); - return element; - }, - - toggleClassName: function(element, className) { - if (!(element = $(element))) return; - return Element[Element.hasClassName(element, className) ? - 'removeClassName' : 'addClassName'](element, className); - }, - - cleanWhitespace: function(element) { - element = $(element); - var node = element.firstChild; - while (node) { - var nextNode = node.nextSibling; - if (node.nodeType == 3 && !/\S/.test(node.nodeValue)) - element.removeChild(node); - node = nextNode; - } - return element; - }, - - empty: function(element) { - return $(element).innerHTML.blank(); - }, - - descendantOf: function(element, ancestor) { - element = $(element), ancestor = $(ancestor); - - if (element.compareDocumentPosition) - return (element.compareDocumentPosition(ancestor) & 8) === 8; - - if (ancestor.contains) - return ancestor.contains(element) && ancestor !== element; - - while (element = element.parentNode) - if (element == ancestor) return true; - - return false; - }, - - scrollTo: function(element) { - element = $(element); - var pos = Element.cumulativeOffset(element); - window.scrollTo(pos[0], pos[1]); - return element; - }, - - getStyle: function(element, style) { - element = $(element); - style = style == 'float' ? 'cssFloat' : style.camelize(); - var value = element.style[style]; - if (!value || value == 'auto') { - var css = document.defaultView.getComputedStyle(element, null); - value = css ? css[style] : null; - } - if (style == 'opacity') return value ? parseFloat(value) : 1.0; - return value == 'auto' ? null : value; - }, - - getOpacity: function(element) { - return $(element).getStyle('opacity'); - }, - - setStyle: function(element, styles) { - element = $(element); - var elementStyle = element.style, match; - if (Object.isString(styles)) { - element.style.cssText += ';' + styles; - return styles.include('opacity') ? - element.setOpacity(styles.match(/opacity:\s*(\d?\.?\d*)/)[1]) : element; - } - for (var property in styles) - if (property == 'opacity') element.setOpacity(styles[property]); - else - elementStyle[(property == 'float' || property == 'cssFloat') ? - (Object.isUndefined(elementStyle.styleFloat) ? 'cssFloat' : 'styleFloat') : - property] = styles[property]; - - return element; - }, - - setOpacity: function(element, value) { - element = $(element); - element.style.opacity = (value == 1 || value === '') ? '' : - (value < 0.00001) ? 0 : value; - return element; - }, - - getDimensions: function(element) { - element = $(element); - var display = Element.getStyle(element, 'display'); - if (display != 'none' && display != null) // Safari bug - return {width: element.offsetWidth, height: element.offsetHeight}; - - var els = element.style; - var originalVisibility = els.visibility; - var originalPosition = els.position; - var originalDisplay = els.display; - els.visibility = 'hidden'; - if (originalPosition != 'fixed') // Switching fixed to absolute causes issues in Safari - els.position = 'absolute'; - els.display = 'block'; - var originalWidth = element.clientWidth; - var originalHeight = element.clientHeight; - els.display = originalDisplay; - els.position = originalPosition; - els.visibility = originalVisibility; - return {width: originalWidth, height: originalHeight}; - }, - - makePositioned: function(element) { - element = $(element); - var pos = Element.getStyle(element, 'position'); - if (pos == 'static' || !pos) { - element._madePositioned = true; - element.style.position = 'relative'; - if (Prototype.Browser.Opera) { - element.style.top = 0; - element.style.left = 0; - } - } - return element; - }, - - undoPositioned: function(element) { - element = $(element); - if (element._madePositioned) { - element._madePositioned = undefined; - element.style.position = - element.style.top = - element.style.left = - element.style.bottom = - element.style.right = ''; - } - return element; - }, - - makeClipping: function(element) { - element = $(element); - if (element._overflow) return element; - element._overflow = Element.getStyle(element, 'overflow') || 'auto'; - if (element._overflow !== 'hidden') - element.style.overflow = 'hidden'; - return element; - }, - - undoClipping: function(element) { - element = $(element); - if (!element._overflow) return element; - element.style.overflow = element._overflow == 'auto' ? '' : element._overflow; - element._overflow = null; - return element; - }, - - cumulativeOffset: function(element) { - var valueT = 0, valueL = 0; - do { - valueT += element.offsetTop || 0; - valueL += element.offsetLeft || 0; - element = element.offsetParent; - } while (element); - return Element._returnOffset(valueL, valueT); - }, - - positionedOffset: function(element) { - var valueT = 0, valueL = 0; - do { - valueT += element.offsetTop || 0; - valueL += element.offsetLeft || 0; - element = element.offsetParent; - if (element) { - if (element.tagName.toUpperCase() == 'BODY') break; - var p = Element.getStyle(element, 'position'); - if (p !== 'static') break; - } - } while (element); - return Element._returnOffset(valueL, valueT); - }, - - absolutize: function(element) { - element = $(element); - if (Element.getStyle(element, 'position') == 'absolute') return element; - - var offsets = Element.positionedOffset(element); - var top = offsets[1]; - var left = offsets[0]; - var width = element.clientWidth; - var height = element.clientHeight; - - element._originalLeft = left - parseFloat(element.style.left || 0); - element._originalTop = top - parseFloat(element.style.top || 0); - element._originalWidth = element.style.width; - element._originalHeight = element.style.height; - - element.style.position = 'absolute'; - element.style.top = top + 'px'; - element.style.left = left + 'px'; - element.style.width = width + 'px'; - element.style.height = height + 'px'; - return element; - }, - - relativize: function(element) { - element = $(element); - if (Element.getStyle(element, 'position') == 'relative') return element; - - element.style.position = 'relative'; - var top = parseFloat(element.style.top || 0) - (element._originalTop || 0); - var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0); - - element.style.top = top + 'px'; - element.style.left = left + 'px'; - element.style.height = element._originalHeight; - element.style.width = element._originalWidth; - return element; - }, - - cumulativeScrollOffset: function(element) { - var valueT = 0, valueL = 0; - do { - valueT += element.scrollTop || 0; - valueL += element.scrollLeft || 0; - element = element.parentNode; - } while (element); - return Element._returnOffset(valueL, valueT); - }, - - getOffsetParent: function(element) { - if (element.offsetParent) return $(element.offsetParent); - if (element == document.body) return $(element); - - while ((element = element.parentNode) && element != document.body) - if (Element.getStyle(element, 'position') != 'static') - return $(element); - - return $(document.body); - }, - - viewportOffset: function(forElement) { - var valueT = 0, valueL = 0; - - var element = forElement; - do { - valueT += element.offsetTop || 0; - valueL += element.offsetLeft || 0; - - if (element.offsetParent == document.body && - Element.getStyle(element, 'position') == 'absolute') break; - - } while (element = element.offsetParent); - - element = forElement; - do { - if (!Prototype.Browser.Opera || (element.tagName && (element.tagName.toUpperCase() == 'BODY'))) { - valueT -= element.scrollTop || 0; - valueL -= element.scrollLeft || 0; - } - } while (element = element.parentNode); - - return Element._returnOffset(valueL, valueT); - }, - - clonePosition: function(element, source) { - var options = Object.extend({ - setLeft: true, - setTop: true, - setWidth: true, - setHeight: true, - offsetTop: 0, - offsetLeft: 0 - }, arguments[2] || { }); - - source = $(source); - var p = Element.viewportOffset(source); - - element = $(element); - var delta = [0, 0]; - var parent = null; - if (Element.getStyle(element, 'position') == 'absolute') { - parent = Element.getOffsetParent(element); - delta = Element.viewportOffset(parent); - } - - if (parent == document.body) { - delta[0] -= document.body.offsetLeft; - delta[1] -= document.body.offsetTop; - } - - if (options.setLeft) element.style.left = (p[0] - delta[0] + options.offsetLeft) + 'px'; - if (options.setTop) element.style.top = (p[1] - delta[1] + options.offsetTop) + 'px'; - if (options.setWidth) element.style.width = source.offsetWidth + 'px'; - if (options.setHeight) element.style.height = source.offsetHeight + 'px'; - return element; - } -}; - -Object.extend(Element.Methods, { - getElementsBySelector: Element.Methods.select, - - childElements: Element.Methods.immediateDescendants -}); - -Element._attributeTranslations = { - write: { - names: { - className: 'class', - htmlFor: 'for' - }, - values: { } - } -}; - -if (Prototype.Browser.Opera) { - Element.Methods.getStyle = Element.Methods.getStyle.wrap( - function(proceed, element, style) { - switch (style) { - case 'left': case 'top': case 'right': case 'bottom': - if (proceed(element, 'position') === 'static') return null; - case 'height': case 'width': - if (!Element.visible(element)) return null; - - var dim = parseInt(proceed(element, style), 10); - - if (dim !== element['offset' + style.capitalize()]) - return dim + 'px'; - - var properties; - if (style === 'height') { - properties = ['border-top-width', 'padding-top', - 'padding-bottom', 'border-bottom-width']; - } - else { - properties = ['border-left-width', 'padding-left', - 'padding-right', 'border-right-width']; - } - return properties.inject(dim, function(memo, property) { - var val = proceed(element, property); - return val === null ? memo : memo - parseInt(val, 10); - }) + 'px'; - default: return proceed(element, style); - } - } - ); - - Element.Methods.readAttribute = Element.Methods.readAttribute.wrap( - function(proceed, element, attribute) { - if (attribute === 'title') return element.title; - return proceed(element, attribute); - } - ); -} - -else if (Prototype.Browser.IE) { - Element.Methods.getOffsetParent = Element.Methods.getOffsetParent.wrap( - function(proceed, element) { - element = $(element); - try { element.offsetParent } - catch(e) { return $(document.body) } - var position = element.getStyle('position'); - if (position !== 'static') return proceed(element); - element.setStyle({ position: 'relative' }); - var value = proceed(element); - element.setStyle({ position: position }); - return value; - } - ); - - $w('positionedOffset viewportOffset').each(function(method) { - Element.Methods[method] = Element.Methods[method].wrap( - function(proceed, element) { - element = $(element); - try { element.offsetParent } - catch(e) { return Element._returnOffset(0,0) } - var position = element.getStyle('position'); - if (position !== 'static') return proceed(element); - var offsetParent = element.getOffsetParent(); - if (offsetParent && offsetParent.getStyle('position') === 'fixed') - offsetParent.setStyle({ zoom: 1 }); - element.setStyle({ position: 'relative' }); - var value = proceed(element); - element.setStyle({ position: position }); - return value; - } - ); - }); - - Element.Methods.cumulativeOffset = Element.Methods.cumulativeOffset.wrap( - function(proceed, element) { - try { element.offsetParent } - catch(e) { return Element._returnOffset(0,0) } - return proceed(element); - } - ); - - Element.Methods.getStyle = function(element, style) { - element = $(element); - style = (style == 'float' || style == 'cssFloat') ? 'styleFloat' : style.camelize(); - var value = element.style[style]; - if (!value && element.currentStyle) value = element.currentStyle[style]; - - if (style == 'opacity') { - if (value = (element.getStyle('filter') || '').match(/alpha\(opacity=(.*)\)/)) - if (value[1]) return parseFloat(value[1]) / 100; - return 1.0; - } - - if (value == 'auto') { - if ((style == 'width' || style == 'height') && (element.getStyle('display') != 'none')) - return element['offset' + style.capitalize()] + 'px'; - return null; - } - return value; - }; - - Element.Methods.setOpacity = function(element, value) { - function stripAlpha(filter){ - return filter.replace(/alpha\([^\)]*\)/gi,''); - } - element = $(element); - var currentStyle = element.currentStyle; - if ((currentStyle && !currentStyle.hasLayout) || - (!currentStyle && element.style.zoom == 'normal')) - element.style.zoom = 1; - - var filter = element.getStyle('filter'), style = element.style; - if (value == 1 || value === '') { - (filter = stripAlpha(filter)) ? - style.filter = filter : style.removeAttribute('filter'); - return element; - } else if (value < 0.00001) value = 0; - style.filter = stripAlpha(filter) + - 'alpha(opacity=' + (value * 100) + ')'; - return element; - }; - - Element._attributeTranslations = (function(){ - - var classProp = 'className'; - var forProp = 'for'; - - var el = document.createElement('div'); - - el.setAttribute(classProp, 'x'); - - if (el.className !== 'x') { - el.setAttribute('class', 'x'); - if (el.className === 'x') { - classProp = 'class'; - } - } - el = null; - - el = document.createElement('label'); - el.setAttribute(forProp, 'x'); - if (el.htmlFor !== 'x') { - el.setAttribute('htmlFor', 'x'); - if (el.htmlFor === 'x') { - forProp = 'htmlFor'; - } - } - el = null; - - return { - read: { - names: { - 'class': classProp, - 'className': classProp, - 'for': forProp, - 'htmlFor': forProp - }, - values: { - _getAttr: function(element, attribute) { - return element.getAttribute(attribute); - }, - _getAttr2: function(element, attribute) { - return element.getAttribute(attribute, 2); - }, - _getAttrNode: function(element, attribute) { - var node = element.getAttributeNode(attribute); - return node ? node.value : ""; - }, - _getEv: (function(){ - - var el = document.createElement('div'); - el.onclick = Prototype.emptyFunction; - var value = el.getAttribute('onclick'); - var f; - - if (String(value).indexOf('{') > -1) { - f = function(element, attribute) { - attribute = element.getAttribute(attribute); - if (!attribute) return null; - attribute = attribute.toString(); - attribute = attribute.split('{')[1]; - attribute = attribute.split('}')[0]; - return attribute.strip(); - }; - } - else if (value === '') { - f = function(element, attribute) { - attribute = element.getAttribute(attribute); - if (!attribute) return null; - return attribute.strip(); - }; - } - el = null; - return f; - })(), - _flag: function(element, attribute) { - return $(element).hasAttribute(attribute) ? attribute : null; - }, - style: function(element) { - return element.style.cssText.toLowerCase(); - }, - title: function(element) { - return element.title; - } - } - } - } - })(); - - Element._attributeTranslations.write = { - names: Object.extend({ - cellpadding: 'cellPadding', - cellspacing: 'cellSpacing' - }, Element._attributeTranslations.read.names), - values: { - checked: function(element, value) { - element.checked = !!value; - }, - - style: function(element, value) { - element.style.cssText = value ? value : ''; - } - } - }; - - Element._attributeTranslations.has = {}; - - $w('colSpan rowSpan vAlign dateTime accessKey tabIndex ' + - 'encType maxLength readOnly longDesc frameBorder').each(function(attr) { - Element._attributeTranslations.write.names[attr.toLowerCase()] = attr; - Element._attributeTranslations.has[attr.toLowerCase()] = attr; - }); - - (function(v) { - Object.extend(v, { - href: v._getAttr2, - src: v._getAttr2, - type: v._getAttr, - action: v._getAttrNode, - disabled: v._flag, - checked: v._flag, - readonly: v._flag, - multiple: v._flag, - onload: v._getEv, - onunload: v._getEv, - onclick: v._getEv, - ondblclick: v._getEv, - onmousedown: v._getEv, - onmouseup: v._getEv, - onmouseover: v._getEv, - onmousemove: v._getEv, - onmouseout: v._getEv, - onfocus: v._getEv, - onblur: v._getEv, - onkeypress: v._getEv, - onkeydown: v._getEv, - onkeyup: v._getEv, - onsubmit: v._getEv, - onreset: v._getEv, - onselect: v._getEv, - onchange: v._getEv - }); - })(Element._attributeTranslations.read.values); - - if (Prototype.BrowserFeatures.ElementExtensions) { - (function() { - function _descendants(element) { - var nodes = element.getElementsByTagName('*'), results = []; - for (var i = 0, node; node = nodes[i]; i++) - if (node.tagName !== "!") // Filter out comment nodes. - results.push(node); - return results; - } - - Element.Methods.down = function(element, expression, index) { - element = $(element); - if (arguments.length == 1) return element.firstDescendant(); - return Object.isNumber(expression) ? _descendants(element)[expression] : - Element.select(element, expression)[index || 0]; - } - })(); - } - -} - -else if (Prototype.Browser.Gecko && /rv:1\.8\.0/.test(navigator.userAgent)) { - Element.Methods.setOpacity = function(element, value) { - element = $(element); - element.style.opacity = (value == 1) ? 0.999999 : - (value === '') ? '' : (value < 0.00001) ? 0 : value; - return element; - }; -} - -else if (Prototype.Browser.WebKit) { - Element.Methods.setOpacity = function(element, value) { - element = $(element); - element.style.opacity = (value == 1 || value === '') ? '' : - (value < 0.00001) ? 0 : value; - - if (value == 1) - if(element.tagName.toUpperCase() == 'IMG' && element.width) { - element.width++; element.width--; - } else try { - var n = document.createTextNode(' '); - element.appendChild(n); - element.removeChild(n); - } catch (e) { } - - return element; - }; - - Element.Methods.cumulativeOffset = function(element) { - var valueT = 0, valueL = 0; - do { - valueT += element.offsetTop || 0; - valueL += element.offsetLeft || 0; - if (element.offsetParent == document.body) - if (Element.getStyle(element, 'position') == 'absolute') break; - - element = element.offsetParent; - } while (element); - - return Element._returnOffset(valueL, valueT); - }; -} - -if ('outerHTML' in document.documentElement) { - Element.Methods.replace = function(element, content) { - element = $(element); - - if (content && content.toElement) content = content.toElement(); - if (Object.isElement(content)) { - element.parentNode.replaceChild(content, element); - return element; - } - - content = Object.toHTML(content); - var parent = element.parentNode, tagName = parent.tagName.toUpperCase(); - - if (Element._insertionTranslations.tags[tagName]) { - var nextSibling = element.next(); - var fragments = Element._getContentFromAnonymousElement(tagName, content.stripScripts()); - parent.removeChild(element); - if (nextSibling) - fragments.each(function(node) { parent.insertBefore(node, nextSibling) }); - else - fragments.each(function(node) { parent.appendChild(node) }); - } - else element.outerHTML = content.stripScripts(); - - content.evalScripts.bind(content).defer(); - return element; - }; -} - -Element._returnOffset = function(l, t) { - var result = [l, t]; - result.left = l; - result.top = t; - return result; -}; - -Element._getContentFromAnonymousElement = function(tagName, html) { - var div = new Element('div'), t = Element._insertionTranslations.tags[tagName]; - if (t) { - div.innerHTML = t[0] + html + t[1]; - t[2].times(function() { div = div.firstChild }); - } else div.innerHTML = html; - return $A(div.childNodes); -}; - -Element._insertionTranslations = { - before: function(element, node) { - element.parentNode.insertBefore(node, element); - }, - top: function(element, node) { - element.insertBefore(node, element.firstChild); - }, - bottom: function(element, node) { - element.appendChild(node); - }, - after: function(element, node) { - element.parentNode.insertBefore(node, element.nextSibling); - }, - tags: { - TABLE: ['', '
', 1], - TBODY: ['', '
', 2], - TR: ['', '
', 3], - TD: ['
', '
', 4], - SELECT: ['', 1] - } -}; - -(function() { - var tags = Element._insertionTranslations.tags; - Object.extend(tags, { - THEAD: tags.TBODY, - TFOOT: tags.TBODY, - TH: tags.TD - }); -})(); - -Element.Methods.Simulated = { - hasAttribute: function(element, attribute) { - attribute = Element._attributeTranslations.has[attribute] || attribute; - var node = $(element).getAttributeNode(attribute); - return !!(node && node.specified); - } -}; - -Element.Methods.ByTag = { }; - -Object.extend(Element, Element.Methods); - -(function(div) { - - if (!Prototype.BrowserFeatures.ElementExtensions && div['__proto__']) { - window.HTMLElement = { }; - window.HTMLElement.prototype = div['__proto__']; - Prototype.BrowserFeatures.ElementExtensions = true; - } - - div = null; - -})(document.createElement('div')) - -Element.extend = (function() { - - function checkDeficiency(tagName) { - if (typeof window.Element != 'undefined') { - var proto = window.Element.prototype; - if (proto) { - var id = '_' + (Math.random()+'').slice(2); - var el = document.createElement(tagName); - proto[id] = 'x'; - var isBuggy = (el[id] !== 'x'); - delete proto[id]; - el = null; - return isBuggy; - } - } - return false; - } - - function extendElementWith(element, methods) { - for (var property in methods) { - var value = methods[property]; - if (Object.isFunction(value) && !(property in element)) - element[property] = value.methodize(); - } - } - - var HTMLOBJECTELEMENT_PROTOTYPE_BUGGY = checkDeficiency('object'); - - if (Prototype.BrowserFeatures.SpecificElementExtensions) { - if (HTMLOBJECTELEMENT_PROTOTYPE_BUGGY) { - return function(element) { - if (element && typeof element._extendedByPrototype == 'undefined') { - var t = element.tagName; - if (t && (/^(?:object|applet|embed)$/i.test(t))) { - extendElementWith(element, Element.Methods); - extendElementWith(element, Element.Methods.Simulated); - extendElementWith(element, Element.Methods.ByTag[t.toUpperCase()]); - } - } - return element; - } - } - return Prototype.K; - } - - var Methods = { }, ByTag = Element.Methods.ByTag; - - var extend = Object.extend(function(element) { - if (!element || typeof element._extendedByPrototype != 'undefined' || - element.nodeType != 1 || element == window) return element; - - var methods = Object.clone(Methods), - tagName = element.tagName.toUpperCase(); - - if (ByTag[tagName]) Object.extend(methods, ByTag[tagName]); - - extendElementWith(element, methods); - - element._extendedByPrototype = Prototype.emptyFunction; - return element; - - }, { - refresh: function() { - if (!Prototype.BrowserFeatures.ElementExtensions) { - Object.extend(Methods, Element.Methods); - Object.extend(Methods, Element.Methods.Simulated); - } - } - }); - - extend.refresh(); - return extend; -})(); - -Element.hasAttribute = function(element, attribute) { - if (element.hasAttribute) return element.hasAttribute(attribute); - return Element.Methods.Simulated.hasAttribute(element, attribute); -}; - -Element.addMethods = function(methods) { - var F = Prototype.BrowserFeatures, T = Element.Methods.ByTag; - - if (!methods) { - Object.extend(Form, Form.Methods); - Object.extend(Form.Element, Form.Element.Methods); - Object.extend(Element.Methods.ByTag, { - "FORM": Object.clone(Form.Methods), - "INPUT": Object.clone(Form.Element.Methods), - "SELECT": Object.clone(Form.Element.Methods), - "TEXTAREA": Object.clone(Form.Element.Methods) - }); - } - - if (arguments.length == 2) { - var tagName = methods; - methods = arguments[1]; - } - - if (!tagName) Object.extend(Element.Methods, methods || { }); - else { - if (Object.isArray(tagName)) tagName.each(extend); - else extend(tagName); - } - - function extend(tagName) { - tagName = tagName.toUpperCase(); - if (!Element.Methods.ByTag[tagName]) - Element.Methods.ByTag[tagName] = { }; - Object.extend(Element.Methods.ByTag[tagName], methods); - } - - function copy(methods, destination, onlyIfAbsent) { - onlyIfAbsent = onlyIfAbsent || false; - for (var property in methods) { - var value = methods[property]; - if (!Object.isFunction(value)) continue; - if (!onlyIfAbsent || !(property in destination)) - destination[property] = value.methodize(); - } - } - - function findDOMClass(tagName) { - var klass; - var trans = { - "OPTGROUP": "OptGroup", "TEXTAREA": "TextArea", "P": "Paragraph", - "FIELDSET": "FieldSet", "UL": "UList", "OL": "OList", "DL": "DList", - "DIR": "Directory", "H1": "Heading", "H2": "Heading", "H3": "Heading", - "H4": "Heading", "H5": "Heading", "H6": "Heading", "Q": "Quote", - "INS": "Mod", "DEL": "Mod", "A": "Anchor", "IMG": "Image", "CAPTION": - "TableCaption", "COL": "TableCol", "COLGROUP": "TableCol", "THEAD": - "TableSection", "TFOOT": "TableSection", "TBODY": "TableSection", "TR": - "TableRow", "TH": "TableCell", "TD": "TableCell", "FRAMESET": - "FrameSet", "IFRAME": "IFrame" - }; - if (trans[tagName]) klass = 'HTML' + trans[tagName] + 'Element'; - if (window[klass]) return window[klass]; - klass = 'HTML' + tagName + 'Element'; - if (window[klass]) return window[klass]; - klass = 'HTML' + tagName.capitalize() + 'Element'; - if (window[klass]) return window[klass]; - - var element = document.createElement(tagName); - var proto = element['__proto__'] || element.constructor.prototype; - element = null; - return proto; - } - - var elementPrototype = window.HTMLElement ? HTMLElement.prototype : - Element.prototype; - - if (F.ElementExtensions) { - copy(Element.Methods, elementPrototype); - copy(Element.Methods.Simulated, elementPrototype, true); - } - - if (F.SpecificElementExtensions) { - for (var tag in Element.Methods.ByTag) { - var klass = findDOMClass(tag); - if (Object.isUndefined(klass)) continue; - copy(T[tag], klass.prototype); - } - } - - Object.extend(Element, Element.Methods); - delete Element.ByTag; - - if (Element.extend.refresh) Element.extend.refresh(); - Element.cache = { }; -}; - - -document.viewport = { - - getDimensions: function() { - return { width: this.getWidth(), height: this.getHeight() }; - }, - - getScrollOffsets: function() { - return Element._returnOffset( - window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft, - window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop); - } -}; - -(function(viewport) { - var B = Prototype.Browser, doc = document, element, property = {}; - - function getRootElement() { - if (B.WebKit && !doc.evaluate) - return document; - - if (B.Opera && window.parseFloat(window.opera.version()) < 9.5) - return document.body; - - return document.documentElement; - } - - function define(D) { - if (!element) element = getRootElement(); - - property[D] = 'client' + D; - - viewport['get' + D] = function() { return element[property[D]] }; - return viewport['get' + D](); - } - - viewport.getWidth = define.curry('Width'); - - viewport.getHeight = define.curry('Height'); -})(document.viewport); - - -Element.Storage = { - UID: 1 -}; - -Element.addMethods({ - getStorage: function(element) { - if (!(element = $(element))) return; - - var uid; - if (element === window) { - uid = 0; - } else { - if (typeof element._prototypeUID === "undefined") - element._prototypeUID = [Element.Storage.UID++]; - uid = element._prototypeUID[0]; - } - - if (!Element.Storage[uid]) - Element.Storage[uid] = $H(); - - return Element.Storage[uid]; - }, - - store: function(element, key, value) { - if (!(element = $(element))) return; - - if (arguments.length === 2) { - Element.getStorage(element).update(key); - } else { - Element.getStorage(element).set(key, value); - } - - return element; - }, - - retrieve: function(element, key, defaultValue) { - if (!(element = $(element))) return; - var hash = Element.getStorage(element), value = hash.get(key); - - if (Object.isUndefined(value)) { - hash.set(key, defaultValue); - value = defaultValue; - } - - return value; - }, - - clone: function(element, deep) { - if (!(element = $(element))) return; - var clone = element.cloneNode(deep); - clone._prototypeUID = void 0; - if (deep) { - var descendants = Element.select(clone, '*'), - i = descendants.length; - while (i--) { - descendants[i]._prototypeUID = void 0; - } - } - return Element.extend(clone); - } -}); -/* Portions of the Selector class are derived from Jack Slocum's DomQuery, - * part of YUI-Ext version 0.40, distributed under the terms of an MIT-style - * license. Please see http://www.yui-ext.com/ for more information. */ - -var Selector = Class.create({ - initialize: function(expression) { - this.expression = expression.strip(); - - if (this.shouldUseSelectorsAPI()) { - this.mode = 'selectorsAPI'; - } else if (this.shouldUseXPath()) { - this.mode = 'xpath'; - this.compileXPathMatcher(); - } else { - this.mode = "normal"; - this.compileMatcher(); - } - - }, - - shouldUseXPath: (function() { - - var IS_DESCENDANT_SELECTOR_BUGGY = (function(){ - var isBuggy = false; - if (document.evaluate && window.XPathResult) { - var el = document.createElement('div'); - el.innerHTML = '
'; - - var xpath = ".//*[local-name()='ul' or local-name()='UL']" + - "//*[local-name()='li' or local-name()='LI']"; - - var result = document.evaluate(xpath, el, null, - XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); - - isBuggy = (result.snapshotLength !== 2); - el = null; - } - return isBuggy; - })(); - - return function() { - if (!Prototype.BrowserFeatures.XPath) return false; - - var e = this.expression; - - if (Prototype.Browser.WebKit && - (e.include("-of-type") || e.include(":empty"))) - return false; - - if ((/(\[[\w-]*?:|:checked)/).test(e)) - return false; - - if (IS_DESCENDANT_SELECTOR_BUGGY) return false; - - return true; - } - - })(), - - shouldUseSelectorsAPI: function() { - if (!Prototype.BrowserFeatures.SelectorsAPI) return false; - - if (Selector.CASE_INSENSITIVE_CLASS_NAMES) return false; - - if (!Selector._div) Selector._div = new Element('div'); - - try { - Selector._div.querySelector(this.expression); - } catch(e) { - return false; - } - - return true; - }, - - compileMatcher: function() { - var e = this.expression, ps = Selector.patterns, h = Selector.handlers, - c = Selector.criteria, le, p, m, len = ps.length, name; - - if (Selector._cache[e]) { - this.matcher = Selector._cache[e]; - return; - } - - this.matcher = ["this.matcher = function(root) {", - "var r = root, h = Selector.handlers, c = false, n;"]; - - while (e && le != e && (/\S/).test(e)) { - le = e; - for (var i = 0; i"; - } -}); - -if (Prototype.BrowserFeatures.SelectorsAPI && - document.compatMode === 'BackCompat') { - Selector.CASE_INSENSITIVE_CLASS_NAMES = (function(){ - var div = document.createElement('div'), - span = document.createElement('span'); - - div.id = "prototype_test_id"; - span.className = 'Test'; - div.appendChild(span); - var isIgnored = (div.querySelector('#prototype_test_id .test') !== null); - div = span = null; - return isIgnored; - })(); -} - -Object.extend(Selector, { - _cache: { }, - - xpath: { - descendant: "//*", - child: "/*", - adjacent: "/following-sibling::*[1]", - laterSibling: '/following-sibling::*', - tagName: function(m) { - if (m[1] == '*') return ''; - return "[local-name()='" + m[1].toLowerCase() + - "' or local-name()='" + m[1].toUpperCase() + "']"; - }, - className: "[contains(concat(' ', @class, ' '), ' #{1} ')]", - id: "[@id='#{1}']", - attrPresence: function(m) { - m[1] = m[1].toLowerCase(); - return new Template("[@#{1}]").evaluate(m); - }, - attr: function(m) { - m[1] = m[1].toLowerCase(); - m[3] = m[5] || m[6]; - return new Template(Selector.xpath.operators[m[2]]).evaluate(m); - }, - pseudo: function(m) { - var h = Selector.xpath.pseudos[m[1]]; - if (!h) return ''; - if (Object.isFunction(h)) return h(m); - return new Template(Selector.xpath.pseudos[m[1]]).evaluate(m); - }, - operators: { - '=': "[@#{1}='#{3}']", - '!=': "[@#{1}!='#{3}']", - '^=': "[starts-with(@#{1}, '#{3}')]", - '$=': "[substring(@#{1}, (string-length(@#{1}) - string-length('#{3}') + 1))='#{3}']", - '*=': "[contains(@#{1}, '#{3}')]", - '~=': "[contains(concat(' ', @#{1}, ' '), ' #{3} ')]", - '|=': "[contains(concat('-', @#{1}, '-'), '-#{3}-')]" - }, - pseudos: { - 'first-child': '[not(preceding-sibling::*)]', - 'last-child': '[not(following-sibling::*)]', - 'only-child': '[not(preceding-sibling::* or following-sibling::*)]', - 'empty': "[count(*) = 0 and (count(text()) = 0)]", - 'checked': "[@checked]", - 'disabled': "[(@disabled) and (@type!='hidden')]", - 'enabled': "[not(@disabled) and (@type!='hidden')]", - 'not': function(m) { - var e = m[6], p = Selector.patterns, - x = Selector.xpath, le, v, len = p.length, name; - - var exclusion = []; - while (e && le != e && (/\S/).test(e)) { - le = e; - for (var i = 0; i= 0)]"; - return new Template(predicate).evaluate({ - fragment: fragment, a: a, b: b }); - } - } - } - }, - - criteria: { - tagName: 'n = h.tagName(n, r, "#{1}", c); c = false;', - className: 'n = h.className(n, r, "#{1}", c); c = false;', - id: 'n = h.id(n, r, "#{1}", c); c = false;', - attrPresence: 'n = h.attrPresence(n, r, "#{1}", c); c = false;', - attr: function(m) { - m[3] = (m[5] || m[6]); - return new Template('n = h.attr(n, r, "#{1}", "#{3}", "#{2}", c); c = false;').evaluate(m); - }, - pseudo: function(m) { - if (m[6]) m[6] = m[6].replace(/"/g, '\\"'); - return new Template('n = h.pseudo(n, "#{1}", "#{6}", r, c); c = false;').evaluate(m); - }, - descendant: 'c = "descendant";', - child: 'c = "child";', - adjacent: 'c = "adjacent";', - laterSibling: 'c = "laterSibling";' - }, - - patterns: [ - { name: 'laterSibling', re: /^\s*~\s*/ }, - { name: 'child', re: /^\s*>\s*/ }, - { name: 'adjacent', re: /^\s*\+\s*/ }, - { name: 'descendant', re: /^\s/ }, - - { name: 'tagName', re: /^\s*(\*|[\w\-]+)(\b|$)?/ }, - { name: 'id', re: /^#([\w\-\*]+)(\b|$)/ }, - { name: 'className', re: /^\.([\w\-\*]+)(\b|$)/ }, - { name: 'pseudo', re: /^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|(?=\s|[:+~>]))/ }, - { name: 'attrPresence', re: /^\[((?:[\w-]+:)?[\w-]+)\]/ }, - { name: 'attr', re: /\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\4]*?)\4|([^'"][^\]]*?)))?\]/ } - ], - - assertions: { - tagName: function(element, matches) { - return matches[1].toUpperCase() == element.tagName.toUpperCase(); - }, - - className: function(element, matches) { - return Element.hasClassName(element, matches[1]); - }, - - id: function(element, matches) { - return element.id === matches[1]; - }, - - attrPresence: function(element, matches) { - return Element.hasAttribute(element, matches[1]); - }, - - attr: function(element, matches) { - var nodeValue = Element.readAttribute(element, matches[1]); - return nodeValue && Selector.operators[matches[2]](nodeValue, matches[5] || matches[6]); - } - }, - - handlers: { - concat: function(a, b) { - for (var i = 0, node; node = b[i]; i++) - a.push(node); - return a; - }, - - mark: function(nodes) { - var _true = Prototype.emptyFunction; - for (var i = 0, node; node = nodes[i]; i++) - node._countedByPrototype = _true; - return nodes; - }, - - unmark: (function(){ - - var PROPERTIES_ATTRIBUTES_MAP = (function(){ - var el = document.createElement('div'), - isBuggy = false, - propName = '_countedByPrototype', - value = 'x' - el[propName] = value; - isBuggy = (el.getAttribute(propName) === value); - el = null; - return isBuggy; - })(); - - return PROPERTIES_ATTRIBUTES_MAP ? - function(nodes) { - for (var i = 0, node; node = nodes[i]; i++) - node.removeAttribute('_countedByPrototype'); - return nodes; - } : - function(nodes) { - for (var i = 0, node; node = nodes[i]; i++) - node._countedByPrototype = void 0; - return nodes; - } - })(), - - index: function(parentNode, reverse, ofType) { - parentNode._countedByPrototype = Prototype.emptyFunction; - if (reverse) { - for (var nodes = parentNode.childNodes, i = nodes.length - 1, j = 1; i >= 0; i--) { - var node = nodes[i]; - if (node.nodeType == 1 && (!ofType || node._countedByPrototype)) node.nodeIndex = j++; - } - } else { - for (var i = 0, j = 1, nodes = parentNode.childNodes; node = nodes[i]; i++) - if (node.nodeType == 1 && (!ofType || node._countedByPrototype)) node.nodeIndex = j++; - } - }, - - unique: function(nodes) { - if (nodes.length == 0) return nodes; - var results = [], n; - for (var i = 0, l = nodes.length; i < l; i++) - if (typeof (n = nodes[i])._countedByPrototype == 'undefined') { - n._countedByPrototype = Prototype.emptyFunction; - results.push(Element.extend(n)); - } - return Selector.handlers.unmark(results); - }, - - descendant: function(nodes) { - var h = Selector.handlers; - for (var i = 0, results = [], node; node = nodes[i]; i++) - h.concat(results, node.getElementsByTagName('*')); - return results; - }, - - child: function(nodes) { - var h = Selector.handlers; - for (var i = 0, results = [], node; node = nodes[i]; i++) { - for (var j = 0, child; child = node.childNodes[j]; j++) - if (child.nodeType == 1 && child.tagName != '!') results.push(child); - } - return results; - }, - - adjacent: function(nodes) { - for (var i = 0, results = [], node; node = nodes[i]; i++) { - var next = this.nextElementSibling(node); - if (next) results.push(next); - } - return results; - }, - - laterSibling: function(nodes) { - var h = Selector.handlers; - for (var i = 0, results = [], node; node = nodes[i]; i++) - h.concat(results, Element.nextSiblings(node)); - return results; - }, - - nextElementSibling: function(node) { - while (node = node.nextSibling) - if (node.nodeType == 1) return node; - return null; - }, - - previousElementSibling: function(node) { - while (node = node.previousSibling) - if (node.nodeType == 1) return node; - return null; - }, - - tagName: function(nodes, root, tagName, combinator) { - var uTagName = tagName.toUpperCase(); - var results = [], h = Selector.handlers; - if (nodes) { - if (combinator) { - if (combinator == "descendant") { - for (var i = 0, node; node = nodes[i]; i++) - h.concat(results, node.getElementsByTagName(tagName)); - return results; - } else nodes = this[combinator](nodes); - if (tagName == "*") return nodes; - } - for (var i = 0, node; node = nodes[i]; i++) - if (node.tagName.toUpperCase() === uTagName) results.push(node); - return results; - } else return root.getElementsByTagName(tagName); - }, - - id: function(nodes, root, id, combinator) { - var targetNode = $(id), h = Selector.handlers; - - if (root == document) { - if (!targetNode) return []; - if (!nodes) return [targetNode]; - } else { - if (!root.sourceIndex || root.sourceIndex < 1) { - var nodes = root.getElementsByTagName('*'); - for (var j = 0, node; node = nodes[j]; j++) { - if (node.id === id) return [node]; - } - } - } - - if (nodes) { - if (combinator) { - if (combinator == 'child') { - for (var i = 0, node; node = nodes[i]; i++) - if (targetNode.parentNode == node) return [targetNode]; - } else if (combinator == 'descendant') { - for (var i = 0, node; node = nodes[i]; i++) - if (Element.descendantOf(targetNode, node)) return [targetNode]; - } else if (combinator == 'adjacent') { - for (var i = 0, node; node = nodes[i]; i++) - if (Selector.handlers.previousElementSibling(targetNode) == node) - return [targetNode]; - } else nodes = h[combinator](nodes); - } - for (var i = 0, node; node = nodes[i]; i++) - if (node == targetNode) return [targetNode]; - return []; - } - return (targetNode && Element.descendantOf(targetNode, root)) ? [targetNode] : []; - }, - - className: function(nodes, root, className, combinator) { - if (nodes && combinator) nodes = this[combinator](nodes); - return Selector.handlers.byClassName(nodes, root, className); - }, - - byClassName: function(nodes, root, className) { - if (!nodes) nodes = Selector.handlers.descendant([root]); - var needle = ' ' + className + ' '; - for (var i = 0, results = [], node, nodeClassName; node = nodes[i]; i++) { - nodeClassName = node.className; - if (nodeClassName.length == 0) continue; - if (nodeClassName == className || (' ' + nodeClassName + ' ').include(needle)) - results.push(node); - } - return results; - }, - - attrPresence: function(nodes, root, attr, combinator) { - if (!nodes) nodes = root.getElementsByTagName("*"); - if (nodes && combinator) nodes = this[combinator](nodes); - var results = []; - for (var i = 0, node; node = nodes[i]; i++) - if (Element.hasAttribute(node, attr)) results.push(node); - return results; - }, - - attr: function(nodes, root, attr, value, operator, combinator) { - if (!nodes) nodes = root.getElementsByTagName("*"); - if (nodes && combinator) nodes = this[combinator](nodes); - var handler = Selector.operators[operator], results = []; - for (var i = 0, node; node = nodes[i]; i++) { - var nodeValue = Element.readAttribute(node, attr); - if (nodeValue === null) continue; - if (handler(nodeValue, value)) results.push(node); - } - return results; - }, - - pseudo: function(nodes, name, value, root, combinator) { - if (nodes && combinator) nodes = this[combinator](nodes); - if (!nodes) nodes = root.getElementsByTagName("*"); - return Selector.pseudos[name](nodes, value, root); - } - }, - - pseudos: { - 'first-child': function(nodes, value, root) { - for (var i = 0, results = [], node; node = nodes[i]; i++) { - if (Selector.handlers.previousElementSibling(node)) continue; - results.push(node); - } - return results; - }, - 'last-child': function(nodes, value, root) { - for (var i = 0, results = [], node; node = nodes[i]; i++) { - if (Selector.handlers.nextElementSibling(node)) continue; - results.push(node); - } - return results; - }, - 'only-child': function(nodes, value, root) { - var h = Selector.handlers; - for (var i = 0, results = [], node; node = nodes[i]; i++) - if (!h.previousElementSibling(node) && !h.nextElementSibling(node)) - results.push(node); - return results; - }, - 'nth-child': function(nodes, formula, root) { - return Selector.pseudos.nth(nodes, formula, root); - }, - 'nth-last-child': function(nodes, formula, root) { - return Selector.pseudos.nth(nodes, formula, root, true); - }, - 'nth-of-type': function(nodes, formula, root) { - return Selector.pseudos.nth(nodes, formula, root, false, true); - }, - 'nth-last-of-type': function(nodes, formula, root) { - return Selector.pseudos.nth(nodes, formula, root, true, true); - }, - 'first-of-type': function(nodes, formula, root) { - return Selector.pseudos.nth(nodes, "1", root, false, true); - }, - 'last-of-type': function(nodes, formula, root) { - return Selector.pseudos.nth(nodes, "1", root, true, true); - }, - 'only-of-type': function(nodes, formula, root) { - var p = Selector.pseudos; - return p['last-of-type'](p['first-of-type'](nodes, formula, root), formula, root); - }, - - getIndices: function(a, b, total) { - if (a == 0) return b > 0 ? [b] : []; - return $R(1, total).inject([], function(memo, i) { - if (0 == (i - b) % a && (i - b) / a >= 0) memo.push(i); - return memo; - }); - }, - - nth: function(nodes, formula, root, reverse, ofType) { - if (nodes.length == 0) return []; - if (formula == 'even') formula = '2n+0'; - if (formula == 'odd') formula = '2n+1'; - var h = Selector.handlers, results = [], indexed = [], m; - h.mark(nodes); - for (var i = 0, node; node = nodes[i]; i++) { - if (!node.parentNode._countedByPrototype) { - h.index(node.parentNode, reverse, ofType); - indexed.push(node.parentNode); - } - } - if (formula.match(/^\d+$/)) { // just a number - formula = Number(formula); - for (var i = 0, node; node = nodes[i]; i++) - if (node.nodeIndex == formula) results.push(node); - } else if (m = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b - if (m[1] == "-") m[1] = -1; - var a = m[1] ? Number(m[1]) : 1; - var b = m[2] ? Number(m[2]) : 0; - var indices = Selector.pseudos.getIndices(a, b, nodes.length); - for (var i = 0, node, l = indices.length; node = nodes[i]; i++) { - for (var j = 0; j < l; j++) - if (node.nodeIndex == indices[j]) results.push(node); - } - } - h.unmark(nodes); - h.unmark(indexed); - return results; - }, - - 'empty': function(nodes, value, root) { - for (var i = 0, results = [], node; node = nodes[i]; i++) { - if (node.tagName == '!' || node.firstChild) continue; - results.push(node); - } - return results; - }, - - 'not': function(nodes, selector, root) { - var h = Selector.handlers, selectorType, m; - var exclusions = new Selector(selector).findElements(root); - h.mark(exclusions); - for (var i = 0, results = [], node; node = nodes[i]; i++) - if (!node._countedByPrototype) results.push(node); - h.unmark(exclusions); - return results; - }, - - 'enabled': function(nodes, value, root) { - for (var i = 0, results = [], node; node = nodes[i]; i++) - if (!node.disabled && (!node.type || node.type !== 'hidden')) - results.push(node); - return results; - }, - - 'disabled': function(nodes, value, root) { - for (var i = 0, results = [], node; node = nodes[i]; i++) - if (node.disabled) results.push(node); - return results; - }, - - 'checked': function(nodes, value, root) { - for (var i = 0, results = [], node; node = nodes[i]; i++) - if (node.checked) results.push(node); - return results; - } - }, - - operators: { - '=': function(nv, v) { return nv == v; }, - '!=': function(nv, v) { return nv != v; }, - '^=': function(nv, v) { return nv == v || nv && nv.startsWith(v); }, - '$=': function(nv, v) { return nv == v || nv && nv.endsWith(v); }, - '*=': function(nv, v) { return nv == v || nv && nv.include(v); }, - '~=': function(nv, v) { return (' ' + nv + ' ').include(' ' + v + ' '); }, - '|=': function(nv, v) { return ('-' + (nv || "").toUpperCase() + - '-').include('-' + (v || "").toUpperCase() + '-'); } - }, - - split: function(expression) { - var expressions = []; - expression.scan(/(([\w#:.~>+()\s-]+|\*|\[.*?\])+)\s*(,|$)/, function(m) { - expressions.push(m[1].strip()); - }); - return expressions; - }, - - matchElements: function(elements, expression) { - var matches = $$(expression), h = Selector.handlers; - h.mark(matches); - for (var i = 0, results = [], element; element = elements[i]; i++) - if (element._countedByPrototype) results.push(element); - h.unmark(matches); - return results; - }, - - findElement: function(elements, expression, index) { - if (Object.isNumber(expression)) { - index = expression; expression = false; - } - return Selector.matchElements(elements, expression || '*')[index || 0]; - }, - - findChildElements: function(element, expressions) { - expressions = Selector.split(expressions.join(',')); - var results = [], h = Selector.handlers; - for (var i = 0, l = expressions.length, selector; i < l; i++) { - selector = new Selector(expressions[i].strip()); - h.concat(results, selector.findElements(element)); - } - return (l > 1) ? h.unique(results) : results; - } -}); - -if (Prototype.Browser.IE) { - Object.extend(Selector.handlers, { - concat: function(a, b) { - for (var i = 0, node; node = b[i]; i++) - if (node.tagName !== "!") a.push(node); - return a; - } - }); -} - -function $$() { - return Selector.findChildElements(document, $A(arguments)); -} - -var Form = { - reset: function(form) { - form = $(form); - form.reset(); - return form; - }, - - serializeElements: function(elements, options) { - if (typeof options != 'object') options = { hash: !!options }; - else if (Object.isUndefined(options.hash)) options.hash = true; - var key, value, submitted = false, submit = options.submit; - - var data = elements.inject({ }, function(result, element) { - if (!element.disabled && element.name) { - key = element.name; value = $(element).getValue(); - if (value != null && element.type != 'file' && (element.type != 'submit' || (!submitted && - submit !== false && (!submit || key == submit) && (submitted = true)))) { - if (key in result) { - if (!Object.isArray(result[key])) result[key] = [result[key]]; - result[key].push(value); - } - else result[key] = value; - } - } - return result; - }); - - return options.hash ? data : Object.toQueryString(data); - } -}; - -Form.Methods = { - serialize: function(form, options) { - return Form.serializeElements(Form.getElements(form), options); - }, - - getElements: function(form) { - var elements = $(form).getElementsByTagName('*'), - element, - arr = [ ], - serializers = Form.Element.Serializers; - for (var i = 0; element = elements[i]; i++) { - arr.push(element); - } - return arr.inject([], function(elements, child) { - if (serializers[child.tagName.toLowerCase()]) - elements.push(Element.extend(child)); - return elements; - }) - }, - - getInputs: function(form, typeName, name) { - form = $(form); - var inputs = form.getElementsByTagName('input'); - - if (!typeName && !name) return $A(inputs).map(Element.extend); - - for (var i = 0, matchingInputs = [], length = inputs.length; i < length; i++) { - var input = inputs[i]; - if ((typeName && input.type != typeName) || (name && input.name != name)) - continue; - matchingInputs.push(Element.extend(input)); - } - - return matchingInputs; - }, - - disable: function(form) { - form = $(form); - Form.getElements(form).invoke('disable'); - return form; - }, - - enable: function(form) { - form = $(form); - Form.getElements(form).invoke('enable'); - return form; - }, - - findFirstElement: function(form) { - var elements = $(form).getElements().findAll(function(element) { - return 'hidden' != element.type && !element.disabled; - }); - var firstByIndex = elements.findAll(function(element) { - return element.hasAttribute('tabIndex') && element.tabIndex >= 0; - }).sortBy(function(element) { return element.tabIndex }).first(); - - return firstByIndex ? firstByIndex : elements.find(function(element) { - return /^(?:input|select|textarea)$/i.test(element.tagName); - }); - }, - - focusFirstElement: function(form) { - form = $(form); - form.findFirstElement().activate(); - return form; - }, - - request: function(form, options) { - form = $(form), options = Object.clone(options || { }); - - var params = options.parameters, action = form.readAttribute('action') || ''; - if (action.blank()) action = window.location.href; - options.parameters = form.serialize(true); - - if (params) { - if (Object.isString(params)) params = params.toQueryParams(); - Object.extend(options.parameters, params); - } - - if (form.hasAttribute('method') && !options.method) - options.method = form.method; - - return new Ajax.Request(action, options); - } -}; - -/*--------------------------------------------------------------------------*/ - - -Form.Element = { - focus: function(element) { - $(element).focus(); - return element; - }, - - select: function(element) { - $(element).select(); - return element; - } -}; - -Form.Element.Methods = { - - serialize: function(element) { - element = $(element); - if (!element.disabled && element.name) { - var value = element.getValue(); - if (value != undefined) { - var pair = { }; - pair[element.name] = value; - return Object.toQueryString(pair); - } - } - return ''; - }, - - getValue: function(element) { - element = $(element); - var method = element.tagName.toLowerCase(); - return Form.Element.Serializers[method](element); - }, - - setValue: function(element, value) { - element = $(element); - var method = element.tagName.toLowerCase(); - Form.Element.Serializers[method](element, value); - return element; - }, - - clear: function(element) { - $(element).value = ''; - return element; - }, - - present: function(element) { - return $(element).value != ''; - }, - - activate: function(element) { - element = $(element); - try { - element.focus(); - if (element.select && (element.tagName.toLowerCase() != 'input' || - !(/^(?:button|reset|submit)$/i.test(element.type)))) - element.select(); - } catch (e) { } - return element; - }, - - disable: function(element) { - element = $(element); - element.disabled = true; - return element; - }, - - enable: function(element) { - element = $(element); - element.disabled = false; - return element; - } -}; - -/*--------------------------------------------------------------------------*/ - -var Field = Form.Element; - -var $F = Form.Element.Methods.getValue; - -/*--------------------------------------------------------------------------*/ - -Form.Element.Serializers = { - input: function(element, value) { - switch (element.type.toLowerCase()) { - case 'checkbox': - case 'radio': - return Form.Element.Serializers.inputSelector(element, value); - default: - return Form.Element.Serializers.textarea(element, value); - } - }, - - inputSelector: function(element, value) { - if (Object.isUndefined(value)) return element.checked ? element.value : null; - else element.checked = !!value; - }, - - textarea: function(element, value) { - if (Object.isUndefined(value)) return element.value; - else element.value = value; - }, - - select: function(element, value) { - if (Object.isUndefined(value)) - return this[element.type == 'select-one' ? - 'selectOne' : 'selectMany'](element); - else { - var opt, currentValue, single = !Object.isArray(value); - for (var i = 0, length = element.length; i < length; i++) { - opt = element.options[i]; - currentValue = this.optionValue(opt); - if (single) { - if (currentValue == value) { - opt.selected = true; - return; - } - } - else opt.selected = value.include(currentValue); - } - } - }, - - selectOne: function(element) { - var index = element.selectedIndex; - return index >= 0 ? this.optionValue(element.options[index]) : null; - }, - - selectMany: function(element) { - var values, length = element.length; - if (!length) return null; - - for (var i = 0, values = []; i < length; i++) { - var opt = element.options[i]; - if (opt.selected) values.push(this.optionValue(opt)); - } - return values; - }, - - optionValue: function(opt) { - return Element.extend(opt).hasAttribute('value') ? opt.value : opt.text; - } -}; - -/*--------------------------------------------------------------------------*/ - - -Abstract.TimedObserver = Class.create(PeriodicalExecuter, { - initialize: function($super, element, frequency, callback) { - $super(callback, frequency); - this.element = $(element); - this.lastValue = this.getValue(); - }, - - execute: function() { - var value = this.getValue(); - if (Object.isString(this.lastValue) && Object.isString(value) ? - this.lastValue != value : String(this.lastValue) != String(value)) { - this.callback(this.element, value); - this.lastValue = value; - } - } -}); - -Form.Element.Observer = Class.create(Abstract.TimedObserver, { - getValue: function() { - return Form.Element.getValue(this.element); - } -}); - -Form.Observer = Class.create(Abstract.TimedObserver, { - getValue: function() { - return Form.serialize(this.element); - } -}); - -/*--------------------------------------------------------------------------*/ - -Abstract.EventObserver = Class.create({ - initialize: function(element, callback) { - this.element = $(element); - this.callback = callback; - - this.lastValue = this.getValue(); - if (this.element.tagName.toLowerCase() == 'form') - this.registerFormCallbacks(); - else - this.registerCallback(this.element); - }, - - onElementEvent: function() { - var value = this.getValue(); - if (this.lastValue != value) { - this.callback(this.element, value); - this.lastValue = value; - } - }, - - registerFormCallbacks: function() { - Form.getElements(this.element).each(this.registerCallback, this); - }, - - registerCallback: function(element) { - if (element.type) { - switch (element.type.toLowerCase()) { - case 'checkbox': - case 'radio': - Event.observe(element, 'click', this.onElementEvent.bind(this)); - break; - default: - Event.observe(element, 'change', this.onElementEvent.bind(this)); - break; - } - } - } -}); - -Form.Element.EventObserver = Class.create(Abstract.EventObserver, { - getValue: function() { - return Form.Element.getValue(this.element); - } -}); - -Form.EventObserver = Class.create(Abstract.EventObserver, { - getValue: function() { - return Form.serialize(this.element); - } -}); -(function() { - - var Event = { - KEY_BACKSPACE: 8, - KEY_TAB: 9, - KEY_RETURN: 13, - KEY_ESC: 27, - KEY_LEFT: 37, - KEY_UP: 38, - KEY_RIGHT: 39, - KEY_DOWN: 40, - KEY_DELETE: 46, - KEY_HOME: 36, - KEY_END: 35, - KEY_PAGEUP: 33, - KEY_PAGEDOWN: 34, - KEY_INSERT: 45, - - cache: {} - }; - - var docEl = document.documentElement; - var MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED = 'onmouseenter' in docEl - && 'onmouseleave' in docEl; - - var _isButton; - if (Prototype.Browser.IE) { - var buttonMap = { 0: 1, 1: 4, 2: 2 }; - _isButton = function(event, code) { - return event.button === buttonMap[code]; - }; - } else if (Prototype.Browser.WebKit) { - _isButton = function(event, code) { - switch (code) { - case 0: return event.which == 1 && !event.metaKey; - case 1: return event.which == 1 && event.metaKey; - default: return false; - } - }; - } else { - _isButton = function(event, code) { - return event.which ? (event.which === code + 1) : (event.button === code); - }; - } - - function isLeftClick(event) { return _isButton(event, 0) } - - function isMiddleClick(event) { return _isButton(event, 1) } - - function isRightClick(event) { return _isButton(event, 2) } - - function element(event) { - event = Event.extend(event); - - var node = event.target, type = event.type, - currentTarget = event.currentTarget; - - if (currentTarget && currentTarget.tagName) { - if (type === 'load' || type === 'error' || - (type === 'click' && currentTarget.tagName.toLowerCase() === 'input' - && currentTarget.type === 'radio')) - node = currentTarget; - } - - if (node.nodeType == Node.TEXT_NODE) - node = node.parentNode; - - return Element.extend(node); - } - - function findElement(event, expression) { - var element = Event.element(event); - if (!expression) return element; - var elements = [element].concat(element.ancestors()); - return Selector.findElement(elements, expression, 0); - } - - function pointer(event) { - return { x: pointerX(event), y: pointerY(event) }; - } - - function pointerX(event) { - var docElement = document.documentElement, - body = document.body || { scrollLeft: 0 }; - - return event.pageX || (event.clientX + - (docElement.scrollLeft || body.scrollLeft) - - (docElement.clientLeft || 0)); - } - - function pointerY(event) { - var docElement = document.documentElement, - body = document.body || { scrollTop: 0 }; - - return event.pageY || (event.clientY + - (docElement.scrollTop || body.scrollTop) - - (docElement.clientTop || 0)); - } - - - function stop(event) { - Event.extend(event); - event.preventDefault(); - event.stopPropagation(); - - event.stopped = true; - } - - Event.Methods = { - isLeftClick: isLeftClick, - isMiddleClick: isMiddleClick, - isRightClick: isRightClick, - - element: element, - findElement: findElement, - - pointer: pointer, - pointerX: pointerX, - pointerY: pointerY, - - stop: stop - }; - - - var methods = Object.keys(Event.Methods).inject({ }, function(m, name) { - m[name] = Event.Methods[name].methodize(); - return m; - }); - - if (Prototype.Browser.IE) { - function _relatedTarget(event) { - var element; - switch (event.type) { - case 'mouseover': element = event.fromElement; break; - case 'mouseout': element = event.toElement; break; - default: return null; - } - return Element.extend(element); - } - - Object.extend(methods, { - stopPropagation: function() { this.cancelBubble = true }, - preventDefault: function() { this.returnValue = false }, - inspect: function() { return '[object Event]' } - }); - - Event.extend = function(event, element) { - if (!event) return false; - if (event._extendedByPrototype) return event; - - event._extendedByPrototype = Prototype.emptyFunction; - var pointer = Event.pointer(event); - - Object.extend(event, { - target: event.srcElement || element, - relatedTarget: _relatedTarget(event), - pageX: pointer.x, - pageY: pointer.y - }); - - return Object.extend(event, methods); - }; - } else { - Event.prototype = window.Event.prototype || document.createEvent('HTMLEvents').__proto__; - Object.extend(Event.prototype, methods); - Event.extend = Prototype.K; - } - - function _createResponder(element, eventName, handler) { - var registry = Element.retrieve(element, 'prototype_event_registry'); - - if (Object.isUndefined(registry)) { - CACHE.push(element); - registry = Element.retrieve(element, 'prototype_event_registry', $H()); - } - - var respondersForEvent = registry.get(eventName); - if (Object.isUndefined(respondersForEvent)) { - respondersForEvent = []; - registry.set(eventName, respondersForEvent); - } - - if (respondersForEvent.pluck('handler').include(handler)) return false; - - var responder; - if (eventName.include(":")) { - responder = function(event) { - if (Object.isUndefined(event.eventName)) - return false; - - if (event.eventName !== eventName) - return false; - - Event.extend(event, element); - handler.call(element, event); - }; - } else { - if (!MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED && - (eventName === "mouseenter" || eventName === "mouseleave")) { - if (eventName === "mouseenter" || eventName === "mouseleave") { - responder = function(event) { - Event.extend(event, element); - - var parent = event.relatedTarget; - while (parent && parent !== element) { - try { parent = parent.parentNode; } - catch(e) { parent = element; } - } - - if (parent === element) return; - - handler.call(element, event); - }; - } - } else { - responder = function(event) { - Event.extend(event, element); - handler.call(element, event); - }; - } - } - - responder.handler = handler; - respondersForEvent.push(responder); - return responder; - } - - function _destroyCache() { - for (var i = 0, length = CACHE.length; i < length; i++) { - Event.stopObserving(CACHE[i]); - CACHE[i] = null; - } - } - - var CACHE = []; - - if (Prototype.Browser.IE) - window.attachEvent('onunload', _destroyCache); - - if (Prototype.Browser.WebKit) - window.addEventListener('unload', Prototype.emptyFunction, false); - - - var _getDOMEventName = Prototype.K; - - if (!MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED) { - _getDOMEventName = function(eventName) { - var translations = { mouseenter: "mouseover", mouseleave: "mouseout" }; - return eventName in translations ? translations[eventName] : eventName; - }; - } - - function observe(element, eventName, handler) { - element = $(element); - - var responder = _createResponder(element, eventName, handler); - - if (!responder) return element; - - if (eventName.include(':')) { - if (element.addEventListener) - element.addEventListener("dataavailable", responder, false); - else { - element.attachEvent("ondataavailable", responder); - element.attachEvent("onfilterchange", responder); - } - } else { - var actualEventName = _getDOMEventName(eventName); - - if (element.addEventListener) - element.addEventListener(actualEventName, responder, false); - else - element.attachEvent("on" + actualEventName, responder); - } - - return element; - } - - function stopObserving(element, eventName, handler) { - element = $(element); - - var registry = Element.retrieve(element, 'prototype_event_registry'); - - if (Object.isUndefined(registry)) return element; - - if (eventName && !handler) { - var responders = registry.get(eventName); - - if (Object.isUndefined(responders)) return element; - - responders.each( function(r) { - Element.stopObserving(element, eventName, r.handler); - }); - return element; - } else if (!eventName) { - registry.each( function(pair) { - var eventName = pair.key, responders = pair.value; - - responders.each( function(r) { - Element.stopObserving(element, eventName, r.handler); - }); - }); - return element; - } - - var responders = registry.get(eventName); - - if (!responders) return; - - var responder = responders.find( function(r) { return r.handler === handler; }); - if (!responder) return element; - - var actualEventName = _getDOMEventName(eventName); - - if (eventName.include(':')) { - if (element.removeEventListener) - element.removeEventListener("dataavailable", responder, false); - else { - element.detachEvent("ondataavailable", responder); - element.detachEvent("onfilterchange", responder); - } - } else { - if (element.removeEventListener) - element.removeEventListener(actualEventName, responder, false); - else - element.detachEvent('on' + actualEventName, responder); - } - - registry.set(eventName, responders.without(responder)); - - return element; - } - - function fire(element, eventName, memo, bubble) { - element = $(element); - - if (Object.isUndefined(bubble)) - bubble = true; - - if (element == document && document.createEvent && !element.dispatchEvent) - element = document.documentElement; - - var event; - if (document.createEvent) { - event = document.createEvent('HTMLEvents'); - event.initEvent('dataavailable', true, true); - } else { - event = document.createEventObject(); - event.eventType = bubble ? 'ondataavailable' : 'onfilterchange'; - } - - event.eventName = eventName; - event.memo = memo || { }; - - if (document.createEvent) - element.dispatchEvent(event); - else - element.fireEvent(event.eventType, event); - - return Event.extend(event); - } - - - Object.extend(Event, Event.Methods); - - Object.extend(Event, { - fire: fire, - observe: observe, - stopObserving: stopObserving - }); - - Element.addMethods({ - fire: fire, - - observe: observe, - - stopObserving: stopObserving - }); - - Object.extend(document, { - fire: fire.methodize(), - - observe: observe.methodize(), - - stopObserving: stopObserving.methodize(), - - loaded: false - }); - - if (window.Event) Object.extend(window.Event, Event); - else window.Event = Event; -})(); - -(function() { - /* Support for the DOMContentLoaded event is based on work by Dan Webb, - Matthias Miller, Dean Edwards, John Resig, and Diego Perini. */ - - var timer; - - function fireContentLoadedEvent() { - if (document.loaded) return; - if (timer) window.clearTimeout(timer); - document.loaded = true; - document.fire('dom:loaded'); - } - - function checkReadyState() { - if (document.readyState === 'complete') { - document.stopObserving('readystatechange', checkReadyState); - fireContentLoadedEvent(); - } - } - - function pollDoScroll() { - try { document.documentElement.doScroll('left'); } - catch(e) { - timer = pollDoScroll.defer(); - return; - } - fireContentLoadedEvent(); - } - - if (document.addEventListener) { - document.addEventListener('DOMContentLoaded', fireContentLoadedEvent, false); - } else { - document.observe('readystatechange', checkReadyState); - if (window == top) - timer = pollDoScroll.defer(); - } - - Event.observe(window, 'load', fireContentLoadedEvent); -})(); - -Element.addMethods(); - -/*------------------------------- DEPRECATED -------------------------------*/ - -Hash.toQueryString = Object.toQueryString; - -var Toggle = { display: Element.toggle }; - -Element.Methods.childOf = Element.Methods.descendantOf; - -var Insertion = { - Before: function(element, content) { - return Element.insert(element, {before:content}); - }, - - Top: function(element, content) { - return Element.insert(element, {top:content}); - }, - - Bottom: function(element, content) { - return Element.insert(element, {bottom:content}); - }, - - After: function(element, content) { - return Element.insert(element, {after:content}); - } -}; - -var $continue = new Error('"throw $continue" is deprecated, use "return" instead'); - -var Position = { - includeScrollOffsets: false, - - prepare: function() { - this.deltaX = window.pageXOffset - || document.documentElement.scrollLeft - || document.body.scrollLeft - || 0; - this.deltaY = window.pageYOffset - || document.documentElement.scrollTop - || document.body.scrollTop - || 0; - }, - - within: function(element, x, y) { - if (this.includeScrollOffsets) - return this.withinIncludingScrolloffsets(element, x, y); - this.xcomp = x; - this.ycomp = y; - this.offset = Element.cumulativeOffset(element); - - return (y >= this.offset[1] && - y < this.offset[1] + element.offsetHeight && - x >= this.offset[0] && - x < this.offset[0] + element.offsetWidth); - }, - - withinIncludingScrolloffsets: function(element, x, y) { - var offsetcache = Element.cumulativeScrollOffset(element); - - this.xcomp = x + offsetcache[0] - this.deltaX; - this.ycomp = y + offsetcache[1] - this.deltaY; - this.offset = Element.cumulativeOffset(element); - - return (this.ycomp >= this.offset[1] && - this.ycomp < this.offset[1] + element.offsetHeight && - this.xcomp >= this.offset[0] && - this.xcomp < this.offset[0] + element.offsetWidth); - }, - - overlap: function(mode, element) { - if (!mode) return 0; - if (mode == 'vertical') - return ((this.offset[1] + element.offsetHeight) - this.ycomp) / - element.offsetHeight; - if (mode == 'horizontal') - return ((this.offset[0] + element.offsetWidth) - this.xcomp) / - element.offsetWidth; - }, - - - cumulativeOffset: Element.Methods.cumulativeOffset, - - positionedOffset: Element.Methods.positionedOffset, - - absolutize: function(element) { - Position.prepare(); - return Element.absolutize(element); - }, - - relativize: function(element) { - Position.prepare(); - return Element.relativize(element); - }, - - realOffset: Element.Methods.cumulativeScrollOffset, - - offsetParent: Element.Methods.getOffsetParent, - - page: Element.Methods.viewportOffset, - - clone: function(source, target, options) { - options = options || { }; - return Element.clonePosition(target, source, options); - } -}; - -/*--------------------------------------------------------------------------*/ - -if (!document.getElementsByClassName) document.getElementsByClassName = function(instanceMethods){ - function iter(name) { - return name.blank() ? null : "[contains(concat(' ', @class, ' '), ' " + name + " ')]"; - } - - instanceMethods.getElementsByClassName = Prototype.BrowserFeatures.XPath ? - function(element, className) { - className = className.toString().strip(); - var cond = /\s/.test(className) ? $w(className).map(iter).join('') : iter(className); - return cond ? document._getElementsByXPath('.//*' + cond, element) : []; - } : function(element, className) { - className = className.toString().strip(); - var elements = [], classNames = (/\s/.test(className) ? $w(className) : null); - if (!classNames && !className) return elements; - - var nodes = $(element).getElementsByTagName('*'); - className = ' ' + className + ' '; - - for (var i = 0, child, cn; child = nodes[i]; i++) { - if (child.className && (cn = ' ' + child.className + ' ') && (cn.include(className) || - (classNames && classNames.all(function(name) { - return !name.toString().blank() && cn.include(' ' + name + ' '); - })))) - elements.push(Element.extend(child)); - } - return elements; - }; - - return function(className, parentElement) { - return $(parentElement || document.body).getElementsByClassName(className); - }; -}(Element.Methods); - -/*--------------------------------------------------------------------------*/ - -Element.ClassNames = Class.create(); -Element.ClassNames.prototype = { - initialize: function(element) { - this.element = $(element); - }, - - _each: function(iterator) { - this.element.className.split(/\s+/).select(function(name) { - return name.length > 0; - })._each(iterator); - }, - - set: function(className) { - this.element.className = className; - }, - - add: function(classNameToAdd) { - if (this.include(classNameToAdd)) return; - this.set($A(this).concat(classNameToAdd).join(' ')); - }, - - remove: function(classNameToRemove) { - if (!this.include(classNameToRemove)) return; - this.set($A(this).without(classNameToRemove).join(' ')); - }, - - toString: function() { - return $A(this).join(' '); - } -}; - -Object.extend(Element.ClassNames.prototype, Enumerable); - -/*--------------------------------------------------------------------------*/ \ No newline at end of file diff --git a/src/builder.js b/src/builder.js deleted file mode 100644 index 8c2b08f..0000000 --- a/src/builder.js +++ /dev/null @@ -1,134 +0,0 @@ -// Copyright (c) 2005-2009 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) -// -// script.aculo.us is freely distributable under the terms of an MIT-style license. -// For details, see the script.aculo.us web site: http://script.aculo.us/ - -var Builder = { - NODEMAP: { - AREA: 'map', - CAPTION: 'table', - COL: 'table', - COLGROUP: 'table', - LEGEND: 'fieldset', - OPTGROUP: 'select', - OPTION: 'select', - PARAM: 'object', - TBODY: 'table', - TD: 'table', - TFOOT: 'table', - TH: 'table', - THEAD: 'table', - TR: 'table' - }, - // note: For Firefox < 1.5, OPTION and OPTGROUP tags are currently broken, - // due to a Firefox bug - node: function(elementName) { - elementName = elementName.toUpperCase(); - - // try innerHTML approach - var parentTag = this.NODEMAP[elementName] || 'div'; - var parentElement = document.createElement(parentTag); - try { // prevent IE "feature": http://dev.rubyonrails.org/ticket/2707 - parentElement.innerHTML = "<" + elementName + ">"; - } catch(e) {} - var element = parentElement.firstChild || null; - - // see if browser added wrapping tags - if(element && (element.tagName.toUpperCase() != elementName)) - element = element.getElementsByTagName(elementName)[0]; - - // fallback to createElement approach - if(!element) element = document.createElement(elementName); - - // abort if nothing could be created - if(!element) return; - - // attributes (or text) - if(arguments[1]) - if(this._isStringOrNumber(arguments[1]) || - (arguments[1] instanceof Array) || - arguments[1].tagName) { - this._children(element, arguments[1]); - } else { - var attrs = this._attributes(arguments[1]); - if(attrs.length) { - try { // prevent IE "feature": http://dev.rubyonrails.org/ticket/2707 - parentElement.innerHTML = "<" +elementName + " " + - attrs + ">"; - } catch(e) {} - element = parentElement.firstChild || null; - // workaround firefox 1.0.X bug - if(!element) { - element = document.createElement(elementName); - for(attr in arguments[1]) - element[attr == 'class' ? 'className' : attr] = arguments[1][attr]; - } - if(element.tagName.toUpperCase() != elementName) - element = parentElement.getElementsByTagName(elementName)[0]; - } - } - - // text, or array of children - if(arguments[2]) - this._children(element, arguments[2]); - - return $(element); - }, - _text: function(text) { - return document.createTextNode(text); - }, - - ATTR_MAP: { - 'className': 'class', - 'htmlFor': 'for' - }, - - _attributes: function(attributes) { - var attrs = []; - for(attribute in attributes) - attrs.push((attribute in this.ATTR_MAP ? this.ATTR_MAP[attribute] : attribute) + - '="' + attributes[attribute].toString().escapeHTML().gsub(/"/,'"') + '"'); - return attrs.join(" "); - }, - _children: function(element, children) { - if(children.tagName) { - element.appendChild(children); - return; - } - if(typeof children=='object') { // array can hold nodes and text - children.flatten().each( function(e) { - if(typeof e=='object') - element.appendChild(e); - else - if(Builder._isStringOrNumber(e)) - element.appendChild(Builder._text(e)); - }); - } else - if(Builder._isStringOrNumber(children)) - element.appendChild(Builder._text(children)); - }, - _isStringOrNumber: function(param) { - return(typeof param=='string' || typeof param=='number'); - }, - build: function(html) { - var element = this.node('div'); - $(element).update(html.strip()); - return element.down(); - }, - dump: function(scope) { - if(typeof scope != 'object' && typeof scope != 'function') scope = window; //global scope - - var tags = ("A ABBR ACRONYM ADDRESS APPLET AREA B BASE BASEFONT BDO BIG BLOCKQUOTE BODY " + - "BR BUTTON CAPTION CENTER CITE CODE COL COLGROUP DD DEL DFN DIR DIV DL DT EM FIELDSET " + - "FONT FORM FRAME FRAMESET H1 H2 H3 H4 H5 H6 HEAD HR HTML I IFRAME IMG INPUT INS ISINDEX "+ - "KBD LABEL LEGEND LI LINK MAP MENU META NOFRAMES NOSCRIPT OBJECT OL OPTGROUP OPTION P "+ - "PARAM PRE Q S SAMP SCRIPT SELECT SMALL SPAN STRIKE STRONG STYLE SUB SUP TABLE TBODY TD "+ - "TEXTAREA TFOOT TH THEAD TITLE TR TT U UL VAR").split(/\s+/); - - tags.each( function(tag){ - scope[tag] = function() { - return Builder.node.apply(Builder, [tag].concat($A(arguments))); - }; - }); - } -}; \ No newline at end of file diff --git a/src/controls.js b/src/controls.js deleted file mode 100644 index b09c93b..0000000 --- a/src/controls.js +++ /dev/null @@ -1,963 +0,0 @@ -// Copyright (c) 2005-2009 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) -// (c) 2005-2009 Ivan Krstic (http://blogs.law.harvard.edu/ivan) -// (c) 2005-2009 Jon Tirsen (http://www.tirsen.com) -// Contributors: -// Richard Livsey -// Rahul Bhargava -// Rob Wills -// -// script.aculo.us is freely distributable under the terms of an MIT-style license. -// For details, see the script.aculo.us web site: http://script.aculo.us/ - -// Autocompleter.Base handles all the autocompletion functionality -// that's independent of the data source for autocompletion. This -// includes drawing the autocompletion menu, observing keyboard -// and mouse events, and similar. -// -// Specific autocompleters need to provide, at the very least, -// a getUpdatedChoices function that will be invoked every time -// the text inside the monitored textbox changes. This method -// should get the text for which to provide autocompletion by -// invoking this.getToken(), NOT by directly accessing -// this.element.value. This is to allow incremental tokenized -// autocompletion. Specific auto-completion logic (AJAX, etc) -// belongs in getUpdatedChoices. -// -// Tokenized incremental autocompletion is enabled automatically -// when an autocompleter is instantiated with the 'tokens' option -// in the options parameter, e.g.: -// new Ajax.Autocompleter('id','upd', '/url/', { tokens: ',' }); -// will incrementally autocomplete with a comma as the token. -// Additionally, ',' in the above example can be replaced with -// a token array, e.g. { tokens: [',', '\n'] } which -// enables autocompletion on multiple tokens. This is most -// useful when one of the tokens is \n (a newline), as it -// allows smart autocompletion after linebreaks. - -if(typeof Effect == 'undefined') - throw("controls.js requires including script.aculo.us' effects.js library"); - -var Autocompleter = { }; -Autocompleter.Base = Class.create({ - baseInitialize: function(element, update, options) { - element = $(element); - this.element = element; - this.update = $(update); - this.hasFocus = false; - this.changed = false; - this.active = false; - this.index = 0; - this.entryCount = 0; - this.oldElementValue = this.element.value; - - if(this.setOptions) - this.setOptions(options); - else - this.options = options || { }; - - this.options.paramName = this.options.paramName || this.element.name; - this.options.tokens = this.options.tokens || []; - this.options.frequency = this.options.frequency || 0.4; - this.options.minChars = this.options.minChars || 1; - this.options.onShow = this.options.onShow || - function(element, update){ - if(!update.style.position || update.style.position=='absolute') { - update.style.position = 'absolute'; - Position.clone(element, update, { - setHeight: false, - offsetTop: element.offsetHeight - }); - } - Effect.Appear(update,{duration:0.15}); - }; - this.options.onHide = this.options.onHide || - function(element, update){ new Effect.Fade(update,{duration:0.15}) }; - - if(typeof(this.options.tokens) == 'string') - this.options.tokens = new Array(this.options.tokens); - // Force carriage returns as token delimiters anyway - if (!this.options.tokens.include('\n')) - this.options.tokens.push('\n'); - - this.observer = null; - - this.element.setAttribute('autocomplete','off'); - - Element.hide(this.update); - - Event.observe(this.element, 'blur', this.onBlur.bindAsEventListener(this)); - Event.observe(this.element, 'keydown', this.onKeyPress.bindAsEventListener(this)); - }, - - show: function() { - if(Element.getStyle(this.update, 'display')=='none') this.options.onShow(this.element, this.update); - if(!this.iefix && - (Prototype.Browser.IE) && - (Element.getStyle(this.update, 'position')=='absolute')) { - new Insertion.After(this.update, - ''); - this.iefix = $(this.update.id+'_iefix'); - } - if(this.iefix) setTimeout(this.fixIEOverlapping.bind(this), 50); - }, - - fixIEOverlapping: function() { - Position.clone(this.update, this.iefix, {setTop:(!this.update.style.height)}); - this.iefix.style.zIndex = 1; - this.update.style.zIndex = 2; - Element.show(this.iefix); - }, - - hide: function() { - this.stopIndicator(); - if(Element.getStyle(this.update, 'display')!='none') this.options.onHide(this.element, this.update); - if(this.iefix) Element.hide(this.iefix); - }, - - startIndicator: function() { - if(this.options.indicator) Element.show(this.options.indicator); - }, - - stopIndicator: function() { - if(this.options.indicator) Element.hide(this.options.indicator); - }, - - onKeyPress: function(event) { - if(this.active) - switch(event.keyCode) { - case Event.KEY_TAB: - case Event.KEY_RETURN: - this.selectEntry(); - Event.stop(event); - case Event.KEY_ESC: - this.hide(); - this.active = false; - Event.stop(event); - return; - case Event.KEY_LEFT: - case Event.KEY_RIGHT: - return; - case Event.KEY_UP: - this.markPrevious(); - this.render(); - Event.stop(event); - return; - case Event.KEY_DOWN: - this.markNext(); - this.render(); - Event.stop(event); - return; - } - else - if(event.keyCode==Event.KEY_TAB || event.keyCode==Event.KEY_RETURN || - (Prototype.Browser.WebKit > 0 && event.keyCode == 0)) return; - - this.changed = true; - this.hasFocus = true; - - if(this.observer) clearTimeout(this.observer); - this.observer = - setTimeout(this.onObserverEvent.bind(this), this.options.frequency*1000); - }, - - activate: function() { - this.changed = false; - this.hasFocus = true; - this.getUpdatedChoices(); - }, - - onHover: function(event) { - var element = Event.findElement(event, 'LI'); - if(this.index != element.autocompleteIndex) - { - this.index = element.autocompleteIndex; - this.render(); - } - Event.stop(event); - }, - - onClick: function(event) { - var element = Event.findElement(event, 'LI'); - this.index = element.autocompleteIndex; - this.selectEntry(); - this.hide(); - }, - - onBlur: function(event) { - // needed to make click events working - setTimeout(this.hide.bind(this), 250); - this.hasFocus = false; - this.active = false; - }, - - render: function() { - if(this.entryCount > 0) { - for (var i = 0; i < this.entryCount; i++) - this.index==i ? - Element.addClassName(this.getEntry(i),"selected") : - Element.removeClassName(this.getEntry(i),"selected"); - if(this.hasFocus) { - this.show(); - this.active = true; - } - } else { - this.active = false; - this.hide(); - } - }, - - markPrevious: function() { - if(this.index > 0) this.index--; - else this.index = this.entryCount-1; - this.getEntry(this.index).scrollIntoView(true); - }, - - markNext: function() { - if(this.index < this.entryCount-1) this.index++; - else this.index = 0; - this.getEntry(this.index).scrollIntoView(false); - }, - - getEntry: function(index) { - return this.update.firstChild.childNodes[index]; - }, - - getCurrentEntry: function() { - return this.getEntry(this.index); - }, - - selectEntry: function() { - this.active = false; - this.updateElement(this.getCurrentEntry()); - }, - - updateElement: function(selectedElement) { - if (this.options.updateElement) { - this.options.updateElement(selectedElement); - return; - } - var value = ''; - if (this.options.select) { - var nodes = $(selectedElement).select('.' + this.options.select) || []; - if(nodes.length>0) value = Element.collectTextNodes(nodes[0], this.options.select); - } else - value = Element.collectTextNodesIgnoreClass(selectedElement, 'informal'); - - var bounds = this.getTokenBounds(); - if (bounds[0] != -1) { - var newValue = this.element.value.substr(0, bounds[0]); - var whitespace = this.element.value.substr(bounds[0]).match(/^\s+/); - if (whitespace) - newValue += whitespace[0]; - this.element.value = newValue + value + this.element.value.substr(bounds[1]); - } else { - this.element.value = value; - } - this.oldElementValue = this.element.value; - this.element.focus(); - - if (this.options.afterUpdateElement) - this.options.afterUpdateElement(this.element, selectedElement); - }, - - updateChoices: function(choices) { - if(!this.changed && this.hasFocus) { - this.update.innerHTML = choices; - Element.cleanWhitespace(this.update); - Element.cleanWhitespace(this.update.down()); - - if(this.update.firstChild && this.update.down().childNodes) { - this.entryCount = - this.update.down().childNodes.length; - for (var i = 0; i < this.entryCount; i++) { - var entry = this.getEntry(i); - entry.autocompleteIndex = i; - this.addObservers(entry); - } - } else { - this.entryCount = 0; - } - - this.stopIndicator(); - this.index = 0; - - if(this.entryCount==1 && this.options.autoSelect) { - this.selectEntry(); - this.hide(); - } else { - this.render(); - } - } - }, - - addObservers: function(element) { - Event.observe(element, "mouseover", this.onHover.bindAsEventListener(this)); - Event.observe(element, "click", this.onClick.bindAsEventListener(this)); - }, - - onObserverEvent: function() { - this.changed = false; - this.tokenBounds = null; - if(this.getToken().length>=this.options.minChars) { - this.getUpdatedChoices(); - } else { - this.active = false; - this.hide(); - } - this.oldElementValue = this.element.value; - }, - - getToken: function() { - var bounds = this.getTokenBounds(); - return this.element.value.substring(bounds[0], bounds[1]).strip(); - }, - - getTokenBounds: function() { - if (null != this.tokenBounds) return this.tokenBounds; - var value = this.element.value; - if (value.strip().empty()) return [-1, 0]; - var diff = arguments.callee.getFirstDifferencePos(value, this.oldElementValue); - var offset = (diff == this.oldElementValue.length ? 1 : 0); - var prevTokenPos = -1, nextTokenPos = value.length; - var tp; - for (var index = 0, l = this.options.tokens.length; index < l; ++index) { - tp = value.lastIndexOf(this.options.tokens[index], diff + offset - 1); - if (tp > prevTokenPos) prevTokenPos = tp; - tp = value.indexOf(this.options.tokens[index], diff + offset); - if (-1 != tp && tp < nextTokenPos) nextTokenPos = tp; - } - return (this.tokenBounds = [prevTokenPos + 1, nextTokenPos]); - } -}); - -Autocompleter.Base.prototype.getTokenBounds.getFirstDifferencePos = function(newS, oldS) { - var boundary = Math.min(newS.length, oldS.length); - for (var index = 0; index < boundary; ++index) - if (newS[index] != oldS[index]) - return index; - return boundary; -}; - -Ajax.Autocompleter = Class.create(Autocompleter.Base, { - initialize: function(element, update, url, options) { - this.baseInitialize(element, update, options); - this.options.asynchronous = true; - this.options.onComplete = this.onComplete.bind(this); - this.options.defaultParams = this.options.parameters || null; - this.url = url; - }, - - getUpdatedChoices: function() { - this.startIndicator(); - - var entry = encodeURIComponent(this.options.paramName) + '=' + - encodeURIComponent(this.getToken()); - - this.options.parameters = this.options.callback ? - this.options.callback(this.element, entry) : entry; - - if(this.options.defaultParams) - this.options.parameters += '&' + this.options.defaultParams; - - new Ajax.Request(this.url, this.options); - }, - - onComplete: function(request) { - this.updateChoices(request.responseText); - } -}); - -// The local array autocompleter. Used when you'd prefer to -// inject an array of autocompletion options into the page, rather -// than sending out Ajax queries, which can be quite slow sometimes. -// -// The constructor takes four parameters. The first two are, as usual, -// the id of the monitored textbox, and id of the autocompletion menu. -// The third is the array you want to autocomplete from, and the fourth -// is the options block. -// -// Extra local autocompletion options: -// - choices - How many autocompletion choices to offer -// -// - partialSearch - If false, the autocompleter will match entered -// text only at the beginning of strings in the -// autocomplete array. Defaults to true, which will -// match text at the beginning of any *word* in the -// strings in the autocomplete array. If you want to -// search anywhere in the string, additionally set -// the option fullSearch to true (default: off). -// -// - fullSsearch - Search anywhere in autocomplete array strings. -// -// - partialChars - How many characters to enter before triggering -// a partial match (unlike minChars, which defines -// how many characters are required to do any match -// at all). Defaults to 2. -// -// - ignoreCase - Whether to ignore case when autocompleting. -// Defaults to true. -// -// It's possible to pass in a custom function as the 'selector' -// option, if you prefer to write your own autocompletion logic. -// In that case, the other options above will not apply unless -// you support them. - -Autocompleter.Local = Class.create(Autocompleter.Base, { - initialize: function(element, update, array, options) { - this.baseInitialize(element, update, options); - this.options.array = array; - }, - - getUpdatedChoices: function() { - this.updateChoices(this.options.selector(this)); - }, - - setOptions: function(options) { - this.options = Object.extend({ - choices: 10, - partialSearch: true, - partialChars: 2, - ignoreCase: true, - fullSearch: false, - selector: function(instance) { - var ret = []; // Beginning matches - var partial = []; // Inside matches - var entry = instance.getToken(); - var count = 0; - - for (var i = 0; i < instance.options.array.length && - ret.length < instance.options.choices ; i++) { - - var elem = instance.options.array[i]; - var foundPos = instance.options.ignoreCase ? - elem.toLowerCase().indexOf(entry.toLowerCase()) : - elem.indexOf(entry); - - while (foundPos != -1) { - if (foundPos == 0 && elem.length != entry.length) { - ret.push("
  • " + elem.substr(0, entry.length) + "" + - elem.substr(entry.length) + "
  • "); - break; - } else if (entry.length >= instance.options.partialChars && - instance.options.partialSearch && foundPos != -1) { - if (instance.options.fullSearch || /\s/.test(elem.substr(foundPos-1,1))) { - partial.push("
  • " + elem.substr(0, foundPos) + "" + - elem.substr(foundPos, entry.length) + "" + elem.substr( - foundPos + entry.length) + "
  • "); - break; - } - } - - foundPos = instance.options.ignoreCase ? - elem.toLowerCase().indexOf(entry.toLowerCase(), foundPos + 1) : - elem.indexOf(entry, foundPos + 1); - - } - } - if (partial.length) - ret = ret.concat(partial.slice(0, instance.options.choices - ret.length)); - return "
      " + ret.join('') + "
    "; - } - }, options || { }); - } -}); - -// AJAX in-place editor and collection editor -// Full rewrite by Christophe Porteneuve (April 2007). - -// Use this if you notice weird scrolling problems on some browsers, -// the DOM might be a bit confused when this gets called so do this -// waits 1 ms (with setTimeout) until it does the activation -Field.scrollFreeActivate = function(field) { - setTimeout(function() { - Field.activate(field); - }, 1); -}; - -Ajax.InPlaceEditor = Class.create({ - initialize: function(element, url, options) { - this.url = url; - this.element = element = $(element); - this.prepareOptions(); - this._controls = { }; - arguments.callee.dealWithDeprecatedOptions(options); // DEPRECATION LAYER!!! - Object.extend(this.options, options || { }); - if (!this.options.formId && this.element.id) { - this.options.formId = this.element.id + '-inplaceeditor'; - if ($(this.options.formId)) - this.options.formId = ''; - } - if (this.options.externalControl) - this.options.externalControl = $(this.options.externalControl); - if (!this.options.externalControl) - this.options.externalControlOnly = false; - this._originalBackground = this.element.getStyle('background-color') || 'transparent'; - this.element.title = this.options.clickToEditText; - this._boundCancelHandler = this.handleFormCancellation.bind(this); - this._boundComplete = (this.options.onComplete || Prototype.emptyFunction).bind(this); - this._boundFailureHandler = this.handleAJAXFailure.bind(this); - this._boundSubmitHandler = this.handleFormSubmission.bind(this); - this._boundWrapperHandler = this.wrapUp.bind(this); - this.registerListeners(); - }, - checkForEscapeOrReturn: function(e) { - if (!this._editing || e.ctrlKey || e.altKey || e.shiftKey) return; - if (Event.KEY_ESC == e.keyCode) - this.handleFormCancellation(e); - else if (Event.KEY_RETURN == e.keyCode) - this.handleFormSubmission(e); - }, - createControl: function(mode, handler, extraClasses) { - var control = this.options[mode + 'Control']; - var text = this.options[mode + 'Text']; - if ('button' == control) { - var btn = document.createElement('input'); - btn.type = 'submit'; - btn.value = text; - btn.className = 'editor_' + mode + '_button'; - if ('cancel' == mode) - btn.onclick = this._boundCancelHandler; - this._form.appendChild(btn); - this._controls[mode] = btn; - } else if ('link' == control) { - var link = document.createElement('a'); - link.href = '#'; - link.appendChild(document.createTextNode(text)); - link.onclick = 'cancel' == mode ? this._boundCancelHandler : this._boundSubmitHandler; - link.className = 'editor_' + mode + '_link'; - if (extraClasses) - link.className += ' ' + extraClasses; - this._form.appendChild(link); - this._controls[mode] = link; - } - }, - createEditField: function() { - var text = (this.options.loadTextURL ? this.options.loadingText : this.getText()); - var fld; - if (1 >= this.options.rows && !/\r|\n/.test(this.getText())) { - fld = document.createElement('input'); - fld.type = 'text'; - var size = this.options.size || this.options.cols || 0; - if (0 < size) fld.size = size; - } else { - fld = document.createElement('textarea'); - fld.rows = (1 >= this.options.rows ? this.options.autoRows : this.options.rows); - fld.cols = this.options.cols || 40; - } - fld.name = this.options.paramName; - fld.value = text; // No HTML breaks conversion anymore - fld.className = 'editor_field'; - if (this.options.submitOnBlur) - fld.onblur = this._boundSubmitHandler; - this._controls.editor = fld; - if (this.options.loadTextURL) - this.loadExternalText(); - this._form.appendChild(this._controls.editor); - }, - createForm: function() { - var ipe = this; - function addText(mode, condition) { - var text = ipe.options['text' + mode + 'Controls']; - if (!text || condition === false) return; - ipe._form.appendChild(document.createTextNode(text)); - }; - this._form = $(document.createElement('form')); - this._form.id = this.options.formId; - this._form.addClassName(this.options.formClassName); - this._form.onsubmit = this._boundSubmitHandler; - this.createEditField(); - if ('textarea' == this._controls.editor.tagName.toLowerCase()) - this._form.appendChild(document.createElement('br')); - if (this.options.onFormCustomization) - this.options.onFormCustomization(this, this._form); - addText('Before', this.options.okControl || this.options.cancelControl); - this.createControl('ok', this._boundSubmitHandler); - addText('Between', this.options.okControl && this.options.cancelControl); - this.createControl('cancel', this._boundCancelHandler, 'editor_cancel'); - addText('After', this.options.okControl || this.options.cancelControl); - }, - destroy: function() { - if (this._oldInnerHTML) - this.element.innerHTML = this._oldInnerHTML; - this.leaveEditMode(); - this.unregisterListeners(); - }, - enterEditMode: function(e) { - if (this._saving || this._editing) return; - this._editing = true; - this.triggerCallback('onEnterEditMode'); - if (this.options.externalControl) - this.options.externalControl.hide(); - this.element.hide(); - this.createForm(); - this.element.parentNode.insertBefore(this._form, this.element); - if (!this.options.loadTextURL) - this.postProcessEditField(); - if (e) Event.stop(e); - }, - enterHover: function(e) { - if (this.options.hoverClassName) - this.element.addClassName(this.options.hoverClassName); - if (this._saving) return; - this.triggerCallback('onEnterHover'); - }, - getText: function() { - return this.element.innerHTML.unescapeHTML(); - }, - handleAJAXFailure: function(transport) { - this.triggerCallback('onFailure', transport); - if (this._oldInnerHTML) { - this.element.innerHTML = this._oldInnerHTML; - this._oldInnerHTML = null; - } - }, - handleFormCancellation: function(e) { - this.wrapUp(); - if (e) Event.stop(e); - }, - handleFormSubmission: function(e) { - var form = this._form; - var value = $F(this._controls.editor); - this.prepareSubmission(); - var params = this.options.callback(form, value) || ''; - if (Object.isString(params)) - params = params.toQueryParams(); - params.editorId = this.element.id; - if (this.options.htmlResponse) { - var options = Object.extend({ evalScripts: true }, this.options.ajaxOptions); - Object.extend(options, { - parameters: params, - onComplete: this._boundWrapperHandler, - onFailure: this._boundFailureHandler - }); - new Ajax.Updater({ success: this.element }, this.url, options); - } else { - var options = Object.extend({ method: 'get' }, this.options.ajaxOptions); - Object.extend(options, { - parameters: params, - onComplete: this._boundWrapperHandler, - onFailure: this._boundFailureHandler - }); - new Ajax.Request(this.url, options); - } - if (e) Event.stop(e); - }, - leaveEditMode: function() { - this.element.removeClassName(this.options.savingClassName); - this.removeForm(); - this.leaveHover(); - this.element.style.backgroundColor = this._originalBackground; - this.element.show(); - if (this.options.externalControl) - this.options.externalControl.show(); - this._saving = false; - this._editing = false; - this._oldInnerHTML = null; - this.triggerCallback('onLeaveEditMode'); - }, - leaveHover: function(e) { - if (this.options.hoverClassName) - this.element.removeClassName(this.options.hoverClassName); - if (this._saving) return; - this.triggerCallback('onLeaveHover'); - }, - loadExternalText: function() { - this._form.addClassName(this.options.loadingClassName); - this._controls.editor.disabled = true; - var options = Object.extend({ method: 'get' }, this.options.ajaxOptions); - Object.extend(options, { - parameters: 'editorId=' + encodeURIComponent(this.element.id), - onComplete: Prototype.emptyFunction, - onSuccess: function(transport) { - this._form.removeClassName(this.options.loadingClassName); - var text = transport.responseText; - if (this.options.stripLoadedTextTags) - text = text.stripTags(); - this._controls.editor.value = text; - this._controls.editor.disabled = false; - this.postProcessEditField(); - }.bind(this), - onFailure: this._boundFailureHandler - }); - new Ajax.Request(this.options.loadTextURL, options); - }, - postProcessEditField: function() { - var fpc = this.options.fieldPostCreation; - if (fpc) - $(this._controls.editor)['focus' == fpc ? 'focus' : 'activate'](); - }, - prepareOptions: function() { - this.options = Object.clone(Ajax.InPlaceEditor.DefaultOptions); - Object.extend(this.options, Ajax.InPlaceEditor.DefaultCallbacks); - [this._extraDefaultOptions].flatten().compact().each(function(defs) { - Object.extend(this.options, defs); - }.bind(this)); - }, - prepareSubmission: function() { - this._saving = true; - this.removeForm(); - this.leaveHover(); - this.showSaving(); - }, - registerListeners: function() { - this._listeners = { }; - var listener; - $H(Ajax.InPlaceEditor.Listeners).each(function(pair) { - listener = this[pair.value].bind(this); - this._listeners[pair.key] = listener; - if (!this.options.externalControlOnly) - this.element.observe(pair.key, listener); - if (this.options.externalControl) - this.options.externalControl.observe(pair.key, listener); - }.bind(this)); - }, - removeForm: function() { - if (!this._form) return; - this._form.remove(); - this._form = null; - this._controls = { }; - }, - showSaving: function() { - this._oldInnerHTML = this.element.innerHTML; - this.element.innerHTML = this.options.savingText; - this.element.addClassName(this.options.savingClassName); - this.element.style.backgroundColor = this._originalBackground; - this.element.show(); - }, - triggerCallback: function(cbName, arg) { - if ('function' == typeof this.options[cbName]) { - this.options[cbName](this, arg); - } - }, - unregisterListeners: function() { - $H(this._listeners).each(function(pair) { - if (!this.options.externalControlOnly) - this.element.stopObserving(pair.key, pair.value); - if (this.options.externalControl) - this.options.externalControl.stopObserving(pair.key, pair.value); - }.bind(this)); - }, - wrapUp: function(transport) { - this.leaveEditMode(); - // Can't use triggerCallback due to backward compatibility: requires - // binding + direct element - this._boundComplete(transport, this.element); - } -}); - -Object.extend(Ajax.InPlaceEditor.prototype, { - dispose: Ajax.InPlaceEditor.prototype.destroy -}); - -Ajax.InPlaceCollectionEditor = Class.create(Ajax.InPlaceEditor, { - initialize: function($super, element, url, options) { - this._extraDefaultOptions = Ajax.InPlaceCollectionEditor.DefaultOptions; - $super(element, url, options); - }, - - createEditField: function() { - var list = document.createElement('select'); - list.name = this.options.paramName; - list.size = 1; - this._controls.editor = list; - this._collection = this.options.collection || []; - if (this.options.loadCollectionURL) - this.loadCollection(); - else - this.checkForExternalText(); - this._form.appendChild(this._controls.editor); - }, - - loadCollection: function() { - this._form.addClassName(this.options.loadingClassName); - this.showLoadingText(this.options.loadingCollectionText); - var options = Object.extend({ method: 'get' }, this.options.ajaxOptions); - Object.extend(options, { - parameters: 'editorId=' + encodeURIComponent(this.element.id), - onComplete: Prototype.emptyFunction, - onSuccess: function(transport) { - var js = transport.responseText.strip(); - if (!/^\[.*\]$/.test(js)) // TODO: improve sanity check - throw('Server returned an invalid collection representation.'); - this._collection = eval(js); - this.checkForExternalText(); - }.bind(this), - onFailure: this.onFailure - }); - new Ajax.Request(this.options.loadCollectionURL, options); - }, - - showLoadingText: function(text) { - this._controls.editor.disabled = true; - var tempOption = this._controls.editor.firstChild; - if (!tempOption) { - tempOption = document.createElement('option'); - tempOption.value = ''; - this._controls.editor.appendChild(tempOption); - tempOption.selected = true; - } - tempOption.update((text || '').stripScripts().stripTags()); - }, - - checkForExternalText: function() { - this._text = this.getText(); - if (this.options.loadTextURL) - this.loadExternalText(); - else - this.buildOptionList(); - }, - - loadExternalText: function() { - this.showLoadingText(this.options.loadingText); - var options = Object.extend({ method: 'get' }, this.options.ajaxOptions); - Object.extend(options, { - parameters: 'editorId=' + encodeURIComponent(this.element.id), - onComplete: Prototype.emptyFunction, - onSuccess: function(transport) { - this._text = transport.responseText.strip(); - this.buildOptionList(); - }.bind(this), - onFailure: this.onFailure - }); - new Ajax.Request(this.options.loadTextURL, options); - }, - - buildOptionList: function() { - this._form.removeClassName(this.options.loadingClassName); - this._collection = this._collection.map(function(entry) { - return 2 === entry.length ? entry : [entry, entry].flatten(); - }); - var marker = ('value' in this.options) ? this.options.value : this._text; - var textFound = this._collection.any(function(entry) { - return entry[0] == marker; - }.bind(this)); - this._controls.editor.update(''); - var option; - this._collection.each(function(entry, index) { - option = document.createElement('option'); - option.value = entry[0]; - option.selected = textFound ? entry[0] == marker : 0 == index; - option.appendChild(document.createTextNode(entry[1])); - this._controls.editor.appendChild(option); - }.bind(this)); - this._controls.editor.disabled = false; - Field.scrollFreeActivate(this._controls.editor); - } -}); - -//**** DEPRECATION LAYER FOR InPlace[Collection]Editor! **** -//**** This only exists for a while, in order to let **** -//**** users adapt to the new API. Read up on the new **** -//**** API and convert your code to it ASAP! **** - -Ajax.InPlaceEditor.prototype.initialize.dealWithDeprecatedOptions = function(options) { - if (!options) return; - function fallback(name, expr) { - if (name in options || expr === undefined) return; - options[name] = expr; - }; - fallback('cancelControl', (options.cancelLink ? 'link' : (options.cancelButton ? 'button' : - options.cancelLink == options.cancelButton == false ? false : undefined))); - fallback('okControl', (options.okLink ? 'link' : (options.okButton ? 'button' : - options.okLink == options.okButton == false ? false : undefined))); - fallback('highlightColor', options.highlightcolor); - fallback('highlightEndColor', options.highlightendcolor); -}; - -Object.extend(Ajax.InPlaceEditor, { - DefaultOptions: { - ajaxOptions: { }, - autoRows: 3, // Use when multi-line w/ rows == 1 - cancelControl: 'link', // 'link'|'button'|false - cancelText: 'cancel', - clickToEditText: 'Click to edit', - externalControl: null, // id|elt - externalControlOnly: false, - fieldPostCreation: 'activate', // 'activate'|'focus'|false - formClassName: 'inplaceeditor-form', - formId: null, // id|elt - highlightColor: '#ffff99', - highlightEndColor: '#ffffff', - hoverClassName: '', - htmlResponse: true, - loadingClassName: 'inplaceeditor-loading', - loadingText: 'Loading...', - okControl: 'button', // 'link'|'button'|false - okText: 'ok', - paramName: 'value', - rows: 1, // If 1 and multi-line, uses autoRows - savingClassName: 'inplaceeditor-saving', - savingText: 'Saving...', - size: 0, - stripLoadedTextTags: false, - submitOnBlur: false, - textAfterControls: '', - textBeforeControls: '', - textBetweenControls: '' - }, - DefaultCallbacks: { - callback: function(form) { - return Form.serialize(form); - }, - onComplete: function(transport, element) { - // For backward compatibility, this one is bound to the IPE, and passes - // the element directly. It was too often customized, so we don't break it. - new Effect.Highlight(element, { - startcolor: this.options.highlightColor, keepBackgroundImage: true }); - }, - onEnterEditMode: null, - onEnterHover: function(ipe) { - ipe.element.style.backgroundColor = ipe.options.highlightColor; - if (ipe._effect) - ipe._effect.cancel(); - }, - onFailure: function(transport, ipe) { - alert('Error communication with the server: ' + transport.responseText.stripTags()); - }, - onFormCustomization: null, // Takes the IPE and its generated form, after editor, before controls. - onLeaveEditMode: null, - onLeaveHover: function(ipe) { - ipe._effect = new Effect.Highlight(ipe.element, { - startcolor: ipe.options.highlightColor, endcolor: ipe.options.highlightEndColor, - restorecolor: ipe._originalBackground, keepBackgroundImage: true - }); - } - }, - Listeners: { - click: 'enterEditMode', - keydown: 'checkForEscapeOrReturn', - mouseover: 'enterHover', - mouseout: 'leaveHover' - } -}); - -Ajax.InPlaceCollectionEditor.DefaultOptions = { - loadingCollectionText: 'Loading options...' -}; - -// Delayed observer, like Form.Element.Observer, -// but waits for delay after last key input -// Ideal for live-search fields - -Form.Element.DelayedObserver = Class.create({ - initialize: function(element, delay, callback) { - this.delay = delay || 0.5; - this.element = $(element); - this.callback = callback; - this.timer = null; - this.lastValue = $F(this.element); - Event.observe(this.element,'keyup',this.delayedListener.bindAsEventListener(this)); - }, - delayedListener: function(event) { - if(this.lastValue == $F(this.element)) return; - if(this.timer) clearTimeout(this.timer); - this.timer = setTimeout(this.onTimerEvent.bind(this), this.delay * 1000); - this.lastValue = $F(this.element); - }, - onTimerEvent: function() { - this.timer = null; - this.callback(this.element, $F(this.element)); - } -}); \ No newline at end of file diff --git a/src/dragdrop.js b/src/dragdrop.js deleted file mode 100644 index 4c67373..0000000 --- a/src/dragdrop.js +++ /dev/null @@ -1,972 +0,0 @@ -// Copyright (c) 2005-2009 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) -// -// script.aculo.us is freely distributable under the terms of an MIT-style license. -// For details, see the script.aculo.us web site: http://script.aculo.us/ - -if(Object.isUndefined(Effect)) - throw("dragdrop.js requires including script.aculo.us' effects.js library"); - -var Droppables = { - drops: [], - - remove: function(element) { - this.drops = this.drops.reject(function(d) { return d.element==$(element) }); - }, - - add: function(element) { - element = $(element); - var options = Object.extend({ - greedy: true, - hoverclass: null, - tree: false - }, arguments[1] || { }); - - // cache containers - if(options.containment) { - options._containers = []; - var containment = options.containment; - if(Object.isArray(containment)) { - containment.each( function(c) { options._containers.push($(c)) }); - } else { - options._containers.push($(containment)); - } - } - - if(options.accept) options.accept = [options.accept].flatten(); - - Element.makePositioned(element); // fix IE - options.element = element; - - this.drops.push(options); - }, - - findDeepestChild: function(drops) { - deepest = drops[0]; - - for (i = 1; i < drops.length; ++i) - if (Element.isParent(drops[i].element, deepest.element)) - deepest = drops[i]; - - return deepest; - }, - - isContained: function(element, drop) { - var containmentNode; - if(drop.tree) { - containmentNode = element.treeNode; - } else { - containmentNode = element.parentNode; - } - return drop._containers.detect(function(c) { return containmentNode == c }); - }, - - isAffected: function(point, element, drop) { - return ( - (drop.element!=element) && - ((!drop._containers) || - this.isContained(element, drop)) && - ((!drop.accept) || - (Element.classNames(element).detect( - function(v) { return drop.accept.include(v) } ) )) && - Position.within(drop.element, point[0], point[1]) ); - }, - - deactivate: function(drop) { - if(drop.hoverclass) - Element.removeClassName(drop.element, drop.hoverclass); - this.last_active = null; - }, - - activate: function(drop) { - if(drop.hoverclass) - Element.addClassName(drop.element, drop.hoverclass); - this.last_active = drop; - }, - - show: function(point, element) { - if(!this.drops.length) return; - var drop, affected = []; - - this.drops.each( function(drop) { - if(Droppables.isAffected(point, element, drop)) - affected.push(drop); - }); - - if(affected.length>0) - drop = Droppables.findDeepestChild(affected); - - if(this.last_active && this.last_active != drop) this.deactivate(this.last_active); - if (drop) { - Position.within(drop.element, point[0], point[1]); - if(drop.onHover) - drop.onHover(element, drop.element, Position.overlap(drop.overlap, drop.element)); - - if (drop != this.last_active) Droppables.activate(drop); - } - }, - - fire: function(event, element) { - if(!this.last_active) return; - Position.prepare(); - - if (this.isAffected([Event.pointerX(event), Event.pointerY(event)], element, this.last_active)) - if (this.last_active.onDrop) { - this.last_active.onDrop(element, this.last_active.element, event); - return true; - } - }, - - reset: function() { - if(this.last_active) - this.deactivate(this.last_active); - } -}; - -var Draggables = { - drags: [], - observers: [], - - register: function(draggable) { - if(this.drags.length == 0) { - this.eventMouseUp = this.endDrag.bindAsEventListener(this); - this.eventMouseMove = this.updateDrag.bindAsEventListener(this); - this.eventKeypress = this.keyPress.bindAsEventListener(this); - - Event.observe(document, "mouseup", this.eventMouseUp); - Event.observe(document, "mousemove", this.eventMouseMove); - Event.observe(document, "keypress", this.eventKeypress); - } - this.drags.push(draggable); - }, - - unregister: function(draggable) { - this.drags = this.drags.reject(function(d) { return d==draggable }); - if(this.drags.length == 0) { - Event.stopObserving(document, "mouseup", this.eventMouseUp); - Event.stopObserving(document, "mousemove", this.eventMouseMove); - Event.stopObserving(document, "keypress", this.eventKeypress); - } - }, - - activate: function(draggable) { - if(draggable.options.delay) { - this._timeout = setTimeout(function() { - Draggables._timeout = null; - window.focus(); - Draggables.activeDraggable = draggable; - }.bind(this), draggable.options.delay); - } else { - window.focus(); // allows keypress events if window isn't currently focused, fails for Safari - this.activeDraggable = draggable; - } - }, - - deactivate: function() { - this.activeDraggable = null; - }, - - updateDrag: function(event) { - if(!this.activeDraggable) return; - var pointer = [Event.pointerX(event), Event.pointerY(event)]; - // Mozilla-based browsers fire successive mousemove events with - // the same coordinates, prevent needless redrawing (moz bug?) - if(this._lastPointer && (this._lastPointer.inspect() == pointer.inspect())) return; - this._lastPointer = pointer; - - this.activeDraggable.updateDrag(event, pointer); - }, - - endDrag: function(event) { - if(this._timeout) { - clearTimeout(this._timeout); - this._timeout = null; - } - if(!this.activeDraggable) return; - this._lastPointer = null; - this.activeDraggable.endDrag(event); - this.activeDraggable = null; - }, - - keyPress: function(event) { - if(this.activeDraggable) - this.activeDraggable.keyPress(event); - }, - - addObserver: function(observer) { - this.observers.push(observer); - this._cacheObserverCallbacks(); - }, - - removeObserver: function(element) { // element instead of observer fixes mem leaks - this.observers = this.observers.reject( function(o) { return o.element==element }); - this._cacheObserverCallbacks(); - }, - - notify: function(eventName, draggable, event) { // 'onStart', 'onEnd', 'onDrag' - if(this[eventName+'Count'] > 0) - this.observers.each( function(o) { - if(o[eventName]) o[eventName](eventName, draggable, event); - }); - if(draggable.options[eventName]) draggable.options[eventName](draggable, event); - }, - - _cacheObserverCallbacks: function() { - ['onStart','onEnd','onDrag'].each( function(eventName) { - Draggables[eventName+'Count'] = Draggables.observers.select( - function(o) { return o[eventName]; } - ).length; - }); - } -}; - -/*--------------------------------------------------------------------------*/ - -var Draggable = Class.create({ - initialize: function(element) { - var defaults = { - handle: false, - reverteffect: function(element, top_offset, left_offset) { - var dur = Math.sqrt(Math.abs(top_offset^2)+Math.abs(left_offset^2))*0.02; - new Effect.Move(element, { x: -left_offset, y: -top_offset, duration: dur, - queue: {scope:'_draggable', position:'end'} - }); - }, - endeffect: function(element) { - var toOpacity = Object.isNumber(element._opacity) ? element._opacity : 1.0; - new Effect.Opacity(element, {duration:0.2, from:0.7, to:toOpacity, - queue: {scope:'_draggable', position:'end'}, - afterFinish: function(){ - Draggable._dragging[element] = false - } - }); - }, - zindex: 1000, - revert: false, - quiet: false, - scroll: false, - scrollSensitivity: 20, - scrollSpeed: 15, - snap: false, // false, or xy or [x,y] or function(x,y){ return [x,y] } - delay: 0 - }; - - if(!arguments[1] || Object.isUndefined(arguments[1].endeffect)) - Object.extend(defaults, { - starteffect: function(element) { - element._opacity = Element.getOpacity(element); - Draggable._dragging[element] = true; - new Effect.Opacity(element, {duration:0.2, from:element._opacity, to:0.7}); - } - }); - - var options = Object.extend(defaults, arguments[1] || { }); - - this.element = $(element); - - if(options.handle && Object.isString(options.handle)) - this.handle = this.element.down('.'+options.handle, 0); - - if(!this.handle) this.handle = $(options.handle); - if(!this.handle) this.handle = this.element; - - if(options.scroll && !options.scroll.scrollTo && !options.scroll.outerHTML) { - options.scroll = $(options.scroll); - this._isScrollChild = Element.childOf(this.element, options.scroll); - } - - Element.makePositioned(this.element); // fix IE - - this.options = options; - this.dragging = false; - - this.eventMouseDown = this.initDrag.bindAsEventListener(this); - Event.observe(this.handle, "mousedown", this.eventMouseDown); - - Draggables.register(this); - }, - - destroy: function() { - Event.stopObserving(this.handle, "mousedown", this.eventMouseDown); - Draggables.unregister(this); - }, - - currentDelta: function() { - return([ - parseInt(Element.getStyle(this.element,'left') || '0'), - parseInt(Element.getStyle(this.element,'top') || '0')]); - }, - - initDrag: function(event) { - if(!Object.isUndefined(Draggable._dragging[this.element]) && - Draggable._dragging[this.element]) return; - if(Event.isLeftClick(event)) { - // abort on form elements, fixes a Firefox issue - var src = Event.element(event); - if((tag_name = src.tagName.toUpperCase()) && ( - tag_name=='INPUT' || - tag_name=='SELECT' || - tag_name=='OPTION' || - tag_name=='BUTTON' || - tag_name=='TEXTAREA')) return; - - var pointer = [Event.pointerX(event), Event.pointerY(event)]; - var pos = this.element.cumulativeOffset(); - this.offset = [0,1].map( function(i) { return (pointer[i] - pos[i]) }); - - Draggables.activate(this); - Event.stop(event); - } - }, - - startDrag: function(event) { - this.dragging = true; - if(!this.delta) - this.delta = this.currentDelta(); - - if(this.options.zindex) { - this.originalZ = parseInt(Element.getStyle(this.element,'z-index') || 0); - this.element.style.zIndex = this.options.zindex; - } - - if(this.options.ghosting) { - this._clone = this.element.cloneNode(true); - this._originallyAbsolute = (this.element.getStyle('position') == 'absolute'); - if (!this._originallyAbsolute) - Position.absolutize(this.element); - this.element.parentNode.insertBefore(this._clone, this.element); - } - - if(this.options.scroll) { - if (this.options.scroll == window) { - var where = this._getWindowScroll(this.options.scroll); - this.originalScrollLeft = where.left; - this.originalScrollTop = where.top; - } else { - this.originalScrollLeft = this.options.scroll.scrollLeft; - this.originalScrollTop = this.options.scroll.scrollTop; - } - } - - Draggables.notify('onStart', this, event); - - if(this.options.starteffect) this.options.starteffect(this.element); - }, - - updateDrag: function(event, pointer) { - if(!this.dragging) this.startDrag(event); - - if(!this.options.quiet){ - Position.prepare(); - Droppables.show(pointer, this.element); - } - - Draggables.notify('onDrag', this, event); - - this.draw(pointer); - if(this.options.change) this.options.change(this); - - if(this.options.scroll) { - this.stopScrolling(); - - var p; - if (this.options.scroll == window) { - with(this._getWindowScroll(this.options.scroll)) { p = [ left, top, left+width, top+height ]; } - } else { - p = Position.page(this.options.scroll); - p[0] += this.options.scroll.scrollLeft + Position.deltaX; - p[1] += this.options.scroll.scrollTop + Position.deltaY; - p.push(p[0]+this.options.scroll.offsetWidth); - p.push(p[1]+this.options.scroll.offsetHeight); - } - var speed = [0,0]; - if(pointer[0] < (p[0]+this.options.scrollSensitivity)) speed[0] = pointer[0]-(p[0]+this.options.scrollSensitivity); - if(pointer[1] < (p[1]+this.options.scrollSensitivity)) speed[1] = pointer[1]-(p[1]+this.options.scrollSensitivity); - if(pointer[0] > (p[2]-this.options.scrollSensitivity)) speed[0] = pointer[0]-(p[2]-this.options.scrollSensitivity); - if(pointer[1] > (p[3]-this.options.scrollSensitivity)) speed[1] = pointer[1]-(p[3]-this.options.scrollSensitivity); - this.startScrolling(speed); - } - - // fix AppleWebKit rendering - if(Prototype.Browser.WebKit) window.scrollBy(0,0); - - Event.stop(event); - }, - - finishDrag: function(event, success) { - this.dragging = false; - - if(this.options.quiet){ - Position.prepare(); - var pointer = [Event.pointerX(event), Event.pointerY(event)]; - Droppables.show(pointer, this.element); - } - - if(this.options.ghosting) { - if (!this._originallyAbsolute) - Position.relativize(this.element); - delete this._originallyAbsolute; - Element.remove(this._clone); - this._clone = null; - } - - var dropped = false; - if(success) { - dropped = Droppables.fire(event, this.element); - if (!dropped) dropped = false; - } - if(dropped && this.options.onDropped) this.options.onDropped(this.element); - Draggables.notify('onEnd', this, event); - - var revert = this.options.revert; - if(revert && Object.isFunction(revert)) revert = revert(this.element); - - var d = this.currentDelta(); - if(revert && this.options.reverteffect) { - if (dropped == 0 || revert != 'failure') - this.options.reverteffect(this.element, - d[1]-this.delta[1], d[0]-this.delta[0]); - } else { - this.delta = d; - } - - if(this.options.zindex) - this.element.style.zIndex = this.originalZ; - - if(this.options.endeffect) - this.options.endeffect(this.element); - - Draggables.deactivate(this); - Droppables.reset(); - }, - - keyPress: function(event) { - if(event.keyCode!=Event.KEY_ESC) return; - this.finishDrag(event, false); - Event.stop(event); - }, - - endDrag: function(event) { - if(!this.dragging) return; - this.stopScrolling(); - this.finishDrag(event, true); - Event.stop(event); - }, - - draw: function(point) { - var pos = this.element.cumulativeOffset(); - if(this.options.ghosting) { - var r = Position.realOffset(this.element); - pos[0] += r[0] - Position.deltaX; pos[1] += r[1] - Position.deltaY; - } - - var d = this.currentDelta(); - pos[0] -= d[0]; pos[1] -= d[1]; - - if(this.options.scroll && (this.options.scroll != window && this._isScrollChild)) { - pos[0] -= this.options.scroll.scrollLeft-this.originalScrollLeft; - pos[1] -= this.options.scroll.scrollTop-this.originalScrollTop; - } - - var p = [0,1].map(function(i){ - return (point[i]-pos[i]-this.offset[i]) - }.bind(this)); - - if(this.options.snap) { - if(Object.isFunction(this.options.snap)) { - p = this.options.snap(p[0],p[1],this); - } else { - if(Object.isArray(this.options.snap)) { - p = p.map( function(v, i) { - return (v/this.options.snap[i]).round()*this.options.snap[i] }.bind(this)); - } else { - p = p.map( function(v) { - return (v/this.options.snap).round()*this.options.snap }.bind(this)); - } - }} - - var style = this.element.style; - if((!this.options.constraint) || (this.options.constraint=='horizontal')) - style.left = p[0] + "px"; - if((!this.options.constraint) || (this.options.constraint=='vertical')) - style.top = p[1] + "px"; - - if(style.visibility=="hidden") style.visibility = ""; // fix gecko rendering - }, - - stopScrolling: function() { - if(this.scrollInterval) { - clearInterval(this.scrollInterval); - this.scrollInterval = null; - Draggables._lastScrollPointer = null; - } - }, - - startScrolling: function(speed) { - if(!(speed[0] || speed[1])) return; - this.scrollSpeed = [speed[0]*this.options.scrollSpeed,speed[1]*this.options.scrollSpeed]; - this.lastScrolled = new Date(); - this.scrollInterval = setInterval(this.scroll.bind(this), 10); - }, - - scroll: function() { - var current = new Date(); - var delta = current - this.lastScrolled; - this.lastScrolled = current; - if(this.options.scroll == window) { - with (this._getWindowScroll(this.options.scroll)) { - if (this.scrollSpeed[0] || this.scrollSpeed[1]) { - var d = delta / 1000; - this.options.scroll.scrollTo( left + d*this.scrollSpeed[0], top + d*this.scrollSpeed[1] ); - } - } - } else { - this.options.scroll.scrollLeft += this.scrollSpeed[0] * delta / 1000; - this.options.scroll.scrollTop += this.scrollSpeed[1] * delta / 1000; - } - - Position.prepare(); - Droppables.show(Draggables._lastPointer, this.element); - Draggables.notify('onDrag', this); - if (this._isScrollChild) { - Draggables._lastScrollPointer = Draggables._lastScrollPointer || $A(Draggables._lastPointer); - Draggables._lastScrollPointer[0] += this.scrollSpeed[0] * delta / 1000; - Draggables._lastScrollPointer[1] += this.scrollSpeed[1] * delta / 1000; - if (Draggables._lastScrollPointer[0] < 0) - Draggables._lastScrollPointer[0] = 0; - if (Draggables._lastScrollPointer[1] < 0) - Draggables._lastScrollPointer[1] = 0; - this.draw(Draggables._lastScrollPointer); - } - - if(this.options.change) this.options.change(this); - }, - - _getWindowScroll: function(w) { - var T, L, W, H; - with (w.document) { - if (w.document.documentElement && documentElement.scrollTop) { - T = documentElement.scrollTop; - L = documentElement.scrollLeft; - } else if (w.document.body) { - T = body.scrollTop; - L = body.scrollLeft; - } - if (w.innerWidth) { - W = w.innerWidth; - H = w.innerHeight; - } else if (w.document.documentElement && documentElement.clientWidth) { - W = documentElement.clientWidth; - H = documentElement.clientHeight; - } else { - W = body.offsetWidth; - H = body.offsetHeight; - } - } - return { top: T, left: L, width: W, height: H }; - } -}); - -Draggable._dragging = { }; - -/*--------------------------------------------------------------------------*/ - -var SortableObserver = Class.create({ - initialize: function(element, observer) { - this.element = $(element); - this.observer = observer; - this.lastValue = Sortable.serialize(this.element); - }, - - onStart: function() { - this.lastValue = Sortable.serialize(this.element); - }, - - onEnd: function() { - Sortable.unmark(); - if(this.lastValue != Sortable.serialize(this.element)) - this.observer(this.element) - } -}); - -var Sortable = { - SERIALIZE_RULE: /^[^_\-](?:[A-Za-z0-9\-\_]*)[_](.*)$/, - - sortables: { }, - - _findRootElement: function(element) { - while (element.tagName.toUpperCase() != "BODY") { - if(element.id && Sortable.sortables[element.id]) return element; - element = element.parentNode; - } - }, - - options: function(element) { - element = Sortable._findRootElement($(element)); - if(!element) return; - return Sortable.sortables[element.id]; - }, - - destroy: function(element){ - element = $(element); - var s = Sortable.sortables[element.id]; - - if(s) { - Draggables.removeObserver(s.element); - s.droppables.each(function(d){ Droppables.remove(d) }); - s.draggables.invoke('destroy'); - - delete Sortable.sortables[s.element.id]; - } - }, - - create: function(element) { - element = $(element); - var options = Object.extend({ - element: element, - tag: 'li', // assumes li children, override with tag: 'tagname' - dropOnEmpty: false, - tree: false, - treeTag: 'ul', - overlap: 'vertical', // one of 'vertical', 'horizontal' - constraint: 'vertical', // one of 'vertical', 'horizontal', false - containment: element, // also takes array of elements (or id's); or false - handle: false, // or a CSS class - only: false, - delay: 0, - hoverclass: null, - ghosting: false, - quiet: false, - scroll: false, - scrollSensitivity: 20, - scrollSpeed: 15, - format: this.SERIALIZE_RULE, - - // these take arrays of elements or ids and can be - // used for better initialization performance - elements: false, - handles: false, - - onChange: Prototype.emptyFunction, - onUpdate: Prototype.emptyFunction - }, arguments[1] || { }); - - // clear any old sortable with same element - this.destroy(element); - - // build options for the draggables - var options_for_draggable = { - revert: true, - quiet: options.quiet, - scroll: options.scroll, - scrollSpeed: options.scrollSpeed, - scrollSensitivity: options.scrollSensitivity, - delay: options.delay, - ghosting: options.ghosting, - constraint: options.constraint, - handle: options.handle }; - - if(options.starteffect) - options_for_draggable.starteffect = options.starteffect; - - if(options.reverteffect) - options_for_draggable.reverteffect = options.reverteffect; - else - if(options.ghosting) options_for_draggable.reverteffect = function(element) { - element.style.top = 0; - element.style.left = 0; - }; - - if(options.endeffect) - options_for_draggable.endeffect = options.endeffect; - - if(options.zindex) - options_for_draggable.zindex = options.zindex; - - // build options for the droppables - var options_for_droppable = { - overlap: options.overlap, - containment: options.containment, - tree: options.tree, - hoverclass: options.hoverclass, - onHover: Sortable.onHover - }; - - var options_for_tree = { - onHover: Sortable.onEmptyHover, - overlap: options.overlap, - containment: options.containment, - hoverclass: options.hoverclass - }; - - // fix for gecko engine - Element.cleanWhitespace(element); - - options.draggables = []; - options.droppables = []; - - // drop on empty handling - if(options.dropOnEmpty || options.tree) { - Droppables.add(element, options_for_tree); - options.droppables.push(element); - } - - (options.elements || this.findElements(element, options) || []).each( function(e,i) { - var handle = options.handles ? $(options.handles[i]) : - (options.handle ? $(e).select('.' + options.handle)[0] : e); - options.draggables.push( - new Draggable(e, Object.extend(options_for_draggable, { handle: handle }))); - Droppables.add(e, options_for_droppable); - if(options.tree) e.treeNode = element; - options.droppables.push(e); - }); - - if(options.tree) { - (Sortable.findTreeElements(element, options) || []).each( function(e) { - Droppables.add(e, options_for_tree); - e.treeNode = element; - options.droppables.push(e); - }); - } - - // keep reference - this.sortables[element.identify()] = options; - - // for onupdate - Draggables.addObserver(new SortableObserver(element, options.onUpdate)); - - }, - - // return all suitable-for-sortable elements in a guaranteed order - findElements: function(element, options) { - return Element.findChildren( - element, options.only, options.tree ? true : false, options.tag); - }, - - findTreeElements: function(element, options) { - return Element.findChildren( - element, options.only, options.tree ? true : false, options.treeTag); - }, - - onHover: function(element, dropon, overlap) { - if(Element.isParent(dropon, element)) return; - - if(overlap > .33 && overlap < .66 && Sortable.options(dropon).tree) { - return; - } else if(overlap>0.5) { - Sortable.mark(dropon, 'before'); - if(dropon.previousSibling != element) { - var oldParentNode = element.parentNode; - element.style.visibility = "hidden"; // fix gecko rendering - dropon.parentNode.insertBefore(element, dropon); - if(dropon.parentNode!=oldParentNode) - Sortable.options(oldParentNode).onChange(element); - Sortable.options(dropon.parentNode).onChange(element); - } - } else { - Sortable.mark(dropon, 'after'); - var nextElement = dropon.nextSibling || null; - if(nextElement != element) { - var oldParentNode = element.parentNode; - element.style.visibility = "hidden"; // fix gecko rendering - dropon.parentNode.insertBefore(element, nextElement); - if(dropon.parentNode!=oldParentNode) - Sortable.options(oldParentNode).onChange(element); - Sortable.options(dropon.parentNode).onChange(element); - } - } - }, - - onEmptyHover: function(element, dropon, overlap) { - var oldParentNode = element.parentNode; - var droponOptions = Sortable.options(dropon); - - if(!Element.isParent(dropon, element)) { - var index; - - var children = Sortable.findElements(dropon, {tag: droponOptions.tag, only: droponOptions.only}); - var child = null; - - if(children) { - var offset = Element.offsetSize(dropon, droponOptions.overlap) * (1.0 - overlap); - - for (index = 0; index < children.length; index += 1) { - if (offset - Element.offsetSize (children[index], droponOptions.overlap) >= 0) { - offset -= Element.offsetSize (children[index], droponOptions.overlap); - } else if (offset - (Element.offsetSize (children[index], droponOptions.overlap) / 2) >= 0) { - child = index + 1 < children.length ? children[index + 1] : null; - break; - } else { - child = children[index]; - break; - } - } - } - - dropon.insertBefore(element, child); - - Sortable.options(oldParentNode).onChange(element); - droponOptions.onChange(element); - } - }, - - unmark: function() { - if(Sortable._marker) Sortable._marker.hide(); - }, - - mark: function(dropon, position) { - // mark on ghosting only - var sortable = Sortable.options(dropon.parentNode); - if(sortable && !sortable.ghosting) return; - - if(!Sortable._marker) { - Sortable._marker = - ($('dropmarker') || Element.extend(document.createElement('DIV'))). - hide().addClassName('dropmarker').setStyle({position:'absolute'}); - document.getElementsByTagName("body").item(0).appendChild(Sortable._marker); - } - var offsets = dropon.cumulativeOffset(); - Sortable._marker.setStyle({left: offsets[0]+'px', top: offsets[1] + 'px'}); - - if(position=='after') - if(sortable.overlap == 'horizontal') - Sortable._marker.setStyle({left: (offsets[0]+dropon.clientWidth) + 'px'}); - else - Sortable._marker.setStyle({top: (offsets[1]+dropon.clientHeight) + 'px'}); - - Sortable._marker.show(); - }, - - _tree: function(element, options, parent) { - var children = Sortable.findElements(element, options) || []; - - for (var i = 0; i < children.length; ++i) { - var match = children[i].id.match(options.format); - - if (!match) continue; - - var child = { - id: encodeURIComponent(match ? match[1] : null), - element: element, - parent: parent, - children: [], - position: parent.children.length, - container: $(children[i]).down(options.treeTag) - }; - - /* Get the element containing the children and recurse over it */ - if (child.container) - this._tree(child.container, options, child); - - parent.children.push (child); - } - - return parent; - }, - - tree: function(element) { - element = $(element); - var sortableOptions = this.options(element); - var options = Object.extend({ - tag: sortableOptions.tag, - treeTag: sortableOptions.treeTag, - only: sortableOptions.only, - name: element.id, - format: sortableOptions.format - }, arguments[1] || { }); - - var root = { - id: null, - parent: null, - children: [], - container: element, - position: 0 - }; - - return Sortable._tree(element, options, root); - }, - - /* Construct a [i] index for a particular node */ - _constructIndex: function(node) { - var index = ''; - do { - if (node.id) index = '[' + node.position + ']' + index; - } while ((node = node.parent) != null); - return index; - }, - - sequence: function(element) { - element = $(element); - var options = Object.extend(this.options(element), arguments[1] || { }); - - return $(this.findElements(element, options) || []).map( function(item) { - return item.id.match(options.format) ? item.id.match(options.format)[1] : ''; - }); - }, - - setSequence: function(element, new_sequence) { - element = $(element); - var options = Object.extend(this.options(element), arguments[2] || { }); - - var nodeMap = { }; - this.findElements(element, options).each( function(n) { - if (n.id.match(options.format)) - nodeMap[n.id.match(options.format)[1]] = [n, n.parentNode]; - n.parentNode.removeChild(n); - }); - - new_sequence.each(function(ident) { - var n = nodeMap[ident]; - if (n) { - n[1].appendChild(n[0]); - delete nodeMap[ident]; - } - }); - }, - - serialize: function(element) { - element = $(element); - var options = Object.extend(Sortable.options(element), arguments[1] || { }); - var name = encodeURIComponent( - (arguments[1] && arguments[1].name) ? arguments[1].name : element.id); - - if (options.tree) { - return Sortable.tree(element, arguments[1]).children.map( function (item) { - return [name + Sortable._constructIndex(item) + "[id]=" + - encodeURIComponent(item.id)].concat(item.children.map(arguments.callee)); - }).flatten().join('&'); - } else { - return Sortable.sequence(element, arguments[1]).map( function(item) { - return name + "[]=" + encodeURIComponent(item); - }).join('&'); - } - } -}; - -// Returns true if child is contained within element -Element.isParent = function(child, element) { - if (!child.parentNode || child == element) return false; - if (child.parentNode == element) return true; - return Element.isParent(child.parentNode, element); -}; - -Element.findChildren = function(element, only, recursive, tagName) { - if(!element.hasChildNodes()) return null; - tagName = tagName.toUpperCase(); - if(only) only = [only].flatten(); - var elements = []; - $A(element.childNodes).each( function(e) { - if(e.tagName && e.tagName.toUpperCase()==tagName && - (!only || (Element.classNames(e).detect(function(v) { return only.include(v) })))) - elements.push(e); - if(recursive) { - var grandchildren = Element.findChildren(e, only, recursive, tagName); - if(grandchildren) elements.push(grandchildren); - } - }); - - return (elements.length>0 ? elements.flatten() : []); -}; - -Element.offsetSize = function (element, type) { - return element['offset' + ((type=='vertical' || type=='height') ? 'Height' : 'Width')]; -}; \ No newline at end of file diff --git a/src/effects.js b/src/effects.js deleted file mode 100644 index 93a6483..0000000 --- a/src/effects.js +++ /dev/null @@ -1,1121 +0,0 @@ -// Copyright (c) 2005-2009 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) -// Contributors: -// Justin Palmer (http://encytemedia.com/) -// Mark Pilgrim (http://diveintomark.org/) -// Martin Bialasinki -// -// script.aculo.us is freely distributable under the terms of an MIT-style license. -// For details, see the script.aculo.us web site: http://script.aculo.us/ - -// converts rgb() and #xxx to #xxxxxx format, -// returns self (or first argument) if not convertable -String.prototype.parseColor = function() { - var color = '#'; - if (this.slice(0,4) == 'rgb(') { - var cols = this.slice(4,this.length-1).split(','); - var i=0; do { color += parseInt(cols[i]).toColorPart() } while (++i<3); - } else { - if (this.slice(0,1) == '#') { - if (this.length==4) for(var i=1;i<4;i++) color += (this.charAt(i) + this.charAt(i)).toLowerCase(); - if (this.length==7) color = this.toLowerCase(); - } - } - return (color.length==7 ? color : (arguments[0] || this)); -}; - -/*--------------------------------------------------------------------------*/ - -Element.collectTextNodes = function(element) { - return $A($(element).childNodes).collect( function(node) { - return (node.nodeType==3 ? node.nodeValue : - (node.hasChildNodes() ? Element.collectTextNodes(node) : '')); - }).flatten().join(''); -}; - -Element.collectTextNodesIgnoreClass = function(element, className) { - return $A($(element).childNodes).collect( function(node) { - return (node.nodeType==3 ? node.nodeValue : - ((node.hasChildNodes() && !Element.hasClassName(node,className)) ? - Element.collectTextNodesIgnoreClass(node, className) : '')); - }).flatten().join(''); -}; - -Element.setContentZoom = function(element, percent) { - element = $(element); - element.setStyle({fontSize: (percent/100) + 'em'}); - if (Prototype.Browser.WebKit) window.scrollBy(0,0); - return element; -}; - -Element.getInlineOpacity = function(element){ - return $(element).style.opacity || ''; -}; - -Element.forceRerendering = function(element) { - try { - element = $(element); - var n = document.createTextNode(' '); - element.appendChild(n); - element.removeChild(n); - } catch(e) { } -}; - -/*--------------------------------------------------------------------------*/ - -var Effect = { - _elementDoesNotExistError: { - name: 'ElementDoesNotExistError', - message: 'The specified DOM element does not exist, but is required for this effect to operate' - }, - Transitions: { - linear: Prototype.K, - sinoidal: function(pos) { - return (-Math.cos(pos*Math.PI)/2) + .5; - }, - reverse: function(pos) { - return 1-pos; - }, - flicker: function(pos) { - var pos = ((-Math.cos(pos*Math.PI)/4) + .75) + Math.random()/4; - return pos > 1 ? 1 : pos; - }, - wobble: function(pos) { - return (-Math.cos(pos*Math.PI*(9*pos))/2) + .5; - }, - pulse: function(pos, pulses) { - return (-Math.cos((pos*((pulses||5)-.5)*2)*Math.PI)/2) + .5; - }, - spring: function(pos) { - return 1 - (Math.cos(pos * 4.5 * Math.PI) * Math.exp(-pos * 6)); - }, - none: function(pos) { - return 0; - }, - full: function(pos) { - return 1; - } - }, - DefaultOptions: { - duration: 1.0, // seconds - fps: 100, // 100= assume 66fps max. - sync: false, // true for combining - from: 0.0, - to: 1.0, - delay: 0.0, - queue: 'parallel' - }, - tagifyText: function(element) { - var tagifyStyle = 'position:relative'; - if (Prototype.Browser.IE) tagifyStyle += ';zoom:1'; - - element = $(element); - $A(element.childNodes).each( function(child) { - if (child.nodeType==3) { - child.nodeValue.toArray().each( function(character) { - element.insertBefore( - new Element('span', {style: tagifyStyle}).update( - character == ' ' ? String.fromCharCode(160) : character), - child); - }); - Element.remove(child); - } - }); - }, - multiple: function(element, effect) { - var elements; - if (((typeof element == 'object') || - Object.isFunction(element)) && - (element.length)) - elements = element; - else - elements = $(element).childNodes; - - var options = Object.extend({ - speed: 0.1, - delay: 0.0 - }, arguments[2] || { }); - var masterDelay = options.delay; - - $A(elements).each( function(element, index) { - new effect(element, Object.extend(options, { delay: index * options.speed + masterDelay })); - }); - }, - PAIRS: { - 'slide': ['SlideDown','SlideUp'], - 'blind': ['BlindDown','BlindUp'], - 'appear': ['Appear','Fade'] - }, - toggle: function(element, effect, options) { - element = $(element); - effect = (effect || 'appear').toLowerCase(); - - return Effect[ Effect.PAIRS[ effect ][ element.visible() ? 1 : 0 ] ](element, Object.extend({ - queue: { position:'end', scope:(element.id || 'global'), limit: 1 } - }, options || {})); - } -}; - -Effect.DefaultOptions.transition = Effect.Transitions.sinoidal; - -/* ------------- core effects ------------- */ - -Effect.ScopedQueue = Class.create(Enumerable, { - initialize: function() { - this.effects = []; - this.interval = null; - }, - _each: function(iterator) { - this.effects._each(iterator); - }, - add: function(effect) { - var timestamp = new Date().getTime(); - - var position = Object.isString(effect.options.queue) ? - effect.options.queue : effect.options.queue.position; - - switch(position) { - case 'front': - // move unstarted effects after this effect - this.effects.findAll(function(e){ return e.state=='idle' }).each( function(e) { - e.startOn += effect.finishOn; - e.finishOn += effect.finishOn; - }); - break; - case 'with-last': - timestamp = this.effects.pluck('startOn').max() || timestamp; - break; - case 'end': - // start effect after last queued effect has finished - timestamp = this.effects.pluck('finishOn').max() || timestamp; - break; - } - - effect.startOn += timestamp; - effect.finishOn += timestamp; - - if (!effect.options.queue.limit || (this.effects.length < effect.options.queue.limit)) - this.effects.push(effect); - - if (!this.interval) - this.interval = setInterval(this.loop.bind(this), 15); - }, - remove: function(effect) { - this.effects = this.effects.reject(function(e) { return e==effect }); - if (this.effects.length == 0) { - clearInterval(this.interval); - this.interval = null; - } - }, - loop: function() { - var timePos = new Date().getTime(); - for(var i=0, len=this.effects.length;i= this.startOn) { - if (timePos >= this.finishOn) { - this.render(1.0); - this.cancel(); - this.event('beforeFinish'); - if (this.finish) this.finish(); - this.event('afterFinish'); - return; - } - var pos = (timePos - this.startOn) / this.totalTime, - frame = (pos * this.totalFrames).round(); - if (frame > this.currentFrame) { - this.render(pos); - this.currentFrame = frame; - } - } - }, - cancel: function() { - if (!this.options.sync) - Effect.Queues.get(Object.isString(this.options.queue) ? - 'global' : this.options.queue.scope).remove(this); - this.state = 'finished'; - }, - event: function(eventName) { - if (this.options[eventName + 'Internal']) this.options[eventName + 'Internal'](this); - if (this.options[eventName]) this.options[eventName](this); - }, - inspect: function() { - var data = $H(); - for(property in this) - if (!Object.isFunction(this[property])) data.set(property, this[property]); - return '#'; - } -}); - -Effect.Parallel = Class.create(Effect.Base, { - initialize: function(effects) { - this.effects = effects || []; - this.start(arguments[1]); - }, - update: function(position) { - this.effects.invoke('render', position); - }, - finish: function(position) { - this.effects.each( function(effect) { - effect.render(1.0); - effect.cancel(); - effect.event('beforeFinish'); - if (effect.finish) effect.finish(position); - effect.event('afterFinish'); - }); - } -}); - -Effect.Tween = Class.create(Effect.Base, { - initialize: function(object, from, to) { - object = Object.isString(object) ? $(object) : object; - var args = $A(arguments), method = args.last(), - options = args.length == 5 ? args[3] : null; - this.method = Object.isFunction(method) ? method.bind(object) : - Object.isFunction(object[method]) ? object[method].bind(object) : - function(value) { object[method] = value }; - this.start(Object.extend({ from: from, to: to }, options || { })); - }, - update: function(position) { - this.method(position); - } -}); - -Effect.Event = Class.create(Effect.Base, { - initialize: function() { - this.start(Object.extend({ duration: 0 }, arguments[0] || { })); - }, - update: Prototype.emptyFunction -}); - -Effect.Opacity = Class.create(Effect.Base, { - initialize: function(element) { - this.element = $(element); - if (!this.element) throw(Effect._elementDoesNotExistError); - // make this work on IE on elements without 'layout' - if (Prototype.Browser.IE && (!this.element.currentStyle.hasLayout)) - this.element.setStyle({zoom: 1}); - var options = Object.extend({ - from: this.element.getOpacity() || 0.0, - to: 1.0 - }, arguments[1] || { }); - this.start(options); - }, - update: function(position) { - this.element.setOpacity(position); - } -}); - -Effect.Move = Class.create(Effect.Base, { - initialize: function(element) { - this.element = $(element); - if (!this.element) throw(Effect._elementDoesNotExistError); - var options = Object.extend({ - x: 0, - y: 0, - mode: 'relative' - }, arguments[1] || { }); - this.start(options); - }, - setup: function() { - this.element.makePositioned(); - this.originalLeft = parseFloat(this.element.getStyle('left') || '0'); - this.originalTop = parseFloat(this.element.getStyle('top') || '0'); - if (this.options.mode == 'absolute') { - this.options.x = this.options.x - this.originalLeft; - this.options.y = this.options.y - this.originalTop; - } - }, - update: function(position) { - this.element.setStyle({ - left: (this.options.x * position + this.originalLeft).round() + 'px', - top: (this.options.y * position + this.originalTop).round() + 'px' - }); - } -}); - -// for backwards compatibility -Effect.MoveBy = function(element, toTop, toLeft) { - return new Effect.Move(element, - Object.extend({ x: toLeft, y: toTop }, arguments[3] || { })); -}; - -Effect.Scale = Class.create(Effect.Base, { - initialize: function(element, percent) { - this.element = $(element); - if (!this.element) throw(Effect._elementDoesNotExistError); - var options = Object.extend({ - scaleX: true, - scaleY: true, - scaleContent: true, - scaleFromCenter: false, - scaleMode: 'box', // 'box' or 'contents' or { } with provided values - scaleFrom: 100.0, - scaleTo: percent - }, arguments[2] || { }); - this.start(options); - }, - setup: function() { - this.restoreAfterFinish = this.options.restoreAfterFinish || false; - this.elementPositioning = this.element.getStyle('position'); - - this.originalStyle = { }; - ['top','left','width','height','fontSize'].each( function(k) { - this.originalStyle[k] = this.element.style[k]; - }.bind(this)); - - this.originalTop = this.element.offsetTop; - this.originalLeft = this.element.offsetLeft; - - var fontSize = this.element.getStyle('font-size') || '100%'; - ['em','px','%','pt'].each( function(fontSizeType) { - if (fontSize.indexOf(fontSizeType)>0) { - this.fontSize = parseFloat(fontSize); - this.fontSizeType = fontSizeType; - } - }.bind(this)); - - this.factor = (this.options.scaleTo - this.options.scaleFrom)/100; - - this.dims = null; - if (this.options.scaleMode=='box') - this.dims = [this.element.offsetHeight, this.element.offsetWidth]; - if (/^content/.test(this.options.scaleMode)) - this.dims = [this.element.scrollHeight, this.element.scrollWidth]; - if (!this.dims) - this.dims = [this.options.scaleMode.originalHeight, - this.options.scaleMode.originalWidth]; - }, - update: function(position) { - var currentScale = (this.options.scaleFrom/100.0) + (this.factor * position); - if (this.options.scaleContent && this.fontSize) - this.element.setStyle({fontSize: this.fontSize * currentScale + this.fontSizeType }); - this.setDimensions(this.dims[0] * currentScale, this.dims[1] * currentScale); - }, - finish: function(position) { - if (this.restoreAfterFinish) this.element.setStyle(this.originalStyle); - }, - setDimensions: function(height, width) { - var d = { }; - if (this.options.scaleX) d.width = width.round() + 'px'; - if (this.options.scaleY) d.height = height.round() + 'px'; - if (this.options.scaleFromCenter) { - var topd = (height - this.dims[0])/2; - var leftd = (width - this.dims[1])/2; - if (this.elementPositioning == 'absolute') { - if (this.options.scaleY) d.top = this.originalTop-topd + 'px'; - if (this.options.scaleX) d.left = this.originalLeft-leftd + 'px'; - } else { - if (this.options.scaleY) d.top = -topd + 'px'; - if (this.options.scaleX) d.left = -leftd + 'px'; - } - } - this.element.setStyle(d); - } -}); - -Effect.Highlight = Class.create(Effect.Base, { - initialize: function(element) { - this.element = $(element); - if (!this.element) throw(Effect._elementDoesNotExistError); - var options = Object.extend({ startcolor: '#ffff99' }, arguments[1] || { }); - this.start(options); - }, - setup: function() { - // Prevent executing on elements not in the layout flow - if (this.element.getStyle('display')=='none') { this.cancel(); return; } - // Disable background image during the effect - this.oldStyle = { }; - if (!this.options.keepBackgroundImage) { - this.oldStyle.backgroundImage = this.element.getStyle('background-image'); - this.element.setStyle({backgroundImage: 'none'}); - } - if (!this.options.endcolor) - this.options.endcolor = this.element.getStyle('background-color').parseColor('#ffffff'); - if (!this.options.restorecolor) - this.options.restorecolor = this.element.getStyle('background-color'); - // init color calculations - this._base = $R(0,2).map(function(i){ return parseInt(this.options.startcolor.slice(i*2+1,i*2+3),16) }.bind(this)); - this._delta = $R(0,2).map(function(i){ return parseInt(this.options.endcolor.slice(i*2+1,i*2+3),16)-this._base[i] }.bind(this)); - }, - update: function(position) { - this.element.setStyle({backgroundColor: $R(0,2).inject('#',function(m,v,i){ - return m+((this._base[i]+(this._delta[i]*position)).round().toColorPart()); }.bind(this)) }); - }, - finish: function() { - this.element.setStyle(Object.extend(this.oldStyle, { - backgroundColor: this.options.restorecolor - })); - } -}); - -Effect.ScrollTo = function(element) { - var options = arguments[1] || { }, - scrollOffsets = document.viewport.getScrollOffsets(), - elementOffsets = $(element).cumulativeOffset(); - - if (options.offset) elementOffsets[1] += options.offset; - - return new Effect.Tween(null, - scrollOffsets.top, - elementOffsets[1], - options, - function(p){ scrollTo(scrollOffsets.left, p.round()); } - ); -}; - -/* ------------- combination effects ------------- */ - -Effect.Fade = function(element) { - element = $(element); - var oldOpacity = element.getInlineOpacity(); - var options = Object.extend({ - from: element.getOpacity() || 1.0, - to: 0.0, - afterFinishInternal: function(effect) { - if (effect.options.to!=0) return; - effect.element.hide().setStyle({opacity: oldOpacity}); - } - }, arguments[1] || { }); - return new Effect.Opacity(element,options); -}; - -Effect.Appear = function(element) { - element = $(element); - var options = Object.extend({ - from: (element.getStyle('display') == 'none' ? 0.0 : element.getOpacity() || 0.0), - to: 1.0, - // force Safari to render floated elements properly - afterFinishInternal: function(effect) { - effect.element.forceRerendering(); - }, - beforeSetup: function(effect) { - effect.element.setOpacity(effect.options.from).show(); - }}, arguments[1] || { }); - return new Effect.Opacity(element,options); -}; - -Effect.Puff = function(element) { - element = $(element); - var oldStyle = { - opacity: element.getInlineOpacity(), - position: element.getStyle('position'), - top: element.style.top, - left: element.style.left, - width: element.style.width, - height: element.style.height - }; - return new Effect.Parallel( - [ new Effect.Scale(element, 200, - { sync: true, scaleFromCenter: true, scaleContent: true, restoreAfterFinish: true }), - new Effect.Opacity(element, { sync: true, to: 0.0 } ) ], - Object.extend({ duration: 1.0, - beforeSetupInternal: function(effect) { - Position.absolutize(effect.effects[0].element); - }, - afterFinishInternal: function(effect) { - effect.effects[0].element.hide().setStyle(oldStyle); } - }, arguments[1] || { }) - ); -}; - -Effect.BlindUp = function(element) { - element = $(element); - element.makeClipping(); - return new Effect.Scale(element, 0, - Object.extend({ scaleContent: false, - scaleX: false, - restoreAfterFinish: true, - afterFinishInternal: function(effect) { - effect.element.hide().undoClipping(); - } - }, arguments[1] || { }) - ); -}; - -Effect.BlindDown = function(element) { - element = $(element); - var elementDimensions = element.getDimensions(); - return new Effect.Scale(element, 100, Object.extend({ - scaleContent: false, - scaleX: false, - scaleFrom: 0, - scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width}, - restoreAfterFinish: true, - afterSetup: function(effect) { - effect.element.makeClipping().setStyle({height: '0px'}).show(); - }, - afterFinishInternal: function(effect) { - effect.element.undoClipping(); - } - }, arguments[1] || { })); -}; - -Effect.SwitchOff = function(element) { - element = $(element); - var oldOpacity = element.getInlineOpacity(); - return new Effect.Appear(element, Object.extend({ - duration: 0.4, - from: 0, - transition: Effect.Transitions.flicker, - afterFinishInternal: function(effect) { - new Effect.Scale(effect.element, 1, { - duration: 0.3, scaleFromCenter: true, - scaleX: false, scaleContent: false, restoreAfterFinish: true, - beforeSetup: function(effect) { - effect.element.makePositioned().makeClipping(); - }, - afterFinishInternal: function(effect) { - effect.element.hide().undoClipping().undoPositioned().setStyle({opacity: oldOpacity}); - } - }); - } - }, arguments[1] || { })); -}; - -Effect.DropOut = function(element) { - element = $(element); - var oldStyle = { - top: element.getStyle('top'), - left: element.getStyle('left'), - opacity: element.getInlineOpacity() }; - return new Effect.Parallel( - [ new Effect.Move(element, {x: 0, y: 100, sync: true }), - new Effect.Opacity(element, { sync: true, to: 0.0 }) ], - Object.extend( - { duration: 0.5, - beforeSetup: function(effect) { - effect.effects[0].element.makePositioned(); - }, - afterFinishInternal: function(effect) { - effect.effects[0].element.hide().undoPositioned().setStyle(oldStyle); - } - }, arguments[1] || { })); -}; - -Effect.Shake = function(element) { - element = $(element); - var options = Object.extend({ - distance: 20, - duration: 0.5 - }, arguments[1] || {}); - var distance = parseFloat(options.distance); - var split = parseFloat(options.duration) / 10.0; - var oldStyle = { - top: element.getStyle('top'), - left: element.getStyle('left') }; - return new Effect.Move(element, - { x: distance, y: 0, duration: split, afterFinishInternal: function(effect) { - new Effect.Move(effect.element, - { x: -distance*2, y: 0, duration: split*2, afterFinishInternal: function(effect) { - new Effect.Move(effect.element, - { x: distance*2, y: 0, duration: split*2, afterFinishInternal: function(effect) { - new Effect.Move(effect.element, - { x: -distance*2, y: 0, duration: split*2, afterFinishInternal: function(effect) { - new Effect.Move(effect.element, - { x: distance*2, y: 0, duration: split*2, afterFinishInternal: function(effect) { - new Effect.Move(effect.element, - { x: -distance, y: 0, duration: split, afterFinishInternal: function(effect) { - effect.element.undoPositioned().setStyle(oldStyle); - }}); }}); }}); }}); }}); }}); -}; - -Effect.SlideDown = function(element) { - element = $(element).cleanWhitespace(); - // SlideDown need to have the content of the element wrapped in a container element with fixed height! - var oldInnerBottom = element.down().getStyle('bottom'); - var elementDimensions = element.getDimensions(); - return new Effect.Scale(element, 100, Object.extend({ - scaleContent: false, - scaleX: false, - scaleFrom: window.opera ? 0 : 1, - scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width}, - restoreAfterFinish: true, - afterSetup: function(effect) { - effect.element.makePositioned(); - effect.element.down().makePositioned(); - if (window.opera) effect.element.setStyle({top: ''}); - effect.element.makeClipping().setStyle({height: '0px'}).show(); - }, - afterUpdateInternal: function(effect) { - effect.element.down().setStyle({bottom: - (effect.dims[0] - effect.element.clientHeight) + 'px' }); - }, - afterFinishInternal: function(effect) { - effect.element.undoClipping().undoPositioned(); - effect.element.down().undoPositioned().setStyle({bottom: oldInnerBottom}); } - }, arguments[1] || { }) - ); -}; - -Effect.SlideUp = function(element) { - element = $(element).cleanWhitespace(); - var oldInnerBottom = element.down().getStyle('bottom'); - var elementDimensions = element.getDimensions(); - return new Effect.Scale(element, window.opera ? 0 : 1, - Object.extend({ scaleContent: false, - scaleX: false, - scaleMode: 'box', - scaleFrom: 100, - scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width}, - restoreAfterFinish: true, - afterSetup: function(effect) { - effect.element.makePositioned(); - effect.element.down().makePositioned(); - if (window.opera) effect.element.setStyle({top: ''}); - effect.element.makeClipping().show(); - }, - afterUpdateInternal: function(effect) { - effect.element.down().setStyle({bottom: - (effect.dims[0] - effect.element.clientHeight) + 'px' }); - }, - afterFinishInternal: function(effect) { - effect.element.hide().undoClipping().undoPositioned(); - effect.element.down().undoPositioned().setStyle({bottom: oldInnerBottom}); - } - }, arguments[1] || { }) - ); -}; - -// Bug in opera makes the TD containing this element expand for a instance after finish -Effect.Squish = function(element) { - return new Effect.Scale(element, window.opera ? 1 : 0, { - restoreAfterFinish: true, - beforeSetup: function(effect) { - effect.element.makeClipping(); - }, - afterFinishInternal: function(effect) { - effect.element.hide().undoClipping(); - } - }); -}; - -Effect.Grow = function(element) { - element = $(element); - var options = Object.extend({ - direction: 'center', - moveTransition: Effect.Transitions.sinoidal, - scaleTransition: Effect.Transitions.sinoidal, - opacityTransition: Effect.Transitions.full - }, arguments[1] || { }); - var oldStyle = { - top: element.style.top, - left: element.style.left, - height: element.style.height, - width: element.style.width, - opacity: element.getInlineOpacity() }; - - var dims = element.getDimensions(); - var initialMoveX, initialMoveY; - var moveX, moveY; - - switch (options.direction) { - case 'top-left': - initialMoveX = initialMoveY = moveX = moveY = 0; - break; - case 'top-right': - initialMoveX = dims.width; - initialMoveY = moveY = 0; - moveX = -dims.width; - break; - case 'bottom-left': - initialMoveX = moveX = 0; - initialMoveY = dims.height; - moveY = -dims.height; - break; - case 'bottom-right': - initialMoveX = dims.width; - initialMoveY = dims.height; - moveX = -dims.width; - moveY = -dims.height; - break; - case 'center': - initialMoveX = dims.width / 2; - initialMoveY = dims.height / 2; - moveX = -dims.width / 2; - moveY = -dims.height / 2; - break; - } - - return new Effect.Move(element, { - x: initialMoveX, - y: initialMoveY, - duration: 0.01, - beforeSetup: function(effect) { - effect.element.hide().makeClipping().makePositioned(); - }, - afterFinishInternal: function(effect) { - new Effect.Parallel( - [ new Effect.Opacity(effect.element, { sync: true, to: 1.0, from: 0.0, transition: options.opacityTransition }), - new Effect.Move(effect.element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition }), - new Effect.Scale(effect.element, 100, { - scaleMode: { originalHeight: dims.height, originalWidth: dims.width }, - sync: true, scaleFrom: window.opera ? 1 : 0, transition: options.scaleTransition, restoreAfterFinish: true}) - ], Object.extend({ - beforeSetup: function(effect) { - effect.effects[0].element.setStyle({height: '0px'}).show(); - }, - afterFinishInternal: function(effect) { - effect.effects[0].element.undoClipping().undoPositioned().setStyle(oldStyle); - } - }, options) - ); - } - }); -}; - -Effect.Shrink = function(element) { - element = $(element); - var options = Object.extend({ - direction: 'center', - moveTransition: Effect.Transitions.sinoidal, - scaleTransition: Effect.Transitions.sinoidal, - opacityTransition: Effect.Transitions.none - }, arguments[1] || { }); - var oldStyle = { - top: element.style.top, - left: element.style.left, - height: element.style.height, - width: element.style.width, - opacity: element.getInlineOpacity() }; - - var dims = element.getDimensions(); - var moveX, moveY; - - switch (options.direction) { - case 'top-left': - moveX = moveY = 0; - break; - case 'top-right': - moveX = dims.width; - moveY = 0; - break; - case 'bottom-left': - moveX = 0; - moveY = dims.height; - break; - case 'bottom-right': - moveX = dims.width; - moveY = dims.height; - break; - case 'center': - moveX = dims.width / 2; - moveY = dims.height / 2; - break; - } - - return new Effect.Parallel( - [ new Effect.Opacity(element, { sync: true, to: 0.0, from: 1.0, transition: options.opacityTransition }), - new Effect.Scale(element, window.opera ? 1 : 0, { sync: true, transition: options.scaleTransition, restoreAfterFinish: true}), - new Effect.Move(element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition }) - ], Object.extend({ - beforeStartInternal: function(effect) { - effect.effects[0].element.makePositioned().makeClipping(); - }, - afterFinishInternal: function(effect) { - effect.effects[0].element.hide().undoClipping().undoPositioned().setStyle(oldStyle); } - }, options) - ); -}; - -Effect.Pulsate = function(element) { - element = $(element); - var options = arguments[1] || { }, - oldOpacity = element.getInlineOpacity(), - transition = options.transition || Effect.Transitions.linear, - reverser = function(pos){ - return 1 - transition((-Math.cos((pos*(options.pulses||5)*2)*Math.PI)/2) + .5); - }; - - return new Effect.Opacity(element, - Object.extend(Object.extend({ duration: 2.0, from: 0, - afterFinishInternal: function(effect) { effect.element.setStyle({opacity: oldOpacity}); } - }, options), {transition: reverser})); -}; - -Effect.Fold = function(element) { - element = $(element); - var oldStyle = { - top: element.style.top, - left: element.style.left, - width: element.style.width, - height: element.style.height }; - element.makeClipping(); - return new Effect.Scale(element, 5, Object.extend({ - scaleContent: false, - scaleX: false, - afterFinishInternal: function(effect) { - new Effect.Scale(element, 1, { - scaleContent: false, - scaleY: false, - afterFinishInternal: function(effect) { - effect.element.hide().undoClipping().setStyle(oldStyle); - } }); - }}, arguments[1] || { })); -}; - -Effect.Morph = Class.create(Effect.Base, { - initialize: function(element) { - this.element = $(element); - if (!this.element) throw(Effect._elementDoesNotExistError); - var options = Object.extend({ - style: { } - }, arguments[1] || { }); - - if (!Object.isString(options.style)) this.style = $H(options.style); - else { - if (options.style.include(':')) - this.style = options.style.parseStyle(); - else { - this.element.addClassName(options.style); - this.style = $H(this.element.getStyles()); - this.element.removeClassName(options.style); - var css = this.element.getStyles(); - this.style = this.style.reject(function(style) { - return style.value == css[style.key]; - }); - options.afterFinishInternal = function(effect) { - effect.element.addClassName(effect.options.style); - effect.transforms.each(function(transform) { - effect.element.style[transform.style] = ''; - }); - }; - } - } - this.start(options); - }, - - setup: function(){ - function parseColor(color){ - if (!color || ['rgba(0, 0, 0, 0)','transparent'].include(color)) color = '#ffffff'; - color = color.parseColor(); - return $R(0,2).map(function(i){ - return parseInt( color.slice(i*2+1,i*2+3), 16 ); - }); - } - this.transforms = this.style.map(function(pair){ - var property = pair[0], value = pair[1], unit = null; - - if (value.parseColor('#zzzzzz') != '#zzzzzz') { - value = value.parseColor(); - unit = 'color'; - } else if (property == 'opacity') { - value = parseFloat(value); - if (Prototype.Browser.IE && (!this.element.currentStyle.hasLayout)) - this.element.setStyle({zoom: 1}); - } else if (Element.CSS_LENGTH.test(value)) { - var components = value.match(/^([\+\-]?[0-9\.]+)(.*)$/); - value = parseFloat(components[1]); - unit = (components.length == 3) ? components[2] : null; - } - - var originalValue = this.element.getStyle(property); - return { - style: property.camelize(), - originalValue: unit=='color' ? parseColor(originalValue) : parseFloat(originalValue || 0), - targetValue: unit=='color' ? parseColor(value) : value, - unit: unit - }; - }.bind(this)).reject(function(transform){ - return ( - (transform.originalValue == transform.targetValue) || - ( - transform.unit != 'color' && - (isNaN(transform.originalValue) || isNaN(transform.targetValue)) - ) - ); - }); - }, - update: function(position) { - var style = { }, transform, i = this.transforms.length; - while(i--) - style[(transform = this.transforms[i]).style] = - transform.unit=='color' ? '#'+ - (Math.round(transform.originalValue[0]+ - (transform.targetValue[0]-transform.originalValue[0])*position)).toColorPart() + - (Math.round(transform.originalValue[1]+ - (transform.targetValue[1]-transform.originalValue[1])*position)).toColorPart() + - (Math.round(transform.originalValue[2]+ - (transform.targetValue[2]-transform.originalValue[2])*position)).toColorPart() : - (transform.originalValue + - (transform.targetValue - transform.originalValue) * position).toFixed(3) + - (transform.unit === null ? '' : transform.unit); - this.element.setStyle(style, true); - } -}); - -Effect.Transform = Class.create({ - initialize: function(tracks){ - this.tracks = []; - this.options = arguments[1] || { }; - this.addTracks(tracks); - }, - addTracks: function(tracks){ - tracks.each(function(track){ - track = $H(track); - var data = track.values().first(); - this.tracks.push($H({ - ids: track.keys().first(), - effect: Effect.Morph, - options: { style: data } - })); - }.bind(this)); - return this; - }, - play: function(){ - return new Effect.Parallel( - this.tracks.map(function(track){ - var ids = track.get('ids'), effect = track.get('effect'), options = track.get('options'); - var elements = [$(ids) || $$(ids)].flatten(); - return elements.map(function(e){ return new effect(e, Object.extend({ sync:true }, options)) }); - }).flatten(), - this.options - ); - } -}); - -Element.CSS_PROPERTIES = $w( - 'backgroundColor backgroundPosition borderBottomColor borderBottomStyle ' + - 'borderBottomWidth borderLeftColor borderLeftStyle borderLeftWidth ' + - 'borderRightColor borderRightStyle borderRightWidth borderSpacing ' + - 'borderTopColor borderTopStyle borderTopWidth bottom clip color ' + - 'fontSize fontWeight height left letterSpacing lineHeight ' + - 'marginBottom marginLeft marginRight marginTop markerOffset maxHeight '+ - 'maxWidth minHeight minWidth opacity outlineColor outlineOffset ' + - 'outlineWidth paddingBottom paddingLeft paddingRight paddingTop ' + - 'right textIndent top width wordSpacing zIndex'); - -Element.CSS_LENGTH = /^(([\+\-]?[0-9\.]+)(em|ex|px|in|cm|mm|pt|pc|\%))|0$/; - -String.__parseStyleElement = document.createElement('div'); -String.prototype.parseStyle = function(){ - var style, styleRules = $H(); - if (Prototype.Browser.WebKit) - style = new Element('div',{style:this}).style; - else { - String.__parseStyleElement.innerHTML = '
    '; - style = String.__parseStyleElement.childNodes[0].style; - } - - Element.CSS_PROPERTIES.each(function(property){ - if (style[property]) styleRules.set(property, style[property]); - }); - - if (Prototype.Browser.IE && this.include('opacity')) - styleRules.set('opacity', this.match(/opacity:\s*((?:0|1)?(?:\.\d*)?)/)[1]); - - return styleRules; -}; - -if (document.defaultView && document.defaultView.getComputedStyle) { - Element.getStyles = function(element) { - var css = document.defaultView.getComputedStyle($(element), null); - return Element.CSS_PROPERTIES.inject({ }, function(styles, property) { - styles[property] = css[property]; - return styles; - }); - }; -} else { - Element.getStyles = function(element) { - element = $(element); - var css = element.currentStyle, styles; - styles = Element.CSS_PROPERTIES.inject({ }, function(results, property) { - results[property] = css[property]; - return results; - }); - if (!styles.opacity) styles.opacity = element.getOpacity(); - return styles; - }; -} - -Effect.Methods = { - morph: function(element, style) { - element = $(element); - new Effect.Morph(element, Object.extend({ style: style }, arguments[2] || { })); - return element; - }, - visualEffect: function(element, effect, options) { - element = $(element); - var s = effect.dasherize().camelize(), klass = s.charAt(0).toUpperCase() + s.substring(1); - new Effect[klass](element, options); - return element; - }, - highlight: function(element, options) { - element = $(element); - new Effect.Highlight(element, options); - return element; - } -}; - -$w('fade appear grow shrink fold blindUp blindDown slideUp slideDown '+ - 'pulsate shake puff squish switchOff dropOut').each( - function(effect) { - Effect.Methods[effect] = function(element, options){ - element = $(element); - Effect[effect.charAt(0).toUpperCase() + effect.substring(1)](element, options); - return element; - }; - } -); - -$w('getInlineOpacity forceRerendering setContentZoom collectTextNodes collectTextNodesIgnoreClass getStyles').each( - function(f) { Effect.Methods[f] = Element[f]; } -); - -Element.addMethods(Effect.Methods); \ No newline at end of file diff --git a/src/javascripttest.rb b/src/javascripttest.rb deleted file mode 100644 index 36d3508..0000000 --- a/src/javascripttest.rb +++ /dev/null @@ -1,203 +0,0 @@ -require 'rake/tasklib' -require 'thread' -require 'webrick' - -class Browser - def supported?; true; end - def setup ; end - def open(url) ; end - def teardown ; end - - def host - require 'rbconfig' - Config::CONFIG['host'] - end - - def macos? - host.include?('darwin') - end - - def windows? - host.include?('mswin') - end - - def linux? - host.include?('linux') - end - - def applescript(script) - raise "Can't run AppleScript on #{host}" unless macos? - system "osascript -e '#{script}' 2>&1 >/dev/null" - end -end - -class FirefoxBrowser < Browser - def initialize(path='c:\Program Files\Mozilla Firefox\firefox.exe') - @path = path - end - - def visit(url) - applescript('tell application "Firefox" to Get URL "' + url + '"') if macos? - system("#{@path} #{url}") if windows? - system("firefox #{url}") if linux? - end - - def to_s - "Firefox" - end -end - -class SafariBrowser < Browser - def supported? - macos? - end - - def setup - applescript('tell application "Safari" to make new document') - end - - def visit(url) - applescript('tell application "Safari" to set URL of front document to "' + url + '"') - end - - def teardown - #applescript('tell application "Safari" to close front document') - end - - def to_s - "Safari" - end -end - -class IEBrowser < Browser - def initialize(path='C:\Program Files\Internet Explorer\IEXPLORE.EXE') - @path = path - end - - def setup - if windows? - puts %{ - MAJOR ANNOYANCE on Windows. - You have to shut down the Internet Explorer manually after each test - for the script to proceed. - Any suggestions on fixing this is GREATLY appreaciated! - Thank you for your understanding. - } - end - end - - def supported? - windows? - end - - def visit(url) - system("#{@path} #{url}") if windows? - end - - def to_s - "Internet Explorer" - end -end - -class KonquerorBrowser < Browser - def supported? - linux? - end - - def visit(url) - system("kfmclient openURL #{url}") - end - - def to_s - "Konqueror" - end -end - -# shut up, webrick :-) -class ::WEBrick::HTTPServer - def access_log(config, req, res) - # nop - end -end -class ::WEBrick::BasicLog - def log(level, data) - # nop - end -end - -class JavaScriptTestTask < ::Rake::TaskLib - - def initialize(name=:test) - @name = name - @tests = [] - @browsers = [] - - @queue = Queue.new - - result = [] - - @server = WEBrick::HTTPServer.new(:Port => 4711) # TODO: make port configurable - @server.mount_proc("/results") do |req, res| - @queue.push(req.query['result']) - res.body = "OK" - end - yield self if block_given? - define - end - - def define - task @name do - trap("INT") { @server.shutdown } - t = Thread.new { @server.start } - - # run all combinations of browsers and tests - @browsers.each do |browser| - if browser.supported? - browser.setup - @tests.each do |test| - browser.visit("http://localhost:4711#{test}?resultsURL=http://localhost:4711/results&t=" + ("%.6f" % Time.now.to_f)) - result = @queue.pop - puts "#{test} on #{browser}: #{result}" - end - browser.teardown - else - puts "Skipping #{browser}, not supported on this OS" - end - browser.teardown - end - - @server.shutdown - t.join - end - end - - def mount(path, dir=nil) - dir = Dir.pwd + path unless dir - - @server.mount(path, WEBrick::HTTPServlet::FileHandler, dir) - end - - # test should be specified as a url - def run(test) - @tests<<\/script>'); - } catch(e) { - // for xhtml+xml served content, fall back to DOM methods - var script = document.createElement('script'); - script.type = 'text/javascript'; - script.src = libraryName; - document.getElementsByTagName('head')[0].appendChild(script); - } - }, - REQUIRED_PROTOTYPE: '1.6.0.3', - load: function() { - function convertVersionString(versionString) { - var v = versionString.replace(/_.*|\./g, ''); - v = parseInt(v + '0'.times(4-v.length)); - return versionString.indexOf('_') > -1 ? v-1 : v; - } - - if((typeof Prototype=='undefined') || - (typeof Element == 'undefined') || - (typeof Element.Methods=='undefined') || - (convertVersionString(Prototype.Version) < - convertVersionString(Scriptaculous.REQUIRED_PROTOTYPE))) - throw("script.aculo.us requires the Prototype JavaScript framework >= " + - Scriptaculous.REQUIRED_PROTOTYPE); - - var js = /scriptaculous\.js(\?.*)?$/; - $$('script[src]').findAll(function(s) { - return s.src.match(js); - }).each(function(s) { - var path = s.src.replace(js, ''), - includes = s.src.match(/\?.*load=([a-z,]*)/); - (includes ? includes[1] : 'builder,effects,dragdrop,controls,slider,sound').split(',').each( - function(include) { Scriptaculous.require(path+include+'.js') }); - }); - } -}; - -Scriptaculous.load(); \ No newline at end of file diff --git a/src/slider.js b/src/slider.js deleted file mode 100644 index cafc7d0..0000000 --- a/src/slider.js +++ /dev/null @@ -1,273 +0,0 @@ -// Copyright (c) 2005-2009 Marty Haught, Thomas Fuchs -// -// script.aculo.us is freely distributable under the terms of an MIT-style license. -// For details, see the script.aculo.us web site: http://script.aculo.us/ - -if (!Control) var Control = { }; - -// options: -// axis: 'vertical', or 'horizontal' (default) -// -// callbacks: -// onChange(value) -// onSlide(value) -Control.Slider = Class.create({ - initialize: function(handle, track, options) { - var slider = this; - - if (Object.isArray(handle)) { - this.handles = handle.collect( function(e) { return $(e) }); - } else { - this.handles = [$(handle)]; - } - - this.track = $(track); - this.options = options || { }; - - this.axis = this.options.axis || 'horizontal'; - this.increment = this.options.increment || 1; - this.step = parseInt(this.options.step || '1'); - this.range = this.options.range || $R(0,1); - - this.value = 0; // assure backwards compat - this.values = this.handles.map( function() { return 0 }); - this.spans = this.options.spans ? this.options.spans.map(function(s){ return $(s) }) : false; - this.options.startSpan = $(this.options.startSpan || null); - this.options.endSpan = $(this.options.endSpan || null); - - this.restricted = this.options.restricted || false; - - this.maximum = this.options.maximum || this.range.end; - this.minimum = this.options.minimum || this.range.start; - - // Will be used to align the handle onto the track, if necessary - this.alignX = parseInt(this.options.alignX || '0'); - this.alignY = parseInt(this.options.alignY || '0'); - - this.trackLength = this.maximumOffset() - this.minimumOffset(); - - this.handleLength = this.isVertical() ? - (this.handles[0].offsetHeight != 0 ? - this.handles[0].offsetHeight : this.handles[0].style.height.replace(/px$/,"")) : - (this.handles[0].offsetWidth != 0 ? this.handles[0].offsetWidth : - this.handles[0].style.width.replace(/px$/,"")); - - this.active = false; - this.dragging = false; - this.disabled = false; - - if (this.options.disabled) this.setDisabled(); - - // Allowed values array - this.allowedValues = this.options.values ? this.options.values.sortBy(Prototype.K) : false; - if (this.allowedValues) { - this.minimum = this.allowedValues.min(); - this.maximum = this.allowedValues.max(); - } - - this.eventMouseDown = this.startDrag.bindAsEventListener(this); - this.eventMouseUp = this.endDrag.bindAsEventListener(this); - this.eventMouseMove = this.update.bindAsEventListener(this); - - // Initialize handles in reverse (make sure first handle is active) - this.handles.each( function(h,i) { - i = slider.handles.length-1-i; - slider.setValue(parseFloat( - (Object.isArray(slider.options.sliderValue) ? - slider.options.sliderValue[i] : slider.options.sliderValue) || - slider.range.start), i); - h.makePositioned().observe("mousedown", slider.eventMouseDown); - }); - - this.track.observe("mousedown", this.eventMouseDown); - document.observe("mouseup", this.eventMouseUp); - document.observe("mousemove", this.eventMouseMove); - - this.initialized = true; - }, - dispose: function() { - var slider = this; - Event.stopObserving(this.track, "mousedown", this.eventMouseDown); - Event.stopObserving(document, "mouseup", this.eventMouseUp); - Event.stopObserving(document, "mousemove", this.eventMouseMove); - this.handles.each( function(h) { - Event.stopObserving(h, "mousedown", slider.eventMouseDown); - }); - }, - setDisabled: function(){ - this.disabled = true; - }, - setEnabled: function(){ - this.disabled = false; - }, - getNearestValue: function(value){ - if (this.allowedValues){ - if (value >= this.allowedValues.max()) return(this.allowedValues.max()); - if (value <= this.allowedValues.min()) return(this.allowedValues.min()); - - var offset = Math.abs(this.allowedValues[0] - value); - var newValue = this.allowedValues[0]; - this.allowedValues.each( function(v) { - var currentOffset = Math.abs(v - value); - if (currentOffset <= offset){ - newValue = v; - offset = currentOffset; - } - }); - return newValue; - } - if (value > this.range.end) return this.range.end; - if (value < this.range.start) return this.range.start; - return value; - }, - setValue: function(sliderValue, handleIdx){ - if (!this.active) { - this.activeHandleIdx = handleIdx || 0; - this.activeHandle = this.handles[this.activeHandleIdx]; - this.updateStyles(); - } - handleIdx = handleIdx || this.activeHandleIdx || 0; - if (this.initialized && this.restricted) { - if ((handleIdx>0) && (sliderValuethis.values[handleIdx+1])) - sliderValue = this.values[handleIdx+1]; - } - sliderValue = this.getNearestValue(sliderValue); - this.values[handleIdx] = sliderValue; - this.value = this.values[0]; // assure backwards compat - - this.handles[handleIdx].style[this.isVertical() ? 'top' : 'left'] = - this.translateToPx(sliderValue); - - this.drawSpans(); - if (!this.dragging || !this.event) this.updateFinished(); - }, - setValueBy: function(delta, handleIdx) { - this.setValue(this.values[handleIdx || this.activeHandleIdx || 0] + delta, - handleIdx || this.activeHandleIdx || 0); - }, - translateToPx: function(value) { - return Math.round( - ((this.trackLength-this.handleLength)/(this.range.end-this.range.start)) * - (value - this.range.start)) + "px"; - }, - translateToValue: function(offset) { - return ((offset/(this.trackLength-this.handleLength) * - (this.range.end-this.range.start)) + this.range.start); - }, - getRange: function(range) { - var v = this.values.sortBy(Prototype.K); - range = range || 0; - return $R(v[range],v[range+1]); - }, - minimumOffset: function(){ - return(this.isVertical() ? this.alignY : this.alignX); - }, - maximumOffset: function(){ - return(this.isVertical() ? - (this.track.offsetHeight != 0 ? this.track.offsetHeight : - this.track.style.height.replace(/px$/,"")) - this.alignY : - (this.track.offsetWidth != 0 ? this.track.offsetWidth : - this.track.style.width.replace(/px$/,"")) - this.alignX); - }, - isVertical: function(){ - return (this.axis == 'vertical'); - }, - drawSpans: function() { - var slider = this; - if (this.spans) - $R(0, this.spans.length-1).each(function(r) { slider.setSpan(slider.spans[r], slider.getRange(r)) }); - if (this.options.startSpan) - this.setSpan(this.options.startSpan, - $R(0, this.values.length>1 ? this.getRange(0).min() : this.value )); - if (this.options.endSpan) - this.setSpan(this.options.endSpan, - $R(this.values.length>1 ? this.getRange(this.spans.length-1).max() : this.value, this.maximum)); - }, - setSpan: function(span, range) { - if (this.isVertical()) { - span.style.top = this.translateToPx(range.start); - span.style.height = this.translateToPx(range.end - range.start + this.range.start); - } else { - span.style.left = this.translateToPx(range.start); - span.style.width = this.translateToPx(range.end - range.start + this.range.start); - } - }, - updateStyles: function() { - this.handles.each( function(h){ Element.removeClassName(h, 'selected') }); - Element.addClassName(this.activeHandle, 'selected'); - }, - startDrag: function(event) { - if (Event.isLeftClick(event)) { - if (!this.disabled){ - this.active = true; - - var handle = Event.element(event); - var pointer = [Event.pointerX(event), Event.pointerY(event)]; - var track = handle; - if (track==this.track) { - var offsets = this.track.cumulativeOffset(); - this.event = event; - this.setValue(this.translateToValue( - (this.isVertical() ? pointer[1]-offsets[1] : pointer[0]-offsets[0])-(this.handleLength/2) - )); - var offsets = this.activeHandle.cumulativeOffset(); - this.offsetX = (pointer[0] - offsets[0]); - this.offsetY = (pointer[1] - offsets[1]); - } else { - // find the handle (prevents issues with Safari) - while((this.handles.indexOf(handle) == -1) && handle.parentNode) - handle = handle.parentNode; - - if (this.handles.indexOf(handle)!=-1) { - this.activeHandle = handle; - this.activeHandleIdx = this.handles.indexOf(this.activeHandle); - this.updateStyles(); - - var offsets = this.activeHandle.cumulativeOffset(); - this.offsetX = (pointer[0] - offsets[0]); - this.offsetY = (pointer[1] - offsets[1]); - } - } - } - Event.stop(event); - } - }, - update: function(event) { - if (this.active) { - if (!this.dragging) this.dragging = true; - this.draw(event); - if (Prototype.Browser.WebKit) window.scrollBy(0,0); - Event.stop(event); - } - }, - draw: function(event) { - var pointer = [Event.pointerX(event), Event.pointerY(event)]; - var offsets = this.track.cumulativeOffset(); - pointer[0] -= this.offsetX + offsets[0]; - pointer[1] -= this.offsetY + offsets[1]; - this.event = event; - this.setValue(this.translateToValue( this.isVertical() ? pointer[1] : pointer[0] )); - if (this.initialized && this.options.onSlide) - this.options.onSlide(this.values.length>1 ? this.values : this.value, this); - }, - endDrag: function(event) { - if (this.active && this.dragging) { - this.finishDrag(event, true); - Event.stop(event); - } - this.active = false; - this.dragging = false; - }, - finishDrag: function(event, success) { - this.active = false; - this.dragging = false; - this.updateFinished(); - }, - updateFinished: function() { - if (this.initialized && this.options.onChange) - this.options.onChange(this.values.length>1 ? this.values : this.value, this); - this.event = null; - } -}); \ No newline at end of file diff --git a/src/sound.js b/src/sound.js deleted file mode 100644 index 9deac5e..0000000 --- a/src/sound.js +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright (c) 2005-2009 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) -// -// Based on code created by Jules Gravinese (http://www.webveteran.com/) -// -// script.aculo.us is freely distributable under the terms of an MIT-style license. -// For details, see the script.aculo.us web site: http://script.aculo.us/ - -Sound = { - tracks: {}, - _enabled: true, - template: - new Template(''), - enable: function(){ - Sound._enabled = true; - }, - disable: function(){ - Sound._enabled = false; - }, - play: function(url){ - if(!Sound._enabled) return; - var options = Object.extend({ - track: 'global', url: url, replace: false - }, arguments[1] || {}); - - if(options.replace && this.tracks[options.track]) { - $R(0, this.tracks[options.track].id).each(function(id){ - var sound = $('sound_'+options.track+'_'+id); - sound.Stop && sound.Stop(); - sound.remove(); - }); - this.tracks[options.track] = null; - } - - if(!this.tracks[options.track]) - this.tracks[options.track] = { id: 0 }; - else - this.tracks[options.track].id++; - - options.id = this.tracks[options.track].id; - $$('body')[0].insert( - Prototype.Browser.IE ? new Element('bgsound',{ - id: 'sound_'+options.track+'_'+options.id, - src: options.url, loop: 1, autostart: true - }) : Sound.template.evaluate(options)); - } -}; - -if(Prototype.Browser.Gecko && navigator.userAgent.indexOf("Win") > 0){ - if(navigator.plugins && $A(navigator.plugins).detect(function(p){ return p.name.indexOf('QuickTime') != -1 })) - Sound.template = new Template(''); - else if(navigator.plugins && $A(navigator.plugins).detect(function(p){ return p.name.indexOf('Windows Media') != -1 })) - Sound.template = new Template(''); - else if(navigator.plugins && $A(navigator.plugins).detect(function(p){ return p.name.indexOf('RealPlayer') != -1 })) - Sound.template = new Template(''); - else - Sound.play = function(){}; -} \ No newline at end of file diff --git a/src/unittest.js b/src/unittest.js deleted file mode 100644 index f181510..0000000 --- a/src/unittest.js +++ /dev/null @@ -1,566 +0,0 @@ -// Copyright (c) 2005-2009 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) -// (c) 2005-2009 Jon Tirsen (http://www.tirsen.com) -// (c) 2005-2009 Michael Schuerig (http://www.schuerig.de/michael/) -// -// script.aculo.us is freely distributable under the terms of an MIT-style license. -// For details, see the script.aculo.us web site: http://script.aculo.us/ - -// experimental, Firefox-only -Event.simulateMouse = function(element, eventName) { - var options = Object.extend({ - pointerX: 0, - pointerY: 0, - buttons: 0, - ctrlKey: false, - altKey: false, - shiftKey: false, - metaKey: false - }, arguments[2] || {}); - var oEvent = document.createEvent("MouseEvents"); - oEvent.initMouseEvent(eventName, true, true, document.defaultView, - options.buttons, options.pointerX, options.pointerY, options.pointerX, options.pointerY, - options.ctrlKey, options.altKey, options.shiftKey, options.metaKey, 0, $(element)); - - if(this.mark) Element.remove(this.mark); - this.mark = document.createElement('div'); - this.mark.appendChild(document.createTextNode(" ")); - document.body.appendChild(this.mark); - this.mark.style.position = 'absolute'; - this.mark.style.top = options.pointerY + "px"; - this.mark.style.left = options.pointerX + "px"; - this.mark.style.width = "5px"; - this.mark.style.height = "5px;"; - this.mark.style.borderTop = "1px solid red;"; - this.mark.style.borderLeft = "1px solid red;"; - - if(this.step) - alert('['+new Date().getTime().toString()+'] '+eventName+'/'+Test.Unit.inspect(options)); - - $(element).dispatchEvent(oEvent); -}; - -// Note: Due to a fix in Firefox 1.0.5/6 that probably fixed "too much", this doesn't work in 1.0.6 or DP2. -// You need to downgrade to 1.0.4 for now to get this working -// See https://bugzilla.mozilla.org/show_bug.cgi?id=289940 for the fix that fixed too much -Event.simulateKey = function(element, eventName) { - var options = Object.extend({ - ctrlKey: false, - altKey: false, - shiftKey: false, - metaKey: false, - keyCode: 0, - charCode: 0 - }, arguments[2] || {}); - - var oEvent = document.createEvent("KeyEvents"); - oEvent.initKeyEvent(eventName, true, true, window, - options.ctrlKey, options.altKey, options.shiftKey, options.metaKey, - options.keyCode, options.charCode ); - $(element).dispatchEvent(oEvent); -}; - -Event.simulateKeys = function(element, command) { - for(var i=0; i' + - '' + - '' + - '' + - '
    StatusTestMessage
    '; - this.logsummary = $('logsummary'); - this.loglines = $('loglines'); - }, - _toHTML: function(txt) { - return txt.escapeHTML().replace(/\n/g,"
    "); - }, - addLinksToResults: function(){ - $$("tr.failed .nameCell").each( function(td){ // todo: limit to children of this.log - td.title = "Run only this test"; - Event.observe(td, 'click', function(){ window.location.search = "?tests=" + td.innerHTML;}); - }); - $$("tr.passed .nameCell").each( function(td){ // todo: limit to children of this.log - td.title = "Run all tests"; - Event.observe(td, 'click', function(){ window.location.search = "";}); - }); - } -}; - -Test.Unit.Runner = Class.create(); -Test.Unit.Runner.prototype = { - initialize: function(testcases) { - this.options = Object.extend({ - testLog: 'testlog' - }, arguments[1] || {}); - this.options.resultsURL = this.parseResultsURLQueryParameter(); - this.options.tests = this.parseTestsQueryParameter(); - if (this.options.testLog) { - this.options.testLog = $(this.options.testLog) || null; - } - if(this.options.tests) { - this.tests = []; - for(var i = 0; i < this.options.tests.length; i++) { - if(/^test/.test(this.options.tests[i])) { - this.tests.push(new Test.Unit.Testcase(this.options.tests[i], testcases[this.options.tests[i]], testcases["setup"], testcases["teardown"])); - } - } - } else { - if (this.options.test) { - this.tests = [new Test.Unit.Testcase(this.options.test, testcases[this.options.test], testcases["setup"], testcases["teardown"])]; - } else { - this.tests = []; - for(var testcase in testcases) { - if(/^test/.test(testcase)) { - this.tests.push( - new Test.Unit.Testcase( - this.options.context ? ' -> ' + this.options.titles[testcase] : testcase, - testcases[testcase], testcases["setup"], testcases["teardown"] - )); - } - } - } - } - this.currentTest = 0; - this.logger = new Test.Unit.Logger(this.options.testLog); - setTimeout(this.runTests.bind(this), 1000); - }, - parseResultsURLQueryParameter: function() { - return window.location.search.parseQuery()["resultsURL"]; - }, - parseTestsQueryParameter: function(){ - if (window.location.search.parseQuery()["tests"]){ - return window.location.search.parseQuery()["tests"].split(','); - }; - }, - // Returns: - // "ERROR" if there was an error, - // "FAILURE" if there was a failure, or - // "SUCCESS" if there was neither - getResult: function() { - var hasFailure = false; - for(var i=0;i 0) { - return "ERROR"; - } - if (this.tests[i].failures > 0) { - hasFailure = true; - } - } - if (hasFailure) { - return "FAILURE"; - } else { - return "SUCCESS"; - } - }, - postResults: function() { - if (this.options.resultsURL) { - new Ajax.Request(this.options.resultsURL, - { method: 'get', parameters: 'result=' + this.getResult(), asynchronous: false }); - } - }, - runTests: function() { - var test = this.tests[this.currentTest]; - if (!test) { - // finished! - this.postResults(); - this.logger.summary(this.summary()); - return; - } - if(!test.isWaiting) { - this.logger.start(test.name); - } - test.run(); - if(test.isWaiting) { - this.logger.message("Waiting for " + test.timeToWait + "ms"); - setTimeout(this.runTests.bind(this), test.timeToWait || 1000); - } else { - this.logger.finish(test.status(), test.summary()); - this.currentTest++; - // tail recursive, hopefully the browser will skip the stackframe - this.runTests(); - } - }, - summary: function() { - var assertions = 0; - var failures = 0; - var errors = 0; - var messages = []; - for(var i=0;i 0) return 'failed'; - if (this.errors > 0) return 'error'; - return 'passed'; - }, - assert: function(expression) { - var message = arguments[1] || 'assert: got "' + Test.Unit.inspect(expression) + '"'; - try { expression ? this.pass() : - this.fail(message); } - catch(e) { this.error(e); } - }, - assertEqual: function(expected, actual) { - var message = arguments[2] || "assertEqual"; - try { (expected == actual) ? this.pass() : - this.fail(message + ': expected "' + Test.Unit.inspect(expected) + - '", actual "' + Test.Unit.inspect(actual) + '"'); } - catch(e) { this.error(e); } - }, - assertInspect: function(expected, actual) { - var message = arguments[2] || "assertInspect"; - try { (expected == actual.inspect()) ? this.pass() : - this.fail(message + ': expected "' + Test.Unit.inspect(expected) + - '", actual "' + Test.Unit.inspect(actual) + '"'); } - catch(e) { this.error(e); } - }, - assertEnumEqual: function(expected, actual) { - var message = arguments[2] || "assertEnumEqual"; - try { $A(expected).length == $A(actual).length && - expected.zip(actual).all(function(pair) { return pair[0] == pair[1] }) ? - this.pass() : this.fail(message + ': expected ' + Test.Unit.inspect(expected) + - ', actual ' + Test.Unit.inspect(actual)); } - catch(e) { this.error(e); } - }, - assertNotEqual: function(expected, actual) { - var message = arguments[2] || "assertNotEqual"; - try { (expected != actual) ? this.pass() : - this.fail(message + ': got "' + Test.Unit.inspect(actual) + '"'); } - catch(e) { this.error(e); } - }, - assertIdentical: function(expected, actual) { - var message = arguments[2] || "assertIdentical"; - try { (expected === actual) ? this.pass() : - this.fail(message + ': expected "' + Test.Unit.inspect(expected) + - '", actual "' + Test.Unit.inspect(actual) + '"'); } - catch(e) { this.error(e); } - }, - assertNotIdentical: function(expected, actual) { - var message = arguments[2] || "assertNotIdentical"; - try { !(expected === actual) ? this.pass() : - this.fail(message + ': expected "' + Test.Unit.inspect(expected) + - '", actual "' + Test.Unit.inspect(actual) + '"'); } - catch(e) { this.error(e); } - }, - assertNull: function(obj) { - var message = arguments[1] || 'assertNull'; - try { (obj==null) ? this.pass() : - this.fail(message + ': got "' + Test.Unit.inspect(obj) + '"'); } - catch(e) { this.error(e); } - }, - assertMatch: function(expected, actual) { - var message = arguments[2] || 'assertMatch'; - var regex = new RegExp(expected); - try { (regex.exec(actual)) ? this.pass() : - this.fail(message + ' : regex: "' + Test.Unit.inspect(expected) + ' did not match: ' + Test.Unit.inspect(actual) + '"'); } - catch(e) { this.error(e); } - }, - assertHidden: function(element) { - var message = arguments[1] || 'assertHidden'; - this.assertEqual("none", element.style.display, message); - }, - assertNotNull: function(object) { - var message = arguments[1] || 'assertNotNull'; - this.assert(object != null, message); - }, - assertType: function(expected, actual) { - var message = arguments[2] || 'assertType'; - try { - (actual.constructor == expected) ? this.pass() : - this.fail(message + ': expected "' + Test.Unit.inspect(expected) + - '", actual "' + (actual.constructor) + '"'); } - catch(e) { this.error(e); } - }, - assertNotOfType: function(expected, actual) { - var message = arguments[2] || 'assertNotOfType'; - try { - (actual.constructor != expected) ? this.pass() : - this.fail(message + ': expected "' + Test.Unit.inspect(expected) + - '", actual "' + (actual.constructor) + '"'); } - catch(e) { this.error(e); } - }, - assertInstanceOf: function(expected, actual) { - var message = arguments[2] || 'assertInstanceOf'; - try { - (actual instanceof expected) ? this.pass() : - this.fail(message + ": object was not an instance of the expected type"); } - catch(e) { this.error(e); } - }, - assertNotInstanceOf: function(expected, actual) { - var message = arguments[2] || 'assertNotInstanceOf'; - try { - !(actual instanceof expected) ? this.pass() : - this.fail(message + ": object was an instance of the not expected type"); } - catch(e) { this.error(e); } - }, - assertRespondsTo: function(method, obj) { - var message = arguments[2] || 'assertRespondsTo'; - try { - (obj[method] && typeof obj[method] == 'function') ? this.pass() : - this.fail(message + ": object doesn't respond to [" + method + "]"); } - catch(e) { this.error(e); } - }, - assertReturnsTrue: function(method, obj) { - var message = arguments[2] || 'assertReturnsTrue'; - try { - var m = obj[method]; - if(!m) m = obj['is'+method.charAt(0).toUpperCase()+method.slice(1)]; - m() ? this.pass() : - this.fail(message + ": method returned false"); } - catch(e) { this.error(e); } - }, - assertReturnsFalse: function(method, obj) { - var message = arguments[2] || 'assertReturnsFalse'; - try { - var m = obj[method]; - if(!m) m = obj['is'+method.charAt(0).toUpperCase()+method.slice(1)]; - !m() ? this.pass() : - this.fail(message + ": method returned true"); } - catch(e) { this.error(e); } - }, - assertRaise: function(exceptionName, method) { - var message = arguments[2] || 'assertRaise'; - try { - method(); - this.fail(message + ": exception expected but none was raised"); } - catch(e) { - ((exceptionName == null) || (e.name==exceptionName)) ? this.pass() : this.error(e); - } - }, - assertElementsMatch: function() { - var expressions = $A(arguments), elements = $A(expressions.shift()); - if (elements.length != expressions.length) { - this.fail('assertElementsMatch: size mismatch: ' + elements.length + ' elements, ' + expressions.length + ' expressions'); - return false; - } - elements.zip(expressions).all(function(pair, index) { - var element = $(pair.first()), expression = pair.last(); - if (element.match(expression)) return true; - this.fail('assertElementsMatch: (in index ' + index + ') expected ' + expression.inspect() + ' but got ' + element.inspect()); - }.bind(this)) && this.pass(); - }, - assertElementMatches: function(element, expression) { - this.assertElementsMatch([element], expression); - }, - benchmark: function(operation, iterations) { - var startAt = new Date(); - (iterations || 1).times(operation); - var timeTaken = ((new Date())-startAt); - this.info((arguments[2] || 'Operation') + ' finished ' + - iterations + ' iterations in ' + (timeTaken/1000)+'s' ); - return timeTaken; - }, - _isVisible: function(element) { - element = $(element); - if(!element.parentNode) return true; - this.assertNotNull(element); - if(element.style && Element.getStyle(element, 'display') == 'none') - return false; - - return this._isVisible(element.parentNode); - }, - assertNotVisible: function(element) { - this.assert(!this._isVisible(element), Test.Unit.inspect(element) + " was not hidden and didn't have a hidden parent either. " + ("" || arguments[1])); - }, - assertVisible: function(element) { - this.assert(this._isVisible(element), Test.Unit.inspect(element) + " was not visible. " + ("" || arguments[1])); - }, - benchmark: function(operation, iterations) { - var startAt = new Date(); - (iterations || 1).times(operation); - var timeTaken = ((new Date())-startAt); - this.info((arguments[2] || 'Operation') + ' finished ' + - iterations + ' iterations in ' + (timeTaken/1000)+'s' ); - return timeTaken; - } -}; - -Test.Unit.Testcase = Class.create(); -Object.extend(Object.extend(Test.Unit.Testcase.prototype, Test.Unit.Assertions.prototype), { - initialize: function(name, test, setup, teardown) { - Test.Unit.Assertions.prototype.initialize.bind(this)(); - this.name = name; - - if(typeof test == 'string') { - test = test.gsub(/(\.should[^\(]+\()/,'#{0}this,'); - test = test.gsub(/(\.should[^\(]+)\(this,\)/,'#{1}(this)'); - this.test = function() { - eval('with(this){'+test+'}'); - } - } else { - this.test = test || function() {}; - } - - this.setup = setup || function() {}; - this.teardown = teardown || function() {}; - this.isWaiting = false; - this.timeToWait = 1000; - }, - wait: function(time, nextPart) { - this.isWaiting = true; - this.test = nextPart; - this.timeToWait = time; - }, - run: function() { - try { - try { - if (!this.isWaiting) this.setup.bind(this)(); - this.isWaiting = false; - this.test.bind(this)(); - } finally { - if(!this.isWaiting) { - this.teardown.bind(this)(); - } - } - } - catch(e) { this.error(e); } - } -}); - -// *EXPERIMENTAL* BDD-style testing to please non-technical folk -// This draws many ideas from RSpec http://rspec.rubyforge.org/ - -Test.setupBDDExtensionMethods = function(){ - var METHODMAP = { - shouldEqual: 'assertEqual', - shouldNotEqual: 'assertNotEqual', - shouldEqualEnum: 'assertEnumEqual', - shouldBeA: 'assertType', - shouldNotBeA: 'assertNotOfType', - shouldBeAn: 'assertType', - shouldNotBeAn: 'assertNotOfType', - shouldBeNull: 'assertNull', - shouldNotBeNull: 'assertNotNull', - - shouldBe: 'assertReturnsTrue', - shouldNotBe: 'assertReturnsFalse', - shouldRespondTo: 'assertRespondsTo' - }; - var makeAssertion = function(assertion, args, object) { - this[assertion].apply(this,(args || []).concat([object])); - }; - - Test.BDDMethods = {}; - $H(METHODMAP).each(function(pair) { - Test.BDDMethods[pair.key] = function() { - var args = $A(arguments); - var scope = args.shift(); - makeAssertion.apply(scope, [pair.value, args, this]); }; - }); - - [Array.prototype, String.prototype, Number.prototype, Boolean.prototype].each( - function(p){ Object.extend(p, Test.BDDMethods) } - ); -}; - -Test.context = function(name, spec, log){ - Test.setupBDDExtensionMethods(); - - var compiledSpec = {}; - var titles = {}; - for(specName in spec) { - switch(specName){ - case "setup": - case "teardown": - compiledSpec[specName] = spec[specName]; - break; - default: - var testName = 'test'+specName.gsub(/\s+/,'-').camelize(); - var body = spec[specName].toString().split('\n').slice(1); - if(/^\{/.test(body[0])) body = body.slice(1); - body.pop(); - body = body.map(function(statement){ - return statement.strip() - }); - compiledSpec[testName] = body.join('\n'); - titles[testName] = specName; - } - } - new Test.Unit.Runner(compiledSpec, { titles: titles, testLog: log || 'testlog', context: name }); -}; \ No newline at end of file diff --git a/test/functional/_ajax_inplaceeditor_result.html b/test/functional/_ajax_inplaceeditor_result.html deleted file mode 100644 index 55dcbea..0000000 --- a/test/functional/_ajax_inplaceeditor_result.html +++ /dev/null @@ -1 +0,0 @@ -Server received: To be edited \ No newline at end of file diff --git a/test/functional/_ajax_inplaceeditor_text.html b/test/functional/_ajax_inplaceeditor_text.html deleted file mode 100644 index a6f35d1..0000000 --- a/test/functional/_ajax_inplaceeditor_text.html +++ /dev/null @@ -1 +0,0 @@ -Text from server \ No newline at end of file diff --git a/test/functional/_autocomplete_result.html b/test/functional/_autocomplete_result.html deleted file mode 100644 index 8ecd6c5..0000000 --- a/test/functional/_autocomplete_result.html +++ /dev/null @@ -1,9 +0,0 @@ -
      -
    • test1selectme1
    • selectme2test2
    • -
    • test3selectme3
    • -
    • BOLDselectme4boldinselectme
    • - -
    • (GET ME NOT)(GET <ME> INSTEAD)(forselectme!)
    • - -
    • Here we have a link which should work
    • -
    \ No newline at end of file diff --git a/test/functional/_autocomplete_result_single.html b/test/functional/_autocomplete_result_single.html deleted file mode 100644 index d6f66fb..0000000 --- a/test/functional/_autocomplete_result_single.html +++ /dev/null @@ -1,3 +0,0 @@ -
      -
    • test1selectme1
    • -
    \ No newline at end of file diff --git a/test/functional/ajax_autocompleter2_test.html b/test/functional/ajax_autocompleter2_test.html deleted file mode 100644 index 53e8aec..0000000 --- a/test/functional/ajax_autocompleter2_test.html +++ /dev/null @@ -1,86 +0,0 @@ - - - - script.aculo.us Autocompleter functional test file - - - - - - - -

    script.aculo.us Autocompleter functional test file

    - - - -This is an incremental Ajax autocompleter. Type something, then type a comma, than type more. This autocompleter features an indicator.
    - -Autocompleter ac1: - - - - - -

    -Non-incremental Ajax autocompleter.
    -Autocompleter ac2: - - - - - -

    -Non-incremental Ajax autocompleter.
    -Autocompleter ac3: - - - - - -

    - -Local incremental array autocompleter ac4
    with full-search. Type 'Jac', hit enter a few
    times, type 'gne'.
    - - - -

    - -Local incremental array autocompleter ac5
    with fixed height and scrollbar. Type 'Jac', hit enter a few
    times, type 'gne'.
    - - - - - -


    -


    -
    - - - diff --git a/test/functional/ajax_autocompleter_test.html b/test/functional/ajax_autocompleter_test.html deleted file mode 100644 index e2e43d9..0000000 --- a/test/functional/ajax_autocompleter_test.html +++ /dev/null @@ -1,71 +0,0 @@ - - - - script.aculo.us Autocompleter functional test file - - - - - - - -

    script.aculo.us Autocompleter functional test file

    - - -Autocompleter ac1 (updated panel is relative, so no overlapping should occur): - - - - -
    - -Autocompleter ac2 w/ parameters: - - - - - -
    - -Autocompleter ac3 (nested in postion:relative div, selects "selectme" class): -
    -
    - - -
    - - - -
    - -

    -Autocompleter ac4 (autoselects option if single single option is returned): -
    - - - - - -
    - - - \ No newline at end of file diff --git a/test/functional/ajax_inplacecollectioneditor_test.html b/test/functional/ajax_inplacecollectioneditor_test.html deleted file mode 100644 index 773b715..0000000 --- a/test/functional/ajax_inplacecollectioneditor_test.html +++ /dev/null @@ -1,60 +0,0 @@ - - - - script.aculo.us Demo - - - - - - - -

    script.aculo.us Demo

    -

    - Demo of the Ajax.InPlaceCollectionEditor. -

    - -

    three

    (should autoselect "three") - - - -

    two

    (should autoselect "two") - - -

    three

    (should manually select "one") - - -

    one

    (should manually select "two") - - - - \ No newline at end of file diff --git a/test/functional/ajax_inplaceeditor_test.html b/test/functional/ajax_inplaceeditor_test.html deleted file mode 100644 index bffeb86..0000000 --- a/test/functional/ajax_inplaceeditor_test.html +++ /dev/null @@ -1,116 +0,0 @@ - - - - script.aculo.us Demo - - - - - - - -

    script.aculo.us Demo

    -

    - Demo of the Ajax.InPlaceEditor. -

    - -

    To be edited

    - - -

    To be edited w/ blur

    - - -

    To be edited w/ okLink and cancelButton

    - - -

    To be edited w/ okLink only

    - - - -With external edit control and custom parameter name   edit - - - - - - - - - -
    testedit
    - - - -

    Multi row editor: Lorum ipsum lorum ipsum lorum ipsum lorum ipsum lorum ipsum lorum ipsum lorum ipsum lorum ipsum lorum ipsum lorum ipsum lorum ipsum lorum ipsum lorum ipsum lorum ipsum lorum ipsum lorum ipsum lorum ipsum

    - - -

    Loads text from server

    - - -



















    -



















    -



















    - -

    Editor very far down to test scrolling bug

    - - - - \ No newline at end of file diff --git a/test/functional/dragdrop2_test.html b/test/functional/dragdrop2_test.html deleted file mode 100644 index 37ac6e8..0000000 --- a/test/functional/dragdrop2_test.html +++ /dev/null @@ -1,85 +0,0 @@ - - - - script.aculo.us Drag and drop functional test file - - - - - - - -

    script.aculo.us Drag and drop functional test file

    - -

    Draggables/Droppables

    - -
    - drag here
    - Revert? -
    - -
    - drag here
    - Revert? - I've onStart, onDrag and onEnd events!
    - -
    - -
    - This box overrides the default endeffect -
    - -
    - This box overrides the default starteffect -
    - -
    - This box overrides the default end- and starteffects -
    - -
    accepts first box
    -
    accepts second box
    - - - - - - \ No newline at end of file diff --git a/test/functional/dragdrop3_test.html b/test/functional/dragdrop3_test.html deleted file mode 100644 index 6fca7b0..0000000 --- a/test/functional/dragdrop3_test.html +++ /dev/null @@ -1,90 +0,0 @@ - - - - script.aculo.us Drag and drop functional test file - - - - - - - -

    script.aculo.us Drag and drop functional test file

    - -

    Draggables/Droppables

    - -
    - -
      -
    • Relatively here!
    • -
    • one
    • -
    • one
    • -
    • one
    • -
    • one
    • -
    • one
    • -
    • one
    • -
    • one
    • -
    • one
    • -
    • one
    • -
    • one
    • -
    • one
    • -
    • one
    • -
    • one
    • -
    • one
    • -
    • one
    • -
    • one
    • -
    • one
    • -
    • one
    • -
    • one
    • -
    • one
    • -
    • one
    • -
    • one
    • -
    • one
    • -
    • one
    • -
    • one
    • -
    • one
    • -
    • one
    • -
    • one
    • -
    • one
    • -
    • one
    • -
    • one
    • -
    • one
    • -
    • one
    • -
    • one
    • -
    • one
    • -
    • one
    • -
    • one
    • -
    • one
    • -
    • one
    • -
    • one
    • -
    • one
    • -
    • one
    • -
    • one
    • -
    • one
    • -
    • one
    • -
    • one
    • -
    • one
    • -
    • one
    • -
    • one
    • -
    • one
    • -
    - -
    - -
    
    -
    -
    -
    -
    -
    \ No newline at end of file
    diff --git a/test/functional/dragdrop4_test.html b/test/functional/dragdrop4_test.html
    deleted file mode 100644
    index 56ec04e..0000000
    --- a/test/functional/dragdrop4_test.html
    +++ /dev/null
    @@ -1,41 +0,0 @@
    -
    -
    -
    -  script.aculo.us Drag and drop functional test file
    -  
    -  
    -  
    -  
    -
    -
    -
    -(inside position:relative container) -

    script.aculo.us Drag and drop functional test file

    - -

    Draggables/Droppables

    - -
    - Ghosting effect - -
    test!
    -
    -
    - -alert contents of test div - -
    - Ghost effect
    -
    - - -
    - - \ No newline at end of file diff --git a/test/functional/dragdrop5_test.html b/test/functional/dragdrop5_test.html deleted file mode 100644 index c84f9e1..0000000 --- a/test/functional/dragdrop5_test.html +++ /dev/null @@ -1,42 +0,0 @@ - - -script.aculo.us Drag and drop functional test file - - - - - - - -

    script.aculo.us Drag and drop functional test file

    - -

    w/o hoverclass

    - -
    -### DROP HERE ### -
    - - - -
    - -Product2 <-- drag this! - - - -

    w/ hoverclass

    - - -
    -### DROP HERE ### -
    - - - - - - \ No newline at end of file diff --git a/test/functional/dragdrop6_test.html b/test/functional/dragdrop6_test.html deleted file mode 100644 index 23ade0a..0000000 --- a/test/functional/dragdrop6_test.html +++ /dev/null @@ -1,76 +0,0 @@ - - - - script.aculo.us Drag and drop functional test file - - - - - - - -

    script.aculo.us Drag and drop functional test file

    - -

    Draggables/Droppables

    - -
    - Normal box -
    - -
    - snap: 25 -
    - -
    - snap: [5,25] -
    - -
    - snap: procedural (e.g. constrain to box) -
    - -
    -
    - snap: procedural (e.g. constrain to parent element) -
    -
    - - - - - - \ No newline at end of file diff --git a/test/functional/dragdrop7_test.html b/test/functional/dragdrop7_test.html deleted file mode 100644 index dd74db1..0000000 --- a/test/functional/dragdrop7_test.html +++ /dev/null @@ -1,211 +0,0 @@ - - - - - - - - - - - - -
    -
    -

    Shrink your window until the right-hand pane is scrollable.

    -

    Drag from the list on left to groups on the right, force the right-hand pane to scroll.

    - -
    -
      -
    • One
    • -
    • Two
    • -
    • Three
    • -
    • Four
    • -
    • Five
    • -
    • Six
    • -
    • Seven
    • -
    • Eight
    • -
    -
    - -
    - -
    -

    Group 1

    -
      -
      -
      -

      Group 2

      -
        -
        -
        -

        Group 3

        -
          -
          -
          -

          Group 4

          -
            -
            -
            -

            Group 5

            -
              -
              -
              -

              Group 6

              -
                -
                -
                -

                Group 7

                -
                  -
                  -
                  -

                  Group 8

                  -
                    -
                    -
                    -

                    Group 9

                    -
                      -
                      -
                      - - \ No newline at end of file diff --git a/test/functional/dragdrop8_test.html b/test/functional/dragdrop8_test.html deleted file mode 100644 index a6a0ff5..0000000 --- a/test/functional/dragdrop8_test.html +++ /dev/null @@ -1,142 +0,0 @@ - - -Drag & Drop - - - - - - - - - -

                      Drag from this table:

                      -
                      -
                      - - - - - - - - - - - -
                      one1uno
                      two2dos
                      three3tres
                      four4quatro
                      five5cinco
                      six6seis
                      seven7siete
                      eight8ocho
                      nine9nueve
                      ten10diez
                      -
                      -
                      -

                      -

                      Drop on this table:

                      -
                      -
                      - - - - - - - - - - - -
                      eleven11once
                      twelve12doce
                      thirteen13trece
                      fourteen14catorce
                      fifteen15quince
                      sixteen16dieciseis
                      seventeen17diecisiete
                      eightteen18dieciocho
                      nineteen19diecinueve
                      twenty20veinte
                      -
                      -
                      -

                      -

                      -

                      - - \ No newline at end of file diff --git a/test/functional/dragdrop9_test.html b/test/functional/dragdrop9_test.html deleted file mode 100644 index c7d44d0..0000000 --- a/test/functional/dragdrop9_test.html +++ /dev/null @@ -1,47 +0,0 @@ - - - - - - - - - -
                      - Draggable -
                      - - -
                      - -
                      - Good Target -
                      - - - -
                      - - - \ No newline at end of file diff --git a/test/functional/dragdrop_delay_test.html b/test/functional/dragdrop_delay_test.html deleted file mode 100644 index df60977..0000000 --- a/test/functional/dragdrop_delay_test.html +++ /dev/null @@ -1,84 +0,0 @@ - - - - - - script.aculo.us functional test - - - - - - - - -

                      No delay sortable

                      - -
                        -
                      • one
                      • - -
                      • two
                      • - -
                      • three
                      • -
                      - -

                      Delayed sortable (500 ms)

                      - -
                        -
                      • one
                      • - -
                      • two
                      • - -
                      • three
                      • -
                      - -

                      No delay draggable

                      - -
                      - Lorem ipsum -
                      - -

                      Delayed draggable (1000 ms)

                      - -
                      - Lorem ipsum -
                      - - - - diff --git a/test/functional/dragdrop_test.html b/test/functional/dragdrop_test.html deleted file mode 100644 index 1079f37..0000000 --- a/test/functional/dragdrop_test.html +++ /dev/null @@ -1,120 +0,0 @@ - - - - script.aculo.us Drag and drop functional test file - - - - - - - -

                      script.aculo.us Drag and drop functional test file

                      - -

                      Draggables/Droppables

                      - -inspect sortables - -
                      - drag here - (but not here)
                      - Revert? -
                      - -
                      - drag here
                      - Revert? -
                      - -
                      testtest
                      - - - - - - -
                        -
                      • Hey there! I'm absolutely positioned
                      • -
                      • one
                      • -
                      • two
                      • -
                      • three
                      • -
                      - -
                        -
                      • Relatively here!
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      - - - - - - - \ No newline at end of file diff --git a/test/functional/dropmarker.png b/test/functional/dropmarker.png deleted file mode 100644 index 77d7387..0000000 Binary files a/test/functional/dropmarker.png and /dev/null differ diff --git a/test/functional/effect_direct_test.html b/test/functional/effect_direct_test.html deleted file mode 100644 index cff8ad7..0000000 --- a/test/functional/effect_direct_test.html +++ /dev/null @@ -1,35 +0,0 @@ - - - - script.aculo.us Effects functional test file - - - - - - - - -

                      script.aculo.us Effects functional test file

                      - -Highlight | -BlindUp | -BlindDown | -SlideUp | -SlideDown - -
                      -Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas enim. Nulla facilisi. Vestibulum accumsan augue vulputate justo. Fusce faucibus. Sed blandit, neque sed lacinia nonummy, diam quam imperdiet justo, at dictum augue nunc a neque. Sed urna lacus, tincidunt at, aliquam id, fringilla id, felis. Vivamus feugiat molestie quam. Sed id dolor. Sed ac purus id sapien sollicitudin ultricies. Aliquam hendrerit orci et odio. Suspendisse volutpat wisi at sem. Integer eget nulla. Duis eu diam a nunc condimentum tempus. Praesent gravida metus vitae massa. Aliquam neque magna, fringilla eu, porta id, interdum sit amet, dui. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin lorem est, ultrices sit amet, condimentum vitae, vehicula a, massa. -
                      - -
                      -Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas enim. Nulla facilisi. Vestibulum accumsan augue vulputate justo. Fusce faucibus. Sed blandit, neque sed lacinia nonummy, diam quam imperdiet justo, at dictum augue nunc a neque. Sed urna lacus, tincidunt at, aliquam id, fringilla id, felis. Vivamus feugiat molestie quam. Sed id dolor. Sed ac purus id sapien sollicitudin ultricies. Aliquam hendrerit orci et odio. Suspendisse volutpat wisi at sem. Integer eget nulla. Duis eu diam a nunc condimentum tempus. Praesent gravida metus vitae massa. Aliquam neque magna, fringilla eu, porta id, interdum sit amet, dui. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin lorem est, ultrices sit amet, condimentum vitae, vehicula a, massa. -
                      - - - \ No newline at end of file diff --git a/test/functional/effect_puff_test.html b/test/functional/effect_puff_test.html deleted file mode 100644 index 47a3cb0..0000000 --- a/test/functional/effect_puff_test.html +++ /dev/null @@ -1,65 +0,0 @@ - - - - script.aculo.us Effects functional test file - - - - - - -

                      script.aculo.us Effects functional test file

                      - -

                      Effect.Puff

                      - -
                      - click to test puff, no position set -
                      - -
                      - click to test puff, floats -
                      - -
                      - click to test puff, absolute position set -
                      - -

                      Floating inside a container

                      - -
                      -
                      - click to puff -
                      -
                      - click to puff -
                      -
                      - click to puff -
                      -
                      - click to puff -
                      -
                      - click to puff -
                      -
                      - click to puff -
                      -
                      - click to puff -
                      -
                      - click to puff -
                      -
                      - click to puff -
                      -
                      - - - - - \ No newline at end of file diff --git a/test/functional/effect_scale_test.html b/test/functional/effect_scale_test.html deleted file mode 100644 index 215205d..0000000 --- a/test/functional/effect_scale_test.html +++ /dev/null @@ -1,29 +0,0 @@ - - - - script.aculo.us Effects functional test file - - - - - - - - -

                      script.aculo.us Effects functional test file

                      - -Scale X only | -Scale Y only | -Scale X and Y - -
                      -Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas enim. Nulla facilisi. Vestibulum accumsan augue vulputate justo. Fusce faucibus. Sed blandit, neque sed lacinia nonummy, diam quam imperdiet justo, at dictum augue nunc a neque. Sed urna lacus, tincidunt at, aliquam id, fringilla id, felis. Vivamus feugiat molestie quam. Sed id dolor. Sed ac purus id sapien sollicitudin ultricies. Aliquam hendrerit orci et odio. Suspendisse volutpat wisi at sem. Integer eget nulla. Duis eu diam a nunc condimentum tempus. Praesent gravida metus vitae massa. Aliquam neque magna, fringilla eu, porta id, interdum sit amet, dui. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin lorem est, ultrices sit amet, condimentum vitae, vehicula a, massa. -
                      - - - \ No newline at end of file diff --git a/test/functional/effect_shake.html b/test/functional/effect_shake.html deleted file mode 100644 index c65848c..0000000 --- a/test/functional/effect_shake.html +++ /dev/null @@ -1,55 +0,0 @@ - - - - script.aculo.us Effects functional test file - - - - - -

                      script.aculo.us Effect.shake functional test file

                      - -

                      Effect.Shake

                      - -
                      - - -shake
                      -shake 2
                      -shake 30
                      -shake 60
                      - - - -shake these
                      - - - - - -
                      shake 10
                      -
                      shake 20
                      -
                      shake 30
                      - -shake slow
                      -shake fast
                      - -shake 2 slow
                      -shake 60 fast
                      - - - - diff --git a/test/functional/effects2_test.html b/test/functional/effects2_test.html deleted file mode 100644 index f88581e..0000000 --- a/test/functional/effects2_test.html +++ /dev/null @@ -1,63 +0,0 @@ - - - - -Untitled Document - - - - - - - - - diff --git a/test/functional/effects3_test.html b/test/functional/effects3_test.html deleted file mode 100644 index dfd2e97..0000000 --- a/test/functional/effects3_test.html +++ /dev/null @@ -1,36 +0,0 @@ - - - - script.aculo.us Effects functional test file - - - - - - -

                      script.aculo.us Effects functional test file

                      - -

                      Effect.SlideDown/Effect.SlideUp

                      - - - -Start slide down | -Start slide up | -cancel() | -inspect() | -add content - - - - - - \ No newline at end of file diff --git a/test/functional/effects4_test.html b/test/functional/effects4_test.html deleted file mode 100644 index e71bee9..0000000 --- a/test/functional/effects4_test.html +++ /dev/null @@ -1,31 +0,0 @@ - - - - script.aculo.us Effects functional test file - - - - - - - - -

                      script.aculo.us Effects functional test file

                      - -Highlight | -BlindUp | -BlindDown | -SlideUp | -SlideDown - -
                      -Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas enim. Nulla facilisi. Vestibulum accumsan augue vulputate justo. Fusce faucibus. Sed blandit, neque sed lacinia nonummy, diam quam imperdiet justo, at dictum augue nunc a neque. Sed urna lacus, tincidunt at, aliquam id, fringilla id, felis. Vivamus feugiat molestie quam. Sed id dolor. Sed ac purus id sapien sollicitudin ultricies. Aliquam hendrerit orci et odio. Suspendisse volutpat wisi at sem. Integer eget nulla. Duis eu diam a nunc condimentum tempus. Praesent gravida metus vitae massa. Aliquam neque magna, fringilla eu, porta id, interdum sit amet, dui. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin lorem est, ultrices sit amet, condimentum vitae, vehicula a, massa. -
                      - - - \ No newline at end of file diff --git a/test/functional/effects5_test.html b/test/functional/effects5_test.html deleted file mode 100644 index 344d6eb..0000000 --- a/test/functional/effects5_test.html +++ /dev/null @@ -1,483 +0,0 @@ - - - - script.aculo.us Effects functional test file - - - - - - -

                      script.aculo.us ScrollTo effect functional test

                      - -scroll (slow-mo) down-below..., -scroll last-heading - -

                      first-headingHeading 2

                      -
                        -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      - -

                      Heading 2

                      -
                        -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      - -

                      Heading 2

                      -
                        -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      - -

                      Heading 2

                      -
                        -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      - -

                      Heading 2

                      -
                        -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      - -

                      Heading 2

                      -
                        -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      - -

                      Heading 2

                      -
                        -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      - -

                      Heading 2

                      -
                        -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      - -

                      Heading 2

                      -
                        -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      - -

                      Heading 2

                      -
                        -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      - -

                      Heading 2

                      -
                        -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      - -

                      Heading 2

                      -
                        -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      - -

                      DOWN BELOWHeading 2

                      -
                        -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      - -scroll... - -

                      Heading 2

                      -
                        -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      - -

                      Heading 2

                      -
                        -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      - -

                      Heading 2

                      -
                        -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      - -

                      Heading 2

                      -
                        -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      - -

                      Heading 2

                      -
                        -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      - -

                      Heading 2

                      -
                        -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      - -

                      Heading 2

                      -
                        -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      - -

                      Heading 2

                      -
                        -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      - -

                      Heading 2

                      -
                        -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      - -

                      Heading 2

                      -
                        -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      - -

                      Heading 2

                      -
                        -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      - -

                      Heading 2

                      -
                        -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      - -

                      Heading 2

                      -
                        -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      - -

                      Heading 2

                      -
                        -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      - -

                      Heading 2

                      -
                        -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      - -

                      Heading 2

                      -
                        -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      - -

                      Heading 2

                      -
                        -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      - -

                      Heading 2

                      -
                        -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      - -

                      Heading 2

                      -
                        -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      - -

                      Heading 2

                      -
                        -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      • item
                      • -
                      - - - - \ No newline at end of file diff --git a/test/functional/effects5b_test.html b/test/functional/effects5b_test.html deleted file mode 100644 index 160f29d..0000000 --- a/test/functional/effects5b_test.html +++ /dev/null @@ -1,39 +0,0 @@ - - - - script.aculo.us Effects functional test file - - - - - - - -
                       
                      - -

                      script.aculo.us ScrollTo effect (with floats) functional test

                      - -(this test only applies to Firefox) - -
                      - -

                      top of float

                      - - scroll to bottom! - -
                       
                      - -

                      Bottom of Float

                      - - w00t - -
                      - - - - - - \ No newline at end of file diff --git a/test/functional/effects6_test.html b/test/functional/effects6_test.html deleted file mode 100644 index fe1f9b0..0000000 --- a/test/functional/effects6_test.html +++ /dev/null @@ -1,61 +0,0 @@ - - - - script.aculo.us Effects functional test file - - - - - - -

                      script.aculo.us Fade/Appear effect functional test

                      -

                      Note: these tests use the browser default CSS style rules.

                      - -

                      DIV

                      -
                      TEST
                      -Effect.Fade | -Effect.Appear - -

                      SPAN

                      -TEST
                      -Effect.Fade | -Effect.Appear - -

                      P

                      -

                      TEST


                      -Effect.Fade | -Effect.Appear - -

                      IMG

                      -test image
                      -Effect.Fade | -Effect.Appear - - -
                      - -

                      The following elements are not supported with Fade/Appear on all browsers!

                      - -

                      TABLE

                      -
                      TEST
                      -Effect.Fade | -Effect.Appear - -

                      TBODY

                      -
                      TEST
                      -Effect.Fade | -Effect.Appear - -

                      TR

                      -
                      TEST
                      -Effect.Fade | -Effect.Appear - -

                      TD

                      -
                      TEST
                      -Effect.Fade | -Effect.Appear - - - \ No newline at end of file diff --git a/test/functional/effects_blind_test.html b/test/functional/effects_blind_test.html deleted file mode 100644 index b469a11..0000000 --- a/test/functional/effects_blind_test.html +++ /dev/null @@ -1,65 +0,0 @@ - - - - script.aculo.us Effects functional test file - - - - - - - - -

                      script.aculo.us Effects functional test file

                      - -

                      Effect.BlindUp/Effect.BlindDown

                      - -
                      - Lorem ipsum dolor sit amet -
                        -
                      • test!
                      • -
                      • test!
                      • -
                      - test! - test! - test! - test! - test! - test! - test! - test! - test! - test! - Lorem ipsum dolor sit amet -
                        -
                      • test!
                      • -
                      • test!
                      • -
                      - Lorem ipsum dolor sit amet -
                        -
                      • test!
                      • -
                      • test!
                      • -
                      - Lorem ipsum dolor sit amet -
                        -
                      • test!
                      • -
                      • test!
                      • -
                      -
                      - -

                      - BlindDown() -

                      - -

                      - BlindUp() -

                      - - - - \ No newline at end of file diff --git a/test/functional/effects_float_appear_test.html b/test/functional/effects_float_appear_test.html deleted file mode 100644 index 1a52725..0000000 --- a/test/functional/effects_float_appear_test.html +++ /dev/null @@ -1,46 +0,0 @@ - - - - script.aculo.us Effects functional test file - - - - - - -

                      script.aculo.us functional test file

                      -

                      - See if workaround for Safari and floating elements with Effect.Appear works. -

                      - -float:left | -float:right | -float:right (setOpacity 1) | -image (non-floating) | -image (floating) | -image (setOpacity 1) - -
                      - - - -
                      - Lorem ipsum dolor sit amet,
                      - consectetur adipisicing elit,
                      - sed do eiusmod tempor incididunt
                      - ut labore et dolore magna aliqua. -
                      - - - - - - - - \ No newline at end of file diff --git a/test/functional/effects_grow_strink_test.html b/test/functional/effects_grow_strink_test.html deleted file mode 100644 index 9607d35..0000000 --- a/test/functional/effects_grow_strink_test.html +++ /dev/null @@ -1,38 +0,0 @@ - - - - script.aculo.us Effects functional test file - - - - - - - - -

                      script.aculo.us Effects functional test file

                      - -

                      Effect.Grow/Effect.Shrink

                      - -
                      -

                      Lorem ipsum dolor sit amet

                      -
                      - -

                      - Grow: - Grow() -

                      - -

                      - Shrink: - Shrink() -

                      - - - - \ No newline at end of file diff --git a/test/functional/effects_highlight_bg_image.html b/test/functional/effects_highlight_bg_image.html deleted file mode 100644 index cb0adf2..0000000 --- a/test/functional/effects_highlight_bg_image.html +++ /dev/null @@ -1,57 +0,0 @@ - - - - - - - - - - -

                      Test of keepBackgroundImage parameter for Effect.Highlight. Click items to show effect.

                      -

                      With the keepBackgroundImage parameter.

                      -
                        -
                      • One
                      • -
                      • Two
                      • -
                      • Three
                      • -
                      - -

                      Without the parameter.

                      -
                        -
                      • One
                      • -
                      • Two
                      • -
                      • Three
                      • -
                      - - \ No newline at end of file diff --git a/test/functional/effects_queue_limit_test.html b/test/functional/effects_queue_limit_test.html deleted file mode 100644 index 64a7842..0000000 --- a/test/functional/effects_queue_limit_test.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - script.aculo.us Effects functional test file - - - - - - - - -

                      script.aculo.us Effects functional test file

                      - -

                      Effect.Queue limit

                      - -up -down -
                      - Do a bit sliding in parallel, with a scoped queue, but I am limited to one : ) so don't try over and over again... -
                      - - - \ No newline at end of file diff --git a/test/functional/effects_queue_test.html b/test/functional/effects_queue_test.html deleted file mode 100644 index 753cb8a..0000000 --- a/test/functional/effects_queue_test.html +++ /dev/null @@ -1,67 +0,0 @@ - - - - script.aculo.us Effects functional test file - - - - - - - - -

                      script.aculo.us Effects functional test file

                      - -

                      Effect.Queue

                      - -
                      -

                      Lorem ipsum dolor sit amet

                      -
                      - -
                      -

                      Lorem ipsum dolor sit amet

                      -
                      - -
                      -

                      Lorem ipsum dolor sit amet

                      -
                      - -
                      - Start queued effects (in 'global' queue) -
                      - - - - - - - - \ No newline at end of file diff --git a/test/functional/effects_random_demo.html b/test/functional/effects_random_demo.html deleted file mode 100644 index 5f6fef3..0000000 --- a/test/functional/effects_random_demo.html +++ /dev/null @@ -1,76 +0,0 @@ - - - - script.aculo.us Effects functional test file - - - - - - - -

                      Random effects demo

                      -Start... | -Show/hide log - -
                      -DIV1 -
                      - -
                      -DIV2 -
                      - -
                      -DIV3 -
                      - -
                      -DIV4 -
                      - -
                      -DIV5 -
                      - -
                      -DIV6 -
                      - -
                      -DIV7 -
                      - -
                      -DIV8 -
                      - -
                      -DIV9 -
                      - - - - - \ No newline at end of file diff --git a/test/functional/effects_test.html b/test/functional/effects_test.html deleted file mode 100644 index 55307d9..0000000 --- a/test/functional/effects_test.html +++ /dev/null @@ -1,74 +0,0 @@ - - - - script.aculo.us Effects functional test file - - - - - -

                      script.aculo.us Effects functional test file

                      - -

                      Effect.Highlight

                      - -
                      - -asdasd - -
                      - - (highlight to red) - -
                      - -
                      - (highlight to greenish) -
                      - -
                      - (bottom-right-grow) -
                      - -
                      - click to test shake -
                      - -
                      - click to test puff -
                      -

                      - update callbacks: (waiting) -- (waiting) -

                      -show puff div again - -test appear - - -test grow - - -test pulsate default times (5) -test pulsate 2 times -
                      - pulsate -
                      - - - - - \ No newline at end of file diff --git a/test/functional/effects_toggle_test.html b/test/functional/effects_toggle_test.html deleted file mode 100644 index d2add64..0000000 --- a/test/functional/effects_toggle_test.html +++ /dev/null @@ -1,36 +0,0 @@ - - - - script.aculo.us Effects functional test file - - - - - - -

                      script.aculo.us Effect.toggle functional test file

                      - -Toggle slide - - -Toggle blind - - - -Toggle appear - - - - - - \ No newline at end of file diff --git a/test/functional/icon.png b/test/functional/icon.png deleted file mode 100644 index f752986..0000000 Binary files a/test/functional/icon.png and /dev/null differ diff --git a/test/functional/index.html b/test/functional/index.html deleted file mode 100644 index 72ff3c4..0000000 --- a/test/functional/index.html +++ /dev/null @@ -1,91 +0,0 @@ - - - - script.aculo.us functional tests - - - - - - - - -

                      script.aculo.us
                      Functional Tests

                      - -

                      - - - -

                      Documentation

                      - -

                      Effects

                      - - -

                      Controls

                      - - -

                      Drag & Drop

                      - - -

                      Sound (experimental)

                      - - -

                      Miscellaneous

                      - - - - \ No newline at end of file diff --git a/test/functional/position_clone_test.html b/test/functional/position_clone_test.html deleted file mode 100644 index 58907fb..0000000 --- a/test/functional/position_clone_test.html +++ /dev/null @@ -1,124 +0,0 @@ - - - - prototype.js Position.clone functional test - - - - - - - - -
                      - -
                      - -
                      - abs -
                      - -
                      - rel -
                      - -
                      - static -
                      - -
                      - -
                      - -
                      - abs-body child -
                      - -

                      - unpositioned p -

                      - - - -
                      - Toggle page scrolling | - Page margings: on | - off -

                      - Absolute marker in position:relative container DIV:
                      - Mark abs | - Mark rel | - Mark static | - Mark abs-body child | - Mark p -

                      - Hidden marker (display:none), in position:relative container DIV switched on when clone is finished:
                      - Mark abs | - Mark rel | - Mark static | - Mark abs-body child | - Mark p -

                      - Absolute marker, child of BODY:
                      - Mark abs | - Mark rel | - Mark static | - Mark abs-body child | - Mark p -

                      - Fixed marker, child of BODY:
                      - Mark abs | - Mark rel | - Mark static | - Mark abs-body child | - Mark p | -
                      -
                      - -
                      -
                      -
                      !
                      -
                      - -
                      - - - -
                      !
                      - -
                      !
                      - - - - - diff --git a/test/functional/slider_test.html b/test/functional/slider_test.html deleted file mode 100644 index 719686c..0000000 --- a/test/functional/slider_test.html +++ /dev/null @@ -1,152 +0,0 @@ - - - - - Text effects tests - - - - - -

                      Sliders

                      - -

                      Standard horizontal slider

                      - -
                      -
                      -
                      - -

                      - -

                      Vertical slider

                      - -
                      -
                      -
                      - -

                      - -

                      Slider with predefined values [2,4,6,8] and a non-default range [2,15]

                      - -
                      -
                      -
                      - -

                      - -

                      Slider with multiple handles

                      - -
                      -
                      -
                      -
                      -
                      - -

                      - -

                      Slider with multiple handles and predefined values

                      - -
                      -
                      -
                      -
                      -
                      - -

                      - -

                      Slider with multiple handles, external controls, handles are restricted (can't be moved prior/after adjacent handles)

                      - -
                      -
                      -
                      -
                      - -

                      - <-- - --> - -

                      - -

                      Fun with spans

                      - - - -
                      -
                      1
                      -
                      2
                      -
                      3
                      - -
                      -
                      - -
                      -
                      -
                      - -



                      - -

                      Slider with span and [1,10] range (test for #3731)

                      - -
                      -
                      !
                      -
                      !
                      -
                      -
                      - - - - - - - - \ No newline at end of file diff --git a/test/functional/sortable2_test.html b/test/functional/sortable2_test.html deleted file mode 100644 index 61ea03c..0000000 --- a/test/functional/sortable2_test.html +++ /dev/null @@ -1,148 +0,0 @@ - - - - script.aculo.us Sortable ghosting functional test file - - - - - - - - -

                      script.aculo.us Sortable ghosting functional test file

                      - -

                      Ghosting

                      - -
                        -
                      • Lorem ipsum dolor
                      • -
                      • sit amet
                      • -
                      • consectetur adipisicing
                      • -
                      • elit
                      • -
                      • sed do eiusmod
                      • -
                      • tempor incididunt
                      • -
                      • ut labore et dolore
                      • -
                      • magna aliqua
                      • -
                      - -

                      (waiting for onChange)

                      - - - -

                      No ghosting

                      - -
                        -
                      • Lorem ipsum dolor
                      • -
                      • sit amet
                      • -
                      • consectetur adipisicing
                      • -
                      • elit
                      • -
                      • sed do eiusmod
                      • -
                      • tempor incididunt
                      • -
                      • ut labore et dolore
                      • -
                      • magna aliqua
                      • -
                      - -

                      (waiting for onChange)

                      - - - -

                      Ghosting (inside position:relative container)

                      -
                      -
                        -
                      • Lorem ipsum dolor
                      • -
                      • sit amet
                      • -
                      • consectetur adipisicing
                      • -
                      • elit
                      • -
                      • sed do eiusmod
                      • -
                      • tempor incididunt
                      • -
                      • ut labore et dolore
                      • -
                      • magna aliqua
                      • -
                      -
                      -

                      (waiting for onChange)

                      - - - - -

                      Ghosting (inside position:relative container)

                      -
                      -
                        -
                      • Lorem ipsum dolor
                      • -
                      • sit amet
                      • -
                      • consectetur adipisicing
                      • -
                      • elit
                      • -
                      • sed do eiusmod
                      • -
                      • tempor incididunt
                      • -
                      • ut labore et dolore
                      • -
                      • magna aliqua
                      • -
                      -
                      -

                      (waiting for onChange)

                      - - - - -
                      - - - \ No newline at end of file diff --git a/test/functional/sortable3_test.html b/test/functional/sortable3_test.html deleted file mode 100644 index 8d9e104..0000000 --- a/test/functional/sortable3_test.html +++ /dev/null @@ -1,40 +0,0 @@ - - - - script.aculo.us sortable functional test file - - - - - - - - -

                      script.aculo.us Sortable two-lists w/ dropOnEmpty functional test file

                      - -
                        -
                      • Hey there! I'm item#1/1
                      • -
                      • Hey there! I'm item#1/2
                      • -
                      • Hey there! I'm item#1/3
                      • -
                      - -
                        -
                      - - - -Serialize sortable1 -Serialize sortable2 - -
                      - - - \ No newline at end of file diff --git a/test/functional/sortable4_test.html b/test/functional/sortable4_test.html deleted file mode 100644 index f80ce5f..0000000 --- a/test/functional/sortable4_test.html +++ /dev/null @@ -1,88 +0,0 @@ - - - - script.aculo.us sortable functional test file - - - - - - - - -

                      script.aculo.us: Two floating sortables with containment and dropOnEmpty

                      - -
                      -
                      -

                      This is the first list

                      -
                        -
                      • Item 1 from first list.
                      • -
                      • Item 2 from first list.
                      • -
                      • Item 3 from first list.
                      • -
                      -
                      -
                      -

                      And now the second list

                      -
                        -
                      • - DRAG HERE Item 1 from second list. -
                      • -
                      • - DRAG HERE Item 2 from second list. -
                      • -
                      • - DRAG HERE Item 3 from second list. -
                      • -
                      -
                      -
                      - -
                      - -
                      
                      -
                      
                      -
                      - 
                      - 
                      - 
                      - 
                      \ No newline at end of file
                      diff --git a/test/functional/sortable5_test.html b/test/functional/sortable5_test.html
                      deleted file mode 100644
                      index 52c39e1..0000000
                      --- a/test/functional/sortable5_test.html
                      +++ /dev/null
                      @@ -1,43 +0,0 @@
                      -
                      -
                      -
                      -  script.aculo.us sortable functional test file
                      -  
                      -  
                      -  
                      -  
                      -  
                      -
                      -
                      -  
                      -  
                      - -
                      - - - - - \ No newline at end of file diff --git a/test/functional/sortable6_test.html b/test/functional/sortable6_test.html deleted file mode 100644 index b802f10..0000000 --- a/test/functional/sortable6_test.html +++ /dev/null @@ -1,148 +0,0 @@ - - - script.aculo.us Drag and drop functional test file - - - - - - -

                      script.aculo.us Drag and drop functional test file

                      - -

                      Scroll window down to test autoscrolling inside scrollable elements when window is scrolled

                      - -

                      Draggables/Droppables

                      - -
                      - -
                        -
                      • Relatively here!
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      - -
                      -

                      Some space in between

                      -
                      - -
                        -
                      • Relatively here!
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      • one
                      • -
                      - -
                      - -
                      
                      -
                      -
                      -
                      -
                      \ No newline at end of file
                      diff --git a/test/functional/sortable_nested_test.html b/test/functional/sortable_nested_test.html
                      deleted file mode 100644
                      index 74a7e57..0000000
                      --- a/test/functional/sortable_nested_test.html
                      +++ /dev/null
                      @@ -1,57 +0,0 @@
                      -
                      -
                      -  Nested Sortable element bug
                      -  
                      -  
                      -
                      -
                      -
                      -
                        - -
                      • -

                        COLLEGE AVE

                        -
                          -
                        • 625
                        • -
                        • 617
                        • -
                        • 601
                        • -
                        -
                      • - -
                      • -

                        Right COLLEGE CT

                        -
                          -
                        • 14
                        • -
                        • 27
                        • -
                        • 30
                        • -
                        -
                      • -
                      - - - - \ No newline at end of file diff --git a/test/functional/sortable_test.html b/test/functional/sortable_test.html deleted file mode 100644 index e86babe..0000000 --- a/test/functional/sortable_test.html +++ /dev/null @@ -1,141 +0,0 @@ - - - - script.aculo.us sortable functional test file - - - - - - - - - -
                        -
                      • Hey there! I'm item#1
                      • -
                      • Hey there! I'm item#2
                      • -
                      • Hey there! I'm item#3
                      • -
                      - -Create sortable | -Destroy sortable | -Serialize sortable - -
                        -
                      • Hey there! I'm item#1HANDLE -SSSSSSSS -SSSSSSSS -SSSSSSSS -SSSSSSSS -SSSSSSSS -SSSSSSSS -SSSSSSSS -SSSSSSSS -SSSSSSSS -SSSSSSSS -SSSSSSSS -SSSSSSSS -SSSSSSSS -SSSSSSSS -SSSSSSSS -SSSSSSSS -SSSSSSSS -
                      • -
                      • Hey there! I'm item#2HANDLE -SSSSSSSS -SSSSSSSS -SSSSSSSS -SSSSSSSS -SSSSSSSS -SSSSSSSS -SSSSSSSS -SSSSSSSS -SSSSSSSS -SSSSSSSS -SSSSSSSS -SSSSSSSS -SSSSSSSS -SSSSSSSS -SSSSSSSS -SSSSSSSS -SSSSSSSS -
                      • -
                      • Hey there! I'm item#3HANDLE -SSSSSSSS -SSSSSSSS -SSSSSSSS -SSSSSSSS -SSSSSSSS -SSSSSSSS -SSSSSSSS -SSSSSSSS -SSSSSSSS -SSSSSSSS -SSSSSSSS -SSSSSSSS -SSSSSSSS -SSSSSSSS -SSSSSSSS -SSSSSSSS -SSSSSSSS -
                      • -
                      - -Create sortable | -Destroy sortable | -Serialize sortable - -

                      no calls to onUpdate

                      - -
                        -
                      • s1 handle
                      • -
                      • s2 handle
                      • -
                      • s3 handle
                      • -
                      • s4 handle
                      • -
                      • s5 handle
                      • -
                      • s6 handle
                      • -
                      • s7 handle
                      • -
                      • s8 handle
                      • -
                      • s9 handle
                      • -
                      • s10 handle
                      • -
                      - - - -20 times: Init with Preselection | -Init normally - - - \ No newline at end of file diff --git a/test/functional/sortable_tree_test.html b/test/functional/sortable_tree_test.html deleted file mode 100644 index 4315373..0000000 --- a/test/functional/sortable_tree_test.html +++ /dev/null @@ -1,185 +0,0 @@ - - - - - Sortable tree test - - - - - - - serialize 1 - - - - - - - - - - - diff --git a/test/functional/sound_test.html b/test/functional/sound_test.html deleted file mode 100644 index 91edd03..0000000 --- a/test/functional/sound_test.html +++ /dev/null @@ -1,21 +0,0 @@ - - - - script.aculo.us Sound functional test file - - - - - -

                      script.aculo.us Sound test file

                      - -play sound (parallel) - -play sound (overwrite) - -Mute -Enable sounds - - - diff --git a/test/functional/sword.mp3 b/test/functional/sword.mp3 deleted file mode 100644 index 9bfda65..0000000 Binary files a/test/functional/sword.mp3 and /dev/null differ diff --git a/test/functional/texteffects_test.html b/test/functional/texteffects_test.html deleted file mode 100644 index b7e3807..0000000 --- a/test/functional/texteffects_test.html +++ /dev/null @@ -1,52 +0,0 @@ - - - - Text effects tests - - - - - -

                      - Maybe this is useful? blah Dunno... -

                      - Appear | - Fade | - DropOut | - show H1 innerHTML -

                      - Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. -

                      -

                      THIS IS A WARNING!

                      -

                      - Appear | - Fade | - DropOut -

                      - -
                      1234567890ABCDEFG
                      -
                      - - Appear | - Fade | - DropOut | - Highlight | - BlindDown - - - -

                      - - Fade all spans on page -

                      - - - \ No newline at end of file diff --git a/test/run_functional_tests.html b/test/run_functional_tests.html deleted file mode 100644 index bd26745..0000000 --- a/test/run_functional_tests.html +++ /dev/null @@ -1,20 +0,0 @@ - - - - - script.aculo.us functional tests - - - - - - - - - <body> - Heya, 1995! - </body> - - - \ No newline at end of file diff --git a/test/run_unit_tests.html b/test/run_unit_tests.html deleted file mode 100644 index 969f21a..0000000 --- a/test/run_unit_tests.html +++ /dev/null @@ -1,20 +0,0 @@ - - - - - script.aculo.us Unit Test Runner - - - - - - - - - <body> - Heya, 1995! - </body> - - - \ No newline at end of file diff --git a/test/test.css b/test/test.css deleted file mode 100644 index 8c738a3..0000000 --- a/test/test.css +++ /dev/null @@ -1,90 +0,0 @@ -body, div, p, h1, h2, h3, ul, ol, span, a, table, td, form, img, li { - font-family: sans-serif; -} - -body { - font-size:0.8em; -} - -.navigation { - background: #9DC569; - color: #fff; -} - -.navigation h1 { - font-size: 20px; -} - -.navigation h2 { - font-size: 16px; - font-weight: normal; - margin: 0; - border: 1px solid #e8a400; - border-bottom: 0; - background: #ffc; - color: #E8A400; - padding: 8px; - padding-bottom: 0; -} - -.navigation ul { - margin-top: 0; - border: 1px solid #E8A400; - border-top: none; - background: #ffc; - padding: 8px; - margin-left: 0; -} - -.navigation ul li { - font-size: 12px; - list-style-type: none; - margin-top: 1px; - margin-bottom: 1px; - color: #555; -} - -.navigation a { - color: #ffc; -} - -.navigation ul li a { - color: #000; -} - -#log { - padding-bottom: 1em; - border-bottom: 2px solid #000; - margin-bottom: 2em; -} - -#logsummary { - margin-bottom: 1em; - padding: 1ex; - border: 1px solid #000; - font-weight: bold; -} - -#logtable { - width:100%; - border-collapse: collapse; - border: 1px dotted #666; -} - -#logtable td, #logtable th { - text-align: left; - padding: 3px 8px; - border: 1px dotted #666; -} - -#logtable .passed { - background-color: #cfc; -} - -#logtable .failed, #logtable .error { - background-color: #fcc; -} - -#logtable .nameCell { - cursor: pointer; -} \ No newline at end of file diff --git a/test/unit/_ajax_inplaceeditor_ipce_alt_text.html b/test/unit/_ajax_inplaceeditor_ipce_alt_text.html deleted file mode 100644 index bdeac89..0000000 --- a/test/unit/_ajax_inplaceeditor_ipce_alt_text.html +++ /dev/null @@ -1 +0,0 @@ -ntbe diff --git a/test/unit/_ajax_inplaceeditor_ipce_collection.js b/test/unit/_ajax_inplaceeditor_ipce_collection.js deleted file mode 100644 index 22754aa..0000000 --- a/test/unit/_ajax_inplaceeditor_ipce_collection.js +++ /dev/null @@ -1 +0,0 @@ -[['foo', 'Foo'], ['bar', 'Bar'], ['ntbe', 'New to be edited'], ['ntbe2', 'New to be edited #2'], ['ntbe3', 'New to be edited #3']] diff --git a/test/unit/_ajax_inplaceeditor_result.html b/test/unit/_ajax_inplaceeditor_result.html deleted file mode 100644 index 55dcbea..0000000 --- a/test/unit/_ajax_inplaceeditor_result.html +++ /dev/null @@ -1 +0,0 @@ -Server received: To be edited \ No newline at end of file diff --git a/test/unit/_ajax_inplaceeditor_result2.html b/test/unit/_ajax_inplaceeditor_result2.html deleted file mode 100644 index 33502d9..0000000 --- a/test/unit/_ajax_inplaceeditor_result2.html +++ /dev/null @@ -1 +0,0 @@ -New to be edited - edited diff --git a/test/unit/_ajax_inplaceeditor_tagged.html b/test/unit/_ajax_inplaceeditor_tagged.html deleted file mode 100644 index eb53d10..0000000 --- a/test/unit/_ajax_inplaceeditor_tagged.html +++ /dev/null @@ -1 +0,0 @@ -New to be edited - edited diff --git a/test/unit/_ajax_inplaceeditor_text.html b/test/unit/_ajax_inplaceeditor_text.html deleted file mode 100644 index a6f35d1..0000000 --- a/test/unit/_ajax_inplaceeditor_text.html +++ /dev/null @@ -1 +0,0 @@ -Text from server \ No newline at end of file diff --git a/test/unit/_ajax_updater_result.html b/test/unit/_ajax_updater_result.html deleted file mode 100644 index 5f11f56..0000000 --- a/test/unit/_ajax_updater_result.html +++ /dev/null @@ -1,20 +0,0 @@ -Test text - - - -more test text - - - - - -even more test text - - some other test text - diff --git a/test/unit/_autocomplete_result.html b/test/unit/_autocomplete_result.html deleted file mode 100644 index f03b34f..0000000 --- a/test/unit/_autocomplete_result.html +++ /dev/null @@ -1,11 +0,0 @@ -

                        -
                      • test1
                      • test2
                      • -
                      • test3
                      • -
                      • BOLD
                      • - -
                      • (GET ME NOT)(GET <ME> INSTEAD)
                      • - -
                      • Here we have a link which should work
                      • - -
                      • Here we have some international Âİ∏Â„§â€ âˆ‘rŸ
                      • -
                      \ No newline at end of file diff --git a/test/unit/_autocomplete_result_nobr.html b/test/unit/_autocomplete_result_nobr.html deleted file mode 100644 index 742ff18..0000000 --- a/test/unit/_autocomplete_result_nobr.html +++ /dev/null @@ -1 +0,0 @@ -
                      • test1
                      • test2
                      • test3
                      • BOLD
                      • (GET ME NOT)(GET <ME> INSTEAD)
                      • Here we have a link which should work
                      • Here we have some international Âİ∏Â„§â€ âˆ‘rŸ
                      \ No newline at end of file diff --git a/test/unit/ajax_autocompleter_test.html b/test/unit/ajax_autocompleter_test.html deleted file mode 100644 index a1a63d2..0000000 --- a/test/unit/ajax_autocompleter_test.html +++ /dev/null @@ -1,243 +0,0 @@ - - - - - script.aculo.us Unit test file - - - - - - - - -

                      script.aculo.us Unit test file

                      -

                      - Tests for Ajax.Autocompleter in controls.js. -

                      - - -
                      - - - - - - - - - - - - - - - - - - - diff --git a/test/unit/ajax_inplaceeditor_test.html b/test/unit/ajax_inplaceeditor_test.html deleted file mode 100644 index 3fd9739..0000000 --- a/test/unit/ajax_inplaceeditor_test.html +++ /dev/null @@ -1,895 +0,0 @@ - - - - script.aculo.us Unit test file - - - - - - - -

                      script.aculo.us Unit test file

                      -

                      - Tests for Ajax.InPlaceEditor and Ajax.InPlaceCollectionEditor in controls.js -

                      - - -
                      - -

                      To be edited

                      -edit - -

                      New to be edited

                      -

                      External control for it

                      - -

                      Me & Myself

                      - -
                      First line
                      -Second line
                      -Third line
                      - - - - - diff --git a/test/unit/bdd_test.html b/test/unit/bdd_test.html deleted file mode 100644 index 3f63730..0000000 --- a/test/unit/bdd_test.html +++ /dev/null @@ -1,150 +0,0 @@ - - - - script.aculo.us Unit test file - - - - - - - -

                      script.aculo.us Unit test file

                      - - -
                      - -
                      initial
                      - - - - - \ No newline at end of file diff --git a/test/unit/builder_test.html b/test/unit/builder_test.html deleted file mode 100644 index 09f70f7..0000000 --- a/test/unit/builder_test.html +++ /dev/null @@ -1,262 +0,0 @@ - - - - script.aculo.us Unit test file - - - - - - - -

                      script.aculo.us Unit test file

                      -

                      - Tests for builder.js -

                      - - -
                      - -
                      - - - - - diff --git a/test/unit/dragdrop_test.html b/test/unit/dragdrop_test.html deleted file mode 100644 index 686bd0f..0000000 --- a/test/unit/dragdrop_test.html +++ /dev/null @@ -1,131 +0,0 @@ - - - - script.aculo.us Unit test file - - - - - - - - - -

                      script.aculo.us Unit test file

                      -

                      - Test of drag & drop functions in dragdrop.js -

                      - - -
                      - -

                      p_test

                      -

                      p_test2

                      -

                      p_test3

                      -img_text -
                      droppable_test
                      - -
                      div_test
                      -
                      div_absolute_test
                      -
                      div_absolute_inline_test
                      - -
                      -
                      droppable_test
                      -
                      droppable_test
                      -
                      - -
                      -
                      droppable_test
                      -
                      - - - - - diff --git a/test/unit/effects_test.html b/test/unit/effects_test.html deleted file mode 100644 index 5ef1658..0000000 --- a/test/unit/effects_test.html +++ /dev/null @@ -1,547 +0,0 @@ - - - - script.aculo.us Unit test file - - - - - - - - -

                      script.aculo.us Unit test file

                      -

                      - Tests for effects.js -

                      - - -
                      - - -
                      - -
                      Well
                      -
                      You know
                      -
                      Whoo-hoo!
                      - -
                      ERROR MESSAGE
                      -
                      SECOND ERROR MESSAGE
                      -
                      THIRD ERROR MESSAGE
                      - -
                        -
                      • Lorem ipsum dolor sit amet, consectetur adipisicing elit,
                      • -
                      • sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
                      • -
                      • Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris
                      • -
                      • nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in
                      • -
                      • reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
                      • -
                      - -
                      ROTFL
                      - -
                      foo!
                      - - - - - diff --git a/test/unit/element_test.html b/test/unit/element_test.html deleted file mode 100644 index 8ac5416..0000000 --- a/test/unit/element_test.html +++ /dev/null @@ -1,116 +0,0 @@ - - - - script.aculo.us Unit test file - - - - - - - - -

                      script.aculo.us Unit test file

                      -

                      - Tests for Element extensions in effects.js -

                      - - -
                      - - -
                      - -
                      - - -
                      - -
                      blah
                      - -
                      - - - -
                      -
                      - - -op2 -op2 -op3 -op3 - - -
                      - First class - Second class - First and Second class - Third class Nested First class - -
                      123
                      • 4
                      - -
                      - -
                      -
                      -
                      -
                      - - - - \ No newline at end of file diff --git a/test/unit/icon.png b/test/unit/icon.png deleted file mode 100644 index f752986..0000000 Binary files a/test/unit/icon.png and /dev/null differ diff --git a/test/unit/index.html b/test/unit/index.html deleted file mode 100644 index 70a3dbb..0000000 --- a/test/unit/index.html +++ /dev/null @@ -1,70 +0,0 @@ - - - - script.aculo.us Unit test file - - - - - - - - -

                      script.aculo.us
                      Unit Tests

                      - -

                      - - - -

                      Documentation

                      - -

                      scriptaculous.js

                      - - -

                      effects.js

                      - - -

                      dragdrop.js

                      - - -

                      builder.js

                      - - -

                      controls.js

                      - - -

                      slider.js

                      - - - -

                      unittest.js

                      - - - - \ No newline at end of file diff --git a/test/unit/loading_test.html b/test/unit/loading_test.html deleted file mode 100644 index d36f96c..0000000 --- a/test/unit/loading_test.html +++ /dev/null @@ -1,41 +0,0 @@ - - - - script.aculo.us Unit test file - - - - - - - -

                      script.aculo.us Unit test file

                      -

                      - Test dynamic loading in scriptaculous.js -

                      - - -
                      - - - - - \ No newline at end of file diff --git a/test/unit/position_clone_test.html b/test/unit/position_clone_test.html deleted file mode 100644 index 0644c63..0000000 --- a/test/unit/position_clone_test.html +++ /dev/null @@ -1,312 +0,0 @@ - - - - script.aculo.us Unit test file - - - - - - - -

                      script.aculo.us Unit test file

                      -

                      - Tests for Postion.clone (to be moved to Prototype) -

                      - - -
                      - - - - - - - - \ No newline at end of file diff --git a/test/unit/slider_test.html b/test/unit/slider_test.html deleted file mode 100644 index 4d3d0d0..0000000 --- a/test/unit/slider_test.html +++ /dev/null @@ -1,437 +0,0 @@ - - - - script.aculo.us Unit test file - - - - - - - -

                      script.aculo.us Unit test file

                      -

                      - Tests for slider.js -

                      - -
                      -
                      -
                      - -
                      -
                      -
                      - -
                      -
                      -
                      - -
                      - 1 - 2 - 3 -
                      - -
                      - 1 - 2 - 3 -
                      - -
                      -
                      1
                      -
                      2
                      -
                      3
                      - -
                      -
                      -
                      - -
                      -
                      1
                      -
                      2
                      -
                      3
                      - -
                      -
                      -
                      - -
                      -
                      1
                      -
                      2
                      -
                      3
                      - -
                      -
                      - -
                      -
                      -
                      - - -
                      - - -
                      - - - - - \ No newline at end of file diff --git a/test/unit/sortable_test.html b/test/unit/sortable_test.html deleted file mode 100644 index c2bafd0..0000000 --- a/test/unit/sortable_test.html +++ /dev/null @@ -1,205 +0,0 @@ - - - - script.aculo.us Unit test file - - - - - - - -

                      script.aculo.us Unit test file

                      -

                      - Test of sortable functions in dragdrop.js -

                      - - -
                      - - -
                        -
                      • item 1
                      • -
                      • item 1
                        • !!!
                      • -
                      • item 1
                      • -
                      • item 1
                      • - -
                      - -
                      -
                      item 4
                      item 5
                      - img - -
                      - -
                      - -
                      - - -
                        -
                      • item 1
                      • -
                      • item 1 -
                          -
                        • !!!
                        • -
                        -
                      • -
                      • item 1
                      • -
                      • item 1
                      • - -
                      - - -
                        -
                      • item 1
                      • -
                      • item 1
                        • !!!
                      • -
                      - -
                        -
                      • item 1
                      • -
                      • item 1
                        • !!!
                      • -
                      - - - - - diff --git a/test/unit/string_test.html b/test/unit/string_test.html deleted file mode 100644 index 7d0fc2d..0000000 --- a/test/unit/string_test.html +++ /dev/null @@ -1,71 +0,0 @@ - - - - script.aculo.us Unit test file - - - - - - - -

                      script.aculo.us Unit test file

                      -

                      - Tests for String.prototype extensions in effects.js -

                      - - -
                      - - - - - \ No newline at end of file diff --git a/test/unit/unittest_test.html b/test/unit/unittest_test.html deleted file mode 100644 index 39c0789..0000000 --- a/test/unit/unittest_test.html +++ /dev/null @@ -1,154 +0,0 @@ - - - - script.aculo.us Unit test file - - - - - - - - -

                      script.aculo.us Unit test file

                      -

                      - This is a preliminary version mostly for testing the unittest library. -

                      - - -
                      - - -
                      - -
                      - - - -
                      -
                      - -
                      • x1
                      • x2
                      -
                      • x1
                      • x2
                      - -
                      XXXX
                      - -
                      testcss1
                      testcss1
                      - - - - - \ No newline at end of file