Giter Site home page Giter Site logo

jxa-cookbook's Introduction

JavaScript for Automation is a new thing in Mac OS X Yosemite. It allows you to control applications using JavaScript language. How awesome!

However, its documentation covers the basics of using JavaScript to interact with the Open Scripting Architecture. For many tasks in scripting, there's a lot to figure out, and many different documentations to refer to.

So I created this JavaScript for Automation cookbook that features a lot of examples, such as:

Where it makes sense, I try to link to the official documentation as much as possible so you can dive deeper.

For ease of editing and contribution, the cookbook's contents are on the wiki.

Enter Wiki

jxa-cookbook's People

Contributors

dtinth avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

jxa-cookbook's Issues

Changing values in applications such as Contacts

It would be nice to have examples of not only reading but also writing to applications from the CLI. Something along:

% osascript -l JavaScript -i
>> contact=Application('Contacts');
=> Application("Contacts")
>> contact.people.byName("John Smith").organization();
=> "Acme Inc."
  1. How to change the organization value (from Acme Inc. to FooBar Co.)?
  2. How to create a new entry with encoding issues (utf-8 drum)?
  3. How to do tie it int the CLI (though this one is already answered in one of your sections)?

better integrating Objective-C Bridge documentation + proposed expansions

The page Using Objective C (ObjC) with JXA is missing from the Table of Contents on the Home page of the wiki.

I think it should definitely be there to help navigation.

I can put it there myself, but I thought I'd create an issue anyway to notify the wiki community I've made this little change.

I will put it in the same order as it is on the Table of Contents sidebar.

Personally though, I think it would make more sense if this section were indexed after Shell and CLI Interactions, but before Importing Scripts from Other Files.

JXA chat network

Hi everybody, more an announcement than an issue.

I've noticed the wiki has not been so active lately, but I've been having a lot of fun with JXA the last few weeks and I thought a way to bring some new energies into the JXA community could be to have a chat somewhere where people can ask questions/share tricks, which doesn't seem exist so far.

Since the community doesn't seem that large I thought a chat with saved history like slack or gitter would be better than something more ephemeral like irc. So I created both a new gitter community and a new slack workspace.
I personally prefer slack, but the fact that every workspace on slack has its own separate log in is a bit annoying compared to logging in on gitter with a github account?

Would be really nice if anybody feels like joining me and get one of the two chats going. ☺️

JXA errors: "failed to get scripting definition", "Application can't be found"

I'm getting these errors right off the bat:

$ osascript -l JavaScript -i 
>> var app = Application.currentApplication()
2015-03-21 15:08:55.254 osascript[3287:40551] warning: failed to get scripting definition from     /usr/bin/osascript; it may not be scriptable.
=> undefined
>> SystemEvents = Application('SystemEvents')
!! Error on line 1: Error: Application can't be found.
>> ObjC.import('stdlib')
=> undefined 
>> ObjC.import('AppKit')
=> undefined
>> var isRunning = false
=> undefined

Any ideas? Is there something I need to update or install before using JXA?

Definitive API?

Is there a way to show just the definitive API? For example, I want to know all the properties or methods of the Application object, where is this?

keystroke/using doesn't seem to work

On the System Events page, se.keystroke('a', { using: 'command down' }) doesn't seem to work for me in a place that keystroke "a" using {command down} worked in AppleScript. I get the error Named parameters must be passed as an object.

Error: Wrong index

In the cookbook examples using app.windows.push(app.Window()) leads to Error: Wrong index

I recommend changing the examples to useapp.Window().make();

How to correctly call $.realpath

//t.js
#!/usr/bin/env osascript -l JavaScript
ObjC.import('stdlib')
console.log($.realpath("t.js",Ref()))

