What is Best Method to Activate Google Chrome Tab for Existing URL?

###What is Best Method to Activate Google Chrome Tab for Existing URL?

All help and suggestions are welcome and appreciated.
When I get done with this script for Chrome, I need to do the same for Safari.

I have three main questions:

  1. How do I compose a whose statement that excludes “missing value” items?
  • How do I get the tab index from the tab object?
  • How do I get the window of the tab object?

**1. How do I compose a whose statement that excludes "missing value" items?**
These always give me trouble.  I'm hoping it is something simple I'm missing.
```applescript
  ### THIS WORKS, but
  --    returns an item of "missing value" for each window that does not have the URL
  set tabFoundList to first tab of windows whose URL is urlToFind
  
  ### This Does NOT Work ###
  --    ERROR:  Google Chrome got an error: Can’t make missing value into type text.
  -- set tabFound2 to first tab of windows whose ((URL is urlToFind) and (URL is not missing value))
  
  ### This Works, but does NOT exclude items with "missing value" ###
  set tabFound2 to first tab of windows whose (URL is urlToFind) and (it is not missing value)

```

**2. How do I get the tab index from the tab object?**
The _tab_ object has an _id_ property, but NOT an _index_ property, and I don't see any way to get the _index_ other than looping the the tabs for the window.

<img src="/uploads/default/original/1X/1d60fb9c0a75ccf2c5cd0205249ec00508a74b90.png" width="425" height="111">


**3. How do I get the window of the tab object?

Also notice in the above screenshot that the SD Results panel shows "tab id 4 of window id 1".
How can I get that info into a variable?  I need to know which window the tab belongs to.


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

###Draft Script to Show/Create Chrome Tab with Given URL
Any/All suggestions for improvements are welcome and appreciated.

```applescript
(*
  PURPOSE:  Show/Create Tab with Given URL
                  * If Tab with URL exists, just Activate it
                  * If not, create new Tab with URL
*)

tell application "Google Chrome"
  
  --- URL TO SHOW/CREATE ---
  --set urlToFind to "https://forum.keyboardmaestro.com/"
  set urlToFind to "http://macscripter.net/"
  
  --- Not Needed for Script.  Just for debug info ---
  set tabList to tabs of windows
  
  (*
  ### I can quickly determine if the URL is already open in a Tab, BUT ###
        • It returns an item of "missing value" for each window that does not have the URL
            • So I have to loop through the list to get the found tab
        * It does NOT provide the Tab index, which is needed to set it as the active tab
            • So I have to loop through all windows and all tabs to get the tab index
        
  set tabFoundList to first tab of windows whose URL is urlToFind
  *)
  
  set winList to every window ## where its tab is not missing value
  set urlFound to false
  
  repeat with oWin in winList
    set tabIndex to 0
    
    ### ? Surely there must be a better way to get the tab index ###
    repeat with oTab in (tabs of oWin)
      set tabIndex to tabIndex + 1
      if ((URL of oTab) = urlToFind) then
        set active tab index of oWin to tabIndex
        set index of oWin to 1
        set urlFound to true
        exit repeat
      end if
    end repeat
  end repeat
  
  if (urlFound is false) then
    --- OPEN URL IN NEW TAB ---
    set oTab to make new tab at window 1 with properties {URL:urlToFind}
  end if
  
end tell
```
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**EDIT:  2017-05-14  9:53 PM CT -- SUMMARY**

[quote="JMichaelTX, post:19, topic:600"]
Congratulations Ed!  Your script is the fastest by 2X when run against my standard test from above (10 win with 20 total tabs):


		@JMichaelTX: 0.39
		@ccstone:    0.38
		@estocky:    0.17
[/quote]

I encourage all who are interested in this to read the entire thread.  There is a lot of good information/insights from the participants.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 Like

Well, I guess sometimes the answer is: It doesn’t matter.

Using the brute force method, my below script runs in 0.16 sec to search through 16 tabs in two windows. So, I’m not going to spend (waste) any more time trying to optimize this script for performance. I know, 16 tabs may be too few for some (I do know one or two people who claim they often keep open upwards of 250 tabs!)

OTOH, if anyone has any suggestions for improvements, I’m all ears!

Here’s my nearly final script (just needs a bit more testing to be sure).
BTW, it pulls data from a Keyboard Maestro Variable, but I’m sure you smart guys can change that if you wish.

