eclipse

ATF jsEvalView

gonGon 2010. 10. 18. 17:21
ATF에는 Firebug처럼 javascript를 입력해서 실행시킬 수 있는 view가 있다.
어떤 방식으로 작동하는지 살펴보자.

view에 대응하는 page객체는 JSEvalPage이다.
createControl() 에서 화면요소를 구성하고, 하단에서 아래처럼 document와 통신할 부분을 초기화해준다.

evaluator.init(webBrowser.getDocument());

Evaluator class의 객체 evaluator의 init() method에서 javascript가 evalute되는 과정은 다음과 같다.

1) EVAL_READY, EVAL_DONE, EVAL_ERROR event에 대한 eventhandler를 document에 등록한다.
    EVAL_READY - ATF_Eval.js가 document dom tree에 추가되면 ATF_Eval.js에서 호출.
    EVAL_DONE - ATF view에서 javascript + enter 입력하고 javascript가 실행된 후에 호출.
    EVAL_ERROR - javascript실행 중 error가 나면 호출.


2) ATF_Eval.js를 읽어들여 document HEAD에 붙인다.
   ATF_Eval.js에 있는 function객체는 "___ATF_INTERNAL__EVAL" id로 등록된다.
   ATF_Eval.js는 loading되면 init()을 실행한다.
   init()에서는 display:none 으로 DIV를 생성하여 INPUT, TEXTAREA를 만들어 붙인 후,
   ATF_EVAL_READY 이벤트를 발생시킨다. 
   Evaluator에서는 이벤트핸들러 handleEvalReady()가 작동하여 아래처럼 INPUT의 참조자를 얻어온다.

   protected void handleEvalReady(nsIDOMEvent event) {
evalIn = (nsIDOMHTMLInputElement) event.getTarget().queryInterface(
nsIDOMHTMLInputElement.NS_IDOMHTMLINPUTELEMENT_IID);
        // no longer need this listener
event.getCurrentTarget().removeEventListener(EVAL_READY, listener, true);
   }

   
3) 입력 component를 만들고 enter에 대한 eventhandler를 붙인다.
   enter가 발생하면 view의 입력창에 있는 String(eval에서 실행할 javascript구문)을 ATF_Eval.js에서 만든 INPUT에 value로 할당하고 EVAL_SET event를 발생시킨다. 
   ATF_Eval.js에서는 EVAL_SET event의 eventhandler로 eval을 실행해 준다.


4) ATF_Eval.js의 function eval()은 evaluate()실행 후, 결과를 받아 TEXTAREA영역에 출력하고 "ATF_EVAL_DONE" event를 발생시킨다. 
   Evaluator 객체의 init()에서 등록한 EVAL_DONE event의 eventhandler가 이를 처리하는데, 
   이 결과를 화면에 보여주기 위한 과정을 살펴볼 필요가 있다.


ATF의 jsEvalView에서 javascript를 입력하고 enter를 치면 Evaluator객체의 evaluate(..)함수가 실행된다. 
evalute(..) 함수는 "EVAL_SET" event를 발생시키기만 하는데 evalRet(evaluate result)를 return한다.
어떻게 된 것일까? 
아래 코드를 보자.

// setting the input node as the target tells the JavaScript to do an
// eval with the target node as context
nsIDOMEventTarget target = (nsIDOMEventTarget) node
.queryInterface(nsIDOMEventTarget.NS_IDOMEVENTTARGET_IID);
target.dispatchEvent(event);

// since this is all single threaded through the UI thread, control is
// passed to the page side
// and returns back to the Java side handler which sets evalRet. At the
// end, it all returns
// to this point.
return evalRet;

single thread이므로 dispatchEvent 이후에 제어가 UI, 즉 javascript - ATF_Eval.js 로 넘어간다. 
ATF_Eval.js에서는 evaluate()후에 ATF_EVAL_DONE event를 발생시킨다.
ATF view의 이벤트핸들러(Evaluate의 handleEvalDone())가 결과를 evalRet에 할당하게 된다.
ATF의 jsEvalView에서, enter이후 결과를 받기까지 과정이 single thread하에서 순차적으로 일어나는 것이다.