Exemple #1
0
/**
 * Callback to count a node's siblings.
 *
 * \param pw         HTML document
 * \param n          DOM node
 * \param same_name  Only count siblings with the same name, or all
 * \param after      Count anteceding instead of preceding siblings
 * \param count      Pointer to location to receive result
 * \return CSS_OK.
 *
 * \post \a count will contain the number of siblings
 */
css_error node_count_siblings(void *pw, void *n, bool same_name,
		bool after, int32_t *count)
{
	int32_t cnt = 0;
	dom_exception exc;
	dom_string *node_name = NULL;

	if (same_name) {
		dom_node *node = n;
		exc = dom_node_get_node_name(node, &node_name);
		if ((exc != DOM_NO_ERR) || (node_name == NULL)) {
			return CSS_NOMEM;
		}
	}

	if (after) {
		dom_node *node = dom_node_ref(n);
		dom_node *next;

		do {
			exc = dom_node_get_next_sibling(node, &next);
			if ((exc != DOM_NO_ERR))
				break;

			dom_node_unref(node);
			node = next;

			cnt += node_count_siblings_check(node, same_name, node_name);
		} while (node != NULL);
	} else {
		dom_node *node = dom_node_ref(n);
		dom_node *next;

		do {
			exc = dom_node_get_previous_sibling(node, &next);
			if ((exc != DOM_NO_ERR))
				break;

			dom_node_unref(node);
			node = next;

			cnt += node_count_siblings_check(node, same_name, node_name);

		} while (node != NULL);
	}

	if (node_name != NULL) {
		dom_string_unref(node_name);
	}

	*count = cnt;
	return CSS_OK;
}
/**
 * Get the node in the collection according name
 *
 * \param col   The collection
 * \param name  The name of target node
 * \param node  The returned node object
 * \return DOM_NO_ERR on success.
 */
dom_exception dom_html_collection_named_item(dom_html_collection *col,
		dom_string *name, struct dom_node **node)
{
	struct dom_node_internal *n = col->root;
	dom_exception err;
        
        while (n != NULL) {
		if (n->type == DOM_ELEMENT_NODE &&
		    col->ic(n, col->ctx) == true) {
			dom_string *id = NULL;

			err = _dom_element_get_id((struct dom_element *) n,
					&id);
			if (err != DOM_NO_ERR) {
				return err;
			}

			if (id != NULL && dom_string_isequal(name, id)) {
				*node = (struct dom_node *) n;
				dom_node_ref(n);
				dom_string_unref(id);

				return DOM_NO_ERR;
			}

			if (id != NULL)
				dom_string_unref(id);
		}

		/* Depth first iterating */
		if (n->first_child != NULL) {
			n = n->first_child;
		} else if (n->next != NULL) {
			n = n->next;
		} else {
			/* No children and siblings */
			struct dom_node_internal *parent = n->parent;

			while (parent != col->root &&
					n == parent->last_child) {
				n = parent;
				parent = parent->parent;
			}
			
			if (parent == col->root)
				n = NULL;
			else
				n = n->next;
		}
	}

	/* Not found the target node */
	*node = NULL;

	return DOM_NO_ERR;
}
Exemple #3
0
static hubbub_error ref_node(void *parser, void *node)
{
	struct dom_node *dnode = (struct dom_node *) node;

	UNUSED(parser);

	dom_node_ref(dnode);

	return HUBBUB_OK;
}
/**
 * Intialiase a dom_html_collection
 *
 * \param doc   The document
 * \param col   The collection object to be initialised
 * \param root  The root element of the collection
 * \param ic    The callback function used to determin whether certain node
 *              beint32_ts to the collection
 * \return DOM_NO_ERR on success.
 */
