Revision 441:cbce1fd3b1b7 public/javascripts/.svn/text-base

View differences:

public/javascripts/.svn/text-base/application.js.svn-base
40 40
	}
41 41
}
42 42

  
43
function collapseAllRowGroups(el) {
44
  var tbody = Element.up(el, 'tbody');
45
  tbody.childElements('tr').each(function(tr) {
46
    if (tr.hasClassName('group')) {
47
      tr.removeClassName('open');
48
    } else {
49
      tr.hide();
50
    }
51
  })
52
}
53

  
54
function expandAllRowGroups(el) {
55
  var tbody = Element.up(el, 'tbody');
56
  tbody.childElements('tr').each(function(tr) {
57
    if (tr.hasClassName('group')) {
58
      tr.addClassName('open');
59
    } else {
60
      tr.show();
61
    }
62
  })
63
}
64

  
65
function toggleAllRowGroups(el) {
66
	var tr = Element.up(el, 'tr');
67
  if (tr.hasClassName('open')) {
68
    collapseAllRowGroups(el);
69
  } else {
70
    expandAllRowGroups(el);
71
  }
72
}
73

  
43 74
function toggleFieldset(el) {
44 75
	var fieldset = Element.up(el, 'fieldset');
45 76
	fieldset.toggleClassName('collapsed');
......
299 330
	}
300 331
});
301 332

  
302
/* shows and hides ajax indicator */
333
/* 
334
 * 1 - registers a callback which copies the csrf token into the
335
 * X-CSRF-Token header with each ajax request.  Necessary to 
336
 * work with rails applications which have fixed
337
 * CVE-2011-0447
338
 * 2 - shows and hides ajax indicator
339
 */
