Copy link to clipboard
Copied
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;
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, {name:g.arrTypes});
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.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;
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;
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.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;
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;
var item2Delete = g.doc.pageItems.itemByID(currentItem.id);
item2Delete.remove();
g.lstPageItems.remove(currentItem);
}
}
}
function btnClose_onClick(){
g.winMain.close();
g = null;
}
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 scr
...Copy link to clipboard
Copied
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
Copy link to clipboard
Copied
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
Copy link to clipboard
Copied
… 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