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

Side by Side Diff: chrome/browser/resources/file_manager/js/combobutton.js

Issue 10411018: [FileBrowser] Added DefaultAction dialog to choose default action. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fixed comments. Created 8 years, 7 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) 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 /** 5 /**
6 * @fileoverview This implements a combobutton control. 6 * @fileoverview This implements a combobutton control.
7 */ 7 */
8 8
9 cr.define('cr.ui', function() { 9 cr.define('cr.ui', function() {
10 /** 10 /**
11 * Sets minWidth for the target, so it's visually as large as source.
12 * @param {HTMLElement} target Element which min-width to tune.
13 * @param {HTMLElement} source Element, which width to use.
14 */
15 function enlarge(target, source) {
16 var cs = target.ownerDocument.defaultView.getComputedStyle(target);
17 target.style.minWidth = (source.getBoundingClientRect().width -
18 parseFloat(cs.borderLeftWidth) -
19 parseFloat(cs.borderRightWidth)) + 'px';
20 }
21
22 /**
23 * Creates a new combobutton element. 11 * Creates a new combobutton element.
24 * @param {Object=} opt_propertyBag Optional properties. 12 * @param {Object=} opt_propertyBag Optional properties.
25 * @constructor 13 * @constructor
26 * @extends {HTMLUListElement} 14 * @extends {HTMLUListElement}
27 */ 15 */
28 var ComboButton = cr.ui.define('div'); 16 var ComboButton = cr.ui.define(cr.ui.MenuButton);
17
29 18
30 ComboButton.prototype = { 19 ComboButton.prototype = {
31 __proto__: HTMLDivElement.prototype, 20 __proto__: cr.ui.MenuButton.prototype,
21
22 defaultItem_: null,
32 23
33 /** 24 /**
34 * The items list. 25 * Truncates drop-down list.
35 */ 26 */
36 items_: null,
37
38 clear: function() { 27 clear: function() {
39 if (this.items_.length > 0) 28 this.menu.clear();
40 // Remove default combobox item if we have added it at addItem.
41 this.removeChild(this.firstChild);
42
43 this.items_ = [];
44 this.popup_.textContent = '';
45 this.multiple = false; 29 this.multiple = false;
46 this.popup_.style.minWidth = '';
47 }, 30 },
48 31
49 addItem: function(item) { 32 addDropDownItem: function(item) {
50 this.items_.push(item); 33 this.multiple = true;
51 if (this.items_.length == 1) { 34 this.menu.addMenuItem(item).data = item;
52 // Set first added item as default on combobox.
53 // First item should be the first element to prepend drop-down arrow and
54 // popup layer.
55 this.insertBefore(item, this.firstChild);
56 } else {
57 this.multiple = true;
58 if (this.popup_.hasChildNodes())
59 this.popup_.insertBefore(item, this.popup_.firstChild);
60 else
61 this.popup_.appendChild(item);
62 if (this.visible)
63 this.setPopupSize_();
64 }
65 }, 35 },
66 36
67 setPopupSize_: function() { 37 /**
68 this.popup_.style.bottom = (this.clientHeight + 1) + 'px'; 38 * Adds separator to drop-down list.
69 enlarge(this.popup_, this); 39 */
40 addSeparator: function() {
41 this.menu.addSeparator();
42 },
43
44 /**
45 * Default item to fire on combobox click
46 */
47 get defaultItem() {
48 return this.defaultItem_;
49 },
50 set defaultItem(defaultItem) {
51 this.defaultItem_ = defaultItem;
52 if (defaultItem.label) {
53 this.labelNode_.textContent = defaultItem.label;
54 } else {
55 this.labelNode_.textContent = '';
56 }
57
58 if (defaultItem.iconUrl) {
59 this.iconNode_.src = defaultItem.iconUrl;
60 } else {
61 this.iconNode_.src = '';
62 }
70 }, 63 },
71 64
72 /** 65 /**
73 * Initializes the element. 66 * Initializes the element.
74 */ 67 */
75 decorate: function() { 68 decorate: function() {
76 this.items_ = []; 69 cr.ui.MenuButton.prototype.decorate.call(this);
77 70
78 this.classList.add('combobutton'); 71 this.classList.add('combobutton');
79 72
73 this.iconNode_ = this.ownerDocument.createElement('img');
74 this.appendChild(this.iconNode_);
75
76 this.labelNode_ = this.ownerDocument.createElement('span');
77 this.appendChild(this.labelNode_);
78
80 var triggerIcon = this.ownerDocument.createElement('span'); 79 var triggerIcon = this.ownerDocument.createElement('span');
81 triggerIcon.className = 'disclosureindicator'; 80 triggerIcon.className = 'disclosureindicator';
82 this.trigger_ = this.ownerDocument.createElement('div'); 81 this.trigger_ = this.ownerDocument.createElement('div');
83 this.trigger_.appendChild(triggerIcon); 82 this.trigger_.appendChild(triggerIcon);
84 83
85 this.popup_ = this.ownerDocument.createElement('div'); 84 this.appendChild(this.trigger_);
86 this.popup_.className = 'popup';
87 85
88 this.appendChild(this.trigger_); 86 this.addEventListener('click', this.handleButtonClick_.bind(this));
89 this.appendChild(this.popup_);
90 87
91 this.addEventListener('click',
92 this.handleButtonClick_.bind(this));
93 this.popup_.addEventListener('click',
94 this.handlePopupClick_.bind(this));
95 this.trigger_.addEventListener('click', 88 this.trigger_.addEventListener('click',
96 this.handleTriggerClicked_.bind(this)); 89 this.handleTriggerClicked_.bind(this));
97 this.addEventListener('mouseout', this.handleMouseOut_.bind(this));
98 90
99 this.visible = true; 91 this.menu.addEventListener('activate',
92 this.handleMenuActivate_.bind(this));
93
94 // Remove mousedown event listener created by MenuButton::decorate,
95 // and move it down to trigger_.
96 this.removeEventListener('mousedown', this);
97 this.trigger_.addEventListener('mousedown', this);
98 },
99
100 /**
101 * Handles the keydown event for the menu button.
102 */
103 handleKeyDown: function(e) {
104 switch (e.keyIdentifier) {
105 case 'Down':
106 case 'Up':
107 if (!this.isMenuShown())
108 this.showMenu();
109 e.preventDefault();
110 break;
111 case 'Esc':
112 case 'U+001B': // Maybe this is remote desktop playing a prank?
113 this.hideMenu();
114 break;
115 }
100 }, 116 },
101 117
102 handleTriggerClicked_: function(event) { 118 handleTriggerClicked_: function(event) {
103 this.open = !this.open;
104 event.stopPropagation(); 119 event.stopPropagation();
105 }, 120 },
106 121
107 handleMouseOut_: function(event) { 122 handleMenuActivate_: function(event) {
108 var x = event.x; 123 this.dispatchSelectEvent(event.target.data);
109 var y = event.y;
110
111 var children = this.childNodes;
112 for (var i = 0; i < children.length; i++)
113 {
114 var r = this.children[i].getBoundingClientRect();
115 if (x >= r.left && x <= r.right && y >= r.top && y <= r.bottom)
116 return;
117 }
118
119 this.open = false;
120 }, 124 },
121 125
122 handleButtonClick_: function(event) { 126 handleButtonClick_: function() {
123 this.dispatchSelectEvent(this.items_[0]); 127 this.dispatchSelectEvent(this.defaultItem_);
124 },
125
126 handlePopupClick_: function(event) {
127 var item = event.target;
128 while (item && item.parentNode != this.popup_)
129 item = item.parentNode;
130 if (!item)
131 return;
132
133 this.open = false;
134 this.dispatchSelectEvent(item);
135 event.stopPropagation();
136 }, 128 },
137 129
138 dispatchSelectEvent: function(item) { 130 dispatchSelectEvent: function(item) {
139 var selectEvent = new Event('select'); 131 var selectEvent = new Event('select');
140 selectEvent.item = item; 132 selectEvent.item = item;
141 this.dispatchEvent(selectEvent); 133 this.dispatchEvent(selectEvent);
142 },
143
144 get visible() {
145 return this.hasAttribute('visible');
146 },
147 set visible(value) {
148 if (value) {
149 this.setAttribute('visible', 'visible');
150 setTimeout(this.setPopupSize_.bind(this), 0);
151 } else {
152 this.removeAttribute('visible');
153 }
154 } 134 }
155 }; 135 };
156 136
157 cr.defineProperty(ComboButton, 'disabled', cr.PropertyKind.BOOL_ATTR); 137 cr.defineProperty(ComboButton, 'disabled', cr.PropertyKind.BOOL_ATTR);
158 cr.defineProperty(ComboButton, 'open', cr.PropertyKind.BOOL_ATTR);
159 cr.defineProperty(ComboButton, 'multiple', cr.PropertyKind.BOOL_ATTR); 138 cr.defineProperty(ComboButton, 'multiple', cr.PropertyKind.BOOL_ATTR);
160 139
161 return { 140 return {
162 ComboButton: ComboButton 141 ComboButton: ComboButton
163 }; 142 };
164 }); 143 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698