Edit page HTML through external Javascript in a Chrome Extension - javascript

I'm working on my first extension ever and I'm somewhat stuck with it, so I'd like the community to give me some orientation on how to do it.
What I want to do is a basic Tab manager, which in first place should (1) read all the open tabs in the browser, (2) display them in a webpage, and (3) allow reordering in the webpage and reflect that in the browser itself.
UPDATED
So far I've already done (1) with the following code in a file named eventPage.js:
chrome.browserAction.onClicked.addListener(function(activeTab){
var newURL = "main.html";
chrome.tabs.create({ url: newURL });
});
chrome.tabs.query({}, function(tabs) {
console.log(tabs);
for (var i=0; i<tabs.length; i++) {
var tabURL = tabs[i].url;
console.log(tabURL);
writeURL(tabURL);
}
});
function writeURL(tabURL) {
var node = document.getElementById('div1');
node.innerHTML = '<p>' + tabURL + '</p>';
}
Where I'm having problems is with (2) because I don't know how to display the information of the tabs in the newly opened main.html; as far as I understand and tested, I can't add script content in the body of the main.html file.
UPDATED
The main.html file at this point doesn't do a thing, what i'd like to do is print all far just
<!doctype html>
<html>
<head>
<title>Tab & Window Manager</title>
<script src="eventPage.js"> </script>
</head>
<body>
Just testing
<div id="div1">
<p id="p1">This is part of the native HTML.</p>
</div>
</body>
</html>
The output I get so far is:
just the last tab, which actually is the extension tab, but I want all tabs to be listed.
So, how can I display all the tabs information in the newly opened html file and what's the best way to do it? I haven't found any example or guide about this specific use case.
Any help will be greatly appreciated.

Related

JavaScript isn't loaded when using link element

Im trying to make a website with JavaScript popups. Basically, when you click a link an alert or prompt comes up saying "You are now entering the [enter webpage name here] section."
For some reason, when I click the link, it will open the page but ignore any JavaScript! Here is the basic code:
HTML:
<html>
<head><link rel="text/javascript" href="effects.js" /></head>
<body>
Click here
</body>
</html>
JavaScript (effects.js):
function common_lang() {
var enterCommon = prompt("You are now entering the Common Languages section.");
}
I don't get why this won't work! Does anyone have any ideas? Also, is there a way to make this more efficient? And I need the file in the same window so I can't use any window.open jazz. But efficiency isn't a priority, remember!
You should use the script tag instead of link
<script type="text/javascript" src="effects.js">
First you need to change the link tag to script like:
<script type="text/javascript" src="effects.js"></script>
Second, this is because you are using the href attribute so the link just redirects you to common_code.html
if you want to navigate to the link based on user prompt selection you can do it like:
Click here
function common_lang() {
var enterCommon = prompt("You are now entering the Common Languages section.");
if(enterCommon) {
var a = document.createElement('a');
a.href = "common_code.html";
a.dispatchEvent(new Event('click'));
}
}

Unable to call JavaScript function in html on button click

I was making a Chrome extension, for which I have an html file, a JavaScript file which opens a modified link in a new tab, the manifest file and the icon.
It works fine but now I want the javascript function to work only when the user clicks a button. So I made a button in the html file, put the js code inside a function and called the function using onclick.
But for some reason, it is not working. On clicking the button nothing seems to happen. I have tried reloading the extension. Also, I took a working example of a simple program in which on clicking the button, a simple "Hello world" message is displayed using alert().
This works fine when I open the html page directly in chrome but when I replaced this with the function that I made, nothing seems to happen on clicking.
Can someone please find the bug/problem?
The urltry.html file is:
<!DOCTYPE html>
<html>
<button onclick="editorial()">View Editorial</button>
<script>
function editorial()
{
chrome.tabs.query({currentWindow: true, active: true}, function(tabs){
var tab_url=tabs[0].url;
var new_url=tab_url.slice(11);
chrome.tabs.create({ url:"http://www.discuss." + new_url});
});
}
</script>
</html>
Due to the default Content Security Policy (CSP) in Google Chrome extensions, the following is disallowed:
Eval and related functions
Inline JavaScript
The suggestion, as provided by Google Chrome Extensions documentation on SCP is to place the code to a separate file and use proper binding to click event from JavaScript. See below.
Your HTML file:
<!DOCTYPE html>
<html>
<head>
<script src="editorial.js"></script>
</head>
<body>
<button id="viewEditorial">View Editorial</button>
</body>
</html>
Your JavaScript file, editorial.js
function editorial() {
chrome.tabs.query({currentWindow: true, active: true}, function(tabs){
var tab_url=tabs[0].url;
var new_url=tab_url.slice(11);
chrome.tabs.create({ url:"http://www.discuss." + new_url});
});
}
document.addEventListener('DOMContentLoaded', function () {
var btn = document.getElementById('viewEditorial');
if (btn) {
btn.addEventListener('click', editorial);
}
});
Note: don't forget that you need to declare "tabs" permission to be able to modify the URL. See the tabs documentation.
You must put your button inside the body tag, otherwise many bad things can happen and probably the browser goes in the quirks mode.
Solution:
<!DOCTYPE html>
<html>
<head>
<script>
function editorial()
{
chrome.tabs.query({currentWindow: true, active: true}, function(tabs){
var tab_url=tabs[0].url;
var new_url=tab_url.slice(11);
chrome.tabs.create({ url:"http://www.discuss." + new_url});
});
}
</script>
</head>
<body>
<button onclick="editorial()">View Editorial</button>
</body>
</html>
You can try with this,
<body>
<button onclick="javascript:editorial()">View Editorial</button>
</body>
This will work in Microsoft EDGE browser also.

