Jump to content
Chimp

Autoit <-> Javascript roundtrip

Recommended Posts

Chimp

How can I do to let return a value from javascript to autoit?

I would like to use some javascript functions, passing values from AutoIt and get result back to autoit,
for example, this little snippet formats a number passed from autoit and show the result in an javascript alert box, but nothing is returned back to autoit.

#include <ie.au3>
Global $oIE = _IECreate("about:blank", 0, 0, 1, 0) ; use an hidden ie instance as a javascript "exposer"
$r = 1000000
$result = $oIE.document.parentwindow.execscript('alert(parseInt( ' & $r & ' ).toLocaleString());')
MsgBox(0, 0, $result)

any suggestions on how to have the result returned back to autoit is welcome
(avoiding temporary storage on phantom hidden fields or such alchemies please)
Thank you


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
Iczer

if FF is OK see my FFF - FireFoxFuctions

Share this post


Link to post
Share on other sites
Chimp

Hi Iczer
I had a look in your udf, but have not found there a way to easly call a javascript function and get back the result to AutoIt.
(even the function _ffcmd() from the ff.au3 seems a bit "hard coded" to me)
thanks for the replay


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
junkew

I assume with execscript that in the javascript you have to do a return "hello world".

I am not sure what you mean with your alchemy part but this is another way of having your things done

with AutoIT you can enter in any browser in any addressbar a bookmarklet/favlet short piece of javascript

javascript:<script>;void(0);

the void(0) is there that the active page does not get screwed

as you can do anything in those short scripts you can add an inputbox at the bottom of the page of pixelsize 1 by 1.

in the javascript you put your information in that inputbox which you then can read with regular autoit functions.

if you do not like that approach you allways can do an alert function in the addressbar and then read the modal dialog and click away the ok button

so type on any page this in your addressbar (with copy paste you loose javascript: so reenter that manually)

javascript:alert(document.body.innerHTML);void(0);

 

Share this post


Link to post
Share on other sites
Chimp

Thanks @junkew for your tips, I will give it a try.
...I still wonder if there is some other way to get results from javascript functions returned directly from the javascript function itself instead of from a "middleman" field (inputbox, alert.. or similar brokers)...

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
Chimp

..... I had given up on this concept, but coming again on this, I see that I was very close to the goal,

I've a way to build a bridge between AutoIt and Javascript.

in this way also the many external javascript library could be easly used from AutoIt.

here a basic example on how to use native javascript functions from AutoIt:

