/** * Callback to determine if a node is the root node of the document. * * \param pw HTML document * \param node DOM node * \param match Pointer to location to receive result * \return CSS_OK. * * \post \a match will contain true if the node matches and false otherwise. */ css_error node_is_root(void *pw, void *node, bool *match) { dom_node *n = node; dom_node *parent; dom_node_type type; dom_exception err; err = dom_node_get_parent_node(n, &parent); if (err != DOM_NO_ERR) { return CSS_NOMEM; } if (parent != NULL) { err = dom_node_get_node_type(parent, &type); dom_node_unref(parent); if (err != DOM_NO_ERR) return CSS_NOMEM; if (type != DOM_DOCUMENT_NODE) { *match = false; return CSS_OK; } } *match = true; return CSS_OK; }
static hubbub_error get_parent(void *parser, void *node, bool element_only, void **result) { dom_hubbub_parser *dom_parser = (dom_hubbub_parser *) parser; dom_exception err; struct dom_node *parent; dom_node_type type = DOM_NODE_TYPE_COUNT; err = dom_node_get_parent_node((struct dom_node *) node, &parent); if (err != DOM_NO_ERR) { dom_parser->msg(DOM_MSG_CRITICAL, dom_parser->mctx, "Error in dom_node_get_parent"); return HUBBUB_UNKNOWN; } if (element_only == false) { *result = parent; return HUBBUB_OK; } err = dom_node_get_node_type(parent, &type); if (err != DOM_NO_ERR) { dom_parser->msg(DOM_MSG_CRITICAL, dom_parser->mctx, "Error in dom_node_get_type"); goto fail; } if (type == DOM_ELEMENT_NODE) { *result = parent; return HUBBUB_OK; } else { *result = NULL; dom_node_unref(parent); return HUBBUB_OK; } return HUBBUB_OK; fail: dom_node_unref(parent); return HUBBUB_UNKNOWN; }
static bool save_complete_libdom_treewalk(dom_node *root, bool (*callback)(dom_node *node, save_complete_event_type event_type, void *ctx), void *ctx) { dom_node *node; node = dom_node_ref(root); /* tree root */ while (node != NULL) { dom_node *next = NULL; 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 */ if (callback(node, EVENT_LEAVE, ctx) == false) { return false; } 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; } if (callback(node, EVENT_LEAVE, ctx) == false) { return false; } 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; } if (callback(node, EVENT_LEAVE, ctx) == false) { return false; } dom_node_unref(node); node = next; } } assert(node != NULL); if (callback(node, EVENT_ENTER, ctx) == false) { return false; /* callback caused early termination */ } } return true; }