sproutcore 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (270) hide show
  1. data/History.txt +4 -0
  2. data/License.txt +20 -0
  3. data/Manifest.txt +269 -0
  4. data/README.txt +67 -0
  5. data/Rakefile +4 -0
  6. data/app_generators/sproutcore/USAGE +5 -0
  7. data/app_generators/sproutcore/sproutcore_generator.rb +66 -0
  8. data/app_generators/sproutcore/templates/README +77 -0
  9. data/app_generators/sproutcore/templates/environment.yml +4 -0
  10. data/bin/sc-build +145 -0
  11. data/bin/sc-gen +24 -0
  12. data/bin/sc-server +63 -0
  13. data/bin/sproutcore +21 -0
  14. data/clients/sc_docs/controllers/docs.js +118 -0
  15. data/clients/sc_docs/core.js +19 -0
  16. data/clients/sc_docs/english.lproj/body.css +159 -0
  17. data/clients/sc_docs/english.lproj/body.rhtml +33 -0
  18. data/clients/sc_docs/english.lproj/controls.css +0 -0
  19. data/clients/sc_docs/english.lproj/icons/small/next.png +0 -0
  20. data/clients/sc_docs/english.lproj/icons/small/reset.png +0 -0
  21. data/clients/sc_docs/english.lproj/images/gradients.png +0 -0
  22. data/clients/sc_docs/english.lproj/images/indicator.gif +0 -0
  23. data/clients/sc_docs/english.lproj/images/toolbar.png +0 -0
  24. data/clients/sc_docs/english.lproj/no_docs.rhtml +7 -0
  25. data/clients/sc_docs/english.lproj/strings.js +14 -0
  26. data/clients/sc_docs/english.lproj/warning.rhtml +6 -0
  27. data/clients/sc_docs/fixtures/doc.js +11 -0
  28. data/clients/sc_docs/main.js +21 -0
  29. data/clients/sc_docs/models/doc.js +9 -0
  30. data/clients/sc_docs/tests/controllers/docs.rhtml +21 -0
  31. data/clients/sc_docs/tests/models/doc.rhtml +21 -0
  32. data/clients/sc_docs/tests/views/doc_frame.rhtml +21 -0
  33. data/clients/sc_docs/tests/views/doc_label_view.rhtml +21 -0
  34. data/clients/sc_docs/views/doc_frame.js +33 -0
  35. data/clients/sc_docs/views/doc_label.js +20 -0
  36. data/clients/sc_test_runner/controllers/runner.js +175 -0
  37. data/clients/sc_test_runner/core.js +19 -0
  38. data/clients/sc_test_runner/english.lproj/body.css +151 -0
  39. data/clients/sc_test_runner/english.lproj/body.rhtml +35 -0
  40. data/clients/sc_test_runner/english.lproj/controls.css +0 -0
  41. data/clients/sc_test_runner/english.lproj/icons/small/next.png +0 -0
  42. data/clients/sc_test_runner/english.lproj/icons/small/reset.png +0 -0
  43. data/clients/sc_test_runner/english.lproj/images/gradients.png +0 -0
  44. data/clients/sc_test_runner/english.lproj/images/indicator.gif +0 -0
  45. data/clients/sc_test_runner/english.lproj/images/toolbar.png +0 -0
  46. data/clients/sc_test_runner/english.lproj/no_tests.rhtml +6 -0
  47. data/clients/sc_test_runner/english.lproj/strings.js +14 -0
  48. data/clients/sc_test_runner/english.lproj/warning.rhtml +6 -0
  49. data/clients/sc_test_runner/fixtures/test.js +12 -0
  50. data/clients/sc_test_runner/main.js +26 -0
  51. data/clients/sc_test_runner/models/test.js +11 -0
  52. data/clients/sc_test_runner/views/runner_frame.js +72 -0
  53. data/clients/sc_test_runner/views/test_label.js +20 -0
  54. data/config/hoe.rb +70 -0
  55. data/config/requirements.rb +17 -0
  56. data/environment.yml +9 -0
  57. data/frameworks/prototype/prototype.js +4186 -0
  58. data/frameworks/sproutcore/Core.js +378 -0
  59. data/frameworks/sproutcore/README +3 -0
  60. data/frameworks/sproutcore/controllers/array.js +236 -0
  61. data/frameworks/sproutcore/controllers/collection.js +305 -0
  62. data/frameworks/sproutcore/controllers/controller.js +323 -0
  63. data/frameworks/sproutcore/controllers/object.js +372 -0
  64. data/frameworks/sproutcore/drag/drag.js +549 -0
  65. data/frameworks/sproutcore/drag/drag_data_source.js +32 -0
  66. data/frameworks/sproutcore/drag/drag_source.js +64 -0
  67. data/frameworks/sproutcore/drag/drop_target.js +153 -0
  68. data/frameworks/sproutcore/english.lproj/blank.gif +0 -0
  69. data/frameworks/sproutcore/english.lproj/buttons.css +589 -0
  70. data/frameworks/sproutcore/english.lproj/buttons.png +0 -0
  71. data/frameworks/sproutcore/english.lproj/inline_text_editor.css +21 -0
  72. data/frameworks/sproutcore/english.lproj/menu.css +121 -0
  73. data/frameworks/sproutcore/english.lproj/panels/background-fat.jpg +0 -0
  74. data/frameworks/sproutcore/english.lproj/panels/background-thin.jpg +0 -0
  75. data/frameworks/sproutcore/english.lproj/panels/bottom-edge.png +0 -0
  76. data/frameworks/sproutcore/english.lproj/panels/bottom-left-corner.png +0 -0
  77. data/frameworks/sproutcore/english.lproj/panels/bottom-right-corner.png +0 -0
  78. data/frameworks/sproutcore/english.lproj/panels/left-edge.png +0 -0
  79. data/frameworks/sproutcore/english.lproj/panels/overlay.png +0 -0
  80. data/frameworks/sproutcore/english.lproj/panels/right-edge.png +0 -0
  81. data/frameworks/sproutcore/english.lproj/panels/top-edge.png +0 -0
  82. data/frameworks/sproutcore/english.lproj/panels/top-left-corner.png +0 -0
  83. data/frameworks/sproutcore/english.lproj/panels/top-right-corner.png +0 -0
  84. data/frameworks/sproutcore/english.lproj/panes.css +155 -0
  85. data/frameworks/sproutcore/english.lproj/picker.css +22 -0
  86. data/frameworks/sproutcore/english.lproj/strings.js +15 -0
  87. data/frameworks/sproutcore/english.lproj/tab.css +23 -0
  88. data/frameworks/sproutcore/english.lproj/tests.css +67 -0
  89. data/frameworks/sproutcore/english.lproj/theme.css +77 -0
  90. data/frameworks/sproutcore/foundation/animator.js +670 -0
  91. data/frameworks/sproutcore/foundation/application.js +199 -0
  92. data/frameworks/sproutcore/foundation/array.js +348 -0
  93. data/frameworks/sproutcore/foundation/benchmark.js +211 -0
  94. data/frameworks/sproutcore/foundation/binding.js +384 -0
  95. data/frameworks/sproutcore/foundation/date.js +357 -0
  96. data/frameworks/sproutcore/foundation/error.js +39 -0
  97. data/frameworks/sproutcore/foundation/input_manager.js +153 -0
  98. data/frameworks/sproutcore/foundation/json.js +296 -0
  99. data/frameworks/sproutcore/foundation/mock.js +42 -0
  100. data/frameworks/sproutcore/foundation/node_descriptor.js +56 -0
  101. data/frameworks/sproutcore/foundation/object.js +777 -0
  102. data/frameworks/sproutcore/foundation/observable.js +451 -0
  103. data/frameworks/sproutcore/foundation/page.js +63 -0
  104. data/frameworks/sproutcore/foundation/path_module.js +413 -0
  105. data/frameworks/sproutcore/foundation/responder.js +310 -0
  106. data/frameworks/sproutcore/foundation/routes.js +371 -0
  107. data/frameworks/sproutcore/foundation/run_loop.js +21 -0
  108. data/frameworks/sproutcore/foundation/server.js +491 -0
  109. data/frameworks/sproutcore/foundation/set.js +96 -0
  110. data/frameworks/sproutcore/foundation/string.js +149 -0
  111. data/frameworks/sproutcore/foundation/undo_manager.js +186 -0
  112. data/frameworks/sproutcore/foundation/unittest.js +622 -0
  113. data/frameworks/sproutcore/foundation/utils.js +61 -0
  114. data/frameworks/sproutcore/globals/panels.js +182 -0
  115. data/frameworks/sproutcore/globals/popups.js +60 -0
  116. data/frameworks/sproutcore/globals/window.js +381 -0
  117. data/frameworks/sproutcore/lib/index.rhtml +66 -0
  118. data/frameworks/sproutcore/models/collection.js +395 -0
  119. data/frameworks/sproutcore/models/record.js +622 -0
  120. data/frameworks/sproutcore/models/store.js +295 -0
  121. data/frameworks/sproutcore/panes/dialog.js +16 -0
  122. data/frameworks/sproutcore/panes/manager.js +164 -0
  123. data/frameworks/sproutcore/panes/menu.js +45 -0
  124. data/frameworks/sproutcore/panes/overlay.js +231 -0
  125. data/frameworks/sproutcore/panes/pane.js +90 -0
  126. data/frameworks/sproutcore/panes/panel.js +19 -0
  127. data/frameworks/sproutcore/panes/picker.js +45 -0
  128. data/frameworks/sproutcore/tests/controllers/array.rhtml +86 -0
  129. data/frameworks/sproutcore/tests/controllers/controller.rhtml +273 -0
  130. data/frameworks/sproutcore/tests/controllers/object.rhtml +327 -0
  131. data/frameworks/sproutcore/tests/foundation/application.rhtml +125 -0
  132. data/frameworks/sproutcore/tests/foundation/array.rhtml +221 -0
  133. data/frameworks/sproutcore/tests/foundation/object.rhtml +69 -0
  134. data/frameworks/sproutcore/tests/globals/window.rhtml +45 -0
  135. data/frameworks/sproutcore/tests/panes/pane.rhtml +88 -0
  136. data/frameworks/sproutcore/tests/views/collection.rhtml +137 -0
  137. data/frameworks/sproutcore/tests/views/popup_button.rhtml +115 -0
  138. data/frameworks/sproutcore/tests/views/text_field.rhtml +37 -0
  139. data/frameworks/sproutcore/validators/credit_card.js +92 -0
  140. data/frameworks/sproutcore/validators/date.js +36 -0
  141. data/frameworks/sproutcore/validators/email.js +29 -0
  142. data/frameworks/sproutcore/validators/not_empty.js +24 -0
  143. data/frameworks/sproutcore/validators/number.js +55 -0
  144. data/frameworks/sproutcore/validators/password.js +78 -0
  145. data/frameworks/sproutcore/validators/validator.js +304 -0
  146. data/frameworks/sproutcore/views/button.js +425 -0
  147. data/frameworks/sproutcore/views/checkbox_field.js +30 -0
  148. data/frameworks/sproutcore/views/collection.js +1521 -0
  149. data/frameworks/sproutcore/views/container.js +62 -0
  150. data/frameworks/sproutcore/views/error_explanation.js +45 -0
  151. data/frameworks/sproutcore/views/field.js +214 -0
  152. data/frameworks/sproutcore/views/filter_button.js +29 -0
  153. data/frameworks/sproutcore/views/form.js +591 -0
  154. data/frameworks/sproutcore/views/image.js +141 -0
  155. data/frameworks/sproutcore/views/inline_text_editor.js +96 -0
  156. data/frameworks/sproutcore/views/label.js +176 -0
  157. data/frameworks/sproutcore/views/menu_item.js +90 -0
  158. data/frameworks/sproutcore/views/pagination.js +54 -0
  159. data/frameworks/sproutcore/views/popup_button.js +86 -0
  160. data/frameworks/sproutcore/views/popup_menu.js +137 -0
  161. data/frameworks/sproutcore/views/progress.js +100 -0
  162. data/frameworks/sproutcore/views/radio_field.js +107 -0
  163. data/frameworks/sproutcore/views/radio_group.js +48 -0
  164. data/frameworks/sproutcore/views/segmented.js +80 -0
  165. data/frameworks/sproutcore/views/select_field.js +272 -0
  166. data/frameworks/sproutcore/views/spinner.js +11 -0
  167. data/frameworks/sproutcore/views/tab.js +126 -0
  168. data/frameworks/sproutcore/views/text_field.js +179 -0
  169. data/frameworks/sproutcore/views/textarea_field.js +14 -0
  170. data/frameworks/sproutcore/views/toolbar.js +29 -0
  171. data/frameworks/sproutcore/views/view.js +1389 -0
  172. data/frameworks/sproutcore/views/workspace.js +170 -0
  173. data/generators/client/README +3 -0
  174. data/generators/client/USAGE +12 -0
  175. data/generators/client/client_generator.rb +53 -0
  176. data/generators/client/templates/core.js +19 -0
  177. data/generators/client/templates/english.lproj/body.css +0 -0
  178. data/generators/client/templates/english.lproj/body.rhtml +3 -0
  179. data/generators/client/templates/english.lproj/controls.css +0 -0
  180. data/generators/client/templates/english.lproj/strings.js +14 -0
  181. data/generators/client/templates/main.js +37 -0
  182. data/generators/controller/USAGE +16 -0
  183. data/generators/controller/controller_generator.rb +51 -0
  184. data/generators/controller/templates/controller.js +21 -0
  185. data/generators/controller/templates/test.rhtml +21 -0
  186. data/generators/framework/README +7 -0
  187. data/generators/framework/USAGE +12 -0
  188. data/generators/framework/framework_generator.rb +53 -0
  189. data/generators/framework/templates/core.js +20 -0
  190. data/generators/framework/templates/english.lproj/body.css +0 -0
  191. data/generators/framework/templates/english.lproj/body.rhtml +3 -0
  192. data/generators/framework/templates/english.lproj/controls.css +0 -0
  193. data/generators/framework/templates/english.lproj/strings.js +14 -0
  194. data/generators/language/USAGE +16 -0
  195. data/generators/language/language_generator.rb +47 -0
  196. data/generators/language/templates/strings.js +10 -0
  197. data/generators/model/USAGE +24 -0
  198. data/generators/model/model_generator.rb +55 -0
  199. data/generators/model/templates/fixture.js +11 -0
  200. data/generators/model/templates/model.js +20 -0
  201. data/generators/model/templates/test.rhtml +21 -0
  202. data/generators/test/USAGE +16 -0
  203. data/generators/test/templates/test.rhtml +21 -0
  204. data/generators/test/test_generator.rb +47 -0
  205. data/generators/view/USAGE +16 -0
  206. data/generators/view/templates/test.rhtml +21 -0
  207. data/generators/view/templates/view.js +20 -0
  208. data/generators/view/view_generator.rb +51 -0
  209. data/jsdoc/README.txt +119 -0
  210. data/jsdoc/app/DocFile.js +137 -0
  211. data/jsdoc/app/DocTag.js +110 -0
  212. data/jsdoc/app/Doclet.js +63 -0
  213. data/jsdoc/app/Dumper.js +143 -0
  214. data/jsdoc/app/JsDoc.js +103 -0
  215. data/jsdoc/app/JsHilite.js +45 -0
  216. data/jsdoc/app/JsIO.js +163 -0
  217. data/jsdoc/app/JsParse.js +385 -0
  218. data/jsdoc/app/JsPlate.js +130 -0
  219. data/jsdoc/app/JsTestrun.js +129 -0
  220. data/jsdoc/app/JsToke.js +564 -0
  221. data/jsdoc/app/Symbol.js +298 -0
  222. data/jsdoc/app/Transformer.js +14 -0
  223. data/jsdoc/app/Util.js +97 -0
  224. data/jsdoc/app/js.jar +0 -0
  225. data/jsdoc/app/run.js +144 -0
  226. data/jsdoc/plugins/min.js +316 -0
  227. data/jsdoc/plugins/strip.js +20 -0
  228. data/jsdoc/templates/sproutcore/class.tmpl +438 -0
  229. data/jsdoc/templates/sproutcore/default.css +241 -0
  230. data/jsdoc/templates/sproutcore/index.html +13 -0
  231. data/jsdoc/templates/sproutcore/index.tmpl +21 -0
  232. data/jsdoc/templates/sproutcore/prototype.js +4186 -0
  233. data/jsdoc/templates/sproutcore/publish.js +236 -0
  234. data/jsdoc/templates/sproutcore/splash.html +7 -0
  235. data/lib/sproutcore/build_tools/html_builder.rb +88 -0
  236. data/lib/sproutcore/build_tools/resource_builder.rb +194 -0
  237. data/lib/sproutcore/build_tools.rb +44 -0
  238. data/lib/sproutcore/bundle.rb +517 -0
  239. data/lib/sproutcore/bundle_manifest.rb +397 -0
  240. data/lib/sproutcore/generator_helper.rb +170 -0
  241. data/lib/sproutcore/helpers/capture_helper.rb +42 -0
  242. data/lib/sproutcore/helpers/static_helper.rb +80 -0
  243. data/lib/sproutcore/helpers/tag_helper.rb +110 -0
  244. data/lib/sproutcore/helpers/text_helper.rb +336 -0
  245. data/lib/sproutcore/helpers.rb +3 -0
  246. data/lib/sproutcore/jsdoc.rb +40 -0
  247. data/lib/sproutcore/jsmin.rb +247 -0
  248. data/lib/sproutcore/library.rb +258 -0
  249. data/lib/sproutcore/merb/bundle_controller.rb +179 -0
  250. data/lib/sproutcore/merb/router.rb +43 -0
  251. data/lib/sproutcore/merb.rb +27 -0
  252. data/lib/sproutcore/version.rb +9 -0
  253. data/lib/sproutcore/view_helpers/button_views.rb +302 -0
  254. data/lib/sproutcore/view_helpers/core_views.rb +284 -0
  255. data/lib/sproutcore/view_helpers/form_views.rb +258 -0
  256. data/lib/sproutcore/view_helpers/menu_views.rb +94 -0
  257. data/lib/sproutcore/view_helpers.rb +628 -0
  258. data/lib/sproutcore.rb +30 -0
  259. data/script/destroy +14 -0
  260. data/script/generate +14 -0
  261. data/script/txt2html +74 -0
  262. data/setup.rb +1585 -0
  263. data/spec/spec.opts +1 -0
  264. data/spec/spec_helper.rb +7 -0
  265. data/spec/sproutcore_spec.rb +11 -0
  266. data/tasks/deployment.rake +34 -0
  267. data/tasks/environment.rake +7 -0
  268. data/tasks/rspec.rake +21 -0
  269. data/tasks/website.rake +17 -0
  270. metadata +365 -0
