Re: [crx] Digest for chromium-extensions@chromium.org - 17 updates in 7 topics

105 views
Skip to first unread message

Christian, Joseph

unread,
Sep 16, 2022, 3:10:11ā€ÆPM9/16/22
to chromium-...@chromium.org
funĀ kjmolkokšŸ’Žā¤ć€½ā¤šŸ’‹šŸ’šŸ›ŒšŸ…šŸ”®šŸ—”

On Thu, Sep 15, 2022 at 9:03 AM <chromium-...@chromium.org> wrote:
Robbi <rob...@gmail.com>: Sep 14 05:48PM -0700

I noticed another thing that worried me not a little.
I will try to be brief and if necessary I will provide the details later.
Ā 
*Scenario*:
Ā 
1. I create a notification with 2 buttons from inside the sw.
2. I press the 1st button. It begin a process which reads an indexedDB
of about 50 Mbytes serializes it into a JSON file, compresses it (gzip) and
finally downloads it. This process takes about 20 seconds.
Ā 
Ā 
*Doing some test, I noticed that, once the notification was created...*
Ā 
- . ...If I wait for the sw to go to sleep and then click on the button,
I see the sw wake up, doing its duty until the end (the file is downloaded).
Ā 
Ā 
- ...With the sw still active, if I wait for a certain amount of time
(however not enough to send the sw to sleep, i.e 10 seconds) and then I
click on the button* the procedure does not end because the sw in the
meantime becomes inactive.*
Ā 
Ā 
*My question is:*
*Shouldn't pressing the button restart the s.w countdown?*
I mean, if the user doesn't see the notification because he has not been in
front of the PC for some time and when he returns he presses the button
everything is fine (because the sw start from inactivity), but if he gets
distracted for a few seconds and then presses the button, everything falls
apart.
*Is this a normal behavior?*
Ā 
Thank you in advance
wOxxOm <wox...@gmail.com>: Sep 15 01:30AM -0700

> *Shouldn't pressing the button restart the s.w countdown?*
Ā 
Assuming it's chrome.notifications.onClicked, it certainly should, just
like any other chrome event that wakes the worker, so apparently it's a bug.
Ā 
Anyway, the only reliable workaround would be to open a new window that
reads IndexedDB and downloads the file because on a slower computer
gzipping of a large database may take more than the nonsensically
inflexible timeout of 30 seconds enforced on ManifestV3 extensions.
Ā 
That said, if you use a js library for gzipping, try the new
CompressionStream instead. Also, since IndexedDB can store Blob or
ArrayBuffer directly, maybe you can reorganize the storage accordingly to
avoid JSON serialization completely.
Ā 
zip('foo').then(blob => download(blob, 'foo.txt.gz', 'application/gzip'))
Ā 
/** @returns {Promise<Blob>} */
function zip(str) {
return new Response(new Response(str).body.pipeThrough(new
CompressionStream('gzip'))).blob();
}
/** @returns {Promise<String>} */
function unzip(blob) {
return new Response(blob.stream().pipeThrough(new
DecompressionStream('gzip'))).text();
}
Ā 
Ā 
On Thursday, September 15, 2022 at 3:48:34 AM UTC+3 Robbi wrote:
Ā 
Robbi <rob...@gmail.com>: Sep 15 04:24AM -0700

