sproutcore 0.9.2 → 0.9.3

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 (48) hide show
  1. data/History.txt +33 -0
  2. data/Manifest.txt +3 -14
  3. data/clients/sc_docs/controllers/docs.js +1 -0
  4. data/clients/sc_docs/core.js +1 -1
  5. data/clients/sc_test_runner/controllers/runner.js +5 -0
  6. data/clients/sc_test_runner/core.js +1 -1
  7. data/frameworks/sproutcore/english.lproj/core.css +41 -0
  8. data/frameworks/sproutcore/english.lproj/theme.css +20 -0
  9. data/frameworks/sproutcore/foundation/animator.js +11 -2
  10. data/frameworks/sproutcore/foundation/date.js +2 -2
  11. data/frameworks/sproutcore/foundation/object.js +2 -2
  12. data/frameworks/sproutcore/foundation/server.js +4 -3
  13. data/frameworks/sproutcore/foundation/set.js +1 -1
  14. data/frameworks/sproutcore/foundation/unittest.js +12 -9
  15. data/frameworks/sproutcore/lib/collection_view.rb +1 -0
  16. data/frameworks/sproutcore/lib/core_views.rb +4 -0
  17. data/frameworks/sproutcore/mixins/editable.js +144 -0
  18. data/frameworks/sproutcore/mixins/inline_editor_delegate.js +72 -0
  19. data/frameworks/sproutcore/mixins/observable.js +45 -16
  20. data/frameworks/sproutcore/mixins/scrollable.js +0 -1
  21. data/frameworks/sproutcore/tests/controllers/controller.rhtml +12 -12
  22. data/frameworks/sproutcore/tests/controllers/object.rhtml +2 -2
  23. data/frameworks/sproutcore/views/collection/collection.js +122 -68
  24. data/frameworks/sproutcore/views/collection/source_list.js +5 -0
  25. data/frameworks/sproutcore/views/field/text_field.js +7 -1
  26. data/frameworks/sproutcore/views/inline_text_field.js +397 -0
  27. data/frameworks/sproutcore/views/label.js +78 -68
  28. data/frameworks/sproutcore/views/list_item.js +184 -31
  29. data/frameworks/sproutcore/views/view.js +41 -9
  30. data/generators/client/templates/core.js +1 -1
  31. data/generators/client/templates/english.lproj/body.css +74 -0
  32. data/generators/framework/templates/core.js +1 -1
  33. data/lib/sproutcore/version.rb +1 -1
  34. metadata +5 -16
  35. data/clients/view_builder/builders/builder.js +0 -339
  36. data/clients/view_builder/builders/button.js +0 -81
  37. data/clients/view_builder/controllers/document.js +0 -21
  38. data/clients/view_builder/core.js +0 -19
  39. data/clients/view_builder/english.lproj/body.css +0 -77
  40. data/clients/view_builder/english.lproj/body.rhtml +0 -41
  41. data/clients/view_builder/english.lproj/controls.css +0 -0
  42. data/clients/view_builder/english.lproj/strings.js +0 -14
  43. data/clients/view_builder/main.js +0 -38
  44. data/clients/view_builder/tests/controllers/document.rhtml +0 -20
  45. data/clients/view_builder/tests/views/builder.rhtml +0 -20
  46. data/clients/view_builder/views/builder.js +0 -23
  47. data/frameworks/sproutcore/english.lproj/inline_text_editor.css +0 -21
  48. data/frameworks/sproutcore/views/inline_text_editor.js +0 -96
