OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 cr.define('options', function() { | 5 cr.define('options', function() { |
6 /** @const */ var DeletableItem = options.DeletableItem; | 6 /** @const */ var DeletableItem = options.DeletableItem; |
7 /** @const */ var DeletableItemList = options.DeletableItemList; | 7 /** @const */ var DeletableItemList = options.DeletableItemList; |
8 | 8 |
9 /** | 9 /** |
10 * Creates a new list item with support for inline editing. | 10 * Creates a new list item with support for inline editing. |
(...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
315 }, | 315 }, |
316 | 316 |
317 /** | 317 /** |
318 * Returns a div containing an <input>, as well as static text if | 318 * Returns a div containing an <input>, as well as static text if |
319 * isPlaceholder is not true. | 319 * isPlaceholder is not true. |
320 * @param {string} text The text of the cell. | 320 * @param {string} text The text of the cell. |
321 * @return {HTMLElement} The HTML element for the cell. | 321 * @return {HTMLElement} The HTML element for the cell. |
322 * @private | 322 * @private |
323 */ | 323 */ |
324 createEditableTextCell: function(text) { | 324 createEditableTextCell: function(text) { |
325 var container = /** @type {HTMLElement} */( | 325 var container = |
326 this.ownerDocument.createElement('div')); | 326 /** @type {HTMLElement} */ (this.ownerDocument.createElement('div')); |
327 var textEl = null; | 327 var textEl = null; |
328 if (!this.isPlaceholder) { | 328 if (!this.isPlaceholder) { |
329 textEl = this.ownerDocument.createElement('div'); | 329 textEl = this.ownerDocument.createElement('div'); |
330 textEl.className = 'static-text overruleable'; | 330 textEl.className = 'static-text overruleable'; |
331 textEl.textContent = text; | 331 textEl.textContent = text; |
332 textEl.setAttribute('displaymode', 'static'); | 332 textEl.setAttribute('displaymode', 'static'); |
333 container.appendChild(textEl); | 333 container.appendChild(textEl); |
334 } | 334 } |
335 | 335 |
336 var inputEl = this.ownerDocument.createElement('input'); | 336 var inputEl = this.ownerDocument.createElement('input'); |
(...skipping 26 matching lines...) Expand all Loading... |
363 */ | 363 */ |
364 addEditField: function(control, staticElement) { | 364 addEditField: function(control, staticElement) { |
365 control.staticVersion = staticElement; | 365 control.staticVersion = staticElement; |
366 if (this.editable) | 366 if (this.editable) |
367 control.tabIndex = -1; | 367 control.tabIndex = -1; |
368 | 368 |
369 if (control.staticVersion) { | 369 if (control.staticVersion) { |
370 if (this.editable) | 370 if (this.editable) |
371 control.staticVersion.tabIndex = -1; | 371 control.staticVersion.tabIndex = -1; |
372 control.staticVersion.editableVersion = control; | 372 control.staticVersion.editableVersion = control; |
373 control.staticVersion.addEventListener('focus', | 373 control.staticVersion.addEventListener( |
374 this.handleFocus.bind(this)); | 374 'focus', this.handleFocus.bind(this)); |
375 } | 375 } |
376 this.editFields_.push(control); | 376 this.editFields_.push(control); |
377 }, | 377 }, |
378 | 378 |
379 /** | 379 /** |
380 * Set the column index for a child element of this InlineEditableItem. | 380 * Set the column index for a child element of this InlineEditableItem. |
381 * Only elements with a column index will be keyboard focusable, e.g. by | 381 * Only elements with a column index will be keyboard focusable, e.g. by |
382 * pressing the tab key. | 382 * pressing the tab key. |
383 * @param {Element} element Element whose column index to set. Method does | 383 * @param {Element} element Element whose column index to set. Method does |
384 * nothing if element is null. | 384 * nothing if element is null. |
(...skipping 17 matching lines...) Expand all Loading... |
402 */ | 402 */ |
403 resetEditableValues_: function() { | 403 resetEditableValues_: function() { |
404 var editFields = this.editFields_; | 404 var editFields = this.editFields_; |
405 for (var i = 0; i < editFields.length; i++) { | 405 for (var i = 0; i < editFields.length; i++) { |
406 var staticLabel = editFields[i].staticVersion; | 406 var staticLabel = editFields[i].staticVersion; |
407 if (!staticLabel && !this.isPlaceholder) | 407 if (!staticLabel && !this.isPlaceholder) |
408 continue; | 408 continue; |
409 | 409 |
410 if (editFields[i].tagName == 'INPUT') { | 410 if (editFields[i].tagName == 'INPUT') { |
411 editFields[i].value = | 411 editFields[i].value = |
412 this.isPlaceholder ? '' : staticLabel.textContent; | 412 this.isPlaceholder ? '' : staticLabel.textContent; |
413 } | 413 } |
414 // Add more tag types here as new createEditable* methods are added. | 414 // Add more tag types here as new createEditable* methods are added. |
415 | 415 |
416 editFields[i].setCustomValidity(''); | 416 editFields[i].setCustomValidity(''); |
417 } | 417 } |
418 }, | 418 }, |
419 | 419 |
420 /** | 420 /** |
421 * Sets the static version of any controls created by createEditable* | 421 * Sets the static version of any controls created by createEditable* |
422 * to match the current value of the editable version. Called on commit so | 422 * to match the current value of the editable version. Called on commit so |
(...skipping 13 matching lines...) Expand all Loading... |
436 } | 436 } |
437 }, | 437 }, |
438 | 438 |
439 /** | 439 /** |
440 * Returns the index of the column that currently has focus, or -1 if no | 440 * Returns the index of the column that currently has focus, or -1 if no |
441 * column has focus. | 441 * column has focus. |
442 * @return {number} | 442 * @return {number} |
443 * @private | 443 * @private |
444 */ | 444 */ |
445 getFocusedColumnIndex_: function() { | 445 getFocusedColumnIndex_: function() { |
446 var element = document.activeElement.editableVersion || | 446 var element = |
447 document.activeElement; | 447 document.activeElement.editableVersion || document.activeElement; |
448 | 448 |
449 if (element.hasAttribute('inlineeditable-column')) | 449 if (element.hasAttribute('inlineeditable-column')) |
450 return parseInt(element.getAttribute('inlineeditable-column'), 10); | 450 return parseInt(element.getAttribute('inlineeditable-column'), 10); |
451 return -1; | 451 return -1; |
452 }, | 452 }, |
453 | 453 |
454 /** | 454 /** |
455 * Returns the element from the column that has the largest index where: | 455 * Returns the element from the column that has the largest index where: |
456 * where: | 456 * where: |
457 * + index <= startIndex, and | 457 * + index <= startIndex, and |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
541 /** | 541 /** |
542 * Called when this InlineEditableItem or any of its children are given | 542 * Called when this InlineEditableItem or any of its children are given |
543 * focus. Updates focusedColumnIndex with the index of the newly focused | 543 * focus. Updates focusedColumnIndex with the index of the newly focused |
544 * column, or -1 if the focused element does not have a column index. | 544 * column, or -1 if the focused element does not have a column index. |
545 * @param {Event} e The focusin event. | 545 * @param {Event} e The focusin event. |
546 * @private | 546 * @private |
547 */ | 547 */ |
548 handleFocusIn_: function(e) { | 548 handleFocusIn_: function(e) { |
549 var target = e.target.editableVersion || e.target; | 549 var target = e.target.editableVersion || e.target; |
550 this.focusedColumnIndex = target.hasAttribute('inlineeditable-column') ? | 550 this.focusedColumnIndex = target.hasAttribute('inlineeditable-column') ? |
551 parseInt(target.getAttribute('inlineeditable-column'), 10) : -1; | 551 parseInt(target.getAttribute('inlineeditable-column'), 10) : |
| 552 -1; |
552 }, | 553 }, |
553 }; | 554 }; |
554 | 555 |
555 /** | 556 /** |
556 * Takes care of committing changes to inline editable list items when the | 557 * Takes care of committing changes to inline editable list items when the |
557 * window loses focus. | 558 * window loses focus. |
558 */ | 559 */ |
559 function handleWindowBlurs() { | 560 function handleWindowBlurs() { |
560 window.addEventListener('blur', function(e) { | 561 window.addEventListener('blur', function(e) { |
561 var itemAncestor = findAncestor(document.activeElement, function(node) { | 562 var itemAncestor = findAncestor(document.activeElement, function(node) { |
(...skipping 27 matching lines...) Expand all Loading... |
589 * Focuses the input element of the placeholder if true. | 590 * Focuses the input element of the placeholder if true. |
590 * @type {boolean} | 591 * @type {boolean} |
591 * @private | 592 * @private |
592 */ | 593 */ |
593 needsToFocusPlaceholder_: false, | 594 needsToFocusPlaceholder_: false, |
594 | 595 |
595 /** @override */ | 596 /** @override */ |
596 decorate: function() { | 597 decorate: function() { |
597 DeletableItemList.prototype.decorate.call(this); | 598 DeletableItemList.prototype.decorate.call(this); |
598 this.setAttribute('inlineeditable', ''); | 599 this.setAttribute('inlineeditable', ''); |
599 this.addEventListener('hasElementFocusChange', | 600 this.addEventListener( |
600 this.handleListFocusChange_); | 601 'hasElementFocusChange', this.handleListFocusChange_); |
601 // <list> isn't focusable by default, but cr.ui.List defaults tabindex to | 602 // <list> isn't focusable by default, but cr.ui.List defaults tabindex to |
602 // 0 if it's not set. | 603 // 0 if it's not set. |
603 this.tabIndex = -1; | 604 this.tabIndex = -1; |
604 }, | 605 }, |
605 | 606 |
606 /** | 607 /** |
607 * Called when the list hierarchy as a whole loses or gains focus; starts | 608 * Called when the list hierarchy as a whole loses or gains focus; starts |
608 * or ends editing for the lead item if necessary. | 609 * or ends editing for the lead item if necessary. |
609 * @param {Event} e The change event. | 610 * @param {Event} e The change event. |
610 * @private | 611 * @private |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
689 | 690 |
690 /** | 691 /** |
691 * Set the selected index without changing the focused element on the page. | 692 * Set the selected index without changing the focused element on the page. |
692 * Used to change the selected index when the list doesn't have focus (and | 693 * Used to change the selected index when the list doesn't have focus (and |
693 * doesn't want to take focus). | 694 * doesn't want to take focus). |
694 * @param {number} index The index to select. | 695 * @param {number} index The index to select. |
695 */ | 696 */ |
696 selectIndexWithoutFocusing: function(index) { | 697 selectIndexWithoutFocusing: function(index) { |
697 // Remove focusability from old item. | 698 // Remove focusability from old item. |
698 var oldItem = this.getListItemByIndex(this.selectionModel.leadIndex) || | 699 var oldItem = this.getListItemByIndex(this.selectionModel.leadIndex) || |
699 this.getInitialFocusableItem(); | 700 this.getInitialFocusableItem(); |
700 if (oldItem) { | 701 if (oldItem) { |
701 oldItem.setEditableValuesFocusable(false); | 702 oldItem.setEditableValuesFocusable(false); |
702 oldItem.setStaticValuesFocusable(false); | 703 oldItem.setStaticValuesFocusable(false); |
703 oldItem.setCloseButtonFocusable(false); | 704 oldItem.setCloseButtonFocusable(false); |
704 oldItem.lead = false; | 705 oldItem.lead = false; |
705 } | 706 } |
706 | 707 |
707 // Select the new item. | 708 // Select the new item. |
708 this.ignoreChangeEvents(function() { | 709 this.ignoreChangeEvents(function() { |
709 this.selectionModel.selectedIndex = index; | 710 this.selectionModel.selectedIndex = index; |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
749 * May be overridden by subclasses to disable focusing the placeholder. | 750 * May be overridden by subclasses to disable focusing the placeholder. |
750 * @return {boolean} True if the placeholder element should be focused on | 751 * @return {boolean} True if the placeholder element should be focused on |
751 * edit commit. | 752 * edit commit. |
752 * @protected | 753 * @protected |
753 */ | 754 */ |
754 shouldFocusPlaceholderOnEditCommit: function() { | 755 shouldFocusPlaceholderOnEditCommit: function() { |
755 return true; | 756 return true; |
756 }, | 757 }, |
757 | 758 |
758 /** | 759 /** |
759 * Override to change which item is initially focusable. | 760 * Override to change which item is initially focusable. |
760 * @return {options.InlineEditableItem} Initially focusable item or null. | 761 * @return {options.InlineEditableItem} Initially focusable item or null. |
761 * @protected | 762 * @protected |
762 */ | 763 */ |
763 getInitialFocusableItem: function() { | 764 getInitialFocusableItem: function() { |
764 return /** @type {options.InlineEditableItem} */( | 765 return /** @type {options.InlineEditableItem} */ ( |
765 this.getListItemByIndex(0)); | 766 this.getListItemByIndex(0)); |
766 }, | 767 }, |
767 }; | 768 }; |
768 | 769 |
769 // Export | 770 // Export |
770 return { | 771 return { |
771 InlineEditableItem: InlineEditableItem, | 772 InlineEditableItem: InlineEditableItem, |
772 InlineEditableItemList: InlineEditableItemList, | 773 InlineEditableItemList: InlineEditableItemList, |
773 }; | 774 }; |
774 }); | 775 }); |
OLD | NEW |