dom_exception _dom_html_collection_initialise(struct dom_html_document *doc,
		struct dom_html_collection *col,
		struct dom_node_internal *root,
		dom_callback_is_in_collection ic, void *ctx)
{
	assert(doc != NULL);
	assert(ic != NULL);
	assert(root != NULL);

	col->doc = doc;
	dom_node_ref(doc);

	col->root = root;
	dom_node_ref(root);

	col->ic = ic;
	col->ctx = ctx;
	col->refcnt = 1;

	return DOM_NO_ERR;
}
Exemple #5
0
static struct html_stylesheet *
html_create_style_element(html_content *c, dom_node *style)
{
	dom_string *val;
	dom_exception exc;
	struct html_stylesheet *stylesheets;

	/* type='text/css', or not present (invalid but common) */
	exc = dom_element_get_attribute(style, corestring_dom_type, &val);
	if (exc == DOM_NO_ERR && val != NULL) {
		if (!dom_string_caseless_lwc_isequal(val,
				corestring_lwc_text_css)) {
			dom_string_unref(val);
			return NULL;
		}
		dom_string_unref(val);
	}

	/* media contains 'screen' or 'all' or not present */
	exc = dom_element_get_attribute(style, corestring_dom_media, &val);
	if (exc == DOM_NO_ERR && val != NULL) {
		if (strcasestr(dom_string_data(val), "screen") == NULL &&
				strcasestr(dom_string_data(val),
						"all") == NULL) {
			dom_string_unref(val);
			return NULL;
		}
		dom_string_unref(val);
	}

	/* Extend array */
	stylesheets = realloc(c->stylesheets,
			      sizeof(struct html_stylesheet) *
			      (c->stylesheet_count + 1));
	if (stylesheets == NULL) {

		content_broadcast_errorcode(&c->base, NSERROR_NOMEM);
		return false;

	}
	c->stylesheets = stylesheets;

	c->stylesheets[c->stylesheet_count].node = dom_node_ref(style);
	c->stylesheets[c->stylesheet_count].sheet = NULL;
	c->stylesheets[c->stylesheet_count].modified = false;
	c->stylesheet_count++;

	return c->stylesheets + (c->stylesheet_count - 1);
}
Exemple #6
0
/**
 * Retrieve the doctype of a document
 *
 * \param doc     The document to retrieve the doctype from
 * \param result  Pointer to location to receive result
 * \return DOM_NO_ERR.
 *
 * The returned node will have its reference count increased. It is
 * the responsibility of the caller to unref the node once it has
 * finished with it.
 */
dom_exception _dom_document_get_doctype(dom_document *doc,
                                        dom_document_type **result)
{
    dom_node_internal *c;

    for (c = doc->base.first_child; c != NULL; c = c->next) {
        if (c->type == DOM_DOCUMENT_TYPE_NODE)
            break;
    }

    if (c != NULL)
        dom_node_ref(c);

    *result = (dom_document_type *) c;

    return DOM_NO_ERR;
}
Exemple #7
0
/**
 * Retrieve the document element of a document
 *
 * \param doc     The document to retrieve the document element from
 * \param result  Pointer to location to receive result
 * \return DOM_NO_ERR.
 *
 * The returned node will have its reference count increased. It is
 * the responsibility of the caller to unref the node once it has
 * finished with it.
 */
dom_exception _dom_document_get_document_element(dom_document *doc,
        dom_element **result)
{
    dom_node_internal *root;

    /* Find the first element node in child list */
    for (root = doc->base.first_child; root != NULL; root = root->next) {
        if (root->type == DOM_ELEMENT_NODE)
            break;
    }

    if (root != NULL)
        dom_node_ref(root);

    *result = (dom_element *) root;

    return DOM_NO_ERR;
}
/**
 * Get the node with certain index
 *
 * \param col  The dom_html_collection object
 * \param index  The index number based on zero
 * \param node   The returned node object
 * \return DOM_NO_ERR on success.
 */
dom_exception dom_html_collection_item(dom_html_collection *col,
		uint32_t index, struct dom_node **node)
{
	struct dom_node_internal *n = col->root;
	uint32_t len = 0;

	while (n != NULL) {
		if (n->type == DOM_ELEMENT_NODE && 
		    col->ic(n, col->ctx) == true)
			len++;

		if (len == index + 1) {
			dom_node_ref(n);
			*node = (struct dom_node *) n;
			return DOM_NO_ERR;
		}

		/* Depth first iterating */
		if (n->first_child != NULL) {
			n = n->first_child;
		} else if (n->next != NULL) {
			n = n->next;
		} else {
			/* No children and siblings */
			struct dom_node_internal *parent = n->parent;

			while (parent != col->root &&
					n == parent->last_child) {
				n = parent;
				parent = parent->parent;
			}
			
			if (n == col->root)
				n = NULL;
			else
				n = n->next;
		}
	}

	/* Not find the node */
	*node = NULL;
	return DOM_NO_ERR;
}
Exemple #9
0
void list_add(struct list* list, void* data)
{
	struct list_elt* elt = list_new_elt(data);
	struct list_elt* tail = list->tail;

	/* if tail was set, make its 'next' ptr point to elt */
	if (tail != NULL) {
		tail->next = elt;
	}

	/* make elt the new tail */
	list->tail = elt;

	if (list->head == NULL) {
		list->head = elt;
	}

	/* inc the size of the list */
	list->size++;
	if (list->type == DOM_STRING)
		dom_string_ref((dom_string *) data);
	if (list->type == NODE)
		dom_node_ref(data);
}
Exemple #10
0
/**
 * Create a Hubbub parser instance
 *
 * \param params The binding creation parameters
 * \param parser Pointer to location to recive instance.
 * \param document Pointer to location to receive document.
 * \return Error code
 */
