Saving OuterHTML using Await Implementation with TWebView

Fivewin features a powerful Web Control class called TWebView.

2.The web rendering operates in async mode.
3.Consequently, users familiar with procedural synchronous modes are facing difficulties in retrieving information from the web.
4.Therefore, I have implemented a synchronous class for TWebView, which is supported by the ‘await’ technique in other languages.
5.The implementation is named TAWaitWeb. To facilitate more convenient usage, I have created user-friendly functions using TAWaitWeb as follows:

Function List


AWait_QuerySelector(oWeb, cQuery, nSecond)
AWait_QuerySelectAll(oWeb, cQuery, nSecond)
AWait_GetOuterHTML(oWeb, cSelector, nSecond)

6.The example scenario is as follows:
Navigate to google.com.
Use AWait_QuerySelector() to wait until the document’s readyState becomes ‘complete’.
Once complete, use AWait_GetOuterHTML() to display the outer HTML.

sample Code

/*
 c)copyright 2023- charleskwonohjun@gmail.com ( Seoul, Korea )
*/

#include "FiveWin.ch"

STATIC oWebView  

FUNCTION Main()
    LOCAL oDlg

    DEFINE DIALOG oDlg TITLE "WebView Test" SIZE 1200, 700

         oDlg:bStart := { || GetOuterHtml( oDlg  ) }

    ACTIVATE DIALOG oDlg CENTER

RETURN NIL

STATIC FUNCTION GetOuterHtml( oDlg  )
   LOCAL cStr
   LOCAL nCounter := 0
   LOCAL lOk  := .f.

   oWebView := TWebView():New( , oDlg:hWnd )
   oWebView:Navigate( "https://www.google.com/" )

   Sleep(300)
   SysWait()

   WHILE .T.

      ++nCounter
      cStr := AWait_QuerySelector( oWebView, "document.readyState", 3000 )  

      IF cStr == "complete"
         lOk := .t.
         EXIT
      ENDIF      

      IF nCounter == 6
         EXIT
      ENDIF  

   ENDDO

   IF !lOk
      MsgStop("Timeout! Try again")
      RETURN NIL
   ENDIF

   ?AWait_GetOuterHTML( oWebView, "html", 3000 )

RETURN NIL

TAWaitWeb.prg

/*

TAWaitWeb.prg

This is a class for Fivewin TWebView that retrieves data from the WebView in Sync mode.
c)copyright 2023- charleskwonohjun@gmail.com ( Seoul, Korea )

*/

#include "fivewin.ch"

FUNCTION AWait_QuerySelector( oWeb, cQuery, nSecond )
    LOCAL oFunc
    LOCAL cReturn := ""

    oFunc := TAWaitWeb():New( oWeb )    
    oFunc:Query( cQuery, nSecond )

    cReturn := oFunc:cReturn    

RETURN cReturn

FUNCTION AWait_QuerySelectAll( oWeb, cQuery, nSecond )
    LOCAL oFunc
    LOCAL cReturn := ""

    oFunc := TAWaitWeb():New( oWeb )    
    oFunc:QuerySelectAll( cQuery, nSecond )

    cReturn := oFunc:cReturn    

RETURN cReturn

FUNCTION AWait_GetOuterHTML( oWeb, cSelector, nSecond )
    LOCAL oFunc
    LOCAL cReturn := ""

    oFunc := TAWaitWeb():New( oWeb )
    oFunc:getOuterHTML( cSelector, nSecond )

    cReturn := oFunc:cReturn    

RETURN cReturn

CLASS TAWaitWeb

    DATA bOldBind
    DATA oWeb
    DATA cQuery
    DATA nSecond

    DATA cReturn

    METHOD New( oWeb, cQuery, nSecond ) CONSTRUCTOR
    METHOD GetBind( cJson, cCalls, ... )
    METHOD Query( cQuery, nSecond )
    METHOD QuerySelectAll( cQuery, nSecond )

    METHOD GetOuterHtml( cSelecter, nSecond )

ENDCLASS    

METHOD New( oWeb ) CLASS TAWaitWeb

    ::oWeb := oWeb
    ::oWeb:Bind( "SendToFWH" )  

RETURN Self

METHOD Query( cQuery, nSecond, cReturn ) CLASS TAWaitWeb
    LOCAL nCounter := 0
    LOCAL lReturn  := .f.
    LOCAL cEval    := "SendToFWH($QUERY$, 'WebFunc')"
    LOCAL nStartSec := GetTickCount()

    DEFAULT nSecond := 500

    ::bOldBind := ::oWeb:bOnBind
    ::oWeb:bOnBind := { | cJson, cCalls, ... | ::GetBind( cJson, cCalls, ... ) }

    cEval := STRTRAN( cEval, "$QUERY$", cQuery )

    ::cReturn := ""

    WHILE .T.
        ::oWeb:Eval( cEval )

        sleep(100)
        SysWait()

        IF !EMPTY( ::cReturn )
            lReturn := .t.
            EXIT
        ENDIF    

        IF GetTickCount() - nStartSec  >= nSecond
           EXIT
        ENDIF
    ENDDO  

    cReturn := ::cReturn

    ::oWeb:bOnBind := ::bOldBind

RETURN lReturn

METHOD QuerySelectAll( cQuery, nSecond, cReturn ) CLASS TAWaitWeb
    LOCAL nCounter := 0
    LOCAL lReturn  := .f.
    LOCAL cEval    := "SendToFWH(querySelectorAll($QUERY$), 'WebFunc')"
    LOCAL nStartSec := GetTickCount()

    DEFAULT nSecond := 500

    ::bOldBind := ::oWeb:bOnBind
    ::oWeb:bOnBind := { | cJson, cCalls, ... | ::GetBind( cJson, cCalls, ... ) }

    cEval := STRTRAN( cEval, "$QUERY$", cQuery )

    ::cReturn := ""

    WHILE .T.
        ::oWeb:Eval( cEval )

        sleep(100)
        SysWait()

        IF !EMPTY( ::cReturn )
           lReturn := .t.
           EXIT
        ENDIF    

        IF GetTickCount() - nStartSec  >= nSecond
           EXIT
        ENDIF    
    ENDDO  

    cReturn := ::cReturn

    ::oWeb:bOnBind := ::bOldBind

RETURN lReturn

METHOD GetOuterHtml( cSelecter, nSecond ) CLASS TAWaitWeb
    LOCAL cQuery := "SendToFWH( document.querySelector('$SELECTER$').outerHTML, 'savehtml')"
    LOCAL cEval
    LOCAL nStartSec := GetTickCount()
    LOCAL lReturn  := .f.

    DEFAULT nSecond := 500

    ::bOldBind := ::oWeb:bOnBind
    ::oWeb:bOnBind := { | cJson, cCalls, ... | ::GetBind( cJson, cCalls, ... ) }

    cEval := STRTRAN( cQuery , "$SELECTER$", cSelecter )

    ::cReturn := ""

    WHILE .T.
        ::oWeb:Eval( cEval )

        sleep(100)
        SysWait()        

        IF !EMPTY( ::cReturn )
            lReturn := .t.
            EXIT
        ENDIF    

        IF GetTickCount() - nStartSec  >= nSecond
           EXIT
        ENDIF  
    ENDDO      

    ::oWeb:bOnBind := ::bOldBind

RETURN lReturn

METHOD GetBind( cJson, cCalls, ... ) CLASS TAWaitWeb
    LOCAL hResponse := hash()

    hb_jsondecode(cJson ,@hResponse )

    ::cReturn := ""

    IF LEN( hResponse ) >= 1
       ::cReturn := hResponse[1]    
    ENDIF  

RETURN NIL

Similar Posts

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다