Applescript – bookmark all tabs in ALL WINDOWS in Safari

applescriptautomatorbookmarkssafarisafari-extensions

Safari, have the Bookmark all tabs, function in the menu Bookmarks -> Add Bookmarks for these N tabs. I looking for a way how to do this automatically with applescript in all opened Safari windows.

With other words, want

  1. choose some bookmark folder, let says "Favorites -> Sessions"
  2. cycle over all Safari windows
  3. if the window has only one TAB simply bookmark it into the above folder
  4. otherwise
    • call the Bookmarks -> Add Bookmarks for these N tabs menu item
    • fill the popup window automatically (e.g. Saved Tabs window1, Saved Tabs window2 … etc.)
  5. repeat from 2

Here https://gist.github.com/kshiteesh/b72e93d31d65008fcd11 is a nice applescript, (also similarly this which could be an good starting point for the development, but asking first here – maybe someone already has done this. 🙂

Any help, please?

Ps – motivation – The Apple's new policy, (blocking support for legacy Safari extensions), unfortunately caused that one of "must to have" Safari extension – Sessions – stops working in the Safari 12. So, looking for some home-grown functionality.

Best Answer

As I told in the above comment, now me using an self-developed automator workflow-app.

I'm an perl language developer, so in the workflow me using an custom-installed perl interpreter and many perl modules too - definitely NOT a solution for an average (common) mac user.

But posting it, mainly for reference and maybe someone could hack it to some better solution. How it works - how to use it:

  • unfortunately it must be run manually - i'm unable figure out how to run some automator workflow (service or app) when the Safari receives the quit event. :(

  • The automator (service) script has two actions:

    • run javascript (I don't know applescript nor Javascript, but the javascript is more understandable for me) - it simply gathers all URL's from all tabs and windows and create a JSON structure, which is passed to the next
    • run a shell script - which runs my perl script with custom installed perl interpreter.
  • when the app is executed, it saves an HTML file into the folder Sessions in my Desktop.
  • The name of the file is like s20190107-164908.html e.g. the current date-time string.
  • it is easy to use the Finder's quick-look feature (spacebar) to quicky check the content of the file.

It is far-far beyond of the original Sessions addon, but it is usable for me.

enter image description here

The full content of the above actions are:

1.) the Javascript

function run(input, parameters) {
    var tablist = [];
    var Safari = Application('Safari');
    Safari.includeStandardAdditions = true;
    Safari.activate();
    var windows = Safari.windows();
    for(let iw=0, wsize=windows.length; iw<wsize; iw++) {
        var wintabs = [];
        var tabs = windows[iw].tabs();
        if (!tabs) continue;
        for(let it=0, tsize=tabs.length; it<tsize; it++) {
            if( tabs[it].url() ) {
                wintabs.push( {"name": tabs[it].name(), "url": tabs[it].url()} );
            }
        }
        if( wintabs.length ) {
            tablist.push(wintabs);
        }
    }
    return JSON.stringify(tablist);
}

and the shell script

export ANYENV_ROOT=/opt/anyenv
export PATH="$ANYENV_ROOT/bin:$PATH"
eval "$(anyenv init -)"

perl -MJSON -MPath::Tiny -MTime::Piece -M5.014 -w -E '
    my $jsonstr = do { local $/; <STDIN> };
    my $j = decode_json($jsonstr);
    my @lines;
    lsay("<ol>");
    for my $w (@$j) {
        lsay("<li><ul>");
        for my $t (@$w) {
            my $astr = "<li><a href=\"$t->{url}\">$t->{name}</a></li>";
            lsay($astr);
        }
        lsay("</ul></li>");
    }
    lsay("</ol>");
    my $sessdir=path( $ENV{HOME}, "Desktop/Sessions");
    $sessdir->mkpath;
    my $sessfile=$sessdir->child(localtime->strftime("s%Y%m%d-%H%M%S.html"));
    $sessfile->spew_utf8(@lines);;
    sub lsay { push @lines, $_ for @_ }
'

Example what do you see in the quick-look:

enter image description here

As I already told - it is NOT a solution for an common user. It is usable only by an developers... :(