diff --git a/contrib/smjs/google_video.js b/contrib/smjs/google_video.js index f267941f..46b5ee19 100644 --- a/contrib/smjs/google_video.js +++ b/contrib/smjs/google_video.js @@ -1,7 +1,7 @@ /* Play videos at video.google.com with minimal niggling. Just follow the link * from the front page or the search page, and the video will automatically * be loaded. */ -function load_google_video(cached) { +function load_google_video(cached, vs) { if (!cached.uri.match(/^http:\/\/video.google.com\/videoplay/)) return true; diff --git a/contrib/smjs/hooks.js b/contrib/smjs/hooks.js index 875904d3..0278e46f 100644 --- a/contrib/smjs/hooks.js +++ b/contrib/smjs/hooks.js @@ -8,9 +8,9 @@ elinks.keymaps.main["@"] = function () { }; elinks.preformat_html_hooks = new Array(); -elinks.preformat_html = function (cached) { +elinks.preformat_html = function (cached, vs) { for (var i in elinks.preformat_html_hooks) - if (!elinks.preformat_html_hooks[i](cached)) + if (!elinks.preformat_html_hooks[i](cached, vs)) return false; return true; @@ -36,13 +36,13 @@ elinks.follow_url_hook = function (url) { return url; }; -function root_w00t(cached) { +function root_w00t(cached, vs) { cached.content = cached.content.replace(/root/g, "w00t"); return true; }; elinks.preformat_html_hooks.push(root_w00t); -function mangle_deb_bugnumbers(cached) { +function mangle_deb_bugnumbers(cached, vs) { if (!cached.uri.match(/^[a-z0-9]+:\/\/[a-z0-9A-Z.-]+debian\.org/) && !cached.uri.match(/changelog\.Debian/)) return true; @@ -55,7 +55,14 @@ function mangle_deb_bugnumbers(cached) { /* Debian Policy Manual 4.4 footnote 16 */ var closes_re = /closes:\s*(?:bug)?\#?\s?\d+(?:,\s*(?:bug)?\#?\s?\d+)*/gi; - cached.content = cached.content.replace(closes_re, rewrite_closes_fn); + var new_content = cached.content.replace(closes_re, rewrite_closes_fn); + if (cached.content_type == 'text/plain') { + cached.content = '
' + new_content + '
'; + vs.plain = "0"; + } else { + cached.content = new_content; + } + return true; } diff --git a/src/scripting/smjs/Makefile b/src/scripting/smjs/Makefile index 7ff12a14..1689f478 100644 --- a/src/scripting/smjs/Makefile +++ b/src/scripting/smjs/Makefile @@ -4,6 +4,6 @@ include $(top_builddir)/Makefile.config INCLUDES += $(SPIDERMONKEY_CFLAGS) OBJS = smjs.o core.o global_object.o hooks.o elinks_object.o cache_object.o \ - bookmarks.o keybinding.o + view_state_object.o bookmarks.o keybinding.o include $(top_srcdir)/Makefile.lib diff --git a/src/scripting/smjs/hooks.c b/src/scripting/smjs/hooks.c index 91a768a4..03097ef0 100644 --- a/src/scripting/smjs/hooks.c +++ b/src/scripting/smjs/hooks.c @@ -12,10 +12,13 @@ #include "main/event.h" #include "main/module.h" #include "scripting/smjs/cache_object.h" +#include "scripting/smjs/view_state_object.h" #include "scripting/smjs/core.h" #include "scripting/smjs/elinks_object.h" #include "scripting/smjs/hooks.h" +#include "session/location.h" #include "session/session.h" +#include "viewer/text/vs.h" static enum evhook_status @@ -88,8 +91,8 @@ script_hook_pre_format_html(va_list ap, void *data) struct session *ses = va_arg(ap, struct session *); struct cache_entry *cached = va_arg(ap, struct cache_entry *); enum evhook_status ret = EVENT_HOOK_STATUS_NEXT; - JSObject *cache_entry_object; - jsval args[1], rval; + JSObject *cache_entry_object, *view_state_object = JSVAL_NULL; + jsval args[2], rval; evhook_use_params(ses && cached); @@ -97,13 +100,20 @@ script_hook_pre_format_html(va_list ap, void *data) smjs_ses = ses; + if (have_location(ses)) { + struct view_state *vs = &cur_loc(ses)->vs; + + view_state_object = smjs_get_view_state_object(vs); + } + cache_entry_object = smjs_get_cache_entry_object(cached); if (!cache_entry_object) goto end; args[0] = OBJECT_TO_JSVAL(cache_entry_object); + args[1] = OBJECT_TO_JSVAL(view_state_object); if (JS_TRUE == smjs_invoke_elinks_object_method("preformat_html", - args, 1, &rval)) + args, 2, &rval)) if (JS_FALSE == JSVAL_TO_BOOLEAN(rval)) ret = EVENT_HOOK_STATUS_LAST; diff --git a/src/scripting/smjs/view_state_object.c b/src/scripting/smjs/view_state_object.c new file mode 100644 index 00000000..a40457e7 --- /dev/null +++ b/src/scripting/smjs/view_state_object.c @@ -0,0 +1,109 @@ +/* Exports struct view_state to the world of ECMAScript */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include "elinks.h" + +#include "ecmascript/spidermonkey/util.h" +#include "protocol/uri.h" +#include "scripting/smjs/view_state_object.h" +#include "scripting/smjs/core.h" +#include "util/error.h" +#include "util/memory.h" +#include "viewer/text/vs.h" + +enum view_state_prop { + VIEW_STATE_PLAIN, + VIEW_STATE_URI, +}; + +static const JSPropertySpec view_state_props[] = { + { "plain", VIEW_STATE_PLAIN, JSPROP_ENUMERATE }, + { "uri", VIEW_STATE_URI, JSPROP_ENUMERATE | JSPROP_READONLY }, + { NULL } +}; + +static JSBool +view_state_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) +{ + struct view_state *vs = JS_GetPrivate(ctx, obj); + + undef_to_jsval(ctx, vp); + + if (!JSVAL_IS_INT(id)) + return JS_FALSE; + + switch (JSVAL_TO_INT(id)) { + case VIEW_STATE_PLAIN: + *vp = INT_TO_JSVAL(vs->plain); + + return JS_TRUE; + case VIEW_STATE_URI: + *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(smjs_ctx, + struri(vs->uri))); + + return JS_TRUE; + default: + INTERNAL("Invalid ID %d in view_state_get_property().", + JSVAL_TO_INT(id)); + } + + return JS_FALSE; +} + +static JSBool +view_state_set_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) +{ + struct view_state *vs = JS_GetPrivate(ctx, obj); + + if (!JSVAL_IS_INT(id)) + return JS_FALSE; + + switch (JSVAL_TO_INT(id)) { + case VIEW_STATE_PLAIN: { + vs->plain = atol(jsval_to_string(ctx, vp)); + + return JS_TRUE; + } + default: + INTERNAL("Invalid ID %d in view_state_set_property().", + JSVAL_TO_INT(id)); + } + + return JS_FALSE; +} + +static const JSClass view_state_class = { + "view_state", + JSCLASS_HAS_PRIVATE, + JS_PropertyStub, JS_PropertyStub, + view_state_get_property, view_state_set_property, + JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub +}; + +JSObject * +smjs_get_view_state_object(struct view_state *vs) +{ + JSObject *view_state_object; + + assert(smjs_ctx); + + view_state_object = JS_NewObject(smjs_ctx, + (JSClass *) &view_state_class, + NULL, NULL); + + if (!view_state_object) return NULL; + + if (JS_FALSE == JS_SetPrivate(smjs_ctx, view_state_object, vs)) + return NULL; + + if (JS_FALSE == JS_DefineProperties(smjs_ctx, view_state_object, + (JSPropertySpec *) view_state_props)) + return NULL; + + return view_state_object; +} diff --git a/src/scripting/smjs/view_state_object.h b/src/scripting/smjs/view_state_object.h new file mode 100644 index 00000000..daf770eb --- /dev/null +++ b/src/scripting/smjs/view_state_object.h @@ -0,0 +1,9 @@ +#ifndef EL__SCRIPTING_SMJS_VIEW_STATE_OBJECT_H +#define EL__SCRIPTING_SMJS_VIEW_STATE_OBJECT_H + +struct view_state; + +JSObject *smjs_get_view_state_object(struct view_state *vs); + +#endif +