###Semi-final Script to Show or Create Tab with Given URL
Option now provided for match type: Contains, Exact, EndsWith
(see below for details)

(*
  PURPOSE:  Show/Create Tab with Given URL
                  * If Tab with URL exists, just Activate it
                  * If not, create new Tab with URL
*)
property LF : linefeed
set scriptResults to "TBD"

--- GET URL TO FIND FROM Keyboard Maestro ---

tell application "Keyboard Maestro Engine" to set urlData to getvariable "SCPT__URLtoFind"

if (urlData = "") then error "[ERROR]" & LF & "Invalid URL: " & "KM Variable 'SCPT__URLtoFind' was EMPTY."


(*
The KM Variable can be one or two lines.

One Line:  
URL only, assumes "CONTAINS" match

Two Lines:
LINE #1: Match Type
LINE #2: The URL (full or partial) to Match
*)

set urlItems to paragraphs of urlData
set numLines to count of urlItems

--- GET URL MATCH TYPE AND URL ---

if (numLines = 1) then -- Default is "CONTAINS"
  set urlMatch to "CONTAINS"
  set urlToFind to item 1 of urlItems
else
  set urlMatch to item 1 of urlItems
  set urlToFind to item 2 of urlItems
  
  if {"CONTAINS", "EXACT", "ENDSWIDTH"} does not contain urlMatch then
    set urlMatch to "CONTAINS"
  end if
  
end if

set AppleScript's text item delimiters to "://"
set urlName to last item of (text items of urlToFind)

--------------------------------------
tell application "Google Chrome"
  ------------------------------------
  
  set urlFound to false
  
  --- SEARCH THROUGH EVERY TAB OF EVERY WINDOW UNTIL A MATCH IS FOUND ---
  --    (If no match, open new Tab)
  
  set winList to every window
  
  -------------------------------------
  repeat with oWin in winList -- search through every window
    -----------------------------------
    set tabIndex to 0
    
    
    ### ? Surely there must be a better way to get the tab index ###
    -- apparently the only way to get tab index is to count
    
    -------------------------------------
    repeat with oTab in (tabs of oWin) -- search through every tab
      ------------------------------------
      set tabIndex to tabIndex + 1
      set urlTab to URL of oTab
      
      if (urlMatch = "CONTAINS") then -- also handles Domain Name match
        if (urlTab contains urlName) then
          set urlFound to true
        end if
        
      else if (urlMatch = "EXACT") then
        if (urlTab = urlToFind) then
          set urlFound to true
        end if
        
      else if (urlMatch = "ENDSWITH") then
        if ((urlTab ends with urlToFind) or (urlTab ends with (urlToFind & "/"))) then
          set urlFound to true
        end if
        
      end if
      
      --------------------
      if urlFound then
        ------------------
        set active tab index of oWin to tabIndex
        set index of oWin to 1
        set scriptResults to "OK" & LF & ¬
          "Existing Tab with URL was Activated." & LF & "Match Type: " & urlMatch & LF & urlToFind
        -----------------
        exit repeat
        -----------------
      end if
      
    end repeat
    
    ------------------------------
    if urlFound then exit repeat
    ------------------------------
    
  end repeat
  
  if (urlFound is false) then
    
    if (urlToFind does not start with "http") then set urlToFind to "http://" & urlToFind
    
    --- OPEN URL IN NEW TAB ---
    tell front window
      set oTab to make new tab at end of tabs with properties {URL:urlToFind}
    end tell
    
    set scriptResults to "OK" & LF & "NEW Tab with URL was Opened." & LF & "Match Type: " & urlMatch & LF & urlToFind
    
  end if -- urlFound is false
  
end tell

return scriptResults


--~~~~~~~~~~~~~~~~~~ END OF MAIN SCRIPT ~~~~~~~~~~~~~~~~~~

###Input for Script

ONE LINE:

• Same as CONTAINS match with Two Lines
• Enter any part of the URL you want to match
• If the full URL contains this, then it will be a match
• Example: keyboardmaestro.com
• This would match ANY Page from EITHER the forum.keyboardmaestro.com OR www.keyboardmaestro.com
web sites.

TWO LINES:

LINE #1: Match Type

• One of the following:
• EXACT CONTAINS ENDSWITH
• If you enter anything else, it will use CONTAINS match.

