2014-05-24 1 views
1

일부 웹 페이지의 DOM을 사용하는 확장 프로그램을 만들려고합니다. 내 웹 페이지와 Firefox 크롬에서 맞춤 전역 컨텍스트로 스크립트를 실행하는 방법은 무엇입니까?

document.getElementById("appcontent").addEventListener("DOMContentLoaded", function(e) { 
    _this._onPageLoad(e); 
}, true); 

그러나 _onPageLoad에서

내 글로벌 컨텍스트 글로벌 윈도우 (ChromeWindow)는 기능이 아닌 창

가 나는 코드가 있습니다. _onPageLoad를 이벤트가 발생한 곳 (웹 페이지)의 전역 컨텍스트로 실행하고 여기에 인수를 전달하려면 어떻게해야합니까?

감사합니다.

답변

1

글쎄, 오버레이 스크립트는 최상위 창 (예 : ChromeWindow)의 컨텍스트에서 실행됩니다.

그러나 다소 다른 컨텍스트를 시뮬레이트합니다.

_this._onPageLoad = function(window, document, e) { 
    // Called as .call(window, window, window.document, e); 
    // this === window === <content window> 
    // document === <content document> 
}; 

document.getElementById("appcontent").addEventListener("DOMContentLoaded", function(e) { 
    let win = e.originalTarget; 
    if (win.ownerDocument) { 
     win = win.ownerDocument; 
    } 
    if (win.defaultView) { 
     win = win.defaultView; 
    } 
    _this._onPageLoad.call(win, win, win.document, e); 
}, true); 

이 부를 것이다 당신의 _onPageLoad와 적절한 이벤트의 부하를 나타내는 문서에 속하는 this, windowdocument. 이 체계는 실제로 글로벌을 재설정하지 않으므로 addEventListener은 여전히 ​​최상위 창을 참조합니다. 또한 스크립트는 샌드 박스에서 실행되지 않으며 여전히 전체 권한을 갖습니다. 결국 결국 조금 더 편리해질뿐입니다.

실제로는 Sandbox을 설정하고 사용할 수도 있지만 이는 다소 복잡합니다. 기본 아이디어는 적절한 권한 (전체 권한 또는 콘텐츠 권한)을 선택하고 샌드 박스를 구성하고 sandboxPrototype.evalInSandbox(...)이라는 콘텐츠 창을 제공하는 것입니다. 이것은 다소 SDK이 콘텐츠 스크립트를 위해 내부적으로 수행하는 작업입니다.하지만 실제 보안 경계 (예 : 사용자가 제공하거나 원격 스크립트를 실행해야하는 경우)를 필요로하지 않는 한 일반적으로 과도합니다.

Lpr2.prototype._evalInSandbox = function(script, doc, data) { 
    var sandbox = new Components.utils.Sandbox(doc.defaultView); 
    sandbox.unsafeWindow = doc.defaultView.window.wrappedJSObject; 
    sandbox.window = doc.defaultView.window; 
    sandbox.document = sandbox.window.document; 
    sandbox.__proto__ = sandbox.window; 
    var functionName = 'execute_' + script.name; 
    var functionText = 'function ' + functionName + script.run.toString().substring(8); 
    functionText += '; window.lpr2data = ' + JSON.stringify(data) + '; ' + functionName + '(window, document, Zepto);'; 
    Services.scriptloader.loadSubScript('chrome://*/content/lib/zepto.min.js', sandbox, 'UTF–8'); 
    Components.utils.evalInSandbox(functionText, sandbox); 
} 

나쁜, 그러나 이것은 나를 위해 단 하나의 작업 solutuion입니다 :

+0

답장을 보내 주셔서 감사합니다. 필자의 경우 필자는 userscripts를 실행하는 것을 거부합니다. 샌드 박스가 어떻게 작동하는지 이해하려고 노력하고 있지만 샌드 박스에서 스크립트를 실행하는 유일한 방법은 이해합니다 .- 문자열로 변환하십시오. ( 또한 ChromWindow에 포함 된 Zepto 라이브러리에 문제가 있습니다. – rndm

+0

XUL 오버레이 애드온에서 직접 재료를 다시 발명하는 대신 SDK 및 해당 컨텐츠 스크립트 ('page-mod')를 사용하는 것이 더 나을 것 같네요. – nmaier

+0

불행히도 page-mod는 불편합니다. 나. – rndm

0

내 솔루션입니다.

관련 문제