I need to access a nested iframe at an arbitrary number of levels deep from a Firefox extension's overlay (an iframe within an iframe within an iframe within...). The overlay receives the event from the iframe, but the DOM accessor method returns nil.
function resizeIframe(evt){
var iframeHeight = evt.target.getAttribute("height");
var frame_id = evt.target.getAttribute("frame_id");
var ifr = content.document.getElementById('ifrm'+frame_id);//returns nil
ifr.style.height = iframeHeight+'px';
}
I'm looking for a robust way to do this, but I would be happy with anything that works at this point. Thanks!
Use window.frameElement property:
var ifr = evt.target.ownerDocument.defaultView.frameElement;
From Firefox 34 onward, we can point the developer tools at a specific iframe within a document.
You can refer to this Mozilla Developer Guide for detail explanation about extension provided by Mozilla to access nested iframes.
Related
I use this code to intercept a dialog from a webview but I can not see the content or interact with it:
Element webview= querySelector("#webview");
Map<String,String> map=new Map();
map["src"]=urlWebView+user;
webview.attributes.addAll(map);
querySelector("#webview_cont").style.visibility="visible";
window.addEventListener("dialog",(Event e){ //Use window or webview returns the same result
e.preventDefault();
... //What should I do here ??
} );
Any solution?
Thanks
Edit
Debug:
Open issue: https://code.google.com/p/dart/issues/detail?id=23556
The problem definitely lies with your usage of Dart's Event class.
It simply does not support the extra properties that Chrome is adding to the event: e.dialog, e.messageText, e.messageType.
It does not seem like there is a ready solution for that, at least not in chrome.dart.
Sadly, I don't know Dart well enough to give you a solution. You need to somehow extend that event class, possibly dropping to JS level.
This library, even if abandoned, should give you ideas on how to do that (by catching the JS-level event and stuffing the extra properties in CustomEvent's detail property), though implementing DialogController (which is not JSON-serializable) would be a bit trickier, I guess.
I'm trying to work around the lack of API for Google Spreahsheet's Filter Views, by passing the filter view's URL into a hyperlink displayed in a sidebar.
Importantly: I want the filter view URL to open in the same window as, and thus replace, the spreadsheet. The hyperlink target should then be _self
function listFilterViews(){
var uiInstance = UiApp.createApplication()
.setTitle('Teacher Views');
var panel = uiInstance.createVerticalPanel();
panel.setSpacing(5)
var scroll = uiInstance.createScrollPanel();
scroll.setHeight("100%")
var url = "https://docs.google.com/blablabla"
var link = uiInstance.createAnchor("click me", url)
link.setTarget("_self")
panel.add(link);
scroll.add(panel)
uiInstance.add(scroll);
SpreadsheetApp.getUi().showSidebar(uiInstance);
}
However, the URL doesn't open in the same window as expected but in an other window instead. How can I fix this?
According to the setTarget documentation:
"(setting a target to _self) will only work if the app is being shown as a standalone service. It will have no effect when called inside a dialog, such as in a Google Spreadsheet."
Apps Script intentionally prevents scripts from being able to switch the view of the current window, as a security measure.
I'm trying to override a JS function named replaceMe in the web page from my add-on's content script, but I see that the original function implementation always gets executed.
Original HTML contains the following function definition:
function replaceMe()
{
alert('original');
}
I'm trying to override it my add-on like (main.js):
tabs.activeTab.attach({
contentScriptFile: self.data.url("replacerContent.js")
});
Here's what my replacerContent.js looks like:
this.replaceMe = function()
{
alert('overridden');
}
However, when I run my addon, I always see the text original being alerted, meaning the redefinition in replacerContent.js never took effect. Can you let me know why? replaceMe not being a privileged method, I should be allowed to override, eh?
This is because there is an intentional security between web content and content scripts. If you want to communicate between web content and you have control over the web page as well, you should use postMessage.
If you don't have control over the web page, there is a hacky workaround. In your content script you can access the window object of the page directly via the global variable unsafeWindow:
var aliased = unsafeWindow.somefunction;
unsafeWindow.somefunction = function(args) {
// do stuff
aliased(args);
}
There are two main caveats to this:
this is unsafe, so you should never trust data that comes from the page.
we have never considered the unsafeWindow hack and have plans to remove it and replace it with a safer api.
Rather than relying on unsafeWindow hack, consider using the DOM.
You can create a page script from a content script:
var script = 'rwt=function()();';
document.addEventListener('DOMContentLoaded', function() {
var scriptEl = document.createElement('script');
scriptEl.textContent = script;
document.head.appendChild(scriptEl);
});
The benefit of this approach is that you can use it in environments without unsafeWindow, e. g. chrome extensions.
You can then use postMessage or DOM events to communicate between the page script and the content script.
In a Firefox add-on built with the Add-on SDK, how can I disable and re-enable JavaScript for a single tab?
The SDK itself doesn't provide this functionality, you will have to work with the XUL directly. What you need to do is accessing the docShell property of the XUL <browser> element corresponding to the tab. The docshell has an allowJavascript property that lets you switch JavaScript on and off. Something like this should work:
var window = require("window-utils").activeBrowserWindow;
var tabBrowser = window.gBrowser;
var browser = tabBrowser.selectedBrowser; // or: tabBrowser.browsers[n]
browser.docShell.allowJavascript = false;
Unfortunately, it doesn't seem possible to take a Tab object and find the corresponding XUL element - you have to work with the XUL window from the start.
Relevant documentation:
window-utils package (the properties activeWindow/activeBrowserWindow are undocumented for some reason).
<tabbrowser> element
<browser> element
nsIDocShell interface
Does anyone know what might have changed since v3.0.5 that would enable extensions to work? Or, maybe I'm missing a setting somewhere? I wrote this add-on that works fine with newer versions, but I can't get it to launch in older ones. Specifically, I can't even get this part to work (this is in my browser overlay.xul):
<html:script>
<![CDATA[
var Cc = Components.classes;
var Ci = Components.interfaces;
var obSvc = Cc["#mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
gBrowser.consoleService = Cc["#mozilla.org/consoleservice;1"].getService(Ci.nsIConsoleService);
gBrowser.log = function(msg){
this.consoleService.logStringMessage(msg);
}
gBrowser.newObj= new MyAddOn();
gBrowser.log("initializing...");
function regListener()
{
obSvc.addObserver(gBrowser.newObj, "http-on-modify-request", false);
}
function unregListener()
{
obSvc.removeObserver(gBrowser.newObj, "http-on-modify-request");
}
window.addEventListener("load", regListener, false);
window.addEventListener("unload", unregListener, false);
]]>
This should attach listeners to the new obj (defined by a linked .js) However, I'm not even getting the "initializing..." message in the console. Any ideas?
Don't use <html:script>, use <script> (assuming you have xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" on your root <overlay> element).
Don't register an application-global listener (http-on-modify-request) from a window overlay. Doing so will make your code run one time in each window the user may have open. Use an XPCOM component instead - https://developer.mozilla.org/en/Setting_HTTP_request_headers
Don't pollute common objects (like gBrowser or the global object (with var Cc)) with your own properties. If everyone did that, no two extensions would work together. Put all your code properties on your own object with a unique name.
accessing gBrowser before the load event is probably what's causing your specific problem.
Set up your environment and check the Error Console to debug problems.
Don't waste time trying to support Firefox 3. It's not supported by Mozilla itself for over a year and shouldn't be used to access the web.
It looks like gBrowser.log is not defined, or at least is not a function, as the error console will probably tell you. I've never heard of it either. Maybe it was added in Fx 3.5?