Commit d335717c authored by pfeldman@chromium.org's avatar pfeldman@chromium.org

2009-12-06 Pavel Feldman <pfeldman@chromium.org>

        Reviewed by Timothy Hatcher.

        Web Inspector: provide custom context menu in the front-end window.

        https://bugs.webkit.org/show_bug.cgi?id=32200

        * English.lproj/localizedStrings.js:
        * GNUmakefile.am:
        * WebCore.gypi:
        * WebCore.pro:
        * WebCore.vcproj/WebCore.vcproj:
        * WebCore.xcodeproj/project.pbxproj:
        * bindings/js/JSInspectorFrontendHostCustom.cpp:
        (WebCore::JSInspectorFrontendHost::showContextMenu):
        * inspector/InspectorFrontend.cpp:
        (WebCore::InspectorFrontend::contextMenuItemSelected):
        (WebCore::InspectorFrontend::contextMenuCleared):
        * inspector/InspectorFrontend.h:
        * inspector/InspectorFrontendHost.cpp:
        (WebCore::InspectorFrontendHost::InspectorFrontendHost):
        (WebCore::InspectorFrontendHost::~InspectorFrontendHost):
        (WebCore::InspectorFrontendHost::showContextMenu):
        (WebCore::InspectorFrontendHost::contextMenuItemSelected):
        (WebCore::InspectorFrontendHost::contextMenuCleared):
        * inspector/InspectorFrontendHost.h:
        (WebCore::InspectorFrontendHost::MenuSelectionHandler::create):
        (WebCore::InspectorFrontendHost::MenuSelectionHandler::~MenuSelectionHandler):
        (WebCore::InspectorFrontendHost::MenuSelectionHandler::disconnect):
        (WebCore::InspectorFrontendHost::MenuSelectionHandler::contextMenuItemSelected):
        (WebCore::InspectorFrontendHost::MenuSelectionHandler::contextMenuCleared):
        (WebCore::InspectorFrontendHost::MenuSelectionHandler::MenuSelectionHandler):
        * inspector/InspectorFrontendHost.idl:
        * inspector/front-end/ContextMenu.js: Added.
        * inspector/front-end/WebKit.qrc:
        * inspector/front-end/inspector.html:
        * inspector/front-end/inspector.js:
        (WebInspector.loaded):
        (WebInspector.documentContextMenu):
        * page/ContextMenuController.cpp:
        (WebCore::ContextMenuController::ContextMenuController):
        (WebCore::ContextMenuController::clearContextMenu):
        (WebCore::ContextMenuController::handleContextMenuEvent):
        (WebCore::ContextMenuController::showContextMenu):
        (WebCore::ContextMenuController::createContextMenu):
        (WebCore::ContextMenuController::contextMenuItemSelected):
        * page/ContextMenuController.h:
        * page/ContextMenuSelectionHandler.h: Added.
        (WebCore::ContextMenuSelectionHandler::ContextMenuSelectionHandler):
        (WebCore::ContextMenuSelectionHandler::~ContextMenuSelectionHandler):
        * platform/ContextMenu.cpp:
        (WebCore::ContextMenu::checkOrEnableIfNeeded):
        * platform/ContextMenuItem.h:


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@51839 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 3d61a29f
2009-12-06 Pavel Feldman <pfeldman@chromium.org>
Reviewed by Timothy Hatcher.
Web Inspector: provide custom context menu in the front-end window.
https://bugs.webkit.org/show_bug.cgi?id=32200
* English.lproj/localizedStrings.js:
* GNUmakefile.am:
* WebCore.gypi:
* WebCore.pro:
* WebCore.vcproj/WebCore.vcproj:
* WebCore.xcodeproj/project.pbxproj:
* bindings/js/JSInspectorFrontendHostCustom.cpp:
(WebCore::JSInspectorFrontendHost::showContextMenu):
* inspector/InspectorFrontend.cpp:
(WebCore::InspectorFrontend::contextMenuItemSelected):
(WebCore::InspectorFrontend::contextMenuCleared):
* inspector/InspectorFrontend.h:
* inspector/InspectorFrontendHost.cpp:
(WebCore::InspectorFrontendHost::InspectorFrontendHost):
(WebCore::InspectorFrontendHost::~InspectorFrontendHost):
(WebCore::InspectorFrontendHost::showContextMenu):
(WebCore::InspectorFrontendHost::contextMenuItemSelected):
(WebCore::InspectorFrontendHost::contextMenuCleared):
* inspector/InspectorFrontendHost.h:
(WebCore::InspectorFrontendHost::MenuSelectionHandler::create):
(WebCore::InspectorFrontendHost::MenuSelectionHandler::~MenuSelectionHandler):
(WebCore::InspectorFrontendHost::MenuSelectionHandler::disconnect):
(WebCore::InspectorFrontendHost::MenuSelectionHandler::contextMenuItemSelected):
(WebCore::InspectorFrontendHost::MenuSelectionHandler::contextMenuCleared):
(WebCore::InspectorFrontendHost::MenuSelectionHandler::MenuSelectionHandler):
* inspector/InspectorFrontendHost.idl:
* inspector/front-end/ContextMenu.js: Added.
* inspector/front-end/WebKit.qrc:
* inspector/front-end/inspector.html:
* inspector/front-end/inspector.js:
(WebInspector.loaded):
(WebInspector.documentContextMenu):
* page/ContextMenuController.cpp:
(WebCore::ContextMenuController::ContextMenuController):
(WebCore::ContextMenuController::clearContextMenu):
(WebCore::ContextMenuController::handleContextMenuEvent):
(WebCore::ContextMenuController::showContextMenu):
(WebCore::ContextMenuController::createContextMenu):
(WebCore::ContextMenuController::contextMenuItemSelected):
* page/ContextMenuController.h:
* page/ContextMenuSelectionHandler.h: Added.
(WebCore::ContextMenuSelectionHandler::ContextMenuSelectionHandler):
(WebCore::ContextMenuSelectionHandler::~ContextMenuSelectionHandler):
* platform/ContextMenu.cpp:
(WebCore::ContextMenu::checkOrEnableIfNeeded):
* platform/ContextMenuItem.h:
2009-12-08 Andras Becsi <abecsi@inf.u-szeged.hu>
Rubber-stamped by Kenneth Rohde Christiansen.
Bvar localizedStrings = new Object;
......
......@@ -1318,6 +1318,7 @@ webcore_sources += \
WebCore/page/ContextMenuClient.h \
WebCore/page/ContextMenuController.cpp \
WebCore/page/ContextMenuController.h \
WebCore/page/ContextMenuSelectionHandler.h \
WebCore/page/Coordinates.h \
WebCore/page/DOMSelection.cpp \
WebCore/page/DOMSelection.h \
......
......@@ -1754,6 +1754,7 @@
'page/ContextMenuClient.h',
'page/ContextMenuController.cpp',
'page/ContextMenuController.h',
'page/ContextMenuSelectionHandler.h',
'page/DOMSelection.cpp',
'page/DOMSelection.h',
'page/DOMTimer.cpp',
......@@ -3639,6 +3640,7 @@
'inspector/front-end/Color.js',
'inspector/front-end/ConsolePanel.js',
'inspector/front-end/ConsoleView.js',
'inspector/front-end/ContextMenu.js',
'inspector/front-end/CookieItemsView.js',
'inspector/front-end/Database.js',
'inspector/front-end/DatabaseQueryView.js',
......
......@@ -1835,6 +1835,7 @@ HEADERS += \
page/Chrome.h \
page/Console.h \
page/ContextMenuController.h \
page/ContextMenuSelectionHandler.h \
page/Coordinates.h \
page/DOMSelection.h \
page/DOMTimer.h \
......
......@@ -20526,6 +20526,10 @@
RelativePath="..\page\ContextMenuController.h"
>
</File>
<File
RelativePath="..\page\ContextMenuSelectionHandler.h"
>
</File>
<File
RelativePath="..\page\Coordinates.h"
>
......@@ -42433,6 +42437,10 @@
RelativePath="..\inspector\front-end\ConsoleView.js"
>
</File>
<File
RelativePath="..\inspector\front-end\ContextMenu.js"
>
</File>
<File
RelativePath="..\inspector\front-end\Database.js"
>
......
......@@ -1246,6 +1246,7 @@
7A74ECBA101839A600BF939E /* InspectorBackend.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7A74ECB8101839A500BF939E /* InspectorBackend.cpp */; };
7A74ECBB101839A600BF939E /* InspectorBackend.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A74ECB9101839A600BF939E /* InspectorBackend.h */; };
7A74ECBD101839DA00BF939E /* JSInspectorFrontendHostCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7A74ECBC101839DA00BF939E /* JSInspectorFrontendHostCustom.cpp */; };
7ADE722610CBBB9B006B3B3A /* ContextMenuSelectionHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 7ADE722510CBBB9B006B3B3A /* ContextMenuSelectionHandler.h */; };
7AED3E050FBB1EAA00D2B03C /* InspectorFrontend.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7AED3E030FBB1EAA00D2B03C /* InspectorFrontend.cpp */; };
7AED3E060FBB1EAA00D2B03C /* InspectorFrontend.h in Headers */ = {isa = PBXBuildFile; fileRef = 7AED3E040FBB1EAA00D2B03C /* InspectorFrontend.h */; };
84224183107E77F400766A87 /* JSSVGFEMorphologyElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84224181107E77F400766A87 /* JSSVGFEMorphologyElement.cpp */; };
......@@ -6580,6 +6581,7 @@
7A74ECB8101839A500BF939E /* InspectorBackend.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InspectorBackend.cpp; sourceTree = "<group>"; };
7A74ECB9101839A600BF939E /* InspectorBackend.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorBackend.h; sourceTree = "<group>"; };
7A74ECBC101839DA00BF939E /* JSInspectorFrontendHostCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSInspectorFrontendHostCustom.cpp; sourceTree = "<group>"; };
7ADE722510CBBB9B006B3B3A /* ContextMenuSelectionHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContextMenuSelectionHandler.h; sourceTree = "<group>"; };
7AED3E030FBB1EAA00D2B03C /* InspectorFrontend.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InspectorFrontend.cpp; sourceTree = "<group>"; };
7AED3E040FBB1EAA00D2B03C /* InspectorFrontend.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorFrontend.h; sourceTree = "<group>"; };
84224181107E77F400766A87 /* JSSVGFEMorphologyElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSSVGFEMorphologyElement.cpp; sourceTree = "<group>"; };
......@@ -11226,6 +11228,7 @@
065AD4F20B0C2EDA005A2B1D /* ContextMenuClient.h */,
065AD4F30B0C2EDA005A2B1D /* ContextMenuController.cpp */,
065AD4F40B0C2EDA005A2B1D /* ContextMenuController.h */,
7ADE722510CBBB9B006B3B3A /* ContextMenuSelectionHandler.h */,
FE6FD4850F676E5700092873 /* Coordinates.h */,
FE6FD4860F676E5700092873 /* Coordinates.idl */,
BC5A86810C33676000EEA649 /* DOMSelection.cpp */,
......@@ -18225,6 +18228,7 @@
7A0E771F10C00DB100A0276E /* JSInspectorFrontendHost.h in Headers */,
F4EAF4AF10C742B1009100D3 /* OpenTypeSanitizer.h in Headers */,
599D1E3310C97D6E00E0EF12 /* jni_utility_private.h in Headers */,
7ADE722610CBBB9B006B3B3A /* ContextMenuSelectionHandler.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
......@@ -35,18 +35,22 @@
#if ENABLE(INSPECTOR)
#include "ContextMenuItem.h"
#include "ExceptionCode.h"
#include "Frame.h"
#include "InspectorController.h"
#include "InspectorFrontendHost.h"
#include "JSEvent.h"
#include "JSNode.h"
#include "JSRange.h"
#include "MouseEvent.h"
#include "Node.h"
#include "Page.h"
#include "TextIterator.h"
#include "VisiblePosition.h"
#include <runtime/JSArray.h>
#include <runtime/JSLock.h>
#include <runtime/JSObject.h>
#include <wtf/Vector.h>
using namespace JSC;
......@@ -89,6 +93,32 @@ JSValue JSInspectorFrontendHost::search(ExecState* exec, const ArgList& args)
return constructArray(exec, result);
}
JSValue JSInspectorFrontendHost::showContextMenu(ExecState* execState, const ArgList& args)
{
if (args.size() < 2)
return jsUndefined();
Event* event = toEvent(args.at(0));
JSArray* array = asArray(args.at(1));
Vector<ContextMenuItem> items;
for (size_t i = 0; i < array->length(); ++i) {
JSObject* item = asObject(array->getIndex(i));
JSValue label = item->get(execState, Identifier(execState, "label"));
JSValue id = item->get(execState, Identifier(execState, "id"));
if (label.isUndefined() || id.isUndefined())
items.append(ContextMenuItem(SeparatorType, ContextMenuItemTagNoAction, String()));
else {
ContextMenuAction typedId = static_cast<ContextMenuAction>(ContextMenuItemBaseCustomTag + id.toInt32(execState));
items.append(ContextMenuItem(ActionType, typedId, label.toString(execState)));
}
}
impl()->showContextMenu(event, items);
return jsUndefined();
}
} // namespace WebCore
#endif // ENABLE(INSPECTOR)
......@@ -496,8 +496,7 @@ namespace WebCore {
#endif
DECLARE_CALLBACK(InspectorFrontendHostSearch);
DECLARE_CALLBACK(InspectorFrontendHostSetting);
DECLARE_CALLBACK(InspectorFrontendHostSetSetting);
DECLARE_CALLBACK(InspectorFrontendHostShowContextMenu);
DECLARE_CALLBACK(ConsoleProfile);
DECLARE_CALLBACK(ConsoleProfileEnd);
......
......@@ -84,4 +84,9 @@ CALLBACK_FUNC_DECL(InspectorFrontendHostSearch)
return result;
}
CALLBACK_FUNC_DECL(InspectorFrontendHostShowContextMenu)
{
return v8::Undefined();
}
} // namespace WebCore
......@@ -530,6 +530,19 @@ void InspectorFrontend::addNodesToSearchResult(const String& nodeIds)
function.call();
}
void InspectorFrontend::contextMenuItemSelected(int itemId)
{
ScriptFunctionCall function(m_scriptState, m_webInspector, "dispatch");
function.appendArgument("contextMenuItemSelected");
function.appendArgument(itemId);
function.call();
}
void InspectorFrontend::contextMenuCleared()
{
callSimpleFunction("contextMenuCleared");
}
void InspectorFrontend::evaluateForTestInFrontend(int callId, const String& script)
{
ScriptFunctionCall function(m_scriptState, m_webInspector, "dispatch");
......
......@@ -132,6 +132,9 @@ namespace WebCore {
void addNodesToSearchResult(const String& nodeIds);
void contextMenuItemSelected(int itemId);
void contextMenuCleared();
ScriptState* scriptState() const { return m_scriptState; }
void evaluateForTestInFrontend(int callId, const String& script);
......
......@@ -32,12 +32,19 @@
#if ENABLE(INSPECTOR)
#include "ContextMenu.h"
#include "ContextMenuItem.h"
#include "ContextMenuController.h"
#include "ContextMenuSelectionHandler.h"
#include "Element.h"
#include "Frame.h"
#include "FrameLoader.h"
#include "HitTestResult.h"
#include "HTMLFrameOwnerElement.h"
#include "InspectorClient.h"
#include "InspectorFrontend.h"
#include "InspectorResource.h"
#include "Page.h"
#include <wtf/RefPtr.h>
#include <wtf/StdLibExtras.h>
......@@ -49,11 +56,13 @@ namespace WebCore {
InspectorFrontendHost::InspectorFrontendHost(InspectorController* inspectorController, InspectorClient* client)
: m_inspectorController(inspectorController)
, m_client(client)
, m_menuSelectionHandler(MenuSelectionHandler::create(this))
{
}
InspectorFrontendHost::~InspectorFrontendHost()
{
m_menuSelectionHandler->disconnect();
}
void InspectorFrontendHost::loaded()
......@@ -199,6 +208,31 @@ void InspectorFrontendHost::setSetting(const String& key, const String& value)
m_inspectorController->setSetting(key, value);
}
void InspectorFrontendHost::showContextMenu(Event* event, Vector<ContextMenuItem>& items)
{
if (!m_inspectorController)
return;
if (!m_inspectorController->windowVisible())
return;
ContextMenuController* menuController = m_inspectorController->m_page->contextMenuController();
menuController->showContextMenu(event, items, m_menuSelectionHandler);
}
void InspectorFrontendHost::contextMenuItemSelected(ContextMenuItem* item)
{
if (m_inspectorController && m_inspectorController->windowVisible()) {
int itemNumber = item->action() - ContextMenuItemBaseCustomTag;
m_inspectorController->m_frontend->contextMenuItemSelected(itemNumber);
}
}
void InspectorFrontendHost::contextMenuCleared()
{
if (m_inspectorController && m_inspectorController->windowVisible())
m_inspectorController->m_frontend->contextMenuCleared();
}
} // namespace WebCore
#endif // ENABLE(INSPECTOR)
......@@ -30,13 +30,17 @@
#define InspectorFrontendHost_h
#include "Console.h"
#include "ContextMenuSelectionHandler.h"
#include "InspectorController.h"
#include "PlatformString.h"
#include <wtf/RefCounted.h>
#include <wtf/Vector.h>
namespace WebCore {
class ContextMenuItem;
class Event;
class InspectorClient;
class Node;
......@@ -51,6 +55,7 @@ public:
~InspectorFrontendHost();
InspectorController* inspectorController() { return m_inspectorController; }
void disconnectController() { m_inspectorController = 0; }
void loaded();
......@@ -73,11 +78,46 @@ public:
String setting(const String& key);
void setSetting(const String& key, const String& value);
// Called from [Custom] implementations.
void showContextMenu(Event*, Vector<ContextMenuItem>& items);
void contextMenuItemSelected(ContextMenuItem*);
void contextMenuCleared();
private:
class MenuSelectionHandler : public ContextMenuSelectionHandler {
public:
static PassRefPtr<MenuSelectionHandler> create(InspectorFrontendHost* frontendHost)
{
return adoptRef(new MenuSelectionHandler(frontendHost));
}
virtual ~MenuSelectionHandler() { }
void disconnect() { m_frontendHost = 0; }
virtual void contextMenuItemSelected(ContextMenuItem* item)
{
if (m_frontendHost)
m_frontendHost->contextMenuItemSelected(item);
}
virtual void contextMenuCleared()
{
if (m_frontendHost)
m_frontendHost->contextMenuCleared();
}
private:
MenuSelectionHandler(InspectorFrontendHost* frontendHost)
: m_frontendHost(frontendHost) { }
InspectorFrontendHost* m_frontendHost;
};
InspectorFrontendHost(InspectorController* inspectorController, InspectorClient* client);
InspectorController* m_inspectorController;
InspectorClient* m_client;
RefPtr<MenuSelectionHandler> m_menuSelectionHandler;
};
} // namespace WebCore
......
......@@ -55,5 +55,6 @@ module core {
void setSetting(in DOMString key, in DOMString value);
[Custom] void search(in Node node, in DOMString query);
[Custom] void showContextMenu(in MouseEvent event, in DOMObject items);
};
}
/*
* Copyright (C) 2009 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
WebInspector.ContextMenu = function() {
this._items = [];
this._handlers = {};
this._appendItem(WebInspector.UIString("Edit as HTML"), this._noop.bind(this));
this._appendItem(WebInspector.UIString("Add attribute"), this._noop.bind(this));
this._appendSeparator();
this._appendItem(WebInspector.UIString("Copy"), this._copy.bind(this));
this._appendItem(WebInspector.UIString("Delete"), this._delete.bind(this));
}
WebInspector.ContextMenu.prototype = {
show: function(event)
{
// FIXME: Uncomment when popup menu has meaningful items.
// InspectorFrontendHost.showContextMenu(event, this._items);
// event.preventDefault();
},
_appendItem: function(label, handler)
{
var id = this._items.length;
this._items.push({id: id, label: label});
this._handlers[id] = handler;
},
_appendSeparator: function()
{
this._items.push({});
},
itemSelected: function(id)
{
if (this._handlers[id])
this._handlers[id].call(this);
},
_copy: function()
{
console.log("context menu: copy");
},
_delete: function()
{
console.log("context menu: delete");
},
_noop: function()
{
console.log("context menu: noop");
}
}
WebInspector.contextMenuItemSelected = function(id)
{
if (WebInspector.contextMenu)
WebInspector.contextMenu.itemSelected(id);
}
WebInspector.contextMenuCleared = function()
{
console.log("context menu: cleared");
}
......@@ -11,6 +11,7 @@
<file>Color.js</file>
<file>ConsolePanel.js</file>
<file>ConsoleView.js</file>
<file>ContextMenu.js</file>
<file>CookieItemsView.js</file>
<file>Database.js</file>
<file>DatabaseQueryView.js</file>
......
......@@ -37,6 +37,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<script type="text/javascript" src="InspectorBackendStub.js"></script>
<script type="text/javascript" src="InspectorFrontendHostStub.js"></script>
<script type="text/javascript" src="Object.js"></script>
<script type="text/javascript" src="ContextMenu.js"></script>
<script type="text/javascript" src="KeyboardShortcut.js"></script>
<script type="text/javascript" src="TextPrompt.js"></script>
<script type="text/javascript" src="Popup.js"></script>
......
......@@ -471,7 +471,7 @@ WebInspector.loaded = function()
document.addEventListener("keyup", this.documentKeyUp.bind(this), true);
document.addEventListener("beforecopy", this.documentCanCopy.bind(this), true);
document.addEventListener("copy", this.documentCopy.bind(this), true);
document.addEventListener("contextmenu", this.contextMenu.bind(this), true);
document.addEventListener("contextmenu", this.contextMenuEventFired.bind(this), true);
var mainPanelsElement = document.getElementById("main-panels");
mainPanelsElement.handleKeyEvent = this.mainKeyDown.bind(this);
......@@ -748,10 +748,14 @@ WebInspector.documentCopy = function(event)
WebInspector[this.currentFocusElement.id + "Copy"](event);
}
WebInspector.contextMenu = function(event)
WebInspector.contextMenuEventFired = function(event)
{
if (event.handled || event.target.hasStyleClass("popup-glasspane"))
event.preventDefault();
if (!this.contextMenu)
this.contextMenu = new WebInspector.ContextMenu();
this.contextMenu.show(event);
}
WebInspector.mainKeyDown = function(event)
......
......@@ -31,6 +31,7 @@
#include "Chrome.h"
#include "ContextMenu.h"
#include "ContextMenuClient.h"
#include "ContextMenuSelectionHandler.h"
#include "Document.h"
#include "DocumentFragment.h"
#include "DocumentLoader.h"
......@@ -66,6 +67,7 @@ ContextMenuController::ContextMenuController(Page* page, ContextMenuClient* clie
: m_page(page)
, m_client(client)
, m_contextMenu(0)
, m_selectionHandler(0)
{
ASSERT_ARG(page, page);
ASSERT_ARG(client, client);
......@@ -79,13 +81,40 @@ ContextMenuController::~ContextMenuController()
void ContextMenuController::clearContextMenu()
{
m_contextMenu.set(0);
if (m_selectionHandler)
m_selectionHandler->contextMenuCleared();
m_selectionHandler = 0;
}
void ContextMenuController::handleContextMenuEvent(Event* event)
{
ASSERT(event->type() == eventNames().contextmenuEvent);
if (!event->isMouseEvent())
m_contextMenu.set(createContextMenu(event));
if (!m_contextMenu)
return;
m_contextMenu->populate();
showContextMenu(event);
}
void ContextMenuController::showContextMenu(Event* event, Vector<ContextMenuItem>& items, PassRefPtr<ContextMenuSelectionHandler> selectionHandler)
{
m_selectionHandler = selectionHandler;
m_contextMenu.set(createContextMenu(event));
if (!m_contextMenu) {
clearContextMenu();
return;
}
for (size_t i = 0; i < items.size(); ++i) {
ContextMenuItem& item = items[i];
m_contextMenu->appendItem(item);
}
showContextMenu(event);
}
ContextMenu* ContextMenuController::createContextMenu(Event* event)
{
if (!event->isMouseEvent())
return 0;
MouseEvent* mouseEvent = static_cast<MouseEvent*>(event);
HitTestResult result(mouseEvent->absoluteLocation());
......@@ -93,18 +122,18 @@ void ContextMenuController::handleContextMenuEvent(Event* event)
result = frame->eventHandler()->hitTestResultAtPoint(mouseEvent->absoluteLocation(), false);
if (!result.innerNonSharedNode())
return;
return 0;
return new ContextMenu(result);
}
m_contextMenu.set(new ContextMenu(result));
m_contextMenu->populate();
void ContextMenuController::showContextMenu(Event* event)
{
#if ENABLE(INSPECTOR)
if (m_page->inspectorController()->enabled())
m_contextMenu->addInspectElementItem();
#endif
PlatformMenuDescription customMenu = m_client->getCustomMenuFromDefaultItems(m_contextMenu.get());
m_contextMenu->setPlatformDescription(customMenu);
event->setDefaultHandled();
}
......@@ -126,6 +155,12 @@ void ContextMenuController::contextMenuItemSelected(ContextMenuItem* item)
return;
}
if (item->action() >= ContextMenuItemBaseCustomTag) {
ASSERT(m_selectionHandler);
m_selectionHandler->contextMenuItemSelected(item);
return;
}
HitTestResult result = m_contextMenu->hitTestResult();
Frame* frame = result.innerNonSharedNode()->document()->frame();
if (!frame)
......
......@@ -28,12 +28,16 @@
#include <wtf/Noncopyable.h>
#include <wtf/OwnPtr.h>
#include <wtf/PassRefPtr.h>
#include <wtf/RefPtr.h>
#include <wtf/Vector.h>
namespace WebCore {
class ContextMenu;
class ContextMenuClient;
class ContextMenuItem;
class ContextMenuSelectionHandler;
class Event;
class Page;
......@@ -48,12 +52,18 @@ namespace WebCore {
void clearContextMenu();
void handleContextMenuEvent(Event*);
void showContextMenu(Event*, Vector<ContextMenuItem>&, PassRefPtr<ContextMenuSelectionHandler>);
void contextMenuItemSelected(ContextMenuItem*);
private:
ContextMenu* createContextMenu(Event*);
void showContextMenu(Event*);
Page* m_page;
ContextMenuClient* m_client;
OwnPtr<ContextMenu> m_contextMenu;
RefPtr<ContextMenuSelectionHandler> m_selectionHandler;
};
}
......
/*
* Copyright (C) 2009 Google Inc. All rights reserved.
*