From c3b710c3f4de2da0fd67c858949c3f420dfd175a Mon Sep 17 00:00:00 2001 From: Konstantin Tokarev Date: Fri, 3 Feb 2017 00:28:43 +0300 Subject: Support custom items in context menu This is particularly important for Inspector, which lacks a lot of useful context menu actions without this patch. Change-Id: I8170c806028ff140206f13e5e1de0409e945e905 Reviewed-by: Konstantin Tokarev --- .../qt/WebCoreSupport/FrameLoaderClientQt.cpp | 4 +- .../WebKit/qt/WebCoreSupport/QWebPageAdapter.cpp | 17 +++++++- Source/WebKit/qt/WebCoreSupport/QWebPageAdapter.h | 4 +- Source/WebKit/qt/WidgetApi/qwebpage.cpp | 45 ++++++++++++++++++++-- Source/WebKit/qt/WidgetApi/qwebpage.h | 2 + Source/WebKit/qt/WidgetApi/qwebpage_p.h | 3 ++ 6 files changed, 68 insertions(+), 7 deletions(-) diff --git a/Source/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.cpp b/Source/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.cpp index 09b0aae82..0b811c8f2 100644 --- a/Source/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.cpp +++ b/Source/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.cpp @@ -735,8 +735,10 @@ void FrameLoaderClientQt::dispatchDidClearWindowObjectInWorld(DOMWrapperWorld* w if (world != mainThreadNormalWorld()) return; - if (m_webFrame) + if (m_webFrame) { m_webFrame->didClearWindowObject(); + m_webFrame->pageAdapter->clearCustomActions(); + } } void FrameLoaderClientQt::documentElementAvailable() diff --git a/Source/WebKit/qt/WebCoreSupport/QWebPageAdapter.cpp b/Source/WebKit/qt/WebCoreSupport/QWebPageAdapter.cpp index 554ab8927..a4e1f7464 100644 --- a/Source/WebKit/qt/WebCoreSupport/QWebPageAdapter.cpp +++ b/Source/WebKit/qt/WebCoreSupport/QWebPageAdapter.cpp @@ -874,8 +874,11 @@ void QWebPageAdapter::dynamicPropertyChangeEvent(QObject* obj, QDynamicPropertyC #define MAP_ACTION_FROM_VALUE(Name, Value) \ case Value: return QWebPageAdapter::Name -static QWebPageAdapter::MenuAction adapterActionForContextMenuAction(WebCore::ContextMenuAction action) +static int adapterActionForContextMenuAction(WebCore::ContextMenuAction action) { + if (action >= ContextMenuItemBaseCustomTag && action <= ContextMenuItemLastCustomTag) + return action; + switch (action) { FOR_EACH_MAPPED_MENU_ACTION(MAP_ACTION_FROM_VALUE, SEMICOLON_SEPARATOR); #if ENABLE(INSPECTOR) @@ -899,7 +902,7 @@ QList descriptionForPlatformMenu(const Vector& items, switch (item.type()) { case WebCore::CheckableActionType: /* fall through */ case WebCore::ActionType: { - QWebPageAdapter::MenuAction action = adapterActionForContextMenuAction(item.action()); + int action = adapterActionForContextMenuAction(item.action()); if (action > QWebPageAdapter::NoAction) { description.type = MenuItem::Action; description.action = action; @@ -1207,6 +1210,16 @@ void QWebPageAdapter::triggerAction(QWebPageAdapter::MenuAction action, QWebHitT } } +void QWebPageAdapter::triggerCustomAction(int action, const QString &title) +{ + if (action >= ContextMenuItemBaseCustomTag && action <= ContextMenuItemLastCustomTag) { + ContextMenuItem item(ActionType, static_cast(action), title); + page->contextMenuController()->contextMenuItemSelected(&item); + } else { + ASSERT_NOT_REACHED(); + } +} + QString QWebPageAdapter::contextMenuItemTagForAction(QWebPageAdapter::MenuAction action, bool* checkable) const { diff --git a/Source/WebKit/qt/WebCoreSupport/QWebPageAdapter.h b/Source/WebKit/qt/WebCoreSupport/QWebPageAdapter.h index ee4d2595a..fcdc25596 100644 --- a/Source/WebKit/qt/WebCoreSupport/QWebPageAdapter.h +++ b/Source/WebKit/qt/WebCoreSupport/QWebPageAdapter.h @@ -204,6 +204,7 @@ public: virtual void createUndoStep(QSharedPointer) = 0; virtual void updateNavigationActions() = 0; + virtual void clearCustomActions() = 0; virtual QWebFrameAdapter* mainFrameAdapter() = 0; @@ -249,7 +250,7 @@ public: Separator, SubMenu } type; - MenuAction action; + int action; enum Trait { None = 0, Enabled = 1, @@ -317,6 +318,7 @@ public: QWebHitTestResultPrivate* updatePositionDependentMenuActions(const QPoint&, QBitArray*); void updateActionInternal(MenuAction, const char* commandName, bool* enabled, bool* checked); void triggerAction(MenuAction, QWebHitTestResultPrivate*, const char* commandName, bool endToEndReload); + void triggerCustomAction(int action, const QString &title); QString contextMenuItemTagForAction(MenuAction, bool* checkable) const; QStringList supportedContentTypes() const; diff --git a/Source/WebKit/qt/WidgetApi/qwebpage.cpp b/Source/WebKit/qt/WidgetApi/qwebpage.cpp index 863621391..388456616 100644 --- a/Source/WebKit/qt/WidgetApi/qwebpage.cpp +++ b/Source/WebKit/qt/WidgetApi/qwebpage.cpp @@ -238,6 +238,8 @@ QWebPagePrivate::~QWebPagePrivate() // in order for various destruction callbacks out of WebCore to // work. deletePage(); + + clearCustomActions(); } void QWebPagePrivate::show() @@ -499,8 +501,15 @@ QMenu *createContextMenu(QWebPage* page, const QList& items, QBitArray const MenuItem &item = items.at(i); switch (item.type) { case MenuItem::Action: { - QWebPage::WebAction action = webActionForAdapterMenuAction(item.action); - QAction *a = page->action(action); + QAction* a = nullptr; + if (item.action < QWebPageAdapter::ActionCount) { + QWebPage::WebAction action = webActionForAdapterMenuAction(static_cast(item.action)); + a = page->action(action); + if (a) + visitedWebActions->setBit(action); + } else { + a = page->customAction(item.action); + } if (a) { a->setText(item.title); a->setEnabled(item.traits & MenuItem::Enabled); @@ -508,7 +517,6 @@ QMenu *createContextMenu(QWebPage* page, const QList& items, QBitArray a->setChecked(item.traits & MenuItem::Checked); menu->addAction(a); - visitedWebActions->setBit(action); } break; } @@ -562,6 +570,16 @@ void QWebPagePrivate::_q_webActionTriggered(bool checked) QWebPage::WebAction action = static_cast(a->data().toInt()); q->triggerAction(action, checked); } + +void QWebPagePrivate::_q_customActionTriggered(bool checked) +{ + Q_UNUSED(checked); + QAction* a = qobject_cast(q->sender()); + if (!a) + return; + int action = a->data().toInt(); + triggerCustomAction(action, a->text()); +} #endif // QT_NO_ACTION void QWebPagePrivate::updateAction(QWebPage::WebAction action) @@ -625,6 +643,12 @@ void QWebPagePrivate::updateNavigationActions() updateAction(QWebPage::ReloadAndBypassCache); } +void QWebPagePrivate::clearCustomActions() +{ + qDeleteAll(customActions); + customActions.clear(); +} + QObject *QWebPagePrivate::inspectorHandle() { return getOrCreateInspector(); @@ -2509,6 +2533,21 @@ QAction *QWebPage::action(WebAction action) const d->updateAction(action); return a; } + +QAction* QWebPage::customAction(int action) const +{ + auto actionIter = d->customActions.constFind(action); + if (actionIter != d->customActions.constEnd()) + return *actionIter; + + QAction* a = new QAction(d->q); + a->setData(action); + connect(a, SIGNAL(triggered(bool)), + this, SLOT(_q_customActionTriggered(bool))); + + d->customActions.insert(action, a); + return a; +} #endif // QT_NO_ACTION /*! diff --git a/Source/WebKit/qt/WidgetApi/qwebpage.h b/Source/WebKit/qt/WidgetApi/qwebpage.h index 01e77d44b..822bd2194 100644 --- a/Source/WebKit/qt/WidgetApi/qwebpage.h +++ b/Source/WebKit/qt/WidgetApi/qwebpage.h @@ -301,6 +301,7 @@ public: #ifndef QT_NO_ACTION QAction *action(WebAction action) const; + QAction *customAction(int action) const; #endif virtual void triggerAction(WebAction action, bool checked = false); @@ -443,6 +444,7 @@ private: Q_PRIVATE_SLOT(d, void _q_onLoadProgressChanged(int)) #ifndef QT_NO_ACTION Q_PRIVATE_SLOT(d, void _q_webActionTriggered(bool checked)) + Q_PRIVATE_SLOT(d, void _q_customActionTriggered(bool checked)) #endif Q_PRIVATE_SLOT(d, void _q_cleanupLeakMessages()) Q_PRIVATE_SLOT(d, void _q_updateScreen(QScreen*)) diff --git a/Source/WebKit/qt/WidgetApi/qwebpage_p.h b/Source/WebKit/qt/WidgetApi/qwebpage_p.h index 604c0a540..34cf288b4 100644 --- a/Source/WebKit/qt/WidgetApi/qwebpage_p.h +++ b/Source/WebKit/qt/WidgetApi/qwebpage_p.h @@ -120,6 +120,7 @@ public: virtual const char* editorCommandForKeyEvent(QKeyEvent*) OVERRIDE; void updateNavigationActions() OVERRIDE; + void clearCustomActions() OVERRIDE; virtual QObject* inspectorHandle() OVERRIDE; virtual void setInspectorFrontend(QObject*) OVERRIDE; @@ -145,6 +146,7 @@ public: void createMainFrame(); void _q_webActionTriggered(bool checked); + void _q_customActionTriggered(bool checked); void updateAction(QWebPage::WebAction); void updateEditorActions(); @@ -198,6 +200,7 @@ public: bool useFixedLayout; QAction *actions[QWebPage::WebActionCount]; + QHash customActions; QPointer window; QWidget* inspectorFrontend; -- cgit v1.2.1