Changeset 73535 in webkit


Ignore:
Timestamp:
Dec 8, 2010 11:26:05 AM (13 years ago)
Author:
bweinstein@apple.com
Message:

Layering Violation in ContextMenu - member variable of type HitTestResult
https://bugs.webkit.org/show_bug.cgi?id=50586

Reviewed by John Sullivan.

WebCore:

ContextMenu had a layering violation by having a member variable of type HitTestResult, because
classes in WebCore/platform can't know about classes in WebCore.

This patch moves the HitTestResult and all functions that use it out of ContextMenu into ContextMenuController.
All of the functions that dealt with populating the ContextMenu are now in ContextMenuController, and this
allowed us to delete the ContextMenu file, putting all of the cross-platform code that used to be it
in ContextMenuController, and the rest of the code is in the platform-specific files.

No change in behavior, no new tests.

  • Android.mk: Removed ContextMenu.cpp.
  • CMakeLists.txt: Ditto.
  • GNUmakefile.am: Ditto.
  • WebCore.gypi: Ditto.
  • WebCore.pro: Ditto.
  • WebCore.vcproj/WebCore.vcproj: Ditto.
  • WebCore.xcodeproj/project.pbxproj: Ditto.
  • page/ContextMenuController.cpp:

(WebCore::ContextMenuController::ContextMenuController): Initialized m_hitTestResult to an empty HitTestResult.
(WebCore::ContextMenuController::handleContextMenuEvent): Call populate on the ContextMenuController instead

of the ContextMenu.

(WebCore::ContextMenuController::createContextMenu): Fix some indination, and store the HitTestResult in a member

variable.

(WebCore::ContextMenuController::showContextMenu): Call addInspectElementItem on the ContextMenuController.
(WebCore::ContextMenuController::contextMenuItemSelected): Use m_hitTestResult whenever we need a HitTestResult.
(WebCore::ContextMenuController::appendItem): Validates the item for its state, and then appends it to the parent menu.

This allowed us to move checkOrEnableIfNeeded from ContextMenu.

These functions were all moved from ContextMenu, and changed slightly to fit in ContextMenuController.
All calls to ContextMenu::appendItem were changed to ContextMenuController::appendItem, which takes care
of validating the menu.
(WebCore::separatorItem): Moved from ContextMenu.
(WebCore::ContextMenuController::createAndAppendFontSubMenu): Ditto.
(WebCore::ContextMenuController::createAndAppendSpellingAndGrammarSubMenu): Ditto.
(WebCore::ContextMenuController::createAndAppendSpeechSubMenu): Ditto.
(WebCore::ContextMenuController::createAndAppendWritingDirectionSubMenu): Ditto.
(WebCore::ContextMenuController::createAndAppendTextDirectionSubMenu): Ditto.
(WebCore::ContextMenuController::createAndAppendSubstitutionsSubMenu): Ditto.
(WebCore::ContextMenuController::createAndAppendTransformationsSubMenu): Ditto.
(WebCore::selectionContainsPossibleWord): Ditto.
(WebCore::ContextMenuController::populate): Ditto.
(WebCore::ContextMenuController::addInspectElementItem): Ditto.
(WebCore::ContextMenuController::checkOrEnableIfNeeded): Ditto.

  • page/ContextMenuController.h:

(WebCore::ContextMenuController::hitTestResult): Returns the HitTestResult of the current ContextMenu.

  • platform/ContextMenu.cpp: Removed.
  • platform/ContextMenu.h:
  • platform/efl/ContextMenuEfl.cpp:

(WebCore::ContextMenu::ContextMenu): Removed m_hitTestResult from the constructor.
(WebCore::ContextMenu::appendItem): Removed the call to checkOrEnableIfNeeded.

  • platform/gtk/ContextMenuGtk.cpp:

(WebCore::ContextMenu::ContextMenu): Removed m_hitTestResult from the constructor.
(WebCore::ContextMenu::appendItem): Ditto.

  • platform/haiku/ContextMenuHaiku.cpp:

(WebCore::ContextMenu::ContextMenu): Removed m_hitTestResult from the constructor.
(WebCore::ContextMenu::appendItem): Ditto.
(WebCore::ContextMenu::insertItem): Ditto.

  • platform/mac/ContextMenuMac.mm:

(-[WebCoreMenuTarget validateMenuItem:]): Calls checkOrEnableIfNeeded on the controller instead of

the context menu.

(WebCore::ContextMenu::ContextMenu): Removed m_hitTestResult from the constructor.
(WebCore::ContextMenu::appendItem): Removed the call to checkOrEnableIfNeeded.
(WebCore::ContextMenu::insertItem): Ditto.

  • platform/win/ContextMenuWin.cpp:

(WebCore::ContextMenu::ContextMenu): Removed m_hitTestResult from the constructor.
(WebCore::ContextMenu::insertItem): Removed the call to checkOrEnableIfNeeded.

  • platform/wx/ContextMenuWx.cpp:

(WebCore::ContextMenu::ContextMenu): Removed m_hitTestResult from the constructor.
(ContextMenu::appendItem): Ditto.

WebKit/chromium:

Update users of ContextMenu and ContextMenuController to match where the new functions
are located.

  • src/ContextMenuClientImpl.cpp:

(WebKit::selectMisspelledWord):
(WebKit::ContextMenuClientImpl::getCustomMenuFromDefaultItems):

WebKit/gtk:

Update users of ContextMenu and ContextMenuController to match where the new functions
are located.

  • WebCoreSupport/ContextMenuClientGtk.cpp:

(WebKit::ContextMenuClient::getCustomMenuFromDefaultItems):

WebKit/mac:

Update users of ContextMenu and ContextMenuController to match where the new functions
are located.

  • WebCoreSupport/WebContextMenuClient.mm:

(WebContextMenuClient::getCustomMenuFromDefaultItems):
(WebContextMenuClient::contextMenuItemSelected):

  • WebView/WebHTMLView.mm:

(-[WebMenuTarget validateMenuItem:]):

WebKit/qt:

Update users of ContextMenu and ContextMenuController to match where the new functions
are located.

  • Api/qwebpage.cpp:

(QWebPagePrivate::createContextMenu):
(QWebPage::updatePositionDependentActions):

WebKit/win:

Update users of ContextMenu and ContextMenuController to match where the new functions
are located.

  • WebCoreSupport/WebContextMenuClient.cpp:

(WebContextMenuClient::getCustomMenuFromDefaultItems): Get the HitTestResult and ContextMenu from the

ContextMenuController (from the page).

(WebContextMenuClient::contextMenuItemSelected): Get the HitTestResult from the ContextMenuController.

  • WebView.cpp:

(WebView::handleContextMenuEvent): Ditto.

WebKit2:

Update users of ContextMenu and ContextMenuController to match where the new functions
are located.

  • Shared/WebContextMenuItemData.cpp:

(WebKit::WebContextMenuItemData::WebContextMenuItemData): Remove the call to checkOrEnableItem, that call will be made when

the ContextMenuItem is added to the ContextMenu through the ContextMenuController.

  • WebProcess/WebPage/WebContextMenu.cpp:

(WebKit::WebContextMenu::show):

