Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[suggestion] Support for JavaScript Environments: Adobe ExtendScript #28353

Closed
alexsasharegan opened this issue Jun 9, 2017 · 15 comments
Closed
Assignees
Labels
*extension-candidate Issue identified as good extension implementation feature-request Request for new features or functionality javascript JavaScript support issues

Comments

@alexsasharegan
Copy link

Per my conversion with vscode on twitter, I'll like to drop a request for/start a conversation around language support for Adobe ExtendScript.

The print industry (where I work) is incorporating more tech & automation, which often means scripting Adobe products like InDesign, Illustrator, & Photoshop. There is a dirth of support & tooling for Adobe's archaic version of javascript, ExtendScript, both from the community & Adobe itself. Right off the bat, their preferred .jsx extension gets confused with React/JSX.

Currently, the largest body of open source development in this space seems to be centered around this github org: https://github.com/ExtendScript/. Notable contributions from users like Fabian Morón Zirfas & bastienEichenberger.

As someone just starting to dive in, I find Adobe's stock resources very difficult to consume. I've been hoping for a collection of official TypeScript typings for each environment so I could have intellisense autocompletion around the different environment globals and insight into the native object types. It's also very hard to go from writing esNEXT to the ExtendScript base of es3.

Does vscode have any language facilities for upgrading/downgrading a project/code window's referenced version of javascript? In other words, on a vscode window by window basis, can one switch from es2015 to es3? Or switch /.jsx?$/ environments from browser (ECMAscript), to server (Node), to some other document type (Adobe ExtendScript, Google Docs scripting, etc.)?

In my opinion, Adobe needs to take the first steps towards enabling good DX and modern tooling. Perhaps issues like this & toolmakers like Microsoft can inspire some conversation or even break contact with Adobe?

TL;DR;

  • Adobe ExtendScript is ancient. It's based on es3 and has entirely different globals
  • Can vscode do anything to make the ExtendScript authoring experience better?
    • Language environment switching for language version & env globals
    • TypeScript typings for intellisense
    • .jsx grammar (not React-style JSX)
  • Shot in the dark: can Microsoft use their voice to push Adobe to improve their automation tooling?
@mjbvz mjbvz self-assigned this Jun 9, 2017
@mjbvz
Copy link
Collaborator

mjbvz commented Jun 9, 2017

I'm not familiar with ExtendScript but I believe that we may already offer some functionality to support this. It sounds like there's also an opportunity for an ExtendScript extension for vscode.

How different is ExtendScript syntax from normal es3? If they are compatible, TypeScript should be able to provide intellisense for ExtendScript. If they are no compatible, unfortunately you'll probable have to write a custom language server that understands ExtendScript

For working with es3 code, TypeScript currently doesn't include typing definitions for the es3 standard library but there's an issue tracking this microsoft/TypeScript#2410 and a PR to add one: microsoft/TypeScript#16077 You can disable the standard es6 based suggestions by creating a jsconfig.json in the root of your project with the contents:

{
    "compilerOptions": {
        "target": "es3",
        "lib": []
    }
}

You can also include additional typings in your workspace using typeAcquision:

{
    "compilerOptions": {
        "target": "es3",
        "lib": []
    },
    "typeAcquisition": {
        "include": [
            "node"
        ]
    }
}

These typings come from definitely typed. If an es3 library d.ts exists, you should be able to include it using typeAcquisition.

You can also author your own d.ts files to improve intellisense for working with Adobe APIs: https://blogs.msdn.microsoft.com/typescript/2016/12/14/writing-dts-files-for-types/

@alexsasharegan
Copy link
Author

My familiarity with ExtendScript is basically nil. I usually deal with es6, but I'm starting to work more closely with our company's adobe automation developer. I'm quickly learning that most of the language features I use on a daily basis are gone. The environment globals are very different. Found some good community documentation here: http://javascript-tools-guide.readthedocs.io/en/latest/index.html

