/*
 * Copyright (C) 2006, 2007, 2008 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 "IWebFrame.idl";
#endif

interface IDOMElement;
interface IDOMHTMLInputElement;
interface IDOMHTMLTextAreaElement;
interface IWebFrame;

/*!
    @protocol  WebFormSubmissionListener
    @discussion .
*/
[
    object,
    oleautomation,
    uuid(1911D650-035E-4204-8746-ABECF77A4C9B),
    pointer_default(unique)
]
interface IWebFormSubmissionListener : IUnknown
{
    HRESULT continueSubmit();
}

/*!
    @class WebFormDelegate
    @discussion The WebFormDelegate class responds to all WebFormDelegate protocol
    methods by doing nothing. It's provided for the convenience of clients who only want
    to implement some of the above methods and ignore others.
*/
/*!
    @protocol  WebFormDelegate
    @discussion .

    Various methods send by controls that edit text to their delegates, which are all
    analogous to similar methods in AppKit/NSControl.h.
    These methods are forwarded from widgets used in forms to the WebFormDelegate.
*/
[
    object,
    oleautomation,
    uuid(4CBEC1BD-ABC3-4bdb-8E5E-4D3BCF9E8C1E),
    pointer_default(unique)
]
interface IWebFormDelegate : IUnknown
{
    //- (void)textFieldDidBeginEditing:(DOMHTMLInputElement *)element inFrame:(WebFrame *)frame;
    HRESULT textFieldDidBeginEditing([in] IDOMHTMLInputElement* element, [in] IWebFrame* frame);

    //- (void)textFieldDidEndEditing:(DOMHTMLInputElement *)element inFrame:(WebFrame *)frame;
    HRESULT textFieldDidEndEditing([in] IDOMHTMLInputElement* element, [in] IWebFrame* frame);

    //- (void)textDidChangeInTextField:(DOMHTMLInputElement *)element inFrame:(WebFrame *)frame;
    HRESULT textDidChangeInTextField([in] IDOMHTMLInputElement* element, [in] IWebFrame* frame);

    //- (void)textDidChangeInTextArea:(DOMHTMLTextAreaElement *)element inFrame:(WebFrame *)frame;
    HRESULT textDidChangeInTextArea([in] IDOMHTMLTextAreaElement* element, [in] IWebFrame* frame);

    //- (BOOL)textField:(DOMHTMLInputElement *)element doCommandBySelector:(SEL)commandSelector inFrame:(WebFrame *)frame;
    HRESULT doPlatformCommand([in] IDOMHTMLInputElement* element, [in] BSTR command, [in] IWebFrame* frame, [out, retval] BOOL* result);

    //- (BOOL)textField:(DOMHTMLInputElement *)element shouldHandleEvent:(NSEvent *)event inFrame:(WebFrame *)frame;
    [local] HRESULT shouldHandleEvent([in] IDOMHTMLInputElement* element, [in] void* event, [in] IWebFrame* frame, [out, retval] BOOL* result);

    // Sent when a form is just about to be submitted (before the load is started)
    // listener must be sent continue when the delegate is done.
    //- (void)frame:(WebFrame *)frame sourceFrame:(WebFrame *)sourceFrame willSubmitForm:(DOMElement *)form withValues:(NSDictionary *)values submissionListener:(id <WebFormSubmissionListener>)listener;
    HRESULT willSubmitForm([in] IWebFrame* frame, [in] IWebFrame* sourceFrame, [in] IDOMElement* form, [in] IPropertyBag* values, [in] IWebFormSubmissionListener* listener);
}
