예제 #1
0
static bool save_complete_handle_attrs(save_complete_ctx *ctx,
		dom_string *node_name, dom_namednodemap *attrs)
{
	uint32_t length, i;
	dom_exception error;

	error = dom_namednodemap_get_length(attrs, &length);
	if (error != DOM_NO_ERR)
		return false;

	for (i = 0; i < length; i++) {
		dom_attr *attr;

		error = dom_namednodemap_item(attrs, i, (void *) &attr);
		if (error != DOM_NO_ERR)
			return false;

		if (attr == NULL)
			continue;

		if (save_complete_handle_attr(ctx, node_name, attr) == false) {
			dom_node_unref(attr);
			return false;
		}

		dom_node_unref(attr);
	}

	return true;
}
예제 #2
0
/**
 * Load the file as it is a XML file
 *
 * \param file		The file path 
 * \param willBeModified	Whether this file will be modified, not used
 */
dom_document *load_xml(const char *file, bool willBeModified)
{
	dom_xml_parser *parser = NULL;
	int handle;
	int readed;
	dom_xml_error error;
	dom_document *ret;
	uint8_t buffer[1024];

	UNUSED(willBeModified);

	parser = dom_xml_parser_create(NULL, NULL, mymsg, NULL, &ret);
	if (parser == NULL) {
		fprintf(stderr, "Can't create XMLParser\n");
		return NULL;
	}

	handle = open(file, O_RDONLY);
	if (handle == -1) {
		dom_node_unref(ret);
		dom_xml_parser_destroy(parser);
		fprintf(stderr, "Can't open test input file: %s\n", file);
		return NULL;
	}

	readed = read(handle, buffer, 1024);
	error = dom_xml_parser_parse_chunk(parser, buffer, readed);
	if (error != DOM_XML_OK) {
		dom_node_unref(ret);
		dom_xml_parser_destroy(parser);
		fprintf(stderr, "Parsing errors occur\n");
		return NULL;
	}

	while(readed == 1024) {
		readed = read(handle, buffer, 1024);
		error = dom_xml_parser_parse_chunk(parser, buffer, readed);
		if (error != DOM_XML_OK) {
			dom_node_unref(ret);
			dom_xml_parser_destroy(parser);
			fprintf(stderr, "Parsing errors occur\n");
			return NULL;
		}
	}

	error = dom_xml_parser_completed(parser);
	if (error != DOM_XML_OK) {
		dom_node_unref(ret);
		dom_xml_parser_destroy(parser);
		fprintf(stderr, "Parsing error when construct DOM\n");
		return NULL;
	}

	dom_xml_parser_destroy(parser);

	return ret;
}
예제 #3
0
파일: select.c 프로젝트: kyllikki/netsurf
/**
 * Callback to find a named sibling node.
 *
 * \param pw       HTML document
 * \param node     DOM node
 * \param qname    Node name to search for
 * \param sibling  Pointer to location to receive sibling
 * \return CSS_OK.
 *
 * \post \a sibling will contain the result, or NULL if there is no match
 */
css_error named_sibling_node(void *pw, void *node,
		const css_qname *qname, void **sibling)
{
	dom_node *n = node;
	dom_node *prev;
	dom_exception err;

	*sibling = NULL;

	/* Find sibling element */
	err = dom_node_get_previous_sibling(n, &n);
	if (err != DOM_NO_ERR)
		return CSS_OK;

	while (n != NULL) {
		dom_node_type type;

		err = dom_node_get_node_type(n, &type);
		if (err != DOM_NO_ERR) {
			dom_node_unref(n);
			return CSS_OK;
		}

		if (type == DOM_ELEMENT_NODE)
			break;

		err = dom_node_get_previous_sibling(n, &prev);
		if (err != DOM_NO_ERR) {
			dom_node_unref(n);
			return CSS_OK;
		}

		dom_node_unref(n);
		n = prev;
	}

	if (n != NULL) {
		dom_string *name;

		err = dom_node_get_node_name(n, &name);
		if (err != DOM_NO_ERR) {
			dom_node_unref(n);
			return CSS_OK;
		}

		dom_node_unref(n);

		if (dom_string_caseless_lwc_isequal(name, qname->name)) {
			*sibling = n;
		}

		dom_string_unref(name);
	}

	return CSS_OK;
}
예제 #4
0
/**
 * Finalise a dom_html_collection object
 *
 * \param col  The dom_html_collection object
 */
