mirror of
https://github.com/rkd77/elinks.git
synced 2024-12-04 14:46:47 -05:00
Changed ecmascript engine to mozjs-17.0.
Was not tested, especially smjs is likely buggy.
This commit is contained in:
parent
9cebc108fd
commit
25dd2ecae9
20
configure.ac
20
configure.ac
@ -608,21 +608,11 @@ case "$with_spidermonkey" in
|
||||
;;
|
||||
esac
|
||||
|
||||
# The SpiderMonkey 1.8.5 standalone sources install mozjs185.pc,
|
||||
# but the Debian libmozjs-dev package installs mozilla-js.pc.
|
||||
# Check mozjs185 first, because it has the version number in the name
|
||||
# and therefore is less likely to be a newer incompatible version.
|
||||
# (This configure script rejects older incompatible versions
|
||||
# but can let newer ones through.)
|
||||
for package in mozjs185 mozilla-js; do
|
||||
for package in mozjs-17.0; do
|
||||
if test -n "$CONFIG_SPIDERMONKEY"; then
|
||||
break
|
||||
else
|
||||
AC_MSG_CHECKING([for SpiderMonkey (1.8.5 or later) in pkg-config $package])
|
||||
# In pkg-config 0.25, pkg-config --exists mozjs185
|
||||
# returns 0 (success) even if mozjs185 depends on
|
||||
# nspr, which has not been installed. However,
|
||||
# pkg-config --cflags mozjs185 returns 1 then.
|
||||
AC_MSG_CHECKING([for SpiderMonkey (mozjs-17.0) in pkg-config $package])
|
||||
if $PKG_CONFIG --cflags --libs $package > /dev/null 2>&AS_MESSAGE_LOG_FD; then
|
||||
SPIDERMONKEY_LIBS="$($PKG_CONFIG --libs $package)"
|
||||
SPIDERMONKEY_CFLAGS="$($PKG_CONFIG --cflags $package)"
|
||||
@ -637,11 +627,7 @@ for package in mozjs185 mozilla-js; do
|
||||
# define XP_UNIX 1
|
||||
#endif
|
||||
#include <jsapi.h>
|
||||
#ifndef JS_VERSION
|
||||
# error <jsapi.h> did not define JS_VERSION
|
||||
#elif JS_VERSION < 185
|
||||
# error too old
|
||||
#endif]], [])],
|
||||
]], [])],
|
||||
[CONFIG_SPIDERMONKEY=yes
|
||||
AC_MSG_RESULT([yes])],
|
||||
[# Leave CONFIG_SPIDERMONKEY blank, to continue the search.
|
||||
|
@ -110,7 +110,7 @@ spidermonkey_DefineFunctions(JSContext *cx, JSObject *obj,
|
||||
JSObject *
|
||||
spidermonkey_InitClass(JSContext *cx, JSObject *obj,
|
||||
JSObject *parent_proto, JSClass *clasp,
|
||||
JSNative constructor, uintN nargs,
|
||||
JSNative constructor, unsigned int nargs,
|
||||
JSPropertySpec *ps,
|
||||
const spidermonkeyFunctionSpec *fs,
|
||||
JSPropertySpec *static_ps,
|
||||
|
@ -39,7 +39,7 @@ void spidermonkey_runtime_release(void);
|
||||
typedef struct spidermonkeyFunctionSpec {
|
||||
const char *name;
|
||||
JSNative call;
|
||||
uint8 nargs;
|
||||
uint8_t nargs;
|
||||
/* ELinks does not use "flags" and "extra" so omit them here. */
|
||||
} spidermonkeyFunctionSpec;
|
||||
|
||||
@ -47,7 +47,7 @@ JSBool spidermonkey_DefineFunctions(JSContext *cx, JSObject *obj,
|
||||
const spidermonkeyFunctionSpec *fs);
|
||||
JSObject *spidermonkey_InitClass(JSContext *cx, JSObject *obj,
|
||||
JSObject *parent_proto, JSClass *clasp,
|
||||
JSNative constructor, uintN nargs,
|
||||
JSNative constructor, unsigned int nargs,
|
||||
JSPropertySpec *ps,
|
||||
const spidermonkeyFunctionSpec *fs,
|
||||
JSPropertySpec *static_ps,
|
||||
@ -87,4 +87,7 @@ jsid_to_string(JSContext *ctx, jsid *id)
|
||||
return jsval_to_string(ctx, &v);
|
||||
}
|
||||
|
||||
#define ELINKS_CAST_PROP_PARAMS JSObject *obj = *(hobj._); \
|
||||
jsval *vp = (hvp._);
|
||||
|
||||
#endif
|
||||
|
@ -169,72 +169,91 @@ spidermonkey_get_interpreter(struct ecmascript_interpreter *interpreter)
|
||||
return NULL;
|
||||
interpreter->backend_data = ctx;
|
||||
JS_SetContextPrivate(ctx, interpreter);
|
||||
JS_SetOptions(ctx, JSOPTION_VAROBJFIX | JSOPTION_JIT | JSOPTION_METHODJIT);
|
||||
JS_SetOptions(ctx, JSOPTION_VAROBJFIX | JSOPTION_METHODJIT);
|
||||
JS_SetVersion(ctx, JSVERSION_LATEST);
|
||||
JS_SetErrorReporter(ctx, error_reporter);
|
||||
#if defined(CONFIG_ECMASCRIPT_SMJS_HEARTBEAT)
|
||||
JS_SetOperationCallback(ctx, heartbeat_callback);
|
||||
#endif
|
||||
|
||||
window_obj = JS_NewCompartmentAndGlobalObject(ctx, (JSClass *) &window_class, NULL);
|
||||
window_obj = JS_NewGlobalObject(ctx, &window_class, NULL);
|
||||
|
||||
if (!window_obj) goto release_and_fail;
|
||||
if (!JS_InitStandardClasses(ctx, window_obj)) goto release_and_fail;
|
||||
if (!JS_DefineProperties(ctx, window_obj, (JSPropertySpec *) window_props))
|
||||
|
||||
if (!JS_InitStandardClasses(ctx, window_obj)) {
|
||||
goto release_and_fail;
|
||||
if (!spidermonkey_DefineFunctions(ctx, window_obj, window_funcs))
|
||||
}
|
||||
|
||||
if (!JS_DefineProperties(ctx, window_obj, window_props)) {
|
||||
goto release_and_fail;
|
||||
if (!JS_SetPrivate(ctx, window_obj, interpreter->vs)) /* to @window_class */
|
||||
}
|
||||
|
||||
if (!spidermonkey_DefineFunctions(ctx, window_obj, window_funcs)) {
|
||||
goto release_and_fail;
|
||||
}
|
||||
JS_SetPrivate(window_obj, interpreter->vs); /* to @window_class */
|
||||
|
||||
document_obj = spidermonkey_InitClass(ctx, window_obj, NULL,
|
||||
(JSClass *) &document_class, NULL, 0,
|
||||
(JSPropertySpec *) document_props,
|
||||
&document_class, NULL, 0,
|
||||
document_props,
|
||||
document_funcs,
|
||||
NULL, NULL);
|
||||
if (!document_obj) goto release_and_fail;
|
||||
if (!document_obj) {
|
||||
goto release_and_fail;
|
||||
}
|
||||
|
||||
forms_obj = spidermonkey_InitClass(ctx, document_obj, NULL,
|
||||
(JSClass *) &forms_class, NULL, 0,
|
||||
(JSPropertySpec *) forms_props,
|
||||
&forms_class, NULL, 0,
|
||||
forms_props,
|
||||
forms_funcs,
|
||||
NULL, NULL);
|
||||
if (!forms_obj) goto release_and_fail;
|
||||
if (!forms_obj) {
|
||||
goto release_and_fail;
|
||||
}
|
||||
|
||||
history_obj = spidermonkey_InitClass(ctx, window_obj, NULL,
|
||||
(JSClass *) &history_class, NULL, 0,
|
||||
&history_class, NULL, 0,
|
||||
(JSPropertySpec *) NULL,
|
||||
history_funcs,
|
||||
NULL, NULL);
|
||||
if (!history_obj) goto release_and_fail;
|
||||
if (!history_obj) {
|
||||
goto release_and_fail;
|
||||
}
|
||||
|
||||
location_obj = spidermonkey_InitClass(ctx, window_obj, NULL,
|
||||
(JSClass *) &location_class, NULL, 0,
|
||||
(JSPropertySpec *) location_props,
|
||||
&location_class, NULL, 0,
|
||||
location_props,
|
||||
location_funcs,
|
||||
NULL, NULL);
|
||||
if (!location_obj) goto release_and_fail;
|
||||
if (!location_obj) {
|
||||
goto release_and_fail;
|
||||
}
|
||||
|
||||
menubar_obj = JS_InitClass(ctx, window_obj, NULL,
|
||||
(JSClass *) &menubar_class, NULL, 0,
|
||||
(JSPropertySpec *) unibar_props, NULL,
|
||||
&menubar_class, NULL, 0,
|
||||
unibar_props, NULL,
|
||||
NULL, NULL);
|
||||
if (!menubar_obj) goto release_and_fail;
|
||||
if (!JS_SetPrivate(ctx, menubar_obj, "t")) /* to @menubar_class */
|
||||
if (!menubar_obj) {
|
||||
goto release_and_fail;
|
||||
}
|
||||
JS_SetPrivate(menubar_obj, "t"); /* to @menubar_class */
|
||||
|
||||
statusbar_obj = JS_InitClass(ctx, window_obj, NULL,
|
||||
(JSClass *) &statusbar_class, NULL, 0,
|
||||
(JSPropertySpec *) unibar_props, NULL,
|
||||
&statusbar_class, NULL, 0,
|
||||
unibar_props, NULL,
|
||||
NULL, NULL);
|
||||
if (!statusbar_obj) goto release_and_fail;
|
||||
if (!JS_SetPrivate(ctx, statusbar_obj, "s")) /* to @statusbar_class */
|
||||
if (!statusbar_obj) {
|
||||
goto release_and_fail;
|
||||
}
|
||||
JS_SetPrivate(statusbar_obj, "s"); /* to @statusbar_class */
|
||||
|
||||
navigator_obj = JS_InitClass(ctx, window_obj, NULL,
|
||||
(JSClass *) &navigator_class, NULL, 0,
|
||||
(JSPropertySpec *) navigator_props, NULL,
|
||||
&navigator_class, NULL, 0,
|
||||
navigator_props, NULL,
|
||||
NULL, NULL);
|
||||
if (!navigator_obj) goto release_and_fail;
|
||||
if (!navigator_obj) {
|
||||
goto release_and_fail;
|
||||
}
|
||||
|
||||
return ctx;
|
||||
|
||||
@ -264,14 +283,18 @@ spidermonkey_eval(struct ecmascript_interpreter *interpreter,
|
||||
jsval rval;
|
||||
|
||||
assert(interpreter);
|
||||
if (!js_module_init_ok) return;
|
||||
if (!js_module_init_ok) {
|
||||
return;
|
||||
}
|
||||
ctx = interpreter->backend_data;
|
||||
|
||||
#if defined(CONFIG_ECMASCRIPT_SMJS_HEARTBEAT)
|
||||
interpreter->heartbeat = add_heartbeat(interpreter);
|
||||
#elif defined(HAVE_JS_SETBRANCHCALLBACK)
|
||||
setup_safeguard(interpreter, ctx);
|
||||
#endif
|
||||
interpreter->ret = ret;
|
||||
|
||||
JS_EvaluateScript(ctx, JS_GetGlobalObject(ctx),
|
||||
code->source, code->length, "", 0, &rval);
|
||||
#if defined(CONFIG_ECMASCRIPT_SMJS_HEARTBEAT)
|
||||
@ -297,6 +320,7 @@ spidermonkey_eval_stringback(struct ecmascript_interpreter *interpreter,
|
||||
#elif defined(HAVE_JS_SETBRANCHCALLBACK)
|
||||
setup_safeguard(interpreter, ctx);
|
||||
#endif
|
||||
|
||||
ret = JS_EvaluateScript(ctx, JS_GetGlobalObject(ctx),
|
||||
code->source, code->length, "", 0, &rval);
|
||||
#if defined(CONFIG_ECMASCRIPT_SMJS_HEARTBEAT)
|
||||
@ -327,7 +351,8 @@ spidermonkey_eval_boolback(struct ecmascript_interpreter *interpreter,
|
||||
if (!js_module_init_ok) return 0;
|
||||
ctx = interpreter->backend_data;
|
||||
interpreter->ret = NULL;
|
||||
fun = JS_CompileFunction(ctx, NULL, "", 0, NULL, code->source,
|
||||
|
||||
fun = JS_CompileFunction(ctx, JS_GetGlobalObject(ctx), "", 0, NULL, code->source,
|
||||
code->length, "", 0);
|
||||
if (!fun)
|
||||
return -1;
|
||||
@ -337,7 +362,8 @@ spidermonkey_eval_boolback(struct ecmascript_interpreter *interpreter,
|
||||
#elif defined(HAVE_JS_SETBRANCHCALLBACK)
|
||||
setup_safeguard(interpreter, ctx);
|
||||
#endif
|
||||
ret = JS_CallFunction(ctx, NULL, fun, 0, NULL, &rval);
|
||||
ret = JS_CallFunction(ctx, JS_GetGlobalObject(ctx), fun, 0, NULL, &rval);
|
||||
|
||||
#if defined(CONFIG_ECMASCRIPT_SMJS_HEARTBEAT)
|
||||
done_heartbeat(interpreter->heartbeat);
|
||||
#endif
|
||||
|
@ -47,149 +47,210 @@
|
||||
#include "viewer/text/vs.h"
|
||||
|
||||
|
||||
static JSBool document_get_property(JSContext *ctx, JSObject *obj, jsid id, jsval *vp);
|
||||
static JSBool document_set_property(JSContext *ctx, JSObject *obj, jsid id, JSBool strict, jsval *vp);
|
||||
static JSBool document_get_property(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSMutableHandleValue hvp);
|
||||
|
||||
/* Each @document_class object must have a @window_class parent. */
|
||||
const JSClass document_class = {
|
||||
JSClass document_class = {
|
||||
"document",
|
||||
JSCLASS_HAS_PRIVATE,
|
||||
JS_PropertyStub, JS_PropertyStub,
|
||||
document_get_property, document_set_property,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub
|
||||
document_get_property, JS_StrictPropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub
|
||||
};
|
||||
|
||||
/* Tinyids of properties. Use negative values to distinguish these
|
||||
* from array indexes (even though this object has no array elements).
|
||||
* ECMAScript code should not use these directly as in document[-1];
|
||||
* future versions of ELinks may change the numbers. */
|
||||
enum document_prop {
|
||||
JSP_DOC_LOC = -1,
|
||||
JSP_DOC_REF = -2,
|
||||
JSP_DOC_TITLE = -3,
|
||||
JSP_DOC_URL = -4,
|
||||
};
|
||||
/* "cookie" is special; it isn't a regular property but we channel it to the
|
||||
* cookie-module. XXX: Would it work if "cookie" was defined in this array? */
|
||||
const JSPropertySpec document_props[] = {
|
||||
{ "location", JSP_DOC_LOC, JSPROP_ENUMERATE },
|
||||
{ "referrer", JSP_DOC_REF, JSPROP_ENUMERATE | JSPROP_READONLY },
|
||||
{ "title", JSP_DOC_TITLE, JSPROP_ENUMERATE }, /* TODO: Charset? */
|
||||
{ "url", JSP_DOC_URL, JSPROP_ENUMERATE },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
/* @document_class.getProperty */
|
||||
#ifdef CONFIG_COOKIES
|
||||
static JSBool
|
||||
document_get_property(JSContext *ctx, JSObject *obj, jsid id, jsval *vp)
|
||||
document_get_property_cookie(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSMutableHandleValue hvp)
|
||||
{
|
||||
ELINKS_CAST_PROP_PARAMS
|
||||
|
||||
JSObject *parent_win; /* instance of @window_class */
|
||||
struct view_state *vs;
|
||||
struct string *cookies;
|
||||
JSClass* classPtr = JS_GetClass(obj);
|
||||
|
||||
if (classPtr != &document_class)
|
||||
return JS_FALSE;
|
||||
|
||||
parent_win = JS_GetParent(obj);
|
||||
assert(JS_InstanceOf(ctx, parent_win, &window_class, NULL));
|
||||
if_assert_failed return JS_FALSE;
|
||||
|
||||
vs = JS_GetInstancePrivate(ctx, parent_win,
|
||||
&window_class, NULL);
|
||||
cookies = send_cookies_js(vs->uri);
|
||||
|
||||
if (cookies) {
|
||||
static unsigned char cookiestr[1024];
|
||||
|
||||
strncpy(cookiestr, cookies->source, 1024);
|
||||
done_string(cookies);
|
||||
string_to_jsval(ctx, vp, cookiestr);
|
||||
} else {
|
||||
string_to_jsval(ctx, vp, "");
|
||||
}
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
document_set_property_cookie(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSBool strict, JSMutableHandleValue hvp)
|
||||
{
|
||||
ELINKS_CAST_PROP_PARAMS
|
||||
|
||||
JSObject *parent_win; /* instance of @window_class */
|
||||
struct view_state *vs;
|
||||
|
||||
/* This can be called if @obj if not itself an instance of the
|
||||
* appropriate class but has one in its prototype chain. Fail
|
||||
* such calls. */
|
||||
if (!JS_InstanceOf(ctx, obj, &document_class, NULL))
|
||||
return JS_FALSE;
|
||||
|
||||
parent_win = JS_GetParent(obj);
|
||||
assert(JS_InstanceOf(ctx, parent_win, &window_class, NULL));
|
||||
if_assert_failed return JS_FALSE;
|
||||
|
||||
vs = JS_GetInstancePrivate(ctx, parent_win,
|
||||
&window_class, NULL);
|
||||
set_cookie(vs->uri, jsval_to_string(ctx, vp));
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static JSBool
|
||||
document_get_property_location(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSMutableHandleValue hvp)
|
||||
{
|
||||
ELINKS_CAST_PROP_PARAMS
|
||||
|
||||
JSObject *parent_win; /* instance of @window_class */
|
||||
JSClass* classPtr = JS_GetClass(obj);
|
||||
|
||||
if (classPtr != &document_class)
|
||||
return JS_FALSE;
|
||||
|
||||
parent_win = JS_GetParent(obj);
|
||||
assert(JS_InstanceOf(ctx, parent_win, &window_class, NULL));
|
||||
if_assert_failed return JS_FALSE;
|
||||
|
||||
JS_GetProperty(ctx, parent_win, "location", vp);
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
document_set_property_location(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSBool strict, JSMutableHandleValue hvp)
|
||||
{
|
||||
ELINKS_CAST_PROP_PARAMS
|
||||
|
||||
JSObject *parent_win; /* instance of @window_class */
|
||||
struct view_state *vs;
|
||||
struct document_view *doc_view;
|
||||
|
||||
/* This can be called if @obj if not itself an instance of the
|
||||
* appropriate class but has one in its prototype chain. Fail
|
||||
* such calls. */
|
||||
if (!JS_InstanceOf(ctx, obj, &document_class, NULL))
|
||||
return JS_FALSE;
|
||||
|
||||
parent_win = JS_GetParent(obj);
|
||||
assert(JS_InstanceOf(ctx, parent_win, &window_class, NULL));
|
||||
if_assert_failed return JS_FALSE;
|
||||
|
||||
vs = JS_GetInstancePrivate(ctx, parent_win,
|
||||
&window_class, NULL);
|
||||
doc_view = vs->doc_view;
|
||||
location_goto(doc_view, jsval_to_string(ctx, vp));
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
|
||||
static JSBool
|
||||
document_get_property_referrer(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSMutableHandleValue hvp)
|
||||
{
|
||||
ELINKS_CAST_PROP_PARAMS
|
||||
|
||||
JSObject *parent_win; /* instance of @window_class */
|
||||
struct view_state *vs;
|
||||
struct document_view *doc_view;
|
||||
struct document *document;
|
||||
struct session *ses;
|
||||
JSClass* classPtr = JS_GetClass(obj);
|
||||
|
||||
/* This can be called if @obj if not itself an instance of the
|
||||
* appropriate class but has one in its prototype chain. Fail
|
||||
* such calls. */
|
||||
if (!JS_InstanceOf(ctx, obj, (JSClass *) &document_class, NULL))
|
||||
if (classPtr != &document_class)
|
||||
return JS_FALSE;
|
||||
parent_win = JS_GetParent(ctx, obj);
|
||||
assert(JS_InstanceOf(ctx, parent_win, (JSClass *) &window_class, NULL));
|
||||
|
||||
parent_win = JS_GetParent(obj);
|
||||
assert(JS_InstanceOf(ctx, parent_win, &window_class, NULL));
|
||||
if_assert_failed return JS_FALSE;
|
||||
|
||||
vs = JS_GetInstancePrivate(ctx, parent_win,
|
||||
(JSClass *) &window_class, NULL);
|
||||
&window_class, NULL);
|
||||
doc_view = vs->doc_view;
|
||||
document = doc_view->document;
|
||||
ses = doc_view->session;
|
||||
|
||||
if (JSID_IS_STRING(id)) {
|
||||
struct form *form;
|
||||
unsigned char *string = jsid_to_string(ctx, &id);
|
||||
|
||||
#ifdef CONFIG_COOKIES
|
||||
if (!strcmp(string, "cookie")) {
|
||||
struct string *cookies = send_cookies_js(vs->uri);
|
||||
|
||||
if (cookies) {
|
||||
static unsigned char cookiestr[1024];
|
||||
|
||||
strncpy(cookiestr, cookies->source, 1024);
|
||||
done_string(cookies);
|
||||
|
||||
string_to_jsval(ctx, vp, cookiestr);
|
||||
} else {
|
||||
string_to_jsval(ctx, vp, "");
|
||||
}
|
||||
return JS_TRUE;
|
||||
}
|
||||
#endif
|
||||
foreach (form, document->forms) {
|
||||
if (!form->name || c_strcasecmp(string, form->name))
|
||||
continue;
|
||||
|
||||
object_to_jsval(ctx, vp, get_form_object(ctx, obj, find_form_view(doc_view, form)));
|
||||
break;
|
||||
}
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
if (!JSID_IS_INT(id))
|
||||
return JS_TRUE;
|
||||
|
||||
undef_to_jsval(ctx, vp);
|
||||
|
||||
switch (JSID_TO_INT(id)) {
|
||||
case JSP_DOC_LOC:
|
||||
JS_GetProperty(ctx, parent_win, "location", vp);
|
||||
switch (get_opt_int("protocol.http.referer.policy", NULL)) {
|
||||
case REFERER_NONE:
|
||||
/* oh well */
|
||||
undef_to_jsval(ctx, vp);
|
||||
break;
|
||||
case JSP_DOC_REF:
|
||||
switch (get_opt_int("protocol.http.referer.policy", NULL)) {
|
||||
case REFERER_NONE:
|
||||
/* oh well */
|
||||
undef_to_jsval(ctx, vp);
|
||||
break;
|
||||
|
||||
case REFERER_FAKE:
|
||||
string_to_jsval(ctx, vp, get_opt_str("protocol.http.referer.fake", NULL));
|
||||
break;
|
||||
case REFERER_FAKE:
|
||||
string_to_jsval(ctx, vp, get_opt_str("protocol.http.referer.fake", NULL));
|
||||
break;
|
||||
|
||||
case REFERER_TRUE:
|
||||
/* XXX: Encode as in add_url_to_httset_prop_string(&prop, ) ? --pasky */
|
||||
if (ses->referrer) {
|
||||
astring_to_jsval(ctx, vp, get_uri_string(ses->referrer, URI_HTTP_REFERRER));
|
||||
}
|
||||
break;
|
||||
|
||||
case REFERER_SAME_URL:
|
||||
astring_to_jsval(ctx, vp, get_uri_string(document->uri, URI_HTTP_REFERRER));
|
||||
break;
|
||||
case REFERER_TRUE:
|
||||
/* XXX: Encode as in add_url_to_httset_prop_string(&prop, ) ? --pasky */
|
||||
if (ses->referrer) {
|
||||
astring_to_jsval(ctx, vp, get_uri_string(ses->referrer, URI_HTTP_REFERRER));
|
||||
}
|
||||
break;
|
||||
case JSP_DOC_TITLE:
|
||||
string_to_jsval(ctx, vp, document->title);
|
||||
break;
|
||||
case JSP_DOC_URL:
|
||||
astring_to_jsval(ctx, vp, get_uri_string(document->uri, URI_ORIGINAL));
|
||||
break;
|
||||
default:
|
||||
/* Unrecognized integer property ID; someone is using
|
||||
* the object as an array. SMJS builtin classes (e.g.
|
||||
* js_RegExpClass) just return JS_TRUE in this case
|
||||
* and leave *@vp unchanged. Do the same here.
|
||||
* (Actually not quite the same, as we already used
|
||||
* @undef_to_jsval.) */
|
||||
|
||||
case REFERER_SAME_URL:
|
||||
astring_to_jsval(ctx, vp, get_uri_string(document->uri, URI_HTTP_REFERRER));
|
||||
break;
|
||||
}
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
/* @document_class.setProperty */
|
||||
|
||||
static JSBool
|
||||
document_set_property(JSContext *ctx, JSObject *obj, jsid id, JSBool strict, jsval *vp)
|
||||
document_get_property_title(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSMutableHandleValue hvp)
|
||||
{
|
||||
ELINKS_CAST_PROP_PARAMS
|
||||
|
||||
JSObject *parent_win; /* instance of @window_class */
|
||||
struct view_state *vs;
|
||||
struct document_view *doc_view;
|
||||
struct document *document;
|
||||
JSClass* classPtr = JS_GetClass(obj);
|
||||
|
||||
if (classPtr != &document_class)
|
||||
return JS_FALSE;
|
||||
|
||||
parent_win = JS_GetParent(obj);
|
||||
assert(JS_InstanceOf(ctx, parent_win, &window_class, NULL));
|
||||
if_assert_failed return JS_FALSE;
|
||||
|
||||
vs = JS_GetInstancePrivate(ctx, parent_win,
|
||||
&window_class, NULL);
|
||||
doc_view = vs->doc_view;
|
||||
document = doc_view->document;
|
||||
string_to_jsval(ctx, vp, document->title);
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
document_set_property_title(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSBool strict, JSMutableHandleValue hvp)
|
||||
{
|
||||
ELINKS_CAST_PROP_PARAMS
|
||||
|
||||
JSObject *parent_win; /* instance of @window_class */
|
||||
struct view_state *vs;
|
||||
struct document_view *doc_view;
|
||||
@ -198,52 +259,134 @@ document_set_property(JSContext *ctx, JSObject *obj, jsid id, JSBool strict, jsv
|
||||
/* This can be called if @obj if not itself an instance of the
|
||||
* appropriate class but has one in its prototype chain. Fail
|
||||
* such calls. */
|
||||
if (!JS_InstanceOf(ctx, obj, (JSClass *) &document_class, NULL))
|
||||
if (!JS_InstanceOf(ctx, obj, &document_class, NULL))
|
||||
return JS_FALSE;
|
||||
parent_win = JS_GetParent(ctx, obj);
|
||||
assert(JS_InstanceOf(ctx, parent_win, (JSClass *) &window_class, NULL));
|
||||
|
||||
parent_win = JS_GetParent(obj);
|
||||
assert(JS_InstanceOf(ctx, parent_win, &window_class, NULL));
|
||||
if_assert_failed return JS_FALSE;
|
||||
|
||||
vs = JS_GetInstancePrivate(ctx, parent_win,
|
||||
(JSClass *) &window_class, NULL);
|
||||
&window_class, NULL);
|
||||
doc_view = vs->doc_view;
|
||||
document = doc_view->document;
|
||||
mem_free_set(&document->title, stracpy(jsval_to_string(ctx, vp)));
|
||||
print_screen_status(doc_view->session);
|
||||
|
||||
if (JSID_IS_STRING(id)) {
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
document_get_property_url(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSMutableHandleValue hvp)
|
||||
{
|
||||
ELINKS_CAST_PROP_PARAMS
|
||||
|
||||
JSObject *parent_win; /* instance of @window_class */
|
||||
struct view_state *vs;
|
||||
struct document_view *doc_view;
|
||||
struct document *document;
|
||||
JSClass* classPtr = JS_GetClass(obj);
|
||||
|
||||
if (classPtr != &document_class)
|
||||
return JS_FALSE;
|
||||
|
||||
parent_win = JS_GetParent(obj);
|
||||
assert(JS_InstanceOf(ctx, parent_win, &window_class, NULL));
|
||||
if_assert_failed return JS_FALSE;
|
||||
|
||||
vs = JS_GetInstancePrivate(ctx, parent_win,
|
||||
&window_class, NULL);
|
||||
doc_view = vs->doc_view;
|
||||
document = doc_view->document;
|
||||
astring_to_jsval(ctx, vp, get_uri_string(document->uri, URI_ORIGINAL));
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
document_set_property_url(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSBool strict, JSMutableHandleValue hvp)
|
||||
{
|
||||
ELINKS_CAST_PROP_PARAMS
|
||||
|
||||
JSObject *parent_win; /* instance of @window_class */
|
||||
struct view_state *vs;
|
||||
struct document_view *doc_view;
|
||||
|
||||
/* This can be called if @obj if not itself an instance of the
|
||||
* appropriate class but has one in its prototype chain. Fail
|
||||
* such calls. */
|
||||
if (!JS_InstanceOf(ctx, obj, &document_class, NULL))
|
||||
return JS_FALSE;
|
||||
|
||||
parent_win = JS_GetParent(obj);
|
||||
assert(JS_InstanceOf(ctx, parent_win, &window_class, NULL));
|
||||
if_assert_failed return JS_FALSE;
|
||||
|
||||
vs = JS_GetInstancePrivate(ctx, parent_win,
|
||||
&window_class, NULL);
|
||||
doc_view = vs->doc_view;
|
||||
location_goto(doc_view, jsval_to_string(ctx, vp));
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
|
||||
/* "cookie" is special; it isn't a regular property but we channel it to the
|
||||
* cookie-module. XXX: Would it work if "cookie" was defined in this array? */
|
||||
JSPropertySpec document_props[] = {
|
||||
#ifdef CONFIG_COOKIES
|
||||
if (!strcmp(jsid_to_string(ctx, &id), "cookie")) {
|
||||
set_cookie(vs->uri, jsval_to_string(ctx, vp));
|
||||
/* Do NOT touch our .cookie property, evil
|
||||
* SpiderMonkey!! */
|
||||
return JS_FALSE;
|
||||
}
|
||||
{ "cookie", 0, JSPROP_ENUMERATE | JSPROP_SHARED, JSOP_WRAPPER(document_get_property_cookie), JSOP_WRAPPER(document_set_property_cookie) },
|
||||
#endif
|
||||
return JS_TRUE;
|
||||
}
|
||||
{ "location", 0, JSPROP_ENUMERATE | JSPROP_SHARED, JSOP_WRAPPER(document_get_property_location), JSOP_WRAPPER(document_set_property_location) },
|
||||
{ "referrer", 0, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_SHARED, JSOP_WRAPPER(document_get_property_referrer), JSOP_NULLWRAPPER },
|
||||
{ "title", 0, JSPROP_ENUMERATE | JSPROP_SHARED, JSOP_WRAPPER(document_get_property_title), JSOP_WRAPPER(document_set_property_title) }, /* TODO: Charset? */
|
||||
{ "url", 0, JSPROP_ENUMERATE | JSPROP_SHARED, JSOP_WRAPPER(document_get_property_url), JSOP_WRAPPER(document_set_property_url) },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
if (!JSID_IS_INT(id))
|
||||
return JS_TRUE;
|
||||
|
||||
switch (JSID_TO_INT(id)) {
|
||||
case JSP_DOC_TITLE:
|
||||
mem_free_set(&document->title, stracpy(jsval_to_string(ctx, vp)));
|
||||
print_screen_status(doc_view->session);
|
||||
break;
|
||||
case JSP_DOC_LOC:
|
||||
case JSP_DOC_URL:
|
||||
/* According to the specs this should be readonly but some
|
||||
* broken sites still assign to it (i.e.
|
||||
* http://www.e-handelsfonden.dk/validering.asp?URL=www.polyteknisk.dk).
|
||||
* So emulate window.location. */
|
||||
location_goto(doc_view, jsval_to_string(ctx, vp));
|
||||
/* @document_class.getProperty */
|
||||
static JSBool
|
||||
document_get_property(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSMutableHandleValue hvp)
|
||||
{
|
||||
ELINKS_CAST_PROP_PARAMS
|
||||
jsid id = *(hid._);
|
||||
|
||||
JSObject *parent_win; /* instance of @window_class */
|
||||
struct view_state *vs;
|
||||
struct document_view *doc_view;
|
||||
struct document *document;
|
||||
struct form *form;
|
||||
unsigned char *string;
|
||||
|
||||
JSClass* classPtr = JS_GetClass(obj);
|
||||
|
||||
if (classPtr != &document_class)
|
||||
return JS_FALSE;
|
||||
|
||||
parent_win = JS_GetParent(obj);
|
||||
assert(JS_InstanceOf(ctx, parent_win, &window_class, NULL));
|
||||
if_assert_failed return JS_FALSE;
|
||||
|
||||
vs = JS_GetInstancePrivate(ctx, parent_win,
|
||||
&window_class, NULL);
|
||||
doc_view = vs->doc_view;
|
||||
document = doc_view->document;
|
||||
string = jsid_to_string(ctx, &id);
|
||||
|
||||
foreach (form, document->forms) {
|
||||
if (!form->name || c_strcasecmp(string, form->name))
|
||||
continue;
|
||||
|
||||
object_to_jsval(ctx, vp, get_form_object(ctx, obj, find_form_view(doc_view, form)));
|
||||
break;
|
||||
}
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSBool document_write(JSContext *ctx, uintN argc, jsval *rval);
|
||||
static JSBool document_writeln(JSContext *ctx, uintN argc, jsval *rval);
|
||||
static JSBool document_write(JSContext *ctx, unsigned int argc, jsval *rval);
|
||||
static JSBool document_writeln(JSContext *ctx, unsigned int argc, jsval *rval);
|
||||
|
||||
const spidermonkeyFunctionSpec document_funcs[] = {
|
||||
{ "write", document_write, 1 },
|
||||
@ -252,7 +395,7 @@ const spidermonkeyFunctionSpec document_funcs[] = {
|
||||
};
|
||||
|
||||
static JSBool
|
||||
document_write_do(JSContext *ctx, uintN argc, jsval *rval, int newline)
|
||||
document_write_do(JSContext *ctx, unsigned int argc, jsval *rval, int newline)
|
||||
{
|
||||
jsval val;
|
||||
struct ecmascript_interpreter *interpreter = JS_GetContextPrivate(ctx);
|
||||
@ -290,7 +433,7 @@ document_write_do(JSContext *ctx, uintN argc, jsval *rval, int newline)
|
||||
|
||||
/* @document_funcs{"write"} */
|
||||
static JSBool
|
||||
document_write(JSContext *ctx, uintN argc, jsval *rval)
|
||||
document_write(JSContext *ctx, unsigned int argc, jsval *rval)
|
||||
{
|
||||
|
||||
return document_write_do(ctx, argc, rval, 0);
|
||||
@ -298,7 +441,7 @@ document_write(JSContext *ctx, uintN argc, jsval *rval)
|
||||
|
||||
/* @document_funcs{"writeln"} */
|
||||
static JSBool
|
||||
document_writeln(JSContext *ctx, uintN argc, jsval *rval)
|
||||
document_writeln(JSContext *ctx, unsigned int argc, jsval *rval)
|
||||
{
|
||||
return document_write_do(ctx, argc, rval, 1);
|
||||
}
|
||||
|
@ -4,8 +4,8 @@
|
||||
|
||||
#include "ecmascript/spidermonkey/util.h"
|
||||
|
||||
extern const JSClass document_class;
|
||||
extern JSClass document_class;
|
||||
extern const spidermonkeyFunctionSpec document_funcs[];
|
||||
extern const JSPropertySpec document_props[];
|
||||
extern JSPropertySpec document_props[];
|
||||
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -6,9 +6,9 @@
|
||||
|
||||
struct form_view;
|
||||
|
||||
extern const JSClass forms_class;
|
||||
extern JSClass forms_class;
|
||||
extern const spidermonkeyFunctionSpec forms_funcs[];
|
||||
extern const JSPropertySpec forms_props[];
|
||||
extern JSPropertySpec forms_props[];
|
||||
|
||||
JSObject *get_form_object(JSContext *ctx, JSObject *jsdoc, struct form_view *fv);
|
||||
|
||||
|
@ -36,7 +36,7 @@ static struct itimerval heartbeat_timer = { { 1, 0 }, { 1, 0 } };
|
||||
JSBool
|
||||
heartbeat_callback(JSContext *ctx)
|
||||
{
|
||||
return JS_FALSE;
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
/* Callback for SIGVTALRM. Go through all heartbeats, decrease each
|
||||
@ -45,31 +45,28 @@ heartbeat_callback(JSContext *ctx)
|
||||
static void
|
||||
check_heartbeats(void *data)
|
||||
{
|
||||
struct heartbeat *hb;
|
||||
struct heartbeat *hb;
|
||||
|
||||
foreach (hb, heartbeats) {
|
||||
foreach (hb, heartbeats) {
|
||||
assert(hb->interpreter);
|
||||
--hb->ttl;
|
||||
|
||||
--hb->ttl;
|
||||
|
||||
if (hb->ttl <= 0) {
|
||||
if (hb->ttl <= 0) {
|
||||
if (hb->interpreter->vs
|
||||
&& hb->interpreter->vs->doc_view
|
||||
&& hb->interpreter->vs->doc_view->session
|
||||
&& hb->interpreter->vs->doc_view->session->tab
|
||||
&& hb->interpreter->vs->doc_view->session->tab->term) {
|
||||
&& hb->interpreter->vs->doc_view
|
||||
&& hb->interpreter->vs->doc_view->session
|
||||
&& hb->interpreter->vs->doc_view->session->tab
|
||||
&& hb->interpreter->vs->doc_view->session->tab->term) {
|
||||
struct session *ses = hb->interpreter->vs->doc_view->session;
|
||||
struct terminal *term = ses->tab->term;
|
||||
int max_exec_time = get_opt_int("ecmascript.max_exec_time", ses);
|
||||
|
||||
ecmascript_timeout_dialog(term, max_exec_time);
|
||||
}
|
||||
|
||||
JS_TriggerOperationCallback(hb->interpreter->backend_data);
|
||||
}
|
||||
}
|
||||
|
||||
install_signal_handler(SIGVTALRM, check_heartbeats, NULL, 1);
|
||||
JS_TriggerOperationCallback(JS_GetRuntime(hb->interpreter->backend_data));
|
||||
}
|
||||
}
|
||||
install_signal_handler(SIGVTALRM, check_heartbeats, NULL, 1);
|
||||
}
|
||||
|
||||
/* Create a new heartbeat for the given interpreter. */
|
||||
@ -77,7 +74,7 @@ struct heartbeat *
|
||||
add_heartbeat(struct ecmascript_interpreter *interpreter)
|
||||
{
|
||||
struct session *ses;
|
||||
struct heartbeat *hb;
|
||||
struct heartbeat *hb;
|
||||
|
||||
assert(interpreter);
|
||||
|
||||
@ -85,27 +82,26 @@ add_heartbeat(struct ecmascript_interpreter *interpreter)
|
||||
ses = NULL;
|
||||
else
|
||||
ses = interpreter->vs->doc_view->session;
|
||||
hb = mem_alloc(sizeof(struct heartbeat));
|
||||
|
||||
hb = mem_alloc(sizeof(struct heartbeat));
|
||||
if (!hb) return NULL;
|
||||
if (!hb) return NULL;
|
||||
|
||||
hb->ttl = get_opt_int("ecmascript.max_exec_time", ses);
|
||||
hb->interpreter = interpreter;
|
||||
hb->ttl = get_opt_int("ecmascript.max_exec_time", ses);
|
||||
hb->interpreter = interpreter;
|
||||
add_to_list(heartbeats, hb);
|
||||
|
||||
add_to_list(heartbeats, hb);
|
||||
/* Update the heartbeat timer. */
|
||||
if (list_is_singleton(*hb)) {
|
||||
heartbeat_timer.it_value.tv_sec = 1;
|
||||
setitimer(ITIMER_VIRTUAL, &heartbeat_timer, NULL);
|
||||
}
|
||||
|
||||
/* Update the heartbeat timer. */
|
||||
if (list_is_singleton(*hb)) {
|
||||
heartbeat_timer.it_value.tv_sec = 1;
|
||||
setitimer(ITIMER_VIRTUAL, &heartbeat_timer, NULL);
|
||||
}
|
||||
/* We install the handler every call to add_heartbeat instead of only on
|
||||
* module initialisation because other code may set other handlers for
|
||||
* the signal. */
|
||||
install_signal_handler(SIGVTALRM, check_heartbeats, NULL, 1);
|
||||
|
||||
/* We install the handler every call to add_heartbeat instead of only on
|
||||
* module initialisation because other code may set other handlers for
|
||||
* the signal. */
|
||||
install_signal_handler(SIGVTALRM, check_heartbeats, NULL, 1);
|
||||
|
||||
return hb;
|
||||
return hb;
|
||||
}
|
||||
|
||||
/* Destroy the given heartbeat. */
|
||||
@ -115,13 +111,13 @@ done_heartbeat(struct heartbeat *hb)
|
||||
if (!hb) return; /* add_heartbeat returned NULL */
|
||||
assert(hb->interpreter);
|
||||
|
||||
/* Stop the heartbeat timer if this heartbeat is the only one. */
|
||||
if (list_is_singleton(*hb)) {
|
||||
heartbeat_timer.it_value.tv_sec = 0;
|
||||
setitimer(ITIMER_VIRTUAL, &heartbeat_timer, NULL);
|
||||
}
|
||||
/* Stop the heartbeat timer if this heartbeat is the only one. */
|
||||
if (list_is_singleton(*hb)) {
|
||||
heartbeat_timer.it_value.tv_sec = 0;
|
||||
setitimer(ITIMER_VIRTUAL, &heartbeat_timer, NULL);
|
||||
}
|
||||
|
||||
del_from_list(hb);
|
||||
hb->interpreter->heartbeat = NULL;
|
||||
mem_free(hb);
|
||||
del_from_list(hb);
|
||||
hb->interpreter->heartbeat = NULL;
|
||||
mem_free(hb);
|
||||
}
|
||||
|
@ -45,16 +45,16 @@
|
||||
#include "viewer/text/vs.h"
|
||||
|
||||
|
||||
static JSBool history_back(JSContext *ctx, uintN argc, jsval *rval);
|
||||
static JSBool history_forward(JSContext *ctx, uintN argc, jsval *rval);
|
||||
static JSBool history_go(JSContext *ctx, uintN argc, jsval *rval);
|
||||
static JSBool history_back(JSContext *ctx, unsigned int argc, jsval *rval);
|
||||
static JSBool history_forward(JSContext *ctx, unsigned int argc, jsval *rval);
|
||||
static JSBool history_go(JSContext *ctx, unsigned int argc, jsval *rval);
|
||||
|
||||
const JSClass history_class = {
|
||||
JSClass history_class = {
|
||||
"history",
|
||||
JSCLASS_HAS_PRIVATE,
|
||||
JS_PropertyStub, JS_PropertyStub,
|
||||
JS_PropertyStub, JS_StrictPropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, NULL
|
||||
};
|
||||
|
||||
const spidermonkeyFunctionSpec history_funcs[] = {
|
||||
@ -66,7 +66,7 @@ const spidermonkeyFunctionSpec history_funcs[] = {
|
||||
|
||||
/* @history_funcs{"back"} */
|
||||
static JSBool
|
||||
history_back(JSContext *ctx, uintN argc, jsval *rval)
|
||||
history_back(JSContext *ctx, unsigned int argc, jsval *rval)
|
||||
{
|
||||
struct ecmascript_interpreter *interpreter = JS_GetContextPrivate(ctx);
|
||||
struct document_view *doc_view = interpreter->vs->doc_view;
|
||||
@ -84,7 +84,7 @@ history_back(JSContext *ctx, uintN argc, jsval *rval)
|
||||
|
||||
/* @history_funcs{"forward"} */
|
||||
static JSBool
|
||||
history_forward(JSContext *ctx, uintN argc, jsval *rval)
|
||||
history_forward(JSContext *ctx, unsigned int argc, jsval *rval)
|
||||
{
|
||||
struct ecmascript_interpreter *interpreter = JS_GetContextPrivate(ctx);
|
||||
struct document_view *doc_view = interpreter->vs->doc_view;
|
||||
@ -98,7 +98,7 @@ history_forward(JSContext *ctx, uintN argc, jsval *rval)
|
||||
|
||||
/* @history_funcs{"go"} */
|
||||
static JSBool
|
||||
history_go(JSContext *ctx, uintN argc, jsval *rval)
|
||||
history_go(JSContext *ctx, unsigned int argc, jsval *rval)
|
||||
{
|
||||
struct ecmascript_interpreter *interpreter = JS_GetContextPrivate(ctx);
|
||||
struct document_view *doc_view = interpreter->vs->doc_view;
|
||||
@ -128,16 +128,16 @@ history_go(JSContext *ctx, uintN argc, jsval *rval)
|
||||
}
|
||||
|
||||
|
||||
static JSBool location_get_property(JSContext *ctx, JSObject *obj, jsid id, jsval *vp);
|
||||
static JSBool location_set_property(JSContext *ctx, JSObject *obj, jsid id, JSBool strict, jsval *vp);
|
||||
static JSBool location_get_property_href(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSMutableHandleValue hvp);
|
||||
static JSBool location_set_property_href(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSBool strict, JSMutableHandleValue hvp);
|
||||
|
||||
/* Each @location_class object must have a @window_class parent. */
|
||||
const JSClass location_class = {
|
||||
JSClass location_class = {
|
||||
"location",
|
||||
JSCLASS_HAS_PRIVATE,
|
||||
JS_PropertyStub, JS_PropertyStub,
|
||||
location_get_property, location_set_property,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub
|
||||
JS_PropertyStub, JS_StrictPropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, NULL
|
||||
};
|
||||
|
||||
/* Tinyids of properties. Use negative values to distinguish these
|
||||
@ -147,56 +147,41 @@ const JSClass location_class = {
|
||||
enum location_prop {
|
||||
JSP_LOC_HREF = -1,
|
||||
};
|
||||
const JSPropertySpec location_props[] = {
|
||||
{ "href", JSP_LOC_HREF, JSPROP_ENUMERATE },
|
||||
JSPropertySpec location_props[] = {
|
||||
{ "href", 0, JSPROP_ENUMERATE|JSPROP_SHARED, JSOP_WRAPPER(location_get_property_href), JSOP_WRAPPER(location_set_property_href) },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
/* @location_class.getProperty */
|
||||
|
||||
static JSBool
|
||||
location_get_property(JSContext *ctx, JSObject *obj, jsid id, jsval *vp)
|
||||
location_get_property_href(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSMutableHandleValue hvp)
|
||||
{
|
||||
ELINKS_CAST_PROP_PARAMS
|
||||
|
||||
JSObject *parent_win; /* instance of @window_class */
|
||||
struct view_state *vs;
|
||||
|
||||
/* This can be called if @obj if not itself an instance of the
|
||||
* appropriate class but has one in its prototype chain. Fail
|
||||
* such calls. */
|
||||
if (!JS_InstanceOf(ctx, obj, (JSClass *) &location_class, NULL))
|
||||
if (!JS_InstanceOf(ctx, obj, &location_class, NULL))
|
||||
return JS_FALSE;
|
||||
parent_win = JS_GetParent(ctx, obj);
|
||||
assert(JS_InstanceOf(ctx, parent_win, (JSClass *) &window_class, NULL));
|
||||
parent_win = JS_GetParent(obj);
|
||||
assert(JS_InstanceOf(ctx, parent_win, &window_class, NULL));
|
||||
if_assert_failed return JS_FALSE;
|
||||
|
||||
vs = JS_GetInstancePrivate(ctx, parent_win,
|
||||
(JSClass *) &window_class, NULL);
|
||||
&window_class, NULL);
|
||||
|
||||
if (!JSID_IS_INT(id))
|
||||
return JS_TRUE;
|
||||
|
||||
undef_to_jsval(ctx, vp);
|
||||
|
||||
switch (JSID_TO_INT(id)) {
|
||||
case JSP_LOC_HREF:
|
||||
astring_to_jsval(ctx, vp, get_uri_string(vs->uri, URI_ORIGINAL));
|
||||
break;
|
||||
default:
|
||||
/* Unrecognized integer property ID; someone is using
|
||||
* the object as an array. SMJS builtin classes (e.g.
|
||||
* js_RegExpClass) just return JS_TRUE in this case
|
||||
* and leave *@vp unchanged. Do the same here.
|
||||
* (Actually not quite the same, as we already used
|
||||
* @undef_to_jsval.) */
|
||||
break;
|
||||
}
|
||||
astring_to_jsval(ctx, vp, get_uri_string(vs->uri, URI_ORIGINAL));
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
/* @location_class.setProperty */
|
||||
static JSBool
|
||||
location_set_property(JSContext *ctx, JSObject *obj, jsid id, JSBool strict, jsval *vp)
|
||||
location_set_property_href(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSBool strict, JSMutableHandleValue hvp)
|
||||
{
|
||||
ELINKS_CAST_PROP_PARAMS
|
||||
JSObject *parent_win; /* instance of @window_class */
|
||||
struct view_state *vs;
|
||||
struct document_view *doc_view;
|
||||
@ -204,29 +189,22 @@ location_set_property(JSContext *ctx, JSObject *obj, jsid id, JSBool strict, jsv
|
||||
/* This can be called if @obj if not itself an instance of the
|
||||
* appropriate class but has one in its prototype chain. Fail
|
||||
* such calls. */
|
||||
if (!JS_InstanceOf(ctx, obj, (JSClass *) &location_class, NULL))
|
||||
if (!JS_InstanceOf(ctx, obj, &location_class, NULL))
|
||||
return JS_FALSE;
|
||||
parent_win = JS_GetParent(ctx, obj);
|
||||
assert(JS_InstanceOf(ctx, parent_win, (JSClass *) &window_class, NULL));
|
||||
parent_win = JS_GetParent(obj);
|
||||
assert(JS_InstanceOf(ctx, parent_win, &window_class, NULL));
|
||||
if_assert_failed return JS_FALSE;
|
||||
|
||||
vs = JS_GetInstancePrivate(ctx, parent_win,
|
||||
(JSClass *) &window_class, NULL);
|
||||
&window_class, NULL);
|
||||
doc_view = vs->doc_view;
|
||||
|
||||
if (!JSID_IS_INT(id))
|
||||
return JS_TRUE;
|
||||
|
||||
switch (JSID_TO_INT(id)) {
|
||||
case JSP_LOC_HREF:
|
||||
location_goto(doc_view, jsval_to_string(ctx, vp));
|
||||
break;
|
||||
}
|
||||
location_goto(doc_view, jsval_to_string(ctx, vp));
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSBool location_toString(JSContext *ctx, uintN argc, jsval *rval);
|
||||
|
||||
static JSBool location_toString(JSContext *ctx, unsigned int argc, jsval *rval);
|
||||
|
||||
const spidermonkeyFunctionSpec location_funcs[] = {
|
||||
{ "toString", location_toString, 0 },
|
||||
@ -236,7 +214,7 @@ const spidermonkeyFunctionSpec location_funcs[] = {
|
||||
|
||||
/* @location_funcs{"toString"}, @location_funcs{"toLocaleString"} */
|
||||
static JSBool
|
||||
location_toString(JSContext *ctx, uintN argc, jsval *rval)
|
||||
location_toString(JSContext *ctx, unsigned int argc, jsval *rval)
|
||||
{
|
||||
jsval val;
|
||||
JSObject *obj = JS_THIS_OBJECT(ctx, rval);
|
||||
|
@ -6,12 +6,12 @@
|
||||
|
||||
struct document_view;
|
||||
|
||||
extern const JSClass history_class;
|
||||
extern JSClass history_class;
|
||||
extern const spidermonkeyFunctionSpec history_funcs[];
|
||||
|
||||
extern const JSClass location_class;
|
||||
extern JSClass location_class;
|
||||
extern const spidermonkeyFunctionSpec location_funcs[];
|
||||
extern const JSPropertySpec location_props[];
|
||||
extern JSPropertySpec location_props[];
|
||||
|
||||
void location_goto(struct document_view *doc_view, unsigned char *url);
|
||||
|
||||
|
@ -44,14 +44,19 @@
|
||||
#include "viewer/text/vs.h"
|
||||
|
||||
|
||||
static JSBool navigator_get_property(JSContext *ctx, JSObject *obj, jsid id, jsval *vp);
|
||||
static JSBool navigator_get_property_appCodeName(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSMutableHandleValue hvp);
|
||||
static JSBool navigator_get_property_appName(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSMutableHandleValue hvp);
|
||||
static JSBool navigator_get_property_appVersion(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSMutableHandleValue hvp);
|
||||
static JSBool navigator_get_property_language(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSMutableHandleValue hvp);
|
||||
static JSBool navigator_get_property_platform(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSMutableHandleValue hvp);
|
||||
static JSBool navigator_get_property_userAgent(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSMutableHandleValue hvp);
|
||||
|
||||
const JSClass navigator_class = {
|
||||
JSClass navigator_class = {
|
||||
"navigator",
|
||||
JSCLASS_HAS_PRIVATE,
|
||||
JS_PropertyStub, JS_PropertyStub,
|
||||
navigator_get_property, JS_StrictPropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub
|
||||
JS_PropertyStub, JS_StrictPropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, NULL
|
||||
};
|
||||
|
||||
/* Tinyids of properties. Use negative values to distinguish these
|
||||
@ -61,94 +66,119 @@ const JSClass navigator_class = {
|
||||
enum navigator_prop {
|
||||
JSP_NAVIGATOR_APP_CODENAME = -1,
|
||||
JSP_NAVIGATOR_APP_NAME = -2,
|
||||
JSP_NAVIGATOR_APP_VERSION = -3,
|
||||
JSP_NAVIGATOR_APP_VERSION = -3,
|
||||
JSP_NAVIGATOR_LANGUAGE = -4,
|
||||
/* JSP_NAVIGATOR_MIME_TYPES = -5, */
|
||||
JSP_NAVIGATOR_PLATFORM = -6,
|
||||
/* JSP_NAVIGATOR_PLUGINS = -7, */
|
||||
JSP_NAVIGATOR_USER_AGENT = -8,
|
||||
};
|
||||
const JSPropertySpec navigator_props[] = {
|
||||
{ "appCodeName", JSP_NAVIGATOR_APP_CODENAME, JSPROP_ENUMERATE | JSPROP_READONLY },
|
||||
{ "appName", JSP_NAVIGATOR_APP_NAME, JSPROP_ENUMERATE | JSPROP_READONLY },
|
||||
{ "appVersion", JSP_NAVIGATOR_APP_VERSION, JSPROP_ENUMERATE | JSPROP_READONLY },
|
||||
{ "language", JSP_NAVIGATOR_LANGUAGE, JSPROP_ENUMERATE | JSPROP_READONLY },
|
||||
{ "platform", JSP_NAVIGATOR_PLATFORM, JSPROP_ENUMERATE | JSPROP_READONLY },
|
||||
{ "userAgent", JSP_NAVIGATOR_USER_AGENT, JSPROP_ENUMERATE | JSPROP_READONLY },
|
||||
JSPropertySpec navigator_props[] = {
|
||||
{ "appCodeName",0, JSPROP_ENUMERATE | JSPROP_READONLY|JSPROP_SHARED, JSOP_WRAPPER(navigator_get_property_appCodeName), JSOP_NULLWRAPPER },
|
||||
{ "appName", 0, JSPROP_ENUMERATE | JSPROP_READONLY|JSPROP_SHARED, JSOP_WRAPPER(navigator_get_property_appName), JSOP_NULLWRAPPER },
|
||||
{ "appVersion", 0, JSPROP_ENUMERATE | JSPROP_READONLY|JSPROP_SHARED, JSOP_WRAPPER(navigator_get_property_appVersion), JSOP_NULLWRAPPER },
|
||||
{ "language", 0, JSPROP_ENUMERATE | JSPROP_READONLY|JSPROP_SHARED, JSOP_WRAPPER(navigator_get_property_language), JSOP_NULLWRAPPER },
|
||||
{ "platform", 0, JSPROP_ENUMERATE | JSPROP_READONLY|JSPROP_SHARED, JSOP_WRAPPER(navigator_get_property_platform), JSOP_NULLWRAPPER },
|
||||
{ "userAgent", 0, JSPROP_ENUMERATE | JSPROP_READONLY|JSPROP_SHARED, JSOP_WRAPPER(navigator_get_property_userAgent), JSOP_NULLWRAPPER },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
|
||||
/* @navigator_class.getProperty */
|
||||
|
||||
static JSBool
|
||||
navigator_get_property(JSContext *ctx, JSObject *obj, jsid id, jsval *vp)
|
||||
navigator_get_property_appCodeName(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSMutableHandleValue hvp)
|
||||
{
|
||||
if (!JSID_IS_INT(id))
|
||||
return JS_TRUE;
|
||||
ELINKS_CAST_PROP_PARAMS
|
||||
(void)obj;
|
||||
|
||||
undef_to_jsval(ctx, vp);
|
||||
|
||||
switch (JSID_TO_INT(id)) {
|
||||
case JSP_NAVIGATOR_APP_CODENAME:
|
||||
string_to_jsval(ctx, vp, "Mozilla"); /* More like a constant nowadays. */
|
||||
break;
|
||||
case JSP_NAVIGATOR_APP_NAME:
|
||||
/* This evil hack makes the compatibility checking .indexOf()
|
||||
* code find what it's looking for. */
|
||||
string_to_jsval(ctx, vp, "ELinks (roughly compatible with Netscape Navigator, Mozilla and Microsoft Internet Explorer)");
|
||||
break;
|
||||
case JSP_NAVIGATOR_APP_VERSION:
|
||||
string_to_jsval(ctx, vp, VERSION);
|
||||
break;
|
||||
case JSP_NAVIGATOR_LANGUAGE:
|
||||
#ifdef CONFIG_NLS
|
||||
if (get_opt_bool("protocol.http.accept_ui_language", NULL))
|
||||
string_to_jsval(ctx, vp, language_to_iso639(current_language));
|
||||
|
||||
#endif
|
||||
break;
|
||||
case JSP_NAVIGATOR_PLATFORM:
|
||||
string_to_jsval(ctx, vp, system_name);
|
||||
break;
|
||||
case JSP_NAVIGATOR_USER_AGENT:
|
||||
{
|
||||
/* FIXME: Code duplication. */
|
||||
unsigned char *optstr = get_opt_str("protocol.http.user_agent",
|
||||
NULL);
|
||||
|
||||
if (*optstr && strcmp(optstr, " ")) {
|
||||
unsigned char *ustr, ts[64] = "";
|
||||
static unsigned char custr[256];
|
||||
/* TODO: Somehow get the terminal in which the
|
||||
* document is actually being displayed. */
|
||||
struct terminal *term = get_default_terminal();
|
||||
|
||||
if (term) {
|
||||
unsigned int tslen = 0;
|
||||
|
||||
ulongcat(ts, &tslen, term->width, 3, 0);
|
||||
ts[tslen++] = 'x';
|
||||
ulongcat(ts, &tslen, term->height, 3, 0);
|
||||
}
|
||||
ustr = subst_user_agent(optstr, VERSION_STRING, system_name, ts);
|
||||
|
||||
if (ustr) {
|
||||
safe_strncpy(custr, ustr, 256);
|
||||
mem_free(ustr);
|
||||
string_to_jsval(ctx, vp, custr);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* Unrecognized integer property ID; someone is using
|
||||
* the object as an array. SMJS builtin classes (e.g.
|
||||
* js_RegExpClass) just return JS_TRUE in this case
|
||||
* and leave *@vp unchanged. Do the same here.
|
||||
* (Actually not quite the same, as we already used
|
||||
* @undef_to_jsval.) */
|
||||
break;
|
||||
}
|
||||
string_to_jsval(ctx, vp, "Mozilla"); /* More like a constant nowadays. */
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
navigator_get_property_appName(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSMutableHandleValue hvp)
|
||||
{
|
||||
ELINKS_CAST_PROP_PARAMS
|
||||
(void)obj;
|
||||
|
||||
string_to_jsval(ctx, vp, "ELinks (roughly compatible with Netscape Navigator, Mozilla and Microsoft Internet Explorer)");
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
navigator_get_property_appVersion(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSMutableHandleValue hvp)
|
||||
{
|
||||
ELINKS_CAST_PROP_PARAMS
|
||||
(void)obj;
|
||||
|
||||
string_to_jsval(ctx, vp, VERSION);
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
navigator_get_property_language(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSMutableHandleValue hvp)
|
||||
{
|
||||
ELINKS_CAST_PROP_PARAMS
|
||||
(void)obj;
|
||||
|
||||
undef_to_jsval(ctx, vp);
|
||||
#ifdef CONFIG_NLS
|
||||
if (get_opt_bool("protocol.http.accept_ui_language", NULL))
|
||||
string_to_jsval(ctx, vp, language_to_iso639(current_language));
|
||||
|
||||
#endif
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
navigator_get_property_platform(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSMutableHandleValue hvp)
|
||||
{
|
||||
ELINKS_CAST_PROP_PARAMS
|
||||
(void)obj;
|
||||
|
||||
string_to_jsval(ctx, vp, system_name);
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
navigator_get_property_userAgent(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSMutableHandleValue hvp)
|
||||
{
|
||||
ELINKS_CAST_PROP_PARAMS
|
||||
unsigned char *optstr;
|
||||
(void)obj;
|
||||
|
||||
optstr = get_opt_str("protocol.http.user_agent", NULL);
|
||||
|
||||
if (*optstr && strcmp(optstr, " ")) {
|
||||
unsigned char *ustr, ts[64] = "";
|
||||
static unsigned char custr[256];
|
||||
/* TODO: Somehow get the terminal in which the
|
||||
* document is actually being displayed. */
|
||||
struct terminal *term = get_default_terminal();
|
||||
|
||||
if (term) {
|
||||
unsigned int tslen = 0;
|
||||
|
||||
ulongcat(ts, &tslen, term->width, 3, 0);
|
||||
ts[tslen++] = 'x';
|
||||
ulongcat(ts, &tslen, term->height, 3, 0);
|
||||
}
|
||||
ustr = subst_user_agent(optstr, VERSION_STRING, system_name, ts);
|
||||
|
||||
if (ustr) {
|
||||
safe_strncpy(custr, ustr, 256);
|
||||
mem_free(ustr);
|
||||
string_to_jsval(ctx, vp, custr);
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
}
|
||||
string_to_jsval(ctx, vp, system_name);
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
#include "ecmascript/spidermonkey/util.h"
|
||||
|
||||
extern const JSClass navigator_class;
|
||||
extern const JSPropertySpec navigator_props[];
|
||||
extern JSClass navigator_class;
|
||||
extern JSPropertySpec navigator_props[];
|
||||
|
||||
#endif
|
||||
|
@ -44,25 +44,24 @@
|
||||
#include "viewer/text/link.h"
|
||||
#include "viewer/text/vs.h"
|
||||
|
||||
|
||||
static JSBool unibar_get_property(JSContext *ctx, JSObject *obj, jsid id, jsval *vp);
|
||||
static JSBool unibar_set_property(JSContext *ctx, JSObject *obj, jsid id, JSBool strict, jsval *vp);
|
||||
static JSBool unibar_get_property_visible(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSMutableHandleValue hvp);
|
||||
static JSBool unibar_set_property_visible(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSBool strict, JSMutableHandleValue hvp);
|
||||
|
||||
/* Each @menubar_class object must have a @window_class parent. */
|
||||
const JSClass menubar_class = {
|
||||
JSClass menubar_class = {
|
||||
"menubar",
|
||||
JSCLASS_HAS_PRIVATE, /* const char * "t" */
|
||||
JS_PropertyStub, JS_PropertyStub,
|
||||
unibar_get_property, unibar_set_property,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub
|
||||
JS_PropertyStub, JS_StrictPropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, NULL
|
||||
};
|
||||
/* Each @statusbar_class object must have a @window_class parent. */
|
||||
const JSClass statusbar_class = {
|
||||
JSClass statusbar_class = {
|
||||
"statusbar",
|
||||
JSCLASS_HAS_PRIVATE, /* const char * "s" */
|
||||
JS_PropertyStub, JS_PropertyStub,
|
||||
unibar_get_property, unibar_set_property,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub
|
||||
JS_PropertyStub, JS_StrictPropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, NULL
|
||||
};
|
||||
|
||||
/* Tinyids of properties. Use negative values to distinguish these
|
||||
@ -72,16 +71,18 @@ const JSClass statusbar_class = {
|
||||
enum unibar_prop {
|
||||
JSP_UNIBAR_VISIBLE = -1,
|
||||
};
|
||||
const JSPropertySpec unibar_props[] = {
|
||||
{ "visible", JSP_UNIBAR_VISIBLE, JSPROP_ENUMERATE },
|
||||
JSPropertySpec unibar_props[] = {
|
||||
{ "visible", 0, JSPROP_ENUMERATE|JSPROP_SHARED, JSOP_WRAPPER(unibar_get_property_visible), JSOP_WRAPPER(unibar_set_property_visible) },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
|
||||
/* @menubar_class.getProperty, @statusbar_class.getProperty */
|
||||
|
||||
static JSBool
|
||||
unibar_get_property(JSContext *ctx, JSObject *obj, jsid id, jsval *vp)
|
||||
unibar_get_property_visible(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSMutableHandleValue hvp)
|
||||
{
|
||||
ELINKS_CAST_PROP_PARAMS
|
||||
|
||||
JSObject *parent_win; /* instance of @window_class */
|
||||
struct view_state *vs;
|
||||
struct document_view *doc_view;
|
||||
@ -91,56 +92,44 @@ unibar_get_property(JSContext *ctx, JSObject *obj, jsid id, jsval *vp)
|
||||
/* This can be called if @obj if not itself an instance of either
|
||||
* appropriate class but has one in its prototype chain. Fail
|
||||
* such calls. */
|
||||
if (!JS_InstanceOf(ctx, obj, (JSClass *) &menubar_class, NULL)
|
||||
&& !JS_InstanceOf(ctx, obj, (JSClass *) &statusbar_class, NULL))
|
||||
if (!JS_InstanceOf(ctx, obj, &menubar_class, NULL)
|
||||
&& !JS_InstanceOf(ctx, obj, &statusbar_class, NULL))
|
||||
return JS_FALSE;
|
||||
parent_win = JS_GetParent(ctx, obj);
|
||||
assert(JS_InstanceOf(ctx, parent_win, (JSClass *) &window_class, NULL));
|
||||
parent_win = JS_GetParent(obj);
|
||||
assert(JS_InstanceOf(ctx, parent_win, &window_class, NULL));
|
||||
if_assert_failed return JS_FALSE;
|
||||
|
||||
vs = JS_GetInstancePrivate(ctx, parent_win,
|
||||
(JSClass *) &window_class, NULL);
|
||||
&window_class, NULL);
|
||||
doc_view = vs->doc_view;
|
||||
status = &doc_view->session->status;
|
||||
bar = JS_GetPrivate(ctx, obj); /* from @menubar_class or @statusbar_class */
|
||||
bar = JS_GetPrivate(obj); /* from @menubar_class or @statusbar_class */
|
||||
|
||||
if (!JSID_IS_INT(id))
|
||||
return JS_TRUE;
|
||||
|
||||
switch (JSID_TO_INT(id)) {
|
||||
case JSP_UNIBAR_VISIBLE:
|
||||
#define unibar_fetch(bar) \
|
||||
boolean_to_jsval(ctx, vp, status->force_show_##bar##_bar >= 0 \
|
||||
? status->force_show_##bar##_bar \
|
||||
: status->show_##bar##_bar)
|
||||
switch (*bar) {
|
||||
case 's':
|
||||
unibar_fetch(status);
|
||||
break;
|
||||
case 't':
|
||||
unibar_fetch(title);
|
||||
break;
|
||||
default:
|
||||
boolean_to_jsval(ctx, vp, 0);
|
||||
break;
|
||||
}
|
||||
#undef unibar_fetch
|
||||
switch (*bar) {
|
||||
case 's':
|
||||
unibar_fetch(status);
|
||||
break;
|
||||
case 't':
|
||||
unibar_fetch(title);
|
||||
break;
|
||||
default:
|
||||
/* Unrecognized integer property ID; someone is using
|
||||
* the object as an array. SMJS builtin classes (e.g.
|
||||
* js_RegExpClass) just return JS_TRUE in this case
|
||||
* and leave *@vp unchanged. Do the same here. */
|
||||
boolean_to_jsval(ctx, vp, 0);
|
||||
break;
|
||||
}
|
||||
#undef unibar_fetch
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
/* @menubar_class.setProperty, @statusbar_class.setProperty */
|
||||
static JSBool
|
||||
unibar_set_property(JSContext *ctx, JSObject *obj, jsid id, JSBool strict, jsval *vp)
|
||||
unibar_set_property_visible(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSBool strict, JSMutableHandleValue hvp)
|
||||
{
|
||||
ELINKS_CAST_PROP_PARAMS
|
||||
|
||||
JSObject *parent_win; /* instance of @window_class */
|
||||
struct view_state *vs;
|
||||
struct document_view *doc_view;
|
||||
@ -150,43 +139,30 @@ unibar_set_property(JSContext *ctx, JSObject *obj, jsid id, JSBool strict, jsval
|
||||
/* This can be called if @obj if not itself an instance of either
|
||||
* appropriate class but has one in its prototype chain. Fail
|
||||
* such calls. */
|
||||
if (!JS_InstanceOf(ctx, obj, (JSClass *) &menubar_class, NULL)
|
||||
&& !JS_InstanceOf(ctx, obj, (JSClass *) &statusbar_class, NULL))
|
||||
if (!JS_InstanceOf(ctx, obj, &menubar_class, NULL)
|
||||
&& !JS_InstanceOf(ctx, obj, &statusbar_class, NULL))
|
||||
return JS_FALSE;
|
||||
parent_win = JS_GetParent(ctx, obj);
|
||||
assert(JS_InstanceOf(ctx, parent_win, (JSClass *) &window_class, NULL));
|
||||
parent_win = JS_GetParent(obj);
|
||||
assert(JS_InstanceOf(ctx, parent_win, &window_class, NULL));
|
||||
if_assert_failed return JS_FALSE;
|
||||
|
||||
vs = JS_GetInstancePrivate(ctx, parent_win,
|
||||
(JSClass *) &window_class, NULL);
|
||||
&window_class, NULL);
|
||||
doc_view = vs->doc_view;
|
||||
status = &doc_view->session->status;
|
||||
bar = JS_GetPrivate(ctx, obj); /* from @menubar_class or @statusbar_class */
|
||||
bar = JS_GetPrivate(obj); /* from @menubar_class or @statusbar_class */
|
||||
|
||||
if (!JSID_IS_INT(id))
|
||||
return JS_TRUE;
|
||||
|
||||
switch (JSID_TO_INT(id)) {
|
||||
case JSP_UNIBAR_VISIBLE:
|
||||
switch (*bar) {
|
||||
case 's':
|
||||
status->force_show_status_bar = jsval_to_boolean(ctx, vp);
|
||||
break;
|
||||
case 't':
|
||||
status->force_show_title_bar = jsval_to_boolean(ctx, vp);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
register_bottom_half(update_status, NULL);
|
||||
switch (*bar) {
|
||||
case 's':
|
||||
status->force_show_status_bar = jsval_to_boolean(ctx, vp);
|
||||
break;
|
||||
case 't':
|
||||
status->force_show_title_bar = jsval_to_boolean(ctx, vp);
|
||||
break;
|
||||
default:
|
||||
/* Unrecognized integer property ID; someone is using
|
||||
* the object as an array. SMJS builtin classes (e.g.
|
||||
* js_RegExpClass) just return JS_TRUE in this case.
|
||||
* Do the same here. */
|
||||
return JS_TRUE;
|
||||
break;
|
||||
}
|
||||
register_bottom_half(update_status, NULL);
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
@ -4,8 +4,8 @@
|
||||
|
||||
#include "ecmascript/spidermonkey/util.h"
|
||||
|
||||
extern const JSClass menubar_class;
|
||||
extern const JSClass statusbar_class;
|
||||
extern const JSPropertySpec unibar_props[];
|
||||
extern JSClass menubar_class;
|
||||
extern JSClass statusbar_class;
|
||||
extern JSPropertySpec unibar_props[];
|
||||
|
||||
#endif
|
||||
|
@ -44,15 +44,21 @@
|
||||
#include "viewer/text/vs.h"
|
||||
|
||||
|
||||
static JSBool window_get_property(JSContext *ctx, JSObject *obj, jsid id, jsval *vp);
|
||||
static JSBool window_set_property(JSContext *ctx, JSObject *obj, jsid id, JSBool strict, jsval *vp);
|
||||
static JSBool window_get_property(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSMutableHandleValue hvp);
|
||||
static JSBool window_get_property_closed(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSMutableHandleValue hvp);
|
||||
static JSBool window_get_property_parent(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSMutableHandleValue hvp);
|
||||
static JSBool window_get_property_self(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSMutableHandleValue hvp);
|
||||
static JSBool window_get_property_status(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSMutableHandleValue hvp);
|
||||
static JSBool window_set_property_status(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSBool strict, JSMutableHandleValue hvp);
|
||||
static JSBool window_get_property_top(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSMutableHandleValue hvp);
|
||||
static JSBool window_get_property_window(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSMutableHandleValue hvp);
|
||||
|
||||
const JSClass window_class = {
|
||||
JSClass window_class = {
|
||||
"window",
|
||||
JSCLASS_HAS_PRIVATE | JSCLASS_GLOBAL_FLAGS, /* struct view_state * */
|
||||
JS_PropertyStub, JS_PropertyStub,
|
||||
window_get_property, window_set_property,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub
|
||||
window_get_property, JS_StrictPropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, NULL
|
||||
};
|
||||
|
||||
|
||||
@ -73,13 +79,13 @@ enum window_prop {
|
||||
* (SpiderMonkey was still asking us about the "location" string after
|
||||
* assigning to it once), instead we do just a little string
|
||||
* comparing. */
|
||||
const JSPropertySpec window_props[] = {
|
||||
{ "closed", JSP_WIN_CLOSED, JSPROP_ENUMERATE | JSPROP_READONLY },
|
||||
{ "parent", JSP_WIN_PARENT, JSPROP_ENUMERATE | JSPROP_READONLY },
|
||||
{ "self", JSP_WIN_SELF, JSPROP_ENUMERATE | JSPROP_READONLY },
|
||||
{ "status", JSP_WIN_STATUS, JSPROP_ENUMERATE },
|
||||
{ "top", JSP_WIN_TOP, JSPROP_ENUMERATE | JSPROP_READONLY },
|
||||
{ "window", JSP_WIN_SELF, JSPROP_ENUMERATE | JSPROP_READONLY },
|
||||
JSPropertySpec window_props[] = {
|
||||
{ "closed", 0, JSPROP_ENUMERATE | JSPROP_READONLY|JSPROP_SHARED, JSOP_WRAPPER(window_get_property_closed), JSOP_NULLWRAPPER },
|
||||
{ "parent", 0, JSPROP_ENUMERATE | JSPROP_READONLY|JSPROP_SHARED, JSOP_WRAPPER(window_get_property_parent), JSOP_NULLWRAPPER },
|
||||
{ "self", 0, JSPROP_ENUMERATE | JSPROP_READONLY|JSPROP_SHARED, JSOP_WRAPPER(window_get_property_self), JSOP_NULLWRAPPER },
|
||||
{ "status", 0, JSPROP_ENUMERATE|JSPROP_SHARED, JSOP_WRAPPER(window_get_property_status), JSOP_WRAPPER(window_set_property_status) },
|
||||
{ "top", 0, JSPROP_ENUMERATE | JSPROP_READONLY|JSPROP_SHARED, JSOP_WRAPPER(window_get_property_top), JSOP_NULLWRAPPER },
|
||||
{ "window", 0, JSPROP_ENUMERATE | JSPROP_READONLY|JSPROP_SHARED, JSOP_WRAPPER(window_get_property_window), JSOP_NULLWRAPPER },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
@ -122,17 +128,20 @@ find_child_frame(struct document_view *doc_view, struct frame_desc *tframe)
|
||||
|
||||
/* @window_class.getProperty */
|
||||
static JSBool
|
||||
window_get_property(JSContext *ctx, JSObject *obj, jsid id, jsval *vp)
|
||||
window_get_property(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSMutableHandleValue hvp)
|
||||
{
|
||||
ELINKS_CAST_PROP_PARAMS
|
||||
jsid id = *(hid._);
|
||||
|
||||
struct view_state *vs;
|
||||
|
||||
/* This can be called if @obj if not itself an instance of the
|
||||
* appropriate class but has one in its prototype chain. Fail
|
||||
* such calls. */
|
||||
if (!JS_InstanceOf(ctx, obj, (JSClass *) &window_class, NULL))
|
||||
if (!JS_InstanceOf(ctx, obj, &window_class, NULL))
|
||||
return JS_FALSE;
|
||||
|
||||
vs = JS_GetInstancePrivate(ctx, obj, (JSClass *) &window_class, NULL);
|
||||
vs = JS_GetInstancePrivate(ctx, obj, &window_class, NULL);
|
||||
|
||||
/* No need for special window.location measurements - when
|
||||
* location is then evaluated in string context, toString()
|
||||
@ -140,9 +149,7 @@ window_get_property(JSContext *ctx, JSObject *obj, jsid id, jsval *vp)
|
||||
* everything's fine. */
|
||||
if (JSID_IS_STRING(id)) {
|
||||
struct document_view *doc_view = vs->doc_view;
|
||||
JSObject *obj;
|
||||
|
||||
obj = try_resolve_frame(doc_view, jsid_to_string(ctx, &id));
|
||||
JSObject *obj = try_resolve_frame(doc_view, jsid_to_string(ctx, &id));
|
||||
/* TODO: Try other lookups (mainly element lookup) until
|
||||
* something yields data. */
|
||||
if (obj) {
|
||||
@ -252,55 +259,9 @@ found_parent:
|
||||
|
||||
void location_goto(struct document_view *doc_view, unsigned char *url);
|
||||
|
||||
/* @window_class.setProperty */
|
||||
static JSBool
|
||||
window_set_property(JSContext *ctx, JSObject *obj, jsid id, JSBool strict, jsval *vp)
|
||||
{
|
||||
struct view_state *vs;
|
||||
|
||||
/* This can be called if @obj if not itself an instance of the
|
||||
* appropriate class but has one in its prototype chain. Fail
|
||||
* such calls. */
|
||||
if (!JS_InstanceOf(ctx, obj, (JSClass *) &window_class, NULL))
|
||||
return JS_FALSE;
|
||||
|
||||
vs = JS_GetInstancePrivate(ctx, obj, (JSClass *) &window_class, NULL);
|
||||
|
||||
if (JSID_IS_STRING(id)) {
|
||||
if (!strcmp(jsid_to_string(ctx, &id), "location")) {
|
||||
struct document_view *doc_view = vs->doc_view;
|
||||
|
||||
location_goto(doc_view, jsval_to_string(ctx, vp));
|
||||
/* Do NOT touch our .location property, evil
|
||||
* SpiderMonkey!! */
|
||||
return JS_FALSE;
|
||||
}
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
if (!JSID_IS_INT(id))
|
||||
return JS_TRUE;
|
||||
|
||||
switch (JSID_TO_INT(id)) {
|
||||
case JSP_WIN_STATUS:
|
||||
mem_free_set(&vs->doc_view->session->status.window_status, stracpy(jsval_to_string(ctx, vp)));
|
||||
print_screen_status(vs->doc_view->session);
|
||||
return JS_TRUE;
|
||||
default:
|
||||
/* Unrecognized integer property ID; someone is using
|
||||
* the object as an array. SMJS builtin classes (e.g.
|
||||
* js_RegExpClass) just return JS_TRUE in this case.
|
||||
* Do the same here. */
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
|
||||
static JSBool window_alert(JSContext *ctx, uintN argc, jsval *rval);
|
||||
static JSBool window_open(JSContext *ctx, uintN argc, jsval *rval);
|
||||
static JSBool window_setTimeout(JSContext *ctx, uintN argc, jsval *rval);
|
||||
static JSBool window_alert(JSContext *ctx, unsigned int argc, jsval *rval);
|
||||
static JSBool window_open(JSContext *ctx, unsigned int argc, jsval *rval);
|
||||
static JSBool window_setTimeout(JSContext *ctx, unsigned int argc, jsval *rval);
|
||||
|
||||
const spidermonkeyFunctionSpec window_funcs[] = {
|
||||
{ "alert", window_alert, 1 },
|
||||
@ -311,7 +272,7 @@ const spidermonkeyFunctionSpec window_funcs[] = {
|
||||
|
||||
/* @window_funcs{"alert"} */
|
||||
static JSBool
|
||||
window_alert(JSContext *ctx, uintN argc, jsval *rval)
|
||||
window_alert(JSContext *ctx, unsigned int argc, jsval *rval)
|
||||
{
|
||||
jsval val;
|
||||
JSObject *obj = JS_THIS_OBJECT(ctx, rval);
|
||||
@ -319,9 +280,9 @@ window_alert(JSContext *ctx, uintN argc, jsval *rval)
|
||||
struct view_state *vs;
|
||||
unsigned char *string;
|
||||
|
||||
if (!JS_InstanceOf(ctx, obj, (JSClass *) &window_class, argv)) return JS_FALSE;
|
||||
if (!JS_InstanceOf(ctx, obj, &window_class, argv)) return JS_FALSE;
|
||||
|
||||
vs = JS_GetInstancePrivate(ctx, obj, (JSClass *) &window_class, argv);
|
||||
vs = JS_GetInstancePrivate(ctx, obj, &window_class, argv);
|
||||
|
||||
if (argc != 1)
|
||||
return JS_TRUE;
|
||||
@ -340,7 +301,7 @@ window_alert(JSContext *ctx, uintN argc, jsval *rval)
|
||||
|
||||
/* @window_funcs{"open"} */
|
||||
static JSBool
|
||||
window_open(JSContext *ctx, uintN argc, jsval *rval)
|
||||
window_open(JSContext *ctx, unsigned int argc, jsval *rval)
|
||||
{
|
||||
jsval val;
|
||||
JSObject *obj = JS_THIS_OBJECT(ctx, rval);
|
||||
@ -354,9 +315,9 @@ window_open(JSContext *ctx, uintN argc, jsval *rval)
|
||||
static time_t ratelimit_start;
|
||||
static int ratelimit_count;
|
||||
|
||||
if (!JS_InstanceOf(ctx, obj, (JSClass *) &window_class, argv)) return JS_FALSE;
|
||||
if (!JS_InstanceOf(ctx, obj, &window_class, argv)) return JS_FALSE;
|
||||
|
||||
vs = JS_GetInstancePrivate(ctx, obj, (JSClass *) &window_class, argv);
|
||||
vs = JS_GetInstancePrivate(ctx, obj, &window_class, argv);
|
||||
doc_view = vs->doc_view;
|
||||
ses = doc_view->session;
|
||||
|
||||
@ -451,7 +412,7 @@ end:
|
||||
|
||||
/* @window_funcs{"setTimeout"} */
|
||||
static JSBool
|
||||
window_setTimeout(JSContext *ctx, uintN argc, jsval *rval)
|
||||
window_setTimeout(JSContext *ctx, unsigned int argc, jsval *rval)
|
||||
{
|
||||
jsval *argv = JS_ARGV(ctx, rval);
|
||||
struct ecmascript_interpreter *interpreter = JS_GetContextPrivate(ctx);
|
||||
@ -476,3 +437,150 @@ window_setTimeout(JSContext *ctx, uintN argc, jsval *rval)
|
||||
ecmascript_set_timeout(interpreter, code, timeout);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
window_get_property_closed(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSMutableHandleValue hvp)
|
||||
{
|
||||
ELINKS_CAST_PROP_PARAMS
|
||||
|
||||
/* This can be called if @obj if not itself an instance of the
|
||||
* appropriate class but has one in its prototype chain. Fail
|
||||
* such calls. */
|
||||
if (!JS_InstanceOf(ctx, obj, &window_class, NULL))
|
||||
return JS_FALSE;
|
||||
|
||||
boolean_to_jsval(ctx, vp, 0);
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
window_get_property_parent(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSMutableHandleValue hvp)
|
||||
{
|
||||
ELINKS_CAST_PROP_PARAMS
|
||||
|
||||
/* This can be called if @obj if not itself an instance of the
|
||||
* appropriate class but has one in its prototype chain. Fail
|
||||
* such calls. */
|
||||
if (!JS_InstanceOf(ctx, obj, &window_class, NULL))
|
||||
return JS_FALSE;
|
||||
|
||||
/* XXX: It would be nice if the following worked, yes.
|
||||
* The problem is that we get called at the point where
|
||||
* document.frame properties are going to be mostly NULL.
|
||||
* But the problem is deeper because at that time we are
|
||||
* yet building scrn_frames so our parent might not be there
|
||||
* yet (XXX: is this true?). The true solution will be to just
|
||||
* have struct document_view *(document_view.parent). --pasky */
|
||||
/* FIXME: So now we alias window.parent to window.top, which is
|
||||
* INCORRECT but works for the most common cases of just two
|
||||
* frames. Better something than nothing. */
|
||||
|
||||
undef_to_jsval(ctx, vp);
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
window_get_property_self(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSMutableHandleValue hvp)
|
||||
{
|
||||
ELINKS_CAST_PROP_PARAMS
|
||||
|
||||
/* This can be called if @obj if not itself an instance of the
|
||||
* appropriate class but has one in its prototype chain. Fail
|
||||
* such calls. */
|
||||
if (!JS_InstanceOf(ctx, obj, &window_class, NULL))
|
||||
return JS_FALSE;
|
||||
|
||||
object_to_jsval(ctx, vp, obj);
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
window_get_property_status(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSMutableHandleValue hvp)
|
||||
{
|
||||
ELINKS_CAST_PROP_PARAMS
|
||||
|
||||
/* This can be called if @obj if not itself an instance of the
|
||||
* appropriate class but has one in its prototype chain. Fail
|
||||
* such calls. */
|
||||
if (!JS_InstanceOf(ctx, obj, &window_class, NULL))
|
||||
return JS_FALSE;
|
||||
|
||||
undef_to_jsval(ctx, vp);
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
window_set_property_status(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSBool strict, JSMutableHandleValue hvp)
|
||||
{
|
||||
ELINKS_CAST_PROP_PARAMS
|
||||
|
||||
struct view_state *vs;
|
||||
|
||||
/* This can be called if @obj if not itself an instance of the
|
||||
* appropriate class but has one in its prototype chain. Fail
|
||||
* such calls. */
|
||||
if (!JS_InstanceOf(ctx, obj, &window_class, NULL))
|
||||
return JS_FALSE;
|
||||
|
||||
vs = JS_GetInstancePrivate(ctx, obj, &window_class, NULL);
|
||||
|
||||
mem_free_set(&vs->doc_view->session->status.window_status, stracpy(jsval_to_string(ctx, vp)));
|
||||
print_screen_status(vs->doc_view->session);
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
window_get_property_top(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSMutableHandleValue hvp)
|
||||
{
|
||||
ELINKS_CAST_PROP_PARAMS
|
||||
|
||||
struct view_state *vs;
|
||||
struct document_view *doc_view;
|
||||
struct document_view *top_view;
|
||||
JSObject *newjsframe;
|
||||
|
||||
/* This can be called if @obj if not itself an instance of the
|
||||
* appropriate class but has one in its prototype chain. Fail
|
||||
* such calls. */
|
||||
if (!JS_InstanceOf(ctx, obj, &window_class, NULL))
|
||||
return JS_FALSE;
|
||||
|
||||
vs = JS_GetInstancePrivate(ctx, obj, &window_class, NULL);
|
||||
doc_view = vs->doc_view;
|
||||
top_view = doc_view->session->doc_view;
|
||||
|
||||
undef_to_jsval(ctx, vp);
|
||||
|
||||
assert(top_view && top_view->vs);
|
||||
if (top_view->vs->ecmascript_fragile)
|
||||
ecmascript_reset_state(top_view->vs);
|
||||
if (!top_view->vs->ecmascript)
|
||||
return JS_TRUE;
|
||||
newjsframe = JS_GetGlobalObject(top_view->vs->ecmascript->backend_data);
|
||||
|
||||
/* Keep this unrolled this way. Will have to check document.domain
|
||||
* JS property. */
|
||||
/* Note that this check is perhaps overparanoid. If top windows
|
||||
* is alien but some other child window is not, we should still
|
||||
* let the script walk thru. That'd mean moving the check to
|
||||
* other individual properties in this switch. */
|
||||
if (compare_uri(vs->uri, top_view->vs->uri, URI_HOST))
|
||||
object_to_jsval(ctx, vp, newjsframe);
|
||||
/* else */
|
||||
/****X*X*X*** SECURITY VIOLATION! RED ALERT, SHIELDS UP! ***X*X*X****\
|
||||
|* (Pasky was apparently looking at the Links2 JS code . ___ ^.^ *|
|
||||
\* for too long.) `.(,_,)\o/ */
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
window_get_property_window(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSMutableHandleValue hvp)
|
||||
{
|
||||
return window_get_property_self(ctx, hobj, hid, hvp);
|
||||
}
|
||||
|
@ -4,8 +4,8 @@
|
||||
|
||||
#include "ecmascript/spidermonkey/util.h"
|
||||
|
||||
extern const JSClass window_class;
|
||||
extern const JSPropertySpec window_props[];
|
||||
extern JSClass window_class;
|
||||
extern JSPropertySpec window_props[];
|
||||
extern const spidermonkeyFunctionSpec window_funcs[];
|
||||
|
||||
#endif
|
||||
|
@ -27,22 +27,26 @@ static const JSClass action_fn_class; /* defined below */
|
||||
|
||||
/* @action_fn_class.finalize */
|
||||
static void
|
||||
smjs_action_fn_finalize(JSContext *ctx, JSObject *obj)
|
||||
smjs_action_fn_finalize(JSFreeOp *op, JSObject *obj)
|
||||
{
|
||||
struct smjs_action_fn_callback_hop *hop;
|
||||
|
||||
#if 0
|
||||
assert(JS_InstanceOf(ctx, obj, (JSClass *) &action_fn_class, NULL));
|
||||
if_assert_failed return;
|
||||
|
||||
hop = JS_GetInstancePrivate(ctx, obj,
|
||||
(JSClass *) &action_fn_class, NULL);
|
||||
#endif
|
||||
|
||||
hop = JS_GetPrivate(obj);
|
||||
|
||||
mem_free_if(hop);
|
||||
}
|
||||
|
||||
/* @action_fn_class.call */
|
||||
static JSBool
|
||||
smjs_action_fn_callback(JSContext *ctx, uintN argc, jsval *rval)
|
||||
smjs_action_fn_callback(JSContext *ctx, unsigned int argc, jsval *rval)
|
||||
{
|
||||
jsval value;
|
||||
jsval *argv = JS_ARGV(ctx, rval);
|
||||
@ -95,7 +99,7 @@ smjs_action_fn_callback(JSContext *ctx, uintN argc, jsval *rval)
|
||||
}
|
||||
|
||||
if (argc >= 1) {
|
||||
int32 val;
|
||||
int32_t val;
|
||||
|
||||
if (JS_TRUE == JS_ValueToInt32(smjs_ctx, argv[0], &val)) {
|
||||
set_kbd_repeat_count(hop->ses, val);
|
||||
@ -117,7 +121,7 @@ static const JSClass action_fn_class = {
|
||||
JS_PropertyStub, JS_StrictPropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub,
|
||||
smjs_action_fn_finalize,
|
||||
NULL, NULL,
|
||||
NULL,
|
||||
smjs_action_fn_callback,
|
||||
};
|
||||
|
||||
@ -145,9 +149,9 @@ smjs_get_action_fn_object(unsigned char *action_str)
|
||||
|
||||
hop->action_id = get_action_from_string(KEYMAP_MAIN, action_str);
|
||||
|
||||
if (-1 != hop->action_id
|
||||
&& JS_TRUE == JS_SetPrivate(smjs_ctx, obj, hop)) { /* to @action_fn_class */
|
||||
return obj;
|
||||
if (-1 != hop->action_id) {
|
||||
JS_SetPrivate(obj, hop); /* to @action_fn_class */
|
||||
return obj;
|
||||
}
|
||||
|
||||
mem_free(hop);
|
||||
@ -159,8 +163,12 @@ smjs_get_action_fn_object(unsigned char *action_str)
|
||||
|
||||
/* @action_class.getProperty */
|
||||
static JSBool
|
||||
action_get_property(JSContext *ctx, JSObject *obj, jsid id, jsval *vp)
|
||||
action_get_property(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSMutableHandleValue hvp)
|
||||
{
|
||||
ELINKS_CAST_PROP_PARAMS
|
||||
jsid id = *(hid._);
|
||||
(void)obj;
|
||||
|
||||
jsval val;
|
||||
JSObject *action_fn;
|
||||
unsigned char *action_str;
|
||||
@ -184,7 +192,7 @@ static const JSClass action_class = {
|
||||
0,
|
||||
JS_PropertyStub, JS_PropertyStub,
|
||||
action_get_property, JS_StrictPropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, NULL,
|
||||
};
|
||||
|
||||
static JSObject *
|
||||
|
@ -33,26 +33,24 @@ smjs_get_bookmark_generic_object(struct bookmark *bookmark, JSClass *clasp)
|
||||
|
||||
if (!bookmark) return jsobj;
|
||||
|
||||
if (JS_TRUE == JS_SetPrivate(smjs_ctx, jsobj, bookmark)) { /* to @bookmark_class or @bookmark_folder_class */
|
||||
object_lock(bookmark);
|
||||
JS_SetPrivate(jsobj, bookmark); /* to @bookmark_class or @bookmark_folder_class */
|
||||
object_lock(bookmark);
|
||||
|
||||
return jsobj;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return jsobj;
|
||||
};
|
||||
|
||||
/* @bookmark_class.finalize, @bookmark_folder_class.finalize */
|
||||
static void
|
||||
bookmark_finalize(JSContext *ctx, JSObject *obj)
|
||||
bookmark_finalize(JSFreeOp *op, JSObject *obj)
|
||||
{
|
||||
struct bookmark *bookmark;
|
||||
|
||||
#if 0
|
||||
assert(JS_InstanceOf(ctx, obj, (JSClass *) &bookmark_class, NULL)
|
||||
|| JS_InstanceOf(ctx, obj, (JSClass *) &bookmark_folder_class, NULL));
|
||||
if_assert_failed return;
|
||||
#endif
|
||||
|
||||
bookmark = JS_GetPrivate(ctx, obj); /* from @bookmark_class or @bookmark_folder_class */
|
||||
bookmark = JS_GetPrivate(obj); /* from @bookmark_class or @bookmark_folder_class */
|
||||
|
||||
if (bookmark) object_unlock(bookmark);
|
||||
}
|
||||
@ -70,10 +68,16 @@ enum bookmark_prop {
|
||||
BOOKMARK_CHILDREN = -3,
|
||||
};
|
||||
|
||||
static JSBool bookmark_get_property_title(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSMutableHandleValue hvp);
|
||||
static JSBool bookmark_set_property_title(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSBool strict, JSMutableHandleValue hvp);
|
||||
static JSBool bookmark_get_property_url(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSMutableHandleValue hvp);
|
||||
static JSBool bookmark_set_property_url(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSBool strict, JSMutableHandleValue hvp);
|
||||
static JSBool bookmark_get_property_children(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSMutableHandleValue hvp);
|
||||
|
||||
static const JSPropertySpec bookmark_props[] = {
|
||||
{ "title", BOOKMARK_TITLE, JSPROP_ENUMERATE },
|
||||
{ "url", BOOKMARK_URL, JSPROP_ENUMERATE },
|
||||
{ "children", BOOKMARK_CHILDREN, JSPROP_ENUMERATE | JSPROP_READONLY },
|
||||
{ "title", 0, JSPROP_ENUMERATE, JSOP_WRAPPER(bookmark_get_property_title), JSOP_WRAPPER(bookmark_set_property_title) },
|
||||
{ "url", 0, JSPROP_ENUMERATE, JSOP_WRAPPER(bookmark_get_property_url), JSOP_WRAPPER(bookmark_set_property_url) },
|
||||
{ "children", 0, JSPROP_ENUMERATE | JSPROP_READONLY, JSOP_WRAPPER(bookmark_get_property_children), JSOP_NULLWRAPPER },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
@ -145,10 +149,11 @@ jsval_to_bookmark_string(JSContext *ctx, jsval val, unsigned char **result)
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
/* @bookmark_class.getProperty */
|
||||
static JSBool
|
||||
bookmark_get_property(JSContext *ctx, JSObject *obj, jsid id, jsval *vp)
|
||||
bookmark_get_property_title(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSMutableHandleValue hvp)
|
||||
{
|
||||
ELINKS_CAST_PROP_PARAMS
|
||||
|
||||
struct bookmark *bookmark;
|
||||
|
||||
/* This can be called if @obj if not itself an instance of the
|
||||
@ -162,35 +167,14 @@ bookmark_get_property(JSContext *ctx, JSObject *obj, jsid id, jsval *vp)
|
||||
|
||||
if (!bookmark) return JS_FALSE;
|
||||
|
||||
undef_to_jsval(ctx, vp);
|
||||
|
||||
if (!JSID_IS_INT(id))
|
||||
return JS_FALSE;
|
||||
|
||||
switch (JSID_TO_INT(id)) {
|
||||
case BOOKMARK_TITLE:
|
||||
return bookmark_string_to_jsval(ctx, bookmark->title, vp);
|
||||
case BOOKMARK_URL:
|
||||
return bookmark_string_to_jsval(ctx, bookmark->url, vp);
|
||||
case BOOKMARK_CHILDREN:
|
||||
*vp = OBJECT_TO_JSVAL(smjs_get_bookmark_folder_object(bookmark));
|
||||
|
||||
return JS_TRUE;
|
||||
default:
|
||||
/* Unrecognized integer property ID; someone is using
|
||||
* the object as an array. SMJS builtin classes (e.g.
|
||||
* js_RegExpClass) just return JS_TRUE in this case
|
||||
* and leave *@vp unchanged. Do the same here.
|
||||
* (Actually not quite the same, as we already used
|
||||
* @undef_to_jsval.) */
|
||||
return JS_TRUE;
|
||||
}
|
||||
return bookmark_string_to_jsval(ctx, bookmark->title, vp);
|
||||
}
|
||||
|
||||
/* @bookmark_class.setProperty */
|
||||
static JSBool
|
||||
bookmark_set_property(JSContext *ctx, JSObject *obj, jsid id, JSBool strict, jsval *vp)
|
||||
bookmark_set_property_title(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSBool strict, JSMutableHandleValue hvp)
|
||||
{
|
||||
ELINKS_CAST_PROP_PARAMS
|
||||
|
||||
struct bookmark *bookmark;
|
||||
unsigned char *title = NULL;
|
||||
unsigned char *url = NULL;
|
||||
@ -207,37 +191,94 @@ bookmark_set_property(JSContext *ctx, JSObject *obj, jsid id, JSBool strict, jsv
|
||||
|
||||
if (!bookmark) return JS_FALSE;
|
||||
|
||||
if (!JSID_IS_INT(id))
|
||||
if (!jsval_to_bookmark_string(ctx, *vp, &title))
|
||||
return JS_FALSE;
|
||||
|
||||
switch (JSID_TO_INT(id)) {
|
||||
case BOOKMARK_TITLE:
|
||||
if (!jsval_to_bookmark_string(ctx, *vp, &title))
|
||||
return JS_FALSE;
|
||||
break;
|
||||
case BOOKMARK_URL:
|
||||
if (!jsval_to_bookmark_string(ctx, *vp, &url))
|
||||
return JS_FALSE;
|
||||
break;
|
||||
default:
|
||||
/* Unrecognized integer property ID; someone is using
|
||||
* the object as an array. SMJS builtin classes (e.g.
|
||||
* js_RegExpClass) just return JS_TRUE in this case.
|
||||
* Do the same here. */
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
ok = update_bookmark(bookmark, get_cp_index("UTF-8"), title, url);
|
||||
mem_free_if(title);
|
||||
mem_free_if(url);
|
||||
return ok ? JS_TRUE : JS_FALSE;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
bookmark_get_property_url(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSMutableHandleValue hvp)
|
||||
{
|
||||
ELINKS_CAST_PROP_PARAMS
|
||||
|
||||
struct bookmark *bookmark;
|
||||
|
||||
/* This can be called if @obj if not itself an instance of the
|
||||
* appropriate class but has one in its prototype chain. Fail
|
||||
* such calls. */
|
||||
if (!JS_InstanceOf(ctx, obj, (JSClass *) &bookmark_class, NULL))
|
||||
return JS_FALSE;
|
||||
|
||||
bookmark = JS_GetInstancePrivate(ctx, obj,
|
||||
(JSClass *) &bookmark_class, NULL);
|
||||
|
||||
if (!bookmark) return JS_FALSE;
|
||||
|
||||
return bookmark_string_to_jsval(ctx, bookmark->url, vp);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
bookmark_set_property_url(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSBool strict, JSMutableHandleValue hvp)
|
||||
{
|
||||
ELINKS_CAST_PROP_PARAMS
|
||||
|
||||
struct bookmark *bookmark;
|
||||
unsigned char *title = NULL;
|
||||
unsigned char *url = NULL;
|
||||
int ok;
|
||||
|
||||
/* This can be called if @obj if not itself an instance of the
|
||||
* appropriate class but has one in its prototype chain. Fail
|
||||
* such calls. */
|
||||
if (!JS_InstanceOf(ctx, obj, (JSClass *) &bookmark_class, NULL))
|
||||
return JS_FALSE;
|
||||
|
||||
bookmark = JS_GetInstancePrivate(ctx, obj,
|
||||
(JSClass *) &bookmark_class, NULL);
|
||||
|
||||
if (!bookmark) return JS_FALSE;
|
||||
|
||||
if (!jsval_to_bookmark_string(ctx, *vp, &url))
|
||||
return JS_FALSE;
|
||||
|
||||
ok = update_bookmark(bookmark, get_cp_index("UTF-8"), title, url);
|
||||
mem_free_if(title);
|
||||
mem_free_if(url);
|
||||
return ok ? JS_TRUE : JS_FALSE;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
bookmark_get_property_children(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSMutableHandleValue hvp)
|
||||
{
|
||||
ELINKS_CAST_PROP_PARAMS
|
||||
|
||||
struct bookmark *bookmark;
|
||||
|
||||
/* This can be called if @obj if not itself an instance of the
|
||||
* appropriate class but has one in its prototype chain. Fail
|
||||
* such calls. */
|
||||
if (!JS_InstanceOf(ctx, obj, (JSClass *) &bookmark_class, NULL))
|
||||
return JS_FALSE;
|
||||
|
||||
bookmark = JS_GetInstancePrivate(ctx, obj,
|
||||
(JSClass *) &bookmark_class, NULL);
|
||||
|
||||
if (!bookmark) return JS_FALSE;
|
||||
|
||||
*vp = OBJECT_TO_JSVAL(smjs_get_bookmark_folder_object(bookmark));
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static const JSClass bookmark_class = {
|
||||
"bookmark",
|
||||
JSCLASS_HAS_PRIVATE, /* struct bookmark * */
|
||||
JS_PropertyStub, JS_PropertyStub,
|
||||
bookmark_get_property, bookmark_set_property,
|
||||
JS_PropertyStub, JS_StrictPropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, bookmark_finalize,
|
||||
};
|
||||
|
||||
@ -262,8 +303,11 @@ smjs_get_bookmark_object(struct bookmark *bookmark)
|
||||
|
||||
/* @bookmark_folder_class.getProperty */
|
||||
static JSBool
|
||||
bookmark_folder_get_property(JSContext *ctx, JSObject *obj, jsid id, jsval *vp)
|
||||
bookmark_folder_get_property(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSMutableHandleValue hvp)
|
||||
{
|
||||
ELINKS_CAST_PROP_PARAMS
|
||||
jsid id = *(hid._);
|
||||
|
||||
struct bookmark *bookmark;
|
||||
struct bookmark *folder;
|
||||
jsval title_jsval = JSVAL_VOID;
|
||||
|
@ -29,20 +29,31 @@ enum cache_entry_prop {
|
||||
CACHE_ENTRY_URI = -5,
|
||||
};
|
||||
|
||||
static JSBool cache_entry_get_property_content(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSMutableHandleValue hvp);
|
||||
static JSBool cache_entry_set_property_content(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSBool strict, JSMutableHandleValue hvp);
|
||||
static JSBool cache_entry_get_property_type(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSMutableHandleValue hvp);
|
||||
static JSBool cache_entry_set_property_type(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSBool strict, JSMutableHandleValue hvp);
|
||||
static JSBool cache_entry_get_property_length(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSMutableHandleValue hvp);
|
||||
static JSBool cache_entry_get_property_head(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSMutableHandleValue hvp);
|
||||
static JSBool cache_entry_set_property_head(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSBool strict, JSMutableHandleValue hvp);
|
||||
static JSBool cache_entry_get_property_uri(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSMutableHandleValue hvp);
|
||||
|
||||
static const JSPropertySpec cache_entry_props[] = {
|
||||
{ "content", CACHE_ENTRY_CONTENT, JSPROP_ENUMERATE },
|
||||
{ "type", CACHE_ENTRY_TYPE, JSPROP_ENUMERATE },
|
||||
{ "length", CACHE_ENTRY_LENGTH, JSPROP_ENUMERATE | JSPROP_READONLY },
|
||||
{ "head", CACHE_ENTRY_HEAD, JSPROP_ENUMERATE },
|
||||
{ "uri", CACHE_ENTRY_URI, JSPROP_ENUMERATE | JSPROP_READONLY },
|
||||
{ "content", 0, JSPROP_ENUMERATE, JSOP_WRAPPER(cache_entry_get_property_content), JSOP_WRAPPER(cache_entry_set_property_content) },
|
||||
{ "type", 0, JSPROP_ENUMERATE, JSOP_WRAPPER(cache_entry_get_property_type), JSOP_WRAPPER(cache_entry_set_property_type)},
|
||||
{ "length", 0, JSPROP_ENUMERATE | JSPROP_READONLY, JSOP_WRAPPER(cache_entry_get_property_length), JSOP_NULLWRAPPER },
|
||||
{ "head", 0, JSPROP_ENUMERATE, JSOP_WRAPPER(cache_entry_get_property_head), JSOP_WRAPPER(cache_entry_set_property_head) },
|
||||
{ "uri", 0, JSPROP_ENUMERATE | JSPROP_READONLY, JSOP_WRAPPER(cache_entry_get_property_uri), JSOP_NULLWRAPPER },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
/* @cache_entry_class.getProperty */
|
||||
static JSBool
|
||||
cache_entry_get_property(JSContext *ctx, JSObject *obj, jsid id, jsval *vp)
|
||||
cache_entry_get_property_content(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSMutableHandleValue hvp)
|
||||
{
|
||||
ELINKS_CAST_PROP_PARAMS
|
||||
|
||||
struct cache_entry *cached;
|
||||
struct fragment *fragment;
|
||||
JSBool ret;
|
||||
|
||||
/* This can be called if @obj if not itself an instance of the
|
||||
@ -65,69 +76,28 @@ cache_entry_get_property(JSContext *ctx, JSObject *obj, jsid id, jsval *vp)
|
||||
object_lock(cached);
|
||||
|
||||
undef_to_jsval(ctx, vp);
|
||||
fragment = get_cache_fragment(cached);
|
||||
|
||||
if (!JSID_IS_INT(id))
|
||||
if (!fragment) {
|
||||
ret = JS_FALSE;
|
||||
else switch (JSID_TO_INT(id)) {
|
||||
case CACHE_ENTRY_CONTENT: {
|
||||
struct fragment *fragment = get_cache_fragment(cached);
|
||||
|
||||
if (!fragment) {
|
||||
ret = JS_FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
*vp = STRING_TO_JSVAL(JS_NewStringCopyN(smjs_ctx,
|
||||
fragment->data,
|
||||
fragment->length));
|
||||
|
||||
} else {
|
||||
*vp = STRING_TO_JSVAL(JS_NewStringCopyN(smjs_ctx, fragment->data, fragment->length));
|
||||
ret = JS_TRUE;
|
||||
break;
|
||||
}
|
||||
case CACHE_ENTRY_TYPE:
|
||||
*vp = STRING_TO_JSVAL(JS_NewStringCopyZ(smjs_ctx,
|
||||
cached->content_type));
|
||||
|
||||
ret = JS_TRUE;
|
||||
break;
|
||||
case CACHE_ENTRY_HEAD:
|
||||
*vp = STRING_TO_JSVAL(JS_NewStringCopyZ(smjs_ctx,
|
||||
cached->head));
|
||||
|
||||
ret = JS_TRUE;
|
||||
break;
|
||||
case CACHE_ENTRY_LENGTH:
|
||||
*vp = INT_TO_JSVAL(cached->length);
|
||||
|
||||
ret = JS_TRUE;
|
||||
break;
|
||||
case CACHE_ENTRY_URI:
|
||||
*vp = STRING_TO_JSVAL(JS_NewStringCopyZ(smjs_ctx,
|
||||
struri(cached->uri)));
|
||||
|
||||
ret = JS_TRUE;
|
||||
break;
|
||||
default:
|
||||
/* Unrecognized integer property ID; someone is using
|
||||
* the object as an array. SMJS builtin classes (e.g.
|
||||
* js_RegExpClass) just return JS_TRUE in this case
|
||||
* and leave *@vp unchanged. Do the same here.
|
||||
* (Actually not quite the same, as we already used
|
||||
* @undef_to_jsval.) */
|
||||
ret = JS_TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
object_unlock(cached);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* @cache_entry_class.setProperty */
|
||||
static JSBool
|
||||
cache_entry_set_property(JSContext *ctx, JSObject *obj, jsid id, JSBool strict, jsval *vp)
|
||||
cache_entry_set_property_content(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSBool strict, JSMutableHandleValue hvp)
|
||||
{
|
||||
ELINKS_CAST_PROP_PARAMS
|
||||
|
||||
struct cache_entry *cached;
|
||||
JSBool ret;
|
||||
JSString *jsstr;
|
||||
unsigned char *str;
|
||||
size_t len;
|
||||
|
||||
/* This can be called if @obj if not itself an instance of the
|
||||
* appropriate class but has one in its prototype chain. Fail
|
||||
@ -148,68 +118,105 @@ cache_entry_set_property(JSContext *ctx, JSObject *obj, jsid id, JSBool strict,
|
||||
* eventually unlock the object. */
|
||||
object_lock(cached);
|
||||
|
||||
if (!JSID_IS_INT(id))
|
||||
ret = JS_FALSE;
|
||||
else switch (JSID_TO_INT(id)) {
|
||||
case CACHE_ENTRY_CONTENT: {
|
||||
JSString *jsstr = JS_ValueToString(smjs_ctx, *vp);
|
||||
unsigned char *str = JS_EncodeString(smjs_ctx, jsstr);
|
||||
size_t len = JS_GetStringLength(jsstr);
|
||||
|
||||
add_fragment(cached, 0, str, len);
|
||||
normalize_cache_entry(cached, len);
|
||||
|
||||
ret = JS_TRUE;
|
||||
break;
|
||||
}
|
||||
case CACHE_ENTRY_TYPE: {
|
||||
JSString *jsstr = JS_ValueToString(smjs_ctx, *vp);
|
||||
unsigned char *str = JS_EncodeString(smjs_ctx, jsstr);
|
||||
|
||||
mem_free_set(&cached->content_type, stracpy(str));
|
||||
|
||||
ret = JS_TRUE;
|
||||
break;
|
||||
}
|
||||
case CACHE_ENTRY_HEAD: {
|
||||
JSString *jsstr = JS_ValueToString(smjs_ctx, *vp);
|
||||
unsigned char *str = JS_EncodeString(smjs_ctx, jsstr);
|
||||
|
||||
mem_free_set(&cached->head, stracpy(str));
|
||||
|
||||
ret = JS_TRUE;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
/* Unrecognized integer property ID; someone is using
|
||||
* the object as an array. SMJS builtin classes (e.g.
|
||||
* js_RegExpClass) just return JS_TRUE in this case.
|
||||
* Do the same here. */
|
||||
ret = JS_TRUE;
|
||||
break;
|
||||
}
|
||||
jsstr = JS_ValueToString(smjs_ctx, *vp);
|
||||
str = JS_EncodeString(smjs_ctx, jsstr);
|
||||
len = JS_GetStringLength(jsstr);
|
||||
add_fragment(cached, 0, str, len);
|
||||
normalize_cache_entry(cached, len);
|
||||
|
||||
object_unlock(cached);
|
||||
return ret;
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
cache_entry_get_property_type(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSMutableHandleValue hvp)
|
||||
{
|
||||
ELINKS_CAST_PROP_PARAMS
|
||||
|
||||
struct cache_entry *cached;
|
||||
|
||||
/* This can be called if @obj if not itself an instance of the
|
||||
* appropriate class but has one in its prototype chain. Fail
|
||||
* such calls. */
|
||||
if (!JS_InstanceOf(ctx, obj, (JSClass *) &cache_entry_class, NULL))
|
||||
return JS_FALSE;
|
||||
|
||||
cached = JS_GetInstancePrivate(ctx, obj,
|
||||
(JSClass *) &cache_entry_class, NULL);
|
||||
if (!cached) return JS_FALSE; /* already detached */
|
||||
|
||||
assert(cache_entry_is_valid(cached));
|
||||
if_assert_failed return JS_FALSE;
|
||||
|
||||
/* Get a strong reference to the cache entry to prevent it
|
||||
* from being deleted if some function called below decides to
|
||||
* collect garbage. After this, all code paths must
|
||||
* eventually unlock the object. */
|
||||
object_lock(cached);
|
||||
*vp = STRING_TO_JSVAL(JS_NewStringCopyZ(smjs_ctx, cached->content_type));
|
||||
object_unlock(cached);
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
cache_entry_set_property_type(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSBool strict, JSMutableHandleValue hvp)
|
||||
{
|
||||
ELINKS_CAST_PROP_PARAMS
|
||||
|
||||
struct cache_entry *cached;
|
||||
JSString *jsstr;
|
||||
unsigned char *str;
|
||||
|
||||
/* This can be called if @obj if not itself an instance of the
|
||||
* appropriate class but has one in its prototype chain. Fail
|
||||
* such calls. */
|
||||
if (!JS_InstanceOf(ctx, obj, (JSClass *) &cache_entry_class, NULL))
|
||||
return JS_FALSE;
|
||||
|
||||
cached = JS_GetInstancePrivate(ctx, obj,
|
||||
(JSClass *) &cache_entry_class, NULL);
|
||||
if (!cached) return JS_FALSE; /* already detached */
|
||||
|
||||
assert(cache_entry_is_valid(cached));
|
||||
if_assert_failed return JS_FALSE;
|
||||
|
||||
/* Get a strong reference to the cache entry to prevent it
|
||||
* from being deleted if some function called below decides to
|
||||
* collect garbage. After this, all code paths must
|
||||
* eventually unlock the object. */
|
||||
object_lock(cached);
|
||||
|
||||
jsstr = JS_ValueToString(smjs_ctx, *vp);
|
||||
str = JS_EncodeString(smjs_ctx, jsstr);
|
||||
mem_free_set(&cached->content_type, stracpy(str));
|
||||
|
||||
object_unlock(cached);
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/** Pointed to by cache_entry_class.finalize. SpiderMonkey
|
||||
* automatically finalizes all objects before it frees the JSRuntime,
|
||||
* so cache_entry.jsobject won't be left dangling. */
|
||||
static void
|
||||
cache_entry_finalize(JSContext *ctx, JSObject *obj)
|
||||
cache_entry_finalize(JSFreeOp *op, JSObject *obj)
|
||||
{
|
||||
struct cache_entry *cached;
|
||||
|
||||
#if 0
|
||||
assert(JS_InstanceOf(ctx, obj, (JSClass *) &cache_entry_class, NULL));
|
||||
if_assert_failed return;
|
||||
#endif
|
||||
|
||||
cached = JS_GetInstancePrivate(ctx, obj,
|
||||
(JSClass *) &cache_entry_class, NULL);
|
||||
cached = JS_GetPrivate(obj);
|
||||
|
||||
if (!cached) return; /* already detached */
|
||||
|
||||
JS_SetPrivate(ctx, obj, NULL); /* perhaps not necessary */
|
||||
JS_SetPrivate(obj, NULL); /* perhaps not necessary */
|
||||
assert(cached->jsobject == obj);
|
||||
if_assert_failed return;
|
||||
cached->jsobject = NULL;
|
||||
@ -219,7 +226,7 @@ static const JSClass cache_entry_class = {
|
||||
"cache_entry",
|
||||
JSCLASS_HAS_PRIVATE, /* struct cache_entry *; a weak reference */
|
||||
JS_PropertyStub, JS_PropertyStub,
|
||||
cache_entry_get_property, cache_entry_set_property,
|
||||
JS_PropertyStub, JS_StrictPropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, cache_entry_finalize
|
||||
};
|
||||
|
||||
@ -252,9 +259,7 @@ smjs_get_cache_entry_object(struct cache_entry *cached)
|
||||
/* Do this last, so that if any previous step fails, we can
|
||||
* just forget the object and its finalizer won't attempt to
|
||||
* access @cached. */
|
||||
if (JS_FALSE == JS_SetPrivate(smjs_ctx, cache_entry_object, cached)) /* to @cache_entry_class */
|
||||
return NULL;
|
||||
|
||||
JS_SetPrivate(cache_entry_object, cached); /* to @cache_entry_class */
|
||||
cached->jsobject = cache_entry_object;
|
||||
return cache_entry_object;
|
||||
}
|
||||
@ -278,6 +283,136 @@ smjs_detach_cache_entry_object(struct cache_entry *cached)
|
||||
== cached);
|
||||
if_assert_failed {}
|
||||
|
||||
JS_SetPrivate(smjs_ctx, cached->jsobject, NULL);
|
||||
JS_SetPrivate(cached->jsobject, NULL);
|
||||
cached->jsobject = NULL;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
cache_entry_get_property_length(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSMutableHandleValue hvp)
|
||||
{
|
||||
ELINKS_CAST_PROP_PARAMS
|
||||
|
||||
struct cache_entry *cached;
|
||||
|
||||
/* This can be called if @obj if not itself an instance of the
|
||||
* appropriate class but has one in its prototype chain. Fail
|
||||
* such calls. */
|
||||
if (!JS_InstanceOf(ctx, obj, (JSClass *) &cache_entry_class, NULL))
|
||||
return JS_FALSE;
|
||||
|
||||
cached = JS_GetInstancePrivate(ctx, obj,
|
||||
(JSClass *) &cache_entry_class, NULL);
|
||||
if (!cached) return JS_FALSE; /* already detached */
|
||||
|
||||
assert(cache_entry_is_valid(cached));
|
||||
if_assert_failed return JS_FALSE;
|
||||
|
||||
/* Get a strong reference to the cache entry to prevent it
|
||||
* from being deleted if some function called below decides to
|
||||
* collect garbage. After this, all code paths must
|
||||
* eventually unlock the object. */
|
||||
object_lock(cached);
|
||||
*vp = INT_TO_JSVAL(cached->length);
|
||||
object_unlock(cached);
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
cache_entry_get_property_head(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSMutableHandleValue hvp)
|
||||
{
|
||||
ELINKS_CAST_PROP_PARAMS
|
||||
|
||||
struct cache_entry *cached;
|
||||
|
||||
/* This can be called if @obj if not itself an instance of the
|
||||
* appropriate class but has one in its prototype chain. Fail
|
||||
* such calls. */
|
||||
if (!JS_InstanceOf(ctx, obj, (JSClass *) &cache_entry_class, NULL))
|
||||
return JS_FALSE;
|
||||
|
||||
cached = JS_GetInstancePrivate(ctx, obj,
|
||||
(JSClass *) &cache_entry_class, NULL);
|
||||
if (!cached) return JS_FALSE; /* already detached */
|
||||
|
||||
assert(cache_entry_is_valid(cached));
|
||||
if_assert_failed return JS_FALSE;
|
||||
|
||||
/* Get a strong reference to the cache entry to prevent it
|
||||
* from being deleted if some function called below decides to
|
||||
* collect garbage. After this, all code paths must
|
||||
* eventually unlock the object. */
|
||||
object_lock(cached);
|
||||
*vp = STRING_TO_JSVAL(JS_NewStringCopyZ(smjs_ctx, cached->head));
|
||||
object_unlock(cached);
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
cache_entry_set_property_head(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSBool strict, JSMutableHandleValue hvp)
|
||||
{
|
||||
ELINKS_CAST_PROP_PARAMS
|
||||
|
||||
struct cache_entry *cached;
|
||||
JSString *jsstr;
|
||||
unsigned char *str;
|
||||
|
||||
/* This can be called if @obj if not itself an instance of the
|
||||
* appropriate class but has one in its prototype chain. Fail
|
||||
* such calls. */
|
||||
if (!JS_InstanceOf(ctx, obj, (JSClass *) &cache_entry_class, NULL))
|
||||
return JS_FALSE;
|
||||
|
||||
cached = JS_GetInstancePrivate(ctx, obj,
|
||||
(JSClass *) &cache_entry_class, NULL);
|
||||
if (!cached) return JS_FALSE; /* already detached */
|
||||
|
||||
assert(cache_entry_is_valid(cached));
|
||||
if_assert_failed return JS_FALSE;
|
||||
|
||||
/* Get a strong reference to the cache entry to prevent it
|
||||
* from being deleted if some function called below decides to
|
||||
* collect garbage. After this, all code paths must
|
||||
* eventually unlock the object. */
|
||||
object_lock(cached);
|
||||
|
||||
jsstr = JS_ValueToString(smjs_ctx, *vp);
|
||||
str = JS_EncodeString(smjs_ctx, jsstr);
|
||||
mem_free_set(&cached->head, stracpy(str));
|
||||
|
||||
object_unlock(cached);
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
cache_entry_get_property_uri(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSMutableHandleValue hvp)
|
||||
{
|
||||
ELINKS_CAST_PROP_PARAMS
|
||||
|
||||
struct cache_entry *cached;
|
||||
|
||||
/* This can be called if @obj if not itself an instance of the
|
||||
* appropriate class but has one in its prototype chain. Fail
|
||||
* such calls. */
|
||||
if (!JS_InstanceOf(ctx, obj, (JSClass *) &cache_entry_class, NULL))
|
||||
return JS_FALSE;
|
||||
|
||||
cached = JS_GetInstancePrivate(ctx, obj,
|
||||
(JSClass *) &cache_entry_class, NULL);
|
||||
if (!cached) return JS_FALSE; /* already detached */
|
||||
|
||||
assert(cache_entry_is_valid(cached));
|
||||
if_assert_failed return JS_FALSE;
|
||||
|
||||
/* Get a strong reference to the cache entry to prevent it
|
||||
* from being deleted if some function called below decides to
|
||||
* collect garbage. After this, all code paths must
|
||||
* eventually unlock the object. */
|
||||
object_lock(cached);
|
||||
*vp = STRING_TO_JSVAL(JS_NewStringCopyZ(smjs_ctx, struri(cached->uri)));
|
||||
object_unlock(cached);
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
@ -94,7 +94,7 @@ smjs_do_file(unsigned char *path)
|
||||
}
|
||||
|
||||
static JSBool
|
||||
smjs_do_file_wrapper(JSContext *ctx, uintN argc, jsval *rval)
|
||||
smjs_do_file_wrapper(JSContext *ctx, unsigned int argc, jsval *rval)
|
||||
{
|
||||
jsval *argv = JS_ARGV(ctx, rval);
|
||||
JSString *jsstr = JS_ValueToString(smjs_ctx, *argv);
|
||||
@ -136,7 +136,7 @@ init_smjs(struct module *module)
|
||||
return;
|
||||
}
|
||||
|
||||
JS_SetOptions(smjs_ctx, JSOPTION_VAROBJFIX | JSOPTION_JIT | JSOPTION_METHODJIT);
|
||||
JS_SetOptions(smjs_ctx, JSOPTION_VAROBJFIX | JSOPTION_METHODJIT);
|
||||
JS_SetVersion(smjs_ctx, JSVERSION_LATEST);
|
||||
|
||||
JS_SetErrorReporter(smjs_ctx, error_reporter);
|
||||
|
@ -33,7 +33,7 @@
|
||||
|
||||
/* @elinks_funcs{"alert"} */
|
||||
static JSBool
|
||||
elinks_alert(JSContext *ctx, uintN argc, jsval *rval)
|
||||
elinks_alert(JSContext *ctx, unsigned int argc, jsval *rval)
|
||||
{
|
||||
jsval val;
|
||||
jsval *argv = JS_ARGV(ctx, rval);
|
||||
@ -69,7 +69,7 @@ elinks_alert(JSContext *ctx, uintN argc, jsval *rval)
|
||||
|
||||
/* @elinks_funcs{"execute"} */
|
||||
static JSBool
|
||||
elinks_execute(JSContext *ctx, uintN argc, jsval *rval)
|
||||
elinks_execute(JSContext *ctx, unsigned int argc, jsval *rval)
|
||||
{
|
||||
jsval val;
|
||||
jsval *argv = JS_ARGV(ctx, rval);
|
||||
@ -95,10 +95,15 @@ enum elinks_prop {
|
||||
ELINKS_SESSION,
|
||||
};
|
||||
|
||||
static JSBool elinks_get_property_home(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSMutableHandleValue hvp);
|
||||
static JSBool elinks_get_property_location(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSMutableHandleValue hvp);
|
||||
static JSBool elinks_set_property_location(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSBool strict, JSMutableHandleValue hvp);
|
||||
static JSBool elinks_get_property_session(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSMutableHandleValue hvp);
|
||||
|
||||
static const JSPropertySpec elinks_props[] = {
|
||||
{ "home", ELINKS_HOME, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY },
|
||||
{ "location", ELINKS_LOCATION, JSPROP_ENUMERATE | JSPROP_PERMANENT },
|
||||
{ "session", ELINKS_SESSION, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY },
|
||||
{ "home", 0, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, JSOP_WRAPPER(elinks_get_property_home), JSOP_NULLWRAPPER },
|
||||
{ "location", 0, JSPROP_ENUMERATE | JSPROP_PERMANENT, JSOP_WRAPPER(elinks_get_property_location), JSOP_WRAPPER(elinks_set_property_location) },
|
||||
{ "session", 0, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, JSOP_WRAPPER(elinks_get_property_session), JSOP_NULLWRAPPER},
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
@ -106,8 +111,11 @@ static const JSClass elinks_class;
|
||||
|
||||
/* @elinks_class.getProperty */
|
||||
static JSBool
|
||||
elinks_get_property(JSContext *ctx, JSObject *obj, jsid id, jsval *vp)
|
||||
elinks_get_property(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSMutableHandleValue hvp)
|
||||
{
|
||||
ELINKS_CAST_PROP_PARAMS
|
||||
jsid id = *(hid._);
|
||||
|
||||
/* This can be called if @obj if not itself an instance of the
|
||||
* appropriate class but has one in its prototype chain. Fail
|
||||
* such calls. */
|
||||
@ -161,8 +169,11 @@ elinks_get_property(JSContext *ctx, JSObject *obj, jsid id, jsval *vp)
|
||||
}
|
||||
|
||||
static JSBool
|
||||
elinks_set_property(JSContext *ctx, JSObject *obj, jsid id, JSBool strict, jsval *vp)
|
||||
elinks_set_property(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSBool strict, JSMutableHandleValue hvp)
|
||||
{
|
||||
ELINKS_CAST_PROP_PARAMS
|
||||
jsid id = *(hid._);
|
||||
|
||||
/* This can be called if @obj if not itself an instance of the
|
||||
* appropriate class but has one in its prototype chain. Fail
|
||||
* such calls. */
|
||||
@ -205,7 +216,7 @@ static const JSClass elinks_class = {
|
||||
0,
|
||||
JS_PropertyStub, JS_PropertyStub,
|
||||
elinks_get_property, elinks_set_property,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, NULL
|
||||
};
|
||||
|
||||
static const spidermonkeyFunctionSpec elinks_funcs[] = {
|
||||
@ -262,3 +273,87 @@ smjs_invoke_elinks_object_method(unsigned char *method, jsval argv[], int argc,
|
||||
return JS_CallFunctionValue(smjs_ctx, smjs_elinks_object,
|
||||
*rval, argc, argv, rval);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
elinks_get_property_home(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSMutableHandleValue hvp)
|
||||
{
|
||||
ELINKS_CAST_PROP_PARAMS
|
||||
|
||||
/* This can be called if @obj if not itself an instance of the
|
||||
* appropriate class but has one in its prototype chain. Fail
|
||||
* such calls. */
|
||||
if (!JS_InstanceOf(ctx, obj, (JSClass *) &elinks_class, NULL))
|
||||
return JS_FALSE;
|
||||
|
||||
*vp = STRING_TO_JSVAL(JS_NewStringCopyZ(smjs_ctx, elinks_home));
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
elinks_get_property_location(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSMutableHandleValue hvp)
|
||||
{
|
||||
ELINKS_CAST_PROP_PARAMS
|
||||
struct uri *uri;
|
||||
|
||||
/* This can be called if @obj if not itself an instance of the
|
||||
* appropriate class but has one in its prototype chain. Fail
|
||||
* such calls. */
|
||||
if (!JS_InstanceOf(ctx, obj, (JSClass *) &elinks_class, NULL))
|
||||
return JS_FALSE;
|
||||
|
||||
if (!smjs_ses) return JS_FALSE;
|
||||
|
||||
uri = have_location(smjs_ses) ? cur_loc(smjs_ses)->vs.uri : smjs_ses->loading_uri;
|
||||
*vp = STRING_TO_JSVAL(JS_NewStringCopyZ(smjs_ctx, uri ? (const char *) struri(uri) : ""));
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
elinks_set_property_location(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSBool strict, JSMutableHandleValue hvp)
|
||||
{
|
||||
ELINKS_CAST_PROP_PARAMS
|
||||
JSString *jsstr;
|
||||
unsigned char *url;
|
||||
|
||||
/* This can be called if @obj if not itself an instance of the
|
||||
* appropriate class but has one in its prototype chain. Fail
|
||||
* such calls. */
|
||||
if (!JS_InstanceOf(ctx, obj, (JSClass *) &elinks_class, NULL))
|
||||
return JS_FALSE;
|
||||
|
||||
if (!smjs_ses) return JS_FALSE;
|
||||
|
||||
jsstr = JS_ValueToString(smjs_ctx, *vp);
|
||||
if (!jsstr) return JS_FALSE;
|
||||
|
||||
url = JS_EncodeString(smjs_ctx, jsstr);
|
||||
if (!url) return JS_FALSE;
|
||||
|
||||
goto_url(smjs_ses, url);
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
elinks_get_property_session(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSMutableHandleValue hvp)
|
||||
{
|
||||
ELINKS_CAST_PROP_PARAMS
|
||||
JSObject *jsobj;
|
||||
|
||||
/* This can be called if @obj if not itself an instance of the
|
||||
* appropriate class but has one in its prototype chain. Fail
|
||||
* such calls. */
|
||||
if (!JS_InstanceOf(ctx, obj, (JSClass *) &elinks_class, NULL))
|
||||
return JS_FALSE;
|
||||
|
||||
if (!smjs_ses) return JS_FALSE;
|
||||
|
||||
jsobj = smjs_get_session_object(smjs_ses);
|
||||
if (!jsobj) return JS_FALSE;
|
||||
|
||||
object_to_jsval(ctx, vp, jsobj);
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ static const JSClass global_class = {
|
||||
"global", JSCLASS_GLOBAL_FLAGS,
|
||||
JS_PropertyStub, JS_PropertyStub,
|
||||
JS_PropertyStub, JS_StrictPropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, NULL
|
||||
};
|
||||
|
||||
static JSObject *
|
||||
@ -29,7 +29,7 @@ smjs_get_global_object(void)
|
||||
|
||||
assert(smjs_ctx);
|
||||
|
||||
jsobj = JS_NewCompartmentAndGlobalObject(smjs_ctx, (JSClass *) &global_class, NULL);
|
||||
jsobj = JS_NewGlobalObject(smjs_ctx, (JSClass *) &global_class, NULL);
|
||||
|
||||
if (!jsobj) return NULL;
|
||||
|
||||
|
@ -18,16 +18,15 @@ static const JSClass smjs_globhist_item_class; /* defined below */
|
||||
|
||||
/* @smjs_globhist_item_class.finalize */
|
||||
static void
|
||||
smjs_globhist_item_finalize(JSContext *ctx, JSObject *obj)
|
||||
smjs_globhist_item_finalize(JSFreeOp *op, JSObject *obj)
|
||||
{
|
||||
struct global_history_item *history_item;
|
||||
|
||||
#if 0
|
||||
assert(JS_InstanceOf(ctx, obj, (JSClass *) &smjs_globhist_item_class, NULL));
|
||||
if_assert_failed return;
|
||||
#endif
|
||||
|
||||
history_item = JS_GetInstancePrivate(ctx, obj,
|
||||
(JSClass *) &smjs_globhist_item_class,
|
||||
NULL);
|
||||
history_item = JS_GetPrivate(obj);
|
||||
|
||||
if (history_item) object_unlock(history_item);
|
||||
}
|
||||
@ -42,18 +41,28 @@ enum smjs_globhist_item_prop {
|
||||
GLOBHIST_LAST_VISIT = -3,
|
||||
};
|
||||
|
||||
static JSBool smjs_globhist_item_get_property_title(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSMutableHandleValue hvp);
|
||||
static JSBool smjs_globhist_item_set_property_title(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSBool strict, JSMutableHandleValue hvp);
|
||||
static JSBool smjs_globhist_item_get_property_url(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSMutableHandleValue hvp);
|
||||
static JSBool smjs_globhist_item_set_property_url(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSBool strict, JSMutableHandleValue hvp);
|
||||
static JSBool smjs_globhist_item_get_property_last_visit(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSMutableHandleValue hvp);
|
||||
static JSBool smjs_globhist_item_set_property_last_visit(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSBool strict, JSMutableHandleValue hvp);
|
||||
|
||||
static const JSPropertySpec smjs_globhist_item_props[] = {
|
||||
{ "title", GLOBHIST_TITLE, JSPROP_ENUMERATE },
|
||||
{ "url", GLOBHIST_URL, JSPROP_ENUMERATE },
|
||||
{ "last_visit", GLOBHIST_LAST_VISIT, JSPROP_ENUMERATE },
|
||||
{ "title", 0, JSPROP_ENUMERATE, JSOP_WRAPPER(smjs_globhist_item_get_property_title), JSOP_WRAPPER(smjs_globhist_item_set_property_title) },
|
||||
{ "url", 0, JSPROP_ENUMERATE, JSOP_WRAPPER(smjs_globhist_item_get_property_url), JSOP_WRAPPER(smjs_globhist_item_set_property_url) },
|
||||
{ "last_visit", 0, JSPROP_ENUMERATE, JSOP_WRAPPER(smjs_globhist_item_get_property_last_visit), JSOP_WRAPPER(smjs_globhist_item_set_property_last_visit) },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
/* @smjs_globhist_item_class.getProperty */
|
||||
static JSBool
|
||||
smjs_globhist_item_get_property(JSContext *ctx, JSObject *obj, jsid id,
|
||||
jsval *vp)
|
||||
smjs_globhist_item_get_property(JSContext *ctx, JSHandleObject hobj, JSHandleId hid,
|
||||
JSMutableHandleValue hvp)
|
||||
{
|
||||
ELINKS_CAST_PROP_PARAMS
|
||||
jsid id = *(hid._);
|
||||
|
||||
struct global_history_item *history_item;
|
||||
|
||||
/* This can be called if @obj if not itself an instance of the
|
||||
@ -101,7 +110,7 @@ smjs_globhist_item_get_property(JSContext *ctx, JSObject *obj, jsid id,
|
||||
* Since the Date object uses milliseconds since the epoch,
|
||||
* I'd rather export that, but SpiderMonkey doesn't provide
|
||||
* a suitable type. -- Miciah */
|
||||
JS_NewNumberValue(smjs_ctx, history_item->last_visit, vp);
|
||||
*vp = JS_NumberValue(history_item->last_visit);
|
||||
|
||||
return JS_TRUE;
|
||||
default:
|
||||
@ -117,8 +126,11 @@ smjs_globhist_item_get_property(JSContext *ctx, JSObject *obj, jsid id,
|
||||
|
||||
/* @smjs_globhist_item_class.setProperty */
|
||||
static JSBool
|
||||
smjs_globhist_item_set_property(JSContext *ctx, JSObject *obj, jsid id, JSBool strict, jsval *vp)
|
||||
smjs_globhist_item_set_property(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSBool strict, JSMutableHandleValue hvp)
|
||||
{
|
||||
ELINKS_CAST_PROP_PARAMS
|
||||
jsid id = *(hid._);
|
||||
|
||||
struct global_history_item *history_item;
|
||||
|
||||
/* This can be called if @obj if not itself an instance of the
|
||||
@ -154,7 +166,7 @@ smjs_globhist_item_set_property(JSContext *ctx, JSObject *obj, jsid id, JSBool s
|
||||
return JS_TRUE;
|
||||
}
|
||||
case GLOBHIST_LAST_VISIT: {
|
||||
uint32 seconds;
|
||||
uint32_t seconds;
|
||||
|
||||
/* Bug 923: Assumes time_t values fit in uint32. */
|
||||
JS_ValueToECMAUint32(smjs_ctx, *vp, &seconds);
|
||||
@ -189,10 +201,10 @@ smjs_get_globhist_item_object(struct global_history_item *history_item)
|
||||
NULL, NULL);
|
||||
if (!jsobj
|
||||
|| JS_TRUE != JS_DefineProperties(smjs_ctx, jsobj,
|
||||
(JSPropertySpec *) smjs_globhist_item_props)
|
||||
|| JS_TRUE != JS_SetPrivate(smjs_ctx, jsobj, history_item)) /* to @smjs_globhist_item_class */
|
||||
(JSPropertySpec *) smjs_globhist_item_props)) {
|
||||
return NULL;
|
||||
|
||||
}
|
||||
JS_SetPrivate(jsobj, history_item); /* to @smjs_globhist_item_class */
|
||||
object_lock(history_item);
|
||||
|
||||
return jsobj;
|
||||
@ -201,8 +213,12 @@ smjs_get_globhist_item_object(struct global_history_item *history_item)
|
||||
|
||||
/* @smjs_globhist_class.getProperty */
|
||||
static JSBool
|
||||
smjs_globhist_get_property(JSContext *ctx, JSObject *obj, jsid id, jsval *vp)
|
||||
smjs_globhist_get_property(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSMutableHandleValue hvp)
|
||||
{
|
||||
ELINKS_CAST_PROP_PARAMS
|
||||
jsid id = *(hid._);
|
||||
(void)obj;
|
||||
|
||||
JSObject *jsobj;
|
||||
unsigned char *uri_string;
|
||||
struct global_history_item *history_item;
|
||||
@ -234,7 +250,7 @@ static const JSClass smjs_globhist_class = {
|
||||
"global_history", 0,
|
||||
JS_PropertyStub, JS_PropertyStub,
|
||||
smjs_globhist_get_property, JS_StrictPropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, NULL,
|
||||
};
|
||||
|
||||
static JSObject *
|
||||
@ -265,3 +281,178 @@ smjs_init_globhist_interface(void)
|
||||
|
||||
JS_SetProperty(smjs_ctx, smjs_elinks_object, "globhist", &val);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
smjs_globhist_item_get_property_title(JSContext *ctx, JSHandleObject hobj, JSHandleId hid,
|
||||
JSMutableHandleValue hvp)
|
||||
{
|
||||
ELINKS_CAST_PROP_PARAMS
|
||||
|
||||
struct global_history_item *history_item;
|
||||
|
||||
/* This can be called if @obj if not itself an instance of the
|
||||
* appropriate class but has one in its prototype chain. Fail
|
||||
* such calls. */
|
||||
if (!JS_InstanceOf(ctx, obj, (JSClass *) &smjs_globhist_item_class, NULL))
|
||||
return JS_FALSE;
|
||||
|
||||
history_item = JS_GetInstancePrivate(ctx, obj,
|
||||
(JSClass *) &smjs_globhist_item_class,
|
||||
NULL);
|
||||
|
||||
if (!history_item) return JS_FALSE;
|
||||
|
||||
*vp = STRING_TO_JSVAL(JS_NewStringCopyZ(smjs_ctx, history_item->title));
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
smjs_globhist_item_set_property_title(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSBool strict, JSMutableHandleValue hvp)
|
||||
{
|
||||
ELINKS_CAST_PROP_PARAMS
|
||||
|
||||
struct global_history_item *history_item;
|
||||
JSString *jsstr;
|
||||
unsigned char *str;
|
||||
|
||||
/* This can be called if @obj if not itself an instance of the
|
||||
* appropriate class but has one in its prototype chain. Fail
|
||||
* such calls. */
|
||||
if (!JS_InstanceOf(ctx, obj, (JSClass *) &smjs_globhist_item_class, NULL))
|
||||
return JS_FALSE;
|
||||
|
||||
history_item = JS_GetInstancePrivate(ctx, obj,
|
||||
(JSClass *) &smjs_globhist_item_class,
|
||||
NULL);
|
||||
|
||||
if (!history_item) return JS_FALSE;
|
||||
|
||||
jsstr = JS_ValueToString(smjs_ctx, *vp);
|
||||
str = JS_EncodeString(smjs_ctx, jsstr);
|
||||
mem_free_set(&history_item->title, stracpy(str));
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
smjs_globhist_item_get_property_url(JSContext *ctx, JSHandleObject hobj, JSHandleId hid,
|
||||
JSMutableHandleValue hvp)
|
||||
{
|
||||
ELINKS_CAST_PROP_PARAMS
|
||||
|
||||
struct global_history_item *history_item;
|
||||
|
||||
/* This can be called if @obj if not itself an instance of the
|
||||
* appropriate class but has one in its prototype chain. Fail
|
||||
* such calls. */
|
||||
if (!JS_InstanceOf(ctx, obj, (JSClass *) &smjs_globhist_item_class, NULL))
|
||||
return JS_FALSE;
|
||||
|
||||
history_item = JS_GetInstancePrivate(ctx, obj,
|
||||
(JSClass *) &smjs_globhist_item_class,
|
||||
NULL);
|
||||
|
||||
if (!history_item) return JS_FALSE;
|
||||
|
||||
*vp = STRING_TO_JSVAL(JS_NewStringCopyZ(smjs_ctx, history_item->url));
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
smjs_globhist_item_set_property_url(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSBool strict, JSMutableHandleValue hvp)
|
||||
{
|
||||
ELINKS_CAST_PROP_PARAMS
|
||||
|
||||
struct global_history_item *history_item;
|
||||
JSString *jsstr;
|
||||
unsigned char *str;
|
||||
|
||||
/* This can be called if @obj if not itself an instance of the
|
||||
* appropriate class but has one in its prototype chain. Fail
|
||||
* such calls. */
|
||||
if (!JS_InstanceOf(ctx, obj, (JSClass *) &smjs_globhist_item_class, NULL))
|
||||
return JS_FALSE;
|
||||
|
||||
history_item = JS_GetInstancePrivate(ctx, obj,
|
||||
(JSClass *) &smjs_globhist_item_class,
|
||||
NULL);
|
||||
|
||||
if (!history_item) return JS_FALSE;
|
||||
|
||||
jsstr = JS_ValueToString(smjs_ctx, *vp);
|
||||
str = JS_EncodeString(smjs_ctx, jsstr);
|
||||
mem_free_set(&history_item->url, stracpy(str));
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
smjs_globhist_item_get_property_last_visit(JSContext *ctx, JSHandleObject hobj, JSHandleId hid,
|
||||
JSMutableHandleValue hvp)
|
||||
{
|
||||
ELINKS_CAST_PROP_PARAMS
|
||||
|
||||
struct global_history_item *history_item;
|
||||
|
||||
/* This can be called if @obj if not itself an instance of the
|
||||
* appropriate class but has one in its prototype chain. Fail
|
||||
* such calls. */
|
||||
if (!JS_InstanceOf(ctx, obj, (JSClass *) &smjs_globhist_item_class, NULL))
|
||||
return JS_FALSE;
|
||||
|
||||
history_item = JS_GetInstancePrivate(ctx, obj,
|
||||
(JSClass *) &smjs_globhist_item_class,
|
||||
NULL);
|
||||
|
||||
if (!history_item) return JS_FALSE;
|
||||
|
||||
/* TODO: I'd rather return a date object, but that introduces
|
||||
* synchronisation issues:
|
||||
*
|
||||
* - How do we cause a change to that date object to affect
|
||||
* the actual global history item?
|
||||
* - How do we get a change to that global history item
|
||||
* to affect all date objects?
|
||||
*
|
||||
* The biggest obstacle is that we have no way to trigger code
|
||||
* when one messes with the date object.
|
||||
*
|
||||
* -- Miciah */
|
||||
/* XXX: Currently, ECMAScript gets seconds since the epoch.
|
||||
* Since the Date object uses milliseconds since the epoch,
|
||||
* I'd rather export that, but SpiderMonkey doesn't provide
|
||||
* a suitable type. -- Miciah */
|
||||
*vp = JS_NumberValue(history_item->last_visit);
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
/* @smjs_globhist_item_class.setProperty */
|
||||
static JSBool
|
||||
smjs_globhist_item_set_property_last_visit(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSBool strict, JSMutableHandleValue hvp)
|
||||
{
|
||||
ELINKS_CAST_PROP_PARAMS
|
||||
|
||||
struct global_history_item *history_item;
|
||||
uint32_t seconds;
|
||||
|
||||
/* This can be called if @obj if not itself an instance of the
|
||||
* appropriate class but has one in its prototype chain. Fail
|
||||
* such calls. */
|
||||
if (!JS_InstanceOf(ctx, obj, (JSClass *) &smjs_globhist_item_class, NULL))
|
||||
return JS_FALSE;
|
||||
|
||||
history_item = JS_GetInstancePrivate(ctx, obj,
|
||||
(JSClass *) &smjs_globhist_item_class,
|
||||
NULL);
|
||||
|
||||
if (!history_item) return JS_FALSE;
|
||||
|
||||
/* Bug 923: Assumes time_t values fit in uint32. */
|
||||
JS_ValueToECMAUint32(smjs_ctx, *vp, &seconds);
|
||||
history_item->last_visit = seconds;
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
@ -17,8 +17,11 @@ static const JSClass keymap_class; /* defined below */
|
||||
|
||||
/* @keymap_class.getProperty */
|
||||
static JSBool
|
||||
keymap_get_property(JSContext *ctx, JSObject *obj, jsid id, jsval *vp)
|
||||
keymap_get_property(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSMutableHandleValue hvp)
|
||||
{
|
||||
ELINKS_CAST_PROP_PARAMS
|
||||
jsid id = *(hid._);
|
||||
|
||||
unsigned char *action_str;
|
||||
const unsigned char *keystroke_str;
|
||||
int *data;
|
||||
@ -74,8 +77,11 @@ smjs_keybinding_action_callback(va_list ap, void *data)
|
||||
|
||||
/* @keymap_class.setProperty */
|
||||
static JSBool
|
||||
keymap_set_property(JSContext *ctx, JSObject *obj, jsid id, JSBool strict, jsval *vp)
|
||||
keymap_set_property(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSBool strict, JSMutableHandleValue hvp)
|
||||
{
|
||||
ELINKS_CAST_PROP_PARAMS
|
||||
jsid id = *(hid._);
|
||||
|
||||
int *data;
|
||||
unsigned char *keymap_str;
|
||||
jsval val;
|
||||
@ -116,7 +122,7 @@ keymap_set_property(JSContext *ctx, JSObject *obj, jsid id, JSBool strict, jsval
|
||||
|
||||
return JS_TRUE;
|
||||
|
||||
} else if (JSVAL_IS_OBJECT(*vp)) {
|
||||
} else if (!JSVAL_IS_PRIMITIVE(*vp) || JSVAL_IS_NULL(*vp)) {
|
||||
unsigned char *err = NULL;
|
||||
int event_id;
|
||||
struct string event_name = NULL_STRING;
|
||||
@ -160,15 +166,15 @@ keymap_set_property(JSContext *ctx, JSObject *obj, jsid id, JSBool strict, jsval
|
||||
|
||||
/* @keymap_class.finalize */
|
||||
static void
|
||||
keymap_finalize(JSContext *ctx, JSObject *obj)
|
||||
keymap_finalize(JSFreeOp *op, JSObject *obj)
|
||||
{
|
||||
void *data;
|
||||
|
||||
#if 0
|
||||
assert(JS_InstanceOf(ctx, obj, (JSClass *) &keymap_class, NULL));
|
||||
if_assert_failed return;
|
||||
#endif
|
||||
|
||||
data = JS_GetInstancePrivate(ctx, obj,
|
||||
(JSClass *) &keymap_class, NULL);
|
||||
data = JS_GetPrivate(obj);
|
||||
|
||||
mem_free(data);
|
||||
}
|
||||
@ -197,12 +203,8 @@ smjs_get_keymap_object(enum keymap_id keymap_id)
|
||||
data = intdup(keymap_id);
|
||||
if (!data) return NULL;
|
||||
|
||||
if (JS_TRUE == JS_SetPrivate(smjs_ctx, keymap_object, data)) /* to @keymap_class */
|
||||
return keymap_object;
|
||||
|
||||
mem_free(data);
|
||||
|
||||
return NULL;
|
||||
JS_SetPrivate(keymap_object, data); /* to @keymap_class */
|
||||
return keymap_object;
|
||||
}
|
||||
|
||||
static const JSClass keymaps_hash_class = {
|
||||
@ -210,7 +212,7 @@ static const JSClass keymaps_hash_class = {
|
||||
JSCLASS_HAS_PRIVATE,
|
||||
JS_PropertyStub, JS_PropertyStub,
|
||||
JS_PropertyStub, JS_StrictPropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, NULL,
|
||||
};
|
||||
|
||||
static JSObject *
|
||||
|
@ -65,7 +65,7 @@ end:
|
||||
}
|
||||
|
||||
static JSBool
|
||||
smjs_load_uri(JSContext *ctx, uintN argc, jsval *rval)
|
||||
smjs_load_uri(JSContext *ctx, unsigned int argc, jsval *rval)
|
||||
{
|
||||
jsval *argv = JS_ARGV(ctx, rval);
|
||||
struct smjs_load_uri_hop *hop;
|
||||
|
@ -42,8 +42,11 @@ static const JSClass location_array_class; /* Defined below. */
|
||||
|
||||
/* @location_array.getProperty */
|
||||
static JSBool
|
||||
smjs_location_array_get_property(JSContext *ctx, JSObject *obj, jsid id, jsval *vp)
|
||||
smjs_location_array_get_property(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSMutableHandleValue hvp)
|
||||
{
|
||||
ELINKS_CAST_PROP_PARAMS
|
||||
jsid id = *(hid._);
|
||||
|
||||
struct session *ses;
|
||||
int index;
|
||||
struct location *loc;
|
||||
@ -90,19 +93,20 @@ smjs_location_array_get_property(JSContext *ctx, JSObject *obj, jsid id, jsval *
|
||||
* finalizes all objects before it frees the JSRuntime, so
|
||||
* session.history_jsobject won't be left dangling. */
|
||||
static void
|
||||
smjs_location_array_finalize(JSContext *ctx, JSObject *obj)
|
||||
smjs_location_array_finalize(JSFreeOp *op, JSObject *obj)
|
||||
{
|
||||
struct session *ses;
|
||||
|
||||
#if 0
|
||||
assert(JS_InstanceOf(ctx, obj, (JSClass *) &location_array_class, NULL));
|
||||
if_assert_failed return;
|
||||
#endif
|
||||
|
||||
ses = JS_GetInstancePrivate(ctx, obj,
|
||||
(JSClass *) &location_array_class, NULL);
|
||||
ses = JS_GetPrivate(obj);
|
||||
|
||||
if (!ses) return; /* already detached */
|
||||
|
||||
JS_SetPrivate(ctx, obj, NULL); /* perhaps not necessary */
|
||||
JS_SetPrivate(obj, NULL); /* perhaps not necessary */
|
||||
assert(ses->history_jsobject == obj);
|
||||
if_assert_failed return;
|
||||
ses->history_jsobject = NULL;
|
||||
@ -135,8 +139,7 @@ smjs_get_session_location_array_object(struct session *ses)
|
||||
/* Do this last, so that if any previous step fails, we can
|
||||
* just forget the object and its finalizer won't attempt to
|
||||
* access @ses. */
|
||||
if (JS_FALSE == JS_SetPrivate(smjs_ctx, obj, ses))
|
||||
return NULL;
|
||||
JS_SetPrivate(obj, ses);
|
||||
|
||||
ses->history_jsobject = obj;
|
||||
return obj;
|
||||
@ -188,8 +191,11 @@ static const JSPropertySpec session_props[] = {
|
||||
|
||||
/* @session_class.getProperty */
|
||||
static JSBool
|
||||
session_get_property(JSContext *ctx, JSObject *obj, jsid id, jsval *vp)
|
||||
session_get_property(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSMutableHandleValue hvp)
|
||||
{
|
||||
ELINKS_CAST_PROP_PARAMS
|
||||
jsid id = *(hid._);
|
||||
|
||||
struct session *ses;
|
||||
|
||||
/* This can be called if @obj if not itself an instance of the
|
||||
@ -294,8 +300,11 @@ session_get_property(JSContext *ctx, JSObject *obj, jsid id, jsval *vp)
|
||||
}
|
||||
|
||||
static JSBool
|
||||
session_set_property(JSContext *ctx, JSObject *obj, jsid id, JSBool strict, jsval *vp)
|
||||
session_set_property(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSBool strict, JSMutableHandleValue hvp)
|
||||
{
|
||||
ELINKS_CAST_PROP_PARAMS
|
||||
jsid id = *(hid._);
|
||||
|
||||
struct session *ses;
|
||||
|
||||
/* This can be called if @obj if not itself an instance of the
|
||||
@ -450,7 +459,7 @@ session_set_property(JSContext *ctx, JSObject *obj, jsid id, JSBool strict, jsva
|
||||
/** Pointed to by session_class.construct. Create a new session (tab)
|
||||
* and return the JSObject wrapper. */
|
||||
static JSBool
|
||||
session_construct(JSContext *ctx, uintN argc, jsval *rval)
|
||||
session_construct(JSContext *ctx, unsigned int argc, jsval *rval)
|
||||
{
|
||||
jsval val;
|
||||
jsval *argv = JS_ARGV(ctx, rval);
|
||||
@ -484,19 +493,20 @@ session_construct(JSContext *ctx, uintN argc, jsval *rval)
|
||||
* finalizes all objects before it frees the JSRuntime, so session.jsobject
|
||||
* won't be left dangling. */
|
||||
static void
|
||||
session_finalize(JSContext *ctx, JSObject *obj)
|
||||
session_finalize(JSFreeOp *op, JSObject *obj)
|
||||
{
|
||||
struct session *ses;
|
||||
|
||||
#if 0
|
||||
assert(JS_InstanceOf(ctx, obj, (JSClass *) &session_class, NULL));
|
||||
if_assert_failed return;
|
||||
#endif
|
||||
|
||||
ses = JS_GetInstancePrivate(ctx, obj,
|
||||
(JSClass *) &session_class, NULL);
|
||||
ses = JS_GetPrivate(obj);
|
||||
|
||||
if (!ses) return; /* already detached */
|
||||
|
||||
JS_SetPrivate(ctx, obj, NULL); /* perhaps not necessary */
|
||||
JS_SetPrivate(obj, NULL); /* perhaps not necessary */
|
||||
assert(ses->jsobject == obj);
|
||||
if_assert_failed return;
|
||||
ses->jsobject = NULL;
|
||||
@ -508,7 +518,7 @@ static const JSClass session_class = {
|
||||
JS_PropertyStub, JS_PropertyStub,
|
||||
session_get_property, session_set_property,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, session_finalize,
|
||||
NULL, NULL, session_construct
|
||||
NULL, NULL, NULL, session_construct
|
||||
};
|
||||
|
||||
/** Return an SMJS object through which scripts can access @a ses.
|
||||
@ -534,8 +544,7 @@ smjs_get_session_object(struct session *ses)
|
||||
/* Do this last, so that if any previous step fails, we can
|
||||
* just forget the object and its finalizer won't attempt to
|
||||
* access @ses. */
|
||||
if (JS_FALSE == JS_SetPrivate(smjs_ctx, obj, ses)) /* to @session_class */
|
||||
return NULL;
|
||||
JS_SetPrivate(obj, ses); /* to @session_class */
|
||||
|
||||
ses->jsobject = obj;
|
||||
return obj;
|
||||
@ -558,7 +567,7 @@ smjs_detach_session_object(struct session *ses)
|
||||
== ses);
|
||||
if_assert_failed {}
|
||||
|
||||
JS_SetPrivate(smjs_ctx, ses->jsobject, NULL);
|
||||
JS_SetPrivate(ses->jsobject, NULL);
|
||||
ses->jsobject = NULL;
|
||||
}
|
||||
|
||||
@ -569,7 +578,7 @@ smjs_detach_session_object(struct session *ses)
|
||||
== ses);
|
||||
if_assert_failed {}
|
||||
|
||||
JS_SetPrivate(smjs_ctx, ses->history_jsobject, NULL);
|
||||
JS_SetPrivate(ses->history_jsobject, NULL);
|
||||
ses->history_jsobject = NULL;
|
||||
}
|
||||
}
|
||||
@ -581,10 +590,13 @@ smjs_detach_session_object(struct session *ses)
|
||||
* previously attached to the session object, the object will remain in
|
||||
* memory but it will no longer be able to access the session object. */
|
||||
static JSBool
|
||||
session_array_get_property(JSContext *ctx, JSObject *obj, jsid id, jsval *vp)
|
||||
session_array_get_property(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSMutableHandleValue hvp)
|
||||
{
|
||||
ELINKS_CAST_PROP_PARAMS
|
||||
jsid id = *(hid._);
|
||||
|
||||
JSObject *tabobj;
|
||||
struct terminal *term = JS_GetPrivate(ctx, obj);
|
||||
struct terminal *term = JS_GetPrivate(obj);
|
||||
int index;
|
||||
struct window *tab;
|
||||
|
||||
@ -614,7 +626,7 @@ static const JSClass session_array_class = {
|
||||
JSCLASS_HAS_PRIVATE, /* struct terminal *term; a weak reference */
|
||||
JS_PropertyStub, JS_PropertyStub,
|
||||
session_array_get_property, JS_StrictPropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, NULL
|
||||
};
|
||||
|
||||
JSObject *
|
||||
@ -629,8 +641,7 @@ smjs_get_session_array_object(struct terminal *term)
|
||||
NULL, NULL);
|
||||
if (!obj) return NULL;
|
||||
|
||||
if (JS_FALSE == JS_SetPrivate(smjs_ctx, obj, term))
|
||||
return NULL;
|
||||
JS_SetPrivate(obj, term);
|
||||
|
||||
return obj;
|
||||
}
|
||||
@ -653,12 +664,12 @@ smjs_detach_session_array_object(struct terminal *term)
|
||||
== term);
|
||||
if_assert_failed {}
|
||||
|
||||
JS_SetPrivate(smjs_ctx, term->session_array_jsobject, NULL);
|
||||
JS_SetPrivate(term->session_array_jsobject, NULL);
|
||||
term->session_array_jsobject = NULL;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
smjs_session_goto_url(JSContext *ctx, uintN argc, jsval *rval)
|
||||
smjs_session_goto_url(JSContext *ctx, unsigned int argc, jsval *rval)
|
||||
{
|
||||
jsval val;
|
||||
struct delayed_open *deo;
|
||||
|
@ -30,8 +30,11 @@ static const JSPropertySpec terminal_props[] = {
|
||||
|
||||
/* @terminal_class.getProperty */
|
||||
static JSBool
|
||||
terminal_get_property(JSContext *ctx, JSObject *obj, jsid id, jsval *vp)
|
||||
terminal_get_property(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSMutableHandleValue hvp)
|
||||
{
|
||||
ELINKS_CAST_PROP_PARAMS
|
||||
jsid id = *(hid._);
|
||||
|
||||
struct terminal *term;
|
||||
|
||||
/* This can be called if @obj if not itself an instance of the
|
||||
@ -68,19 +71,18 @@ terminal_get_property(JSContext *ctx, JSObject *obj, jsid id, jsval *vp)
|
||||
* finalizes all objects before it frees the JSRuntime, so terminal.jsobject
|
||||
* won't be left dangling. */
|
||||
static void
|
||||
terminal_finalize(JSContext *ctx, JSObject *obj)
|
||||
terminal_finalize(JSFreeOp *op, JSObject *obj)
|
||||
{
|
||||
struct terminal *term;
|
||||
|
||||
#if 0
|
||||
assert(JS_InstanceOf(ctx, obj, (JSClass *) &terminal_class, NULL));
|
||||
if_assert_failed return;
|
||||
|
||||
term = JS_GetInstancePrivate(ctx, obj,
|
||||
(JSClass *) &terminal_class, NULL);
|
||||
#endif
|
||||
term = JS_GetPrivate(obj);
|
||||
|
||||
if (!term) return; /* already detached */
|
||||
|
||||
JS_SetPrivate(ctx, obj, NULL); /* perhaps not necessary */
|
||||
JS_SetPrivate(obj, NULL); /* perhaps not necessary */
|
||||
assert(term->jsobject == obj);
|
||||
if_assert_failed return;
|
||||
term->jsobject = NULL;
|
||||
@ -118,8 +120,7 @@ smjs_get_terminal_object(struct terminal *term)
|
||||
/* Do this last, so that if any previous step fails, we can
|
||||
* just forget the object and its finalizer won't attempt to
|
||||
* access @cached. */
|
||||
if (JS_FALSE == JS_SetPrivate(smjs_ctx, obj, term)) /* to @terminal_class */
|
||||
return NULL;
|
||||
JS_SetPrivate(obj, term); /* to @terminal_class */
|
||||
|
||||
term->jsobject = obj;
|
||||
return obj;
|
||||
@ -145,15 +146,18 @@ smjs_detach_terminal_object(struct terminal *term)
|
||||
== term);
|
||||
if_assert_failed {}
|
||||
|
||||
JS_SetPrivate(smjs_ctx, term->jsobject, NULL);
|
||||
JS_SetPrivate(term->jsobject, NULL);
|
||||
term->jsobject = NULL;
|
||||
}
|
||||
|
||||
|
||||
/* @terminal_array_class.getProperty */
|
||||
static JSBool
|
||||
terminal_array_get_property(JSContext *ctx, JSObject *obj, jsid id, jsval *vp)
|
||||
terminal_array_get_property(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSMutableHandleValue hvp)
|
||||
{
|
||||
ELINKS_CAST_PROP_PARAMS
|
||||
jsid id = *(hid._);
|
||||
|
||||
int index;
|
||||
struct terminal *term;
|
||||
|
||||
@ -181,7 +185,7 @@ static const JSClass terminal_array_class = {
|
||||
0,
|
||||
JS_PropertyStub, JS_PropertyStub,
|
||||
terminal_array_get_property, JS_StrictPropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, NULL
|
||||
};
|
||||
|
||||
/** Return an SMJS object that scripts can use an array to get terminal
|
||||
|
@ -39,8 +39,11 @@ static const JSPropertySpec view_state_props[] = {
|
||||
|
||||
/* @view_state_class.getProperty */
|
||||
static JSBool
|
||||
view_state_get_property(JSContext *ctx, JSObject *obj, jsid id, jsval *vp)
|
||||
view_state_get_property(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSMutableHandleValue hvp)
|
||||
{
|
||||
ELINKS_CAST_PROP_PARAMS
|
||||
jsid id = *(hid._);
|
||||
|
||||
struct view_state *vs;
|
||||
|
||||
/* This can be called if @obj if not itself an instance of the
|
||||
@ -81,8 +84,11 @@ view_state_get_property(JSContext *ctx, JSObject *obj, jsid id, jsval *vp)
|
||||
|
||||
/* @view_state_class.setProperty */
|
||||
static JSBool
|
||||
view_state_set_property(JSContext *ctx, JSObject *obj, jsid id, JSBool strict, jsval *vp)
|
||||
view_state_set_property(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSBool strict, JSMutableHandleValue hvp)
|
||||
{
|
||||
ELINKS_CAST_PROP_PARAMS
|
||||
jsid id = *(hid._);
|
||||
|
||||
struct view_state *vs;
|
||||
|
||||
/* This can be called if @obj if not itself an instance of the
|
||||
@ -117,19 +123,22 @@ view_state_set_property(JSContext *ctx, JSObject *obj, jsid id, JSBool strict, j
|
||||
* finalizes all objects before it frees the JSRuntime, so view_state.jsobject
|
||||
* won't be left dangling. */
|
||||
static void
|
||||
view_state_finalize(JSContext *ctx, JSObject *obj)
|
||||
view_state_finalize(JSFreeOp *op, JSObject *obj)
|
||||
{
|
||||
struct view_state *vs;
|
||||
|
||||
#if 0
|
||||
assert(JS_InstanceOf(ctx, obj, (JSClass *) &view_state_class, NULL));
|
||||
if_assert_failed return;
|
||||
|
||||
vs = JS_GetInstancePrivate(ctx, obj,
|
||||
(JSClass *) &view_state_class, NULL);
|
||||
#endif
|
||||
|
||||
vs = JS_GetPrivate(obj);
|
||||
|
||||
if (!vs) return; /* already detached */
|
||||
|
||||
JS_SetPrivate(ctx, obj, NULL); /* perhaps not necessary */
|
||||
JS_SetPrivate(obj, NULL); /* perhaps not necessary */
|
||||
assert(vs->jsobject == obj);
|
||||
if_assert_failed return;
|
||||
vs->jsobject = NULL;
|
||||
@ -168,16 +177,18 @@ smjs_get_view_state_object(struct view_state *vs)
|
||||
/* Do this last, so that if any previous step fails, we can
|
||||
* just forget the object and its finalizer won't attempt to
|
||||
* access @vs. */
|
||||
if (JS_FALSE == JS_SetPrivate(smjs_ctx, view_state_object, vs)) /* to @view_state_class */
|
||||
return NULL;
|
||||
JS_SetPrivate(view_state_object, vs); /* to @view_state_class */
|
||||
|
||||
vs->jsobject = view_state_object;
|
||||
return view_state_object;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
smjs_elinks_get_view_state(JSContext *ctx, JSObject *obj, jsid id, jsval *vp)
|
||||
smjs_elinks_get_view_state(JSContext *ctx, JSHandleObject hobj, JSHandleId hid, JSMutableHandleValue hvp)
|
||||
{
|
||||
ELINKS_CAST_PROP_PARAMS
|
||||
(void)obj;
|
||||
|
||||
JSObject *vs_obj;
|
||||
struct view_state *vs;
|
||||
|
||||
@ -214,7 +225,7 @@ smjs_detach_view_state_object(struct view_state *vs)
|
||||
== vs);
|
||||
if_assert_failed {}
|
||||
|
||||
JS_SetPrivate(smjs_ctx, vs->jsobject, NULL);
|
||||
JS_SetPrivate(vs->jsobject, NULL);
|
||||
vs->jsobject = NULL;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
<p><a href="javascript:document.title = 'This is a test'; document.title += ', this document URL is '+document.url;void(0);">Change the document.title while preventing going anywhere because returning <code>undefined</code>.</a></p>
|
||||
|
||||
<p><a href="javascript:document.url='elinks.or.cz';">Change the document.url</a> (which is impossible because it's read-only, but the return value of the statement is used as the link target so it magically still works).</p>
|
||||
<p><a href="javascript:document.url='http://elinks.or.cz';">Change the document.url</a> (which is impossible because it's read-only, but the return value of the statement is used as the link target so it magically still works).</p>
|
||||
|
||||
<p><a href="javascript:{ document.title = 'This is a test'; document.title += ', this document URL is '+document.url; 'elinks.or.cz' }">Change the document.title and go to elinks.or.cz (return value of statement).</a></p>
|
||||
<p><a href="javascript:{ document.title = 'This is a test'; document.title += ', this document URL is '+document.url; 'http://elinks.or.cz' }">Change the document.title and go to elinks.or.cz (return value of statement).</a></p>
|
||||
|
Loading…
Reference in New Issue
Block a user