我正在写应该是一个相当简单的 Firefox 扩展。但这是我的第一个 firefox 扩展和我的第一个 javascript 程序,而且我习惯了 C 和汇编语言,没有任何东西是隐藏的,所以我很难理解会发生什么。
window.open()
我的问题将是关于我的扩展使用or创建的多个窗口中的多个执行上下文(或[部分] 缺乏)window.openDialog()
。但首先让我描述一下我的扩展在做什么,以防万一。
我的扩展程序本质上很简单,因为它不会以任何方式更改 firefox 浏览器窗口。它不会添加任何新的 GUI 元素,不会添加、删除或修改任何菜单项,也不会通过操作 firefox 浏览器中的任何小部件或控件或菜单来调用它。
我的扩展程序所做的是检测鼠标光标何时暂停,以及当鼠标暂停在文本节点上时,我的扩展程序调用window.open()
或window.openDialog()
在鼠标光标暂停的术语上方显示一个微小的、无边界的“澄清窗口”。
“澄清窗口”看起来很像一个工具提示窗口,除了它是一个小型的 Firefox 浏览器,它的内容是 HTML [如果需要的话,可以使用 javascript],所以它看起来比工具提示更好更丰富。“澄清窗口”还包含一些按钮。一个按钮创建并显示一个更大的“详细窗口”,其中包含有关鼠标光标下术语的更详细信息。另一个按钮创建并显示一个“选项窗口”,让操作员控制我的扩展程序的各个方面如何工作。这些窗口也是由我的扩展程序调用window.open()
or创建的window.openDialog()
,因此它们都是显示 HTML [如果需要,使用 javascript] 的 Firefox 浏览器窗口。
我的扩展中的所有全局/共享变量都在一个结构中,该结构在我的扩展的 javascript 程序的顶部定义和初始化。
因此,一旦安装了我的扩展程序,当有人(“操作员”)打开 firefox 浏览器时,无论 firefox 浏览器加载什么 HTML 页面,我的扩展程序都会在浏览器中运行。当鼠标光标停在文本节点上时,我的扩展程序会在鼠标光标下找到术语(单词、短语、首字母缩写词),创建一个描述该术语的 HTML 文件,然后调用window.open()
或window.openDialog()
创建“澄清窗口”并显示该 HTML文件(名义上是“clarify.html”)。
由于这个微小的、无边界的“澄清窗口”也是一个 firefox 浏览器(即使显示时没有任何 UI 元素),我的扩展也是“澄清窗口”的一部分。因此,如果操作员将鼠标光标暂停在“澄清窗口”中的某个术语上,同样的动作会再次发生。最初我的扩展代码在第一个上面显示了另一个“澄清窗口”,这个过程递归地工作。这行得通,有点可爱和优雅,但最终我认为这种行为“太过分了”。所以我改变了代码来检查鼠标是否停在“澄清窗口”中的一个词上,如果是这样,只需更新一个“澄清窗口”的内容。
我的问题适用于这些操作方式中的任何一种,但是这两种成功都暗示我不知何故,在“澄清窗口”中执行的扩展基本上独立于在原始Firefox浏览器窗口中执行的扩展......主要是因为代码按预期工作,我在编写代码时假设这两个实例是独立的。
好的,现在对于让我需要了解多个 javascript 程序/扩展的“执行上下文”如何相关(或不相关)的“困难案例”。
当鼠标停在术语上时,我的扩展程序会在术语周围插入一些简单的标记,以通过更改文本颜色来“突出显示”术语(这不会改变术语的大小,因此不会导致文本重排)。如果操作者将鼠标光标移入“澄清窗口”,则执行上下文切换到“澄清窗口”中的扩展javascript,原浏览器窗口中的扩展javascript不再接收事件(如“ mousemove
”、“ mouseover
”、 " mouseout
" 等等) --- "澄清窗口" 的执行上下文接收所有这些事件(由 安装addEventHandler()
)。
看起来这几乎不会出现问题。但确实如此。我注意到的第一个案例如下。当操作员将鼠标光标移动到“澄清窗口”的末尾,然后超出“澄清窗口”的末尾并超出“澄清窗口”时,执行 javascript 会收到一个“ mouseout
”事件。但是,如果鼠标光标随后位于桌面或某个完全不相关的应用程序创建的窗口上,那么......不会再发生任何事情。
当这种情况发生时,“澄清窗口”可以在收到“ mouseout
”事件时自行销毁,以确保被放弃的“澄清窗口”不会滞留在原来的 firefox 浏览器上。
不过,这个词在原来的firefox浏览器Woops中仍然突出显示。大问题!
这就是“执行上下文”之间的性质和关系变得至关重要的地方。
这是我想象的两种可能的解决方案,但我不知道是否应该工作,更不用说实际工作,以及随着新浏览器版本的发布可能存在哪些可靠性问题。
两种解决方案都调用window.openDialog()
而不是window.open()
打开“澄清窗口”。关键区别在于,window.openDialog()
允许传递额外的(任意)参数,然后可以通过在创建的窗口中运行的扩展程序访问这些参数。我可以想象两种解决方案:
#1:将term_highlight_remove()
函数的 [地址] 传递到window.openDialog()
. 这个函数,实际上我的扩展中的所有函数只是那个全局/共享结构的成员,但我认为这并不重要(虽然我当然不知道,因为 javascript 对我来说是一个完全的谜考虑到我的低级、面向 C 的心态)。
#2:将整个全局/共享结构的 [地址] 传递到window.openDialog()
. 然后“澄清窗口”上下文中的扩展 javascript 可能可以访问该结构中的所有变量,并且可以执行自己的term_highlight_remove()
功能,但会修改原始浏览器中属于扩展 javascript 的变量。
我感觉#2 行不通,但#1 可能。我怀疑 #2 的原因如下。term_highlight_remove()
该函数所做的一件事是style="color:#FFFF60"
从原始浏览器中的术语周围删除类似的属性。我宁愿怀疑term_highlight_remove()
在“澄清窗口”的上下文中执行不可能修改原始浏览器窗口中的 HTML。
剩下方法#1。以下是我想象它的工作原理。
当term_highlight_remove()
函数的 [address of] 在 的额外参数中传递时window.openDialog()
,我希望这不仅term_highlight_remove()
在原始浏览器的执行上下文中传递函数的地址,而且还希望 javascript 以某种方式跟踪执行上下文该功能的[地址]。
如果是这样,那么希望当“澄清窗口”中的扩展 javascript 调用传入的term_highlight_remove()
函数时,调用该函数的行为会以某种方式神奇地从“澄清窗口”的执行上下文切换到原始浏览器窗口的执行上下文.
如果确实发生了这种情况,那么term_highlight_remove()
它调用的函数应该(我希望)访问属于原始浏览器窗口的全局/共享结构中的变量,并且应该(我希望)访问和修改该结构中的 HTML 元素以修改其中的 HTML原来的浏览器。
哇!
所以问题是......这些执行上下文如何工作(在上述情况下)?
上面的#1 或#2 是否有效?如果两者都没有,我如何达到我需要的结果?