Notifying iFrame page from Firefox extension? - javascript

I'm writing a Firefox extension and need to notify an iFrame page of certain events. The iFrame page is contained within a sidebar created by the extension, and this iFrame page is controlled by me.
When I load the iFrame page, the extension code needs to send a notification and trigger something to happen within the iFrame page.
To accomplish this, I'm creating an event from the extension Javascript and firing the event, which the iFrame page is listening to.
Unfortunately, when invoking document.createEvent(), this error pops up (copied, with the quotes, straight out of Firebug):
Operation is not supported" code: "9
Any clues on the error, or suggestions on how to trigger something in an iFrame page from the extension Javascript?

Firebug helps debug web pages. From your description it appears that the problem happens in your extension, so set up the profile according to the documentation and look in the Error Console.
Other than that, remote debugging requires seeing more of your code :)

That error is NS_ERROR_DOM_NOT_SUPPORTED_ERR. Are you using the right document (the content one, not the XUL window)? Although, I'm not convinced that that would error out either (in fact, I think it should work).

This is an example of code that works for me:
var eventName = "my-event";
var event = document.createEvent('Events');
event.initEvent(eventName, true, true);
document.getElementById('my_event_listener').dispatchEvent(event)

Related

Firefox Addon How to cannot access browser page DOM from the Popup JS?

