OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 library editable_label; | 5 library editable_label; |
6 | 6 |
7 import 'dart:html'; | 7 import 'dart:html'; |
8 import 'dart:async'; | |
9 import 'package:polymer/polymer.dart'; | 8 import 'package:polymer/polymer.dart'; |
10 | 9 |
11 /** | 10 /** |
12 * Label whose [value] can be edited by double clicking. When editing, it | 11 * Label whose [value] can be edited by double clicking. When editing, it |
13 * displays a form and input element, otherwise it displays the label. | 12 * displays a form and input element, otherwise it displays the label. |
14 */ | 13 */ |
15 class EditableLabel extends PolymerElement with ObservableMixin { | 14 class EditableLabel extends PolymerElement with ObservableMixin { |
16 @observable bool editing = false; | 15 @observable bool editing = false; |
17 @observable String value = ''; | 16 @observable String value = ''; |
18 bool get applyAuthorStyles => true; | 17 bool get applyAuthorStyles => true; |
19 | 18 |
20 // TODO(jmesserly): replace this with allowing not-operator in templates. | |
21 bool get notEditing => !editing; | |
22 | |
23 InputElement get _editBox => getShadowRoot("editable-label").query('#edit'); | 19 InputElement get _editBox => getShadowRoot("editable-label").query('#edit'); |
24 | 20 |
25 void created() { | |
26 super.created(); | |
27 | |
28 bindProperty(this, const Symbol('editing'), | |
29 () => notifyProperty(this, const Symbol('notEditing'))); | |
30 } | |
31 | |
32 void edit() { | 21 void edit() { |
33 editing = true; | 22 editing = true; |
34 | 23 |
35 // This causes _editBox to be inserted. | 24 // This causes _editBox to be inserted. |
36 Observable.dirtyCheck(); | 25 performMicrotaskCheckpoint(); |
37 | 26 |
38 // TODO(sigmund): remove the 2 runAsync calls. To do so, we might want to | 27 // For IE and Firefox: use .focus(), then reset the value to move the |
39 // make dirtyCheck return a future or something to indicate that all | 28 // cursor to the end. |
40 // change propagations are done. | 29 _editBox.focus(); |
41 runAsync(() => runAsync(() { | 30 _editBox.value = ''; |
42 // For IE and Firefox: use .focus(), then reset the value to move the | 31 _editBox.value = value; |
43 // cursor to the end. | |
44 _editBox.focus(); | |
45 _editBox.value = ''; | |
46 _editBox.value = value; | |
47 })); | |
48 } | 32 } |
49 | 33 |
50 void update(Event e) { | 34 void update(Event e) { |
51 e.preventDefault(); // don't submit the form | 35 e.preventDefault(); // don't submit the form |
52 if (!editing) return; // bail if user canceled | 36 if (!editing) return; // bail if user canceled |
53 value = _editBox.value; | 37 value = _editBox.value; |
54 editing = false; | 38 editing = false; |
55 } | 39 } |
56 | 40 |
57 void maybeCancel(KeyboardEvent e) { | 41 void maybeCancel(KeyboardEvent e) { |
58 if (e.keyCode == KeyCode.ESC) { | 42 if (e.keyCode == KeyCode.ESC) { |
59 editing = false; | 43 editing = false; |
60 } | 44 } |
61 } | 45 } |
62 } | 46 } |
63 | 47 |
64 @polymerInitMethod | 48 @polymerInitMethod |
65 void _init() { | 49 void _init() { |
66 registerPolymerElement('editable-label', () => new EditableLabel()); | 50 registerPolymerElement('editable-label', () => new EditableLabel()); |
67 } | 51 } |
OLD | NEW |