houdini 0.2.4 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +3 -1
 - data/Gemfile.lock +97 -88
 - data/README.markdown +31 -27
 - data/app/controllers/houdini/postbacks_controller.rb +7 -9
 - data/config/routes.rb +2 -2
 - data/houdini.gemspec +3 -2
 - data/lib/houdini.rb +35 -7
 - data/lib/houdini/model.rb +14 -49
 - data/lib/houdini/postback_processor.rb +21 -0
 - data/lib/houdini/task.rb +46 -10
 - data/lib/houdini/task_manager.rb +20 -0
 - data/lib/houdini/version.rb +1 -1
 - data/spec/dummy/app/models/article.rb +12 -14
 - data/spec/houdini/model_spec.rb +27 -0
 - data/spec/houdini/postback_processor_spec.rb +44 -0
 - data/spec/houdini/task_manager_spec.rb +26 -0
 - data/spec/houdini/task_spec.rb +136 -0
 - data/spec/houdini_spec.rb +25 -0
 - data/spec/requests/integration_spec.rb +21 -19
 - data/spec/spec_helper.rb +3 -3
 - metadata +76 -118
 - data/lib/houdini/base.rb +0 -35
 - data/spec/controllers/houdini/postbacks_controller_spec.rb +0 -0
 - data/spec/dummy/config/initializers/backtrace_silencers.rb +0 -7
 - data/spec/dummy/config/initializers/inflections.rb +0 -10
 - data/spec/dummy/config/initializers/mime_types.rb +0 -5
 - data/spec/dummy/public/404.html +0 -26
 - data/spec/dummy/public/422.html +0 -26
 - data/spec/dummy/public/500.html +0 -26
 - data/spec/dummy/public/favicon.ico +0 -0
 - data/spec/dummy/public/javascripts/application.js +0 -2
 - data/spec/dummy/public/javascripts/controls.js +0 -965
 - data/spec/dummy/public/javascripts/dragdrop.js +0 -974
 - data/spec/dummy/public/javascripts/effects.js +0 -1123
 - data/spec/dummy/public/javascripts/prototype.js +0 -6001
 - data/spec/dummy/public/javascripts/rails.js +0 -175
 - data/spec/dummy/public/stylesheets/.gitkeep +0 -0
 - data/spec/houdini_rails_spec.rb +0 -4
 
| 
         @@ -1,965 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            // script.aculo.us controls.js v1.8.3, Thu Oct 08 11:23:33 +0200 2009
         
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
     | 
    
         
            -
            // Copyright (c) 2005-2009 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
         
     | 
| 
       4 
     | 
    
         
            -
            //           (c) 2005-2009 Ivan Krstic (http://blogs.law.harvard.edu/ivan)
         
     | 
| 
       5 
     | 
    
         
            -
            //           (c) 2005-2009 Jon Tirsen (http://www.tirsen.com)
         
     | 
| 
       6 
     | 
    
         
            -
            // Contributors:
         
     | 
| 
       7 
     | 
    
         
            -
            //  Richard Livsey
         
     | 
| 
       8 
     | 
    
         
            -
            //  Rahul Bhargava
         
     | 
| 
       9 
     | 
    
         
            -
            //  Rob Wills
         
     | 
| 
       10 
     | 
    
         
            -
            //
         
     | 
| 
       11 
     | 
    
         
            -
            // script.aculo.us is freely distributable under the terms of an MIT-style license.
         
     | 
| 
       12 
     | 
    
         
            -
            // For details, see the script.aculo.us web site: http://script.aculo.us/
         
     | 
| 
       13 
     | 
    
         
            -
             
     | 
| 
       14 
     | 
    
         
            -
            // Autocompleter.Base handles all the autocompletion functionality
         
     | 
| 
       15 
     | 
    
         
            -
            // that's independent of the data source for autocompletion. This
         
     | 
| 
       16 
     | 
    
         
            -
            // includes drawing the autocompletion menu, observing keyboard
         
     | 
| 
       17 
     | 
    
         
            -
            // and mouse events, and similar.
         
     | 
| 
       18 
     | 
    
         
            -
            //
         
     | 
| 
       19 
     | 
    
         
            -
            // Specific autocompleters need to provide, at the very least,
         
     | 
| 
       20 
     | 
    
         
            -
            // a getUpdatedChoices function that will be invoked every time
         
     | 
| 
       21 
     | 
    
         
            -
            // the text inside the monitored textbox changes. This method
         
     | 
| 
       22 
     | 
    
         
            -
            // should get the text for which to provide autocompletion by
         
     | 
| 
       23 
     | 
    
         
            -
            // invoking this.getToken(), NOT by directly accessing
         
     | 
| 
       24 
     | 
    
         
            -
            // this.element.value. This is to allow incremental tokenized
         
     | 
| 
       25 
     | 
    
         
            -
            // autocompletion. Specific auto-completion logic (AJAX, etc)
         
     | 
| 
       26 
     | 
    
         
            -
            // belongs in getUpdatedChoices.
         
     | 
| 
       27 
     | 
    
         
            -
            //
         
     | 
| 
       28 
     | 
    
         
            -
            // Tokenized incremental autocompletion is enabled automatically
         
     | 
| 
       29 
     | 
    
         
            -
            // when an autocompleter is instantiated with the 'tokens' option
         
     | 
| 
       30 
     | 
    
         
            -
            // in the options parameter, e.g.:
         
     | 
| 
       31 
     | 
    
         
            -
            // new Ajax.Autocompleter('id','upd', '/url/', { tokens: ',' });
         
     | 
| 
       32 
     | 
    
         
            -
            // will incrementally autocomplete with a comma as the token.
         
     | 
| 
       33 
     | 
    
         
            -
            // Additionally, ',' in the above example can be replaced with
         
     | 
| 
       34 
     | 
    
         
            -
            // a token array, e.g. { tokens: [',', '\n'] } which
         
     | 
| 
       35 
     | 
    
         
            -
            // enables autocompletion on multiple tokens. This is most
         
     | 
| 
       36 
     | 
    
         
            -
            // useful when one of the tokens is \n (a newline), as it
         
     | 
| 
       37 
     | 
    
         
            -
            // allows smart autocompletion after linebreaks.
         
     | 
| 
       38 
     | 
    
         
            -
             
     | 
| 
       39 
     | 
    
         
            -
            if(typeof Effect == 'undefined')
         
     | 
| 
       40 
     | 
    
         
            -
              throw("controls.js requires including script.aculo.us' effects.js library");
         
     | 
| 
       41 
     | 
    
         
            -
             
     | 
| 
       42 
     | 
    
         
            -
            var Autocompleter = { };
         
     | 
