Get Title and Url of the active browser tab

Post your working scripts, libraries and tools for AHK v1.1 and older
User avatar
rommmcek
Posts: 1478
Joined: 15 Aug 2014, 15:18

Re: Get Title and Url of the active browser tab

24 Jan 2021, 12:10

Just a moment...
I had to clean up the code a bit...
It will copy the results to the Clipboard and save them to the file (in the script folder) too. If you don' want to write to your HD you can comment the FileAppend command.
Attachments
Get Acc children.ahk
(3.32 KiB) Downloaded 310 times
Last edited by rommmcek on 24 Jan 2021, 13:02, edited 1 time in total.
c4p
Posts: 21
Joined: 18 Jan 2017, 18:38

Re: Get Title and Url of the active browser tab

04 Feb 2021, 14:40

curious, I am not getting anything for the URL in MS Edge or Google Chrome. Is this likely because of the dated OS install? Unfortunately a work computer which I can't upgrade.

Win 10 Pro
Ver 1909
Installed 2/9/20
Build 8.18363.1316

MS Edge
Version 88.0.705.56 (Official build) (64-bit)

Google Chrome
Version 87.0.4280.141 (Official Build) (64-bit)
User avatar
rommmcek
Posts: 1478
Joined: 15 Aug 2014, 15:18

Re: Get Title and Url of the active browser tab

04 Feb 2021, 16:25

Guess: I think old OS version is not a problem, but improper blocking/postponing of OS updates can lead to partially/broken driver updates. In that case obviously GetAccData() can't work as designed.
I'm an amateur and certainly not an IT expert, so I can't propose which driver to update!

P.s.: If you run Get Acc children on those browsers and search for Role: 42 (if it exists), what are the results for Name and Value?
User avatar
tdalon
Posts: 44
Joined: 21 Apr 2017, 07:19
Location: Germany
Contact:

Re: Get Title and Url of the active browser tab

08 Feb 2021, 16:23

Hi.
Just giving it a try. For Chrome it works nicely.
For Vivaldi thought no url is returned. Have you tried it with Vivaldi? (I have the latest Vivaldi version)
User avatar
rommmcek
Posts: 1478
Joined: 15 Aug 2014, 15:18

Re: Get Title and Url of the active browser tab

08 Feb 2021, 17:11

Vivaldi does not support Accessibility by default, so you have to run it with a switch e.g. vivaldi.exe --force-renderer-accessibility
tuzi
Posts: 223
Joined: 27 Apr 2016, 23:40

Re: Get Title and Url of the active browser tab

08 Feb 2021, 22:31

win10 x64 2016 ltsb
ahk 1.1.33.02
ie 11.2125.14393.0
chrome 86.0.4240.75

work fine
thank you~
c4p
Posts: 21
Joined: 18 Jan 2017, 18:38

Re: Get Title and Url of the active browser tab

10 Feb 2021, 07:57

Weird. Works now...Thanks
========================
Name: Address and search bar
Value: https://www.autohotkey.com/boards/viewtopic.php?f=6&t=85383&sid=4ee84b411972eedad54a0b2800f9107b&start=20
Role: 42
State: 1048576
Path: 4.1.2.1.2.5.6
x185 y38 w550 h26
========================
neogna2
Posts: 591
Joined: 15 Sep 2016, 15:44

Re: Get Title and Url of the active browser tab

03 Apr 2021, 02:56

(Question spurred by discussion in thread Example of getting firefox address bar url with UIA )
@rommmcek I'm trying to learn how this code works. Could you perhaps comment/describe some steps in the GetAccData code that makes the biggest speed difference compared to using the Acc.ahk library?
User avatar
rommmcek
Posts: 1478
Joined: 15 Aug 2014, 15:18

Re: Get Title and Url of the active browser tab

03 Apr 2021, 18:24

On given browser the first call of GetAccData() retrieves AccObj, then parses it and retrieves Url. AccObj is them stored for subsequent use.
The next time (on the same browser - same Id handle) we use stored AccObj to retrieve Url (skipping one step makes it faster).
The trick for some reason does not work on IE and Vivaldi.

P.s.: Sorry for not very prompt answer!
neogna2
Posts: 591
Joined: 15 Sep 2016, 15:44

Re: Get Title and Url of the active browser tab

04 Apr 2021, 06:28

rommmcek wrote:
03 Apr 2021, 18:24
On given browser the first call of GetAccData() retrieves AccObj, then parses it and retrieves Url. AccObj is them stored for subsequent use.
The next time (on the same browser - same Id handle) we use stored AccObj to retrieve Url (skipping one step makes it faster).
Ok, got it.

A question about your function ParseAccData()

Code: Select all

