Jump to content
Chimp

how to capture some events from a javascript (custom) object?

Recommended Posts

Chimp

Hi to all, in this script I'm using a Javascript library called VIS to display data on a timeline. All is performed within a browser control embedded in the AutoIt GUI, and the AutoIt script should interact with what is going on in the browser control.
what I'm stuck on is on finding a way to get notified in the AutoIt script on some events fired from that javascript library.

When I use the ObjEvent()  to get notified about events fired by html elements from the html page, all works ok...
I'm stuck instead on how to receive notifications from events fired by a javascript (custom?) object. The DataSet object.

in very short:
To add, edit or remove Items on the Timeline, first a DataSet is created and bound to the Timeline, then all variations performed on the DataSet will be automatically visualized in the form of Items located on the Timeline. All variations on the DataSet will also fire events. (use the button to create new items from autoit, or doubbleclick on the timeline to also create new items by the javascript library)

now my problem is:
since the DataSet is setted to fire events anytime some data in the DatSet is added and/or changed and/or deleted, i would like to be notified about such events in my AutoIt program, but I've not achieved the goal so far.

In this example the events generated by the DataSet are notified within the HTML page and displayed within the browser control, but not forwarded to AutoIt.

Any help to achieve this goal is higly appreciated.
Thanks

#include <GUIConstantsEx.au3>
#include <MsgBoxConstants.au3>
#include <string.au3>
#include <array.au3>
Global $g_idGUIEdit

 ; read html page from bottom of this script
 ; and write it to a file on disk
CreateHtmlPage()

Example()
Exit

