3 Replies Latest reply on Jun 22, 2017 9:25 PM by Laubender

    Script causes InDesign CC to crash

    simonvg

      Hi - I'm learning javascript from 'InDesign CS5 Automation Using XML & Javascript'. Some of the tutorial scripts work fine in my old version of InDesign CS5.5, but not in CC. The following script works fine in CS5.5 but causes InDesign CC to crash. Can anyone tell me why this happens? Thanks!

       

      #targetengine "session"

      var g = {};

      main();

       

      function main(){

          if(app.documents.length == 0){

              alert('Please open a document');

              }

          else{

              loadPageItems();

              buildDialog();

              updateListbox();

              }

          }

       

      function loadPageItems(){

          displayProgressBar();

          docPageItemsList();

          masterPageItemsList();

         

          function displayProgressBar(){

              g.doc = app.activeDocument;

              g.winProg = new Window('palette', undefined, undefined, {closeButton:false});

              g.winProg.prg = g.winProg.add('progressbar', [0,0,400,20]);

              g.winProg.add('statictext', [100,30,300,50], 'Updating list of page items');

              var numItems = g.doc.pageItems.length;

              g.winProg.prg.value = 0;

              g.winProg.prg.maxvalue = numItems;

              g.winProg.show();

              }

         

          function docPageItemsList(){

              g.arrPageItems = [];

              for (var i = 0; i<g.doc.pages.length; i++){

                  var currentPage = g.doc.pages.item(i);

                  for(var j=0; j < currentPage.pageItems.length; j++){

                      var currentPageItem = currentPage.pageItems.item(j).getElements()[0];

                      g.arrPageItems.push(currentPageItem);

                      g.winProg.prg.value++;

                      }

                  }

              }

          function masterPageItemsList(){

              for (var i=0; i<g.doc.masterSpreads.length; i++){

                  var currentMaster = g.doc.masterSpreads[i];

                  for (var j=0; j<currentMaster.pages.length; j++){

                      var currentPage = currentMaster.pages.item(j);

                      for (var k = 0; k<currentPage.pageItems.length; k++){

                          var currentPageItem = currentPage.pageItems.item(k).getElements()[0];

                          g.arrPageItems.push(currentPageItem);

                          g.winProg.prg.value++;

                          }

                      }

                  }

                  g.winProg.prg.value = 0;

                  g.winProg.close();

              } 

          }

       

      function buildDialog(){

          createWindow();

          dataTypesCheckboxes();

          pageItemsListbox();

          selectItemsGroup();

          moveLayerGroup();

          deleteAndCloseButtons();

          g.winMain.show();

         

          function createWindow(){

              g.winMain = new Window("palette", "Layer manager");

              g.winMain.orientation = "row";

              g.winMain.alignChildren = "top";

              }

         

          function dataTypesCheckboxes(){

              g.grpTypes = g.winMain.add('group');

              g.grpTypes.orientation = "column";

              g.grpTypes.alignChildren = "left";

              g.arrTypes = ['Text frame', 'Picture frame', 'Group', 'Shape', 'Line', 'Type on a path', 'Movie', 'Sound', 'Button'];

              for (var i=0; i<g.arrTypes.length; i++){

                  var currentChk = g.grpTypes.add('checkbox', undefined, g.arrTypes[i], {name:g.arrTypes[i]});

                  currentChk.value = true;

                  currentChk.onClick = updateListbox;

                  }

              }

         

          function pageItemsListbox(){

              var grpItems = g.winMain.add('group');

              grpItems.orientation = 'column';

              grpItems.alignChildren = 'top';

              g.lstPageItems = grpItems.add('listbox', undefined, undefined, {multiselect:true, numberOfColumns: 3, showHeaders:true, columnTitles:['Page', 'Item', 'Layer'], columnWidths:[50,125,125]});

              g.lstPageItems.size = [300,250];

              g.lstPageItems.onDoubleClick = lstPageItems_onDoubleClick;

              }

         

          function selectItemsGroup(){

              g.grpButtons = g.winMain.add('group');

              g.grpButtons.orientation = 'column';

              var pnlType = g.grpButtons.add('panel');

              g.ddlTypes = pnlType.add('dropdownlist', undefined, g.arrTypes);

              var btnSelect = pnlType.add('button', undefined, 'Select by type');

              btnSelect.size = [120,20];

              btnSelect.onClick = btnSelect_onClick;

              g.chkAdd = pnlType.add('checkbox', undefined, 'Add to selection');

              }

         

          function moveLayerGroup(){

              var pnlMove = g.grpButtons.add('panel');

              var arrLayers = [];

              for(var i=0; i<g.doc.layers.length; i++){

                  arrLayers.push(g.doc.layers[i].name);

                  }

              arrLayers.push('-');

              arrLayers.push('New Layer');

              g.ddlLayers = pnlMove.add('dropdownlist', undefined, arrLayers);

              var btnMove = pnlMove.add('button', undefined, 'Move to layer');

              btnMove.size = [120,20];

              btnMove.onClick = btnMove_onClick;

              }

         

          function deleteAndCloseButtons(){

              var btnDelete = g.grpButtons.add('button', undefined, 'Delete selected');

              btnDelete.size = [120,20];

              btnDelete.onClick = btnDelete_onClick;

              var btnClose = g.grpButtons.add('button', undefined, 'Close');

              btnClose.size = [120,20];

              btnClose.onClick = btnClose_onClick;

              }

          }

      function updateListbox(){

          app.scriptPreferences.enableRedraw = false;

          g.lstPageItems.selection = null;

          g.lstPageItems.removeAll();

          g.winProg.show();

          for (var i = 0; i < g.arrPageItems.length; i ++){

              var currentPageItem = g.arrPageItems[i];

              var currentPage = currentPageItem.parentPage;

              var currentItemType = detectType(currentPageItem);

              currentCheckBox = g.grpTypes.children[currentItemType];

              if(currentCheckBox.value == true){

                  var currentListItem = g.lstPageItems.add('item', currentPage.name);

                  currentListItem.subItems[0].text = currentItemType;

                  currentListItem.subItems[1].text = currentPageItem.itemLayer.name;

                  currentListItem.id = currentPageItem.id;

              }

              g.winProg.prg.value ++;

          }

          g.winProg.prg.value =0;

          g.winProg.close();

          app.scriptPreferences.enableRedraw = true;

      } // end function updateListbox

       

      function detectType(currentPageItem){

          if(currentPageItem instanceof TextFrame){return 'Text frame'};

          if(currentPageItem instanceof Group){return 'Group'};

          if(currentPageItem instanceof Button){return 'Button'};

          if(currentPageItem instanceof Rectangle || currentPageItem instanceof Oval || currentPageItem instanceof Polygon){

              if(currentPageItem.movies.length>0){return 'Movie'};

              else if(currentPageItem.sounds.length>0){return 'Sound'};

              else if(currentPageItem.textPaths.length>0){return 'Type on a path'};

              else if(currentPageItem.contentType == ContentType.GRAPHIC_TYPE){return 'Picture frame'};

              else{return 'Shape'};

              }

          if(currentPageItem instanceof GraphicLine){

              if(currentPageItem.textPaths.length>0){return 'Type on a path'};

              else{return 'Line'};

              }

          }

       

      function lstPageItems_onDoubleClick(){

          var idClicked = this.selection[0].id;

          var item2Select = g.doc.pageItems.itemByID(idClicked);

          item2Select.select();

          }

       

       

       

         

         

       

       

       

         

       

                 

      function btnSelect_onClick(){

          if(g.ddlTypes.selection == null){

              alert('Please make a selection from the dropdown list');

              }

          else{

              if(g.chkAdd.value == false){g.lstPageItems.selection = null;}

              app.scriptPreferences.enableRedraw = false;

              g.winProg.prg.value = 0;

              g.winProg.show();

              for (var i=0; i<g.lstPageItems.items.length; i++){

                  var currentItem = g.lstPageItems.items[i];

                  if(currentItem.subItems[0].text == g.ddlTypes.selection.text){

                      currentItem.selected = true;

                      }

                  g.winProg.prg.value++;

                  }

              g.winProg.hide();

              app.scriptPreferences.enableRedraw = true;

              }

          }

       

      function btnMove_onClick(){

          if(g.lstPageItems.selection == null || g.ddlLayers.selection == null){

              alert('Please select items to be moved and layers to be moved to');

              }

          else{

              //Target new layer?

              if(g.ddlLayers.selection.text == 'New Layer'){

                  var newLayer = prompt('Please enter a name for your new layer', "");

                  if(newLayer == ""||newLayer == null){

                      alert('No new layer created');

                      return;

                      }

                  try{

                      var targetLayer = g.doc.layers.add();

                      targetLayer.name = newLayer;

                      g.ddlLayers.selection = null;

                      g.ddlLayers.removeAll();

                      for(var i=0; i<g.doc.layers.length; i++){

                          g.ddlLayers.add('item',g.doc.layers[i].name);

                          }

                      g.ddlLayers.add('separator');

                      g.ddlLayers.add('item','New Layer');

                      }

                  catch(err){

                      alert('A layer with that name already exists');

                      targeLayer.remove();

                      return;

                      }

                  }   

              //Target existing layer?

              else{

                  var newLayer = g.ddlLayers.selection.text;

                  var targetLayer = g.doc.layers.itemByName(newLayer);

                  }

             

              //Move items

              for (var i=0; i<g.lstPageItems.selection.length; i++){

                  var currentItem = g.lstPageItems.selection[i];

                  var item2Move = g.doc.pageItems.itemByID(currentItem.id);

                  item2move.itemLayer = targetLayer;

                  currentItem.subItems[1].text = targetLayer.name;

                  }

              }

          }

       

      function btnDelete_onClick(){

          var blnConfirm = confirm('Are you sure you want to delete the selected items?');

          if(blnConfirm == true){

              var arrDelete = g.lstPageItems.selection;

              for (var i=0; i<arrDelete.length; i++){

                  var currentItem = arrDelete[i];

                  var item2Delete = g.doc.pageItems.itemByID(currentItem.id);

                  item2Delete.remove();

                  g.lstPageItems.remove(currentItem);

                  }

              }

          }

      function btnClose_onClick(){

          g.winMain.close();

          g = null;

          }

        • 1. Re: Script causes InDesign CC to crash
          Marc Autret Level 4

          Hi simonvg,

           

          There is at least one statement that may explain why InDesign CC crashes, and that's the very last line: g = null.

           

          Indeed, CC has serious problems with nullified-zeroed-deleted variables, especially when ScriptUI components are embedded behind the identifier.

           

          So your first step is to remove g = null. This should at least let InDesign survive.

           

          But, in my opinion, the code still exposes issues (lazy implementation, bad design choices, overuse of JS closures…) so I'd be surprised if the script worked properly. If you're learning ExtendScript, be aware that Adobe is not good (to say the least!) at providing robust and educational snippets.

           

          @+

          Marc

          1 person found this helpful
          • 2. Re: Script causes InDesign CC to crash
            simonvg Level 1

            Thanks very much Marc - removing g = null does the trick, the code works fine without it, but won't that cause possible problems with other scripts, having the global variable active for the remainder of the session?

             

            Also, as I'm very much a beginner, I don't have a sense of where the implementation is lazy and how the code could be better designed. Could you perhaps give me some pointers or examples, if it's not too much trouble? Still need to get my head around exactly what closures are, so not going to worry too much about that at this point.

             

            Thanks

            Simon

            • 3. Re: Script causes InDesign CC to crash
              Laubender Adobe Community Professional & MVP

              https://forums.adobe.com/people/Marc+Autret  wrote

              … If you're learning ExtendScript, be aware that Adobe is not good (to say the least!) at providing robust and educational snippets.

              Hi Marc,

              FWIW: I'm sure, Simon used the script 03-layer-manager_completed.jsx from Grant Gamble's book that stems from early 2011: https://indesignsecrets.com/new-indesign-automation-book.php


              So this is no sample Adobe provided.

               

              Regards,
              Uwe