diff --git a/src/ecmascript/ecmascript.h b/src/ecmascript/ecmascript.h index 74072645..d1e57ed7 100644 --- a/src/ecmascript/ecmascript.h +++ b/src/ecmascript/ecmascript.h @@ -65,6 +65,7 @@ struct ecmascript_interpreter { void *ar; void *document_obj; JS::RootedValue fun; + bool changed; }; /* Why is the interpreter bound to {struct view_state} instead of {struct diff --git a/src/ecmascript/spidermonkey.c b/src/ecmascript/spidermonkey.c index 03cb872b..5ac9cc07 100644 --- a/src/ecmascript/spidermonkey.c +++ b/src/ecmascript/spidermonkey.c @@ -52,8 +52,11 @@ #include "viewer/text/draw.h" #include "viewer/text/form.h" #include "viewer/text/link.h" +#include "viewer/text/view.h" #include "viewer/text/vs.h" +#include + /*** Global methods */ @@ -139,8 +142,6 @@ PrintError(JSContext* cx, FILE* file, JS::ConstUTF8CharsZ toStringResult, return true; } - - static void error_reporter(JSContext *ctx, JSErrorReport *report) { @@ -425,6 +426,53 @@ spidermonkey_check_for_exception(JSContext *ctx) { } +static void +delayed_reload(void *data) +{ + struct delayed_rel *rel = data; + + assert(rel); + doc_rerender_after_document_update(rel->ses); + mem_free(rel); +} + +static void +check_for_rerender(struct ecmascript_interpreter *interpreter) +{ + if (interpreter->changed) { + struct document_view *doc_view = interpreter->vs->doc_view; + struct document *document = doc_view->document; + struct session *ses = doc_view->session; + struct cache_entry *cached = document->cached; + struct fragment *f = get_cache_fragment(cached); + + if (document->dom && f && f->length) { + xmlpp::Document *docu = (xmlpp::Document *)document->dom; + std::string doc1_string = docu->write_to_string_formatted(); + //delete docu; + document->dom = NULL; + + size_t fd_len=f->length; + delete_entry_content(cached); + /* This is very ugly, indeed. And Yes fd_len isn't + * logically correct. But using nu_len will cause + * the document to render improperly. + * TBD: somehow better rerender the document + * now it's places on the session level in doc_loading_callback */ + int ret = add_fragment(cached, 0, doc1_string.c_str(), doc1_string.size()); + normalize_cache_entry(cached, doc1_string.size()); + document->ecmascript_counter++; + interpreter->changed = false; + + struct delayed_rel *rel = mem_calloc(1, sizeof(*rel)); + + if (rel) { + rel->ses = ses; + register_bottom_half(delayed_reload, rel); + } + } + } +} void spidermonkey_eval(struct ecmascript_interpreter *interpreter, @@ -455,6 +503,8 @@ spidermonkey_eval(struct ecmascript_interpreter *interpreter, done_heartbeat(interpreter->heartbeat); JS_LeaveCompartment(ctx, comp); JS_EndRequest(ctx); + + check_for_rerender(interpreter); } void @@ -481,6 +531,8 @@ spidermonkey_call_function(struct ecmascript_interpreter *interpreter, done_heartbeat(interpreter->heartbeat); JS_LeaveCompartment(ctx, comp); JS_EndRequest(ctx); + + check_for_rerender(interpreter); } @@ -525,6 +577,9 @@ spidermonkey_eval_stringback(struct ecmascript_interpreter *interpreter, } JS_LeaveCompartment(ctx, comp); JS_EndRequest(ctx); + + check_for_rerender(interpreter); + return result; } @@ -577,6 +632,8 @@ spidermonkey_eval_boolback(struct ecmascript_interpreter *interpreter, JS_LeaveCompartment(ctx, comp); JS_EndRequest(ctx); + check_for_rerender(interpreter); + return result; } diff --git a/src/ecmascript/spidermonkey/element.c b/src/ecmascript/spidermonkey/element.c index a75cbc68..ac44ef08 100644 --- a/src/ecmascript/spidermonkey/element.c +++ b/src/ecmascript/spidermonkey/element.c @@ -66,7 +66,7 @@ static bool element_get_property_firstElementChild(JSContext *ctx, unsigned int static bool element_get_property_id(JSContext *ctx, unsigned int argc, JS::Value *vp); static bool element_set_property_id(JSContext *ctx, unsigned int argc, JS::Value *vp); static bool element_get_property_innerHtml(JSContext *ctx, unsigned int argc, JS::Value *vp); -static bool element_set_property_innerHtml(JSContext *ctx, unsigned int argc, JS::Value *vp); +static bool element_set_property_innerText(JSContext *ctx, unsigned int argc, JS::Value *vp); static bool element_get_property_lang(JSContext *ctx, unsigned int argc, JS::Value *vp); static bool element_set_property_lang(JSContext *ctx, unsigned int argc, JS::Value *vp); static bool element_get_property_lastChild(JSContext *ctx, unsigned int argc, JS::Value *vp); @@ -109,7 +109,8 @@ JSPropertySpec element_props[] = { JS_PSG("firstChild", element_get_property_firstChild, JSPROP_ENUMERATE), JS_PSG("firstElementChild", element_get_property_firstElementChild, JSPROP_ENUMERATE), JS_PSGS("id", element_get_property_id, element_set_property_id, JSPROP_ENUMERATE), - JS_PSGS("innerHTML", element_get_property_innerHtml, element_set_property_innerHtml, JSPROP_ENUMERATE), + JS_PSGS("innerHTML", element_get_property_innerHtml, element_set_property_innerText, JSPROP_ENUMERATE), + JS_PSGS("innerText", element_get_property_innerHtml, element_set_property_innerText, JSPROP_ENUMERATE), JS_PSGS("lang", element_get_property_lang, element_set_property_lang, JSPROP_ENUMERATE), JS_PSG("lastChild", element_get_property_lastChild, JSPROP_ENUMERATE), JS_PSG("lastElementChild", element_get_property_lastElementChild, JSPROP_ENUMERATE), @@ -1472,7 +1473,7 @@ element_set_property_id(JSContext *ctx, unsigned int argc, JS::Value *vp) } static bool -element_set_property_innerHtml(JSContext *ctx, unsigned int argc, JS::Value *vp) +element_set_property_innerText(JSContext *ctx, unsigned int argc, JS::Value *vp) { JS::CallArgs args = CallArgsFromVp(argc, vp); JS::RootedObject hobj(ctx, &args.thisv().toObject()); @@ -1510,6 +1511,7 @@ element_set_property_innerHtml(JSContext *ctx, unsigned int argc, JS::Value *vp) char *text = JS_EncodeString(ctx, args[0].toString()); el->add_child_text(text); + interpreter->changed = true; return true; } diff --git a/src/session/session.c b/src/session/session.c index e482ae37..3b756214 100644 --- a/src/session/session.c +++ b/src/session/session.c @@ -640,6 +640,7 @@ doc_rerender_after_document_update(struct session *ses) { ** how to display the final Javascript render ** taken from toggle_plain_html(ses, ses->doc_view, 0); ** This is toggled */ + assert(ses && ses->doc_view && ses->tab && ses->tab->term); if_assert_failed { diff --git a/src/session/session.h b/src/session/session.h index d6ff4529..29e9eabd 100644 --- a/src/session/session.h +++ b/src/session/session.h @@ -31,6 +31,10 @@ struct delayed_open { char *target; }; +struct delayed_rel { + struct session *ses; +}; + enum remote_session_flags { SES_REMOTE_NEW_TAB = 1, SES_REMOTE_NEW_WINDOW = 2, @@ -323,6 +327,10 @@ int set_kbd_repeat_count(struct session *ses, int new_count); void maybe_pre_format_html(struct cache_entry *cached, struct session *ses); #endif +#ifdef CONFIG_ECMASCRIPT +void doc_rerender_after_document_update(struct session *ses); +#endif + #ifdef __cplusplus } #endif