mirror of
https://gitlab.winehq.org/wine/wine.git
synced 2024-11-19 17:06:04 -07:00
mshtml: Check if window global prop still exists before returning its id.
We have to introduce special handling for jscript, as it's probably integrated on native mshtml. Signed-off-by: Gabriel Ivăncescu <gabrielopcode@gmail.com>
This commit is contained in:
parent
055bf9f5a2
commit
9b264c948f
Notes:
Alexandre Julliard
2024-11-14 23:12:21 +01:00
Approved-by: Jacek Caban (@jacek) Approved-by: Alexandre Julliard (@julliard) Merge-Request: https://gitlab.winehq.org/wine/wine/merge_requests/6721
4 changed files with 144 additions and 3 deletions
|
@ -48,6 +48,7 @@ IDispatch *script_parse_event(HTMLInnerWindow*,LPCWSTR);
|
||||||
HRESULT exec_script(HTMLInnerWindow*,const WCHAR*,const WCHAR*,VARIANT*);
|
HRESULT exec_script(HTMLInnerWindow*,const WCHAR*,const WCHAR*,VARIANT*);
|
||||||
void update_browser_script_mode(GeckoBrowser*,IUri*);
|
void update_browser_script_mode(GeckoBrowser*,IUri*);
|
||||||
BOOL find_global_prop(HTMLInnerWindow*,const WCHAR*,DWORD,ScriptHost**,DISPID*);
|
BOOL find_global_prop(HTMLInnerWindow*,const WCHAR*,DWORD,ScriptHost**,DISPID*);
|
||||||
|
HRESULT global_prop_still_exists(HTMLInnerWindow*,global_prop_t*);
|
||||||
IDispatch *get_script_disp(ScriptHost*);
|
IDispatch *get_script_disp(ScriptHost*);
|
||||||
IActiveScriptSite *get_first_script_site(HTMLInnerWindow*);
|
IActiveScriptSite *get_first_script_site(HTMLInnerWindow*);
|
||||||
void initialize_script_global(HTMLInnerWindow*);
|
void initialize_script_global(HTMLInnerWindow*);
|
||||||
|
|
|
@ -3324,8 +3324,10 @@ HRESULT search_window_props(HTMLInnerWindow *This, const WCHAR *name, DWORD grfd
|
||||||
for(i=0; i < This->global_prop_cnt; i++) {
|
for(i=0; i < This->global_prop_cnt; i++) {
|
||||||
/* FIXME: case sensitivity */
|
/* FIXME: case sensitivity */
|
||||||
if(!wcscmp(This->global_props[i].name, name)) {
|
if(!wcscmp(This->global_props[i].name, name)) {
|
||||||
*pid = MSHTML_DISPID_CUSTOM_MIN+i;
|
HRESULT hres = global_prop_still_exists(This, &This->global_props[i]);
|
||||||
return S_OK;
|
if(hres == S_OK)
|
||||||
|
*pid = MSHTML_DISPID_CUSTOM_MIN + i;
|
||||||
|
return (hres == DISP_E_MEMBERNOTFOUND) ? DISP_E_UNKNOWNNAME : hres;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -85,6 +85,7 @@ struct ScriptHost {
|
||||||
SCRIPTSTATE script_state;
|
SCRIPTSTATE script_state;
|
||||||
|
|
||||||
HTMLInnerWindow *window;
|
HTMLInnerWindow *window;
|
||||||
|
IDispatchEx *script_dispex;
|
||||||
|
|
||||||
GUID guid;
|
GUID guid;
|
||||||
struct list entry;
|
struct list entry;
|
||||||
|
@ -255,6 +256,18 @@ static BOOL init_script_engine(ScriptHost *script_host, IActiveScript *script)
|
||||||
if(is_second_init)
|
if(is_second_init)
|
||||||
set_script_prop(first_host->script, SCRIPTPROP_ABBREVIATE_GLOBALNAME_RESOLUTION, &var);
|
set_script_prop(first_host->script, SCRIPTPROP_ABBREVIATE_GLOBALNAME_RESOLUTION, &var);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(IsEqualGUID(&script_host->guid, &CLSID_JScript)) {
|
||||||
|
IDispatch *script_disp;
|
||||||
|
|
||||||
|
hres = IActiveScript_GetScriptDispatch(script, NULL, &script_disp);
|
||||||
|
if(FAILED(hres))
|
||||||
|
WARN("GetScriptDispatch failed: %08lx\n", hres);
|
||||||
|
else {
|
||||||
|
IDispatch_QueryInterface(script_disp, &IID_IDispatchEx, (void**)&script_host->script_dispex);
|
||||||
|
IDispatch_Release(script_disp);
|
||||||
|
}
|
||||||
|
}
|
||||||
}else {
|
}else {
|
||||||
WARN("AddNamedItem failed: %08lx\n", hres);
|
WARN("AddNamedItem failed: %08lx\n", hres);
|
||||||
}
|
}
|
||||||
|
@ -288,6 +301,8 @@ static void release_script_engine(ScriptHost *This)
|
||||||
unlink_ref(&This->parse);
|
unlink_ref(&This->parse);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(This->script_dispex)
|
||||||
|
IDispatchEx_Release(This->script_dispex);
|
||||||
IActiveScript_Release(This->script);
|
IActiveScript_Release(This->script);
|
||||||
This->script = NULL;
|
This->script = NULL;
|
||||||
This->script_state = SCRIPTSTATE_UNINITIALIZED;
|
This->script_state = SCRIPTSTATE_UNINITIALIZED;
|
||||||
|
@ -1825,6 +1840,48 @@ BOOL find_global_prop(HTMLInnerWindow *window, const WCHAR *name, DWORD flags, S
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HRESULT global_prop_still_exists(HTMLInnerWindow *window, global_prop_t *prop)
|
||||||
|
{
|
||||||
|
HRESULT hres;
|
||||||
|
|
||||||
|
switch(prop->type) {
|
||||||
|
case GLOBAL_SCRIPTVAR: {
|
||||||
|
DWORD properties;
|
||||||
|
|
||||||
|
if(!prop->script_host->script)
|
||||||
|
return E_UNEXPECTED;
|
||||||
|
if(!prop->script_host->script_dispex)
|
||||||
|
return S_OK;
|
||||||
|
return IDispatchEx_GetMemberProperties(prop->script_host->script_dispex, prop->id, 0, &properties);
|
||||||
|
}
|
||||||
|
case GLOBAL_ELEMENTVAR: {
|
||||||
|
IHTMLElement *elem;
|
||||||
|
|
||||||
|
hres = IHTMLDocument3_getElementById(&window->doc->IHTMLDocument3_iface, prop->name, &elem);
|
||||||
|
if(FAILED(hres))
|
||||||
|
return hres;
|
||||||
|
|
||||||
|
if(!elem)
|
||||||
|
return DISP_E_MEMBERNOTFOUND;
|
||||||
|
IHTMLElement_Release(elem);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
case GLOBAL_FRAMEVAR: {
|
||||||
|
HTMLOuterWindow *frame;
|
||||||
|
|
||||||
|
hres = get_frame_by_name(window->base.outer_window, prop->name, FALSE, &frame);
|
||||||
|
if(FAILED(hres))
|
||||||
|
return hres;
|
||||||
|
|
||||||
|
return frame ? S_OK : DISP_E_MEMBERNOTFOUND;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
static BOOL is_jscript_available(void)
|
static BOOL is_jscript_available(void)
|
||||||
{
|
{
|
||||||
static BOOL available, checked;
|
static BOOL available, checked;
|
||||||
|
|
|
@ -1449,8 +1449,89 @@ sync_test("delete_prop", function() {
|
||||||
ok(obj.globalprop4, "globalprop4 = " + globalprop4);
|
ok(obj.globalprop4, "globalprop4 = " + globalprop4);
|
||||||
r = (delete globalprop4);
|
r = (delete globalprop4);
|
||||||
ok(r, "delete returned " + r);
|
ok(r, "delete returned " + r);
|
||||||
todo_wine.
|
|
||||||
ok(!("globalprop4" in obj), "globalprop4 is still in obj");
|
ok(!("globalprop4" in obj), "globalprop4 is still in obj");
|
||||||
|
|
||||||
|
globalprop5 = true;
|
||||||
|
ok(obj.globalprop5, "globalprop5 = " + globalprop5);
|
||||||
|
try {
|
||||||
|
r = (delete window.globalprop5);
|
||||||
|
ok(v >= 9, "did not get an expected exception deleting globalprop5");
|
||||||
|
ok(r, "delete returned " + r);
|
||||||
|
todo_wine.
|
||||||
|
ok(!("globalprop5" in obj), "globalprop5 is still in obj");
|
||||||
|
}catch(ex) {
|
||||||
|
ok(v < 9, "expected exception deleting globalprop5");
|
||||||
|
ok(ex.number === 0xa01bd - 0x80000000, "deleting globalprop5 threw " + ex.number);
|
||||||
|
ok("globalprop5" in obj, "globalprop5 is not in obj");
|
||||||
|
}
|
||||||
|
|
||||||
|
document.body.innerHTML = '<div id="winetest"/>';
|
||||||
|
ok("winetest" in obj, "winetest not in obj");
|
||||||
|
try {
|
||||||
|
r = (delete window.winetest);
|
||||||
|
ok(v >= 9, "did not get an expected exception deleting winetest");
|
||||||
|
ok(r, "delete returned " + r);
|
||||||
|
}catch(ex) {
|
||||||
|
ok(v < 9, "expected exception deleting winetest");
|
||||||
|
ok(ex.number === 0xa01bd - 0x80000000, "deleting winetest threw " + ex.number);
|
||||||
|
}
|
||||||
|
ok("winetest" in obj, "winetest is not in obj");
|
||||||
|
document.body.innerHTML = "";
|
||||||
|
ok(!("winetest" in obj), "winetest is still in obj");
|
||||||
|
|
||||||
|
document.body.innerHTML = '<div id="foobar"/>';
|
||||||
|
ok("foobar" in obj, "foobar not in obj");
|
||||||
|
window.foobar = "1234";
|
||||||
|
ok(obj.foobar === "1234", "foobar = " + obj.foobar);
|
||||||
|
document.body.innerHTML = "";
|
||||||
|
ok("foobar" in obj, "foobar is not in obj");
|
||||||
|
ok(obj.foobar === "1234", "foobar = " + obj.foobar);
|
||||||
|
try {
|
||||||
|
r = (delete window.foobar);
|
||||||
|
ok(v >= 9, "did not get an expected exception deleting foobar");
|
||||||
|
ok(r, "delete returned " + r);
|
||||||
|
ok(!("foobar" in obj), "foobar is still in obj");
|
||||||
|
}catch(ex) {
|
||||||
|
ok(v < 9, "expected exception deleting foobar");
|
||||||
|
ok(ex.number === 0xa01bd - 0x80000000, "deleting foobar threw " + ex.number);
|
||||||
|
ok("foobar" in obj, "foobar is not in obj");
|
||||||
|
}
|
||||||
|
|
||||||
|
document.body.innerHTML = '<div id="barfoo"/>';
|
||||||
|
ok("barfoo" in obj, "barfoo not in obj");
|
||||||
|
window.barfoo = "5678";
|
||||||
|
ok(obj.barfoo === "5678", "barfoo = " + obj.barfoo);
|
||||||
|
try {
|
||||||
|
r = (delete window.barfoo);
|
||||||
|
ok(v >= 9, "did not get an expected exception deleting barfoo");
|
||||||
|
ok(r, "delete returned " + r);
|
||||||
|
ok(obj.barfoo !== "5678", "barfoo is still 5678");
|
||||||
|
}catch(ex) {
|
||||||
|
ok(v < 9, "expected exception deleting barfoo");
|
||||||
|
ok(ex.number === 0xa01bd - 0x80000000, "deleting barfoo threw " + ex.number);
|
||||||
|
ok(obj.barfoo === "5678", "barfoo = " + obj.barfoo);
|
||||||
|
}
|
||||||
|
ok("barfoo" in obj, "barfoo is not in obj");
|
||||||
|
document.body.innerHTML = "";
|
||||||
|
if(v < 9)
|
||||||
|
ok("barfoo" in obj, "barfoo is not in obj");
|
||||||
|
else
|
||||||
|
ok(!("barfoo" in obj), "barfoo is still in obj");
|
||||||
|
|
||||||
|
document.body.innerHTML = '<iframe id="testwine"/>';
|
||||||
|
ok("testwine" in obj, "testwine not in obj");
|
||||||
|
try {
|
||||||
|
r = (delete window.testwine);
|
||||||
|
ok(v >= 9, "did not get an expected exception deleting testwine");
|
||||||
|
ok(r, "delete returned " + r);
|
||||||
|
}catch(ex) {
|
||||||
|
ok(v < 9, "expected exception deleting testwine");
|
||||||
|
ok(ex.number === 0xa01bd - 0x80000000, "deleting testwine threw " + ex.number);
|
||||||
|
}
|
||||||
|
ok("testwine" in obj, "testwine is not in obj");
|
||||||
|
|
||||||
|
document.body.innerHTML = "";
|
||||||
|
ok(!("testwine" in obj), "testwine is still in obj");
|
||||||
});
|
});
|
||||||
|
|
||||||
sync_test("detached arguments", function() {
|
sync_test("detached arguments", function() {
|
||||||
|
|
Loading…
Reference in a new issue