Chrome Dev Tools: <page context> and <top frame>? - javascript

What do these drop downs do? I assume they execute console commands in different contexts but I see weird, nonsensical choices when I click them.

Lets take Gmail as an example and start by looking at the first drop down:
List of frames
What you can see here are all frames that are embedded into the current page. Each of these frames is sandboxed. Being sandboxed means that there is no access from one sandbox to the other sandboxes. Scripts executed inside one frame can't access DOM or JS variables of the other frame. This is due to security reasons, we don't want a script inside an iframe to have access to the page it was embedded in (this would allow e.g. ads embedded into a blog to read what you are typing or what you keep in your cookies).
List of contexts
In the second drop down we have list of contexts for selected frame e.g. here is a list of contexts for Gmails <top frame>:
These are sandboxes created for each script that was injected by Chrome extension to the selected frame (these scripts are known as 'content scripts'). However, these are different from the frame sandboxes that I've mentioned before. Scripts injected by Chrome extensions have unlimited access to the DOM of the page they were injected to but operate in a separate JS execution context called isolated world (don't have access to "JavaScript variables or functions created by the page"). In this case it's more about making sure that scripts from different extensions don't interfere with each other than about the security:
Isolated worlds allow each content script to make changes to its
JavaScript environment without worrying about conflicting with the
page or with other content scripts. For example, a content script
could include JQuery v1 and the page could include JQuery v2, and they
wouldn't conflict with each other.
BTW Part of the url after chrome:// represents extension ID and using it you can figure out the name of the extension that injected the code (check 'Developer mode' on the chrome://extensions/ page).
Why do we need that?
You may want to see errors / console.* messages generated by an iframe.
While debugging your Chrome extension you may want to see errors / console.* messages that your injected script have produced.
You may want to execute some code from console in context different than the default one.

Related

Share a variable between multiple userscripts [duplicate]

