Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / third_party / WebKit / Source / devtools / front_end / ui / Toolbar.js
bloba56de42eb1b35fc32905035c56431fa97d5ae82c
1 /*
2 * Copyright (C) 2009 Google Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
13 * distribution.
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 /**
32 * @constructor
33 * @param {!Element=} parentElement
35 WebInspector.Toolbar = function(parentElement)
37 /** @type {!Array.<!WebInspector.ToolbarItem>} */
38 this._items = [];
39 this.element = parentElement ? parentElement.createChild("div", "toolbar") : createElementWithClass("div", "toolbar");
40 this._shadowRoot = WebInspector.createShadowRootWithCoreStyles(this.element);
41 this._shadowRoot.appendChild(WebInspector.Widget.createStyleElement("ui/toolbar.css"));
42 this._contentElement = this._shadowRoot.createChild("div", "toolbar-shadow");
43 this._contentElement.createChild("content");
46 WebInspector.Toolbar.prototype = {
47 makeVertical: function()
49 this._contentElement.classList.add("vertical");
52 makeBlueOnHover: function()
54 this._contentElement.classList.add("blue-on-hover");
57 /**
58 * @param {boolean} enabled
60 setEnabled: function(enabled)
62 for (var item of this._items)
63 item.setEnabled(enabled);
66 /**
67 * @param {!WebInspector.ToolbarItem} item
69 appendToolbarItem: function(item)
71 this._items.push(item);
72 item._toolbar = this;
73 this._contentElement.insertBefore(item.element, this._contentElement.lastChild);
74 this._hideSeparatorDupes();
77 appendSeparator: function()
79 this.appendToolbarItem(new WebInspector.ToolbarSeparator());
82 removeToolbarItems: function()
84 for (var item of this._items)
85 delete item._toolbar;
86 this._items = [];
87 this._contentElement.removeChildren();
88 this._contentElement.createChild("content");
91 /**
92 * @param {string} color
94 setColor: function(color)
96 var style = createElement("style");
97 style.textContent = "button.toolbar-item .glyph { background-color: " + color + " !important }";
98 this._shadowRoot.appendChild(style);
102 * @param {string} color
104 setToggledColor: function(color)
106 var style = createElement("style");
107 style.textContent = "button.toolbar-item.toggled-on .glyph { background-color: " + color + " !important }";
108 this._shadowRoot.appendChild(style);
111 _hideSeparatorDupes: function()
113 if (!this._items.length)
114 return;
115 // Don't hide first and last separators if they were added explicitly.
116 var previousIsSeparator = this._items[0] instanceof WebInspector.ToolbarSeparator;
117 var lastSeparator;
118 for (var i = 1; i < this._items.length; ++i) {
119 if (this._items[i] instanceof WebInspector.ToolbarSeparator) {
120 this._items[i].setVisible(!previousIsSeparator);
121 previousIsSeparator = true;
122 lastSeparator = this._items[i];
123 continue;
125 if (this._items[i].visible()) {
126 previousIsSeparator = false;
127 lastSeparator = null;
130 if (lastSeparator && lastSeparator !== this._items.peekLast())
131 lastSeparator.setVisible(false);
136 * @constructor
137 * @extends {WebInspector.Object}
138 * @param {!Element} element
140 WebInspector.ToolbarItem = function(element)
142 this.element = element;
143 this.element.classList.add("toolbar-item");
144 this._enabled = true;
145 this._visible = true;
146 this.element.addEventListener("mouseenter", this._mouseEnter.bind(this), false);
147 this.element.addEventListener("mouseleave", this._mouseLeave.bind(this), false);
150 WebInspector.ToolbarItem.prototype = {
151 _mouseEnter: function()
153 this.element.classList.add("hover");
156 _mouseLeave: function()
158 this.element.classList.remove("hover");
162 * @param {boolean} value
164 setEnabled: function(value)
166 if (this._enabled === value)
167 return;
168 this._enabled = value;
169 this._applyEnabledState();
172 _applyEnabledState: function()
174 this.element.disabled = !this._enabled;
178 * @return {boolean} x
180 visible: function()
182 return this._visible;
186 * @param {boolean} x
188 setVisible: function(x)
190 if (this._visible === x)
191 return;
192 this.element.classList.toggle("hidden", !x);
193 this._visible = x;
194 if (this._toolbar && !(this instanceof WebInspector.ToolbarSeparator))
195 this._toolbar._hideSeparatorDupes();
198 __proto__: WebInspector.Object.prototype
202 * @constructor
203 * @extends {WebInspector.ToolbarItem}
204 * @param {!Array.<string>} counters
206 WebInspector.ToolbarCounter = function(counters)
208 WebInspector.ToolbarItem.call(this, createElementWithClass("div", "toolbar-counter hidden"));
209 this.element.addEventListener("click", this._clicked.bind(this), false);
210 /** @type {!Array.<!{element: !Element, counter: string, value: number, title: string}>} */
211 this._counters = [];
212 for (var i = 0; i < counters.length; ++i) {
213 var element = this.element.createChild("span", "toolbar-counter-item");
214 var icon = element.createChild("label", "", "dt-icon-label");
215 icon.type = counters[i];
216 var span = icon.createChild("span");
217 this._counters.push({counter: counters[i], element: element, value: 0, title: "", span: span});
219 this._update();
222 WebInspector.ToolbarCounter.prototype = {
224 * @param {string} counter
225 * @param {number} value
226 * @param {string} title
228 setCounter: function(counter, value, title)
230 for (var i = 0; i < this._counters.length; ++i) {
231 if (this._counters[i].counter === counter) {
232 this._counters[i].value = value;
233 this._counters[i].title = title;
234 this._update();
235 return;
240 _update: function()
242 var total = 0;
243 var title = "";
244 for (var i = 0; i < this._counters.length; ++i) {
245 var counter = this._counters[i];
246 var value = counter.value;
247 if (!counter.value) {
248 counter.element.classList.add("hidden");
249 continue;
251 counter.element.classList.remove("hidden");
252 counter.element.classList.toggle("toolbar-counter-item-first", !total);
253 counter.span.textContent = value;
254 total += value;
255 if (counter.title) {
256 if (title)
257 title += ", ";
258 title += counter.title;
261 this.element.classList.toggle("hidden", !total);
262 WebInspector.Tooltip.install(this.element, title, this._actionId);
266 * @param {!Event} event
268 _clicked: function(event)
270 if (this._actionId)
271 WebInspector.actionRegistry.execute(this._actionId);
272 else
273 this.dispatchEventToListeners("click", event);
277 * @param {string} actionId
279 setAction: function(actionId)
281 this._actionId = actionId;
282 this._update();
285 __proto__: WebInspector.ToolbarItem.prototype
289 * @constructor
290 * @extends {WebInspector.ToolbarItem}
291 * @param {string} text
292 * @param {string=} className
294 WebInspector.ToolbarText = function(text, className)
296 WebInspector.ToolbarItem.call(this, createElementWithClass("span", "toolbar-text"));
297 if (className)
298 this.element.classList.add(className);
299 this.element.textContent = text;
302 WebInspector.ToolbarText.prototype = {
304 * @param {string} text
306 setText: function(text)
308 this.element.textContent = text;
311 __proto__: WebInspector.ToolbarItem.prototype
315 * @constructor
316 * @extends {WebInspector.ToolbarItem}
317 * @param {string=} placeholder
318 * @param {number=} growFactor
320 WebInspector.ToolbarInput = function(placeholder, growFactor)
322 WebInspector.ToolbarItem.call(this, createElementWithClass("input", "toolbar-item"));
323 this.element.addEventListener("input", this._onChangeCallback.bind(this), false);
324 if (growFactor)
325 this.element.style.flexGrow = growFactor;
326 if (placeholder)
327 this.element.setAttribute("placeholder", placeholder);
328 this._value = "";
331 WebInspector.ToolbarInput.Event = {
332 TextChanged: "TextChanged"
335 WebInspector.ToolbarInput.prototype = {
337 * @param {string} value
339 setValue: function(value)
341 this._value = value;
342 this.element.value = value;
346 * @return {string}
348 value: function()
350 return this.element.value;
353 _onChangeCallback: function()
355 this.dispatchEventToListeners(WebInspector.ToolbarInput.Event.TextChanged, this.element.value);
358 __proto__: WebInspector.ToolbarItem.prototype
362 * @constructor
363 * @extends {WebInspector.ToolbarItem}
364 * @param {string} title
365 * @param {string} className
366 * @param {number=} states
368 WebInspector.ToolbarButtonBase = function(title, className, states)
370 WebInspector.ToolbarItem.call(this, createElementWithClass("button", className + " toolbar-item"));
371 this.element.addEventListener("click", this._clicked.bind(this), false);
372 this.element.addEventListener("mousedown", this._mouseDown.bind(this), false);
373 this.element.addEventListener("mouseup", this._mouseUp.bind(this), false);
374 this._longClickController = new WebInspector.LongClickController(this.element);
375 this._longClickController.addEventListener(WebInspector.LongClickController.Events.LongClick, this._onLongClick.bind(this));
377 this._states = states;
378 if (!states)
379 this._states = 2;
381 if (states == 2)
382 this._state = "off";
383 else
384 this._state = "0";
386 this.setTitle(title);
387 this.className = className;
390 WebInspector.ToolbarButtonBase.prototype = {
392 * @param {!WebInspector.Event} event
394 _onLongClick: function(event)
396 var nativeEvent = event.data;
397 this.dispatchEventToListeners("longClickDown", nativeEvent);
401 * @param {!Event} event
403 _clicked: function(event)
405 this._longClickController.reset();
406 if (this._actionId)
407 WebInspector.actionRegistry.execute(this._actionId);
408 else
409 this.dispatchEventToListeners("click", event);
413 * @param {!Event} event
415 _mouseDown: function(event)
417 this.dispatchEventToListeners("mousedown", event);
421 * @param {!Event} event
423 _mouseUp: function(event)
425 this.dispatchEventToListeners("mouseup", event);
429 * @param {string} actionId
431 setAction: function(actionId)
433 this._actionId = actionId;
434 WebInspector.Tooltip.install(this.element, this._title, this._actionId);
438 * @override
440 _applyEnabledState: function()
442 this.element.disabled = !this._enabled;
443 this._longClickController.reset();
447 * @return {boolean}
449 enabled: function()
451 return this._enabled;
455 * @return {string}
457 title: function()
459 return this._title;
463 * @param {string} title
465 setTitle: function(title)
467 if (this._title === title)
468 return;
469 this._title = title;
470 WebInspector.Tooltip.install(this.element, title, this._actionId);
474 * @return {string}
476 state: function()
478 return this._state;
482 * @param {string} x
484 setState: function(x)
486 if (this._state === x)
487 return;
489 this.element.classList.remove("toggled-" + this._state);
490 this.element.classList.add("toggled-" + x);
491 this._state = x;
495 * @return {boolean}
497 toggled: function()
499 if (this._states !== 2)
500 throw("Only used toggled when there are 2 states, otherwise, use state");
501 return this.state() === "on";
505 * @param {boolean} x
507 setToggled: function(x)
509 if (this._states !== 2)
510 throw("Only used toggled when there are 2 states, otherwise, use state");
511 this.setState(x ? "on" : "off");
514 makeLongClickEnabled: function()
516 this._longClickController.enable();
517 this._longClickGlyph = this.element.createChild("div", "fill long-click-glyph toolbar-button-theme");
520 unmakeLongClickEnabled: function()
522 this._longClickController.disable();
523 if (this._longClickGlyph)
524 this.element.removeChild(this._longClickGlyph);
528 * @param {?function():!Array.<!WebInspector.ToolbarButton>} buttonsProvider
530 setLongClickOptionsEnabled: function(buttonsProvider)
532 if (buttonsProvider) {
533 if (!this._longClickOptionsData) {
534 this.makeLongClickEnabled();
536 var longClickDownListener = this._showOptions.bind(this);
537 this.addEventListener("longClickDown", longClickDownListener, this);
539 this._longClickOptionsData = {
540 longClickDownListener: longClickDownListener
543 this._longClickOptionsData.buttonsProvider = buttonsProvider;
544 } else {
545 if (!this._longClickOptionsData)
546 return;
548 this.removeEventListener("longClickDown", this._longClickOptionsData.longClickDownListener, this);
549 delete this._longClickOptionsData;
551 this.unmakeLongClickEnabled();
555 _showOptions: function()
557 var buttons = this._longClickOptionsData.buttonsProvider();
558 var mainButtonClone = new WebInspector.ToolbarButton(this.title(), this.className, this._states);
559 mainButtonClone.addEventListener("click", clicked.bind(this));
562 * @param {!WebInspector.Event} event
563 * @this {WebInspector.ToolbarButtonBase}
565 function clicked(event)
567 this._clicked(/** @type {!Event} */ (event.data));
570 mainButtonClone.setState(this.state());
571 buttons.push(mainButtonClone);
573 var document = this.element.ownerDocument;
574 document.documentElement.addEventListener("mouseup", mouseUp, false);
576 var optionsGlassPane = new WebInspector.GlassPane(document);
577 var optionsBar = new WebInspector.Toolbar(optionsGlassPane.element);
579 optionsBar.element.classList.add("fill");
580 optionsBar._contentElement.classList.add("floating");
581 const buttonHeight = 26;
583 var hostButtonPosition = this.element.totalOffset();
585 var topNotBottom = hostButtonPosition.top + buttonHeight * buttons.length < document.documentElement.offsetHeight;
587 if (topNotBottom)
588 buttons = buttons.reverse();
590 optionsBar.element.style.height = (buttonHeight * buttons.length) + "px";
591 if (topNotBottom)
592 optionsBar.element.style.top = (hostButtonPosition.top + 1) + "px";
593 else
594 optionsBar.element.style.top = (hostButtonPosition.top - (buttonHeight * (buttons.length - 1))) + "px";
595 optionsBar.element.style.left = (hostButtonPosition.left + 1) + "px";
597 for (var i = 0; i < buttons.length; ++i) {
598 buttons[i].element.addEventListener("mousemove", mouseOver, false);
599 buttons[i].element.addEventListener("mouseout", mouseOut, false);
600 optionsBar.appendToolbarItem(buttons[i]);
602 var hostButtonIndex = topNotBottom ? 0 : buttons.length - 1;
603 buttons[hostButtonIndex].element.classList.add("emulate-active");
605 function mouseOver(e)
607 if (e.which !== 1)
608 return;
609 var buttonElement = e.target.enclosingNodeOrSelfWithClass("toolbar-item");
610 buttonElement.classList.add("emulate-active");
613 function mouseOut(e)
615 if (e.which !== 1)
616 return;
617 var buttonElement = e.target.enclosingNodeOrSelfWithClass("toolbar-item");
618 buttonElement.classList.remove("emulate-active");
621 function mouseUp(e)
623 if (e.which !== 1)
624 return;
625 optionsGlassPane.dispose();
626 document.documentElement.removeEventListener("mouseup", mouseUp, false);
628 for (var i = 0; i < buttons.length; ++i) {
629 if (buttons[i].element.classList.contains("emulate-active")) {
630 buttons[i].element.classList.remove("emulate-active");
631 buttons[i]._clicked(e);
632 break;
638 __proto__: WebInspector.ToolbarItem.prototype
642 * @constructor
643 * @extends {WebInspector.ToolbarButtonBase}
644 * @param {string} title
645 * @param {string} className
646 * @param {number=} states
648 WebInspector.ToolbarButton = function(title, className, states)
650 WebInspector.ToolbarButtonBase.call(this, title, className, states);
652 this._glyphElement = this.element.createChild("div", "glyph toolbar-button-theme");
655 WebInspector.ToolbarButton.prototype = {
657 * @param {string} iconURL
659 setBackgroundImage: function(iconURL)
661 this.element.style.backgroundImage = "url(" + iconURL + ")";
662 this._glyphElement.classList.add("hidden");
665 __proto__: WebInspector.ToolbarButtonBase.prototype
669 * @param {string} actionId
670 * @return {!WebInspector.ToolbarButton}
672 WebInspector.ToolbarButton.createActionButton = function(actionId)
674 var registry = WebInspector.actionRegistry;
675 var button = new WebInspector.ToolbarButton(registry.actionTitle(actionId), registry.actionIcon(actionId));
676 button.setAction(actionId);
677 return button;
681 * @constructor
682 * @extends {WebInspector.ToolbarButton}
683 * @param {string} title
684 * @param {string} className
685 * @param {function(!WebInspector.ContextMenu)} contextMenuHandler
687 WebInspector.ToolbarMenuButton = function(title, className, contextMenuHandler)
689 WebInspector.ToolbarButton.call(this, title, className);
690 this._contextMenuHandler = contextMenuHandler;
693 WebInspector.ToolbarMenuButton.prototype = {
695 * @override
696 * @param {!Event} event
698 _clicked: function(event)
700 var contextMenu = new WebInspector.ContextMenu(event,
701 true,
702 this.element.totalOffsetLeft(),
703 this.element.totalOffsetTop() + this.element.offsetHeight);
704 this._contextMenuHandler(contextMenu);
705 contextMenu.show();
708 __proto__: WebInspector.ToolbarButton.prototype
712 * @constructor
713 * @extends {WebInspector.ToolbarButton}
714 * @param {!WebInspector.Setting} setting
715 * @param {string} className
716 * @param {string} title
717 * @param {string=} toggledTitle
719 WebInspector.ToolbarSettingToggle = function(setting, className, title, toggledTitle)
721 WebInspector.ToolbarButton.call(this, "", className, 2);
722 this._defaultTitle = title;
723 this._toggledTitle = toggledTitle || title;
724 this._setting = setting;
725 this._settingChanged();
726 this._setting.addChangeListener(this._settingChanged, this);
729 WebInspector.ToolbarSettingToggle.prototype = {
730 _settingChanged: function()
732 var toggled = this._setting.get();
733 this.setToggled(toggled);
734 this.setTitle(toggled ? this._toggledTitle : this._defaultTitle);
738 * @override
739 * @param {!Event} event
741 _clicked: function(event)
743 this._setting.set(!this.toggled());
744 WebInspector.ToolbarButton.prototype._clicked.call(this, event);
747 __proto__: WebInspector.ToolbarButton.prototype
751 * @constructor
752 * @extends {WebInspector.ToolbarItem}
754 WebInspector.ToolbarSeparator = function()
756 WebInspector.ToolbarItem.call(this, createElementWithClass("div", "toolbar-divider"));
759 WebInspector.ToolbarSeparator.prototype = {
760 __proto__: WebInspector.ToolbarItem.prototype
764 * @constructor
765 * @extends {WebInspector.ToolbarButtonBase}
766 * @param {string} title
767 * @param {string} className
768 * @param {string} text
769 * @param {number=} states
771 WebInspector.ToolbarTextButton = function(title, className, text, states)
773 WebInspector.ToolbarButtonBase.call(this, title, className, states);
775 this._textElement = this.element.createChild("div", "toolbar-button-text");
776 this._textElement.textContent = text;
779 WebInspector.ToolbarTextButton.prototype = {
780 __proto__: WebInspector.ToolbarButtonBase.prototype
784 * @interface
786 WebInspector.ToolbarItem.Provider = function()
790 WebInspector.ToolbarItem.Provider.prototype = {
792 * @return {?WebInspector.ToolbarItem}
794 item: function() {}
798 * @constructor
799 * @extends {WebInspector.ToolbarItem}
800 * @param {?function(!Event)} changeHandler
801 * @param {string=} className
803 WebInspector.ToolbarComboBox = function(changeHandler, className)
805 WebInspector.ToolbarItem.call(this, createElementWithClass("span", "toolbar-select-container"));
807 this._selectElement = this.element.createChild("select", "toolbar-item");
808 this.element.createChild("div", "toolbar-select-arrow");
809 if (changeHandler)
810 this._selectElement.addEventListener("change", changeHandler, false);
811 if (className)
812 this._selectElement.classList.add(className);
815 WebInspector.ToolbarComboBox.prototype = {
817 * @return {!HTMLSelectElement}
819 selectElement: function()
821 return /** @type {!HTMLSelectElement} */ (this._selectElement);
825 * @return {number}
827 size: function()
829 return this._selectElement.childElementCount;
833 * @return {!Array.<!Element>}
835 options: function()
837 return Array.prototype.slice.call(this._selectElement.children, 0);
841 * @param {!Element} option
843 addOption: function(option)
845 this._selectElement.appendChild(option);
849 * @param {string} label
850 * @param {string=} title
851 * @param {string=} value
852 * @return {!Element}
854 createOption: function(label, title, value)
856 var option = this._selectElement.createChild("option");
857 option.text = label;
858 if (title)
859 option.title = title;
860 if (typeof value !== "undefined")
861 option.value = value;
862 return option;
866 * @override
868 _applyEnabledState: function()
870 this._selectElement.disabled = !this._enabled;
874 * @param {!Element} option
876 removeOption: function(option)
878 this._selectElement.removeChild(option);
881 removeOptions: function()
883 this._selectElement.removeChildren();
887 * @return {?Element}
889 selectedOption: function()
891 if (this._selectElement.selectedIndex >= 0)
892 return this._selectElement[this._selectElement.selectedIndex];
893 return null;
897 * @param {!Element} option
899 select: function(option)
901 this._selectElement.selectedIndex = Array.prototype.indexOf.call(/** @type {?} */ (this._selectElement), option);
905 * @param {number} index
907 setSelectedIndex: function(index)
909 this._selectElement.selectedIndex = index;
913 * @return {number}
915 selectedIndex: function()
917 return this._selectElement.selectedIndex;
921 * @param {number} width
923 setMaxWidth: function(width)
925 this._selectElement.style.maxWidth = width + "px";
928 __proto__: WebInspector.ToolbarItem.prototype
932 * @constructor
933 * @extends {WebInspector.ToolbarItem}
934 * @param {string} text
935 * @param {string=} title
936 * @param {!WebInspector.Setting=} setting
938 WebInspector.ToolbarCheckbox = function(text, title, setting)
940 WebInspector.ToolbarItem.call(this, createCheckboxLabel(text));
941 this.element.classList.add("checkbox");
942 this.inputElement = this.element.checkboxElement;
943 if (title)
944 this.element.title = title;
945 if (setting)
946 WebInspector.SettingsUI.bindCheckbox(this.inputElement, setting);
949 WebInspector.ToolbarCheckbox.prototype = {
951 * @return {boolean}
953 checked: function()
955 return this.inputElement.checked;
958 __proto__: WebInspector.ToolbarItem.prototype
962 * @constructor
963 * @extends {WebInspector.Toolbar}
964 * @param {string} location
965 * @param {!Element=} parentElement
967 WebInspector.ExtensibleToolbar = function(location, parentElement)
969 WebInspector.Toolbar.call(this, parentElement);
970 this._loadItems(location);
973 WebInspector.ExtensibleToolbar.prototype = {
975 * @param {string} location
977 _loadItems: function(location)
979 var extensions = self.runtime.extensions(WebInspector.ToolbarItem.Provider);
980 var promises = [];
981 for (var i = 0; i < extensions.length; ++i) {
982 if (extensions[i].descriptor()["location"] === location)
983 promises.push(resolveItem(extensions[i]));
985 Promise.all(promises).then(appendItemsInOrder.bind(this));
988 * @param {!Runtime.Extension} extension
989 * @return {!Promise.<?WebInspector.ToolbarItem>}
991 function resolveItem(extension)
993 var descriptor = extension.descriptor();
994 if (descriptor["separator"])
995 return Promise.resolve(/** @type {?WebInspector.ToolbarItem} */(new WebInspector.ToolbarSeparator()));
996 if (!descriptor["className"])
997 return Promise.resolve(new WebInspector.ToolbarButton(WebInspector.UIString(descriptor["title"]), descriptor["elementClass"])).then(attachHandler);
998 return extension.instancePromise().then(fetchItemFromProvider).then(attachHandler);
1001 * @param {!Object} provider
1003 function fetchItemFromProvider(provider)
1005 return /** @type {!WebInspector.ToolbarItem.Provider} */ (provider).item();
1009 * @param {?WebInspector.ToolbarItem} item
1010 * @return {?WebInspector.ToolbarItem} item
1012 function attachHandler(item)
1014 var actionId = extension.descriptor()["actionId"];
1015 if (actionId && item && (item instanceof WebInspector.ToolbarButtonBase || item instanceof WebInspector.ToolbarCounter))
1016 item.setAction(actionId);
1017 else if (actionId)
1018 console.error("Can only set action " + actionId + " for a button or counter.");
1019 return item;
1024 * @param {!Array.<?WebInspector.ToolbarItem>} items
1025 * @this {WebInspector.ExtensibleToolbar}
1027 function appendItemsInOrder(items)
1029 for (var i = 0; i < items.length; ++i) {
1030 var item = items[i];
1031 if (item)
1032 this.appendToolbarItem(item);
1037 __proto__: WebInspector.Toolbar.prototype