172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2010 The Chromium Authors. All rights reserved. 272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Use of this source code is governed by a BSD-style license that can be 372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// found in the LICENSE file. 472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsencr.define('options', function() { 672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const DeletableItem = options.DeletableItem; 772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const DeletableItemList = options.DeletableItemList; 872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen /** 1072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen * Creates a new list item with support for inline editing. 1172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen * @constructor 1272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen * @extends {options.DeletableListItem} 1372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen */ 1472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen function InlineEditableItem() { 1572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen var el = cr.doc.createElement('div'); 1672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen InlineEditableItem.decorate(el); 1772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return el; 1872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 1972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 2072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen /** 2172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen * Decorates an element as a inline-editable list item. Note that this is 2272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen * a subclass of DeletableItem. 2372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen * @param {!HTMLElement} el The element to decorate. 2472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen */ 2572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen InlineEditableItem.decorate = function(el) { 2672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen el.__proto__ = InlineEditableItem.prototype; 2772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen el.decorate(); 2872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen }; 2972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 3072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen InlineEditableItem.prototype = { 3172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen __proto__: DeletableItem.prototype, 3272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 3372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen /** 3472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen * Whether or not this item can be edited. 3572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen * @type {boolean} 3672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen * @private 3772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen */ 3872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen editable_: true, 3972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 4072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen /** 41ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * Whether or not this is a placeholder for adding a new item. 42ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * @type {boolean} 43ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * @private 44ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen */ 45ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen isPlaceholder_: false, 46ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 47ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen /** 48ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * Fields associated with edit mode. 49ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * @type {array} 50ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * @private 51ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen */ 52ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen editFields_: null, 53ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 54ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen /** 5572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen * Whether or not the current edit should be considered cancelled, rather 5672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen * than committed, when editing ends. 5772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen * @type {boolean} 5872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen * @private 5972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen */ 6072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen editCancelled_: true, 6172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 62dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen /** 63dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen * The editable item corresponding to the last click, if any. Used to decide 64dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen * initial focus when entering edit mode. 65dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen * @type {HTMLElement} 66dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen * @private 67dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen */ 68dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen editClickTarget_: null, 69dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 7072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen /** @inheritDoc */ 7172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen decorate: function() { 7272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen DeletableItem.prototype.decorate.call(this); 7372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 74ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen this.editFields_ = []; 75dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen this.addEventListener('mousedown', this.handleMouseDown_.bind(this)); 7672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen this.addEventListener('keydown', this.handleKeyDown_.bind(this)); 7772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen this.addEventListener('leadChange', this.handleLeadChange_); 7872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen }, 7972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 8072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen /** @inheritDoc */ 8172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen selectionChanged: function() { 8272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen this.updateEditState(); 8372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen }, 8472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 8572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen /** 8672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen * Called when this element gains or loses 'lead' status. Updates editing 8772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen * mode accordingly. 8872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen * @private 8972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen */ 9072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen handleLeadChange_: function() { 9172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen this.updateEditState(); 9272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen }, 9372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 9472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen /** 9572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen * Updates the edit state based on the current selected and lead states. 9672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen */ 9772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen updateEditState: function() { 9872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (this.editable) 9972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen this.editing = this.selected && this.lead; 10072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen }, 10172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 10272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen /** 10372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen * Whether the user is currently editing the list item. 10472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen * @type {boolean} 10572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen */ 10672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen get editing() { 10772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return this.hasAttribute('editing'); 10872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen }, 10972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen set editing(editing) { 11072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (this.editing == editing) 11172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return; 11272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 11372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (editing) 11472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen this.setAttribute('editing', ''); 11572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen else 11672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen this.removeAttribute('editing'); 11772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 11872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (editing) { 11972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen this.editCancelled_ = false; 12072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 12172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen cr.dispatchSimpleEvent(this, 'edit', true); 12272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 123dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen var focusElement = this.editClickTarget_ || this.initialFocusElement; 124dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen this.editClickTarget_ = null; 125dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 12672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // When this is called in response to the selectedChange event, 12772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // the list grabs focus immediately afterwards. Thus we must delay 12872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // our focus grab. 129dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen var self = this; 13072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (focusElement) { 13172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen window.setTimeout(function() { 13272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Make sure we are still in edit mode by the time we execute. 13372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (self.editing) { 13472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen focusElement.focus(); 13572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen focusElement.select(); 13672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 13772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen }, 50); 13872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 13972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } else { 14072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!this.editCancelled_ && this.hasBeenEdited && 14172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen this.currentInputIsValid) { 14272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen this.updateStaticValues_(); 14372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen cr.dispatchSimpleEvent(this, 'commitedit', true); 14472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } else { 14572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen this.resetEditableValues_(); 14672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen cr.dispatchSimpleEvent(this, 'canceledit', true); 14772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 14872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 14972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen }, 15072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 15172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen /** 15272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen * Whether the item is editable. 15372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen * @type {boolean} 15472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen */ 15572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen get editable() { 15672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return this.editable_; 15772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen }, 15872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen set editable(editable) { 15972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen this.editable_ = editable; 16072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!editable) 16172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen this.editing = false; 16272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen }, 16372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 16472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen /** 165ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * Whether the item is a new item placeholder. 166ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * @type {boolean} 167ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen */ 168ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen get isPlaceholder() { 169ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return this.isPlaceholder_; 170ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen }, 171ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen set isPlaceholder(isPlaceholder) { 172ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen this.isPlaceholder_ = isPlaceholder; 173ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (isPlaceholder) 174ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen this.deletable = false; 175ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen }, 176ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 177ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen /** 178dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen * The HTML element that should have focus initially when editing starts, 179dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen * if a specific element wasn't clicked. 18072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen * Defaults to the first <input> element; can be overriden by subclasses if 18172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen * a different element should be focused. 18272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen * @type {HTMLElement} 18372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen */ 18472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen get initialFocusElement() { 18572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return this.contentElement.querySelector('input'); 18672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen }, 18772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 18872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen /** 18972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen * Whether the input in currently valid to submit. If this returns false 19072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen * when editing would be submitted, either editing will not be ended, 19172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen * or it will be cancelled, depending on the context. 19272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen * Can be overrided by subclasses to perform input validation. 19372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen * @type {boolean} 19472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen */ 19572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen get currentInputIsValid() { 19672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return true; 19772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen }, 19872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 19972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen /** 20072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen * Returns true if the item has been changed by an edit. 20172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen * Can be overrided by subclasses to return false when nothing has changed 20272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen * to avoid unnecessary commits. 20372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen * @type {boolean} 20472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen */ 20572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen get hasBeenEdited() { 20672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return true; 20772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen }, 20872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 20972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen /** 21072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen * Returns a div containing an <input>, as well as static text if 211ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * isPlaceholder is not true. 21272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen * @param {string} text The text of the cell. 21372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen * @return {HTMLElement} The HTML element for the cell. 21472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen * @private 21572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen */ 216ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen createEditableTextCell: function(text) { 21772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen var container = this.ownerDocument.createElement('div'); 21872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 219ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!this.isPlaceholder) { 22072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen var textEl = this.ownerDocument.createElement('div'); 22172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen textEl.className = 'static-text'; 22272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen textEl.textContent = text; 22372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen textEl.setAttribute('displaymode', 'static'); 22472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen container.appendChild(textEl); 22572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 22672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 22772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen var inputEl = this.ownerDocument.createElement('input'); 22872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen inputEl.type = 'text'; 22972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen inputEl.value = text; 230ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!this.isPlaceholder) { 23172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen inputEl.setAttribute('displaymode', 'edit'); 23272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen inputEl.staticVersion = textEl; 23372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 23472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen container.appendChild(inputEl); 235ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen this.editFields_.push(inputEl); 23672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 23772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return container; 23872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen }, 23972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 24072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen /** 24172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen * Resets the editable version of any controls created by createEditable* 24272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen * to match the static text. 24372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen * @private 24472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen */ 24572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen resetEditableValues_: function() { 246ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen var editFields = this.editFields_; 24772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen for (var i = 0; i < editFields.length; i++) { 24872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen var staticLabel = editFields[i].staticVersion; 249ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!staticLabel && !this.isPlaceholder) 25072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen continue; 251ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (editFields[i].tagName == 'INPUT') { 252ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen editFields[i].value = 253ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen this.isPlaceholder ? '' : staticLabel.textContent; 254ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 25572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Add more tag types here as new createEditable* methods are added. 25672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 25772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen editFields[i].setCustomValidity(''); 25872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 25972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen }, 26072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 26172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen /** 26272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen * Sets the static version of any controls created by createEditable* 26372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen * to match the current value of the editable version. Called on commit so 26472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen * that there's no flicker of the old value before the model updates. 26572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen * @private 26672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen */ 26772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen updateStaticValues_: function() { 268ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen var editFields = this.editFields_; 26972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen for (var i = 0; i < editFields.length; i++) { 27072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen var staticLabel = editFields[i].staticVersion; 27172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!staticLabel) 27272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen continue; 27372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (editFields[i].tagName == 'INPUT') 27472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen staticLabel.textContent = editFields[i].value; 27572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Add more tag types here as new createEditable* methods are added. 27672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 27772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen }, 27872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 27972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen /** 28072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen * Called a key is pressed. Handles committing and cancelling edits. 28172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen * @param {Event} e The key down event. 28272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen * @private 28372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen */ 28472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen handleKeyDown_: function(e) { 28572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!this.editing) 28672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return; 28772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 28872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen var endEdit = false; 28972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen switch (e.keyIdentifier) { 29072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen case 'U+001B': // Esc 29172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen this.editCancelled_ = true; 29272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen endEdit = true; 29372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen break; 29472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen case 'Enter': 29572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (this.currentInputIsValid) 29672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen endEdit = true; 29772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen break; 29872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 29972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 30072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (endEdit) { 30172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Blurring will trigger the edit to end; see InlineEditableItemList. 30272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen this.ownerDocument.activeElement.blur(); 30372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Make sure that handled keys aren't passed on and double-handled. 30472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // (e.g., esc shouldn't both cancel an edit and close a subpage) 30572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen e.stopPropagation(); 30672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 30772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen }, 308dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 309dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen /** 310dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen * Called when the list item is clicked. If the click target corresponds to 311dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen * an editable item, stores that item to focus when edit mode is started. 312dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen * @param {Event} e The mouse down event. 313dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen * @private 314dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen */ 315dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen handleMouseDown_: function(e) { 316dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (!this.editable || this.editing) 317dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return; 318dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 319dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen var clickTarget = e.target; 320ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen var editFields = this.editFields_; 321dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen for (var i = 0; i < editFields.length; i++) { 322ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (editFields[i] == clickTarget || 323ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen editFields[i].staticVersion == clickTarget) { 324dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen this.editClickTarget_ = editFields[i]; 325dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return; 326dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 327dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 328dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen }, 32972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen }; 33072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 33172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen var InlineEditableItemList = cr.ui.define('list'); 33272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 33372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen InlineEditableItemList.prototype = { 33472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen __proto__: DeletableItemList.prototype, 33572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 33672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen /** @inheritDoc */ 33772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen decorate: function() { 33872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen DeletableItemList.prototype.decorate.call(this); 33972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen this.setAttribute('inlineeditable', ''); 34072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen this.addEventListener('hasElementFocusChange', 34172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen this.handleListFocusChange_); 34272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen }, 34372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 34472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen /** 34572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen * Called when the list hierarchy as a whole loses or gains focus; starts 34672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen * or ends editing for the lead item if necessary. 34772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen * @param {Event} e The change event. 34872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen * @private 34972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen */ 35072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen handleListFocusChange_: function(e) { 35172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen var leadItem = this.getListItemByIndex(this.selectionModel.leadIndex); 35272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (leadItem) { 35372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (e.newValue) 35472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen leadItem.updateEditState(); 35572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen else 35672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen leadItem.editing = false; 35772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 35872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen }, 35972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen }; 36072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 36172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Export 36272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return { 36372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen InlineEditableItem: InlineEditableItem, 36472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen InlineEditableItemList: InlineEditableItemList, 36572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen }; 36672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}); 367