sproutcore 0.9.1 → 0.9.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
@@ -1,21 +1,34 @@
|
|
1
1
|
// ========================================================================
|
2
2
|
// SproutCore
|
3
|
-
// copyright 2006-
|
3
|
+
// copyright 2006-2008 Sprout Systems, Inc.
|
4
4
|
// ========================================================================
|
5
5
|
|
6
|
-
require('views/field') ;
|
6
|
+
require('views/field/field') ;
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
8
|
+
/**
|
9
|
+
@class
|
10
|
+
|
11
|
+
A text field is an input element with type "text". This view adds support
|
12
|
+
for hinted values, etc.
|
13
|
+
|
14
|
+
@extends SC.FieldView
|
15
|
+
@author Charles Jolley
|
16
|
+
*/
|
17
|
+
SC.TextFieldView = SC.FieldView.extend(
|
18
|
+
/** @scope SC.TextFieldView.prototype */ {
|
11
19
|
|
12
20
|
emptyElement: '<input type="text" value="" />',
|
13
21
|
|
14
22
|
// PROPERTIES
|
15
|
-
|
23
|
+
|
24
|
+
/**
|
25
|
+
The hint to display while the field is not active. Can be a loc key.
|
26
|
+
*/
|
16
27
|
hint: null,
|
17
28
|
|
18
|
-
|
29
|
+
/**
|
30
|
+
automatically set to YES if the hint is currently showing.
|
31
|
+
*/
|
19
32
|
isHintShowing: false,
|
20
33
|
|
21
34
|
|
@@ -59,7 +72,10 @@ SC.TextFieldView = SC.FieldView.extend({
|
|
59
72
|
this.resignFirstResponder() ;
|
60
73
|
}
|
61
74
|
},
|
62
|
-
|
75
|
+
|
76
|
+
/**
|
77
|
+
tied to the isEnabled state
|
78
|
+
*/
|
63
79
|
acceptsFirstResponder: function() {
|
64
80
|
return this.get('isEnabled');
|
65
81
|
}.property('isEnabled'),
|
@@ -70,6 +86,7 @@ SC.TextFieldView = SC.FieldView.extend({
|
|
70
86
|
|
71
87
|
// when we become first responder, focus the text field if needed and
|
72
88
|
// hide the hint text.
|
89
|
+
/** @private */
|
73
90
|
didBecomeFirstResponder: function() {
|
74
91
|
|
75
92
|
// focus the text field.
|
@@ -87,6 +104,7 @@ SC.TextFieldView = SC.FieldView.extend({
|
|
87
104
|
|
88
105
|
// when we lose first responder, blur the text field if needed and show
|
89
106
|
// the hint text if needed.
|
107
|
+
/** @private */
|
90
108
|
willLoseFirstResponder: function() {
|
91
109
|
|
92
110
|
if (this._isFocused) {
|
@@ -116,16 +134,19 @@ SC.TextFieldView = SC.FieldView.extend({
|
|
116
134
|
},
|
117
135
|
|
118
136
|
// field value updates...
|
137
|
+
/** @private */
|
119
138
|
getFieldValue: function() {
|
120
139
|
return this._value ;
|
121
140
|
},
|
122
141
|
|
142
|
+
/** @private */
|
123
143
|
setFieldValue: function(value) {
|
124
144
|
if (this._value == value) return ;
|
125
145
|
this._value = value ;
|
126
146
|
this._updateFieldHint() ;
|
127
147
|
},
|
128
148
|
|
149
|
+
/** @private */
|
129
150
|
mouseDown: function(e)
|
130
151
|
{
|
131
152
|
e._stopWhenHandled = false;
|
@@ -133,6 +154,7 @@ SC.TextFieldView = SC.FieldView.extend({
|
|
133
154
|
},
|
134
155
|
|
135
156
|
// trap key-press events and notify as needed.
|
157
|
+
/** @private */
|
136
158
|
keyDown: function(evt) {
|
137
159
|
if (this._value != this.rootElement.value) {
|
138
160
|
this._value = this.rootElement.value ;
|
@@ -143,6 +165,7 @@ SC.TextFieldView = SC.FieldView.extend({
|
|
143
165
|
//return false;
|
144
166
|
},
|
145
167
|
|
168
|
+
/** @private */
|
146
169
|
keyUp: function() {
|
147
170
|
if (this._value != this.rootElement.value) {
|
148
171
|
this._value = this.rootElement.value ;
|
@@ -162,18 +185,44 @@ SC.TextFieldView = SC.FieldView.extend({
|
|
162
185
|
// THESE ARE DUMMY IMPLEMENTATIONS OF THE REPONDER METHODS FOR KEYBOARD
|
163
186
|
// ACTIONS HANDLED BY THE BROWSER. This avoids having the responder
|
164
187
|
// bubble up these items.
|
188
|
+
|
189
|
+
/** @private */
|
165
190
|
deleteBackward: function(evt) { evt._stopWhenHandled = false; return true; },
|
191
|
+
|
192
|
+
/** @private */
|
166
193
|
deleteForward: function(evt) { evt._stopWhenHandled = false; return true; },
|
194
|
+
|
195
|
+
/** @private */
|
167
196
|
moveLeft: function(evt) { evt._stopWhenHandled = false; return true; },
|
197
|
+
|
198
|
+
/** @private */
|
168
199
|
moveRight: function(evt) { evt._stopWhenHandled = false; return true; },
|
200
|
+
|
201
|
+
/** @private */
|
169
202
|
moveUp: function(evt) { evt._stopWhenHandled = false; return true; },
|
203
|
+
|
204
|
+
/** @private */
|
170
205
|
moveDown: function(evt) { evt._stopWhenHandled = false; return true; },
|
206
|
+
|
207
|
+
/** @private */
|
171
208
|
moveLeftAndModifySelection: function(evt) { evt._stopWhenHandled = false; return true; },
|
209
|
+
|
210
|
+
/** @private */
|
172
211
|
moveRightAndModifySelection: function(evt) { evt._stopWhenHandled = false; return true; },
|
212
|
+
|
213
|
+
/** @private */
|
173
214
|
moveUpAndModifySelection: function(evt) { evt._stopWhenHandled = false; return true; },
|
215
|
+
|
216
|
+
/** @private */
|
174
217
|
moveDownAndModifySelection: function(evt) { evt._stopWhenHandled = false; return true; },
|
218
|
+
|
219
|
+
/** @private */
|
175
220
|
moveToBeginningOfDocument: function(evt) { evt._stopWhenHandled = false; return true; },
|
221
|
+
|
222
|
+
/** @private */
|
176
223
|
moveToEndOfDocument: function(evt) { evt._stopWhenHandled = false; return true; },
|
224
|
+
|
225
|
+
/** @private */
|
177
226
|
selectAll: function(evt) { evt._stopWhenHandled = false; return true; }
|
178
227
|
|
179
228
|
}) ;
|
@@ -1,11 +1,21 @@
|
|
1
1
|
// ========================================================================
|
2
2
|
// SproutCore
|
3
|
-
// copyright 2006-
|
3
|
+
// copyright 2006-2008 Sprout Systems, Inc.
|
4
4
|
// ========================================================================
|
5
5
|
|
6
|
-
require('views/text_field') ;
|
6
|
+
require('views/field/text_field') ;
|
7
7
|
|
8
|
-
|
8
|
+
/**
|
9
|
+
@class
|
10
|
+
|
11
|
+
Manages a text area field.
|
12
|
+
|
13
|
+
@extends SC.TextFieldView
|
14
|
+
@author Skip Baney
|
15
|
+
@version 1.0
|
16
|
+
*/
|
17
|
+
SC.TextareaFieldView = SC.TextFieldView.extend(
|
18
|
+
/** @scope SC.TextareaFieldView.prototype */ {
|
9
19
|
|
10
20
|
emptyElement: '<textarea></textarea>',
|
11
21
|
|
@@ -1,9 +1,9 @@
|
|
1
1
|
// ========================================================================
|
2
2
|
// SproutCore
|
3
|
-
// copyright 2006-
|
3
|
+
// copyright 2006-2008 Sprout Systems, Inc.
|
4
4
|
// ========================================================================
|
5
5
|
|
6
|
-
require('views/button') ;
|
6
|
+
require('views/button/button') ;
|
7
7
|
|
8
8
|
// A filter button sets a filter property to whatever you specifiy. It
|
9
9
|
// also binds to the same property and updates its isSelected state based
|
@@ -1,11 +1,11 @@
|
|
1
1
|
// ========================================================================
|
2
2
|
// SproutCore
|
3
|
-
// copyright 2006-
|
3
|
+
// copyright 2006-2008 Sprout Systems, Inc.
|
4
4
|
// ========================================================================
|
5
5
|
|
6
6
|
require('views/view') ;
|
7
|
-
require('views/button') ;
|
8
|
-
require('views/text_field') ;
|
7
|
+
require('views/button/button') ;
|
8
|
+
require('views/field/text_field') ;
|
9
9
|
|
10
10
|
// FormView provides a simple way for you to "stage" input by capturing
|
11
11
|
// data from your views into the form before it is set on your actual
|
@@ -1,38 +1,134 @@
|
|
1
1
|
// ========================================================================
|
2
2
|
// SproutCore
|
3
|
-
// copyright 2006-
|
3
|
+
// copyright 2006-2008 Sprout Systems, Inc.
|
4
4
|
// ========================================================================
|
5
5
|
|
6
6
|
require('views/view') ;
|
7
|
+
require('mixins/control') ;
|
7
8
|
|
8
9
|
lc_cnt = 0 ;
|
9
10
|
|
10
|
-
SC.
|
11
|
-
|
11
|
+
SC.IMAGE_STATE_NONE = 'none';
|
12
|
+
SC.IMAGE_STATE_LOADING = 'loading';
|
13
|
+
SC.IMAGE_STATE_LOADED = 'loaded';
|
14
|
+
SC.IMAGE_STATE_FAILED = 'failed';
|
15
|
+
|
16
|
+
/**
|
17
|
+
URL to a transparent GIF. Used for spriting.
|
18
|
+
*/
|
19
|
+
SC.BLANK_IMAGE_URL = static_url('blank.gif');
|
20
|
+
|
21
|
+
/**
|
22
|
+
@class
|
23
|
+
|
24
|
+
Displays an image in the browser.
|
25
|
+
|
26
|
+
The ImageView can be used to efficiently display images in the browser.
|
27
|
+
It includes a built in support for a number of features that can improve
|
28
|
+
your page load time if you use a lot of images including a image loading
|
29
|
+
queue and automatic support for CSS spriting.
|
30
|
+
|
31
|
+
@extends SC.View
|
32
|
+
@extends SC.Control
|
33
|
+
@author Charles Jolley
|
34
|
+
*/
|
35
|
+
SC.ImageView = SC.View.extend(SC.Control,
|
36
|
+
/** @scope SC.ImageView.prototype */ {
|
12
37
|
|
13
|
-
|
38
|
+
/** Image views contain an img tag. */
|
39
|
+
emptyElement: '<img src="%@" class="sc-image-view" />'.fmt(SC.BLANK_IMAGE_URL),
|
14
40
|
|
15
|
-
|
16
|
-
|
41
|
+
/**
|
42
|
+
Current load status of the image.
|
43
|
+
|
44
|
+
This status changes as an image is loaded from the server. If spriting
|
45
|
+
is used, this will always be loaded. Must be one of the following
|
46
|
+
constants: SC.IMAGE_STATE_NONE, SC.IMAGE_STATE_LOADING,
|
47
|
+
SC.IMAGE_STATE_LOADED, SC.IMAGE_STATE_FAILED
|
48
|
+
*/
|
49
|
+
status: SC.IMAGE_STATE_NONE,
|
17
50
|
|
18
|
-
|
51
|
+
/**
|
52
|
+
A url or CSS class name.
|
53
|
+
|
54
|
+
This is the image you want the view to display. It should be either a
|
55
|
+
url or css class name. You can also set the content and
|
56
|
+
contentValueKey properties to have this value extracted
|
57
|
+
automatically.
|
58
|
+
|
59
|
+
If you want to use CSS spriting, set this value to a CSS class name. If
|
60
|
+
you need to use multiple class names to set your icon, separate them by
|
61
|
+
spaces.
|
62
|
+
*/
|
63
|
+
value: null,
|
64
|
+
_value: null,
|
65
|
+
|
66
|
+
/**
|
67
|
+
Invoked whenever the content or value changes. (To be removed in
|
68
|
+
SproutCore 1.0)
|
69
|
+
|
70
|
+
This method is no longer necessary since we have the standard SC.Control
|
71
|
+
behavior.
|
72
|
+
|
73
|
+
@deprecated
|
74
|
+
@param {Object} content The content object.
|
75
|
+
@returns {String} the URL or CSS class name
|
76
|
+
*/
|
19
77
|
transform: function(content) { return content; },
|
20
78
|
|
21
|
-
|
22
|
-
|
23
|
-
|
79
|
+
valueObserver: function() {
|
80
|
+
|
81
|
+
// get the new URL.
|
82
|
+
var value = this.get('value') ;
|
83
|
+
|
84
|
+
// invoke the old transform method if it is defined
|
85
|
+
if (this.transform !== SC.ImageView.prototype.transform) {
|
86
|
+
var content = this.get('content') || '' ;
|
87
|
+
value = this.transform(content) ;
|
88
|
+
}
|
89
|
+
|
90
|
+
// if the value has not changed, do nothing.
|
91
|
+
if (value == this._value) return ;
|
24
92
|
|
25
|
-
if
|
93
|
+
// if the old value was a class name, then we need to remove it.
|
94
|
+
if (this._value && this._value.length>0 && !SC.ImageView.valueIsUrl(this._value)) {
|
95
|
+
var classNames = this._value.split(' ') ;
|
96
|
+
var idx = classNames.length ;
|
97
|
+
while(--idx >= 0) {
|
98
|
+
this.removeClassName(classNames[idx]);
|
99
|
+
}
|
100
|
+
this.removeClassName('sc-sprite') ;
|
101
|
+
}
|
102
|
+
this._value = value ;
|
103
|
+
|
104
|
+
// if the new value is empty, just clear the img.
|
105
|
+
if (!value || value.length == 0) {
|
106
|
+
this.rootElement.src = SC.BLANK_IMAGE_URL;
|
107
|
+
this.set('status', SC.IMAGE_STATE_NONE) ;
|
108
|
+
|
109
|
+
// if a new value was set that is a URL, load the image URL.
|
110
|
+
} else if (SC.ImageView.valueIsUrl(value)) {
|
26
111
|
this.beginPropertyChanges() ;
|
27
|
-
this.set('status',
|
28
|
-
SC.imageCache.loadImage(
|
112
|
+
this.set('status', SC.IMAGE_STATE_LOADING) ;
|
113
|
+
SC.imageCache.loadImage(value, this, this._onLoadComplete) ;
|
29
114
|
this.endPropertyChanges() ;
|
115
|
+
|
116
|
+
// if the new is a CSS class name, set an empty image and add class name
|
30
117
|
} else {
|
31
|
-
|
32
|
-
|
118
|
+
var classNames = value.split(' ');
|
119
|
+
var idx = classNames.length ;
|
120
|
+
while(--idx >= 0) this.addClassName(classNames[idx]) ;
|
121
|
+
this.addClassName('sc-sprite') ;
|
122
|
+
this.rootElement.src = SC.BLANK_IMAGE_URL ;
|
123
|
+
this.set('status', SC.IMAGE_STATE_LOADED) ;
|
33
124
|
}
|
34
|
-
}.observes('
|
125
|
+
}.observes('value'),
|
35
126
|
|
127
|
+
|
128
|
+
/**
|
129
|
+
Invoked once an image loads. If an image has already been loaded,
|
130
|
+
this method will be invoked immediately.
|
131
|
+
*/
|
36
132
|
_onLoadComplete: function(url, status, img) {
|
37
133
|
this.beginPropertyChanges() ;
|
38
134
|
this.set('imageWidth', parseInt(img.width,0)) ;
|
@@ -40,7 +136,7 @@ SC.ImageView = SC.View.extend({
|
|
40
136
|
this.set('status',status) ;
|
41
137
|
this.endPropertyChanges() ;
|
42
138
|
|
43
|
-
if (status ==
|
139
|
+
if (status == SC.IMAGE_STATE_LOADED) {
|
44
140
|
if (this.imageDidLoad) this.imageDidLoad(url) ;
|
45
141
|
this.rootElement.src = url ;
|
46
142
|
} else {
|
@@ -50,6 +146,7 @@ SC.ImageView = SC.View.extend({
|
|
50
146
|
|
51
147
|
init: function() {
|
52
148
|
arguments.callee.base.apply(this,arguments) ;
|
149
|
+
this.valueObserver() ;
|
53
150
|
if (this.rootElement.src) {
|
54
151
|
this.set('imageWidth',parseInt(this.rootElement.width,0)) ;
|
55
152
|
this.set('imageHeight',parseInt(this.rootElement.height,0)) ;
|
@@ -58,9 +155,19 @@ SC.ImageView = SC.View.extend({
|
|
58
155
|
|
59
156
|
}) ;
|
60
157
|
|
61
|
-
|
62
|
-
|
63
|
-
|
158
|
+
/**
|
159
|
+
Returns YES if the passed value looks like an URL and not a CSS class
|
160
|
+
name.
|
161
|
+
*/
|
162
|
+
SC.ImageView.valueIsUrl = function(value) {
|
163
|
+
return (value.indexOf('/') >= 0) || (value.indexOf('.') >= 0) ;
|
164
|
+
} ;
|
165
|
+
|
166
|
+
/**
|
167
|
+
The image cache will create Image objects to preload a set of
|
168
|
+
images. This will control the number of images being loaded to maximize
|
169
|
+
browser throughput.
|
170
|
+
*/
|
64
171
|
SC.imageCache = SC.Object.create({
|
65
172
|
|
66
173
|
// this restricts the maximum number of images that can load in.
|
@@ -83,7 +190,7 @@ SC.imageCache = SC.Object.create({
|
|
83
190
|
if (dta.img == null) {
|
84
191
|
this._queue.push(dta) ;
|
85
192
|
if (!this._imgTimeout) {
|
86
|
-
this._imgTimeout =
|
193
|
+
this._imgTimeout = this.invokeLater(this.loadNextImage, 100) ;
|
87
194
|
}
|
88
195
|
}
|
89
196
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
// ========================================================================
|
2
2
|
// SproutCore
|
3
|
-
// copyright 2006-
|
3
|
+
// copyright 2006-2008 Sprout Systems, Inc.
|
4
4
|
// ========================================================================
|
5
5
|
|
6
6
|
SC.inlineTextEditor = SC.View.extend({
|
@@ -1,22 +1,113 @@
|
|
1
1
|
// ========================================================================
|
2
2
|
// SproutCore
|
3
|
-
// copyright 2006-
|
3
|
+
// copyright 2006-2008 Sprout Systems, Inc.
|
4
4
|
// ========================================================================
|
5
5
|
|
6
6
|
require('views/view') ;
|
7
|
+
require('mixins/control') ;
|
8
|
+
require('mixins/delegate_support');
|
7
9
|
|
8
|
-
|
10
|
+
/**
|
11
|
+
@class
|
12
|
+
|
13
|
+
Displays a static string of text.
|
14
|
+
|
15
|
+
You use a label view anytime you need to display a static string of text
|
16
|
+
or to display text that may need to be edited using only an inline control.
|
17
|
+
|
18
|
+
@extends SC.View
|
19
|
+
@extends SC.Control
|
20
|
+
@extends SC.DelegateSupport
|
21
|
+
@author Charles Jolley
|
22
|
+
@version 1.0
|
23
|
+
*/
|
24
|
+
SC.LabelView = SC.View.extend(SC.DelegateSupport, SC.Control,
|
25
|
+
/** @scope SC.LabelView.prototype */ {
|
26
|
+
|
27
|
+
emptyElement: '<span class="sc-label-view"></span>',
|
9
28
|
|
10
29
|
/**
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
30
|
+
If true, value will be escaped to avoid scripting attacks.
|
31
|
+
|
32
|
+
This is a default value that can be overridden by the
|
33
|
+
settings on the owner view.
|
34
|
+
*/
|
35
|
+
escapeHtml: true,
|
36
|
+
|
37
|
+
/**
|
38
|
+
If true, then the value will be localized.
|
39
|
+
|
40
|
+
This is a default default that can be overidden by the
|
41
|
+
settings in the owner view.
|
42
|
+
*/
|
43
|
+
localize: false,
|
44
|
+
|
15
45
|
/**
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
46
|
+
Set this to a validator or to a function and the value
|
47
|
+
will be passed through it before being set.
|
48
|
+
|
49
|
+
This is a default default that can be overidden by the
|
50
|
+
settings in the owner view.
|
51
|
+
*/
|
52
|
+
formatter: null,
|
53
|
+
|
54
|
+
/**
|
55
|
+
The value of the label.
|
56
|
+
|
57
|
+
You may also set the value using a content object and a contentValueKey.
|
58
|
+
|
59
|
+
@field {String}
|
60
|
+
*/
|
61
|
+
value: '',
|
62
|
+
|
63
|
+
/**
|
64
|
+
[RO] The value that will actually be displayed.
|
65
|
+
|
66
|
+
This property is dynamically computed by applying localization,
|
67
|
+
string conversion and other normalization utilities.
|
68
|
+
|
69
|
+
@field
|
70
|
+
*/
|
71
|
+
displayValue: function() {
|
72
|
+
var value = this.get('value') ;
|
73
|
+
|
74
|
+
// 1. apply the formatter
|
75
|
+
var formatter = this.getDelegateProperty(this.displayDelegate, 'formatter') ;
|
76
|
+
if (formatter) {
|
77
|
+
var formattedValue = ($type(formatter) == T_FUNCTION) ? formatter(value, this) : formatter.fieldValueForObject(value, this) ;
|
78
|
+
if (formattedValue != null) value = formattedValue ;
|
79
|
+
}
|
80
|
+
|
81
|
+
// 2. If the returned value is an array, convert items to strings and
|
82
|
+
// join with commas.
|
83
|
+
if ($type(value) == T_ARRAY) {
|
84
|
+
var ary = [];
|
85
|
+
for(var idx=0;idx<value.get('length');idx++) {
|
86
|
+
var x = value.objectAt(idx) ;
|
87
|
+
if (x != null && x.toString) x = x.toString() ;
|
88
|
+
ary.push(x) ;
|
89
|
+
}
|
90
|
+
value = ary.join(',') ;
|
91
|
+
}
|
92
|
+
|
93
|
+
// 3. If value is not a string, convert to string. (handles 0)
|
94
|
+
if (value != null && value.toString) value = value.toString() ;
|
95
|
+
|
96
|
+
// 4. Localize
|
97
|
+
if (value && this.getDelegateProperty(this.displayDelegate, 'localize')) value = value.loc() ;
|
98
|
+
|
99
|
+
return value ;
|
100
|
+
}.property('value'),
|
101
|
+
|
102
|
+
/**
|
103
|
+
enables editing using the inline editor
|
104
|
+
*/
|
105
|
+
isEditable: NO,
|
106
|
+
|
107
|
+
/**
|
108
|
+
YES if currently editing label view.
|
109
|
+
*/
|
110
|
+
isEditing: NO,
|
20
111
|
|
21
112
|
|
22
113
|
/**
|
@@ -29,24 +120,13 @@ SC.LabelView = SC.View.extend({
|
|
29
120
|
*/
|
30
121
|
localize: false,
|
31
122
|
|
32
|
-
|
33
|
-
/**
|
34
|
-
* @constructor
|
35
|
-
*/
|
36
|
-
init: function()
|
37
|
-
{
|
38
|
-
arguments.callee.base.call(this) ;
|
39
|
-
if (this.get("localize"))
|
40
|
-
{
|
41
|
-
var inner = this.get("asHTML");
|
42
|
-
if (inner !== "") this.set("content", inner);
|
43
|
-
}
|
44
|
-
},
|
45
123
|
|
46
124
|
/**
|
47
|
-
|
48
|
-
|
49
|
-
|
125
|
+
Event dispatcher callback.
|
126
|
+
If isEditable is set to true, opens the inline text editor view.
|
127
|
+
|
128
|
+
@param {DOMMouseEvent} evt DOM event
|
129
|
+
|
50
130
|
*/
|
51
131
|
doubleClick: function( evt )
|
52
132
|
{
|
@@ -55,30 +135,32 @@ SC.LabelView = SC.View.extend({
|
|
55
135
|
|
56
136
|
|
57
137
|
/**
|
58
|
-
|
59
|
-
|
60
|
-
|
138
|
+
Opens the inline text editor (closing it if it was already open for another view).
|
139
|
+
|
140
|
+
@return void
|
141
|
+
*/
|
61
142
|
beginInlineEdit: function()
|
62
143
|
{
|
63
144
|
if ( !this.get('isEditable') ) return;
|
64
145
|
if ( this.get('isEditing') ) return;
|
65
146
|
|
66
147
|
this.set('isEditing', true);
|
67
|
-
this.set("
|
148
|
+
this.set("innerHTML", ''); // blank out the label contents
|
68
149
|
this.appendChild( SC.inlineTextEditor );
|
69
|
-
SC.inlineTextEditor.field.set('value', this.get('
|
150
|
+
SC.inlineTextEditor.field.set('value', this.get('value'));
|
70
151
|
SC.inlineTextEditor.field.becomeFirstResponder();
|
71
152
|
},
|
72
153
|
/**
|
73
|
-
|
74
|
-
|
75
|
-
|
154
|
+
Closes the inline text editor.
|
155
|
+
|
156
|
+
@return void
|
157
|
+
*/
|
76
158
|
endInlineEdit: function()
|
77
159
|
{
|
78
160
|
if ( !this.get('isEditing') ) return;
|
79
161
|
|
80
162
|
// if there were changes, then commit them...
|
81
|
-
if ( SC.inlineTextEditor.field.get('value') != this.get('
|
163
|
+
if ( SC.inlineTextEditor.field.get('value') != this.get('value') )
|
82
164
|
{
|
83
165
|
this._inlineEditValue = SC.inlineTextEditor.field.get('value') ;
|
84
166
|
this._closeInlineEditor(false) ;
|
@@ -103,78 +185,53 @@ SC.LabelView = SC.View.extend({
|
|
103
185
|
this.removeChild( SC.inlineTextEditor );
|
104
186
|
if(!canceled)
|
105
187
|
{
|
106
|
-
this.set('
|
188
|
+
this.set('value',this._inlineEditValue) ;
|
107
189
|
this.commitInlineEdit();
|
108
190
|
}
|
109
191
|
else
|
110
192
|
{
|
111
|
-
this.
|
193
|
+
this._valueDidChange() ; // restore value.
|
112
194
|
}
|
113
195
|
},
|
114
196
|
|
115
197
|
// abstract method... implement to persist changes made in the editor.
|
116
198
|
commitInlineEdit: function() {},
|
117
|
-
|
118
|
-
|
119
|
-
// setting this to a non-null value will cause the label to get the
|
120
|
-
// property value and use that for display.
|
121
|
-
property: function(key, value) {
|
122
|
-
if ((value !== undefined) && (value != this._property)) {
|
123
|
-
if (this._content) {
|
124
|
-
var func = this._boundObserver() ;
|
125
|
-
if (this._property && this._content && this._content.removeObserver) this._content.removeObserver(this._property,func);
|
126
|
-
this._property = value ;
|
127
|
-
if (this._property && this._content && this._content.addObserver) this._content.addObserver(this._property,func) ;
|
128
|
-
} else this._property = value ;
|
129
|
-
}
|
130
|
-
return this._property ;
|
131
|
-
}.property(),
|
132
199
|
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
if (
|
140
|
-
|
141
|
-
|
142
|
-
if (prop && this._content && this._content.removeObserver) this._content.removeObserver(prop, func) ;
|
143
|
-
this._content = value ;
|
144
|
-
if (prop && this._content && this._content.addObserver) this._content.addObserver(prop, func) ;
|
145
|
-
this._updateValue() ;
|
146
|
-
}
|
147
|
-
return this._content ;
|
148
|
-
}.property(),
|
149
|
-
|
150
|
-
contentBindingDefault: SC.Binding.Single,
|
151
|
-
|
152
|
-
_updateValue: function() {
|
153
|
-
var value = this._content ;
|
154
|
-
var prop = this.get('property') ;
|
155
|
-
if (prop && value && value.get) value = value.get(prop) ;
|
156
|
-
|
157
|
-
// apply formatter
|
158
|
-
var formatter = this.get('formatter') ;
|
159
|
-
if (formatter) {
|
160
|
-
var formattedValue = (SC.typeOf(formatter) == "function") ? formatter(value,this) : formatter.fieldValueForObject(value) ;
|
161
|
-
if (formattedValue) value = formattedValue ;
|
200
|
+
/** @private */
|
201
|
+
init: function()
|
202
|
+
{
|
203
|
+
arguments.callee.base.call(this) ;
|
204
|
+
|
205
|
+
// if we are supposed to localize, get the content value
|
206
|
+
if (this.get("localize")) {
|
207
|
+
this.value = this._value = this.get('innerHTML').loc() ;
|
208
|
+
if (this.value != '') this.set('innerHTML', this.value) ;
|
162
209
|
}
|
210
|
+
},
|
163
211
|
|
164
|
-
|
212
|
+
/**
|
213
|
+
@private
|
214
|
+
|
215
|
+
Invoked whenever the monitored value on the content object
|
216
|
+
changes.
|
165
217
|
|
166
|
-
|
167
|
-
|
168
|
-
|
218
|
+
The value processed is either the contentValueKey, if set, or
|
219
|
+
it is the content object itself.
|
220
|
+
*/
|
221
|
+
_valueDidChange: function() {
|
222
|
+
|
223
|
+
var value = this.get('value') ;
|
224
|
+
if (value == this._value) return; // nothing to do
|
225
|
+
|
226
|
+
// get display value
|
227
|
+
var value = this.get('displayValue') ;
|
169
228
|
|
170
|
-
//
|
171
|
-
this.
|
229
|
+
// Escape HTML
|
230
|
+
if (this.getDelegateProperty(this.displayDelegate, 'escapeHtml')) {
|
231
|
+
this.set('innerText', value || '') ;
|
232
|
+
} else this.set('innerHTML', value || '') ;
|
172
233
|
|
173
|
-
}
|
234
|
+
}.observes('value')
|
174
235
|
|
175
|
-
_boundObserver: function() {
|
176
|
-
if (!this._observer) this._observer = this._updateValue.bind(this) ;
|
177
|
-
return this._observer ;
|
178
|
-
}
|
179
236
|
|
180
237
|
});
|