Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#7622: MV3: Add support for SVG theme icons #7925

Closed
wants to merge 8 commits into from
Closed

Conversation

fregante
Copy link
Contributor

@fregante fregante commented Mar 14, 2024

Ready for review, but not complete.

What does this PR do?

Checklist

  • Remove hardcoded demo image
  • Deploy our own proxy
  • Update tests
  • Designate a primary reviewer: @grahamlangford

Copy link

codecov bot commented Mar 15, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 72.91%. Comparing base (602a7de) to head (80c1062).

❗ Current head 80c1062 differs from pull request most recent head 5ffd4d9. Consider uploading reports for the commit 5ffd4d9 to get more accurate results

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #7925   +/-   ##
=======================================
  Coverage   72.91%   72.91%           
=======================================
  Files        1291     1291           
  Lines       40206    40206           
  Branches     7482     7482           
=======================================
  Hits        29315    29315           
  Misses      10891    10891           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@fregante
Copy link
Contributor Author

Current status:

  • all online solutions expect this issue to be solved via postMessage, which is not available for MV3 offscreen documents
  • runtime.sendMessage does not appear to support "transferable" objects, so I can't pass around Blob, ImageData, ImageBitmap
  • those types aren't exactly "serializable"
  • probably the only way I can do this is to:
    1. pass the url to the offscreen document
    2. return a raw array of pixels in the offscreen document (via getImageData().data)
    3. use OffscreenCanvas again to paint it in the background worker
    4. use getImageData() to get the proper ImageData object again

@fregante
Copy link
Contributor Author

Can we just setup a proxy? This appears to have too many small issues to be maintainable. If we spun up a small server/lambda/vercel we could pass an SVG URL and receive a PNG, preserving most of the existing code here

+ if (url.endsWith('svg')) {
+  url = `https://svg-to-png.pixiebrix.com/?width=32&height=32&url=${url}`
+ }
const { data } = await axios.get<Blob>(url, { responseType: "blob" });
return await blobToImageData(data);

The proxy itself can use any off-the-shelves SVG-to-PNG converter. Example:

We'll need it until it's natively supported:

@fregante
Copy link
Contributor Author

fregante commented Mar 15, 2024

Most of the code improvements were extracted to a non-MV3-specific PR that is ready to be reviewed and merged #7935

@@ -25,6 +25,8 @@ export default async function setToolbarIconFromTheme({
toolbarIcon,
themeName,
}: Pick<ThemeAssets, "logo" | "toolbarIcon" | "themeName">) {
toolbarIcon =
"https://upload.wikimedia.org/wikipedia/commons/f/fd/Ghostscript_Tiger.svg";
if (toolbarIcon) {
Copy link
Contributor Author

@fregante fregante Mar 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hardcoded demo image. This image is SVG and lacks a height/width attribute, which further complicates things without a proxy.

await image.decode();
// `createImageBitmap` will fail on SVGs that lack width/height attributes, so we must use <img>
return image;
return blobToImageData(blob, width, height);
Copy link
Contributor Author

@fregante fregante Mar 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Boom. This is all that's needed to fully support SVGs both in MV2 and MV3.

Compare it to the chrome.offscreen-based version (which still had edge cases): https://github.com/pixiebrix/pixiebrix-extension/pull/7925/files/12865f341294d30f965c0cd9ae342ba8fc0e9d97..1a024cf3ce400684bf73ddd0e60be282083cff0b

}

function getSvgProxyUrl(url: string): string {
return `https://svg-to-png.mrproper.dev/${url}`;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rust-based demo proxy working on CloudFlare Workers. We need to deploy our own before merging this PR

https://github.com/GewoonJaap/svg-to-png-cf-worker

@grahamlangford
Copy link
Collaborator

Can we just setup a proxy? This appears to have too many small issues to be maintainable. If we spun up a small server/lambda/vercel we could pass an SVG URL and receive a PNG, preserving most of the existing code here

+ if (url.endsWith('svg')) {
+  url = `https://svg-to-png.pixiebrix.com/?width=32&height=32&url=${url}`
+ }
const { data } = await axios.get<Blob>(url, { responseType: "blob" });
return await blobToImageData(data);

The proxy itself can use any off-the-shelves SVG-to-PNG converter. Example:

We'll need it until it's natively supported:

It's unfortunate Heroku doesn't support serverless functions. Let me discuss with @johnnymetz what the best approach would be for us. I don't see why we couldn't.

Alternatively, we might just setup an endpoint on App.

@fregante
Copy link
Contributor Author

We also have an account on Vercel already so we could set that up. CloudFlare might be even safer (more generous free plan, as well as a repo ready to be deployed)

@grahamlangford
Copy link
Collaborator

grahamlangford commented Mar 19, 2024

@johnnymetz will create a separate Extension issue to look into this. We're going to pursue the cf worker solution initially.

@johnnymetz
Copy link
Collaborator

Here's the issue: #7982

@twschiller twschiller added this to the 1.8.12 milestone Mar 21, 2024
@twschiller
Copy link
Contributor

Closing out this PR because we're going to be creating/hosting the PNG based icon: https://www.notion.so/pixiebrix/Support-custom-branding-MV3-browser-action-icon-f43f5cf790ed4776b15e23638f5ce580?pvs=4

@twschiller twschiller closed this Mar 25, 2024
@fregante
Copy link
Contributor Author

If we don't support SVG here, we still need to apply most changes in this PR

@fregante fregante deleted the F/mv3/action-icon branch March 27, 2024 08:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

MV3 support for custom browser action icon
4 participants