Executing Javascript on an external website
Posted: Wed Sep 18, 2024 1:18 pm
Hello folks,
what is the best (correct) way to control an external website via Javascript?
I have an OSM website and would like to use and control this page in Purebasic via the WebGadget.
Means, I would like to execute Javascript in the website via PureBasic.
The following code seems to make this possible. I call the JavaScript function f_showMessage() with PureBasic and this is successfully executed in the browser (WegGadget).
Before I now try to integrate the map extensively, I would like to ask again whether it should be done in this way?
Thank you!
what is the best (correct) way to control an external website via Javascript?
I have an OSM website and would like to use and control this page in Purebasic via the WebGadget.
Means, I would like to execute Javascript in the website via PureBasic.
The following code seems to make this possible. I call the JavaScript function f_showMessage() with PureBasic and this is successfully executed in the browser (WegGadget).
Before I now try to integrate the map extensively, I would like to ask again whether it should be done in this way?
Thank you!

Code: Select all
; Adapted from https://www.purebasic.fr/english/viewtopic.php?p=273634
Prototype.s ProtoExecuteJavaScript(gadget, Function$, Arguments$, Separator$, timeout=500)
JSMutex = CreateMutex()
Procedure.s JavaScriptQuote(code.s)
code = ReplaceString(code, "\", "\\")
code = ReplaceString(code, Chr(34), "\"+Chr(34))
ProcedureReturn Chr(34)+code+Chr(34)
EndProcedure
Procedure.l JavaScriptResetTitle(gadget.l)
Shared JSMutex
LockMutex(JSMutex)
SetGadgetText(gadget, "javascript:void(function(){document.title='';})();")
UnlockMutex(JSMutex)
EndProcedure
Procedure JavaScriptExamineThread(gadget.l)
title.s = ""
Repeat
title = GetGadgetItemText(gadget, #PB_Web_PageTitle)
If title = ""
Delay(100)
EndIf
Until title > ""
EndProcedure
Procedure.s ProcExecuteJavaScript(gadget, Function$, Arguments$, Separator$, timeout)
Shared JSMutex
If GadgetType(gadget) <> #PB_GadgetType_Web
ProcedureReturn ""
EndIf
code.s = ""
If Trim(Arguments$) = ""
code = ""
ElseIf Seperator$ = ""
code = JavaScriptQuote(Arguments$)
Else
Count = CountString(Arguments$, Separator$)+1
For i = 1 To Count
code = code + JavaScriptQuote(StringField(Arguments$, i, Separator$))
If i <> Count
code = code + ","
EndIf
Next i
EndIf
code = Function$+"("+code+");"
JavaScriptResetTitle(gadget)
LockMutex(JSMutex)
code = JavaScriptQuote(code)
js.s = "javascript:void(function(){document.title='';try{var ret = eval("+code
js = js + ");document.title=ret;}catch(e){document.title='exception: '+e;}})();"
SetGadgetText(gadget, js)
thread = CreateThread(@JavaScriptExamineThread(), gadget)
If thread <> 0
WaitThread(thread, timeout)
EndIf
UnlockMutex(JSMutex)
title.s = GetGadgetItemText(gadget, #PB_Web_PageTitle)
ProcedureReturn title
EndProcedure
ExecuteJavaScript.ProtoExecuteJavaScript = @ProcExecuteJavaScript()
Enumeration
#Gadget_Web
#Gadget_Command
#Gadget_Args
#Gadget_Text
#Gadget_Button
EndEnumeration
Procedure Resize()
Width = WindowWidth(0)
Height = WindowHeight(0)
ResizeGadget(#Gadget_Web, 5, 5, Width-10, Height-60)
ResizeGadget(#Gadget_Command, 5, Height-50, (Width-105)/4, 20)
ResizeGadget(#Gadget_Args, 10+(Width-105)/4, Height-50, ((Width-105)*3)/4, 20)
ResizeGadget(#Gadget_Text, 5, Height-25, Width-10, 20)
ResizeGadget(#Gadget_Button, Width-90, Height-50, 85, 20)
EndProcedure
If OpenWindow(0, 0, 0, 800, 600, "Javascript test", #PB_Window_ScreenCentered|#PB_Window_SizeGadget|#PB_Window_MaximizeGadget|#PB_Window_MinimizeGadget)
WebGadget(#Gadget_Web, 0, 0, 0, 0, "", #PB_Web_Edge)
StringGadget(#Gadget_Command, 0, 0, 0, 0, "f_showMessage")
StringGadget(#Gadget_Args, 0, 0, 0, 0, "Message via ExecuteJavascript :-)")
TextGadget(#Gadget_Text, 0, 0, 0, 0, "Type commandname into the first, and arguments into the second box. Do not include ()", #PB_Text_Border)
ButtonGadget(#Gadget_Button, 0, 0, 0, 0, "Execute")
Resize()
html.s = ~"<!DOCTYPE html><html lang=\"de\">" + #CRLF$ +
~"<head><meta charset=\"UTF-8\">" + #CRLF$ +
~"<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">" + #CRLF$ +
"<title>Alert mit JavaScript</title>" + #CRLF$ +
"<script>" + #CRLF$ +
"function f_showMessage(text) {" + #CRLF$ +
"alert(text);" + #CRLF$ +
"}" + #CRLF$ +
"</script></head>" + #CRLF$ +
"<body><h1>Messagebox with JavaScript</h1>" + #CRLF$ +
"<p>Please click the button below, to open the Messagebox.</p>" + #CRLF$ +
~"<button onclick=\"f_showMessage('You have clicked the button. Please try it with Execute Javascript also')\">Test Messagebox</button>" + #CRLF$ +
"</body></html>"
SetGadgetItemText(#Gadget_Web, #PB_Web_HtmlCode, html)
Repeat
Event = WaitWindowEvent()
If Event = #PB_Event_SizeWindow
Resize()
ElseIf Event = #PB_Event_Gadget And EventGadget() = #Gadget_Button
Command$ = GetGadgetText(#Gadget_Command)
Arguments$ = GetGadgetText(#Gadget_Args)
Result$ = ExecuteJavaScript(#Gadget_Web, Command$, Arguments$, ",")
SetGadgetText(#Gadget_Text, "Result: "+Result$)
EndIf
Until Event = #PB_Event_CloseWindow
EndIf
End