I'm trying to run a hosted script with content privileges in my Firefox extension. To do this, I create a content iframe in the hidden window pointed at a html file that pulls the script. This script requires the 'history' be available, but the iframes created in the hidden window have no history for some reason.
Chromebug reports this for the iframe's contentWindow.history:
object does not support history (nsIDOMHistory)
And the script gives this error when its not available:
Error: Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsIDOMHistory.length]
Any ideas?
It turns out that the hidden window's URL used to be about:blank, but this was apparently a security flaw, so it is now resource://gre/res/hiddenWindow.html (or resource://gre-resources/hiddenWindow.html on trunk) so it doesn't have the chrome privileges that a XUL browser element needs in order to be able to wire up its own session history, or even to access its own content document.
Even using a XUL iframe element you have to be careful since none of its properties work, again because it is running without chrome privileges. So you have to do stuff like iframeElement.boxObject.QueryInterface(Components.interfaces.nsIContainerBoxObject).docShell.QueryInterface(Components.interfaces.nsIInterfaceRequestor).getInterface(Components.interfaces.nsIDOMWindow) to retrieve its content window.
A <browser type="content"> will automatically wire up session history by default, while an <iframe type="content"> will not, but you could always wire it up yourself manually.
Don't forget to ensure that your element is created in the XUL namespace. I believe the hidden window is the about:blank HTML document except on the Mac.
Related
First of all, I thank you for your help and support.
If I want to attach a content script to a tab that I do not have its id. The tab is opened when the extension's button is clicked as in the following.
function openIndexPage() {
browser.tabs.create({
"url": "data/index-page.html"
});
} //end openIndexPage
browser.browserAction.onClicked.addListener(openIndexPage);
How can I attach content script to the index-page.html? I can not use the normal HTML <script></script> to attach it as it needs to access the storage. Can you help me solve this dilemma please?
You can't inject content scripts into HTML pages from your extension and there's no need to do so.
HTML pages which are loaded from within your extension, be that as a tab, window, options page, popup, etc., are loaded into the background context. This is the same context in which your background script(s) run. However, scripts associated with such HTML pages (i.e. in separate JavaScript files referenced from <script> tags) run in the scope of that page. They have access to all the chrome.*/browser.* APIs which are available to your background script(s). If they so desire, they can gain references to the other scopes within the background context. If you want more information about communicating between such scripts, please see: Communicate between scripts in the background context (background script, browser action, page action, options page, etc.)
Thus, there is no need to load a content script into such pages. The scripts running in the page already have access to the DOM of that page and all the privileged extension APIs. Such scripts are not restricted to only the APIs available to content scripts.
Side note: Content scripts are attached to the tab's content, not the tab
Content scripts are not attached to a tab, per se. They are injected into the content that is currently displayed in a tab. This happens either through a manifest.json content_scripts entry having a matching URL, or through tabs.executeScript() being called to inject it into a specified tab. If different content is loaded into the tab, then the content script is destroyed. Thus, it's attached to the content, not the actual tab. In other words, it does not get automatically reloaded when the tab changes to a new URL, unless that URL matches a manifest.json content_scripts entry or tabs.executeScript() is called again.
I'm new to firefox and I used JPM to make a firefox addon and submitted it to Mozilla. One reason they gave for rejecting it was the use of iframe elements without a type attribute.
Here are the two situations that an iframe will be loaded.
Whenever a page is loaded a content script will be injected to that page and that content script will insert an iframe that acts as the extension's menu. I set the type attribute using jquery append.
$("body").append("<iframe type='content'></iframe>")
Whenever a user clicks a button appended to a youtube video it will load the video through an iframe and display that video on the page with some additional viewing features. The type attribute is being set using vanilla javascript myIframe.type = 'content'
Is there something I am completely missing or is how I am setting the type attribute correct?
I have a bookmarklet that opens a dialog (in reality an iframe) and extracts some information. When the dialog is dismissed I want to put that information into edit text fields on the original page in the browser (like the way LastPass will automatically fill-in login forms on a page).
Is this possible? I'm thinking that same-origin-policy will prevent this, but maybe there is a way (without installing extensions such as greasemonkey, etc).
Edit: to be more precise: the bookmarklet appends a DIV to the original page; that DIV contains an IFRAME that loads my page; this page fetches some information; once this information is fetched within the IFRAME I want to remove the DIV and (somehow) put that information into the original page.
The issue I face is communicating the information in the IFRAME back to the original page.
What you are looking for are the functions addEventListener and postMessage.
Relevant links:
http://caniuse.com/#feat=x-doc-messaging
How do you use window.postMessage across domains?
I am developing an addon using Firefox's Addon SDK (v. 1.11). My extension dynamically creates an iframe on each website and then loads an html file which includes other resources such as images, font files, etc. from the add on's local directory.
Problem
When loading any of such local resources (i.e.: "resource://" schema), the iframe fails to display them and a message is thrown:
Security Error: Content at http: //www.XXX may not load or link to
resource://XXX
This is a security measure introduced on Firefox 3. When developing without the Addon SDK, the way around it is declaring a directory with "contentaccessible=yes", making the directory's contents accessible to anyone, including my add on. However, I have not been able to find similar functionality using the Addon SDK. Is there a better way of using local data on an iframe that my addon creates and inserts into a page?
I don't think you can directly load an iFrame that points to a resource inside your URL. The browser complains because it's either breaking same origin policy or cross site scripting one. I can't remember which one right now.
if it is html content you want to load you can always inject it into the DOM and then send a message to the document object using the events API to display your custom html. I've done this in the past and it works.
so from main.js send a message to content script which will then inject your iframe html into the DOM and then you can send the document object a message to display it.
I hope this helps.
Not sure if this was the case when you posted the question, but it appears that "resource://" should no longer be used with the Addon SDK.
If you're using the resource inside of an HTML file in the extension, you can reference it locally, otherwise you should use data.url('whatever.jpg') and pass around that value as needed.
Full info is here: http://blog.mozilla.org/addons/2012/01/11/sdk-1-4-known-issue-with-hard-coding-resource-uris/
I have a JSP page, where some parts of the pages are loaded from the backend using AJAX. For example, when I first open the page, the URL is http://www.made-up-domain-name-because-of-stack-overflow-restrictions.com/listUsers.do. The page contains an "add user" button, which loads HTML content (containing a form etc.) from the backend to the div-element with id "addArea". The URL stays the same the whole time (naturally), as the request is done in the background.
The problem I have is that the content loaded using AJAX is not completely viewable with any means.
Using Firefox I can see the new HTML with the Firebug add-on and "Inspect element", but the content within the script-tags is not visible that way (also not in the "Script" tab in Firebug - only the originally loaded scripts appear there). If I use "View page source" in FF a page reload is executed and I don't see the newly generated content (I only see the content of page http://www.made-up-domain-name-because-of-stack-overflow-restrictions.com/listUsers.do as it was when first loaded).
With Chrome I have the same problem as with Firefox.
Using IE I see only the original source.
Of course I can work around this by adding debugging mechanisms to the JS code and working half-blind, or moving parts of the JS code to external files etc., but if by any means possible, I would prefer to just view the code loaded using AJAX. Any suggestions, perhaps using some add-on?
Update: There is a better way: see the accepted answer for this question: How to debug dynamically loaded javascript(with jquery) in the browser's debugger itself?
You can use the JavaScript Deobfuscator extension for that. It can show you what scripts are compiled/executed on a webpage - including the ones that were loaded dynamically.