【发布时间】:2014-04-05 17:20:44
【问题描述】:
我正在编写一个相当简单的 Firefox 扩展。但这是我的第一个 firefox 扩展和我的第一个 javascript 程序,而且我已经习惯了 C 和汇编语言,什么都没有隐藏,所以我很难理解会发生什么。
我的问题是关于我的扩展使用window.open() 或window.openDialog() 创建的多个窗口中的多个执行上下文(或[部分] 缺乏)。但首先让我描述一下我的扩展程序正在做什么,以防万一。
我的扩展程序本质上很简单,因为它不会以任何方式更改 firefox 浏览器窗口。它不添加任何新的 GUI 元素,不添加、删除或修改任何菜单项,也不通过在 firefox 浏览器中操作任何小部件或控件或菜单来调用它。
我的扩展程序所做的是检测鼠标光标何时暂停,当鼠标在文本节点上暂停时,我的扩展程序调用window.open() 或window.openDialog() 以在上方显示一个微小的、无边框的“澄清窗口”鼠标光标暂停的词。
“澄清窗口”看起来很像工具提示窗口,除了它是一个小型的 firefox 浏览器外,它的内容是 HTML [如果需要的话,还可以使用 javascript],因此它看起来比工具提示更好、更丰富。 “澄清窗口”还包含一些按钮。一个按钮创建并显示一个更大的“详细窗口”,其中包含有关鼠标光标下术语的更详细信息。另一个按钮创建并显示一个“选项窗口”,让操作员控制我的扩展程序的各个方面如何工作。这些窗口也是由我调用window.open() 或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()函数的[地址]在window.openDialog()的额外参数中传递时,我希望这不仅在原始浏览器的执行上下文中传递term_highlight_remove()函数的地址,而且不知何故,javascript会跟踪该函数[地址]的执行上下文。
如果是这样,那么希望当“澄清窗口”中的扩展 javascript 调用传入的 term_highlight_remove() 函数时,调用该函数的行为会以某种方式神奇地从“澄清窗口”的执行上下文切换到执行原始浏览器窗口的上下文。
如果确实发生了这种情况,那么它调用的term_highlight_remove() 函数应该(我希望)访问属于原始浏览器窗口的全局/共享结构中的变量,并且应该(我希望)访问和修改其中的 HTML 元素在原始浏览器中修改 HTML 的结构。
哇!
所以问题是......这些执行上下文是如何工作的(在上述情况下)?
上面的 #1 或 #2 是否有效?如果两者都没有,我如何达到我需要的结果?
【问题讨论】:
-
你能分享一下这个SO主题stackoverflow.com/questions/22156879/…如何突出显示文档中的单词,这个人在问那个问题
标签: javascript html firefox firefox-addon executioncontext