2009-11-10 Yaar Schnitman <yaar@chromium.org>
authoreric@webkit.org <eric@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 10 Nov 2009 18:27:16 +0000 (18:27 +0000)
committereric@webkit.org <eric@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 10 Nov 2009 18:27:16 +0000 (18:27 +0000)
        Reviewed by Dimitri Glazkov.

        Up-streaming Chromium API src files: DOMUtilities...FrameLoaderClientImpl

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

        * src/DOMUtilitiesPrivate.cpp: Added.
        (WebCore::toHTMLElement):
        (WebKit::toHTMLInputElement):
        (WebKit::toHTMLLinkElement):
        (WebKit::toHTMLMetaElement):
        (WebKit::toHTMLOptionElement):
        (WebKit::nameOfInputElement):
        * src/DOMUtilitiesPrivate.h: Added.
        * src/DragClientImpl.cpp: Added.
        (WebKit::DragClientImpl::willPerformDragDestinationAction):
        (WebKit::DragClientImpl::willPerformDragSourceAction):
        (WebKit::DragClientImpl::actionMaskForDrag):
        (WebKit::DragClientImpl::dragSourceActionMaskForPoint):
        (WebKit::DragClientImpl::startDrag):
        (WebKit::DragClientImpl::createDragImageForLink):
        (WebKit::DragClientImpl::dragControllerDestroyed):
        * src/DragClientImpl.h: Added.
        (WebKit::DragClientImpl::DragClientImpl):
        * src/EditorClientImpl.cpp: Added.
        (WebKit::EditorClientImpl::EditorClientImpl):
        (WebKit::EditorClientImpl::~EditorClientImpl):
        (WebKit::EditorClientImpl::pageDestroyed):
        (WebKit::EditorClientImpl::shouldShowDeleteInterface):
        (WebKit::EditorClientImpl::smartInsertDeleteEnabled):
        (WebKit::EditorClientImpl::isSelectTrailingWhitespaceEnabled):
        (WebKit::EditorClientImpl::shouldSpellcheckByDefault):
        (WebKit::EditorClientImpl::isContinuousSpellCheckingEnabled):
        (WebKit::EditorClientImpl::toggleContinuousSpellChecking):
        (WebKit::EditorClientImpl::isGrammarCheckingEnabled):
        (WebKit::EditorClientImpl::toggleGrammarChecking):
        (WebKit::EditorClientImpl::spellCheckerDocumentTag):
        (WebKit::EditorClientImpl::isEditable):
        (WebKit::EditorClientImpl::shouldBeginEditing):
        (WebKit::EditorClientImpl::shouldEndEditing):
        (WebKit::EditorClientImpl::shouldInsertNode):
        (WebKit::EditorClientImpl::shouldInsertText):
        (WebKit::EditorClientImpl::shouldDeleteRange):
        (WebKit::EditorClientImpl::shouldChangeSelectedRange):
        (WebKit::EditorClientImpl::shouldApplyStyle):
        (WebKit::EditorClientImpl::shouldMoveRangeAfterDelete):
        (WebKit::EditorClientImpl::didBeginEditing):
        (WebKit::EditorClientImpl::respondToChangedSelection):
        (WebKit::EditorClientImpl::respondToChangedContents):
        (WebKit::EditorClientImpl::didEndEditing):
        (WebKit::EditorClientImpl::didWriteSelectionToPasteboard):
        (WebKit::EditorClientImpl::didSetSelectionTypesForPasteboard):
        (WebKit::EditorClientImpl::registerCommandForUndo):
        (WebKit::EditorClientImpl::registerCommandForRedo):
        (WebKit::EditorClientImpl::clearUndoRedoOperations):
        (WebKit::EditorClientImpl::canUndo):
        (WebKit::EditorClientImpl::canRedo):
        (WebKit::EditorClientImpl::undo):
        (WebKit::EditorClientImpl::redo):
        (WebKit::):
        (WebKit::EditorClientImpl::interpretKeyEvent):
        (WebKit::EditorClientImpl::handleEditingKeyboardEvent):
        (WebKit::EditorClientImpl::handleKeyboardEvent):
        (WebKit::EditorClientImpl::handleInputMethodKeydown):
        (WebKit::EditorClientImpl::textFieldDidBeginEditing):
        (WebKit::EditorClientImpl::textFieldDidEndEditing):
        (WebKit::EditorClientImpl::textDidChangeInTextField):
        (WebKit::EditorClientImpl::showFormAutofillForNode):
        (WebKit::EditorClientImpl::autofill):
        (WebKit::EditorClientImpl::doAutofill):
        (WebKit::EditorClientImpl::cancelPendingAutofill):
        (WebKit::EditorClientImpl::onAutofillSuggestionAccepted):
        (WebKit::EditorClientImpl::doTextFieldCommandFromEvent):
        (WebKit::EditorClientImpl::textWillBeDeletedInTextField):
        (WebKit::EditorClientImpl::textDidChangeInTextArea):
        (WebKit::EditorClientImpl::ignoreWordInSpellDocument):
        (WebKit::EditorClientImpl::learnWord):
        (WebKit::EditorClientImpl::checkSpellingOfString):
        (WebKit::EditorClientImpl::getAutoCorrectSuggestionForMisspelledWord):
        (WebKit::EditorClientImpl::checkGrammarOfString):
        (WebKit::EditorClientImpl::updateSpellingUIWithGrammarString):
        (WebKit::EditorClientImpl::updateSpellingUIWithMisspelledWord):
        (WebKit::EditorClientImpl::showSpellingUI):
        (WebKit::EditorClientImpl::spellingUIIsShowing):
        (WebKit::EditorClientImpl::getGuessesForWord):
        (WebKit::EditorClientImpl::setInputMethodState):
        * src/EditorClientImpl.h: Added.
        (WebKit::EditorClientImpl::):
        * src/FrameLoaderClientImpl.cpp: Added.
        (WebKit::):
        (WebKit::FrameLoaderClientImpl::FrameLoaderClientImpl):
        (WebKit::FrameLoaderClientImpl::~FrameLoaderClientImpl):
        (WebKit::FrameLoaderClientImpl::frameLoaderDestroyed):
        (WebKit::FrameLoaderClientImpl::windowObjectCleared):
        (WebKit::FrameLoaderClientImpl::documentElementAvailable):
        (WebKit::FrameLoaderClientImpl::didCreateScriptContextForFrame):
        (WebKit::FrameLoaderClientImpl::didDestroyScriptContextForFrame):
        (WebKit::FrameLoaderClientImpl::didCreateIsolatedScriptContext):
        (WebKit::FrameLoaderClientImpl::didPerformFirstNavigation):
        (WebKit::FrameLoaderClientImpl::registerForIconNotification):
        (WebKit::FrameLoaderClientImpl::didChangeScrollOffset):
        (WebKit::FrameLoaderClientImpl::allowJavaScript):
        (WebKit::FrameLoaderClientImpl::hasWebView):
        (WebKit::FrameLoaderClientImpl::hasFrameView):
        (WebKit::FrameLoaderClientImpl::makeDocumentView):
        (WebKit::FrameLoaderClientImpl::makeRepresentation):
        (WebKit::FrameLoaderClientImpl::forceLayout):
        (WebKit::FrameLoaderClientImpl::forceLayoutForNonHTML):
        (WebKit::FrameLoaderClientImpl::setCopiesOnScroll):
        (WebKit::FrameLoaderClientImpl::detachedFromParent2):
        (WebKit::FrameLoaderClientImpl::detachedFromParent3):
        (WebKit::FrameLoaderClientImpl::assignIdentifierToInitialRequest):
        (WebKit::determineTargetTypeFromLoader):
        (WebKit::FrameLoaderClientImpl::dispatchWillSendRequest):
        (WebKit::FrameLoaderClientImpl::shouldUseCredentialStorage):
        (WebKit::FrameLoaderClientImpl::dispatchDidReceiveAuthenticationChallenge):
        (WebKit::FrameLoaderClientImpl::dispatchDidCancelAuthenticationChallenge):
        (WebKit::FrameLoaderClientImpl::dispatchDidReceiveResponse):
        (WebKit::FrameLoaderClientImpl::dispatchDidReceiveContentLength):
        (WebKit::FrameLoaderClientImpl::dispatchDidFinishLoading):
        (WebKit::FrameLoaderClientImpl::dispatchDidFailLoading):
        (WebKit::FrameLoaderClientImpl::dispatchDidFinishDocumentLoad):
        (WebKit::FrameLoaderClientImpl::dispatchDidLoadResourceFromMemoryCache):
        (WebKit::FrameLoaderClientImpl::dispatchDidLoadResourceByXMLHttpRequest):
        (WebKit::FrameLoaderClientImpl::dispatchDidHandleOnloadEvents):
        (WebKit::FrameLoaderClientImpl::dispatchDidReceiveServerRedirectForProvisionalLoad):
        (WebKit::FrameLoaderClientImpl::dispatchDidCancelClientRedirect):
        (WebKit::FrameLoaderClientImpl::dispatchWillPerformClientRedirect):
        (WebKit::FrameLoaderClientImpl::dispatchDidChangeLocationWithinPage):
        (WebKit::FrameLoaderClientImpl::dispatchWillClose):
        (WebKit::FrameLoaderClientImpl::dispatchDidReceiveIcon):
        (WebKit::FrameLoaderClientImpl::dispatchDidStartProvisionalLoad):
        (WebKit::FrameLoaderClientImpl::dispatchDidReceiveTitle):
        (WebKit::FrameLoaderClientImpl::dispatchDidCommitLoad):
        (WebKit::FrameLoaderClientImpl::dispatchDidFailProvisionalLoad):
        (WebKit::FrameLoaderClientImpl::dispatchDidFailLoad):
        (WebKit::FrameLoaderClientImpl::dispatchDidFinishLoad):
        (WebKit::FrameLoaderClientImpl::dispatchDidFirstLayout):
        (WebKit::FrameLoaderClientImpl::dispatchDidFirstVisuallyNonEmptyLayout):
        (WebKit::FrameLoaderClientImpl::dispatchCreatePage):
        (WebKit::FrameLoaderClientImpl::dispatchShow):
        (WebKit::shouldTreatAsAttachment):
        (WebKit::FrameLoaderClientImpl::dispatchDecidePolicyForMIMEType):
        (WebKit::FrameLoaderClientImpl::dispatchDecidePolicyForNewWindowAction):
        (WebKit::FrameLoaderClientImpl::dispatchDecidePolicyForNavigationAction):
        (WebKit::FrameLoaderClientImpl::cancelPolicyCheck):
        (WebKit::FrameLoaderClientImpl::dispatchUnableToImplementPolicy):
        (WebKit::FrameLoaderClientImpl::dispatchWillSubmitForm):
        (WebKit::FrameLoaderClientImpl::dispatchDidLoadMainResource):
        (WebKit::FrameLoaderClientImpl::revertToProvisionalState):
        (WebKit::FrameLoaderClientImpl::setMainDocumentError):
        (WebKit::FrameLoaderClientImpl::postProgressStartedNotification):
        (WebKit::FrameLoaderClientImpl::postProgressEstimateChangedNotification):
        (WebKit::FrameLoaderClientImpl::postProgressFinishedNotification):
        (WebKit::FrameLoaderClientImpl::setMainFrameDocumentReady):
        (WebKit::FrameLoaderClientImpl::startDownload):
        (WebKit::FrameLoaderClientImpl::willChangeTitle):
        (WebKit::FrameLoaderClientImpl::didChangeTitle):
        (WebKit::FrameLoaderClientImpl::committedLoad):
        (WebKit::FrameLoaderClientImpl::finishedLoading):
        (WebKit::FrameLoaderClientImpl::updateGlobalHistory):
        (WebKit::FrameLoaderClientImpl::updateGlobalHistoryRedirectLinks):
        (WebKit::FrameLoaderClientImpl::shouldGoToHistoryItem):
        (WebKit::FrameLoaderClientImpl::didDisplayInsecureContent):
        (WebKit::FrameLoaderClientImpl::didRunInsecureContent):
        (WebKit::FrameLoaderClientImpl::blockedError):
        (WebKit::FrameLoaderClientImpl::cancelledError):
        (WebKit::FrameLoaderClientImpl::cannotShowURLError):
        (WebKit::FrameLoaderClientImpl::interruptForPolicyChangeError):
        (WebKit::FrameLoaderClientImpl::cannotShowMIMETypeError):
        (WebKit::FrameLoaderClientImpl::fileDoesNotExistError):
        (WebKit::FrameLoaderClientImpl::pluginWillHandleLoadError):
        (WebKit::FrameLoaderClientImpl::shouldFallBack):
        (WebKit::FrameLoaderClientImpl::canHandleRequest):
        (WebKit::FrameLoaderClientImpl::canShowMIMEType):
        (WebKit::FrameLoaderClientImpl::representationExistsForURLScheme):
        (WebKit::FrameLoaderClientImpl::generatedMIMETypeForURLScheme):
        (WebKit::FrameLoaderClientImpl::frameLoadCompleted):
        (WebKit::FrameLoaderClientImpl::saveViewStateToItem):
        (WebKit::FrameLoaderClientImpl::restoreViewState):
        (WebKit::FrameLoaderClientImpl::provisionalLoadStarted):
        (WebKit::FrameLoaderClientImpl::didFinishLoad):
        (WebKit::FrameLoaderClientImpl::prepareForDataSourceReplacement):
        (WebKit::FrameLoaderClientImpl::createDocumentLoader):
        (WebKit::FrameLoaderClientImpl::setTitle):
        (WebKit::FrameLoaderClientImpl::userAgent):
        (WebKit::FrameLoaderClientImpl::savePlatformDataToCachedFrame):
        (WebKit::FrameLoaderClientImpl::transitionToCommittedFromCachedFrame):
        (WebKit::FrameLoaderClientImpl::transitionToCommittedForNewPage):
        (WebKit::FrameLoaderClientImpl::canCachePage):
        (WebKit::FrameLoaderClientImpl::download):
        (WebKit::FrameLoaderClientImpl::createFrame):
        (WebKit::FrameLoaderClientImpl::createPlugin):
        (WebKit::FrameLoaderClientImpl::redirectDataToPlugin):
        (WebKit::FrameLoaderClientImpl::createJavaAppletWidget):
        (WebKit::FrameLoaderClientImpl::objectContentType):
        (WebKit::FrameLoaderClientImpl::overrideMediaType):
        (WebKit::FrameLoaderClientImpl::actionSpecifiesNavigationPolicy):
        (WebKit::FrameLoaderClientImpl::handleBackForwardNavigation):
        (WebKit::FrameLoaderClientImpl::pluginLoadObserver):
        * src/FrameLoaderClientImpl.h: Added.
        (WebKit::FrameLoaderClientImpl::webFrame):
        (WebKit::FrameLoaderClientImpl::willChangeEstimatedProgress):
        (WebKit::FrameLoaderClientImpl::didChangeEstimatedProgress):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@50742 268f45cc-cd09-0410-ab3c-d52691b4dbfc

WebKit/chromium/ChangeLog
WebKit/chromium/src/DOMUtilitiesPrivate.cpp [new file with mode: 0644]
WebKit/chromium/src/DOMUtilitiesPrivate.h [new file with mode: 0644]
WebKit/chromium/src/DragClientImpl.cpp [new file with mode: 0644]
WebKit/chromium/src/DragClientImpl.h [new file with mode: 0644]
WebKit/chromium/src/EditorClientImpl.cpp [new file with mode: 0644]
WebKit/chromium/src/EditorClientImpl.h [new file with mode: 0644]
WebKit/chromium/src/FrameLoaderClientImpl.cpp [new file with mode: 0644]
WebKit/chromium/src/FrameLoaderClientImpl.h [new file with mode: 0644]

