Can postMessage sends more complex objects - javascript

I'm currently working on a webExtension, and injected the html of my webExtension into an iframe. I want to drag stuff from arbitrary web pages into a droppable area in the iframe, and display them in the droppable area. I have a dragstartListener that uses postMessage to send the HTMLdocument of the element dragged everytime it listens to a dragstart event. But postMessage cannot send objects with methods inside. Are there any alternatives to implement the function? Thank you!

I figured out a solution: using XMLSerializer.
XML Serializer can actually serialize dom elements into strings. Postmessage can send strings to another window safely.

Related

Best way to interact with iframe

Hey guys i really need your help. I am creating some kind of application for dynamically searching multiple items. For example, I want to search specific products in one store via iframe(for example, src will be 'www.store.com/search'), i create a array of all objects which i want to search and i create loop which will change iframe's src('www.store.com/search/item-1', 'www.store.com/search/item-2', etc.). I need to access price for selected item, preferably through iframes dom element. I was trying to access iframes dom element and console with no success (Blocked a frame with origin from accessing a cross-origin frame). I am pretty sure im not headed in the right direction, does anyone have better solution or a way to bypass this?
If you don't control the contents inside of the iframe there is no easy way to do this. The web browser has a security feature (called CORS - https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) to prevent this sort of interaction for security reasons.
In order for this to be possible the page inside of the iframe needs to be your page, and you need to configure the CORS settings on it to allow being used with an iframe like this.

Looker Custom Iframe embedded events

I'm using looker for a table visualisation.
I need the embedded iframe to communicate with parent window.
I'm using embedded Iframe events for some visualisations. And I'm receiving the default events
But I'm need to create and broadcast my own events.
For example, one cell in the table should broadcast user:clicked:icon which the parent window can than act upon.
Tried several methods through the LookML interface on the dimensions that I'm using (html, action etc) to even get something like page:changed to trigger, but with no success
Update
Found a current work around. Using an existing action (page:changed) on an html created dimension (a tag). I was able to intercept a navigation and accomplish some communication between the parent wrapper and looker iframe

Firefox Addon to manipulate DOM without giving the website access to the changes

I write a Mozilla Firefox Addon, that lets me comment websites: When I open a website and click somewhere, the plugin creates a <div> box at this location, where I can enter a comment text. Later, when I open the website again, the plugin automatically puts my previously created comment boxes at the places they where before. (Similar to a comment feature in many PDF readers, etc.)
This leads to a security problem: A website could use an event listener to listen to the creation of new <div> elements and read their content, allowing it to read my private comments.
How can I solve this security issue? Basically, I want a Firefox addon to put private content in a website, while the website should not be able to access this content via JavaScript. (Unless I want it to.)
I could listen to listeners and detach them as soon as the website attaches them - but that does sound like a solid solution.
Is there a security concept in order to make my addon the authority over DOM changes, respectively, to control the access to certain elements?
Alternatively, would it be possible to implement some sort of overlay, which would not be an actual part of the websites DOM but only accessible by the addon?
Similar security problems should occur with other addons. How do they solve it?
If you inject the DOM in a document, the document will always be able to manipulate it, you can't really do much about it. You can either:
1) Don't inject your comment directly in the document, but just a placeholder were there is the first words of the comment, or an image version of the comment (you can generate that with canvas), leave the full ones in your JavaScript Add-on scope, that is not accessible from the page: when you click to edit or add, you can open a panel instead and do the editing there.
2) Inject an iframe, if you have your page remotely in another domain shouldn't be a problem at all, the parent's document can't access to the iframe; but also viceversa: you need to attach content script to your iframe in order to talk with your add-on code, and then you can use your add-on code to send and receive messages from both iframe and parent's document.
If you use a local resource:// document, I'm afraid you need a terrible workaround instead, and you need to use sandbox policies to avoid that the parent's document can communicate with the iframe itself. See my reply here: Firefox Addon SDK: Loading addon file into iframe
3) Use CSS: you can apply a CSS to a document via contentStyle and contentStyleFile in page-mods. The CSS attached in this way can't be inspected by the document itself, and you could use content to add your text to the page, without actually adding DOM that can be inspected. So, your style for instance could be:
span#comment-12::after{
content: 'Hello World';
}
Where the DOM you add could be:
<div><span id='comment-12'></span></div>
If the page tries to inspect the content of the span, it will get an empty text node; and because from the page itself the stylesheet added in this way cannot be inspected, they cannot the styles rules to get the text.
Not sure if there are alternatives, those are the solutions that pop to my mind.
Add-ons that do similar things implement some combination of a whitelist / blacklist feature where the add-on user either specifies which sites they want the action to happen on, or a range of sites they don't want it to happen on. As an add-on author, you would create this and perhaps provide a sensible default configuration. Adblock Plus does something similar.
Create an iframe and bind all your events to the new DOM. By giving it a different domain to the website, you will prevent them from listening in to events and changes.
Addons can use use the anonymous content API used by the devtools to create its node highlighter overlays.
Although the operations supported on anonymous content are fairly limited, so it may or may not be sufficient for your use-case.

Cloning a node duplicates events

I have a DOM fragment on page that I need to display in an overlay.
Using YUI I replace the node and then placing a clone in the overlay with the following line of YUI code:
var overlayContent = content.replace(content.cloneNode(true));
The issue I am experiencing is that now the content seems to send multiple AJAX calls to the server. So when a user clicks a button to increment an item then multiple sets are added instead of singular items and seems to work in multiples of two.
Being new to YUI I am not sure how to prevent this from happening and would appreciate any steer as to prevent this.
It is not good idea to clone a node while setting the body content of a YUI overlay. You should pass plain markup (which you can get using getHTML() method) as the body content of the overlay.
We decided to re-engineer the existing implementation and not using cloning at all.
Instead we pulled the existing fragment from the DOM into the overlay and then on overlay close put it back from where it came.

addEventListener that listens to the contents of an iframe

Background: I have written a bookmarklet (JavaScript) that appends an iframe to the current page you are viewing. This iframe's src attribute is pointing to a form back on my application.
Problem: I am trying to utilize addEventListener to detect if that form has been submitted. However, I don't seem to be able to access the elements within the iframe.
For example:
document.getElementById(remote_form_id).addEventListener("submit",afterSubmit,true)
does not work because the getElementByID call is returning null.
My current work-around is to add an event listener on the iframe to listen for a "load" action and then call an intermediary function that ups a counter because I know how many times the iframe will be loaded before I need to call afterSubmit().
document.getElementById(marklet_iframe_id).addEventListener("load",listenForSubmit,true)
function listenForSubmit(){
if (count==1){afterSubmit();}
count++;
}
Basically, I'm looking for a best practice cause this is a crap approach.
Although it doesn't work in IE, you may want to look at the postMessage method of the pages' window objects. It allows you to asynchronously send string data between windows, even when direct access would be forbidden by the same-origin policy.
You can do something like this:
var doc = document.getElementById(marklet_iframe_id).contentDocument;
var form = doc.getElementById(formId)
form.addEventListener("submit", afterSubmit, true)
Try the EasyXDM library which uses the best-available techniques in a given user's browser to achieve this. It also is "best practice-y" in that its goal is to send messages between windows, and it's up to those windows to handle the messages, which mimicks the postMessage functionality available in HTML5 browsers.

Categories

Resources