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

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: Address review comments 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;
arv (Not doing code reviews) 2011/01/11 23:29:29 It would be good if we could move these to cr.ui i
stuartmorgan 2011/01/12 00:26:51 Sure; added to my TODO list.
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 this.addEventListener('keydown', this.handleKeyDown_.bind(this));
53 },
54
55 /** @inheritDoc */
56 selectionChanged: function() {
57 if (this.editable)
58 this.editing = this.selected;
59 },
60
61 /**
62 * Whether the user is currently editing the list item.
63 * @type {boolean}
64 */
65 get editing() {
66 return this.hasAttribute('editing');
67 },
68 set editing(editing) {
69 if (this.editing == editing)
70 return;
71
72 if (editing)
73 this.setAttribute('editing', '');
74 else
75 this.removeAttribute('editing');
76
77 if (editing) {
78 this.editCancelled_ = false;
79
80 cr.dispatchSimpleEvent(this, 'edit', true);
81
82 var focusElement = this.initialFocusElement;
83 // When this is called in response to the selectedChange event,
84 // the list grabs focus immediately afterwards. Thus we must delay
85 // our focus grab.
86 if (focusElement) {
87 window.setTimeout(function() {
88 focusElement.focus();
89 focusElement.select();
90 }, 50);
91 }
92 } else {
93 if (!this.editCancelled_ && this.hasBeenEdited() &&
94 this.currentInputIsValid) {
95 cr.dispatchSimpleEvent(this, 'commitedit', true);
96 } else {
97 cr.dispatchSimpleEvent(this, 'canceledit', true);
98 }
99 }
100 },
101
102 /**
103 * Whether the item is editable.
104 * @type {boolean}
105 */
106 get editable() {
107 return this.editable_;
108 },
109 set editable(editable) {
110 this.editable_ = editable;
111 if (!editable)
112 this.editing = false;
113 },
114
115 /**
116 * The HTML element that should have focus initially when editing starts.
117 * Should be overriden by subclasses.
118 * @type {HTMLElement}
119 */
120 get initialFocusElement() {
121 return null;
122 },
123
124 /**
125 * Whether the input in currently valid to submit. If this returns false
126 * when editing would be submitted, either editing will not be ended,
127 * or it will be cancelled, depending on the context.
128 * Can be overrided by subclasses to perform input validation.
129 */
130 get currentInputIsValid() {
131 return true;
132 },
133
134 /**
135 * Returns true if the item has been changed by an edit.
136 * Can be overrided by subclasses to return false when nothing has changed
137 * to avoid unnecessary commits.
138 */
139 hasBeenEdited: function() {
140 return true;
141 },
142
143 /**
144 * Called a key is pressed. Handles committing and cancelling edits.
145 * @param {Event} e The key down event.
146 * @private
147 */
148 handleKeyDown_: function(e) {
149 if (!this.editing)
150 return;
151
152 var endEdit = false;
153 switch (e.keyIdentifier) {
154 case 'U+001B': // Esc
155 this.editCancelled_ = true;
156 endEdit = true;
157 break;
158 case 'Enter':
159 if (this.currentInputIsValid)
160 endEdit = true;
161 break;
162 }
163
164 if (endEdit) {
165 // Blurring will trigger the edit to end; see InlineEditableItemList.
166 this.ownerDocument.activeElement.blur();
167 // Make sure that handled keys aren't passed on and double-handled.
168 // (e.g., esc shouldn't both cancel an edit and close a subpage)
169 e.stopPropagation();
170 }
171 },
172 };
173
174 var InlineEditableItemList = cr.ui.define('list');
175
176 InlineEditableItemList.prototype = {
177 __proto__: DeletableItemList.prototype,
178
179 /** @inheritDoc */
180 decorate: function() {
181 DeletableItemList.prototype.decorate.call(this);
182 this.addEventListener('blur', this.handleBlur_.bind(this), true);
183 },
184
185 /**
186 * Called when an element in the list is blurred. Removes selection (thus
187 * ending edit) if focus moves outside the list.
188 * @param {Event} e The blur event.
189 * @private
190 */
191 handleBlur_: function(e) {
192 // When the blur event happens we do not know who is getting focus so we
193 // delay this a bit until we know if the new focus node is outside the
194 // list.
195 var list = this;
196 var doc = e.target.ownerDocument;
197 window.setTimeout(function() {
198 var activeElement = doc.activeElement;
199 if (!list.contains(activeElement))
200 list.selectionModel.unselectAll();
201 }, 50);
202 },
203 };
204
205 // Export
206 return {
207 InlineEditableItem: InlineEditableItem,
208 InlineEditableItemList: InlineEditableItemList,
209 };
210 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698