bhf 1.0.0.beta8 → 1.0.0.beta13

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.
@@ -168,7 +168,7 @@ class Bhf::EntriesController < Bhf::ApplicationController
168
168
  def manage_many_to_many
169
169
  return unless params[:has_and_belongs_to_many]
170
170
  params[:has_and_belongs_to_many].each_pair do |relation, ids|
171
- next unless ids.empty?
171
+ next if ids.nil? || ids.empty?
172
172
  reflection = @model.reflections[relation]
173
173
  relation_array = @object.send(relation)
174
174
  reflection.klass.unscoped.find(ids.keys).each do |relation_obj|
@@ -208,7 +208,7 @@ class Bhf::EntriesController < Bhf::ApplicationController
208
208
  return unless params[:has_many]
209
209
  object_id = @object.send(@model.bhf_primary_key)
210
210
  params[:has_many].each_pair do |relation, ids|
211
- next unless ids.empty?
211
+ next if ids.nil? || ids.empty?
212
212
  reflection = @model.reflections[relation]
213
213
  preset_ids = @object.send(relation).collect do |object|
214
214
  object.send(object.class.bhf_primary_key).to_s
@@ -1,11 +1,7 @@
1
1
  = node f, field do
2
2
  - file = f.object.send(field.name)
3
- - if file.present? && file.attachment.present?
4
- - file_blob_url = main_app.route_for(:rails_service_blob, file.blob.signed_id, file.blob.filename)
5
- - if file.blob.image?
6
- = link_to image_tag(main_app.route_for(:rails_representation, file.variant(resize: "200>")), class: 'uploaded_image'), file_blob_url
7
- - else
8
- = link_to file.blob.filename.to_s, file_blob_url, class: 'uploaded_file'
3
+ - if file.present?
4
+ = render partial: 'bhf/form/column/attachment_presenter', locals: {attachment: file.attachment}
9
5
 
10
6
  - if f.object.respond_to?(:"#{field.name}_destroy")
11
7
  .file_delete
@@ -0,0 +1,10 @@
1
+ = node f, field do
2
+ - f.object.send(field.name).attachments.each do |attachment|
3
+ - if attachment.present?
4
+ = render partial: 'bhf/form/column/attachment_presenter', locals: {attachment: attachment}
5
+ - if f.object.respond_to?(:"#{field.name}_destroy")
6
+ .file_delete
7
+ = f.check_box "#{field.name}_destroy"
8
+ = f.label "#{field.name}_destroy", t('bhf.helpers.file.delete')
9
+
10
+ =# f.file_field field.name, direct_upload: true, data: {:'direct-upload-url' => main_app.rails_direct_uploads_url}
@@ -0,0 +1,6 @@
1
+ - if attachment.present?
2
+ - file_blob_url = main_app.route_for(:rails_service_blob, attachment.blob.signed_id, attachment.blob.filename)
3
+ - if attachment.blob.image?
4
+ = link_to image_tag(main_app.route_for(:rails_representation, attachment.variant(resize: "200>")), class: 'uploaded_image'), file_blob_url
5
+ - else
6
+ = link_to attachment.blob.filename.to_s, file_blob_url, class: 'uploaded_file'
@@ -1,2 +1,2 @@
1
1
  = node f, field do
2
- = f.rich_text_area field.name, class: 'default_input'
2
+ = f.rich_text_area field.name, class: 'trix_input trix-content'
@@ -2,16 +2,16 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: bhf 1.0.0.beta8 ruby lib
5
+ # stub: bhf 1.0.0.beta13 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "bhf".freeze
9
- s.version = "1.0.0.beta8"
9
+ s.version = "1.0.0.beta13"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new("> 1.3.1".freeze) if s.respond_to? :required_rubygems_version=
12
12
  s.require_paths = ["lib".freeze]
13
13
  s.authors = ["Anton Pawlik".freeze]
14
- s.date = "2019-12-27"
14
+ s.date = "2020-07-16"
15
15
  s.description = "A simple to use Rails-Engine-Gem that offers an admin interface for trusted user. Easy integratable and highly configurable and agnostic. Works with ActiveRecord and Mongoid.".freeze
16
16
  s.email = "anton.pawlik@gmail.com".freeze
17
17
  s.extra_rdoc_files = [
@@ -35,6 +35,7 @@ Gem::Specification.new do |s|
35
35
  "app/assets/images/bhf/small_ajax_loader.gif",
36
36
  "app/assets/images/bhf/small_ajax_loader_h.gif",
37
37
  "app/assets/images/bhf/wmd-buttons.png",
38
+ "app/assets/javascripts/bhf/MooTools-More-1.6.0.js",
38
39
  "app/assets/javascripts/bhf/application.js",
39
40
  "app/assets/javascripts/bhf/classes/Ajaxify.js",
40
41
  "app/assets/javascripts/bhf/classes/ArrayFields.js",
@@ -54,14 +55,13 @@ Gem::Specification.new do |s|
54
55
  "app/assets/javascripts/bhf/locales/Locale.de-DE.js",
55
56
  "app/assets/javascripts/bhf/locales/Locale.en-US.js",
56
57
  "app/assets/javascripts/bhf/locales/Locale.pt-PT.js",
57
- "app/assets/javascripts/bhf/mootools-core-1.5.0-full-compat.js",
58
- "app/assets/javascripts/bhf/mootools-more-1.5.0.js",
59
58
  "app/assets/javascripts/bhf/mootools_ujs.js",
60
59
  "app/assets/javascripts/bhf/trix.js",
61
60
  "app/assets/stylesheets/bhf/MooEditable.scss",
62
61
  "app/assets/stylesheets/bhf/application.sass",
63
62
  "app/assets/stylesheets/bhf/functions.sass",
64
63
  "app/assets/stylesheets/bhf/reset.sass",
64
+ "app/assets/stylesheets/bhf/trix.scss",
65
65
  "app/assets/stylesheets/bhf/typo.scss",
66
66
  "app/controllers/bhf/application_controller.rb",
67
67
  "app/controllers/bhf/embed_entries_controller.rb",
@@ -83,7 +83,9 @@ Gem::Specification.new do |s|
83
83
  "app/views/bhf/form/belongs_to/_select.html.haml",
84
84
  "app/views/bhf/form/belongs_to/_static.html.haml",
85
85
  "app/views/bhf/form/column/_activestorage_attachment.html.haml",
86
+ "app/views/bhf/form/column/_activestorage_attachments.html.haml",
86
87
  "app/views/bhf/form/column/_array.html.haml",
88
+ "app/views/bhf/form/column/_attachment_presenter.html.haml",
87
89
  "app/views/bhf/form/column/_boolean.html.haml",
88
90
  "app/views/bhf/form/column/_date.html.haml",
89
91
  "app/views/bhf/form/column/_hash.html.haml",
@@ -172,7 +174,7 @@ Gem::Specification.new do |s|
172
174
  ]
173
175
  s.homepage = "http://antpaw.github.io/bhf".freeze
174
176
  s.licenses = ["MIT".freeze]
175
- s.rubygems_version = "3.0.6".freeze
177
+ s.rubygems_version = "3.0.8".freeze
176
178
  s.summary = "A simple to use Rails-Engine-Gem that offers an admin interface for trusted user.".freeze
177
179
 
178
180
  if s.respond_to? :specification_version then
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bhf
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.beta8
4
+ version: 1.0.0.beta13
5
5
  platform: ruby
6
6
  authors:
7
7
  - Anton Pawlik
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-12-27 00:00:00.000000000 Z
11
+ date: 2020-07-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -176,6 +176,7 @@ files:
176
176
  - app/assets/images/bhf/small_ajax_loader.gif
177
177
  - app/assets/images/bhf/small_ajax_loader_h.gif
178
178
  - app/assets/images/bhf/wmd-buttons.png
179
+ - app/assets/javascripts/bhf/MooTools-More-1.6.0.js
179
180
  - app/assets/javascripts/bhf/application.js
180
181
  - app/assets/javascripts/bhf/classes/Ajaxify.js
181
182
  - app/assets/javascripts/bhf/classes/ArrayFields.js
@@ -195,14 +196,13 @@ files:
195
196
  - app/assets/javascripts/bhf/locales/Locale.de-DE.js
196
197
  - app/assets/javascripts/bhf/locales/Locale.en-US.js
197
198
  - app/assets/javascripts/bhf/locales/Locale.pt-PT.js
198
- - app/assets/javascripts/bhf/mootools-core-1.5.0-full-compat.js
199
- - app/assets/javascripts/bhf/mootools-more-1.5.0.js
200
199
  - app/assets/javascripts/bhf/mootools_ujs.js
201
200
  - app/assets/javascripts/bhf/trix.js
202
201
  - app/assets/stylesheets/bhf/MooEditable.scss
203
202
  - app/assets/stylesheets/bhf/application.sass
204
203
  - app/assets/stylesheets/bhf/functions.sass
205
204
  - app/assets/stylesheets/bhf/reset.sass
205
+ - app/assets/stylesheets/bhf/trix.scss
206
206
  - app/assets/stylesheets/bhf/typo.scss
207
207
  - app/controllers/bhf/application_controller.rb
208
208
  - app/controllers/bhf/embed_entries_controller.rb
@@ -224,7 +224,9 @@ files:
224
224
  - app/views/bhf/form/belongs_to/_select.html.haml
225
225
  - app/views/bhf/form/belongs_to/_static.html.haml
226
226
  - app/views/bhf/form/column/_activestorage_attachment.html.haml
227
+ - app/views/bhf/form/column/_activestorage_attachments.html.haml
227
228
  - app/views/bhf/form/column/_array.html.haml
229
+ - app/views/bhf/form/column/_attachment_presenter.html.haml
228
230
  - app/views/bhf/form/column/_boolean.html.haml
229
231
  - app/views/bhf/form/column/_date.html.haml
230
232
  - app/views/bhf/form/column/_hash.html.haml
@@ -329,7 +331,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
329
331
  - !ruby/object:Gem::Version
330
332
  version: 1.3.1
331
333
  requirements: []
332
- rubygems_version: 3.0.6
334
+ rubygems_version: 3.0.8
333
335
  signing_key:
334
336
  specification_version: 4
335
337
  summary: A simple to use Rails-Engine-Gem that offers an admin interface for trusted
