InDesign スクリプト 要素を配置（複製したページアイテムに）

複製したページアイテムに要素を配置するスクリプトは、これで良いのかな・・・？

~~~JavaScript
/*
複製したページアイテムに要素を配置
更新 2021/06/12

構造に読み込むXMLの例
<?xml version="1.0" encoding='UTF-8' standalone="yes"?>
<Root>
<!--文字コードに注意-->
<猫の名前 placePageNumber='1'>こはく</猫の名前>
<猫の名前 placePageNumber='2'>ぼんた</猫の名前>
<猫の名前 placePageNumber='3'>くろい</猫の名前>
</Root>
*/

// アプリ指定
#target "indesign";

// スクリプト名
var scriptName = "要素を配置（複製したページアイテムに）";

//スクリプト動作指定（一つのアンドゥ履歴にする、及び、アンドゥ名の指定）
app.doScript(function () {

    //  配置ページ番号を指定する属性の属性名
    var placePageNumberAssignAttributeName ="placePageNumber";

    // ダイアログ
    var dialogueFlg = confirm("構造の選択された要素を最後に選択された要素のページアイテムを複製してページの左上を原点にした位置に配置します。" + "\r\r" + "ページを指定するのに" + placePageNumberAssignAttributeName + "名の属性とその値（ページ番号）を使用します。", "", scriptName);

    // Noの場合
    if (dialogueFlg == false) {

        // 終了
        exit();
    }

    // 複製元のオブジェクト
    var copySourceObject;

    // 選択を入れる
    selectObjects = app.activeDocument.selection;

    // 全ての選択を解除
    app.activeDocument.selection　= null;

    // 基準のオブジェクトの位置と大きさ
    var baselineObjectGeometricBounds;

    // 基準のオブジェクトのページの位置と大きさ
    var baselineObjectPageBounds;

    // 基準のオブジェクトのフラグにfalseを入れる
    var baselineObjectFlg = false;

     // 選択がある場合
    if(selectObjects.length > 0){

        // 最後の選択が要素の場合
        if(selectObjects[selectObjects.length - 1].constructor.name == "XMLElement"){

            // 要素の参照がStoryの場合
            if(selectObjects[selectObjects.length - 1].xmlContent.constructor.name == "Story"){

                // parentPageに値がある場合
                if (selectObjects[selectObjects.length - 1].xmlContent.textContainers[0].parentPage){

                    // 要素の参照の持つ最初のテキストフレームを入れる
                    copySourceObject = selectObjects[selectObjects.length - 1].xmlContent.textContainers[0];

                    // 位置と大きさを入れる
                    baselineObjectGeometricBounds = copySourceObject.geometricBounds;

                    // ページの位置と大きさを入れる
                    baselineObjectPageBounds = copySourceObject.parentPage.bounds;

                    // 選択に最後の選択の要素を追加
                    selectObjects[selectObjects.length - 1].select(SelectionOptions.addTo);

                    // trueを入れる
                    baselineObjectFlg = true;
                }
            }
        }

        // falseの場合
        if(baselineObjectFlg == false){

            // 選択状態を元に戻す
            app.activeDocument.selection = selectObjects;

            // 結果表示
            alert("最後に選択された要素のページ（ページアイテム）を取得出来ませんでした。",scriptName);

            // 終了
            exit();
        }

        // 配置ページ番号
        var placePageNumber;

        // 配置数
        var placeNumber = 0;

        // 配置の位置と大きさ
        var placeBounds;

        // 選択の数引く１だけ繰り返す
        for(var i = 0; i < selectObjects.length - 1; i++){

            // 選択が要素の場合
            if (selectObjects[i].constructor.name == "XMLElement"){

                // ストーリーのコンストラクタ名を取得する関数を使い結果がXMLストーリー（ページアイテムがない）の場合
                if(getStoryConstructorName(selectObjects[i]) == "XmlStory"){

                    // placePageNumberAssignAttributeName名の属性がある場合
                    if(selectObjects[i].xmlAttributes.itemByName(placePageNumberAssignAttributeName).isValid == true){

                        // 属性の値が正数の場合
                        if(selectObjects[i].xmlAttributes.itemByName(placePageNumberAssignAttributeName).value.match(/^[1-9][0-9]*$/) != null){

                            // 属性の値を入れる
                            placePageNumber = selectObjects[i].xmlAttributes.itemByName(placePageNumberAssignAttributeName).value;

                            // ページの数だけ繰り返す
                            for(var ii = 0; ii < app.activeDocument.pages.length; ii++){

                                // ページが存在する場合
                                if(app.activeDocument.pages[ii].name == placePageNumber){

                                    // 配置の位置と大きさに位置と大きさを入れる
                                    placeBounds = assignBounds(baselineObjectGeometricBounds,baselineObjectPageBounds,app.activeDocument.pages[ii].bounds)

                                    // 配置
                                    selectObjects[i].placeIntoCopy(app.activeDocument.pages[ii],[placeBounds[0],placeBounds[1]],copySourceObject);

                                    // 配置数を追加
                                    placeNumber++;
                                    
                                    // 繰り返しを抜ける
                                    break;
                                }
                            }
                        }
                    }
                }
            }
        }

        // 結果表示
        alert("指定の元の要素と配置された要素を選択しました。" + "\r" + "配置予定数（最後の選択を除いた数） " + (selectObjects.length - 1) + "\r" + "配置数 " + placeNumber,scriptName);
    }

//スクリプト動作指定（一つのアンドゥ履歴にする、及び、アンドゥ名の指定）の続き
}, ScriptLanguage.JAVASCRIPT, [scriptName], UndoModes.ENTIRE_SCRIPT, scriptName);