void _dom_html_collection_finalise(struct dom_html_collection *col)
{
	dom_node_unref(col->doc);
	col->doc = NULL;

	dom_node_unref(col->root);
	col->root = NULL;

	col->ic = NULL;
}
예제 #5
0
파일: select.c 프로젝트: kyllikki/netsurf
/**
 * 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;
}
예제 #6
0
파일: select.c 프로젝트: kyllikki/netsurf
/**
 * 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;
}
예제 #7
0
파일: xml2dom.c 프로젝트: Joouis/EVGUI
dom_exception dom_element_get_elements_by_tag_name(dom_element *element, dom_string *string, dom_nodelist **outNodeList) {
  dom_nodelist *result = NULL;
  dom_element **nodeList = NULL;
  int nodeCount = 0;
  for (ezxml_t candidate = ezxml_child(element->node, string->s); candidate; candidate = candidate->next) {
      if (NULL == nodeList) {
        nodeList = (dom_element **)malloc(nodeCount * sizeof(dom_element *));
      } else {
        dom_element **t = realloc(nodeList, (1+nodeCount) * sizeof(dom_element *));
        if (t) {
          nodeList = t;
        } else {
          for (int i = 0; i < nodeCount; ++i) {
            dom_node_unref(nodeList[i]);
          }
          free(nodeList);
          *outNodeList = result;
          return DOM_MEM_ERR;
        }
      }
      dom_element *elem = (dom_element *)calloc(sizeof(dom_element), 1);
      elem->node = candidate;
      elem->ref = 1;
      nodeList[nodeCount++] = elem;
  }
  if (nodeCount) {
    result = calloc(sizeof(dom_nodelist), 1);
    result->nodes = nodeList;
    result->count = nodeCount;
    result->ref = 1;
  }
  *outNodeList = result;
  return DOM_NO_ERR;
}
예제 #8
0
파일: select.c 프로젝트: kyllikki/netsurf
/**
 * Callback to retrieve the preceding sibling of a node.
 *
 * \param pw       HTML document
 * \param node     DOM node
 * \param sibling  Pointer to location to receive sibling
 * \return CSS_OK.
 *
 * \post \a sibling will contain the result, or NULL if there is no match
 */
css_error sibling_node(void *pw, void *node, void **sibling)
{
	dom_node *n = node;
	dom_node *prev;
	dom_exception err;

	*sibling = NULL;

	/* Find sibling element */
	err = dom_node_get_previous_sibling(n, &n);
	if (err != DOM_NO_ERR)
		return CSS_OK;

	while (n != NULL) {
		dom_node_type type;

		err = dom_node_get_node_type(n, &type);
		if (err != DOM_NO_ERR) {
			dom_node_unref(n);
			return CSS_OK;
		}

		if (type == DOM_ELEMENT_NODE)
			break;

		err = dom_node_get_previous_sibling(n, &prev);
		if (err != DOM_NO_ERR) {
			dom_node_unref(n);
			return CSS_OK;
		}

		dom_node_unref(n);
		n = prev;
	}

	if (n != NULL) {
		/** \todo Sort out reference counting */
		dom_node_unref(n);

		*sibling = n;
	}

	return CSS_OK;
}
예제 #9
0
static hubbub_error reparent_children(void *parser, void *node,
		void *new_parent)
{
	dom_hubbub_parser *dom_parser = (dom_hubbub_parser *) parser;
	dom_exception err;
	struct dom_node *child, *result;

	while(true) {
		err = dom_node_get_first_child((struct dom_node *) node,
				&child);
		if (err != DOM_NO_ERR) {
			dom_parser->msg(DOM_MSG_CRITICAL, dom_parser->mctx,
					"Error in dom_note_get_first_child");
			return HUBBUB_UNKNOWN;
		}
		if (child == NULL)
			break;

		err = dom_node_remove_child(node, (struct dom_node *) child,
				&result);
		if (err != DOM_NO_ERR) {
			dom_parser->msg(DOM_MSG_CRITICAL, dom_parser->mctx,
					"Error in dom_node_remove_child");
			goto fail;
		}
		dom_node_unref(result);

		err = dom_node_append_child((struct dom_node *) new_parent,
				(struct dom_node *) child, &result);
		if (err != DOM_NO_ERR) {
			dom_parser->msg(DOM_MSG_CRITICAL, dom_parser->mctx,
					"Error in dom_node_append_child");
			goto fail;
		}
		dom_node_unref(result);
		dom_node_unref(child);
	}
	return HUBBUB_OK;

fail:
	dom_node_unref(child);
	return HUBBUB_UNKNOWN;
}
예제 #10
0
static hubbub_error unref_node(void *parser, void *node)
{
	struct dom_node *dnode = (struct dom_node *) node;

	UNUSED(parser);

	dom_node_unref(dnode);

	return HUBBUB_OK;
}
예제 #11
0
파일: imagemap.c 프로젝트: mmuman/NetSurf
/**
 * Extract an imagemap from html source
 *
 * \param node  XML node containing map
 * \param c     Content containing document
 * \param entry List of map entries
 * \param tname The sub-tags to consider on this pass
 * \return false on memory exhaustion, true otherwise
 */
