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

Extension Icons for Light/Dark/Custom Theme #229

Open
hanguokai opened this issue Jun 13, 2022 · 35 comments
Open

Extension Icons for Light/Dark/Custom Theme #229

hanguokai opened this issue Jun 13, 2022 · 35 comments
Labels
enhancement Enhancement or change to an existing feature implemented: safari Implemented in Safari supportive: chrome Supportive from Chrome supportive: firefox Supportive from Firefox

Comments

@hanguokai
Copy link
Member

hanguokai commented Jun 13, 2022

A little related to issue-216. Besides the text color and background color of the BadgeText, the extension icon itself is also a problem to adapt to various themes (Light/Dark/Custom).

Current state, developers can set static extension icon or dynamic change it by setIcon(). But:

  • Developers can't set different icons for different themes (at least in static way). So the icon is good for one theme, but may be illegible for another theme.
  • Single icon with transparent background is difficult to adapt to different color themes, unless you fill the background with a solid color.
  • To setIcon() dynamically, developers may need to know current background color of the browser toolbar to choose a color with sufficient contrast to draw the icon. Note: background color of browser toolbar may differ from the system theme, see this discussion.
@yankovichv
Copy link

I fully support it. However, it seems to me that it should be implemented as a browser-based JS API available for websites as well. The point is that all the problems from the list above are relevant for Favicons.

@hanguokai
Copy link
Member Author

website favicon vs extension icon

I think website favicon and extension icon are not exactly the same problem.

Here is a stackoverflow question for website favicon. There are several solution for it. For example, svg favicon with media query, <link> element with media attribute. At least, there is a no-JS solution for light/dart theme.

But these solutions do not apply to extensions. Extension icons are declared in manifest.json. And there is no window.matchMedia('xxx').addEventListener in extension service worker. There are also custom theme(extension theme) that can change toolbar color.

@dotproto
Copy link
Member

Chromium is tracking a similar feature request in issue 893175. A Chromium engineer shared a link to a design doc we were considering in comment 19, but that effort is currently on hold.

@xeenon, @zombie, and @mukul-p, it might be worth taking a look at this and sharing feedback either on the doc or on a related issue.

@hanguokai
Copy link
Member Author

I see the design doc. It is a static(declarative) way in manifest file. I think it solves 90% of the problems.

I think a runtime API should also be provided to solve dynamic problems, because developers can change icon by setIcon() method. For example adding two new apis below:

chrome.runtime.getTheme(); // return 'light' or 'dart' or background color
chrome.runtime.onThemeChanged.addListener(theme => changeIt()); // listener for theme changed

@carlosjeurissen
Copy link
Contributor

carlosjeurissen commented Jun 23, 2022

We can draw some inspiration from ongoing discussion on how to handle this in PWA manifests, see:
w3c/manifest#758
w3c/manifest#975
w3c/image-resource#26

In general, going for a list of icons versus an object, like Mozilla did with theme_icons and PWA do with icons will give us more flexibility.

We can go for a syntax like this:

  "icons": [{
    "src": "/pwa-36.png",
    "sizes": "36x36",
    "media": "(prefers-color-scheme: dark)"
  }, {
    "src": "/pwa-adaptive-48.png",
    "sizes": "48x48",
    "purpose": "toolbar"
  }]

Or adding a color_scheme property. Which can be set to "light", "dark", and potentially "monospace" as many extension developers prefer to blend into the browsers design. This has the added benefit it's clear the browser will choose a dark-mode icon when the background of the browser team is a darker color even tho the OS is not using "dark mode".

@mixedpuppy
Copy link

Firefox implementation can be seen at e.g. https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/action

@carlosjeurissen
Copy link
Contributor

carlosjeurissen commented Jul 7, 2022

For best backwards compatibility, we can consider implementing the theme_icons property for action/page_action/browser_action as is currently implemented by Firefox:

"action": {
  "browser_style": true,
  "default_icon": {
    "16": "button/geo-16.png",
    "32": "button/geo-32.png"
  },
  "default_title": "Whereami?",
  "default_popup": "popup/geo.html",
  "theme_icons": [{
    "light": "icons/geo-16-light.png",
    "dark": "icons/geo-16.png",
    "size": 16
  }, {
    "light": "icons/geo-32-light.png",
    "dark": "icons/geo-32.png",
    "size": 32
  }]
}

default_icon would continue to work fine. While theme_icons would take priority over default_icon if present. light would be used when light text and icons are needed. For example, with a darker background or with dark mode theme. While dark would be used for light mode themes.

We can then move forward with more breaking changes in regard to icons for Manifest v4.

@hanguokai
Copy link
Member Author

light would be used when light text and icons are needed. For example, with a darker background or with dark mode theme. While dark would be used for light mode themes.

I didn't know Firefox's theme_icons before. For me, it's counterintuitive. I prefer dark for icons used in dark theme and light for icons used in light theme.

@carlosjeurissen
Copy link
Contributor

carlosjeurissen commented Aug 4, 2022

@hanguokai This would then be something we can fix once drafting MV4.

As for the API to update theme_icons, we can go for:

browser.action.setThemeIcons([{
    "light": "icons/geo-16-light.png",
    "dark": "icons/geo-16.png",
    "size": 16
  }, {
    "light": "icons/geo-32-light.png",
    "dark": "icons/geo-32.png",
    "size": 32
  }])

Calling this method would overwrite the theme_icons (if present) defined in the manifest file. If set to an empty array or null or undefined, resets the themeIcons to what has been defined in the manifest file or otherwise fallback to what is defined in 'default_icon'.

Currently in Firefox, setIcon will overwrite what is defined in theme_icons. Thus at least for MV2 and MV3 we seem to have to stick to this. This means setIcon would also overwrite setThemeIcons. This is not an issue considering developers can check the presence of setThemeIcons and use that instead of setIcon if present. Naturally setThemeIcons would overwrite the icon set by setIcon.

@xeenon
Copy link
Collaborator

xeenon commented Aug 4, 2022

The theme_icons key and browser.action.setThemeIcons sounds good to me for Safari.

@Rob--W
Copy link
Member

Rob--W commented Jan 25, 2023

Discussion on this issue has been narrowed to the action API, but the need for having a dark variant is broader than that. E.g. extension icons in chrome://extensions (Chrome) or about:addons (Firefox) are not toolbar buttons, but there is still a need to have dark theme support.

@Loirooriol
Copy link

For reference, 5 years ago I proposed browser.browserAction.setThemeIcons in https://bugzilla.mozilla.org/show_bug.cgi?id=1484840

@willdurand
Copy link

Chromium is tracking a similar feature request in issue 893175. A Chromium engineer shared a link to a design doc we were considering in comment 19, but that effort is currently on hold.

@xeenon, @zombie, and @mukul-p, it might be worth taking a look at this and sharing feedback either on the doc or on a related issue.

We (Mozilla) are going to add support for icons.dark and icons.light as well as action.default_icon.dark and action.default_icon.light in the manifest file (all versions probably). Here, dark and light refer to the current theme color scheme and not the text color like theme_icons like mentioned in some docs/links above.

As for theme_icons, we'll likely deprecate the manifest key in MV3+.

@sunxivincent
Copy link

any updates on chrome extension support for dark mode icon?

@Rob--W Rob--W added follow-up: chrome Needs a response from a Chrome representative supportive: firefox Supportive from Firefox labels Feb 16, 2023
@oliverdunk oliverdunk added supportive: chrome Supportive from Chrome and removed follow-up: chrome Needs a response from a Chrome representative labels May 11, 2023
@JamesCoyle
Copy link

@carlosjeurissen extending setIcon to allow for the icon variants would work for me. I can't currently think of a use-case that wouldn't work with that.

@phaux
Copy link

phaux commented May 12, 2024

It would be nice if SVG icons simply supported fill="currentColor" or something similar.

Edit: this currently works thanks to fill="context-fill" special property, but it only works in official Mozilla extensions, because it's non-standard. The current Mozilla plan is to implement and use CSS linked parameters spec for that.

Edit2: w3c/csswg-drafts#9872

@xeenon
Copy link
Collaborator

xeenon commented May 20, 2024

@phaux I agree, that should work in Safari.

@carlosjeurissen
Copy link
Contributor

@phaux how about using an env variable for this to provide authors a way to have a fallback in case the browser does not support this feature?

@DanielHerr
Copy link

