[solved] How to read changed html code inside 'div contenteditable'

Just starting out? Need help? Post your questions and find answers here.
flashbob
User
User
Posts: 92
Joined: Sat May 11, 2024 4:04 pm

[solved] How to read changed html code inside 'div contenteditable'

Post by flashbob »

Hi, attached an easy sample to format html code.
When I edit the content (add some text), it is not possible to read the changed HTML code (see button "get html").
Any ideas ?

Code: Select all

EnableExplicit

Enumeration FormGadget
  #web_gadget
  #Btn_bold
  #Btn_italics
  #Btn_underline
  #Btn_read_html
EndEnumeration

Define event
Define HtmlCode$= "<html><body>" +
                    "<div contenteditable>" +
                      "Hello World (from inline HTML)" +
                    "</div>" +
                  "</body></html>"

Declare get_html_Text()
Declare format_Text(tag_begin$, tag_end$) 

; ---- read (changed) html code
Procedure get_html_Text()
  Debug GetGadgetItemText(#web_gadget, #PB_Web_HtmlCode)
  ; ??
EndProcedure

;---- format selected text
Procedure format_Text(tag_begin$, tag_end$) 
  Protected selected_text$ = GetGadgetItemText(#web_gadget, #PB_Web_SelectedText)
  Protected html_code$     = GetGadgetItemText(#web_gadget, #PB_Web_HtmlCode)
  Protected new_code$      = tag_begin$ + selected_text$ + tag_end$
  Protected new_html_code$ = ""
  Protected start_pos, text_pos
  
  ; get start position of 'visible' text
  start_pos = FindString(html_code$, "<div contenteditable>")+21-1
  
  ; get start position of selected text
  text_pos = FindString(html_code$, selected_text$, start_pos)
  
  ; expand selected html code with tags
  new_html_code$ = ReplaceString(html_code$, selected_text$, new_code$, #PB_String_CaseSensitive,text_pos,1)
  
  ; remove duplicate tags
  new_html_code$ = ReplaceString(new_html_code$, tag_begin$ + tag_begin$, tag_begin$)
  new_html_code$ = ReplaceString(new_html_code$, tag_end$   + tag_end$,   tag_end$)
  
  ; refresh inline Text
  SetGadgetItemText(#web_gadget, #PB_Web_HtmlCode, new_html_code$)
  
EndProcedure
; -----------------------------------------------------------------

OpenWindow(0, 0, 0, 600, 400, "Editable HTML Content", 
           #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_MaximizeGadget | #PB_Window_MinimizeGadget)

ButtonGadget(#Btn_read_html, 5, 5, 85, 25, "get html")
ButtonGadget(#Btn_bold,      95, 5, 85, 25, "bold")
ButtonGadget(#Btn_italics,  185, 5, 85, 25, "italics")
ButtonGadget(#Btn_underline,275, 5, 85, 25, "underline")

WebGadget(#web_gadget, 0, 35, 600, 400, "")
SetGadgetItemText(#web_gadget, #PB_Web_HtmlCode, HtmlCode$)

; -----------------------------------------------------------------

Repeat
  event = WaitWindowEvent()
  
  Select event
    Case #PB_Event_Gadget
      Select EventGadget()
        Case #Btn_bold      : format_Text("<b>","</b>")
        Case #Btn_italics   : format_text("<i>","</i>")
        Case #Btn_underline : format_text("<u>","</u>")  
        Case #Btn_read_html : get_html_Text()
      EndSelect
  EndSelect
Until event = #PB_Event_CloseWindow

Last edited by flashbob on Tue May 14, 2024 6:10 pm, edited 1 time in total.
boddhi
Enthusiast
Enthusiast
Posts: 524
Joined: Mon Nov 15, 2010 9:53 pm

Re: How to read changed html code inside 'div contenteditable'

Post by boddhi »

Hi,

Seems to work fine under PB 6.10 x64/Win 10 x64
Image
If my English syntax and lexicon are incorrect, please bear with Google translate and DeepL. They rarely agree with each other!
Except on this sentence...
User avatar
Caronte3D
Addict
Addict
Posts: 1355
Joined: Fri Jan 22, 2016 5:33 pm
Location: Some Universe

Re: How to read changed html code inside 'div contenteditable'

Post by Caronte3D »

I think he mean edit the text writing in place
flashbob
User
User
Posts: 92
Joined: Sat May 11, 2024 4:04 pm

Re: How to read changed html code inside 'div contenteditable'

Post by flashbob »

Caronte3D wrote: Mon May 13, 2024 1:59 pm I think he mean edit the text writing in place
... correct
boddhi
Enthusiast
Enthusiast
Posts: 524
Joined: Mon Nov 15, 2010 9:53 pm

Re: How to read changed html code inside 'div contenteditable'

Post by boddhi »

Caronte3D wrote:I think he mean edit the text writing in place
I really don't know... Maybe, I misunderstood :)

However:

Code: Select all

GetGadgetItemText(#web_gadget, #PB_Web_HtmlCode)
Returns HTML code (i.e with HTML tags)
 

Code: Select all

GetGadgetItemText(#web_gadget, #PB_Web_SelectedText)
Returns pure text (i.e without HTML tags)
If my English syntax and lexicon are incorrect, please bear with Google translate and DeepL. They rarely agree with each other!
Except on this sentence...
flashbob
User
User
Posts: 92
Joined: Sat May 11, 2024 4:04 pm

Re: How to read changed html code inside 'div contenteditable'

Post by flashbob »

The command "getgadgetItemText" is well known and has also been used in the code. But how can I read changed text from the WebGadget?
Try to add text and press button "get text". You will get only the initial html code...
boddhi
Enthusiast
Enthusiast
Posts: 524
Joined: Mon Nov 15, 2010 9:53 pm

Re: How to read changed html code inside 'div contenteditable'

Post by boddhi »

Works with:

Code: Select all

WebGadget(#web_gadget, 0, 35, 600, 400, "",  #PB_Web_Edge  )
There may be a limitation due to the old IE11 ActiveX object?!
If my English syntax and lexicon are incorrect, please bear with Google translate and DeepL. They rarely agree with each other!
Except on this sentence...
flashbob
User
User
Posts: 92
Joined: Sat May 11, 2024 4:04 pm

Re: How to read changed html code inside 'div contenteditable'

Post by flashbob »

boddhi wrote: Mon May 13, 2024 5:45 pm Works with:

Code: Select all

WebGadget(#web_gadget, 0, 35, 600, 400, "",  #PB_Web_Edge  )
There may be a limitation due to the old IE11 ActiveX object?!
No, there are no limitations under Windows 7 for this case. WebGadget has the limitation. No problem with other prog language.
Maybe I have to find a workaround using the WinAPI (Win) and cocoa (MAC) for this purpose ...
boddhi
Enthusiast
Enthusiast
Posts: 524
Joined: Mon Nov 15, 2010 9:53 pm

Re: How to read changed html code inside 'div contenteditable'

Post by boddhi »

Sorry, I am not at all an expert on the subject. Maybe wait a little for a response from a specialist.

Maybe too it's a bug (or there's a valid reason for not being able to retrieve the modified HTML code with PB)
If my English syntax and lexicon are incorrect, please bear with Google translate and DeepL. They rarely agree with each other!
Except on this sentence...
breeze4me
Enthusiast
Enthusiast
Posts: 633
Joined: Thu Mar 09, 2006 9:24 am
Location: S. Kor

Re: How to read changed html code inside 'div contenteditable'

Post by breeze4me »

For Windows.

Code: Select all

EnableExplicit

Enumeration FormGadget
  #web_gadget
  #Btn_bold
  #Btn_italics
  #Btn_underline
  #Btn_read_html
EndEnumeration

Define event
Define HtmlCode$= "<html><body>" +
                    "<div contenteditable>" +
                      "Hello World (from inline HTML)" +
                    "</div>" +
                  "</body></html>"

Declare.s get_html_Text(WebGadget)
Declare format_Text(tag_begin$, tag_end$) 

; ---- read (changed) html code
Procedure.s get_html_Text(WebGadget)
  Protected sResult.s, *OuterHTML, Browser.IWebBrowser2 = GetWindowLong_(GadgetID(WebGadget), #GWL_USERDATA)
  Protected DocumentDispatch.IDispatch, DocElement.IHTMLElement, Document3.IHTMLDocument3
  If Browser
    If Browser\get_Document(@DocumentDispatch) = #S_OK And DocumentDispatch
      If DocumentDispatch\QueryInterface(?IID_IHTMLDocument3, @Document3) = #S_OK And Document3
        If Document3\get_documentElement(@DocElement) = #S_OK And DocElement
          If DocElement\get_outerHTML(@*OuterHTML) = #S_OK
            If *OuterHTML
              sResult = PeekS(*OuterHTML)
              SysFreeString_(*OuterHTML)
            EndIf
          EndIf
          DocElement\Release()
        EndIf
        Document3\Release()
      EndIf
      DocumentDispatch\Release()
    EndIf
  EndIf
  ProcedureReturn sResult
  
  DataSection
    IID_IHTMLDocument3:
    Data.l $3050F485
    Data.w $98B5,$11CF
    Data.b $BB,$82,$00,$AA,$00,$BD,$CE,$0B
  EndDataSection
EndProcedure

;---- format selected text
Procedure format_Text(tag_begin$, tag_end$) 
  Protected selected_text$ = GetGadgetItemText(#web_gadget, #PB_Web_SelectedText)
  Protected html_code$     = get_html_Text(#web_gadget)
  Protected new_code$      = tag_begin$ + selected_text$ + tag_end$
  Protected new_html_code$ = ""
  Protected start_pos, text_pos
  
  ; get start position of 'visible' text
  ; Remove the trailing ">" because the string that follows is different for different versions of Windows. 
  start_pos = FindString(html_code$, "<div contenteditable")+21-1
  
  ; get start position of selected text
  text_pos = FindString(html_code$, selected_text$, start_pos)
  
  ; expand selected html code with tags
  new_html_code$ = ReplaceString(html_code$, selected_text$, new_code$, #PB_String_CaseSensitive,text_pos,1)
  
  ; remove duplicate tags
  new_html_code$ = ReplaceString(new_html_code$, tag_begin$ + tag_begin$, tag_begin$)
  new_html_code$ = ReplaceString(new_html_code$, tag_end$   + tag_end$,   tag_end$)
  
  ; refresh inline Text
  SetGadgetItemText(#web_gadget, #PB_Web_HtmlCode, new_html_code$)
  
EndProcedure
; -----------------------------------------------------------------

OpenWindow(0, 0, 0, 600, 400, "Editable HTML Content", 
           #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_MaximizeGadget | #PB_Window_MinimizeGadget)

ButtonGadget(#Btn_read_html, 5, 5, 85, 25, "get html")
ButtonGadget(#Btn_bold,      95, 5, 85, 25, "bold")
ButtonGadget(#Btn_italics,  185, 5, 85, 25, "italics")
ButtonGadget(#Btn_underline,275, 5, 85, 25, "underline")

WebGadget(#web_gadget, 0, 35, 600, 400, "")
SetGadgetItemText(#web_gadget, #PB_Web_HtmlCode, HtmlCode$)

; -----------------------------------------------------------------

Repeat
  event = WaitWindowEvent()
  
  Select event
    Case #PB_Event_Gadget
      Select EventGadget()
        Case #Btn_bold      : format_Text("<b>","</b>")
        Case #Btn_italics   : format_text("<i>","</i>")
        Case #Btn_underline : format_text("<u>","</u>")  
        Case #Btn_read_html : Debug get_html_Text(#web_gadget)
      EndSelect
  EndSelect
Until event = #PB_Event_CloseWindow
flashbob
User
User
Posts: 92
Joined: Sat May 11, 2024 4:04 pm

Re: How to read changed html code inside 'div contenteditable'

Post by flashbob »

Thank you breeze4me for your windows example - works fine!

I have now added the code for Mac and included your code.

Here the code (workaround) for MAC and Windows :

Code: Select all


; ----------------------------------------------------------
;
; Purpose
; simple example to display, format, change html text. The tag 
; <div contenteditable> is used to edit text.
; (should run under Win 7 / MAC OS)
; 
; Problem
; The command "GetGadgetItemText()" doesn't work. Only the initial 
; html code is displayed and no additional text entered 
; 
; Workaround
; see below, should work For windows/Mac
;
; ----------------------------------------------------------

EnableExplicit

Enumeration FormGadget
  #web_gadget
  #Btn_bold
  #Btn_italics
  #Btn_underline
  #Btn_read_html
EndEnumeration

Define event
Define HtmlCode$= "<html><body>" +
                    "<div contenteditable>" +
                      "Hello World (from inline HTML). Try to edit Text ..." +
                    "</div>" +
                  "</body></html>"

Declare.s get_html_Text(WebGadget)
Declare format_Text(tag_begin$, tag_end$) 


; ---- read (changed) html code
Procedure.s get_html_Text(WebGadget)
  Protected sResult.s
  
  ; following command does not work for changed html code
  ; sResult= GetGadgetItemText(WebGadget, #PB_Web_HtmlCode)
  
  ; Workaround for MAC / Windows
  CompilerIf #PB_Compiler_OS = #PB_OS_MacOS
    
    Protected URL$, NSString
    ; --- examples to read html code
    ;URL$ = "document.getElementsByTagName('body')[0].innerHTML;"   ; get inner HTML (<body> ... </body>)
    ;URL$ = "document.getElementsByTagName('div')[0].innerHTML;"    ; get inner HTML (<div> ... </div>)
    URL$     = "document.documentElement.outerHTML;"                ; get entire document ( <html> ... </html>)
    NSString = CocoaMessage(0, GadgetID(#web_gadget), "stringByEvaluatingJavaScriptFromString:$", @URL$)
    sResult  = PeekS(CocoaMessage(0, NSString, "UTF8String"), -1, #PB_UTF8)
    
  CompilerElseIf #PB_Compiler_OS = #PB_OS_Windows
    
    ; workaround Win - thx to breeze4me   
    Protected *OuterHTML, Browser.IWebBrowser2 = GetWindowLong_(GadgetID(WebGadget), #GWL_USERDATA)
    Protected DocumentDispatch.IDispatch, DocElement.IHTMLElement, Document3.IHTMLDocument3
    If Browser
      If Browser\get_Document(@DocumentDispatch) = #S_OK And DocumentDispatch
        If DocumentDispatch\QueryInterface(?IID_IHTMLDocument3, @Document3) = #S_OK And Document3
          If Document3\get_documentElement(@DocElement) = #S_OK And DocElement
            If DocElement\get_outerHTML(@*OuterHTML) = #S_OK
              If *OuterHTML
                sResult = PeekS(*OuterHTML)
                SysFreeString_(*OuterHTML)
              EndIf
            EndIf
            DocElement\Release()
          EndIf
          Document3\Release()
        EndIf
        DocumentDispatch\Release()
      EndIf
    EndIf
 
    DataSection
      IID_IHTMLDocument3:
      Data.l $3050F485 
      Data.w $98B5,$11CF
      Data.b $BB,$82,$00,$AA,$00,$BD,$CE,$0B
    EndDataSection
  CompilerEndIf
  
  ProcedureReturn sResult
EndProcedure


;---- format selected text
Procedure format_Text(tag_begin$, tag_end$) 
  Protected selected_text$ = GetGadgetItemText(#web_gadget, #PB_Web_SelectedText)
  Protected html_code$
  Protected new_code$      = tag_begin$ + selected_text$ + tag_end$
  Protected new_html_code$ = ""
  Protected start_pos, text_pos
  
  ; read changed text (Mac/Win)
  html_code$ = get_html_Text(#web_gadget)
  
  ; get start position of 'visible' text
  start_pos = FindString(html_code$, "<div contenteditable>")+21-1
  
  ; get start position of selected text
  text_pos = FindString(html_code$, selected_text$, start_pos)
  
  ; expand selected html code with tags
  new_html_code$ = ReplaceString(html_code$, selected_text$, new_code$, #PB_String_CaseSensitive,text_pos,1)
  
  ; remove duplicate tags
  new_html_code$ = ReplaceString(new_html_code$, tag_begin$ + tag_begin$, tag_begin$)
  new_html_code$ = ReplaceString(new_html_code$, tag_end$   + tag_end$,   tag_end$)
  
  ; refresh inline Text
  SetGadgetItemText(#web_gadget, #PB_Web_HtmlCode, new_html_code$)
  
EndProcedure


; -----------------------------------------------------------------

OpenWindow(0, 0, 0, 600, 400, "Editable HTML Content", 
           #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_MaximizeGadget | #PB_Window_MinimizeGadget)

ButtonGadget(#Btn_read_html, 5, 5, 85, 25, "get html")
ButtonGadget(#Btn_bold,      95, 5, 85, 25, "bold")
ButtonGadget(#Btn_italics,  185, 5, 85, 25, "italics")
ButtonGadget(#Btn_underline,275, 5, 85, 25, "underline")

WebGadget(#web_gadget, 0, 35, 600, 400, "")

; initial demo html code 
SetGadgetItemText(#web_gadget, #PB_Web_HtmlCode, HtmlCode$)

; -----------------------------------------------------------------

Repeat
  event = WaitWindowEvent()
  
  Select event
    Case #PB_Event_Gadget
      Select EventGadget()
        Case #Btn_bold      : format_Text("<b>","</b>")
        Case #Btn_italics   : format_text("<i>","</i>")
        Case #Btn_underline : format_text("<u>","</u>")
        Case #Btn_read_html : Debug get_html_Text(#web_gadget)
      EndSelect
  EndSelect
Until event = #PB_Event_CloseWindow

... hope this helps others. Unfortunately, many functions are only possible by calling external APIs ...
dige
Addict
Addict
Posts: 1391
Joined: Wed Apr 30, 2003 8:15 am
Location: Germany
Contact:

Re: How to read changed html code inside 'div contenteditable'

Post by dige »

breeze4me wrote: Tue May 14, 2024 7:31 am For Windows.
[..]
Works, thank you very much. However, there is a problem with umlauts. If I change World to Wörld, this is initially transferred correctly with GetHtml. But if I then format it, Wörld suddenly becomes Wörld.
"Daddy, I'll run faster, then it is not so far..."
infratec
Always Here
Always Here
Posts: 7588
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: [solved] How to read changed html code inside 'div contenteditable'

Post by infratec »

@dige
No, you have a problem with html :wink:

ö is:

Code: Select all

&ouml;
in html
User avatar
Kiffi
Addict
Addict
Posts: 1486
Joined: Tue Mar 02, 2004 1:20 pm
Location: Amphibios 9

Re: [solved] How to read changed html code inside 'div contenteditable'

Post by Kiffi »

@flashbob:

You should revise your procedure for inserting the tags:

Image
Hygge
flashbob
User
User
Posts: 92
Joined: Sat May 11, 2024 4:04 pm

Re: [solved] How to read changed html code inside 'div contenteditable'

Post by flashbob »

Of course, everyone can change or expand the code as they wish. Then there are no problems with umlauts etc. But that's just small stuff.
Essentially it was about finding a workaround for the error.

@kiffi
It is not an example of optimal code, it's just a little demo. Maybe there will be someone who can optimize this example and then post it somewhere else in the forum. :wink:
Post Reply