[PATCH 4/4] mshtml: Implement IWineDOMTokenList_remove() method.
Paul Gofman
pgofman at codeweavers.com
Mon Jul 19 04:55:46 CDT 2021
Signed-off-by: Paul Gofman <pgofman at codeweavers.com>
---
dlls/mshtml/htmlelem.c | 55 ++++++++++++++++++++++++----
dlls/mshtml/mshtml_private_iface.idl | 2 +
dlls/mshtml/tests/dom.js | 43 ++++++++++++++++++++++
3 files changed, 92 insertions(+), 8 deletions(-)
diff --git a/dlls/mshtml/htmlelem.c b/dlls/mshtml/htmlelem.c
index b5b0daa2539..4506f170616 100644
--- a/dlls/mshtml/htmlelem.c
+++ b/dlls/mshtml/htmlelem.c
@@ -6515,11 +6515,12 @@ static const WCHAR *find_token(const WCHAR *list, const WCHAR *token, unsigned i
return NULL;
}
-static HRESULT WINAPI token_list_add(IWineDOMTokenList *iface, SAFEARRAY *token_array)
+static HRESULT WINAPI token_list_add_remove(IWineDOMTokenList *iface, SAFEARRAY *token_array, BOOL remove)
{
struct token_list *token_list = impl_from_IWineDOMTokenList(iface);
unsigned int i, len, old_len, new_len;
WCHAR *token, *old, *new;
+ const WCHAR *old_pos;
VARIANT *var, tmp;
HRESULT hr;
@@ -6578,7 +6579,8 @@ static HRESULT WINAPI token_list_add(IWineDOMTokenList *iface, SAFEARRAY *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);
hr = S_OK;
@@ -6586,7 +6588,25 @@ static HRESULT WINAPI token_list_add(IWineDOMTokenList *iface, SAFEARRAY *token_
}
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 = heap_alloc(sizeof(*new) * (new_len + 1))))
{
@@ -6596,11 +6616,19 @@ static HRESULT WINAPI token_list_add(IWineDOMTokenList *iface, SAFEARRAY *token_
goto done;
}
- 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);
@@ -6616,6 +6644,16 @@ done:
return hr;
}
+static HRESULT WINAPI token_list_add(IWineDOMTokenList *iface, SAFEARRAY *token_array)
+{
+ return token_list_add_remove(iface, token_array, FALSE);
+}
+
+static HRESULT WINAPI token_list_remove(IWineDOMTokenList *iface, SAFEARRAY *token_array)
+{
+ return token_list_add_remove(iface, token_array, TRUE);
+}
+
static const IWineDOMTokenListVtbl WineDOMTokenListVtbl = {
token_list_QueryInterface,
token_list_AddRef,
@@ -6625,6 +6663,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 b50d2f9502b..7dc4928aab8 100644
--- a/dlls/mshtml/mshtml_private_iface.idl
+++ b/dlls/mshtml/mshtml_private_iface.idl
@@ -113,6 +113,8 @@ interface IWineDOMTokenList : IDispatch
{
[vararg, id(1)]
HRESULT add([in] SAFEARRAY(VARIANT) token);
+ [vararg, id(2)]
+ HRESULT remove([in] SAFEARRAY(VARIANT) token);
}
} /* library MSHTML_private */
diff --git a/dlls/mshtml/tests/dom.js b/dlls/mshtml/tests/dom.js
index ae6d49da26c..f3fe245d250 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", 4);
+ 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