SoftContextMenu.js [plain text]
if (!InspectorFrontendHost.showContextMenu) {
WebInspector.SoftContextMenu = function(items)
{
this._items = items;
}
WebInspector.SoftContextMenu.prototype = {
show: function(event)
{
this._x = event.x;
this._y = event.y;
this._time = new Date().getTime();
var absoluteX = event.pageX;
var absoluteY = event.pageY;
var targetElement = event.target;
while (targetElement && window !== targetElement.ownerDocument.defaultView) {
var frameElement = targetElement.ownerDocument.defaultView.frameElement;
absoluteY += frameElement.totalOffsetTop();
absoluteX += frameElement.totalOffsetLeft();
targetElement = frameElement;
}
this._glassPaneElement = document.createElement("div");
this._glassPaneElement.className = "soft-context-menu-glass-pane";
this._glassPaneElement.tabIndex = 0;
this._glassPaneElement.addEventListener("mouseup", this._glassPaneMouseUp.bind(this), false);
this._contextMenuElement = document.createElement("div");
this._contextMenuElement.className = "soft-context-menu";
this._contextMenuElement.tabIndex = 0;
this._contextMenuElement.style.top = absoluteY + "px";
this._contextMenuElement.style.left = absoluteX + "px";
this._contextMenuElement.addEventListener("mousedown", this._discardMenu.bind(this), false);
this._contextMenuElement.addEventListener("keydown", this._menuKeyDown.bind(this), false);
this._contextMenuElement.addEventListener("blur", this._discardMenu.bind(this), false);
for (var i = 0; i < this._items.length; ++i)
this._contextMenuElement.appendChild(this._createMenuItem(this._items[i]));
this._glassPaneElement.appendChild(this._contextMenuElement);
document.body.appendChild(this._glassPaneElement);
this._contextMenuElement.focus();
if (document.body.offsetWidth < this._contextMenuElement.offsetLeft + this._contextMenuElement.offsetWidth)
this._contextMenuElement.style.left = (absoluteX - this._contextMenuElement.offsetWidth) + "px";
if (document.body.offsetHeight < this._contextMenuElement.offsetTop + this._contextMenuElement.offsetHeight)
this._contextMenuElement.style.top = (document.body.offsetHeight - this._contextMenuElement.offsetHeight) + "px";
event.consume(true);
},
_createMenuItem: function(item)
{
if (item.type === "separator")
return this._createSeparator();
var menuItemElement = document.createElement("div");
menuItemElement.className = "soft-context-menu-item";
var checkMarkElement = document.createElement("span");
checkMarkElement.textContent = "\u2713 "; checkMarkElement.className = "soft-context-menu-item-checkmark";
if (!item.checked)
checkMarkElement.style.opacity = "0";
menuItemElement.appendChild(checkMarkElement);
menuItemElement.appendChild(document.createTextNode(item.label));
menuItemElement.addEventListener("mousedown", this._menuItemMouseDown.bind(this), false);
menuItemElement.addEventListener("mouseup", this._menuItemMouseUp.bind(this), false);
menuItemElement.addEventListener("mouseover", this._menuItemMouseOver.bind(this), false);
menuItemElement.addEventListener("mouseout", this._menuItemMouseOut.bind(this), false);
menuItemElement._actionId = item.id;
return menuItemElement;
},
_createSeparator: function()
{
var separatorElement = document.createElement("div");
separatorElement.className = "soft-context-menu-separator";
separatorElement._isSeparator = true;
return separatorElement;
},
_menuItemMouseDown: function(event)
{
event.consume(true);
},
_menuItemMouseUp: function(event)
{
this._triggerAction(event.target, event);
},
_triggerAction: function(menuItemElement, event)
{
this._discardMenu(event);
if (typeof menuItemElement._actionId !== "undefined") {
WebInspector.contextMenuItemSelected(menuItemElement._actionId);
delete menuItemElement._actionId;
}
},
_menuItemMouseOver: function(event)
{
this._highlightMenuItem(event.target);
},
_menuItemMouseOut: function(event)
{
this._highlightMenuItem(null);
},
_highlightMenuItem: function(menuItemElement)
{
if (this._highlightedMenuItemElement)
this._highlightedMenuItemElement.removeStyleClass("soft-context-menu-item-mouse-over");
this._highlightedMenuItemElement = menuItemElement;
if (this._highlightedMenuItemElement)
this._highlightedMenuItemElement.addStyleClass("soft-context-menu-item-mouse-over");
},
_highlightPrevious: function()
{
var menuItemElement = this._highlightedMenuItemElement ? this._highlightedMenuItemElement.previousSibling : this._contextMenuElement.lastChild;
while (menuItemElement && menuItemElement._isSeparator)
menuItemElement = menuItemElement.previousSibling;
if (menuItemElement)
this._highlightMenuItem(menuItemElement);
},
_highlightNext: function()
{
var menuItemElement = this._highlightedMenuItemElement ? this._highlightedMenuItemElement.nextSibling : this._contextMenuElement.firstChild;
while (menuItemElement && menuItemElement._isSeparator)
menuItemElement = menuItemElement.nextSibling;
if (menuItemElement)
this._highlightMenuItem(menuItemElement);
},
_menuKeyDown: function(event)
{
switch (event.keyIdentifier) {
case "Up":
this._highlightPrevious(); break;
case "Down":
this._highlightNext(); break;
case "U+001B": this._discardMenu(event); break;
case "Enter":
if (!isEnterKey(event))
break;
case "U+0020": if (this._highlightedMenuItemElement)
this._triggerAction(this._highlightedMenuItemElement, event);
break;
}
event.consume(true);
},
_glassPaneMouseUp: function(event)
{
if (event.x === this._x && event.y === this._y && new Date().getTime() - this._time < 300)
return;
this._discardMenu(event);
},
_discardMenu: function(event)
{
if (this._glassPaneElement) {
var glassPane = this._glassPaneElement;
delete this._glassPaneElement;
document.body.removeChild(glassPane);
event.consume(true);
}
}
}
InspectorFrontendHost.showContextMenu = function(event, items)
{
new WebInspector.SoftContextMenu(items).show(event);
}
}