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.
Related
As the title says, I need my addon to execute a script that will inject some CSS when a specific URL is opened. How would one go about calling on a script to run?
Assuming that you are using the add-on SDK, this is done by using page-mod (documentation on MDN).
The page I have linked to on MDN has a considerable amount of information on the subject of using page-mod. Quoting from that page:
page-mod:
Run scripts in the context of web pages whose URL matches a given pattern.
Usage:
To use page-mod, you specify:
one or more scripts (or other things, e.g. CSS) to attach. The SDK calls these scripts "content scripts".
a pattern that a page's URL must match, in order for the
script(s) to be attached to that page.
For example, the following add-on displays an alert whenever the user visits any page hosted at "mozilla.org":
var pageMod = require("sdk/page-mod");
pageMod.PageMod({
include: "*.mozilla.org",
contentScript: 'window.alert("Page matches ruleset");'
});
For your specific desire to inject CSS, you would use either of the following two options to the page-mod constructor:
contentStyle: Lists stylesheets to attach, supplied as strings.
contentStyleFile: Lists stylesheets to attach, supplied in separate files.
You wanted to know how to execute a script. You wanted the script to inject CSS, but that is done directly with the options above rather than having a script do it. However, if you wanted to inject a script file to perform additional tasks, you would use the contentScriptFile option.
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?
How can I manage page state history in share (surf?) so that I remember for example which yui tab was active and on which page the pager was on?
I noticed that alfresco share does something like that after form submit. You get redirected to the exact same page url where you were before. If any "ajax state" (don't know what they are called) parameters are in url like #something=asdf you get the same url.
But when using manual navigation like moving through site pages those parameters aren't saved.
Is this even a good idea to do? To save page state in session for example?
Some pages have support for URL parameters that are passed in. In those cases the browser history is used, e.g. we editing metadata in the full page meta data view the user is send back to the page he is coming from. This is done in javascript by calling window.history.go(-1) after form submit but only works when parameters are set/retrieved by URL. The document library implements page specific javascript for setting the URL and parsing parameters from it.
I some places Alfresco uses the preference service to store user settings between different pages permanently. For example this is used in the document library for the "show folders" and "simple/thumbnail view" buttons. Here is some sample code from the document library javascript setting a preference option:
var PREFERENCES_DOCLIST = "org.alfresco.share.documentList",
PREF_SHOW_FOLDERS = PREFERENCES_DOCLIST + ".showFolders";
var preferences = new Alfresco.service.Preferences();
this.services.preferences.set(PREF_SHOW_FOLDERS, true);
The evaluation of the properties is usually done in the Share component webscripts, you can have a look in share\WEB-INF\classes\alfresco\site-webscripts\org\alfresco\components\documentlibrary\include\documentlist.lib.js for an example.
In any case you have to dig into Alfresco's javascript code in the browser and the share tier to see how to implement it.
You could check parameters sended to the server side after form submiting in the firebug (firefox plugin) and then you could use the same parameters.
Also perhaps you should use yui history manager:
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.
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.