I am developing Google Chrome extension. Each time my JavaScript source changes, I find myself having to click "load unpacked extension" again to have the changes take effect.
Reloading the extension at each iteration is very tedious. Can it be avoided?
Depends on the asset, lets review:
Asset ----------------------------------------- Action needed
popup.html HTML -------------------------- Refresh browser page
popup.html JS ------------------------------- Refresh browser page
contentscript via manifest ----------------- Reload extension
contentscript via executeScript (code) - location.reload(true) on background page
contentscript via executeScript (file) ---- Refresh browser page
background.html HTML ------------------- location.reload(true) on background page
background.html JS ------------------------ location.reload(true) on background page
For more information on how to do the location.reload(true) see the page on debugging
The content script requiring a plugin reload has been brought up recently and acknowledged by the chromium team:
http://code.google.com/p/chromium/issues/detail?id=104610
Consider using programmatic injection (contentscript via executeScript (file)) to avoid having to reload the plugin for content script updates.
Related
I have a MV2 Chrome extension that on the popup page I added a "Shortcut" link so that user can access chrome://extensions/shortcuts by clicking it.
However, after upgrading to MV3, the link doesn't work.
Should I simply remove this feature?
You can resolve this issue by opening the page programmatically.
add some suitable selector to the link (popup html):
Configure Commands
add an event listener to open the shortcuts page (in popup script):
// get the DOM node
const link = document.getElementById("commands-link");
// add click event handler that opens the shortcuts page
link.addEventListener('click', () => chrome.tabs.create({
url: "chrome://extensions/configureCommands"
}));
I have a Firefox OS app in which I have opened an web page via mozbrowser attribute.
<iframe id="inlineFrameExample"
mozbrowser=true
src="<some external link>"
</iframe>
How can we retrieve DOM content of the iframe?
You can retrieve DOM content via executeScript() method present in Browser API. It will run the script against the iframe and will allow you to do DOM computation tasks.
Note: The example mentioned in the document didn't worked but the syntax given below worked for me. The diff is is passed as string.
iframe.executeScript('put_your_script_here', {origin: 'domain_name'});
Is there any way to debug chrome extension using debugger ( break points and step in/out)
beside console.log ?
Chrome 70.x debugging of chrome background scripts is broken, especially when you dynamically load them and they are not in the manifest. Have a ticket open to get it fixed; however they have not been very helpful; however found a work around...
Put a console.log("yourvariablenamehere") in your background.js script.
Hit F12 to open the dev tools, anchored to the bottom of the web page.
Load the background script via a button in your popup.html. Something like this from a button event...
var guid = CreateGuid();
chrome.tabs.executeScript(null, { file: "script/jquery-3.3.1.js" }, function () {
$.get("script/scrollPage.js?ver=" + guid, function (sScriptBody, textStatus, jsXHR) {
chrome.tabs.executeScript(null, { code: sScriptBody });
}, "text");
});
In the dev tools console you should see your logged variable. On the same line as the logged message is a VM with a number tacked onto it, a virtual script page. Select that VM page and then you get to the background script! Now put a breakpoint in the virtual script page, click the same button in your popup.html and it gets hit. And when you reload the popup and execute the background script that breakpoint is hit!
Hope this helps.
If you want to inspecting content scripts, a great method I found is using Console by selecting your extension in javascript context:
By selecting the extension you will have access to the global objects within that extension.
Reference:
Using the Developer tools to debug your extension
I am trying to write a Chrome devtools extension for a JS SDK we have developed. This SDK has an API addEventListener (the events are not DOM events) that I would like to use to be able to display all the events that are being published in the devtools panel I made.
Basically I would like to be able to have the following code in my devtools page script :
chrome.devtools.inspectedWindow.eval(
"mySDKonTheContentPage", function(result, isException){
mySDK =result;
mySDK.addEventListener("myEvent", function(){
doSomethingInDevtoolsUI();
});
});
Since content scripts don't have access (do they?) to the page's JS objects, I don't really know where to start.
In the script on your page, you can use window.postMessage to send your data to the content script. From there you can set up communication between the content script and the DevTools panel via a background page.
See: Messaging from Injected Scripts to the DevTools Page and Messaging from Content Scripts to the DevTools Page for examples of this in the documentation.
(Cross posted here)
Hi,
I have a sandboxed page (specified in my manifest) which is loaded into an iframe in my extension's background page. From within my sandboxed page, I'd like to open a new window and write to it, i.e.:
var win = window.open(); win.document.write('<p>Hello!</p>');
This works from my extension's background page and from regular web pages, but when invoked from either content scripts or my sandboxed page, the window opens, but I cannot access the win object (it's defined, but empty---console.log outputs "Window {}").
I assume this is due to same-origin policies (with every window being given a uinque-origin within the sandboxed environment). However, since the window opens an about:blank page, I'm confused why this would matter.
Is this a feature? Is there a parameter I can add to my manifest to avoid this? And does anyone know of work-arounds that don't involve using postMessage back to my background page? My ideal solution is to have my sandboxed script open a new window and interact with it directly, not with message passing.
I can provide a full example if necessary, but I'm hoping someone might just know off the top of their head. I'm running Chrome 24.0.1312.57 on Mac and 24.0.1312.68 on Ubuntu if that helps.
Thanks,
Hank
Content scripts, by definition, are part of external regular web pages you load so I'm not really sure how your script could work on a "regular web page" but not the content script. Do you mean the code works when you embed it in your own pages, but not in other pages via the content script?
Regardless, if the script is working properly from your background page, you could always try messaging. (more here: http://developer.chrome.com/extensions/messaging.html)
Script for your sandbox/contentscript:
//send message to background page
chrome.extension.sendMessage({todo: "newWindow"});
In background page:
//create a listener
chrome.extension.onMessage.addListener(
function(request, sender) {
if (request.todo === "newWindow") {
//do your stuff here
var win = window.open(); win.document.write('<p>Hello!</p>');
}
});
Per the cross-post here, the issue is indeed that the opened window is given a unique origin. This was intentional as the members of the standards working group (SWG) felt that it would be more secure to not make an exception for about:blank pages where they inherit the sandbox's origin.
However, to get around this issue, at least for my purposes, I can use the following method. First, forget sandboxing. This workaround uses an iframe embedded in a background page with the src url set to data:text/html,.... This gives a unique origin to the iframe so it's no longer in extension space. That means eval can be used and chrome apis cannot be accessed. Unlike in a sandbox, windows opened from the iframe share that same origin as the iframe, allowing created windows to be accessed. For example:
In a background html page:
<html>
<head>
...
<script src="background.js"></script>
...
</head>
<body>
...
<iframe id="myframe"></iframe>
...
</body>
</html>
In background.js:
...
document.getElementById('myframe').setAttribute('src', 'data:text/html,'+
encodeURI('<html><head>'+
'<script src='+chrome.extension.getURL('jquery.js')+'></script>'+
'<script src='+chrome.extension.getURL('myscript.js')+'></script>'+
...
'</head><body></body></html>'
));
...
In myscript.js
jQuery(document).ready(function(){
...
// To receive messages from background.js.
window.addEventListener('message', function(e){ ... } );
// To send messages to background.js.
parent.postMessage({...}, '*');
// To open AND ACCESS a window.
var win = window.open();
win.document.write('Hello'); // Fails in sandbox, works here.
// Eval code, if you want. Can't do this from an extension
// page loaded normally unless you allow eval in your manifest.
// Here, it's okay!
eval( 'var x = window.open(); x.document.write("Hi!")' );
// No chrome apis.
chrome.log( chrome.extension ); // -> undefined
chrome.log( chrome.windows ); // -> undefined
// No direct access to background page (e.g., parent).
chrome.log( parent ); // -> Window with no properties.
...
});