For my use case, I am dynamically creating the browser icon at runtime. In order to accommodate dark and light modes, I draw different styles to a canvas and then set the icon to the canvas contents. An API design which takes as input both images would be better than needing to detect the theme in a offscreen document, but would still require wasted work painting the unused theme's respective canvas.

Preferably media queries would be exposed to service workers, but something like browser.runtime.theme == "light" || "dark" would also be nice.

Also, notifications are another surface to consider.

@oliverdunk
Copy link
Member

An API design which takes as input both images would be better than needing to detect the theme in a offscreen document, but would still require wasted work painting the unused theme's respective canvas.

The tradeoff here is that it means the icons wouldn't be available when the theme first changes, and we couldn't update them at the same time as everything else. I don't think exposing media queries to service workers is off the table but I think we'd be hesitant to encourage doing reactive work based on theme changes, at least in the most common cases :)

Also, notifications are another surface to consider.

For sure!

@carlosjeurissen
Copy link
Contributor

carlosjeurissen commented May 28, 2024

@oliverdunk Very much agree with having both dark and light icons available so a theme switch can be made is a good one. However I believe exposing additional metadata for the action icon would be very useful in reducing the icons needed to generate and action icons are as pixel perfect as possible. For example, devicePixelRatio is currently not available in serviceWorkers sadly.

Think about a method like chrome.action.getIconSpecs() returning

{
    "size": 16,
    "dpi": 2,
    "actualSize": 32,
    "color_schemes": ["light", "dark"]
}

color_schemes would give the color schemes the browser supports. This again reduces the amount of icons needing to be generated with imageData.

@DanielHerr
Copy link

On the topic of DPR, I just realized that the multiple monitor use case is also something to consider. There can be multiple screens with different icon sizes.

So for a hypothetical function to get the icon size, you would need to return a set or array of icon sizes. You should then be able to use that with the existing size based action.setIcon, though I haven't tested whether that API handles multiple monitors correctly in browser implementations.

As far as I can tell calculating icon sizes for multiple screens is currently not trivally implemented.
On Chrome OS you can calculate the icon size as 16 * DPR as retrieved from chrome.system.display, which is easy enough.
However, that API doesn't expose the needed data on other platforms, so you have to fall back to either getScreenDetails on Chromium on Linux/Windows/Mac, which requires a permission prompt, not from the background but from an extension popup or tab.
Alternatively on Firefox creating a tab or popup on each display and retrieving DPR data from there, if the browser.windows.create API even allows that, or requiring a global content script injected just to read DPR on other screens.

Should this icon size retrieval topic be filed as a separate issue?

@xeenon
Copy link
Collaborator

xeenon commented Jun 4, 2024

A new issue would be best.

xeenon added a commit to xeenon/WebKit that referenced this issue Aug 31, 2024
https://webkit.org/b/278818
rdar://problem/134885372

Reviewed by NOBODY (OOPS!).

Add support for `icon_variants` manifest parsing under the `WK_WEB_EXTENSIONS_ICON_VARIANTS` flag,
with optimizations to ensure efficient icon loading.

This change introduces `icon_variants` manifest parsing, explicitly supporting different icon sets,
such as dark mode icons. To achieve this efficiently, icons are now cached by size, reducing disk
I/O by avoiding repeated loads when the browser frequently requests the same icon. The cache is
automatically invalidated when device scales change, such as when connecting or disconnecting a
display with a different scale factor.

Only the necessary icons are loaded based on the specific scale factor of all screens, halving the
image loads compared to previous behavior. This ensures that even as more extensions adopt dark
mode icons, typical image loads remain at two images (light and dark).

Proposal: https://github.com/w3c/webextensions/blob/main/proposals/dark_mode_extension_icons.md
WECG issue: w3c/webextensions#229

* Source/WTF/wtf/PlatformEnableCocoa.h: Added ENABLE_WK_WEB_EXTENSIONS_ICON_VARIANTS.
* Source/WebCore/en.lproj/Localizable.strings: Updated.
* Source/WebKit/Platform/cocoa/CocoaHelpers.h:
* Source/WebKit/Platform/cocoa/CocoaHelpers.mm:
(WebKit::availableScreenScales): Added.
(WebKit::largestDisplayScale): Added.
* Source/WebKit/Platform/spi/ios/UIKitSPI.h:
* Source/WebKit/UIProcess/Extensions/Cocoa/WebExtensionActionCocoa.mm:
(WebKit::WebExtensionAction::icon):
* Source/WebKit/UIProcess/Extensions/Cocoa/WebExtensionCocoa.mm:
(WebKit::WebExtension::icon):
(WebKit::WebExtension::actionIcon):
(WebKit::WebExtension::populateActionPropertiesIfNeeded):
(WebKit::WebExtension::populateSidebarActionProperties):
(WebKit::WebExtension::populateSidePanelProperties):
(WebKit::WebExtension::imageForPath):
(WebKit::WebExtension::bestSizeInIconsDictionary): Added.
(WebKit::WebExtension::pathForBestImageInIconsDictionary):
(WebKit::WebExtension::bestImageInIconsDictionary):
(WebKit::WebExtension::bestImageForIconsDictionaryManifestKey):
(WebKit::toColorSchemes): Added.
(WebKit::WebExtension::iconsDictionaryForBestIconVariant): Added.
(WebKit::WebExtension::bestImageForIconVariants): Added.
(WebKit::WebExtension::bestImageForIconVariantsManifestKey): Added.
* Source/WebKit/UIProcess/Extensions/Cocoa/WebExtensionMenuItemCocoa.mm:
(WebKit::WebExtensionMenuItem::icon const):
* Source/WebKit/UIProcess/Extensions/WebExtension.h:
* Tools/TestWebKitAPI/Tests/WebKitCocoa/WKWebExtension.mm:
(TestWebKitAPI::TEST(WKWebExtension, MultipleIconVariants)): Added.
(TestWebKitAPI::TEST(WKWebExtension, SingleIconVariant)): Added.
(TestWebKitAPI::TEST(WKWebExtension, AnySizeIconVariant)): Added.
(TestWebKitAPI::TEST(WKWebExtension, NoIconVariants)): Added.
(TestWebKitAPI::TEST(WKWebExtension, IconsAndIconVariantsSpecified)): Added.
(TestWebKitAPI::TEST(WKWebExtension, ActionIconVariantsMultiple)): Added.
(TestWebKitAPI::TEST(WKWebExtension, ActionIconSingleVariant)): Added.
(TestWebKitAPI::TEST(WKWebExtension, ActionIconAnySizeVariant)): Added.
(TestWebKitAPI::TEST(WKWebExtension, ActionNoIconVariants)): Added.
(TestWebKitAPI::TEST(WKWebExtension, ActionIconsAndIconVariantsSpecified)): Added.
* Tools/TestWebKitAPI/cocoa/WebExtensionUtilities.h:
* Tools/TestWebKitAPI/cocoa/WebExtensionUtilities.mm:
(TestWebKitAPI::Util::performWithAppearance): Added.
(TestWebKitAPI::Util::pixelColor): Added.
(TestWebKitAPI::Util::toSRGBColor): Added.
(TestWebKitAPI::Util::compareColors): Added.
xeenon added a commit to xeenon/WebKit that referenced this issue Aug 31, 2024
https://webkit.org/b/278818
rdar://problem/134885372

Reviewed by NOBODY (OOPS!).

Add support for `icon_variants` manifest parsing under the `WK_WEB_EXTENSIONS_ICON_VARIANTS` flag,
with optimizations to ensure efficient icon loading.

This change introduces `icon_variants` manifest parsing, explicitly supporting different icon sets,
such as dark mode icons. To achieve this efficiently, icons are now cached by size, reducing disk
I/O by avoiding repeated loads when the browser frequently requests the same icon. The cache is
automatically invalidated when device scales change, such as when connecting or disconnecting a
display with a different scale factor.

Only the necessary icons are loaded based on the specific scale factor of all screens, halving the
image loads compared to previous behavior. This ensures that even as more extensions adopt dark
mode icons, typical image loads remain at two images (light and dark).

Proposal: https://github.com/w3c/webextensions/blob/main/proposals/dark_mode_extension_icons.md
WECG issue: w3c/webextensions#229

