Move dom walker to utils/libdom.{c|h}. Add a few HTML elements to core strings.

This commit is contained in:
Michael Drake 2012-10-12 16:21:29 +01:00
parent e7e3329767
commit 4fccdf18f3
6 changed files with 228 additions and 109 deletions

View File

@ -17,9 +17,9 @@ S_RENDER := box.c box_construct.c box_normalise.c \
html_forms.c imagemap.c layout.c list.c search.c table.c \
textinput.c textplain.c
S_UTILS := base64.c corestrings.c filename.c hashtable.c locale.c \
messages.c nsurl.c talloc.c url.c utf8.c utils.c useragent.c \
filepath.c log.c
S_UTILS := base64.c corestrings.c filename.c filepath.c hashtable.c \
libdom.c locale.c log.c messages.c nsurl.c talloc.c url.c \
utf8.c utils.c useragent.c
S_HTTP := challenge.c generics.c primitives.c parameter.c \
content-disposition.c content-type.c www-authenticate.c

View File

@ -45,6 +45,7 @@
#include "render/search.h"
#include "utils/corestrings.h"
#include "utils/http.h"
#include "utils/libdom.h"
#include "utils/log.h"
#include "utils/messages.h"
#include "utils/schedule.h"
@ -1626,111 +1627,6 @@ no_memory:
}
/* depth-first walk the dom calling callback for each element
*
* @param root the dom node to use as the root of the tree walk
* @return true if all nodes were examined, false if the callback terminated
* the walk early.
*/
static bool
html_treewalk_dom(dom_node *root,
bool (*callback)(dom_node *node, dom_string *name, void *ctx),
void *ctx)
{
dom_node *node;
bool result = true;;
node = dom_node_ref(root); /* tree root */
while (node != NULL) {
dom_node *next = NULL;
dom_node_type type;
dom_string *name;
dom_exception exc;
exc = dom_node_get_first_child(node, &next);
if (exc != DOM_NO_ERR) {
dom_node_unref(node);
break;
}
if (next != NULL) { /* 1. children */
dom_node_unref(node);
node = next;
} else {
exc = dom_node_get_next_sibling(node, &next);
if (exc != DOM_NO_ERR) {
dom_node_unref(node);
break;
}
if (next != NULL) { /* 2. siblings */
dom_node_unref(node);
node = next;
} else { /* 3. ancestor siblings */
while (node != NULL) {
exc = dom_node_get_next_sibling(node,
&next);
if (exc != DOM_NO_ERR) {
dom_node_unref(node);
node = NULL;
break;
}
if (next != NULL) {
dom_node_unref(next);
break;
}
exc = dom_node_get_parent_node(node,
&next);
if (exc != DOM_NO_ERR) {
dom_node_unref(node);
node = NULL;
break;
}
dom_node_unref(node);
node = next;
}
if (node == NULL)
break;
exc = dom_node_get_next_sibling(node, &next);
if (exc != DOM_NO_ERR) {
dom_node_unref(node);
break;
}
dom_node_unref(node);
node = next;
}
}
assert(node != NULL);
exc = dom_node_get_node_type(node, &type);
if ((exc != DOM_NO_ERR) || (type != DOM_ELEMENT_NODE))
continue;
exc = dom_node_get_node_name(node, &name);
if (exc != DOM_NO_ERR)
continue;
result = callback(node, name, ctx);
dom_string_unref(name);
if (result == false) {
break; /* callback caused early termination */
}
}
return result;
}
struct find_stylesheet_ctx {
unsigned int count;
@ -1957,7 +1853,7 @@ static bool html_find_stylesheets(html_content *c, dom_node *html)
LOG(("%d fetches active", c->base.active));
result = html_treewalk_dom(html, html_process_stylesheet, &ctx);
result = libdom_treewalk(html, html_process_stylesheet, &ctx);
assert(c->stylesheet_count == ctx.count);

View File

@ -65,6 +65,7 @@ lwc_string *corestring_lwc_img;
lwc_string *corestring_lwc_input;
lwc_string *corestring_lwc_justify;
lwc_string *corestring_lwc_left;
lwc_string *corestring_lwc_li;
lwc_string *corestring_lwc_link;
lwc_string *corestring_lwc_meta;
lwc_string *corestring_lwc_middle;
@ -103,6 +104,7 @@ lwc_string *corestring_lwc_thead;
lwc_string *corestring_lwc_title;
lwc_string *corestring_lwc_top;
lwc_string *corestring_lwc_tr;
lwc_string *corestring_lwc_ul;
lwc_string *corestring_lwc_url;
lwc_string *corestring_lwc_yes;
lwc_string *corestring_lwc__blank;
@ -206,6 +208,7 @@ void corestrings_fini(void)
CSS_LWC_STRING_UNREF(input);
CSS_LWC_STRING_UNREF(justify);
CSS_LWC_STRING_UNREF(left);
CSS_LWC_STRING_UNREF(li);
CSS_LWC_STRING_UNREF(link);
CSS_LWC_STRING_UNREF(meta);
CSS_LWC_STRING_UNREF(middle);
@ -244,6 +247,7 @@ void corestrings_fini(void)
CSS_LWC_STRING_UNREF(title);
CSS_LWC_STRING_UNREF(top);
CSS_LWC_STRING_UNREF(tr);
CSS_LWC_STRING_UNREF(ul);
CSS_LWC_STRING_UNREF(url);
CSS_LWC_STRING_UNREF(yes);
CSS_LWC_STRING_UNREF(_blank);
@ -367,6 +371,7 @@ nserror corestrings_init(void)
CSS_LWC_STRING_INTERN(input);
CSS_LWC_STRING_INTERN(justify);
CSS_LWC_STRING_INTERN(left);
CSS_LWC_STRING_INTERN(li);
CSS_LWC_STRING_INTERN(link);
CSS_LWC_STRING_INTERN(meta);
CSS_LWC_STRING_INTERN(middle);
@ -403,6 +408,7 @@ nserror corestrings_init(void)
CSS_LWC_STRING_INTERN(title);
CSS_LWC_STRING_INTERN(top);
CSS_LWC_STRING_INTERN(tr);
CSS_LWC_STRING_INTERN(ul);
CSS_LWC_STRING_INTERN(url);
CSS_LWC_STRING_INTERN(yes);
CSS_LWC_STRING_INTERN(_blank);

View File

@ -69,6 +69,7 @@ extern lwc_string *corestring_lwc_img;
extern lwc_string *corestring_lwc_input;
extern lwc_string *corestring_lwc_justify;
extern lwc_string *corestring_lwc_left;
extern lwc_string *corestring_lwc_li;
extern lwc_string *corestring_lwc_link;
extern lwc_string *corestring_lwc_meta;
extern lwc_string *corestring_lwc_middle;
@ -107,6 +108,7 @@ extern lwc_string *corestring_lwc_thead;
extern lwc_string *corestring_lwc_title;
extern lwc_string *corestring_lwc_top;
extern lwc_string *corestring_lwc_tr;
extern lwc_string *corestring_lwc_ul;
extern lwc_string *corestring_lwc_url;
extern lwc_string *corestring_lwc_yes;
extern lwc_string *corestring_lwc__blank;

164
utils/libdom.c Normal file
View File

@ -0,0 +1,164 @@
/*
* Copyright 2012 Vincent Sanders <vince@netsurf-browser.org>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
* NetSurf is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/** \file
* libdom utilities (implementation).
*/
#include <assert.h>
#include "utils/libdom.h"
/* exported interface documented in libdom.h */
bool libdom_treewalk(dom_node *root,
bool (*callback)(dom_node *node, dom_string *name, void *ctx),
void *ctx)
{
dom_node *node;
bool result = true;;
node = dom_node_ref(root); /* tree root */
while (node != NULL) {
dom_node *next = NULL;
dom_node_type type;
dom_string *name;
dom_exception exc;
exc = dom_node_get_first_child(node, &next);
if (exc != DOM_NO_ERR) {
dom_node_unref(node);
break;
}
if (next != NULL) { /* 1. children */
dom_node_unref(node);
node = next;
} else {
exc = dom_node_get_next_sibling(node, &next);
if (exc != DOM_NO_ERR) {
dom_node_unref(node);
break;
}
if (next != NULL) { /* 2. siblings */
dom_node_unref(node);
node = next;
} else { /* 3. ancestor siblings */
while (node != NULL) {
exc = dom_node_get_next_sibling(node,
&next);
if (exc != DOM_NO_ERR) {
dom_node_unref(node);
node = NULL;
break;
}
if (next != NULL) {
dom_node_unref(next);
break;
}
exc = dom_node_get_parent_node(node,
&next);
if (exc != DOM_NO_ERR) {
dom_node_unref(node);
node = NULL;
break;
}
dom_node_unref(node);
node = next;
}
if (node == NULL)
break;
exc = dom_node_get_next_sibling(node, &next);
if (exc != DOM_NO_ERR) {
dom_node_unref(node);
break;
}
dom_node_unref(node);
node = next;
}
}
assert(node != NULL);
exc = dom_node_get_node_type(node, &type);
if ((exc != DOM_NO_ERR) || (type != DOM_ELEMENT_NODE))
continue;
exc = dom_node_get_node_name(node, &name);
if (exc != DOM_NO_ERR)
continue;
result = callback(node, name, ctx);
dom_string_unref(name);
if (result == false) {
break; /* callback caused early termination */
}
}
return result;
}
/* libdom_treewalk context for libdom_find_element */
struct find_element_ctx {
lwc_string *search;
dom_node *found;
};
/* libdom_treewalk callback for libdom_find_element */
static bool libdom_find_element_callback(dom_node *node, dom_string *name,
void *ctx)
{
struct find_element_ctx *data = ctx;
if (dom_string_caseless_lwc_isequal(name, data->search)) {
/* Found element */
data->found = node;
return false; /* Discontinue search */
}
return true; /* Continue search */
}
/* exported interface documented in libdom.h */
dom_node *libdom_find_element(dom_node *node, lwc_string *element_name)
{
struct find_element_ctx data;
assert(element_name != NULL);
if (node == NULL)
return NULL;
data.search = element_name;
data.found = NULL;
libdom_treewalk(node, libdom_find_element_callback, &data);
return data.found;
}

51
utils/libdom.h Normal file
View File

@ -0,0 +1,51 @@
/*
* Copyright 2011 John-Mark Bell <jmb@netsurf-browser.org>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
* NetSurf is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/** \file
* libdom utilities (implementation).
*/
#ifndef NETSURF_UTILS_LIBDOM_H_
#define NETSURF_UTILS_LIBDOM_H_
#include <stdbool.h>
#include <dom/dom.h>
/* depth-first walk the dom calling callback for each element
*
* \param root the dom node to use as the root of the tree walk
* \return true if all nodes were examined, false if the callback terminated
* the walk early.
*/
bool libdom_treewalk(dom_node *root,
bool (*callback)(dom_node *node, dom_string *name, void *ctx),
void *ctx);
/**
* Search the descendants of a node for an element.
*
* \param node dom_node to search children of, or NULL
* \param element_name name of element to find
* \return first child of node which is an element and matches name, or
* NULL if not found or parameter node is NULL
*/
dom_node *libdom_find_element(dom_node *node, lwc_string *element_name);
#endif