/*
 * Copyright (C) 2006, 2007, 2008, 2014-2015 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. ``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
 * 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 DO_NO_IMPORTS
import "oaidl.idl";
import "ocidl.idl";
import "DOMHTML.idl";
import "IWebArchive.idl";
import "IWebFrameView.idl";
import "IWebView.idl";
import "IWebURLRequest.idl";
import "DOMCore.idl";
#endif

cpp_quote("// this is done to get midl to treat the JavaScriptCore API types as pointer types")
cpp_quote("#if 0")
typedef void* JSGlobalContextRef;
cpp_quote("#else")
cpp_quote("typedef struct OpaqueJSContext* JSGlobalContextRef;")
cpp_quote("#endif")

interface IDOMDocument;
interface IDOMElement;
interface IDOMHTMLElement;
interface IWebURLRequest;
interface IWebArchive;
interface IWebDataSource;
interface IWebFramePrivate;
interface IWebFrameView;
interface IWebView;

/*!
    @class WebFrame
    @discussion Every web page is represented by at least one WebFrame.  A WebFrame
    has a WebFrameView and a WebDataSource.
    @interface WebFrame : NSObject
*/
[
    object,
    oleautomation,
    uuid(B4B22EF7-DD43-4d01-A992-99C4A8B1F845),
    pointer_default(unique)
]
interface IWebFrame : IUnknown
{
    /*!
        @method name
        @result The frame name.
        - (NSString *)name;
    */
    HRESULT name([out, retval] BSTR* frameName);

    /*!
        @method webView
        @result Returns the WebView for the document that includes this frame.
        - (WebView *)webView;
    */
    HRESULT webView([out, retval] IWebView** view);

    /*!
        @method frameView
        @result The WebFrameView for this frame.
        - (WebFrameView *)frameView;
    */
    HRESULT frameView([out, retval] IWebFrameView** view);

    /*!
        @method DOMDocument
        @abstract Returns the DOM document of the frame.
        @description Returns nil if the frame does not contain a DOM document such as a standalone image.
        - (DOMDocument *)DOMDocument;
    */
    HRESULT DOMDocument([out, retval] IDOMDocument** document);

    /*!
        @method frameElement
        @abstract Returns the frame element of the frame.
        @description The class of the result is either DOMHTMLFrameElement, DOMHTMLIFrameElement or DOMHTMLObjectElement.
        Returns nil if the frame is the main frame since there is no frame element for the frame in this case.
        - (DOMHTMLElement *)frameElement;
    */
    HRESULT frameElement([out, retval] IDOMHTMLElement** frameElement);

    /*!
        @method loadRequest:
        @param request The web request to load.
        - (void)loadRequest:(NSURLRequest *)request;
    */
    HRESULT loadRequest([in] IWebURLRequest* request);

    /*!
        @method loadData:MIMEType:textEncodingName:baseURL:
        @param data The data to use for the main page of the document.
        @param MIMEType The MIME type of the data.
        @param encodingName The encoding of the data.
        @param URL The base URL to apply to relative URLs within the document.
        - (void)loadData:(NSData *)data MIMEType:(NSString *)MIMEType textEncodingName:(NSString *)encodingName baseURL:(NSURL *)URL;
    */
    HRESULT loadData([in] IStream* data, [in] BSTR mimeType, [in] BSTR textEncodingName, [in] BSTR url);

    /*!
        @method loadHTMLString:baseURL:
        @param string The string to use for the main page of the document.
        @param URL The base URL to apply to relative URLs within the document.
        - (void)loadHTMLString:(NSString *)string baseURL:(NSURL *)URL;
    */
    HRESULT loadHTMLString([in] BSTR string, [in] BSTR baseURL);

    /*!
        @method loadAlternateHTMLString:baseURL:forUnreachableURL:
        @abstract Loads a page to display as a substitute for a URL that could not be reached.
        @discussion This allows clients to display page-loading errors in the webview itself.
        This is typically called while processing the WebFrameLoadDelegate method
        -webView:didFailProvisionalLoadWithError:forFrame: or one of the the WebPolicyDelegate methods
        -webView:decidePolicyForMIMEType:request:frame:decisionListener: or
        -webView:unableToImplementPolicyWithError:frame:. If it is called from within one of those
        three delegate methods then the back/forward list will be maintained appropriately.
        @param string The string to use for the main page of the document.
        @param baseURL The baseURL to apply to relative URLs within the document.
        @param unreachableURL The URL for which this page will serve as alternate content.
        - (void)loadAlternateHTMLString:(NSString *)string baseURL:(NSURL *)baseURL forUnreachableURL:(NSURL *)unreachableURL;
    */
    HRESULT loadAlternateHTMLString([in] BSTR str, [in] BSTR baseURL, [in] BSTR unreachableURL);