| 
       43 
     | 
    
         
            -
            Autocompleter.Base = Class.create({
         
     | 
| 
       44 
     | 
    
         
            -
              baseInitialize: function(element, update, options) {
         
     | 
| 
       45 
     | 
    
         
            -
                element          = $(element);
         
     | 
| 
       46 
     | 
    
         
            -
                this.element     = element;
         
     | 
| 
       47 
     | 
    
         
            -
                this.update      = $(update);
         
     | 
| 
       48 
     | 
    
         
            -
                this.hasFocus    = false;
         
     | 
| 
       49 
     | 
    
         
            -
                this.changed     = false;
         
     | 
| 
       50 
     | 
    
         
            -
                this.active      = false;
         
     | 
| 
       51 
     | 
    
         
            -
                this.index       = 0;
         
     | 
| 
       52 
     | 
    
         
            -
                this.entryCount  = 0;
         
     | 
| 
       53 
     | 
    
         
            -
                this.oldElementValue = this.element.value;
         
     | 
| 
       54 
     | 
    
         
            -
             
     | 
| 
       55 
     | 
    
         
            -
                if(this.setOptions)
         
     | 
| 
       56 
     | 
    
         
            -
                  this.setOptions(options);
         
     | 
| 
       57 
     | 
    
         
            -
                else
         
     | 
| 
       58 
     | 
    
         
            -
                  this.options = options || { };
         
     | 
| 
       59 
     | 
    
         
            -
             
     | 
| 
       60 
     | 
    
         
            -
                this.options.paramName    = this.options.paramName || this.element.name;
         
     | 
| 
       61 
     | 
    
         
            -
                this.options.tokens       = this.options.tokens || [];
         
     | 
| 
       62 
     | 
    
         
            -
                this.options.frequency    = this.options.frequency || 0.4;
         
     | 
| 
       63 
     | 
    
         
            -
                this.options.minChars     = this.options.minChars || 1;
         
     | 
| 
       64 
     | 
    
         
            -
                this.options.onShow       = this.options.onShow ||
         
     | 
| 
       65 
     | 
    
         
            -
                  function(element, update){
         
     | 
| 
       66 
     | 
    
         
            -
                    if(!update.style.position || update.style.position=='absolute') {
         
     | 
| 
       67 
     | 
    
         
            -
                      update.style.position = 'absolute';
         
     | 
| 
       68 
     | 
    
         
            -
                      Position.clone(element, update, {
         
     | 
| 
       69 
     | 
    
         
            -
                        setHeight: false,
         
     | 
| 
       70 
     | 
    
         
            -
                        offsetTop: element.offsetHeight
         
     | 
| 
       71 
     | 
    
         
            -
                      });
         
     | 
| 
       72 
     | 
    
         
            -
                    }
         
     | 
| 
       73 
     | 
    
         
            -
                    Effect.Appear(update,{duration:0.15});
         
     | 
| 
       74 
     | 
    
         
            -
                  };
         
     | 
| 
       75 
     | 
    
         
            -
                this.options.onHide = this.options.onHide ||
         
     | 
| 
       76 
     | 
    
         
            -
                  function(element, update){ new Effect.Fade(update,{duration:0.15}) };
         
     | 
| 
       77 
     | 
    
         
            -
             
     | 
| 
       78 
     | 
    
         
            -
                if(typeof(this.options.tokens) == 'string')
         
     | 
| 
       79 
     | 
    
         
            -
                  this.options.tokens = new Array(this.options.tokens);
         
     | 
| 
       80 
     | 
    
         
            -
                // Force carriage returns as token delimiters anyway
         
     | 
| 
       81 
     | 
    
         
            -
                if (!this.options.tokens.include('\n'))
         
     | 
| 
       82 
     | 
    
         
            -
                  this.options.tokens.push('\n');
         
     | 
| 
       83 
     | 
    
         
            -
             
     | 
| 
       84 
     | 
    
         
            -
                this.observer = null;
         
     | 
| 
       85 
     | 
    
         
            -
             
     | 
| 
       86 
     | 
    
         
            -
                this.element.setAttribute('autocomplete','off');
         
     | 
| 
       87 
     | 
    
         
            -
             
     | 
| 
       88 
     | 
    
         
            -
                Element.hide(this.update);
         
     | 
| 
       89 
     | 
    
         
            -
             
     | 
| 
       90 
     | 
    
         
            -
                Event.observe(this.element, 'blur', this.onBlur.bindAsEventListener(this));
         
     | 
| 
       91 
     | 
    
         
            -
                Event.observe(this.element, 'keydown', this.onKeyPress.bindAsEventListener(this));
         
     | 
| 
       92 
     | 
    
         
            -
              },
         
     | 
| 
       93 
     | 
    
         
            -
             
     | 
| 
       94 
     | 
    
         
            -
              show: function() {
         
     | 
| 
       95 
     | 
    
         
            -
                if(Element.getStyle(this.update, 'display')=='none') this.options.onShow(this.element, this.update);
         
     | 
| 
       96 
     | 
    
         
            -
                if(!this.iefix &&
         
     | 
| 
       97 
     | 
    
         
            -
                  (Prototype.Browser.IE) &&
         
     | 
| 
       98 
     | 
    
         
            -
                  (Element.getStyle(this.update, 'position')=='absolute')) {
         
     | 
| 
       99 
     | 
    
         
            -
                  new Insertion.After(this.update,
         
     | 
| 
       100 
     | 
    
         
            -
                   '<iframe id="' + this.update.id + '_iefix" '+
         
     | 
| 
       101 
     | 
    
         
            -
                   'style="display:none;position:absolute;filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);" ' +
         
     | 
| 
       102 
     | 
    
         
            -
                   'src="javascript:false;" frameborder="0" scrolling="no"></iframe>');
         
     | 
| 
       103 
     | 
    
         
            -
                  this.iefix = $(this.update.id+'_iefix');
         
     | 
| 
       104 
     | 
    
         
            -
                }
         
     | 
| 
       105 
     | 
    
         
            -
                if(this.iefix) setTimeout(this.fixIEOverlapping.bind(this), 50);
         
     | 
| 
       106 
     | 
    
         
            -
              },
         
     | 
| 
       107 
     | 
    
         
            -
             
     | 
| 
       108 
     | 
    
         
            -
              fixIEOverlapping: function() {
         
     | 
| 
       109 
     | 
    
         
            -
                Position.clone(this.update, this.iefix, {setTop:(!this.update.style.height)});
         
     | 
| 
       110 
     | 
    
         
            -
                this.iefix.style.zIndex = 1;
         
     | 
| 
       111 
     | 
    
         
            -
                this.update.style.zIndex = 2;
         
     | 
| 
       112 
     | 
    
         
            -
                Element.show(this.iefix);
         
     | 
| 
       113 
     | 
    
         
            -
              },
         
     | 
| 
       114 
     | 
    
         
            -
             
     | 
| 
       115 
     | 
    
         
            -
              hide: function() {
         
     | 
| 
       116 
     | 
    
         
            -
                this.stopIndicator();
         
     | 
| 
       117 
     | 
    
         
            -
                if(Element.getStyle(this.update, 'display')!='none') this.options.onHide(this.element, this.update);
         
     | 
| 
       118 
     | 
    
         
            -
                if(this.iefix) Element.hide(this.iefix);
         
     | 
| 
       119 
     | 
    
         
            -
              },
         
     | 
| 
       120 
     | 
    
         
            -
             
     | 
| 
       121 
     | 
    
         
            -
              startIndicator: function() {
         
     | 
| 
       122 
     | 
    
         
            -
                if(this.options.indicator) Element.show(this.options.indicator);
         
     | 
| 
       123 
     | 
    
         
            -
              },
         
     | 
| 
       124 
     | 
    
         
            -
             
     | 
| 
       125 
     | 
    
         
            -
              stopIndicator: function() {
         
     | 
| 
       126 
     | 
    
         
            -
                if(this.options.indicator) Element.hide(this.options.indicator);
         
     | 
| 
       127 
     | 
    
         
            -
              },
         
     | 
| 
       128 
     | 
    
         
            -
             
     | 
| 
       129 
     | 
    
         
            -
              onKeyPress: function(event) {
         
     | 
| 
       130 
     | 
    
         
            -
                if(this.active)
         
     | 
| 
       131 
     | 
    
         
            -
                  switch(event.keyCode) {
         
     | 
| 
       132 
     | 
    
         
            -
                   case Event.KEY_TAB:
         
     | 
| 
       133 
     | 
    
         
            -
                   case Event.KEY_RETURN:
         
     | 
| 
       134 
     | 
    
         
            -
                     this.selectEntry();
         
     | 
| 
       135 
     | 
    
         
            -
                     Event.stop(event);
         
     | 
| 
       136 
     | 
    
         
            -
                   case Event.KEY_ESC:
         
     | 
| 
       137 
     | 
    
         
            -
                     this.hide();
         
     | 
| 
       138 
     | 
    
         
            -
                     this.active = false;
         
     | 
| 
       139 
     | 
    
         
            -
                     Event.stop(event);
         
     | 
| 
       140 
     | 
    
         
            -
                     return;
         
     | 
| 
       141 
     | 
    
         
            -
                   case Event.KEY_LEFT:
         
     | 
| 
       142 
     | 
    
         
            -
                   case Event.KEY_RIGHT:
         
     | 
| 
       143 
     | 
    
         
            -
                     return;
         
     | 
| 
       144 
     | 
    
         
            -
                   case Event.KEY_UP:
         
     | 
| 
       145 
     | 
    
         
            -
                     this.markPrevious();
         
     | 
| 
       146 
     | 
    
         
            -
                     this.render();
         
     | 
| 
       147 
     | 
    
         
            -
                     Event.stop(event);
         
     | 
| 
       148 
     | 
    
         
            -
                     return;
         
     | 
| 
       149 
     | 
    
         
            -
                   case Event.KEY_DOWN:
         
     | 
| 
       150 
     | 
    
         
            -
                     this.markNext();
         
     | 
| 
       151 
     | 
    
         
            -
                     this.render();
         
     | 
| 
       152 
     | 
    
         
            -
                     Event.stop(event);
         
     | 
| 
       153 
     | 
    
         
            -
                     return;
         
     | 
| 
       154 
     | 
    
         
            -
                  }
         
     | 
| 
       155 
     | 
    
         
            -
                 else
         
     | 
| 
       156 
     | 
    
         
            -
                   if(event.keyCode==Event.KEY_TAB || event.keyCode==Event.KEY_RETURN ||
         
     | 
| 
       157 
     | 
    
         
            -
                     (Prototype.Browser.WebKit > 0 && event.keyCode == 0)) return;
         
     | 
| 
       158 
     | 
    
         
            -
             
     | 
| 
       159 
     | 
    
         
            -
                this.changed = true;
         
     | 
| 
       160 
     | 
    
         
            -
                this.hasFocus = true;
         
     | 
| 
       161 
     | 
    
         
            -
             
     | 
| 
       162 
     | 
    
         
            -
                if(this.observer) clearTimeout(this.observer);
         
     | 
| 
       163 
     | 
    
         
            -
                  this.observer =
         
     | 
| 
       164 
     | 
    
         
            -
                    setTimeout(this.onObserverEvent.bind(this), this.options.frequency*1000);
         
     | 
| 
       165 
     | 
    
         
            -
              },
         
     | 
| 
       166 
     | 
    
         
            -
             
     | 
| 
       167 
     | 
    
         
            -
              activate: function() {
         
     | 
| 
       168 
     | 
    
         
            -
                this.changed = false;
         
     | 
| 
       169 
     | 
    
         
            -
                this.hasFocus = true;
         
     | 
| 
       170 
     | 
    
         
            -
                this.getUpdatedChoices();
         
     | 
| 
       171 
     | 
    
         
            -
              },
         
     | 
| 
       172 
     | 
    
         
            -
             
     | 
| 
       173 
     | 
    
         
            -
              onHover: function(event) {
         
     | 
| 
       174 
     | 
    
         
            -
                var element = Event.findElement(event, 'LI');
         
     | 
| 
       175 
     | 
    
         
            -
                if(this.index != element.autocompleteIndex)
         
     | 
| 
       176 
     | 
    
         
            -
                {
         
     | 
| 
       177 
     | 
    
         
            -
                    this.index = element.autocompleteIndex;
         
     | 
| 
       178 
     | 
    
         
            -
                    this.render();
         
     | 
| 
       179 
     | 
    
         
            -
                }
         
     | 
| 
       180 
     | 
    
         
            -
                Event.stop(event);
         
     | 
| 
       181 
     | 
    
         
            -
              },
         
     | 
| 
       182 
     | 
    
         
            -
             
     | 
| 
       183 
     | 
    
         
            -
              onClick: function(event) {
         
     | 
| 
       184 
     | 
    
         
            -
                var element = Event.findElement(event, 'LI');
         
     | 
| 
       185 
     | 
    
         
            -
                this.index = element.autocompleteIndex;
         
     | 
| 
       186 
     | 
    
         
            -
                this.selectEntry();
         
     | 
| 
       187 
     | 
    
         
            -
                this.hide();
         
     | 
| 
       188 
     | 
    
         
            -
              },
         
     | 
| 
       189 
     | 
    
         
            -
             
     | 
| 
       190 
     | 
    
         
            -
              onBlur: function(event) {
         
     | 
| 
       191 
     | 
    
         
            -
                // needed to make click events working
         
     | 
| 
       192 
     | 
    
         
            -
                setTimeout(this.hide.bind(this), 250);
         
     | 
| 
       193 
     | 
    
         
            -
                this.hasFocus = false;
         
     | 
| 
       194 
     | 
    
         
            -
                this.active = false;
         
     | 
| 
       195 
     | 
    
         
            -
              },
         
     | 
| 
       196 
     | 
    
         
            -
             
     | 
| 
       197 
     | 
    
         
            -
              render: function() {
         
     | 
| 
       198 
     | 
    
         
            -
                if(this.entryCount > 0) {
         
     | 
| 
       199 
     | 
    
         
            -
                  for (var i = 0; i < this.entryCount; i++)
         
     | 
| 
       200 
     | 
    
         
            -
                    this.index==i ?
         
     | 
| 
       201 
     | 
    
         
            -
                      Element.addClassName(this.getEntry(i),"selected") :
         
     | 
| 
       202 
     | 
    
         
            -
                      Element.removeClassName(this.getEntry(i),"selected");
         
     | 
| 
       203 
     | 
    
         
            -
                  if(this.hasFocus) {
         
     | 
| 
       204 
     | 
    
         
            -
                    this.show();
         
     | 
| 
       205 
     | 
    
         
            -
                    this.active = true;
         
     | 
| 
       206 
     | 
    
         
            -
                  }
         
     | 
| 
       207 
     | 
    
         
            -
                } else {
         
     | 
| 
       208 
     | 
    
         
            -
                  this.active = false;
         
     | 
| 
       209 
     | 
    
         
            -
                  this.hide();
         
     | 
| 
       210 
     | 
    
         
            -
                }
         
     | 
| 
       211 
     | 
    
         
            -
              },
         
     | 
| 
       212 
     | 
    
         
            -
             
     | 
| 
       213 
     | 
    
         
            -
              markPrevious: function() {
         
     | 
| 
       214 
     | 
    
         
            -
                if(this.index > 0) this.index--;
         
     | 
| 
       215 
     | 
    
         
            -
                  else this.index = this.entryCount-1;
         
     | 
| 
       216 
     | 
    
         
            -
                this.getEntry(this.index).scrollIntoView(true);
         
     | 
| 
       217 
     | 
    
         
            -
              },
         
     | 
| 
       218 
     | 
    
         
            -
             
     | 
| 
       219 
     | 
    
         
            -
              markNext: function() {
         
     | 
| 
       220 
     | 
    
         
            -
                if(this.index < this.entryCount-1) this.index++;
         
     | 
| 
       221 
     | 
    
         
            -
                  else this.index = 0;
         
     | 
| 
       222 
     | 
    
         
            -
                this.getEntry(this.index).scrollIntoView(false);
         
     | 
| 
       223 
     | 
    
         
            -
              },
         
     | 
| 
       224 
     | 
    
         
            -
             
     | 
| 
       225 
     | 
    
         
            -
              getEntry: function(index) {
         
     | 
| 
       226 
     | 
    
         
            -
                return this.update.firstChild.childNodes[index];
         
     | 
| 
       227 
     | 
    
         
            -
              },
         
     | 
| 
       228 
     | 
    
         
            -
             
     | 
| 
       229 
     | 
    
         
            -
              getCurrentEntry: function() {
         
     | 
| 
       230 
     | 
    
         
            -
                return this.getEntry(this.index);
         
     | 
| 
       231 
     | 
    
         
            -
              },
         
     | 
| 
       232 
     | 
    
         
            -
             
     | 
| 
       233 
     | 
    
         
            -
              selectEntry: function() {
         
     | 
| 
       234 
     | 
    
         
            -
                this.active = false;
         
     | 
| 
       235 
     | 
    
         
            -
                this.updateElement(this.getCurrentEntry());
         
     | 
| 
       236 
     | 
    
         
            -
              },
         
     | 
| 
       237 
     | 
    
         
            -
             
     | 
| 
       238 
     | 
    
         
            -
              updateElement: function(selectedElement) {
         
     | 
| 
       239 
     | 
    
         
            -
                if (this.options.updateElement) {
         
     | 
| 
       240 
     | 
    
         
            -
                  this.options.updateElement(selectedElement);
         
     | 
| 
       241 
     | 
    
         
            -
                  return;
         
     | 
| 
       242 
     | 
    
         
            -
                }
         
     | 
| 
       243 
     | 
    
         
            -
                var value = '';
         
     | 
| 
       244 
     | 
    
         
            -
                if (this.options.select) {
         
     | 
| 
       245 
     | 
    
         
            -
                  var nodes = $(selectedElement).select('.' + this.options.select) || [];
         
     | 
| 
       246 
     | 
    
         
            -
                  if(nodes.length>0) value = Element.collectTextNodes(nodes[0], this.options.select);
         
     | 
| 
       247 
     | 
    
         
            -
                } else
         
     | 
| 
       248 
     | 
    
         
            -
                  value = Element.collectTextNodesIgnoreClass(selectedElement, 'informal');
         
     | 
| 
       249 
     | 
    
         
            -
             
     | 
| 
       250 
     | 
    
         
            -
                var bounds = this.getTokenBounds();
         
     | 
| 
       251 
     | 
    
         
            -
                if (bounds[0] != -1) {
         
     | 
| 
       252 
     | 
    
         
            -
                  var newValue = this.element.value.substr(0, bounds[0]);
         
     | 
| 
       253 
     | 
    
         
            -
                  var whitespace = this.element.value.substr(bounds[0]).match(/^\s+/);
         
     | 
| 
       254 
     | 
    
         
            -
                  if (whitespace)
         
     | 
| 
       255 
     | 
    
         
            -
                    newValue += whitespace[0];
         
     | 
| 
       256 
     | 
    
         
            -
                  this.element.value = newValue + value + this.element.value.substr(bounds[1]);
         
     | 
| 
       257 
     | 
    
         
            -
                } else {
         
     | 
| 
       258 
     | 
    
         
            -
                  this.element.value = value;
         
     | 
| 
       259 
     | 
    
         
            -
                }
         
     | 
| 
       260 
     | 
    
         
            -
                this.oldElementValue = this.element.value;
         
     | 
| 
       261 
     | 
    
         
            -
                this.element.focus();
         
     | 
| 
       262 
     | 
    
         
            -
             
     | 
| 
       263 
     | 
    
         
            -
                if (this.options.afterUpdateElement)
         
     | 
| 
       264 
     | 
    
         
            -
                  this.options.afterUpdateElement(this.element, selectedElement);
         
     | 
| 
       265 
     | 
    
         
            -
              },
         
     | 
| 
       266 
     | 
    
         
            -
             
     | 
| 
       267 
     | 
    
         
            -
              updateChoices: function(choices) {
         
     | 
| 
       268 
     | 
    
         
            -
                if(!this.changed && this.hasFocus) {
         
     | 
| 
       269 
     | 
    
         
            -
                  this.update.innerHTML = choices;
         
     | 
| 
       270 
     | 
    
         
            -
                  Element.cleanWhitespace(this.update);
         
     | 
| 
       271 
     | 
    
         
            -
                  Element.cleanWhitespace(this.update.down());
         
     | 
| 
       272 
     | 
    
         
            -
             
     | 
| 
       273 
     | 
    
         
            -
                  if(this.update.firstChild && this.update.down().childNodes) {
         
     | 
| 
       274 
     | 
    
         
            -
                    this.entryCount =
         
     | 
| 
       275 
     | 
    
         
            -
                      this.update.down().childNodes.length;
         
     | 
| 
       276 
     | 
    
         
            -
                    for (var i = 0; i < this.entryCount; i++) {
         
     | 
| 
       277 
     | 
    
         
            -
                      var entry = this.getEntry(i);
         
     | 
| 
       278 
     | 
    
         
            -
                      entry.autocompleteIndex = i;
         
     | 
| 
       279 
     | 
    
         
            -
                      this.addObservers(entry);
         
     | 
| 
       280 
     | 
    
         
            -
                    }
         
     | 
| 
       281 
     | 
    
         
            -
                  } else {
         
     | 
| 
       282 
     | 
    
         
            -
                    this.entryCount = 0;
         
     | 
| 
       283 
     | 
    
         
            -
                  }
         
     | 
| 
       284 
     | 
    
         
            -
             
     | 
| 
       285 
     | 
    
         
            -
                  this.stopIndicator();
         
     | 
| 
       286 
     | 
    
         
            -
                  this.index = 0;
         
     | 
| 
       287 
     | 
    
         
            -
             
     | 
| 
       288 
     | 
    
         
            -
                  if(this.entryCount==1 && this.options.autoSelect) {
         
     | 
| 
       289 
     | 
    
         
            -
                    this.selectEntry();
         
     | 
| 
       290 
     | 
    
         
            -
                    this.hide();
         
     | 
| 
       291 
     | 
    
         
            -
                  } else {
         
     | 
| 
       292 
     | 
    
         
            -
                    this.render();
         
     | 
| 
       293 
     | 
    
         
            -
                  }
         
     | 
| 
       294 
     | 
    
         
            -
                }
         
     | 
| 
       295 
     | 
    
         
            -
              },
         
     | 
| 
       296 
     | 
    
         
            -
             
     | 
| 
       297 
     | 
    
         
            -
              addObservers: function(element) {
         
     | 
| 
       298 
     | 
    
         
            -
                Event.observe(element, "mouseover", this.onHover.bindAsEventListener(this));
         
     | 
| 
       299 
     | 
    
         
            -
                Event.observe(element, "click", this.onClick.bindAsEventListener(this));
         
     | 
| 
       300 
     | 
    
         
            -
              },
         
     | 
| 
       301 
     | 
    
         
            -
             
     | 
| 
       302 
     | 
    
         
            -
              onObserverEvent: function() {
         
     | 
| 
       303 
     | 
    
         
            -
                this.changed = false;
         
     | 
| 
       304 
     | 
    
         
            -
                this.tokenBounds = null;
         
     | 
| 
       305 
     | 
    
         
            -
                if(this.getToken().length>=this.options.minChars) {
         
     | 
| 
       306 
     | 
    
         
            -
                  this.getUpdatedChoices();
         
     | 
| 
       307 
     | 
    
         
            -
                } else {
         
     | 
| 
       308 
     | 
    
         
            -
                  this.active = false;
         
     | 
| 
       309 
     | 
    
         
            -
                  this.hide();
         
     | 
| 
       310 
     | 
    
         
            -
                }
         
     | 
| 
       311 
     | 
    
         
            -
                this.oldElementValue = this.element.value;
         
     | 
| 
       312 
     | 
    
         
            -
              },
         
     | 
| 
       313 
     | 
    
         
            -
             
     | 
| 
       314 
     | 
    
         
            -
              getToken: function() {
         
     | 
| 
       315 
     | 
    
         
            -
                var bounds = this.getTokenBounds();
         
     | 
| 
       316 
     | 
    
         
            -
                return this.element.value.substring(bounds[0], bounds[1]).strip();
         
     | 
| 
       317 
     | 
    
         
            -
              },
         
     | 
| 
       318 
     | 
    
         
            -
             
     | 
| 
       319 
     | 
    
         
            -
              getTokenBounds: function() {
         
     | 
| 
       320 
     | 
    
         
            -
                if (null != this.tokenBounds) return this.tokenBounds;
         
     | 
| 
       321 
     | 
    
         
            -
                var value = this.element.value;
         
     | 
| 
       322 
     | 
    
         
            -
                if (value.strip().empty()) return [-1, 0];
         
     | 
| 
       323 
     | 
    
         
            -
                var diff = arguments.callee.getFirstDifferencePos(value, this.oldElementValue);
         
     | 
| 
       324 
     | 
    
         
            -
                var offset = (diff == this.oldElementValue.length ? 1 : 0);
         
     | 
| 
       325 
     | 
    
         
            -
                var prevTokenPos = -1, nextTokenPos = value.length;
         
     | 
| 
       326 
     | 
    
         
            -
                var tp;
         
     | 
| 
       327 
     | 
    
         
            -
                for (var index = 0, l = this.options.tokens.length; index < l; ++index) {
         
     | 
| 
       328 
     | 
    
         
            -
                  tp = value.lastIndexOf(this.options.tokens[index], diff + offset - 1);
         
     | 
| 
       329 
     | 
    
         
            -
                  if (tp > prevTokenPos) prevTokenPos = tp;
         
     | 
| 
       330 
     | 
    
         
            -
                  tp = value.indexOf(this.options.tokens[index], diff + offset);
         
     | 
| 
       331 
     | 
    
         
            -
                  if (-1 != tp && tp < nextTokenPos) nextTokenPos = tp;
         
     | 
| 
       332 
     | 
    
         
            -
                }
         
     | 
| 
       333 
     | 
    
         
            -
                return (this.tokenBounds = [prevTokenPos + 1, nextTokenPos]);
         
     | 
| 
       334 
     | 
    
         
            -
              }
         
     | 
| 
       335 
     | 
    
         
            -
            });
         
     | 
