From: Jacek Caban jacek@codeweavers.com
--- dlls/mshtml/mshtml_private.h | 3 ++- dlls/mshtml/omnavigator.c | 18 ++++++++++-------- dlls/mshtml/tests/documentmode.js | 15 +++++++++++++++ dlls/mshtml/tests/es5.js | 2 ++ 4 files changed, 29 insertions(+), 9 deletions(-)
diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index ca8629b64ef..daf7f825aa1 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -407,7 +407,8 @@ typedef struct { } dispex_static_data_vtbl_t;
#define ALL_PROTOTYPES \ - X(DOMImplementation) + X(DOMImplementation) \ + X(Navigator)
typedef enum { PROT_NONE, diff --git a/dlls/mshtml/omnavigator.c b/dlls/mshtml/omnavigator.c index 93a48309e2e..873c55dcd40 100644 --- a/dlls/mshtml/omnavigator.c +++ b/dlls/mshtml/omnavigator.c @@ -28,6 +28,7 @@ #include "wine/debug.h"
#include "mshtml_private.h" +#include "mshtmdid.h"
WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
@@ -1141,21 +1142,22 @@ static void OmNavigator_destructor(DispatchEx *dispex) free(This); }
-static const dispex_static_data_vtbl_t OmNavigator_dispex_vtbl = { +static const dispex_static_data_vtbl_t Navigator_dispex_vtbl = { .query_interface = OmNavigator_query_interface, .destructor = OmNavigator_destructor, .unlink = OmNavigator_unlink };
-static const tid_t OmNavigator_iface_tids[] = { +static const tid_t Navigator_iface_tids[] = { IOmNavigator_tid, 0 }; -static dispex_static_data_t OmNavigator_dispex = { - "Navigator", - &OmNavigator_dispex_vtbl, - DispHTMLNavigator_tid, - OmNavigator_iface_tids +dispex_static_data_t Navigator_dispex = { + .name = "Navigator", + .id = PROT_Navigator, + .vtbl = &Navigator_dispex_vtbl, + .disp_tid = DispHTMLNavigator_tid, + .iface_tids = Navigator_iface_tids, };
HRESULT create_navigator(HTMLInnerWindow *script_global, IOmNavigator **navigator) @@ -1168,7 +1170,7 @@ HRESULT create_navigator(HTMLInnerWindow *script_global, IOmNavigator **navigato
ret->IOmNavigator_iface.lpVtbl = &OmNavigatorVtbl;
- init_dispatch(&ret->dispex, &OmNavigator_dispex, script_global, + init_dispatch(&ret->dispex, &Navigator_dispex, script_global, dispex_compat_mode(&script_global->event_target.dispex));
*navigator = &ret->IOmNavigator_iface; diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index c2f0a7ecb82..5d9cf4a19ed 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -3108,3 +3108,18 @@ sync_test("form", function() { form.innerHTML = ""; ok(form[0] === "test", "form[0] = " + form[0]); }); + +sync_test("prototypes", function() { + var v = document.documentMode; + if(v < 9) + return; + + function check(obj, proto, name) { + ok(Object.getPrototypeOf(obj) === proto, "unexpected " + name + " prototype object"); + } + + check(document.implementation, DOMImplementation.prototype, "implementation"); + check(DOMImplementation.prototype, Object.prototype, "implementation prototype"); + check(window.navigator, Navigator.prototype, "navigator"); + check(Navigator.prototype, Object.prototype, "navigator prototype"); +}); diff --git a/dlls/mshtml/tests/es5.js b/dlls/mshtml/tests/es5.js index 78b50a40ec6..f2d81be9c7d 100644 --- a/dlls/mshtml/tests/es5.js +++ b/dlls/mshtml/tests/es5.js @@ -2754,4 +2754,6 @@ sync_test("prototypes", function() { DOMImplementation = constr;
ok(document.implementation instanceof DOMImplementation, "document.implementation is not an instance of DOMImplementation"); + ok(navigator instanceof Navigator, "navigator is not an instance of Navigator"); + ok(!(navigator instanceof DOMImplementation), "navigator is an instance of DOMImplementation"); });
From: Jacek Caban jacek@codeweavers.com
--- dlls/mshtml/htmlbody.c | 13 +++++++------ dlls/mshtml/mshtml_private.h | 1 + dlls/mshtml/tests/documentmode.js | 1 + dlls/mshtml/tests/es5.js | 1 + 4 files changed, 10 insertions(+), 6 deletions(-)
diff --git a/dlls/mshtml/htmlbody.c b/dlls/mshtml/htmlbody.c index 135712afcd2..576c0d1fd0f 100644 --- a/dlls/mshtml/htmlbody.c +++ b/dlls/mshtml/htmlbody.c @@ -893,12 +893,13 @@ static const tid_t HTMLBodyElement_iface_tids[] = { 0 };
-static dispex_static_data_t HTMLBodyElement_dispex = { - "HTMLBodyElement", - &HTMLBodyElement_event_target_vtbl.dispex_vtbl, - DispHTMLBody_tid, - HTMLBodyElement_iface_tids, - HTMLElement_init_dispex_info +dispex_static_data_t HTMLBodyElement_dispex = { + .name = "HTMLBodyElement", + .id = PROT_HTMLBodyElement, + .vtbl = &HTMLBodyElement_event_target_vtbl.dispex_vtbl, + .disp_tid = DispHTMLBody_tid, + .iface_tids = HTMLBodyElement_iface_tids, + .init_info = HTMLElement_init_dispex_info, };
HRESULT HTMLBodyElement_Create(HTMLDocumentNode *doc, nsIDOMElement *nselem, HTMLElement **elem) diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index daf7f825aa1..c2f8d508e5c 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -408,6 +408,7 @@ typedef struct {
#define ALL_PROTOTYPES \ X(DOMImplementation) \ + X(HTMLBodyElement) \ X(Navigator)
typedef enum { diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index 5d9cf4a19ed..e8905374dcd 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -3122,4 +3122,5 @@ sync_test("prototypes", function() { check(DOMImplementation.prototype, Object.prototype, "implementation prototype"); check(window.navigator, Navigator.prototype, "navigator"); check(Navigator.prototype, Object.prototype, "navigator prototype"); + check(document.body, HTMLBodyElement.prototype, "body element"); }); diff --git a/dlls/mshtml/tests/es5.js b/dlls/mshtml/tests/es5.js index f2d81be9c7d..98d5ec37cb4 100644 --- a/dlls/mshtml/tests/es5.js +++ b/dlls/mshtml/tests/es5.js @@ -2756,4 +2756,5 @@ sync_test("prototypes", function() { ok(document.implementation instanceof DOMImplementation, "document.implementation is not an instance of DOMImplementation"); ok(navigator instanceof Navigator, "navigator is not an instance of Navigator"); ok(!(navigator instanceof DOMImplementation), "navigator is an instance of DOMImplementation"); + ok(document.body instanceof HTMLBodyElement, "body is not an instance of HTMLBodyElement"); });
From: Jacek Caban jacek@codeweavers.com
And use it for HTMLBodyElement prototype. --- dlls/mshtml/dispex.c | 32 +++++++++++++++++++++++++------ dlls/mshtml/htmlbody.c | 1 + dlls/mshtml/htmlelem.c | 13 +++++++------ dlls/mshtml/mshtml_private.h | 2 ++ dlls/mshtml/tests/documentmode.js | 1 + dlls/mshtml/tests/es5.js | 4 ++++ 6 files changed, 41 insertions(+), 12 deletions(-)
diff --git a/dlls/mshtml/dispex.c b/dlls/mshtml/dispex.c index 1848fef01f2..ff3ed946284 100644 --- a/dlls/mshtml/dispex.c +++ b/dlls/mshtml/dispex.c @@ -501,10 +501,24 @@ static BOOL find_prototype_member(const dispex_data_t *info, DISPID id)
if(compat_mode < COMPAT_MODE_IE9) return FALSE; - if(!(info = info->desc->prototype_info[compat_mode - COMPAT_MODE_IE9])) - return FALSE; - if(bsearch(&id, info->funcs, info->func_cnt, sizeof(info->funcs[0]), dispid_cmp)) - return TRUE; + + if(!info->is_prototype) { + if(!info->desc->id) + return FALSE; + info = info->desc->prototype_info[compat_mode - COMPAT_MODE_IE9]; + }else { + if(!info->desc->prototype_id) + return FALSE; + info = object_descriptors[info->desc->prototype_id]->prototype_info[compat_mode - COMPAT_MODE_IE9]; + } + + for(;;) { + if(bsearch(&id, info->funcs, info->func_cnt, sizeof(info->funcs[0]), dispid_cmp)) + return TRUE; + if(!info->desc->prototype_id) + break; + info = object_descriptors[info->desc->prototype_id]->prototype_info[compat_mode - COMPAT_MODE_IE9]; + } return FALSE; }
@@ -2805,8 +2819,8 @@ static const dispex_static_data_vtbl_t prototype_dispex_vtbl = { static HRESULT get_prototype(HTMLInnerWindow *script_global, prototype_id_t id, DispatchEx **ret) { compat_mode_t compat_mode = dispex_compat_mode(&script_global->event_target.dispex); + DispatchEx *prototype, *prot_prototype = NULL; dispex_static_data_t *desc; - DispatchEx *prototype; dispex_data_t *info;
if(script_global->prototypes[id]) { @@ -2815,6 +2829,12 @@ static HRESULT get_prototype(HTMLInnerWindow *script_global, prototype_id_t id, }
desc = object_descriptors[id]; + if(desc->prototype_id) { + HRESULT hres = get_prototype(script_global, desc->prototype_id, &prot_prototype); + if(FAILED(hres)) + ERR("Failed to get a prototype: %08lx\n", hres); + } + info = desc->prototype_info[compat_mode - COMPAT_MODE_IE9]; if(!info) { EnterCriticalSection(&cs_dispex_static_data); @@ -2836,7 +2856,7 @@ static HRESULT get_prototype(HTMLInnerWindow *script_global, prototype_id_t id,
if(!(prototype = calloc(sizeof(*prototype), 1))) return E_OUTOFMEMORY; - init_dispatch_from_desc(prototype, info, script_global, NULL); + init_dispatch_from_desc(prototype, info, script_global, prot_prototype); *ret = script_global->prototypes[id] = prototype; return S_OK; } diff --git a/dlls/mshtml/htmlbody.c b/dlls/mshtml/htmlbody.c index 576c0d1fd0f..5e91ddd4fd5 100644 --- a/dlls/mshtml/htmlbody.c +++ b/dlls/mshtml/htmlbody.c @@ -896,6 +896,7 @@ static const tid_t HTMLBodyElement_iface_tids[] = { dispex_static_data_t HTMLBodyElement_dispex = { .name = "HTMLBodyElement", .id = PROT_HTMLBodyElement, + .prototype_id = PROT_HTMLElement, .vtbl = &HTMLBodyElement_event_target_vtbl.dispex_vtbl, .disp_tid = DispHTMLBody_tid, .iface_tids = HTMLBodyElement_iface_tids, diff --git a/dlls/mshtml/htmlelem.c b/dlls/mshtml/htmlelem.c index f6be9c8d35e..9a86c7f2f65 100644 --- a/dlls/mshtml/htmlelem.c +++ b/dlls/mshtml/htmlelem.c @@ -7235,12 +7235,13 @@ static const IWineHTMLElementPrivateVtbl WineHTMLElementPrivateVtbl = { htmlelement_private_get_classList, };
-static dispex_static_data_t HTMLElement_dispex = { - "HTMLElement", - &HTMLElement_event_target_vtbl.dispex_vtbl, - DispHTMLUnknownElement_tid, - HTMLElement_iface_tids, - HTMLElement_init_dispex_info +dispex_static_data_t HTMLElement_dispex = { + .name = "HTMLElement", + .id = PROT_HTMLElement, + .vtbl = &HTMLElement_event_target_vtbl.dispex_vtbl, + .disp_tid = DispHTMLUnknownElement_tid, + .iface_tids = HTMLElement_iface_tids, + .init_info = HTMLElement_init_dispex_info, };
static dispex_static_data_t HTMLUnknownElement_dispex = { diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index c2f8d508e5c..78387532fb5 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -409,6 +409,7 @@ typedef struct { #define ALL_PROTOTYPES \ X(DOMImplementation) \ X(HTMLBodyElement) \ + X(HTMLElement) \ X(Navigator)
typedef enum { @@ -429,6 +430,7 @@ typedef struct { dispex_data_t *prototype_info[COMPAT_MODE_CNT - COMPAT_MODE_IE9]; dispex_data_t *delayed_init_info; prototype_id_t id; + prototype_id_t prototype_id; UINT32 js_flags; char prototype_name[64]; } dispex_static_data_t; diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index e8905374dcd..96e3aa878fa 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -3123,4 +3123,5 @@ sync_test("prototypes", function() { check(window.navigator, Navigator.prototype, "navigator"); check(Navigator.prototype, Object.prototype, "navigator prototype"); check(document.body, HTMLBodyElement.prototype, "body element"); + check(HTMLBodyElement.prototype, HTMLElement.prototype, "body prototype"); }); diff --git a/dlls/mshtml/tests/es5.js b/dlls/mshtml/tests/es5.js index 98d5ec37cb4..ec05974432c 100644 --- a/dlls/mshtml/tests/es5.js +++ b/dlls/mshtml/tests/es5.js @@ -2753,8 +2753,12 @@ sync_test("prototypes", function() { ok(DOMImplementation === 1, "DOMImplementation = " + DOMImplementation + " expected 1"); DOMImplementation = constr;
+ ok(!HTMLBodyElement.prototype.hasOwnProperty("click"), "HTMLBodyElement prototype has own click property"); + ok(HTMLElement.prototype.hasOwnProperty("click"), "HTMLElement prototype does not have own click property"); + ok(document.implementation instanceof DOMImplementation, "document.implementation is not an instance of DOMImplementation"); ok(navigator instanceof Navigator, "navigator is not an instance of Navigator"); ok(!(navigator instanceof DOMImplementation), "navigator is an instance of DOMImplementation"); ok(document.body instanceof HTMLBodyElement, "body is not an instance of HTMLBodyElement"); + ok(document.body instanceof HTMLElement, "body is not an instance of HTMLElement"); });
From: Jacek Caban jacek@codeweavers.com
--- dlls/mshtml/htmlelem.c | 7 +++++++ dlls/mshtml/htmlnode.c | 17 +++++++++-------- dlls/mshtml/mshtml_private.h | 4 +++- dlls/mshtml/tests/documentmode.js | 3 +++ dlls/mshtml/tests/es5.js | 7 +++++++ 5 files changed, 29 insertions(+), 9 deletions(-)
diff --git a/dlls/mshtml/htmlelem.c b/dlls/mshtml/htmlelem.c index 9a86c7f2f65..7001ff3b7da 100644 --- a/dlls/mshtml/htmlelem.c +++ b/dlls/mshtml/htmlelem.c @@ -7235,9 +7235,16 @@ static const IWineHTMLElementPrivateVtbl WineHTMLElementPrivateVtbl = { htmlelement_private_get_classList, };
+dispex_static_data_t Element_dispex = { + .name = "Element", + .id = PROT_Element, + .prototype_id = PROT_Node, +}; + dispex_static_data_t HTMLElement_dispex = { .name = "HTMLElement", .id = PROT_HTMLElement, + .prototype_id = PROT_Element, .vtbl = &HTMLElement_event_target_vtbl.dispex_vtbl, .disp_tid = DispHTMLUnknownElement_tid, .iface_tids = HTMLElement_iface_tids, diff --git a/dlls/mshtml/htmlnode.c b/dlls/mshtml/htmlnode.c index 8f9de03fd93..263c04c4485 100644 --- a/dlls/mshtml/htmlnode.c +++ b/dlls/mshtml/htmlnode.c @@ -1286,7 +1286,7 @@ void HTMLDOMNode_Init(HTMLDocumentNode *doc, HTMLDOMNode *node, nsIDOMNode *nsno assert(nsres == NS_OK); }
-static const dispex_static_data_vtbl_t HTMLDOMNode_dispex_vtbl = { +static const dispex_static_data_vtbl_t Node_dispex_vtbl = { .query_interface = HTMLDOMNode_query_interface, .destructor = HTMLDOMNode_destructor, .traverse = HTMLDOMNode_traverse, @@ -1297,12 +1297,13 @@ static const tid_t HTMLDOMNode_iface_tids[] = { IHTMLDOMNode_tid, 0 }; -static dispex_static_data_t HTMLDOMNode_dispex = { - "Node", - &HTMLDOMNode_dispex_vtbl, - IHTMLDOMNode_tid, - HTMLDOMNode_iface_tids, - HTMLDOMNode_init_dispex_info +dispex_static_data_t Node_dispex = { + .name = "Node", + .id = PROT_Node, + .vtbl = &Node_dispex_vtbl, + .disp_tid = IHTMLDOMNode_tid, + .iface_tids = HTMLDOMNode_iface_tids, + .init_info = HTMLDOMNode_init_dispex_info, };
static HRESULT create_node(HTMLDocumentNode *doc, nsIDOMNode *nsnode, HTMLDOMNode **ret) @@ -1356,7 +1357,7 @@ static HRESULT create_node(HTMLDocumentNode *doc, nsIDOMNode *nsnode, HTMLDOMNod return E_OUTOFMEMORY;
node->vtbl = &HTMLDOMNodeImplVtbl; - HTMLDOMNode_Init(doc, node, nsnode, &HTMLDOMNode_dispex); + HTMLDOMNode_Init(doc, node, nsnode, &Node_dispex); *ret = node; } } diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 78387532fb5..7662558fffd 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -408,9 +408,11 @@ typedef struct {
#define ALL_PROTOTYPES \ X(DOMImplementation) \ + X(Element) \ X(HTMLBodyElement) \ X(HTMLElement) \ - X(Navigator) + X(Navigator) \ + X(Node)
typedef enum { PROT_NONE, diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index 96e3aa878fa..15a2fbc83a0 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -3124,4 +3124,7 @@ sync_test("prototypes", function() { check(Navigator.prototype, Object.prototype, "navigator prototype"); check(document.body, HTMLBodyElement.prototype, "body element"); check(HTMLBodyElement.prototype, HTMLElement.prototype, "body prototype"); + check(HTMLElement.prototype, Element.prototype, "html element prototype"); + check(Element.prototype, Node.prototype, "element prototype"); + check(Node.prototype, Object.prototype, "node prototype"); }); diff --git a/dlls/mshtml/tests/es5.js b/dlls/mshtml/tests/es5.js index ec05974432c..b5fdbdf708a 100644 --- a/dlls/mshtml/tests/es5.js +++ b/dlls/mshtml/tests/es5.js @@ -2756,9 +2756,16 @@ sync_test("prototypes", function() { ok(!HTMLBodyElement.prototype.hasOwnProperty("click"), "HTMLBodyElement prototype has own click property"); ok(HTMLElement.prototype.hasOwnProperty("click"), "HTMLElement prototype does not have own click property");
+ ok(!HTMLBodyElement.prototype.hasOwnProperty("removeChild"), "HTMLBodyElement prototype has own removeChild property"); + ok(!HTMLElement.prototype.hasOwnProperty("removeChild"), "HTMLElement prototype has own removeChild property"); + ok(!Element.prototype.hasOwnProperty("removeChild"), "Element prototype has own removeChild property"); + ok(Node.prototype.hasOwnProperty("removeChild"), "Node prototype does not have own removeChild property"); + ok(document.implementation instanceof DOMImplementation, "document.implementation is not an instance of DOMImplementation"); ok(navigator instanceof Navigator, "navigator is not an instance of Navigator"); ok(!(navigator instanceof DOMImplementation), "navigator is an instance of DOMImplementation"); ok(document.body instanceof HTMLBodyElement, "body is not an instance of HTMLBodyElement"); ok(document.body instanceof HTMLElement, "body is not an instance of HTMLElement"); + ok(document.body instanceof Element, "body is not an instance of Element"); + ok(document.body instanceof Node, "body is not an instance of Node"); });
From: Jacek Caban jacek@codeweavers.com
--- dlls/mshtml/htmlstorage.c | 15 ++++++++------- dlls/mshtml/mshtml_private.h | 3 ++- dlls/mshtml/tests/documentmode.js | 2 ++ 3 files changed, 12 insertions(+), 8 deletions(-)
diff --git a/dlls/mshtml/htmlstorage.c b/dlls/mshtml/htmlstorage.c index 05ef086a814..f6131d14691 100644 --- a/dlls/mshtml/htmlstorage.c +++ b/dlls/mshtml/htmlstorage.c @@ -1278,7 +1278,7 @@ static HRESULT HTMLStorage_get_prop_desc(DispatchEx *dispex, DISPID id, struct p return S_OK; }
-static const dispex_static_data_vtbl_t HTMLStorage_dispex_vtbl = { +static const dispex_static_data_vtbl_t Storage_dispex_vtbl = { .query_interface = HTMLStorage_query_interface, .destructor = HTMLStorage_destructor, .traverse = HTMLStorage_traverse, @@ -1294,11 +1294,12 @@ static const tid_t HTMLStorage_iface_tids[] = { IHTMLStorage_tid, 0 }; -static dispex_static_data_t HTMLStorage_dispex = { - "Storage", - &HTMLStorage_dispex_vtbl, - IHTMLStorage_tid, - HTMLStorage_iface_tids +dispex_static_data_t Storage_dispex = { + .name = "Storage", + .id = PROT_Storage, + .vtbl = &Storage_dispex_vtbl, + .disp_tid = IHTMLStorage_tid, + .iface_tids = HTMLStorage_iface_tids, };
static HRESULT build_session_origin(IUri *uri, BSTR hostname, BSTR *ret) @@ -1451,7 +1452,7 @@ HRESULT create_html_storage(HTMLInnerWindow *window, BOOL local, IHTMLStorage ** storage->window = window; IHTMLWindow2_AddRef(&window->base.IHTMLWindow2_iface);
- init_dispatch(&storage->dispex, &HTMLStorage_dispex, window, + init_dispatch(&storage->dispex, &Storage_dispex, window, dispex_compat_mode(&window->event_target.dispex));
*p = &storage->IHTMLStorage_iface; diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 7662558fffd..958a7eef8a6 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -412,7 +412,8 @@ typedef struct { X(HTMLBodyElement) \ X(HTMLElement) \ X(Navigator) \ - X(Node) + X(Node) \ + X(Storage)
typedef enum { PROT_NONE, diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index 15a2fbc83a0..bbee5155946 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -3127,4 +3127,6 @@ sync_test("prototypes", function() { check(HTMLElement.prototype, Element.prototype, "html element prototype"); check(Element.prototype, Node.prototype, "element prototype"); check(Node.prototype, Object.prototype, "node prototype"); + check(sessionStorage, Storage.prototype, "storage"); + check(Storage.prototype, Object.prototype, "storage prototype"); });
From: Jacek Caban jacek@codeweavers.com
--- dlls/mshtml/dispex.c | 6 ++++-- dlls/mshtml/htmldoc.c | 26 +++++++++++++++++--------- dlls/mshtml/mshtml_private.h | 2 ++ dlls/mshtml/tests/documentmode.js | 5 +++++ dlls/mshtml/tests/events.c | 1 - 5 files changed, 28 insertions(+), 12 deletions(-)
diff --git a/dlls/mshtml/dispex.c b/dlls/mshtml/dispex.c index ff3ed946284..e4e678a7efd 100644 --- a/dlls/mshtml/dispex.c +++ b/dlls/mshtml/dispex.c @@ -1812,6 +1812,7 @@ static void init_host_object(DispatchEx *dispex, HTMLInnerWindow *script_global,
static BOOL ensure_real_info(DispatchEx *dispex) { + compat_mode_t compat_mode; HTMLInnerWindow *script_global; DispatchEx *prototype = NULL;
@@ -1819,8 +1820,9 @@ static BOOL ensure_real_info(DispatchEx *dispex) return TRUE;
script_global = dispex->info->vtbl->get_script_global(dispex); + compat_mode = script_global->doc->document_mode;
- if(dispex->info->compat_mode >= COMPAT_MODE_IE9 && dispex->info->desc->id) { + if(compat_mode >= COMPAT_MODE_IE9 && dispex->info->desc->id) { HRESULT hres = get_prototype(script_global, dispex->info->desc->id, &prototype); if(FAILED(hres)) { ERR("could not get prototype: %08lx\n", hres); @@ -1828,7 +1830,7 @@ static BOOL ensure_real_info(DispatchEx *dispex) } }
- if (!(dispex->info = ensure_dispex_info(dispex->info->desc, script_global->doc->document_mode))) + if (!(dispex->info = ensure_dispex_info(dispex->info->desc, compat_mode))) return FALSE; init_host_object(dispex, script_global, prototype); return TRUE; diff --git a/dlls/mshtml/htmldoc.c b/dlls/mshtml/htmldoc.c index 31d879de837..13731e62474 100644 --- a/dlls/mshtml/htmldoc.c +++ b/dlls/mshtml/htmldoc.c @@ -5625,7 +5625,7 @@ static HRESULT HTMLDocumentNode_handle_event(DispatchEx* dispex, DOMEvent *event return S_OK; }
-static const event_target_vtbl_t HTMLDocumentNode_event_target_vtbl = { +static const event_target_vtbl_t HTMLDocument_event_target_vtbl = { { .query_interface = HTMLDocumentNode_query_interface, .destructor = HTMLDocumentNode_destructor, @@ -5707,12 +5707,20 @@ static void HTMLDocumentNode_init_dispex_info(dispex_data_t *info, compat_mode_t dispex_info_add_interface(info, IHTMLDocument2_tid, mode >= COMPAT_MODE_IE11 ? document2_ie11_hooks : document2_hooks); }
-static dispex_static_data_t HTMLDocumentNode_dispex = { - "HTMLDocument", - &HTMLDocumentNode_event_target_vtbl.dispex_vtbl, - DispHTMLDocument_tid, - HTMLDocumentNode_iface_tids, - HTMLDocumentNode_init_dispex_info +dispex_static_data_t Document_dispex = { + .name = "Document", + .id = PROT_Document, + .prototype_id = PROT_Node, +}; + +dispex_static_data_t HTMLDocument_dispex = { + .name = "HTMLDocument", + .id = PROT_HTMLDocument, + .prototype_id = PROT_Document, + .vtbl = &HTMLDocument_event_target_vtbl.dispex_vtbl, + .disp_tid = DispHTMLDocument_tid, + .iface_tids = HTMLDocumentNode_iface_tids, + .init_info = HTMLDocumentNode_init_dispex_info, };
static HTMLDocumentNode *alloc_doc_node(HTMLDocumentObj *doc_obj, HTMLInnerWindow *window, HTMLInnerWindow *script_global) @@ -5791,7 +5799,7 @@ HRESULT create_document_node(nsIDOMDocument *nsdoc, GeckoBrowser *browser, HTMLI doc->html_document = NULL; }
- HTMLDOMNode_Init(doc, &doc->node, (nsIDOMNode*)doc->dom_document, &HTMLDocumentNode_dispex); + HTMLDOMNode_Init(doc, &doc->node, (nsIDOMNode*)doc->dom_document, &HTMLDocument_dispex);
init_document_mutation(doc); doc_init_events(doc); @@ -5824,7 +5832,7 @@ static HRESULT create_document_fragment(nsIDOMNode *nsnode, HTMLDocumentNode *do if(!doc_frag) return E_OUTOFMEMORY;
- HTMLDOMNode_Init(doc_node, &doc_frag->node, nsnode, &HTMLDocumentNode_dispex); + HTMLDOMNode_Init(doc_node, &doc_frag->node, nsnode, &HTMLDocument_dispex); doc_frag->node.vtbl = &HTMLDocumentFragmentImplVtbl; doc_frag->document_mode = lock_document_mode(doc_node);
diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 958a7eef8a6..c30a2355605 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -408,8 +408,10 @@ typedef struct {
#define ALL_PROTOTYPES \ X(DOMImplementation) \ + X(Document) \ X(Element) \ X(HTMLBodyElement) \ + X(HTMLDocument) \ X(HTMLElement) \ X(Navigator) \ X(Node) \ diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index bbee5155946..85a063a564e 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -3129,4 +3129,9 @@ sync_test("prototypes", function() { check(Node.prototype, Object.prototype, "node prototype"); check(sessionStorage, Storage.prototype, "storage"); check(Storage.prototype, Object.prototype, "storage prototype"); + if(v >= 11) { + check(document, HTMLDocument.prototype, "html document"); + check(HTMLDocument.prototype, Document.prototype, "html document prototype"); + check(Document.prototype, Node.prototype, "document prototype"); + } }); diff --git a/dlls/mshtml/tests/events.c b/dlls/mshtml/tests/events.c index 6b48fcda226..2cf63f06dd3 100644 --- a/dlls/mshtml/tests/events.c +++ b/dlls/mshtml/tests/events.c @@ -4250,7 +4250,6 @@ static void test_doc_obj(IHTMLDocument2 *doc) hres = IHTMLDocument2_Invoke(doc, has_own_prop_id, &IID_NULL, 0, DISPATCH_METHOD, &dp, &res, NULL, NULL); ok(hres == S_OK, "Invoke(hasOwnProperty("createElement")) failed: %08lx\n", hres); ok(V_VT(&res) == VT_BOOL, "VT = %d\n", V_VT(&res)); - todo_wine ok(V_BOOL(&res) == VARIANT_FALSE, "hasOwnProperty("createElement") = %d\n", V_BOOL(&res));
hres = IHTMLDocument2_GetIDsOfNames(doc, &IID_NULL, &V_BSTR(&arg), 1, 0, &dispid);
From: Jacek Caban jacek@codeweavers.com
--- dlls/mshtml/dispex.c | 6 ++---- dlls/mshtml/htmlwindow.c | 16 +++++++--------- dlls/mshtml/mshtml_private.h | 4 +++- dlls/mshtml/script.c | 11 ++++++++--- dlls/mshtml/tests/documentmode.js | 2 ++ 5 files changed, 22 insertions(+), 17 deletions(-)
diff --git a/dlls/mshtml/dispex.c b/dlls/mshtml/dispex.c index e4e678a7efd..817547581e3 100644 --- a/dlls/mshtml/dispex.c +++ b/dlls/mshtml/dispex.c @@ -45,8 +45,6 @@ static CRITICAL_SECTION_DEBUG cs_dispex_static_data_dbg = }; static CRITICAL_SECTION cs_dispex_static_data = { &cs_dispex_static_data_dbg, -1, 0, 0, 0, 0 };
-static HRESULT get_prototype(HTMLInnerWindow *script_global, prototype_id_t id, DispatchEx **ret); - typedef struct { IID iid; VARIANT default_value; @@ -2818,9 +2816,9 @@ static const dispex_static_data_vtbl_t prototype_dispex_vtbl = { .find_dispid = prototype_find_dispid, };
-static HRESULT get_prototype(HTMLInnerWindow *script_global, prototype_id_t id, DispatchEx **ret) +HRESULT get_prototype(HTMLInnerWindow *script_global, prototype_id_t id, DispatchEx **ret) { - compat_mode_t compat_mode = dispex_compat_mode(&script_global->event_target.dispex); + compat_mode_t compat_mode = script_global->doc->document_mode; DispatchEx *prototype, *prot_prototype = NULL; dispex_static_data_t *desc; dispex_data_t *info; diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c index 3569b9caad1..a2afcdfdfbc 100644 --- a/dlls/mshtml/htmlwindow.c +++ b/dlls/mshtml/htmlwindow.c @@ -4207,14 +4207,12 @@ static const event_target_vtbl_t HTMLWindow_event_target_vtbl = { .set_current_event = HTMLWindow_set_current_event };
-static const tid_t HTMLWindow_iface_tids[] = { 0 }; - -static dispex_static_data_t HTMLWindow_dispex = { - "Window", - &HTMLWindow_event_target_vtbl.dispex_vtbl, - DispHTMLWindow2_tid, - HTMLWindow_iface_tids, - HTMLWindow_init_dispex_info +dispex_static_data_t Window_dispex = { + .name = "Window", + .id = PROT_Window, + .vtbl = &HTMLWindow_event_target_vtbl.dispex_vtbl, + .disp_tid = DispHTMLWindow2_tid, + .init_info = HTMLWindow_init_dispex_info, };
static nsresult NSAPI outer_window_traverse(void *ccp, void *p, nsCycleCollectionTraversalCallback *cb) @@ -4352,7 +4350,7 @@ static HRESULT create_inner_window(HTMLOuterWindow *outer_window, IMoniker *mon, window->base.outer_window = outer_window; window->base.inner_window = window;
- init_event_target(&window->event_target, &HTMLWindow_dispex, NULL); + init_event_target(&window->event_target, &Window_dispex, NULL);
window->task_magic = get_task_target_magic();
diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index c30a2355605..e5f842a2f4d 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -415,7 +415,8 @@ typedef struct { X(HTMLElement) \ X(Navigator) \ X(Node) \ - X(Storage) + X(Storage) \ + X(Window)
typedef enum { PROT_NONE, @@ -552,6 +553,7 @@ HRESULT dispex_define_property(DispatchEx *dispex, const WCHAR *name, DWORD flag HRESULT dispex_index_prop_desc(DispatchEx*,DISPID,struct property_info*); IWineJSDispatchHost *dispex_outer_iface(DispatchEx *dispex); HRESULT get_constructor(HTMLInnerWindow *script_global, prototype_id_t id, DispatchEx **ret); +HRESULT get_prototype(HTMLInnerWindow *script_global, prototype_id_t id, DispatchEx **ret);
typedef enum { DISPEXPROP_CUSTOM, diff --git a/dlls/mshtml/script.c b/dlls/mshtml/script.c index 30571c15fff..7ac26e63a3b 100644 --- a/dlls/mshtml/script.c +++ b/dlls/mshtml/script.c @@ -203,13 +203,18 @@ static BOOL init_script_engine(ScriptHost *script_host, IActiveScript *script) IWineJScript *jscript; hres = IActiveScript_QueryInterface(script, &IID_IWineJScript, (void **)&jscript); if(SUCCEEDED(hres)) { + DispatchEx *prototype; + assert(!script_host->window->jscript); assert(!script_host->window->event_target.dispex.jsdisp); script_host->window->jscript = jscript;
- hres = IWineJScript_InitHostObject(jscript, - &script_host->window->event_target.dispex.IWineJSDispatchHost_iface, - NULL, 0, &script_host->window->event_target.dispex.jsdisp); + hres = get_prototype(script_host->window, PROT_Window, &prototype); + if(SUCCEEDED(hres)) + hres = IWineJScript_InitHostObject(jscript, + &script_host->window->event_target.dispex.IWineJSDispatchHost_iface, + prototype->jsdisp, object_descriptors[PROT_Window]->js_flags, + &script_host->window->event_target.dispex.jsdisp); if(FAILED(hres)) ERR("Could not initialize script global: %08lx\n", hres);
diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index 85a063a564e..08e2daeff1e 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -3134,4 +3134,6 @@ sync_test("prototypes", function() { check(HTMLDocument.prototype, Document.prototype, "html document prototype"); check(Document.prototype, Node.prototype, "document prototype"); } + check(window, Window.prototype, "window"); + check(Window.prototype, Object.prototype, "window prototype"); });
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=147538
Your paranoid android.
=== debian11b (64 bit WoW report) ===
user32: input.c:4305: Test succeeded inside todo block: button_down_hwnd_todo 1: got MSG_TEST_WIN hwnd 00000000039100F2, msg WM_LBUTTONDOWN, wparam 0x1, lparam 0x320032