Scripting question: How to alter row text while keeping formatting?

It is, but other standard methods such as insert or splice don’t seem to work… at least I can’t seem to make them work.

So, then magic? :sparkles:

1 Like

The problem is that those references (despite some pre-processor syntactic sugar which aims to achieve some array-like syntax) are not really JS Array objects.

(They’re actually OSA API function references)

( presumably someone decided to implement unshift for them, in addition to push, which despite appearances, is not actually JS’s Array.push method )

I noticed attributesRun property of textContent returned an array, and I had the feeling that, in order to prepend elements to that array, I could try .unshift method. A feeling, I think.

Not quite, ironically :slight_smile:

    return typeof (
        row
        .textContent
        .attributeRuns
    );

   // → function

while …

 return (
        row
        .textContent
        .attributeRuns
    ).toString();

  // → [object ArraySpecifier]

ArraySpecifier is a class which Apple wrote for the JXA interface, deliberately making it look a bit like a JS Array, with [n] preprocessed to the new class’s own .at(n) method, and a "push" intended to remind us of Array.push, though it actually does something rather different (introduces a new member to a non-array OSA collection structure)

Ditto "unshift", which they don’t seem to have documented, but you have very helpfully discovered for us :slight_smile:

1 Like

PS, if you try this:

(() => {
    "use strict";

    const
        bike = Application("bike"),
        doc = bike.documents.at(0),
        row = doc.rows.at(0),
        attributeRun = bike.AttributeRun({
            bold: true
        }, "additional text ");

    return Automation.getDisplayString(
        row
        .textContent
        .attributeRuns
    );
})();

You will harvest:

Application("Bike")
.documents.at(0).rows.at(0).textContent.attributeRuns

which reveals that although the preprocessor will accept forms like:

Application("Bike")
.documents[0].rows[0].textContent.attributeRuns

from the user, to give the impression that documents, rows etc are arrays, on grounds of familiarity or ease of use,

they are not actually JS Arrays beneath the hood, and lack nearly all of JS Array’s methods and properties (though they do implement a .length property)


Note that you can obtain a genuine Array as a result of calling the .attributeRuns function ( adding () to get a function call expression .attributeRuns()

but using the real Array.push on that resulting array won’t add a new attribute run to the underlying OSA collection.

Array.push and ArraySpecifier.push are two quite different beasts.

1 Like

Yes, of course ! Because it’s necessary to use trailing parenthesis to obtain the actual value; as you clarified below. I mean, it’s really a method instead of a property.

Thank you for the info about ArraySpecifier class. Very useful !


PS: Methods are indeed properties. It’s just that functions are stored there, instead of saturated values.

1 Like