static bool
imagemap_extract_map_entries(dom_node *node, html_content *c,
			     struct mapentry **entry, dom_string *tname)
{
	dom_nodelist *nlist;
	dom_exception exc;
	unsigned long ent;
	uint32_t tag_count;

	exc = dom_element_get_elements_by_tag_name(node, tname, &nlist);
	if (exc != DOM_NO_ERR) {
		return false;
	}

	exc = dom_nodelist_get_length(nlist, &tag_count);
	if (exc != DOM_NO_ERR) {
		dom_nodelist_unref(nlist);
		return false;
	}

	for (ent = 0; ent < tag_count; ++ent) {
		dom_node *subnode;

		exc = dom_nodelist_item(nlist, ent, &subnode);
		if (exc != DOM_NO_ERR) {
			dom_nodelist_unref(nlist);
			return false;
		}
		if (imagemap_addtolist(c, subnode, c->base_url,
				       entry, tname) == false) {
			dom_node_unref(subnode);
			dom_nodelist_unref(nlist);
			return false;
		}
		dom_node_unref(subnode);
	}

	dom_nodelist_unref(nlist);

	return true;
}
예제 #12
0
/**
 * Destroy a Hubbub parser instance
 *
 * \param parser  The Hubbub parser object
 */
void dom_hubbub_parser_destroy(dom_hubbub_parser *parser)
{
	hubbub_parser_destroy(parser->parser);
	parser->parser = NULL;

	if (parser->doc != NULL) {
		dom_node_unref((struct dom_node *) parser->doc);
		parser->doc = NULL;
	}

	free(parser);
}
예제 #13
0
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;
}
예제 #14
0
파일: select.c 프로젝트: kyllikki/netsurf
/**
 * Callback to determine if a node is empty.
 *
 * \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 is empty and false otherwise.
 */
css_error node_is_empty(void *pw, void *node, bool *match)
{
	dom_node *n = node, *next;
	dom_exception err;

	*match = true;

	err = dom_node_get_first_child(n, &n);
	if (err != DOM_NO_ERR) {
		return CSS_BADPARM;
	}

	while (n != NULL) {
		dom_node_type ntype;
		err = dom_node_get_node_type(n, &ntype);
		if (err != DOM_NO_ERR) {
			dom_node_unref(n);
			return CSS_BADPARM;
		}

		if (ntype == DOM_ELEMENT_NODE ||
		    ntype == DOM_TEXT_NODE) {
			*match = false;
			dom_node_unref(n);
			break;
		}

		err = dom_node_get_next_sibling(n, &next);
		if (err != DOM_NO_ERR) {
			dom_node_unref(n);
			return CSS_BADPARM;
		}
		dom_node_unref(n);
		n = next;
	}

	return CSS_OK;
}
예제 #15
0
파일: xml2dom.c 프로젝트: Joouis/EVGUI
void dom_nodelist_unref(dom_nodelist *nodeList) {
  assert(nodeList);
  nodeList->ref--;
  if (0 == nodeList->ref) {
    int count = nodeList->count;
    for (int i = 0; i < count; ++i) {
      dom_node_unref(nodeList->nodes[i]);
    }
    if (0 < count) {
     free(nodeList->nodes);
    }
    free(nodeList);
  }
}
예제 #16
0
void list_destroy(struct list* list)
{
	struct list_elt* elt = list->head;
	while (elt != NULL) {
		if (list->type == DOM_STRING)
			dom_string_unref((dom_string *) elt->data);
		if (list->type == NODE)
			dom_node_unref(elt->data);
		struct list_elt* nextElt = elt->next;
		free(elt);
		elt = nextElt;
	}
	free(list);
}
예제 #17
0
static struct form_control *
parse_select_element(struct form *forms, dom_html_select_element *select)
{
	struct form_control *control = NULL;
	dom_html_form_element *form = NULL;
	dom_string *ds_name = NULL;

	char *name = NULL;

	if (dom_html_select_element_get_form(select, &form) != DOM_NO_ERR)
		goto out;

	if (dom_html_select_element_get_name(select, &ds_name) != DOM_NO_ERR)
		goto out;

	if (ds_name != NULL)
		name = strndup(dom_string_data(ds_name),
			       dom_string_byte_length(ds_name));

	control = form_new_control(select, GADGET_SELECT);

	if (control == NULL)
		goto out;

	if (name != NULL) {
		/* Hand the name string over */
		control->name = name;
		name = NULL;
	}

	dom_html_select_element_get_multiple(select,
			&(control->data.select.multiple));

	if (form != NULL && control != NULL)
		form_add_control(find_form(forms, form), control);

out:
	if (form != NULL)
		dom_node_unref(form);
	if (ds_name != NULL)
		dom_string_unref(ds_name);

	if (name != NULL)
		free(name);


	return control;
}
예제 #18
0
/* documented in html_internal.h */
struct form *html_forms_get_forms(const char *docenc, dom_html_document *doc)
{
	dom_html_collection *forms;
	struct form *ret = NULL, *newf;
	dom_node *node;
	unsigned long n;
	uint32_t nforms;