#include <IE.au3>
; *** create a minimal 'html' page listing for the browser
Local $sHTML = "<HTML><HEAD><script>" & @CRLF ; html opening tags
; here, within the HEAD tag, we insert the javascript code
; sence the .execscript method is no longer supported (https://msdn.microsoft.com/en-us/library/ms536420(v=vs.85).aspx)
; we have to use the eval method instead. A reference to the global object is needed to access the eval method. See here:
; http://stackoverflow.com/questions/9642491/getting-a-reference-to-the-global-object-in-an-unknown-environment-in-strict-mod
; http://perfectionkills.com/unnecessarily-comprehensive-look-into-a-rather-insignificant-issue-of-global-objects-creation/#ecmascript_5_strict_mode
$sHTML &= "var global = (1,eval)('this');" & @CRLF ; the 'global' variable get a handle to the global object

$sHTML &= "</script></HEAD></HTML>" & @CRLF ; html closing tags
; *** end of html page listing

Local $oIE = _IECreate("about:blank",0,0,0) ; an hidden browser (used as javascript engine provider)

_IEDocWriteHTML($oIE, $sHTML) ; inject above html (and library) in browser
_IEAction($oIE, "refresh")

; https://msdn.microsoft.com/en-us/library/52f50e9t(v=vs.94).aspx
Local $ohJS = $oIE.document.parentwindow.global ; $ohJS is a reference to the Global Obj
; ---- now the javascript engine can be used in our AutoIt script using the $ohJS reference ----

; example of use:
$i = 1000000 ; an unformatted number
; we use a javascript method to format our number
; and we get the result from javascript directly in an AutoIt variable by the javascript eval method ...
Local $result = $ohJS.eval('parseInt( ' & $i & ' ).toLocaleString();')
MsgBox(0,"Debug", $result)

_IEQuit($oIE)

Here, another example on how to use an external javascript library called moment.js.
it's a library similar to the #include <date.au3> but written in javascript.
you have to download the library and save it in the same path of this script before you run it:

#include <IE.au3>
;
; to load the moment.js library, get it from the site: http://momentjs.com/
; and save it to the script path prior to run this script
;
Local $sJScript = FileRead(".\moment.js") ; load library from disk
; you could also get it 'on the fly' from the net using InetRead() like this:
; Local $dJScript = InetRead("http://momentjs.com/downloads/moment.js")
; Local $sJScript = BinaryToString($dJScript)

; *** create a minimal 'html' page listing for the browser
Local $sHTML = "<HTML><HEAD><script>" & @CRLF ; html opening tags
;
; here, within the HEAD tag, we insert the javascript code
;
; sence the .execscript method is no longer supported (https://msdn.microsoft.com/en-us/library/ms536420(v=vs.85).aspx)
; we have to use the eval method instead. A reference to the global object is needed to access the eval method.
; see here:
; http://stackoverflow.com/questions/9642491/getting-a-reference-to-the-global-object-in-an-unknown-environment-in-strict-mod
; http://perfectionkills.com/unnecessarily-comprehensive-look-into-a-rather-insignificant-issue-of-global-objects-creation/#ecmascript_5_strict_mode
$sHTML &= "var global = (1,eval)('this');" & @CRLF ; the 'global' variable get a handle to the global object

; here we include the moment.js library within the HEAD tag (something like #include in AutoIt)
$sHTML &= $sJScript  & @CRLF

$sHTML &= "</script></HEAD></HTML>" & @CRLF ; html closing tags
; *** end of html page listing

Local $oIE = _IECreate("about:blank",0,0,0) ; an hidden browser (used as javascript engine provider)

_IEDocWriteHTML($oIE, $sHTML) ; inject above html (and library) in browser
_IEAction($oIE, "refresh")

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

; ---- now the javascript engine can be used in our AutoIt script using the $ohJS reference ----

; example of use:

$i = 1000000 ; an unformatted number

; we use a javascript method to format our number
; and we get the result from javascript directly in an AutoIt variable by the javascript eval method ...
Local $result = $ohJS.eval('parseInt( ' & $i & ' ).toLocaleString();')
MsgBox(0,"Debug", $result)

; here we use a function from the external moment.js library included above...
$result = $ohJS.eval("moment().format('LLLL');")
MsgBox(0, "Debug", $result)

_IEQuit($oIE)

I've tested those 2 draft scripts only on ie9 at the moment, but should work even on ie11 since I use the eval method instead of the now unsupported execScript method.

those 2 examples are just a proof of concept, and I think that can be improved, but in my opinion this "bridge" is an interesting tool....

improvements and suggestions are welcome.
Thank You everybody.

Edited by Chimp
  • Like 1

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

If you are only trying to get JavaScript returns with AutoIt I would suggest ScriptControl.

Example:

$oSC = ObjCreate("ScriptControl")
$oSC.Language = "JScript"
$oSC.AddCode("var testvar={a:123,b:456,c:789}"); or could be FileRead like: $oSC.AddCode(FileRead("script.js"))
$testvar = $oSC.Eval("testvar")
MsgBox(0, "", "testvar.a: "&$testvar.a&@CRLF&"testvar.b: "&$testvar.b&@CRLF&"testvar.c: "&$testvar.c)
MsgBox(0, "", "testvar.a+testvar.b+testvar.c = "&$oSC.Eval("testvar.a+testvar.b+testvar.c"))

Additional information here: Using the ScriptControl

Here's a finished solution:

 

  • Like 2

Share this post


Link to post
Share on other sites
Chimp

Waw! definitely interesting! Thanks alot @genius257  for the valuable information, the useful example (and the very interesting links). appreciated very much!

nonetheless, I also like the 'bridge' across Javascript and AutoIt as built ln my post above.

...What pro and/or cons (if any) on using the ScriptControl vs the explorer object and viceversa....? :think:

Just to not leave that script from post#7 'incomplete', I've to say that it was not working on win7 x64 + ie11, so here is a modified version that worked also on ie11.

Local $dJScript = InetRead("http://momentjs.com/downloads/moment.js") ; get a library from the net
Local $sJScript = BinaryToString($dJScript)
; Local $sJScript = FileRead(".\moment.js") ; or load library from disk

; *** create a minimal 'html' page listing for the browser
Local $sHTML = "<HTML><HEAD>" & @CRLF
$sHTML &= "<script>" & @CRLF ; Javascripts goes here
; $sHTML &= '"use strict";' & @CRLF ;
$sHTML &= 'var JSglobal = (1,eval)("this");' & @CRLF ; the 'global' variable get a handle to the javascript global object
$sHTML &= $sJScript & @CRLF ; #include <moment.js>
$sHTML &= "</script>" & @CRLF
$sHTML &= "</HEAD></HTML>" & @CRLF ; html closing tags
; *** end of html page listing

Local $oIE = ObjCreate("Shell.Explorer.2")
GUICreate("", 10, 10, @DesktopWidth + 10, @DesktopHeight + 10) ; place the gui out of screen
GUICtrlCreateObj($oIE, 0, 0, 10, 10) ; this render $oIE usable
GUISetState(@SW_HIDE) ; hide GUI

$oIE.navigate('about:blank')
While Not String($oIE.readyState) = 'complete' ; wait for about:blank
    Sleep(100)
WEnd

$oIE.document.Write($sHTML) ; inject lising directly to the HTML document:
$oIE.document.close() ; close the write stream
$oIE.document.execCommand("Refresh")

; this waits till the document is ready to be used (portion of code from IE.au3)
While Not (String($oIE.readyState) = "complete" Or $oIE.readyState = 4)
    Sleep(100)
WEnd
While Not (String($oIE.document.readyState) = "complete" Or $oIE.document.readyState = 4)
    Sleep(100)
WEnd

; https://msdn.microsoft.com/en-us/library/52f50e9t(v=vs.94).aspx
Local $ohJS = $oIE.document.parentwindow.JSglobal ; $ohJS is a reference to the javascript Global Obj
; ---- now the javascript engine can be used in our AutoIt script using the $ohJS reference ----

; simple example of use:
Local $i = 1000000 ; an unformatted number
; we use native javascript method to format our number
; and we get the result from javascript directly in an AutoIt variable by the javascript eval method ...
Local $result = $ohJS.eval('parseInt( ' & $i & ' ).toLocaleString();')
MsgBox(0, "Debug", $result)

; here we use a function from the 'external' moment.js library (included above...)
$result = $ohJS.eval("moment().format('LLLL');")
MsgBox(0, "Debug", $result)

 


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
43 minutes ago, Chimp said:

What pro and/or cons (if any) on using the ScriptControl vs the explorer object and viceversa....? :think:

ScriptControl is missing normal stuff from browser js sutch as native JSON (you can add it with a script). I remember having issues with trying to implement a script for string compression, but a few line changes to scriptcontrol here and there and it worked :) (It was lz-string.js and i believe it was some bitwise functionality).

A big pro with scriptcontrol is the functionallity with something like AutoIt. Using AutoItObject.Au3, you can call AutoIt functions from within Javascript functions. you are also able to add elements from AutoIt in Javascript, however things like AutoIt arrays are Unknown type in Javascript.

But if you are looking for webpage manipulation or such, IE is best.

I would advise to play around with it if you wish :)

Personally i love importing javascript elements into AutoIt, though in some cases the speed of AutoIt is more important than the flexibility of Javascript

 

Edit:

Here is a pdf export of my onenote page with scriptcontrol (seems better than browsing 3-4 pages for the same info)

 

ScriptControl.pdf

Edited by genius257
  • Like 1

Share this post


Link to post
Share on other sites
Chimp

thanks for the clarifications... :)


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

Javascript Array to AutoIt

... thanks to this JavaScript Object JSON, and to this method specifically JSON.stringify, it's possible (from IE9  and newer) to transfer an array from Javascript to AutoIt. (and eventually  using this other nice Json.au3 udf you can then recreate the same array in AutoIt)

This following simple script performs what said above, but, running the same script more times, it happens that sometime it works well, and sometime it fails on the JSON.stringify method on line 60. (I'm testing on win7 x64 IE9)

Anyone have any idea why this random error happens or what I'm doing wrong?
Thanks for any hint.

#include <AutoItConstants.au3>
; #include <array.au3>
; #include <Json.au3>

; *** create a minimal 'html' page listing for the browser
Local $sHTML = "<HTML><HEAD>" & @CRLF
$sHTML &= "<script>" & @CRLF ; Javascripts goes here

$sHTML &= 'var JSglobal = (1,eval)("this");' & @CRLF ; the 'global' variable get a handle to the javascript global object

; ============================ this Javascript returns an array
$sHTML &= '   function makeArray() {' & @CRLF
$sHTML &= 'var myArray = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];' & @CRLF
$sHTML &= 'return myArray;' & @CRLF
$sHTML &= '}' & @CRLF
; =============================================================

$sHTML &= "</script>" & @CRLF
$sHTML &= "</HEAD></HTML>" & @CRLF ; html closing tags
; *** end of html page listing

Local $oIE = ObjCreate("Shell.Explorer.2")
GUICreate("", 10, 10, @DesktopWidth + 10, @DesktopHeight + 10) ; place the gui out of screen
GUICtrlCreateObj($oIE, 0, 0, 10, 10) ; this render $oIE usable
GUISetState(@SW_HIDE) ; hide GUI

$oIE.navigate('about:blank')
While Not String($oIE.readyState) = 'complete' ; wait for about:blank
    Sleep(100)
WEnd

$oIE.document.Write($sHTML) ; inject lising directly to the HTML document:
$oIE.document.close() ; close the write stream
$oIE.document.execCommand("Refresh")

; this waits till the document is ready to be used (portion of code from the _IELoadWait() function in IE.au3)
While Not (String($oIE.readyState) = "complete" Or $oIE.readyState = 4)
    Sleep(100)
WEnd
While Not (String($oIE.document.readyState) = "complete" Or $oIE.document.readyState = 4)
    Sleep(100)
WEnd

; https://msdn.microsoft.com/en-us/library/52f50e9t(v=vs.94).aspx
Local $ohJS = $oIE.document.parentwindow.JSglobal ; $ohJS is a reference to the javascript Global Obj
; ---- now the javascript engine can be used in our AutoIt script using the $ohJS reference ----

; This call a javascript function that returns an javascript array
$result1 = $ohJS.eval('makeArray();')

; this obj is (should be) a javascript array (not recognized as is outside the javascript)
_ObjDescription($result1) ; this javascript array have to be 'serialized' in JSON

; Serializes a JavaScript value into 'JavaScript Object Notation' (JSON) text.
; https://msdn.microsoft.com/en-us/library/cc836459(v=vs.85).aspx
$result2 = $ohJS.JSON.stringify($result1) ; this sometime works and sometime fail ...?????? why <--- ??????

MsgBox(0, "Debug JSON string", $result2) ; a json string representing the array

; Local $Data1 = Json_Decode($result2)
; _ArrayDisplay($Data1)

Func _ObjDescription(ByRef $oObj)
    If IsObj($oObj) Then
        $sObjInfos = 'The name of the Object:' & @CRLF & ObjName($oObj, $OBJ_NAME) & @CRLF
        $sObjInfos &= '------------------------------------------------------------' & @CRLF
        $sObjInfos &= 'Description string of the Object:' & @CRLF & ObjName($oObj, $OBJ_STRING) & @CRLF
        $sObjInfos &= '------------------------------------------------------------' & @CRLF
        $sObjInfos &= 'The ProgID of the Object:' & @CRLF & ObjName($oObj, $OBJ_PROGID) & @CRLF
        $sObjInfos &= '------------------------------------------------------------' & @CRLF
        $sObjInfos &= 'The file that is associated with the object in the Registry:' & @CRLF & ObjName($oObj, $OBJ_FILE) & @CRLF
        $sObjInfos &= '------------------------------------------------------------' & @CRLF
        $sObjInfos &= 'Module name in which the object runs:' & @CRLF & ObjName($oObj, $OBJ_MODULE) & @CRLF
        $sObjInfos &= '------------------------------------------------------------' & @CRLF
        $sObjInfos &= "CLSID of the object's coclass:" & @CRLF & ObjName($oObj, $OBJ_CLSID) & @CRLF
        $sObjInfos &= '------------------------------------------------------------' & @CRLF
        $sObjInfos &= "IID of the object's interface:" & @CRLF & ObjName($oObj, $OBJ_IID) & @CRLF
        $sObjInfos &= '------------------------------------------------------------' & @CRLF
    Else
        $sObjInfos = "Is not an object)"
    EndIf
    MsgBox(0, "Debug: Obj info", $sObjInfos)
EndFunc   ;==>_ObjDescription

 

Edited by Chimp
corrections on the _ObjDescription() function

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

When i try to run your code it always fails.

Also the JSON object returns 'undefined' when i try to extract it with eval like below:

MsgBox(0, "", $ohJS.eval("typeof JSON"))

I hate to sound like a broken record, but why "Shell.Explorer.2" and not "ScriptControl"? Some requirements IE is better suited for in your scenario? :)

 

Edit:

Here's an example:

$oSC = ObjCreate("ScriptControl")
$oSC.Language = "JScript"
$oSC.AddCode(BinaryToString(InetRead("https://raw.githubusercontent.com/douglascrockford/JSON-js/master/json2.js")))
$oSC.Eval("Array.prototype.Item = function(i){return this[i];}"); enable fetching of array item with Array.Item function
$myArray = $oSC.Eval('["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]')
For $i=0 To $myArray.length-1
    ConsoleWrite( $myArray.Item($i) & @CRLF )
Next
MsgBox(0, "", $oSC.Eval("JSON").stringify($myArray))

 

Edited by genius257
  • Like 1

Share this post


Link to post
Share on other sites
Chimp
10 minutes ago, genius257 said:

