/* DOMTokenList binding for browser using duktape and libdom * * Copyright 2015 Vincent Sanders * * 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; %}