Hubbub treebuilding interface ============================= Introduction ------------ hubbub uses an interface to build a tree. this is what the functions should do. Types ----- hubbub_string ------------- Reference counting ------------------ The callback interface provides hooks to allow tree nodes to be reference counted. There is, however, no requirement that the client actually performs reference counting. It is perfectly acceptable to use some other object use tracking scheme (e.g. garbage collection). The descriptions below describe the expected reference counting behaviour, regardless. Callback behaviour ------------------ The first parameter to all callbacks is the context passed to the library on initialisation. All node creation functions should return 0 on success, and something else on failure. Node creation ------------- | int hubbub_tree_create_comment(void *ctx, | const hubbub_string *data, | void **result); | | int hubbub_tree_create_doctype(void *ctx, | const hubbub_doctype *doctype, | void **result); | | int hubbub_tree_create_element(void *ctx, | const hubbub_tag *tag, | void **result); | | int hubbub_tree_create_text(void *ctx, | const hubbub_string *data, | void **result); All node creation functions must create a node with the information passed in their second argument, and place a pointer to that node in *result. The reference count of the created node must be set to 1. | int hubbub_tree_clone_node(void *ctx, | void *node, | bool deep, | void **result); If deep == false, then this function must duplicate "node" and none of its children, and place a pointer to the clone in *result. It must also set the reference count of the clone to 1. The clone must be isolated from the document tree (it must have no parent or sibling nodes). If deep == true, then this function must duplicate "node" and all of its children. A pointer to the clone of "node" must be placed in *result. The reference count of the clone must be set to 1. The reference count of all other created nodes must be set to 0. The clone must also be isolated from the document tree (it must have no parent or sibling nodes). Reference counting ------------------ | int hubbub_tree_ref_node(void *ctx, void *node); | int hubbub_tree_unref_node(void *ctx, void *node); These functions should increase and decrease the reference count of "node", respectively. If the reference count of "node" falls to zero, and it is isolated from the document tree (it has no parent or sibling nodes), then it must be destroyed. Tree manipulation ----------------- | int hubbub_tree_append_child(void *ctx, | void *parent, | void *child, | void **result); This function must append the node "child" to the end of the list of children of the node "parent", and place a pointer to the newly-inserted node in *result. If the node "child" is a text node, and the last child node of "parent" is also a text node, then instead the text of "child" must be appended to that node, and a pointer to the node thus appended to must be placed in *result. In any case, the reference count of the node pointed to by *result at the end of these steps must be incremented. | int hubbub_tree_insert_before(void *ctx, | void *parent, | void *child, | void *ref_child, | void **result); This function must insert the node "child" into the list of children of "parent" immediately before the node "ref_child", and place a pointer to the newly-inserted node in *result. If the node "child" is a text node, and the node "ref_child" or the node before "ref_child" is also a text node, then instead the text of "child" must be prepended to the text of "ref_child", or appended to the text of node before "ref_node", and a pointer to the node thus appended to must be placed in *result. In any case, the reference count of the node pointed to by *result at the end of these steps must be incremented. | int hubbub_tree_remove_child(void *ctx, | void *parent, | void *child, | void **result); This function must remove the node "child" from the document tree. It must increment the reference count of the node "child", and place a pointer to the newly-removed node in *result. | int hubbub_tree_reparent_children(void *ctx, | void *node, | void *new_parent); This function must detach all children from "node" and insert them into "new_parent" in the same order as they were found in "node". | int hubbub_tree_get_parent(void *ctx, | void *node, | bool element_only, | void **result); This function must retrieve the parent of "node". If there is no parent node, then NULL must be placed in *result. Otherwise, it must increment the reference count of the parent, and place a pointer to the parent in *result. If "element_only" == true and the retrieved parent is not an element node, then act as if no parent exists. | int hubbub_tree_has_children(void *ctx, | void *node, | bool *result); If "node" has any child nodes attached to it, then *result must be set to true. Otherwise, *result must be set to false. | int hubbub_tree_form_associate(void *ctx, | void *form, | void *node); This function must associate "node" with the node "form" (which is the currently active form element). | int hubbub_tree_add_attributes(void *ctx, | void *node, | const hubbub_attribute *attributes, | uint32_t n_attributes); For each attribute in the array "attributes", this function must check to see if there is such an attribute already present on "node". If there is not such an attribute, then the attribute must be added to "node". | int hubbub_tree_set_quirks_mode(void *ctx, | hubbub_quirks_mode mode); This function must set the quirks mode flag of the document to "mode". | int hubbub_tree_encoding_change(void *ctx, | const char *name); This function is called when a meta tag which specifies a charset is seen in the treebuilder. [1] The client is responsible for checking if the encoding the document is being processed as should actually be changed, and if it should, this function should return 1. In this case, the parser instance will return the error code HUBBUB_ENCODINGCHANGE when it returns from parsing the chunk that triggered the encoding change. The parser instance should then be destroyed and a new one created with that encoding specified. [1] http://www.whatwg.org/specs/web-apps/current-work/#in-head