mirror of
https://github.com/netsurf-browser/netsurf
synced 2024-11-22 06:21:45 +03:00
Currently untested (and unused) "drop file on content" handling, and HTML implementation.
svn path=/trunk/netsurf/; revision=13214
This commit is contained in:
parent
70c8d94858
commit
02780e1f2d
@ -746,6 +746,19 @@ bool content_scroll_at_point(struct hlcache_handle *h,
|
||||
}
|
||||
|
||||
|
||||
bool content_drop_file_at_point(struct hlcache_handle *h,
|
||||
int x, int y, char *file)
|
||||
{
|
||||
struct content *c = hlcache_handle_get_content(h);
|
||||
assert(c != 0);
|
||||
|
||||
if (c->handler->drop_file_at_point != NULL)
|
||||
return c->handler->drop_file_at_point(c, x, y, file);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void content_add_error(struct content *c, const char *token,
|
||||
unsigned int line)
|
||||
{
|
||||
|
@ -177,6 +177,8 @@ void content_get_contextual_content(struct hlcache_handle *h,
|
||||
int x, int y, struct contextual_content *data);
|
||||
bool content_scroll_at_point(struct hlcache_handle *h,
|
||||
int x, int y, int scrx, int scry);
|
||||
bool content_drop_file_at_point(struct hlcache_handle *h,
|
||||
int x, int y, char *file);
|
||||
struct content_rfc5988_link *content_find_rfc5988_link(struct hlcache_handle *c,
|
||||
lwc_string *rel);
|
||||
|
||||
|
@ -71,6 +71,8 @@ struct content_handler {
|
||||
struct contextual_content *data);
|
||||
bool (*scroll_at_point)(struct content *c, int x, int y,
|
||||
int scrx, int scry);
|
||||
bool (*drop_file_at_point)(struct content *c, int x, int y,
|
||||
char *file);
|
||||
nserror (*clone)(const struct content *old, struct content **newc);
|
||||
bool (*matches_quirks)(const struct content *c, bool quirks);
|
||||
content_type (*type)(void);
|
||||
|
155
render/html.c
155
render/html.c
@ -49,6 +49,7 @@
|
||||
#include "utils/schedule.h"
|
||||
#include "utils/talloc.h"
|
||||
#include "utils/url.h"
|
||||
#include "utils/utf8.h"
|
||||
#include "utils/utils.h"
|
||||
|
||||
#define CHUNK 4096
|
||||
@ -81,6 +82,8 @@ static void html_get_contextual_content(struct content *c,
|
||||
int x, int y, struct contextual_content *data);
|
||||
static bool html_scroll_at_point(struct content *c,
|
||||
int x, int y, int scrx, int scry);
|
||||
static bool html_drop_file_at_point(struct content *c,
|
||||
int x, int y, char *file);
|
||||
struct search_context *html_get_search(struct content *c);
|
||||
static nserror html_clone(const struct content *old, struct content **newc);
|
||||
static content_type html_content_type(void);
|
||||
@ -128,6 +131,7 @@ static const content_handler html_content_handler = {
|
||||
.get_selection = html_get_selection,
|
||||
.get_contextual_content = html_get_contextual_content,
|
||||
.scroll_at_point = html_scroll_at_point,
|
||||
.drop_file_at_point = html_drop_file_at_point,
|
||||
.clone = html_clone,
|
||||
.type = html_content_type,
|
||||
.no_share = true,
|
||||
@ -2317,6 +2321,157 @@ bool html_scroll_at_point(struct content *c, int x, int y, int scrx, int scry)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Drop a file onto a content at a particular point.
|
||||
*
|
||||
* \param c html content to look inside
|
||||
* \param x x-coordinate of point of interest
|
||||
* \param y y-coordinate of point of interest
|
||||
* \param file path to file to be dropped
|
||||
* \return true iff file drop has been handled
|
||||
*/
|
||||
bool html_drop_file_at_point(struct content *c, int x, int y, char *file)
|
||||
{
|
||||
html_content *html = (html_content *) c;
|
||||
|
||||
struct box *box = html->layout;
|
||||
struct box *next;
|
||||
struct box *file_box = NULL;
|
||||
struct box *text_box = NULL;
|
||||
int box_x = 0, box_y = 0;
|
||||
hlcache_handle *containing_content = NULL;
|
||||
|
||||
/* Scan box tree for boxes that can handle drop */
|
||||
while ((next = box_at_point(box, x, y, &box_x, &box_y,
|
||||
&containing_content)) != NULL) {
|
||||
box = next;
|
||||
|
||||
if (box->style && css_computed_visibility(box->style) ==
|
||||
CSS_VISIBILITY_HIDDEN)
|
||||
continue;
|
||||
|
||||
if (box->gadget) {
|
||||
switch (box->gadget->type) {
|
||||
case GADGET_FILE:
|
||||
file_box = box;
|
||||
break;
|
||||
|
||||
case GADGET_TEXTBOX:
|
||||
case GADGET_TEXTAREA:
|
||||
case GADGET_PASSWORD:
|
||||
text_box = box;
|
||||
break;
|
||||
|
||||
default: /* appease compiler */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!file_box && !text_box)
|
||||
/* No box capable of handling drop */
|
||||
return false;
|
||||
|
||||
/* Handle the drop */
|
||||
if (file_box) {
|
||||
/* File dropped on file input */
|
||||
utf8_convert_ret ret;
|
||||
char *utf8_fn;
|
||||
|
||||
ret = utf8_from_local_encoding(file, 0,
|
||||
&utf8_fn);
|
||||
if (ret != UTF8_CONVERT_OK) {
|
||||
/* A bad encoding should never happen */
|
||||
assert(ret != UTF8_CONVERT_BADENC);
|
||||
LOG(("utf8_from_local_encoding failed"));
|
||||
/* Load was for us - just no memory */
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Found: update form input */
|
||||
free(file_box->gadget->value);
|
||||
file_box->gadget->value = utf8_fn;
|
||||
|
||||
/* Redraw box. */
|
||||
html_redraw_a_box(containing_content, file_box);
|
||||
|
||||
} else if (html->bw != NULL) {
|
||||
/* File dropped on text input */
|
||||
|
||||
size_t file_len;
|
||||
FILE *fp = NULL;
|
||||
char *buffer;
|
||||
char *utf8_buff;
|
||||
utf8_convert_ret ret;
|
||||
unsigned int size;
|
||||
|
||||
/* Open file */
|
||||
fp = fopen(file, "rb");
|
||||
if (fp == NULL) {
|
||||
/* Couldn't open file, but drop was for us */
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Get filesize */
|
||||
fseek(fp, 0, SEEK_END);
|
||||
file_len = ftell(fp);
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
|
||||
/* Allocate buffer for file data */
|
||||
buffer = malloc(file_len + 1);
|
||||
if (buffer == NULL) {
|
||||
/* No memory, but drop was for us */
|
||||
fclose(fp);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Stick file into buffer */
|
||||
if (file_len != fread(buffer, 1, file_len, fp)) {
|
||||
/* Failed, but drop was for us */
|
||||
free(buffer);
|
||||
fclose(fp);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Done with file */
|
||||
fclose(fp);
|
||||
|
||||
/* Ensure buffer's string termination */
|
||||
buffer[file_len] = '\0';
|
||||
|
||||
/* TODO: Sniff for text? */
|
||||
|
||||
/* Convert to UTF-8 */
|
||||
ret = utf8_from_local_encoding(buffer, file_len, &utf8_buff);
|
||||
if (ret != UTF8_CONVERT_OK) {
|
||||
/* bad encoding shouldn't happen */
|
||||
assert(ret != UTF8_CONVERT_BADENC);
|
||||
LOG(("utf8_from_local_encoding failed"));
|
||||
free(buffer);
|
||||
warn_user("NoMemory", NULL);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Done with buffer */
|
||||
free(buffer);
|
||||
|
||||
/* Get new length */
|
||||
size = strlen(utf8_buff);
|
||||
|
||||
/* Simulate a click over the input box, to place caret */
|
||||
browser_window_mouse_click(html->bw,
|
||||
BROWSER_MOUSE_PRESS_1, x, y);
|
||||
|
||||
/* Paste the file as text */
|
||||
browser_window_paste_text(html->bw, utf8_buff, size, true);
|
||||
|
||||
free(utf8_buff);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set an HTML content's search context
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user