| 
       336 
     | 
    
         
            -
             
     | 
| 
       337 
     | 
    
         
            -
            Autocompleter.Base.prototype.getTokenBounds.getFirstDifferencePos = function(newS, oldS) {
         
     | 
| 
       338 
     | 
    
         
            -
              var boundary = Math.min(newS.length, oldS.length);
         
     | 
| 
       339 
     | 
    
         
            -
              for (var index = 0; index < boundary; ++index)
         
     | 
| 
       340 
     | 
    
         
            -
                if (newS[index] != oldS[index])
         
     | 
| 
       341 
     | 
    
         
            -
                  return index;
         
     | 
| 
       342 
     | 
    
         
            -
              return boundary;
         
     | 
| 
       343 
     | 
    
         
            -
            };
         
     | 
| 
       344 
     | 
    
         
            -
             
     | 
| 
       345 
     | 
    
         
            -
            Ajax.Autocompleter = Class.create(Autocompleter.Base, {
         
     | 
| 
       346 
     | 
    
         
            -
              initialize: function(element, update, url, options) {
         
     | 
| 
       347 
     | 
    
         
            -
                this.baseInitialize(element, update, options);
         
     | 
| 
       348 
     | 
    
         
            -
                this.options.asynchronous  = true;
         
     | 
| 
       349 
     | 
    
         
            -
                this.options.onComplete    = this.onComplete.bind(this);
         
     | 
| 
       350 
     | 
    
         
            -
                this.options.defaultParams = this.options.parameters || null;
         
     | 
| 
       351 
     | 
    
         
            -
                this.url                   = url;
         
     | 
| 
       352 
     | 
    
         
            -
              },
         
     | 
| 
       353 
     | 
    
         
            -
             
     | 
| 
       354 
     | 
    
         
            -
              getUpdatedChoices: function() {
         
     | 
| 
       355 
     | 
    
         
            -
                this.startIndicator();
         
     | 
| 
       356 
     | 
    
         
            -
             
     | 
| 
       357 
     | 
    
         
            -
                var entry = encodeURIComponent(this.options.paramName) + '=' +
         
     | 
| 
       358 
     | 
    
         
            -
                  encodeURIComponent(this.getToken());
         
     | 
| 
       359 
     | 
    
         
            -
             
     | 
| 
       360 
     | 
    
         
            -
                this.options.parameters = this.options.callback ?
         
     | 
| 
       361 
     | 
    
         
            -
                  this.options.callback(this.element, entry) : entry;
         
     | 
| 
       362 
     | 
    
         
            -
             
     | 
| 
       363 
     | 
    
         
            -
                if(this.options.defaultParams)
         
     | 
| 
       364 
     | 
    
         
            -
                  this.options.parameters += '&' + this.options.defaultParams;
         
     | 
| 
       365 
     | 
    
         
            -
             
     | 
| 
       366 
     | 
    
         
            -
                new Ajax.Request(this.url, this.options);
         
     | 
| 
       367 
     | 
    
         
            -
              },
         
     | 
| 
       368 
     | 
    
         
            -
             
     | 
| 
       369 
     | 
    
         
            -
              onComplete: function(request) {
         
     | 
| 
       370 
     | 
    
         
            -
                this.updateChoices(request.responseText);
         
     | 
| 
       371 
     | 
    
         
            -
              }
         
     | 
| 
       372 
     | 
    
         
            -
            });
         
     | 
