Copy link to clipboard
Copied
I have something already written that will go through and add pageItems to an array based on the fill or stroke color being the same. At first I was moving each item to a layer named with the color that the item was either filled with or stroked with. After moving all items to a different layer in the document I would attempt to go through and delete the empty layers. I am not exactly sure what was happening but it seemed that the script started to try and delete layers before all pageItems were moved to the new layer. So there were empty layers left. I tried redraw() before trying to delete the layers this worked a little better but still did not work entirely, and seemed to be speratic and deleting 0, 1, 2, 3.... layers everytime I ran it. I cannot seem to find a solution to this.
So my next attempt was to collect each item to an array and try to add that to app or document selection
app.selection = [pageItems...]
app.activeDocument.selection = [pageItems]
The script would freeze up, and when I quit it I was left with some of the items selected. Again not exactly sure what was happening here either.
I also tried to research a way to move the array of pageItems all at once after being collected. Not finding anything on this so not sure if it is possible.
I am trying to avoid running through a loop again. There are over 4,000 pageItems I am testing on, production files could possibly be much more.
2 Correct answers
Without seeing your code, I don't know what's going on, BUT I think there's a good chance the problem is caused by the rearrangement of the document messing up your references to the pageItems.
To test, you could try a few things. First, your "array" might be "an array like object", and not a vanilla Array. From memory, you can do var newArray = oldArray.slice() to make a normal array. That might work. Sorry I can't test now so it's just from my poor memory.
Or maybe you could get new references
...I am wondering how you are moving pageItems from one layer to another, but regardless you should be able to delete empty layers at the end. Like m1b said, deleting items from a collection with forward iteration is problematic because of rearrangement, so you could try backward iteration.
for (var i = app.activeDocument.layers.length - 1; i >= 0; i--) {
if (app.activeDocument.layers[i].pageItems.length == 0) {
app.activeDocument.layers[i].remove();
}
}
Explore related tutorials & articles
Copy link to clipboard
Copied
Without seeing your code, I don't know what's going on, BUT I think there's a good chance the problem is caused by the rearrangement of the document messing up your references to the pageItems.
To test, you could try a few things. First, your "array" might be "an array like object", and not a vanilla Array. From memory, you can do var newArray = oldArray.slice() to make a normal array. That might work. Sorry I can't test now so it's just from my poor memory.
Or maybe you could get new references to your objects after moving them or deleting layers? Also, working with arrays in reverse order can often work as it might not mess up the references (depending on what you're doing). For example, deleting items starting at the end of the array won't change the indices of the unprocessed items.
Copy link to clipboard
Copied
I am wondering how you are moving pageItems from one layer to another, but regardless you should be able to delete empty layers at the end. Like m1b said, deleting items from a collection with forward iteration is problematic because of rearrangement, so you could try backward iteration.
for (var i = app.activeDocument.layers.length - 1; i >= 0; i--) {
if (app.activeDocument.layers[i].pageItems.length == 0) {
app.activeDocument.layers[i].remove();
}
}
Copy link to clipboard
Copied
That appears to have worked. Thank you both.
femkeblanco, I was moving each item one at a time as I came across them for a color check. When I had the issue deleting the layers I thought it was a timing issue, first thought was if I could move all items at once then remove layers may help with the timing. So I collected all pageItems by color into an array, grouped them, then moved them to the layer created.
Code, its messy right now but it works with the backwards iteration. If you all know of a way to do this efficently please let me know.
//@include "../utils/json2.jsx"
doc = app.activeDocument
drillBoxes()
function drillBoxes(){
allPageItems = filterPageItems()
seps = seprateItems(allPageItems)
moveToLayer(seps)
removeEmptyLayers(doc.layers)
}
function addToGroup(arr){
groupCollect = doc.groupItems.add()
for(i=0; i<arr.length; i++){
arr[i].move(groupCollect, ElementPlacement.PLACEATBEGINNING)
}
return groupCollect
}
function moveToLayer(sepObj, callback){
for(y=0; y < sepObj.colors; y++){
nGroup = addToGroup(seps[seps.colornames[y]])
nGroup.move(doc.layers[seps.colornames[y]], ElementPlacement.PLACEATBEGINNING)
}
}
function seprateItems(allPageItems){
//Move all items at once?
createdLayers = {}
createdLayers['colors'] = 0
createdLayers['colornames'] = []
len = allPageItems.length
for(z=0; z < len; z++){
j = allPageItems[z].length - 1
while(j >= 0){
currItem = allPageItems[z][j]
if(currItem.typename === 'CompoundPathItem'){
if(currItem.pathItems.length){
if(currItem.pathItems[0].filled){
currColor = currItem.pathItems[0].fillColor
}else{
currColor = currItem.pathItems[0].strokeColor
}
if(currColor.constructor.name === 'SpotColor'){
if(currColor.spot.name === '[Registration]'){
currItem.remove()
j--
continue
}
if(createdLayers[currColor.spot.name + 'color']){
createdLayers[currColor.spot.name].push(currItem)
}else{
addLayer(currColor.spot.name, [50, 50, 50])
doc.layers[currColor.spot.name].zOrder(ZOrderMethod.SENDTOBACK)
createdLayers[currColor.spot.name] = []
createdLayers[currColor.spot.name].push(currItem)
createdLayers['colors'] += 1
createdLayers['colornames'].push(currColor.spot.name)
createdLayers[currColor.spot.name + 'color'] = true
}
}else{
currItem.remove()
}
}else{
curItem.remove()
j--
continue
}
}else{
if(currItem.fillColor.constructor.name === 'SpotColor' || currItem.strokeColor.constructor.name === 'SpotColor'){
if(currItem.filled){
currColor = currItem.fillColor
}else{
currColor = currItem.strokeColor
}
if(currColor.spot.name === '[Registration]'){
currItem.remove()
j--
continue
}
if(createdLayers[currColor.spot.name + 'color']){
createdLayers[currColor.spot.name].push(currItem)
}else{
addLayer(currColor.spot.name, [50, 50, 50])
doc.layers[currColor.spot.name].zOrder(ZOrderMethod.SENDTOBACK)
createdLayers[currColor.spot.name] = []
createdLayers[currColor.spot.name].push(currItem)
createdLayers['colors'] += 1
createdLayers['colornames'].push(currColor.spot.name)
createdLayers[currColor.spot.name + 'color'] = true
}
}else{
currItem.remove()
}
}
j--
}
}
return createdLayers
callback()
}
function filterPageItems(){
collect = []
docLayers = doc.layers
for(i=0; i < docLayers.length; i++){
currLayer = docLayers[i]
returnArr = []
collectedPageItems = pageItemCustomRecursive(currLayer, returnArr)
collect.push(collectedPageItems)
}
// cleanCollect = twoDeArraytoOneDe(collect)
return collect
}
function pageItemCustomRecursive(parent, returnItems){
if(parent.typename == "Layer" && parent.layers.length > 0){
var layers = parent.layers
for( var i = 0; i < layers.length; i++ ) {
var subLayer = layers[i]
pageItemRecursive(subLayer, returnItems)
}
}
var items = parent.pageItems
for( var j = 0; j < items.length; j++ ){
var curItem = items[j]
if(curItem.typename == "GroupItem"){
pageItemRecursive(curItem, returnItems)
}else if(curItem.typename == "MeshItem" || "PlacedItem" || "SymbolItem" || "RasterItem" || "NonNativeItem" || "PluginItem" || "PathItem" || "CompoundPathItem"){
returnItems.push(curItem)
}
}
return returnItems
}
function removeEmptyLayers(arr){
$.writeln(arr)
app.redraw()
for(i=arr.length-1; i >= 0; i--){
$.writeln(arr[i])
if(arr[i].pageItems.length === 0){
arr[i].remove()
}else{
$.writeln(arr[i])
continue
}
}
}
function addLayer(name, rgbColors){
if (rgbColors === undefined){rgbColors = [255, 0, 255]}
var cont = true;
function change() {
cont = !cont;
}
for(i = 0; i < app.activeDocument.layers.length; i++){
if(app.activeDocument.layers[i].name == name){
change();
}
}
if (cont == true) {
var newColor = new RGBColor();
newColor.red = rgbColors[0];
newColor.green = rgbColors[1];
newColor.blue = rgbColors[2];
var newLayer = app.activeDocument.layers.add();
newLayer.name = name;
newLayer.color = newColor;
}
app.activeDocument.layers[name].visibile = true
app.activeDocument.layers[name].locked = false
app.activeDocument.activeLayer = app.activeDocument.layers.getByName(name);
}
Also using this function from another file