//test
➜ untitled ./t.js
[1] 86703 segmentation fault ./t.js
➜ untitled ./t.js
/Users/ZhouG/WebstormProjects/untitled/t.js
➜ untitled ./t.js
osascript(86716,0x7fffada643c0) malloc: *** error for object 0x7fb5b2ca8388: incorrect checksum for freed object - object was probably modified after being freed.
*** set a breakpoint in malloc_error_break to debug
[1] 86716 abort ./t.js
➜ untitled ./t.js
osascript(86722,0x7fffada643c0) malloc: *** error for object 0x7fd248525908: incorrect checksum for freed object - object was probably modified after being freed.
*** set a breakpoint in malloc_error_break to debug
[1] 86722 abort ./t.js
➜ untitled ./t.js
osascript(86728,0x7fffada643c0) malloc: *** error for object 0x7ff5cec66648: incorrect checksum for freed object - object was probably modified after being freed.
*** set a breakpoint in malloc_error_break to debug
[1] 86728 abort ./t.js
➜ untitled ./t.js
osascript(86734,0x7fffada643c0) malloc: *** error for object 0x7ff0765785b8: incorrect checksum for freed object - object was probably modified after being freed.
*** set a breakpoint in malloc_error_break to debug
[1] 86734 abort ./t.js
➜ untitled ./t.js
/Users/ZhouG/WebstormProjects/untitled/t.js
➜ untitled ./t.js
/Users/ZhouG/WebstormProjects/untitled/t.js

read file as class utf8

StandardAdditions of ScriptEditor has a function for reading files and it has the option "as"...

so i have code in apple script that work nice:
read file theFile as «class utf8»

how can i do this in JS?
app.read(Path(theFile), {as: ???});

text in my file with utf8:
AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz
АаБбВвГгДдЕеЁёЖжЗзИиЙйКкЛлМмНнОоПпРрСсТтУуФфХхЦцЧчШшЩщЪъЫыЬьЭэЮюЯя
_-–—,;:!¡?.…·'‚‹›"«()[]§¶@*/&#%‡•`˜^˙˚°©∂∆+±<=≠>¬|~⁄√∞∫≈≤≥¢$£€ªåÅæçfiƒºß™Ω

text in my file without utf8:
AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz
–Р–∞–С–±–Т–≤–У–≥–Ф–і–Х–µ–Б—С–Ц–ґ–Ч–Ј–Ш–Є–Щ–є–Ъ–Ї–Ы–ї–Ь–Љ–Э–љ–Ю–Њ–Я–њ–†—А–°—Б–Ґ—В–£—Г–§—Д–•—Е–¶—Ж–І—З–®—И–©—Й–™—К–Ђ—Л–ђ—М–≠—Н–Ѓ—О–ѓ—П
_-вАУвАФ,;:!¬°?.вА¶¬Ј'вАЪвАєвАЇ"¬Ђ()[]¬І¬ґ@*/\&#%вА°вАҐ`ЋЬ^ЋЩЋЪ¬∞¬©вИВвИЖ+¬±<=вЙ†>¬ђ|~вБДвИЪвИЮвИЂвЙИвЙ§вЙ•¬Ґ$¬£вВђ¬™√•√Е√¶√ІпђБ∆Т¬Ї√ЯвДҐќ©

How to copy image or file to clipboard?

AppleScript copy image to clipboard by path like this

set img to POSIX file ("/Users/lll00lll/Library/Documents/temp.jpg")
set the clipboard to img

but how to translate AppleScript code to JavaScript?

JavaScript like this can copy string to clipboard but not img or file

var app = Application('Script Editor');
app.includeStandardAdditions = true;
app.setTheClipboardTo(str);

or use Objective-C ?but i don't how to edit it to "generalPasteboard.setData"

$.NSPasteboard.generalPasteboard.clearContents;
$.NSPasteboard.generalPasteboard.setStringForType($(str), $.NSPasteboardTypeString);

Integrating with JXA-Snippets example scripts

