mirror of
https://github.com/netsurf-browser/netsurf
synced 2024-11-24 15:29:45 +03:00
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>
This commit is contained in:
parent
764fca4f3a
commit
7bcd4fd246
44
content/handlers/javascript/duktape/DOMSettableTokenList.bnd
Normal file
44
content/handlers/javascript/duktape/DOMSettableTokenList.bnd
Normal file
@ -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;
|
||||
%}
|
163
content/handlers/javascript/duktape/DOMTokenList.bnd
Normal file
163
content/handlers/javascript/duktape/DOMTokenList.bnd
Normal file
@ -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;
|
||||
%}
|
@ -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);
|
||||
|
@ -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"
|
||||
|
@ -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;
|
29
test/js/class-list.html
Normal file
29
test/js/class-list.html
Normal file
@ -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>
|
@ -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>
|
||||
|
Loading…
Reference in New Issue
Block a user