| 
       373 
     | 
    
         
            -
             
     | 
| 
       374 
     | 
    
         
            -
            // The local array autocompleter. Used when you'd prefer to
         
     | 
| 
       375 
     | 
    
         
            -
            // inject an array of autocompletion options into the page, rather
         
     | 
| 
       376 
     | 
    
         
            -
            // than sending out Ajax queries, which can be quite slow sometimes.
         
     | 
| 
       377 
     | 
    
         
            -
            //
         
     | 
| 
       378 
     | 
    
         
            -
            // The constructor takes four parameters. The first two are, as usual,
         
     | 
| 
       379 
     | 
    
         
            -
            // the id of the monitored textbox, and id of the autocompletion menu.
         
     | 
| 
       380 
     | 
    
         
            -
            // The third is the array you want to autocomplete from, and the fourth
         
     | 
| 
       381 
     | 
    
         
            -
            // is the options block.
         
     | 
| 
       382 
     | 
    
         
            -
            //
         
     | 
| 
       383 
     | 
    
         
            -
            // Extra local autocompletion options:
         
     | 
| 
       384 
     | 
    
         
            -
            // - choices - How many autocompletion choices to offer
         
     | 
| 
       385 
     | 
    
         
            -
            //
         
     | 
| 
       386 
     | 
    
         
            -
            // - partialSearch - If false, the autocompleter will match entered
         
     | 
| 
       387 
     | 
    
         
            -
            //                    text only at the beginning of strings in the
         
     | 
| 
       388 
     | 
    
         
            -
            //                    autocomplete array. Defaults to true, which will
         
     | 
| 
       389 
     | 
    
         
            -
            //                    match text at the beginning of any *word* in the
         
     | 
| 
       390 
     | 
    
         
            -
            //                    strings in the autocomplete array. If you want to
         
     | 
| 
       391 
     | 
    
         
            -
            //                    search anywhere in the string, additionally set
         
     | 
| 
       392 
     | 
    
         
            -
            //                    the option fullSearch to true (default: off).
         
     | 
| 
       393 
     | 
    
         
            -
            //
         
     | 
| 
       394 
     | 
    
         
            -
            // - fullSsearch - Search anywhere in autocomplete array strings.
         
     | 
| 
       395 
     | 
    
         
            -
            //
         
     | 
| 
       396 
     | 
    
         
            -
            // - partialChars - How many characters to enter before triggering
         
     | 
| 
       397 
     | 
    
         
            -
            //                   a partial match (unlike minChars, which defines
         
     | 
| 
       398 
     | 
    
         
            -
            //                   how many characters are required to do any match
         
     | 
| 
       399 
     | 
    
         
            -
            //                   at all). Defaults to 2.
         
     | 
| 
       400 
     | 
    
         
            -
            //
         
     | 
| 
       401 
     | 
    
         
            -
            // - ignoreCase - Whether to ignore case when autocompleting.
         
     | 
| 
       402 
     | 
    
         
            -
            //                 Defaults to true.
         
     | 
| 
       403 
     | 
    
         
            -
            //
         
     | 
| 
       404 
     | 
    
         
            -
            // It's possible to pass in a custom function as the 'selector'
         
     | 
| 
       405 
     | 
    
         
            -
            // option, if you prefer to write your own autocompletion logic.
         
     | 
| 
       406 
     | 
    
         
            -
            // In that case, the other options above will not apply unless
         
     | 
| 
       407 
     | 
    
         
            -
            // you support them.
         
     | 
| 
       408 
     | 
    
         
            -
             
     | 
| 
       409 
     | 
    
         
            -
            Autocompleter.Local = Class.create(Autocompleter.Base, {
         
     | 
| 
       410 
     | 
    
         
            -
              initialize: function(element, update, array, options) {
         
     | 
| 
       411 
     | 
    
         
            -
                this.baseInitialize(element, update, options);
         
     | 
| 
       412 
     | 
    
         
            -
                this.options.array = array;
         
     | 
| 
       413 
     | 
    
         
            -
              },
         
     | 
| 
       414 
     | 
    
         
            -
             
     | 
| 
       415 
     | 
    
         
            -
              getUpdatedChoices: function() {
         
     | 
| 
       416 
     | 
    
         
            -
                this.updateChoices(this.options.selector(this));
         
     | 
| 
       417 
     | 
    
         
            -
              },
         
     | 
| 
       418 
     | 
    
         
            -
             
     | 
| 
       419 
     | 
    
         
            -
              setOptions: function(options) {
         
     | 
| 
       420 
     | 
    
         
            -
                this.options = Object.extend({
         
     | 
| 
       421 
     | 
    
         
            -
                  choices: 10,
         
     | 
| 
       422 
     | 
    
         
            -
                  partialSearch: true,
         
     | 
| 
       423 
     | 
    
         
            -
                  partialChars: 2,
         
     | 
| 
       424 
     | 
    
         
            -
                  ignoreCase: true,
         
     | 
| 
       425 
     | 
    
         
            -
                  fullSearch: false,
         
     | 
| 
       426 
     | 
    
         
            -
                  selector: function(instance) {
         
     | 
| 
       427 
     | 
    
         
            -
                    var ret       = []; // Beginning matches
         
     | 
| 
       428 
     | 
    
         
            -
                    var partial   = []; // Inside matches
         
     | 
| 
       429 
     | 
    
         
            -
                    var entry     = instance.getToken();
         
     | 
| 
       430 
     | 
    
         
            -
                    var count     = 0;
         
     | 
| 
       431 
     | 
    
         
            -
             
     | 
| 
       432 
     | 
    
         
            -
                    for (var i = 0; i < instance.options.array.length &&
         
     | 
| 
       433 
     | 
    
         
            -
                      ret.length < instance.options.choices ; i++) {
         
     | 
| 
       434 
     | 
    
         
            -
             
     | 
| 
       435 
     | 
    
         
            -
                      var elem = instance.options.array[i];
         
     | 
| 
       436 
     | 
    
         
            -
                      var foundPos = instance.options.ignoreCase ?
         
     | 
| 
       437 
     | 
    
         
            -
                        elem.toLowerCase().indexOf(entry.toLowerCase()) :
         
     | 
| 
       438 
     | 
    
         
            -
                        elem.indexOf(entry);
         
     | 
| 
       439 
     | 
    
         
            -
             
     | 
| 
       440 
     | 
    
         
            -
                      while (foundPos != -1) {
         
     | 
| 
       441 
     | 
    
         
            -
                        if (foundPos == 0 && elem.length != entry.length) {
         
     | 
| 
       442 
     | 
    
         
            -
                          ret.push("<li><strong>" + elem.substr(0, entry.length) + "</strong>" +
         
     | 
| 
       443 
     | 
    
         
            -
                            elem.substr(entry.length) + "</li>");
         
     | 
| 
       444 
     | 
    
         
            -
                          break;
         
     | 
| 
       445 
     | 
    
         
            -
                        } else if (entry.length >= instance.options.partialChars &&
         
     | 
| 
       446 
     | 
    
         
            -
                          instance.options.partialSearch && foundPos != -1) {
         
     | 
| 
       447 
     | 
    
         
            -
                          if (instance.options.fullSearch || /\s/.test(elem.substr(foundPos-1,1))) {
         
     | 
| 
       448 
     | 
    
         
            -
                            partial.push("<li>" + elem.substr(0, foundPos) + "<strong>" +
         
     | 
| 
       449 
     | 
    
         
            -
                              elem.substr(foundPos, entry.length) + "</strong>" + elem.substr(
         
     | 
| 
       450 
     | 
    
         
            -
                              foundPos + entry.length) + "</li>");
         
     | 
| 
       451 
     | 
    
         
            -
                            break;
         
     | 
| 
       452 
     | 
    
         
            -
                          }
         
     | 
| 
       453 
     | 
    
         
            -
                        }
         
     | 
| 
       454 
     | 
    
         
            -
             
     | 
| 
       455 
     | 
    
         
            -
                        foundPos = instance.options.ignoreCase ?
         
     | 
| 
       456 
     | 
    
         
            -
                          elem.toLowerCase().indexOf(entry.toLowerCase(), foundPos + 1) :
         
     | 
| 
       457 
     | 
    
         
            -
                          elem.indexOf(entry, foundPos + 1);
         
     | 
| 
       458 
     | 
    
         
            -
             
     | 
| 
       459 
     | 
    
         
            -
                      }
         
     | 
| 
       460 
     | 
    
         
            -
                    }
         
     | 
| 
       461 
     | 
    
         
            -
                    if (partial.length)
         
     | 
| 
       462 
     | 
    
         
            -
                      ret = ret.concat(partial.slice(0, instance.options.choices - ret.length));
         
     | 
| 
       463 
     | 
    
         
            -
                    return "<ul>" + ret.join('') + "</ul>";
         
     | 
| 
       464 
     | 
    
         
            -
                  }
         
     | 
| 
       465 
     | 
    
         
            -
                }, options || { });
         
     | 
| 
       466 
     | 
    
         
            -
              }
         
     | 
| 
       467 
     | 
    
         
            -
            });
         
     | 
| 
       468 
     | 
    
         
            -
             
     | 
| 
       469 
     | 
    
         
            -
            // AJAX in-place editor and collection editor
         
     | 
| 
       470 
     | 
    
         
            -
            // Full rewrite by Christophe Porteneuve <tdd@tddsworld.com> (April 2007).
         
     | 
| 
       471 
     | 
    
         
            -
             
     | 
| 
       472 
     | 
    
         
            -
            // Use this if you notice weird scrolling problems on some browsers,
         
     | 
| 
       473 
     | 
    
         
            -
            // the DOM might be a bit confused when this gets called so do this
         
     | 
| 
       474 
     | 
    
         
            -
            // waits 1 ms (with setTimeout) until it does the activation
         
     | 
| 
       475 
     | 
    
         
            -
            Field.scrollFreeActivate = function(field) {
         
     | 
| 
       476 
     | 
    
         
            -
              setTimeout(function() {
         
     | 
| 
       477 
     | 
    
         
            -
                Field.activate(field);
         
     | 
| 
       478 
     | 
    
         
            -
              }, 1);
         
     | 
| 
       479 
     | 
    
         
            -
            };
         
     | 
| 
       480 
     | 
    
         
            -
             
     | 
