From: Gabriel Ivăncescu gabrielopcode@gmail.com
`length` for localStorage is not updated immediately on native, which suggests some caching is involved for a period of time (probably for performance reasons to avoid reading the file everytime the prop is read), or it doesn't block like the rest since the write is asynchronous, making it unreliable to test, which is why the tests for it are basic.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlstorage.c | 21 +++++++++++++++++++-- dlls/mshtml/tests/misc.c | 30 ++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 2 deletions(-)
diff --git a/dlls/mshtml/htmlstorage.c b/dlls/mshtml/htmlstorage.c index f1c5801764d..9b0beff8f9f 100644 --- a/dlls/mshtml/htmlstorage.c +++ b/dlls/mshtml/htmlstorage.c @@ -383,8 +383,25 @@ static HRESULT get_node_list(const WCHAR *filename, IXMLDOMNodeList **node_list) static HRESULT WINAPI HTMLStorage_get_length(IHTMLStorage *iface, LONG *p) { HTMLStorage *This = impl_from_IHTMLStorage(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + IXMLDOMNodeList *node_list; + HRESULT hres; + + TRACE("(%p)->(%p)\n", This, p); + + if(!This->filename) { + *p = This->session_storage->num_keys; + return S_OK; + } + + WaitForSingleObject(This->mutex, INFINITE); + hres = get_node_list(This->filename, &node_list); + if(SUCCEEDED(hres)) { + hres = IXMLDOMNodeList_get_length(node_list, p); + IXMLDOMNodeList_Release(node_list); + } + ReleaseMutex(This->mutex); + + return hres; }
static HRESULT WINAPI HTMLStorage_get_remainingSpace(IHTMLStorage *iface, LONG *p) diff --git a/dlls/mshtml/tests/misc.c b/dlls/mshtml/tests/misc.c index d898b04fffa..d1bdd2d544e 100644 --- a/dlls/mshtml/tests/misc.c +++ b/dlls/mshtml/tests/misc.c @@ -197,6 +197,7 @@ static void test_HTMLStorage(void) { IHTMLDocument2 *doc, *doc2; IHTMLStorage *storage, *storage2; + LONG length, lval; VARIANT var; BSTR key, value; HRESULT hres; @@ -220,6 +221,10 @@ static void test_HTMLStorage(void) hres = IHTMLStorage_removeItem(storage, key); ok(hres == S_OK, "removeItem failed: %08lx\n", hres);
+ hres = IHTMLStorage_get_length(storage, &length); + ok(hres == S_OK, "get_length failed %08lx\n", hres); + ok(length >= 0, "length = %ld\n", lval); + value = SysAllocString(L"null"); hres = IHTMLStorage_setItem(storage, key, value); ok(hres == S_OK, "setItem failed: %08lx\n", hres); @@ -337,6 +342,10 @@ static void test_HTMLStorage(void) hres = get_sessionstorage(doc2, &storage2); ok(hres == S_OK, "got %08lx\n", hres);
+ hres = IHTMLStorage_get_length(storage, &lval); + ok(hres == S_OK, "get_length failed %08lx\n", hres); + ok(lval == 0, "length = %ld\n", lval); + key = SysAllocString(L""); V_VT(&var) = 0xdead; hres = IHTMLStorage_getItem(storage, key, &var); @@ -353,6 +362,13 @@ static void test_HTMLStorage(void) ok(hres == S_OK, "setItem failed: %08lx\n", hres); SysFreeString(value);
+ hres = IHTMLStorage_get_length(storage, &lval); + ok(hres == S_OK, "get_length failed %08lx\n", hres); + ok(lval == 1, "length = %ld\n", lval); + hres = IHTMLStorage_get_length(storage2, &lval); + ok(hres == S_OK, "get_length failed %08lx\n", hres); + ok(lval == 1, "length = %ld\n", lval); + V_VT(&var) = 0xdead; hres = IHTMLStorage_getItem(storage, key, &var); ok(hres == S_OK, "getItem failed: %08lx\n", hres); @@ -420,6 +436,13 @@ static void test_HTMLStorage(void) VariantClear(&var); SysFreeString(key);
+ hres = IHTMLStorage_get_length(storage, &lval); + ok(hres == S_OK, "get_length failed %08lx\n", hres); + ok(lval == 2, "length = %ld\n", lval); + hres = IHTMLStorage_get_length(storage2, &lval); + ok(hres == S_OK, "get_length failed %08lx\n", hres); + ok(lval == 2, "length = %ld\n", lval); + hres = IHTMLStorage_key(storage, 0, &key); ok(hres == S_OK, "key failed %08lx\n", hres); ok(!wcscmp(key, L"undefined"), "key(0) = %s\n", wine_dbgstr_w(key)); @@ -458,6 +481,13 @@ static void test_HTMLStorage(void) hres = IHTMLStorage_clear(storage2); ok(hres == S_OK, "clear failed %08lx\n", hres);
+ hres = IHTMLStorage_get_length(storage, &lval); + ok(hres == S_OK, "get_length failed %08lx\n", hres); + ok(lval == 0, "length = %ld\n", lval); + hres = IHTMLStorage_get_length(storage2, &lval); + ok(hres == S_OK, "get_length failed %08lx\n", hres); + ok(lval == 0, "length = %ld\n", lval); + hres = IHTMLStorage_key(storage, 0, &key); ok(hres == E_INVALIDARG, "key failed %08lx\n", hres);