Get the string from selected text/ highlighted text using JXA - automator

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!

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:
Sending Keystrokes in JXA
JXA Resources

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.

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.

Related

HTMLIFrameElement.contentWindow.print() from GoogleSheets is not opening print preview

I am using GoogleSheets to print a png/image file using HTMLService. I created a temporary Iframe element with an img tag in the modalDialog and call IFrame element's contentWindow.print() function after IFrame element and its image are loaded. (I have not set visibility:hidden attribute of IFrame element to check if image is getting loaded.)
However, I only see the printer dialog without any print preview. I am testing on Firefox. Am I missing anything?
[Updated] - I am using Googles Apps script. performPrint() is in printJsSource.html and openUrl() is in Code.gs.
Inside printJsSource.html
function performPrint(iframeElement, params) {
try {
iframeElement.focus()
// If Edge or IE, try catch with execCommand
if (Browser.isEdge() || Browser.isIE()) {
try {
iframeElement.contentWindow.document.execCommand('print', false, null)
} catch (e) {
iframeElement.contentWindow.print()
}
} else {
// Other browsers
iframeElement.contentWindow.print() // as I am using Firefox, it is coming here
}
} catch (error) {
params.onError(error)
} finally {
//cleanUp(params)
}
}
Inside Code.gs
function openUrl() {
var html = HtmlService.createHtmlOutputFromFile("printJsSource");
html.setWidth(500).setHeight(500);
var ui = SpreadsheetApp.getUi().showModalDialog(html, "Opening ..." );
}
I think there is some general confusion about the concept
First of all, function performPrint() seems to be a client-side Javascript funciton, while function openUrl() is a server-side Apps Script function.
While you did not specify either you use Google Apps Script - if you do so, function openUrl()belongs into the code.gs file and function performPrint() into printJsSource.html file
function openUrl() allows you to open a modal dialog which can show some data on the UI, e.g. your image
Do not confuse this behavior with actual printing (preview)!
It is NOT possible to trigger the opening of a Google Sheets printing preview programamticaly!
The Javascript method you are using iframeElement.contentWindow.print() might trigger the printing of the whole content of a browser window (different from the Google Sheets printing dialog, also depends on the browser), but if you try to incorporate it into the client-side coe of an Apps Script project, you will most likely run into restrictions due to the scopes of modal diloags and usage of iframes.
While from your code it is hard to say either you implemented the funcitons in the correct files of the Apps Script project, keep in mind that to work with iframes you need to specify in function openUrl()
html.setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);

Getting the current page's window with the low level api of the Firefox SDK

I'm creating a Firefox extension for adding some functionality to certain Web pages. I need to check that some elements do exist and highlight them, so I'm using xpath to check and locate them. I know about manipulating tabs and the content through tabs and ports, but I really need to use the low level API and do it without ports. The thing is, I don't know how to get the current opened tab window (I can also open the tab, but I'm not getting the window). I already tryed to open a tab and :
tabs.open({
url: url,
onOpen: function onOpen(tab) {
// get the XUL tab that corresponds to this high-level tab
var lowLevelTab = viewFor(tab);
var browser = tab_utils.getBrowserForTab(lowLevelTab);
var doc = browser.contentDocument;
console.log(doc); //THIS IS AN EMPTY DOC
// get the most recent window. This give me a XUL window, and I can't sucessfully execute eval on that...
var win = utils.getMostRecentBrowserWindow();
}})
I sawa lot of methods for retrieving different kinds of windows, but I'm not finding the explanation about the differences. E.g. Chroe window, XUL window, NSI window, base window...I just need the current Web page's document window.
Any clarification is welcome.
Thanks in advance,
I just needed to listen for another tab event:
onReady: function onOpen(tab) {
var content = utils.getMostRecentBrowserWindow().content;
var domInstances = content.document.evaluate(me.getTemplateXpath(), content.document, null, 4, null);
var res = domInstances.iterateNext();
while (res) {
console.log(res);
res.style["background-color"] = "orange";
res = domInstances.iterateNext();
}
callback();
}

Open URL with a set Target

