summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Silverstone <dsilvers@digital-scurf.org>2022-11-27 09:40:47 +0000
committerDaniel Silverstone <dsilvers@digital-scurf.org>2022-11-27 09:40:47 +0000
commit7bcd4fd2465631f4a17e1920594e9c2536b6f057 (patch)
tree5c12885af1c2a2f852ef21493c001a57b7f133cb
parent764fca4f3abfc7437003f496d52039ad7e6b779d (diff)
downloadnetsurf-7bcd4fd2465631f4a17e1920594e9c2536b6f057.tar.gz
netsurf-7bcd4fd2465631f4a17e1920594e9c2536b6f057.tar.bz2
DOMTokenList: Add support and testing for this
We add both DOMTokenList and DOMSettableTokenList and introduce polyfills for stringifying it until nsgenbind can do that. We also bring in a test to demonstrate all that we have. Note: This does not implement the extra methods that exist according to MDN, we may need a polyfill to bring that up to snuff. Signed-off-by: Daniel Silverstone <dsilvers@digital-scurf.org>
-rw-r--r--content/handlers/javascript/duktape/DOMSettableTokenList.bnd44
-rw-r--r--content/handlers/javascript/duktape/DOMTokenList.bnd163
-rw-r--r--content/handlers/javascript/duktape/Element.bnd21
-rw-r--r--content/handlers/javascript/duktape/netsurf.bnd2
-rw-r--r--content/handlers/javascript/duktape/polyfill.js18
-rw-r--r--test/js/class-list.html29
-rw-r--r--test/js/index.html1
7 files changed, 278 insertions, 0 deletions
diff --git a/content/handlers/javascript/duktape/DOMSettableTokenList.bnd b/content/handlers/javascript/duktape/DOMSettableTokenList.bnd
new file mode 100644
index 000000000..ac5c7062a
--- /dev/null
+++ b/content/handlers/javascript/duktape/DOMSettableTokenList.bnd
@@ -0,0 +1,44 @@
+/* DOMTokenList binding for browser using duktape and libdom
+ *
+ * Copyright 2015 Vincent Sanders <vince@netsurf-browser.org>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * Released under the terms of the MIT License,
+ * http://www.opensource.org/licenses/mit-license
+ */
+
+class DOMSettableTokenList {
+};
+
+init DOMSettableTokenList(struct dom_tokenlist *tokens::tokens);
+
+getter DOMSettableTokenList::value()
+%{
+ dom_exception exc;
+ dom_string *value;
+
+ exc = dom_tokenlist_get_value(priv->parent.tokens, &value);
+ if (exc != DOM_NO_ERR) return 0; /* coerced to undefined */
+
+ duk_push_lstring(ctx, dom_string_data(value), dom_string_length(value));
+ dom_string_unref(value);
+
+ return 1;
+%}
+
+setter DOMSettableTokenList::value()
+%{
+ dom_exception exc;
+ dom_string *value;
+ duk_size_t slen;
+ const char *s = duk_require_lstring(ctx, 0, &slen);
+
+ exc = dom_string_create_interned((const uint8_t *)s, slen, &value);
+ if (exc != DOM_NO_ERR) return 0;
+
+ exc = dom_tokenlist_set_value(priv->parent.tokens, value);
+ dom_string_unref(value);
+
+ return 0;
+%} \ No newline at end of file
diff --git a/content/handlers/javascript/duktape/DOMTokenList.bnd b/content/handlers/javascript/duktape/DOMTokenList.bnd
new file mode 100644
index 000000000..928d9ef35
--- /dev/null
+++ b/content/handlers/javascript/duktape/DOMTokenList.bnd
@@ -0,0 +1,163 @@
+/* DOMTokenList binding for browser using duktape and libdom
+ *
+ * Copyright 2015 Vincent Sanders <vince@netsurf-browser.org>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * Released under the terms of the MIT License,
+ * http://www.opensource.org/licenses/mit-license
+ */
+
+class DOMTokenList {
+ private struct dom_tokenlist *tokens;
+};
+
+init DOMTokenList(struct dom_tokenlist *tokens)
+%{
+ priv->tokens = tokens;
+ dom_tokenlist_ref(tokens);
+%}
+
+fini DOMTokenList()
+%{
+ dom_tokenlist_unref(priv->tokens);
+%}
+
+getter DOMTokenList::length()
+%{
+ dom_exception err;
+ uint32_t len;
+
+ err = dom_tokenlist_get_length(priv->tokens, &len);
+
+ if (err != DOM_NO_ERR) return 0; /* coerced to undefined */
+
+ duk_push_uint(ctx, (duk_uint_t)len);
+
+ return 1;
+%}
+
+method DOMTokenList::item()
+%{
+ unsigned long i = duk_to_uint(ctx, 0);
+ dom_exception err;
+ dom_string *value;
+
+ err = dom_tokenlist_item(priv->tokens, i, &value);
+
+ if (err != DOM_NO_ERR) return 0; /* coerced to undefined */
+
+ if (value == NULL) {
+ duk_push_null(ctx);
+ return 1;
+ }
+
+ duk_push_lstring(ctx, dom_string_data(value), dom_string_length(value));
+ dom_string_unref(value);
+
+ return 1;
+%}
+
+method DOMTokenList::add()
+%{
+ dom_exception exc;
+ dom_string *value;
+ duk_size_t slen;
+ const char *s;
+ duk_idx_t spos;
+
+ for (spos = 0; spos < duk_get_top(ctx); ++spos) {
+ s = duk_safe_to_lstring(ctx, spos, &slen);
+
+ duk_safe_to_lstring(ctx, 0, &slen);
+
+ exc = dom_string_create_interned((const uint8_t *)s, slen, &value);
+ if (exc != DOM_NO_ERR) return 0;
+
+ exc = dom_tokenlist_add(priv->tokens, value);
+ dom_string_unref(value);
+ }
+
+ return 0;
+%}
+
+method DOMTokenList::remove()
+%{
+ dom_exception exc;
+ dom_string *value;
+ duk_size_t slen;
+ const char *s;
+ duk_idx_t spos;
+
+ for (spos = 0; spos < duk_get_top(ctx); ++spos) {
+ s = duk_safe_to_lstring(ctx, spos, &slen);
+
+ duk_safe_to_lstring(ctx, 0, &slen);
+
+ exc = dom_string_create_interned((const uint8_t *)s, slen, &value);
+ if (exc != DOM_NO_ERR) return 0;
+
+ exc = dom_tokenlist_remove(priv->tokens, value);
+ dom_string_unref(value);
+ }
+
+ return 0;
+%}
+
+method DOMTokenList::contains()
+%{
+ dom_exception exc;
+ dom_string *value;
+ duk_size_t slen;
+ const char *s = duk_safe_to_lstring(ctx, 0, &slen);
+ bool present = false;
+
+ exc = dom_string_create_interned((const uint8_t *)s, slen, &value);
+ if (exc != DOM_NO_ERR) return 0;
+
+ exc = dom_tokenlist_contains(priv->tokens, value, &present);
+ dom_string_unref(value);
+ if (exc != DOM_NO_ERR) return 0;
+
+ duk_push_boolean(ctx, present);
+
+ return 1;
+%}
+
+method DOMTokenList::toggle()
+%{
+ dom_exception exc;
+ dom_string *value;
+ duk_size_t slen;
+ const char *s = duk_require_lstring(ctx, 0, &slen);
+ bool toggle_set = duk_get_top(ctx) > 1;
+ bool toggle = duk_opt_boolean(ctx, 1, 0);
+ bool present;
+
+ exc = dom_string_create_interned((const uint8_t *)s, slen, &value);
+ if (exc != DOM_NO_ERR) return 0;
+
+ exc = dom_tokenlist_contains(priv->tokens, value, &present);
+ if (exc != DOM_NO_ERR) {
+ dom_string_unref(value);
+ return 0;
+ }
+
+ /* Decision matrix is based on present, toggle_set, and toggle */
+ if (toggle_set) {
+ if (toggle) {
+ exc = dom_tokenlist_add(priv->tokens, value);
+ } else {
+ exc = dom_tokenlist_remove(priv->tokens, value);
+ }
+ } else {
+ if (present) {
+ exc = dom_tokenlist_add(priv->tokens, value);
+ } else {
+ exc = dom_tokenlist_remove(priv->tokens, value);
+ }
+ }
+ dom_string_unref(value);
+
+ return 0;
+%} \ No newline at end of file
diff --git a/content/handlers/javascript/duktape/Element.bnd b/content/handlers/javascript/duktape/Element.bnd
index a965a6ceb..677a9578e 100644
--- a/content/handlers/javascript/duktape/Element.bnd
+++ b/content/handlers/javascript/duktape/Element.bnd
@@ -392,6 +392,27 @@ setter Element::className ()
return 0;
%}
+getter Element::classList ()
+%{
+ dom_exception exc;
+ dom_tokenlist *tokens;
+
+ exc = dom_tokenlist_create((dom_element *)priv->parent.node, corestring_dom_class, &tokens);
+ if (exc != DOM_NO_ERR) return 0; /* Coerced to undefined */
+
+ /* Create a settable tokenlist - While the IDL says this isn't settable, all browsers
+ * seem to make it settable, so we'll permit it too
+ */
+ duk_push_pointer(ctx, tokens);
+ if (dukky_create_object(ctx, PROTO_NAME(DOMSETTABLETOKENLIST), 1) != DUK_EXEC_SUCCESS) {
+ dom_tokenlist_unref(tokens);
+ NSLOG(dukky, DEBUG, "Unable to create DOMSettableTokenList object");
+ return 0; /* Coerced to undefined */
+ }
+ dom_tokenlist_unref(tokens);
+ return 1;
+%}
+
getter Element::innerHTML()
%{
duk_push_lstring(ctx, "", 0);
diff --git a/content/handlers/javascript/duktape/netsurf.bnd b/content/handlers/javascript/duktape/netsurf.bnd
index 651c2fdfa..483f3471f 100644
--- a/content/handlers/javascript/duktape/netsurf.bnd
+++ b/content/handlers/javascript/duktape/netsurf.bnd
@@ -60,6 +60,8 @@ struct dom_html_br_element;
#include "Document.bnd"
#include "Node.bnd"
#include "NodeList.bnd"
+#include "DOMTokenList.bnd"
+#include "DOMSettableTokenList.bnd"
#include "NamedNodeMap.bnd"
#include "Element.bnd"
#include "HTMLCollection.bnd"
diff --git a/content/handlers/javascript/duktape/polyfill.js b/content/handlers/javascript/duktape/polyfill.js
index 5f0215618..6c85ce1a0 100644
--- a/content/handlers/javascript/duktape/polyfill.js
+++ b/content/handlers/javascript/duktape/polyfill.js
@@ -83,3 +83,21 @@ if (!Array.from) {
};
}());
}
+
+// DOMTokenList formatter, in theory we can remove this if we do the stringifier IDL support
+
+DOMTokenList.prototype.toString = function () {
+ if (this.length == 0) {
+ return "";
+ }
+
+ var ret = this.item(0);
+ for (var index = 1; index < this.length; index++) {
+ ret = ret + " " + this.item(index);
+ }
+
+ return ret;
+}
+
+// Inherit the same toString for settable lists
+DOMSettableTokenList.prototype.toString = DOMTokenList.prototype.toString; \ No newline at end of file
diff --git a/test/js/class-list.html b/test/js/class-list.html
new file mode 100644
index 000000000..4c73283e5
--- /dev/null
+++ b/test/js/class-list.html
@@ -0,0 +1,29 @@
+<html>
+ <head>
+ <title>Class List (and other token lists?)</title>
+ <style>
+ .bad { background-color: red; }
+ .ok { background-color: green; }
+ </style>
+ </head>
+ <body>
+ <h1>This is a set of demonstrators for the token list Element.classList</h1>
+ <h2>This first is taken from the MDN for DOMTokenList</h2>
+ <span id="demo1" class=" d d e f bad"></span>
+ <script>
+ var span = document.getElementById("demo1");
+ var classes = span.classList;
+ classes.add("x", "d", "g");
+ classes.remove("e", "g");
+ classes.toggle("d"); // Toggles d off
+ classes.toggle("q", false); // Forces q off (won't be present)
+ classes.toggle("d"); // Toggles d on
+ classes.toggle("d", true); // Forces d on (won't toggle it off again)
+ if (classes.contains("d")) {
+ classes.add("ok")
+ classes.remove("bad")
+ span.textContent = "span classList is \"" + classes + '"';
+ }
+ </script>
+ </body>
+</html>
diff --git a/test/js/index.html b/test/js/index.html
index 032946726..6d2c6541e 100644
--- a/test/js/index.html
+++ b/test/js/index.html
@@ -104,6 +104,7 @@
<li><a href="assorted-log-doc-write.html">console.log and document.write</a></li>
<li><a href="wikipedia-lcm.html">Example from wikipedia</a></li>
<li><a href="verify-instanceofness.html">Check instanceof behaviour</a></li>
+<li><a href="class-list.html">Class list (and other token lists?)</a></li>
<li><a href="mandelbrot.html">Canvas/ImageData Mandelbrot ploter</a></li>
<li><a href="life.html">Game of Life</a></li>
</ul>