I have two scripts. I put them in the same namespace (the #namespace field).
I'd like them to interactive with another.
Specifically I want script A to set RunByDefault to 123. Have script B check if RunByDefault==123 or not and then have script A using a timeout or anything to call a function in script B.
How do I do this? I'd hate to merge the scripts.
The scripts cannot directly interact with each other and // #namespace is just to resolve script name conflicts. (That is, you can have 2 different scripts named "Link Remover", only if they have different namespaces.)
Separate scripts can swap information using:
Cookies -- works same-domain only
localStorage -- works same-domain only
Sending and receiving values via AJAX to a server that you control -- works cross-domain.
That's it.
Different running instances, of the same script, can swap information using GM_setValue() and GM_getValue(). This technique has the advantage of being cross-domain, easy, and invisible to the target web page(s).
See this working example of cross-tab communication in Tampermonkey.
On Chrome, and only Chrome, you might be able to use the non-standard FileSystem API to store data on a local file. But this would probably require the user to click for every transaction -- if it worked at all.
Another option is to write an extension (add-on) to act as a helper and do the file IO. You would interact with it via postMessage, usually.
In practice, I've never encountered a situation were it wasn't easier and cleaner to just merge any scripts that really need to share data.
Also, scripts cannot share code, but they can inject JS into the target page and both access that.
Finally, AFAICT, scripts always run sequentially, not in parallel. But you can control the execution order from the Manage User Scripts panel

Manipulating the current document from an Add-on SDK panel

I am writing a Firefox add-on using the new SDK that does 5 very simple jobs. They are roughly related, so I would prefer a single add-on with a dropdown menu which I have implemented in a Panel.
I am working my way through the new SDK documentation, but can't find a direct solution. I find I can add a panel, but I cannot see how to manipulate the document in the current tab.
This is possible, isn't it? Using the global document doesn't work as presumably refers to the panel, or at least not to the document I am viewing.
So, how do I access the document from an add-on panel?
The short answer to your question is that you don't access web content from your main JavaScript code. You interact with the document (web content) in the browser's tab using Content Scripts. You can have the content script pass messages to your main script.
MDN summarizes the principals of using content scripts with the SDK as follows:
Content scripts can be one of the more confusing aspects of working
with the SDK, but you're very likely to have to use them. There are
five basic principles:
the add-on's main code, including "main.js" and other modules in "lib", can use the SDK high-level and low-level APIs, but
can't access web content directly
content scripts can't use the SDK's APIs (no access to globals exports, require) but can access web content
SDK APIs that use content scripts, like page-mod and tabs, provide functions that enable the add-on's main code to
load content scripts into web pages
content scripts can be loaded in as strings, but are more often stored as separate files under the add-on's "data" directory. jpm
doesn't make a "data" directory by default, so you must add it and put
your content scripts in there.
a message-passing API allows the main code and content scripts to communicate with each other
Exactly how you would do what you are wanting is unclear because you have not provided a clear description of what you are doing. However, it almost sounds like you could implement what you want using the context-menu. The context menu is one of the ways to attach a content script to the current tab and may provide you with the dropdown menu feel which you desired (although it is part of the context menu, not a dropdown menu).

Inject dynamic script in Firefox extension

I'm doing an extension now and i have one part of script which is static (will never change) and another part which is loaded from the website. And, i'm seeing 2 ways:
To load it with XMLHttpRequest and inject into web page
To put it as a <script src="example.com/myscript.js"></script> and have it load it itself
But, the second way probably won't have access to my extension API (to functions defined in extension files, i.e. in chrome://myext/script.js)
And, the first way will probably be unsecure because i will have to eval the code in a gBrowser.contentWindow.wrappedJSObject object which is a Window object for the loaded page
Any ideas?
Are you saying that you want the dynamic script to have chrome privileges? If so, why not load it using XMLHttpRequest, save it to disk and then import it as a JavaScript Module (https://developer.mozilla.org/en/JavaScript_code_modules/Using). Obviously there are security considerations since you are giving a script from the web pretty much unlimited privileged, but if you control the script's source then you are presumably okay. If you are really worried you can use HTTPS to download the script, which will protect against someone intercepting the traffic.
If you want the code to run with content privileges but have access to functions in your chrome JavaScript, then maybe you want to expose the chrome functions to content as described in this article: http://weblogs.mozillazine.org/weirdal/archives/017188.html

Chrome: window.content.document?

I'm developing a Google Chrome Extension and I'm wondering what is the Chrome equivilant of window.content.document?
Looks like crome extensions depend on script injection if you want to interact with pages:
http://code.google.com/chrome/extensions/content_scripts.html
You can inject code or .js files.
For extension <-> DOM communication:
http://code.google.com/chrome/extensions/content_scripts.html#host-page-communication
To access windows: http://code.google.com/chrome/extensions/windows.html
Lets just say there's no direct access to DOM from Extension as far as I can see.
There is no window.content in Chrome right now (August 2014)
but window.document works just as well.
Like BGerrissen said, there is no direct access capability across different windows.
It is a restriction that different domain script cannot directly access each other.
As an extension, the main script itself is in a standalone chrome process.
You can put many functions, computations, preference code in this background.html.
And inject small portion of JS code into the content of other tab or window to manipulate the HTML content. And there communications to each other can be achieved by using postMessage and message handler.
Yes, BGerrissen it correct. You need to communicate with web pages via a shared DOM using content scripts.
It's quite tricky, requiring you to register events and listeners and bind data to a DOM element that both scripts can access.
http://code.google.com/chrome/extensions/content_scripts.html#host-page-communication
There's an example in Google Chrome labs where an extension script makes a web page red:
http://code.google.com/chrome/extensions/samples.html#ede3c47b7757245be42ec33fd5ca63df4b490066

Why do some websites (like facebook) load scripts in an iframe?

Why do some websites (like facebook) load scripts in an iframe?
Is this to allow the site to load more than 2 resources at a time because the iframe's resources are at different URLs?
What you are seing, might be an application of "Comet" communication, using a hidden iframe as data channel. A short explanation of the technique according to Wikipedia:
A basic technique for dynamic web application is to use a hidden IFrame HTML element (an inline frame, which allows a website to embed one HTML document inside another). This invisible IFrame is sent as a chunked block, which implicitly declares it as infinitely long (sometimes called “forever frame”). As events occur, the iframe is gradually filled with script tags, containing JavaScript to be executed in the browser. Because browsers render HTML pages incrementally, each script tag is executed as it is received.
This could be used for something like a chat, where messages are expected to appear without noticeable delay, and preferably without periodical "polling" for new data. If this is what you have come across, you should see several <script> elements in the frame, and more should be added as times go by.
EDIT
So to actually address your question... I don't know! The following information might be helpful, however:
Facebook prepends all of the JS variables and functions with your application ID.
var ID;
becomes
var 1262682068026-ID;
This limits the scope of your javascript to only your application so you can't use the DOM to get at their friends, phone number, email, address, etc, unless authorized. It makes a little sub-sandbox for you to play in.
More info on scoping here:
Facebook Docs
javascript loaded in iframe have no access to parent page objects (cross-domain restriction)
They load comet (aka comet, HTTP Push, long-lived, etc) connections in an iFrame because Internet Explorer eventually drops it:
http://cometdaily.com/2007/10/25/http-streaming-and-internet-explorer/
As it is effectively a continuous long poll, this is a blocker, this hack also increases IE's 2 connection limit leading to better responsiveness, background info:
http://alex.dojotoolkit.org/2006/02/what-else-is-burried-down-in-the-depths-of-googles-amazing-javascript/

Categories

Resources