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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/resources/options/inline_editable_list.js
diff --git a/chrome/browser/resources/options/inline_editable_list.js b/chrome/browser/resources/options/inline_editable_list.js
new file mode 100644
index 0000000000000000000000000000000000000000..bc4996bebd448487c0ffc4b4e2c2d761dc230c19
--- /dev/null
+++ b/chrome/browser/resources/options/inline_editable_list.js
@@ -0,0 +1,237 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+cr.define('options', function() {
+ const DeletableItem = options.DeletableItem;
+ const DeletableItemList = options.DeletableItemList;
+
+ /**
+ * Creates a new list item with support for inline editing.
+ * @constructor
+ * @extends {options.DeletableListItem}
+ */
+ function InlineEditableItem() {
+ var el = cr.doc.createElement('div');
+ InlineEditableItem.decorate(el);
+ return el;
+ }
+
+ /**
+ * Decorates an element as a inline-editable list item. Note that this is
+ * a subclass of DeletableItem.
+ * @param {!HTMLElement} el The element to decorate.
+ */
+ InlineEditableItem.decorate = function(el) {
+ el.__proto__ = InlineEditableItem.prototype;
+ el.decorate();
+ };
+
+ InlineEditableItem.prototype = {
+ __proto__: DeletableItem.prototype,
+
+ /**
+ * Whether or not this item can be edited.
+ * @type {boolean}
+ * @private
+ */
+ editable_: true,
+
+ /**
+ * Whether or not the current edit should be considered cancelled, rather
+ * than committed, when editing ends.
+ * @type {boolean}
+ * @private
+ */
+ editCancelled_: true,
+
+ /** @inheritDoc */
+ decorate: function() {
+ DeletableItem.prototype.decorate.call(this);
+
+ var listItem = this;
+
+ 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
+ if (listItem.editable)
+ listItem.editing = listItem.selected;
+ });
+
+ this.addEventListener('keydown', this.handleKeyDown_.bind(this));
+ },
+
+ /**
+ * Whether the user is currently editing the list item.
+ * @type {boolean}
+ */
+ get editing() {
+ return this.hasAttribute('editing');
+ },
+ set editing(editing) {
+ if (this.editing == editing)
+ return;
+
+ if (editing)
+ this.setAttribute('editing', '');
+ else
+ this.removeAttribute('editing');
+
+
Evan Stade 2011/01/11 21:06:01 remove extra line
stuartmorgan 2011/01/11 23:18:41 Done.
+ if (editing) {
+ this.editCancelled_ = false;
+
+ 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.
+
+ var focusElement = this.initialFocusElement();
+ // When this is called in response to the selectedChange event,
+ // the list grabs focus immediately afterwards. Thus we must delay
+ // our focus grab.
+ if (focusElement) {
+ window.setTimeout(function() {
+ focusElement.focus();
+ focusElement.select();
+ }, 50);
+ }
+ } else {
+ if (!this.editCancelled_ && this.hasBeenEdited() &&
+ this.currentInputIsValid())
Evan Stade 2011/01/11 21:06:01 curlies for multi-line conditional
stuartmorgan 2011/01/11 23:18:41 Done.
+ this.onEditCommitted();
+ else
+ this.onEditCancelled();
+ }
+ },
+
+ /**
+ * Whether the item is editable.
+ * @type {boolean}
+ */
+ get editable() {
+ return this.editable_;
+ },
+ set editable(editable) {
+ this.editable_ = editable;
+ if (!editable)
+ this.editing = false;
+ },
+
+ /**
+ * Returns the HTML element that should have focus initially when editing
+ * starts.
+ * Should be overriden by subclasses.
+ * @return {HTMLElement} The element to focus when editing starts
+ */
+ initialFocusElement: function() {
arv (Not doing code reviews) 2011/01/11 21:52:45 Use getter?
stuartmorgan 2011/01/11 23:18:41 Done.
+ return null;
+ },
+
+ /**
+ * Returns true if the input in currently valid to submit. If this returns
+ * false when editing would be submitted, either editing will not be ended,
+ * or it will be cancelled, depending on the context.
+ * Can be overrided by subclasses to perform input validation.
+ */
+ currentInputIsValid: function() {
arv (Not doing code reviews) 2011/01/11 21:52:45 use getter?
stuartmorgan 2011/01/11 23:18:41 Done.
+ return true;
+ },
+
+ /**
+ * Returns true if the item has been changed by an edit.
+ * Can be overrided by subclasses to return false when nothing has changed
+ * to avoid unnecessary commits.
+ */
+ hasBeenEdited: function() {
+ return true;
+ },
+
+ /**
+ * Called when editing mode starts.
+ * Can be overridden by subclasses to do any pre-edit tasks.
+ */
+ onEditStarted: function() {
+ },
+
+ /**
+ * Called when editing mode ends without cancelling.
+ * Should be overridden by subclasses to do any post-edit tasks, such as
+ * commiting the change.
+ */
+ onEditCommitted: function() {
+ },
+
+ /**
+ * Called when editing mode is cancelled.
+ * Should be overridden by subclasses to do any post-cancellation tasks,
+ * such as undoing changes to the editable controls.
+ */
+ onEditCancelled: function() {
+ },
+
+ /**
+ * Called a key is pressed. Handles committing and cancelling edits.
+ * @param {Event} e The key down event.
+ * @private
+ */
+ handleKeyDown_: function(e) {
+ if (!this.editing)
+ return;
+
+ var endEdit = false;
+ switch (e.keyIdentifier) {
+ case 'U+001B': // Esc
+ this.editCancelled_ = true;
+ endEdit = true;
+ break;
+ case 'Enter':
+ if (this.currentInputIsValid())
+ endEdit = true;
+ break;
+ }
+
+ if (endEdit) {
+ // Blurring will trigger the edit to end; see InlineEditableItemList.
+ this.ownerDocument.activeElement.blur();
+ // Make sure that handled keys aren't passed on and double-handled.
+ // (e.g., esc shouldn't both cancel an edit and close a subpage)
+ e.stopPropagation();
+ }
+ },
+ };
+
+ var InlineEditableItemList = cr.ui.define('list');
+
+ InlineEditableItemList.prototype = {
+ __proto__: DeletableItemList.prototype,
+
+ /** @inheritDoc */
+ decorate: function() {
+ DeletableItemList.prototype.decorate.call(this);
+ this.addEventListener('blur', this.handleBlur_.bind(this), true);
+ },
+
+ /**
+ * Called when an element in the list is blurred. Removes selection (thus
+ * ending edit) if focus moves outside the list.
+ * @param {Event} e The blur event.
+ * @private
+ */
+ handleBlur_: function(e) {
+ // When the blur event happens we do not know who is getting focus so we
+ // delay this a bit until we know if the new focus node is outside the
+ // list.
+ var list = this;
+ var doc = e.target.ownerDocument;
+ window.setTimeout(function() {
+ var activeElement = doc.activeElement;
+ if (!list.contains(activeElement))
+ list.selectionModel.unselectAll();
+ }, 50);
+ },
+ };
+
+ // Export
+ return {
+ InlineEditableItem: InlineEditableItem,
+ InlineEditableItemList: InlineEditableItemList,
+ };
+
Evan Stade 2011/01/11 21:06:01 extra line here and at eof
stuartmorgan 2011/01/11 23:18:41 Done.
+});
+

Powered by Google App Engine
This is Rietveld 408576698