* Source/WTF/wtf/PlatformEnableCocoa.h: Added ENABLE_WK_WEB_EXTENSIONS_ICON_VARIANTS.
* Source/WebCore/en.lproj/Localizable.strings: Updated.
* Source/WebKit/Platform/cocoa/CocoaHelpers.h:
* Source/WebKit/Platform/cocoa/CocoaHelpers.mm:
(WebKit::availableScreenScales): Added.
(WebKit::largestDisplayScale): Added.
* Source/WebKit/Platform/spi/ios/UIKitSPI.h:
* Source/WebKit/UIProcess/Extensions/Cocoa/WebExtensionActionCocoa.mm:
(WebKit::WebExtensionAction::icon):
* Source/WebKit/UIProcess/Extensions/Cocoa/WebExtensionCocoa.mm:
(WebKit::WebExtension::icon):
(WebKit::WebExtension::actionIcon):
(WebKit::WebExtension::populateActionPropertiesIfNeeded):
(WebKit::WebExtension::populateSidebarActionProperties):
(WebKit::WebExtension::populateSidePanelProperties):
(WebKit::WebExtension::imageForPath):
(WebKit::WebExtension::bestSizeInIconsDictionary): Added.
(WebKit::WebExtension::pathForBestImageInIconsDictionary):
(WebKit::WebExtension::bestImageInIconsDictionary):
(WebKit::WebExtension::bestImageForIconsDictionaryManifestKey):
(WebKit::toColorSchemes): Added.
(WebKit::WebExtension::iconsDictionaryForBestIconVariant): Added.
(WebKit::WebExtension::bestImageForIconVariants): Added.
(WebKit::WebExtension::bestImageForIconVariantsManifestKey): Added.
* Source/WebKit/UIProcess/Extensions/Cocoa/WebExtensionMenuItemCocoa.mm:
(WebKit::WebExtensionMenuItem::icon const):
* Source/WebKit/UIProcess/Extensions/WebExtension.h:
* Tools/TestWebKitAPI/Tests/WebKitCocoa/WKWebExtension.mm:
(TestWebKitAPI::TEST(WKWebExtension, MultipleIconVariants)): Added.
(TestWebKitAPI::TEST(WKWebExtension, SingleIconVariant)): Added.
(TestWebKitAPI::TEST(WKWebExtension, AnySizeIconVariant)): Added.
(TestWebKitAPI::TEST(WKWebExtension, NoIconVariants)): Added.
(TestWebKitAPI::TEST(WKWebExtension, IconsAndIconVariantsSpecified)): Added.
(TestWebKitAPI::TEST(WKWebExtension, ActionIconVariantsMultiple)): Added.
(TestWebKitAPI::TEST(WKWebExtension, ActionIconSingleVariant)): Added.
(TestWebKitAPI::TEST(WKWebExtension, ActionIconAnySizeVariant)): Added.
(TestWebKitAPI::TEST(WKWebExtension, ActionNoIconVariants)): Added.
(TestWebKitAPI::TEST(WKWebExtension, ActionIconsAndIconVariantsSpecified)): Added.
* Tools/TestWebKitAPI/cocoa/WebExtensionUtilities.h:
* Tools/TestWebKitAPI/cocoa/WebExtensionUtilities.mm:
(TestWebKitAPI::Util::performWithAppearance): Added.
(TestWebKitAPI::Util::pixelColor): Added.
(TestWebKitAPI::Util::toSRGBColor): Added.
(TestWebKitAPI::Util::compareColors): Added.
xeenon added a commit to xeenon/WebKit that referenced this issue Aug 31, 2024
https://webkit.org/b/278818
rdar://problem/134885372

Reviewed by NOBODY (OOPS!).

Add support for `icon_variants` manifest parsing under the `WK_WEB_EXTENSIONS_ICON_VARIANTS` flag,
with optimizations to ensure efficient icon loading.

This change introduces `icon_variants` manifest parsing, explicitly supporting different icon sets,
such as dark mode icons. To achieve this efficiently, icons are now cached by size, reducing disk
I/O by avoiding repeated loads when the browser frequently requests the same icon. The cache is
automatically invalidated when device scales change, such as when connecting or disconnecting a
display with a different scale factor.

Only the necessary icons are loaded based on the specific scale factor of all screens, halving the
image loads compared to previous behavior. This ensures that even as more extensions adopt dark
mode icons, typical image loads remain at two images (light and dark).

Proposal: https://github.com/w3c/webextensions/blob/main/proposals/dark_mode_extension_icons.md
WECG issue: w3c/webextensions#229

* Source/WTF/wtf/PlatformEnableCocoa.h: Added ENABLE_WK_WEB_EXTENSIONS_ICON_VARIANTS.
* Source/WebCore/en.lproj/Localizable.strings: Updated.
* Source/WebKit/Platform/cocoa/CocoaHelpers.h:
* Source/WebKit/Platform/cocoa/CocoaHelpers.mm:
(WebKit::availableScreenScales): Added.
(WebKit::largestDisplayScale): Added.
* Source/WebKit/Platform/spi/ios/UIKitSPI.h:
* Source/WebKit/UIProcess/Extensions/Cocoa/WebExtensionActionCocoa.mm:
(WebKit::WebExtensionAction::icon):
* Source/WebKit/UIProcess/Extensions/Cocoa/WebExtensionCocoa.mm:
(WebKit::WebExtension::icon):
(WebKit::WebExtension::actionIcon):
(WebKit::WebExtension::populateActionPropertiesIfNeeded):
(WebKit::WebExtension::populateSidebarActionProperties):
(WebKit::WebExtension::populateSidePanelProperties):
(WebKit::WebExtension::imageForPath):
(WebKit::WebExtension::bestSizeInIconsDictionary): Added.
(WebKit::WebExtension::pathForBestImageInIconsDictionary):
(WebKit::WebExtension::bestImageInIconsDictionary):
(WebKit::WebExtension::bestImageForIconsDictionaryManifestKey):
(WebKit::toColorSchemes): Added.
(WebKit::WebExtension::iconsDictionaryForBestIconVariant): Added.
(WebKit::WebExtension::bestImageForIconVariants): Added.
(WebKit::WebExtension::bestImageForIconVariantsManifestKey): Added.
* Source/WebKit/UIProcess/Extensions/Cocoa/WebExtensionMenuItemCocoa.mm:
(WebKit::WebExtensionMenuItem::icon const):
* Source/WebKit/UIProcess/Extensions/WebExtension.h:
* Tools/TestWebKitAPI/Tests/WebKitCocoa/WKWebExtension.mm:
(TestWebKitAPI::TEST(WKWebExtension, MultipleIconVariants)): Added.
(TestWebKitAPI::TEST(WKWebExtension, SingleIconVariant)): Added.
(TestWebKitAPI::TEST(WKWebExtension, AnySizeIconVariant)): Added.
(TestWebKitAPI::TEST(WKWebExtension, NoIconVariants)): Added.
(TestWebKitAPI::TEST(WKWebExtension, IconsAndIconVariantsSpecified)): Added.
(TestWebKitAPI::TEST(WKWebExtension, ActionIconVariantsMultiple)): Added.
(TestWebKitAPI::TEST(WKWebExtension, ActionIconSingleVariant)): Added.
(TestWebKitAPI::TEST(WKWebExtension, ActionIconAnySizeVariant)): Added.
(TestWebKitAPI::TEST(WKWebExtension, ActionNoIconVariants)): Added.
(TestWebKitAPI::TEST(WKWebExtension, ActionIconsAndIconVariantsSpecified)): Added.
* Tools/TestWebKitAPI/cocoa/WebExtensionUtilities.h:
* Tools/TestWebKitAPI/cocoa/WebExtensionUtilities.mm:
(TestWebKitAPI::Util::performWithAppearance): Added.
(TestWebKitAPI::Util::pixelColor): Added.
(TestWebKitAPI::Util::toSRGBColor): Added.
(TestWebKitAPI::Util::compareColors): Added.
xeenon added a commit to xeenon/WebKit that referenced this issue Aug 31, 2024
https://webkit.org/b/278818
rdar://problem/134885372

Reviewed by NOBODY (OOPS!).

Add support for `icon_variants` manifest parsing under the `WK_WEB_EXTENSIONS_ICON_VARIANTS` flag,
with optimizations to ensure efficient icon loading.

This change introduces `icon_variants` manifest parsing, explicitly supporting different icon sets,
such as dark mode icons. To achieve this efficiently, icons are now cached by size, reducing disk
I/O by avoiding repeated loads when the browser frequently requests the same icon. The cache is
automatically invalidated when device scales change, such as when connecting or disconnecting a
display with a different scale factor.