Hi @wOxxOm, thank you for your reply.
I am using the browser's native compression method for the first time and
so I don't know if I got things right. Part of the code I got from a post
of yours on SO.
I believe that I already follow most of your advice. The only thing is that
in my DB there are no blobs or arrayBuffers but json objects.
Ā 
Now I'm going to create a small extension to try to understand if and how
the countdown starts again after pressing the button.
Creating a function that resolves a promise after 10-20 seconds should be
enough to do this test.
If the countdown does not restart then it is clear that there is a bug
somewhere.
Ā 
This is the code from reading the db to dowload the archive file:
Do you see something strange?
Ā 
*//sw script*
opt = {
type: "basic",
title: "Do you want to backup your data?",
message: "bla bla bla...",
iconUrl: 'img/warning.png',
buttons: [{
title: "Proceed"
}, {
title: "Not now"
}
],
requireInteraction: true
}
chrome.notifications.create('BS', opt);
Ā 
chrome.notifications.onButtonClicked.addListener((id, btnIdx) => {
if (id == 'BS') {
if (btnIdx == 0) {
chrome.notifications.clear(id, _ => {
exportBusy = true;
var req = indexedDB.open('foobar'); //opening the db
req.addEventListener('success', e => {
db = e.target.result;
var objExport = { /* This is the skeleton of the
object I'm going to backup */
'name': db.name,
'version': db.version,
'objectStores': [{
name: 'mainNetworkData ',
data: [] /* it will be populated later */
}, {
name: 'otherStuff',
data: [] /* it will be populated later */
}
]
};
var arrProm = [];
var arrOs = objExport.objectStores;
for (let i = 0; i < arrOs.length; i++)
arrProm[i] = queryKey(db, arrOs[i].name, null,
null); //pulling out the objectStores from db (asynchronously)

Promise.all(arrProm).then(results => {
results.forEach((r, i) => {
arrOs[i].data = r.slice() //populating the
big object...
});

chrome.windows.create({url: 'downloader.html',
state: 'minimized'});

self.addEventListener('message', function onMsg(e) {
if (e.data === 'sendBlob') {
async function send(dst) {
//all heavy stuff is done after the
window is created (not too stylish!)
var content = JSON.stringify(objExport);
const stream = new
Response(content).body.pipeThrough(new CompressionStream('gzip'));
blob = await new
Response(stream).blob();
dst.postMessage({blob}, [await
blob.arrayBuffer()])
};
self.removeEventListener('message', onMsg);
send(e.source)
} else if (e.data === 'done')
exportBusy = false
})
}).catch(err => {})
})
})
} else
chrome.notifications.clear(id)
}
});
Ā 
*//downloader.html*
<html>
<head> <script src="./script/downloader.js"></script> </head>
<body>Don't close this window.<br> It will close automatically when the
download is complete. </body>
</html>
Ā 
*//downloader.js*
navigator.serviceWorker.ready.then(swr =>
swr.active.postMessage('sendBlob'));
navigator.serviceWorker.onmessage = async e => {
if (e.data.blob) {
let url = URL.createObjectURL(e.data.blob);
let downloadAnchorNode = document.createElement("a");
downloadAnchorNode.download = "foobar.gz";
downloadAnchorNode.href = url;
downloadAnchorNode.addEventListener("click", _ => setTimeout(_ => {
URL.revokeObjectURL(url);
e.source.postMessage('done');
window.close()
}, 500));
downloadAnchorNode.click();
downloadAnchorNode.remove()
}
}
Ā 
Il giorno giovedƬ 15 settembre 2022 alle 10:30:06 UTC+2 wOxxOm ha scritto:
Ā 
wOxxOm <wox...@gmail.com>: Sep 15 04:41AM -0700

Well, the code is fine but since you're opening a new window anyway, you
should just move it all inside downloader.js. This way, the service
worker's listener will only call chrome.windows.create.
Ā 
On Thursday, September 15, 2022 at 2:24:16 PM UTC+3 Robbi wrote:
Ā 
Robbi <rob...@gmail.com>: Sep 15 05:04AM -0700

Yes you are right. Without asking too many questions, the *sure *solution
would be just this.
Ā 
Il giorno giovedƬ 15 settembre 2022 alle 13:41:35 UTC+2 wOxxOm ha scritto:
Ā 
Robbi <rob...@gmail.com>: Sep 15 05:53AM -0700

A simple extension like this below confirms my hypothesis.
The button wakes up the sw but if the latter is already awake it does not
restart the countdown.
Ā 
*//manifest.json*
{
"manifest_version": 3,
"name": "foobar",
"description": "foo bar",
"version": "0.1",
"background": { "service_worker": "sw.js" },
"permissions": [ "notifications" ]
}
Ā 
*//sw.js*
chrome.notifications.onButtonClicked.addListener((id, btnIdx) => {
function wait(sec) {
return new Promise(ok => setTimeout(ok, 1e3 * sec))
}
chrome.notifications.clear(id);
if (btnIdx == 0) {
* wait(20)*
.then(_ => {
chrome.notifications.create('DONE', {
type: "basic",
title: "Done!",
message: "Done!",
iconUrl: './warning.png',
requireInteraction: true
})
})
}
});
chrome.runtime.onInstalled.addListener(details => {
chrome.notifications.create('BCK', {
type: "basic",
title: "Do you want to backup your data?",
message: "The operation takes *20 *seconds",
iconUrl: './warning.png',
buttons: [
{ title: "YES" },
{ title: "NO" }
],
requireInteraction: true
})
})
Il giorno giovedƬ 15 settembre 2022 alle 14:04:19 UTC+2 Robbi ha scritto:
Ā 
wOxxOm <wox...@gmail.com>: Sep 15 06:40AM -0700

