1

I'm supper new here, either Javascript and JXA, so pardon me if I make some stupid questions. But I'm trying to figure out a way to get the string from the highlighted text using JXA - JavaScript for Automation, for Javascript can be recognized in Automator since Yosemite, I thought I can make something work with these: window.getSelection in:

function getSelectedText() {
  if (window.getSelection) {
      txt = window.getSelection();
  } else if (window.document.getSelection) {
      txt =window.document.getSelection();
  } else if (window.document.selection) {
      txt = window.document.selection.createRange().text;
  }
  return txt;  
}

This code is not mine, somebody posted this. But I've found out that I can't use window or document here in Automator to make change to Mac OS, so can someone show me how to convert this Javascript code into JXA which Automator can understand?

Thanks a lot!

Le Hoa
  • 23
  • 4

3 Answers3

2

In general, you can use the System Events app to copy and paste with any app.

'use strict';

//--- GET A REF TO CURRENT APP WITH STD ADDITONS ---
var app = Application.currentApplication()
app.includeStandardAdditions = true

var seApp = Application('System Events')

//--- Set the Clipboard so we can test for no selection ---
app.setTheClipboardTo("[NONE]")

//--- Activate the App to COPY the Selection ---
var safariApp = Application("Safari")
safariApp.activate()
delay(0.2) // adjust the delay as needed

//--- Issue the COPY Command ---
seApp.keystroke('c', { using: 'command down' }) // Press ⌘C 
delay(0.2) // adjust the delay as needed

//--- Get the Text on the Clipboard ---
var clipStr = app.theClipboard()
console.log(clipStr)

//--- Display Alert if NO Selection was Made ---
if (clipStr === "[NONE]") {
 var msgStr = "NO Selection was made"
 console.log(msgStr)
 app.activate()
 app.displayAlert(msgStr)
}

For more info see:

JMichaelTX
  • 1,659
  • 14
  • 19
  • Thanks for! But it seems that this is a little bit high-level for me to understand. I made it work in Automator, but I want to really know what is going on in your codes, can you please give some further explanation about it? Thanks a bunch! – Le Hoa Jun 21 '16 at 08:05
  • Glad it worked for you. If this answers your question, please check it as the "accepted answer." (See http://stackoverflow.com/help/accepted-answer) I provided detailed comments in my script that should guide you. I also provided two references -- did you read them? I don't know what else to add. If you want to ask a specific question, I'll try to answer. – JMichaelTX Jun 26 '16 at 04:26
  • sorry, I was trying to vote but it said I need at least 15 reputations to do so. Didn't know the check mark works that way. Yah I googled it out and kind of got what the codes do in specific. Many thanks. – Le Hoa Jun 27 '16 at 02:53
1

Don't do that, it's only applicable to JavaScript embedded inside a web browser. JXA is a standalone JS interpreter that has absolutely no understanding of web pages or DOM (and frankly doesn't have much clue about Mac application scripting either, btw).

Instead, use Automator to create an OS X Service as services can manipulate selected text in almost any OS X app; no application scripting required.

foo
  • 3,171
  • 17
  • 18
  • It's true that making it with Automator workflow is much less effort, I managed to create one. But I was told to do it again using Javascript, that's why things have become this complicated. Anyway, thanks for your answer. – Le Hoa Jun 21 '16 at 07:32
  • Who told you to do it again in JavaScript? Do they even know what they're talking about? There is no way to get selected text from applications using the DOM-based JavaScript in your original post, because that's not how Mac automation works. The closest you can get is to use GUI Scripting as in JMichaelTX's post to send Cmd-C keystrokes, but GUI Scripting is an abominable hack: flaky, unreliable, and an absolute last resort; definitely not the sort of code you want to be writing for others to use. OS X Services are the correct way to do it, and the easiest way to write those is in Automator. – foo Jun 21 '16 at 11:05
  • i.e. Use the right tool for the job. Anyone who says otherwise is an idiot. If your 'Manipulate Selected Text' service needs to interact with scriptable applications or the Unix shell, Automator includes `Run AppleScript` and `Run Shell Script` actions for running scripts directly. [Here's another Services tutorial](http://arstechnica.com/apple/2011/03/howto-build-mac-os-x-services-with-automator-and-shell-scripting/) that shows how to do this. – foo Jun 21 '16 at 11:15
  • Sorry I didn't make myself clear enough. I realized that the using of "window" or "document" is impossible in JXA, or Automator, so I asked if anyone know how to write a Javascript that can do the job without using the DOM methods, since there are quite little documentation about JXA methods that I can refer to. Not that using DOM-based Javascript to get the selected text. – Le Hoa Jun 22 '16 at 07:51
  • And you are right. We should use the right tool to do the job. I'm learning and my instructor tell me to do this task. Maybe it's not an efficient way, but at least I now know it's not an efficient way. And receiving answers from pros like you guys also teach me a lot. Thank you. – Le Hoa Jun 22 '16 at 07:51
1

You need to mix JXA and Safari’s javaScript…

var Safari = Application("Safari") // get Safari

selection = Safari.doJavaScript("document.getSelection().toString()",{    
    in: Safari.windows[0].tabs[0] // assume frontmost window and tab
})

The script is in JXA, but the document.getSelection().toString() is Safari’s javaScript.

Of course you will need to enable apple events in Safari… http://osxdaily.com/2011/11/03/enable-the-develop-menu-in-safari/

If you want the selected text from another application, the code might be very different.

JakeCigar
  • 603
  • 6
  • 12
  • Yea I want to get the text from other applications too... But this is really good references. Thank you! – Le Hoa Jun 21 '16 at 07:58