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
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
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.
33 * @param {!WebInspector.ContextMenu} topLevelMenu
34 * @param {string} type
35 * @param {string=} label
36 * @param {boolean=} disabled
37 * @param {boolean=} checked
39 WebInspector.ContextMenuItem = function(topLevelMenu, type, label, disabled, checked)
43 this._disabled = disabled;
44 this._checked = checked;
45 this._contextMenu = topLevelMenu;
46 if (type === "item" || type === "checkbox")
47 this._id = topLevelMenu.nextId();
50 WebInspector.ContextMenuItem.prototype = {
72 return !this._disabled;
76 * @param {boolean} enabled
78 setEnabled: function(enabled)
80 this._disabled = !enabled;
83 _buildDescriptor: function()
87 return { type: "item", id: this._id, label: this._label, enabled: !this._disabled };
89 return { type: "separator" };
91 return { type: "checkbox", id: this._id, label: this._label, checked: !!this._checked, enabled: !this._disabled };
98 * @extends {WebInspector.ContextMenuItem}
99 * @param {!WebInspector.ContextMenu} topLevelMenu
100 * @param {string=} label
101 * @param {boolean=} disabled
103 WebInspector.ContextSubMenuItem = function(topLevelMenu, label, disabled)
105 WebInspector.ContextMenuItem.call(this, topLevelMenu, "subMenu", label, disabled);
106 /** @type {!Array.<!WebInspector.ContextMenuItem>} */
110 WebInspector.ContextSubMenuItem.prototype = {
112 * @param {string} label
113 * @param {function(?)} handler
114 * @param {boolean=} disabled
115 * @return {!WebInspector.ContextMenuItem}
117 appendItem: function(label, handler, disabled)
119 var item = new WebInspector.ContextMenuItem(this._contextMenu, "item", label, disabled);
120 this._pushItem(item);
121 this._contextMenu._setHandler(item.id(), handler);
126 * @param {string} label
127 * @param {boolean=} disabled
128 * @return {!WebInspector.ContextSubMenuItem}
130 appendSubMenuItem: function(label, disabled)
132 var item = new WebInspector.ContextSubMenuItem(this._contextMenu, label, disabled);
133 this._pushItem(item);
138 * @param {string} label
139 * @param {function()} handler
140 * @param {boolean=} checked
141 * @param {boolean=} disabled
142 * @return {!WebInspector.ContextMenuItem}
144 appendCheckboxItem: function(label, handler, checked, disabled)
146 var item = new WebInspector.ContextMenuItem(this._contextMenu, "checkbox", label, disabled, checked);
147 this._pushItem(item);
148 this._contextMenu._setHandler(item.id(), handler);
152 appendSeparator: function()
154 if (this._items.length)
155 this._pendingSeparator = true;
159 * @param {!WebInspector.ContextMenuItem} item
161 _pushItem: function(item)
163 if (this._pendingSeparator) {
164 this._items.push(new WebInspector.ContextMenuItem(this._contextMenu, "separator"));
165 delete this._pendingSeparator;
167 this._items.push(item);
175 return !this._items.length;
178 _buildDescriptor: function()
180 var result = { type: "subMenu", label: this._label, enabled: !this._disabled, subItems: [] };
181 for (var i = 0; i < this._items.length; ++i)
182 result.subItems.push(this._items[i]._buildDescriptor());
186 __proto__: WebInspector.ContextMenuItem.prototype
191 * @extends {WebInspector.ContextSubMenuItem}
192 * @param {?Event} event
194 WebInspector.ContextMenu = function(event)
196 WebInspector.ContextSubMenuItem.call(this, this, "");
197 this._event = /** @type {!Event} */ (event);
203 * @param {boolean} useSoftMenu
205 WebInspector.ContextMenu.setUseSoftMenu = function(useSoftMenu)
207 WebInspector.ContextMenu._useSoftMenu = useSoftMenu;
210 WebInspector.ContextMenu.prototype = {
221 var menuObject = this._buildDescriptor();
223 if (menuObject.length) {
224 WebInspector._contextMenu = this;
225 if (WebInspector.ContextMenu._useSoftMenu) {
226 var softMenu = new WebInspector.SoftContextMenu(menuObject);
227 softMenu.show(this._event);
229 InspectorFrontendHost.showContextMenu(this._event, menuObject);
231 this._event.consume(true);
237 * @param {function(?)} handler
239 _setHandler: function(id, handler)
242 this._handlers[id] = handler;
245 _buildDescriptor: function()
248 for (var i = 0; i < this._items.length; ++i)
249 result.push(this._items[i]._buildDescriptor());
253 _itemSelected: function(id)
255 if (this._handlers[id])
256 this._handlers[id].call(this);
260 * @param {!Object} target
262 appendApplicableItems: function(target)
264 WebInspector.moduleManager.extensions(WebInspector.ContextMenu.Provider, target).forEach(processProviders.bind(this));
267 * @param {!WebInspector.ModuleManager.Extension} extension
268 * @this {WebInspector.ContextMenu}
270 function processProviders(extension)
272 var provider = /** @type {!WebInspector.ContextMenu.Provider} */ (extension.instance());
273 this.appendSeparator();
274 provider.appendApplicableItems(this._event, this, target);
275 this.appendSeparator();
279 __proto__: WebInspector.ContextSubMenuItem.prototype
285 WebInspector.ContextMenu.Provider = function() {
288 WebInspector.ContextMenu.Provider.prototype = {
290 * @param {!Event} event
291 * @param {!WebInspector.ContextMenu} contextMenu
292 * @param {!Object} target
294 appendApplicableItems: function(event, contextMenu, target) { }
297 WebInspector.contextMenuItemSelected = function(id)
299 if (WebInspector._contextMenu)
300 WebInspector._contextMenu._itemSelected(id);
303 WebInspector.contextMenuCleared = function()
305 // FIXME: Unfortunately, contextMenuCleared is invoked between show and item selected
306 // so we can't delete last menu object from WebInspector. Fix the contract.