1

I'm currently writing WebExtension under Firefox and I've stuck on interacting with page. I have a content script that needs an access to the page variables, for example jQuery instance.

I'm accessing jQuery with

var $ = window.wrappedJSObject.$;

And this works pretty good, I can add DOM elements to page etc, but there is a problem with event handling. For example, this code works fine:

$('#nav-bar').append('<img src="..."/>'); // Works great

But when I try to add event handler, it fails

$('#button').click(function () {}); // Fails

Error message says that

Permission denied to access property "handler"

My guess is Firefox WebExtensions have some security measures that prevent from easily adding event handlers, but I've been out of luck looking what is the cause. How can I make it work?

stil
  • 5,306
  • 3
  • 38
  • 44
  • Please [edit] the question to be on-topic: include a **complete** [mcve] that *duplicates the problem*. Including a *manifest.json*, some of the background/content/popup scripts/HTML. Questions seeking debugging help ("**why isn't this code working?**") must include: ►the desired behavior, ►a specific problem or error *and* ►the shortest code necessary to reproduce it **in the question itself**. Questions without a clear problem statement are not useful to other readers. See: "**How to create a [mcve]**", [What topics can I ask about here?](http://stackoverflow.com/help/on-topic), and [ask]. – Makyen Feb 01 '17 at 18:48
  • If you are using *any* library, including jQuery, you should download that library, include it with your add-on and inject it into the content script context. You should **not** do what you are doing, which executes functions which are in the page context in the content script context. This breaks the security separation which exists between the page context and content script context. If you do do so, it is nearly certain that your add-on will be rejected in AMO review due to intentionally opening this security hole. The alternative is to load and run scripts in the page context. – Makyen Feb 01 '17 at 18:54
  • 1
    Thanks for your input, but my add-on is site-specific and will never be published in AMO. I'm aware of security implications, but this add-on is going to be for my personal use. My add-on needs exact instance of jQuery that page uses in order to work. At beginning I had running UserScript, but decided that WebExtension has some extra features I was missing. – stil Feb 01 '17 at 19:05

1 Answers1

2

Your problem is that you are attempting to define a function in the content script process (the anonymous click listener), but have it executed from the page context as an event handler. This results in the function not being available for jQuery to manipulate, nor for it to be actually added as a listener.

The correct solution to this is to keep the code which operates in the page context separate from the code that executes in the content script process. Any code which you desire to function in the page context should be handled using one of the methods described in Building a Chrome Extension - Inject code in a page using a Content script. You should then communicate back and forth between them through any of the normal available methodologies.

What I would recommend is that you download the jQuery version you desire to use, include it in your extension, and include it in the scripts which you inject as content scripts. You can then use that version of jQuery for most of what you are doing. When you really need to be manipulating the state of the page context jQuery object, you can then specifically access it through the various methods in the answer linked above. You can, if you want your extension to be Firefox only, use the window.wrappedJSObject to access the jQuery which exists in the page context for those things for which you really need to have that access. Doing so comes with its own limitations. One of which you have already encountered.

Doing what you appear to desire to do in a way that is cross-browser compatible takes about as much coding effort as dealing with the situation you fine yourself in a Firefox specific manner (there are options to do so). In addition to the benefit that it would be cross-browser compatible, also makes it a bit more future-proof.

Community
  • 1
  • 1
Makyen
  • 31,849
  • 12
  • 86
  • 121