dom_hubbub_error
dom_hubbub_parser_create(dom_hubbub_parser_params *params,
			 dom_hubbub_parser **parser,
			 dom_document **document)
{
	dom_hubbub_parser *binding;
	hubbub_parser_optparams optparams;
	hubbub_error error;
	dom_exception err;
	dom_string *idname = NULL;

	/* check result parameters */
	if (document == NULL) {
		return DOM_HUBBUB_BADPARM;
	}

	if (parser == NULL) {
		return DOM_HUBBUB_BADPARM;
	}

	/* setup binding parser context */
	binding = malloc(sizeof(dom_hubbub_parser));
	if (binding == NULL) {
		return DOM_HUBBUB_NOMEM;
	}

	binding->parser = NULL;
	binding->doc = NULL;
	binding->encoding = params->enc;

	if (params->enc != NULL) {
		binding->encoding_source = DOM_HUBBUB_ENCODING_SOURCE_HEADER;
	} else {
		binding->encoding_source = DOM_HUBBUB_ENCODING_SOURCE_DETECTED;
	}

	binding->complete = false;

	if (params->msg == NULL) {
		binding->msg = dom_hubbub_parser_default_msg;
	} else {
		binding->msg = params->msg;
	}
	binding->mctx = params->ctx;

	/* ensure script function is valid or use the default */
	if (params->script == NULL) {
		binding->script = dom_hubbub_parser_default_script;
	} else {
		binding->script = params->script;
	}

	/* create hubbub parser */
	error = hubbub_parser_create(binding->encoding,
				     params->fix_enc,
				     dom_hubbub_alloc,
				     NULL,
				     &binding->parser);
	if (error != HUBBUB_OK)	 {
		free(binding);
		return (DOM_HUBBUB_HUBBUB_ERR | error);
	}

	/* create DOM document */
	err = dom_implementation_create_document(DOM_IMPLEMENTATION_HTML,
						 NULL,
						 NULL,
						 NULL,
						 params->daf,
						 params->ctx,
						 &binding->doc);
	if (err != DOM_NO_ERR) {
		hubbub_parser_destroy(binding->parser);
		free(binding);
		return DOM_HUBBUB_DOM;
	}

	binding->tree_handler = tree_handler;
	binding->tree_handler.ctx = (void *)binding;

	/* set tree handler on parser */
	optparams.tree_handler = &binding->tree_handler;
	hubbub_parser_setopt(binding->parser,
			     HUBBUB_PARSER_TREE_HANDLER,
			     &optparams);

	/* set document node*/
	optparams.document_node = dom_node_ref((struct dom_node *)binding->doc);
	hubbub_parser_setopt(binding->parser,
			     HUBBUB_PARSER_DOCUMENT_NODE,
			     &optparams);

	/* set scripting state */
	optparams.enable_scripting = params->enable_script;
	hubbub_parser_setopt(binding->parser,
			     HUBBUB_PARSER_ENABLE_SCRIPTING,
			     &optparams);

	/* set the document id parameter before the parse so searches
	 * based on id succeed.
	 */
	err = dom_string_create_interned((const uint8_t *) "id",
					 SLEN("id"),
					 &idname);
	if (err != DOM_NO_ERR) {
		binding->msg(DOM_MSG_ERROR, binding->mctx, "Can't set DOM document id name");
		hubbub_parser_destroy(binding->parser);
		free(binding);
		return DOM_HUBBUB_DOM;
	}
	_dom_document_set_id_name(binding->doc, idname);
	dom_string_unref(idname);

	/* set return parameters */
	*document = (dom_document *)dom_node_ref(binding->doc);
	*parser = binding;

	return DOM_HUBBUB_OK;
}
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;
}