[PATCH v2 4/4] mshtml: Implement IWineDOMTokenList_remove() method.
Paul Gofman
pgofman at codeweavers.com
Mon Jul 19 07:53:18 CDT 2021
Signed-off-by: Paul Gofman <pgofman at codeweavers.com>
---
v2:
- define _remove argument as BSTR (and remove multiple arguments tests).
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);
});
--
2.31.1
More information about the wine-devel
mailing list