Chrome Extension not working after Chrome 73 but only if loaded from the store - google-chrome-extension

I have a Chrome extension (https://chrome.google.com/webstore/detail/apsic-xbench-extension-fo/nhadbgflnognogbicnbeepnbpehlocgc) that suddenly stopped working right after the Chrome 73 update.
The symptom is that if I go to the page where the extension is designed to work (https://translate.google.com/toolkit) and I click on the extension icon, instead of running the background page code, the pop-up menu for the extension appears (as if I had right-clicked the icon).
However, if I load the exact same code locally (not from the store), the Chrome extension runs fine.
The background page console for the extension loaded from the store does not seem to issue any error. If I place a breakpoint for the first line in the onClicked listener for the page action, it does not stop there for the Chrome store extension (and the breakpoint works fine for the extension loaded locally).
Why do I get different behaviors if I load the extension from the Chrome store or I load it locally?
In Chrome 72, the extension worked fine.

Answering own question: I tracked down the issue. It turned out that if the Chrome extension was installed from the Chrome store using Chrome 72, then it did not work right after the update to Chrome 73.
However, if after Chrome 73 is updated, you remove the extension and add it again from the Chrome store, then the Chrome extension works again. Strange but true.

Chrome 73 inject some new security. Just try to move your xHTTP requests to your background script with chrome.runtime.sendMessage and get response with SendResponse callback.
In content or popup script replace ajax with :
chrome.runtime.sendMessage(
{ action: "check", data: {/* params for url */}},
// callback with url response
function(response) {
if( response.success ) {
var myDataFromUrl = response.data;
...
} else {
console.log('Error with `check`,', response.data);
}
}
);
From background script:
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
var url = 'https://mysyte.com/';
if(request.action === 'check' ) {
url = url + 'check'
ajax( url, request.data,
success: function( d ) {
sendResponse({success: true, data: d});
},
error : function( d ) {
sendResponse({success: false, data: d});
}
);
}
});
function ajax( url, params, cbSuccess, cbError ) { ... }

Related

why the active tabs was undefined when send message from backend to content script in google chrome extension v3

I am tried to send message from background in google chrome extension v3, this is the background message send code looks like:
export function sendMessageToContent(message: MessageBase) {
debugger
chrome.tabs.query({active:true,currentWindow:true},function(tabs){
var activeTab = tabs[0];
if(activeTab && activeTab.id !== undefined){
chrome.tabs.sendMessage(activeTab.id, {"message": "clicked_browser_action"});
}
});
}
when I get the current active tab, the tabs was return undefined, why did this happen? I am sure there contains active tabs in google chrome broswer, what should I do to fix this problem? This is the debug view:

"Scroll to Text" not working in Extension

I've built a Chrome Extension (pop-up) and one of the primary functions is opening different web pages when the user clicks on a link. Sometimes I want to focus on specific text on the new page so I'm trying to use the "scroll to text fragment" feature through my extension.
Unfortunately, when the page loads, this feature (scroll to text) fails. I have tested the exact same link manually and it works fine, but when I inject this link into the browser through my extension, nothing happens except the page loading as normal.
Here are a few more details that might help:
The problem I'm having is using Chrome.tabs.update() which is triggered by a user clicking a link in my popup
We are using manifest v2 not v3
The exact command from the popup javascript is (not tab id as it defaults to current tab):
chrome.tabs.update({ url: "http://example.com/#:~:text=example", })
In the manifest, we do not have the "tabs" permission.
Is there a special permission needed to use this feature in my extension? Is there something I need to do in my extension code to make this work as expected? I'm at a loss for next steps.
This is the exact feature I'm referring to: https://chromestatus.com/feature/4733392803332096
And here's an example of the feature in action:
https://chromestatus.com/feature/4733392803332096#:~:text=Motivation-,Navigating%20to%20a%20URL,-today%20will%20load
Any help would be greatly appreciated. Thank you.
There's no special permission so apparently it's a bug in Chrome: crbug.com/1241508
A simple workaround is to use chrome.tabs.create and close the original tab, but it flickers in the tab strip and loses the tab's back/forward history, sessionStorage, and so on.
function navigate(url) {
chrome.tabs.query({active: true, currentWindow: true}, ([tab]) => {
chrome.tabs.remove(tab.id);
chrome.tabs.create({ url, index: tab.index });
});
}
Another workaround is to set the hash part of the URL in the content script, but it requires host permissions for the navigated site in manifest.json like *://example.com/
async function navigate(url) {
if (await setUrlInContentScript(url)) {
return true;
}
const [base, hash] = url.split('#');
await onTabReceivedUrl(await new Promise(resolve => {
chrome.tabs.update({ url: base }, resolve);
}));
return setUrlInContentScript('#' + hash, 'hash');
function setUrlInContentScript(url, part = 'href') {
return new Promise(resolve => {
chrome.tabs.executeScript({
code: `location.${part}=${JSON.stringify(url)}`,
runAt: 'document_start',
}, () => resolve(!chrome.runtime.lastError));
});
}
function onTabReceivedUrl(tab) {
return new Promise(resolve => {
chrome.tabs.onUpdated.addListener(function onUpdated(tabId, info) {
if (tabId === tab.id && info.url) {
chrome.tabs.onUpdated.removeListener(onUpdated);
resolve();
}
});
});
}
}
In my case I discovered, that one of the characters ~ was encoded. You need the real characters to get Scroll to Text working.