Only the necessary icons are loaded based on the specific scale factor of all screens, halving the
image loads compared to previous behavior. This ensures that even as more extensions adopt dark
mode icons, typical image loads remain at two images (light and dark).

Proposal: https://github.com/w3c/webextensions/blob/main/proposals/dark_mode_extension_icons.md
WECG issue: w3c/webextensions#229

* Source/WTF/wtf/PlatformEnableCocoa.h: Added ENABLE_WK_WEB_EXTENSIONS_ICON_VARIANTS.
* Source/WebCore/en.lproj/Localizable.strings: Updated.
* Source/WebKit/Platform/cocoa/CocoaHelpers.h:
* Source/WebKit/Platform/cocoa/CocoaHelpers.mm:
(WebKit::availableScreenScales): Added.
(WebKit::largestDisplayScale): Added.
* Source/WebKit/Platform/spi/ios/UIKitSPI.h:
* Source/WebKit/UIProcess/Extensions/Cocoa/WebExtensionActionCocoa.mm:
(WebKit::WebExtensionAction::icon):
* Source/WebKit/UIProcess/Extensions/Cocoa/WebExtensionCocoa.mm:
(WebKit::WebExtension::icon):
(WebKit::WebExtension::actionIcon):
(WebKit::WebExtension::populateActionPropertiesIfNeeded):
(WebKit::WebExtension::populateSidebarActionProperties):
(WebKit::WebExtension::populateSidePanelProperties):
(WebKit::WebExtension::imageForPath):
(WebKit::WebExtension::bestSizeInIconsDictionary): Added.
(WebKit::WebExtension::pathForBestImageInIconsDictionary):
(WebKit::WebExtension::bestImageInIconsDictionary):
(WebKit::WebExtension::bestImageForIconsDictionaryManifestKey):
(WebKit::toColorSchemes): Added.
(WebKit::WebExtension::iconsDictionaryForBestIconVariant): Added.
(WebKit::WebExtension::bestImageForIconVariants): Added.
(WebKit::WebExtension::bestImageForIconVariantsManifestKey): Added.
* Source/WebKit/UIProcess/Extensions/Cocoa/WebExtensionMenuItemCocoa.mm:
(WebKit::WebExtensionMenuItem::icon const):
* Source/WebKit/UIProcess/Extensions/WebExtension.h:
* Tools/TestWebKitAPI/Tests/WebKitCocoa/WKWebExtension.mm:
(TestWebKitAPI::TEST(WKWebExtension, MultipleIconVariants)): Added.
(TestWebKitAPI::TEST(WKWebExtension, SingleIconVariant)): Added.
(TestWebKitAPI::TEST(WKWebExtension, AnySizeIconVariant)): Added.
(TestWebKitAPI::TEST(WKWebExtension, NoIconVariants)): Added.
(TestWebKitAPI::TEST(WKWebExtension, IconsAndIconVariantsSpecified)): Added.
(TestWebKitAPI::TEST(WKWebExtension, ActionIconVariantsMultiple)): Added.
(TestWebKitAPI::TEST(WKWebExtension, ActionIconSingleVariant)): Added.
(TestWebKitAPI::TEST(WKWebExtension, ActionIconAnySizeVariant)): Added.
(TestWebKitAPI::TEST(WKWebExtension, ActionNoIconVariants)): Added.
(TestWebKitAPI::TEST(WKWebExtension, ActionIconsAndIconVariantsSpecified)): Added.
* Tools/TestWebKitAPI/cocoa/WebExtensionUtilities.h:
* Tools/TestWebKitAPI/cocoa/WebExtensionUtilities.mm:
(TestWebKitAPI::Util::performWithAppearance): Added.
(TestWebKitAPI::Util::pixelColor): Added.
(TestWebKitAPI::Util::toSRGBColor): Added.
(TestWebKitAPI::Util::compareColors): Added.
xeenon added a commit to xeenon/WebKit that referenced this issue Sep 3, 2024
https://webkit.org/b/278818
rdar://problem/134885372

Reviewed by NOBODY (OOPS!).

Add support for `icon_variants` manifest parsing under the `WK_WEB_EXTENSIONS_ICON_VARIANTS` flag,
with optimizations to ensure efficient icon loading.

This change introduces `icon_variants` manifest parsing, explicitly supporting different icon sets,
such as dark mode icons. To achieve this efficiently, icons are now cached by size, reducing disk
I/O by avoiding repeated loads when the browser frequently requests the same icon. The cache is
automatically invalidated when device scales change, such as when connecting or disconnecting a
display with a different scale factor.

Only the necessary icons are loaded based on the specific scale factor of all screens, halving the
image loads compared to previous behavior. This ensures that even as more extensions adopt dark
mode icons, typical image loads remain at two images (light and dark).

Proposal: https://github.com/w3c/webextensions/blob/main/proposals/dark_mode_extension_icons.md
WECG issue: w3c/webextensions#229

* Source/WTF/wtf/PlatformEnableCocoa.h: Added ENABLE_WK_WEB_EXTENSIONS_ICON_VARIANTS.
* Source/WebCore/en.lproj/Localizable.strings: Updated.
* Source/WebKit/Platform/cocoa/CocoaHelpers.h:
* Source/WebKit/Platform/cocoa/CocoaHelpers.mm:
(WebKit::availableScreenScales): Added.
(WebKit::largestDisplayScale): Added.
* Source/WebKit/Platform/spi/ios/UIKitSPI.h:
* Source/WebKit/UIProcess/Extensions/Cocoa/WebExtensionActionCocoa.mm:
(WebKit::WebExtensionAction::icon):
* Source/WebKit/UIProcess/Extensions/Cocoa/WebExtensionCocoa.mm:
(WebKit::WebExtension::icon):
(WebKit::WebExtension::actionIcon):
(WebKit::WebExtension::populateActionPropertiesIfNeeded):
(WebKit::WebExtension::populateSidebarActionProperties):
(WebKit::WebExtension::populateSidePanelProperties):
(WebKit::WebExtension::imageForPath):
(WebKit::WebExtension::bestSizeInIconsDictionary): Added.
(WebKit::WebExtension::pathForBestImageInIconsDictionary):
(WebKit::WebExtension::bestImageInIconsDictionary):
(WebKit::WebExtension::bestImageForIconsDictionaryManifestKey):
(WebKit::toColorSchemes): Added.
(WebKit::WebExtension::iconsDictionaryForBestIconVariant): Added.
(WebKit::WebExtension::bestImageForIconVariants): Added.
(WebKit::WebExtension::bestImageForIconVariantsManifestKey): Added.
* Source/WebKit/UIProcess/Extensions/Cocoa/WebExtensionMenuItemCocoa.mm:
(WebKit::WebExtensionMenuItem::icon const):
* Source/WebKit/UIProcess/Extensions/WebExtension.h:
* Tools/TestWebKitAPI/Tests/WebKitCocoa/WKWebExtension.mm:
(TestWebKitAPI::TEST(WKWebExtension, MultipleIconVariants)): Added.
(TestWebKitAPI::TEST(WKWebExtension, SingleIconVariant)): Added.
(TestWebKitAPI::TEST(WKWebExtension, AnySizeIconVariant)): Added.
(TestWebKitAPI::TEST(WKWebExtension, NoIconVariants)): Added.
(TestWebKitAPI::TEST(WKWebExtension, IconsAndIconVariantsSpecified)): Added.
(TestWebKitAPI::TEST(WKWebExtension, ActionIconVariantsMultiple)): Added.
(TestWebKitAPI::TEST(WKWebExtension, ActionIconSingleVariant)): Added.
(TestWebKitAPI::TEST(WKWebExtension, ActionIconAnySizeVariant)): Added.
(TestWebKitAPI::TEST(WKWebExtension, ActionNoIconVariants)): Added.
(TestWebKitAPI::TEST(WKWebExtension, ActionIconsAndIconVariantsSpecified)): Added.
* Tools/TestWebKitAPI/cocoa/WebExtensionUtilities.h:
* Tools/TestWebKitAPI/cocoa/WebExtensionUtilities.mm:
(TestWebKitAPI::Util::performWithAppearance): Added.
(TestWebKitAPI::Util::pixelColor): Added.
(TestWebKitAPI::Util::toSRGBColor): Added.
(TestWebKitAPI::Util::compareColors): Added.
webkit-commit-queue pushed a commit to xeenon/WebKit that referenced this issue Sep 3, 2024
https://webkit.org/b/278818
rdar://problem/134885372