303 340
Ajax.Responders.register({
304
    onCreate: function(){
341
    onCreate: function(request){
342
        var csrf_meta_tag = $$('meta[name=csrf-token]')[0];
343

  
344
        if (csrf_meta_tag) {
345
            var header = 'X-CSRF-Token',
346
                token = csrf_meta_tag.readAttribute('content');
347

  
348
            if (!request.options.requestHeaders) {
349
              request.options.requestHeaders = {};
350
            }
351
            request.options.requestHeaders[header] = token;
352
          }
353

  
305 354
        if ($('ajax-indicator') && Ajax.activeRequestCount > 0) {
306 355
            Element.show('ajax-indicator');
307 356
        }
public/javascripts/.svn/text-base/context_menu.js.svn-base
36 36

  
37 37
  Click: function(e) {
38 38
  	this.hideMenu();
39
  	if (Event.element(e).tagName == 'A') { return; }
39
  	if (Event.element(e).tagName == 'A' || Event.element(e).tagName == 'IMG') { return; }
40 40
    if (Event.isLeftClick(e) || (navigator.appVersion.match(/\bMSIE\b/))) {      
41 41
      var tr = Event.findElement(e, 'tr');
42 42
      if (tr!=null && tr!=document && tr.hasClassName('hascontextmenu')) {
......
50 50
            tr.removeClassName('context-menu-selection');
51 51
          }
52 52
        } else {
53
          if (e.ctrlKey) {
53
          if (e.ctrlKey || e.metaKey) {
54 54
            this.toggleSelection(tr);
55 55
          } else if (e.shiftKey) {
56 56
            if (this.lastSelected != null) {
public/javascripts/.svn/text-base/prototype.js.svn-base
1
/*  Prototype JavaScript framework, version 1.6.0.3
2
 *  (c) 2005-2008 Sam Stephenson
1
/*  Prototype JavaScript framework, version 1.7
2
 *  (c) 2005-2010 Sam Stephenson
3 3
 *
4 4
 *  Prototype is freely distributable under the terms of an MIT-style license.
5 5
 *  For details, see the Prototype web site: http://www.prototypejs.org/
......
7 7
 *--------------------------------------------------------------------------*/
8 8

  
9 9
var Prototype = {
10
  Version: '1.6.0.3',
11

  
12
  Browser: {
13
    IE:     !!(window.attachEvent &&
14
      navigator.userAgent.indexOf('Opera') === -1),
15
    Opera:  navigator.userAgent.indexOf('Opera') > -1,
16
    WebKit: navigator.userAgent.indexOf('AppleWebKit/') > -1,
17
    Gecko:  navigator.userAgent.indexOf('Gecko') > -1 &&
18
      navigator.userAgent.indexOf('KHTML') === -1,
19
    MobileSafari: !!navigator.userAgent.match(/Apple.*Mobile.*Safari/)
20
  },
10

  
11
  Version: '1.7',
12

  
13
  Browser: (function(){
14
    var ua = navigator.userAgent;
15
    var isOpera = Object.prototype.toString.call(window.opera) == '[object Opera]';
16
    return {
17
      IE:             !!window.attachEvent && !isOpera,
18
      Opera:          isOpera,
19
      WebKit:         ua.indexOf('AppleWebKit/') > -1,
20
      Gecko:          ua.indexOf('Gecko') > -1 && ua.indexOf('KHTML') === -1,
21
      MobileSafari:   /Apple.*Mobile/.test(ua)
22
    }
23
  })(),
21 24

  
22 25
  BrowserFeatures: {
23 26
    XPath: !!document.evaluate,
27

  
24 28
    SelectorsAPI: !!document.querySelector,
25
    ElementExtensions: !!window.HTMLElement,
26
    SpecificElementExtensions:
27
      document.createElement('div')['__proto__'] &&
28
      document.createElement('div')['__proto__'] !==
29
        document.createElement('form')['__proto__']
29

  
30
    ElementExtensions: (function() {
31
      var constructor = window.Element || window.HTMLElement;
32
      return !!(constructor && constructor.prototype);
33
    })(),
34
    SpecificElementExtensions: (function() {
35
      if (typeof window.HTMLDivElement !== 'undefined')
36
        return true;
37

  
38
      var div = document.createElement('div'),
39
          form = document.createElement('form'),
40
          isSupported = false;
41

  
42
      if (div['__proto__'] && (div['__proto__'] !== form['__proto__'])) {
43
        isSupported = true;
44
      }
45

  
46
      div = form = null;
47

  
48
      return isSupported;
49
    })()
30 50
  },
31 51

  
32 52
  ScriptFragment: '<script[^>]*>([\\S\\s]*?)<\/script>',
33 53
  JSONFilter: /^\/\*-secure-([\s\S]*)\*\/\s*$/,
34 54

  
35 55
  emptyFunction: function() { },
56

  
36 57
  K: function(x) { return x }
37 58
};
38 59

  
......
40 61
  Prototype.BrowserFeatures.SpecificElementExtensions = false;
41 62

  
42 63

  
43
/* Based on Alex Arnell's inheritance implementation. */
44
var Class = {
45
  create: function() {
46
    var parent = null, properties = $A(arguments);
47
    if (Object.isFunction(properties[0]))
48
      parent = properties.shift();
49

  
50
    function klass() {
51
      this.initialize.apply(this, arguments);
52
    }
53

  
54
    Object.extend(klass, Class.Methods);
55
    klass.superclass = parent;
56
    klass.subclasses = [];
57

  
58
    if (parent) {
59
      var subclass = function() { };
60
      subclass.prototype = parent.prototype;
61
      klass.prototype = new subclass;
62
      parent.subclasses.push(klass);
63
    }
64

  
65
    for (var i = 0; i < properties.length; i++)
66
      klass.addMethods(properties[i]);
67

  
68
    if (!klass.prototype.initialize)
69
      klass.prototype.initialize = Prototype.emptyFunction;
70

  
71
    klass.prototype.constructor = klass;
72

  
73
    return klass;
74
  }
75
};
76

  
77
Class.Methods = {
78
  addMethods: function(source) {
79
    var ancestor   = this.superclass && this.superclass.prototype;
80
    var properties = Object.keys(source);
81

  
82
    if (!Object.keys({ toString: true }).length)
83
      properties.push("toString", "valueOf");
84

  
85
    for (var i = 0, length = properties.length; i < length; i++) {
86
      var property = properties[i], value = source[property];
87
      if (ancestor && Object.isFunction(value) &&
88
          value.argumentNames().first() == "$super") {
89
        var method = value;
90
        value = (function(m) {
91
          return function() { return ancestor[m].apply(this, arguments) };
92
        })(property).wrap(method);
93

  
94
        value.valueOf = method.valueOf.bind(method);
95
        value.toString = method.toString.bind(method);
96
      }
97
      this.prototype[property] = value;
98
    }
99

  
100
    return this;
101
  }
102
};
103

  
104 64
var Abstract = { };
105 65

  
106
Object.extend = function(destination, source) {
107
  for (var property in source)
108
    destination[property] = source[property];
109
  return destination;
110
};
111

  
112
Object.extend(Object, {
113
  inspect: function(object) {
114
    try {
115
      if (Object.isUndefined(object)) return 'undefined';
116
      if (object === null) return 'null';
117
      return object.inspect ? object.inspect() : String(object);
118
    } catch (e) {
119
      if (e instanceof RangeError) return '...';
120
      throw e;
121
    }
122
  },
123

  
124
  toJSON: function(object) {
125
    var type = typeof object;
126
    switch (type) {
127
      case 'undefined':
128
      case 'function':
129
      case 'unknown': return;
130
      case 'boolean': return object.toString();
131
    }
132

  
133
    if (object === null) return 'null';
134
    if (object.toJSON) return object.toJSON();
135
    if (Object.isElement(object)) return;
136

  
137
    var results = [];
138
    for (var property in object) {
139
      var value = Object.toJSON(object[property]);
140
      if (!Object.isUndefined(value))
141
        results.push(property.toJSON() + ': ' + value);
142
    }
143

  
144
    return '{' + results.join(', ') + '}';
145
  },
146

  
147
  toQueryString: function(object) {
148
    return $H(object).toQueryString();
149
  },
150

  
151
  toHTML: function(object) {
152
    return object && object.toHTML ? object.toHTML() : String.interpret(object);
153
  },
154

  
155
  keys: function(object) {
156
    var keys = [];
157
    for (var property in object)
158
      keys.push(property);
159
    return keys;
160
  },
161

  
162
  values: function(object) {
163
    var values = [];
164
    for (var property in object)
165
      values.push(object[property]);
166
    return values;
167
  },
168

  
169
  clone: function(object) {
170
    return Object.extend({ }, object);
171
  },
172

  
173
  isElement: function(object) {
174
    return !!(object && object.nodeType == 1);
175
  },
176

  
177
  isArray: function(object) {
178
    return object != null && typeof object == "object" &&
179
      'splice' in object && 'join' in object;
180
  },
181

  
182
  isHash: function(object) {
183
    return object instanceof Hash;
184
  },
185

  
186
  isFunction: function(object) {
187
    return typeof object == "function";
188
  },
189

  
190
  isString: function(object) {
191
    return typeof object == "string";
192
  },
193

  
194
  isNumber: function(object) {
195
    return typeof object == "number";
196
  },
197

  
198
  isUndefined: function(object) {
199
    return typeof object == "undefined";
200
  }
201
});
202

  
203
Object.extend(Function.prototype, {
204
  argumentNames: function() {
205
    var names = this.toString().match(/^[\s\(]*function[^(]*\(([^\)]*)\)/)[1]
206
      .replace(/\s+/g, '').split(',');
207
    return names.length == 1 && !names[0] ? [] : names;
208
  },
209

  
210
  bind: function() {
211
    if (arguments.length < 2 && Object.isUndefined(arguments[0])) return this;
212
    var __method = this, args = $A(arguments), object = args.shift();
213
    return function() {
214
      return __method.apply(object, args.concat($A(arguments)));
215
    }
216
  },
217

  
218
  bindAsEventListener: function() {
219
    var __method = this, args = $A(arguments), object = args.shift();
220
    return function(event) {
221
      return __method.apply(object, [event || window.event].concat(args));
222
    }
223
  },
224

  
225
  curry: function() {
226
    if (!arguments.length) return this;
227
    var __method = this, args = $A(arguments);
228
    return function() {
229
      return __method.apply(this, args.concat($A(arguments)));
230
    }
231
  },
232

  
233
  delay: function() {
234
    var __method = this, args = $A(arguments), timeout = args.shift() * 1000;
235
    return window.setTimeout(function() {
236
      return __method.apply(__method, args);
237
    }, timeout);
238
  },
239

  
240
  defer: function() {
241
    var args = [0.01].concat($A(arguments));
242
    return this.delay.apply(this, args);
243
  },
244

  
245
  wrap: function(wrapper) {
246
    var __method = this;
247
    return function() {
248
      return wrapper.apply(this, [__method.bind(this)].concat($A(arguments)));
249
    }
250
  },
251

  
252
  methodize: function() {
253
    if (this._methodized) return this._methodized;
254
    var __method = this;
255
    return this._methodized = function() {
256
      return __method.apply(null, [this].concat($A(arguments)));
257
    };
258
  }
259
});
260

  
261
Date.prototype.toJSON = function() {
262
  return '"' + this.getUTCFullYear() + '-' +
263
    (this.getUTCMonth() + 1).toPaddedString(2) + '-' +
264
    this.getUTCDate().toPaddedString(2) + 'T' +
265
    this.getUTCHours().toPaddedString(2) + ':' +
266
    this.getUTCMinutes().toPaddedString(2) + ':' +
267
    this.getUTCSeconds().toPaddedString(2) + 'Z"';
268
};
269 66

  
270 67
var Try = {
271 68
  these: function() {
......
283 80
  }
284 81
};
285 82

  
83
/* Based on Alex Arnell's inheritance implementation. */
84

  
85
var Class = (function() {
86

  
87
  var IS_DONTENUM_BUGGY = (function(){
88
    for (var p in { toString: 1 }) {
89
      if (p === 'toString') return false;
90
    }
91
    return true;
92
  })();
93

  
94
  function subclass() {};
95
  function create() {
96
    var parent = null, properties = $A(arguments);
97
    if (Object.isFunction(properties[0]))
98
      parent = properties.shift();
99

  
100
    function klass() {
101
      this.initialize.apply(this, arguments);
102
    }
103

  
104
    Object.extend(klass, Class.Methods);
105
    klass.superclass = parent;
106
    klass.subclasses = [];
107

  
108
    if (parent) {
109
      subclass.prototype = parent.prototype;
110
      klass.prototype = new subclass;
111
      parent.subclasses.push(klass);
112
    }
113

  
114
    for (var i = 0, length = properties.length; i < length; i++)
115
      klass.addMethods(properties[i]);
116

  
117
    if (!klass.prototype.initialize)
118
      klass.prototype.initialize = Prototype.emptyFunction;
119

  
120
    klass.prototype.constructor = klass;
121
    return klass;
122
  }
123

  
124
  function addMethods(source) {
125
    var ancestor   = this.superclass && this.superclass.prototype,
126
        properties = Object.keys(source);
127

  
128
    if (IS_DONTENUM_BUGGY) {
129
      if (source.toString != Object.prototype.toString)
130
        properties.push("toString");
131
      if (source.valueOf != Object.prototype.valueOf)
132
        properties.push("valueOf");
133
    }
134

  
135
    for (var i = 0, length = properties.length; i < length; i++) {
136
      var property = properties[i], value = source[property];
137
      if (ancestor && Object.isFunction(value) &&
138
          value.argumentNames()[0] == "$super") {
139
        var method = value;
140
        value = (function(m) {
141
          return function() { return ancestor[m].apply(this, arguments); };
142
        })(property).wrap(method);
143

  
144
        value.valueOf = method.valueOf.bind(method);
145
        value.toString = method.toString.bind(method);
146
      }
147
      this.prototype[property] = value;
148
    }
149

  
150
    return this;
151
  }
152

  
153
  return {
154
    create: create,
155
    Methods: {
156
      addMethods: addMethods
157
    }
158
  };
159
})();
160
(function() {
161

  
162
  var _toString = Object.prototype.toString,
163
      NULL_TYPE = 'Null',
164
      UNDEFINED_TYPE = 'Undefined',
165
      BOOLEAN_TYPE = 'Boolean',
166
      NUMBER_TYPE = 'Number',
167
      STRING_TYPE = 'String',
168
      OBJECT_TYPE = 'Object',
169
      FUNCTION_CLASS = '[object Function]',
170
      BOOLEAN_CLASS = '[object Boolean]',
171
      NUMBER_CLASS = '[object Number]',
172
      STRING_CLASS = '[object String]',
173
      ARRAY_CLASS = '[object Array]',
174
      DATE_CLASS = '[object Date]',
175
      NATIVE_JSON_STRINGIFY_SUPPORT = window.JSON &&
176
        typeof JSON.stringify === 'function' &&
177
        JSON.stringify(0) === '0' &&
178
        typeof JSON.stringify(Prototype.K) === 'undefined';
179

  
180
  function Type(o) {
181
    switch(o) {
182
      case null: return NULL_TYPE;
183
      case (void 0): return UNDEFINED_TYPE;
184
    }
185
    var type = typeof o;
186
    switch(type) {
187
      case 'boolean': return BOOLEAN_TYPE;
188
      case 'number':  return NUMBER_TYPE;
189
      case 'string':  return STRING_TYPE;
190
    }
191
    return OBJECT_TYPE;
192
  }
193

  
194
  function extend(destination, source) {
195
    for (var property in source)
196
      destination[property] = source[property];
197
    return destination;
198
  }
199

  
200
  function inspect(object) {
201
    try {
202
      if (isUndefined(object)) return 'undefined';
203
      if (object === null) return 'null';
204
      return object.inspect ? object.inspect() : String(object);
205
    } catch (e) {
206
      if (e instanceof RangeError) return '...';
207
      throw e;
208
    }
209
  }
210

  
211
  function toJSON(value) {
212
    return Str('', { '': value }, []);
213
  }
214

  
215
  function Str(key, holder, stack) {
216
    var value = holder[key],
217
        type = typeof value;
218

  
219
    if (Type(value) === OBJECT_TYPE && typeof value.toJSON === 'function') {
220
      value = value.toJSON(key);
221
    }
222

  
223
    var _class = _toString.call(value);
224

  
225
    switch (_class) {
226
      case NUMBER_CLASS:
227
      case BOOLEAN_CLASS:
228
      case STRING_CLASS:
229
        value = value.valueOf();
230
    }
231

  
232
    switch (value) {
233
      case null: return 'null';
234
      case true: return 'true';
235
      case false: return 'false';
236
    }
237

  
238
    type = typeof value;
239
    switch (type) {
240
      case 'string':
241
        return value.inspect(true);
242
      case 'number':
243
        return isFinite(value) ? String(value) : 'null';
244
      case 'object':
245

  
246
        for (var i = 0, length = stack.length; i < length; i++) {
247
          if (stack[i] === value) { throw new TypeError(); }
248
        }
249
        stack.push(value);
250

  
251
        var partial = [];
252
        if (_class === ARRAY_CLASS) {
253
          for (var i = 0, length = value.length; i < length; i++) {
254
            var str = Str(i, value, stack);
255
            partial.push(typeof str === 'undefined' ? 'null' : str);
256
          }
257
          partial = '[' + partial.join(',') + ']';
258
        } else {
259
          var keys = Object.keys(value);
260
          for (var i = 0, length = keys.length; i < length; i++) {
261
            var key = keys[i], str = Str(key, value, stack);
262
            if (typeof str !== "undefined") {
263
               partial.push(key.inspect(true)+ ':' + str);
264
             }
265
          }
266
          partial = '{' + partial.join(',') + '}';
267
        }
268
        stack.pop();
269
        return partial;
270
    }
271
  }
272

  
273
  function stringify(object) {
274
    return JSON.stringify(object);
275
  }
276

  
277
  function toQueryString(object) {
278
    return $H(object).toQueryString();
279
  }
280

  
281
  function toHTML(object) {
282
    return object && object.toHTML ? object.toHTML() : String.interpret(object);
283
  }
284

  
285
  function keys(object) {
286
    if (Type(object) !== OBJECT_TYPE) { throw new TypeError(); }
287
    var results = [];
288
    for (var property in object) {
289
      if (object.hasOwnProperty(property)) {
290
        results.push(property);
291
      }
292
    }
293
    return results;
294
  }
295

  
296
  function values(object) {
297
    var results = [];
298
    for (var property in object)
299
      results.push(object[property]);
300
    return results;
301
  }
302

  
303
  function clone(object) {
304
    return extend({ }, object);
305
  }
306

  
307
  function isElement(object) {
308
    return !!(object && object.nodeType == 1);
309
  }
310

  
311
  function isArray(object) {
312
    return _toString.call(object) === ARRAY_CLASS;
313
  }
314

  
315
  var hasNativeIsArray = (typeof Array.isArray == 'function')
316
    && Array.isArray([]) && !Array.isArray({});
317

  
318
  if (hasNativeIsArray) {
319
    isArray = Array.isArray;
320
  }
321

  
322
  function isHash(object) {
323
    return object instanceof Hash;
324
  }
325

  
326
  function isFunction(object) {
327
    return _toString.call(object) === FUNCTION_CLASS;
328
  }
329

  
330
  function isString(object) {
331
    return _toString.call(object) === STRING_CLASS;
332
  }
333

  
334
  function isNumber(object) {
335
    return _toString.call(object) === NUMBER_CLASS;
336
  }
337

  
338
  function isDate(object) {
339
    return _toString.call(object) === DATE_CLASS;
340
  }
341

  
342
  function isUndefined(object) {
343
    return typeof object === "undefined";
344
  }
345

  
346
  extend(Object, {
347
    extend:        extend,
348
    inspect:       inspect,
349
    toJSON:        NATIVE_JSON_STRINGIFY_SUPPORT ? stringify : toJSON,
350
    toQueryString: toQueryString,
351
    toHTML:        toHTML,
352
    keys:          Object.keys || keys,
353
    values:        values,
354
    clone:         clone,
355
    isElement:     isElement,
356
    isArray:       isArray,
357
    isHash:        isHash,
358
    isFunction:    isFunction,
359
    isString:      isString,
360
    isNumber:      isNumber,
361
    isDate:        isDate,
362
    isUndefined:   isUndefined
363
  });
364
})();
365
Object.extend(Function.prototype, (function() {
366
  var slice = Array.prototype.slice;
367

  
368
  function update(array, args) {
369
    var arrayLength = array.length, length = args.length;
370
    while (length--) array[arrayLength + length] = args[length];
371
    return array;
372
  }
373

  
374
  function merge(array, args) {
375
    array = slice.call(array, 0);
376
    return update(array, args);
377
  }
378

  
379
  function argumentNames() {
380
    var names = this.toString().match(/^[\s\(]*function[^(]*\(([^)]*)\)/)[1]
381
      .replace(/\/\/.*?[\r\n]|\/\*(?:.|[\r\n])*?\*\//g, '')
382
      .replace(/\s+/g, '').split(',');
383
    return names.length == 1 && !names[0] ? [] : names;
384
  }
385

  
386
  function bind(context) {
387
    if (arguments.length < 2 && Object.isUndefined(arguments[0])) return this;
388
    var __method = this, args = slice.call(arguments, 1);
389
    return function() {
390
      var a = merge(args, arguments);
391
      return __method.apply(context, a);
392
    }
393
  }
394

  
395
  function bindAsEventListener(context) {
396
    var __method = this, args = slice.call(arguments, 1);
397
    return function(event) {
398
      var a = update([event || window.event], args);
399
      return __method.apply(context, a);
400
    }
401
  }
402

  
403
  function curry() {
404
    if (!arguments.length) return this;
405
    var __method = this, args = slice.call(arguments, 0);
406
    return function() {
407
      var a = merge(args, arguments);
408
      return __method.apply(this, a);
409
    }
410
  }
411

  
412
  function delay(timeout) {
413
    var __method = this, args = slice.call(arguments, 1);
414
    timeout = timeout * 1000;
415
    return window.setTimeout(function() {
416
      return __method.apply(__method, args);
417
    }, timeout);
418
  }
419

  
420
  function defer() {
421
    var args = update([0.01], arguments);
422
    return this.delay.apply(this, args);
423
  }
424

  
425
  function wrap(wrapper) {
426
    var __method = this;
427
    return function() {
428
      var a = update([__method.bind(this)], arguments);
429
      return wrapper.apply(this, a);
430
    }
431
  }
432

  
433
  function methodize() {
434
    if (this._methodized) return this._methodized;
435
    var __method = this;
436
    return this._methodized = function() {
437
      var a = update([this], arguments);
438
      return __method.apply(null, a);
439
    };
440
  }
441

  
442
  return {
443
    argumentNames:       argumentNames,
444
    bind:                bind,
445
    bindAsEventListener: bindAsEventListener,
446
    curry:               curry,
447
    delay:               delay,
448
    defer:               defer,
449
    wrap:                wrap,
450
    methodize:           methodize
451
  }
452
})());
453

  
454

  
455

  
456
(function(proto) {
457

  
458

  
459
  function toISOString() {
460
    return this.getUTCFullYear() + '-' +
461
      (this.getUTCMonth() + 1).toPaddedString(2) + '-' +
462
      this.getUTCDate().toPaddedString(2) + 'T' +
463
      this.getUTCHours().toPaddedString(2) + ':' +
464
      this.getUTCMinutes().toPaddedString(2) + ':' +
465
      this.getUTCSeconds().toPaddedString(2) + 'Z';
466
  }
467

  
468

  
469
  function toJSON() {
470
    return this.toISOString();
471
  }
472

  
473
  if (!proto.toISOString) proto.toISOString = toISOString;
474
  if (!proto.toJSON) proto.toJSON = toJSON;
475

  
476
})(Date.prototype);
477

  
478

  
286 479
RegExp.prototype.match = RegExp.prototype.test;
287 480

  
288 481
RegExp.escape = function(str) {
289 482
  return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1');
290 483
};
291

  
292
/*--------------------------------------------------------------------------*/
293

  
294 484
var PeriodicalExecuter = Class.create({
295 485
  initialize: function(callback, frequency) {
296 486
    this.callback = callback;
......
319 509
      try {
320 510
        this.currentlyExecuting = true;
321 511
        this.execute();
322
      } finally {
323 512
        this.currentlyExecuting = false;
513
      } catch(e) {
514
        this.currentlyExecuting = false;
515
        throw e;
324 516
      }
325 517
    }
326 518
  }
......
339 531
  }
340 532
});
341 533

  
342
Object.extend(String.prototype, {
343
  gsub: function(pattern, replacement) {
534
Object.extend(String.prototype, (function() {
535
  var NATIVE_JSON_PARSE_SUPPORT = window.JSON &&
536
    typeof JSON.parse === 'function' &&
537
    JSON.parse('{"test": true}').test;
538

  
539
  function prepareReplacement(replacement) {
540
    if (Object.isFunction(replacement)) return replacement;
541
    var template = new Template(replacement);
542
    return function(match) { return template.evaluate(match) };
543
  }
544

  
545
  function gsub(pattern, replacement) {
344 546
    var result = '', source = this, match;
345
    replacement = arguments.callee.prepareReplacement(replacement);
547
    replacement = prepareReplacement(replacement);
548

  
549
    if (Object.isString(pattern))
550
      pattern = RegExp.escape(pattern);
551

  
552
    if (!(pattern.length || pattern.source)) {
553
      replacement = replacement('');
554
      return replacement + source.split('').join(replacement) + replacement;
555
    }
346 556

  
347 557
    while (source.length > 0) {
348 558
      if (match = source.match(pattern)) {
......
354 564
      }
355 565
    }
356 566
    return result;
357
  },
358

  
359
  sub: function(pattern, replacement, count) {
360
    replacement = this.gsub.prepareReplacement(replacement);
567
  }
568

  
569
  function sub(pattern, replacement, count) {
570
    replacement = prepareReplacement(replacement);
361 571
    count = Object.isUndefined(count) ? 1 : count;
362 572

  
363 573
    return this.gsub(pattern, function(match) {
364 574
      if (--count < 0) return match[0];
365 575
      return replacement(match);
366 576
    });
367
  },
368

  
369
  scan: function(pattern, iterator) {
577
  }
578

  
579
  function scan(pattern, iterator) {
370 580
    this.gsub(pattern, iterator);
371 581
    return String(this);
372
  },
373

  
374
  truncate: function(length, truncation) {
582
  }
583

  
584
  function truncate(length, truncation) {
375 585
    length = length || 30;
376 586
    truncation = Object.isUndefined(truncation) ? '...' : truncation;
377 587
    return this.length > length ?
378 588
      this.slice(0, length - truncation.length) + truncation : String(this);
379
  },
380

  
381
  strip: function() {
589
  }
590

  
591
  function strip() {
382 592
    return this.replace(/^\s+/, '').replace(/\s+$/, '');
383
  },
384

  
385
  stripTags: function() {
386
    return this.replace(/<\/?[^>]+>/gi, '');
387
  },
388

  
389
  stripScripts: function() {
593
  }
594

  
595
  function stripTags() {
596
    return this.replace(/<\w+(\s+("[^"]*"|'[^']*'|[^>])+)?>|<\/\w+>/gi, '');
597
  }
598

  
599
  function stripScripts() {
390 600
    return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), '');
391
  },
392

  
393
  extractScripts: function() {
394
    var matchAll = new RegExp(Prototype.ScriptFragment, 'img');
395
    var matchOne = new RegExp(Prototype.ScriptFragment, 'im');
601
  }
602

  
603
  function extractScripts() {
604
    var matchAll = new RegExp(Prototype.ScriptFragment, 'img'),
605
        matchOne = new RegExp(Prototype.ScriptFragment, 'im');
396 606
    return (this.match(matchAll) || []).map(function(scriptTag) {
397 607
      return (scriptTag.match(matchOne) || ['', ''])[1];
398 608
    });
399
  },
400

  
401
  evalScripts: function() {
609
  }
610

  
611
  function evalScripts() {
402 612
    return this.extractScripts().map(function(script) { return eval(script) });
403
  },
404

  
405
  escapeHTML: function() {
406
    var self = arguments.callee;
407
    self.text.data = this;
408
    return self.div.innerHTML;
409
  },
410

  
411
  unescapeHTML: function() {
412
    var div = new Element('div');
413
    div.innerHTML = this.stripTags();
414
    return div.childNodes[0] ? (div.childNodes.length > 1 ?
415
      $A(div.childNodes).inject('', function(memo, node) { return memo+node.nodeValue }) :
416
      div.childNodes[0].nodeValue) : '';
417
  },
418

  
419
  toQueryParams: function(separator) {
613
  }
614

  
615
  function escapeHTML() {
616
    return this.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
617
  }
618

  
619
  function unescapeHTML() {
620
    return this.stripTags().replace(/&lt;/g,'<').replace(/&gt;/g,'>').replace(/&amp;/g,'&');
621
  }
622

  
623

  
624
  function toQueryParams(separator) {
420 625
    var match = this.strip().match(/([^?#]*)(#.*)?$/);
421 626
    if (!match) return { };
422 627

  
423 628
    return match[1].split(separator || '&').inject({ }, function(hash, pair) {
424 629
      if ((pair = pair.split('='))[0]) {
425
        var key = decodeURIComponent(pair.shift());
426
        var value = pair.length > 1 ? pair.join('=') : pair[0];
630
        var key = decodeURIComponent(pair.shift()),
631
            value = pair.length > 1 ? pair.join('=') : pair[0];
632

  
427 633
        if (value != undefined) value = decodeURIComponent(value);
428 634

  
429 635
        if (key in hash) {
......
434 640
      }
435 641
      return hash;
436 642
    });
437
  },
438

  
439
  toArray: function() {
643
  }
644

  
645
  function toArray() {
440 646
    return this.split('');
441
  },
442

  
443
  succ: function() {
647
  }
648

  
649
  function succ() {
444 650
    return this.slice(0, this.length - 1) +
445 651
      String.fromCharCode(this.charCodeAt(this.length - 1) + 1);
446
  },
447

  
448
  times: function(count) {
652
  }
653

  
654
  function times(count) {
449 655
    return count < 1 ? '' : new Array(count + 1).join(this);
450
  },
451

  
452
  camelize: function() {
453
    var parts = this.split('-'), len = parts.length;
454
    if (len == 1) return parts[0];
455

  
456
    var camelized = this.charAt(0) == '-'
457
      ? parts[0].charAt(0).toUpperCase() + parts[0].substring(1)
458
      : parts[0];
459

  
460
    for (var i = 1; i < len; i++)
461
      camelized += parts[i].charAt(0).toUpperCase() + parts[i].substring(1);
462

  
463
    return camelized;
464
  },
465

  
466
  capitalize: function() {
656
  }
657

  
658
  function camelize() {
659
    return this.replace(/-+(.)?/g, function(match, chr) {
660
      return chr ? chr.toUpperCase() : '';
661
    });
662
  }
663

  
664
  function capitalize() {
467 665
    return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();
468
  },
469

  
470
  underscore: function() {
471
    return this.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/,'#{1}_#{2}').gsub(/([a-z\d])([A-Z])/,'#{1}_#{2}').gsub(/-/,'_').toLowerCase();
472
  },
473

  
474
  dasherize: function() {
475
    return this.gsub(/_/,'-');
476
  },
477

  
478
  inspect: function(useDoubleQuotes) {
479
    var escapedString = this.gsub(/[\x00-\x1f\\]/, function(match) {
480
      var character = String.specialChar[match[0]];
481
      return character ? character : '\\u00' + match[0].charCodeAt().toPaddedString(2, 16);
666
  }
667

  
668
  function underscore() {
669
    return this.replace(/::/g, '/')
670
               .replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2')
671
               .replace(/([a-z\d])([A-Z])/g, '$1_$2')
672
               .replace(/-/g, '_')
673
               .toLowerCase();
674
  }
675

  
676
  function dasherize() {
677
    return this.replace(/_/g, '-');
678
  }
679

  
680
  function inspect(useDoubleQuotes) {
681
    var escapedString = this.replace(/[\x00-\x1f\\]/g, function(character) {
682
      if (character in String.specialChar) {
683
        return String.specialChar[character];
684
      }
685
      return '\\u00' + character.charCodeAt().toPaddedString(2, 16);
482 686
    });
483 687
    if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"';
484 688
    return "'" + escapedString.replace(/'/g, '\\\'') + "'";
485
  },
486

  
487
  toJSON: function() {
488
    return this.inspect(true);
489
  },
490

  
491
  unfilterJSON: function(filter) {
492
    return this.sub(filter || Prototype.JSONFilter, '#{1}');
493
  },
494

  
495
  isJSON: function() {
689
  }
690

  
691
  function unfilterJSON(filter) {
692
    return this.replace(filter || Prototype.JSONFilter, '$1');
693
  }
694

  
695
  function isJSON() {
496 696
    var str = this;
497 697
    if (str.blank()) return false;
498
    str = this.replace(/\\./g, '@').replace(/"[^"\\\n\r]*"/g, '');
499
    return (/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(str);
500
  },
501

  
502
  evalJSON: function(sanitize) {
503
    var json = this.unfilterJSON();
698
    str = str.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@');
699
    str = str.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']');
700
    str = str.replace(/(?:^|:|,)(?:\s*\[)+/g, '');
701
    return (/^[\],:{}\s]*$/).test(str);
702
  }
703

  
704
  function evalJSON(sanitize) {
705
    var json = this.unfilterJSON(),
706
        cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
707
    if (cx.test(json)) {
708
      json = json.replace(cx, function (a) {
709
        return '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
710
      });
711
    }
504 712
    try {
505 713
      if (!sanitize || json.isJSON()) return eval('(' + json + ')');
506 714
    } catch (e) { }
507 715
    throw new SyntaxError('Badly formed JSON string: ' + this.inspect());
508
  },
509

  
510
  include: function(pattern) {
716
  }
717

  
718
  function parseJSON() {
719
    var json = this.unfilterJSON();
720
    return JSON.parse(json);
721
  }
722

  
723
  function include(pattern) {
511 724
    return this.indexOf(pattern) > -1;
512
  },
513

  
514
  startsWith: function(pattern) {
515
    return this.indexOf(pattern) === 0;
516
  },
517

  
518
  endsWith: function(pattern) {
725
  }
726

  
727
  function startsWith(pattern) {
728
    return this.lastIndexOf(pattern, 0) === 0;
729
  }
730

  
731
  function endsWith(pattern) {
519 732
    var d = this.length - pattern.length;
520
    return d >= 0 && this.lastIndexOf(pattern) === d;
521
  },
522

  
523
  empty: function() {
733
    return d >= 0 && this.indexOf(pattern, d) === d;
734
  }
735

  
736
  function empty() {
524 737
    return this == '';
525
  },
526

  
527
  blank: function() {
738
  }
739

  
740
  function blank() {
528 741
    return /^\s*$/.test(this);
529
  },
530

  
531
  interpolate: function(object, pattern) {
742
  }
743

  
744
  function interpolate(object, pattern) {
532 745
    return new Template(this, pattern).evaluate(object);
533 746
  }
534
});
535

  
536
if (Prototype.Browser.WebKit || Prototype.Browser.IE) Object.extend(String.prototype, {
537
  escapeHTML: function() {
538
    return this.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
539
  },
540
  unescapeHTML: function() {
541
    return this.stripTags().replace(/&amp;/g,'&').replace(/&lt;/g,'<').replace(/&gt;/g,'>');
542
  }
543
});
544

  
545
String.prototype.gsub.prepareReplacement = function(replacement) {
546
  if (Object.isFunction(replacement)) return replacement;
547
  var template = new Template(replacement);
548
  return function(match) { return template.evaluate(match) };
549
};
550

  
551
String.prototype.parseQuery = String.prototype.toQueryParams;
552

  
553
Object.extend(String.prototype.escapeHTML, {
554
  div:  document.createElement('div'),
555
  text: document.createTextNode('')
556
});
557

  
558
String.prototype.escapeHTML.div.appendChild(String.prototype.escapeHTML.text);
747

  
748
  return {
749
    gsub:           gsub,
750
    sub:            sub,
751
    scan:           scan,
752
    truncate:       truncate,
753
    strip:          String.prototype.trim || strip,
754
    stripTags:      stripTags,
755
    stripScripts:   stripScripts,
756
    extractScripts: extractScripts,
757
    evalScripts:    evalScripts,
758
    escapeHTML:     escapeHTML,
759
    unescapeHTML:   unescapeHTML,
760
    toQueryParams:  toQueryParams,
761
    parseQuery:     toQueryParams,
762
    toArray:        toArray,
763
    succ:           succ,
764
    times:          times,
765
    camelize:       camelize,
766
    capitalize:     capitalize,
767
    underscore:     underscore,
768
    dasherize:      dasherize,
769
    inspect:        inspect,
770
    unfilterJSON:   unfilterJSON,
771
    isJSON:         isJSON,
772
    evalJSON:       NATIVE_JSON_PARSE_SUPPORT ? parseJSON : evalJSON,
773
    include:        include,
774
    startsWith:     startsWith,
775
    endsWith:       endsWith,
776
    empty:          empty,
777
    blank:          blank,
778
    interpolate:    interpolate
779
  };
780
})());
559 781

  
560 782
var Template = Class.create({
561 783
  initialize: function(template, pattern) {
......
564 786
  },
565 787

  
566 788
  evaluate: function(object) {
567
    if (Object.isFunction(object.toTemplateReplacements))
789
    if (object && Object.isFunction(object.toTemplateReplacements))
568 790
      object = object.toTemplateReplacements();
569 791

  
570 792
    return this.template.gsub(this.pattern, function(match) {
571
      if (object == null) return '';
793
      if (object == null) return (match[1] + '');
572 794

  
573 795
      var before = match[1] || '';
574 796
      if (before == '\\') return match[2];
575 797

  
576
      var ctx = object, expr = match[3];
577
      var pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/;
798
      var ctx = object, expr = match[3],
799
          pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/;
800

  
578 801
      match = pattern.exec(expr);
579 802
      if (match == null) return before;
580 803

  
581 804
      while (match != null) {
582
        var comp = match[1].startsWith('[') ? match[2].gsub('\\\\]', ']') : match[1];
805
        var comp = match[1].startsWith('[') ? match[2].replace(/\\\\]/g, ']') : match[1];
583 806
        ctx = ctx[comp];
584 807
        if (null == ctx || '' == match[3]) break;
585 808
        expr = expr.substring('[' == match[3] ? match[1].length : match[0].length);
......
594 817

  
595 818
var $break = { };
596 819

  
597
var Enumerable = {
598
  each: function(iterator, context) {
820
var Enumerable = (function() {
821
  function each(iterator, context) {
599 822
    var index = 0;
600 823
    try {
601 824
      this._each(function(value) {
......
605 828
      if (e != $break) throw e;
606 829
    }
607 830
    return this;
608
  },
609

  
610
  eachSlice: function(number, iterator, context) {
831
  }
832

  
833
  function eachSlice(number, iterator, context) {
611 834
    var index = -number, slices = [], array = this.toArray();
612 835
    if (number < 1) return array;
613 836
    while ((index += number) < array.length)
614 837
      slices.push(array.slice(index, index+number));
615 838
    return slices.collect(iterator, context);
616
  },
617

  
618
  all: function(iterator, context) {
839
  }
840

  
841
  function all(iterator, context) {
619 842
    iterator = iterator || Prototype.K;
620 843
    var result = true;
621 844
    this.each(function(value, index) {
......
623 846
      if (!result) throw $break;
624 847
    });
625 848
    return result;
626
  },
627

  
628
  any: function(iterator, context) {
849
  }
850

  
851
  function any(iterator, context) {
629 852
    iterator = iterator || Prototype.K;
630 853
    var result = false;
631 854
    this.each(function(value, index) {
......
633 856
        throw $break;
634 857
    });
635 858
    return result;
636
  },
637

  
638
  collect: function(iterator, context) {
859
  }
860

  
861
  function collect(iterator, context) {
639 862
    iterator = iterator || Prototype.K;
640 863
    var results = [];
641 864
    this.each(function(value, index) {
642 865
      results.push(iterator.call(context, value, index));
643 866
    });
644 867
    return results;
645
  },
646

  
647
  detect: function(iterator, context) {
868
  }
869

  
870
  function detect(iterator, context) {
648 871
    var result;
649 872
    this.each(function(value, index) {
650 873
      if (iterator.call(context, value, index)) {
......
653 876
      }
654 877
    });
655 878
    return result;
656
  },
657

  
658
  findAll: function(iterator, context) {
879
  }
880

  
881
  function findAll(iterator, context) {
659 882
    var results = [];
660 883
    this.each(function(value, index) {
661 884
      if (iterator.call(context, value, index))
662 885
        results.push(value);
663 886
    });
664 887
    return results;
665
  },
666

  
667
  grep: function(filter, iterator, context) {
888
  }
889

  
890
  function grep(filter, iterator, context) {
668 891
    iterator = iterator || Prototype.K;
669 892
    var results = [];
670 893

  
671 894
    if (Object.isString(filter))
672
      filter = new RegExp(filter);
895
      filter = new RegExp(RegExp.escape(filter));
673 896

  
674 897
    this.each(function(value, index) {
675 898
      if (filter.match(value))
676 899
        results.push(iterator.call(context, value, index));
677 900
    });
678 901
    return results;
679
  },
680

  
681
  include: function(object) {
902
  }
903

  
904
  function include(object) {
682 905
    if (Object.isFunction(this.indexOf))
683 906
      if (this.indexOf(object) != -1) return true;
684 907

  
......
690 913
      }
691 914
    });
692 915
    return found;
693
  },
694

  
695
  inGroupsOf: function(number, fillWith) {
916
  }
917

  
918
  function inGroupsOf(number, fillWith) {
696 919
    fillWith = Object.isUndefined(fillWith) ? null : fillWith;
697 920
    return this.eachSlice(number, function(slice) {
698 921
      while(slice.length < number) slice.push(fillWith);
699 922
      return slice;
700 923
    });
701
  },
702

  
703
  inject: function(memo, iterator, context) {
924
  }
925

  
926
  function inject(memo, iterator, context) {
704 927
    this.each(function(value, index) {
705 928
      memo = iterator.call(context, memo, value, index);
706 929
    });
707 930
    return memo;
708
  },
709

  
710
  invoke: function(method) {
931
  }
932

  
933
  function invoke(method) {
711 934
    var args = $A(arguments).slice(1);
712 935
    return this.map(function(value) {
713 936
      return value[method].apply(value, args);
714 937
    });
715
  },
716

  
717
  max: function(iterator, context) {
938
  }
939

  
940
  function max(iterator, context) {
718 941
    iterator = iterator || Prototype.K;
719 942
    var result;
720 943
    this.each(function(value, index) {
......
723 946
        result = value;
724 947
    });
725 948
    return result;
726
  },
727

  
728
  min: function(iterator, context) {
949
  }
950

  
951
  function min(iterator, context) {
729 952
    iterator = iterator || Prototype.K;
730 953
    var result;
731 954
    this.each(function(value, index) {
......
734 957
        result = value;
735 958
    });
736 959
    return result;
737
  },
738

  
739
  partition: function(iterator, context) {
960
  }
961

  
962
  function partition(iterator, context) {
740 963
    iterator = iterator || Prototype.K;
741 964
    var trues = [], falses = [];
742 965
    this.each(function(value, index) {
......
744 967
        trues : falses).push(value);
745 968
    });
746 969
    return [trues, falses];
747
  },
748

  
749
  pluck: function(property) {
970
  }
971

  
972
  function pluck(property) {
750 973
    var results = [];
751 974
    this.each(function(value) {
752 975
      results.push(value[property]);
753 976
    });
754 977
    return results;
755
  },
756

  
757
  reject: function(iterator, context) {
978
  }
979

  
980
  function reject(iterator, context) {
758 981
    var results = [];
759 982
    this.each(function(value, index) {
760 983
      if (!iterator.call(context, value, index))
761 984
        results.push(value);
762 985
    });
763 986
    return results;
764
  },
765

  
766
  sortBy: function(iterator, context) {
987
  }
988

  
989
  function sortBy(iterator, context) {
767 990
    return this.map(function(value, index) {
768 991
      return {
769 992
        value: value,
......
773 996
      var a = left.criteria, b = right.criteria;
774 997
      return a < b ? -1 : a > b ? 1 : 0;
775 998
    }).pluck('value');
776
  },
777

  
778
  toArray: function() {
999
  }
1000

  
1001
  function toArray() {
779 1002
    return this.map();
780
  },
781

  
782
  zip: function() {
1003
  }
1004

  
1005
  function zip() {
783 1006
    var iterator = Prototype.K, args = $A(arguments);
784 1007
    if (Object.isFunction(args.last()))
785 1008
      iterator = args.pop();
......
788 1011
    return this.map(function(value, index) {
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff