chrome extension new tab override but does not focus on input element [duplicate] - google-chrome-extension

With Chrome 27, it seems that extensions that override Chrome's New Tab Page can't take focus away from Chrome's Omnibox like they used to in previous versions of Chrome.
Is there a new way to focus an input box in a New Tab Page, or has this functionality been disabled completely? :(
To test this, create an extension folder with three files:
1. manifest.json:
{
"name": "Focus Test",
"version": "0",
"minimum_chrome_version": "27",
"chrome_url_overrides": {
"newtab": "newTab.html"
},
"manifest_version": 2
}
2. focus.js:
document.getElementById('foo').focus();
3. newTab.html:
<html>
<body>
<input id="foo" type="text" />
<script type="text/javascript" src="focus.js"></script>
</body>
</html>
Then, when you load the extension and open a new tab, the input field does not get focused on the new tab page.
I have also tried adding the autofocus attribute to the input field, but no luck either. The extension's new tab page can't take focus away from Chrome's Omnibox.
Any ideas? Is this a bug or a new "feature"?

ManifestV3 update
This answer is adapted from https://stackoverflow.com/a/11348302/1754517.
This has been tested with both Manifest V2 and V3.
Tested in Google Chrome 99.0.4844.51 64-bit (Windows 10).
Replace the content of focus.js with:
if (location.search !== "?x") {
location.search = "?x";
throw new Error; // load everything on the next page;
// stop execution on this page
}
Add the autofocus attribute to the <input>.
Go to the Extensions page in Chrome and click the Load unpacked button. Choose the folder of your extension.
Open your new tab page. You might see a modal dialogue reading Change back to Google?. Click Keep it to keep your custom new tab page.
Inline Javascript - Manifest V2 only
If you're inlining the Javascript in the HTML file, then you'll need to take some extra steps:
After adding your inline Javascript to your HTML file, open DevTools (F12 key) and observe the error output in the Console. Example output you should see:
Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'self' blob: filesystem:".
Either the 'unsafe-inline' keyword, a hash ('sha256-MK0Gypb4mkZTI11eCOtWT+mGYcJNpN5zccvhfeaRb6E='), or a nonce ('nonce-...') is required to enable inline execution.
Select & copy this hash.
Add a line to manifest.json to allow the JS to run, pasting in the hash you just copied between the single-quotes. E.g.:
"content_security_policy": "script-src 'self' 'sha256-MK0Gypb4mkZTI11eCOtWT+mGYcJNpN5zccvhfeaRb6E='"
Go to the Extensions page again. Remove the extension, then re-add it using the Load unpacked button.
Open your new tab page. Your extension should now autofocus on the <input>.
Note inlining only works with Manifest V2; Manifest V3 returns a failure message when attempting to load the extension (even with a properly formed "content_security_policy" object in manifest.json, to replace the Manifest V2 "content_security_policy" string):
Failed to load extension
File C:\path\to\extension
Error 'content_security_policy.extension_pages': Insecure CSP value "'sha256-...'" in directive 'script-src'.
Could not load manifest.

As per the Chrome Extension Documentation,
Don't rely on the page having the keyboard focus.
The address bar always gets the focus first when the user creates a new tab.
See reference here: Override Pages

Here's the solution for Manifest v3
chrome.tabs.onCreated.addListener((tab) => {
if (tab.pendingUrl === 'chrome://newtab/') {
chrome.tabs.remove(tab.id)
chrome.tabs.create({
url: '/index.html',
})
}
})
I saw a pretty old blog which updates the new tab conditionally. However, simply updating the tab does not steal the focus. I had to close the pending tab and open a new one.
Cons: An ugly chrome-extension://akfdobdepdedlohhjdalbeadhkbelajj/index.html in the URL bar.

I have a cheap work around that allows stealing focus from address bar focus. It's not for everyone. I do actually do use this because I want to control a new tab focus just that bad in my own custom new tab solution:
<script>
alert('Use enter key to cancel this alert and then I will control your focus');
document.getElementById('...AckerAppleIsCrafty...').focus()
</script>
USE CASE: I built my own HTML chrome custom tab that has a search input that custom searches my history and bookmarks the way I like it too.
Cash me focusing outside how bout dat?

Related

Why wont copying to clipboard work in my extension, even though permissions and HTML code works? [duplicate]

This question already has answers here:
onclick or inline script isn't working in extension
(5 answers)
Closed 3 years ago.
I'm making a chrome extension where the user can press a button and text will get copied to their clipboard. I've written the HTML and Javascript to do this and the code works when I open the HTML file in my browser. The issue is that when I open the extension (running that same HTML file), the button won't copy any text to the clipboard. I do have the permission "clipboardWrite" enabled in my manifest.json file and chrome://extensions also says "Modify data you copy and paste" when I go to details > permissions.
To try to fix the issue, I've reloaded the extension, deleted and re-added the unpacked folder, and restarted my computer; none of which solved my problem. I've also tested it in multiple browsers and it fails to work in all of them.
Here's some code that re-creates the issue I'm getting:
popup.html:
<!DOCTYPE html><html>
<body>
<script>
/*Function that copies text. This works fine in a browser but not in the extension*/
function clip(string) {
const ta = document.createElement('textarea'); //creates a constant of a textarea
ta.value = string; //adds 'string' parameter into the textarea
ta.setAttribute("id", "temptextarea");
document.body.appendChild(ta); //adds an instance of the textarea
ta.select(); //selects the text in the textarea (may be the issue for chrome extension)
document.execCommand('Copy'); //copies the selected text
document.body.removeChild(ta); //removes the instance of the textarea
}
</script>
<!--Button that copies text.-->
<button onclick="clip('This text gets copied')">Copy Text!</button>
</body>
</html>
manifest.json:
{
"manifest_version": 2,
"name": "My Extenstion Name",
"version": "1.0.0",
"permissions": [
"clipboardWrite"
],
"browser_action": {
"default_popup": "popup.html",
"default_title": "My Extension Name"
}
}
When running this code snippet in a browser tab, you'll get the expected result: it will copy "This text gets copied" to your clipboard when you click the button. For whatever reason, when you put those two files into a folder and upload it to chrome://extenstions, the text doesn't get copied to your clipboard. This confuses me because logically, the only reason it wouldn't be able to work in the extension is because of insufficient permissions, but as I stated earlier, it does have permission to write to the clipboard.
Thanks in advance!
The reason this code isn't working is because chrome extensions throw an exception if you use onclick="". You need to use an event listener in this case.

Chrome Extension's browser action with a popup that inject/delete CSS

I would like to ask a way to inject css or delete injected css through browse action pop up window for the chrome extension. I had try to look through few places to get ideal on how to do it but I fail to understand them.
I would like to make extension which similar to "A browser action with a popup that changes the page color" but click on the div in the popup.html to load or unload the css file that created.
This is my current work (https://github.com/Zhekoay/Self-Custom-Dark-Theme) which direct insert css using content script. Now i would like to make it able to load or unload differently instead one-time load all.
Chrome API can't remove CSS injected via manifest.json.
Inject the code just like the demo extension does, but use a file parameter with a name of your content script that will add or remove (if it exists) a link element under document.documentElement with an id equal to chrome.runtime.id and href pointing to a web accessible CSS file.
remove "content_scripts" from manifest.json
add "web_accessible_resources": ["*.css"] to manifest.json
add a click handler for the div in popup.js
in the click handler: chrome.tabs.executeScript({file: 'content.js'});
content.js:
(function() {
var styleElement = document.getElementById(chrome.runtime.id);
if (styleElement) {
styleElement.remove();
return;
}
var css = ({
'www.youtube.com': 'app_yt_HoveredImg.css',
'www.messenger.com': 'fb_messenger_styles.css',
'www.google.com': 'google_styles.css',
'translate.google.com': 'google_styles.css',
'apis.google.com': 'google_styles.css',
})[location.hostname];
if (!css) {
return;
}
styleElement = document.createElement('link');
styleElement.id = chrome.runtime.id;
styleElement.rel = 'stylesheet';
styleElement.href = chrome.runtime.getURL(css);
document.documentElement.appendChild(styleElement);
})();
Note, in this workflow you only need "permissions": ["activeTab"] instead of "tabs": the advantage is that activeTab doesn't ask for permissions when the extension is installed.

are there any chrome extension API to set focus in the web page content? [duplicate]

With Chrome 27, it seems that extensions that override Chrome's New Tab Page can't take focus away from Chrome's Omnibox like they used to in previous versions of Chrome.
Is there a new way to focus an input box in a New Tab Page, or has this functionality been disabled completely? :(
To test this, create an extension folder with three files:
1. manifest.json:
{
"name": "Focus Test",
"version": "0",
"minimum_chrome_version": "27",
"chrome_url_overrides": {
"newtab": "newTab.html"
},
"manifest_version": 2
}
2. focus.js:
document.getElementById('foo').focus();
3. newTab.html:
<html>
<body>
<input id="foo" type="text" />
<script type="text/javascript" src="focus.js"></script>
</body>
</html>
Then, when you load the extension and open a new tab, the input field does not get focused on the new tab page.
I have also tried adding the autofocus attribute to the input field, but no luck either. The extension's new tab page can't take focus away from Chrome's Omnibox.
Any ideas? Is this a bug or a new "feature"?
ManifestV3 update
This answer is adapted from https://stackoverflow.com/a/11348302/1754517.
This has been tested with both Manifest V2 and V3.
Tested in Google Chrome 99.0.4844.51 64-bit (Windows 10).
Replace the content of focus.js with:
if (location.search !== "?x") {
location.search = "?x";
throw new Error; // load everything on the next page;
// stop execution on this page
}
Add the autofocus attribute to the <input>.
Go to the Extensions page in Chrome and click the Load unpacked button. Choose the folder of your extension.
Open your new tab page. You might see a modal dialogue reading Change back to Google?. Click Keep it to keep your custom new tab page.
Inline Javascript - Manifest V2 only
If you're inlining the Javascript in the HTML file, then you'll need to take some extra steps:
After adding your inline Javascript to your HTML file, open DevTools (F12 key) and observe the error output in the Console. Example output you should see:
Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'self' blob: filesystem:".
Either the 'unsafe-inline' keyword, a hash ('sha256-MK0Gypb4mkZTI11eCOtWT+mGYcJNpN5zccvhfeaRb6E='), or a nonce ('nonce-...') is required to enable inline execution.
Select & copy this hash.
Add a line to manifest.json to allow the JS to run, pasting in the hash you just copied between the single-quotes. E.g.:
"content_security_policy": "script-src 'self' 'sha256-MK0Gypb4mkZTI11eCOtWT+mGYcJNpN5zccvhfeaRb6E='"
Go to the Extensions page again. Remove the extension, then re-add it using the Load unpacked button.
Open your new tab page. Your extension should now autofocus on the <input>.
Note inlining only works with Manifest V2; Manifest V3 returns a failure message when attempting to load the extension (even with a properly formed "content_security_policy" object in manifest.json, to replace the Manifest V2 "content_security_policy" string):
Failed to load extension
File C:\path\to\extension
Error 'content_security_policy.extension_pages': Insecure CSP value "'sha256-...'" in directive 'script-src'.
Could not load manifest.
As per the Chrome Extension Documentation,
Don't rely on the page having the keyboard focus.
The address bar always gets the focus first when the user creates a new tab.
See reference here: Override Pages
Here's the solution for Manifest v3
chrome.tabs.onCreated.addListener((tab) => {
if (tab.pendingUrl === 'chrome://newtab/') {
chrome.tabs.remove(tab.id)
chrome.tabs.create({
url: '/index.html',
})
}
})
I saw a pretty old blog which updates the new tab conditionally. However, simply updating the tab does not steal the focus. I had to close the pending tab and open a new one.
Cons: An ugly chrome-extension://akfdobdepdedlohhjdalbeadhkbelajj/index.html in the URL bar.
I have a cheap work around that allows stealing focus from address bar focus. It's not for everyone. I do actually do use this because I want to control a new tab focus just that bad in my own custom new tab solution:
<script>
alert('Use enter key to cancel this alert and then I will control your focus');
document.getElementById('...AckerAppleIsCrafty...').focus()
</script>
USE CASE: I built my own HTML chrome custom tab that has a search input that custom searches my history and bookmarks the way I like it too.
Cash me focusing outside how bout dat?

chrome.devtools.network.getHAR does not work

I am trying create a simple chrome extension to get number of http requests visible in network tab of chrome developer toolbar.
I added manifest.json:
{
"name": "Entries",
"version": "1.0",
"description": "Give me entries",
"devtools_page": "devtools.html",
"manifest_version": 2
}
devtools.html :
<html>
<body>
<script src="devtools.js"></script>
</body>
</html>
devtools.js:
chrome.devtools.network.getHAR(function(result) {
var entries = result.entries;
Console.warn("entries : " + entries.length);
});
But when I add this extension --> open developer toolbar --> load a page
I don't see any result :(
This is a very simple example.. can anyone please help me point if I am missing any inputs here ?
Is there any way I can debug ?
First of all, Console doesn't exist, try console.
However, the bigger issue here may be that you are writing to the wrong console. This should became a bit more understandable when you'll get to the end of this answer.
To debug custom devtools extensions you have to debug devtools with devtools. If this sounds like a madness then follow these simple steps:
open devtools A for any website
detach devtools window (using button in the lower left corner)
open another devtools B (while in the first devtools) using one of available keyboard shortcuts
enjoy debugging devtools A with devtools B
Everything that you output to the console from your extension in the devtools A will appear in the console of the devtools B.
create a new panel with in the devtools.js using 'chrome.devtools.panels.create'
add a listener to to panel onshow event 'panel.onShown.addListener'
with the onshow event call 'chrome.devtools.network.getHAR'

Select2 isn't working fine on a chrome extension popup

I'm experiencing a bad behavior of Select2 on a chrome extension using AngularJS and Angular-UI.
The scenario
Select2's content is loaded asynchronously via AngularJs $resouces module.
What should happen?
The content should be display when i click on the Select2.
What is actually happening?
When i first click on any select2 dropdown, it just winks and then hides.
Obs.:
The same code works just fine out of chrome's extension popup.
You can see it working here: http://moneynow2.apphb.com.
And can browse the code here at my github repository.
Mine working fine in Chrome extension, but I'm getting "Refused to execute inline event handler because it violates the following Content Security Policy directive: "default-src 'self' chrome-extension-resource:". Note that 'script-src' was not explicitly set, so 'default-src' is used as a fallback." In chrome console.
This is really hard to test.
It looks like in a popup, when I open the dropmenu, the route gets reloaded (the whole controller and contents of ng-view reloads). This doesn't occur on the webpage. I thought that the popup was appearing in the bottom-right corner, stretching out the window (it happened as I stepped through it). When this occurred, I thought it might have triggered a window-scroll event which actually causes select2 to disappear (it's a feature of select2 to prevent the dropmenu from staying in some random place since it's pos:fixed).
I also don't know enough about chrome popups to figure out what events may cause the 'url' to change or a scroll event to trigger, etc.
At first I would have suggested doing selectOptions = { data: $myResource.query() } or something, but I'm starting to think it won't help.
Suggestion:
Try removing the router and see what happens. I don't really know that you should bother with it in a chrome extension. In such a small space, less code is probably better anyway.

Resources