Set WebGadget HTML content + call parent page commands

Share your advanced knowledge/code with the community.
User avatar
eddy
Posts: 124
Joined: Thu Mar 27, 2014 8:34 am

Set WebGadget HTML content + call parent page commands

Post by eddy »

- set IFRAME HTML content
- communication/action between IFRAME elements and the parent page
- using srcdoc polyfill (for IE9 compatibility)

Code: Select all

; ************************
; filename : WebGadgetUtils.sbi
; ************************

Procedure SetWebGadgetHTMLText(WebGadget, ContentText.s)
  Static isSrcDocPluginReady.b
  If Not isSrcDocPluginReady
    isSrcDocPluginReady=#True 
    ;// Remark: this is a plugin only for IE compatibility.
    ;// I load the plugin here instead of using $.GetScript(...) because IE cannot load script from github CDN
    
    !/*! srcdoc-polyfill - v0.1.1 - 2013-03-01
    !* http://github.com/jugglinmike/srcdoc-polyfill/
    !* Copyright (c) 2013 Mike Pennisi; Licensed MIT */
    !(function(t,e){var c,n,o=t.srcDoc,r=!!("srcdoc"in e.createElement("iframe")),i={compliant:function(t,e){e&&t.setAttribute("srcdoc",e)},legacy:function(t,e){var c;t&&t.getAttribute&&(e?t.setAttribute("srcdoc",e):e=t.getAttribute("srcdoc"),e&&(c="javascript: window.frameElement.getAttribute('srcdoc');",t.setAttribute("src",c),t.contentWindow&&(t.contentWindow.location=c)))}},s=t.srcDoc={set:i.compliant,noConflict:function(){return t.srcDoc=o,s}};if(!r)for(s.set=i.legacy,n=e.getElementsByTagName("iframe"),c=n.length;c--;)s.set(n[c])})(this,this.document);
  EndIf 
  
  Protected gadgetId=GadgetID(WebGadget)
  !var iframe=v_gadgetId.gadget;
  !srcDoc.set(iframe,v_ContentText);    
EndProcedure 