Reviewed by Brian Weinstein.

Add support for `icon_variants` manifest parsing under the `WK_WEB_EXTENSIONS_ICON_VARIANTS` flag,
with optimizations to ensure efficient icon loading.

This change introduces `icon_variants` manifest parsing, explicitly supporting different icon sets,
such as dark mode icons. To achieve this efficiently, icons are now cached by size, reducing disk
I/O by avoiding repeated loads when the browser frequently requests the same icon. The cache is
automatically invalidated when device scales change, such as when connecting or disconnecting a
display with a different scale factor.

Only the necessary icons are loaded based on the specific scale factor of all screens, halving the
image loads compared to previous behavior. This ensures that even as more extensions adopt dark
mode icons, typical image loads remain at two images (light and dark).

Proposal: https://github.com/w3c/webextensions/blob/main/proposals/dark_mode_extension_icons.md
WECG issue: w3c/webextensions#229

* Source/WTF/wtf/PlatformEnableCocoa.h: Added ENABLE_WK_WEB_EXTENSIONS_ICON_VARIANTS.
* Source/WebCore/en.lproj/Localizable.strings: Updated.
* Source/WebKit/Platform/cocoa/CocoaHelpers.h:
* Source/WebKit/Platform/cocoa/CocoaHelpers.mm:
(WebKit::availableScreenScales): Added.
(WebKit::largestDisplayScale): Added.
* Source/WebKit/Platform/spi/ios/UIKitSPI.h:
* Source/WebKit/UIProcess/Extensions/Cocoa/WebExtensionActionCocoa.mm:
(WebKit::WebExtensionAction::icon):
* Source/WebKit/UIProcess/Extensions/Cocoa/WebExtensionCocoa.mm:
(WebKit::WebExtension::icon):
(WebKit::WebExtension::actionIcon):
(WebKit::WebExtension::populateActionPropertiesIfNeeded):
(WebKit::WebExtension::populateSidebarActionProperties):
(WebKit::WebExtension::populateSidePanelProperties):
(WebKit::WebExtension::imageForPath):
(WebKit::WebExtension::bestSizeInIconsDictionary): Added.
(WebKit::WebExtension::pathForBestImageInIconsDictionary):
(WebKit::WebExtension::bestImageInIconsDictionary):
(WebKit::WebExtension::bestImageForIconsDictionaryManifestKey):
(WebKit::toColorSchemes): Added.
(WebKit::WebExtension::iconsDictionaryForBestIconVariant): Added.
(WebKit::WebExtension::bestImageForIconVariants): Added.
(WebKit::WebExtension::bestImageForIconVariantsManifestKey): Added.
* Source/WebKit/UIProcess/Extensions/Cocoa/WebExtensionMenuItemCocoa.mm:
(WebKit::WebExtensionMenuItem::icon const):
* Source/WebKit/UIProcess/Extensions/WebExtension.h:
* Tools/TestWebKitAPI/Tests/WebKitCocoa/WKWebExtension.mm:
(TestWebKitAPI::TEST(WKWebExtension, MultipleIconVariants)): Added.
(TestWebKitAPI::TEST(WKWebExtension, SingleIconVariant)): Added.
(TestWebKitAPI::TEST(WKWebExtension, AnySizeIconVariant)): Added.
(TestWebKitAPI::TEST(WKWebExtension, NoIconVariants)): Added.
(TestWebKitAPI::TEST(WKWebExtension, IconsAndIconVariantsSpecified)): Added.
(TestWebKitAPI::TEST(WKWebExtension, ActionIconVariantsMultiple)): Added.
(TestWebKitAPI::TEST(WKWebExtension, ActionIconSingleVariant)): Added.
(TestWebKitAPI::TEST(WKWebExtension, ActionIconAnySizeVariant)): Added.
(TestWebKitAPI::TEST(WKWebExtension, ActionNoIconVariants)): Added.
(TestWebKitAPI::TEST(WKWebExtension, ActionIconsAndIconVariantsSpecified)): Added.
* Tools/TestWebKitAPI/cocoa/WebExtensionUtilities.h:
* Tools/TestWebKitAPI/cocoa/WebExtensionUtilities.mm:
(TestWebKitAPI::Util::performWithAppearance): Added.
(TestWebKitAPI::Util::pixelColor): Added.
(TestWebKitAPI::Util::toSRGBColor): Added.
(TestWebKitAPI::Util::compareColors): Added.

Canonical link: https://commits.webkit.org/283118@main
@xeenon xeenon added implemented: safari Implemented in Safari and removed supportive: safari Supportive from Safari labels Sep 3, 2024
xeenon added a commit to xeenon/WebKit that referenced this issue Sep 4, 2024
…or Web Extensions.

https://webkit.org/b/279135
rdar://problem/134885372

Reviewed by NOBODY (OOPS!).

Add support for the `icons_variants` key in `menus.create()` and `menus.update()`.
Also add support for `variants` key in `action.setIcon()`.

Proposal: https://github.com/w3c/webextensions/blob/main/proposals/dark_mode_extension_icons.md
WECG issue: w3c/webextensions#229

* Source/WebKit/Shared/Extensions/WebExtensionMenuItem.serialization.in:
* Source/WebKit/Shared/Extensions/WebExtensionMenuItemParameters.h:
* Source/WebKit/UIProcess/Extensions/Cocoa/API/WebExtensionContextAPIActionCocoa.mm:
(WebKit::WebExtensionContext::actionSetIcon):
* Source/WebKit/UIProcess/Extensions/Cocoa/WebExtensionActionCocoa.mm:
(WebKit::WebExtensionAction::clearCustomizations):
(WebKit::WebExtensionAction::icon):
(WebKit::WebExtensionAction::setIcons):
(WebKit::WebExtensionAction::setIconVariants):
(WebKit::WebExtensionAction::clearIconCache):
(WebKit::WebExtensionAction::setIconsDictionary): Deleted.
* Source/WebKit/UIProcess/Extensions/Cocoa/WebExtensionMenuItemCocoa.mm:
(WebKit::WebExtensionMenuItem::WebExtensionMenuItem):
(WebKit::WebExtensionMenuItem::minimalParameters const):
(WebKit::WebExtensionMenuItem::update):
(WebKit::WebExtensionMenuItem::icon const):
(WebKit::WebExtensionMenuItem::clearIconCache const):
* Source/WebKit/UIProcess/Extensions/WebExtensionAction.h:
* Source/WebKit/UIProcess/Extensions/WebExtensionContext.h:
* Source/WebKit/UIProcess/Extensions/WebExtensionContext.messages.in:
* Source/WebKit/UIProcess/Extensions/WebExtensionMenuItem.h:
* Source/WebKit/WebProcess/Extensions/API/Cocoa/WebExtensionAPIActionCocoa.mm:
(WebKit::WebExtensionAPIAction::isValidDimensionKey):
(WebKit::WebExtensionAPIAction::parseIconPath):
(WebKit::WebExtensionAPIAction::parseIconPathsDictionary):
(WebKit::WebExtensionAPIAction::parseIconImageDataDictionary):
(WebKit::WebExtensionAPIAction::parseIconVariants):
(WebKit::WebExtensionAPIAction::setIcon):
* Source/WebKit/WebProcess/Extensions/API/Cocoa/WebExtensionAPIMenusCocoa.mm:
(WebKit::WebExtensionAPIMenus::parseCreateAndUpdateProperties):
(WebKit::WebExtensionAPIMenus::createMenu):
(WebKit::WebExtensionAPIMenus::update):
* Source/WebKit/WebProcess/Extensions/API/WebExtensionAPIAction.h:
* Source/WebKit/WebProcess/Extensions/API/WebExtensionAPIMenus.h:
* Source/WebKit/WebProcess/Extensions/Bindings/Scripts/CodeGeneratorExtensions.pm:
(_generateImplementationFile):
* Source/WebKit/WebProcess/Extensions/Interfaces/WebExtensionAPIMenus.idl:
* Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/xcshareddata/xcschemes/TestWebKitAPI.xcscheme:
* Tools/TestWebKitAPI/Tests/WebKitCocoa/WKWebExtensionAPIAction.mm:
(TestWebKitAPI::TEST(WKWebExtensionAPIAction, SetIconWithDataURL)): Renamed.
(TestWebKitAPI::TEST(WKWebExtensionAPIAction, SetIconWithVariants)): Added.
(TestWebKitAPI::TEST(WKWebExtensionAPIAction, SetIconWithImageDataAndVariants)): Added.
(TestWebKitAPI::TEST(WKWebExtensionAPIAction, SetIconThrowsWithNoValidVariants)): Added.
(TestWebKitAPI::TEST(WKWebExtensionAPIAction, SetIconWithMixedValidAndInvalidVariants)): Added.
(TestWebKitAPI::TEST(WKWebExtensionAPIAction, SetIconWithAnySizeVariantAndSVGDataURL)): Added.
(TestWebKitAPI::TEST(WKWebExtensionAPIAction, SetIconWithSVGDataURL)): Deleted.
* Tools/TestWebKitAPI/Tests/WebKitCocoa/WKWebExtensionAPIMenus.mm:
(TestWebKitAPI::TEST(WKWebExtensionAPIMenus, Errors)): Fixed expectations.
(TestWebKitAPI::TEST(WKWebExtensionAPIMenus, MenuItemWithIconVariants)): Added.
(TestWebKitAPI::TEST(WKWebExtensionAPIMenus, MenuItemWithImageDataVariants)): Added.
(TestWebKitAPI::TEST(WKWebExtensionAPIMenus, MenuItemWithWithNoValidVariants)): Added.
(TestWebKitAPI::TEST(WKWebExtensionAPIMenus, MenuItemWithMixedValidAndInvalidIconVariants)): Added.
(TestWebKitAPI::TEST(WKWebExtensionAPIMenus, MenuItemWithAnySizeVariantAndSVGDataURL)): Added.
(TestWebKitAPI::TEST(WKWebExtensionAPIMenus, UpdateMenuItemWithIconVariants)): Added.
(TestWebKitAPI::TEST(WKWebExtensionAPIMenus, ClearMenuItemIconVariantsWithNull)): Added.
(TestWebKitAPI::TEST(WKWebExtensionAPIMenus, ClearMenuItemIconVariantsWithEmpty)): Added.
xeenon added a commit to xeenon/WebKit that referenced this issue Sep 4, 2024
…or Web Extensions.

