Chrome extension security policy for dynamic URLs on new tabs - javascript

Im simply trying to get text from a input and from there open a URL with a newtab/window (either or) with this value included in the URL.
Example
<html>
<head>
<title>Getting Started Extension's Popup</title>
<style>
body {
min-width: 357px;
overflow-x: hidden;
}
img {
margin: 5px;
border: 2px solid black;
vertical-align: middle;
width: 75px;
height: 75px;
}
</style>
</head>
<body>
<input type="text" name="enter" class="enter" value="9999" id="lolz"/>
<input type="button" value="click" />
</body>
</html>
popup.js (Unsure about)
chrome.browserAction.onClicked.addListener(function(activeTab){
document.getElementById('lolz').value
var newURL = "https://stackoverflow.com/" + value;
chrome.tabs.create({ url: newURL });
});
So the end result is a new window with the url "https://stackoverflow.com/9999"
Currently im getting the following error.
Refused to execute inline event handler because it violates the following Content Security Policy directive: "script-src 'self' chrome-extension-resource:".
This is on the popup.html:30

You can't have inline scripts or function calls in your html (e.g. onclick for your input button)
Add the script with src to the head section
<head>
...
<script src="popup.js"></script>
</head>
Add an id to your button.
popup.js should look like this:
document.addEventListener('DOMContentLoaded', function () {
document.querySelector('input#yourButtonID').addEventListener('click', popup);
});
function popup()
{
var newURL = "http://stackoverflow.com/" + document.getElementById("lolz").value;
chrome.tabs.create({ url: newURL });
}
Change yourButtonID with the actual id.

Related

How to get Iframe's document content after changing its src in JS?

I have an iframe that changes src pages when the page would normally switch to another page so that my main JS file can continue running in the background. For the first page, the one defined in the HTML src for the Iframe, I can access the inner document just fine by using iframe.contentDocument.
However, when I change the src, the contentDocument does not change with it, and I cannot access the Iframe's document in the JS at all.
So is there any way to access the new document of an Iframe after changing its source in JS? Or is there an easier alternative for the way I am doing things?
Thanks.
How I've tried:
iframe.src = "pages/home/home.html"
innerDoc = iframe.contentDocument || iframe.contentWindow.document
and the innerDoc does not change from the original page.
I've even tried making an entirely new Iframe that never had the original page as its src
document.body.removeChild(iframe)
let i = document.createElement('iframe')
i.src='pages/home/home.html'
document.body.appendChild(i)
innerDoc = i.contentDocument || i.contentWindow.document
This just makes innerDoc an empty HTML document with an empty head and body.
It appears that the page you are loading inside the iframe is from the same domain as the parent window - so you should not need messaging.
You will, however, need to wait for the "load" event before accessing the page content. This is the same for any webpage, not just one embedded in an iframe. Note that you cannot access the contentWindow for an iframe until it is attached to the DOM:
let i = document.createElement('iframe');
// go ahead and attach it to the dom - you can "hide" it with css
document.body.appendChild(i);
// now that you can access the contentWindow, attach a "load" event
i.contentWindow.addEventListener('load', () => {
// now you should be able to access the content
});
// do this last to avoid race conditions with caching and what not
// this might not be necessary, but it doesn't hurt
i.src='pages/home/home.html'
You can "hide" the iframe off screen if you want with something like this:
iframe {
position: absolute;
top: -9999em;
width: 1px;
height: 1px;
}
the "messaging" way is using Window.postMessage
parent Page:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>main Page</title>
<style>
body { font-size: 16px; font-family: Arial, Helvetica, sans-serif; }
iframe { width: 24em; height: 15em; border:3px solid blue; }
#get-iframe-info { width: 24em; border: 1px solid orange; padding: .5em; }
</style>
</head>
<body>
<h4>main page</h4>
<p>parent input :
<input id="in-txt" type="text" placeholder="type something">
<button id="Bt-Send2iFrame">Send2iFrame</button>
</p>
<p> iframe part : <br>
<iframe id="iFrame-01" src="page_iFrame.html" frameborder="0"></iframe>
</p>
<p id="get-iframe-info">iframe return: <br>>
<span></span>
</p>
<script>
const
inTxt = document.querySelector('#in-txt')
, btSend = document.querySelector('#Bt-Send2iFrame')
, iFrame01_ct = document.querySelector('#iFrame-01').contentWindow
, sp_getiFram = document.querySelector('#get-iframe-info span')
;
btSend.onclick =_=>
{
let info = { txt: inTxt.value }
iFrame01_ct.postMessage( JSON.stringify(info), "*")
}
window.onmessage=e=>
{
let info = JSON.parse( e.data )
sp_getiFram.textContent = info.txt
}
</script>
</body>
</html>
iFrame page(s)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<style>
body { font-family: 'Courier New', Courier, monospace; font-size: 14px;}
p { width: 20em; border: 2px solid aquamarine; padding: .5em; }
</style>
</head>
<body>
<h4>page iFrame</h4>
<input id="inTxt" type="text" placeholder="send text">
<button id="btSend">send to parent</button>
<p id="get-parent-info"> info from Parent: <br>>
<span></span>
</p>
<script>
const sp_infoParent = document.querySelector('#get-parent-info span')
;
btSend.onclick =_=>
{
let info = { txt: inTxt.value }
window.parent.postMessage( JSON.stringify(info), "*")
}
window.onmessage=e=>
{
let info = JSON.parse( e.data )
sp_infoParent.textContent = info.txt
}
</script>
</body>
</html>