Add HTML when a certain checkbox is checked

I want to add HTML to a page a certain checkbox is clicked (right now it's Reddit's 'Remember Me' checkbox, but in the future I'm want it to work with more checkboxes). I have made this content script, but I have no idea if it's doing anything to the opened chrome tab.
\\content_script.js
$(document).ready(function() {
var inputTable = document.getElementByTagName('input');
for(var i=0; i<inputTable.length; i++){
if((inputTable[i].getAttribute('type')=='checkbox') && (inputTable[i].getAttribute('name')=='rem')){
var rememberMe = inputTable[i];
}
}
document.addEventListener('DOMContentLoaded', function () {
rememberMe.addEventListener('change', changeHandler);
});
}
function changeHandler(){
if(rememberMe.checked){
var remTrack = chrome.extension.getURL ("rememberme.htm");
document.body.insertBefore (remTrack, document.body.firstChild);
}
else{
}
}
rememberme.htm is the html that I want to add containing the mp3 that I want to play (Will this work if the page isn't necessarily in HTML5?).
<!DOCTYPE html>
<html><head>
<title>Remember Me</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link href="style.css" rel="stylesheet" type="text/css">
<script type="text/javascript" src="jquery.min.js"></script>
<script type="text/javascript" src="HelloWorld.js"></script>
</head><body>
<audio autoplay loop>
<source src="remember.mp3" type="audio/mpeg">
</audio>
</body></html>
From what I've been reading it seems like I should just make the content script call whatever javascript that I want the open chrome tab to run, but I don't know how to do this while also inserting HTML into the open chrome tab. Any help is appreciated, and if the tag won't work if the page is not in HTML5 then what is the easiest way to play the mp3 in javascript?
Reddit is my favorite page, I guess that Redditors should stick together, so here's your script refactored.
It appends a track with 'God Save the Queen' played by United States Navy Band to Reddit homepage after clicking remember me button. When specifying audio source you need to give an url where the track is located, just like with images. You also don't need to add head and body, and the way you are fetching your html it is mistaken, you're actually getting only an url not html of your extension.
window.onload = main();
function main() {
var elem = document.getElementById('rem-login-main');
elem = addEventListener('change',changeHandler);
}
function changeHandler () {
var yourAudio = document.createElement('audio');
yourAudio.src = "http://upload.wikimedia.org/wikipedia/commons/d/de/United_States_Navy_Band_-_God_Save_the_Queen.ogg";
yourAudio.controls = true;
yourAudio.autoplay = true;
var parentNode = document.getElementById('header');
parentNode.insertBefore(yourAudio);
}
To test it go to Reddit, click F12, open chrome browser devtools console, within devtools go to tab sources, find tab snippets, right click, create new snippet, copy paste this code, save it, click play button on the right (it says 'run snippet' when you hover over it). If you want to make it an extension you need manifest.json.
Hope it works, don't remember to upvote or accept an answer if you find it useful.

Javascript print div not working in Safari

I have a Javascript function that prints the contents of two elements in a webpage. It works in Chrome, Firefox and IE but Safari just brings up an empty window and if I select print, it simply prints a blank page.
Here's my code:
var content = "<!doctype html><html><head>";
content += '<link rel="stylesheet" href="/css/normalise.css" type="text/css" />';
content += '<link rel="stylesheet" href="/App_Themes/CS2011/StyleSheet.css" type="text/css" />';
content += "</head><body>";
//Find the div to insert the rest of the html after
var contractToFind = $(divElement).parent().find("div").get(0);
//Insert rest of code
content += contractToFind.innerHTML;
content += "</body></html>";
//Set up print window and print
var printWindow = window.open('', '', params);
printWindow.document.write(content);
printWindow.document.close();
printWindow.focus();
printWindow.print();
//Close the window
printWindow.close();
Is there a way I can modify my code to allow it to render the page properly in Safari so I can print it? Preferably without using additional plugins.
Edit: Thanks Eric but that didn't work for me. Adding a time delay to the print seems to work well although it's not ideal, even a 10ms delay solves the issue. The line I used was:
setTimeout(this.print, 100);
I found a solution to this problem. The problem resides in the fact that window.print() is not standard for all browser and Safari probably takes a different approach on when triggering it.
I changed a little your code so maybe this solution can't fit your possibility but it works for all browser (tested on Safari, FF, Chrome, IE8).
Note that you need to have a different page for the popup content (I changed the code to retrieve the contract to make a sample for myself, hope you will figure out how to get contract content).
The code:
HTML for the page that opens the popup
<body>
<input type="button" id="popup" value="Open Popup" />
<div id="yourContract">
<div>blablabla</div>
<div>blablabla2</div>
<div>blablabla3</div>
<table>
<tr>
<td>blablabla td1</td>
<td>blablabla td2</td>
</tr>
<tr>
<td>blablabla td3</td>
<td>blablabla td4</td>
</tr>
</table>
</div>
</body>
<script>
$("#popup").click(function(){
var win = window.open("static.html");
});
</script>
HTML for the popup (static.html):
<!DOCTYPE html>
<html>
<head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
<script>
$.holdReady(true);
$.getScript("print.js", function() {
$.holdReady(false);
});
</script>
</head>
<body>
<script>
var contract = window.opener.$("#yourContract").html(); //change to fit your needs
$("body").html(contract);
</script>
</body>
</html>
JS file (print.js) called by static.html
$(document).ready(function(){
window.print();
window.close();
});
How does it works:
static.html consists of two script section. The section in the body loads via javascript the content in the page.
The section in the head prevent the document to trigger ready status by setting holdReady to true. Then it loads print.js which waits for document to be ready, but we will decide the exact moment because we are preventing it.
After the script is included in the page holdReady is set again to false, triggering the ready status to document and calling the print() and close() functions on the window.
This however occurs after the browser has loaded all the page content, so you will see the preview in the popup page and the print dialog.
Hope this solution is what you need.

Prevent webpage dialog from spawning new browser window?

I have an open web page dialog. From there, what I'd like to do is when the user clicks on a link, refresh the contents of the dialog with modified query string parameters. The problem I am running into is that rather than refresh the same web page with new parameters, a new browser window pops up.
Here is the page used to open the dialog:
<!DOCTYPE html>
<html>
<head>
<title></title>
<script type="text/javascript">
function ShowPopup() {
var popWinFeatures = "dialogWidth: 800px;dialogHeight:600px;center:yes;status:no;scroll:no;resizable:yes;help:no";
window.showModalDialog("webPageDialog.html","PopUpWin",popWinFeatures);
}
</script>
</head>
<body>
Click For Modal
</body>
</html>
and this is the code within the webpage dialog that attempts to refresh the webpage with changed query string parameters:
<!DOCTYPE html>
<html>
<head>
<title></title>
<script src="scripts/jquery-1.6.4.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function(){
var queryString = "?ab=123";
var newURL = window.location.protocol + "//" + window.location.host + "/" + window.location.pathname;
$('#testLink').attr('href', newURL+queryString);
});
</script>
</head>
<body>
Please Click Me
</body>
</html>
I've also tried using window.open as well as setting window.location. And I've also tried setting window.location.href but the result was the same.
the new browser window displays exactly what I expect. It's just not in the same window.
Thoughts?
Since posting this question, I came up with two possible solutions. In case anyone comes after me and wants to know what I ended up doing, here you go!
The first was just to make the popup non-modal. Removing the modal piece gave me the behavior exactly like I expected it. This didn't work in my situation however for a different reason... It seems that the session cookie was not carried over which in this web app, would cause the log-in page to be displayed before then displaying the correct page. This struck me as odd, but ran out of time to investigate why that was happening.
Second (and this is the solution i ended up going with) was to use an iframe, and display what i needed within the iframe. Definitely not my favorite, but it works!

Categories

Resources