Strange result inspecting Safari windows for tabs

This is part an AppleScript question and part an SD issue.

Where did the tabs element go?

According to the Safari dictionary tabs are an element of windows. Therefore running the following script displays a list of tabs in the results inspector (or an error — see below).

tell application "Safari"
	the tabs of window 1
end tell

However, after executing the following the results inspector doesn’t include the tabs element that Safari’s AppleScript dictionary says windows have. Why?

tell application "Safari"
    window 1
end tell

Windows without Tabs

Not all windows have tabs. When the designated window has no tabs an error occurs rather than the expression returning an empty list.

Windows with no tabs? Many applications have a few windows hanging around with no document, tabs, or whatever that document’s windows typically hold. These are palettes, dialog boxes, etc. (Someone else could contribute by characterizing these oddball windows more accurately and generally.) But in general they return empty strings or lists when queried.

However in the case of Safari’s windows we must write

tell application "Safari"
	try
		the tabs of window 1
	on error
		{}
	end try
end tell

How many tabless windows hang around in Safari? Well, at the moment I have 40 windows on Safari’s Windows menu . (I am grateful for relatively recent improvements in Safari that allow this many windows to be open, with quite a few tabs in some of them.) However there are 97 total windows! What are those other windows?

One has the name “Passwords”, another the name “Thanks!” The rest have no names.

Another weirdness is that if you select one of these in the results inspector and disclose its contents, in contrast to “regular” windows, all you see is class and properties. Opening properties shows the properties you would see in a “regular” window’s display in the results inspector.

Other than the question of what all those nameless windows are (a question I would love an answer to), how much of this is AppleScript weirdness, how much is SD’s unavoidable behavior, and how much is an SD bug?

I suspect you are viewing a window without any tabs, and so SD is filtering out the empty element collection. I cannot make Safari demonstrate a no-tabs window, but here’s an example using the finder:

Filtered empty elements (the default);

And unfiltered empty elements:

This is all down to Safari. SD is telling you the truth (i.e. displaying the data Safari returns to it when SD sends AppleEvents to introspect Safari’s scripting interface).

The root cause of all this is something called Cocoa Scripting which provides the scripting interface to most Cocoa applications. It is simply terrible and exhibits many strange bugs.


A regular window, but the tabs element is absent


A window with no tabs, properties not expanded.


A window with no tabs, empty name, properties expanded
(The script doesn’t show it but adding `the tabs of`` produces an error.)


A window with no tabs, non-empty name, properties expanded

I always believe SD’s data displays, and appreciate the way it reveals bugs, ambiguities, inconsistencies, and inaccessibility in AppleScript. I just had never run into a situation where an application’s dictionary defines elements that don’t show in the results inspector — tabs in this case.

The problem here is that not all of Safari’s window objects are browser windows. Here’s a simple example:

  • quit Safari
  • launch Safari
  • in the browser window, ensure there are a couple of tabs open
  • summon the Safari preferences window

Now, in SD’s dictionary explorer, open Safari, and expand all the window objects. You should see something like this:

I’ve expanded windows 1 and 3 because they are not browser windows. One is the preferences window and the other is some unknown window which I did not create.

In addition to these windows not having any tabs, you’ll note that SD received an error when it asked for the value of the current tab property. A good scripting interface would (a) filter out hidden windows (window 3), and (b) would introduce separate window classes, one for each type of window (browser window, preferences window, etc.). With (b) done, then the tabs element collection and current tab property would only exist in browser window instances, and you could check a window’s class to see what it is and act accordingly.

These changes to Safari’s scripting interface would allow you to write code something like this:

tell application "Safari"
    repeat with aBrowserWindow in browser windows
        tabs
    end repeat
end tell

As it is, you try/on error technique is probably the best way to proceed.

But. In the variable pane the tabs do show up.

Absolutely agree on qualifying window types. Some applications do that, don’t they?

There still is the question of why the tab elements don’t appear in SD’s results pane (but, as I just posted, do appear in the variables pane.

Anytime I’ve ever created a new window I’ve always had a single tab created.
The script below creates a new tab along with the window. The “New” command in Safari does the same thing. I’ve never seen them do anything else.

tell application "Safari" to make new document

This causes me to wonder if any windows in Safari have been created by some third party software. I would expect such software would be a Safari extension. I am not aware of anything else that could generate a window in Safari that doesn’t have have a tab from the start unless it is a Safari bug.

A “tab” being an element of a window means it can be the case there are no elements of type “tab” but I can’t think of any non-third-party software that would do that. It’s a nonstandard thing to do for a Safari user window to do. Tabs are part of Apple’s interface for Safari windows.

None of my Safari scripts have ever checked for the presence of tabs before accessing any kind of “tab” information in the front window and it never caused a problem. I might check for the presence of a particular tab but I’ve never had to check if there are any tabs at all. I’ve never had to do something like in the script below:

tell application "Safari"
	if ((count of tabs of window 1) > 0) then
		-- error
	end if
end tell

If I use the script below to create a window with a tab that has no name Safari overrides the name and gives it a different name. Again it seems like a only Safari extension or a bug could do that kind of thing. No interapplication communication, including Script Debugger" would be able to do do that. That only leaves Safari, it’s extensions and lousy web page scripts used by the web developer as possible culprits. Not all web sites have good web developers. Safari extensions and poorly written web page script scripts have the power to make a real mess of things if the creator does know how to do it correctly. Any of these can do stuff like you’ve seen.

tell application "Safari" make new document with properties {name:""}

I’ve work with “Script Debugger” and “Safari” for a long time and never had any problems like this.

MitchellModel can I ask you if you are you are sure what application or process is creating these windows? Have you ever seen a tabless, nameless window created? Do the messed up pages only occur on the same sites.

This can be limitations of Cocoa Scripting like Mark suggested or it can be a tech support issue. Unfortunately this site is not set up for general tech support. I can say if the problem goes away using a different Mac with the same OS it is probably a tech support problem.

I am currently using Safari 9.1.1 under “El Capitan” 10.11.5. If the problem is on Mac OS Sierra then I have no idea what Safari would be doing.

Bill

I must be misunderstanding you because I cannot reproduce this. Here’s a video of what I see when I iterate through the Safari windows here:

I’m wondering if perhaps he’s miswriting and actually talking about the Result Panel of the Result & Variables Tab and the Inspector Tab.

In any case when not talking to Safari’s front window it’s good practice to use this form:

tell application "Safari"
   tell (windows where its document is not missing value)
      {name, tabs}
   end tell
end tell

Also – remember that windows are not indexed properly if Safari has been hidden – this has been a problem since Mountain Lion (if memory serves).

-Chris