@@ -0,0 +1,549 @@
1
+ // ========================================================================
2
+ // SproutCore
3
+ // copyright 2006-2007 Sprout Systems, Inc.
4
+ // ========================================================================
5
+
6
+ require('Core') ;
7
+ require('views/view') ;
8
+
9
+ SC.DRAG_LINK = 0x0004; SC.DRAG_COPY = 0x0001; SC.DRAG_MOVE = 0x0002;
10
+ SC.DRAG_NONE = 0x0000; SC.DRAG_ANY = 0x0007 ;
11
+
12
+ /**
13
+
14
+ @class
15
+
16
+ An instance of this object is created whenever a drag occurs. The instance
17
+ manages the mouse events and coordinating with droppable targets until the
18
+ user releases the mouse button.
19
+
20
+ To initiate a drag, you should call SC.Drag.start() with the options below
21
+ specified in a hash. Pass the ones you need to get the drag you want:
22
+
23
+ {{{
24
+ event: (req)
25
+ The mouse event that triggered the drag. This will be used to
26
+ position the element.
27
+
28
+ source: (req)
29
+ The drag source object that should be consulted during the drag operations.
30
+ This is usually the container view that initiated the drag.
31
+
32
+ dragView: (req)
33
+ This should point to a view that will be used as the source image for
34
+ the drag. The drag operation will clone the DOM elements for this
35
+ view and add the class name 'drag-image' to the outermost element.
36
+
37
+ ghost: YES | NO
38
+ if YES or not passed, then drag view image will show, but the source
39
+ dragView will not be hidden. set to NO to make it appear that the
40
+ dragView itself is being dragged around.
41
+
42
+ slideBack: YES | NO
43
+ If YES or not specified, then if the drag operation is cancelled, the
44
+ dragView will slide back to its source origin.
45
+
46
+ origin:
47
+ If passed, this will be used as the origin point for the ghostView
48
+ when it slides back. You normally do not need to pass this unless
49
+ the ghost view does not appear in the main UI.
50
+
51
+ data:
52
+ Optional hash of data types and values. You can use this to pass a
53
+ static set of data instead of providing a dataSource. If you provide
54
+ a dataSource, it will override this.
55
+
56
+ dataSource:
57
+ Optional object that will provide the data for the drag to be consumed
58
+ by the drop target. If you do not pass this parameter or the data
59
+ hash, then the source object will be used if it implements the
60
+ SC.DragDataSource protocol.
61
+
62
+ anchorView:
63
+ if you pass this optional view, then the drag will only be allowed to
64
+ happen within this view. The ghostView will actually be added as a
65
+ child of this view during the drag. Normally the anchorView is the
66
+ window.
67
+ }}}
68
+
69
+ @extends SC.Object
70
+ */
71
+ SC.Drag = SC.Object.extend(
72
+ /** @scope SC.Drag.prototype */
73
+ {
74
+ /** [RO] The source object used to coordinate this drag. */
75
+ source: null,
76
+
77
+ /** The actual image being dragged around the screen.
78
+
79
+ This is created automatically from the dragView.
80
+ */
81
+ ghostView: null,
82
+
83
+ /**
84
+ The view that was used as the source of the ghostView.
85
+
86
+ The drag view is not moved from its original location during a drag.
87
+ Instead, the DOM content of the view is cloned and managed by the
88
+ ghostView. If you want to visually indicate that the view is being
89
+ movied, you may want to temporarily hide it during the drag.
90
+ */
91
+ dragView: null,
92
+
93
+ /**
94
+ If YES, the dragView is automatically hidden while dragging around the ghost.
95
+ */
96
+ ghost: YES,
97
+
98
+ /**
99
+ If YES, then the ghostView will slide back to its original location if drag is cancelled.
100
+ */
101
+ slideBack: YES,
102
+
103
+ /** The original mouse down event. */
104
+ mouseDownEvent: null,
105
+
106
+ /**
107
+ The origin to slide back to in the coordinate of the dragView's offsetParent.
108
+ */
109
+ ghostOffset: { x: 0, y: 0 },
110
+
111
+ /**
112
+ The current location of the mouse pointer in window coordinates.
113
+
114
+ This is updated as long as the mouse button is pressed.
115
+ */
116
+ location: null,
117
+
118
+ // ..........................................
119
+ // DRAG DATA
120
+ //
121
+
122
+ /**
123
+ (Property) Data types supported by this drag operation.
124
+
125
+ Returns an array of data types supported by the drag source. This may
126
+ be generated dynamically depending on the data source.
127
+
128
+ If you are implementing a drag source, you will need to provide these data
129
+ types so that drop targets can detect if they can accept your drag data.
130
+
131
+ If you are implementing a drop target, you should inspect this property
132
+ on your dragEntered() and prepareForDragOperation() methods to determine
133
+ if you can handle any of the data types offered up by the drag source.
134
+
135
+ @returns {Array} available data types
136
+ */
137
+ dataTypes: function() {
138
+
139
+ // first try to use the data source.
140
+ if (this.dataSource) return this.dataSource.get('dragDataTypes') ;
141
+
142
+ // if that fails, get the keys from the data hash.
143
+ if (this.data) {
144
+ var ret = [];
145
+ for(var key in this._data) {
146
+ if (this.data.hasOwnProperty(key)) ret.push(key) ;
147
+ }
148
+ return key ;
149
+ }
150
+
151
+ // if that fails, then check to see if the source object is a dataSource.
152
+ var source = this.get('source') ;
153
+ if (source && source.dragDataTypes) return source.get('dragDataTypes') ;
154
+
155
+ // no data types found. :(
156
+ return [] ;
157
+ }.property(),
158
+
159
+ /**
160
+ Retrieve the data for the specified dataType from the drag source.
161
+
162
+ Drop targets can use this method during their performDragOperation() method
163
+ to retrieve the actual data provided by the drag data source. This data
164
+ may be generated dynamically depending on the data source.
165
+
166
+ @param {Object} dataType data type you want to retrieve. Should be one of the values returned in the dataTypes property
167
+
168
+ @returns {Object} The generated data.
169
+ */
170
+ dataForType: function(dataType) {
171
+
172
+ // first try to use the data Source.
173
+ if (this.dataSource) {
174
+ return this.dataSource.dragDataForType(dataType, this) ;
175
+
176
+ // then try to use the data hash.
177
+ } else if (this.data) {
178
+ return this.data[dataType];
179
+
180
+ // if all else fails, check to see if the source object is a data source.
181
+ } else {
182
+ var source = this.get('source') ;
183
+ if (source && $type(source.dragDataForType) == T_FUNCTION) {
184
+ return source.dragDataForType(dataType, this) ;
185
+
186
+ // no data source found. :(
187
+ } else return null ;
188
+ }
189
+ },
190
+
191
+ /**
192
+ Optional object used to provide the data for the drag.
193
+
194
+ Drag source can designate a dataSource object to generate the data for
195
+ a drag dynamically. The data source can and often is the drag source
196
+ object itself.
197
+
198
+ Data Source objects must comply with the SC.DragDataSource interface. If
199
+ you do not want to implement this interface, you can provide the data
200
+ directly with the data property.
201
+
202
+ If you are implementing a drop target, use the dataTypes property and
203
+ dataForTypes() method to access data instead of working directly with these
204
+ properties.
205
+
206
+ @type {Object}
207
+ */
208
+ dataSource: null,
209
+
210
+ /**
211
+ Optional hash of data. Used if no dataSource was provided.
212
+
213
+ Drag sources can provide a hash of data when the drag begins instead of
214
+ specifying an actual dataSource. The data is stored in this property.
215
+ If you are implementing a drop target, use the dataTypes property and
216
+ dataForTypes() method to access data instead of working directly with these
217
+ properties.
218
+
219
+ @type {Object}
220
+ */
221
+ data: null,
222
+
223
+ // this will actually start the drag process.
224
+ startDrag: function() {
225
+
226
+ // create the ghost view and position.
227
+ this._createGhostView() ;
228
+
229
+ // compute the offset from the original mouse location.
230
+ var origin = this.dragView.convertFrameToView(this.dragView.get('origin'), null);
231
+ var pointer = Event.pointerLocation(this.event) ;
232
+ this.ghostOffset = { x: (pointer.x-origin.x), y: (pointer.y-origin.y) };
233
+
234
+ // position the ghost view.
235
+ this._positionGhostView(this.event) ;
236
+
237
+ // notify window a drag is in process. mouseDragged notifications will
238
+ // go to the drag instead.
239
+ SC.window.dragDidStart(this) ;
240
+
241
+ if (this.source && this.source.dragDidBegin) {
242
+ this.source.dragDidBegin(this, pointer) ;
243
+ }
244
+ },
245
+
246
+ _lastLoc: {},
247
+
248
+ /**
249
+ @private
250
+
251
+ This method is called repeatedly during a mouse drag. It updates the
252
+ position of the ghost image, then it looks for a current drop target and
253
+ notifies it.
254
+ */
255
+ mouseDragged: function(evt) {
256
+ // ignore duplicate calls.
257
+ var loc = Event.pointerLocation(evt) ;
258
+ if ((loc.x == this._lastLoc.x) && (loc.y == this._lastLoc.y)) return ;
259
+ this._lastLoc = loc ;
260
+ this.set('location', loc) ;
261
+
262
+ this._positionGhostView(evt) ;
263
+ var last = this._lastTarget ;
264
+
265
+ // STEP 1: Determine the deepest drop target that allows an operation.
266
+ // if the drop target selected the last time this method was called differs
267
+ // from the deepest target found, then go up the chain until we either hit the
268
+ // last one or find one that will allow a drag operation
269
+ var target = this._findDropTarget(evt) ; // deepest drop target
270
+ var op = SC.DRAG_NONE ;
271
+ while (target && (target != last) && (op == SC.DRAG_NONE)) {
272
+
273
+ // make sure the drag source will permit a drop operation on the named target.
274
+ // if source does not implement this callback, just assume a drop is allowed
275
+ // by the source.
276
+ if (target && this.source && this.source.dragSourceOperationMaskFor) {
277
+ op = this.source.dragSourceOperationMaskFor(target, this) ;
278
+ } else op = SC.DRAG_ANY ;
279
+
280
+ // now, let's see if the target will accept the drag. If it does not respond
281
+ // to dragEntered, then assume NO drag opts.
282
+ if ((op != SC.DRAG_NONE) && target && target.dragEntered) {
283
+ op = op & target.dragEntered(this, evt) ;
284
+ } else op = SC.DRAG_NONE ;
285
+
286
+ console.log(SC.Drag.inspectOperation(op)) ;
287
+
288
+ // if DRAG_NONE, then look for the next parent that is a drop zone.
289
+ if (op == SC.DRAG_NONE) target = this._findNextDropTarget(target) ;
290
+ }
291
+
292
+ // STEP 2: Refocus the drop target.
293
+ // If a new drop target was found then this part of the method will exit the
294
+ // last drag target and start the new one.
295
+ if (target != last) {
296
+
297
+ // if the new target does not match the last target, exit that target.
298
+ if (last && last.dragExited) last.dragExited(this, evt) ;
299
+
300
+ if (target && this.source && this.source.dragSourceOperationMaskFor) {
301
+ op = this.source.dragSourceOperationMaskFor(target, this) ;
302
+ } else op = SC.DRAG_ANY ;
303
+
304
+ // save new op and set target to null if op = DRAG_NONE
305
+ this.sourceDropOperations = op ;
306
+
307
+ // now notify the new target, if there is one. Save the allowed drop
308
+ // operations as the logical AND between the ops allowed by the source
309
+ // and target.
310
+ if (target && target.dragEntered) {
311
+ this.dropOperations = op & target.dragEntered(this, evt) ;
312
+ } else this.dropOperations = SC.DRAG_NONE ;
313
+
314
+ if (this.dropOperations == SC.DRAG_NONE) target = null ;
315
+
316
+ // if nothing has changed, send dragUpdated
317
+ } else {
318
+ if (target && target.dragUpdated) target.dragUpdated(this, evt) ;
319
+ }
320
+
321
+ // notify source that the drag moved.
322
+ if (this.source && this.source.dragDidMove) {
323
+ this.source.dragDidMove(this, loc) ;
324
+ }
325
+
326
+ this._lastTarget = target ;
327
+ },
328
+
329
+ /**
330
+ @private
331
+
332
+ Called when the mouse is released. Performs any necessary cleanup and
333
+ executes the drop target protocol to try to complete the drag operation.
334
+ */
335
+ mouseUp: function(evt) {
336
+ var loc = Event.pointerLocation(evt) ;
337
+
338
+ // try to have the drop target perform the drop...
339
+ var target = this._lastTarget ;
340
+ var op = this.dropOperations;
341
+
342
+ if (target && target.prepareForDragOperation(op, this)) {
343
+ op = target.performDragOperation(op, this) ;
344
+ }
345
+
346
+ // create cleanupFunc. This function will be called at the end of this
347
+ // function or after the ghostView slides back to its origin.
348
+ var drag = this ;
349
+ var cleanupFunc = function() {
350
+ if (target) target.concludeDragOperation(op, this) ;
351
+ drag._destroyGhostView() ;
352
+ };
353
+
354
+ // notify drop target.
355
+ if (target && target.dragEnded) target.dragEnded(this, evt) ;
356
+ this._lastTarget = null ;
357
+
358
+ // clean up ghost view. if sldeBack is true, then do the animation.
359
+ if ((op == SC.DRAG_NONE) && this.get('slideBack')) {
360
+ var loc = this.dragView.convertFrameToView(this.dragView.get('origin'), null) ;
361
+ this._ghostView.transitionTo(1.0,
362
+ "left: %@px; top: %@px".fmt(loc.x, loc.y),
363
+ { duration: 200, onComplete: cleanupFunc }) ;
364
+
365
+ } else cleanupFunc() ;
366
+
367
+ // notify the source that everything has completed.
368
+ if (this.source && this.source.dragDidEnd) {
369
+ this.source.dragDidEnd(this, loc, op) ;
370
+ }
371
+
372
+ },
373
+
374
+ // ..........................................
375
+ // PRIVATE PROPERTIES AND METHODS
376
+ //
377
+
378
+ // positions the ghost view underneath the mouse with the initial offset
379
+ // recorded by when the drag started.
380
+ _positionGhostView: function(evt) {
381
+ var loc = { x: Event.pointerX(evt), y: Event.pointerY(evt) } ;
382
+ loc.x -= this.ghostOffset.x ;
383
+ loc.y -= this.ghostOffset.y ;
384
+ this._ghostView.set('origin', loc) ;
385
+ },
386
+
387
+ // this will create the ghostView and add it to the main HTML document.
388
+ // it will also position it underneath the current mouse location.
389
+ _createGhostView: function() {
390
+
391
+ // create the elements by cloning the dragView.
392
+ var el = this.dragView.rootElement.cloneNode(true) ;
393
+
394
+ // create the ghost view instance add ghost class name.
395
+ this._ghostView = this._ghostViewClass.viewFor(el) ;
396
+ this._ghostView.owner = this ;
397
+ this._ghostView.addClassName('ghost') ;
398
+ this._ghostView.set('isPositioned', true) ; // make absolute position.
399
+
400
+ // add to bottom of main document body and to window.
401
+ SC.window.appendChild(this._ghostView) ;
402
+ },
403
+
404
+ _destroyGhostView: function() {
405
+ if (this._ghostView) {
406
+ this._ghostView.removeFromParent() ;
407
+ this._ghostView = null ; // this will allow the GC to collect it.
408
+ }
409
+ },
410
+
411
+ _ghostView: null,
412
+
413
+ // Return an array of drop targets, sorted with any nested drop targets
414
+ // at the top of the array. The first time this method is called during
415
+ // a drag, it will reconstruct this array using the current set of
416
+ // drop targets. Afterwards it uses the cached set until the drop
417
+ // completes.
418
+ //
419
+ // This means that if you change the view hierarchy of your drop targets
420
+ // during a drag, it will probably be wrong.
421
+ _dropTargets: function() {
422
+ if (this._cachedDropTargets) return this._cachedDropTargets ;
423
+ var ret = [];
424
+
425
+ // build array of drop targets
426
+ var dt = SC.Drag._dropTargets ;
427
+ for(var key in dt) {
428
+ if (!dt.hasOwnProperty(key)) continue ;
429
+ ret.push(dt[key]) ;
430
+ }
431
+
432
+ // now resort. This custom function will sort nested drop targets
433
+ // at the start of the list.
434
+ ret = ret.sort(function(a,b) {
435
+ var view = a;
436
+ while((view = view.parentNode) && (view != SC.window)) {
437
+ if (b == view) return -1 ;
438
+ }
439
+ return 1;
440
+ }) ;
441
+
442
+ this._cachedDropTargets = ret ;
443
+
444
+ console.log('ret: %@'.fmt(ret.join(','))) ;
445
+ return ret ;
446
+ },
447
+
448
+ // This will search through the drop targets, looking for one in the
449
+ // target area.
450
+ _findDropTarget: function(evt) {
451
+ var dt = this._dropTargets() ;
452
+ var loc = { x: Event.pointerX(evt), y: Event.pointerY(evt) } ;
453
+
454
+ var ret = null ;
455
+ for(var idx=0;idx<dt.length;idx++) {
456
+ var t = dt[idx] ;
457
+ if(!t.get('isVisibleInWindow')) continue ;
458
+
459
+ // get frame, converted to view.
460
+ var f = t.convertFrameToView(t.get('frame'), null) ;
461
+
462
+ // check to see if loc is inside. If so, then make this the drop
463
+ // target unless there is a drop target and the current one
464
+ // is not deeper.
465
+ if (SC.pointInRect(loc, f)) return t;
466
+ }
467
+ return null ;
468
+ },
469
+
470
+ // Search the parent nodes of the target to find another view matching the drop
471
+ // target. Returns null if no matching target is found.
472
+ _findNextDropTarget: function(target) {
473
+ while ((target = target.parentNode) && (target != SC.window)) {
474
+ if (SC.Drag._dropTargets[target._guid]) return target ;
475
+ }
476
+ return null ;
477
+ },
478
+
479
+ _ghostViewClass: SC.View.extend({})
480
+
481
+ }) ;
482
+
483
+ SC.Drag.mixin(
484
+ /** @scope SC.Drag */
485
+ {
486
+
487
+
488
+ /**
489
+ This is the method you use to initiate a new drag. See class documentation
490
+ for more info on the options taken by this method.
491
+
492
+ @params {Hash} ops a hash of options. See documentation above.
493
+
494
+ */
495
+ start: function(ops) {
496
+ var ret = this.create(ops) ;
497
+ ret.startDrag() ;
498
+ return ret ;
499
+ },
500
+
501
+ _dropTargets: {},
502
+
503
+ /**
504
+ Register the view object as a drop target.
505
+
506
+ This method is called automatically whenever a view is created with the
507
+ isDropTarget property set to YES. You generally will not need to call it
508
+ yourself.
509
+ */
510
+ addDropTarget: function(target) {
511
+ this._dropTargets[target._guid] = target ;
512
+ },
513
+
514
+ /**
515
+ Remove a view from the list of drop targets.
516
+
517
+ This method is called automatically whenever a view is removed from the
518
+ hierarchy. You generally will not need to call it yourself.
519
+ */
520
+ removeDropTarget: function(target) {
521
+ delete this._dropTargets[target._guid] ;
522
+ },
523
+
524
+ /**
525
+ Convenience method to turn a operation mask into a descriptive string.
526
+ */
527
+ inspectOperation: function(op) {
528
+ var ret = [] ;
529
+ if (op == SC.DRAG_NONE) {
530
+ ret = ['DRAG_NONE'];
531
+ } else if (op == SC.DRAG_ANY) {
532
+ ret = ['DRAG_ANY'] ;
533
+ } else {
534
+ if (op & SC.DRAG_LINK) {
535
+ ret.push('DRAG_LINK') ;
536
+ }
537
+
538
+ if (op & SC.DRAG_COPY) {
539
+ ret.push('DRAG_COPY') ;
540
+ }
541
+
542
+ if (op & SC.DRAG_MOVE) {
543
+ ret.push('DRAG_MOVE') ;
544
+ }
545
+ }
546
+ return ret.join('|') ;
547
+ }
548
+
549
+ });
@@ -0,0 +1,32 @@
1
+ // ========================================================================
2
+ // SproutCore
3
+ // copyright 2006-2007 Sprout Systems, Inc.
4
+ // ========================================================================
5
+
6
+ require('drag/drag') ;
7
+
8
+
9
+ // This mixin can be used to implement a dynamic data source for a drag
10
+ // operation. You can return a set of allowed data types and then the
11
+ // method will be used to actually get data in that format when requested.
12
+ SC.DragDataSource = {
13
+
14
+ // Implement this property as an array of data types you want to support
15
+ // for drag operations.
16
+ dragDataTypes: [],
17
+
18
+ // Implement this method to return the data in the format passed. Return
19
+ // null if the requested data type cannot be generated.
20
+ //
21
+ // dataType:
22
+ // The proposed dataType to return. This will always be one of the
23
+ // data types declared in dragDataTypes.
24
+ //
25
+ // drag:
26
+ // The Drag instance managing this drag.
27
+ //
28
+ dragDataForType: function(dataType, drag) { return null; }
29
+
30
+ };
31
+
32
+
@@ -0,0 +1,64 @@
1
+ // ========================================================================
2
+ // SproutCore
3
+ // copyright 2006-2007 Sprout Systems, Inc.
4
+ // ========================================================================
5
+
6
+ require('drag/drag') ;
7
+
8
+ // The DataSource protocol is used to dynamically generate multiple types of
9
+ // data from a single object. You must implement this protocol if you want to
10
+ // provide the data for a drag event.
11
+ SC.DragSource = {
12
+
13
+ // This method is called when the drag begins. You can use this to do any
14
+ // visual highlighting to indicate that the receive is the source of the
15
+ // drag.
16
+ //
17
+ // drag:
18
+ // The Drag instance managing this drag.
19
+ //
20
+ // atPoint:
21
+ // The point in WINDOW coordinates where the drag began. You can use
22
+ // convertOffsetFromView() to convert this to local coordinates.
23
+ dragDidBegin: function(drag, atPoint) {},
24
+
25
+ // This method is called when the drag ended. You can use this to do any
26
+ // cleanup. The operation is the actual operation performed on the drag.
27
+ //
28
+ // drag:
29
+ // The SC.Drag instance managing the drag.
30
+ //
31
+ // endPoint:
32
+ // The point in WINDOW coordinates where the drag ended.
33
+ //
34
+ // operation: SC.DRAG_COPY | SC.DRAG_MOVE | SC.DRAG_LINK | SC.DRAG_NONE
35
+ // The drag operation that was performed.
36
+ //
37
+ dragDidEnd: function(drag, endPoint, operation) {},
38
+
39
+ // This method is called whenever the drag image is moved. This is
40
+ // similar to the dragUpdated() method called on drop targets.
41
+ dragDidMove: function(drag, newPoint) {},
42
+
43
+ // This method must be overridden for drag operations to be allowed.
44
+ // Return a bitwise OR'd mask of the drag operations allowed on the
45
+ // specified target. If you don't care about the target, just return a
46
+ // constant value.
47
+ //
48
+ // dropTarget:
49
+ // The proposed target of the drop.
50
+ //
51
+ // drag:
52
+ // The SC.Drag instance managing this drag.
53
+ //
54
+ dragSourceOperationMaskFor: function(dropTarget, drag) {
55
+ return SC.DRAG_NONE ;
56
+ },
57
+
58
+ // If this property is set to NO or is not implemented, then the user may
59
+ // modify the drag operation by changing the modifier keys they have
60
+ // pressed.
61
+ ignoreModifierKeysWhileDragging: NO
62
+
63
+ } ;
64
+