/*
 * Copyright (C) 2006, 2007 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 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. 
 */

cpp_quote("/*")
cpp_quote(" * Copyright (C) 2006, 2007 Apple Inc.  All rights reserved.")
cpp_quote(" *")
cpp_quote(" * Redistribution and use in source and binary forms, with or without")
cpp_quote(" * modification, are permitted provided that the following conditions")
cpp_quote(" * are met:")
cpp_quote(" * 1. Redistributions of source code must retain the above copyright")
cpp_quote(" *    notice, this list of conditions and the following disclaimer.")
cpp_quote(" * 2. Redistributions in binary form must reproduce the above copyright")
cpp_quote(" *    notice, this list of conditions and the following disclaimer in the")
cpp_quote(" *    documentation and/or other materials provided with the distribution.")
cpp_quote(" *")
cpp_quote(" * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY")
cpp_quote(" * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE")
cpp_quote(" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR")
cpp_quote(" * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR")
cpp_quote(" * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,")
cpp_quote(" * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,")
cpp_quote(" * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR")
cpp_quote(" * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY")
cpp_quote(" * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT")
cpp_quote(" * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE")
cpp_quote(" * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ")
cpp_quote(" */")

import "oaidl.idl";
import "ocidl.idl";
import "IWebFormDelegate.idl";
import "IWebFrameLoadDelegatePrivate.idl";
import "IWebInspector.idl";

[
    object,
    oleautomation,
    uuid(44914369-DEB5-4fcf-A6A3-30C02E73154F),
    pointer_default(unique)
]
interface IWebViewPrivate : IUnknown
{
    /*!
        @method _setInViewSourceMode:
        @abstract Used to place a WebView into a special source-viewing mode.
        - (void)_setInViewSourceMode:(BOOL)flag;
      */
    HRESULT setInViewSourceMode([in] BOOL flag);

    /*!
        @method _inViewSourceMode;
        @abstract Whether or not the WebView is in source-view mode for HTML.
        - (BOOL)_inViewSourceMode;
      */
    HRESULT inViewSourceMode([out, retval] BOOL* flag);

    HRESULT viewWindow([out, retval] OLE_HANDLE* window);

    // May well become public
    //- (void)_setFormDelegate:(id<WebFormDelegate>)delegate;
    HRESULT setFormDelegate([in] IWebFormDelegate* formDelegate);

    //- (id<WebFormDelegate>)_formDelegate;
    HRESULT formDelegate([out, retval] IWebFormDelegate** formDelegate);

    HRESULT setFrameLoadDelegatePrivate([in] IWebFrameLoadDelegatePrivate* frameLoadDelegatePrivate);
    HRESULT frameLoadDelegatePrivate([out, retval] IWebFrameLoadDelegatePrivate** frameLoadDelegatePrivate);

    HRESULT scrollOffset([out, retval] LPPOINT offset);
    HRESULT scrollBy([in] LPPOINT offset);
    HRESULT visibleContentRect([out, retval] LPRECT rect);
    
    // SPI for DumpRenderTree
    HRESULT updateFocusedAndActiveState();

    // Support for displaying multiple text matches.
    HRESULT markAllMatchesForText([in] BSTR search, [in] BOOL caseSensitive, [in] BOOL highlight, [in] UINT limit, [out] UINT* matches);
    HRESULT unmarkAllTextMatches();
    HRESULT rectsForTextMatches([out]IEnumTextMatches** pmatches);
    HRESULT selectionRect([in, out] RECT* rc);
    HRESULT generateSelectionImage(BOOL forceWhiteText, [out, retval] OLE_HANDLE* hBitmap);

    HRESULT canHandleRequest([in] IWebURLRequest* request, [out, retval] BOOL* result);

    HRESULT clearFocusNode();

    HRESULT setTabKeyCyclesThroughElements([in] BOOL cycles);
    HRESULT tabKeyCyclesThroughElements([out, retval] BOOL* result);

    HRESULT setAllowSiteSpecificHacks([in] BOOL allows);
    HRESULT addAdditionalPluginPath([in] BSTR path);

    HRESULT loadBackForwardListFromOtherView([in] IWebView* otherView);

    HRESULT setCustomDropTarget([in] IDropTarget* dt);
    HRESULT removeCustomDropTarget();

    HRESULT setInitialFocus([in] BOOL forward);

    HRESULT inspector([out, retval] IWebInspector**);

    HRESULT clearUndoRedoOperations();

    HRESULT setProhibitsMainFrameScrolling([in] BOOL prohibits);

    // SPI for DumpRenderTree. This is global to all WebViews.
    HRESULT setShouldApplyMacFontAscentHack([in] BOOL shouldApply);

    /*!
        @method shouldClose:
        @abstract This function will fire the before unload handler for a page.  
        If the user cancels the closing of a webview from the alert popped up by the 
        before unload handler, then this function will return false.
    */
    HRESULT shouldClose([out, retval] BOOL* result);

    // SPI for DumpRenderTree
    HRESULT executeCoreCommandByName([in] BSTR name, [in] BSTR value);

    HRESULT windowAncestryDidChange();

    HRESULT paintDocumentRectToContext([in] RECT rect, [in] OLE_HANDLE dc);

    HRESULT setDefersCallbacks([in] BOOL defersCallbacks);
    HRESULT defersCallbacks([out, retval] BOOL* defersCallbacks);

    HRESULT standardUserAgentWithApplicationName([in] BSTR applicationName, [retval][out] BSTR* groupName);
}
