Highlight elements on cross origin page - javascript

I need to accomplish something very similar to the "inspect element" functionality with Chrome developer tools (see attached screenshot).
The main thing I'm looking for is the ability to recognize and highlight an element on the given page. I can display an overlay, add a class to the element, etc. I know that using an iFrame and trying to access and manipulate the DOM w/in the iFrame won't work directly because its cross-domain. I also know about post messages if you have control over the site, but I may not have that all the time. The main issue I have is that I am only trying to temporarily highlight elements on a page as if I had clicked "inspect element" and displaying that. It doesn't need to persist or anything, just to highlight specific elements (h1 tags for example), when the user loads a website within my app. Even the ability to use the chrome developer tools where it lets you "edit as HTML" would work if there were a way to do so.
Is there any way, using an iFrame, a new tab, or any other means that I can use to highlight elements on a given website who's URL is provided? I've attached another image of the "goal".

It seems like you have three options to highlight the elements.
1. Browser Extension
2. Send events through postMessage to direct the iframe site to manipulate its DOM
3. Send events through postMessage to receive information about the positioning of the DOM and overlay elements on top of the iframe.
#1 seems to be a longer overhaul to do. #2 and 3 is only possible if you will always have access to the website in the iframe.
https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage
The window.postMessage() method safely enables cross-origin communication between Window objects; e.g., between a page and a pop-up that it spawned, or between a page and an iframe embedded within it.

Related

To have reference to outer most <body> tag from the iFrame

I am working on PowerBI custom visual. What I want to do is access outer most body tag to attach an element using jQuery but I am not able to do that as all custom visual are loaded in an iFrame and my current window object only points to iframe container area.
How can I access outside from this iFrame to parent window (topmost)? I know and I have gone through similar answers on StackOverflow and GitHub. I even liked this answer here.
How to communicate between iframe and the parent site?
Now the problem is, It is the same domain iframe as what I see in URL i.e. https://app.powerbi.com.
The second thing is while developing custom visual in VSC or other editors using PBIVIZ APIs, you only have access to iframe container where your custom visual is loaded. Thus you can't access code that is there outside or at the parent location of this iFrame. I believe it is part of PowerBI environment itself.
Third thing is, there is no configuration available to remove or load custom visual without iFrame itself. Please let me know if there is one.
This is also done for one of the Power BI's own visual (date slicer) which doesn't load any iFrame when you inspect that code in the browser.
Does anyone have any Idea? GitHub issue for more information: https://github.com/microsoft/PowerBI-visuals/issues/544
There is no option to get access to parent DOM. The visuals execute inside iframe by security reasons and also iframe isolates in functionality aspects. (ex. prevent changing styles of Power BI interface)

On hover of a url display the website in a popup div?

I am trying to do something like:
Google
When a user hovers the link:
<div id="display-site">
//working site contained in a div
</div>
Note I am aware that I can open the link in a new window using html, thought I am interested in figuring out how I would go about 'previewing' the website contained in the <a> tag, in a div container, (if the link is hovered).
This can be done by creating an <iframe> in the DOM on hovering over an <a> and loading the href as the iframe's src= attribute. In order to make it look like a popup, you would need to position the <iframe> at an absolute location, and set its z-index CSS property to a higher value than the rest of the page content.
However, if you need to make modifications to the display of the loaded frame, such as sizing some elements to accommodate the zoom level as suggested by #David's answer, you may run afoul of the same-origin policy, as scripts will not be permitted to access properties of the loaded frame outisde the same domain.
From MDN:
Scripts trying to access a frame's content are subject to the same-origin policy, and cannot access most of the properties in the other window object if it was loaded from a different domain. This also applies to a script inside a frame trying to access its parent window. Cross-domain communication can still be achieved with window.postMessage.
Before continuing - check this benefits the user experience. When I move my mouse over a page and brush over a hyperlink I don't always want a link preview to appear on top. However, assuming this is in the best interests of your users...
Implementation wise, this can be done, as #Michael suggests, by using an <iframe>, however the document within the iframe will be displayed at the user's set zoom level, but showing a 250x250 window of a document designed for at least 1024x768 isn't going to help the user. Thus you need to display a zoomed-out, birds' eye representation of the web-page to the user.
There are ways to get the current viewport zoom level ( How to detect page zoom level in all modern browsers? ) but I don't know how setting it works (in all liklihood it's probably impossible in most cases). Furthermore I don't think you can set zoom on a per-iframe basis (assuming you can set it all).
The best way forward then is to display a scaled-down bitmap page rendering to the user - like Google does for popular pages in its search results. However this means that for every page you link to you need to get a rendered image of the target page.
I remember a few years ago there were companies that provided page thumbnail services (it was part of those annoying doubly-underlined ad text in webpages that was popular around 2005-2008), but they're a rarity now.
I guess you'll have to then set up your own service and host a layout engine (Gecko, WebKit, or Trident) in a way it can generate page thumbnails for you.
All things considered, I don't think it's worth it.
Something like this, just an idea
$('a').hover(function()
{
$('#display-site').load((this).attr('href'));
$('#display-site').show();
});
You will need to set the css property as needed
1- Find a jquery plugin that displays tooltips on element hover.
2- Insert an Iframe of the website that the link refers to inside a div residing in the tooltip container.