how to integrate spinner page with rest of HTML

I have a project where I am creating a spinner page but I am having difficulty integrating the spinner page while I am redirecting to a URL. Basically I have a multiplication program. If the answer is correct it prompts correct and goes to a specific URL(http://stackoverflow.com) and if is incorrect it goes to another URL(http://yahoo.com). Before it actually goes to those pages I would like the spinner that I created to show up first while the pages are loading. Can someone help me with this? Thanks in advance.
Here is my main HTML page(index1.html):
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="stylesheet.css">
<script
src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js">
</script>
<meta charset="ISO-8859-1">
<title>A Multiplication Game</title>
</head>
**<script>
window.addEventListener("loader", function(){
var spinner=document.getElementById("spinner");
document.body.removeChild(load_screen);
});
</script>**
<body >
<span id="mathprompt">What is <span id="num1">8</span> multiplied by
<span id="num2">E</span>?
</span>
<br>
<span id="inputrow">
<input type="text" id="inputfield">
<button id="submitbutton">Submit</button>
</span>
**<div class="loader" id="spinner"></div>**
<p id="response"></p>
<script src="script.js" type="text/javascript"></script>
</body>
</html>
Here is my JavaScript code(script.js). As you can see I have declared spinner as a variable but not sure if I should right the function for it here or in HTML:
var num1;
var num2;
var guess;
var answer;
var response;
$(document).ready(function() {
num1=document.getElementById("num1");
num2=document.getElementById("num2");
guess=document.getElementById("inputfield");
response=document.getElementById("response");
**spinner=document.getElementById("spinner");**
$("#submitbutton").click(function(){
checkAnswer();
redirectPage();
});
setNumbers();
});
function setNumbers(){
num1.innerHTML = Math.floor(Math.random() * 10)+1;
num2.innerHTML = Math.floor(Math.random() * 10)+1;
}
function checkAnswer(){
var n1 = parseInt(num1.innerHTML);
var n2 = parseInt(num2.innerHTML);
answer = n1 * n2;
if (parseInt(guess.value) == answer){
response.innerHTML = "Correct!";
} else
response.innerHTML = "Incorrect!";
}
function redirectPage(){
if (parseInt(guess.value) == answer){
window.location.href = "http://stackoverflow.com";
} else{
window.location.href = "http://yahoo.com";
}
}
And here is the code for the spinner in the css(stylesheet.css):
#charset "ISO-8859-1";
#inputrow{
background-color:#80ff80;
}
#mathprompt{
font-size: 34px;
color:orange;
text-align: center;
}
#response{
font-size: 34px;
color:white;
text-align: center;
}
body {
background-color: #8080c0;
text-align: center;
}
**.loader{
border:16px solid #f3f3f3;
border-radius: 50%;
border-top: 16px solid #3498db;
width: 240px;
height: 240px;
animation: spin 2s linear infinite;
margin-left: auto;
margin-right: auto;
text-align:center;
}
#keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}**
You seem to want to detect that an external website is loaded...you cannot detect this, in Javascript you won't have access to the "loaded" event of an external website loaded in a new tab of your browser.
All your can do is display a loading, then doing a "redirect" in javascript.
And when yahoo/stackoverflow page will be loaded (having replaced your website in the browser tab), your loader will obviously have disappeared...is it what you want ?
You have 3 cases :
If you load yahoo/stackoverflow in an iframe embedded in your page, yes you could display a loading and detect that the page is loaded in your iframe (for instance you load a page of your own in the iframe, you can in JS access to the page's content...you load Yahoo/Stackoverflow in the iframe, then when in JS you cannot access to iframe content, it means that the external page is loaded...)
if you are redirecting to the yahoo/stackoverflow page, you will only be able to display a loading before the external pages are beginning to load...
you can try to prefetch the external page, you display a loading, and when the page is loaded, then you redirect to the page...your browser will have cached almost all html elements i think (to check)...
var myPrefetchedPage;
$.ajax({
url: "test.html",
cache: false,
success: function(html){
myPrefetchedPage = html;
}
})
Preloading code in an iframe :
jQuery(document).ready(function ($) {
$app = $('.app');
$app.addClass('loading');
$iframe = $('<iframe>');
$iframe.attr({src: 'http://www.yahoo.fr/'});
$iframe.appendTo($('body'));
// When <iframe> has been loaded, remove loading spinner to reveal <iframe>
// or redirect to the page in your browser tab.
$iframe.load(function() {
$('.app').remove();
// redirect to the real page
window.location.href='http://www.yahoo.fr/';
});
});

Loading JavaScript in a Chrome Extension

This is my first post on SO and my first time making a Chrome Extension. I've read alot of documentation, but I am still unsure how to get this to work. Below are my html and js files. I want to be able to type something in the source box and have the have the word print out in the results area in real time. I have tested this code on my local host so i know it works, but for some reason it is acting up as a chrome extension.
popup.html
<!doctype html>
<html>
<head>
<title>Getting Started Extension Popup</title>
<style>
body {
min-width: 357px;
overflow-x: hidden;
}
img {
margin: 5px;
border: 2px solid black;
vertical-align: middle;
width: 75px;
height: 75px;
}
</style>
<script src="popup.js"></script>
</head>
<body>
<textarea id="source"></textarea>
<div id="result">
</div>
</body>
</html>
Here's the js:
function main() {
document.getElementById('source').keydown(function() {
var source = document.getElementById('source').value;
var outputValue = source.replace(/command/gi, "⌘")
.replace(/tab/gi, "⇥")
.replace(/return/gi, "⏎")
.replace(/option/gi, "⌥")
.replace(/control/gi, "⌃")
.replace(/esc/gi, "⎋")
.replace(/left/gi, "←")
.replace(/down/gi, "↓")
.replace(/up/gi, "↑")
.replace(/right/gi, "→")
.replace(/shift/gi, "⇧")
.replace(/eject/gi, "⏏")
.replace(/caps\s\(lock\)/gi, "⇪")
.replace(/save/gi, "⌘ + S")
.replace(/print/gi, "⌘ + P")
.replace(/find/gi, "⌘ + F");
document.getElementById("result").innerHTML = outputValue;
}
}
1) What wOxxOm said in the comment: element.keydown(function() { ... }) does not exist. This definitely comes from some jQuery code - you could use that if you add it to your extension, or you could use addEventListener.
2) You declare a function main(), but nothing ever calls it. A good place to call it would be a DOMContentLoaded event listener on document:
document.addEventListener("DOMContentLoaded", main);
function main() {
/* ... */
}

