sproutcore 1.6.0.1 → 1.7.1.beta

Sign up to get free protection for your applications and to get access to all the features.
Files changed (143) hide show
  1. data/CHANGELOG +21 -0
  2. data/Gemfile +5 -0
  3. data/Rakefile +26 -13
  4. data/VERSION.yml +2 -2
  5. data/lib/Buildfile +43 -4
  6. data/lib/buildtasks/build.rake +10 -0
  7. data/lib/buildtasks/helpers/file_rule.rb +22 -0
  8. data/lib/buildtasks/helpers/file_rule_list.rb +137 -0
  9. data/lib/buildtasks/manifest.rake +133 -122
  10. data/lib/frameworks/sproutcore/CHANGELOG.md +69 -2
  11. data/lib/frameworks/sproutcore/apps/tests/english.lproj/strings.js +1 -0
  12. data/lib/frameworks/sproutcore/frameworks/bootstrap/system/browser.js +28 -22
  13. data/lib/frameworks/sproutcore/frameworks/core_foundation/controllers/array.js +9 -5
  14. data/lib/frameworks/sproutcore/frameworks/core_foundation/controllers/controller.js +1 -1
  15. data/lib/frameworks/sproutcore/frameworks/core_foundation/controls/button.js +18 -13
  16. data/lib/frameworks/sproutcore/frameworks/core_foundation/ext/handlebars/bind.js +5 -3
  17. data/lib/frameworks/sproutcore/frameworks/core_foundation/ext/handlebars/collection.js +2 -0
  18. data/lib/frameworks/sproutcore/frameworks/core_foundation/mixins/action_support.js +80 -0
  19. data/lib/frameworks/sproutcore/frameworks/core_foundation/mixins/template_helpers/text_field_support.js +84 -116
  20. data/lib/frameworks/sproutcore/frameworks/core_foundation/panes/pane.js +8 -5
  21. data/lib/frameworks/sproutcore/frameworks/core_foundation/system/event.js +157 -157
  22. data/lib/frameworks/sproutcore/frameworks/core_foundation/system/platform.js +5 -3
  23. data/lib/frameworks/sproutcore/frameworks/core_foundation/system/root_responder.js +6 -6
  24. data/lib/frameworks/sproutcore/frameworks/core_foundation/system/sparse_array.js +10 -7
  25. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/mixins/action_support.js +106 -0
  26. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/template/collection.js +18 -0
  27. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/template/handlebars.js +71 -1
  28. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/attribute_bindings_test.js +38 -0
  29. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/class_name_bindings_test.js +47 -0
  30. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/layoutChildViews.js +18 -18
  31. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/layoutStyle.js +42 -10
  32. data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/keyboard.js +26 -1
  33. data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/layout_style.js +14 -8
  34. data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view.js +158 -1
  35. data/lib/frameworks/sproutcore/frameworks/datastore/models/record.js +15 -2
  36. data/lib/frameworks/sproutcore/frameworks/datastore/models/record_attribute.js +108 -108
  37. data/lib/frameworks/sproutcore/frameworks/datastore/system/query.js +1 -1
  38. data/lib/frameworks/sproutcore/frameworks/datastore/system/record_array.js +2 -4
  39. data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/record/error_methods.js +2 -2
  40. data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/single_attribute.js +26 -0
  41. data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/query/builders.js +7 -0
  42. data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/record_array/error_methods.js +1 -1
  43. data/lib/frameworks/sproutcore/frameworks/datetime/frameworks/core/system/datetime.js +4 -1
  44. data/lib/frameworks/sproutcore/frameworks/datetime/frameworks/core/tests/system/datetime.js +6 -0
  45. data/lib/frameworks/sproutcore/frameworks/desktop/panes/menu.js +26 -5
  46. data/lib/frameworks/sproutcore/frameworks/desktop/panes/picker.js +97 -96
  47. data/lib/frameworks/sproutcore/frameworks/desktop/system/drag.js +4 -3
  48. data/lib/frameworks/sproutcore/frameworks/desktop/tests/panes/menu/ui.js +17 -4
  49. data/lib/frameworks/sproutcore/frameworks/desktop/views/collection.js +7 -7
  50. data/lib/frameworks/sproutcore/frameworks/desktop/views/menu_item.js +7 -5
  51. data/lib/frameworks/sproutcore/frameworks/desktop/views/scroll.js +12 -3
  52. data/lib/frameworks/sproutcore/frameworks/desktop/views/web.js +23 -14
  53. data/lib/frameworks/sproutcore/frameworks/experimental/Buildfile +5 -1
  54. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/menu/render_delegates/menu_scroller.js +28 -0
  55. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/menu/tests/menu/scroll.js +235 -0
  56. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/menu/views/menu/scroll.js +363 -0
  57. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/menu/views/menu/scroller.js +250 -0
  58. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/render_delegates/desktop_scroller.js +92 -0
  59. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/render_delegates/native_scroll.js +25 -0
  60. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/render_delegates/scroll.js +33 -0
  61. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/render_delegates/touch_scroller.js +76 -0
  62. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/tests/scroll/integration.js +50 -0
  63. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/tests/scroll/methods.js +143 -0
  64. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/tests/scroll/ui.js +258 -0
  65. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/views/core_scroll.js +1164 -0
  66. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/views/core_scroller.js +332 -0
  67. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/views/desktop/scroll.js +236 -0
  68. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/views/desktop/scroller.js +347 -0
  69. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/views/scroll.js +15 -0
  70. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/views/scroller.js +10 -0
  71. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/views/touch/scroll.js +804 -0
  72. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/views/touch/scroller.js +133 -0
  73. data/lib/frameworks/sproutcore/frameworks/foundation/resources/text_field.css +3 -3
  74. data/lib/frameworks/sproutcore/frameworks/foundation/validators/number.js +3 -1
  75. data/lib/frameworks/sproutcore/frameworks/foundation/views/text_field.js +3 -3
  76. data/lib/frameworks/sproutcore/frameworks/media/views/audio.js +2 -1
  77. data/lib/frameworks/sproutcore/frameworks/media/views/controls.js +2 -1
  78. data/lib/frameworks/sproutcore/frameworks/media/views/media_slider.js +2 -4
  79. data/lib/frameworks/sproutcore/frameworks/media/views/mini_controls.js +2 -4
  80. data/lib/frameworks/sproutcore/frameworks/media/views/simple_controls.js +2 -4
  81. data/lib/frameworks/sproutcore/frameworks/media/views/video.js +2 -2
  82. data/lib/frameworks/sproutcore/frameworks/routing/system/routes.js +29 -3
  83. data/lib/frameworks/sproutcore/frameworks/runtime/core.js +2 -2
  84. data/lib/frameworks/sproutcore/frameworks/runtime/debug/test_suites/array/replace.js +1 -1
  85. data/lib/frameworks/sproutcore/frameworks/runtime/private/property_chain.js +2 -1
  86. data/lib/frameworks/sproutcore/frameworks/runtime/system/binding.js +3 -3
  87. data/lib/frameworks/sproutcore/frameworks/runtime/system/index_set.js +2 -2
  88. data/lib/frameworks/sproutcore/frameworks/runtime/system/object.js +1 -1
  89. data/lib/frameworks/sproutcore/themes/ace/resources/collection/normal/list_item.css +2 -2
  90. data/lib/frameworks/sproutcore/themes/legacy_theme/english.lproj/segmented.css +1 -1
  91. data/lib/gen/app/templates/apps/@target_name@/Buildfile +3 -5
  92. data/lib/gen/app/templates/apps/@target_name@/resources/_theme.css +18 -0
  93. data/lib/gen/project/templates/@filename@/Buildfile +2 -2
  94. data/lib/sproutcore/builders/chance_file.rb +9 -16
  95. data/lib/sproutcore/builders/html.rb +2 -1
  96. data/lib/sproutcore/builders/minify.rb +4 -35
  97. data/lib/sproutcore/builders/module.rb +38 -1
  98. data/lib/sproutcore/builders/split.rb +63 -0
  99. data/lib/sproutcore/builders/strings.rb +7 -1
  100. data/lib/sproutcore/builders.rb +1 -0
  101. data/lib/sproutcore/helpers/css_split.rb +190 -0
  102. data/lib/sproutcore/helpers/entry_sorter.rb +2 -0
  103. data/lib/sproutcore/helpers/minifier.rb +40 -16
  104. data/lib/sproutcore/helpers/static_helper.rb +35 -17
  105. data/lib/sproutcore/helpers.rb +1 -1
  106. data/lib/sproutcore/models/manifest.rb +26 -0
  107. data/lib/sproutcore/models/target.rb +12 -1
  108. data/lib/sproutcore/rack/proxy.rb +244 -225
  109. data/lib/sproutcore/rack/restrict_ip.rb +67 -0
  110. data/lib/sproutcore/rack/service.rb +8 -2
  111. data/lib/sproutcore/rack.rb +1 -0
  112. data/lib/sproutcore/tools/build.rb +91 -43
  113. data/lib/sproutcore/tools/gen.rb +2 -3
  114. data/lib/sproutcore/tools/manifest.rb +22 -16
  115. data/lib/sproutcore/tools/server.rb +21 -0
  116. data/lib/sproutcore/tools.rb +102 -46
  117. data/lib/sproutcore.rb +30 -5
  118. data/spec/buildtasks/helpers/accept_list +22 -0
  119. data/spec/buildtasks/helpers/accept_list.rb +128 -0
  120. data/spec/buildtasks/helpers/list.json +11 -0
  121. data/spec/buildtasks/manifest/prepare_build_tasks/chance_2x_spec.rb +1 -39
  122. data/spec/buildtasks/manifest/prepare_build_tasks/chance_spec.rb +0 -38
  123. data/spec/buildtasks/manifest/prepare_build_tasks/combine_spec.rb +4 -4
  124. data/spec/buildtasks/manifest/prepare_build_tasks/module_spec.rb +2 -2
  125. data/spec/buildtasks/manifest/prepare_build_tasks/packed_2x_indirect_spec.rb +7 -16
  126. data/spec/buildtasks/manifest/prepare_build_tasks/packed_2x_spec.rb +7 -17
  127. data/spec/buildtasks/manifest/prepare_build_tasks/packed_spec.rb +11 -6
  128. data/spec/fixtures/builder_tests/Buildfile +2 -1
  129. data/spec/fixtures/builder_tests/apps/module_test/modules/required_module/core.js +0 -0
  130. data/spec/lib/builders/module_spec.rb +1 -1
  131. data/spec/spec_helper.rb +1 -0
  132. data/sproutcore.gemspec +4 -9
  133. data/vendor/chance/lib/chance/factory.rb +45 -0
  134. data/vendor/chance/lib/chance/instance/data_url.rb +0 -29
  135. data/vendor/chance/lib/chance/instance/slicing.rb +57 -4
  136. data/vendor/chance/lib/chance/instance/spriting.rb +112 -21
  137. data/vendor/chance/lib/chance/instance.rb +173 -28
  138. data/vendor/chance/lib/chance/parser.rb +80 -52
  139. data/vendor/chance/lib/chance.rb +25 -6
  140. data/vendor/sproutcore/SCCompiler.jar +0 -0
  141. data/vendor/sproutcore/lib/args4j-2.0.12.jar +0 -0
  142. data/vendor/sproutcore/lib/yuicompressor-2.4.2.jar +0 -0
  143. metadata +97 -38
