mshtml: Implement IWineDOMTokenList_remove() method.

Signed-off-by: Paul Gofman <pgofman@codeweavers.com>
Signed-off-by: Jacek Caban <jacek@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Paul Gofman 2021-07-19 15:53:18 +03:00 committed by Alexandre Julliard
parent 44031d7085
commit 94fb930251
3 changed files with 93 additions and 9 deletions

View File

@ -6515,14 +6515,15 @@ static const WCHAR *find_token(const WCHAR *list, const WCHAR *token, unsigned i
return NULL;
}
static HRESULT WINAPI token_list_add(IWineDOMTokenList *iface, BSTR token)
static HRESULT WINAPI token_list_add_remove(IWineDOMTokenList *iface, BSTR token, BOOL remove)
{
struct token_list *token_list = impl_from_IWineDOMTokenList(iface);
unsigned int i, len, old_len, new_len;
const WCHAR *old_pos;
BSTR new, old;
HRESULT hr;
TRACE("iface %p, token %s.\n", iface, debugstr_w(token));
TRACE("iface %p, token %s, remove %#x.\n", iface, debugstr_w(token), remove);
len = token ? lstrlenW(token) : 0;
if (!len)
@ -6543,14 +6544,33 @@ static HRESULT WINAPI token_list_add(IWineDOMTokenList *iface, BSTR token)
TRACE("old %s.\n", debugstr_w(old));
if (find_token(old, token, len))
if (((old_pos = find_token(old, token, len)) && !remove)
|| (!old_pos && remove))
{
SysFreeString(old);
return S_OK;
}
old_len = old ? lstrlenW(old) : 0;
new_len = old_len + len + !!old_len;
if (remove)
{
while (old_pos != old && iswspace(old_pos[-1]))
{
--old_pos;
++len;
}
while (iswspace(old_pos[len]))
++len;
if (old_pos != old && old_pos[len])
--len;
new_len = old_len - len;
}
else
{
new_len = old_len + len + !!old_len;
}
if (!(new = SysAllocStringLen(NULL, new_len)))
{
@ -6559,11 +6579,19 @@ static HRESULT WINAPI token_list_add(IWineDOMTokenList *iface, BSTR token)
return E_OUTOFMEMORY;
}
memcpy(new, old, sizeof(*new) * old_len);
if (old_len)
new[old_len++]= L' ';
memcpy(new + old_len, token, sizeof(*new) * len);
new[old_len + len] = 0;
if (remove)
{
memcpy(new, old, sizeof(*new) * (old_pos - old));
memcpy(new + (old_pos - old), old_pos + len, sizeof(*new) * (old_len - (old_pos - old) - len + 1));
}
else
{
memcpy(new, old, sizeof(*new) * old_len);
if (old_len)
new[old_len++]= L' ';
memcpy(new + old_len, token, sizeof(*new) * len);
new[old_len + len] = 0;
}
SysFreeString(old);
@ -6574,6 +6602,16 @@ static HRESULT WINAPI token_list_add(IWineDOMTokenList *iface, BSTR token)
return hr;
}
static HRESULT WINAPI token_list_add(IWineDOMTokenList *iface, BSTR token)
{
return token_list_add_remove(iface, token, FALSE);
}
static HRESULT WINAPI token_list_remove(IWineDOMTokenList *iface, BSTR token)
{
return token_list_add_remove(iface, token, TRUE);
}
static const IWineDOMTokenListVtbl WineDOMTokenListVtbl = {
token_list_QueryInterface,
token_list_AddRef,
@ -6583,6 +6621,7 @@ static const IWineDOMTokenListVtbl WineDOMTokenListVtbl = {
token_list_GetIDsOfNames,
token_list_Invoke,
token_list_add,
token_list_remove,
};
static const tid_t token_list_iface_tids[] = {

View File

@ -113,6 +113,8 @@ interface IWineDOMTokenList : IDispatch
{
[id(1)]
HRESULT add([in] BSTR token);
[id(2)]
HRESULT remove([in] BSTR token);
}
} /* library MSHTML_private */

View File

@ -562,4 +562,47 @@ sync_test("classList", function() {
exception = true;
}
ok(exception, "Expected exception for classList.add(\"e f\")");
classList.remove("e");
ok(elem.className === "a b c 4", "remove: expected className 'a b c 4', got " + elem.className);
exception = false
try
{
classList.remove("e f");
}
catch(e)
{
exception = true;
}
ok(exception, "remove: expected exception for classList.remove(\"e f\")");
exception = false
try
{
classList.remove("");
}
catch(e)
{
exception = true;
}
ok(exception, "remove: expected exception for classList.remove(\"\")");
classList.remove("d");
ok(elem.className === "a b c 4", "remove: expected className 'a b c 4', got " + elem.className);
classList.remove("c");
ok(elem.className === "a b 4", "remove: expected className 'a b 4', got " + elem.className);
classList.remove(4);
ok(elem.className === "a b", "remove: expected className 'a b', got " + elem.className);
classList.remove('a');
ok(elem.className === "b", "remove: expected className 'b', got " + elem.className);
classList.remove("a");
ok(elem.className === "b", "remove (2): expected className 'b', got " + elem.className);
classList.remove("b");
ok(elem.className === "", "remove: expected className '', got " + elem.className);
});