0

I'm working on a project that involves using Applescript to make a list of open URLs within the users Google Chrome Browser, in order to save them for when I eventually want to re-open Chrome. Finding that I needed to have a way to determine which tabs were present in which windows, I decided to try and make a nested list in Applescript, in which each window is it's own sublist of tab URLs, and then return it in the variable declared before the subshell.

The way I'm doing this is via the following code

tabs=$(/usr/bin/osascript << EOT
    tell application "Google Chrome"
        # save a variable to the number of windows open     
        set windowCount to number of windows        
        set myWindows to {}

        repeat with x from 1 to windowCount     
            # count the tabs in the window we are iterated upon     
            set tabcount to number of tabs in window x

            # this list will hold the URLs, delimited by commas         
            set myURLs to {}

            # secondary loop, this time iterating tabs
            repeat with y from 1 to tabcount            
                # grab URL from current tab
                set tabURL to URL of tab y of window x

                # append URL to end of list         
                copy tabURL to the end of myURLs
            end repeat

            # this means our end result will be a list of lists
            # containing the URLs of all the tabs of all the windows
            copy myURLs to the end of myWindows             
        end repeat

        return myWindows
    end tell
    EOT)

The issue I'm running into is that, although Applescript is building the nested list properly, i.e.

{{"https://stackoverflow.com/questions/ask"}, {"https://twitter.com", "https://facebook.com"}}

Bash seems to flatten the list when I reference $tabs later into something like

https://stackoverflow.com/questions/ask, https://twitter.com, https://facebook.com

which leads me to believe Applescript and Bash aren't getting along when passing complex variables. Is this the case and is Bash not able to read multi-dimensional lists from Applescript? Or am I simply programming this incorrectly?

Thank you!

CJK
  • 5,732
  • 1
  • 8
  • 26
  • Why are you mixing `bash` and AppleScript for this task? I'd write the `list` to a disk file and read it back as a `list` when needed, and process either by `osascript` or an AppleScript script/app, etc. – user3439894 Nov 08 '19 at 20:23
  • For generating your nested list, did you have a look at the output from running: `tell app "Google Chrome" to set myURLs to the URL of every tab in every window` ? Re: `bash`, it has no relationship to AppleScript whatsoever, and the only data type exchanged between the two is text. Also, agree with @user3439894 – CJK Nov 08 '19 at 20:31

1 Answers1

0

Here's a basic, barebones script that contains two handlers: storeURLs() and restoreURLs().

storeURLs() retrieves a nested list of currently-open Chrome tabs (grouped by window) and writes their URLs out to file. restoreURLs() reads this file and opens the URLs in Chrome, restoring the arrangement of tabs and windows.

Running the script in its current form will store the list of URLs in the file ~/.chrometabs. To get the script to restore the saved URLs, comment out the first occurrence of "storeURLs()" (line 6) by prepending it with two hyphens (--) or a hash (#); and uncomment the line below that, by deleting the two hyphens before "restoreURLs()".

property home : system attribute "HOME"
property file : home & "/.chrometabs" --> /Users/%YOU%/.chrometabs


on run
    storeURLs()
    --restoreURLs()
end run

on storeURLs()
    close access (open for access my file)

    tell application id "com.google.chrome" to set ¬
        URLs to the URL of every tab in every window

    write the URLs to my file
    return the URLs
end storeURLs

to restoreURLs()
    close access (open for access my file)
    if (get eof of my file) = 0 then return false
    set URLs to read my file as list

    tell application id "com.google.chrome"
        repeat with URLgroup in the reverse of URLs
            tell (make new window)
                set the active tab's URL to the URLgroup's 1st item
                repeat with |URL| in the rest of the URLgroup
                    make new tab with properties {URL:|URL|}
                end repeat
            end tell
        end repeat

        activate
    end tell

    return the URLs
end restoreURLs

The script doesn't contain anything more than the most basic error-prevention, and as such, will benefit from additional error-handling. It was written and tested using AppleScript version 2.5 in macOS 10.12.6. The only potential problem I anticipate in more recent versions of macOS (Mojave, Catalina) would be security bollocks that could prevent the script creating and/or writing to the file path ~/.chrometabs, either due to its location, or due to the leading "." in the file name which denotes an invisible file in macOS.

CJK
  • 5,732
  • 1
  • 8
  • 26