	if (doc == NULL)
		return NULL;

	/* Attempt to build a set of all the forms */
	if (dom_html_document_get_forms(doc, &forms) != DOM_NO_ERR)
		return NULL;

	/* Count the number of forms so we can iterate */
	if (dom_html_collection_get_length(forms, &nforms) != DOM_NO_ERR)
		goto out;

	/* Iterate the forms collection, making form structs for returning */
	for (n = 0; n < nforms; ++n) {
		if (dom_html_collection_item(forms, n, &node) != DOM_NO_ERR) {
			goto out;
		}
		newf = parse_form_element(docenc, node);
		dom_node_unref(node);
		if (newf == NULL) {
			goto err;
		}
		newf->prev = ret;
		ret = newf;
	}

	/* All went well */
	goto out;
err:
	while (ret != NULL) {
		struct form *prev = ret->prev;
		/* Destroy ret */
		free(ret);
		ret = prev;
	}
out:
	/* Finished with the collection, return it */
	dom_html_collection_unref(forms);

	return ret;
}
예제 #19
0
svgtiny_code svgtiny_parse(struct svgtiny_diagram *diagram,
		const char *buffer, size_t size, const char *url,
		int viewport_width, int viewport_height)
{
	svgtiny_code code;
    dom_document *document;

    code = svgtiny_parse_dom(buffer, size, url, &document);
    if (code != svgtiny_OK) {
        return code;
    }

    code = svgtiny_parse_svg_from_dom(diagram, document, viewport_width, viewport_height);
	dom_node_unref(document);
    return code;
}
예제 #20
0
static struct form_control *
parse_textarea_element(struct form *forms, dom_html_text_area_element *ta)
{
	struct form_control *control = NULL;
	dom_html_form_element *form = NULL;
	dom_string *ds_name = NULL;

	char *name = NULL;

	if (dom_html_text_area_element_get_form(ta, &form) != DOM_NO_ERR)
		goto out;

	if (dom_html_text_area_element_get_name(ta, &ds_name) != DOM_NO_ERR)
		goto out;

	if (ds_name != NULL)
		name = strndup(dom_string_data(ds_name),
			       dom_string_byte_length(ds_name));

	control = form_new_control(ta, GADGET_TEXTAREA);

	if (control == NULL)
		goto out;

	if (name != NULL) {
		/* Hand the name string over */
		control->name = name;
		name = NULL;
	}

	if (form != NULL && control != NULL)
		form_add_control(find_form(forms, form), control);

out:
	if (form != NULL)
		dom_node_unref(form);
	if (ds_name != NULL)
		dom_string_unref(ds_name);

	if (name != NULL)
		free(name);


	return control;
}
예제 #21
0
/* exported interface documented in render/html_internal.h */
nserror html_css_free_stylesheets(html_content *html)
{
	unsigned int i;

	guit->misc->schedule(-1, html_css_process_modified_styles, html);

	for (i = 0; i != html->stylesheet_count; i++) {
		if (html->stylesheets[i].sheet != NULL) {
			hlcache_handle_release(html->stylesheets[i].sheet);
		}
		if (html->stylesheets[i].node != NULL) {
			dom_node_unref(html->stylesheets[i].node);
		}
	}
	free(html->stylesheets);

	return NSERROR_OK;
}
예제 #22
0
static struct form_control *
parse_button_element(struct form *forms, dom_html_button_element *button)
{
	struct form_control *control = NULL;
	dom_exception err;
	dom_html_form_element *form = NULL;
	dom_string *ds_type = NULL;
	dom_string *ds_value = NULL;
	dom_string *ds_name = NULL;

	err = dom_html_button_element_get_form(button, &form);
	if (err != DOM_NO_ERR)
		goto out;

	err = dom_html_button_element_get_type(button, &ds_type);
	if (err != DOM_NO_ERR)
		goto out;

	if (ds_type == NULL) {
		control = form_new_control(button, GADGET_SUBMIT);
	} else {
		if (dom_string_caseless_lwc_isequal(ds_type,
				corestring_lwc_submit)) {
			control = form_new_control(button, GADGET_SUBMIT);
		} else if (dom_string_caseless_lwc_isequal(ds_type,
				corestring_lwc_reset)) {
			control = form_new_control(button, GADGET_RESET);
		} else {
			control = form_new_control(button, GADGET_BUTTON);
		}
	}

	if (control == NULL)
		goto out;

	err = dom_html_button_element_get_value(button, &ds_value);
	if (err != DOM_NO_ERR)
		goto out;
	err = dom_html_button_element_get_name(button, &ds_name);
	if (err != DOM_NO_ERR)
		goto out;

	if (ds_value != NULL) {
		control->value = strndup(
			dom_string_data(ds_value),
			dom_string_byte_length(ds_value));

		if (control->value == NULL) {
			form_free_control(control);
			control = NULL;
			goto out;
		}
	}

	if (ds_name != NULL) {
		control->name = strndup(
			dom_string_data(ds_name),
			dom_string_byte_length(ds_name));

		if (control->name == NULL) {
			form_free_control(control);
			control = NULL;
			goto out;
		}
	}

	if (form != NULL && control != NULL)
		form_add_control(find_form(forms, form), control);

out:
	if (form != NULL)
		dom_node_unref(form);
	if (ds_type != NULL)
		dom_string_unref(ds_type);
	if (ds_value != NULL)
		dom_string_unref(ds_value);
	if (ds_name != NULL)
		dom_string_unref(ds_name);

	return control;
}
예제 #23
0
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;
}
예제 #24
0
svgtiny_code svgtiny_parse_svg(dom_element *svg,
		struct svgtiny_parse_state state)
{
	float x, y, width, height;
	dom_string *view_box;
	dom_element *child;
	dom_exception exc;

