Skip to main content
Legend
August 13, 2023
解決済み

オブジェクトが何のイベントに反応するか調べたい(ExtendScript/UXP)

  • August 13, 2023
  • 返信数 4.
  • 1128 ビュー

appやdocumentなどのオブジェクトが,何のイベントに対応していて捕捉できるか調べたいです。効率よく調べる方法はありますか?

 

イベント一覧を見てもいまいちどんなときに発動するのかわかりません。現状,対象オブジェクトにすべてのイベントリスナーを追加し,手動で変化を起こして反応を観察しています。

 

// 例:app.alignDistributePreferencesの変化を何のイベントで捕捉できるか調べる
// 結果:反応するイベントなし

// preact
import { h } from 'preact' ;
import { useEffect } from 'preact/hooks' ;

// adobe
import * as InDesign from 'indesign' ;
const { app } = InDesign ;

const EventList = [
  'beforePlace', 
  'afterPlace', 
  'afterLinksChanged', 
  'afterNew', 
  'beforeDelete', 
  'afterDelete', 
  'beforeUpdate', 
  'afterUpdate', 
  'beforeEmbed', 
  'afterEmbed', 
  'beforeUnembed', 
  'afterUnembed', 
  'beforeMove', 
  'afterMove', 
  'onInvoke', 
  'beforeInvoke', 
  'afterInvoke', 
  'beforeDisplay', 
  'beforeQuit', 
  'afterQuit', 
  'afterContextChanged', 
  'afterSelectionChanged', 
  'afterSelectionAttributeChanged', 
  // 'beforeDeactivate', 
  // 'afterActivate', 
  'afterOpen', 
  'beforeClose', 
  'afterClose', 
] ;

export const App = () => {
  const targetObject = app.alignDistributePreferences ;

  const handleEvent = (event) => {
    console.log(event.eventType) ;
  } ;

  const addListeners = () => {
    for(let eventLabel of EventList) {
      try {
        targetObject.addEventListener(eventLabel, handleEvent) ;
      } catch(e) {
        // skip
      }
    }
  } ;

  const removeListeners = () => {
    console.log('remove') ;
    for(let eventLabel of EventList) {
      try {
        targetObject.removeEventListener(eventLabel, handleEvent) ;
      } catch(e) {
        // skip
      }
    }
  } ;

  // componentDidMount
  useEffect(() => {
    console.log('init') ;
    addListeners() ;

    // componentDidUnmount
    return removeListeners ;
  }, []) ;

  return (
    <div>
      <sp-button
        onClick={removeListeners}
      >
        Remove Events
      </sp-button>
    </div>
  ) ;
} ;

 

このトピックへの返信は締め切られました。
解決に役立った回答 kawamoto_α

InDesignで取得可能なイベントは
https://developer.adobe.com/indesign/dom/api/e/Event/
では網羅されていなくて、

https://developer.adobe.com/indesign/dom/api/d/DocumentEvent/
https://developer.adobe.com/indesign/dom/api/i/ImportExportEvent/
https://developer.adobe.com/indesign/dom/api/m/MutationEvent/
https://developer.adobe.com/indesign/dom/api/p/PrintEvent/

あたりも見る必要があります。

 

お~まちさん、Ten Aさんがおっしゃっているように、ほとんどのイベントは親オブジェクトに伝搬していくので、appにイベントリスナを置いとけば捕まえられます。

 

捕まえられないのは”This event does not bubble”って書いてあるやつです。メニューアクションのafterInvokeとかがそうですね。

返信数 4

kawamoto_α
kawamoto_α解決!
Participating Frequently
August 21, 2023

InDesignで取得可能なイベントは
https://developer.adobe.com/indesign/dom/api/e/Event/
では網羅されていなくて、

https://developer.adobe.com/indesign/dom/api/d/DocumentEvent/
https://developer.adobe.com/indesign/dom/api/i/ImportExportEvent/
https://developer.adobe.com/indesign/dom/api/m/MutationEvent/
https://developer.adobe.com/indesign/dom/api/p/PrintEvent/

あたりも見る必要があります。

 

お~まちさん、Ten Aさんがおっしゃっているように、ほとんどのイベントは親オブジェクトに伝搬していくので、appにイベントリスナを置いとけば捕まえられます。

 

捕まえられないのは”This event does not bubble”って書いてあるやつです。メニューアクションのafterInvokeとかがそうですね。

sttk3作成者
Legend
August 21, 2023

ありがとうございます。alignDistributePreferencesの場合,もしかしたらMutationEventのafterAttributeChangedが反応するかもしれません(未検証)。

 

bubbleは意味を知りませんでしたがそういう意味でしたか。イベントが親要素に泡のように浮上していくイメージのようですね。参考になりました。

Ten A
Community Expert
Community Expert
August 17, 2023

どのアプリケーションもイベント周りは謎が多いです(^-^;

Ten A
Community Expert
Community Expert
August 17, 2023

このあたりの仕様はExtendScriptと一緒ですから大体はバブリングしますのでおーまちさんの言われる通りトップレベルオブジェクトでトラップ可能ではないかと思います。
例外として、eventListener周りのイベントはバブリングしませんのでリスナー自体をトラップする必要があります。

ただ、appに当てちゃうとぜ〜んぶ反応するのでテストの際はdocumentに当ててテスト用のドキュメント以外に影響が出ないようにすることが多いです。

たとえば、以下のような構成で…

 

var listner = app.activeDocument.addEventListener (
    ‘afterPlace’,
    function (ev){
        var tg = ev.target;
        var mybnds = tg.geometricBounds;
        tg.geometricBounds = [mybnds[0],mybnds[1],mybnds[0]+30,mybnds[1]+30];
        tg.fit (FitOptions.proportionally);
        tg.fit (FitOptions.centerContent);
        });
listner.name = ‘testEvent’;

 

sttk3作成者
Legend
August 17, 2023

なるほど,特定の書類に影響を封じ込められるのはいいですね。実は当初書いたコードはイベントの削除が不十分で,アプリ終了まで残っていたのでこの対策の重要性を実感しました。ありがとうございます。

Omachi
Legend
August 13, 2023

私がイベントを取得する際は、appオブジェクトにすべてのイベントリスナを設定して、手動操作しています。

イベントは上位オブジェクトに伝播するのでappオブジェクトだけに設定して問題ないと思います。

発生したイベントのEvent.targetもしくはEvent.parentで、どのオブジェクトで発生したかわかるので。

(自信がないので別の方の意見も聞きたいです)

sttk3作成者
Legend
August 13, 2023

すべてのイベントリスナーを設定する方針は一緒なのですね。appだけに網を張っていれば良いなら少し楽になります。ありがとうございます。

 

私もほかのかたの意見も聞いてみたいので,ここのサイトに解説がある・自分はこうしているなどの声を引き続き募集しております。