/* ストーリーのコンストラクタ名を取得する関数、引数（オブジェクト）の宣言 */
function getStoryConstructorName(anyObject) {

    // parentStoryプロパティが存在する場合
    if (anyObject.hasOwnProperty("parentStory") == true) {

        // エラー処理
        try{

            // parentStoryの値がある場合
            if (anyObject.parentStory) {

                // コンストラクタ名を戻す
                return anyObject.parentStory.constructor.name;
            }

        // エラーの場合
        }catch(e){

            // 抜ける
            return;
        }

    // Applicationの場合
    } else if (anyObject.constructor.name == "Application") {

        // 抜ける
        return;
    }

    // オブジェクトの階層を一つ上げて再帰関数
    return getStoryConstructorName(anyObject.parent);
}
/* ストーリーのコンストラクタ名を取得する関数の宣言終了 */

/* 位置と大きさを指定する関数、引数（元のオブジェクトの位置と大きさ、元のオブジェクトのページの位置と大きさ、選択オブジェクトのページの位置と大きさ）の宣言*/
function assignBounds(baselineObjectGeometricBounds,baselineObjectPageBounds,selectObjectPageBounds){

    // 指定するオブジェクトの位置と大きさ
    var assignObjectBounds = [0,0,0,0];

    // 指定するオブジェクトの位置と大きさの左上のYに基準のオブジェクトの位置と大きさの左上のY引く基準のオブジェクトのページの位置と大きさの左上のY足す選択オブジェクトのページの位置と大きさの左上のYを入れる
    assignObjectBounds[0] = baselineObjectGeometricBounds[0] - baselineObjectPageBounds[0] + selectObjectPageBounds[0];

    // 指定するオブジェクトの位置と大きさの左上のXに基準のオブジェクトの位置と大きさの左上のX引く基準のオブジェクトのページの位置と大きさの左上のX足す選択オブジェクトのページの位置と大きさの左上のXを入れる
    assignObjectBounds[1] = baselineObjectGeometricBounds[1] - baselineObjectPageBounds[1] + selectObjectPageBounds[1];

    // 指定するオブジェクトの位置と大きさの左上のYに基準のオブジェクトの位置と大きさの左上のY引く基準のオブジェクトのページの位置と大きさの左上のY足す選択オブジェクトのページの位置と大きさの左上のYを入れる
    assignObjectBounds[2] = baselineObjectGeometricBounds[2] - baselineObjectPageBounds[0] + selectObjectPageBounds[0];

    // 指定するオブジェクトの位置と大きさの左上のXに基準のオブジェクトの位置と大きさの左上のX引く基準のオブジェクトのページの位置と大きさの左上のX足す選択オブジェクトのページの位置と大きさの左上のXを入れる
    assignObjectBounds[3] = baselineObjectGeometricBounds[3] - baselineObjectPageBounds[1] + selectObjectPageBounds[1];

    // 位置と大きさを戻す
    return assignObjectBounds;
}
/* 位置と大きさを指定する関数の宣言終了*/
~~~