FWIW, I threw this little ditty to set the stage for testing. I’m curious if your results are the same after running this.
It closes all Google Chrome windows, then opens ten new ones, each with ten tabs, then sets the last tab of the last window to the target tab, so any testing has to go through every tab.
tell application "Google Chrome" to close windows
set targetURL to "http://macscripter.net/"
set newURLList to {"http://macscripter.net/index.php", ¬
"http://macscripter.net/register-pp.php", ¬
"http://macscripter.net/guidelines.php", ¬
"http://macscripter.net/page.php?id=1", ¬
"http://macscripter.net/login.php", ¬
"http://macscripter.net/viewforum.php?id=2", ¬
"http://macscripter.net/viewforum.php?id=31", ¬
"http://macscripter.net/viewforum.php?id=63", ¬
"http://macscripter.net/viewtopic.php?pid=190102#p190102"}
tell application "Google Chrome"
repeat 10 times
make new window
set URL of tab 1 of window 1 to some item of newURLList
repeat 9 times
make new tab at beginning of window 1
set URL of tab 1 of window 1 to some item of newURLList
end repeat
end repeat
set the URL of the last tab of the last window to targetURL
end tell
You did a great job optimizing the list-based version.
I tried pretty hard to beat it and couldn’t, although I didn’t resort to script-objects.
(I think Nigel Garvey has a way to make a script-object iterate through lists faster than a plain script, but I’m not going to go there.)
While I was experimenting I had one more go at using whose clauses.
-Chris
------------------------------------------------------------------------------
# Auth: Christopher Stone
# dCre: 2017/05/15 15:45
# dMod: 2017/05/15 17:14
# Appl: Google Chrome
# Task: Get Tabs whose URL starts with a given string - whose clause version.
# Libs: None
# Osax: None
# Tags: @Applescript, @Script, @Google_Chrome, @Get, @Tabs, @Whose, @URL, @Starts_With, @String
------------------------------------------------------------------------------
set targetURL to "https://www.macupdate.com/"
tell application "Google Chrome"
tell windows
set tabList to tabs where its URL starts with targetURL
end tell
end tell
try
tabList / 0
on error e
set AppleScript's text item delimiters to {"Can’t make {", "} into type real.", "{", "}", ", ", "«class asDB» id (application \"Google Chrome\") of "}
set tabList to text items of e
repeat with theTab in tabList
if contents of theTab = "" then set contents of theTab to 0
end repeat
set tabList to text of tabList
if length of tabList > 0 then
set theTab to item 1 of tabList
set AppleScript's text item delimiters to {"id ", " of"}
set {tabID, winID} to {text item 2, text item 4} of theTab
set tabID to tabID as integer
tell application "Google Chrome" to set tabIDList to id of tabs of window id winID
repeat with i from 1 to length of tabIDList
if (item i of tabIDList) = tabID then
set tabIndex to i
exit repeat
end if
end repeat
tell application "Google Chrome"
tell window id winID
set index to 1
set active tab index to tabIndex
end tell
end tell
raiseWindowOne() of me
else
tell application "Google Chrome" to make new tab at window 1 with properties {URL:targetURL}
end if
end try
------------------------------------------------------------------------------
--» 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
------------------------------------------------------------------------------
TEST: Search 10 windows with a total of 20 tabs, and open new tab @ccstone: 0.14 (ver 2) @estocky: 0.17 @ccstone: 0.38 @JMichaelTX: 0.39
Great job Chris!
Given that all of these are << 0.5 sec, it seems to me that this is mostly an academic test, unless you are one of those that like 10’s of windows with hundreds of tabs (not me).
Chris, I know you love to shave hundredths of a second off a script/process, but I am not nearly that driven. I routinely use a delay of 0.20 sec in my KM Macros, and they all seem fast to me (but maybe not to others).
As one of our colleagues likes to point out, sometimes programmer’s time is more valuable than execution time.
Still, it is good to know what techniques are the fastest. Now that I know that, there is no reason not to use that technique unless I have a compelling reason to do otherwise.
I thought I saw an opportunity to yet further optimize your script by checking for an empty “tabList”, meaning the the URL is not found in any of the tabs.
Seems like it should be faster, but it also runs in 0.14 seconds.
Tested with Script Debugger 6.0.4 (6A198) on macOS 10.11.6.
###My Mod to Chris’ Script
This just shows the changes.
tell application "Google Chrome"
tell windows
set tabList to tabs where its URL starts with targetURL
end tell
end tell
### MOD by JMichaelTX ###
set actionStr to "TBD"
if tabList as text = "" then
set actionStr to "** JUST OPEN URL IN NEW TAB"
tell application "Google Chrome" to make new tab at window 1 with properties {URL:targetURL}
return
end if
### End of MOD ###
try
tabList / 0
on error e
BTW, is there a better method for testing for an empty list of lists than: if tabList as text = "" then
tell application "Google Chrome"
tell windows
set tabList to tabs
end tell
end tell
set testTabs to my isEmpty(tabList)
set testListEmpty to my isEmpty({{}, {}, {}})
set testListNotEmpty to my isEmpty({{}, {"not empty"}, {}})
set testTextNotEmpty to my isEmpty("not empty")
set testTextEmpty to my isEmpty("")
on isEmpty(pObject)
try
if (pObject as text = "") then
return true
else
return false
end if
on error
return false
end try
end isEmpty
Many thanks to all in this thread for creating and posting scripts for this task. This is a life saver for me and something I would be unlikely to have created with my beginner Applescript skills. I’ve estimated this applescript – triggered using Keyboard Maestro – will save me between 3 to 6 hours per year of tedious tab hunting in my management role.
I have tried setting a variable A to id / tab object to restore the active tab after using the above script (post 16) to activate the tab
set A to the front tab of the front window
or
set A to the id of the active tab of the front window
Run Script from post 16
tell application “System Events” to keystroke (the clipboard as text)
delay 3
set active tab index of front window to A
Errors
If set A to the id of the active tab of the front window
=Google Chrome got an error: Invalid tab index entered." number 9
If set A to the front tab of the front window, then
=error “Google Chrome got an error: Can’t make tab id 714 of window id 98 into type integer.” number -1700 from tab id 714 of window id 98 to integer
Hi, I have managed to get a working solution for I wanted to do
Its a dirty workaround from brilliant work from Masters of applescript art
wud be grateful to suggest changes to look like a proper work
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "AppKit"
--https://apple.stackexchange.com/questions/271161/how-to-get-the-selected-text-into-an-applescript-without-copying-the-text-to-th
--https://mjtsai.com/blog/2017/01/30/processing-the-selected-text-via-script/#comment-2669464
-- Back up clipboard contents:
set savedClipboard to my fetchStorableClipboard()
-- Copy selected text to clipboard:
set thePasteboard to current application's NSPasteboard's generalPasteboard()
set theCount to thePasteboard's changeCount()
-- Copy selected text to clipboard:
tell application "System Events" to keystroke "c" using {command down}
-- Check for changed clipboard:
repeat 20 times
if thePasteboard's changeCount() is not theCount then exit repeat
delay 0.1
end repeat
-- Set the selected to ClipBoard, Ready to paste
set theSelectedText to the clipboard
-- Block for doing Copy & paste
on fetchStorableClipboard()
set aMutableArray to current application's NSMutableArray's array() -- used to store contents
-- get the pasteboard and then its pasteboard items
set thePasteboard to current application's NSPasteboard's generalPasteboard()
-- loop through pasteboard items
repeat with anItem in thePasteboard's pasteboardItems()
-- make a new pasteboard item to store existing item's stuff
set newPBItem to current application's NSPasteboardItem's alloc()'s init()
-- get the types of data stored on the pasteboard item
set theTypes to anItem's types()
-- for each type, get the corresponding data and store it all in the new pasteboard item
repeat with aType in theTypes
set theData to (anItem's dataForType:aType)'s mutableCopy()
if theData is not missing value then
(newPBItem's setData:theData forType:aType)
end if
end repeat
-- add new pasteboard item to array
(aMutableArray's addObject:newPBItem)
end repeat
return aMutableArray
end fetchStorableClipboard
on putOnClipboard:theArray
-- get pasteboard
set thePasteboard to current application's NSPasteboard's generalPasteboard()
-- clear it, then write new contents
thePasteboard's clearContents()
thePasteboard's writeObjects:theArray
end putOnClipboard:
-- Google Chrome
tell application "Google Chrome"
set restoreURL to URL of active tab of front window as text
--https://forum.latenightsw.com/t/what-is-best-method-to-activate-google-chrome-tab-for-existing-url/600/16
-- Find paper DropBox URL, and set it active to paste
set windowTabList to URL of tabs of every window
set targetURL to "paper.dropbox.com"
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) contains 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
delay 1
-- Block to paste the clipBoard & restore to Saved one
tell application "System Events" to keystroke "v" using {command down}
tell application "System Events" to keystroke {return}
delay 0.1 -- Without this delay, may restore clipboard before pasting.
-- Restore clipboard:
(my putOnClipboard:savedClipboard)
delay 1
-- Block to restore the URL
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) = restoreURL 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
end tell