Пример #1
0
void fire_event(HTMLDocumentNode *doc, eventid_t eid, BOOL set_event, nsIDOMNode *target, nsIDOMEvent *nsevent,
        IDispatch *script_this)
{
    HTMLEventObj *event_obj = NULL;
    HTMLDOMNode *node;
    HRESULT hres;

    if(set_event) {
        hres = get_node(doc, target, TRUE, &node);
        if(FAILED(hres))
            return;

        event_obj = create_event();
        node_release(node);
        if(!event_obj)
            return;

        hres = set_event_info(event_obj, node, eid, nsevent);
        if(FAILED(hres)) {
            IHTMLEventObj_Release(&event_obj->IHTMLEventObj_iface);
            return;
        }
    }

    fire_event_obj(doc, eid, event_obj, target, script_this);

    if(event_obj)
        IHTMLEventObj_Release(&event_obj->IHTMLEventObj_iface);
}
Пример #2
0
HRESULT dispatch_event(HTMLDOMNode *node, const WCHAR *event_name, VARIANT *event_var, VARIANT_BOOL *cancelled)
{
    HTMLEventObj *event_obj = NULL;
    eventid_t eid;
    HRESULT hres;

    eid = attr_to_eid(event_name);
    if(eid == EVENTID_LAST) {
        WARN("unknown event %s\n", debugstr_w(event_name));
        return E_INVALIDARG;
    }

    if(event_var && V_VT(event_var) != VT_EMPTY && V_VT(event_var) != VT_ERROR) {
        if(V_VT(event_var) != VT_DISPATCH) {
            FIXME("event_var %s not supported\n", debugstr_variant(event_var));
            return E_NOTIMPL;
        }

        if(V_DISPATCH(event_var)) {
            IHTMLEventObj *event_iface;

            hres = IDispatch_QueryInterface(V_DISPATCH(event_var), &IID_IHTMLEventObj, (void**)&event_iface);
            if(FAILED(hres)) {
                FIXME("No IHTMLEventObj iface\n");
                return hres;
            }

            event_obj = unsafe_impl_from_IHTMLEventObj(event_iface);
            if(!event_obj) {
                ERR("Not our IHTMLEventObj?\n");
                IHTMLEventObj_Release(event_iface);
                return E_FAIL;
            }
        }
    }

    if(event_obj) {
        hres = set_event_info(event_obj, node, eid, NULL);
        if(SUCCEEDED(hres))
            fire_event_obj(node->doc, eid, event_obj, node->nsnode, NULL);

        IHTMLEventObj_Release(&event_obj->IHTMLEventObj_iface);
        if(FAILED(hres))
            return hres;
    }else {
        if(!(event_info[eid].flags & EVENT_DEFAULTLISTENER)) {
            FIXME("not EVENT_DEFAULTEVENTHANDLER\n");
            return E_NOTIMPL;
        }

        fire_event(node->doc, eid, TRUE, node->nsnode, NULL, NULL);
    }

    *cancelled = VARIANT_TRUE; /* FIXME */
    return S_OK;
}
Пример #3
0
static IHTMLEventObj *create_event(HTMLDOMNode *target, eventid_t eid, nsIDOMEvent *nsevent)
{
    HTMLEventObj *ret;

    ret = heap_alloc(sizeof(*ret));
    if(!ret)
        return NULL;

    ret->IHTMLEventObj_iface.lpVtbl = &HTMLEventObjVtbl;
    ret->ref = 1;
    ret->type = event_info+eid;

    ret->nsevent = nsevent;
    if(nsevent) {
        nsIDOMEvent_AddRef(nsevent);
    }else if(event_types[event_info[eid].type]) {
        nsIDOMDocumentEvent *doc_event;
        nsresult nsres;

        nsres = nsIDOMHTMLDocument_QueryInterface(target->doc->nsdoc, &IID_nsIDOMDocumentEvent,
                 (void**)&doc_event);
        if(NS_SUCCEEDED(nsres)) {
            nsAString type_str;

            nsAString_InitDepend(&type_str, event_types[event_info[eid].type]);
            nsres = nsIDOMDocumentEvent_CreateEvent(doc_event, &type_str, &ret->nsevent);
            nsAString_Finish(&type_str);
            nsIDOMDocumentEvent_Release(doc_event);
        }
        if(NS_FAILED(nsres)) {
            ERR("Could not create event: %08x\n", nsres);
            IHTMLEventObj_Release(&ret->IHTMLEventObj_iface);
            return NULL;
        }
    }

    ret->target = target;
    IHTMLDOMNode_AddRef(&target->IHTMLDOMNode_iface);

    init_dispex(&ret->dispex, (IUnknown*)&ret->IHTMLEventObj_iface, &HTMLEventObj_dispex);

    return &ret->IHTMLEventObj_iface;
}
Пример #4
0
void fire_event(HTMLDocumentNode *doc, eventid_t eid, BOOL set_event, nsIDOMNode *target, nsIDOMEvent *nsevent)
{
    IHTMLEventObj *prev_event, *event_obj = NULL;
    nsIDOMNode *parent, *nsnode;
    HTMLDOMNode *node;
    PRUint16 node_type;
    HRESULT hres;

    TRACE("(%p) %s\n", doc, debugstr_w(event_info[eid].name));

    prev_event = doc->basedoc.window->event;
    if(set_event) {
        hres = get_node(doc, target, TRUE, &node);
        if(FAILED(hres))
            return;

        event_obj = create_event(node, eid, nsevent);
    }
    doc->basedoc.window->event = event_obj;

    nsIDOMNode_GetNodeType(target, &node_type);
    nsnode = target;
    nsIDOMNode_AddRef(nsnode);

    switch(node_type) {
    case ELEMENT_NODE:
        do {
            hres = get_node(doc, nsnode, FALSE, &node);
            if(SUCCEEDED(hres) && node)
                call_event_handlers(doc, event_obj, *get_node_event_target(node),
                        node->cp_container, eid, (IDispatch*)&node->IHTMLDOMNode_iface);

            if(!(event_info[eid].flags & EVENT_BUBBLE))
                break;

            nsIDOMNode_GetParentNode(nsnode, &parent);
            nsIDOMNode_Release(nsnode);
            nsnode = parent;
            if(!nsnode)
                break;

            nsIDOMNode_GetNodeType(nsnode, &node_type);
        }while(node_type == ELEMENT_NODE);

        if(!(event_info[eid].flags & EVENT_BUBBLE))
            break;

    case DOCUMENT_NODE:
        if(event_info[eid].flags & EVENT_FORWARDBODY) {
            nsIDOMHTMLElement *nsbody;
            nsresult nsres;

            nsres = nsIDOMHTMLDocument_GetBody(doc->nsdoc, &nsbody);
            if(NS_SUCCEEDED(nsres) && nsbody) {
                hres = get_node(doc, (nsIDOMNode*)nsbody, FALSE, &node);
                if(SUCCEEDED(hres) && node)
                    call_event_handlers(doc, event_obj, *get_node_event_target(node),
                            node->cp_container, eid, (IDispatch*)&node->IHTMLDOMNode_iface);
                nsIDOMHTMLElement_Release(nsbody);
            }else {
                ERR("Could not get body: %08x\n", nsres);
            }
        }

        call_event_handlers(doc, event_obj, doc->node.event_target, &doc->basedoc.cp_container, eid,
                (IDispatch*)&doc->basedoc.IHTMLDocument2_iface);
        break;

    default:
        FIXME("unimplemented node type %d\n", node_type);
    }

    if(nsnode)
        nsIDOMNode_Release(nsnode);

    if(event_obj)
        IHTMLEventObj_Release(event_obj);
    doc->basedoc.window->event = prev_event;
}