EDIT:
The solution I am seeking is a command line to be run to accomplish this from a batch file in Windows.
How would I mimic a browser function to open a URL with a specific target so that if that tab is already open it will load there instead of creating a new tab?
So instead of the default http://url.com with the target "_blank", I could change this to "w00t", etc.
I am using Chrome exclusively, so if this were to be a Chrome specific command, that would be acceptable.
You could create a HTML-page and add the following code like this:
<script>
var url = getQueryVariable("url");
var target = getQueryVariable("target");
window.open(url,target);
function getQueryVariable(variable) {
var query = window.location.search.substring(1);
var vars = query.split("&");
for (var i=0;i<vars.length;i++) {
var pair = vars[i].split("=");
if (pair[0] == variable) {
return pair[1];
}
}
}
</script>
I have this script hosted here: scriptcoded.github.io/redirect
You could then call it from a batch-file using this command:
START scriptcoded.github.io/redirect?url=http://www.google.com&target=w00t
Use ?url=http://www.google.com&target=_blank to set the redirect.
The only problems I find with this method is that some browsers blocks the new window and that the tab won't close. Yes, we could use window.close();, but it will only close tabs that were opened by the webpage itself.
Hope it helps!
set name for html tag of target page like this:
<html name="w00t">
Note: A link to URL with target name, sets the name for target window automatically:
Google

Google Script to open URL in same window as Spreadsheet

I'm trying to work around the lack of API for Google Spreahsheet's Filter Views, by passing the filter view's URL into a hyperlink displayed in a sidebar.
Importantly: I want the filter view URL to open in the same window as, and thus replace, the spreadsheet. The hyperlink target should then be _self
function listFilterViews(){
var uiInstance = UiApp.createApplication()
.setTitle('Teacher Views');
var panel = uiInstance.createVerticalPanel();
panel.setSpacing(5)
var scroll = uiInstance.createScrollPanel();
scroll.setHeight("100%")
var url = "https://docs.google.com/blablabla"
var link = uiInstance.createAnchor("click me", url)
link.setTarget("_self")
panel.add(link);
scroll.add(panel)
uiInstance.add(scroll);
SpreadsheetApp.getUi().showSidebar(uiInstance);
}
However, the URL doesn't open in the same window as expected but in an other window instead. How can I fix this?
According to the setTarget documentation:
"(setting a target to _self) will only work if the app is being shown as a standalone service. It will have no effect when called inside a dialog, such as in a Google Spreadsheet."
Apps Script intentionally prevents scripts from being able to switch the view of the current window, as a security measure.

Text URL in AIR iOS app not selectable

I'm using AIR 2.0 (soon will be updating to 3.3 with Flash CS6) to create an iPad app. We have textfields (Classic, dynamic) which sometimes contain one or multiple htmlText links which need to be clickable. In the desktop version of the program, all text is selectable and the links are easily accessed. My problem is that it takes me mashing the link like 20 times on the iPad before it will recognize that there's a link and navigate to it in Safari. The other strange thing is that none of the text appears to be selectable - I can't get the iPad cursor, copy/paste menu, etc. to show up.
I think, from reading other threads, that the hit area for the URL is only the stroke on the text itself... if that's true, what can I do to increase the hit area? Or make text selectable? It was suggested elsewhere to put movieclips behind the URLs but that's not really possible as this is all dynamic text from XML files.
I've read about StageText but I gather this is only used for input fields, which is not the case here.
I'm reasonably advanced in AS3 but I'd prefer an easy solution over re-writing large chunks of code. At the moment the only thing I can think to do is get the URL and make it so that as soon as you touch anywhere on the textfield, it navigates to the link. But this would break down if there were more than 1 URL in a given textfield.
Any ideas?
I had this exact same issue, and it's had me flummoxed for a while.
Here's what I did to get the desired behaviour:
1) Instead of using a listener for TextEvent.LINK, listen for MouseEvent.CLICK (or TouchEvent.TAP) on the TextField.
eg.
var tf:TextField = new TextField();
tf.addEventListener(MouseEvent.CLICK, linkClicked);
2) In the linkClicked() handler, you use getCharIndexAtPoint() to determine the index of the character that was clicked, and then from that determine the URL from the TextFormat of the character. This is adapted from a post by Colin Holgate on the Adobe Forums (http://forums.adobe.com/thread/231754)
public function linkClicked(e:MouseEvent):void {
var idx:int = e.target.getCharIndexAtPoint(e.localX, e.localY);
trace("Tapped:",idx);
var tf:TextFormat = e.target.getTextFormat(idx);
if(tf.url != "" && tf.url != null) {
var linkURL:String = tf.url;
trace(linkURL);
// Hyperlink processing code here
dispatchEvent(new UIEvent(UIEvent.LINK_TAPPED,tf.url));
}
}
3) The last line (dispatchEvent()) is sending a custom event to another function to process the link, but you could easily inline your code here.
I've tested on an iPad 3 running iOS6.1, building with AIR3.5. Links are much more responsive, and I don't find myself mashing the screen trying to hit the stroke of the text!

Resources