Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(345)

Side by Side Diff: chrome/browser/resources/options/inline_editable_list.js

Issue 6151004: DOMUI Prefs: Replace search engine edit overlay with inline editing. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Whitespace fix Created 9 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 cr.define('options', function() {
6 const DeletableItem = options.DeletableItem;
7 const DeletableItemList = options.DeletableItemList;
8
9 /**
10 * Creates a new list item with support for inline editing.
11 * @constructor
12 * @extends {options.DeletableListItem}
13 */
14 function InlineEditableItem() {
15 var el = cr.doc.createElement('div');
16 InlineEditableItem.decorate(el);
17 return el;
18 }
19
20 /**
21 * Decorates an element as a inline-editable list item. Note that this is
22 * a subclass of DeletableItem.
23 * @param {!HTMLElement} el The element to decorate.
24 */
25 InlineEditableItem.decorate = function(el) {
26 el.__proto__ = InlineEditableItem.prototype;
27 el.decorate();
28 };
29
30 InlineEditableItem.prototype = {
31 __proto__: DeletableItem.prototype,
32
33 /**
34 * Whether or not this item can be edited.
35 * @type {boolean}
36 * @private
37 */
38 editable_: true,
39
40 /**
41 * Whether or not the current edit should be considered cancelled, rather
42 * than committed, when editing ends.
43 * @type {boolean}
44 * @private
45 */
46 editCancelled_: true,
47
48 /** @inheritDoc */
49 decorate: function() {
50 DeletableItem.prototype.decorate.call(this);
51
52 var listItem = this;
53
54 this.addEventListener('selectedChange', function(event) {
arv (Not doing code reviews) 2011/01/11 21:52:45 You should be able to override the selected setter
stuartmorgan 2011/01/11 23:18:41 Actually, I discovered that there's already a sele
55 if (listItem.editable)
56 listItem.editing = listItem.selected;
57 });
58
59 this.addEventListener('keydown', this.handleKeyDown_.bind(this));
60 },
61
62 /**
63 * Whether the user is currently editing the list item.
64 * @type {boolean}
65 */
66 get editing() {
67 return this.hasAttribute('editing');
68 },
69 set editing(editing) {
70 if (this.editing == editing)
71 return;
72
73 if (editing)
74 this.setAttribute('editing', '');
75 else
76 this.removeAttribute('editing');
77
78
Evan Stade 2011/01/11 21:06:01 remove extra line
stuartmorgan 2011/01/11 23:18:41 Done.
79 if (editing) {
80 this.editCancelled_ = false;
81
82 this.onEditStarted();
arv (Not doing code reviews) 2011/01/11 21:52:45 cr.dispatchEvent
stuartmorgan 2011/01/11 23:18:41 Done, for all three onEdit* calls.
83
84 var focusElement = this.initialFocusElement();
85 // When this is called in response to the selectedChange event,
86 // the list grabs focus immediately afterwards. Thus we must delay
87 // our focus grab.
88 if (focusElement) {
89 window.setTimeout(function() {
90 focusElement.focus();
91 focusElement.select();
92 }, 50);
93 }
94 } else {
95 if (!this.editCancelled_ && this.hasBeenEdited() &&
96 this.currentInputIsValid())
Evan Stade 2011/01/11 21:06:01 curlies for multi-line conditional
stuartmorgan 2011/01/11 23:18:41 Done.
97 this.onEditCommitted();
98 else
99 this.onEditCancelled();
100 }
101 },
102
103 /**
104 * Whether the item is editable.
105 * @type {boolean}
106 */
107 get editable() {
108 return this.editable_;
109 },
110 set editable(editable) {
111 this.editable_ = editable;
112 if (!editable)
113 this.editing = false;
114 },
115
116 /**
117 * Returns the HTML element that should have focus initially when editing
118 * starts.
119 * Should be overriden by subclasses.
120 * @return {HTMLElement} The element to focus when editing starts
121 */
122 initialFocusElement: function() {
arv (Not doing code reviews) 2011/01/11 21:52:45 Use getter?
stuartmorgan 2011/01/11 23:18:41 Done.
123 return null;
124 },
125
126 /**
127 * Returns true if the input in currently valid to submit. If this returns
128 * false when editing would be submitted, either editing will not be ended,
129 * or it will be cancelled, depending on the context.
130 * Can be overrided by subclasses to perform input validation.
131 */
132 currentInputIsValid: function() {
arv (Not doing code reviews) 2011/01/11 21:52:45 use getter?
stuartmorgan 2011/01/11 23:18:41 Done.
133 return true;
134 },
135
136 /**
137 * Returns true if the item has been changed by an edit.
138 * Can be overrided by subclasses to return false when nothing has changed
139 * to avoid unnecessary commits.
140 */
141 hasBeenEdited: function() {
142 return true;
143 },
144
145 /**
146 * Called when editing mode starts.
147 * Can be overridden by subclasses to do any pre-edit tasks.
148 */
149 onEditStarted: function() {
150 },
151
152 /**
153 * Called when editing mode ends without cancelling.
154 * Should be overridden by subclasses to do any post-edit tasks, such as
155 * commiting the change.
156 */
157 onEditCommitted: function() {
158 },
159
160 /**
161 * Called when editing mode is cancelled.
162 * Should be overridden by subclasses to do any post-cancellation tasks,
163 * such as undoing changes to the editable controls.
164 */
165 onEditCancelled: function() {
166 },
167
168 /**
169 * Called a key is pressed. Handles committing and cancelling edits.
170 * @param {Event} e The key down event.
171 * @private
172 */
173 handleKeyDown_: function(e) {
174 if (!this.editing)
175 return;
176
177 var endEdit = false;
178 switch (e.keyIdentifier) {
179 case 'U+001B': // Esc
180 this.editCancelled_ = true;
181 endEdit = true;
182 break;
183 case 'Enter':
184 if (this.currentInputIsValid())
185 endEdit = true;
186 break;
187 }
188
189 if (endEdit) {
190 // Blurring will trigger the edit to end; see InlineEditableItemList.
191 this.ownerDocument.activeElement.blur();
192 // Make sure that handled keys aren't passed on and double-handled.
193 // (e.g., esc shouldn't both cancel an edit and close a subpage)
194 e.stopPropagation();
195 }
196 },
197 };
198
199 var InlineEditableItemList = cr.ui.define('list');
200
201 InlineEditableItemList.prototype = {
202 __proto__: DeletableItemList.prototype,
203
204 /** @inheritDoc */
205 decorate: function() {
206 DeletableItemList.prototype.decorate.call(this);
207 this.addEventListener('blur', this.handleBlur_.bind(this), true);
208 },
209
210 /**
211 * Called when an element in the list is blurred. Removes selection (thus
212 * ending edit) if focus moves outside the list.
213 * @param {Event} e The blur event.
214 * @private
215 */
216 handleBlur_: function(e) {
217 // When the blur event happens we do not know who is getting focus so we
218 // delay this a bit until we know if the new focus node is outside the
219 // list.
220 var list = this;
221 var doc = e.target.ownerDocument;
222 window.setTimeout(function() {
223 var activeElement = doc.activeElement;
224 if (!list.contains(activeElement))
225 list.selectionModel.unselectAll();
226 }, 50);
227 },
228 };
229
230 // Export
231 return {
232 InlineEditableItem: InlineEditableItem,
233 InlineEditableItemList: InlineEditableItemList,
234 };
235
Evan Stade 2011/01/11 21:06:01 extra line here and at eof
stuartmorgan 2011/01/11 23:18:41 Done.
236 });
237
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698