ParseAccData(accObj, accData:="") {
    try   accData? "": accData:= [accObj.accName(0)]
    try   if accObj.accRole(0) = 42 && accObj.accName(0) && accObj.accValue(0)
              accData.2:= SubStr(u:=accObj.accValue(0), 1, 4)="http"? u: "http://" u, accData.3:= accObj
          For nChild, accChild in GetAccChildren(accObj)
              accData.2? "": ParseAccData(accChild, accData)
          Return accData
}
Is this a correct interpretation:
- Line 2 checks if object role is ROLE_SYSTEM_TEXT (constant 42, a.k.a. "editable_text" ) and has Name and has Value.
- if true true true then it sets the URL to accData.2 (adding prefix "http://" if not existant).
- Line 5-6 recursively calls ParseAccData(), in effect traversing the original Acc object's whole tree of child elements
- This means that the function assumes that the first ROLE_SYSTEM_TEXT element with Name and Value that it traverses to is the URL.

References
https://docs.microsoft.com/en-us/windows/win32/api/oleacc/nf-oleacc-iaccessible-get_accrole
https://docs.microsoft.com/en-us/windows/win32/winauto/object-roles
"ROLE_SYSTEM_TEXT The object represents selectable text that allows edits or is designated as read-only."
https://www.magnumdb.com/search?q=ROLE_SYSTEM_TEXT
User avatar
rommmcek
Posts: 1478
Joined: 15 Aug 2014, 15:18

Re: Get Title and Url of the active browser tab

04 Apr 2021, 09:21

