static nserror gui_launch_url(struct nsurl *url) { status_t status; // try to open it as an URI BString mimeType = "application/x-vnd.Be.URL."; BString arg(nsurl_access(url)); mimeType.Append(arg, arg.FindFirst(":")); // special case, text/x-email is used traditionally // use it instead if (arg.IFindFirst("mailto:") == 0) mimeType = "text/x-email"; // the protocol should be alphanum // we just check if it's registered // if not there is likely no supporting app anyway if (!BMimeType::IsValid(mimeType.String())) return NSERROR_NO_FETCH_HANDLER; char *args[2] = { (char *)nsurl_access(url), NULL }; status = be_roster->Launch(mimeType.String(), 1, args); if (status < B_OK) beos_warn_user("Cannot launch url", strerror(status)); return NSERROR_OK; }
END_TEST /** * url reference (copy) and unreference(free) */ START_TEST(nsurl_ref_test) { nserror err; nsurl *res1; nsurl *res2; err = nsurl_create(base_str, &res1); /* result must be valid */ ck_assert(err == NSERROR_OK); res2 = nsurl_ref(res1); ck_assert_str_eq(nsurl_access(res1), nsurl_access(res2)); nsurl_unref(res2); nsurl_unref(res1); }
/** * Callback for defer scripts */ static nserror convert_script_defer_cb(hlcache_handle *script, const hlcache_event *event, void *pw) { html_content *parent = pw; unsigned int i; struct html_script *s; /* Find script */ for (i = 0, s = parent->scripts; i != parent->scripts_count; i++, s++) { if (s->type == HTML_SCRIPT_DEFER && s->data.handle == script) break; } assert(i != parent->scripts_count); switch (event->type) { case CONTENT_MSG_LOADING: break; case CONTENT_MSG_READY: break; case CONTENT_MSG_DONE: LOG(("script %d done '%s'", i, nsurl_access(hlcache_handle_get_url(script)))); parent->base.active--; LOG(("%d fetches active", parent->base.active)); break; case CONTENT_MSG_ERROR: LOG(("script %s failed: %s", nsurl_access(hlcache_handle_get_url(script)), event->data.error)); hlcache_handle_release(script); s->data.handle = NULL; parent->base.active--; LOG(("%d fetches active", parent->base.active)); content_add_error(&parent->base, "?", 0); break; case CONTENT_MSG_STATUS: break; default: assert(0); } /* if there are no active fetches remaining begin post parse * conversion */ if (html_can_begin_conversion(parent)) { html_begin_conversion(parent); } return NSERROR_OK; }
/** * Dump imagemap data to the log * * \param c The containing content */ void imagemap_dump(html_content *c) { unsigned int i; int j; assert(c != NULL); if (c->imagemaps == NULL) return; for (i = 0; i != HASH_SIZE; i++) { struct imagemap *map; struct mapentry *entry; map = c->imagemaps[i]; while (map != NULL) { LOG(("Imagemap: %s", map->key)); for (entry = map->list; entry; entry = entry->next) { switch (entry->type) { case IMAGEMAP_DEFAULT: LOG(("\tDefault: %s", nsurl_access( entry->url))); break; case IMAGEMAP_RECT: LOG(("\tRectangle: %s: [(%d,%d),(%d,%d)]", nsurl_access(entry->url), entry->bounds.rect.x0, entry->bounds.rect.y0, entry->bounds.rect.x1, entry->bounds.rect.y1)); break; case IMAGEMAP_CIRCLE: LOG(("\tCircle: %s: [(%d,%d),%d]", nsurl_access(entry->url), entry->bounds.circle.x, entry->bounds.circle.y, entry->bounds.circle.r)); break; case IMAGEMAP_POLY: LOG(("\tPolygon: %s:", nsurl_access( entry->url))); for (j = 0; j != entry->bounds.poly.num; j++) { fprintf(stderr, "(%d,%d) ", (int)entry->bounds.poly.xcoords[j], (int)entry->bounds.poly.ycoords[j]); } fprintf(stderr,"\n"); break; } } map = map->next; } } }
nserror gui_window_save_link(struct gui_window *g, nsurl *url, const char *title) { char fname[1024]; STRPTR openurlstring,linkname; struct DiskObject *dobj = NULL; linkname = ASPrintf("Link_to_%s",FilePart(nsurl_access(url))); if(AslRequestTags(savereq, ASLFR_Window, g->shared->win, ASLFR_SleepWindow, TRUE, ASLFR_TitleText,messages_get("NetSurf"), ASLFR_Screen,scrn, ASLFR_InitialFile,linkname, TAG_DONE)) { strlcpy(fname, savereq->fr_Drawer, 1024); AddPart(fname,savereq->fr_File,1024); ami_set_pointer(g->shared, GUI_POINTER_WAIT, false); if(ami_download_check_overwrite(fname, g->shared->win, 0)) { BPTR fh; if((fh = FOpen(fname,MODE_NEWFILE,0))) { /* \todo Should be URLOpen on OS4.1 */ openurlstring = ASPrintf("openurl \"%s\"\n",nsurl_access(url)); FWrite(fh,openurlstring,1,strlen(openurlstring)); FClose(fh); FreeVec(openurlstring); SetComment(fname, nsurl_access(url)); dobj = GetIconTags(NULL,ICONGETA_GetDefaultName,"url", ICONGETA_GetDefaultType,WBPROJECT, TAG_DONE); dobj->do_DefaultTool = "IconX"; PutIconTags(fname,dobj, ICONPUTA_NotifyWorkbench,TRUE, TAG_DONE); FreeDiskObject(dobj); } FreeVec(linkname); } ami_reset_pointer(g->shared); } return NSERROR_OK; }
nserror nsgtk_viewsource(GtkWindow *parent, struct browser_window *bw) { nserror ret; struct hlcache_handle *hlcontent; const char *source_data; unsigned long source_size; char *ndata = NULL; size_t ndata_len; char *filename; char *title; hlcontent = browser_window_get_content(bw); if (hlcontent == NULL) { return NSERROR_BAD_PARAMETER; } if (content_get_type(hlcontent) != CONTENT_HTML) { return NSERROR_BAD_CONTENT; } source_data = content_get_source_data(hlcontent, &source_size); ret = nsurl_nice(browser_window_get_url(bw), &filename, false); if (ret != NSERROR_OK) { filename = strdup(messages_get("SaveSource")); if (filename == NULL) { return NSERROR_NOMEM; } } title = malloc(strlen(nsurl_access(browser_window_get_url(bw))) + SLEN("Source of - NetSurf") + 1); if (title == NULL) { free(filename); return NSERROR_NOMEM; } sprintf(title, "Source of %s - NetSurf", nsurl_access(browser_window_get_url(bw))); ret = utf8_from_enc(source_data, content_get_encoding(hlcontent, CONTENT_ENCODING_NORMAL), source_size, &ndata, &ndata_len); if (ret == NSERROR_OK) { ret = nsgtk_viewdata(title, filename, ndata, ndata_len); } free(filename); free(title); return ret; }
static nserror html_convert_css_callback(hlcache_handle *css, const hlcache_event *event, void *pw) { html_content *parent = pw; unsigned int i; struct html_stylesheet *s; /* Find sheet */ for (i = 0, s = parent->stylesheets; i != parent->stylesheet_count; i++, s++) { if (s->sheet == css) break; } assert(i != parent->stylesheet_count); switch (event->type) { case CONTENT_MSG_DONE: LOG("done stylesheet slot %d '%s'", i, nsurl_access(hlcache_handle_get_url(css))); parent->base.active--; LOG("%d fetches active", parent->base.active); break; case CONTENT_MSG_ERROR: LOG("stylesheet %s failed: %s", nsurl_access(hlcache_handle_get_url(css)), event->data.error); hlcache_handle_release(css); s->sheet = NULL; parent->base.active--; LOG("%d fetches active", parent->base.active); content_add_error(&parent->base, "?", 0); break; case CONTENT_MSG_POINTER: /* Really don't want this to continue after the switch */ return NSERROR_OK; default: break; } if (html_can_begin_conversion(parent)) { html_begin_conversion(parent); } return NSERROR_OK; }
static bool fetch_resource_notfound_handler(struct fetch_resource_context *ctx) { fetch_msg msg; int code = 404; char buffer[1024]; const char *title; char key[8]; /* content is going to return error code */ fetch_set_http_code(ctx->fetchh, code); /* content type */ if (fetch_resource_send_header(ctx, "Content-Type: text/html")) goto fetch_resource_notfound_handler_aborted; snprintf(key, sizeof key, "HTTP%03d", code); title = messages_get(key); snprintf(buffer, sizeof buffer, "<html><head><title>%s</title></head>" "<body><h1>%s</h1>" "<p>Error %d while fetching file %s</p></body></html>", title, title, code, nsurl_access(ctx->url)); msg.type = FETCH_DATA; msg.data.header_or_data.buf = (const uint8_t *) buffer; msg.data.header_or_data.len = strlen(buffer); if (fetch_resource_send_callback(&msg, ctx)) goto fetch_resource_notfound_handler_aborted; msg.type = FETCH_FINISHED; fetch_resource_send_callback(&msg, ctx); fetch_resource_notfound_handler_aborted: return false; }
static bool save_complete_inventory(save_complete_ctx *ctx) { nserror ret; FILE *fp; char *fname = NULL; save_complete_entry *entry; ret = netsurf_mkpath(&fname, NULL, 2, ctx->path, "Inventory"); if (ret != NSERROR_OK) { return false; } fp = fopen(fname, "w"); free(fname); if (fp == NULL) { LOG("fopen(): errno = %i", errno); guit->misc->warning("SaveError", strerror(errno)); return false; } for (entry = ctx->list; entry != NULL; entry = entry->next) { fprintf(fp, "%p %s\n", entry->content, nsurl_access(hlcache_handle_get_url( entry->content))); } fclose(fp); return true; }
static nserror gui_cert_verify(nsurl *url, const struct ssl_cert_info *certs, unsigned long num, nserror (*cb)(bool proceed, void *pw), void *cbpw) { struct sslcert_session_data *data; LOG("url %s", nsurl_access(url)); // TODO: localize string int b = form_alert(1, "[2][SSL Verify failed, continue?][Continue|Abort|Details...]"); if(b == 1){ // Accept urldb_set_cert_permissions(url, true); cb(true, cbpw); } else if(b == 2) { // Reject urldb_set_cert_permissions(url, false); cb(false, cbpw); } else if(b == 3) { // Inspect sslcert_viewer_create_session_data(num, url, cb, cbpw, certs, &data); atari_sslcert_viewer_open(data); } return NSERROR_OK; }
static void *fetch_rsrc_setup(struct fetch *parent_fetch, nsurl *url, bool only_2xx, bool downgrade_tls, const char *post_urlenc, const struct fetch_multipart_data *post_multipart, const char **headers) { struct fetch_rsrc_context *ctx; ctx = (struct fetch_rsrc_context *)calloc(1, sizeof(*ctx)); if (ctx == NULL) return NULL; ctx->parent_fetch = parent_fetch; /* TODO: keep as nsurl to avoid copy */ ctx->url = (char *)malloc(nsurl_length(url) + 1); if (ctx->url == NULL) { free(ctx); return NULL; } memcpy(ctx->url, nsurl_access(url), nsurl_length(url) + 1); RING_INSERT(ring, ctx); return ctx; }
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, nsurl_access(hlcache_handle_get_url(c)), save_leafname, LEAFNAME_MAX, icon_buf, sizeof(icon_buf)); gui_current_drag_type = GUI_DRAG_SAVE; ro_gui_drag_icon(pointer.pos.x, pointer.pos.y, icon_buf); }
static bool save_complete_inventory(save_complete_ctx *ctx) { FILE *fp; bool error; save_complete_entry *entry; char fullpath[PATH_MAX]; strncpy(fullpath, ctx->path, sizeof fullpath); error = path_add_part(fullpath, sizeof fullpath, "Inventory"); if (error == false) { warn_user("NoMemory", NULL); return false; } fp = fopen(fullpath, "w"); if (fp == NULL) { LOG(("fopen(): errno = %i", errno)); warn_user("SaveError", strerror(errno)); return false; } for (entry = ctx->list; entry != NULL; entry = entry->next) { fprintf(fp, "%p %s\n", entry->content, nsurl_access(hlcache_handle_get_url( entry->content))); } fclose(fp); return true; }
void content_convert(struct content *c) { assert(c); assert(c->status == CONTENT_STATUS_LOADING || c->status == CONTENT_STATUS_ERROR); if (c->status != CONTENT_STATUS_LOADING) return; if (c->locked == true) return; LOG("content "URL_FMT_SPC" (%p)", nsurl_access(llcache_handle_get_url(c->llcache)), c); if (c->handler->data_complete != NULL) { c->locked = true; if (c->handler->data_complete(c) == false) { content_set_error(c); } /* Conversion to the READY state will unlock the content */ } else { content_set_ready(c); content_set_done(c); } }
/** * Informs the hotlist that some content has been visited. Internal procedure. * * \param content the content visited * \param node the node to update siblings and children of */ static void hotlist_visited_internal(hlcache_handle *content, struct node *node) { struct node *child; const char *text; const char *url; if (content == NULL || hlcache_handle_get_url(content) == NULL || hotlist_tree == NULL) return; /* TODO: do this with a nsurl instead */ url = nsurl_access(hlcache_handle_get_url(content)); for (; node; node = tree_node_get_next(node)) { if (!tree_node_is_folder(node)) { text = tree_url_node_get_url(node); if (strcmp(text, url) == 0) { tree_update_URL_node(hotlist_tree, node, url, NULL); } } child = tree_node_get_child(node); if (child != NULL) { hotlist_visited_internal(content, child); } } }
void content_remove_user(struct content *c, void (*callback)(struct content *c, content_msg msg, union content_msg_data data, void *pw), void *pw) { struct content_user *user, *next; LOG("content "URL_FMT_SPC" (%p), user %p %p", nsurl_access(llcache_handle_get_url(c->llcache)), c, callback, pw); /* user_list starts with a sentinel */ for (user = c->user_list; user->next != 0 && !(user->next->callback == callback && user->next->pw == pw); user = user->next) ; if (user->next == 0) { LOG("user not found in list"); assert(0); return; } if (c->handler->remove_user != NULL) c->handler->remove_user(c); next = user->next; user->next = next->next; free(next); }
/** * 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; }
nserror content__init(struct content *c, const content_handler *handler, lwc_string *imime_type, const http_parameter *params, llcache_handle *llcache, const char *fallback_charset, bool quirks) { struct content_user *user_sentinel; nserror error; LOG(("url "URL_FMT_SPC" -> %p", nsurl_access(llcache_handle_get_url(llcache)), c)); user_sentinel = calloc(1, sizeof(struct content_user)); if (user_sentinel == NULL) { return NSERROR_NOMEM; } if (fallback_charset != NULL) { c->fallback_charset = strdup(fallback_charset); if (c->fallback_charset == NULL) { free(user_sentinel); return NSERROR_NOMEM; } } c->llcache = llcache; c->mime_type = lwc_string_ref(imime_type); c->handler = handler; c->status = CONTENT_STATUS_LOADING; c->width = 0; c->height = 0; c->available_width = 0; c->quirks = quirks; c->refresh = 0; c->time = wallclock(); c->size = 0; c->title = NULL; c->active = 0; user_sentinel->callback = NULL; user_sentinel->pw = NULL; user_sentinel->next = NULL; c->user_list = user_sentinel; c->sub_status[0] = 0; c->locked = false; c->total_size = 0; c->http_code = 0; c->error_count = 0; content_set_status(c, messages_get("Loading")); /* Finally, claim low-level cache events */ error = llcache_handle_change_callback(llcache, content_llcache_callback, c); if (error != NSERROR_OK) { lwc_string_unref(c->mime_type); return error; } return NSERROR_OK; }
/* exported interface documented in content/content_protected.h */ const char *content__get_title(struct content *c) { if (c == NULL) return NULL; return c->title != NULL ? c->title : nsurl_access(llcache_handle_get_url(c->llcache)); }
void content_close(hlcache_handle *h) { struct content *c = hlcache_handle_get_content(h); assert(c != 0); LOG("content %p %s", c, nsurl_access(llcache_handle_get_url(c->llcache))); if (c->handler->close != NULL) c->handler->close(c); }
/* exported interface documented in content/fetch.h */ void fetch_abort(struct fetch *f) { assert(f); #ifdef DEBUG_FETCH_VERBOSE LOG(("fetch %p, fetcher %p, url '%s'", f, f->fetcher_handle, nsurl_access(f->url))); #endif f->ops->abort_fetch(f->fetcher_handle); }
void content_open(hlcache_handle *h, struct browser_window *bw, struct content *page, struct object_params *params) { struct content *c = hlcache_handle_get_content(h); assert(c != 0); LOG("content %p %s", c, nsurl_access(llcache_handle_get_url(c->llcache))); if (c->handler->open != NULL) c->handler->open(c, bw, page, params); }
/** * Find the status code and content type and inform the caller. * * Return true if the fetch is being aborted. */ static bool fetch_curl_process_headers(struct curl_fetch_info *f) { long http_code; CURLcode code; fetch_msg msg; f->had_headers = true; if (!f->http_code) { code = curl_easy_getinfo(f->curl_handle, CURLINFO_HTTP_CODE, &f->http_code); fetch_set_http_code(f->fetch_handle, f->http_code); assert(code == CURLE_OK); } http_code = f->http_code; LOG("HTTP status code %li", http_code); if (http_code == 304 && !f->post_urlenc && !f->post_multipart) { /* Not Modified && GET request */ msg.type = FETCH_NOTMODIFIED; fetch_send_callback(&msg, f->fetch_handle); return true; } /* handle HTTP redirects (3xx response codes) */ if (300 <= http_code && http_code < 400 && f->location != 0) { LOG("FETCH_REDIRECT, '%s'", f->location); msg.type = FETCH_REDIRECT; msg.data.redirect = f->location; fetch_send_callback(&msg, f->fetch_handle); return true; } /* handle HTTP 401 (Authentication errors) */ if (http_code == 401) { msg.type = FETCH_AUTH; msg.data.auth.realm = f->realm; fetch_send_callback(&msg, f->fetch_handle); return true; } /* handle HTTP errors (non 2xx response codes) */ if (f->only_2xx && strncmp(nsurl_access(f->url), "http", 4) == 0 && (http_code < 200 || 299 < http_code)) { msg.type = FETCH_ERROR; msg.data.error = messages_get("Not2xx"); fetch_send_callback(&msg, f->fetch_handle); return true; } if (f->abort) return true; return false; }
static void __CDECL menu_add_bookmark(short item, short title, void *data) { LOG(("%s", __FUNCTION__)); if (input_window) { if( input_window->browser->bw->current_content != NULL ){ atari_hotlist_add_page( nsurl_access(hlcache_handle_get_url(input_window->browser->bw->current_content)), NULL ); } } }
/** * callback for each entry to add to completion list */ static bool nsgtk_completion_udb_callback(nsurl *url, const struct url_data *data) { GtkTreeIter iter; if (data->visits != 0) { gtk_list_store_append(nsgtk_completion_list, &iter); gtk_list_store_set(nsgtk_completion_list, &iter, 0, nsurl_access(url), -1); } return true; }
/** * Abort a fetch. */ static void fetch_curl_abort(void *vf) { struct curl_fetch_info *f = (struct curl_fetch_info *)vf; assert(f); LOG("fetch %p, url '%s'", f, nsurl_access(f->url)); if (f->curl_handle) { f->abort = true; } else { fetch_remove_from_queues(f->fetch_handle); fetch_free(f->fetch_handle); } }
static nserror gui_window_set_url(struct gui_window *w, nsurl *url) { int l; if (w == NULL) return NSERROR_OK; l = strlen(nsurl_access(url))+1; if (w->url == NULL) { w->url = malloc(l); } else { w->url = realloc(w->url, l); } strncpy(w->url, nsurl_access(url), l); w->url[l] = 0; if(input_window == w->root->active_gui_window) { toolbar_set_url(w->root->toolbar, nsurl_access(url)); } return NSERROR_OK; }
static bool fetch_resource_redirect_handler(struct fetch_resource_context *ctx) { fetch_msg msg; /* content is going to return redirect */ fetch_set_http_code(ctx->fetchh, 302); msg.type = FETCH_REDIRECT; msg.data.redirect = nsurl_access(ctx->redirect_url); fetch_resource_send_callback(&msg, ctx); return true; }
void ami_print(struct hlcache_handle *c, int copies) { double height; float scale = nsoption_int(print_scale) / 100.0; if(ami_print_info.msgport == NULL) ami_print_init(); #ifdef __amigaos4__ 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; #else if(!(ami_print_info.PReq = (struct IODRPTagsReq *)CreateIORequest(ami_print_info.msgport, sizeof(struct IODRPTagsReq)))) return; #endif if(OpenDevice("printer.device", nsoption_int(printer_unit), (struct IORequest *)ami_print_info.PReq, 0)) { amiga_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, nsurl_access(hlcache_handle_get_url(c)), ami_layout_table); 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)) { amiga_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 */ }
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; }