diff --git a/CHANGELOG.md b/CHANGELOG.md index be0bc128d..7d2cce350 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,10 @@ All notable changes to this project will be documented in this file. - "Show detail" context menu item for items in folder preview - [#1682] AS2 - Adding class by context menu on packages +### Changed +- AS1/2 - Single DoAction tag inside frame is now displayed directly as frame node + so there is no longer need to expand frame nodes (useful for fast switching scripts) + ### Fixed - [#2456] FLA export - NullPointer exception while exporting to CS4 or lower via commandline - Touch point, snap align and snap to objects incorrect position when editing nested layers diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java index 1c7510e26..45293ff99 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java @@ -3276,18 +3276,22 @@ public final class SWF implements SWFContainerItem, Timelined, Openable { } } else if (treeItem instanceof FrameScript) { FrameScript frameScript = (FrameScript) treeItem; - Frame parentFrame = frameScript.getFrame(); - for (TreeItem subItem : parentFrame.actionContainers) { - getASMs(exportFileNames, getASMWrapToTagScript(subItem), nodesToExport, exportAll || exportNode, asmsToExport, - pathExportFilenames + File.separator + getASMPath(true, subItem), - pathNoExportFilenames + File.separator + getASMPath(false, subItem) - ); - } - for (TreeItem subItem : parentFrame.actions) { - getASMs(exportFileNames, getASMWrapToTagScript(subItem), nodesToExport, exportAll || exportNode, asmsToExport, - pathExportFilenames + File.separator + getASMPath(true, subItem), - pathNoExportFilenames + File.separator + getASMPath(false, subItem) - ); + if (frameScript.getSingleDoActionTag() != null && !exportFileNames) { + asmsToExport.put(pathNoExportFilenames, frameScript.getSingleDoActionTag()); + } else { + Frame parentFrame = frameScript.getFrame(); + for (TreeItem subItem : parentFrame.actionContainers) { + getASMs(exportFileNames, getASMWrapToTagScript(subItem), nodesToExport, exportAll || exportNode, asmsToExport, + pathExportFilenames + File.separator + getASMPath(true, subItem), + pathNoExportFilenames + File.separator + getASMPath(false, subItem) + ); + } + for (TreeItem subItem : parentFrame.actions) { + getASMs(exportFileNames, getASMWrapToTagScript(subItem), nodesToExport, exportAll || exportNode, asmsToExport, + pathExportFilenames + File.separator + getASMPath(true, subItem), + pathNoExportFilenames + File.separator + getASMPath(false, subItem) + ); + } } } else if (treeItem instanceof AS2Package) { AS2Package as2Package = (AS2Package) treeItem; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/timeline/FrameScript.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/timeline/FrameScript.java index 9329cb581..fa69c5d5e 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/timeline/FrameScript.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/timeline/FrameScript.java @@ -17,6 +17,7 @@ package com.jpexs.decompiler.flash.timeline; import com.jpexs.decompiler.flash.SWF; +import com.jpexs.decompiler.flash.tags.DoActionTag; import com.jpexs.decompiler.flash.tags.base.Exportable; import com.jpexs.decompiler.flash.treeitems.Openable; import com.jpexs.decompiler.flash.treeitems.TreeItem; @@ -70,8 +71,22 @@ public class FrameScript implements TreeItem, Exportable { @Override public String toString() { + if (getSingleDoActionTag() != null) { + return frame.toString() + " - " + "DoAction"; + } return frame.toString(); } + + public DoActionTag getSingleDoActionTag() { + if (!frame.actionContainers.isEmpty()) { + return null; + } + if (frame.actions.size() != 1) { + return null; + } + + return frame.actions.get(0); + } /** * Gets export filename. diff --git a/src/com/jpexs/decompiler/flash/gui/ExportDialog.java b/src/com/jpexs/decompiler/flash/gui/ExportDialog.java index 309328d88..a7ece180d 100644 --- a/src/com/jpexs/decompiler/flash/gui/ExportDialog.java +++ b/src/com/jpexs/decompiler/flash/gui/ExportDialog.java @@ -47,12 +47,12 @@ import com.jpexs.decompiler.flash.tags.base.SoundTag; import com.jpexs.decompiler.flash.tags.base.SymbolClassTypeTag; import com.jpexs.decompiler.flash.tags.base.TextTag; import com.jpexs.decompiler.flash.timeline.Frame; +import com.jpexs.decompiler.flash.timeline.FrameScript; import com.jpexs.decompiler.flash.timeline.TagScript; import com.jpexs.decompiler.flash.treeitems.AS3ClassTreeItem; import com.jpexs.decompiler.flash.treeitems.TreeItem; import java.awt.BorderLayout; import java.awt.Container; -import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; @@ -103,7 +103,7 @@ public class ExportDialog extends AppDialog { {ImageTag.class}, {DefineVideoStreamTag.class}, {SoundTag.class}, - {ASMSource.class, ScriptPack.class, TagScript.class}, + {ASMSource.class, ScriptPack.class, TagScript.class, FrameScript.class}, {BinaryDataInterface.class}, {Frame.class}, {Frame.class}, diff --git a/src/com/jpexs/decompiler/flash/gui/FolderListPanel.java b/src/com/jpexs/decompiler/flash/gui/FolderListPanel.java index 1e6bbcfd4..153a5a5b2 100644 --- a/src/com/jpexs/decompiler/flash/gui/FolderListPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/FolderListPanel.java @@ -20,6 +20,7 @@ import com.jpexs.decompiler.flash.configuration.Configuration; import com.jpexs.decompiler.flash.gui.tagtree.AbstractTagTree; import com.jpexs.decompiler.flash.tags.DoInitActionTag; import com.jpexs.decompiler.flash.tags.Tag; +import com.jpexs.decompiler.flash.timeline.FrameScript; import com.jpexs.decompiler.flash.treeitems.TreeItem; import com.jpexs.helpers.SerializableImage; import java.awt.Color; @@ -242,6 +243,10 @@ public class FolderListPanel extends JPanel { TreeItem treeItem = items.get(index); TreeNodeType type = AbstractTagTree.getTreeNodeType(treeItem); + if ((treeItem instanceof FrameScript) && ((FrameScript) treeItem).getSingleDoActionTag() != null) { + type = TreeNodeType.AS_FRAME; + } + Icon icon = ICONS.get(type); icon.paintIcon(l, g, x * CELL_WIDTH + BORDER_SIZE + PREVIEW_SIZE / 2 - icon.getIconWidth() / 2, y * CELL_HEIGHT + BORDER_SIZE + PREVIEW_SIZE / 2 - icon.getIconHeight() / 2); String s = null; diff --git a/src/com/jpexs/decompiler/flash/gui/MainPanel.java b/src/com/jpexs/decompiler/flash/gui/MainPanel.java index 9cfec34b8..ed7ac633d 100644 --- a/src/com/jpexs/decompiler/flash/gui/MainPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/MainPanel.java @@ -182,6 +182,7 @@ import com.jpexs.decompiler.flash.tags.gfx.DefineExternalStreamSound; import com.jpexs.decompiler.flash.tags.text.TextParseException; import com.jpexs.decompiler.flash.timeline.AS3Package; import com.jpexs.decompiler.flash.timeline.Frame; +import com.jpexs.decompiler.flash.timeline.FrameScript; import com.jpexs.decompiler.flash.timeline.Scene; import com.jpexs.decompiler.flash.timeline.SceneFrame; import com.jpexs.decompiler.flash.timeline.SoundStreamFrameRange; @@ -2958,6 +2959,11 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se if (ts.getTag() instanceof ASMSource) { as = (ASMSource) ts.getTag(); } + } else if (t instanceof FrameScript) { + FrameScript fs = (FrameScript) t; + if (fs.getSingleDoActionTag() != null) { + as = fs.getSingleDoActionTag(); + } } if (as != null) { SWF s = as.getSourceTag().getSwf(); @@ -6152,6 +6158,14 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se treeItem = ((TagScript) treeItem).getTag(); preferScript = true; } + + if (treeItem instanceof FrameScript) { + FrameScript fs = (FrameScript) treeItem; + DoActionTag doAction = fs.getSingleDoActionTag(); + if (doAction != null) { + treeItem = doAction; + } + } folderPreviewPanel.clear(); folderListPanel.clear(); diff --git a/src/com/jpexs/decompiler/flash/gui/action/ActionPanel.java b/src/com/jpexs/decompiler/flash/gui/action/ActionPanel.java index f89f3285e..8a7f28336 100644 --- a/src/com/jpexs/decompiler/flash/gui/action/ActionPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/action/ActionPanel.java @@ -541,9 +541,15 @@ public class ActionPanel extends JPanel implements SearchListener { + if (isCancelled()) { + return; + } editor.setShowMarkers(false); setEditorText(asm.getScriptName(), asm.getExportedScriptName(), "; " + AppStrings.translate("work.disassembling") + "...", "text/flasm"); if (decompileNeeded) { @@ -552,12 +558,18 @@ public class ActionPanel extends JPanel implements SearchListener { decompiledEditor.setShowMarkers(false); diff --git a/src/com/jpexs/decompiler/flash/gui/tagtree/AbstractTagTree.java b/src/com/jpexs/decompiler/flash/gui/tagtree/AbstractTagTree.java index 2e94d155a..03620a82f 100644 --- a/src/com/jpexs/decompiler/flash/gui/tagtree/AbstractTagTree.java +++ b/src/com/jpexs/decompiler/flash/gui/tagtree/AbstractTagTree.java @@ -189,8 +189,17 @@ public abstract class AbstractTagTree extends JTree { return View.getIcon("folderscripts16"); } + + TreeNodeType type = getTreeNodeType(val); + if (val instanceof FrameScript) { + FrameScript fs = (FrameScript) val; + if (fs.getSingleDoActionTag() != null) { + type = TreeNodeType.AS_FRAME; + } + } + if (type == TreeNodeType.FOLDER && folderExpanded) { type = TreeNodeType.FOLDER_OPEN; } @@ -653,6 +662,12 @@ public abstract class AbstractTagTree extends JTree { d = tag; } } + if (d instanceof FrameScript) { + DoActionTag tag = ((FrameScript) d).getSingleDoActionTag(); + if (tag != null) { + d = tag; + } + } if (d instanceof Tag || d instanceof ASMSource diff --git a/src/com/jpexs/decompiler/flash/gui/tagtree/TagTreeContextMenu.java b/src/com/jpexs/decompiler/flash/gui/tagtree/TagTreeContextMenu.java index 6e611f119..52308d1f6 100644 --- a/src/com/jpexs/decompiler/flash/gui/tagtree/TagTreeContextMenu.java +++ b/src/com/jpexs/decompiler/flash/gui/tagtree/TagTreeContextMenu.java @@ -374,6 +374,24 @@ public class TagTreeContextMenu extends JPopupMenu { return items; } + private List filterOutScriptItems(List items) { + List noScriptItems = new ArrayList<>(); + for (TreeItem item : items) { + if (item instanceof TagScript) { + item = ((TagScript) item).getTag(); + } + if ((item instanceof FrameScript) && ((FrameScript) item).getSingleDoActionTag() != null) { + item = ((FrameScript) item).getSingleDoActionTag(); + } + noScriptItems.add(item); + } + return noScriptItems; + } + + private List getSelectedNoScriptItems() { + return filterOutScriptItems(items); + } + public TagTreeContextMenu(final List trees, MainPanel mainPanel) { this.mainPanel = mainPanel; @@ -1163,6 +1181,12 @@ public class TagTreeContextMenu extends JPopupMenu { continue; } } + if (item instanceof FrameScript) { + DoActionTag tag = ((FrameScript) item).getSingleDoActionTag(); + if (tag != null) { + continue; + } + } allSelectedIsTag = false; allSelectedIsTagWithClassName = false; @@ -1179,6 +1203,11 @@ public class TagTreeContextMenu extends JPopupMenu { if (tag instanceof DoActionTag || tag instanceof DoInitActionTag) { continue; } + } else if (item instanceof FrameScript) { + DoActionTag tag = ((FrameScript) item).getSingleDoActionTag(); + if (tag != null) { + continue; + } } else if (item instanceof Frame) { continue; } @@ -1352,6 +1381,12 @@ public class TagTreeContextMenu extends JPopupMenu { if (allSelectedIsTag) { boolean canUndo = false; for (TreeItem item : items) { + if (item instanceof TagScript) { + item = ((TagScript) item).getTag(); + } + if ((item instanceof FrameScript) && ((FrameScript) item).getSingleDoActionTag() != null) { + item = ((FrameScript) item).getSingleDoActionTag(); + } if (item instanceof Tag) { Tag tag = (Tag) item; if (tag.canUndo()) { @@ -1695,7 +1730,10 @@ public class TagTreeContextMenu extends JPopupMenu { if ((firstItem instanceof SWF) || (firstItem instanceof DefineSpriteTag) || (firstItem instanceof Frame)) { pasteInsideMenuItem.setVisible(true); } - if ((firstItem instanceof Tag) || (firstItem instanceof Frame)) { + if ((firstItem instanceof Tag) + || (firstItem instanceof Frame) + || (firstItem instanceof TagScript) + || ((firstItem instanceof FrameScript) && ((FrameScript) firstItem).getSingleDoActionTag() != null)) { pasteAfterMenuItem.setVisible(true); pasteBeforeMenuItem.setVisible(true); } @@ -1760,6 +1798,8 @@ public class TagTreeContextMenu extends JPopupMenu { for (TreeItem item : items) { if (item instanceof TagScript) { tagItems.add(((TagScript) item).getTag()); + } else if (item instanceof FrameScript) { + tagItems.add(((FrameScript) item).getSingleDoActionTag()); } else { tagItems.add((Tag) item); } @@ -2260,6 +2300,13 @@ public class TagTreeContextMenu extends JPopupMenu { Timelined timelined = null; int index = -1; + + if (item instanceof TagScript) { + item = ((TagScript) item).getTag(); + } + if ((item instanceof FrameScript) && ((FrameScript) item).getSingleDoActionTag() != null) { + item = ((FrameScript) item).getSingleDoActionTag(); + } if (item instanceof Tag) { Tag itemTag = (Tag) item; timelined = itemTag.getTimelined(); @@ -2301,6 +2348,12 @@ public class TagTreeContextMenu extends JPopupMenu { Timelined timelined = null; int index = -1; + if (item instanceof TagScript) { + item = ((TagScript) item).getTag(); + } + if ((item instanceof FrameScript) && ((FrameScript) item).getSingleDoActionTag() != null) { + item = ((FrameScript) item).getSingleDoActionTag(); + } if (item instanceof Tag) { Tag itemTag = (Tag) item; timelined = itemTag.getTimelined(); @@ -3485,8 +3538,11 @@ public class TagTreeContextMenu extends JPopupMenu { if (subItem instanceof FrameScript) { if (((FrameScript) subItem).getFrame().frame + 1 == targetFrame) { TreePath framePath = scriptsPath.pathByAddingChild(subItem); - List doActionTags = mainPanel.tagTree.getFullModel().getAllChildren(subItem); - TreePath doActionPath = framePath.pathByAddingChild(doActionTags.get(doActionTags.size() - 1)); + TreePath doActionPath = framePath; + if (((FrameScript) subItem).getSingleDoActionTag() == null) { + List doActionTags = mainPanel.tagTree.getFullModel().getAllChildren(subItem); + doActionPath = framePath.pathByAddingChild(doActionTags.get(doActionTags.size() - 1)); + } mainPanel.tagTree.setSelectionPath(doActionPath); mainPanel.tagTree.scrollPathToVisible(doActionPath); break; @@ -3982,6 +4038,8 @@ public class TagTreeContextMenu extends JPopupMenu { out.add(t); } else if (t instanceof ASMSource) { out.add(t); + } else if ((t instanceof FrameScript) && (((FrameScript) t).getSingleDoActionTag() != null)) { + out.add(t); } else { populateScriptSubs(t, out); } @@ -4038,6 +4096,8 @@ public class TagTreeContextMenu extends JPopupMenu { tagsToRemove.add((Tag) item); } else if ((item instanceof TagScript) && (((TagScript) item).getTag() instanceof ASMSource)) { tagsToRemove.add(((TagScript) item).getTag()); + } else if ((item instanceof FrameScript) && (((FrameScript) item).getSingleDoActionTag() != null)) { + tagsToRemove.add(((FrameScript) item).getSingleDoActionTag()); } else if (item instanceof Frame) { Frame frameNode = (Frame) item; Frame frame = frameNode.timeline.getFrame(frameNode.frame); @@ -4334,6 +4394,12 @@ public class TagTreeContextMenu extends JPopupMenu { Set computeSWFs = new LinkedIdentityHashSet<>(); for (TreeItem item : sel) { + if (item instanceof TagScript) { + item = ((TagScript) item).getTag(); + } + if ((item instanceof FrameScript) && ((FrameScript) item).getSingleDoActionTag() != null) { + item = ((FrameScript) item).getSingleDoActionTag(); + } if (item instanceof Tag) { try { Tag tag = (Tag) item; @@ -4389,7 +4455,7 @@ public class TagTreeContextMenu extends JPopupMenu { } private void cloneActionPerformed(ActionEvent e) { - List items = getSelectedItems(); + List items = getSelectedNoScriptItems(); /* Currently useless since all selected items must have the same parent * but a better way to detect for parent/child selection * could remove that limitation */ @@ -4500,6 +4566,9 @@ public class TagTreeContextMenu extends JPopupMenu { if (item instanceof TagScript) { item = ((TagScript) item).getTag(); } + if ((item instanceof FrameScript) && ((FrameScript) item).getSingleDoActionTag() != null) { + item = ((FrameScript) item).getSingleDoActionTag(); + } if (item instanceof SceneFrame) { item = ((SceneFrame) item).getFrame(); } @@ -4802,12 +4871,12 @@ public class TagTreeContextMenu extends JPopupMenu { } public void copyTagOrFrameToClipboardActionPerformed(ActionEvent evt) { - List items = getSelectedItems(); + List items = getSelectedNoScriptItems(); copyTagOrFrameToClipboardActionPerformed(evt, items); } public void copyTagOrFrameToClipboardActionPerformed(ActionEvent evt, List items) { - mainPanel.copyToClipboard(items); + mainPanel.copyToClipboard(filterOutScriptItems(items)); } private Set getDependenciesSet(List items) { @@ -4846,17 +4915,17 @@ public class TagTreeContextMenu extends JPopupMenu { } public void copyTagToClipboardWithDependenciesActionPerformed(ActionEvent evt, List items) { - mainPanel.copyToClipboard(getDependenciesSet(items)); + mainPanel.copyToClipboard(getDependenciesSet(filterOutScriptItems(items))); } public void cutTagOrFrameToClipboardActionPerformed(ActionEvent evt) { - List items = getSelectedItems(); + List items = getSelectedNoScriptItems(); mainPanel.cutToClipboard(items); mainPanel.repaintTree(); } public void cutTagToClipboardWithDependenciesActionPerformed(ActionEvent evt) { - List items = getSelectedItems(); + List items = getSelectedNoScriptItems(); mainPanel.cutToClipboard(getDependenciesSet(items)); mainPanel.repaintTree(); } @@ -4873,6 +4942,12 @@ public class TagTreeContextMenu extends JPopupMenu { Timelined timelined; Tag position; int positionInt; + if (item instanceof TagScript) { + item = ((TagScript) item).getTag(); + } + if ((item instanceof FrameScript) && ((FrameScript) item).getSingleDoActionTag() != null) { + item = ((FrameScript) item).getSingleDoActionTag(); + } if (item instanceof Frame) { Frame frame = (Frame) item; timelined = frame.timeline.timelined; @@ -4901,6 +4976,12 @@ public class TagTreeContextMenu extends JPopupMenu { Timelined timelined; Tag position; int positionInt; + if (item instanceof TagScript) { + item = ((TagScript) item).getTag(); + } + if ((item instanceof FrameScript) && ((FrameScript) item).getSingleDoActionTag() != null) { + item = ((FrameScript) item).getSingleDoActionTag(); + } if (item instanceof Frame) { Frame frame = (Frame) item; timelined = frame.timeline.timelined; @@ -4928,6 +5009,12 @@ public class TagTreeContextMenu extends JPopupMenu { } else { Timelined timelined; Tag position; + if (item instanceof TagScript) { + item = ((TagScript) item).getTag(); + } + if ((item instanceof FrameScript) && ((FrameScript) item).getSingleDoActionTag() != null) { + item = ((FrameScript) item).getSingleDoActionTag(); + } if (item instanceof Frame) { Frame frame = (Frame) item; position = frame.allInnerTags.get(frame.allInnerTags.size() - 1); diff --git a/src/com/jpexs/decompiler/flash/gui/tagtree/TagTreeModel.java b/src/com/jpexs/decompiler/flash/gui/tagtree/TagTreeModel.java index e977feec1..66e94a336 100644 --- a/src/com/jpexs/decompiler/flash/gui/tagtree/TagTreeModel.java +++ b/src/com/jpexs/decompiler/flash/gui/tagtree/TagTreeModel.java @@ -404,14 +404,14 @@ public class TagTreeModel extends AbstractTagTreeModel { } } } - + List ret = new ArrayList<>(); for (String f : FOLDERS_ORDER) { if (folderNames.contains(f)) { ret.add(f); } } - + return ret; } @@ -579,6 +579,20 @@ public class TagTreeModel extends AbstractTagTreeModel { if (objNoTs == nNoTs) { return true; } + + TreeItem objNoFs = obj; + if ((obj instanceof FrameScript) && ((FrameScript) obj).getSingleDoActionTag() != null) { + objNoFs = ((FrameScript) obj).getSingleDoActionTag(); + } + + TreeItem nNoFs = n; + if ((n instanceof FrameScript) && ((FrameScript) n).getSingleDoActionTag() != null) { + nNoFs = ((FrameScript) n).getSingleDoActionTag(); + } + + if (objNoFs == nNoFs) { + return true; + } } return false; } @@ -710,6 +724,9 @@ public class TagTreeModel extends AbstractTagTreeModel { } else if (parentNode instanceof AS2Package) { return ((AS2Package) parentNode).getAllChildren(); } else if (parentNode instanceof FrameScript) { + if (((FrameScript) parentNode).getSingleDoActionTag() != null) { + return new ArrayList<>(); + } Frame parentFrame = ((FrameScript) parentNode).getFrame(); result.addAll(parentFrame.actionContainers); result.addAll(parentFrame.actions); @@ -807,6 +824,9 @@ public class TagTreeModel extends AbstractTagTreeModel { } else if (parentNode instanceof AS2Package) { return ((AS2Package) parentNode).getChild(index); } else if (parentNode instanceof FrameScript) { + if (((FrameScript) parentNode).getSingleDoActionTag() != null) { + return null; + } Frame parentFrame = ((FrameScript) parentNode).getFrame(); TreeItem result; if (index < parentFrame.actionContainers.size()) { @@ -884,6 +904,9 @@ public class TagTreeModel extends AbstractTagTreeModel { } else if (parentNode instanceof AS2Package) { return mappedSize + ((AS2Package) parentNode).getChildCount(); } else if (parentNode instanceof FrameScript) { + if (((FrameScript) parentNode).getSingleDoActionTag() != null) { + return 0; + } Frame parentFrame = ((FrameScript) parentNode).getFrame(); return mappedSize + parentFrame.actionContainers.size() + parentFrame.actions.size(); } else if (parentNode instanceof TagScript) { @@ -956,6 +979,9 @@ public class TagTreeModel extends AbstractTagTreeModel { } else if (parentNode instanceof AS2Package) { return indexOfAdd(baseIndex, ((AS2Package) parentNode).getIndexOfChild(childNode)); } else if (parentNode instanceof FrameScript) { + if (((FrameScript) parentNode).getSingleDoActionTag() != null) { + return -1; + } Frame parentFrame = ((FrameScript) parentNode).getFrame(); if (childNode instanceof TagScript) { childNode = ((TagScript) childNode).getTag();