| 
       481 
     | 
    
         
            -
            Ajax.InPlaceEditor = Class.create({
         
     | 
| 
       482 
     | 
    
         
            -
              initialize: function(element, url, options) {
         
     | 
| 
       483 
     | 
    
         
            -
                this.url = url;
         
     | 
| 
       484 
     | 
    
         
            -
                this.element = element = $(element);
         
     | 
| 
       485 
     | 
    
         
            -
                this.prepareOptions();
         
     | 
| 
       486 
     | 
    
         
            -
                this._controls = { };
         
     | 
| 
       487 
     | 
    
         
            -
                arguments.callee.dealWithDeprecatedOptions(options); // DEPRECATION LAYER!!!
         
     | 
| 
       488 
     | 
    
         
            -
                Object.extend(this.options, options || { });
         
     | 
| 
       489 
     | 
    
         
            -
                if (!this.options.formId && this.element.id) {
         
     | 
| 
       490 
     | 
    
         
            -
                  this.options.formId = this.element.id + '-inplaceeditor';
         
     | 
| 
       491 
     | 
    
         
            -
                  if ($(this.options.formId))
         
     | 
| 
       492 
     | 
    
         
            -
                    this.options.formId = '';
         
     | 
| 
       493 
     | 
    
         
            -
                }
         
     | 
| 
       494 
     | 
    
         
            -
                if (this.options.externalControl)
         
     | 
| 
       495 
     | 
    
         
            -
                  this.options.externalControl = $(this.options.externalControl);
         
     | 
| 
       496 
     | 
    
         
            -
                if (!this.options.externalControl)
         
     | 
| 
       497 
     | 
    
         
            -
                  this.options.externalControlOnly = false;
         
     | 
| 
       498 
     | 
    
         
            -
                this._originalBackground = this.element.getStyle('background-color') || 'transparent';
         
     | 
| 
       499 
     | 
    
         
            -
                this.element.title = this.options.clickToEditText;
         
     | 
| 
       500 
     | 
    
         
            -
                this._boundCancelHandler = this.handleFormCancellation.bind(this);
         
     | 
| 
       501 
     | 
    
         
            -
                this._boundComplete = (this.options.onComplete || Prototype.emptyFunction).bind(this);
         
     | 
| 
       502 
     | 
    
         
            -
                this._boundFailureHandler = this.handleAJAXFailure.bind(this);
         
     | 
| 
       503 
     | 
    
         
            -
                this._boundSubmitHandler = this.handleFormSubmission.bind(this);
         
     | 
| 
       504 
     | 
    
         
            -
                this._boundWrapperHandler = this.wrapUp.bind(this);
         
     | 
| 
       505 
     | 
    
         
            -
                this.registerListeners();
         
     | 
| 
       506 
     | 
    
         
            -
              },
         
     | 
| 
       507 
     | 
    
         
            -
              checkForEscapeOrReturn: function(e) {
         
     | 
| 
       508 
     | 
    
         
            -
                if (!this._editing || e.ctrlKey || e.altKey || e.shiftKey) return;
         
     | 
| 
       509 
     | 
    
         
            -
                if (Event.KEY_ESC == e.keyCode)
         
     | 
| 
       510 
     | 
    
         
            -
                  this.handleFormCancellation(e);
         
     | 
| 
       511 
     | 
    
         
            -
                else if (Event.KEY_RETURN == e.keyCode)
         
     | 
| 
       512 
     | 
    
         
            -
                  this.handleFormSubmission(e);
         
     | 
| 
       513 
     | 
    
         
            -
              },
         
     | 
| 
       514 
     | 
    
         
            -
              createControl: function(mode, handler, extraClasses) {
         
     | 
| 
       515 
     | 
    
         
            -
                var control = this.options[mode + 'Control'];
         
     | 
| 
       516 
     | 
    
         
            -
                var text = this.options[mode + 'Text'];
         
     | 
| 
       517 
     | 
    
         
            -
                if ('button' == control) {
         
     | 
| 
       518 
     | 
    
         
            -
                  var btn = document.createElement('input');
         
     | 
| 
       519 
     | 
    
         
            -
                  btn.type = 'submit';
         
     | 
| 
       520 
     | 
    
         
            -
                  btn.value = text;
         
     | 
| 
       521 
     | 
    
         
            -
                  btn.className = 'editor_' + mode + '_button';
         
     | 
| 
       522 
     | 
    
         
            -
                  if ('cancel' == mode)
         
     | 
| 
       523 
     | 
    
         
            -
                    btn.onclick = this._boundCancelHandler;
         
     | 
| 
       524 
     | 
    
         
            -
                  this._form.appendChild(btn);
         
     | 
| 
       525 
     | 
    
         
            -
                  this._controls[mode] = btn;
         
     | 
| 
       526 
     | 
    
         
            -
                } else if ('link' == control) {
         
     | 
| 
       527 
     | 
    
         
            -
                  var link = document.createElement('a');
         
     | 
| 
       528 
     | 
    
         
            -
                  link.href = '#';
         
     | 
| 
       529 
     | 
    
         
            -
                  link.appendChild(document.createTextNode(text));
         
     | 
| 
       530 
     | 
    
         
            -
                  link.onclick = 'cancel' == mode ? this._boundCancelHandler : this._boundSubmitHandler;
         
     | 
| 
       531 
     | 
    
         
            -
                  link.className = 'editor_' + mode + '_link';
         
     | 
| 
       532 
     | 
    
         
            -
                  if (extraClasses)
         
     | 
| 
       533 
     | 
    
         
            -
                    link.className += ' ' + extraClasses;
         
     | 
| 
       534 
     | 
    
         
            -
                  this._form.appendChild(link);
         
     | 
| 
       535 
     | 
    
         
            -
                  this._controls[mode] = link;
         
     | 
| 
       536 
     | 
    
         
            -
                }
         
     | 
| 
       537 
     | 
    
         
            -
              },
         
     | 
| 
       538 
     | 
    
         
            -
              createEditField: function() {
         
     | 
| 
       539 
     | 
    
         
            -
                var text = (this.options.loadTextURL ? this.options.loadingText : this.getText());
         
     | 
| 
       540 
     | 
    
         
            -
                var fld;
         
     | 
| 
       541 
     | 
    
         
            -
                if (1 >= this.options.rows && !/\r|\n/.test(this.getText())) {
         
     | 
| 
       542 
     | 
    
         
            -
                  fld = document.createElement('input');
         
     | 
| 
       543 
     | 
    
         
            -
                  fld.type = 'text';
         
     | 
| 
       544 
     | 
    
         
            -
                  var size = this.options.size || this.options.cols || 0;
         
     | 
| 
       545 
     | 
    
         
            -
                  if (0 < size) fld.size = size;
         
     | 
| 
       546 
     | 
    
         
            -
                } else {
         
     | 
| 
       547 
     | 
    
         
            -
                  fld = document.createElement('textarea');
         
     | 
| 
       548 
     | 
    
         
            -
                  fld.rows = (1 >= this.options.rows ? this.options.autoRows : this.options.rows);
         
     | 
| 
       549 
     | 
    
         
            -
                  fld.cols = this.options.cols || 40;
         
     | 
| 
       550 
     | 
    
         
            -
                }
         
     | 
| 
       551 
     | 
    
         
            -
                fld.name = this.options.paramName;
         
     | 
| 
       552 
     | 
    
         
            -
                fld.value = text; // No HTML breaks conversion anymore
         
     | 
| 
       553 
     | 
    
         
            -
                fld.className = 'editor_field';
         
     | 
| 
       554 
     | 
    
         
            -
                if (this.options.submitOnBlur)
         
     | 
| 
       555 
     | 
    
         
            -
                  fld.onblur = this._boundSubmitHandler;
         
     | 
| 
       556 
     | 
    
         
            -
                this._controls.editor = fld;
         
     | 
| 
       557 
     | 
    
         
            -
                if (this.options.loadTextURL)
         
     | 
| 
       558 
     | 
    
         
            -
                  this.loadExternalText();
         
     | 
| 
       559 
     | 
    
         
            -
                this._form.appendChild(this._controls.editor);
         
     | 
| 
       560 
     | 
    
         
            -
              },
         
     | 
| 
       561 
     | 
    
         
            -
              createForm: function() {
         
     | 
| 
       562 
     | 
    
         
            -
                var ipe = this;
         
     | 
| 
       563 
     | 
    
         
            -
                function addText(mode, condition) {
         
     | 
| 
       564 
     | 
    
         
            -
                  var text = ipe.options['text' + mode + 'Controls'];
         
     | 
| 
       565 
     | 
    
         
            -
                  if (!text || condition === false) return;
         
     | 
| 
       566 
     | 
    
         
            -
                  ipe._form.appendChild(document.createTextNode(text));
         
     | 
| 
       567 
     | 
    
         
            -
                };
         
     | 
| 
       568 
     | 
    
         
            -
                this._form = $(document.createElement('form'));
         
     | 
| 
       569 
     | 
    
         
            -
                this._form.id = this.options.formId;
         
     | 
| 
       570 
     | 
    
         
            -
                this._form.addClassName(this.options.formClassName);
         
     | 
| 
       571 
     | 
    
         
            -
                this._form.onsubmit = this._boundSubmitHandler;
         
     | 
| 
       572 
     | 
    
         
            -
                this.createEditField();
         
     | 
| 
       573 
     | 
    
         
            -
                if ('textarea' == this._controls.editor.tagName.toLowerCase())
         
     | 
| 
       574 
     | 
    
         
            -
                  this._form.appendChild(document.createElement('br'));
         
     | 
| 
       575 
     | 
    
         
            -
                if (this.options.onFormCustomization)
         
     | 
| 
       576 
     | 
    
         
            -
                  this.options.onFormCustomization(this, this._form);
         
     | 
| 
       577 
     | 
    
         
            -
                addText('Before', this.options.okControl || this.options.cancelControl);
         
     | 
| 
       578 
     | 
    
         
            -
                this.createControl('ok', this._boundSubmitHandler);
         
     | 
| 
       579 
     | 
    
         
            -
                addText('Between', this.options.okControl && this.options.cancelControl);
         
     | 
| 
       580 
     | 
    
         
            -
                this.createControl('cancel', this._boundCancelHandler, 'editor_cancel');
         
     | 
| 
       581 
     | 
    
         
            -
                addText('After', this.options.okControl || this.options.cancelControl);
         
     | 
| 
       582 
     | 
    
         
            -
              },
         
     | 
| 
       583 
     | 
    
         
            -
              destroy: function() {
         
     | 
| 
       584 
     | 
    
         
            -
                if (this._oldInnerHTML)
         
     | 
| 
       585 
     | 
    
         
            -
                  this.element.innerHTML = this._oldInnerHTML;
         
     | 
| 
       586 
     | 
    
         
            -
                this.leaveEditMode();
         
     | 
| 
       587 
     | 
    
         
            -
                this.unregisterListeners();
         
     | 
| 
       588 
     | 
    
         
            -
              },
         
     | 
| 
       589 
     | 
    
         
            -
              enterEditMode: function(e) {
         
     | 
| 
       590 
     | 
    
         
            -
                if (this._saving || this._editing) return;
         
     | 
| 
       591 
     | 
    
         
            -
                this._editing = true;
         
     | 
| 
       592 
     | 
    
         
            -
                this.triggerCallback('onEnterEditMode');
         
     | 
| 
       593 
     | 
    
         
            -
                if (this.options.externalControl)
         
     | 
| 
       594 
     | 
    
         
            -
                  this.options.externalControl.hide();
         
     | 
| 
       595 
     | 
    
         
            -
                this.element.hide();
         
     | 
| 
       596 
     | 
    
         
            -
                this.createForm();
         
     | 
| 
       597 
     | 
    
         
            -
                this.element.parentNode.insertBefore(this._form, this.element);
         
     | 
| 
       598 
     | 
    
         
            -
                if (!this.options.loadTextURL)
         
     | 
| 
       599 
     | 
    
         
            -
                  this.postProcessEditField();
         
     | 
| 
       600 
     | 
    
         
            -
                if (e) Event.stop(e);
         
     | 
| 
       601 
     | 
    
         
            -
              },
         
     | 
| 
       602 
     | 
    
         
            -
              enterHover: function(e) {
         
     | 
| 
       603 
     | 
    
         
            -
                if (this.options.hoverClassName)
         
     | 
| 
       604 
     | 
    
         
            -
                  this.element.addClassName(this.options.hoverClassName);
         
     | 
| 
       605 
     | 
    
         
            -
                if (this._saving) return;
         
     | 
| 
       606 
     | 
    
         
            -
                this.triggerCallback('onEnterHover');
         
     | 
| 
       607 
     | 
    
         
            -
              },
         
     | 
| 
       608 
     | 
    
         
            -
              getText: function() {
         
     | 
| 
       609 
     | 
    
         
            -
                return this.element.innerHTML.unescapeHTML();
         
     | 
| 
       610 
     | 
    
         
            -
              },
         
     | 
| 
       611 
     | 
    
         
            -
              handleAJAXFailure: function(transport) {
         
     | 
| 
       612 
     | 
    
         
            -
                this.triggerCallback('onFailure', transport);
         
     | 
| 
       613 
     | 
    
         
            -
                if (this._oldInnerHTML) {
         
     | 
| 
       614 
     | 
    
         
            -
                  this.element.innerHTML = this._oldInnerHTML;
         
     | 
| 
       615 
     | 
    
         
            -
                  this._oldInnerHTML = null;
         
     | 
| 
       616 
     | 
    
         
            -
                }
         
     | 
| 
       617 
     | 
    
         
            -
              },
         
     | 
| 
       618 
     | 
    
         
            -
              handleFormCancellation: function(e) {
         
     | 
| 
       619 
     | 
    
         
            -
                this.wrapUp();
         
     | 
| 
       620 
     | 
    
         
            -
                if (e) Event.stop(e);
         
     | 
| 
       621 
     | 
    
         
            -
              },
         
     | 
| 
       622 
     | 
    
         
            -
              handleFormSubmission: function(e) {
         
     | 
| 
       623 
     | 
    
         
            -
                var form = this._form;
         
     | 
| 
       624 
     | 
    
         
            -
                var value = $F(this._controls.editor);
         
     | 
| 
       625 
     | 
    
         
            -
                this.prepareSubmission();
         
     | 
| 
       626 
     | 
    
         
            -
                var params = this.options.callback(form, value) || '';
         
     | 
| 
       627 
     | 
    
         
            -
                if (Object.isString(params))
         
     | 
| 
       628 
     | 
    
         
            -
                  params = params.toQueryParams();
         
     | 
| 
       629 
     | 
    
         
            -
                params.editorId = this.element.id;
         
     | 
| 
       630 
     | 
    
         
            -
                if (this.options.htmlResponse) {
         
     | 
| 
       631 
     | 
    
         
            -
                  var options = Object.extend({ evalScripts: true }, this.options.ajaxOptions);
         
     | 
| 
       632 
     | 
    
         
            -
                  Object.extend(options, {
         
     | 
| 
       633 
     | 
    
         
            -
                    parameters: params,
         
     | 
| 
       634 
     | 
    
         
            -
                    onComplete: this._boundWrapperHandler,
         
     | 
| 
       635 
     | 
    
         
            -
                    onFailure: this._boundFailureHandler
         
     | 
| 
       636 
     | 
    
         
            -
                  });
         
     | 
| 
       637 
     | 
    
         
            -
                  new Ajax.Updater({ success: this.element }, this.url, options);
         
     | 
| 
       638 
     | 
    
         
            -
                } else {
         
     | 
| 
       639 
     | 
    
         
            -
                  var options = Object.extend({ method: 'get' }, this.options.ajaxOptions);
         
     | 
| 
       640 
     | 
    
         
            -
                  Object.extend(options, {
         
     | 
| 
       641 
     | 
    
         
            -
                    parameters: params,
         
     | 
| 
       642 
     | 
    
         
            -
                    onComplete: this._boundWrapperHandler,
         
     | 
| 
       643 
     | 
    
         
            -
                    onFailure: this._boundFailureHandler
         
     | 
| 
       644 
     | 
    
         
            -
                  });
         
     | 
| 
       645 
     | 
    
         
            -
                  new Ajax.Request(this.url, options);
         
     | 
| 
       646 
     | 
    
         
            -
                }
         
     | 
| 
       647 
     | 
    
         
            -
                if (e) Event.stop(e);
         
     | 
| 
       648 
     | 
    
         
            -
              },
         
     | 
| 
       649 
     | 
    
         
            -
              leaveEditMode: function() {
         
     | 
| 
       650 
     | 
    
         
            -
                this.element.removeClassName(this.options.savingClassName);
         
     | 
| 
       651 
     | 
    
         
            -
                this.removeForm();
         
     | 
| 
       652 
     | 
    
         
            -
                this.leaveHover();
         
     | 
| 
       653 
     | 
    
         
            -
                this.element.style.backgroundColor = this._originalBackground;
         
     | 
| 
       654 
     | 
    
         
            -
                this.element.show();
         
     | 
| 
       655 
     | 
    
         
            -
                if (this.options.externalControl)
         
     | 
| 
       656 
     | 
    
         
            -
                  this.options.externalControl.show();
         
     | 
| 
       657 
     | 
    
         
            -
                this._saving = false;
         
     | 
| 
       658 
     | 
    
         
            -
                this._editing = false;
         
     | 
| 
       659 
     | 
    
         
            -
                this._oldInnerHTML = null;
         
     | 
| 
       660 
     | 
    
         
            -
                this.triggerCallback('onLeaveEditMode');
         
     | 
| 
       661 
     | 
    
         
            -
              },
         
     | 
| 
       662 
     | 
    
         
            -
              leaveHover: function(e) {
         
     | 
| 
       663 
     | 
    
         
            -
                if (this.options.hoverClassName)
         
     | 
| 
       664 
     | 
    
         
            -
                  this.element.removeClassName(this.options.hoverClassName);
         
     | 
| 
       665 
     | 
    
         
            -
                if (this._saving) return;
         
     | 
| 
       666 
     | 
    
         
            -
                this.triggerCallback('onLeaveHover');
         
     | 
| 
       667 
     | 
    
         
            -
              },
         
     | 
| 
       668 
     | 
    
         
            -
              loadExternalText: function() {
         
     | 
| 
       669 
     | 
    
         
            -
                this._form.addClassName(this.options.loadingClassName);
         
     | 
| 
       670 
     | 
    
         
            -
                this._controls.editor.disabled = true;
         
     | 
| 
       671 
     | 
    
         
            -
                var options = Object.extend({ method: 'get' }, this.options.ajaxOptions);
         
     | 
| 
       672 
     | 
    
         
            -
                Object.extend(options, {
         
     | 
| 
       673 
     | 
    
         
            -
                  parameters: 'editorId=' + encodeURIComponent(this.element.id),
         
     | 
| 
       674 
     | 
    
         
            -
                  onComplete: Prototype.emptyFunction,
         
     | 
| 
       675 
     | 
    
         
            -
                  onSuccess: function(transport) {
         
     | 
| 
       676 
     | 
    
         
            -
                    this._form.removeClassName(this.options.loadingClassName);
         
     | 
| 
       677 
     | 
    
         
            -
                    var text = transport.responseText;
         
     | 
| 
       678 
     | 
    
         
            -
                    if (this.options.stripLoadedTextTags)
         
     | 
| 
       679 
     | 
    
         
            -
                      text = text.stripTags();
         
     | 
| 
       680 
     | 
    
         
            -
                    this._controls.editor.value = text;
         
     | 
| 
       681 
     | 
    
         
            -
                    this._controls.editor.disabled = false;
         
     | 
| 
       682 
     | 
    
         
            -
                    this.postProcessEditField();
         
     | 
| 
       683 
     | 
    
         
            -
                  }.bind(this),
         
     | 
| 
       684 
     | 
    
         
            -
                  onFailure: this._boundFailureHandler
         
     | 
| 
       685 
     | 
    
         
            -
                });
         
     | 
| 
       686 
     | 
    
         
            -
                new Ajax.Request(this.options.loadTextURL, options);
         
     | 
| 
       687 
     | 
    
         
            -
              },
         
     | 
| 
       688 
     | 
    
         
            -
              postProcessEditField: function() {
         
     | 
| 
       689 
     | 
    
         
            -
                var fpc = this.options.fieldPostCreation;
         
     | 
| 
       690 
     | 
    
         
            -
                if (fpc)
         
     | 
| 
       691 
     | 
    
         
            -
                  $(this._controls.editor)['focus' == fpc ? 'focus' : 'activate']();
         
     | 
| 
       692 
     | 
    
         
            -
              },
         
     | 
| 
       693 
     | 
    
         
            -
              prepareOptions: function() {
         
     | 
| 
       694 
     | 
    
         
            -
                this.options = Object.clone(Ajax.InPlaceEditor.DefaultOptions);
         
     | 
| 
       695 
     | 
    
         
            -
                Object.extend(this.options, Ajax.InPlaceEditor.DefaultCallbacks);
         
     | 
| 
       696 
     | 
    
         
            -
                [this._extraDefaultOptions].flatten().compact().each(function(defs) {
         
     | 
| 
       697 
     | 
    
         
            -
                  Object.extend(this.options, defs);
         
     | 
| 
       698 
     | 
    
         
            -
                }.bind(this));
         
     | 
| 
       699 
     | 
    
         
            -
              },
         
     | 
| 
       700 
     | 
    
         
            -
              prepareSubmission: function() {
         
     | 
| 
       701 
     | 
    
         
            -
                this._saving = true;
         
     | 
| 
       702 
     | 
    
         
            -
                this.removeForm();
         
     | 
| 
       703 
     | 
    
         
            -
                this.leaveHover();
         
     | 
| 
       704 
     | 
    
         
            -
                this.showSaving();
         
     | 
| 
       705 
     | 
    
         
            -
              },
         
     | 
| 
       706 
     | 
    
         
            -
              registerListeners: function() {
         
     | 
| 
       707 
     | 
    
         
            -
                this._listeners = { };
         
     | 
| 
       708 
     | 
    
         
            -
                var listener;
         
     | 
| 
       709 
     | 
    
         
            -
                $H(Ajax.InPlaceEditor.Listeners).each(function(pair) {
         
     | 
| 
       710 
     | 
    
         
            -
                  listener = this[pair.value].bind(this);
         
     | 
| 
       711 
     | 
    
         
            -
                  this._listeners[pair.key] = listener;
         
     | 
| 
       712 
     | 
    
         
            -
                  if (!this.options.externalControlOnly)
         
     | 
| 
       713 
     | 
    
         
            -
                    this.element.observe(pair.key, listener);
         
     | 
| 
       714 
     | 
    
         
            -
                  if (this.options.externalControl)
         
     | 
| 
       715 
     | 
    
         
            -
                    this.options.externalControl.observe(pair.key, listener);
         
     | 
| 
       716 
     | 
    
         
            -
                }.bind(this));
         
     | 
| 
       717 
     | 
    
         
            -
              },
         
     | 
| 
       718 
     | 
    
         
            -
              removeForm: function() {
         
     | 
| 
       719 
     | 
    
         
            -
                if (!this._form) return;
         
     | 
| 
       720 
     | 
    
         
            -
                this._form.remove();
         
     | 
| 
       721 
     | 
    
         
            -
                this._form = null;
         
     | 
| 
       722 
     | 
    
         
            -
                this._controls = { };
         
     | 
| 
       723 
     | 
    
         
            -
              },
         
     | 
| 
       724 
     | 
    
         
            -
              showSaving: function() {
         
     | 
| 
       725 
     | 
    
         
            -
                this._oldInnerHTML = this.element.innerHTML;
         
     | 
| 
       726 
     | 
    
         
            -
                this.element.innerHTML = this.options.savingText;
         
     | 
| 
       727 
     | 
    
         
            -
                this.element.addClassName(this.options.savingClassName);
         
     | 
| 
       728 
     | 
    
         
            -
                this.element.style.backgroundColor = this._originalBackground;
         
     | 
| 
       729 
     | 
    
         
            -
                this.element.show();
         
     | 
| 
       730 
     | 
    
         
            -
              },
         
     | 
| 
       731 
     | 
    
         
            -
              triggerCallback: function(cbName, arg) {
         
     | 
| 
       732 
     | 
    
         
            -
                if ('function' == typeof this.options[cbName]) {
         
     | 
| 
       733 
     | 
    
         
            -
                  this.options[cbName](this, arg);
         
     | 
| 
       734 
     | 
    
         
            -
                }
         
     | 
| 
       735 
     | 
    
         
            -
              },
         
     | 
| 
       736 
     | 
    
         
            -
              unregisterListeners: function() {
         
     | 
| 
       737 
     | 
    
         
            -
                $H(this._listeners).each(function(pair) {
         
     | 
| 
       738 
     | 
    
         
            -
                  if (!this.options.externalControlOnly)
         
     | 
| 
       739 
     | 
    
         
            -
                    this.element.stopObserving(pair.key, pair.value);
         
     | 
| 
       740 
     | 
    
         
            -
                  if (this.options.externalControl)
         
     | 
| 
       741 
     | 
    
         
            -
                    this.options.externalControl.stopObserving(pair.key, pair.value);
         
     | 
| 
       742 
     | 
    
         
            -
                }.bind(this));
         
     | 
| 
       743 
     | 
    
         
            -
              },
         
     | 
| 
       744 
     | 
    
         
            -
              wrapUp: function(transport) {
         
     | 
| 
       745 
     | 
    
         
            -
                this.leaveEditMode();
         
     | 
| 
       746 
     | 
    
         
            -
                // Can't use triggerCallback due to backward compatibility: requires
         
     | 
| 
       747 
     | 
    
         
            -
                // binding + direct element
         
     | 
| 
       748 
     | 
    
         
            -
                this._boundComplete(transport, this.element);
         
     | 
| 
       749 
     | 
    
         
            -
              }
         
     | 
| 
       750 
     | 
    
         
            -
            });
         
     | 
