1
0
Fork 0

Changed ecmascript engine to mozjs-17.0.

Was not tested, especially smjs is likely buggy.
This commit is contained in:
Witold Filipczyk 2019-02-10 21:00:37 +01:00
parent 9cebc108fd
commit 25dd2ecae9
30 changed files with 3588 additions and 1094 deletions

View File

@ -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.

View File

@ -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,

View File

@ -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

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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);

View File

@ -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);
}

View File

@ -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);

View File

@ -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);

View File

@ -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;
}

View File

@ -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

View File

@ -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
};