From 4375984708d76f9fbf2fce4c9d5dbc977588a024 Mon Sep 17 00:00:00 2001 From: Witold Filipczyk Date: Mon, 25 Sep 2023 10:52:19 +0200 Subject: [PATCH] [js] Distinguish between document.write(ln) and other modifications Reparse document only for document.write(ln). --- src/ecmascript/ecmascript.cpp | 7 ++--- src/ecmascript/ecmascript.h | 3 ++- src/ecmascript/libdom/mujs/document.c | 3 ++- src/ecmascript/libdom/mujs/element.c | 26 +++++++++---------- src/ecmascript/libdom/mujs/style.c | 2 +- src/ecmascript/libdom/quickjs/document.c | 3 ++- src/ecmascript/libdom/quickjs/element.c | 26 +++++++++---------- src/ecmascript/libdom/quickjs/style.c | 2 +- .../libdom/spidermonkey/document.cpp | 3 ++- .../libdom/spidermonkey/element.cpp | 26 +++++++++---------- src/ecmascript/libdom/spidermonkey/style.cpp | 2 +- src/session/session.h | 1 + 12 files changed, 55 insertions(+), 49 deletions(-) diff --git a/src/ecmascript/ecmascript.cpp b/src/ecmascript/ecmascript.cpp index 6cdd51fa4..8f0a4e1dd 100644 --- a/src/ecmascript/ecmascript.cpp +++ b/src/ecmascript/ecmascript.cpp @@ -312,7 +312,7 @@ delayed_reload(void *data) assert(rel); reset_document(rel->document); - dump_xhtml(rel->cached, rel->document, 1); + dump_xhtml(rel->cached, rel->document, rel->was_write); sort_links(rel->document); draw_formatted(rel->ses, 0); mem_free(rel); @@ -355,17 +355,18 @@ check_for_rerender(struct ecmascript_interpreter *interpreter, const char* text) //fprintf(stderr, "%s\n", text); if (document->dom) { - interpreter->changed = false; - struct delayed_rel *rel = (struct delayed_rel *)mem_calloc(1, sizeof(*rel)); if (rel) { rel->cached = cached; rel->document = document; rel->ses = ses; + rel->was_write = interpreter->was_write; object_lock(document); register_bottom_half(delayed_reload, rel); } + interpreter->changed = 0; + interpreter->was_write = 0; } } } diff --git a/src/ecmascript/ecmascript.h b/src/ecmascript/ecmascript.h index 7cb819a0f..d887c4a43 100644 --- a/src/ecmascript/ecmascript.h +++ b/src/ecmascript/ecmascript.h @@ -110,8 +110,9 @@ struct ecmascript_interpreter { #ifdef CONFIG_MUJS const char *fun; #endif - bool changed; int element_offset; + unsigned int changed:1; + unsigned int was_write:1; }; struct ecmascript_timeout { diff --git a/src/ecmascript/libdom/mujs/document.c b/src/ecmascript/libdom/mujs/document.c index 418393ee3..289c5b103 100644 --- a/src/ecmascript/libdom/mujs/document.c +++ b/src/ecmascript/libdom/mujs/document.c @@ -786,7 +786,8 @@ mjs_document_write_do(js_State *J, int newline) done_string(&string); interpreter->current_writecode = interpreter->current_writecode->next; } - interpreter->changed = true; + interpreter->changed = 1; + interpreter->was_write = 1; } } diff --git a/src/ecmascript/libdom/mujs/element.c b/src/ecmascript/libdom/mujs/element.c index d89f51b66..4bf7b3d94 100644 --- a/src/ecmascript/libdom/mujs/element.c +++ b/src/ecmascript/libdom/mujs/element.c @@ -1137,7 +1137,7 @@ mjs_element_set_property_className(js_State *J) if (exc == DOM_NO_ERR && classstr) { exc = dom_element_set_attribute(el, corestring_dom_class, classstr); - interpreter->changed = true; + interpreter->changed = 1; dom_string_unref(classstr); } js_pushundefined(J); @@ -1170,7 +1170,7 @@ mjs_element_set_property_dir(js_State *J) if (exc == DOM_NO_ERR && dir) { exc = dom_element_set_attribute(el, corestring_dom_dir, dir); - interpreter->changed = true; + interpreter->changed = 1; dom_string_unref(dir); } } @@ -1202,7 +1202,7 @@ mjs_element_set_property_id(js_State *J) if (exc == DOM_NO_ERR && idstr) { exc = dom_element_set_attribute(el, corestring_dom_id, idstr); - interpreter->changed = true; + interpreter->changed = 1; dom_string_unref(idstr); } js_pushundefined(J); @@ -1337,7 +1337,7 @@ out: if (body != NULL) { dom_node_unref(body); } - interpreter->changed = true; + interpreter->changed = 1; js_pushundefined(J); } @@ -1365,7 +1365,7 @@ mjs_element_set_property_innerText(js_State *J) xmlpp::Node::remove_node(*it); } el->add_child_text(val); - interpreter->changed = true; + interpreter->changed = 1; #endif js_pushundefined(J); } @@ -1395,7 +1395,7 @@ mjs_element_set_property_lang(js_State *J) if (exc == DOM_NO_ERR && langstr) { exc = dom_element_set_attribute(el, corestring_dom_lang, langstr); - interpreter->changed = true; + interpreter->changed = 1; dom_string_unref(langstr); } js_pushundefined(J); @@ -1427,7 +1427,7 @@ mjs_element_set_property_title(js_State *J) if (exc == DOM_NO_ERR && titlestr) { exc = dom_element_set_attribute(el, corestring_dom_title, titlestr); - interpreter->changed = true; + interpreter->changed = 1; dom_string_unref(titlestr); } js_pushundefined(J); @@ -1675,7 +1675,7 @@ mjs_element_appendChild(js_State *J) exc = dom_node_append_child(el, el2, &res); if (exc == DOM_NO_ERR && res) { - interpreter->changed = true; + interpreter->changed = 1; mjs_push_element(J, res); return; } @@ -2142,7 +2142,7 @@ mjs_element_insertBefore(js_State *J) js_pushundefined(J); return; } - interpreter->changed = true; + interpreter->changed = 1; mjs_push_element(J, spare); } @@ -2329,7 +2329,7 @@ mjs_element_remove(js_State *J) return; } xmlpp::Node::remove_node(el); - interpreter->changed = true; + interpreter->changed = 1; #endif js_pushundefined(J); } @@ -2348,7 +2348,7 @@ mjs_element_removeChild(js_State *J) exc = dom_node_remove_child(el, el2, &spare); if (exc == DOM_NO_ERR && spare) { - interpreter->changed = true; + interpreter->changed = 1; mjs_push_element(J, spare); return; } @@ -2375,7 +2375,7 @@ mjs_element_replaceWith(js_State *J) auto n = xmlAddPrevSibling(el->cobj(), rep->cobj()); xmlpp::Node::create_wrapper(n); xmlpp::Node::remove_node(el); - interpreter->changed = true; + interpreter->changed = 1; #endif js_pushundefined(J); } @@ -2433,7 +2433,7 @@ mjs_element_setAttribute(js_State *J) js_pushundefined(J); return; } - interpreter->changed = true; + interpreter->changed = 1; js_pushundefined(J); } diff --git a/src/ecmascript/libdom/mujs/style.c b/src/ecmascript/libdom/mujs/style.c index bd5329040..8a7446ac6 100644 --- a/src/ecmascript/libdom/mujs/style.c +++ b/src/ecmascript/libdom/mujs/style.c @@ -106,7 +106,7 @@ mjs_set_style(js_State *J, const char *property) if (exc == DOM_NO_ERR && stylestr) { exc = dom_element_set_attribute(el, corestring_dom_style, stylestr); - interpreter->changed = true; + interpreter->changed = 1; dom_string_unref(stylestr); } mem_free(res); diff --git a/src/ecmascript/libdom/quickjs/document.c b/src/ecmascript/libdom/quickjs/document.c index f7610c6c0..2d6aea6d5 100644 --- a/src/ecmascript/libdom/quickjs/document.c +++ b/src/ecmascript/libdom/quickjs/document.c @@ -862,7 +862,8 @@ js_document_write_do(JSContext *ctx, JSValueConst this_val, int argc, JSValueCon done_string(&string); interpreter->current_writecode = interpreter->current_writecode->next; } - interpreter->changed = true; + interpreter->changed = 1; + interpreter->was_write = 1; } } diff --git a/src/ecmascript/libdom/quickjs/element.c b/src/ecmascript/libdom/quickjs/element.c index f70db18ab..591de0064 100644 --- a/src/ecmascript/libdom/quickjs/element.c +++ b/src/ecmascript/libdom/quickjs/element.c @@ -1164,7 +1164,7 @@ js_element_set_property_className(JSContext *ctx, JSValueConst this_val, JSValue if (exc == DOM_NO_ERR && classstr) { exc = dom_element_set_attribute(el, corestring_dom_class, classstr); - interpreter->changed = true; + interpreter->changed = 1; dom_string_unref(classstr); } JS_FreeCString(ctx, str); @@ -1200,7 +1200,7 @@ js_element_set_property_dir(JSContext *ctx, JSValueConst this_val, JSValue val) if (exc == DOM_NO_ERR && dir) { exc = dom_element_set_attribute(el, corestring_dom_dir, dir); - interpreter->changed = true; + interpreter->changed = 1; dom_string_unref(dir); } } @@ -1236,7 +1236,7 @@ js_element_set_property_id(JSContext *ctx, JSValueConst this_val, JSValue val) if (exc == DOM_NO_ERR && idstr) { exc = dom_element_set_attribute(el, corestring_dom_id, idstr); - interpreter->changed = true; + interpreter->changed = 1; dom_string_unref(idstr); } JS_FreeCString(ctx, str); @@ -1377,7 +1377,7 @@ out: dom_node_unref(body); } JS_FreeCString(ctx, s); - interpreter->changed = true; + interpreter->changed = 1; return JS_UNDEFINED; } @@ -1413,7 +1413,7 @@ js_element_set_property_innerText(JSContext *ctx, JSValueConst this_val, JSValue return JS_EXCEPTION; } el->add_child_text(str); - interpreter->changed = true; + interpreter->changed = 1; JS_FreeCString(ctx, str); #endif @@ -1447,7 +1447,7 @@ js_element_set_property_lang(JSContext *ctx, JSValueConst this_val, JSValue val) if (exc == DOM_NO_ERR && langstr) { exc = dom_element_set_attribute(el, corestring_dom_lang, langstr); - interpreter->changed = true; + interpreter->changed = 1; dom_string_unref(langstr); } JS_FreeCString(ctx, str); @@ -1482,7 +1482,7 @@ js_element_set_property_title(JSContext *ctx, JSValueConst this_val, JSValue val if (exc == DOM_NO_ERR && titlestr) { exc = dom_element_set_attribute(el, corestring_dom_title, titlestr); - interpreter->changed = true; + interpreter->changed = 1; dom_string_unref(titlestr); } JS_FreeCString(ctx, str); @@ -1743,7 +1743,7 @@ js_element_appendChild(JSContext *ctx, JSValueConst this_val, int argc, JSValueC exc = dom_node_append_child(el, el2, &res); if (exc == DOM_NO_ERR && res) { - interpreter->changed = true; + interpreter->changed = 1; return getElement(ctx, res); } @@ -2288,7 +2288,7 @@ js_element_insertBefore(JSContext *ctx, JSValueConst this_val, int argc, JSValue if (err != DOM_NO_ERR) { return JS_UNDEFINED; } - interpreter->changed = true; + interpreter->changed = 1; return getElement(ctx, spare); } @@ -2538,7 +2538,7 @@ js_element_remove(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst } xmlpp::Node::remove_node(el); - interpreter->changed = true; + interpreter->changed = 1; #endif return JS_UNDEFINED; @@ -2571,7 +2571,7 @@ js_element_removeChild(JSContext *ctx, JSValueConst this_val, int argc, JSValueC exc = dom_node_remove_child(el, el2, &spare); if (exc == DOM_NO_ERR && spare) { - interpreter->changed = true; + interpreter->changed = 1; return getElement(ctx, spare); } @@ -2607,7 +2607,7 @@ js_element_replaceWith(JSContext *ctx, JSValueConst this_val, int argc, JSValueC auto n = xmlAddPrevSibling(el->cobj(), rep->cobj()); xmlpp::Node::create_wrapper(n); xmlpp::Node::remove_node(el); - interpreter->changed = true; + interpreter->changed = 1; #endif return JS_UNDEFINED; @@ -2672,7 +2672,7 @@ js_element_setAttribute(JSContext *ctx, JSValueConst this_val, int argc, JSValue if (exc != DOM_NO_ERR) { return JS_UNDEFINED; } - interpreter->changed = true; + interpreter->changed = 1; return JS_UNDEFINED; } diff --git a/src/ecmascript/libdom/quickjs/style.c b/src/ecmascript/libdom/quickjs/style.c index dd8f4edca..42b360f14 100644 --- a/src/ecmascript/libdom/quickjs/style.c +++ b/src/ecmascript/libdom/quickjs/style.c @@ -110,7 +110,7 @@ js_set_style(JSContext *ctx, JSValueConst this_val, JSValue val, const char *pro if (exc == DOM_NO_ERR && stylestr) { exc = dom_element_set_attribute(el, corestring_dom_style, stylestr); - interpreter->changed = true; + interpreter->changed = 1; dom_string_unref(stylestr); } mem_free(res); diff --git a/src/ecmascript/libdom/spidermonkey/document.cpp b/src/ecmascript/libdom/spidermonkey/document.cpp index 1ae2e5831..edf57f0b3 100644 --- a/src/ecmascript/libdom/spidermonkey/document.cpp +++ b/src/ecmascript/libdom/spidermonkey/document.cpp @@ -1172,7 +1172,8 @@ document_write_do(JSContext *ctx, unsigned int argc, JS::Value *rval, int newlin done_string(&string); interpreter->current_writecode = interpreter->current_writecode->next; } - interpreter->changed = true; + interpreter->changed = 1; + interpreter->was_write = 1; } } diff --git a/src/ecmascript/libdom/spidermonkey/element.cpp b/src/ecmascript/libdom/spidermonkey/element.cpp index d7ad26356..e39331777 100644 --- a/src/ecmascript/libdom/spidermonkey/element.cpp +++ b/src/ecmascript/libdom/spidermonkey/element.cpp @@ -2266,7 +2266,7 @@ element_set_property_className(JSContext *ctx, unsigned int argc, JS::Value *vp) if (exc == DOM_NO_ERR && classstr) { exc = dom_element_set_attribute(el, corestring_dom_class, classstr); - interpreter->changed = true; + interpreter->changed = 1; dom_string_unref(classstr); } mem_free(str); @@ -2328,7 +2328,7 @@ element_set_property_dir(JSContext *ctx, unsigned int argc, JS::Value *vp) if (exc == DOM_NO_ERR && dir) { exc = dom_element_set_attribute(el, corestring_dom_dir, dir); - interpreter->changed = true; + interpreter->changed = 1; dom_string_unref(dir); } } @@ -2390,7 +2390,7 @@ element_set_property_id(JSContext *ctx, unsigned int argc, JS::Value *vp) if (exc == DOM_NO_ERR && idstr) { exc = dom_element_set_attribute(el, corestring_dom_id, idstr); - interpreter->changed = true; + interpreter->changed = 1; dom_string_unref(idstr); } mem_free(str); @@ -2557,7 +2557,7 @@ out: dom_node_unref(body); } mem_free(s); - interpreter->changed = true; + interpreter->changed = 1; return true; } @@ -2615,7 +2615,7 @@ element_set_property_innerText(JSContext *ctx, unsigned int argc, JS::Value *vp) char *text = jsval_to_string(ctx, args[0]); el->add_child_text(text); - interpreter->changed = true; + interpreter->changed = 1; mem_free_if(text); #endif @@ -2674,7 +2674,7 @@ element_set_property_lang(JSContext *ctx, unsigned int argc, JS::Value *vp) if (exc == DOM_NO_ERR && langstr) { exc = dom_element_set_attribute(el, corestring_dom_lang, langstr); - interpreter->changed = true; + interpreter->changed = 1; dom_string_unref(langstr); } mem_free(str); @@ -2812,7 +2812,7 @@ element_set_property_title(JSContext *ctx, unsigned int argc, JS::Value *vp) if (exc == DOM_NO_ERR && titlestr) { exc = dom_element_set_attribute(el, corestring_dom_title, titlestr); - interpreter->changed = true; + interpreter->changed = 1; dom_string_unref(titlestr); } mem_free(str); @@ -3173,7 +3173,7 @@ element_appendChild(JSContext *ctx, unsigned int argc, JS::Value *rval) exc = dom_node_append_child(el, el2, &res); if (exc == DOM_NO_ERR && res) { - interpreter->changed = true; + interpreter->changed = 1; JSObject *obj = getElement(ctx, res); args.rval().setObject(*obj); return true; @@ -3894,7 +3894,7 @@ element_insertBefore(JSContext *ctx, unsigned int argc, JS::Value *rval) } JSObject *obj = getElement(ctx, spare); args.rval().setObject(*obj); - interpreter->changed = true; + interpreter->changed = 1; return true; } @@ -4219,7 +4219,7 @@ element_remove(JSContext *ctx, unsigned int argc, JS::Value *rval) } xmlpp::Node::remove_node(el); - interpreter->changed = true; + interpreter->changed = 1; #endif return true; } @@ -4263,7 +4263,7 @@ element_removeChild(JSContext *ctx, unsigned int argc, JS::Value *rval) exc = dom_node_remove_child(el, el2, &spare); if (exc == DOM_NO_ERR && spare) { - interpreter->changed = true; + interpreter->changed = 1; JSObject *obj = getElement(ctx, spare); args.rval().setObject(*obj); return true; @@ -4314,7 +4314,7 @@ element_replaceWith(JSContext *ctx, unsigned int argc, JS::Value *rval) auto n = xmlAddPrevSibling(el->cobj(), rep->cobj()); xmlpp::Node::create_wrapper(n); xmlpp::Node::remove_node(el); - interpreter->changed = true; + interpreter->changed = 1; args.rval().setUndefined(); #endif return true; @@ -4393,7 +4393,7 @@ element_setAttribute(JSContext *ctx, unsigned int argc, JS::Value *rval) if (exc != DOM_NO_ERR) { return true; } - interpreter->changed = true; + interpreter->changed = 1; return true; } diff --git a/src/ecmascript/libdom/spidermonkey/style.cpp b/src/ecmascript/libdom/spidermonkey/style.cpp index f8bd596cf..6e1611817 100644 --- a/src/ecmascript/libdom/spidermonkey/style.cpp +++ b/src/ecmascript/libdom/spidermonkey/style.cpp @@ -576,7 +576,7 @@ style_set_style(JSContext *ctx, unsigned int argc, JS::Value *vp, const char *pr if (exc == DOM_NO_ERR && stylestr) { exc = dom_element_set_attribute(el, corestring_dom_style, stylestr); - interpreter->changed = true; + interpreter->changed = 1; dom_string_unref(stylestr); } mem_free(res); diff --git a/src/session/session.h b/src/session/session.h index 7897f03af..bdfec0d9e 100644 --- a/src/session/session.h +++ b/src/session/session.h @@ -37,6 +37,7 @@ struct delayed_rel { struct cache_entry *cached; struct document *document; struct session *ses; + int was_write; }; enum remote_session_flags {