chrome extension popup same tab still not working

I used the code I found here.
But it´s still not working out to open my link out of the popup.html in the currently active tab.
popup.html
<!doctype html>
<html>
<style>
body {
min-width: 156px;
max-width: 100%;
position: relative;
vertical-align:middle;
}
div {
margin:1px 1px 1px 1px;
}
</style>
<head>
<title>I-Serv Switcher</title>
<script src="js.js"></script>
</head>
<body>
<script src="js.js"></script>
<div style="width:50px; height:50px; background-color:blue; float:left;">Click.</div>
</body>
</html>
As you can see there is a little blue div. when i add target="_blank", then google opens in a new tab. But adding the following .js should take the link out of the clicked div with href and open it in the active tab.
js.js
var hrefs = document.getElementsByTagName("a");
function openLink() {
var href = this.href;
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
var tab = tabs[0];
chrome.tabs.update(tab.id, {url: href});
});
}
for (var i=0,a; a=hrefs[i]; ++i) {
hrefs[i].addEventListener('click', openLink);
}
the permission "tabs" is given in the manifest.json
What am i doing wrong ?
Did I forget something ?
Your code executes at the moment the <script> tag is read.
The rest of the DOM is not constructed yet; document.getElementsByTagName("a") is, therefore, empty.
To fix this, you need to wrap your code in a DOMContentLoaded event:
document.addEventListener("DOMContentLoaded", function() {
var hrefs = document.getElementsByTagName("a");
/* ... */
});
Note that you can easily debug your popup by right-clicking your extension's button and selecting "Inspect popup"