https://webkit.org/b/279135
rdar://problem/134885372

Reviewed by NOBODY (OOPS!).

Add support for the `icons_variants` key in `menus.create()` and `menus.update()`.
Also add support for `variants` key in `action.setIcon()`.

Proposal: https://github.com/w3c/webextensions/blob/main/proposals/dark_mode_extension_icons.md
WECG issue: w3c/webextensions#229

* Source/WebKit/Shared/Extensions/WebExtensionMenuItem.serialization.in:
* Source/WebKit/Shared/Extensions/WebExtensionMenuItemParameters.h:
* Source/WebKit/UIProcess/Extensions/Cocoa/API/WebExtensionContextAPIActionCocoa.mm:
(WebKit::WebExtensionContext::actionSetIcon):
* Source/WebKit/UIProcess/Extensions/Cocoa/WebExtensionActionCocoa.mm:
(WebKit::WebExtensionAction::clearCustomizations):
(WebKit::WebExtensionAction::icon):
(WebKit::WebExtensionAction::setIcons):
(WebKit::WebExtensionAction::setIconVariants):
(WebKit::WebExtensionAction::clearIconCache):
(WebKit::WebExtensionAction::setIconsDictionary): Deleted.
* Source/WebKit/UIProcess/Extensions/Cocoa/WebExtensionMenuItemCocoa.mm:
(WebKit::WebExtensionMenuItem::WebExtensionMenuItem):
(WebKit::WebExtensionMenuItem::minimalParameters const):
(WebKit::WebExtensionMenuItem::update):
(WebKit::WebExtensionMenuItem::icon const):
(WebKit::WebExtensionMenuItem::clearIconCache const):
* Source/WebKit/UIProcess/Extensions/WebExtensionAction.h:
* Source/WebKit/UIProcess/Extensions/WebExtensionContext.h:
* Source/WebKit/UIProcess/Extensions/WebExtensionContext.messages.in:
* Source/WebKit/UIProcess/Extensions/WebExtensionMenuItem.h:
* Source/WebKit/WebProcess/Extensions/API/Cocoa/WebExtensionAPIActionCocoa.mm:
(WebKit::WebExtensionAPIAction::isValidDimensionKey):
(WebKit::WebExtensionAPIAction::parseIconPath):
(WebKit::WebExtensionAPIAction::parseIconPathsDictionary):
(WebKit::WebExtensionAPIAction::parseIconImageDataDictionary):
(WebKit::WebExtensionAPIAction::parseIconVariants):
(WebKit::WebExtensionAPIAction::setIcon):
* Source/WebKit/WebProcess/Extensions/API/Cocoa/WebExtensionAPIMenusCocoa.mm:
(WebKit::WebExtensionAPIMenus::parseCreateAndUpdateProperties):
(WebKit::WebExtensionAPIMenus::createMenu):
(WebKit::WebExtensionAPIMenus::update):
* Source/WebKit/WebProcess/Extensions/API/WebExtensionAPIAction.h:
* Source/WebKit/WebProcess/Extensions/API/WebExtensionAPIMenus.h:
* Source/WebKit/WebProcess/Extensions/Bindings/Scripts/CodeGeneratorExtensions.pm:
(_generateImplementationFile):
* Source/WebKit/WebProcess/Extensions/Interfaces/WebExtensionAPIMenus.idl:
* Tools/TestWebKitAPI/Tests/WebKitCocoa/WKWebExtensionAPIAction.mm:
(TestWebKitAPI::TEST(WKWebExtensionAPIAction, SetIconWithDataURL)): Renamed.
(TestWebKitAPI::TEST(WKWebExtensionAPIAction, SetIconWithVariants)): Added.
(TestWebKitAPI::TEST(WKWebExtensionAPIAction, SetIconWithImageDataAndVariants)): Added.
(TestWebKitAPI::TEST(WKWebExtensionAPIAction, SetIconThrowsWithNoValidVariants)): Added.
(TestWebKitAPI::TEST(WKWebExtensionAPIAction, SetIconWithMixedValidAndInvalidVariants)): Added.
(TestWebKitAPI::TEST(WKWebExtensionAPIAction, SetIconWithAnySizeVariantAndSVGDataURL)): Added.
(TestWebKitAPI::TEST(WKWebExtensionAPIAction, SetIconWithSVGDataURL)): Deleted.
* Tools/TestWebKitAPI/Tests/WebKitCocoa/WKWebExtensionAPIMenus.mm:
(TestWebKitAPI::TEST(WKWebExtensionAPIMenus, Errors)): Fixed expectations.
(TestWebKitAPI::TEST(WKWebExtensionAPIMenus, MenuItemWithIconVariants)): Added.
(TestWebKitAPI::TEST(WKWebExtensionAPIMenus, MenuItemWithImageDataVariants)): Added.
(TestWebKitAPI::TEST(WKWebExtensionAPIMenus, MenuItemWithWithNoValidVariants)): Added.
(TestWebKitAPI::TEST(WKWebExtensionAPIMenus, MenuItemWithMixedValidAndInvalidIconVariants)): Added.
(TestWebKitAPI::TEST(WKWebExtensionAPIMenus, MenuItemWithAnySizeVariantAndSVGDataURL)): Added.
(TestWebKitAPI::TEST(WKWebExtensionAPIMenus, UpdateMenuItemWithIconVariants)): Added.
(TestWebKitAPI::TEST(WKWebExtensionAPIMenus, ClearMenuItemIconVariantsWithNull)): Added.
(TestWebKitAPI::TEST(WKWebExtensionAPIMenus, ClearMenuItemIconVariantsWithEmpty)): Added.
xeenon added a commit to xeenon/WebKit that referenced this issue Sep 4, 2024
…or Web Extensions.

https://webkit.org/b/279135
rdar://problem/134885372

Reviewed by NOBODY (OOPS!).

Add support for the `icons_variants` key in `menus.create()` and `menus.update()`.
Also add support for `variants` key in `action.setIcon()`.

Proposal: https://github.com/w3c/webextensions/blob/main/proposals/dark_mode_extension_icons.md
WECG issue: w3c/webextensions#229

