Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-cw
Commits
e28cc104
Commit
e28cc104
authored
Sep 01, 2022
by
Gabriel Ivăncescu
Committed by
Alexandre Julliard
Sep 01, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
mshtml: Implement props for Storage by forwarding to the underlying storage.
Signed-off-by:
Gabriel Ivăncescu
<
gabrielopcode@gmail.com
>
parent
74e6ec1e
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
184 additions
and
2 deletions
+184
-2
htmlstorage.c
dlls/mshtml/htmlstorage.c
+158
-1
mshtml_private.h
dlls/mshtml/mshtml_private.h
+5
-0
dom.js
dlls/mshtml/tests/dom.js
+21
-1
No files found.
dlls/mshtml/htmlstorage.c
View file @
e28cc104
...
...
@@ -39,6 +39,8 @@ typedef struct {
DispatchEx
dispex
;
IHTMLStorage
IHTMLStorage_iface
;
LONG
ref
;
unsigned
num_props
;
BSTR
*
props
;
struct
session_map_entry
*
session_storage
;
WCHAR
*
filename
;
HANDLE
mutex
;
...
...
@@ -178,6 +180,16 @@ void destroy_session_storage(thread_data_t *thread_data)
}
}
static
void
release_props
(
HTMLStorage
*
This
)
{
BSTR
*
prop
=
This
->
props
,
*
end
=
prop
+
This
->
num_props
;
while
(
prop
!=
end
)
{
SysFreeString
(
*
prop
);
prop
++
;
}
heap_free
(
This
->
props
);
}
static
inline
HTMLStorage
*
impl_from_IHTMLStorage
(
IHTMLStorage
*
iface
)
{
return
CONTAINING_RECORD
(
iface
,
HTMLStorage
,
IHTMLStorage_iface
);
...
...
@@ -227,6 +239,7 @@ static ULONG WINAPI HTMLStorage_Release(IHTMLStorage *iface)
release_dispex
(
&
This
->
dispex
);
heap_free
(
This
->
filename
);
CloseHandle
(
This
->
mutex
);
release_props
(
This
);
heap_free
(
This
);
}
...
...
@@ -835,13 +848,157 @@ static const IHTMLStorageVtbl HTMLStorageVtbl = {
HTMLStorage_clear
};
static
inline
HTMLStorage
*
impl_from_DispatchEx
(
DispatchEx
*
iface
)
{
return
CONTAINING_RECORD
(
iface
,
HTMLStorage
,
dispex
);
}
static
HRESULT
check_item
(
HTMLStorage
*
This
,
const
WCHAR
*
key
)
{
struct
session_entry
*
session_entry
;
IXMLDOMNode
*
root
,
*
node
;
IXMLDOMDocument
*
doc
;
HRESULT
hres
;
BSTR
query
;
if
(
!
This
->
filename
)
{
hres
=
get_session_entry
(
This
->
session_storage
,
key
,
FALSE
,
&
session_entry
);
if
(
SUCCEEDED
(
hres
))
hres
=
(
session_entry
&&
session_entry
->
value
)
?
S_OK
:
S_FALSE
;
return
hres
;
}
WaitForSingleObject
(
This
->
mutex
,
INFINITE
);
hres
=
open_document
(
This
->
filename
,
&
doc
);
if
(
hres
==
S_OK
)
{
hres
=
get_root_node
(
doc
,
&
root
);
IXMLDOMDocument_Release
(
doc
);
if
(
hres
==
S_OK
)
{
if
(
!
(
query
=
build_query
(
key
)))
hres
=
E_OUTOFMEMORY
;
else
{
hres
=
IXMLDOMNode_selectSingleNode
(
root
,
query
,
&
node
);
SysFreeString
(
query
);
if
(
hres
==
S_OK
)
IXMLDOMNode_Release
(
node
);
}
IXMLDOMNode_Release
(
root
);
}
}
ReleaseMutex
(
This
->
mutex
);
return
hres
;
}
static
HRESULT
get_prop
(
HTMLStorage
*
This
,
const
WCHAR
*
name
,
DISPID
*
dispid
)
{
UINT
name_len
=
wcslen
(
name
);
BSTR
p
,
*
prop
,
*
end
;
for
(
prop
=
This
->
props
,
end
=
prop
+
This
->
num_props
;
prop
!=
end
;
prop
++
)
{
if
(
SysStringLen
(
*
prop
)
==
name_len
&&
!
memcmp
(
*
prop
,
name
,
name_len
*
sizeof
(
WCHAR
)))
{
*
dispid
=
MSHTML_DISPID_CUSTOM_MIN
+
(
prop
-
This
->
props
);
return
S_OK
;
}
}
if
(
is_power_of_2
(
This
->
num_props
))
{
BSTR
*
new_props
=
heap_realloc
(
This
->
props
,
max
(
This
->
num_props
*
2
*
sizeof
(
BSTR
*
),
1
));
if
(
!
new_props
)
return
E_OUTOFMEMORY
;
This
->
props
=
new_props
;
}
if
(
!
(
p
=
SysAllocStringLen
(
name
,
name_len
)))
return
E_OUTOFMEMORY
;
This
->
props
[
This
->
num_props
]
=
p
;
*
dispid
=
MSHTML_DISPID_CUSTOM_MIN
+
This
->
num_props
++
;
return
S_OK
;
}
static
HRESULT
HTMLStorage_get_dispid
(
DispatchEx
*
dispex
,
BSTR
name
,
DWORD
flags
,
DISPID
*
dispid
)
{
HTMLStorage
*
This
=
impl_from_DispatchEx
(
dispex
);
HRESULT
hres
;
if
(
flags
&
fdexNameCaseInsensitive
)
FIXME
(
"case insensitive not supported
\n
"
);
if
(
!
(
flags
&
fdexNameEnsure
))
{
hres
=
check_item
(
This
,
name
);
if
(
hres
!=
S_OK
)
return
FAILED
(
hres
)
?
hres
:
DISP_E_UNKNOWNNAME
;
}
return
get_prop
(
This
,
name
,
dispid
);
}
static
HRESULT
HTMLStorage_invoke
(
DispatchEx
*
dispex
,
DISPID
id
,
LCID
lcid
,
WORD
flags
,
DISPPARAMS
*
params
,
VARIANT
*
res
,
EXCEPINFO
*
ei
,
IServiceProvider
*
caller
)
{
HTMLStorage
*
This
=
impl_from_DispatchEx
(
dispex
);
DWORD
idx
=
id
-
MSHTML_DISPID_CUSTOM_MIN
;
HRESULT
hres
;
BSTR
bstr
;
if
(
idx
>=
This
->
num_props
)
return
DISP_E_MEMBERNOTFOUND
;
switch
(
flags
)
{
case
DISPATCH_PROPERTYGET
:
hres
=
HTMLStorage_getItem
(
&
This
->
IHTMLStorage_iface
,
This
->
props
[
idx
],
res
);
if
(
FAILED
(
hres
))
return
hres
;
if
(
V_VT
(
res
)
==
VT_NULL
)
return
DISP_E_MEMBERNOTFOUND
;
break
;
case
DISPATCH_PROPERTYPUTREF
:
case
DISPATCH_PROPERTYPUT
:
if
(
params
->
cArgs
!=
1
||
(
params
->
cNamedArgs
&&
params
->
rgdispidNamedArgs
[
0
]
!=
DISPID_PROPERTYPUT
))
{
FIXME
(
"unimplemented args %u %u
\n
"
,
params
->
cArgs
,
params
->
cNamedArgs
);
return
E_NOTIMPL
;
}
bstr
=
V_BSTR
(
params
->
rgvarg
);
if
(
V_VT
(
params
->
rgvarg
)
!=
VT_BSTR
)
{
VARIANT
var
;
hres
=
change_type
(
&
var
,
params
->
rgvarg
,
VT_BSTR
,
caller
);
if
(
FAILED
(
hres
))
return
hres
;
bstr
=
V_BSTR
(
&
var
);
}
hres
=
HTMLStorage_setItem
(
&
This
->
IHTMLStorage_iface
,
This
->
props
[
idx
],
bstr
);
if
(
V_VT
(
params
->
rgvarg
)
!=
VT_BSTR
)
SysFreeString
(
bstr
);
return
hres
;
default:
FIXME
(
"unimplemented flags %x
\n
"
,
flags
);
return
E_NOTIMPL
;
}
return
S_OK
;
}
static
const
dispex_static_data_vtbl_t
HTMLStorage_dispex_vtbl
=
{
NULL
,
HTMLStorage_get_dispid
,
HTMLStorage_invoke
,
NULL
};
static
const
tid_t
HTMLStorage_iface_tids
[]
=
{
IHTMLStorage_tid
,
0
};
static
dispex_static_data_t
HTMLStorage_dispex
=
{
L"Storage"
,
NULL
,
&
HTMLStorage_dispex_vtbl
,
IHTMLStorage_tid
,
HTMLStorage_iface_tids
};
...
...
dlls/mshtml/mshtml_private.h
View file @
e28cc104
...
...
@@ -1423,6 +1423,11 @@ static inline BOOL is_digit(WCHAR c)
return
'0'
<=
c
&&
c
<=
'9'
;
}
static
inline
BOOL
is_power_of_2
(
unsigned
x
)
{
return
!
(
x
&
(
x
-
1
));
}
#ifdef __i386__
extern
void
*
call_thiscall_func
;
#endif
...
...
dlls/mshtml/tests/dom.js
View file @
e28cc104
...
...
@@ -473,7 +473,27 @@ sync_test("storage", function() {
"typeof(window.localStorage) = "
+
typeof
(
window
.
localStorage
));
var
item
=
sessionStorage
.
getItem
(
"nonexisting"
);
ok
(
item
===
null
,
"item = "
+
item
);
ok
(
item
===
null
,
"'nonexisting' item = "
+
item
);
item
=
sessionStorage
[
"nonexisting"
];
ok
(
item
===
undefined
,
"[nonexisting] item = "
+
item
);
ok
(
!
(
"nonexisting"
in
sessionStorage
),
"nonexisting in sessionStorage"
);
sessionStorage
.
setItem
(
"foobar"
,
42
);
ok
(
"foobar"
in
sessionStorage
,
"foobar not in sessionStorage"
);
item
=
sessionStorage
.
getItem
(
"foobar"
);
ok
(
item
===
"42"
,
"'foobar' item = "
+
item
);
item
=
sessionStorage
[
"foobar"
];
ok
(
item
===
"42"
,
"[foobar] item = "
+
item
);
sessionStorage
.
removeItem
(
"foobar"
);
item
=
sessionStorage
[
"foobar"
];
ok
(
item
===
undefined
,
"[foobar] item after removal = "
+
item
);
sessionStorage
[
"barfoo"
]
=
true
;
ok
(
"barfoo"
in
sessionStorage
,
"barfoo not in sessionStorage"
);
item
=
sessionStorage
[
"barfoo"
];
ok
(
item
===
"true"
,
"[barfoo] item = "
+
item
);
item
=
sessionStorage
.
getItem
(
"barfoo"
);
ok
(
item
===
"true"
,
"'barfoo' item = "
+
item
);
});
async_test
(
"animation"
,
function
()
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment