How do I modify DOM html page from background script? The html page exists in the extension's root folder. When then page is opened the URL is looked like "chrome-extension://hffffemnacblbojccelnkhnafndfkhgc/block.html"
File tree in my extension:
css/
bootstrap-theme.css
bootstrap-theme.css.map
bootstrap-theme.min.css
bootstrap.css
bootstrap.css.map
bootstrap.min.css
popup.css
fonts/
img/
128-128.png
1413232635_virus detected 2.png
16-16.png
48-48.png
js/
block.js
bootstrap.js
bootstrap.min.js
event.js
jquery-1.11.1.js
jquery.cookie.js
block.html
manifest.json
popup.html
manifest.json
{
"manifest_version": 2,
"name": "Viper Security ATD",
"version": "1.0",
"description": "Viper Security Advance Threat Defence.",
"icons": {
"48": "img/48-48.png",
"128": "img/128-128.png"
},
"browser_action": {
"default_icon": "img/16-16.png",
"default_title": "Viper Security Advance Threat Defence",
"default_popup": "popup.html"
},
"background": {
"scripts": ["js/jquery-1.11.1.js","js/event.js"],
"persistent": true
},
"permissions": [
"<all_urls>",
"tabs",
"webNavigation"
]
}
I want Modify dom of a HTML page of my extension from background javascript. The page exists on my extension's root. the page url looking like:chrome-extension://hffffemnacblbojccelnkhnafndfkhgc/block.html
Technically, you can do that.
If the page with block.html is open, the background page can get a reference to its window object with this code:
var win = chrome.extension.getViews("tab").filter(
function(w) {return w.location.pathname == "/block.html"}
)[0];
win.document.getElementById("foo").value("bar"); // Modify that page
win.somefunc(); // Call a global function in that page
// etc.
It is probably cleaner, however, to use Messaging and send messages from the background script that will be received by every block.html open.
Note: you can't modify the actual files, you can only modify the DOM of an opened document.
Related
I'm testing a Chrome extension that can display some information about a PDF file the user is currently viewing, ideally inserted as an iFrame. I don't want this to happen automatically, so I'm using a background script to listen for the click event, and then injecting the content script. (The extension communicates with an external server but that isn't relevant to this question.)
Here is my manifest.json:
{
"name": "Test",
"version": "0.0.1",
"manifest_version": 2,
"description": "Test",
"background": {
"scripts": [
"background.js"
],
"persistent": false
},
"browser_action": {
"default_title": "Test"
},
"permissions": [
"activeTab"
]
}
Here is background.js:
hrome.browserAction.onClicked.addListener(function (tab) {
chrome.tabs.executeScript({'file': 'popup.js'})
});
And here is popup.js:
var widgetHtml =
'<div id="main" style="position: fixed;top: 14px;">'+
' <p>some stuff goes here</p>'+
'</div>';
var iframe = document.createElement('iframe');
document.body.insertBefore(iframe,document.body.firstChild)
iframe.contentDocument.body.innerHTML = widgetHtml;
This works like a charm on non-PDF pages, but it doesn't inject anything on PDF pages. If I use the exact popup.js script in the console, it of course works fine as well.
I've read through Run a Chrome Plugin On a PDF Page, which tries to automatically detect PDFs, and this one, How to inject content script view on the PDF viewer?, but it doesn't seem to work. What am I missing?
I'm currently trying to make sense of Google Chrome Extension development, but I'm having issues understanding it correctly.
I'm developing an extension that hosts a list of URLs and opens them on click. This sounds like a trivial task, but it doesn't work. Probably I'm doing something blatantly wrong.
Screenshot
It's not styled, but that's step 2. Basically, I want to open a shortcut on click:
manifest.json
{
"manifest_version": 2,
"name": "Chrome Shortcuts",
"description": "This extension provides shortcuts to locations in Google Chrome",
"version": "1.0.0",
"browser_action":
{
"default_icon": "icon.png",
"default_popup": "popup.html"
},
"content_scripts":
[
{
"js": [ "popup.js" ],
"matches": [ "http://*/*", "https://*/*" ]
}
],
"permissions":
[
"tabs",
"http://*/*"
]
}
popup.html
<!doctype html>
<html>
<head>
<title>Chrome Shortcuts</title>
<script src="popup.js"></script>
</head>
<body>
<ul>
<li>Settings - Passwords</li>
</ul>
</body>
</html>
popup.js
function OpenShortcut(location)
{
chrome.tabs.create({ url: location });
}
You cannot open chrome:// URLs using standard methods. This is a privileged page and the navigation will fail.
Instead, you need to use tabs API. Specifically,
chrome.tabs.create({url: "chrome://settings/passwords"});
Add active: false if you need it to open in background without closing the popup.
I completely missed the fact you're doing it already, sorry! The issue is with trying to activate your code with href="javascript:[some code]".
This, as well as onclick="[some code]", will fail in a Chrome extension due to the Content Security Policy. Specifically, inline code is not allowed (and you cannot modify the CSP in a way that allows it).
The docs give a solution to this - assign the handler from your code, i.e.
document.addEventListener('DOMContentLoaded', function () {
document.getElementById('link1').addEventListener('click', function() {
OpenShortcut('chrome://settings/passwords');
});
});
For this to work, add an id attribute to your links. DOMContentLoaded wrapper is required, since your popup.js is executed before your node exists in the DOM.
When I inspected the page, script is injected as expected. But in the console I get Denying load of chrome-extension://lkklhmfekbnfjhmcapngedajgkfbmapm/lib/codemirror.js. Resources must be listed in the web_accessible_resources manifest key in order to be loaded by pages outside the extension.
manifest.json
{
"name":"test",
"description":"Test description",
"version":"1.0",
"manifest_version": 2 ,
"browser_action": {
"default_icon": "icon.png"
},
"content_scripts": [
{
"matches": ["file:///*test*"],
"js": ["test.js"]
}
],
"web_accessible_resources": ["lib/codemirror.js"]
}
test.js
var srcArray = ["lib/codemirror.js"];
function AddScript(value)
{
var s = document.createElement("SCRIPT")
s.src = chrome.extension.getURL(value);
s.onload = function() {
this.parentNode.removeChild(this);
};
(document.head||document.documentElement).appendChild(s);
}
srcArray.forEach(AddScript);
I cannot figure out what may be causing the issue. Any advice would be appreciated.
I'm not sure, but if you want to insert some scripts to some page, you can use chrome.tabs.executeScript API. That is good way, and you don't care about web_accessible_resources
How can I create an extension for Chrome that adds an icon to the toolbar, and when you click it, it opens a new tab with some local web page (for example: f.html)?
I saw this question, but it doesn't really explains what should I add in the manifest file...
This is not true for newer chrome apps.
Newer chrome apps having manifest_version: 2
requires the tabs be opened as:
chrome.browserAction.onClicked.addListener(function(activeTab)
{
var newURL = "http://www.youtube.com/watch?v=oHg5SJYRHA0";
chrome.tabs.create({ url: newURL });
});
Well, in the extensions docs, it states in manifest, you would need to include "tabs" as its permission. Same way they explain the hello world application:
Manifest File:
{
"name": "My Extension",
"version": "1.0",
"description": "Opens up a local webpage",
"icons": { "128": "icon_128.png" },
"background_page": "bg.html",
"browser_action": {
"default_title": "",
"default_icon": "icon_19.png"
},
"permissions": [
"tabs"
],
}
Within the background page, you listen to the mouse click event on the browser action.
chrome.browserAction.onClicked.addListener(function(tab) {
chrome.tabs.create({'url': chrome.extension.getURL('f.html')}, function(tab) {
// Tab opened.
});
});
As you noticed above, you will see that I used the question you saw in the other post. Note, this isn't tested, but I believe it should work.
chrome.tabs.create need the permission of "tabs".
Simply using window.open in extension without need of any permission. and the code is shorter. I suggest this solution.
window.open(url,'_blank');
I have tried many ways( all documented procedures)to inject script into a specific page upon checking URL at onUpdated.addListener. Finally the below code with 'executescript' seems to work, but not perfectly. I could able to get alerts but can not able to find document elements of the page through getElementById/getElementsByName.
When I inspected the page, script is injected. But in error console I get:
Denying load of chrome-extension://jfeiadiicafjpmaefageabnpamkapdhe/js/Leoscript.js. Resources must be listed in the web_accessible_resources manifest key in order to be loaded by pages outside the extension.
Manifest.json:
{
"name": "Leo Extension for Job Boards",
"version": "1.6",
"manifest_version": 2,
"content_security_policy": "script-src 'self'; object-src 'self'",
"description": "Leo Extension",
"background": {
"scripts": ["js/Leojshelper.js"],
"persistent": true
},
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["js/eventPage.js"],
"run_at" : "document_start"
}
],
"icons":{"48":"images/bob48.png", "128":"images/bob128.png"}, //Define any icon sizes and the files that you want to use with them. 48/128 etc.
"browser_action": {
"default_icon": "images/bob.png", // What icon do you want to display on the chrome toolbar
"default_popup": "LeoExtwatch.html" // The page to popup when button clicked.
},
"permissions": [
"tabs", "<all_urls>" // "http://*/*","https://*/*" // Cross Site Access Requests
],
"web_accessible_resources": ["js/LeoScript.js"]
}
I have also given 'web_accessible_resources' permission to the script, but still no success. Code in background script:
chrome.tabs.onUpdated.addListener(function (tabId, changeInfo, tab) {
if (changeInfo.status == 'complete') {
if (tab.url.indexOf("in.yahoo") !== -1) {
chrome.tabs.update(tabId, { url: "https://login.yahoo.com/config/mail?.intl=us" });
chrome.tabs.executeScript(tabId, {
code: "document.body.appendChild(document.createElement('script')).src='" +
chrome.extension.getURL("js/LeoScript.js") + "';"
}, null);
Code in LeoScript.js, which will be injected into specific page.
$(document).ready(function () {
alert('injected');
document.getElementById('username').value='aaaaaaa';
});
Content Script :eventPage.js which I used to inject script.
var script = document.createElement('script');
script.src = chrome.extension.getURL("js/Leoscript.js");
(document.body || document.head || document.documentElement).appendChild(script);
Please point me at any changes in the above code that will solve the permission issues. Thanks in advance.
UPDATE: Finally figured out your problem. In eventPage.js, you tried to inject js/Leoscript.js, which is NOT whitelisted, instead of js/LeoScript.js (with a capital 'S'), which is whitelisted. Note that URLs are case-sensitive!
chrome.tabs.executeScript(tabId, {file: 'js/LeoScript.js'});
LeoScript.js:
alert('injected');
document.getElementById('username').value='aaaaaaa';
EDIT:
This is working version where combination of web_accessible_resources and Injection is used
manifest.json
{
"name":"Off Screen Tabs Demo",
"description":"This demonstrates Off Screen Tabs API",
"manifest_version":2,
"version":"1",
"permissions":["tabs","<all_urls>"],
"browser_action":{
"default_icon":"screen.png",
"default_popup":"popup.html"
},
"web_accessible_resources": ["js/LeoScript.js"] ,
"permissions":["tabs","<all_urls>"]
}
LeoScript.js
alert("Injected..");
popup.html
<html>
<head>
<script src="popup.js"></script>
</head>
<body>
</body>
</html>
popup.js*
document.addEventListener("DOMContentLoaded",function (){
chrome.tabs.executeScript( {"file": "js/LeoScript.js"});
});
Let me know if you still have problem in getting it running
Many will land up on this page for this error because they have not included their images/web resources in the manifest.json file. The link to the api documentation is helpful, so sharing it: web resource in manifest