Very good! You analyzed it very well! I'd add the following:
neogna2 wrote:
04 Apr 2021, 06:28
- Line 2 checks if object role is ROLE_SYSTEM_TEXT (constant 42, a.k.a. "editable_text" ) and has Name and has Value.
- if true true true then it sets the URL to accData.2
neogna2 wrote:
04 Apr 2021, 06:28
- This means that the function assumes that the first ROLE_SYSTEM_TEXT element with Name and Value that it traverses to is the URL.
This was my conclusion after analyzing data from Get Acc children (What led to improvement of the Acc Viewer regarding Path too)
neogna2 wrote:
04 Apr 2021, 06:28
(adding prefix "http://" if not existant)
Yes, it is a bit simplified (ignoring if it is "http" or "https"), but seems to work.
neogna2 wrote:
04 Apr 2021, 06:28
- Line 5-6 recursively calls ParseAccData(), in effect traversing the original Acc object's whole tree of child elements
Yes, but only (I'm sure you noticed) until accData.2 is empty, for break does not work as one would think. I assume because each recursive call launches a new thread and they run asynchronously (some finishing earlier even if launched later and vice versa - thus ToDo: ParseAccData() should be rewritten using Loop... Until or While)
neogna2
Posts: 591
Joined: 15 Sep 2016, 15:44

Re: Get Title and Url of the active browser tab

05 Apr 2021, 04:26

rommmcek wrote:
04 Apr 2021, 09:21
neogna2 wrote:
04 Apr 2021, 06:28
- Line 5-6 recursively calls ParseAccData(), in effect traversing the original Acc object's whole tree of child elements
Yes, but only (I'm sure you noticed) until accData.2 is empty
You're right. Let me try to describe it again, because putting it in words helps me learn.

I should have said that it traverses (with for-loops and recursive function calls) the window's Acc object tree looking for an object with the URL value. Once found the URL is stored in accData.2. Thereafter it steps through only the already started for-loops and each step in each such for-loop is now fast because the ternary evaluates true and ParseAccData() is not called.

To illustrate we can imagine that the Acc tree looks like this

Code: Select all

window
1
1.1
1.2
1.2.1
1.2.2 <-- URL value here
1.2.2.1
1.2.2.2
1.2.3
1.2.3.1
2
2.1
2.2
Once we get to point 1.2.2 in the tree and store the URL in accData.2 the following things happen:
(1) 1.2.2's two children are for-looped over (but no ParseAccData() call)
(2) return to caller, on level 1.2
(3) 1.2's ongoing for-loop steps to the next child 1.2.3 (but no ParseAccData() call)
(4) return to caller, on level 1
(5) 1's ongoing for-loop has no steps left, since 1.2 was its last child
(6) return to caller, on window object level
(7) window object's ongoing for-loop steps to the next child 2 (but no ParseAccData() call)
(8) return to caller outside function

We can modify the function to skip (1) with a conditional check above the for-loop line. That does appear to save ~150ms in a speedtest that repeats the URL lookup 1000 times - not much.

Code: Select all

ParseAccData(accObj, accData:="") {
    try   accData? "": accData:= [accObj.accName(0)]
    try   if accObj.accRole(0) = 42 && accObj.accName(0) && accObj.accValue(0)
              accData.2:= SubStr(u:=accObj.accValue(0), 1, 4)="http"? u: "http://" u, accData.3:= accObj
          if accData.2
              Return accData
         For nChild, accChild in GetAccChildren(accObj)
              accData.2? "": ParseAccData(accChild, accData)
          Return accData
}
rommmcek wrote:
04 Apr 2021, 09:21
for break does not work as one would think. I assume because each recursive call launches a new thread and they run asynchronously (some finishing earlier even if launched later and vice versa
Is that really the case? I thought the recursive calls were done in series, the next call starting only after the previous has returned.
malcev
Posts: 1769
Joined: 12 Aug 2014, 12:37

Re: Get Title and Url of the active browser tab

05 Apr 2021, 09:10

The trick for some reason does not work on IE and Vivaldi.
I do not have vivaldi, but with IE "cache" should work.
User avatar
rommmcek
Posts: 1478
Joined: 15 Aug 2014, 15:18

Re: Get Title and Url of the active browser tab

06 Apr 2021, 17:19

Thanks for the Info! I will try it again (after some time)!
User avatar
rommmcek
Posts: 1478
Joined: 15 Aug 2014, 15:18

Re: Get Title and Url of the active browser tab

07 Apr 2021, 15:26

@malcev: Yes, it works for IE just fine! I must have had a bug when was testing... Thank you!
(Vivaldi does not work - don't bother.)

@neogna2: You pinpointed it!
neogna2 wrote:
05 Apr 2021, 04:26
We can modify the function to skip (1) with a conditional check above the for-loop line. That does appear to save ~150ms in a speedtest that repeats the URL lookup 1000 times - not much.
I deliberately skipped it since the speed gain is marginal! I tried to store the AccPath too, but there was no significant improvement either.
neogna2 wrote:
05 Apr 2021, 04:26
Is that really the case? I thought the recursive calls were done in series, the next call starting only after the previous has returned.
I'm not 100% sure!, but I couldn't make it with break! To note: AccObj is not the same as Ahk-Array/Obj...
malcev
Posts: 1769
Joined: 12 Aug 2014, 12:37

Re: Get Title and Url of the active browser tab

07 Apr 2021, 22:07

Vivaldi also will work if You send 1 time WM_GETOBJECT to the control Chrome_RenderWidgetHostHWND1 of vivaldi.
User avatar
rommmcek
Posts: 1478
Joined: 15 Aug 2014, 15:18

Re: Get Title and Url of the active browser tab

08 Apr 2021, 07:48

I tried it for educational purpose. It works!
Issues:
- Didn't know what parameters (wp, lp) to use. Tried 0, 1, 0xFFFFFFFC and blank. All work.
- It works only on one tab i.e. when the Tab is switched AccObj should be refreshed (didn't find other way, storing AccObj for each tab seems not to work)

Thank you!

P.s.: Where the heck do you get these ideas? Probably because it is related to UIA too?
malcev
Posts: 1769
Joined: 12 Aug 2014, 12:37

Re: Get Title and Url of the active browser tab

08 Apr 2021, 10:06

It works only on one tab i.e. when the Tab is switched AccObj should be refreshed
Then it means something wrong with Your code.
For me cache works.

Code: Select all

f11::
if !isobject(acc)
   acc := Acc_Get("object", "4.1.2.1.1.1.1.1.2.1.2.3.1.1",, "A")
msgbox % acc.accvalue(0)
return
Didn't know what parameters (wp, lp) to use

Code: Select all

SendMessage, WM_GETOBJECT := 0x003D, 0, 1, Chrome_RenderWidgetHostHWND1, % "ahk_id " WinID
Where the heck do you get these ideas?
How Chrome detects the presence of Assistive Technology
For performance reasons Chromium waits until it detects the presence of assistive technology before enabling full support for accessibility APIs.

Windows: Chrome calls NotifyWinEvent with EVENT_SYSTEM_ALERT and the custom object id of 1. If it subsequently receives a WM_GETOBJECT call for that custom object id, it assumes that assistive technology is running.

Mac OS X: Chromium turns on or off accessibility support based on whether it sees a client, such as VoiceOver, has set the AXEnhancedUserInterface attribute on the main application window.

To override:

Start Chrome with this flag: --force-renderer-accessibility
Or, visit this url to turn it on from within Chrome: chrome://accessibility
https://www.chromium.org/developers/design-documents/accessibility#TOC-How-Chrome-detects-the-presence-of-Assistive-Technology
User avatar
rommmcek
Posts: 1478
Joined: 15 Aug 2014, 15:18

Re: Get Title and Url of the active browser tab

08 Apr 2021, 14:35

Thanks for the elaborated answer w/ quotesr! (One must be a good connaisseur of Acc to take right conclusions form that)

Something on my OS is blocking Acc in some browser. The flag --force-renderer-accessibility was needed for me only on Vivaldi.
Your code wich is (generally known code - w/o buffering the AccObj) should work (w/ individual AccPath) and has worked in the past, but now despite relaunching the Vivaldi does not work at all. I should restart OS, but now I can't. It even does not work on Chrome, FF and IE (strange). However it works on Edge and Comodo Dragon (Chromium based). In the contrast GetAccData() works on all my browsers w/ the mentioned issue on Vivaldi.
[edit]: And of course your UIA works fine too!

Return to “Scripts and Functions (v1)”

Who is online

Users browsing this forum: scriptor2016 and 95 guests