	svgtiny_setup_state_local(&state);

	svgtiny_parse_position_attributes(svg, state, &x, &y, &width, &height);
	svgtiny_parse_paint_attributes(svg, &state);
	svgtiny_parse_font_attributes(svg, &state);

	exc = dom_element_get_attribute(svg, state.interned_viewBox,
					&view_box);
	if (exc != DOM_NO_ERR) {
		svgtiny_cleanup_state_local(&state);
		return svgtiny_LIBDOM_ERROR;
	}

	if (view_box) {
		char *s = strndup(dom_string_data(view_box),
				  dom_string_byte_length(view_box));
		float min_x, min_y, vwidth, vheight;
		if (sscanf(s, "%f,%f,%f,%f",
				&min_x, &min_y, &vwidth, &vheight) == 4 ||
				sscanf(s, "%f %f %f %f",
				&min_x, &min_y, &vwidth, &vheight) == 4) {
			state.ctm.a = (float) state.viewport_width / vwidth;
			state.ctm.d = (float) state.viewport_height / vheight;
			state.ctm.e += -min_x * state.ctm.a;
			state.ctm.f += -min_y * state.ctm.d;
		}
		free(s);
		dom_string_unref(view_box);
	}

	svgtiny_parse_transform_attributes(svg, &state);

	exc = dom_node_get_first_child(svg, (dom_node **) (void *) &child);
	if (exc != DOM_NO_ERR) {
		svgtiny_cleanup_state_local(&state);
		return svgtiny_LIBDOM_ERROR;
	}
	while (child != NULL) {
		dom_element *next;
		dom_node_type nodetype;
		svgtiny_code code = svgtiny_OK;

		exc = dom_node_get_node_type(child, &nodetype);
		if (exc != DOM_NO_ERR) {
			dom_node_unref(child);
			return svgtiny_LIBDOM_ERROR;
		}
		if (nodetype == DOM_ELEMENT_NODE) {
			dom_string *nodename;
			exc = dom_node_get_node_name(child, &nodename);
			if (exc != DOM_NO_ERR) {
				dom_node_unref(child);
				svgtiny_cleanup_state_local(&state);
				return svgtiny_LIBDOM_ERROR;
			}
			if (dom_string_caseless_isequal(state.interned_svg,
							nodename))
				code = svgtiny_parse_svg(child, state);
			else if (dom_string_caseless_isequal(state.interned_g,
							     nodename))
				code = svgtiny_parse_svg(child, state);
			else if (dom_string_caseless_isequal(state.interned_a,
							     nodename))
				code = svgtiny_parse_svg(child, state);
			else if (dom_string_caseless_isequal(state.interned_path,
							     nodename))
				code = svgtiny_parse_path(child, state);
			else if (dom_string_caseless_isequal(state.interned_rect,
							     nodename))
				code = svgtiny_parse_rect(child, state);
			else if (dom_string_caseless_isequal(state.interned_circle,
							     nodename))
				code = svgtiny_parse_circle(child, state);
			else if (dom_string_caseless_isequal(state.interned_ellipse,
							     nodename))
				code = svgtiny_parse_ellipse(child, state);
			else if (dom_string_caseless_isequal(state.interned_line,
							     nodename))
				code = svgtiny_parse_line(child, state);
			else if (dom_string_caseless_isequal(state.interned_polyline,
							     nodename))
				code = svgtiny_parse_poly(child, state, false);
			else if (dom_string_caseless_isequal(state.interned_polygon,
							     nodename))
				code = svgtiny_parse_poly(child, state, true);
			else if (dom_string_caseless_isequal(state.interned_text,
							     nodename))
				code = svgtiny_parse_text(child, state);
			dom_string_unref(nodename);
		}
		if (code != svgtiny_OK) {
			dom_node_unref(child);
			svgtiny_cleanup_state_local(&state);
			return code;
		}
		exc = dom_node_get_next_sibling(child,
						(dom_node **) (void *) &next);
		dom_node_unref(child);
		if (exc != DOM_NO_ERR) {
			svgtiny_cleanup_state_local(&state);
			return svgtiny_LIBDOM_ERROR;
		}
		child = next;
	}

