Get the Browser Page Title & URL for Safari, Chrome, or FireFox

It has nothing to do with version 7. Keyboard Maestro gets the Chrome title/URL using AppleScript, specifically:

tell application "Google Chrome"
  if it is running then
    tell window 1
      set r to execute active tab javascript "document.title"
      if r is missing value then
        set r to ""
      end if
    end tell
  else
    set r to "Not Running"
  end if
end tell
r

The AppleScript in turn is executed via osascript.

For reasons unknown to me, this AppleScript interaction with Google Chrome fails for some people some of the time. This knocks out the Google Chrome actions as well as the Google Chrome text tokens.

Its particularly odd in that it does not seem to stop other AppleScript access to Google Chrome.

However, since I have never been able to duplicate it, and since it tends to be transient, its very hard to even figure out what is failing.

Thanks for the clarification, Peter.

Sorry for the delay... I'm not sure if this is correct: The name is "Google Chrome", displayed in KM:

Is that what you mean?

Perhaps web-page dependent ? A particular context in which I do find it reproducible is when Chrome’s front window is displaying Google’s search page.

In this context:

Safari evaluates document.title → “Google”, but
Chrome evaluates document.title → “”

With both browsers displaying the Google search page, the code below, evaluating document.title first in Safari and then in Chrome, reproducibly returns:

["Google", ""]

Test code (JavaScript for Applications):

// With front page of both browsers at the Google search page,
// Safari returns "Google", but Chrome returns only an empty string.

function run() {
  return ["Safari", "Chrome"].map(
    function (strBrowser) {
      return evalJSinBrowser(
        
        // Function to be evaluated in Browser
        function () {
          return document.title;
        },
        
        [], strBrowser
      );
    }
  );
}

// Evaluate code for a function application to a named browser (Chrome | Safari)
// fn --> [arg] --> strBrowserName --> a
function evalJSinBrowser(fnMain, lstArgs, strBrowser) {

  var strDefault = "Safari",
    blnSafari = ((
      strBrowser = ((strBrowser || '').indexOf(strDefault) === 0) ?
      strDefault : "Google Chrome"
    ) === strDefault),
    appBrowser = Application(strBrowser),
    lstWins = appBrowser.windows(),
    lngWins = lstWins.length,

    // an open window (new if none exists)
    oWin = lngWins ? lstWins[0] : blnSafari ?
    appBrowser.Document().make() && appBrowser.windows[0] :
    appBrowser.Window().make(),

    // code of an fnMain().apply(null, lstArgs) function application
    strJS = [
      '(',
      fnMain.toString(),
      ').apply(null, ',
      JSON.stringify(lstArgs),
      ');'
    ].join('');

  return (
    blnSafari ?
    appBrowser.doJavaScript(
      strJS, {
        "in": oWin.tabs[0]
      }
    ) :
    oWin.activeTab.execute({
      "javascript": strJS
    })
  );
}

Hi Michael (TX), the Chrome Page is the frontmost app/screen, when i execute the macro.

Looking a little deeper, I notice that if I request a Google search page through the Home icon of Chrome, it serves a page which does in fact lack an /html/head/title element (contrary, I think, to W3C guidelines : -)