| 
       751 
     | 
    
         
            -
             
     | 
| 
       752 
     | 
    
         
            -
            Object.extend(Ajax.InPlaceEditor.prototype, {
         
     | 
| 
       753 
     | 
    
         
            -
              dispose: Ajax.InPlaceEditor.prototype.destroy
         
     | 
| 
       754 
     | 
    
         
            -
            });
         
     | 
| 
       755 
     | 
    
         
            -
             
     | 
| 
       756 
     | 
    
         
            -
            Ajax.InPlaceCollectionEditor = Class.create(Ajax.InPlaceEditor, {
         
     | 
| 
       757 
     | 
    
         
            -
              initialize: function($super, element, url, options) {
         
     | 
| 
       758 
     | 
    
         
            -
                this._extraDefaultOptions = Ajax.InPlaceCollectionEditor.DefaultOptions;
         
     | 
| 
       759 
     | 
    
         
            -
                $super(element, url, options);
         
     | 
| 
       760 
     | 
    
         
            -
              },
         
     | 
| 
       761 
     | 
    
         
            -
             
     | 
| 
       762 
     | 
    
         
            -
              createEditField: function() {
         
     | 
| 
       763 
     | 
    
         
            -
                var list = document.createElement('select');
         
     | 
| 
       764 
     | 
    
         
            -
                list.name = this.options.paramName;
         
     | 
| 
       765 
     | 
    
         
            -
                list.size = 1;
         
     | 
| 
       766 
     | 
    
         
            -
                this._controls.editor = list;
         
     | 
| 
       767 
     | 
    
         
            -
                this._collection = this.options.collection || [];
         
     | 
| 
       768 
     | 
    
         
            -
                if (this.options.loadCollectionURL)
         
     | 
| 
       769 
     | 
    
         
            -
                  this.loadCollection();
         
     | 
| 
       770 
     | 
    
         
            -
                else
         
     | 
| 
       771 
     | 
    
         
            -
                  this.checkForExternalText();
         
     | 
| 
       772 
     | 
    
         
            -
                this._form.appendChild(this._controls.editor);
         
     | 
| 
       773 
     | 
    
         
            -
              },
         
     | 
| 
       774 
     | 
    
         
            -
             
     | 
| 
       775 
     | 
    
         
            -
              loadCollection: function() {
         
     | 
| 
       776 
     | 
    
         
            -
                this._form.addClassName(this.options.loadingClassName);
         
     | 
| 
       777 
     | 
    
         
            -
                this.showLoadingText(this.options.loadingCollectionText);
         
     | 
| 
       778 
     | 
    
         
            -
                var options = Object.extend({ method: 'get' }, this.options.ajaxOptions);
         
     | 
| 
       779 
     | 
    
         
            -
                Object.extend(options, {
         
     | 
| 
       780 
     | 
    
         
            -
                  parameters: 'editorId=' + encodeURIComponent(this.element.id),
         
     | 
| 
       781 
     | 
    
         
            -
                  onComplete: Prototype.emptyFunction,
         
     | 
| 
       782 
     | 
    
         
            -
                  onSuccess: function(transport) {
         
     | 
| 
       783 
     | 
    
         
            -
                    var js = transport.responseText.strip();
         
     | 
| 
       784 
     | 
    
         
            -
                    if (!/^\[.*\]$/.test(js)) // TODO: improve sanity check
         
     | 
| 
       785 
     | 
    
         
            -
                      throw('Server returned an invalid collection representation.');
         
     | 
| 
       786 
     | 
    
         
            -
                    this._collection = eval(js);
         
     | 
| 
       787 
     | 
    
         
            -
                    this.checkForExternalText();
         
     | 
| 
       788 
     | 
    
         
            -
                  }.bind(this),
         
     | 
| 
       789 
     | 
    
         
            -
                  onFailure: this.onFailure
         
     | 
| 
       790 
     | 
    
         
            -
                });
         
     | 
| 
       791 
     | 
    
         
            -
                new Ajax.Request(this.options.loadCollectionURL, options);
         
     | 
| 
       792 
     | 
    
         
            -
              },
         
     | 
| 
       793 
     | 
    
         
            -
             
     | 
| 
       794 
     | 
    
         
            -
              showLoadingText: function(text) {
         
     | 
| 
       795 
     | 
    
         
            -
                this._controls.editor.disabled = true;
         
     | 
| 
       796 
     | 
    
         
            -
                var tempOption = this._controls.editor.firstChild;
         
     | 
| 
       797 
     | 
    
         
            -
                if (!tempOption) {
         
     | 
| 
       798 
     | 
    
         
            -
                  tempOption = document.createElement('option');
         
     | 
| 
       799 
     | 
    
         
            -
                  tempOption.value = '';
         
     | 
| 
       800 
     | 
    
         
            -
                  this._controls.editor.appendChild(tempOption);
         
     | 
| 
       801 
     | 
    
         
            -
                  tempOption.selected = true;
         
     | 
| 
       802 
     | 
    
         
            -
                }
         
     | 
| 
       803 
     | 
    
         
            -
                tempOption.update((text || '').stripScripts().stripTags());
         
     | 
| 
       804 
     | 
    
         
            -
              },
         
     | 
| 
       805 
     | 
    
         
            -
             
     | 
| 
       806 
     | 
    
         
            -
              checkForExternalText: function() {
         
     | 
| 
       807 
     | 
    
         
            -
                this._text = this.getText();
         
     | 
| 
       808 
     | 
    
         
            -
                if (this.options.loadTextURL)
         
     | 
| 
       809 
     | 
    
         
            -
                  this.loadExternalText();
         
     | 
| 
       810 
     | 
    
         
            -
                else
         
     | 
| 
       811 
     | 
    
         
            -
                  this.buildOptionList();
         
     | 
| 
       812 
     | 
    
         
            -
              },
         
     | 
| 
       813 
     | 
    
         
            -
             
     | 
| 
       814 
     | 
    
         
            -
              loadExternalText: function() {
         
     | 
| 
       815 
     | 
    
         
            -
                this.showLoadingText(this.options.loadingText);
         
     | 
| 
       816 
     | 
    
         
            -
                var options = Object.extend({ method: 'get' }, this.options.ajaxOptions);
         
     | 
| 
       817 
     | 
    
         
            -
                Object.extend(options, {
         
     | 
| 
       818 
     | 
    
         
            -
                  parameters: 'editorId=' + encodeURIComponent(this.element.id),
         
     | 
| 
       819 
     | 
    
         
            -
                  onComplete: Prototype.emptyFunction,
         
     | 
| 
       820 
     | 
    
         
            -
                  onSuccess: function(transport) {
         
     | 
| 
       821 
     | 
    
         
            -
                    this._text = transport.responseText.strip();
         
     | 
| 
       822 
     | 
    
         
            -
                    this.buildOptionList();
         
     | 
| 
       823 
     | 
    
         
            -
                  }.bind(this),
         
     | 
| 
       824 
     | 
    
         
            -
                  onFailure: this.onFailure
         
     | 
| 
       825 
     | 
    
         
            -
                });
         
     | 
| 
       826 
     | 
    
         
            -
                new Ajax.Request(this.options.loadTextURL, options);
         
     | 
| 
       827 
     | 
    
         
            -
              },
         
     | 
| 
       828 
     | 
    
         
            -
             
     | 
| 
       829 
     | 
    
         
            -
              buildOptionList: function() {
         
     | 
| 
       830 
     | 
    
         
            -
                this._form.removeClassName(this.options.loadingClassName);
         
     | 
| 
       831 
     | 
    
         
            -
                this._collection = this._collection.map(function(entry) {
         
     | 
| 
       832 
     | 
    
         
            -
                  return 2 === entry.length ? entry : [entry, entry].flatten();
         
     | 
| 
       833 
     | 
    
         
            -
                });
         
     | 
| 
       834 
     | 
    
         
            -
                var marker = ('value' in this.options) ? this.options.value : this._text;
         
     | 
| 
       835 
     | 
    
         
            -
                var textFound = this._collection.any(function(entry) {
         
     | 
| 
       836 
     | 
    
         
            -
                  return entry[0] == marker;
         
     | 
| 
       837 
     | 
    
         
            -
                }.bind(this));
         
     | 
| 
       838 
     | 
    
         
            -
                this._controls.editor.update('');
         
     | 
| 
       839 
     | 
    
         
            -
                var option;
         
     | 
| 
       840 
     | 
    
         
            -
                this._collection.each(function(entry, index) {
         
     | 
| 
       841 
     | 
    
         
            -
                  option = document.createElement('option');
         
     | 
| 
       842 
     | 
    
         
            -
                  option.value = entry[0];
         
     | 
| 
       843 
     | 
    
         
            -
                  option.selected = textFound ? entry[0] == marker : 0 == index;
         
     | 
| 
       844 
     | 
    
         
            -
                  option.appendChild(document.createTextNode(entry[1]));
         
     | 
| 
       845 
     | 
    
         
            -
                  this._controls.editor.appendChild(option);
         
     | 
| 
       846 
     | 
    
         
            -
                }.bind(this));
         
     | 
| 
       847 
     | 
    
         
            -
                this._controls.editor.disabled = false;
         
     | 
| 
       848 
     | 
    
         
            -
                Field.scrollFreeActivate(this._controls.editor);
         
     | 
| 
       849 
     | 
    
         
            -
              }
         
     | 
| 
       850 
     | 
    
         
            -
            });
         
     | 