	svgtiny_cleanup_state_local(&state);
	return svgtiny_OK;
}
예제 #25
0
void svgtiny_free_dom(dom_document *dom) {
    dom_node_unref(dom);
}
예제 #26
0
svgtiny_code svgtiny_parse_svg_from_dom(struct svgtiny_diagram *diagram,
        dom_document *document, int viewport_width, int viewport_height)
{
    dom_element *svg;
    dom_exception exc;
	svgtiny_code code;

    exc = dom_document_get_document_element(document, &svg);
	if (exc != DOM_NO_ERR) {
		dom_node_unref(document);
		return svgtiny_LIBDOM_ERROR;
	}

	struct svgtiny_parse_state state;
	float x, y, width, height;

	assert(diagram);

	state.gradient_x1 = NULL;
	state.gradient_y1 = NULL;
	state.gradient_x2 = NULL;
	state.gradient_y2 = NULL;


	/* get graphic dimensions */
	memset(&state, 0, sizeof(state));
	state.diagram = diagram;
	state.document = document;
	state.viewport_width = viewport_width;
	state.viewport_height = viewport_height;

#define SVGTINY_STRING_ACTION2(s,n)					\
	if (dom_string_create_interned((const uint8_t *) #n,		\
				       strlen(#n), &state.interned_##s)	\
	    != DOM_NO_ERR) {						\
		code = svgtiny_LIBDOM_ERROR;				\
		goto cleanup;						\
	}
#include "svgtiny_strings.h"
#undef SVGTINY_STRING_ACTION2

	svgtiny_parse_position_attributes(svg, state, &x, &y, &width, &height);
	diagram->width = width;
	diagram->height = height;

	/* set up parsing state */
	state.viewport_width = width;
	state.viewport_height = height;
	state.ctm.a = 1; /*(float) viewport_width / (float) width;*/
	state.ctm.b = 0;
	state.ctm.c = 0;
	state.ctm.d = 1; /*(float) viewport_height / (float) height;*/
	state.ctm.e = 0; /*x;*/
	state.ctm.f = 0; /*y;*/
	/*state.style = css_base_style;
	state.style.font_size.value.length.value = option_font_size * 0.1;*/
	state.fill = 0x000000;
	state.stroke = svgtiny_TRANSPARENT;
	state.stroke_width = 1;
	state.linear_gradient_stop_count = 0;

	/* parse tree */
	code = svgtiny_parse_svg(svg, state);

	dom_node_unref(svg);

cleanup:
	svgtiny_cleanup_state_local(&state);
#define SVGTINY_STRING_ACTION2(s,n)			\
	if (state.interned_##s != NULL)			\
		dom_string_unref(state.interned_##s);
#include "svgtiny_strings.h"
#undef SVGTINY_STRING_ACTION2
	return code;
}
예제 #27
0
svgtiny_code svgtiny_parse_dom(const char *buffer, size_t size, const char *url, dom_document **output_dom)
{
	dom_document *document;
	dom_exception exc;
	dom_xml_parser *parser;
	dom_xml_error err;
	dom_element *svg;
	dom_string *svg_name;
	lwc_string *svg_name_lwc;

    assert(buffer);
	assert(url);

	UNUSED(url);

    parser = dom_xml_parser_create(NULL, NULL,
                                   ignore_msg, NULL, &document);

	if (parser == NULL)
		return svgtiny_LIBDOM_ERROR;

	err = dom_xml_parser_parse_chunk(parser, (uint8_t *)buffer, size);
	if (err != DOM_XML_OK) {
		dom_node_unref(document);
		dom_xml_parser_destroy(parser);
		return svgtiny_LIBDOM_ERROR;
	}

	err = dom_xml_parser_completed(parser);
	if (err != DOM_XML_OK) {
		dom_node_unref(document);
		dom_xml_parser_destroy(parser);
		return svgtiny_LIBDOM_ERROR;
	}

	/* We're done parsing, drop the parser.
	 * We now own the document entirely.
	 */
	dom_xml_parser_destroy(parser);

	/* find root <svg> element */
	exc = dom_document_get_document_element(document, &svg);
	if (exc != DOM_NO_ERR) {
		dom_node_unref(document);
		return svgtiny_LIBDOM_ERROR;
	}
	exc = dom_node_get_node_name(svg, &svg_name);
	if (exc != DOM_NO_ERR) {
		dom_node_unref(svg);
		dom_node_unref(document);
		return svgtiny_LIBDOM_ERROR;
	}
	if (lwc_intern_string("svg", 3 /* SLEN("svg") */,
			      &svg_name_lwc) != lwc_error_ok) {
		dom_string_unref(svg_name);
		dom_node_unref(svg);
		dom_node_unref(document);
		return svgtiny_LIBDOM_ERROR;
	}
	if (!dom_string_caseless_lwc_isequal(svg_name, svg_name_lwc)) {
		lwc_string_unref(svg_name_lwc);
		dom_string_unref(svg_name);
		dom_node_unref(svg);
		dom_node_unref(document);
		return svgtiny_NOT_SVG;
	}

	dom_node_unref(svg);
	lwc_string_unref(svg_name_lwc);
	dom_string_unref(svg_name);

    *output_dom = document;
    return svgtiny_OK;
}
예제 #28
0
svgtiny_code svgtiny_parse_text(dom_element *text,
		struct svgtiny_parse_state state)
{
	float x, y, width, height;
	float px, py;
	dom_node *child;
	dom_exception exc;

	svgtiny_setup_state_local(&state);

	svgtiny_parse_position_attributes(text, state,
			&x, &y, &width, &height);
	svgtiny_parse_font_attributes(text, &state);
	svgtiny_parse_transform_attributes(text, &state);

	px = state.ctm.a * x + state.ctm.c * y + state.ctm.e;
	py = state.ctm.b * x + state.ctm.d * y + state.ctm.f;
/* 	state.ctm.e = px - state.origin_x; */
/* 	state.ctm.f = py - state.origin_y; */

	/*struct css_style style = state.style;
	style.font_size.value.length.value *= state.ctm.a;*/
	
        exc = dom_node_get_first_child(text, &child);
	if (exc != DOM_NO_ERR) {
		return svgtiny_LIBDOM_ERROR;
		svgtiny_cleanup_state_local(&state);
	}
	while (child != NULL) {
		dom_node *next;
		dom_node_type nodetype;
		svgtiny_code code = svgtiny_OK;

		exc = dom_node_get_node_type(child, &nodetype);
		if (exc != DOM_NO_ERR) {
			dom_node_unref(child);
			svgtiny_cleanup_state_local(&state);
			return svgtiny_LIBDOM_ERROR;
		}
		if (nodetype == DOM_ELEMENT_NODE) {
			dom_string *nodename;
			exc = dom_node_get_node_name(child, &nodename);
			if (exc != DOM_NO_ERR) {
				dom_node_unref(child);
				svgtiny_cleanup_state_local(&state);
				return svgtiny_LIBDOM_ERROR;
			}
			if (dom_string_caseless_isequal(nodename,
							state.interned_tspan))
				code = svgtiny_parse_text((dom_element *)child,
							  state);
			dom_string_unref(nodename);
		} else if (nodetype == DOM_TEXT_NODE) {
			struct svgtiny_shape *shape = svgtiny_add_shape(&state);
			dom_string *content;
			if (shape == NULL) {
				dom_node_unref(child);
				svgtiny_cleanup_state_local(&state);
				return svgtiny_OUT_OF_MEMORY;
			}
			exc = dom_text_get_whole_text(child, &content);
			if (exc != DOM_NO_ERR) {
				dom_node_unref(child);
				svgtiny_cleanup_state_local(&state);
				return svgtiny_LIBDOM_ERROR;
			}
			if (content != NULL) {
				shape->text = strndup(dom_string_data(content),
						      dom_string_byte_length(content));
				dom_string_unref(content);
			} else {
				shape->text = strdup("");
			}
			shape->text_x = px;
			shape->text_y = py;
			state.diagram->shape_count++;
		}

		if (code != svgtiny_OK) {
			dom_node_unref(child);
			svgtiny_cleanup_state_local(&state);
			return code;
		}
		exc = dom_node_get_next_sibling(child, &next);
		dom_node_unref(child);
		if (exc != DOM_NO_ERR) {
			svgtiny_cleanup_state_local(&state);
			return svgtiny_LIBDOM_ERROR;
		}
		child = next;
	}

	svgtiny_cleanup_state_local(&state);

	return svgtiny_OK;
}
예제 #29
0
static struct form_control *
parse_input_element(struct form *forms, dom_html_input_element *input)
{
	struct form_control *control = NULL;
	dom_html_form_element *form = NULL;
	dom_string *ds_type = NULL;
	dom_string *ds_name = NULL;
	dom_string *ds_value = NULL;

	char *name = NULL;

	if (dom_html_input_element_get_form(input, &form) != DOM_NO_ERR)
		goto out;

	if (dom_html_input_element_get_type(input, &ds_type) != DOM_NO_ERR)
		goto out;

	if (dom_html_input_element_get_name(input, &ds_name) != DOM_NO_ERR)
		goto out;

	if (ds_name != NULL)
		name = strndup(dom_string_data(ds_name),
			       dom_string_byte_length(ds_name));

	if (ds_type != NULL && dom_string_caseless_lwc_isequal(ds_type,
			corestring_lwc_password)) {
		control = form_new_control(input, GADGET_PASSWORD);
	} else if (ds_type != NULL && dom_string_caseless_lwc_isequal(ds_type,
			corestring_lwc_file)) {
		control = form_new_control(input, GADGET_FILE);
	} else if (ds_type != NULL && dom_string_caseless_lwc_isequal(ds_type,
			corestring_lwc_hidden)) {
		control = form_new_control(input, GADGET_HIDDEN);
	} else if (ds_type != NULL && dom_string_caseless_lwc_isequal(ds_type,
			corestring_lwc_checkbox)) {
		control = form_new_control(input, GADGET_CHECKBOX);
	} else if (ds_type != NULL && dom_string_caseless_lwc_isequal(ds_type,
			corestring_lwc_radio)) {
		control = form_new_control(input, GADGET_RADIO);
	} else if (ds_type != NULL && dom_string_caseless_lwc_isequal(ds_type,
			corestring_lwc_submit)) {
		control = form_new_control(input, GADGET_SUBMIT);
	} else if (ds_type != NULL && dom_string_caseless_lwc_isequal(ds_type,
			corestring_lwc_reset)) {
		control = form_new_control(input, GADGET_RESET);
	} else if (ds_type != NULL && dom_string_caseless_lwc_isequal(ds_type,
			corestring_lwc_button)) {
		control = form_new_control(input, GADGET_BUTTON);
	} else if (ds_type != NULL && dom_string_caseless_lwc_isequal(ds_type,
			corestring_lwc_image)) {
		control = form_new_control(input, GADGET_IMAGE);
	} else {
		control = form_new_control(input, GADGET_TEXTBOX);
	}

	if (control == NULL)
		goto out;

	if (name != NULL) {
		/* Hand the name string over */
		control->name = name;
		name = NULL;
	}

	if (control->type == GADGET_CHECKBOX || control->type == GADGET_RADIO) {
		bool selected;
		if (dom_html_input_element_get_checked(
			    input, &selected) == DOM_NO_ERR) {
			control->selected = selected;
		}
	}

	if (control->type == GADGET_PASSWORD ||
	    control->type == GADGET_TEXTBOX) {
		int32_t maxlength;
		if (dom_html_input_element_get_max_length(
			    input, &maxlength) != DOM_NO_ERR) {
			maxlength = -1;
		}

		if (maxlength >= 0) {
			/* Got valid maxlength */
			control->maxlength = maxlength;
		} else {
			/* Input has no maxlength attr, or
			 * dom_html_input_element_get_max_length failed.
			 *
			 * Set it to something insane. */
			control->maxlength = UINT_MAX;
		}
	}

	if (control->type != GADGET_FILE && control->type != GADGET_IMAGE) {
		if (dom_html_input_element_get_value(
			    input, &ds_value) == DOM_NO_ERR) {
			if (ds_value != NULL) {
				control->value = strndup(
					dom_string_data(ds_value),
					dom_string_byte_length(ds_value));
				if (control->value == NULL) {
					form_free_control(control);
					control = NULL;
					goto out;
				}
				control->length = strlen(control->value);
			}
		}

		if (control->type == GADGET_TEXTBOX ||
				control->type == GADGET_PASSWORD) {
			if (control->value == NULL) {
				control->value = strdup("");
				if (control->value == NULL) {
					form_free_control(control);
					control = NULL;
					goto out;
				}

				control->length = 0;
			}

			control->initial_value = strdup(control->value);
			if (control->initial_value == NULL) {
				form_free_control(control);
				control = NULL;
				goto out;
			}
		}
	}

	if (form != NULL && control != NULL)
		form_add_control(find_form(forms, form), control);

out:
	if (form != NULL)
		dom_node_unref(form);
	if (ds_type != NULL)
		dom_string_unref(ds_type);
	if (ds_name != NULL)
		dom_string_unref(ds_name);
	if (ds_value != NULL)
		dom_string_unref(ds_value);

	if (name != NULL)
		free(name);

	return control;
}
예제 #30
0
void binding_destroy_document(dom_document *doc)
{
	dom_node_unref(doc);
}