From 764b0af2badeea4becffc17423807362713e046a Mon Sep 17 00:00:00 2001 From: Witold Filipczyk Date: Wed, 28 Dec 2022 21:05:59 +0100 Subject: [PATCH] [ecmascript] Rewritten document.write string list instead of single string. --- src/ecmascript/ecmascript.cpp | 27 +++++++++-------- src/ecmascript/ecmascript.h | 4 +-- src/ecmascript/spidermonkey/document.cpp | 38 +++++++++++++++--------- 3 files changed, 40 insertions(+), 29 deletions(-) diff --git a/src/ecmascript/ecmascript.cpp b/src/ecmascript/ecmascript.cpp index 6ff0ac79..19701e00 100644 --- a/src/ecmascript/ecmascript.cpp +++ b/src/ecmascript/ecmascript.cpp @@ -304,7 +304,8 @@ ecmascript_get_interpreter(struct view_state *vs) } (void)init_string(&interpreter->code); - (void)init_string(&interpreter->writecode); + init_list(interpreter->writecode); + interpreter->current_writecode = (struct ecmascript_string_list_item *)interpreter->writecode.next; return interpreter; } @@ -325,7 +326,7 @@ ecmascript_put_interpreter(struct ecmascript_interpreter *interpreter) #endif free_ecmascript_string_list(&interpreter->onload_snippets); done_string(&interpreter->code); - done_string(&interpreter->writecode); + free_ecmascript_string_list(&interpreter->writecode); /* Is it superfluous? */ if (interpreter->vs->doc_view) { struct ecmascript_timeout *t; @@ -374,12 +375,14 @@ check_for_rerender(struct ecmascript_interpreter *interpreter, const char* text) struct cache_entry *cached = document->cached; if (!strcmp(text, "eval")) { - if (interpreter->write_element_offset) { - if (interpreter->writecode.length) { + struct ecmascript_string_list_item *item; + + foreach(item, interpreter->writecode) { + if (item->string.length) { std::map *mapa = (std::map *)document->element_map; if (mapa) { - auto element = (*mapa).find(interpreter->write_element_offset); + auto element = (*mapa).find(item->element_offset); if (element != (*mapa).end()) { xmlpp::Element *el = element->second; @@ -389,7 +392,7 @@ check_for_rerender(struct ecmascript_interpreter *interpreter, const char* text) if (!parent) goto fromstart; xmlpp::ustring text = ""; - text += interpreter->writecode.source; + text += item->string.source; text += ""; xmlDoc* doc = htmlReadDoc((xmlChar*)text.c_str(), NULL, "utf-8", HTML_PARSE_RECOVER | HTML_PARSE_NOERROR | HTML_PARSE_NOWARNING); @@ -406,16 +409,14 @@ check_for_rerender(struct ecmascript_interpreter *interpreter, const char* text) xmlpp::Node::create_wrapper(n); } xmlpp::Node::remove_node(el); + } else { +fromstart: + add_fragment(cached, 0, item->string.source, item->string.length); + document->ecmascript_counter++; + break; } } } - interpreter->write_element_offset = 0; - } else { - if (interpreter->writecode.length) { -fromstart: - add_fragment(cached, 0, interpreter->writecode.source, interpreter->writecode.length); - document->ecmascript_counter++; - } } } diff --git a/src/ecmascript/ecmascript.h b/src/ecmascript/ecmascript.h index 3aae9cac..f627a723 100644 --- a/src/ecmascript/ecmascript.h +++ b/src/ecmascript/ecmascript.h @@ -67,7 +67,8 @@ struct ecmascript_interpreter { struct string code; /* document.write buffer */ - struct string writecode; + LIST_OF(struct ecmascript_string_list_item) writecode; + struct ecmascript_string_list_item *current_writecode; struct heartbeat *heartbeat; @@ -110,7 +111,6 @@ struct ecmascript_interpreter { #endif bool changed; int element_offset; - int write_element_offset; }; struct ecmascript_timeout { diff --git a/src/ecmascript/spidermonkey/document.cpp b/src/ecmascript/spidermonkey/document.cpp index bd2dea5e..59114c93 100644 --- a/src/ecmascript/spidermonkey/document.cpp +++ b/src/ecmascript/spidermonkey/document.cpp @@ -1305,25 +1305,35 @@ document_write_do(JSContext *ctx, unsigned int argc, JS::Value *rval, int newlin struct ecmascript_interpreter *interpreter = (struct ecmascript_interpreter *)JS::GetRealmPrivate(comp); JS::CallArgs args = JS::CallArgsFromVp(argc, rval); - if (argc >= 1) - { - interpreter->write_element_offset = interpreter->element_offset; - for (unsigned int i = 0; i < argc; ++i) - { - char *str = jsval_to_string(ctx, args[i]); + if (argc >= 1) { + int element_offset = interpreter->element_offset; - if (str) { - add_to_string(&interpreter->writecode, str); - mem_free(str); + struct string string; + + if (init_string(&string)) { + for (unsigned int i = 0; i < argc; ++i) { + char *str = jsval_to_string(ctx, args[i]); + + if (str) { + add_to_string(&string, str); + mem_free(str); + } } - } - if (newline) - { - add_to_string(&interpreter->writecode, "\n"); + if (newline) { + add_to_string(&string, "\n"); + } + if (element_offset == interpreter->current_writecode->element_offset) { + add_string_to_string(&interpreter->current_writecode->string, &string); + done_string(&string); + } else { + struct string *ret = add_to_ecmascript_string_list(&interpreter->writecode, string.source, string.length, element_offset); + done_string(&string); + interpreter->current_writecode = interpreter->current_writecode->next; + } + interpreter->changed = true; } } - interpreter->changed = true; #ifdef CONFIG_LEDS set_led_value(interpreter->vs->doc_view->session->status.ecmascript_led, 'J');