Android Question Richtexteditor - how they did it ?

Phayao

Active Member
Licensed User
Longtime User
Hello,

i am working on my own richtext editor based on webview and javascript.
With the webviewextras library i can call javascript functions that were loaded from a asset file into a webview.
The problem i am facing is that i cannot assign in B4A a variable to the content of the webview.

With webviewextras i can call a javascript function that returns the content:
B4X:
// call B4A function
function getHTML() {
    B4A.CallSub("returnHTML",true,document.getElementById('myDiv').innerHTML);
}
The content is then transferred to the B4A function "returnHTML" - that's fine.
BUT i see no way to simply call a B4A class directly like:
B4X:
mycontent = editor.getHTML

The same is true for the opposite, to fill a webview by a simple call in B4A, like:
B4X:
editor.putHTML = "bla bla bla"

This is probably due my lack of understanding of Javascript :-( and the way to interact with B4A.
Maybe its possible with another library like ultimatewebview or webkitwebview .... but these are quite undocumented as far as i can see. Any idea how this class "editor" could look like ?

Any help is very much appreciated,

Chris
 
Last edited:

Phayao

Active Member
Licensed User
Longtime User
Thank you Erel,
that's true, nevertheless the function
B4X:
Sub RunJavaScript (js As String) As ResumableSub
    wvExtras.executeJavascript(wvEditor, $"B4A.CallSub('returnHTML', true, ${js})"$)
    Wait For returnHTML(content As String)
    Log("return = "& content)
    Return content
End Sub

is resumable,so it can only return the result via "wait for..." which makes the calling function itself resumable...
I couldn't figure out a simple way to assign the content from Javascript to a variable like
B4X:
myContent = editor.content

I tried this idea with a global variable HTML:
B4X:
Sub RunJavaScript (js As String) As ResumableSub
    wvExtras.executeJavascript(wvEditor, $"B4A.CallSub('returnHTML', true, ${js})"$)
    Wait For returnHTML(content As String)
    Log("return = "& content)
    HTML = content   '  <== to be retrieved from the calling main code as:  myContent = editor.HTML
                                 '  is NOT working, HTML has no value at this point !
    Return content

Probably it's not possible by B4A but using some Java function... ?
Maybe there's a trick around it. Nevertheless i'm still experimenting ;-)

Chris
 
Upvote 0

MicroDrie

Well-Known Member
Licensed User
Probably it's not possible by B4A but using some Java function... ?
Perhaps creating your own Java library with the Simple Library Compiler (SLC - Build libraries without Eclipse), might be the solution to get more or complete control over the required Java functions. With this you can release all Java functions based on the information supplied by your program and read the result back into your program. I myself use the free Notepad++ for creating the Java source file via free Portable apps.
 
Upvote 0

Phayao

Active Member
Licensed User
Longtime User
The only way i could see is the following clumsy idea:
in main program:
B4X:
    wait for (editor.GetWebViewContent) complete(content As String)    ' working !
    Log("Getwebviewcont call finished - content = "& content)

in editor class:
B4X:
public Sub GetWebViewContent As ResumableSub
    Dim js As String = "getHTML()"    ' <== JS function function getHTML() {
                '    B4A.CallSub("returnHTML",false,document.getElementById('myDiv').innerHTML);
    Log("js= "& js)
    wvExtras.executeJavascript(wvEditor,js)
  
    Wait For returnHTML(content As String)
    Log("getwebview content = "& content) '<- program stops here when i just call: re.GetWebViewContent !!
    Return content
End Sub

It's maybe the only way in B4A because we have to wait for the javascript to respond.
In SMMRichtexteditor this is somehow managed by the library, that's what i wanted to "copy", but probably not in B4A ;-)
Any other ideas are appreciated, thank you !
 
Upvote 0

ilan

Expert
Licensed User
Longtime User
try this (MainPage):

B4X:
Sub Class_Globals
    Private Root As B4XView
    Private xui As XUI
    Private lbl1,tf1 As B4XView
    Private web1 As WebView
    Private editor As editor 'ignore
End Sub

Public Sub Initialize
'    B4XPages.GetManager.LogEvents = True
End Sub

'This event will be called once, before the page becomes visible.
Private Sub B4XPage_Created (Root1 As B4XView)
    Root = Root1
    Root.LoadLayout("MainPage")
    editor.Initialize(web1)
    web1.LoadUrl("http://www.google.com")
End Sub
 
Private Sub Get_Click
    editor.getHtml(lbl1,"SIvCob")
End Sub

Private Sub Put_Click
    editor.putHtml(tf1,"SIvCob")
End Sub

Editor Class:

B4X:
Sub Class_Globals
    Private webView1 As WebView
End Sub

'Initializes the object. You can add parameters to this method if needed.
Public Sub Initialize(wView As WebView)
    webView1 = wView    
End Sub

Private Sub runJS (JS As String) As ResumableSub
    Return webView1.As(JavaObject).RunMethodJO("getEngine", Null).RunMethod("executeScript", Array(JS))
End Sub

Public Sub getHtml(v As B4XView, ElementId As String)
    Wait For (runJS($"document.getElementById('${ElementId}').innerHTML;"$)) Complete(Html As String)
    v.Text = Html.SubString2(0,Html.IndexOf("<a href="))
End Sub

Public Sub putHtml(v As B4XView, ElementId As String)
    runJS($"document.getElementById('${ElementId}').innerHTML = '${v.Text}';"$)
End Sub

1683794494264.png
 

Attachments

  • js.zip
    3.9 KB · Views: 57
Upvote 0
Top