When i try to run your code it always fails.

what IE version are you using?

om my system it works 50% of runs (....??)

12 minutes ago, genius257 said:

I hate to sound like a broken record, but why "Shell.Explorer.2" and not "ScriptControl"? Some requirements IE is better suited for in your scenario? :)

II would interact with objects on the embedded IE obj transfer arrays and eventually also interact with canvas... seems that this is not allowed with "ScriptControl", right?

p.s.

you don't sound at all like a broken record :)

 


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
11 minutes ago, Chimp said:

what IE version are you using?

Version: 11.633.10586.0

11 minutes ago, Chimp said:

II would interact with objects on the embedded IE obj transfer arrays and eventually also interact with canvas... seems that this is not allowed with "ScriptControl", right?

The interaction with a canvas is indeed impractical, if not impossible with "ScriptControl"

11 minutes ago, Chimp said:

you don't sound at all like a broken record :)

Thank you ;)

Share this post


Link to post
Share on other sites
Chimp

Thanks @genius257 for the example in post#13, nice one.

And is there some way to attach to an IE obj embedded in an AutoIt GUI (and related dom objects on it)?


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

... both

EDIT:

or better, I think you have first to attch to the IE obj and then using it to 'navigate' into it's DOM, or there is a way to directly attach to objects created within it?

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

Then something like the embedded object?

Opt("GuiOnEventMode", 1)

$oIE = ObjCreate("Shell.Explorer.2")
$hGui = GUICreate("Title", 700, 320)
GUISetOnEvent(-3, "_MyExit", $hGui)
GUISetState()
$hIE = GUICtrlCreateObj($oIE, 10, 10, 680, 300)
$oIE.navigate('about:blank')
$oIE.document.Write('<!DOCTYPE HTML><html><head><style>body{background-color:#010;color:#FFF;}</style></head><body>this is the body</body></html>')
While 1
    Sleep(10)
WEnd

Func _MyExit()
    Exit
EndFunc

 

Share this post


Link to post
Share on other sites
Chimp

@genius257 ...sorry for the delay...

... that listing for example could be the 'basic' gui, then, in short, I would 'write' for example this page (a timeline from this site) into the embbedded IE, and finally use "ScriptControl" (or whatever) to interact with the timeline so to use it as a graphic frontend where to display data, while data is managed by AutoIt on an SQLite database for example...
I was trying now to do something like that, but I'm having problems on opening the above page into the embedded IE (the timeline is not shown...)
I will come back to this tomorrow.... 02:58 AM here....