* Source/WebKit/Shared/Extensions/WebExtensionMenuItem.serialization.in:
* Source/WebKit/Shared/Extensions/WebExtensionMenuItemParameters.h:
* Source/WebKit/UIProcess/Extensions/Cocoa/API/WebExtensionContextAPIActionCocoa.mm:
(WebKit::WebExtensionContext::actionSetIcon):
* Source/WebKit/UIProcess/Extensions/Cocoa/WebExtensionActionCocoa.mm:
(WebKit::WebExtensionAction::clearCustomizations):
(WebKit::WebExtensionAction::icon):
(WebKit::WebExtensionAction::setIcons):
(WebKit::WebExtensionAction::setIconVariants):
(WebKit::WebExtensionAction::clearIconCache):
(WebKit::WebExtensionAction::setIconsDictionary): Deleted.
* Source/WebKit/UIProcess/Extensions/Cocoa/WebExtensionMenuItemCocoa.mm:
(WebKit::WebExtensionMenuItem::WebExtensionMenuItem):
(WebKit::WebExtensionMenuItem::minimalParameters const):
(WebKit::WebExtensionMenuItem::update):
(WebKit::WebExtensionMenuItem::icon const):
(WebKit::WebExtensionMenuItem::clearIconCache const):
* Source/WebKit/UIProcess/Extensions/WebExtensionAction.h:
* Source/WebKit/UIProcess/Extensions/WebExtensionContext.h:
* Source/WebKit/UIProcess/Extensions/WebExtensionContext.messages.in:
* Source/WebKit/UIProcess/Extensions/WebExtensionMenuItem.h:
* Source/WebKit/WebProcess/Extensions/API/Cocoa/WebExtensionAPIActionCocoa.mm:
(WebKit::WebExtensionAPIAction::isValidDimensionKey):
(WebKit::WebExtensionAPIAction::parseIconPath):
(WebKit::WebExtensionAPIAction::parseIconPathsDictionary):
(WebKit::WebExtensionAPIAction::parseIconImageDataDictionary):
(WebKit::WebExtensionAPIAction::parseIconVariants):
(WebKit::WebExtensionAPIAction::setIcon):
* Source/WebKit/WebProcess/Extensions/API/Cocoa/WebExtensionAPIMenusCocoa.mm:
(WebKit::WebExtensionAPIMenus::parseCreateAndUpdateProperties):
(WebKit::WebExtensionAPIMenus::createMenu):
(WebKit::WebExtensionAPIMenus::update):
* Source/WebKit/WebProcess/Extensions/API/WebExtensionAPIAction.h:
* Source/WebKit/WebProcess/Extensions/API/WebExtensionAPIMenus.h:
* Source/WebKit/WebProcess/Extensions/Bindings/Scripts/CodeGeneratorExtensions.pm:
(_generateImplementationFile):
* Source/WebKit/WebProcess/Extensions/Interfaces/WebExtensionAPIMenus.idl:
* Tools/TestWebKitAPI/Tests/WebKitCocoa/WKWebExtensionAPIAction.mm:
(TestWebKitAPI::TEST(WKWebExtensionAPIAction, SetIconWithDataURL)): Renamed.
(TestWebKitAPI::TEST(WKWebExtensionAPIAction, SetIconWithVariants)): Added.
(TestWebKitAPI::TEST(WKWebExtensionAPIAction, SetIconWithImageDataAndVariants)): Added.
(TestWebKitAPI::TEST(WKWebExtensionAPIAction, SetIconThrowsWithNoValidVariants)): Added.
(TestWebKitAPI::TEST(WKWebExtensionAPIAction, SetIconWithMixedValidAndInvalidVariants)): Added.
(TestWebKitAPI::TEST(WKWebExtensionAPIAction, SetIconWithAnySizeVariantAndSVGDataURL)): Added.
(TestWebKitAPI::TEST(WKWebExtensionAPIAction, SetIconWithSVGDataURL)): Deleted.
* Tools/TestWebKitAPI/Tests/WebKitCocoa/WKWebExtensionAPIMenus.mm:
(TestWebKitAPI::TEST(WKWebExtensionAPIMenus, Errors)): Fixed expectations.
(TestWebKitAPI::TEST(WKWebExtensionAPIMenus, MenuItemWithIconVariants)): Added.
(TestWebKitAPI::TEST(WKWebExtensionAPIMenus, MenuItemWithImageDataVariants)): Added.
(TestWebKitAPI::TEST(WKWebExtensionAPIMenus, MenuItemWithWithNoValidVariants)): Added.
(TestWebKitAPI::TEST(WKWebExtensionAPIMenus, MenuItemWithMixedValidAndInvalidIconVariants)): Added.
(TestWebKitAPI::TEST(WKWebExtensionAPIMenus, MenuItemWithAnySizeVariantAndSVGDataURL)): Added.
(TestWebKitAPI::TEST(WKWebExtensionAPIMenus, UpdateMenuItemWithIconVariants)): Added.
(TestWebKitAPI::TEST(WKWebExtensionAPIMenus, ClearMenuItemIconVariantsWithNull)): Added.
(TestWebKitAPI::TEST(WKWebExtensionAPIMenus, ClearMenuItemIconVariantsWithEmpty)): Added.
xeenon added a commit to xeenon/WebKit that referenced this issue Sep 5, 2024
…or Web Extensions.

https://webkit.org/b/279135
rdar://problem/134885372

Reviewed by NOBODY (OOPS!).

Add support for the `icons_variants` key in `menus.create()` and `menus.update()`.
Also add support for `variants` key in `action.setIcon()`.

Proposal: https://github.com/w3c/webextensions/blob/main/proposals/dark_mode_extension_icons.md
WECG issue: w3c/webextensions#229

* Source/WebKit/Shared/Extensions/WebExtensionMenuItem.serialization.in:
* Source/WebKit/Shared/Extensions/WebExtensionMenuItemParameters.h:
* Source/WebKit/UIProcess/Extensions/Cocoa/API/WebExtensionContextAPIActionCocoa.mm:
(WebKit::WebExtensionContext::actionSetIcon):
* Source/WebKit/UIProcess/Extensions/Cocoa/WebExtensionActionCocoa.mm:
(WebKit::WebExtensionAction::clearCustomizations):
(WebKit::WebExtensionAction::icon):
(WebKit::WebExtensionAction::setIcons):
(WebKit::WebExtensionAction::setIconVariants):
(WebKit::WebExtensionAction::clearIconCache):
(WebKit::WebExtensionAction::setIconsDictionary): Deleted.
* Source/WebKit/UIProcess/Extensions/Cocoa/WebExtensionMenuItemCocoa.mm:
(WebKit::WebExtensionMenuItem::WebExtensionMenuItem):
(WebKit::WebExtensionMenuItem::minimalParameters const):
(WebKit::WebExtensionMenuItem::update):
(WebKit::WebExtensionMenuItem::icon const):
(WebKit::WebExtensionMenuItem::clearIconCache const):
* Source/WebKit/UIProcess/Extensions/WebExtensionAction.h:
* Source/WebKit/UIProcess/Extensions/WebExtensionContext.h:
* Source/WebKit/UIProcess/Extensions/WebExtensionContext.messages.in:
* Source/WebKit/UIProcess/Extensions/WebExtensionMenuItem.h:
* Source/WebKit/WebProcess/Extensions/API/Cocoa/WebExtensionAPIActionCocoa.mm:
(WebKit::WebExtensionAPIAction::isValidDimensionKey):
(WebKit::WebExtensionAPIAction::parseIconPath):
(WebKit::WebExtensionAPIAction::parseIconPathsDictionary):
(WebKit::WebExtensionAPIAction::parseIconImageDataDictionary):
(WebKit::WebExtensionAPIAction::parseIconVariants):
(WebKit::WebExtensionAPIAction::setIcon):
* Source/WebKit/WebProcess/Extensions/API/Cocoa/WebExtensionAPIMenusCocoa.mm:
(WebKit::WebExtensionAPIMenus::parseCreateAndUpdateProperties):
(WebKit::WebExtensionAPIMenus::createMenu):
(WebKit::WebExtensionAPIMenus::update):
* Source/WebKit/WebProcess/Extensions/API/WebExtensionAPIAction.h:
* Source/WebKit/WebProcess/Extensions/API/WebExtensionAPIMenus.h:
* Source/WebKit/WebProcess/Extensions/Bindings/Scripts/CodeGeneratorExtensions.pm:
(_generateImplementationFile):
* Source/WebKit/WebProcess/Extensions/Interfaces/WebExtensionAPIMenus.idl:
* Tools/TestWebKitAPI/Tests/WebKitCocoa/WKWebExtensionAPIAction.mm:
(TestWebKitAPI::TEST(WKWebExtensionAPIAction, SetIconWithDataURL)): Renamed.
(TestWebKitAPI::TEST(WKWebExtensionAPIAction, SetIconWithVariants)): Added.
(TestWebKitAPI::TEST(WKWebExtensionAPIAction, SetIconWithImageDataAndVariants)): Added.
(TestWebKitAPI::TEST(WKWebExtensionAPIAction, SetIconThrowsWithNoValidVariants)): Added.
(TestWebKitAPI::TEST(WKWebExtensionAPIAction, SetIconWithMixedValidAndInvalidVariants)): Added.
(TestWebKitAPI::TEST(WKWebExtensionAPIAction, SetIconWithAnySizeVariantAndSVGDataURL)): Added.
(TestWebKitAPI::TEST(WKWebExtensionAPIAction, SetIconWithSVGDataURL)): Deleted.
* Tools/TestWebKitAPI/Tests/WebKitCocoa/WKWebExtensionAPIMenus.mm:
(TestWebKitAPI::TEST(WKWebExtensionAPIMenus, Errors)): Fixed expectations.
(TestWebKitAPI::TEST(WKWebExtensionAPIMenus, MenuItemWithIconVariants)): Added.
(TestWebKitAPI::TEST(WKWebExtensionAPIMenus, MenuItemWithImageDataVariants)): Added.
(TestWebKitAPI::TEST(WKWebExtensionAPIMenus, MenuItemWithWithNoValidVariants)): Added.
(TestWebKitAPI::TEST(WKWebExtensionAPIMenus, MenuItemWithMixedValidAndInvalidIconVariants)): Added.
(TestWebKitAPI::TEST(WKWebExtensionAPIMenus, MenuItemWithAnySizeVariantAndSVGDataURL)): Added.
(TestWebKitAPI::TEST(WKWebExtensionAPIMenus, UpdateMenuItemWithIconVariants)): Added.
(TestWebKitAPI::TEST(WKWebExtensionAPIMenus, ClearMenuItemIconVariantsWithNull)): Added.
(TestWebKitAPI::TEST(WKWebExtensionAPIMenus, ClearMenuItemIconVariantsWithEmpty)): Added.
webkit-commit-queue pushed a commit to xeenon/WebKit that referenced this issue Sep 5, 2024
…or Web Extensions.