Insert Webpages into Div instead of iframe?

Here's the entire code for my loop.html file. It first pulls the list of urls from a separate XML file that is in the same directory and then loops through them, given specified time. The time element is the amount it will wait until it cycles to the next page. What I want to do is to use DIV to cycle through the URLs, since iframe is not supported in all the browsers and does not display some of the content when I run the html script. The thing I am not sure about is what to do with the "dashboard.url"--when i want to use a div?
I found this piece of code from a different site--that when you replace the frams['theDisplay'] line with, it sets the div to a webpage--but I want to have something like this, using the dashboard.url
$("#siteloader").html('<object data="http://latimes.com" />');
I am sorry if this is a really long question, and if you get frustrated. I am just trying to learn as I go. Thank you!
Example of list.xml format:
<list>
<url>
<link>http:latimes.com</link>
<time>2</time>
</url>
<url>
<link>http:stackoverflow.com</link>
<time>4</time>
</url>
</list>
Entire HTML code:
<!DOCTYPE HTML>
<!--Created by Megan Chiu - 30 June 2013-->
<html>
<!-- CSS -->
<style type="text/css">
displayArea {
margin: 0;
width: 100%;
}
html, body {
height: 100%
width: 100%;
}
div {
height: 100%;
width: 100%
}
object {
width: 100%;
min-height: 100%;
}
</style>
<head>
<meta charset="UTF-8">
<style type="text/css">
body, html { margin: 0; padding: 0; width: 100%; height: 100%;
overflow: hidden; }
iframe { border: none; }
</style>
<script src="http://code.jquery.com/jquery-1.10.1.min.js"
type="text/javascript"></script>
<script src="http://code.jquery.com/jquery-1.7.2.min.js"></script>
<script type="text/javascript">
var Dash = {
nextIndex: 0,
dashboards: [],
loadXML: function() {
$.ajax( {
type: "GET",
url: "list.xml",
dataType: "xml",
success: Dash.renderXML
});
},
renderXML: function(xml) {
$(xml).find("url").each(function() {
var _link = $(this).find('link').text();
var _time = $(this).find('time').text();
Dash.dashboards.push({url:_link, time:_time});
});
Dash.display();
},
display: function()
{
var dashboard = Dash.dashboards[Dash.nextIndex];
frames['theDisplay'].location.href = dashboard.url;
Dash.nextIndex = (Dash.nextIndex + 1) % Dash.dashboards.length;
setTimeout(Dash.display, dashboard.time * 1000);
}
};
window.onload = Dash.loadXML;
</script>
</head>
<body>
</body>
<iframe id="theDisplay" width="100%" height="100%"></iframe>
</html>
<div id="content1"></div>
<script>
document.getElementById("content1").innerHTML='<object type="text/html" data="header.php" ></object>';
alert('Load_Ok');
</script>
You cannot load content from another website just with pure JavaScript. Period.
http://en.wikipedia.org/wiki/Same_origin_policy
So what you can do? You can make a web request from your server and get Http response from remote server and put them into div element.
<div><%=(new WebClient()).DownloadString("http://www.stackoverflow.com")%></div>
But one of biggest problem is that, since you will download all styles and scripts from remote website then your page probably will not look good. Not even human readable. And if you will keep hitting from same IP to those servers you will may blocked by them.
Good luck.

Categories

Resources