BlitzMax and JavaScript together

Started by TomToad, May 10, 2019, 14:05:41

Previous topic - Next topic

TomToad

I have an html page loaded into a MaxGUI HTMLView which contains a JavaScript program.  I would like to know if it is possible to access variables and call functions within the script from BlitzMAX.
For example, html:
<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body>
<p>Hello, my name is <span id="name"></span>!</p>

<script>
var first = "Tom";
var last = "Toad";
var fullName = first + " " + last;
//How can I get and set these variables in BlitzMAX?

document.getElementById("name").innerHTML = fullName;

function changeName(name) {
//how can I call this function in BlitzMAX?
document.getElementById("name").innerHTML = name;
}
</script>
</body>
</html>

and BlitzMax:
Code (blitzmax) Select
SuperStrict
Import maxgui.drivers

Global MainWindow:TGadget = CreateWindow("Test HTML Frame",0,0,800,600,Null,WINDOW_DEFAULT|WINDOW_CENTER|WINDOW_CLIENTCOORDS)
Global HTMLView:TGadget = CreateHTMLView(0,20,ClientWidth(MainWindow),ClientHeight(MainWindow)-20,MainWindow)
Global ChangeNameButton:TGadget = CreateButton("Change Name",0,0,120,20,MainWindow)
Global ChangeVariableButton:TGadget = CreateButton("Change First Name",120,0,120,20,MainWindow)
AddHook EmitEventHook,hook
Local testpage:String = "file:///"+AppDir+"/test.html"
HtmlViewGo(HTMLView,testpage)

Repeat
WaitEvent()
Forever

Function hook:Object(id:Int, data:Object,context:Object)
Local event:TEvent = TEvent(data)

Select event.id
Case EVENT_WINDOWCLOSE, EVENT_APPTERMINATE
End
Case EVENT_GADGETACTION
Select event.source
Case ChangeNameButton
'How would I call changeName(name) in the JS script?
'JavaScript('changeName("John Doe")') '<-----???
Case ChangeVariableButton
'How to access the variable in the JS script
'Local CurrentFirstName = JavaScriptGetValue("first") '<--- get value of variable
'JavaScriptSetValue("first","John") '<-----set value of variable
End Select
End Select
Return data
End Function
------------------------------------------------
8 rabbits equals 1 rabbyte.

Derron

I think the htmlview cannot interact with the calling code/blitzmax.
It is like a window/view which is separate from the rest

You can only manipulate the html you pass to the webview (replace placeholders with your current values).

Bye
Ron

TomToad

I found HtmlViewRun() function that allows me to execute a script, and from there, call functions and change global variables.  Now I just need to figure out how to get information from JavaScript back into BlitzMAX.
------------------------------------------------
8 rabbits equals 1 rabbyte.

TomToad

Finally figured a way to send information from Javascript back to BlitzMax.  Just needed to use XMLHttpRequest() and open a socket in BlitzMax to receive the request.

HTML code: test.html
<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body>
<p>Hello, my name is <span id="name"></span>!</p>

<script>
var first = "Tom";
var last = "Toad";
var fullName = first + " " + last;
//How can I get and set these variables in BlitzMAX?

document.getElementById("name").innerHTML = fullName;

function changeName(firstName, lastName) {
//how can I call this function in BlitzMAX?
first = firstName;
last = lastName;
fullName = first + " " + last;
document.getElementById("name").innerHTML = fullName;
}

function getName() {
return fullName;
}
</script>
</body>
</html>


BlitzMax code:
Code (blitzmax) Select
SuperStrict
Import maxgui.drivers

Global MainWindow:TGadget = CreateWindow("Test HTML Frame",0,0,800,600,Null,WINDOW_DEFAULT|WINDOW_CENTER|WINDOW_CLIENTCOORDS)
Global HTMLView:TGadget = CreateHTMLView(0,20,ClientWidth(MainWindow),ClientHeight(MainWindow)-20,MainWindow)
Global ChangeNameButton:TGadget = CreateButton("Change Name",0,0,120,20,MainWindow)
Global PrintNameButton:TGadget = CreateButton("Print Name",120,0,120,20,MainWindow)
AddHook EmitEventHook,hook
Local testpage:String = "file:///"+AppDir+"/test.html"
HtmlViewGo(HTMLView,testpage)

Repeat
WaitEvent()
Forever

Function hook:Object(id:Int, data:Object,context:Object)
Local event:TEvent = TEvent(data)

Select event.id
Case EVENT_WINDOWCLOSE, EVENT_APPTERMINATE
End
Case EVENT_GADGETACTION
Select event.source
Case ChangeNameButton
Local Firstnames:String[] = ["John","Mary","Tom","Sam","Frank","Martha"]
Local Lastnames:String[] = ["Doe","Smith","Jones","Taylor"]
HtmlViewRun(HTMLView,"changeName('"+Firstnames[Rand(0,5)]+"','"+Lastnames[Rand(0,3)]+"');")
Case PrintNameButton
SetStatusText MainWindow, getValue(HTMLView,"fullName")
End Select
End Select
Return data
End Function

Function getValue:String(View:TGadget, Key:String)
Local data:String = Null
Local socket:TSocket = CreateTCPSocket()
Local result:Int = BindSocket(socket,8080)
If Not result Then RuntimeError("Cannot bind socket")
SocketListen(socket)
HtmlViewRun(View,"var xhr = new XMLHttpRequest(); " + ..
"xhr.open(~qPOST~q,~qhttp://127.0.0.1:8080~q,true); " + ..
"xhr.setRequestHeader(~qString-Value~q, "+Key+".toString()); " + ..
"xhr.send();")

Local remoteSocket:TSocket = SocketAccept(socket,5000)
If remoteSocket
Local in:TSocketStream = CreateSocketStream(remoteSocket)
Local Post:String = "get"
While Post <> ""
Post = ReadLine(in).Replace("~r","").Trim()
Local Params:String[] = Post.split(": ")
If Params.length >= 2
If Params[0] = "String-Value"
data = Params[1]
EndIf
EndIf
Wend
CloseStream in
EndIf
CloseSocket socket
Return data
End Function
------------------------------------------------
8 rabbits equals 1 rabbyte.