(If, however, I request the Google search page with an explicit URL, rather than Chrome's home button, Google serves me a slightly different page - one in which the text of /html/head/title is "Google".

So in the earlier test, the different results from Safari and Chrome reflected a quirk of Google's servers, rather than a divergence of the Safari and Chrome evaluation engines …

Perhaps that is what people have been encountering ?

UPDATE

If we look at a page from the New York Times, its outer level has a value for /html/head/title

(see the last line here)

but embedded lower down in the same page is another document in which the title is an empty string:

It occurs to me that Chrome and Safari may handle these cases differently.

If embedded documents with empty titles are the issue, then there are various ways of evaluating an XPath to the first non-empty instance of /html/head/title

Aternative routes to title of page in Chrome.kmmacros (4.6 KB)

(function () {
	var nodeTitle = document.evaluate(
		'//html/head/title[string-length(text()) > 0]',
		document,
		null, 0, 0
	).iterateNext();
	
	return nodeTitle ? nodeTitle.textContent : '';
})()

Or compressed a bit into a token:

%ChromeJavaScript%(function(){var a=document.evaluate("//html/head/title[string-length(text()) > 0]",document,null,0,0).iterateNext();return a?a.textContent:""})()%

and for the case of the URL, perhaps worth trying a .js token like:

%ChromeJavaScript%document.URL%

Rob, these look handy. Thanks.

Do you think your method of getting Chome page title & URL is more bullet-proof than the native KM method (which uses AppleScript under the hood)?

I did think so for a moment

(when I noticed cases of empty title tags)

but since then I’ve found that trying to get any of these actions to talk to Chrome in a newly restarted session, before Chrome has been run, can create a glitch, at least on my system.

( Cleared by closing and restarting KM, I think )

Perhaps there’s a condition in which a Chrome helper process is not ready for the conversation ? Not sure …

UPDATE

More specifically …

If I just log out and log back in, and then run these actions without launching Chrome, the response is as expected: they return the string ‘Not Running’.

If, however, I restart the machine, and then run one of these actions without launching Chrome:

  1. No string at all is returned.
  2. Still no string if I run them again after launching Chrome and opening a web page.
  3. Normal functioning is restored if I close and reopen KM. (but not if I simply close and reopen Chrome)

Seems like the issue is avoided by ensuring that Chrome is running before executing these actions, which is easy enough to do with either putting the macro in the proper Group, or specifically testing for it in a KM If/Then action.

1 Like

@JMichaelTX
Hi and good day JMichael, Did you maybe update the KM Macro BRW SUB Get Page Title & URL from Safari… ?
It is no longer at the Dropbox link.
/
with best regards,
Omar KN
Stockholm, Sweden

Omar, my apologies for not responding to this much sooner. I missed your post and just discovered it. I have updated the macro and attached it to this thread, so it should be available for download now. Just go to my original post at the top.

Hi and good day Michael,

I have updated the macro and attached it to this thread, so it should be available for download now. Just go to my original post at the top.

Phantastic!

As it is a sub macro I added a simple if/else action: Set Clipboard to Styled Text, which works,
but the action Apply Style to Clipboard (System Clipboard) is not swallowed, whereever I set it! see red frame.

More fun with Style ...

Why wouldn't it work, any idea?

/
with best regards,
Omar K N
Stockholm, Sweden

Omar, this should work. I use it in a lot of my macros.
When I have a problem like this, I copy the Action with the issue, and paste it into a new TEST macro for testing, so I can isolate the Action. You might try that.

If you can't get it to work, then it is best if you can attach your macro to your post here, so we can test.

Lots of good stuff here, but just as a quibble, wouldn’t the keystroke sequence you used for Firefox also work (less elegantly) for Safari and Chrome?

It might, but as a general rule it is best to avoid using UI scripting unless there is no other alternative. UI changes often happen, which can break macros and scripts that depend on the UI.

FireFox has no scripting support, so we are forced to use UI scripting for it.

It also occurred to me as I was reading your response that keystrokes can’t be relied on because the user may have rebound them, either through the the App Shortcuts section of the Shortcuts Tab of the Keyboard System Preference Pane or through KM macros.

I am a long time user of KBD maestro, but had never registered on the forum, I did today just to offer thanks. you came back to your own link many years later in order to tell us in Version 8, there is a direct way to get the browser URL.

I never would have known to look, so I likely would have generated some terrible work around... thanks for that extra effort and thoughtfulness!

1 Like

Hey Dan,

Welcome to the forum!  :sunglasses:


I'm sad to say that @JMichaelTX will not see your thank you note...

The Passing of JMichaelTX

JMichaelTX – Unforgettable Generosity With His Time and Knowledge

-Chris

1 Like

Oh wow! Well his tribute on this forum is certainly appropriate.
Thanks for the link.
--dan

1 Like