Paul Gofman : mshtml: Implement IWineDOMTokenList_remove() method.
Module: wine Branch: master Commit: 94fb93025180febc94984de44a3f026c20ade0e2 URL: https://source.winehq.org/git/wine.git/?a=commit;h=94fb93025180febc94984de44... Author: Paul Gofman <pgofman(a)codeweavers.com> Date: Mon Jul 19 15:53:18 2021 +0300 mshtml: Implement IWineDOMTokenList_remove() method. Signed-off-by: Paul Gofman <pgofman(a)codeweavers.com> Signed-off-by: Jacek Caban <jacek(a)codeweavers.com> Signed-off-by: Alexandre Julliard <julliard(a)winehq.org> --- dlls/mshtml/htmlelem.c | 57 ++++++++++++++++++++++++++++++------ dlls/mshtml/mshtml_private_iface.idl | 2 ++ dlls/mshtml/tests/dom.js | 43 +++++++++++++++++++++++++++ 3 files changed, 93 insertions(+), 9 deletions(-) diff --git a/dlls/mshtml/htmlelem.c b/dlls/mshtml/htmlelem.c index fd9ef686381..9ad538d2b00 100644 --- a/dlls/mshtml/htmlelem.c +++ b/dlls/mshtml/htmlelem.c @@ -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[] = { diff --git a/dlls/mshtml/mshtml_private_iface.idl b/dlls/mshtml/mshtml_private_iface.idl index 8a2c9463dca..491f4afb0b6 100644 --- a/dlls/mshtml/mshtml_private_iface.idl +++ b/dlls/mshtml/mshtml_private_iface.idl @@ -113,6 +113,8 @@ interface IWineDOMTokenList : IDispatch { [id(1)] HRESULT add([in] BSTR token); + [id(2)] + HRESULT remove([in] BSTR token); } } /* library MSHTML_private */ diff --git a/dlls/mshtml/tests/dom.js b/dlls/mshtml/tests/dom.js index ccbb3d8b69d..0085b40efed 100644 --- a/dlls/mshtml/tests/dom.js +++ b/dlls/mshtml/tests/dom.js @@ -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); });
participants (1)
-
Alexandre Julliard