sproutcore 0.9.1 → 0.9.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +233 -0
- data/Manifest.txt +67 -34
- data/bin/sc-build +12 -1
- data/bin/sc-gen +1 -1
- data/bin/sproutcore +14 -0
- data/clients/sc_docs/controllers/docs.js +38 -8
- data/clients/sc_docs/english.lproj/body.css +80 -127
- data/clients/sc_docs/english.lproj/body.rhtml +43 -23
- data/clients/sc_docs/english.lproj/no_docs.rhtml +2 -1
- data/clients/sc_docs/english.lproj/tabs.rhtml +16 -0
- data/clients/sc_docs/main.js +14 -9
- data/clients/sc_docs/models/doc.js +1 -1
- data/clients/sc_docs/tests/controllers/docs.rhtml +1 -2
- data/clients/sc_docs/tests/models/doc.rhtml +1 -2
- data/clients/sc_docs/tests/views/doc_frame.rhtml +1 -2
- data/clients/sc_docs/tests/views/doc_label_view.rhtml +1 -2
- data/clients/sc_docs/views/doc_frame.js +1 -1
- data/clients/sc_test_runner/controllers/runner.js +31 -8
- data/clients/sc_test_runner/english.lproj/body.css +62 -122
- data/clients/sc_test_runner/english.lproj/body.rhtml +62 -26
- data/clients/sc_test_runner/main.js +1 -6
- data/clients/sc_test_runner/models/test.js +14 -1
- data/clients/sc_test_runner/views/runner_frame.js +4 -2
- data/clients/view_builder/builders/builder.js +339 -0
- data/clients/view_builder/builders/button.js +81 -0
- data/clients/view_builder/controllers/document.js +21 -0
- data/clients/view_builder/core.js +19 -0
- data/clients/view_builder/english.lproj/body.css +77 -0
- data/clients/view_builder/english.lproj/body.rhtml +41 -0
- data/clients/{sc_docs → view_builder}/english.lproj/controls.css +0 -0
- data/clients/view_builder/english.lproj/strings.js +14 -0
- data/clients/view_builder/main.js +38 -0
- data/clients/view_builder/tests/controllers/document.rhtml +20 -0
- data/clients/view_builder/tests/views/builder.rhtml +20 -0
- data/clients/view_builder/views/builder.js +23 -0
- data/frameworks/prototype/prototype.js +1 -1
- data/frameworks/sproutcore/Core.js +32 -7
- data/frameworks/sproutcore/README +1 -1
- data/frameworks/sproutcore/animation/animation.js +411 -0
- data/frameworks/sproutcore/controllers/array.js +17 -9
- data/frameworks/sproutcore/controllers/collection.js +9 -110
- data/frameworks/sproutcore/controllers/controller.js +1 -1
- data/frameworks/sproutcore/controllers/object.js +2 -1
- data/frameworks/sproutcore/drag/drag.js +267 -56
- data/frameworks/sproutcore/drag/drag_data_source.js +24 -16
- data/frameworks/sproutcore/drag/drag_source.js +53 -42
- data/frameworks/sproutcore/drag/drop_target.js +2 -2
- data/frameworks/sproutcore/english.lproj/buttons.css +337 -236
- data/frameworks/sproutcore/english.lproj/core.css +115 -0
- data/frameworks/sproutcore/english.lproj/icons.css +227 -0
- data/{clients/sc_docs → frameworks/sproutcore}/english.lproj/images/indicator.gif +0 -0
- data/frameworks/sproutcore/english.lproj/images/sc-theme-sprite.png +0 -0
- data/frameworks/sproutcore/english.lproj/images/sc-theme-ysprite.png +0 -0
- data/frameworks/sproutcore/english.lproj/images/shared-icons.png +0 -0
- data/frameworks/sproutcore/english.lproj/menu.css +1 -1
- data/frameworks/sproutcore/english.lproj/strings.js +1 -1
- data/frameworks/sproutcore/english.lproj/theme.css +405 -31
- data/frameworks/sproutcore/foundation/application.js +15 -11
- data/frameworks/sproutcore/foundation/benchmark.js +1 -1
- data/frameworks/sproutcore/foundation/binding.js +2 -2
- data/frameworks/sproutcore/foundation/date.js +1 -1
- data/frameworks/sproutcore/foundation/error.js +1 -1
- data/frameworks/sproutcore/foundation/input_manager.js +32 -21
- data/frameworks/sproutcore/foundation/mock.js +1 -1
- data/frameworks/sproutcore/foundation/node_descriptor.js +9 -6
- data/frameworks/sproutcore/foundation/object.js +249 -177
- data/frameworks/sproutcore/foundation/page.js +5 -2
- data/frameworks/sproutcore/foundation/path_module.js +11 -10
- data/frameworks/sproutcore/foundation/responder.js +5 -2
- data/frameworks/sproutcore/foundation/routes.js +17 -13
- data/frameworks/sproutcore/foundation/run_loop.js +249 -11
- data/frameworks/sproutcore/foundation/server.js +1 -1
- data/frameworks/sproutcore/foundation/set.js +3 -3
- data/frameworks/sproutcore/foundation/string.js +5 -3
- data/frameworks/sproutcore/foundation/timer.js +371 -0
- data/frameworks/sproutcore/foundation/undo_manager.js +1 -1
- data/frameworks/sproutcore/foundation/unittest.js +3 -3
- data/frameworks/sproutcore/foundation/utils.js +161 -2
- data/frameworks/sproutcore/globals/panels.js +1 -1
- data/frameworks/sproutcore/globals/popups.js +4 -3
- data/frameworks/sproutcore/globals/window.js +44 -4
- data/frameworks/sproutcore/lib/button_views.rb +328 -0
- data/frameworks/sproutcore/lib/collection_view.rb +80 -0
- data/frameworks/sproutcore/lib/core_views.rb +281 -0
- data/frameworks/sproutcore/lib/form_views.rb +253 -0
- data/frameworks/sproutcore/lib/index.rhtml +2 -0
- data/frameworks/sproutcore/lib/menu_views.rb +88 -0
- data/frameworks/sproutcore/{foundation → mixins}/array.js +60 -29
- data/frameworks/sproutcore/mixins/control.js +265 -0
- data/frameworks/sproutcore/mixins/delegate_support.js +66 -0
- data/frameworks/sproutcore/{foundation → mixins}/observable.js +176 -6
- data/frameworks/sproutcore/mixins/scrollable.js +245 -0
- data/frameworks/sproutcore/mixins/selection_support.js +148 -0
- data/frameworks/sproutcore/mixins/validatable.js +152 -0
- data/frameworks/sproutcore/models/collection.js +5 -5
- data/frameworks/sproutcore/models/record.js +1 -1
- data/frameworks/sproutcore/models/store.js +1 -1
- data/frameworks/sproutcore/panes/dialog.js +1 -1
- data/frameworks/sproutcore/panes/manager.js +1 -1
- data/frameworks/sproutcore/panes/menu.js +1 -1
- data/frameworks/sproutcore/panes/overlay.js +2 -2
- data/frameworks/sproutcore/panes/panel.js +1 -1
- data/frameworks/sproutcore/panes/picker.js +1 -1
- data/frameworks/sproutcore/tests/controllers/array.rhtml +44 -4
- data/frameworks/sproutcore/tests/foundation/timer/invalidate.rhtml +33 -0
- data/frameworks/sproutcore/tests/foundation/timer/invokeLater.rhtml +145 -0
- data/frameworks/sproutcore/tests/foundation/timer/isPaused.rhtml +70 -0
- data/frameworks/sproutcore/tests/foundation/timer/schedule.rhtml +145 -0
- data/frameworks/sproutcore/tests/views/{scroll.rhtml → checkbox.rhtml} +3 -3
- data/frameworks/sproutcore/tests/views/{collection.rhtml → collection/base.rhtml} +33 -32
- data/frameworks/sproutcore/tests/views/collection/incremental_rendering.rhtml +260 -0
- data/frameworks/sproutcore/tests/views/image_cell.rhtml +19 -0
- data/frameworks/sproutcore/tests/views/label_item.rhtml +2 -4
- data/frameworks/sproutcore/tests/views/list.rhtml +2 -3
- data/frameworks/sproutcore/tests/views/list_item.rhtml +20 -0
- data/frameworks/sproutcore/tests/views/slider.rhtml +20 -0
- data/frameworks/sproutcore/tests/views/text_cell.rhtml +19 -0
- data/frameworks/sproutcore/tests/views/view/clippingFrame.rhtml +395 -0
- data/frameworks/sproutcore/tests/views/view/frame.rhtml +353 -0
- data/frameworks/sproutcore/tests/views/view/innerFrame.rhtml +347 -0
- data/frameworks/sproutcore/tests/views/view/isVisibleInWindow.rhtml +148 -0
- data/frameworks/sproutcore/tests/views/view/scrollFrame.rhtml +468 -0
- data/frameworks/sproutcore/validators/credit_card.js +33 -13
- data/frameworks/sproutcore/validators/date.js +26 -6
- data/frameworks/sproutcore/validators/email.js +21 -3
- data/frameworks/sproutcore/validators/not_empty.js +11 -1
- data/frameworks/sproutcore/validators/number.js +18 -4
- data/frameworks/sproutcore/validators/password.js +12 -1
- data/frameworks/sproutcore/validators/validator.js +204 -194
- data/frameworks/sproutcore/views/{button.js → button/button.js} +96 -94
- data/frameworks/sproutcore/views/button/checkbox.js +29 -0
- data/frameworks/sproutcore/views/button/disclosure.js +42 -0
- data/frameworks/sproutcore/views/button/radio.js +29 -0
- data/frameworks/sproutcore/views/{collection.js → collection/collection.js} +1373 -1024
- data/frameworks/sproutcore/views/collection/grid.js +124 -46
- data/frameworks/sproutcore/views/collection/image_cell.js +17 -46
- data/frameworks/sproutcore/views/collection/list.js +45 -35
- data/frameworks/sproutcore/views/collection/source_list.js +386 -0
- data/frameworks/sproutcore/views/collection/table.js +118 -0
- data/frameworks/sproutcore/views/container.js +7 -2
- data/frameworks/sproutcore/views/error_explanation.js +23 -10
- data/frameworks/sproutcore/views/{checkbox_field.js → field/checkbox_field.js} +16 -6
- data/frameworks/sproutcore/views/field/field.js +219 -0
- data/frameworks/sproutcore/views/{radio_field.js → field/radio_field.js} +27 -12
- data/frameworks/sproutcore/views/{select_field.js → field/select_field.js} +116 -90
- data/frameworks/sproutcore/views/{text_field.js → field/text_field.js} +57 -8
- data/frameworks/sproutcore/views/{textarea_field.js → field/textarea_field.js} +13 -3
- data/frameworks/sproutcore/views/filter_button.js +2 -2
- data/frameworks/sproutcore/views/form.js +3 -3
- data/frameworks/sproutcore/views/image.js +128 -21
- data/frameworks/sproutcore/views/inline_text_editor.js +1 -1
- data/frameworks/sproutcore/views/label.js +149 -92
- data/frameworks/sproutcore/views/list_item.js +225 -0
- data/frameworks/sproutcore/views/menu_item.js +10 -4
- data/frameworks/sproutcore/views/pagination.js +11 -4
- data/frameworks/sproutcore/views/popup_button.js +25 -21
- data/frameworks/sproutcore/views/popup_menu.js +10 -4
- data/frameworks/sproutcore/views/progress.js +29 -16
- data/frameworks/sproutcore/views/radio_group.js +1 -1
- data/frameworks/sproutcore/views/scroll.js +60 -20
- data/frameworks/sproutcore/views/segmented.js +1 -1
- data/frameworks/sproutcore/views/slider.js +132 -0
- data/frameworks/sproutcore/views/source_list_group.js +130 -0
- data/frameworks/sproutcore/views/spinner.js +1 -1
- data/frameworks/sproutcore/views/split.js +292 -0
- data/frameworks/sproutcore/views/split_divider.js +109 -0
- data/frameworks/sproutcore/views/tab.js +1 -1
- data/frameworks/sproutcore/views/toolbar.js +1 -1
- data/frameworks/sproutcore/views/view.js +1272 -591
- data/generators/client/templates/english.lproj/body.css +1 -1
- data/generators/controller/controller_generator.rb +1 -1
- data/generators/controller/templates/test.rhtml +2 -1
- data/generators/model/templates/test.rhtml +1 -1
- data/generators/test/templates/test.rhtml +1 -1
- data/generators/view/templates/test.rhtml +1 -1
- data/jsdoc/templates/sproutcore/class.tmpl +241 -338
- data/jsdoc/templates/sproutcore/default.css +105 -155
- data/jsdoc/templates/sproutcore/index.tmpl +43 -8
- data/jsdoc/templates/sproutcore/publish.js +9 -4
- data/lib/sproutcore/build_tools/html_builder.rb +29 -13
- data/lib/sproutcore/build_tools/resource_builder.rb +1 -1
- data/lib/sproutcore/bundle.rb +86 -25
- data/lib/sproutcore/jsdoc.rb +2 -0
- data/lib/sproutcore/version.rb +1 -1
- data/lib/sproutcore/view_helpers.rb +36 -3
- data/tasks/deployment.rake +1 -1
- metadata +69 -36
- data/clients/sc_docs/english.lproj/icons/small/next.png +0 -0
- data/clients/sc_docs/english.lproj/icons/small/reset.png +0 -0
- data/clients/sc_docs/english.lproj/images/gradients.png +0 -0
- data/clients/sc_docs/english.lproj/images/toolbar.png +0 -0
- data/clients/sc_docs/english.lproj/warning.rhtml +0 -6
- data/clients/sc_test_runner/english.lproj/warning.rhtml +0 -6
- data/frameworks/sproutcore/english.lproj/buttons.png +0 -0
- data/frameworks/sproutcore/english.lproj/collections.css +0 -82
- data/frameworks/sproutcore/english.lproj/images/buttons-sprite.png +0 -0
- data/frameworks/sproutcore/views/collection/collection_item.js +0 -36
- data/frameworks/sproutcore/views/collection/text_cell.js +0 -128
- data/frameworks/sproutcore/views/field.js +0 -214
- data/frameworks/sproutcore/views/workspace.js +0 -170
- data/generators/client/templates/english.lproj/controls.css +0 -0
- data/generators/framework/templates/english.lproj/body.css +0 -0
- data/generators/framework/templates/english.lproj/body.rhtml +0 -3
- data/generators/framework/templates/english.lproj/controls.css +0 -0
- data/lib/sproutcore/view_helpers/button_views.rb +0 -302
- data/lib/sproutcore/view_helpers/core_views.rb +0 -292
- data/lib/sproutcore/view_helpers/form_views.rb +0 -258
- data/lib/sproutcore/view_helpers/menu_views.rb +0 -94
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
# :requires option in routes.rb.
|
|
23
23
|
-%>
|
|
24
24
|
<%= stylesheets_for_client %>
|
|
25
|
+
<%= @content_for_page_styles %>
|
|
25
26
|
</head>
|
|
26
27
|
<body class="<%= @theme || 'sc-theme' %>">
|
|
27
28
|
<% #
|
|
@@ -50,6 +51,7 @@
|
|
|
50
51
|
-%>
|
|
51
52
|
<!-- Include Site Javascript -->
|
|
52
53
|
<%= javascripts_for_client %>
|
|
54
|
+
<%= @content_for_page_javascript %>
|
|
53
55
|
|
|
54
56
|
<% #
|
|
55
57
|
# The following lines to the closing body tag must be included at the
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
############################################################
|
|
2
|
+
# MENU VIEW HELPERS
|
|
3
|
+
#
|
|
4
|
+
# The view helpers defined in this file help you create popup menus. You can
|
|
5
|
+
# define a menu in your RHTML helper to be used somewhere else with code like
|
|
6
|
+
# this:
|
|
7
|
+
#
|
|
8
|
+
|
|
9
|
+
# This is the quick way to define a menu item. Use this approach if you just
|
|
10
|
+
# want to create a menu with item names and perform an action:
|
|
11
|
+
#
|
|
12
|
+
# <% menu_view :action_menu, :validate=>'My.controller.validate' do |m| %>
|
|
13
|
+
# <%= m.item :item_1, 'Item 1', :action => 'doSomething' %>
|
|
14
|
+
# <%= m.separator_item %>
|
|
15
|
+
# <%= m.item :item_2, 'Item 2', :action => 'doAnother Thing' %>
|
|
16
|
+
# <% end %>
|
|
17
|
+
#
|
|
18
|
+
require_helpers 'core_views'
|
|
19
|
+
require_helpers 'button_views'
|
|
20
|
+
|
|
21
|
+
# This will create a popup menu. You should define internal outlets
|
|
22
|
+
# for the menu items. More options to follow.
|
|
23
|
+
view_helper :popup_menu_view do
|
|
24
|
+
var :tag, 'ul'
|
|
25
|
+
view 'SC.PopupMenuView'
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Creates a menu item view. Normally you don't want to create these
|
|
29
|
+
# directly. Instead use the menu_view helpers.
|
|
30
|
+
#
|
|
31
|
+
# OPTIONS:
|
|
32
|
+
# :action =>
|
|
33
|
+
# The action to invoke when the menu item is selected.
|
|
34
|
+
#
|
|
35
|
+
# :label =>
|
|
36
|
+
# The label for the menu item.
|
|
37
|
+
#
|
|
38
|
+
# :icon =>
|
|
39
|
+
# The icon for the menu item. No icon will show if this is not set.
|
|
40
|
+
#
|
|
41
|
+
# :shortcut =>
|
|
42
|
+
# The shortcut key for this menu item. Shortcuts are only active when
|
|
43
|
+
# the anchorview the popup menu is attached to is part of the in-focus
|
|
44
|
+
# pane. Shortcuts should be named in the standard input manager
|
|
45
|
+
# syntax like this: alt_ctrl_shift_k (for Alt-Ctrl-Shift-K)
|
|
46
|
+
#
|
|
47
|
+
# Note that on the web, Cmd (on the Mac) and Ctrl are equivalent.
|
|
48
|
+
# Always use ctrl when defining shortcuts.
|
|
49
|
+
#
|
|
50
|
+
# :enabled (bindable) =>
|
|
51
|
+
# Determines if the menu item will be enabled or not. This is generally
|
|
52
|
+
# handled by your validate method or through bindings.
|
|
53
|
+
#
|
|
54
|
+
# :selected (bindable) =>
|
|
55
|
+
# Determines if the menu item is selected or not. May also be a mixed
|
|
56
|
+
# state. This is generally handled by your validate method or through
|
|
57
|
+
# bindings.
|
|
58
|
+
#
|
|
59
|
+
# :alt =>
|
|
60
|
+
# name another item in this menu that is the alternate form of the
|
|
61
|
+
# receiver. If the alt item is enabled, this one will be hidden and
|
|
62
|
+
# visa versa.
|
|
63
|
+
#
|
|
64
|
+
view_helper :menu_item_view, :extends => :button_view do
|
|
65
|
+
|
|
66
|
+
# JavaScript
|
|
67
|
+
view 'SC.MenuItemView'
|
|
68
|
+
|
|
69
|
+
# HTML
|
|
70
|
+
var :tag, 'li'
|
|
71
|
+
var(:shortcut) { |sc| sc.split('_').map { |x| x.capitalize } * '-' }
|
|
72
|
+
css_class_names << 'menu-item'
|
|
73
|
+
|
|
74
|
+
@my_href = @href || 'javascript:;'
|
|
75
|
+
@href = nil
|
|
76
|
+
@inner_html = [
|
|
77
|
+
%(<a href="#{@my_href}">),
|
|
78
|
+
'<span class="sel">✓</span>',
|
|
79
|
+
'<span class="mixed">-</span>',
|
|
80
|
+
'<span class="inner">',
|
|
81
|
+
@image,
|
|
82
|
+
%(<span class="label">#{@label}</span>),
|
|
83
|
+
'</span>',
|
|
84
|
+
%(<span class="shortcut">#{@shortcut}</span>),
|
|
85
|
+
'</a>'
|
|
86
|
+
] * ''
|
|
87
|
+
|
|
88
|
+
end
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
// ==========================================================================
|
|
2
2
|
// SproutCore -- JavaScript Application Framework
|
|
3
|
-
// copyright 2006-
|
|
3
|
+
// copyright 2006-2008, Sprout Systems, Inc. and contributors.
|
|
4
4
|
// ==========================================================================
|
|
5
5
|
|
|
6
|
-
require('
|
|
6
|
+
require('mixins/observable');
|
|
7
7
|
|
|
8
8
|
// Make Arrays observable
|
|
9
9
|
Object.extend(Array.prototype, SC.Observable) ;
|
|
@@ -11,7 +11,7 @@ Object.extend(Array.prototype, SC.Observable) ;
|
|
|
11
11
|
SC.OUT_OF_RANGE_EXCEPTION = "Index out of range" ;
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
|
-
@namespace
|
|
14
|
+
@namespace
|
|
15
15
|
|
|
16
16
|
This module implements Observer-friendly Array-like behavior. This mixin is
|
|
17
17
|
picked up by the Array class as well as other controllers, etc. that want to
|
|
@@ -125,8 +125,9 @@ SC.Array = {
|
|
|
125
125
|
*/
|
|
126
126
|
removeAt: function(idx) {
|
|
127
127
|
if ((idx < 0) || (idx >= this.get('length'))) throw SC.OUT_OF_RANGE_EXCEPTION;
|
|
128
|
+
var ret = this.objectAt(idx) ;
|
|
128
129
|
this.replace(idx,1,[]);
|
|
129
|
-
return
|
|
130
|
+
return ret ;
|
|
130
131
|
},
|
|
131
132
|
|
|
132
133
|
/**
|
|
@@ -198,8 +199,35 @@ SC.Array = {
|
|
|
198
199
|
if (ary.objectAt(loc) != this.objectAt(loc)) return false ;
|
|
199
200
|
}
|
|
200
201
|
return true ;
|
|
202
|
+
},
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
Invoke the passed method and arguments on the member elements as long as
|
|
206
|
+
the value returned is the first argument.
|
|
207
|
+
|
|
208
|
+
@param {Object} retValue the expected return value
|
|
209
|
+
@param {String} methodName the method to call
|
|
210
|
+
@returns {Object} the return value of the last time the method was
|
|
211
|
+
invoked.
|
|
212
|
+
*/
|
|
213
|
+
invokeWhile: function(retValue, methodName) {
|
|
214
|
+
var ret ;
|
|
215
|
+
var args = $A(arguments) ;
|
|
216
|
+
retValue = args.shift() ;
|
|
217
|
+
methodName = args.shift() ;
|
|
218
|
+
|
|
219
|
+
try {
|
|
220
|
+
this._each(function(item) {
|
|
221
|
+
var func = (item) ? item[methodName] : null ;
|
|
222
|
+
ret = func.apply(item, args) ;
|
|
223
|
+
if (ret != retValue) throw $break ;
|
|
224
|
+
});
|
|
225
|
+
} catch (e) {
|
|
226
|
+
if (e != $break) throw e ;
|
|
227
|
+
}
|
|
228
|
+
return ret ;
|
|
201
229
|
}
|
|
202
|
-
|
|
230
|
+
|
|
203
231
|
} ;
|
|
204
232
|
|
|
205
233
|
// All arrays have the SC.Array mixin. Do this before we add the
|
|
@@ -279,21 +307,15 @@ Object.extend(Array.prototype, {
|
|
|
279
307
|
return ret ;
|
|
280
308
|
},
|
|
281
309
|
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
}
|
|
292
|
-
return ret ;
|
|
293
|
-
},
|
|
294
|
-
|
|
295
|
-
// This will invoke the passed method and arguments on the member elements
|
|
296
|
-
// as long as the value returned is the first argument.
|
|
310
|
+
/*
|
|
311
|
+
Invoke the passed method and arguments on the member elements as long as
|
|
312
|
+
the value returned is the first argument.
|
|
313
|
+
|
|
314
|
+
@param {Object} retValue the expected return value
|
|
315
|
+
@param {String} methodName the method to call
|
|
316
|
+
@returns {Object} the return value of the last time the method was
|
|
317
|
+
invoked.
|
|
318
|
+
*/
|
|
297
319
|
invokeWhile: function(retValue, methodName) {
|
|
298
320
|
var ret ;
|
|
299
321
|
var args = $A(arguments) ;
|
|
@@ -313,6 +335,20 @@ Object.extend(Array.prototype, {
|
|
|
313
335
|
return ret ;
|
|
314
336
|
},
|
|
315
337
|
|
|
338
|
+
map: function(iterator) {
|
|
339
|
+
var ret = [] ;
|
|
340
|
+
try {
|
|
341
|
+
for(var index=0;index<this.length;index++) {
|
|
342
|
+
var item = this[index] ;
|
|
343
|
+
ret.push((iterator || Prototype.K).call(item,item,index)) ;
|
|
344
|
+
} ;
|
|
345
|
+
} catch (e) {
|
|
346
|
+
if (e != $break) throw e ;
|
|
347
|
+
}
|
|
348
|
+
return ret ;
|
|
349
|
+
},
|
|
350
|
+
|
|
351
|
+
|
|
316
352
|
// If you ask for an unknown property, then try to collect the value
|
|
317
353
|
// from member items.
|
|
318
354
|
unknownProperty: function(key, value) {
|
|
@@ -328,17 +364,12 @@ Array.prototype.collect = Array.prototype.map ;
|
|
|
328
364
|
// Returns the passed item as an array. If the item is already an array,
|
|
329
365
|
// it is returned as is. If it is not an array, it is placed into one. If
|
|
330
366
|
// it is null, an empty array is returned.
|
|
331
|
-
Array.asArray = function (array)
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
{
|
|
367
|
+
Array.asArray = function (array) {
|
|
368
|
+
if(array &&
|
|
369
|
+
((array.length === undefined) || ($type(array) == T_FUNCTION))) {
|
|
335
370
|
return [array];
|
|
336
371
|
}
|
|
337
|
-
|
|
338
|
-
{
|
|
339
|
-
return array;
|
|
340
|
-
}
|
|
341
|
-
return [];
|
|
372
|
+
return (array) ? array : [] ;
|
|
342
373
|
};
|
|
343
374
|
|
|
344
375
|
// Alias for asArray
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
// ========================================================================
|
|
2
|
+
// SproutCore
|
|
3
|
+
// copyright 2006-2008 Sprout Systems, Inc.
|
|
4
|
+
// ========================================================================
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
Indicates a value has a mixed state of both on and off.
|
|
8
|
+
*/
|
|
9
|
+
SC.MIXED_STATE = '__MIXED__' ;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
@namespace
|
|
13
|
+
|
|
14
|
+
A Control is a view that also implements some basic state functionality.
|
|
15
|
+
Apply this mixin to any view that you want to have standard control
|
|
16
|
+
functionality including showing a selected state, enabled state, focus
|
|
17
|
+
state, etc.
|
|
18
|
+
|
|
19
|
+
h2. About Values and Content
|
|
20
|
+
|
|
21
|
+
Controls typically are used to represent a single value, such as a number,
|
|
22
|
+
boolean or string. The value a control is managing is typically stored in
|
|
23
|
+
a "value" property. You will typically use the value property when working
|
|
24
|
+
with controls such as buttons and text fields in a form.
|
|
25
|
+
|
|
26
|
+
An alternative way of working with a control is to use it to manage some
|
|
27
|
+
specific aspect of a content object. For example, you might use a label
|
|
28
|
+
view control to display the "name" property of a Contact record. This
|
|
29
|
+
approach is often necessary when using the control as part of a collection
|
|
30
|
+
view.
|
|
31
|
+
|
|
32
|
+
You can use the content-approach to work with a control by setting the
|
|
33
|
+
"content" and "contentValueKey" properties of the control. The
|
|
34
|
+
"content" property is the content object you want to manage, while the
|
|
35
|
+
"contentValueKey" is the name of the property on the content object
|
|
36
|
+
you want the control to display.
|
|
37
|
+
|
|
38
|
+
The default implementation of the Control mixin will essentially map the
|
|
39
|
+
contentValueKey of a content object to the value property of the
|
|
40
|
+
control. Thus if you are writing a custom control yourself, you can simply
|
|
41
|
+
work with the value property and the content object support will come for
|
|
42
|
+
free. Just write an observer for the value property and update your
|
|
43
|
+
view accordingly.
|
|
44
|
+
|
|
45
|
+
If you are working with a control that needs to display multiple aspects
|
|
46
|
+
of a single content object (for example showing an icon and label), then
|
|
47
|
+
you can override the contentValueDidChange() method instead of observing
|
|
48
|
+
the value property. This method will be called anytime _any_ property
|
|
49
|
+
on the content object changes. You should use this method to check the
|
|
50
|
+
properties you care about on the content object and update your view if
|
|
51
|
+
anything you care about has changed.
|
|
52
|
+
|
|
53
|
+
h2. Delegate Support
|
|
54
|
+
|
|
55
|
+
Controls can optionally get the contentDisplayProperty from a
|
|
56
|
+
displayDelegate, if it is set. The displayDelegate is often used to
|
|
57
|
+
delegate common display-related configurations such as which content value
|
|
58
|
+
to show. Anytime your control is shown as part of a collection view, the
|
|
59
|
+
collection view will be automatically set as its displayDelegate.
|
|
60
|
+
|
|
61
|
+
*/
|
|
62
|
+
SC.Control = {
|
|
63
|
+
|
|
64
|
+
initMixin: function() {
|
|
65
|
+
this._contentObserver(); // setup content observing if needed.
|
|
66
|
+
this.isSelectedObserver() ;
|
|
67
|
+
this.isEnabledObserver() ;
|
|
68
|
+
this.isFocusedObserver();
|
|
69
|
+
},
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
Set to true when the item is selected.
|
|
73
|
+
|
|
74
|
+
This property is observable and bindable.
|
|
75
|
+
*/
|
|
76
|
+
isSelected: false,
|
|
77
|
+
isSelectedBindingDefault: SC.Binding.OneWayBool,
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
Set to true when the item is enabled.
|
|
81
|
+
|
|
82
|
+
This property is observable and bindable.
|
|
83
|
+
*/
|
|
84
|
+
isEnabled: true,
|
|
85
|
+
isEnabledBindingDefault: SC.Binding.OneWayBool,
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
The value represented by this control.
|
|
89
|
+
|
|
90
|
+
Most controls represent a value of some type, such as a number, string
|
|
91
|
+
or image URL. This property should hold that value. It is bindable
|
|
92
|
+
and observable. Changing this value will immediately change the
|
|
93
|
+
appearance of the control. Likewise, editing the control
|
|
94
|
+
will immediately change this value.
|
|
95
|
+
|
|
96
|
+
If instead of setting a single value on a control, you would like to
|
|
97
|
+
set a content object and have the control display a single property
|
|
98
|
+
of that control, then you should use the content property instead.
|
|
99
|
+
*/
|
|
100
|
+
value: null,
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
The content object represented by this control.
|
|
104
|
+
|
|
105
|
+
Often you need to use a control to display some single aspect of an
|
|
106
|
+
object, especially if you are using the control as an item view in a
|
|
107
|
+
collection view.
|
|
108
|
+
|
|
109
|
+
In those cases, you can set the content and contentValueKey for the
|
|
110
|
+
control. This will cause the control to observe the content object for
|
|
111
|
+
changes to the value property and then set the value of that property
|
|
112
|
+
on the "value" property of this object.
|
|
113
|
+
|
|
114
|
+
Note that unless you are using this control as part of a form or
|
|
115
|
+
collection view, then it would be better to instead bind the value of
|
|
116
|
+
the control directly to a controller property.
|
|
117
|
+
*/
|
|
118
|
+
content: null,
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
The property on the content object that would want to represent the
|
|
122
|
+
value of this control. This property should only be set before the
|
|
123
|
+
content object is first set. If you have a displayDelegate, then
|
|
124
|
+
you can also use the contentValueKey of the displayDelegate.
|
|
125
|
+
*/
|
|
126
|
+
contentValueKey: null,
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
Invoked whenever any property on the content object changes.
|
|
130
|
+
|
|
131
|
+
The default implementation will update the value property of the view
|
|
132
|
+
if the contentValueKey property has changed. You can override this
|
|
133
|
+
method to implement whatever additional changes you would like.
|
|
134
|
+
|
|
135
|
+
The key will typically contain the name of the property that changed or
|
|
136
|
+
'*' if the content object itself has changed. You should generally do
|
|
137
|
+
a total reset of '*' is changed.
|
|
138
|
+
|
|
139
|
+
@param {Object} target the content object
|
|
140
|
+
@param {String} key the property that changes
|
|
141
|
+
*/
|
|
142
|
+
contentPropertyDidChange: function(target, key) {
|
|
143
|
+
if (!!this._contentValueKey && ((key == this._contentValueKey) || (key == '*'))) {
|
|
144
|
+
var content = this.get('content') ;
|
|
145
|
+
var value = (content) ? content.get(this._contentValueKey) : null;
|
|
146
|
+
if (value != this._contentValue) {
|
|
147
|
+
this._contentValue = value ;
|
|
148
|
+
this.set('value', value) ;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
},
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
Relays changes to the value back to the content object if you are using
|
|
155
|
+
a content object.
|
|
156
|
+
|
|
157
|
+
This observer is triggered whenever the value changes. It will only do
|
|
158
|
+
something if it finds you are using the content property and
|
|
159
|
+
contentValueKey and the new value does not match the old value of the
|
|
160
|
+
content object.
|
|
161
|
+
|
|
162
|
+
If you are using contentValueKey in some other way than typically
|
|
163
|
+
implemented by this mixin, then you may want to override this method as
|
|
164
|
+
well.
|
|
165
|
+
*/
|
|
166
|
+
updateContentWithValueObserver: function() {
|
|
167
|
+
if (!this._contentValueKey) return; // do nothing if disabled
|
|
168
|
+
|
|
169
|
+
// get value. return if value matches current content value.
|
|
170
|
+
// this avoids infinite loops where setting the value from the content
|
|
171
|
+
// in turns sets the content and so on.
|
|
172
|
+
var value = this.get('value') ;
|
|
173
|
+
if (value == this._contentValue) return ;
|
|
174
|
+
|
|
175
|
+
var content = this.get('content') ;
|
|
176
|
+
if (!content) return; // do nothing if no content.
|
|
177
|
+
|
|
178
|
+
// passed all of our checks, update the content (and the _contentValue
|
|
179
|
+
// to avoid infinite loops)
|
|
180
|
+
this._contentValue = value ;
|
|
181
|
+
content.set(this._contentValueKey, value) ;
|
|
182
|
+
|
|
183
|
+
}.observes('value'),
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
Default observer for selected state changes
|
|
187
|
+
|
|
188
|
+
The default will simply add either a "mixed" or "sel" class name to the
|
|
189
|
+
root element of your view based on the state. You can override this with
|
|
190
|
+
your own behavior if you prefer.
|
|
191
|
+
*/
|
|
192
|
+
isSelectedObserver: function() {
|
|
193
|
+
var sel = this.get('isSelected') ;
|
|
194
|
+
this.setClassName('mixed', sel == SC.MIXED_STATE) ;
|
|
195
|
+
this.setClassName('sel', sel && (sel != SC.MIXED_STATE)) ;
|
|
196
|
+
}.observes('isSelected'),
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
Default observer for the isEnabled state.
|
|
200
|
+
|
|
201
|
+
The default will simply add or remove a "disabled" class name to the root
|
|
202
|
+
element of your view based on the state. You can override this with your
|
|
203
|
+
own behavior if you prefer.
|
|
204
|
+
*/
|
|
205
|
+
isEnabledObserver: function() {
|
|
206
|
+
var disabled = !this.get('isEnabled') ;
|
|
207
|
+
this.setClassName('disabled', disabled);
|
|
208
|
+
|
|
209
|
+
// set disabled attr as well if relevant
|
|
210
|
+
if (this.rootElement && (this.rootElement.disabled !== undefined) && (this.rootElement.disabled != disabled)) {
|
|
211
|
+
this.rootElement.disabled = disabled ;
|
|
212
|
+
}
|
|
213
|
+
}.observes('isEnabled'),
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
Default observer for the isFirstResponder state.
|
|
217
|
+
|
|
218
|
+
The default will add or remove a "focus" class name ot the root element
|
|
219
|
+
of your view based on the state. You can override this with your own
|
|
220
|
+
behavior if you prefer.
|
|
221
|
+
*/
|
|
222
|
+
isFocusedObserver: function() {
|
|
223
|
+
this.setClassName('focus', !!this.get('isFirstResponder')) ;
|
|
224
|
+
}.observes('isFirstResponder'),
|
|
225
|
+
|
|
226
|
+
// This should be null so that if content is also null, the
|
|
227
|
+
// _contentObserver won't do anything on init.
|
|
228
|
+
_content: null,
|
|
229
|
+
|
|
230
|
+
/** @private
|
|
231
|
+
Observes when a content object has changed and handles notifying
|
|
232
|
+
changes to the value of the content object.
|
|
233
|
+
*/
|
|
234
|
+
_contentObserver: function() {
|
|
235
|
+
var content = this.get('content') ;
|
|
236
|
+
if (this._content == content) return; // nothing changed
|
|
237
|
+
|
|
238
|
+
// create bound observer function
|
|
239
|
+
if (!this._boundContentPropertyDidChangeObserver) {
|
|
240
|
+
this._boundContentPropertyDidChangeObserver = this.contentPropertyDidChange.bind(this) ;
|
|
241
|
+
}
|
|
242
|
+
var f = this._boundContentPropertyDidChangeObserver ;
|
|
243
|
+
|
|
244
|
+
// remove an observer from the old content if necessary
|
|
245
|
+
if (this._content && this._content.removeObserver) {
|
|
246
|
+
this._content.removeObserver('*', f) ;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
// cache for future use
|
|
250
|
+
var del = this.displayDelegate ;
|
|
251
|
+
this._contentValueKey = this.getDelegateProperty(del, 'contentValueKey');
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
// add observer to new content if necessary.
|
|
255
|
+
this._content = content ;
|
|
256
|
+
if (this._content && this._content.addObserver) {
|
|
257
|
+
this._content.addObserver('*', f) ;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// notify that value did change.
|
|
261
|
+
this.contentPropertyDidChange(this._content, '*') ;
|
|
262
|
+
|
|
263
|
+
}.observes('content')
|
|
264
|
+
|
|
265
|
+
};
|