From: Jacek Caban jacek@codeweavers.com
--- dlls/mshtml/dispex.c | 5 ++-- dlls/mshtml/htmldoc.c | 31 +++++++++++-------- dlls/mshtml/htmlwindow.c | 2 +- dlls/mshtml/mshtml_private.h | 2 +- dlls/mshtml/tests/documentmode.js | 4 +-- dlls/mshtml/tests/es5.js | 49 ++++++++++++++++++++++++++----- dlls/mshtml/tests/events.c | 1 - 7 files changed, 65 insertions(+), 29 deletions(-)
diff --git a/dlls/mshtml/dispex.c b/dlls/mshtml/dispex.c index 6bbc34b516e..d9d7b35526f 100644 --- a/dlls/mshtml/dispex.c +++ b/dlls/mshtml/dispex.c @@ -1734,13 +1734,14 @@ static dispex_data_t *ensure_dispex_info(DispatchEx *dispex, dispex_static_data_
static BOOL ensure_real_info(DispatchEx *dispex) { + HTMLInnerWindow *script_global = NULL; compat_mode_t compat_mode;
if(dispex->info != dispex->info->desc->delayed_init_info) return TRUE;
- compat_mode = dispex->info->desc->vtbl->get_compat_mode(dispex); - dispex->info = ensure_dispex_info(dispex, dispex->info->desc, compat_mode, NULL); + compat_mode = dispex->info->desc->vtbl->get_compat_mode(dispex, &script_global); + dispex->info = ensure_dispex_info(dispex, dispex->info->desc, compat_mode, script_global); return dispex->info != NULL; }
diff --git a/dlls/mshtml/htmldoc.c b/dlls/mshtml/htmldoc.c index 6fe1516a720..0eb2bc3bcda 100644 --- a/dlls/mshtml/htmldoc.c +++ b/dlls/mshtml/htmldoc.c @@ -5364,17 +5364,6 @@ static void HTMLDocumentNode_destructor(DispatchEx *dispex) HTMLDOMNode_destructor(&This->node.event_target.dispex); }
-static HRESULT HTMLDocumentNode_get_name(DispatchEx *dispex, DISPID id, BSTR *name) -{ - HTMLDocumentNode *This = impl_from_DispatchEx(dispex); - DWORD idx = id - MSHTML_DISPID_CUSTOM_MIN; - - if(!This->dom_document || idx >= This->elem_vars_cnt) - return DISP_E_MEMBERNOTFOUND; - - return (*name = SysAllocString(This->elem_vars[idx])) ? S_OK : E_OUTOFMEMORY; -} - static HRESULT HTMLDocumentNode_get_dispid(DispatchEx *dispex, const WCHAR *name, DWORD grfdex, DISPID *dispid) { HTMLDocumentNode *This = impl_from_DispatchEx(dispex); @@ -5531,12 +5520,28 @@ static HRESULT HTMLDocumentNode_next_dispid(DispatchEx *dispex, DISPID id, DISPI return S_OK; }
-static compat_mode_t HTMLDocumentNode_get_compat_mode(DispatchEx *dispex) +static HRESULT HTMLDocumentNode_get_prop_desc(DispatchEx *dispex, DISPID id, struct property_info *desc) +{ + HTMLDocumentNode *This = impl_from_DispatchEx(dispex); + DWORD idx = id - MSHTML_DISPID_CUSTOM_MIN; + + if(!This->dom_document || idx >= This->elem_vars_cnt) + return DISP_E_MEMBERNOTFOUND; + + desc->name = This->elem_vars[idx]; + desc->id = id; + desc->flags = PROPF_WRITABLE | PROPF_CONFIGURABLE | PROPF_ENUMERABLE; + desc->func_iid = 0; + return S_OK; +} + +static compat_mode_t HTMLDocumentNode_get_compat_mode(DispatchEx *dispex, HTMLInnerWindow **script_global) { HTMLDocumentNode *This = impl_from_DispatchEx(dispex);
TRACE("(%p) returning %u\n", This, This->document_mode);
+ *script_global = This->script_global; return lock_document_mode(This); }
@@ -5628,9 +5633,9 @@ static const event_target_vtbl_t HTMLDocumentNode_event_target_vtbl = { .destructor = HTMLDocumentNode_destructor, .traverse = HTMLDocumentNode_traverse, .unlink = HTMLDocumentNode_unlink, - .get_name = HTMLDocumentNode_get_name, .get_dispid = HTMLDocumentNode_get_dispid, .find_dispid = HTMLDocumentNode_find_dispid, + .get_prop_desc = HTMLDocumentNode_get_prop_desc, .invoke = HTMLDocumentNode_invoke, .disp_invoke = HTMLDocumentNode_disp_invoke, .next_dispid = HTMLDocumentNode_next_dispid, diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c index c40d3fe889b..ceac07e4dd3 100644 --- a/dlls/mshtml/htmlwindow.c +++ b/dlls/mshtml/htmlwindow.c @@ -3946,7 +3946,7 @@ static HRESULT HTMLWindow_next_dispid(DispatchEx *dispex, DISPID id, DISPID *pid return S_OK; }
-static compat_mode_t HTMLWindow_get_compat_mode(DispatchEx *dispex) +static compat_mode_t HTMLWindow_get_compat_mode(DispatchEx *dispex, HTMLInnerWindow **script_global) { HTMLInnerWindow *This = impl_from_DispatchEx(dispex); return lock_document_mode(This->doc); diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 4e6a79108bb..04c51fb2503 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -398,7 +398,7 @@ typedef struct { HRESULT (*disp_invoke)(DispatchEx*,DISPID,LCID,WORD,DISPPARAMS*,VARIANT*,EXCEPINFO*,IServiceProvider*);
/* Used by objects that want to delay their compat mode initialization until actually needed */ - compat_mode_t (*get_compat_mode)(DispatchEx*); + compat_mode_t (*get_compat_mode)(DispatchEx*,HTMLInnerWindow**);
/* Used by objects that want to populate some dynamic props on initialization */ HRESULT (*populate_props)(DispatchEx*); diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index 76598cadb77..5fada630a51 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -296,7 +296,7 @@ sync_test("builtin_toString", function() { if(clientRects) test("clientRect", clientRects[0], "ClientRect", null, true); if(clientRects) test("clientRects", clientRects, "ClientRectList"); if(currentStyle) test("currentStyle", currentStyle, "MSCurrentStyleCSSProperties", null, true); - if(v >= 11 /* todo_wine */) test("document", document, v < 11 ? "Document" : "HTMLDocument", null, true); + if(v >= 11 /* todo_wine */) test("document", document, v < 11 ? "Document" : "HTMLDocument"); test("elements", document.getElementsByTagName("body"), "HTMLCollection", null, true); test("history", window.history, "History"); test("implementation", document.implementation, "DOMImplementation"); @@ -379,7 +379,6 @@ sync_test("builtin_obj", function() { }catch(ex) { e = ex.number; } - todo_wine_if(v >= 9). ok(e === (v < 9 ? 0xa0005 : 0x0ffff) - 0x80000000, "[f.call(Object, 'div')] e = " + e);
e = 0; @@ -388,7 +387,6 @@ sync_test("builtin_obj", function() { }catch(ex) { e = ex.number; } - todo_wine_if(v >= 9). ok(e === (v < 9 ? 0xa0005 : 0x0ffff) - 0x80000000, "[f.call(null, 'div')] e = " + e);
var elem1 = f.call(document, "div"); diff --git a/dlls/mshtml/tests/es5.js b/dlls/mshtml/tests/es5.js index 1225a744de6..ddffea263a6 100644 --- a/dlls/mshtml/tests/es5.js +++ b/dlls/mshtml/tests/es5.js @@ -41,6 +41,15 @@ var JS_E_ARRAYBUFFER_EXPECTED = 0x800a15e4;
var tests = [];
+function check_enum(o, name) { + var ret = 0; + for(var iter in o) { + if(iter == name) ret++; + } + ok(ret < 2, name + " enumerated " + ret + " times"); + return ret != 0; +} + sync_test("script vars", function() { function foo() { } foo.prototype.foo = 13; @@ -2637,14 +2646,6 @@ sync_test("screen", function() { o.prop2 = 3; ok(!("prop2" in o), "o.prop2 = " + o.prop2);
- function check_enum(o, name) { - var ret = 0; - for(var iter in o) { - if(iter == name) ret++; - } - ok(ret < 2, name + " enumerated " + ret + " times"); - return ret != 0; - } ok(check_enum(o, "width"), "width not enumerated"); ok(check_enum(o, "height"), "height not enumerated"); ok(check_enum(o, "prop"), "prop not enumerated"); @@ -2692,3 +2693,35 @@ async_test("script_global", function() { iframe.src = "about:blank"; document.body.appendChild(iframe); }); + +sync_test("form_as_prop", function() { + document.body.innerHTML = '<form id="testid" name="testname"></form>'; + var form = document.body.firstChild; + var o = Object.create(document); + + ok(document.testid === form, "document.testid = " + document.testid); + ok(o.testid === form, "o.testid = " + o.testid); + ok(document.hasOwnProperty("testid"), 'document.hasOwnProperty("testid") = ' + document.hasOwnProperty("testid")); + ok(!o.hasOwnProperty("testid"), 'o.hasOwnProperty("testid") = ' + o.hasOwnProperty("testid")); + test_own_data_prop_desc(document, "testid", true, true, true); + + ok(document.testname === form, "document.testname = " + document.testname); + ok(o.testname === form, "o.testname = " + o.testname); + ok(document.hasOwnProperty("testname"), 'document.hasOwnProperty("testname") = ' + document.hasOwnProperty("testname")); + ok(!o.hasOwnProperty("testname"), 'o.hasOwnProperty("testname") = ' + o.hasOwnProperty("testname")); + test_own_data_prop_desc(document, "testname", true, true, true); + todo_wine. + ok(!check_enum(document, "testid"), "testid enumerated in document"); + ok(check_enum(document, "testname"), "testid not enumerated in document"); + todo_wine. + ok(!check_enum(o, "testid"), "testid enumerated in o"); + ok(check_enum(o, "testname"), "testid not enumerated in o"); + + document.body.innerHTML = ''; + ok(!("testid" in o), "testid is in o"); + ok(!("testname" in o), "testname is in o"); + ok(!("testid" in document), "testid is in document"); + ok(!("testname" in document), "testname is in document"); + ok(!document.hasOwnProperty("testid"), 'document.hasOwnProperty("testid") = ' + document.hasOwnProperty("testid")); + ok(!document.hasOwnProperty("testname"), 'document.hasOwnProperty("testname") = ' + document.hasOwnProperty("testname")); +}); diff --git a/dlls/mshtml/tests/events.c b/dlls/mshtml/tests/events.c index 9760d6bcb9a..6b48fcda226 100644 --- a/dlls/mshtml/tests/events.c +++ b/dlls/mshtml/tests/events.c @@ -4239,7 +4239,6 @@ static void test_doc_obj(IHTMLDocument2 *doc) /* jscript prop on prototype chain */ bstr = SysAllocString(L"hasOwnProperty"); hres = IHTMLDocument2_GetIDsOfNames(doc, &IID_NULL, &bstr, 1, 0, &has_own_prop_id); - todo_wine_if(document_mode >= 9) ok(hres == (document_mode < 9 ? DISP_E_UNKNOWNNAME : S_OK), "GetIDsOfNames(hasOwnProperty) returned: %08lx\n", hres); SysFreeString(bstr);