mirror of
https://github.com/rkd77/elinks.git
synced 2024-12-04 14:46:47 -05:00
Ecmascript: 8 last urls opened by window.open() remembered in a safer way.
This commit is contained in:
parent
9cca645dac
commit
c571aea567
@ -64,6 +64,51 @@ static struct option_info ecmascript_options[] = {
|
|||||||
NULL_OPTION_INFO,
|
NULL_OPTION_INFO,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define NUMBER_OF_URLS_TO_REMEMBER 8
|
||||||
|
static struct {
|
||||||
|
unsigned char *url;
|
||||||
|
unsigned char *frame;
|
||||||
|
} u[NUMBER_OF_URLS_TO_REMEMBER];
|
||||||
|
static int url_index = 0;
|
||||||
|
|
||||||
|
int
|
||||||
|
ecmascript_check_url(unsigned char *url, unsigned char *frame)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
/* Because of gradual rendering window.open is called many
|
||||||
|
* times with the same arguments.
|
||||||
|
* This workaround remembers NUMBER_OF_URLS_TO_REMEMBER last
|
||||||
|
* opened URLs and do not let open them again.
|
||||||
|
*/
|
||||||
|
|
||||||
|
for (i = 0; i < NUMBER_OF_URLS_TO_REMEMBER; i++) {
|
||||||
|
if (!u[i].url) break;
|
||||||
|
if (!strcmp(u[i].url, url) && !strcmp(u[i].frame, frame)) {
|
||||||
|
mem_free(url);
|
||||||
|
mem_free(frame);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
u[url_index].url = url;
|
||||||
|
u[url_index].frame = frame;
|
||||||
|
url_index++;
|
||||||
|
if (url_index >= NUMBER_OF_URLS_TO_REMEMBER) url_index = 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ecmascript_free_urls(struct module *module)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < NUMBER_OF_URLS_TO_REMEMBER; i++) {
|
||||||
|
mem_free_if(u[i].url);
|
||||||
|
mem_free_if(u[i].frame);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef NUMBER_OF_URLS_TO_REMEMBER
|
||||||
|
|
||||||
struct ecmascript_interpreter *
|
struct ecmascript_interpreter *
|
||||||
ecmascript_get_interpreter(struct view_state *vs)
|
ecmascript_get_interpreter(struct view_state *vs)
|
||||||
{
|
{
|
||||||
@ -266,5 +311,5 @@ struct module ecmascript_module = struct_module(
|
|||||||
/* submodules: */ ecmascript_modules,
|
/* submodules: */ ecmascript_modules,
|
||||||
/* data: */ NULL,
|
/* data: */ NULL,
|
||||||
/* init: */ NULL,
|
/* init: */ NULL,
|
||||||
/* done: */ NULL
|
/* done: */ ecmascript_free_urls
|
||||||
);
|
);
|
||||||
|
@ -54,6 +54,9 @@ struct ecmascript_interpreter {
|
|||||||
* reset for each rerendering, and it sucks to do all the magic to preserve the
|
* reset for each rerendering, and it sucks to do all the magic to preserve the
|
||||||
* interpreter over the rerenderings (we tried). */
|
* interpreter over the rerenderings (we tried). */
|
||||||
|
|
||||||
|
int ecmascript_check_url(unsigned char *url, unsigned char *frame);
|
||||||
|
void ecmascript_free_urls(struct module *module);
|
||||||
|
|
||||||
struct ecmascript_interpreter *ecmascript_get_interpreter(struct view_state*vs);
|
struct ecmascript_interpreter *ecmascript_get_interpreter(struct view_state*vs);
|
||||||
void ecmascript_put_interpreter(struct ecmascript_interpreter *interpreter);
|
void ecmascript_put_interpreter(struct ecmascript_interpreter *interpreter);
|
||||||
|
|
||||||
|
@ -93,8 +93,6 @@ js_try_resolve_frame(struct document_view *doc_view, unsigned char *id)
|
|||||||
return js_get_global_object(target->vs.ecmascript->backend_data);
|
return js_get_global_object(target->vs.ecmascript->backend_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
window_get(struct SEE_interpreter *interp, struct SEE_object *o,
|
window_get(struct SEE_interpreter *interp, struct SEE_object *o,
|
||||||
struct SEE_string *p, struct SEE_value *res)
|
struct SEE_string *p, struct SEE_value *res)
|
||||||
@ -228,10 +226,10 @@ js_window_open(struct SEE_interpreter *interp, struct SEE_object *self,
|
|||||||
struct view_state *vs = win->vs;
|
struct view_state *vs = win->vs;
|
||||||
struct document_view *doc_view = vs->doc_view;
|
struct document_view *doc_view = vs->doc_view;
|
||||||
struct session *ses = doc_view->session;
|
struct session *ses = doc_view->session;
|
||||||
unsigned char *target = NULL;
|
unsigned char *frame = "";
|
||||||
unsigned char *url, *url2;
|
unsigned char *url;
|
||||||
struct uri *uri;
|
struct uri *uri;
|
||||||
struct SEE_value url_value, target_value;
|
struct SEE_value url_value;
|
||||||
#if 0
|
#if 0
|
||||||
static time_t ratelimit_start;
|
static time_t ratelimit_start;
|
||||||
static int ratelimit_count;
|
static int ratelimit_count;
|
||||||
@ -261,70 +259,42 @@ js_window_open(struct SEE_interpreter *interp, struct SEE_object *self,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
SEE_ToString(interp, argv[0], &url_value);
|
SEE_ToString(interp, argv[0], &url_value);
|
||||||
if (argc > 1) {
|
|
||||||
/* Because of gradual rendering window.open is called many
|
|
||||||
* times with the same arguments.
|
|
||||||
* This workaround remembers NUMBER_OF_URLS_TO_REMEMBER last
|
|
||||||
* opened URLs and do not let open them again.
|
|
||||||
*/
|
|
||||||
#define NUMBER_OF_URLS_TO_REMEMBER 8
|
|
||||||
static struct {
|
|
||||||
struct SEE_interpreter *interp;
|
|
||||||
struct SEE_string *url;
|
|
||||||
struct SEE_string *target;
|
|
||||||
} strings[NUMBER_OF_URLS_TO_REMEMBER];
|
|
||||||
static int indeks = 0;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
SEE_ToString(interp, argv[1], &target_value);
|
|
||||||
for (i = 0; i < NUMBER_OF_URLS_TO_REMEMBER; i++) {
|
|
||||||
if (!(strings[i].url && strings[i].target
|
|
||||||
&& strings[i].interp))
|
|
||||||
continue;
|
|
||||||
if (strings[i].interp == interp
|
|
||||||
&& !SEE_string_cmp(url_value.u.string, strings[i].url)
|
|
||||||
&& !SEE_string_cmp(target_value.u.string, strings[i].target))
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
strings[indeks].interp = interp;
|
|
||||||
strings[indeks].url = url_value.u.string;
|
|
||||||
strings[indeks].target = target_value.u.string;
|
|
||||||
indeks++;
|
|
||||||
if (indeks >= NUMBER_OF_URLS_TO_REMEMBER) indeks = 0;
|
|
||||||
#undef NUMBER_OF_URLS_TO_REMEMBER
|
|
||||||
}
|
|
||||||
|
|
||||||
url = SEE_string_to_unsigned_char(url_value.u.string);
|
url = SEE_string_to_unsigned_char(url_value.u.string);
|
||||||
if (!url) return;
|
if (!url) return;
|
||||||
|
trim_chars(url, ' ', 0);
|
||||||
|
if (argc > 1) {
|
||||||
|
struct SEE_value target_value;
|
||||||
|
|
||||||
|
SEE_ToString(interp, argv[1], &target_value);
|
||||||
|
frame = SEE_string_to_unsigned_char(target_value.u.string);
|
||||||
|
if (!frame) {
|
||||||
|
mem_free(url);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* url and frame will be freed by ecmascript_check_url */
|
||||||
|
if (!ecmascript_check_url(url, frame)) return;
|
||||||
|
}
|
||||||
/* TODO: Support for window naming and perhaps some window features? */
|
/* TODO: Support for window naming and perhaps some window features? */
|
||||||
|
|
||||||
url2 = join_urls(doc_view->document->uri,
|
url = join_urls(doc_view->document->uri, url);
|
||||||
trim_chars(url, ' ', 0));
|
if (!url) return;
|
||||||
|
uri = get_uri(url, 0);
|
||||||
mem_free(url);
|
mem_free(url);
|
||||||
if (!url2) return;
|
|
||||||
uri = get_uri(url2, 0);
|
|
||||||
mem_free(url2);
|
|
||||||
if (!uri) return;
|
if (!uri) return;
|
||||||
|
|
||||||
if (argc > 1) {
|
if (*frame && strcasecmp(frame, "_blank")) {
|
||||||
target = SEE_string_to_unsigned_char(target_value.u.string);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (target && *target && strcasecmp(target, "_blank")) {
|
|
||||||
struct delayed_open *deo = mem_calloc(1, sizeof(*deo));
|
struct delayed_open *deo = mem_calloc(1, sizeof(*deo));
|
||||||
|
|
||||||
if (deo) {
|
if (deo) {
|
||||||
deo->ses = ses;
|
deo->ses = ses;
|
||||||
deo->uri = get_uri_reference(uri);
|
deo->uri = get_uri_reference(uri);
|
||||||
deo->target = target;
|
deo->target = stracpy(frame);
|
||||||
/* target will be freed in delayed_goto_uri_frame */
|
/* target will be freed in delayed_goto_uri_frame */
|
||||||
register_bottom_half(delayed_goto_uri_frame, deo);
|
register_bottom_half(delayed_goto_uri_frame, deo);
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mem_free_if(target);
|
|
||||||
if (!get_cmd_opt_bool("no-connect")
|
if (!get_cmd_opt_bool("no-connect")
|
||||||
&& !get_cmd_opt_bool("no-home")
|
&& !get_cmd_opt_bool("no-home")
|
||||||
&& !get_cmd_opt_bool("anonymous")
|
&& !get_cmd_opt_bool("anonymous")
|
||||||
@ -345,10 +315,8 @@ js_window_open(struct SEE_interpreter *interp, struct SEE_object *self,
|
|||||||
|
|
||||||
end:
|
end:
|
||||||
done_uri(uri);
|
done_uri(uri);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
init_js_window_object(struct ecmascript_interpreter *interpreter)
|
init_js_window_object(struct ecmascript_interpreter *interpreter)
|
||||||
{
|
{
|
||||||
|
@ -295,7 +295,7 @@ window_open(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
|||||||
struct view_state *vs = JS_GetPrivate(ctx, obj);
|
struct view_state *vs = JS_GetPrivate(ctx, obj);
|
||||||
struct document_view *doc_view = vs->doc_view;
|
struct document_view *doc_view = vs->doc_view;
|
||||||
struct session *ses = doc_view->session;
|
struct session *ses = doc_view->session;
|
||||||
unsigned char *target = "";
|
unsigned char *frame = "";
|
||||||
unsigned char *url;
|
unsigned char *url;
|
||||||
struct uri *uri;
|
struct uri *uri;
|
||||||
static time_t ratelimit_start;
|
static time_t ratelimit_start;
|
||||||
@ -310,31 +310,15 @@ window_open(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
|||||||
|
|
||||||
if (argc < 1) return JS_TRUE;
|
if (argc < 1) return JS_TRUE;
|
||||||
|
|
||||||
url = jsval_to_string(ctx, &argv[0]);
|
url = stracpy(jsval_to_string(ctx, &argv[0]));
|
||||||
|
trim_chars(url, ' ', 0);
|
||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
JSString *url_string = JS_ValueToString(ctx, argv[0]);
|
frame = stracpy(jsval_to_string(ctx, &argv[1]));
|
||||||
JSString *target_string = JS_ValueToString(ctx, argv[1]);
|
if (!frame) {
|
||||||
int i;
|
mem_free(url);
|
||||||
#define NUMBER_OF_URLS_TO_REMEMBER 8
|
|
||||||
static struct {
|
|
||||||
JSString *url;
|
|
||||||
JSString *frame;
|
|
||||||
} strings[NUMBER_OF_URLS_TO_REMEMBER];
|
|
||||||
static int indeks;
|
|
||||||
|
|
||||||
target = jsval_to_string(ctx, &argv[1]);
|
|
||||||
for (i = 0; i < NUMBER_OF_URLS_TO_REMEMBER; i++) {
|
|
||||||
if (!(strings[i].url && strings[i].frame))
|
|
||||||
continue;
|
|
||||||
if (!JS_CompareStrings(url_string, strings[i].url)
|
|
||||||
&& !JS_CompareStrings(target_string, strings[i].frame))
|
|
||||||
return JS_TRUE;
|
return JS_TRUE;
|
||||||
}
|
}
|
||||||
strings[indeks].url = JS_InternString(ctx, url);
|
if (!ecmascript_check_url(url, frame)) return JS_TRUE;
|
||||||
strings[indeks].frame = JS_InternString(ctx, target);
|
|
||||||
indeks++;
|
|
||||||
if (indeks >= NUMBER_OF_URLS_TO_REMEMBER) indeks = 0;
|
|
||||||
#undef NUMBER_OF_URLS_TO_REMEMBER
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ratelimit window opening. Recursive window.open() is very nice.
|
/* Ratelimit window opening. Recursive window.open() is very nice.
|
||||||
@ -351,21 +335,20 @@ window_open(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
|||||||
|
|
||||||
/* TODO: Support for window naming and perhaps some window features? */
|
/* TODO: Support for window naming and perhaps some window features? */
|
||||||
|
|
||||||
url = join_urls(doc_view->document->uri,
|
url = join_urls(doc_view->document->uri, url);
|
||||||
trim_chars(url, ' ', 0));
|
|
||||||
if (!url) return JS_TRUE;
|
if (!url) return JS_TRUE;
|
||||||
uri = get_uri(url, 0);
|
uri = get_uri(url, 0);
|
||||||
mem_free(url);
|
mem_free(url);
|
||||||
if (!uri) return JS_TRUE;
|
if (!uri) return JS_TRUE;
|
||||||
|
|
||||||
|
|
||||||
if (*target && strcasecmp(target, "_blank")) {
|
if (*frame && strcasecmp(frame, "_blank")) {
|
||||||
struct delayed_open *deo = mem_calloc(1, sizeof(*deo));
|
struct delayed_open *deo = mem_calloc(1, sizeof(*deo));
|
||||||
|
|
||||||
if (deo) {
|
if (deo) {
|
||||||
deo->ses = ses;
|
deo->ses = ses;
|
||||||
deo->uri = get_uri_reference(uri);
|
deo->uri = get_uri_reference(uri);
|
||||||
deo->target = stracpy(target);
|
deo->target = stracpy(frame);
|
||||||
register_bottom_half(delayed_goto_uri_frame, deo);
|
register_bottom_half(delayed_goto_uri_frame, deo);
|
||||||
boolean_to_jsval(ctx, rval, 1);
|
boolean_to_jsval(ctx, rval, 1);
|
||||||
goto end;
|
goto end;
|
||||||
|
Loading…
Reference in New Issue
Block a user