diff --git a/_minutes/2024-09-23-wecg-tpac.md b/_minutes/2024-09-23-wecg-tpac.md new file mode 100644 index 00000000..2c083479 --- /dev/null +++ b/_minutes/2024-09-23-wecg-tpac.md @@ -0,0 +1,305 @@ +# WECG TPAC Sep 23, 2024 + + +## Agenda + +Monday: https://github.com/w3c/webextensions/wiki/TPAC-2024-Coordination#monday + + * 09:00 - 10:30 + * [15 min] Kickoff - Review the week's agenda & format + * Welcome from Simeon Vincent + * [15 min] Topic discussion + * [30 min] Native messaging + * [30 min] postMessage() replacement + * Related issues: ([#77](https://github.com/w3c/webextensions/issues/77), [#78](https://github.com/w3c/webextensions/issues/78)) + * 11:00 - 12:30 + * [30 min] Internationalization + * [30 min] API development, rollout, and launching + * [30 min] dom.executeScript discussion continued + + +## Attendees + + * Oliver Dunk (Google Chrome) + * David Johnson (Apple) + * Simeon Vincent (Mozilla) + * Rob Wu (Mozilla) + * Kiara Rose (Apple) + * Brian Weinstein (Apple) + * Elijah Sawyers (Apple) + * Devlin Cronin (Google Chrome) + * George Henderson (Capital One) + * Carlos Jeurissen (Jeurissen Apps) + * Timothy Hatcher (Apple) + * Mukul Purohit (Microsoft) + * Casey Garland (Capital One) + * Jordan Spivack (Capital One) + * Christos Bacharakis (Eyeo) + * Matt Gibson (Bitwarden) + + +## Notes + + +### Kickoff + + * [simeon] See wiki for upcoming agenda and topics: https://github.com/w3c/webextensions/wiki/TPAC-2024-Coordination + * [simeon] Wednesday has breakout sessions from other W3C groups; if they seem interesting, please add it to the wiki. + * [simeon] FYI we have a chat channel at https://chat.mozilla.org/#/room/#wecg:mozilla.org + + +### Topic discussion + + * [simeon] Any suggested changes to the agenda? + * (silent) + * [devlin] I note that some of the 30 minute topics would probably take longer than 30 minutes; Otherwise we would have addressed them before. + + +### Native messaging + + * [timothy] This has come recently; in Firefox and Chrome nativeMessaging is stdin/stdout-based. We have recently seen research showing that this design is unsafe against attacks that replace binaries. At Apple we try to safeguard against local malware. Our internal team that develops the iCloud Password extension for Chrome is looking hard at this. Are there areas where we can improve this? + * [rob] FYI some recent reports about nativeMessaging being unsafe against local malware: + * https://bugzilla.mozilla.org/show_bug.cgi?id=1892797 + * https://blog.1password.com/august-2024-security-update/ + * https://crbug.com/334764458 + * [devlin] Are there cross-platform or platform-specific mechanisms to verify the application, e.g. a hash of an application binary? Also interested in using web tech for this use case. E.g. if it is feasible to use https. + * [timothy] Could be a decent approach. In Safari we use platform APIs for native messaging that are safeguarded by code signatures of the binary. + * [oliver] How to ensure that the binary that is launched is the expected binary; also other way around, how can the binary verify that the launcher is the expected browser. + * [carlos] Do browsers currently do any hash verification of installed extension files? + * [devlin] We verify the integrity of packaged extensions and re-download the original package if needed; cannot defend against patched Chrome. + * [oliver] You can also arbitrarily set the ID of an unpacked extension, which allows you to communicate with the application even with an unpatched browser. + * [simeon] There are increasingly multiple browsers; possibly concerning if usage requires signature by e.g. Google. + * [oliver] Does not have to be just Firefox and Chrome. Native applications could have an allowlist of binaries that can communicate with it customizable by the user. + * [simeon] Signature verification could extend to the certificate bundled with the native app. May help verify a self-signed local certificate or a cert bundled with the application. + * [devlin] I don't know which tools are publicly available for verifying third-party applications via the OS. + * [oliver] E.g. in Chrome the update process breaks the signature of the Chrome binary. + * [oliver] What is available at Safari? + * [timothy] I don't know. + * [devlin] What does 1Password use? + * [oliver] They use signature APIs; if the signature cannot be verified the user is prompted to restart the browser. + * [Matt] Mac supports a way to verify the other end of the pipe. + * [simeon] Mukul, could you look into the signing capabilities on Windows? + * [mukul] I can get clarity on that aspect. + * [rob] Could survey developers to see what capabilities they're using to verify the exchange of native messaging exchange, and see if this is something we can offer as a cross-platform API. + * [simeon] I'm not aware of extensions that do this. + * [devlin] Do extensions encrypt the traffic over the channel? + * [Matt] We do. + * [simeon] Could you show a small document or video showing the flow, so we can get a better picture of what the experience is like? + * [Matt] Sure. + * Created https://github.com/w3c/webextensions/issues/706 + * [devlin] Also question on native messaging API. Whether the current stdin/stdout format is sufficient or whether leveraging web APIs (enabling fetch(), headers, etc) would be preferable. + * [oliver] Establishing a native message connection is unreliable. Checking permissions, file locations, etc. Hard to know if when I call sendNativeMessage() it will work. Once working, data transfer is usually fine. + * [casey] We rely on it on iOS. + * [timothy] 20% of extensions in Safari use it. It is made easy, the native messaging component is bundled with the native apps. + * [simeon] Could well known URLs be used? Android / iOS use some well-known formats. + * [carlos] That is called asset links. + * [simeon] And whether this can be built upon to establish the handshake. + * [jon] The reliability of doing this in the manifests may be shaky. + * [simeon] Was not thinking of the native messaging manifest, but a source of truth e.g. when the extension is installed from the extension store or app from an app store. Has implications about offline behavior. + * [oliver] Rob shared some links before, 1Password for example has proposed some improvement there. + * [devlin] Safari can do lots of magic, is there something that Chrome can do too? + * [devlin] Is there interest in leaning more on web tech for native messaging use cases? + * [rob] Don't expect that it would help here - local applications can always forge any agreed-upon request details. A local server with a HTTP-based API is something that extension developers can already implement. + * [carlos] Can a native application verify an extension came from a given store? + * [devlin] Potentially. We have that information in Chrome. Not sure what it would look like. Hesitant about putting more information in the native messaging manifest. Also worried about tying verification to the distribution channel – don't want to negatively impact 3rd party browsers. + +Action Items: + + * [oliver] Look into 1Password's research and any possible solutions + * [mukul] Look into verification options on Windows + * [timothy] Look at options for Chrome to verify applications on macOS + * This can be done with the `SecCodeCheckValidity`, `SecCodeValidateFileResource`, and SecCodeCopySigningInformation from the Security framework. + * https://developer.apple.com/documentation/security/defining-launch-environment-and-library-constraints?language=objc + * [simeon] Schedule follow-up discussion for later this week + * (editorial note by Rob: this topic was not discussed further this week) + + +### postMessage() replacement + + * Related issues: ([#77](https://github.com/w3c/webextensions/issues/77), [#78](https://github.com/w3c/webextensions/issues/78)) + * [timothy] Extensions are often exploited because they use postMessage to listen to any broadcast and realize that the page can also do that. Security researchers often find vulnerabilities in extensions that do this. + * E.g. https://spaceraccoon.dev/universal-code-execution-browser-extensions/ + * [timothy] Devlin has created proposals based on previous discussions + * https://github.com/w3c/webextensions/pull/678 + * https://github.com/w3c/webextensions/pull/679 + * [devlin] dom.execute() allows synchronous communication across worlds, dom.createPort() would create a port that enables this script to communicate. These APIs were designed in the earlier San Diego meetup. Rob and Carlos have already provided some feedback on these topics. + * San Diego meeting minutes: [2024-03-20-san-diego-meetup.md](https://github.com/w3c/webextensions/blob/main/_minutes/2024-03-20-san-diego-meetup.md#user-scripts) + * [devlin] The idea is that in the content script world there is a way to create a port, set up a handler, execute code in the main world that receives the port and can communicate back with the content script. + * [devlin] Would this address the concerns, Timothy? + * [timothy] I think so. Current issue is that postMessage can broadcast and the web page can eavesdrop and intercept. This approach means that only the content script has access to that port. + * [george] Is this independent of externally_connectable? + * [devlin] This is about communication between the content script and a script in the main world in the web page. Sometimes you need to have some state from the main world in your content script. You can do this currently by abusing postMessage. + * [george] Could we allow you to use a chrome-extension:// URL in the postMessage APIs? + * [devlin] A malicious main world could also set this, so it doesn't solve as many problems as the proposals here do. + * [carlos] Is cross-frame communication out of scope here? We might still want to communicate between a content script and a host and an iframe within that host. + * [devlin] I think so. + * [rob] If there is a generic way to send values, one can also send instances of MessagePort/MessageChannel from the web platform to establish communication. + * [devlin] If you want to communicate between a content script and a trusted extension context, can you just use runtime.sendMessage? + * [carlos] You would need to check the message came from the right frame. + * [devlin] This is solvable by looking at the sender. + * [rob] Don't think this alone would solve the issues with postMessage. If you can call methods, the page can intercept it via the prototype chain. Are there more guarantees we should offer? + * [rob] The root cause of the described issues is not just postMessage, but that there are currently no guarantees for some minimal execution behavior in the main world. Should we expose some? + * [devlin] Do you have examples? + * [rob] In Chrome internally, $Array, $Object, etc. (built-ins, e.g. [safe_builtins.h in Chromium](https://source.chromium.org/chromium/chromium/src/+/main:extensions/renderer/safe_builtins.h;drc=f473c24b5ec27bd02930650b51dbb1004be7ba5b)) + * [devlin] Like safe builtins? I can see the utility. That would be something we could potentially do, I'm not sure what form this would take. We could have a way to pass in types when creating the port. + * [devlin] Could see doing this via a flag and on the receiving end bind to the original prototypes. + * [rob] Firefox has the X-Ray system, I'm not sure if Chrome has something similar. + * [rob] You could pass a DOM element from the content script world to the main world. + * [devlin] We discussed this in San Diego. We decided to hold off since passing DOM elements is weird. + * [rob] DOM elements are a specific instance of the generic issue of the need to be able to pass by reference rather than a copy. + * [devlin] For DOM elements, there's enough ways to find an element. + * [rob] This can be interfered with by the web page. DuckDuckGo has asked for this functionality in the past ([issue 284](https://github.com/w3c/webextensions/issues/284)). Anyone here with use cases? + * [george] We have UI we inject into the page. This sounds similar to concerns we have there. + * [oliver] Related concern: if you want to provide or override an API to the main world. Might be nice if you could expose an API in the main world, pass data to the isolated world for execution, and pass the result back to the isolated world. + * [devlin] We wouldn't be able to pass direct references to a value from another world, which would limit the utility of this. + * [oliver] Maybe calling with a copy would be enough? + * [devlin] Would break for anything that works on a reference vs. a value. + * [carlos] I have an extension that does some scripting in the main world before other content is loaded. + * [rob] What limitations do you have? + * [carlos] Since mv3 injected script must conform to main page's CSP and not be inline. + * [rob] Should be addressed by dom.execute() + * [rob] I have an extension which rewrites URLs on google.com. It does this by intercepting the href getter of the HTML element. Needs to run in main world. To prevent extension from breaking Google, extension needs to only hook where appropriate, Oliver's proposal could help. Allow me to act as middleware and decide if we should modify value, return something different etc. + * [devlin] In Chrome, that kind of back and forth between contexts would not go well. + * [rob] Need some guarantees for referencing the unmodified prototypes. + * [devlin] Could this be solved if you inject a script to save all the builtins before any other script runs, and expose them as a frozen object? + * [rob] Yes, user script managers do this. The problem is that there is no guarantee it runs before any other script. + * [devlin] There would be with dom.execute(). + * [rob] What guarantees the content script always runs first? + * [devlin] I think that's orthogonal. One way to guarantee: document.write in an iframe. + * [rob] That's Chrome-specific. In Firefox there are also some cases where it is possible for document_start scripts to not run before other code starts executing. + * [devlin] In general we consider those bugs. Document_start should run before anything else. That's the point. + * [rob] Your recommendation is to use document_start to save references. + * [devlin] Yes. In practice, safe builtins are visible to the page. + * [Matt] To support FIDO2 and WebAuthN, we need to override default globals for the relevant methods. Our preference would be to declare that we want to participate in that flow and have the browser facilitate that. + * [timothy] I agree, specifically in passkeys we should offer an API for passkey providers. + * [oliver] From the extension perspective I am supportive. But when discussed before with passkey devs, there was much hesitation. E.g. they preferred OS-level integration over extensions. + * [george] Another use case (Capital One shopping), we inject a node in the DOM & we want to prevent modifications to it or removal of it. + * [timothy] Having a protected way to draw over the page might be good, but using popup or sidebar may be the most trusted solution. + * [george] That may be best for a browser, but it's a suboptimal user experience. + * [devlin] We've talked about declarative badging in the past, where the browser would mediate a piece of extension UI in the page. + * [george] That's also very important for in-page permission requests. + * [Matt] Can also mediate injection of additional, unnecessary content in the page. + * [oliver] Would there be interest in a session for this. Declarative badging. Access to another layer on the page. There was hesitation to this in the past. + * [devlin] Still hesitant. Don't know if anyone is willing to experiment on and drive this effort. + * [rob] What is declarative badging? Something different to declarativeContent + action.ShowAction? + * [devlin] Conceptually similar to declarativeContent in that you can specify selectors, but also URL patterns, assets, etc that enable the browser to display in the page. Without requiring host permissions. + * [timothy] We'd be interested in that. Safari's permission model tries to mostly not require host permissions. + * [devlin] Are there any action items? + * [oliver] Re dom.execute, would like to discuss `world` and `worldId` params. + * [oliver] Whether we can convince extensions to use the new mechanisms instead of insecure postMessage methods. + * [timothy] Many extensions also use CustomEvent. + * (dom.execute discussion continues later today) + +Action items + + * [simeon] Schedule time to discuss exposing extension UI in page that doesn't require injecting into the host document. + * (editorial note by Rob: this topic was not discussed further this week) + + +### Internationalization + + * [carlos] Listed some at https://github.com/w3c/webextensions/issues/659#issuecomment-2362976001 + +[Issue 569](https://github.com/w3c/webextensions/pull/569): Proposal: i18n-system-languages + + * [carlos] proposal for i18n.getPreferredSystemLanguages & i18n.getSystemUILanguage + * [simeon] Any open concerns? + * [rob] Could the result of this API be passed to the Intl APIs from the web platform? E.g. Intl.DateTimeFormatter + * [carlos] The values from this API could be passed to these APIs. + * [rob] The doc lists “Sponsoring browser: TBD”. Our proposal process requires at least one sponsor. + * [oliver] Timothy said that Safari would be willing to sponsor it. + * [kiara] Confirms. + * [oliver] Don't seem to be any open concerns left. + * [rob] So next step here is to update the sponsoring browser and then update it . + * [oliver] Addison left [feedback](https://github.com/w3c/webextensions/pull/569#pullrequestreview-2118488618) on the PR, I'll ping him to see if he believes that the concerns have sufficiently been addressed. + +[Issue 274](https://github.com/w3c/webextensions/issues/274): Proposal: i18n.getLanguageDictionary + + * [oliver] Devlin left some feedback at https://github.com/w3c/webextensions/issues/274#issuecomment-2197270387 + * [oliver] Chrome preference was proposal C. + * [rob] If we implemented this, we would likely make it asynchronous. + * [oliver] Seems that nobody is excited about an asynchronous version of proposal C. + * [oliver] In that case, the other proposals Chrome is supportive of are proposal B and proposal E. + * [carlos] Having an asynchronous initialization could speed up any extension. e.g a browser.i18n.getLanguageDictionary() which returns a Promise and works without any parameters for a default. This would likely be a change for a future manifest version though. + * [rob] Do we have examples of extensions that need this functionality, e.g. in the form of parsing localization files and doing something specific with this? + * [simeon] I think fregante had an extension which does this. + * [rob] Extensions would need logic to fallback to other locales if they implemented this functionality themselves. + * [carlos] Other browsers fall back to multiple; Firefox is the only one that has one fallback. (see [issue 296](https://github.com/w3c/webextensions/issues/296)) + * [rob] (added post meeting in a different meeting, with I18n group) After discussions, Firefox is supportive of also implementing multiple fallbacks: https://github.com/w3c/webextensions/issues/296#issuecomment-2369812944 + + +### API development, rollout, and launching + + * [devlin] Wanted to chat about how we rollout APIs. Typically we restrict an API to certain channels or behind a flag, don't get much feedback unfortunately and then roll out the API more widely. APIs being limited to Canary makes it hard for developers to test with their users. + * [devlin] Do other browser vendors have an appetite for solving this problem? + * [rob] Would be useful, definitely. Thinking about it another way, if a developer wants to use an experimental feature, they will need a way to detect if the feature is exposed and supported. I think this is critical for extensions to adopt new API. + * [patrick] As background, I was a lead dev for modernizr, a feature testing library. The open web solves this problem with origin trials. On the open web, websites can add a meta tag to their page to enable an API. This uses a key which developers can only get once they agree that the API may go away. The API will work across all channels but there is no expectation it will last forever. Chrome recently landed token support in extensions in Stable. + * [devlin] Origin trials are a strong possibility here. Often covers functionality without alternatives. + * [patrick] Origin trials solve the real-world feedback use case, not the developer feedback session. + * [george] Can chrome.experimental be used for this? + * [devlin] There is another session on that this week; Short version is that there is a lot of baggage with chrome.experimental that we don't use. + * [brian] Are there concerns about dataloss, e.g. if an experimental data storage API is removed. + * [patrick] Yes, the origin trial is associated with a specific user. If the trial is revoked or removed then the user may go back to the old case. This is why we have to communicate that the origin trial may go away. + * [oliver] We're discussing origin trials - are there other options we should discuss? + * [devlin] Is there appetite from developers for being able to experiment with APIs with a portion of the population? + * [george] Yes, if you control the size of the population / stability of the population. + * [oliver] Does any developer want anything less than 100%? + * [george] We don't feel strongly here. + * [oliver] Devlin, do you want anything less than 100%? + * [devlin] Would lean towards 100% rollout, the main value of an origin trial is explicit agreement that this is not released. + * [david] Does Chrome require feedback / check-ins from developers? + * [patrick] No. + * [carlos] It would be valuable to be able to tell if an origin trial is active. Could also be API behavior changes that are not obvious from feature detection. + * [simeon] Example of flow for origin trial flow, from a developer point of few. Register, fill in extension URL/ID. Consent to the policies and then you get an origin trial. https://developer.chrome.com/origintrials/#/register_trial/1049901663130746881 + * [carlos] A method to query whether a specific origin trial string would be active. + * [matt] The only way that we would use this is we can convince 100% of the users to opt in to functionality. + * [timothy] Devs can always choose to use just the old or the new one. + * [rob] I imagine that if there are new capabilities associated with it, that developers are more willing to go through the effort, whereas just a “different” way to do this would not get much traction. + * [devlin] Any alternative options? I don't have ideas. + * [carlos] Developers could also opt in via the manifest file, without origin trials. As the issue of origin verification does not exist for extensions. + * [simeon] 100% availability may result in the assumption on the developer's part that the feature is fully available. + * [rob] What was the response to whether we need origin trials? + * [devlin] I think Carlos raises a good point that if we are looking at 100% rollout, having something in the manifest that doesn't use the origin trial system may be valuable. + * [rob] Could also not require origin trials, but allow developers to sign up / register extensions so we can contact them about updates to the trial. Those could have breaking releases. + * [patrick] Chrome's origin trials do normally send updates. + * [oliver] Prior art, Cloudflare has “compatibility” flags. All breaking changes are behind compatibility flags. https://developers.cloudflare.com/workers/configuration/compatibility-dates/#setting-compatibility-flags + * [devlin] Do other browsers support origin trials? + * [rob] Firefox has an implementation, but it is not widely used. + * [patrick] One negative that wasn't mentioned is that origin trials require code to reach stable. + * [devlin] Right, if we experimented for 1 month that would put us 3 months behind HEAD. + * [george] We'd be especially interested in testing things that improve existing API. Testing new things would be a larger ask. + +Action Items: + + * [devlin] File issue and write proposal. + + +### dom.execute discussion continued + + * Carry overs: + * [devlin] Discuss how to pass DOM elements between worlds. + * [oliver] Re dom.createPort, would like to discuss `world` and `worldId` params on createPort(). + * [oliver] Would also like to discuss ways we can discourage postMessage usage. + * [oliver] Re dom.createPort, would like to discuss `world` and `worldId` params on createPort(). + * [oliver] The proposal tries to force a 1:1 communication, this proposal forces that by requiring the worldId to be specified. I lean towards not having the properties, and throw an error when the port is sent again. + * [timothy] I'm also in favor of not adding it. + * [rob] Same. + * [devlin] I was thinking that forcing it would make it easier from the implementation POV, and communicate the expectations to developers. Not thinking that this would be hugely important. I'm fine with dropping it. + * [rob] For prior art, the web platform has the MessageChannel() constructor consisting of two MessagePort instances. A port can be sent only once, any further attempt raises an error. Would you prefer to have special serialization of the port or use another approach to get the port to the other world? + * [devlin] Treating the value specially is my preference. + * [rob] Makes sense. + * [devlin] Discuss how to pass DOM elements between worlds. + * [devlin] On the Chrome side there would not be support for passing DOM elements as JS references across worlds. Rob's point about the need to pass a handle, and that querySelector can be manipulated by the main world. + * [rob] This is only a problem if you need secrecy. Extensions can currently create an iframe in a closed shadow dom to get a secure reference to the iframe's global to get a reference to unmodified global prototypes. + * [] puppeteer/Playwright use case. Right now it does not play nice with elements in shadow DOM for that reason. + * [oliver] Could you speak to the concerns around special serialization for DOM elements? + * [devlin] Implementation complexity. Want to avoid special serialization that isn't directly related to the API. + * [oliver] From an API perspective it seems quite intuitive. Having to set an id and retrieve it back seems not. + * [timothy] I am in favor of passing a DOM element resolving to the JS wrapper on the DOM element. + * [rob] I don't think that's too different from existing wrapping behavior. + * [devlin] Tricky in chromium because we don't have access to the blink layer in the message handler. + * [rob] If implementation complexity is a concern, we could limit support for it to the top-level elements in the args array (to dom.execute) only. Setting a DOM element as a value in an object in the args array would throw (due to structuredClone not supporting DOM elements). + * [devlin] Could something where we have top level handling: if it's a port do X, if it's an element do Y, if it's an object structured clone. + * [oliver] Would we accept different behaviors across browsers? + * [devlin] Not ideal. If there is a hard technical limitation in Chrome I would not block it in other browsers. + * [rob] And extensions can feature-detect it by detecting thrown errors from being unable to structurally clone a value. diff --git a/_minutes/2024-09-24-wecg-tpac.md b/_minutes/2024-09-24-wecg-tpac.md new file mode 100644 index 00000000..b79a7619 --- /dev/null +++ b/_minutes/2024-09-24-wecg-tpac.md @@ -0,0 +1,464 @@ +# WECG TPAC Sep 24, 2024 + + +## Agenda + +Tuesday: https://github.com/w3c/webextensions/wiki/TPAC-2024-Coordination#tuesday + + * 09:00 - 10:30 + * [5 min] Agenda review + * [45 min] Experimental APIs + * [55 min] Community prioritization of medium-scoped features we've all agreed are reasonable (Oliver) + * 11:00 - 12:30 + * [90 min] Leads sync (closed session) + * 14:00 - 15:00 + * (original agenda canceled due to power outage) + * 15:00 - 17:00 + * [120 min] Issue triage & backlog cleanup + + +## Attendees + + * Rob Wu (Mozilla) + * Christos Bacharakis (Eyeo) + * Timothy Hatcher (Apple) + * Kiara Rose (Apple) + * David Johnson (Apple) + * Elijah Sawyers (Apple) + * Brian Weinstein (Apple) + * Simeon Vincent (Mozilla) + * Mukul Purohit (Microsoft) + * Devlin Cronin (Google) + * Carlos Jeurissen (Jeurissen Apps) + * Oliver Dunk (Google) + * Patrick Kettner (Google) + * Jordan Spivack (Capital One) + * Casey Garland (Capital One) + * George Henderson (Capital One) + * Tomislav Jovanovic (Mozilla) + + +## Notes + + +### Session intro + + * [oliver] Yesterday we met with the Internationalization group, about i18n.getPreferredSystemLanguages and others. If the API name has user preferences in it, we should return the user preferences and not the default. Also talked about MessageFormat2. They are going to join us on Thursday. + * [rob] FYI I met with James Graham from the Browser Tools and Testing group, because there is a PR about adding installation of extensions to WebDriver-bidi at https://github.com/w3c/webdriver-bidi/pull/778. We'll meet with them on Thursday. + * (added later) Meeting minutes of Thursday's meeting between the WECG and BTT: https://www.w3.org/2024/09/26-webdriver-minutes.html#t14 + + +### Experimental APIs + + * [devlin] Recap of experimental APIs. experimental namespace in Chrome has baggage, prefer not using it. How to introduce experimental APIs without avoiding namespace conflicts in the future? Options include namespacing, suffixing APIs (e.g. Private suffix in Chrome). + * [timothy] Are these on by default in shipping? + * [devlin] Depends on definition in shipping. + * [timothy] Enabled by default in Canary. + * [devlin] Recent example, e.g. prompt AI, which they would like to eventually be exposed on the web. But they want to prototype as an extension API first and remove later. How to do this without long-lasting impact on extensions? Currently has a long name I can't recall. Another example is experimental AI data API. Intended to be used by anyone, but currently requires a CLI flag. + * [timothy] All experimental features in Safari/WebKit have experimental flags, mostly disabled by default. Having a way to toggle them is a go-to, not name prefixes. + * [devlin] (...) AI data API example not enabled by default in production. Prompt AI expected to need a different toggle, for use in extensions. Having a toggle does not preclude collisions. Segmentation here is valuable here. + * [timothy] What about underscore prefixes? + * [devlin] Typically used for internal / reserved use. + * [simeon] What if extensions can input their custom name, for the API/namespace? + * [devlin] Biggest issue is requiring a CLI flag. + * [simeon] Thinking of about:config in Firefox for example. + * [devlin] Would not work for all extensions. + * [devlin] Personal preference right now is a new namespace, but differently than “experimental”. + * [patrick] e.g. chrome.temporary. + * [devlin] E.g. “chrome.donotusethis”. Name to discourage usage and emphasize that it may be temporary. + * [patrick] If the goal is to discourage people from using it, the name should be verbose and clear, e.g. chrome.experimentalThisWillGoAwaySoon. + * [simeon] browser.THIS_IS_EXPERIMENTAL. + * [timothy] E.g. “unsafe” or something like that. + * [devlin] Long and verbose sounds good, but some of them would probably not go away. Internally the Chromium code base sometimes include “DoNotUse” suffix to deprecate/discourage, but there may still be valid remaining use cases. + * [patrick] Maybe names like chrome.thisWillGoAwayBySomeDate + * [devlin] Could incorporate the second bucket into the API namespace. + * [jordan] How about “unstable”? + * [devlin] Good candidate. Exact name does not matter. Can bikeshed async. + * [devlin] Do we want to use the separate bucket idea for this? + * [simeon] And this is independent of yesterday's discussion on origin trials, right? + * [devlin] Yes, yesterday is about APIs that we do not have the intention of breaking, this is about APIs that we do not want to ship to stable. + * [rob] To clarify, this is for features that we don't want to ship to stable? + * [devlin] Not mainline, may still reach stable release channel. + * [rob] What would be the extension store policy for accepting these? + * [devlin] Store decision per API. There may be some that we want to expose publicly. That's part of why we can't use experimental – the experimental permission is auto-rejected. + * [rob] When I asked my team about names, “trials” was one of the suggestions for the namespace. It is not verbose though. + * [devlin] And may be confused with origin trials. I prefer alternatives such as “unstable”, “exploratory”. + * [devlin] Tentative decision: use a namespace (name to be selected) for experimental APIs. I'll take the action item to write this up. + * [devlin] Would other browsers expect adoption? + * [timothy] Yes, would be useful. + * [rob] Yes. + * [devlin] To what extent do we want to raise these in the WECG? On Chrome's side it may be a FYI. + * [timothy] Heads-up would be good. E.g. “Do you have plans for names in this road”, to avoid sidebar/sidepanel issue. + * [david] Since we are thinking of this as likely not conflicting, do we want to think this as reserving a namespace where each browser can do something on their own? + * [devlin] That's what it will likely end up being. Hopeful we won't collide, but should communicate to devs that if it happens it doesn't necessarily mean anything. + * [simeon] A challenge there is that there is no reliable way to distinguish browsers. + * [devlin] Almost no developer should be using this API unless they really want to use this API. Separately, I appreciate the challenge of identifying the browser, we should discuss how to address it later. + * [carlos] Reliable way is to check the protocol of the origin (chrome-extension, moz-extension, etc.) + * [oliver] Even more so, between browser engines we should give heads-up. E.g. no two Chromium forks with the same name. + * [devlin] My stance is that if extension developers are using these APIs, they should exactly know what they are doing. It should target specific browsers. + * [patrick] The idea is that these APIs would not be added to main extensions. + * [rob] As an extension developer, I often look for a way to accomplish my goal and will use whatever API is available to accomplish it. + * [devlin] If you're truly determined and your users are truly determined, then you can do it, but if that doesn't work in a fork I have limited sympathy. + * [simeon] I am not convinced; are you saying that a large extension with large user bases should fork their main code base into a separate extension to use such APIs? + * [devlin] … For example, with the experimental AI API we are planning to fully remove it. + * [rob] Would you consider timebombs in API? Auto-disable a namespace after a certain date, and require extensions to put the expected time in the manifest. + * [devlin] Could be considered on a per-API basis. + * [rob] Recap? + * [devlin] Seems we're aligned on browser.<SOMETHING> (namespace to be decided). (…) + * [rob] What prevents APIs added to this namespace from becoming de facto required to be implemented in other browsers, due to Chrome's market share? + * [devlin] Main thing is that anything requires some form of toggle, to prevent use by arbitrary extensions. + * [timothy] Goes with notifying other browsers of experimental APIs. Gives a chance for us to call out conflicting names/plans. + +Action items + + * [devlin] Propose concrete naming, attributes of new namespace bucket, process for new things getting added, and create an issue (first) + * [rob] I created: [Issue 702](https://github.com/w3c/webextensions/issues/702): Namespace for experimental APIs + + +### Community prioritization of medium-scoped features we've all agreed are reasonable + + * [oliver] Conversations in Chrome, about medium-priority feature requests, that we think would be useful to do, but no time to implement yet. E.g. runtime.onEnabled, userScripts.execute. We have an internal list, but it may not match an external list. Idea is to get a separate list. E.g. we could spend time on listing issues today and discuss which to focus on. + * [oliver] Perhaps we can search for supportive:chrome supportive:safari supportive:firefox in our Github issues? + * [timothy] That would exclude implemented:safari labels. + * [rob] OR is supported with commas, e.g. label:”supportive: chrome”,”implemented: chrome” + * [simeon] https://github.com/w3c/webextensions/issues?q=is%3Aopen+is%3Aissue+label%3A%22supportive%3A+chrome%22%2C%22implemented%3A+chrome%22+label%3A%22supportive%3A+safari%22%2C%22implemented%3A+safari%22+label%3A%22supportive%3A+firefox%22%2C%22implemented%3A+firefox%22+ + * is:open is:issue label:"supportive: chrome","implemented: chrome" label:"supportive: safari","implemented: safari" label:"supportive: firefox","implemented: firefox" + * [oliver] I added a “Community Interest” section to this document; interested extension developers could provide suggestions here. 10 minutes. + * [timothy] Maybe anything implemented in one to implement in another? + * [devlin] I don't think that you mean that. + * [timothy] Things like storage.getAllKeys() + * [devlin] Would be an attribute that adds value, but not automatic. + * [rob] browser namespace is not in the query output, but I think that it is one area that Chrome could work on for cross-browser. https://github.com/w3c/webextensions/issues/532 + * [rob] Historically we have not been good to close issues. Since [#369](https://github.com/w3c/webextensions/issues/369) (extensions' ability to block requests from other extensions in DNR) is universally implemented, I suppose that we can close this now? + * [devlin] Yes. + * [timothy] Yes. + * _(everyone collects issues)_ + * [oliver] Everyone votes on three topics, below. + * _(discussion notes included in the list below)_ + * [oliver] I'll make sure that everything on this list is also represented internally. + + +#### Candidates + + * icon_variants (for Chrome, Firefox?) [#229](https://github.com/w3c/webextensions/issues/229) + * Capital One (Casey) + * Oliver Dunk + * Proposal: Decode regexFilter matches in Declarative Net Request as query parameters [#636](https://github.com/w3c/webextensions/issues/636) + * User Scripts toggle in chrome://extensions instead of developer mode requirement + * TL;DR: Instead of requiring developer mode, we could introduce a per-extension toggle in the "details" page for the extension, similar to "allow on file URLs" and "allow incognito" + * [rob] Who put this here? Do we have an issue tracking this? + * [devlin] Me, no issue yet; in response to developer feedback in the mailing list + * **runtime.onEnabled / runtime.onExtensionLoaded [#353](https://github.com/w3c/webextensions/issues/353)** + * **Votes** + * Sim + * Capital One (Casey) + * Mukule + * Christos + * Notes + * [simeon] There is currently no way to do this. + * [rob] In my extensions I use the storage.session API for this - read storage.session, run (async) initialization logic, save flag. + * Use match_origin_as_fallback by default for scripting.executeScript [#673](https://github.com/w3c/webextensions/issues/673) + * Kiara + * Support Promise as return value from runtime.onMessage callback [#338](https://github.com/w3c/webextensions/issues/338) + * Oliver Dunk + * Capital One (Jordan) + * Proposal: Add alias for tabs permission [#619](https://github.com/w3c/webextensions/issues/619) + * Proposal: StorageArea.getAllKeys() [#517](https://github.com/w3c/webextensions/issues/517) + * Christos + * **sidePanel API: sidePanel.close() and sidePanel.toggle() [#521](https://github.com/w3c/webextensions/issues/521)** + * **Votes** + * Capital One + * Simeon + * Christos + * Mukul + * Notes + * [oliver] window.close() can close it. + * [simeon] Not in Firefox. + * [devlin] Sounds like a bug in Firefox, would you be willing to fix it? + * [rob] Yes. + * [rob] Filed https://bugzilla.mozilla.org/show_bug.cgi?id=1921631. + * Extensions API to query the current browser theme [#680](https://github.com/w3c/webextensions/issues/680) + * [devlin note] May not be straightforward + * Determine the nuances of aliasing chrome and browser [#532](https://github.com/w3c/webextensions/issues/532) + * Oliver Dunk + * Rob Wu + * Capital One (Jordan) + * Inconsistency: Persistence of alarms in browser.alarms API [#406](https://github.com/w3c/webextensions/issues/406) + * Capital One + * Rob Wu + * Add API to switch focus from sidePanel to main document to enable accessibility features [#693](https://github.com/w3c/webextensions/issues/693) + * **Proposal: declaring background scripts in a neutral way [#282](https://github.com/w3c/webextensions/issues/282)** + * **Votes** + * Timothy + * Brian + * Jeurissen Apps (Carlos) + * Kiara + * Notes + * [devlin]: `preferred_environment` is unlikely to be implemented in Chrome (since we only support SWs) + * Carlos: But Chrome could support scripts array and generate a SW script + * Devlin: Ack; let's talk more + * **Introducing browser.i18n.getOSLanguage [#252](https://github.com/w3c/webextensions/issues/252)** + * **Votes** + * Jeurissen Apps (Carlos) + * Timothy + * Mukul + * Capital One (Jordan) + * Notes + * [oliver] Any use cases? + * [jordan] Internationalization purposes. + * [simeon] Is there a meaningful difference between OS and browser language? Capital One? + * [george] We don't have a localized extension currently, so this is future-facing. + * [oliver] Far to say that this is a lower priority? + * [capital one people] Yes. + * **Proposal: i18n.getLanguageDictionary [#274](https://github.com/w3c/webextensions/issues/274)** + * **Votes** + * Jeurissen Apps (Carlos) + * Timothy + * Simeon + * Capital One (Jordan) + * Notes + * [oliver] Similar to getOSLanguage in terms of priority. + * Carlos: For capital one it seems? Not for other developers/companies + + +### Issue Triage + + +#### Candidates for Discussion + +**Criteria:** + + * **Issues should be things we can discuss and make progress on in 5 - 10 minutes** + * **Goal is _triage_, not necessarily completion or resolution** + * **Candidates types** + * **Determining general browser supportiveness for small - medium issues** + * **Updating labels on existing issues (e.g., marking as implemented)** + * **Closing out issues that are fixed or WontFix** + * **Avoid** + * **Discussions of entire new API namespaces (unless proposing we WontFix them)** + * **Fundamental changes to the platform** + + +#### Discussed issues + + * [Issue 693](https://github.com/w3c/webextensions/issues/693): Add API to switch focus from sidePanel to main document to enable accessibility features + * [devlin] What would switching to the main document look like? + * [carlos] Switching tabs causes the tab to be focused again. + * [simeon] Firefox does that too. + * [rob] Would we introduce a new method to focus the main content area? + * [devlin] Basically yes. Another question is whether to focus individual frames too. + * [timothy] Focusing the tab focuses whatever frame was focused last. + * [devlin] Allowing developers to control focus very directly can potentially cause clickjacking issues. + * [simeon] Jackie mentioned that the sidebar is not focused when it is opened. I don't think that we need a general API to focus the sidepanel. + * [timothy] Opening again should be OK. + * [oliver] If there is a field in a page, and you close the sidepanel, it does not focus the input field again. I would expect some focus to be remembered. + * [devlin] I would envision this to be an API on tabs, not sidepanel. + * [simeon] Focus here is on focusing the window, not the sidepanel. + * [rob] I think that we do not need to specify the focus behavior too closely, following the defaults of the browser would make sense. + * [rob] If the address bar was focused and you call this method, what happens? + * [devlin] It focuses the main content in the tab (document tree in Chrome, webview in Safari) - whatever was the active frame is focused. + * [oliver] Same question with popup. + * [devlin] I expect the popup to be closed. + * [devlin] I have more concerns with stealing tab focus. + * [timothy] We could require a user gesture. + * [oliver] Should we make it so the side panel gets focus when it first opens? + * [devlin] Yes, I would lean towards this. + * [timothy] And calling open when it was already open, focuses. + * [devlin] Maybe? + * **Resolution**: Add method to focus tab (tabs.focus()), opening sidebar should focus the sidebar, possibly even when it was already open. + * **Action item**: Oliver to reply on issue + * [oliver] Commented https://github.com/w3c/webextensions/issues/693#issuecomment-2372499691 + * [Issue 689](https://github.com/w3c/webextensions/issues/689): I hope browsers can provide an API to hide/show the bookmarks bar + * [devlin] Not interested in doing this. + * [simeon] Firefox supports the browserSettings API. Rob, thoughts? + * [rob] Use case? + * [devlin] Screen sharing. + * [rob] What they could is modify the video to remove the content. + * [timothy] Use case is video streaming in general, more content would have to be culled than just bookmarks bar. + * [devlin] Not much appetite on the Chrome side to allow extensions to hide browser UI. I see utility in the use case, but that is not something we would write an extension API for. + * [timothy] You could almost do this now with window.open and fiddly window flags. + * [devlin] If you wanted a clean demo of a feature in the browser, reducing chrome wouldn't serve you. + * [devlin] The class of issues - customize browser - is within the realm of extensions. The specific user-facing sessions are not user controllable. Exceptions exist, such as privacy features. Core browser settings cannot be modified. + * [simeon] I can get onboard with that for the bookmarks bar, how about management API to manage the pinned state of extension button. + * [devlin] Don't love the management API in general. Don't particularly like having extensions manage the install or disable state of extensions. + * **Resolution**: Chrome/Firefox/Safari opposed, Close as won't fix. Enterprise policy can manage pinned state. + * **Action item**: Devlin to reply on the issue [[done](https://github.com/w3c/webextensions/issues/689#issuecomment-2374754666)] + * [Issue 694](https://github.com/w3c/webextensions/issues/694): [DNR] in opposition to webRequestBlocking, declarativeNetRequest rules are not applied if the request is redirected + * [rob] Firefox's behavior makes sense IMO - it is a different request. + * [devlin] Agreed. We fixed it in DNR. + * [rob] Is Chrome's webRequest behavior intentional? + * [devlin] No + * [rob] DNR and webRequest share the backend in Chrome, is the observed result really accurate? + * [devlin] Yes they share the same stack, should check again. + * **Action item**: Devlin to confirm that the headers should not be added from webRequest + * **Action item**: Brian to confirm that DNR does not add headers in Safari after a redirect. + * [brian] It appears DNR in Safari adds the headers to redirect. + * [Issue 274](https://github.com/w3c/webextensions/issues/274): Proposal: i18n.getLanguageDictionary + * [carlos] We talked about the proposals yesterday; Rob was in favor of async initialization and then allow synchronous getMessage. + * [rob] Could we address this by switching the language across all contexts. + * [carlos] Could have a content script that you want to match the page content. + * [rob] Is that a use case that should have first-class support in extension APIs? + * [carlos] Being able to use it could enable re-use. + * [devlin] Don't like the pattern of set, get message, set back. Creates some raciness. + * [devlin] Don't think this is the right time to introduce custom return types in extension APIs. It doesn't introduce new performance issues – getMessage is already sync. + * [rob] I'm surprised that it would not introduce perf issues - the languages may not be available in memory. + * [devlin] That's why I said new issues. + * [oliver] How does that work with fallbacks? Do we collapse it all into one bundle? + * [timothy] That is what we do. + * [oliver] My understanding was Firefox would only support this asynchronously. + * [rob] We could do it sync if we want to by blocking the content process, but that is not good design. The perf issue is not present with the default language, because the locale data can be computed in advance and be shared with all processes via shared memory. + * [timothy] That's essentially what we do. + * [carlos] In theory it would only need to block the first time. + * [oliver] For proposal D, either this is synchronous and the browser handles blocking behind the scenes, or this asynchronous and the developer needs to wait for promises to resolve building their UI. Would rather the complexity be on the browser side. + * [devlin] Rob, how opposed are you with synchronous getmessage with a locale param? + * [rob] Can be convinced, but don't think it's a great design. Every new locale creates a blocking lookup. It's like sync XHR. It exists, but we'd rather it didn't. + * [devlin] There's no utility in calling it for 100 languages. Sync XHR has \*lots\* of utility. + * [rob] Can we make this opt in via a permission? Seems not great for every extension to be able to do this. + * [devlin] Would be opposed to a permission. + * [oliver] Would hope this will be fairly quick. + * [timothy] If a spinning disk is involved we're potentially fetching 4 files from disk. + * [devlin] (...) Can cache results in the renderer process for the duration of the session. + * [rob] Not a question of \*can\* it be sync, but \*if\* it should be sync. How would a developer know when the pessimistic case will happen? + * [devlin] If we're talking about augmenting getMessage or returning a dictionary of strings. + * [rob] How would Safari feel about a permission? + * [timothy] Not applicable to our implementation due to auto-grant of permissions. + * [rob] I'll go with a neutral position if we are going with sync getMessage + locale option.. + * [devlin] Carlos, do you need this in a content script? + * [carlos] Yes. + * [oliver] For clarity, what do you mean by neutral, Rob? + * [rob] I don't like the design, but if everyone else implements it we likely will as well. + * [carlos] What's the concern with custom data types? + * [devlin] Don't have an existing pattern in Chromium of returning objects that aren't plain JS. There are a lot of other questions that this raises: can you instantiate your own objects, can you modify the prototype chain, (...) + * [devlin] Carlos, for the suggestion of returning a function, I think returning a dictionary is more natural. Would be open to B. + * [timothy] I'm open to B + * [simeon] I prefer B because it makes the async operation clear and provides sync access to data after. + * [oliver] For clarity, B would be a plain JavaScript object with property values that are the resolved strings, correct? + * [devlin] Yes. + * [simeon] For clarity, how would substitutions be handled in the returned object? + * [timothy] The return message format strings. + * … + * [oliver] If a developer decides that our message format isn't robust enough, they could use their own string resolution algorithm in combination with MessageFormat2 + * [devlin] We are well beyond triage at this point. Let's move on. + * **Resolution:** Chrome/Firefox/Safari supportive of option B. + * [Issue 646](https://github.com/w3c/webextensions/issues/646): userScripts API: method to get matching ids for a URL + * [devlin] There is a work-around, but not perfect. + * [timothy] If this were to be added, it should be on scripting. I voiced it before, userScripts should have been in scripting. + * [devlin] Rob, if I understood your comment, it is basically a URL does not equal injection. + * [rob] Yes. + * [simeon] Is the hesitation that the proposal target by URL and not documentId or another concept? + * [rob] Might not always have a URL or tab. + * [rob] userScripts API does not support match_origin_as_fallback. + * [devlin] We could add it to the userScripts API too. + * [oliver] Another option is a method to get contexts that have been injected into, which would take some kind of context parameter. + * [devlin] Tophf proposed get matching IDs for a URL, you noted that URL is insufficient to target. Is there an alternative? + * [rob] I suggested more targeting information. + * [devlin] Sounds like you're saying “given this set of conditions, what scripts would be injected?” But that's not quite what's being requested. They don't want to guess what might be injected, but to know what has been injected. + * [rob] Match patterns and glob patterns could help. A script may match but not inject. Devlin noted that match origin as fallback is not supported, but could be. + * [devlin] Even if we add match patterns and glob patterns and so on, but the use case is to know what has been injected. Asking the developer to climb the frame tree to get all the context, that sounds unnecessarily complex. + * [oliver] We've discussed getContexts in the past. If we included both content and user scripts, would that address it? + * [devlin] With user scripts there can be multiple injected in separate worlds in the same page. + * [rob] When a script is injected, there's no trace. + * [devlin] Impl detail, you could trace it. + * [rob] Stepping back, are we in all inclined to add a method that returns whether scripts are injected in a specific frame/document? + * [devlin] Should either have two places or a unified method. Setting aside the namespace and method name, we should have a way to get the scripts that are injected into a given frame/tab/frametree/etc. We should figure out naming, namespacing, properties, etc. later. + * **Action item**: Devlin to reply on the issue [[done](https://github.com/w3c/webextensions/issues/646#issuecomment-2374746743)] + * [Issue 533](https://github.com/w3c/webextensions/issues/533): Enhance browser.storage.local to allow storing binary data directly + * [oliver] As a note, session storage is unique in Chrome. Due to how we implemented it we do support a larger range of data types than we do in other storage areas. + * [timothy] Interesting to know, we do not. We use an in-memory SQL database. + * [oliver] We use a key-value store. + * [rob] On Firefox side we use structured clone for storage.session. + * [oliver] How hard would it be in Chrome to implement this? + * [rob] IndexedDB also supports structured cloning, which you also support. + * [devlin] Extension storage is not great. Would prefer web APIs. + * [oliver] Not all features are available in service workers. + * [devlin] + * [timothy] We prefer extensions to use extension storage. Mostly for tracking purposes, we have different APIs, clearing extension storage is clearly attributed to extensions. I'd like us to explore structured clone. That said, we haven't seen much demand for it, that's why it is not a priority. + * [devlin] It is less a (...). The more we make chrome.storage not suck, the more people would use it and its performance isn't great. + * [oliver] So we are neutral? + * [devlin] No inherent objection to it, but I don't know if we are going to do it anytime soon. + * [oliver] [Commented](https://github.com/w3c/webextensions/issues/533#issuecomment-2372558594). + * [Issue 534](https://github.com/w3c/webextensions/issues/534): Inconsistency with indexedDB in browser extensions + * [devlin] (reading issue description out loud) + * [devlin] Sounds like Firefox is effectively running permanently in incognito mode when “Never remember history” is enabled. + * [rob] Yes. + * [oliver] I'm not familiar with never remember history. If I went to 3 sites and went to the History viewer, I wouldn't expect to see data. + * [rob] Extensions are not enabled in private by default. Never remember history is a sort of permanent private browsing. + * [devlin] I think Oliver is mostly saying the naming is weird. + * [devlin] What's the right behavior for extensions with web storage in private / regular mode for Safari. I don't like the idea of clearing web storage outside of Incognito mode. + * [rob] That's not what the table in the issue is saying. + * [timothy] Safari clears IndexedDB data when an origin is not used after 7 days. + * [devlin] They are looking at spanning mode. Not clear what happens with split. + * [devlin] With split mode, if you store data in web APIs while in incognito mode, when you close the incognito session the profile is deleted and therefore so is the data. Mostly true that this is a feature as it allows extensions to store data in web storage that behaves like the web context does, but persistent data can be stored in extension storage. + * [rob] Does Safari support split? + * [timothy] No. The table is correct. + * [rob] Firefox also does not support split. Only recently added the ability for extensions explicitly marked as split to load. + * [devlin] Does anyone have interest in implementing split mode? + * [timothy] No one has asked for it. + * [rob] Not a priority. + * [devlin] In that case, the behavior we'd expect is for a spanning mode extension web storage is persisted but in split incognito the regular + * [rob] The underlying issue is that developers want a reliable way of storing data in IndexedDB. + * [devlin] We're largely happy with Chrome's current behavior of keeping web data in spanning mode, destroying it in split. Seems like Firefox needs to decide what the extension behavior in general when “never remember history” is enabled. + * [rob] Never remember is permanent private mode, so destroying data is appropriate. Any appetite for providing a way to get a persistent indexedDB session? + * [devlin] No. + * [tomislav] I think Devlin is saying Firefox is free to handle this however it wants given the lack of consistency. + * Resolution: None! + * **Action item**: Devlin to add rationale for current Chrome behavior [[done](https://github.com/w3c/webextensions/issues/534#issuecomment-2374769783)] + * **Action item**: Firefox to decide how they want to handle IndexedDB in “never remember” mode. + * [Issue 570](https://github.com/w3c/webextensions/issues/570): Inconsistency: dns.resolve() + * [oliver] Only action item here was to check with the Chrome security team to see if we could expose our existing `dns` API implementation. I haven't done that and will try to do it in the future. + * **Action item**: Oliver to follow up. + * [Issue 507](https://github.com/w3c/webextensions/issues/507): Support $schema in manifest.json + * [devlin] What's the request? + * [carlos] Allow extensions to use a “$schema” key in the manifest. + * [oliver] Doesn't throw an error, but does return a warning. + * [david] There seems to be some confusion. Users reported that it threw an error when uploading but later stopped returning an error. + * [carlos] There are more keys that could raise warnings. Like browser_specific_settings. + * [oliver] Browser specific settings is a feature we don't support, but has some value elsewhere. “$schema” + * [devlin] we warn on browser_specific_settings because we don't support it. Developers try to specify it expecting it to … Sorry, was thinking browser overrides, not browser specific settings. + * [rob] Would you consider not warning on browser_specific_settings? + * [timothy] Safari also uses it. + * [devlin] Open to it. + * [devlin] Back to this issue, hesitant to support arbitrary fields used by some random tools. Worried about proliferation of everyone's pet keys. + * [timothy] $schema is a standard. + * [tomislav] Agreed with reasoning. + * [devlin] If this is used by a large amount of the community, I'm in favor of ignoring it. + * [rob] So we are committing to maintaining a list of intentionally recognized properties even if ignored, starting with browser_specific_settings and $schema. + * [devlin] Yes. + * [rob] There is already a Chromium issue for this at https://issues.chromium.org/issues/40196501. + * **Resolution**: Agreement that $schema should not be warned about. + * **Resolution**: Chrome to intentionally ignore browser_specific_settings and $schema instead of warning. + * [rob] Note: This is now implemented in Chrome: https://github.com/w3c/webextensions/issues/507#issuecomment-2384073091 + * [Issue 115](https://github.com/w3c/webextensions/issues/115): Proposal: move browser specific settings to browser_specific_settings + * [rob] Are you neutral or opposed towards adding chrome to browser_specific_settings? + * [devlin] What is put there? + * [rob] E.g. putting strict_min_version. + * [timothy] We use it in that way too. + * [rob] Chrome could then add a browser_specific_settings.chrome.strict_min_version key with the semantics of minimum_chrome_version. + * [devlin] No objections, would not be a priority to implement. + * [Issue 12](https://github.com/w3c/webextensions/issues/12): request: allow to retrieve a frameID from an <iframe> element + * No updates; Oliver to follow-follow-up + * **Action item**: Oliver to follow up + * [Issue 8](https://github.com/w3c/webextensions/issues/8): executeScript API may inject scripts in an unexpected target at runtime + * [rob] Chrome has implemented documentId, so could we put `chrome: implemented` here, and supportive in Firefox and Safari? + * [devlin] Sounds good to me. + * [rob] I've updated the labels. + * [Issue 1](https://github.com/w3c/webextensions/issues/1): What to do with the older CG? + * **Resolution**: Timothy to handle the proper procedure to update pointers and close the group + * [Issue 483](https://github.com/w3c/webextensions/issues/483): Proposal: API to embed pages in WebExtension bypassing CSP + * [devlin] What's the CSP we need to bypass + * [oliver] frame-ancestors + * [devlin] I'm good with bypassing all of that + * [oliver] I need to create a proposal for this. + * **Resolution**: Oliver to create a proposal. + * [Issue 688](https://github.com/w3c/webextensions/issues/688): dev_permissions / self_permissions key in manifest + * [devlin] Request here is support for a manifest key. + * [rob] optional_permissions could be used. + * [devlin] Or a separate build. + * [simeon] Is there interest for other browsers to support them as optional? + * [devlin] Yes, I am supportive of making all permissions optional. + * [rob] So our consensus is to not support this, and encourage a separate build or optional permissions? + * [devlin] Yes, and support all permissions as optional where feasible. + * **Resolution: Close** + * [devlin] Jordan, are you okay with this resolution? + * [jordan] Yes. + * [simeon] Closed & commented. diff --git a/_minutes/2024-09-26-wecg-tpac.md b/_minutes/2024-09-26-wecg-tpac.md new file mode 100644 index 00000000..e75c384a --- /dev/null +++ b/_minutes/2024-09-26-wecg-tpac.md @@ -0,0 +1,410 @@ +# WECG TPAC Sep 26, 2024 + + +## Agenda + +Thursday: https://github.com/w3c/webextensions/wiki/TPAC-2024-Coordination#thursday + + * 08:00 - 09:00 + * [60 min] Regular WECG meeting (minutes: [2024-09-26-wecg.md](https://github.com/w3c/webextensions/blob/main/_minutes/2024-09-26-wecg.md)). + * 11:00 - 12:30 + * [60 min] MessageFormat 2 - presentation & discussion + * [30 min] Declarative cosmetic rules ([#362](https://github.com/w3c/webextensions/issues/362)) + * 15:00 - 16:00 (non-WECG meeting) + * [60 min] Browser Testing and Tools Sync + * 16:30 - 18:00 + * [50 min] Event management in non-persistent contexts (Devlin) + * [40 min] WebExtensions permission model + + +## Attendees + + * Rob Wu (Mozilla) + * Christos Bacharakis (Eyeo) + * Timothy Hatcher (Apple) + * Kiara Rose (Apple) + * David Johnson (Apple) + * Elijah Sawyers (Apple) + * Brian Weinstein (Apple) + * Simeon Vincent (Mozilla) + * Mukul Purohit (Microsoft) + * Devlin Cronin (Google) + * Carlos Jeurissen (Jeurissen Apps) + * Oliver Dunk (Google) + * Jordan Spivack (Capital One) + * Casey Garland (Capital One) + * George Henderson (Capital One) + * Tomislav Jovanovic (Mozilla) + * Ioana Chiorean (Interledger Foundation) + * Eemeli Aro (Mozilla) + * Ali Spivak (Google) + * Brian Shultz (Tango) + * Mohamed Elgendi (Malwarebytes) + + +## Notes + + +### [60 min] MessageFormat 2 - presentation & discussion + + * [eemeli] Have been working under the Unicode consortium to define a new message formatting language - called MessageFormat2. Successor to ICU MessageFormat, which was not specified as standard. This work started under the i18n group under TC39. Spun off in 2019 to be under Unicode since needs are not JavaScript specific. Work is reaching a point where 2.0 release may be concluded this year, or next Spring. Lots of parties waiting on this. Have done some work over the last two days building this demo. Expect we can do this without backwards compatibility issues. + * [eemeli] <Demo> + * Current messages.json vs example of MF2: https://github.com/eemeli/myqonly/commit/d286337fdf4e2b16e394decceb0fc470583294b2 + * Showing messages.json file where “message” contains the translation in MF2 format, with 18n.getMessage calls accepting an object with properties. + * Showing new features such as first-class pluralization support. + * E.g. `.input {$num :number} .match $num one {{1 review on Github}} * {{{$num} reviews on Github}}` + * Non-parametric messages looking identical to the existing messages.json format. + * To distinguish between regular messages.json and MF2 messages.json file, the top-level object has a `”@@format”: “mf2”` property. + * [eemeli] Main question - what are the possible blockers to adopting this: 1) supporting multiple formats, and 2) specifically MessageFormat 2? MF2 is a new spec, so there are not currently a large number of users. Before introducing [Intl.MessageFormat](https://github.com/tc39/proposal-intl-messageformat) in JS, TC39 wants to see more adoption in the wild. Use case for web extensions is similar. Could this be adopted? If not, what are the blockers? + * [devlin] Can you give a brief overview of the capabilities that MF2 provides? I see pluralization in this demo. What else? + * [eemeli] Yes, there are other benefits. :number annotations allow you to pass options similar to Intl.NumberFormat. Matching is not limited to numbers but can be related to grammatical gender, verb tense and many other ways messages can vary. Format suitable for both developers and translators. + * [devlin] You also mentioned that Mozilla is adopting this and have benefits to the ecosystem at large. Are there other adopters of note? + * [eemeli] Because this work is being done at Unicode, it will be made available as part of ICU4C and ICU4J. ICU4X implementation will follow. + * [devlin] You mentioned you're planning to launch version 2.0. What does this mean? + * [eemeli] Stability policy guarantees start applying, and it's a marker that we've internal consensus in the WG that this is good for the long term (no more tweaks). + * [devlin] The demo format looks heavily designed to be compatible with existing messages.json format. Is this same structure the one you would choose if you didn't have to do this? message.json isn't the only place we could do this – could signal in the manifest. + * [eemeli] A lot of focus has been on MessageFormat (i.e, a single message). We are also working on [message resource syntax](https://github.com/eemeli/message-resource-wg), but this is not developed as far. Working to find where its spec will live. Heavily based on TOML, takes into account specific requirements we've identified as beneficial for message authors and translators. This format allows attaching messages and comments. This helps provide additional context to translators to translate a given string. Based on our experience at Mozilla, we should be able to build a parser with performance on part with JSON parsing. + * [devlin] Do you have an example of a message with placeholders and descriptions? Or pluralisation or matching? + * [eemeli] Not to hand. + * [timothy] Would almost like to see inputs in a distinct section if we stuck with JSON format. + * [eemeli] This is assuming translators will end up looking at raw format. This will happen in many cases but a lot of translation work these days is mediated through tooling. A big focus has been making things easier for tooling, syntax highlighting, assistive technologies. + * [devlin] (To carlos) Do you use automated translations? + * [carlos] Around 5000 users have signed up to translate. Current translation support doesn't include things like gender. Looking forward to adopting something like this. + * [devlin] Was mostly wondering what tooling would need to be in place. Carlos, would this work for you if there was tooling? + * [carlos] Yes. + * [timothy] If there is another better file format, we could also adopt that instead. + * [eemeli] Yes, but there is a danger that this work is slow. MessageFormat started midway through 2019 and is only reaching this stage now. It could be another 2, 3 or 4 years before MessageResource is standardized. + * [devlin] If the message format is not in the spec, what components are included in the stable spec? + * [eemeli] Everything that is in MessageFormat 2 spec (including standard functions) could be used. There is also support for custom functions but this should likely be left out of messages.json until this is figured out in TC39. It would make sense to align. + * [devlin] In WebExtensions, we try to have the contents of the package be reviewable for privacy/security reasons. If the format is too flexible, one might worry about how it could be abused. + * [timothy] Demo JSON format can be hard to parse. + * [devlin] less worried about that then how it could be abused (for example, arbitrary code execution). + * [eemeli] Without custom functions arbitrary code execution should absolutely not be possible. We've also limited what custom functions can do. Spec promises not to present a case where a standard function is not implementable as a black box that does not use external inputs. + * [eemeli] MessageFormat 2 does not need to be output to a string. You can format to parts. There will be further work to ensure security of this. + * [carlos] For clarity on previous comments, I'm not waiting on tools for gender to be integrated. That's not a blocker for me. + * [timothy] Plain text without substitutions doesn't need curly braces? + * [eemeli] Nope. + * [timothy] Demo isn't using a modified format? + * [eemeli] Demo is using a [MessageFormat 2 library](https://github.com/messageformat/messageformat/tree/main/packages/mf2-messageformat) with no modifications. + * [simeon] Did you strip newlines in the demo? + * [eemeli] Yes, since this is easiest in JSON. + * [timothy] The other format had lots of @ symbols, what were these for? + * [eemeli] <Demo of format with more formatting> + * `.input {$total :number} .match $total 0 {{Nothing to do! \\\\o/}} one {{Found 1 thing to do}} * {{Found {$total} things to do}}` + * Above is one line because JSON does not support line breaks, more natural MF2 formatting would include line breaks such as: +``` +.input {$total :number} +.match $total +0 {{Nothing to do! \\\\o/}} +one {{Found 1 thing to do}} +* {{Found {$total} things to do}} +``` + + * [oliver] As someone not familiar with MF2, the JSON format looks more readable than the TOML format. + * [timothy] I also see potential for separating the message in an object with properties for “0”, “one”, “\*” instead of embedding another microformat in the JSON. + * [george] Have you looked at [i18next](https://www.i18next.com/misc/json-format) for inspiration on format? + * [eemeli] Yes, there is a prototype of using i18next for MessageFormat. We are trying to take learnings from other projects and start from the ground up so we don't accumulate tech debt. + * [devlin] Is there validation of inputs? e.g numbers Is there overlap with JSON schema? + * [eemeli] There's validation. If input is not a number, BigInt, a string with a JSON representation of a number, an object with a valueOf() method that returns an object with a number or a string. + * [timothy] You don't think we should go the route of using JSON, and should instead use string microformat? + * [eemeli] Correct. + * [simeon] When we were talking about this previously, we were discussing messages file, manifest as possible locations for this. We were also considering being able to migrate specific files or messages so it can be done more gradually. + * [timothy] This sounds aspirational but there are already syntax changes to how you pass in substitutions. + * [devlin] Independently, this is a strict superset. We might be able to write a tool that does a translation between formats. + * [eemeli] Separately from introducing MessageFormat 2, passing an object with keys to getMessage() should work. Current syntax has examples for variables included, you can do that in MessageFormat 2 but slightly differently. + * [oliver] Is @example a reserved space or just a name that is irrelevant? + * [eemeli] The @ marks it as an attribute with no runtime impact, but “example” is made up, but agreed we might want to agree on some common terms. + * [timothy] Back to gradual rollout, I still think this will be difficult if you start adopting plurals, currency input and only have the message in the new format in certain translations. So not sure if this should be a goal. + * [simeon] Yeah, to Devlin's point it should be possible to convert. + * [timothy] I would opt for a key in the manifest to opt in to the MF2. + * [oliver] From a practicality point of view, you mentioned in a previous session that there are reference implementations and browsers will need to ship an implementation once this is supported by TC39? + * [eemeli] Yes. Functions provided won't necessarily be the ICU ones, but they can be. + * [rob] Timothy mentioned declaring format in the manifest. Would that be JSON or MF2? + * [timothy] As JSON or whatever format, as opposed to putting `”@@format”: “mf2”` in the JSON. + * [eemeli] Whatever format, allow for future changes by using a string/enum value rather than a boolean. + * [rob] What are next steps? + * [eemeli] Haven't heard blockers or concerns related to waiting for wider industry adoption before considering adoption in WebExtensions. + * [devlin] I do have some concerns. As Timothy alluded to, we want to use something because we don't want to roll our own. So want something somewhat standardized, it sounds like you are on a good track. There is no particular milestone we need to wait for. + * [eemeli] Once this reaches 2.0, accepted into CLDR and ICU, this will be the only standardized message formatting syntax. + * [timothy] Once this is in ICU, I see no issues for us adopting this. + * [eemeli] Hopefully coming in a matter of months. In this demo I've made a point of avoiding parts of MF2 outside of getMessage. Want to avoid the possibility of conflicting with future TC39 specs. + * [tomislav] So what shouldn't we be doing? + * [eemeli] Formatted parts. We should only return strings. Formatted parts could take e.g. a DOM element as input, and the result could include that element, or other non-string values. + * [devlin] Concrete next steps: we're likely waiting on MF2 finishing. After that, we can take up adoption discussions. + * [timothy] One thing I notice is that we only have a message key in the messages.json. + * [devlin] The messages.json format also accepts a “description” field next to the “message” field. This would still be applicable. + * [devlin] You mentioned Firefox are planning on adopting this, have you spoken to Chrome engineers localizing the browser? + * [eemeli] To some extent yes. A number of Google engineers are contributing to MessageFormat 2 spec; not sure if they are working on Chrome. + * [timothy] And Apple folks? + * [eemeli] Yes, George Rhoten, although they have not been active for a little while. + * [rob] We should file an issue to track this, previous and future discussions. + * **Resolution**: Wait for MF2 finalization and pick it up from there, create a tracking issue. + * [eemeli] Created: [Issue 698](https://github.com/w3c/webextensions/issues/698): MessageFormat 2 support + + +### [60 min] Browser Testing and Tools Sync + + * The WECG met with the Browser Testing and Tools group to discuss extension installation through WebDriver BiDi (including a related PR at https://github.com/w3c/webdriver-bidi/pull/778). We anticipate needing this functionality to integrate WebExtensions testing in wpt ([#19](https://github.com/w3c/webextensions/issues/19)). + * Minutes: https://www.w3.org/2024/09/26-webdriver-minutes.html#t14 + + +### [30 min] Declarative cosmetic rules (#362) + + * [Issue 362](https://github.com/w3c/webextensions/issues/362): Proposal: Declarative Cosmetic Rules + * [david] We've been thinking about this at Apple. Looking at rule formats we have for content blockers today. Would like to apply Declarative Net Request API to content on the page as well. Do we want to limit the scope to blocking/hiding content or also adding content/badging? + * [timothy] Devlin mentioned badging earlier this week. + * [devlin] I'd like to limit to blocking for now. I'm supportive of expanding in the future. Expect that other capabilities would significantly slow down work. + * [timothy] Was initially hesitant to use a new namespace, but if this morphs into adding content as well that may make more sense. + * [george] Can you clarify “blocking? + * [timothy] Hiding or removing page content. There is an option for display: none; and an option for visibility: hidden. + * [david] Thoughts about other approaches? + * [devlin] Nothing specific at the moment. For cosmetic rules, would be helpful if we had content blockers here. Do we care about relationships between content like initiator? I assume we care about child frame or main frame. Not sure what else we'd need to carry over. + * [george] in the filter rules I've seen I don't think they take parents into account beyond CSS selectors. + * [devlin] Would be curious how often global selectors are used and why. Seems like it could be performance draining. Would we want limits on CSS selector size/depth? From our experience with declarativeContent, matching many CSS rules is costly. Could we e.g. limit to 5000 global cosmetic rules with limited depth. Curious what we could do that would be guardians that don't hinder blocking. + * [timothy] In practice we haven't seen issues with selector complexity today. We've even opened it up to the :has() selector. We have a CSS JIT which helps with performance for this use case. + * [george] Could you apply rules dynamically after page load? + * [timothy] Right now there's no dynamic way. It's applied at document_start. + * [oliver] Issue on GitHub was opened by AdGuard. They requested domains and excluded domains. + * [devlin] Expect they'll need at least URLs. Google and Google Maps are very different. How have modern web dev practices impacted selectors? For example, ID is no longer reliable. + * [timothy] Seen in React that IDs are dynamic. CSS is flexible with CSS selector syntax. + * [devlin] Ways to work around the ID limitation. Are there enough dynamic flows that those work around no longer apply? + * [mohamed] … + * [devlin] washingtonpost.com may have a different layout, different number of children, etc. on every page load. + * [mohamed] there are some patterns that repeat on spice sites. Might not apply across domains. + * [devlin] Was thinking more broadly about industry trends and what is/isn't reliable. + * [timothy] Notable feature of our implementation. + * [devlin] We're supportive. Know this is a useful case. Blocking content without host permissions is huge. + * [timothy] Also opens the door for adding content. + * [george] Do you allow for blocking inside shadow dom? + * [timothy] Don't think so. CSS doesn't allow you to select inside. + * [rob] I think that it should be supported. + * [simeon] Have been selectors in the past that pierce. We could support it here if CSS writ large does not. + * [rob] CSS folks have been very hesitant about adding selector support for “piercing”. I recently linked some relevant https://github.com/w3c/webextensions/issues/647#issuecomment-2204351255. We should be able to match inside shadow root without selector support. + * [timothy] XPATH in shadow root might be an alternative as well. + * [david] Would love to get feedback on features that should be considered for V1. + * [casey] Would users be able to tap/click to reveal? + * [devlin] Would probably want to support something like that. + * [george] A feature I'd like to see is the ability to dynamically set rules and apply them to the active tab without reload. + * [casey] Have you thought about … + * [timothy] Not requiring host permissions is ideal. Being able to add content to the page and, once the user interacts, getting access to the page to enhance it is ideal. + * [david] Starting point would likely be inject always. + * [timothy] Pinterest tag use case. + * [david] Could imagine abuse scenarios where an extension puts transparent content across 100% of the page to trigger injection. + * [rob] Action items? + * [timothy] Apple to write a proposal. Names? Leaning towards a new namespace. Allows API to + * [oliver] browser.declarativeCosmeticRules + * [devlin] Don't need to include “declarative” + * [oliver] Don't like “cosmetic” as it implies visual-only. + * [devlin] Would like to allude to page appearance. + * [rob] What functionality do you expect to host in this namespace? + * [timothy] cosmetic additions. + * [devlin] Not just cosmetic. + * [simeon] So injecting a UI that can grant activeTab? + * [devlin] Leaving the door open to that option. + * [david] Main use case is hiding content. + * [] Save content modification. + + +### [50 min] Event management in non-persistent contexts (Devlin) + + * [devlin] There's a common thread of non-persistent contexts are hard. I've been wondering how we can make this easier. Don't want to move away from non-persistence. I'd be curious for general thoughts on main problems and challenges. The three that come to mind are (1) there is no guarantee your service worker will stay alive while you are handling an event (2) there is no way to asynchronously register a listener and (3) there is not a good way to bootstrap state in the listener. + * [tomislav] Can you elaborate on the last one? + * [devlin] You have to init each time you handle an event in case the event started your non-persistent context. After awaiting something you may no longer have a user gesture. + * [simeon] Loss of user gesture in async handlers on background startup is a problem I wanted to call out. + * [rob] Added several related issues corresponding to the three topics: + * https://github.com/w3c/webextensions/issues/416 (waitUntil proposal) + * (covers “there is no guarantee your service worker will stay alive while you are handling an event”) + * https://github.com/w3c/webextensions/issues/501 (toggleable event listener) + * (covers “there is no way to asynchronously register a listener“) + * [rob] Idea behind it of being able to register an event listener later was related. + * https://github.com/w3c/webextensions/issues/353 (onEnabled proposal) + * (related to “there is not a good way to bootstrap state in the listener”) + * [rob] Not exact match, this is about bootstrap at startup, not at event dispatch. + * [devlin] Don't see how 519 is related. + * [rob] Corrected to 501. + * [rob] Related to bootstrapping, 353. + * [oliver] Do we want to talk about more advanced filtering capabilities on event listeners? + * [devlin] Could. + * [oliver] The reason for this is that we've said we don't want to add filters to new events until we've had a general discussion. + * [devlin] Let's punt on that for now. + * [devlin] Other problems? In the past we've discussed freezing instead of stopping the process, almost like pausing a debugger and resuming later. Not sure that's the right solution, but restoring state may be useful. + * [timothy] Isn't that session storage? + * [devlin] Still async. + * [rob] Did you mean retrieving config, etc. for bootstrapping? + * [devlin] Related. Not having to wait on fetching data from storage, for example. + * [rob] We, browser, could delay startup of the context based on initializing session state. I'd be in favor of storing state and restoring it before initialization. + * [timothy] That seems fine. + * [rob] (to devlin) To confirm, would you be ok with that idea? + * [devlin] … trying to figure out what the main problems we're trying to solve are. + * [rob] Would like to support synchronously available state at startup, which also addresses the togglable listener case. + * [devlin] Doesn't address togglable listeners, you don't want to be woken up. + * [rob] Right, they complement each other. There are two aspects: ensuring that an event whose listener is removed does not wake up, but also that a renewed listener registration can detect the event. Synchronously available state at startup enables the extension to register a listener and receive event data. Otherwise events are either dropped, or we would have to remember event details near startup and dispatch later. + * [devlin] Does today. + * [rob] Would have to limit to a bounded time. + * [devlin] Not necessarily. Could introduce a message queue to queue events until listeners are ready. + * [timothy] We queue some messages while waiting for a process to spin up. It's very short. + * [devlin] In effect we all do. But we could also have a queue in the renderer to wait on the initialization before dispatching. This is already implemented by some extensions in userland. + * [rob] I think these 3 areas you outlined are a good start. + * [carlos] ATM every listener needs to be top level. That means SW gets started at times when it doesn't need to be. + * [devlin] Ties into the question of whether you need to register synchronously, togglable events. + * [timothy] Or filters. + * [simeon] Is the idea of updating a filter for a registered listener part of any of these? + * [devlin] If nothing else you can unregister and register again with a different filter. + * [devlin] Do we agree that these three issues mentioned at the start are the three issues to focus on? + * [rob] Yes. + * [timothy] Yes. + + +#### Topic: “there is not a good way to bootstrap state in the listener” + + * [devlin] One ​​of the most impactful ones is having state synchronously available at startup. Building block for extensions and for addressing other issues. Are we all on board with addressing this? + * [timothy] Yes. + * [tomislav] yes. + * [devlin] Are we comfortable saying the SW will start slower? + * [timothy] Depends on how much storage, etc. we set aside. + * [tomislav] Keep the developer in control. If they don't use it, there's minimal impact. + * [oliver] Would want to avoid introducing another storage area. + * [devlin] Torn on that. Session storage is more or less JSON. + * [oliver] We should fix that. + * [timothy] Doesn't match our behavior. + * [rob] Firefox already supports structured cloning in the storage.session API. + * [devlin] Structured cloning is great, tabling that. We could do structured cloning, but we should aim for more flexibility. For example, that doesn't cover an initialized WASM module. We said these values would be available when the bg context starts. Does that include browser start? + * [timothy] I'm inclined to tie it to the browser session. + * [rob] Could support two, one small that persists, and more storage for resumed workers/event pages. + * [rob] Another argument against combining in `storage.session` is that is has the setAccessLevel method that can cause storage.session to be exposed to content scripts, readable & writable. + * [devlin] Are we okay with the assumption that extensions will initialize this data on browser start? + * [oliver] Session storage was motivated in large part by password managers. I imagine they'd also want this. + * [devlin] If were providing a solution that allows behavioral configuration, we'd want that to persist across browser sessions. But if we do that, we'd have less flexibility in what we expose. + * [tomislav] Wouldn't that just bring us back to where we are now where they must initialize at startup? + * [devlin] Not necessarily, you could limit your conditional handling by listening to browser startup. assuming browser start is the first event, every subsequent event would have that state initialized. + * [carlos] Having data persists has privacy implications, no? Persisting data means it's serialized. + * [devlin] We can provide guidance on how to use this safely, properly. I don't think we can say “because of password managers we can't do this at all.” + * [devlin] We've gone back and forth on persisting across browser starts. + * [timothy] I could go either way. Agree that it limits us. + * [devlin] I assume persisting across browser starts is generally desirable for developers. Curious for extension devs opinions? + * [casey] Yeah, we already do that. We might rework it if we had the option of deferring to the browser. + * [carlos] same + * [rob] Should we add a method to flush the storage? + * [devlin] it's a storage API, so we'd have all the same CRUD APIs. + * [rob] Would it be sync? + * [devlin] From the extension's point of view, but that doesn't mean it would be under the hood. + * [rob] use case might be to flush and store data to persist as fast as possible + * [devlin] Can provide extensions a mechanism to notify when write completes. + * [rob] More important part is for extension to be able to signal that writes are not critical. + * [devlin] We are past the 30 min mark. Next steps: browser vendor to draft a proposal. + * **Action Item**: Devlin to draft proposal for synchronous storage mechanism + * [rob] Created [Issue 703](https://github.com/w3c/webextensions/issues/703): State in background scripts, synchronously available across restarts + + +#### Topic: “there is no guarantee your service worker will stay alive while you are handling an event” + + * [rob] There is a proposal here, but pending “chrome: follow-up”. + * [Issue 416](https://github.com/w3c/webextensions/issues/416): Introduce runtime.waitUntil API to keep background service worker / event page active during a specific task + * [devlin] waitUntil makes sense. What I'm torn on is I don't know how we would do it. IDK what that would look like in an extension. The web has an event. In extensions there's no such thing, just bags of data. There's nothing to hang the method on. The open question is how do we do something like that without fully adopting the Event interface. Could see this being something like `chrome.runtime.waitUntil()`. + * [rob] I wouldn't require it to be tied to Event; there is also utility in having a runtime.waitUntil method that can be called without extension API. + * [devlin] Would prefer to have a waitUnit in response to events. + * [rob] Could be implemented by only allowing waitUntil when an event has been called recently. We can discuss mitigations more later. + * [devlin] Could theoretically have a manifest key to opt into a given style of lifetime management. That could enable us to dispatch events with the current data bags on an event object. + * [tomislav] You're proposing a manifest key causing all events to dispatch an event? + * [devlin] They would receive a thing, an Event, an Object interface, etc. But largely yes. + * [devlin] To be clear, not attached to any particular solution. This is for discussion and ideation. + * [rob] Could introduce an extentableEvent manifest key that lists the specific events that should receive event objects. + * [devlin] On the web you call waitUntil on the event. If we could match that, that brings us more in line with the web platform, avoids introducing a pattern that doesn't have a clear association between the event and the wait mechanism. + * [devlin] We can't do that today, but right now the listener has data passed in. You could imagine that we wrap that in an object that also has a waitUntil method. + * [tomislav] I think we should discuss making our events more web like. This doesn't seem like a sufficient motivator for a partial step in that direction. + * [timothy] Agreed. + * [devlin] I don't think it would be that complex to pass in an object with a method. + * [timothy] It's not our complexity. + * [tomislav] It's the ecosystem. + * [devlin] I'm not attached to this. That said, I don't think waitUntil is a small issue. Would wonder if there are other things this would pave the way for. I don't want to completely replace our event system at this moment, but do want to lay the groundwork for addressing these problems. + * [rob] Are you suggesting that addListener should take an object, e.g. as suggested in ​​[issue 519](https://github.com/w3c/webextensions/issues/519)? + * [devlin] No, have the thing passed to the listener be the event. + * [oliver] Feels like we're making this complicated. What's necessary to address the pain point can be addressed with smaller mitigations. + * [tomislav] If you're in an event, you're allowed to call this method with a promise. + * [timothy] We definitely know when we're handling an event. + * [rob] runtime.waitUntil also allows for integration with web APIs. + * [devlin] Main action item is to write a proposal for a synchronous storage mechanism. Maybe another if we want a proposal for waitUntil. + * [tomislav] Do you not think we should move towards the web model for events? + * [devlin] I'm open to it. What we were discussing was a step towards that. + * [tomislav] Worried about documentation challenges with that. + * **Resolution**: Consensus on capability of extending lifetime, with mitigations. + * **Action item**: Rob to draft concrete proposal. + + +### [40 min] WebExtensions permission model + + * [simeon] Multiple recent issues, even just 7 in the 6xx range. + * [devlin] A lot of these issues seem like good candidates for issue triage (some were already triaged), tomorrow. Potential discussion around scoping permissions to origins. + + +#### [Issue 687](https://github.com/w3c/webextensions/issues/687): Proposal: Targeted Permissions + + * [rob] General issue is that some capabilities are not dangerous, but are in a namespace that's restricted by a permission. + * [devlin] History API referenced here seems like a good example. + * [rob] I see 3 levels in the history API example: privacy-impacting (querying history), destructive (deletion), already-possible-in-other-ways (add history item). Would you require permission warnings for them all, even the last one? + * [devlin] Yes. Not sure about the last one. + * [devlin] In general we strive to have APIs bucketed in a way that you generally want that functionality and there aren't dramatic differences in what the APIs can do/capabilities they expose. Already have some examples where scaling of permissions doesn't match namespaces. For example, downloads.download vs. downloads.open. Don't know that we'd want to go towards a new permission for every method – would be challenging to explain to the user, hard for developers to rationalize. + * [timothy] I know other browsers struggle with extensions adding new permissions and getting disabled. + * [devlin] Brian mentioned that Tango wants new permissions but avoids requesting because they will be disabled. + * [brian] Definitely. + * [brian] We have 3 main buckets: browsing history, ability to track across web pages, webpage content. + * [devlin] Generally in favor of more granular then we have now, but not as granular as per-method. + * [timothy] Liked where you were going with the history example. + * [devlin] Essentially read and write. + * [random talk about incognito – can't open a tab in a specific window unless you have incognito access] + * [rob] Another aspect is that there are some APIs that are useful but don't pose a risk. Would we be comfortable with making them available without a permission warning? + * [devlin] Without a permission or warning? + * [rob] Warning. For an extension that only wants to save something, it's a bit much to warn about downloads.download, since the same functionality is already freely available in web content APIs (``). + * [devlin] Given a permission, we would determine an appropriate warning for that permission which may be no warning. If we think there's an API with meaningful buckets, it makes sense to segment those buckets and warn as appropriate. + * [rob] Safari doesn't have warnings so this isn't relevant, right? + * [timothy] Depends on the buckets. May still be relevant. + * [david] For example, DNR. Basic capabilities are fine and don't show a warning, but you want to redirect and then we need to tell the user. + * [devlin] Seems like we're largely in agreement. + * [devlin] If we had history.read and history.write, would we deprecate history? + * [timothy] Next manifest version. + * [rob] What if we define new features outside the bounds of those permissions? E.g. history.delete. Unless we are confident that we can define all permission scopes upfront, we should not deprecate the broader history. + * [oliver] Next step might be a call to action for anyone in the community that wants to break down permissions. + * [devlin] Would prefer not to do all of them. Maybe just 3 to start, maybe find a pattern. + * [tomislav] Get a sense of how well its working and determine next steps. + * [devlin] Anything else on finer grained permission warnings? + * **Resolution**: Tentatively in favor of finer grained permissions. Proposals welcome. + + +#### Per-origin permissions + + * [devlin] The last piece was further breaking down permissions by host permissions. Opposed to that approach. The reason we have host permissions is that they generally give you the ability to perform arbitrary, dangerous actions on a given origin. There's not a meaningful distinction between being able to access, say, cookies via a content script and being able to access them via the Cookies API. + * [devlin] Maybe httpOnly could be behind a finer grained permission, since content scripts cannot read them. + * [rob] webRequest can see httpOnly cookies. + * [tomislav] Using webrequest is how I found out just how far you can go with host permissions. + * [timothy] We have the concept of associated app domains. In that case we should just grant access to those origins. + * [rob] We don't have that. + * [devlin] It is not something we would do. + * [timothy] Could hypothetically do a DNS verification step, but that's asking to set up a whole set of infrastructure. + * [tomislav] Google and Apple already have that, Mozilla does not. + * [timothy] I know it's a lot, but giving you instant access to your own cookies seems like a win. + * [devlin] We know developers want it, but store concepts are out of scope. + * [devlin] Circling back, since limiting which APIs you can use by host doesn't impose a meaningful constraint. Are we all on board with passing on this? + * [tomislav] Yes. + * [timothy] Yes. + * [carlos] There are likely other ways you could constrain permissions, like only allowing an extension to access host permissions when showing extension UI. + * [casey] We use hosts to determine when we should expose UI, though. + * [carlos] As a popup you might not need access to a site, opting out could improve the security of the extension. + * [timothy] We see URL access as the ability to track. Page access is a whole other level of data access. + * [devlin] I'm very supportive of providing users with more tools to scope the duration of grants. There's not too much we can do here, though, as it's a browser UI consideration. + * [simeon] Suggest we wrap up there. + * [tomislav] one quick topic… + + +#### Optional-only permissions + + * [tomislav] Have run into two situations where we have wanted to support optional permissions. E.g. experimental APIs and userScripts API. In the userScripts API example, the “userScripts” permission can be in the manifest be ignored. + * [tomislav] Suggestion: optional only permissions (name not final). Permissions that you can declare in the manifest, but that would never be granted by default. + * [devlin] Sounds interesting, would not be sure if we would use it in Chrome. + * [timothy] Use feature detection for experimental APIs? + * [devlin] In userScripts API case, we would not want extensions to trigger the install prompt. + * [tomislav] Whether you display the permission request is up to the browser. It wouldn't necessarily be triggered by the extension. It would be a capability that's directly mappable to the manifest. + * [timothy] I would expect permissions.contains() to return false if you do not have the permission. + * [devlin] You have the permission, you just can't use it. + * (laughter) + * [timothy] Sounds like it should be equivalent to no permission. + * [devlin] I can see a case for a permission.contains special handling. Don't know if there's anything else we'd use this for other than user scripts. diff --git a/_minutes/2024-09-26-wecg.md b/_minutes/2024-09-26-wecg.md new file mode 100644 index 00000000..31d4240e --- /dev/null +++ b/_minutes/2024-09-26-wecg.md @@ -0,0 +1,175 @@ +# WECG Meetings 2024, Public Notes, Sep 26 + + * Chair: Simeon Vincent + * Scribes: Rob Wu + +Time: 8 AM PDT = https://everytimezone.com/?t=66f4a400,384 +Call-in details: [WebExtensions CG, 26th September 2024](https://www.w3.org/events/meetings/a97adab8-e1ae-4a2b-85cf-e6b6d3d35f00/20240926T080000/) +Zoom issues? Ping @zombie (Tomislav Jovanovic) in [chat](https://github.com/w3c/webextensions/blob/main/CONTRIBUTING.md#joining-chat) + + +## Agenda: [discussion in #686](https://github.com/w3c/webextensions/issues/686), [github issues](https://github.com/w3c/webextensions/issues) + +The meeting will start at 3 minutes after the hour. + +See [issue 531](https://github.com/w3c/webextensions/issues/531) for an explanation of this agenda format. + + * **Announcements** (2 minutes) + * TPAC is in full swing! + * **Triage** (25 minutes) + * [Issue 695](https://github.com/w3c/webextensions/issues/695): documentUrl and documentOrigin should be just url and origin in runtime.getContexts and be defined for the worker context + * [Issue 694](https://github.com/w3c/webextensions/issues/694): [DNR] in contrast to webRequestBlocking, declarativeNetRequest rules are not applied if the request is redirected #694 + * [Issue 693](https://github.com/w3c/webextensions/issues/693): Add API to switch focus from sidePanel to main document to enable accessibility features + * [Issue 692](https://github.com/w3c/webextensions/issues/692): Addressing auto-sizing of extension UI (options, popup, sidepanel) + * [Issue 687](https://github.com/w3c/webextensions/issues/687): Proposal: Targeted Permissions + * [PR 690](https://github.com/w3c/webextensions/pull/690): Proposal: add cookies.removeAll() method + * [PR 691](https://github.com/w3c/webextensions/pull/691): Multiple User Script Worlds proposal polish + * **Timely issues** (30 minutes) + * TPAC Recap (so far) ([wiki](https://github.com/w3c/webextensions/wiki/TPAC-2024-Coordination)) + * **Check-in on existing issues** (0 minutes) + * N/A + + +## Attendees (sign yourself in) + + 1. Simeon Vincent (Mozilla) + 2. Oliver Dunk (Google) + 3. David Johnson (Apple) + 4. Timothy Hatcher (Apple) + 5. Elijah Sawyers (Apple) + 6. Kiara Rose (Apple) + 7. Rob Wu (Mozilla) + 8. Mukul Purohit (Microsoft) + 9. Carlos Jeurissen (Jeurissen Apps) + 10. Mike Selander (1Password) + 11. George Henderson (Capital One) + 12. Tim Heflin (Keeper) + + +## Meeting notes + +Intro + + * [simeon] Today is a different session than usual; we'll do an issue triage like usual and then check in with what has happened at TPAC so far. + +[Issue 695](https://github.com/w3c/webextensions/issues/695): documentUrl and documentOrigin should be just url and origin in runtime.getContexts and be defined for the worker context + + * [simeon] toph argues that the “document” prefix is redundant, and that it should be dropped. + * [timothy] I'm usually in favor of not being redundant in APIs. + * [oliver] In principle that seems to make sense. Not sure what we'd do in chrome. Wouldn't like to have both. + * [simeon] Suggestion was to alias to the new names. + * [rob] Currently only extension contexts are returned. During design, we also accounted for content scripts. In that case url would be ambiguous and documentUrl would be clear. SWs don't have a meaningful URL save for the entry point. Don't see much value in this change. + * [timothy] Has Firefox shipped getContexts? + * [rob] Yes, Firefox has shipped getContexts() already. + * [simeon] Also leaning towards opposed. + * [timothy] Mostly leaning towards neutral since we haven't implemented it. + * [oliver] Are we aligned with closing it? + * [rob] Yes. + * **Resolution**: Close, consider changing in next manifest version if any. + +[Issue 694](https://github.com/w3c/webextensions/issues/694): [DNR] in contrast to webRequestBlocking, declarativeNetRequest rules are not applied if the request is redirected + + * [simeon] I think we discussed this yesterday. Rob, do you recall the next steps? + * [rob] I think Chrome was going to double check the intended behavior. + * [oliver] Yeah, we think this might be the intended behavior and webRequest was “wrong”. Will double check + * [rob] Wondering about XHR/fetch. Do redirects preserve headers? + * [simeon] Not sure. I think so but wouldn't bet on it. + * [rob] Preserving the header after a cross-origin redirect could result in inadvertent leakage of headers. Would especially be a problem for things like Authorization headers with sensitive auth tokens, injected through declarativeNetRequest.updateSessionRules. + * **Resolution**: Next steps are to test XHR, Chrome to double-check their intended behavior, and for someone to test cross-browser behavior. + +[Issue 693](https://github.com/w3c/webextensions/issues/693): Add API to switch focus from sidePanel to main document to enable accessibility features + + * [simeon] We discussed this during the in-person meeting earlier this week; Oliver summarized the outcome at https://github.com/w3c/webextensions/issues/693#issuecomment-2372499691 + * [oliver] The behavior[ @hanguokai](https://github.com/hanguokai) mentioned seems like a bug. We should look at ensuring the side panel takes focus from the page when it is first opened regardless of the mechanism used to open it. + * [oliver] We are supportive of implementing a tabs.focus() method which would return focus to the web content. This would close the popup if open and move focus away from other parts of the UI such as the address bar. + * [simeon] We are all supportive of this, as reflected in the label. + +[Issue 692](https://github.com/w3c/webextensions/issues/692): Addressing auto-sizing of extension UI (options, popup, sidepanel) + + * [carlos] Historically the viewport of a viewport is not designed by the web page, but the browser. Extensions are allowed to define the viewport in some cases (options_ui, popup, sidepanel). As an extension developer it is difficult to work with the browser and extension controlling the dimensions. + * [timothy] The scenario Carlos is referring to is when a page is used in a tab, in a popup, etc. A potential solution would be to support a media query to control styles dependent on auto-sizing. I think that it would be useful. + * [oliver] Don't recall if Chrome's options UI has autosize behavior. + * [rob] Yes it does, and sometimes it runs off the screen. + * [oliver] To confirm, the auto-size media query doesn't exist today. + * [carlos] Correct, this would be a new capability to handle this and similar cases. + * [timothy] Options page is strange too - in Chrome it is embedded in a subview, in Safari it is a tab. + * [carlos] And sometimes only one of the width/height can be controlled by the extension. + * [carlos] (...) autosize side bar. + * [timothy] Not sure about that. + * [oliver] I don't think that we would want autosize of sidepanels in Chrome. + * [simeon] When I discussed this with Devlin, he expressed the desire that this be solved at the web platform level rather than just extensions. + * [rob] Now that you mention it, I recall discussing something like this before + * [carlos] I believe we verbally discussed it ~2 years ago. Setting a fixed height can result in auto-size leading to two scrollbars. + * [rob] How do you address this today? + * [carlos] A bunch of hacks. Too obtuse to expect other developers to implement. E.g. 600x600, and if the viewport is below 600 and the width is above, then apply the full size. But if that is done before the page is fully loaded, the popup will be super small. Sometimes the scrollbar adds something to the width/height. + * [rob] Recently saw a Firefox bug report that turned out to be a bug by the extension not accounting for zoom level. How would you account for that here? Would be nice to have zoom behavior specified more clearly. + * [simeon] Sounds like we are all supportive. + * [rob] Supportive here means open to improvements. There is no concrete suggestion here. + * [rob] Emilio (from Mozilla) commented on the issue. He is also here in person during TPAC this week. Are there Google folks working on layout/CSS and also here? Perhaps we can set up a meeting to discuss this topic. + * [oliver] Rachel Andrew from the CSS Working Group is at TPAC. I'll see if we can set something up or I can at least get some thoughts. + * **Resolution**: Open to further discussion. Current path we want to explore is working with CSS WG on an auto-size media query. + +[Issue 687](https://github.com/w3c/webextensions/issues/687): Proposal: Targeted Permissions + + * [simeon] Targeted Permissions request is aimed at narrowing the permissions that the extensions have to request so that they don't have to request access to powerful permissions to access only a part of an API namespace. E.g. general capabilities in the history API is to delete entries, whereas entries with privacy controls are getVisits(). + * [rob] History may not be a great example. Users would likely be surprised and disappointed if the extension deletes their full history. + * [oliver] General idea sounds useful, we'd be neutral on this. + * [] On a case-by-case basis. + * [rob] We use namespaces to group functionality, but also true that several capabilities exposed on namespaces are not unsafe. For example, download.download. It's possible to trigger a download on the web by creating a download anchor and triggering a click on it. See that we could expose more functionality without having to request dangerous permission. Another example is webNavigation. Would be nice to observe navigations that you have permissions to without having to request a new permission-with-warning. + * [timothy] And also getFrames(). + * [rob] Hmm, perhaps for webNavigation we should just drop the warning. + * [simeon] I have wanted to use webNavigation many times in the past and have avoided it because of the permission warning. + * [rob] Same. + * [carlos] Same. + * [timothy] Are we aligned on dropping webNavigation warning? + * [simeon] We have a session on permissions later today, perhaps we can cover it there too. + * [timothy] Let's table for later today. + * [rob] Note that TPAC meeting notes will be published later. + * **Resolution**: Will be discussed more at a dedicated session later today at TPAC. + +[PR 690](https://github.com/w3c/webextensions/pull/690): Proposal: add cookies.removeAll() method + + * [simeon] Aaron from Google opened a proposal to add cookies.removeAll(). I don't have a lot of context, do you Rob? + * [rob] Ran into Aaron yesterday and discussed the context for the request. He was working on a unit test in the context of cookie partitioning (CHIPS) and noticed that remove() removed more cookies than expected, and fixed that. He saw utility in removing multiple matching cookies at once and opened a bug report. + * [rob] I noted that this is not unique to CHIPS. I reported a bug a couple years ago that remove() removed more than expected in Chrome. + * https://issues.chromium.org/issues/40572551 + * [rob] The API is supposed to return a descriptor of the matched cookie by design (as indicated by its return value), but in reality Chrome may remove more than one cookie. Partition key isn't the only way to match multiple cookies. A cookie's “primary key” is composed of multiple properties, but the cookies.remove() API does not accept enough properties to precisely match one cookie. + * [timothy] What cookie should be removed when the parameters to cookie.remove() match multiple cookies? + * [rob] Unspecified. In Firefox we iterate over matching cookies and remove the first match. In Chrome it removed all matching cookies, but Aaron changed this to match fewer cookies when partitioning is involved. + * [timothy] I don't know what we would do. + * [rob] Would be useful to specify the behavior more clearly to aid in interoperability. Aaron was working on this primarily due to cookie partitioning, not clear if he would work on improvements here. Oliver, thoughts on how to handle this? + * [oliver] Only concern is that it could be a breaking change. “Best match” sounds best. + * [timothy] Right, like Rob said we don't have info to make a better match. + * [rob] I analyzed this 7 years ago, and removing one would be compatible (and usually expected) by extensions. See “4. Analysis of API usage by extensions in the wild.” at https://bugzilla.mozilla.org/show_bug.cgi?id=1387957#c9 + * [oliver] Open discussion on the proposal cookies.removeAll() with an empty object, would the default behavior be to delete everything? I suggested we require a url property. + * [timothy] I'm in favor of requiring at least some filter. For example, removing a tracker cookie with a known name across all domains. + * [oliver] Yes, makes sense. + * [rob] Agreed. + * [simeon] If you want to remove all, would you provide a url with a broad host permission pattern? + * [oliver] You can already use the browsingData API. + * [mukul] The proposal is to have a separate API, we can consider new options. + * `cookies.remove(filter, )` + * [oliver] A potential issue is return type. + * [rob] Wouldn't make it an option. Can already be confusing. Matches the pattern of get & getAll. remove and removeAll would be symmetrical. + * [oliver] Does the proposal not mention the return type? + * [rob] That is feedback that I already put there. + * [oliver] My expectation is an array of removed cookies. + * [rob] Wonder if we should not return deleted cookies as it would be more optimal from the DB perspective. If they wanted the cookies, they could do getAll first. But that would require both methods to have the same semantics. We can have some specific exceptions, such as not accepting an empty object as discussed before. getAll has some special handling for partitionKey that primarily serves backwards-compatibility purposes, but is odd from the API design perspective. Since removeAll() is new, we could consider different behavior for partitionKey: getAll() currently matches unpartitioned cookies only when partitionKey, removeAll could match all cookies (including partitioned cookies) if partitionKey is omitted. + * [oliver] In Chrome the data that is easily available is the number of deleted cookies. + * [timothy] In Safari, we would likely have to do a get before a remove. We can easily return the results without extra work. + * [rob] In Firefox we also query before removing. + * [rob] Let's revisit this issue in the future once Aaron has updated the PR. + +[PR 691](https://github.com/w3c/webextensions/pull/691): Multiple User Script Worlds proposal polish + + * [simeon] Small PR that I created; small polish to clarify text in the proposal. I also realize that I don't understand the term “function signature”. + +Closing words + + * [simeon] We planned to talk about TPAC, but we have spent all time discussing issues. We will discuss the outcomes of this week later. + * [rob] And link the meeting notes from https://github.com/w3c/webextensions/issues/659. + * [oliver] For people interested in joining TPAC, where could they join now? + * [simeon] Wiki page with up-to-date schedule: https://github.com/w3c/webextensions/wiki/TPAC-2024-Coordination + * [simeon] The work-in-progress notes are linked from the Agenda section of the TPAC 2024 coordination page. We'll get the notes polished and publish after TPAC. + +The next meeting will be on [Thursday, October 10th, 8 AM PDT (3 PM UTC)](https://everytimezone.com/?t=67071900,384) diff --git a/_minutes/2024-09-27-wecg-tpac.md b/_minutes/2024-09-27-wecg-tpac.md new file mode 100644 index 00000000..21b92481 --- /dev/null +++ b/_minutes/2024-09-27-wecg-tpac.md @@ -0,0 +1,683 @@ +# WECG TPAC Sep 27, 2024 + + +## Agenda + +Friday: https://github.com/w3c/webextensions/wiki/TPAC-2024-Coordination#friday + + * 09:00 - 10:15 + * [75 min] WebExtensions integration into Web Platform Test + * 11:00 - 12:30 + * [90 min] Issue triage + * 14:00 - 17:10 + * [130 min] wpt testing + * 17:10 - 17:30 + * [20 min] Spec Discussion + + +## Attendees + + * Rob Wu (Mozilla) + * Christos Bacharakis (Eyeo) + * Timothy Hatcher (Apple) + * Kiara Rose (Apple) + * David Johnson (Apple) + * Elijah Sawyers (Apple) + * Simeon Vincent (Mozilla) + * Mukul Purohit (Microsoft) + * Devlin Cronin (Google) + * Carlos Jeurissen (Jeurissen Apps) + * Oliver Dunk (Google) + * Jordan Spivack (Capital One) + * Casey Garland (Capital One) + * George Henderson (Capital One) + * Tomislav Jovanovic (Mozilla) + * Mohamed Elgendi (Malwarebytes) + * Panos Astithas (Google) + * Aaron Selya (Google Chrome) + + +## Notes + + +### WebExtensions integration into Web Platform Test + + * [oliver] Patrick has a branch with some web-platform-tests work: https://github.com/web-platform-tests/wpt/compare/master...patrickkettner:web-platform-tests:webextensions + * [oliver] WIP for the tests in the runtime namespace, and how to load extensions in Chrome to load an unpacked extension via the CDP. Has restrictions to connect to Chrome in a special way that WPT does not use. We should fix the Chrome command so it works in WPT. + * [simeon] Are the changes ready to review? + * [oliver] https://chromedevtools.github.io/devtools-protocol/tot/Extensions/#method-loadUnpacked + * [oliver] You pass a path you want to load. + * [simeon] This is not the base64 zip? + * [oliver] No. I'm not sure if we need that. The driver can write to a temp file and pass the path. + * [simeon] [tries and fails to find source to see] + * [oliver] Should we go back to loading with the command line flag, then explore DTP / BiDi commands. + * [simeon] Seems reasonable. We can crawl, walk, run here. + * [oliver] Would be good to move forward, and have smaller PRs. That is about all I have for the Chrome side. + * [simeon] Safari folks? Do we have a way to do this? + * [kiara] We have a way we can hook up here. + * [simeon] Would it be possible to make this available publicly now? + * [kiara] What we can do it have some type of detection, and allow it. + * [timothy] This is something we will likely get in STP soon. + * [simeon] \*A wild Rob appears.\* + * [rob] I'll join in person for the next meeting. + * [simeon] Where is Firefox for integration with WPT? + * [rob] Tom worked on it mostly. I will check. From the protocol perspective, it is all doable. We have everything we need to do it. + * [simeon] So what are next steps? + * [oliver] If we merge the branch Patrick has, I can maybe do that for the Chrome side. Do the WPT folks know this is coming? + * [simeon] They are part of the Browser Tools and Testing team? + * [panos] They are aware, I am here observing. + * [simeon] We do have a branch in progress from Google. + * [oliver] I can work with Patrick and update the PR. We should all look at the WebDriver BiDi patch too. + * [rob] Does Patrick's patch build upon WebDriver-bidi? + * [oliver] Right now using Chrome Devtools Protocol. + * [simeon] At least with load unpack at launch we can start and switch over to dynamic loading later. + * [oliver] What WPT does in general - I think I spoke with Maxim - they are currently not working on WebDriver-bidi but that is a P0 top priority that they are working on. Rob, did you say someone from Moz is willing to implement the BiDi PR? + * [rob] Yes, a Moz contributor is interested in implementing this. + * [oliver] Safari folks, you're open to this as well? + * [timothy] We will with our folks more familiar with the WebDriver stuff to implement the classic approach - expect it to be straightforward. + * [simeon] Next step? + * [timothy] Test with runtime.getURL(). + * [simeon] Wanting to flesh out the shape of the tests. Maybe pair programming later today? + * [timothy] We have not talked yet about how this should look like internally. E.g. browser.test namespace for asserts, or adopting the wpt harness. + * [simeon] Is browser.test extension-specific? Or wpt? + * [timothy] Extension-specific namespace that Firefox, Chrome and Safari have, with testing utilities such as assertTrue, . + * [rob] This namespace was originally from Chrome. There are some minor differences, such as assertDeepEqual vs. checkDeepEq. We should specify more specifically what we expect these utilities to do. + * [simeon] If we don't have a set of common capabilities, should we lean more on WPT infrastructure? + * [timothy] The reason for considering this is that our internal tests are already writing these are already using browser.test. + * [rob] To be clear, there is a lot of overlap between browser.test implementations. If there are differences we can fix them up, run tests and fix up failing tests if any. No external consumers of that namespace. + * [kiara] I'd also lean towards preferring browser.test. + * [timothy] Agree that there's enough overlap that we could use it relatively easily. + * [kiara] How do we handle chrome.test vs. browser.test? + * [oliver] Maybe we can just use browser.test? + * [timothy] We have a special test mode that we can run, it adds the browser.test namespace, reduces timer constraints for browser.alarms, etc.. + * [oliver] Thinking we'd use our existing method names from the browser.test namespace and under the hood use WPT implementations. + * [timothy] Was thinking of that too - a stub that basically does what the browser does internally. + * [simeon] What are the next steps for browser.test? + * [timothy] Sit down and look at the differences. + * [rob] Is safari's browser.test part of WebKit? + * [timothy] Yes. + * [rob] That means all test implementations are open source. Should be easy to see what they're doing. + * [kiara] Link to browser.test IDL and implementation: + * IDL Interface: + https://github.com/WebKit/WebKit/blob/68dd7315eb68b5df3a07786e5a59ab7f1f7085dc/Source/WebKit/WebProcess/Extensions/Interfaces/WebExtensionAPITest.idl + * Implementation: + https://github.com/WebKit/WebKit/blob/68dd7315eb68b5df3a07786e5a59ab7f1f7085dc/Source/WebKit/WebProcess/Extensions/API/Cocoa/WebExtensionAPITestCocoa.mm + * [rob] Chrome's implementation of chrome.test + * API schema: https://source.chromium.org/chromium/chromium/src/+/main:extensions/common/api/test.json;drc=abe36fd704986c2e4f54b4bd35c291d6beb0e28c + * Implementation: https://source.chromium.org/chromium/chromium/src/+/main:extensions/renderer/resources/test_custom_bindings.js;drc=abe36fd704986c2e4f54b4bd35c291d6beb0e28c + * [rob] Firefox's implementation of browser.test: + * API schema: https://searchfox.org/mozilla-central/rev/9fa446ad77af13847a7da250135fc58b1a1bd5b9/toolkit/components/extensions/schemas/test.json + * Implementation: https://searchfox.org/mozilla-central/rev/9fa446ad77af13847a7da250135fc58b1a1bd5b9/toolkit/components/extensions/child/ext-test.js + * [timothy] Regarding browser vs. chrome, I expect that all of our tests will need to do `globalThis.browser ??= chrome` for now. + * [rob] Would we prefer to import a shared file that includes the namespace alias? That would allow us to include other common utilities as well. + * [timothy] I'm sure we would. Makes sense. + * [simeon] Question about internal timers, time-based operations. How do we fake that? I assume we don't use wall clock time? + * [timothy] We do. That's why we relax the timer constraints of the alarms API. + * [rob] I don't think that any browsers fake the time. Running faster/slower can have side effects. In Firefox we increase / decrease the timers as needed. + * [oliver] Looks like in some chrome tests we adjust test timers in some cases. For example, advance time by one second. + * [rob] We have something similar in Firefox that provides more precise control in specific tests. But translating that to WPT tests is likely difficult. + * [simeon] Anything else we need to work through? + * [rob] Do we expect to run all assertions inside the tests? That's what WPT requires. In Firefox we have asserts that are outside the extension of the test itself. E.g. in cases where there are no extension contexts. + * [timothy] We run most of our test logic in background scripts. If it does suspend, that's useful as well. + * [rob] If you want to test that a background suspends after a reasonable amount of time, you cannot wait for that condition and do the check in the background script. You need another context to monitor and react. + * [timothy] In testing mode we reduce our BG suspension time down to 3 seconds from 30 so we can exercise it more. + * [rob] Just for that test? Imagine that could cause issues with other tests. + * [timothy] That length seems to be a good balance between normal expected behavior and faster execution. + * [rob] Sounds like we may want some utilities for these specific situations. + * [timothy] Could hang a setter on browser.test. + * [simeon] Parallelization concerns? + * [timothy] Could impact. + * [oliver] Could we defer those sorts of tests until we have more API tests? Could see having a new WebDriver BiDi command to change SW timeout. + * [rob] Agree with that. We should consider these capabilities in the design phase. If we hang a lot of utilities, the may not be available everywhere. + * [timothy] We expose the utilities everywhere. + * [rob] We don't. In Chrome and Firefox, the test namespace is only exposed in extension contexts. + * [timothy] They are browser utilities for us, but we expose them to the main world. They're not used outside of extensions use cases today. + * [rob] Open question is whether we should expose them in the main world as well. + * [oliver] Asking Devlin is probably best. If we're exposing them in WPT utilities, we can decide where we want to expose them in that interface. + * [rob] What is the preferred direction for WPT specific utilities? Can tackle this when we hack something together. + * [timothy] depends on how many tests we're doing. It would be ideal if the majority is drag and drop rather than find/replace from assert1 to assert2. + * [rob] Makes sense to have the test utilities behave identically. Would also be nice to have names of similar length for formatting purposes. + * [rob] Concrete next steps? + * [oliver] Have some called out earlier in the notes. + * [rob] WPT folks, any opinion on how the utility should look? + * [panos] If things are more consistent with what you already have, would be easier to review and accept what you have. Preference would be as seamless an integration as possible, but if you get a lot of value from the current differences, that's not a deal breaker. + * [rob] Does “seamless integration” imply following the conventions of wpt or conventions or conventions that browsers are already following? + * [panos] Preference would be following the conventions of WPT. + * [rob] Test APIs. Extension's browser.assert vs wpt's assert_equals. + * [oliver] Example: https://source.chromium.org/chromium/chromium/src/+/main:chrome/test/data/extensions/api_test/omnibox/test.js;l=35;drc=dd9f87319822765342f2e9ba7e32a3034bdb3260 + * [timothy] These would already work in Safari today - I see utility in copy-pasting without rewriting or rethinking. We have 400+ tests that use this syntax, that we could easily move over without much syntax. + * [panos] Concern is if someone familiar with web and wants to add a test to extensions, that the test APIs are different. That having said, there are already wpt tests that are different. Personally I could be convinced that extension tests can use browser.test, but others on the wpt team may differ. + * [simeon] What would be the best way to ask? + * [panos] Yes. This should be the consultation that happens as part of opening the PR. We have at least monthly meetings where we go over these. + * [simeon] When are these meetings usually held? + * [panos] Tuesday 8am pacific. + * [timothy] We usually use 8am on Thursdays; would work for us. + * [rob] Can you drop a link with information about joining these meetings? + * [panos] Don't have that information on hand. We can invite any of you if you'd like. Do you want to join the next one soon, or after the PR? + * [rob] We can work on the PR first (potentially today) and then get to you. Since you are aware of the ongoing discussions, if you have any strong opinions already, please reach out to us internally. + * [panos] Next Tuesday at 8am we have another session. Also have a channel on Matrix, https://matrix.to/#/#wpt:matrix.org + * [simeon] I'd suggest we aim for the session after that. + * [panos] Next session after that is November 5th. + * [rob] Sounds good. + * [simeon] Would it be useful to schedule some check-ins before then? + * [kiara] Yes. + * [simeon] We can work out the specific times later, tentatively thinking 8AM on a day other than Thursday. + * [rob] Any questions that might block us from prototyping in the afternoon? Safari folks, are you available to hack on this in the afternoon? + * [timothy] Kiara and Elijah can work on it. + * [rob] Oliver do you know if Patrick is available? + * [oliver] Not sure. We're good to prototype, though. + * [rob] I'll check with Tom. + * [rob] Let's do a hackathon today; objective is to have a runtime.getURL() test running across browsers. + + +### Issue Triage + + +#### Candidates for Discussion + +**Criteria:** + + * **Issues should be things we can discuss and make progress on in 5 - 10 minutes** + * **Goal is _triage_, not necessarily completion or resolution** + * **Candidates types** + * **Determining general browser supportiveness for small - medium issues** + * **Updating labels on existing issues (e.g., marking as implemented)** + * **Closing out issues that are fixed or WontFix** + * **Avoid** + * **Discussions of entire new API namespaces (unless proposing we WontFix them)** + * **Fundamental changes to the platform** + + +#### Discussed issues + + * (no issue) ttsEngine + * [oliver] Quick FYI: Updates to [chrome.ttsEngine](https://developer.chrome.com/docs/extensions/reference/api/ttsEngine). Checking there's no interest from other vendors. + * [devlin] Chrome has two text to speech APIs. There's chrome.tts and chrome.ttsEngine. tts invokes the speaking, ttsEngine performs the speaking. Chrome needed to provide more features for engine in order to support adding new languages on the fly. Adding this for reading mode and being added to the public API for its general utility. Callers will be able to request new languages via tts API and ttsEngine will be able to download the appropriate resources in the background. AFAIK we are the only implementers of this API. Anyone else interested in this capability? + * [timothy] No + * [tomislav] We are working on genAI experiments, one of them might be a ttsEngine. Probably not through this API for now. + * [rob] Would like to follow up internally about interest in exposing this, and if yes, whether it would be through the ttsEngine extension API. + * [devlin] Oliver, is there much functional difference between the extension and web APIs? + * [oliver] I don't know off the top of my head. + * [devlin] ttsEngine might make sense in the world where other browsers want to enable custom voices. + * [timothy] May not in a world with [Web Speech](https://developer.mozilla.org/en-US/docs/Web/API/Web_Speech_API)? + * [devlin] TTS engine may make sense, but tts may not. + * [timothy] is this used by many extensions? + * [devlin] No, there aren't many but the ones that are there are important. + * [carlos' computer] TEST. + * [carlos] The web speech API works in a service worker. + * [Issue 683](https://github.com/w3c/webextensions/issues/683): Feature request. More granular Extension's hotkeys scope + * [devlin] No. I don't think that scoping to tabs makes as much sense to hotkeys in general. Content scripts would probably make more sense. Do think we should do more with commands: toggling enabled state, allowing commands to be defined outside the manifest, etc. But this capability seems like it would have relatively little utility for a good amount more complexity. + * [oliver] Concerned about UI complexity? + * [devlin] Agreed. + * [timothy] Agree that commands could use more love. Firefox has some capabilities like the ability to change shortcuts at runtime. + * [rob] … I see use cases such as being able to invoke even when tab content area isn't focused. + * [oliver] Everyone in favor of closing when we have a comment? + * [timothy] Yes. + * [devlin] Yes. + * [rob] Should we address my last comment? + * [devlin] Would make sense to expose an API, isCommandEnabled. + * [rob] User could customize the commands. + * [devlin] If there's a single extension that uses ctrl+cmd+shift+g users can figure that out. + * [rob] Not concerned about that. + * [carlos] Seems more user facing to solve in the browser UI rather than in extensions. + * [timothy] We've solved more or less in browser UI. + * [devlin] Letting an extension know if a command is enabled makes sense + * [rob] Should we expose in an event? + * [devlin] Would make sense. Should table for now. + * **Resolution**: Close + * devlin to add comment and close out + * [Issue 639](https://github.com/w3c/webextensions/issues/639): i18n.getMessage() pluralization + * [devlin] Solved with message format 2, right? + * [timothy] Agreed. + * [devlin] Even messages TC39 proposal for Intl.MessageFormat. + * [oliver] Close in favor of issue 698? + * [devlin] Yes. + * **Resolution**: Close, the work will be tracked by [issue 698](https://github.com/w3c/webextensions/issues/698). + * [Issue 640](https://github.com/w3c/webextensions/issues/640): Proposal: Remove multiple bookmarks in bookmarks.remove() + * [devlin] No objections. Not fond of options (e.g. string | strings[]) but makes sense in this context. Performance benefits and race condition benefits to making this a single operation. + * [rob] What would the race condition be? + * [devlin] If it's an atomic operation you can be assured that you will remove all of them at once. + * [rob] Would we specify this to be atomic? Either all or nothing. + * [devlin] That's not a part of triage ;) Good question. Inclined to say we'll do our best and it's okay to have partial removal. If you ask to remove 50 and we only remove 49 because one was already removed, that's acceptable. + * [timothy] We don't support bookmarks yet, but this would be preferable for us as we use a DB for bookmarks. + * **Resolution**: Everyone supportive of the ability to remove multiple bookmarks at once. + * [Issue 615](https://github.com/w3c/webextensions/issues/615): userstyles support + * [rob] TL;DR is request to add support for registering CSS in the scripting/userScripts API. + * [timothy] duplicating something already in scripting... + * [devlin] So we have file support for registering stylesheets in scripting.registerContentScripts, but not arbitrary css code. Supportive of adding this, but through the scripting API. We do not need to add it to the userScripts namespace since the scripting namespace already accepts arbitrary CSS code in scripting.insertCSS. + * [rob] So to recap, we are all supportive of supporting arbitrary stylesheets through scripting.registerContentScripts, but not in the userScripts API. + * [devlin] Correct. + * [timothy] Yes. + * **Resolution:** Add support for registering user styles to the `scripting.registerContentScripts()` method. + * [Issue 624](https://github.com/w3c/webextensions/issues/624): Proposal: getLeafTarget() method + * [oliver] When discussed, both Firefox and Safari were supportive. I chatted with Devlin, and wonder whether this could be added to the web side, with an extension-only option to opt in to closed shadow roots. I spoke to one of the Dominics on the Chrome side, and there is an expectation that we would encounter strong opposition to adding this to the web platform. Someone from Apple had similar reservations. + * [devlin] Do we need to add something? Is there a reason where we want event.getComposedPath() to not include shadow roots? + * [rob] Web compatibility. A web API behaving differently in a web page vs content script could be surprising. + * [devlin] That seems okay to me. + * [oliver] Returning more elements than expected seems okay. + * [devlin] We should discuss this more. Making this work with compose path would be preferable. + * [rob] Should we require a manifest key for that? This is a strong deviation from the web platform, which assumes that shadow DOM is generally invisible. + * [devlin] Do you feel strongly about piercing shadow roots? + * [rob] Don't want to set the precedent of changing behavior of existing web APIs. Documentation story can become very complicated. If we have a manifest key, at least we have something specific we can point to that changes web APIs in a specific way. + * [devlin] Okay, so we would need some sort of mechanism. + * [rob] Yes. And I'd prefer to have a flag to change the behavior. + * [oliver] I'd feel weird about having an extension changing web behavior. + * [devlin] Yeah, would prefer a property passed into the function call. Agree with Timothy that we collectively need to get over hesitation of extension specific functionality. + * **Action item**: Oliver to follow up with Chrome to see the preferred approach. + * [Issue 658](https://github.com/w3c/webextensions/issues/658): Proposal: API to allow incognito access + * [devlin] No. I can see the utility and understand the rationale for the request, but this is a capability that we want to keep behind user initiation and to make it harder for extensions to socially engineer access to. + * [timothy] Agreed. + * [simeon] Checking if you have permission? + * [devlin] We already have a way to do that. + * [devlin] Any objections to closing issue 658 as wontfix? + * [rob] No objection. + * **Resolution**: Close. + * Tom to close as WontFix with rationale + * [Issue 657](https://github.com/w3c/webextensions/issues/657): [MV3] Clarify browser inconsistency for temporary host permissions granted on extension click + * [simeon] Short version: we discussed but have not aligned on click-to-script behavior, the ability to restrict host permissions to extensions and only running scripts in response to interaction with the extension button. Like activeTab but different (forcing extension to be activeTab). What do other browsers think? + * [timothy] that also reloads? + * [devlin] Depends. When you withhold host permissions, things that would have injected don't. If you have things that inject at document start or end, we can't retroactively inject at those times. If you only have scripts that inject at document idle then we can inject at any moment. + * [timothy] We inject everything after the host permissions have been granted, without forcing to reload. + * [tomislav] We do the same. If a MV3 extension is not granted permissions, and the user enabled access, scripts are injected. + * [devlin] Main reason for this behavior is that we don't expect extensions to accommodate that behavior. We don't think that most extensions would do that. The only way to not have the extension break is to not do that. + * [simeon] When this capability was introduced, the concept of a requested host permission not being granted was foreign. Chrome had to take this approach then. + * [tomislav] And that predates Safari WebExtensions and Firefox's MV3. + * [timothy] We haven't had complaints about this. + * [rob] We haven't either. + * [devlin] I'd push back on this as this issue specifically says they need document start and they'd prefer Chrome's behavior. + * [rob] Majority of extensions don't care. + * [devlin] I don't think that's true. The default is idle. If you're specifying document start, there's a strong change there's a reason you have requested that point in the lifecycle. + * [rob] The extension could trigger a reload if they really wanted to. Every approach has disadvantages. Would be nice if extensions could specify their desired behavior in the manifest: only inject if at the run_at time, allow later injection, reload after permission change. + * [timothy] Supportive of a manifest key to specify the desired behavior. + * [devlin] Generally hesitant to introduce that level of behavior control to extensions. Not necessarily fundamentally opposed, but don't like it. + * [tomislav] If extensions prefer the behavior of Chrome, the extension could show a popup and tell the user to reload. The developer is in the best position to know their intent and prompt. + * [devlin] Expect that a single digit percentage of developers are considering these edge cases. They have already provided an explicit signal that they want to run early. + * [tomislav] Maybe they just want to run as early as possible, not explicitly at that moment. + * [devlin] Not entirely opposed to manifest key, but would not expect much usage either. + * [devlin] Extension could code to not rely on document_start. + * [tomislav] Maybe not rely. + * [devlin] I don't think so, but we don't have a way to prove this one way or the other. + * [rob] As an extension dev I often want to run as early as possible but it's okay if I don't, running later is better than nothing. + * [devlin] I think we have both groups: extensions that want to run early and its okay if they don't, and extensions that will break if they don't run before anything else. On the Chrome side, we want to optimize for not breaking the extensions as much as possible. We want users to be able to withhold host permissions. + * [rob] On the other side this breaks UX where the user installs the extension and the page doesn't behave as expected. + * [simeon] User could also do what they do and then choose to reload later. + * [timothy] We communicate to devs that they cannot rely on document_start. + * [devlin] At some point this is a browser decision and it's okay to not align. + * [devlin] In Chrome, activeTab applies while you are in the same origin while in the tab. + * [rob] Does this mean that the whole extension has access to the origin while the tab has not made a cross-origin navigation yet? + * [devlin] It has access to that origin in that tab. + * [tomislav] For us that's the concept of active script and active tab permissions. + * [tomislav] That is the behavior we aim for in Firefox. + * [timothy] We match the Chrome behavior. + * **Resolution**: Stickiness of “activeTab” is aligned. Different viewpoints on the tradeoffs related to script injection at document_start. No consensus on providing a way for an extension to specify the desired behavior in the manifest. + * [Issue 698](https://github.com/w3c/webextensions/issues/698): MessageFormat 2 support + * [oliver] Just confirming we are all happy with supportive labels here :) + * [devlin] Yes. + * [rob] Firefox also supportive. + * [timothy] Safari too. + * **Resolution**: Everyone in favor of MessageFormat 2 support. + * [Issue 645](https://github.com/w3c/webextensions/issues/645): Inconsistency: Commands API support for Cmd+Alt on Apple OSs + * [oliver] Had some discussion in Chromium. Someone at Microsoft is working on this. + * [devlin] If you specify Cmd+Alt as a mac specific shortcut but not the default, I think it works. Because it's a platform specific entry and no internal mapping of Ctrl to Command is necessary, I think this is handled correctly on Mac. + * [oliver] Just tested, doesn't work. + * [devlin] Well, we should fix that. Supportive of allowing mac-specific fields in the mac-specific fields (not in linux, windows, etc). + * **Resolution**: Chrome in favor of fixing (Firefox and Safari already implemented). + * [Issue 503](https://github.com/w3c/webextensions/issues/503): Ability to detect browser variant / fork + * [rob] Simeon, you reached out to other browsers. + * [simeon] They did not care. + * [oliver] Is Chrome supportive of runtime.getBrowserInfo? + * [devlin] In general returning names is fine. This relies on forks updating the name, not sure if they would do that. + * [simeon] I reached out to Arc and they didn't have an appetite for it. + * [devlin] Many forks deliberately mimic Chrome. + * [carlos] My impression is that this is less of an issue for extensions. + * [simeon] Could we take the name from the about page and return that? + * [devlin] No. We … + * [simeon] I assume there's a well-known string that identifies the browser. + * [timothy] What Simeon is saying is whether it can return something dynamically that is already defined in a fork. + * [aaron] There are also malicious reasons why some forks would want to pretend to be Chrome and Chromium as much as possible. + * [devlin] Would like to not return strings since it can be localized. What we could do is to return Chrome in Google Chrome and something else in Chromium. + * [timothy] We have a desire to return a browser name as well. Ideally something that forks would automatically expose the correct value. + * [rob] We cannot do perfect. What we can do is to have Chrome and Chromium, where forks can customize if needed. Firefox and Safari can also do something. + * [carlos] Would like an easier way to differentiate between browsers than parsing the extension's URL. + * [timothy] Why can it not be async. + * [simeon] Every extension API is async by default and only made sync when there's a compelling reason. + * [rob] On the web, feature detection sometimes requires synchronous execution. Do we want to support those cases? + * [devlin] If we are just looking at identifying which browser it is, we can make it sync. + * [timothy] We'd just have to send over that info synchronously on renderer start. + * [rob] In Firefox also feasible. Question is not whether we can, but whether we want/should. + * [devlin] I am okay with this being sync. I don't expect adverse impacts on future implementations. + * [rob] Since the existing getBrowserInfo() API is async, we would then have to introduce a new method. + * [devlin] Is getBrowserInfo() new, and widely used? + * [rob] getBrowserInfo() has been around for a long while and is used by at least hundreds of extensions in Firefox. + * [carlos] Name and vendor seems like they are likely to be different in forks. In other browsers it may make sense to have a hardcoded string for “Firefox” or “Safari” + * [devlin] Would that not be addressed by the name field? + * [timothy] No, Firefox Night, Firefox Developer Edition, etc. Vendor might make sense across forks. + * [devlin] that could change as well. + * [simeon] In the web equivalent of this API, “brands” can returns multiple fields. For example, “vivaldi” and “chromium”. + * [rob] Should we consult others that have more experience with “brands” on whether we should return a single or multiple values? + * [devlin] Could, but what benefit? + * [rob] For example, something that works in Chrome but not chromium. + * [devlin] Extensions could use navigate.userAgentData + * [rob] Right, in that case we can just return what it does not provide yet. + * [rob] Do we want this to be a method or a constant? + * [timothy] Method seems fine. + * [devlin] I can see it either way. Constant matches navigator.userAgentData better. + * [timothy] True. + * [devlin] Could also enable no name collision with Firefox's implementation, e.g. runtime.BROWSER_INFO (or runtime.browserInfo). + * **Resolution:** Everyone supportive of a constant exposing the info, next step is for someone to author a proposal. + * [Issue 653](https://github.com/w3c/webextensions/issues/653): API for extensions to exclusion/deny list their content scripts + * [devlin] This functionality is already provided through excludeMatches and excludeGlobs + * [oliver] The possible solution in the issue mentions (1) injecting into existing tabs and (2) unloading when a content script becomes excluded. We don't want to do (1) and (2) is not possible. + * [carlos] When content scripts are injected is different across browsers, at install time (whether to apply to already-injected tabs). + * [rob] For that topic we already have an issue tracking this ([issue 617](https://github.com/w3c/webextensions/issues/617)). How does that relate to the current topic? + * [devlin] Reason for excludeMatches being insufficient is that Chrome does not inject in existing tabs. We are unlikely to change that. + * [timothy] We do. Open to a property to control this, but in general would prefer the default to be inject into all tabs. + * [rob] Could add an option to do this, as suggested by 617. + * [devlin] Since 617 exists, inclined to close this. + * **Resolution**: Close this issue in favor of 617. + * [Issue 617](https://github.com/w3c/webextensions/issues/617): manifest key to enable automatic injection of content scripts after installation/update + * [devlin] Not opposed. + * [rob] Meaning neutral? + * [devlin] Yes. + + +## wpt testing + + +### Attendees + + * Rob Wu (Mozilla) + * Simeon Vincent (Mozilla) + * Tomislav Jovanovic (Mozilla) + * Kiara Rose (Apple) + * Elijah Sawyers (Apple) + * Devlin Cronin (Google) + * Oliver Dunk (Google) + * Carlos Jeurissen (Jeurissen Apps) + + +### wpt summary + +This is a summary of the agreed-upon direction from the wpt discussion, on the topic of the steps towards testing extension APIs in wpt across browsers (Firefox, Chrome, Safari). + + * We will use browser.test (probably with `globalThis.browser??=chrome` shim) in the extension contexts for now + * This will require exposing `browser.test` in these contexts in Chrome + * We can do this with a new commandline switch, only respected if the browser is automated + * (Firefox and Safari already expose the `browser.test` namespace) + * We need to introduce a new `browser.test` API to signal that the context is in a WPT (e.g., `browser.test.setIsWebPlatformTest()`). This then adjusts the behavior of test.notifyPass(), notifyFail(), succeed(), etc to pass the result to the WPT page rather than signaling in another way. + * This is per context, because it enables for easier initial implementation. Most tests would likely be one JS file anyway. When multiple JS contexts are involved (e.g. content scripts, then each context needs to call this method again. + * We will introduce an `extension_test` style test shim (in a JS file resource served from wpt) which will load the extension, wait for results + * Future areas of investigation and investment include: + * Using WPT assertions and success / failure indications directly. We are not doing this in the initial version because there's no good way to pass test bindings to the extension context (e.g. the `test_driver` object) + * Generated extensions to reduce boilerplate, require only one file per test (instead of multiple) + + +### wpt discussion + +Note: this session lasted 130 minutes and the minutes do not capture the full discussion due to the pace of the conversation and the fact that the scribes were busily participating in the meeting itself. Parts of the discussion are captured below, and a summary is available above in “wpt summary” + + * [rob] At least one from every vendor to work on getting wpt running. + * [tomislav] wpt may test service worker but always requires a web page to be present. + * [simeon] IIRC, Patrick's prototype has a web page where. + * [tomislav] Should we try to plug in the same system that they have - register for test harness events, shuffle it, and post to the main world? Many wpt tests have custom asserts / test functions. They are not strongly enforcing the use of wpt only utilities. + * [rob] They + * [tomislav] So do we want to use the existing browser.test namespace? + * [kiara] Yes. + * [devlin] Yes. + * [rob] Complication: browser.test is only available in extension contexts in Chrome, but it's available in the main world in Safari and Firefox. + * [oliver] Before that, the browser needs a way to communicate test results back to WPT. + * [rob] I think browser.test comes first. + * [oliver] Perhaps in parallel. + * [devlin] Perhaps we should first talk about what we want our WPT tests to look like and work backwards from there. + * [rob] Do you mean an empty JS or HTML file? + * [devlin] Let's say we start with a given extension. In Chrome I'd do something like: + +``` +constexpr char kBackgroundJs[] = + R"(const id = 'a'.repeat(32); + chrome.test.assertEq(id, chrome.runtime.id); + chrome.test.notifyPass();)"; + +IN_PROC_BROWSER_TEST_F(Foo, Foo) { + TestExtensionDir test_dir; + test_dir.WriteManifest(kManifest); // defined elsewhere + test_dir.WriteFile(FILE_PATH_LITERAL("background.js"), kBackgoundJs); + ASSERT_TRUE(RunExtensionTest(test_dir.UnpackedPath()); +} +``` + + * [devlin] In Chrome, that would be the entirety of our test file. + * [rob] I like minimizing the boilerplate. + * [devlin] WPT won't look like the above block as it uses Chrome- and Google-specific concepts. + +``` +// HTML + + + + + +//path/to/extension/dir/manifest.json +{ + "manifest_version": 3, + "version": "0.1", + "name": "runtime.id test", + "background": {"service_worker": "background.js"} +} + +//path/to/extension/dir/background.js +const id = 'a'.repeat(32); +chrome.test.assertEq(id, chrome.runtime.id); +chrome.test.notifyPass(); +``` + + * [oliver] Example of HTML from Patrick's branch: https://github.com/patrickkettner/web-platform-tests/blob/3f9e5bc002917bcf7ca331351f8e881c847e20ce/webextensions/browser.runtime.html + + * [] Example of referencing extension through meta tag https://github.com/web-platform-tests/wpt/commit/a216f40084db20012640e53913b8efc1d78fdb95#diff-218bc85625c42c5c7e3b2c64541584fedee32db01ec0dde4e0c49876b30343a5L3 + * <Missed a couple minutes of notes due to looking at source> + * [rob] Pausing on the HTML boilerplate, we could have a JS file, a module so that it supports top-level await, and run it to completion. + * [devlin] You might need to set up your listener before triggering other behavior. + +``` +chrome.tabs.onCreated.addListener((tab) => { + chrome.test.notifyPass(); +}); +chrome.tabs.create({url: 'http://exaple.com'}); +``` + + * [rob] That could work. I was thinking of something different. + +``` +const id = 'a'.repeat(32); +chrome.test.assertDeepEq({ ... }, await browser.runtime.getBrowserInfo()); +chrome.test.notifyPass(); +``` + + * [devlin] Shouldn't require `notifyPass()` at the end. For flexible code paths, it shouldn't be related to a specific function call or something at the end of the file. + * [rob] There's no explicit notification. + +``` +let done = new Promise(resolve => { + chrome.tabs.onCreated.addListener((tab) => { + resolve(); + } +}); +chrome.tabs.create({url: 'http://exaple.com'}); +await done; +chrome.test.notifyPass(); +``` + + * [devlin] Ugly + * [rob] Yes. Just discussing options. + * [devlin] That's not a linear flow. Line 3 executes after line 6. + * [rob] Semantics. Point is that the test file could be JS that defines a set of steps. + * [devlin] Don't know how many cases we wouldn't care about the extension context. + * [rob] By default we could assume the background and allow specific overrides. One complication is that in MV3 the background context could terminate, so that may not be an ideal default. + * [devlin] There may be too much customization that needs to happen for each test. + * [rob] The easiest way to load a test might be to declare a background key in the manifest. Is that right? + * [devlin] Depends on the test. Some in a background, some in an extension page, some in a content script. + * [tomislav] Patrick's test is modeled after basic WPT cases. WPT has other examples where there's a worker or other specialized context. I'm suggesting we start with a boilerplate-full approach that enables us to cover all of the use cases we want. In the future we can optimize. Search for .worker.js for examples. + * [rob] I don't see many examples of this. + * [tomislav] Most are .any.js. + * [rob] Example with async code and assertions: https://searchfox.org/mozilla-central/rev/837f3a1ff2622c8303750c35d84bdc41a5cd079c/testing/web-platform/tests/IndexedDB/blob-valid-after-deletion.any.js + * [tomislav] has META comments at the top - could specify extension manifest / permissions there. + * [tomislav] defined in https://searchfox.org/mozilla-central/rev/837f3a1ff2622c8303750c35d84bdc41a5cd079c/testing/web-platform/tests/IndexedDB/resources/support.js#114 + * [rob] Are Google and Apple onboard on such a syntax? I recall Apple expressing the desire for extension test resources to be put in the source tree. + * [kiara] The proposed single-file syntax looks good. + * [devlin] Something like this? + +Generated file version: +// test/runtime.js +``` +//// Might need: +// META: script-"support.js" +// META: permissions="foo,bar" +// META: script_type="service_worker" +//// Or, if you want: +// META: manifest="manifest.json" + +// In the future, we could avoid having extension_test() and build this support +// into the WPT runner, but for now, we essentially polyfill it. +extension_test( + function runtimeId() { + assert_eq('a'.repeat(32), chrome.runtime.id); + }, + function someOtherTest() { + ... + }, +); +``` +-> This generates an extension with a manifest like: + +``` +{ + "name": "test", + "manifest_version": 3, + "version": "0.1", + "permissions": ["foo", "bar"], + "background": {"service_worker": "service_worker.js"} +} +``` +And service_worker.js contains the test file above + +Non-generated file version: + +**test/runtime.js** +``` +// META: script-"support.js" +extension_test('path/to/extension'); +``` +**test/manifest.json** +``` +{ + "name": "test", + "manifest_version": 3, + "version": "0.1", + "permissions": ["foo", "bar"], + "background": {"service_worker": "runtime_worker.js"} +} +``` +**test/runtime_worker.js** +``` +chrome.test.setIsWPT(true); + +chrome.test.runTests([ + function runtimeId() { + chrome.test.assertEq('a'.repeat(32), chrome.runtime.id); + }, + function someOtherTest() { + ... + }, +]); +``` + + * [oliver] Rather than script_type="service_worker", that would be implied by the filename. + * [tomislav] Could be, yes. Depending on where you put this example, e.g. if you use .service_worker.js that's one thing, but if you use .any (or appropriate extension-specific variant) then that + * (... long discussion…) + * [devlin] So if the wpt test runner loads the script and executes as an extension, then we would not need a separate `extension_test` function. + * [rob] Example with plain “promise_test”. Also shows parametrization of tests: https://searchfox.org/mozilla-central/rev/837f3a1ff2622c8303750c35d84bdc41a5cd079c/testing/web-platform/tests/fetch/api/cors/cors-basic.any.js + * [devlin] In this case we're looking at modifying the wpt core runner to support this. How willing are they willing to modify this? + * [tomislav] We first need to show that we have all browser vendors participating in getting this up and running with tests before asking for any core WPT changes. + +// support.js +``` +// Generation version: +function extension_test(...tests) { + // 1. Read metatags from script file + // 2. Generate Manifest content based on metatags + // 3. Create temp directory <-- Is this possible? + // 4. Write Manifest content to temp_dir/manifest.json <-- Is this possible? + // 5. Write service_worker.js (in this case) with <-- Is this possible? + // stringified `tests`. + // 6. Load extension + // 7. Wait for signal of done-ness <-- What does this look like? +} + +// Non-generation version: +function extension_test(path) { + // 1. Load extension from `path` + await test_driver.install_unpacked_extension(path); + window.addEventListener("message", e => { // or CustomEvent, whatever. + // do something with e.data received from the browser. + // browser sends data here upon calling + // browser.test.notifyWPT() in the extension. + }, { once: true }); +} +``` + + * [devlin] Want to drill a little into signaling done-ness. + * [tomislav] Don't recall offhand. + * [devlin] Extension would have to signal and pass back to WPT runner, right? + * [tomislav] (_thinking)_ yes + * [rob] This would generate a lot of files. Another approach is to have unpacked extensions in a directory; each test can be a separate js file (with a corresponding auto-generated HTML page), and tests are loaded e.g. in browser tabs or iframes. + * [devlin] If we have the full extension in the repo, we don't need to generate anything. We just load the extension and wait for done-ness. + * [rob] But something needs to inject the WPT test utilities in the test contexts. + * [devlin] Initiating load – we have the ability to load the extension in that we (will all) have a WebDriver loader. + * [oliver] Here's an example of an any.js: https://searchfox.org/mozilla-central/source/testing/web-platform/tests/xhr/formdata/has.any.js + * `view-source:https://wpt.live/xhr/formdata/has.any.worker.html` + * (.... long discussion…) + * [rob] browser.test.notifyPass() could instruct the browser to look up the wpt document and send the results there. + * [] + * [devlin] What we want to do is to signal at the start of the extension code that this is an extension test, and that modifies the behavior of the test API so that assertXX/../notifyPass/notifyFail would forward everything to the wpt runner. + * [devlin] See no issues on the Chrome side to do this. + * [rob] Same. + * [kiara] Same. + * [tomislav] The above browser.test hookup with the browser are not needed for today's prototype - we can implement everything independent of the browser. + * + * [devlin] How browser.test bindings expose to release version of Chrome. + * Tentative proposal: + * New command line switch (--enable-chrome-test-api) + * Only works if the browser is automated + * [rob] Kiara, do you see this all as feasibly implementable in Safari? Specifically collecting assertions etc. in the browser.test namespace. + * [kiara] Yes. + * [devlin] + * [rob] Could expose `/_wpt/` that forwards any requests to a wpt server. + * [devlin] If needed, we could. + * [oilver] https://web-platform-tests.org/writing-tests/testharness-api.html#external-api + * [] + * [oliver] Do we use browser.test or chrome.test? + * [devlin] Chrome doesn't have browser, don't want to block on that. Could be solved by adding browser shim at the top of each JS file. + * Summaries + * (see wpt summary at the top of the wpt testing section) + + +# Spec Discussion + + * (No minutes for this section, only the conclusions are recorded in the notes) + * Principles + * We should specify things that are the same between browsers already (not wishful thinking) + * Agreed upon candidates for specification + * Concepts + * Extension Events (including the API) + * Maybe messaging, but with explicit gaps in e.g. message serialization + * Match patterns + * Content scripts + * APIs + * Permissions (this is relatively similar between browsers) + * Runtime (much of this is shared between browsers) + * runtime.id and runtime.getURL() + * not runtime.sendMessage / runtime.onMessage due to subtle differences (e.g. structured cloning vs JSON serialization). + * Commands (commands manifest key, commands.getAll(), commands.onCommand) + * Considered but rejected + * alarms (subtle timing differences, see existing WECG issues) + * dom diff --git a/_minutes/2024-10-10-wecg.md b/_minutes/2024-10-10-wecg.md new file mode 100644 index 00000000..ab87c748 --- /dev/null +++ b/_minutes/2024-10-10-wecg.md @@ -0,0 +1,150 @@ +# WECG Meetings 2024, Public Notes, Oct 10 + + * Chair: Timothy Hatcher + * Scribes: Simeon Vincent + +Time: 8 AM PDT = https://everytimezone.com/?t=67071900,384 +Call-in details: [WebExtensions CG, 10th October 2024](https://www.w3.org/events/meetings/a97adab8-e1ae-4a2b-85cf-e6b6d3d35f00/20241010T080000/) +Zoom issues? Ping @zombie (Tomislav Jovanovic) in [chat](https://github.com/w3c/webextensions/blob/main/CONTRIBUTING.md#joining-chat) + + +## Agenda: [discussion in #697](https://github.com/w3c/webextensions/issues/697), [github issues](https://github.com/w3c/webextensions/issues) + +The meeting will start at 3 minutes after the hour. + +See [issue 531](https://github.com/w3c/webextensions/issues/531) for an explanation of this agenda format. + + * **Announcements** (12 minutes) + * [TPAC recap](https://github.com/w3c/webextensions/commit/829852ef49cd8b2e1542e08381ec1ca94e7ef8b4) + * **Triage** (15 minutes) + * [Issue 698](https://github.com/w3c/webextensions/issues/698): MessageFormat 2 support + * [Issue 699](https://github.com/w3c/webextensions/issues/699): Allow object as second i18n.getMessage() argument + * [Issue 701](https://github.com/w3c/webextensions/issues/701): Block extension from specific hosts + * [Issue 702](https://github.com/w3c/webextensions/issues/702): Namespace for experimental APIs + * [Issue 703](https://github.com/w3c/webextensions/issues/703): State in background scripts, synchronously available across restarts + * [Issue 707](https://github.com/w3c/webextensions/issues/707): Request for Comments: Extension Performance + * **Timely issues** (10 minutes) + * [PR 690](https://github.com/w3c/webextensions/pull/690): ​​Proposal: add cookies.removeAll() method + * [PR 679](https://github.com/w3c/webextensions/pull/679): Proposal: dom.createPort() + * [PR 678](https://github.com/w3c/webextensions/pull/678): Proposal: dom.execute() + * **Check-in on existing issues** (10 minutes) + * [Issue 601](https://github.com/w3c/webextensions/issues/601): Proposal: StorageArea.getKeys() + * [PR 569](https://github.com/w3c/webextensions/pull/569): Proposal: i18n-system-languages + + +## Attendees (sign yourself in) + + 1. Oliver Dunk (Google) + 2. David Johnson (Apple) + 3. Timothy Hatcher (Apple) + 4. Simeon Vincent (Mozilla) + 5. Casey Garland (Capital One) + 6. Carlos Jeurissen (Jeurissen Apps) + 7. Mukul Purohit (Microsoft) + 8. Aaron Selya (Google) + 9. Jordan Spivack (Capital One) + 10. Maxim Topciu (AdGuard) + 11. Solomon Kinard (Google) + 12. Tim Heflin (Keeper) + + +## Meeting notes + +[TPAC recap](https://github.com/w3c/webextensions/commit/829852ef49cd8b2e1542e08381ec1ca94e7ef8b4) + + * [timothy] Second day we continued discussions on experimental APIs and held an issue prioritization session for small issues to help align browser vendor next steps with community interest. After that we had a lead session to discuss continuing to evolve the group. After the power outage, we did a backlog cleanup session and got through around 12 issues. + * [timothy] Wednesday was mostly breakout sessions. We didn't have any scheduled related to our group, but other breakout sessions were amazing. My favorite was the one about how we do the internet on the moon. + * [timothy] On Thursday we had our regular WECG meeting where we did a deep dive on Message Format 2 – what the format could look like, how we might integrate it into extensions, state of the standard and the fact that it should be available soon. It's currently polyfilled in Firefox. It's pretty impressive that we can potentially quickly adopt a message format with support for pluralization and other useful features. + * [timothy] Apple to create a proposal for declarative cosmetic rules. Later we attended a session with the browser tools and testing meeting WG to discuss how we'd tackle testing extensions in WPT. BiDi is the way forward, but we will likely need a compatible implementation with the current WebDriver system. After that we had a discussion about asynchronous background startup and state restoration. No firm conclusions from that discussion, but there was a broad range of options discussed. + * [oliver] Would be good to get a concrete proposal together. A lot of ideas were discussed, but we should try to dig into and advance one. + * [timothy] Next we discussed permissions. There are a number of scenarios where you don't know that you need a permission. One example was needing to provide your own deny list. Conversation was spread, so I'm light on details. That was it for Thursday. + * [timothy] On Friday we had a large morning session on testing. This discussion got into more details how how we integrate into WPT. After the Browser Tools and Testing sync, we discussed more details about transferring the extension over between test runner and test client. After that we did another 90 minute session for issue triage. I left after this, but there was one final sync on browser tools and testing. Aspects discussed included whether tests should be single file solutions, etc. + * [oliver] We had a final sync to discuss next steps on the spec. Picked out a couple of examples – small APIs where we felt we could specify common behavior. + * [timothy] Makes sense to focus on the smaller pieces. It was a very productive week. + * [simeon] Just want to say that I appreciate the way that we all work together. + * [timothy] Also appreciate how we run our meetings. I found the queue systems a bit difficult to work with. + +[Issue 698](https://github.com/w3c/webextensions/issues/698): MessageFormat 2 support + + * [timothy] This captures details that we discussed during the meeting. Looks like supportive labels are already applied. + +[Issue 699](https://github.com/w3c/webextensions/issues/699): Allow object as second i18n.getMessage() argument + + * [timothy] Came out of the messageFormat 2 discussion. Would be useful to provide an object rather than just an array. Would be nice to have named parameters. Allows for semantic names, more flexibility in how strings may be rearranged. + * [oliver] Had some discussion with Devlin. We are generally supportive of being able to specify the names of substitutions. Worth noting that other proposals conflict with this one. For example, providing a second parameter for a substitution language – how would that conflict with the ability to specify a language dictionary. Bears further discussion. + * [timothy] Again, I vote for live objects. + * [timothy] Was everyone supportive fo this idea? Please check labels. + * [oliver] Would maybe go neutral until we have a more updated proposal. + * [timothy] Could you add a comment about the discussion you had? + * [oliver] Can do. + +[Issue 701](https://github.com/w3c/webextensions/issues/701): Block extension from specific hosts + + * [timothy] If an extension requests access to all sites, there's no way to remove specific sites. If a host permission is declared in the manifest, there's no way to withdrawal it. The issue crater is essentially proposing a blocklist to add host permission patterns to block. We could support this, but curious for others thoughts. + * [oliver] I believe we've had concerns in the past, but don't recall details. Will need to follow up + * [timothy] Don't think every extension will use it, but extensions that want to block content on specific hosts would find it useful. + * [carlos] There were previous proposals to do this in the manifest. This is dynamic. Potentially less secure, but covers more use cases. + * https://github.com/w3c/webextensions/issues/123 + * [timothy] I don't have much concern since this would be reducing permissions rather than increasing them. + * [oliver] Might need to think through how this is presented to users. For example, if extension blocks access to bank.com users might assume that bank.com is safe, but the extension could still access coordinating sites. + * [casey] As a dev, if we could use it we would. We want to make sure we never track users on a number of sites. I expect we would enthusiastically use this. + * [timothy] Definitely worth considering. + * [simeon] We don't have to show every detail to the user. Even if there's no UI informing users that the extension is doing the right thing, good actors should use it + * [timothy] There would at least be a visual indication in Safari as the extension's action is grayed out when it doesn't have access on the current page. + +[Issue 702](https://github.com/w3c/webextensions/issues/702): Namespace for experimental APIs + + * [timothy] In short, we were all supportive during TPAC but we didn't come up with a name because naming is hard. Some proposed names were thrown around and were captured in the notes but not the issue. I think in the room at the time “unstable” was a favorite. I think Chrome is to use this first? + * [oliver] I believe Devlin is going to create a proposal in the next few weeks. + +[Issue 703](https://github.com/w3c/webextensions/issues/703): State in background scripts, synchronously available across restarts + + * [timothy] In addition to session storage which is async, this would give extensions some immediate background data on startup. We were supportive of this, as were others I believe. + * [oliver] When we were talking earlier about non-persistent lifetimes, this is one of the ideas that came up. Would be good to create a proposal for it. + * [timothy] Add labels when you can. + +[Issue 707](https://github.com/w3c/webextensions/issues/707): Request for Comments: Extension Performance + + * [timothy] This goes into details about how devtools is spread out across many different contexts. Could have a unified place to gather performance, console logging, cross-context issues. + * [oliver] There was a brief conversation in Matrix about this asking if we were interested in performance. Nothing specific in mind on how to action this. We want to measure extensions aren't negatively impacting site performance, but no ideas off the top of my head. + * [jordan] This was me. Scope could be small or wider ranging, depending on how in depth you want to get. Seems like there's room for tooling improvements. + * [timothy] Definitely gotten feedback about the difficulty of debugging across many different contexts. For folks more familiar with web debugging, this can be difficult to work with. + * [simeon] Might be worth noting that we can't lean on motivated developers to explore ideas here because extensions can't debug extensions like they can websites. + +[PR 690](https://github.com/w3c/webextensions/pull/690): ​​Proposal: add cookies.removeAll() method + + * [timothy] Largely a reminder for me. This PR introduces a .removeAll() method. Aaron recently pushed a couple updates. + * [aaron] Yep, thanks for the feedback. Expect that this will get resolved soon once Rob gets back from vacation. We seem well aligned, just need to work through small details and clarifications. + * [timothy] Requirement is now to have a top level url, right? + * [aaron] yes, and I think you suggested that should be safe. Might end up going away from my initial idea of having a top level site in a parameter and allow just a partition key with just a top level site. The site would be enclosed in the partition key. + * [timothy] I think my preference would be to match where top level site is normally, rather than promoting it to the top for just this method. I think that's in line with Rob's feedback. I'll take another pass. + +[PR 679](https://github.com/w3c/webextensions/pull/679): Proposal: dom.createPort() + + * [timothy] There's been a decent amount of discussion in the last two weeks on this. This is relevant to the dom.execute() proposal. I want to go back over and add additional comments, I'd encourage others to as well. Would like to keep the momentum from TPAC going and finish these out. + * [simeon] Would it be useful to have an example for migrating off postmessage? Maybe for an MDN content update? + * [timothy] There's a decent example in the proposal. Not exactly what you were describing for migrating from A to B. Would definitely be good to have that on MDN. + +[PR 678](https://github.com/w3c/webextensions/pull/678): Proposal: dom.execute() + + * [timothy] This is really in support of dom.createPort(), but can also be used for other purposes so you don't have to message to your background script all the time. Doesn't require creating a script tag in the main world. + +[Issue 601](https://github.com/w3c/webextensions/issues/601): Proposal: StorageArea.getKeys() + + * [timothy] Recently had someone implement this in WebKit. That's two implementations. Wanted to check if Firefox is still interested. + * [simeon] I expect so, but don't want to commit the eng folks to work without their input. + * [timothy] Should ship in Safari Tech Preview soon. + +[PR 569](https://github.com/w3c/webextensions/pull/569): Proposal: i18n-system-languages + + * [timothy] I've approved, could use approval from another vendor. This is Carlos' proposal. He took the time to implement it in WebKit during TPAC. I think he may have done another implementation as well? + * [carlos] Yes, I have a patch for Firefox. It still needs a test, but that should be it. + * [timothy] Anything outstanding that's blocking the proposal? + * [carlos] Nothing that I'm aware of. + * [timothy] Would be good to get feedback from Chrome and Firefox, especially with a Firefox proposal pending. + +Open discussion + + * [simeon] I'm working on a podcast related to extensions. If anyone here is interested, I'd love to sit down and chat about thoughts or opinions about the platform, proposals, the ecosystem, etc. Feel free to reach out on Matrix or elsewhere 🙂 + +The next meeting will be on [Thursday, October 24th, 8 AM PDT (3 PM UTC)](https://everytimezone.com/?t=67198e00,384). diff --git a/_minutes/README.md b/_minutes/README.md index 90dbbe0c..95c43776 100644 --- a/_minutes/README.md +++ b/_minutes/README.md @@ -10,24 +10,33 @@ After the end of each meeting, meeting notes are published here. ## Upcoming meetings -- 2024-09-23 until 2024-09-27 = TPAC 2024 ([issue 659](https://github.com/w3c/webextensions/issues/659)) ([TPAC 2024 Coordination](https://github.com/w3c/webextensions/wiki/TPAC-2024-Coordination)) -- 2024-09-26 at 8 AM PDT = https://everytimezone.com/?t=66f4a400,384 -- 2024-10-10 at 8 AM PDT = https://everytimezone.com/?t=67071900,384 +- 2024-10-24 at 8 AM PDT = https://everytimezone.com/?t=67198e00,384 +- 2024-11-07 at 8 AM PST = https://everytimezone.com/?t=672c0300,3c0 ## Past meetings +* 2024-10-10 ([minutes](2024-10-10-wecg.md)) +* 2024-09-27 at TPAC ([minutes](2024-09-27-wecg-tpac.md)) +* 2024-09-26 at TPAC ([minutes](2024-09-26-wecg-tpac.md)) +* 2024-09-26 ([minutes](2024-09-26-wecg.md)) +* 2024-09-24 at TPAC ([minutes](2024-09-24-wecg-tpac.md)) +* 2024-09-23 at TPAC ([minutes](2024-09-23-wecg-tpac.md)) * 2024-09-12 ([minutes](2024-09-12-wecg.md)) * 2024-08-29 ([minutes](2024-08-29-wecg.md)) * 2024-08-15 ([minutes](2024-08-15-wecg.md)) * 2024-08-01 ([minutes](2024-08-01-wecg.md)) -* 2024-07-18 ([minutes](2024-07-18-wecg.md)) -* 2024-07-04 ([minutes](2024-07-04-wecg.md))
All past meeting notes **2024** +* 2024-10-10 ([minutes](2024-10-10-wecg.md)) +* 2024-09-27 at TPAC ([minutes](2024-09-27-wecg-tpac.md)) +* 2024-09-26 at TPAC ([minutes](2024-09-26-wecg-tpac.md)) +* 2024-09-26 ([minutes](2024-09-26-wecg.md)) +* 2024-09-24 at TPAC ([minutes](2024-09-24-wecg-tpac.md)) +* 2024-09-23 at TPAC ([minutes](2024-09-23-wecg-tpac.md)) * 2024-09-12 ([minutes](2024-09-12-wecg.md)) * 2024-08-29 ([minutes](2024-08-29-wecg.md)) * 2024-08-15 ([minutes](2024-08-15-wecg.md)) diff --git a/_minutes/export-minutes.html b/_minutes/export-minutes.html index 8fd27563..c43251f2 100644 --- a/_minutes/export-minutes.html +++ b/_minutes/export-minutes.html @@ -22,7 +22,8 @@ } #extraInfoOutput { white-space: pre-wrap; - height: 7em; + height: 8em; + overflow-y: auto; } #input, #output { flex: 1; @@ -75,6 +76,10 @@ - Issues: ${serializeIssues(issues)} - PRs: ${serializeIssues(prs)} - Mentioned issues without link to issue: ${serializeIssues(mentionedWithoutLink)}`; + if (markdownText.includes("```")) { + extraInfoOutput.textContent += ` +WARNING: ${markdownText.match(/```/g).length / 2} code blocks (\`\`\`) found. You should verify the rendered output!`; + } }; /** @@ -86,7 +91,7 @@ - Replace boldfaced with **xx** - Replace italic with _xx_ - Replace links with [text](anchor) -- Replace h1, h2, h3 with #, ## and ### +- Replace h1, h2, h3, h4 with #, ##, ### and #### - Format h1 header for consistency. - Replace ol,ul and li with correctly indented list items. - Fixup whitespace. @@ -95,12 +100,9 @@ let root = elemRootInput.cloneNode(true); // Apply code formatting first, before escaping characters. - for (let c of root.querySelectorAll(`span[style*="font-family:'Courier New'"]`)) { - c.prepend("`"); - c.append("`"); - // replaceAllInTextNodes skips ` only if they are in the same text node. - c.normalize(); - } + // To avoid interference by transformations below, the code is replaced + // with placeholders, which we should restore in the end. + const { finalRestoreCodeBlocks } = replaceAllCodeBlocks(root); // Escape < to avoid rendering as HTML. replaceAllInTextNodes(root, "<", "<"); @@ -148,6 +150,9 @@ for (let h of root.querySelectorAll("h3")) { h.prepend(`\n### `); } + for (let h of root.querySelectorAll("h4")) { + h.prepend(`\n#### `); + } for (let li of root.querySelectorAll("li")) { let level = 0; @@ -190,7 +195,7 @@ elem.after("\n"); } // Blank line after every header. - for (let elem of root.querySelectorAll("h1,h2,h3")) { + for (let elem of root.querySelectorAll("h1,h2,h3,h4")) { elem.after("\n\n"); } @@ -218,6 +223,8 @@ // Trim leading whitespace. textContent = textContent.trim(); + textContent = finalRestoreCodeBlocks(textContent); + return textContent; } @@ -248,6 +255,92 @@ node.parentNode.replaceChild(document.createTextNode(proposed), node); } } + +// Replaces code elements in |root| with. +function replaceAllCodeBlocks(root, getPlaceholder) { + // To prevent code blocks from being affected by text-based transformations + // in the end, replace the text with placeholders. + const codeTexts = new Map(); + let nextCodeId = 1000; + function getPlaceholder(txt) { + // Assuming that minutes will never contain MINUTE_PLACEHOLDER_. + let placeholder = `^^^MINUTE_PLACEHOLDER_${nextCodeId++}===`; + codeTexts.set(placeholder, txt); + return placeholder; + } + function restorePlaceholders(txt) { + return txt.replace( + /\^\^\^MINUTE_PLACEHOLDER_\d+===/g, + placeholder => codeTexts.get(placeholder) + ); + } + + // First pass: Detect code lines (possibly multiline code) and inline code. + for (let c of root.querySelectorAll(`span[style*="font-family"][style*="monospace"]`)) { + if (c.style.fontFamily.includes("monospace")) { + if (c.closest("[this_is_really_a_code_block]")) { + // Already processed (determined that parent is code block). + continue; + } + if ( + c.parentNode.tagName === "P" && + !c.parentNode.querySelector(`span[style*="font-family"]:not([style*="monospace"])`) + ) { + // Part of code block. + c.parentNode.setAttribute("this_is_really_a_code_block", ""); + } else { + // Has siblings that is not code. + c.setAttribute("this_is_really_a_code_block", ""); + } + } + } + // Second pass: Collapse multiline code with ```, use ` otherwise. + for (let c of root.querySelectorAll("[this_is_really_a_code_block]")) { + if (!root.contains(c)) { + // Already processed and remove()d below. + continue; + } + let codeNodes = []; + for ( + let nod = c; + nod?.matches?.("[this_is_really_a_code_block],br"); + nod = nod.nextSibling + ) { + codeNodes.push(nod); + } + let codeText = ""; + for (let nod of codeNodes) { + // br can be top-level, sole child of p, or wrapped in span. + for (let br of nod.querySelectorAll("br")) { + br.replaceWith("\n"); + } + codeText += nod.textContent; + if (nod.tagName === "P" || nod.tagName === "BR") { + codeText += "\n"; + } + } + codeText = codeText.replace(/\n+$/, ""); + + // Replace actual content with placeholder to prevent other logic such as + // the link wrapping / text replacement logic from mangling the code block. + c.textContent = getPlaceholder(codeText); + + if (codeText.trim().includes("\n")) { + c.textContent = "```\n" + codeText + "\n```"; + } else { + c.textContent = "`" + codeText + "`"; + } + // codeNodes[0] === c; remove all except c. + codeNodes.slice(1).forEach(nod => nod.remove()); + } + + function finalRestoreCodeBlocks(textContent) { + textContent = restorePlaceholders(textContent); + return textContent; + } + + return { finalRestoreCodeBlocks }; +}