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

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

Issue 8359008: Improve extension settings accessibility. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 years, 2 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
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 'use strict'; 6 'use strict';
7 7
8 /** 8 /**
9 * A lookup helper function to find the first node that has an id (starting 9 * A lookup helper function to find the first node that has an id (starting
10 * at |node| and going up the parent chain). 10 * at |node| and going up the parent chain).
11 * @param {Element} node The node to start looking at. 11 * @param {Element} node The node to start looking at.
12 */ 12 */
13 function findIdNode(node) { 13 function findIdNode(node) {
14 while (node && !node.id) { 14 while (node && !node.id) {
15 node = node.parentNode; 15 node = node.parentNode;
16 } 16 }
17 return node; 17 return node;
18 } 18 }
19 19
20 /** 20 /**
21 * Creates a new list of extensions. 21 * Creates a new list of extensions.
22 * @param {Object=} opt_propertyBag Optional properties. 22 * @param {Object=} opt_propertyBag Optional properties.
23 * @constructor 23 * @constructor
24 * @extends {cr.ui.div} 24 * @extends {cr.ui.div}
25 */ 25 */
26 var ExtensionsList = cr.ui.define('div'); 26 var ExtensionsList = cr.ui.define('div');
27 27
28 var handleInstalled = false; 28 var handlersInstalled = false;
29 29
30 ExtensionsList.prototype = { 30 ExtensionsList.prototype = {
31 __proto__: HTMLDivElement.prototype, 31 __proto__: HTMLDivElement.prototype,
32 32
33 /** @inheritDoc */ 33 /** @inheritDoc */
34 decorate: function() { 34 decorate: function() {
35 this.initControlsAndHandlers_(); 35 this.initControlsAndHandlers_();
36 36
37 var showingDetails = []; 37 var showingDetails = [];
38 var showingWarning = []; 38 var showingWarning = [];
(...skipping 13 matching lines...) Expand all
52 var toggleSection = $('dev'); 52 var toggleSection = $('dev');
53 if (this.data_.developerMode) { 53 if (this.data_.developerMode) {
54 toggleSection.classList.add('dev-open'); 54 toggleSection.classList.add('dev-open');
55 toggleSection.classList.remove('dev-closed'); 55 toggleSection.classList.remove('dev-closed');
56 toggleButton.checked = true; 56 toggleButton.checked = true;
57 } else { 57 } else {
58 toggleSection.classList.remove('dev-open'); 58 toggleSection.classList.remove('dev-open');
59 toggleSection.classList.add('dev-closed'); 59 toggleSection.classList.add('dev-closed');
60 } 60 }
61 61
62 // Install handler for key presses. 62 // Instal global event handlers.
63 if (!handleInstalled) { 63 if (!handlersInstalled) {
64 this.ownerDocument.addEventListener('keyup', 64 this.ownerDocument.addEventListener('keyup',
65 this.upEventHandler_.bind(this)); 65 this.upEventHandler_.bind(this));
66 this.ownerDocument.addEventListener('mouseup', 66 this.ownerDocument.addEventListener('mouseup',
67 this.upEventHandler_.bind(this)); 67 this.upEventHandler_.bind(this));
68 handleInstalled = true; 68
69 // Support full keyboard accessibility without making things ugly
70 // for users who click, by hiding some focus outlines when the user
71 // clicks anywhere, but showing them when the user presses any key.
72 this.ownerDocument.body.classList.add('hide-some-focus-outlines');
73 this.ownerDocument.addEventListener('click', (function(e) {
74 this.ownerDocument.body.classList.add('hide-some-focus-outlines');
75 return true;
76 }).bind(this), true);
77 this.ownerDocument.addEventListener('keydown', (function(e) {
78 this.ownerDocument.body.classList.remove('hide-some-focus-outlines');
79 return true;
80 }).bind(this), true);
81
82 handlersInstalled = true;
69 } 83 }
70 }, 84 },
71 85
72 /** 86 /**
73 * Deletes the existing Extension nodes from the page to make room for new 87 * Deletes the existing Extension nodes from the page to make room for new
74 * ones. It also keeps track of who was showing details so when the 88 * ones. It also keeps track of who was showing details so when the
75 * extension list gets recreated we can recreate that state. 89 * extension list gets recreated we can recreate that state.
76 * @param {Array} showingDetails An array that will contain the list of 90 * @param {Array} showingDetails An array that will contain the list of
77 * id's of extension that had the details section 91 * id's of extension that had the details section
78 * expanded. 92 * expanded.
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
151 wrapper.appendChild(vboxOuter); 165 wrapper.appendChild(vboxOuter);
152 166
153 var hbox = this.ownerDocument.createElement('div'); 167 var hbox = this.ownerDocument.createElement('div');
154 hbox.classList.add('hbox'); 168 hbox.classList.add('hbox');
155 vboxOuter.appendChild(hbox); 169 vboxOuter.appendChild(hbox);
156 170
157 // Add a container div for the zippy, so we can extend the hit area. 171 // Add a container div for the zippy, so we can extend the hit area.
158 var container = this.ownerDocument.createElement('div'); 172 var container = this.ownerDocument.createElement('div');
159 // Clicking anywhere on the div expands/collapses the details. 173 // Clicking anywhere on the div expands/collapses the details.
160 container.classList.add('extension-zippy-container'); 174 container.classList.add('extension-zippy-container');
175 container.title = expanded ?
176 localStrings.getString('extensionSettingsHideDetails') :
177 localStrings.getString('extensionSettingsShowDetails');
178 container.tabIndex = 0;
179 container.setAttribute('role', 'button');
180 container.setAttribute('aria-controls', extension.id + '_details');
181 container.setAttribute('aria-expanded', expanded);
161 container.addEventListener('click', this.handleZippyClick_.bind(this)); 182 container.addEventListener('click', this.handleZippyClick_.bind(this));
183 container.addEventListener('keydown',
184 this.handleZippyKeyDown_.bind(this));
162 hbox.appendChild(container); 185 hbox.appendChild(container);
163 186
164 // On the far left we have the zippy icon. 187 // On the far left we have the zippy icon.
165 var div = this.ownerDocument.createElement('div'); 188 var div = this.ownerDocument.createElement('div');
166 div.id = id + '_zippy'; 189 div.id = id + '_zippy';
167 div.classList.add('extension-zippy-default'); 190 div.classList.add('extension-zippy-default');
168 div.classList.add(expanded ? 'extension-zippy-expanded' : 191 div.classList.add(expanded ? 'extension-zippy-expanded' :
169 'extension-zippy-collapsed'); 192 'extension-zippy-collapsed');
170 container.appendChild(div); 193 container.appendChild(div);
171 194
(...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after
515 538
516 var span = this.ownerDocument.createElement('span'); 539 var span = this.ownerDocument.createElement('span');
517 span.innerHTML = 540 span.innerHTML =
518 localStrings.getString('extensionSettingsIncognitoWarning'); 541 localStrings.getString('extensionSettingsIncognitoWarning');
519 content.appendChild(span); 542 content.appendChild(span);
520 itemsShown++; 543 itemsShown++;
521 } 544 }
522 545
523 var zippy = extension.id + '_zippy'; 546 var zippy = extension.id + '_zippy';
524 $(zippy).hidden = !itemsShown; 547 $(zippy).hidden = !itemsShown;
548
549 // If this isn't expanded now, make sure the newly-added controls
550 // are not part of the tab order.
551 if (!expanded) {
552 var detailsControls = details.querySelectorAll('a, input');
553 for (var i = 0; i < detailsControls.length; i++)
554 detailsControls[i].tabIndex = -1;
555 }
525 }, 556 },
526 557
527 /** 558 /**
528 * A helper function to add contextual actions for extensions (action links) 559 * A helper function to add contextual actions for extensions (action links)
529 * to the page. 560 * to the page.
530 */ 561 */
531 addLinkTo_: function(parent, linkText, id, handler) { 562 addLinkTo_: function(parent, linkText, id, handler) {
532 var link = this.ownerDocument.createElement('a'); 563 var link = this.ownerDocument.createElement('a');
533 link.className = 'extension-links-trailing'; 564 link.className = 'extension-links-trailing';
534 link.textContent = linkText; 565 link.textContent = linkText;
(...skipping 10 matching lines...) Expand all
545 */ 576 */
546 getExtensionWithId_: function(id) { 577 getExtensionWithId_: function(id) {
547 for (var i = 0; i < this.data_.extensions.length; ++i) { 578 for (var i = 0; i < this.data_.extensions.length; ++i) {
548 if (this.data_.extensions[i].id == id) 579 if (this.data_.extensions[i].id == id)
549 return this.data_.extensions[i]; 580 return this.data_.extensions[i];
550 } 581 }
551 return null; 582 return null;
552 }, 583 },
553 584
554 /** 585 /**
586 * Handles a key down on the zippy icon.
587 * @param {Event} e Key event.
588 * @private
589 */
590 handleZippyKeyDown_: function(e) {
591 if (e.keyCode == 13 || e.keyCode == 32) // Enter or Space.
592 this.handleZippyClick_(e);
593 },
594
595 /**
555 * Handles the mouseclick on the zippy icon (that expands and collapses the 596 * Handles the mouseclick on the zippy icon (that expands and collapses the
556 * details section). 597 * details section).
557 * @param {Event} e Change event. 598 * @param {Event} e Mouse event.
558 * @private 599 * @private
559 */ 600 */
560 handleZippyClick_: function(e) { 601 handleZippyClick_: function(e) {
561 var node = findIdNode(e.target.parentNode); 602 var node = findIdNode(e.target.parentNode);
562 var iter = this.firstChild; 603 var iter = this.firstChild;
563 while (iter) { 604 while (iter) {
564 var zippy = $(iter.id + '_zippy'); 605 var zippy = $(iter.id + '_zippy');
565 var details = $(iter.id + '_details'); 606 var details = $(iter.id + '_details');
607 var container = zippy.parentElement;
566 if (iter.id == node.id) { 608 if (iter.id == node.id) {
567 // Toggle visibility. 609 // Toggle visibility.
568 if (iter.classList.contains('extension-list-item-expanded')) { 610 if (iter.classList.contains('extension-list-item-expanded')) {
569 // Hide yo kids! Hide yo wife! 611 // Hide yo kids! Hide yo wife!
570 zippy.classList.remove('extension-zippy-expanded'); 612 zippy.classList.remove('extension-zippy-expanded');
571 zippy.classList.add('extension-zippy-collapsed'); 613 zippy.classList.add('extension-zippy-collapsed');
572 details.classList.remove('extension-details-visible'); 614 details.classList.remove('extension-details-visible');
573 details.classList.add('extension-details-hidden'); 615 details.classList.add('extension-details-hidden');
574 iter.classList.remove('extension-list-item-expanded'); 616 iter.classList.remove('extension-list-item-expanded');
575 iter.classList.add('extension-list-item-collaped'); 617 iter.classList.add('extension-list-item-collaped');
618 container.setAttribute('aria-expanded', 'false');
619 container.title =
620 localStrings.getString('extensionSettingsShowDetails');
621 var detailsControls = details.querySelectorAll('a, input');
622 for (var i = 0; i < detailsControls.length; i++)
623 detailsControls[i].tabIndex = -1;
576 624
577 // Hide yo incognito warning. 625 // Hide yo incognito warning.
578 var butterBar = 626 var butterBar =
579 this.querySelector('#' + iter.id + '_incognitoWarning'); 627 this.querySelector('#' + iter.id + '_incognitoWarning');
580 if (!(butterBar === null)) 628 if (!(butterBar === null))
581 butterBar.hidden = true; 629 butterBar.hidden = true;
582 } else { 630 } else {
583 // Show the contents. 631 // Show the contents.
584 zippy.classList.remove('extension-zippy-collapsed'); 632 zippy.classList.remove('extension-zippy-collapsed');
585 zippy.classList.add('extension-zippy-expanded'); 633 zippy.classList.add('extension-zippy-expanded');
586 details.classList.remove('extension-details-hidden'); 634 details.classList.remove('extension-details-hidden');
587 details.classList.add('extension-details-visible'); 635 details.classList.add('extension-details-visible');
588 iter.classList.remove('extension-list-item-collaped'); 636 iter.classList.remove('extension-list-item-collaped');
589 iter.classList.add('extension-list-item-expanded'); 637 iter.classList.add('extension-list-item-expanded');
638 container.setAttribute('aria-expanded', 'true');
639 container.title =
640 localStrings.getString('extensionSettingsHideDetails');
641 var detailsControls = details.querySelectorAll('a, input');
642 for (var i = 0; i < detailsControls.length; i++)
643 detailsControls[i].tabIndex = 0;
590 } 644 }
591 } 645 }
592 iter = iter.nextSibling; 646 iter = iter.nextSibling;
593 } 647 }
594 }, 648 },
595 649
596 /** 650 /**
597 * Handles the mouse-up and keyboard-up events. This is used to limit the 651 * Handles the mouse-up and keyboard-up events. This is used to limit the
598 * number of items to show in the list, when the user is searching for items 652 * number of items to show in the list, when the user is searching for items
599 * with the search box. Otherwise, if one match is found, the whole list of 653 * with the search box. Otherwise, if one match is found, the whole list of
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
726 ]); 780 ]);
727 } 781 }
728 } 782 }
729 }, 783 },
730 }; 784 };
731 785
732 return { 786 return {
733 ExtensionsList: ExtensionsList 787 ExtensionsList: ExtensionsList
734 }; 788 };
735 }); 789 });
OLDNEW
« no previous file with comments | « chrome/app/generated_resources.grd ('k') | chrome/browser/resources/options/extension_settings.css » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698