Google Chrome Extension Manipulate DOM of Open or Current tab

Ok, JavaScript/jQuery I got that, I can work with that to do what I want in general. However what I am trying to do currently is work with the DOM of the open/current tab, and I am wondering if that is possible or is all the work I do with an extension limited to the html I provide it with a "background.html" or equivalent.
For todays attempt at taking a strike at a google extension I want to take images on a page and store them in an array to create a slide show like effect from it via a bar I want to add to the bottom of the page appending it to the existing DOM of the open/current tab. I then want "hide" elements in the DOM til the bar is closed.
So my first question is, is something like this possible, can I manipulate the DOM in such a way and read from it.
Content Scripts are scripts which run in an environment between a page and the Chrome extension. These scripts are loaded on every page load, and have full access to the page's DOM. DOM methods, such as document.getElementById() behave as if they were a part of the page.
The global window objects (including frames and HTMLIFrameElement.contentWindow) are the only objects which are not directly readable by Content scripts.
Content scripts run on every page as defined in the manifest file. Specify a match pattern at the "content_scripts" section, to define on which pages the content script has to run. Also add this pattern to the "permissions" section, to unlock the ability to modify the page's DOM.
Note: Only a few of the chrome.* APIs, can be used by these scripts (such as chrome.extension.sendRequest to communicate with the background page).
In a background page, the DOM of a page is not directly accessible. You can inject scripts in an arbitrary tab using chrome.extension.executeScript, but you won't be able to get a direct reference to an element. For this purpose, Content scripts are required.

Change Default Action of IFRAME Hyperlink Clicks

I'm using Google search in a page, and it shows up in an IFRAME. However, when you click on a link in the search, it's leaving my site and redirecting to that other site. Is there a way to intercept that call with jQuery and make it open that link in a new window, instead?
Due to security reasons, what you can do with an iframe is very limited (In cases where you frame another domain).
The way this is implemented varies a bit from browser to browsers but most browsers won't let you manipulate the data in the iframe.
To my knowledge this isn't possible, assuming you are refering to an implementation of http://www.google.com/cse/

Webpage limitations when wrapped inside an IFrame?

I am developing a webpage which our customers want to insert on their websites by wrapping my page in an iframe (cross domain). I don't need to interact with the parent or know anything about whats outside the iframe.
I am using HTML, CSS, Javascript and Webservices.
Question: How am I limited inside an iframe compared to if my page was running outside the iframe?
You're not. Any JS linked within the iframe from your domain will act in the context of the iframe. Aside from being crammed into an unusual container it should work the same as it would if it was loaded independently.
If your needs should change however, there are ways to send signals between parent frame and iframe if both pages have JS written to cooperate. There's methods using the # in URLs which can be read by the parent and don't force page reloads and I believe they share the window.resize event which can be fired manually without actually resizing the window.
UPDATE: There are far better ways to communicate between cross-domain iframes now than there used to be. Naturally you'll still require cooperating JS on both ends but you can use window.postMessage rather than triggering messages via window.resize and data after a hash symbol in the URL. That was a cool trick though.
When creating links you should have in mind to maybe use the target-attribute of the a-tag if you want to create a link for the parent window. Otherwise the new page would be loaded into the iframe.

Categories

Resources