| 
       851 
     | 
    
         
            -
             
     | 
| 
       852 
     | 
    
         
            -
            //**** DEPRECATION LAYER FOR InPlace[Collection]Editor! ****
         
     | 
| 
       853 
     | 
    
         
            -
            //**** This only  exists for a while,  in order to  let ****
         
     | 
| 
       854 
     | 
    
         
            -
            //**** users adapt to  the new API.  Read up on the new ****
         
     | 
| 
       855 
     | 
    
         
            -
            //**** API and convert your code to it ASAP!            ****
         
     | 
| 
       856 
     | 
    
         
            -
             
     | 
| 
       857 
     | 
    
         
            -
            Ajax.InPlaceEditor.prototype.initialize.dealWithDeprecatedOptions = function(options) {
         
     | 
| 
       858 
     | 
    
         
            -
              if (!options) return;
         
     | 
| 
       859 
     | 
    
         
            -
              function fallback(name, expr) {
         
     | 
| 
       860 
     | 
    
         
            -
                if (name in options || expr === undefined) return;
         
     | 
| 
       861 
     | 
    
         
            -
                options[name] = expr;
         
     | 
| 
       862 
     | 
    
         
            -
              };
         
     | 
| 
       863 
     | 
    
         
            -
              fallback('cancelControl', (options.cancelLink ? 'link' : (options.cancelButton ? 'button' :
         
     | 
| 
       864 
     | 
    
         
            -
                options.cancelLink == options.cancelButton == false ? false : undefined)));
         
     | 
| 
       865 
     | 
    
         
            -
              fallback('okControl', (options.okLink ? 'link' : (options.okButton ? 'button' :
         
     | 
| 
       866 
     | 
    
         
            -
                options.okLink == options.okButton == false ? false : undefined)));
         
     | 
| 
       867 
     | 
    
         
            -
              fallback('highlightColor', options.highlightcolor);
         
     | 
| 
       868 
     | 
    
         
            -
              fallback('highlightEndColor', options.highlightendcolor);
         
     | 
| 
       869 
     | 
    
         
            -
            };
         
     | 
