Rose debug info
---------------

Блог {AISCRIPTS}

Рабочие заметки о скриптах для Иллюстратора
Скрипты Иллюстрации О дизайне

Честный перебор слоёв

В документации Adobe Illustrator CC Reference: JavaScript заявлено, что в конструкции app.activeDocument.layers хранятся слои документа. Авторы нигде не уточняют, что речь про слои верхнего уровня. Но в Иллюстраторе слои, как матрёшку, можно вкладывать один в другой.

Количество слоёв не совпадает с восприятием зрителя

Чтобы узнать истинное количество слоёв потребуется рекурсивная функция, то есть вызывающая сама себя.


var count = 0;

countingLayers(activeDocument.layers);
alert('True layers length: ' + count);

function countingLayers(_layers) {
  for (var i = 0; i < _layers.length; i++) {
    var iLayer = _layers[i];
    if (iLayer.layers.length > 0) { 
      countingLayers(iLayer.layers);
    }
    count++;
  }
}

Функция countingLayers() получает на входе все слои верхнего уровня. Дальше в цикле определяется, содержит ли каждый слой внутри себя другие. Если да, то функция вызывает сама себя с новым аргументом: всеми подслоями текущего.

Скрипт подсчитал слои, как видит их человек

Я использовал подобную рекурсию в RenameItems, для поиска и замены символов в именах слоёв. Также рекурсивные функции следует применять для честного перебора всех групп документа с учётом вложенных.

Баг textFrame в CC 2020 (24.3)

От версии к версии Иллюстратора разработчики добавляют новые фичи и неторопливо фиксят существующие годами баги. Неприятный сюрприз при обновлениях, когда ломается работающий инструмент. Так произошло с созданием объектов textFrame через JS. Точнее пересозданием.

Обнаружился баг на примере скрипта NumeratesPoints. Там с включенным превью скрипт создаёт textFrames, а после ввода пользователем нового числа откатывает историю и создаёт новые номера.

Изменение нумерации в реальном времени

После августовского обновления CC 2020 до версии 24.3 вдруг Иллюстратор начал постоянно вылетать с включенным превью. Комментируя отдельные куски кода, я отыскал, что проблема не во всей функции, а только в части, пересоздающей текст.

Простой тест на коротком скрипте подтвердил это. Создадим любой текстовый фрейм, откатим историю на 1 шаг и снова создадим текст — Иллюстратор 24.3 вылетит.


addText();
app.undo();
addText();

function addText() {
  var str = activeDocument.textFrames.add();
  str.textRange.characterAttributes.size = 16;
  str.contents = 'Example';
  str.top = 0;
  str.left = 0;
}

Демонстрация выполнения на CC 2019 и краша CC 2020 версии 24.3

После CC 2020 24.3 у Адоб вышел Иллюстратор CC 2021, где эта проблема исчезла. А в скрипте NumeratesPoints добавилась заплатка — отключение функции превью для пользователей версии 24.3.


var AI_VER = app.version.slice(0, 4);
if (AI_VER == '24.3') isPreview.enabled = false;

Запоздалое переименование

В свойстве name содержится имя объектов в Иллюстраторе, которое отображается в панели Layers. Чтобы переименовать выделенный объект, достаточно такой конструкции:


selection[0].name = 'квадрат';

Но нас ожидает сюрприз, новое имя не отобразится в слоях, пока мы не сбросим выделение или не выделим другой объект.

Новое имя появилось только после действия

Костыльное решение, чтобы объект оставался выделенным — после присвоения имени переоткрыть панель Layers.


app.executeMenuCommand('AdobeLayerPalette1'); // close
app.executeMenuCommand('AdobeLayerPalette1'); // open

И эти строчки можно обернуть в функцию для быстрого вызова, как я сделал в своём скрипте RenameItems.


function reopenLayersPanel() {
  app.executeMenuCommand('AdobeLayerPalette1'); // close
  app.executeMenuCommand('AdobeLayerPalette1'); // open
}

Новое имя у выделенного объекта сразу появилось в панели Layers