index bc446137ae43ecb8fe393d1c0d625efd97cbd432..693b77ce3170fadadb4c3353e958937edd63d0fa 100644 (file)
@@ -1,3 +1,210 @@
+2009-11-10  Yaar Schnitman  <yaar@chromium.org>
+
+        Reviewed by Dimitri Glazkov.
+
+        Up-streaming Chromium API src files: DOMUtilities...FrameLoaderClientImpl
+
+        https://bugs.webkit.org/show_bug.cgi?id=31276
+
+        * src/DOMUtilitiesPrivate.cpp: Added.
+        (WebCore::toHTMLElement):
+        (WebKit::toHTMLInputElement):
+        (WebKit::toHTMLLinkElement):
+        (WebKit::toHTMLMetaElement):
+        (WebKit::toHTMLOptionElement):
+        (WebKit::nameOfInputElement):
+        * src/DOMUtilitiesPrivate.h: Added.
+        * src/DragClientImpl.cpp: Added.
+        (WebKit::DragClientImpl::willPerformDragDestinationAction):
+        (WebKit::DragClientImpl::willPerformDragSourceAction):
+        (WebKit::DragClientImpl::actionMaskForDrag):
+        (WebKit::DragClientImpl::dragSourceActionMaskForPoint):
+        (WebKit::DragClientImpl::startDrag):
+        (WebKit::DragClientImpl::createDragImageForLink):
+        (WebKit::DragClientImpl::dragControllerDestroyed):
+        * src/DragClientImpl.h: Added.
+        (WebKit::DragClientImpl::DragClientImpl):
+        * src/EditorClientImpl.cpp: Added.
+        (WebKit::EditorClientImpl::EditorClientImpl):
+        (WebKit::EditorClientImpl::~EditorClientImpl):
+        (WebKit::EditorClientImpl::pageDestroyed):
+        (WebKit::EditorClientImpl::shouldShowDeleteInterface):
+        (WebKit::EditorClientImpl::smartInsertDeleteEnabled):
+        (WebKit::EditorClientImpl::isSelectTrailingWhitespaceEnabled):
+        (WebKit::EditorClientImpl::shouldSpellcheckByDefault):
+        (WebKit::EditorClientImpl::isContinuousSpellCheckingEnabled):
+        (WebKit::EditorClientImpl::toggleContinuousSpellChecking):
+        (WebKit::EditorClientImpl::isGrammarCheckingEnabled):
+        (WebKit::EditorClientImpl::toggleGrammarChecking):
+        (WebKit::EditorClientImpl::spellCheckerDocumentTag):
+        (WebKit::EditorClientImpl::isEditable):
+        (WebKit::EditorClientImpl::shouldBeginEditing):
+        (WebKit::EditorClientImpl::shouldEndEditing):
+        (WebKit::EditorClientImpl::shouldInsertNode):
+        (WebKit::EditorClientImpl::shouldInsertText):
+        (WebKit::EditorClientImpl::shouldDeleteRange):
+        (WebKit::EditorClientImpl::shouldChangeSelectedRange):
+        (WebKit::EditorClientImpl::shouldApplyStyle):
+        (WebKit::EditorClientImpl::shouldMoveRangeAfterDelete):
+        (WebKit::EditorClientImpl::didBeginEditing):
+        (WebKit::EditorClientImpl::respondToChangedSelection):
+        (WebKit::EditorClientImpl::respondToChangedContents):
+        (WebKit::EditorClientImpl::didEndEditing):
+        (WebKit::EditorClientImpl::didWriteSelectionToPasteboard):
+        (WebKit::EditorClientImpl::didSetSelectionTypesForPasteboard):
+        (WebKit::EditorClientImpl::registerCommandForUndo):
+        (WebKit::EditorClientImpl::registerCommandForRedo):
+        (WebKit::EditorClientImpl::clearUndoRedoOperations):
+        (WebKit::EditorClientImpl::canUndo):
+        (WebKit::EditorClientImpl::canRedo):
+        (WebKit::EditorClientImpl::undo):
+        (WebKit::EditorClientImpl::redo):
+        (WebKit::):
+        (WebKit::EditorClientImpl::interpretKeyEvent):
+        (WebKit::EditorClientImpl::handleEditingKeyboardEvent):
+        (WebKit::EditorClientImpl::handleKeyboardEvent):
+        (WebKit::EditorClientImpl::handleInputMethodKeydown):
+        (WebKit::EditorClientImpl::textFieldDidBeginEditing):
+        (WebKit::EditorClientImpl::textFieldDidEndEditing):
+        (WebKit::EditorClientImpl::textDidChangeInTextField):
+        (WebKit::EditorClientImpl::showFormAutofillForNode):
+        (WebKit::EditorClientImpl::autofill):
+        (WebKit::EditorClientImpl::doAutofill):
+        (WebKit::EditorClientImpl::cancelPendingAutofill):
+        (WebKit::EditorClientImpl::onAutofillSuggestionAccepted):
+        (WebKit::EditorClientImpl::doTextFieldCommandFromEvent):
+        (WebKit::EditorClientImpl::textWillBeDeletedInTextField):
+        (WebKit::EditorClientImpl::textDidChangeInTextArea):
+        (WebKit::EditorClientImpl::ignoreWordInSpellDocument):
+        (WebKit::EditorClientImpl::learnWord):
+        (WebKit::EditorClientImpl::checkSpellingOfString):
+        (WebKit::EditorClientImpl::getAutoCorrectSuggestionForMisspelledWord):
+        (WebKit::EditorClientImpl::checkGrammarOfString):
+        (WebKit::EditorClientImpl::updateSpellingUIWithGrammarString):
+        (WebKit::EditorClientImpl::updateSpellingUIWithMisspelledWord):
+        (WebKit::EditorClientImpl::showSpellingUI):
+        (WebKit::EditorClientImpl::spellingUIIsShowing):
+        (WebKit::EditorClientImpl::getGuessesForWord):
+        (WebKit::EditorClientImpl::setInputMethodState):
+        * src/EditorClientImpl.h: Added.
+        (WebKit::EditorClientImpl::):
+        * src/FrameLoaderClientImpl.cpp: Added.
+        (WebKit::):
+        (WebKit::FrameLoaderClientImpl::FrameLoaderClientImpl):
+        (WebKit::FrameLoaderClientImpl::~FrameLoaderClientImpl):
+        (WebKit::FrameLoaderClientImpl::frameLoaderDestroyed):
+        (WebKit::FrameLoaderClientImpl::windowObjectCleared):
+        (WebKit::FrameLoaderClientImpl::documentElementAvailable):
+        (WebKit::FrameLoaderClientImpl::didCreateScriptContextForFrame):
+        (WebKit::FrameLoaderClientImpl::didDestroyScriptContextForFrame):
+        (WebKit::FrameLoaderClientImpl::didCreateIsolatedScriptContext):
+        (WebKit::FrameLoaderClientImpl::didPerformFirstNavigation):
+        (WebKit::FrameLoaderClientImpl::registerForIconNotification):
+        (WebKit::FrameLoaderClientImpl::didChangeScrollOffset):
+        (WebKit::FrameLoaderClientImpl::allowJavaScript):
+        (WebKit::FrameLoaderClientImpl::hasWebView):
+        (WebKit::FrameLoaderClientImpl::hasFrameView):
+        (WebKit::FrameLoaderClientImpl::makeDocumentView):
+        (WebKit::FrameLoaderClientImpl::makeRepresentation):
+        (WebKit::FrameLoaderClientImpl::forceLayout):
+        (WebKit::FrameLoaderClientImpl::forceLayoutForNonHTML):
+        (WebKit::FrameLoaderClientImpl::setCopiesOnScroll):
+        (WebKit::FrameLoaderClientImpl::detachedFromParent2):
+        (WebKit::FrameLoaderClientImpl::detachedFromParent3):
+        (WebKit::FrameLoaderClientImpl::assignIdentifierToInitialRequest):
+        (WebKit::determineTargetTypeFromLoader):
+        (WebKit::FrameLoaderClientImpl::dispatchWillSendRequest):
+        (WebKit::FrameLoaderClientImpl::shouldUseCredentialStorage):
+        (WebKit::FrameLoaderClientImpl::dispatchDidReceiveAuthenticationChallenge):
+        (WebKit::FrameLoaderClientImpl::dispatchDidCancelAuthenticationChallenge):
+        (WebKit::FrameLoaderClientImpl::dispatchDidReceiveResponse):
+        (WebKit::FrameLoaderClientImpl::dispatchDidReceiveContentLength):
+        (WebKit::FrameLoaderClientImpl::dispatchDidFinishLoading):
+        (WebKit::FrameLoaderClientImpl::dispatchDidFailLoading):
+        (WebKit::FrameLoaderClientImpl::dispatchDidFinishDocumentLoad):
+        (WebKit::FrameLoaderClientImpl::dispatchDidLoadResourceFromMemoryCache):
+        (WebKit::FrameLoaderClientImpl::dispatchDidLoadResourceByXMLHttpRequest):
+        (WebKit::FrameLoaderClientImpl::dispatchDidHandleOnloadEvents):
+        (WebKit::FrameLoaderClientImpl::dispatchDidReceiveServerRedirectForProvisionalLoad):
+        (WebKit::FrameLoaderClientImpl::dispatchDidCancelClientRedirect):
+        (WebKit::FrameLoaderClientImpl::dispatchWillPerformClientRedirect):
+        (WebKit::FrameLoaderClientImpl::dispatchDidChangeLocationWithinPage):
+        (WebKit::FrameLoaderClientImpl::dispatchWillClose):
+        (WebKit::FrameLoaderClientImpl::dispatchDidReceiveIcon):
+        (WebKit::FrameLoaderClientImpl::dispatchDidStartProvisionalLoad):
+        (WebKit::FrameLoaderClientImpl::dispatchDidReceiveTitle):
+        (WebKit::FrameLoaderClientImpl::dispatchDidCommitLoad):
+        (WebKit::FrameLoaderClientImpl::dispatchDidFailProvisionalLoad):
+        (WebKit::FrameLoaderClientImpl::dispatchDidFailLoad):
+        (WebKit::FrameLoaderClientImpl::dispatchDidFinishLoad):
+        (WebKit::FrameLoaderClientImpl::dispatchDidFirstLayout):
+        (WebKit::FrameLoaderClientImpl::dispatchDidFirstVisuallyNonEmptyLayout):
+        (WebKit::FrameLoaderClientImpl::dispatchCreatePage):
+        (WebKit::FrameLoaderClientImpl::dispatchShow):
+        (WebKit::shouldTreatAsAttachment):
+        (WebKit::FrameLoaderClientImpl::dispatchDecidePolicyForMIMEType):
+        (WebKit::FrameLoaderClientImpl::dispatchDecidePolicyForNewWindowAction):
+        (WebKit::FrameLoaderClientImpl::dispatchDecidePolicyForNavigationAction):
+        (WebKit::FrameLoaderClientImpl::cancelPolicyCheck):
+        (WebKit::FrameLoaderClientImpl::dispatchUnableToImplementPolicy):
+        (WebKit::FrameLoaderClientImpl::dispatchWillSubmitForm):
+        (WebKit::FrameLoaderClientImpl::dispatchDidLoadMainResource):
+        (WebKit::FrameLoaderClientImpl::revertToProvisionalState):
+        (WebKit::FrameLoaderClientImpl::setMainDocumentError):
+        (WebKit::FrameLoaderClientImpl::postProgressStartedNotification):
+        (WebKit::FrameLoaderClientImpl::postProgressEstimateChangedNotification):
+        (WebKit::FrameLoaderClientImpl::postProgressFinishedNotification):
+        (WebKit::FrameLoaderClientImpl::setMainFrameDocumentReady):
+        (WebKit::FrameLoaderClientImpl::startDownload):
+        (WebKit::FrameLoaderClientImpl::willChangeTitle):
+        (WebKit::FrameLoaderClientImpl::didChangeTitle):
+        (WebKit::FrameLoaderClientImpl::committedLoad):
+        (WebKit::FrameLoaderClientImpl::finishedLoading):
+        (WebKit::FrameLoaderClientImpl::updateGlobalHistory):
+        (WebKit::FrameLoaderClientImpl::updateGlobalHistoryRedirectLinks):
+        (WebKit::FrameLoaderClientImpl::shouldGoToHistoryItem):
+        (WebKit::FrameLoaderClientImpl::didDisplayInsecureContent):
+        (WebKit::FrameLoaderClientImpl::didRunInsecureContent):
+        (WebKit::FrameLoaderClientImpl::blockedError):
+        (WebKit::FrameLoaderClientImpl::cancelledError):
+        (WebKit::FrameLoaderClientImpl::cannotShowURLError):
+        (WebKit::FrameLoaderClientImpl::interruptForPolicyChangeError):
+        (WebKit::FrameLoaderClientImpl::cannotShowMIMETypeError):
+        (WebKit::FrameLoaderClientImpl::fileDoesNotExistError):
+        (WebKit::FrameLoaderClientImpl::pluginWillHandleLoadError):
+        (WebKit::FrameLoaderClientImpl::shouldFallBack):
+        (WebKit::FrameLoaderClientImpl::canHandleRequest):
+        (WebKit::FrameLoaderClientImpl::canShowMIMEType):
+        (WebKit::FrameLoaderClientImpl::representationExistsForURLScheme):
+        (WebKit::FrameLoaderClientImpl::generatedMIMETypeForURLScheme):
+        (WebKit::FrameLoaderClientImpl::frameLoadCompleted):
+        (WebKit::FrameLoaderClientImpl::saveViewStateToItem):
+        (WebKit::FrameLoaderClientImpl::restoreViewState):
+        (WebKit::FrameLoaderClientImpl::provisionalLoadStarted):
+        (WebKit::FrameLoaderClientImpl::didFinishLoad):
+        (WebKit::FrameLoaderClientImpl::prepareForDataSourceReplacement):
+        (WebKit::FrameLoaderClientImpl::createDocumentLoader):
+        (WebKit::FrameLoaderClientImpl::setTitle):
+        (WebKit::FrameLoaderClientImpl::userAgent):
+        (WebKit::FrameLoaderClientImpl::savePlatformDataToCachedFrame):
+        (WebKit::FrameLoaderClientImpl::transitionToCommittedFromCachedFrame):
+        (WebKit::FrameLoaderClientImpl::transitionToCommittedForNewPage):
+        (WebKit::FrameLoaderClientImpl::canCachePage):
+        (WebKit::FrameLoaderClientImpl::download):
+        (WebKit::FrameLoaderClientImpl::createFrame):
+        (WebKit::FrameLoaderClientImpl::createPlugin):
+        (WebKit::FrameLoaderClientImpl::redirectDataToPlugin):
+        (WebKit::FrameLoaderClientImpl::createJavaAppletWidget):
+        (WebKit::FrameLoaderClientImpl::objectContentType):
+        (WebKit::FrameLoaderClientImpl::overrideMediaType):
+        (WebKit::FrameLoaderClientImpl::actionSpecifiesNavigationPolicy):
+        (WebKit::FrameLoaderClientImpl::handleBackForwardNavigation):
+        (WebKit::FrameLoaderClientImpl::pluginLoadObserver):
+        * src/FrameLoaderClientImpl.h: Added.
+        (WebKit::FrameLoaderClientImpl::webFrame):
+        (WebKit::FrameLoaderClientImpl::willChangeEstimatedProgress):
+        (WebKit::FrameLoaderClientImpl::didChangeEstimatedProgress):
+
 2009-11-10  Yaar Schnitman  <yaar@chromium.org>
 
         Reviewed by Dimitri Glazkov.