LINE #2: The URL (full or partial) to Match

• EXACT
• The URL must be the FULL URL, including URL scheme (like “http://” or “https://”)
• The best way to get this is to click in the Browser Address bar and copy the URL.
• Example: https://forum.keyboardmaestro.com/

• CONTAINS
• Enter any part of the URL you want to match
• It ignores the URL scheme, so “http” and “https” which match either in the actual URL.
• If the full URL contains this, then it will be a match
• Example: keyboardmaestro.com
• This would match ANY Page from EITHER the forum.keyboardmaestro.com OR www.keyboardmaestro.com

• ENDSWITH
• Enter the last part of the URL
• Example: forum.keyboardmaestro.com
• This would match ONLY the main home page of https://forum.keyboardmaestro.com

• DOMAIN
• Enter the Domain Name
• Example: keyboardmaestro.com
• This would match any page on any site that uses that Domain Name

1 Like

Hey Jim,

I’ve spent a lot of time trying to optimize window/tab management in Safari, and a while back I spent a fair amount fooling with Chrome.

Iterating through a list of objects tends to be slower than iterating through a list of plain text.

This is a little more convoluted than your script, but it’s faster — particularly as the window count goes up.

One of the important design criteria was to use the window id to bring the window forward — and NOT use the window index or window name.

Chrome stupidly requires the tab-index when setting the active tab and yet does NOT offer the index in tab properties. Nor can you directly deduce the window a tab is in from its properties.

So you can’t find a specific tab and then directly make it and its container window active.

This sort of thing is often rather kludgy, because many developers don’t regularly script their own products and leave out relatively no-brainer features.

-Chris

------------------------------------------------------------------------------
# Auth: Christopher Stone
# dCre: 2017/05/13 14:30
# dMod: 2017/05/13 15:20 
# Appl: Google Chrome
# Task: Find Tab Containing a URL and bring first hit to front – if NOT found create a new window with that URL.
# Libs: None
# Osax: None
# Tags: @Applescript, @Script, @Google_Chrome, @System_Events, @Find, @Tab, @Containing, @URL, @Bring, @First, @Hit, @Front, @Create, @New, @Window
------------------------------------------------------------------------------

set urlToFind to "https://forum.keyboardmaestro.com"

set exitRepeat2 to false
set tabID to missing value

tell application "Google Chrome"
   set {tabList, urlList} to {it, URL} of tabs of windows
   
   repeat with ndx1 from 1 to length of urlList
      set n1 to ndx1
      repeat with ndx2 from 1 to (length of item ndx1 of urlList)
         set tabIndex to ndx2
         if item ndx2 of (item ndx1 of urlList) contains urlToFind then
            set tabID to item ndx2 of (item ndx1 of tabList)
            set exitRepeat2 to true
            exit repeat
         end if
      end repeat
      if exitRepeat2 then exit repeat
   end repeat
   
   if tabID ≠ missing value then
      
      try
         tabID / 0
      on error e
         set AppleScript's text item delimiters to {"window id ", " of application"}
         set winID to text item 2 of e
      end try
      
      set index of window id winID to 1
      raiseWindowOne() of me
      tell front window to set active tab index to tabIndex
      
   else
      
      set newWin to make new window
      tell newWin
         set bounds to {228, 23, 1542, 1196}
         set URL of active tab to urlToFind
      end tell
      
   end if
   
end tell

------------------------------------------------------------------------------
--» HANDLERS
------------------------------------------------------------------------------
on raiseWindowOne()
   tell application "System Events"
      tell application process "Google Chrome"
         tell window 1
            perform action "AXRaise"
         end tell
      end tell
   end tell
end raiseWindowOne
------------------------------------------------------------------------------

Chris, many thanks for sharing your script. I have learned a lot from it.

Perhaps the power of one’s Mac can make a material difference. I ran a test on my iMac 27-Inch Late 2015, MK482LL/A,Quad Core 3.3 i5, Retina 5K, 2TB Fusion Drive.

  • Test Set: Total of 20 tabs open in 2 windows
  • URL to Find: NOT open in any tab
  • Running Script Debugger 6.0.4 (6A198) on macOS 10.11.6
  • 10 other apps open (but not doing anything), including KM Editor and Engine

####RESULTS for First Time the Script was Run

So you can see that both are actually very fast, and there is a difference of only 0.06 seconds, or 0.003/tab

Since I almost never have more than 20 documents (tabs) open at once in Chrome, either script works fine for me from a performance POV.

I totally agree. While the Chrome Tab object provides some useful data, it does NOT provide some critical data:

  • Tab Index (needed to set as Active Tab)
  • Window ID (needed to set as frontmost window)

It is too bad that AppleScript objects do not have the property of “parent”.
In many/most OO languages this is a common property.
So we would have:
set oWin to parent of oTab

which is very useful.

Thanks again for all your help.

Hey JM,

As I mentioned the speed difference becomes more pronounced as you add more windows.

-Chris

Container objects are common — the dev just has to write the code…

-Chris

OK. In other languages, the “parent” property is built into the language.

How many windows do you think it would take before it makes a material difference?

I ran the test with my script again with 10 windows with a total of 20 tabs, and still it took only 0.87 seconds.

Still, I get your point. Your script took only 0.33 sec.

I knew there was a good reason I don’t use a lot of windows (other than clutter) – Performance!

Your point about looping through lists rather than objects has given me an idea. I’ll have to see if it works out.

Yes — it’s silly to have an object-oriented language where you cannot get the parent of an object…

-Chris

Think Mitchell with 20 windows and 220 tabs…

-Chris

Chris, thanks so much for pointing out this important design pattern (use lists instead of objects).

My revised script now runs in 0.28 seconds for 10 windows with a total of 20 tabs.

####Here are the key changes:

  set winIDList to id of every window
  
  -------------------------------------
  repeat with aWinID in winIDList -- search through every window ID
    -----------------------------------
    set tabIndex to 0
   
    set oWin to window id aWinID 
    set urlList to URL of tabs of oWin
    
    -------------------------------------
    repeat with aTabURL in urlList -- search through every tab URL
      ------------------------------------
      set tabIndex to tabIndex + 1
      set urlTab to aTabURL as text

. . .

###Script Revised to Use Lists instead of Objects

(*
  PURPOSE:  Show/Create Tab with Given URL
                  * If Tab with URL exists, just Activate it
                  * If not, create new Tab with URL
*)
property LF : linefeed
property defaultBrowser : "Google Chrome"

set scriptResults to "TBD"

######### JUST FOR TESTING ###########

set urlMatch to "EXACT"
set urlToFind to "https://forum.keyboardmaestro.com/"

--------------------------------------
tell application "Google Chrome"
  ------------------------------------
  --    activate
  
  set urlFound to false
  
  --- SEARCH THROUGH EVERY TAB OF EVERY WINDOW UNTIL A MATCH IS FOUND ---
  --    (If no match, open new Tab)
  
  set winIDList to id of every window
  set numWin to length of winIDList
  
  -------------------------------------
  repeat with aWinID in winIDList -- search through every window
    -----------------------------------
    set tabIndex to 0
    log aWinID
    
    
    ### ? Surely there must be a better way to get the tab index ###
    -- apparently the only way to get tab index is to count
    
    set oWin to window id aWinID --  (first window whose id is aWinID)
    set urlList to URL of tabs of oWin
    
    -------------------------------------
    repeat with aTabURL in urlList -- search through every tab
      ------------------------------------
      set tabIndex to tabIndex + 1
      set urlTab to aTabURL as text
      
      if (urlMatch = "CONTAINS") then -- also handles Domain Name match
        if (urlTab contains urlName) then
          set urlFound to true
        end if
        
      else if (urlMatch = "EXACT") then
        if (urlTab = urlToFind) then
          set urlFound to true
        end if
        
      else if (urlMatch = "ENDSWITH") then
        if ((urlTab ends with urlToFind) or (urlTab ends with (urlToFind & "/"))) then
          set urlFound to true
        end if
        
      end if
      
      --------------------
      if urlFound then
        ------------------
        
        set active tab index of oWin to tabIndex
        set index of oWin to 1
        set scriptResults to "OK" & LF & ¬
          "Existing Tab with URL was Activated." & LF & "Match Type: " & urlMatch & LF & urlToFind
        -----------------
        exit repeat
        -----------------
      end if
      
    end repeat
    
    ------------------------------
    if urlFound then exit repeat
    ------------------------------
    
  end repeat
  
  if (urlFound is false) then
    
    if (urlToFind does not start with "http") then set urlToFind to "http://" & urlToFind
    
    --- OPEN URL IN NEW TAB ---
    tell front window
      set oTab to make new tab at end of tabs with properties {URL:urlToFind}
    end tell
    
    set scriptResults to "OK" & LF & "NEW Tab with URL was Opened." & LF & "Match Type: " & urlMatch & LF & urlToFind
    
  end if -- urlFound is false
  
end tell

return scriptResults


--~~~~~~~~~~~~~~~~~~ END OF MAIN SCRIPT ~~~~~~~~~~~~~~~~~~


###New Idea: Create a Flat List of Tab Records
Chris (@ccstone), what do you think about this script which builds a list of records of all tabs of all windows? It creates a flat list with each item being a record with the following record keys:

  • WinID
  • TabIndex
  • Tab ID
  • TabURL
  • TabTitle

Can it be improved? Instead of a list of records, would you use a list of lists?
Can it be used as the basis for a number of derivative scripts?
How would we search for a matching URL, or Title?

tell application "Google Chrome"
  
  set winIDList to id of windows
  set {tabIDList, tabURLList, tabTitleList} to {id, URL, title} of tabs of windows
  
  set tabList to {} -- Flat list of all tabs in all windows
  
  set numWin to length of tabIDList
  
  repeat with iWin from 1 to numWin
    set winIDofTab to item iWin of winIDList
    set numTabs to length of item iWin of tabIDList
    
    repeat with iTab from 1 to numTabs
      
      set end of tabList to ¬
        {WinID:winIDofTab, TabIndex:iTab, TabID:item iTab of item iWin of tabIDList, TabURL:item iTab of item iWin of tabURLList, TabTitle:item iTab of item iWin of tabTitleList ¬
          } ¬
          
    end repeat
  end repeat
  
end tell

@ShaneStanley, I hope your vacation trip is going well. Any pics you’d like to share?

If you are interested, and have a few moments, I’d love to know your thoughts about this.
Can we use ASObjC Array Dictionary tools to help us with this use case?
Given a list of records, how can we quickly search for records that match a specific key, like:

  • TabURL is urlToFind
  • TabURL contains urlToFind
  • TabTitle contains textToFind

Actually I should have started with, what is the best way to present the user with list to choose from, and then will activate the tab that matches? I’m thinking Myriad Tables, right?

What I’d love to do is present the user with a table of the following to select from:
Win#, Tab#, Domain Name, TabTitle

and then activate the tab the user selected.

Any/all suggestions/guidance is much appreciated.

Hey JM,

It’s not a bad idea at all.

The reason I wrote my Safari-Tabs script using vanilla AppleScript and loops was so people would at least try it (and hopefully use it).

But I’ve done many projects similarly to what you propose, except I use fully-flat-text-records and usually tab-delimit them.

Then I use the Satimage.osax to search the result.

Here’s your script adapted to this method and used to bring a given tab to the front.

------------------------------------------------------------------------------
# Auth: Christopher Stone (building on work of Jim Underwood)
# dCre: 2017/05/14 12:12
# dMod: 2017/05/14 12:30 
# Appl: Google Chrome
# Task: Compile a flat, tab-delimited text list of tab-info-records and search it to bring the found tab frontmost.
# Libs: None
# Osax: Satimage.osax
# Tags: @Applescript, @Script, @Satimage.osax, @Google_Chrome, @System_Events, @Compile, @Flat, @Tab-delimited, @Text, @List, @Info-Records, @Search, @Found, @Tab, @Frontmost
------------------------------------------------------------------------------

set tabInfoList to {} -- Flat text list of all tabs in all windows

tell application "Google Chrome"
   set winIDList to id of windows
   set {tabIDList, tabURLList, tabTitleList} to {id, URL, title} of tabs of windows
   set numWin to length of tabIDList
   
   repeat with iWin from 1 to numWin
      set winIDofTab to item iWin of winIDList
      set numTabs to length of item iWin of tabIDList
      set AppleScript's text item delimiters to {"	"}
      repeat with iTab from 1 to numTabs
         set end of tabInfoList to items 1 thru -2 of {¬
            item iTab of item iWin of tabURLList, ¬
            item iTab of item iWin of tabTitleList, ¬
            winIDofTab, ¬
            item iTab of item iWin of tabIDList, ¬
            iTab, ¬
            ""} as text
      end repeat
   end repeat
   
end tell

set tabInfoList to join (sortlist tabInfoList) using linefeed

set foundRec to fnd("^https?://forum.latenightsw.com.+", tabInfoList, true, true) of me

if length of foundRec = 1 then
   
   set AppleScript's text item delimiters to "	"
   set foundRec to text items of item 1 of foundRec
   
   tell application "Google Chrome"
      tell window id (item 3 of foundRec)
         set index to 1
         set active tab index to (item 5 of foundRec)
      end tell
   end tell
   
   raiseWindowOne()
   
end if

------------------------------------------------------------------------------
--» HANDLERS
------------------------------------------------------------------------------
on fnd(_find, _data, _all, strRslt)
   try
      find text _find in _data all occurrences _all string result strRslt with regexp without case sensitive
   on error
      return false
   end try
end fnd
------------------------------------------------------------------------------
on raiseWindowOne()
   tell application "System Events"
      tell application process "Google Chrome"
         tell window 1
            perform action "AXRaise"
         end tell
      end tell
   end tell
end raiseWindowOne
------------------------------------------------------------------------------

-Chris

I meant to say that AppleScript records are poor at just about everything — and slooow.

Of course AppleScriptObjC brings great new tools to the table with dictionaries and predicates.

I’m still not able to use those at will — I have to dig through my library of AppleScriptObjC and painfully assemble them from example code I have.

They are so powerful though, that I really need to get them into my working vocabulary.

-Chris

This is how I would do it, seems pretty quick on my mac, but I haven’t timed it outside of SD, where it took .08 seconds to find the right tab out of 35 tabs in 3 windows.

(Of course SD slows execution down a lot, and you can’t count that to be consistent. (A script slower than another script when both are run in SD could be quicker than the other script when both run at RT.)

 tell application "Google Chrome"
	set windowTabList to URL of tabs of every window
	set targetURL to "http://macscripter.net/"
	set found to false
	set windowIndex to 1
	repeat with thisWindowsTabs in windowTabList
		set TabIndex to 1
		repeat with TabURL in thisWindowsTabs
			
			if TabURL as text = targetURL then
				set index of window windowIndex to 1
				set active tab index of window 1 to TabIndex
				set found to true
				exit repeat
			end if
			set TabIndex to TabIndex + 1
		end repeat
		if found then exit repeat
		set windowIndex to windowIndex + 1
	end repeat
	if not found then
		make new tab at window 1 with properties {URL:targetURL}
		
	end if
end tell

Whoops posted wrong version…

This version is even faster, sends only GC commands to GC

tell application "Google Chrome" to set windowTabList to URL of tabs of every window

set targetURL to "http://macscripter.net/"
set found to false
set windowIndex to 1
repeat with thisWindowsTabs in windowTabList
	set TabIndex to 1
	repeat with TabURL in thisWindowsTabs
		if TabURL as text = targetURL then
			
			tell application "Google Chrome"
				set index of window windowIndex to 1
				set active tab index of window 1 to TabIndex
			end tell
			
			set found to true
			exit repeat
		end if
		set TabIndex to TabIndex + 1
	end repeat
	if found then exit repeat
	set windowIndex to windowIndex + 1
end repeat
if not found then
	tell application "Google Chrome" to make new tab at window 1 with properties {URL:targetURL}
end if
2 Likes

Yep, I’ve been very frustrated with the limited use of AppleScript Records, especially when you compare them to JavaScript Objects/Arrays.

I had the same thought. I’m hoping that Shane can point us in the right direction to making Records useful. I really like being able to reference an object’s value by its key.

Congratulations Ed! Your script is the fastest by 2X when run against my standard test from above (10 win with 20 total tabs):

@JMichaelTX: 0.39 @ccstone: 0.38 @estocky: 0.17

I don’t see any change in time on my iMac-27.

I think the key is you ask Chrome only ONE time for tab/win data:

set windowTabList to URL of tabs of every window

All of the rest of your script is processing a list of strings, until you find the matching URL, or have to create a new tab.

And you just count the items to get the window index instead using the window “id” in some manner.


@ccstone and @estockly: 
This has been an interesting exercise.  Thanks for sharing your solutions and insights.

:slight_smile: I found it an interesting thread. Google Chrome is an incomplete mess when it comes to AppleScripting, but in some ways it’s better than Safari and more stable.