1
0
mirror of https://github.com/rkd77/elinks.git synced 2024-06-27 01:25:34 +00:00

[js] Test commit for "rerendering" of page after modifcation by scripts

This commit is contained in:
Witold Filipczyk 2021-06-05 21:58:29 +02:00
parent 80c1c7a278
commit 871d47bf41
5 changed files with 74 additions and 5 deletions

View File

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

View File

@ -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 <libxml++/libxml++.h>
/*** 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;
}

View File

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

View File

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

View File

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