I will definitely take a look at the guide to authoring d.ts files (something I've been curious to get more into anyways), and I'll see how far I can get with understanding the language service in vscode. Do you have any links for starting down that path?

@mjbvz
Copy link
Collaborator

mjbvz commented Jun 9, 2017

Yes, try seeing if the existing JS tooling will work with ExtendScript first. d.ts files and the right project configuration may provide most of what you are after. Writing a language server would be a pretty major investment and hopefully will not be necessary.

If ExtendScript augments JavaScript or just uses JavaScript patterns that our current tooling does not understand, you can also try looking into writing a typescript language service plugin: https://github.com/Microsoft/TypeScript/wiki/Writing-a-Language-Service-Plugin

Here's our documentation on creating a language server: https://code.visualstudio.com/docs/extensions/example-language-server Before starting down this path, please let me know what problems you run into with our existing JavaScript support though

@mjbvz mjbvz added *extension-candidate Issue identified as good extension implementation feature-request Request for new features or functionality javascript JavaScript support issues labels Jun 12, 2017
@ericdrobinson
Copy link

ericdrobinson commented Jun 26, 2017

ExtendScript is basically ECMAScript 3rd Edition + API Extensions. See (emphasis mine):

Adobe provides an extended implementation of JavaScript, called ExtendScript, that is used by many Adobe applications that provide a scripting interface. In addition to implementing the JavaScript language according to the ECMA JavaScript specification, ExtendScript provides certain additional features and utilities.

As such, VSCode (powered by TypeScript) is almost capable of handling the language with a few configuration changes. In fact, due to the nature of how TypeScript works with tsconfig.json files, you can set up an Adobe CEP Extension environment within a single VSCode project window. Let's tackle what's needed:

JSX Files Should Be Treated As JavaScript

This one's pretty easy. You can override the setting for .jsx files in the VSCode settings.json. See here for information on how to do this.

Core JavaScript API Support

While ExtendScript is based on ECMAScript 3, it is possible to "approximate" the experience by using the ECMAScript 5 typings. You'll get "type resolution" for a few APIs that wouldn't be supported. Unfortunately, at time of writing, the es5 typings are actually polluted with some typings from es6. While this will hopefully be addressed sometime in the near future, you should get the vast majority of what you need with the base es5 typings. To do that, you provide a tsconfig.json with the following settings:

{
    "compilerOptions": {
        "lib": [         // Specifying "lib" overwrites defaults (stops import of HTML DOM stuff).
            "es5"
        ],
        "target": "es3"  // In case TypeScript is used, this will compile to ECMAScript 3 (ExtendScript!) compatible code.
    }
}

Core ExtendScript API Support

This effectively requires a lib.extendscript.d.ts file. I have an active request with Adobe for them to support this directly as it would be extremely helpful. In the meanwhile, it is not difficult to create your own typings file by using the ExtendScript Toolkit's Object Model Viewer to get copy-pastable documentation for the ExtendScript APIs. I have done this with the base Helper class, myself, and it works great.

Adobe Application API Support

Each Adobe Application also provides its own Application-specific ExtendScript APIs. They have varying degrees of documentation, mainly provided through samples, though some provide other resources (e.g. Premiere Pro).

Here again I have an active request with Adobe for them to support this directly. Some documentation appears to be included with the ExtendScript Toolkit Object Model Viewer, but it tends to be incomplete. Support for files like PremierePro.2015.d.ts, PremierePro.2017.d.ts, AfterEffects.2017.d.ts, AfterEffects.2017.1.d.ts etc. would be very welcome, but would best come from Adobe as certain APIs are simply undocumented outside of that company.

A Single Environment In VSCode That Supports CEP Development

Provided you have a "root" folder for each JavaScript context your CEP project, you can add "root"-specific tsconfig.json files to specify how you want the JavaScript types to be matched. This means that you can support the ExtendScript DOM in the same project as the HTML DOM used by the panel interface. To do this you would add one folder for each context, say: dom_app for ExtendScript and dom_html for the Panel. In dom_app/tsconfig.json you would add the settings shown above. For the dom_html/tsconfig.json, you would add settings akin to the following:

{
    "compilerOptions": {
        "lib": [        // This could probably be left out, but this way you can specify supported features.
            "dom",
            "es5",
            "es2015.promise"
        ],
       "target": "es5"  // Chrome 41 supports much of ECMAScript 5. However, this may need to be changed to ES3 to be safe.
    }
}

The "Chrome 41" note is related to the fact that recent versions of CEP (6.1 and 7.0) are based on nw.js 0.12.1, which incorporated a version of the Chromium Embedded Framework that equates to Chrome 41.

TL;DR

Quick responses to your [non MS-specific] bullet-list items:

Adobe ExtendScript is ancient. It's based on es3 and has entirely different globals

ExtendScript has additional globals. Everything defined in the ECMA-262, 3rd Edition Standard is also available in ExtendScript. The DOM is what differs - it's not the HTML DOM but the ExtendScript DOM.

Language environment switching for language version & env globals

Yes. This is outlined in detail above, but the basics are: set up a tsconfig.json file to only use the es5 typings (or [future] es3) and specify your own (or [future?] Adobe-provided) ExtendScript typings.

TypeScript typings for intellisense

This would be best handled by Adobe, but you could get a good deal of it done on your own with the help of the ExtendScript Toolkit's Object Model Viewer to provide the necessary documentation rundown.

.jsx grammar (not React-style JSX)

There are two additions to the ECMAScript 3 grammar:

  1. Preprocessor Directives - There are functional workarounds for all three defined directives.
  2. Operator Overloads - The syntax for this aligns with standard ECMAScript 3 syntax and therefore "just works".

Beyond these additions, ExtendScript grammar/syntax is ECMAScript 3 grammar/syntax. As a result, you can just overwrite the default .jsx extension's language assignment in your project.

In summation, a good deal of what you're looking for is already doable with a bit of setup!

@alexsasharegan
Copy link
Author

Thank you so much, @ericdrobinson!!! 🎉 🎉 🎉 I'm helping my company's Adobe automation developer with his work, so I'm a bit of a middle-man here. I've been getting into using TypeScript more lately since I switched to using vscode (and code makes using TS a breeze).

There are a lot of really big config wins laid out here! I will check out the OMV (and that doc page you referenced was a huge help for me the other week—Adobe's docs are not easily digested).

I would be supremely excited if Adobe released official typings of their scripting API's!!! Where can I put my ear to the ground for news on that?

@ericdrobinson
Copy link

I would be supremely excited if Adobe released official typings of their scripting API's!!! Where can I put my ear to the ground for news on that?

Honestly, I'm not 100% sure. I have a meeting with someone at Adobe about this very thing later today. I'll ask after this and see where the best place to get updates would be.

I've been getting into using TypeScript more lately since I switched to using vscode (and code makes using TS a breeze).

It sure does! If you're using TypeScript in your Adobe CEP projects, the more complete tsconfig.json files would look more like the following:

dom_app/tsconfig.json:

{
    "compilerOptions": {
        "allowJs": true,            // Allows JavaScript files to be compiled.
        "lib": [                    // Specifying "lib" overwrites defaults (stops import of HTML DOM stuff).
            "es5"
        ],
        "strict": true,             // Shorthand for the following four options:
        // "noImplicitAny": true,
        // "noImplicitThis": true,
        // "alwaysStrict": true,
        // "strictNullChecks": true,
        "target": "es3"             // In case TypeScript is used, this will compile to ECMAScript 3 (ExtendScript!) compatible code.
    }
}

dom_html/tsconfig.json:

{
    "compilerOptions": {
        "allowJs": true,            // Allows JavaScript files to be compiled.
        "lib": [                    // This could probably be left out, but this way you can specify supported features.
            "dom",
            "es5",
            "es2015.promise"
        ],
        "strict": true,             // Shorthand for the following four options:
        // "noImplicitAny": true,
        // "noImplicitThis": true,
        // "alwaysStrict": true,
        // "strictNullChecks": true,
        "target": "es5"             // Chrome 41 supports much of ECMAScript 5. However, this may need to be changed to ES3 to be safe.
    }
}

In addition, if you have certain scripts that you would like to use in both contexts, you can add a third root directory called shared that sits next to dom_app and dom_html. You would place your .js or .ts files in there and add the following to both tsconfig.json files:

{
    "compilerOptions": {
        // ...
    },
    "include": [                    // Custom include to get the shared folder.
        "./**/*",
        "../shared/**/*"
    ]
}

This is useful if you have some useful utility functions that you like to use everywhere.

Note that you will probably want to add a separate tsconfig.json file to the shared directory with the "lowest common denominator" of typings supported (read: es3 or es5). When actually compiling your shared TypeScript, the output generated for each "context" will match that specified in the tsconfig.json for that context (ExtendScript context would get compiled to ES3, HTML context would get compiled to ES5 [with the above settings]). TypeScript really is neat.

@ericdrobinson
Copy link

Oh. I should also point out that there's nothing-at-all sacred about the .jsx extension with ExtendScript. Adobe applications will happily load your scripts with whatever extension you give them, including .js. If that's easier than setting up the custom file association (or you use JavaScript React in your project), then you can simply name your ExtendScript files *.jsx or even something like *.es/*.esx.

@alexsasharegan
Copy link
Author

I hope some good news comes out of that meeting! Tech is invading the world of print, so it's only a matter of time before voices like mine increase in volume (both in numbers and decibels).

And I'm already using the plain .js extension (syntax highlighting and autocompletion is important!). I really like the idea of writing TS files with an es3 target though. I've been mentally attempting to keep track of all the polyfills I need when helping out with the scripting (as a newer developer, I'm a heavy user of es6 and beyond via build tooling).

@ericdrobinson
Copy link

I'm a heavy user of es6 and beyond via build tooling

If you're using Webpack, take a look at this post in the Adobe forums. Polyfills can really sneak up on you pretty easily with modern tooling!

@alexsasharegan
Copy link
Author

Interesting. I've only used Webpack in a dev-for-web context, so I can see how I haven't run into this yet. This is a great heads up!

@ericdrobinson
Copy link

I've only used Webpack in a dev-for-web context

Adobe CEP extension development effectively is web development. You just have a fixed browser target (Chrome 41 equivalent for recent versions).

@ericdrobinson
Copy link

I hope some good news comes out of that meeting! Tech is invading the world of print, so it's only a matter of time before voices like mine increase in volume (both in numbers and decibels).

The meeting went very well. They seem really interested in what TypeScript-enabled environments like VSCode can do for users working on extensions. To that end, they're even open to pull requests and it sounds as though they're interested in helping improve a base set of declaration files.

To be clear: I showed them an environment we'd set up with the hopes that they would be interested in supporting it as its already proven to be extremely powerful/helpful, incomplete though it may be and they responded with "We'd be happy to help! Want to add it to the repo?"

I only just issued the Pull Request so it may be a little premature to celebrate, but I am cautiously optimistic.

Either way, some of those type declaration files and the project setup in the public Pull Request will probably be useful to someone ;)

@ericdrobinson
Copy link

That was fast... the PR was accepted and is now part of the CEP/Samples repository. Hopefully things will continue to improve along these lines!

@alexsasharegan
Copy link
Author

This is awesome news! You're quite a few steps ahead of me with regards to development on the Adobe platform, but a base set of declaration files would really pave the way for developers like me to build. It's the ability to intelligently hack away versus laboriously study docs & slowly write code—and that difference is huge to me.

@mjbvz
Copy link
Collaborator

mjbvz commented Nov 3, 2017

Closing this out since support can be provided by an extension and would not be included in core VS Code

@mjbvz mjbvz closed this as completed Nov 3, 2017
@vscodebot vscodebot bot locked and limited conversation to collaborators Dec 18, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
*extension-candidate Issue identified as good extension implementation feature-request Request for new features or functionality javascript JavaScript support issues
Projects
None yet
Development

No branches or pull requests

3 participants