/* exported interface documented in render/html_internal.h */ nserror html_css_quirks_stylesheets(html_content *c) { nserror ns_error = NSERROR_OK; hlcache_child_context child; assert(c->stylesheets != NULL); if (c->quirks == DOM_DOCUMENT_QUIRKS_MODE_FULL) { child.charset = c->encoding; child.quirks = c->base.quirks; ns_error = hlcache_handle_retrieve(html_quirks_stylesheet_url, 0, content_get_url(&c->base), NULL, html_convert_css_callback, c, &child, CONTENT_CSS, &c->stylesheets[STYLESHEET_QUIRKS].sheet); if (ns_error != NSERROR_OK) { return ns_error; } c->base.active++; LOG("%d fetches active", c->base.active); } return ns_error; }
bool save_complete_inventory(const char *path, struct save_complete_entry *list) { char urlpath[256]; FILE *fp; char *pathstring, *standardpath = (path[0] == '/') ? (char *)(path + 1) : (char *)path; struct save_complete_entry *entry; snprintf(urlpath, sizeof urlpath, "file:///%s/Inventory", standardpath); pathstring = url_to_path(urlpath); if (pathstring == NULL) { warn_user("NoMemory", 0); return false; } fp = fopen(pathstring, "w"); free(pathstring); if (!fp) { LOG(("fopen(): errno = %i", errno)); warn_user("SaveError", strerror(errno)); return false; } for (entry = list; entry; entry = entry->next) { fprintf(fp, "%p %s\n", entry->content, content_get_url(entry->content)); } fclose(fp); return true; }
void ro_gui_save_prepare(gui_save_type save_type, hlcache_handle *h, struct selection *s, const char *url, const char *title) { char name_buf[FILENAME_MAX]; size_t leaf_offset = 0; char icon_buf[20]; assert( (save_type == GUI_SAVE_LINK_URI) || (save_type == GUI_SAVE_LINK_URL) || (save_type == GUI_SAVE_LINK_TEXT) || (save_type == GUI_SAVE_HOTLIST_EXPORT_HTML) || (save_type == GUI_SAVE_HISTORY_EXPORT_HTML) || (save_type == GUI_SAVE_TEXT_SELECTION) || h); gui_save_selection = s; gui_save_url = url; gui_save_title = title; if (save_dir) { leaf_offset = save_dir_len; memcpy(name_buf, save_dir, leaf_offset); name_buf[leaf_offset++] = '.'; } ro_gui_save_set_state(h, save_type, h ? content_get_url(h) : url, name_buf + leaf_offset, icon_buf); ro_gui_set_icon_sprite(dialog_saveas, ICON_SAVE_ICON, saveas_area, icon_buf); ro_gui_set_icon_string(dialog_saveas, ICON_SAVE_PATH, name_buf, true); ro_gui_wimp_event_memorise(dialog_saveas); }
void gui_drag_save_object(gui_save_type save_type, hlcache_handle *c, struct gui_window *g) { wimp_pointer pointer; char icon_buf[20]; os_error *error; /* Close the save window because otherwise we need two contexts */ xwimp_create_menu(wimp_CLOSE_MENU, 0, 0); ro_gui_dialog_close(dialog_saveas); gui_save_sourcew = g->window; saving_from_dialog = false; error = xwimp_get_pointer_info(&pointer); if (error) { LOG(("xwimp_get_pointer_info: 0x%x: %s", error->errnum, error->errmess)); warn_user("WimpError", error->errmess); return; } ro_gui_save_set_state(c, save_type, content_get_url(c), save_leafname, icon_buf); gui_current_drag_type = GUI_DRAG_SAVE; ro_gui_drag_icon(pointer.pos.x, pointer.pos.y, icon_buf); }
/** * Initialise a CSS content * * \param c Content to initialise * \param params Content-Type parameters * \return true on success, false on failure */ nserror nscss_create(const content_handler *handler, lwc_string *imime_type, const http_parameter *params, llcache_handle *llcache, const char *fallback_charset, bool quirks, struct content **c) { nscss_content *result; const char *charset = NULL; const char *xnsbase = NULL; lwc_string *charset_value = NULL; union content_msg_data msg_data; nserror error; result = calloc(1, sizeof(nscss_content)); if (result == NULL) return NSERROR_NOMEM; error = content__init(&result->base, handler, imime_type, params, llcache, fallback_charset, quirks); if (error != NSERROR_OK) { free(result); return error; } /* Find charset specified on HTTP layer, if any */ error = http_parameter_list_find_item(params, css_charset, &charset_value); if (error != NSERROR_OK || lwc_string_length(charset_value) == 0) { /* No charset specified, use fallback, if any */ /** \todo libcss will take this as gospel, which is wrong */ charset = fallback_charset; } else { charset = lwc_string_data(charset_value); } /* Compute base URL for stylesheet */ xnsbase = llcache_handle_get_header(llcache, "X-NS-Base"); if (xnsbase == NULL) { xnsbase = nsurl_access(content_get_url(&result->base)); } error = nscss_create_css_data(&result->data, xnsbase, charset, result->base.quirks, nscss_content_done, result); if (error != NSERROR_OK) { msg_data.error = messages_get("NoMemory"); content_broadcast(&result->base, CONTENT_MSG_ERROR, msg_data); if (charset_value != NULL) lwc_string_unref(charset_value); free(result); return error; } if (charset_value != NULL) lwc_string_unref(charset_value); *c = (struct content *) result; return NSERROR_OK; }
hlcache_handle * save_complete_list_find(const char *url, struct save_complete_entry *list) { struct save_complete_entry *entry; for (entry = list; entry; entry = entry->next) if (strcmp(url, content_get_url(entry->content)) == 0) return entry->content; return 0; }
static nserror html_stylesheet_from_domnode(html_content *c, dom_node *node, hlcache_handle **sheet) { hlcache_child_context child; dom_string *style; nsurl *url; dom_exception exc; nserror error; uint32_t key; char urlbuf[64]; child.charset = c->encoding; child.quirks = c->base.quirks; exc = dom_node_get_text_content(node, &style); if ((exc != DOM_NO_ERR) || (style == NULL)) { LOG("No text content"); return NSERROR_OK; } error = html_css_fetcher_add_item(style, c->base_url, &key); if (error != NSERROR_OK) { dom_string_unref(style); return error; } dom_string_unref(style); snprintf(urlbuf, sizeof(urlbuf), "x-ns-css:%u", key); error = nsurl_create(urlbuf, &url); if (error != NSERROR_OK) { return error; } error = hlcache_handle_retrieve(url, 0, content_get_url(&c->base), NULL, html_convert_css_callback, c, &child, CONTENT_CSS, sheet); if (error != NSERROR_OK) { nsurl_unref(url); return error; } nsurl_unref(url); c->base.active++; LOG("%d fetches active", c->base.active); return NSERROR_OK; }
/** * Save stylesheets imported by a CONTENT_CSS. * * \param imports Array of imports * \param count Number of imports in list * \param path Path to save to * \return true on success, false on error and error reported */ bool save_imported_sheets(struct nscss_import *imports, uint32_t count, const char *path, struct save_complete_entry **list) { char filename[256]; unsigned int j; char *source; int source_len; bool res; for (j = 0; j != count; j++) { hlcache_handle *css = imports[j].c; const char *css_data; unsigned long css_size; struct nscss_import *child_imports; uint32_t child_import_count; if (css == NULL) continue; if (save_complete_list_check(css, *list)) continue; if (!save_complete_list_add(css, list)) { warn_user("NoMemory", 0); return false; } child_imports = nscss_get_imports(css, &child_import_count); if (!save_imported_sheets(child_imports, child_import_count, path, list)) return false; snprintf(filename, sizeof filename, "%p", css); css_data = content_get_source_data(css, &css_size); source = rewrite_stylesheet_urls(css_data, css_size, &source_len, content_get_url(css), *list); if (!source) { warn_user("NoMemory", 0); return false; } res = save_complete_gui_save(path, filename, source_len, source, CONTENT_CSS); free(source); if (res == false) return false; } return true; }
nserror nscss_clone(const struct content *old, struct content **newc) { const nscss_content *old_css = (const nscss_content *) old; nscss_content *new_css; const char *data; unsigned long size; nserror error; new_css = calloc(1, sizeof(nscss_content)); if (new_css == NULL) return NSERROR_NOMEM; /* Clone content */ error = content__clone(old, &new_css->base); if (error != NSERROR_OK) { content_destroy(&new_css->base); return error; } /* Simply replay create/process/convert */ error = nscss_create_css_data(&new_css->data, nsurl_access(content_get_url(&new_css->base)), old_css->data.charset, new_css->base.quirks, nscss_content_done, new_css); if (error != NSERROR_OK) { content_destroy(&new_css->base); return error; } data = content__get_source_data(&new_css->base, &size); if (size > 0) { if (nscss_process_data(&new_css->base, data, size) == false) { content_destroy(&new_css->base); return NSERROR_CLONE_FAILED; } } if (old->status == CONTENT_STATUS_READY || old->status == CONTENT_STATUS_DONE) { if (nscss_convert(&new_css->base) == false) { content_destroy(&new_css->base); return NSERROR_CLONE_FAILED; } } *newc = (struct content *) new_css; return NSERROR_OK; }
/* exported interface documented in render/html_internal.h */ bool html_fetch_object(html_content *c, nsurl *url, struct box *box, content_type permitted_types, int available_width, int available_height, bool background) { struct content_html_object *object; hlcache_child_context child; nserror error; /* If we've already been aborted, don't bother attempting the fetch */ if (c->aborted) return true; child.charset = c->encoding; child.quirks = c->base.quirks; object = calloc(1, sizeof(struct content_html_object)); if (object == NULL) { return false; } object->parent = (struct content *) c; object->next = NULL; object->content = NULL; object->box = box; object->permitted_types = permitted_types; object->background = background; error = hlcache_handle_retrieve(url, HLCACHE_RETRIEVE_SNIFF_TYPE, content_get_url(&c->base), NULL, html_object_callback, object, &child, object->permitted_types, &object->content); if (error != NSERROR_OK) { free(object); return error != NSERROR_NOMEM; } /* add to content object list */ object->next = c->object_list; c->object_list = object; c->num_objects++; if (box != NULL) { c->base.active++; LOG("%d fetches active", c->base.active); } return true; }
static bool html_replace_object(struct content_html_object *object, nsurl *url) { html_content *c; hlcache_child_context child; html_content *page; nserror error; assert(object != NULL); assert(object->box != NULL); c = (html_content *) object->parent; child.charset = c->encoding; child.quirks = c->base.quirks; if (object->content != NULL) { /* remove existing object */ if (content_get_status(object->content) != CONTENT_STATUS_DONE) { c->base.active--; LOG("%d fetches active", c->base.active); } hlcache_handle_release(object->content); object->content = NULL; object->box->object = NULL; } /* initialise fetch */ error = hlcache_handle_retrieve(url, HLCACHE_RETRIEVE_SNIFF_TYPE, content_get_url(&c->base), NULL, html_object_callback, object, &child, object->permitted_types, &object->content); if (error != NSERROR_OK) return false; for (page = c; page != NULL; page = page->page) { page->base.active++; LOG("%d fetches active", c->base.active); page->base.status = CONTENT_STATUS_READY; } return true; }
void ami_print(struct hlcache_handle *c, int copies) { double height, print_height; float scale = option_print_scale / 100.0; if(!ami_print_info.msgport) return; if(!(ami_print_info.PReq = (struct IODRPTagsReq *)AllocSysObjectTags(ASOT_IOREQUEST, ASOIOR_Size, sizeof(struct IODRPTagsReq), ASOIOR_ReplyPort, ami_print_info.msgport, ASO_NoTrack, FALSE, TAG_DONE))) return; if(OpenDevice("printer.device", option_printer_unit, (struct IORequest *)ami_print_info.PReq, 0)) { warn_user("CompError","printer.device"); return; } ami_print_info.PD = (struct PrinterData *)ami_print_info.PReq->io_Device; ami_print_info.PED = &ami_print_info.PD->pd_SegmentData->ps_PED; ami_print_info.ps = print_make_settings(PRINT_DEFAULT, content_get_url(c), &nsfont); ami_print_info.ps->page_width = ami_print_info.PED->ped_MaxXDots; ami_print_info.ps->page_height = ami_print_info.PED->ped_MaxYDots; ami_print_info.ps->scale = scale; if(!print_set_up(c, &amiprinter, ami_print_info.ps, &height)) { warn_user("PrintError","print_set_up() returned false"); ami_print_close_device(); return; } height *= ami_print_info.ps->scale; ami_print_info.pages = height / ami_print_info.ps->page_height; ami_print_info.c = c; ami_print_progress(); while(ami_print_cont()); /* remove while() for async printing */ }
static void svg_reformat(struct content *c, int width, int height) { svg_content *svg = (svg_content *) c; const char *source_data; unsigned long source_size; assert(svg->diagram); /* Avoid reformats to same width/height as we already reformatted to */ if (width != svg->current_width || height != svg->current_height) { source_data = content__get_source_data(c, &source_size); svgtiny_parse(svg->diagram, source_data, source_size, nsurl_access(content_get_url(c)), width, height); svg->current_width = width; svg->current_height = height; } c->width = svg->diagram->width; c->height = svg->diagram->height; }
void html_mouse_action(struct content *c, struct browser_window *bw, browser_mouse_state mouse, int x, int y) { html_content *html = (html_content *) c; enum { ACTION_NONE, ACTION_SUBMIT, ACTION_GO } action = ACTION_NONE; const char *title = 0; nsurl *url = 0; const char *target = 0; char status_buffer[200]; const char *status = 0; browser_pointer_shape pointer = BROWSER_POINTER_DEFAULT; bool imagemap = false; int box_x = 0, box_y = 0; int gadget_box_x = 0, gadget_box_y = 0; int html_object_pos_x = 0, html_object_pos_y = 0; int text_box_x = 0; struct box *url_box = 0; struct box *gadget_box = 0; struct box *text_box = 0; struct box *box; struct form_control *gadget = 0; hlcache_handle *object = NULL; struct box *html_object_box = NULL; struct browser_window *iframe = NULL; struct box *next_box; struct box *drag_candidate = NULL; struct scrollbar *scrollbar = NULL; plot_font_style_t fstyle; int scroll_mouse_x = 0, scroll_mouse_y = 0; int padding_left, padding_right, padding_top, padding_bottom; browser_drag_type drag_type = browser_window_get_drag_type(bw); union content_msg_data msg_data; struct dom_node *node = NULL; if (drag_type != DRAGGING_NONE && !mouse && html->visible_select_menu != NULL) { /* drag end: select menu */ form_select_mouse_drag_end(html->visible_select_menu, mouse, x, y); } if (html->visible_select_menu != NULL) { box = html->visible_select_menu->box; box_coords(box, &box_x, &box_y); box_x -= box->border[LEFT].width; box_y += box->height + box->border[BOTTOM].width + box->padding[BOTTOM] + box->padding[TOP]; status = form_select_mouse_action(html->visible_select_menu, mouse, x - box_x, y - box_y); if (status != NULL) { msg_data.explicit_status_text = status; content_broadcast(c, CONTENT_MSG_STATUS, msg_data); } else { int width, height; form_select_get_dimensions(html->visible_select_menu, &width, &height); html->visible_select_menu = NULL; browser_window_redraw_rect(bw, box_x, box_y, width, height); } return; } if (!mouse && html->scrollbar != NULL) { /* drag end: scrollbar */ html_overflow_scroll_drag_end(html->scrollbar, mouse, x, y); } if (html->scrollbar != NULL) { struct html_scrollbar_data *data = scrollbar_get_data(html->scrollbar); box = data->box; box_coords(box, &box_x, &box_y); if (scrollbar_is_horizontal(html->scrollbar)) { scroll_mouse_x = x - box_x ; scroll_mouse_y = y - (box_y + box->padding[TOP] + box->height + box->padding[BOTTOM] - SCROLLBAR_WIDTH); status = scrollbar_mouse_action(html->scrollbar, mouse, scroll_mouse_x, scroll_mouse_y); } else { scroll_mouse_x = x - (box_x + box->padding[LEFT] + box->width + box->padding[RIGHT] - SCROLLBAR_WIDTH); scroll_mouse_y = y - box_y; status = scrollbar_mouse_action(html->scrollbar, mouse, scroll_mouse_x, scroll_mouse_y); } msg_data.explicit_status_text = status; content_broadcast(c, CONTENT_MSG_STATUS, msg_data); return; } /* Content related drags handled by now */ browser_window_set_drag_type(bw, DRAGGING_NONE, NULL); /* search the box tree for a link, imagemap, form control, or * box with scrollbars */ box = html->layout; /* Consider the margins of the html page now */ box_x = box->margin[LEFT]; box_y = box->margin[TOP]; /* descend through visible boxes setting more specific values for: * box - deepest box at point * html_object_box - html object * html_object_pos_x - html object * html_object_pos_y - html object * object - non html object * iframe - iframe * url - href or imagemap * target - href or imagemap or gadget * url_box - href or imagemap * imagemap - imagemap * gadget - gadget * gadget_box - gadget * gadget_box_x - gadget * gadget_box_y - gadget * title - title * pointer * * drag_candidate - first box with scroll * padding_left - box with scroll * padding_right * padding_top * padding_bottom * scrollbar - inside padding box stops decent * scroll_mouse_x - inside padding box stops decent * scroll_mouse_y - inside padding box stops decent * * text_box - text box * text_box_x - text_box */ while ((next_box = box_at_point(box, x, y, &box_x, &box_y)) != NULL) { box = next_box; if ((box->style != NULL) && (css_computed_visibility(box->style) == CSS_VISIBILITY_HIDDEN)) { continue; } if (box->node != NULL) { node = box->node; } if (box->object) { if (content_get_type(box->object) == CONTENT_HTML) { html_object_box = box; html_object_pos_x = box_x; html_object_pos_y = box_y; } else { object = box->object; } } if (box->iframe) { iframe = box->iframe; } if (box->href) { url = box->href; target = box->target; url_box = box; } if (box->usemap) { url = imagemap_get(html, box->usemap, box_x, box_y, x, y, &target); if (url) { imagemap = true; url_box = box; } } if (box->gadget) { gadget = box->gadget; gadget_box = box; gadget_box_x = box_x; gadget_box_y = box_y; if (gadget->form) target = gadget->form->target; } if (box->title) { title = box->title; } pointer = get_pointer_shape(box, false); if ((box->scroll_x != NULL) || (box->scroll_y != NULL)) { if (drag_candidate == NULL) { drag_candidate = box; } padding_left = box_x + scrollbar_get_offset(box->scroll_x); padding_right = padding_left + box->padding[LEFT] + box->width + box->padding[RIGHT]; padding_top = box_y + scrollbar_get_offset(box->scroll_y); padding_bottom = padding_top + box->padding[TOP] + box->height + box->padding[BOTTOM]; if ((x > padding_left) && (x < padding_right) && (y > padding_top) && (y < padding_bottom)) { /* mouse inside padding box */ if ((box->scroll_y != NULL) && (x > (padding_right - SCROLLBAR_WIDTH))) { /* mouse above vertical box scroll */ scrollbar = box->scroll_y; scroll_mouse_x = x - (padding_right - SCROLLBAR_WIDTH); scroll_mouse_y = y - padding_top; break; } else if ((box->scroll_x != NULL) && (y > (padding_bottom - SCROLLBAR_WIDTH))) { /* mouse above horizontal box scroll */ scrollbar = box->scroll_x; scroll_mouse_x = x - padding_left; scroll_mouse_y = y - (padding_bottom - SCROLLBAR_WIDTH); break; } } } if (box->text && !box->object) { text_box = box; text_box_x = box_x; } } /* use of box_x, box_y, or content below this point is probably a * mistake; they will refer to the last box returned by box_at_point */ if (scrollbar) { status = scrollbar_mouse_action(scrollbar, mouse, scroll_mouse_x, scroll_mouse_y); pointer = BROWSER_POINTER_DEFAULT; } else if (gadget) { switch (gadget->type) { case GADGET_SELECT: status = messages_get("FormSelect"); pointer = BROWSER_POINTER_MENU; if (mouse & BROWSER_MOUSE_CLICK_1 && nsoption_bool(core_select_menu)) { html->visible_select_menu = gadget; form_open_select_menu(c, gadget, form_select_menu_callback, c); pointer = BROWSER_POINTER_DEFAULT; } else if (mouse & BROWSER_MOUSE_CLICK_1) gui_create_form_select_menu(bw, gadget); break; case GADGET_CHECKBOX: status = messages_get("FormCheckbox"); if (mouse & BROWSER_MOUSE_CLICK_1) { gadget->selected = !gadget->selected; html__redraw_a_box(html, gadget_box); } break; case GADGET_RADIO: status = messages_get("FormRadio"); if (mouse & BROWSER_MOUSE_CLICK_1) form_radio_set(html, gadget); break; case GADGET_IMAGE: if (mouse & BROWSER_MOUSE_CLICK_1) { gadget->data.image.mx = x - gadget_box_x; gadget->data.image.my = y - gadget_box_y; } /* drop through */ case GADGET_SUBMIT: if (gadget->form) { snprintf(status_buffer, sizeof status_buffer, messages_get("FormSubmit"), gadget->form->action); status = status_buffer; pointer = get_pointer_shape(gadget_box, false); if (mouse & (BROWSER_MOUSE_CLICK_1 | BROWSER_MOUSE_CLICK_2)) action = ACTION_SUBMIT; } else { status = messages_get("FormBadSubmit"); } break; case GADGET_TEXTAREA: status = messages_get("FormTextarea"); pointer = get_pointer_shape(gadget_box, false); if (mouse & (BROWSER_MOUSE_PRESS_1 | BROWSER_MOUSE_PRESS_2)) { if (text_box && selection_root(&html->sel) != gadget_box) selection_init(&html->sel, gadget_box); textinput_textarea_click(c, mouse, gadget_box, gadget_box_x, gadget_box_y, x - gadget_box_x, y - gadget_box_y); } if (text_box) { int pixel_offset; size_t idx; font_plot_style_from_css(text_box->style, &fstyle); nsfont.font_position_in_string(&fstyle, text_box->text, text_box->length, x - gadget_box_x - text_box->x, &idx, &pixel_offset); selection_click(&html->sel, mouse, text_box->byte_offset + idx); if (selection_dragging(&html->sel)) { browser_window_set_drag_type(bw, DRAGGING_SELECTION, NULL); status = messages_get("Selecting"); } } else if (mouse & BROWSER_MOUSE_PRESS_1) selection_clear(&html->sel, true); break; case GADGET_TEXTBOX: case GADGET_PASSWORD: status = messages_get("FormTextbox"); pointer = get_pointer_shape(gadget_box, false); if ((mouse & BROWSER_MOUSE_PRESS_1) && !(mouse & (BROWSER_MOUSE_MOD_1 | BROWSER_MOUSE_MOD_2))) { textinput_input_click(c, gadget_box, gadget_box_x, gadget_box_y, x - gadget_box_x, y - gadget_box_y); } if (text_box) { int pixel_offset; size_t idx; if (mouse & (BROWSER_MOUSE_DRAG_1 | BROWSER_MOUSE_DRAG_2)) selection_init(&html->sel, gadget_box); font_plot_style_from_css(text_box->style, &fstyle); nsfont.font_position_in_string(&fstyle, text_box->text, text_box->length, x - gadget_box_x - text_box->x, &idx, &pixel_offset); selection_click(&html->sel, mouse, text_box->byte_offset + idx); if (selection_dragging(&html->sel)) browser_window_set_drag_type(bw, DRAGGING_SELECTION, NULL); } else if (mouse & BROWSER_MOUSE_PRESS_1) selection_clear(&html->sel, true); break; case GADGET_HIDDEN: /* not possible: no box generated */ break; case GADGET_RESET: status = messages_get("FormReset"); break; case GADGET_FILE: status = messages_get("FormFile"); break; case GADGET_BUTTON: /* This gadget cannot be activated */ status = messages_get("FormButton"); break; } } else if (object && (mouse & BROWSER_MOUSE_MOD_2)) { if (mouse & BROWSER_MOUSE_DRAG_2) { msg_data.dragsave.type = CONTENT_SAVE_NATIVE; msg_data.dragsave.content = object; content_broadcast(c, CONTENT_MSG_DRAGSAVE, msg_data); } else if (mouse & BROWSER_MOUSE_DRAG_1) { msg_data.dragsave.type = CONTENT_SAVE_ORIG; msg_data.dragsave.content = object; content_broadcast(c, CONTENT_MSG_DRAGSAVE, msg_data); } /* \todo should have a drag-saving object msg */ } else if (iframe) { int pos_x, pos_y; float scale = browser_window_get_scale(bw); browser_window_get_position(iframe, false, &pos_x, &pos_y); pos_x /= scale; pos_y /= scale; if (mouse & BROWSER_MOUSE_CLICK_1 || mouse & BROWSER_MOUSE_CLICK_2) { browser_window_mouse_click(iframe, mouse, x - pos_x, y - pos_y); } else { browser_window_mouse_track(iframe, mouse, x - pos_x, y - pos_y); } } else if (html_object_box) { if (mouse & BROWSER_MOUSE_CLICK_1 || mouse & BROWSER_MOUSE_CLICK_2) { content_mouse_action(html_object_box->object, bw, mouse, x - html_object_pos_x, y - html_object_pos_y); } else { content_mouse_track(html_object_box->object, bw, mouse, x - html_object_pos_x, y - html_object_pos_y); } } else if (url) { if (title) { snprintf(status_buffer, sizeof status_buffer, "%s: %s", nsurl_access(url), title); status = status_buffer; } else status = nsurl_access(url); pointer = get_pointer_shape(url_box, imagemap); if (mouse & BROWSER_MOUSE_CLICK_1 && mouse & BROWSER_MOUSE_MOD_1) { /* force download of link */ browser_window_go_post(bw, nsurl_access(url), 0, 0, false, nsurl_access(content_get_url(c)), true, true, 0); } else if (mouse & BROWSER_MOUSE_CLICK_2 && mouse & BROWSER_MOUSE_MOD_1) { msg_data.savelink.url = nsurl_access(url); msg_data.savelink.title = title; content_broadcast(c, CONTENT_MSG_SAVELINK, msg_data); } else if (mouse & (BROWSER_MOUSE_CLICK_1 | BROWSER_MOUSE_CLICK_2)) action = ACTION_GO; } else { bool done = false; /* frame resizing */ if (browser_window_frame_resize_start(bw, mouse, x, y, &pointer)) { if (mouse & (BROWSER_MOUSE_DRAG_1 | BROWSER_MOUSE_DRAG_2)) { status = messages_get("FrameDrag"); } done = true; } /* if clicking in the main page, remove the selection from any * text areas */ if (!done) { struct box *layout = html->layout; if (mouse && (mouse < BROWSER_MOUSE_MOD_1) && selection_root(&html->sel) != layout) { selection_init(&html->sel, layout); } if (text_box) { int pixel_offset; size_t idx; font_plot_style_from_css(text_box->style, &fstyle); nsfont.font_position_in_string(&fstyle, text_box->text, text_box->length, x - text_box_x, &idx, &pixel_offset); if (selection_click(&html->sel, mouse, text_box->byte_offset + idx)) { /* key presses must be directed at the * main browser window, paste text * operations ignored */ if (selection_dragging(&html->sel)) { browser_window_set_drag_type(bw, DRAGGING_SELECTION, NULL); status = messages_get( "Selecting"); } done = true; } } else if (mouse & BROWSER_MOUSE_PRESS_1) selection_clear(&html->sel, true); } if (!done) { if (title) status = title; if (mouse & BROWSER_MOUSE_DRAG_1) { if (mouse & BROWSER_MOUSE_MOD_2) { msg_data.dragsave.type = CONTENT_SAVE_COMPLETE; msg_data.dragsave.content = NULL; content_broadcast(c, CONTENT_MSG_DRAGSAVE, msg_data); } else { if (drag_candidate == NULL) { browser_window_page_drag_start( bw, x, y); } else { html_box_drag_start( drag_candidate, x, y); } pointer = BROWSER_POINTER_MOVE; } } else if (mouse & BROWSER_MOUSE_DRAG_2) { if (mouse & BROWSER_MOUSE_MOD_2) { msg_data.dragsave.type = CONTENT_SAVE_SOURCE; msg_data.dragsave.content = NULL; content_broadcast(c, CONTENT_MSG_DRAGSAVE, msg_data); } else { if (drag_candidate == NULL) { browser_window_page_drag_start( bw, x, y); } else { html_box_drag_start( drag_candidate, x, y); } pointer = BROWSER_POINTER_MOVE; } } } if (mouse && mouse < BROWSER_MOUSE_MOD_1) { /* ensure key presses still act on the browser window */ browser_window_remove_caret(bw); } } if (!iframe && !html_object_box) { msg_data.explicit_status_text = status; content_broadcast(c, CONTENT_MSG_STATUS, msg_data); msg_data.pointer = pointer; content_broadcast(c, CONTENT_MSG_POINTER, msg_data); } /* fire dom click event */ if ((mouse & BROWSER_MOUSE_CLICK_1) || (mouse & BROWSER_MOUSE_CLICK_2)) { js_fire_event(html->jscontext, "click", html->document, node); } /* deferred actions that can cause this browser_window to be destroyed * and must therefore be done after set_status/pointer */ switch (action) { case ACTION_SUBMIT: form_submit(content_get_url(c), browser_window_find_target(bw, target, mouse), gadget->form, gadget); break; case ACTION_GO: browser_window_go(browser_window_find_target(bw, target, mouse), nsurl_access(url), nsurl_access(content_get_url(c)), true); break; case ACTION_NONE: break; } }
bool box_textarea_keypress(html_content *html, struct box *box, uint32_t key) { struct form_control *gadget = box->gadget; struct textarea *ta = gadget->data.text.ta; struct form* form = box->gadget->form; struct content *c = (struct content *) html; assert(ta != NULL); if (gadget->type != GADGET_TEXTAREA) { switch (key) { case NS_KEY_NL: case NS_KEY_CR: if (form) form_submit(content_get_url(c), html->bw, form, 0); return true; case NS_KEY_TAB: { struct form_control *next_input; /* Find next text entry field that is actually * displayed (i.e. has an associated box) */ for (next_input = gadget->next; next_input && ((next_input->type != GADGET_TEXTBOX && next_input->type != GADGET_TEXTAREA && next_input->type != GADGET_PASSWORD) || !next_input->box); next_input = next_input->next) ; if (!next_input) return true; textarea_set_caret(ta, -1); textarea_set_caret(next_input->data.text.ta, 0); } return true; case NS_KEY_SHIFT_TAB: { struct form_control *prev_input; /* Find previous text entry field that is actually * displayed (i.e. has an associated box) */ for (prev_input = gadget->prev; prev_input && ((prev_input->type != GADGET_TEXTBOX && prev_input->type != GADGET_TEXTAREA && prev_input->type != GADGET_PASSWORD) || !prev_input->box); prev_input = prev_input->prev) ; if (!prev_input) return true; textarea_set_caret(ta, -1); textarea_set_caret(prev_input->data.text.ta, 0); } return true; default: /* Pass to textarea widget */ break; } } return textarea_keypress(ta, key); }
bool save_complete_html(hlcache_handle *c, const char *path, bool index, struct save_complete_entry **list) { struct html_stylesheet *sheets; struct content_html_object *objects; const char *base_url; char filename[256]; unsigned int i, count; xmlDocPtr doc; bool res; if (content_get_type(c) != CONTENT_HTML) return false; if (save_complete_list_check(c, *list)) return true; base_url = html_get_base_url(c); /* save stylesheets, ignoring the base and adblocking sheets */ sheets = html_get_stylesheets(c, &count); for (i = STYLESHEET_START; i != count; i++) { hlcache_handle *css; const char *css_data; unsigned long css_size; char *source; int source_len; struct nscss_import *imports; uint32_t import_count; if (sheets[i].type == HTML_STYLESHEET_INTERNAL) { if (save_imported_sheets( sheets[i].data.internal->imports, sheets[i].data.internal->import_count, path, list) == false) return false; continue; } css = sheets[i].data.external; if (!css) continue; if (save_complete_list_check(css, *list)) continue; if (!save_complete_list_add(css, list)) { warn_user("NoMemory", 0); return false; } imports = nscss_get_imports(css, &import_count); if (!save_imported_sheets(imports, import_count, path, list)) return false; snprintf(filename, sizeof filename, "%p", css); css_data = content_get_source_data(css, &css_size); source = rewrite_stylesheet_urls(css_data, css_size, &source_len, content_get_url(css), *list); if (!source) { warn_user("NoMemory", 0); return false; } res = save_complete_gui_save(path, filename, source_len, source, CONTENT_CSS); free(source); if (res == false) return false; } /* save objects */ objects = html_get_objects(c, &count); for (i = 0; i != count; i++) { hlcache_handle *obj = objects[i].content; const char *obj_data; unsigned long obj_size; if (obj == NULL || content_get_type(obj) >= CONTENT_OTHER) continue; obj_data = content_get_source_data(obj, &obj_size); if (obj_data == NULL) continue; if (save_complete_list_check(obj, *list)) continue; if (!save_complete_list_add(obj, list)) { warn_user("NoMemory", 0); return false; } if (content_get_type(obj) == CONTENT_HTML) { if (!save_complete_html(obj, path, false, list)) return false; continue; } snprintf(filename, sizeof filename, "%p", obj); res = save_complete_gui_save(path, filename, obj_size, obj_data, content_get_type(obj)); if(res == false) return false; } /*save_complete_list_dump();*/ /* copy document */ doc = xmlCopyDoc(html_get_document(c), 1); if (doc == NULL) { warn_user("NoMemory", 0); return false; } /* rewrite all urls we know about */ if (!rewrite_document_urls(doc, html_get_base_url(c), *list)) { xmlFreeDoc(doc); warn_user("NoMemory", 0); return false; } /* save the html file out last of all */ if (index) snprintf(filename, sizeof filename, "index"); else snprintf(filename, sizeof filename, "%p", c); errno = 0; if (save_complete_htmlSaveFileFormat(path, filename, doc, 0, 0) == -1) { if (errno) warn_user("SaveError", strerror(errno)); else warn_user("SaveError", "htmlSaveFileFormat failed"); xmlFreeDoc(doc); return false; } xmlFreeDoc(doc); return true; }
nserror favicon_callback(hlcache_handle *icon, const hlcache_event *event, void *pw) { struct content *c = pw; switch (event->type) { case CONTENT_MSG_LOADING: /* check that the favicon is really a correct image type */ if (content_get_type(icon) == CONTENT_UNKNOWN) { union content_msg_data msg_data; LOG(("%s is not a favicon", content_get_url(icon))); hlcache_handle_abort(icon); hlcache_handle_release(icon); c->data.html.favicon = NULL; c->active -= 1; content_add_error(c, "NotFavIco", 0); msg_data.error = messages_get("NotFavIco"); content_broadcast(c, CONTENT_MSG_STATUS, msg_data); } break; case CONTENT_MSG_READY: break; case CONTENT_MSG_DONE: c->active -= 1; break; case CONTENT_MSG_ERROR: LOG(("favicon %s failed: %s", content_get_url(icon), event->data.error)); hlcache_handle_release(c->data.html.favicon); c->data.html.favicon = NULL; content_add_error(c, "?", 0); c->active -= 1; break; case CONTENT_MSG_STATUS: content_broadcast(c, CONTENT_MSG_STATUS, event->data); break; case CONTENT_MSG_REDRAW: /* Fall through */ case CONTENT_MSG_REFRESH: /* Fall through */ case CONTENT_MSG_REFORMAT: break; default: assert(0); } if (c->active == 0) { /* all objects have arrived */ content__reformat(c, c->available_width, c->height); html_set_status(c, ""); content_set_done(c); } return NSERROR_OK; }
void gui_cert_verify(struct browser_window *bw, hlcache_handle *c, const struct ssl_cert_info *certs, unsigned long num) { const struct ssl_cert_info *from; struct session_cert *to; struct session_data *data; struct tree *tree; struct node *node; long i; STRPTR yesorno,reqcontents; int res = 0; struct treeview_window *twin; assert(bw && c && certs); /* copy the certificate information */ data = calloc(1, sizeof(struct session_data)); if (!data) { warn_user("NoMemory", 0); return; } data->url = strdup(content_get_url(c)); if (!data->url) { free(data); warn_user("NoMemory", 0); return; } data->bw = bw; data->num = num; data->certs = calloc(num, sizeof(struct session_cert)); if (!data->certs) { free(data->url); free(data); warn_user("NoMemory", 0); return; } for (i = 0; i < (long)num; i++) { to = &data->certs[i]; from = &certs[i]; to->subject_t = strdup(from->subject); to->issuer_t = strdup(from->issuer); if ((!to->subject_t) || (!to->issuer_t)) { for (; i >= 0; i--) { to = &data->certs[i]; free(to->subject_t); free(to->issuer_t); } free(data->certs); free(data->url); free(data); warn_user("NoMemory", 0); return; } snprintf(to->version, sizeof data->certs->version, "%ld", from->version); snprintf(to->valid_from, sizeof data->certs->valid_from, "%s", from->not_before); snprintf(to->type, sizeof data->certs->type, "%d", from->cert_type); snprintf(to->valid_to, sizeof data->certs->valid_to, "%s", from->not_after); snprintf(to->serial, sizeof data->certs->serial, "%ld", from->serial); } tree = calloc(sizeof(struct tree), 1); if (!tree) { //ro_gui_cert_close(ssl_w); warn_user("NoMemory", 0); return; } tree->root = tree_create_folder_node(NULL, "Root"); if (!tree->root) { // ro_gui_cert_close(ssl_w); warn_user("NoMemory", 0); free(tree); tree = NULL; return; } tree->root->expanded = true; tree->handle = 0; tree->movable = false; tree->no_drag = true; tree->no_vscroll = true; tree->no_furniture = true; tree->single_selection = true; data->tree = tree; /* put the SSL names in the tree */ for (i = 0; i < (long)num; i++) { node = tree_create_leaf_node(tree->root, certs[i].subject); if (node) { node->data.data = TREE_ELEMENT_SSL; tree_set_node_sprite(node, "small_xxx", "small_xxx"); } } tree_initialise(tree); ami_open_tree(tree,AMI_TREE_SSLCERT); twin = (struct treeview_window *)data->tree->handle; if(yesorno = ASPrintf("%s|%s",messages_get("Accept"),messages_get("Reject"))) { if(reqcontents = ASPrintf("%s\n\n%s: %s\n%s: %s\n%s: %s\n%s: %s\n%s: %s", messages_get("SSLError"), messages_get("Subject"), to->subject_t, messages_get("Issuer"), to->issuer_t, messages_get("Version"), to->version, messages_get("ValidFrom"), to->valid_from, messages_get("ValidTo"), to->valid_to)) { res = TimedDosRequesterTags(TDR_ImageType,TDRIMAGE_QUESTION, TDR_Window,twin->win, TDR_TitleString,messages_get("NetSurf"), TDR_GadgetString,yesorno, TDR_FormatString,reqcontents, TAG_DONE); FreeVec(reqcontents); } FreeVec(yesorno); } if(res == 1) { ami_gui_cert_apply(data); } ami_gui_cert_close(data); }
bool amiga_icon_convert(struct content *c) { amiga_icon_content *icon_c = (amiga_icon_content *)c; union content_msg_data msg_data; struct DiskObject *dobj; ULONG *imagebuf; unsigned char *imagebufptr = NULL; ULONG size; int width = 0, height = 0; long format = 0; int err = 0; uint8 r, g, b, a; ULONG offset; const char *url; char *filename; char *p; ULONG trans, pals1; struct ColorRegister *pal1; url = nsurl_access(content_get_url(c)); filename = url_to_path(url); /* This loader will only work on local files, so fail if not a local path */ if(filename == NULL) { msg_data.error = messages_get("NoMemory"); content_broadcast(c, CONTENT_MSG_ERROR, msg_data); return false; } p = strstr(filename, ".info"); *p = '\0'; dobj = GetIconTagList(filename, NULL); if(dobj == NULL) { msg_data.error = messages_get("NoMemory"); content_broadcast(c, CONTENT_MSG_ERROR, msg_data); return false; } err = IconControl(dobj, ICONCTRLA_GetImageDataFormat,&format, ICONCTRLA_GetWidth,&width, ICONCTRLA_GetHeight,&height, TAG_DONE); /* Check icon is direct mapped (truecolour) or palette-mapped colour. We need additional code to handle planar icons */ if((format != IDFMT_DIRECTMAPPED) && (format==IDFMT_PALETTEMAPPED)) { if(dobj) FreeDiskObject(dobj); return false; } icon_c->bitmap = bitmap_create(width, height, BITMAP_NEW); if (!icon_c->bitmap) { msg_data.error = messages_get("NoMemory"); content_broadcast(c, CONTENT_MSG_ERROR, msg_data); if(dobj) FreeDiskObject(dobj); return false; } imagebuf = (ULONG *) bitmap_get_buffer(icon_c->bitmap); if (!imagebuf) { msg_data.error = messages_get("NoMemory"); content_broadcast(c, CONTENT_MSG_ERROR, msg_data); if(dobj) FreeDiskObject(dobj); return false; } err = IconControl(dobj, ICONCTRLA_GetImageData1, &imagebufptr, TAG_DONE); if(format==IDFMT_PALETTEMAPPED) { IconControl(dobj, ICONCTRLA_GetTransparentColor1, &trans, ICONCTRLA_GetPalette1, &pal1, ICONCTRLA_GetPaletteSize1, &pals1, TAG_DONE); imagebufptr = (unsigned char *) amiga_icon_convertcolouricon32((UBYTE *)imagebufptr, width, height, trans, pals1, pal1, 0xff); } /* Decoded data is ARGB, so ensure correct byte order */ size = width * height * 4; for (offset = 0; offset < size; offset += 4) { b = imagebufptr[offset+3]; g = imagebufptr[offset+2]; r = imagebufptr[offset+1]; a = imagebufptr[offset]; *imagebuf = r << 24 | g << 16 | b << 8 | a; imagebuf++; } c->width = width; c->height = height; bitmap_modified(icon_c->bitmap); content_set_ready(c); content_set_done(c); content_set_status(c, ""); if(dobj) FreeDiskObject(dobj); if(format==IDFMT_PALETTEMAPPED) FreeVec(imagebufptr); return true; }
/* exported interface documented in render/html_internal.h */ nserror html_css_new_stylesheets(html_content *c) { nserror ns_error; hlcache_child_context child; if (c->stylesheets != NULL) { return NSERROR_OK; /* already initialised */ } /* stylesheet 0 is the base style sheet, * stylesheet 1 is the quirks mode style sheet, * stylesheet 2 is the adblocking stylesheet, * stylesheet 3 is the user stylesheet */ c->stylesheets = calloc(STYLESHEET_START, sizeof(struct html_stylesheet)); if (c->stylesheets == NULL) { return NSERROR_NOMEM; } c->stylesheets[STYLESHEET_BASE].sheet = NULL; c->stylesheets[STYLESHEET_QUIRKS].sheet = NULL; c->stylesheets[STYLESHEET_ADBLOCK].sheet = NULL; c->stylesheets[STYLESHEET_USER].sheet = NULL; c->stylesheet_count = STYLESHEET_START; child.charset = c->encoding; child.quirks = c->base.quirks; ns_error = hlcache_handle_retrieve(html_default_stylesheet_url, 0, content_get_url(&c->base), NULL, html_convert_css_callback, c, &child, CONTENT_CSS, &c->stylesheets[STYLESHEET_BASE].sheet); if (ns_error != NSERROR_OK) { return ns_error; } c->base.active++; LOG("%d fetches active", c->base.active); if (nsoption_bool(block_advertisements)) { ns_error = hlcache_handle_retrieve(html_adblock_stylesheet_url, 0, content_get_url(&c->base), NULL, html_convert_css_callback, c, &child, CONTENT_CSS, &c->stylesheets[STYLESHEET_ADBLOCK].sheet); if (ns_error != NSERROR_OK) { return ns_error; } c->base.active++; LOG("%d fetches active", c->base.active); } ns_error = hlcache_handle_retrieve(html_user_stylesheet_url, 0, content_get_url(&c->base), NULL, html_convert_css_callback, c, &child, CONTENT_CSS, &c->stylesheets[STYLESHEET_USER].sheet); if (ns_error != NSERROR_OK) { return ns_error; } c->base.active++; LOG("%d fetches active", c->base.active); return ns_error; }
/** * process a script with a src tag */ static dom_hubbub_error exec_src_script(html_content *c, dom_node *node, dom_string *mimetype, dom_string *src) { nserror ns_error; nsurl *joined; hlcache_child_context child; struct html_script *nscript; union content_msg_data msg_data; bool async; bool defer; enum html_script_type script_type; hlcache_handle_callback script_cb; dom_hubbub_error ret = DOM_HUBBUB_OK; dom_exception exc; /* returned by libdom functions */ /* src url */ ns_error = nsurl_join(c->base_url, dom_string_data(src), &joined); if (ns_error != NSERROR_OK) { msg_data.error = messages_get("NoMemory"); content_broadcast(&c->base, CONTENT_MSG_ERROR, msg_data); return DOM_HUBBUB_NOMEM; } LOG(("script %i '%s'", c->scripts_count, nsurl_access(joined))); /* there are three ways to process the script tag at this point: * * Syncronously pause the parent parse and continue after * the script has downloaded and executed. (default) * Async Start the script downloading and execute it when it * becomes available. * Defered Start the script downloading and execute it when * the page has completed parsing, may be set along * with async where it is ignored. */ /* we interpret the presence of the async and defer attribute * as true and ignore its value, technically only the empty * value or the attribute name itself are valid. However * various browsers interpret this in various ways the most * compatible approach is to be liberal and accept any * value. Note setting the values to "false" still makes them true! */ exc = dom_element_has_attribute(node, corestring_dom_async, &async); if (exc != DOM_NO_ERR) { return DOM_HUBBUB_OK; /* dom error */ } if (async) { /* asyncronous script */ script_type = HTML_SCRIPT_ASYNC; script_cb = convert_script_async_cb; } else { exc = dom_element_has_attribute(node, corestring_dom_defer, &defer); if (exc != DOM_NO_ERR) { return DOM_HUBBUB_OK; /* dom error */ } if (defer) { /* defered script */ script_type = HTML_SCRIPT_DEFER; script_cb = convert_script_defer_cb; } else { /* syncronous script */ script_type = HTML_SCRIPT_SYNC; script_cb = convert_script_sync_cb; } } nscript = html_process_new_script(c, mimetype, script_type); if (nscript == NULL) { nsurl_unref(joined); msg_data.error = messages_get("NoMemory"); content_broadcast(&c->base, CONTENT_MSG_ERROR, msg_data); return DOM_HUBBUB_NOMEM; } /* set up child fetch encoding and quirks */ child.charset = c->encoding; child.quirks = c->base.quirks; ns_error = hlcache_handle_retrieve(joined, 0, content_get_url(&c->base), NULL, script_cb, c, &child, CONTENT_SCRIPT, &nscript->data.handle); nsurl_unref(joined); if (ns_error != NSERROR_OK) { /* @todo Deal with fetch error better. currently assume * fetch never became active */ /* mark duff script fetch as already started */ nscript->already_started = true; LOG(("Fetch failed with error %d",ns_error)); } else { /* update base content active fetch count */ c->base.active++; LOG(("%d fetches active", c->base.active)); switch (script_type) { case HTML_SCRIPT_SYNC: ret = DOM_HUBBUB_HUBBUB_ERR | HUBBUB_PAUSED; case HTML_SCRIPT_ASYNC: break; case HTML_SCRIPT_DEFER: break; default: assert(0); } } return ret; }
bool html_css_process_link(html_content *htmlc, dom_node *node) { dom_string *rel, *type_attr, *media, *href; struct html_stylesheet *stylesheets; nsurl *joined; dom_exception exc; nserror ns_error; hlcache_child_context child; /* rel=<space separated list, including 'stylesheet'> */ exc = dom_element_get_attribute(node, corestring_dom_rel, &rel); if (exc != DOM_NO_ERR || rel == NULL) return true; if (strcasestr(dom_string_data(rel), "stylesheet") == 0) { dom_string_unref(rel); return true; } else if (strcasestr(dom_string_data(rel), "alternate") != 0) { /* Ignore alternate stylesheets */ dom_string_unref(rel); return true; } dom_string_unref(rel); /* type='text/css' or not present */ exc = dom_element_get_attribute(node, corestring_dom_type, &type_attr); if (exc == DOM_NO_ERR && type_attr != NULL) { if (!dom_string_caseless_lwc_isequal(type_attr, corestring_lwc_text_css)) { dom_string_unref(type_attr); return true; } dom_string_unref(type_attr); } /* media contains 'screen' or 'all' or not present */ exc = dom_element_get_attribute(node, corestring_dom_media, &media); if (exc == DOM_NO_ERR && media != NULL) { if (strcasestr(dom_string_data(media), "screen") == NULL && strcasestr(dom_string_data(media), "all") == NULL) { dom_string_unref(media); return true; } dom_string_unref(media); } /* href='...' */ exc = dom_element_get_attribute(node, corestring_dom_href, &href); if (exc != DOM_NO_ERR || href == NULL) return true; /* TODO: only the first preferred stylesheets (ie. * those with a title attribute) should be loaded * (see HTML4 14.3) */ ns_error = nsurl_join(htmlc->base_url, dom_string_data(href), &joined); if (ns_error != NSERROR_OK) { dom_string_unref(href); goto no_memory; } dom_string_unref(href); LOG("linked stylesheet %i '%s'", htmlc->stylesheet_count, nsurl_access(joined)); /* extend stylesheets array to allow for new sheet */ stylesheets = realloc(htmlc->stylesheets, sizeof(struct html_stylesheet) * (htmlc->stylesheet_count + 1)); if (stylesheets == NULL) { nsurl_unref(joined); ns_error = NSERROR_NOMEM; goto no_memory; } htmlc->stylesheets = stylesheets; htmlc->stylesheets[htmlc->stylesheet_count].node = NULL; htmlc->stylesheets[htmlc->stylesheet_count].modified = false; /* start fetch */ child.charset = htmlc->encoding; child.quirks = htmlc->base.quirks; ns_error = hlcache_handle_retrieve(joined, 0, content_get_url(&htmlc->base), NULL, html_convert_css_callback, htmlc, &child, CONTENT_CSS, &htmlc->stylesheets[htmlc->stylesheet_count].sheet); nsurl_unref(joined); if (ns_error != NSERROR_OK) goto no_memory; htmlc->stylesheet_count++; htmlc->base.active++; LOG("%d fetches active", htmlc->base.active); return true; no_memory: content_broadcast_errorcode(&htmlc->base, ns_error); return false; }
option_accept_language = strdup((const char *) lang); if (option_accept_language == NULL) option_accept_language = old_lang; else free(old_lang); g_free(lang); return FALSE; } ENTRY_CHANGED(entryHomePageURL, option_homepage_url) END_HANDLER BUTTON_CLICKED(setCurrentPage) const gchar *url = content_get_url(current_browser->current_content); gtk_entry_set_text(GTK_ENTRY(entryHomePageURL), url); option_homepage_url = strdup(gtk_entry_get_text(GTK_ENTRY(entryHomePageURL))); END_HANDLER BUTTON_CLICKED(setDefaultPage) gtk_entry_set_text(GTK_ENTRY(entryHomePageURL), "http://www.netsurf-browser.org/welcome/"); option_homepage_url = strdup(gtk_entry_get_text(GTK_ENTRY(entryHomePageURL))); END_HANDLER CHECK_CHANGED(checkHideAdverts, option_block_ads) END_HANDLER