    /*!
        @method loadArchive:
        @abstract Causes WebFrame to load a WebArchive.
        @param archive The archive to be loaded.
        - (void)loadArchive:(WebArchive *)archive;
    */
    HRESULT loadArchive([in] IWebArchive* archive);

    /*!
        @method dataSource
        @discussion Returns the committed data source.  Will return nil if the
        provisional data source hasn't yet been loaded.
        @result The datasource for this frame.
        - (WebDataSource *)dataSource;
    */
    HRESULT dataSource([out, retval] IWebDataSource** source);

    /*!
        @method provisionalDataSource
        @discussion Will return the provisional data source.  The provisional data source will
        be nil if no data source has been set on the frame, or the data source
        has successfully transitioned to the committed data source.
        @result The provisional datasource of this frame.
        - (WebDataSource *)provisionalDataSource;
    */
    HRESULT provisionalDataSource([out, retval] IWebDataSource** source);

    /*!
        @method stopLoading
        @discussion Stop any pending loads on the frame's data source,
        and its children.
        - (void)stopLoading;
    */
    HRESULT stopLoading();

    /*!
        @method reload
        - (void)reload;
    */
    HRESULT reload();

    /*!
        @method findFrameNamed:
        @discussion This method returns a frame with the given name. findFrameNamed returns self 
        for _self and _current, the parent frame for _parent and the main frame for _top. 
        findFrameNamed returns self for _parent and _top if the receiver is the mainFrame.
        findFrameNamed first searches from the current frame to all descending frames then the
        rest of the frames in the WebView. If still not found, findFrameNamed searches the
        frames of the other WebViews.
        @param name The name of the frame to find.
        @result The frame matching the provided name. nil if the frame is not found.
        - (WebFrame *)findFrameNamed:(NSString *)name;
    */
    HRESULT findFrameNamed([in] BSTR name, [out, retval] IWebFrame** frame);

    /*!
        @method parentFrame
        @result The frame containing this frame, or nil if this is a top level frame.
        - (WebFrame *)parentFrame;
    */
    HRESULT parentFrame([out, retval] IWebFrame** frame);

    /*!
        @method childFrames
        @discussion The frames in the array are associated with a frame set or iframe.
        @result Returns an array of WebFrame.
        - (NSArray *)childFrames;
    */
    HRESULT childFrames([out, retval] IEnumVARIANT** enumFrames);


  /* This is a DOMElement on mac, but maybe should be a DOMHTMLFrameElement? */
    HRESULT currentForm([out, retval] IDOMElement** frameElement);

    /*!
        @method setAllowsScrolling:
        @abstract Sets whether the WebFrameView allows its document to be scrolled
        @param flag YES to allow the document to be scrolled, NO to disallow scrolling
        - (void)setAllowsScrolling:(BOOL)flag;
    */
   HRESULT setAllowsScrolling([in] BOOL flag);

    /*!
        @method allowsScrolling
        @abstract Returns whether the WebFrameView allows its document to be scrolled
        @result YES if the document is allowed to scroll, otherwise NO
        - (BOOL)allowsScrolling;
    */
   HRESULT allowsScrolling([out, retval] BOOL* flag);

    /*!
        @method globalContext
        @result The frame's global JavaScript execution context.  Use this method to
        bridge between the WebKit and JavaScriptCore APIs.
    */
   [local] JSGlobalContextRef globalContext();

   /*!
        @method setIsDisconnected
        @abstract Set whether a frame is disconnected
        @param flag YES to mark the frame as disconnected, NO keeps it a regular frame
   */
   HRESULT setIsDisconnected([in] BOOL flag);

      /*!
        @method setExcludeFromTextSearch
        @abstract Set whether a frame should be excluded from text search
        @param flag YES to mark the frame as not searchable
   */
   HRESULT setExcludeFromTextSearch([in] BOOL flag);

   /*!
       @method reloadFromOrigin
       @discussion Performs HTTP/1.1 end-to-end reload.
   */
   HRESULT reloadFromOrigin();

    /*!
        @method DOMWindow
        @abstract Returns the DOM window of the frame.
        @description Returns nil if the frame does not contain a DOM window such as a standalone image.
        - (DOMWindow *)DOMWindow;
    */
    HRESULT DOMWindow([out, retval] IDOMWindow** window);
}

[ uuid(5418D783-A3BA-48F3-BAC1-535EE264035A) ]
interface IWebFrame2 : IWebFrame
{
    /*!
    @method isMainFrame
    @description Returns TRUE if the frame is the main frame.
    */
    HRESULT isMainFrame([out, retval] BOOL* flag);
}
