Пример #1
0
PassRefPtr<HistoryItem> HistoryController::createItem(bool useOriginal)
{
    DocumentLoader* docLoader = m_frame->loader()->documentLoader();
    
    KURL unreachableURL = docLoader ? docLoader->unreachableURL() : KURL();
    
    KURL url;
    KURL originalURL;

    if (!unreachableURL.isEmpty()) {
        url = unreachableURL;
        originalURL = unreachableURL;
    } else {
        originalURL = docLoader ? docLoader->originalURL() : KURL();
        if (useOriginal)
            url = originalURL;
        else if (docLoader)
            url = docLoader->requestURL();
    }

    LOG(History, "WebCoreHistory: Creating item for %s", url.string().ascii().data());
    
    // Frames that have never successfully loaded any content
    // may have no URL at all. Currently our history code can't
    // deal with such things, so we nip that in the bud here.
    // Later we may want to learn to live with nil for URL.
    // See bug 3368236 and related bugs for more information.
    if (url.isEmpty()) 
        url = blankURL();
    if (originalURL.isEmpty())
        originalURL = blankURL();
    
    Frame* parentFrame = m_frame->tree()->parent();
    String parent = parentFrame ? parentFrame->tree()->name() : "";
    String title = docLoader ? docLoader->title() : "";

    RefPtr<HistoryItem> item = HistoryItem::create(url, m_frame->tree()->name(), parent, title);
    item->setOriginalURLString(originalURL.string());

    if (!unreachableURL.isEmpty() || !docLoader || docLoader->response().httpStatusCode() >= 400)
        item->setLastVisitWasFailure(true);

    // Save form state if this is a POST
    if (docLoader) {
        if (useOriginal)
            item->setFormInfoFromRequest(docLoader->originalRequest());
        else
            item->setFormInfoFromRequest(docLoader->request());
    }
    
    // Set the item for which we will save document state
    m_previousItem = m_currentItem;
    m_currentItem = item;
    
    return item.release();
}
void FrameLoaderClientAndroid::updateGlobalHistory() {
    ASSERT(m_frame);

    DocumentLoader* docLoader = m_frame->loader()->documentLoader();
    ASSERT(docLoader);

    // Code copied from FrameLoader.cpp:createHistoryItem
    // Only add this URL to the database if it is a valid page
    if (docLoader->unreachableURL().isEmpty()
            && docLoader->response().httpStatusCode() < 400) {
        m_webFrame->updateVisitedHistory(docLoader->urlForHistory(), false);
        if (!docLoader->serverRedirectSourceForHistory().isNull())
            m_webFrame->updateVisitedHistory(KURL(ParsedURLString, docLoader->serverRedirectDestinationForHistory()), false);
    }
}
Пример #3
0
void HistoryController::initializeItem(HistoryItem* item)
{
    DocumentLoader* documentLoader = m_frame->loader()->documentLoader();
    ASSERT(documentLoader);

    KURL unreachableURL = documentLoader->unreachableURL();

    KURL url;
    KURL originalURL;

    if (!unreachableURL.isEmpty()) {
        url = unreachableURL;
        originalURL = unreachableURL;
    } else {
        url = documentLoader->url();
        originalURL = documentLoader->originalURL();
    }

    // Frames that have never successfully loaded any content
    // may have no URL at all. Currently our history code can't
    // deal with such things, so we nip that in the bud here.
    // Later we may want to learn to live with nil for URL.
    // See bug 3368236 and related bugs for more information.
    if (url.isEmpty()) 
        url = blankURL();
    if (originalURL.isEmpty())
        originalURL = blankURL();
    
    Frame* parentFrame = m_frame->tree()->parent();
    String parent = parentFrame ? parentFrame->tree()->uniqueName() : "";
    StringWithDirection title = documentLoader->title();

    item->setURL(url);
    item->setTarget(m_frame->tree()->uniqueName());
    item->setParent(parent);
    // FIXME: should store title directionality in history as well.
    item->setTitle(title.string());
    item->setOriginalURLString(originalURL.string());

    if (!unreachableURL.isEmpty() || documentLoader->response().httpStatusCode() >= 400)
        item->setLastVisitWasFailure(true);

    // Save form state if this is a POST
    item->setFormInfoFromRequest(documentLoader->request());
}
void WebFrameLoaderClient::updateGlobalHistoryRedirectLinks()
{                                                                                                                                                          
    WebHistory* history = WebHistory::sharedHistory();                                                                                                     
    if (!history)                                                                                                                                          
        return;                                                                                                                                            
    DocumentLoader* loader = core(m_webFrame)->loader()->documentLoader();
    ASSERT(loader->unreachableURL().isEmpty());

    if (!loader->clientRedirectSourceForHistory().isNull()) {
        if (WebHistoryItem *webHistoryItem = history->itemForURLString(loader->clientRedirectSourceForHistory())) {
            webHistoryItem->getPrivateItem()->m_historyItem.get()->addRedirectURL(loader->clientRedirectDestinationForHistory());
        }
    }
                                                                                              
    if (!loader->serverRedirectSourceForHistory().isNull()) {                               
        if (WebHistoryItem *webHistoryItem = history->itemForURLString(loader->serverRedirectSourceForHistory())) {
            webHistoryItem->getPrivateItem()->m_historyItem.get()->addRedirectURL(loader->serverRedirectDestinationForHistory());
        }
    }
}
Пример #5
0
void WebFrameLoaderClient::updateGlobalHistoryRedirectLinks()
{
    WebView* webView = m_webFrame->webView();
    COMPtr<IWebHistoryDelegate> historyDelegate;
    webView->historyDelegate(&historyDelegate);

    WebHistory* history = WebHistory::sharedHistory();

    DocumentLoader* loader = core(m_webFrame)->loader()->documentLoader();
    ASSERT(loader->unreachableURL().isEmpty());

    if (!loader->clientRedirectSourceForHistory().isNull()) {
        if (historyDelegate) {
            BString sourceURL(loader->clientRedirectSourceForHistory());
            BString destURL(loader->clientRedirectDestinationForHistory());
            historyDelegate->didPerformClientRedirectFromURL(webView, sourceURL, destURL, m_webFrame);
        } else {
            if (history) {
                if (COMPtr<IWebHistoryItem> iWebHistoryItem = history->itemForURLString(loader->clientRedirectSourceForHistory())) {
                    COMPtr<WebHistoryItem> webHistoryItem(Query, iWebHistoryItem);
                    webHistoryItem->historyItem()->addRedirectURL(loader->clientRedirectDestinationForHistory());
                }
            }
        }
    }

    if (!loader->serverRedirectSourceForHistory().isNull()) {
        if (historyDelegate) {
            BString sourceURL(loader->serverRedirectSourceForHistory());
            BString destURL(loader->serverRedirectDestinationForHistory());
            historyDelegate->didPerformServerRedirectFromURL(webView, sourceURL, destURL, m_webFrame);
        } else {
            if (history) {
                if (COMPtr<IWebHistoryItem> iWebHistoryItem = history->itemForURLString(loader->serverRedirectSourceForHistory())) {
                    COMPtr<WebHistoryItem> webHistoryItem(Query, iWebHistoryItem);
                    webHistoryItem->historyItem()->addRedirectURL(loader->serverRedirectDestinationForHistory());
                }
            }
        }
    }
}
Пример #6
0
void WebFrameLoaderClient::updateGlobalHistoryRedirectLinks()
{
    WebPage* webPage = m_frame->page();
    if (!webPage || !webPage->pageGroup()->isVisibleToHistoryClient())
        return;

    DocumentLoader* loader = m_frame->coreFrame()->loader()->documentLoader();
    ASSERT(loader->unreachableURL().isEmpty());

    // Client redirect
    if (!loader->clientRedirectSourceForHistory().isNull()) {
        WebProcess::shared().connection()->send(Messages::WebContext::DidPerformClientRedirect(webPage->pageID(),
            loader->clientRedirectSourceForHistory(), loader->clientRedirectDestinationForHistory(), m_frame->frameID()), 0);
    }

    // Server redirect
    if (!loader->serverRedirectSourceForHistory().isNull()) {
        WebProcess::shared().connection()->send(Messages::WebContext::DidPerformServerRedirect(webPage->pageID(),
            loader->serverRedirectSourceForHistory(), loader->serverRedirectDestinationForHistory(), m_frame->frameID()), 0);
    }
}
Пример #7
0
void WebFrameLoaderClient::dispatchDidStartProvisionalLoad()
{
    WebPage* webPage = m_frame->page();
    if (!webPage)
        return;

    webPage->findController().hideFindUI();
    webPage->sandboxExtensionTracker().didStartProvisionalLoad(m_frame);

    DocumentLoader* provisionalLoader = m_frame->coreFrame()->loader()->provisionalDocumentLoader();
    const String& url = provisionalLoader->url().string();
    RefPtr<APIObject> userData;

    // Notify the bundle client.
    webPage->injectedBundleLoaderClient().didStartProvisionalLoadForFrame(webPage, m_frame, userData);

    String unreachableURL = provisionalLoader->unreachableURL().string();

    // Notify the UIProcess.
    webPage->send(Messages::WebPageProxy::DidStartProvisionalLoadForFrame(m_frame->frameID(), url, unreachableURL, InjectedBundleUserMessageEncoder(userData.get())));
}
Пример #8
0
void HistoryController::updateCurrentItem()
{
    if (!m_currentItem)
        return;

    DocumentLoader* documentLoader = m_frame->loader()->documentLoader();

    if (!documentLoader->unreachableURL().isEmpty())
        return;

    if (m_currentItem->url() != documentLoader->url()) {
        // We ended up on a completely different URL this time, so the HistoryItem
        // needs to be re-initialized.  Preserve the isTargetItem flag as it is a
        // property of how this HistoryItem was originally created and is not
        // dependent on the document.
        bool isTargetItem = m_currentItem->isTargetItem();
        m_currentItem->reset();
        initializeItem(m_currentItem.get());
        m_currentItem->setIsTargetItem(isTargetItem);
    } else {
        // Even if the final URL didn't change, the form data may have changed.
        m_currentItem->setFormInfoFromRequest(documentLoader->request());
    }
}
void WebFrameLoaderClient::updateGlobalHistoryRedirectLinks()
{
    WebView* webView = m_webFrame->webView();
    SharedPtr<WebHistoryDelegate> historyDelegate = webView->historyDelegate();

    WebHistory* history = WebHistory::sharedHistory();

    DocumentLoader* loader = core(m_webFrame)->loader()->documentLoader();
    ASSERT(loader->unreachableURL().isEmpty());

    if (!loader->clientRedirectSourceForHistory().isNull()) {
        if (historyDelegate) {
            String sourceURL(loader->clientRedirectSourceForHistory());
            String destinationURL(loader->clientRedirectDestinationForHistory());
            historyDelegate->didPerformClientRedirectFromURL(webView, sourceURL.utf8().data(), destinationURL.utf8().data(), m_webFrame);
        } else {
            if (history) {
                if (WebHistoryItem* webHistoryItem = history->itemForURLString(strdup(loader->clientRedirectSourceForHistory().utf8().data())))
                    webHistoryItem->getPrivateItem()->m_historyItem.get()->addRedirectURL(loader->clientRedirectDestinationForHistory());
            }
        }
    }

    if (!loader->serverRedirectSourceForHistory().isNull()) {
        if (historyDelegate) {
            String sourceURL(loader->serverRedirectSourceForHistory());
            String destinationURL(loader->serverRedirectDestinationForHistory());
            historyDelegate->didPerformServerRedirectFromURL(webView, sourceURL.utf8().data(), destinationURL.utf8().data(), m_webFrame);
        } else {
            if (history) {
                if (WebHistoryItem *webHistoryItem = history->itemForURLString(strdup(loader->serverRedirectSourceForHistory().utf8().data())))
                    webHistoryItem->getPrivateItem()->m_historyItem.get()->addRedirectURL(loader->serverRedirectDestinationForHistory());
            }
        }
    }
}
Пример #10
0
void ContextMenuController::contextMenuItemSelected(ContextMenuItem* item)
{
    ASSERT(item->type() == ActionType || item->type() == CheckableActionType);

    if (item->action() >= ContextMenuItemBaseApplicationTag) {
        m_client->contextMenuItemSelected(item, m_contextMenu.get());
        return;
    }

    if (item->action() >= ContextMenuItemBaseCustomTag) {
        ASSERT(m_menuProvider);
        m_menuProvider->contextMenuItemSelected(item);
        return;
    }

    HitTestResult result = m_contextMenu->hitTestResult();
    Frame* frame = result.innerNonSharedNode()->document()->frame();
    if (!frame)
        return;

    switch (item->action()) {
    case ContextMenuItemTagOpenLinkInNewWindow:
        openNewWindow(result.absoluteLinkURL(), frame);
        break;
    case ContextMenuItemTagDownloadLinkToDisk:
        // FIXME: Some day we should be able to do this from within WebCore.
        m_client->downloadURL(result.absoluteLinkURL());
        break;
    case ContextMenuItemTagCopyLinkToClipboard:
        frame->editor()->copyURL(result.absoluteLinkURL(), result.textContent());
        break;
    case ContextMenuItemTagOpenImageInNewWindow:
        openNewWindow(result.absoluteImageURL(), frame);
        break;
    case ContextMenuItemTagDownloadImageToDisk:
        // FIXME: Some day we should be able to do this from within WebCore.
        m_client->downloadURL(result.absoluteImageURL());
        break;
    case ContextMenuItemTagCopyImageToClipboard:
        // FIXME: The Pasteboard class is not written yet
        // For now, call into the client. This is temporary!
        frame->editor()->copyImage(result);
        break;
    case ContextMenuItemTagOpenMediaInNewWindow:
        openNewWindow(result.absoluteMediaURL(), frame);
        break;
    case ContextMenuItemTagCopyMediaLinkToClipboard:
        frame->editor()->copyURL(result.absoluteMediaURL(), result.textContent());
        break;
    case ContextMenuItemTagToggleMediaControls:
        result.toggleMediaControlsDisplay();
        break;
    case ContextMenuItemTagToggleMediaLoop:
        result.toggleMediaLoopPlayback();
        break;
    case ContextMenuItemTagEnterVideoFullscreen:
        result.enterFullscreenForVideo();
        break;
    case ContextMenuItemTagMediaPlayPause:
        result.toggleMediaPlayState();
        break;
    case ContextMenuItemTagMediaMute:
        result.toggleMediaMuteState();
        break;
    case ContextMenuItemTagOpenFrameInNewWindow: {
        DocumentLoader* loader = frame->loader()->documentLoader();
        if (!loader->unreachableURL().isEmpty())
            openNewWindow(loader->unreachableURL(), frame);
        else
            openNewWindow(loader->url(), frame);
        break;
    }
    case ContextMenuItemTagCopy:
        frame->editor()->copy();
        break;
    case ContextMenuItemTagGoBack:
        if (Page* page = frame->page())
            page->goBackOrForward(-1);
        break;
    case ContextMenuItemTagGoForward:
        if (Page* page = frame->page())
            page->goBackOrForward(1);
        break;
    case ContextMenuItemTagStop:
        frame->loader()->stop();
        break;
    case ContextMenuItemTagReload:
        frame->loader()->reload();
        break;
    case ContextMenuItemTagCut:
        frame->editor()->cut();
        break;
    case ContextMenuItemTagPaste:
        frame->editor()->paste();
        break;
#if PLATFORM(GTK)
    case ContextMenuItemTagDelete:
        frame->editor()->performDelete();
        break;
    case ContextMenuItemTagSelectAll:
        frame->editor()->command("SelectAll").execute();
        break;
#endif
    case ContextMenuItemTagSpellingGuess:
        ASSERT(frame->editor()->selectedText().length());
        if (frame->editor()->shouldInsertText(item->title(), frame->selection()->toNormalizedRange().get(), EditorInsertActionPasted)) {
            Document* document = frame->document();
            RefPtr<ReplaceSelectionCommand> command = ReplaceSelectionCommand::create(document, createFragmentFromMarkup(document, item->title(), ""), true, false, true);
            applyCommand(command);
            frame->selection()->revealSelection(ScrollAlignment::alignToEdgeIfNeeded);
        }
        break;
    case ContextMenuItemTagIgnoreSpelling:
        frame->editor()->ignoreSpelling();
        break;
    case ContextMenuItemTagLearnSpelling:
        frame->editor()->learnSpelling();
        break;
    case ContextMenuItemTagSearchWeb:
        m_client->searchWithGoogle(frame);
        break;
    case ContextMenuItemTagLookUpInDictionary:
        // FIXME: Some day we may be able to do this from within WebCore.
        m_client->lookUpInDictionary(frame);
        break;
    case ContextMenuItemTagOpenLink:
        if (Frame* targetFrame = result.targetFrame())
            targetFrame->loader()->loadFrameRequest(FrameLoadRequest(ResourceRequest(result.absoluteLinkURL(), frame->loader()->outgoingReferrer())), false, false, 0, 0, SendReferrer);
        else
            openNewWindow(result.absoluteLinkURL(), frame);
        break;
    case ContextMenuItemTagBold:
        frame->editor()->command("ToggleBold").execute();
        break;
    case ContextMenuItemTagItalic:
        frame->editor()->command("ToggleItalic").execute();
        break;
    case ContextMenuItemTagUnderline:
        frame->editor()->toggleUnderline();
        break;
    case ContextMenuItemTagOutline:
        // We actually never enable this because CSS does not have a way to specify an outline font,
        // which may make this difficult to implement. Maybe a special case of text-shadow?
        break;
    case ContextMenuItemTagStartSpeaking: {
        ExceptionCode ec;
        RefPtr<Range> selectedRange = frame->selection()->toNormalizedRange();
        if (!selectedRange || selectedRange->collapsed(ec)) {
            Document* document = result.innerNonSharedNode()->document();
            selectedRange = document->createRange();
            selectedRange->selectNode(document->documentElement(), ec);
        }
        m_client->speak(plainText(selectedRange.get()));
        break;
    }
    case ContextMenuItemTagStopSpeaking:
        m_client->stopSpeaking();
        break;
    case ContextMenuItemTagDefaultDirection:
        frame->editor()->setBaseWritingDirection(NaturalWritingDirection);
        break;
    case ContextMenuItemTagLeftToRight:
        frame->editor()->setBaseWritingDirection(LeftToRightWritingDirection);
        break;
    case ContextMenuItemTagRightToLeft:
        frame->editor()->setBaseWritingDirection(RightToLeftWritingDirection);
        break;
    case ContextMenuItemTagTextDirectionDefault:
        frame->editor()->command("MakeTextWritingDirectionNatural").execute();
        break;
    case ContextMenuItemTagTextDirectionLeftToRight:
        frame->editor()->command("MakeTextWritingDirectionLeftToRight").execute();
        break;
    case ContextMenuItemTagTextDirectionRightToLeft:
        frame->editor()->command("MakeTextWritingDirectionRightToLeft").execute();
        break;
#if PLATFORM(MAC)
    case ContextMenuItemTagSearchInSpotlight:
        m_client->searchWithSpotlight();
        break;
#endif
    case ContextMenuItemTagShowSpellingPanel:
        frame->editor()->showSpellingGuessPanel();
        break;
    case ContextMenuItemTagCheckSpelling:
        frame->editor()->advanceToNextMisspelling();
        break;
    case ContextMenuItemTagCheckSpellingWhileTyping:
        frame->editor()->toggleContinuousSpellChecking();
        break;
#ifndef BUILDING_ON_TIGER
    case ContextMenuItemTagCheckGrammarWithSpelling:
        frame->editor()->toggleGrammarChecking();
        break;
#endif
#if PLATFORM(MAC)
    case ContextMenuItemTagShowFonts:
        frame->editor()->showFontPanel();
        break;
    case ContextMenuItemTagStyles:
        frame->editor()->showStylesPanel();
        break;
    case ContextMenuItemTagShowColors:
        frame->editor()->showColorPanel();
        break;
#endif
#if PLATFORM(MAC) && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
    case ContextMenuItemTagMakeUpperCase:
        frame->editor()->uppercaseWord();
        break;
    case ContextMenuItemTagMakeLowerCase:
        frame->editor()->lowercaseWord();
        break;
    case ContextMenuItemTagCapitalize:
        frame->editor()->capitalizeWord();
        break;
    case ContextMenuItemTagShowSubstitutions:
        frame->editor()->showSubstitutionsPanel();
        break;
    case ContextMenuItemTagSmartCopyPaste:
        frame->editor()->toggleSmartInsertDelete();
        break;
    case ContextMenuItemTagSmartQuotes:
        frame->editor()->toggleAutomaticQuoteSubstitution();
        break;
    case ContextMenuItemTagSmartDashes:
        frame->editor()->toggleAutomaticDashSubstitution();
        break;
    case ContextMenuItemTagSmartLinks:
        frame->editor()->toggleAutomaticLinkDetection();
        break;
    case ContextMenuItemTagTextReplacement:
        frame->editor()->toggleAutomaticTextReplacement();
        break;
    case ContextMenuItemTagCorrectSpellingAutomatically:
        frame->editor()->toggleAutomaticSpellingCorrection();
        break;
    case ContextMenuItemTagChangeBack:
        frame->editor()->changeBackToReplacedString(result.replacedString());
        break;
#endif
#if ENABLE(INSPECTOR)
    case ContextMenuItemTagInspectElement:
        if (Page* page = frame->page())
            page->inspectorController()->inspect(result.innerNonSharedNode());
        break;
#endif
    default:
        break;
    }
}
Пример #11
0
void ContextMenuController::contextMenuItemSelected(ContextMenuItem* item)
{
    ASSERT(item->type() == ActionType || item->type() == CheckableActionType);

    if (item->action() >= ContextMenuItemBaseApplicationTag) {
        m_client->contextMenuItemSelected(item, m_contextMenu.get());
        return;
    }

    HitTestResult result = m_contextMenu->hitTestResult();
    Frame* frame = result.innerNonSharedNode()->document()->frame();
    if (!frame)
        return;
    
    switch (item->action()) {
        case ContextMenuItemTagOpenLinkInNewWindow: 
            openNewWindow(result.absoluteLinkURL(), frame);
            break;
        case ContextMenuItemTagDownloadLinkToDisk:
            // FIXME: Some day we should be able to do this from within WebCore.
            m_client->downloadURL(result.absoluteLinkURL());
            break;
        case ContextMenuItemTagCopyLinkToClipboard:
            frame->editor()->copyURL(result.absoluteLinkURL(), result.textContent());
            break;
        case ContextMenuItemTagOpenImageInNewWindow:
            openNewWindow(result.absoluteImageURL(), frame);
            break;
        case ContextMenuItemTagDownloadImageToDisk:
            // FIXME: Some day we should be able to do this from within WebCore.
            m_client->downloadURL(result.absoluteImageURL());
            break;
        case ContextMenuItemTagCopyImageToClipboard:
            // FIXME: The Pasteboard class is not written yet
            // For now, call into the client. This is temporary!
            frame->editor()->copyImage(result);
            break;
        case ContextMenuItemTagOpenFrameInNewWindow: {
            DocumentLoader* loader = frame->loader()->documentLoader();
            if (!loader->unreachableURL().isEmpty())
                openNewWindow(loader->unreachableURL(), frame);
            else
                openNewWindow(loader->url(), frame);
            break;
        }
        case ContextMenuItemTagCopy:
            frame->editor()->copy();
            break;
        case ContextMenuItemTagGoBack:
            frame->loader()->goBackOrForward(-1);
            break;
        case ContextMenuItemTagGoForward:
            frame->loader()->goBackOrForward(1);
            break;
        case ContextMenuItemTagStop:
            frame->loader()->stop();
            break;
        case ContextMenuItemTagReload:
            frame->loader()->reload();
            break;
        case ContextMenuItemTagCut:
            frame->editor()->cut();
            break;
        case ContextMenuItemTagPaste:
            frame->editor()->paste();
            break;
#if PLATFORM(GTK) || PLATFORM(BAL)
        case ContextMenuItemTagDelete:
            frame->editor()->performDelete();
            break;
        case ContextMenuItemTagSelectAll:
            frame->editor()->command("SelectAll").execute();
            break;
#endif
        case ContextMenuItemTagSpellingGuess:
            ASSERT(frame->selectedText().length());
            if (frame->editor()->shouldInsertText(item->title(), frame->selection()->toRange().get(),
                EditorInsertActionPasted)) {
                Document* document = frame->document();
                RefPtr<ReplaceSelectionCommand> command =
                    ReplaceSelectionCommand::create(document, createFragmentFromMarkup(document, item->title(), ""),
                                                                                   true, false, true);
                applyCommand(command);
                frame->revealSelection(RenderLayer::gAlignToEdgeIfNeeded);
            }
            break;
        case ContextMenuItemTagIgnoreSpelling:
            frame->editor()->ignoreSpelling();
            break;
        case ContextMenuItemTagLearnSpelling:
            frame->editor()->learnSpelling();
            break;
        case ContextMenuItemTagSearchWeb:
            m_client->searchWithGoogle(frame);
            break;
        case ContextMenuItemTagLookUpInDictionary:
            // FIXME: Some day we may be able to do this from within WebCore.
            m_client->lookUpInDictionary(frame);
            break;
        case ContextMenuItemTagOpenLink:
            if (Frame* targetFrame = result.targetFrame())
                targetFrame->loader()->loadFrameRequestWithFormAndValues(FrameLoadRequest(ResourceRequest(result.absoluteLinkURL(), 
                    frame->loader()->outgoingReferrer())), false, 0, 0, HashMap<String, String>());
            else
                openNewWindow(result.absoluteLinkURL(), frame);
            break;
        case ContextMenuItemTagBold:
            frame->editor()->command("ToggleBold").execute();
            break;
        case ContextMenuItemTagItalic:
            frame->editor()->command("ToggleItalic").execute();
            break;
        case ContextMenuItemTagUnderline:
            frame->editor()->toggleUnderline();
            break;
        case ContextMenuItemTagOutline:
            // We actually never enable this because CSS does not have a way to specify an outline font,
            // which may make this difficult to implement. Maybe a special case of text-shadow?
            break;
        case ContextMenuItemTagStartSpeaking: {
            ExceptionCode ec;
            RefPtr<Range> selectedRange = frame->selection()->toRange();
            if (!selectedRange || selectedRange->collapsed(ec)) {
                Document* document = result.innerNonSharedNode()->document();
                selectedRange = document->createRange();
                selectedRange->selectNode(document->documentElement(), ec);
            }
            m_client->speak(plainText(selectedRange.get()));
            break;
        }
        case ContextMenuItemTagStopSpeaking:
            m_client->stopSpeaking();
            break;
        case ContextMenuItemTagDefaultDirection:
            frame->editor()->setBaseWritingDirection(NaturalWritingDirection);
            break;
        case ContextMenuItemTagLeftToRight:
            frame->editor()->setBaseWritingDirection(LeftToRightWritingDirection);
            break;
        case ContextMenuItemTagRightToLeft:
            frame->editor()->setBaseWritingDirection(RightToLeftWritingDirection);
            break;
#if PLATFORM(MAC)
        case ContextMenuItemTagSearchInSpotlight:
            m_client->searchWithSpotlight();
            break;
#endif
        case ContextMenuItemTagShowSpellingPanel:
            frame->editor()->showSpellingGuessPanel();
            break;
        case ContextMenuItemTagCheckSpelling:
            frame->editor()->advanceToNextMisspelling();
            break;
        case ContextMenuItemTagCheckSpellingWhileTyping:
            frame->editor()->toggleContinuousSpellChecking();
            break;
#ifndef BUILDING_ON_TIGER
        case ContextMenuItemTagCheckGrammarWithSpelling:
            frame->editor()->toggleGrammarChecking();
            break;
#endif
#if PLATFORM(MAC)
        case ContextMenuItemTagShowFonts:
            frame->editor()->showFontPanel();
            break;
        case ContextMenuItemTagStyles:
            frame->editor()->showStylesPanel();
            break;
        case ContextMenuItemTagShowColors:
            frame->editor()->showColorPanel();
            break;
#endif
        case ContextMenuItemTagInspectElement:
            if (Page* page = frame->page())
                page->inspectorController()->inspect(result.innerNonSharedNode());
            break;
        default:
            break;
    }
}