How to inject a react app based chrome extension inside a webpage?

I'm developing a react app based chrome extension which uses Google's material design and has a couple of pages with navigation.
I want to inject the extension inside the browser tab when the extension is launched from the browser address toolbar. I've seen multiple extensions do so by injecting a div(inside the body of webpage) containing an iframe with src equal to the extension's pop-up HTML page.
I execute the following function when the extension is launched. Which basically injects the extension into the target webpage body but it appears multiple times inside the target web page.
function main() {
const extensionOrigin = "chrome-extension://" + chrome.runtime.id;
if (!location.ancestorOrigins.contains(extensionOrigin)) {
// Fetch the local React index.html page
fetch(chrome.runtime.getURL("index.html") /*, options */)
.then((response) => response.text())
.then((html) => {
const styleStashHTML = html.replace(
/\/static\//g,
`${extensionOrigin}/static/`
);
const body = document.getElementsByTagName("body")[0];
$(styleStashHTML).appendTo(body);
})
.catch((error) => {
console.warn(error);
});
}
}
See Image of Incorrect Injection
Any help or guidance would be very appreciated. Thanks!

unable to executeScript in chrome

I am learning to make a chrome extension and deveoped one with a popup browser action and have the following js file (called in popup.html via )
chrome.tabs.executeScript({
code:
"var frameworks = [];" +
"if(!!window.Vue) frameworks.push('Vue.js');" +
"if(!!window.jQuery) frameworks.push('jQuery.js');" +
"frameworks;"
}, (frameworks) => {
document.body.innerHTML = frameworks[0].length
})
But when I am testing it on my website made using both vue and jquery it returns 0, I also checked it on other websites but all behaved same.
What am I doing wrong here?

Chrome extension detect Google search refresh

How can my content script detect a refresh of Google's search?
I believe it is an AJAX reload of the page and not a "real" refresh, so my events won't detect the refresh.
Is it possible to detect it somehow in both a Google Chrome extension and a Firefox WebExtensions add-on?
Google search is a dynamically updated page. Several well-known methods exist to detect an update: MutationObserver, timer-based approach (see waitForKeyElements wrapper), and an event used by the site like pjax:end on GitHub.
Luckily, Google Search in Chrome browser uses message event, so here's our content script:
window.addEventListener('message', function onMessage(e) {
// console.log(e);
if (typeof e.data === 'object' && e.data.type === 'sr') {
onSearchUpdated();
}
});
function onSearchUpdated() {
document.getElementById('resultStats').style.backgroundColor = 'yellow';
}
This method relies on an undocumented site feature which doesn't work in Firefox, for example.
A more reliable crossbrowser method available to Chrome extensions and WebExtensions is to monitor page url changes because Google Search results page always updates its URL hash part. We'll need a background/event page, chrome.tabs.onUpdated listener, and messaging:
background.js
var rxGoogleSearch = /^https?:\/\/(www\.)?google\.(com|\w\w(\.\w\w)?)\/.*?[?#&]q=/;
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
if (rxGoogleSearch.test(changeInfo.url)) {
chrome.tabs.sendMessage(tabId, 'url-update');
}
});
content.js
chrome.runtime.onMessage.addListener(function(msg, sender, sendResponse) {
if (msg === 'url-update') {
onSearchUpdated();
}
});
function onSearchUpdated() {
document.getElementById('resultStats').style.backgroundColor = 'yellow';
}
manifest.json: background/event page and content script declarations, "tabs" permission.

Resources