how does javascript execution context work in firefox extensions with multiple windows?

扶醉桌前 提交于 2019-12-25 08:15:40

问题


I am writing what should be a fairly straightforward firefox extension. But this is my first firefox-extension and my first javascript program, and I'm used to C and assembly-language where nothing is hidden, so I'm having a difficult time understanding what to expect.

My question will be about multiple execution contexts (or the [partial] lack thereof) in multiple windows my extension creates with window.open() or window.openDialog(). But first let me describe what my extension is doing, in case that matters.

My extension is essentially simple in that it does not change the firefox browser window in any way. It doesn't add any new GUI elements, doesn't add, remove or modify any menu items, it isn't invoked by operating any of the widgets or controls or menus in the firefox browser.

What my extension does do is detect when the mouse cursor pauses, and when the mouse pauses over a text-node, my extension calls window.open() or window.openDialog() to display a tiny, borderless, "clarify window" just above the term the mouse cursor paused over.

The "clarify window" looks alot like a tooltip window, except being a tiny firefox browser its content is HTML [with javascript if desired], so it can look much nicer and richer than a tooltip. The "clarify window" also contains a few buttons. One button creates and displays a larger "elaborate window" that contains more elaborate information about the term under the mouse cursor. Another button creates and displays an "option window" that lets the operator control how various aspects of my extension works. These windows are also created by my extension calling window.open() or window.openDialog(), so they are both firefox browser windows that display HTML [with javascript if desired].

ALL the global/shared variables in my extension are inside a single structure that is defined and initialized at the top of the javascript program that is my extension.

So, once my extension is installed, when someone (the "operator") opens a firefox browser, my extension is running in the browser no matter what HTML page the firefox browser loads. When the mouse cursor pauses over a text node, my extension finds the term (word, phrase, acronym) under the mouse cursor, creates an HTML file that describes that term, then calls window.open() or window.openDialog() to create the "clarify window" and displays that HTML file (nominally "clarify.html").

Since this tiny, borderless "clarify window" is also a firefox browser (even though displayed without any UI elements), my extension is also part of the "clarify window". So if the operator pauses the mouse cursor over a term in the "clarify window", the same kind of action occurs again. Originally my extension code displayed yet another "clarify window" above the first, and this process worked recursively. This worked, and was kind of cute and elegant, but eventually I decided this behavior was "too much". So I changed the code to check whether the mouse paused over a term in the "clarify window", and if so, just update the contents of the one "clarify window".

My question applies to either of these ways of operation, but both these successes imply to me that somehow or other, the extension executing in the "clarify window" is essentially independent of the extension executing in the original firefox browser window... mostly because the code works as expected and I assumed the two instances were independent when I wrote the code.

Okay, now for the "difficult case" that makes me need to understand how the "execution context" of the multiple javascript programs/extensions are related (or not).

When the mouse pauses over the term, my extension inserts some simple markup around the term to "highlight" the term by changing the text color (which doesn't change the size of the term, and therefore never causes text reflow). If the operator moves the mouse cursor into the "clarify window", the execution context switches to the extension javascript in the "clarify window", and the extension javascript in the original browser window no longer receives events (like "mousemove", "mouseover", "mouseout" and so forth) --- the execution context of the "clarify window" receives all those events (installed by addEventHandler()).

It almost seemed this would not present a problem. But it does. The first case I noticed was the following. When the operator moves the mouse cursor to the end of the "clarify window", then beyond the end and outside the "clarify window", the execution javascript receives a "mouseout" event as it should. However, if the mouse cursor is then over the desktop or a window created by some completely unrelated application, then... nothing further occurs.

When this happens, the "clarify window" can destroy itself when it receives the "mouseout" event to assure the abandoned "clarify window" does not become stranded over the original firefox browser.

However, the term is still highlighted in the original firefox browser Woops. Big problem!

This is where the nature-of and relationships-between "execution contexts" becomes crucial.

Here are two possible solutions that I imagine, but I have no idea whether either SHOULD work, much less ACTUALLY work, and what reliability issues might exists as new browser versions are released.

Both solutions call window.openDialog() instead of window.open() to open the "clarify window". The key difference is, window.openDialog() allows extra (arbitrary) arguments to be passed, which can then be accessed by the extension running in the created window. I can imagine two solutions:

#1: pass [the address of] the term_highlight_remove() function into window.openDialog(). This function, and indeed all functions in my extension are just members of that global/shared structure, but I don't think that matters in any way (though I certainly don't know, given that javascript is a total freaking mystery to me given my low-level, C-oriented mindset).

#2: pass [the address of] the entire global/shared structure into window.openDialog(). Then the extension javascript in the "clarify window" context MAYBE has access to all variables in that structure, and could execute its own term_highlight_remove() function but modify the variables that belong to the extension javascript in the original browser.

I have a feeling that #2 will not work, but #1 might. The reason I am skeptical #2 works is the following. One thing the term_highlight_remove() function does is to remove an attribute that is something like style="color:#FFFF60" from around the term in the original browser. I rather suspect that executing term_highlight_remove() in the context of the "clarify window" cannot possibly modify HTML in the original browser window.

Which leaves approach #1. The following is how I fantasize this works.

When the [address of] the term_highlight_remove() function is passed in an extra argument of window.openDialog(), I would hope that somehow this not only passes the address of the term_highlight_remove() function in the execution context of the original browser, but also that somehow javascript keeps track of the execution context of that function [address].

If so, then hopefully when the extension javascript in the "clarify window" calls the passed-in term_highlight_remove() function, the act of calling that function somehow magically switches from the execution context of the "clarify window" to the execution context of the original browser window.

If this does happen, then the term_highlight_remove() function it calls should (I hope) access variables from the global/shared structure that belongs to the original browser window AND should (I hope) access and modify the HTML elements from that structure to modify the HTML in the original browser.

Whew!

So the question is... how do these execution contexts work (in the situation described above)?

And does either #1 or #2 above work? And if neither does, how to I achieve the results I require?


回答1:


Can you upload your code to github, it would be easier to understand. Also why use window and why not a panel? You can put an iframe inside the panel? Anyways you aren't receiving pointer-events below the window because its covered. Try putting in the window css pointer-events:none; on the clarify window. However because you are using window.open it probably won't work, what you need to do is use Services.ww so like:

var {utils, Cu} = Components; Cu.import('resource://gre/modules/Services.jsm'); var win = Services.ww.openWindow(null, "YOUR_CLARIFY.HTML_URL_HERE", "_blank", "chrome", null);

when this window opens set the style of it to pointer-events:none

Now to make it not work inside the calrifyWindow, just add to the top of your code:

if (document.location.indexOf('clarify.html') > -1) {
    return;
}


来源:https://stackoverflow.com/questions/22167458/how-does-javascript-execution-context-work-in-firefox-extensions-with-multiple-w

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!