0

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?

honestann
  • 1,374
  • 12
  • 19
  • can you please share in this SO topic http://stackoverflow.com/questions/22156879/looking-for-an-addon-to-automatically-select-all-instances-of-selected-word-in-t/22163697 how to highlighting words in the document, this guy was asking that question – Noitidart Mar 04 '14 at 13:49

1 Answers1

0

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;
}
Noitidart
  • 35,443
  • 37
  • 154
  • 323
  • Well, part of my reply is: I'm a firefox-extension novice AND a javascript novice. But the content of your post makes me believe your impression of my problem is different than the problem I actually have. I need to get pointer events over ALL of my windows, because I want the services my extension provides to work in ALL of those windows. The problem is when the mouse cursor exists the "clarify window" into the desktop area... at which point my extension gets NO more events, and thus cannot be stimulated to remove the highlight from the term in the browser window. – honestann Mar 05 '14 at 07:56
  • I don't know what a panel is, but I'm guessing a panel cannot appear exactly where I want it (directly above the term the mouse cursor paused over), and perhaps it doesn't contain HTML or execute my extension (while my extension needs it to contain HTML and needs it to execute my extension so my extension services are provided in ALL the windows my extension creates (the "clarify window", the "elaborate window" and the "option window"). Or maybe I am not understanding your message, which would not be surprising because I am indeed a notice at firefox-extensions and javascript. – honestann Mar 05 '14 at 08:00
  • Plus... though I appreciate your comments... I really am curious about how the execution contexts work in the kind of situation I describe. – honestann Mar 05 '14 at 08:01
  • @honestann Compile your addon and post it on github or dropbox or something. A panel is meant exactly for showing up where you mouse is and with greater control, it even comes with an arrow install this [HERE](https://gist.github.com/Noitidart/9266173) you will see new icon in url bar and click it you will see pretty panel. Your question is extremely long, make it succinct and people will help you out. Otherwise topics like this go unanswered. – Noitidart Mar 05 '14 at 09:51
  • Okay, I see the "panel" can display HTML. However, is my extension running in the panel as well as the main firefox browser window? If not, the panel won't work for me. As for posting my code, I'm in the middle of screwing around with it so it doesn't work right now. But in a couple days maybe I'll do that and try to attract your attention again. – honestann Mar 06 '14 at 15:41
  • Yeah in panel to dispaly the html you have to add an iframe and you're attaching your addon to all page loads it looks like. If you're not attaching to all frames then thats a problem, because if a html window has frames then its not going to have your addon. – Noitidart Mar 06 '14 at 17:48
  • Okay, thanks. Looks like I have to stick to my current approach, and create the windows with `window.openDialog()`. Before I post any code, I'll probably try passing the [address of] my `term_destroy()` or `term_highlight_destroy()` function, then call it just before the clarify window closes itself (when the mouse cursor exists the clarify window). Trying this will tell me at least part of how the execution context stuff works. – honestann Mar 07 '14 at 10:45
  • unregister top level windows then, because if your windows are open and user closes firefox browser window, firefox wont close, u'll basically glitch people out and they wont know why their firefox is hanging. – Noitidart Mar 07 '14 at 10:56
  • Let me see if I understand this. If someone closes the firefox browser and my extension has one or more windows open, that would prevent the firefox browser (and my windows) from being terminated? How about the following approach. When my extension executing in the firefox browser receives an event something like `document_unload` or something, it checks `window.closed` (on its own window == firefox browser), and if the return value is `true == closed`, it closes all the window it created. Does that work? If not, is there a way for my extension (any window event) to detect close? – honestann Mar 07 '14 at 23:05
  • You have to watch for all windows and on close determine if there are any non browser windows. However its tricky because what if another addon uses windows that intend to be open till physically closed. Your solution is to unregister top level windows see here http://stackoverflow.com/questions/21926453/how-to-insert-xul-panel-so-doesnt-minimize-with-window – Noitidart Mar 08 '14 at 07:25