1

I have Photoshop CC2019 PSD document containing several smart objects that contains other smart objects that contains other smart objects. Some of these have linked layers. Normally, such images are not updated automatically (which is extremely annoying, Adobe!) but you have to manually update each of them once the linked image content has changed.

There is a .jsx script file named "Update All Modified Content.jsx" which auto-updates linked layers (PNG image in my case) but only if the smart object is in the top most document - that is no nested smart objects with linked layers are updated automatically.

My question is: does anyone know how to update the content of the above mentioned .jsx file so that it would auto-update all linked images across all the smart objects in PSD document including nested ones?

For those who care or would be willing to help updating the code here it is:

// Update all modified content
var idplacedLayerUpdateAllModified = stringIDToTypeID( "placedLayerUpdateAllModified" );
executeAction( idplacedLayerUpdateAllModified, undefined, DialogModes.NO );

1 Answer 1

1

So, after spending half a day with it I finally solved it myself. Here is the code:

#target photoshop

// SET INITIAL ACTIVE DOCUMENT
var mainDocument = app.activeDocument;

// SAVE THE DOCUMENT NAME FOR FUTURE USE
var mainDocName = mainDocument.name;

// RUN THE MAIN UPDATE FUNCTION
mainDocument.suspendHistory("processAllSmartObjects", "autoupdateAllSmartObjects(mainDocument, 0)");

// FINALLY SAVE THE MAIN DOCUMENT
mainDocument.save();

function autoupdateAllSmartObjects(theParent, prevVal) {

    // FUNCTION TO TEST IF SMARTOBJECT IS LINKED
    function isLinkedSO(obj) {

        var localFilePath = "";
        var ref = new ActionReference();
        ref.putIdentifier(charIDToTypeID('Lyr '), obj.id);
        var desc = executeActionGet(ref);
        var smObj = desc.getObjectValue(stringIDToTypeID('smartObject'));  
        var isLinked = false;

        // TEST IF IT HAS LINKED FILE
        try {
            var localFilePath = smObj.getPath(stringIDToTypeID('link'));
            isLinked = true;

        } catch(e) {
            //
        }

        return isLinked; 
    }

    // FUNCTION TO UPDATE LINKED SMART OBJECT 
    function doTheUpdate(LYR, stackNr) {

        // SET ACTIVE LAYER TO ACTUALY ITERATED ONE
        app.activeDocument.activeLayer = LYR;

        // RUN IN "SILENT" MODE
        app.displayDialogs = DialogModes.NO;
        var layer = app.activeDocument.activeLayer;

        // IF ACTIVE LAYER IS SMARTOBJECT
        if (layer.kind == "LayerKind.SMARTOBJECT") {

            //alert(layer);

            // OPEN THE SMARTOBJECT
            app.runMenuItem(stringIDToTypeID('placedLayerEditContents'));

            // DO THE ACTUAL FILE UPDATE
            var idplacedLayerUpdateAllModified = stringIDToTypeID( "placedLayerUpdateAllModified" );
            executeAction( idplacedLayerUpdateAllModified, undefined, DialogModes.NO);

            // IF IT IS NOT THE "CORE/MAIN" DOCUMENT
            if(stackNr > 0) {

                // SAVE CHANGES (UPDATE) AND CLOSE IT
                app.activeDocument.close(SaveOptions.SAVECHANGES);
            }

            // CONTINUE INSIDE THIS ACTIVE SMARTOBJECT
            autoupdateAllSmartObjects(app.activeDocument, stackNr);
        }

        return;
    }

    // FUNCTION TO PARSE GROUPS
    function parseGroup(LYR) {

        var groupLayers = LYR.layers;

        // IF GROUP IS NOT EMPTY
        if(groupLayers.length > 0) {

            // PARSE ALL LAYERS IN THE GROUP
            for (var i = groupLayers.length - 1; i >= 0; i--) {

                var lyr = groupLayers[i];

                // IF NOT LOCKED = NOT EDITABL:E
                if(!lyr.allLocked) {

                    // YET ANOTHER GROUP?
                    if (lyr.typename == "LayerSet") {

                        // IF IT IS NOT EMPTY
                        if (lyr.layers.length > 0) {

                            // RE-RUN THE SCRIPT ANEW WITH THE SELECTED GROUP AS LAYERS SOURCE
                            autoupdateAllSmartObjects(lyr, 0);
                        }

                    // LAYERS
                    } else if (lyr.typename == "ArtLayer") {

                        // IF THE LAYER IS SMARTOBJECT
                        if (lyr.kind == LayerKind.SMARTOBJECT) {

                            // IF THE LAYER IS SET TO "visible" (THAT IS: NOT DISABLED)
                            if(lyr.visible){

                                // TEST IF THE SMARTOBJECT IS ACTUALLY LINKED
                                if(!isLinkedSO(lyr)) {

                                    // RUN THE UPDATE SUB-FUNCTION
                                    doTheUpdate(lyr, i);
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    // PARSE ALL THE LAYERS
    for (var i = theParent.layers.length - 1 - prevVal; i >= 0; i--) {

        var theLayer = theParent.layers[i];

        // ONLY ArtLayers
        if (theLayer.typename == "ArtLayer") {

            // IF THE LAYER IS SMARTOBJECT
            if (theLayer.kind == LayerKind.SMARTOBJECT) {

                // IF THE LAYER IS SET TO "visible" (THAT IS: NOT DISABLED)
                if(theLayer.visible){

                    // TEST IF THE SMARTOBJECT IS ACTUALLY LINKED
                    if(!isLinkedSO(theLayer)){

                        // RUN THE UPDATE SUB-FUNCTION
                        doTheUpdate(theLayer, i);

                        // IF WE ARE AT THE LAST LAYER IN THE STACK AND IT IS NOT OUR MAIN DOCUMENT
                        if(i == 0 && app.activeDocument.name !== mainDocName) {

                            // SAVE CHANGES (UPDATE) AND CLOSE IT
                            app.activeDocument.close(SaveOptions.SAVECHANGES);
                        }
                    }
                }
            }

        // ONLY Groups
        } else if (theLayer.typename == "LayerSet") {

            // RUN SUB-FUNCTION FOR GROUP PARSING
            parseGroup(theLayer);

        // ANYTHING ELSE
        } else {

            autoupdateAllSmartObjects(theLayer, m);
        }
    }

    return;
};

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.