Hi I made (JXA-Snippets)[https://github.com/SeamlessIO/JXA-Snippets] because I was missing a source of JXA examples.
JXA-Cookbook helped me out quite a bit and I was thinking we could combine the two somehow. Maybe an ingredients section in the Cookbook.

XML ?

It would be very useful, I think to include a section on working with XML and xQuery in JXA.

(Particularly if anyone has experimented successfully with using NSXMLDocument from JXA – so far it is defeating me :-)

Rob

Test for Uploading Images

I have been unable to find a method to actually upload (as opposed to link) an image for use in the wiki.

I found this tip, which is really a workaround, that I'm testing here.
https://stackoverflow.com/a/20119831/915019

If you want to quickly upload an image with drag/drop, you can perform the following (albeit hackish):

Create a dummy issue; drag & drop your image there; copy/paste the uploaded markdown image code to your wiki;

After you create the issue once, you can use it any number of times to do this.

Hope this helps anyone looking for a quick fix, without needing to have the image reside in the repo.

So here is a test image:

updated-icon-small

The code looks like this:
![updated-icon-small](https://user-images.githubusercontent.com/11052885/27666742-9eb026c8-5c3b-11e7-9201-ee256f70c4fa.gif)

Is there a better way?

Clipboard typeClasses ?

In Applescript we can evaluate

the clipboard as record

and get an object with keys to any RTF, HTML utf8 etc data

The Javascript view of the StandardAdditions.sdef documentation suggests something similar, but doesn't (I think) define the set of accepted type class arguments.

theClipboard method : Return the contents of an application’s clipboard. Use in a ‘tell’ block after activating the application
theClipboard
[as: type class] : the type of data desired
→ any : the data

It might be good, if anyone can unlock JXA access to HTML and RTF clipboard contents, to have a clipboard section of this Wiki …

( .clipbboardInfo() returns an array of byte sizes for various types of clipboard data, but offers only undefined where one might expect to see the type class names. Perhaps ObjC access to NSPasteBoard is the route to take … )

Problems with Mojave?

Since I upgraded to macOS 10.14, $.NSMakeRect now always throws NSInvalidArgumentException with reason: NSGetSizeAndAlignment(): unsupported type encoding spec 'G' at 'GPoint}"size"{CGSize}}' in '{CGPoint}"size"{CGSize}}' ... wat?!

Anybody else run into this? Ideas on what's going on?

Program:

#!/usr/bin/env osascript -l JavaScript
ObjC.import("Cocoa");

function run(argv) {
    var r = $.NSMakeRect(0, 0, 100, 100);
}

Result:

2018-10-16 11:16:52.101 osascript[53689:2461150] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'NSGetSizeAndAlignment(): unsupported type encoding spec 'G' at 'GPoint}"size"{CGSize}}' in '{CGPoint}"size"{CGSize}}''
*** First throw call stack:
(
        0   CoreFoundation                      0x00007fff2f762571 __exceptionPreprocess + 256
        1   libobjc.A.dylib                     0x00007fff5b70fefb objc_exception_throw + 48
        2   CoreFoundation                      0x00007fff2f6b4bf0 __NSGetSizeAndAlignment + 1093
        3   CoreFoundation                      0x00007fff2f6b4a60 __NSGetSizeAndAlignment + 693
        4   CoreFoundation                      0x00007fff2f6c17d5 NSGetSizeAndAlignment + 33
        5   JavaScriptAppleEvents               0x00007fff4db298ba JSOCObjCTypeIterateTypes + 136
        6   JavaScriptAppleEvents               0x00007fff4db299ae JSOCObjCTypeIterateStructElements + 131
        7   JavaScriptAppleEvents               0x00007fff4db490a7 +[JSOCType typeWithObjCType:] + 457
        8   JavaScriptAppleEvents               0x00007fff4db276af -[JSOCBridgeSupport typeForArgumentInfo:fallbackObjCType:] + 475
        9   JavaScriptAppleEvents               0x00007fff4db27751 -[JSOCBridgeSupport typeForFunctionInfo:isBlock:] + 99
        10  JavaScriptAppleEvents               0x00007fff4db282ac -[JSOCBridgeSupport functionPointerForFunctionWithName:] + 89
        11  JavaScriptAppleEvents               0x00007fff4db22f92 __JSOCFunctionConstructorBlock_block_invoke + 304
        12  CoreFoundation                      0x00007fff2f6b80ec __invoking___ + 140
        13  CoreFoundation                      0x00007fff2f6b7fb7 -[NSInvocation invoke] + 311
        14  JavaScriptCore                      0x00007fff32d0cde8 _ZN3JSC24ObjCCallbackFunctionImpl4callEP9JSContextP13OpaqueJSValuemPKPKS3_PS6_ + 440
        15  JavaScriptCore                      0x00007fff32d0c81c _ZN3JSCL34objCCallbackFunctionCallAsFunctionEPK15OpaqueJSContextP13OpaqueJSValueS4_mPKPKS3_PS6_ + 236
        16  JavaScriptCore                      0x00007fff32d0c0ec _ZN3JSC19APICallbackFunction4callINS_20ObjCCallbackFunctionEEExPNS_9ExecStateE + 492
        17  JavaScriptCore                      0x00007fff32cf4d63 vmEntryToNative + 241
        18  JavaScriptCore                      0x00007fff32b1e7fe _ZN3JSC11Interpreter11executeCallEPNS_9ExecStateEPNS_8JSObjectENS_8CallTypeERKNS_8CallDataENS_7JSValueERKNS_7ArgListE + 542
        19  JavaScriptCore                      0x00007fff33546051 _ZN3JSC12profiledCallEPNS_9ExecStateENS_15ProfilingReasonENS_7JSValueENS_8CallTypeERKNS_8CallDataES3_RKNS_7ArgListE + 177
        20  JavaScriptCore                      0x00007fff32b1e474 JSObjectCallAsFunction + 468
        21  JavaScriptCore                      0x00007fff32c84763 -[JSValue callWithArguments:] + 291
        22  JavaScriptAppleEvents               0x00007fff4db30215 __JSOCDollarObject_block_invoke_2 + 357
        23  CoreFoundation                      0x00007fff2f6b80ec __invoking___ + 140
        24  CoreFoundation                      0x00007fff2f6b7fb7 -[NSInvocation invoke] + 311
        25  JavaScriptCore                      0x00007fff32d0cde8 _ZN3JSC24ObjCCallbackFunctionImpl4callEP9JSContextP13OpaqueJSValuemPKPKS3_PS6_ + 440
        26  JavaScriptCore                      0x00007fff32d0c81c _ZN3JSCL34objCCallbackFunctionCallAsFunctionEPK15OpaqueJSContextP13OpaqueJSValueS4_mPKPKS3_PS6_ + 236
        27  JavaScriptCore                      0x00007fff32d0c0ec _ZN3JSC19APICallbackFunction4callINS_20ObjCCallbackFunctionEEExPNS_9ExecStateE + 492
        28  JavaScriptCore                      0x00007fff32cf4d63 vmEntryToNative + 241
        29  JavaScriptCore                      0x00007fff32b1e7fe _ZN3JSC11Interpreter11executeCallEPNS_9ExecStateEPNS_8JSObjectENS_8CallTypeERKNS_8CallDataENS_7JSValueERKNS_7ArgListE + 542
        30  JavaScriptCore                      0x00007fff33546051 _ZN3JSC12profiledCallEPNS_9ExecStateENS_15ProfilingReasonENS_7JSValueENS_8CallTypeERKNS_8CallDataES3_RKNS_7ArgListE + 177
        31  JavaScriptCore                      0x00007fff32b1e474 JSObjectCallAsFunction + 468
        32  JavaScriptAppleEvents               0x00007fff4db2fd0e GetProperty + 309
        33  JavaScriptCore                      0x00007fff32d27361 _ZN3JSC16JSCallbackObjectINS_20JSDestructibleObjectEE14callbackGetterEPNS_9ExecStateExNS_12PropertyNameE + 225
        34  JavaScriptCore                      0x00007fff32ca1876 llint_slow_path_get_by_id + 5302
        35  JavaScriptCore                      0x00007fff32cf7a73 llint_entry + 11449
        36  JavaScriptCore                      0x00007fff32cf4c45 vmEntryToJavaScript + 235
        37  JavaScriptCore                      0x00007fff32b1e7b6 _ZN3JSC11Interpreter11executeCallEPNS_9ExecStateEPNS_8JSObjectENS_8CallTypeERKNS_8CallDataENS_7JSValueERKNS_7ArgListE + 470
        38  JavaScriptCore                      0x00007fff33546051 _ZN3JSC12profiledCallEPNS_9ExecStateENS_15ProfilingReasonENS_7JSValueENS_8CallTypeERKNS_8CallDataES3_RKNS_7ArgListE + 177
        39  JavaScriptCore                      0x00007fff32b1e474 JSObjectCallAsFunction + 468
        40  JavaScriptCore                      0x00007fff32c84763 -[JSValue callWithArguments:] + 291
        41  JavaScriptOSA                       0x00007fff4db71927 -[JSStorage(JSProcedures) handleEvent:inContext:modeFlags:resultingResultID:] + 3551
        42  CoreFoundation                      0x00007fff2f6b80ec __invoking___ + 140
        43  CoreFoundation                      0x00007fff2f6b7fb7 -[NSInvocation invoke] + 311
        44  JavaScript                          0x0000000117c517bc JavaScriptComponent + 1140
        45  OpenScripting                       0x00007fff2ece12da OSAExecuteEvent + 52
        46  osascript                           0x000000010c73b565 osascript + 9573
        47  libdyld.dylib                       0x00007fff5c7d6085 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
Abort trap: 6

Can't import a custom framework

I followed the chapter Using Objective C (ObjC) with JXA and tried to import a custom framework as follows,

#!/usr/bin/osascript -l JavaScript

ObjC.import('/User/me/demo.framework')
$.Demo.test()

but I got an error execution error: Error on line 2: Error: nothing found to import (-2700) when executed it.
Is there some special work to the framework that can be imported in JXA?
BTW, the demo.framework's implementation is simple.

// demo.h
@interface Demo
+ (void)test;
@end
// demo.m
#import "demo.h"
@implementation Demo
+(void)test
{
    NSLog(@"Test!");
}
@end

Evaluating Application.running() simpler than the methods now described

I wonder whether the discussion of checking that an application is running

(at https://github.com/dtinth/JXA-Cookbook/wiki/Getting-the-Application-Instance#checking-that-an-application-is-running-before-using-application )

overlooks the method .running() on the Application interface ?

This doesn't seem to incur obvious overhead (doesn't, for example, attempt to launch the app).

if (Application('TaskPaper').running()) {
    // ...
}

Accepting drag and drop files

If you save an applescript as an application, you can process files which are dropped into its icon by defining a function called open. For example:

on run
    set _files to (choose file with multiple selections allowed)
    main(_files)
end run

on open _files
    main(_files)
end open

Is this possible with Javascript?

NSMatrix selectCell

I have one problem in my code below.
I am interested in matrix1.selectedCell.tag
If I change state of the 2nd cell to true it changes, but the state of the first cell is not changed to false,
and I can't select one of them.
I understand that I need to use selectCell(atRow:column:) or selectCell(withTag:) methods, but I can not understand the syntax.

Please help me to understand the syntax of selectCell(atRow:column:) or selectCell(withTag:) methods

//================ code ===================
var app = Application.currentApplication();
app.includeStandardAdditions = true;
ObjC.import("Cocoa");

var styleMask = $.NSTitledWindowMask | $.NSClosableWindowMask | $.NSMiniaturizableWindowMask;
var windowWidth = 450;
var windowHeight = 295;
var minWidth = 450;
var minHeight = 295;
var ctrlsHeight = 80;
var window = $.NSWindow.alloc.initWithContentRectStyleMaskBackingDefer(
$.NSMakeRect(0, 0, windowWidth, windowHeight),
styleMask,
$.NSBackingStoreBuffered,
false
);

var proto = $.NSButtonCell.alloc.init;
proto.title = "Options";
proto.buttonType = $.NSRadioButton;

var matrix1 = $.NSMatrix.alloc.initWithFrameModePrototypeNumberOfRowsNumberOfColumns(
$.NSMakeRect(198, 195, 270, 20),
$.NSRadioModeMatrix, proto, 1, 3
);

matrix1.cellSize = {width: 90, height: 20};

var m1Cells = matrix1.cells;

m1Cells.objectAtIndex(0).title = "Title 1";
m1Cells.objectAtIndex(0).tag = 1;
m1Cells.objectAtIndex(1).title = "Title 2";
m1Cells.objectAtIndex(1).tag = 2;
m1Cells.objectAtIndex(2).title = "Title 3";
m1Cells.objectAtIndex(2).tag = 3;

window.contentView.addSubview(matrix1);

window.center;
window.title = "Matrix Test";
window.makeKeyAndOrderFront(window);

matrix1.cells.objectAtIndex(1).state = true;

console.log(matrix1.selectedCell.title.js);
console.log(matrix1.selectedCell.tag);
//================ code ===================

How to work with ObjC functions with pointer parameters?

Take this as an example:

CGError CGGetDisplaysWithRect(CGRect rect, uint32_t maxDisplays, CGDirectDisplayID *displays, uint32_t *matchingDisplayCount);

The above function returns a "result code".
However the function is designed to get all the displays which 'contain/intersect' a specified rectangle.

In ObjC this variable, displays, is passed by reference (or by a pointer). i.e.

CGGetDisplaysWithRect(rect,<someInt>,&displays,<someInt>)

would fill the variable displays with the display IDs for all displays connected to the computer which intersects rectangle rect.

In Javascript however, there are no pointers. Thus I assume there are also no pointers in JXA? How do you deal with these sorts of functions in JXA?

Note: Now, on 01/07/2017, I've had a little more practice with javascript I know that all objects passed to a function are passed 'by reference'. However in the case of JXA this still doesn't help because the way these objects are dealt with in javascript is different to how the variables are used in ObjC

Object specifiers and Apple Music

Hi there! First, let me just say on behalf of many frustrated Apple Script developers, thank you for this resource.

I'd like to start a discussion about a bug(?) I've been dealing with for a while. This is definitely a bug in my application (which I have now fixed), but I wonder if it is a bug in the JXA implementation or not.

I am referring to this part of your documentation: https://github.com/JXA-Cookbook/JXA-Cookbook/wiki/iTunes#getting-the-current-track-an-example-of-specifier-vs-property-access

Simply put, when not using what you refer to as an "object specifier", it isn't possible to get the name/artist of the playing track when that track is from Apple Music. When it is a track in my own library (including iTunes In The Cloud, even when streaming and not locally downloaded) it works fine, but whenever it is a track from Apple Music, it fails.

Examples:

Example fetching current track using property (e.g. with parenthesis)

Code:

var musicApp = Application('com.apple.Music');
if (musicApp.playerState() === 'playing') {
    var track = musicApp.currentTrack();

    console.log(track.name());
}

Replies, when streaming a song from iTunes in the Cloud:

app = Application("Music")
	app.playerState()
		--> "playing"
	app.currentTrack()
		--> app.sources.byId(63).userPlaylists.byId(26027).sharedTracks.byId(26072)
	app.sources.byId(63).userPlaylists.byId(26027).sharedTracks.byId(26072).name()
		--> "Gravity"

Replies, when streaming a song from Apple Music:

app = Application("Music")
	app.playerState()
		--> "playing"
	app.currentTrack()
		--> app.sources.byId(70).playlists.byId(64278).urlTracks.byId(65530)
	app.sources.byId(70).playlists.byId(64278).urlTracks.byId(65530).name()
		--> Error -1728: Can't get object.
Example fetching current track using object specifier (e.g. without parenthesis)

Code:

var musicApp = Application('com.apple.Music');
if (musicApp.playerState() === 'playing') {
    var track = musicApp.currentTrack;

    console.log(track.name());
}

Replies, when streaming a song from iTunes in the Cloud:

app = Application("Music")
	app.playerState()
		--> "playing"
	app.currentTrack.name()
		--> "Gravity"

Replies, when streaming a song from Apple Music:

app = Application("Music")
	app.playerState()
		--> "playing"
	app.currentTrack.name()
		--> "Little Things"

I'd love some discussion about this, particularly regarding iTunes/Music.app. Does this apply to other types of objects? Does anyone have any idea why this happens? What if I wanted to keep a reference to a previously playing song, am I out of luck?

(This may be related to #11, but looks like the behavior has either changed, or this was not debugged/discussed enough previously. I'd like to see this issue be kept open for some discussion to occur for a bit.)

Semicolons?

Any particular reason the semicolons were left out of all the code samples? So far as I can tell all Standard JavaScript syntax is require semicolons to delimit a statement, right?

Using IconRef

My goal is to get an image of currently used text input. Here's my code:

ObjC.import('Carbon');
ObjC.import('Cocoa');

var currentSource = $.TISCopyCurrentKeyboardInputSource();
var iconRef = $.TISGetInputSourceProperty(currentSource, $.kTISPropertyIconRef);
var image = $.NSImage.alloc.initWithIconRef(iconRef);

However I'm getting an error "Ref has incompatible type" when I pass iconRef to initWithIconRef.

Similar code in swift works:

import Carbon
import Cocoa

let currentSource = TISCopyCurrentKeyboardInputSource()?.takeUnretainedValue()
let iconRef = OpaquePointer(TISGetInputSourceProperty(currentSource, kTISPropertyIconRef)) as IconRef
let image = NSImage(iconRef: iconRef)

screen shot 2018-12-09 at 12 19 43 am

In case of Objective-C I'd also need to cast:

TISInputSourceRef currentSource = TISCopyCurrentKeyboardInputSource();
IconRef iconRef = (IconRef)TISGetInputSourceProperty(currentSource, kTISPropertyIconRef);
NSImage *image = [[NSImage alloc] initWithIconRef:iconRef];

Is it possible that during this (IconRef) casting something going on behind the scenes? Is it possible to achieve the same with JXA?

New Section/Page Started: Using Objective C (ObjC) with JXA

Hi all. This is not an issue, but an announcement. I have started a new Wiki section/page:

Using Objective C (ObjC) with JXA

If you have any interest in this subject, please contribute to this page.

I am still a JXA novice, and definitely an ObjC novice, so I'd love to turn over leadership of this page to someone more knowledgeable than me. If you are that person, or know of someone who is, please speak out.

See the page for purpose/details.

Added navigation to wiki-pages

I hope this was a welcome change — since wiki-reversion is easy, I went with “edit first, ask questions later.”

I added a “next/previous” link to each page on the wiki to aid sequential reading:

screen shot 2017-05-02 at 3 57 14 am

GitHub Markdown isn't exactly the easiest medium to do beautiful navigation in, heh. I hope my hacky approach is amenable to y'all. <3

Using Javascript in OS X Script Editor

Perhaps this is tangential to JXA, but do we know the format / API for Yosemite Script Editor plug-ins ?

( as in Script Editor > Preferences > Plugins )

( Raw Script Editor has quite limited built-in support for JXA – no automatic reformatting, indenting, quoting – and filling these gaps with scripts yields slowish performance ... )

I haven't seen any documentation for these plug-ins ...

Any resources on CSV manipulation?

I'm trying to put together a workflow that will parse a CSV and merge that array with one returned from Configurator based on a common field. All the examples I've found use JQuery to do array merges. Is there a way to access JQuery functionality in JSA or is there another way to accomplish this?

How Do I Get Outlook 2011 Msg by ID using JXA?

Any ideas on what the JXA equivalent of this AppleScript is?

tell application "Microsoft Outlook"
  open message id 123
  activate
end tell

I've tried just about everything, but nothing works, including these:

var olApp = Application("Microsoft Outlook");
olApp.includeStandardAdditions = true;

//--- NONE of These Work ---

var oMsg = olApp.Message({id: 123});
var oMsg = olApp.message({id: 123});
var oMsg  = olApp.messages({id: 123});
var oMsg  = olApp.messages()({id: 123});

//--- This Works, but is VERY SLOW ---
var oMsg  = olApp.messages.whose({id: 123});

//-- Once I Have an Object Ref to the Msg, this should work ---
olApp.open(oMsg);

Be more detailed in the File and Folder section

It seems that we can't use the Path() object directly like this:

Path("/path/to/file").name()

I haven't found a shorter way than this to just get the name if a file/folder:

Application("System Events").aliases.byName("/path/to/file").name();

There seems to be different ways to deal with the file system. For example how to use openForAccess from the Standard additions?

There should be also a short overview of generic methods like byName or links to further documentations.

How to expose values in Script Libraries

So, the documentation is a little sparse about what is exposed when Library access a “Script Library” file:

To use scripts as libraries, store them in ~/Library/Script Libraries/.

Suppose you have a script library named toolbox.scpt, which contains the following code:

function log(message) {
    TextEdit = Application('TextEdit')
    doc = TextEdit.documents['Log.rtf']
    doc.text = message
}

So, I ran a little test on my own:

// The documented approach
function one(){                     return true }

// Identifier bindings
         two = function(){          return true }
     var three = function(){        return true }
     let four = function(){         return true }

// Explicit property creation
    this.five = function(){         return true }
;(function(){ return this })()
        .six = function(){          return true }
> ./test.sh
✓ 1. Function declaration of the global environment
✓ 2. Implicit propery of the objective global environment
✓ 3. Identifier binding on the objective global environment
✗ 4. Identifier binding on the declarative global environment
✓ 5. Explicit property of the objective global environment (via `this` self-ref)
✓ 6. Explicit property of the objective global environment (via anon func)

I suppose this should have been obvious, but I was afraid Apple was doing some jiggery-pokery on the backend, specifically and exclusively extracting only function-declarations from the global environment or something like that.

Thought this might belong in the Cookbook!

Need Help with richtext - Maybe an example?

I've searched high and low for how to do this and I can't seem to figure out how to extract presentationNotes from a Keynote presentation. I'm trying to extract all the presentationNotes and placing them into .txt file. However no matter what
document.slides[0].presentationNotes returns an object specifier so does document.slides[0].presentationNotes.words[0]
I simply cant see the notes and trying put them in a textEdit application document doesn't seem to work either.
Any help would be appreciated.

Menu Items scripting

The wiki on System Events says that menu items can't be scripted unless osascript is given Accessibility access, and recommends using tccutil.py to do this. However, as of MacOS Sierra,
tccutil.py can no longer be used to grant access without disabling SIP:

https://github.com/jacobsalmela/tccutil/issues/18

Please mention this in the wiki.

Reading/setting input language ? (Requires reading CFStringRef or casting to NSString)

Following the very helpful ObjC example at:

https://github.com/myshov/xkbswitch-macosx/blob/master/xkbswitch/main.m

and testing snippets like these in JXA:

(function () {
    'use strict';

    ObjC.import('Carbon');
    ObjC.import('stdio');

    var sourceList = $.TISCreateInputSourceList(null, false);

    var current_source = $.TISCopyCurrentKeyboardInputSource();

    var cfs = $.TISGetInputSourceProperty(current_source, $.kTISPropertyInputSourceID);
    var cfn = $.TISGetInputSourceProperty(current_source, $.kTISPropertyLocalizedName)

    var sourceCount = $.CFArrayGetCount(sourceList)

    return $.CFArrayGetValueAtIndex(sourceList, 0)
})();

One quickly hits the challenge of how to read an [object Ref] to CF objects like CFString.

Does anyone have an insight into how that can be done ?

Move this repo to an organization

I haven’t edited this book for several years now.

However, there are a lot of content now, thanks to everyone’s contribution!

I started this project when I’m still a JXA novice. I think one of the best way to solidify the knowledge is to write it down and share it with others. I don’t use JXA much anymore, so I stopped working on this. But thanks to the contributors, this project continues to grow. I am very happy that others are doing the same thing.

Now, the majority of contributions are by contributors!

Lines User %
696 @dtinth 41.6%
299 @Tatsh 17.9%
212 @ELLIOTTCABLE 12.7%
185 @RobTrew 11.1%
148 @JMichaelTX 8.9%
65 @geoff-codes 3.9%

Since I am not maintaining this project anymore and most work is done by contributors nowadays, I think it is not quite right that the project is still attributed to me, I think I should move this repo to a new organization.

If you’re a contributor and would like to take the organization forward, please let me know and I’ll make you an owner of the new org. Thanks everyone for your contributions!

TypeScript typings?

Anyone know if it's possible to automatically generate .d.ts files (i.e. TypeScript ambient typings) from the .sdef scripting definition files? That would enable method and property completion and type-checking in all TypeScript-supporting editors.

Loading other javascript modules?

Thanks for putting this wiki together, it's a nice resource as info on JS for Automation is hard to come by! You might want to add a pointer to https://github.com/tylergaw/js-osx-app-examples, which is also handy.

I was wondering if you knew of a way to load another javascript file in these scripts, like node's require(). It seems like there should be an obvious/simple way to do this, but I haven't found it yet!

How does `Application('System Events').make` work?

Hi, I'm trying to convert this existing script:

tell application "System Events"
  make login item with properties {path:"/Applications/Application.app", hidden:false"}
end tell
return

Here is what I have so far:

#!/usr/bin/env osascript -l JavaScript

'use strict';

ObjC.import('stdlib')

function run(argv) {

  var systemEvents = Application('System Events')

  systemEvents.make({
    new: 'LoginItem',
    at: systemEvents.loginItems,
    withProperties: {
      name: "Application",
      path: "/Applications/Application.app",
      hidden: false,
      kind: "Programm"
    }
  })

  $.exit(0)
}

I am stuck at this line however, as I don't actually know what to pass to the new: property, I think the other properties are correct.

    new: 'LoginItem',

I hope someone can point me in the right direction.

Root Access?

I'm trying to follow the instructions on utilizing libraries through Browserify and could use a kick in the right direction.

I have Node installed and have downloaded several packages.

I can install browserify through the normal install command, but when I try to use "npm install -g browserify" I get a message about not having root access. Is this critical to things functioning? Does the Browserify library have to be installed at a root level in order for JXA to leverage it? If so, is there a workaround to all the restrictions on that access added in El Capitan? Also, for clarity, is browserify giving you access to the NPM packages on the fly or do you have to use it to bundle the library and store a bundled version locally? Any help would be appreciated.

Side-by-side JXA/AppleScript Example(s)

There are tons of resources and existing scripts for AppleScript on the web, but not so many for JXA. It would be nice to see some examples with equivalent scripts written in both JXA and AppleScript, so that newbies could see how the languages map to one another.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.