Skip to main content
benl13565393
Inspiring
February 21, 2018
Answered

Multiple timelines detected in JSFL

  • February 21, 2018
  • 3 replies
  • 1374 views

I have a JSFL script that I wrote to convert Graphic types back to MovieClips. I want to run it on main timeline. What I have found is a call to

document.getTimeline()

or

document.currentTimeline

is dependent upon the current timeline the current document is in. So, for example, if you are in the timeline of a symbol, it will be using that timeline.

As I want this applied to the whole file, I need to access the main timeline.

var dom = fl.getDocumentDOM()

var timelines = dom.timelines

for (t in timelines) {

  fl.trace("TIMELINE " + timelines.name + " " + timelines.libraryItem)

}

I used this code as a test. The results yielded:

TIMELINE LevelUpPopup-0 null

TIMELINE LevelUpPopup-0 null

It appears they are identical (I checked the layers but have omitted for brevity here).

I'm curious if anyone knows why there are two identical timelines showing up. Note that they both are showing the scene name. And the null for the libraryItem is supposed to indicate it is the scene as well.

This topic has been closed for replies.
Correct answer ClayUUID

You're using for...in to iterate over an array, which is, basically, wrong.

This sample code from the Extending Adobe Flash Professional documentation works as expected, returning only one result:

var i = 0;

var curTimelines = fl.getDocumentDOM().timelines;

while (i < fl.getDocumentDOM().timelines.length) {

    alert(curTimelines.name);

    ++i;

}

So no, it's not a bug.

3 replies

ClayUUIDCorrect answer
Legend
February 21, 2018

You're using for...in to iterate over an array, which is, basically, wrong.

This sample code from the Extending Adobe Flash Professional documentation works as expected, returning only one result:

var i = 0;

var curTimelines = fl.getDocumentDOM().timelines;

while (i < fl.getDocumentDOM().timelines.length) {

    alert(curTimelines.name);

    ++i;

}

So no, it's not a bug.

benl13565393
Inspiring
February 21, 2018

This is super helpful and obviously my bad. The curse of flipping between Python and JSFL.

I swore I did a fl.trace(dom.timelines.length), but clearly not as it yields the expect value 1.

Thanks for pointing this error out!

benl13565393
Inspiring
February 21, 2018

I also filed a bug with Adobe in regards to this. Unless someone has a real explanation, this seems like a bug in the JSFL.

JoãoCésar17023019
Community Expert
Community Expert
February 21, 2018

Hi.

It's because this 'timelines' property returns all scenes you have in your document. If you want the timeline from symbols, you have to get it from each element in your document.

Based on a function I wrote some time ago to get all symbols from the current scene, I rewrote the function and used it to create a function that convert all symbols, from all timelines, to a specific element type:

Convert Symbols JSFL code:

function convertSymbols(from, to)

{

    var array = getAllSymbolsFromAllTimelines();

   

    if (!array)

        return;

   

    for (var i = 0, total = array.length; i < total; i++)

    {

        for (var j = 0, total2 = array.length; j < total2; j++)

        {

            if (array.symbolType == from)

                array.symbolType = to;

        }

    }

}

function getAllSymbolsFromAllTimelines()

{

    var doc = fl.getDocumentDOM();

   

    if (!doc)

    {

        fl.trace("You must have a document opened.");

        return;

    }

   

    var timelines = doc.timelines;

    var array = [];

   

    for (var i = 0, total = timelines.length; i < total; i++)

        array = getAllTimelineSymbols(timelines);       

   

    return array;

}

function getAllTimelineSymbols(timeline)

{

    var array = [];

    var count = 0;

   

    getAllTimelineSymbols2(timeline);

   

    function getAllTimelineSymbols2(timeline)

    {

        for (var i = 0, total = timeline.layers.length; i < total; i++)

        {           

            for (var j = 0, total2 = timeline.layers.frames.length; j < total2; j += timeline.layers.frames.startFrame + timeline.layers.frames.duration)

            {

                for (var k = 0, total3 = timeline.layers.frames.elements.length; k < total3; k++)

                {

                    var element = timeline.layers.frames.elements;

                    count++;                   

                   

                    if (element.instanceType == "symbol")

                    {

                        array.push(element);

                        getAllTimelineSymbols2(element.libraryItem.timeline);

                    }                   

                    else

                        continue;

                }           

            }

        }   

    }

   

    return array;

}

convertSymbols("movie clip", "graphic");

Convert Symbols JSFL download:

https://goo.gl/LY2WA5

I hope it helps.

Regards,

JC

benl13565393
Inspiring
February 21, 2018

JC,

Thanks for your response. The confusing item here is there is only one scene. And if you look at the output above, the timeline name is identical. And if I go to the Scene Panel, there is only one scene. For some reason, there are 2 timelines showing up

Some of the files can take a bit of time to work through, so I'd rather not traverse the same scene timeline twice.

Also thanks for the code. I'm doing something similar but I'm doing it "in place". I use a dictionary to determine if it has been done or not.

So my recursion looks like this.

if (!(symbol.name in symbolsDone)) {

  if (symbol.itemType == 'undefined' ||

  symbol.itemType == 'component' ||

  symbol.itemType == 'folder' ||

  symbol.itemType == 'font' ||

  symbol.itemType == 'sound' ||

  symbol.itemType == 'bitmap' ||

  symbol.itemType == 'compiled clip' ||

  symbol.itemType == 'screen' ||

  symbol.itemType == 'video') {

  fl.trace("WARNING: symbol " + symbol.name + " (layer: " + layer.name + ", frame: " + f + ") is unsupported itemType " + symbol.itemType)

  } else {

  symbolsDone[symbol.name] = true

  count += convertToType(symbol.timeline, type, symbolsDone, ignoredSymbols)

  }

}

In my case, I've chosen to flag certain types as warnings to look at.

JoãoCésar17023019
Community Expert
Community Expert
February 21, 2018

Clay is right!