.....thanks for any help.... :)

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

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

    • Chimp
      By Chimp
      The DOM allows to do anything with elements and their contents, but first we need to reach the corresponding DOM object, get it into a variable, and then we are able to modify it. *
      Well, this little tool (although it is not very nice aesthetically) allows you to get visually a "selector" usable to reference DOM objects.
      Once you have the "selector" of an element you can pass it to the javascript querySelector() function that will return a reference to that element.
      To use this tool you have to:
      1) open the web page you want to inspect into IE browser
      2) run this script (if it find more instances of IE running, it allows you to chose one)
      3) move the mouse over the browser. The "selector" of the element below the pointer is catched automatically while hovering. To copy the selector in the clipboard just right click on the element.
      As you can see, while hovering, the element pointed by the mouse is highlighted with a thin red dotted frame to allow you to better "take aim"
      when the selector is copied to the clipboard a little acoustic signal is emitted as a confirm, then you can paste it in your listing where you need it.
      I hope it can come in handy and save you time when you need to automate a site .... have fun
      #include <IE.au3> #include <GUIConstantsEx.au3> #include <GuiListBox.au3> #include <WindowsConstants.au3> #include <Misc.au3> ; for _IsPressed (23 END key) Global $hDLL = DllOpen("user32.dll") ; following global variables are automatically updated by events from the browser ; ------------------------------------------------------------------------------------- Global $g_iMouseX, $g_iMouseY ; coordinates of the mouse while mooving over the browser Global $bCopySelector = False ; becomes True when you right click on wanted element ; ------------------------------------------------------------------------------------- Global $oIE = _Get_IE() ; get IE instance to inspect If IsObj($oIE) Then $hIE = _IEPropertyGet($oIE, "hwnd") WinActivate($hIE) _InspectElements() EndIf DllClose($hDLL) Exit Func _InspectElements() ; it uses the global variable $oIE as source ; --- set IE to interact with AutoIt --- Local $oDocument Do ; wait for document Sleep(250) $oDocument = $oIE.document Until IsObj($oDocument) Local $oWindow = $oDocument.ParentWindow ; create a reference to the javascript eval method ; in the body section of the dovument $oWindow.setTimeout("document.body.JSeval = eval; ", 0) ; attach the $JSeval variable to the javascript eval method Local $JSeval Do $JSeval = Execute('$oIE.Document.body.JSeval') Until IsObj($JSeval) ; --------------------------------------------- ; Inject Javascript functions/elements to $oIE ; --------------------------------------------- ; Get the DOM path of an element (a CSS selector) ; ----------------------------------------------- ; This javascript function returns the CSS selector of the passed element. ; You can then use the returned path to get a reference to the pointed ; element by the QuerySelector() javascript function ; function copied from the following link: ; https://stackoverflow.com/questions/5728558/get-the-dom-path-of-the-clicked-a ; see answer by "Aleksandar Totic" (thanks to him) Local $sJScript = "" & _ " function getDomPath(el) {" & _ " if (!el) {" & _ " return;" & _ " }" & _ " var stack = [];" & _ " var isShadow = false;" & _ " while (el.parentNode != null) {" & _ " var sibCount = 0;" & _ " var sibIndex = 0;" & _ " for ( var i = 0; i < el.parentNode.childNodes.length; i++ ) {" & _ " var sib = el.parentNode.childNodes[i];" & _ " if ( sib.nodeName == el.nodeName ) {" & _ " if ( sib === el ) {" & _ " sibIndex = sibCount;" & _ " }" & _ " sibCount++;" & _ " }" & _ " }" & _ " var nodeName = el.nodeName.toLowerCase();" & _ " if (isShadow) {" & _ " nodeName += ""::shadow"";" & _ " isShadow = false;" & _ " }" & _ " if ( sibCount > 1 ) {" & _ " stack.unshift(nodeName + ':nth-of-type(' + (sibIndex + 1) + ')');" & _ " } else {" & _ " stack.unshift(nodeName);" & _ " }" & _ " el = el.parentNode;" & _ " if (el.nodeType === 11) {" & _ " isShadow = true;" & _ " el = el.host;" & _ " }" & _ " }" & _ " stack.splice(0,1);" & _ " return stack.join(' > ');" & _ " }" ; more infos here: https://www.kirupa.com/html5/finding_elements_dom_using_querySelector.htm ; Inject the above javascript function contained in the $sJScript variable into the document _JS_Inject($oIE, $sJScript) Local $_getDomPath ; a reference to call above function from AutoIt Do Sleep(250) $_getDomPath = $jsEval("getDomPath") Until IsObj($_getDomPath) ; ; ; Inject a DIV in the web page ; ---------------------------- ; it will be used to higligt selected element $sJScript = 'au3_div = document.createElement("div");' & _ 'au3_div.style.position = "fixed"; ' & _ 'au3_div.style.width = " 10px"; ' & _ 'au3_div.style.height = " 10px"; ' & _ 'au3_div.style.top = "0px"; ' & _ 'au3_div.style.left = "0px"; ' & _ 'au3_div.style.background = "rgba(0, 255, 0, 0.4);"; ' & _ 'au3_div.style.color = " white"; ' & _ 'au3_div.style.zIndex = "10000"; ' & _ 'au3_div.style.visibility = "hidden"; ' & _ 'document.body.appendChild(au3_div);' _JS_Inject($oIE, $sJScript) Do Sleep(250) $oMyDIV = $jsEval("au3_div") Until IsObj($oMyDIV) ; ------------------- ; hook some IE events ; ------------------- Local $oEventObjects[2], $oEventsSource $oEventsSource = $oIE.document.documentElement ; element we want catch events from ; https://docs.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/platform-apis/aa769636(v=vs.85) $oEventObjects[0] = ObjEvent($oEventsSource, "_HTMLElementEvents2_", "HTMLElementEvents2") ; https://docs.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/platform-apis/aa768283(v%3dvs.85) $oEventObjects[1] = ObjEvent($oIE, "_IEEvent_", "DWebBrowserEvents2") ; open a GUI where to show some element's properties ; -------------------------------------------------- Local $hGUIMain = GUICreate("Info", 500, 100, -1, -1, -1, $WS_EX_TOPMOST) Local $hProperties = GUICtrlCreateEdit("", 0, 0, 500, 100) GUICtrlSetFont(-1, 9, -1, -1, "Courier New") GUISetState() ;Show GUI ; -------------------------------------------------- ; --------- ; Main loop ; --------- Local $iMouseX, $iMouseY, $oElement, $oNewElement, $sSelector Local $oGotElement, $sElementInfos Local $sSaved_StyleOutline ; Loop until the user exits. While IsObj($oIE) Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop ; ---> end EndSwitch If ($g_iMouseX <> $iMouseX) Or ($g_iMouseY <> $iMouseY) Then $iMouseX = $g_iMouseX $iMouseY = $g_iMouseY ; $oElement = $oIE.document.elementFromPoint($iMouseX, $iMouseY) ; <-- this way is slower $oNewElement = $JSeval('document.elementFromPoint(' & $iMouseX & ',' & $iMouseY & ');') If $oNewElement <> $oElement Then If IsObj($oElement) Then $oElement.style.outline = $sSaved_StyleOutline $oElement = $oNewElement ; $bSelfie = False ; $iSelf_Timer = TimerInit() $sSaved_StyleOutline = $oElement.style.outline ; save original element outline style $sSelector = $_getDomPath($oElement) If $sSelector <> "" Then $oGotElement = $JSeval('document.querySelector("' & $sSelector & '");') $oGotElement.style.outline = "1px dashed red" ; mark new pointed element ; https://css-tricks.com/ $sElementInfos = "" & _ "nodeName: " & $oGotElement.nodeName & @CRLF & _ "id: " & $oGotElement.id & @CRLF & _ "---------" & @CRLF & _ $sSelector ControlSetText($hGUIMain, "", $hProperties, $sElementInfos) EndIf EndIf EndIf If $bCopySelector And ($sSelector <> "") Then ; And (TimerDiff($iSelf_Timer) > $bSelfie_Delay) Then ; ToolTip ( $sSelector, Default, Default, "", 1, 1) $oMyDIV.style.left = $oGotElement.getBoundingClientRect().left & "px" $oMyDIV.style.top = $oGotElement.getBoundingClientRect().top & "px" $oMyDIV.style.width = $oGotElement.offsetWidth & "px" $oMyDIV.style.height = $oGotElement.offsetHeight & "px" $oMyDIV.style.visibility = "visible" ; shows the green overlay DIV ClipPut($sSelector) $sElementInfos &= @CRLF & "selector copied to ClipBoard" ControlSetText($hGUIMain, "", $hProperties, $sElementInfos) Beep(2000, 50) $bCopySelector = False Sleep(250) $oMyDIV.style.visibility = "hidden" ; hides the green overlay DIV ; ToolTip('') EndIf If _IsPressed("23", $hDLL) Then ; END key pressed If IsObj($oElement) Then $oElement.style.outline = $sSaved_StyleOutline WinActivate($hGUIMain) ; WinSetState($hGUIMain, "", @SW_SHOW) $aWin = WinGetPos($hGUIMain) MouseMove($aWin[0] + $aWin[2] / 2, $aWin[1] + $aWin[3] / 2, 0) EndIf WEnd ; the end ; ------------------------------------------ For $i = 0 To UBound($oEventObjects) - 1 ; Tell IE we don't want to receive events. $oEventObjects[$i] .Stop $oEventObjects[$i] = 0 Next $oIE = 0 ; Remove IE from memory GUIDelete($hGUIMain) ; Remove GUI ; ------------------------------------------ EndFunc ;==>_InspectElements Func _Get_IE() ; Example 5 from the _IEAttach help ; Create an array of object references to all current browser instances ; The first array element will contain the number of instances found Local $aIE[1] $aIE[0] = 0 Local $i = 1, $oIEx While 1 $oIEx = _IEAttach("", "instance", $i) If @error = $_IEStatus_NoMatch Then ExitLoop ReDim $aIE[$i + 1] $aIE[$i] = $oIEx $aIE[0] = $i $i += 1 WEnd If $aIE[0] > 0 Then If $aIE[0] = 1 Then Return $aIE[1] ; only one IE is running, return this then ; ; Create a little list box to choose the IE instance from Local $hChoose_IE = GUICreate("IE Instances", 600, 350) Local $Label1 = GUICtrlCreateLabel($aIE[0] & " running Instances of IE browser found, click the one you want to attach to then click on 'ok'", 5, 5, 590, 20) Local $List1 = GUICtrlCreateList("", 5, 30, 590, 300, BitOR($LBS_STANDARD, $LBS_EXTENDEDSEL)) Local $hButton_choosed = GUICtrlCreateButton("OK", 5, 325, 590, 20) For $i = 1 To $aIE[0] GUICtrlSetData($List1, $i & ") " & _IEPropertyGet($aIE[$i], "locationurl")) Next GUISetState(@SW_SHOW) While 1 ; wait for a selection Switch GUIGetMsg() Case $GUI_EVENT_CLOSE GUIDelete($hChoose_IE) Return False Case $hButton_choosed $aSelected = _GUICtrlListBox_GetSelItems($List1) If $aSelected[0] Then GUIDelete($hChoose_IE) Return $aIE[$aSelected[1] + 1] Else MsgBox(0, "Info", "Please select an item") EndIf EndSwitch WEnd Else MsgBox(0, 'error', "Sorry" & @CRLF & @CRLF & "no running IE instances found") EndIf EndFunc ;==>_Get_IE ; this function creates a javascript script into the html document ; of the passed $oIE object using the createElement method. Func _JS_Inject($oIE, $sJScript, $bIsUrl = False) ; ; get a reference to the document object Local $objDocument = $oIE.document ; Local $oScript = $objDocument.createElement('script') ; $oScript.type = 'text/javascript' If $bIsUrl Then $oScript.src = $sJScript ; works if $sJScript is a link to a js listing (url) Else ; (https://stackoverflow.com/questions/35213147/difference-between-text-content-vs-inner-text) ; $oScript.innerText = $sJScript $oScript.TextContent = $sJScript ; works if $sJScript contains the listing itself EndIf ; $objDocument.getElementsByTagName('head').item(0).appendChild($oScript) ; $objDocument.getElementsByTagName('head').item(0).removeChild($oScript); ; EndFunc ;==>_JS_Inject ; ------------------------------------------------------------------- ; following function(s) are called by registered $oIE elements events ; ------------------------------------------------------------------- ; ; The function automatically fired by an event ; will receive as parameter an Event Obj. ; This obj has properties related to ; the object that fired the event. ; See following link: ; https://msdn.microsoft.com/en-us/library/aa703876(v=vs.85).aspx ; function called by the mousemove event ; we use this to update 2 global variables: Volatile Func _HTMLElementEvents2_onMousemove($oEvent) $g_iMouseX = $oEvent.clientX $g_iMouseY = $oEvent.clientY EndFunc ;==>_HTMLElementEvents2_onMousemove ; function called by the contextmenu event ; we use this to update 1 global variable ; and we also neutralize this event: Volatile Func _HTMLElementEvents2_onContextmenu($oEvent) $oEvent.cancelBubble = True ; event propagation cancelled $oEvent.returnValue = False ; prevent default behaviour $bCopySelector = True ; when True, selector will be copied to clipboard in main loop EndFunc ;==>_HTMLElementEvents2_onContextmenu ; https://docs.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/platform-apis/aa768280%28v%3dvs.85%29 Func _IEEvent_BeforeNavigate2($oIEpDisp, $sIEURL, $iIEFlags, $sIETargetFrameName, $sIEPostData, $iIEHeaders, $bIECancel) ;ConsoleWrite("Debug: navigate away cancelled." & @CRLF) ; https://stackoverflow.com/questions/6526876/how-to-cancel-or-dispose-current-navigation-at-webbrowser-element $oIE.stop EndFunc ;==>_IEEvent_BeforeNavigate2 Here is a simple example on how a "selector" can be used in AutoIt.
      suppose we want automate the login to the AutoIt site with our username and password.
      I've already prepared a very simple "template" where are missing some important parts without which the script can't work. Missing parts are the references to the elements of the AutoIt web page that we have to manage by our script.
      well, here is where the tool I have just posted here above comes to our help.
      follow this steps:
      1) in IE open the AutoIt site at the forum page (https://www.autoitscript.com/forum/)
      2) run the above tool (select the IE instance and/or bring it to front if needed)
      3) when the script is "ready", move the mouse over the "Existing user? Sign In" string and right click the mouse button. Doing so the "selector" of that element is copied to the clipboard. Now we can paste it in our AutoLogIt.au3 script as value of the $sSignIn variable.
      4) now click on the "Existing user? Sign In"  to open the "Sig In" session from where we will copy selectors of each of the 2 input box Username and Password, in the same way as we have already done in step 3, and paste those selectors to the $sInputUserId and $sInputPasswd variables respectively.
      5) do the same for the "Sign In" Button and paste it's selector to the $sSignInButn variable
      6) of course also fill the $sMyUserId and $sMyPasswd variables with your data.
      That's It. Run the AutoLogIt script and it should Log you on automatically to the forum.
      AutoLogIt.au3
      #include <ie.au3> $sMyUserId = "" ; <-- your userid here $sMyPasswd = "" ; <-- your password here ; set selectors here $sSignIn = "" ; <-- SigIn element selector here $sInputUserId = "" ; <-- UserId input selector here $sInputPasswd = "" ; <-- Password input selector here $sSignInButn = "" ; <-- Sig In button selector here $oIE = _IECreate("https://www.autoitscript.com/forum/") ; here is how to use the QuerySelector javascript function $hDOM_Element = $oIE.document.QuerySelector($sSignIn) ; get the "sign in" link element ; perform a click action on the above element $hDOM_Element.click() ; or _IEAction($hDOM_Element, "click") as well ; fill the username input $hDOM_Element = $oIE.document.QuerySelector($sInputUserId) $hDOM_Element.value = $sMyUserId ; fill the password input $hDOM_Element = $oIE.document.QuerySelector($sInputPasswd) $hDOM_Element.value = $sMyPasswd ; .... or also using the dot notation directly .... $oIE.document.QuerySelector($sSignInButn).click() Sleep(5000) ; this should logout $sMenu = "body > div:nth-of-type(2) > header > div > ul > li:nth-of-type(6) > a:nth-of-type(2)" $oIE.document.QuerySelector($sMenu).click() $sLogOut = "body > ul > li:nth-of-type(9) > a" $oIE.document.QuerySelector($sLogOut).click()  
    • Chimp
      By Chimp
      This is a little experiment that makes use of a "Browser Control" embedded in a GUI in order to be able to use AutoIt, HTML, JavaScript and CSS all together.
      This little toy will only work on systems with IE11.
      The purpose is to drag all the names of the scientists & drop on the right ones. (among scientists it has also infiltrated an intruder). I hope you find it entertaining.
      I've posted it here in the hope to have some suggestions on how to improve it all (I mean the interaction between Autoit Javascript html and css). Thanks
      ; this works on systems with IE11 ; ------------------------------- #include <GUIConstantsEx.au3> #include <array.au3> Global $oIE, $oDocument, $ohJS, $sDroping Global $iCorrect = 0, $iGoal = 11 Example() Exit Func Example() Local $aScientists[12][2] = _ [["Schrodinger", "Schrodinger"],["Planck", "Planck"],["Pauli", "Pauli"],["Einstein", "Einstein"], _ ["Chimp", "Chimp"],["Dirac", "Dirac"],["Heisenberg", "Heisenberg"],["Born", "Born"], _ ["De Broglie", "De_Broglie"],["Bohr", "Bohr"],["Sommerfeld", "Sommerfeld"],["", "empty"]] Local $oIE = ObjCreate("Shell.Explorer.2") ; Create a BrowserControl Local $hGUI = GUICreate("", 660, 600, 30, 30) GUICtrlCreateObj($oIE, 0, 0, 660, 600) ; Place BrowserControl on the GUI GUISetState() ;Show GUI $oIE.navigate('about:blank') ; file:///' & @ScriptDir & '\WhoIsWho.html') While Not String($oIE.readyState) = 'complete' ; wait for about:blank Sleep(100) WEnd ; this waits till the document is ready to be used (portion of code from IE.au3) While Not (String($oIE.readyState) = "complete" Or $oIE.readyState = 4) Sleep(100) WEnd While Not (String($oIE.document.readyState) = "complete" Or $oIE.document.readyState = 4) Sleep(100) WEnd $oIE.document.Write(_GetHTML()) ; inject lising directly to the HTML document: $oIE.document.close() ; close the write stream $oIE.document.execCommand("Refresh") While Not String($oIE.readyState) = 'complete' ; wait for readyState after a refresh Sleep(100) WEnd ; https://msdn.microsoft.com/en-us/library/52f50e9t(v=vs.94).aspx ; $ohJS is a reference to the javascript Global Obj ; ------------------------------------------------- $ohJS = $oIE.document.parentwindow.JSglobal $oDocument = $oIE.document Local $oTable1 = $ohJS.table1 Local $oTable2 = $ohJS.table2 _Randomize($aScientists, $oTable1) ; --- Setup events ------------ ; https://msdn.microsoft.com/en-us/library/hh801967(v=vs.85).aspx Local $aoEventObject[2] $aoEventObject[0] = ObjEvent($oTable1, "IEEvent_", "HTMLTableEvents2") $aoEventObject[1] = ObjEvent($oTable2, "IEEvent_", "HTMLTableEvents2") ; ----------------------------- ; Loop until the user exits. While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop EndSwitch If $iCorrect = $iGoal Then _Goal() _Randomize($aScientists, $oTable1) $iCorrect = 0 EndIf WEnd ; the end For $i = 0 To UBound($aoEventObject) - 1 $aoEventObject[$i] .stop Next $aoEventObject = 0 ; Kill the Event Object $oIE = 0 ; Remove IE from memory (not really necessary). GUIDelete($hGUI) ; Remove GUI EndFunc ;==>Example ; --- event management zone --- ; following functions are fired by events occurred in the browser control Volatile Func IEEvent_onDragstart($oEvent) ; we save the ID of the dragged obj into the $sDroping variable ; for a later use in the drop function $sDroping = $oEvent.srcElement.ID EndFunc ;==>IEEvent_onDragstart Volatile Func IEEvent_onDragOver($oEvent) $ohJS.event.preventDefault() EndFunc ;==>IEEvent_onDragOver Volatile Func IEEvent_onDrop($oEvent) $ohJS.event.preventDefault() If $sDroping <> "" Then If $oDocument.getElementById($sDroping).innerText <> $oEvent.srcElement.innerText Then If $oEvent.srcElement.ClassName = $oDocument.getElementById($sDroping).ClassName Then $oEvent.srcElement.innerText = $oDocument.getElementById($sDroping).innerText $oDocument.getElementById($sDroping).innerText = "" $oDocument.getElementById($sDroping).draggable = False $oDocument.getElementById($sDroping).setAttribute("style") = "background-color: #80ff80;" $iCorrect += 1 Else For $i = 1 To 3 $oDocument.getElementById($sDroping).setAttribute("style") = "background-color: #ff0000;" Sleep(125) $oDocument.getElementById($sDroping).setAttribute("style") = "background-color: #ffffff;" Sleep(125) Next EndIf EndIf $sDroping = "" EndIf EndFunc ;==>IEEvent_onDrop Func _Randomize(ByRef $aScientists, ByRef $oTable) Local $iRows = ($oTable.rows.length) - 1 Local $iCols = ($oTable.rows.item(0).cells.length) - 1 Local $index _ArrayShuffle($aScientists) For $y = 0 To $iRows For $x = 0 To $iCols $index = ($y * ($iCols + 1)) + $x $oTable.rows.item($y).cells.item($x).innerText = $aScientists[$index][0] ; text $oTable.rows.item($y).cells.item($x).className = $aScientists[$index][1] ; class $oTable.rows.item($y).cells.item($x).draggable = $aScientists[$index][0] <> "" Next Next EndFunc ;==>_Randomize Func _Goal() Local $oTable1 = $ohJS.table1 ; names Local $oTable2 = $ohJS.table2 ; photos Local $iRows = ($oTable1.rows.length) Sleep(250) Local $iCols = 6 ; ($oTable1.rows.item(0).cells.length) Local $aIndex[$iRows * $iCols], $sTemp For $i = 0 To UBound($aIndex) - 1 $aIndex[$i] = $i ; + 1 Next _ArrayShuffle($aIndex) For $i = 0 To UBound($aIndex) - 1 $oTable2.rows.item(Int($aIndex[$i] / $iCols)).cells.item(Mod($aIndex[$i], $iCols)).innerText = "" $oTemp0 = $oTable2.rows $oTemp1 = $oTemp0.item(Int($aIndex[$i] / $iCols)).cells $oTemp2 = $oTemp1.item(Mod($aIndex[$i], $iCols)).getAttribute("style") $oTable2.rows.item(Int($aIndex[$i] / $iCols)).cells.item(Mod($aIndex[$i], $iCols)).setAttribute("style") = "background-color: " & _rndColor() Sleep(100); MsgBox(0,"Debug",$sTemp) $oTable2.rows.item(Int($aIndex[$i] / $iCols)).cells.item(Mod($aIndex[$i], $iCols)).setAttribute("style") = $oTemp2 Next For $x = 1 To 2 For $i = 0 To UBound($aIndex) - 1 $oTable1.rows.item(Int($aIndex[$i] / $iCols)).cells.item(Mod($aIndex[$i], $iCols)).setAttribute("style") = "background-color: " & _rndColor() Sleep(100) $oTable1.rows.item(Int($aIndex[$i] / $iCols)).cells.item(Mod($aIndex[$i], $iCols)).setAttribute("style") = "background-color: #ffffff;" Next Next EndFunc ;==>_Goal Func _rndColor() Return String("#" & Hex(Random(0, 255, 1), 2) & Hex(Random(0, 255, 1), 2) & Hex(Random(0, 255, 1), 2) & ";") EndFunc ;==>_rndColor Func _GetHTML() Local $sHTML = _ "<!DOCTYPE HTML>" & @CRLF & _ "<html>" & @CRLF & _ "<head>" & @CRLF & _ "<meta http-equiv=""X-UA-Compatible"" content=""IE=edge"" />" & @CRLF & _ " <script type=""text/javascript"">" & @CRLF & _ " var JSglobal = (1,eval)(""this"");" & @CRLF & _ " </script>" & @CRLF & _ "</head>" & @CRLF & _ "<body>" & @CRLF & _ "<h2>Who is who?</h2>" & @CRLF & _ "<p>Drag&Drop names on the right scientist</p>" & @CRLF & _ "<img src=""http://oi66.tinypic.com/2q0lue9.jpg""" & @CRLF & _ "height=""394"" width=""640""" & @CRLF & _ "style=""position: absolute; left: 10px; top: 100px;"">" & @CRLF & _ "" & @CRLF & _ "<style>" & @CRLF & _ ".target td {width: 100px; height: 160px; text-align: center; color: white; font-weight: bold; vertical-align: bottom; border: 0px solid grey;}" & @CRLF & _ ".source td {width: 100px; height: 30px; text-align: center; border: 1px solid red;}" & @CRLF & _ "</style>" & @CRLF & _ "" & @CRLF & _ "<table class=""target"" style=""position: absolute; left: 25px; top: 100px;"" id=""table2"">" & @CRLF & _ " <tr><td class=""Schrodinger""></td><td class=""Planck""></td><td class=""Pauli""></td><td class=""Einstein""></td><td class=""Chimp""></td><td class=""Dirac""></td></tr>" & @CRLF & _ " <tr><td class=""Heisenberg""></td><td class=""Born""></td><td class=""De_Broglie""></td><td class=""Bohr""></td><td class=""Sommerfeld""></td><td class=""empty""></td></tr>" & @CRLF & _ "</table>" & @CRLF & _ "" & @CRLF & _ "<table class=""source"" style=""position: absolute; left: 10px; top: 504px;"" id=""table1"">" & @CRLF & _ " <tr><td ID=""td1""></td><td ID=""td2""></td><td ID=""td3""></td><td ID=""td4"" ></td><td ID=""td5"" ></td><td ID=""td6"" ></td></tr>" & @CRLF & _ " <tr><td ID=""td7""></td><td ID=""td8""></td><td ID=""td9""></td><td ID=""td10""></td><td ID=""td11""></td><td ID=""td12""></td></tr>" & @CRLF & _ "</table>" & @CRLF & _ "</body>" & @CRLF & _ "</html>" Return $sHTML EndFunc ;==>_GetHTML  
    • Seminko
      By Seminko
      Is there a way to grab non-hardcoded but rather javascript generated data from a webpage?
      Tried a get request as well as _IEBodyReadHTML but both seem to grab the code without the javascript generated data.
      $oHTTP = ObjCreate("winhttp.winhttprequest.5.1") $oHTTP.Open("GET", "link", False) $oHTTP.Send() $oReceived = $oHTTP.ResponseText $oStatusCode = $oHTTP.Status Global $DataArray[10][5] If $oStatusCode <> 200 Then Exit MsgBox(1, "Error", "Status Code <> 200") EndIf FileWrite(@ScriptDir & "\output.txt", $oReceived) ; //////// #include <IE.au3> Local $FullLink = "link" Local $oIE = _IECreate($FullLink, 0, 0) _IELoadWait($oIE) Local $sText = _IEBodyReadHTML($oIE) FileWrite(@ScriptDir & "\output.txt", $sText)  
    • 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  
×