/** * Dispatch a DOMNodeInsertedIntoDocument/DOMNodeRemovedFromDocument event * * \param doc The document object * \param et The EventTarget object * \param type "DOMNodeInserted" or "DOMNodeRemoved" * \param success Whether this event's default action get called * \return DOM_NO_ERR on success, appropriate dom_exception on failure. */ dom_exception __dom_dispatch_node_change_document_event(dom_document *doc, dom_event_target *et, dom_mutation_type change, bool *success) { struct dom_mutation_event *evt; dom_string *type = NULL; dom_exception err; err = _dom_mutation_event_create(doc, &evt); if (err != DOM_NO_ERR) return err; if (change == DOM_MUTATION_ADDITION) { type = dom_string_ref(doc->_memo_domnodeinsertedintodocument); } else if (change == DOM_MUTATION_REMOVAL) { type = dom_string_ref(doc->_memo_domnoderemovedfromdocument); } else { assert("Should never be here" == NULL); } /* Initialise the event with corresponding parameters */ err = dom_mutation_event_init(evt, type, true, false, NULL, NULL, NULL, NULL, change); dom_string_unref(type); if (err != DOM_NO_ERR) goto cleanup; err = dom_event_target_dispatch_event(et, evt, success); if (err != DOM_NO_ERR) goto cleanup; cleanup: _dom_mutation_event_destroy(evt); return err; }
/** * Set the local externally-stored parts of a parse state. * Call this in functions that made a new state on the stack. * Doesn't make own copy of global state, such as the interned string list. */ static void svgtiny_setup_state_local(struct svgtiny_parse_state *state) { if (state->gradient_x1 != NULL) { dom_string_ref(state->gradient_x1); } if (state->gradient_y1 != NULL) { dom_string_ref(state->gradient_y1); } if (state->gradient_x2 != NULL) { dom_string_ref(state->gradient_x2); } if (state->gradient_y2 != NULL) { dom_string_ref(state->gradient_y2); } }
/* create new html script entry */ static struct html_script * html_process_new_script(html_content *c, dom_string *mimetype, enum html_script_type type) { struct html_script *nscript; /* add space for new script entry */ nscript = realloc(c->scripts, sizeof(struct html_script) * (c->scripts_count + 1)); if (nscript == NULL) { return NULL; } c->scripts = nscript; /* increment script entry count */ nscript = &c->scripts[c->scripts_count]; c->scripts_count++; nscript->already_started = false; nscript->parser_inserted = false; nscript->force_async = true; nscript->ready_exec = false; nscript->async = false; nscript->defer = false; nscript->type = type; nscript->mimetype = dom_string_ref(mimetype); /* reference mimetype */ return nscript; }
/** * Get the internal data of this event * * \param evt The Event object * \param data The internal data of this Event * \return DOM_NO_ERR. */ dom_exception _dom_text_event_get_data(dom_text_event *evt, dom_string **data) { *data = evt->data; dom_string_ref(*data); return DOM_NO_ERR; }
/** * Initialise the TextEvent * * \param evt The Event object * \param type The type of this UIEvent * \param bubble Whether this event can bubble * \param cancelable Whether this event is cancelable * \param view The AbstractView of this UIEvent * \param data The text data * \return DOM_NO_ERR on success, appropriate dom_exception on failure. */ dom_exception _dom_text_event_init(dom_text_event *evt, dom_string *type, bool bubble, bool cancelable, struct dom_abstract_view *view, dom_string *data) { evt->data = data; dom_string_ref(data); return _dom_ui_event_init(&evt->base, type, bubble, cancelable, view, 0); }
/* The virtual function used to parse attribute value, see src/core/element.c * for detail */ dom_exception _dom_html_base_element_parse_attribute(dom_element *ele, dom_string *name, dom_string *value, dom_string **parsed) { UNUSED(ele); UNUSED(name); dom_string_ref(value); *parsed = value; return DOM_NO_ERR; }
/** * process script node parser callback * * */ dom_hubbub_error html_process_script(void *ctx, dom_node *node) { html_content *c = (html_content *)ctx; dom_exception exc; /* returned by libdom functions */ dom_string *src, *mimetype; dom_hubbub_error err = DOM_HUBBUB_OK; /* ensure javascript context is available */ if (c->jscontext == NULL) { union content_msg_data msg_data; msg_data.jscontext = &c->jscontext; content_broadcast(&c->base, CONTENT_MSG_GETCTX, msg_data); LOG(("javascript context %p ", c->jscontext)); if (c->jscontext == NULL) { /* no context and it could not be created, abort */ return DOM_HUBBUB_OK; } } LOG(("content %p parser %p node %p", c, c->parser, node)); exc = dom_element_get_attribute(node, corestring_dom_type, &mimetype); if (exc != DOM_NO_ERR || mimetype == NULL) { mimetype = dom_string_ref(corestring_dom_text_javascript); } exc = dom_element_get_attribute(node, corestring_dom_src, &src); if (exc != DOM_NO_ERR || src == NULL) { err = exec_inline_script(c, node, mimetype); } else { err = exec_src_script(c, node, mimetype, src); dom_string_unref(src); } dom_string_unref(mimetype); return err; }
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); }
/* exported function documented in string.h */ dom_exception dom_string_whitespace_op(dom_string *s, enum dom_whitespace_op op, dom_string **ret) { const uint8_t *src_text = (const uint8_t *) dom_string_data(s); size_t len = dom_string_byte_length(s); const uint8_t *src_pos; const uint8_t *src_end; dom_exception exc; uint8_t *temp_pos; uint8_t *temp; if (len == 0) { *ret = dom_string_ref(s); } temp = malloc(len); if (temp == NULL) { return DOM_NO_MEM_ERR; } src_pos = src_text; src_end = src_text + len; temp_pos = temp; if (op & DOM_WHITESPACE_STRIP_LEADING) { while (src_pos < src_end) { if (*src_pos == ' ' || *src_pos == '\t' || *src_pos == '\n' || *src_pos == '\r' || *src_pos == '\f') src_pos++; else break; } } while (src_pos < src_end) { if ((op & DOM_WHITESPACE_COLLAPSE) && (*src_pos == ' ' || *src_pos == '\t' || *src_pos == '\n' || *src_pos == '\r' || *src_pos == '\f')) { /* Got a whitespace character */ do { /* Skip all adjacent whitespace */ src_pos++; } while (src_pos < src_end && (*src_pos == ' ' || *src_pos == '\t' || *src_pos == '\n' || *src_pos == '\r' || *src_pos == '\f')); /* Gets replaced with single space in output */ *temp_pos++ = ' '; } else { /* Otherwise, copy to output */ *temp_pos++ = *src_pos++; } } if (op & DOM_WHITESPACE_STRIP_TRAILING) { while (temp_pos > temp) { temp_pos--; if (*temp_pos != ' ' && *temp_pos != '\t' && *temp_pos != '\n' && *temp_pos != '\r' && *temp_pos != '\f') { temp_pos++; break; } } } /* New length */ len = temp_pos - temp; /* Make new string */ if (((dom_string_internal *) s)->type == DOM_STRING_CDATA) { exc = dom_string_create(temp, len, ret); } else { exc = dom_string_create_interned(temp, len, ret); } free(temp); return exc; }
/** * Adds an imagemap entry to the list * * \param c The html content that the imagemap belongs to * \param n The xmlNode representing the entry to add * \param base_url Base URL for resolving relative URLs * \param entry Pointer to list of entries * \param tagtype The type of tag * \return false on memory exhaustion, true otherwise */ static bool imagemap_addtolist(const struct html_content *c, dom_node *n, nsurl *base_url, struct mapentry **entry, dom_string *tagtype) { dom_exception exc; dom_string *href = NULL, *target = NULL, *shape = NULL; dom_string *coords = NULL; struct mapentry *new_map, *temp; bool ret = true; if (dom_string_caseless_isequal(tagtype, corestring_dom_area)) { bool nohref = false; exc = dom_element_has_attribute(n, corestring_dom_nohref, &nohref); if ((exc != DOM_NO_ERR) || nohref) /* Skip <area nohref="anything" /> */ goto ok_out; } exc = dom_element_get_attribute(n, corestring_dom_href, &href); if (exc != DOM_NO_ERR || href == NULL) { /* No href="" attribute, skip this element */ goto ok_out; } exc = dom_element_get_attribute(n, corestring_dom_target, &target); if (exc != DOM_NO_ERR) { goto ok_out; } exc = dom_element_get_attribute(n, corestring_dom_shape, &shape); if (exc != DOM_NO_ERR) { goto ok_out; } /* If there's no shape, we default to rectangles */ if (shape == NULL) shape = dom_string_ref(corestring_dom_rect); if (!dom_string_caseless_lwc_isequal(shape, corestring_lwc_default)) { /* If not 'default' and there's no 'coords' give up */ exc = dom_element_get_attribute(n, corestring_dom_coords, &coords); if (exc != DOM_NO_ERR || coords == NULL) { goto ok_out; } } new_map = calloc(1, sizeof(*new_map)); if (new_map == NULL) { goto bad_out; } if (dom_string_caseless_lwc_isequal(shape, corestring_lwc_rect) || dom_string_caseless_lwc_isequal(shape, corestring_lwc_rectangle)) new_map->type = IMAGEMAP_RECT; else if (dom_string_caseless_lwc_isequal(shape, corestring_lwc_circle)) new_map->type = IMAGEMAP_CIRCLE; else if (dom_string_caseless_lwc_isequal(shape, corestring_lwc_poly) || dom_string_caseless_lwc_isequal(shape, corestring_lwc_polygon)) new_map->type = IMAGEMAP_POLY; else if (dom_string_caseless_lwc_isequal(shape, corestring_lwc_default)) new_map->type = IMAGEMAP_DEFAULT; else goto bad_out; if (box_extract_link(c, href, base_url, &new_map->url) == false) goto bad_out; if (new_map->url == NULL) { /* non-fatal error -> ignore this */ goto ok_free_map_out; } if (target != NULL) { /* Copy target into the map */ new_map->target = malloc(dom_string_byte_length(target) + 1); if (new_map->target == NULL) goto bad_out; /* Safe, but relies on dom_strings being NULL terminated */ /* \todo Do this better */ strcpy(new_map->target, dom_string_data(target)); } if (new_map->type != IMAGEMAP_DEFAULT) { int x, y; float *xcoords, *ycoords; /* coordinates are a comma-separated list of values */ char *val = strtok((char *)dom_string_data(coords), ","); int num = 1; switch (new_map->type) { case IMAGEMAP_RECT: /* (left, top, right, bottom) */ while (val != NULL && num <= 4) { switch (num) { case 1: new_map->bounds.rect.x0 = atoi(val); break; case 2: new_map->bounds.rect.y0 = atoi(val); break; case 3: new_map->bounds.rect.x1 = atoi(val); break; case 4: new_map->bounds.rect.y1 = atoi(val); break; } num++; val = strtok(NULL, ","); } break; case IMAGEMAP_CIRCLE: /* (x, y, radius ) */ while (val != NULL && num <= 3) { switch (num) { case 1: new_map->bounds.circle.x = atoi(val); break; case 2: new_map->bounds.circle.y = atoi(val); break; case 3: new_map->bounds.circle.r = atoi(val); break; } num++; val = strtok(NULL, ","); } break; case IMAGEMAP_POLY: new_map->bounds.poly.xcoords = NULL; new_map->bounds.poly.ycoords = NULL; while (val != NULL) { x = atoi(val); val = strtok(NULL, ","); if (val == NULL) break; y = atoi(val); xcoords = realloc(new_map->bounds.poly.xcoords, num * sizeof(float)); if (xcoords == NULL) { goto bad_out; } new_map->bounds.poly.xcoords = xcoords; ycoords = realloc(new_map->bounds.poly.ycoords, num * sizeof(float)); if (ycoords == NULL) { goto bad_out; } new_map->bounds.poly.ycoords = ycoords; new_map->bounds.poly.xcoords[num - 1] = x; new_map->bounds.poly.ycoords[num - 1] = y; num++; val = strtok(NULL, ","); } new_map->bounds.poly.num = num - 1; break; default: break; } } new_map->next = NULL; if (*entry) { /* add to END of list */ for (temp = (*entry); temp->next != NULL; temp = temp->next) ; temp->next = new_map; } else { (*entry) = new_map; } /* All good, linked in, let's clean up */ goto ok_out; bad_out: ret = false; ok_free_map_out: if (new_map != NULL) { if (new_map->url != NULL) nsurl_unref(new_map->url); if (new_map->type == IMAGEMAP_POLY && new_map->bounds.poly.ycoords != NULL) free(new_map->bounds.poly.ycoords); if (new_map->type == IMAGEMAP_POLY && new_map->bounds.poly.xcoords != NULL) free(new_map->bounds.poly.xcoords); if (new_map->target != NULL) free(new_map->target); free(new_map); } ok_out: if (href != NULL) dom_string_unref(href); if (target != NULL) dom_string_unref(target); if (shape != NULL) dom_string_unref(shape); if (coords != NULL) dom_string_unref(coords); return ret; }