Func Example()
    Local $hGUIMain = GUICreate("Event Test", 1000, 600)
    $g_idGUIEdit = GUICtrlCreateEdit("", 500, 405, 490, 175)
    GUICtrlSetFont(-1, 9, 400, -1, 'Courier New')
    GUICtrlCreateLabel("Below are some Browser events 'captured' from the above web page by AutoIt", 500, 385, 990, 20)
    Local $idGUIExit = GUICtrlCreateButton(" Close and exit", 5, 580, 990, 15)

    Local $hButton1 = GUICtrlCreateButton("Add an Item to timeline", 10, 400, 150, 40)
    GUISetState() ;Show GUI

    ; We prepare the Internet Explorer as our test subject
    Global $oIE = ObjCreate("Shell.Explorer.2")
    $hIE = GUICtrlCreateObj($oIE, 5, 5, 990, 380) ; <- embedd $oIE in the AutoIt GUI

    ; load our web page, javascript and css in the browser
    ToolTip("...downloading javascript, please wait")
    $oIE.navigate('file:///' & @ScriptDir & '\Page.html')
    Sleep(1000) ; Give it some time to load the web page
    ToolTip("")

    Do ; wait for document
        Sleep(250)
        $oDocument = $oIE.document
    Until IsObj($oDocument)

    ; https://msdn.microsoft.com/en-us/library/52f50e9t(v=vs.94).aspx
    ; $ohJS is a reference to the javascript Global Obj
    ; -------------------------------------------------
    Global $ohJS = $oIE.document.parentwindow.JSglobal

    ; --- Setup catch of events ---

    ;   https://msdn.microsoft.com/en-us/library/aa769764(v=vs.85).aspx
    ;   HTMLDocumentEvents2 interface (catch OnClick, OnMouseOver, .... etc
    Global $oEventObject = ObjEvent($oDocument, "IEEvent2_", "HTMLDocumentEvents2") ; OK, this events are catched

    ; Attempt to catch events fired by the DataSet.
    ; items is the DataSet obj created in the Browser
    ; Global $oEventObject = ObjEvent($ohJS.items, "OnDataSet_") ; ???? how to catch events from the DataSet <---- ?????

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

    ; Loop until the user exits.
    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE, $idGUIExit
                ExitLoop

            Case $hButton1
                ; add a job to the timeline (a simple example just to test)
                ; to generate a unique ID I use the following: @YEAR & @MON & @MDAY & @HOUR & @MIN & @SEC & @MSEC
                Local $result = $ohJS.eval("items.add([{id: " & @YEAR & @MON & @MDAY & @HOUR & @MIN & @SEC & @MSEC & ", content: '<b>item 4</b> Added at " & @HOUR & ":" & @MIN & ":" & @SEC & " ', start: '2014-01-19'}]);")
                ConsoleWrite("DataSet now contains " & $ohJS.items.length & " Items" & @CRLF)

        EndSwitch
    WEnd

    ; the end
    $oEventObject.Stop ; Tell IE we don't want to receive events.
    $oEventObject = 0 ; Kill the Event Object
    $oIE = 0 ; Remove IE from memory (not really necessary).
    GUIDelete($hGUIMain) ; Remove GUI
EndFunc   ;==>Example

; --- event management zone ---
; A few Internet Explorer Event Functions
; below function are fired by events occurred in the browser
Volatile Func IEEvent2_onClick($oEvent)
    ConsolePrint("mouse click: " & $oEvent.clientX & ',' & $oEvent.clientY & '  on ' & $oEvent.srcElement.NodeName & '  - ' & $oEvent.srcElement.ID)
EndFunc   ;==>IEEvent2_onClick

Volatile Func IEEvent2_onDblClick($oEvent)
    ConsolePrint("mouse DoubleClick: @" & $oEvent.clientX & ',' & $oEvent.clientY)
EndFunc   ;==>IEEvent2_onDblClick

Volatile Func OnDataSet_add($oEvent)
    ConsolePrint("!!!! event from DataSet " & IsObj($oEvent)) ; type
EndFunc   ;==>OnDataSet_add

Func ConsolePrint($sMsg)
    Local Const $iMaxLines = 9 ; keep last 12 lines only
    $sMsg = @HOUR & ':' & @MIN & ':' & @SEC & ':' & @MSEC & @TAB & $sMsg & @CRLF
    $sMsg = StringReplace(GUICtrlRead($g_idGUIEdit) & $sMsg, @CR, @CR)
    If @extended > $iMaxLines Then ; more than $iMaxLines
        $sMsg = StringMid($sMsg, StringInStr($sMsg, @CR, 0, -1 * $iMaxLines) + 2)
    EndIf
    GUICtrlSetData($g_idGUIEdit, $sMsg)
EndFunc   ;==>ConsolePrint

Func CreateHtmlPage()
    Local $sStart = @LF & "#cs;HTML"
    Local $sEnd = "#ce;HTML" & @CR
    Local $aArray = _StringBetween(FileRead(@ScriptFullPath), $sStart, $sEnd)
    Local $sPage = @ScriptDir & '\Page.html'
    Local $hFile = FileOpen($sPage, 2) ;  $FO_OVERWRITE (2) = Write mode (erase previous contents)
    FileWrite($hFile, $aArray[0])
    FileFlush($hFile)
    FileClose($hFile)
EndFunc   ;==>CreateHtmlPage

#cs;HTML
    <!DOCTYPE HTML>
    <html>
    <head>
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <script type="text/javascript">
    var JSglobal = (1,eval)("this");
    </script>
    <style type="text/css">
    body, html {
    font-family: arial, sans-serif;
    font-size: 11pt;
    }
    </style>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/vis/4.16.1/vis.min.js"></script>
    <link href="https://cdnjs.cloudflare.com/ajax/libs/vis/4.16.1/vis.min.css" rel="stylesheet" type="text/css" />
    </head>
    <body>

    <div id="visualization" style="border-width:3px; border-color:yellow; border-style:double;"></div>
    <p></p>
    <div id="log"></div>

    <script type="text/javascript">
    // DOM element where the Timeline will be attached
    var container = document.getElementById('visualization');

    // Create an empty DataSet (allows two way data-binding)
    var items = new vis.DataSet({type: { start: 'ISODate', end: 'ISODate', notes: '' }});

    // items.addEventListener('click',resetElements,true);

    // add items to the DataSet
    items.add([
    {id: 1, content: 'item 1 <b>start</b>', start: '2014-01-23'},
    {id: 2, content: 'item 2', start: '2014-01-18 00:00', end: '2014-01-18 23:59'},
    {id: 3, content: 'item 3', start: '2014-01-21'},
    {id: 5, content: 'item 5', start: '2014-01-28', type:'point'},
    {id: 6, content: 'item 6', start: '2014-01-26'}
    ]);

    // Configuration for the Timeline
    var options = {orientation: 'top',
    editable: {
    add: true,
    remove: true,
    updateTime: true,
    updateGroup: true
    }
    };

    // Create a Timeline
    var timeline = new vis.Timeline(container, items, options);

    // turn events on
    timeline.on('rangechange', function (properties) {
    logEvent('rangechange', properties);
    });
    timeline.on('rangechanged', function (properties) {
    logEvent('rangechanged', properties);
    });
    timeline.on('select', function (properties) {
    logEvent('select', properties);
    });

    items.on('*', function (event, properties) {
    logEvent(event, properties);
    });

    function logEvent(event, properties) {
    var log = document.getElementById('log');
    var msg = document.createElement('div');
    msg.innerHTML = 'event=' + JSON.stringify(event) + ', ' +
    'properties=' + JSON.stringify(properties);
    log.firstChild ? log.insertBefore(msg, log.firstChild) : log.appendChild(msg);
    }
    </script>
    </body>
    </html>
#ce;HTML
;

 


small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Share this post


Link to post
Share on other sites
Chimp

Hi @genius257 thanks for answering,
... I'm afraid I don't get your hint, all the needed objects are already created in the Browser Control, what I'm trying to achieve is a way to receive notifications about events fired by the javascript DataSet object, hopefully simply using the ObjEvent() function in a "correct" way (it's what I'm not been able)
 could you please elaborate on your hint?


small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Share this post


Link to post
Share on other sites
genius257
2 hours ago, Chimp said:

Hi @genius257 thanks for answering,
... I'm afraid I don't get your hint, all the needed objects are already created in the Browser Control, what I'm trying to achieve is a way to receive notifications about events fired by the javascript DataSet object, hopefully simply using the ObjEvent() function in a "correct" way (it's what I'm not been able)
 could you please elaborate on your hint?

Hi @Chimp.

No i would say not all object are created, at least not if you want to push JS notifications to AutoIt. Below is your code, and I've added functionality to run AutoIt function instead of your js function named "logEvent".

#include <GUIConstantsEx.au3>
#include <MsgBoxConstants.au3>
#include <string.au3>
#include <array.au3>
Global $g_idGUIEdit

#include <AutoItObject.au3>
Func logEvent($oThis, $event, $properties)
    #forcedef $ohJS
    MsgBox(0, "AutoIt function logEvent", "event=" & $ohJS.JSON.stringify($event) & ", properties=" & $ohJS.JSON.stringify($properties))
EndFunc

 ; read html page from bottom of this script
 ; and write it to a file on disk
CreateHtmlPage()

Example()
Exit

Func Example()
    Local $hGUIMain = GUICreate("Event Test", 1000, 600)
    $g_idGUIEdit = GUICtrlCreateEdit("", 500, 405, 490, 175)
    GUICtrlSetFont(-1, 9, 400, -1, 'Courier New')
    GUICtrlCreateLabel("Below are some Browser events 'captured' from the above web page by AutoIt", 500, 385, 990, 20)
    Local $idGUIExit = GUICtrlCreateButton(" Close and exit", 5, 580, 990, 15)

    Local $hButton1 = GUICtrlCreateButton("Add an Item to timeline", 10, 400, 150, 40)
    GUISetState() ;Show GUI

    ; We prepare the Internet Explorer as our test subject
    Global $oIE = ObjCreate("Shell.Explorer.2")
    $hIE = GUICtrlCreateObj($oIE, 5, 5, 990, 380) ; <- embedd $oIE in the AutoIt GUI

    ; load our web page, javascript and css in the browser
    ToolTip("...downloading javascript, please wait")
    $oIE.navigate('file:///' & @ScriptDir & '\Page.html')
    Sleep(1000) ; Give it some time to load the web page
    ToolTip("")

    Do ; wait for document
        Sleep(250)
        $oDocument = $oIE.document
    Until IsObj($oDocument)

    ; https://msdn.microsoft.com/en-us/library/52f50e9t(v=vs.94).aspx
    ; $ohJS is a reference to the javascript Global Obj
    ; -------------------------------------------------
    Global $ohJS = $oIE.document.parentwindow.JSglobal


    $ohJS.eval("var AutoIt = undefined");create varialbe to hold the object
    _AutoItObject_Startup()
    $oObject = _AutoItObject_Create()
    _AutoItObject_AddMethod($oObject, "logEvent", "logEvent")
    $ohJS.AutoIt = $oObject
;~  $ohJS.eval("alert(AutoIt.logEvent())")

    ; --- Setup catch of events ---

    ;   https://msdn.microsoft.com/en-us/library/aa769764(v=vs.85).aspx
    ;   HTMLDocumentEvents2 interface (catch OnClick, OnMouseOver, .... etc
    Global $oEventObject = ObjEvent($oDocument, "IEEvent2_", "HTMLDocumentEvents2") ; OK, this events are catched

    ; Attempt to catch events fired by the DataSet.
    ; items is the DataSet obj created in the Browser
    ; Global $oEventObject = ObjEvent($ohJS.items, "OnDataSet_") ; ???? how to catch events from the DataSet <---- ?????

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

    ; Loop until the user exits.
    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE, $idGUIExit
                ExitLoop

            Case $hButton1
                ; add a job to the timeline (a simple example just to test)
                ; to generate a unique ID I use the following: @YEAR & @MON & @MDAY & @HOUR & @MIN & @SEC & @MSEC
                Local $result = $ohJS.eval("items.add([{id: " & @YEAR & @MON & @MDAY & @HOUR & @MIN & @SEC & @MSEC & ", content: '<b>item 4</b> Added at " & @HOUR & ":" & @MIN & ":" & @SEC & " ', start: '2014-01-19'}]);")
                ConsoleWrite("DataSet now contains " & $ohJS.items.length & " Items" & @CRLF)

        EndSwitch
    WEnd

    ; the end
    $oEventObject.Stop ; Tell IE we don't want to receive events.
    $oEventObject = 0 ; Kill the Event Object
    $oIE = 0 ; Remove IE from memory (not really necessary).
    GUIDelete($hGUIMain) ; Remove GUI
EndFunc   ;==>Example

; --- event management zone ---
; A few Internet Explorer Event Functions
; below function are fired by events occurred in the browser
Volatile Func IEEvent2_onClick($oEvent)
    ConsolePrint("mouse click: " & $oEvent.clientX & ',' & $oEvent.clientY & '  on ' & $oEvent.srcElement.NodeName & '  - ' & $oEvent.srcElement.ID)
EndFunc   ;==>IEEvent2_onClick

Volatile Func IEEvent2_onDblClick($oEvent)
    ConsolePrint("mouse DoubleClick: @" & $oEvent.clientX & ',' & $oEvent.clientY)
EndFunc   ;==>IEEvent2_onDblClick

Volatile Func OnDataSet_add($oEvent)
    ConsolePrint("!!!! event from DataSet " & IsObj($oEvent)) ; type
EndFunc   ;==>OnDataSet_add

Func ConsolePrint($sMsg)
    Local Const $iMaxLines = 9 ; keep last 12 lines only
    $sMsg = @HOUR & ':' & @MIN & ':' & @SEC & ':' & @MSEC & @TAB & $sMsg & @CRLF
    $sMsg = StringReplace(GUICtrlRead($g_idGUIEdit) & $sMsg, @CR, @CR)
    If @extended > $iMaxLines Then ; more than $iMaxLines
        $sMsg = StringMid($sMsg, StringInStr($sMsg, @CR, 0, -1 * $iMaxLines) + 2)
    EndIf
    GUICtrlSetData($g_idGUIEdit, $sMsg)
EndFunc   ;==>ConsolePrint

Func CreateHtmlPage()
    Local $sStart = @LF & "#cs;HTML"
    Local $sEnd = "#ce;HTML" & @CR
    Local $aArray = _StringBetween(FileRead(@ScriptFullPath), $sStart, $sEnd)
    Local $sPage = @ScriptDir & '\Page.html'
    Local $hFile = FileOpen($sPage, 2) ;  $FO_OVERWRITE (2) = Write mode (erase previous contents)
    FileWrite($hFile, $aArray[0])
    FileFlush($hFile)
    FileClose($hFile)
EndFunc   ;==>CreateHtmlPage

#cs;HTML
    <!DOCTYPE HTML>
    <html>
    <head>
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <script type="text/javascript">
    var JSglobal = (1,eval)("this");
    </script>
    <style type="text/css">
    body, html {
    font-family: arial, sans-serif;
    font-size: 11pt;
    }
    </style>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/vis/4.16.1/vis.min.js"></script>
    <link href="https://cdnjs.cloudflare.com/ajax/libs/vis/4.16.1/vis.min.css" rel="stylesheet" type="text/css" />
    </head>
    <body>

    <div id="visualization" style="border-width:3px; border-color:yellow; border-style:double;"></div>
    <p></p>
    <div id="log"></div>

    <script type="text/javascript">
    // DOM element where the Timeline will be attached
    var container = document.getElementById('visualization');

    // Create an empty DataSet (allows two way data-binding)
    var items = new vis.DataSet({type: { start: 'ISODate', end: 'ISODate', notes: '' }});

    // items.addEventListener('click',resetElements,true);

    // add items to the DataSet
    items.add([
    {id: 1, content: 'item 1 <b>start</b>', start: '2014-01-23'},
    {id: 2, content: 'item 2', start: '2014-01-18 00:00', end: '2014-01-18 23:59'},
    {id: 3, content: 'item 3', start: '2014-01-21'},
    {id: 5, content: 'item 5', start: '2014-01-28', type:'point'},
    {id: 6, content: 'item 6', start: '2014-01-26'}
    ]);

    // Configuration for the Timeline
    var options = {orientation: 'top',
    editable: {
    add: true,
    remove: true,
    updateTime: true,
    updateGroup: true
    }
    };

    // Create a Timeline
    var timeline = new vis.Timeline(container, items, options);

    // turn events on
    timeline.on('rangechange', function (properties) {
    logEvent('rangechange', properties);
    });
    timeline.on('rangechanged', function (properties) {
    logEvent('rangechanged', properties);
    });
    timeline.on('select', function (properties) {
    logEvent('select', properties);
    });

    items.on('*', function (event, properties) {
    //logEvent(event, properties);
        AutoIt.logEvent(event, properties);
    });

    function logEvent(event, properties) {
    var log = document.getElementById('log');
    var msg = document.createElement('div');
    msg.innerHTML = 'event=' + JSON.stringify(event) + ', ' +
    'properties=' + JSON.stringify(properties);
    log.firstChild ? log.insertBefore(msg, log.firstChild) : log.appendChild(msg);
    }
    </script>
    </body>
    </html>
#ce;HTML
;

 

  • Like 3

Share this post


Link to post
Share on other sites
trancexx

Just to add to what @genius257 suggested, you can use that method to directly call any AutoIt function (either built-in or user defined) from within javascript.

#AutoIt3Wrapper_UseX64=n
#include <GUIConstantsEx.au3>
#include <MsgBoxConstants.au3>
#include <string.au3>
#include <array.au3>

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
#include "AutoItObject.au3"
_AutoItObject_StartUp()
; set up a mini framework of AutoIt Functions/constants and stick them on an object
Global $oAutoIt = _AutoItObject_Create()
_AutoItObject_AddMethod($oAutoIt, "call", "_call")
; Maybe to directly acess any function
Func _call($oSelf, $sFunc, _
        $vParam1 = 0, $vParam2 = 0, $vParam3 = 0, $vParam4 = 0, $vParam5 = 0, $vParam6 = 0, _
        $vParam7 = 0, $vParam8 = 0, $vParam9 = 0, $vParam10 = 0, $vParam11 = 0, $vParam12 = 0, _
        $vParam13 = 0, $vParam14 = 0, $vParam15 = 0, $vParam16 = 0, $vParam17 = 0, $vParam18 = 0, _
        $vParam19 = 0, $vParam20 = 0, $vParam21 = 0, $vParam22 = 0, $vParam23 = 0, $vParam24 = 0, _
        $vParam25 = 0, $vParam26 = 0, $vParam27 = 0, $vParam28 = 0, $vParam29 = 0, $vParam30 = 0)
    Local $sExec = $sFunc & "("
    If @NumParams = 3 And IsArray($vParam1) And UBound($vParam1, 0) = 1 Then
        For $n = 0 To UBound($vParam1) - 1
            $sExec &= "$vParam1[" & $n & "],"
        Next
    Else
        If @NumParams = 2 Then
            $sExec &= ")"
        Else
            For $n = 1 To @NumParams - 2
                $sExec &= "$vParam" & $n & ","
            Next
        EndIf
    EndIf
    Return Execute(StringTrimRight($sExec, 1) & ")")
EndFunc
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Global $g_idGUIEdit

; read html page from bottom of this script
; and write it to a file on disk
CreateHtmlPage()

Example()
Exit

Func Example()
    Local $hGUIMain = GUICreate("Event Test", 1000, 600)
    $g_idGUIEdit = GUICtrlCreateEdit("", 500, 405, 490, 175)
    GUICtrlSetFont(-1, 9, 400, -1, 'Courier New')
    GUICtrlCreateLabel("Below are some Browser events 'captured' from the above web page by AutoIt", 500, 385, 990, 20)
    Local $idGUIExit = GUICtrlCreateButton(" Close and exit", 5, 580, 990, 15)

    Local $hButton1 = GUICtrlCreateButton("Add an Item to timeline", 10, 400, 150, 40)
    GUISetState() ;Show GUI

    ; We prepare the Internet Explorer as our test subject
    Global $oIE = ObjCreate("Shell.Explorer.2")
    $hIE = GUICtrlCreateObj($oIE, 5, 5, 990, 380) ; <- embedd $oIE in the AutoIt GUI

    ; load our web page, javascript and css in the browser
    ToolTip("...downloading javascript, please wait")
    $oIE.navigate('file:///' & @ScriptDir & '\Page.html')
    Sleep(1000) ; Give it some time to load the web page
    ToolTip("")

    Do ; wait for document
        Sleep(250)
        $oDocument = $oIE.document
    Until IsObj($oDocument)

    ; https://msdn.microsoft.com/en-us/library/52f50e9t(v=vs.94).aspx
    ; $ohJS is a reference to the javascript Global Obj
    ; -------------------------------------------------
    Global $ohJS = $oIE.document.parentwindow.JSglobal
    $ohJS.AutoIt = $oAutoIt
    ; --- Setup catch of events ---

    ;   https://msdn.microsoft.com/en-us/library/aa769764(v=vs.85).aspx
    ;   HTMLDocumentEvents2 interface (catch OnClick, OnMouseOver, .... etc
    Global $oEventObject = ObjEvent($oDocument, "IEEvent2_", "HTMLDocumentEvents2") ; OK, this events are catched

    ; Attempt to catch events fired by the DataSet.
    ; items is the DataSet obj created in the Browser
;~   Global $oEventObject = ObjEvent($ohJS.items);, "OnDataSet_") ; ???? how to catch events from the DataSet <---- ?????

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

    ; Loop until the user exits.
    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE, $idGUIExit
                ExitLoop

            Case $hButton1
                ; add a job to the timeline (a simple example just to test)
                ; to generate a unique ID I use the following: @YEAR & @MON & @MDAY & @HOUR & @MIN & @SEC & @MSEC
                Local $result = $ohJS.eval("items.add([{id: " & @YEAR & @MON & @MDAY & @HOUR & @MIN & @SEC & @MSEC & ", content: '<b>item 4</b> Added at " & @HOUR & ":" & @MIN & ":" & @SEC & " ', start: '2014-01-19'}]);")
                ConsoleWrite("DataSet now contains " & $ohJS.items.length & " Items" & @CRLF)

        EndSwitch
    WEnd

    ; the end
    $oEventObject.Stop ; Tell IE we don't want to receive events.
    $oEventObject = 0 ; Kill the Event Object
    $oIE = 0 ; Remove IE from memory (not really necessary).
    GUIDelete($hGUIMain) ; Remove GUI
EndFunc   ;==>Example

; --- event management zone ---
; A few Internet Explorer Event Functions
; below function are fired by events occurred in the browser
Volatile Func IEEvent2_onClick($oEvent)
    ConsolePrint("mouse click: " & $oEvent.clientX & ',' & $oEvent.clientY & '  on ' & $oEvent.srcElement.NodeName & '  - ' & $oEvent.srcElement.ID)
EndFunc   ;==>IEEvent2_onClick

Volatile Func IEEvent2_onDblClick($oEvent)
    ConsolePrint("mouse DoubleClick: @" & $oEvent.clientX & ',' & $oEvent.clientY)
EndFunc   ;==>IEEvent2_onDblClick

Volatile Func OnDataSet_add($oEvent)
    ConsolePrint("!!!! event from DataSet " & IsObj($oEvent)) ; type
EndFunc   ;==>OnDataSet_add

Func ConsolePrint($sMsg)
    Local Const $iMaxLines = 9 ; keep last 12 lines only
    $sMsg = @HOUR & ':' & @MIN & ':' & @SEC & ':' & @MSEC & @TAB & $sMsg & @CRLF
    $sMsg = StringReplace(GUICtrlRead($g_idGUIEdit) & $sMsg, @CR, @CR)
    If @extended > $iMaxLines Then ; more than $iMaxLines
        $sMsg = StringMid($sMsg, StringInStr($sMsg, @CR, 0, -1 * $iMaxLines) + 2)
    EndIf
    GUICtrlSetData($g_idGUIEdit, $sMsg)
EndFunc   ;==>ConsolePrint

Func CreateHtmlPage()
    Local $sStart = @LF & "#cs;HTML"
    Local $sEnd = "#ce;HTML" & @CR
    Local $aArray = _StringBetween(FileRead(@ScriptFullPath), $sStart, $sEnd)
    Local $sPage = @ScriptDir & '\Page.html'
    Local $hFile = FileOpen($sPage, 2) ;  $FO_OVERWRITE (2) = Write mode (erase previous contents)
    FileWrite($hFile, $aArray[0])
    FileFlush($hFile)
    FileClose($hFile)
EndFunc   ;==>CreateHtmlPage

#cs;HTML
    <!DOCTYPE HTML>
    <html>
    <head>
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <script type="text/javascript">
    var JSglobal = (1,eval)("this"), AutoIt;
    </script>
    <style type="text/css">
    body, html {
    font-family: arial, sans-serif;
    font-size: 11pt;
    }
    </style>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/vis/4.16.1/vis.min.js"></script>
    <link href="https://cdnjs.cloudflare.com/ajax/libs/vis/4.16.1/vis.min.css" rel="stylesheet" type="text/css" />
    </head>
    <body>

    <div id="visualization" style="border-width:3px; border-color:yellow; border-style:double;"></div>
    <p></p>
    <div id="log"></div>

    <script type="text/javascript">
    // DOM element where the Timeline will be attached
    var container = document.getElementById('visualization');

    // Create an empty DataSet (allows two way data-binding)
    var items = new vis.DataSet({type: { start: 'ISODate', end: 'ISODate', notes: '' }});

    // items.addEventListener('click',resetElements,true);

    // add items to the DataSet
    items.add([
    {id: 1, content: 'item 1 <b>start</b>', start: '2014-01-23'},
    {id: 2, content: 'item 2', start: '2014-01-18 00:00', end: '2014-01-18 23:59'},
    {id: 3, content: 'item 3', start: '2014-01-21'},
    {id: 5, content: 'item 5', start: '2014-01-28', type:'point'},
    {id: 6, content: 'item 6', start: '2014-01-26'}
    ]);

    // Configuration for the Timeline
    var options = {orientation: 'top',
    editable: {
    add: true,
    remove: true,
    updateTime: true,
    updateGroup: true
    }
    };

    // Create a Timeline
    var timeline = new vis.Timeline(container, items, options);

    // turn events on
    timeline.on('rangechange', function (properties) {
    logEvent('rangechange', properties);
    });
    timeline.on('rangechanged', function (properties) {
    logEvent('rangechanged', properties);
    });
    timeline.on('select', function (properties) {
    logEvent('select', properties);
    });

    items.on('*', function (event, properties) {
    logEvent(event, properties);
    });

    function logEvent(event, properties) {
    var log = document.getElementById('log');
    var msg = document.createElement('div');
    msg.innerHTML = 'event=' + JSON.stringify(event) + ', ' +
    'properties=' + JSON.stringify(properties);
    log.firstChild ? log.insertBefore(msg, log.firstChild) : log.appendChild(msg);
    AutoIt.call("ConsolePrint", msg.innerHTML);
    //AutoIt.call("MsgBox", 4096, "Maybe like this", msg.innerHTML);
    }
    </script>
    </body>
    </html>
#ce;HTML
;

 

  • Like 1

♡♡♡

.

eMyvnE

Share this post


Link to post
Share on other sites
Chimp

Hi @genius257, thanks very much for your interesting example (as usual from you)

Since I also like understand what's happening under the hood, and since I've never made use before of the AutoitObject.udf, in short this is what I understand:

I thought you built a mechanism that pushes events from Javascript to AutoIt. A reverse way from that used by the ObjEvent(), that instead it "Pulls" events directly  from within AutoIt by listening what's autonomously dispatched by javascript's objects. A bit twisted but quite interesting way,
But it's not like that, It's even better, as @trancexx kindly pointed out (many thanks @trancexx ),  you are not pushing events to AutoIt, but executing AutoiT code directly from within javascript as callback function in response to javascript events... surprising! (now I know why your name is @genius... :)

I've never looked at the AutoitObject.udf before, but I think I've missed something interesting... It's a very powerful tool indeed (if you know how and when to use it of course). It can open a very deep integration between AutoIt and the embedde Browser Control as in this case for example.
Wondering, since it seems an abbandoned thread :'( , if this is a stable and safe tool to use in production and with new OSes...

Many thanks again! @genius257 and @trancexx for the very appreciated and enlightening examples !

P.S.

:huh2: I'm still wondering why this isn't feasible using native ObjEvent() can't listen events fired by the javascript DataSet... ??

Edited by Chimp

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Share this post


Link to post
Share on other sites
genius257

 

3 hours ago, Chimp said:

Wondering, since it seems an abbandoned thread :'( , if this is a stable and safe tool to use in production and with new OSes.

Well if you want to make sure or change something, the source for the dll is included in the thread. I've tried looking into adding functionality for getter and setter, but I'm not experienced enough to fully understand it, and too lazy to read up so far :) maybe a day when I'm bored.

4 hours ago, Chimp said:

:huh2: I'm still wondering why this isn't feasible using native ObjEvent() can't listen events fired by the javascript DataSet... ??

As i understand the ObjEvent catches events from the object itself, so the browser object would haft to have some extra functionality, or javascript could use "fireEvent", with some information sent along with the event.

44 minutes ago, trancexx said:

You actually don't need AutoItObject for simple tasks like this, because ObjCreateInterface() exist for some time now, so you can write:

Wow! I didn't know that was possible thank you ;)

 

Edit:

4 hours ago, Chimp said:

code directly from within javascript as callback function in response to javascript events... surprising! (now I know why your name is @genius... :)

Thank you for your flattering compliment *blush*

4 hours ago, Chimp said:

Many thanks again! @genius257 and @trancexx for the very appreciated and enlightening examples !

Anytime! :D Glad i could help

Share this post


Link to post
Share on other sites
Chimp
1 hour ago, trancexx said:

.... You actually don't need AutoItObject for simple tasks like this ...

... simple taks like this??? :frantics: ....you are centuries ahead!

1 hour ago, trancexx said:

.... because ObjCreateInterface() exist for some time now, so you can write: .....

... you really fly high, even over the eagles :thumbsup:

 

@trancexx, WAW! you made my day. Thank you very much for this pearl of code! It simply achieves the goal without relying on 'third parts'...,

I really like it very much.... (even if I don't understand much of what's happening inner the script..:blink:).

what other to say?  ....thanks for existing! :)

 

 

