HRESULT jsval_copy(jsval_t v, jsval_t *r)
{
    switch(jsval_type(v)) {
    case JSV_UNDEFINED:
    case JSV_NULL:
    case JSV_NUMBER:
    case JSV_BOOL:
        *r = v;
        return S_OK;
    case JSV_OBJECT:
        if(get_object(v))
            IDispatch_AddRef(get_object(v));
        *r = v;
        return S_OK;
    case JSV_STRING: {
        jsstr_addref(get_string(v));
        *r = v;
        return S_OK;
    }
    case JSV_VARIANT:
        return jsval_variant(r, get_variant(v));
    }

    assert(0);
    return E_FAIL;
}
Esempio n. 2
0
static HRESULT WINAPI Test_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
        VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
{
    ok(pspCaller != NULL, "pspCaller == NULL\n");

    switch(id) {
    case DISPID_TEST_TESTARGCONV:
        CHECK_EXPECT(testArgConv);

        ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags);
        ok(pdp != NULL, "pdp == NULL\n");
        ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
        ok(!pvarRes, "pvarRes != NULL\n");
        ok(pei != NULL, "pei == NULL\n");

        ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
        ok(V_VT(pdp->rgvarg) == VT_DISPATCH, "V_VT(rgvarg) = %d\n", V_VT(pdp->rgvarg));

        test_caller(pspCaller, V_DISPATCH(pdp->rgvarg));

        stored_obj = V_DISPATCH(pdp->rgvarg);
        IDispatch_AddRef(stored_obj);
        break;

    default:
        ok(0, "unexpected call\n");
        return E_NOTIMPL;
    }

    return S_OK;
}
Esempio n. 3
0
static HRESULT WINAPI HTMLDOMChildrenCollection_item(IHTMLDOMChildrenCollection *iface, LONG index, IDispatch **ppItem)
{
    HTMLDOMChildrenCollection *This = impl_from_IHTMLDOMChildrenCollection(iface);
    nsIDOMNode *nsnode = NULL;
    HTMLDOMNode *node;
    PRUint32 length=0;
    nsresult nsres;
    HRESULT hres;

    TRACE("(%p)->(%d %p)\n", This, index, ppItem);

    if (ppItem)
        *ppItem = NULL;
    else
        return E_POINTER;

    nsIDOMNodeList_GetLength(This->nslist, &length);
    if(index < 0 || index >= length)
        return E_INVALIDARG;

    nsres = nsIDOMNodeList_Item(This->nslist, index, &nsnode);
    if(NS_FAILED(nsres) || !nsnode) {
        ERR("Item failed: %08x\n", nsres);
        return E_FAIL;
    }

    hres = get_node(This->doc, nsnode, TRUE, &node);
    if(FAILED(hres))
        return hres;

    *ppItem = (IDispatch*)&node->IHTMLDOMNode_iface;
    IDispatch_AddRef(*ppItem);
    return S_OK;
}
Esempio n. 4
0
HRESULT attach_event(EventTarget *event_target, BSTR name, IDispatch *disp, VARIANT_BOOL *res)
{
    event_target_t *data;
    eventid_t eid;
    DWORD i = 0;

    eid = attr_to_eid(name);
    if(eid == EVENTID_LAST) {
        WARN("Unknown event\n");
        *res = VARIANT_TRUE;
        return S_OK;
    }

    data = get_event_target_data(event_target, TRUE);
    if(!data)
        return E_OUTOFMEMORY;

    if(data->event_table[eid]) {
        while(i < data->event_table[eid]->handler_cnt && data->event_table[eid]->handlers[i])
            i++;
        if(i == data->event_table[eid]->handler_cnt && !alloc_handler_vector(data, eid, i+1))
            return E_OUTOFMEMORY;
    }else if(!alloc_handler_vector(data, eid, i+1)) {
        return E_OUTOFMEMORY;
    }

    IDispatch_AddRef(disp);
    data->event_table[eid]->handlers[i] = disp;

    bind_event(event_target, eid);

    *res = VARIANT_TRUE;
    return S_OK;
}
Esempio n. 5
0
HRESULT attach_event(event_target_t **event_target_ptr, HTMLDocument *doc, BSTR name,
        IDispatch *disp, VARIANT_BOOL *res)
{
    event_target_t *event_target;
    eventid_t eid;
    DWORD i = 0;

    eid = attr_to_eid(name);
    if(eid == EVENTID_LAST) {
        WARN("Unknown event\n");
        *res = VARIANT_TRUE;
        return S_OK;
    }

    event_target = get_event_target(event_target_ptr);
    if(!event_target)
        return E_OUTOFMEMORY;

    if(event_target->event_table[eid]) {
        while(i < event_target->event_table[eid]->handler_cnt && event_target->event_table[eid]->handlers[i])
            i++;
        if(i == event_target->event_table[eid]->handler_cnt && !alloc_handler_vector(event_target, eid, i+1))
            return E_OUTOFMEMORY;
    }else if(!alloc_handler_vector(event_target, eid, i+1)) {
        return E_OUTOFMEMORY;
    }

    IDispatch_AddRef(disp);
    event_target->event_table[eid]->handlers[i] = disp;

    *res = VARIANT_TRUE;
    return ensure_nsevent_handler(doc->doc_node, event_target, eid);
}
Esempio n. 6
0
File: dispex.c Progetto: bpon/wine
static HRESULT function_invoke(DispatchEx *This, func_info_t *func, WORD flags, DISPPARAMS *dp, VARIANT *res,
        EXCEPINFO *ei)
{
    HRESULT hres;

    switch(flags) {
    case DISPATCH_METHOD|DISPATCH_PROPERTYGET:
        if(!res)
            return E_INVALIDARG;
        /* fall through */
    case DISPATCH_METHOD:
        hres = typeinfo_invoke(This, func, flags, dp, res, ei);
        break;
    case DISPATCH_PROPERTYGET: {
        dispex_dynamic_data_t *dynamic_data;

        if(func->id == DISPID_VALUE) {
            BSTR ret;

            ret = SysAllocString(objectW);
            if(!ret)
                return E_OUTOFMEMORY;

            V_VT(res) = VT_BSTR;
            V_BSTR(res) = ret;
            return S_OK;
        }

        dynamic_data = get_dynamic_data(This);
        if(!dynamic_data)
            return E_OUTOFMEMORY;

        if(!dynamic_data->func_disps) {
            dynamic_data->func_disps = heap_alloc_zero(This->data->data->func_disp_cnt * sizeof(func_disp_t*));
            if(!dynamic_data->func_disps)
                return E_OUTOFMEMORY;
        }

        if(!dynamic_data->func_disps[func->func_disp_idx]) {
            dynamic_data->func_disps[func->func_disp_idx] = create_func_disp(This, func);
            if(!dynamic_data->func_disps[func->func_disp_idx])
                return E_OUTOFMEMORY;
        }

        V_VT(res) = VT_DISPATCH;
        V_DISPATCH(res) = (IDispatch*)&dynamic_data->func_disps[func->func_disp_idx]->dispex.IDispatchEx_iface;
        IDispatch_AddRef(V_DISPATCH(res));
        hres = S_OK;
        break;
    }
    default:
        FIXME("Unimplemented flags %x\n", flags);
        /* fall through */
    case DISPATCH_PROPERTYPUT:
        hres = E_NOTIMPL;
    }

    return hres;
}
HRESULT variant_to_jsval(VARIANT *var, jsval_t *r)
{
    switch(V_VT(var)) {
    case VT_EMPTY:
        *r = jsval_undefined();
        return S_OK;
    case VT_NULL:
        *r = jsval_null();
        return S_OK;
    case VT_BOOL:
        *r = jsval_bool(V_BOOL(var));
        return S_OK;
    case VT_I4:
        *r = jsval_number(V_I4(var));
        return S_OK;
    case VT_R8:
        *r = jsval_number(V_R8(var));
        return S_OK;
    case VT_BSTR: {
        jsstr_t *str;

        str = jsstr_alloc_len(V_BSTR(var), SysStringLen(V_BSTR(var)));
        if(!str)
            return E_OUTOFMEMORY;
        if(!V_BSTR(var))
            str->length_flags |= JSSTR_FLAG_NULLBSTR;

        *r = jsval_string(str);
        return S_OK;
    }
    case VT_DISPATCH: {
        if(V_DISPATCH(var))
            IDispatch_AddRef(V_DISPATCH(var));
        *r = jsval_disp(V_DISPATCH(var));
        return S_OK;
    }
    case VT_I2:
        *r = jsval_number(V_I2(var));
        return S_OK;
    case VT_INT:
        *r = jsval_number(V_INT(var));
        return S_OK;
    case VT_UNKNOWN:
        if(V_UNKNOWN(var)) {
            IDispatch *disp;
            HRESULT hres;

            hres = IUnknown_QueryInterface(V_UNKNOWN(var), &IID_IDispatch, (void**)&disp);
            if(SUCCEEDED(hres)) {
                *r = jsval_disp(disp);
                return S_OK;
            }
        }
        /* fall through */
    default:
        return jsval_variant(r, var);
    }
}
Esempio n. 8
0
static HRESULT get_item_idx(HTMLElementCollection *This, UINT idx, IDispatch **ret)
{
    if(idx < This->len) {
        *ret = (IDispatch*)This->elems[idx];
        IDispatch_AddRef(*ret);
    }

    return S_OK;
}
Esempio n. 9
0
static HRESULT get_item_idx(HTMLElementCollection *This, UINT idx, IDispatch **ret)
{
    if(idx < This->len) {
        *ret = (IDispatch*)&This->elems[idx]->node.event_target.dispex.IDispatchEx_iface;
        IDispatch_AddRef(*ret);
    }

    return S_OK;
}
Esempio n. 10
0
static HRESULT WINAPI JScript_AddNamedItem(IActiveScript *iface,
                                           LPCOLESTR pstrName, DWORD dwFlags)
{
    JScript *This = impl_from_IActiveScript(iface);
    named_item_t *item;
    IDispatch *disp = NULL;
    HRESULT hres;

    TRACE("(%p)->(%s %x)\n", This, debugstr_w(pstrName), dwFlags);

    if(This->thread_id != GetCurrentThreadId() || !This->ctx || This->ctx->state == SCRIPTSTATE_CLOSED)
        return E_UNEXPECTED;

    if(dwFlags & SCRIPTITEM_GLOBALMEMBERS) {
        IUnknown *unk;

        hres = IActiveScriptSite_GetItemInfo(This->site, pstrName, SCRIPTINFO_IUNKNOWN, &unk, NULL);
        if(FAILED(hres)) {
            WARN("GetItemInfo failed: %08x\n", hres);
            return hres;
        }

        hres = IUnknown_QueryInterface(unk, &IID_IDispatch, (void**)&disp);
        IUnknown_Release(unk);
        if(FAILED(hres)) {
            WARN("object does not implement IDispatch\n");
            return hres;
        }

        if(This->ctx->host_global)
            IDispatch_Release(This->ctx->host_global);
        IDispatch_AddRef(disp);
        This->ctx->host_global = disp;
    }

    item = heap_alloc(sizeof(*item));
    if(!item) {
        if(disp)
            IDispatch_Release(disp);
        return E_OUTOFMEMORY;
    }

    item->disp = disp;
    item->flags = dwFlags;
    item->name = heap_strdupW(pstrName);
    if(!item->name) {
        if(disp)
            IDispatch_Release(disp);
        heap_free(item);
        return E_OUTOFMEMORY;
    }

    item->next = This->ctx->named_items;
    This->ctx->named_items = item;

    return S_OK;
}
Esempio n. 11
0
static HRESULT WINAPI HTMLFormElement_get_elements(IHTMLFormElement *iface, IDispatch **p)
{
    HTMLFormElement *This = impl_from_IHTMLFormElement(iface);

    TRACE("(%p)->(%p)\n", This, p);

    *p = (IDispatch*)&This->IHTMLFormElement_iface;
    IDispatch_AddRef(*p);
    return S_OK;
}
Esempio n. 12
0
HRESULT jsval_to_variant(jsval_t val, VARIANT *retv)
{
    switch(jsval_type(val)) {
    case JSV_UNDEFINED:
        V_VT(retv) = VT_EMPTY;
        return S_OK;
    case JSV_NULL:
        V_VT(retv) = VT_NULL;
        return S_OK;
    case JSV_OBJECT:
        V_VT(retv) = VT_DISPATCH;
        if(get_object(val))
            IDispatch_AddRef(get_object(val));
        V_DISPATCH(retv) = get_object(val);
        return S_OK;
    case JSV_STRING: {
        jsstr_t *str = get_string(val);

        V_VT(retv) = VT_BSTR;
        if(str->length_flags & JSSTR_FLAG_NULLBSTR) {
            V_BSTR(retv) = NULL;
        } else {
            V_BSTR(retv) = SysAllocStringLen(NULL, jsstr_length(str));
            if(V_BSTR(retv))
                jsstr_flush(str, V_BSTR(retv));
            else
                return E_OUTOFMEMORY;
        }
        return S_OK;
    }
    case JSV_NUMBER: {
        double n = get_number(val);

        if(is_int32(n)) {
            V_VT(retv) = VT_I4;
            V_I4(retv) = n;
        } else {
            V_VT(retv) = VT_R8;
            V_R8(retv) = n;
        }

        return S_OK;
    }
    case JSV_BOOL:
        V_VT(retv) = VT_BOOL;
        V_BOOL(retv) = get_bool(val) ? VARIANT_TRUE : VARIANT_FALSE;
        return S_OK;
    case JSV_VARIANT:
        V_VT(retv) = VT_EMPTY;
        return VariantCopy(retv, get_variant(val));
    }

    assert(0);
    return E_FAIL;
}
Esempio n. 13
0
static HRESULT WINAPI httprequest_put_onreadystatechange(IXMLHTTPRequest *iface, IDispatch *sink)
{
    httprequest *This = impl_from_IXMLHTTPRequest( iface );

    TRACE("(%p)->(%p)\n", This, sink);

    if (This->sink) IDispatch_Release(This->sink);
    if ((This->sink = sink)) IDispatch_AddRef(This->sink);

    return S_OK;
}
Esempio n. 14
0
HRESULT get_event_handler(event_target_t **event_target, eventid_t eid, VARIANT *var)
{
    if(*event_target && (*event_target)->event_table[eid] && (*event_target)->event_table[eid]->handler_prop) {
        V_VT(var) = VT_DISPATCH;
        V_DISPATCH(var) = (*event_target)->event_table[eid]->handler_prop;
        IDispatch_AddRef(V_DISPATCH(var));
    }else {
        V_VT(var) = VT_NULL;
    }

    return S_OK;
}
Esempio n. 15
0
static HRESULT HTMLIFrame_get_document(HTMLDOMNode *iface, IDispatch **p)
{
    HTMLIFrame *This = impl_from_HTMLDOMNode(iface);

    if(!This->framebase.content_window || !This->framebase.content_window->doc) {
        *p = NULL;
        return S_OK;
    }

    *p = (IDispatch*)&This->framebase.content_window->doc->basedoc.IHTMLDocument2_iface;
    IDispatch_AddRef(*p);
    return S_OK;
}
Esempio n. 16
0
static HRESULT WINAPI WebBrowser_get_Application(IWebBrowser2 *iface, IDispatch **ppDisp)
{
    WebBrowser *This = WEBBROWSER_THIS(iface);

    TRACE("(%p)->(%p)\n", This, ppDisp);

    if(!ppDisp)
        return E_POINTER;

    *ppDisp = (IDispatch*)WEBBROWSER2(This);
    IDispatch_AddRef(*ppDisp);
    return S_OK;
}
Esempio n. 17
0
static HRESULT WINAPI WebBrowser_get_Application(IWebBrowser2 *iface, IDispatch **ppDisp)
{
    WebBrowser *This = impl_from_IWebBrowser2(iface);

    TRACE("(%p)->(%p)\n", This, ppDisp);

    if(!ppDisp)
        return E_POINTER;

    *ppDisp = (IDispatch*)&This->IWebBrowser2_iface;
    IDispatch_AddRef(*ppDisp);
    return S_OK;
}
Esempio n. 18
0
static HRESULT WINAPI HTMLDOMNode2_get_ownerDocument(IHTMLDOMNode2 *iface, IDispatch **p)
{
    HTMLDOMNode *This = impl_from_IHTMLDOMNode2(iface);

    TRACE("(%p)->(%p)\n", This, p);

    /* FIXME: Better check for document node */
    if(This == &This->doc->node) {
        *p = NULL;
    }else {
        *p = (IDispatch*)&This->doc->basedoc.IHTMLDocument2_iface;
        IDispatch_AddRef(*p);
    }
    return S_OK;
}
Esempio n. 19
0
static HRESULT WINAPI dispevent_QueryInterface(IDispatch *iface, REFIID riid, void **ppvObject)
{
    *ppvObject = NULL;

    if ( IsEqualGUID( riid, &IID_IDispatch) ||
         IsEqualGUID( riid, &IID_IUnknown) )
    {
        *ppvObject = iface;
    }
    else
        return E_NOINTERFACE;

    IDispatch_AddRef( iface );

    return S_OK;
}
Esempio n. 20
0
static HRESULT WINAPI JScript_GetScriptDispatch(IActiveScript *iface, LPCOLESTR pstrItemName,
                                                IDispatch **ppdisp)
{
    JScript *This = impl_from_IActiveScript(iface);

    TRACE("(%p)->(%p)\n", This, ppdisp);

    if(!ppdisp)
        return E_POINTER;

    if(This->thread_id != GetCurrentThreadId() || !This->ctx->global) {
        *ppdisp = NULL;
        return E_UNEXPECTED;
    }

    *ppdisp = to_disp(This->ctx->global);
    IDispatch_AddRef(*ppdisp);
    return S_OK;
}
Esempio n. 21
0
static HRESULT WINAPI HTMLElementCollectionEnum_Next(IEnumVARIANT *iface, ULONG celt, VARIANT *rgVar, ULONG *pCeltFetched)
{
    HTMLElementCollectionEnum *This = impl_from_IEnumVARIANT(iface);
    ULONG fetched = 0;

    TRACE("(%p)->(%d %p %p)\n", This, celt, rgVar, pCeltFetched);

    while(This->iter+fetched < This->col->len && fetched < celt) {
        V_VT(rgVar+fetched) = VT_DISPATCH;
        V_DISPATCH(rgVar+fetched) = (IDispatch*)&This->col->elems[This->iter+fetched]->IHTMLElement_iface;
        IDispatch_AddRef(V_DISPATCH(rgVar+fetched));
        fetched++;
    }

    This->iter += fetched;
    if(pCeltFetched)
        *pCeltFetched = fetched;
    return fetched == celt ? S_OK : S_FALSE;
}
Esempio n. 22
0
static HRESULT set_event_handler_disp(EventTarget *event_target, eventid_t eid, IDispatch *disp)
{
    event_target_t *data;

    remove_event_handler(event_target, eid);
    if(!disp)
        return S_OK;

    data = get_event_target_data(event_target, TRUE);
    if(!data)
        return E_OUTOFMEMORY;

    if(!alloc_handler_vector(data, eid, 0))
        return E_OUTOFMEMORY;

    data->event_table[eid]->handler_prop = disp;
    IDispatch_AddRef(disp);

    bind_event(event_target, eid);
    return S_OK;
}
Esempio n. 23
0
PHP_COM_DOTNET_API void php_com_wrap_dispatch(zval *z, IDispatch *disp,
        int codepage)
{
    php_com_dotnet_object *obj;

    obj = emalloc(sizeof(*obj));
    memset(obj, 0, sizeof(*obj));
    obj->code_page = codepage;
    obj->ce = php_com_variant_class_entry;
    obj->zo.ce = php_com_variant_class_entry;

    VariantInit(&obj->v);
    V_VT(&obj->v) = VT_DISPATCH;
    V_DISPATCH(&obj->v) = disp;

    IDispatch_AddRef(V_DISPATCH(&obj->v));
    IDispatch_GetTypeInfo(V_DISPATCH(&obj->v), 0, LANG_NEUTRAL, &obj->typeinfo);

    zend_object_std_init(&obj->zo, php_com_variant_class_entry);
    obj->zo.handlers = &php_com_object_handlers;
    ZVAL_OBJ(z, &obj->zo);
}
Esempio n. 24
0
/* ECMA-262 3rd Edition    9.9 */
HRESULT to_object(exec_ctx_t *ctx, VARIANT *v, IDispatch **disp)
{
    DispatchEx *dispex;
    HRESULT hres;

    switch(V_VT(v)) {
    case VT_BSTR:
        hres = create_string(ctx->parser->script, V_BSTR(v), SysStringLen(V_BSTR(v)), &dispex);
        if(FAILED(hres))
            return hres;

        *disp = (IDispatch*)_IDispatchEx_(dispex);
        break;
    case VT_I4:
    case VT_R8:
        hres = create_number(ctx->parser->script, v, &dispex);
        if(FAILED(hres))
            return hres;

        *disp = (IDispatch*)_IDispatchEx_(dispex);
        break;
    case VT_DISPATCH:
        IDispatch_AddRef(V_DISPATCH(v));
        *disp = V_DISPATCH(v);
        break;
    case VT_BOOL:
        hres = create_bool(ctx->parser->script, V_BOOL(v), &dispex);
        if(FAILED(hres))
            return hres;

        *disp = (IDispatch*)_IDispatchEx_(dispex);
        break;
    default:
        FIXME("unsupported vt %d\n", V_VT(v));
        return E_NOTIMPL;
    }

    return S_OK;
}
Esempio n. 25
0
HRESULT get_event_handler(EventTarget *event_target, eventid_t eid, VARIANT *var)
{
    event_target_t *data;
    VARIANT *v;
    HRESULT hres;

    hres = dispex_get_dprop_ref(&event_target->dispex, event_info[eid].attr_name, FALSE, &v);
    if(SUCCEEDED(hres) && V_VT(v) != VT_EMPTY) {
        V_VT(var) = VT_EMPTY;
        return VariantCopy(var, v);
    }

    data = get_event_target_data(event_target, FALSE);
    if(data && data->event_table[eid] && data->event_table[eid]->handler_prop) {
        V_VT(var) = VT_DISPATCH;
        V_DISPATCH(var) = data->event_table[eid]->handler_prop;
        IDispatch_AddRef(V_DISPATCH(var));
    }else {
        V_VT(var) = VT_NULL;
    }

    return S_OK;
}
Esempio n. 26
0
static HRESULT set_event_handler_disp(event_target_t **event_target_ptr, HTMLDocumentNode *doc,
        eventid_t eid, IDispatch *disp)
{
    event_target_t *event_target;

    if(!disp)
        return remove_event_handler(event_target_ptr, eid);

    event_target = get_event_target(event_target_ptr);
    if(!event_target)
        return E_OUTOFMEMORY;

    if(!alloc_handler_vector(event_target, eid, 0))
        return E_OUTOFMEMORY;

    if(event_target->event_table[eid]->handler_prop)
        IDispatch_Release(event_target->event_table[eid]->handler_prop);

    event_target->event_table[eid]->handler_prop = disp;
    IDispatch_AddRef(disp);

    return ensure_nsevent_handler(doc, event_target, eid);
}
Esempio n. 27
0
HRESULT get_plugin_disp(HTMLPluginContainer *plugin_container, IDispatch **ret)
{
    PluginHost *host;

    host = plugin_container->plugin_host;
    if(!host) {
        ERR("No plugin host\n");
        return E_UNEXPECTED;
    }

    if(!host->disp) {
        *ret = NULL;
        return S_OK;
    }

    if(!check_script_safety(host)) {
        FIXME("Insecure object\n");
        return E_FAIL;
    }

    IDispatch_AddRef(host->disp);
    *ret = host->disp;
    return S_OK;
}
Esempio n. 28
0
static HRESULT WINAPI HTMLElementCollection_item(IHTMLElementCollection *iface,
        VARIANT name, VARIANT index, IDispatch **pdisp)
{
    HTMLElementCollection *This = impl_from_IHTMLElementCollection(iface);
    HRESULT hres = S_OK;

    TRACE("(%p)->(%s %s %p)\n", This, debugstr_variant(&name), debugstr_variant(&index), pdisp);

    *pdisp = NULL;

    switch(V_VT(&name)) {
    case VT_I4:
    case VT_INT:
        if(V_I4(&name) < 0)
            return E_INVALIDARG;
        hres = get_item_idx(This, V_I4(&name), pdisp);
        break;

    case VT_UI4:
    case VT_UINT:
        hres = get_item_idx(This, V_UINT(&name), pdisp);
        break;

    case VT_BSTR: {
        DWORD i;

        if(V_VT(&index) == VT_I4) {
            LONG idx = V_I4(&index);

            if(idx < 0)
                return E_INVALIDARG;

            for(i=0; i<This->len; i++) {
                if(is_elem_name(This->elems[i], V_BSTR(&name)) && !idx--)
                    break;
            }

            if(i != This->len) {
                *pdisp = (IDispatch*)&This->elems[i]->IHTMLElement_iface;
                IDispatch_AddRef(*pdisp);
            }
        }else {
            elem_vector_t buf = {NULL, 0, 8};

            buf.buf = heap_alloc(buf.size*sizeof(HTMLElement*));

            for(i=0; i<This->len; i++) {
                if(is_elem_name(This->elems[i], V_BSTR(&name))) {
                    node_addref(&This->elems[i]->node);
                    elem_vector_add(&buf, This->elems[i]);
                }
            }

            if(buf.len > 1) {
                elem_vector_normalize(&buf);
                *pdisp = (IDispatch*)HTMLElementCollection_Create(buf.buf, buf.len);
            }else {
                if(buf.len == 1) {
                    /* Already AddRef-ed */
                    *pdisp = (IDispatch*)&buf.buf[0]->IHTMLElement_iface;
                }

                heap_free(buf.buf);
            }
        }
        break;
    }

    default:
        FIXME("Unsupported name %s\n", debugstr_variant(&name));
        hres = E_NOTIMPL;
    }

    if(SUCCEEDED(hres))
        TRACE("returning %p\n", *pdisp);
    return hres;
}
Esempio n. 29
0
static
HRESULT get_ie_elem_at(IDispatch *doc, int x, int y, IDispatch **ret_elem)
{
    IDispatch *inner_doc;
    VARIANTARG args[2];
    VARIANT var;
    HRESULT hres;

    inner_doc = doc;
    IDispatch_AddRef(inner_doc);

    {
        IDispatch *win;

        hres = get_property_dp(inner_doc, L"parentWindow", &win);
        if(FAILED(hres)) {
            IDispatch_Release(inner_doc);

            spr->log_hresult(
                LOG_LEVEL_NOTIFY,
                L"ie-scroll: Failed to get document.parentWindow",
                hres, 1);
            return hres;
        }

        {
            long sx = 0, sy = 0;

            get_property_long(win, L"screenLeft", &sx);
            get_property_long(win, L"screenTop", &sy);
            IDispatch_Release(win);

            x -= sx;
            y -= sy;
        }
    }

    while(1) {
        IDispatch *elem;

        args[0].vt = VT_I4;
        args[0].lVal = y;
        args[1].vt = VT_I4;
        args[1].lVal = x;

        hres = call_method_s(inner_doc, L"elementFromPoint", args, 2, &var);
        IDispatch_Release(inner_doc);
        if(FAILED(hres)) {
            spr->log_hresult(
                LOG_LEVEL_NOTIFY,
                L"ie-scroll: Failed to get document.elementFromPoint",
                hres, 1);
            return hres;
        }

        if(var.vt != VT_DISPATCH) {
            spr->log_printf(
                LOG_LEVEL_NOTIFY,
                L"ie-scroll: Failed to get document.elementFromPoint: "
                L"return value is not IDispatch\n");
            return E_FAIL;
        }

        elem = var.pdispVal;
        if(elem == NULL) {
            spr->log_printf(
                LOG_LEVEL_NOTIFY,
                L"ie-scroll: Failed to get document.elementFromPoint: "
                L"return value is NULL\n");
            return E_FAIL;
        }

        {
            BSTR str;

            hres = get_property_str(elem, L"tagName", &str);
            if(FAILED(hres)) {
                IDispatch_Release(elem);

                spr->log_hresult(
                    LOG_LEVEL_NOTIFY,
                    L"ie-scroll: Failed to get element.tagName",
                    hres, 1);
                return hres;
            }
            spr->log_printf(LOG_LEVEL_DEBUG,
                            L"ie-scroll: tagName of target element: %ls\n",
                            str);

            if(str == NULL || wcsstr(str, L"FRAME") == NULL) {
                SysFreeString(str);

                *ret_elem = elem;
                break;
            }

            SysFreeString(str);
        }

        {
            static LPOLESTR props[] =
            {L"contentWindow", L"document", NULL};
            hres = get_property_dpv(elem, props, &inner_doc);
        }
        if(FAILED(hres)) {
            *ret_elem = elem;

            spr->log_hresult(
                LOG_LEVEL_NOTIFY,
                L"ie-scroll: Failed to get "
                L"frameElement.contentWindow.document",
                hres, 1);
            break;
        }

        while(1) {
            IDispatch *parent = NULL;
            long ox = 0, oy = 0, cx = 0, cy = 0, sx = 0, sy = 0;
            BSTR tp = NULL;

            get_property_long(elem, L"clientLeft", &cx);
            get_property_long(elem, L"clientTop", &cy);
            get_property_long(elem, L"offsetLeft", &ox);
            get_property_long(elem, L"offsetTop", &oy);
            get_property_long(elem, L"scrollLeft", &sx);
            get_property_long(elem, L"scrollTop", &sy);

            x -= cx + ox - sx;
            y -= cy + oy - sy;

            hres = get_property_dp(elem, L"offsetParent", &parent);
            if(FAILED(hres) || parent == NULL) {
                break;
            }

            get_property_str(parent, L"tagName", &tp);
            if(tp != NULL && wcscmp(tp, L"FRAMESET") == 0) {
                SysFreeString(tp);
                IDispatch_Release(parent);
                break;
            }
            SysFreeString(tp);

            IDispatch_Release(elem);
            elem = parent;
        }

        while(1) {
            IDispatch *parent = NULL;
            long sx = 0, sy = 0;

            hres = get_property_dp(elem, L"parentElement", &parent);
            if(FAILED(hres) || parent == NULL) {
                break;
            }

            get_property_long(parent, L"scrollLeft", &sx);
            get_property_long(parent, L"scrollTop", &sy);

            x += sx;
            y += sy;

            IDispatch_Release(elem);
            elem = parent;
        }

        IDispatch_Release(elem);
    }

    return S_OK;
}
Esempio n. 30
0
static
HRESULT get_scrollable_parent(IDispatch *elem, IDispatch **ret_elem)
{
    HRESULT hres;

    IDispatch_AddRef(elem);

    while(1) {
        BSTR overflow = NULL, curoverflow = NULL, tagname = NULL;
        BSTR compatmode = NULL;
        static LPOLESTR props[] = {L"style", L"overflow", NULL};
        static LPOLESTR curprops[] = {L"currentStyle", L"overflow", NULL};
        static LPOLESTR compatmode_props[] = {
            L"ownerDocument", L"compatMode", NULL
        };

        if(SUCCEEDED(get_property_strv(elem, props, &overflow)) &&
                SUCCEEDED(get_property_strv(elem, curprops, &curoverflow)) &&
                SUCCEEDED(get_property_str(elem, L"tagName", &tagname))) {
            if(overflow == NULL) {
                overflow = curoverflow;
                curoverflow = NULL;
            }

            if((tagname != NULL &&
                    (wcscmp(tagname, L"HTML") == 0 ||
                     wcscmp(tagname, L"BODY") == 0 ||
                     wcscmp(tagname, L"TEXTAREA") == 0) &&
                    (overflow == NULL ||
                     wcscmp(overflow, L"visible") == 0)) ||
                    (overflow != NULL &&
                     (wcscmp(overflow, L"auto") == 0 ||
                      wcscmp(overflow, L"scroll") == 0))) {
                long cw, ch, sw, sh;

                if(tagname != NULL &&
                        wcscmp(tagname, L"BODY") == 0 &&
                        SUCCEEDED(get_property_strv(elem, compatmode_props,
                                                    &compatmode)) &&
                        compatmode != NULL &&
                        wcscmp(compatmode, L"CSS1Compat") == 0) {
                    /* workaround for IE7:
                       ignore BODY element if DOCTYPE is exists */
                }
                else if(
                    SUCCEEDED(get_property_long(elem, L"clientWidth", &cw)) &&
                    SUCCEEDED(get_property_long(elem, L"clientHeight", &ch)) &&
                    SUCCEEDED(get_property_long(elem, L"scrollWidth", &sw)) &&
                    SUCCEEDED(get_property_long(elem, L"scrollHeight", &sh))) {
                    if(cw != 0 && ch != 0 && (cw < sw || ch < sh)) {
                        spr->log_printf(
                            LOG_LEVEL_DEBUG,
                            L"ie-scroll: tagName of scroll target element: "
                            L"%ls\n",
                            tagname);

                        SysFreeString(overflow);
                        SysFreeString(curoverflow);
                        SysFreeString(tagname);
                        SysFreeString(compatmode);
                        break;
                    }
                }
            }
        }
        SysFreeString(overflow);
        SysFreeString(curoverflow);
        SysFreeString(tagname);
        SysFreeString(compatmode);

        {
            IDispatch *parent;

            hres = get_property_dp(elem, L"parentElement", &parent);
            IDispatch_Release(elem);
            if(FAILED(hres)) {
                spr->log_hresult(
                    LOG_LEVEL_NOTIFY,
                    L"ie-scroll: Failed to get element.parentElement",
                    hres, 1);
                return hres;
            }

            if(parent == NULL) {
                spr->log_printf(
                    LOG_LEVEL_DEBUG,
                    L"ie-scroll: scroll target element is not found\n");
                return E_FAIL;
            }

            elem = parent;
        }
    }

    *ret_elem = elem;

    return S_OK;
}