@@ -26,6 +26,11 @@ SC.SourceListView = SC.CollectionView.extend(
26
26
  */
27
27
  contentValueKey: null,
28
28
 
29
+ /**
30
+ Set to YES if you want the content value to be editable.
31
+ */
32
+ contentValueIsEditable: NO,
33
+
29
34
  /**
30
35
  Set to YES if you want source list items to display an icon.
31
36
 
@@ -4,6 +4,7 @@
4
4
  // ========================================================================
5
5
 
6
6
  require('views/field/field') ;
7
+ require('mixins/editable') ;
7
8
 
8
9
  /**
9
10
  @class
@@ -12,9 +13,10 @@ require('views/field/field') ;
12
13
  for hinted values, etc.
13
14
 
14
15
  @extends SC.FieldView
16
+ @extends SC.Editable
15
17
  @author Charles Jolley
16
18
  */
17
- SC.TextFieldView = SC.FieldView.extend(
19
+ SC.TextFieldView = SC.FieldView.extend(SC.Editable,
18
20
  /** @scope SC.TextFieldView.prototype */ {
19
21
 
20
22
  emptyElement: '<input type="text" value="" />',
@@ -31,6 +33,10 @@ SC.TextFieldView = SC.FieldView.extend(
31
33
  */
32
34
  isHintShowing: false,
33
35
 
36
+ /**
37
+ If YES then the text field is currently editing.
38
+ */
39
+ isEditing: NO,
34
40
 
35
41
  // PRIVATE SUPPORT METHODS
36
42
  init: function() {
@@ -0,0 +1,397 @@
1
+ // ========================================================================
2
+ // SproutCore
3
+ // copyright 2006-2008 Sprout Systems, Inc.
4
+ // ========================================================================
5
+
6
+ require('views/view') ;
7
+ require('mixins/delegate_support') ;
8
+ require('views/field/text_field') ;
9
+ require('mixins/inline_editor_delegate');
10
+
11
+ /**
12
+ @class
13
+
14
+ The inline text editor is used to display an editable area for controls
15
+ that are not always editable such as label views and source list views.
16
+
17
+ You generally will not use the inline editor directly but instead will
18
+ invoke beginEditing() and endEditing() on the views yous are
19
+ editing. If you would like to use the inline editor for your own views,
20
+ you can do that also by using the editing API described here.
21
+
22
+ h2. Using the Inline Editor in Your Own Views
23
+
24
+ If you need to use the inline editor with custom views you have written,
25
+ you will need to work with the class methods to begin, commit, and discard
26
+ editing changes.
27
+
28
+ h3. Starting the Editor
29
+
30
+ The inline editor works by positioning itself over the top of your view
31
+ with the same offset, width, and font information. As the user types, the
32
+ field will automatically resize vertically to make room for the user's text.
33
+
34
+ To activate the inline editor you must call beginEdition() with at least
35
+ the target view you want the editor to position itself on top of:
36
+
37
+ {{{
38
+ SC.InlineTextFieldView.beginEditing({
39
+ target: view, validator: validator
40
+ }) ;
41
+ }}}
42
+
43
+ You can pass a variety of options to this method to configure the inline
44
+ editor behavior, including:
45
+
46
+ - *frame* The editors initial frame in viewport coordinates (REQ)
47
+ - *exampleElement* A DOM element to use when copying styles.
48
+ - *delegate* Optional delegate to receive update notices. If not passed, the target view will be treated as the delegate. (REQ)
49
+ - *value* The initial value of the edit field. If not passed, the value property of the target view will be used instead.
50
+ - *multiline* If YES then the hitting return will add to the value instead of exiting the inline editor.
51
+ - *selectedRange* The range of text that should be selected. If omitted, then the insertion point will be placed at the end of the value.
52
+ - *commitOnBlur* If YES then bluring will commit the value, otherwise it will discard the current value. Defaults to YES.
53
+ - *validator* Optional validator will be attached to the field.
54
+
55
+ If the inline editor is currently in use elsewhere, it will automatically
56
+ close itself over there and begin editing for your view instead. The
57
+ editor expects your source view to implement the InlineTextFieldViewDelegate
58
+ protocol.
59
+
60
+ h2. Commiting or Discarding Changes
61
+
62
+ Normally the editor will automatically commit or discard its changes
63
+ whenever the user exits the edit mode. If you need to force the editor to
64
+ end editing, you can do so by calling commitEditing() or discardEditing():
65
+
66
+ {{{
67
+ SC.InlineTextFieldView.commitEditing();
68
+ SC.InlineTextFieldView.discardEditing();
69
+ }}}
70
+
71
+ Both methods will try to end the editing context and will call the
72
+ relevent delegate methods on the delegate you passed to beginEditing().
73
+
74
+ Note that it is possible an editor may not be able to commit editing
75
+ changes because either the delegate disallowed it or because its validator
76
+ failed. In this case commitEditing() will return NO. If you want to
77
+ end editing anyway, you can discard the editing changes instead by calling
78
+ discardEditing(). This method will generally suceed unless your delegate
79
+ refuses it as well.
80
+
81
+ @extends SC.View
82
+ @extends SC.DelegateSupport
83
+ @extends SC.InlineEditorDelegate
84
+ @since SproutCore 1.0
85
+ */
86
+ SC.InlineTextFieldView = SC.View.extend(SC.DelegateSupport, SC.InlineEditorDelegate,
87
+ /** @scope SC.InlineTextFieldView.prototype */ {
88
+
89
+ /**
90
+ Invoked by the class method to begin editing on an inline editor.
91
+
92
+ You generally should call the class method beginEditing() instead of
93
+ this one since it will make sure to create and use the shared editor
94
+ instance.
95
+
96
+ @params options {Hash} hash of options for editing
97
+ @returns {Boolean} YES if editor began editing, NO if it failed.
98
+ */
99
+ beginEditing: function(options) {
100
+
101
+ // end existing editing if necessary
102
+ this.beginPropertyChanges();
103
+ if (this.get('isEditing') && !this.blurEditor()) {
104
+ this.endPropertyChanges(); return NO ;
105
+ }
106
+
107
+ this._frame = options.frame ;
108
+ this._exampleElement = options.exampleElement ;
109
+ this._delegate = options.delegate ;
110
+
111
+ if (!this._frame || !this._delegate) {
112
+ throw "At least frame and delegate options are required for inline editor";
113
+ }
114
+
115
+ this._originalValue = options.value || '' ;
116
+ this._multiline = (options.multiline !== undefined) ? options.multiline : NO ;
117
+ this._commitOnBlur = (options.commitOnBlur !== undefined) ? options.commitOnBlur : YES ;
118
+
119
+ // set field values
120
+ var field = this.outlet('field') ;
121
+ field.set('validator', options.validator) ;
122
+ field.set('value', this._originalValue) ;
123
+ field.set('selectedRange', options.selectedRange || { start: this._originalValue.length, length: 0 }) ;
124
+
125
+ this.set('isEditing', YES) ;
126
+
127
+ // add to window.
128
+ SC.window.appendChild(this) ;
129
+
130
+ // get style for view.
131
+ this.updateViewStyle() ;
132
+
133
+ var del = this._delegate ;
134
+ this.invokeDelegateMethod(del, 'inlineEditorWillBeginEditing', this) ;
135
+ this.resizeToFit(field.getFieldValue()) ;
136
+
137
+ // allow notifications to go
138
+ this.endPropertyChanges() ;
139
+
140
+ // and become first responder
141
+ this.field.becomeFirstResponder() ;
142
+
143
+ this.invokeDelegateMethod(del, 'inlineEditorDidBeginEditing', this) ;
144
+ },
145
+
146
+
147
+ /**
148
+ Tries to commit the current value of the field and end editing.
149
+
150
+ Do not use this method, use the class method instead.
151
+ */
152
+ commitEditing: function() {
153
+ // try to validate field. If it fails, return false.
154
+ var field = this.outlet('field') ;
155
+ if (!$ok(field.validateSubmit())) return NO ;
156
+ return this._endEditing(field.get('value')) ;
157
+ },
158
+
159
+ /**
160
+ Tries to discard the current value of the field and end editing.
161
+
162
+ Do not use this method, use the class method instead.
163
+ */
164
+ discardEditing: function() {
165
+ return this._endEditing(this._originalValue) ;
166
+ },
167
+
168
+ /**
169
+ Invoked whenever the editor loses (or should lose) first responder
170
+ status to commit or discard editing.
171
+ */
172
+ blurEditor: function() {
173
+ if (!this.get('isEditing')) return YES ;
174
+ return (this._commitOnBlur) ? this.commitEditing() : this.discardEditing();
175
+ },
176
+
177
+ /** @private
178
+ Called by commitEditing and discardEditing to actually end editing.
179
+
180
+ @returns {Boolean} NO if editing did not exit
181
+ */
182
+ _endEditing: function(finalValue) {
183
+ if (!this.get('isEditing')) return YES ;
184
+
185
+ // get permission from the delegate.
186
+ var del = this._delegate ;
187
+ if (!this.invokeDelegateMethod(del, 'inlineEditorShouldEndEditing', this, finalValue)) return NO ;
188
+
189
+ // OK, we are allowed to end editing. Notify delegate of final value
190
+ // and clean up.
191
+ console.log('applying finalValue: %@'.fmt(finalValue)) ;
192
+ this.invokeDelegateMethod(del, 'inlineEditorDidEndEditing', this, finalValue) ;
193
+
194
+ // cleanup cached values
195
+ this._originalValue = this._delegate = this._exampleElement = this._frame = null ;
196
+ this.set('isEditing', NO) ;
197
+
198
+ // resign first responder if not done already. This may call us in a
199
+ // loop but since isEditing is already NO, nothing will happen.
200
+ if (this.field.get('isFirstResponder')) this.field.resignFirstResponder();
201
+ if (this.get('parentNode')) this.removeFromParent() ;
202
+
203
+ return YES ;
204
+ },
205
+
206
+ /**
207
+ YES if the editor is currently visible and editing.
208
+
209
+ @type {Boolean}
210
+ */
211
+ isEditing: NO,
212
+
213
+ /** @private */
214
+ emptyElement: [
215
+ '<div class="sc-inline-text-field-view">',
216
+ '<div class="sizer"></div>',
217
+ '<textarea class="inner-field" wrap="virtual"></textarea>',
218
+ '</div>'
219
+ ].join(''),
220
+
221
+ /**
222
+ Collects the appropriate style information from the targetView to
223
+ make the inline editor appear similar.
224
+ */
225
+ updateViewStyle: function() {
226
+ // collect font and frame from target.
227
+ var f= this._frame ;
228
+ var el = this._exampleElement ;
229
+
230
+ var styles = {
231
+ fontSize: Element.getStyle(el,'font-size'),
232
+ fontFamily: Element.getStyle(el,'font-family'),
233
+ fontWeight: Element.getStyle(el,'font-weight'),
234
+ paddingLeft: Element.getStyle(el,'padding-left'),
235
+ paddingRight: Element.getStyle(el,'padding-right'),
236
+ paddingTop: Element.getStyle(el,'padding-top'),
237
+ paddingBottom: Element.getStyle(el,'padding-bottom'),
238
+ lineHeight: Element.getStyle(el,'line-height'),
239
+ textAlign: Element.getStyle(el,'text-align')
240
+ } ;
241
+
242
+ var field = this.outlet('field') ;
243
+ var sizer = this.outlet('sizer') ;
244
+
245
+ field.setStyle(styles) ;
246
+
247
+ styles.opacity = 0 ;
248
+ sizer.setStyle(styles) ;
249
+ sizer.recacheFrames() ;
250
+
251
+ this.set('frame', f) ;
252
+ },
253
+
254
+ /**
255
+ Resizes the visible textarea to fix the actual text in the text area.
256
+
257
+ This method works by keeping a div positioned immediately beneath the
258
+ text area with an opacity of 0 that contains the same text as the
259
+ input text field itself. This is then used to calculate the required
260
+ size for the text area.
261
+ */
262
+ resizeToFit: function(newValue)
263
+ {
264
+ var sizer = this.outlet('sizer');
265
+ var field = this.outlet('field');
266
+
267
+ // XSS attack waiting to happen... escape the form input;
268
+ var text = (newValue || '').escapeHTML();
269
+
270
+ // convert the textarea's newlines into something comparable for the sizer
271
+ // div appending a space to give a line with no text a visible height.
272
+ text = text.replace(/ /g, "&nbsp; ").replace(/\n/g, "<br />&nbsp;");
273
+
274
+ // get the text size
275
+ sizer.set('innerHTML', text || "&nbsp;");
276
+ sizer.recacheFrames() ;
277
+ var h = sizer.get('frame').height;
278
+ this.set('frame', { height: h }) ;
279
+ },
280
+
281
+ /**
282
+ The actual text field view used for editing.
283
+ */
284
+ field: SC.TextFieldView.extend({
285
+
286
+ // handle mouseDown event if we are currently editing so that events
287
+ // don't go any further?
288
+ mouseDown: function(e) {
289
+ arguments.callee.base.call(this, e) ;
290
+ return this.owner.get('isEditing');
291
+ },
292
+
293
+ // [Safari] if you don't take key focus away from an element before you
294
+ // remove it from the DOM key events are no longer sent to the browser.
295
+ willRemoveFromParent: function() {
296
+ this.get('rootElement').blur();
297
+ },
298
+
299
+ // ask owner to end editing.
300
+ willLoseFirstResponder: function()
301
+ {
302
+ // should have been covered by willRemoveFromParent, but this was needed
303
+ // too.
304
+ this.get('rootElement').blur();
305
+ return this.owner.blurEditor() ;
306
+ },
307
+
308
+ // invoked when the user presses escape. Returns true to ignore
309
+ // keystroke
310
+ cancel: function() {
311
+ this.owner.discardEditing();
312
+ return YES;
313
+ },
314
+
315
+ // do it here instead of waiting on the binding to make sure the UI
316
+ // updates immediately.
317
+ fieldValueDidChange: function(partialChange) {
318
+ arguments.callee.base.call(this, partialChange) ;
319
+ this.owner.resizeToFit(this.getFieldValue()) ;
320
+ },
321
+
322
+ // invoked when the user presses return. If this is a multi-line field,
323
+ // then allow the newine to proceed. Otherwise, try to commit the
324
+ // edit.
325
+ insertNewline: function(evt) {
326
+ if (this.owner_multiline) {
327
+ return arguments.callee.base.call(this, evt) ;
328
+ } else {
329
+ this.owner.commitEditing() ;
330
+ return YES ;
331
+ }
332
+ }
333
+
334
+ }).outletFor('.inner-field?'),
335
+
336
+ sizer: SC.View.outletFor('.sizer?')
337
+
338
+ });
339
+
340
+
341
+ SC.InlineTextFieldView.mixin(
342
+ /** @static SC.InlineTextFieldView */ {
343
+ /** Call this method to make the inline editor begin editing for your view.
344
+
345
+ If the inline editor is already being used for another value it will
346
+ try to dismiss itself from the other editor and attach itself to the
347
+ new view instead. If this process fails for some reason (for example
348
+ if the other view did not allow the view to end editing) then this
349
+ method will return false.
350
+
351
+ You should pass a set of options that at least includes the target
352
+ view. See class definition for options.
353
+
354
+ @params options {Hash} hash of options for editing
355
+ @returns {Boolean} YES if editor began editing, NO if it failed.
356
+ */
357
+ beginEditing: function(options) {
358
+ if (!this.sharedEditor) this.sharedEditor = this.create() ;
359
+ return this.sharedEditor.beginEditing(options) ;
360
+ },
361
+
362
+ /** Save the current value of the inline editor and exit edit mode.
363
+
364
+ If the inline editor is being used it will try to end the editing and
365
+ close. If the inline editor could not end for some reason (for example
366
+ if the delegate did not allow the editing to end) then this method will
367
+ return NO.
368
+
369
+ @returns {Boolean} YES if the inline editor ended or no edit was in
370
+ progress.
371
+ */
372
+ commitEditing: function() {
373
+ return (this.sharedEditor) ? this.sharedEditor.commitEditing() : YES ;
374
+ },
375
+
376
+ /** Discard the current value of the inline editor and exit edit mode.
377
+
378
+ If the inline editor is in use, this method will try to end the editing,
379
+ restoring the original value of the target view. If the inline editor
380
+ could not end for some reason (for example if the delegate did not
381
+ allow editing to end) then this method will return NO.
382
+
383
+ @returns {Boolean} YES if the inline editor ended or no edit was in progress.
384
+ */
385
+ discardEditing: function() {
386
+ return (this.sharedEditor) ? this.sharedEditor.discardEditing() : YES ;
387
+ },
388
+
389
+ /**
390
+ The current shared inline editor. This property will often remain NULL
391
+ until you actually begin editing for the first time.
392
+
393
+ @type {SC.InlineTextFieldView}
394
+ */
395
+ sharedEditor: null
396
+
397
+ }) ;
@@ -6,6 +6,8 @@
6
6
  require('views/view') ;
7
7
  require('mixins/control') ;
8
8
  require('mixins/delegate_support');
9
+ require('views/inline_text_field');
10
+ require('mixins/inline_editor_delegate');
9
11
 
10
12
  /**
11
13
  @class
@@ -18,10 +20,11 @@ require('mixins/delegate_support');
18
20
  @extends SC.View
19
21
  @extends SC.Control
20
22
  @extends SC.DelegateSupport
21
- @author Charles Jolley
22
- @version 1.0
23
+ @extends SC.InlineEditorDelegate
24
+ @extends SC.Editable
25
+ @since SproutCore 1.0
23
26
  */
24
- SC.LabelView = SC.View.extend(SC.DelegateSupport, SC.Control,
27
+ SC.LabelView = SC.View.extend(SC.DelegateSupport, SC.Control, SC.InlineEditorDelegate,
25
28
  /** @scope SC.LabelView.prototype */ {
26
29
 
27
30
  emptyElement: '<span class="sc-label-view"></span>',
@@ -120,6 +123,15 @@ SC.LabelView = SC.View.extend(SC.DelegateSupport, SC.Control,
120
123
  */
121
124
  localize: false,
122
125
 
126
+ /**
127
+ Validator to use during inline editing.
128
+
129
+ If you have set isEditing to YES, then any validator you set on this
130
+ property will be used when the label view is put into edit mode.
131
+
132
+ @type {SC.Validator}
133
+ */
134
+ validator: null,
123
135
 
124
136
  /**
125
137
  Event dispatcher callback.
@@ -128,85 +140,83 @@ SC.LabelView = SC.View.extend(SC.DelegateSupport, SC.Control,
128
140
  @param {DOMMouseEvent} evt DOM event
129
141
 
130
142
  */
131
- doubleClick: function( evt )
132
- {
133
- this.beginInlineEdit();
134
- },
143
+ doubleClick: function( evt ) { return this.beginEditing(); },
135
144
 
136
145
 
137
146
  /**
138
- Opens the inline text editor (closing it if it was already open for another view).
147
+ Opens the inline text editor (closing it if it was already open for
148
+ another view).
139
149
 
140
- @return void
150
+ @return {Boolean} YES if did begin editing
141
151
  */
142
- beginInlineEdit: function()
152
+ beginEditing: function()
143
153
  {
144
- if ( !this.get('isEditable') ) return;
145
- if ( this.get('isEditing') ) return;
146
-
147
- this.set('isEditing', true);
148
- this.set("innerHTML", ''); // blank out the label contents
149
- this.appendChild( SC.inlineTextEditor );
150
- SC.inlineTextEditor.field.set('value', this.get('value'));
151
- SC.inlineTextEditor.field.becomeFirstResponder();
154
+ if (this.get('isEditing')) return YES ;
155
+ if (!this.get('isEditable')) return NO ;
156
+
157
+ var value = this.get('value') || '' ;
158
+ var f = this.convertFrameToView(this.get('frame'), null) ;
159
+ var el = this.rootElement;
160
+ SC.InlineTextFieldView.beginEditing({
161
+ frame: f,
162
+ delegate: this,
163
+ exampleElement: el,
164
+ value: value,
165
+ multiline: NO,
166
+ validator: this.get('validator')
167
+ });
152
168
  },
169
+
153
170
  /**
154
- Closes the inline text editor.
171
+ Cancels the current inline editor and then exits editor.
155
172
 
156
- @return void
173
+ @return {Boolean} NO if the editor could not exit.
157
174
  */
158
- endInlineEdit: function()
159
- {
160
- if ( !this.get('isEditing') ) return;
161
-
162
- // if there were changes, then commit them...
163
- if ( SC.inlineTextEditor.field.get('value') != this.get('value') )
164
- {
165
- this._inlineEditValue = SC.inlineTextEditor.field.get('value') ;
166
- this._closeInlineEditor(false) ;
167
- }
168
- else
169
- {
170
- this.cancelInlineEdit() ;
171
- }
175
+ discardEditing: function() {
176
+ if (!this.get('isEditing')) return YES ;
177
+ return SC.InlineTextFieldView.discardEditing() ;
172
178
  },
173
179
 
174
- _inlineEditValue: '',
175
-
176
- cancelInlineEdit: function()
177
- {
178
- if ( !this.get('isEditing') ) return;
179
- this._closeInlineEditor(true);
180
+ /**
181
+ Commits current inline editor and then exits editor.
182
+
183
+ @return {Boolean} NO if the editor could not exit
184
+ */
185
+ commitEditing: function() {
186
+ if (!this.get('isEditing')) return YES ;
187
+ return SC.InlineTextFieldView.commitEditing() ;
180
188
  },
181
-
182
- _closeInlineEditor: function(canceled)
183
- {
184
- this.set('isEditing', false);
185
- this.removeChild( SC.inlineTextEditor );
186
- if(!canceled)
187
- {
188
- this.set('value',this._inlineEditValue) ;
189
- this.commitInlineEdit();
190
- }
191
- else
192
- {
193
- this._valueDidChange() ; // restore value.
194
- }
189
+
190
+ /** @private
191
+ Set editing to true so edits will no longer be allowed.
192
+ */
193
+ inlineEditorWillBeginEditing: function(inlineEditor) {
194
+ this.set('isEditing', YES);
195
195
  },
196
-
197
- // abstract method... implement to persist changes made in the editor.
198
- commitInlineEdit: function() {},
199
-
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) ;
209
- }
196
+
197
+ /** @private
198
+ Hide the label view while the inline editor covers it.
199
+ */
200
+ inlineEditorDidBeginEditing: function(inlineEditor) {
201
+ this._oldOpacity = this.getStyle('opacity') ;
202
+ this.setStyle({ opacity: 0.0 }) ;
203
+ },
204
+
205
+ /** @private
206
+ Could check with a validator someday...
207
+ */
208
+ inlineEditorShouldEndEditing: function(inlineEditor, finalValue) {
209
+ return YES ;
210
+ },
211
+
212
+ /** @private
213
+ Update the field value and make it visible again.
214
+ */
215
+ inlineEditorDidEndEditing: function(inlineEditor, finalValue) {
216
+ this.setIfChanged('value', finalValue) ;
217
+ this.setStyle({ opacity: this._oldOpacity }) ;
218
+ this._oldOpacity = null ;
219
+ this.set('isEditing', NO) ;
210
220
  },
211
221
 
212
222
  /**