Skip to content

Commit b830fae

Browse files
committed
progress commit, attempts to load functions in global scope (kind of works)
1 parent 03bc329 commit b830fae

4 files changed

Lines changed: 150 additions & 48 deletions

File tree

src/JSEngine.cpp

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,28 @@ bool JSEngine::executeScript(const std::string& script) {
3636

3737
lastError = "";
3838

39-
// Use safer execution without try/catch for now
40-
int result = js_dostring(J, script.c_str());
39+
std::cout << "[JSEngine] Executing script (length: " << script.length() << ")" << std::endl;
4140

42-
if (result != 0) {
43-
lastError = "Script execution returned error code: " + std::to_string(result);
41+
// Use js_ploadstring + js_pcall for better global scope handling and exception safety
42+
// This ensures function declarations persist in the global scope
43+
if (js_ploadstring(J, "[script]", script.c_str())) {
44+
lastError = std::string("Script loading error: ") + js_trystring(J, -1, "Error");
45+
js_pop(J, 1);
46+
std::cout << "[JSEngine] Script loading failed: " << lastError << std::endl;
47+
return false;
48+
}
49+
50+
// Call the loaded script with no arguments
51+
js_pushundefined(J);
52+
if (js_pcall(J, 0)) {
53+
lastError = std::string("Script execution error: ") + js_trystring(J, -1, "Error");
54+
js_pop(J, 1);
55+
std::cout << "[JSEngine] Script execution failed: " << lastError << std::endl;
4456
return false;
4557
}
4658

59+
js_pop(J, 1); // Pop the result
60+
std::cout << "[JSEngine] Script executed successfully" << std::endl;
4761
return true;
4862
}
4963

@@ -112,6 +126,17 @@ double JSEngine::getGlobalNumber(const std::string& name) {
112126
return 0.0;
113127
}
114128

129+
bool JSEngine::globalFunctionExists(const std::string& name) {
130+
if (!J) return false;
131+
132+
js_getglobal(J, name.c_str());
133+
bool isFunction = js_iscallable(J, -1);
134+
js_pop(J, 1);
135+
136+
std::cout << "[JSEngine] Function '" << name << "' exists: " << (isFunction ? "YES" : "NO") << std::endl;
137+
return isFunction;
138+
}
139+
115140
bool JSEngine::parseJSON(const std::string& jsonStr) {
116141
if (!J) {
117142
lastError = "JavaScript state not initialized";
@@ -157,12 +182,21 @@ bool JSEngine::parseJSON(const std::string& jsonStr) {
157182

158183
std::string script = "var parsedJSON = JSON.parse('" + escapedJson + "');";
159184

160-
int result = js_dostring(J, script.c_str());
161-
if (result != 0) {
162-
lastError = "JSON.parse script execution failed with code: " + std::to_string(result);
185+
if (js_ploadstring(J, "[json]", script.c_str())) {
186+
lastError = std::string("JSON.parse loading error: ") + js_trystring(J, -1, "Error");
187+
js_pop(J, 1);
188+
return false;
189+
}
190+
191+
js_pushundefined(J);
192+
if (js_pcall(J, 0)) {
193+
lastError = std::string("JSON.parse execution error: ") + js_trystring(J, -1, "Error");
194+
js_pop(J, 1);
163195
return false;
164196
}
165197

198+
js_pop(J, 1); // Pop the result
199+
166200
std::cout << "JSON.parse executed successfully!" << std::endl;
167201
return true;
168202

src/JSEngine.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ class JSEngine {
2828
std::string getGlobalString(const std::string& name);
2929
double getGlobalNumber(const std::string& name);
3030

31+
// Check if a global function exists
32+
bool globalFunctionExists(const std::string& name);
33+
3134
// JSON parsing utilities
3235
bool parseJSON(const std::string& jsonStr);
3336
std::vector<std::string> getArrayFromGlobal(const std::string& globalName, const std::string& arrayPath);

src/WebView.cpp

Lines changed: 101 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -465,59 +465,122 @@ void WebView::executePageScripts() {
465465
// Find and execute script tags from the HTML document
466466
// We need to traverse the litehtml document to find script elements
467467
executeScriptsFromDocument();
468+
469+
// Test if any functions were defined (for debugging)
470+
std::cout << "Testing for common function names after script execution..." << std::endl;
471+
jsEngine->globalFunctionExists("updateValue");
472+
jsEngine->globalFunctionExists("resetValue");
473+
jsEngine->globalFunctionExists("loadValue");
474+
jsEngine->globalFunctionExists("testFunction");
475+
jsEngine->globalFunctionExists("simpleTest");
476+
jsEngine->globalFunctionExists("myGlobalFunction");
468477
}
469478

470479
void WebView::executeScriptsFromDocument() {
471480
if (!m_doc) return;
472481

473-
// For now, we'll implement a basic script extraction
474-
// This is a simplified approach - in a full implementation, we'd properly traverse the DOM tree
482+
std::cout << "[WebView] Starting script extraction from document" << std::endl;
483+
std::cout << "[WebView] HTML content length: " << this->contents.length() << std::endl;
484+
485+
// Debug: Show first 500 characters of HTML content to see what we're working with
486+
std::cout << "[WebView] HTML content preview:" << std::endl;
487+
std::cout << this->contents.substr(0, 500) << std::endl;
488+
std::cout << "[WebView] ..." << std::endl;
475489

476490
// Look for script content in the original HTML
477491
std::string html = this->contents;
478492
size_t pos = 0;
479-
480-
while ((pos = html.find("<script", pos)) != std::string::npos) {
481-
// Find the end of the opening script tag
482-
size_t tagEnd = html.find(">", pos);
483-
if (tagEnd == std::string::npos) break;
484-
485-
// Check if this is a script with type="text/javascript" or no type (default)
486-
std::string openingTag = html.substr(pos, tagEnd - pos + 1);
487-
bool isJavaScript = true;
488-
489-
// Simple check for non-JavaScript script types
490-
if (openingTag.find("type=") != std::string::npos &&
491-
openingTag.find("javascript") == std::string::npos &&
492-
openingTag.find("text/javascript") == std::string::npos &&
493-
openingTag.find("application/javascript") == std::string::npos) {
494-
isJavaScript = false;
495-
}
496-
497-
if (isJavaScript) {
498-
// Find the closing script tag
499-
size_t scriptEnd = html.find("</script>", tagEnd);
500-
if (scriptEnd != std::string::npos) {
501-
// Extract the script content
502-
std::string scriptContent = html.substr(tagEnd + 1, scriptEnd - tagEnd - 1);
493+
int scriptCount = 0;
494+
495+
// Try both lowercase and uppercase script tags
496+
std::vector<std::string> scriptTags = {"<script", "<SCRIPT"};
497+
498+
for (const auto& scriptTag : scriptTags) {
499+
pos = 0;
500+
while ((pos = html.find(scriptTag, pos)) != std::string::npos) {
501+
scriptCount++;
502+
std::cout << "[WebView] Found script tag #" << scriptCount << " (" << scriptTag << ") at position " << pos << std::endl;
503+
504+
// Find the end of the opening script tag
505+
size_t tagEnd = html.find(">", pos);
506+
if (tagEnd == std::string::npos) {
507+
std::cout << "[WebView] No closing > found for script tag" << std::endl;
508+
break;
509+
}
510+
511+
// Check if this is a script with type="text/javascript" or no type (default)
512+
std::string openingTag = html.substr(pos, tagEnd - pos + 1);
513+
std::cout << "[WebView] Opening tag: " << openingTag << std::endl;
514+
515+
bool isJavaScript = true;
516+
517+
// Simple check for non-JavaScript script types
518+
if (openingTag.find("type=") != std::string::npos &&
519+
openingTag.find("javascript") == std::string::npos &&
520+
openingTag.find("text/javascript") == std::string::npos &&
521+
openingTag.find("application/javascript") == std::string::npos) {
522+
isJavaScript = false;
523+
}
524+
525+
std::cout << "[WebView] Is JavaScript: " << (isJavaScript ? "YES" : "NO") << std::endl;
526+
527+
if (isJavaScript) {
528+
// Find the closing script tag (try both cases)
529+
size_t scriptEnd = std::string::npos;
530+
std::string closingTag;
503531

504-
// Trim whitespace
505-
size_t start = scriptContent.find_first_not_of(" \t\n\r");
506-
size_t end = scriptContent.find_last_not_of(" \t\n\r");
532+
if (scriptTag == "<script") {
533+
scriptEnd = html.find("</script>", tagEnd);
534+
closingTag = "</script>";
535+
} else {
536+
scriptEnd = html.find("</SCRIPT>", tagEnd);
537+
closingTag = "</SCRIPT>";
538+
}
539+
540+
// If case-specific closing tag not found, try the other case
541+
if (scriptEnd == std::string::npos) {
542+
if (scriptTag == "<script") {
543+
scriptEnd = html.find("</SCRIPT>", tagEnd);
544+
closingTag = "</SCRIPT>";
545+
} else {
546+
scriptEnd = html.find("</script>", tagEnd);
547+
closingTag = "</script>";
548+
}
549+
}
507550

508-
if (start != std::string::npos && end != std::string::npos) {
509-
scriptContent = scriptContent.substr(start, end - start + 1);
551+
if (scriptEnd != std::string::npos) {
552+
// Extract the script content
553+
std::string scriptContent = html.substr(tagEnd + 1, scriptEnd - tagEnd - 1);
510554

511-
if (!scriptContent.empty()) {
512-
std::cout << "Executing script: " << std::endl << scriptContent.substr(0, 100) << "..." << std::endl;
513-
executeJavaScript(scriptContent);
555+
std::cout << "[WebView] Raw script content length: " << scriptContent.length() << std::endl;
556+
std::cout << "[WebView] Raw script preview: " << scriptContent.substr(0, 100) << "..." << std::endl;
557+
558+
// Trim whitespace
559+
size_t start = scriptContent.find_first_not_of(" \t\n\r");
560+
size_t end = scriptContent.find_last_not_of(" \t\n\r");
561+
562+
if (start != std::string::npos && end != std::string::npos) {
563+
scriptContent = scriptContent.substr(start, end - start + 1);
564+
565+
if (!scriptContent.empty()) {
566+
std::cout << "[WebView] Executing script content (length " << scriptContent.length() << ")" << std::endl;
567+
executeJavaScript(scriptContent);
568+
} else {
569+
std::cout << "[WebView] Script content is empty after trimming" << std::endl;
570+
}
571+
} else {
572+
std::cout << "[WebView] No non-whitespace content found in script" << std::endl;
514573
}
574+
} else {
575+
std::cout << "[WebView] No closing " << closingTag << " tag found" << std::endl;
515576
}
516577
}
578+
579+
pos = tagEnd + 1;
517580
}
518-
519-
pos = tagEnd + 1;
520581
}
582+
583+
std::cout << "[WebView] Script extraction completed. Found " << scriptCount << " script tags total" << std::endl;
521584
}
522585

523586
bool WebView::executeJavaScript(const std::string& script) {
@@ -547,7 +610,7 @@ void WebView::cleanupJavaScript() {
547610
void WebView::recreateDocument() {
548611
if (!container) return;
549612

550-
std::cout << "Starting document recreation..." << std::endl;
613+
std::cout << "[WebView] recreateDocument() called - this will not re-execute scripts!" << std::endl;
551614

552615
// Store the current state
553616
std::string currentUrl = this->url;
@@ -564,7 +627,7 @@ void WebView::recreateDocument() {
564627
this->m_doc = litehtml::document::createFromString(this->contents.c_str(), container);
565628
this->needsRender = true;
566629

567-
std::cout << "Successfully recreated litehtml document from modified contents" << std::endl;
630+
std::cout << "[WebView] Successfully recreated litehtml document from modified contents" << std::endl;
568631

569632
// Do NOT execute page scripts again as that would cause infinite loops
570633
}

utils/BrocContainer.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -611,15 +611,17 @@ void BrocContainer::executeJavaScriptOnClick(const litehtml::element::ptr& eleme
611611
// Get the onclick attribute
612612
const char* onclick = element->get_attr("onclick");
613613
if (onclick && strlen(onclick) > 0) {
614-
std::cout << "Executing onclick JavaScript: " << onclick << std::endl;
614+
std::cout << "[BrocContainer] Executing onclick JavaScript: " << onclick << std::endl;
615615

616616
// Execute the JavaScript code
617617
bool success = webView->jsEngine->executeScript(onclick);
618618
if (!success) {
619-
std::cout << "Failed to execute onclick JavaScript" << std::endl;
619+
std::cout << "[BrocContainer] Failed to execute onclick JavaScript: " << webView->jsEngine->getLastError() << std::endl;
620+
} else {
621+
std::cout << "[BrocContainer] onclick JavaScript executed successfully" << std::endl;
620622
}
621623
} else {
622-
std::cout << "No onclick handler found for button" << std::endl;
624+
std::cout << "[BrocContainer] No onclick handler found for button" << std::endl;
623625
}
624626
}
625627

0 commit comments

Comments
 (0)