From 4d58ed656248d975e0394fbfec66215a45e74dfa Mon Sep 17 00:00:00 2001 From: John-Mark Bell Date: Fri, 9 Nov 2012 23:22:19 +0000 Subject: Port hotlist load/save to libdom. --- desktop/tree_url_node.c | 525 +++++++++++++++++++++++++++--------------------- 1 file changed, 295 insertions(+), 230 deletions(-) (limited to 'desktop/tree_url_node.c') diff --git a/desktop/tree_url_node.c b/desktop/tree_url_node.c index a69a1375e..3bff10272 100644 --- a/desktop/tree_url_node.c +++ b/desktop/tree_url_node.c @@ -24,8 +24,9 @@ #include #include -#include -#include + +#include +#include #include "content/content.h" #include "content/hlcache.h" @@ -33,9 +34,12 @@ #include "desktop/browser.h" #include "desktop/options.h" #include "desktop/tree_url_node.h" +#include "utils/corestrings.h" +#include "utils/domutils.h" #include "utils/log.h" #include "utils/messages.h" #include "utils/url.h" +#include "utils/utf8.h" #include "utils/utils.h" /** Flags for each type of url tree node. */ @@ -461,81 +465,98 @@ node_callback_resp tree_url_node_callback(void *user_data, return NODE_CALLBACK_NOT_HANDLED; } -/** - * Search the children of an xmlNode for an element. - * - * \param node xmlNode to search children of, or 0 - * \param name name of element to find - * \return first child of node which is an element and matches name, or - * 0 if not found or parameter node is 0 - */ -static xmlNode *tree_url_find_xml_element(xmlNode *node, const char *name) -{ - xmlNode *xmlnode; - if (node == NULL) - return NULL; - - for (xmlnode = node->children; - xmlnode && !(xmlnode->type == XML_ELEMENT_NODE && - strcasecmp((const char *) xmlnode->name, name) == 0); - xmlnode = xmlnode->next) - ; +typedef struct { + struct tree *tree; + struct node *directory; + tree_node_user_callback callback; + void *callback_data; + bool last_was_h4; + dom_string *title; +} tree_url_load_ctx; - return xmlnode; -} +static void tree_url_load_directory(dom_node *ul, tree_url_load_ctx *ctx); /** * Parse an entry represented as a li. * - * \param li xmlNode for parsed li + * \param li DOM node for parsed li * \param directory directory to add this entry to */ -static void tree_url_load_entry(xmlNode *li, struct tree *tree, - struct node *directory, tree_node_user_callback callback, - void *callback_data) +static void tree_url_load_entry(dom_node *li, tree_url_load_ctx *ctx) { - char *url1 = NULL; - char *title = NULL; - struct node *entry; - xmlNode *xmlnode; - const struct url_data *data; + dom_node *a; + dom_string *title1; + dom_string *url1; + char *title, *url2; nsurl *url; + const struct url_data *data; + struct node *entry; + dom_exception derror; nserror error; - for (xmlnode = li->children; xmlnode; xmlnode = xmlnode->next) { - /* The li must contain an "a" element */ - if (xmlnode->type == XML_ELEMENT_NODE && - strcasecmp((const char *)xmlnode->name, "a") == 0) { - url1 = (char *)xmlGetProp(xmlnode, - (const xmlChar *) "href"); - title = (char *)xmlNodeGetContent(xmlnode); - } + /* The li must contain an "a" element */ + a = find_first_named_dom_element(li, corestring_lwc_a); + if (a == NULL) { + warn_user("TreeLoadError", "(Missing in
  • )"); + return; + } + + derror = dom_node_get_text_content(a, &title1); + if (derror != DOM_NO_ERR || title1 == NULL) { + warn_user("TreeLoadError", "(No title)"); + dom_node_unref(a); + return; } - if ((url1 == NULL) || (title == NULL)) { - warn_user("TreeLoadError", "(Missing in
  • or " - "memory exhausted.)"); + derror = dom_element_get_attribute(a, corestring_dom_href, &url1); + if (derror != DOM_NO_ERR || url1 == NULL) { + warn_user("TreeLoadError", "(No URL)"); + dom_string_unref(title1); + dom_node_unref(a); return; } + title = strndup(dom_string_data(title1), + dom_string_byte_length(title1)); + if (title == NULL) { + warn_user("NoMemory", NULL); + dom_string_unref(url1); + dom_string_unref(title1); + dom_node_unref(a); + return; + } + + dom_string_unref(title1); + /* We're loading external input. * This may be garbage, so attempt to normalise via nsurl */ - error = nsurl_create(url1, &url); + url2 = strndup(dom_string_data(url1), dom_string_byte_length(url1)); + if (url2 == NULL) { + warn_user("NoMemory", NULL); + free(title); + dom_string_unref(url1); + dom_node_unref(a); + return; + } + + dom_string_unref(url1); + + error = nsurl_create(url2, &url); + + free(url2); + if (error != NSERROR_OK) { - LOG(("Failed normalising '%s'", url1)); + LOG(("Failed normalising '%s'", url2)); warn_user("NoMemory", NULL); - xmlFree(url1); - xmlFree(title); + free(title); + dom_node_unref(a); return; } - /* No longer need this */ - xmlFree(url1); - data = urldb_get_url_data(url); if (data == NULL) { /* No entry in database, so add one */ @@ -544,8 +565,9 @@ static void tree_url_load_entry(xmlNode *li, struct tree *tree, data = urldb_get_url_data(url); } if (data == NULL) { - xmlFree(title); nsurl_unref(url); + free(title); + dom_node_unref(a); return; } @@ -556,106 +578,139 @@ static void tree_url_load_entry(xmlNode *li, struct tree *tree, /* Force the title in the hotlist */ urldb_set_url_title(url, title); - entry = tree_create_URL_node(tree, directory, url, title, - callback, callback_data); + entry = tree_create_URL_node(ctx->tree, ctx->directory, url, title, + ctx->callback, ctx->callback_data); if (entry == NULL) { /** \todo why isn't this fatal? */ warn_user("NoMemory", 0); } else { - tree_update_URL_node(tree, entry, url, data); + tree_update_URL_node(ctx->tree, entry, url, data); } - - xmlFree(title); nsurl_unref(url); + free(title); + dom_node_unref(a); } -/** - * Parse a directory represented as a ul. - * - * \param ul xmlNode for parsed ul - * \param directory directory to add this directory to - */ -static void tree_url_load_directory(xmlNode *ul, struct tree *tree, - struct node *directory, tree_node_user_callback callback, - void *callback_data) +static bool tree_url_load_directory_cb(dom_node *node, void *ctx) { - char *title; - struct node *dir; - xmlNode *xmlnode; - xmlChar *id; + tree_url_load_ctx *tctx = ctx; + dom_string *name; + dom_exception error; - assert(ul != NULL); - assert(directory != NULL); + /* The ul may contain entries as a li, or directories as + * an h4 followed by a ul. Non-element nodes may be present + * (eg. text, comments), and are ignored. */ - for (xmlnode = ul->children; xmlnode; xmlnode = xmlnode->next) { - /* The ul may contain entries as a li, or directories as - * an h4 followed by a ul. Non-element nodes may be present - * (eg. text, comments), and are ignored. */ + error = dom_node_get_node_name(node, &name); + if (error != DOM_NO_ERR || name == NULL) + return false; - if (xmlnode->type != XML_ELEMENT_NODE) - continue; + if (dom_string_caseless_lwc_isequal(name, corestring_lwc_li)) { + /* entry */ + tree_url_load_entry(node, tctx); + tctx->last_was_h4 = false; + } else if (dom_string_caseless_lwc_isequal(name, corestring_lwc_h4)) { + /* directory (a) */ + dom_string *title; + + error = dom_node_get_text_content(node, &title); + if (error != DOM_NO_ERR || title == NULL) { + warn_user("TreeLoadError", "(Empty

    " + "or memory exhausted.)"); + dom_string_unref(name); + return false; + } - if (strcasecmp((const char *)xmlnode->name, "li") == 0) { - /* entry */ - tree_url_load_entry(xmlnode, tree, directory, callback, - callback_data); + if (tctx->title != NULL) + dom_string_unref(tctx->title); + tctx->title = title; + tctx->last_was_h4 = true; + } else if (tctx->last_was_h4 && dom_string_caseless_lwc_isequal(name, + corestring_lwc_ul)) { + /* directory (b) */ + dom_string *id; + bool dir_is_default; + struct node *dir; + char *title; + tree_url_load_ctx new_ctx; + + error = dom_element_get_attribute(node, corestring_dom_id, &id); + if (error != DOM_NO_ERR) { + dom_string_unref(name); + return false; + } - } else if (strcasecmp((const char *)xmlnode->name, "h4") == 0) { - /* directory */ - bool dir_is_default = false; - title = (char *) xmlNodeGetContent(xmlnode ); - if (!title) { - warn_user("TreeLoadError", "(Empty

    " - "or memory exhausted.)"); - return; - } + if (id != NULL) { + dir_is_default = dom_string_caseless_lwc_isequal(id, + corestring_lwc_default); - for (xmlnode = xmlnode->next; - xmlnode && xmlnode->type != XML_ELEMENT_NODE; - xmlnode = xmlnode->next) - ; - if ((xmlnode == NULL) || - strcasecmp((const char *)xmlnode->name, "ul") != 0) { - /* next element isn't expected ul */ - free(title); - warn_user("TreeLoadError", "(Expected " - "