Closed spector700 closed 1 month ago
@spector700 Hi Nick, thanks so much for the report. At the moment I'm not too sure what's going on (seems like a pretty weird bug), but I do see moz-extension
URL's in the error message, and that seems like an indicator that it might have to do with certain browser extensions. Ivan Kutskir has announced that Photopea works best when browser extensions are disabled. If possible, could you try disabling your browser extensions? If that doesn't work, let me know and we can try to investigate this in more detail!
Yeah, It looks like it was the Dark Reader extension. Thanks for the help.
Do you have any idea why that happens? If I have app.activeDocument.close() in a script to insert images into smart objects, it doesn't do that.
But If I do it separately, then it does the spamming.
@spector700 Glad to have helped. As for your error message, it's hard to say, but it looks like something to do with MutationObserver
(called when DOM elements are created or destroyed). Seems like your Dark Reader extension has trouble iterating through the "tab" elements in Photopea, probably trying to access elements after they've been modified/deleted, hence the target is null
.
@spector700 By the way, just out of curiosity, may I ask what your project is about?
So far, I am building a site to add an image to all the smart objects, then resize to fit the screen, then show the result or download. Perhaps have a canvas on the page to position it with a live preview.
So I had A working version of all this, but I wanted to clean it up with your class. However, I'm also having another issue.
I have this function that I send to open all the smart objects:
const smartObjects = await photopea.runScript(
findSmartLayers.toString() + "findSmartLayers()",
);
console.log(smartObjects);
function findSmartLayers() {
let smartObjects = [];
const mainDoc = app.activeDocument;
let index = { nameIndex: 0 };
function loopLayers(parrentLayer) {
let layers = parrentLayer.layers;
for (let i = 0; i < layers.length; i++) {
if (layers[i].typename == "LayerSet") {
// loop throgh the layerSet (folder)
loopLayers(layers[i]);
} else if (
layers[i].kind == LayerKind.SMARTOBJECT &&
layers[i].positionLocked == false
) {
// open the smart object
app.activeDocument.activeLayer = layers[i];
executeAction(stringIDToTypeID("placedLayerEditContents"));
// rename to the index so each is unieque when useing getByName()
app.activeDocument.name = index.nameIndex;
index.nameIndex += 1;
smartObjects.push({
docName: app.activeDocument.name,
name: layers[i].name,
visible: layers[i].visible,
width: app.activeDocument.width,
height: app.activeDocument.height,
resolution: app.activeDocument.resolution,
});
// reactivate the main document
app.activeDocument = mainDoc;
}
}
}
loopLayers(mainDoc);
app.echoToOE(JSON.stringify({ SMART_OBJECTS: smartObjects }));
}
It works and opens all of them. However, the app.echoToOE(JSON.stringify({ SMART_OBJECTS: smartObjects }));
is never received in the array.
I'm guessing it's because it's receiving 'done' too early? (I'm bad at JavaScript promises)
I can do something like this to have a custom finish message, which works. But I don't know if this will cause me problems latter.
async runScript(script) {
await this._pause();
let message = script + " \napp.echoToOE('FINISHED')";
let waitForMessage = new Promise((res) => {
let outputs = [];
let messageHandle = (e) => {
if (e.source == this.contentWindow) {
if (e.data == "done") return;
outputs.push(e.data);
if (e.data == "FINISHED") {
window.removeEventListener("message", messageHandle);
res(outputs);
}
}
};
window.addEventListener("message", messageHandle);
this.contentWindow.postMessage(message, "*");
});
return await waitForMessage;
}
@spector700 I was able to replicate your issue. ["done"]
was echoed the first time, but the second time it worked as expected. So I suppose you could get away with calling runScript
until you get a response other than done:
let smartObjects = ["done"];
let reps = 0; // count loop repetitions to avoid infinite loop
while (smartObjects && smartObjects[0] == "done") {
smartObjects = await photopea.runScript(
findSmartLayers.toString() + "findSmartLayers()",
);
console.log(smartObjects);
if (reps > 10) break; // avoid an infinite loop
}
Hello,
I am trying to use your class. If I try to close open documents before opening another file, It works, however the console gets spammed with
target is null
and doesn't stop:Here is the code:
If there is no open files, it opens fine and shows no errors.
If there is an open file, it closes fine and opens the next file fine. Then shows non-stop error.