Looks like this is matching the standard web platform behavior. Reusing it
for extensions is completely nonsensical, though, precisely for the reason
that it breaks any complex operation such as zipping or processing video
etc. Yet another evidence out of dozens or hundreds why service worker idea
was a mistake. It's also a regression compared to behavior of a ManifestV2
event page. Will you open a bug report on https://crbug.com?
Ā 
Here's an MV2 demo that shows that the kill timer (15 seconds) is prolonged
as expected:
Ā 
Ā 
- *manifest.json*

{
"name": "test MV2",
"version": "1.0",
"manifest_version": 2,
"background": {
"scripts": ["bg.js"],
"persistent": false
},
"permissions": [
"notifications"
]
}

-
*bg.js *
chrome.notifications.onButtonClicked.addListener(console.log);
chrome.notifications.getAll(n => {
if (!n.BCK) {
chrome.notifications.create('BCK', {
title: 'The background script should run while',
message: 'you click a button below every 5 seconds',
type: 'basic',
iconUrl:
'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==',
buttons: [{title: 'YES'}, {title: 'NO'}],
requireInteraction: true,
});
}
});

Ā 
On Thursday, September 15, 2022 at 3:53:12 PM UTC+3 Robbi wrote:
Ā 
Robbi <rob...@gmail.com>: Sep 15 07:01AM -0700

Yes, I was thinking of opening one. I have already opened 3 reports for
different things and two of them have yet to go through the triage phase.
I sadly found that if the bug is not starred by many people after about a
year it is closed because anybody don't give a f**k . Bad thoughts?
Anyway, as soon as I have reported the bug I place a link here so that you
can add information or impressions (if needed).
Ā 
Il giorno giovedƬ 15 settembre 2022 alle 15:40:21 UTC+2 wOxxOm ha scritto:
Ā 
Dmytro Chumak <di...@getselectstar.com>: Sep 15 04:24AM -0700

Atm we luckily built our chrome extension including our bundles directly in
the extension. However, we use a lot of components from the main app, which
obviously have a ton of business logic that is tightly connected with the
API.
Ā 
Any update on this means that we have to release both - chrome extension
and API. In the case of chrome extension - that is not easy, because the
review could take 3 days, which means some features are down until the
update won't happen. I know you told us that external script is the best
solution and this also could be a reason. However, we canā€™t use external
scripts in manifest v3. Here the statement:
Ā 
*In Manifest V3, all of your extensionā€™s logic must be included in the
extension. You can no longer load and execute a remotely hosted file. A
number of alternative approaches are available, depending on your use case
and the reason for remote hosting. Here are approaches to consider:*
...
*Consider migrating application logic from the extension to a remote web
service that your extension can call. (Essentially a form of message
passing.) This provides you the ability to keep code private and change the
code on demand while avoiding the extra overhead of resubmitting to the
Chrome Web Store.*
Ā 
I am not really sure what they mean by this.
Ā 
I am also not sure if something like below would be a better approach in
that case (bundle everything in one file file and just make fetch request
like this (kind of an external script loading trick)):
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
$.get("http://127.0.0.1:8000/bundle.js
<http://127.0.0.1:8000/static/plugin/somesite.js>", function(result) {
chrome.tabs.executeScript(tabs[0].id, {code: result}); }, "text"); });
Ā 
Would be great to hear your thoughts on this!
Ā 
Source:
https://developer.chrome.com/docs/extensions/mv3/intro/mv3-migration/#remotely-hosted-code
Uday prasad <udaypr...@gmail.com>: Sep 15 02:19AM -0700

