Any idea for #PB_Web_Busy with WebViewGadget? or other WebPageLoaded procedure?

Just starting out? Need help? Post your questions and find answers here.
zikitrake
Addict
Addict
Posts: 868
Joined: Thu Mar 25, 2004 2:15 pm
Location: Spain

Any idea for #PB_Web_Busy with WebViewGadget? or other WebPageLoaded procedure?

Post by zikitrake »

Is there any way to emulate WebGadget -> GetGadgetAttribute(*Gadget, #PB_Web_Busy) s in the new gadget WebViewGadget?

Or another way to ensure that a website has loaded completely.

Thank you in advance!

PD: PB 6.20 beta 4
PB 6.21 beta, PureVision User
zikitrake
Addict
Addict
Posts: 868
Joined: Thu Mar 25, 2004 2:15 pm
Location: Spain

Re: Any idea for #PB_Web_Busy with WebViewGadget? or other WebPageLoaded procedure?

Post by zikitrake »

For the classic WebGadget I use this procedure:

Code: Select all

Procedure Web_NoBusy(idGadgetWeb.i, timeOutMax.i = 20000)
  
  Protected timerIni

  timerIni = ElapsedMilliseconds()

  While GetGadgetAttribute(idGadgetWeb, #PB_Web_Busy) <> 0
    WindowEvent()
    Delay(10)
    If ElapsedMilliseconds() - timerIni > timeOutMax
      Break
    EndIf
  Wend
  
EndProcedure
But I have no idea how to convert it for WebViewGadget :o
PB 6.21 beta, PureVision User
dige
Addict
Addict
Posts: 1391
Joined: Wed Apr 30, 2003 8:15 am
Location: Germany
Contact:

Re: Any idea for #PB_Web_Busy with WebViewGadget? or other WebPageLoaded procedure?

Post by dige »

With the WebViewGadget() you can use the code injection trick. So query “DOMContentLoaded” via addEventListener and have it reported back

https://www.purebasic.fr/english/viewto ... ed#p620606
"Daddy, I'll run faster, then it is not so far..."
zikitrake
Addict
Addict
Posts: 868
Joined: Thu Mar 25, 2004 2:15 pm
Location: Spain

Re: Any idea for #PB_Web_Busy with WebViewGadget? or other WebPageLoaded procedure?

Post by zikitrake »

dige wrote: Fri Jan 31, 2025 2:05 pm With the WebViewGadget() you can use the code injection trick. So query “DOMContentLoaded” via addEventListener and have it reported back

https://www.purebasic.fr/english/viewto ... ed#p620606
Nice! Thank you, I'll try at night. Have a nice weekend!!
PB 6.21 beta, PureVision User
infratec
Always Here
Always Here
Posts: 7575
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Any idea for #PB_Web_Busy with WebViewGadget? or other WebPageLoaded procedure?

Post by infratec »

Code: Select all

;----------------------------------------------------------------------------------------
; https://learn.microsoft.com/en-us/microsoft-edge/webview2/concepts/navigation-events

DataSection
  IID_IUnknown:
  Data.l $00000000
  Data.w $0000, $0000
  Data.b $C0, $00, $00, $00, $00, $00, $00, $46
EndDataSection

Structure IUnknownBase_Structure
  *pVtbl
  *pQueryInterface
  *pAddRef
  *pRelease
  *pInvoke
  
  lRefCount.l
  Token.q
EndStructure

Structure ICoreWebView2NavigationCompletedEventHandler_Structure Extends IUnknownBase_Structure
  *pFunction
EndStructure

Structure ICoreWebView2ContentLoadingEventHandler_Structure Extends IUnknownBase_Structure
  *pFunction
EndStructure


Global NewMap NavigationCompletedEventHandler.ICoreWebView2NavigationCompletedEventHandler_Structure()

Procedure.l ICoreWebView2NavigationCompletedEventHandler_QueryInterface(*this.IUnknownBase_Structure, *riid.IID, *ppvObject.Integer)
  If *ppvObject And *riid
    If CompareMemory(*riid, ?IID_IUnknown, SizeOf(IID))
      *this\lRefCount + 1
      *ppvObject\i = *this
    Else
      *ppvObject\i = 0
      ProcedureReturn #E_NOINTERFACE
    EndIf
  Else
    ProcedureReturn #E_POINTER
  EndIf
  ProcedureReturn #S_OK
EndProcedure

Procedure.l ICoreWebView2NavigationCompletedEventHandler_AddRef(*this.IUnknownBase_Structure)
  *this\lRefCount + 1
  ProcedureReturn *this\lRefCount
EndProcedure

Procedure.l ICoreWebView2NavigationCompletedEventHandler_Release(*this.IUnknownBase_Structure)
  *this\lRefCount - 1
  ProcedureReturn *this\lRefCount
EndProcedure

Procedure.l ICoreWebView2NavigationCompletedEventHandler_Invoke(*this.ICoreWebView2NavigationCompletedEventHandler_Structure, *sender.ICoreWebView2, *args.ICoreWebView2NavigationCompletedEventArgs)
  Protected isSuccess, *uri, uri.s
  
  If *args And *args\get_IsSuccess(@isSuccess) = #S_OK And isSuccess
    If *sender
      If *sender\get_Source(@*uri) = #S_OK
        If *uri
          uri = PeekS(*uri)
          If *this\pFunction
            CallFunctionFast(*this\pFunction, @uri)
          EndIf
          CoTaskMemFree_(*uri)
        EndIf
      EndIf
    EndIf
  EndIf
  
  ProcedureReturn #S_OK
  
EndProcedure


Procedure.i WebViewSetNavigateCompleteEventHandler(WebView, *EventHandler)
  
  Protected Result.i
  Protected Controller.ICoreWebView2Controller, Core.ICoreWebView2
  Protected *NavigationCompletedEventHandler.ICoreWebView2NavigationCompletedEventHandler_Structure
  Protected Token.q
  
  
  If GadgetType(WebView) = #PB_GadgetType_WebView And *EventHandler <> #Null
    
    Controller = GetGadgetAttribute(WebView, #PB_WebView_ICoreController)
    If Controller
      
      If Controller\get_CoreWebView2(@Core) = #S_OK And Core <> #Null
        
        If FindMapElement(NavigationCompletedEventHandler(), Str(WebView))
          If NavigationCompletedEventHandler()\Token
            Core\remove_NavigationCompleted(NavigationCompletedEventHandler()\Token)
          EndIf
          DeleteMapElement(NavigationCompletedEventHandler())
        EndIf
        
        *NavigationCompletedEventHandler = AddMapElement(NavigationCompletedEventHandler(), Str(WebView))
        If *NavigationCompletedEventHandler
          
          *NavigationCompletedEventHandler\pVtbl = *NavigationCompletedEventHandler + OffsetOf(IUnknownBase_Structure\pQueryInterface)
          *NavigationCompletedEventHandler\pQueryInterface = @ICoreWebView2NavigationCompletedEventHandler_QueryInterface()
          *NavigationCompletedEventHandler\pAddRef         = @ICoreWebView2NavigationCompletedEventHandler_AddRef()
          *NavigationCompletedEventHandler\pRelease        = @ICoreWebView2NavigationCompletedEventHandler_Release()
          *NavigationCompletedEventHandler\pInvoke         = @ICoreWebView2NavigationCompletedEventHandler_Invoke()
          
          *NavigationCompletedEventHandler\pFunction = *EventHandler
          
          If Core\add_NavigationCompleted(*NavigationCompletedEventHandler, @*NavigationCompletedEventHandler\Token) = #S_OK
            Result = #True
          Else
            DeleteMapElement(NavigationCompletedEventHandler())
          EndIf
          
        EndIf
        
      EndIf
      
      Core\Release()
    EndIf
  EndIf
  
  ProcedureReturn Result
  
EndProcedure


Global NewMap ContentLoadingEventHandler.ICoreWebView2ContentLoadingEventHandler_Structure()

Procedure.l ICoreWebView2ContentLoadingEventHandler_QueryInterface(*this.IUnknownBase_Structure, *riid.IID, *ppvObject.Integer)
  If *ppvObject And *riid
    If CompareMemory(*riid, ?IID_IUnknown, SizeOf(IID))
      *this\lRefCount + 1
      *ppvObject\i = *this
    Else
      *ppvObject\i = 0
      ProcedureReturn #E_NOINTERFACE
    EndIf
  Else
    ProcedureReturn #E_POINTER
  EndIf
  ProcedureReturn #S_OK
EndProcedure

Procedure.l ICoreWebView2ContentLoadingEventHandler_AddRef(*this.IUnknownBase_Structure)
  *this\lRefCount + 1
  ProcedureReturn *this\lRefCount
EndProcedure

Procedure.l ICoreWebView2ContentLoadingEventHandler_Release(*this.IUnknownBase_Structure)
  *this\lRefCount - 1
  ProcedureReturn *this\lRefCount
EndProcedure

Procedure.l ICoreWebView2ContentLoadingEventHandler_Invoke(*this.ICoreWebView2ContentLoadingEventHandler_Structure, *sender.ICoreWebView2, *args.ICoreWebView2ContentLoadingEventArgs)
  
  Protected isSuccess, *uri, uri.s
  
  ;If *args And *args\get_IsSuccess(@isSuccess) = #S_OK And isSuccess
  If *sender
    If *sender\get_Source(@*uri) = #S_OK
      If *uri
        uri = PeekS(*uri)
        If *this\pFunction
          CallFunctionFast(*this\pFunction, @uri)
        EndIf
        CoTaskMemFree_(*uri)
      EndIf
    EndIf
  EndIf
  ;EndIf
  
  ProcedureReturn #S_OK
EndProcedure



Procedure.i WebViewSetContentLoadingEventHandler(WebView, *EventHandler)
  
  Protected Result.i
  Protected Controller.ICoreWebView2Controller, Core.ICoreWebView2
  Protected *ContentLoadingEventHandler.ICoreWebView2ContentLoadingEventHandler_Structure
  Protected Token.q
  
  
  If GadgetType(WebView) = #PB_GadgetType_WebView And *EventHandler <> #Null
    
    Controller = GetGadgetAttribute(WebView, #PB_WebView_ICoreController)
    If Controller
      
      If Controller\get_CoreWebView2(@Core) = #S_OK 
        If Core
          
          If FindMapElement(ContentLoadingEventHandler(), Str(WebView))
            If ContentLoadingEventHandler()\Token
              Core\remove_ContentLoading(ContentLoadingEventHandler()\Token)
            EndIf
            DeleteMapElement(ContentLoadingEventHandler())
          EndIf
          
          *ContentLoadingEventHandler = AddMapElement(ContentLoadingEventHandler(), Str(WebView))
          
          
          If *ContentLoadingEventHandler
            
            *ContentLoadingEventHandler\pVtbl = *ContentLoadingEventHandler + OffsetOf(IUnknownBase_Structure\pQueryInterface)
            *ContentLoadingEventHandler\pQueryInterface = @ICoreWebView2ContentLoadingEventHandler_QueryInterface()
            *ContentLoadingEventHandler\pAddRef         = @ICoreWebView2ContentLoadingEventHandler_AddRef()
            *ContentLoadingEventHandler\pRelease        = @ICoreWebView2ContentLoadingEventHandler_Release()
            *ContentLoadingEventHandler\pInvoke         = @ICoreWebView2ContentLoadingEventHandler_Invoke()
            
            *ContentLoadingEventHandler\pFunction = *EventHandler
            
            If Core\add_ContentLoading(*ContentLoadingEventHandler, @*ContentLoadingEventHandler\Token) = #S_OK
              ;Debug *ContentLoadingEventHandler\Token
              Result = #True
            Else
              DeleteMapElement(ContentLoadingEventHandler())
            EndIf
            
          EndIf
          
          Core\Release()
        EndIf
      EndIf
    EndIf
  EndIf
  
  ProcedureReturn Result
  
EndProcedure


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


Global WebView2_Busy.i

Procedure ContentLoading(uri.s)
  Debug "Loading: " + uri
  WebView2_Busy = #True
EndProcedure


Procedure NaviComplete(uri.s)
  Debug "Loaded: " + uri
  WebView2_Busy = #False
EndProcedure


OpenWindow(0, 0, 0, 1000, 900, "", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)

StringGadget(0, 0, 0, 400, 30, "https://www.purebasic.com")
ButtonGadget(1, 410, 0, 50, 30, "Go")
WebViewGadget(2, 0, 35, 1000, 900)

WebViewSetContentLoadingEventHandler(2, @ContentLoading())
WebViewSetNavigateCompleteEventHandler(2, @NaviComplete())


SetGadgetText(2, "file://" + #PB_Compiler_Home + "examples/sources/Data/WebView/webview.html")

AddWindowTimer(0, 1, 100)

Repeat 
  Event = WaitWindowEvent()
  If Event = #PB_Event_Timer
    If EventTimer() = 1
      If WebView2_Busy
        Debug "WebView is Busy"
      EndIf
    EndIf
  EndIf
  If Event = #PB_Event_Gadget
    If EventGadget() = 1
      SetGadgetText(2, Trim(GetGadgetText(0)))
    EndIf
  EndIf
Until Event = #PB_Event_CloseWindow
dige
Addict
Addict
Posts: 1391
Joined: Wed Apr 30, 2003 8:15 am
Location: Germany
Contact:

Re: Any idea for #PB_Web_Busy with WebViewGadget? or other WebPageLoaded procedure?

Post by dige »

Great! Thx a lot infratec! :D
"Daddy, I'll run faster, then it is not so far..."
zikitrake
Addict
Addict
Posts: 868
Joined: Thu Mar 25, 2004 2:15 pm
Location: Spain

Re: Any idea for #PB_Web_Busy with WebViewGadget? or other WebPageLoaded procedure?

Post by zikitrake »

@infratec, @dige Thank you so much for bailing me out!

This last code works great for me! :D
PB 6.21 beta, PureVision User
zikitrake
Addict
Addict
Posts: 868
Joined: Thu Mar 25, 2004 2:15 pm
Location: Spain

Re: Any idea for #PB_Web_Busy with WebViewGadget? or other WebPageLoaded procedure?

Post by zikitrake »

infratec wrote: Sun Feb 02, 2025 3:56 pm
I'm trying your code but it only works when a full webpage is loaded, no?

In this example, if I change in the left window the name "Jani" to "Peter", and click in "Run" button It don't detect any change in the web.

Code: Select all

;----------------------------------------------------------------------------------------
; https://learn.microsoft.com/en-us/microsoft-edge/webview2/concepts/navigation-events

DataSection
  IID_IUnknown:
  Data.l $00000000
  Data.w $0000, $0000
  Data.b $C0, $00, $00, $00, $00, $00, $00, $46
EndDataSection

Structure IUnknownBase_Structure
  *pVtbl
  *pQueryInterface
  *pAddRef
  *pRelease
  *pInvoke
  
  lRefCount.l
  Token.q
EndStructure

Structure ICoreWebView2NavigationCompletedEventHandler_Structure Extends IUnknownBase_Structure
  *pFunction
EndStructure

Structure ICoreWebView2ContentLoadingEventHandler_Structure Extends IUnknownBase_Structure
  *pFunction
EndStructure


Global NewMap NavigationCompletedEventHandler.ICoreWebView2NavigationCompletedEventHandler_Structure()

Procedure.l ICoreWebView2NavigationCompletedEventHandler_QueryInterface(*this.IUnknownBase_Structure, *riid.IID, *ppvObject.Integer)
  If *ppvObject And *riid
    If CompareMemory(*riid, ?IID_IUnknown, SizeOf(IID))
      *this\lRefCount + 1
      *ppvObject\i = *this
    Else
      *ppvObject\i = 0
      ProcedureReturn #E_NOINTERFACE
    EndIf
  Else
    ProcedureReturn #E_POINTER
  EndIf
  ProcedureReturn #S_OK
EndProcedure

Procedure.l ICoreWebView2NavigationCompletedEventHandler_AddRef(*this.IUnknownBase_Structure)
  *this\lRefCount + 1
  ProcedureReturn *this\lRefCount
EndProcedure

Procedure.l ICoreWebView2NavigationCompletedEventHandler_Release(*this.IUnknownBase_Structure)
  *this\lRefCount - 1
  ProcedureReturn *this\lRefCount
EndProcedure

Procedure.l ICoreWebView2NavigationCompletedEventHandler_Invoke(*this.ICoreWebView2NavigationCompletedEventHandler_Structure, *sender.ICoreWebView2, *args.ICoreWebView2NavigationCompletedEventArgs)
  Protected isSuccess, *uri, uri.s
  
  If *args And *args\get_IsSuccess(@isSuccess) = #S_OK And isSuccess
    If *sender
      If *sender\get_Source(@*uri) = #S_OK
        If *uri
          uri = PeekS(*uri)
          If *this\pFunction
            CallFunctionFast(*this\pFunction, @uri)
          EndIf
          CoTaskMemFree_(*uri)
        EndIf
      EndIf
    EndIf
  EndIf
  
  ProcedureReturn #S_OK
  
EndProcedure


Procedure.i WebViewSetNavigateCompleteEventHandler(WebView, *EventHandler)
  
  Protected Result.i
  Protected Controller.ICoreWebView2Controller, Core.ICoreWebView2
  Protected *NavigationCompletedEventHandler.ICoreWebView2NavigationCompletedEventHandler_Structure
  Protected Token.q
  
  
  If GadgetType(WebView) = #PB_GadgetType_WebView And *EventHandler <> #Null
    
    Controller = GetGadgetAttribute(WebView, #PB_WebView_ICoreController)
    If Controller
      
      If Controller\get_CoreWebView2(@Core) = #S_OK And Core <> #Null
        
        If FindMapElement(NavigationCompletedEventHandler(), Str(WebView))
          If NavigationCompletedEventHandler()\Token
            Core\remove_NavigationCompleted(NavigationCompletedEventHandler()\Token)
          EndIf
          DeleteMapElement(NavigationCompletedEventHandler())
        EndIf
        
        *NavigationCompletedEventHandler = AddMapElement(NavigationCompletedEventHandler(), Str(WebView))
        If *NavigationCompletedEventHandler
          
          *NavigationCompletedEventHandler\pVtbl = *NavigationCompletedEventHandler + OffsetOf(IUnknownBase_Structure\pQueryInterface)
          *NavigationCompletedEventHandler\pQueryInterface = @ICoreWebView2NavigationCompletedEventHandler_QueryInterface()
          *NavigationCompletedEventHandler\pAddRef         = @ICoreWebView2NavigationCompletedEventHandler_AddRef()
          *NavigationCompletedEventHandler\pRelease        = @ICoreWebView2NavigationCompletedEventHandler_Release()
          *NavigationCompletedEventHandler\pInvoke         = @ICoreWebView2NavigationCompletedEventHandler_Invoke()
          
          *NavigationCompletedEventHandler\pFunction = *EventHandler
          
          If Core\add_NavigationCompleted(*NavigationCompletedEventHandler, @*NavigationCompletedEventHandler\Token) = #S_OK
            Result = #True
          Else
            DeleteMapElement(NavigationCompletedEventHandler())
          EndIf
          
        EndIf
        
      EndIf
      
      Core\Release()
    EndIf
  EndIf
  
  ProcedureReturn Result
  
EndProcedure


Global NewMap ContentLoadingEventHandler.ICoreWebView2ContentLoadingEventHandler_Structure()

Procedure.l ICoreWebView2ContentLoadingEventHandler_QueryInterface(*this.IUnknownBase_Structure, *riid.IID, *ppvObject.Integer)
  If *ppvObject And *riid
    If CompareMemory(*riid, ?IID_IUnknown, SizeOf(IID))
      *this\lRefCount + 1
      *ppvObject\i = *this
    Else
      *ppvObject\i = 0
      ProcedureReturn #E_NOINTERFACE
    EndIf
  Else
    ProcedureReturn #E_POINTER
  EndIf
  ProcedureReturn #S_OK
EndProcedure

Procedure.l ICoreWebView2ContentLoadingEventHandler_AddRef(*this.IUnknownBase_Structure)
  *this\lRefCount + 1
  ProcedureReturn *this\lRefCount
EndProcedure

Procedure.l ICoreWebView2ContentLoadingEventHandler_Release(*this.IUnknownBase_Structure)
  *this\lRefCount - 1
  ProcedureReturn *this\lRefCount
EndProcedure

Procedure.l ICoreWebView2ContentLoadingEventHandler_Invoke(*this.ICoreWebView2ContentLoadingEventHandler_Structure, *sender.ICoreWebView2, *args.ICoreWebView2ContentLoadingEventArgs)
  
  Protected isSuccess, *uri, uri.s
  
  ;If *args And *args\get_IsSuccess(@isSuccess) = #S_OK And isSuccess
  If *sender
    If *sender\get_Source(@*uri) = #S_OK
      If *uri
        uri = PeekS(*uri)
        If *this\pFunction
          CallFunctionFast(*this\pFunction, @uri)
        EndIf
        CoTaskMemFree_(*uri)
      EndIf
    EndIf
  EndIf
  ;EndIf
  
  ProcedureReturn #S_OK
EndProcedure



Procedure.i WebViewSetContentLoadingEventHandler(WebView, *EventHandler)
  
  Protected Result.i
  Protected Controller.ICoreWebView2Controller, Core.ICoreWebView2
  Protected *ContentLoadingEventHandler.ICoreWebView2ContentLoadingEventHandler_Structure
  Protected Token.q
  
  
  If GadgetType(WebView) = #PB_GadgetType_WebView And *EventHandler <> #Null
    
    Controller = GetGadgetAttribute(WebView, #PB_WebView_ICoreController)
    If Controller
      
      If Controller\get_CoreWebView2(@Core) = #S_OK 
        If Core
          
          If FindMapElement(ContentLoadingEventHandler(), Str(WebView))
            If ContentLoadingEventHandler()\Token
              Core\remove_ContentLoading(ContentLoadingEventHandler()\Token)
            EndIf
            DeleteMapElement(ContentLoadingEventHandler())
          EndIf
          
          *ContentLoadingEventHandler = AddMapElement(ContentLoadingEventHandler(), Str(WebView))
          
          
          If *ContentLoadingEventHandler
            
            *ContentLoadingEventHandler\pVtbl = *ContentLoadingEventHandler + OffsetOf(IUnknownBase_Structure\pQueryInterface)
            *ContentLoadingEventHandler\pQueryInterface = @ICoreWebView2ContentLoadingEventHandler_QueryInterface()
            *ContentLoadingEventHandler\pAddRef         = @ICoreWebView2ContentLoadingEventHandler_AddRef()
            *ContentLoadingEventHandler\pRelease        = @ICoreWebView2ContentLoadingEventHandler_Release()
            *ContentLoadingEventHandler\pInvoke         = @ICoreWebView2ContentLoadingEventHandler_Invoke()
            
            *ContentLoadingEventHandler\pFunction = *EventHandler
            
            If Core\add_ContentLoading(*ContentLoadingEventHandler, @*ContentLoadingEventHandler\Token) = #S_OK
              ;Debug *ContentLoadingEventHandler\Token
              Result = #True
            Else
              DeleteMapElement(ContentLoadingEventHandler())
            EndIf
            
          EndIf
          
          Core\Release()
        EndIf
      EndIf
    EndIf
  EndIf
  
  ProcedureReturn Result
  
EndProcedure


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


Global WebView2_Busy.i

Procedure ContentLoading(uri.s)
  Debug "Loading: " + uri
  WebView2_Busy = #True
EndProcedure


Procedure NaviComplete(uri.s)
  Debug "Loaded: " + uri
  WebView2_Busy = #False
EndProcedure


OpenWindow(0, 0, 0, 1000, 900, "", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)

StringGadget(0, 0, 0, 400, 30, "https://www.w3schools.com/xml/tryit.asp?filename=tryxml_parsertest2")
ButtonGadget(1, 410, 0, 50, 30, "Go")
WebViewGadget(2, 0, 35, 1000, 900)

WebViewSetContentLoadingEventHandler(2, @ContentLoading())
WebViewSetNavigateCompleteEventHandler(2, @NaviComplete())


SetGadgetText(2, "https://www.w3schools.com/xml/tryit.asp?filename=tryxml_parsertest2")

AddWindowTimer(0, 1, 100)

Repeat 
  Event = WaitWindowEvent()
  If Event = #PB_Event_Timer
    If EventTimer() = 1
      If WebView2_Busy
        Debug "WebView is Busy"
      EndIf
    EndIf
  EndIf
  If Event = #PB_Event_Gadget
    If EventGadget() = 1
      SetGadgetText(2, Trim(GetGadgetText(0)))
    EndIf
  EndIf
Until Event = #PB_Event_CloseWindow
I tried with "https://www.openstreetmap.org/" too with the same results... I assume this is normal, but is there any possibility to detect this change with some changes in your code?

I understand that the mistake is mine when I wrote the title and content of this post, because I implied that I was only looking to detect when a page finished loading, and not also when that page experienced a change.

Thank you and sorry for my bad english
PB 6.21 beta, PureVision User
zikitrake
Addict
Addict
Posts: 868
Joined: Thu Mar 25, 2004 2:15 pm
Location: Spain

Re: Any idea for #PB_Web_Busy with WebViewGadget? or other WebPageLoaded procedure?

Post by zikitrake »

following in @infratec 's footst, I just tried adding a new procedure: WebViewSetSourceChangedEventHandler() to try detect when a page experienced a change, but it don't works either... I'll continue with my experiments :lol:

Code: Select all

;----------------------------------------------------------------------------------------
; https://learn.microsoft.com/en-us/microsoft-edge/webview2/concepts/navigation-events

DataSection
  IID_IUnknown:
  Data.l $00000000
  Data.w $0000, $0000
  Data.b $C0, $00, $00, $00, $00, $00, $00, $46
EndDataSection

Structure IUnknownBase_Structure
  *pVtbl
  *pQueryInterface
  *pAddRef
  *pRelease
  *pInvoke
  
  lRefCount.l
  Token.q
EndStructure

Structure ICoreWebView2NavigationCompletedEventHandler_Structure Extends IUnknownBase_Structure
  *pFunction
EndStructure

Structure ICoreWebView2ContentLoadingEventHandler_Structure Extends IUnknownBase_Structure
  *pFunction
EndStructure

Structure ICoreWebView2SourceChangedEventHandler_Structure Extends IUnknownBase_Structure
  *pFunction
EndStructure


Global NewMap NavigationCompletedEventHandler.ICoreWebView2NavigationCompletedEventHandler_Structure()
Procedure.l ICoreWebView2NavigationCompletedEventHandler_QueryInterface(*this.IUnknownBase_Structure, *riid.IID, *ppvObject.Integer)
  If *ppvObject And *riid
    If CompareMemory(*riid, ?IID_IUnknown, SizeOf(IID))
      *this\lRefCount + 1
      *ppvObject\i = *this
    Else
      *ppvObject\i = 0
      ProcedureReturn #E_NOINTERFACE
    EndIf
  Else
    ProcedureReturn #E_POINTER
  EndIf
  ProcedureReturn #S_OK
EndProcedure
Procedure.l ICoreWebView2NavigationCompletedEventHandler_AddRef(*this.IUnknownBase_Structure)
  *this\lRefCount + 1
  ProcedureReturn *this\lRefCount
EndProcedure
Procedure.l ICoreWebView2NavigationCompletedEventHandler_Release(*this.IUnknownBase_Structure)
  *this\lRefCount - 1
  ProcedureReturn *this\lRefCount
EndProcedure
Procedure.l ICoreWebView2NavigationCompletedEventHandler_Invoke(*this.ICoreWebView2NavigationCompletedEventHandler_Structure, *sender.ICoreWebView2, *args.ICoreWebView2NavigationCompletedEventArgs)
  Protected isSuccess, *uri, uri.s
  
  If *args And *args\get_IsSuccess(@isSuccess) = #S_OK And isSuccess
    If *sender
      If *sender\get_Source(@*uri) = #S_OK
        If *uri
          uri = PeekS(*uri)
          If *this\pFunction
            CallFunctionFast(*this\pFunction, @uri)
          EndIf
          CoTaskMemFree_(*uri)
        EndIf
      EndIf
    EndIf
  EndIf
  
  ProcedureReturn #S_OK
  
EndProcedure

Procedure.i WebViewSetNavigateCompleteEventHandler(WebView, *EventHandler)
  
  Protected Result.i
  Protected Controller.ICoreWebView2Controller, Core.ICoreWebView2
  Protected *NavigationCompletedEventHandler.ICoreWebView2NavigationCompletedEventHandler_Structure
  Protected Token.q
  
  
  If GadgetType(WebView) = #PB_GadgetType_WebView And *EventHandler <> #Null
    
    Controller = GetGadgetAttribute(WebView, #PB_WebView_ICoreController)
    If Controller
      
      If Controller\get_CoreWebView2(@Core) = #S_OK And Core <> #Null
        
        If FindMapElement(NavigationCompletedEventHandler(), Str(WebView))
          If NavigationCompletedEventHandler()\Token
            Core\remove_NavigationCompleted(NavigationCompletedEventHandler()\Token)
          EndIf
          DeleteMapElement(NavigationCompletedEventHandler())
        EndIf
        
        *NavigationCompletedEventHandler = AddMapElement(NavigationCompletedEventHandler(), Str(WebView))
        If *NavigationCompletedEventHandler
          
          *NavigationCompletedEventHandler\pVtbl = *NavigationCompletedEventHandler + OffsetOf(IUnknownBase_Structure\pQueryInterface)
          *NavigationCompletedEventHandler\pQueryInterface = @ICoreWebView2NavigationCompletedEventHandler_QueryInterface()
          *NavigationCompletedEventHandler\pAddRef         = @ICoreWebView2NavigationCompletedEventHandler_AddRef()
          *NavigationCompletedEventHandler\pRelease        = @ICoreWebView2NavigationCompletedEventHandler_Release()
          *NavigationCompletedEventHandler\pInvoke         = @ICoreWebView2NavigationCompletedEventHandler_Invoke()
          
          *NavigationCompletedEventHandler\pFunction = *EventHandler
          
          If Core\add_NavigationCompleted(*NavigationCompletedEventHandler, @*NavigationCompletedEventHandler\Token) = #S_OK
            Result = #True
          Else
            DeleteMapElement(NavigationCompletedEventHandler())
          EndIf
          
        EndIf
        
      EndIf
      
      Core\Release()
    EndIf
  EndIf
  
  ProcedureReturn Result
  
EndProcedure


Global NewMap ContentLoadingEventHandler.ICoreWebView2ContentLoadingEventHandler_Structure()
Procedure.l ICoreWebView2ContentLoadingEventHandler_QueryInterface(*this.IUnknownBase_Structure, *riid.IID, *ppvObject.Integer)
  If *ppvObject And *riid
    If CompareMemory(*riid, ?IID_IUnknown, SizeOf(IID))
      *this\lRefCount + 1
      *ppvObject\i = *this
    Else
      *ppvObject\i = 0
      ProcedureReturn #E_NOINTERFACE
    EndIf
  Else
    ProcedureReturn #E_POINTER
  EndIf
  ProcedureReturn #S_OK
EndProcedure
Procedure.l ICoreWebView2ContentLoadingEventHandler_AddRef(*this.IUnknownBase_Structure)
  *this\lRefCount + 1
  ProcedureReturn *this\lRefCount
EndProcedure
Procedure.l ICoreWebView2ContentLoadingEventHandler_Release(*this.IUnknownBase_Structure)
  *this\lRefCount - 1
  ProcedureReturn *this\lRefCount
EndProcedure
Procedure.l ICoreWebView2ContentLoadingEventHandler_Invoke(*this.ICoreWebView2ContentLoadingEventHandler_Structure, *sender.ICoreWebView2, *args.ICoreWebView2ContentLoadingEventArgs)
  
  Protected isSuccess, *uri, uri.s
  
  ;If *args And *args\get_IsSuccess(@isSuccess) = #S_OK And isSuccess
  If *sender
    If *sender\get_Source(@*uri) = #S_OK
      If *uri
        uri = PeekS(*uri)
        If *this\pFunction
          CallFunctionFast(*this\pFunction, @uri)
        EndIf
        CoTaskMemFree_(*uri)
      EndIf
    EndIf
  EndIf
  ;EndIf
  
  ProcedureReturn #S_OK
EndProcedure

Procedure.i WebViewSetContentLoadingEventHandler(WebView, *EventHandler)
  
  Protected Result.i
  Protected Controller.ICoreWebView2Controller, Core.ICoreWebView2
  Protected *ContentLoadingEventHandler.ICoreWebView2ContentLoadingEventHandler_Structure
  Protected Token.q
  
  
  If GadgetType(WebView) = #PB_GadgetType_WebView And *EventHandler <> #Null
    
    Controller = GetGadgetAttribute(WebView, #PB_WebView_ICoreController)
    If Controller
      
      If Controller\get_CoreWebView2(@Core) = #S_OK 
        If Core
          
          If FindMapElement(ContentLoadingEventHandler(), Str(WebView))
            If ContentLoadingEventHandler()\Token
              Core\remove_ContentLoading(ContentLoadingEventHandler()\Token)
            EndIf
            DeleteMapElement(ContentLoadingEventHandler())
          EndIf
          
          *ContentLoadingEventHandler = AddMapElement(ContentLoadingEventHandler(), Str(WebView))
          
          
          If *ContentLoadingEventHandler
            
            *ContentLoadingEventHandler\pVtbl = *ContentLoadingEventHandler + OffsetOf(IUnknownBase_Structure\pQueryInterface)
            *ContentLoadingEventHandler\pQueryInterface = @ICoreWebView2ContentLoadingEventHandler_QueryInterface()
            *ContentLoadingEventHandler\pAddRef         = @ICoreWebView2ContentLoadingEventHandler_AddRef()
            *ContentLoadingEventHandler\pRelease        = @ICoreWebView2ContentLoadingEventHandler_Release()
            *ContentLoadingEventHandler\pInvoke         = @ICoreWebView2ContentLoadingEventHandler_Invoke()
            
            *ContentLoadingEventHandler\pFunction = *EventHandler
            
            If Core\add_ContentLoading(*ContentLoadingEventHandler, @*ContentLoadingEventHandler\Token) = #S_OK
              ;Debug *ContentLoadingEventHandler\Token
              Result = #True
            Else
              DeleteMapElement(ContentLoadingEventHandler())
            EndIf
            
          EndIf
          
          Core\Release()
        EndIf
      EndIf
    EndIf
  EndIf
  
  ProcedureReturn Result
  
EndProcedure


Global NewMap SourceChangedEventHandler.ICoreWebView2SourceChangedEventHandler_Structure()
Procedure.l ICoreWebView2SourceChangedEventHandler_QueryInterface(*this.IUnknownBase_Structure, *riid.IID, *ppvObject.Integer)
  If *ppvObject And *riid
    If CompareMemory(*riid, ?IID_IUnknown, SizeOf(IID))
      *this\lRefCount + 1
      *ppvObject\i = *this
    Else
      *ppvObject\i = 0
      ProcedureReturn #E_NOINTERFACE
    EndIf
  Else
    ProcedureReturn #E_POINTER
  EndIf
  ProcedureReturn #S_OK
EndProcedure
Procedure.l ICoreWebView2SourceChangedEventHandler_AddRef(*this.IUnknownBase_Structure)
  *this\lRefCount + 1
  ProcedureReturn *this\lRefCount
EndProcedure
Procedure.l ICoreWebView2SourceChangedEventHandler_Release(*this.IUnknownBase_Structure)
  *this\lRefCount - 1
  ProcedureReturn *this\lRefCount
EndProcedure
Procedure.l ICoreWebView2SourceChangedEventHandler_Invoke(*this.ICoreWebView2SourceChangedEventHandler_Structure, *sender.ICoreWebView2, *args.ICoreWebView2SourceChangedEventArgs)
  
  Protected isNewDoc, *uri, uri.s
  
  If *args And *args\get_IsNewDocument(@isNewDoc) = #S_OK And isNewDoc
    If *sender
      If *sender\get_Source(@*uri) = #S_OK
        If *uri
          uri = PeekS(*uri)
          If *this\pFunction
            CallFunctionFast(*this\pFunction, @uri)
          EndIf
          CoTaskMemFree_(*uri)
        EndIf
      EndIf
    EndIf
  EndIf
  Debug isNewDoc
  
EndProcedure

Procedure.i WebViewSetSourceChangedEventHandler(WebView, *EventHandler)
  
  Protected Result.i
  Protected Controller.ICoreWebView2Controller, Core.ICoreWebView2
  Protected *SourceChangedEventHandler.ICoreWebView2SourceChangedEventHandler_Structure
  Protected Token.q
  
  
  If GadgetType(WebView) = #PB_GadgetType_WebView And *EventHandler <> #Null
    
    Controller = GetGadgetAttribute(WebView, #PB_WebView_ICoreController)
    If Controller
      
      If Controller\get_CoreWebView2(@Core) = #S_OK 
        If Core
          
          If FindMapElement(SourceChangedEventHandler(), Str(WebView))
            If SourceChangedEventHandler()\Token
              Core\remove_SourceChanged(SourceChangedEventHandler()\Token)
            EndIf
            DeleteMapElement(SourceChangedEventHandler())
          EndIf
          
          *SourceChangedEventHandler = AddMapElement(SourceChangedEventHandler(), Str(WebView))
          
          
          If *SourceChangedEventHandler
            
            *SourceChangedEventHandler\pVtbl = *SourceChangedEventHandler + OffsetOf(IUnknownBase_Structure\pQueryInterface)
            *SourceChangedEventHandler\pQueryInterface = @ICoreWebView2SourceChangedEventHandler_QueryInterface()
            *SourceChangedEventHandler\pAddRef         = @ICoreWebView2SourceChangedEventHandler_AddRef()
            *SourceChangedEventHandler\pRelease        = @ICoreWebView2SourceChangedEventHandler_Release()
            *SourceChangedEventHandler\pInvoke         = @ICoreWebView2SourceChangedEventHandler_Invoke()
            
            *SourceChangedEventHandler\pFunction = *EventHandler
            
            If Core\add_SourceChanged(*SourceChangedEventHandler, @*SourceChangedEventHandler\Token) = #S_OK
              ;Debug *SourceChangedEventHandler\Token
              Result = #True
            Else
              DeleteMapElement(SourceChangedEventHandler())
            EndIf
            
          EndIf
          
          Core\Release()
        EndIf
      EndIf
    EndIf
  EndIf
  
  ProcedureReturn Result
  
EndProcedure




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


Global WebView2_Busy.b, WebView2_SourceChanged.b

Procedure ContentLoading(uri.s)
  ;Debug "Loading: " + uri
  WebView2_Busy = #True
EndProcedure
Procedure NaviComplete(uri.s)
  ;Debug "Loaded: " + uri
  WebView2_Busy = #False
EndProcedure

Procedure ContentSourceChanged(uri.s)
  Debug "source change: " + uri
  WebView2_SourceChanged = #True
EndProcedure
Procedure ContentSourceEqual(uri.s)
  Debug "source equal: " + uri
  WebView2_SourceChanged = #False
EndProcedure


OpenWindow(0, 0, 0, 1000, 900, "", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)

StringGadget(0, 0, 0, 400, 30, "https://www.w3schools.com/xml/tryit.asp?filename=tryxml_parsertest2")
ButtonGadget(1, 410, 0, 50, 30, "Go")
WebViewGadget(2, 0, 35, 1000, 900)

; WebViewSetContentLoadingEventHandler(2, @ContentLoading())
; WebViewSetNavigateCompleteEventHandler(2, @NaviComplete())

WebViewSetSourceChangedEventHandler(2, @ContentSourceChanged())


SetGadgetText(2, "https://www.w3schools.com/xml/tryit.asp?filename=tryxml_parsertest2")

AddWindowTimer(0, 1, 100)

Repeat 
  Event = WaitWindowEvent()
  If Event = #PB_Event_Timer
    If EventTimer() = 1
      If WebView2_Busy
        ;Debug "WebView is Busy"
      EndIf
      If WebView2_SourceChanged
        Debug "source changed!!!"
        WebView2_SourceChanged = #False
      Else
        Debug "source equal!"
      EndIf
      
    EndIf
  EndIf
  If Event = #PB_Event_Gadget
    If EventGadget() = 1
      SetGadgetText(2, Trim(GetGadgetText(0)))
    EndIf
  EndIf
Until Event = #PB_Event_CloseWindow
PB 6.21 beta, PureVision User
breeze4me
Enthusiast
Enthusiast
Posts: 633
Joined: Thu Mar 09, 2006 9:24 am
Location: S. Kor

Re: Any idea for #PB_Web_Busy with WebViewGadget? or other WebPageLoaded procedure?

Post by breeze4me »

This method will not work for the site “www.openstreetmap.org”, you will need to get the information through MutationObserver or use the API provided by that site.

Code: Select all

;----------------------------------------------------------------------------------------
; https://learn.microsoft.com/en-us/microsoft-edge/webview2/concepts/navigation-events

DataSection
  IID_IUnknown:
  Data.l $00000000
  Data.w $0000, $0000
  Data.b $C0, $00, $00, $00, $00, $00, $00, $46
EndDataSection

Structure IUnknownBase_Structure
  *pVtbl
  *pQueryInterface
  *pAddRef
  *pRelease
  *pInvoke
  
  lRefCount.l
  Token.q
EndStructure

Structure ICoreWebView2NavigationCompletedEventHandler_Structure Extends IUnknownBase_Structure
  *pFunction
EndStructure

Structure ICoreWebView2ContentLoadingEventHandler_Structure Extends IUnknownBase_Structure
  *pFunction
EndStructure


Global NewMap NavigationCompletedEventHandler.ICoreWebView2NavigationCompletedEventHandler_Structure()

Procedure.l ICoreWebView2NavigationCompletedEventHandler_QueryInterface(*this.IUnknownBase_Structure, *riid.IID, *ppvObject.Integer)
  If *ppvObject And *riid
    If CompareMemory(*riid, ?IID_IUnknown, SizeOf(IID))
      *this\lRefCount + 1
      *ppvObject\i = *this
    Else
      *ppvObject\i = 0
      ProcedureReturn #E_NOINTERFACE
    EndIf
  Else
    ProcedureReturn #E_POINTER
  EndIf
  ProcedureReturn #S_OK
EndProcedure

Procedure.l ICoreWebView2NavigationCompletedEventHandler_AddRef(*this.IUnknownBase_Structure)
  *this\lRefCount + 1
  ProcedureReturn *this\lRefCount
EndProcedure

Procedure.l ICoreWebView2NavigationCompletedEventHandler_Release(*this.IUnknownBase_Structure)
  *this\lRefCount - 1
  ProcedureReturn *this\lRefCount
EndProcedure

Procedure.l ICoreWebView2NavigationCompletedEventHandler_Invoke(*this.ICoreWebView2NavigationCompletedEventHandler_Structure, *sender.ICoreWebView2, *args.ICoreWebView2NavigationCompletedEventArgs)
  Protected isSuccess, *uri, uri.s
  
  If *args And *args\get_IsSuccess(@isSuccess) = #S_OK And isSuccess
    If *sender
      If *sender\get_Source(@*uri) = #S_OK
        If *uri
          uri = PeekS(*uri)
          If *this\pFunction
            CallFunctionFast(*this\pFunction, @uri)
          EndIf
          CoTaskMemFree_(*uri)
        EndIf
      EndIf
    EndIf
  EndIf
  
  ProcedureReturn #S_OK
  
EndProcedure


Procedure.i WebViewSetNavigateCompleteEventHandler(WebView, *EventHandler)
  
  Protected Result.i
  Protected Controller.ICoreWebView2Controller, Core.ICoreWebView2
  Protected *NavigationCompletedEventHandler.ICoreWebView2NavigationCompletedEventHandler_Structure
  Protected Token.q
  
  
  If GadgetType(WebView) = #PB_GadgetType_WebView And *EventHandler <> #Null
    
    Controller = GetGadgetAttribute(WebView, #PB_WebView_ICoreController)
    If Controller
      
      If Controller\get_CoreWebView2(@Core) = #S_OK And Core <> #Null
        
        If FindMapElement(NavigationCompletedEventHandler(), Str(WebView))
          If NavigationCompletedEventHandler()\Token
            Core\remove_NavigationCompleted(NavigationCompletedEventHandler()\Token)
          EndIf
          DeleteMapElement(NavigationCompletedEventHandler())
        EndIf
        
        *NavigationCompletedEventHandler = AddMapElement(NavigationCompletedEventHandler(), Str(WebView))
        If *NavigationCompletedEventHandler
          
          *NavigationCompletedEventHandler\pVtbl = *NavigationCompletedEventHandler + OffsetOf(IUnknownBase_Structure\pQueryInterface)
          *NavigationCompletedEventHandler\pQueryInterface = @ICoreWebView2NavigationCompletedEventHandler_QueryInterface()
          *NavigationCompletedEventHandler\pAddRef         = @ICoreWebView2NavigationCompletedEventHandler_AddRef()
          *NavigationCompletedEventHandler\pRelease        = @ICoreWebView2NavigationCompletedEventHandler_Release()
          *NavigationCompletedEventHandler\pInvoke         = @ICoreWebView2NavigationCompletedEventHandler_Invoke()
          
          *NavigationCompletedEventHandler\pFunction = *EventHandler
          
          If Core\add_NavigationCompleted(*NavigationCompletedEventHandler, @*NavigationCompletedEventHandler\Token) = #S_OK
            Result = #True
          Else
            DeleteMapElement(NavigationCompletedEventHandler())
          EndIf
          
        EndIf
        
      EndIf
      
      Core\Release()
    EndIf
  EndIf
  
  ProcedureReturn Result
  
EndProcedure


Global NewMap ContentLoadingEventHandler.ICoreWebView2ContentLoadingEventHandler_Structure()

Procedure.l ICoreWebView2ContentLoadingEventHandler_QueryInterface(*this.IUnknownBase_Structure, *riid.IID, *ppvObject.Integer)
  If *ppvObject And *riid
    If CompareMemory(*riid, ?IID_IUnknown, SizeOf(IID))
      *this\lRefCount + 1
      *ppvObject\i = *this
    Else
      *ppvObject\i = 0
      ProcedureReturn #E_NOINTERFACE
    EndIf
  Else
    ProcedureReturn #E_POINTER
  EndIf
  ProcedureReturn #S_OK
EndProcedure

Procedure.l ICoreWebView2ContentLoadingEventHandler_AddRef(*this.IUnknownBase_Structure)
  *this\lRefCount + 1
  ProcedureReturn *this\lRefCount
EndProcedure

Procedure.l ICoreWebView2ContentLoadingEventHandler_Release(*this.IUnknownBase_Structure)
  *this\lRefCount - 1
  ProcedureReturn *this\lRefCount
EndProcedure

Procedure.l ICoreWebView2ContentLoadingEventHandler_Invoke(*this.ICoreWebView2ContentLoadingEventHandler_Structure, *sender.ICoreWebView2, *args.ICoreWebView2ContentLoadingEventArgs)
  
  Protected isSuccess, *uri, uri.s
  
  ;If *args And *args\get_IsSuccess(@isSuccess) = #S_OK And isSuccess
  If *sender
    If *sender\get_Source(@*uri) = #S_OK
      If *uri
        uri = PeekS(*uri)
        If *this\pFunction
          CallFunctionFast(*this\pFunction, @uri)
        EndIf
        CoTaskMemFree_(*uri)
      EndIf
    EndIf
  EndIf
  ;EndIf
  
  ProcedureReturn #S_OK
EndProcedure



Procedure.i WebViewSetContentLoadingEventHandler(WebView, *EventHandler)
  
  Protected Result.i
  Protected Controller.ICoreWebView2Controller, Core.ICoreWebView2
  Protected *ContentLoadingEventHandler.ICoreWebView2ContentLoadingEventHandler_Structure
  Protected Token.q
  
  
  If GadgetType(WebView) = #PB_GadgetType_WebView And *EventHandler <> #Null
    
    Controller = GetGadgetAttribute(WebView, #PB_WebView_ICoreController)
    If Controller
      
      If Controller\get_CoreWebView2(@Core) = #S_OK 
        If Core
          
          If FindMapElement(ContentLoadingEventHandler(), Str(WebView))
            If ContentLoadingEventHandler()\Token
              Core\remove_ContentLoading(ContentLoadingEventHandler()\Token)
            EndIf
            DeleteMapElement(ContentLoadingEventHandler())
          EndIf
          
          *ContentLoadingEventHandler = AddMapElement(ContentLoadingEventHandler(), Str(WebView))
          
          
          If *ContentLoadingEventHandler
            
            *ContentLoadingEventHandler\pVtbl = *ContentLoadingEventHandler + OffsetOf(IUnknownBase_Structure\pQueryInterface)
            *ContentLoadingEventHandler\pQueryInterface = @ICoreWebView2ContentLoadingEventHandler_QueryInterface()
            *ContentLoadingEventHandler\pAddRef         = @ICoreWebView2ContentLoadingEventHandler_AddRef()
            *ContentLoadingEventHandler\pRelease        = @ICoreWebView2ContentLoadingEventHandler_Release()
            *ContentLoadingEventHandler\pInvoke         = @ICoreWebView2ContentLoadingEventHandler_Invoke()
            
            *ContentLoadingEventHandler\pFunction = *EventHandler
            
            If Core\add_ContentLoading(*ContentLoadingEventHandler, @*ContentLoadingEventHandler\Token) = #S_OK
              ;Debug *ContentLoadingEventHandler\Token
              Result = #True
            Else
              DeleteMapElement(ContentLoadingEventHandler())
            EndIf
            
          EndIf
          
          Core\Release()
        EndIf
      EndIf
    EndIf
  EndIf
  
  ProcedureReturn Result
  
EndProcedure


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


Global WebView2_Busy.i

Procedure ContentLoading(uri.s)
  Debug "Loading: " + uri
  WebView2_Busy = #True
EndProcedure

Procedure NaviComplete(uri.s)
  
  ; https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver
;   Protected js$ = "function callback(mutationList, observer) {" + 
;                   "  mutationList.forEach((mutation) => {" + 
;                   "    switch (mutation.type) {" + 
;                   ~"      case \"attributes\":" + 
;                   ;"        window.WV_Changed(1, mutation.attributeName, mutation.target.tagName, mutation.target.innerHTML );" +
;                   "        window.WV_Changed(1, mutation.attributeName, mutation.target.tagName);" +
;                   "        break;" + 
;                   ~"      case \"childList\":" + 
;                   "        window.WV_Changed(2);" +
;                   "        break;" + 
;                   ~"      case \"characterData\":" + 
;                   "        window.WV_Changed(3);" +
;                   "        break;" + 
;                   "    }" + 
;                   "  });" + 
;                   "};" + 
;                   "const observer = new MutationObserver(callback);" + 
;                   "observer.observe(document.documentElement, { attributes: true, childList: true, subtree: true, characterData: true } );"
  
  Protected js$ = ~"document.documentElement.addEventListener(\"change\", (event) => {" +
                  " window.WV_Changed(0);" +
                  "});"
  
  Debug "Loaded: " + uri
  WebView2_Busy = #False

  WebViewExecuteScript(2, js$)
  
EndProcedure

Procedure WV_Changed(JsonParameters$)
  
  Debug #PB_Compiler_Procedure + " " + JsonParameters$
  
  ;ProcedureReturn
EndProcedure


OpenWindow(0, 0, 0, 1000, 900, "", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
StringGadget(0, 0, 0, 400, 30, "https://www.openstreetmap.org")
ButtonGadget(1, 410, 0, 50, 30, "Go")
WebViewGadget(2, 0, 35, 1000, 900)

; WebViewSetContentLoadingEventHandler(2, @ContentLoading())
WebViewSetNavigateCompleteEventHandler(2, @NaviComplete())

BindWebViewCallback(2, "WV_Changed", @WV_Changed())

SetGadgetText(2, "https://www.w3schools.com/xml/tryit.asp?filename=tryxml_parsertest2")


; AddWindowTimer(0, 1, 100)

Repeat 
  Event = WaitWindowEvent()
;   If Event = #PB_Event_Timer
;     If EventTimer() = 1
;       If WebView2_Busy
;         Debug "WebView is Busy"
;       EndIf
;     EndIf
;   EndIf
  If Event = #PB_Event_Gadget
    If EventGadget() = 1
      SetGadgetText(2, Trim(GetGadgetText(0)))
    EndIf
  EndIf
Until Event = #PB_Event_CloseWindow

zikitrake
Addict
Addict
Posts: 868
Joined: Thu Mar 25, 2004 2:15 pm
Location: Spain

Re: Any idea for #PB_Web_Busy with WebViewGadget? or other WebPageLoaded procedure?

Post by zikitrake »

breeze4me wrote: Thu Feb 06, 2025 1:01 pm This method will not work for the site “www.openstreetmap.org”, you will need to get the information through MutationObserver or use the API provided by that site.

Code: Select all

...
Thank you! I think I already solved it with MutationObserver some minutes ago :)

https://www.purebasic.fr/english/viewtopic.php?t=86218
PB 6.21 beta, PureVision User
Post Reply