0

I have difficulty using JavaScript in ScriptEditor

AppleScript copy image to clipboard by path like this

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

But how to translate above AppleScript code to JavaScript?

JavaScript like this can copy string to clipboard but not image 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);
l00
  • 1

2 Answers2

2

This uses the JS-ObjC bridge to put one or more files onto the clipboard. fsCopy can be passed a single file path or an array of file paths, and returns the number of items on the clipboard after the operation completes (obviously, this should equal the number of file paths).

ObjC.import('AppKit');


function fsCopy(fs) {
    const pb = $.NSPasteboard.generalPasteboard;
    pb.clearContents;

    [].concat(fs).forEach(f => 
        pb.writeObjects([
            ObjC.unwrap($.NSURL
            .fileURLWithPath(f))
        ])
    );

    return pb.pasteboardItems.count * 1;
}
CJK
  • 5,732
  • 1
  • 8
  • 26
0

Simplifying CJK's answer slightly:

// makes Cocoa NS* classes available under $
ObjC.import('AppKit'); // same as ObjC.import('Cocoa');

// necessary to get correct result, but I'm not sure why
$.NSPasteboard.generalPasteboard.clearContents;

// create a Cocoa URL for the file system item
const nsUrl = $.NSURL.fileURLWithPath('/Users/lll00lll/Library/Documents/temp.jpg');

// set the pasteboard to the URL
// .js unwraps the NSUrl reference for use in Obj-C
$.NSPasteboard.generalPasteboard.writeObjects([nsUrl.js]);

Explaination

In the original question, the AppleScript snippet sets the clipboard to a URL for the file. The JSX snippet sets the clipboard to a UTF string. I tried using the JSX Path() type, but it sets the clipboard to a nonsense flavor.

This answer manually creates a Cocoa URL and sets the pasteboard to that.

The writeObjects() method will also accept NSImage, so you can pass an image in memory (though it's slower than passing a reference to a file):

const nsImage = $.NSImage.alloc.initByReferencingFile('/Users/lll00lll/Library/Documents/temp.jpg');
$.NSPasteboard.generalPasteboard.writeObjects([nsImage.js]);
Mat Gessel
  • 562
  • 8
  • 17
  • That’s not a simplification of my code. We use the same three lines to clear the contents, form the `NSURL` and unwrap it, then write to the pasteboard. The extra lines in my code are because the content you’ve isolated is housed inside a function that iterates over multiple paths and append these to the pasteboard. Having stripped out actual functional aspects of code, you haven’t simplified it, but rather shown what happens in the situation of a single file path. – CJK Dec 08 '20 at 08:17