# Copyright (C) 2010, 2011 Apple 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 INC. AND ITS 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 APPLE INC. OR ITS 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.

messages -> WebPageProxy {
    # UI messages
    CreateNewPage(WebCore::WindowFeatures windowFeatures, uint32_t modifiers, int32_t mouseButton) -> (uint64_t newPageID, WebKit::WebPageCreationParameters newPageParameters)
    ShowPage()
    ClosePage()
    RunJavaScriptAlert(uint64_t frameID, WTF::String message) -> ()
    RunJavaScriptConfirm(uint64_t frameID, WTF::String message) -> (bool result)
    RunJavaScriptPrompt(uint64_t frameID, WTF::String message, WTF::String defaultValue) -> (WTF::String result)
    MouseDidMoveOverElement(uint32_t modifiers, WebKit::InjectedBundleUserMessageEncoder userData);
    MissingPluginButtonClicked(WTF::String mimeType, WTF::String url, WTF::String pluginsPageURL)
    DidChangeViewportData(WebCore::ViewportArguments arguments)
    DidReceiveEvent(uint32_t type, bool handled)
    SetCursor(WebCore::Cursor cursor)
    SetStatusText(WTF::String statusText)
    SetToolTip(WTF::String toolTip)
    SetFocus(bool focused)
    TakeFocus(uint32_t direction)
    FocusedFrameChanged(uint64_t frameID)
    FrameSetLargestFrameChanged(uint64_t frameID)
    SetToolbarsAreVisible(bool toolbarsAreVisible)
    GetToolbarsAreVisible() -> (bool toolbarsAreVisible)
    SetMenuBarIsVisible(bool menuBarIsVisible);
    GetMenuBarIsVisible() -> (bool menuBarIsVisible);
    SetStatusBarIsVisible(bool statusBarIsVisible)
    GetStatusBarIsVisible() -> (bool statusBarIsVisible)
    SetIsResizable(bool isResizable)
    GetIsResizable() -> (bool isResizable)
    SetWindowFrame(WebCore::FloatRect windowFrame)
    GetWindowFrame() -> (WebCore::FloatRect windowFrame)
    WindowToScreen(WebCore::IntRect rect) -> (WebCore::IntRect screenFrame)
    RunBeforeUnloadConfirmPanel(WTF::String message, uint64_t frameID) -> (bool shouldClose)
    PageDidScroll()
    RunOpenPanel(uint64_t frameID, WebKit::WebOpenPanelParameters::Data parameters)
    PrintFrame(uint64_t frameID) -> ()
    RunModal()
    DidCompleteRubberBandForMainFrame(WebCore::IntSize initialOverhang)
    DidChangeScrollbarsForMainFrame(bool hasHorizontalScrollbar, bool hasVerticalScrollbar)
    DidChangeScrollOffsetPinningForMainFrame(bool hasHorizontalScrollbar, bool hasVerticalScrollbar)

#if ENABLE(TILED_BACKING_STORE)
    PageDidRequestScroll(WebCore::IntPoint point)
#endif
#if PLATFORM(QT)
    DidChangeContentsSize(WebCore::IntSize newSize)
    DidFindZoomableArea(WebCore::IntRect area)
#endif

    # Policy messages
    DecidePolicyForResponse(uint64_t frameID, WebCore::ResourceResponse response, WebCore::ResourceRequest request, uint64_t listenerID, WebKit::InjectedBundleUserMessageEncoder userData) -> (bool receivedPolicyAction, uint64_t policyAction, uint64_t downloadID)
    DecidePolicyForNavigationAction(uint64_t frameID, uint32_t navigationType, uint32_t modifiers, int32_t mouseButton, WebCore::ResourceRequest request, uint64_t listenerID, WebKit::InjectedBundleUserMessageEncoder userData) -> (bool receivedPolicyAction, uint64_t policyAction, uint64_t downloadID)
    DecidePolicyForNewWindowAction(uint64_t frameID, uint32_t navigationType, uint32_t modifiers, int32_t mouseButton, WebCore::ResourceRequest request, WTF::String frameName, uint64_t listenerID, WebKit::InjectedBundleUserMessageEncoder userData)
    UnableToImplementPolicy(uint64_t frameID, WebCore::ResourceError error, WebKit::InjectedBundleUserMessageEncoder userData)

    # Progress messages
    DidChangeProgress(double value)
    DidFinishProgress()
    DidStartProgress()

    # Frame lifetime messages
    DidCreateMainFrame(uint64_t frameID)
    DidCreateSubframe(uint64_t frameID, uint64_t parentFrameID)
    DidSaveFrameToPageCache(uint64_t frameID);
    DidRestoreFrameFromPageCache(uint64_t frameID, uint64_t parentFrameID);

    # Frame load messages
    DidCommitLoadForFrame(uint64_t frameID, WTF::String mimeType, bool hasCustomRepresentation, WebKit::PlatformCertificateInfo certificateInfo, WebKit::InjectedBundleUserMessageEncoder userData)
    DidFailLoadForFrame(uint64_t frameID, WebCore::ResourceError error, WebKit::InjectedBundleUserMessageEncoder userData)
    DidFailProvisionalLoadForFrame(uint64_t frameID, WebCore::ResourceError error, WebKit::InjectedBundleUserMessageEncoder userData)
    DidFinishDocumentLoadForFrame(uint64_t frameID, WebKit::InjectedBundleUserMessageEncoder userData)
    DidFinishLoadForFrame(uint64_t frameID, WebKit::InjectedBundleUserMessageEncoder userData)
    DidFirstLayoutForFrame(uint64_t frameID, WebKit::InjectedBundleUserMessageEncoder userData)
    DidFirstVisuallyNonEmptyLayoutForFrame(uint64_t frameID, WebKit::InjectedBundleUserMessageEncoder userData)
    DidReceiveServerRedirectForProvisionalLoadForFrame(uint64_t frameID, WTF::String url, WebKit::InjectedBundleUserMessageEncoder userData)
    DidRemoveFrameFromHierarchy(uint64_t frameID, WebKit::InjectedBundleUserMessageEncoder userData)
    DidStartProvisionalLoadForFrame(uint64_t frameID, WTF::String url, WTF::String unreachableURL, WebKit::InjectedBundleUserMessageEncoder userData)
    DidReceiveTitleForFrame(uint64_t frameID, WTF::String title, WebKit::InjectedBundleUserMessageEncoder userData)
    DidDisplayInsecureContentForFrame(uint64_t frameID, WebKit::InjectedBundleUserMessageEncoder userData)
    DidRunInsecureContentForFrame(uint64_t frameID, WebKit::InjectedBundleUserMessageEncoder userData)
    DidSameDocumentNavigationForFrame(uint64_t frameID, uint32_t type, WTF::String url, WebKit::InjectedBundleUserMessageEncoder userData)

    FrameDidBecomeFrameSet(uint64_t frameID, bool value)

    # Resource load messages
    DidInitiateLoadForResource(uint64_t frameID, uint64_t resourceIdentifier, WebCore::ResourceRequest request, bool pageIsProvisionallyLoading)
    DidSendRequestForResource(uint64_t frameID, uint64_t resourceIdentifier, WebCore::ResourceRequest request, WebCore::ResourceResponse redirectResponse)
    DidReceiveResponseForResource(uint64_t frameID, uint64_t resourceIdentifier, WebCore::ResourceResponse response)
    DidReceiveContentLengthForResource(uint64_t frameID, uint64_t resourceIdentifier, uint64_t contentLength)
    DidFinishLoadForResource(uint64_t frameID, uint64_t resourceIdentifier)
    DidFailLoadForResource(uint64_t frameID, uint64_t resourceIdentifier, WebCore::ResourceError error)

    # Custom representations
    DidFinishLoadingDataForCustomRepresentation(WTF::String suggestedFilename, CoreIPC::DataReference data)

    # Forms messages
    WillSubmitForm(uint64_t frameID, uint64_t sourceFrameID, WebKit::StringPairVector textFieldValues, uint64_t listenerID, WebKit::InjectedBundleUserMessageEncoder userData)

    # Callback messages
    VoidCallback(uint64_t callbackID)
    DataCallback(CoreIPC::DataReference resultData, uint64_t callbackID)
    StringCallback(WTF::String resultString, uint64_t callbackID)
    ScriptValueCallback(CoreIPC::DataReference resultData, uint64_t callbackID)
    ComputedPagesCallback(Vector<WebCore::IntRect> pageRects, double totalScaleFactorForPrinting, uint64_t callbackID)
    ValidateCommandCallback(WTF::String command, bool isEnabled, int32_t state, uint64_t callbackID)

    ViewScaleFactorDidChange(double scaleFactor)

#if PLATFORM(GTK)
    # Support for GTK+ platform keybindings
    GetEditorCommandsForKeyEvent() -> (Vector<WTF::String> commandsList)
#endif

    # BackForward messages
    BackForwardAddItem(uint64_t itemID)
    BackForwardGoToItem(uint64_t itemID)
    BackForwardItemAtIndex(int32_t itemIndex) -> (uint64_t itemID)
    BackForwardBackListCount() -> (int32_t count)
    BackForwardForwardListCount() -> (int32_t count)
    BackForwardClear()
    ShouldGoToBackForwardListItem(uint64_t itemID) -> (bool shouldGoToBackForwardListItem)

    # Undo/Redo messages
    RegisterEditCommandForUndo(uint64_t commandID, uint32_t editAction)
    ClearAllEditCommands()
    CanUndoRedo(uint32_t action) -> (bool result)
    ExecuteUndoRedo(uint32_t action) -> (bool result)

    # Editor notifications
    EditorStateChanged(WebKit::EditorState editorState)
#if PLATFORM(WIN)
    DidChangeCompositionSelection(bool hasChanged)
#endif

    # Find messages
    DidCountStringMatches(WTF::String string, uint32_t matchCount)
    SetFindIndicator(WebCore::FloatRect selectionRect, Vector<WebCore::FloatRect> textRects, WebKit::ShareableBitmap::Handle contentImageHandle, bool fadeOut)
    DidFindString(WTF::String string, uint32_t matchCount)
    DidFailToFindString(WTF::String string)

    # PopupMenu messages
    ShowPopupMenu(WebCore::IntRect rect, uint64_t textDirection, Vector<WebKit::WebPopupItem> items, int32_t selectedIndex, WebKit::PlatformPopupMenuData data)
    HidePopupMenu()
#if PLATFORM(WIN)
    SetPopupMenuSelectedIndex(int32_t selectedIndex)
#endif

    # ContextMenu messages
    ShowContextMenu(WebCore::IntPoint menuLocation, WebKit::ContextMenuState state, Vector<WebKit::WebContextMenuItemData> items, WebKit::InjectedBundleUserMessageEncoder userData)

    # Authentication messages
    CanAuthenticateAgainstProtectionSpaceInFrame(uint64_t frameID, WebCore::ProtectionSpace protectionSpace) -> (bool canAuthenticate)
    DidReceiveAuthenticationChallenge(uint64_t frameID, WebCore::AuthenticationChallenge challenge, uint64_t challengeID)

    # Database messages
    ExceededDatabaseQuota(uint64_t frameID, WTF::String originIdentifier, WTF::String databaseName, WTF::String databaseDisplayName, uint64_t currentQuota, uint64_t currentUsage, uint64_t expectedUsage) -> (uint64_t newQuota)

    # Geolocation messages
    RequestGeolocationPermissionForFrame(uint64_t geolocationID, uint64_t frameID, WTF::String originIdentifier)

    # Spelling and grammar messages
#if USE(UNIFIED_TEXT_CHECKING)  
    CheckTextOfParagraph(WTF::String text, uint64_t checkingTypes) -> (Vector<WebCore::TextCheckingResult> results)
#endif
    CheckSpellingOfString(WTF::String text) -> (int32_t misspellingLocation, int32_t misspellingLength)
    CheckGrammarOfString(WTF::String text) -> (Vector<WebCore::GrammarDetail> results, int32_t badGrammarLocation, int32_t badGrammarLength)
    SpellingUIIsShowing() -> (bool isShowing)
    UpdateSpellingUIWithMisspelledWord(WTF::String misspelledWord)
    UpdateSpellingUIWithGrammarString(WTF::String badGrammarPhrase, WebCore::GrammarDetail grammarDetail)
    GetGuessesForWord(WTF::String word, WTF::String context) -> (Vector<WTF::String> guesses)
    LearnWord(WTF::String word);
    IgnoreWord(WTF::String word);

    # Drag and drop messages
    DidPerformDragControllerAction(uint64_t resultOperation)
#if PLATFORM(MAC)
    SetDragImage(WebCore::IntPoint clientPosition, WebKit::ShareableBitmap::Handle dragImage, bool linkDrag)
#endif
#if PLATFORM(WIN)
    StartDragDrop(WebCore::IntPoint imagePoint, WebCore::IntPoint dragPoint, uint64_t okEffect, HashMap<UINT,Vector<String> > dataMap, WebCore::IntSize dragImageSize, WebKit::SharedMemory::Handle dragImage, bool linkDrag)
#endif

#if PLATFORM(MAC)
    # Dictionary support.
    DidPerformDictionaryLookup(WTF::String text, WebKit::DictionaryPopupInfo dictionaryPopupInfo)

    # Keyboard input support messages
    InterpretQueuedKeyEvent(WebKit::EditorState state) -> (bool handled, Vector<WebCore::KeypressCommand> savedCommands)
    ExecuteSavedCommandBySelector(WTF::String selector) -> (bool handled)

    # Remote accessibility messages
    RegisterWebProcessAccessibilityToken(CoreIPC::DataReference data)

    # Plug-in complex text input support messages
    SetComplexTextInputEnabled(uint64_t pluginComplexTextInputIdentifier, bool complexTextInputEnabled)

    # Speech messages
    GetIsSpeaking() -> (bool isSpeaking)
    Speak(WTF::String string)
    StopSpeaking()

    # Spotlight
    SearchWithSpotlight(WTF::String string)
#endif

#if PLATFORM(MAC)
    SubstitutionsPanelIsShowing() -> (bool isShowing)
#endif
#if PLATFORM(MAC) && !defined(BUILDING_ON_SNOW_LEOPARD)
    # Autocorrection messages
    ShowCorrectionPanel(int32_t panelType, WebCore::FloatRect boundingBoxOfReplacedString, String replacedString, String replacementString, Vector<String> alternativeReplacementStrings)
    DismissCorrectionPanel(int32_t reason)
    DismissCorrectionPanelSoon(int32_t reason) -> (String result)
    RecordAutocorrectionResponse(int32_t responseType, String replacedString, String replacementString);
#endif

#if PLATFORM(WIN)
    # Windows 7 Gesture Messages
    SetGestureReachedScrollingLimit(bool limitReached)
#endif

    # Search popup menus
    SaveRecentSearches(WTF::String name, Vector<String> searchItems)
    LoadRecentSearches(WTF::String name) -> (Vector<String> result)
}
