2014-12-29 17 views
1

부트 스트랩 파이어 폭스 확장 기능을 작성하고 있습니다. 파이어 폭스 개발자 에디션 v36.2a 사용하기이상한 도마뱀 붙이는 행동 (js 모듈 사이에 nsiDomWindows 배열을 전달하려고 시도)

나는 두 가지 문제점이 있는데, 나는 이해할 수 없다. 첫 번째 것, 단순한 성가심 :

내 부트 스트랩 Console.utils.imports 내 응용 프로그램을로드하는 js 파일 (네임 스페이스 개체를 만들고 다른 모든 js 파일을 네임 스페이스의 속성으로 가져옵니다.) 다른 모든 파일에는이 네임 스페이스 파일이 포함되어 있습니다. 서로 액세스 할 수 있습니다. 심지어 상태를 저장하고 모든 것이 노드 캐쉬 모듈과 매우 유사하게 작동합니다. 예를 들어 전체 애플리케이션에서 공유되는 모든 클래스의 객체가 하나만있는 것처럼 보입니다. 이제는 이런 일이 발생합니다 :

내 네임 스페이스 파일은 다음을 수행합니다.

namespace.console = Components.utils.import('you know the one/console.jsm') 
namespace.Services = Components.utils.import('you know the one/Services.jsm') 
namespace.Cu  = Components.utils 

이제 가져 오는 다른 파일 파일, 네임 스페이스 개체를 얻을 수 있지만 namespace.Cu 정의되지 않습니다. console.log(namespace) 괜찮아요 그러나 나를 확장하고 그 모든 속성을 볼 수있는 Cu, 보여줍니다 ... 등 다른 모든 것들 (콘솔, 서비스, 내 자신의 클래스) 괜찮아요,하지만 CC에서, CI 등 구성 요소에서 시도 - "정의되지 않은 .

내 응용 프로그램의 다른 장소에서 nsiDomWindows 배열을 반환하는 함수 (파일 A에 있음)가 있습니다. 파일 B의 함수가이 파일을 호출하고 도착하면 유사한 이야기를합니다. 콘솔에서 모두 잘 보이는 Array, 볼 수있는 ChromeWidows가 있습니다. 하지만 실제로 더 이상 배열이 아니며 object 유형이며 array [0]은 정의되지 않습니다. 두 클래스를 같은 파일에 넣으면 괜찮습니다. 더 혼란

, 난 이미 다른 파일에이 방법을 사용하고있는 모든 괜찮다고 생각 :이 도마뱀의 보안 조치와 함께해야 할 일을했을 경우 나도 궁금

// A.js 
// 
function A() 
{ 
    b = new B() 
    c = new C() 

    let windows = b.windowList() // works fine, yields an actual valid array 
            // with valid windows inside 
    c.doSomething()    // broken, see below 
    c.doSomething(windows)  // passing it as a parameter 
            // doesn't help, still broken 
} 

// B.js 
// 
function B() 
{ 
    this.windowList = function windowList() 
    { 
     let result = [] 

     // get open windows from nsiWindowMediator 
     // foreach... 
     // 
     result.push(nsiDomWindow) 

     console.log(typeof result) // Array -> it's completely valid here 

     return result 
    } 
} 


// C.js 
// 
function C() 
{ 
    this.b = new B() 


    this.doSomething = function doSomething(windows) 
    { 
     if(! windows) 

      windows = this.b.windowList() 


     console.log(windows) // in the console shows: 
           // Array[ ChromeWindow -> about:home ] 
           // I can inspect all it's properties, looks ok 

     console.log(typeof windows)   // object 
     console.log(windows.constructor.name) // undefined 

     console.log(windows[ 0 ] )   // undefined 

     // looping over the object properties shows that it does 
     // have 1 property called '0' which points at undefined 
     // note: there was only one open window in the array. 
    } 
} 

// Note: the order in which I use Components.utils.import on these is B, C, A 

,하지만 래퍼 개체가 없습니다 어디에서나 볼 수 있으며 afaik는 크롬 코드에서 콘텐츠 코드 만 보호해야합니다 (이 코드는 모두 크롬 코드입니다).

그것은 함수의 반환 값이 호출의 양면에서 동일하지 않아야하는 합리적인 이유를 생각할 수 없기 때문에 저를 좌절시키는 종류의 버그입니다.

운좋게도 해결 방법이 있습니다. 필자의 make 파일에 모든 js 파일을 연결하고 Components.utils를 한 번만 수행하면됩니다. 내가 사용해야하는 모질라 API가 적을수록 더 행복하고 생산적 일 것입니다.