https://webkit.org/b/279135
rdar://problem/134885372

Reviewed by Brian Weinstein.

Add support for the `icons_variants` key in `menus.create()` and `menus.update()`.
Also add support for `variants` key in `action.setIcon()`.

Proposal: https://github.com/w3c/webextensions/blob/main/proposals/dark_mode_extension_icons.md
WECG issue: w3c/webextensions#229

* Source/WebKit/Shared/Extensions/WebExtensionMenuItem.serialization.in:
* Source/WebKit/Shared/Extensions/WebExtensionMenuItemParameters.h:
* Source/WebKit/UIProcess/Extensions/Cocoa/API/WebExtensionContextAPIActionCocoa.mm:
(WebKit::WebExtensionContext::actionSetIcon):
* Source/WebKit/UIProcess/Extensions/Cocoa/WebExtensionActionCocoa.mm:
(WebKit::WebExtensionAction::clearCustomizations):
(WebKit::WebExtensionAction::icon):
(WebKit::WebExtensionAction::setIcons):
(WebKit::WebExtensionAction::setIconVariants):
(WebKit::WebExtensionAction::clearIconCache):
(WebKit::WebExtensionAction::setIconsDictionary): Deleted.
* Source/WebKit/UIProcess/Extensions/Cocoa/WebExtensionMenuItemCocoa.mm:
(WebKit::WebExtensionMenuItem::WebExtensionMenuItem):
(WebKit::WebExtensionMenuItem::minimalParameters const):
(WebKit::WebExtensionMenuItem::update):
(WebKit::WebExtensionMenuItem::icon const):
(WebKit::WebExtensionMenuItem::clearIconCache const):
* Source/WebKit/UIProcess/Extensions/WebExtensionAction.h:
* Source/WebKit/UIProcess/Extensions/WebExtensionContext.h:
* Source/WebKit/UIProcess/Extensions/WebExtensionContext.messages.in:
* Source/WebKit/UIProcess/Extensions/WebExtensionMenuItem.h:
* Source/WebKit/WebProcess/Extensions/API/Cocoa/WebExtensionAPIActionCocoa.mm:
(WebKit::WebExtensionAPIAction::isValidDimensionKey):
(WebKit::WebExtensionAPIAction::parseIconPath):
(WebKit::WebExtensionAPIAction::parseIconPathsDictionary):
(WebKit::WebExtensionAPIAction::parseIconImageDataDictionary):
(WebKit::WebExtensionAPIAction::parseIconVariants):
(WebKit::WebExtensionAPIAction::setIcon):
* Source/WebKit/WebProcess/Extensions/API/Cocoa/WebExtensionAPIMenusCocoa.mm:
(WebKit::WebExtensionAPIMenus::parseCreateAndUpdateProperties):
(WebKit::WebExtensionAPIMenus::createMenu):
(WebKit::WebExtensionAPIMenus::update):
* Source/WebKit/WebProcess/Extensions/API/WebExtensionAPIAction.h:
* Source/WebKit/WebProcess/Extensions/API/WebExtensionAPIMenus.h:
* Source/WebKit/WebProcess/Extensions/Bindings/Scripts/CodeGeneratorExtensions.pm:
(_generateImplementationFile):
* Source/WebKit/WebProcess/Extensions/Interfaces/WebExtensionAPIMenus.idl:
* Tools/TestWebKitAPI/Tests/WebKitCocoa/WKWebExtensionAPIAction.mm:
(TestWebKitAPI::TEST(WKWebExtensionAPIAction, SetIconWithDataURL)): Renamed.
(TestWebKitAPI::TEST(WKWebExtensionAPIAction, SetIconWithVariants)): Added.
(TestWebKitAPI::TEST(WKWebExtensionAPIAction, SetIconWithImageDataAndVariants)): Added.
(TestWebKitAPI::TEST(WKWebExtensionAPIAction, SetIconThrowsWithNoValidVariants)): Added.
(TestWebKitAPI::TEST(WKWebExtensionAPIAction, SetIconWithMixedValidAndInvalidVariants)): Added.
(TestWebKitAPI::TEST(WKWebExtensionAPIAction, SetIconWithAnySizeVariantAndSVGDataURL)): Added.
(TestWebKitAPI::TEST(WKWebExtensionAPIAction, SetIconWithSVGDataURL)): Deleted.
* Tools/TestWebKitAPI/Tests/WebKitCocoa/WKWebExtensionAPIMenus.mm:
(TestWebKitAPI::TEST(WKWebExtensionAPIMenus, Errors)): Fixed expectations.
(TestWebKitAPI::TEST(WKWebExtensionAPIMenus, MenuItemWithIconVariants)): Added.
(TestWebKitAPI::TEST(WKWebExtensionAPIMenus, MenuItemWithImageDataVariants)): Added.
(TestWebKitAPI::TEST(WKWebExtensionAPIMenus, MenuItemWithWithNoValidVariants)): Added.
(TestWebKitAPI::TEST(WKWebExtensionAPIMenus, MenuItemWithMixedValidAndInvalidIconVariants)): Added.
(TestWebKitAPI::TEST(WKWebExtensionAPIMenus, MenuItemWithAnySizeVariantAndSVGDataURL)): Added.
(TestWebKitAPI::TEST(WKWebExtensionAPIMenus, UpdateMenuItemWithIconVariants)): Added.
(TestWebKitAPI::TEST(WKWebExtensionAPIMenus, ClearMenuItemIconVariantsWithNull)): Added.
(TestWebKitAPI::TEST(WKWebExtensionAPIMenus, ClearMenuItemIconVariantsWithEmpty)): Added.

Canonical link: https://commits.webkit.org/283219@main
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Enhancement or change to an existing feature implemented: safari Implemented in Safari supportive: chrome Supportive from Chrome supportive: firefox Supportive from Firefox
Projects
None yet
Development

No branches or pull requests