| 
       870 
     | 
    
         
            -
             
     | 
| 
       871 
     | 
    
         
            -
            Object.extend(Ajax.InPlaceEditor, {
         
     | 
| 
       872 
     | 
    
         
            -
              DefaultOptions: {
         
     | 
| 
       873 
     | 
    
         
            -
                ajaxOptions: { },
         
     | 
| 
       874 
     | 
    
         
            -
                autoRows: 3,                                // Use when multi-line w/ rows == 1
         
     | 
| 
       875 
     | 
    
         
            -
                cancelControl: 'link',                      // 'link'|'button'|false
         
     | 
| 
       876 
     | 
    
         
            -
                cancelText: 'cancel',
         
     | 
| 
       877 
     | 
    
         
            -
                clickToEditText: 'Click to edit',
         
     | 
| 
       878 
     | 
    
         
            -
                externalControl: null,                      // id|elt
         
     | 
| 
       879 
     | 
    
         
            -
                externalControlOnly: false,
         
     | 
| 
       880 
     | 
    
         
            -
                fieldPostCreation: 'activate',              // 'activate'|'focus'|false
         
     | 
| 
       881 
     | 
    
         
            -
                formClassName: 'inplaceeditor-form',
         
     | 
| 
       882 
     | 
    
         
            -
                formId: null,                               // id|elt
         
     | 
| 
       883 
     | 
    
         
            -
                highlightColor: '#ffff99',
         
     | 
| 
       884 
     | 
    
         
            -
                highlightEndColor: '#ffffff',
         
     | 
| 
       885 
     | 
    
         
            -
                hoverClassName: '',
         
     | 
| 
       886 
     | 
    
         
            -
                htmlResponse: true,
         
     | 
| 
       887 
     | 
    
         
            -
                loadingClassName: 'inplaceeditor-loading',
         
     | 
| 
       888 
     | 
    
         
            -
                loadingText: 'Loading...',
         
     | 
| 
       889 
     | 
    
         
            -
                okControl: 'button',                        // 'link'|'button'|false
         
     | 
| 
       890 
     | 
    
         
            -
                okText: 'ok',
         
     | 
| 
       891 
     | 
    
         
            -
                paramName: 'value',
         
     | 
| 
       892 
     | 
    
         
            -
                rows: 1,                                    // If 1 and multi-line, uses autoRows
         
     | 
| 
       893 
     | 
    
         
            -
                savingClassName: 'inplaceeditor-saving',
         
     | 
| 
       894 
     | 
    
         
            -
                savingText: 'Saving...',
         
     | 
| 
       895 
     | 
    
         
            -
                size: 0,
         
     | 
| 
       896 
     | 
    
         
            -
                stripLoadedTextTags: false,
         
     | 
| 
       897 
     | 
    
         
            -
                submitOnBlur: false,
         
     | 
| 
       898 
     | 
    
         
            -
                textAfterControls: '',
         
     | 
| 
       899 
     | 
    
         
            -
                textBeforeControls: '',
         
     | 
| 
       900 
     | 
    
         
            -
                textBetweenControls: ''
         
     | 
| 
       901 
     | 
    
         
            -
              },
         
     | 
| 
       902 
     | 
    
         
            -
              DefaultCallbacks: {
         
     | 
| 
       903 
     | 
    
         
            -
                callback: function(form) {
         
     | 
| 
       904 
     | 
    
         
            -
                  return Form.serialize(form);
         
     | 
| 
       905 
     | 
    
         
            -
                },
         
     | 
| 
       906 
     | 
    
         
            -
                onComplete: function(transport, element) {
         
     | 
| 
       907 
     | 
    
         
            -
                  // For backward compatibility, this one is bound to the IPE, and passes
         
     | 
| 
       908 
     | 
    
         
            -
                  // the element directly.  It was too often customized, so we don't break it.
         
     | 
| 
       909 
     | 
    
         
            -
                  new Effect.Highlight(element, {
         
     | 
| 
       910 
     | 
    
         
            -
                    startcolor: this.options.highlightColor, keepBackgroundImage: true });
         
     | 
| 
       911 
     | 
    
         
            -
                },
         
     | 
| 
       912 
     | 
    
         
            -
                onEnterEditMode: null,
         
     | 
| 
       913 
     | 
    
         
            -
                onEnterHover: function(ipe) {
         
     | 
| 
       914 
     | 
    
         
            -
                  ipe.element.style.backgroundColor = ipe.options.highlightColor;
         
     | 
| 
       915 
     | 
    
         
            -
                  if (ipe._effect)
         
     | 
| 
       916 
     | 
    
         
            -
                    ipe._effect.cancel();
         
     | 
| 
       917 
     | 
    
         
            -
                },
         
     | 
| 
       918 
     | 
    
         
            -
                onFailure: function(transport, ipe) {
         
     | 
| 
       919 
     | 
    
         
            -
                  alert('Error communication with the server: ' + transport.responseText.stripTags());
         
     | 
| 
       920 
     | 
    
         
            -
                },
         
     | 
| 
       921 
     | 
    
         
            -
                onFormCustomization: null, // Takes the IPE and its generated form, after editor, before controls.
         
     | 
| 
       922 
     | 
    
         
            -
                onLeaveEditMode: null,
         
     | 
| 
       923 
     | 
    
         
            -
                onLeaveHover: function(ipe) {
         
     | 
| 
       924 
     | 
    
         
            -
                  ipe._effect = new Effect.Highlight(ipe.element, {
         
     | 
| 
       925 
     | 
    
         
            -
                    startcolor: ipe.options.highlightColor, endcolor: ipe.options.highlightEndColor,
         
     | 
| 
       926 
     | 
    
         
            -
                    restorecolor: ipe._originalBackground, keepBackgroundImage: true
         
     | 
| 
       927 
     | 
    
         
            -
                  });
         
     | 
| 
       928 
     | 
    
         
            -
                }
         
     | 
| 
       929 
     | 
    
         
            -
              },
         
     | 
| 
       930 
     | 
    
         
            -
              Listeners: {
         
     | 
| 
       931 
     | 
    
         
            -
                click: 'enterEditMode',
         
     | 
| 
       932 
     | 
    
         
            -
                keydown: 'checkForEscapeOrReturn',
         
     | 
| 
       933 
     | 
    
         
            -
                mouseover: 'enterHover',
         
     | 
| 
       934 
     | 
    
         
            -
                mouseout: 'leaveHover'
         
     | 
| 
       935 
     | 
    
         
            -
              }
         
     | 
| 
       936 
     | 
    
         
            -
            });
         
     | 
| 
       937 
     | 
    
         
            -
             
     | 
| 
       938 
     | 
    
         
            -
            Ajax.InPlaceCollectionEditor.DefaultOptions = {
         
     | 
| 
       939 
     | 
    
         
            -
              loadingCollectionText: 'Loading options...'
         
     | 
| 
       940 
     | 
    
         
            -
            };
         
     | 
| 
       941 
     | 
    
         
            -
             
     | 
| 
       942 
     | 
    
         
            -
            // Delayed observer, like Form.Element.Observer,
         
     | 
| 
       943 
     | 
    
         
            -
            // but waits for delay after last key input
         
     | 
| 
       944 
     | 
    
         
            -
            // Ideal for live-search fields
         
     | 
| 
       945 
     | 
    
         
            -
             
     | 
| 
       946 
     | 
    
         
            -
            Form.Element.DelayedObserver = Class.create({
         
     | 
| 
       947 
     | 
    
         
            -
              initialize: function(element, delay, callback) {
         
     | 
| 
       948 
     | 
    
         
            -
                this.delay     = delay || 0.5;
         
     | 
| 
       949 
     | 
    
         
            -
                this.element   = $(element);
         
     | 
| 
       950 
     | 
    
         
            -
                this.callback  = callback;
         
     | 
| 
       951 
     | 
    
         
            -
                this.timer     = null;
         
     | 
| 
       952 
     | 
    
         
            -
                this.lastValue = $F(this.element);
         
     | 
| 
       953 
     | 
    
         
            -
                Event.observe(this.element,'keyup',this.delayedListener.bindAsEventListener(this));
         
     | 
| 
       954 
     | 
    
         
            -
              },
         
     | 
| 
       955 
     | 
    
         
            -
              delayedListener: function(event) {
         
     | 
| 
       956 
     | 
    
         
            -
                if(this.lastValue == $F(this.element)) return;
         
     | 
| 
       957 
     | 
    
         
            -
                if(this.timer) clearTimeout(this.timer);
         
     | 
| 
       958 
     | 
    
         
            -
                this.timer = setTimeout(this.onTimerEvent.bind(this), this.delay * 1000);
         
     | 
| 
       959 
     | 
    
         
            -
                this.lastValue = $F(this.element);
         
     | 
| 
       960 
     | 
    
         
            -
              },
         
     | 
| 
       961 
     | 
    
         
            -
              onTimerEvent: function() {
         
     | 
| 
       962 
     | 
    
         
            -
                this.timer = null;
         
     | 
| 
       963 
     | 
    
         
            -
                this.callback(this.element, $F(this.element));
         
     | 
| 
       964 
     | 
    
         
            -
              }
         
     | 
| 
       965 
     | 
    
         
            -
            });
         
     |