diff --git a/WebKit/chromium/src/DOMUtilitiesPrivate.cpp b/WebKit/chromium/src/DOMUtilitiesPrivate.cpp
new file mode 100644 (file)
index 0000000..e84d4fb
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "DOMUtilitiesPrivate.h"
+
+#include "Element.h"
+#include "HTMLInputElement.h"
+#include "HTMLLinkElement.h"
+#include "HTMLMetaElement.h"
+#include "HTMLNames.h"
+#include "HTMLOptionElement.h"
+#include "Node.h"
+
+using namespace WebCore;
+
+namespace {
+
+template <class HTMLNodeType>
+HTMLNodeType* toHTMLElement(Node* node, const QualifiedName& name)
+{
+    if (node->isHTMLElement()
+        && static_cast<HTMLElement*>(node)->hasTagName(name)) {
+        return static_cast<HTMLNodeType*>(node);
+    }
+    return 0;
+}
+
+} // namespace
+
+namespace WebKit {
+
+HTMLInputElement* toHTMLInputElement(Node* node)
+{
+    return toHTMLElement<HTMLInputElement>(node, HTMLNames::inputTag);
+}
+
+HTMLLinkElement* toHTMLLinkElement(Node* node)
+{
+    return toHTMLElement<HTMLLinkElement>(node, HTMLNames::linkTag);
+}
+
+HTMLMetaElement* toHTMLMetaElement(Node* node)
+{
+    return toHTMLElement<HTMLMetaElement>(node, HTMLNames::metaTag);
+}
+
+HTMLOptionElement* toHTMLOptionElement(Node* node)
+{
+    return toHTMLElement<HTMLOptionElement>(node, HTMLNames::optionTag);
+}
+
+String nameOfInputElement(HTMLInputElement* element)
+{
+    String name = element->name();
+    String trimmedName = name.stripWhiteSpace();
+    if (!trimmedName.isEmpty())
+        return trimmedName;
+
+    name = element->getAttribute(HTMLNames::idAttr);
+    trimmedName = name.stripWhiteSpace();
+    if (!trimmedName.isEmpty())
+        return trimmedName;
+
+    return String();
+}
+
+} // namespace WebKit
diff --git a/WebKit/chromium/src/DOMUtilitiesPrivate.h b/WebKit/chromium/src/DOMUtilitiesPrivate.h
new file mode 100644 (file)
index 0000000..c701d0a
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DOMUtilitiesPrivate_h
+#define DOMUtilitiesPrivate_h
+
+namespace WebCore {
+class HTMLInputElement;
+class HTMLLinkElement;
+class HTMLMetaElement;
+class HTMLOptionElement;
+class Node;
+class String;
+}
+
+// This file is an aggregate of useful WebCore operations.
+namespace WebKit {
+
+// If node is an HTML node with a tag name of name it is casted and returned.
+// If node is not an HTML node or the tag name is not name, 0 is returned.
+WebCore::HTMLInputElement* toHTMLInputElement(WebCore::Node*);
+WebCore::HTMLLinkElement* toHTMLLinkElement(WebCore::Node*);
+WebCore::HTMLMetaElement* toHTMLMetaElement(WebCore::Node*);
+WebCore::HTMLOptionElement* toHTMLOptionElement(WebCore::Node*);
+
+// Returns the name that should be used for the specified |element| when
+// storing autofill data.  This is either the field name or its id, an empty
+// string if it has no name and no id.
+WebCore::String nameOfInputElement(WebCore::HTMLInputElement*);
+
+} // namespace WebKit
+
+#endif
diff --git a/WebKit/chromium/src/DragClientImpl.cpp b/WebKit/chromium/src/DragClientImpl.cpp
new file mode 100644 (file)
index 0000000..5d8a9c3
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "DragClientImpl.h"
+
+#include "ChromiumDataObject.h"
+#include "ClipboardChromium.h"
+#include "Frame.h"
+#include "WebDragData.h"
+#include "WebViewClient.h"
+#include "WebViewImpl.h"
+
+using namespace WebCore;
+
+namespace WebKit {
+
+void DragClientImpl::willPerformDragDestinationAction(DragDestinationAction, DragData*)
+{
+    // FIXME
+}
+
+void DragClientImpl::willPerformDragSourceAction(DragSourceAction, const IntPoint&, Clipboard*)
+{
+    // FIXME
+}
+
+DragDestinationAction DragClientImpl::actionMaskForDrag(DragData*)
+{
+    if (m_webView->client() && m_webView->client()->acceptsLoadDrops())
+        return DragDestinationActionAny;
+
+    return static_cast<DragDestinationAction>(
+        DragDestinationActionDHTML | DragDestinationActionEdit);
+}
+
+DragSourceAction DragClientImpl::dragSourceActionMaskForPoint(const IntPoint& windowPoint)
+{
+    // We want to handle drag operations for all source types.
+    return DragSourceActionAny;
+}
+
+void DragClientImpl::startDrag(DragImageRef dragImage,
+                               const IntPoint& dragImageOrigin,
+                               const IntPoint& eventPos,
+                               Clipboard* clipboard,
+                               Frame* frame,
+                               bool isLinkDrag)
+{
+    // Add a ref to the frame just in case a load occurs mid-drag.
+    RefPtr<Frame> frameProtector = frame;
+
+    WebDragData dragData = static_cast<ClipboardChromium*>(clipboard)->dataObject();
+
+    DragOperation dragOperationMask;
+    if (!clipboard->sourceOperation(dragOperationMask))
+        dragOperationMask = DragOperationEvery;
+
+    m_webView->startDragging(
+        eventPos, dragData, static_cast<WebDragOperationsMask>(dragOperationMask));
+}
+
+DragImageRef DragClientImpl::createDragImageForLink(KURL&, const String& label, Frame*)
+{
+    // FIXME
+    return 0;
+}
+
+void DragClientImpl::dragControllerDestroyed()
+{
+    // Our lifetime is bound to the WebViewImpl.
+}
+
+} // namespace WebKit
diff --git a/WebKit/chromium/src/DragClientImpl.h b/WebKit/chromium/src/DragClientImpl.h
new file mode 100644 (file)
index 0000000..fc4c608
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DragClientImpl_h
+#define DragClientImpl_h
+
+#include "DragActions.h"
+#include "DragClient.h"
+
+namespace WebCore {
+class ClipBoard;
+class DragData;
+class IntPoint;
+class KURL;
+}
+
+namespace WebKit {
+class WebViewImpl;
+
+class DragClientImpl : public WebCore::DragClient {
+public:
+    DragClientImpl(WebViewImpl* webView) : m_webView(webView) { }
+
+    virtual void willPerformDragDestinationAction(
+        WebCore::DragDestinationAction, WebCore::DragData*);
+    virtual void willPerformDragSourceAction(
+        WebCore::DragSourceAction, const WebCore::IntPoint&, WebCore::Clipboard*);
+    virtual WebCore::DragDestinationAction actionMaskForDrag(WebCore::DragData*);
+    virtual WebCore::DragSourceAction dragSourceActionMaskForPoint(
+        const WebCore::IntPoint& windowPoint);
+    virtual void startDrag(
+        WebCore::DragImageRef dragImage,
+        const WebCore::IntPoint& dragImageOrigin,
+        const WebCore::IntPoint& eventPos,
+        WebCore::Clipboard* clipboard,
+        WebCore::Frame* frame,
+        bool isLinkDrag = false);
+    virtual WebCore::DragImageRef createDragImageForLink(
+        WebCore::KURL&, const WebCore::String& label, WebCore::Frame*);
+    virtual void dragControllerDestroyed();
+
+private:
+    WebViewImpl* m_webView;
+};
+
+} // namespace WebKit
+
+#endif
diff --git a/WebKit/chromium/src/EditorClientImpl.cpp b/WebKit/chromium/src/EditorClientImpl.cpp
new file mode 100644 (file)
index 0000000..d84ce12
--- /dev/null
@@ -0,0 +1,921 @@
+/*
+ * Copyright (C) 2006, 2007 Apple, Inc.  All rights reserved.
+ * Copyright (C) 2009 Google, Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "EditorClientImpl.h"
+
+#include "Document.h"
+#include "EditCommand.h"
+#include "Editor.h"
+#include "EventHandler.h"
+#include "EventNames.h"
+#include "Frame.h"
+#include "HTMLInputElement.h"
+#include "HTMLNames.h"
+#include "KeyboardCodes.h"
+#include "KeyboardEvent.h"
+#include "PlatformKeyboardEvent.h"
+#include "PlatformString.h"
+#include "RenderObject.h"
+
+#include "DOMUtilitiesPrivate.h"
+#include "WebEditingAction.h"
+#include "WebFrameImpl.h"
+#include "WebKit.h"
+#include "WebNode.h"
+#include "WebPasswordAutocompleteListener.h"
+#include "WebRange.h"
+#include "WebTextAffinity.h"
+#include "WebViewClient.h"
+#include "WebViewImpl.h"
+
+using namespace WebCore;
+
+namespace WebKit {
+
+// Arbitrary depth limit for the undo stack, to keep it from using
+// unbounded memory.  This is the maximum number of distinct undoable
+// actions -- unbroken stretches of typed characters are coalesced
+// into a single action.
+static const size_t maximumUndoStackDepth = 1000;
+
+// The size above which we stop triggering autofill for an input text field
+// (so to avoid sending long strings through IPC).
+static const size_t maximumTextSizeForAutofill = 1000;
+
+EditorClientImpl::EditorClientImpl(WebViewImpl* webview)
+    : m_webView(webview)
+    , m_inRedo(false)
+    , m_backspaceOrDeletePressed(false)
+    , m_spellCheckThisFieldStatus(SpellCheckAutomatic)
+    , m_autofillTimer(this, &EditorClientImpl::doAutofill)
+{
+}
+
+EditorClientImpl::~EditorClientImpl()
+{
+}
+
+void EditorClientImpl::pageDestroyed()
+{
+    // Our lifetime is bound to the WebViewImpl.
+}
+
+bool EditorClientImpl::shouldShowDeleteInterface(HTMLElement* elem)
+{
+    // Normally, we don't care to show WebCore's deletion UI, so we only enable
+    // it if in testing mode and the test specifically requests it by using this
+    // magic class name.
+    return WebKit::layoutTestMode()
+           && elem->getAttribute(HTMLNames::classAttr) == "needsDeletionUI";
+}
+
+bool EditorClientImpl::smartInsertDeleteEnabled()
+{
+    if (m_webView->client())
+        return m_webView->client()->isSmartInsertDeleteEnabled();
+    return true;
+}
+
+bool EditorClientImpl::isSelectTrailingWhitespaceEnabled()
+{
+    if (m_webView->client())
+        return m_webView->client()->isSelectTrailingWhitespaceEnabled();
+#if PLATFORM(WIN_OS)
+    return true;
+#else
+    return false;
+#endif
+}
+
+bool EditorClientImpl::shouldSpellcheckByDefault()
+{
+    // Spellcheck should be enabled for all editable areas (such as textareas,
+    // contentEditable regions, and designMode docs), except text inputs.
+    const Frame* frame = m_webView->focusedWebCoreFrame();
+    if (!frame)
+        return false;
+    const Editor* editor = frame->editor();
+    if (!editor)
+        return false;
+    if (editor->spellCheckingEnabledInFocusedNode())
+        return true;
+    const Document* document = frame->document();
+    if (!document)
+        return false;
+    const Node* node = document->focusedNode();
+    // If |node| is null, we default to allowing spellchecking. This is done in
+    // order to mitigate the issue when the user clicks outside the textbox, as a
+    // result of which |node| becomes null, resulting in all the spell check
+    // markers being deleted. Also, the Frame will decide not to do spellchecking
+    // if the user can't edit - so returning true here will not cause any problems
+    // to the Frame's behavior.
+    if (!node)
+        return true;
+    const RenderObject* renderer = node->renderer();
+    if (!renderer)
+        return false;
+
+    return !renderer->isTextField();
+}
+
+bool EditorClientImpl::isContinuousSpellCheckingEnabled()
+{
+    if (m_spellCheckThisFieldStatus == SpellCheckForcedOff)
+        return false;
+    if (m_spellCheckThisFieldStatus == SpellCheckForcedOn)
+        return true;
+    return shouldSpellcheckByDefault();
+}
+
+void EditorClientImpl::toggleContinuousSpellChecking()
+{
+    if (isContinuousSpellCheckingEnabled())
+        m_spellCheckThisFieldStatus = SpellCheckForcedOff;
+    else
+        m_spellCheckThisFieldStatus = SpellCheckForcedOn;
+}
+
+bool EditorClientImpl::isGrammarCheckingEnabled()
+{
+    return false;
+}
+
+void EditorClientImpl::toggleGrammarChecking()
+{
+    notImplemented();
+}
+
+int EditorClientImpl::spellCheckerDocumentTag()
+{
+    ASSERT_NOT_REACHED();
+    return 0;
+}
+
+bool EditorClientImpl::isEditable()
+{
+    return false;
+}
+
+bool EditorClientImpl::shouldBeginEditing(Range* range)
+{
+    if (m_webView->client())
+        return m_webView->client()->shouldBeginEditing(WebRange(range));
+    return true;
+}
+
+bool EditorClientImpl::shouldEndEditing(Range* range)
+{
+    if (m_webView->client())
+        return m_webView->client()->shouldEndEditing(WebRange(range));
+    return true;
+}
+
+bool EditorClientImpl::shouldInsertNode(Node* node,
+                                        Range* range,
+                                        EditorInsertAction action)
+{
+    if (m_webView->client()) {
+        return m_webView->client()->shouldInsertNode(WebNode(node),
+                                                     WebRange(range),
+                                                     static_cast<WebEditingAction>(action));
+    }
+    return true;
+}
+
+bool EditorClientImpl::shouldInsertText(const String& text,
+                                        Range* range,
+                                        EditorInsertAction action)
+{
+    if (m_webView->client()) {
+        return m_webView->client()->shouldInsertText(WebString(text),
+                                                     WebRange(range),
+                                                     static_cast<WebEditingAction>(action));
+    }
+    return true;
+}
+
+
+bool EditorClientImpl::shouldDeleteRange(Range* range)
+{
+    if (m_webView->client())
+        return m_webView->client()->shouldDeleteRange(WebRange(range));
+    return true;
+}
+
+bool EditorClientImpl::shouldChangeSelectedRange(Range* fromRange,
+                                                 Range* toRange,
+                                                 EAffinity affinity,
+                                                 bool stillSelecting)
+{
+    if (m_webView->client()) {
+        return m_webView->client()->shouldChangeSelectedRange(WebRange(fromRange),
+                                                              WebRange(toRange),
+                                                              static_cast<WebTextAffinity>(affinity),
+                                                              stillSelecting);
+    }
+    return true;
+}
+
+bool EditorClientImpl::shouldApplyStyle(CSSStyleDeclaration* style,
+                                        Range* range)
+{
+    if (m_webView->client()) {
+        // FIXME: Pass a reference to the CSSStyleDeclaration somehow.
+        return m_webView->client()->shouldApplyStyle(WebString(),
+                                                     WebRange(range));
+    }
+    return true;
+}
+
+bool EditorClientImpl::shouldMoveRangeAfterDelete(Range* range,
+                                                  Range* rangeToBeReplaced)
+{
+    return true;
+}
+
+void EditorClientImpl::didBeginEditing()
+{
+    if (m_webView->client())
+        m_webView->client()->didBeginEditing();
+}
+
+void EditorClientImpl::respondToChangedSelection()
+{
+    if (m_webView->client()) {
+        Frame* frame = m_webView->focusedWebCoreFrame();
+        if (frame)
+            m_webView->client()->didChangeSelection(!frame->selection()->isRange());
+    }
+}
+
+void EditorClientImpl::respondToChangedContents()
+{
+    if (m_webView->client())
+        m_webView->client()->didChangeContents();
+}
+
+void EditorClientImpl::didEndEditing()
+{
+    if (m_webView->client())
+        m_webView->client()->didEndEditing();
+}
+
+void EditorClientImpl::didWriteSelectionToPasteboard()
+{
+}
+
+void EditorClientImpl::didSetSelectionTypesForPasteboard()
+{
+}
+
+void EditorClientImpl::registerCommandForUndo(PassRefPtr<EditCommand> command)
+{
+    if (m_undoStack.size() == maximumUndoStackDepth)
+        m_undoStack.removeFirst(); // drop oldest item off the far end
+    if (!m_inRedo)
+        m_redoStack.clear();
+    m_undoStack.append(command);
+}
+
+void EditorClientImpl::registerCommandForRedo(PassRefPtr<EditCommand> command)
+{
+    m_redoStack.append(command);
+}
+
+void EditorClientImpl::clearUndoRedoOperations()
+{
+    m_undoStack.clear();
+    m_redoStack.clear();
+}
+
+bool EditorClientImpl::canUndo() const
+{
+    return !m_undoStack.isEmpty();
+}
+
+bool EditorClientImpl::canRedo() const
+{
+    return !m_redoStack.isEmpty();
+}
+
+void EditorClientImpl::undo()
+{
+    if (canUndo()) {
+        EditCommandStack::iterator back = --m_undoStack.end();
+        RefPtr<EditCommand> command(*back);
+        m_undoStack.remove(back);
+        command->unapply();
+        // unapply will call us back to push this command onto the redo stack.
+    }
+}
+
+void EditorClientImpl::redo()
+{
+    if (canRedo()) {
+        EditCommandStack::iterator back = --m_redoStack.end();
+        RefPtr<EditCommand> command(*back);
+        m_redoStack.remove(back);
+
+        ASSERT(!m_inRedo);
+        m_inRedo = true;
+        command->reapply();
+        // reapply will call us back to push this command onto the undo stack.
+        m_inRedo = false;
+    }
+}
+
+//
+// The below code was adapted from the WebKit file webview.cpp
+//
+
+static const unsigned CtrlKey = 1 << 0;
+static const unsigned AltKey = 1 << 1;
+static const unsigned ShiftKey = 1 << 2;
+static const unsigned MetaKey = 1 << 3;
+#if PLATFORM(DARWIN)
+// Aliases for the generic key defintions to make kbd shortcuts definitions more
+// readable on OS X.
+static const unsigned OptionKey  = AltKey;
+
+// Do not use this constant for anything but cursor movement commands. Keys
+// with cmd set have their |isSystemKey| bit set, so chances are the shortcut
+// will not be executed. Another, less important, reason is that shortcuts
+// defined in the renderer do not blink the menu item that they triggered.  See
+// http://crbug.com/25856 and the bugs linked from there for details.
+static const unsigned CommandKey = MetaKey;
+#endif
+
+// Keys with special meaning. These will be delegated to the editor using
+// the execCommand() method
+struct KeyDownEntry {
+    unsigned virtualKey;
+    unsigned modifiers;
+    const char* name;
+};
+
+struct KeyPressEntry {
+    unsigned charCode;
+    unsigned modifiers;
+    const char* name;
+};
+
+static const KeyDownEntry keyDownEntries[] = {
+    { VKEY_LEFT,   0,                  "MoveLeft"                             },
+    { VKEY_LEFT,   ShiftKey,           "MoveLeftAndModifySelection"           },
+#if PLATFORM(DARWIN)
+    { VKEY_LEFT,   OptionKey,          "MoveWordLeft"                         },
+    { VKEY_LEFT,   OptionKey | ShiftKey,
+        "MoveWordLeftAndModifySelection"                                      },
+#else
+    { VKEY_LEFT,   CtrlKey,            "MoveWordLeft"                         },
+    { VKEY_LEFT,   CtrlKey | ShiftKey,
+        "MoveWordLeftAndModifySelection"                                      },
+#endif
+    { VKEY_RIGHT,  0,                  "MoveRight"                            },
+    { VKEY_RIGHT,  ShiftKey,           "MoveRightAndModifySelection"          },
+#if PLATFORM(DARWIN)
+    { VKEY_RIGHT,  OptionKey,          "MoveWordRight"                        },
+    { VKEY_RIGHT,  OptionKey | ShiftKey,
+      "MoveWordRightAndModifySelection"                                       },
+#else
+    { VKEY_RIGHT,  CtrlKey,            "MoveWordRight"                        },
+    { VKEY_RIGHT,  CtrlKey | ShiftKey,
+      "MoveWordRightAndModifySelection"                                       },
+#endif
+    { VKEY_UP,     0,                  "MoveUp"                               },
+    { VKEY_UP,     ShiftKey,           "MoveUpAndModifySelection"             },
+    { VKEY_PRIOR,  ShiftKey,           "MovePageUpAndModifySelection"         },
+    { VKEY_DOWN,   0,                  "MoveDown"                             },
+    { VKEY_DOWN,   ShiftKey,           "MoveDownAndModifySelection"           },
+    { VKEY_NEXT,   ShiftKey,           "MovePageDownAndModifySelection"       },
+    { VKEY_PRIOR,  0,                  "MovePageUp"                           },
+    { VKEY_NEXT,   0,                  "MovePageDown"                         },
+    { VKEY_HOME,   0,                  "MoveToBeginningOfLine"                },
+    { VKEY_HOME,   ShiftKey,
+        "MoveToBeginningOfLineAndModifySelection"                             },
+#if PLATFORM(DARWIN)
+    { VKEY_LEFT,   CommandKey,         "MoveToBeginningOfLine"                },
+    { VKEY_LEFT,   CommandKey | ShiftKey,
+      "MoveToBeginningOfLineAndModifySelection"                               },
+#endif
+#if PLATFORM(DARWIN)
+    { VKEY_UP,     CommandKey,         "MoveToBeginningOfDocument"            },
+    { VKEY_UP,     CommandKey | ShiftKey,
+        "MoveToBeginningOfDocumentAndModifySelection"                         },
+#else
+    { VKEY_HOME,   CtrlKey,            "MoveToBeginningOfDocument"            },
+    { VKEY_HOME,   CtrlKey | ShiftKey,
+        "MoveToBeginningOfDocumentAndModifySelection"                         },
+#endif
+    { VKEY_END,    0,                  "MoveToEndOfLine"                      },
+    { VKEY_END,    ShiftKey,           "MoveToEndOfLineAndModifySelection"    },
+#if PLATFORM(DARWIN)
+    { VKEY_DOWN,   CommandKey,         "MoveToEndOfDocument"                  },
+    { VKEY_DOWN,   CommandKey | ShiftKey,
+        "MoveToEndOfDocumentAndModifySelection"                               },
+#else
+    { VKEY_END,    CtrlKey,            "MoveToEndOfDocument"                  },
+    { VKEY_END,    CtrlKey | ShiftKey,
+        "MoveToEndOfDocumentAndModifySelection"                               },
+#endif
+#if PLATFORM(DARWIN)
+    { VKEY_RIGHT,  CommandKey,         "MoveToEndOfLine"                      },
+    { VKEY_RIGHT,  CommandKey | ShiftKey,
+        "MoveToEndOfLineAndModifySelection"                                   },
+#endif
+    { VKEY_BACK,   0,                  "DeleteBackward"                       },
+    { VKEY_BACK,   ShiftKey,           "DeleteBackward"                       },
+    { VKEY_DELETE, 0,                  "DeleteForward"                        },
+#if PLATFORM(DARWIN)
+    { VKEY_BACK,   OptionKey,          "DeleteWordBackward"                   },
+    { VKEY_DELETE, OptionKey,          "DeleteWordForward"                    },
+#else
+    { VKEY_BACK,   CtrlKey,            "DeleteWordBackward"                   },
+    { VKEY_DELETE, CtrlKey,            "DeleteWordForward"                    },
+#endif
+    { 'B',         CtrlKey,            "ToggleBold"                           },
+    { 'I',         CtrlKey,            "ToggleItalic"                         },
+    { 'U',         CtrlKey,            "ToggleUnderline"                      },
+    { VKEY_ESCAPE, 0,                  "Cancel"                               },
+    { VKEY_OEM_PERIOD, CtrlKey,        "Cancel"                               },
+    { VKEY_TAB,    0,                  "InsertTab"                            },
+    { VKEY_TAB,    ShiftKey,           "InsertBacktab"                        },
+    { VKEY_RETURN, 0,                  "InsertNewline"                        },
+    { VKEY_RETURN, CtrlKey,            "InsertNewline"                        },
+    { VKEY_RETURN, AltKey,             "InsertNewline"                        },
+    { VKEY_RETURN, AltKey | ShiftKey,  "InsertNewline"                        },
+    { VKEY_RETURN, ShiftKey,           "InsertLineBreak"                      },
+    { VKEY_INSERT, CtrlKey,            "Copy"                                 },
+    { VKEY_INSERT, ShiftKey,           "Paste"                                },
+    { VKEY_DELETE, ShiftKey,           "Cut"                                  },
+#if !PLATFORM(DARWIN)
+    // On OS X, we pipe these back to the browser, so that it can do menu item
+    // blinking.
+    { 'C',         CtrlKey,            "Copy"                                 },
+    { 'V',         CtrlKey,            "Paste"                                },
+    { 'V',         CtrlKey | ShiftKey, "PasteAndMatchStyle"                   },
+    { 'X',         CtrlKey,            "Cut"                                  },
+    { 'A',         CtrlKey,            "SelectAll"                            },
+    { 'Z',         CtrlKey,            "Undo"                                 },
+    { 'Z',         CtrlKey | ShiftKey, "Redo"                                 },
+    { 'Y',         CtrlKey,            "Redo"                                 },
+#endif
+};
+
+static const KeyPressEntry keyPressEntries[] = {
+    { '\t',   0,                  "InsertTab"                                 },
+    { '\t',   ShiftKey,           "InsertBacktab"                             },
+    { '\r',   0,                  "InsertNewline"                             },
+    { '\r',   CtrlKey,            "InsertNewline"                             },
+    { '\r',   ShiftKey,           "InsertLineBreak"                           },
+    { '\r',   AltKey,             "InsertNewline"                             },
+    { '\r',   AltKey | ShiftKey,  "InsertNewline"                             },
+};
+
+const char* EditorClientImpl::interpretKeyEvent(const KeyboardEvent* evt)
+{
+    const PlatformKeyboardEvent* keyEvent = evt->keyEvent();
+    if (!keyEvent)
+        return "";
+
+    static HashMap<int, const char*>* keyDownCommandsMap = 0;
+    static HashMap<int, const char*>* keyPressCommandsMap = 0;
+
+    if (!keyDownCommandsMap) {
+        keyDownCommandsMap = new HashMap<int, const char*>;
+        keyPressCommandsMap = new HashMap<int, const char*>;
+
+        for (unsigned i = 0; i < arraysize(keyDownEntries); i++) {
+            keyDownCommandsMap->set(keyDownEntries[i].modifiers << 16 | keyDownEntries[i].virtualKey,
+                                    keyDownEntries[i].name);
+        }
+
+        for (unsigned i = 0; i < arraysize(keyPressEntries); i++) {
+            keyPressCommandsMap->set(keyPressEntries[i].modifiers << 16 | keyPressEntries[i].charCode,
+                                     keyPressEntries[i].name);
+        }
+    }
+
+    unsigned modifiers = 0;
+    if (keyEvent->shiftKey())
+        modifiers |= ShiftKey;
+    if (keyEvent->altKey())
+        modifiers |= AltKey;
+    if (keyEvent->ctrlKey())
+        modifiers |= CtrlKey;
+    if (keyEvent->metaKey())
+        modifiers |= MetaKey;
+
+    if (keyEvent->type() == PlatformKeyboardEvent::RawKeyDown) {
+        int mapKey = modifiers << 16 | evt->keyCode();
+        return mapKey ? keyDownCommandsMap->get(mapKey) : 0;
+    }
+
+    int mapKey = modifiers << 16 | evt->charCode();
+    return mapKey ? keyPressCommandsMap->get(mapKey) : 0;
+}
+
+bool EditorClientImpl::handleEditingKeyboardEvent(KeyboardEvent* evt)
+{
+    const PlatformKeyboardEvent* keyEvent = evt->keyEvent();
+    // do not treat this as text input if it's a system key event
+    if (!keyEvent || keyEvent->isSystemKey())
+        return false;
+
+    Frame* frame = evt->target()->toNode()->document()->frame();
+    if (!frame)
+        return false;
+
+    String commandName = interpretKeyEvent(evt);
+    Editor::Command command = frame->editor()->command(commandName);
+
+    if (keyEvent->type() == PlatformKeyboardEvent::RawKeyDown) {
+        // WebKit doesn't have enough information about mode to decide how
+        // commands that just insert text if executed via Editor should be treated,
+        // so we leave it upon WebCore to either handle them immediately
+        // (e.g. Tab that changes focus) or let a keypress event be generated
+        // (e.g. Tab that inserts a Tab character, or Enter).
+        if (command.isTextInsertion() || commandName.isEmpty())
+            return false;
+        if (command.execute(evt)) {
+            if (m_webView->client())
+                m_webView->client()->didExecuteCommand(WebString(commandName));
+            return true;
+        }
+        return false;
+    }
+
+    if (command.execute(evt)) {
+        if (m_webView->client())
+            m_webView->client()->didExecuteCommand(WebString(commandName));
+        return true;
+    }
+
+    // Here we need to filter key events.
+    // On Gtk/Linux, it emits key events with ASCII text and ctrl on for ctrl-<x>.
+    // In Webkit, EditorClient::handleKeyboardEvent in
+    // WebKit/gtk/WebCoreSupport/EditorClientGtk.cpp drop such events.
+    // On Mac, it emits key events with ASCII text and meta on for Command-<x>.
+    // These key events should not emit text insert event.
+    // Alt key would be used to insert alternative character, so we should let
+    // through. Also note that Ctrl-Alt combination equals to AltGr key which is
+    // also used to insert alternative character.
+    // http://code.google.com/p/chromium/issues/detail?id=10846
+    // Windows sets both alt and meta are on when "Alt" key pressed.
+    // http://code.google.com/p/chromium/issues/detail?id=2215
+    // Also, we should not rely on an assumption that keyboards don't
+    // send ASCII characters when pressing a control key on Windows,
+    // which may be configured to do it so by user.
+    // See also http://en.wikipedia.org/wiki/Keyboard_Layout
+    // FIXME(ukai): investigate more detail for various keyboard layout.
+    if (evt->keyEvent()->text().length() == 1) {
+        UChar ch = evt->keyEvent()->text()[0U];
+
+        // Don't insert null or control characters as they can result in
+        // unexpected behaviour
+        if (ch < ' ')
+            return false;
+#if !PLATFORM(WIN_OS)
+        // Don't insert ASCII character if ctrl w/o alt or meta is on.
+        // On Mac, we should ignore events when meta is on (Command-<x>).
+        if (ch < 0x80) {
+            if (evt->keyEvent()->ctrlKey() && !evt->keyEvent()->altKey())
+                return false;
+#if PLATFORM(DARWIN)
+            if (evt->keyEvent()->metaKey())
+            return false;
+#endif
+        }
+#endif
+    }
+
+    if (!frame->editor()->canEdit())
+        return false;
+
+    return frame->editor()->insertText(evt->keyEvent()->text(), evt);
+}
+
+void EditorClientImpl::handleKeyboardEvent(KeyboardEvent* evt)
+{
+    if (evt->keyCode() == VKEY_DOWN
+        || evt->keyCode() == VKEY_UP) {
+        ASSERT(evt->target()->toNode());
+        showFormAutofillForNode(evt->target()->toNode());
+    }
+
+    // Give the embedder a chance to handle the keyboard event.
+    if ((m_webView->client()
+         && m_webView->client()->handleCurrentKeyboardEvent())
+        || handleEditingKeyboardEvent(evt))
+        evt->setDefaultHandled();
+}
+
+void EditorClientImpl::handleInputMethodKeydown(KeyboardEvent* keyEvent)
+{
+    // We handle IME within chrome.
+}
+
+void EditorClientImpl::textFieldDidBeginEditing(Element*)
+{
+}
+
+void EditorClientImpl::textFieldDidEndEditing(Element* element)
+{
+    // Notification that focus was lost.  Be careful with this, it's also sent
+    // when the page is being closed.
+
+    // Cancel any pending DoAutofill call.
+    m_autofillArgs.clear();
+    m_autofillTimer.stop();
+
+    // Hide any showing popup.
+    m_webView->hideAutoCompletePopup();
+
+    if (!m_webView->client())
+        return; // The page is getting closed, don't fill the password.
+
+    // Notify any password-listener of the focus change.
+    HTMLInputElement* inputElement = WebKit::toHTMLInputElement(element);
+    if (!inputElement)
+        return;
+
+    WebFrameImpl* webframe = WebFrameImpl::fromFrame(inputElement->document()->frame());
+    if (!webframe)
+        return;
+
+    WebPasswordAutocompleteListener* listener = webframe->getPasswordListener(inputElement);
+    if (!listener)
+        return;
+
+    listener->didBlurInputElement(inputElement->value());
+}
+
+void EditorClientImpl::textDidChangeInTextField(Element* element)
+{
+    ASSERT(element->hasLocalName(HTMLNames::inputTag));
+    // Note that we only show the autofill popup in this case if the caret is at
+    // the end.  This matches FireFox and Safari but not IE.
+    autofill(static_cast<HTMLInputElement*>(element), false, false,
+             true);
+}
+
+bool EditorClientImpl::showFormAutofillForNode(Node* node)
+{
+    HTMLInputElement* inputElement = WebKit::toHTMLInputElement(node);
+    if (inputElement)
+        return autofill(inputElement, true, true, false);
+    return false;
+}
+
+bool EditorClientImpl::autofill(HTMLInputElement* inputElement,
+                                bool autofillFormOnly,
+                                bool autofillOnEmptyValue,
+                                bool requireCaretAtEnd)
+{
+    // Cancel any pending DoAutofill call.
+    m_autofillArgs.clear();
+    m_autofillTimer.stop();
+
+    // Let's try to trigger autofill for that field, if applicable.
+    if (!inputElement->isEnabledFormControl() || !inputElement->isTextField()
+        || inputElement->isPasswordField()
+        || !inputElement->autoComplete())
+        return false;
+
+    WebString name = WebKit::nameOfInputElement(inputElement);
+    if (name.isEmpty()) // If the field has no name, then we won't have values.
+        return false;
+
+    // Don't attempt to autofill with values that are too large.
+    if (inputElement->value().length() > maximumTextSizeForAutofill)
+        return false;
+
+    m_autofillArgs = new AutofillArgs();
+    m_autofillArgs->inputElement = inputElement;
+    m_autofillArgs->autofillFormOnly = autofillFormOnly;
+    m_autofillArgs->autofillOnEmptyValue = autofillOnEmptyValue;
+    m_autofillArgs->requireCaretAtEnd = requireCaretAtEnd;
+    m_autofillArgs->backspaceOrDeletePressed = m_backspaceOrDeletePressed;
+
+    if (!requireCaretAtEnd)
+        doAutofill(0);
+    else {
+        // We post a task for doing the autofill as the caret position is not set
+        // properly at this point (http://bugs.webkit.org/show_bug.cgi?id=16976)
+        // and we need it to determine whether or not to trigger autofill.
+        m_autofillTimer.startOneShot(0.0);
+    }
+    return true;
+}
+
+void EditorClientImpl::doAutofill(Timer<EditorClientImpl>* timer)
+{
+    OwnPtr<AutofillArgs> args(m_autofillArgs.release());
+    HTMLInputElement* inputElement = args->inputElement.get();
+
+    const String& value = inputElement->value();
+
+    // Enforce autofill_on_empty_value and caret_at_end.
+
+    bool isCaretAtEnd = true;
+    if (args->requireCaretAtEnd)
+        isCaretAtEnd = inputElement->selectionStart() == inputElement->selectionEnd()
+                       && inputElement->selectionEnd() == static_cast<int>(value.length());
+
+    if ((!args->autofillOnEmptyValue && value.isEmpty()) || !isCaretAtEnd) {
+        m_webView->hideAutoCompletePopup();
+        return;
+    }
+
+    // First let's see if there is a password listener for that element.
+    // We won't trigger form autofill in that case, as having both behavior on
+    // a node would be confusing.
+    WebFrameImpl* webframe = WebFrameImpl::fromFrame(inputElement->document()->frame());
+    if (!webframe)
+        return;
+    WebPasswordAutocompleteListener* listener = webframe->getPasswordListener(inputElement);
+    if (listener) {
+        if (args->autofillFormOnly)
+            return;
+
+        listener->performInlineAutocomplete(value,
+                                            args->backspaceOrDeletePressed,
+                                            true);
+        return;
+    }
+
+    // Then trigger form autofill.
+    WebString name = WebKit::nameOfInputElement(inputElement);
+    ASSERT(static_cast<int>(name.length()) > 0);
+
+    if (m_webView->client())
+        m_webView->client()->queryAutofillSuggestions(WebNode(inputElement),
+                                                      name, WebString(value));
+}
+
+void EditorClientImpl::cancelPendingAutofill()
+{
+    m_autofillArgs.clear();
+    m_autofillTimer.stop();
+}
+
+void EditorClientImpl::onAutofillSuggestionAccepted(HTMLInputElement* textField)
+{
+    WebFrameImpl* webframe = WebFrameImpl::fromFrame(textField->document()->frame());
+    if (!webframe)
+        return;
+
+    WebPasswordAutocompleteListener* listener = webframe->getPasswordListener(textField);
+    // Password listeners need to autocomplete other fields that depend on the
+    // input element with autofill suggestions.
+    if (listener)
+        listener->performInlineAutocomplete(textField->value(), false, false);
+}
+
+bool EditorClientImpl::doTextFieldCommandFromEvent(Element* element,
+                                                   KeyboardEvent* event)
+{
+    // Remember if backspace was pressed for the autofill.  It is not clear how to
+    // find if backspace was pressed from textFieldDidBeginEditing and
+    // textDidChangeInTextField as when these methods are called the value of the
+    // input element already contains the type character.
+    m_backspaceOrDeletePressed = event->keyCode() == VKEY_BACK || event->keyCode() == VKEY_DELETE;
+
+    // The Mac code appears to use this method as a hook to implement special
+    // keyboard commands specific to Safari's auto-fill implementation.  We
+    // just return false to allow the default action.
+    return false;
+}
+
+void EditorClientImpl::textWillBeDeletedInTextField(Element*)
+{
+}
+
+void EditorClientImpl::textDidChangeInTextArea(Element*)
+{
+}
+
+void EditorClientImpl::ignoreWordInSpellDocument(const String&)
+{
+    notImplemented();
+}
+
+void EditorClientImpl::learnWord(const String&)
+{
+    notImplemented();
+}
+
+void EditorClientImpl::checkSpellingOfString(const UChar* text, int length,
+                                             int* misspellingLocation,
+                                             int* misspellingLength)
+{
+    // SpellCheckWord will write (0, 0) into the output vars, which is what our
+    // caller expects if the word is spelled correctly.
+    int spellLocation = -1;
+    int spellLength = 0;
+
+    // Check to see if the provided text is spelled correctly.
+    if (isContinuousSpellCheckingEnabled() && m_webView->client())
+        m_webView->client()->spellCheck(WebString(text, length), spellLocation, spellLength);
+    else {
+        spellLocation = 0;
+        spellLength = 0;
+    }
+
+    // Note: the Mac code checks if the pointers are null before writing to them,
+    // so we do too.
+    if (misspellingLocation)
+        *misspellingLocation = spellLocation;
+    if (misspellingLength)
+        *misspellingLength = spellLength;
+}
+
+String EditorClientImpl::getAutoCorrectSuggestionForMisspelledWord(const String& misspelledWord)
+{
+    if (!(isContinuousSpellCheckingEnabled() && m_webView->client()))
+        return String();
+
+    // Do not autocorrect words with capital letters in it except the
+    // first letter. This will remove cases changing "IMB" to "IBM".
+    for (size_t i = 1; i < misspelledWord.length(); i++) {
+        if (u_isupper(static_cast<UChar32>(misspelledWord[i])))
+            return String();
+    }
+
+    return m_webView->client()->autoCorrectWord(WebString(misspelledWord));
+}
+
+void EditorClientImpl::checkGrammarOfString(const UChar*, int length,
+                                            WTF::Vector<GrammarDetail>&,
+                                            int* badGrammarLocation,
+                                            int* badGrammarLength)
+{
+    notImplemented();
+    if (badGrammarLocation)
+        *badGrammarLocation = 0;
+    if (badGrammarLength)
+        *badGrammarLength = 0;
+}
+
+void EditorClientImpl::updateSpellingUIWithGrammarString(const String&,
+                                                         const GrammarDetail& detail)
+{
+    notImplemented();
+}
+
+void EditorClientImpl::updateSpellingUIWithMisspelledWord(const String& misspelledWord)
+{
+    if (m_webView->client())
+        m_webView->client()->updateSpellingUIWithMisspelledWord(WebString(misspelledWord));
+}
+
+void EditorClientImpl::showSpellingUI(bool show)
+{
+    if (m_webView->client())
+        m_webView->client()->showSpellingUI(show);
+}
+
+bool EditorClientImpl::spellingUIIsShowing()
+{
+    if (m_webView->client())
+        return m_webView->client()->isShowingSpellingUI();
+    return false;
+}
+
+void EditorClientImpl::getGuessesForWord(const String&,
+                                         WTF::Vector<String>& guesses)
+{
+    notImplemented();
+}
+
+void EditorClientImpl::setInputMethodState(bool enabled)
+{
+    if (m_webView->client())
+        m_webView->client()->setInputMethodEnabled(enabled);
+}
+
+} // namesace WebKit
diff --git a/WebKit/chromium/src/EditorClientImpl.h b/WebKit/chromium/src/EditorClientImpl.h
new file mode 100644 (file)
index 0000000..fd08b4d
--- /dev/null
@@ -0,0 +1,194 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef EditorClientImpl_h
+#define EditorClientImpl_h
+
+#include "EditorClient.h"
+#include "Timer.h"
+#include <wtf/Deque.h>
+
+namespace WebCore {
+class HTMLInputElement;
+}
+
+namespace WebKit {
+class WebViewImpl;
+
+class EditorClientImpl : public WebCore::EditorClient {
+public:
+    EditorClientImpl(WebViewImpl* webView);
+
+    virtual ~EditorClientImpl();
+    virtual void pageDestroyed();
+
+    virtual bool shouldShowDeleteInterface(WebCore::HTMLElement*);
+    virtual bool smartInsertDeleteEnabled();
+    virtual bool isSelectTrailingWhitespaceEnabled();
+    virtual bool isContinuousSpellCheckingEnabled();
+    virtual void toggleContinuousSpellChecking();
+    virtual bool isGrammarCheckingEnabled();
+    virtual void toggleGrammarChecking();
+    virtual int spellCheckerDocumentTag();
+    virtual bool isEditable();
+    virtual bool shouldBeginEditing(WebCore::Range*);
+    virtual bool shouldEndEditing(WebCore::Range*);
+    virtual bool shouldInsertNode(WebCore::Node*, WebCore::Range*, WebCore::EditorInsertAction);
+    virtual bool shouldInsertText(const WebCore::String&, WebCore::Range*, WebCore::EditorInsertAction);
+    virtual bool shouldDeleteRange(WebCore::Range*);
+    virtual bool shouldChangeSelectedRange(WebCore::Range* fromRange,
+                                           WebCore::Range* toRange,
+                                           WebCore::EAffinity,
+                                           bool stillSelecting);
+    virtual bool shouldApplyStyle(WebCore::CSSStyleDeclaration*, WebCore::Range*);
+    virtual bool shouldMoveRangeAfterDelete(WebCore::Range*, WebCore::Range*);
+    virtual void didBeginEditing();
+    virtual void respondToChangedContents();
+    virtual void respondToChangedSelection();
+    virtual void didEndEditing();
+    virtual void didWriteSelectionToPasteboard();
+    virtual void didSetSelectionTypesForPasteboard();
+    virtual void registerCommandForUndo(PassRefPtr<WebCore::EditCommand>);
+    virtual void registerCommandForRedo(PassRefPtr<WebCore::EditCommand>);
+    virtual void clearUndoRedoOperations();
+    virtual bool canUndo() const;
+    virtual bool canRedo() const;
+    virtual void undo();
+    virtual void redo();
+    virtual const char* interpretKeyEvent(const WebCore::KeyboardEvent*);
+    virtual bool handleEditingKeyboardEvent(WebCore::KeyboardEvent*);
+    virtual void handleKeyboardEvent(WebCore::KeyboardEvent*);
+    virtual void handleInputMethodKeydown(WebCore::KeyboardEvent*);
+    virtual void textFieldDidBeginEditing(WebCore::Element*);
+    virtual void textFieldDidEndEditing(WebCore::Element*);
+    virtual void textDidChangeInTextField(WebCore::Element*);
+    virtual bool doTextFieldCommandFromEvent(WebCore::Element*, WebCore::KeyboardEvent*);
+    virtual void textWillBeDeletedInTextField(WebCore::Element*);
+    virtual void textDidChangeInTextArea(WebCore::Element*);
+    virtual void ignoreWordInSpellDocument(const WebCore::String&);
+    virtual void learnWord(const WebCore::String&);
+    virtual void checkSpellingOfString(const UChar*, int length,
+                                       int* misspellingLocation,
+                                       int* misspellingLength);
+    virtual void checkGrammarOfString(const UChar*, int length,
+                                      WTF::Vector<WebCore::GrammarDetail>&,
+                                      int* badGrammarLocation,
+                                      int* badGrammarLength);
+    virtual WebCore::String getAutoCorrectSuggestionForMisspelledWord(const WebCore::String&);
+    virtual void updateSpellingUIWithGrammarString(const WebCore::String&, const WebCore::GrammarDetail&);
+    virtual void updateSpellingUIWithMisspelledWord(const WebCore::String&);
+    virtual void showSpellingUI(bool show);
+    virtual bool spellingUIIsShowing();
+    virtual void getGuessesForWord(const WebCore::String& word,
+                                   WTF::Vector<WebCore::String>& guesses);
+    virtual void setInputMethodState(bool enabled);
+
+    // Shows the form autofill popup for |node| if it is an HTMLInputElement and
+    // it is empty.  This is called when you press the up or down arrow in a
+    // text-field or when clicking an already focused text-field.
+    // Returns true if the autofill popup has been scheduled to be shown, false
+    // otherwise.
+    virtual bool showFormAutofillForNode(WebCore::Node*);
+
+    // Notification that the text changed due to acceptance of a suggestion
+    // provided by an autofill popup.  Having a separate callback in this case
+    // is a simple way to break the cycle that would otherwise occur if
+    // textDidChangeInTextField was called.
+    virtual void onAutofillSuggestionAccepted(WebCore::HTMLInputElement*);
+
+private:
+    void modifySelection(WebCore::Frame*, WebCore::KeyboardEvent*);
+
+    // Triggers autofill for an input element if applicable.  This can be form
+    // autofill (via a popup-menu) or password autofill depending on the
+    // input element.  If |formAutofillOnly| is true, password autofill is not
+    // triggered.
+    // |autofillOnEmptyValue| indicates whether the autofill should be shown
+    // when the text-field is empty.
+    // If |requiresCaretAtEnd| is true, the autofill popup is only shown if the
+    // caret is located at the end of the entered text.
+    // Returns true if the autofill popup has been scheduled to be shown, false
+    // otherwise.
+    bool autofill(WebCore::HTMLInputElement*,
+                  bool formAutofillOnly, bool autofillOnEmptyValue,
+                  bool requiresCaretAtEnd);
+
+    // Called to process the autofill described by m_autofillArgs.
+    // This method is invoked asynchronously if the caret position is not
+    // reflecting the last text change yet, and we need it to decide whether or
+    // not to show the autofill popup.
+    void doAutofill(WebCore::Timer<EditorClientImpl>*);
+
+    void cancelPendingAutofill();
+
+    // Returns whether or not the focused control needs spell-checking.
+    // Currently, this function just retrieves the focused node and determines
+    // whether or not it is a <textarea> element or an element whose
+    // contenteditable attribute is true.
+    // FIXME: Bug 740540: This code just implements the default behavior
+    // proposed in this issue. We should also retrieve "spellcheck" attributes
+    // for text fields and create a flag to over-write the default behavior.
+    bool shouldSpellcheckByDefault();
+
+    WebViewImpl* m_webView;
+    bool m_inRedo;
+
+    typedef Deque<RefPtr<WebCore::EditCommand> > EditCommandStack;
+    EditCommandStack m_undoStack;
+    EditCommandStack m_redoStack;
+
+    // Whether the last entered key was a backspace.
+    bool m_backspaceOrDeletePressed;
+
+    // This flag is set to false if spell check for this editor is manually
+    // turned off. The default setting is SpellCheckAutomatic.
+    enum {
+        SpellCheckAutomatic,
+        SpellCheckForcedOn,
+        SpellCheckForcedOff
+    };
+    int m_spellCheckThisFieldStatus;
+
+    // Used to delay autofill processing.
+    WebCore::Timer<EditorClientImpl> m_autofillTimer;
+
+    struct AutofillArgs {
+        RefPtr<WebCore::HTMLInputElement> inputElement;
+        bool autofillFormOnly;
+        bool autofillOnEmptyValue;
+        bool requireCaretAtEnd;
+        bool backspaceOrDeletePressed;
+    };
+    OwnPtr<AutofillArgs> m_autofillArgs;
+};
+
+} // namespace WebKit
+
+#endif
diff --git a/WebKit/chromium/src/FrameLoaderClientImpl.cpp b/WebKit/chromium/src/FrameLoaderClientImpl.cpp
new file mode 100644 (file)
index 0000000..2b4b1bc
--- /dev/null
@@ -0,0 +1,1412 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "FrameLoaderClientImpl.h"
+
+#include "Chrome.h"
+#include "CString.h"
+#include "Document.h"
+#include "DocumentLoader.h"
+#include "FormState.h"
+#include "FrameLoader.h"
+#include "FrameLoadRequest.h"
+#include "HitTestResult.h"
+#include "HTMLAppletElement.h"
+#include "HTMLFormElement.h"  // needed by FormState.h
+#include "HTMLNames.h"
+#include "MIMETypeRegistry.h"
+#include "MouseEvent.h"
+#include "Page.h"
+#include "PlatformString.h"
+#include "PluginData.h"
+#include "StringExtras.h"
+#include "WebDataSourceImpl.h"
+#include "WebDevToolsAgentPrivate.h"
+#include "WebFormElement.h"
+#include "WebFrameClient.h"
+#include "WebFrameImpl.h"
+#include "WebKit.h"
+#include "WebKitClient.h"
+#include "WebMimeRegistry.h"
+#include "WebNode.h"
+#include "WebPlugin.h"
+#include "WebPluginContainerImpl.h"
+#include "WebPluginLoadObserver.h"
+#include "WebPluginParams.h"
+#include "WebSecurityOrigin.h"
+#include "WebURL.h"
+#include "WebURLError.h"
+#include "WebVector.h"
+#include "WebViewClient.h"
+#include "WebViewImpl.h"
+#include "WindowFeatures.h"
+#include "WrappedResourceRequest.h"
+#include "WrappedResourceResponse.h"
+
+using namespace WebCore;
+
+namespace WebKit {
+
+// Domain for internal error codes.
+static const char internalErrorDomain[] = "WebKit";
+
+// An internal error code.  Used to note a policy change error resulting from
+// dispatchDecidePolicyForMIMEType not passing the PolicyUse option.
+enum {
+    PolicyChangeError = -10000,
+};
+
+FrameLoaderClientImpl::FrameLoaderClientImpl(WebFrameImpl* frame)
+    : m_webFrame(frame)
+    , m_hasRepresentation(false)
+    , m_sentInitialResponseToPlugin(false)
+    , m_nextNavigationPolicy(WebNavigationPolicyIgnore)
+{
+}
+
+FrameLoaderClientImpl::~FrameLoaderClientImpl()
+{
+}
+
+void FrameLoaderClientImpl::frameLoaderDestroyed()
+{
+    // When the WebFrame was created, it had an extra reference given to it on
+    // behalf of the Frame.  Since the WebFrame owns us, this extra ref also
+    // serves to keep us alive until the FrameLoader is done with us.  The
+    // FrameLoader calls this method when it's going away.  Therefore, we balance
+    // out that extra reference, which may cause 'this' to be deleted.
+    m_webFrame->closing();
+    m_webFrame->deref();
+}
+
+void FrameLoaderClientImpl::windowObjectCleared()
+{
+    if (m_webFrame->client())
+        m_webFrame->client()->didClearWindowObject(m_webFrame);
+
+    WebViewImpl* webview = m_webFrame->viewImpl();
+    if (webview->devToolsAgentPrivate())
+        webview->devToolsAgentPrivate()->didClearWindowObject(m_webFrame);
+}
+
+void FrameLoaderClientImpl::documentElementAvailable()
+{
+    if (m_webFrame->client())
+        m_webFrame->client()->didCreateDocumentElement(m_webFrame);
+}
+
+void FrameLoaderClientImpl::didCreateScriptContextForFrame()
+{
+    if (m_webFrame->client())
+        m_webFrame->client()->didCreateScriptContext(m_webFrame);
+}
+
+void FrameLoaderClientImpl::didDestroyScriptContextForFrame()
+{
+    if (m_webFrame->client())
+        m_webFrame->client()->didDestroyScriptContext(m_webFrame);
+}
+
+void FrameLoaderClientImpl::didCreateIsolatedScriptContext()
+{
+    if (m_webFrame->client())
+        m_webFrame->client()->didCreateIsolatedScriptContext(m_webFrame);
+}
+
+void FrameLoaderClientImpl::didPerformFirstNavigation() const
+{
+}
+
+void FrameLoaderClientImpl::registerForIconNotification(bool)
+{
+}
+
+void FrameLoaderClientImpl::didChangeScrollOffset()
+{
+    if (m_webFrame->client())
+        m_webFrame->client()->didChangeScrollOffset(m_webFrame);
+}
+
+bool FrameLoaderClientImpl::allowJavaScript(bool enabledPerSettings)
+{
+    if (m_webFrame->client())
+        return m_webFrame->client()->allowScript(m_webFrame, enabledPerSettings);
+
+    return enabledPerSettings;
+}
+
+bool FrameLoaderClientImpl::hasWebView() const
+{
+    return m_webFrame->viewImpl();
+}
+
+bool FrameLoaderClientImpl::hasFrameView() const
+{
+    // The Mac port has this notion of a WebFrameView, which seems to be
+    // some wrapper around an NSView.  Since our equivalent is HWND, I guess
+    // we have a "frameview" whenever we have the toplevel HWND.
+    return m_webFrame->viewImpl();
+}
+
+void FrameLoaderClientImpl::makeDocumentView()
+{
+    m_webFrame->createFrameView();
+}
+
+void FrameLoaderClientImpl::makeRepresentation(DocumentLoader*)
+{
+    m_hasRepresentation = true;
+}
+
+void FrameLoaderClientImpl::forceLayout()
+{
+    // FIXME
+}
+
+void FrameLoaderClientImpl::forceLayoutForNonHTML()
+{
+    // FIXME
+}
+
+void FrameLoaderClientImpl::setCopiesOnScroll()
+{
+    // FIXME
+}
+
+void FrameLoaderClientImpl::detachedFromParent2()
+{
+    // Nothing to do here.
+}
+
+void FrameLoaderClientImpl::detachedFromParent3()
+{
+    // Close down the proxy.  The purpose of this change is to make the
+    // call to ScriptController::clearWindowShell a no-op when called from
+    // Frame::pageDestroyed.  Without this change, this call to clearWindowShell
+    // will cause a crash.  If you remove/modify this, just ensure that you can
+    // go to a page and then navigate to a new page without getting any asserts
+    // or crashes.
+    m_webFrame->frame()->script()->proxy()->clearForClose();
+}
+
+// This function is responsible for associating the |identifier| with a given
+// subresource load.  The following functions that accept an |identifier| are
+// called for each subresource, so they should not be dispatched to the
+// WebFrame.
+void FrameLoaderClientImpl::assignIdentifierToInitialRequest(
+    unsigned long identifier, DocumentLoader* loader,
+    const ResourceRequest& request)
+{
+    if (m_webFrame->client()) {
+        WrappedResourceRequest webreq(request);
+        m_webFrame->client()->assignIdentifierToRequest(
+            m_webFrame, identifier, webreq);
+    }
+}
+
+// Determines whether the request being loaded by |loader| is a frame or a
+// subresource. A subresource in this context is anything other than a frame --
+// this includes images and xmlhttp requests.  It is important to note that a
+// subresource is NOT limited to stuff loaded through the frame's subresource
+// loader. Synchronous xmlhttp requests for example, do not go through the
+// subresource loader, but we still label them as TargetIsSubResource.
+//
+// The important edge cases to consider when modifying this function are
+// how synchronous resource loads are treated during load/unload threshold.
+static ResourceRequest::TargetType determineTargetTypeFromLoader(DocumentLoader* loader)
+{
+    if (loader == loader->frameLoader()->provisionalDocumentLoader()) {
+        if (loader->frameLoader()->isLoadingMainFrame())
+            return ResourceRequest::TargetIsMainFrame;
+        return ResourceRequest::TargetIsSubFrame;
+    }
+    return ResourceRequest::TargetIsSubResource;
+}
+
+void FrameLoaderClientImpl::dispatchWillSendRequest(
+    DocumentLoader* loader, unsigned long identifier, ResourceRequest& request,
+    const ResourceResponse& redirectResponse)
+{
+    if (loader) {
+        // We want to distinguish between a request for a document to be loaded into
+        // the main frame, a sub-frame, or the sub-objects in that document.
+        request.setTargetType(determineTargetTypeFromLoader(loader));
+    }
+
+    // FrameLoader::loadEmptyDocumentSynchronously() creates an empty document
+    // with no URL.  We don't like that, so we'll rename it to about:blank.
+    if (request.url().isEmpty())
+        request.setURL(KURL(ParsedURLString, "about:blank"));
+    if (request.firstPartyForCookies().isEmpty())
+        request.setFirstPartyForCookies(KURL(ParsedURLString, "about:blank"));
+
+    // Give the WebFrameClient a crack at the request.
+    if (m_webFrame->client()) {
+        WrappedResourceRequest webreq(request);
+        WrappedResourceResponse webresp(redirectResponse);
+        m_webFrame->client()->willSendRequest(
+            m_webFrame, identifier, webreq, webresp);
+    }
+}
+
+bool FrameLoaderClientImpl::shouldUseCredentialStorage(
+    DocumentLoader*, unsigned long identifier)
+{
+    // FIXME
+    // Intended to pass through to a method on the resource load delegate.
+    // If implemented, that method controls whether the browser should ask the
+    // networking layer for a stored default credential for the page (say from
+    // the Mac OS keychain). If the method returns false, the user should be
+    // presented with an authentication challenge whether or not the networking
+    // layer has a credential stored.
+    // This returns true for backward compatibility: the ability to override the
+    // system credential store is new. (Actually, not yet fully implemented in
+    // WebKit, as of this writing.)
+    return true;
+}
+
+void FrameLoaderClientImpl::dispatchDidReceiveAuthenticationChallenge(
+    DocumentLoader*, unsigned long identifier, const AuthenticationChallenge&)
+{
+    // FIXME
+}
+
+void FrameLoaderClientImpl::dispatchDidCancelAuthenticationChallenge(
+    DocumentLoader*, unsigned long identifier, const AuthenticationChallenge&)
+{
+    // FIXME
+}
+
+void FrameLoaderClientImpl::dispatchDidReceiveResponse(DocumentLoader* loader,
+                                                       unsigned long identifier,
+                                                       const ResourceResponse& response)
+{
+    if (m_webFrame->client()) {
+        WrappedResourceResponse webresp(response);
+        m_webFrame->client()->didReceiveResponse(m_webFrame, identifier, webresp);
+    }
+}
+
+void FrameLoaderClientImpl::dispatchDidReceiveContentLength(
+    DocumentLoader* loader,
+    unsigned long identifier,
+    int lengthReceived)
+{
+}
+
+// Called when a particular resource load completes
+void FrameLoaderClientImpl::dispatchDidFinishLoading(DocumentLoader* loader,
+                                                    unsigned long identifier)
+{
+    if (m_webFrame->client())
+        m_webFrame->client()->didFinishResourceLoad(m_webFrame, identifier);
+}
+
+void FrameLoaderClientImpl::dispatchDidFailLoading(DocumentLoader* loader,
+                                                  unsigned long identifier,
+                                                  const ResourceError& error)
+{
+    if (m_webFrame->client())
+        m_webFrame->client()->didFailResourceLoad(m_webFrame, identifier, error);
+}
+
+void FrameLoaderClientImpl::dispatchDidFinishDocumentLoad()
+{
+    // A frame may be reused.  This call ensures we don't hold on to our password
+    // listeners and their associated HTMLInputElements.
+    m_webFrame->clearPasswordListeners();
+
+    if (m_webFrame->client())
+        m_webFrame->client()->didFinishDocumentLoad(m_webFrame);
+}
+
+bool FrameLoaderClientImpl::dispatchDidLoadResourceFromMemoryCache(
+    DocumentLoader* loader,
+    const ResourceRequest& request,
+    const ResourceResponse& response,
+    int length)
+{
+    if (m_webFrame->client()) {
+        WrappedResourceRequest webreq(request);
+        WrappedResourceResponse webresp(response);
+        m_webFrame->client()->didLoadResourceFromMemoryCache(
+            m_webFrame, webreq, webresp);
+    }
+    return false;  // Do not suppress remaining notifications
+}
+
+void FrameLoaderClientImpl::dispatchDidLoadResourceByXMLHttpRequest(
+    unsigned long identifier,
+    const ScriptString& source)
+{
+}
+
+void FrameLoaderClientImpl::dispatchDidHandleOnloadEvents()
+{
+    if (m_webFrame->client())
+        m_webFrame->client()->didHandleOnloadEvents(m_webFrame);
+}
+
+// Redirect Tracking
+// =================
+// We want to keep track of the chain of redirects that occur during page
+// loading. There are two types of redirects, server redirects which are HTTP
+// response codes, and client redirects which are document.location= and meta
+// refreshes.
+//
+// This outlines the callbacks that we get in different redirect situations,
+// and how each call modifies the redirect chain.
+//
+// Normal page load
+// ----------------
+//   dispatchDidStartProvisionalLoad() -> adds URL to the redirect list
+//   dispatchDidCommitLoad()           -> DISPATCHES & clears list
+//
+// Server redirect (success)
+// -------------------------
+//   dispatchDidStartProvisionalLoad()                    -> adds source URL
+//   dispatchDidReceiveServerRedirectForProvisionalLoad() -> adds dest URL
+//   dispatchDidCommitLoad()                              -> DISPATCHES
+//
+// Client redirect (success)
+// -------------------------
+//   (on page)
+//   dispatchWillPerformClientRedirect() -> saves expected redirect
+//   dispatchDidStartProvisionalLoad()   -> appends redirect source (since
+//                                          it matches the expected redirect)
+//                                          and the current page as the dest)
+//   dispatchDidCancelClientRedirect()   -> clears expected redirect
+//   dispatchDidCommitLoad()             -> DISPATCHES
+//
+// Client redirect (cancelled)
+// (e.g meta-refresh trumped by manual doc.location change, or just cancelled
+// because a link was clicked that requires the meta refresh to be rescheduled
+// (the SOURCE URL may have changed).
+// ---------------------------
+//   dispatchDidCancelClientRedirect()                 -> clears expected redirect
+//   dispatchDidStartProvisionalLoad()                 -> adds only URL to redirect list
+//   dispatchDidCommitLoad()                           -> DISPATCHES & clears list
+//   rescheduled ? dispatchWillPerformClientRedirect() -> saves expected redirect
+//               : nothing
+
+// Client redirect (failure)
+// -------------------------
+//   (on page)
+//   dispatchWillPerformClientRedirect() -> saves expected redirect
+//   dispatchDidStartProvisionalLoad()   -> appends redirect source (since
+//                                          it matches the expected redirect)
+//                                          and the current page as the dest)
+//   dispatchDidCancelClientRedirect()
+//   dispatchDidFailProvisionalLoad()
+//
+// Load 1 -> Server redirect to 2 -> client redirect to 3 -> server redirect to 4
+// ------------------------------------------------------------------------------
+//   dispatchDidStartProvisionalLoad()                    -> adds source URL 1
+//   dispatchDidReceiveServerRedirectForProvisionalLoad() -> adds dest URL 2
+//   dispatchDidCommitLoad()                              -> DISPATCHES 1+2
+//    -- begin client redirect and NEW DATA SOURCE
+//   dispatchWillPerformClientRedirect()                  -> saves expected redirect
+//   dispatchDidStartProvisionalLoad()                    -> appends URL 2 and URL 3
+//   dispatchDidReceiveServerRedirectForProvisionalLoad() -> appends destination URL 4
+//   dispatchDidCancelClientRedirect()                    -> clears expected redirect
+//   dispatchDidCommitLoad()                              -> DISPATCHES
+//
+// Interesting case with multiple location changes involving anchors.
+// Load page 1 containing future client-redirect (back to 1, e.g meta refresh) > Click
+// on a link back to the same page (i.e an anchor href) >
+// client-redirect finally fires (with new source, set to 1#anchor)
+// -----------------------------------------------------------------------------
+//   dispatchWillPerformClientRedirect(non-zero 'interval' param) -> saves expected redirect
+//   -- click on anchor href
+//   dispatchDidCancelClientRedirect()                            -> clears expected redirect
+//   dispatchDidStartProvisionalLoad()                            -> adds 1#anchor source
+//   dispatchDidCommitLoad()                                      -> DISPATCHES 1#anchor
+//   dispatchWillPerformClientRedirect()                          -> saves exp. source (1#anchor)
+//   -- redirect timer fires
+//   dispatchDidStartProvisionalLoad()                            -> appends 1#anchor (src) and 1 (dest)
+//   dispatchDidCancelClientRedirect()                            -> clears expected redirect
+//   dispatchDidCommitLoad()                                      -> DISPATCHES 1#anchor + 1
+//
+void FrameLoaderClientImpl::dispatchDidReceiveServerRedirectForProvisionalLoad()
+{
+    WebDataSourceImpl* ds = m_webFrame->provisionalDataSourceImpl();
+    if (!ds) {
+        // Got a server redirect when there is no provisional DS!
+        ASSERT_NOT_REACHED();
+        return;
+    }
+
+    // The server redirect may have been blocked.
+    if (ds->request().isNull())
+        return;
+
+    // A provisional load should have started already, which should have put an
+    // entry in our redirect chain.
+    ASSERT(ds->hasRedirectChain());
+
+    // The URL of the destination is on the provisional data source. We also need
+    // to update the redirect chain to account for this addition (we do this
+    // before the callback so the callback can look at the redirect chain to see
+    // what happened).
+    ds->appendRedirect(ds->request().url());
+
+    if (m_webFrame->client())
+        m_webFrame->client()->didReceiveServerRedirectForProvisionalLoad(m_webFrame);
+}
+
+// Called on both success and failure of a client redirect.
+void FrameLoaderClientImpl::dispatchDidCancelClientRedirect()
+{
+    // No longer expecting a client redirect.
+    if (m_webFrame->client()) {
+        m_expectedClientRedirectSrc = KURL();
+        m_expectedClientRedirectDest = KURL();
+        m_webFrame->client()->didCancelClientRedirect(m_webFrame);
+    }
+
+    // No need to clear the redirect chain, since that data source has already
+    // been deleted by the time this function is called.
+}
+
+void FrameLoaderClientImpl::dispatchWillPerformClientRedirect(
+    const KURL& url,
+    double interval,
+    double fireDate)
+{
+    // Tells dispatchDidStartProvisionalLoad that if it sees this item it is a
+    // redirect and the source item should be added as the start of the chain.
+    m_expectedClientRedirectSrc = m_webFrame->url();
+    m_expectedClientRedirectDest = url;
+
+    // FIXME: bug 1135512. Webkit does not properly notify us of cancelling
+    // http > file client redirects. Since the FrameLoader's policy is to never
+    // carry out such a navigation anyway, the best thing we can do for now to
+    // not get confused is ignore this notification.
+    if (m_expectedClientRedirectDest.isLocalFile()
+        && m_expectedClientRedirectSrc.protocolInHTTPFamily()) {
+        m_expectedClientRedirectSrc = KURL();
+        m_expectedClientRedirectDest = KURL();
+        return;
+    }
+
+    if (m_webFrame->client()) {
+        m_webFrame->client()->willPerformClientRedirect(
+            m_webFrame,
+            m_expectedClientRedirectSrc,
+            m_expectedClientRedirectDest,
+            static_cast<unsigned int>(interval),
+            static_cast<unsigned int>(fireDate));
+    }
+}
+
+void FrameLoaderClientImpl::dispatchDidChangeLocationWithinPage()
+{
+    // Anchor fragment navigations are not normal loads, so we need to synthesize
+    // some events for our delegate.
+    WebViewImpl* webView = m_webFrame->viewImpl();
+    if (webView->client())
+        webView->client()->didStartLoading();
+
+    WebDataSourceImpl* ds = m_webFrame->dataSourceImpl();
+    ASSERT(ds);  // Should not be null when navigating to a reference fragment!
+    if (ds) {
+        KURL url = ds->request().url();
+        KURL chainEnd;
+        if (ds->hasRedirectChain()) {
+            chainEnd = ds->endOfRedirectChain();
+            ds->clearRedirectChain();
+        }
+
+        // Figure out if this location change is because of a JS-initiated
+        // client redirect (e.g onload/setTimeout document.location.href=).
+        // FIXME: (bugs 1085325, 1046841) We don't get proper redirect
+        // performed/cancelled notifications across anchor navigations, so the
+        // other redirect-tracking code in this class (see
+        // dispatch*ClientRedirect() and dispatchDidStartProvisionalLoad) is
+        // insufficient to catch and properly flag these transitions. Once a
+        // proper fix for this bug is identified and applied the following
+        // block may no longer be required.
+        bool wasClientRedirect =
+            (url == m_expectedClientRedirectDest && chainEnd == m_expectedClientRedirectSrc)
+            || !m_webFrame->isProcessingUserGesture();
+
+        if (wasClientRedirect) {
+            if (m_webFrame->client())
+                m_webFrame->client()->didCompleteClientRedirect(m_webFrame, chainEnd);
+            ds->appendRedirect(chainEnd);
+            // Make sure we clear the expected redirect since we just effectively
+            // completed it.
+            m_expectedClientRedirectSrc = KURL();
+            m_expectedClientRedirectDest = KURL();
+        }
+
+        // Regardless of how we got here, we are navigating to a URL so we need to
+        // add it to the redirect chain.
+        ds->appendRedirect(url);
+    }
+
+    bool isNewNavigation;
+    webView->didCommitLoad(&isNewNavigation);
+    if (m_webFrame->client())
+        m_webFrame->client()->didChangeLocationWithinPage(m_webFrame, isNewNavigation);
+
+    if (webView->client())
+        webView->client()->didStopLoading();
+}
+
+void FrameLoaderClientImpl::dispatchWillClose()
+{
+    if (m_webFrame->client())
+        m_webFrame->client()->willClose(m_webFrame);
+}
+
+void FrameLoaderClientImpl::dispatchDidReceiveIcon()
+{
+    // The icon database is disabled, so this should never be called.
+    ASSERT_NOT_REACHED();
+}
+
+void FrameLoaderClientImpl::dispatchDidStartProvisionalLoad()
+{
+    // In case a redirect occurs, we need this to be set so that the redirect
+    // handling code can tell where the redirect came from. Server redirects
+    // will occur on the provisional load, so we need to keep track of the most
+    // recent provisional load URL.
+    // See dispatchDidReceiveServerRedirectForProvisionalLoad.
+    WebDataSourceImpl* ds = m_webFrame->provisionalDataSourceImpl();
+    if (!ds) {
+        ASSERT_NOT_REACHED();
+        return;
+    }
+    KURL url = ds->request().url();
+
+    // Since the provisional load just started, we should have not gotten
+    // any redirects yet.
+    ASSERT(!ds->hasRedirectChain());
+
+    // If this load is what we expected from a client redirect, treat it as a
+    // redirect from that original page. The expected redirect urls will be
+    // cleared by DidCancelClientRedirect.
+    bool completingClientRedirect = false;
+    if (m_expectedClientRedirectSrc.isValid()) {
+        // m_expectedClientRedirectDest could be something like
+        // "javascript:history.go(-1)" thus we need to exclude url starts with
+        // "javascript:". See bug: 1080873
+        ASSERT(m_expectedClientRedirectDest.protocolIs("javascript")
+            || m_expectedClientRedirectDest == url);
+        ds->appendRedirect(m_expectedClientRedirectSrc);
+        completingClientRedirect = true;
+    }
+    ds->appendRedirect(url);
+
+    if (m_webFrame->client()) {
+        // Whatever information didCompleteClientRedirect contains should only
+        // be considered relevant until the next provisional load has started.
+        // So we first tell the client that the load started, and then tell it
+        // about the client redirect the load is responsible for completing.
+        m_webFrame->client()->didStartProvisionalLoad(m_webFrame);
+        if (completingClientRedirect) {
+            m_webFrame->client()->didCompleteClientRedirect(
+                m_webFrame, m_expectedClientRedirectSrc);
+        }
+    }
+}
+
+void FrameLoaderClientImpl::dispatchDidReceiveTitle(const String& title)
+{
+    if (m_webFrame->client())
+        m_webFrame->client()->didReceiveTitle(m_webFrame, title);
+}
+
+void FrameLoaderClientImpl::dispatchDidCommitLoad()
+{
+    WebViewImpl* webview = m_webFrame->viewImpl();
+    bool isNewNavigation;
+    webview->didCommitLoad(&isNewNavigation);
+
+    if (m_webFrame->client())
+        m_webFrame->client()->didCommitProvisionalLoad(m_webFrame, isNewNavigation);
+
+    if (webview->devToolsAgentPrivate())
+        webview->devToolsAgentPrivate()->didCommitProvisionalLoad(m_webFrame, isNewNavigation);
+}
+
+void FrameLoaderClientImpl::dispatchDidFailProvisionalLoad(
+    const ResourceError& error)
+{
+
+    // If a policy change occured, then we do not want to inform the plugin
+    // delegate.  See http://b/907789 for details.  FIXME: This means the
+    // plugin won't receive NPP_URLNotify, which seems like it could result in
+    // a memory leak in the plugin!!
+    if (error.domain() == internalErrorDomain
+        && error.errorCode() == PolicyChangeError) {
+        m_webFrame->didFail(cancelledError(error.failingURL()), true);
+        return;
+    }
+
+    OwnPtr<WebPluginLoadObserver> observer = pluginLoadObserver();
+    m_webFrame->didFail(error, true);
+    if (observer)
+        observer->didFailLoading(error);
+}
+
+void FrameLoaderClientImpl::dispatchDidFailLoad(const ResourceError& error)
+{
+    OwnPtr<WebPluginLoadObserver> observer = pluginLoadObserver();
+    m_webFrame->didFail(error, false);
+    if (observer)
+        observer->didFailLoading(error);
+
+    // Don't clear the redirect chain, this will happen in the middle of client
+    // redirects, and we need the context. The chain will be cleared when the
+    // provisional load succeeds or fails, not the "real" one.
+}
+
+void FrameLoaderClientImpl::dispatchDidFinishLoad()
+{
+    OwnPtr<WebPluginLoadObserver> observer = pluginLoadObserver();
+
+    if (m_webFrame->client())
+        m_webFrame->client()->didFinishLoad(m_webFrame);
+
+    if (observer)
+        observer->didFinishLoading();
+
+    // Don't clear the redirect chain, this will happen in the middle of client
+    // redirects, and we need the context. The chain will be cleared when the
+    // provisional load succeeds or fails, not the "real" one.
+}
+
+void FrameLoaderClientImpl::dispatchDidFirstLayout()
+{
+}
+
+void FrameLoaderClientImpl::dispatchDidFirstVisuallyNonEmptyLayout()
+{
+    // FIXME: called when webkit finished layout of a page that was visually non-empty.
+    // All resources have not necessarily finished loading.
+}
+
+Frame* FrameLoaderClientImpl::dispatchCreatePage()
+{
+    struct WindowFeatures features;
+    Page* newPage = m_webFrame->frame()->page()->chrome()->createWindow(
+        m_webFrame->frame(), FrameLoadRequest(), features);
+
+    // Make sure that we have a valid disposition.  This should have been set in
+    // the preceeding call to dispatchDecidePolicyForNewWindowAction.
+    ASSERT(m_nextNavigationPolicy != WebNavigationPolicyIgnore);
+    WebNavigationPolicy policy = m_nextNavigationPolicy;
+    m_nextNavigationPolicy = WebNavigationPolicyIgnore;
+
+    // createWindow can return null (e.g., popup blocker denies the window).
+    if (!newPage)
+        return 0;
+
+    WebViewImpl::fromPage(newPage)->setInitialNavigationPolicy(policy);
+    return newPage->mainFrame();
+}
+
+void FrameLoaderClientImpl::dispatchShow()
+{
+    WebViewImpl* webView = m_webFrame->viewImpl();
+    if (webView && webView->client())
+        webView->client()->show(webView->initialNavigationPolicy());
+}
+
+static bool shouldTreatAsAttachment(const ResourceResponse& response)
+{
+    const String& contentDisposition =
+        response.httpHeaderField("Content-Disposition");
+    if (contentDisposition.isEmpty())
+        return false;
+
+    // Some broken sites just send
+    // Content-Disposition: ; filename="file"
+    // screen those out here.
+    if (contentDisposition.startsWith(";"))
+        return false;
+
+    if (contentDisposition.startsWith("inline", false))
+        return false;
+
+    // Some broken sites just send
+    // Content-Disposition: filename="file"
+    // without a disposition token... screen those out.
+    if (contentDisposition.startsWith("filename", false))
+        return false;
+
+    // Also in use is Content-Disposition: name="file"
+    if (contentDisposition.startsWith("name", false))
+        return false;
+
+    // We have a content-disposition of "attachment" or unknown.
+    // RFC 2183, section 2.8 says that an unknown disposition
+    // value should be treated as "attachment"
+    return true;
+}
+
+void FrameLoaderClientImpl::dispatchDecidePolicyForMIMEType(
+     FramePolicyFunction function,
+     const String& mimeType,
+     const ResourceRequest&)
+{
+    const ResourceResponse& response =
+        m_webFrame->frame()->loader()->activeDocumentLoader()->response();
+
+    PolicyAction action;
+
+    int statusCode = response.httpStatusCode();
+    if (statusCode == 204 || statusCode == 205) {
+        // The server does not want us to replace the page contents.
+        action = PolicyIgnore;
+    } else if (shouldTreatAsAttachment(response)) {
+        // The server wants us to download instead of replacing the page contents.
+        // Downloading is handled by the embedder, but we still get the initial
+        // response so that we can ignore it and clean up properly.
+        action = PolicyIgnore;
+    } else if (!canShowMIMEType(mimeType)) {
+        // Make sure that we can actually handle this type internally.
+        action = PolicyIgnore;
+    } else {
+        // OK, we will render this page.
+        action = PolicyUse;
+    }
+
+    // NOTE: PolicyChangeError will be generated when action is not PolicyUse.
+    (m_webFrame->frame()->loader()->policyChecker()->*function)(action);
+}
+
+void FrameLoaderClientImpl::dispatchDecidePolicyForNewWindowAction(
+    FramePolicyFunction function,
+    const NavigationAction& action,
+    const ResourceRequest& request,
+    PassRefPtr<FormState> formState,
+    const String& frameName)
+{
+    WebNavigationPolicy navigationPolicy;
+    if (!actionSpecifiesNavigationPolicy(action, &navigationPolicy))
+        navigationPolicy = WebNavigationPolicyNewForegroundTab;
+
+    PolicyAction policyAction;
+    if (navigationPolicy == WebNavigationPolicyDownload)
+        policyAction = PolicyDownload;
+    else {
+        policyAction = PolicyUse;
+
+        // Remember the disposition for when dispatchCreatePage is called.  It is
+        // unfortunate that WebCore does not provide us with any context when
+        // creating or showing the new window that would allow us to avoid having
+        // to keep this state.
+        m_nextNavigationPolicy = navigationPolicy;
+    }
+    (m_webFrame->frame()->loader()->policyChecker()->*function)(policyAction);
+}
+
+void FrameLoaderClientImpl::dispatchDecidePolicyForNavigationAction(
+    FramePolicyFunction function,
+    const NavigationAction& action,
+    const ResourceRequest& request,
+    PassRefPtr<FormState> formState) {
+    PolicyAction policyAction = PolicyIgnore;
+
+    // It is valid for this function to be invoked in code paths where the
+    // the webview is closed.
+    // The null check here is to fix a crash that seems strange
+    // (see - https://bugs.webkit.org/show_bug.cgi?id=23554).
+    if (m_webFrame->client() && !request.url().isNull()) {
+      WebNavigationPolicy navigationPolicy = WebNavigationPolicyCurrentTab;
+      actionSpecifiesNavigationPolicy(action, &navigationPolicy);
+
+      // Give the delegate a chance to change the navigation policy.
+      const WebDataSourceImpl* ds = m_webFrame->provisionalDataSourceImpl();
+      if (ds) {
+          KURL url = ds->request().url();
+          if (url.protocolIs(backForwardNavigationScheme)) {
+              handleBackForwardNavigation(url);
+              navigationPolicy = WebNavigationPolicyIgnore;
+          } else {
+              bool isRedirect = ds->hasRedirectChain();
+
+              WebNavigationType webnavType =
+                  WebDataSourceImpl::toWebNavigationType(action.type());
+
+              RefPtr<Node> node;
+              for (const Event* event = action.event(); event; event = event->underlyingEvent()) {
+                  if (event->isMouseEvent()) {
+                      const MouseEvent* mouseEvent =
+                          static_cast<const MouseEvent*>(event);
+                      node = m_webFrame->frame()->eventHandler()->hitTestResultAtPoint(
+                          mouseEvent->absoluteLocation(), false).innerNonSharedNode();
+                      break;
+                  }
+              }
+              WebNode originatingNode(node);
+
+              navigationPolicy = m_webFrame->client()->decidePolicyForNavigation(
+                  m_webFrame, ds->request(), webnavType, originatingNode,
+                  navigationPolicy, isRedirect);
+          }
+      }
+
+      if (navigationPolicy == WebNavigationPolicyCurrentTab)
+          policyAction = PolicyUse;
+      else if (navigationPolicy == WebNavigationPolicyDownload)
+          policyAction = PolicyDownload;
+      else {
+          if (navigationPolicy != WebNavigationPolicyIgnore) {
+              WrappedResourceRequest webreq(request);
+              m_webFrame->client()->loadURLExternally(m_webFrame, webreq, navigationPolicy);
+          }
+          policyAction = PolicyIgnore;
+      }
+    }
+
+    (m_webFrame->frame()->loader()->policyChecker()->*function)(policyAction);
+}
+
+void FrameLoaderClientImpl::cancelPolicyCheck()
+{
+    // FIXME
+}
+
+void FrameLoaderClientImpl::dispatchUnableToImplementPolicy(const ResourceError& error)
+{
+    m_webFrame->client()->unableToImplementPolicyWithError(m_webFrame, error);
+}
+
+void FrameLoaderClientImpl::dispatchWillSubmitForm(FramePolicyFunction function,
+    PassRefPtr<FormState> formState)
+{
+    if (m_webFrame->client())
+        m_webFrame->client()->willSubmitForm(m_webFrame, WebFormElement(formState->form()));
+    (m_webFrame->frame()->loader()->policyChecker()->*function)(PolicyUse);
+}
+
+void FrameLoaderClientImpl::dispatchDidLoadMainResource(DocumentLoader*)
+{
+    // FIXME
+}
+
+void FrameLoaderClientImpl::revertToProvisionalState(DocumentLoader*)
+{
+    m_hasRepresentation = true;
+}
+
+void FrameLoaderClientImpl::setMainDocumentError(DocumentLoader*,
+                                                 const ResourceError& error)
+{
+    if (m_pluginWidget.get()) {
+        if (m_sentInitialResponseToPlugin) {
+            m_pluginWidget->didFailLoading(error);
+            m_sentInitialResponseToPlugin = false;
+        }
+        m_pluginWidget = 0;
+    }
+}
+
+void FrameLoaderClientImpl::postProgressStartedNotification()
+{
+    WebViewImpl* webview = m_webFrame->viewImpl();
+    if (webview && webview->client())
+        webview->client()->didStartLoading();
+}
+
+void FrameLoaderClientImpl::postProgressEstimateChangedNotification()
+{
+    // FIXME
+}
+
+void FrameLoaderClientImpl::postProgressFinishedNotification()
+{
+    // FIXME: why might the webview be null?  http://b/1234461
+    WebViewImpl* webview = m_webFrame->viewImpl();
+    if (webview && webview->client())
+        webview->client()->didStopLoading();
+}
+
+void FrameLoaderClientImpl::setMainFrameDocumentReady(bool ready)
+{
+    // FIXME
+}
+
+// Creates a new connection and begins downloading from that (contrast this
+// with |download|).
+void FrameLoaderClientImpl::startDownload(const ResourceRequest& request)
+{
+    if (m_webFrame->client()) {
+        WrappedResourceRequest webreq(request);
+        m_webFrame->client()->loadURLExternally(
+            m_webFrame, webreq, WebNavigationPolicyDownload);
+    }
+}
+
+void FrameLoaderClientImpl::willChangeTitle(DocumentLoader*)
+{
+    // FIXME
+}
+
+void FrameLoaderClientImpl::didChangeTitle(DocumentLoader*)
+{
+    // FIXME
+}
+
+// Called whenever data is received.
+void FrameLoaderClientImpl::committedLoad(DocumentLoader* loader, const char* data, int length)
+{
+    if (!m_pluginWidget.get()) {
+        if (m_webFrame->client()) {
+            bool preventDefault = false;
+            m_webFrame->client()->didReceiveDocumentData(m_webFrame, data, length, preventDefault);
+            if (!preventDefault)
+                m_webFrame->commitDocumentData(data, length);
+        }
+    }
+
+    // If we are sending data to MediaDocument, we should stop here
+    // and cancel the request.
+    if (m_webFrame->frame()->document()
+        && m_webFrame->frame()->document()->isMediaDocument())
+        loader->cancelMainResourceLoad(pluginWillHandleLoadError(loader->response()));
+
+    // The plugin widget could have been created in the m_webFrame->DidReceiveData
+    // function.
+    if (m_pluginWidget.get()) {
+        if (!m_sentInitialResponseToPlugin) {
+            m_sentInitialResponseToPlugin = true;
+            m_pluginWidget->didReceiveResponse(
+                m_webFrame->frame()->loader()->activeDocumentLoader()->response());
+        }
+        m_pluginWidget->didReceiveData(data, length);
+    }
+}
+
+void FrameLoaderClientImpl::finishedLoading(DocumentLoader* dl)
+{
+    if (m_pluginWidget.get()) {
+        m_pluginWidget->didFinishLoading();
+        m_pluginWidget = 0;
+        m_sentInitialResponseToPlugin = false;
+    } else {
+        // This is necessary to create an empty document. See bug 634004.
+        // However, we only want to do this if makeRepresentation has been called, to
+        // match the behavior on the Mac.
+        if (m_hasRepresentation)
+            dl->frameLoader()->setEncoding("", false);
+    }
+}
+
+void FrameLoaderClientImpl::updateGlobalHistory()
+{
+}
+
+void FrameLoaderClientImpl::updateGlobalHistoryRedirectLinks()
+{
+}
+
+bool FrameLoaderClientImpl::shouldGoToHistoryItem(HistoryItem*) const
+{
+    // FIXME
+    return true;
+}
+
+void FrameLoaderClientImpl::didDisplayInsecureContent()
+{
+    if (m_webFrame->client())
+        m_webFrame->client()->didDisplayInsecureContent(m_webFrame);
+}
+
+void FrameLoaderClientImpl::didRunInsecureContent(SecurityOrigin* origin)
+{
+    if (m_webFrame->client())
+        m_webFrame->client()->didRunInsecureContent(m_webFrame, WebSecurityOrigin(origin));
+}
+
+ResourceError FrameLoaderClientImpl::blockedError(const ResourceRequest&)
+{
+    // FIXME
+    return ResourceError();
+}
+
+ResourceError FrameLoaderClientImpl::cancelledError(const ResourceRequest& request)
+{
+    if (!m_webFrame->client())
+        return ResourceError();
+
+    return m_webFrame->client()->cancelledError(
+        m_webFrame, WrappedResourceRequest(request));
+}
+
+ResourceError FrameLoaderClientImpl::cannotShowURLError(const ResourceRequest& request)
+{
+    if (!m_webFrame->client())
+        return ResourceError();
+
+    return m_webFrame->client()->cannotHandleRequestError(
+        m_webFrame, WrappedResourceRequest(request));
+}
+
+ResourceError FrameLoaderClientImpl::interruptForPolicyChangeError(
+    const ResourceRequest& request)
+{
+    return ResourceError(internalErrorDomain, PolicyChangeError,
+                         request.url().string(), String());
+}
+
+ResourceError FrameLoaderClientImpl::cannotShowMIMETypeError(const ResourceResponse&)
+{
+    // FIXME
+    return ResourceError();
+}
+
+ResourceError FrameLoaderClientImpl::fileDoesNotExistError(const ResourceResponse&)
+{
+    // FIXME
+    return ResourceError();
+}
+
+ResourceError FrameLoaderClientImpl::pluginWillHandleLoadError(const ResourceResponse&)
+{
+    // FIXME
+    return ResourceError();
+}
+
+bool FrameLoaderClientImpl::shouldFallBack(const ResourceError& error)
+{
+    // This method is called when we fail to load the URL for an <object> tag
+    // that has fallback content (child elements) and is being loaded as a frame.
+    // The error parameter indicates the reason for the load failure.
+    // We should let the fallback content load only if this wasn't a cancelled
+    // request.
+    // Note: The mac version also has a case for "WebKitErrorPluginWillHandleLoad"
+    ResourceError c = cancelledError(ResourceRequest());
+    return error.errorCode() != c.errorCode() || error.domain() != c.domain();
+}
+
+bool FrameLoaderClientImpl::canHandleRequest(const ResourceRequest& request) const
+{
+    return m_webFrame->client()->canHandleRequest(
+        m_webFrame, WrappedResourceRequest(request));
+}
+
+bool FrameLoaderClientImpl::canShowMIMEType(const String& mimeType) const
+{
+    // This method is called to determine if the media type can be shown
+    // "internally" (i.e. inside the browser) regardless of whether or not the
+    // browser or a plugin is doing the rendering.
+
+    // mimeType strings are supposed to be ASCII, but if they are not for some
+    // reason, then it just means that the mime type will fail all of these "is
+    // supported" checks and go down the path of an unhandled mime type.
+    if (webKitClient()->mimeRegistry()->supportsMIMEType(mimeType) == WebMimeRegistry::IsSupported)
+        return true;
+
+    // If Chrome is started with the --disable-plugins switch, pluginData is null.
+    PluginData* pluginData = m_webFrame->frame()->page()->pluginData();
+
+    // See if the type is handled by an installed plugin, if so, we can show it.
+    // FIXME: (http://b/1085524) This is the place to stick a preference to
+    //        disable full page plugins (optionally for certain types!)
+    return !mimeType.isEmpty() && pluginData && pluginData->supportsMimeType(mimeType);
+}
+
+bool FrameLoaderClientImpl::representationExistsForURLScheme(const String&) const
+{
+    // FIXME
+    return false;
+}
+
+String FrameLoaderClientImpl::generatedMIMETypeForURLScheme(const String& scheme) const
+{
+    // This appears to generate MIME types for protocol handlers that are handled
+    // internally. The only place I can find in the WebKit code that uses this
+    // function is WebView::registerViewClass, where it is used as part of the
+    // process by which custom view classes for certain document representations
+    // are registered.
+    String mimeType("x-apple-web-kit/");
+    mimeType.append(scheme.lower());
+    return mimeType;
+}
+
+void FrameLoaderClientImpl::frameLoadCompleted()
+{
+    // FIXME: the mac port also conditionally calls setDrawsBackground:YES on
+    // it's ScrollView here.
+
+    // This comment from the Mac port:
+    // Note: Can be called multiple times.
+    // Even if already complete, we might have set a previous item on a frame that
+    // didn't do any data loading on the past transaction. Make sure to clear these out.
+
+    // FIXME: setPreviousHistoryItem() no longer exists. http://crbug.com/8566
+    // m_webFrame->frame()->loader()->setPreviousHistoryItem(0);
+}
+
+void FrameLoaderClientImpl::saveViewStateToItem(HistoryItem*)
+{
+    // FIXME
+}
+
+void FrameLoaderClientImpl::restoreViewState()
+{
+    // FIXME: probably scrolls to last position when you go back or forward
+}
+
+void FrameLoaderClientImpl::provisionalLoadStarted()
+{
+    // FIXME: On mac, this does various caching stuff
+}
+
+void FrameLoaderClientImpl::didFinishLoad()
+{
+    OwnPtr<WebPluginLoadObserver> observer = pluginLoadObserver();
+    if (observer)
+        observer->didFinishLoading();
+}
+
+void FrameLoaderClientImpl::prepareForDataSourceReplacement()
+{
+    // FIXME
+}
+
+PassRefPtr<DocumentLoader> FrameLoaderClientImpl::createDocumentLoader(
+    const ResourceRequest& request,
+    const SubstituteData& data)
+{
+    RefPtr<WebDataSourceImpl> ds = WebDataSourceImpl::create(request, data);
+    if (m_webFrame->client())
+        m_webFrame->client()->didCreateDataSource(m_webFrame, ds.get());
+    return ds.release();
+}
+
+void FrameLoaderClientImpl::setTitle(const String& title, const KURL& url)
+{
+    // FIXME: inform consumer of changes to the title.
+}
+
+String FrameLoaderClientImpl::userAgent(const KURL& url)
+{
+    return webKitClient()->userAgent(url);
+}
+
+void FrameLoaderClientImpl::savePlatformDataToCachedFrame(CachedFrame*)
+{
+    // The page cache should be disabled.
+    ASSERT_NOT_REACHED();
+}
+
+void FrameLoaderClientImpl::transitionToCommittedFromCachedFrame(CachedFrame*)
+{
+    ASSERT_NOT_REACHED();
+}
+
+// Called when the FrameLoader goes into a state in which a new page load
+// will occur.
+void FrameLoaderClientImpl::transitionToCommittedForNewPage()
+{
+    makeDocumentView();
+}
+
+bool FrameLoaderClientImpl::canCachePage() const
+{
+    // Since we manage the cache, always report this page as non-cacheable to
+    // FrameLoader.
+    return false;
+}
+
+// Downloading is handled in the browser process, not WebKit. If we get to this
+// point, our download detection code in the ResourceDispatcherHost is broken!
+void FrameLoaderClientImpl::download(ResourceHandle* handle,
+                                     const ResourceRequest& request,
+                                     const ResourceRequest& initialRequest,
+                                     const ResourceResponse& response)
+{
+    ASSERT_NOT_REACHED();
+}
+
+PassRefPtr<Frame> FrameLoaderClientImpl::createFrame(
+    const KURL& url,
+    const String& name,
+    HTMLFrameOwnerElement* ownerElement,
+    const String& referrer,
+    bool allowsScrolling,
+    int marginWidth,
+    int marginHeight)
+{
+    FrameLoadRequest frameRequest(ResourceRequest(url, referrer), name);
+    return m_webFrame->createChildFrame(frameRequest, ownerElement);
+}
+
+PassRefPtr<Widget> FrameLoaderClientImpl::createPlugin(
+    const IntSize& size, // FIXME: how do we use this?
+    HTMLPlugInElement* element,
+    const KURL& url,
+    const Vector<String>& paramNames,
+    const Vector<String>& paramValues,
+    const String& mimeType,
+    bool loadManually)
+{
+#if !PLATFORM(WIN_OS)
+    // WebCore asks us to make a plugin even if we don't have a
+    // registered handler, with a comment saying it's so we can display
+    // the broken plugin icon.  In Chromium, we normally register a
+    // fallback plugin handler that allows you to install a missing
+    // plugin.  Since we don't yet have a default plugin handler, we
+    // need to return null here rather than going through all the
+    // plugin-creation IPCs only to discover we don't have a plugin
+    // registered, which causes a crash.
+    // FIXME: remove me once we have a default plugin.
+    if (objectContentType(url, mimeType) != ObjectContentNetscapePlugin)
+        return 0;
+#endif
+
+    if (!m_webFrame->client())
+        return 0;
+
+    WebPluginParams params;
+    params.url = url;
+    params.mimeType = mimeType;
+    params.attributeNames = paramNames;
+    params.attributeValues = paramValues;
+    params.loadManually = loadManually;
+
+    WebPlugin* webPlugin = m_webFrame->client()->createPlugin(m_webFrame, params);
+    if (!webPlugin)
+        return 0;
+
+    // The container takes ownership of the WebPlugin.
+    RefPtr<WebPluginContainerImpl> container =
+        WebPluginContainerImpl::create(element, webPlugin);
+
+    if (!webPlugin->initialize(container.get()))
+        return 0;
+
+    // The element might have been removed during plugin initialization!
+    if (!element->renderer())
+        return 0;
+
+    return container;
+}
+
+// This method gets called when a plugin is put in place of html content
+// (e.g., acrobat reader).
+void FrameLoaderClientImpl::redirectDataToPlugin(Widget* pluginWidget)
+{
+    m_pluginWidget = static_cast<WebPluginContainerImpl*>(pluginWidget);
+    ASSERT(m_pluginWidget.get());
+}
+
+PassRefPtr<Widget> FrameLoaderClientImpl::createJavaAppletWidget(
+    const IntSize& size,
+    HTMLAppletElement* element,
+    const KURL& /* baseURL */,
+    const Vector<String>& paramNames,
+    const Vector<String>& paramValues)
+{
+    return createPlugin(size, element, KURL(), paramNames, paramValues,
+        "application/x-java-applet", false);
+}
+
+ObjectContentType FrameLoaderClientImpl::objectContentType(
+    const KURL& url,
+    const String& explicitMimeType)
+{
+    // This code is based on Apple's implementation from
+    // WebCoreSupport/WebFrameBridge.mm.
+
+    String mimeType = explicitMimeType;
+    if (mimeType.isEmpty()) {
+        // Try to guess the MIME type based off the extension.
+        String filename = url.lastPathComponent();
+        int extensionPos = filename.reverseFind('.');
+        if (extensionPos >= 0)
+            mimeType = MIMETypeRegistry::getMIMETypeForPath(url.path());
+
+        if (mimeType.isEmpty())
+            return ObjectContentFrame;
+    }
+
+    if (MIMETypeRegistry::isSupportedImageMIMEType(mimeType))
+        return ObjectContentImage;
+
+    // If Chrome is started with the --disable-plugins switch, pluginData is 0.
+    PluginData* pluginData = m_webFrame->frame()->page()->pluginData();
+    if (pluginData && pluginData->supportsMimeType(mimeType))
+        return ObjectContentNetscapePlugin;
+
+    if (MIMETypeRegistry::isSupportedNonImageMIMEType(mimeType))
+        return ObjectContentFrame;
+
+    return ObjectContentNone;
+}
+
+String FrameLoaderClientImpl::overrideMediaType() const
+{
+    // FIXME
+    return String();
+}
+
+bool FrameLoaderClientImpl::actionSpecifiesNavigationPolicy(
+    const NavigationAction& action,
+    WebNavigationPolicy* policy)
+{
+    if ((action.type() != NavigationTypeLinkClicked) || !action.event()->isMouseEvent())
+        return false;
+
+    const MouseEvent* event = static_cast<const MouseEvent*>(action.event());
+    return WebViewImpl::navigationPolicyFromMouseEvent(
+        event->button(), event->ctrlKey(), event->shiftKey(), event->altKey(),
+        event->metaKey(), policy);
+}
+
+void FrameLoaderClientImpl::handleBackForwardNavigation(const KURL& url)
+{
+    ASSERT(url.protocolIs(backForwardNavigationScheme));
+
+    bool ok;
+    int offset = url.lastPathComponent().toIntStrict(&ok);
+    if (!ok)
+        return;
+
+    WebViewImpl* webview = m_webFrame->viewImpl();
+    if (webview->client())
+        webview->client()->navigateBackForwardSoon(offset);
+}
+
+PassOwnPtr<WebPluginLoadObserver> FrameLoaderClientImpl::pluginLoadObserver()
+{
+    WebDataSourceImpl* ds = WebDataSourceImpl::fromDocumentLoader(
+        m_webFrame->frame()->loader()->activeDocumentLoader());
+    return ds->releasePluginLoadObserver();
+}
+
+} // namespace WebKit
diff --git a/WebKit/chromium/src/FrameLoaderClientImpl.h b/WebKit/chromium/src/FrameLoaderClientImpl.h
new file mode 100644 (file)
index 0000000..d5592f9
--- /dev/null
@@ -0,0 +1,234 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef FrameLoaderClientImpl_h
+#define FrameLoaderClientImpl_h
+
+// FIXME: remove this relative path once consumers from glue are removed.
+#include "../public/WebNavigationPolicy.h"
+#include "FrameLoaderClient.h"
+#include "KURL.h"
+#include <wtf/PassOwnPtr.h>
+#include <wtf/RefPtr.h>
+
+
+namespace WebKit {
+
+class WebFrameImpl;
+class WebPluginContainerImpl;
+class WebPluginLoadObserver;
+
+class FrameLoaderClientImpl : public WebCore::FrameLoaderClient {
+public:
+    FrameLoaderClientImpl(WebFrameImpl* webFrame);
+    ~FrameLoaderClientImpl();
+
+    WebFrameImpl* webFrame() const { return m_webFrame; }
+
+    // WebCore::FrameLoaderClient ----------------------------------------------
+
+    virtual void frameLoaderDestroyed();
+
+    // Notifies the WebView delegate that the JS window object has been cleared,
+    // giving it a chance to bind native objects to the window before script
+    // parsing begins.
+    virtual void windowObjectCleared();
+    virtual void documentElementAvailable();
+
+    // A frame's V8 context was created or destroyed.
+    virtual void didCreateScriptContextForFrame();
+    virtual void didDestroyScriptContextForFrame();
+
+    // A context untied to a frame was created (through evaluateInNewContext).
+    // This context is not tied to the lifetime of its frame, and is destroyed
+    // in garbage collection.
+    virtual void didCreateIsolatedScriptContext();
+
+    virtual bool hasWebView() const;
+    virtual bool hasFrameView() const;
+    virtual void makeRepresentation(WebCore::DocumentLoader*);
+    virtual void forceLayout();
+    virtual void forceLayoutForNonHTML();
+    virtual void setCopiesOnScroll();
+    virtual void detachedFromParent2();
+    virtual void detachedFromParent3();
+    virtual void assignIdentifierToInitialRequest(unsigned long identifier, WebCore::DocumentLoader*, const WebCore::ResourceRequest&);
+    virtual void dispatchWillSendRequest(WebCore::DocumentLoader*, unsigned long identifier, WebCore::ResourceRequest&, const WebCore::ResourceResponse& redirectResponse);
+    virtual bool shouldUseCredentialStorage(WebCore::DocumentLoader*, unsigned long identifier);
+    virtual void dispatchDidReceiveAuthenticationChallenge(WebCore::DocumentLoader*, unsigned long identifier, const WebCore::AuthenticationChallenge&);
+    virtual void dispatchDidCancelAuthenticationChallenge(WebCore::DocumentLoader*, unsigned long identifier, const WebCore::AuthenticationChallenge&);
+    virtual void dispatchDidReceiveResponse(WebCore::DocumentLoader*, unsigned long identifier, const WebCore::ResourceResponse&);
+    virtual void dispatchDidReceiveContentLength(WebCore::DocumentLoader*, unsigned long identifier, int lengthReceived);
+    virtual void dispatchDidFinishLoading(WebCore::DocumentLoader*, unsigned long identifier);
+    virtual void dispatchDidFailLoading(WebCore::DocumentLoader*, unsigned long identifier, const WebCore::ResourceError&);
+    virtual bool dispatchDidLoadResourceFromMemoryCache(WebCore::DocumentLoader*, const WebCore::ResourceRequest&, const WebCore::ResourceResponse&, int length);
+    virtual void dispatchDidLoadResourceByXMLHttpRequest(unsigned long identifier, const WebCore::ScriptString&);
+    virtual void dispatchDidHandleOnloadEvents();
+    virtual void dispatchDidReceiveServerRedirectForProvisionalLoad();
+    virtual void dispatchDidCancelClientRedirect();
+    virtual void dispatchWillPerformClientRedirect(const WebCore::KURL&, double interval, double fireDate);
+    virtual void dispatchDidChangeLocationWithinPage();
+    virtual void dispatchWillClose();
+    virtual void dispatchDidReceiveIcon();
+    virtual void dispatchDidStartProvisionalLoad();
+    virtual void dispatchDidReceiveTitle(const WebCore::String& title);
+    virtual void dispatchDidCommitLoad();
+    virtual void dispatchDidFailProvisionalLoad(const WebCore::ResourceError&);
+    virtual void dispatchDidFailLoad(const WebCore::ResourceError&);
+    virtual void dispatchDidFinishDocumentLoad();
+    virtual void dispatchDidFinishLoad();
+    virtual void dispatchDidFirstLayout();
+    virtual void dispatchDidFirstVisuallyNonEmptyLayout();
+    virtual WebCore::Frame* dispatchCreatePage();
+    virtual void dispatchShow();
+    virtual void dispatchDecidePolicyForMIMEType(WebCore::FramePolicyFunction function, const WebCore::String& mime_type, const WebCore::ResourceRequest&);
+    virtual void dispatchDecidePolicyForNewWindowAction(WebCore::FramePolicyFunction function, const WebCore::NavigationAction& action, const WebCore::ResourceRequest& request, PassRefPtr<WebCore::FormState> form_state, const WebCore::String& frame_name);
+    virtual void dispatchDecidePolicyForNavigationAction(WebCore::FramePolicyFunction function, const WebCore::NavigationAction& action, const WebCore::ResourceRequest& request, PassRefPtr<WebCore::FormState> form_state);
+    virtual void cancelPolicyCheck();
+    virtual void dispatchUnableToImplementPolicy(const WebCore::ResourceError&);
+    virtual void dispatchWillSubmitForm(WebCore::FramePolicyFunction, PassRefPtr<WebCore::FormState>);
+    virtual void dispatchDidLoadMainResource(WebCore::DocumentLoader*);
+    virtual void revertToProvisionalState(WebCore::DocumentLoader*);
+    virtual void setMainDocumentError(WebCore::DocumentLoader*, const WebCore::ResourceError&);
+    virtual void willChangeEstimatedProgress() { }
+    virtual void didChangeEstimatedProgress() { }
+    virtual void postProgressStartedNotification();
+    virtual void postProgressEstimateChangedNotification();
+    virtual void postProgressFinishedNotification();
+    virtual void setMainFrameDocumentReady(bool);
+    virtual void startDownload(const WebCore::ResourceRequest&);
+    virtual void willChangeTitle(WebCore::DocumentLoader*);
+    virtual void didChangeTitle(WebCore::DocumentLoader*);
+    virtual void committedLoad(WebCore::DocumentLoader*, const char*, int);
+    virtual void finishedLoading(WebCore::DocumentLoader*);
+    virtual void updateGlobalHistory();
+    virtual void updateGlobalHistoryRedirectLinks();
+    virtual bool shouldGoToHistoryItem(WebCore::HistoryItem*) const;
+    virtual void didDisplayInsecureContent();
+    virtual void didRunInsecureContent(WebCore::SecurityOrigin*);
+    virtual WebCore::ResourceError blockedError(const WebCore::ResourceRequest&);
+    virtual WebCore::ResourceError cancelledError(const WebCore::ResourceRequest&);
+    virtual WebCore::ResourceError cannotShowURLError(const WebCore::ResourceRequest&);
+    virtual WebCore::ResourceError interruptForPolicyChangeError(const WebCore::ResourceRequest&);
+    virtual WebCore::ResourceError cannotShowMIMETypeError(const WebCore::ResourceResponse&);
+    virtual WebCore::ResourceError fileDoesNotExistError(const WebCore::ResourceResponse&);
+    virtual WebCore::ResourceError pluginWillHandleLoadError(const WebCore::ResourceResponse&);
+    virtual bool shouldFallBack(const WebCore::ResourceError&);
+    virtual bool canHandleRequest(const WebCore::ResourceRequest&) const;
+    virtual bool canShowMIMEType(const WebCore::String& MIMEType) const;
+    virtual bool representationExistsForURLScheme(const WebCore::String& URLScheme) const;
+    virtual WebCore::String generatedMIMETypeForURLScheme(const WebCore::String& URLScheme) const;
+    virtual void frameLoadCompleted();
+    virtual void saveViewStateToItem(WebCore::HistoryItem*);
+    virtual void restoreViewState();
+    virtual void provisionalLoadStarted();
+    virtual void didFinishLoad();
+    virtual void prepareForDataSourceReplacement();
+    virtual PassRefPtr<WebCore::DocumentLoader> createDocumentLoader(
+        const WebCore::ResourceRequest&, const WebCore::SubstituteData&);
+    virtual void setTitle(const WebCore::String& title, const WebCore::KURL&);
+    virtual WebCore::String userAgent(const WebCore::KURL&);
+    virtual void savePlatformDataToCachedFrame(WebCore::CachedFrame*);
+    virtual void transitionToCommittedFromCachedFrame(WebCore::CachedFrame*);
+    virtual void transitionToCommittedForNewPage();
+    virtual bool canCachePage() const;
+    virtual void download(
+        WebCore::ResourceHandle*, const WebCore::ResourceRequest&,
+        const WebCore::ResourceRequest& initialRequest,
+        const WebCore::ResourceResponse&);
+    virtual PassRefPtr<WebCore::Frame> createFrame(
+        const WebCore::KURL& url, const WebCore::String& name,
+        WebCore::HTMLFrameOwnerElement* ownerElement,
+        const WebCore::String& referrer, bool allowsScrolling,
+        int marginWidth, int marginHeight);
+    virtual PassRefPtr<WebCore::Widget> createPlugin(
+        const WebCore::IntSize&, WebCore::HTMLPlugInElement*, const WebCore::KURL&,
+        const Vector<WebCore::String>&, const Vector<WebCore::String>&,
+        const WebCore::String&, bool loadManually);
+    virtual void redirectDataToPlugin(WebCore::Widget* pluginWidget);
+    virtual PassRefPtr<WebCore::Widget> createJavaAppletWidget(
+        const WebCore::IntSize&,
+        WebCore::HTMLAppletElement*,
+        const WebCore::KURL& /* base_url */,
+        const Vector<WebCore::String>& paramNames,
+        const Vector<WebCore::String>& paramValues);
+    virtual WebCore::ObjectContentType objectContentType(
+        const WebCore::KURL& url, const WebCore::String& mimeType);
+    virtual WebCore::String overrideMediaType() const;
+    virtual void didPerformFirstNavigation() const;
+    virtual void registerForIconNotification(bool listen = true);
+    virtual void didChangeScrollOffset();
+    virtual bool allowJavaScript(bool enabledPerSettings);
+
+private:
+    void makeDocumentView();
+
+    // Given a NavigationAction, determine the associated WebNavigationPolicy.
+    // For example, a middle click means "open in background tab".
+    static bool actionSpecifiesNavigationPolicy(
+        const WebCore::NavigationAction& action, WebNavigationPolicy* policy);
+
+    // Called when a dummy back-forward navigation is intercepted.
+    void handleBackForwardNavigation(const WebCore::KURL&);
+
+    PassOwnPtr<WebPluginLoadObserver> pluginLoadObserver();
+
+    // The WebFrame that owns this object and manages its lifetime. Therefore,
+    // the web frame object is guaranteed to exist.
+    WebFrameImpl* m_webFrame;
+
+    // True if makeRepresentation was called.  We don't actually have a concept
+    // of a "representation", but we need to know when we're expected to have one.
+    // See finishedLoading().
+    bool m_hasRepresentation;
+
+    // Used to help track client redirects. When a provisional load starts, it
+    // has no redirects in its chain. But in the case of client redirects, we want
+    // to add that initial load as a redirect. When we get a new provisional load
+    // and the dest URL matches that load, we know that it was the result of a
+    // previous client redirect and the source should be added as a redirect.
+    // Both should be empty if unused.
+    WebCore::KURL m_expectedClientRedirectSrc;
+    WebCore::KURL m_expectedClientRedirectDest;
+
+    // Contains a pointer to the plugin widget.
+    RefPtr<WebPluginContainerImpl> m_pluginWidget;
+
+    // Indicates if we need to send over the initial notification to the plugin
+    // which specifies that the plugin should be ready to accept data.
+    bool m_sentInitialResponseToPlugin;
+
+    // The navigation policy to use for the next call to dispatchCreatePage.
+    WebNavigationPolicy m_nextNavigationPolicy;
+};
+
+} // namespace WebKit
+
+#endif