Procedure.s CallPageCommand(Command.i, Parameters.s="()")    
  Parameters=ReplaceString(Parameters,"'","'")
  Parameters=ReplaceString(Parameters,#DQUOTE$,""")
  Protected cmd.s="parent.window.PB_PageCommand["+Command+"]"+Parameters
  ProcedureReturn cmd
EndProcedure

Procedure.i AddPageCommand(*CommandProcedure)
  !var cmdKey='PB_PageCommand';
  !var cmds=window[cmdKey] ? window[cmdKey] : [];
  !var cmdIndex=cmds.push(p_CommandProcedure)-1;
  !window[cmdKey]=cmds
  !return cmdIndex;
EndProcedure

Procedure AddWebGadgetElement(WebGadget,NewElement.s,TargetElement.s="body")
  Protected gadgetId=GadgetID(WebGadget)
  !$(v_NewElement).appendTo($(v_gadgetId.gadget).contents().find(v_TargetElement));
EndProcedure


CompilerIf #PB_Compiler_IsMainFile
  ; ***************************************************
  ; EXAMPLE 1 - Fullscreen Webgadget & Calling page commands
  ; ***************************************************
  
  Procedure AddHorzLine() 
    ;Add horizontal line inside the WebGadget (IFRAME)    
    AddWebGadgetElement(1,"<hr/>","body")
  EndProcedure
  
  Procedure ShowAlert(message.s)
    ;Show alert message
    !alert(v_message);
  EndProcedure
  
  Procedure GadgetResizing() 
    ;Fullscreen WebGadget (IFRAME)
    Protected win=EventWindow()    
    If win=10 : ResizeGadget(1,#PB_Ignore,#PB_Ignore,WindowWidth(win),WindowHeight(win)) : EndIf 
  EndProcedure
  
  Procedure GadgetEvents()
    Protected gadget=EventGadget()
    If gadget=2 
      AddHorzLine()
    EndIf     
  EndProcedure

  
  If OpenWindow(10, 0, 0, 0, 0, "FullScreen Window", #PB_Window_Background)    
    BindEvent(#PB_Event_SizeWindow, @GadgetResizing())
    BindEvent(#PB_Event_Gadget, @GadgetEvents())
    
    cmdAddLine=AddPageCommand(@AddHorzLine())
    cmdAlert=AddPageCommand(@ShowAlert())
    callAddLine.s=CallPageCommand(cmdAddLine)
    callAlert1.s=CallPageCommand(cmdAlert,"('My name is \'SpiderBasic\'. "+#DQUOTE$+"Oops!"+#DQUOTE$+" Bye.')")
    callAlert2.s=CallPageCommand(cmdAlert,"("+#DQUOTE$+"My name is 'PureBasic'. \"+#DQUOTE$+"Doh!\"+#DQUOTE$+" Bye."+#DQUOTE$+")")
    WebGadget(1,0,0,DesktopWidth(0),DesktopHeight(0),"")
    HTMLCode.s="<!DOCTYPE html>"+
               "<html>"+
               "  <head>"+
               "    <meta charset='utf-8'>"+
               "    <meta http-equiv='X-UA-Compatible' content='IE=edge'>"+
               "    <meta name='viewport' content='width=device-width, initial-scale=1'>"+
               "    <title>Default Page In IFRAME container</title>"+  
               "  </head>"+
               "  <body>"+
               "  <h1>Hello, World!</h1>"+
               "  <a onclick='"+callAddLine+";return false;' href='#' >Add line </a><br/>"+
               "  <a onclick='"+callAlert1+";return false;' href='#' >Show Spiderbasic message</a><br/>"+
               "  <a onclick="+#DQUOTE$+callAlert2+";return false;"+#DQUOTE$+" href='#' >Show Purebasic message</a>"+
               "  </body>"+
               "</html>" 
    SetWebGadgetHTMLText(1,HTMLCode)    
    
    ButtonGadget(2,5,5, 200,20,"Add Line")
  EndIf
CompilerEndIf
Last edited by eddy on Sat Apr 26, 2014 11:26 am, edited 4 times in total.
User avatar
eddy
Posts: 124
Joined: Thu Mar 27, 2014 8:34 am

Re: WebGadget (IFRAME action and communication)

Post by eddy »

update
- AddPageCommand : register parent page command
- CallPageCommand : generate script to call parent page command from IFRAME child page
User avatar
eddy
Posts: 124
Joined: Thu Mar 27, 2014 8:34 am

Re: WebGadget (IFRAME action and communication)

Post by eddy »

Code: Select all

XIncludeFile "[Library Path]\WebGadgetUtils.sbi"

CompilerIf #PB_Compiler_IsMainFile
  ; ***************************************************
  ; EXAMPLE 2
  ; ***************************************************
  
  Enumeration
    #Window
    #WebGadget
  EndEnumeration
  
  Procedure AddHorzLine(InChildPage.b) 
    If InChildPage
      ; add line inside child page (webgadget IFRAME)
      AddWebGadgetElement(#WebGadget,"<hr style='background:cyan;border-color:cyan'/>","body")
    Else 
      ; add line inside parent page (fullscreen main window)
      winId=WindowID(#Window)
      !$('<hr style="background:red;border-color:red"/>').appendTo($(v_winId.element));
    EndIf     
  EndProcedure
  
  
  If OpenWindow(#Window, 0, 0, 0, 0, "FullScreen Window", #PB_Window_Background)    
    
    cmdAddLine=AddPageCommand(@AddHorzLine())
    callAddChildLine.s=CallPageCommand(cmdAddLine,"(1)")
    Debug callAddChildLine
    callAddParentLine.s=CallPageCommand(cmdAddLine,"(0)")
    Debug callAddParentLine
    HTMLCode.s="<!DOCTYPE html>"+
               "<html>"+
               "  <head>"+
               "    <meta charset='utf-8'>"+
               "    <meta http-equiv='X-UA-Compatible' content='IE=edge'>"+
               "    <meta name='viewport' content='width=device-width, initial-scale=1'>"+
               "    <title>Inside IFRAME</title>"+  
               "  </head>"+
               "  <body style='background:blue;font-size:20px;color:white'>"+
               "  <h1>CHILD PAGE</h1>"+
               "  <input type='button' onclick='"+callAddChildLine+";return false;' value='Add line in child page' /><br/>"+
               "  <input type='button' onclick='"+callAddParentLine+";return false;' value='Add line in parent page' /><br/>"+
               "  </body>"+
               "</html>" 
    WebGadget(#WebGadget,100,100,800,600,"")
    SetWebGadgetHTMLText(#WebGadget,HTMLCode)    
    
    TextGadget(#PB_Any,50,50, 200,20,"PARENT PAGE")
  EndIf
CompilerEndIf
elread
Posts: 3
Joined: Fri Mar 18, 2016 9:56 pm

Re: Set WebGadget HTML content + call parent page commands

Post by elread »

In the SB version 1.20 (x86,Win) this library doesn't work. There was a blank screen and no errors after I run both the examples. How could that be fixed?
jamirokwai
Posts: 40
Joined: Fri Sep 25, 2015 12:00 pm

Re: Set WebGadget HTML content + call parent page commands

Post by jamirokwai »

All v_ and p_ have to be lower case:

Code: Select all

; ************************
; filename : WebGadgetUtils.sbi
; ************************

Procedure SetWebGadgetHTMLText(WebGadget, ContentText.s)
  Static isSrcDocPluginReady.b
  If Not isSrcDocPluginReady
    isSrcDocPluginReady=#True 
    ;// Remark: this is a plugin only for IE compatibility.
    ;// I load the plugin here instead of using $.GetScript(...) because IE cannot load script from github CDN
    
    !/*! srcdoc-polyfill - v0.1.1 - 2013-03-01
    !* http://github.com/jugglinmike/srcdoc-polyfill/
    !* Copyright (c) 2013 Mike Pennisi; Licensed MIT */
    !(function(t,e){var c,n,o=t.srcDoc,r=!!("srcdoc"in e.createElement("iframe")),i={compliant:function(t,e){e&&t.setAttribute("srcdoc",e)},legacy:function(t,e){var c;t&&t.getAttribute&&(e?t.setAttribute("srcdoc",e):e=t.getAttribute("srcdoc"),e&&(c="javascript: window.frameElement.getAttribute('srcdoc');",t.setAttribute("src",c),t.contentWindow&&(t.contentWindow.location=c)))}},s=t.srcDoc={set:i.compliant,noConflict:function(){return t.srcDoc=o,s}};if(!r)for(s.set=i.legacy,n=e.getElementsByTagName("iframe"),c=n.length;c--;)s.set(n[c])})(this,this.document);
  EndIf 
  
  Protected gadgetId=GadgetID(WebGadget)
  !var iframe=v_gadgetid.gadget;
  !srcDoc.set(iframe,v_contenttext);    
EndProcedure 

Procedure.s CallPageCommand(Command.i, Parameters.s="()")    
  Parameters=ReplaceString(Parameters,"'","'")
  Parameters=ReplaceString(Parameters,#DQUOTE$,""")
  Protected cmd.s="parent.window.PB_PageCommand["+Command+"]"+Parameters
  ProcedureReturn cmd
EndProcedure

Procedure.i AddPageCommand(*CommandProcedure)
  !var cmdKey='PB_PageCommand';
  !var cmds=window[cmdKey] ? window[cmdKey] : [];
  !var cmdIndex=cmds.push(p_commandprocedure)-1;
  !window[cmdKey]=cmds
  !return cmdIndex;
EndProcedure

Procedure AddWebGadgetElement(WebGadget,NewElement.s,TargetElement.s="body")
  Protected gadgetId=GadgetID(WebGadget)
  !$(v_newelement).appendTo($(v_gadgetid.gadget).contents().find(v_targetelement));
EndProcedure


CompilerIf #PB_Compiler_IsMainFile
  ; ***************************************************
  ; EXAMPLE 1 - Fullscreen Webgadget & Calling page commands
  ; ***************************************************
  
  Procedure AddHorzLine() 
    ;Add horizontal line inside the WebGadget (IFRAME)    
    AddWebGadgetElement(1,"<hr/>","body")
  EndProcedure
  
  Procedure ShowAlert(message.s)
    ;Show alert message
    !alert(v_message);
  EndProcedure
  
  Procedure GadgetResizing() 
    ;Fullscreen WebGadget (IFRAME)
    Protected win=EventWindow()    
    If win=10 : ResizeGadget(1,#PB_Ignore,#PB_Ignore,WindowWidth(win),WindowHeight(win)) : EndIf 
  EndProcedure
  
  Procedure GadgetEvents()
    Protected gadget=EventGadget()
    If gadget=2 
      AddHorzLine()
    EndIf     
  EndProcedure

  
  If OpenWindow(10, 0, 0, 0, 0, "FullScreen Window", #PB_Window_Background)    
    BindEvent(#PB_Event_SizeWindow, @GadgetResizing())
    BindEvent(#PB_Event_Gadget, @GadgetEvents())
    
    cmdAddLine=AddPageCommand(@AddHorzLine())
    cmdAlert=AddPageCommand(@ShowAlert())
    callAddLine.s=CallPageCommand(cmdAddLine)
    callAlert1.s=CallPageCommand(cmdAlert,"('My name is \'SpiderBasic\'. "+#DQUOTE$+"Oops!"+#DQUOTE$+" Bye.')")
    callAlert2.s=CallPageCommand(cmdAlert,"("+#DQUOTE$+"My name is 'PureBasic'. \"+#DQUOTE$+"Doh!\"+#DQUOTE$+" Bye."+#DQUOTE$+")")
    WebGadget(1,0,0,DesktopWidth(0),DesktopHeight(0),"")
    HTMLCode.s="<!DOCTYPE html>"+
               "<html>"+
               "  <head>"+
               "    <meta charset='utf-8'>"+
               "    <meta http-equiv='X-UA-Compatible' content='IE=edge'>"+
               "    <meta name='viewport' content='width=device-width, initial-scale=1'>"+
               "    <title>Default Page In IFRAME container</title>"+  
               "  </head>"+
               "  <body>"+
               "  <h1>Hello, World!</h1>"+
               "  <a onclick='"+callAddLine+";return false;' href='#' >Add line </a><br/>"+
               "  <a onclick='"+callAlert1+";return false;' href='#' >Show Spiderbasic message</a><br/>"+
               "  <a onclick="+#DQUOTE$+callAlert2+";return false;"+#DQUOTE$+" href='#' >Show Purebasic message</a>"+
               "  </body>"+
               "</html>" 
    SetWebGadgetHTMLText(1,HTMLCode)    
    
    ButtonGadget(2,5,5, 200,20,"Add Line")
  EndIf
CompilerEndIf
AZJIO
Posts: 73
Joined: Wed Dec 14, 2022 1:13 pm

Re: Set WebGadget HTML content + call parent page commands

Post by AZJIO »

I added a text replacement to highlight operators, functions, numbers in the opened file.

Code: Select all

EnableExplicit

Global g_id_file, g_Format
Global flgThemes, tmp$
Global cmdAddLine, cmdAddLine2, callAddChildLine.s, callAddParentLine.s, HTMLCode.s

XIncludeFile "WebGadgetUtils.sbi"

#Menu = 0
Enumeration
	#Window
	#WebGadget
EndEnumeration

Procedure ReadCallback(Status, Filename$, File, Size)
	Protected Text$
	If Status = #PB_Status_Loaded
		; Debug "File: " + Filename$ + " - Size: " + Size + " bytes"
		g_Format = ReadStringFormat(File)
		Text$ = ReadString(File, g_Format | #PB_File_IgnoreEOL)
; 		Text$ = ReplaceString(Text$, "Text$", "<b class='red'>Text$</b>")
		! v_text$ = v_text$.replace("&", "&amp;")
		! v_text$ = v_text$.replace(">", "&gt;")
		! v_text$ = v_text$.replace("<", "&lt;")
		! v_text$ = v_text$.replace(/[=,*\\/()+-]+?/gm, "<font class='red'>$&</font>")
		! v_text$ = v_text$.replace(/\b(?<!#)[a-z]\w+?(?:\.[sbuacif])?(?=\s*\<font class='red'\>[=,)]\<\/font\>)/gmi, "<font class='var'>$&</font>")
		! v_text$ = v_text$.replace(/\b(If|EndIf|Else|ElseIf|EndProcedure|Procedure|Protected|Global|Debug|Case|Select|EndSelect|Until|Repeat)\b/gm, "<font class='kw'>$&</font>")
		! v_text$ = v_text$.replace(/#\w+?/gm, "<font class='fuchsia'>$&</font>")
; 		! v_text$ = v_text$.replace(/(\w+)(?=\()/gm, "<font class='aqua'>$1</font>")
		! v_text$ = v_text$.replace(/(\w+?)(?=\<font class\='red'\>\(\<\/font\>)/gm, "<font class='func'>$1</font>")
		! v_text$ = v_text$.replace(/(?<![a-z])\d+?/gm, "<font class='num'>$&</font>")
		! v_text$ = v_text$.replace(/@/gm, "<font class='yellow'>$&</font>")
		! v_text$ = v_text$.replace(/\w+?\$/gm, "<font class='var'>$&</font>")
; 		! v_text$ = v_text$.replace(/^[ \t]*?;.*?$/gm, "<font class='green'>$&</font>")
		! v_text$ = v_text$.replace(/;[^"]*?$/gm, "<font class='green'>$&</font>")
		! v_text$ = v_text$.replace(/\".+?\"/gm, "<font class='str1'>$&</font>")
; 		! v_text$ = v_text$.replace(/(\d+\.\d+\.\d+)/g, "<font class='yellow'>$1</font>")
		AddWebGadgetElement(#WebGadget, "<pre>" +Text$ + "</pre>","body")
		CloseFile(File)
	ElseIf Status = #PB_Status_Error
		MessageRequester("Failed to open file: " + #CRLF$ + Filename$)
	EndIf
EndProcedure

Procedure OpenFileRequesterCallback()
	If NextSelectedFile()
		g_id_file = ReadFile(#PB_Any, SelectedFileID(), @ReadCallback(), #PB_LocalFile)
	EndIf
EndProcedure

Procedure ChooseFile()
	OpenFileRequester("*.*", @OpenFileRequesterCallback())
EndProcedure

Procedure OpenFileName()
	OpenFileRequester("*.*", @OpenFileRequesterCallback())
EndProcedure

Procedure Clear()
	SetWebGadgetHTMLText(#WebGadget,HTMLCode)
EndProcedure

Enumeration
	#mOpen
	#mClear
EndEnumeration

Procedure EventsMenu()
	Select EventMenu()
		Case #mOpen
			ChooseFile()
		Case #mClear
			Clear()
	EndSelect
EndProcedure

If OpenWindow(#Window, 0, 0, 0, 0, "FullScreen Window", #PB_Window_Background)
	If CreateMenu(#Menu, WindowID(#Window))
		MenuTitle("Файл")
		MenuItem(#mOpen, "Open")
		MenuBar()
		MenuItem(#mClear, "Clear")
	EndIf
	BindEvent(#PB_Event_Menu, @EventsMenu())

; 	cmdAddLine=AddPageCommand(@OpenFileName())
; 	cmdAddLine2=AddPageCommand(@Clear())
; 	callAddChildLine=CallPageCommand(cmdAddLine)
; 	Debug callAddChildLine
; 	callAddParentLine=CallPageCommand(cmdAddLine2)
; 	Debug callAddParentLine
	HTMLCode="<!DOCTYPE html>"+
		"<html>"+
		"  <head>"+
		"    <meta charset='utf-8'>"+
		"    <meta http-equiv='X-UA-Compatible' content='IE=edge'>"+
		"    <meta name='viewport' content='width=device-width, initial-scale=1'>"+
		"    <title>Inside IFRAME</title>"+
; 		"   <link type='text/css' rel='stylesheet' href='styles.css'>"+
		"  <style>"+
		"  .red{color: #ff8888}"+
		"  .green{color: #71ae71}"+
		"  .kw{color: #009fff}"+
		"  .func{color: #AAA6DB}"+
		"  .yellow{color: #f3cf70}"+
		"  .num{color: #ebcb9c}"+
		"  .str1{color: #aaaaaa}"+
		"  .purple{color: #ff88ff}"+
		"  .var{color: #D29A6C}"+
		"  </style>"+
		"  </head>"+
		"  <body style='background:#333;font-size:20px;color:#aaa'>"+
; 		"  <input type='button' onclick='"+callAddChildLine+";return false;' value='Open' /><br/>"+
; 		"  <input type='button' onclick='"+callAddParentLine+";return false;' value='Clear' /><br/>"+
		"  </body>"+
		"</html>"
	WebGadget(#WebGadget,0,0,800,600,"")
	SetWebGadgetHTMLText(#WebGadget,HTMLCode)
EndIf
Post Reply