@@ -1,2561 +0,0 @@
1
- /*
2
- ---
3
- MooTools: the javascript framework
4
-
5
- web build:
6
- - http://mootools.net/more/335fff3ee615958016e5569b21c1d4cf
7
-
8
- packager build:
9
- - packager build More/Date More/String.Extras More/Sortables More/Assets More/IframeShim More/Locale More/Locale.en-US.Date More/Locale.de-DE.Date
10
-
11
- ...
12
- */
13
-
14
- /*
15
- ---
16
-
17
- script: More.js
18
-
19
- name: More
20
-
21
- description: MooTools More
22
-
23
- license: MIT-style license
24
-
25
- authors:
26
- - Guillermo Rauch
27
- - Thomas Aylott
28
- - Scott Kyle
29
- - Arian Stolwijk
30
- - Tim Wienk
31
- - Christoph Pojer
32
- - Aaron Newton
33
- - Jacob Thornton
34
-
35
- requires:
36
- - Core/MooTools
37
-
38
- provides: [MooTools.More]
39
-
40
- ...
41
- */
42
-
43
- MooTools.More = {
44
- version: '1.5.0',
45
- build: '73db5e24e6e9c5c87b3a27aebef2248053f7db37'
46
- };
47
-
48
-
49
- /*
50
- ---
51
-
52
- script: Object.Extras.js
53
-
54
- name: Object.Extras
55
-
56
- description: Extra Object generics, like getFromPath which allows a path notation to child elements.
57
-
58
- license: MIT-style license
59
-
60
- authors:
61
- - Aaron Newton
62
-
63
- requires:
64
- - Core/Object
65
- - MooTools.More
66
-
67
- provides: [Object.Extras]
68
-
69
- ...
70
- */
71
-
72
- (function(){
73
-
74
- var defined = function(value){
75
- return value != null;
76
- };
77
-
78
- var hasOwnProperty = Object.prototype.hasOwnProperty;
79
-
80
- Object.extend({
81
-
82
- getFromPath: function(source, parts){
83
- if (typeof parts == 'string') parts = parts.split('.');
84
- for (var i = 0, l = parts.length; i < l; i++){
85
- if (hasOwnProperty.call(source, parts[i])) source = source[parts[i]];
86
- else return null;
87
- }
88
- return source;
89
- },
90
-
91
- cleanValues: function(object, method){
92
- method = method || defined;
93
- for (var key in object) if (!method(object[key])){
94
- delete object[key];
95
- }
96
- return object;
97
- },
98
-
99
- erase: function(object, key){
100
- if (hasOwnProperty.call(object, key)) delete object[key];
101
- return object;
102
- },
103
-
104
- run: function(object){
105
- var args = Array.slice(arguments, 1);
106
- for (var key in object) if (object[key].apply){
107
- object[key].apply(object, args);
108
- }
109
- return object;
110
- }
111
-
112
- });
113
-
114
- })();
115
-
116
-
117
- /*
118
- ---
119
-
120
- script: Locale.js
121
-
122
- name: Locale
123
-
124
- description: Provides methods for localization.
125
-
126
- license: MIT-style license
127
-
128
- authors:
129
- - Aaron Newton
130
- - Arian Stolwijk
131
-
132
- requires:
133
- - Core/Events
134
- - Object.Extras
135
- - MooTools.More
136
-
137
- provides: [Locale, Lang]
138
-
139
- ...
140
- */
141
-
142
- (function(){
143
-
144
- var current = null,
145
- locales = {},
146
- inherits = {};
147
-
148
- var getSet = function(set){
149
- if (instanceOf(set, Locale.Set)) return set;
150
- else return locales[set];
151
- };
152
-
153
- var Locale = this.Locale = {
154
-
155
- define: function(locale, set, key, value){
156
- var name;
157
- if (instanceOf(locale, Locale.Set)){
158
- name = locale.name;
159
- if (name) locales[name] = locale;
160
- } else {
161
- name = locale;
162
- if (!locales[name]) locales[name] = new Locale.Set(name);
163
- locale = locales[name];
164
- }
165
-
166
- if (set) locale.define(set, key, value);
167
-
168
-
169
-
170
- if (!current) current = locale;
171
-
172
- return locale;
173
- },
174
-
175
- use: function(locale){
176
- locale = getSet(locale);
177
-
178
- if (locale){
179
- current = locale;
180
-
181
- this.fireEvent('change', locale);
182
-
183
-
184
- }
185
-
186
- return this;
187
- },
188
-
189
- getCurrent: function(){
190
- return current;
191
- },
192
-
193
- get: function(key, args){
194
- return (current) ? current.get(key, args) : '';
195
- },
196
-
197
- inherit: function(locale, inherits, set){
198
- locale = getSet(locale);
199
-
200
- if (locale) locale.inherit(inherits, set);
201
- return this;
202
- },
203
-
204
- list: function(){
205
- return Object.keys(locales);
206
- }
207
-
208
- };
209
-
210
- Object.append(Locale, new Events);
211
-
212
- Locale.Set = new Class({
213
-
214
- sets: {},
215
-
216
- inherits: {
217
- locales: [],
218
- sets: {}
219
- },
220
-
221
- initialize: function(name){
222
- this.name = name || '';
223
- },
224
-
225
- define: function(set, key, value){
226
- var defineData = this.sets[set];
227
- if (!defineData) defineData = {};
228
-
229
- if (key){
230
- if (typeOf(key) == 'object') defineData = Object.merge(defineData, key);
231
- else defineData[key] = value;
232
- }
233
- this.sets[set] = defineData;
234
-
235
- return this;
236
- },
237
-
238
- get: function(key, args, _base){
239
- var value = Object.getFromPath(this.sets, key);
240
- if (value != null){
241
- var type = typeOf(value);
242
- if (type == 'function') value = value.apply(null, Array.from(args));
243
- else if (type == 'object') value = Object.clone(value);
244
- return value;
245
- }
246
-
247
- // get value of inherited locales
248
- var index = key.indexOf('.'),
249
- set = index < 0 ? key : key.substr(0, index),
250
- names = (this.inherits.sets[set] || []).combine(this.inherits.locales).include('en-US');
251
- if (!_base) _base = [];
252
-
253
- for (var i = 0, l = names.length; i < l; i++){
254
- if (_base.contains(names[i])) continue;
255
- _base.include(names[i]);
256
-
257
- var locale = locales[names[i]];
258
- if (!locale) continue;
259
-
260
- value = locale.get(key, args, _base);
261
- if (value != null) return value;
262
- }
263
-
264
- return '';
265
- },
266
-
267
- inherit: function(names, set){
268
- names = Array.from(names);
269
-
270
- if (set && !this.inherits.sets[set]) this.inherits.sets[set] = [];
271
-
272
- var l = names.length;
273
- while (l--) (set ? this.inherits.sets[set] : this.inherits.locales).unshift(names[l]);
274
-
275
- return this;
276
- }
277
-
278
- });
279
-
280
-
281
-
282
- })();
283
-
284
-
285
- /*
286
- ---
287
-
288
- name: Locale.en-US.Date
289
-
290
- description: Date messages for US English.
291
-
292
- license: MIT-style license
293
-
294
- authors:
295
- - Aaron Newton
296
-
297
- requires:
298
- - Locale
299
-
300
- provides: [Locale.en-US.Date]
301
-
302
- ...
303
- */
304
-
305
- Locale.define('en-US', 'Date', {
306
-
307
- months: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
308
- months_abbr: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
309
- days: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
310
- days_abbr: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
311
-
312
- // Culture's date order: MM/DD/YYYY
313
- dateOrder: ['month', 'date', 'year'],
314
- shortDate: '%m/%d/%Y',
315
- shortTime: '%I:%M%p',
316
- AM: 'AM',
317
- PM: 'PM',
318
- firstDayOfWeek: 0,
319
-
320
- // Date.Extras
321
- ordinal: function(dayOfMonth){
322
- // 1st, 2nd, 3rd, etc.
323
- return (dayOfMonth > 3 && dayOfMonth < 21) ? 'th' : ['th', 'st', 'nd', 'rd', 'th'][Math.min(dayOfMonth % 10, 4)];
324
- },
325
-
326
- lessThanMinuteAgo: 'less than a minute ago',
327
- minuteAgo: 'about a minute ago',
328
- minutesAgo: '{delta} minutes ago',
329
- hourAgo: 'about an hour ago',
330
- hoursAgo: 'about {delta} hours ago',
331
- dayAgo: '1 day ago',
332
- daysAgo: '{delta} days ago',
333
- weekAgo: '1 week ago',
334
- weeksAgo: '{delta} weeks ago',
335
- monthAgo: '1 month ago',
336
- monthsAgo: '{delta} months ago',
337
- yearAgo: '1 year ago',
338
- yearsAgo: '{delta} years ago',
339
-
340
- lessThanMinuteUntil: 'less than a minute from now',
341
- minuteUntil: 'about a minute from now',
342
- minutesUntil: '{delta} minutes from now',
343
- hourUntil: 'about an hour from now',
344
- hoursUntil: 'about {delta} hours from now',
345
- dayUntil: '1 day from now',
346
- daysUntil: '{delta} days from now',
347
- weekUntil: '1 week from now',
348
- weeksUntil: '{delta} weeks from now',
349
- monthUntil: '1 month from now',
350
- monthsUntil: '{delta} months from now',
351
- yearUntil: '1 year from now',
352
- yearsUntil: '{delta} years from now'
353
-
354
- });
355
-
356
-
357
- /*
358
- ---
359
-
360
- script: Date.js
361
-
362
- name: Date
363
-
364
- description: Extends the Date native object to include methods useful in managing dates.
365
-
366
- license: MIT-style license
367
-
368
- authors:
369
- - Aaron Newton
370
- - Nicholas Barthelemy - https://svn.nbarthelemy.com/date-js/
371
- - Harald Kirshner - mail [at] digitarald.de; http://digitarald.de
372
- - Scott Kyle - scott [at] appden.com; http://appden.com
373
-
374
- requires:
375
- - Core/Array
376
- - Core/String
377
- - Core/Number
378
- - MooTools.More
379
- - Locale
380
- - Locale.en-US.Date
381
-
382
- provides: [Date]
383
-
384
- ...
385
- */
386
-
387
- (function(){
388
-
389
- var Date = this.Date;
390
-
391
- var DateMethods = Date.Methods = {
392
- ms: 'Milliseconds',
393
- year: 'FullYear',
394
- min: 'Minutes',
395
- mo: 'Month',
396
- sec: 'Seconds',
397
- hr: 'Hours'
398
- };
399
-
400
- ['Date', 'Day', 'FullYear', 'Hours', 'Milliseconds', 'Minutes', 'Month', 'Seconds', 'Time', 'TimezoneOffset',
401
- 'Week', 'Timezone', 'GMTOffset', 'DayOfYear', 'LastMonth', 'LastDayOfMonth', 'UTCDate', 'UTCDay', 'UTCFullYear',
402
- 'AMPM', 'Ordinal', 'UTCHours', 'UTCMilliseconds', 'UTCMinutes', 'UTCMonth', 'UTCSeconds', 'UTCMilliseconds'].each(function(method){
403
- Date.Methods[method.toLowerCase()] = method;
404
- });
405
-
406
- var pad = function(n, digits, string){
407
- if (digits == 1) return n;
408
- return n < Math.pow(10, digits - 1) ? (string || '0') + pad(n, digits - 1, string) : n;
409
- };
410
-
411
- Date.implement({
412
-
413
- set: function(prop, value){
414
- prop = prop.toLowerCase();
415
- var method = DateMethods[prop] && 'set' + DateMethods[prop];
416
- if (method && this[method]) this[method](value);
417
- return this;
418
- }.overloadSetter(),
419
-
420
- get: function(prop){
421
- prop = prop.toLowerCase();
422
- var method = DateMethods[prop] && 'get' + DateMethods[prop];
423
- if (method && this[method]) return this[method]();
424
- return null;
425
- }.overloadGetter(),
426
-
427
- clone: function(){
428
- return new Date(this.get('time'));
429
- },
430
-
431
- increment: function(interval, times){
432
- interval = interval || 'day';
433
- times = times != null ? times : 1;
434
-
435
- switch (interval){
436
- case 'year':
437
- return this.increment('month', times * 12);
438
- case 'month':
439
- var d = this.get('date');
440
- this.set('date', 1).set('mo', this.get('mo') + times);
441
- return this.set('date', d.min(this.get('lastdayofmonth')));
442
- case 'week':
443
- return this.increment('day', times * 7);
444
- case 'day':
445
- return this.set('date', this.get('date') + times);
446
- }
447
-
448
- if (!Date.units[interval]) throw new Error(interval + ' is not a supported interval');
449
-
450
- return this.set('time', this.get('time') + times * Date.units[interval]());
451
- },
452
-
453
- decrement: function(interval, times){
454
- return this.increment(interval, -1 * (times != null ? times : 1));
455
- },
456
-
457
- isLeapYear: function(){
458
- return Date.isLeapYear(this.get('year'));
459
- },
460
-
461
- clearTime: function(){
462
- return this.set({hr: 0, min: 0, sec: 0, ms: 0});
463
- },
464
-
465
- diff: function(date, resolution){
466
- if (typeOf(date) == 'string') date = Date.parse(date);
467
-
468
- return ((date - this) / Date.units[resolution || 'day'](3, 3)).round(); // non-leap year, 30-day month
469
- },
470
-
471
- getLastDayOfMonth: function(){
472
- return Date.daysInMonth(this.get('mo'), this.get('year'));
473
- },
474
-
475
- getDayOfYear: function(){
476
- return (Date.UTC(this.get('year'), this.get('mo'), this.get('date') + 1)
477
- - Date.UTC(this.get('year'), 0, 1)) / Date.units.day();
478
- },
479
-
480
- setDay: function(day, firstDayOfWeek){
481
- if (firstDayOfWeek == null){
482
- firstDayOfWeek = Date.getMsg('firstDayOfWeek');
483
- if (firstDayOfWeek === '') firstDayOfWeek = 1;
484
- }
485
-
486
- day = (7 + Date.parseDay(day, true) - firstDayOfWeek) % 7;
487
- var currentDay = (7 + this.get('day') - firstDayOfWeek) % 7;
488
-
489
- return this.increment('day', day - currentDay);
490
- },
491
-
492
- getWeek: function(firstDayOfWeek){
493
- if (firstDayOfWeek == null){
494
- firstDayOfWeek = Date.getMsg('firstDayOfWeek');
495
- if (firstDayOfWeek === '') firstDayOfWeek = 1;
496
- }
497
-
498
- var date = this,
499
- dayOfWeek = (7 + date.get('day') - firstDayOfWeek) % 7,
500
- dividend = 0,
501
- firstDayOfYear;
502
-
503
- if (firstDayOfWeek == 1){
504
- // ISO-8601, week belongs to year that has the most days of the week (i.e. has the thursday of the week)
505
- var month = date.get('month'),
506
- startOfWeek = date.get('date') - dayOfWeek;
507
-
508
- if (month == 11 && startOfWeek > 28) return 1; // Week 1 of next year
509
-
510
- if (month == 0 && startOfWeek < -2){
511
- // Use a date from last year to determine the week
512
- date = new Date(date).decrement('day', dayOfWeek);
513
- dayOfWeek = 0;
514
- }
515
-
516
- firstDayOfYear = new Date(date.get('year'), 0, 1).get('day') || 7;
517
- if (firstDayOfYear > 4) dividend = -7; // First week of the year is not week 1
518
- } else {
519
- // In other cultures the first week of the year is always week 1 and the last week always 53 or 54.
520
- // Days in the same week can have a different weeknumber if the week spreads across two years.
521
- firstDayOfYear = new Date(date.get('year'), 0, 1).get('day');
522
- }
523
-
524
- dividend += date.get('dayofyear');
525
- dividend += 6 - dayOfWeek; // Add days so we calculate the current date's week as a full week
526
- dividend += (7 + firstDayOfYear - firstDayOfWeek) % 7; // Make up for first week of the year not being a full week
527
-
528
- return (dividend / 7);
529
- },
530
-
531
- getOrdinal: function(day){
532
- return Date.getMsg('ordinal', day || this.get('date'));
533
- },
534
-
535
- getTimezone: function(){
536
- return this.toString()
537
- .replace(/^.*? ([A-Z]{3}).[0-9]{4}.*$/, '$1')
538
- .replace(/^.*?\(([A-Z])[a-z]+ ([A-Z])[a-z]+ ([A-Z])[a-z]+\)$/, '$1$2$3');
539
- },
540
-
541
- getGMTOffset: function(){
542
- var off = this.get('timezoneOffset');
543
- return ((off > 0) ? '-' : '+') + pad((off.abs() / 60).floor(), 2) + pad(off % 60, 2);
544
- },
545
-
546
- setAMPM: function(ampm){
547
- ampm = ampm.toUpperCase();
548
- var hr = this.get('hr');
549
- if (hr > 11 && ampm == 'AM') return this.decrement('hour', 12);
550
- else if (hr < 12 && ampm == 'PM') return this.increment('hour', 12);
551
- return this;
552
- },
553
-
554
- getAMPM: function(){
555
- return (this.get('hr') < 12) ? 'AM' : 'PM';
556
- },
557
-
558
- parse: function(str){
559
- this.set('time', Date.parse(str));
560
- return this;
561
- },
562
-
563
- isValid: function(date){
564
- if (!date) date = this;
565
- return typeOf(date) == 'date' && !isNaN(date.valueOf());
566
- },
567
-
568
- format: function(format){
569
- if (!this.isValid()) return 'invalid date';
570
-
571
- if (!format) format = '%x %X';
572
- if (typeof format == 'string') format = formats[format.toLowerCase()] || format;
573
- if (typeof format == 'function') return format(this);
574
-
575
- var d = this;
576
- return format.replace(/%([a-z%])/gi,
577
- function($0, $1){
578
- switch ($1){
579
- case 'a': return Date.getMsg('days_abbr')[d.get('day')];
580
- case 'A': return Date.getMsg('days')[d.get('day')];
581
- case 'b': return Date.getMsg('months_abbr')[d.get('month')];
582
- case 'B': return Date.getMsg('months')[d.get('month')];
583
- case 'c': return d.format('%a %b %d %H:%M:%S %Y');
584
- case 'd': return pad(d.get('date'), 2);
585
- case 'e': return pad(d.get('date'), 2, ' ');
586
- case 'H': return pad(d.get('hr'), 2);
587
- case 'I': return pad((d.get('hr') % 12) || 12, 2);
588
- case 'j': return pad(d.get('dayofyear'), 3);
589
- case 'k': return pad(d.get('hr'), 2, ' ');
590
- case 'l': return pad((d.get('hr') % 12) || 12, 2, ' ');
591
- case 'L': return pad(d.get('ms'), 3);
592
- case 'm': return pad((d.get('mo') + 1), 2);
593
- case 'M': return pad(d.get('min'), 2);
594
- case 'o': return d.get('ordinal');
595
- case 'p': return Date.getMsg(d.get('ampm'));
596
- case 's': return Math.round(d / 1000);
597
- case 'S': return pad(d.get('seconds'), 2);
598
- case 'T': return d.format('%H:%M:%S');
599
- case 'U': return pad(d.get('week'), 2);
600
- case 'w': return d.get('day');
601
- case 'x': return d.format(Date.getMsg('shortDate'));
602
- case 'X': return d.format(Date.getMsg('shortTime'));
603
- case 'y': return d.get('year').toString().substr(2);
604
- case 'Y': return d.get('year');
605
- case 'z': return d.get('GMTOffset');
606
- case 'Z': return d.get('Timezone');
607
- }
608
- return $1;
609
- }
610
- );
611
- },
612
-
613
- toISOString: function(){
614
- return this.format('iso8601');
615
- }
616
-
617
- }).alias({
618
- toJSON: 'toISOString',
619
- compare: 'diff',
620
- strftime: 'format'
621
- });
622
-
623
- // The day and month abbreviations are standardized, so we cannot use simply %a and %b because they will get localized
624
- var rfcDayAbbr = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
625
- rfcMonthAbbr = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
626
-
627
- var formats = {
628
- db: '%Y-%m-%d %H:%M:%S',
629
- compact: '%Y%m%dT%H%M%S',
630
- 'short': '%d %b %H:%M',
631
- 'long': '%B %d, %Y %H:%M',
632
- rfc822: function(date){
633
- return rfcDayAbbr[date.get('day')] + date.format(', %d ') + rfcMonthAbbr[date.get('month')] + date.format(' %Y %H:%M:%S %Z');
634
- },
635
- rfc2822: function(date){
636
- return rfcDayAbbr[date.get('day')] + date.format(', %d ') + rfcMonthAbbr[date.get('month')] + date.format(' %Y %H:%M:%S %z');
637
- },
638
- iso8601: function(date){
639
- return (
640
- date.getUTCFullYear() + '-' +
641
- pad(date.getUTCMonth() + 1, 2) + '-' +
642
- pad(date.getUTCDate(), 2) + 'T' +
643
- pad(date.getUTCHours(), 2) + ':' +
644
- pad(date.getUTCMinutes(), 2) + ':' +
645
- pad(date.getUTCSeconds(), 2) + '.' +
646
- pad(date.getUTCMilliseconds(), 3) + 'Z'
647
- );
648
- }
649
- };
650
-
651
- var parsePatterns = [],
652
- nativeParse = Date.parse;
653
-
654
- var parseWord = function(type, word, num){
655
- var ret = -1,
656
- translated = Date.getMsg(type + 's');
657
- switch (typeOf(word)){
658
- case 'object':
659
- ret = translated[word.get(type)];
660
- break;
661
- case 'number':
662
- ret = translated[word];
663
- if (!ret) throw new Error('Invalid ' + type + ' index: ' + word);
664
- break;
665
- case 'string':
666
- var match = translated.filter(function(name){
667
- return this.test(name);
668
- }, new RegExp('^' + word, 'i'));
669
- if (!match.length) throw new Error('Invalid ' + type + ' string');
670
- if (match.length > 1) throw new Error('Ambiguous ' + type);
671
- ret = match[0];
672
- }
673
-
674
- return (num) ? translated.indexOf(ret) : ret;
675
- };
676
-
677
- var startCentury = 1900,
678
- startYear = 70;
679
-
680
- Date.extend({
681
-
682
- getMsg: function(key, args){
683
- return Locale.get('Date.' + key, args);
684
- },
685
-
686
- units: {
687
- ms: Function.from(1),
688
- second: Function.from(1000),
689
- minute: Function.from(60000),
690
- hour: Function.from(3600000),
691
- day: Function.from(86400000),
692
- week: Function.from(608400000),
693
- month: function(month, year){
694
- var d = new Date;
695
- return Date.daysInMonth(month != null ? month : d.get('mo'), year != null ? year : d.get('year')) * 86400000;
696
- },
697
- year: function(year){
698
- year = year || new Date().get('year');
699
- return Date.isLeapYear(year) ? 31622400000 : 31536000000;
700
- }
701
- },
702
-
703
- daysInMonth: function(month, year){
704
- return [31, Date.isLeapYear(year) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month];
705
- },
706
-
707
- isLeapYear: function(year){
708
- return ((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0);
709
- },
710
-
711
- parse: function(from){
712
- var t = typeOf(from);
713
- if (t == 'number') return new Date(from);
714
- if (t != 'string') return from;
715
- from = from.clean();
716
- if (!from.length) return null;
717
-
718
- var parsed;
719
- parsePatterns.some(function(pattern){
720
- var bits = pattern.re.exec(from);
721
- return (bits) ? (parsed = pattern.handler(bits)) : false;
722
- });
723
-
724
- if (!(parsed && parsed.isValid())){
725
- parsed = new Date(nativeParse(from));
726
- if (!(parsed && parsed.isValid())) parsed = new Date(from.toInt());
727
- }
728
- return parsed;
729
- },
730
-
731
- parseDay: function(day, num){
732
- return parseWord('day', day, num);
733
- },
734
-
735
- parseMonth: function(month, num){
736
- return parseWord('month', month, num);
737
- },
738
-
739
- parseUTC: function(value){
740
- var localDate = new Date(value);
741
- var utcSeconds = Date.UTC(
742
- localDate.get('year'),
743
- localDate.get('mo'),
744
- localDate.get('date'),
745
- localDate.get('hr'),
746
- localDate.get('min'),
747
- localDate.get('sec'),
748
- localDate.get('ms')
749
- );
750
- return new Date(utcSeconds);
751
- },
752
-
753
- orderIndex: function(unit){
754
- return Date.getMsg('dateOrder').indexOf(unit) + 1;
755
- },
756
-
757
- defineFormat: function(name, format){
758
- formats[name] = format;
759
- return this;
760
- },
761
-
762
-
763
-
764
- defineParser: function(pattern){
765
- parsePatterns.push((pattern.re && pattern.handler) ? pattern : build(pattern));
766
- return this;
767
- },
768
-
769
- defineParsers: function(){
770
- Array.flatten(arguments).each(Date.defineParser);
771
- return this;
772
- },
773
-
774
- define2DigitYearStart: function(year){
775
- startYear = year % 100;
776
- startCentury = year - startYear;
777
- return this;
778
- }
779
-
780
- }).extend({
781
- defineFormats: Date.defineFormat.overloadSetter()
782
- });
783
-
784
- var regexOf = function(type){
785
- return new RegExp('(?:' + Date.getMsg(type).map(function(name){
786
- return name.substr(0, 3);
787
- }).join('|') + ')[a-z]*');
788
- };
789
-
790
- var replacers = function(key){
791
- switch (key){
792
- case 'T':
793
- return '%H:%M:%S';
794
- case 'x': // iso8601 covers yyyy-mm-dd, so just check if month is first
795
- return ((Date.orderIndex('month') == 1) ? '%m[-./]%d' : '%d[-./]%m') + '([-./]%y)?';
796
- case 'X':
797
- return '%H([.:]%M)?([.:]%S([.:]%s)?)? ?%p? ?%z?';
798
- }
799
- return null;
800
- };
801
-
802
- var keys = {
803
- d: /[0-2]?[0-9]|3[01]/,
804
- H: /[01]?[0-9]|2[0-3]/,
805
- I: /0?[1-9]|1[0-2]/,
806
- M: /[0-5]?\d/,
807
- s: /\d+/,
808
- o: /[a-z]*/,
809
- p: /[ap]\.?m\.?/,
810
- y: /\d{2}|\d{4}/,
811
- Y: /\d{4}/,
812
- z: /Z|[+-]\d{2}(?::?\d{2})?/
813
- };
814
-
815
- keys.m = keys.I;
816
- keys.S = keys.M;
817
-
818
- var currentLanguage;
819
-
820
- var recompile = function(language){
821
- currentLanguage = language;
822
-
823
- keys.a = keys.A = regexOf('days');
824
- keys.b = keys.B = regexOf('months');
825
-
826
- parsePatterns.each(function(pattern, i){
827
- if (pattern.format) parsePatterns[i] = build(pattern.format);
828
- });
829
- };
830
-
831
- var build = function(format){
832
- if (!currentLanguage) return {format: format};
833
-
834
- var parsed = [];
835
- var re = (format.source || format) // allow format to be regex
836
- .replace(/%([a-z])/gi,
837
- function($0, $1){
838
- return replacers($1) || $0;
839
- }
840
- ).replace(/\((?!\?)/g, '(?:') // make all groups non-capturing
841
- .replace(/ (?!\?|\*)/g, ',? ') // be forgiving with spaces and commas
842
- .replace(/%([a-z%])/gi,
843
- function($0, $1){
844
- var p = keys[$1];
845
- if (!p) return $1;
846
- parsed.push($1);
847
- return '(' + p.source + ')';
848
- }
849
- ).replace(/\[a-z\]/gi, '[a-z\\u00c0-\\uffff;\&]'); // handle unicode words
850
-
851
- return {
852
- format: format,
853
- re: new RegExp('^' + re + '$', 'i'),
854
- handler: function(bits){
855
- bits = bits.slice(1).associate(parsed);
856
- var date = new Date().clearTime(),
857
- year = bits.y || bits.Y;
858
-
859
- if (year != null) handle.call(date, 'y', year); // need to start in the right year
860
- if ('d' in bits) handle.call(date, 'd', 1);
861
- if ('m' in bits || bits.b || bits.B) handle.call(date, 'm', 1);
862
-
863
- for (var key in bits) handle.call(date, key, bits[key]);
864
- return date;
865
- }
866
- };
867
- };
868
-
869
- var handle = function(key, value){
870
- if (!value) return this;
871
-
872
- switch (key){
873
- case 'a': case 'A': return this.set('day', Date.parseDay(value, true));
874
- case 'b': case 'B': return this.set('mo', Date.parseMonth(value, true));
875
- case 'd': return this.set('date', value);
876
- case 'H': case 'I': return this.set('hr', value);
877
- case 'm': return this.set('mo', value - 1);
878
- case 'M': return this.set('min', value);
879
- case 'p': return this.set('ampm', value.replace(/\./g, ''));
880
- case 'S': return this.set('sec', value);
881
- case 's': return this.set('ms', ('0.' + value) * 1000);
882
- case 'w': return this.set('day', value);
883
- case 'Y': return this.set('year', value);
884
- case 'y':
885
- value = +value;
886
- if (value < 100) value += startCentury + (value < startYear ? 100 : 0);
887
- return this.set('year', value);
888
- case 'z':
889
- if (value == 'Z') value = '+00';
890
- var offset = value.match(/([+-])(\d{2}):?(\d{2})?/);
891
- offset = (offset[1] + '1') * (offset[2] * 60 + (+offset[3] || 0)) + this.getTimezoneOffset();
892
- return this.set('time', this - offset * 60000);
893
- }
894
-
895
- return this;
896
- };
897
-
898
- Date.defineParsers(
899
- '%Y([-./]%m([-./]%d((T| )%X)?)?)?', // "1999-12-31", "1999-12-31 11:59pm", "1999-12-31 23:59:59", ISO8601
900
- '%Y%m%d(T%H(%M%S?)?)?', // "19991231", "19991231T1159", compact
901
- '%x( %X)?', // "12/31", "12.31.99", "12-31-1999", "12/31/2008 11:59 PM"
902
- '%d%o( %b( %Y)?)?( %X)?', // "31st", "31st December", "31 Dec 1999", "31 Dec 1999 11:59pm"
903
- '%b( %d%o)?( %Y)?( %X)?', // Same as above with month and day switched
904
- '%Y %b( %d%o( %X)?)?', // Same as above with year coming first
905
- '%o %b %d %X %z %Y', // "Thu Oct 22 08:11:23 +0000 2009"
906
- '%T', // %H:%M:%S
907
- '%H:%M( ?%p)?' // "11:05pm", "11:05 am" and "11:05"
908
- );
909
-
910
- Locale.addEvent('change', function(language){
911
- if (Locale.get('Date')) recompile(language);
912
- }).fireEvent('change', Locale.getCurrent());
913
-
914
- })();
915
-
916
-
917
- /*
918
- ---
919
-
920
- script: String.Extras.js
921
-
922
- name: String.Extras
923
-
924
- description: Extends the String native object to include methods useful in managing various kinds of strings (query strings, urls, html, etc).
925
-
926
- license: MIT-style license
927
-
928
- authors:
929
- - Aaron Newton
930
- - Guillermo Rauch
931
- - Christopher Pitt
932
-
933
- requires:
934
- - Core/String
935
- - Core/Array
936
- - MooTools.More
937
-
938
- provides: [String.Extras]
939
-
940
- ...
941
- */
942
-
943
- (function(){
944
-
945
- var special = {
946
- 'a': /[àáâãäåăą]/g,
947
- 'A': /[ÀÁÂÃÄÅĂĄ]/g,
948
- 'c': /[ćčç]/g,
949
- 'C': /[ĆČÇ]/g,
950
- 'd': /[ďđ]/g,
951
- 'D': /[ĎÐ]/g,
952
- 'e': /[èéêëěę]/g,
953
- 'E': /[ÈÉÊËĚĘ]/g,
954
- 'g': /[ğ]/g,
955
- 'G': /[Ğ]/g,
956
- 'i': /[ìíîï]/g,
957
- 'I': /[ÌÍÎÏ]/g,
958
- 'l': /[ĺľł]/g,
959
- 'L': /[ĹĽŁ]/g,
960
- 'n': /[ñňń]/g,
961
- 'N': /[ÑŇŃ]/g,
962
- 'o': /[òóôõöøő]/g,
963
- 'O': /[ÒÓÔÕÖØ]/g,
964
- 'r': /[řŕ]/g,
965
- 'R': /[ŘŔ]/g,
966
- 's': /[ššş]/g,
967
- 'S': /[ŠŞŚ]/g,
968
- 't': /[ťţ]/g,
969
- 'T': /[ŤŢ]/g,
970
- 'u': /[ùúûůüµ]/g,
971
- 'U': /[ÙÚÛŮÜ]/g,
972
- 'y': /[ÿý]/g,
973
- 'Y': /[ŸÝ]/g,
974
- 'z': /[žźż]/g,
975
- 'Z': /[ŽŹŻ]/g,
976
- 'th': /[þ]/g,
977
- 'TH': /[Þ]/g,
978
- 'dh': /[ð]/g,
979
- 'DH': /[Ð]/g,
980
- 'ss': /[ß]/g,
981
- 'oe': /[œ]/g,
982
- 'OE': /[Œ]/g,
983
- 'ae': /[æ]/g,
984
- 'AE': /[Æ]/g
985
- },
986
-
987
- tidy = {
988
- ' ': /[\xa0\u2002\u2003\u2009]/g,
989
- '*': /[\xb7]/g,
990
- '\'': /[\u2018\u2019]/g,
991
- '"': /[\u201c\u201d]/g,
992
- '...': /[\u2026]/g,
993
- '-': /[\u2013]/g,
994
- // '--': /[\u2014]/g,
995
- '&raquo;': /[\uFFFD]/g
996
- },
997
-
998
- conversions = {
999
- ms: 1,
1000
- s: 1000,
1001
- m: 6e4,
1002
- h: 36e5
1003
- },
1004
-
1005
- findUnits = /(\d*.?\d+)([msh]+)/;
1006
-
1007
- var walk = function(string, replacements){
1008
- var result = string, key;
1009
- for (key in replacements) result = result.replace(replacements[key], key);
1010
- return result;
1011
- };
1012
-
1013
- var getRegexForTag = function(tag, contents){
1014
- tag = tag || '';
1015
- var regstr = contents ? "<" + tag + "(?!\\w)[^>]*>([\\s\\S]*?)<\/" + tag + "(?!\\w)>" : "<\/?" + tag + "([^>]+)?>",
1016
- reg = new RegExp(regstr, "gi");
1017
- return reg;
1018
- };
1019
-
1020
- String.implement({
1021
-
1022
- standardize: function(){
1023
- return walk(this, special);
1024
- },
1025
-
1026
- repeat: function(times){
1027
- return new Array(times + 1).join(this);
1028
- },
1029
-
1030
- pad: function(length, str, direction){
1031
- if (this.length >= length) return this;
1032
-
1033
- var pad = (str == null ? ' ' : '' + str)
1034
- .repeat(length - this.length)
1035
- .substr(0, length - this.length);
1036
-
1037
- if (!direction || direction == 'right') return this + pad;
1038
- if (direction == 'left') return pad + this;
1039
-
1040
- return pad.substr(0, (pad.length / 2).floor()) + this + pad.substr(0, (pad.length / 2).ceil());
1041
- },
1042
-
1043
- getTags: function(tag, contents){
1044
- return this.match(getRegexForTag(tag, contents)) || [];
1045
- },
1046
-
1047
- stripTags: function(tag, contents){
1048
- return this.replace(getRegexForTag(tag, contents), '');
1049
- },
1050
-
1051
- tidy: function(){
1052
- return walk(this, tidy);
1053
- },
1054
-
1055
- truncate: function(max, trail, atChar){
1056
- var string = this;
1057
- if (trail == null && arguments.length == 1) trail = '…';
1058
- if (string.length > max){
1059
- string = string.substring(0, max);
1060
- if (atChar){
1061
- var index = string.lastIndexOf(atChar);
1062
- if (index != -1) string = string.substr(0, index);
1063
- }
1064
- if (trail) string += trail;
1065
- }
1066
- return string;
1067
- },
1068
-
1069
- ms: function(){
1070
- // "Borrowed" from https://gist.github.com/1503944
1071
- var units = findUnits.exec(this);
1072
- if (units == null) return Number(this);
1073
- return Number(units[1]) * conversions[units[2]];
1074
- }
1075
-
1076
- });
1077
-
1078
- })();
1079
-
1080
-
1081
- /*
1082
- ---
1083
-
1084
- script: Drag.js
1085
-
1086
- name: Drag
1087
-
1088
- description: The base Drag Class. Can be used to drag and resize Elements using mouse events.
1089
-
1090
- license: MIT-style license
1091
-
1092
- authors:
1093
- - Valerio Proietti
1094
- - Tom Occhinno
1095
- - Jan Kassens
1096
-
1097
- requires:
1098
- - Core/Events
1099
- - Core/Options
1100
- - Core/Element.Event
1101
- - Core/Element.Style
1102
- - Core/Element.Dimensions
1103
- - MooTools.More
1104
-
1105
- provides: [Drag]
1106
- ...
1107
-
1108
- */
1109
-
1110
- var Drag = new Class({
1111
-
1112
- Implements: [Events, Options],
1113
-
1114
- options: {/*
1115
- onBeforeStart: function(thisElement){},
1116
- onStart: function(thisElement, event){},
1117
- onSnap: function(thisElement){},
1118
- onDrag: function(thisElement, event){},
1119
- onCancel: function(thisElement){},
1120
- onComplete: function(thisElement, event){},*/
1121
- snap: 6,
1122
- unit: 'px',
1123
- grid: false,
1124
- style: true,
1125
- limit: false,
1126
- handle: false,
1127
- invert: false,
1128
- preventDefault: false,
1129
- stopPropagation: false,
1130
- modifiers: {x: 'left', y: 'top'}
1131
- },
1132
-
1133
- initialize: function(){
1134
- var params = Array.link(arguments, {
1135
- 'options': Type.isObject,
1136
- 'element': function(obj){
1137
- return obj != null;
1138
- }
1139
- });
1140
-
1141
- this.element = document.id(params.element);
1142
- this.document = this.element.getDocument();
1143
- this.setOptions(params.options || {});
1144
- var htype = typeOf(this.options.handle);
1145
- this.handles = ((htype == 'array' || htype == 'collection') ? $$(this.options.handle) : document.id(this.options.handle)) || this.element;
1146
- this.mouse = {'now': {}, 'pos': {}};
1147
- this.value = {'start': {}, 'now': {}};
1148
-
1149
- this.selection = 'selectstart' in document ? 'selectstart' : 'mousedown';
1150
-
1151
-
1152
- if ('ondragstart' in document && !('FileReader' in window) && !Drag.ondragstartFixed){
1153
- document.ondragstart = Function.from(false);
1154
- Drag.ondragstartFixed = true;
1155
- }
1156
-
1157
- this.bound = {
1158
- start: this.start.bind(this),
1159
- check: this.check.bind(this),
1160
- drag: this.drag.bind(this),
1161
- stop: this.stop.bind(this),
1162
- cancel: this.cancel.bind(this),
1163
- eventStop: Function.from(false)
1164
- };
1165
- this.attach();
1166
- },
1167
-
1168
- attach: function(){
1169
- this.handles.addEvent('mousedown', this.bound.start);
1170
- return this;
1171
- },
1172
-
1173
- detach: function(){
1174
- this.handles.removeEvent('mousedown', this.bound.start);
1175
- return this;
1176
- },
1177
-
1178
- start: function(event){
1179
- var options = this.options;
1180
-
1181
- if (event.rightClick) return;
1182
-
1183
- if (options.preventDefault) event.preventDefault();
1184
- if (options.stopPropagation) event.stopPropagation();
1185
- this.mouse.start = event.page;
1186
-
1187
- this.fireEvent('beforeStart', this.element);
1188
-
1189
- var limit = options.limit;
1190
- this.limit = {x: [], y: []};
1191
-
1192
- var z, coordinates;
1193
- for (z in options.modifiers){
1194
- if (!options.modifiers[z]) continue;
1195
-
1196
- var style = this.element.getStyle(options.modifiers[z]);
1197
-
1198
- // Some browsers (IE and Opera) don't always return pixels.
1199
- if (style && !style.match(/px$/)){
1200
- if (!coordinates) coordinates = this.element.getCoordinates(this.element.getOffsetParent());
1201
- style = coordinates[options.modifiers[z]];
1202
- }
1203
-
1204
- if (options.style) this.value.now[z] = (style || 0).toInt();
1205
- else this.value.now[z] = this.element[options.modifiers[z]];
1206
-
1207
- if (options.invert) this.value.now[z] *= -1;
1208
-
1209
- this.mouse.pos[z] = event.page[z] - this.value.now[z];
1210
-
1211
- if (limit && limit[z]){
1212
- var i = 2;
1213
- while (i--){
1214
- var limitZI = limit[z][i];
1215
- if (limitZI || limitZI === 0) this.limit[z][i] = (typeof limitZI == 'function') ? limitZI() : limitZI;
1216
- }
1217
- }
1218
- }
1219
-
1220
- if (typeOf(this.options.grid) == 'number') this.options.grid = {
1221
- x: this.options.grid,
1222
- y: this.options.grid
1223
- };
1224
-
1225
- var events = {
1226
- mousemove: this.bound.check,
1227
- mouseup: this.bound.cancel
1228
- };
1229
- events[this.selection] = this.bound.eventStop;
1230
- this.document.addEvents(events);
1231
- },
1232
-
1233
- check: function(event){
1234
- if (this.options.preventDefault) event.preventDefault();
1235
- var distance = Math.round(Math.sqrt(Math.pow(event.page.x - this.mouse.start.x, 2) + Math.pow(event.page.y - this.mouse.start.y, 2)));
1236
- if (distance > this.options.snap){
1237
- this.cancel();
1238
- this.document.addEvents({
1239
- mousemove: this.bound.drag,
1240
- mouseup: this.bound.stop
1241
- });
1242
- this.fireEvent('start', [this.element, event]).fireEvent('snap', this.element);
1243
- }
1244
- },
1245
-
1246
- drag: function(event){
1247
- var options = this.options;
1248
-
1249
- if (options.preventDefault) event.preventDefault();
1250
- this.mouse.now = event.page;
1251
-
1252
- for (var z in options.modifiers){
1253
- if (!options.modifiers[z]) continue;
1254
- this.value.now[z] = this.mouse.now[z] - this.mouse.pos[z];
1255
-
1256
- if (options.invert) this.value.now[z] *= -1;
1257
-
1258
- if (options.limit && this.limit[z]){
1259
- if ((this.limit[z][1] || this.limit[z][1] === 0) && (this.value.now[z] > this.limit[z][1])){
1260
- this.value.now[z] = this.limit[z][1];
1261
- } else if ((this.limit[z][0] || this.limit[z][0] === 0) && (this.value.now[z] < this.limit[z][0])){
1262
- this.value.now[z] = this.limit[z][0];
1263
- }
1264
- }
1265
-
1266
- if (options.grid[z]) this.value.now[z] -= ((this.value.now[z] - (this.limit[z][0]||0)) % options.grid[z]);
1267
-
1268
- if (options.style) this.element.setStyle(options.modifiers[z], this.value.now[z] + options.unit);
1269
- else this.element[options.modifiers[z]] = this.value.now[z];
1270
- }
1271
-
1272
- this.fireEvent('drag', [this.element, event]);
1273
- },
1274
-
1275
- cancel: function(event){
1276
- this.document.removeEvents({
1277
- mousemove: this.bound.check,
1278
- mouseup: this.bound.cancel
1279
- });
1280
- if (event){
1281
- this.document.removeEvent(this.selection, this.bound.eventStop);
1282
- this.fireEvent('cancel', this.element);
1283
- }
1284
- },
1285
-
1286
- stop: function(event){
1287
- var events = {
1288
- mousemove: this.bound.drag,
1289
- mouseup: this.bound.stop
1290
- };
1291
- events[this.selection] = this.bound.eventStop;
1292
- this.document.removeEvents(events);
1293
- if (event) this.fireEvent('complete', [this.element, event]);
1294
- }
1295
-
1296
- });
1297
-
1298
- Element.implement({
1299
-
1300
- makeResizable: function(options){
1301
- var drag = new Drag(this, Object.merge({
1302
- modifiers: {
1303
- x: 'width',
1304
- y: 'height'
1305
- }
1306
- }, options));
1307
-
1308
- this.store('resizer', drag);
1309
- return drag.addEvent('drag', function(){
1310
- this.fireEvent('resize', drag);
1311
- }.bind(this));
1312
- }
1313
-
1314
- });
1315
-
1316
-
1317
- /*
1318
- ---
1319
-
1320
- script: Drag.Move.js
1321
-
1322
- name: Drag.Move
1323
-
1324
- description: A Drag extension that provides support for the constraining of draggables to containers and droppables.
1325
-
1326
- license: MIT-style license
1327
-
1328
- authors:
1329
- - Valerio Proietti
1330
- - Tom Occhinno
1331
- - Jan Kassens
1332
- - Aaron Newton
1333
- - Scott Kyle
1334
-
1335
- requires:
1336
- - Core/Element.Dimensions
1337
- - Drag
1338
-
1339
- provides: [Drag.Move]
1340
-
1341
- ...
1342
- */
1343
-
1344
- Drag.Move = new Class({
1345
-
1346
- Extends: Drag,
1347
-
1348
- options: {/*
1349
- onEnter: function(thisElement, overed){},
1350
- onLeave: function(thisElement, overed){},
1351
- onDrop: function(thisElement, overed, event){},*/
1352
- droppables: [],
1353
- container: false,
1354
- precalculate: false,
1355
- includeMargins: true,
1356
- checkDroppables: true
1357
- },
1358
-
1359
- initialize: function(element, options){
1360
- this.parent(element, options);
1361
- element = this.element;
1362
-
1363
- this.droppables = $$(this.options.droppables);
1364
- this.setContainer(this.options.container);
1365
-
1366
- if (this.options.style){
1367
- if (this.options.modifiers.x == 'left' && this.options.modifiers.y == 'top'){
1368
- var parent = element.getOffsetParent(),
1369
- styles = element.getStyles('left', 'top');
1370
- if (parent && (styles.left == 'auto' || styles.top == 'auto')){
1371
- element.setPosition(element.getPosition(parent));
1372
- }
1373
- }
1374
-
1375
- if (element.getStyle('position') == 'static') element.setStyle('position', 'absolute');
1376
- }
1377
-
1378
- this.addEvent('start', this.checkDroppables, true);
1379
- this.overed = null;
1380
- },
1381
-
1382
- setContainer: function(container) {
1383
- this.container = document.id(container);
1384
- if (this.container && typeOf(this.container) != 'element'){
1385
- this.container = document.id(this.container.getDocument().body);
1386
- }
1387
- },
1388
-
1389
- start: function(event){
1390
- if (this.container) this.options.limit = this.calculateLimit();
1391
-
1392
- if (this.options.precalculate){
1393
- this.positions = this.droppables.map(function(el){
1394
- return el.getCoordinates();
1395
- });
1396
- }
1397
-
1398
- this.parent(event);
1399
- },
1400
-
1401
- calculateLimit: function(){
1402
- var element = this.element,
1403
- container = this.container,
1404
-
1405
- offsetParent = document.id(element.getOffsetParent()) || document.body,
1406
- containerCoordinates = container.getCoordinates(offsetParent),
1407
- elementMargin = {},
1408
- elementBorder = {},
1409
- containerMargin = {},
1410
- containerBorder = {},
1411
- offsetParentPadding = {};
1412
-
1413
- ['top', 'right', 'bottom', 'left'].each(function(pad){
1414
- elementMargin[pad] = element.getStyle('margin-' + pad).toInt();
1415
- elementBorder[pad] = element.getStyle('border-' + pad).toInt();
1416
- containerMargin[pad] = container.getStyle('margin-' + pad).toInt();
1417
- containerBorder[pad] = container.getStyle('border-' + pad).toInt();
1418
- offsetParentPadding[pad] = offsetParent.getStyle('padding-' + pad).toInt();
1419
- }, this);
1420
-
1421
- var width = element.offsetWidth + elementMargin.left + elementMargin.right,
1422
- height = element.offsetHeight + elementMargin.top + elementMargin.bottom,
1423
- left = 0,
1424
- top = 0,
1425
- right = containerCoordinates.right - containerBorder.right - width,
1426
- bottom = containerCoordinates.bottom - containerBorder.bottom - height;
1427
-
1428
- if (this.options.includeMargins){
1429
- left += elementMargin.left;
1430
- top += elementMargin.top;
1431
- } else {
1432
- right += elementMargin.right;
1433
- bottom += elementMargin.bottom;
1434
- }
1435
-
1436
- if (element.getStyle('position') == 'relative'){
1437
- var coords = element.getCoordinates(offsetParent);
1438
- coords.left -= element.getStyle('left').toInt();
1439
- coords.top -= element.getStyle('top').toInt();
1440
-
1441
- left -= coords.left;
1442
- top -= coords.top;
1443
- if (container.getStyle('position') != 'relative'){
1444
- left += containerBorder.left;
1445
- top += containerBorder.top;
1446
- }
1447
- right += elementMargin.left - coords.left;
1448
- bottom += elementMargin.top - coords.top;
1449
-
1450
- if (container != offsetParent){
1451
- left += containerMargin.left + offsetParentPadding.left;
1452
- if (!offsetParentPadding.left && left < 0) left = 0;
1453
- top += offsetParent == document.body ? 0 : containerMargin.top + offsetParentPadding.top;
1454
- if (!offsetParentPadding.top && top < 0) top = 0;
1455
- }
1456
- } else {
1457
- left -= elementMargin.left;
1458
- top -= elementMargin.top;
1459
- if (container != offsetParent){
1460
- left += containerCoordinates.left + containerBorder.left;
1461
- top += containerCoordinates.top + containerBorder.top;
1462
- }
1463
- }
1464
-
1465
- return {
1466
- x: [left, right],
1467
- y: [top, bottom]
1468
- };
1469
- },
1470
-
1471
- getDroppableCoordinates: function(element){
1472
- var position = element.getCoordinates();
1473
- if (element.getStyle('position') == 'fixed'){
1474
- var scroll = window.getScroll();
1475
- position.left += scroll.x;
1476
- position.right += scroll.x;
1477
- position.top += scroll.y;
1478
- position.bottom += scroll.y;
1479
- }
1480
- return position;
1481
- },
1482
-
1483
- checkDroppables: function(){
1484
- var overed = this.droppables.filter(function(el, i){
1485
- el = this.positions ? this.positions[i] : this.getDroppableCoordinates(el);
1486
- var now = this.mouse.now;
1487
- return (now.x > el.left && now.x < el.right && now.y < el.bottom && now.y > el.top);
1488
- }, this).getLast();
1489
-
1490
- if (this.overed != overed){
1491
- if (this.overed) this.fireEvent('leave', [this.element, this.overed]);
1492
- if (overed) this.fireEvent('enter', [this.element, overed]);
1493
- this.overed = overed;
1494
- }
1495
- },
1496
-
1497
- drag: function(event){
1498
- this.parent(event);
1499
- if (this.options.checkDroppables && this.droppables.length) this.checkDroppables();
1500
- },
1501
-
1502
- stop: function(event){
1503
- this.checkDroppables();
1504
- this.fireEvent('drop', [this.element, this.overed, event]);
1505
- this.overed = null;
1506
- return this.parent(event);
1507
- }
1508
-
1509
- });
1510
-
1511
- Element.implement({
1512
-
1513
- makeDraggable: function(options){
1514
- var drag = new Drag.Move(this, options);
1515
- this.store('dragger', drag);
1516
- return drag;
1517
- }
1518
-
1519
- });
1520
-
1521
-
1522
- /*
1523
- ---
1524
-
1525
- script: Sortables.js
1526
-
1527
- name: Sortables
1528
-
1529
- description: Class for creating a drag and drop sorting interface for lists of items.
1530
-
1531
- license: MIT-style license
1532
-
1533
- authors:
1534
- - Tom Occhino
1535
-
1536
- requires:
1537
- - Core/Fx.Morph
1538
- - Drag.Move
1539
-
1540
- provides: [Sortables]
1541
-
1542
- ...
1543
- */
1544
-
1545
- var Sortables = new Class({
1546
-
1547
- Implements: [Events, Options],
1548
-
1549
- options: {/*
1550
- onSort: function(element, clone){},
1551
- onStart: function(element, clone){},
1552
- onComplete: function(element){},*/
1553
- opacity: 1,
1554
- clone: false,
1555
- revert: false,
1556
- handle: false,
1557
- dragOptions: {},
1558
- unDraggableTags: ['button', 'input', 'a', 'textarea', 'select', 'option']
1559
- },
1560
-
1561
- initialize: function(lists, options){
1562
- this.setOptions(options);
1563
-
1564
- this.elements = [];
1565
- this.lists = [];
1566
- this.idle = true;
1567
-
1568
- this.addLists($$(document.id(lists) || lists));
1569
-
1570
- if (!this.options.clone) this.options.revert = false;
1571
- if (this.options.revert) this.effect = new Fx.Morph(null, Object.merge({
1572
- duration: 250,
1573
- link: 'cancel'
1574
- }, this.options.revert));
1575
- },
1576
-
1577
- attach: function(){
1578
- this.addLists(this.lists);
1579
- return this;
1580
- },
1581
-
1582
- detach: function(){
1583
- this.lists = this.removeLists(this.lists);
1584
- return this;
1585
- },
1586
-
1587
- addItems: function(){
1588
- Array.flatten(arguments).each(function(element){
1589
- this.elements.push(element);
1590
- var start = element.retrieve('sortables:start', function(event){
1591
- this.start.call(this, event, element);
1592
- }.bind(this));
1593
- (this.options.handle ? element.getElement(this.options.handle) || element : element).addEvent('mousedown', start);
1594
- }, this);
1595
- return this;
1596
- },
1597
-
1598
- addLists: function(){
1599
- Array.flatten(arguments).each(function(list){
1600
- this.lists.include(list);
1601
- this.addItems(list.getChildren());
1602
- }, this);
1603
- return this;
1604
- },
1605
-
1606
- removeItems: function(){
1607
- return $$(Array.flatten(arguments).map(function(element){
1608
- this.elements.erase(element);
1609
- var start = element.retrieve('sortables:start');
1610
- (this.options.handle ? element.getElement(this.options.handle) || element : element).removeEvent('mousedown', start);
1611
-
1612
- return element;
1613
- }, this));
1614
- },
1615
-
1616
- removeLists: function(){
1617
- return $$(Array.flatten(arguments).map(function(list){
1618
- this.lists.erase(list);
1619
- this.removeItems(list.getChildren());
1620
-
1621
- return list;
1622
- }, this));
1623
- },
1624
-
1625
- getDroppableCoordinates: function (element){
1626
- var offsetParent = element.getOffsetParent();
1627
- var position = element.getPosition(offsetParent);
1628
- var scroll = {
1629
- w: window.getScroll(),
1630
- offsetParent: offsetParent.getScroll()
1631
- };
1632
- position.x += scroll.offsetParent.x;
1633
- position.y += scroll.offsetParent.y;
1634
-
1635
- if (offsetParent.getStyle('position') == 'fixed'){
1636
- position.x -= scroll.w.x;
1637
- position.y -= scroll.w.y;
1638
- }
1639
-
1640
- return position;
1641
- },
1642
-
1643
- getClone: function(event, element){
1644
- if (!this.options.clone) return new Element(element.tagName).inject(document.body);
1645
- if (typeOf(this.options.clone) == 'function') return this.options.clone.call(this, event, element, this.list);
1646
- var clone = element.clone(true).setStyles({
1647
- margin: 0,
1648
- position: 'absolute',
1649
- visibility: 'hidden',
1650
- width: element.getStyle('width')
1651
- }).addEvent('mousedown', function(event){
1652
- element.fireEvent('mousedown', event);
1653
- });
1654
- //prevent the duplicated radio inputs from unchecking the real one
1655
- if (clone.get('html').test('radio')){
1656
- clone.getElements('input[type=radio]').each(function(input, i){
1657
- input.set('name', 'clone_' + i);
1658
- if (input.get('checked')) element.getElements('input[type=radio]')[i].set('checked', true);
1659
- });
1660
- }
1661
-
1662
- return clone.inject(this.list).setPosition(this.getDroppableCoordinates(this.element));
1663
- },
1664
-
1665
- getDroppables: function(){
1666
- var droppables = this.list.getChildren().erase(this.clone).erase(this.element);
1667
- if (!this.options.constrain) droppables.append(this.lists).erase(this.list);
1668
- return droppables;
1669
- },
1670
-
1671
- insert: function(dragging, element){
1672
- var where = 'inside';
1673
- if (this.lists.contains(element)){
1674
- this.list = element;
1675
- this.drag.droppables = this.getDroppables();
1676
- } else {
1677
- where = this.element.getAllPrevious().contains(element) ? 'before' : 'after';
1678
- }
1679
- this.element.inject(element, where);
1680
- this.fireEvent('sort', [this.element, this.clone]);
1681
- },
1682
-
1683
- start: function(event, element){
1684
- if (
1685
- !this.idle ||
1686
- event.rightClick ||
1687
- (!this.options.handle && this.options.unDraggableTags.contains(event.target.get('tag')))
1688
- ) return;
1689
-
1690
- this.idle = false;
1691
- this.element = element;
1692
- this.opacity = element.getStyle('opacity');
1693
- this.list = element.getParent();
1694
- this.clone = this.getClone(event, element);
1695
-
1696
- this.drag = new Drag.Move(this.clone, Object.merge({
1697
-
1698
- droppables: this.getDroppables()
1699
- }, this.options.dragOptions)).addEvents({
1700
- onSnap: function(){
1701
- event.stop();
1702
- this.clone.setStyle('visibility', 'visible');
1703
- this.element.setStyle('opacity', this.options.opacity || 0);
1704
- this.fireEvent('start', [this.element, this.clone]);
1705
- }.bind(this),
1706
- onEnter: this.insert.bind(this),
1707
- onCancel: this.end.bind(this),
1708
- onComplete: this.end.bind(this)
1709
- });
1710
-
1711
- this.clone.inject(this.element, 'before');
1712
- this.drag.start(event);
1713
- },
1714
-
1715
- end: function(){
1716
- this.drag.detach();
1717
- this.element.setStyle('opacity', this.opacity);
1718
- var self = this;
1719
- if (this.effect){
1720
- var dim = this.element.getStyles('width', 'height'),
1721
- clone = this.clone,
1722
- pos = clone.computePosition(this.getDroppableCoordinates(clone));
1723
-
1724
- var destroy = function(){
1725
- this.removeEvent('cancel', destroy);
1726
- clone.destroy();
1727
- self.reset();
1728
- };
1729
-
1730
- this.effect.element = clone;
1731
- this.effect.start({
1732
- top: pos.top,
1733
- left: pos.left,
1734
- width: dim.width,
1735
- height: dim.height,
1736
- opacity: 0.25
1737
- }).addEvent('cancel', destroy).chain(destroy);
1738
- } else {
1739
- this.clone.destroy();
1740
- self.reset();
1741
- }
1742
-
1743
- },
1744
-
1745
- reset: function(){
1746
- this.idle = true;
1747
- this.fireEvent('complete', this.element);
1748
- },
1749
-
1750
- serialize: function(){
1751
- var params = Array.link(arguments, {
1752
- modifier: Type.isFunction,
1753
- index: function(obj){
1754
- return obj != null;
1755
- }
1756
- });
1757
- var serial = this.lists.map(function(list){
1758
- return list.getChildren().map(params.modifier || function(element){
1759
- return element.get('id');
1760
- }, this);
1761
- }, this);
1762
-
1763
- var index = params.index;
1764
- if (this.lists.length == 1) index = 0;
1765
- return (index || index === 0) && index >= 0 && index < this.lists.length ? serial[index] : serial;
1766
- }
1767
-
1768
- });
1769
-
1770
-
1771
- /*
1772
- ---
1773
-
1774
- script: Assets.js
1775
-
1776
- name: Assets
1777
-
1778
- description: Provides methods to dynamically load JavaScript, CSS, and Image files into the document.
1779
-
1780
- license: MIT-style license
1781
-
1782
- authors:
1783
- - Valerio Proietti
1784
-
1785
- requires:
1786
- - Core/Element.Event
1787
- - MooTools.More
1788
-
1789
- provides: [Assets]
1790
-
1791
- ...
1792
- */
1793
-
1794
- var Asset = {
1795
-
1796
- javascript: function(source, properties){
1797
- if (!properties) properties = {};
1798
-
1799
- var script = new Element('script', {src: source, type: 'text/javascript'}),
1800
- doc = properties.document || document,
1801
- load = properties.onload || properties.onLoad;
1802
-
1803
- delete properties.onload;
1804
- delete properties.onLoad;
1805
- delete properties.document;
1806
-
1807
- if (load){
1808
- if (!script.addEventListener){
1809
- script.addEvent('readystatechange', function(){
1810
- if (['loaded', 'complete'].contains(this.readyState)) load.call(this);
1811
- });
1812
- } else {
1813
- script.addEvent('load', load);
1814
- }
1815
- }
1816
-
1817
- return script.set(properties).inject(doc.head);
1818
- },
1819
-
1820
- css: function(source, properties){
1821
- if (!properties) properties = {};
1822
-
1823
- var link = new Element('link', {
1824
- rel: 'stylesheet',
1825
- media: 'screen',
1826
- type: 'text/css',
1827
- href: source
1828
- });
1829
-
1830
- var load = properties.onload || properties.onLoad,
1831
- doc = properties.document || document;
1832
-
1833
- delete properties.onload;
1834
- delete properties.onLoad;
1835
- delete properties.document;
1836
-
1837
- if (load) link.addEvent('load', load);
1838
- return link.set(properties).inject(doc.head);
1839
- },
1840
-
1841
- image: function(source, properties){
1842
- if (!properties) properties = {};
1843
-
1844
- var image = new Image(),
1845
- element = document.id(image) || new Element('img');
1846
-
1847
- ['load', 'abort', 'error'].each(function(name){
1848
- var type = 'on' + name,
1849
- cap = 'on' + name.capitalize(),
1850
- event = properties[type] || properties[cap] || function(){};
1851
-
1852
- delete properties[cap];
1853
- delete properties[type];
1854
-
1855
- image[type] = function(){
1856
- if (!image) return;
1857
- if (!element.parentNode){
1858
- element.width = image.width;
1859
- element.height = image.height;
1860
- }
1861
- image = image.onload = image.onabort = image.onerror = null;
1862
- event.delay(1, element, element);
1863
- element.fireEvent(name, element, 1);
1864
- };
1865
- });
1866
-
1867
- image.src = element.src = source;
1868
- if (image && image.complete) image.onload.delay(1);
1869
- return element.set(properties);
1870
- },
1871
-
1872
- images: function(sources, options){
1873
- sources = Array.from(sources);
1874
-
1875
- var fn = function(){},
1876
- counter = 0;
1877
-
1878
- options = Object.merge({
1879
- onComplete: fn,
1880
- onProgress: fn,
1881
- onError: fn,
1882
- properties: {}
1883
- }, options);
1884
-
1885
- return new Elements(sources.map(function(source, index){
1886
- return Asset.image(source, Object.append(options.properties, {
1887
- onload: function(){
1888
- counter++;
1889
- options.onProgress.call(this, counter, index, source);
1890
- if (counter == sources.length) options.onComplete();
1891
- },
1892
- onerror: function(){
1893
- counter++;
1894
- options.onError.call(this, counter, index, source);
1895
- if (counter == sources.length) options.onComplete();
1896
- }
1897
- }));
1898
- }));
1899
- }
1900
-
1901
- };
1902
-
1903
-
1904
- /*
1905
- ---
1906
-
1907
- script: Element.Measure.js
1908
-
1909
- name: Element.Measure
1910
-
1911
- description: Extends the Element native object to include methods useful in measuring dimensions.
1912
-
1913
- credits: "Element.measure / .expose methods by Daniel Steigerwald License: MIT-style license. Copyright: Copyright (c) 2008 Daniel Steigerwald, daniel.steigerwald.cz"
1914
-
1915
- license: MIT-style license
1916
-
1917
- authors:
1918
- - Aaron Newton
1919
-
1920
- requires:
1921
- - Core/Element.Style
1922
- - Core/Element.Dimensions
1923
- - MooTools.More
1924
-
1925
- provides: [Element.Measure]
1926
-
1927
- ...
1928
- */
1929
-
1930
- (function(){
1931
-
1932
- var getStylesList = function(styles, planes){
1933
- var list = [];
1934
- Object.each(planes, function(directions){
1935
- Object.each(directions, function(edge){
1936
- styles.each(function(style){
1937
- list.push(style + '-' + edge + (style == 'border' ? '-width' : ''));
1938
- });
1939
- });
1940
- });
1941
- return list;
1942
- };
1943
-
1944
- var calculateEdgeSize = function(edge, styles){
1945
- var total = 0;
1946
- Object.each(styles, function(value, style){
1947
- if (style.test(edge)) total = total + value.toInt();
1948
- });
1949
- return total;
1950
- };
1951
-
1952
- var isVisible = function(el){
1953
- return !!(!el || el.offsetHeight || el.offsetWidth);
1954
- };
1955
-
1956
-
1957
- Element.implement({
1958
-
1959
- measure: function(fn){
1960
- if (isVisible(this)) return fn.call(this);
1961
- var parent = this.getParent(),
1962
- toMeasure = [];
1963
- while (!isVisible(parent) && parent != document.body){
1964
- toMeasure.push(parent.expose());
1965
- parent = parent.getParent();
1966
- }
1967
- var restore = this.expose(),
1968
- result = fn.call(this);
1969
- restore();
1970
- toMeasure.each(function(restore){
1971
- restore();
1972
- });
1973
- return result;
1974
- },
1975
-
1976
- expose: function(){
1977
- if (this.getStyle('display') != 'none') return function(){};
1978
- var before = this.style.cssText;
1979
- this.setStyles({
1980
- display: 'block',
1981
- position: 'absolute',
1982
- visibility: 'hidden'
1983
- });
1984
- return function(){
1985
- this.style.cssText = before;
1986
- }.bind(this);
1987
- },
1988
-
1989
- getDimensions: function(options){
1990
- options = Object.merge({computeSize: false}, options);
1991
- var dim = {x: 0, y: 0};
1992
-
1993
- var getSize = function(el, options){
1994
- return (options.computeSize) ? el.getComputedSize(options) : el.getSize();
1995
- };
1996
-
1997
- var parent = this.getParent('body');
1998
-
1999
- if (parent && this.getStyle('display') == 'none'){
2000
- dim = this.measure(function(){
2001
- return getSize(this, options);
2002
- });
2003
- } else if (parent){
2004
- try { //safari sometimes crashes here, so catch it
2005
- dim = getSize(this, options);
2006
- }catch(e){}
2007
- }
2008
-
2009
- return Object.append(dim, (dim.x || dim.x === 0) ? {
2010
- width: dim.x,
2011
- height: dim.y
2012
- } : {
2013
- x: dim.width,
2014
- y: dim.height
2015
- }
2016
- );
2017
- },
2018
-
2019
- getComputedSize: function(options){
2020
-
2021
-
2022
- options = Object.merge({
2023
- styles: ['padding','border'],
2024
- planes: {
2025
- height: ['top','bottom'],
2026
- width: ['left','right']
2027
- },
2028
- mode: 'both'
2029
- }, options);
2030
-
2031
- var styles = {},
2032
- size = {width: 0, height: 0},
2033
- dimensions;
2034
-
2035
- if (options.mode == 'vertical'){
2036
- delete size.width;
2037
- delete options.planes.width;
2038
- } else if (options.mode == 'horizontal'){
2039
- delete size.height;
2040
- delete options.planes.height;
2041
- }
2042
-
2043
- getStylesList(options.styles, options.planes).each(function(style){
2044
- styles[style] = this.getStyle(style).toInt();
2045
- }, this);
2046
-
2047
- Object.each(options.planes, function(edges, plane){
2048
-
2049
- var capitalized = plane.capitalize(),
2050
- style = this.getStyle(plane);
2051
-
2052
- if (style == 'auto' && !dimensions) dimensions = this.getDimensions();
2053
-
2054
- style = styles[plane] = (style == 'auto') ? dimensions[plane] : style.toInt();
2055
- size['total' + capitalized] = style;
2056
-
2057
- edges.each(function(edge){
2058
- var edgesize = calculateEdgeSize(edge, styles);
2059
- size['computed' + edge.capitalize()] = edgesize;
2060
- size['total' + capitalized] += edgesize;
2061
- });
2062
-
2063
- }, this);
2064
-
2065
- return Object.append(size, styles);
2066
- }
2067
-
2068
- });
2069
-
2070
- })();
2071
-
2072
-
2073
- /*
2074
- ---
2075
-
2076
- script: Element.Position.js
2077
-
2078
- name: Element.Position
2079
-
2080
- description: Extends the Element native object to include methods useful positioning elements relative to others.
2081
-
2082
- license: MIT-style license
2083
-
2084
- authors:
2085
- - Aaron Newton
2086
- - Jacob Thornton
2087
-
2088
- requires:
2089
- - Core/Options
2090
- - Core/Element.Dimensions
2091
- - Element.Measure
2092
-
2093
- provides: [Element.Position]
2094
-
2095
- ...
2096
- */
2097
-
2098
- (function(original){
2099
-
2100
- var local = Element.Position = {
2101
-
2102
- options: {/*
2103
- edge: false,
2104
- returnPos: false,
2105
- minimum: {x: 0, y: 0},
2106
- maximum: {x: 0, y: 0},
2107
- relFixedPosition: false,
2108
- ignoreMargins: false,
2109
- ignoreScroll: false,
2110
- allowNegative: false,*/
2111
- relativeTo: document.body,
2112
- position: {
2113
- x: 'center', //left, center, right
2114
- y: 'center' //top, center, bottom
2115
- },
2116
- offset: {x: 0, y: 0}
2117
- },
2118
-
2119
- getOptions: function(element, options){
2120
- options = Object.merge({}, local.options, options);
2121
- local.setPositionOption(options);
2122
- local.setEdgeOption(options);
2123
- local.setOffsetOption(element, options);
2124
- local.setDimensionsOption(element, options);
2125
- return options;
2126
- },
2127
-
2128
- setPositionOption: function(options){
2129
- options.position = local.getCoordinateFromValue(options.position);
2130
- },
2131
-
2132
- setEdgeOption: function(options){
2133
- var edgeOption = local.getCoordinateFromValue(options.edge);
2134
- options.edge = edgeOption ? edgeOption :
2135
- (options.position.x == 'center' && options.position.y == 'center') ? {x: 'center', y: 'center'} :
2136
- {x: 'left', y: 'top'};
2137
- },
2138
-
2139
- setOffsetOption: function(element, options){
2140
- var parentOffset = {x: 0, y: 0};
2141
- var parentScroll = {x: 0, y: 0};
2142
- var offsetParent = element.measure(function(){
2143
- return document.id(this.getOffsetParent());
2144
- });
2145
-
2146
- if (!offsetParent || offsetParent == element.getDocument().body) return;
2147
-
2148
- parentScroll = offsetParent.getScroll();
2149
- parentOffset = offsetParent.measure(function(){
2150
- var position = this.getPosition();
2151
- if (this.getStyle('position') == 'fixed'){
2152
- var scroll = window.getScroll();
2153
- position.x += scroll.x;
2154
- position.y += scroll.y;
2155
- }
2156
- return position;
2157
- });
2158
-
2159
- options.offset = {
2160
- parentPositioned: offsetParent != document.id(options.relativeTo),
2161
- x: options.offset.x - parentOffset.x + parentScroll.x,
2162
- y: options.offset.y - parentOffset.y + parentScroll.y
2163
- };
2164
- },
2165
-
2166
- setDimensionsOption: function(element, options){
2167
- options.dimensions = element.getDimensions({
2168
- computeSize: true,
2169
- styles: ['padding', 'border', 'margin']
2170
- });
2171
- },
2172
-
2173
- getPosition: function(element, options){
2174
- var position = {};
2175
- options = local.getOptions(element, options);
2176
- var relativeTo = document.id(options.relativeTo) || document.body;
2177
-
2178
- local.setPositionCoordinates(options, position, relativeTo);
2179
- if (options.edge) local.toEdge(position, options);
2180
-
2181
- var offset = options.offset;
2182
- position.left = ((position.x >= 0 || offset.parentPositioned || options.allowNegative) ? position.x : 0).toInt();
2183
- position.top = ((position.y >= 0 || offset.parentPositioned || options.allowNegative) ? position.y : 0).toInt();
2184
-
2185
- local.toMinMax(position, options);
2186
-
2187
- if (options.relFixedPosition || relativeTo.getStyle('position') == 'fixed') local.toRelFixedPosition(relativeTo, position);
2188
- if (options.ignoreScroll) local.toIgnoreScroll(relativeTo, position);
2189
- if (options.ignoreMargins) local.toIgnoreMargins(position, options);
2190
-
2191
- position.left = Math.ceil(position.left);
2192
- position.top = Math.ceil(position.top);
2193
- delete position.x;
2194
- delete position.y;
2195
-
2196
- return position;
2197
- },
2198
-
2199
- setPositionCoordinates: function(options, position, relativeTo){
2200
- var offsetY = options.offset.y,
2201
- offsetX = options.offset.x,
2202
- calc = (relativeTo == document.body) ? window.getScroll() : relativeTo.getPosition(),
2203
- top = calc.y,
2204
- left = calc.x,
2205
- winSize = window.getSize();
2206
-
2207
- switch(options.position.x){
2208
- case 'left': position.x = left + offsetX; break;
2209
- case 'right': position.x = left + offsetX + relativeTo.offsetWidth; break;
2210
- default: position.x = left + ((relativeTo == document.body ? winSize.x : relativeTo.offsetWidth) / 2) + offsetX; break;
2211
- }
2212
-
2213
- switch(options.position.y){
2214
- case 'top': position.y = top + offsetY; break;
2215
- case 'bottom': position.y = top + offsetY + relativeTo.offsetHeight; break;
2216
- default: position.y = top + ((relativeTo == document.body ? winSize.y : relativeTo.offsetHeight) / 2) + offsetY; break;
2217
- }
2218
- },
2219
-
2220
- toMinMax: function(position, options){
2221
- var xy = {left: 'x', top: 'y'}, value;
2222
- ['minimum', 'maximum'].each(function(minmax){
2223
- ['left', 'top'].each(function(lr){
2224
- value = options[minmax] ? options[minmax][xy[lr]] : null;
2225
- if (value != null && ((minmax == 'minimum') ? position[lr] < value : position[lr] > value)) position[lr] = value;
2226
- });
2227
- });
2228
- },
2229
-
2230
- toRelFixedPosition: function(relativeTo, position){
2231
- var winScroll = window.getScroll();
2232
- position.top += winScroll.y;
2233
- position.left += winScroll.x;
2234
- },
2235
-
2236
- toIgnoreScroll: function(relativeTo, position){
2237
- var relScroll = relativeTo.getScroll();
2238
- position.top -= relScroll.y;
2239
- position.left -= relScroll.x;
2240
- },
2241
-
2242
- toIgnoreMargins: function(position, options){
2243
- position.left += options.edge.x == 'right'
2244
- ? options.dimensions['margin-right']
2245
- : (options.edge.x != 'center'
2246
- ? -options.dimensions['margin-left']
2247
- : -options.dimensions['margin-left'] + ((options.dimensions['margin-right'] + options.dimensions['margin-left']) / 2));
2248
-
2249
- position.top += options.edge.y == 'bottom'
2250
- ? options.dimensions['margin-bottom']
2251
- : (options.edge.y != 'center'
2252
- ? -options.dimensions['margin-top']
2253
- : -options.dimensions['margin-top'] + ((options.dimensions['margin-bottom'] + options.dimensions['margin-top']) / 2));
2254
- },
2255
-
2256
- toEdge: function(position, options){
2257
- var edgeOffset = {},
2258
- dimensions = options.dimensions,
2259
- edge = options.edge;
2260
-
2261
- switch(edge.x){
2262
- case 'left': edgeOffset.x = 0; break;
2263
- case 'right': edgeOffset.x = -dimensions.x - dimensions.computedRight - dimensions.computedLeft; break;
2264
- // center
2265
- default: edgeOffset.x = -(Math.round(dimensions.totalWidth / 2)); break;
2266
- }
2267
-
2268
- switch(edge.y){
2269
- case 'top': edgeOffset.y = 0; break;
2270
- case 'bottom': edgeOffset.y = -dimensions.y - dimensions.computedTop - dimensions.computedBottom; break;
2271
- // center
2272
- default: edgeOffset.y = -(Math.round(dimensions.totalHeight / 2)); break;
2273
- }
2274
-
2275
- position.x += edgeOffset.x;
2276
- position.y += edgeOffset.y;
2277
- },
2278
-
2279
- getCoordinateFromValue: function(option){
2280
- if (typeOf(option) != 'string') return option;
2281
- option = option.toLowerCase();
2282
-
2283
- return {
2284
- x: option.test('left') ? 'left'
2285
- : (option.test('right') ? 'right' : 'center'),
2286
- y: option.test(/upper|top/) ? 'top'
2287
- : (option.test('bottom') ? 'bottom' : 'center')
2288
- };
2289
- }
2290
-
2291
- };
2292
-
2293
- Element.implement({
2294
-
2295
- position: function(options){
2296
- if (options && (options.x != null || options.y != null)){
2297
- return (original ? original.apply(this, arguments) : this);
2298
- }
2299
- var position = this.setStyle('position', 'absolute').calculatePosition(options);
2300
- return (options && options.returnPos) ? position : this.setStyles(position);
2301
- },
2302
-
2303
- calculatePosition: function(options){
2304
- return local.getPosition(this, options);
2305
- }
2306
-
2307
- });
2308
-
2309
- })(Element.prototype.position);
2310
-
2311
-
2312
- /*
2313
- ---
2314
-
2315
- script: Class.Occlude.js
2316
-
2317
- name: Class.Occlude
2318
-
2319
- description: Prevents a class from being applied to a DOM element twice.
2320
-
2321
- license: MIT-style license.
2322
-
2323
- authors:
2324
- - Aaron Newton
2325
-
2326
- requires:
2327
- - Core/Class
2328
- - Core/Element
2329
- - MooTools.More
2330
-
2331
- provides: [Class.Occlude]
2332
-
2333
- ...
2334
- */
2335
-
2336
- Class.Occlude = new Class({
2337
-
2338
- occlude: function(property, element){
2339
- element = document.id(element || this.element);
2340
- var instance = element.retrieve(property || this.property);
2341
- if (instance && !this.occluded)
2342
- return (this.occluded = instance);
2343
-
2344
- this.occluded = false;
2345
- element.store(property || this.property, this);
2346
- return this.occluded;
2347
- }
2348
-
2349
- });
2350
-
2351
-
2352
- /*
2353
- ---
2354
-
2355
- script: IframeShim.js
2356
-
2357
- name: IframeShim
2358
-
2359
- description: Defines IframeShim, a class for obscuring select lists and flash objects in IE.
2360
-
2361
- license: MIT-style license
2362
-
2363
- authors:
2364
- - Aaron Newton
2365
-
2366
- requires:
2367
- - Core/Element.Event
2368
- - Core/Element.Style
2369
- - Core/Options
2370
- - Core/Events
2371
- - Element.Position
2372
- - Class.Occlude
2373
-
2374
- provides: [IframeShim]
2375
-
2376
- ...
2377
- */
2378
-
2379
- (function(){
2380
-
2381
- var browsers = false;
2382
-
2383
-
2384
- this.IframeShim = new Class({
2385
-
2386
- Implements: [Options, Events, Class.Occlude],
2387
-
2388
- options: {
2389
- className: 'iframeShim',
2390
- src: 'javascript:false;document.write("");',
2391
- display: false,
2392
- zIndex: null,
2393
- margin: 0,
2394
- offset: {x: 0, y: 0},
2395
- browsers: browsers
2396
- },
2397
-
2398
- property: 'IframeShim',
2399
-
2400
- initialize: function(element, options){
2401
- this.element = document.id(element);
2402
- if (this.occlude()) return this.occluded;
2403
- this.setOptions(options);
2404
- this.makeShim();
2405
- return this;
2406
- },
2407
-
2408
- makeShim: function(){
2409
- if (this.options.browsers){
2410
- var zIndex = this.element.getStyle('zIndex').toInt();
2411
-
2412
- if (!zIndex){
2413
- zIndex = 1;
2414
- var pos = this.element.getStyle('position');
2415
- if (pos == 'static' || !pos) this.element.setStyle('position', 'relative');
2416
- this.element.setStyle('zIndex', zIndex);
2417
- }
2418
- zIndex = ((this.options.zIndex != null || this.options.zIndex === 0) && zIndex > this.options.zIndex) ? this.options.zIndex : zIndex - 1;
2419
- if (zIndex < 0) zIndex = 1;
2420
- this.shim = new Element('iframe', {
2421
- src: this.options.src,
2422
- scrolling: 'no',
2423
- frameborder: 0,
2424
- styles: {
2425
- zIndex: zIndex,
2426
- position: 'absolute',
2427
- border: 'none',
2428
- filter: 'progid:DXImageTransform.Microsoft.Alpha(style=0,opacity=0)'
2429
- },
2430
- 'class': this.options.className
2431
- }).store('IframeShim', this);
2432
- var inject = (function(){
2433
- this.shim.inject(this.element, 'after');
2434
- this[this.options.display ? 'show' : 'hide']();
2435
- this.fireEvent('inject');
2436
- }).bind(this);
2437
- if (!IframeShim.ready) window.addEvent('load', inject);
2438
- else inject();
2439
- } else {
2440
- this.position = this.hide = this.show = this.dispose = Function.from(this);
2441
- }
2442
- },
2443
-
2444
- position: function(){
2445
- if (!IframeShim.ready || !this.shim) return this;
2446
- var size = this.element.measure(function(){
2447
- return this.getSize();
2448
- });
2449
- if (this.options.margin != undefined){
2450
- size.x = size.x - (this.options.margin * 2);
2451
- size.y = size.y - (this.options.margin * 2);
2452
- this.options.offset.x += this.options.margin;
2453
- this.options.offset.y += this.options.margin;
2454
- }
2455
- this.shim.set({width: size.x, height: size.y}).position({
2456
- relativeTo: this.element,
2457
- offset: this.options.offset
2458
- });
2459
- return this;
2460
- },
2461
-
2462
- hide: function(){
2463
- if (this.shim) this.shim.setStyle('display', 'none');
2464
- return this;
2465
- },
2466
-
2467
- show: function(){
2468
- if (this.shim) this.shim.setStyle('display', 'block');
2469
- return this.position();
2470
- },
2471
-
2472
- dispose: function(){
2473
- if (this.shim) this.shim.dispose();
2474
- return this;
2475
- },
2476
-
2477
- destroy: function(){
2478
- if (this.shim) this.shim.destroy();
2479
- return this;
2480
- }
2481
-
2482
- });
2483
-
2484
- })();
2485
-
2486
- window.addEvent('load', function(){
2487
- IframeShim.ready = true;
2488
- });
2489
-
2490
-
2491
- /*
2492
- ---
2493
-
2494
- name: Locale.de-DE.Date
2495
-
2496
- description: Date messages for German.
2497
-
2498
- license: MIT-style license
2499
-
2500
- authors:
2501
- - Christoph Pojer
2502
- - Frank Rossi
2503
- - Ulrich Petri
2504
- - Fabian Beiner
2505
-
2506
- requires:
2507
- - Locale
2508
-
2509
- provides: [Locale.de-DE.Date]
2510
-
2511
- ...
2512
- */
2513
-
2514
- Locale.define('de-DE', 'Date', {
2515
-
2516
- months: ['Januar', 'Februar', 'März', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember'],
2517
- months_abbr: ['Jan', 'Feb', 'Mär', 'Apr', 'Mai', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dez'],
2518
- days: ['Sonntag', 'Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag'],
2519
- days_abbr: ['So', 'Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa'],
2520
-
2521
- // Culture's date order: DD.MM.YYYY
2522
- dateOrder: ['date', 'month', 'year'],
2523
- shortDate: '%d.%m.%Y',
2524
- shortTime: '%H:%M',
2525
- AM: 'vormittags',
2526
- PM: 'nachmittags',
2527
- firstDayOfWeek: 1,
2528
-
2529
- // Date.Extras
2530
- ordinal: '.',
2531
-
2532
- lessThanMinuteAgo: 'vor weniger als einer Minute',
2533
- minuteAgo: 'vor einer Minute',
2534
- minutesAgo: 'vor {delta} Minuten',
2535
- hourAgo: 'vor einer Stunde',
2536
- hoursAgo: 'vor {delta} Stunden',
2537
- dayAgo: 'vor einem Tag',
2538
- daysAgo: 'vor {delta} Tagen',
2539
- weekAgo: 'vor einer Woche',
2540
- weeksAgo: 'vor {delta} Wochen',
2541
- monthAgo: 'vor einem Monat',
2542
- monthsAgo: 'vor {delta} Monaten',
2543
- yearAgo: 'vor einem Jahr',
2544
- yearsAgo: 'vor {delta} Jahren',
2545
-
2546
- lessThanMinuteUntil: 'in weniger als einer Minute',
2547
- minuteUntil: 'in einer Minute',
2548
- minutesUntil: 'in {delta} Minuten',
2549
- hourUntil: 'in ca. einer Stunde',
2550
- hoursUntil: 'in ca. {delta} Stunden',
2551
- dayUntil: 'in einem Tag',
2552
- daysUntil: 'in {delta} Tagen',
2553
- weekUntil: 'in einer Woche',
2554
- weeksUntil: 'in {delta} Wochen',
2555
- monthUntil: 'in einem Monat',
2556
- monthsUntil: 'in {delta} Monaten',
2557
- yearUntil: 'in einem Jahr',
2558
- yearsUntil: 'in {delta} Jahren'
2559
-
2560
- });
2561
-