모질라 코드의 오류도 표시됩니다. Console.jsm에서 "shouldLog가 함수가 아닙니다."라는 오류가 발생했습니다. 이 함수는 해당 파일에서 더 높은 위치에 명확하게 정의되어 있습니다. 오류를 throw하는 줄은 반환되는 익명의 함수입니다. 그 범위를 의심 할 여지없이 상속해야하지만 그렇지 않습니다. 무언가 반환 가치를 망가뜨릴 수 있으며 이것이 관련되어있을 수 있습니다.

본 발명은 앞서 언급 된 문제점들 중 제 1 문제점을 나타내는 샘플 애드온이 첨부 된 bug on bugzilla을 출원 하였다.

갱신는 :

미안 해요, 나는 두 가지를 혼동. Cu의 첫 번째 경우에 어떤 일이 발생했는지 알 수 없습니다. 방금 Cu가 내 네임 스페이스에 추가되기 전에 문제가 발생한 파일을로드했으며 전역 범위에서 const {console, Services, Cu} = 네임 스페이스를 수행 했으므로 속성이 작성되기 전에 실제로 평가되었습니다.그것에 관한 혼란스러운 부분은 콘솔에 참조를 유지한다는 것입니다. 문제의 코드가 네임 스페이스를 기록하기 전에 나에게 묻는다면 불행한 디자인 선택입니다. 나중에 상황을 볼 수 있습니다. 고려하지 않았다.

아직 한 함수가 다른 함수를 수신하는 수신 함수로 어떻게 완벽하게 건전한 값을 반환하는지, Console.jsm에서 선언 한 함수가 상속받은 함수에서 더 이상 존재하지 않는 것을 설명하지 못합니다. 범위.

전반적으로 첫 번째 문제는 다른 문제와 관련이 없습니다. 그러나 나는 다른 것을 설명하기 위해 재현 할 수있는 작은 애드온을 만들 수는 없다. 2. 내가 생각하는대로 그것을 업로드 할 것이다. Btw은

:

let a = { some: "value" } 

console.log(a) 

delete a.some 

// output: Object { } 

을 목적으로 (일반적으로는 주 목적이다) 콘솔은 한계가있어 가지고 있으며,에 그것은 일반적으로 더 나은 디버깅 : 콘솔에 의해 함정 쉽게 (자바 스크립트 스크래치 패드에 다음을 넣어) 볼 수 있습니다 디버거에서 중단 점을 설정하거나 사용하십시오. JSON.stringify

답변

1

필자는 앞에서 언급 한 모든 문제를 올바로 언로드하지 못하도록 제한했다고 생각합니다. 나는 제거하지 않은 eventlisteners를 가지고 있었고, 그들이 해고되었을 때, 사물이나 범위는 무효화 될 수 있습니다.

확장 자동 설치 프로그램을 사용하면 제대로로드되지 않은 Addon을 다시로드 할 때 신뢰할 수없는 상태의 Addon 코드가 만들어지기 때문에이 문제를 더욱 심각하게 만듭니다.

shouldLog는 함수가 아니기 때문에 Components.utils.unload로로드 한 모든 모듈을 언로드해야한다고 생각해서 Console.jsm을 언로드했습니다.

try-catch 블록에서 모든 진입 점을 내 소프트웨어로 래핑 한 결과 이제는 더 원활하게 실행됩니다. 이제 코드를 업데이트 한 후 addon을 제거하고 Firefox를 다시 시작해야 할 필요가 거의 없습니다.

재미있는 일간의 디버깅 같이 좋은 것은 어디에도 없습니다 ...

0

나는 그것을 전혀 읽지 못했지만 : 첫 번째 문제는 잘못 가져 오는 것입니다. 당신이 Cu.import에서 보낸 VAR에 특정 네임 스페이스에 가져하려면

이처럼 수행해야합니다

Cu.import에게 ('자원 : //gre/modules/ctypes.jsm를' , 네임 스페이스);

var에 ㅋ 필요 없음 = Cu.import

Console.jsm 및 Services.jsm 테 같은 일이라는 VAR를 내보낼 수 있습니다.

그냥 ('rsource : //gre/modules/ctypes.jsm') Cu.import을에도 수 있습니다 이렇게 및 Cu에 대한 액세스를 얻을 또한

ctypes.blah

처럼 사용하여 시작 :

var {Cu: utils, Cr: results} = Components 

다음은 하나의 범위에서 모듈을 변경하면 해당 범위에서 다시 Cu.import를 수행 할 때까지 다른 범위에서 변경되지 않는다고 생각합니다.

+0

감사합니다. 수입 방법이 다르다는 것을 알고 있습니다. 모두 작동합니다. 문제가 아닙니다. 내가 가져 오기 위해 내 네임 스페이스를 전달하지 않는 이유는 콘솔이 예를 들어 ConsoleAPI를 내 보낸다는 것입니다.그러나 나는 첫 번째 문제를 알았고 나머지는 똑같은 문제가 아닙니다. 나는 그것을 업데이트에서 설명했다. – nus