HiI am trying to develop small simple popup extension in Firefox, I am new to the Firefox extension development Framework.
I used this boilerplate to speed up this process
I Added a small button to the popup with an id = testid1 by overriding the popup.html file and adding this line
<a id="testid1" href="#" class="js-options">Test</a>
I added it the corresponding EventListener by overriding the popup.addEventListener in the popup.js file
popup.addEventListener("click", function (e) {
if (e.target && e.target.matches("#testid1 ")) {
var element_from_popup_html = document.getElementById("elementid1").value;
var element_from_web_page = document.getElementById("elementid2").value;
alert('it work');
}}
I made sure that this event lister triggers correctly and is working by using an Alert.
I am trying to get 2 elements from the DOM Element1(inside popup page), and Element2(Fromthe webbrowser)
I can't get the : element_from_web_page!!
and I have document.getElementById("elementid2") is NULL.
So After digging some more the : document here is the popup.html, How am I supposed to access this webbrowser browsed page. I used to use document keyword for this!!
Also found out that I can use the Javascript API from mozilla by using _ext2.default.and_put_the_chosen_api_here but I only need simple dom find by id?
I managed to solve my problem after reading some more about the Firefox Extensions. So basically what I was doing is managing the popup document not the webpage. In order to interact with the webbrowser current page I needed to change another type of js called a content script, which is different from the popup.js javascript file(similar to the background script) that I was editing.
So basically I had to use the communication between the background and content-script with regards to the documentation.
On the content_script.js , I interacted with the web-page using some eval function.

I can't access the web page DOM from a Chrome Extension pop up

I am struggling to access the DOM of the web page for my Chrome Extension.
In one extension I made, my extension parses the DOM from the content.js file without issue. This happens as the page loads. The user does not need to interact/open the extension at all, it just needs to be running in the backgorund.
Now I'm trying to trigger this from a button. This means the user will click the extension icon in the browser, and the popup.html will show some HTML (including the button).
This is where the problem lies for me. When I now try access the DOM (via click event of the button), it shows the popup.html's DOM, not the web page (The active tab).
So, a quick look through the docs (which I'm open to admit I struggle with) show that it could be a permissions issue. In my manifest.json file, I added
"permissions": [
"activeTab"
],
This didn't help :(
So in this new extension, I'm not using the background.js nor content.js .. I guess this is the problem, as the javascript I'm calling is embeded in the HTML pop up! This makes sense to me (as to the behaviour I'm getting).
How do I access the DOM of the active tab from the HTML pop up
The only way of accessing a page's DOM is by using a content script. Since you've set the activeTab permission you can use chrome.tabs.executeScript to inject a content script into the active tab by omitting the first parameter (the tabId).
Here is an example:
chrome.tabs.executeScript({ file: "content.js" });
I have had this same issue, I click on the button to open an popup, then how do I access the contents of the popup. Yes, you will need to use content scripts, but a trick I done to accomplish this, was when the popup is open, use window.name and get the name of that window. Then you can reference that popup window by var test = window.name('', 'name of that window'). Then you can reference the dom elements of the popup from test. Worked for me, let me know if I need to include some code to better explain.

extension using background, content and devtools together

I've been trying to figure this out from the docs and samples but there just isn't enough there yet (or maybe I'm missing something?).
I want to create a devtools panel but I still want access to the inspected window's dom like I get in content scripts. Right now my option is eval something in the context of the inspected window, but i would really rather not do that if I can avoid it. If I can just use a content script along with my devtools page/scripts that would be idea, but it doesn't seem to be working like I expect that it should - i can't seem to use the background page to send messages between my devtools page and my content script.
Also, is there a way to get those cool dom subtrees to display like they do in the elements panel or in the console along with the awesome hover/highlight feature?
UPDATE
So I can connect to the content script from the panel page by forwarding the tab id of the inspected window and pulling that out in my background page. So I have to do this
// devtools.js
chrome.extension.sendMessage({
'to': chrome.devtools.inspectedWindow.tabId,
'message': 'whatever'
});
and
//background.js
chrome.extension.onMessage.addListener(function(message,sender,callback) {
message.from = sender.tab.id;
chrome.tabs.sendMessage(message.to, message, callback);
});
And my content.js script gets the message just fine ... and i thought that the sender's tab id would work to send things back from the content script, but it doesn't. The background script gets the message but the devtools page never gets it back.
I'm having a bit of trouble figuring out how to properly debug devtools extensions as well. The content script can log to the page's console and the background script logs to the background page that you can inspect from the extensions page, but where does the devtools page log to?
The code I was originally testing works fine now with Chrome 26+ ... I think I was doing something that should have worked but didn't at the time that caused the behavior I was seeing.
#Konrad Dzwinel's comment was very helping on debugging devtools and noting that fact that this method actually should and does work. Thanks!
Just a quick update from 2016 (and Chrome 54+) for anybody who could also struggling debugging DevTools extension:
After adding custom DevTools pane successfully and showing Angular2 app in it, I found that the extension isn't connected to the page DevTools console and sources. Hitting on the page DevTools window F12 as suggested above doesn't work (have no idea if it's Chrome itself of some problems in my system), the page DevTools window is closed. But pressing Ctl+Alt+I on the page DevTools window opened one more DevTools window with the custom pane application sources and console attached.

Javascript Launch Popup and Fill a text field

I am struggling with this, hope something can shed some light.
On click of a button, I want to open a popup window, and transfer data from parent window to a text field in the popup. And, ensure popup is fully loaded before data is filled.
I tried using document.ReadyState=="complete", but it fires before the popup is fully loaded. I also tried to check the popup.body in a setTimeOut method, but to no avail.
Can you please help ?
PS: Popup window is a form from another domain !.
You won't be able to do this unless you control both domains due to XSS restrictions, but if you do control the content on both domains it's fairly simple with a bit of JS in the page you have opened in a frame.
Using window.opener in the frame will allow you to call any functions defined in the main window, this along with the seconds pages onload event is all you need to trigger a function when it loads.
If the content of the second page is not under your control the best thing you can do is an AJAX request which you will then need to be inserted into your page, this is a little nasty but will work.

Can Chrome extension content scripts access window.opener?

In my extension, I'm trying to determine whether a new tab was created as a popup by another tab and if so, which tab.
I thought I would be able to use window.opener from a content script to help figure this out. But it looks like window.opener doesn't work correctly in content scripts.
When I create a tab manually, it's window.opener is null as expected.
When a tab is created as a popup by another tab, its window.opener is undefined. I can infer from this that the tab was created as a popup, but I can't use it to figure out which tab created the new one.
Is this a known issue, and does anybody know of any workarounds?
I didn't look closely into this problem, but I think I can point you in the right direction. Content script can't access a variable from a parent window because it is sandboxed. A workaround would be to run your code directly on a page, to do this you need to inject your script inside a script tag:
Your content script would look like this:
function injectJs(link) {
var scr = document.createElement("script");
scr.type="text/javascript";
scr.src=link;
(document.head || document.body || document.documentElement).appendChild(scr);
}
injectJs(chrome.extension.getURL("inject.js"));
Now you can run your code without sandbox restrictions as if it was right on the page:
inject.js:
alert(window.opener);
I assume you would like to now pass this information back to a background page, which is another challenge as you can't use Chrome API. Good news is that content script can access DOM and listen to DOM events, so you can use them to pass information to a content script which would send it to a background page. I am pretty sure you should be able to register a custom DOM event and have your content script listening to it (haven't tried this part myself).

Categories