I am trying to create chrome extension v3 with existing reactjs and
typescript project.
Ā 
*manifest.json :*
Ā 
{
"name": "Sample project",
"description": "Sample Chrome extension",
"version": "1.0",
"manifest_version": 3,
"action": {
"default_popup": "index.html",
"default_title": "Open the popup"
}
}
Ā 
*'public/index.html':*
Ā 
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/logo.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta name="description" content="sample app" />
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo.svg" />
<link
href="https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap"
rel="stylesheet"
/>
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<title>%REACT_APP_TITLE%</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
</body>
</html>
Ā 
When I click the extension in developer mode the following errors are
generated:
Ā 
Ā 
- Refused to load the script
'https://www.googletagmanager.com/gtag/js?l=dataLayer&id=G-KJFKE93ST6'
because it violates the following Content Security Policy directive:
"script-src 'self'". Note that 'script-src-elem' was not explicitly set, so
'script-src' is used as a fallback.
- Refused to load the script
'https://www.googletagmanager.com/gtag/js?l=dataLayer&id=G-KJFKE93ST6'
because it violates the following Content Security Policy directive:
"script-src 'self' 'wasm-unsafe-eval'". Note that 'script-src-elem' was not
explicitly set, so 'script-src' is used as a fallback.
- Uncaught NotFoundError: URL not found: /index.html

Project consists of google analytics.
Ā 
What might be the cause and necessary changes need to be done?
PhistucK <phis...@gmail.com>: Sep 15 12:21PM +0100

Starting with the last error, you put your index.html in the public folder,
but your manifest says it is on the root folder, so prepend public/ to the
default_popup value.
Ā 
Regarding the other errors, nothing in the code you shared points to
loading anything external (or even an internal script, which is weird
considering the content of the file), so I guess something in your
TypeScript code is trying to load Google Tag Manager and you omitted the
(internal) script from the HTML you shared here.
Note that you cannot load anything external (like Google Tag Manager from
that URL) in your normal extension pages/popups.
If you need to load Google Tag Manager, you will have to use a
sandbox/webview/similar (not so familiar with the options, sorry).
Ā 
ā˜†*PhistucK*
Ā 
Ā 
On Thu, Sep 15, 2022 at 10:20 AM Uday prasad <udaypr...@gmail.com>
wrote:
Ā 
Yuan Ho <tian...@gmail.com>: Sep 15 03:25AM -0700

It's hard to debug when the extension is loaded from unpacked. Is there a
chrome launch flag which can make chrome treat extensions loaded unpacked
as force installed extension? Thanks.
Ā 
On Thursday, 14 July 2022 at 06:33:56 UTC+8 Simeon Vincent wrote:
Ā 
Yuan Ho <tian...@gmail.com>: Sep 15 03:21AM -0700

I am having exactly the same problem. Is there a chrome launch flag which
can make chrome treat extensions loaded unpacked as force installed
extension?
On Thursday, 23 June 2022 at 18:18:15 UTC+8 Br Dev wrote:
Ā 
Robbi <rob...@gmail.com>: Sep 14 04:57PM -0700

thanks, for now I have only contacted the CWS One Stop support.
As soon as I get a reply I will inform the group
Ā 
Il giorno mercoledƬ 14 settembre 2022 alle 11:37:23 UTC+2 Jackie Han ha
scritto:
Ā 
botanrice <14bena...@gmail.com>: Sep 14 11:36AM -0700

Hello!
Ā 
I am attempting to solve the same exact problem - I want to click a button
in popup.js, retrieve data from background.js accessing an IndexedDB
database, then display that data in my popup.html. I can't seem to get this
work but have followed the suggestions here just about exactly. I am
failing to be able to *return messages* once I have successfully received
them. Below is a snippet of my code:
Ā 
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
if (message.name === "dbinfo") {
console.log("Received 'dbinfo'");
sendResponse({data: "okay! gotcha!"});
return true;
}
}
);
Ā 
The only response I receive is "Received 'dbinfo'" in my DevTools console.
Ā 
Thank you in advance :)
On Saturday, March 12, 2022 at 5:16:25 AM UTC-5 Stefan vd wrote:
Ā 
Stefan vd <stefa...@gmail.com>: Sep 14 11:39AM -0700

Hi botanrice,
Ā 
Add the return outside the *if *code part.
Ā 
Thanks,
Stefan vd
On Wednesday, September 14, 2022 at 8:36:05 PM UTC+2 botanrice wrote:
Ā 
wOxxOm <wox...@gmail.com>: Sep 14 11:50AM -0700

botanrice, there's absolutely no need for `return true` in your code
because you send the response immediately. There's also no need for the
background script and messaging because you can access IndexedDB right in
the popup script, which works faster due to direct access.
Ā 
On Wednesday, September 14, 2022 at 9:39:23 PM UTC+3 Stefan vd wrote:
Ā 
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page.
To unsubscribe from this group and stop receiving emails from it send an email to chromium-extens...@chromium.org.
Reply all
Reply to author
Forward
0 new messages