Location:
trunk
Files:
1 deleted
40 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/Android.mk

    r73430 r73535  
    451451        platform/Arena.cpp \
    452452        platform/ContentType.cpp \
    453         platform/ContextMenu.cpp \
    454453        platform/CrossThreadCopier.cpp \
    455454        platform/DeprecatedPtrListImpl.cpp \
  • trunk/WebCore/CMakeLists.txt

    r73434 r73535  
    12711271    platform/Arena.cpp
    12721272    platform/ContentType.cpp
    1273     platform/ContextMenu.cpp
    12741273    platform/CrossThreadCopier.cpp
    12751274    platform/DeprecatedPtrListImpl.cpp
  • trunk/WebCore/ChangeLog

    r73534 r73535  
     12010-12-07  Brian Weinstein  <bweinstein@apple.com>
     2
     3        Reviewed by John Sullivan.
     4
     5        Layering Violation in ContextMenu - member variable of type HitTestResult
     6        https://bugs.webkit.org/show_bug.cgi?id=50586
     7       
     8        ContextMenu had a layering violation by having a member variable of type HitTestResult, because
     9        classes in WebCore/platform can't know about classes in WebCore.
     10       
     11        This patch moves the HitTestResult and all functions that use it out of ContextMenu into ContextMenuController.
     12        All of the functions that dealt with populating the ContextMenu are now in ContextMenuController, and this
     13        allowed us to delete the ContextMenu file, putting all of the cross-platform code that used to be it
     14        in ContextMenuController, and the rest of the code is in the platform-specific files.
     15
     16        No change in behavior, no new tests.
     17
     18        * Android.mk: Removed ContextMenu.cpp.
     19        * CMakeLists.txt: Ditto.
     20        * GNUmakefile.am: Ditto.
     21        * WebCore.gypi: Ditto.
     22        * WebCore.pro: Ditto.
     23        * WebCore.vcproj/WebCore.vcproj: Ditto.
     24        * WebCore.xcodeproj/project.pbxproj: Ditto.
     25
     26        * page/ContextMenuController.cpp:
     27        (WebCore::ContextMenuController::ContextMenuController): Initialized m_hitTestResult to an empty HitTestResult.
     28        (WebCore::ContextMenuController::handleContextMenuEvent): Call populate on the ContextMenuController instead
     29            of the ContextMenu.
     30        (WebCore::ContextMenuController::createContextMenu): Fix some indination, and store the HitTestResult in a member
     31            variable.
     32        (WebCore::ContextMenuController::showContextMenu): Call addInspectElementItem on the ContextMenuController.
     33        (WebCore::ContextMenuController::contextMenuItemSelected): Use m_hitTestResult whenever we need a HitTestResult.
     34        (WebCore::ContextMenuController::appendItem): Validates the item for its state, and then appends it to the parent menu.
     35            This allowed us to move checkOrEnableIfNeeded from ContextMenu.
     36
     37        These functions were all moved from ContextMenu, and changed slightly to fit in ContextMenuController.
     38        All calls to ContextMenu::appendItem were changed to ContextMenuController::appendItem, which takes care
     39        of validating the menu.
     40        (WebCore::separatorItem): Moved from ContextMenu.
     41        (WebCore::ContextMenuController::createAndAppendFontSubMenu): Ditto.
     42        (WebCore::ContextMenuController::createAndAppendSpellingAndGrammarSubMenu): Ditto.
     43        (WebCore::ContextMenuController::createAndAppendSpeechSubMenu): Ditto.
     44        (WebCore::ContextMenuController::createAndAppendWritingDirectionSubMenu): Ditto.
     45        (WebCore::ContextMenuController::createAndAppendTextDirectionSubMenu): Ditto.
     46        (WebCore::ContextMenuController::createAndAppendSubstitutionsSubMenu): Ditto.
     47        (WebCore::ContextMenuController::createAndAppendTransformationsSubMenu): Ditto.
     48        (WebCore::selectionContainsPossibleWord): Ditto.
     49        (WebCore::ContextMenuController::populate): Ditto.
     50        (WebCore::ContextMenuController::addInspectElementItem): Ditto.
     51        (WebCore::ContextMenuController::checkOrEnableIfNeeded): Ditto.
     52       
     53        * page/ContextMenuController.h:
     54        (WebCore::ContextMenuController::hitTestResult): Returns the HitTestResult of the current ContextMenu.
     55
     56        * platform/ContextMenu.cpp: Removed.
     57        * platform/ContextMenu.h:
     58        * platform/efl/ContextMenuEfl.cpp:
     59        (WebCore::ContextMenu::ContextMenu): Removed m_hitTestResult from the constructor.
     60        (WebCore::ContextMenu::appendItem): Removed the call to checkOrEnableIfNeeded.
     61        * platform/gtk/ContextMenuGtk.cpp:
     62        (WebCore::ContextMenu::ContextMenu): Removed m_hitTestResult from the constructor.
     63        (WebCore::ContextMenu::appendItem): Ditto.
     64        * platform/haiku/ContextMenuHaiku.cpp:
     65        (WebCore::ContextMenu::ContextMenu): Removed m_hitTestResult from the constructor.
     66        (WebCore::ContextMenu::appendItem): Ditto.
     67        (WebCore::ContextMenu::insertItem): Ditto.
     68        * platform/mac/ContextMenuMac.mm:
     69        (-[WebCoreMenuTarget validateMenuItem:]): Calls checkOrEnableIfNeeded on the controller instead of
     70            the context menu.
     71        (WebCore::ContextMenu::ContextMenu): Removed m_hitTestResult from the constructor.
     72        (WebCore::ContextMenu::appendItem): Removed the call to checkOrEnableIfNeeded.
     73        (WebCore::ContextMenu::insertItem): Ditto.
     74        * platform/win/ContextMenuWin.cpp:
     75        (WebCore::ContextMenu::ContextMenu): Removed m_hitTestResult from the constructor.
     76        (WebCore::ContextMenu::insertItem): Removed the call to checkOrEnableIfNeeded.
     77        * platform/wx/ContextMenuWx.cpp:
     78        (WebCore::ContextMenu::ContextMenu): Removed m_hitTestResult from the constructor.
     79        (ContextMenu::appendItem): Ditto.
     80
    1812010-12-08  Martin Robinson  <mrobinson@igalia.com>
    282
  • trunk/WebCore/GNUmakefile.am

    r73430 r73535  
    22592259        WebCore/platform/ContentType.cpp \
    22602260        WebCore/platform/ContentType.h \
    2261         WebCore/platform/ContextMenu.cpp \
    22622261        WebCore/platform/ContextMenu.h \
    22632262        WebCore/platform/ContextMenuItem.h \
  • trunk/WebCore/WebCore.exp.in

    r73533 r73535  
    12541254__ZN7WebCore15ContextMenuItemD1Ev
    12551255__ZN7WebCore21ContextMenuController16clearContextMenuEv
     1256__ZNK7WebCore21ContextMenuController21checkOrEnableIfNeededERNS_15ContextMenuItemE
    12561257__ZN7WebCore21ContextMenuController23contextMenuItemSelectedEPNS_15ContextMenuItemE
    12571258__ZN7WebCore21contextMenuItemVectorEP14NSMutableArray
     
    12591260__ZN7WebCore6Chrome15showContextMenuEv
    12601261__ZNK7WebCore11ContextMenu19platformDescriptionEv
    1261 __ZNK7WebCore11ContextMenu21checkOrEnableIfNeededERNS_15ContextMenuItemE
    12621262__ZNK7WebCore15ContextMenuItem15platformSubMenuEv
    12631263__ZNK7WebCore15ContextMenuItem4typeEv
  • trunk/WebCore/WebCore.gypi

    r73501 r73535  
    34223422            'platform/ContentType.cpp',
    34233423            'platform/ContentType.h',
    3424             'platform/ContextMenu.cpp',
    34253424            'platform/ContextMenu.h',
    34263425            'platform/ContextMenuItem.h',
  • trunk/WebCore/WebCore.pro

    r73430 r73535  
    11521152    platform/text/Hyphenation.cpp \
    11531153    platform/ContentType.cpp \
    1154     platform/ContextMenu.cpp \
    11551154    platform/CrossThreadCopier.cpp \
    11561155    platform/DeprecatedPtrListImpl.cpp \
  • trunk/WebCore/WebCore.vcproj/WebCore.vcproj

    r73501 r73535  
    2531525315                        </File>
    2531625316                        <File
    25317                                 RelativePath="..\platform\ContextMenu.cpp"
    25318                                 >
    25319                         </File>
    25320                         <File
    2532125317                                RelativePath="..\platform\ContextMenu.h"
    2532225318                                >
  • trunk/WebCore/WebCore.xcodeproj/project.pbxproj

    r73496 r73535  
    28402840                93B2D8180F9920EE006AE6B2 /* SuddenTermination.mm in Sources */ = {isa = PBXBuildFile; fileRef = 93B2D8170F9920EE006AE6B2 /* SuddenTermination.mm */; };
    28412841                93B6A0E60B0BCA5C00F5027A /* ContextMenu.h in Headers */ = {isa = PBXBuildFile; fileRef = 93B6A0E50B0BCA5C00F5027A /* ContextMenu.h */; settings = {ATTRIBUTES = (Private, ); }; };
    2842                 93B6A0E80B0BCA6700F5027A /* ContextMenu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93B6A0E70B0BCA6700F5027A /* ContextMenu.cpp */; };
    28432842                93B6A0EA0B0BCA8400F5027A /* ContextMenuMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 93B6A0E90B0BCA8400F5027A /* ContextMenuMac.mm */; };
    28442843                93B70D6309EB0C7C009D8468 /* JSDOMBinding.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93B70D4709EB0C7C009D8468 /* JSDOMBinding.cpp */; };
     
    90089007                93B2D8170F9920EE006AE6B2 /* SuddenTermination.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = SuddenTermination.mm; sourceTree = "<group>"; };
    90099008                93B6A0E50B0BCA5C00F5027A /* ContextMenu.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ContextMenu.h; sourceTree = "<group>"; };
    9010                 93B6A0E70B0BCA6700F5027A /* ContextMenu.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ContextMenu.cpp; sourceTree = "<group>"; };
    90119009                93B6A0E90B0BCA8400F5027A /* ContextMenuMac.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = ContextMenuMac.mm; sourceTree = "<group>"; };
    90129010                93B70D4709EB0C7C009D8468 /* JSDOMBinding.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JSDOMBinding.cpp; sourceTree = "<group>"; };
     
    1757517573                                41D015C90F4B5C71004A662F /* ContentType.cpp */,
    1757617574                                41D015C80F4B5C71004A662F /* ContentType.h */,
    17577                                 93B6A0E70B0BCA6700F5027A /* ContextMenu.cpp */,
    1757817575                                93B6A0E50B0BCA5C00F5027A /* ContextMenu.h */,
    1757917576                                06027CAC0B1CBFC000884B2D /* ContextMenuItem.h */,
     
    2195721954                                BC5EB9800E82072500B25965 /* ContentData.cpp in Sources */,
    2195821955                                41D015CB0F4B5C71004A662F /* ContentType.cpp in Sources */,
    21959                                 93B6A0E80B0BCA6700F5027A /* ContextMenu.cpp in Sources */,
    2196021956                                065AD4F60B0C2EDA005A2B1D /* ContextMenuController.cpp in Sources */,
    2196121957                                06027CB30B1CC03D00884B2D /* ContextMenuItemMac.mm in Sources */,
  • trunk/WebCore/page/ContextMenuController.cpp

    r73444 r73535  
    3434#include "ContextMenu.h"
    3535#include "ContextMenuClient.h"
     36#include "ContextMenuItem.h"
    3637#include "ContextMenuProvider.h"
    3738#include "Document.h"
     
    5152#include "HitTestResult.h"
    5253#include "InspectorController.h"
     54#include "LocalizedStrings.h"
    5355#include "MouseEvent.h"
    5456#include "NavigationAction.h"
     
    6466#include "WindowFeatures.h"
    6567#include "markup.h"
     68#include <wtf/unicode/Unicode.h>
     69
     70using namespace WTF;
     71using namespace Unicode;
    6672
    6773namespace WebCore {
     
    9197void ContextMenuController::handleContextMenuEvent(Event* event)
    9298{
    93     m_contextMenu.set(createContextMenu(event));
     99    m_contextMenu = createContextMenu(event);
    94100    if (!m_contextMenu)
    95101        return;
    96     m_contextMenu->populate();
     102
     103    populate();
     104
    97105    showContextMenu(event);
    98106}
     
    102110    m_menuProvider = menuProvider;
    103111
    104     m_contextMenu.set(createContextMenu(event));
     112    m_contextMenu = createContextMenu(event);
    105113    if (!m_contextMenu) {
    106114        clearContextMenu();
     
    112120}
    113121
    114 ContextMenu* ContextMenuController::createContextMenu(Event* event)
    115 {
    116    if (!event->isMouseEvent())
     122PassOwnPtr<ContextMenu> ContextMenuController::createContextMenu(Event* event)
     123{
     124    if (!event->isMouseEvent())
    117125        return 0;
     126
    118127    MouseEvent* mouseEvent = static_cast<MouseEvent*>(event);
    119128    HitTestResult result(mouseEvent->absoluteLocation());
     
    124133    if (!result.innerNonSharedNode())
    125134        return 0;
    126     return new ContextMenu(result);
     135
     136    m_hitTestResult = result;
     137
     138    return new ContextMenu;
    127139}
    128140
     
    131143#if ENABLE(INSPECTOR)
    132144    if (m_page->inspectorController()->enabled())
    133         m_contextMenu->addInspectElementItem();
     145        addInspectElementItem();
    134146#endif
    135147    PlatformMenuDescription customMenu = m_client->getCustomMenuFromDefaultItems(m_contextMenu.get());
     
    163175    }
    164176
    165     HitTestResult result = m_contextMenu->hitTestResult();
    166     Frame* frame = result.innerNonSharedNode()->document()->frame();
     177    Frame* frame = m_hitTestResult.innerNonSharedNode()->document()->frame();
    167178    if (!frame)
    168179        return;
     
    170181    switch (item->action()) {
    171182    case ContextMenuItemTagOpenLinkInNewWindow:
    172         openNewWindow(result.absoluteLinkURL(), frame);
     183        openNewWindow(m_hitTestResult.absoluteLinkURL(), frame);
    173184        break;
    174185    case ContextMenuItemTagDownloadLinkToDisk:
    175186        // FIXME: Some day we should be able to do this from within WebCore.
    176         m_client->downloadURL(result.absoluteLinkURL());
     187        m_client->downloadURL(m_hitTestResult.absoluteLinkURL());
    177188        break;
    178189    case ContextMenuItemTagCopyLinkToClipboard:
    179         frame->editor()->copyURL(result.absoluteLinkURL(), result.textContent());
     190        frame->editor()->copyURL(m_hitTestResult.absoluteLinkURL(), m_hitTestResult.textContent());
    180191        break;
    181192    case ContextMenuItemTagOpenImageInNewWindow:
    182         openNewWindow(result.absoluteImageURL(), frame);
     193        openNewWindow(m_hitTestResult.absoluteImageURL(), frame);
    183194        break;
    184195    case ContextMenuItemTagDownloadImageToDisk:
    185196        // FIXME: Some day we should be able to do this from within WebCore.
    186         m_client->downloadURL(result.absoluteImageURL());
     197        m_client->downloadURL(m_hitTestResult.absoluteImageURL());
    187198        break;
    188199    case ContextMenuItemTagCopyImageToClipboard:
    189200        // FIXME: The Pasteboard class is not written yet
    190201        // For now, call into the client. This is temporary!
    191         frame->editor()->copyImage(result);
     202        frame->editor()->copyImage(m_hitTestResult);
    192203        break;
    193204    case ContextMenuItemTagOpenMediaInNewWindow:
    194         openNewWindow(result.absoluteMediaURL(), frame);
     205        openNewWindow(m_hitTestResult.absoluteMediaURL(), frame);
    195206        break;
    196207    case ContextMenuItemTagCopyMediaLinkToClipboard:
    197         frame->editor()->copyURL(result.absoluteMediaURL(), result.textContent());
     208        frame->editor()->copyURL(m_hitTestResult.absoluteMediaURL(), m_hitTestResult.textContent());
    198209        break;
    199210    case ContextMenuItemTagToggleMediaControls:
    200         result.toggleMediaControlsDisplay();
     211        m_hitTestResult.toggleMediaControlsDisplay();
    201212        break;
    202213    case ContextMenuItemTagToggleMediaLoop:
    203         result.toggleMediaLoopPlayback();
     214        m_hitTestResult.toggleMediaLoopPlayback();
    204215        break;
    205216    case ContextMenuItemTagEnterVideoFullscreen:
    206         result.enterFullscreenForVideo();
     217        m_hitTestResult.enterFullscreenForVideo();
    207218        break;
    208219    case ContextMenuItemTagMediaPlayPause:
    209         result.toggleMediaPlayState();
     220        m_hitTestResult.toggleMediaPlayState();
    210221        break;
    211222    case ContextMenuItemTagMediaMute:
    212         result.toggleMediaMuteState();
     223        m_hitTestResult.toggleMediaMuteState();
    213224        break;
    214225    case ContextMenuItemTagOpenFrameInNewWindow: {
     
    274285        break;
    275286    case ContextMenuItemTagOpenLink:
    276         if (Frame* targetFrame = result.targetFrame())
    277             targetFrame->loader()->loadFrameRequest(FrameLoadRequest(frame->document()->securityOrigin(), ResourceRequest(result.absoluteLinkURL(), frame->loader()->outgoingReferrer())), false, false, 0, 0, SendReferrer);
     287        if (Frame* targetFrame = m_hitTestResult.targetFrame())
     288            targetFrame->loader()->loadFrameRequest(FrameLoadRequest(frame->document()->securityOrigin(), ResourceRequest(m_hitTestResult.absoluteLinkURL(), frame->loader()->outgoingReferrer())), false, false, 0, 0, SendReferrer);
    278289        else
    279             openNewWindow(result.absoluteLinkURL(), frame);
     290            openNewWindow(m_hitTestResult.absoluteLinkURL(), frame);
    280291        break;
    281292    case ContextMenuItemTagBold:
     
    296307        RefPtr<Range> selectedRange = frame->selection()->toNormalizedRange();
    297308        if (!selectedRange || selectedRange->collapsed(ec)) {
    298             Document* document = result.innerNonSharedNode()->document();
     309            Document* document = m_hitTestResult.innerNonSharedNode()->document();
    299310            selectedRange = document->createRange();
    300311            selectedRange->selectNode(document->documentElement(), ec);
     
    386397        break;
    387398    case ContextMenuItemTagChangeBack:
    388         frame->editor()->changeBackToReplacedString(result.replacedString());
     399        frame->editor()->changeBackToReplacedString(m_hitTestResult.replacedString());
    389400        break;
    390401#endif
     
    392403    case ContextMenuItemTagInspectElement:
    393404        if (Page* page = frame->page())
    394             page->inspectorController()->inspect(result.innerNonSharedNode());
     405            page->inspectorController()->inspect(m_hitTestResult.innerNonSharedNode());
    395406        break;
    396407#endif
     
    400411}
    401412
     413void ContextMenuController::appendItem(ContextMenuItem& menuItem, ContextMenu* parentMenu)
     414{
     415    checkOrEnableIfNeeded(menuItem);
     416    if (parentMenu)
     417        parentMenu->appendItem(menuItem);
     418}
     419
     420static PassOwnPtr<ContextMenuItem> separatorItem()
     421{
     422    return new ContextMenuItem(SeparatorType, ContextMenuItemTagNoAction, String());
     423}
     424
     425void ContextMenuController::createAndAppendFontSubMenu(ContextMenuItem& fontMenuItem)
     426{
     427    ContextMenu fontMenu;
     428
     429#if PLATFORM(MAC)
     430    ContextMenuItem showFonts(ActionType, ContextMenuItemTagShowFonts, contextMenuItemTagShowFonts());
     431#endif
     432    ContextMenuItem bold(CheckableActionType, ContextMenuItemTagBold, contextMenuItemTagBold());
     433    ContextMenuItem italic(CheckableActionType, ContextMenuItemTagItalic, contextMenuItemTagItalic());
     434    ContextMenuItem underline(CheckableActionType, ContextMenuItemTagUnderline, contextMenuItemTagUnderline());
     435    ContextMenuItem outline(ActionType, ContextMenuItemTagOutline, contextMenuItemTagOutline());
     436#if PLATFORM(MAC)
     437    ContextMenuItem styles(ActionType, ContextMenuItemTagStyles, contextMenuItemTagStyles());
     438    ContextMenuItem showColors(ActionType, ContextMenuItemTagShowColors, contextMenuItemTagShowColors());
     439#endif
     440
     441#if PLATFORM(MAC)
     442    appendItem(showFonts, &fontMenu);
     443#endif
     444    appendItem(bold, &fontMenu);
     445    appendItem(italic, &fontMenu);
     446    appendItem(underline, &fontMenu);
     447    appendItem(outline, &fontMenu);
     448#if PLATFORM(MAC)
     449    appendItem(styles, &fontMenu);
     450    appendItem(*separatorItem(), &fontMenu);
     451    appendItem(showColors, &fontMenu);
     452#endif
     453
     454    fontMenuItem.setSubMenu(&fontMenu);
     455}
     456
     457#if !defined(BUILDING_ON_TIGER)
     458
     459#if !PLATFORM(GTK)
     460
     461void ContextMenuController::createAndAppendSpellingAndGrammarSubMenu(ContextMenuItem& spellingAndGrammarMenuItem)
     462{
     463    ContextMenu spellingAndGrammarMenu;
     464
     465    ContextMenuItem showSpellingPanel(ActionType, ContextMenuItemTagShowSpellingPanel,
     466        contextMenuItemTagShowSpellingPanel(true));
     467    ContextMenuItem checkSpelling(ActionType, ContextMenuItemTagCheckSpelling,
     468        contextMenuItemTagCheckSpelling());
     469    ContextMenuItem checkAsYouType(CheckableActionType, ContextMenuItemTagCheckSpellingWhileTyping,
     470        contextMenuItemTagCheckSpellingWhileTyping());
     471    ContextMenuItem grammarWithSpelling(CheckableActionType, ContextMenuItemTagCheckGrammarWithSpelling,
     472        contextMenuItemTagCheckGrammarWithSpelling());
     473#if PLATFORM(MAC) && !defined(BUILDING_ON_LEOPARD)
     474    ContextMenuItem correctSpelling(CheckableActionType, ContextMenuItemTagCorrectSpellingAutomatically,
     475        contextMenuItemTagCorrectSpellingAutomatically());
     476#endif
     477
     478    appendItem(showSpellingPanel, &spellingAndGrammarMenu);
     479    appendItem(checkSpelling, &spellingAndGrammarMenu);
     480#if PLATFORM(MAC) && !defined(BUILDING_ON_LEOPARD)
     481    appendItem(*separatorItem(), &spellingAndGrammarMenu);
     482#endif
     483    appendItem(checkAsYouType, &spellingAndGrammarMenu);
     484    appendItem(grammarWithSpelling, &spellingAndGrammarMenu);
     485#if PLATFORM(MAC) && !defined(BUILDING_ON_LEOPARD)
     486    appendItem(correctSpelling, &spellingAndGrammarMenu);
     487#endif
     488
     489    spellingAndGrammarMenuItem.setSubMenu(&spellingAndGrammarMenu);
     490}
     491
     492#endif // !PLATFORM(GTK)
     493
     494#else
     495
     496void ContextMenuController::createAndAppendSpellingAndGrammarSubMenu(ContextMenuItem& spellingAndGrammarMenuItem)
     497{
     498    ContextMenu spellingMenu;
     499
     500    ContextMenuItem showSpellingPanel(ActionType, ContextMenuItemTagShowSpellingPanel,
     501        contextMenuItemTagShowSpellingPanel(true));
     502    ContextMenuItem checkSpelling(ActionType, ContextMenuItemTagCheckSpelling,
     503        contextMenuItemTagCheckSpelling());
     504    ContextMenuItem checkAsYouType(CheckableActionType, ContextMenuItemTagCheckSpellingWhileTyping,
     505        contextMenuItemTagCheckSpellingWhileTyping());
     506
     507    appendItem(showSpellingPanel, &spellingMenu);
     508    appendItem(checkSpelling, &spellingMenu);
     509    appendItem(checkAsYouType, &spellingMenu);
     510
     511    spellingMenuItem.setSubMenu(&spellingMenu);
     512}
     513
     514#endif
     515
     516#if PLATFORM(MAC)
     517
     518void ContextMenuController::createAndAppendSpeechSubMenu(ContextMenuItem& speechMenuItem)
     519{
     520    ContextMenu speechMenu;
     521
     522    ContextMenuItem start(ActionType, ContextMenuItemTagStartSpeaking, contextMenuItemTagStartSpeaking());
     523    ContextMenuItem stop(ActionType, ContextMenuItemTagStopSpeaking, contextMenuItemTagStopSpeaking());
     524
     525    appendItem(start, &speechMenu);
     526    appendItem(stop, &speechMenu);
     527
     528    speechMenuItem.setSubMenu(&speechMenu);
     529}
     530
     531#endif
     532 
     533#if !PLATFORM(GTK)
     534
     535void ContextMenuController::createAndAppendWritingDirectionSubMenu(ContextMenuItem& writingDirectionMenuItem)
     536{
     537    ContextMenu writingDirectionMenu;
     538
     539    ContextMenuItem defaultItem(ActionType, ContextMenuItemTagDefaultDirection,
     540        contextMenuItemTagDefaultDirection());
     541    ContextMenuItem ltr(CheckableActionType, ContextMenuItemTagLeftToRight, contextMenuItemTagLeftToRight());
     542    ContextMenuItem rtl(CheckableActionType, ContextMenuItemTagRightToLeft, contextMenuItemTagRightToLeft());
     543
     544    appendItem(defaultItem, &writingDirectionMenu);
     545    appendItem(ltr, &writingDirectionMenu);
     546    appendItem(rtl, &writingDirectionMenu);
     547
     548    writingDirectionMenuItem.setSubMenu(&writingDirectionMenu);
     549}
     550
     551void ContextMenuController::createAndAppendTextDirectionSubMenu(ContextMenuItem& textDirectionMenuItem)
     552{
     553    ContextMenu textDirectionMenu;
     554
     555    ContextMenuItem defaultItem(ActionType, ContextMenuItemTagTextDirectionDefault, contextMenuItemTagDefaultDirection());
     556    ContextMenuItem ltr(CheckableActionType, ContextMenuItemTagTextDirectionLeftToRight, contextMenuItemTagLeftToRight());
     557    ContextMenuItem rtl(CheckableActionType, ContextMenuItemTagTextDirectionRightToLeft, contextMenuItemTagRightToLeft());
     558
     559    appendItem(defaultItem, &textDirectionMenu);
     560    appendItem(ltr, &textDirectionMenu);
     561    appendItem(rtl, &textDirectionMenu);
     562
     563    textDirectionMenuItem.setSubMenu(&textDirectionMenu);
     564}
     565
     566#endif
     567
     568#if PLATFORM(MAC) && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
     569
     570void ContextMenuController::createAndAppendSubstitutionsSubMenu(ContextMenuItem& substitutionsMenuItem)
     571{
     572    ContextMenu substitutionsMenu;
     573
     574    ContextMenuItem showSubstitutions(ActionType, ContextMenuItemTagShowSubstitutions, contextMenuItemTagShowSubstitutions(true));
     575    ContextMenuItem smartCopyPaste(CheckableActionType, ContextMenuItemTagSmartCopyPaste, contextMenuItemTagSmartCopyPaste());
     576    ContextMenuItem smartQuotes(CheckableActionType, ContextMenuItemTagSmartQuotes, contextMenuItemTagSmartQuotes());
     577    ContextMenuItem smartDashes(CheckableActionType, ContextMenuItemTagSmartDashes, contextMenuItemTagSmartDashes());
     578    ContextMenuItem smartLinks(CheckableActionType, ContextMenuItemTagSmartLinks, contextMenuItemTagSmartLinks());
     579    ContextMenuItem textReplacement(CheckableActionType, ContextMenuItemTagTextReplacement, contextMenuItemTagTextReplacement());
     580
     581    appendItem(showSubstitutions, &substitutionsMenu);
     582    appendItem(*separatorItem(), &substitutionsMenu);
     583    appendItem(smartCopyPaste, &substitutionsMenu);
     584    appendItem(smartQuotes, &substitutionsMenu);
     585    appendItem(smartDashes, &substitutionsMenu);
     586    appendItem(smartLinks, &substitutionsMenu);
     587    appendItem(textReplacement, &substitutionsMenu);
     588
     589    substitutionsMenuItem.setSubMenu(&substitutionsMenu);
     590}
     591
     592void ContextMenuController::createAndAppendTransformationsSubMenu(ContextMenuItem& transformationsMenuItem)
     593{
     594    ContextMenu transformationsMenu;
     595
     596    ContextMenuItem makeUpperCase(ActionType, ContextMenuItemTagMakeUpperCase, contextMenuItemTagMakeUpperCase());
     597    ContextMenuItem makeLowerCase(ActionType, ContextMenuItemTagMakeLowerCase, contextMenuItemTagMakeLowerCase());
     598    ContextMenuItem capitalize(ActionType, ContextMenuItemTagCapitalize, contextMenuItemTagCapitalize());
     599
     600    appendItem(makeUpperCase, &transformationsMenu);
     601    appendItem(makeLowerCase, &transformationsMenu);
     602    appendItem(capitalize, &transformationsMenu);
     603
     604    transformationsMenuItem.setSubMenu(&transformationsMenu);
     605}
     606
     607#endif
     608
     609static bool selectionContainsPossibleWord(Frame* frame)
     610{
     611    // Current algorithm: look for a character that's not just a separator.
     612    for (TextIterator it(frame->selection()->toNormalizedRange().get()); !it.atEnd(); it.advance()) {
     613        int length = it.length();
     614        const UChar* characters = it.characters();
     615        for (int i = 0; i < length; ++i)
     616            if (!(category(characters[i]) & (Separator_Space | Separator_Line | Separator_Paragraph)))
     617                return true;
     618    }
     619    return false;
     620}
     621
     622void ContextMenuController::populate()
     623{
     624    ContextMenuItem OpenLinkItem(ActionType, ContextMenuItemTagOpenLink, contextMenuItemTagOpenLink());
     625    ContextMenuItem OpenLinkInNewWindowItem(ActionType, ContextMenuItemTagOpenLinkInNewWindow,
     626        contextMenuItemTagOpenLinkInNewWindow());
     627    ContextMenuItem DownloadFileItem(ActionType, ContextMenuItemTagDownloadLinkToDisk,
     628        contextMenuItemTagDownloadLinkToDisk());
     629    ContextMenuItem CopyLinkItem(ActionType, ContextMenuItemTagCopyLinkToClipboard,
     630        contextMenuItemTagCopyLinkToClipboard());
     631    ContextMenuItem OpenImageInNewWindowItem(ActionType, ContextMenuItemTagOpenImageInNewWindow,
     632        contextMenuItemTagOpenImageInNewWindow());
     633    ContextMenuItem DownloadImageItem(ActionType, ContextMenuItemTagDownloadImageToDisk,
     634        contextMenuItemTagDownloadImageToDisk());
     635    ContextMenuItem CopyImageItem(ActionType, ContextMenuItemTagCopyImageToClipboard,
     636        contextMenuItemTagCopyImageToClipboard());
     637    ContextMenuItem OpenMediaInNewWindowItem(ActionType, ContextMenuItemTagOpenMediaInNewWindow, String());
     638    ContextMenuItem CopyMediaLinkItem(ActionType, ContextMenuItemTagCopyMediaLinkToClipboard,
     639        String());
     640    ContextMenuItem MediaPlayPause(ActionType, ContextMenuItemTagMediaPlayPause,
     641        contextMenuItemTagMediaPlay());
     642    ContextMenuItem MediaMute(ActionType, ContextMenuItemTagMediaMute,
     643        contextMenuItemTagMediaMute());
     644    ContextMenuItem ToggleMediaControls(CheckableActionType, ContextMenuItemTagToggleMediaControls,
     645        contextMenuItemTagToggleMediaControls());
     646    ContextMenuItem ToggleMediaLoop(CheckableActionType, ContextMenuItemTagToggleMediaLoop,
     647        contextMenuItemTagToggleMediaLoop());
     648    ContextMenuItem EnterVideoFullscreen(ActionType, ContextMenuItemTagEnterVideoFullscreen,
     649        contextMenuItemTagEnterVideoFullscreen());
     650#if PLATFORM(MAC)
     651    ContextMenuItem SearchSpotlightItem(ActionType, ContextMenuItemTagSearchInSpotlight,
     652        contextMenuItemTagSearchInSpotlight());
     653    ContextMenuItem LookInDictionaryItem(ActionType, ContextMenuItemTagLookUpInDictionary,
     654        contextMenuItemTagLookUpInDictionary());
     655#endif
     656#if !PLATFORM(GTK)
     657    ContextMenuItem SearchWebItem(ActionType, ContextMenuItemTagSearchWeb, contextMenuItemTagSearchWeb());
     658#endif
     659    ContextMenuItem CopyItem(ActionType, ContextMenuItemTagCopy, contextMenuItemTagCopy());
     660    ContextMenuItem BackItem(ActionType, ContextMenuItemTagGoBack, contextMenuItemTagGoBack());
     661    ContextMenuItem ForwardItem(ActionType, ContextMenuItemTagGoForward,  contextMenuItemTagGoForward());
     662    ContextMenuItem StopItem(ActionType, ContextMenuItemTagStop, contextMenuItemTagStop());
     663    ContextMenuItem ReloadItem(ActionType, ContextMenuItemTagReload, contextMenuItemTagReload());
     664    ContextMenuItem OpenFrameItem(ActionType, ContextMenuItemTagOpenFrameInNewWindow,
     665        contextMenuItemTagOpenFrameInNewWindow());
     666    ContextMenuItem NoGuessesItem(ActionType, ContextMenuItemTagNoGuessesFound,
     667        contextMenuItemTagNoGuessesFound());
     668    ContextMenuItem IgnoreSpellingItem(ActionType, ContextMenuItemTagIgnoreSpelling,
     669        contextMenuItemTagIgnoreSpelling());
     670    ContextMenuItem LearnSpellingItem(ActionType, ContextMenuItemTagLearnSpelling,
     671        contextMenuItemTagLearnSpelling());
     672    ContextMenuItem IgnoreGrammarItem(ActionType, ContextMenuItemTagIgnoreGrammar,
     673        contextMenuItemTagIgnoreGrammar());
     674    ContextMenuItem CutItem(ActionType, ContextMenuItemTagCut, contextMenuItemTagCut());
     675    ContextMenuItem PasteItem(ActionType, ContextMenuItemTagPaste, contextMenuItemTagPaste());
     676#if PLATFORM(GTK)
     677    ContextMenuItem DeleteItem(ActionType, ContextMenuItemTagDelete, contextMenuItemTagDelete());
     678    ContextMenuItem SelectAllItem(ActionType, ContextMenuItemTagSelectAll, contextMenuItemTagSelectAll());
     679#endif
     680
     681    Node* node = m_hitTestResult.innerNonSharedNode();
     682    if (!node)
     683        return;
     684#if PLATFORM(GTK)
     685    if (!m_hitTestResult.isContentEditable() && (node->isElementNode() && static_cast<Element*>(node)->isFormControlElement()))
     686        return;
     687#endif
     688    Frame* frame = node->document()->frame();
     689    if (!frame)
     690        return;
     691
     692    if (!m_hitTestResult.isContentEditable()) {
     693        FrameLoader* loader = frame->loader();
     694        KURL linkURL = m_hitTestResult.absoluteLinkURL();
     695        if (!linkURL.isEmpty()) {
     696            if (loader->canHandleRequest(ResourceRequest(linkURL))) {
     697                appendItem(OpenLinkItem, m_contextMenu.get());
     698                appendItem(OpenLinkInNewWindowItem, m_contextMenu.get());
     699                appendItem(DownloadFileItem, m_contextMenu.get());
     700            }
     701            appendItem(CopyLinkItem, m_contextMenu.get());
     702        }
     703
     704        KURL imageURL = m_hitTestResult.absoluteImageURL();
     705        if (!imageURL.isEmpty()) {
     706            if (!linkURL.isEmpty())
     707                appendItem(*separatorItem(), m_contextMenu.get());
     708
     709            appendItem(OpenImageInNewWindowItem, m_contextMenu.get());
     710            appendItem(DownloadImageItem, m_contextMenu.get());
     711            if (imageURL.isLocalFile() || m_hitTestResult.image())
     712                appendItem(CopyImageItem, m_contextMenu.get());
     713        }
     714
     715        KURL mediaURL = m_hitTestResult.absoluteMediaURL();
     716        if (!mediaURL.isEmpty()) {
     717            if (!linkURL.isEmpty() || !imageURL.isEmpty())
     718                appendItem(*separatorItem(), m_contextMenu.get());
     719
     720            appendItem(MediaPlayPause, m_contextMenu.get());
     721            appendItem(MediaMute, m_contextMenu.get());
     722            appendItem(ToggleMediaControls, m_contextMenu.get());
     723            appendItem(ToggleMediaLoop, m_contextMenu.get());
     724            appendItem(EnterVideoFullscreen, m_contextMenu.get());
     725
     726            appendItem(*separatorItem(), m_contextMenu.get());
     727            appendItem(CopyMediaLinkItem, m_contextMenu.get());
     728            appendItem(OpenMediaInNewWindowItem, m_contextMenu.get());
     729        }
     730
     731        if (imageURL.isEmpty() && linkURL.isEmpty() && mediaURL.isEmpty()) {
     732            if (m_hitTestResult.isSelected()) {
     733                if (selectionContainsPossibleWord(frame)) {
     734#if PLATFORM(MAC)
     735                    appendItem(SearchSpotlightItem, m_contextMenu.get());
     736#endif
     737#if !PLATFORM(GTK)
     738                    appendItem(SearchWebItem, m_contextMenu.get());
     739                    appendItem(*separatorItem(), m_contextMenu.get());
     740#endif
     741#if PLATFORM(MAC)
     742                    appendItem(LookInDictionaryItem, m_contextMenu.get());
     743                    appendItem(*separatorItem(), m_contextMenu.get());
     744#endif
     745                }
     746                appendItem(CopyItem, m_contextMenu.get());
     747#if PLATFORM(MAC)
     748                appendItem(*separatorItem(), m_contextMenu.get());
     749                ContextMenuItem SpeechMenuItem(SubmenuType, ContextMenuItemTagSpeechMenu, contextMenuItemTagSpeechMenu());
     750                createAndAppendSpeechSubMenu(SpeechMenuItem);
     751                appendItem(SpeechMenuItem, m_contextMenu.get());
     752#endif               
     753            } else {
     754#if ENABLE(INSPECTOR)
     755                if (!(frame->page() && frame->page()->inspectorController()->hasInspectorFrontendClient())) {
     756#endif
     757                if (frame->page() && frame->page()->backForward()->canGoBackOrForward(-1))
     758                    appendItem(BackItem, m_contextMenu.get());
     759
     760                if (frame->page() && frame->page()->backForward()->canGoBackOrForward(1))
     761                    appendItem(ForwardItem, m_contextMenu.get());
     762
     763                // use isLoadingInAPISense rather than isLoading because Stop/Reload are
     764                // intended to match WebKit's API, not WebCore's internal notion of loading status
     765                if (loader->documentLoader()->isLoadingInAPISense())
     766                    appendItem(StopItem, m_contextMenu.get());
     767                else
     768                    appendItem(ReloadItem, m_contextMenu.get());
     769#if ENABLE(INSPECTOR)
     770                }
     771#endif
     772
     773                if (frame->page() && frame != frame->page()->mainFrame())
     774                    appendItem(OpenFrameItem, m_contextMenu.get());
     775            }
     776        }
     777    } else { // Make an editing context menu
     778        SelectionController* selection = frame->selection();
     779        bool inPasswordField = selection->isInPasswordField();
     780        bool spellCheckingEnabled = frame->editor()->isSpellCheckingEnabledFor(node);
     781       
     782        if (!inPasswordField && spellCheckingEnabled) {
     783            // Consider adding spelling-related or grammar-related context menu items (never both, since a single selected range
     784            // is never considered a misspelling and bad grammar at the same time)
     785            bool misspelling;
     786            bool badGrammar;
     787            Vector<String> guesses = frame->editor()->guessesForMisspelledOrUngrammaticalSelection(misspelling, badGrammar);
     788            if (misspelling || badGrammar) {
     789                size_t size = guesses.size();
     790                if (size == 0) {
     791                    // If there's bad grammar but no suggestions (e.g., repeated word), just leave off the suggestions
     792                    // list and trailing separator rather than adding a "No Guesses Found" item (matches AppKit)
     793                    if (misspelling) {
     794                        appendItem(NoGuessesItem, m_contextMenu.get());
     795                        appendItem(*separatorItem(), m_contextMenu.get());
     796                    }
     797                } else {
     798                    for (unsigned i = 0; i < size; i++) {
     799                        const String &guess = guesses[i];
     800                        if (!guess.isEmpty()) {
     801                            ContextMenuItem item(ActionType, ContextMenuItemTagSpellingGuess, guess);
     802                            appendItem(item, m_contextMenu.get());
     803                        }
     804                    }
     805                    appendItem(*separatorItem(), m_contextMenu.get());                   
     806                }
     807               
     808                if (misspelling) {
     809                    appendItem(IgnoreSpellingItem, m_contextMenu.get());
     810                    appendItem(LearnSpellingItem, m_contextMenu.get());
     811                } else
     812                    appendItem(IgnoreGrammarItem, m_contextMenu.get());
     813                appendItem(*separatorItem(), m_contextMenu.get());
     814#if PLATFORM(MAC) && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
     815            } else {
     816                // If the string was autocorrected, generate a contextual menu item allowing it to be changed back.
     817                String replacedString = m_hitTestResult.replacedString();
     818                if (!replacedString.isEmpty()) {
     819                    ContextMenuItem item(ActionType, ContextMenuItemTagChangeBack, contextMenuItemTagChangeBack(replacedString));
     820                    appendItem(item, m_contextMenu.get());
     821                    appendItem(*separatorItem(), m_contextMenu.get());
     822                }
     823#endif
     824            }
     825        }
     826
     827        FrameLoader* loader = frame->loader();
     828        KURL linkURL = m_hitTestResult.absoluteLinkURL();
     829        if (!linkURL.isEmpty()) {
     830            if (loader->canHandleRequest(ResourceRequest(linkURL))) {
     831                appendItem(OpenLinkItem, m_contextMenu.get());
     832                appendItem(OpenLinkInNewWindowItem, m_contextMenu.get());
     833                appendItem(DownloadFileItem, m_contextMenu.get());
     834            }
     835            appendItem(CopyLinkItem, m_contextMenu.get());
     836            appendItem(*separatorItem(), m_contextMenu.get());
     837        }
     838
     839        if (m_hitTestResult.isSelected() && !inPasswordField && selectionContainsPossibleWord(frame)) {
     840#if PLATFORM(MAC)
     841            appendItem(SearchSpotlightItem, m_contextMenu.get());
     842#endif
     843#if !PLATFORM(GTK)
     844            appendItem(SearchWebItem, m_contextMenu.get());
     845            appendItem(*separatorItem(), m_contextMenu.get());
     846#endif
     847     
     848#if PLATFORM(MAC)
     849            appendItem(LookInDictionaryItem, m_contextMenu.get());
     850            appendItem(*separatorItem(), m_contextMenu.get());
     851#endif
     852        }
     853
     854        appendItem(CutItem, m_contextMenu.get());
     855        appendItem(CopyItem, m_contextMenu.get());
     856        appendItem(PasteItem, m_contextMenu.get());
     857#if PLATFORM(GTK)
     858        appendItem(DeleteItem, m_contextMenu.get());
     859        appendItem(*separatorItem(), m_contextMenu.get());
     860        appendItem(SelectAllItem, m_contextMenu.get());
     861#endif
     862
     863        if (!inPasswordField) {
     864            appendItem(*separatorItem(), m_contextMenu.get());
     865#ifndef BUILDING_ON_TIGER
     866#if !PLATFORM(GTK)
     867            ContextMenuItem SpellingAndGrammarMenuItem(SubmenuType, ContextMenuItemTagSpellingMenu,
     868                contextMenuItemTagSpellingMenu());
     869            createAndAppendSpellingAndGrammarSubMenu(SpellingAndGrammarMenuItem);
     870            appendItem(SpellingAndGrammarMenuItem, m_contextMenu.get());
     871#endif
     872#else
     873            ContextMenuItem SpellingMenuItem(SubmenuType, ContextMenuItemTagSpellingMenu,
     874                contextMenuItemTagSpellingMenu());
     875            createAndAppendSpellingSubMenu(SpellingMenuItem);
     876            appendItem(SpellingMenuItem, m_contextMenu.get());
     877#endif
     878#if PLATFORM(MAC) && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
     879            ContextMenuItem substitutionsMenuItem(SubmenuType, ContextMenuItemTagSubstitutionsMenu,
     880                contextMenuItemTagSubstitutionsMenu());
     881            createAndAppendSubstitutionsSubMenu(substitutionsMenuItem);
     882            appendItem(substitutionsMenuItem, m_contextMenu.get());
     883            ContextMenuItem transformationsMenuItem(SubmenuType, ContextMenuItemTagTransformationsMenu,
     884                contextMenuItemTagTransformationsMenu());
     885            createAndAppendTransformationsSubMenu(transformationsMenuItem);
     886            appendItem(transformationsMenuItem, m_contextMenu.get());
     887#endif
     888#if PLATFORM(GTK)
     889            bool shouldShowFontMenu = frame->editor()->canEditRichly();
     890#else
     891            bool shouldShowFontMenu = true;
     892#endif
     893            if (shouldShowFontMenu) {
     894                ContextMenuItem FontMenuItem(SubmenuType, ContextMenuItemTagFontMenu,
     895                    contextMenuItemTagFontMenu());
     896                createAndAppendFontSubMenu(FontMenuItem);
     897                appendItem(FontMenuItem, m_contextMenu.get());
     898            }
     899#if PLATFORM(MAC)
     900            ContextMenuItem SpeechMenuItem(SubmenuType, ContextMenuItemTagSpeechMenu, contextMenuItemTagSpeechMenu());
     901            createAndAppendSpeechSubMenu(SpeechMenuItem);
     902            appendItem(SpeechMenuItem, m_contextMenu.get());
     903#endif
     904#if !PLATFORM(GTK)
     905            ContextMenuItem WritingDirectionMenuItem(SubmenuType, ContextMenuItemTagWritingDirectionMenu,
     906                contextMenuItemTagWritingDirectionMenu());
     907            createAndAppendWritingDirectionSubMenu(WritingDirectionMenuItem);
     908            appendItem(WritingDirectionMenuItem, m_contextMenu.get());
     909            if (Page* page = frame->page()) {
     910                if (Settings* settings = page->settings()) {
     911                    bool includeTextDirectionSubmenu = settings->textDirectionSubmenuInclusionBehavior() == TextDirectionSubmenuAlwaysIncluded
     912                        || (settings->textDirectionSubmenuInclusionBehavior() == TextDirectionSubmenuAutomaticallyIncluded && frame->editor()->hasBidiSelection());
     913                    if (includeTextDirectionSubmenu) {
     914                        ContextMenuItem TextDirectionMenuItem(SubmenuType, ContextMenuItemTagTextDirectionMenu,
     915                            contextMenuItemTagTextDirectionMenu());
     916                        createAndAppendTextDirectionSubMenu(TextDirectionMenuItem);
     917                        appendItem(TextDirectionMenuItem, m_contextMenu.get());
     918                    }
     919                }
     920            }
     921#endif
     922        }
     923    }
     924}
     925
     926#if ENABLE(INSPECTOR)
     927void ContextMenuController::addInspectElementItem()
     928{
     929    Node* node = m_hitTestResult.innerNonSharedNode();
     930    if (!node)
     931        return;
     932
     933    Frame* frame = node->document()->frame();
     934    if (!frame)
     935        return;
     936
     937    Page* page = frame->page();
     938    if (!page)
     939        return;
     940
     941    if (!page->inspectorController())
     942        return;
     943
     944    ContextMenuItem InspectElementItem(ActionType, ContextMenuItemTagInspectElement, contextMenuItemTagInspectElement());
     945    appendItem(*separatorItem(), m_contextMenu.get());
     946    appendItem(InspectElementItem, m_contextMenu.get());
     947}
     948#endif // ENABLE(INSPECTOR)
     949
     950void ContextMenuController::checkOrEnableIfNeeded(ContextMenuItem& item) const
     951{
     952    if (item.type() == SeparatorType)
     953        return;
     954   
     955    Frame* frame = m_hitTestResult.innerNonSharedNode()->document()->frame();
     956    if (!frame)
     957        return;
     958
     959    // Custom items already have proper checked and enabled values.
     960    if (ContextMenuItemBaseCustomTag <= item.action() && item.action() <= ContextMenuItemLastCustomTag)
     961        return;
     962
     963    bool shouldEnable = true;
     964    bool shouldCheck = false;
     965
     966    switch (item.action()) {
     967        case ContextMenuItemTagCheckSpelling:
     968            shouldEnable = frame->editor()->canEdit();
     969            break;
     970        case ContextMenuItemTagDefaultDirection:
     971            shouldCheck = false;
     972            shouldEnable = false;
     973            break;
     974        case ContextMenuItemTagLeftToRight:
     975        case ContextMenuItemTagRightToLeft: {
     976            ExceptionCode ec = 0;
     977            RefPtr<CSSStyleDeclaration> style = frame->document()->createCSSStyleDeclaration();
     978            String direction = item.action() == ContextMenuItemTagLeftToRight ? "ltr" : "rtl";
     979            style->setProperty(CSSPropertyDirection, direction, false, ec);
     980            shouldCheck = frame->editor()->selectionHasStyle(style.get()) != FalseTriState;
     981            shouldEnable = true;
     982            break;
     983        }
     984        case ContextMenuItemTagTextDirectionDefault: {
     985            Editor::Command command = frame->editor()->command("MakeTextWritingDirectionNatural");
     986            shouldCheck = command.state() == TrueTriState;
     987            shouldEnable = command.isEnabled();
     988            break;
     989        }
     990        case ContextMenuItemTagTextDirectionLeftToRight: {
     991            Editor::Command command = frame->editor()->command("MakeTextWritingDirectionLeftToRight");
     992            shouldCheck = command.state() == TrueTriState;
     993            shouldEnable = command.isEnabled();
     994            break;
     995        }
     996        case ContextMenuItemTagTextDirectionRightToLeft: {
     997            Editor::Command command = frame->editor()->command("MakeTextWritingDirectionRightToLeft");
     998            shouldCheck = command.state() == TrueTriState;
     999            shouldEnable = command.isEnabled();
     1000            break;
     1001        }
     1002        case ContextMenuItemTagCopy:
     1003            shouldEnable = frame->editor()->canDHTMLCopy() || frame->editor()->canCopy();
     1004            break;
     1005        case ContextMenuItemTagCut:
     1006            shouldEnable = frame->editor()->canDHTMLCut() || frame->editor()->canCut();
     1007            break;
     1008        case ContextMenuItemTagIgnoreSpelling:
     1009        case ContextMenuItemTagLearnSpelling:
     1010            shouldEnable = frame->selection()->isRange();
     1011            break;
     1012        case ContextMenuItemTagPaste:
     1013            shouldEnable = frame->editor()->canDHTMLPaste() || frame->editor()->canPaste();
     1014            break;
     1015#if PLATFORM(GTK)
     1016        case ContextMenuItemTagDelete:
     1017            shouldEnable = frame->editor()->canDelete();
     1018            break;
     1019        case ContextMenuItemTagSelectAll:
     1020        case ContextMenuItemTagInputMethods:
     1021        case ContextMenuItemTagUnicode:
     1022            shouldEnable = true;
     1023            break;
     1024#endif
     1025        case ContextMenuItemTagUnderline: {
     1026            ExceptionCode ec = 0;
     1027            RefPtr<CSSStyleDeclaration> style = frame->document()->createCSSStyleDeclaration();
     1028            style->setProperty(CSSPropertyWebkitTextDecorationsInEffect, "underline", false, ec);
     1029            shouldCheck = frame->editor()->selectionHasStyle(style.get()) != FalseTriState;
     1030            shouldEnable = frame->editor()->canEditRichly();
     1031            break;
     1032        }
     1033        case ContextMenuItemTagLookUpInDictionary:
     1034            shouldEnable = frame->selection()->isRange();
     1035            break;
     1036        case ContextMenuItemTagCheckGrammarWithSpelling:
     1037#ifndef BUILDING_ON_TIGER
     1038            if (frame->editor()->isGrammarCheckingEnabled())
     1039                shouldCheck = true;
     1040            shouldEnable = true;
     1041#endif
     1042            break;
     1043        case ContextMenuItemTagItalic: {
     1044            ExceptionCode ec = 0;
     1045            RefPtr<CSSStyleDeclaration> style = frame->document()->createCSSStyleDeclaration();
     1046            style->setProperty(CSSPropertyFontStyle, "italic", false, ec);
     1047            shouldCheck = frame->editor()->selectionHasStyle(style.get()) != FalseTriState;
     1048            shouldEnable = frame->editor()->canEditRichly();
     1049            break;
     1050        }
     1051        case ContextMenuItemTagBold: {
     1052            ExceptionCode ec = 0;
     1053            RefPtr<CSSStyleDeclaration> style = frame->document()->createCSSStyleDeclaration();
     1054            style->setProperty(CSSPropertyFontWeight, "bold", false, ec);
     1055            shouldCheck = frame->editor()->selectionHasStyle(style.get()) != FalseTriState;
     1056            shouldEnable = frame->editor()->canEditRichly();
     1057            break;
     1058        }
     1059        case ContextMenuItemTagOutline:
     1060            shouldEnable = false;
     1061            break;
     1062        case ContextMenuItemTagShowSpellingPanel:
     1063#ifndef BUILDING_ON_TIGER
     1064            if (frame->editor()->spellingPanelIsShowing())
     1065                item.setTitle(contextMenuItemTagShowSpellingPanel(false));
     1066            else
     1067                item.setTitle(contextMenuItemTagShowSpellingPanel(true));
     1068#endif
     1069            shouldEnable = frame->editor()->canEdit();
     1070            break;
     1071        case ContextMenuItemTagNoGuessesFound:
     1072            shouldEnable = false;
     1073            break;
     1074        case ContextMenuItemTagCheckSpellingWhileTyping:
     1075            shouldCheck = frame->editor()->isContinuousSpellCheckingEnabled();
     1076            break;
     1077#if PLATFORM(MAC)
     1078        case ContextMenuItemTagSubstitutionsMenu:
     1079        case ContextMenuItemTagTransformationsMenu:
     1080            break;
     1081        case ContextMenuItemTagShowSubstitutions:
     1082#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
     1083            if (frame->editor()->substitutionsPanelIsShowing())
     1084                item.setTitle(contextMenuItemTagShowSubstitutions(false));
     1085            else
     1086                item.setTitle(contextMenuItemTagShowSubstitutions(true));
     1087            shouldEnable = frame->editor()->canEdit();
     1088#endif
     1089            break;
     1090        case ContextMenuItemTagMakeUpperCase:
     1091        case ContextMenuItemTagMakeLowerCase:
     1092        case ContextMenuItemTagCapitalize:
     1093        case ContextMenuItemTagChangeBack:
     1094            shouldEnable = frame->editor()->canEdit();
     1095            break;
     1096        case ContextMenuItemTagCorrectSpellingAutomatically:
     1097#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
     1098            shouldCheck = frame->editor()->isAutomaticSpellingCorrectionEnabled();
     1099#endif
     1100            break;
     1101        case ContextMenuItemTagSmartCopyPaste:
     1102#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
     1103            shouldCheck = frame->editor()->smartInsertDeleteEnabled();
     1104#endif
     1105            break;
     1106        case ContextMenuItemTagSmartQuotes:
     1107#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
     1108            shouldCheck = frame->editor()->isAutomaticQuoteSubstitutionEnabled();
     1109#endif
     1110            break;
     1111        case ContextMenuItemTagSmartDashes:
     1112#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
     1113            shouldCheck = frame->editor()->isAutomaticDashSubstitutionEnabled();
     1114#endif
     1115            break;
     1116        case ContextMenuItemTagSmartLinks:
     1117#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
     1118            shouldCheck = frame->editor()->isAutomaticLinkDetectionEnabled();
     1119#endif
     1120            break;
     1121        case ContextMenuItemTagTextReplacement:
     1122#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
     1123            shouldCheck = frame->editor()->isAutomaticTextReplacementEnabled();
     1124#endif
     1125            break;
     1126        case ContextMenuItemTagStopSpeaking:
     1127            shouldEnable = client() && client()->isSpeaking();
     1128            break;
     1129#else // PLATFORM(MAC) ends here
     1130        case ContextMenuItemTagStopSpeaking:
     1131            break;
     1132#endif
     1133#if PLATFORM(GTK)
     1134        case ContextMenuItemTagGoBack:
     1135            shouldEnable = frame->page() && frame->page()->backForward()->canGoBackOrForward(-1);
     1136            break;
     1137        case ContextMenuItemTagGoForward:
     1138            shouldEnable = frame->page() && frame->page()->backForward()->canGoBackOrForward(1);
     1139            break;
     1140        case ContextMenuItemTagStop:
     1141            shouldEnable = frame->loader()->documentLoader()->isLoadingInAPISense();
     1142            break;
     1143        case ContextMenuItemTagReload:
     1144            shouldEnable = !frame->loader()->documentLoader()->isLoadingInAPISense();
     1145            break;
     1146        case ContextMenuItemTagFontMenu:
     1147            shouldEnable = frame->editor()->canEditRichly();
     1148            break;
     1149#else
     1150        case ContextMenuItemTagGoBack:
     1151        case ContextMenuItemTagGoForward:
     1152        case ContextMenuItemTagStop:
     1153        case ContextMenuItemTagReload:
     1154        case ContextMenuItemTagFontMenu:
     1155#endif
     1156        case ContextMenuItemTagNoAction:
     1157        case ContextMenuItemTagOpenLinkInNewWindow:
     1158        case ContextMenuItemTagDownloadLinkToDisk:
     1159        case ContextMenuItemTagCopyLinkToClipboard:
     1160        case ContextMenuItemTagOpenImageInNewWindow:
     1161        case ContextMenuItemTagDownloadImageToDisk:
     1162        case ContextMenuItemTagCopyImageToClipboard:
     1163            break;
     1164        case ContextMenuItemTagOpenMediaInNewWindow:
     1165            if (m_hitTestResult.mediaIsVideo())
     1166                item.setTitle(contextMenuItemTagOpenVideoInNewWindow());
     1167            else
     1168                item.setTitle(contextMenuItemTagOpenAudioInNewWindow());
     1169            break;
     1170        case ContextMenuItemTagCopyMediaLinkToClipboard:
     1171            if (m_hitTestResult.mediaIsVideo())
     1172                item.setTitle(contextMenuItemTagCopyVideoLinkToClipboard());
     1173            else
     1174                item.setTitle(contextMenuItemTagCopyAudioLinkToClipboard());
     1175            break;
     1176        case ContextMenuItemTagToggleMediaControls:
     1177            shouldCheck = m_hitTestResult.mediaControlsEnabled();
     1178            break;
     1179        case ContextMenuItemTagToggleMediaLoop:
     1180            shouldCheck = m_hitTestResult.mediaLoopEnabled();
     1181            break;
     1182        case ContextMenuItemTagEnterVideoFullscreen:
     1183            shouldEnable = m_hitTestResult.mediaSupportsFullscreen();
     1184            break;
     1185        case ContextMenuItemTagOpenFrameInNewWindow:
     1186        case ContextMenuItemTagSpellingGuess:
     1187        case ContextMenuItemTagOther:
     1188        case ContextMenuItemTagSearchInSpotlight:
     1189        case ContextMenuItemTagSearchWeb:
     1190        case ContextMenuItemTagOpenWithDefaultApplication:
     1191        case ContextMenuItemPDFActualSize:
     1192        case ContextMenuItemPDFZoomIn:
     1193        case ContextMenuItemPDFZoomOut:
     1194        case ContextMenuItemPDFAutoSize:
     1195        case ContextMenuItemPDFSinglePage:
     1196        case ContextMenuItemPDFFacingPages:
     1197        case ContextMenuItemPDFContinuous:
     1198        case ContextMenuItemPDFNextPage:
     1199        case ContextMenuItemPDFPreviousPage:
     1200        case ContextMenuItemTagOpenLink:
     1201        case ContextMenuItemTagIgnoreGrammar:
     1202        case ContextMenuItemTagSpellingMenu:
     1203        case ContextMenuItemTagShowFonts:
     1204        case ContextMenuItemTagStyles:
     1205        case ContextMenuItemTagShowColors:
     1206        case ContextMenuItemTagSpeechMenu:
     1207        case ContextMenuItemTagStartSpeaking:
     1208        case ContextMenuItemTagWritingDirectionMenu:
     1209        case ContextMenuItemTagTextDirectionMenu:
     1210        case ContextMenuItemTagPDFSinglePageScrolling:
     1211        case ContextMenuItemTagPDFFacingPagesScrolling:
     1212#if ENABLE(INSPECTOR)
     1213        case ContextMenuItemTagInspectElement:
     1214#endif
     1215        case ContextMenuItemBaseCustomTag:
     1216        case ContextMenuItemCustomTagNoAction:
     1217        case ContextMenuItemLastCustomTag:
     1218        case ContextMenuItemBaseApplicationTag:
     1219            break;
     1220        case ContextMenuItemTagMediaPlayPause:
     1221            if (m_hitTestResult.mediaPlaying())
     1222                item.setTitle(contextMenuItemTagMediaPause());
     1223            else
     1224                item.setTitle(contextMenuItemTagMediaPlay());
     1225            break;
     1226        case ContextMenuItemTagMediaMute:
     1227            shouldEnable = m_hitTestResult.mediaHasAudio();
     1228            shouldCheck = shouldEnable &&  m_hitTestResult.mediaMuted();
     1229            break;
     1230    }
     1231
     1232    item.setChecked(shouldCheck);
     1233    item.setEnabled(shouldEnable);
     1234}
     1235
    4021236} // namespace WebCore
    4031237
  • trunk/WebCore/page/ContextMenuController.h

    r51993 r73535  
    2727#define ContextMenuController_h
    2828
     29#include "HitTestResult.h"
    2930#include <wtf/Noncopyable.h>
    3031#include <wtf/OwnPtr.h>
     
    4647        ~ContextMenuController();
    4748
    48         ContextMenuClient* client() { return m_client; }
     49        ContextMenuClient* client() const { return m_client; }
    4950
    5051        ContextMenu* contextMenu() const { return m_contextMenu.get(); }
     
    5455        void showContextMenu(Event*, PassRefPtr<ContextMenuProvider>);
    5556
     57        void populate();
    5658        void contextMenuItemSelected(ContextMenuItem*);
     59        void addInspectElementItem();
     60
     61        void checkOrEnableIfNeeded(ContextMenuItem&) const;
     62
     63        void setHitTestResult(const HitTestResult& result) { m_hitTestResult = result; }
     64        const HitTestResult& hitTestResult() { return m_hitTestResult; }
    5765
    5866    private:
    59         ContextMenu* createContextMenu(Event*);
     67        PassOwnPtr<ContextMenu> createContextMenu(Event*);
    6068        void showContextMenu(Event*);
     69       
     70        void appendItem(ContextMenuItem&, ContextMenu* parentMenu);
     71
     72        void createAndAppendFontSubMenu(ContextMenuItem&);
     73        void createAndAppendSpellingAndGrammarSubMenu(ContextMenuItem&);
     74        void createAndAppendSpellingSubMenu(ContextMenuItem&);
     75        void createAndAppendSpeechSubMenu(ContextMenuItem& );
     76        void createAndAppendWritingDirectionSubMenu(ContextMenuItem&);
     77        void createAndAppendTextDirectionSubMenu(ContextMenuItem&);
     78        void createAndAppendSubstitutionsSubMenu(ContextMenuItem&);
     79        void createAndAppendTransformationsSubMenu(ContextMenuItem&);
    6180
    6281        Page* m_page;
     
    6483        OwnPtr<ContextMenu> m_contextMenu;
    6584        RefPtr<ContextMenuProvider> m_menuProvider;
     85        HitTestResult m_hitTestResult;
    6686    };
    6787
  • trunk/WebCore/platform/ContextMenu.h

    r72585 r73535  
    3030
    3131#include "ContextMenuItem.h"
    32 #include "HitTestResult.h"
    3332#include "PlatformMenuDescription.h"
    3433#include "PlatformString.h"
     
    4948    {
    5049    public:
    51         ContextMenu(const HitTestResult&);
    52         ContextMenu(const HitTestResult&, const PlatformMenuDescription);
     50        ContextMenu();
     51        ContextMenu(const PlatformMenuDescription);
    5352        ~ContextMenu();
    54 
    55         void populate();
    56         void addInspectElementItem();
    57         void checkOrEnableIfNeeded(ContextMenuItem&) const;
    5853
    5954        void insertItem(unsigned position, ContextMenuItem&);
     
    6560        unsigned itemCount() const;
    6661
    67         HitTestResult hitTestResult() const { return m_hitTestResult; }
    68         ContextMenuController* controller() const;
    69 
    7062        PlatformMenuDescription platformDescription() const;
    7163        void setPlatformDescription(PlatformMenuDescription);
     
    7668#endif
    7769    private:
    78         HitTestResult m_hitTestResult;
    7970#if PLATFORM(MAC)
    8071        // Keep this in sync with the PlatformMenuDescription typedef
  • trunk/WebCore/platform/android/TemporaryLinkStubs.cpp

    r71484 r73535  
    168168
    169169
    170 ContextMenu::ContextMenu(const HitTestResult& result) : m_hitTestResult(result)
     170ContextMenu::ContextMenu()
    171171{
    172172    ASSERT_NOT_REACHED();
  • trunk/WebCore/platform/brew/ContextMenuBrew.cpp

    r60907 r73535  
    3333namespace WebCore {
    3434
    35 ContextMenu::ContextMenu(const HitTestResult& result)
    36     : m_hitTestResult(result)
     35ContextMenu::ContextMenu()
    3736{
    3837    ASSERT_NOT_REACHED();
     
    4039}
    4140
    42 ContextMenu::ContextMenu(const HitTestResult& result, const PlatformMenuDescription menu)
    43     : m_hitTestResult(result)
     41ContextMenu::ContextMenu(const PlatformMenuDescription menu)
    4442{
    4543    ASSERT_NOT_REACHED();
  • trunk/WebCore/platform/chromium/ContextMenuChromium.cpp

    r51874 r73535  
    3737// nothing.
    3838
    39 ContextMenu::ContextMenu(const HitTestResult& result)
    40     : m_hitTestResult(result)
     39ContextMenu::ContextMenu()
    4140{
    4241}
    4342
    44 ContextMenu::ContextMenu(const HitTestResult& result, const PlatformMenuDescription menu)
    45     : m_hitTestResult(result)
     43ContextMenu::ContextMenu(const PlatformMenuDescription menu)
    4644{
    4745}
  • trunk/WebCore/platform/efl/ContextMenuEfl.cpp

    r60454 r73535  
    3030namespace WebCore {
    3131
    32 ContextMenu::ContextMenu(const HitTestResult& result)
    33     : m_hitTestResult(result)
     32ContextMenu::ContextMenu()
    3433{
    35     m_contextMenuClient = static_cast<ContextMenuClientEfl*>(controller()->client());
    36     m_platformDescription = m_contextMenuClient->createPlatformDescription(this);
     34    m_platformDescription = (PlatformMenuDescription) ewk_context_menu_new(m_view, menu->controller());
    3735}
    3836
    39 ContextMenu::ContextMenu(const HitTestResult& result, const PlatformMenuDescription menu)
    40     : m_hitTestResult(result)
    41     , m_platformDescription(menu)
     37ContextMenu::ContextMenu(const PlatformMenuDescription menu)
     38    : m_platformDescription(menu)
    4239{
    43     m_contextMenuClient = static_cast<ContextMenuClientEfl*>(controller()->client());
    4440}
    4541
     
    4743{
    4844    if (m_platformDescription)
    49         m_contextMenuClient->freePlatformDescription(m_platformDescription);
     45        ewk_context_menu_free(static_cast<Ewk_Context_Menu*>(m_platformDescription));
    5046}
    5147
    5248void ContextMenu::appendItem(ContextMenuItem& item)
    5349{
    54     checkOrEnableIfNeeded(item);
    55     m_contextMenuClient->appendItem(m_platformDescription, item);
     50    ewk_context_menu_item_append(static_cast<Ewk_Context_Menu*>(m_platformDescription), item);
    5651}
    5752
     
    6156
    6257    m_platformDescription = menu;
    63     m_contextMenuClient->show(m_platformDescription);
     58    ewk_context_menu_show(static_cast<Ewk_Context_Menu*>(m_platformDescription));
    6459}
    6560
  • trunk/WebCore/platform/efl/ContextMenuItemEfl.cpp

    r60454 r73535  
    117117
    118118    m_platformDescription.type = SubmenuType;
    119     m_platformDescription.subMenu = new ContextMenu(subMenu->hitTestResult(),
    120             subMenu->releasePlatformDescription());
     119    m_platformDescription.subMenu = new ContextMenu(subMenu->releasePlatformDescription());
    121120}
    122121
  • trunk/WebCore/platform/gtk/ContextMenuGtk.cpp

    r73534 r73535  
    2424namespace WebCore {
    2525
    26 ContextMenu::ContextMenu(const HitTestResult& result)
    27     : m_hitTestResult(result)
     26ContextMenu::ContextMenu()
    2827{
    2928    m_platformDescription = GTK_MENU(gtk_menu_new());
     
    4140{
    4241    ASSERT(m_platformDescription);
    43     checkOrEnableIfNeeded(item);
    4442
    4543    GtkMenuItem* platformItem = ContextMenuItem::createNativeMenuItem(item.releasePlatformDescription());
  • trunk/WebCore/platform/haiku/ContextMenuHaiku.cpp

    r47206 r73535  
    7676};
    7777
    78 ContextMenu::ContextMenu(const HitTestResult& result)
    79     : m_hitTestResult(result)
    80     , m_platformDescription(new BMenu("context_menu"))
     78ContextMenu::ContextMenu()
     79    : m_platformDescription(new BMenu("context_menu"))
    8180{
    8281}
     
    8988void ContextMenu::appendItem(ContextMenuItem& item)
    9089{
    91     checkOrEnableIfNeeded(item);
    92 
    9390    BMenuItem* menuItem = item.releasePlatformDescription();
    9491    if (menuItem)
     
    103100void ContextMenu::insertItem(unsigned position, ContextMenuItem& item)
    104101{
    105     checkOrEnableIfNeeded(item);
    106 
    107102    BMenuItem* menuItem = item.releasePlatformDescription();
    108103    if (menuItem)
  • trunk/WebCore/platform/mac/ContextMenuMac.mm

    r73469 r73535  
    3131namespace WebCore {
    3232
    33 ContextMenu::ContextMenu(const HitTestResult& result)
    34     : m_hitTestResult(result)
     33ContextMenu::ContextMenu()
    3534{
    3635    NSMutableArray* array = [[NSMutableArray alloc] init];
     
    3938}
    4039
    41 ContextMenu::ContextMenu(const HitTestResult& result, const PlatformMenuDescription menu)
    42     : m_hitTestResult(result)
    43     , m_platformDescription(menu)
     40ContextMenu::ContextMenu(const PlatformMenuDescription menu)
     41    : m_platformDescription(menu)
    4442{
    4543}
     
    5149void ContextMenu::appendItem(ContextMenuItem& item)
    5250{
    53     checkOrEnableIfNeeded(item);
    54 
    5551    NSMenuItem* platformItem = item.releasePlatformDescription();
    5652
     
    6157void ContextMenu::insertItem(unsigned position, ContextMenuItem& item)
    6258{
    63     checkOrEnableIfNeeded(item);
    64 
    6559    NSMenuItem* platformItem = item.releasePlatformDescription();
    6660
  • trunk/WebCore/platform/qt/ContextMenuQt.cpp

    r71682 r73535  
    3636namespace WebCore {
    3737
    38 ContextMenu::ContextMenu(const HitTestResult& result)
    39     : m_hitTestResult(result)
     38ContextMenu::ContextMenu()
    4039{
    4140}
  • trunk/WebCore/platform/win/ContextMenuWin.cpp

    r72585 r73535  
    4444namespace WebCore {
    4545
    46 ContextMenu::ContextMenu(const HitTestResult& result)
    47     : m_hitTestResult(result)
    48     , m_platformDescription(0)
     46ContextMenu::ContextMenu()
     47    : m_platformDescription(0)
    4948#if OS(WINCE)
    5049    , m_itemCount(0)
     
    5453}
    5554
    56 ContextMenu::ContextMenu(const HitTestResult& result, const PlatformMenuDescription menu)
    57     : m_hitTestResult(result)
    58     , m_platformDescription(0)
     55ContextMenu::ContextMenu(const PlatformMenuDescription menu)
     56    : m_platformDescription(0)
    5957#if OS(WINCE)
    6058    , m_itemCount(0)
     
    118116    if (!m_platformDescription)
    119117        return;
    120 
    121     checkOrEnableIfNeeded(item);
    122118
    123119#if OS(WINCE)
  • trunk/WebCore/platform/wx/ContextMenuWx.cpp

    r52420 r73535  
    4343}
    4444
    45 ContextMenu::ContextMenu(const HitTestResult& result) : m_hitTestResult(result)
     45ContextMenu::ContextMenu()
    4646{
    4747    m_platformDescription = new wxMenu(0);
     
    5858    if (!m_platformDescription)
    5959        return;
    60    
    61     checkOrEnableIfNeeded(item);
    6260       
    6361    PlatformMenuItemDescription itemDescription = item.releasePlatformDescription();   
  • trunk/WebCore/rendering/HitTestResult.cpp

    r69192 r73535  
    4949using namespace HTMLNames;
    5050
     51HitTestResult::HitTestResult()
     52    : m_isOverWidget(false)
     53    , m_isRectBased(false)
     54    , m_topPadding(0)
     55    , m_rightPadding(0)
     56    , m_bottomPadding(0)
     57    , m_leftPadding(0)
     58{
     59}
     60
    5161HitTestResult::HitTestResult(const IntPoint& point)
    5262    : m_point(point)
  • trunk/WebCore/rendering/HitTestResult.h

    r69192 r73535  
    4444class HitTestResult {
    4545public:
     46    HitTestResult();
    4647    HitTestResult(const IntPoint&);
    4748    // Pass non-negative padding values to perform a rect-based hit test.
  • trunk/WebKit/chromium/ChangeLog

    r73444 r73535  
     12010-12-07  Brian Weinstein  <bweinstein@apple.com>
     2
     3        Reviewed by John Sullivan.
     4
     5        Layering Violation in ContextMenu - member variable of type HitTestResult
     6        https://bugs.webkit.org/show_bug.cgi?id=50586
     7       
     8        Update users of ContextMenu and ContextMenuController to match where the new functions
     9        are located.
     10
     11        * src/ContextMenuClientImpl.cpp:
     12        (WebKit::selectMisspelledWord):
     13        (WebKit::ContextMenuClientImpl::getCustomMenuFromDefaultItems):
     14
    1152010-12-06  Darin Adler  <darin@apple.com>
    216
  • trunk/WebKit/chromium/src/ContextMenuClientImpl.cpp

    r73436 r73535  
    3535#include "CSSStyleDeclaration.h"
    3636#include "ContextMenu.h"
     37#include "ContextMenuController.h"
    3738#include "Document.h"
    3839#include "DocumentLoader.h"
     
    4647#include "KURL.h"
    4748#include "MediaError.h"
     49#include "Page.h"
    4850#include "PlatformString.h"
    4951#include "RenderWidget.h"
     
    111113    // Selection is empty, so change the selection to the word under the cursor.
    112114    HitTestResult hitTestResult = selectedFrame->eventHandler()->
    113         hitTestResultAtPoint(defaultMenu->hitTestResult().point(), true);
     115        hitTestResultAtPoint(selectedFrame->page()->contextMenuController()->hitTestResult().point(), true);
    114116    Node* innerNode = hitTestResult.innerNode();
    115117    VisiblePosition pos(innerNode->renderer()->positionForPoint(
     
    145147        return 0;
    146148
    147     HitTestResult r = defaultMenu->hitTestResult();
     149    HitTestResult r = m_webView->page()->contextMenuController()->hitTestResult();
    148150    Frame* selectedFrame = r.innerNonSharedNode()->document()->frame();
    149151
  • trunk/WebKit/gtk/ChangeLog

    r73534 r73535  
     12010-12-08  Brian Weinstein  <bweinstein@apple.com>
     2
     3        Reviewed by John Sullivan.
     4
     5        Layering Violation in ContextMenu - member variable of type HitTestResult
     6        https://bugs.webkit.org/show_bug.cgi?id=50586
     7       
     8        Update users of ContextMenu and ContextMenuController to match where the new functions
     9        are located.
     10
     11        * WebCoreSupport/ContextMenuClientGtk.cpp:
     12        (WebKit::ContextMenuClient::getCustomMenuFromDefaultItems):
     13
    1142010-12-08  Martin Robinson  <mrobinson@igalia.com>
    215
  • trunk/WebKit/gtk/WebCoreSupport/ContextMenuClientGtk.cpp

    r67591 r73535  
    2121#include "ContextMenu.h"
    2222#include "ContextMenuClientGtk.h"
     23#include "ContextMenuController.h"
    2324
    2425#include "HitTestResult.h"
    2526#include "KURL.h"
    2627#include "NotImplemented.h"
     28#include "Page.h"
    2729#include <wtf/text/CString.h>
    2830
     
    130132    GtkMenu* gtkmenu = menu->releasePlatformDescription();
    131133
    132     HitTestResult result = menu->hitTestResult();
    133134    WebKitWebView* webView = m_webView;
     135    HitTestResult result = core(webView)->contextMenuController()->hitTestResult();
    134136
    135137    if (result.isContentEditable()) {
  • trunk/WebKit/mac/ChangeLog

    r73469 r73535  
     12010-12-07  Brian Weinstein  <bweinstein@apple.com>
     2
     3        Reviewed by John Sullivan.
     4
     5        Layering Violation in ContextMenu - member variable of type HitTestResult
     6        https://bugs.webkit.org/show_bug.cgi?id=50586
     7       
     8        Update users of ContextMenu and ContextMenuController to match where the new functions
     9        are located.
     10
     11        * WebCoreSupport/WebContextMenuClient.mm:
     12        (WebContextMenuClient::getCustomMenuFromDefaultItems):
     13        (WebContextMenuClient::contextMenuItemSelected):
     14        * WebView/WebHTMLView.mm:
     15        (-[WebMenuTarget validateMenuItem:]):
     16
    1172010-12-07  Brian Weinstein  <bweinstein@apple.com>
    218
  • trunk/WebKit/mac/WebCoreSupport/WebContextMenuClient.mm

    r63904 r73535  
    4343#import "WebViewInternal.h"
    4444#import <WebCore/ContextMenu.h>
     45#import <WebCore/ContextMenuController.h>
    4546#import <WebCore/KURL.h>
    4647#import <WebCore/LocalizedStrings.h>
     48#import <WebCore/Page.h>
    4749#import <WebCore/RuntimeApplicationChecks.h>
    4850#import <WebKit/DOMPrivate.h>
     
    279281        return defaultMenu->platformDescription();
    280282
    281     NSDictionary *element = [[[WebElementDictionary alloc] initWithHitTestResult:defaultMenu->hitTestResult()] autorelease];
     283    NSDictionary *element = [[[WebElementDictionary alloc] initWithHitTestResult:[m_webView page]->contextMenuController()->hitTestResult()] autorelease];
    282284
    283285    BOOL preVersion3Client = isPreVersion3Client();
     
    309311    SEL selector = @selector(webView:contextMenuItemSelected:forElement:);
    310312    if ([delegate respondsToSelector:selector]) {
    311         NSDictionary *element = [[WebElementDictionary alloc] initWithHitTestResult:parentMenu->hitTestResult()];
     313        NSDictionary *element = [[WebElementDictionary alloc] initWithHitTestResult:[m_webView page]->contextMenuController()->hitTestResult()];
    312314        NSMenuItem *platformItem = item->releasePlatformDescription();
    313315
  • trunk/WebKit/mac/WebView/WebHTMLView.mm

    r73469 r73535  
    171171    WebCore::ContextMenuItem coreItem(item);
    172172    ASSERT(_menuController->contextMenu());
    173     _menuController->contextMenu()->checkOrEnableIfNeeded(coreItem);
     173    _menuController->checkOrEnableIfNeeded(coreItem);
    174174    return coreItem.enabled();
    175175}
  • trunk/WebKit/qt/Api/qwebpage.cpp

    r73445 r73535  
    444444                if (a) {
    445445                    ContextMenuItem it(item);
    446                     webcoreMenu->checkOrEnableIfNeeded(it);
     446                    page->contextMenuController()->checkOrEnableIfNeeded(it);
    447447                    PlatformMenuItemDescription desc = it.releasePlatformDescription();
    448448                    a->setEnabled(desc.enabled);
     
    32103210    else
    32113211        d->hitTestResult = QWebHitTestResult(new QWebHitTestResultPrivate(result));
    3212     WebCore::ContextMenu menu(result);
    3213     menu.populate();
     3212
     3213    d->page->contextMenuController()->setHitTestResult(result);
     3214    d->page->contextMenuController()->populate();
    32143215   
    32153216#if ENABLE(INSPECTOR)
    32163217    if (d->page->inspectorController()->enabled())
    3217         menu.addInspectElementItem();
     3218        d->page->contextMenuController()->addInspectElementItem();
    32183219#endif
    32193220
     
    32243225
    32253226    // Then we let createContextMenu() enable the actions that are put into the menu
    3226     d->currentContextMenu = d->createContextMenu(&menu, menu.platformDescription(), &visitedWebActions);
     3227    d->currentContextMenu = d->createContextMenu(d->page->contextMenuController()->contextMenu(), d->page->contextMenuController()->contextMenu()->platformDescription(), &visitedWebActions);
    32273228#endif // QT_NO_CONTEXTMENU
    32283229
  • trunk/WebKit/qt/ChangeLog

    r73445 r73535  
     12010-12-07  Brian Weinstein  <bweinstein@apple.com>
     2
     3        Reviewed by John Sullivan.
     4
     5        Layering Violation in ContextMenu - member variable of type HitTestResult
     6        https://bugs.webkit.org/show_bug.cgi?id=50586
     7       
     8        Update users of ContextMenu and ContextMenuController to match where the new functions
     9        are located.
     10
     11        * Api/qwebpage.cpp:
     12        (QWebPagePrivate::createContextMenu):
     13        (QWebPage::updatePositionDependentActions):
     14
    1152010-12-07  Darin Adler  <darin@apple.com>
    216
  • trunk/WebKit/win/ChangeLog

    r73448 r73535  
     12010-12-07  Brian Weinstein  <bweinstein@apple.com>
     2
     3        Reviewed by John Sullivan.
     4
     5        Layering Violation in ContextMenu - member variable of type HitTestResult
     6        https://bugs.webkit.org/show_bug.cgi?id=50586
     7       
     8        Update users of ContextMenu and ContextMenuController to match where the new functions
     9        are located.
     10
     11        * WebCoreSupport/WebContextMenuClient.cpp:
     12        (WebContextMenuClient::getCustomMenuFromDefaultItems): Get the HitTestResult and ContextMenu from the
     13            ContextMenuController (from the page).
     14        (WebContextMenuClient::contextMenuItemSelected): Get the HitTestResult from the ContextMenuController.
     15        * WebView.cpp:
     16        (WebView::handleContextMenuEvent): Ditto.
     17
    1182010-12-07  Jessie Berlin  <jberlin@apple.com>
    219
  • trunk/WebKit/win/WebCoreSupport/WebContextMenuClient.cpp

    r73448 r73535  
    3333
    3434#include <WebCore/ContextMenu.h>
     35#include <WebCore/ContextMenuController.h>
    3536#include <WebCore/Event.h>
    3637#include <WebCore/Frame.h>
     
    6566    HMENU newMenu = 0;
    6667    COMPtr<WebElementPropertyBag> propertyBag;
    67     propertyBag.adoptRef(WebElementPropertyBag::createInstance(menu->hitTestResult()));
     68    propertyBag.adoptRef(WebElementPropertyBag::createInstance(m_webView->page()->contextMenuController()->hitTestResult()));
    6869    // FIXME: We need to decide whether to do the default before calling this delegate method
    6970    if (FAILED(uiDelegate->contextMenuItemsForElement(m_webView, propertyBag.get(), (OLE_HANDLE)(ULONG64)menu->platformDescription(), (OLE_HANDLE*)&newMenu)))
     
    8384
    8485    COMPtr<WebElementPropertyBag> propertyBag;
    85     propertyBag.adoptRef(WebElementPropertyBag::createInstance(parentMenu->hitTestResult()));
     86    propertyBag.adoptRef(WebElementPropertyBag::createInstance(m_webView->page()->contextMenuController()->hitTestResult()));
    8687           
    8788    uiDelegate->contextMenuItemSelected(m_webView, item->releasePlatformDescription(), propertyBag.get());
  • trunk/WebKit/win/WebView.cpp

    r71903 r73535  
    12461246        return false;
    12471247
     1248    ContextMenuController* contextMenuController = m_page->contextMenuController();
     1249
    12481250    // Show the menu
    1249     ContextMenu* coreMenu = m_page->contextMenuController()->contextMenu();
     1251    ContextMenu* coreMenu = contextMenuController->contextMenu();
    12501252    if (!coreMenu)
    12511253        return false;
    12521254
    1253     Node* node = coreMenu->hitTestResult().innerNonSharedNode();
     1255    Node* node = contextMenuController->hitTestResult().innerNonSharedNode();
    12541256    if (!node)
    12551257        return false;
     
    12631265        return false;
    12641266
    1265     POINT point(view->contentsToWindow(coreMenu->hitTestResult().point()));
     1267    POINT point(view->contentsToWindow(contextMenuController->hitTestResult().point()));
    12661268
    12671269    // Translate the point to screen coordinates
  • trunk/WebKit2/ChangeLog

    r73533 r73535  
     12010-12-07  Brian Weinstein  <bweinstein@apple.com>
     2
     3        Reviewed by John Sullivan.
     4
     5        Layering Violation in ContextMenu - member variable of type HitTestResult
     6        https://bugs.webkit.org/show_bug.cgi?id=50586
     7       
     8        Update users of ContextMenu and ContextMenuController to match where the new functions
     9        are located.
     10
     11        * Shared/WebContextMenuItemData.cpp:
     12        (WebKit::WebContextMenuItemData::WebContextMenuItemData): Remove the call to checkOrEnableItem, that call will be made when
     13            the ContextMenuItem is added to the ContextMenu through the ContextMenuController.
     14        * WebProcess/WebPage/WebContextMenu.cpp:
     15        (WebKit::WebContextMenu::show):
     16
    1172010-12-08  Jessie Berlin  <jberlin@apple.com>
    218
  • trunk/WebKit2/Shared/WebContextMenuItemData.cpp

    r72707 r73535  
    7373        m_submenu = kitItems(coreSubmenu, menu);
    7474    }
    75    
    76     menu->checkOrEnableIfNeeded(item);
    7775   
    7876    m_enabled = item.enabled();
  • trunk/WebKit2/WebProcess/WebPage/WebContextMenu.cpp

    r72446 r73535  
    4848void WebContextMenu::show()
    4949{
    50     ContextMenu* menu = m_page->corePage()->contextMenuController()->contextMenu();
     50    ContextMenuController* controller = m_page->corePage()->contextMenuController();
     51    if (!controller)
     52        return;
     53    ContextMenu* menu = controller->contextMenu();
    5154    if (!menu)
    5255        return;
    53     Node* node = menu->hitTestResult().innerNonSharedNode();
     56    Node* node = controller->hitTestResult().innerNonSharedNode();
    5457    if (!node)
    5558        return;
     
    6669    Vector<WebContextMenuItemData> newMenu;
    6770    RefPtr<APIObject> userData;
    68     RefPtr<InjectedBundleHitTestResult> hitTestResult = InjectedBundleHitTestResult::create(menu->hitTestResult());
     71    RefPtr<InjectedBundleHitTestResult> hitTestResult = InjectedBundleHitTestResult::create(controller->hitTestResult());
    6972    if (m_page->injectedBundleContextMenuClient().getCustomMenuFromDefaultItems(m_page, hitTestResult.get(), proposedMenu, newMenu, userData))
    7073        proposedMenu = newMenu;
    7174
    7275    // Notify the UIProcess.
    73     m_page->send(Messages::WebPageProxy::ShowContextMenu(view->contentsToWindow(menu->hitTestResult().point()), proposedMenu, InjectedBundleUserMessageEncoder(userData.get())));
     76    m_page->send(Messages::WebPageProxy::ShowContextMenu(view->contentsToWindow(controller->hitTestResult().point()), proposedMenu, InjectedBundleUserMessageEncoder(userData.get())));
    7477}
    7578
Note: See TracChangeset for help on using the changeset viewer.