49 minutes ago, genius257 said:

Well if you want to make sure or change something, the source for the dll is included in the thread. I've tried looking into adding functionality for getter and setter, but I'm not experienced enough to fully understand it, and too lazy to read up so far :) maybe a day when I'm bored.

@genius257 I am not able to do this, but.... I hope that you get bored sooner or later.... ;)

 

Thank you everybody !


small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Share this post


Link to post
Share on other sites
AdmiralAlkex
4 hours ago, trancexx said:

^^ AutoitObject isn't maintained. The version I tested with was compiled by @AdmiralAlkex and I think x64 version isn't working. I'm not sure if he changed some compile options or is it something else.

I had to install some helpfile creator or something, you can see my ramblings in the post before the upload... But I'm fairly sure I wouldn't have changed something that could affect the running of the code.

If anything's broken in a way it shouldn't be, maybe I didn't have the last version of the code. No one did ever clearly confirm that I did. I am not the only one with a copy of the SVN, am I?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Similar Content

    • guinness
      By guinness
      Just trying out the latest version of AutoIt and thinking more functional
      #include <Array.au3> ; Example ; An example of filtering, mapping and reducing arrays, using a function reference. ; This is similiar to how it would be done in the likes of JavaScript ; i.e. more functional (declarative) than procedural (imperative) ; Filter example Local $aiFilteredBefore[] = [1, 2, 3, 50, 30, 40, 20, 30] Local $aiFilteredAfter = _ArrayFilter($aiFilteredBefore, GtrThan30) _ArrayDisplay($aiFilteredAfter, '_ArrayFilter::') ; Map example Local $aiMappedBefore[] = [1, 2, 3, 4, 5, 6, 7, 8, 9] Local $aiMappedAfter = _ArrayMap($aiMappedBefore, MultiplyByTwo) _ArrayDisplay($aiMappedAfter, '_ArrayMap::') ; Reduce example ; Sum all values in the array Local $aiReducedBefore[] = [1, 2, 3, 50, 30, 40, 20, 30] ConsoleWrite('_ArrayReduce:: ' & _ArrayReduce($aiReducedBefore, SumValues) & @CRLF) ; Passing an empty array, will return the initial value; otherwise, sets @error to 4 ; if no initial value is defined Local $aEmpty[] = [] ConsoleWrite('_ArrayReduce:: ' & _ArrayReduce($aEmpty, SumValues, 0) & @CRLF) ; Array callback functions (for the examples only) Func GtrThan30($iValue) Return $iValue > 30 EndFunc ;==>GtrThan30 Func MultiplyByTwo($iValue, $iIndex, $aiArray) ; Notice how the function is called with the optional arguments "index" and "original array" ConsoleWrite('Index:: ' & $iIndex & ', Array:: ' & _ArrayToString($aiArray) & @CRLF) Return $iValue * 2 EndFunc ;==>MultiplyByTwo Func SumValues($a, $b) Return $a + $b EndFunc ;==>SumValues ; Functions ; The callback function is invoked with fn(value, [index, [array]]) Func _ArrayFilter($avArray, $hFunc) If Not IsArray($avArray) Then ; Null is more appropriate than returning the likes of -1 or an empty array Return SetError(1, 0, Null) EndIf If Not IsFunc($hFunc) Then Return SetError(2, 0, Null) EndIf Local Const $iLength = UBound($avArray) Local $avFiltered[$iLength] If $iLength = 0 Then Return $avFiltered EndIf Local $iIndex = 0 For $i = 0 To $iLength - 1 Local $bIsFiltered = __ArrayCall($hFunc, 3, $avArray[$i], $i, $avArray) If @error Then Return SetError(@error, @extended, Null) ElseIf $bIsFiltered Then $avFiltered[$iIndex] = $avArray[$i] $iIndex += 1 EndIf Next ReDim $avFiltered[$iIndex] Return $avFiltered EndFunc ;==>_ArrayFilter ; The callback function is invoked with fn(value, [index, [array]]) Func _ArrayMap($avArray, $hFunc) If Not IsArray($avArray) Then ; Null is more appropriate than returning the likes of -1 or an empty array Return SetError(1, 0, Null) EndIf If Not IsFunc($hFunc) Then Return SetError(2, 0, Null) EndIf Local Const $iLength = UBound($avArray) Local $avMapped[$iLength] If $iLength = 0 Then Return $avMapped EndIf For $i = 0 To $iLength - 1 $avMapped[$i] = __ArrayCall($hFunc, 3, $avArray[$i], $i, $avArray) If @error Then Return SetError(@error, @extended, Null) EndIf Next Return $avMapped EndFunc ;==>_ArrayMap ; The callback function is invoked with fn(current, value, [index, [array]]) Func _ArrayReduce($avArray, $hFunc, $vInitial = Default) If Not IsArray($avArray) Then ; Null is more appropriate than returning the likes of -1 or an empty array Return SetError(1, 0, Null) EndIf If Not IsFunc($hFunc) Then Return SetError(2, 0, Null) EndIf Local $bHasInitial = @NumParams >= 3 Local $iLength = UBound($avArray) If $iLength = 0 Then If Not $bHasInitial Then Return SetError(4, 0, Null) EndIf Return $vInitial EndIf For $i = 0 To $iLength - 1 If $bHasInitial Then $vInitial = __ArrayCall($hFunc, 3, $vInitial, $avArray[$i], $i, $avArray) If @error Then Return SetError(@error, @extended, Null) EndIf Else $bHasInitial = True $vInitial = $avArray[$i] EndIf Next Return $vInitial EndFunc ;==>_ArrayReduce Func __ArrayCall($hFunc, $iError, $vArg1 = Default, $vArg2 = Default, $vArg3 = Default, $vArg4 = Default) Local Const $CALL_ERROR = 0xDEAD Local Const $CALL_EXTENDED = 0xBEEF Local $vRet = Call($hFunc, $vArg1) If @error = $CALL_ERROR And @extended = $CALL_EXTENDED Then $vRet = Call($hFunc, $vArg1, $vArg2) If @error = $CALL_ERROR And @extended = $CALL_EXTENDED Then $vRet = Call($hFunc, $vArg1, $vArg2, $vArg3) If @error = $CALL_ERROR And @extended = $CALL_EXTENDED Then $vRet = Call($hFunc, $vArg1, $vArg2, $vArg3, $vArg4) If @error = $CALL_ERROR And @extended = $CALL_EXTENDED Then ; The function exists, but there is no appropriate function signature Return SetError($iError, 0, Null) EndIf EndIf EndIf EndIf Return SetError(@error, @extended, $vRet) EndFunc ;==>__ArrayCall  
    • Chimp
      By Chimp
      An example on how to inject jQuery into a web page
      It can be useful to manage the page from AutoIt using jQuery.
      Idea from here: http://www.learningjquery.com/2009/04/better-stronger-safer-jquerify-bookmarklet
      Suggestions and improvements are welcome
      #include <ie.au3> Example() Func Example() Local $oIE = _IECreate("www.google.com") Local $jQuery = _jQuerify($oIE) MsgBox(0, "Version", "jQuery version: " & $jQuery.fn.jquery) MsgBox(0, "Example", "click ok to exit." & @CRLF & "Google logo will fade out by jQuery...") $jQuery('#hplogo').fadeOut(3000) ; jQuery will fade out the google logo EndFunc ;==>Example ; #FUNCTION# ==================================================================================================================== ; Name ..........: _jQuerify ; Description ...: ; Syntax ........: _jQuerify(Byref $oIE) ; Parameters ....: $oIE - Object variable of an InternetExplorer.Application. ; Return values .: an object variable pointing to the jQuery library ; Author ........: Chimp ; Modified ......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: ; =============================================================================================================================== Func _jQuerify(ByRef $oIE) Local $jsEval, $jQuery, $otherlib = False ; create a reference to the javascript eval() function $oIE.document.parentWindow.setTimeout('document.head.eval = eval', 0) Do Sleep(250) $jsEval = Execute('$oIE.Document.head.eval') Until IsObj($jsEval) ; if jQuery is not already loaded then load it If $jsEval("typeof jQuery=='undefined'") Then ; check if the '$' (dollar) name is already in use by other library If $jsEval("typeof $=='function'") Then $otherlib = True Local $oScript = $oIE.document.createElement('script'); $oScript.type = 'text/javascript' ; If you want to load jQuery from a disk file use the following statement ; where i.e. jquery-1.9.1.js is the file containing the jQuery source ; (or also use a string variable containing the whole jQuery listing) ;~ $oScript.TextContent = FileRead(@ScriptDir & "\jquery-1.9.1.js") ; <--- from a file ; If you want to download jQuery from the web use this statement $oScript.src = 'https://code.jquery.com/jquery-latest.min.js' ; <--- from an url $oIE.document.getElementsByTagName('head').item(0).appendChild($oScript) Do Sleep(250) Until $jsEval("typeof jQuery == 'function'") EndIf Do Sleep(250) $jQuery = $jsEval("jQuery") Until IsObj($jQuery) If $otherlib Then $jsEval('jQuery.noConflict();') Return $jQuery EndFunc ;==>_jQuerify  
    • XaelloNegative
      By XaelloNegative
      Hi there.
      Im having some kind of a coder block here, 
      <td class="treeview ctl00_CenterContent_objTreeView_2" style="white-space:nowrap;"> <input type="checkbox" name="ctl00_CenterContent_objTreeViewn1CheckBox" id="ctl00_CenterContent_objTreeViewn1CheckBox"> <span class="ctl00_CenterContent_objTreeView_0 treeview ctl00_CenterContent_objTreeView_1" id="ctl00_CenterContent_objTreeViewt1" style="border-style:none;font-size:1em;"> <i class="fa fa-file-code-o fa-fw"> </i> <span data-placement="bottom" data-toggle="tooltip" title="" data-original-title="Tool tip for said part">REFUNDS</span></span></td> this is a code directly from the website im working with. I was thinking of inserting a javascript that would get the "REFUNDS" part. Any ideas on how to do so?
      Any thoughts will be highly appreciated.
    • tarretarretarre
      By tarretarretarre
      AutoIt-SocketIo
      Yep yep, this is pretty much an attempt to port the existing project's concept https://socket.io/ to AutoIt's Codebase. So i will not go in to so much detail.
      This is how the communication is done http://i.imgur.com/0mMfsBD.png Each client is isolated to the server http://i.imgur.com/rVO2LFb.png Features
      Easy API VarType Translation (Example: If the server sends an int, the client will receive an int and vice versa) Fully featured examples Data encryption (Using Autoit's UDF Crypt.au3) Limitations / Drawbacks
      It is not possible to Broadcast/Emit objects Only 1D-arrays are allowed to be Broadcasted/Emitted (2D arrays will probably never be supported) Changelog
      Version 1.5.0 (This update DOES NOT break scripts)
      Added AutoIt like docs under Docs\. The docs are generated so its a 1 to 1 reflection of the UDF headers. Print of documentation Added a production ready server example. Added a new method: _Io_DevDebug which will display useful information when debugging. Added a new method: _Io_SetMaxRecvPackageSize which defaults to whatever _Io_setRecvPackageSize is set to. Added a new method: _Io_setOnPrefix which defaults to _On_ Added a new default client & server event called flood. Flood occurs when exceeding the $__g_io_nMaxPacketSize. $__g_io_nMaxPacketSize is set by _Io_SetMaxRecvPackageSize Fixed the 16 parameter limit when sending data with _Io_Emit, _Io_Broadcast, _Io_BroadcastToAll and _Io_BroadcastToRoom. This works on the same premise that AutoIt's Call Does Fixed a TRUNCATION problem when receiving packages which could cause crashes! Fixed a programming error which caused $__g_ionPacketSize to reset to default 4096 if _Io_Connect or _Io_listenwere called after _Io_setRecvPackageSize Fixed _Io_setEventPreScript and _Io_setEventPostScript They didnt work. Lol. Changed how events are fired so the client cannot crash the server by sending the wrong number of parameters (This also allows for optional parameters on callbacks) Changed _Io_On. The second parameter $fCallback can now be set to null. Doing this, the function assumes that the callback is: _On_<eventName>.  
      Changelog History
      Api methods
      Please see the docs provided
      Default events
      Server events
      connection Client events
      banned Server and Client events
      disconnect flood View source on github
       
      Autoit-Socket-IO-1.0.0.zip (OLD!)
      Autoit-Socket-IO-1.1.0.zip (OLD)
      Autoit-Socket-IO-1.3.0.zip (OLD)
      Autoit-Socket-IO-1.4.0.zip (OLD)
      Autoit-Socket-IO-1.5.0.zip (NEWEST 2017-12-20)
    • Patryk
      By Patryk
      Dear Colleagues,
      I have no idea how to refer to style.display in my loop. There is a button like: 
      <input name="ctl00$bodyPlaceholder$btnFecharProcessamento" class="button" id="bodyPlaceholder_btnFecharProcessamento" style="display: none;" onclick="FecharJanelaProcessamento();return false;" type="submit" value="Fechar"> I want it to be clicked as soon as button's style change from style="display: none;" to  style= ="display: inline-block;" 
      This is what I got, but it's not working...
      Func GetButtons() $oButtons = _IEGetObjByName($oForm,"ctl00$bodyPlaceholder$btnFecharProcessamento",-1) $i = 0 While $i <> 1 For $oBtn In $oButtons If _IEFormElementGetValue($oBtn) = "Fechar" And $oBtn.document.style.display = "display: inline-block;" Then $i = 1 _IEAction($oBtn, "focus") _IEAction($oBtn, "click") ExitLoop EndIf Next WEnd EndFunc  
      I will really appreciate if you could help me with these loop!
×