Gitweb links:
...log
http://git.netsurf-browser.org/libdom.git/shortlog/ad4cdc900f197c0f373615...
...commit
http://git.netsurf-browser.org/libdom.git/commit/ad4cdc900f197c0f373615d4...
...tree
http://git.netsurf-browser.org/libdom.git/tree/ad4cdc900f197c0f373615d454...
The branch, master has been updated
via ad4cdc900f197c0f373615d454275f38a9c4d181 (commit)
via 14f1b4abd5f395555e8d96e18c5db844bff17fde (commit)
from 2e61b186ea44241fd8adfc626802f01f2dfbffed (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
-----------------------------------------------------------------------
Summary of changes:
.clang-format | 120 +++++
Makefile | 2 +-
include/dom/core/tokenlist.h | 43 ++
include/dom/dom.h | 1 +
src/core/Makefile | 2 +-
src/core/tokenlist.c | 547 ++++++++++++++++++++
.../dom/core/entity_ref.h => src/core/tokenlist.h | 11 +-
7 files changed, 721 insertions(+), 5 deletions(-)
create mode 100644 .clang-format
create mode 100644 include/dom/core/tokenlist.h
create mode 100644 src/core/tokenlist.c
copy include/dom/core/entity_ref.h => src/core/tokenlist.h (55%)
diff --git a/.clang-format b/.clang-format
new file mode 100644
index 0000000..75df82a
--- /dev/null
+++ b/.clang-format
@@ -0,0 +1,120 @@
+---
+Language: Cpp
+AccessModifierOffset: -2
+AlignAfterOpenBracket: Align
+AlignConsecutiveAssignments: false
+AlignConsecutiveDeclarations: false
+AlignEscapedNewlines: Right
+AlignOperands: true
+AlignTrailingComments: false
+AllowAllParametersOfDeclarationOnNextLine: false
+AllowShortBlocksOnASingleLine: false
+AllowShortCaseLabelsOnASingleLine: false
+AllowShortFunctionsOnASingleLine: None
+AllowShortIfStatementsOnASingleLine: false
+AllowShortLoopsOnASingleLine: false
+AlwaysBreakAfterReturnType: None
+AlwaysBreakBeforeMultilineStrings: false
+AlwaysBreakTemplateDeclarations: MultiLine
+BinPackArguments: false
+BinPackParameters: false
+BraceWrapping:
+ AfterClass: true
+ AfterControlStatement: false
+ AfterEnum: false
+ AfterFunction: true
+ AfterNamespace: true
+ AfterObjCDeclaration: false
+ AfterStruct: false
+ AfterUnion: false
+ AfterExternBlock: false
+ BeforeCatch: false
+ BeforeElse: false
+ IndentBraces: false
+ SplitEmptyFunction: true
+ SplitEmptyRecord: true
+ SplitEmptyNamespace: true
+BreakBeforeBinaryOperators: None
+BreakBeforeBraces: Linux
+BreakBeforeInheritanceComma: false
+BreakInheritanceList: BeforeColon
+BreakBeforeTernaryOperators: true
+BreakConstructorInitializersBeforeComma: false
+BreakConstructorInitializers: BeforeColon
+BreakAfterJavaFieldAnnotations: false
+BreakStringLiterals: false
+ColumnLimit: 80
+CommentPragmas: '^ IWYU pragma:'
+CompactNamespaces: false
+ConstructorInitializerAllOnOneLineOrOnePerLine: false
+ConstructorInitializerIndentWidth: 8
+ContinuationIndentWidth: 8
+Cpp11BracedListStyle: true
+DerivePointerAlignment: false
+DisableFormat: false
+ExperimentalAutoDetectBinPacking: false
+FixNamespaceComments: true
+ForEachMacros:
+ - foreach
+ - Q_FOREACH
+ - BOOST_FOREACH
+IncludeBlocks: Preserve
+IncludeCategories:
+ - Regex: '^(<.*/)'
+ Priority: 3
+ - Regex: '^(<(nsutils)/)'
+ Priority: 2
+ - Regex: '"utils/'
+ Priority: 4
+ - Regex: '"netsurf/'
+ Priority: 5
+ - Regex: '.*'
+ Priority: 6
+IncludeIsMainRegex: '(Test)?$'
+IndentCaseLabels: false
+IndentPPDirectives: None
+IndentWidth: 8
+IndentWrappedFunctionNames: false
+JavaScriptQuotes: Leave
+JavaScriptWrapImports: true
+KeepEmptyLinesAtTheStartOfBlocks: true
+MacroBlockBegin: ''
+MacroBlockEnd: ''
+MaxEmptyLinesToKeep: 2
+NamespaceIndentation: None
+ObjCBinPackProtocolList: Auto
+ObjCBlockIndentWidth: 2
+ObjCSpaceAfterProperty: false
+ObjCSpaceBeforeProtocolList: true
+PenaltyBreakAssignment: 100
+PenaltyBreakBeforeFirstCallParameter: 50
+PenaltyBreakComment: 300
+PenaltyBreakFirstLessLess: 120
+PenaltyBreakString: 1000
+PenaltyBreakTemplateDeclaration: 10
+PenaltyExcessCharacter: 1000000
+PenaltyReturnTypeOnItsOwnLine: 19
+PointerAlignment: Right
+ReflowComments: true
+SortIncludes: false
+SortUsingDeclarations: true
+SpaceAfterCStyleCast: false
+SpaceAfterTemplateKeyword: true
+SpaceBeforeAssignmentOperators: true
+SpaceBeforeCpp11BracedList: false
+SpaceBeforeCtorInitializerColon: true
+SpaceBeforeInheritanceColon: true
+SpaceBeforeParens: ControlStatements
+SpaceBeforeRangeBasedForLoopColon: true
+SpaceInEmptyParentheses: false
+SpacesBeforeTrailingComments: 1
+SpacesInAngles: false
+SpacesInContainerLiterals: true
+SpacesInCStyleCastParentheses: false
+SpacesInParentheses: false
+SpacesInSquareBrackets: false
+Standard: Cpp11
+TabWidth: 8
+UseTab: Always
+...
+
diff --git a/Makefile b/Makefile
index 8d9df61..a539ff7 100644
--- a/Makefile
+++ b/Makefile
@@ -69,7 +69,7 @@ INSTALL_ITEMS := $(INSTALL_ITEMS) $(I):$(Is)/entity_ref.h
INSTALL_ITEMS := $(INSTALL_ITEMS) $(I):$(Is)/element.h;$(Is)/exceptions.h
INSTALL_ITEMS := $(INSTALL_ITEMS) $(I):$(Is)/implementation.h
INSTALL_ITEMS := $(INSTALL_ITEMS) $(I):$(Is)/namednodemap.h;$(Is)/node.h
-INSTALL_ITEMS := $(INSTALL_ITEMS) $(I):$(Is)/nodelist.h;$(Is)/string.h
+INSTALL_ITEMS := $(INSTALL_ITEMS) $(I):$(Is)/nodelist.h;$(Is)/tokenlist.h;$(Is)/string.h
INSTALL_ITEMS := $(INSTALL_ITEMS) $(I):$(Is)/pi.h
INSTALL_ITEMS := $(INSTALL_ITEMS) $(I):$(Is)/text.h;$(Is)/typeinfo.h
diff --git a/include/dom/core/tokenlist.h b/include/dom/core/tokenlist.h
new file mode 100644
index 0000000..718d3a5
--- /dev/null
+++ b/include/dom/core/tokenlist.h
@@ -0,0 +1,43 @@
+/*
+ * This file is part of libdom.
+ * Licensed under the MIT License,
+ *
http://www.opensource.org/licenses/mit-license.php
+ * Copyright 2022 Daniel Silverstone <dsilvers(a)netsurf-browser.org>
+ */
+
+#ifndef dom_core_tokenlist_h_
+#define dom_core_tokenlist_h_
+
+#include <dom/core/exceptions.h>
+
+struct dom_element;
+struct dom_string;
+
+typedef struct dom_tokenlist dom_tokenlist;
+
+void dom_tokenlist_ref(struct dom_tokenlist *list);
+void dom_tokenlist_unref(struct dom_tokenlist *list);
+
+dom_exception dom_tokenlist_create(struct dom_element *ele, struct dom_string *attr,
dom_tokenlist **list);
+
+dom_exception dom_tokenlist_get_length(struct dom_tokenlist *list,
+ uint32_t *length);
+dom_exception _dom_tokenlist_item(struct dom_tokenlist *list,
+ uint32_t index, struct dom_string **value);
+
+#define dom_tokenlist_item(l, i, n) _dom_tokenlist_item((dom_tokenlist *) (l), \
+ (uint32_t) (i), (struct dom_string **) (n))
+
+dom_exception dom_tokenlist_get_value(struct dom_tokenlist *list,
+ struct dom_string **value);
+
+dom_exception dom_tokenlist_set_value(struct dom_tokenlist *list,
+ struct dom_string *value);
+
+dom_exception dom_tokenlist_contains(struct dom_tokenlist *list, struct dom_string
*value, bool *contains);
+
+dom_exception dom_tokenlist_add(struct dom_tokenlist *list, struct dom_string *value);
+
+dom_exception dom_tokenlist_remove(struct dom_tokenlist *list, struct dom_string
*value);
+
+#endif
diff --git a/include/dom/dom.h b/include/dom/dom.h
index c10e5a6..00bf3d9 100644
--- a/include/dom/dom.h
+++ b/include/dom/dom.h
@@ -32,6 +32,7 @@
#include <dom/core/doc_fragment.h>
#include <dom/core/entity_ref.h>
#include <dom/core/nodelist.h>
+#include <dom/core/tokenlist.h>
#include <dom/core/string.h>
#include <dom/core/text.h>
#include <dom/core/pi.h>
diff --git a/src/core/Makefile b/src/core/Makefile
index 41fd51f..5d9c969 100644
--- a/src/core/Makefile
+++ b/src/core/Makefile
@@ -6,6 +6,6 @@ DIR_SOURCES := \
text.c typeinfo.c comment.c \
namednodemap.c nodelist.c \
cdatasection.c document_type.c entity_ref.c pi.c \
- doc_fragment.c document.c
+ doc_fragment.c document.c tokenlist.c
include $(NSBUILD)/Makefile.subdir
diff --git a/src/core/tokenlist.c b/src/core/tokenlist.c
new file mode 100644
index 0000000..c227b31
--- /dev/null
+++ b/src/core/tokenlist.c
@@ -0,0 +1,547 @@
+/*
+ * This file is part of libdom.
+ * Licensed under the MIT License,
+ *
http://www.opensource.org/licenses/mit-license.php
+ * Copyright 2022 Daniel Silverstone <dsilvers(a)digital-scurf.org>
+ */
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <dom/core/element.h>
+#include <dom/core/nodelist.h>
+#include <dom/core/tokenlist.h>
+#include <dom/core/string.h>
+#include <dom/events/event.h>
+#include <dom/events/event_target.h>
+#include <dom/events/event_listener.h>
+#include <dom/events/mutation_event.h>
+
+#include "core/element.h"
+#include "core/document.h"
+
+#include "utils/utils.h"
+
+#define DOM_TOKENLIST_GROW_INCREMENT 4
+
+struct dom_tokenlist {
+ uint32_t refcnt;
+ dom_element *ele;
+ dom_string *attr;
+ dom_event_listener *listener;
+ dom_string *last_set;
+ bool needs_parse;
+ /* Parsed content, for optimal access */
+ dom_string **entries;
+ uint32_t len;
+ uint32_t alloc;
+};
+
+/* Handle a DOMAttrModified event which might be to do with our attribute */
+
+static void _dom_tokenlist_handle_attrmodified(dom_event *evt, void *pw)
+{
+ dom_mutation_event *mutevt = (dom_mutation_event *)evt;
+ dom_tokenlist *list = (dom_tokenlist *)pw;
+ dom_exception exc;
+ dom_string *value;
+
+ {
+ dom_node *target;
+ exc = dom_event_get_target(mutevt, &target);
+ if (exc != DOM_NO_ERR)
+ return;
+ dom_node_unref(target);
+ if (target != (dom_node *)list->ele)
+ return;
+ }
+
+ {
+ dom_string *attr;
+ exc = dom_mutation_event_get_attr_name(mutevt, &attr);
+ if (exc != DOM_NO_ERR)
+ return;
+ if (!dom_string_isequal(attr, list->attr)) {
+ dom_string_unref(attr);
+ return;
+ }
+ dom_string_unref(attr);
+ }
+
+ /* At this point we know that this is a mutation of our attribute on our
+ * node */
+
+ exc = dom_mutation_event_get_new_value(mutevt, &value);
+ if (exc != DOM_NO_ERR)
+ return;
+
+ if (list->last_set != NULL &&
+ dom_string_isequal(list->last_set, value)) {
+ /* We've just seen the mutation event for one of our own set
+ * operations */
+ dom_string_unref(value);
+ return;
+ }
+
+ /* Mark that we need to re-parse the tokenlist on the next request */
+ list->needs_parse = true;
+
+ dom_string_unref(value);
+}
+
+static dom_exception _dom_tokenlist_make_room(dom_tokenlist *list)
+{
+ if (list->len == list->alloc) {
+ uint32_t new_alloc = list->alloc + DOM_TOKENLIST_GROW_INCREMENT;
+ dom_string **new_entries = realloc(
+ list->entries, new_alloc * sizeof(dom_string *));
+ if (new_entries == NULL)
+ return DOM_NO_MEM_ERR;
+ list->alloc = new_alloc;
+ list->entries = new_entries;
+ }
+
+ return DOM_NO_ERR;
+}
+
+static dom_exception _dom_tokenlist_reparse(dom_tokenlist *list)
+{
+ dom_exception exc;
+ dom_string *value;
+ const char *pos;
+ uint32_t remaining, check;
+ uint32_t n_entries = 0;
+ dom_string *temp;
+ bool found;
+
+ if (!list->needs_parse)
+ return DOM_NO_ERR;
+
+ /* Clean down the current entries */
+ while (list->len-- > 0)
+ dom_string_unref(list->entries[list->len]);
+ list->len = 0;
+
+ /* Get the "new" attribute value */
+ exc = dom_element_get_attribute(list->ele, list->attr, &value);
+ if (exc != DOM_NO_ERR)
+ return exc;
+
+ /* If there is no value, we're an empty list and we're done */
+ if (value == NULL) {
+ list->needs_parse = false;
+ return DOM_NO_ERR;
+ }
+
+ /* OK, there's something here to do, so let's do it... */
+
+ /* Count number of entries */
+ for (pos = dom_string_data(value), remaining = dom_string_length(value);
+ remaining > 0;) {
+ if (*pos != ' ') {
+ while (*pos != ' ' && remaining > 0) {
+ remaining--;
+ pos++;
+ }
+ n_entries++;
+ } else {
+ while (*pos == ' ' && remaining > 0) {
+ remaining--;
+ pos++;
+ }
+ }
+ }
+
+ /* If there are no entries (all whitespace) just bail here */
+ if (n_entries == 0) {
+ list->needs_parse = false;
+ dom_string_unref(value);
+ return DOM_NO_ERR;
+ }
+
+ /* If we need more room, reallocate the buffer */
+ if (list->alloc < n_entries) {
+ dom_string **new_alloc = realloc(
+ list->entries, n_entries * sizeof(dom_string *));
+ if (new_alloc == NULL) {
+ dom_string_unref(value);
+ return DOM_NO_MEM_ERR;
+ }
+ list->entries = new_alloc;
+ list->alloc = n_entries;
+ }
+
+ /* And now parse those entries into the buffer */
+ for (pos = dom_string_data(value),
+ remaining = dom_string_length(value),
+ n_entries = 0;
+ remaining > 0;) {
+ if (*pos != ' ') {
+ const char *s = pos;
+ while (*pos != ' ' && remaining > 0) {
+ pos++;
+ remaining--;
+ }
+ exc = dom_string_create_interned((const uint8_t *)s,
+ pos - s,
+ &temp);
+ if (exc != DOM_NO_ERR) {
+ dom_string_unref(value);
+ return exc;
+ }
+ found = false;
+ for (check = 0; check < list->len; check++) {
+ if (dom_string_isequal(temp,
+ list->entries[check])) {
+ found = true;
+ break;
+ }
+ }
+ if (found == true) {
+ dom_string_unref(temp);
+ } else {
+ list->entries[list->len] = temp;
+ list->len++;
+ }
+ } else {
+ while (*pos == ' ' && remaining > 0) {
+ pos++;
+ remaining--;
+ }
+ }
+ }
+
+ dom_string_unref(value);
+ list->needs_parse = false;
+
+ return DOM_NO_ERR;
+}
+
+static dom_exception _dom_tokenlist_reify(dom_tokenlist *list)
+{
+ dom_exception exc;
+ uint32_t nchars = 0, n;
+ char *buffer, *next;
+ dom_string *output;
+
+ if (list->len == 0) {
+ if (list->last_set != NULL) {
+ dom_node_unref(list->last_set);
+ }
+ list->last_set = dom_string_ref(
+ list->ele->base.owner->_memo_empty);
+ return dom_element_set_attribute(list->ele,
+ list->attr,
+ list->last_set);
+ }
+
+ for (n = 0; n < list->len; ++n)
+ nchars += dom_string_length(list->entries[n]);
+
+ buffer = calloc(1, nchars + list->len);
+ if (buffer == NULL)
+ return DOM_NO_MEM_ERR;
+
+ for (next = buffer, n = 0; n < list->len; ++n) {
+ uint32_t slen = dom_string_length(list->entries[n]);
+ memcpy(next, dom_string_data(list->entries[n]), slen);
+ next[slen] = ' ';
+ next += slen + 1;
+ }
+
+ exc = dom_string_create_interned((const uint8_t *)buffer,
+ nchars + list->len - 1,
+ &output);
+ free(buffer);
+ if (exc != DOM_NO_ERR)
+ return exc;
+
+ if (list->last_set != NULL) {
+ dom_string_unref(list->last_set);
+ }
+ list->last_set = output;
+
+ return dom_element_set_attribute(list->ele, list->attr, list->last_set);
+}
+
+/**********************************************************************************/
+
+/**
+ * Create a tokenlist
+ *
+ * \param ele The element which owns the tokenlist attribute
+ * \param attr The name of the attribute we are treating as a tokenlist
+ * \param list The tokenlist output which is set on success
+ * \return DOM_NO_ERR on success, DOM_NO_MEM_ERR on memory exhaustion
+ *
+ * The returned list will already be referenced, so the client need not
+ * do so explicitly. The client must unref the list once finished with it.
+ *
+ * This list will take its own references to ::ele and ::attr
+ */
+dom_exception
+dom_tokenlist_create(dom_element *ele, dom_string *attr, dom_tokenlist **list)
+{
+ dom_tokenlist *l;
+ dom_exception exc;
+
+ l = calloc(1, sizeof(dom_tokenlist));
+ if (l == NULL)
+ return DOM_NO_MEM_ERR;
+
+ l->refcnt = 1;
+ l->ele = (dom_element *)dom_node_ref(ele);
+ l->attr = dom_string_ref(attr);
+ l->needs_parse = true;
+
+ exc = dom_event_listener_create(_dom_tokenlist_handle_attrmodified,
+ l,
+ &l->listener);
+ if (exc != DOM_NO_ERR)
+ goto fail;
+
+ exc = dom_event_target_add_event_listener(
+ ele,
+ ele->base.owner->_memo_domattrmodified,
+ l->listener,
+ false);
+
+ if (exc != DOM_NO_ERR)
+ goto fail;
+
+ *list = l;
+
+ return DOM_NO_ERR;
+
+fail:
+ if (l->listener != NULL)
+ dom_event_listener_unref(l->listener);
+ dom_node_unref(l->ele);
+ dom_string_unref(l->attr);
+ free(l);
+ return exc;
+}
+
+/**
+ * Claim a ref on a tokenlist
+ *
+ * \param list The tokenlist to claim a ref on
+ */
+void dom_tokenlist_ref(dom_tokenlist *list)
+{
+ assert(list != NULL);
+ list->refcnt++;
+}
+
+/**
+ * Release a ref on a tokenlist
+ *
+ * \param list The list to release the reference of
+ *
+ * If you release the last ref, this cleans up the tokenlist
+ */
+void dom_tokenlist_unref(dom_tokenlist *list)
+{
+ assert(list != NULL);
+
+ if (--list->refcnt > 0)
+ return;
+
+ if (list->alloc > 0) {
+ while (list->len-- > 0)
+ dom_string_unref(list->entries[list->len]);
+ free(list->entries);
+ }
+
+ dom_event_target_remove_event_listener(
+ list->ele,
+ list->ele->base.owner->_memo_domattrmodified,
+ list->listener,
+ false);
+
+ dom_event_listener_unref(list->listener);
+
+ if (list->last_set != NULL)
+ dom_string_unref(list->last_set);
+
+ dom_string_unref(list->attr);
+ dom_node_unref(list->ele);
+
+ free(list);
+}
+
+/**
+ * Get the length of the tokenlist
+ *
+ * \param list The list to get the length of
+ * \param length Length of the list outputs here
+ * \return DOM_NO_ERR on success, otherwise the failure code
+ */
+dom_exception dom_tokenlist_get_length(dom_tokenlist *list, uint32_t *length)
+{
+ dom_exception exc;
+ assert(list != NULL);
+
+ exc = _dom_tokenlist_reparse(list);
+ if (exc != DOM_NO_ERR)
+ return exc;
+
+ *length = list->len;
+
+ return DOM_NO_ERR;
+}
+
+/**
+ * Get a particular item from the tokenlist
+ *
+ * \param list The list to retrieve the item from
+ * \param index The index of the item to retrieve
+ * \param value The value of the item returns here
+ * \return DOM_NO_ERR on success, otherwise the failure code
+ */
+dom_exception
+_dom_tokenlist_item(dom_tokenlist *list, uint32_t index, dom_string **value)
+{
+ dom_exception exc;
+ assert(list != NULL);
+
+ exc = _dom_tokenlist_reparse(list);
+ if (exc != DOM_NO_ERR)
+ return exc;
+
+ if (index >= list->len) {
+ *value = NULL;
+ return DOM_NO_ERR;
+ }
+
+ *value = dom_string_ref(list->entries[index]);
+ return DOM_NO_ERR;
+}
+
+/**
+ * Retrieve the value of the tokenlist as a string
+ *
+ * \param list The list to retrieve the value of
+ * \param value The value of the list returns here
+ * \return DOM_NO_ERR on success, otherwise the failure code
+ */
+dom_exception dom_tokenlist_get_value(dom_tokenlist *list, dom_string **value)
+{
+ assert(list != NULL);
+
+ return dom_element_get_attribute(list->ele, list->attr, value);
+}
+
+/**
+ * Set the value of the tokenlist as a string
+ *
+ * \param list The list to set the value of
+ * \param value The value to set
+ * \return DOM_NO_ERR on success, otherwise the failure code
+ *
+ */
+dom_exception dom_tokenlist_set_value(dom_tokenlist *list, dom_string *value)
+{
+ assert(list != NULL);
+
+ return dom_element_set_attribute(list->ele, list->attr, value);
+}
+
+/**
+ * Check if the given value is in the tokenlist
+ *
+ * \param list The list to scan for the given value
+ * \param value The value to look for in the token list
+ * \param contains This will be set based on whether or not the value is present
+ * \return DOM_NO_ERR on success, otherwise the failure code
+ */
+dom_exception
+dom_tokenlist_contains(dom_tokenlist *list, dom_string *value, bool *contains)
+{
+ dom_exception exc;
+ uint32_t n;
+
+ assert(list != NULL);
+
+ exc = _dom_tokenlist_reparse(list);
+ if (exc != DOM_NO_ERR)
+ return exc;
+
+ *contains = false;
+
+ for (n = 0; n < list->len; n++) {
+ if (dom_string_isequal(value, list->entries[n])) {
+ *contains = true;
+ break;
+ }
+ }
+
+ return DOM_NO_ERR;
+}
+
+/**
+ * Add the given value to the tokenlist
+ *
+ * \param list The list to add to
+ * \param value The value to add
+ * \return DOM_NO_ERR on success, otherwise the failure code
+ */
+dom_exception dom_tokenlist_add(dom_tokenlist *list, dom_string *value)
+{
+ dom_exception exc;
+ bool present = false;
+
+ assert(list != NULL);
+
+ exc = dom_tokenlist_contains(list, value, &present);
+ if (exc != DOM_NO_ERR)
+ return exc;
+
+ if (present == true)
+ return DOM_NO_ERR;
+
+ exc = _dom_tokenlist_make_room(list);
+ if (exc != DOM_NO_ERR)
+ return exc;
+
+ list->entries[list->len++] = dom_string_ref(value);
+
+ exc = _dom_tokenlist_reify(list);
+
+ return exc;
+}
+
+/**
+ * Remove the given value from the tokenlist
+ *
+ * \param list The list to remove from
+ * \param value The value to remove
+ * \return DOM_NO_ERR on success, otherwise the failure code
+ */
+dom_exception dom_tokenlist_remove(dom_tokenlist *list, dom_string *value)
+{
+ dom_exception exc;
+ uint32_t n, m;
+
+ assert(list != NULL);
+
+ exc = _dom_tokenlist_reparse(list);
+ if (exc != DOM_NO_ERR)
+ return false;
+
+ for (n = 0; n < list->len; ++n) {
+ if (dom_string_isequal(value, list->entries[n])) {
+ dom_string_unref(list->entries[n]);
+ for (m = n + 1; m < list->len; ++m) {
+ list->entries[m - 1] = list->entries[m];
+ }
+ list->len--;
+ break;
+ }
+ }
+
+ exc = _dom_tokenlist_reify(list);
+
+ return exc;
+}
diff --git a/include/dom/core/entity_ref.h b/src/core/tokenlist.h
similarity index 55%
copy from include/dom/core/entity_ref.h
copy to src/core/tokenlist.h
index 4a1d64e..325d726 100644
--- a/include/dom/core/entity_ref.h
+++ b/src/core/tokenlist.h
@@ -5,9 +5,14 @@
* Copyright 2007 John-Mark Bell <jmb(a)netsurf-browser.org>
*/
-#ifndef dom_core_entityreference_h_
-#define dom_core_entityreference_h_
+#ifndef dom_internal_core_tokenlist_h_
+#define dom_internal_core_tokenlist_h_
-typedef struct dom_entity_reference dom_entity_reference;
+#include <stdbool.h>
+
+#include <dom/core/tokenlist.h>
+
+struct dom_element;
+struct dom_string;
#endif
--
Document Object Model library