@@ -11,23 +11,23 @@ sc_require('system/core_query') ;
11
11
  The event class provides a simple cross-platform library for capturing and
12
12
  delivering events on DOM elements and other objects. While this library
13
13
  is based on code from both jQuery and Prototype.js, it includes a number of
14
- additional features including support for handler objects and event
14
+ additional features including support for handler objects and event
15
15
  delegation.
16
16
 
17
17
  Since native events are implemented very unevenly across browsers,
18
18
  SproutCore will convert all native events into a standardized instance of
19
- this special event class.
20
-
21
- SproutCore events implement the standard W3C event API as well as some
19
+ this special event class.
20
+
21
+ SproutCore events implement the standard W3C event API as well as some
22
22
  additional helper methods.
23
23
 
24
24
  @constructor
25
25
  @param {Event} originalEvent
26
26
  @returns {SC.Event} event instance
27
-
27
+
28
28
  @since SproutCore 1.0
29
29
  */
30
- SC.Event = function(originalEvent) {
30
+ SC.Event = function(originalEvent) {
31
31
  var idx, len;
32
32
  // copy properties from original event, if passed in.
33
33
  if (originalEvent) {
@@ -46,7 +46,7 @@ SC.Event = function(originalEvent) {
46
46
 
47
47
  // Fix target property, if necessary
48
48
  // Fixes #1925 where srcElement might not be defined either
49
- if (!this.target) this.target = this.srcElement || document;
49
+ if (!this.target) this.target = this.srcElement || document;
50
50
 
51
51
  // check if target is a textnode (safari)
52
52
  if (this.target.nodeType === 3 ) this.target = this.target.parentNode;
@@ -89,7 +89,7 @@ SC.Event = function(originalEvent) {
89
89
  this.wheelDeltaX = 0-(originalEvent.wheelDeltaX||0);
90
90
 
91
91
  // normalize wheelDelta for Firefox
92
- // note that we multiple the delta on FF to make it's acceleration more
92
+ // note that we multiple the delta on FF to make it's acceleration more
93
93
  // natural.
94
94
  } else if (!SC.none(originalEvent.detail) && SC.browser.mozilla) {
95
95
  if (originalEvent.axis && (originalEvent.axis === originalEvent.HORIZONTAL_AXIS)) {
@@ -120,7 +120,7 @@ SC.Event = function(originalEvent) {
120
120
  this.wheelDeltaY *= deltaMultiplier;
121
121
  }
122
122
 
123
- return this;
123
+ return this;
124
124
  } ;
125
125
 
126
126
  SC.mixin(SC.Event, /** @scope SC.Event */ {
@@ -180,67 +180,67 @@ SC.mixin(SC.Event, /** @scope SC.Event */ {
180
180
  */
181
181
  _MOUSE_WHEEL_LIMIT_INVALIDATED: NO,
182
182
 
183
- /**
183
+ /**
184
184
  Standard method to create a new event. Pass the native browser event you
185
185
  wish to wrap if needed.
186
186
  */
187
187
  create: function(e) { return new SC.Event(e); },
188
188
 
189
189
  // the code below was borrowed from jQuery, Dean Edwards, and Prototype.js
190
-
190
+
191
191
  /**
192
192
  Bind an event to an element.
193
193
 
194
194
  This method will cause the passed handler to be executed whenever a
195
195
  relevant event occurs on the named element. This method supports a
196
196
  variety of handler types, depending on the kind of support you need.
197
-
197
+
198
198
  ## Simple Function Handlers
199
199
 
200
200
  SC.Event.add(anElement, "click", myClickHandler) ;
201
-
201
+
202
202
  The most basic type of handler you can pass is a function. This function
203
203
  will be executed everytime an event of the type you specify occurs on the
204
204
  named element. You can optionally pass an additional context object which
205
205
  will be included on the event in the event.data property.
206
-
206
+
207
207
  When your handler function is called the, the function's "this" property
208
208
  will point to the element the event occurred on.
209
-
209
+
210
210
  The click handler for this method must have a method signature like:
211
-
211
+
212
212
  function(event) { return YES|NO; }
213
-
213
+
214
214
  ## Method Invocations
215
215
 
216
216
  SC.Event.add(anElement, "click", myObject, myObject.aMethod) ;
217
217
 
218
- Optionally you can specify a target object and a method on the object to
218
+ Optionally you can specify a target object and a method on the object to
219
219
  be invoked when the event occurs. This will invoke the method function
220
- with the target object you pass as "this". The method should have a
220
+ with the target object you pass as "this". The method should have a
221
221
  signature like:
222
-
222
+
223
223
  function(event, targetElement) { return YES|NO; }
224
224
 
225
225
  Like function handlers, you can pass an additional context data paramater
226
226
  that will be included on the event in the event.data property.
227
-
227
+
228
228
  ## Handler Return Values
229
229
 
230
- Both handler functions should return YES if you want the event to
230
+ Both handler functions should return YES if you want the event to
231
231
  continue to propagate and NO if you want it to stop. Returning NO will
232
- both stop bubbling of the event and will prevent any default action
232
+ both stop bubbling of the event and will prevent any default action
233
233
  taken by the browser. You can also control these two behaviors separately
234
234
  by calling the stopPropagation() or preventDefault() methods on the event
235
235
  itself, returning YES from your method.
236
-
236
+
237
237
  ## Limitations
238
-
239
- Although SproutCore's event implementation is based on jQuery, it is
238
+
239
+ Although SproutCore's event implementation is based on jQuery, it is
240
240
  much simpler in design. Notably, it does not support namespaced events
241
241
  and you can only pass a single type at a time.
242
-
243
- If you need more advanced event handling, consider the SC.ClassicResponder
242
+
243
+ If you need more advanced event handling, consider the SC.ClassicResponder
244
244
  functionality provided by SproutCore or use your favorite DOM library.
245
245
 
246
246
  @param {Element} elem a DOM element, window, or document object
@@ -252,11 +252,11 @@ SC.mixin(SC.Event, /** @scope SC.Event */ {
252
252
  */
253
253
  add: function(elem, eventType, target, method, context, useCapture) {
254
254
 
255
- // if a CQ object is passed in, either call add on each item in the
255
+ // if a CQ object is passed in, either call add on each item in the
256
256
  // matched set, or simply get the first element and use that.
257
257
  if (elem && elem.isCoreQuery) {
258
258
  if (elem.length > 0) {
259
- elem.forEach(function(e) {
259
+ elem.forEach(function(e) {
260
260
  this.add(e, eventType, target, method, context);
261
261
  }, this);
262
262
  return this;
@@ -267,7 +267,7 @@ SC.mixin(SC.Event, /** @scope SC.Event */ {
267
267
  if (!useCapture) {
268
268
  useCapture = NO;
269
269
  }
270
-
270
+
271
271
  // cannot register events on text nodes, etc.
272
272
  if ( elem.nodeType === 3 || elem.nodeType === 8 ) return SC.Event;
273
273
 
@@ -278,7 +278,7 @@ SC.mixin(SC.Event, /** @scope SC.Event */ {
278
278
  // if target is a function, treat it as the method, with optional context
279
279
  if (SC.typeOf(target) === SC.T_FUNCTION) {
280
280
  context = method; method = target; target = null;
281
-
281
+
282
282
  // handle case where passed method is a key on the target.
283
283
  } else if (target && SC.typeOf(method) === SC.T_STRING) {
284
284
  method = target[method] ;
@@ -288,12 +288,12 @@ SC.mixin(SC.Event, /** @scope SC.Event */ {
288
288
  // not exist yet, create it and also setup the shared listener for this
289
289
  // eventType.
290
290
  var events = SC.data(elem, "sc_events") || SC.data(elem, "sc_events", {}) ,
291
- handlers = events[eventType];
291
+ handlers = events[eventType];
292
292
  if (!handlers) {
293
293
  handlers = events[eventType] = {} ;
294
294
  this._addEventListener(elem, eventType, useCapture) ;
295
295
  }
296
-
296
+
297
297
  // Build the handler array and add to queue
298
298
  handlers[SC.hashFor(target, method)] = [target, method, context];
299
299
  SC.Event._global[eventType] = YES ; // optimization for global triggers
@@ -309,21 +309,21 @@ SC.mixin(SC.Event, /** @scope SC.Event */ {
309
309
  To remove a specific handler, you must pass in the same function or the
310
310
  same target and method as you passed into SC.Event.add(). See that method
311
311
  for full documentation on the parameters you can pass in.
312
-
312
+
313
313
  If you omit a specific handler but provide both an element and eventType,
314
314
  then all handlers for that element will be removed. If you provide only
315
315
  and element, then all handlers for all events on that element will be
316
316
  removed.
317
-
317
+
318
318
  ## Limitations
319
-
320
- Although SproutCore's event implementation is based on jQuery, it is
319
+
320
+ Although SproutCore's event implementation is based on jQuery, it is
321
321
  much simpler in design. Notably, it does not support namespaced events
322
322
  and you can only pass a single type at a time.
323
-
324
- If you need more advanced event handling, consider the SC.ClassicResponder
323
+
324
+ If you need more advanced event handling, consider the SC.ClassicResponder
325
325
  functionality provided by SproutCore or use your favorite DOM library.
326
-
326
+
327
327
  @param {Element} elem a DOM element, window, or document object
328
328
  @param {String} eventType the event type to remove
329
329
  @param {Object} target The target object for a method call. Or a function.
@@ -332,18 +332,18 @@ SC.mixin(SC.Event, /** @scope SC.Event */ {
332
332
  */
333
333
  remove: function(elem, eventType, target, method) {
334
334
 
335
- // if a CQ object is passed in, either call add on each item in the
335
+ // if a CQ object is passed in, either call add on each item in the
336
336
  // matched set, or simply get the first element and use that.
337
337
  if (elem && elem.isCoreQuery) {
338
338
  if (elem.length > 0) {
339
- elem.forEach(function(e) {
339
+ elem.forEach(function(e) {
340
340
  this.remove(e, eventType, target, method);
341
341
  }, this);
342
342
  return this;
343
343
  } else elem = elem[0];
344
344
  }
345
345
  if (!elem) return this; // nothing to do
346
-
346
+
347
347
  // don't do events on text and comment nodes
348
348
  if ( elem.nodeType === 3 || elem.nodeType === 8 ) return SC.Event;
349
349
 
@@ -362,19 +362,19 @@ SC.mixin(SC.Event, /** @scope SC.Event */ {
362
362
  } else if (handlers = events[eventType]) {
363
363
 
364
364
  var cleanupHandlers = NO ;
365
-
365
+
366
366
  // if a target/method is provided, remove only that one
367
367
  if (target || method) {
368
-
368
+
369
369
  // normalize the target/method
370
370
  if (SC.typeOf(target) === SC.T_FUNCTION) {
371
371
  method = target; target = null ;
372
372
  } else if (SC.typeOf(method) === SC.T_STRING) {
373
373
  method = target[method] ;
374
374
  }
375
-
375
+
376
376
  delete handlers[SC.hashFor(target, method)];
377
-
377
+
378
378
  // check to see if there are handlers left on this event/eventType.
379
379
  // if not, then cleanup the handlers.
380
380
  key = null ;
@@ -383,15 +383,15 @@ SC.mixin(SC.Event, /** @scope SC.Event */ {
383
383
 
384
384
  // otherwise, just cleanup all handlers
385
385
  } else cleanupHandlers = YES ;
386
-
387
- // If there are no more handlers left on this event type, remove
386
+
387
+ // If there are no more handlers left on this event type, remove
388
388
  // eventType hash from queue.
389
389
  if (cleanupHandlers) {
390
390
  delete events[eventType] ;
391
391
  this._removeEventListener(elem, eventType) ;
392
392
  }
393
-
394
- // verify that there are still events registered on this element. If
393
+
394
+ // verify that there are still events registered on this element. If
395
395
  // there aren't, cleanup the element completely to avoid memory leaks.
396
396
  key = null ;
397
397
  for(key in events) break;
@@ -399,20 +399,20 @@ SC.mixin(SC.Event, /** @scope SC.Event */ {
399
399
  SC.removeData(elem, "sc_events") ;
400
400
  delete this._elements[SC.guidFor(elem)]; // important to avoid leaks
401
401
  }
402
-
402
+
403
403
  }
404
-
404
+
405
405
  elem = events = handlers = null ; // avoid memory leaks
406
406
  return this ;
407
407
  },
408
408
 
409
409
  NO_BUBBLE: ['blur', 'focus', 'change'],
410
-
410
+
411
411
  /**
412
- Generates a simulated event object. This is mostly useful for unit
413
- testing. You can pass the return value of this property into the
412
+ Generates a simulated event object. This is mostly useful for unit
413
+ testing. You can pass the return value of this property into the
414
414
  trigger() method to actually send the event.
415
-
415
+
416
416
  @param {Element} elem the element the event targets
417
417
  @param {String} eventType event type. mousedown, mouseup, etc
418
418
  @param {Hash} attrs optional additonal attributes to apply to event.
@@ -433,24 +433,24 @@ SC.mixin(SC.Event, /** @scope SC.Event */ {
433
433
  if (attrs) SC.mixin(ret, attrs) ;
434
434
  return ret ;
435
435
  },
436
-
436
+
437
437
  /**
438
- Trigger an event execution immediately. You can use this method to
438
+ Trigger an event execution immediately. You can use this method to
439
439
  simulate arbitrary events on arbitary elements.
440
440
 
441
441
  ## Limitations
442
-
443
- Note that although this is based on the jQuery implementation, it is
442
+
443
+ Note that although this is based on the jQuery implementation, it is
444
444
  much simpler. Notably namespaced events are not supported and you cannot
445
445
  trigger events globally.
446
-
447
- If you need more advanced event handling, consider the SC.Responder
446
+
447
+ If you need more advanced event handling, consider the SC.Responder
448
448
  functionality provided by SproutCore or use your favorite DOM library.
449
449
 
450
450
  ## Example
451
-
451
+
452
452
  SC.Event.trigger(view.get('layer'), 'mousedown');
453
-
453
+
454
454
  @param elem {Element} the target element
455
455
  @param eventType {String} the event type
456
456
  @param args {Array} optional argument or arguments to pass to handler.
@@ -459,11 +459,11 @@ SC.mixin(SC.Event, /** @scope SC.Event */ {
459
459
  */
460
460
  trigger: function(elem, eventType, args, donative) {
461
461
 
462
- // if a CQ object is passed in, either call add on each item in the
462
+ // if a CQ object is passed in, either call add on each item in the
463
463
  // matched set, or simply get the first element and use that.
464
464
  if (elem && elem.isCoreQuery) {
465
465
  if (elem.length > 0) {
466
- elem.forEach(function(e) {
466
+ elem.forEach(function(e) {
467
467
  this.trigger(e, eventType, args, donative);
468
468
  }, this);
469
469
  return this;
@@ -473,11 +473,11 @@ SC.mixin(SC.Event, /** @scope SC.Event */ {
473
473
 
474
474
  // don't do events on text and comment nodes
475
475
  if ( elem.nodeType === 3 || elem.nodeType === 8 ) return undefined;
476
-
476
+
477
477
  // Normalize to an array
478
478
  args = SC.A(args) ;
479
479
 
480
- var ret, fn = SC.typeOf(elem[eventType] || null) === SC.T_FUNCTION ,
480
+ var ret, fn = SC.typeOf(elem[eventType] || null) === SC.T_FUNCTION ,
481
481
  event, current, onfoo, isClick;
482
482
 
483
483
  // Get the event to pass, creating a fake one if necessary
@@ -486,15 +486,15 @@ SC.mixin(SC.Event, /** @scope SC.Event */ {
486
486
  event = this.simulateEvent(elem, eventType) ;
487
487
  args.unshift(event) ;
488
488
  }
489
-
489
+
490
490
  event.type = eventType ;
491
-
491
+
492
492
  // Trigger the event - bubble if enabled
493
493
  current = elem;
494
494
  do {
495
495
  ret = SC.Event.handle.apply(current, args);
496
496
  current = (current===document) ? null : (current.parentNode || document);
497
- } while(!ret && event.bubbles && current);
497
+ } while(!ret && event.bubbles && current);
498
498
  current = null ;
499
499
 
500
500
  // Handle triggering native .onfoo handlers
@@ -510,7 +510,7 @@ SC.mixin(SC.Event, /** @scope SC.Event */ {
510
510
  // prevent IE from throwing an error for some hidden elements
511
511
  } catch (e) {}
512
512
  }
513
-
513
+
514
514
  this.triggered = NO;
515
515
 
516
516
  return ret;
@@ -518,16 +518,16 @@ SC.mixin(SC.Event, /** @scope SC.Event */ {
518
518
 
519
519
  /**
520
520
  This method will handle the passed event, finding any registered listeners
521
- and executing them. If you have an event you want handled, you can
521
+ and executing them. If you have an event you want handled, you can
522
522
  manually invoke this method. This function expects it's "this" value to
523
- be the element the event occurred on, so you should always call this
523
+ be the element the event occurred on, so you should always call this
524
524
  method like:
525
-
525
+
526
526
  SC.Event.handle.call(element, event) ;
527
527
 
528
528
  Note that like other parts of this library, the handle function does not
529
529
  support namespaces.
530
-
530
+
531
531
  @param event {Event} the event to handle
532
532
  @returns {Boolean}
533
533
  */
@@ -536,7 +536,7 @@ SC.mixin(SC.Event, /** @scope SC.Event */ {
536
536
  // ignore events triggered after window is unloaded or if double-called
537
537
  // from within a trigger.
538
538
  if ((typeof SC === "undefined") || SC.Event.triggered) return YES ;
539
-
539
+
540
540
  // returned undefined or NO
541
541
  var val, ret, namespace, all, handlers, args, key, handler, method, target;
542
542
 
@@ -548,7 +548,7 @@ SC.mixin(SC.Event, /** @scope SC.Event */ {
548
548
  // get the handlers for this event type
549
549
  handlers = (SC.data(this, "sc_events") || {})[event.type];
550
550
  if (!handlers) return NO ; // nothing to do
551
-
551
+
552
552
  // invoke all handlers
553
553
  for (key in handlers ) {
554
554
  handler = handlers[key];
@@ -562,11 +562,11 @@ SC.mixin(SC.Event, /** @scope SC.Event */ {
562
562
 
563
563
  target = handler[0] || this;
564
564
  ret = method.apply( target, args );
565
-
565
+
566
566
  if (val !== NO) val = ret;
567
567
 
568
568
  // if method returned NO, do not continue. Stop propogation and
569
- // return default. Note that we test explicitly for NO since
569
+ // return default. Note that we test explicitly for NO since
570
570
  // if the handler returns no specific value, we do not want to stop.
571
571
  if ( ret === NO ) {
572
572
  event.preventDefault();
@@ -578,29 +578,29 @@ SC.mixin(SC.Event, /** @scope SC.Event */ {
578
578
  },
579
579
 
580
580
  /**
581
- This method is called just before the window unloads to unhook all
581
+ This method is called just before the window unloads to unhook all
582
582
  registered events.
583
583
  */
584
584
  unload: function() {
585
585
  var key, elements = this._elements ;
586
586
  for(key in elements) this.remove(elements[key]) ;
587
-
587
+
588
588
  // just in case some book-keeping was screwed up. avoid memory leaks
589
589
  for(key in elements) delete elements[key] ;
590
- delete this._elements ;
590
+ delete this._elements ;
591
591
  },
592
-
592
+
593
593
  /**
594
594
  This hash contains handlers for special or custom events. You can add
595
595
  your own handlers for custom events here by simply naming the event and
596
596
  including a hash with the following properties:
597
-
597
+
598
598
  - setup: this function should setup the handler or return NO
599
599
  - teardown: this function should remove the event listener
600
-
600
+
601
601
  */
602
602
  special: {
603
-
603
+
604
604
  ready: {
605
605
  setup: function() {
606
606
  // Make sure the ready event is setup
@@ -675,11 +675,11 @@ SC.mixin(SC.Event, /** @scope SC.Event */ {
675
675
  KEY_PAGEUP: 33,
676
676
  KEY_PAGEDOWN: 34,
677
677
  KEY_INSERT: 45,
678
-
678
+
679
679
  _withinElement: function(event, elem) {
680
680
  // Check if mouse(over|out) are still within the same parent element
681
681
  var parent = event.relatedTarget;
682
-
682
+
683
683
  // Traverse up the tree
684
684
  while ( parent && parent != elem ) {
685
685
  try { parent = parent.parentNode; } catch(error) { parent = elem; }
@@ -688,14 +688,14 @@ SC.mixin(SC.Event, /** @scope SC.Event */ {
688
688
  // Return YES if we actually just moused on to a sub-element
689
689
  return parent === elem;
690
690
  },
691
-
691
+
692
692
  /** @private
693
693
  Adds the primary event listener for the named type on the element.
694
-
695
- If the event type has a special handler defined in SC.Event.special,
694
+
695
+ If the event type has a special handler defined in SC.Event.special,
696
696
  then that handler will be used. Otherwise the normal browser method will
697
697
  be used.
698
-
698
+
699
699
  @param elem {Element} the target element
700
700
  @param eventType {String} the event type
701
701
  */
@@ -710,17 +710,17 @@ SC.mixin(SC.Event, /** @scope SC.Event */ {
710
710
  // Only use addEventListener/attachEvent if the special
711
711
  // events handler returns NO
712
712
  if ( !special || special.setup.call(elem)===NO) {
713
-
714
- // Save element in cache. This must be removed later to avoid
713
+
714
+ // Save element in cache. This must be removed later to avoid
715
715
  // memory leaks.
716
716
  var guid = SC.guidFor(elem) ;
717
717
  this._elements[guid] = elem;
718
-
719
- listener = SC.data(elem, "listener") || SC.data(elem, "listener",
718
+
719
+ listener = SC.data(elem, "listener") || SC.data(elem, "listener",
720
720
  function() {
721
- return SC.Event.handle.apply(SC.Event._elements[guid], arguments);
721
+ return SC.Event.handle.apply(SC.Event._elements[guid], arguments);
722
722
  }) ;
723
-
723
+
724
724
  // Bind the global event handler to the element
725
725
  if (elem.addEventListener) {
726
726
  elem.addEventListener(eventType, listener, useCapture);
@@ -729,25 +729,25 @@ SC.mixin(SC.Event, /** @scope SC.Event */ {
729
729
  // there is currently a hack in request , but it needs to fixed here.
730
730
  elem.attachEvent("on" + eventType, listener);
731
731
  }
732
- //
732
+ //
733
733
  // else {
734
734
  // elem.onreadystatechange = listener;
735
735
  // }
736
736
  }
737
-
737
+
738
738
  elem = special = listener = null ; // avoid memory leak
739
739
  },
740
740
 
741
741
  /** @private
742
742
  Removes the primary event listener for the named type on the element.
743
-
744
- If the event type has a special handler defined in SC.Event.special,
743
+
744
+ If the event type has a special handler defined in SC.Event.special,
745
745
  then that handler will be used. Otherwise the normal browser method will
746
746
  be used.
747
-
747
+
748
748
  Note that this will not clear the _elements hash from the element. You
749
749
  must call SC.Event.unload() on unload to make sure that is cleared.
750
-
750
+
751
751
  @param elem {Element} the target element
752
752
  @param eventType {String} the event type
753
753
  */
@@ -763,66 +763,66 @@ SC.mixin(SC.Event, /** @scope SC.Event */ {
763
763
  }
764
764
  }
765
765
  }
766
-
766
+
767
767
  elem = special = listener = null ;
768
768
  },
769
769
 
770
770
  _elements: {},
771
-
771
+
772
772
  // implement preventDefault() in a cross platform way
773
-
773
+
774
774
  /** @private Take an incoming event and convert it to a normalized event. */
775
775
  normalizeEvent: function(event) {
776
776
  if (event === window.event) {
777
777
  // IE can't do event.normalized on an Event object
778
- return SC.Event.create(event) ;
778
+ return SC.Event.create(event) ;
779
779
  } else {
780
780
  return event.normalized ? event : SC.Event.create(event) ;
781
781
  }
782
782
  },
783
-
783
+
784
784
  _global: {},
785
785
 
786
786
  /** @private properties to copy from native event onto the event */
787
787
  _props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target timeStamp toElement type view which touches targetTouches changedTouches animationName elapsedTime dataTransfer".split(" ")
788
-
788
+
789
789
  }) ;
790
790
 
791
791
  SC.Event.prototype = {
792
792
 
793
793
  /**
794
- Set to YES if you have called either preventDefault() or stopPropagation().
795
- This allows a generic event handler to notice if you want to provide
794
+ Set to YES if you have called either preventDefault() or stopPropagation().
795
+ This allows a generic event handler to notice if you want to provide
796
796
  detailed control over how the browser handles the real event.
797
-
797
+
798
798
  @property {Boolean}
799
799
  */
800
800
  hasCustomEventHandling: NO,
801
-
801
+
802
802
  /**
803
803
  Returns the touches owned by the supplied view.
804
-
804
+
805
805
  @param {SC.View}
806
806
  @returns {Array} touches an array of SC.Touch objects
807
807
  */
808
808
  touchesForView: function(view) {
809
809
  if (this.touchContext) return this.touchContext.touchesForView(view);
810
810
  },
811
-
811
+
812
812
  /**
813
813
  Same as touchesForView, but sounds better for responders.
814
-
814
+
815
815
  @param {SC.RootResponder}
816
816
  @returns {Array} touches an array of SC.Touch objects
817
817
  */
818
818
  touchesForResponder: function(responder) {
819
819
  if (this.touchContext) return this.touchContext.touchesForView(responder);
820
820
  },
821
-
821
+
822
822
  /**
823
- Returns average data--x, y, and d (distance)--for the touches owned by the
823
+ Returns average data--x, y, and d (distance)--for the touches owned by the
824
824
  supplied view.
825
-
825
+
826
826
  @param {SC.View}
827
827
  @returns {Array} touches an array of SC.Touch objects
828
828
  */
@@ -830,22 +830,22 @@ SC.Event.prototype = {
830
830
  if (this.touchContext) return this.touchContext.averagedTouchesForView(view);
831
831
  return null;
832
832
  },
833
-
833
+
834
834
  /**
835
835
  Indicates that you want to allow the normal default behavior. Sets
836
836
  the hasCustomEventHandling property to YES but does not cancel the event.
837
-
837
+
838
838
  @returns {SC.Event} receiver
839
839
  */
840
840
  allowDefault: function() {
841
841
  this.hasCustomEventHandling = YES ;
842
- return this ;
842
+ return this ;
843
843
  },
844
-
845
- /**
844
+
845
+ /**
846
846
  Implements W3C standard. Will prevent the browser from performing its
847
847
  default action on this event.
848
-
848
+
849
849
  @returns {SC.Event} receiver
850
850
  */
851
851
  preventDefault: function() {
@@ -860,7 +860,7 @@ SC.Event.prototype = {
860
860
 
861
861
  /**
862
862
  Implements W3C standard. Prevents further bubbling of the event.
863
-
863
+
864
864
  @returns {SC.Event} receiver
865
865
  */
866
866
  stopPropagation: function() {
@@ -869,30 +869,30 @@ SC.Event.prototype = {
869
869
  if (evt.stopPropagation) evt.stopPropagation() ;
870
870
  evt.cancelBubble = YES ; // IE
871
871
  }
872
- this.hasCustomEventHandling = YES ;
872
+ this.hasCustomEventHandling = YES ;
873
873
  return this ;
874
874
  },
875
875
 
876
- /**
877
- Stops both the default action and further propogation. This is more
876
+ /**
877
+ Stops both the default action and further propogation. This is more
878
878
  convenient than calling both.
879
-
879
+
880
880
  @returns {SC.Event} receiver
881
881
  */
882
882
  stop: function() {
883
883
  return this.preventDefault().stopPropagation();
884
884
  },
885
-
886
- /**
887
- Always YES to indicate the event was normalized.
888
-
885
+
886
+ /**
887
+ Always YES to indicate the event was normalized.
888
+
889
889
  @property {Boolean}
890
890
  */
891
891
  normalized: YES,
892
892
 
893
- /**
894
- Returns the pressed character (found in this.which) as a string.
895
-
893
+ /**
894
+ Returns the pressed character (found in this.which) as a string.
895
+
896
896
  @returns {String}
897
897
  */
898
898
  getCharString: function() {
@@ -901,31 +901,31 @@ SC.Event.prototype = {
901
901
  return String.fromCharCode(0);
902
902
  }
903
903
  else {
904
- return (this.keyCode>0) ? String.fromCharCode(this.keyCode) : null;
904
+ return (this.keyCode>0) ? String.fromCharCode(this.keyCode) : null;
905
905
  }
906
906
  }
907
907
  else {
908
908
  return (this.charCode>0) ? String.fromCharCode(this.charCode) : null;
909
909
  }
910
910
  },
911
-
912
- /**
913
- Returns character codes for the event. The first value is the normalized
914
- code string, with any shift or ctrl characters added to the begining.
911
+
912
+ /**
913
+ Returns character codes for the event. The first value is the normalized
914
+ code string, with any shift or ctrl characters added to the begining.
915
915
  The second value is the char string by itself.
916
-
916
+
917
917
  @returns {Array}
918
918
  */
919
919
  commandCodes: function() {
920
920
  var code=this.keyCode, ret=null, key=null, modifiers='', lowercase ;
921
-
921
+
922
922
  // handle function keys.
923
923
  if (code) {
924
924
  ret = SC.FUNCTION_KEYS[code] ;
925
925
  if (!ret && (this.altKey || this.ctrlKey || this.metaKey)) {
926
926
  ret = SC.PRINTABLE_KEYS[code];
927
927
  }
928
-
928
+
929
929
  if (ret) {
930
930
  if (this.altKey) modifiers += 'alt_' ;
931
931
  if (this.ctrlKey || this.metaKey) modifiers += 'ctrl_' ;
@@ -941,14 +941,14 @@ SC.Event.prototype = {
941
941
  if (this.metaKey) {
942
942
  modifiers = 'meta_' ;
943
943
  ret = lowercase;
944
-
944
+
945
945
  } else ret = null ;
946
946
  }
947
947
 
948
948
  if (ret) ret = modifiers + ret ;
949
949
  return [ret, key] ;
950
950
  }
951
-
951
+
952
952
  } ;
953
953
 
954
954
  // Also provide a Prototype-like API so that people can use either one.
@@ -963,7 +963,7 @@ SC.Event.stopObserving = SC.Event.remove ;
963
963
  SC.Event.fire = SC.Event.trigger;
964
964
 
965
965
  // Register unload handler to eliminate any registered handlers
966
- // This avoids leaks in IE and issues with mouseout or other handlers on
966
+ // This avoids leaks in IE and issues with mouseout or other handlers on
967
967
  // other browsers.
968
968
 
969
969
  if(SC.browser.msie) SC.Event.add(window, 'unload', SC.Event.prototype, SC.Event.unload) ;
@@ -973,11 +973,11 @@ SC.MODIFIER_KEYS = {
973
973
  };
974
974
 
975
975
  SC.FUNCTION_KEYS = {
976
- 8: 'backspace', 9: 'tab', 13: 'return', 19: 'pause', 27: 'escape',
977
- 33: 'pageup', 34: 'pagedown', 35: 'end', 36: 'home',
978
- 37: 'left', 38: 'up', 39: 'right', 40: 'down', 44: 'printscreen',
979
- 45: 'insert', 46: 'delete', 112: 'f1', 113: 'f2', 114: 'f3', 115: 'f4',
980
- 116: 'f5', 117: 'f7', 119: 'f8', 120: 'f9', 121: 'f10', 122: 'f11',
976
+ 8: 'backspace', 9: 'tab', 13: 'return', 19: 'pause', 27: 'escape',
977
+ 33: 'pageup', 34: 'pagedown', 35: 'end', 36: 'home',
978
+ 37: 'left', 38: 'up', 39: 'right', 40: 'down', 44: 'printscreen',
979
+ 45: 'insert', 46: 'delete', 112: 'f1', 113: 'f2', 114: 'f3', 115: 'f4',
980
+ 116: 'f5', 117: 'f7', 119: 'f8', 120: 'f9', 121: 'f10', 122: 'f11',
981
981
  123: 'f12', 144: 'numlock', 145: 'scrolllock'
982
982
  } ;
983
983