ExtendScript / extendscriptr

An NPM command line tool to compile modern javascript (es5 & es6) into executable extendscript (es3)
Do What The F*ck You Want To Public License
153 stars 15 forks source link

What is the best way to deal with array-like, but not true Array collections in Illustrator #64

Closed gotnone closed 3 years ago

gotnone commented 3 years ago

I would like to use the forEach() function on app.activeDocument.pageItems, but it is not a proper Array. I tried to get around this by using Array.from(app.activeDocument.pageItems), but this does not appear to be an available function. I was successful using [].concat(app.activeDocument.pageItems). Is this the most efficient way to make pageItems into an Array? Is there a way to use forEach() with the non-Array, but array like collections in Illustrator?

Perhaps there should be a warning about these array like collections in the readme.

ff6347 commented 3 years ago

I don't think you can use these functions with collections and illustrator. But the built-in Extendscriot engine has some nice features for collections like everyItem or lastItem. At least I know them from InDesign.  Take a look at the documentation for that.

About the notice that for each doesn't work, we accept pull requests. 😉

gotnone commented 3 years ago

Maybe I am missing something, but I don't believe that Illustrator supports everyItem for collections as InDesign does. I have always written old fashioned for(var i=0, i<collection.length; i++) { manipulateCollection(collection[i]); } loops.

I noticed that attempts to use the array spread shim on the Artboards collection in Illustrator fails because it falls through all of the checks in _toConsumableArray(). However, Artboards and other collections in Illustrator can satisfy all the "duck-type" requirements to be consumed by the _arrayLikeToArray(arr) function. What negative impact would there be if a new predicate were appended to the _toConsumableArray() checks as follows:

function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _duckTypeArray(arr) || _nonIterableSpread(); }

function _duckTypeArray(duck) { if(typeof duck.length === "number" && typeof duck[0] !== "undefined") return _arrayLikeToArray(duck); }

Are there other types of javascript object that are able to satisfy these duck requirements, but explode when passed to _arrayLikeToArray()?

ff6347 commented 3 years ago

hi @gotnone sorry that I can't help. I'm actually not getting the context of your question and I stopped doing Adobe Scripting for already quite some time. The simplest answer I have is "ExtendScript is like writing JS in 1999 and it is annoying" I think your question should be asked in the Adobe Scripting Forums. You will find a lot of helpful and savvy people over there.

gotnone commented 3 years ago

To clarify a little bit, if I understand correctly, _toConsumableArray is a shim that is inserted by babel (@babel/runtime/helpers/toConsumableArray.js) when the array spread operator is used, and probably in some other cases when using extendscriptr. This function does not handle the ExtendScript array like collections, yet, because they fail the predicate in all of the currently implemented conversion functions. I believe that it is possible to create a new conversion function which will work with the array like collections (or at least make copies as true Array objects let myartboards = [...app.activeDocument.artboards];).

If I want to modify this babel shim to include this new function and to add it to the list of conversion functions in the _toConsumableArray shim , is it best to ask upstream at babel? Or, do you know if there is there a way to do so within the extendscriptr or extendscript-es5-shim framework?

ff6347 commented 3 years ago

You could fork extendscriptr and modify your fork as you like

gotnone commented 3 years ago

I believe that babel upstream may be the better avenue for getting a solution. Thanks for looking into this.