Compare commits

...

151 Commits

Author SHA1 Message Date
Ralph Slooten
f33f9bec2d Merge branch 'release/v1.28.4' 2026-01-25 10:07:35 +13:00
Ralph Slooten
ff47ba96b8 Release v1.28.4 2026-01-25 10:07:35 +13:00
Ralph Slooten
b9f36312d7 Fix: Avoid error on image type assertion in thumbnail generation
Use imaging.Clone to ensure the image is always *image.NRGBA, preventing panics when decoding non-NRGBA images (e.g., JPEGs as *image.YCbCr).
2026-01-25 10:05:39 +13:00
Ralph Slooten
291c449591 Chore: Update node dependencies 2026-01-25 10:05:38 +13:00
Ralph Slooten
d7a4a60536 Chore: Update Go dependencies 2026-01-25 10:05:38 +13:00
Ralph Slooten
464ff68c34 Fix: Prevent nested MAIL command during an active SMTP transaction (#623) 2026-01-25 10:05:28 +13:00
Ralph Slooten
9383c5876b Fix: Ensure SMTP HELO/EHLO command is issued before MAIL FROM as per RFC 5321 (#621) 2026-01-23 17:27:13 +13:00
Ralph Slooten
a3616e52d9 Chore: Increase allowed SMTP email address length to 1024 chars & return clearer SMTP responses for failures (#620)
This goes against the RFC5321 recommendation, however enforcing the recommended limits is clearly causing issues with users, and it appears no investigated SMTP servers enforce the strict limits either.
2026-01-23 16:46:29 +13:00
Ralph Slooten
980e54c21f Merge tag 'v1.28.3' into develop
Release v1.28.3
2026-01-18 21:36:02 +13:00
Ralph Slooten
eac491cd89 Merge branch 'release/v1.28.3' 2026-01-18 21:35:55 +13:00
Ralph Slooten
12076bca72 Release v1.28.3 2026-01-18 21:35:54 +13:00
Ralph Slooten
028ca1d715 Chore: Update node dependencies 2026-01-18 12:24:54 +13:00
Ralph Slooten
7d7ba88e9c Chore: Update Go dependencies 2026-01-18 12:22:46 +13:00
Ralph Slooten
973fc1f975 Merge branch 'feature/GHSA-6jxm-fv7w-rw5j' into develop 2026-01-18 12:00:09 +13:00
Ralph Slooten
1679a0aba5 Security: Prevent Server-Side Request Forgery (SSRF) via HTML Check API ([GHSA-6jxm-fv7w-rw5j](https://github.com/axllent/mailpit/security/advisories/GHSA-6jxm-fv7w-rw5j)) 2026-01-18 11:58:24 +13:00
Ralph Slooten
4a4c149eed Formatting 2026-01-18 11:57:23 +13:00
Ralph Slooten
c01335f0e3 Merge branch 'feature/GHSA-54wq-72mp-cq7c' into develop 2026-01-18 11:53:11 +13:00
Ralph Slooten
181cb0714a Test: Add maximum email length validation tests - RFC5321 (section 4.5.3.1) 2026-01-18 11:51:23 +13:00
Ralph Slooten
00d52d5931 Fix: Validate maximum lengths of email addresses - RFC5321 (section 4.5.3.1) 2026-01-18 11:51:23 +13:00
Ralph Slooten
050da038af Test: Add SMTP tests for address compliancy (RFC 5322) and header injection 2026-01-18 11:51:23 +13:00
Ralph Slooten
36cc06c125 Security: Ensure SMTP TO & FROM addresses are RFC 5322 compliant and prevent header injection ([GHSA-54wq-72mp-cq7c](https://github.com/axllent/mailpit/security/advisories/GHSA-54wq-72mp-cq7c)) 2026-01-18 11:50:33 +13:00
Ralph Slooten
2734efbc66 Test: Update tag tests with length limits and @ character 2026-01-17 11:22:19 +13:00
Ralph Slooten
7cda4a36f1 Chore: Allow @ character in message tags & set max length to 100 characters per tag 2026-01-17 11:12:45 +13:00
Ralph Slooten
45b3676e52 Fix: Auto-tagging using SMTP username using plain auth (#617) 2026-01-16 13:50:15 +13:00
BTC-Tim
d50347d667 Fix: Correctly detect macOS group in install.sh (#619) 2026-01-16 10:12:11 +13:00
Omar Kurt
c035139b54 Chore: Fix formatting and update reporting instructions in SECURITY.md (#614) 2026-01-11 10:24:58 +13:00
Ralph Slooten
3108d82e06 Fix: Correctly render default addresses in release modal after settings change (#594) 2026-01-10 22:19:18 +13:00
Ralph Slooten
648d5863da Merge tag 'v1.28.2' into develop
Release v1.28.2
2026-01-10 16:16:14 +13:00
Ralph Slooten
585ea1dc30 Merge branch 'release/v1.28.2' 2026-01-10 16:16:06 +13:00
Ralph Slooten
c66a06379a Release v1.28.2 2026-01-10 16:16:05 +13:00
Ralph Slooten
c5c9292863 More reliable handling for default release email editing 2026-01-10 15:56:19 +13:00
Ralph Slooten
6f1f4f34c9 Security: Prevent Cross-Site WebSocket Hijacking (CSWSH) allowing unauthenticated access to message data [CVE-2026-22689](https://github.com/axllent/mailpit/security/advisories/GHSA-524m-q5m7-79mm) 2026-01-10 15:42:14 +13:00
Ralph Slooten
877a9159ce Delay bootstrap-tags init until after render 2026-01-08 16:23:24 +13:00
Ralph Slooten
c4582889ad Update default release address wording 2026-01-08 16:20:00 +13:00
Ralph Slooten
cd1cf695b9 Merge branch 'feature/default-release-address' into develop 2026-01-08 16:04:23 +13:00
Ralph Slooten
392904fd23 Chore: Avoid empty URL query parameter when returning to inbox from message view 2026-01-08 16:03:35 +13:00
Ralph Slooten
f0160c0e29 Feature: Allow default mail addresses to be set when releasing message (#594) 2026-01-08 16:03:35 +13:00
Ralph Slooten
f9024d1f77 Chore: Remove webkit warnings about missing template / render functions 2026-01-08 16:03:34 +13:00
Ralph Slooten
061f159293 Merge tag 'v1.28.1' into develop
Release v1.28.1
2026-01-06 15:38:14 +13:00
Ralph Slooten
e69a0d75c9 Merge branch 'release/v1.28.1' 2026-01-06 15:38:11 +13:00
Ralph Slooten
0847167694 Release v1.28.1 2026-01-06 15:38:11 +13:00
Ralph Slooten
6dd3587ec6 Move security commits to top of list 2026-01-06 15:35:49 +13:00
Ralph Slooten
2d1e38d4fd Chore: Update node dependencies 2026-01-06 15:34:20 +13:00
Ralph Slooten
153174f928 Chore: Update Go dependencies 2026-01-06 15:34:20 +13:00
Ralph Slooten
3b9b470c09 Security: Restrict screenshot proxy to only support asset links contained in messages [CVE-2026-21859](https://github.com/axllent/mailpit/security/advisories/GHSA-8v65-47jx-7mfr)
This fix prevents unrestricted network probing via the screenshot proxy by limiting requests to images, fonts and CSS links found within a message, and returns a generic HTTP error to the client when unsupported content types are requested, not found, or otherwise disallowed.

See CWE-918 Server-Side Request Forgery (SSRF)
2026-01-06 15:33:50 +13:00
dependabot[bot]
dd99a4bcf0 Chore: Bump esbuild from 0.25.12 to 0.27.2 (#611)
Bumps [esbuild](https://github.com/evanw/esbuild) from 0.25.12 to 0.27.2.
- [Release notes](https://github.com/evanw/esbuild/releases)
- [Changelog](https://github.com/evanw/esbuild/blob/main/CHANGELOG.md)
- [Commits](https://github.com/evanw/esbuild/compare/v0.25.12...v0.27.2)

---
updated-dependencies:
- dependency-name: esbuild
  dependency-version: 0.27.2
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-01 22:16:37 +13:00
dependabot[bot]
5bf2f2796b Chore: Bump actions/setup-node from 5 to 6 (#598)
Bumps [actions/setup-node](https://github.com/actions/setup-node) from 5 to 6.
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](https://github.com/actions/setup-node/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/setup-node
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-01 22:13:15 +13:00
dependabot[bot]
a469655f65 Chore: Bump actions/stale from 10.0.0 to 10.1.1 (#604)
Bumps [actions/stale](https://github.com/actions/stale) from 10.0.0 to 10.1.1.
- [Release notes](https://github.com/actions/stale/releases)
- [Changelog](https://github.com/actions/stale/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/stale/compare/v10.0.0...v10.1.1)

---
updated-dependencies:
- dependency-name: actions/stale
  dependency-version: 10.1.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-01 22:12:43 +13:00
dependabot[bot]
432fedeafa Chore: Bump actions/cache from 4 to 5 (#607)
Bumps [actions/cache](https://github.com/actions/cache) from 4 to 5.
- [Release notes](https://github.com/actions/cache/releases)
- [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md)
- [Commits](https://github.com/actions/cache/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/cache
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-01 22:12:15 +13:00
dependabot[bot]
37e4ff4139 Chore: Bump actions/checkout from 5 to 6 (#610)
Bumps [actions/checkout](https://github.com/actions/checkout) from 5 to 6.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-01 22:11:51 +13:00
Ralph Slooten
2808316dd2 Temporarily disable swagger validation due to persistent service issues 2025-12-22 17:12:35 +13:00
Ralph Slooten
43d759b0fc Update close-stale-issues workflow to include close-issue-reason 2025-12-22 16:45:44 +13:00
Ralph Slooten
264222d599 Test: Increase swagger test timeout 2025-12-20 17:07:36 +13:00
Ralph Slooten
5e4bdb78b8 Test: Add inline message tests 2025-12-20 16:45:57 +13:00
Ralph Slooten
fc9572156b Merge tag 'v1.28.0' into develop
Release v1.28.0
2025-11-26 17:44:28 +13:00
Ralph Slooten
d52a0d550f Merge branch 'release/v1.28.0' 2025-11-26 17:44:26 +13:00
Ralph Slooten
fcce621f18 Release v1.28.0 2025-11-26 17:44:26 +13:00
Ralph Slooten
f4cd19aac2 Merge branch 'feature/updates' into develop 2025-11-26 17:33:38 +13:00
Ralph Slooten
46ccf866b2 Chore: Update caniemail test database 2025-11-26 17:32:49 +13:00
Ralph Slooten
266611fda0 Chore: Update node dependencies 2025-11-26 17:32:18 +13:00
Ralph Slooten
fe3920e3c6 Chore: Update Go dependencies 2025-11-26 17:29:03 +13:00
Ralph Slooten
ac02802d62 Merge branch 'feature/relay-smtp-errors' into develop 2025-11-26 16:34:39 +13:00
Ralph Slooten
7d6aab4e01 Refactor imports and improve logging in SMTP relay functionality 2025-11-26 16:30:28 +13:00
Ralph Slooten
36d8525557 Refactor command handlers to ignore unused parameters 2025-11-26 16:30:14 +13:00
Dennis
0f0a5d942f Feature: Optionally propagate SMTP errors (#588)
* forward smtp errors

* lint and formatting

* forward smtp errors in forward-impl
2025-11-26 16:17:44 +13:00
dependabot[bot]
b987006897 Bump golang.org/x/crypto from 0.43.0 to 0.45.0 (#586)
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.43.0 to 0.45.0.
- [Commits](https://github.com/golang/crypto/compare/v0.43.0...v0.45.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-version: 0.45.0
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-20 16:14:38 +13:00
dependabot[bot]
c8e0bee8bb Bump js-yaml from 4.1.0 to 4.1.1 (#585)
Bumps [js-yaml](https://github.com/nodeca/js-yaml) from 4.1.0 to 4.1.1.
- [Changelog](https://github.com/nodeca/js-yaml/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nodeca/js-yaml/compare/4.1.0...4.1.1)

---
updated-dependencies:
- dependency-name: js-yaml
  dependency-version: 4.1.1
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-17 08:08:55 +13:00
Ralph Slooten
3b0ae24c2a Merge tag 'v1.27.11' into develop
Release v1.27.11
2025-11-09 11:38:25 +13:00
Ralph Slooten
aca491f10c Merge branch 'release/v1.27.11' 2025-11-09 11:38:22 +13:00
Ralph Slooten
6724f0ccdd Release v1.27.11 2025-11-09 11:38:21 +13:00
Ralph Slooten
93088f3361 Chore: Add type assertion for value in imaging assignment 2025-11-09 11:33:51 +13:00
Ralph Slooten
e817bf5f7d Chore: Update node dependencies 2025-11-09 11:19:03 +13:00
Ralph Slooten
4d100a9ec3 Chore: Update Go dependencies 2025-11-09 11:16:20 +13:00
Ralph Slooten
958fa6cf1a Add thanks.dev link 2025-11-05 22:04:33 +13:00
Ralph Slooten
27e12474f5 Add link to Mailtrap 2025-11-04 16:57:45 +13:00
Ralph Slooten
302b269fb6 Merge tag 'v1.27.10' into develop
Release v1.27.10
2025-10-09 15:40:09 +13:00
Ralph Slooten
2d9157ffd3 Merge branch 'release/v1.27.10' 2025-10-09 15:40:06 +13:00
Ralph Slooten
242c96244a Release v1.27.10 2025-10-09 15:40:06 +13:00
Ralph Slooten
d308e7f30b Merge branch 'feature/fix' into develop 2025-10-09 15:37:09 +13:00
Ralph Slooten
85a9cc3c2b Chore: Update node dependencies 2025-10-09 15:36:16 +13:00
Ralph Slooten
f94ce556e5 Chore: Update Go dependencies 2025-10-09 15:33:04 +13:00
Ralph Slooten
5ad8619893 Fix: Prevent potential information disclosure via indirect expvar library (Prometheus)
This is a security fix which prevents potential information disclosure due to a pre-registered HTTP route. The Prometheus client imports the go stdlib expvar, which in turn is auto-registers `/debug/vars` on the default servemux. This fix ensures no default/global routes are inherited via the http library.
2025-10-08 17:32:05 +13:00
Ralph Slooten
8d692b6bd9 Chore: Update GitHub Actions 2025-10-08 17:32:05 +13:00
Ralph Slooten
99ab38fbba Chore: Add tooltip to messages nav dropdown 2025-10-08 17:32:05 +13:00
Ralph Slooten
2cf040e787 Chore: Update GitHub Actions 2025-10-01 21:53:32 +13:00
Ralph Slooten
cde80bf0fd Chore: Add tooltip to messages nav dropdown 2025-09-29 17:07:40 +13:00
Ralph Slooten
1a41d433c6 Merge tag 'v1.27.9' into develop
Release v1.27.9
2025-09-29 15:41:06 +13:00
Ralph Slooten
49557e8e59 Merge branch 'release/v1.27.9' 2025-09-29 15:41:03 +13:00
Ralph Slooten
339f6ef31d Release v1.27.9 2025-09-29 15:41:03 +13:00
Ralph Slooten
2e187cfcef Chore: Update node dependencies 2025-09-29 15:14:29 +13:00
Ralph Slooten
39ecefa108 Chore: Update Go dependencies 2025-09-29 15:11:45 +13:00
Ralph Slooten
ae65312d02 Chore: Update navbar theme to use data-bs-theme attribute for consistency 2025-09-26 14:50:27 +12:00
Ralph Slooten
0770bd8d19 Chore: Add margin to icons in release and delete buttons for consistent spacing 2025-09-26 14:50:06 +12:00
Ralph Slooten
e2314fb3b9 Chore: UI tweaks to pagination layout for clearer navigation (#568) 2025-09-26 14:48:51 +12:00
Ralph Slooten
1dd0bf3d29 Merge tag 'v1.27.8' into develop
Release v1.27.8
2025-09-14 22:34:07 +12:00
Ralph Slooten
568ad5da62 Merge branch 'release/v1.27.8' 2025-09-14 22:34:04 +12:00
Ralph Slooten
d3063ea248 Release v1.27.8 2025-09-14 22:34:03 +12:00
Ralph Slooten
6ccc294a1e Chore: Update caniemail test database 2025-09-14 22:23:44 +12:00
Ralph Slooten
5629f39d40 Chore: Update node dependencies 2025-09-14 22:22:55 +12:00
Ralph Slooten
314f30bee5 Chore: Update Go dependencies 2025-09-14 22:22:09 +12:00
Ralph Slooten
5c8931c04d Merge tag 'v1.27.7' into develop
Release v1.27.7
2025-08-27 15:57:12 +12:00
Ralph Slooten
ca6357f262 Merge branch 'release/v1.27.7' 2025-08-27 15:57:09 +12:00
Ralph Slooten
3645219615 Release v1.27.7 2025-08-27 15:57:09 +12:00
Ralph Slooten
7d74516270 Fix: Move HELO/EHLO hostname setting to the correct position in SMTP client creation (#558) 2025-08-26 12:17:01 +12:00
Ralph Slooten
fb1a06bc86 Merge tag 'v1.27.6' into develop
Release v1.27.6
2025-08-24 13:47:29 +12:00
Ralph Slooten
7809a26374 Merge branch 'release/v1.27.6' 2025-08-24 13:47:25 +12:00
Ralph Slooten
120f078a32 Release v1.27.6 2025-08-24 13:47:25 +12:00
Ralph Slooten
776912d38a Chore: Update node dependencies 2025-08-24 13:44:27 +12:00
Ralph Slooten
e3b37943a8 Chore: Update Go dependencies 2025-08-24 13:41:21 +12:00
Stéphan Kochen
5054d98701 Feature: Add optional --no-release-check to version subcommand (#557) 2025-08-22 22:44:00 +12:00
Peter Krawczyk
8ce6fc0db5 Chore: Set HELO/EHLO hostname when connecting to external SMTP server (#556)
When a message is forwarded or released, Mailpit introduces itself as
`localhost` to the upstream server. This happens because `net/smtp` forces the
value to be `localhost` if `client.Hello` is not called. This is explicitly
documented at https://pkg.go.dev/net/smtp#Client.Hello

Therefore, both `internal/smtpd/relay.go` (`createRelaySMTPClient`) and
`internal/smtpd/forward.go` (`createForwardingSMTPClient`) should either call
`client.Hello(os.Hostname())` or create a config (perhaps `config.HeloHostname`)
and use `client.Hello()` with that value immediately before returning from
either of those functions. (The HELO/EHLO command comes after TLS negotiation
but before any other SMTP commands.) This commit does the former.

Without this feature, Mailpit cannot be used in combination with Google
Workspace's SMTP Relay functionality, as it rejects any connection that
identifies itself as `localhost`.

Relates to #146
2025-08-22 16:04:03 +12:00
Ralph Slooten
933d064a51 Merge tag 'v1.27.5' into develop
Release v1.27.5
2025-08-17 12:41:46 +12:00
Ralph Slooten
ad26ca34e5 Merge branch 'release/v1.27.5' 2025-08-17 12:41:43 +12:00
Ralph Slooten
531801f934 Release v1.27.5 2025-08-17 12:41:42 +12:00
Ralph Slooten
0faa71310e Chore: Update caniemail test database 2025-08-17 12:35:45 +12:00
Ralph Slooten
646e93c58b Chore: Update node dependencies 2025-08-17 12:34:59 +12:00
Ralph Slooten
854844924f Chore: Update Go dependencies 2025-08-17 12:31:49 +12:00
Felipe
343db8bb61 Fix: Support optional UIDL argument in POP3 server (#552)
* fix: use single-line response when UIDL has an argument

The test changes included here don't necessarily deal with the fact that
the response used to be multi-line: the failure wouldn't occur during
the `c.Uidl()` calls, but rather on the next one as the client would
still have data from the server to receive, causing a parsing error like
so:

    pop3_test.go:103: strconv.Atoi: parsing "unique-id": invalid syntax

The server now correctly replies with a single line response when an
argument is passed, as required by [the spec][1]

[1]: https://www.rfc-editor.org/rfc/rfc1939.html#page-12

* fix: UIDL accepts at most one argument
2025-08-17 12:24:53 +12:00
Ralph Slooten
781d8d2332 Merge tag 'v1.27.4' into develop
Release v1.27.4
2025-08-10 21:26:12 +12:00
Ralph Slooten
618d1f77b5 Merge branch 'release/v1.27.4' 2025-08-10 21:25:52 +12:00
Ralph Slooten
5577b748af Release v1.27.4 2025-08-10 21:25:51 +12:00
Ralph Slooten
4619d9be88 Chore: Update caniemail test database 2025-08-10 21:18:23 +12:00
Ralph Slooten
6051952a9b Chore: Update node dependencies 2025-08-10 21:17:32 +12:00
Ralph Slooten
a54697b3de Chore: Update Go dependencies 2025-08-10 21:14:38 +12:00
Ralph Slooten
f6bb0d1ffd Merge branch 'feature/drop-rejected-recipients' into develop 2025-08-10 21:09:29 +12:00
Ralph Slooten
41ef4ecd60 Rename smtp-silently-drop-rejected-recipients to smtp-ignore-rejected-recipients 2025-08-10 21:04:22 +12:00
Matthias Gliwka
39d80df809 Feature: Allow rejected SMTP recipients to be silently dropped (#549) 2025-08-10 20:34:26 +12:00
Ralph Slooten
be95839838 Merge tag 'v1.27.3' into develop
Release v1.27.3
2025-07-29 01:22:02 +12:00
Ralph Slooten
8f187fe275 Merge branch 'release/v1.27.3' 2025-07-29 01:21:55 +12:00
Ralph Slooten
bb2793354a Release v1.27.3 2025-07-29 01:21:53 +12:00
Ralph Slooten
42aa38ddeb Fix: Fix sendmail when using an --smtp-addr <ip>:<port> (#542) 2025-07-29 01:20:55 +12:00
Ralph Slooten
7423b9660b Merge tag 'v1.27.2' into develop
Release v1.27.2
2025-07-27 12:36:34 +12:00
Ralph Slooten
0b7503261c Merge branch 'release/v1.27.2' 2025-07-27 12:36:30 +12:00
Ralph Slooten
e43be79968 Release v1.27.2 2025-07-27 12:36:29 +12:00
Ralph Slooten
70855a50c5 Chore: Update node dependencies 2025-07-27 12:29:56 +12:00
Ralph Slooten
0b21a3aba2 Chore: Update Go dependencies 2025-07-27 12:28:09 +12:00
Ralph Slooten
507217844b Security: Add ReadHeaderTimeout to Prometheus metrics server 2025-07-25 20:39:13 +12:00
Ralph Slooten
5a4d13b15a Security: Prevent integer overflow conversion to uint64 2025-07-25 20:33:27 +12:00
Ralph Slooten
fbc1dc6118 Do not expose unnecessary Prometheus functions 2025-07-25 20:33:27 +12:00
Ralph Slooten
2a7aa33a0a Fix: Do not check latest release for Prometheus statistics (#522) 2025-07-25 20:33:20 +12:00
dependabot[bot]
45f07d3c9b Bump form-data from 4.0.3 to 4.0.4
---
updated-dependencies:
- dependency-name: form-data
  dependency-version: 4.0.4
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-24 17:32:03 +12:00
dependabot[bot]
894220dc44 Bump axios from 1.10.0 to 1.11.0
Bumps [axios](https://github.com/axios/axios) from 1.10.0 to 1.11.0.
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/v1.10.0...v1.11.0)

---
updated-dependencies:
- dependency-name: axios
  dependency-version: 1.11.0
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-24 17:30:56 +12:00
Ralph Slooten
cce21854b9 Chore: Refactor JS functions and remove unused parameters 2025-07-24 17:27:11 +12:00
Ralph Slooten
33fe814c34 Chore: Update eslint config, remove neostandard 2025-07-24 17:26:20 +12:00
Ralph Slooten
df75064009 Merge branch 'feature/snakeoil' into develop 2025-07-24 17:04:25 +12:00
Ralph Slooten
e1ed21abff Chore: Allow sendmail to send to untrusted TLS server 2025-07-24 17:04:15 +12:00
Ralph Slooten
f3e3536cdb Feature: Add ability to generate self-signed (snakeoil) certificates for UI, SMTP and POP3 (#539) 2025-07-24 17:02:50 +12:00
Ralph Slooten
38c343867e Merge branch 'feature/535-bug' into develop 2025-07-18 23:43:17 +12:00
Ralph Slooten
75504c7bba Fix: Support angle brackets for text/plain URLs with spaces (#535) 2025-07-18 23:43:05 +12:00
Dennis
79323df3bd Fix: Use MaxMessages to determine pruning (#536) 2025-07-16 22:16:25 +12:00
Ralph Slooten
5a672df0fc Merge tag 'v1.27.1' into develop
Release v1.27.1
2025-07-06 17:34:56 +12:00
78 changed files with 3095 additions and 4377 deletions

1
.github/FUNDING.yml vendored
View File

@@ -1,3 +1,4 @@
# These are supported funding model platforms
github: [axllent]
thanks_dev: u/gh/axllent

10
.github/SECURITY.md vendored
View File

@@ -2,10 +2,12 @@
Your efforts to responsibly disclose your findings are appreciated.
** **Please do _not_ report security vulnerabilities through public GitHub issues.** **
**Please do not report security vulnerabilities through public GitHub issues.**
If you believe you have found a **security vulnerability**, then please report it to security@axllent.org so
your findings can be investigated, and if confirmed, fixed and released in a timely manner.
If you believe you have found a security vulnerability, you can report it using one of the following methods:
1. **GitHub Security Advisory (Recommended):** Use the "Report a vulnerability" button in the [Security tab](../../security/advisories/new) of this repository.
2. **Email:** Send your findings to security@axllent.org
Your report should include:
@@ -14,6 +16,6 @@ Your report should include:
- Reproduction steps (if applicable)
- Any other details you think are likely to be important
You should receive an initial acknowledgement within 24 hours in most cases, and will kept updated throughout the process.
You should receive an initial acknowledgement within 24 hours in most cases, and will be kept updated throughout the process.
With your consent, your contributions will be publicly acknowledged.

1
.github/cliff.toml vendored
View File

@@ -28,6 +28,7 @@ trim = true
# HTML comments added for grouping order, stripped on generation
commit_parsers = [
{body = ".*security", group = "<!-- 1 -->Security"},
{message = "(?i)^security", group = "<!-- 1 -->Security"},
{message = "(?i)^feat", group = "<!-- 2 -->Feature"},
{message = "(?i)^chore", group = "<!-- 3 -->Chore"},
{message = "(?i)^libs", group = "<!-- 3 -->Chore"},

View File

@@ -8,7 +8,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v6
- name: Set up QEMU
uses: docker/setup-qemu-action@v3

View File

@@ -8,7 +8,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v6
- name: Set up QEMU
uses: docker/setup-qemu-action@v3

View File

@@ -10,12 +10,13 @@ jobs:
issues: write
pull-requests: write
steps:
- uses: actions/stale@v9.1.0
- uses: actions/stale@v10.1.1
with:
days-before-issue-stale: 7
days-before-issue-close: 3
exempt-issue-labels: "enhancement,bug,awaiting feedback"
stale-issue-label: "stale"
close-issue-reason: "completed"
stale-issue-message: "This issue has been marked as stale because it has been open for 7 days with no activity."
close-issue-message: "This issue was closed because there has been no activity since being marked as stale."
days-before-pr-stale: -1

View File

@@ -38,7 +38,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v6
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL

View File

@@ -21,10 +21,10 @@ jobs:
- goarch: arm
goos: windows
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
# build the assets
- uses: actions/setup-node@v4
- uses: actions/setup-node@v6
with:
node-version: 22
cache: 'npm'

View File

@@ -17,9 +17,9 @@ jobs:
# the HTTP address the rqlite node should advertise
HTTP_ADV_ADDR: "localhost:4001"
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- name: Setup Go
uses: actions/setup-go@v5
uses: actions/setup-go@v6
with:
go-version: 'stable'
cache-dependency-path: "**/*.sum"

View File

@@ -12,13 +12,13 @@ jobs:
os: [ubuntu-latest, windows-latest, macos-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/setup-go@v5
- uses: actions/setup-go@v6
with:
go-version: ${{ matrix.go-version }}
cache: false
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- name: Set up Go environment
uses: actions/cache@v4
uses: actions/cache@v5
with:
path: |
~/.cache/go-build
@@ -38,7 +38,7 @@ jobs:
# build the assets
- name: Set up node environment
if: startsWith(matrix.os, 'ubuntu') == true
uses: actions/setup-node@v4
uses: actions/setup-node@v6
with:
node-version: 22
cache: 'npm'
@@ -52,9 +52,10 @@ jobs:
if: startsWith(matrix.os, 'ubuntu') == true
run: npm run package
# validate the swagger file
- name: Validate OpenAPI definition
if: startsWith(matrix.os, 'ubuntu') == true
uses: swaggerexpert/swagger-editor-validate@v1
with:
definition-file: server/ui/api/v1/swagger.json
# # validate the swagger file
# - name: Validate OpenAPI definition
# if: startsWith(matrix.os, 'ubuntu') == true
# uses: swaggerexpert/swagger-editor-validate@v1
# with:
# definition-file: server/ui/api/v1/swagger.json
# default-timeout: 20000

View File

@@ -2,6 +2,193 @@
Notable changes to Mailpit will be documented in this file.
## [v1.28.4]
### Chore
- Increase allowed SMTP email address length to 1024 chars & return clearer SMTP responses for failures ([#620](https://github.com/axllent/mailpit/issues/620))
- Update Go dependencies
- Update node dependencies
### Fix
- Ensure SMTP HELO/EHLO command is issued before MAIL FROM as per RFC 5321 ([#621](https://github.com/axllent/mailpit/issues/621))
- Prevent nested MAIL command during an active SMTP transaction ([#623](https://github.com/axllent/mailpit/issues/623))
- Avoid error on image type assertion in thumbnail generation
## [v1.28.3]
### Security
- Ensure SMTP TO & FROM addresses are RFC 5322 compliant and prevent header injection ([GHSA-54wq-72mp-cq7c](https://github.com/axllent/mailpit/security/advisories/GHSA-54wq-72mp-cq7c))
- Prevent Server-Side Request Forgery (SSRF) via HTML Check API ([GHSA-6jxm-fv7w-rw5j](https://github.com/axllent/mailpit/security/advisories/GHSA-6jxm-fv7w-rw5j))
### Chore
- Fix formatting and update reporting instructions in SECURITY.md ([#614](https://github.com/axllent/mailpit/issues/614))
- Allow `@` character in message tags & set max length to 100 characters per tag
- Update Go dependencies
- Update node dependencies
### Fix
- Correctly render default addresses in release modal after settings change ([#594](https://github.com/axllent/mailpit/issues/594))
- Correctly detect macOS group in install.sh ([#619](https://github.com/axllent/mailpit/issues/619))
- Auto-tagging using SMTP username using plain auth ([#617](https://github.com/axllent/mailpit/issues/617))
- Validate maximum lengths of email addresses - RFC5321 (section 4.5.3.1)
### Test
- Update tag tests with length limits and `@` character
- Add SMTP tests for address compliancy (RFC 5322) and header injection
- Add maximum email length validation tests - RFC5321 (section 4.5.3.1)
## [v1.28.2]
### Security
- Prevent Cross-Site WebSocket Hijacking (CSWSH) allowing unauthenticated access to message data [CVE-2026-22689](https://github.com/axllent/mailpit/security/advisories/GHSA-524m-q5m7-79mm)
### Feature
- Allow default mail addresses to be set when releasing message ([#594](https://github.com/axllent/mailpit/issues/594))
### Chore
- Remove webkit warnings about missing template / render functions
- Avoid empty URL query parameter when returning to inbox from message view
## [v1.28.1]
### Security
- Restrict screenshot proxy to only support asset links contained in messages [CVE-2026-21859](https://github.com/axllent/mailpit/security/advisories/GHSA-8v65-47jx-7mfr)
### Chore
- Bump actions/checkout from 5 to 6 ([#610](https://github.com/axllent/mailpit/issues/610))
- Bump actions/cache from 4 to 5 ([#607](https://github.com/axllent/mailpit/issues/607))
- Bump actions/stale from 10.0.0 to 10.1.1 ([#604](https://github.com/axllent/mailpit/issues/604))
- Bump actions/setup-node from 5 to 6 ([#598](https://github.com/axllent/mailpit/issues/598))
- Bump esbuild from 0.25.12 to 0.27.2 ([#611](https://github.com/axllent/mailpit/issues/611))
- Update Go dependencies
- Update node dependencies
### Test
- Add inline message tests
- Increase swagger test timeout
## [v1.28.0]
### Feature
- Optionally propagate SMTP errors ([#588](https://github.com/axllent/mailpit/issues/588))
### Chore
- Update Go dependencies
- Update node dependencies
- Update caniemail test database
## [v1.27.11]
### Chore
- Update Go dependencies
- Update node dependencies
- Add type assertion for value in imaging assignment
## [v1.27.10]
### Security
- Prevent potential information disclosure via indirect expvar library (Prometheus)
### Chore
- Add tooltip to messages nav dropdown
- Update GitHub Actions
- Add tooltip to messages nav dropdown
- Update GitHub Actions
- Update Go dependencies
- Update node dependencies
## [v1.27.9]
### Chore
- UI tweaks to pagination layout for clearer navigation ([#568](https://github.com/axllent/mailpit/issues/568))
- Add margin to icons in release and delete buttons for consistent spacing
- Update navbar theme to use data-bs-theme attribute for consistency
- Update Go dependencies
- Update node dependencies
## [v1.27.8]
### Chore
- Update Go dependencies
- Update node dependencies
- Update caniemail test database
## [v1.27.7]
### Fix
- Move HELO/EHLO hostname setting to the correct position in SMTP client creation ([#558](https://github.com/axllent/mailpit/issues/558))
## [v1.27.6]
### Feature
- Add optional --no-release-check to version subcommand ([#557](https://github.com/axllent/mailpit/issues/557))
### Chore
- Set HELO/EHLO hostname when connecting to external SMTP server ([#556](https://github.com/axllent/mailpit/issues/556))
- Update Go dependencies
- Update node dependencies
## [v1.27.5]
### Chore
- Update Go dependencies
- Update node dependencies
- Update caniemail test database
### Fix
- Support optional UIDL argument in POP3 server ([#552](https://github.com/axllent/mailpit/issues/552))
## [v1.27.4]
### Feature
- Allow rejected SMTP recipients to be silently dropped ([#549](https://github.com/axllent/mailpit/issues/549))
### Chore
- Update Go dependencies
- Update node dependencies
- Update caniemail test database
## [v1.27.3]
### Fix
- Fix sendmail when using an `--smtp-addr <ip>:<port>` ([#542](https://github.com/axllent/mailpit/issues/542))
## [v1.27.2]
### Security
- Prevent integer overflow conversion to uint64
- Add ReadHeaderTimeout to Prometheus metrics server
### Feature
- Add ability to generate self-signed (snakeoil) certificates for UI, SMTP and POP3 ([#539](https://github.com/axllent/mailpit/issues/539))
### Chore
- Allow sendmail to send to untrusted TLS server
- Update eslint config, remove neostandard
- Refactor JS functions and remove unused parameters
- Update Go dependencies
- Update node dependencies
### Fix
- Use MaxMessages to determine pruning ([#536](https://github.com/axllent/mailpit/issues/536))
- Support angle brackets for text/plain URLs with spaces ([#535](https://github.com/axllent/mailpit/issues/535))
- Do not check latest release for Prometheus statistics ([#522](https://github.com/axllent/mailpit/issues/522))
## [v1.27.1]
### Chore
@@ -1630,6 +1817,9 @@ Notable changes to Mailpit will be documented in this file.
## [1.1.4]
### Security
- Add restrictive HTTP Content-Security-Policy
### Feature
- Add --quiet flag to display only errors
@@ -1638,9 +1828,6 @@ Notable changes to Mailpit will be documented in this file.
- Add favicon unread message counter
- Minor UI color change & unread count position adjustment
### Security
- Add restrictive HTTP Content-Security-Policy
## [1.1.3]
@@ -1727,14 +1914,14 @@ Notable changes to Mailpit will be documented in this file.
## [0.1.2]
### Feature
- Optional browser notifications (HTTPS only)
### Security
- Use strconv.Atoi() for safe string to int conversions
- Sanitize mailbox names
- Don't allow tar files containing a ".."
### Feature
- Optional browser notifications (HTTPS only)
## [0.1.1]

View File

@@ -115,3 +115,10 @@ Please refer to [the documentation](https://mailpit.axllent.org/docs/install/tes
Mailpit's SMTP server (default on port 1025), so you will likely need to configure your sending application to deliver mail via that port.
A common MTA (Mail Transfer Agent) that delivers system emails to an SMTP server is `sendmail`, used by many applications, including PHP.
Mailpit can also act as substitute for sendmail. For instructions on how to set this up, please refer to the [sendmail documentation](https://mailpit.axllent.org/docs/install/sendmail/).
---
<p align="center">
For team features, multiple inboxes, and a hosted setup, try
<a href="https://mailtrap.io/?ref=mailpit">Mailtrap</a>, our friendly companion.
</p>

View File

@@ -17,7 +17,7 @@ The database can either be the database file (eg: --database /var/lib/mailpit/ma
URL of a running Mailpit instance (eg: --http http://127.0.0.1/). If dumping over HTTP, the URL
should be the base URL of your running Mailpit instance, not the link to the API itself.`,
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
Run: func(_ *cobra.Command, args []string) {
if err := dump.Sync(args[0]); err != nil {
logger.Log().Fatal(err)
}

View File

@@ -30,7 +30,7 @@ Mailpit server. Each email must be a separate file (eg: Maildir format, not mbox
The --recent flag will only consider files with a modification date within the last X days.`,
// Hidden: true,
Args: cobra.MinimumNArgs(1),
Run: func(cmd *cobra.Command, args []string) {
Run: func(_ *cobra.Command, args []string) {
var count int
var total int
var per100start = time.Now()

View File

@@ -28,7 +28,7 @@ status 1 if unhealthy.
If running within Docker, it should automatically detect environment
settings to determine the HTTP bind interface & port.
`,
Run: func(cmd *cobra.Command, args []string) {
Run: func(_ *cobra.Command, _ []string) {
webroot := strings.TrimRight(path.Join("/", config.Webroot, "/"), "/") + "/"
proto := "http"
if useHTTPS {

View File

@@ -18,7 +18,7 @@ var reindexCmd = &cobra.Command{
If you have several thousand messages in your mailbox, then it is advised to shut down
Mailpit while you reindex as this process will likely result in database locking issues.`,
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
Run: func(_ *cobra.Command, args []string) {
config.Database = args[0]
config.MaxMessages = 0

View File

@@ -126,6 +126,7 @@ func init() {
rootCmd.Flags().BoolVar(&config.SMTPStrictRFCHeaders, "smtp-strict-rfc-headers", config.SMTPStrictRFCHeaders, "Return SMTP error if message headers contain <CR><CR><LF>")
rootCmd.Flags().IntVar(&config.SMTPMaxRecipients, "smtp-max-recipients", config.SMTPMaxRecipients, "Maximum SMTP recipients allowed")
rootCmd.Flags().StringVar(&config.SMTPAllowedRecipients, "smtp-allowed-recipients", config.SMTPAllowedRecipients, "Only allow SMTP recipients matching a regular expression (default allow all)")
rootCmd.Flags().BoolVar(&config.SMTPIgnoreRejectedRecipients, "smtp-ignore-rejected-recipients", config.SMTPIgnoreRejectedRecipients, "Ignore rejected SMTP recipients with 2xx response")
rootCmd.Flags().BoolVar(&smtpd.DisableReverseDNS, "smtp-disable-rdns", smtpd.DisableReverseDNS, "Disable SMTP reverse DNS lookups")
// SMTP relay
@@ -301,6 +302,9 @@ func initConfigFromEnv() {
if len(os.Getenv("MP_SMTP_ALLOWED_RECIPIENTS")) > 0 {
config.SMTPAllowedRecipients = os.Getenv("MP_SMTP_ALLOWED_RECIPIENTS")
}
if getEnabledFromEnv("MP_SMTP_IGNORE_REJECTED_RECIPIENTS") {
config.SMTPIgnoreRejectedRecipients = true
}
if getEnabledFromEnv("MP_SMTP_DISABLE_RDNS") {
smtpd.DisableReverseDNS = true
}
@@ -328,6 +332,7 @@ func initConfigFromEnv() {
config.SMTPRelayConfig.AllowedRecipients = os.Getenv("MP_SMTP_RELAY_ALLOWED_RECIPIENTS")
config.SMTPRelayConfig.BlockedRecipients = os.Getenv("MP_SMTP_RELAY_BLOCKED_RECIPIENTS")
config.SMTPRelayConfig.PreserveMessageIDs = getEnabledFromEnv("MP_SMTP_RELAY_PRESERVE_MESSAGE_IDS")
config.SMTPRelayConfig.ForwardSMTPErrors = getEnabledFromEnv("MP_SMTP_RELAY_FWD_SMTP_ERRORS")
// SMTP forwarding
config.SMTPForwardConfigFile = os.Getenv("MP_SMTP_FORWARD_CONFIG")
@@ -346,6 +351,7 @@ func initConfigFromEnv() {
config.SMTPForwardConfig.ReturnPath = os.Getenv("MP_SMTP_FORWARD_RETURN_PATH")
config.SMTPForwardConfig.OverrideFrom = os.Getenv("MP_SMTP_FORWARD_OVERRIDE_FROM")
config.SMTPForwardConfig.To = os.Getenv("MP_SMTP_FORWARD_TO")
config.SMTPForwardConfig.ForwardSMTPErrors = getEnabledFromEnv("MP_SMTP_FORWARD_FWD_SMTP_ERRORS")
// Chaos
chaos.Enabled = getEnabledFromEnv("MP_ENABLE_CHAOS")

View File

@@ -14,8 +14,9 @@ var versionCmd = &cobra.Command{
Use: "version",
Short: "Display the current version & update information",
Long: `Display the current version & update information (if available).`,
Run: func(cmd *cobra.Command, args []string) {
Run: func(cmd *cobra.Command, _ []string) {
update, _ := cmd.Flags().GetBool("update")
noReleaseCheck, _ := cmd.Flags().GetBool("no-release-check")
if update {
// Update the application
@@ -32,23 +33,25 @@ var versionCmd = &cobra.Command{
fmt.Printf("%s %s compiled with %s on %s/%s\n",
os.Args[0], config.Version, runtime.Version(), runtime.GOOS, runtime.GOARCH)
release, err := config.GHRUConfig.Latest()
if err != nil {
fmt.Printf("Error checking for latest release: %s\n", err)
os.Exit(1)
}
if !noReleaseCheck {
release, err := config.GHRUConfig.Latest()
if err != nil {
fmt.Printf("Error checking for latest release: %s\n", err)
os.Exit(1)
}
// The latest version is the same version
if release.Tag == config.Version {
os.Exit(0)
}
// The latest version is the same version
if release.Tag == config.Version {
os.Exit(0)
}
// A newer release is available
fmt.Printf(
"\nUpdate available: %s\nRun `%s version -u` to update (requires read/write access to install directory).\n",
release.Tag,
os.Args[0],
)
// A newer release is available
fmt.Printf(
"\nUpdate available: %s\nRun `%s version -u` to update (requires read/write access to install directory).\n",
release.Tag,
os.Args[0],
)
}
},
}
@@ -57,4 +60,6 @@ func init() {
versionCmd.Flags().
BoolP("update", "u", false, "update to latest version")
versionCmd.Flags().
Bool("no-release-check", false, "do not check online for the latest release version")
}

View File

@@ -15,6 +15,7 @@ import (
"github.com/axllent/mailpit/internal/auth"
"github.com/axllent/mailpit/internal/logger"
"github.com/axllent/mailpit/internal/smtpd/chaos"
"github.com/axllent/mailpit/internal/snakeoil"
"github.com/axllent/mailpit/internal/spamassassin"
"github.com/axllent/mailpit/internal/tools"
)
@@ -130,7 +131,7 @@ var (
CLITagsArg string
// ValidTagRegexp represents a valid tag
ValidTagRegexp = regexp.MustCompile(`^([a-zA-Z0-9\-\ \_\.]){1,}$`)
ValidTagRegexp = regexp.MustCompile(`^([a-zA-Z0-9\-\ \_\.@]){1,100}$`)
// TagsConfig is a yaml file to pre-load tags
TagsConfig string
@@ -180,6 +181,9 @@ var (
// SMTPAllowedRecipientsRegexp is the compiled version of SMTPAllowedRecipients
SMTPAllowedRecipientsRegexp *regexp.Regexp
// SMTPIgnoreRejectedRecipients if true, will accept emails to rejected recipients with 2xx response but silently drop them
SMTPIgnoreRejectedRecipients bool
// POP3Listen address - if set then Mailpit will start the POP3 server and listen on this address
POP3Listen = "[::]:1110"
@@ -248,6 +252,7 @@ type SMTPRelayConfigStruct struct {
BlockedRecipients string `yaml:"blocked-recipients"` // regex, if set prevents relating to these addresses
BlockedRecipientsRegexp *regexp.Regexp // compiled regexp using BlockedRecipients
PreserveMessageIDs bool `yaml:"preserve-message-ids"` // preserve the original Message-ID when relaying
ForwardSMTPErrors bool `yaml:"forward-smtp-errors"` // whether to log smtp-errors or forward them to upstream-client
// DEPRECATED 2024/03/12
RecipientAllowlist string `yaml:"recipient-allowlist"`
@@ -255,18 +260,19 @@ type SMTPRelayConfigStruct struct {
// SMTPForwardConfigStruct struct for parsing yaml & storing variables
type SMTPForwardConfigStruct struct {
To string `yaml:"to"` // comma-separated list of email addresses
Host string `yaml:"host"` // SMTP host
Port int `yaml:"port"` // SMTP port
STARTTLS bool `yaml:"starttls"` // whether to use STARTTLS
TLS bool `yaml:"tls"` // whether to use TLS
AllowInsecure bool `yaml:"allow-insecure"` // allow insecure authentication, ignore TLS validation
Auth string `yaml:"auth"` // none, plain, login, cram-md5
Username string `yaml:"username"` // plain & cram-md5
Password string `yaml:"password"` // plain
Secret string `yaml:"secret"` // cram-md5
ReturnPath string `yaml:"return-path"` // allow overriding the bounce address
OverrideFrom string `yaml:"override-from"` // allow overriding of the from address
To string `yaml:"to"` // comma-separated list of email addresses
Host string `yaml:"host"` // SMTP host
Port int `yaml:"port"` // SMTP port
STARTTLS bool `yaml:"starttls"` // whether to use STARTTLS
TLS bool `yaml:"tls"` // whether to use TLS
AllowInsecure bool `yaml:"allow-insecure"` // allow insecure authentication, ignore TLS validation
Auth string `yaml:"auth"` // none, plain, login, cram-md5
Username string `yaml:"username"` // plain & cram-md5
Password string `yaml:"password"` // plain
Secret string `yaml:"secret"` // cram-md5
ReturnPath string `yaml:"return-path"` // allow overriding the bounce address
OverrideFrom string `yaml:"override-from"` // allow overriding of the from address
ForwardSMTPErrors bool `yaml:"forward-smtp-errors"` // whether to log smtp-errors or forward them to upstream-client
}
// VerifyConfig wil do some basic checking
@@ -279,7 +285,8 @@ func VerifyConfig() error {
// The default Content Security Policy is updates on every application page load to replace script-src 'self'
// with a random nonce ID to prevent XSS. This applies to the Mailpit app & API.
// See server.middleWareFunc()
ContentSecurityPolicy = fmt.Sprintf("default-src 'self'; script-src 'self'; style-src %s 'unsafe-inline'; frame-src 'self'; img-src * data: blob:; font-src %s data:; media-src 'self'; connect-src 'self' ws: wss:; object-src 'none'; base-uri 'self';",
ContentSecurityPolicy = fmt.Sprintf(
"default-src 'self'; script-src 'self'; style-src %s 'unsafe-inline'; frame-src 'self'; img-src * data: blob:; font-src %s data:; media-src 'self'; connect-src 'self' ws: wss:; object-src 'none'; base-uri 'self';",
cssFontRestriction, cssFontRestriction,
)
@@ -333,8 +340,19 @@ func VerifyConfig() error {
}
if UITLSCert != "" {
UITLSCert = filepath.Clean(UITLSCert)
UITLSKey = filepath.Clean(UITLSKey)
if strings.HasPrefix(UITLSCert, "sans:") {
// generate a self-signed certificate
UITLSCert = snakeoil.Public(UITLSCert)
} else {
UITLSCert = filepath.Clean(UITLSCert)
}
if strings.HasPrefix(UITLSKey, "sans:") {
// generate a self-signed key
UITLSKey = snakeoil.Private(UITLSKey)
} else {
UITLSKey = filepath.Clean(UITLSKey)
}
if !isFile(UITLSCert) {
return fmt.Errorf("[ui] TLS certificate not found or readable: %s", UITLSCert)
@@ -393,8 +411,19 @@ func VerifyConfig() error {
}
if SMTPTLSCert != "" {
SMTPTLSCert = filepath.Clean(SMTPTLSCert)
SMTPTLSKey = filepath.Clean(SMTPTLSKey)
if strings.HasPrefix(SMTPTLSCert, "sans:") {
// generate a self-signed certificate
SMTPTLSCert = snakeoil.Public(SMTPTLSCert)
} else {
SMTPTLSCert = filepath.Clean(SMTPTLSCert)
}
if strings.HasPrefix(SMTPTLSKey, "sans:") {
// generate a self-signed key
SMTPTLSKey = snakeoil.Private(SMTPTLSKey)
} else {
SMTPTLSKey = filepath.Clean(SMTPTLSKey)
}
if !isFile(SMTPTLSCert) {
return fmt.Errorf("[smtp] TLS certificate not found or readable: %s", SMTPTLSCert)
@@ -462,8 +491,18 @@ func VerifyConfig() error {
// POP3 server
if POP3TLSCert != "" {
POP3TLSCert = filepath.Clean(POP3TLSCert)
POP3TLSKey = filepath.Clean(POP3TLSKey)
if strings.HasPrefix(POP3TLSCert, "sans:") {
// generate a self-signed certificate
POP3TLSCert = snakeoil.Public(POP3TLSCert)
} else {
POP3TLSCert = filepath.Clean(POP3TLSCert)
}
if strings.HasPrefix(POP3TLSKey, "sans:") {
// generate a self-signed key
POP3TLSKey = snakeoil.Private(POP3TLSKey)
} else {
POP3TLSKey = filepath.Clean(POP3TLSKey)
}
if !isFile(POP3TLSCert) {
return fmt.Errorf("[pop3] TLS certificate not found or readable: %s", POP3TLSCert)
@@ -548,6 +587,14 @@ func VerifyConfig() error {
logger.Log().Infof("[smtp] only allowing recipients matching regexp: %s", SMTPAllowedRecipients)
}
if SMTPIgnoreRejectedRecipients {
if SMTPAllowedRecipientsRegexp == nil {
logger.Log().Warn("[smtp] ignoring rejected recipients has no effect without setting smtp-allowed-recipients")
} else {
logger.Log().Info("[smtp] ignoring rejected recipients")
}
}
if err := parseRelayConfig(SMTPRelayConfigFile); err != nil {
return err
}
@@ -571,8 +618,10 @@ func VerifyConfig() error {
}
SMTPRelayMatchingRegexp = re
logger.Log().Infof("[relay] auto-relaying new messages to recipients matching \"%s\" via %s:%d",
SMTPRelayMatching, SMTPRelayConfig.Host, SMTPRelayConfig.Port)
logger.Log().Infof(
"[relay] auto-relaying new messages to recipients matching \"%s\" via %s:%d",
SMTPRelayMatching, SMTPRelayConfig.Host, SMTPRelayConfig.Port,
)
}
}

View File

@@ -1,34 +1,76 @@
import eslintConfigPrettier from "eslint-config-prettier/flat";
import neostandard, { resolveIgnoresFromGitignore } from "neostandard";
import globals from "globals";
import { includeIgnoreFile } from "@eslint/compat";
import js from "@eslint/js";
import vue from "eslint-plugin-vue";
import { fileURLToPath } from "node:url";
const gitignorePath = fileURLToPath(new URL(".gitignore", import.meta.url));
export default [
/* Baseline JS rules, provided by Neostandard */
...neostandard({
/* Allows references to browser APIs like `document` */
env: ["browser"],
/* Use .gitignore to prevent linting of irrelevant files */
includeIgnoreFile(gitignorePath, ".gitignore"),
/* We rely on .gitignore to avoid running against dist / dependency files */
ignores: resolveIgnoresFromGitignore(),
/* Disables a range of style-related rules, as we use Prettier for that */
noStyle: true,
/* Ensures we only lint JS and Vue files */
/* ESLint's recommended rules */
{
files: ["**/*.js", "**/*.vue"],
}),
languageOptions: { globals: { ...globals.browser, ...globals.node } },
rules: js.configs.recommended.rules,
},
/* Vue-specific rules */
...vue.configs["flat/recommended"],
/* Prettier is responsible for formatting, so this disables any conflicting rules */
/* Prettier is responsible for formatting, so we disable conflicting rules */
eslintConfigPrettier,
/* Our custom rules */
{
rules: {
/* We prefer arrow functions for tidiness and consistency */
/* Always use arrow functions for tidiness and consistency */
"prefer-arrow-callback": "error",
/* Always use camelCase for variable names */
camelcase: [
"error",
{
ignoreDestructuring: false,
ignoreGlobals: true,
ignoreImports: false,
properties: "never",
},
],
/* The default case in switch statements must always be last */
"default-case-last": "error",
/* Always use dot notation where possible (e.g. `obj.val` over `obj['val']`) */
"dot-notation": "error",
/* Always use `===` and `!==` for comparisons unless unambiguous */
eqeqeq: ["error", "smart"],
/* Never use `eval()` as it violates our CSP and can lead to security issues */
"no-eval": "error",
"no-implied-eval": "error",
/* Prevents accidental use of template literals in plain strings, e.g. "my ${var}" */
"no-template-curly-in-string": "error",
/* Avoid unnecessary ternary operators */
"no-unneeded-ternary": "error",
/* Avoid unused expressions that have no purpose */
"no-unused-expressions": "error",
/* Always use `const` or `let` to make scope behaviour clear */
"no-var": "error",
/* Always use shorthand syntax for objects where possible, e.g. { a, b() { } } */
"object-shorthand": "error",
/* Always use `const` for variables that are never reassigned */
"prefer-const": "error",
},
},
];

68
go.mod
View File

@@ -3,32 +3,33 @@ module github.com/axllent/mailpit
go 1.24.3
require (
github.com/PuerkitoBio/goquery v1.10.3
github.com/PuerkitoBio/goquery v1.11.0
github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de
github.com/axllent/ghru/v2 v2.0.2
github.com/axllent/semver v1.0.0
github.com/goccy/go-yaml v1.18.0
github.com/gomarkdown/markdown v0.0.0-20250311123330-531bef5e742b
github.com/goccy/go-yaml v1.19.2
github.com/gomarkdown/markdown v0.0.0-20250810172220-2e2c11897d1a
github.com/gorilla/mux v1.8.1
github.com/gorilla/websocket v1.5.3
github.com/jhillyerd/enmime/v2 v2.2.0
github.com/klauspost/compress v1.18.0
github.com/kovidgoyal/imaging v1.6.4
github.com/klauspost/compress v1.18.3
github.com/kovidgoyal/imaging v1.8.19
github.com/leporo/sqlf v1.4.0
github.com/lithammer/shortuuid/v4 v4.2.0
github.com/mneis/go-telnet v0.0.0-20221017141824-6f643e477c62
github.com/prometheus/client_golang v1.22.0
github.com/pkg/errors v0.9.1
github.com/prometheus/client_golang v1.23.2
github.com/rqlite/gorqlite v0.0.0-20250609141355-ac86a4a1c9a8
github.com/sirupsen/logrus v1.9.3
github.com/spf13/cobra v1.9.1
github.com/spf13/pflag v1.0.6
github.com/sirupsen/logrus v1.9.4
github.com/spf13/cobra v1.10.2
github.com/spf13/pflag v1.0.10
github.com/tg123/go-htpasswd v1.2.4
github.com/vanng822/go-premailer v1.25.0
golang.org/x/crypto v0.39.0
golang.org/x/net v0.41.0
golang.org/x/text v0.26.0
golang.org/x/time v0.12.0
modernc.org/sqlite v1.38.0
github.com/vanng822/go-premailer v1.30.0
golang.org/x/crypto v0.47.0
golang.org/x/net v0.49.0
golang.org/x/text v0.33.0
golang.org/x/time v0.14.0
modernc.org/sqlite v1.44.3
)
require (
@@ -37,6 +38,9 @@ require (
github.com/beorn7/perks v1.0.1 // indirect
github.com/cention-sany/utf7 v0.0.0-20170124080048-26cad61bd60a // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/clipperhouse/displaywidth v0.7.0 // indirect
github.com/clipperhouse/stringish v0.1.1 // indirect
github.com/clipperhouse/uax29/v2 v2.3.1 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/fatih/color v1.18.0 // indirect
github.com/gogs/chardet v0.0.0-20211120154057-b7413eaefb8f // indirect
@@ -44,30 +48,34 @@ require (
github.com/gorilla/css v1.0.1 // indirect
github.com/inbucket/html2text v1.0.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/kovidgoyal/go-parallel v1.1.1 // indirect
github.com/kovidgoyal/go-shm v1.0.0 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/mattn/go-colorable v0.1.14 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-runewidth v0.0.16 // indirect
github.com/mattn/go-runewidth v0.0.19 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/ncruces/go-strftime v0.1.9 // indirect
github.com/olekukonko/errors v1.1.0 // indirect
github.com/olekukonko/ll v0.0.9 // indirect
github.com/olekukonko/tablewriter v1.0.8 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/ncruces/go-strftime v1.0.0 // indirect
github.com/olekukonko/cat v0.0.0-20250911104152-50322a0618f6 // indirect
github.com/olekukonko/errors v1.2.0 // indirect
github.com/olekukonko/ll v0.1.4-0.20260115111900-9e59c2286df0 // indirect
github.com/olekukonko/tablewriter v1.1.3 // indirect
github.com/prometheus/client_model v0.6.2 // indirect
github.com/prometheus/common v0.65.0 // indirect
github.com/prometheus/procfs v0.17.0 // indirect
github.com/prometheus/common v0.67.5 // indirect
github.com/prometheus/procfs v0.19.2 // indirect
github.com/reiver/go-oi v1.0.0 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
github.com/rivo/uniseg v0.4.7 // indirect
github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd // indirect
github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/vanng822/css v1.0.1 // indirect
golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b // indirect
golang.org/x/image v0.28.0 // indirect
golang.org/x/mod v0.25.0 // indirect
golang.org/x/sys v0.33.0 // indirect
google.golang.org/protobuf v1.36.6 // indirect
modernc.org/libc v1.66.2 // indirect
go.yaml.in/yaml/v2 v2.4.3 // indirect
golang.org/x/exp v0.0.0-20260112195511-716be5621a96 // indirect
golang.org/x/image v0.35.0 // indirect
golang.org/x/mod v0.32.0 // indirect
golang.org/x/sys v0.40.0 // indirect
google.golang.org/protobuf v1.36.11 // indirect
modernc.org/libc v1.67.6 // indirect
modernc.org/mathutil v1.7.1 // indirect
modernc.org/memory v1.11.0 // indirect
)

177
go.sum
View File

@@ -1,7 +1,7 @@
github.com/GehirnInc/crypt v0.0.0-20230320061759-8cc1b52080c5 h1:IEjq88XO4PuBDcvmjQJcQGg+w+UaafSy8G5Kcb5tBhI=
github.com/GehirnInc/crypt v0.0.0-20230320061759-8cc1b52080c5/go.mod h1:exZ0C/1emQJAw5tHOaUDyY1ycttqBAPcxuzf7QbY6ec=
github.com/PuerkitoBio/goquery v1.10.3 h1:pFYcNSqHxBD06Fpj/KsbStFRsgRATgnf3LeXiUkhzPo=
github.com/PuerkitoBio/goquery v1.10.3/go.mod h1:tMUX0zDMHXYlAQk6p35XxQMqMweEKB7iK7iLNd4RH4Y=
github.com/PuerkitoBio/goquery v1.11.0 h1:jZ7pwMQXIITcUXNH83LLk+txlaEy6NVOfTuP43xxfqw=
github.com/PuerkitoBio/goquery v1.11.0/go.mod h1:wQHgxUOU3JGuj3oD/QFfxUdlzW6xPHfqyHre6VMY4DQ=
github.com/andybalholm/cascadia v1.3.3 h1:AG2YHrzJIm4BZ19iwJ/DAua6Btl3IwJX+VI4kktS1LM=
github.com/andybalholm/cascadia v1.3.3/go.mod h1:xNd9bqTn98Ln4DwST8/nG+H0yuB8Hmgu1YHNnWw0GeA=
github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de h1:FxWPpzIjnTlhPwqqXc4/vE0f7GvRjuAsbW+HOIe8KnA=
@@ -16,7 +16,14 @@ github.com/cention-sany/utf7 v0.0.0-20170124080048-26cad61bd60a h1:MISbI8sU/PSK/
github.com/cention-sany/utf7 v0.0.0-20170124080048-26cad61bd60a/go.mod h1:2GxOXOlEPAMFPfp014mK1SWq8G8BN8o7/dfYqJrVGn8=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/clipperhouse/displaywidth v0.7.0 h1:QNv1GYsnLX9QBrcWUtMlogpTXuM5FVnBwKWp1O5NwmE=
github.com/clipperhouse/displaywidth v0.7.0/go.mod h1:R+kHuzaYWFkTm7xoMmK1lFydbci4X2CicfbGstSGg0o=
github.com/clipperhouse/stringish v0.1.1 h1:+NSqMOr3GR6k1FdRhhnXrLfztGzuG+VuFDfatpWHKCs=
github.com/clipperhouse/stringish v0.1.1/go.mod h1:v/WhFtE1q0ovMta2+m+UbpZ+2/HEXNWYXQgCt4hdOzA=
github.com/clipperhouse/uax29/v2 v2.3.1 h1:RjM8gnVbFbgI67SBekIC7ihFpyXwRPYWXn9BZActHbw=
github.com/clipperhouse/uax29/v2 v2.3.1/go.mod h1:Wn1g7MK6OoeDT0vL+Q0SQLDz/KpfsVRgg6W7ihQeh4g=
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -26,12 +33,12 @@ github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
github.com/go-test/deep v1.1.1 h1:0r/53hagsehfO4bzD2Pgr/+RgHqhmf+k1Bpse2cTu1U=
github.com/go-test/deep v1.1.1/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
github.com/goccy/go-yaml v1.18.0 h1:8W7wMFS12Pcas7KU+VVkaiCng+kG8QiFeFwzFb+rwuw=
github.com/goccy/go-yaml v1.18.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA=
github.com/goccy/go-yaml v1.19.2 h1:PmFC1S6h8ljIz6gMRBopkjP1TVT7xuwrButHID66PoM=
github.com/goccy/go-yaml v1.19.2/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA=
github.com/gogs/chardet v0.0.0-20211120154057-b7413eaefb8f h1:3BSP1Tbs2djlpprl7wCLuiqMaUh5SJkkzI2gDs+FgLs=
github.com/gogs/chardet v0.0.0-20211120154057-b7413eaefb8f/go.mod h1:Pcatq5tYkCW2Q6yrR2VRHlbHpZ/R4/7qyL1TCF7vl14=
github.com/gomarkdown/markdown v0.0.0-20250311123330-531bef5e742b h1:EY/KpStFl60qA17CptGXhwfZ+k1sFNJIUNR8DdbcuUk=
github.com/gomarkdown/markdown v0.0.0-20250311123330-531bef5e742b/go.mod h1:JDGcbDT52eL4fju3sZ4TeHGsQwhG9nbDV21aMyhwPoA=
github.com/gomarkdown/markdown v0.0.0-20250810172220-2e2c11897d1a h1:l7A0loSszR5zHd/qK53ZIHMO8b3bBSmENnQ6eKnUT0A=
github.com/gomarkdown/markdown v0.0.0-20250810172220-2e2c11897d1a/go.mod h1:JDGcbDT52eL4fju3sZ4TeHGsQwhG9nbDV21aMyhwPoA=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
@@ -45,16 +52,26 @@ github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
github.com/inbucket/html2text v1.0.0 h1:N5kza++4uBBDJ2Z3KUnTRyPNoBcW+YfOgNiNmNB+sgs=
github.com/inbucket/html2text v1.0.0/go.mod h1:5TrhXQKGU+LXurODaSm55Y9eXoPBRnYiOz4x2XfUoJU=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/jhillyerd/enmime/v2 v2.2.0 h1:Pe35MB96eZK5Q0XjlvPftOgWypQpd1gcbfJKAt7rsB8=
github.com/jhillyerd/enmime/v2 v2.2.0/go.mod h1:SOBXlCemjhiV2DvHhAKnJiWrtJGS/Ffuw4Iy7NjBTaI=
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
github.com/kovidgoyal/imaging v1.6.4 h1:K0idhRPXnRrJBKnBYcTfI1HTWSNDeAn7hYDvf9I0dCk=
github.com/kovidgoyal/imaging v1.6.4/go.mod h1:bEIgsaZmXlvFfkv/CUxr9rJook6AQkJnpB5EPosRfRY=
github.com/klauspost/compress v1.18.3 h1:9PJRvfbmTabkOX8moIpXPbMMbYN60bWImDDU7L+/6zw=
github.com/klauspost/compress v1.18.3/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4=
github.com/kovidgoyal/go-parallel v1.1.1 h1:1OzpNjtrUkBPq3UaqrnvOoB2F9RttSt811uiUXyI7ok=
github.com/kovidgoyal/go-parallel v1.1.1/go.mod h1:BJNIbe6+hxyFWv7n6oEDPj3PA5qSw5OCtf0hcVxWJiw=
github.com/kovidgoyal/go-shm v1.0.0 h1:HJEel9D1F9YhULvClEHJLawoRSj/1u/EDV7MJbBPgQo=
github.com/kovidgoyal/go-shm v1.0.0/go.mod h1:Yzb80Xf9L3kaoB2RGok9hHwMIt7Oif61kT6t3+VnZds=
github.com/kovidgoyal/imaging v1.8.19 h1:zWJdQqF2tfSKjvoB7XpLRhVGbYsze++M0iaqZ4ZkhNk=
github.com/kovidgoyal/imaging v1.8.19/go.mod h1:I0q8RdoEuyc4G8GFOF9CaluTUHQSf68d6TmsqpvfRI8=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
github.com/leporo/sqlf v1.4.0 h1:SyWnX/8GSGOzVmanG0Ub1c04mR9nNl6Tq3IeFKX2/4c=
@@ -66,52 +83,56 @@ github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stg
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mattn/go-runewidth v0.0.19 h1:v++JhqYnZuu5jSKrk9RbgF5v4CGUjqRfBm05byFGLdw=
github.com/mattn/go-runewidth v0.0.19/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs=
github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y=
github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
github.com/mneis/go-telnet v0.0.0-20221017141824-6f643e477c62 h1:XMG5DklHoioVYysfYglOB7vRBg/LOUJZy2mq2QyedLg=
github.com/mneis/go-telnet v0.0.0-20221017141824-6f643e477c62/go.mod h1:niAM5cni0I/47IFA995xQfeK58Mkbb7FHJjacY4OGQg=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4=
github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls=
github.com/olekukonko/errors v1.1.0 h1:RNuGIh15QdDenh+hNvKrJkmxxjV4hcS50Db478Ou5sM=
github.com/olekukonko/errors v1.1.0/go.mod h1:ppzxA5jBKcO1vIpCXQ9ZqgDh8iwODz6OXIGKU8r5m4Y=
github.com/olekukonko/ll v0.0.9 h1:Y+1YqDfVkqMWuEQMclsF9HUR5+a82+dxJuL1HHSRpxI=
github.com/olekukonko/ll v0.0.9/go.mod h1:En+sEW0JNETl26+K8eZ6/W4UQ7CYSrrgg/EdIYT2H8g=
github.com/olekukonko/tablewriter v1.0.8 h1:f6wJzHg4QUtJdvrVPKco4QTrAylgaU0+b9br/lJxEiQ=
github.com/olekukonko/tablewriter v1.0.8/go.mod h1:H428M+HzoUXC6JU2Abj9IT9ooRmdq9CxuDmKMtrOCMs=
github.com/ncruces/go-strftime v1.0.0 h1:HMFp8mLCTPp341M/ZnA4qaf7ZlsbTc+miZjCLOFAw7w=
github.com/ncruces/go-strftime v1.0.0/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls=
github.com/olekukonko/cat v0.0.0-20250911104152-50322a0618f6 h1:zrbMGy9YXpIeTnGj4EljqMiZsIcE09mmF8XsD5AYOJc=
github.com/olekukonko/cat v0.0.0-20250911104152-50322a0618f6/go.mod h1:rEKTHC9roVVicUIfZK7DYrdIoM0EOr8mK1Hj5s3JjH0=
github.com/olekukonko/errors v1.2.0 h1:10Zcn4GeV59t/EGqJc8fUjtFT/FuUh5bTMzZ1XwmCRo=
github.com/olekukonko/errors v1.2.0/go.mod h1:ppzxA5jBKcO1vIpCXQ9ZqgDh8iwODz6OXIGKU8r5m4Y=
github.com/olekukonko/ll v0.1.4-0.20260115111900-9e59c2286df0 h1:jrYnow5+hy3WRDCBypUFvVKNSPPCdqgSXIE9eJDD8LM=
github.com/olekukonko/ll v0.1.4-0.20260115111900-9e59c2286df0/go.mod h1:b52bVQRRPObe+yyBl0TxNfhesL0nedD4Cht0/zx55Ew=
github.com/olekukonko/tablewriter v1.1.3 h1:VSHhghXxrP0JHl+0NnKid7WoEmd9/urKRJLysb70nnA=
github.com/olekukonko/tablewriter v1.1.3/go.mod h1:9VU0knjhmMkXjnMKrZ3+L2JhhtsQ/L38BbL3CRNE8tM=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_golang v1.22.0 h1:rb93p9lokFEsctTys46VnV1kLCDpVZ0a/Y92Vm0Zc6Q=
github.com/prometheus/client_golang v1.22.0/go.mod h1:R7ljNsLXhuQXYZYtw6GAE9AZg8Y7vEW5scdCXrWRXC0=
github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o=
github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg=
github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk=
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
github.com/prometheus/common v0.65.0 h1:QDwzd+G1twt//Kwj/Ww6E9FQq1iVMmODnILtW1t2VzE=
github.com/prometheus/common v0.65.0/go.mod h1:0gZns+BLRQ3V6NdaerOhMbwwRbNh9hkGINtQAsP5GS8=
github.com/prometheus/procfs v0.17.0 h1:FuLQ+05u4ZI+SS/w9+BWEM2TXiHKsUQ9TADiRH7DuK0=
github.com/prometheus/procfs v0.17.0/go.mod h1:oPQLaDAMRbA+u8H5Pbfq+dl3VDAvHxMUOVhe0wYB2zw=
github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4=
github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw=
github.com/prometheus/procfs v0.19.2 h1:zUMhqEW66Ex7OXIiDkll3tl9a1ZdilUOd/F6ZXw4Vws=
github.com/prometheus/procfs v0.19.2/go.mod h1:M0aotyiemPhBCM0z5w87kL22CxfcH05ZpYlu+b4J7mw=
github.com/reiver/go-oi v1.0.0 h1:nvECWD7LF+vOs8leNGV/ww+F2iZKf3EYjYZ527turzM=
github.com/reiver/go-oi v1.0.0/go.mod h1:RrDBct90BAhoDTxB1fenZwfykqeGvhI6LsNfStJoEkI=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
github.com/rqlite/gorqlite v0.0.0-20250609141355-ac86a4a1c9a8 h1:BoxiqWvhprOB2isgM59s8wkgKwAoyQH66Twfmof41oE=
github.com/rqlite/gorqlite v0.0.0-20250609141355-ac86a4a1c9a8/go.mod h1:xF/KoXmrRyahPfo5L7Szb5cAAUl53dMWBh9cMruGEZg=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd h1:CmH9+J6ZSsIjUK3dcGsnCnO41eRBOnY12zwkn5qVwgc=
github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd/go.mod h1:hPqNNc0+uJM6H+SuU8sEs5K5IQeKccPqeSjfgcKGgPk=
github.com/scylladb/termtables v0.0.0-20191203121021-c4c0b6d42ff4/go.mod h1:C1a7PQSMz9NShzorzCiG2fk9+xuCgLkPeCvMHYR2OWg=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/sirupsen/logrus v1.9.4 h1:TsZE7l11zFCLZnZ+teH4Umoq5BhEIfIzfRDZ1Uzql2w=
github.com/sirupsen/logrus v1.9.4/go.mod h1:ftWc9WdOfJ0a92nsE2jF5u5ZwH8Bv2zdeOC42RjbV2g=
github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU=
github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4=
github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf h1:pvbZ0lM0XWPBqUKqFU8cmavspvIl9nulOYwdy6IFRRo=
github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf/go.mod h1:RJID2RhlZKId02nZ62WenDCkgHFerpIOmW0iT7GKmXM=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
@@ -121,36 +142,41 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
github.com/tg123/go-htpasswd v1.2.4 h1:HgH8KKCjdmo7jjXWN9k1nefPBd7Be3tFCTjc2jPraPU=
github.com/tg123/go-htpasswd v1.2.4/go.mod h1:EKThQok9xHkun6NBMynNv6Jmu24A33XdZzzl4Q7H1+0=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/vanng822/css v1.0.1 h1:10yiXc4e8NI8ldU6mSrWmSWMuyWgPr9DZ63RSlsgDw8=
github.com/vanng822/css v1.0.1/go.mod h1:tcnB1voG49QhCrwq1W0w5hhGasvOg+VQp9i9H1rCM1w=
github.com/vanng822/go-premailer v1.25.0 h1:hGHKfroCXrCDTyGVR8o4HCON5/HWvc7C1uocS+VnaZs=
github.com/vanng822/go-premailer v1.25.0/go.mod h1:8WJKIPZtegxqSOA8+eDFx7QNesKmMYfGEIodLTJqrtM=
github.com/vanng822/go-premailer v1.30.0 h1:9oAp2PrJm4rvPnBgP57J/K1sJ1fQvSrU8TxamFvvwGU=
github.com/vanng822/go-premailer v1.30.0/go.mod h1:1okMIRBIcWIK1g5vJKaXi2ytD1ulsIc9wUGwK7UD3/I=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0=
go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8=
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
golang.org/x/crypto v0.39.0 h1:SHs+kF4LP+f+p14esP5jAoDpHU8Gu/v9lFRK6IT5imM=
golang.org/x/crypto v0.39.0/go.mod h1:L+Xg3Wf6HoL4Bn4238Z6ft6KfEpN0tJGo53AAPC632U=
golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b h1:M2rDM6z3Fhozi9O7NWsxAkg/yqS/lQJ6PmkyIV3YP+o=
golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b/go.mod h1:3//PLf8L/X+8b4vuAfHzxeRUl04Adcb341+IGKfnqS8=
golang.org/x/image v0.28.0 h1:gdem5JW1OLS4FbkWgLO+7ZeFzYtL3xClb97GaUzYMFE=
golang.org/x/image v0.28.0/go.mod h1:GUJYXtnGKEUgggyzh+Vxt+AviiCcyiwpsl8iQ8MvwGY=
golang.org/x/crypto v0.47.0 h1:V6e3FRj+n4dbpw86FJ8Fv7XVOql7TEwpHapKoMJ/GO8=
golang.org/x/crypto v0.47.0/go.mod h1:ff3Y9VzzKbwSSEzWqJsJVBnWmRwRSHt/6Op5n9bQc4A=
golang.org/x/exp v0.0.0-20260112195511-716be5621a96 h1:Z/6YuSHTLOHfNFdb8zVZomZr7cqNgTJvA8+Qz75D8gU=
golang.org/x/exp v0.0.0-20260112195511-716be5621a96/go.mod h1:nzimsREAkjBCIEFtHiYkrJyT+2uy9YZJB7H1k68CXZU=
golang.org/x/image v0.35.0 h1:LKjiHdgMtO8z7Fh18nGY6KDcoEtVfsgLDPeLyguqb7I=
golang.org/x/image v0.35.0/go.mod h1:MwPLTVgvxSASsxdLzKrl8BRFuyqMyGhLwmC+TO1Sybk=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.25.0 h1:n7a+ZbQKQA/Ysbyb0/6IbB1H/X41mKgbhfv7AfG/44w=
golang.org/x/mod v0.25.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
golang.org/x/mod v0.32.0 h1:9F4d3PHLljb6x//jOyokMv3eX+YDeepZSEo3mFJy93c=
golang.org/x/mod v0.32.0/go.mod h1:SgipZ/3h2Ci89DlEtEXWUk/HteuRin+HHhN+WbNhguU=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
@@ -160,8 +186,8 @@ golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
golang.org/x/net v0.41.0 h1:vBTly1HeNPEn3wtREYfy4GZ/NECgw2Cnl+nK6Nz3uvw=
golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA=
golang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o=
golang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -169,13 +195,12 @@ golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.15.0 h1:KWH3jNZsfyT6xfAfKiz6MRNmd46ByHDYaZ7KSkCtdW8=
golang.org/x/sync v0.15.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@@ -184,8 +209,8 @@ golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ=
golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
@@ -204,37 +229,41 @@ golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M=
golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA=
golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE=
golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE=
golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8=
golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI=
golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
golang.org/x/tools v0.34.0 h1:qIpSLOxeCYGg9TrcJokLBG4KFA6d795g0xkBkiESGlo=
golang.org/x/tools v0.34.0/go.mod h1:pAP9OwEaY1CAW3HOmg3hLZC5Z0CCmzjAF2UQMSqNARg=
golang.org/x/tools v0.41.0 h1:a9b8iMweWG+S0OBnlU36rzLp20z1Rp10w+IY2czHTQc=
golang.org/x/tools v0.41.0/go.mod h1:XSY6eDqxVNiYgezAVqqCeihT4j1U2CCsqvH3WhQpnlg=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
modernc.org/cc/v4 v4.26.2 h1:991HMkLjJzYBIfha6ECZdjrIYz2/1ayr+FL8GN+CNzM=
modernc.org/cc/v4 v4.26.2/go.mod h1:uVtb5OGqUKpoLWhqwNQo/8LwvoiEBLvZXIQ/SmO6mL0=
modernc.org/ccgo/v4 v4.28.0 h1:rjznn6WWehKq7dG4JtLRKxb52Ecv8OUGah8+Z/SfpNU=
modernc.org/ccgo/v4 v4.28.0/go.mod h1:JygV3+9AV6SmPhDasu4JgquwU81XAKLd3OKTUDNOiKE=
modernc.org/fileutil v1.3.8 h1:qtzNm7ED75pd1C7WgAGcK4edm4fvhtBsEiI/0NQ54YM=
modernc.org/fileutil v1.3.8/go.mod h1:HxmghZSZVAz/LXcMNwZPA/DRrQZEVP9VX0V4LQGQFOc=
modernc.org/cc/v4 v4.27.1 h1:9W30zRlYrefrDV2JE2O8VDtJ1yPGownxciz5rrbQZis=
modernc.org/cc/v4 v4.27.1/go.mod h1:uVtb5OGqUKpoLWhqwNQo/8LwvoiEBLvZXIQ/SmO6mL0=
modernc.org/ccgo/v4 v4.30.1 h1:4r4U1J6Fhj98NKfSjnPUN7Ze2c6MnAdL0hWw6+LrJpc=
modernc.org/ccgo/v4 v4.30.1/go.mod h1:bIOeI1JL54Utlxn+LwrFyjCx2n2RDiYEaJVSrgdrRfM=
modernc.org/fileutil v1.3.40 h1:ZGMswMNc9JOCrcrakF1HrvmergNLAmxOPjizirpfqBA=
modernc.org/fileutil v1.3.40/go.mod h1:HxmghZSZVAz/LXcMNwZPA/DRrQZEVP9VX0V4LQGQFOc=
modernc.org/gc/v2 v2.6.5 h1:nyqdV8q46KvTpZlsw66kWqwXRHdjIlJOhG6kxiV/9xI=
modernc.org/gc/v2 v2.6.5/go.mod h1:YgIahr1ypgfe7chRuJi2gD7DBQiKSLMPgBQe9oIiito=
modernc.org/goabi0 v0.1.2 h1:9mfG19tFBypPnlSKRAjI5nXGMLmVy+jLyKNVKsMzt/8=
modernc.org/goabi0 v0.1.2/go.mod h1:CEFRnnJhKvWT1c1JTI3Avm+tgOWbkOu5oPA8eH8LnMI=
modernc.org/libc v1.66.2 h1:JCBxlJzZOIwZY54fzjHN3Wsn8Ty5PUTPr/xioRkmecI=
modernc.org/libc v1.66.2/go.mod h1:ceIGzvXxP+JV3pgVjP9avPZo6Chlsfof2egXBH3YT5Q=
modernc.org/gc/v3 v3.1.1 h1:k8T3gkXWY9sEiytKhcgyiZ2L0DTyCQ/nvX+LoCljoRE=
modernc.org/gc/v3 v3.1.1/go.mod h1:HFK/6AGESC7Ex+EZJhJ2Gni6cTaYpSMmU/cT9RmlfYY=
modernc.org/goabi0 v0.2.0 h1:HvEowk7LxcPd0eq6mVOAEMai46V+i7Jrj13t4AzuNks=
modernc.org/goabi0 v0.2.0/go.mod h1:CEFRnnJhKvWT1c1JTI3Avm+tgOWbkOu5oPA8eH8LnMI=
modernc.org/libc v1.67.6 h1:eVOQvpModVLKOdT+LvBPjdQqfrZq+pC39BygcT+E7OI=
modernc.org/libc v1.67.6/go.mod h1:JAhxUVlolfYDErnwiqaLvUqc8nfb2r6S6slAgZOnaiE=
modernc.org/mathutil v1.7.1 h1:GCZVGXdaN8gTqB1Mf/usp1Y/hSqgI2vAGGP4jZMCxOU=
modernc.org/mathutil v1.7.1/go.mod h1:4p5IwJITfppl0G4sUEDtCr4DthTaT47/N3aT6MhfgJg=
modernc.org/memory v1.11.0 h1:o4QC8aMQzmcwCK3t3Ux/ZHmwFPzE6hf2Y5LbkRs+hbI=
@@ -243,8 +272,8 @@ modernc.org/opt v0.1.4 h1:2kNGMRiUjrp4LcaPuLY2PzUfqM/w9N23quVwhKt5Qm8=
modernc.org/opt v0.1.4/go.mod h1:03fq9lsNfvkYSfxrfUhZCWPk1lm4cq4N+Bh//bEtgns=
modernc.org/sortutil v1.2.1 h1:+xyoGf15mM3NMlPDnFqrteY07klSFxLElE2PVuWIJ7w=
modernc.org/sortutil v1.2.1/go.mod h1:7ZI3a3REbai7gzCLcotuw9AC4VZVpYMjDzETGsSMqJE=
modernc.org/sqlite v1.38.0 h1:+4OrfPQ8pxHKuWG4md1JpR/EYAh3Md7TdejuuzE7EUI=
modernc.org/sqlite v1.38.0/go.mod h1:1Bj+yES4SVvBZ4cBOpVZ6QgesMCKpJZDq0nxYzOpmNE=
modernc.org/sqlite v1.44.3 h1:+39JvV/HWMcYslAwRxHb8067w+2zowvFOUrOWIy9PjY=
modernc.org/sqlite v1.44.3/go.mod h1:CzbrU2lSB1DKUusvwGz7rqEKIq+NUd8GWuBBZDs9/nA=
modernc.org/strutil v1.2.1 h1:UneZBkQA+DX2Rp35KcM69cSsNES9ly8mQWD71HKlOA0=
modernc.org/strutil v1.2.1/go.mod h1:EHkiggD70koQxjVdSBM3JKM7k6L0FbGE5eymy9i3B9A=
modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y=

View File

@@ -15,7 +15,7 @@ done
OS=
case "$(uname -s)" in
Linux) OS="linux" ;;
Darwin) OS="Darwin" ;;
Darwin) OS="darwin" ;;
*)
echo "OS not supported."
exit 2

View File

@@ -1,6 +1,6 @@
{
"api_version":"1.0.4",
"last_update_date":"2025-06-12 18:27:28 +0000",
"last_update_date":"2025-11-10 14:54:35 +0000",
"nicenames":{"family":{"gmail":"Gmail","outlook":"Outlook","yahoo":"Yahoo! Mail","apple-mail":"Apple Mail","aol":"AOL","thunderbird":"Mozilla Thunderbird","microsoft":"Microsoft","samsung-email":"Samsung Email","sfr":"SFR","orange":"Orange","protonmail":"ProtonMail","hey":"HEY","mail-ru":"Mail.ru","fastmail":"Fastmail","laposte":"LaPoste.net","t-online-de":"T-online.de","free-fr":"Free.fr","gmx":"GMX","web-de":"WEB.DE","ionos-1and1":"1&1","rainloop":"RainLoop","wp-pl":"WP.pl"},"platform":{"desktop-app":"Desktop","desktop-webmail":"Desktop Webmail","mobile-webmail":"Mobile Webmail","webmail":"Webmail","ios":"iOS","android":"Android","windows":"Windows","macos":"macOS","windows-mail":"Windows Mail","outlook-com":"Outlook.com"},"support":{"supported":"Supported","mitigated":"Partially supported","unsupported":"Not supported","unknown":"Support unknown","mixed":"Mixed support"},"category":{"html":"HTML","css":"CSS","image":"Image formats","others":"Others"}},
"data":[
{
@@ -110,7 +110,7 @@
"last_test_date":"2023-12-19",
"test_url":"https://www.caniemail.com/tests/css-font-face.html",
"test_results_url":"https://app.emailonacid.com/app/acidtest/veY9MhuhgFeF1ly5crrhTXawfLJSwxgpYi27OElI7iSoc/list",
"stats":{"apple-mail":{"macos":{"12.2":"y"},"ios":{"10.3":"y","12.3.1":"y"}},"gmail":{"desktop-webmail":{"2019-07":"n #6"},"ios":{"2019-07":"n"},"android":{"2019-07":"n"},"mobile-webmail":{"2020-02":"n"}},"orange":{"desktop-webmail":{"2019-05":"a #2","2021-03":"n #7","2024-03":"n"},"ios":{"2019-07":"y","2024-03":"n"},"android":{"2019-07":"a #1","2024-04":"n"}},"outlook":{"windows":{"2003":"a #3","2007":"a #4 #5","2010":"a #4 #5","2013":"a #4 #5","2016":"a #4 #5","2019":"a #4"},"windows-mail":{"2020-01":"n"},"macos":{"2011":"y","2016":"y","16.80":"n"},"outlook-com":{"2019-07":"n","2023-12":"n"},"ios":{"2.51.1":"y","3.29.0":"n"},"android":{"2019-07":"n"}},"samsung-email":{"android":{"6.0":"y #8","2021-11":"y #8"}},"sfr":{"desktop-webmail":{"2019-07":"a #2"},"ios":{"2019-07":"n"},"android":{"2019-07":"n"}},"thunderbird":{"macos":{"60.7":"y","78.5":"y"}},"aol":{"desktop-webmail":{"2020-01":"n"},"ios":{"2020-01":"n"},"android":{"2020-01":"n"}},"yahoo":{"desktop-webmail":{"2019-07":"n"},"ios":{"2019-07":"n"},"android":{"2019-07":"n"}},"protonmail":{"desktop-webmail":{"2020-03":"n"},"ios":{"2020-03":"n"},"android":{"2020-03":"y"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"n"}},"fastmail":{"desktop-webmail":{"2021-07":"n"}},"laposte":{"desktop-webmail":{"2021-08":"a #2"}},"gmx":{"desktop-webmail":{"2022-06":"n"},"ios":{"2022-06":"y"},"android":{"2022-06":"n"}},"web-de":{"desktop-webmail":{"2022-06":"n"},"ios":{"2022-06":"y"},"android":{"2022-06":"n"}},"ionos-1and1":{"desktop-webmail":{"2022-06":"y"},"android":{"2022-06":"n"}}},
"stats":{"apple-mail":{"macos":{"12.2":"y"},"ios":{"10.3":"y","12.3.1":"y"}},"gmail":{"desktop-webmail":{"2019-07":"n #6"},"ios":{"2019-07":"n"},"android":{"2019-07":"n"},"mobile-webmail":{"2020-02":"n"}},"orange":{"desktop-webmail":{"2019-05":"a #2","2021-03":"n #7","2024-03":"n"},"ios":{"2019-07":"y","2024-03":"n"},"android":{"2019-07":"a #1","2024-04":"n"}},"outlook":{"windows":{"2003":"a #3","2007":"a #4 #5","2010":"a #4 #5","2013":"a #4 #5","2016":"a #4 #5","2019":"a #4"},"windows-mail":{"2020-01":"n"},"macos":{"2011":"y","2016":"y","16.80":"n"},"outlook-com":{"2019-07":"n","2023-12":"n"},"ios":{"2.51.1":"y","3.29.0":"n"},"android":{"2019-07":"n"}},"samsung-email":{"android":{"6.0":"y #8","2021-11":"y #8"}},"sfr":{"desktop-webmail":{"2019-07":"a #2","2025-07":"n"},"ios":{"2019-07":"n"},"android":{"2019-07":"n"}},"thunderbird":{"macos":{"60.7":"y","78.5":"y"}},"aol":{"desktop-webmail":{"2020-01":"n"},"ios":{"2020-01":"n"},"android":{"2020-01":"n"}},"yahoo":{"desktop-webmail":{"2019-07":"n"},"ios":{"2019-07":"n"},"android":{"2019-07":"n"}},"protonmail":{"desktop-webmail":{"2020-03":"n"},"ios":{"2020-03":"n"},"android":{"2020-03":"y"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"n"}},"fastmail":{"desktop-webmail":{"2021-07":"n"}},"laposte":{"desktop-webmail":{"2021-08":"a #2","2025-07":"n"}},"gmx":{"desktop-webmail":{"2022-06":"n"},"ios":{"2022-06":"y"},"android":{"2022-06":"n"}},"web-de":{"desktop-webmail":{"2022-06":"n"},"ios":{"2022-06":"y"},"android":{"2022-06":"n"}},"ionos-1and1":{"desktop-webmail":{"2022-06":"y"},"android":{"2022-06":"n"}}},
"notes":null,
"notes_by_num":{"1":"Partial. Only supported through a `<link>` tag.","2":"Partial. Only supported directly through a `<style>` tag.","3":"Buggy. Support depends on the version of IE installed.","4":"Partial. The declaration is supported but distant fonts are ignored.","5":"Buggy. Elements using a font declared with `@font-face` ignore the font stack and fall back to Times New Roman. Use `mso-generic-font-family` and `mso-font-alt` to control the fallback.","6":"Not supported. Roboto and Google Sans can be used, but only because they're embedded with the webmail's own styles.","7":"Not supported. The `@font-face` declaration is kept but the `src` property is removed.","8":"Not supported when using a Microsoft email address; outlook, live, hotmail, etc."}
},
@@ -126,7 +126,7 @@
"last_test_date":"2019-02-28",
"test_url":"https://www.caniemail.com/tests/css-placement.html",
"test_results_url":"https://app.emailonacid.com/app/acidtest/6vV9sx4RoRsdnkZBDjLWwSC18VcUQzJY00tlj2NVSxKKv/list",
"stats":{"apple-mail":{"macos":{"12.4":"y"},"ios":{"12.1":"y"}},"gmail":{"desktop-webmail":{"2019-02":"n"},"ios":{"2019-02":"n"},"android":{"2019-02":"n"},"mobile-webmail":{"2020-02":"n"}},"orange":{"desktop-webmail":{"2019-08":"n","2021-03":"n"},"ios":{"2019-08":"y","2023-12":"n"},"android":{"2019-08":"y","2023-12":"n"}},"outlook":{"windows":{"2007":"y","2010":"y","2013":"y","2016":"y","2019":"y"},"windows-mail":{"2019-02":"y"},"macos":{"2019-02":"y","16.80":"n"},"outlook-com":{"2019-02":"n","2023-12":"n"},"ios":{"2019-02":"n"},"android":{"2019-02":"n"}},"thunderbird":{"macos":{"60.8":"y","78.5":"n"}},"yahoo":{"desktop-webmail":{"2019-02":"n"},"ios":{"2019-02":"n"},"android":{"2019-02":"n"}},"aol":{"desktop-webmail":{"2019-02":"n"},"ios":{"2019-02":"n"},"android":{"2020-01":"n"}},"samsung-email":{"android":{"5.0.10.2":"n"}},"sfr":{"desktop-webmail":{"2019-08":"n"},"ios":{"2019-08":"n"},"android":{"2019-08":"n"}},"protonmail":{"desktop-webmail":{"2020-03":"n"},"ios":{"2020-03":"n"},"android":{"2020-03":"y"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"n"}},"fastmail":{"desktop-webmail":{"2021-07":"n"}},"laposte":{"desktop-webmail":{"2021-08":"n"}},"gmx":{"desktop-webmail":{"2022-06":"n"},"ios":{"2022-06":"y"},"android":{"2022-06":"n"}},"web-de":{"desktop-webmail":{"2022-06":"n"},"ios":{"2022-06":"y"},"android":{"2022-06":"n"}},"ionos-1and1":{"desktop-webmail":{"2022-06":"y"},"android":{"2022-06":"n"}},"wp-pl":{"desktop-webmail":{"2023-12":"n"}}},
"stats":{"apple-mail":{"macos":{"12.4":"y"},"ios":{"12.1":"y"}},"gmail":{"desktop-webmail":{"2019-02":"n"},"ios":{"2019-02":"n"},"android":{"2019-02":"n"},"mobile-webmail":{"2020-02":"n"}},"orange":{"desktop-webmail":{"2019-08":"n","2021-03":"n"},"ios":{"2019-08":"y","2023-12":"n"},"android":{"2019-08":"y","2023-12":"n"}},"outlook":{"windows":{"2007":"y","2010":"y","2013":"y","2016":"y","2019":"y"},"windows-mail":{"2019-02":"y"},"macos":{"2019-02":"y","16.80":"n"},"outlook-com":{"2019-02":"n","2023-12":"n"},"ios":{"2019-02":"n"},"android":{"2019-02":"n"}},"thunderbird":{"macos":{"60.8":"y","78.5":"n"}},"yahoo":{"desktop-webmail":{"2019-02":"n"},"ios":{"2019-02":"n"},"android":{"2019-02":"n"}},"aol":{"desktop-webmail":{"2019-02":"n"},"ios":{"2019-02":"n"},"android":{"2020-01":"n"}},"samsung-email":{"android":{"5.0.10.2":"n"}},"sfr":{"desktop-webmail":{"2019-08":"n","2025-07":"n"},"ios":{"2019-08":"n"},"android":{"2019-08":"n"}},"protonmail":{"desktop-webmail":{"2020-03":"n"},"ios":{"2020-03":"n"},"android":{"2020-03":"y"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"n"}},"fastmail":{"desktop-webmail":{"2021-07":"n"}},"laposte":{"desktop-webmail":{"2021-08":"n","2025-07":"n"}},"gmx":{"desktop-webmail":{"2022-06":"n"},"ios":{"2022-06":"y"},"android":{"2022-06":"n"}},"web-de":{"desktop-webmail":{"2022-06":"n"},"ios":{"2022-06":"y"},"android":{"2022-06":"n"}},"ionos-1and1":{"desktop-webmail":{"2022-06":"y"},"android":{"2022-06":"n"}},"wp-pl":{"desktop-webmail":{"2023-12":"n"}}},
"notes":null,
"notes_by_num":null
},
@@ -142,7 +142,7 @@
"last_test_date":"2021-05-25",
"test_url":"https://www.caniemail.com/tests/css-animation.html",
"test_results_url":"https://app.emailonacid.com/app/acidtest/u4oWccYOFNNyTagHs2NSUZqJYQ3MssrqDMocBnRa35hf7/list",
"stats":{"apple-mail":{"macos":{"13":"y"},"ios":{"13":"y"}},"gmail":{"desktop-webmail":{"2021-05":"n"},"ios":{"2021-05":"n"},"android":{"2021-05":"n"},"mobile-webmail":{"2021-05":"n"}},"orange":{"desktop-webmail":{"2021-05":"n #1"},"ios":{"2021-05":"n"},"android":{"2021-05":"n"}},"outlook":{"windows":{"2003":"n","2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"windows-mail":{"2021-05":"n"},"macos":{"2011":"y","2016":"y","16.80":"n"},"outlook-com":{"2021-05":"n"},"ios":{"2021-05":"n"},"android":{"2021-05":"n"}},"samsung-email":{"android":{"6.1":"y"}},"sfr":{"desktop-webmail":{"2021-05":"a #1"},"ios":{"2021-05":"n"},"android":{"2021-05":"n"}},"thunderbird":{"macos":{"78.10":"y"}},"aol":{"desktop-webmail":{"2021-05":"y"},"ios":{"2021-05":"n"},"android":{"2021-05":"n"}},"yahoo":{"desktop-webmail":{"2021-05":"y"},"ios":{"2021-05":"n"},"android":{"2021-05":"n"}},"protonmail":{"desktop-webmail":{"2021-05":"n"},"ios":{"2021-05":"n"},"android":{"2021-05":"n"}},"hey":{"desktop-webmail":{"2021-05":"y"}},"mail-ru":{"desktop-webmail":{"2021-05":"n"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"a #1"}},"gmx":{"desktop-webmail":{"2022-06":"n"},"ios":{"2022-06":"y"},"android":{"2022-06":"y"}},"web-de":{"desktop-webmail":{"2022-06":"n"},"ios":{"2022-06":"y"},"android":{"2022-06":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-06":"a #2"},"android":{"2022-06":"y"}}},
"stats":{"apple-mail":{"macos":{"13":"y"},"ios":{"13":"y"}},"gmail":{"desktop-webmail":{"2021-05":"n"},"ios":{"2021-05":"n"},"android":{"2021-05":"n"},"mobile-webmail":{"2021-05":"n"}},"orange":{"desktop-webmail":{"2021-05":"n #1"},"ios":{"2021-05":"n"},"android":{"2021-05":"n"}},"outlook":{"windows":{"2003":"n","2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"windows-mail":{"2021-05":"n"},"macos":{"2011":"y","2016":"y","16.80":"n"},"outlook-com":{"2021-05":"n"},"ios":{"2021-05":"n"},"android":{"2021-05":"n"}},"samsung-email":{"android":{"6.1":"y"}},"sfr":{"desktop-webmail":{"2021-05":"a #1","2025-07":"n"},"ios":{"2021-05":"n"},"android":{"2021-05":"n"}},"thunderbird":{"macos":{"78.10":"y"}},"aol":{"desktop-webmail":{"2021-05":"y"},"ios":{"2021-05":"n"},"android":{"2021-05":"n"}},"yahoo":{"desktop-webmail":{"2021-05":"y"},"ios":{"2021-05":"n"},"android":{"2021-05":"n"}},"protonmail":{"desktop-webmail":{"2021-05":"n"},"ios":{"2021-05":"n"},"android":{"2021-05":"n"}},"hey":{"desktop-webmail":{"2021-05":"y"}},"mail-ru":{"desktop-webmail":{"2021-05":"n"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"a #1","2025-07":"n"}},"gmx":{"desktop-webmail":{"2022-06":"n"},"ios":{"2022-06":"y"},"android":{"2022-06":"y"}},"web-de":{"desktop-webmail":{"2022-06":"n"},"ios":{"2022-06":"y"},"android":{"2022-06":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-06":"a #2"},"android":{"2022-06":"y"}}},
"notes":null,
"notes_by_num":{"1":"Not supported. The `@keyframes` declaration is kept but values are incorrectly prefixed.","2":"Partial. Only supports from and to keyframes. Does not support % keyframes"}
},
@@ -158,7 +158,7 @@
"last_test_date":"2019-08-20",
"test_url":"https://www.caniemail.com/tests/css-media.html",
"test_results_url":"https://app.emailonacid.com/app/acidtest/hMLCNCSKZYHkLgLOpIWltlnYjtagbNsrwzMxalc2VbghN/list",
"stats":{"apple-mail":{"macos":{"10.3":"y"},"ios":{"10.3":"y","12.2":"y"}},"gmail":{"desktop-webmail":{"2019-08":"n"},"ios":{"2019-08":"n"},"android":{"2019-08":"n"},"mobile-webmail":{"2020-02":"n"}},"orange":{"desktop-webmail":{"2019-08":"y #1","2021-03":"y"},"ios":{"2019-08":"y"},"android":{"2019-08":"y"}},"outlook":{"windows":{"2003":"n","2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"windows-mail":{"2020-01":"n"},"macos":{"2011":"y","2016":"y","16.80":"y"},"outlook-com":{"2019-08":"y"},"ios":{"2019-08":"y"},"android":{"2019-08":"y"}},"samsung-email":{"android":{"5.0.10.2":"y","6.0":"y"}},"sfr":{"desktop-webmail":{"2019-08":"y"},"ios":{"2019-08":"n"},"android":{"2019-08":"n"}},"thunderbird":{"macos":{"60.3":"n","78.5":"n"}},"yahoo":{"desktop-webmail":{"2019-08":"n"},"ios":{"2019-08":"n"},"android":{"2019-08":"n"}},"aol":{"desktop-webmail":{"2019-02":"n"},"ios":{"2019-02":"n"},"android":{"2019-02":"n"}},"protonmail":{"desktop-webmail":{"2020-03":"n"},"ios":{"2020-03":"n"},"android":{"2020-03":"y"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"n"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"y"}},"gmx":{"desktop-webmail":{"2022-06":"n"},"ios":{"2022-06":"y"},"android":{"2022-06":"y"}},"web-de":{"desktop-webmail":{"2022-06":"n"},"ios":{"2022-06":"y"},"android":{"2022-06":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-06":"y"},"android":{"2022-06":"y"}}},
"stats":{"apple-mail":{"macos":{"10.3":"y"},"ios":{"10.3":"y","12.2":"y"}},"gmail":{"desktop-webmail":{"2019-08":"n"},"ios":{"2019-08":"n"},"android":{"2019-08":"n"},"mobile-webmail":{"2020-02":"n"}},"orange":{"desktop-webmail":{"2019-08":"y #1","2021-03":"y"},"ios":{"2019-08":"y"},"android":{"2019-08":"y"}},"outlook":{"windows":{"2003":"n","2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"windows-mail":{"2020-01":"n"},"macos":{"2011":"y","2016":"y","16.80":"y"},"outlook-com":{"2019-08":"y"},"ios":{"2019-08":"y"},"android":{"2019-08":"y"}},"samsung-email":{"android":{"5.0.10.2":"y","6.0":"y"}},"sfr":{"desktop-webmail":{"2019-08":"y","2025-07":"n"},"ios":{"2019-08":"n"},"android":{"2019-08":"n"}},"thunderbird":{"macos":{"60.3":"n","78.5":"n"}},"yahoo":{"desktop-webmail":{"2019-08":"n"},"ios":{"2019-08":"n"},"android":{"2019-08":"n"}},"aol":{"desktop-webmail":{"2019-02":"n"},"ios":{"2019-02":"n"},"android":{"2019-02":"n"}},"protonmail":{"desktop-webmail":{"2020-03":"n"},"ios":{"2020-03":"n"},"android":{"2020-03":"y"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"n"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"y","2025-07":"n"}},"gmx":{"desktop-webmail":{"2022-06":"n"},"ios":{"2022-06":"y"},"android":{"2022-06":"y"}},"web-de":{"desktop-webmail":{"2022-06":"n"},"ios":{"2022-06":"y"},"android":{"2022-06":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-06":"y"},"android":{"2022-06":"y"}}},
"notes":null,
"notes_by_num":{"1":"Buggy. The first rule inside a media query is not prefixed."}
},
@@ -174,7 +174,7 @@
"last_test_date":"2022-08-29",
"test_url":"https://www.caniemail.com/tests/css-media-hover.html",
"test_results_url":"https://testi.at/proj/onECpNVH8Dhv7BSLPXUbQ4s0O",
"stats":{"apple-mail":{"macos":{"2022-08":"y"},"ios":{"2022-08":"y"}},"gmail":{"desktop-webmail":{"2022-08":"n"},"ios":{"2022-08":"n"},"android":{"2022-08":"n"},"mobile-webmail":{"2022-08":"n"}},"orange":{"desktop-webmail":{"2022-08":"u"},"ios":{"2022-08":"u"},"android":{"2022-08":"u"}},"outlook":{"windows":{"2022-08":"n"},"windows-mail":{"2022-08":"n"},"macos":{"2011":"y","2016":"y","16.80":"y"},"outlook-com":{"2022-08":"y"},"ios":{"2022-08":"y"},"android":{"2022-08":"y"}},"samsung-email":{"android":{"10":"y","11":"y"}},"sfr":{"desktop-webmail":{"2024-03":"y"},"ios":{"2024-03":"n"},"android":{"2024-03":"n"}},"thunderbird":{"macos":{"2022-08":"u"}},"aol":{"desktop-webmail":{"2022-08":"n"},"ios":{"2022-08":"n"},"android":{"2022-08":"n"}},"yahoo":{"desktop-webmail":{"2022-08":"n"},"ios":{"2022-08":"n"},"android":{"2022-08":"n"}},"protonmail":{"desktop-webmail":{"2022-08":"u"},"ios":{"2022-08":"u"},"android":{"2022-08":"u"}},"hey":{"desktop-webmail":{"2022-08":"u"}},"mail-ru":{"desktop-webmail":{"2022-08":"n"}},"fastmail":{"desktop-webmail":{"2022-08":"u"}},"laposte":{"desktop-webmail":{"2022-08":"u"}}},
"stats":{"apple-mail":{"macos":{"2022-08":"y"},"ios":{"2022-08":"y"}},"gmail":{"desktop-webmail":{"2022-08":"n"},"ios":{"2022-08":"n"},"android":{"2022-08":"n"},"mobile-webmail":{"2022-08":"n"}},"orange":{"desktop-webmail":{"2022-08":"u"},"ios":{"2022-08":"u"},"android":{"2022-08":"u"}},"outlook":{"windows":{"2022-08":"n"},"windows-mail":{"2022-08":"n"},"macos":{"2011":"y","2016":"y","16.80":"y"},"outlook-com":{"2022-08":"y"},"ios":{"2022-08":"y"},"android":{"2022-08":"y"}},"samsung-email":{"android":{"10":"y","11":"y"}},"sfr":{"desktop-webmail":{"2024-03":"y","2025-07":"n"},"ios":{"2024-03":"n"},"android":{"2024-03":"n"}},"thunderbird":{"macos":{"2022-08":"u"}},"aol":{"desktop-webmail":{"2022-08":"n"},"ios":{"2022-08":"n"},"android":{"2022-08":"n"}},"yahoo":{"desktop-webmail":{"2022-08":"n"},"ios":{"2022-08":"n"},"android":{"2022-08":"n"}},"protonmail":{"desktop-webmail":{"2022-08":"y"},"ios":{"2022-08":"y"},"android":{"2022-08":"y"}},"hey":{"desktop-webmail":{"2022-08":"u"}},"mail-ru":{"desktop-webmail":{"2022-08":"n"}},"fastmail":{"desktop-webmail":{"2022-08":"u"}},"laposte":{"desktop-webmail":{"2022-08":"u","2025-07":"n"}}},
"notes":null,
"notes_by_num":null
},
@@ -190,7 +190,7 @@
"last_test_date":"2019-08-20",
"test_url":"https://www.caniemail.com/tests/css-media.html",
"test_results_url":"https://app.emailonacid.com/app/acidtest/hMLCNCSKZYHkLgLOpIWltlnYjtagbNsrwzMxalc2VbghN/list",
"stats":{"apple-mail":{"macos":{"10.3":"y"},"ios":{"10.3":"n","12":"y","13":"y","15":"y","18.3.2":"a #2"}},"gmail":{"desktop-webmail":{"2019-08":"y"},"ios":{"2019-08":"y","2025-04":"n"},"android":{"2019-08":"y"},"mobile-webmail":{"2020-02":"n"}},"orange":{"desktop-webmail":{"2019-08":"y #1","2021-03":"y","2024-04":"y"},"ios":{"2019-08":"n","2024-04":"y"},"android":{"2019-08":"y","2024-04":"y"}},"outlook":{"windows":{"2003":"n","2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"windows-mail":{"2020-01":"n"},"macos":{"2011":"y","2016":"y","16.80":"y"},"outlook-com":{"2019-08":"y"},"ios":{"2019-08":"y"},"android":{"2019-08":"y"}},"samsung-email":{"android":{"5.0.10.2":"n","6.0":"y"}},"sfr":{"desktop-webmail":{"2019-08":"y"},"ios":{"2019-08":"n"},"android":{"2019-08":"n"}},"thunderbird":{"macos":{"60.3":"y","78.5":"n"}},"yahoo":{"desktop-webmail":{"2019-08":"n"},"ios":{"2019-08":"n"},"android":{"2019-08":"n"}},"aol":{"desktop-webmail":{"2019-02":"n"},"ios":{"2019-02":"n"},"android":{"2019-02":"n"}},"protonmail":{"desktop-webmail":{"2020-03":"n"},"ios":{"2020-03":"n"},"android":{"2020-03":"n"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"y"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"y"}},"gmx":{"desktop-webmail":{"2022-06":"y"},"ios":{"2022-06":"y"},"android":{"2022-06":"y"}},"web-de":{"desktop-webmail":{"2022-06":"y"},"ios":{"2022-06":"y"},"android":{"2022-06":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-06":"y"},"android":{"2022-06":"y"}}},
"stats":{"apple-mail":{"macos":{"10.3":"y"},"ios":{"10.3":"n","12":"y","13":"y","15":"y","18.3.2":"a #2"}},"gmail":{"desktop-webmail":{"2019-08":"y"},"ios":{"2019-08":"y","2025-04":"n"},"android":{"2019-08":"y"},"mobile-webmail":{"2020-02":"n"}},"orange":{"desktop-webmail":{"2019-08":"y #1","2021-03":"y","2024-04":"y"},"ios":{"2019-08":"n","2024-04":"y"},"android":{"2019-08":"y","2024-04":"y"}},"outlook":{"windows":{"2003":"n","2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"windows-mail":{"2020-01":"n"},"macos":{"2011":"y","2016":"y","16.80":"y"},"outlook-com":{"2019-08":"y"},"ios":{"2019-08":"y"},"android":{"2019-08":"y"}},"samsung-email":{"android":{"5.0.10.2":"n","6.0":"y"}},"sfr":{"desktop-webmail":{"2019-08":"y","2025-07":"n"},"ios":{"2019-08":"n"},"android":{"2019-08":"n"}},"thunderbird":{"macos":{"60.3":"y","78.5":"n"}},"yahoo":{"desktop-webmail":{"2019-08":"n"},"ios":{"2019-08":"n"},"android":{"2019-08":"n"}},"aol":{"desktop-webmail":{"2019-02":"n"},"ios":{"2019-02":"n"},"android":{"2019-02":"n"}},"protonmail":{"desktop-webmail":{"2020-03":"n"},"ios":{"2020-03":"n"},"android":{"2020-03":"n"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"y"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"y","2025-07":"n"}},"gmx":{"desktop-webmail":{"2022-06":"y"},"ios":{"2022-06":"y"},"android":{"2022-06":"y"}},"web-de":{"desktop-webmail":{"2022-06":"y"},"ios":{"2022-06":"y"},"android":{"2022-06":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-06":"y"},"android":{"2022-06":"y"}}},
"notes":null,
"notes_by_num":{"1":"Buggy. The first rule inside a media query is not prefixed.","2":"Partial. `orientation:portrait` is not supported."}
},
@@ -206,7 +206,7 @@
"last_test_date":"2023-03-08",
"test_url":"https://www.caniemail.com/tests/css-media-prefers-color-scheme.html",
"test_results_url":"https://app.emailonacid.com/app/acidtest/CBhafIa5yXDRKQKbV442rVFISXim84wMgXaoCqVFD8VTe/list",
"stats":{"apple-mail":{"macos":{"10.3":"n","12.4":"y","16.0":"y"},"ios":{"12.2":"n","13.0":"y","16.1":"y"}},"gmail":{"desktop-webmail":{"2020-01":"n","2022-12":"n"},"ios":{"2020-01":"n","2022-12":"n"},"android":{"2020-01":"n","2022-12":"n"},"mobile-webmail":{"2020-02":"n","2022-12":"n"}},"orange":{"desktop-webmail":{"2019-08":"y","2021-03":"y","2022-12":"y","2024-04":"y"},"ios":{"2020-01":"n","2022-12":"y","2024-04":"y"},"android":{"2020-01":"n","2022-12":"n","2024-04":"y"}},"outlook":{"windows":{"2003":"n","2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"windows-mail":{"2020-01":"n"},"macos":{"2019":"y","16.70":"y #3","16.80":"y #3"},"outlook-com":{"2019-07":"y","2022-12":"y #3"},"ios":{"2020-01":"y","2022-12":"y #3"},"android":{"2020-01":"n","2022-12":"n #3","2023-03":"y #3"}},"samsung-email":{"android":{"6.0":"n","6.1":"y"}},"sfr":{"desktop-webmail":{"2019-08":"y","2022-12":"y"},"ios":{"2019-08":"n","2022-12":"n"},"android":{"2019-08":"n","2022-12":"n"}},"thunderbird":{"macos":{"60.8":"n","68.4":"y","78.5":"n","91.13":"n"}},"aol":{"desktop-webmail":{"2020-01":"n #1"},"ios":{"2020-01":"n #1"},"android":{"2020-01":"n #1"}},"yahoo":{"desktop-webmail":{"2020-01":"n #1","2022-12":"n #6"},"ios":{"2020-01":"n #1","2022-12":"n"},"android":{"2020-01":"n #1","2022-12":"n"}},"protonmail":{"desktop-webmail":{"2020-03":"n","2022-12":"n"},"ios":{"2020-03":"n"},"android":{"2020-03":"n"}},"hey":{"desktop-webmail":{"2020-06":"y","2022-12":"n #5"}},"mail-ru":{"desktop-webmail":{"2020-10":"n","2022-12":"n"}},"fastmail":{"desktop-webmail":{"2021-07":"n #2","2022-12":"y #4"}},"laposte":{"desktop-webmail":{"2021-08":"y","2022-12":"y"}},"free-fr":{"desktop-webmail":{"2022-12":"y"}},"t-online-de":{"desktop-webmail":{"2022-12":"n"}},"gmx":{"desktop-webmail":{"2022-06":"n"},"ios":{"2022-06":"y"},"android":{"2022-06":"y"}},"web-de":{"desktop-webmail":{"2022-06":"n"},"ios":{"2022-06":"y"},"android":{"2022-06":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-06":"y"},"android":{"2022-06":"y"}}},
"stats":{"apple-mail":{"macos":{"10.3":"n","12.4":"y","16.0":"y"},"ios":{"12.2":"n","13.0":"y","16.1":"y"}},"gmail":{"desktop-webmail":{"2020-01":"n","2022-12":"n"},"ios":{"2020-01":"n","2022-12":"n"},"android":{"2020-01":"n","2022-12":"n"},"mobile-webmail":{"2020-02":"n","2022-12":"n"}},"orange":{"desktop-webmail":{"2019-08":"y","2021-03":"y","2022-12":"y","2024-04":"y"},"ios":{"2020-01":"n","2022-12":"y","2024-04":"y"},"android":{"2020-01":"n","2022-12":"n","2024-04":"y"}},"outlook":{"windows":{"2003":"n","2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"windows-mail":{"2020-01":"n"},"macos":{"2019":"y","16.70":"y #3","16.80":"y #3"},"outlook-com":{"2019-07":"y","2022-12":"y #3"},"ios":{"2020-01":"y","2022-12":"y #3"},"android":{"2020-01":"n","2022-12":"n #3","2023-03":"y #3"}},"samsung-email":{"android":{"6.0":"n","6.1":"y"}},"sfr":{"desktop-webmail":{"2019-08":"y","2022-12":"y","2025-07":"n"},"ios":{"2019-08":"n","2022-12":"n"},"android":{"2019-08":"n","2022-12":"n"}},"thunderbird":{"macos":{"60.8":"n","68.4":"y","78.5":"n","91.13":"n"}},"aol":{"desktop-webmail":{"2020-01":"n #1"},"ios":{"2020-01":"n #1"},"android":{"2020-01":"n #1"}},"yahoo":{"desktop-webmail":{"2020-01":"n #1","2022-12":"n #6"},"ios":{"2020-01":"n #1","2022-12":"n"},"android":{"2020-01":"n #1","2022-12":"n"}},"protonmail":{"desktop-webmail":{"2020-03":"n","2022-12":"n"},"ios":{"2020-03":"n"},"android":{"2020-03":"n"}},"hey":{"desktop-webmail":{"2020-06":"y","2022-12":"n #5"}},"mail-ru":{"desktop-webmail":{"2020-10":"n","2022-12":"n"}},"fastmail":{"desktop-webmail":{"2021-07":"n #2","2022-12":"y #4"}},"laposte":{"desktop-webmail":{"2021-08":"y","2022-12":"y","2025-07":"n"}},"free-fr":{"desktop-webmail":{"2022-12":"y"}},"t-online-de":{"desktop-webmail":{"2022-12":"n"}},"gmx":{"desktop-webmail":{"2022-06":"n"},"ios":{"2022-06":"y"},"android":{"2022-06":"y"}},"web-de":{"desktop-webmail":{"2022-06":"n"},"ios":{"2022-06":"y"},"android":{"2022-06":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-06":"y"},"android":{"2022-06":"y"}}},
"notes":null,
"notes_by_num":{"1":"Not supported. `@media (prefers-color-scheme)` is transformed into `@media ( _filtered_a )`.","2":"Not supported. `@media (prefers-color-scheme:dark)` is transformed into `@media none`.","3":"Additional custom `data` attributes (`data-ogsc`, `data-ogac`, `data-ogsb`, `data-ogab`) are added when viewing an email in dark mode. See [this article](https://www.hteumeuleu.com/2021/emails-react-outlook-com-dark-mode/) for examples.","4":"`@media (prefers-color-scheme:dark)` is transformed into `@media all` at run time if it applies.","5":"Not supported. `@media (prefers-color-scheme:dark)` is transformed into `@media (false)`","6":"Not supported. `@media (prefers-color-scheme:dark)` is transformed into `@media ()`"}
},
@@ -222,9 +222,9 @@
"last_test_date":"2021-02-20",
"test_url":"https://www.caniemail.com/tests/css-media-prefers-reduced-motion.html",
"test_results_url":"https://testi.at/proj/e3GT3l1CxqBUoE3u9keC4WLf5",
"stats":{"apple-mail":{"macos":{"11":"y","12":"y","13":"y"},"ios":{"11":"y","12":"y","13":"y","14":"y"}},"gmail":{"desktop-webmail":{"2020-12":"n"},"ios":{"2020-12":"n"},"android":{"2020-12":"n"},"mobile-webmail":{"2020-12":"n"}},"orange":{"desktop-webmail":{"2021-02":"y","2021-03":"y"},"ios":{"2021-02":"y"},"android":{"2021-02":"y"}},"outlook":{"windows":{"2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"windows-mail":{"16005.13426.20316.0":"n"},"macos":{"2020-12":"y","16.80":"y"},"outlook-com":{"2020-12":"y"},"ios":{"2020-12":"y"},"android":{"4.2048.4":"y"}},"yahoo":{"desktop-webmail":{"2020-12":"n"},"ios":{"2021-02":"n"},"android":{"6.16.2.1519779":"n"}},"aol":{"desktop-webmail":{"2020-12":"n"},"ios":{"2021-02":"n"},"android":{"2021-02":"n"}},"samsung-email":{"android":{"6.1.31.2":"y"}},"sfr":{"desktop-webmail":{"2021-02":"y"},"ios":{"2021-02":"n"},"android":{"2021-02":"n"}},"thunderbird":{"macos":{"78.7":"n"}},"protonmail":{"desktop-webmail":{"2021-02":"n"},"ios":{"2021-02":"n"},"android":{"2021-02":"n"}},"hey":{"desktop-webmail":{"2021-02":"y"}},"mail-ru":{"desktop-webmail":{"2021-02":"n"}},"fastmail":{"desktop-webmail":{"2021-07":"n #1"}},"laposte":{"desktop-webmail":{"2021-08":"y"}},"gmx":{"desktop-webmail":{"2022-06":"n"},"ios":{"2022-06":"y"},"android":{"2022-06":"y"}},"web-de":{"desktop-webmail":{"2022-06":"n"},"ios":{"2022-06":"y"},"android":{"2022-06":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-06":"y"},"android":{"2022-06":"y"}}},
"stats":{"apple-mail":{"macos":{"11":"y","12":"y","13":"y"},"ios":{"11":"y","12":"y","13":"y","14":"y"}},"gmail":{"desktop-webmail":{"2020-12":"n"},"ios":{"2020-12":"n"},"android":{"2020-12":"n"},"mobile-webmail":{"2020-12":"n"}},"orange":{"desktop-webmail":{"2021-02":"y","2021-03":"y"},"ios":{"2021-02":"y"},"android":{"2021-02":"y"}},"outlook":{"windows":{"2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"windows-mail":{"16005.13426.20316.0":"n"},"macos":{"2020-12":"y","16.80":"y"},"outlook-com":{"2020-12":"y"},"ios":{"2020-12":"y"},"android":{"4.2048.4":"y"}},"yahoo":{"desktop-webmail":{"2020-12":"n"},"ios":{"2021-02":"n"},"android":{"6.16.2.1519779":"n"}},"aol":{"desktop-webmail":{"2020-12":"n"},"ios":{"2021-02":"n"},"android":{"2021-02":"n"}},"samsung-email":{"android":{"6.1.31.2":"y"}},"sfr":{"desktop-webmail":{"2021-02":"y"},"ios":{"2021-02":"n"},"android":{"2021-02":"n"}},"thunderbird":{"macos":{"78.7":"n"}},"protonmail":{"desktop-webmail":{"2021-02":"a #2"},"ios":{"2021-02":"a #2"},"android":{"2021-02":"a #2"}},"hey":{"desktop-webmail":{"2021-02":"y"}},"mail-ru":{"desktop-webmail":{"2021-02":"n"}},"fastmail":{"desktop-webmail":{"2021-07":"n #1"}},"laposte":{"desktop-webmail":{"2021-08":"y","2025-07":"n"}},"gmx":{"desktop-webmail":{"2022-06":"n"},"ios":{"2022-06":"y"},"android":{"2022-06":"y"}},"web-de":{"desktop-webmail":{"2022-06":"n"},"ios":{"2022-06":"y"},"android":{"2022-06":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-06":"y"},"android":{"2022-06":"y"}}},
"notes":null,
"notes_by_num":{"1":"Not supported. `@media (prefers-reduced-motion:reduce)` is transformed into `@media none`."}
"notes_by_num":{"1":"Not supported. `@media (prefers-reduced-motion:reduce)` is transformed into `@media none`.","2":"Partially supported. Not supported on `picture`."}
},
{
@@ -238,7 +238,7 @@
"last_test_date":"2023-12-13",
"test_url":"https://www.caniemail.com/tests/css-media.html",
"test_results_url":"https://app.emailonacid.com/app/acidtest/hMLCNCSKZYHkLgLOpIWltlnYjtagbNsrwzMxalc2VbghN/list",
"stats":{"apple-mail":{"macos":{"10.3":"y"},"ios":{"10.3":"y","12.2":"y"}},"gmail":{"desktop-webmail":{"2019-08":"a #1 #7","2020-01":"a #7"},"ios":{"2019-08":"a #1 #6 #7","2020-01":"a #6 #7"},"android":{"2019-08":"a #1 #6 #7","2022-07":"a #6 #7"},"mobile-webmail":{"2020-02":"n"}},"orange":{"desktop-webmail":{"2019-08":"y #5","2021-03":"y"},"ios":{"2019-08":"y"},"android":{"2019-08":"y"}},"outlook":{"windows":{"2003":"a #1","2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"windows-mail":{"2020-01":"n"},"macos":{"2011":"y","2016":"y","16.80":"a #1 #10"},"outlook-com":{"2019-08":"a #1","2023-12":"a #1 #10"},"ios":{"2019-08":"a #1"},"android":{"2019-08":"a #1"}},"samsung-email":{"android":{"5.0.10.2":"y","6.0":"y","6.1.90.16":"a #9"}},"sfr":{"desktop-webmail":{"2019-08":"y"},"ios":{"2019-08":"n"},"android":{"2019-08":"n"}},"thunderbird":{"macos":{"60.3":"y","78.5":"n","102.11":"n"}},"yahoo":{"desktop-webmail":{"2019-08":"a #1 #2","2020-01":"a #2"},"ios":{"2019-08":"a #1 #2","2020-01":"a #2"},"android":{"2019-08":"a #1 #2 #3","2020-01":"a #2 #3"}},"aol":{"desktop-webmail":{"2019-02":"a #1 #2","2020-01":"a #2"},"ios":{"2019-02":"a #1 #2","2020-01":"a #2"},"android":{"2019-02":"a #1 #2","2020-01":"a #2"}},"protonmail":{"desktop-webmail":{"2020-03":"n","2023-05":"a #8"},"ios":{"2020-03":"n","2023-05":"a #8"},"android":{"2020-03":"y"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"a #1 #7"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"y"}},"gmx":{"desktop-webmail":{"2022-06":"y #1"},"ios":{"2022-06":"y"},"android":{"2022-06":"y"}},"web-de":{"desktop-webmail":{"2022-06":"y #1"},"ios":{"2022-06":"y"},"android":{"2022-06":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-06":"y"},"android":{"2022-06":"y"}}},
"stats":{"apple-mail":{"macos":{"10.3":"y"},"ios":{"10.3":"y","12.2":"y"}},"gmail":{"desktop-webmail":{"2019-08":"a #1 #7","2020-01":"a #7"},"ios":{"2019-08":"a #1 #6 #7","2020-01":"a #6 #7"},"android":{"2019-08":"a #1 #6 #7","2022-07":"a #6 #7"},"mobile-webmail":{"2020-02":"n"}},"orange":{"desktop-webmail":{"2019-08":"y #5","2021-03":"y"},"ios":{"2019-08":"y"},"android":{"2019-08":"y"}},"outlook":{"windows":{"2003":"a #1","2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"windows-mail":{"2020-01":"n"},"macos":{"2011":"y","2016":"y","16.80":"a #1 #10"},"outlook-com":{"2019-08":"a #1","2023-12":"a #1 #10"},"ios":{"2019-08":"a #1"},"android":{"2019-08":"a #1"}},"samsung-email":{"android":{"5.0.10.2":"y","6.0":"y","6.1.90.16":"a #9"}},"sfr":{"desktop-webmail":{"2019-08":"y","2025-07":"n"},"ios":{"2019-08":"n"},"android":{"2019-08":"n"}},"thunderbird":{"macos":{"60.3":"y","78.5":"n","102.11":"n"}},"yahoo":{"desktop-webmail":{"2019-08":"a #1 #2","2020-01":"a #2"},"ios":{"2019-08":"a #1 #2","2020-01":"a #2"},"android":{"2019-08":"a #1 #2 #3","2020-01":"a #2 #3","2025-06":"a #2"}},"aol":{"desktop-webmail":{"2019-02":"a #1 #2","2020-01":"a #2"},"ios":{"2019-02":"a #1 #2","2020-01":"a #2"},"android":{"2019-02":"a #1 #2","2020-01":"a #2"}},"protonmail":{"desktop-webmail":{"2020-03":"n","2023-05":"a #8"},"ios":{"2020-03":"n","2023-05":"a #8"},"android":{"2020-03":"y"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"a #1 #7"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"y","2025-07":"n"}},"gmx":{"desktop-webmail":{"2022-06":"y #1"},"ios":{"2022-06":"y"},"android":{"2022-06":"y"}},"web-de":{"desktop-webmail":{"2022-06":"y #1"},"ios":{"2022-06":"y"},"android":{"2022-06":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-06":"y"},"android":{"2022-06":"y"}}},
"notes":null,
"notes_by_num":{"1":"Partial. Does not support nested media queries.","2":"Partial. Only supports `screen`, `min-width`, `max-width`, `min-height` and `max-height` based media queries.","3":"Buggy. Requires a double `<head>` hack to work.","4":"Partial. Does not support simple `@media {}` declarations.","5":"Buggy. The first rule inside a media query is not prefixed.","6":"Partial. Not supported with non Google accounts.","7":"Partial. Does not support height based media queries.","8":"Partial. Does not support landscape media query.","9":"Partial. Not supported with Hotmail/Outlook accounts.","10":"Partial. Nested media queries are removed."}
},
@@ -254,7 +254,7 @@
"last_test_date":"2020-05-25",
"test_url":"https://www.caniemail.com/tests/css-at-supports.html",
"test_results_url":"https://app.emailonacid.com/app/acidtest/No78GouZXTsxEZCD6z4Hn2frAvg3tHBw1SRAP8SwPKsZ5/list",
"stats":{"apple-mail":{"macos":{"13":"y"},"ios":{"13":"y"}},"gmail":{"desktop-webmail":{"2020-05":"n"},"ios":{"2020-05":"n"},"android":{"2020-05":"n"},"mobile-webmail":{"2020-05":"n"}},"orange":{"desktop-webmail":{"2020-05":"y","2021-03":"y"},"ios":{"2020-05":"y"},"android":{"2020-05":"y"}},"outlook":{"windows":{"2003":"n","2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"windows-mail":{"2020-05":"n"},"macos":{"2011":"y","2016":"y","16.80":"n"},"outlook-com":{"2020-05":"n"},"ios":{"2020-05":"n"},"android":{"2020-05":"n"}},"samsung-email":{"android":{"6.0":"y"}},"sfr":{"desktop-webmail":{"2020-05":"y"},"ios":{"2020-05":"n"},"android":{"2020-05":"n"}},"thunderbird":{"macos":{"68.7":"y","78.5":"n"}},"aol":{"desktop-webmail":{"2020-05":"y #1"},"ios":{"2020-05":"y #1"},"android":{"2020-05":"y #1"}},"yahoo":{"desktop-webmail":{"2020-05":"y #1"},"ios":{"2020-05":"y #1"},"android":{"2020-05":"y #1"}},"protonmail":{"desktop-webmail":{"2020-05":"n"},"ios":{"2020-05":"n"},"android":{"2020-05":"y"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"n"}},"fastmail":{"desktop-webmail":{"2021-07":"n #2"}},"laposte":{"desktop-webmail":{"2021-08":"y"}},"gmx":{"desktop-webmail":{"2022-06":"n"},"ios":{"2022-06":"y"},"android":{"2022-06":"y"}},"web-de":{"desktop-webmail":{"2022-06":"n"},"ios":{"2022-06":"y"},"android":{"2022-06":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-06":"y"},"android":{"2022-06":"y"}}},
"stats":{"apple-mail":{"macos":{"13":"y"},"ios":{"13":"y"}},"gmail":{"desktop-webmail":{"2020-05":"n"},"ios":{"2020-05":"n"},"android":{"2020-05":"n"},"mobile-webmail":{"2020-05":"n"}},"orange":{"desktop-webmail":{"2020-05":"y","2021-03":"y"},"ios":{"2020-05":"y"},"android":{"2020-05":"y"}},"outlook":{"windows":{"2003":"n","2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"windows-mail":{"2020-05":"n"},"macos":{"2011":"y","2016":"y","16.80":"n"},"outlook-com":{"2020-05":"n"},"ios":{"2020-05":"n"},"android":{"2020-05":"n"}},"samsung-email":{"android":{"6.0":"y"}},"sfr":{"desktop-webmail":{"2020-05":"y","2025-07":"n"},"ios":{"2020-05":"n"},"android":{"2020-05":"n"}},"thunderbird":{"macos":{"68.7":"y","78.5":"n"}},"aol":{"desktop-webmail":{"2020-05":"y #1"},"ios":{"2020-05":"y #1"},"android":{"2020-05":"y #1"}},"yahoo":{"desktop-webmail":{"2020-05":"y #1"},"ios":{"2020-05":"y #1"},"android":{"2020-05":"y #1"}},"protonmail":{"desktop-webmail":{"2020-05":"n"},"ios":{"2020-05":"n"},"android":{"2020-05":"y"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"n"}},"fastmail":{"desktop-webmail":{"2021-07":"n #2"}},"laposte":{"desktop-webmail":{"2021-08":"y","2025-07":"n"}},"gmx":{"desktop-webmail":{"2022-06":"n"},"ios":{"2022-06":"y"},"android":{"2022-06":"y"}},"web-de":{"desktop-webmail":{"2022-06":"n"},"ios":{"2022-06":"y"},"android":{"2022-06":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-06":"y"},"android":{"2022-06":"y"}}},
"notes":null,
"notes_by_num":{"1":"Properties not supported by the client are replaced by `_filtered_a` inside the parenthesis.","2":"Not supported. `@supports` is transformed into `@media not all`."}
},
@@ -430,7 +430,7 @@
"last_test_date":"2022-07-14",
"test_url":"https://www.caniemail.com/tests/css-block-size.html",
"test_results_url":"https://testi.at/proj/0xeT11rcnx6IzN7f9NsVFlZ",
"stats":{"apple-mail":{"macos":{"10.13":"n","10.15":"y","11":"y","12":"y"},"ios":{"14":"y","15":"y"}},"gmail":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"},"mobile-webmail":{"2022-07":"n"}},"orange":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"u"}},"outlook":{"windows":{"2013":"n","2016":"n","2019":"n","2022":"n"},"windows-mail":{"2022-07":"n"},"macos":{"16.56":"y","16.80":"n"},"outlook-com":{"2022-07":"n","2024-01":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"}},"samsung-email":{"android":{"10":"y","11":"y"}},"sfr":{"desktop-webmail":{"2022-07":"y"},"ios":{"2022-07":"y"},"android":{"2022-07":"u"}},"thunderbird":{"macos":{"91.11.0":"y"}},"aol":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"}},"yahoo":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"}},"protonmail":{"desktop-webmail":{"2022-07":"y"},"ios":{"2022-07":"y"},"android":{"2022-07":"u"}},"hey":{"desktop-webmail":{"2022-07":"y"}},"mail-ru":{"desktop-webmail":{"2022-07":"y"}},"fastmail":{"desktop-webmail":{"2022-07":"y"}},"laposte":{"desktop-webmail":{"2022-07":"y"}},"gmx":{"desktop-webmail":{"2022-09":"n"},"ios":{"2022-09":"y"},"android":{"2022-09":"y"}},"web-de":{"desktop-webmail":{"2022-09":"n"},"ios":{"2022-09":"y"},"android":{"2022-09":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-09":"y"},"android":{"2022-09":"y"}}},
"stats":{"apple-mail":{"macos":{"10.13":"n","10.15":"y","11":"y","12":"y"},"ios":{"14":"y","15":"y"}},"gmail":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"},"mobile-webmail":{"2022-07":"n"}},"orange":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"u"}},"outlook":{"windows":{"2013":"n","2016":"n","2019":"n","2022":"n"},"windows-mail":{"2022-07":"n"},"macos":{"16.56":"y","16.80":"n"},"outlook-com":{"2022-07":"n","2024-01":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"}},"samsung-email":{"android":{"10":"y","11":"y"}},"sfr":{"desktop-webmail":{"2022-07":"y"},"ios":{"2022-07":"y"},"android":{"2022-07":"u"}},"thunderbird":{"macos":{"91.11.0":"y"}},"aol":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"}},"yahoo":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"}},"protonmail":{"desktop-webmail":{"2022-07":"y"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"hey":{"desktop-webmail":{"2022-07":"y"}},"mail-ru":{"desktop-webmail":{"2022-07":"y"}},"fastmail":{"desktop-webmail":{"2022-07":"y"}},"laposte":{"desktop-webmail":{"2022-07":"y"}},"gmx":{"desktop-webmail":{"2022-09":"n"},"ios":{"2022-09":"y"},"android":{"2022-09":"y"}},"web-de":{"desktop-webmail":{"2022-09":"n"},"ios":{"2022-09":"y"},"android":{"2022-09":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-09":"y"},"android":{"2022-09":"y"}}},
"notes":null,
"notes_by_num":null
},
@@ -446,7 +446,7 @@
"last_test_date":"2023-12-20",
"test_url":"https://www.caniemail.com/tests/css-border-collapse.html",
"test_results_url":"https://testi.at/proj/4zk4fe7tv86fn4bc6",
"stats":{"apple-mail":{"macos":{"2023-12":"y"},"ios":{"2023-12":"y"}},"gmail":{"desktop-webmail":{"2023-12":"y"},"ios":{"2023-12":"y"},"android":{"2023-12":"y"},"mobile-webmail":{"2023-12":"y"}},"orange":{"desktop-webmail":{"2023-12":"u"},"ios":{"2023-12":"u"},"android":{"2023-12":"u"}},"outlook":{"windows":{"2023-12":"y"},"windows-mail":{"2023-12":"y"},"macos":{"2023-12":"y"},"outlook-com":{"2023-12":"y"},"ios":{"2023-12":"y"},"android":{"2023-12":"y"}},"yahoo":{"desktop-webmail":{"2023-12":"y"},"ios":{"2023-12":"y"},"android":{"2023-12":"y"}},"aol":{"desktop-webmail":{"2023-12":"y"},"ios":{"2023-12":"y"},"android":{"2023-12":"y"}},"samsung-email":{"android":{"2023-12":"y"}},"sfr":{"desktop-webmail":{"2024-03":"y"},"ios":{"2024-03":"y"},"android":{"2024-03":"y"}},"thunderbird":{"macos":{"2023-12":"y"}},"protonmail":{"desktop-webmail":{"2023-12":"u"},"ios":{"2023-12":"u"},"android":{"2023-12":"u"}},"hey":{"desktop-webmail":{"2023-12":"u"}},"mail-ru":{"desktop-webmail":{"2023-12":"y"}},"fastmail":{"desktop-webmail":{"2023-12":"u"}},"laposte":{"desktop-webmail":{"2023-12":"u"}},"gmx":{"desktop-webmail":{"2023-12":"y"},"ios":{"2023-12":"u"},"android":{"2023-12":"u"}},"web-de":{"desktop-webmail":{"2023-12":"y"},"ios":{"2023-12":"u"},"android":{"2023-12":"u"}},"ionos-1and1":{"desktop-webmail":{"2023-12":"u"},"android":{"2023-12":"u"}}},
"stats":{"apple-mail":{"macos":{"2023-12":"y"},"ios":{"2023-12":"y"}},"gmail":{"desktop-webmail":{"2023-12":"y"},"ios":{"2023-12":"y"},"android":{"2023-12":"y"},"mobile-webmail":{"2023-12":"y"}},"orange":{"desktop-webmail":{"2023-12":"u"},"ios":{"2023-12":"u"},"android":{"2023-12":"u"}},"outlook":{"windows":{"2023-12":"y"},"windows-mail":{"2023-12":"y"},"macos":{"2023-12":"y"},"outlook-com":{"2023-12":"y"},"ios":{"2023-12":"y"},"android":{"2023-12":"y"}},"yahoo":{"desktop-webmail":{"2023-12":"y"},"ios":{"2023-12":"y"},"android":{"2023-12":"y"}},"aol":{"desktop-webmail":{"2023-12":"y"},"ios":{"2023-12":"y"},"android":{"2023-12":"y"}},"samsung-email":{"android":{"2023-12":"y"}},"sfr":{"desktop-webmail":{"2024-03":"y"},"ios":{"2024-03":"y"},"android":{"2024-03":"y"}},"thunderbird":{"macos":{"2023-12":"y"}},"protonmail":{"desktop-webmail":{"2023-12":"y"},"ios":{"2023-12":"y"},"android":{"2023-12":"y"}},"hey":{"desktop-webmail":{"2023-12":"u"}},"mail-ru":{"desktop-webmail":{"2023-12":"y"}},"fastmail":{"desktop-webmail":{"2023-12":"u"}},"laposte":{"desktop-webmail":{"2023-12":"u"}},"gmx":{"desktop-webmail":{"2023-12":"y"},"ios":{"2023-12":"u"},"android":{"2023-12":"u"}},"web-de":{"desktop-webmail":{"2023-12":"y"},"ios":{"2023-12":"u"},"android":{"2023-12":"u"}},"ionos-1and1":{"desktop-webmail":{"2023-12":"u"},"android":{"2023-12":"u"}}},
"notes":null,
"notes_by_num":null
},
@@ -478,7 +478,7 @@
"last_test_date":"2022-07-14",
"test_url":"https://www.caniemail.com/tests/css-border-logical-properties.html",
"test_results_url":"https://testi.at/proj/1yxFDAGtwrUmbf4tzMTY",
"stats":{"apple-mail":{"macos":{"10.12":"n","10.13":"n","10.15":"a #1","11":"y","12":"y"},"ios":{"11":"n","12":"a #1","13":"a #1","14":"a #1","15":"y"}},"gmail":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"},"mobile-webmail":{"2022-07":"n"}},"orange":{"desktop-webmail":{"2022-07":"u"},"ios":{"2022-07":"u"},"android":{"2022-07":"u"}},"outlook":{"windows":{"2013":"n","2016":"n","2019":"n","2021":"n"},"windows-mail":{"2022-07":"n"},"macos":{"2011":"a #1","2016":"a #1","16.80":"n"},"outlook-com":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"}},"samsung-email":{"android":{"10":"a #1","11":"a #1"}},"sfr":{"desktop-webmail":{"2024-03":"y"},"ios":{"2024-03":"y"},"android":{"2024-03":"y"}},"thunderbird":{"macos":{"60.3":"u"}},"aol":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"}},"yahoo":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"}},"protonmail":{"desktop-webmail":{"2022-07":"u"},"ios":{"2022-07":"u"},"android":{"2022-07":"u"}},"hey":{"desktop-webmail":{"2022-07":"u"}},"mail-ru":{"desktop-webmail":{"2022-07":"y"}},"fastmail":{"desktop-webmail":{"2022-07":"u"}},"laposte":{"desktop-webmail":{"2022-07":"u"}},"gmx":{"desktop-webmail":{"2022-09":"n"},"ios":{"2022-09":"y"},"android":{"2022-09":"y"}},"web-de":{"desktop-webmail":{"2022-09":"n"},"ios":{"2022-09":"y"},"android":{"2022-09":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-09":"y"},"android":{"2022-09":"y"}}},
"stats":{"apple-mail":{"macos":{"10.12":"n","10.13":"n","10.15":"a #1","11":"y","12":"y"},"ios":{"11":"n","12":"a #1","13":"a #1","14":"a #1","15":"y"}},"gmail":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"},"mobile-webmail":{"2022-07":"n"}},"orange":{"desktop-webmail":{"2022-07":"u"},"ios":{"2022-07":"u"},"android":{"2022-07":"u"}},"outlook":{"windows":{"2013":"n","2016":"n","2019":"n","2021":"n"},"windows-mail":{"2022-07":"n"},"macos":{"2011":"a #1","2016":"a #1","16.80":"n"},"outlook-com":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"}},"samsung-email":{"android":{"10":"a #1","11":"a #1"}},"sfr":{"desktop-webmail":{"2024-03":"y"},"ios":{"2024-03":"y"},"android":{"2024-03":"y"}},"thunderbird":{"macos":{"60.3":"u"}},"aol":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"}},"yahoo":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"}},"protonmail":{"desktop-webmail":{"2022-07":"y"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"hey":{"desktop-webmail":{"2022-07":"u"}},"mail-ru":{"desktop-webmail":{"2022-07":"y"}},"fastmail":{"desktop-webmail":{"2022-07":"u"}},"laposte":{"desktop-webmail":{"2022-07":"u"}},"gmx":{"desktop-webmail":{"2022-09":"n"},"ios":{"2022-09":"y"},"android":{"2022-09":"y"}},"web-de":{"desktop-webmail":{"2022-09":"n"},"ios":{"2022-09":"y"},"android":{"2022-09":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-09":"y"},"android":{"2022-09":"y"}}},
"notes":null,
"notes_by_num":{"1":"Partial. `border-<inline/block>-color` and `border-<inline/block>-width` does not work."}
},
@@ -494,7 +494,7 @@
"last_test_date":"2022-07-14",
"test_url":"https://www.caniemail.com/tests/css-border-logical-properties.html",
"test_results_url":"https://testi.at/proj/1yxFDAGtwrUmbf4tzMTY",
"stats":{"apple-mail":{"macos":{"10.12":"n","10.13":"n","10.15":"y","11":"y","12":"y"},"ios":{"11":"n","12":"y","13":"y","14":"y","15":"y"}},"gmail":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"},"mobile-webmail":{"2022-07":"n"}},"orange":{"desktop-webmail":{"2022-07":"u"},"ios":{"2022-07":"u"},"android":{"2022-07":"u"}},"outlook":{"windows":{"2013":"n","2016":"n","2019":"n","2021":"n"},"windows-mail":{"2022-07":"n"},"macos":{"2011":"y","2016":"y","16.80":"n"},"outlook-com":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"}},"samsung-email":{"android":{"10":"y","11":"y"}},"sfr":{"desktop-webmail":{"2024-03":"y"},"ios":{"2024-03":"y"},"android":{"2024-03":"y"}},"thunderbird":{"macos":{"60.3":"u"}},"aol":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"}},"yahoo":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"}},"protonmail":{"desktop-webmail":{"2022-07":"u"},"ios":{"2022-07":"u"},"android":{"2022-07":"u"}},"hey":{"desktop-webmail":{"2022-07":"u"}},"mail-ru":{"desktop-webmail":{"2022-07":"y"}},"fastmail":{"desktop-webmail":{"2022-07":"u"}},"laposte":{"desktop-webmail":{"2022-07":"u"}},"gmx":{"desktop-webmail":{"2022-09":"n"},"ios":{"2022-09":"y"},"android":{"2022-09":"y"}},"web-de":{"desktop-webmail":{"2022-09":"n"},"ios":{"2022-09":"y"},"android":{"2022-09":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-09":"y"},"android":{"2022-09":"y"}}},
"stats":{"apple-mail":{"macos":{"10.12":"n","10.13":"n","10.15":"y","11":"y","12":"y"},"ios":{"11":"n","12":"y","13":"y","14":"y","15":"y"}},"gmail":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"},"mobile-webmail":{"2022-07":"n"}},"orange":{"desktop-webmail":{"2022-07":"u"},"ios":{"2022-07":"u"},"android":{"2022-07":"u"}},"outlook":{"windows":{"2013":"n","2016":"n","2019":"n","2021":"n"},"windows-mail":{"2022-07":"n"},"macos":{"2011":"y","2016":"y","16.80":"n"},"outlook-com":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"}},"samsung-email":{"android":{"10":"y","11":"y"}},"sfr":{"desktop-webmail":{"2024-03":"y"},"ios":{"2024-03":"y"},"android":{"2024-03":"y"}},"thunderbird":{"macos":{"60.3":"u"}},"aol":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"}},"yahoo":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"}},"protonmail":{"desktop-webmail":{"2022-07":"y"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"hey":{"desktop-webmail":{"2022-07":"u"}},"mail-ru":{"desktop-webmail":{"2022-07":"y"}},"fastmail":{"desktop-webmail":{"2022-07":"u"}},"laposte":{"desktop-webmail":{"2022-07":"u"}},"gmx":{"desktop-webmail":{"2022-09":"n"},"ios":{"2022-09":"y"},"android":{"2022-09":"y"}},"web-de":{"desktop-webmail":{"2022-09":"n"},"ios":{"2022-09":"y"},"android":{"2022-09":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-09":"y"},"android":{"2022-09":"y"}}},
"notes":null,
"notes_by_num":null
},
@@ -510,7 +510,7 @@
"last_test_date":"2022-07-13",
"test_url":"https://www.caniemail.com/tests/css-border-logical-properties.html",
"test_results_url":"https://testi.at/proj/1yxFDAGtwrUmbf4tzMTY",
"stats":{"apple-mail":{"macos":{"10.15":"n","11":"y","12":"y"},"ios":{"13":"n","14":"n","15":"y"}},"gmail":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"},"mobile-webmail":{"2022-07":"n"}},"orange":{"desktop-webmail":{"2022-07":"u"},"ios":{"2022-07":"u"},"android":{"2022-07":"u"}},"outlook":{"windows":{"2013":"n","2016":"n","2019":"n","2021":"n"},"windows-mail":{"2022-07":"n"},"macos":{"2011":"n","2016":"n","16.80":"n"},"outlook-com":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"}},"samsung-email":{"android":{"10":"n","11":"n"}},"sfr":{"desktop-webmail":{"2024-03":"y"},"ios":{"2024-03":"y"},"android":{"2024-03":"y"}},"thunderbird":{"macos":{"60.3":"u"}},"aol":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"}},"yahoo":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"}},"protonmail":{"desktop-webmail":{"2022-07":"u"},"ios":{"2022-07":"u"},"android":{"2022-07":"u"}},"hey":{"desktop-webmail":{"2022-07":"u"}},"mail-ru":{"desktop-webmail":{"2022-07":"y"}},"fastmail":{"desktop-webmail":{"2022-07":"u"}},"laposte":{"desktop-webmail":{"2022-07":"u"}},"gmx":{"desktop-webmail":{"2022-09":"n"},"ios":{"2022-09":"y"},"android":{"2022-09":"y"}},"web-de":{"desktop-webmail":{"2022-09":"n"},"ios":{"2022-09":"y"},"android":{"2022-09":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-09":"y"},"android":{"2022-09":"y"}}},
"stats":{"apple-mail":{"macos":{"10.15":"n","11":"y","12":"y"},"ios":{"13":"n","14":"n","15":"y"}},"gmail":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"},"mobile-webmail":{"2022-07":"n"}},"orange":{"desktop-webmail":{"2022-07":"u"},"ios":{"2022-07":"u"},"android":{"2022-07":"u"}},"outlook":{"windows":{"2013":"n","2016":"n","2019":"n","2021":"n"},"windows-mail":{"2022-07":"n"},"macos":{"2011":"n","2016":"n","16.80":"n"},"outlook-com":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"}},"samsung-email":{"android":{"10":"n","11":"n"}},"sfr":{"desktop-webmail":{"2024-03":"y"},"ios":{"2024-03":"y"},"android":{"2024-03":"y"}},"thunderbird":{"macos":{"60.3":"u"}},"aol":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"}},"yahoo":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"}},"protonmail":{"desktop-webmail":{"2022-07":"y"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"hey":{"desktop-webmail":{"2022-07":"u"}},"mail-ru":{"desktop-webmail":{"2022-07":"y"}},"fastmail":{"desktop-webmail":{"2022-07":"u"}},"laposte":{"desktop-webmail":{"2022-07":"u"}},"gmx":{"desktop-webmail":{"2022-09":"n"},"ios":{"2022-09":"y"},"android":{"2022-09":"y"}},"web-de":{"desktop-webmail":{"2022-09":"n"},"ios":{"2022-09":"y"},"android":{"2022-09":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-09":"y"},"android":{"2022-09":"y"}}},
"notes":null,
"notes_by_num":null
},
@@ -526,7 +526,7 @@
"last_test_date":"2022-08-16",
"test_url":"https://www.caniemail.com/tests/css-border-logical-properties.html",
"test_results_url":"https://testi.at/proj/1yxFDAGtwrUmbf4tzMTY",
"stats":{"apple-mail":{"macos":{"10.15":"n","11":"n","12":"y"},"ios":{"13":"n","14":"n","15":"y"}},"gmail":{"desktop-webmail":{"2022-08":"n"},"ios":{"2022-08":"n"},"android":{"2022-08":"n"},"mobile-webmail":{"2022-08":"n"}},"orange":{"desktop-webmail":{"2022-08":"u"},"ios":{"2022-08":"u"},"android":{"2022-08":"u"}},"outlook":{"windows":{"2013":"n","2016":"n","2019":"n","2021":"n"},"windows-mail":{"2022-08":"n"},"macos":{"2011":"n","2016":"n","16.80":"n"},"outlook-com":{"2022-08":"n"},"ios":{"2022-08":"n"},"android":{"2022-08":"n"}},"samsung-email":{"android":{"10":"n","11":"n"}},"sfr":{"desktop-webmail":{"2024-03":"y"},"ios":{"2024-03":"y"},"android":{"2024-03":"y"}},"thunderbird":{"macos":{"60.3":"u"}},"aol":{"desktop-webmail":{"2022-08":"n"},"ios":{"2022-08":"n"},"android":{"2022-08":"n"}},"yahoo":{"desktop-webmail":{"2022-08":"n"},"ios":{"2022-08":"n"},"android":{"2022-08":"n"}},"protonmail":{"desktop-webmail":{"2022-08":"u"},"ios":{"2022-08":"u"},"android":{"2022-08":"u"}},"hey":{"desktop-webmail":{"2022-08":"u"}},"mail-ru":{"desktop-webmail":{"2022-08":"y"}},"fastmail":{"desktop-webmail":{"2022-08":"u"}},"laposte":{"desktop-webmail":{"2022-08":"u"}}},
"stats":{"apple-mail":{"macos":{"10.15":"n","11":"n","12":"y"},"ios":{"13":"n","14":"n","15":"y"}},"gmail":{"desktop-webmail":{"2022-08":"n"},"ios":{"2022-08":"n"},"android":{"2022-08":"n"},"mobile-webmail":{"2022-08":"n"}},"orange":{"desktop-webmail":{"2022-08":"u"},"ios":{"2022-08":"u"},"android":{"2022-08":"u"}},"outlook":{"windows":{"2013":"n","2016":"n","2019":"n","2021":"n"},"windows-mail":{"2022-08":"n"},"macos":{"2011":"n","2016":"n","16.80":"n"},"outlook-com":{"2022-08":"n"},"ios":{"2022-08":"n"},"android":{"2022-08":"n"}},"samsung-email":{"android":{"10":"n","11":"n"}},"sfr":{"desktop-webmail":{"2024-03":"y"},"ios":{"2024-03":"y"},"android":{"2024-03":"y"}},"thunderbird":{"macos":{"60.3":"u"}},"aol":{"desktop-webmail":{"2022-08":"n"},"ios":{"2022-08":"n"},"android":{"2022-08":"n"}},"yahoo":{"desktop-webmail":{"2022-08":"n"},"ios":{"2022-08":"n"},"android":{"2022-08":"n"}},"protonmail":{"desktop-webmail":{"2022-08":"y"},"ios":{"2022-08":"y"},"android":{"2022-08":"y"}},"hey":{"desktop-webmail":{"2022-08":"u"}},"mail-ru":{"desktop-webmail":{"2022-08":"y"}},"fastmail":{"desktop-webmail":{"2022-08":"u"}},"laposte":{"desktop-webmail":{"2022-08":"u"}}},
"notes":null,
"notes_by_num":null
},
@@ -558,7 +558,7 @@
"last_test_date":"2023-12-20",
"test_url":"https://www.caniemail.com/tests/css-border-spacing.html",
"test_results_url":"https://testi.at/proj/dyodfk8c5dhjanflz",
"stats":{"apple-mail":{"macos":{"2023-12":"y"},"ios":{"2023-12":"y"}},"gmail":{"desktop-webmail":{"2023-12":"y"},"ios":{"2023-12":"y"},"android":{"2023-12":"y"},"mobile-webmail":{"2023-12":"y"}},"orange":{"desktop-webmail":{"2023-12":"u"},"ios":{"2023-12":"u"},"android":{"2023-12":"u"}},"outlook":{"windows":{"2013":"n","2016":"n","2019":"n","2021":"n"},"windows-mail":{"2023-12":"n"},"macos":{"2023-12":"n"},"outlook-com":{"2023-12":"y"},"ios":{"2023-12":"y"},"android":{"2023-12":"y"}},"yahoo":{"desktop-webmail":{"2023-12":"y"},"ios":{"2023-12":"y"},"android":{"2023-12":"y"}},"aol":{"desktop-webmail":{"2023-12":"y"},"ios":{"2023-12":"y"},"android":{"2023-12":"y"}},"samsung-email":{"android":{"2023-12":"y"}},"sfr":{"desktop-webmail":{"2024-03":"y"},"ios":{"2024-03":"y"},"android":{"2024-03":"y"}},"thunderbird":{"macos":{"2023-12":"y"}},"protonmail":{"desktop-webmail":{"2023-12":"u"},"ios":{"2023-12":"u"},"android":{"2023-12":"u"}},"hey":{"desktop-webmail":{"2023-12":"u"}},"mail-ru":{"desktop-webmail":{"2023-12":"y"}},"fastmail":{"desktop-webmail":{"2023-12":"u"}},"laposte":{"desktop-webmail":{"2023-12":"u"}},"gmx":{"desktop-webmail":{"2023-12":"y"},"ios":{"2023-12":"u"},"android":{"2023-12":"u"}},"web-de":{"desktop-webmail":{"2023-12":"y"},"ios":{"2023-12":"u"},"android":{"2023-12":"u"}},"ionos-1and1":{"desktop-webmail":{"2023-12":"u"},"android":{"2023-12":"u"}}},
"stats":{"apple-mail":{"macos":{"2023-12":"y"},"ios":{"2023-12":"y"}},"gmail":{"desktop-webmail":{"2023-12":"y"},"ios":{"2023-12":"y"},"android":{"2023-12":"y"},"mobile-webmail":{"2023-12":"y"}},"orange":{"desktop-webmail":{"2023-12":"u"},"ios":{"2023-12":"u"},"android":{"2023-12":"u"}},"outlook":{"windows":{"2013":"n","2016":"n","2019":"n","2021":"n"},"windows-mail":{"2023-12":"n"},"macos":{"2023-12":"n"},"outlook-com":{"2023-12":"y"},"ios":{"2023-12":"y"},"android":{"2023-12":"y"}},"yahoo":{"desktop-webmail":{"2023-12":"y"},"ios":{"2023-12":"y"},"android":{"2023-12":"y"}},"aol":{"desktop-webmail":{"2023-12":"y"},"ios":{"2023-12":"y"},"android":{"2023-12":"y"}},"samsung-email":{"android":{"2023-12":"y"}},"sfr":{"desktop-webmail":{"2024-03":"y"},"ios":{"2024-03":"y"},"android":{"2024-03":"y"}},"thunderbird":{"macos":{"2023-12":"y"}},"protonmail":{"desktop-webmail":{"2023-12":"y"},"ios":{"2023-12":"y"},"android":{"2023-12":"y"}},"hey":{"desktop-webmail":{"2023-12":"u"}},"mail-ru":{"desktop-webmail":{"2023-12":"y"}},"fastmail":{"desktop-webmail":{"2023-12":"u"}},"laposte":{"desktop-webmail":{"2023-12":"u"}},"gmx":{"desktop-webmail":{"2023-12":"y"},"ios":{"2023-12":"u"},"android":{"2023-12":"u"}},"web-de":{"desktop-webmail":{"2023-12":"y"},"ios":{"2023-12":"u"},"android":{"2023-12":"u"}},"ionos-1and1":{"desktop-webmail":{"2023-12":"u"},"android":{"2023-12":"u"}}},
"notes":null,
"notes_by_num":null
},
@@ -739,6 +739,22 @@
"notes_by_num":{"1":"Partial. Not supported with Hotmail/Outlook accounts."}
},
{
"slug":"css-cursor",
"title":"cursor",
"description":"The cursor CSS property sets the mouse cursor, if any, to show when the mouse pointer is over an element.",
"url":"https://www.caniemail.com/features/css-cursor/",
"category":"css",
"tags":["accessibility"],
"keywords":"pointer, mouse, touch",
"last_test_date":"2025-07-02",
"test_url":"https://www.caniemail.com/tests/css-cursor.html",
"test_results_url":"https://testi.at/proj/52gbh94rh6lncdl4fge",
"stats":{"apple-mail":{"macos":{"15":"a #1"},"ios":{"15":"n #3"}},"gmail":{"desktop-webmail":{"2025-07":"n #2"},"ios":{"2025-07":"n #2"},"android":{"2025-07":"n #2"},"mobile-webmail":{"2025-07":"n #2"}},"orange":{"desktop-webmail":{"2025-07":"u"},"ios":{"2025-07":"u"},"android":{"2025-07":"u"}},"outlook":{"windows":{"2007":"u","2010":"u","2013":"u","2016":"u","2019":"u"},"windows-mail":{"2025-07":"u"},"macos":{"16.98":"n"},"outlook-com":{"2025-07":"n"},"ios":{"2025-07":"n #3"},"android":{"2025-07":"n"}},"samsung-email":{"android":{"6.0":"u"}},"sfr":{"desktop-webmail":{"2025-07":"u"},"ios":{"2025-07":"u"},"android":{"2025-07":"u"}},"thunderbird":{"macos":{"78.14":"y"}},"aol":{"desktop-webmail":{"2025-07":"u"},"ios":{"2025-07":"u"},"android":{"2025-07":"u"}},"yahoo":{"desktop-webmail":{"2025-07":"a #4"},"ios":{"2025-07":"n #3"},"android":{"2025-07":"a #4"}},"protonmail":{"desktop-webmail":{"2025-07":"a #5"},"ios":{"2025-07":"u"},"android":{"2025-07":"u"}},"hey":{"desktop-webmail":{"2025-07":"u"}},"mail-ru":{"desktop-webmail":{"2025-07":"u"}},"fastmail":{"desktop-webmail":{"2025-07":"u"}},"laposte":{"desktop-webmail":{"2025-07":"u"}},"free-fr":{"desktop-webmail":{"2025-07":"u"}},"t-online-de":{"desktop-webmail":{"2025-07":"u"}},"gmx":{"desktop-webmail":{"2025-07":"a #6"},"ios":{"2025-07":"n #3"},"android":{"2025-07":"y"}},"web-de":{"desktop-webmail":{"2025-07":"u"},"ios":{"2025-07":"u"},"android":{"2025-07":"u"}},"ionos-1and1":{"desktop-webmail":{"2025-07":"u"},"android":{"2025-07":"u"}}},
"notes":"Cursor appearance on Android mobile devices depends on external pointer device/mouse. Cursor on iOS mobile devices also requires assistive touch to be enabled, and does not appear to respond to content.",
"notes_by_num":{"1":"Partial. URL is not supported.","2":"Cursor property is removed.","3":"iOS assistive touch does not respond to cursor.","4":"Partial. Only supports: crosshair, help, move, pointer, progress, text, wait, auto, default, and all single-direction resize properties.","5":"Partial. URL buggy and only works inline.","6":"Partial. Inline CSS only. Only supports: crosshair, help, move, pointer, wait, auto, default, and all single-direction resize properties."}
},
{
"slug":"css-direction",
"title":"direction",
@@ -830,7 +846,7 @@
"last_test_date":"2024-08-23",
"test_url":"https://www.caniemail.com/tests/css-empty-cells.html",
"test_results_url":"https://testi.at/proj/kgl7t57xs8jxueze0v8",
"stats":{"apple-mail":{"macos":{"2024-08":"y"},"ios":{"2024-08":"y"}},"gmail":{"desktop-webmail":{"2024-08":"y"},"ios":{"2024-08":"y"},"android":{"2024-08":"y"},"mobile-webmail":{"2024-08":"u"}},"orange":{"desktop-webmail":{"2024-08":"u"},"ios":{"2024-08":"u"},"android":{"2024-08":"u"}},"outlook":{"windows":{"2013":"n","2016":"n","2019":"n","2021":"n"},"windows-mail":{"2024-08":"n"},"macos":{"2024-08":"y"},"outlook-com":{"2024-08":"y"},"ios":{"2024-08":"y"},"android":{"2024-08":"y"}},"yahoo":{"desktop-webmail":{"2024-08":"y"},"ios":{"2024-08":"n"},"android":{"2024-08":"n"}},"aol":{"desktop-webmail":{"2024-08":"y"},"ios":{"2024-08":"n"},"android":{"2024-08":"n"}},"samsung-email":{"android":{"2024-08":"y"}},"sfr":{"desktop-webmail":{"2024-03":"u"},"ios":{"2024-03":"u"},"android":{"2024-03":"u"}},"protonmail":{"desktop-webmail":{"2024-08":"u"},"ios":{"2024-08":"u"},"android":{"2024-08":"u"}},"hey":{"desktop-webmail":{"2024-08":"u"}},"mail-ru":{"desktop-webmail":{"2024-08":"n"}},"fastmail":{"desktop-webmail":{"2024-08":"u"}}},
"stats":{"apple-mail":{"macos":{"2024-08":"y"},"ios":{"2024-08":"y"}},"gmail":{"desktop-webmail":{"2024-08":"y"},"ios":{"2024-08":"y"},"android":{"2024-08":"y"},"mobile-webmail":{"2024-08":"u"}},"orange":{"desktop-webmail":{"2024-08":"u"},"ios":{"2024-08":"u"},"android":{"2024-08":"u"}},"outlook":{"windows":{"2013":"n","2016":"n","2019":"n","2021":"n"},"windows-mail":{"2024-08":"n"},"macos":{"2024-08":"y"},"outlook-com":{"2024-08":"y"},"ios":{"2024-08":"y"},"android":{"2024-08":"y"}},"yahoo":{"desktop-webmail":{"2024-08":"y"},"ios":{"2024-08":"n"},"android":{"2024-08":"n"}},"aol":{"desktop-webmail":{"2024-08":"y"},"ios":{"2024-08":"n"},"android":{"2024-08":"n"}},"samsung-email":{"android":{"2024-08":"y"}},"sfr":{"desktop-webmail":{"2024-03":"u"},"ios":{"2024-03":"u"},"android":{"2024-03":"u"}},"protonmail":{"desktop-webmail":{"2024-08":"y"},"ios":{"2024-08":"y"},"android":{"2024-08":"y"}},"hey":{"desktop-webmail":{"2024-08":"u"}},"mail-ru":{"desktop-webmail":{"2024-08":"n"}},"fastmail":{"desktop-webmail":{"2024-08":"u"}}},
"notes":null,
"notes_by_num":null
},
@@ -910,7 +926,7 @@
"last_test_date":"2022-08-01",
"test_url":"https://www.caniemail.com/tests/css-font-kerning.html",
"test_results_url":"https://app.emailonacid.com/app/acidtest/RlRYNGDjVNBhofxCNxloUcRbUVWGDhJ2kZ4fy6HXpEatH/list",
"stats":{"apple-mail":{"macos":{"11":"y","12":"y","13":"y","14":"y","15":"y"},"ios":{"11":"y","12":"y","13":"y","14":"y","15":"y"}},"gmail":{"desktop-webmail":{"2022-08":"y"},"ios":{"2022-08":"y"},"android":{"2022-08":"y"},"mobile-webmail":{"2022-08":"y"}},"outlook":{"windows":{"2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"macos":{"2022-08":"y","16.80":"y"},"outlook-com":{"2022-08":"y"},"ios":{"2022-08":"y"},"android":{"4.2101.1":"y"}},"yahoo":{"desktop-webmail":{"2022-08":"n","2024-03":"n"},"ios":{"2024-03":"n"},"android":{"2024-03":"n"}},"aol":{"desktop-webmail":{"2022-08":"n"}},"samsung-email":{"android":{"6.1.31.2":"y"}},"mail-ru":{"desktop-webmail":{"2022-08":"n"}},"free-fr":{"desktop-webmail":{"2022-08":"y"}},"gmx":{"desktop-webmail":{"2022-08":"n"}},"t-online-de":{"desktop-webmail":{"2022-08":"n"}},"sfr":{"desktop-webmail":{"2024-03":"y"},"ios":{"2024-03":"u"},"android":{"2024-03":"u"}},"thunderbird":{"macos":{"128.9.0":"y"}}},
"stats":{"apple-mail":{"macos":{"11":"y","12":"y","13":"y","14":"y","15":"y"},"ios":{"11":"y","12":"y","13":"y","14":"y","15":"y"}},"gmail":{"desktop-webmail":{"2022-08":"y"},"ios":{"2022-08":"y"},"android":{"2022-08":"y"},"mobile-webmail":{"2022-08":"y"}},"outlook":{"windows":{"2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"macos":{"2022-08":"y","16.80":"y"},"outlook-com":{"2022-08":"y"},"ios":{"2022-08":"y"},"android":{"4.2101.1":"y"}},"yahoo":{"desktop-webmail":{"2022-08":"n","2024-03":"n"},"ios":{"2024-03":"n"},"android":{"2024-03":"n"}},"aol":{"desktop-webmail":{"2022-08":"n"}},"samsung-email":{"android":{"6.1.31.2":"y"}},"mail-ru":{"desktop-webmail":{"2022-08":"n"}},"free-fr":{"desktop-webmail":{"2022-08":"y"}},"gmx":{"desktop-webmail":{"2022-08":"n"}},"t-online-de":{"desktop-webmail":{"2022-08":"n"}},"sfr":{"desktop-webmail":{"2024-03":"y"},"ios":{"2024-03":"u"},"android":{"2024-03":"u"}},"thunderbird":{"macos":{"128.9.0":"y"}},"protonmail":{"desktop-webmail":{"2023-12":"y"},"ios":{"2023-12":"y"},"android":{"2023-12":"y"}}},
"notes":null,
"notes_by_num":null
},
@@ -1006,9 +1022,9 @@
"last_test_date":"2024-08-14",
"test_url":"https://www.caniemail.com/tests/css-function-light-dark.html",
"test_results_url":"https://app.emailonacid.com/app/acidtest/Lai13xyIE95H6jo1BBs6ay0f3RvJdPL344S3j3M7FbeU4/list",
"stats":{"apple-mail":{"macos":{"16.0":"y #1"},"ios":{"17.5.1":"y"}},"gmail":{"desktop-webmail":{"2024-08":"n"},"ios":{"2024-08":"n"},"android":{"2024-08":"n"},"mobile-webmail":{"2024-08":"n"}},"orange":{"desktop-webmail":{"2024-08":"n"},"ios":{"2024-08":"n"},"android":{"2024-08":"u"}},"outlook":{"windows":{"2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"windows-mail":{"2024-08":"n"},"macos":{"16.88":"n"},"outlook-com":{"2024-08":"n"},"ios":{"2024-08":"n"},"android":{"2024-08":"u"}},"samsung-email":{"android":{"6.0":"u"}},"sfr":{"desktop-webmail":{"2024-08":"a #2"},"ios":{"2024-08":"a #1 #2"},"android":{"2024-08":"u"}},"thunderbird":{"macos":{"115.10.1":"n","128.1.0":"y"}},"aol":{"desktop-webmail":{"2024-08":"n"},"ios":{"2024-08":"n"},"android":{"2024-08":"u"}},"yahoo":{"desktop-webmail":{"2024-08":"n"},"ios":{"2024-08":"n"},"android":{"2024-08":"u"}},"protonmail":{"desktop-webmail":{"2024-08":"a #2"},"ios":{"2024-08":"y #1"},"android":{"2024-08":"u"}},"hey":{"desktop-webmail":{"2024-08":"a #2"}},"mail-ru":{"desktop-webmail":{"2024-08":"a #2"}},"fastmail":{"desktop-webmail":{"2024-08":"u"}},"laposte":{"desktop-webmail":{"2024-08":"a #2"}},"free-fr":{"desktop-webmail":{"2024-08":"n"}},"t-online-de":{"desktop-webmail":{"2024-08":"a #2"}},"gmx":{"desktop-webmail":{"2024-08":"n"}}},
"stats":{"apple-mail":{"macos":{"16.0":"y #1"},"ios":{"17.5.1":"y"}},"gmail":{"desktop-webmail":{"2024-08":"n"},"ios":{"2024-08":"n"},"android":{"2024-08":"n"},"mobile-webmail":{"2024-08":"n"}},"orange":{"desktop-webmail":{"2024-08":"n"},"ios":{"2024-08":"n"},"android":{"2024-08":"u"}},"outlook":{"windows":{"2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"windows-mail":{"2024-08":"n"},"macos":{"16.88":"n"},"outlook-com":{"2024-08":"n"},"ios":{"2024-08":"n"},"android":{"2024-08":"u"}},"samsung-email":{"android":{"6.2":"a #3"}},"sfr":{"desktop-webmail":{"2024-08":"a #2"},"ios":{"2024-08":"a #1 #2"},"android":{"2024-08":"u"}},"thunderbird":{"macos":{"115.10.1":"n","128.1.0":"y"}},"aol":{"desktop-webmail":{"2024-08":"n"},"ios":{"2024-08":"n"},"android":{"2024-08":"u"}},"yahoo":{"desktop-webmail":{"2024-08":"n"},"ios":{"2024-08":"n"},"android":{"2024-08":"u"}},"protonmail":{"desktop-webmail":{"2024-08":"a #2"},"ios":{"2024-08":"y #1"},"android":{"2024-08":"u"}},"hey":{"desktop-webmail":{"2024-08":"a #2"}},"mail-ru":{"desktop-webmail":{"2024-08":"a #2"}},"fastmail":{"desktop-webmail":{"2024-08":"u"}},"laposte":{"desktop-webmail":{"2024-08":"a #2"}},"free-fr":{"desktop-webmail":{"2024-08":"n"}},"t-online-de":{"desktop-webmail":{"2024-08":"a #2"}},"gmx":{"desktop-webmail":{"2024-08":"n"}}},
"notes":null,
"notes_by_num":{"1":"Only supported if youve updated your OS with Safari 17.5 or later.","2":"Buggy. The function is supported but the color stays light even in dark mode."}
"notes_by_num":{"1":"Only supported if youve updated your OS with Safari 17.5 or later.","2":"Buggy. The function is supported but the color stays light even in dark mode.","3":"Partial. Not supported with Hotmail/Outlook accounts."}
},
{
@@ -1150,9 +1166,9 @@
"last_test_date":"2021-11-30",
"test_url":"https://www.caniemail.com/tests/css-important.html",
"test_results_url":"https://app.emailonacid.com/app/acidtest/JEyxyPfKHFZCPKxlgiOugpH4lyNrXX39cd9M8xaW1DojH/list",
"stats":{"apple-mail":{"macos":{"13":"y","15":"y"},"ios":{"15":"y"}},"gmail":{"desktop-webmail":{"2021-11":"a #1"},"ios":{"2021-11":"a #1 #2"},"android":{"2021-11":"a #1 #2"},"mobile-webmail":{"2021-11":"a #1 #2"}},"orange":{"desktop-webmail":{"2021-11":"n #3"},"ios":{"2021-11":"n #3"},"android":{"2021-11":"n #3"}},"outlook":{"windows":{"2007":"a #4 #5","2010":"a #4 #5","2013":"a #4 #5","2016":"a #4 #5","2019":"a #4 #5"},"windows-mail":{"2021-11":"a #4"},"macos":{"16.56":"y","16.80":"y"},"outlook-com":{"2021-11":"y"},"ios":{"2021-11":"y"},"android":{"2021-11":"y"}},"samsung-email":{"android":{"7.0":"y"}},"sfr":{"desktop-webmail":{"2021-11":"y"},"ios":{"2021-11":"a #6"},"android":{"2021-11":"a #6"}},"thunderbird":{"macos":{"91.2.1":"y"}},"aol":{"desktop-webmail":{"2021-11":"a #7"},"ios":{"2021-11":"a #7"},"android":{"2021-11":"a #7"}},"yahoo":{"desktop-webmail":{"2021-11":"a #7"},"ios":{"2021-11":"a #7"},"android":{"2021-11":"a #7"}},"protonmail":{"desktop-webmail":{"2021-11":"a #8"},"ios":{"2021-11":"a #6"},"android":{"2021-11":"a #6"}},"hey":{"desktop-webmail":{"2021-11":"y"}},"mail-ru":{"desktop-webmail":{"2021-11":"y"}},"fastmail":{"desktop-webmail":{"2021-11":"y"}},"laposte":{"desktop-webmail":{"2021-11":"y"}},"gmx":{"desktop-webmail":{"2022-06":"n"},"ios":{"2022-06":"y"},"android":{"2022-06":"y"}},"web-de":{"desktop-webmail":{"2022-06":"n"},"ios":{"2022-06":"y"},"android":{"2022-06":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-06":"y"},"android":{"2022-06":"y"}},"wp-pl":{"desktop-webmail":{"2023-12":"n"}}},
"stats":{"apple-mail":{"macos":{"13":"y","15":"y"},"ios":{"15":"y"}},"gmail":{"desktop-webmail":{"2021-11":"a #1"},"ios":{"2021-11":"a #1 #2"},"android":{"2021-11":"a #1 #2"},"mobile-webmail":{"2021-11":"a #1 #2"}},"orange":{"desktop-webmail":{"2021-11":"n #3"},"ios":{"2021-11":"n #3"},"android":{"2021-11":"n #3"}},"outlook":{"windows":{"2007":"a #4 #5","2010":"a #4 #5","2013":"a #4 #5","2016":"a #4 #5","2019":"a #4 #5"},"windows-mail":{"2021-11":"a #4"},"macos":{"16.56":"y","16.80":"y"},"outlook-com":{"2021-11":"y"},"ios":{"2021-11":"y"},"android":{"2021-11":"y"}},"samsung-email":{"android":{"7.0":"y"}},"sfr":{"desktop-webmail":{"2021-11":"y"},"ios":{"2021-11":"a #6"},"android":{"2021-11":"a #6"}},"thunderbird":{"macos":{"91.2.1":"y"}},"aol":{"desktop-webmail":{"2021-11":"a #7"},"ios":{"2021-11":"a #7"},"android":{"2021-11":"a #7"}},"yahoo":{"desktop-webmail":{"2021-11":"a #7"},"ios":{"2021-11":"a #7"},"android":{"2021-11":"a #7"}},"protonmail":{"desktop-webmail":{"2021-11":"a #8"},"ios":{"2021-11":"a #6","2025-08":"a #9"},"android":{"2021-11":"a #6"}},"hey":{"desktop-webmail":{"2021-11":"y"}},"mail-ru":{"desktop-webmail":{"2021-11":"y"}},"fastmail":{"desktop-webmail":{"2021-11":"y"}},"laposte":{"desktop-webmail":{"2021-11":"y"}},"gmx":{"desktop-webmail":{"2022-06":"n"},"ios":{"2022-06":"y"},"android":{"2022-06":"y"}},"web-de":{"desktop-webmail":{"2022-06":"n"},"ios":{"2022-06":"y"},"android":{"2022-06":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-06":"y"},"android":{"2022-06":"y"}},"wp-pl":{"desktop-webmail":{"2023-12":"n"}}},
"notes":null,
"notes_by_num":{"1":"Partial. Only supported in lowercase. (See [email-bugs#13](https://github.com/hteumeuleu/email-bugs/issues/13))","2":"Partial. Only supported inline when using a Non Gmail Account due to the lack of `<style>` support.","3":"Not supported. The entire declaration is removed if there is no space before `!important`.","4":"Partial. Only supported with a space before.","5":"Partial. Not supported inline. (See [email-bugs#31](https://github.com/hteumeuleu/email-bugs/issues/31))","6":"Partial. Only supported inline due to the lack of `<style>` support.","7":"Partial. Removed if there is no space before when used with a `background-image` property. (See [email-bugs#16](https://github.com/hteumeuleu/email-bugs/issues/16))","8":"Partial. Only supported in lowercase."}
"notes_by_num":{"1":"Partial. Only supported in lowercase. (See [email-bugs#13](https://github.com/hteumeuleu/email-bugs/issues/13))","2":"Partial. Only supported inline when using a Non Gmail Account due to the lack of `<style>` support.","3":"Not supported. The entire declaration is removed if there is no space before `!important`.","4":"Partial. Only supported with a space before.","5":"Partial. Not supported inline. (See [email-bugs#31](https://github.com/hteumeuleu/email-bugs/issues/31))","6":"Partial. Only supported inline due to the lack of `<style>` support.","7":"Partial. Removed if there is no space before when used with a `background-image` property. (See [email-bugs#16](https://github.com/hteumeuleu/email-bugs/issues/16))","8":"Partial. Only supported in lowercase.","9":"Partial. Only supported if not written in lowercase."}
},
{
@@ -1358,7 +1374,7 @@
"last_test_date":"2022-07-13",
"test_url":"https://www.caniemail.com/tests/css-margin-logical-properties.html",
"test_results_url":"https://testi.at/proj/qAmuL03Fg51cE6hkbNSVrXik",
"stats":{"apple-mail":{"macos":{"10.12.6":"n","10.13.6":"n","10.15.7":"y","12.4":"y"},"ios":{"11.4":"n","12":"y","13":"y","14":"y","15":"y"}},"gmail":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"},"mobile-webmail":{"2022-07":"n"}},"orange":{"desktop-webmail":{"2022-07":"u"},"ios":{"2022-07":"u"},"android":{"2022-07":"u"}},"outlook":{"windows":{"2013":"n","2016":"n","2019":"n","2021":"n"},"windows-mail":{"2022-07":"n"},"macos":{"2011":"y","2016":"y","16.80":"n"},"outlook-com":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"}},"samsung-email":{"android":{"10":"y","11":"y"}},"sfr":{"desktop-webmail":{"2022-07":"u"},"ios":{"2022-07":"u"},"android":{"2022-07":"u"}},"thunderbird":{"macos":{"60.3":"u"}},"aol":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"}},"yahoo":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"}},"protonmail":{"desktop-webmail":{"2022-07":"u"},"ios":{"2022-07":"u"},"android":{"2022-07":"u"}},"hey":{"desktop-webmail":{"2022-07":"u"}},"mail-ru":{"desktop-webmail":{"2022-07":"y"}},"fastmail":{"desktop-webmail":{"2022-07":"u"}},"laposte":{"desktop-webmail":{"2022-07":"u"}},"gmx":{"desktop-webmail":{"2022-09":"n"},"ios":{"2022-09":"y"},"android":{"2022-09":"y"}},"web-de":{"desktop-webmail":{"2022-09":"n"},"ios":{"2022-09":"y"},"android":{"2022-09":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-09":"y"},"android":{"2022-09":"y"}}},
"stats":{"apple-mail":{"macos":{"10.12.6":"n","10.13.6":"n","10.15.7":"y","12.4":"y"},"ios":{"11.4":"n","12":"y","13":"y","14":"y","15":"y"}},"gmail":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"},"mobile-webmail":{"2022-07":"n"}},"orange":{"desktop-webmail":{"2022-07":"u"},"ios":{"2022-07":"u"},"android":{"2022-07":"u"}},"outlook":{"windows":{"2013":"n","2016":"n","2019":"n","2021":"n"},"windows-mail":{"2022-07":"n"},"macos":{"2011":"y","2016":"y","16.80":"n"},"outlook-com":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"}},"samsung-email":{"android":{"10":"y","11":"y"}},"sfr":{"desktop-webmail":{"2022-07":"u"},"ios":{"2022-07":"u"},"android":{"2022-07":"u"}},"thunderbird":{"macos":{"60.3":"u"}},"aol":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"}},"yahoo":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"}},"protonmail":{"desktop-webmail":{"2022-07":"y"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"hey":{"desktop-webmail":{"2022-07":"u"}},"mail-ru":{"desktop-webmail":{"2022-07":"y"}},"fastmail":{"desktop-webmail":{"2022-07":"u"}},"laposte":{"desktop-webmail":{"2022-07":"u"}},"gmx":{"desktop-webmail":{"2022-09":"n"},"ios":{"2022-09":"y"},"android":{"2022-09":"y"}},"web-de":{"desktop-webmail":{"2022-09":"n"},"ios":{"2022-09":"y"},"android":{"2022-09":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-09":"y"},"android":{"2022-09":"y"}}},
"notes":null,
"notes_by_num":null
},
@@ -1390,7 +1406,7 @@
"last_test_date":"2022-07-13",
"test_url":"https://www.caniemail.com/tests/css-margin-logical-properties.html",
"test_results_url":"https://testi.at/proj/qAmuL03Fg51cE6hkbNSVrXik",
"stats":{"apple-mail":{"macos":{"10.12.6":"n","10.13.6":"n","10.15.7":"y","12.4":"y"},"ios":{"11.4":"n","12":"y","13":"y","14":"y","15":"y"}},"gmail":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"},"mobile-webmail":{"2022-07":"n"}},"orange":{"desktop-webmail":{"2022-07":"u"},"ios":{"2022-07":"u"},"android":{"2022-07":"u"}},"outlook":{"windows":{"2013":"n","2016":"n","2019":"n","2021":"n"},"windows-mail":{"2022-07":"n"},"macos":{"2011":"y","2016":"y","16.80":"n"},"outlook-com":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"}},"samsung-email":{"android":{"10":"y","11":"y"}},"sfr":{"desktop-webmail":{"2022-07":"u"},"ios":{"2022-07":"u"},"android":{"2022-07":"u"}},"thunderbird":{"macos":{"60.3":"u"}},"aol":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"}},"yahoo":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"}},"protonmail":{"desktop-webmail":{"2022-07":"u"},"ios":{"2022-07":"u"},"android":{"2022-07":"u"}},"hey":{"desktop-webmail":{"2022-07":"u"}},"mail-ru":{"desktop-webmail":{"2022-07":"y"}},"fastmail":{"desktop-webmail":{"2022-07":"u"}},"laposte":{"desktop-webmail":{"2022-07":"u"}},"gmx":{"desktop-webmail":{"2022-09":"n"},"ios":{"2022-09":"y"},"android":{"2022-09":"y"}},"web-de":{"desktop-webmail":{"2022-09":"n"},"ios":{"2022-09":"y"},"android":{"2022-09":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-09":"y"},"android":{"2022-09":"y"}}},
"stats":{"apple-mail":{"macos":{"10.12.6":"n","10.13.6":"n","10.15.7":"y","12.4":"y"},"ios":{"11.4":"n","12":"y","13":"y","14":"y","15":"y"}},"gmail":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"},"mobile-webmail":{"2022-07":"n"}},"orange":{"desktop-webmail":{"2022-07":"u"},"ios":{"2022-07":"u"},"android":{"2022-07":"u"}},"outlook":{"windows":{"2013":"n","2016":"n","2019":"n","2021":"n"},"windows-mail":{"2022-07":"n"},"macos":{"2011":"y","2016":"y","16.80":"n"},"outlook-com":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"}},"samsung-email":{"android":{"10":"y","11":"y"}},"sfr":{"desktop-webmail":{"2022-07":"u"},"ios":{"2022-07":"u"},"android":{"2022-07":"u"}},"thunderbird":{"macos":{"60.3":"u"}},"aol":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"}},"yahoo":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"}},"protonmail":{"desktop-webmail":{"2022-07":"y"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"hey":{"desktop-webmail":{"2022-07":"u"}},"mail-ru":{"desktop-webmail":{"2022-07":"y"}},"fastmail":{"desktop-webmail":{"2022-07":"u"}},"laposte":{"desktop-webmail":{"2022-07":"u"}},"gmx":{"desktop-webmail":{"2022-09":"n"},"ios":{"2022-09":"y"},"android":{"2022-09":"y"}},"web-de":{"desktop-webmail":{"2022-09":"n"},"ios":{"2022-09":"y"},"android":{"2022-09":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-09":"y"},"android":{"2022-09":"y"}}},
"notes":null,
"notes_by_num":null
},
@@ -1438,7 +1454,7 @@
"last_test_date":"2022-09-01",
"test_url":"https://www.caniemail.com/tests/css-max-block-size.html",
"test_results_url":"https://testi.at/proj/1y7SkPH3W7FPg0HwxS9lEiY",
"stats":{"apple-mail":{"macos":{"16":"y","17":"y","18":"y","19":"y","20":"y","21":"y"},"ios":{"11":"y","12":"y","13":"y","14":"y","15":"y"}},"gmail":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-08":"n"},"mobile-webmail":{"2022-07":"u"}},"orange":{"desktop-webmail":{"2022-07":"u"},"ios":{"2022-07":"u"},"android":{"2022-07":"u"}},"outlook":{"windows":{"2007":"n","2010":"n","2013":"n","2016":"n","2019":"n","2021":"n"},"windows-mail":{"2022-07":"n"},"macos":{"2022-07":"y","16.80":"n"},"outlook-com":{"2022-07":"n","2024-01":"n"},"ios":{"2022-07":"y"},"android":{"2022-07":"n"}},"yahoo":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"}},"aol":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"u"},"android":{"2022-07":"u"}},"samsung-email":{"android":{"2022-09":"y"}},"protonmail":{"desktop-webmail":{"2022-07":"u"},"ios":{"2022-07":"u"},"android":{"2022-07":"u"}},"hey":{"desktop-webmail":{"2022-07":"u"}},"mail-ru":{"desktop-webmail":{"2022-07":"y"}},"fastmail":{"desktop-webmail":{"2022-07":"u"}}},
"stats":{"apple-mail":{"macos":{"16":"y","17":"y","18":"y","19":"y","20":"y","21":"y"},"ios":{"11":"y","12":"y","13":"y","14":"y","15":"y"}},"gmail":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-08":"n"},"mobile-webmail":{"2022-07":"u"}},"orange":{"desktop-webmail":{"2022-07":"u"},"ios":{"2022-07":"u"},"android":{"2022-07":"u"}},"outlook":{"windows":{"2007":"n","2010":"n","2013":"n","2016":"n","2019":"n","2021":"n"},"windows-mail":{"2022-07":"n"},"macos":{"2022-07":"y","16.80":"n"},"outlook-com":{"2022-07":"n","2024-01":"n"},"ios":{"2022-07":"y"},"android":{"2022-07":"n"}},"yahoo":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"}},"aol":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"u"},"android":{"2022-07":"u"}},"samsung-email":{"android":{"2022-09":"y"}},"protonmail":{"desktop-webmail":{"2022-07":"y"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"hey":{"desktop-webmail":{"2022-07":"u"}},"mail-ru":{"desktop-webmail":{"2022-07":"y"}},"fastmail":{"desktop-webmail":{"2022-07":"u"}}},
"notes":null,
"notes_by_num":null
},
@@ -1470,7 +1486,7 @@
"last_test_date":"2024-05-31",
"test_url":"https://www.caniemail.com/tests/css-max-inline-size.html",
"test_results_url":"https://testi.at/proj/8r8g0dn81y8jc72z09",
"stats":{"apple-mail":{"macos":{"2024-05":"y"},"ios":{"2024-05":"y"}},"gmail":{"desktop-webmail":{"2024-05":"n"},"ios":{"2024-05":"n"},"android":{"2024-05":"n"},"mobile-webmail":{"2024-05":"n"}},"orange":{"desktop-webmail":{"2024-05":"u"},"ios":{"2024-05":"u"},"android":{"2024-05":"u"}},"outlook":{"windows":{"2013":"n","2016":"n","2019":"n","2021":"n"},"windows-mail":{"2024-05":"n"},"macos":{"2024-05":"n"},"outlook-com":{"2024-05":"n"},"ios":{"2024-05":"n"},"android":{"2024-05":"n"}},"yahoo":{"desktop-webmail":{"2024-05":"n"},"ios":{"2024-05":"n"},"android":{"2024-05":"n"}},"aol":{"desktop-webmail":{"2024-05":"n"},"ios":{"2024-05":"n"},"android":{"2024-05":"n"}},"samsung-email":{"android":{"2024-05":"y"}},"sfr":{"desktop-webmail":{"2024-05":"u"},"ios":{"2024-05":"u"},"android":{"2024-05":"u"}},"protonmail":{"desktop-webmail":{"2024-05":"u"},"ios":{"2024-05":"u"},"android":{"2024-05":"u"}},"hey":{"desktop-webmail":{"2024-05":"u"}},"mail-ru":{"desktop-webmail":{"2024-05":"y"}},"fastmail":{"desktop-webmail":{"2024-05":"u"}},"laposte":{"desktop-webmail":{"2021-08":"u"}},"gmx":{"desktop-webmail":{"2024-05":"n"},"ios":{"2024-05":"u"},"android":{"2024-05":"u"}},"web-de":{"desktop-webmail":{"2024-05":"n"},"ios":{"2024-05":"u"},"android":{"2024-05":"u"}},"ionos-1and1":{"desktop-webmail":{"2024-05":"u"},"android":{"2024-05":"u"}}},
"stats":{"apple-mail":{"macos":{"2024-05":"y"},"ios":{"2024-05":"y"}},"gmail":{"desktop-webmail":{"2024-05":"n"},"ios":{"2024-05":"n"},"android":{"2024-05":"n"},"mobile-webmail":{"2024-05":"n"}},"orange":{"desktop-webmail":{"2024-05":"u"},"ios":{"2024-05":"u"},"android":{"2024-05":"u"}},"outlook":{"windows":{"2013":"n","2016":"n","2019":"n","2021":"n"},"windows-mail":{"2024-05":"n"},"macos":{"2024-05":"n"},"outlook-com":{"2024-05":"n"},"ios":{"2024-05":"n"},"android":{"2024-05":"n"}},"yahoo":{"desktop-webmail":{"2024-05":"n"},"ios":{"2024-05":"n"},"android":{"2024-05":"n"}},"aol":{"desktop-webmail":{"2024-05":"n"},"ios":{"2024-05":"n"},"android":{"2024-05":"n"}},"samsung-email":{"android":{"2024-05":"y"}},"sfr":{"desktop-webmail":{"2024-05":"u"},"ios":{"2024-05":"u"},"android":{"2024-05":"u"}},"protonmail":{"desktop-webmail":{"2024-05":"y"},"ios":{"2024-05":"y"},"android":{"2024-05":"y"}},"hey":{"desktop-webmail":{"2024-05":"u"}},"mail-ru":{"desktop-webmail":{"2024-05":"y"}},"fastmail":{"desktop-webmail":{"2024-05":"u"}},"laposte":{"desktop-webmail":{"2021-08":"u"}},"gmx":{"desktop-webmail":{"2024-05":"n"},"ios":{"2024-05":"u"},"android":{"2024-05":"u"}},"web-de":{"desktop-webmail":{"2024-05":"n"},"ios":{"2024-05":"u"},"android":{"2024-05":"u"}},"ionos-1and1":{"desktop-webmail":{"2024-05":"u"},"android":{"2024-05":"u"}}},
"notes":null,
"notes_by_num":null
},
@@ -1486,7 +1502,7 @@
"last_test_date":"2019-08-02",
"test_url":"https://www.caniemail.com/tests/css-width-height.html",
"test_results_url":"https://app.emailonacid.com/app/acidtest/dP8XNPcCLZGrogYGvFgCRRjJJO2nTWxchQ0WZSu0Pxcyb/list",
"stats":{"apple-mail":{"macos":{"10.3":"y"},"ios":{"5.1":"a #2","6.1":"a #2","10.3":"y","12.2":"y"}},"gmail":{"desktop-webmail":{"2019-08":"y"},"ios":{"2019-08":"y"},"android":{"2019-08":"y"},"mobile-webmail":{"2020-02":"y"}},"orange":{"desktop-webmail":{"2019-08":"y","2021-03":"y"},"ios":{"2019-08":"y"},"android":{"2019-08":"y"}},"outlook":{"windows":{"2003":"a #2","2007":"n","2010":"n","2013":"n","2016":"n","2019":"a #1"},"windows-mail":{"2020-01":"a #1"},"macos":{"2011":"y","2016":"y","16.80":"y"},"outlook-com":{"2019-08":"y","2024-01":"y"},"ios":{"2019-08":"y"},"android":{"2019-08":"y"}},"samsung-email":{"android":{"6.0":"y"}},"sfr":{"desktop-webmail":{"2019-08":"y"},"ios":{"2019-08":"y"},"android":{"2019-08":"y"}},"thunderbird":{"macos":{"60.7":"y"}},"aol":{"desktop-webmail":{"2020-01":"y"},"ios":{"2020-01":"a #2"},"android":{"2020-01":"y"}},"yahoo":{"desktop-webmail":{"2019-08":"y"},"ios":{"2019-08":"a #2"},"android":{"2019-08":"y"}},"protonmail":{"desktop-webmail":{"2020-03":"y"},"ios":{"2020-03":"a #2"},"android":{"2020-03":"y"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"y"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"y"}},"gmx":{"desktop-webmail":{"2022-06":"y"},"ios":{"2022-06":"y"},"android":{"2022-06":"y"}},"web-de":{"desktop-webmail":{"2022-06":"y"},"ios":{"2022-06":"y"},"android":{"2022-06":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-06":"y"},"android":{"2022-06":"y"}}},
"stats":{"apple-mail":{"macos":{"10.3":"y"},"ios":{"5.1":"a #2","6.1":"a #2","10.3":"y","12.2":"y"}},"gmail":{"desktop-webmail":{"2019-08":"y"},"ios":{"2019-08":"y"},"android":{"2019-08":"y"},"mobile-webmail":{"2020-02":"y"}},"orange":{"desktop-webmail":{"2019-08":"y","2021-03":"y"},"ios":{"2019-08":"y"},"android":{"2019-08":"y"}},"outlook":{"windows":{"2003":"a #2","2007":"n","2010":"n","2013":"n","2016":"n","2019":"a #1"},"windows-mail":{"2020-01":"a #1"},"macos":{"2011":"y","2016":"y","16.80":"y"},"outlook-com":{"2019-08":"y","2024-01":"y"},"ios":{"2019-08":"y"},"android":{"2019-08":"y"}},"samsung-email":{"android":{"6.0":"y"}},"sfr":{"desktop-webmail":{"2019-08":"y"},"ios":{"2019-08":"y"},"android":{"2019-08":"y"}},"thunderbird":{"macos":{"60.7":"y"}},"aol":{"desktop-webmail":{"2020-01":"y"},"ios":{"2020-01":"a #2","2025-11":"y"},"android":{"2020-01":"y"}},"yahoo":{"desktop-webmail":{"2019-08":"y"},"ios":{"2019-08":"a #2","2025-11":"y"},"android":{"2019-08":"y"}},"protonmail":{"desktop-webmail":{"2020-03":"y"},"ios":{"2020-03":"a #2","2025-11":"y"},"android":{"2020-03":"y"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"y"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"y"}},"gmx":{"desktop-webmail":{"2022-06":"y"},"ios":{"2022-06":"y"},"android":{"2022-06":"y"}},"web-de":{"desktop-webmail":{"2022-06":"y"},"ios":{"2022-06":"y"},"android":{"2022-06":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-06":"y"},"android":{"2022-06":"y"}}},
"notes":null,
"notes_by_num":{"1":"Partial. Only works on `<table>` elements.","2":"Partial. Doesn't work on `<table>` elements, as per [CSS 2.1 specification](https://www.w3.org/TR/CSS2/visudet.html#min-max-widths)."}
},
@@ -1502,7 +1518,7 @@
"last_test_date":"2024-05-31",
"test_url":"https://www.caniemail.com/tests/css-min-block-size.html",
"test_results_url":"https://testi.at/proj/73yg05zgtpk3cez6ua5",
"stats":{"apple-mail":{"macos":{"2024-05":"y"},"ios":{"2024-05":"y"}},"gmail":{"desktop-webmail":{"2024-05":"n"},"ios":{"2024-05":"n"},"android":{"2024-05":"n"},"mobile-webmail":{"2024-05":"n"}},"orange":{"desktop-webmail":{"2024-05":"u"},"ios":{"2024-05":"u"},"android":{"2024-05":"u"}},"outlook":{"windows":{"2013":"n","2016":"n","2019":"n","2021":"n"},"windows-mail":{"2024-05":"n"},"macos":{"2024-05":"n"},"outlook-com":{"2024-05":"n"},"ios":{"2024-05":"n"},"android":{"2024-05":"n"}},"yahoo":{"desktop-webmail":{"2024-05":"n"},"ios":{"2024-05":"n"},"android":{"2024-05":"n"}},"aol":{"desktop-webmail":{"2024-05":"n"},"ios":{"2024-05":"n"},"android":{"2024-05":"n"}},"samsung-email":{"android":{"2024-05":"y"}},"sfr":{"desktop-webmail":{"2024-05":"u"},"ios":{"2024-05":"u"},"android":{"2024-05":"u"}},"protonmail":{"desktop-webmail":{"2024-05":"u"},"ios":{"2024-05":"u"},"android":{"2024-05":"u"}},"hey":{"desktop-webmail":{"2024-05":"u"}},"mail-ru":{"desktop-webmail":{"2024-05":"y"}},"fastmail":{"desktop-webmail":{"2024-05":"u"}},"laposte":{"desktop-webmail":{"2021-08":"u"}},"gmx":{"desktop-webmail":{"2024-05":"n"},"ios":{"2024-05":"u"},"android":{"2024-05":"u"}},"web-de":{"desktop-webmail":{"2024-05":"n"},"ios":{"2024-05":"u"},"android":{"2024-05":"u"}},"ionos-1and1":{"desktop-webmail":{"2024-05":"u"},"android":{"2024-05":"u"}}},
"stats":{"apple-mail":{"macos":{"2024-05":"y"},"ios":{"2024-05":"y"}},"gmail":{"desktop-webmail":{"2024-05":"n"},"ios":{"2024-05":"n"},"android":{"2024-05":"n"},"mobile-webmail":{"2024-05":"n"}},"orange":{"desktop-webmail":{"2024-05":"u"},"ios":{"2024-05":"u"},"android":{"2024-05":"u"}},"outlook":{"windows":{"2013":"n","2016":"n","2019":"n","2021":"n"},"windows-mail":{"2024-05":"n"},"macos":{"2024-05":"n"},"outlook-com":{"2024-05":"n"},"ios":{"2024-05":"n"},"android":{"2024-05":"n"}},"yahoo":{"desktop-webmail":{"2024-05":"n"},"ios":{"2024-05":"n"},"android":{"2024-05":"n"}},"aol":{"desktop-webmail":{"2024-05":"n"},"ios":{"2024-05":"n"},"android":{"2024-05":"n"}},"samsung-email":{"android":{"2024-05":"y"}},"sfr":{"desktop-webmail":{"2024-05":"u"},"ios":{"2024-05":"u"},"android":{"2024-05":"u"}},"protonmail":{"desktop-webmail":{"2024-05":"y"},"ios":{"2024-05":"y"},"android":{"2024-05":"y"}},"hey":{"desktop-webmail":{"2024-05":"u"}},"mail-ru":{"desktop-webmail":{"2024-05":"y"}},"fastmail":{"desktop-webmail":{"2024-05":"u"}},"laposte":{"desktop-webmail":{"2021-08":"u"}},"gmx":{"desktop-webmail":{"2024-05":"n"},"ios":{"2024-05":"u"},"android":{"2024-05":"u"}},"web-de":{"desktop-webmail":{"2024-05":"n"},"ios":{"2024-05":"u"},"android":{"2024-05":"u"}},"ionos-1and1":{"desktop-webmail":{"2024-05":"u"},"android":{"2024-05":"u"}}},
"notes":null,
"notes_by_num":null
},
@@ -1534,7 +1550,7 @@
"last_test_date":"2022-08-30",
"test_url":"https://www.caniemail.com/tests/css-min-inline-size.html",
"test_results_url":"https://testi.at/proj/6m0cx5puENPh8pLi9rpSPzJSB",
"stats":{"apple-mail":{"macos":{"16":"y","17":"y","18":"y","19":"y","20":"y","21":"y"},"ios":{"11":"y","12":"y","13":"y","14":"y","15":"y"}},"gmail":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-08":"n"},"mobile-webmail":{"2022-07":"n"}},"orange":{"desktop-webmail":{"2022-07":"u"},"ios":{"2022-07":"u"},"android":{"2022-07":"u"}},"outlook":{"windows":{"2007":"n","2010":"n","2013":"n","2016":"n","2019":"n","2021":"n"},"windows-mail":{"2022-07":"n"},"macos":{"2022-07":"y","16.80":"n"},"outlook-com":{"2022-07":"n","2024-01":"n"},"ios":{"2022-07":"y"},"android":{"2022-07":"n"}},"yahoo":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"}},"aol":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"u"},"android":{"2022-07":"u"}},"samsung-email":{"android":{"2022-07":"y"}},"sfr":{"desktop-webmail":{"2022-07":"u"},"ios":{"2022-07":"u"},"android":{"2022-07":"u"}},"protonmail":{"desktop-webmail":{"2022-07":"u"},"ios":{"2022-07":"u"},"android":{"2022-07":"u"}},"hey":{"desktop-webmail":{"2022-07":"u"}},"mail-ru":{"desktop-webmail":{"2022-07":"y"}},"fastmail":{"desktop-webmail":{"2022-07":"u"}}},
"stats":{"apple-mail":{"macos":{"16":"y","17":"y","18":"y","19":"y","20":"y","21":"y"},"ios":{"11":"y","12":"y","13":"y","14":"y","15":"y"}},"gmail":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-08":"n"},"mobile-webmail":{"2022-07":"n"}},"orange":{"desktop-webmail":{"2022-07":"u"},"ios":{"2022-07":"u"},"android":{"2022-07":"u"}},"outlook":{"windows":{"2007":"n","2010":"n","2013":"n","2016":"n","2019":"n","2021":"n"},"windows-mail":{"2022-07":"n"},"macos":{"2022-07":"y","16.80":"n"},"outlook-com":{"2022-07":"n","2024-01":"n"},"ios":{"2022-07":"y"},"android":{"2022-07":"n"}},"yahoo":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"}},"aol":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"u"},"android":{"2022-07":"u"}},"samsung-email":{"android":{"2022-07":"y"}},"sfr":{"desktop-webmail":{"2022-07":"u"},"ios":{"2022-07":"u"},"android":{"2022-07":"u"}},"protonmail":{"desktop-webmail":{"2022-07":"y"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"hey":{"desktop-webmail":{"2022-07":"u"}},"mail-ru":{"desktop-webmail":{"2022-07":"y"}},"fastmail":{"desktop-webmail":{"2022-07":"u"}}},
"notes":null,
"notes_by_num":null
},
@@ -1646,7 +1662,7 @@
"last_test_date":"2019-02-28",
"test_url":"https://www.caniemail.com/tests/css-visual-effects.html",
"test_results_url":"https://app.emailonacid.com/app/acidtest/DhTRmGsVH6uobU4pHD3CasJywfBL4HnEjA1LOF8f9ctso/list",
"stats":{"apple-mail":{"macos":{"12.4":"y"},"ios":{"12.1":"y"}},"gmail":{"desktop-webmail":{"2019-02":"y"},"ios":{"2019-02":"y"},"android":{"2019-02":"y"},"mobile-webmail":{"2020-02":"n"}},"orange":{"desktop-webmail":{"2019-08":"y","2021-03":"n","2024-04":"n"},"ios":{"2019-08":"y","2024-04":"n"},"android":{"2019-08":"y","2024-04":"n"}},"outlook":{"windows":{"2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"windows-mail":{"2019-02":"n"},"macos":{"2019-02":"y","16.80":"y"},"outlook-com":{"2019-02":"y","2024-01":"y"},"ios":{"2019-02":"y"},"android":{"2019-02":"y"}},"thunderbird":{"macos":{"60.8":"y"}},"yahoo":{"desktop-webmail":{"2019-02":"n"},"ios":{"2019-02":"n"},"android":{"2019-02":"n"}},"aol":{"desktop-webmail":{"2019-02":"n"},"ios":{"2019-02":"n"},"android":{"2019-02":"n"}},"samsung-email":{"android":{"5.0.10.2":"y"}},"sfr":{"desktop-webmail":{"2019-08":"y"},"ios":{"2019-08":"y"},"android":{"2019-08":"y"}},"protonmail":{"desktop-webmail":{"2020-03":"y"},"ios":{"2020-03":"y"},"android":{"2020-03":"y"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"n"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"y"}},"gmx":{"desktop-webmail":{"2022-06":"n"},"ios":{"2022-06":"y"},"android":{"2022-06":"y"}},"web-de":{"desktop-webmail":{"2022-06":"n"},"ios":{"2022-06":"y"},"android":{"2022-06":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-06":"y"},"android":{"2022-06":"y"}}},
"stats":{"apple-mail":{"macos":{"12.4":"y"},"ios":{"12.1":"y"}},"gmail":{"desktop-webmail":{"2019-02":"y"},"ios":{"2019-02":"y"},"android":{"2019-02":"y"},"mobile-webmail":{"2020-02":"n"}},"orange":{"desktop-webmail":{"2019-08":"y","2021-03":"n","2024-04":"n"},"ios":{"2019-08":"y","2024-04":"n"},"android":{"2019-08":"y","2024-04":"n"}},"outlook":{"windows":{"2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"windows-mail":{"2019-02":"n"},"macos":{"2019-02":"y","16.80":"y"},"outlook-com":{"2019-02":"y","2024-01":"y"},"ios":{"2019-02":"y"},"android":{"2019-02":"y"}},"thunderbird":{"macos":{"60.8":"y"}},"yahoo":{"desktop-webmail":{"2019-02":"n","2025-06":"y"},"ios":{"2019-02":"n","2025-06":"y"},"android":{"2019-02":"n","2025-06":"y"}},"aol":{"desktop-webmail":{"2019-02":"n"},"ios":{"2019-02":"n"},"android":{"2019-02":"n"}},"samsung-email":{"android":{"5.0.10.2":"y"}},"sfr":{"desktop-webmail":{"2019-08":"y"},"ios":{"2019-08":"y"},"android":{"2019-08":"y"}},"protonmail":{"desktop-webmail":{"2020-03":"y"},"ios":{"2020-03":"y"},"android":{"2020-03":"y"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"n"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"y"}},"gmx":{"desktop-webmail":{"2022-06":"n"},"ios":{"2022-06":"y"},"android":{"2022-06":"y"}},"web-de":{"desktop-webmail":{"2022-06":"n"},"ios":{"2022-06":"y"},"android":{"2022-06":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-06":"y"},"android":{"2022-06":"y"}}},
"notes":null,
"notes_by_num":null
},
@@ -1723,10 +1739,10 @@
"category":"css",
"tags":[],
"keywords":"overflow-block, overflow-inline",
"last_test_date":"2024-10-02",
"last_test_date":"2025-05-27",
"test_url":"https://www.caniemail.com/tests/css-box-model.html",
"test_results_url":"https://testi.at/proj/p4rru3ez069p15p6ij",
"stats":{"apple-mail":{"macos":{"12.4":"a #1","2024-10":"a #4"},"ios":{"12.1":"y","2024-10":"a #4"}},"gmail":{"desktop-webmail":{"2019-02":"y","2024-10":"a #4"},"ios":{"2019-02":"y","2024-10":"a #4"},"android":{"2019-02":"y","2024-10":"a #4"},"mobile-webmail":{"2020-02":"y","2024-10":"a #4"}},"orange":{"desktop-webmail":{"2019-08":"n #2","2021-03":"y","2024-10":"a #3"},"ios":{"2019-08":"y"},"android":{"2019-08":"y"}},"outlook":{"windows":{"2013":"n","2016":"n","2019":"n","2021":"n"},"windows-mail":{"2019-02":"n"},"macos":{"2019-02":"y","16.80":"y","2024-10":"a #4"},"outlook-com":{"2019-02":"y","2024-01":"y","2024-10":"a #3"},"ios":{"2019-02":"y","2024-10":"a #4"},"android":{"2019-02":"n"}},"yahoo":{"desktop-webmail":{"2019-02":"y"},"ios":{"2019-02":"y","2024-10":"a #4"},"android":{"2019-02":"n"}},"aol":{"desktop-webmail":{"2019-02":"y","2024-10":"a #4"},"ios":{"2019-02":"y","2024-10":"a #4"},"android":{"2019-02":"n"}},"samsung-email":{"android":{"5.0.10.2":"y","2024-10":"a #4"}},"sfr":{"desktop-webmail":{"2019-08":"y"},"ios":{"2019-08":"y"},"android":{"2019-08":"y"}},"thunderbird":{"macos":{"60.5":"y"}},"protonmail":{"desktop-webmail":{"2020-03":"y"},"ios":{"2020-03":"y"},"android":{"2020-03":"y"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"y","2024-10":"a #3"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"y"}},"gmx":{"desktop-webmail":{"2022-06":"y","2024-10":"a #3"},"ios":{"2022-06":"y","2024-10":"a #3"},"android":{"2022-06":"y","2024-10":"a #3"}},"web-de":{"desktop-webmail":{"2022-06":"y","2024-10":"a #3"},"ios":{"2022-06":"y","2024-10":"a #3"},"android":{"2022-06":"y","2024-10":"a #3"}},"ionos-1and1":{"desktop-webmail":{"2022-06":"y"},"android":{"2022-06":"y"}}},
"test_results_url":"https://testi.at/proj/278gsp8afyl8f6nbu4",
"stats":{"apple-mail":{"macos":{"12.4":"a #1","2024-10":"a #4"},"ios":{"12.1":"y","2024-10":"a #4"}},"gmail":{"desktop-webmail":{"2019-02":"y","2024-10":"a #4"},"ios":{"2019-02":"y","2024-10":"a #4"},"android":{"2019-02":"y","2024-10":"a #4","2025-07":"a #1 #4"},"mobile-webmail":{"2020-02":"y","2024-10":"a #4"}},"orange":{"desktop-webmail":{"2019-08":"n #2","2021-03":"y","2024-10":"a #3"},"ios":{"2019-08":"y"},"android":{"2019-08":"y"}},"outlook":{"windows":{"2013":"n","2016":"n","2019":"n","2021":"n","2024":"n"},"windows-mail":{"2019-02":"n"},"macos":{"2019-02":"y","16.80":"y","2024-10":"a #4"},"outlook-com":{"2019-02":"y","2024-01":"y","2024-10":"a #3","2025-05":"a #4"},"ios":{"2019-02":"y","2024-10":"a #4"},"android":{"2019-02":"n","2025-05":"a #1 #4"}},"yahoo":{"desktop-webmail":{"2019-02":"y","2025-05":"a #4"},"ios":{"2019-02":"y","2024-10":"a #4"},"android":{"2019-02":"n","2025-05":"a #1 #4"}},"aol":{"desktop-webmail":{"2019-02":"y","2024-10":"a #4"},"ios":{"2019-02":"y","2024-10":"a #4"},"android":{"2019-02":"n","2025-07":"a #1 #4"}},"samsung-email":{"android":{"5.0.10.2":"y","2024-10":"a #4"}},"sfr":{"desktop-webmail":{"2019-08":"y"},"ios":{"2019-08":"y"},"android":{"2019-08":"y"}},"thunderbird":{"macos":{"60.5":"y","138":"y"}},"protonmail":{"desktop-webmail":{"2020-03":"y","2025-07":"a #3"},"ios":{"2020-03":"y","2025-07":"a #3"},"android":{"2020-03":"y","2025-07":"a #1 #3"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"y","2024-10":"a #3"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"y"}},"gmx":{"desktop-webmail":{"2022-06":"y","2024-10":"a #3"},"ios":{"2022-06":"y","2024-10":"a #3"},"android":{"2022-06":"y","2024-10":"a #3","2025-07":"a #1 #3"}},"web-de":{"desktop-webmail":{"2022-06":"y","2024-10":"a #3"},"ios":{"2022-06":"y","2024-10":"a #3"},"android":{"2022-06":"y","2024-10":"a #3"}},"ionos-1and1":{"desktop-webmail":{"2022-06":"y"},"android":{"2022-06":"y"}}},
"notes":null,
"notes_by_num":{"1":"Buggy. Cannot scroll through to hidden content.","2":"Not supported. `overflow` is replaced by `java-script`.","3":"Partial. Support for `overflow-block` & `overflow-inline` depends on browser support.","4":"Partial. `overflow-block` & `overflow-inline` not supported."}
},
@@ -1742,7 +1758,7 @@
"last_test_date":"2022-07-13",
"test_url":"https://www.caniemail.com/tests/css-padding-logical-properties.html",
"test_results_url":"https://testi.at/proj/Y91uDXJIDLc6M0FkVXipW",
"stats":{"apple-mail":{"macos":{"10.12.6":"n","10.13.6":"n","10.15.7":"y","12.4":"y"},"ios":{"11.4":"n","12":"y","13":"y","14":"y","15":"y"}},"gmail":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"},"mobile-webmail":{"2022-07":"n"}},"orange":{"desktop-webmail":{"2022-07":"u"},"ios":{"2022-07":"u"},"android":{"2022-07":"u"}},"outlook":{"windows":{"2013":"n","2016":"n","2019":"n","2021":"n"},"windows-mail":{"2022-07":"n"},"macos":{"2011":"y","2016":"y","16.80":"n"},"outlook-com":{"2022-07":"n","2024-01":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"}},"samsung-email":{"android":{"10":"y","11":"y"}},"sfr":{"desktop-webmail":{"2022-07":"u"},"ios":{"2022-07":"u"},"android":{"2022-07":"u"}},"thunderbird":{"macos":{"60.3":"u"}},"aol":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"}},"yahoo":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"}},"protonmail":{"desktop-webmail":{"2022-07":"u"},"ios":{"2022-07":"u"},"android":{"2022-07":"u"}},"hey":{"desktop-webmail":{"2022-07":"u"}},"mail-ru":{"desktop-webmail":{"2022-07":"y"}},"fastmail":{"desktop-webmail":{"2022-07":"u"}},"laposte":{"desktop-webmail":{"2022-07":"u"}},"gmx":{"desktop-webmail":{"2022-09":"n"},"ios":{"2022-09":"y"},"android":{"2022-09":"y"}},"web-de":{"desktop-webmail":{"2022-09":"n"},"ios":{"2022-09":"y"},"android":{"2022-09":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-09":"y"},"android":{"2022-09":"y"}}},
"stats":{"apple-mail":{"macos":{"10.12.6":"n","10.13.6":"n","10.15.7":"y","12.4":"y"},"ios":{"11.4":"n","12":"y","13":"y","14":"y","15":"y"}},"gmail":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"},"mobile-webmail":{"2022-07":"n"}},"orange":{"desktop-webmail":{"2022-07":"u"},"ios":{"2022-07":"u"},"android":{"2022-07":"u"}},"outlook":{"windows":{"2013":"n","2016":"n","2019":"n","2021":"n"},"windows-mail":{"2022-07":"n"},"macos":{"2011":"y","2016":"y","16.80":"n"},"outlook-com":{"2022-07":"n","2024-01":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"}},"samsung-email":{"android":{"10":"y","11":"y"}},"sfr":{"desktop-webmail":{"2022-07":"u"},"ios":{"2022-07":"u"},"android":{"2022-07":"u"}},"thunderbird":{"macos":{"60.3":"u"}},"aol":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"}},"yahoo":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"}},"protonmail":{"desktop-webmail":{"2022-07":"y"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"hey":{"desktop-webmail":{"2022-07":"u"}},"mail-ru":{"desktop-webmail":{"2022-07":"y"}},"fastmail":{"desktop-webmail":{"2022-07":"u"}},"laposte":{"desktop-webmail":{"2022-07":"u"}},"gmx":{"desktop-webmail":{"2022-09":"n"},"ios":{"2022-09":"y"},"android":{"2022-09":"y"}},"web-de":{"desktop-webmail":{"2022-09":"n"},"ios":{"2022-09":"y"},"android":{"2022-09":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-09":"y"},"android":{"2022-09":"y"}}},
"notes":null,
"notes_by_num":null
},
@@ -1758,7 +1774,7 @@
"last_test_date":"2022-07-13",
"test_url":"https://www.caniemail.com/tests/css-padding-logical-properties.html",
"test_results_url":"https://testi.at/proj/Y91uDXJIDLc6M0FkVXipW",
"stats":{"apple-mail":{"macos":{"10.12.6":"n","10.13.6":"n","10.15.7":"n","12.4":"y"},"ios":{"11.4":"n","12":"n","13":"n","14":"n","15":"y"}},"gmail":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"},"mobile-webmail":{"2022-07":"n"}},"orange":{"desktop-webmail":{"2022-07":"u"},"ios":{"2022-07":"u"},"android":{"2022-07":"u"}},"outlook":{"windows":{"2013":"n","2016":"n","2019":"n","2021":"n"},"windows-mail":{"2022-07":"n"},"macos":{"2011":"n","2016":"n","16.80":"n"},"outlook-com":{"2022-07":"n","2024-01":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"}},"samsung-email":{"android":{"10":"n","11":"n"}},"sfr":{"desktop-webmail":{"2022-07":"u"},"ios":{"2022-07":"u"},"android":{"2022-07":"u"}},"thunderbird":{"macos":{"60.3":"u"}},"aol":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"}},"yahoo":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"}},"protonmail":{"desktop-webmail":{"2022-07":"u"},"ios":{"2022-07":"u"},"android":{"2022-07":"u"}},"hey":{"desktop-webmail":{"2022-07":"u"}},"mail-ru":{"desktop-webmail":{"2022-07":"y"}},"fastmail":{"desktop-webmail":{"2022-07":"u"}},"laposte":{"desktop-webmail":{"2022-07":"u"}},"gmx":{"desktop-webmail":{"2022-09":"n"},"ios":{"2022-09":"y"},"android":{"2022-09":"y"}},"web-de":{"desktop-webmail":{"2022-09":"n"},"ios":{"2022-09":"y"},"android":{"2022-09":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-09":"y"},"android":{"2022-09":"y"}}},
"stats":{"apple-mail":{"macos":{"10.12.6":"n","10.13.6":"n","10.15.7":"n","12.4":"y"},"ios":{"11.4":"n","12":"n","13":"n","14":"n","15":"y"}},"gmail":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"},"mobile-webmail":{"2022-07":"n"}},"orange":{"desktop-webmail":{"2022-07":"u"},"ios":{"2022-07":"u"},"android":{"2022-07":"u"}},"outlook":{"windows":{"2013":"n","2016":"n","2019":"n","2021":"n"},"windows-mail":{"2022-07":"n"},"macos":{"2011":"n","2016":"n","16.80":"n"},"outlook-com":{"2022-07":"n","2024-01":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"}},"samsung-email":{"android":{"10":"n","11":"n"}},"sfr":{"desktop-webmail":{"2022-07":"u"},"ios":{"2022-07":"u"},"android":{"2022-07":"u"}},"thunderbird":{"macos":{"60.3":"u"}},"aol":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"}},"yahoo":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"}},"protonmail":{"desktop-webmail":{"2022-07":"y"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"hey":{"desktop-webmail":{"2022-07":"u"}},"mail-ru":{"desktop-webmail":{"2022-07":"y"}},"fastmail":{"desktop-webmail":{"2022-07":"u"}},"laposte":{"desktop-webmail":{"2022-07":"u"}},"gmx":{"desktop-webmail":{"2022-09":"n"},"ios":{"2022-09":"y"},"android":{"2022-09":"y"}},"web-de":{"desktop-webmail":{"2022-09":"n"},"ios":{"2022-09":"y"},"android":{"2022-09":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-09":"y"},"android":{"2022-09":"y"}}},
"notes":null,
"notes_by_num":null
},
@@ -1774,7 +1790,7 @@
"last_test_date":"2022-07-13",
"test_url":"https://www.caniemail.com/tests/css-padding-logical-properties.html",
"test_results_url":"https://testi.at/proj/Y91uDXJIDLc6M0FkVXipW",
"stats":{"apple-mail":{"macos":{"10.12.6":"n","10.13.6":"n","10.15.7":"y","12.4":"y"},"ios":{"11.4":"n","12":"y","13":"y","14":"y","15":"y"}},"gmail":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"},"mobile-webmail":{"2022-07":"n"}},"orange":{"desktop-webmail":{"2022-07":"u"},"ios":{"2022-07":"u"},"android":{"2022-07":"u"}},"outlook":{"windows":{"2013":"n","2016":"n","2019":"n","2021":"n"},"windows-mail":{"2022-07":"n"},"macos":{"2011":"y","2016":"y","16.80":"n"},"outlook-com":{"2022-07":"n","2024-01":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"}},"samsung-email":{"android":{"10":"y","11":"y"}},"sfr":{"desktop-webmail":{"2022-07":"u"},"ios":{"2022-07":"u"},"android":{"2022-07":"u"}},"thunderbird":{"macos":{"60.3":"u"}},"aol":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"}},"yahoo":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"}},"protonmail":{"desktop-webmail":{"2022-07":"u"},"ios":{"2022-07":"u"},"android":{"2022-07":"u"}},"hey":{"desktop-webmail":{"2022-07":"u"}},"mail-ru":{"desktop-webmail":{"2022-07":"y"}},"fastmail":{"desktop-webmail":{"2022-07":"u"}},"laposte":{"desktop-webmail":{"2022-07":"u"}},"gmx":{"desktop-webmail":{"2022-09":"n"},"ios":{"2022-09":"y"},"android":{"2022-09":"y"}},"web-de":{"desktop-webmail":{"2022-09":"n"},"ios":{"2022-09":"y"},"android":{"2022-09":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-09":"y"},"android":{"2022-09":"y"}}},
"stats":{"apple-mail":{"macos":{"10.12.6":"n","10.13.6":"n","10.15.7":"y","12.4":"y"},"ios":{"11.4":"n","12":"y","13":"y","14":"y","15":"y"}},"gmail":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"},"mobile-webmail":{"2022-07":"n"}},"orange":{"desktop-webmail":{"2022-07":"u"},"ios":{"2022-07":"u"},"android":{"2022-07":"u"}},"outlook":{"windows":{"2013":"n","2016":"n","2019":"n","2021":"n"},"windows-mail":{"2022-07":"n"},"macos":{"2011":"y","2016":"y","16.80":"n"},"outlook-com":{"2022-07":"n","2024-01":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"}},"samsung-email":{"android":{"10":"y","11":"y"}},"sfr":{"desktop-webmail":{"2022-07":"u"},"ios":{"2022-07":"u"},"android":{"2022-07":"u"}},"thunderbird":{"macos":{"60.3":"u"}},"aol":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"}},"yahoo":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"}},"protonmail":{"desktop-webmail":{"2022-07":"y"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"hey":{"desktop-webmail":{"2022-07":"u"}},"mail-ru":{"desktop-webmail":{"2022-07":"y"}},"fastmail":{"desktop-webmail":{"2022-07":"u"}},"laposte":{"desktop-webmail":{"2022-07":"u"}},"gmx":{"desktop-webmail":{"2022-09":"n"},"ios":{"2022-09":"y"},"android":{"2022-09":"y"}},"web-de":{"desktop-webmail":{"2022-09":"n"},"ios":{"2022-09":"y"},"android":{"2022-09":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-09":"y"},"android":{"2022-09":"y"}}},
"notes":null,
"notes_by_num":null
},
@@ -1822,7 +1838,7 @@
"last_test_date":"2019-10-28",
"test_url":"https://www.caniemail.com/tests/css-selectors-pseudo-classes.html",
"test_results_url":"https://app.emailonacid.com/app/acidtest/cl8ZYgIGE372fkVVuJkwNJDd7B4JUpo23Nz6qANcSlRUA/list",
"stats":{"apple-mail":{"macos":{"12.4":"n","16":"a #2"},"ios":{"13.1":"n"}},"gmail":{"desktop-webmail":{"2019-10":"n"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"},"mobile-webmail":{"2020-02":"n"}},"orange":{"desktop-webmail":{"2019-10":"y","2021-03":"y"},"ios":{"2019-10":"n"},"android":{"2019-10":"y"}},"outlook":{"windows":{"2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"windows-mail":{"2019-10":"n"},"macos":{"2019-02":"y","16.80":"a #1"},"outlook-com":{"2019-10":"a #1","2024-01":"a #1"},"ios":{"2019-10":"n"},"android":{"2019-10":"y"}},"thunderbird":{"macos":{"60.8":"y"}},"yahoo":{"desktop-webmail":{"2019-02":"y"},"ios":{"2019-02":"y"},"android":{"2019-02":"y"}},"aol":{"desktop-webmail":{"2019-02":"y"},"ios":{"2019-02":"n"},"android":{"2019-02":"y"}},"samsung-email":{"android":{"6.0.04.6":"n"}},"sfr":{"desktop-webmail":{"2020-01":"y"},"ios":{"2020-01":"n"},"android":{"2020-01":"n"}},"protonmail":{"desktop-webmail":{"2020-03":"n"},"ios":{"2020-03":"n"},"android":{"2020-03":"y"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"n"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"y"}},"gmx":{"desktop-webmail":{"2022-07":"y"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"web-de":{"desktop-webmail":{"2022-07":"y"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-07":"y"},"android":{"2022-07":"y"}}},
"stats":{"apple-mail":{"macos":{"12.4":"n","16":"a #2"},"ios":{"13.1":"n"}},"gmail":{"desktop-webmail":{"2019-10":"n"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"},"mobile-webmail":{"2020-02":"n"}},"orange":{"desktop-webmail":{"2019-10":"y","2021-03":"y"},"ios":{"2019-10":"n"},"android":{"2019-10":"y"}},"outlook":{"windows":{"2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"windows-mail":{"2019-10":"n"},"macos":{"2019-02":"y","16.80":"a #1"},"outlook-com":{"2019-10":"a #1","2024-01":"a #1"},"ios":{"2019-10":"n"},"android":{"2019-10":"y"}},"thunderbird":{"macos":{"60.8":"y"}},"yahoo":{"desktop-webmail":{"2019-02":"y"},"ios":{"2019-02":"y"},"android":{"2019-02":"y"}},"aol":{"desktop-webmail":{"2019-02":"y"},"ios":{"2019-02":"n"},"android":{"2019-02":"y"}},"samsung-email":{"android":{"6.0.04.6":"n"}},"sfr":{"desktop-webmail":{"2020-01":"y","2025-07":"n"},"ios":{"2020-01":"n"},"android":{"2020-01":"n"}},"protonmail":{"desktop-webmail":{"2020-03":"y"},"ios":{"2020-03":"y"},"android":{"2020-03":"y"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"n"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"y","2025-07":"n"}},"gmx":{"desktop-webmail":{"2022-07":"y"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"web-de":{"desktop-webmail":{"2022-07":"y"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-07":"y"},"android":{"2022-07":"y"}}},
"notes":null,
"notes_by_num":{"1":"Partial. Only supported on type selectors.","2":"Partial. Supported with mouse clicks. Not supported with keyboard input."}
},
@@ -1838,7 +1854,7 @@
"last_test_date":"2020-03-10",
"test_url":"https://www.caniemail.com/tests/css-selectors-pseudo-classes.html",
"test_results_url":"https://app.emailonacid.com/app/acidtest/jRZRnTXxdqCwNM60saxYK4Ee7783SAj1qQKytJlOoB7dO/list",
"stats":{"apple-mail":{"macos":{"12.4":"y"},"ios":{"13.3":"y"}},"gmail":{"desktop-webmail":{"2020-03":"n"},"ios":{"2020-03":"n"},"android":{"2020-03":"n"},"mobile-webmail":{"2020-03":"n"}},"orange":{"desktop-webmail":{"2020-03":"n #2","2021-03":"n #2"},"ios":{"2020-03":"n #2"},"android":{"2020-03":"n #2"}},"outlook":{"windows":{"2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"windows-mail":{"2020-03":"n"},"macos":{"2011":"y","2016":"y","16.80":"a #1"},"outlook-com":{"2020-03":"a #1","2024-01":"a #1"},"ios":{"2020-03":"a #1"},"android":{"2020-03":"a #1"}},"samsung-email":{"android":{"7.0":"y"}},"sfr":{"desktop-webmail":{"2020-03":"n #2"},"ios":{"2020-03":"n"},"android":{"2020-03":"n"}},"thunderbird":{"macos":{"68.5":"y"}},"aol":{"desktop-webmail":{"2020-03":"y"},"ios":{"2020-03":"y"},"android":{"2020-03":"y"}},"yahoo":{"desktop-webmail":{"2020-03":"y"},"ios":{"2020-03":"y"},"android":{"2020-03":"y"}},"protonmail":{"desktop-webmail":{"2020-03":"n"},"ios":{"2020-03":"n"},"android":{"2020-03":"n"}},"hey":{"desktop-webmail":{"2020-06":"n"}},"mail-ru":{"desktop-webmail":{"2020-10":"n"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"n #2"}},"gmx":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"y"},"android":{"2022-07":"n"}},"web-de":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"y"},"android":{"2022-07":"n"}},"ionos-1and1":{"desktop-webmail":{"2022-07":"n"},"android":{"2022-07":"n"}}},
"stats":{"apple-mail":{"macos":{"12.4":"y"},"ios":{"13.3":"y"}},"gmail":{"desktop-webmail":{"2020-03":"n"},"ios":{"2020-03":"n"},"android":{"2020-03":"n"},"mobile-webmail":{"2020-03":"n"}},"orange":{"desktop-webmail":{"2020-03":"n #2","2021-03":"n #2"},"ios":{"2020-03":"n #2"},"android":{"2020-03":"n #2"}},"outlook":{"windows":{"2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"windows-mail":{"2020-03":"n"},"macos":{"2011":"y","2016":"y","16.80":"a #1"},"outlook-com":{"2020-03":"a #1","2024-01":"a #1"},"ios":{"2020-03":"a #1"},"android":{"2020-03":"a #1"}},"samsung-email":{"android":{"7.0":"y"}},"sfr":{"desktop-webmail":{"2020-03":"n #2","2025-07":"n"},"ios":{"2020-03":"n"},"android":{"2020-03":"n"}},"thunderbird":{"macos":{"68.5":"y"}},"aol":{"desktop-webmail":{"2020-03":"y"},"ios":{"2020-03":"y"},"android":{"2020-03":"y"}},"yahoo":{"desktop-webmail":{"2020-03":"y"},"ios":{"2020-03":"y"},"android":{"2020-03":"y"}},"protonmail":{"desktop-webmail":{"2020-03":"n"},"ios":{"2020-03":"n"},"android":{"2020-03":"n"}},"hey":{"desktop-webmail":{"2020-06":"n"}},"mail-ru":{"desktop-webmail":{"2020-10":"n"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"n #2","2025-07":"n"}},"gmx":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"y"},"android":{"2022-07":"n"}},"web-de":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"y"},"android":{"2022-07":"n"}},"ionos-1and1":{"desktop-webmail":{"2022-07":"n"},"android":{"2022-07":"n"}}},
"notes":null,
"notes_by_num":{"1":"Partial. Only supported on type selectors.","2":"Not supported. `<input>` elements are transformed into `<noinput>`."}
},
@@ -1854,7 +1870,7 @@
"last_test_date":"2019-10-16",
"test_url":"https://www.caniemail.com/tests/css-selectors-pseudo-classes.html",
"test_results_url":"https://app.emailonacid.com/app/acidtest/cl8ZYgIGE372fkVVuJkwNJDd7B4JUpo23Nz6qANcSlRUA/list",
"stats":{"apple-mail":{"macos":{"12.4":"y"},"ios":{"13.1":"y"}},"gmail":{"desktop-webmail":{"2019-10":"n"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"},"mobile-webmail":{"2020-02":"n"}},"orange":{"desktop-webmail":{"2019-10":"y","2021-03":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"outlook":{"windows":{"2003":"y","2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"windows-mail":{"2019-10":"n"},"macos":{"2011":"y","2016":"y","16.80":"a #1"},"outlook-com":{"2019-10":"a #1","2024-01":"a #1"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"samsung-email":{"android":{"6.0":"y"}},"sfr":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"}},"thunderbird":{"macos":{"60.3":"y"}},"aol":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"yahoo":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"protonmail":{"desktop-webmail":{"2020-03":"n"},"ios":{"2020-03":"n"},"android":{"2020-03":"y"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"n"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"y"}},"gmx":{"desktop-webmail":{"2022-07":"y"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"web-de":{"desktop-webmail":{"2022-07":"y"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-07":"y"},"android":{"2022-07":"y"}}},
"stats":{"apple-mail":{"macos":{"12.4":"y"},"ios":{"13.1":"y"}},"gmail":{"desktop-webmail":{"2019-10":"n"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"},"mobile-webmail":{"2020-02":"n"}},"orange":{"desktop-webmail":{"2019-10":"y","2021-03":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"outlook":{"windows":{"2003":"y","2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"windows-mail":{"2019-10":"n"},"macos":{"2011":"y","2016":"y","16.80":"a #1"},"outlook-com":{"2019-10":"a #1","2024-01":"a #1"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"samsung-email":{"android":{"6.0":"y"}},"sfr":{"desktop-webmail":{"2019-10":"y","2025-07":"n"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"}},"thunderbird":{"macos":{"60.3":"y"}},"aol":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"yahoo":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"protonmail":{"desktop-webmail":{"2020-03":"n"},"ios":{"2020-03":"n"},"android":{"2020-03":"y"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"n"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"y","2025-07":"n"}},"gmx":{"desktop-webmail":{"2022-07":"y"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"web-de":{"desktop-webmail":{"2022-07":"y"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-07":"y"},"android":{"2022-07":"y"}}},
"notes":null,
"notes_by_num":{"1":"Partial. Only supported on type selectors."}
},
@@ -1870,7 +1886,7 @@
"last_test_date":"2019-10-16",
"test_url":"https://www.caniemail.com/tests/css-selectors-pseudo-classes.html",
"test_results_url":"https://app.emailonacid.com/app/acidtest/cl8ZYgIGE372fkVVuJkwNJDd7B4JUpo23Nz6qANcSlRUA/list",
"stats":{"apple-mail":{"macos":{"12.4":"y"},"ios":{"13.1":"y"}},"gmail":{"desktop-webmail":{"2019-10":"n"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"},"mobile-webmail":{"2020-02":"n"}},"orange":{"desktop-webmail":{"2019-10":"y","2021-03":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"outlook":{"windows":{"2003":"y","2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"windows-mail":{"2019-10":"n"},"macos":{"2011":"y","2016":"y","16.80":"a #1"},"outlook-com":{"2019-10":"a #1","2024-01":"a #1"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"samsung-email":{"android":{"6.0":"y"}},"sfr":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"}},"thunderbird":{"macos":{"60.3":"y"}},"aol":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"yahoo":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"protonmail":{"desktop-webmail":{"2020-03":"n"},"ios":{"2020-03":"n"},"android":{"2020-03":"y"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"n"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"y"}},"gmx":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"web-de":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-07":"y"},"android":{"2022-07":"y"}}},
"stats":{"apple-mail":{"macos":{"12.4":"y"},"ios":{"13.1":"y"}},"gmail":{"desktop-webmail":{"2019-10":"n"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"},"mobile-webmail":{"2020-02":"n"}},"orange":{"desktop-webmail":{"2019-10":"y","2021-03":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"outlook":{"windows":{"2003":"y","2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"windows-mail":{"2019-10":"n"},"macos":{"2011":"y","2016":"y","16.80":"a #1"},"outlook-com":{"2019-10":"a #1","2024-01":"a #1"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"samsung-email":{"android":{"6.0":"y"}},"sfr":{"desktop-webmail":{"2019-10":"y","2025-07":"n"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"}},"thunderbird":{"macos":{"60.3":"y"}},"aol":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"yahoo":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"protonmail":{"desktop-webmail":{"2020-03":"n"},"ios":{"2020-03":"n"},"android":{"2020-03":"y"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"n"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"y","2025-07":"n"}},"gmx":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"web-de":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-07":"y"},"android":{"2022-07":"y"}}},
"notes":null,
"notes_by_num":{"1":"Partial. Only supported on type selectors."}
},
@@ -1886,7 +1902,7 @@
"last_test_date":"2019-10-28",
"test_url":"https://www.caniemail.com/tests/css-selectors-pseudo-classes.html",
"test_results_url":"https://app.emailonacid.com/app/acidtest/cl8ZYgIGE372fkVVuJkwNJDd7B4JUpo23Nz6qANcSlRUA/list",
"stats":{"apple-mail":{"macos":{"12.4":"n","16":"y"},"ios":{"13.1":"n"}},"gmail":{"desktop-webmail":{"2019-10":"n"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"},"mobile-webmail":{"2020-02":"n"}},"orange":{"desktop-webmail":{"2019-10":"y","2021-03":"y"},"ios":{"2019-10":"n"},"android":{"2019-10":"y"}},"outlook":{"windows":{"2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"windows-mail":{"2019-10":"n"},"macos":{"2019-02":"y","16.80":"a #1"},"outlook-com":{"2019-10":"a #1","2024-01":"a #1"},"ios":{"2019-10":"n"},"android":{"2019-10":"y"}},"thunderbird":{"macos":{"60.8":"y"}},"yahoo":{"desktop-webmail":{"2019-02":"y"},"ios":{"2019-02":"y"},"android":{"2019-02":"y"}},"aol":{"desktop-webmail":{"2019-02":"y"},"ios":{"2019-02":"n"},"android":{"2019-02":"y"}},"samsung-email":{"android":{"6.0.04.6":"y"}},"sfr":{"desktop-webmail":{"2020-01":"y"},"ios":{"2020-01":"n"},"android":{"2020-01":"n"}},"protonmail":{"desktop-webmail":{"2020-03":"n"},"ios":{"2020-03":"n"},"android":{"2020-03":"y"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"n"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"y"}},"gmx":{"desktop-webmail":{"2022-07":"y"},"ios":{"2022-07":"y"},"android":{"2022-07":"n"}},"web-de":{"desktop-webmail":{"2022-07":"y"},"ios":{"2022-07":"y"},"android":{"2022-07":"n"}},"ionos-1and1":{"desktop-webmail":{"2022-07":"y"},"android":{"2022-07":"n"}}},
"stats":{"apple-mail":{"macos":{"12.4":"n","16":"y"},"ios":{"13.1":"n"}},"gmail":{"desktop-webmail":{"2019-10":"n"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"},"mobile-webmail":{"2020-02":"n"}},"orange":{"desktop-webmail":{"2019-10":"y","2021-03":"y"},"ios":{"2019-10":"n"},"android":{"2019-10":"y"}},"outlook":{"windows":{"2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"windows-mail":{"2019-10":"n"},"macos":{"2019-02":"y","16.80":"a #1"},"outlook-com":{"2019-10":"a #1","2024-01":"a #1"},"ios":{"2019-10":"n"},"android":{"2019-10":"y"}},"thunderbird":{"macos":{"60.8":"y"}},"yahoo":{"desktop-webmail":{"2019-02":"y"},"ios":{"2019-02":"y"},"android":{"2019-02":"y"}},"aol":{"desktop-webmail":{"2019-02":"y"},"ios":{"2019-02":"n"},"android":{"2019-02":"y"}},"samsung-email":{"android":{"6.0.04.6":"y"}},"sfr":{"desktop-webmail":{"2020-01":"y","2025-07":"n"},"ios":{"2020-01":"n"},"android":{"2020-01":"n"}},"protonmail":{"desktop-webmail":{"2020-03":"y"},"ios":{"2020-03":"y"},"android":{"2020-03":"y"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"n"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"y","2025-07":"n"}},"gmx":{"desktop-webmail":{"2022-07":"y"},"ios":{"2022-07":"y"},"android":{"2022-07":"n"}},"web-de":{"desktop-webmail":{"2022-07":"y"},"ios":{"2022-07":"y"},"android":{"2022-07":"n"}},"ionos-1and1":{"desktop-webmail":{"2022-07":"y"},"android":{"2022-07":"n"}}},
"notes":null,
"notes_by_num":{"1":"Partial. Only supported on type selectors."}
},
@@ -1902,7 +1918,7 @@
"last_test_date":"2022-03-15",
"test_url":"https://www.caniemail.com/tests/css-has.html",
"test_results_url":"",
"stats":{"apple-mail":{"macos":{"15.0":"n","16.0":"y"},"ios":{"15.1":"n","15.4":"y"}},"gmail":{"desktop-webmail":{"2021-12":"n","2023-09":"n"},"ios":{"2021-12":"n","2023-09":"n"},"android":{"2021-12":"n","2023-09":"n"},"mobile-webmail":{"2021-12":"n"}},"orange":{"desktop-webmail":{"2021-12":"y"},"ios":{"2021-12":"n"},"android":{"2021-12":"n"}},"outlook":{"windows":{"2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"windows-mail":{"2021-12":"n"},"macos":{"16.56":"n","16.73":"y","16.80":"n"},"outlook-com":{"2021-12":"n","2023-09":"n","2024-01":"n"},"ios":{"2021-12":"n","2023-09":"n"},"android":{"2021-12":"n"}},"samsung-email":{"android":{"6.0":"n","6.1.82":"y"}},"sfr":{"desktop-webmail":{"2021-12":"y"},"ios":{"2021-12":"n"},"android":{"2021-12":"n"}},"thunderbird":{"macos":{"78.14":"n","115.2":"n"}},"aol":{"desktop-webmail":{"2021-12":"n #1"},"ios":{"2021-12":"n"},"android":{"2021-12":"n"}},"yahoo":{"desktop-webmail":{"2021-12":"n #1","2023-09":"n #1"},"ios":{"2021-12":"n","2023-09":"n"},"android":{"2021-12":"n","2023-09":"n"}},"protonmail":{"desktop-webmail":{"2021-12":"n #2","2023-09":"y"},"ios":{"2021-12":"n","2023-09":"y"},"android":{"2021-12":"n","2023-09":"n"}},"hey":{"desktop-webmail":{"2021-12":"y"}},"mail-ru":{"desktop-webmail":{"2021-12":"n","2023-09":"n"}},"fastmail":{"desktop-webmail":{"2021-12":"n","2023-09":"y"}},"laposte":{"desktop-webmail":{"2021-12":"y"}},"gmx":{"desktop-webmail":{"2022-07":"n","2023-09":"n"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"web-de":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-07":"y"},"android":{"2022-07":"y"}}},
"stats":{"apple-mail":{"macos":{"15.0":"n","16.0":"y"},"ios":{"15.1":"n","15.4":"y"}},"gmail":{"desktop-webmail":{"2021-12":"n","2023-09":"n"},"ios":{"2021-12":"n","2023-09":"n"},"android":{"2021-12":"n","2023-09":"n"},"mobile-webmail":{"2021-12":"n"}},"orange":{"desktop-webmail":{"2021-12":"y"},"ios":{"2021-12":"n"},"android":{"2021-12":"n"}},"outlook":{"windows":{"2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"windows-mail":{"2021-12":"n"},"macos":{"16.56":"n","16.73":"y","16.80":"n"},"outlook-com":{"2021-12":"n","2023-09":"n","2024-01":"n"},"ios":{"2021-12":"n","2023-09":"n"},"android":{"2021-12":"n"}},"samsung-email":{"android":{"6.0":"n","6.1.82":"y"}},"sfr":{"desktop-webmail":{"2021-12":"y","2025-07":"n"},"ios":{"2021-12":"n"},"android":{"2021-12":"n"}},"thunderbird":{"macos":{"78.14":"n","115.2":"n"}},"aol":{"desktop-webmail":{"2021-12":"n #1"},"ios":{"2021-12":"n"},"android":{"2021-12":"n"}},"yahoo":{"desktop-webmail":{"2021-12":"n #1","2023-09":"n #1"},"ios":{"2021-12":"n","2023-09":"n"},"android":{"2021-12":"n","2023-09":"n"}},"protonmail":{"desktop-webmail":{"2021-12":"n #2","2023-09":"y"},"ios":{"2021-12":"n","2023-09":"y"},"android":{"2021-12":"n","2023-09":"n"}},"hey":{"desktop-webmail":{"2021-12":"y"}},"mail-ru":{"desktop-webmail":{"2021-12":"n","2023-09":"n"}},"fastmail":{"desktop-webmail":{"2021-12":"n","2023-09":"y"}},"laposte":{"desktop-webmail":{"2021-12":"y","2025-07":"n"}},"gmx":{"desktop-webmail":{"2022-07":"n","2023-09":"n"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"web-de":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-07":"y"},"android":{"2022-07":"y"}}},
"notes":"As of december 2021, `:has()` is only supported in [Safari Technology Preview 137](https://webkit.org/blog/12156/release-notes-for-safari-technology-preview-137/). As of march 2022, it is supported in Safari 15.4.",
"notes_by_num":{"1":"Not supported. `:has(…)` is replaced by `:has`.","2":"Not supported. But the pseudo-class seems interpreted and computed server side."}
},
@@ -1918,7 +1934,7 @@
"last_test_date":"2019-10-23",
"test_url":"https://www.caniemail.com/tests/css-selectors-pseudo-classes.html",
"test_results_url":"https://app.emailonacid.com/app/acidtest/cl8ZYgIGE372fkVVuJkwNJDd7B4JUpo23Nz6qANcSlRUA/list",
"stats":{"apple-mail":{"macos":{"12.4":"y"},"ios":{"12.1":"y","13.1":"y"}},"gmail":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"n"},"android":{"2019-10":"a #1"},"mobile-webmail":{"2020-02":"n"}},"orange":{"desktop-webmail":{"2019-10":"y","2021-03":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"outlook":{"windows":{"2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"windows-mail":{"2019-10":"n"},"macos":{"2019-02":"y","16.80":"a #2"},"outlook-com":{"2019-10":"a #2","2024-01":"a #2"},"ios":{"2019-10":"n"},"android":{"2019-10":"y"}},"thunderbird":{"macos":{"60.8":"y"}},"yahoo":{"desktop-webmail":{"2019-02":"y"},"ios":{"2019-02":"y"},"android":{"2019-02":"y"}},"aol":{"desktop-webmail":{"2019-02":"y"},"ios":{"2019-02":"n"},"android":{"2019-02":"y"}},"samsung-email":{"android":{"5.0.10.2":"y","6.0.04.6":"y"}},"sfr":{"desktop-webmail":{"2020-01":"y"},"ios":{"2020-01":"n"},"android":{"2020-01":"n"}},"protonmail":{"desktop-webmail":{"2020-03":"n"},"ios":{"2020-03":"n"},"android":{"2020-03":"y"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"n"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"y"}},"gmx":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"web-de":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-07":"y"},"android":{"2022-07":"y"}}},
"stats":{"apple-mail":{"macos":{"12.4":"y"},"ios":{"12.1":"y","13.1":"y"}},"gmail":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"n"},"android":{"2019-10":"a #1"},"mobile-webmail":{"2020-02":"n"}},"orange":{"desktop-webmail":{"2019-10":"y","2021-03":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"outlook":{"windows":{"2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"windows-mail":{"2019-10":"n"},"macos":{"2019-02":"y","16.80":"a #2"},"outlook-com":{"2019-10":"a #2","2024-01":"a #2"},"ios":{"2019-10":"n"},"android":{"2019-10":"y"}},"thunderbird":{"macos":{"60.8":"y"}},"yahoo":{"desktop-webmail":{"2019-02":"y"},"ios":{"2019-02":"y"},"android":{"2019-02":"y"}},"aol":{"desktop-webmail":{"2019-02":"y"},"ios":{"2019-02":"n"},"android":{"2019-02":"y"}},"samsung-email":{"android":{"5.0.10.2":"y","6.0.04.6":"y"}},"sfr":{"desktop-webmail":{"2020-01":"y","2025-07":"n"},"ios":{"2020-01":"n"},"android":{"2020-01":"n"}},"protonmail":{"desktop-webmail":{"2020-03":"y"},"ios":{"2020-03":"y"},"android":{"2020-03":"y"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"n"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"y","2025-07":"n"}},"gmx":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"web-de":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-07":"y"},"android":{"2022-07":"y"}}},
"notes":null,
"notes_by_num":{"1":"Partial. Not supported with non Google accounts.","2":"Partial. Only supported on type selectors."}
},
@@ -1934,7 +1950,7 @@
"last_test_date":"2022-07-12",
"test_url":"https://www.caniemail.com/tests/css-pseudo-selectors-lang.html",
"test_results_url":"https://testi.at/proj/gGZHWn1FNVBHweeCPYAFL4MSXy",
"stats":{"apple-mail":{"macos":{"15":"y"},"ios":{"15":"y"}},"gmail":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"},"mobile-webmail":{"2022-07":"n"}},"orange":{"desktop-webmail":{"2022-07":"u"},"ios":{"2022-07":"u"},"android":{"2022-07":"u"}},"outlook":{"windows":{"2013":"n","2016":"n","2019":"n","2021":"n"},"windows-mail":{"2022-07":"n"},"macos":{"16.56":"y","16.80":"n"},"outlook-com":{"2022-07":"n","2024-01":"n"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"samsung-email":{"android":{"10":"y","11":"y"}},"sfr":{"desktop-webmail":{"2022-07":"u"},"ios":{"2022-07":"u"},"android":{"2022-07":"u"}},"thunderbird":{"macos":{"78.14":"u"}},"aol":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"}},"yahoo":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"}},"protonmail":{"desktop-webmail":{"2022-07":"u"},"ios":{"2022-07":"u"},"android":{"2022-07":"u"}},"hey":{"desktop-webmail":{"2022-07":"u"}},"mail-ru":{"desktop-webmail":{"2022-07":"n"}},"fastmail":{"desktop-webmail":{"2022-07":"u"}},"laposte":{"desktop-webmail":{"2022-07":"u"}}},
"stats":{"apple-mail":{"macos":{"15":"y"},"ios":{"15":"y"}},"gmail":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"},"mobile-webmail":{"2022-07":"n"}},"orange":{"desktop-webmail":{"2022-07":"u"},"ios":{"2022-07":"u"},"android":{"2022-07":"u"}},"outlook":{"windows":{"2013":"n","2016":"n","2019":"n","2021":"n"},"windows-mail":{"2022-07":"n"},"macos":{"16.56":"y","16.80":"n"},"outlook-com":{"2022-07":"n","2024-01":"n"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"samsung-email":{"android":{"10":"y","11":"y"}},"sfr":{"desktop-webmail":{"2022-07":"u","2025-07":"n"},"ios":{"2022-07":"u"},"android":{"2022-07":"u"}},"thunderbird":{"macos":{"78.14":"u"}},"aol":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"}},"yahoo":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"}},"protonmail":{"desktop-webmail":{"2022-07":"y"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"hey":{"desktop-webmail":{"2022-07":"u"}},"mail-ru":{"desktop-webmail":{"2022-07":"n"}},"fastmail":{"desktop-webmail":{"2022-07":"u"}},"laposte":{"desktop-webmail":{"2022-07":"u","2025-07":"n"}}},
"notes":null,
"notes_by_num":null
},
@@ -1950,7 +1966,7 @@
"last_test_date":"2019-10-19",
"test_url":"https://www.caniemail.com/tests/css-selectors-pseudo-classes.html",
"test_results_url":"https://app.emailonacid.com/app/acidtest/cl8ZYgIGE372fkVVuJkwNJDd7B4JUpo23Nz6qANcSlRUA/list",
"stats":{"apple-mail":{"macos":{"12.4":"y"},"ios":{"13.1":"y"}},"gmail":{"desktop-webmail":{"2019-10":"n"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"},"mobile-webmail":{"2020-02":"n"}},"orange":{"desktop-webmail":{"2019-10":"y","2021-03":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"outlook":{"windows":{"2003":"n","2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"windows-mail":{"2019-10":"n"},"macos":{"2011":"y","2016":"y","16.80":"a #1"},"outlook-com":{"2019-10":"a #1","2024-01":"a #1"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"samsung-email":{"android":{"6.0":"y"}},"sfr":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"}},"thunderbird":{"macos":{"60.3":"y"}},"aol":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"yahoo":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"protonmail":{"desktop-webmail":{"2020-03":"n"},"ios":{"2020-03":"n"},"android":{"2020-03":"y"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"n"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"y"}},"gmx":{"desktop-webmail":{"2022-07":"y"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"web-de":{"desktop-webmail":{"2022-07":"y"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-07":"y"},"android":{"2022-07":"y"}}},
"stats":{"apple-mail":{"macos":{"12.4":"y"},"ios":{"13.1":"y"}},"gmail":{"desktop-webmail":{"2019-10":"n"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"},"mobile-webmail":{"2020-02":"n"}},"orange":{"desktop-webmail":{"2019-10":"y","2021-03":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"outlook":{"windows":{"2003":"n","2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"windows-mail":{"2019-10":"n"},"macos":{"2011":"y","2016":"y","16.80":"a #1"},"outlook-com":{"2019-10":"a #1","2024-01":"a #1"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"samsung-email":{"android":{"6.0":"y"}},"sfr":{"desktop-webmail":{"2019-10":"y","2025-07":"n"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"}},"thunderbird":{"macos":{"60.3":"y"}},"aol":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"yahoo":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"protonmail":{"desktop-webmail":{"2020-03":"n"},"ios":{"2020-03":"n"},"android":{"2020-03":"y"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"n"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"y","2025-07":"n"}},"gmx":{"desktop-webmail":{"2022-07":"y"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"web-de":{"desktop-webmail":{"2022-07":"y"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-07":"y"},"android":{"2022-07":"y"}}},
"notes":null,
"notes_by_num":{"1":"Partial. Only supported on type selectors."}
},
@@ -1966,7 +1982,7 @@
"last_test_date":"2019-10-19",
"test_url":"https://www.caniemail.com/tests/css-selectors-pseudo-classes.html",
"test_results_url":"https://app.emailonacid.com/app/acidtest/cl8ZYgIGE372fkVVuJkwNJDd7B4JUpo23Nz6qANcSlRUA/list",
"stats":{"apple-mail":{"macos":{"12.4":"y"},"ios":{"13.1":"y"}},"gmail":{"desktop-webmail":{"2019-10":"n"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"},"mobile-webmail":{"2020-02":"n"}},"orange":{"desktop-webmail":{"2019-10":"y","2021-03":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"outlook":{"windows":{"2003":"n","2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"windows-mail":{"2019-10":"n"},"macos":{"2011":"y","2016":"y","16.80":"a #1"},"outlook-com":{"2019-10":"a #1","2024-01":"a #1"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"samsung-email":{"android":{"6.0":"y"}},"sfr":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"}},"thunderbird":{"macos":{"60.3":"y"}},"aol":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"yahoo":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"protonmail":{"desktop-webmail":{"2020-03":"n"},"ios":{"2020-03":"n"},"android":{"2020-03":"y"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"n"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"y"}},"gmx":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"web-de":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-07":"y"},"android":{"2022-07":"y"}}},
"stats":{"apple-mail":{"macos":{"12.4":"y"},"ios":{"13.1":"y"}},"gmail":{"desktop-webmail":{"2019-10":"n"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"},"mobile-webmail":{"2020-02":"n"}},"orange":{"desktop-webmail":{"2019-10":"y","2021-03":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"outlook":{"windows":{"2003":"n","2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"windows-mail":{"2019-10":"n"},"macos":{"2011":"y","2016":"y","16.80":"a #1"},"outlook-com":{"2019-10":"a #1","2024-01":"a #1"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"samsung-email":{"android":{"6.0":"y"}},"sfr":{"desktop-webmail":{"2019-10":"y","2025-07":"n"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"}},"thunderbird":{"macos":{"60.3":"y"}},"aol":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"yahoo":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"protonmail":{"desktop-webmail":{"2020-03":"n"},"ios":{"2020-03":"n"},"android":{"2020-03":"y"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"n"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"y","2025-07":"n"}},"gmx":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"web-de":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-07":"y"},"android":{"2022-07":"y"}}},
"notes":null,
"notes_by_num":{"1":"Partial. Only supported on type selectors."}
},
@@ -1982,7 +1998,7 @@
"last_test_date":"2019-10-23",
"test_url":"https://www.caniemail.com/tests/css-selectors-pseudo-classes.html",
"test_results_url":"https://app.emailonacid.com/app/acidtest/cl8ZYgIGE372fkVVuJkwNJDd7B4JUpo23Nz6qANcSlRUA/list",
"stats":{"apple-mail":{"macos":{"12.4":"y"},"ios":{"13.1":"y"}},"gmail":{"desktop-webmail":{"2019-10":"n"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"},"mobile-webmail":{"2020-02":"n"}},"orange":{"desktop-webmail":{"2019-10":"y","2021-03":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"outlook":{"windows":{"2003":"y","2007":"y","2010":"y","2013":"y","2016":"y","2019":"y"},"windows-mail":{"2019-10":"y"},"macos":{"2011":"y","2016":"y","16.80":"a #1"},"outlook-com":{"2019-10":"y","2024-01":"a #1"},"ios":{"2.51.1":"y","4.7.1":"y"},"android":{"2019-10":"y"}},"samsung-email":{"android":{"6.0":"y"}},"sfr":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"}},"thunderbird":{"macos":{"60.3":"y"}},"aol":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"yahoo":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"protonmail":{"desktop-webmail":{"2020-03":"n"},"ios":{"2020-03":"n"},"android":{"2020-03":"y"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"n"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"y"}},"gmx":{"desktop-webmail":{"2022-07":"y"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"web-de":{"desktop-webmail":{"2022-07":"y"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-07":"y"},"android":{"2022-07":"y"}}},
"stats":{"apple-mail":{"macos":{"12.4":"y"},"ios":{"13.1":"y"}},"gmail":{"desktop-webmail":{"2019-10":"n"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"},"mobile-webmail":{"2020-02":"n"}},"orange":{"desktop-webmail":{"2019-10":"y","2021-03":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"outlook":{"windows":{"2003":"y","2007":"y","2010":"y","2013":"y","2016":"y","2019":"y"},"windows-mail":{"2019-10":"y"},"macos":{"2011":"y","2016":"y","16.80":"a #1"},"outlook-com":{"2019-10":"y","2024-01":"a #1"},"ios":{"2.51.1":"y","4.7.1":"y"},"android":{"2019-10":"y"}},"samsung-email":{"android":{"6.0":"y"}},"sfr":{"desktop-webmail":{"2019-10":"y","2025-07":"n"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"}},"thunderbird":{"macos":{"60.3":"y"}},"aol":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"yahoo":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"protonmail":{"desktop-webmail":{"2020-03":"n"},"ios":{"2020-03":"n"},"android":{"2020-03":"y"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"n"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"y","2025-07":"n"}},"gmx":{"desktop-webmail":{"2022-07":"y"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"web-de":{"desktop-webmail":{"2022-07":"y"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-07":"y"},"android":{"2022-07":"y"}}},
"notes":null,
"notes_by_num":null
},
@@ -1998,7 +2014,7 @@
"last_test_date":"2019-10-23",
"test_url":"https://www.caniemail.com/tests/css-selectors-pseudo-classes.html",
"test_results_url":"https://app.emailonacid.com/app/acidtest/cl8ZYgIGE372fkVVuJkwNJDd7B4JUpo23Nz6qANcSlRUA/list",
"stats":{"apple-mail":{"macos":{"12.4":"y"},"ios":{"13.1":"y"}},"gmail":{"desktop-webmail":{"2019-10":"n"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"},"mobile-webmail":{"2020-02":"n"}},"orange":{"desktop-webmail":{"2019-10":"y","2021-03":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"outlook":{"windows":{"2003":"n","2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"windows-mail":{"2019-10":"n"},"macos":{"2011":"y","2016":"y","16.80":"n"},"outlook-com":{"2019-10":"n","2024-01":"n"},"ios":{"2.51.1":"y","4.7.1":"n"},"android":{"2019-10":"n"}},"samsung-email":{"android":{"6.0":"y"}},"sfr":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"}},"thunderbird":{"macos":{"60.3":"y"}},"aol":{"desktop-webmail":{"2019-10":"n"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"}},"yahoo":{"desktop-webmail":{"2019-10":"n"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"}},"protonmail":{"desktop-webmail":{"2020-03":"n"},"ios":{"2020-03":"n"},"android":{"2020-03":"y"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"n"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"y"}},"gmx":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"web-de":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-07":"y"},"android":{"2022-07":"y"}}},
"stats":{"apple-mail":{"macos":{"12.4":"y"},"ios":{"13.1":"y"}},"gmail":{"desktop-webmail":{"2019-10":"n"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"},"mobile-webmail":{"2020-02":"n"}},"orange":{"desktop-webmail":{"2019-10":"y","2021-03":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"outlook":{"windows":{"2003":"n","2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"windows-mail":{"2019-10":"n"},"macos":{"2011":"y","2016":"y","16.80":"n"},"outlook-com":{"2019-10":"n","2024-01":"n"},"ios":{"2.51.1":"y","4.7.1":"n"},"android":{"2019-10":"n"}},"samsung-email":{"android":{"6.0":"y"}},"sfr":{"desktop-webmail":{"2019-10":"y","2025-07":"n"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"}},"thunderbird":{"macos":{"60.3":"y"}},"aol":{"desktop-webmail":{"2019-10":"n"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"}},"yahoo":{"desktop-webmail":{"2019-10":"n"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"}},"protonmail":{"desktop-webmail":{"2020-03":"n"},"ios":{"2020-03":"n"},"android":{"2020-03":"y"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"n"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"y","2025-07":"n"}},"gmx":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"web-de":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-07":"y"},"android":{"2022-07":"y"}}},
"notes":null,
"notes_by_num":null
},
@@ -2014,7 +2030,7 @@
"last_test_date":"2019-10-19",
"test_url":"https://www.caniemail.com/tests/css-selectors-pseudo-classes.html",
"test_results_url":"https://app.emailonacid.com/app/acidtest/cl8ZYgIGE372fkVVuJkwNJDd7B4JUpo23Nz6qANcSlRUA/list",
"stats":{"apple-mail":{"macos":{"12.4":"y"},"ios":{"13.1":"y"}},"gmail":{"desktop-webmail":{"2019-10":"n"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"},"mobile-webmail":{"2020-02":"n"}},"orange":{"desktop-webmail":{"2019-10":"y","2021-03":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"outlook":{"windows":{"2003":"n","2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"windows-mail":{"2019-10":"n"},"macos":{"2011":"y","2016":"y","16.80":"n"},"outlook-com":{"2019-10":"a #1","2024-01":"n"},"ios":{"2.51.1":"y","4.7.1":"n"},"android":{"2019-10":"n"}},"samsung-email":{"android":{"6.0":"y"}},"sfr":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"}},"thunderbird":{"macos":{"60.3":"y"}},"aol":{"desktop-webmail":{"2019-10":"n #2"},"ios":{"2019-10":"n #2"},"android":{"2019-10":"n #2"}},"yahoo":{"desktop-webmail":{"2019-10":"n #2"},"ios":{"2019-10":"n #2"},"android":{"2019-10":"n #2"}},"protonmail":{"desktop-webmail":{"2020-03":"n"},"ios":{"2020-03":"n"},"android":{"2020-03":"y"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"n"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"y"}},"gmx":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"web-de":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-07":"y"},"android":{"2022-07":"y"}}},
"stats":{"apple-mail":{"macos":{"12.4":"y"},"ios":{"13.1":"y"}},"gmail":{"desktop-webmail":{"2019-10":"n"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"},"mobile-webmail":{"2020-02":"n"}},"orange":{"desktop-webmail":{"2019-10":"y","2021-03":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"outlook":{"windows":{"2003":"n","2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"windows-mail":{"2019-10":"n"},"macos":{"2011":"y","2016":"y","16.80":"n"},"outlook-com":{"2019-10":"a #1","2024-01":"n"},"ios":{"2.51.1":"y","4.7.1":"n"},"android":{"2019-10":"n"}},"samsung-email":{"android":{"6.0":"y"}},"sfr":{"desktop-webmail":{"2019-10":"y","2025-07":"n"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"}},"thunderbird":{"macos":{"60.3":"y"}},"aol":{"desktop-webmail":{"2019-10":"n #2"},"ios":{"2019-10":"n #2"},"android":{"2019-10":"n #2"}},"yahoo":{"desktop-webmail":{"2019-10":"n #2"},"ios":{"2019-10":"n #2"},"android":{"2019-10":"n #2"}},"protonmail":{"desktop-webmail":{"2020-03":"n"},"ios":{"2020-03":"n"},"android":{"2020-03":"y"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"n"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"y","2025-07":"n"}},"gmx":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"web-de":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-07":"y"},"android":{"2022-07":"y"}}},
"notes":null,
"notes_by_num":{"1":"Partial. Only supported on type selectors.","2":"Not supported. Removes the parenthesis part."}
},
@@ -2030,7 +2046,7 @@
"last_test_date":"2019-10-19",
"test_url":"https://www.caniemail.com/tests/css-selectors-pseudo-classes.html",
"test_results_url":"https://app.emailonacid.com/app/acidtest/cl8ZYgIGE372fkVVuJkwNJDd7B4JUpo23Nz6qANcSlRUA/list",
"stats":{"apple-mail":{"macos":{"12.4":"y"},"ios":{"13.1":"y"}},"gmail":{"desktop-webmail":{"2019-10":"n"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"},"mobile-webmail":{"2020-02":"n"}},"orange":{"desktop-webmail":{"2019-10":"y","2021-03":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"outlook":{"windows":{"2003":"n","2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"windows-mail":{"2019-10":"n"},"macos":{"2011":"y","2016":"y","16.80":"n"},"outlook-com":{"2019-10":"a #1","2024-01":"n"},"ios":{"2.51.1":"y","4.7.1":"n"},"android":{"2019-10":"n"}},"samsung-email":{"android":{"6.0":"y"}},"sfr":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"}},"thunderbird":{"macos":{"60.3":"y"}},"aol":{"desktop-webmail":{"2019-10":"n #2"},"ios":{"2019-10":"n #2"},"android":{"2019-10":"n #2"}},"yahoo":{"desktop-webmail":{"2019-10":"n #2"},"ios":{"2019-10":"n #2"},"android":{"2019-10":"n #2"}},"protonmail":{"desktop-webmail":{"2020-03":"n"},"ios":{"2020-03":"n"},"android":{"2020-03":"y"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"n"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"y"}},"gmx":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"web-de":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-07":"y"},"android":{"2022-07":"y"}}},
"stats":{"apple-mail":{"macos":{"12.4":"y"},"ios":{"13.1":"y"}},"gmail":{"desktop-webmail":{"2019-10":"n"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"},"mobile-webmail":{"2020-02":"n"}},"orange":{"desktop-webmail":{"2019-10":"y","2021-03":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"outlook":{"windows":{"2003":"n","2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"windows-mail":{"2019-10":"n"},"macos":{"2011":"y","2016":"y","16.80":"n"},"outlook-com":{"2019-10":"a #1","2024-01":"n"},"ios":{"2.51.1":"y","4.7.1":"n"},"android":{"2019-10":"n"}},"samsung-email":{"android":{"6.0":"y"}},"sfr":{"desktop-webmail":{"2019-10":"y","2025-07":"n"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"}},"thunderbird":{"macos":{"60.3":"y"}},"aol":{"desktop-webmail":{"2019-10":"n #2"},"ios":{"2019-10":"n #2"},"android":{"2019-10":"n #2"}},"yahoo":{"desktop-webmail":{"2019-10":"n #2"},"ios":{"2019-10":"n #2"},"android":{"2019-10":"n #2"}},"protonmail":{"desktop-webmail":{"2020-03":"n"},"ios":{"2020-03":"n"},"android":{"2020-03":"y"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"n"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"y","2025-07":"n"}},"gmx":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"web-de":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-07":"y"},"android":{"2022-07":"y"}}},
"notes":null,
"notes_by_num":{"1":"Partial. Only supported on type selectors.","2":"Not supported. Removes the parenthesis part."}
},
@@ -2046,7 +2062,7 @@
"last_test_date":"2019-10-19",
"test_url":"https://www.caniemail.com/tests/css-selectors-pseudo-classes.html",
"test_results_url":"https://app.emailonacid.com/app/acidtest/cl8ZYgIGE372fkVVuJkwNJDd7B4JUpo23Nz6qANcSlRUA/list",
"stats":{"apple-mail":{"macos":{"12.4":"y"},"ios":{"13.1":"y"}},"gmail":{"desktop-webmail":{"2019-10":"n"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"},"mobile-webmail":{"2020-02":"n"}},"orange":{"desktop-webmail":{"2019-10":"y","2021-03":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"outlook":{"windows":{"2003":"n","2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"windows-mail":{"2019-10":"n"},"macos":{"2011":"y","2016":"y","16.80":"n"},"outlook-com":{"2019-10":"a #1","2024-01":"n"},"ios":{"2.51.1":"y","4.7.1":"n"},"android":{"2019-10":"n"}},"samsung-email":{"android":{"6.0":"y"}},"sfr":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"}},"thunderbird":{"macos":{"60.3":"y"}},"aol":{"desktop-webmail":{"2019-10":"n #2"},"ios":{"2019-10":"n #2"},"android":{"2019-10":"n #2"}},"yahoo":{"desktop-webmail":{"2019-10":"n #2"},"ios":{"2019-10":"n #2"},"android":{"2019-10":"n #2"}},"protonmail":{"desktop-webmail":{"2020-03":"n"},"ios":{"2020-03":"n"},"android":{"2020-03":"n"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"n"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"y"}},"gmx":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"web-de":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-07":"y"},"android":{"2022-07":"y"}}},
"stats":{"apple-mail":{"macos":{"12.4":"y"},"ios":{"13.1":"y"}},"gmail":{"desktop-webmail":{"2019-10":"n"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"},"mobile-webmail":{"2020-02":"n"}},"orange":{"desktop-webmail":{"2019-10":"y","2021-03":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"outlook":{"windows":{"2003":"n","2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"windows-mail":{"2019-10":"n"},"macos":{"2011":"y","2016":"y","16.80":"n"},"outlook-com":{"2019-10":"a #1","2024-01":"n"},"ios":{"2.51.1":"y","4.7.1":"n"},"android":{"2019-10":"n"}},"samsung-email":{"android":{"6.0":"y"}},"sfr":{"desktop-webmail":{"2019-10":"y","2025-07":"n"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"}},"thunderbird":{"macos":{"60.3":"y"}},"aol":{"desktop-webmail":{"2019-10":"n #2"},"ios":{"2019-10":"n #2"},"android":{"2019-10":"n #2"}},"yahoo":{"desktop-webmail":{"2019-10":"n #2"},"ios":{"2019-10":"n #2"},"android":{"2019-10":"n #2"}},"protonmail":{"desktop-webmail":{"2020-03":"n"},"ios":{"2020-03":"n"},"android":{"2020-03":"n"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"n"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"y","2025-07":"n"}},"gmx":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"web-de":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-07":"y"},"android":{"2022-07":"y"}}},
"notes":null,
"notes_by_num":{"1":"Partial. Only supported on type selectors.","2":"Not supported. Removes the parenthesis part."}
},
@@ -2062,7 +2078,7 @@
"last_test_date":"2019-10-19",
"test_url":"https://www.caniemail.com/tests/css-selectors-pseudo-classes.html",
"test_results_url":"https://app.emailonacid.com/app/acidtest/cl8ZYgIGE372fkVVuJkwNJDd7B4JUpo23Nz6qANcSlRUA/list",
"stats":{"apple-mail":{"macos":{"12.4":"y"},"ios":{"13.1":"y"}},"gmail":{"desktop-webmail":{"2019-10":"n"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"},"mobile-webmail":{"2020-02":"n"}},"orange":{"desktop-webmail":{"2019-10":"y","2021-03":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"outlook":{"windows":{"2003":"n","2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"windows-mail":{"2019-10":"n"},"macos":{"2011":"y","2016":"y","16.80":"n"},"outlook-com":{"2019-10":"a #1","2024-01":"n"},"ios":{"2.51.1":"y","4.7.1":"n"},"android":{"2019-10":"n"}},"samsung-email":{"android":{"6.0":"y"}},"sfr":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"}},"thunderbird":{"macos":{"60.3":"y"}},"aol":{"desktop-webmail":{"2019-10":"n #2"},"ios":{"2019-10":"n #2"},"android":{"2019-10":"n #2"}},"yahoo":{"desktop-webmail":{"2019-10":"n #2"},"ios":{"2019-10":"n #2"},"android":{"2019-10":"n #2"}},"protonmail":{"desktop-webmail":{"2020-03":"n"},"ios":{"2020-03":"n"},"android":{"2020-03":"n"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"n"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"y"}},"gmx":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"web-de":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-07":"y"},"android":{"2022-07":"y"}}},
"stats":{"apple-mail":{"macos":{"12.4":"y"},"ios":{"13.1":"y"}},"gmail":{"desktop-webmail":{"2019-10":"n"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"},"mobile-webmail":{"2020-02":"n"}},"orange":{"desktop-webmail":{"2019-10":"y","2021-03":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"outlook":{"windows":{"2003":"n","2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"windows-mail":{"2019-10":"n"},"macos":{"2011":"y","2016":"y","16.80":"n"},"outlook-com":{"2019-10":"a #1","2024-01":"n"},"ios":{"2.51.1":"y","4.7.1":"n"},"android":{"2019-10":"n"}},"samsung-email":{"android":{"6.0":"y"}},"sfr":{"desktop-webmail":{"2019-10":"y","2025-07":"n"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"}},"thunderbird":{"macos":{"60.3":"y"}},"aol":{"desktop-webmail":{"2019-10":"n #2"},"ios":{"2019-10":"n #2"},"android":{"2019-10":"n #2"}},"yahoo":{"desktop-webmail":{"2019-10":"n #2"},"ios":{"2019-10":"n #2"},"android":{"2019-10":"n #2"}},"protonmail":{"desktop-webmail":{"2020-03":"n"},"ios":{"2020-03":"n"},"android":{"2020-03":"n"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"n"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"y","2025-07":"n"}},"gmx":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"web-de":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-07":"y"},"android":{"2022-07":"y"}}},
"notes":null,
"notes_by_num":{"1":"Partial. Only supported on type selectors.","2":"Not supported. Removes the parenthesis part."}
},
@@ -2078,7 +2094,7 @@
"last_test_date":"2019-10-19",
"test_url":"https://www.caniemail.com/tests/css-selectors-pseudo-classes.html",
"test_results_url":"https://app.emailonacid.com/app/acidtest/cl8ZYgIGE372fkVVuJkwNJDd7B4JUpo23Nz6qANcSlRUA/list",
"stats":{"apple-mail":{"macos":{"12.4":"y"},"ios":{"13.1":"y"}},"gmail":{"desktop-webmail":{"2019-10":"n"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"},"mobile-webmail":{"2020-02":"n"}},"orange":{"desktop-webmail":{"2019-10":"y","2021-03":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"outlook":{"windows":{"2003":"n","2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"windows-mail":{"2019-10":"n"},"macos":{"2011":"y","2016":"y","16.80":"a #1"},"outlook-com":{"2019-10":"a #1","2024-01":"a #1"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"samsung-email":{"android":{"6.0":"y"}},"sfr":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"}},"thunderbird":{"macos":{"60.3":"y"}},"aol":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"yahoo":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"protonmail":{"desktop-webmail":{"2020-03":"n"},"ios":{"2020-03":"n"},"android":{"2020-03":"y"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"n"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"y"}},"gmx":{"desktop-webmail":{"2022-07":"y"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"web-de":{"desktop-webmail":{"2022-07":"y"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-07":"y"},"android":{"2022-07":"y"}}},
"stats":{"apple-mail":{"macos":{"12.4":"y"},"ios":{"13.1":"y"}},"gmail":{"desktop-webmail":{"2019-10":"n"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"},"mobile-webmail":{"2020-02":"n"}},"orange":{"desktop-webmail":{"2019-10":"y","2021-03":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"outlook":{"windows":{"2003":"n","2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"windows-mail":{"2019-10":"n"},"macos":{"2011":"y","2016":"y","16.80":"a #1"},"outlook-com":{"2019-10":"a #1","2024-01":"a #1"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"samsung-email":{"android":{"6.0":"y"}},"sfr":{"desktop-webmail":{"2019-10":"y","2025-07":"n"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"}},"thunderbird":{"macos":{"60.3":"y"}},"aol":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"yahoo":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"protonmail":{"desktop-webmail":{"2020-03":"n"},"ios":{"2020-03":"n"},"android":{"2020-03":"y"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"n"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"y","2025-07":"n"}},"gmx":{"desktop-webmail":{"2022-07":"y"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"web-de":{"desktop-webmail":{"2022-07":"y"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-07":"y"},"android":{"2022-07":"y"}}},
"notes":null,
"notes_by_num":{"1":"Partial. Only supported on type selectors."}
},
@@ -2094,7 +2110,7 @@
"last_test_date":"2019-10-19",
"test_url":"https://www.caniemail.com/tests/css-selectors-pseudo-classes.html",
"test_results_url":"https://app.emailonacid.com/app/acidtest/cl8ZYgIGE372fkVVuJkwNJDd7B4JUpo23Nz6qANcSlRUA/list",
"stats":{"apple-mail":{"macos":{"12.4":"y"},"ios":{"13.1":"y"}},"gmail":{"desktop-webmail":{"2019-10":"n"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"},"mobile-webmail":{"2020-02":"n"}},"orange":{"desktop-webmail":{"2019-10":"y","2021-03":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"outlook":{"windows":{"2003":"n","2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"windows-mail":{"2019-10":"n"},"macos":{"2011":"y","2016":"y","16.80":"a #1"},"outlook-com":{"2019-10":"a #1","2024-01":"a #1"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"samsung-email":{"android":{"6.0":"y"}},"sfr":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"}},"thunderbird":{"macos":{"60.3":"y"}},"aol":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"yahoo":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"protonmail":{"desktop-webmail":{"2020-03":"n"},"ios":{"2020-03":"n"},"android":{"2020-03":"y"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"n"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"y"}},"gmx":{"desktop-webmail":{"2022-07":"y"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"web-de":{"desktop-webmail":{"2022-07":"y"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-07":"y"},"android":{"2022-07":"y"}}},
"stats":{"apple-mail":{"macos":{"12.4":"y"},"ios":{"13.1":"y"}},"gmail":{"desktop-webmail":{"2019-10":"n"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"},"mobile-webmail":{"2020-02":"n"}},"orange":{"desktop-webmail":{"2019-10":"y","2021-03":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"outlook":{"windows":{"2003":"n","2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"windows-mail":{"2019-10":"n"},"macos":{"2011":"y","2016":"y","16.80":"a #1"},"outlook-com":{"2019-10":"a #1","2024-01":"a #1"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"samsung-email":{"android":{"6.0":"y"}},"sfr":{"desktop-webmail":{"2019-10":"y","2025-07":"n"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"}},"thunderbird":{"macos":{"60.3":"y"}},"aol":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"yahoo":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"protonmail":{"desktop-webmail":{"2020-03":"n"},"ios":{"2020-03":"n"},"android":{"2020-03":"y"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"n"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"y","2025-07":"n"}},"gmx":{"desktop-webmail":{"2022-07":"y"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"web-de":{"desktop-webmail":{"2022-07":"y"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-07":"y"},"android":{"2022-07":"y"}}},
"notes":null,
"notes_by_num":{"1":"Partial. Only supported on type selectors."}
},
@@ -2110,7 +2126,7 @@
"last_test_date":"2019-10-28",
"test_url":"https://www.caniemail.com/tests/css-selectors-pseudo-classes.html",
"test_results_url":"https://app.emailonacid.com/app/acidtest/cl8ZYgIGE372fkVVuJkwNJDd7B4JUpo23Nz6qANcSlRUA/list",
"stats":{"apple-mail":{"macos":{"12.4":"n"},"ios":{"13.1":"n"}},"gmail":{"desktop-webmail":{"2019-10":"n"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"},"mobile-webmail":{"2020-02":"n"}},"orange":{"desktop-webmail":{"2019-10":"y","2021-03":"n #2"},"ios":{"2019-10":"n"},"android":{"2019-10":"y"}},"outlook":{"windows":{"2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"windows-mail":{"2019-10":"n"},"macos":{"2019-02":"y","16.80":"a #1 #2"},"outlook-com":{"2019-10":"a #1 #2","2024-01":"a #1 #2"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"thunderbird":{"macos":{"60.8":"y"}},"yahoo":{"desktop-webmail":{"2019-02":"y"},"ios":{"2019-02":"y"},"android":{"2019-02":"y"}},"aol":{"desktop-webmail":{"2019-02":"y"},"ios":{"2019-02":"n"},"android":{"2019-02":"y"}},"samsung-email":{"android":{"6.0.04.6":"y"}},"sfr":{"desktop-webmail":{"2020-01":"y"},"ios":{"2020-01":"n"},"android":{"2020-01":"n"}},"protonmail":{"desktop-webmail":{"2020-03":"n"},"ios":{"2020-03":"n"},"android":{"2020-03":"y"}},"hey":{"desktop-webmail":{"2020-06":"n"}},"mail-ru":{"desktop-webmail":{"2020-10":"n"}},"fastmail":{"desktop-webmail":{"2021-07":"n #2"}},"laposte":{"desktop-webmail":{"2021-08":"n #2"}},"gmx":{"desktop-webmail":{"2022-07":"y"},"ios":{"2022-07":"y"},"android":{"2022-07":"n"}},"web-de":{"desktop-webmail":{"2022-07":"y"},"ios":{"2022-07":"y"},"android":{"2022-07":"n"}},"ionos-1and1":{"desktop-webmail":{"2022-07":"n"},"android":{"2022-07":"n"}}},
"stats":{"apple-mail":{"macos":{"12.4":"n"},"ios":{"13.1":"n"}},"gmail":{"desktop-webmail":{"2019-10":"n"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"},"mobile-webmail":{"2020-02":"n"}},"orange":{"desktop-webmail":{"2019-10":"y","2021-03":"n #2"},"ios":{"2019-10":"n"},"android":{"2019-10":"y"}},"outlook":{"windows":{"2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"windows-mail":{"2019-10":"n"},"macos":{"2019-02":"y","16.80":"a #1 #2"},"outlook-com":{"2019-10":"a #1 #2","2024-01":"a #1 #2"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"thunderbird":{"macos":{"60.8":"y"}},"yahoo":{"desktop-webmail":{"2019-02":"y"},"ios":{"2019-02":"y"},"android":{"2019-02":"y"}},"aol":{"desktop-webmail":{"2019-02":"y"},"ios":{"2019-02":"n"},"android":{"2019-02":"y"}},"samsung-email":{"android":{"6.0.04.6":"y"}},"sfr":{"desktop-webmail":{"2020-01":"y","2025-07":"n"},"ios":{"2020-01":"n"},"android":{"2020-01":"n"}},"protonmail":{"desktop-webmail":{"2020-03":"n"},"ios":{"2020-03":"n"},"android":{"2020-03":"y"}},"hey":{"desktop-webmail":{"2020-06":"n"}},"mail-ru":{"desktop-webmail":{"2020-10":"n"}},"fastmail":{"desktop-webmail":{"2021-07":"n #2"}},"laposte":{"desktop-webmail":{"2021-08":"n #2","2025-07":"n"}},"gmx":{"desktop-webmail":{"2022-07":"y"},"ios":{"2022-07":"y"},"android":{"2022-07":"n"}},"web-de":{"desktop-webmail":{"2022-07":"y"},"ios":{"2022-07":"y"},"android":{"2022-07":"n"}},"ionos-1and1":{"desktop-webmail":{"2022-07":"n"},"android":{"2022-07":"n"}}},
"notes":null,
"notes_by_num":{"1":"Partial. Only supported on type selectors.","2":"Buggy. Not filtered but doesn't work."}
},
@@ -2126,7 +2142,7 @@
"last_test_date":"2019-10-28",
"test_url":"https://www.caniemail.com/tests/css-selectors-pseudo-classes.html",
"test_results_url":"https://app.emailonacid.com/app/acidtest/cl8ZYgIGE372fkVVuJkwNJDd7B4JUpo23Nz6qANcSlRUA/list",
"stats":{"apple-mail":{"macos":{"12.4":"n"},"ios":{"13.1":"n"}},"gmail":{"desktop-webmail":{"2019-10":"n"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"},"mobile-webmail":{"2020-02":"n"}},"orange":{"desktop-webmail":{"2019-10":"y","2021-03":"y"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"}},"outlook":{"windows":{"2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"windows-mail":{"2019-10":"n"},"macos":{"2019-02":"y","16.80":"a #1"},"outlook-com":{"2019-10":"a #1","2024-01":"a #1"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"thunderbird":{"macos":{"60.8":"y"}},"yahoo":{"desktop-webmail":{"2019-02":"y"},"ios":{"2019-02":"y"},"android":{"2019-02":"y"}},"aol":{"desktop-webmail":{"2019-02":"y"},"ios":{"2019-02":"n"},"android":{"2019-02":"y"}},"samsung-email":{"android":{"6.0.04.6":"n"}},"sfr":{"desktop-webmail":{"2020-01":"y"},"ios":{"2020-01":"n"},"android":{"2020-01":"n"}},"protonmail":{"desktop-webmail":{"2020-03":"n"},"ios":{"2020-03":"n"},"android":{"2020-03":"n"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"n"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"y"}},"gmx":{"desktop-webmail":{"2022-07":"y"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"}},"web-de":{"desktop-webmail":{"2022-07":"y"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"}},"ionos-1and1":{"desktop-webmail":{"2022-07":"y"},"android":{"2022-07":"n"}}},
"stats":{"apple-mail":{"macos":{"12.4":"n"},"ios":{"13.1":"n"}},"gmail":{"desktop-webmail":{"2019-10":"n"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"},"mobile-webmail":{"2020-02":"n"}},"orange":{"desktop-webmail":{"2019-10":"y","2021-03":"y"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"}},"outlook":{"windows":{"2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"windows-mail":{"2019-10":"n"},"macos":{"2019-02":"y","16.80":"a #1"},"outlook-com":{"2019-10":"a #1","2024-01":"a #1"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"thunderbird":{"macos":{"60.8":"y"}},"yahoo":{"desktop-webmail":{"2019-02":"y"},"ios":{"2019-02":"y"},"android":{"2019-02":"y"}},"aol":{"desktop-webmail":{"2019-02":"y"},"ios":{"2019-02":"n"},"android":{"2019-02":"y"}},"samsung-email":{"android":{"6.0.04.6":"n"}},"sfr":{"desktop-webmail":{"2020-01":"y","2025-07":"n"},"ios":{"2020-01":"n"},"android":{"2020-01":"n"}},"protonmail":{"desktop-webmail":{"2020-03":"n"},"ios":{"2020-03":"n"},"android":{"2020-03":"n"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"n"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"y","2025-07":"n"}},"gmx":{"desktop-webmail":{"2022-07":"y"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"}},"web-de":{"desktop-webmail":{"2022-07":"y"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"}},"ionos-1and1":{"desktop-webmail":{"2022-07":"y"},"android":{"2022-07":"n"}}},
"notes":null,
"notes_by_num":{"1":"Partial. Only supported on type selectors."}
},
@@ -2142,7 +2158,7 @@
"last_test_date":"2020-05-21",
"test_url":"https://www.caniemail.com/tests/css-pseudo-elements.html",
"test_results_url":"https://app.emailonacid.com/app/acidtest/qXO9EwD1KSCSCrmUEccVDxVOl3Cyc4LPAbb83ElW2OFge/list",
"stats":{"apple-mail":{"macos":{"13":"y"},"ios":{"13":"y"}},"gmail":{"desktop-webmail":{"2020-05":"n"},"ios":{"2020-05":"n"},"android":{"2020-05":"n"},"mobile-webmail":{"2020-05":"n"}},"orange":{"desktop-webmail":{"2020-05":"y","2021-03":"n #2","2024-04":"n #2"},"ios":{"2020-05":"y","2024-04":"n"},"android":{"2020-05":"n","2024-04":"n"}},"outlook":{"windows":{"2003":"n","2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"windows-mail":{"2020-05":"n"},"macos":{"2011":"y","2016":"y","2019":"a #1","16.80":"a #1 #3"},"outlook-com":{"2020-05":"n","2024-01":"a #3"},"ios":{"2.51.1":"y","4.38.0":"n","4.2352.0":"a #3"},"android":{"2020-05":"n"}},"samsung-email":{"android":{"6.0":"y"}},"sfr":{"desktop-webmail":{"2020-05":"y"},"ios":{"2020-05":"n"},"android":{"2020-05":"n"}},"thunderbird":{"macos":{"68.8":"y"}},"aol":{"desktop-webmail":{"2020-05":"n"},"ios":{"2020-05":"n"},"android":{"2020-05":"n"}},"yahoo":{"desktop-webmail":{"2020-05":"n"},"ios":{"2020-05":"n"},"android":{"2020-05":"n"}},"protonmail":{"desktop-webmail":{"2020-05":"n"},"ios":{"2020-05":"n"},"android":{"2020-05":"y"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"n"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"y"}},"gmx":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"web-de":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-07":"y"},"android":{"2022-07":"y"}}},
"stats":{"apple-mail":{"macos":{"13":"y"},"ios":{"13":"y"}},"gmail":{"desktop-webmail":{"2020-05":"n"},"ios":{"2020-05":"n"},"android":{"2020-05":"n"},"mobile-webmail":{"2020-05":"n"}},"orange":{"desktop-webmail":{"2020-05":"y","2021-03":"n #2","2024-04":"n #2"},"ios":{"2020-05":"y","2024-04":"n"},"android":{"2020-05":"n","2024-04":"n"}},"outlook":{"windows":{"2003":"n","2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"windows-mail":{"2020-05":"n"},"macos":{"2011":"y","2016":"y","2019":"a #1","16.80":"a #1 #3"},"outlook-com":{"2020-05":"n","2024-01":"a #3"},"ios":{"2.51.1":"y","4.38.0":"n","4.2352.0":"a #3"},"android":{"2020-05":"n"}},"samsung-email":{"android":{"6.0":"y"}},"sfr":{"desktop-webmail":{"2020-05":"y","2025-07":"n"},"ios":{"2020-05":"n"},"android":{"2020-05":"n"}},"thunderbird":{"macos":{"68.8":"y"}},"aol":{"desktop-webmail":{"2020-05":"n"},"ios":{"2020-05":"n"},"android":{"2020-05":"n"}},"yahoo":{"desktop-webmail":{"2020-05":"n"},"ios":{"2020-05":"n"},"android":{"2020-05":"n"}},"protonmail":{"desktop-webmail":{"2020-05":"n"},"ios":{"2020-05":"n"},"android":{"2020-05":"y"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"n"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"y","2025-07":"n"}},"gmx":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"web-de":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-07":"y"},"android":{"2022-07":"y"}}},
"notes":null,
"notes_by_num":{"1":"Not supported with non Outlook accounts.","2":"The pseudo-element is supported but the `content` property is not.","3":"Partial. Only supported on type selectors."}
},
@@ -2158,7 +2174,7 @@
"last_test_date":"2020-05-21",
"test_url":"https://www.caniemail.com/tests/css-pseudo-elements.html",
"test_results_url":"https://app.emailonacid.com/app/acidtest/qXO9EwD1KSCSCrmUEccVDxVOl3Cyc4LPAbb83ElW2OFge/list",
"stats":{"apple-mail":{"macos":{"13":"y"},"ios":{"13":"y"}},"gmail":{"desktop-webmail":{"2020-05":"n"},"ios":{"2020-05":"n"},"android":{"2020-05":"n"},"mobile-webmail":{"2020-05":"n"}},"orange":{"desktop-webmail":{"2020-05":"y","2021-03":"n #2","2024-04":"n #2"},"ios":{"2020-05":"y","2024-04":"n"},"android":{"2020-05":"n","2024-04":"n"}},"outlook":{"windows":{"2003":"n","2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"windows-mail":{"2020-05":"n"},"macos":{"2011":"y","2016":"y","2019":"a #1","16.80":"a #1 #3"},"outlook-com":{"2020-05":"n","2024-01":"a #3"},"ios":{"2.51.1":"y","4.38.0":"n","4.2352.0":"a #3"},"android":{"2020-05":"n"}},"samsung-email":{"android":{"6.0":"y"}},"sfr":{"desktop-webmail":{"2020-05":"y"},"ios":{"2020-05":"n"},"android":{"2020-05":"n"}},"thunderbird":{"macos":{"68.8":"y"}},"aol":{"desktop-webmail":{"2020-05":"n"},"ios":{"2020-05":"n"},"android":{"2020-05":"n"}},"yahoo":{"desktop-webmail":{"2020-05":"n"},"ios":{"2020-05":"n"},"android":{"2020-05":"n"}},"protonmail":{"desktop-webmail":{"2020-05":"n"},"ios":{"2020-05":"n"},"android":{"2020-05":"y"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"n"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"y"}},"gmx":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"web-de":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-07":"y"},"android":{"2022-07":"y"}}},
"stats":{"apple-mail":{"macos":{"13":"y"},"ios":{"13":"y"}},"gmail":{"desktop-webmail":{"2020-05":"n"},"ios":{"2020-05":"n"},"android":{"2020-05":"n"},"mobile-webmail":{"2020-05":"n"}},"orange":{"desktop-webmail":{"2020-05":"y","2021-03":"n #2","2024-04":"n #2"},"ios":{"2020-05":"y","2024-04":"n"},"android":{"2020-05":"n","2024-04":"n"}},"outlook":{"windows":{"2003":"n","2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"windows-mail":{"2020-05":"n"},"macos":{"2011":"y","2016":"y","2019":"a #1","16.80":"a #1 #3"},"outlook-com":{"2020-05":"n","2024-01":"a #3"},"ios":{"2.51.1":"y","4.38.0":"n","4.2352.0":"a #3"},"android":{"2020-05":"n"}},"samsung-email":{"android":{"6.0":"y"}},"sfr":{"desktop-webmail":{"2020-05":"y","2025-07":"n"},"ios":{"2020-05":"n"},"android":{"2020-05":"n"}},"thunderbird":{"macos":{"68.8":"y"}},"aol":{"desktop-webmail":{"2020-05":"n"},"ios":{"2020-05":"n"},"android":{"2020-05":"n"}},"yahoo":{"desktop-webmail":{"2020-05":"n"},"ios":{"2020-05":"n"},"android":{"2020-05":"n"}},"protonmail":{"desktop-webmail":{"2020-05":"n"},"ios":{"2020-05":"n"},"android":{"2020-05":"y"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"n"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"y","2025-07":"n"}},"gmx":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"web-de":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-07":"y"},"android":{"2022-07":"y"}}},
"notes":null,
"notes_by_num":{"1":"Not supported with non Outlook accounts.","2":"The pseudo-element is supported but the `content` property is not.","3":"Partial. Only supported on type selectors."}
},
@@ -2174,7 +2190,7 @@
"last_test_date":"2020-05-21",
"test_url":"https://www.caniemail.com/tests/css-pseudo-elements.html",
"test_results_url":"https://app.emailonacid.com/app/acidtest/qXO9EwD1KSCSCrmUEccVDxVOl3Cyc4LPAbb83ElW2OFge/list",
"stats":{"apple-mail":{"macos":{"13":"y"},"ios":{"13":"y"}},"gmail":{"desktop-webmail":{"2020-05":"n"},"ios":{"2020-05":"n"},"android":{"2020-05":"n"},"mobile-webmail":{"2020-05":"n"}},"orange":{"desktop-webmail":{"2020-05":"y","2021-03":"y"},"ios":{"2020-05":"y"},"android":{"2020-05":"n"}},"outlook":{"windows":{"2003":"y","2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"windows-mail":{"2020-05":"n"},"macos":{"2011":"y","2016":"y","2019":"a #1","16.80":"a #1 #2"},"outlook-com":{"2020-05":"n","2024-01":"a #2"},"ios":{"2.51.1":"y","4.38.0":"n","4.2352.0":"a #2"},"android":{"2020-05":"n"}},"samsung-email":{"android":{"6.0":"y"}},"sfr":{"desktop-webmail":{"2020-05":"y"},"ios":{"2020-05":"n"},"android":{"2020-05":"n"}},"thunderbird":{"macos":{"68.8":"y"}},"aol":{"desktop-webmail":{"2020-05":"y"},"ios":{"2020-05":"y"},"android":{"2020-05":"y"}},"yahoo":{"desktop-webmail":{"2020-05":"y"},"ios":{"2020-05":"y"},"android":{"2020-05":"y"}},"protonmail":{"desktop-webmail":{"2020-05":"n"},"ios":{"2020-05":"n"},"android":{"2020-05":"y"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"n"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"y"}},"gmx":{"desktop-webmail":{"2022-07":"y"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"web-de":{"desktop-webmail":{"2022-07":"y"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-07":"y"},"android":{"2022-07":"y"}}},
"stats":{"apple-mail":{"macos":{"13":"y"},"ios":{"13":"y"}},"gmail":{"desktop-webmail":{"2020-05":"n"},"ios":{"2020-05":"n"},"android":{"2020-05":"n"},"mobile-webmail":{"2020-05":"n"}},"orange":{"desktop-webmail":{"2020-05":"y","2021-03":"y"},"ios":{"2020-05":"y"},"android":{"2020-05":"n"}},"outlook":{"windows":{"2003":"y","2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"windows-mail":{"2020-05":"n"},"macos":{"2011":"y","2016":"y","2019":"a #1","16.80":"a #1 #2"},"outlook-com":{"2020-05":"n","2024-01":"a #2"},"ios":{"2.51.1":"y","4.38.0":"n","4.2352.0":"a #2"},"android":{"2020-05":"n"}},"samsung-email":{"android":{"6.0":"y"}},"sfr":{"desktop-webmail":{"2020-05":"y","2025-07":"n"},"ios":{"2020-05":"n"},"android":{"2020-05":"n"}},"thunderbird":{"macos":{"68.8":"y"}},"aol":{"desktop-webmail":{"2020-05":"y"},"ios":{"2020-05":"y"},"android":{"2020-05":"y"}},"yahoo":{"desktop-webmail":{"2020-05":"y"},"ios":{"2020-05":"y"},"android":{"2020-05":"y"}},"protonmail":{"desktop-webmail":{"2020-05":"n"},"ios":{"2020-05":"n"},"android":{"2020-05":"y"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"n"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"y","2025-07":"n"}},"gmx":{"desktop-webmail":{"2022-07":"y"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"web-de":{"desktop-webmail":{"2022-07":"y"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-07":"y"},"android":{"2022-07":"y"}}},
"notes":null,
"notes_by_num":{"1":"Not supported with non Outlook accounts.","2":"Partial. Only supported on type selectors."}
},
@@ -2190,7 +2206,7 @@
"last_test_date":"2020-05-21",
"test_url":"https://www.caniemail.com/tests/css-pseudo-elements.html",
"test_results_url":"https://app.emailonacid.com/app/acidtest/qXO9EwD1KSCSCrmUEccVDxVOl3Cyc4LPAbb83ElW2OFge/list",
"stats":{"apple-mail":{"macos":{"13":"y"},"ios":{"13":"y"}},"gmail":{"desktop-webmail":{"2020-05":"n"},"ios":{"2020-05":"n"},"android":{"2020-05":"n"},"mobile-webmail":{"2020-05":"n"}},"orange":{"desktop-webmail":{"2020-05":"y","2021-03":"y"},"ios":{"2020-05":"y"},"android":{"2020-05":"n"}},"outlook":{"windows":{"2003":"y","2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"windows-mail":{"2020-05":"n"},"macos":{"2011":"y","2016":"y","2019":"a #1","16.80":"a #1 #2"},"outlook-com":{"2020-05":"n","2024-01":"a #2"},"ios":{"2.51.1":"y","4.38.0":"n","4.2352.0":"a #2"},"android":{"2020-05":"n"}},"samsung-email":{"android":{"6.0":"y"}},"sfr":{"desktop-webmail":{"2020-05":"y"},"ios":{"2020-05":"n"},"android":{"2020-05":"n"}},"thunderbird":{"macos":{"68.8":"y"}},"aol":{"desktop-webmail":{"2020-05":"y"},"ios":{"2020-05":"y"},"android":{"2020-05":"y"}},"yahoo":{"desktop-webmail":{"2020-05":"y"},"ios":{"2020-05":"y"},"android":{"2020-05":"y"}},"protonmail":{"desktop-webmail":{"2020-05":"n"},"ios":{"2020-05":"n"},"android":{"2020-05":"y"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"n"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"y"}},"gmx":{"desktop-webmail":{"2022-07":"y"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"web-de":{"desktop-webmail":{"2022-07":"y"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-07":"y"},"android":{"2022-07":"y"}}},
"stats":{"apple-mail":{"macos":{"13":"y"},"ios":{"13":"y"}},"gmail":{"desktop-webmail":{"2020-05":"n"},"ios":{"2020-05":"n"},"android":{"2020-05":"n"},"mobile-webmail":{"2020-05":"n"}},"orange":{"desktop-webmail":{"2020-05":"y","2021-03":"y"},"ios":{"2020-05":"y"},"android":{"2020-05":"n"}},"outlook":{"windows":{"2003":"y","2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"windows-mail":{"2020-05":"n"},"macos":{"2011":"y","2016":"y","2019":"a #1","16.80":"a #1 #2"},"outlook-com":{"2020-05":"n","2024-01":"a #2"},"ios":{"2.51.1":"y","4.38.0":"n","4.2352.0":"a #2"},"android":{"2020-05":"n"}},"samsung-email":{"android":{"6.0":"y"}},"sfr":{"desktop-webmail":{"2020-05":"y","2025-07":"n"},"ios":{"2020-05":"n"},"android":{"2020-05":"n"}},"thunderbird":{"macos":{"68.8":"y"}},"aol":{"desktop-webmail":{"2020-05":"y"},"ios":{"2020-05":"y"},"android":{"2020-05":"y"}},"yahoo":{"desktop-webmail":{"2020-05":"y"},"ios":{"2020-05":"y"},"android":{"2020-05":"y"}},"protonmail":{"desktop-webmail":{"2020-05":"n"},"ios":{"2020-05":"n"},"android":{"2020-05":"y"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"n"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"y","2025-07":"n"}},"gmx":{"desktop-webmail":{"2022-07":"y"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"web-de":{"desktop-webmail":{"2022-07":"y"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-07":"y"},"android":{"2022-07":"y"}}},
"notes":null,
"notes_by_num":{"1":"Not supported with non Outlook accounts.","2":"Partial. Only supported on type selectors."}
},
@@ -2206,7 +2222,7 @@
"last_test_date":"2022-12-28",
"test_url":"https://www.caniemail.com/tests/css-marker.html",
"test_results_url":"https://app.emailonacid.com/app/acidtest/7ebtlnke6f0814MElvJWzdRU5lTKcZULpbP9ef9OCuxv3/list",
"stats":{"apple-mail":{"macos":{"13":"y"},"ios":{"16.2":"y"}},"gmail":{"desktop-webmail":{"2022-12":"n"},"ios":{"2022-12":"n"},"android":{"2022-12":"n"},"mobile-webmail":{"2022-12":"n"}},"orange":{"desktop-webmail":{"2022-12":"y"},"ios":{"2022-12":"y"},"android":{"2022-12":"n"}},"outlook":{"windows":{"2003":"n","2007":"n","2010":"n","2013":"n","2016":"n","2019":"n #1"},"windows-mail":{"2022-12":"n"},"macos":{"2022-12":"y","16.80":"n"},"outlook-com":{"2022-12":"n","2024-01":"n"},"ios":{"2022-12":"n","2024-01":"n"},"android":{"2022-12":"n"}},"samsung-email":{"android":{"6.0":"y"}},"sfr":{"desktop-webmail":{"2022-12":"y"},"ios":{"2022-12":"n"},"android":{"2022-12":"n"}},"thunderbird":{"macos":{"102.6":"y"}},"aol":{"desktop-webmail":{"2022-12":"y"},"ios":{"2022-12":"y"},"android":{"2022-12":"y"}},"yahoo":{"desktop-webmail":{"2022-12":"y"},"ios":{"2022-12":"y"},"android":{"2022-12":"y"}},"protonmail":{"desktop-webmail":{"2022-12":"y"},"ios":{"2022-12":"y"},"android":{"2022-12":"n"}},"hey":{"desktop-webmail":{"2022-12":"y"}},"mail-ru":{"desktop-webmail":{"2022-12":"n"}},"fastmail":{"desktop-webmail":{"2022-12":"y"}},"laposte":{"desktop-webmail":{"2022-12":"y"}}},
"stats":{"apple-mail":{"macos":{"13":"y"},"ios":{"16.2":"y"}},"gmail":{"desktop-webmail":{"2022-12":"n"},"ios":{"2022-12":"n"},"android":{"2022-12":"n"},"mobile-webmail":{"2022-12":"n"}},"orange":{"desktop-webmail":{"2022-12":"y"},"ios":{"2022-12":"y"},"android":{"2022-12":"n"}},"outlook":{"windows":{"2003":"n","2007":"n","2010":"n","2013":"n","2016":"n","2019":"n #1"},"windows-mail":{"2022-12":"n"},"macos":{"2022-12":"y","16.80":"n"},"outlook-com":{"2022-12":"n","2024-01":"n"},"ios":{"2022-12":"n","2024-01":"n"},"android":{"2022-12":"n"}},"samsung-email":{"android":{"6.0":"y"}},"sfr":{"desktop-webmail":{"2022-12":"y","2025-07":"n"},"ios":{"2022-12":"n"},"android":{"2022-12":"n"}},"thunderbird":{"macos":{"102.6":"y"}},"aol":{"desktop-webmail":{"2022-12":"y"},"ios":{"2022-12":"y"},"android":{"2022-12":"y"}},"yahoo":{"desktop-webmail":{"2022-12":"y"},"ios":{"2022-12":"y"},"android":{"2022-12":"y"}},"protonmail":{"desktop-webmail":{"2022-12":"y"},"ios":{"2022-12":"y"},"android":{"2022-12":"n"}},"hey":{"desktop-webmail":{"2022-12":"y"}},"mail-ru":{"desktop-webmail":{"2022-12":"n"}},"fastmail":{"desktop-webmail":{"2022-12":"y"}},"laposte":{"desktop-webmail":{"2022-12":"y","2025-07":"n"}}},
"notes":null,
"notes_by_num":{"1":"Not supported. But `@list` declarations can achieve the same thing."}
},
@@ -2222,7 +2238,7 @@
"last_test_date":"2020-05-21",
"test_url":"https://www.caniemail.com/tests/css-pseudo-elements.html",
"test_results_url":"https://app.emailonacid.com/app/acidtest/qXO9EwD1KSCSCrmUEccVDxVOl3Cyc4LPAbb83ElW2OFge/list",
"stats":{"apple-mail":{"macos":{"13":"y"},"ios":{"13":"y"}},"gmail":{"desktop-webmail":{"2020-05":"n"},"ios":{"2020-05":"n"},"android":{"2020-05":"n"},"mobile-webmail":{"2020-05":"n"}},"orange":{"desktop-webmail":{"2020-05":"n","2021-03":"n #2"},"ios":{"2020-05":"n"},"android":{"2020-05":"n"}},"outlook":{"windows":{"2003":"n","2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"windows-mail":{"2020-05":"n"},"macos":{"2011":"y","2016":"y","2019":"a #1","16.80":"a #1 #2"},"outlook-com":{"2020-05":"n","2024-01":"a #2"},"ios":{"2.51.1":"y","4.38.0":"n","4.2352.0":"a #2"},"android":{"2020-05":"n"}},"samsung-email":{"android":{"6.0":"y"}},"sfr":{"desktop-webmail":{"2020-05":"n"},"ios":{"2020-05":"n"},"android":{"2020-05":"n"}},"thunderbird":{"macos":{"68.8":"y"}},"aol":{"desktop-webmail":{"2020-05":"y"},"ios":{"2020-05":"y"},"android":{"2020-05":"y"}},"yahoo":{"desktop-webmail":{"2020-05":"y"},"ios":{"2020-05":"y"},"android":{"2020-05":"y"}},"protonmail":{"desktop-webmail":{"2020-05":"n"},"ios":{"2020-05":"n"},"android":{"2020-05":"n"}},"hey":{"desktop-webmail":{"2020-06":"n"}},"mail-ru":{"desktop-webmail":{"2020-10":"n"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"n #2"}},"gmx":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"y"},"android":{"2022-07":"n"}},"web-de":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"y"},"android":{"2022-07":"n"}},"ionos-1and1":{"desktop-webmail":{"2022-07":"n"},"android":{"2022-07":"n"}}},
"stats":{"apple-mail":{"macos":{"13":"y"},"ios":{"13":"y"}},"gmail":{"desktop-webmail":{"2020-05":"n"},"ios":{"2020-05":"n"},"android":{"2020-05":"n"},"mobile-webmail":{"2020-05":"n"}},"orange":{"desktop-webmail":{"2020-05":"n","2021-03":"n #2"},"ios":{"2020-05":"n"},"android":{"2020-05":"n"}},"outlook":{"windows":{"2003":"n","2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"windows-mail":{"2020-05":"n"},"macos":{"2011":"y","2016":"y","2019":"a #1","16.80":"a #1 #2"},"outlook-com":{"2020-05":"n","2024-01":"a #2"},"ios":{"2.51.1":"y","4.38.0":"n","4.2352.0":"a #2"},"android":{"2020-05":"n"}},"samsung-email":{"android":{"6.0":"y"}},"sfr":{"desktop-webmail":{"2020-05":"n","2025-07":"n"},"ios":{"2020-05":"n"},"android":{"2020-05":"n"}},"thunderbird":{"macos":{"68.8":"y"}},"aol":{"desktop-webmail":{"2020-05":"y"},"ios":{"2020-05":"y"},"android":{"2020-05":"y"}},"yahoo":{"desktop-webmail":{"2020-05":"y"},"ios":{"2020-05":"y"},"android":{"2020-05":"y"}},"protonmail":{"desktop-webmail":{"2020-05":"n"},"ios":{"2020-05":"n"},"android":{"2020-05":"n"}},"hey":{"desktop-webmail":{"2020-06":"n"}},"mail-ru":{"desktop-webmail":{"2020-10":"n"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"n #2","2025-07":"n"}},"gmx":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"y"},"android":{"2022-07":"n"}},"web-de":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"y"},"android":{"2022-07":"n"}},"ionos-1and1":{"desktop-webmail":{"2022-07":"n"},"android":{"2022-07":"n"}}},
"notes":null,
"notes_by_num":{"1":"Not supported with non Outlook accounts.","2":"The pseudo-element is supported but `<input>` elements are not.","3":"Partial. Only supported on type selectors."}
},
@@ -2350,7 +2366,7 @@
"last_test_date":"2019-10-13",
"test_url":"https://www.caniemail.com/tests/css-selectors.html",
"test_results_url":"https://app.emailonacid.com/app/acidtest/kQbnzGXMSxMg2NDGmrcxIXOHrROwokTB29RcSssnkoPlS/list",
"stats":{"apple-mail":{"macos":{"12.4":"y"},"ios":{"13.1":"y"}},"gmail":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"a #1"},"android":{"2019-10":"a #1"},"mobile-webmail":{"2020-02":"n"}},"orange":{"desktop-webmail":{"2019-10":"y","2021-03":"n","2024-04":"y"},"ios":{"2019-10":"y","2024-04":"y"},"android":{"2019-10":"y","2024-04":"y"}},"outlook":{"windows":{"2003":"y","2007":"n #3","2010":"n #3","2013":"n #3","2016":"n #3","2019":"n #3"},"windows-mail":{"2019-10":"n #3"},"macos":{"2011":"y","2016":"y","16.80":"y"},"outlook-com":{"2019-10":"n #4","2024-01":"n #4"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"samsung-email":{"android":{"6.0":"y"}},"sfr":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"}},"thunderbird":{"macos":{"60.3":"y"}},"aol":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"yahoo":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"a #2"}},"protonmail":{"desktop-webmail":{"2020-03":"n"},"ios":{"2020-03":"n"},"android":{"2020-03":"y"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"y"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"y"}},"gmx":{"desktop-webmail":{"2022-06":"a #5"},"ios":{"2022-06":"y"},"android":{"2022-06":"y"}},"web-de":{"desktop-webmail":{"2022-06":"a #5"},"ios":{"2022-06":"y"},"android":{"2022-06":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-06":"y"},"android":{"2022-06":"y"}}},
"stats":{"apple-mail":{"macos":{"12.4":"y"},"ios":{"13.1":"y"}},"gmail":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"a #1"},"android":{"2019-10":"a #1"},"mobile-webmail":{"2020-02":"n"}},"orange":{"desktop-webmail":{"2019-10":"y","2021-03":"n","2024-04":"y"},"ios":{"2019-10":"y","2024-04":"y"},"android":{"2019-10":"y","2024-04":"y"}},"outlook":{"windows":{"2003":"y","2007":"n #3","2010":"n #3","2013":"n #3","2016":"n #3","2019":"n #3"},"windows-mail":{"2019-10":"n #3"},"macos":{"2011":"y","2016":"y","16.80":"y"},"outlook-com":{"2019-10":"n #4","2024-01":"n #4"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"samsung-email":{"android":{"6.0":"y"}},"sfr":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"}},"thunderbird":{"macos":{"60.3":"y"}},"aol":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"yahoo":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"a #2","2025-06":"y"}},"protonmail":{"desktop-webmail":{"2020-03":"n"},"ios":{"2020-03":"n"},"android":{"2020-03":"y"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"y"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"y"}},"gmx":{"desktop-webmail":{"2022-06":"a #5"},"ios":{"2022-06":"y"},"android":{"2022-06":"y"}},"web-de":{"desktop-webmail":{"2022-06":"a #5"},"ios":{"2022-06":"y"},"android":{"2022-06":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-06":"y"},"android":{"2022-06":"y"}}},
"notes":null,
"notes_by_num":{"1":"Partial. Not supported with non Google accounts.","2":"Buggy. The first `<head>` in the HTML is removed, so `<style>` elements need to be in a second `<head>` element.","3":"Buggy. Styles will be applied to the first selector of the chain.","4":"Buggy. Only the first selector of the chain is prefixed in the styles, but all classes are prefixed in the HTML.","5":"Partial. Only when used as class or ID selectors"}
},
@@ -2366,7 +2382,7 @@
"last_test_date":"2019-10-13",
"test_url":"https://www.caniemail.com/tests/css-selectors.html",
"test_results_url":"https://app.emailonacid.com/app/acidtest/kQbnzGXMSxMg2NDGmrcxIXOHrROwokTB29RcSssnkoPlS/list",
"stats":{"apple-mail":{"macos":{"12.4":"y"},"ios":{"13.1":"y"}},"gmail":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"a #1"},"android":{"2019-10":"a #1"},"mobile-webmail":{"2020-02":"n"}},"orange":{"desktop-webmail":{"2019-10":"y","2021-03":"n"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"outlook":{"windows":{"2003":"y","2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"windows-mail":{"2023-06":"n"},"macos":{"2011":"y","2016":"y","16.80":"y"},"outlook-com":{"2019-10":"y","2024-01":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"samsung-email":{"android":{"6.0":"y"}},"sfr":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"}},"thunderbird":{"macos":{"60.3":"y"}},"aol":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"yahoo":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"a #2"}},"protonmail":{"desktop-webmail":{"2020-03":"n"},"ios":{"2020-03":"n"},"android":{"2020-03":"y"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"y"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"y"}},"gmx":{"desktop-webmail":{"2022-06":"n"},"ios":{"2022-06":"y"},"android":{"2022-06":"y"}},"web-de":{"desktop-webmail":{"2022-06":"n"},"ios":{"2022-06":"y"},"android":{"2022-06":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-06":"y"},"android":{"2022-06":"y"}}},
"stats":{"apple-mail":{"macos":{"12.4":"y"},"ios":{"13.1":"y"}},"gmail":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"a #1"},"android":{"2019-10":"a #1"},"mobile-webmail":{"2020-02":"n"}},"orange":{"desktop-webmail":{"2019-10":"y","2021-03":"n"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"outlook":{"windows":{"2003":"y","2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"windows-mail":{"2023-06":"n"},"macos":{"2011":"y","2016":"y","16.80":"y"},"outlook-com":{"2019-10":"y","2024-01":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"samsung-email":{"android":{"6.0":"y"}},"sfr":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"}},"thunderbird":{"macos":{"60.3":"y"}},"aol":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"yahoo":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"a #2","2025-06":"y"}},"protonmail":{"desktop-webmail":{"2020-03":"n"},"ios":{"2020-03":"n"},"android":{"2020-03":"y"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"y"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"y"}},"gmx":{"desktop-webmail":{"2022-06":"n"},"ios":{"2022-06":"y"},"android":{"2022-06":"y"}},"web-de":{"desktop-webmail":{"2022-06":"n"},"ios":{"2022-06":"y"},"android":{"2022-06":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-06":"y"},"android":{"2022-06":"y"}}},
"notes":null,
"notes_by_num":{"1":"Partial. Not supported with non Google accounts.","2":"Buggy. The first `<head>` in the HTML is removed, so `<style>` elements need to be in a second `<head>` element."}
},
@@ -2382,7 +2398,7 @@
"last_test_date":"2019-10-13",
"test_url":"https://www.caniemail.com/tests/css-selectors.html",
"test_results_url":"https://app.emailonacid.com/app/acidtest/kQbnzGXMSxMg2NDGmrcxIXOHrROwokTB29RcSssnkoPlS/list",
"stats":{"apple-mail":{"macos":{"12.4":"y"},"ios":{"13.1":"y"}},"gmail":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"a #1"},"android":{"2019-10":"a #1"},"mobile-webmail":{"2020-02":"n"}},"orange":{"desktop-webmail":{"2019-10":"y","2021-03":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"outlook":{"windows":{"2003":"y","2007":"y","2010":"y","2013":"y","2016":"y","2019":"y"},"windows-mail":{"2019-10":"y"},"macos":{"2011":"y","2016":"y","16.80":"y"},"outlook-com":{"2019-10":"y","2024-01":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"samsung-email":{"android":{"6.0":"y"}},"sfr":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"}},"thunderbird":{"macos":{"60.3":"y"}},"aol":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"yahoo":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"a #2"}},"protonmail":{"desktop-webmail":{"2020-03":"n"},"ios":{"2020-03":"n"},"android":{"2020-03":"y"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"y"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"y"}},"gmx":{"desktop-webmail":{"2022-06":"y"},"ios":{"2022-06":"y"},"android":{"2022-06":"y"}},"web-de":{"desktop-webmail":{"2022-06":"y"},"ios":{"2022-06":"y"},"android":{"2022-06":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-06":"y"},"android":{"2022-06":"y"}}},
"stats":{"apple-mail":{"macos":{"12.4":"y"},"ios":{"13.1":"y"}},"gmail":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"a #1"},"android":{"2019-10":"a #1"},"mobile-webmail":{"2020-02":"n"}},"orange":{"desktop-webmail":{"2019-10":"y","2021-03":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"outlook":{"windows":{"2003":"y","2007":"y","2010":"y","2013":"y","2016":"y","2019":"y"},"windows-mail":{"2019-10":"y"},"macos":{"2011":"y","2016":"y","16.80":"y"},"outlook-com":{"2019-10":"y","2024-01":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"samsung-email":{"android":{"6.0":"y"}},"sfr":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"}},"thunderbird":{"macos":{"60.3":"y"}},"aol":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"yahoo":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"a #2","2025-06":"y"}},"protonmail":{"desktop-webmail":{"2020-03":"n"},"ios":{"2020-03":"n"},"android":{"2020-03":"y"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"y"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"y"}},"gmx":{"desktop-webmail":{"2022-06":"y"},"ios":{"2022-06":"y"},"android":{"2022-06":"y"}},"web-de":{"desktop-webmail":{"2022-06":"y"},"ios":{"2022-06":"y"},"android":{"2022-06":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-06":"y"},"android":{"2022-06":"y"}}},
"notes":null,
"notes_by_num":{"1":"Partial. Not supported with non Google accounts.","2":"Buggy. The first `<head>` in the HTML is removed, so `<style>` elements need to be in a second `<head>` element."}
},
@@ -2398,7 +2414,7 @@
"last_test_date":"2019-10-13",
"test_url":"https://www.caniemail.com/tests/css-selectors.html",
"test_results_url":"https://app.emailonacid.com/app/acidtest/kQbnzGXMSxMg2NDGmrcxIXOHrROwokTB29RcSssnkoPlS/list",
"stats":{"apple-mail":{"macos":{"12.4":"y"},"ios":{"13.1":"y"}},"gmail":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"a #1"},"android":{"2019-10":"a #1"},"mobile-webmail":{"2020-02":"n"}},"orange":{"desktop-webmail":{"2019-10":"y","2021-03":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"outlook":{"windows":{"2003":"y","2007":"y","2010":"y","2013":"y","2016":"y","2019":"y"},"windows-mail":{"2019-10":"y"},"macos":{"2011":"y","2016":"y","16.80":"y"},"outlook-com":{"2019-10":"y","2024-01":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"samsung-email":{"android":{"6.0":"y"}},"sfr":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"}},"thunderbird":{"macos":{"60.3":"y"}},"aol":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"yahoo":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"a #2"}},"protonmail":{"desktop-webmail":{"2020-03":"n"},"ios":{"2020-03":"n"},"android":{"2020-03":"y"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"y"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"y"}},"gmx":{"desktop-webmail":{"2022-06":"a #3"},"ios":{"2022-06":"y"},"android":{"2022-06":"y"}},"web-de":{"desktop-webmail":{"2022-06":"a #3"},"ios":{"2022-06":"y"},"android":{"2022-06":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-06":"y"},"android":{"2022-06":"y"}}},
"stats":{"apple-mail":{"macos":{"12.4":"y"},"ios":{"13.1":"y"}},"gmail":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"a #1"},"android":{"2019-10":"a #1"},"mobile-webmail":{"2020-02":"n"}},"orange":{"desktop-webmail":{"2019-10":"y","2021-03":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"outlook":{"windows":{"2003":"y","2007":"y","2010":"y","2013":"y","2016":"y","2019":"y"},"windows-mail":{"2019-10":"y"},"macos":{"2011":"y","2016":"y","16.80":"y"},"outlook-com":{"2019-10":"y","2024-01":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"samsung-email":{"android":{"6.0":"y"}},"sfr":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"}},"thunderbird":{"macos":{"60.3":"y"}},"aol":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"yahoo":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"a #2","2025-06":"y"}},"protonmail":{"desktop-webmail":{"2020-03":"n"},"ios":{"2020-03":"n"},"android":{"2020-03":"y"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"y"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"y"}},"gmx":{"desktop-webmail":{"2022-06":"a #3"},"ios":{"2022-06":"y"},"android":{"2022-06":"y"}},"web-de":{"desktop-webmail":{"2022-06":"a #3"},"ios":{"2022-06":"y"},"android":{"2022-06":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-06":"y"},"android":{"2022-06":"y"}}},
"notes":null,
"notes_by_num":{"1":"Partial. Not supported with non Google accounts.","2":"Buggy. The first `<head>` in the HTML is removed, so `<style>` elements need to be in a second `<head>` element.","3":"Partial. Only when used as class or ID selectors"}
},
@@ -2430,7 +2446,7 @@
"last_test_date":"2019-10-13",
"test_url":"https://www.caniemail.com/tests/css-selectors.html",
"test_results_url":"https://app.emailonacid.com/app/acidtest/kQbnzGXMSxMg2NDGmrcxIXOHrROwokTB29RcSssnkoPlS/list",
"stats":{"apple-mail":{"macos":{"12.4":"y"},"ios":{"13.1":"y"}},"gmail":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"a #1"},"android":{"2019-10":"a #1"},"mobile-webmail":{"2020-02":"n"}},"orange":{"desktop-webmail":{"2019-10":"y","2021-03":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"outlook":{"windows":{"2003":"y","2007":"y","2010":"y","2013":"y","2016":"y","2019":"y"},"windows-mail":{"2019-10":"y"},"macos":{"2011":"y","2016":"y","16.80":"y"},"outlook-com":{"2019-10":"y","2024-01":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"samsung-email":{"android":{"6.0":"y"}},"sfr":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"}},"thunderbird":{"macos":{"60.3":"y"}},"aol":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"yahoo":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"a #2"}},"protonmail":{"desktop-webmail":{"2020-03":"n"},"ios":{"2020-03":"n"},"android":{"2020-03":"y"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"y"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"y"}},"gmx":{"desktop-webmail":{"2022-06":"a #3"},"ios":{"2022-06":"y"},"android":{"2022-06":"y"}},"web-de":{"desktop-webmail":{"2022-06":"a #3"},"ios":{"2022-06":"y"},"android":{"2022-06":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-06":"y"},"android":{"2022-06":"y"}}},
"stats":{"apple-mail":{"macos":{"12.4":"y"},"ios":{"13.1":"y"}},"gmail":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"a #1"},"android":{"2019-10":"a #1"},"mobile-webmail":{"2020-02":"n"}},"orange":{"desktop-webmail":{"2019-10":"y","2021-03":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"outlook":{"windows":{"2003":"y","2007":"y","2010":"y","2013":"y","2016":"y","2019":"y"},"windows-mail":{"2019-10":"y"},"macos":{"2011":"y","2016":"y","16.80":"y"},"outlook-com":{"2019-10":"y","2024-01":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"samsung-email":{"android":{"6.0":"y"}},"sfr":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"}},"thunderbird":{"macos":{"60.3":"y"}},"aol":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"yahoo":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"a #2","2025-06":"y"}},"protonmail":{"desktop-webmail":{"2020-03":"n"},"ios":{"2020-03":"n"},"android":{"2020-03":"y"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"y"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"y"}},"gmx":{"desktop-webmail":{"2022-06":"a #3"},"ios":{"2022-06":"y"},"android":{"2022-06":"y"}},"web-de":{"desktop-webmail":{"2022-06":"a #3"},"ios":{"2022-06":"y"},"android":{"2022-06":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-06":"y"},"android":{"2022-06":"y"}}},
"notes":null,
"notes_by_num":{"1":"Partial. Not supported with non Google accounts.","2":"Buggy. The first `<head>` in the HTML is removed, so `<style>` elements need to be in a second `<head>` element.","3":"Partial. Only when used as class or ID selectors"}
},
@@ -2446,7 +2462,7 @@
"last_test_date":"2019-10-13",
"test_url":"https://www.caniemail.com/tests/css-selectors.html",
"test_results_url":"https://app.emailonacid.com/app/acidtest/kQbnzGXMSxMg2NDGmrcxIXOHrROwokTB29RcSssnkoPlS/list",
"stats":{"apple-mail":{"macos":{"12.4":"y"},"ios":{"13.1":"y"}},"gmail":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"a #1"},"android":{"2019-10":"a #1"},"mobile-webmail":{"2020-02":"n"}},"orange":{"desktop-webmail":{"2019-10":"y","2021-03":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"outlook":{"windows":{"2003":"y","2007":"y","2010":"y","2013":"y","2016":"y","2019":"y"},"windows-mail":{"2019-10":"y"},"macos":{"2011":"y","2016":"y","16.80":"y"},"outlook-com":{"2019-10":"y","2024-01":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"samsung-email":{"android":{"6.0":"y"}},"sfr":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"}},"thunderbird":{"macos":{"60.3":"y"}},"aol":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"yahoo":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"a #2"}},"protonmail":{"desktop-webmail":{"2020-03":"n"},"ios":{"2020-03":"n"},"android":{"2020-03":"y"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"y"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"y"}},"gmx":{"desktop-webmail":{"2022-06":"y"},"ios":{"2022-06":"y"},"android":{"2022-06":"y"}},"web-de":{"desktop-webmail":{"2022-06":"y"},"ios":{"2022-06":"y"},"android":{"2022-06":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-06":"n"},"android":{"2022-06":"y"}}},
"stats":{"apple-mail":{"macos":{"12.4":"y"},"ios":{"13.1":"y"}},"gmail":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"a #1"},"android":{"2019-10":"a #1"},"mobile-webmail":{"2020-02":"n"}},"orange":{"desktop-webmail":{"2019-10":"y","2021-03":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"outlook":{"windows":{"2003":"y","2007":"y","2010":"y","2013":"y","2016":"y","2019":"y"},"windows-mail":{"2019-10":"y"},"macos":{"2011":"y","2016":"y","16.80":"y"},"outlook-com":{"2019-10":"y","2024-01":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"samsung-email":{"android":{"6.0":"y"}},"sfr":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"}},"thunderbird":{"macos":{"60.3":"y"}},"aol":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"yahoo":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"a #2","2025-06":"y"}},"protonmail":{"desktop-webmail":{"2020-03":"n"},"ios":{"2020-03":"n"},"android":{"2020-03":"y"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"y"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"y"}},"gmx":{"desktop-webmail":{"2022-06":"y"},"ios":{"2022-06":"y"},"android":{"2022-06":"y"}},"web-de":{"desktop-webmail":{"2022-06":"y"},"ios":{"2022-06":"y"},"android":{"2022-06":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-06":"n"},"android":{"2022-06":"y"}}},
"notes":null,
"notes_by_num":{"1":"Partial. Not supported with non Google accounts.","2":"Buggy. The first `<head>` in the HTML is removed, so `<style>` elements need to be in a second `<head>` element."}
},
@@ -2462,7 +2478,7 @@
"last_test_date":"2019-10-13",
"test_url":"https://www.caniemail.com/tests/css-selectors.html",
"test_results_url":"https://app.emailonacid.com/app/acidtest/kQbnzGXMSxMg2NDGmrcxIXOHrROwokTB29RcSssnkoPlS/list",
"stats":{"apple-mail":{"macos":{"12.4":"y"},"ios":{"13.1":"y"}},"gmail":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"a #1"},"android":{"2019-10":"a #1"},"mobile-webmail":{"2020-02":"n"}},"orange":{"desktop-webmail":{"2019-10":"y","2021-03":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"outlook":{"windows":{"2003":"y","2007":"y","2010":"y","2013":"y","2016":"y","2019":"y"},"windows-mail":{"2019-10":"y"},"macos":{"2011":"y","2016":"y","16.80":"y"},"outlook-com":{"2019-10":"y","2024-01":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"samsung-email":{"android":{"6.0":"y"}},"sfr":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"}},"thunderbird":{"macos":{"60.3":"y"}},"aol":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"yahoo":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"a #2"}},"protonmail":{"desktop-webmail":{"2020-03":"n"},"ios":{"2020-03":"n"},"android":{"2020-03":"y"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"y"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"y"}},"gmx":{"desktop-webmail":{"2022-06":"n"},"ios":{"2022-06":"y"},"android":{"2022-06":"y"}},"web-de":{"desktop-webmail":{"2022-06":"n"},"ios":{"2022-06":"y"},"android":{"2022-06":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-06":"y"},"android":{"2022-06":"y"}}},
"stats":{"apple-mail":{"macos":{"12.4":"y"},"ios":{"13.1":"y"}},"gmail":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"a #1"},"android":{"2019-10":"a #1"},"mobile-webmail":{"2020-02":"n"}},"orange":{"desktop-webmail":{"2019-10":"y","2021-03":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"outlook":{"windows":{"2003":"y","2007":"y","2010":"y","2013":"y","2016":"y","2019":"y"},"windows-mail":{"2019-10":"y"},"macos":{"2011":"y","2016":"y","16.80":"y"},"outlook-com":{"2019-10":"y","2024-01":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"samsung-email":{"android":{"6.0":"y"}},"sfr":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"}},"thunderbird":{"macos":{"60.3":"y"}},"aol":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"yahoo":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"a #2","2025-06":"y"}},"protonmail":{"desktop-webmail":{"2020-03":"n"},"ios":{"2020-03":"n"},"android":{"2020-03":"y"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"y"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"y"}},"gmx":{"desktop-webmail":{"2022-06":"n"},"ios":{"2022-06":"y"},"android":{"2022-06":"y"}},"web-de":{"desktop-webmail":{"2022-06":"n"},"ios":{"2022-06":"y"},"android":{"2022-06":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-06":"y"},"android":{"2022-06":"y"}}},
"notes":null,
"notes_by_num":{"1":"Partial. Not supported with non Google accounts.","2":"Buggy. The first `<head>` in the HTML is removed, so `<style>` elements need to be in a second `<head>` element."}
},
@@ -2478,7 +2494,7 @@
"last_test_date":"2019-10-13",
"test_url":"https://www.caniemail.com/tests/css-selectors.html",
"test_results_url":"https://app.emailonacid.com/app/acidtest/kQbnzGXMSxMg2NDGmrcxIXOHrROwokTB29RcSssnkoPlS/list",
"stats":{"apple-mail":{"macos":{"12.4":"y"},"ios":{"13.1":"y"}},"gmail":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"a #1"},"android":{"2019-10":"a #1"},"mobile-webmail":{"2020-02":"n"}},"orange":{"desktop-webmail":{"2019-10":"y","2021-03":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"outlook":{"windows":{"2003":"y","2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"windows-mail":{"2019-10":"n"},"macos":{"2011":"y","2016":"y","16.80":"y"},"outlook-com":{"2019-10":"y","2024-01":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"samsung-email":{"android":{"6.0":"y"}},"sfr":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"}},"thunderbird":{"macos":{"60.3":"y"}},"aol":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"yahoo":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"a #2"}},"protonmail":{"desktop-webmail":{"2020-03":"n"},"ios":{"2020-03":"n"},"android":{"2020-03":"y"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"n #3"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"y"}},"gmx":{"desktop-webmail":{"2022-06":"y"},"ios":{"2022-06":"y"},"android":{"2022-06":"y"}},"web-de":{"desktop-webmail":{"2022-06":"y"},"ios":{"2022-06":"y"},"android":{"2022-06":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-06":"y"},"android":{"2022-06":"y"}}},
"stats":{"apple-mail":{"macos":{"12.4":"y"},"ios":{"13.1":"y"}},"gmail":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"a #1"},"android":{"2019-10":"a #1"},"mobile-webmail":{"2020-02":"n"}},"orange":{"desktop-webmail":{"2019-10":"y","2021-03":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"outlook":{"windows":{"2003":"y","2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"windows-mail":{"2019-10":"n"},"macos":{"2011":"y","2016":"y","16.80":"y"},"outlook-com":{"2019-10":"y","2024-01":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"samsung-email":{"android":{"6.0":"y"}},"sfr":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"n"},"android":{"2019-10":"n"}},"thunderbird":{"macos":{"60.3":"y"}},"aol":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"y"}},"yahoo":{"desktop-webmail":{"2019-10":"y"},"ios":{"2019-10":"y"},"android":{"2019-10":"a #2","2025-06":"y"}},"protonmail":{"desktop-webmail":{"2020-03":"n"},"ios":{"2020-03":"n"},"android":{"2020-03":"y"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"n #3"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"y"}},"gmx":{"desktop-webmail":{"2022-06":"y"},"ios":{"2022-06":"y"},"android":{"2022-06":"y"}},"web-de":{"desktop-webmail":{"2022-06":"y"},"ios":{"2022-06":"y"},"android":{"2022-06":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-06":"y"},"android":{"2022-06":"y"}}},
"notes":null,
"notes_by_num":{"1":"Partial. Not supported with non Google accounts.","2":"Buggy. The first `<head>` in the HTML is removed, so `<style>` elements need to be in a second `<head>` element.","3":"Not supported. The selector is removed and left prefixed with the outer most parent element."}
},
@@ -2558,7 +2574,7 @@
"last_test_date":"2022-07-20",
"test_url":"https://www.caniemail.com/tests/css-table-layout.html",
"test_results_url":"https://testi.at/proj/G4buV6sBBxUr6quykrtVA3sk",
"stats":{"apple-mail":{"macos":{"16":"y","17":"y","18":"y","19":"y","20":"y","21":"y"},"ios":{"11":"y","12":"y","13":"y","14":"y","15":"y"}},"gmail":{"desktop-webmail":{"2022-07":"y"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"},"mobile-webmail":{"2022-07":"u"}},"orange":{"desktop-webmail":{"2022-07":"u"},"ios":{"2022-07":"u"},"android":{"2022-07":"u"}},"outlook":{"windows":{"2007":"n","2010":"n","2013":"n","2016":"n","2019":"n","2021":"n"},"windows-mail":{"2022-07":"n"},"macos":{"2022-07":"y","16.80":"n #1"},"outlook-com":{"2022-07":"y","2024-01":"y"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"yahoo":{"desktop-webmail":{"2022-07":"y"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"aol":{"desktop-webmail":{"2022-07":"y"},"ios":{"2022-07":"u"},"android":{"2022-07":"u"}},"samsung-email":{"android":{"2022-07":"y"}},"sfr":{"desktop-webmail":{"2022-07":"u"},"ios":{"2022-07":"u"},"android":{"2022-07":"u"}},"protonmail":{"desktop-webmail":{"2022-07":"u"},"ios":{"2022-07":"u"},"android":{"2022-07":"u"}},"hey":{"desktop-webmail":{"2022-07":"u"}},"mail-ru":{"desktop-webmail":{"2022-07":"y"}},"fastmail":{"desktop-webmail":{"2022-07":"u"}}},
"stats":{"apple-mail":{"macos":{"16":"y","17":"y","18":"y","19":"y","20":"y","21":"y"},"ios":{"11":"y","12":"y","13":"y","14":"y","15":"y"}},"gmail":{"desktop-webmail":{"2022-07":"y"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"},"mobile-webmail":{"2022-07":"u"}},"orange":{"desktop-webmail":{"2022-07":"u"},"ios":{"2022-07":"u"},"android":{"2022-07":"u"}},"outlook":{"windows":{"2007":"n","2010":"n","2013":"n","2016":"n","2019":"n","2021":"n"},"windows-mail":{"2022-07":"n"},"macos":{"2022-07":"y","16.80":"n #1"},"outlook-com":{"2022-07":"y","2024-01":"y"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"yahoo":{"desktop-webmail":{"2022-07":"y"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"aol":{"desktop-webmail":{"2022-07":"y"},"ios":{"2022-07":"u"},"android":{"2022-07":"u"}},"samsung-email":{"android":{"2022-07":"y"}},"sfr":{"desktop-webmail":{"2022-07":"u"},"ios":{"2022-07":"u"},"android":{"2022-07":"u"}},"protonmail":{"desktop-webmail":{"2022-07":"y"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"hey":{"desktop-webmail":{"2022-07":"u"}},"mail-ru":{"desktop-webmail":{"2022-07":"y"}},"fastmail":{"desktop-webmail":{"2022-07":"u"}}},
"notes":null,
"notes_by_num":{"1":"Not supported. All tables are forced to `table-layout:fixed`."}
},
@@ -2574,7 +2590,7 @@
"last_test_date":"2022-08-31",
"test_url":"https://www.caniemail.com/tests/css-text-align-last.html",
"test_results_url":"https://app.emailonacid.com/app/acidtest/LxplTmJT9Ilq9GUyn8Aq8MVK6EO427qmx1Ic4A7jc7bOJ/list",
"stats":{"apple-mail":{"macos":{"2022-10":"y"},"ios":{"11":"n","12":"n","13":"n","14":"n","15":"n","16.0":"y"}},"gmail":{"desktop-webmail":{"2022-08":"y"},"ios":{"2022-08":"y"},"android":{"2022-08":"y"},"mobile-webmail":{"2021-08":"y"}},"outlook":{"windows":{"2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"macos":{"2022-08":"n","16.80":"n"},"outlook-com":{"2022-08":"y","2024-01":"n"},"ios":{"2022-08":"n"},"android":{"2022-08":"n"}},"yahoo":{"desktop-webmail":{"2022-08":"n","2024-03":"n"},"ios":{"2024-03":"n"},"android":{"2024-03":"n"}},"aol":{"desktop-webmail":{"2022-08":"n"}},"samsung-email":{"android":{"6.1.51.1":"y"}},"free-fr":{"desktop-webmail":{"2022-08":"y"}},"t-online-de":{"desktop-webmail":{"2022-08":"y"}},"mail-ru":{"desktop-webmail":{"2022-08":"y"}}},
"stats":{"apple-mail":{"macos":{"2022-10":"y"},"ios":{"11":"n","12":"n","13":"n","14":"n","15":"n","16.0":"y"}},"gmail":{"desktop-webmail":{"2022-08":"y"},"ios":{"2022-08":"y"},"android":{"2022-08":"y"},"mobile-webmail":{"2021-08":"y"}},"outlook":{"windows":{"2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"macos":{"2022-08":"n","16.80":"n"},"outlook-com":{"2022-08":"y","2024-01":"n"},"ios":{"2022-08":"n"},"android":{"2022-08":"n"}},"yahoo":{"desktop-webmail":{"2022-08":"n","2024-03":"n"},"ios":{"2024-03":"n"},"android":{"2024-03":"n"}},"aol":{"desktop-webmail":{"2022-08":"n"}},"samsung-email":{"android":{"6.1.51.1":"y"}},"protonmail":{"desktop-webmail":{"2022-07":"y"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"free-fr":{"desktop-webmail":{"2022-08":"y"}},"t-online-de":{"desktop-webmail":{"2022-08":"y"}},"mail-ru":{"desktop-webmail":{"2022-08":"y"}}},
"notes":null,
"notes_by_num":null
},
@@ -2622,7 +2638,7 @@
"last_test_date":"2023-12-06",
"test_url":"https://www.caniemail.com/tests/css-text-decoration-line.html",
"test_results_url":"https://testi.at/proj/kg6y1a4eiynkf8z7t4",
"stats":{"apple-mail":{"macos":{"2023-12":"y"},"ios":{"11":"n","12":"y","13":"y","14":"y"}},"gmail":{"desktop-webmail":{"2023-12":"y"},"ios":{"2023-12":"y"},"android":{"6":"n","7":"n","8":"y","9":"y","10":"y","11":"y","12":"y","13":"y"},"mobile-webmail":{"2023-12":"y"}},"orange":{"desktop-webmail":{"2023-12":"u"},"ios":{"2023-12":"u"},"android":{"2023-12":"u"}},"outlook":{"windows":{"2013":"n","2016":"n","2019":"n","2021":"n"},"windows-mail":{"2023-12":"n"},"macos":{"2023-12":"y","16.80":"y"},"outlook-com":{"2023-12":"y","2024-01":"y"},"ios":{"2023-12":"y"},"android":{"2023-12":"y"}},"yahoo":{"desktop-webmail":{"2023-12":"y"},"ios":{"2023-12":"y"},"android":{"2023-12":"n"}},"aol":{"desktop-webmail":{"2023-12":"y"},"ios":{"2023-12":"y"},"android":{"2023-12":"n"}},"samsung-email":{"android":{"2023-12":"y"}},"sfr":{"desktop-webmail":{"2023-12":"u"},"ios":{"2023-12":"u"},"android":{"2023-12":"u"}},"thunderbird":{"macos":{"2023-12":"y"}},"protonmail":{"desktop-webmail":{"2023-12":"y"},"ios":{"2023-12":"y"},"android":{"2023-12":"y"}},"hey":{"desktop-webmail":{"2023-12":"u"}},"mail-ru":{"desktop-webmail":{"2023-12":"y"}},"fastmail":{"desktop-webmail":{"2023-12":"u"}},"laposte":{"desktop-webmail":{"2023-12":"u"}},"gmx":{"desktop-webmail":{"2023-12":"n"},"ios":{"2023-12":"u"},"android":{"2023-12":"u"}},"web-de":{"desktop-webmail":{"2023-12":"n"},"ios":{"2023-12":"u"},"android":{"2023-12":"u"}},"ionos-1and1":{"desktop-webmail":{"2023-12":"u"},"android":{"2023-12":"u"}}},
"stats":{"apple-mail":{"macos":{"2023-12":"y"},"ios":{"11":"n","12":"y","13":"y","14":"y"}},"gmail":{"desktop-webmail":{"2023-12":"y"},"ios":{"2023-12":"y"},"android":{"6":"n","7":"n","8":"y","9":"y","10":"y","11":"y","12":"y","13":"y"},"mobile-webmail":{"2023-12":"y"}},"orange":{"desktop-webmail":{"2023-12":"u"},"ios":{"2023-12":"u"},"android":{"2023-12":"u"}},"outlook":{"windows":{"2013":"n","2016":"n","2019":"n","2021":"n"},"windows-mail":{"2023-12":"n"},"macos":{"2023-12":"y","16.80":"y"},"outlook-com":{"2023-12":"y","2024-01":"y"},"ios":{"2023-12":"y"},"android":{"2023-12":"y"}},"yahoo":{"desktop-webmail":{"2023-12":"y"},"ios":{"2023-12":"y"},"android":{"2023-12":"n","2025-06":"y"}},"aol":{"desktop-webmail":{"2023-12":"y"},"ios":{"2023-12":"y"},"android":{"2023-12":"n"}},"samsung-email":{"android":{"2023-12":"y"}},"sfr":{"desktop-webmail":{"2023-12":"u"},"ios":{"2023-12":"u"},"android":{"2023-12":"u"}},"thunderbird":{"macos":{"2023-12":"y"}},"protonmail":{"desktop-webmail":{"2023-12":"y"},"ios":{"2023-12":"y"},"android":{"2023-12":"y"}},"hey":{"desktop-webmail":{"2023-12":"u"}},"mail-ru":{"desktop-webmail":{"2023-12":"y"}},"fastmail":{"desktop-webmail":{"2023-12":"u"}},"laposte":{"desktop-webmail":{"2023-12":"u"}},"gmx":{"desktop-webmail":{"2023-12":"n"},"ios":{"2023-12":"u"},"android":{"2023-12":"u"}},"web-de":{"desktop-webmail":{"2023-12":"n"},"ios":{"2023-12":"u"},"android":{"2023-12":"u"}},"ionos-1and1":{"desktop-webmail":{"2023-12":"u"},"android":{"2023-12":"u"}}},
"notes":null,
"notes_by_num":null
},
@@ -2638,7 +2654,7 @@
"last_test_date":"2023-12-08",
"test_url":"https://www.caniemail.com/tests/css-text-decoration-skip-ink.html",
"test_results_url":"https://testi.at/proj/n477u94ixnz0kbrh6",
"stats":{"apple-mail":{"macos":{"10.15":"n","11.7":"n","12.7":"y","13.6":"y"},"ios":{"10":"n","11":"n","12":"n","13":"y","14":"y","15":"y"}},"gmail":{"desktop-webmail":{"2023-12":"n"},"ios":{"2023-12":"n"},"android":{"2023-12":"n"},"mobile-webmail":{"2023-12":"n"}},"orange":{"desktop-webmail":{"2023-12":"n"},"ios":{"2023-12":"n"},"android":{"2023-12":"u"}},"outlook":{"windows":{"2013":"n","2016":"n","2019":"n","2021":"n"},"windows-mail":{"2023-12":"n"},"macos":{"2023-12":"n","16.80":"n"},"outlook-com":{"2023-12":"n","2024-01":"n"},"ios":{"2023-12":"n"},"android":{"2023-12":"n"}},"yahoo":{"desktop-webmail":{"2023-12":"n"},"ios":{"2023-12":"n"},"android":{"2023-12":"n"}},"aol":{"desktop-webmail":{"2023-12":"n"},"ios":{"2023-12":"n"},"android":{"2023-12":"n"}},"samsung-email":{"android":{"2023-12":"y"}},"sfr":{"desktop-webmail":{"2023-12":"y"},"ios":{"2023-12":"u"},"android":{"2023-12":"u"}},"thunderbird":{"macos":{"2023-12":"y"}},"protonmail":{"desktop-webmail":{"2023-12":"y"},"ios":{"2023-12":"y"},"android":{"2023-12":"u"}},"hey":{"desktop-webmail":{"2023-12":"y"}},"mail-ru":{"desktop-webmail":{"2023-12":"y"}},"fastmail":{"desktop-webmail":{"2023-12":"y"}},"laposte":{"desktop-webmail":{"2023-12":"y"}},"gmx":{"desktop-webmail":{"2023-12":"n"},"ios":{"2023-12":"u"},"android":{"2023-12":"u"}},"web-de":{"desktop-webmail":{"2023-12":"n"},"ios":{"2023-12":"u"},"android":{"2023-12":"u"}},"ionos-1and1":{"desktop-webmail":{"2023-12":"u"},"android":{"2023-12":"u"}}},
"stats":{"apple-mail":{"macos":{"10.15":"n","11.7":"n","12.7":"y","13.6":"y"},"ios":{"10":"n","11":"n","12":"n","13":"y","14":"y","15":"y"}},"gmail":{"desktop-webmail":{"2023-12":"n"},"ios":{"2023-12":"n"},"android":{"2023-12":"n"},"mobile-webmail":{"2023-12":"n"}},"orange":{"desktop-webmail":{"2023-12":"n"},"ios":{"2023-12":"n"},"android":{"2023-12":"u"}},"outlook":{"windows":{"2013":"n","2016":"n","2019":"n","2021":"n"},"windows-mail":{"2023-12":"n"},"macos":{"2023-12":"n","16.80":"n"},"outlook-com":{"2023-12":"n","2024-01":"n"},"ios":{"2023-12":"n"},"android":{"2023-12":"n"}},"yahoo":{"desktop-webmail":{"2023-12":"n"},"ios":{"2023-12":"n"},"android":{"2023-12":"n"}},"aol":{"desktop-webmail":{"2023-12":"n"},"ios":{"2023-12":"n"},"android":{"2023-12":"n"}},"samsung-email":{"android":{"2023-12":"y"}},"sfr":{"desktop-webmail":{"2023-12":"y"},"ios":{"2023-12":"u"},"android":{"2023-12":"u"}},"thunderbird":{"macos":{"2023-12":"y"}},"protonmail":{"desktop-webmail":{"2023-12":"y"},"ios":{"2023-12":"y"},"android":{"2023-12":"y"}},"hey":{"desktop-webmail":{"2023-12":"y"}},"mail-ru":{"desktop-webmail":{"2023-12":"y"}},"fastmail":{"desktop-webmail":{"2023-12":"y"}},"laposte":{"desktop-webmail":{"2023-12":"y"}},"gmx":{"desktop-webmail":{"2023-12":"n"},"ios":{"2023-12":"u"},"android":{"2023-12":"u"}},"web-de":{"desktop-webmail":{"2023-12":"n"},"ios":{"2023-12":"u"},"android":{"2023-12":"u"}},"ionos-1and1":{"desktop-webmail":{"2023-12":"u"},"android":{"2023-12":"u"}}},
"notes":null,
"notes_by_num":null
},
@@ -2654,7 +2670,7 @@
"last_test_date":"2023-12-06",
"test_url":"https://www.caniemail.com/tests/css-text-decoration-style.html",
"test_results_url":"https://testi.at/proj/jalr04oy0yrxfd7kuo",
"stats":{"apple-mail":{"macos":{"2023-12":"y"},"ios":{"11":"n","12":"y","13":"y","14":"y"}},"gmail":{"desktop-webmail":{"2023-12":"y"},"ios":{"2023-12":"y"},"android":{"6":"n","7":"n","8":"y","9":"y","10":"y","11":"y","12":"y","13":"y"},"mobile-webmail":{"2023-12":"y"}},"orange":{"desktop-webmail":{"2023-12":"u"},"ios":{"2023-12":"u"},"android":{"2023-12":"u"}},"outlook":{"windows":{"2013":"n","2016":"n","2019":"n","2021":"n"},"windows-mail":{"2023-12":"n"},"macos":{"2023-12":"y","16.80":"y"},"outlook-com":{"2023-12":"y","2024-01":"y"},"ios":{"2023-12":"y"},"android":{"2023-12":"y"}},"yahoo":{"desktop-webmail":{"2023-12":"y"},"ios":{"2023-12":"y"},"android":{"2023-12":"n"}},"aol":{"desktop-webmail":{"2023-12":"y"},"ios":{"2023-12":"y"},"android":{"2023-12":"n"}},"samsung-email":{"android":{"2023-12":"y"}},"sfr":{"desktop-webmail":{"2023-12":"u"},"ios":{"2023-12":"u"},"android":{"2023-12":"u"}},"thunderbird":{"macos":{"2023-12":"y"}},"protonmail":{"desktop-webmail":{"2023-12":"u"},"ios":{"2023-12":"u"},"android":{"2023-12":"u"}},"hey":{"desktop-webmail":{"2023-12":"u"}},"mail-ru":{"desktop-webmail":{"2023-12":"y"}},"fastmail":{"desktop-webmail":{"2023-12":"u"}},"laposte":{"desktop-webmail":{"2023-12":"u"}},"gmx":{"desktop-webmail":{"2023-12":"n"},"ios":{"2023-12":"u"},"android":{"2023-12":"u"}},"web-de":{"desktop-webmail":{"2023-12":"n"},"ios":{"2023-12":"u"},"android":{"2023-12":"u"}},"ionos-1and1":{"desktop-webmail":{"2023-12":"u"},"android":{"2023-12":"u"}}},
"stats":{"apple-mail":{"macos":{"2023-12":"y"},"ios":{"11":"n","12":"y","13":"y","14":"y"}},"gmail":{"desktop-webmail":{"2023-12":"y"},"ios":{"2023-12":"y"},"android":{"6":"n","7":"n","8":"y","9":"y","10":"y","11":"y","12":"y","13":"y"},"mobile-webmail":{"2023-12":"y"}},"orange":{"desktop-webmail":{"2023-12":"u"},"ios":{"2023-12":"u"},"android":{"2023-12":"u"}},"outlook":{"windows":{"2013":"n","2016":"n","2019":"n","2021":"n"},"windows-mail":{"2023-12":"n"},"macos":{"2023-12":"y","16.80":"y"},"outlook-com":{"2023-12":"y","2024-01":"y"},"ios":{"2023-12":"y"},"android":{"2023-12":"y"}},"yahoo":{"desktop-webmail":{"2023-12":"y"},"ios":{"2023-12":"y"},"android":{"2023-12":"n","2025-06":"y"}},"aol":{"desktop-webmail":{"2023-12":"y"},"ios":{"2023-12":"y"},"android":{"2023-12":"n"}},"samsung-email":{"android":{"2023-12":"y"}},"sfr":{"desktop-webmail":{"2023-12":"u"},"ios":{"2023-12":"u"},"android":{"2023-12":"u"}},"thunderbird":{"macos":{"2023-12":"y"}},"protonmail":{"desktop-webmail":{"2023-12":"y"},"ios":{"2023-12":"y"},"android":{"2023-12":"y"}},"hey":{"desktop-webmail":{"2023-12":"u"}},"mail-ru":{"desktop-webmail":{"2023-12":"y"}},"fastmail":{"desktop-webmail":{"2023-12":"u"}},"laposte":{"desktop-webmail":{"2023-12":"u"}},"gmx":{"desktop-webmail":{"2023-12":"n"},"ios":{"2023-12":"u"},"android":{"2023-12":"u"}},"web-de":{"desktop-webmail":{"2023-12":"n"},"ios":{"2023-12":"u"},"android":{"2023-12":"u"}},"ionos-1and1":{"desktop-webmail":{"2023-12":"u"},"android":{"2023-12":"u"}}},
"notes":null,
"notes_by_num":null
},
@@ -2702,7 +2718,7 @@
"last_test_date":"2022-07-07",
"test_url":"https://www.caniemail.com/tests/css-text-emphasis.html",
"test_results_url":"https://testi.at/proj/O0yCP6t6l3sZ1xFrLZuEx6I5O",
"stats":{"apple-mail":{"macos":{"2022-07":"y"},"ios":{"11":"y","12":"y","13":"y","14":"y","15":"y"}},"gmail":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"},"mobile-webmail":{"2022-07":"n"}},"orange":{"desktop-webmail":{"2022-07":"u"},"ios":{"2022-07":"u"},"android":{"2022-07":"u"}},"outlook":{"windows":{"2013":"n","2016":"n","2019":"n","2021":"n"},"windows-mail":{"2022-07":"n"},"macos":{"2022-07":"y","16.80":"y"},"outlook-com":{"2022-07":"n","2024-01":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"}},"samsung-email":{"android":{"10":"n","11":"n"}},"sfr":{"desktop-webmail":{"2022-07":"u"},"ios":{"2022-07":"u"},"android":{"2022-07":"u"}},"thunderbird":{"macos":{"78.14":"u"}},"aol":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"}},"yahoo":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"}},"protonmail":{"desktop-webmail":{"2022-07":"u"},"ios":{"2022-07":"u"},"android":{"2022-07":"u"}},"hey":{"desktop-webmail":{"2022-07":"u"}},"mail-ru":{"desktop-webmail":{"2022-07":"y"}},"fastmail":{"desktop-webmail":{"2022-07":"u"}},"laposte":{"desktop-webmail":{"2022-07":"u"}},"gmx":{"desktop-webmail":{"2022-09":"n"},"ios":{"2022-09":"y"},"android":{"2022-09":"y"}},"web-de":{"desktop-webmail":{"2022-09":"n"},"ios":{"2022-09":"y"},"android":{"2022-09":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-09":"y"},"android":{"2022-09":"y"}}},
"stats":{"apple-mail":{"macos":{"2022-07":"y"},"ios":{"11":"y","12":"y","13":"y","14":"y","15":"y"}},"gmail":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"},"mobile-webmail":{"2022-07":"n"}},"orange":{"desktop-webmail":{"2022-07":"u"},"ios":{"2022-07":"u"},"android":{"2022-07":"u"}},"outlook":{"windows":{"2013":"n","2016":"n","2019":"n","2021":"n"},"windows-mail":{"2022-07":"n"},"macos":{"2022-07":"y","16.80":"y"},"outlook-com":{"2022-07":"n","2024-01":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"}},"samsung-email":{"android":{"10":"n","11":"n"}},"sfr":{"desktop-webmail":{"2022-07":"u"},"ios":{"2022-07":"u"},"android":{"2022-07":"u"}},"thunderbird":{"macos":{"78.14":"u"}},"aol":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"}},"yahoo":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"}},"protonmail":{"desktop-webmail":{"2022-07":"y"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"hey":{"desktop-webmail":{"2022-07":"u"}},"mail-ru":{"desktop-webmail":{"2022-07":"y"}},"fastmail":{"desktop-webmail":{"2022-07":"u"}},"laposte":{"desktop-webmail":{"2022-07":"u"}},"gmx":{"desktop-webmail":{"2022-09":"n"},"ios":{"2022-09":"y"},"android":{"2022-09":"y"}},"web-de":{"desktop-webmail":{"2022-09":"n"},"ios":{"2022-09":"y"},"android":{"2022-09":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-09":"y"},"android":{"2022-09":"y"}}},
"notes":null,
"notes_by_num":null
},
@@ -2718,7 +2734,7 @@
"last_test_date":"2022-07-07",
"test_url":"https://www.caniemail.com/tests/css-text-emphasis.html",
"test_results_url":"https://testi.at/proj/O0yCP6t6l3sZ1xFrLZuEx6I5O",
"stats":{"apple-mail":{"macos":{"2022-07":"y"},"ios":{"11":"y","12":"y","13":"y","14":"y","15":"y"}},"gmail":{"desktop-webmail":{"2022-07":"y"},"ios":{"2022-07":"y"},"android":{"2022-07":"n"},"mobile-webmail":{"2022-07":"n"}},"orange":{"desktop-webmail":{"2022-07":"u"},"ios":{"2022-07":"u"},"android":{"2022-07":"u"}},"outlook":{"windows":{"2013":"n","2016":"n","2019":"n","2021":"n"},"windows-mail":{"2022-07":"n"},"macos":{"2022-07":"y","16.80":"y"},"outlook-com":{"2022-07":"y","2024-01":"y"},"ios":{"2022-07":"y"},"android":{"2022-07":"n"}},"samsung-email":{"android":{"10":"n","11":"n"}},"sfr":{"desktop-webmail":{"2022-07":"u"},"ios":{"2022-07":"u"},"android":{"2022-07":"u"}},"thunderbird":{"macos":{"78.14":"u"}},"aol":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"}},"yahoo":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"}},"protonmail":{"desktop-webmail":{"2022-07":"u"},"ios":{"2022-07":"u"},"android":{"2022-07":"u"}},"hey":{"desktop-webmail":{"2022-07":"u"}},"mail-ru":{"desktop-webmail":{"2022-07":"y"}},"fastmail":{"desktop-webmail":{"2022-07":"u"}},"laposte":{"desktop-webmail":{"2022-07":"u"}},"gmx":{"desktop-webmail":{"2022-09":"n"},"ios":{"2022-09":"y"},"android":{"2022-09":"y"}},"web-de":{"desktop-webmail":{"2022-09":"n"},"ios":{"2022-09":"y"},"android":{"2022-09":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-09":"y"},"android":{"2022-09":"y"}}},
"stats":{"apple-mail":{"macos":{"2022-07":"y"},"ios":{"11":"y","12":"y","13":"y","14":"y","15":"y"}},"gmail":{"desktop-webmail":{"2022-07":"y"},"ios":{"2022-07":"y"},"android":{"2022-07":"n"},"mobile-webmail":{"2022-07":"n"}},"orange":{"desktop-webmail":{"2022-07":"u"},"ios":{"2022-07":"u"},"android":{"2022-07":"u"}},"outlook":{"windows":{"2013":"n","2016":"n","2019":"n","2021":"n"},"windows-mail":{"2022-07":"n"},"macos":{"2022-07":"y","16.80":"y"},"outlook-com":{"2022-07":"y","2024-01":"y"},"ios":{"2022-07":"y"},"android":{"2022-07":"n"}},"samsung-email":{"android":{"10":"n","11":"n"}},"sfr":{"desktop-webmail":{"2022-07":"u"},"ios":{"2022-07":"u"},"android":{"2022-07":"u"}},"thunderbird":{"macos":{"78.14":"u"}},"aol":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"}},"yahoo":{"desktop-webmail":{"2022-07":"n"},"ios":{"2022-07":"n"},"android":{"2022-07":"n"}},"protonmail":{"desktop-webmail":{"2022-07":"y"},"ios":{"2022-07":"y"},"android":{"2022-07":"y"}},"hey":{"desktop-webmail":{"2022-07":"u"}},"mail-ru":{"desktop-webmail":{"2022-07":"y"}},"fastmail":{"desktop-webmail":{"2022-07":"u"}},"laposte":{"desktop-webmail":{"2022-07":"u"}},"gmx":{"desktop-webmail":{"2022-09":"n"},"ios":{"2022-09":"y"},"android":{"2022-09":"y"}},"web-de":{"desktop-webmail":{"2022-09":"n"},"ios":{"2022-09":"y"},"android":{"2022-09":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-09":"y"},"android":{"2022-09":"y"}}},
"notes":null,
"notes_by_num":null
},
@@ -2766,7 +2782,7 @@
"last_test_date":"2023-12-08",
"test_url":"https://www.caniemail.com/tests/css-text-orientation.html",
"test_results_url":"https://testi.at/proj/6vppidbfjxnczrxh4",
"stats":{"apple-mail":{"macos":{"10.15":"a #1","11.7":"y","12.7":"y","13.6":"y","14.1":"y"},"ios":{"10":"n","11":"n","12":"y","13":"y","14":"y","15":"y"}},"gmail":{"desktop-webmail":{"2023-12":"y"},"ios":{"10":"n","11":"n","12":"y","13":"y","14":"y","15":"y"},"android":{"2023-12":"y"},"mobile-webmail":{"2023-12":"y"}},"orange":{"desktop-webmail":{"2023-12":"u"},"ios":{"2023-12":"u"},"android":{"2023-12":"u"}},"outlook":{"windows":{"2013":"n","2016":"n","2019":"n","2021":"n"},"windows-mail":{"2023-12":"n"},"macos":{"2023-12":"n","16.80":"y"},"outlook-com":{"2023-12":"y","2024-01":"y"},"ios":{"10":"n","11":"n","12":"y","13":"y","14":"y","15":"y"},"android":{"2023-12":"y"}},"yahoo":{"desktop-webmail":{"2023-12":"n"},"ios":{"2023-12":"n"},"android":{"2023-12":"n"}},"aol":{"desktop-webmail":{"2023-12":"n"},"ios":{"2023-12":"n"},"android":{"2023-12":"n"}},"samsung-email":{"android":{"2023-12":"y"}},"sfr":{"desktop-webmail":{"2023-12":"u"},"ios":{"2023-12":"u"},"android":{"2023-12":"u"}},"thunderbird":{"macos":{"2023-12":"y"}},"protonmail":{"desktop-webmail":{"2023-12":"u"},"ios":{"2023-12":"u"},"android":{"2023-12":"u"}},"hey":{"desktop-webmail":{"2023-12":"u"}},"mail-ru":{"desktop-webmail":{"2023-12":"y"}},"fastmail":{"desktop-webmail":{"2023-12":"u"}},"laposte":{"desktop-webmail":{"2023-12":"u"}},"gmx":{"desktop-webmail":{"2023-12":"n"},"ios":{"2023-12":"u"},"android":{"2023-12":"u"}},"web-de":{"desktop-webmail":{"2023-12":"n"},"ios":{"2023-12":"u"},"android":{"2023-12":"u"}},"ionos-1and1":{"desktop-webmail":{"2023-12":"u"},"android":{"2023-12":"u"}}},
"stats":{"apple-mail":{"macos":{"10.15":"a #1","11.7":"y","12.7":"y","13.6":"y","14.1":"y"},"ios":{"10":"n","11":"n","12":"y","13":"y","14":"y","15":"y"}},"gmail":{"desktop-webmail":{"2023-12":"y"},"ios":{"10":"n","11":"n","12":"y","13":"y","14":"y","15":"y"},"android":{"2023-12":"y"},"mobile-webmail":{"2023-12":"y"}},"orange":{"desktop-webmail":{"2023-12":"u"},"ios":{"2023-12":"u"},"android":{"2023-12":"u"}},"outlook":{"windows":{"2013":"n","2016":"n","2019":"n","2021":"n"},"windows-mail":{"2023-12":"n"},"macos":{"2023-12":"n","16.80":"y"},"outlook-com":{"2023-12":"y","2024-01":"y"},"ios":{"10":"n","11":"n","12":"y","13":"y","14":"y","15":"y"},"android":{"2023-12":"y"}},"yahoo":{"desktop-webmail":{"2023-12":"n"},"ios":{"2023-12":"n"},"android":{"2023-12":"n"}},"aol":{"desktop-webmail":{"2023-12":"n"},"ios":{"2023-12":"n"},"android":{"2023-12":"n"}},"samsung-email":{"android":{"2023-12":"y"}},"sfr":{"desktop-webmail":{"2023-12":"u"},"ios":{"2023-12":"u"},"android":{"2023-12":"u"}},"thunderbird":{"macos":{"2023-12":"y"}},"protonmail":{"desktop-webmail":{"2023-12":"y"},"ios":{"2023-12":"y"},"android":{"2023-12":"y"}},"hey":{"desktop-webmail":{"2023-12":"u"}},"mail-ru":{"desktop-webmail":{"2023-12":"y"}},"fastmail":{"desktop-webmail":{"2023-12":"u"}},"laposte":{"desktop-webmail":{"2023-12":"u"}},"gmx":{"desktop-webmail":{"2023-12":"n"},"ios":{"2023-12":"u"},"android":{"2023-12":"u"}},"web-de":{"desktop-webmail":{"2023-12":"n"},"ios":{"2023-12":"u"},"android":{"2023-12":"u"}},"ionos-1and1":{"desktop-webmail":{"2023-12":"u"},"android":{"2023-12":"u"}}},
"notes":null,
"notes_by_num":{"1":"Partial. `sideways` is not supported"}
},
@@ -2798,7 +2814,7 @@
"last_test_date":"2019-02-28",
"test_url":"https://www.caniemail.com/tests/css-box-model.html",
"test_results_url":"https://app.emailonacid.com/app/acidtest/pyPQFHSYLFrhbRShalju0B2fYNwUgLuyKTLx4MLqiw5mE/list",
"stats":{"apple-mail":{"macos":{"12.4":"y"},"ios":{"12.1":"y"}},"gmail":{"desktop-webmail":{"2019-02":"n"},"ios":{"2019-02":"n"},"android":{"2019-02":"n"},"mobile-webmail":{"2020-02":"n"}},"orange":{"desktop-webmail":{"2019-08":"y","2021-03":"y"},"ios":{"2019-08":"y"},"android":{"2019-08":"y"}},"outlook":{"windows":{"2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"windows-mail":{"2019-02":"n"},"macos":{"2019-02":"y","16.80":"n"},"outlook-com":{"2019-02":"n","2024-01":"n"},"ios":{"2019-02":"n"},"android":{"2019-02":"n"}},"yahoo":{"desktop-webmail":{"2019-02":"y"},"ios":{"2019-02":"y"},"android":{"2019-02":"n"}},"aol":{"desktop-webmail":{"2019-02":"y"},"ios":{"2019-02":"y"},"android":{"2019-02":"y"}},"samsung-email":{"android":{"5.0.10.2":"y"}},"sfr":{"desktop-webmail":{"2020-01":"y"},"ios":{"2020-01":"y"},"android":{"2020-01":"y"}},"thunderbird":{"macos":{"60.5":"y"}},"protonmail":{"desktop-webmail":{"2020-03":"y"},"ios":{"2020-03":"y"},"android":{"2020-03":"y"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"y"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"y"}},"gmx":{"desktop-webmail":{"2022-08":"y"},"ios":{"2022-08":"y"},"android":{"2022-08":"y"}},"web-de":{"desktop-webmail":{"2022-08":"y"},"ios":{"2022-08":"y"},"android":{"2022-08":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-08":"y"},"android":{"2022-08":"y"}}},
"stats":{"apple-mail":{"macos":{"12.4":"y"},"ios":{"12.1":"y"}},"gmail":{"desktop-webmail":{"2019-02":"n"},"ios":{"2019-02":"n"},"android":{"2019-02":"n"},"mobile-webmail":{"2020-02":"n"}},"orange":{"desktop-webmail":{"2019-08":"y","2021-03":"y"},"ios":{"2019-08":"y"},"android":{"2019-08":"y"}},"outlook":{"windows":{"2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"windows-mail":{"2019-02":"n"},"macos":{"2019-02":"y","16.80":"n"},"outlook-com":{"2019-02":"n","2024-01":"n"},"ios":{"2019-02":"n"},"android":{"2019-02":"n"}},"yahoo":{"desktop-webmail":{"2019-02":"y"},"ios":{"2019-02":"y"},"android":{"2019-02":"n","2025-06":"y"}},"aol":{"desktop-webmail":{"2019-02":"y"},"ios":{"2019-02":"y"},"android":{"2019-02":"y"}},"samsung-email":{"android":{"5.0.10.2":"y"}},"sfr":{"desktop-webmail":{"2020-01":"y"},"ios":{"2020-01":"y"},"android":{"2020-01":"y"}},"thunderbird":{"macos":{"60.5":"y"}},"protonmail":{"desktop-webmail":{"2020-03":"y"},"ios":{"2020-03":"y"},"android":{"2020-03":"y"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"y"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"y"}},"gmx":{"desktop-webmail":{"2022-08":"y"},"ios":{"2022-08":"y"},"android":{"2022-08":"y"}},"web-de":{"desktop-webmail":{"2022-08":"y"},"ios":{"2022-08":"y"},"android":{"2022-08":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-08":"y"},"android":{"2022-08":"y"}}},
"notes":null,
"notes_by_num":null
},
@@ -2846,7 +2862,7 @@
"last_test_date":"2023-12-08",
"test_url":"https://www.caniemail.com/tests/css-text-underline-position.html",
"test_results_url":"https://testi.at/proj/yd99u8e12nvh97jcv",
"stats":{"apple-mail":{"macos":{"2023-12":"a #1"},"ios":{"2023-12":"a #1"}},"gmail":{"desktop-webmail":{"2023-12":"y"},"ios":{"2023-12":"a #1"},"android":{"2023-12":"y"},"mobile-webmail":{"2023-12":"y"}},"orange":{"desktop-webmail":{"2023-12":"u"},"ios":{"2023-12":"u"},"android":{"2023-12":"u"}},"outlook":{"windows":{"2013":"n","2016":"n","2019":"n","2021":"n"},"windows-mail":{"2023-12":"n"},"macos":{"2023-12":"n","16.80":"n"},"outlook-com":{"2023-12":"y","2024-01":"y"},"ios":{"2023-12":"a #1"},"android":{"2023-12":"y"}},"yahoo":{"desktop-webmail":{"2023-12":"n"},"ios":{"2023-12":"n"},"android":{"2023-12":"n"}},"aol":{"desktop-webmail":{"2023-12":"n"},"ios":{"2023-12":"n"},"android":{"2023-12":"n"}},"samsung-email":{"android":{"2023-12":"y"}},"sfr":{"desktop-webmail":{"2023-12":"u"},"ios":{"2023-12":"u"},"android":{"2023-12":"u"}},"thunderbird":{"macos":{"2023-12":"y"}},"protonmail":{"desktop-webmail":{"2023-12":"u"},"ios":{"2023-12":"u"},"android":{"2023-12":"u"}},"hey":{"desktop-webmail":{"2023-12":"u"}},"mail-ru":{"desktop-webmail":{"2023-12":"y"}},"fastmail":{"desktop-webmail":{"2023-12":"u"}},"laposte":{"desktop-webmail":{"2023-12":"u"}},"gmx":{"desktop-webmail":{"2023-12":"n"},"ios":{"2023-12":"u"},"android":{"2023-12":"u"}},"web-de":{"desktop-webmail":{"2023-12":"n"},"ios":{"2023-12":"u"},"android":{"2023-12":"u"}},"ionos-1and1":{"desktop-webmail":{"2023-12":"u"},"android":{"2023-12":"u"}}},
"stats":{"apple-mail":{"macos":{"2023-12":"a #1"},"ios":{"2023-12":"a #1"}},"gmail":{"desktop-webmail":{"2023-12":"y"},"ios":{"2023-12":"a #1"},"android":{"2023-12":"y"},"mobile-webmail":{"2023-12":"y"}},"orange":{"desktop-webmail":{"2023-12":"u"},"ios":{"2023-12":"u"},"android":{"2023-12":"u"}},"outlook":{"windows":{"2013":"n","2016":"n","2019":"n","2021":"n"},"windows-mail":{"2023-12":"n"},"macos":{"2023-12":"n","16.80":"n"},"outlook-com":{"2023-12":"y","2024-01":"y"},"ios":{"2023-12":"a #1"},"android":{"2023-12":"y"}},"yahoo":{"desktop-webmail":{"2023-12":"n"},"ios":{"2023-12":"n"},"android":{"2023-12":"n"}},"aol":{"desktop-webmail":{"2023-12":"n"},"ios":{"2023-12":"n"},"android":{"2023-12":"n"}},"samsung-email":{"android":{"2023-12":"y"}},"sfr":{"desktop-webmail":{"2023-12":"u"},"ios":{"2023-12":"u"},"android":{"2023-12":"u"}},"thunderbird":{"macos":{"2023-12":"y"}},"protonmail":{"desktop-webmail":{"2023-12":"y"},"ios":{"2023-12":"y"},"android":{"2023-12":"y"}},"hey":{"desktop-webmail":{"2023-12":"u"}},"mail-ru":{"desktop-webmail":{"2023-12":"y"}},"fastmail":{"desktop-webmail":{"2023-12":"u"}},"laposte":{"desktop-webmail":{"2023-12":"u"}},"gmx":{"desktop-webmail":{"2023-12":"n"},"ios":{"2023-12":"u"},"android":{"2023-12":"u"}},"web-de":{"desktop-webmail":{"2023-12":"n"},"ios":{"2023-12":"u"},"android":{"2023-12":"u"}},"ionos-1and1":{"desktop-webmail":{"2023-12":"u"},"android":{"2023-12":"u"}}},
"notes":null,
"notes_by_num":{"1":"Partial. Supports `under` but not `right` and `left`"}
},
@@ -3230,7 +3246,7 @@
"last_test_date":"2019-02-28",
"test_url":"https://www.caniemail.com/tests/css-visual-effects.html",
"test_results_url":"https://app.emailonacid.com/app/acidtest/DhTRmGsVH6uobU4pHD3CasJywfBL4HnEjA1LOF8f9ctso/list",
"stats":{"apple-mail":{"macos":{"12.4":"y #1"},"ios":{"12.1":"y #1"}},"gmail":{"desktop-webmail":{"2019-02":"n"},"ios":{"2019-02":"n"},"android":{"2019-02":"n"},"mobile-webmail":{"2020-02":"n"}},"orange":{"desktop-webmail":{"2019-08":"y","2021-03":"a #2","2024-04":"n"},"ios":{"2019-08":"a #1","2024-04":"n"},"android":{"2019-08":"y","2024-04":"n"}},"outlook":{"windows":{"2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"windows-mail":{"2019-02":"n"},"macos":{"2019-02":"y #1","16.80":"y #1"},"outlook-com":{"2019-02":"y","2024-01":"y"},"ios":{"2019-02":"y #1"},"android":{"2019-02":"y"}},"thunderbird":{"macos":{"60.8":"y"}},"yahoo":{"desktop-webmail":{"2019-02":"y"},"ios":{"2019-02":"y #1"},"android":{"2019-02":"n"}},"aol":{"desktop-webmail":{"2019-02":"n"},"ios":{"2019-02":"y #1"},"android":{"2019-02":"y"}},"samsung-email":{"android":{"5.0.10.2":"y"}},"sfr":{"desktop-webmail":{"2019-08":"y"},"ios":{"2019-08":"y #1"},"android":{"2019-08":"y"}},"protonmail":{"desktop-webmail":{"2020-03":"y"},"ios":{"2020-03":"y #1"},"android":{"2020-03":"y"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"y"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"y"}},"gmx":{"desktop-webmail":{"2022-09":"y"},"ios":{"2022-09":"y"},"android":{"2022-09":"y"}},"web-de":{"desktop-webmail":{"2022-09":"y"},"ios":{"2022-09":"y"},"android":{"2022-09":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-09":"y"},"android":{"2022-09":"y"}}},
"stats":{"apple-mail":{"macos":{"12.4":"y #1"},"ios":{"12.1":"y #1"}},"gmail":{"desktop-webmail":{"2019-02":"n"},"ios":{"2019-02":"n"},"android":{"2019-02":"n"},"mobile-webmail":{"2020-02":"n"}},"orange":{"desktop-webmail":{"2019-08":"y","2021-03":"a #2","2024-04":"n"},"ios":{"2019-08":"a #1","2024-04":"n"},"android":{"2019-08":"y","2024-04":"n"}},"outlook":{"windows":{"2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"windows-mail":{"2019-02":"n"},"macos":{"2019-02":"y #1","16.80":"y #1"},"outlook-com":{"2019-02":"y","2024-01":"y"},"ios":{"2019-02":"y #1"},"android":{"2019-02":"y"}},"thunderbird":{"macos":{"60.8":"y"}},"yahoo":{"desktop-webmail":{"2019-02":"y"},"ios":{"2019-02":"y #1"},"android":{"2019-02":"n","2025-06":"y"}},"aol":{"desktop-webmail":{"2019-02":"n"},"ios":{"2019-02":"y #1"},"android":{"2019-02":"y"}},"samsung-email":{"android":{"5.0.10.2":"y"}},"sfr":{"desktop-webmail":{"2019-08":"y"},"ios":{"2019-08":"y #1"},"android":{"2019-08":"y"}},"protonmail":{"desktop-webmail":{"2020-03":"y"},"ios":{"2020-03":"y #1"},"android":{"2020-03":"y"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-10":"y"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"y"}},"gmx":{"desktop-webmail":{"2022-09":"y"},"ios":{"2022-09":"y"},"android":{"2022-09":"y"}},"web-de":{"desktop-webmail":{"2022-09":"y"},"ios":{"2022-09":"y"},"android":{"2022-09":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-09":"y"},"android":{"2022-09":"y"}}},
"notes":null,
"notes_by_num":{"1":"Buggy. `visibility:collapse` applied to a `<tr>` only hides content and does not \"remove\" it from layout.","2":"Partially supported. `visibility:collapse` is not supported."}
},
@@ -3326,11 +3342,27 @@
"last_test_date":"2024-03-13",
"test_url":"https://www.caniemail.com/tests/css-word-spacing.html",
"test_results_url":"https://testi.at/proj/8r8pfrlvcxklca32ij",
"stats":{"apple-mail":{"macos":{"2024-03":"y"},"ios":{"2024-03":"y"}},"gmail":{"desktop-webmail":{"2024-03":"y"},"ios":{"2024-03":"y"},"android":{"2024-03":"y"},"mobile-webmail":{"2024-03":"y"}},"orange":{"desktop-webmail":{"2024-03":"u"},"ios":{"2024-03":"u"},"android":{"2024-03":"u"}},"outlook":{"windows":{"2013":"n","2016":"n","2019":"n","2021":"n"},"windows-mail":{"2024-03":"n"},"macos":{"2024-03":"y"},"outlook-com":{"2024-03":"y"},"ios":{"2024-03":"y"},"android":{"2024-03":"y"}},"yahoo":{"desktop-webmail":{"2024-03":"a #1"},"ios":{"2024-03":"a #1"},"android":{"2024-03":"n"}},"aol":{"desktop-webmail":{"2024-03":"a #1"},"ios":{"2024-03":"a #1"},"android":{"2024-03":"n"}},"samsung-email":{"android":{"2024-03":"y"}},"sfr":{"desktop-webmail":{"2024-03":"u"},"ios":{"2024-03":"u"},"android":{"2024-03":"u"}},"thunderbird":{"macos":{"2024-03":"y"}},"protonmail":{"desktop-webmail":{"2024-03":"u"},"ios":{"2024-03":"u"},"android":{"2024-03":"u"}},"hey":{"desktop-webmail":{"2024-03":"u"}},"mail-ru":{"desktop-webmail":{"2024-03":"y"}},"fastmail":{"desktop-webmail":{"2024-03":"u"}},"laposte":{"desktop-webmail":{"2024-03":"u"}},"gmx":{"desktop-webmail":{"2024-03":"a #1"},"ios":{"2024-03":"u"},"android":{"2024-03":"u"}},"web-de":{"desktop-webmail":{"2024-03":"a #1"},"ios":{"2024-03":"u"},"android":{"2024-03":"u"}},"ionos-1and1":{"desktop-webmail":{"2024-03":"u"},"android":{"2024-03":"u"}}},
"stats":{"apple-mail":{"macos":{"2024-03":"y"},"ios":{"2024-03":"y"}},"gmail":{"desktop-webmail":{"2024-03":"y"},"ios":{"2024-03":"y"},"android":{"2024-03":"y"},"mobile-webmail":{"2024-03":"y"}},"orange":{"desktop-webmail":{"2024-03":"u"},"ios":{"2024-03":"u"},"android":{"2024-03":"u"}},"outlook":{"windows":{"2013":"n","2016":"n","2019":"n","2021":"n"},"windows-mail":{"2024-03":"n"},"macos":{"2024-03":"y"},"outlook-com":{"2024-03":"y"},"ios":{"2024-03":"y"},"android":{"2024-03":"y"}},"yahoo":{"desktop-webmail":{"2024-03":"a #1"},"ios":{"2024-03":"a #1"},"android":{"2024-03":"n","2025-06":"a #1"}},"aol":{"desktop-webmail":{"2024-03":"a #1"},"ios":{"2024-03":"a #1"},"android":{"2024-03":"n"}},"samsung-email":{"android":{"2024-03":"y"}},"sfr":{"desktop-webmail":{"2024-03":"u"},"ios":{"2024-03":"u"},"android":{"2024-03":"u"}},"thunderbird":{"macos":{"2024-03":"y"}},"protonmail":{"desktop-webmail":{"2024-03":"y"},"ios":{"2024-03":"y"},"android":{"2024-03":"y"}},"hey":{"desktop-webmail":{"2024-03":"u"}},"mail-ru":{"desktop-webmail":{"2024-03":"y"}},"fastmail":{"desktop-webmail":{"2024-03":"u"}},"laposte":{"desktop-webmail":{"2024-03":"u"}},"gmx":{"desktop-webmail":{"2024-03":"a #1"},"ios":{"2024-03":"u"},"android":{"2024-03":"u"}},"web-de":{"desktop-webmail":{"2024-03":"a #1"},"ios":{"2024-03":"u"},"android":{"2024-03":"u"}},"ionos-1and1":{"desktop-webmail":{"2024-03":"u"},"android":{"2024-03":"u"}}},
"notes":null,
"notes_by_num":{"1":"Does not support `rem` and `ch` values."}
},
{
"slug":"css-word-wrap",
"title":"word-wrap",
"description":"The word-wrap CSS property (now standardized as overflow-wrap) controls whether the browser should break words to prevent them from overflowing their container. When set to break-word, it forces otherwise unbreakable strings to wrap onto the next line to avoid layout issues.",
"url":"https://www.caniemail.com/features/css-word-wrap/",
"category":"css",
"tags":[],
"keywords":"word-wrap, word-break, overflow-wrap",
"last_test_date":"2025-05-08",
"test_url":"https://www.caniemail.com/tests/css-word-wrap.html",
"test_results_url":"https://app.emailonacid.com/app/acidtest/vCaPUwbCjmYsdRJi38QdpqJSetV5X7wBQh5iymp8t1Sty/list",
"stats":{"apple-mail":{"macos":{"16":"y"},"ios":{"16":"y"}},"gmail":{"desktop-webmail":{"2025-05":"a #1"},"android":{"2025-05":"a #1"}},"outlook":{"windows":{"2016":"n #2","2019":"n #2","2021":"n #2"},"windows-mail":{"2025-05":"n"},"outlook-com":{"2022-05":"y #3"},"ios":{"2025-05":"y #3"},"android":{"2025-05":"n"}},"yahoo":{"desktop-webmail":{"2025-05":"y"}}},
"notes":null,
"notes_by_num":{"1":"Applies `word-wrap: break-word` to all items.","2":"Does not honor any wrapping, including `word-wrap`, `overflow-wrap`, and `word-break`. Using an equivalent MSO breakdown (`-ms-word-break: break-all` and `mso-hyphenate: none` together) does not work.","3":"Supports both `word-wrap` and equivalent MSO breakdown (`-ms-word-break: break-all` and `mso-hyphenate: none` together)"}
},
{
"slug":"css-writing-mode",
"title":"writing-mode",
@@ -3390,7 +3422,7 @@
"last_test_date":"2024-01-03",
"test_url":"https://www.caniemail.com/tests/html-acronym.html",
"test_results_url":"https://testi.at/proj/ayebhgpxu58yce2bhd",
"stats":{"apple-mail":{"macos":{"2024-01":"y"},"ios":{"2024-01":"y"}},"gmail":{"desktop-webmail":{"2024-01":"y"},"ios":{"2024-01":"y"},"android":{"2024-01":"y"},"mobile-webmail":{"2024-01":"y"}},"orange":{"desktop-webmail":{"2024-01":"u"},"ios":{"2024-01":"u"},"android":{"2024-01":"u"}},"outlook":{"windows":{"2013":"n #1","2016":"n #1","2019":"n #1","2021":"n #1"},"windows-mail":{"2024-01":"n #1"},"macos":{"2024-01":"y"},"outlook-com":{"2024-01":"y"},"ios":{"2024-01":"y"},"android":{"2024-01":"y"}},"samsung-email":{"android":{"2024-01":"y"}},"sfr":{"desktop-webmail":{"2024-03":"y"},"ios":{"2024-03":"y"},"android":{"2024-03":"y"}},"thunderbird":{"macos":{"2024-01":"y"}},"aol":{"desktop-webmail":{"2024-01":"n"},"ios":{"2024-01":"n"},"android":{"2024-01":"n"}},"yahoo":{"desktop-webmail":{"2024-01":"n"},"ios":{"2024-01":"n"},"android":{"2024-01":"n"}},"protonmail":{"desktop-webmail":{"2024-01":"u"},"ios":{"2024-01":"u"},"android":{"2024-01":"u"}},"hey":{"desktop-webmail":{"2024-01":"u"}},"mail-ru":{"desktop-webmail":{"2024-01":"n"}},"fastmail":{"desktop-webmail":{"2024-01":"u"}},"laposte":{"desktop-webmail":{"2024-01":"u"}},"free-fr":{"desktop-webmail":{"2024-01":"u"}},"t-online-de":{"desktop-webmail":{"2024-01":"y"}},"gmx":{"desktop-webmail":{"2024-01":"y"}},"web-de":{"desktop-webmail":{"2024-01":"y"}}},
"stats":{"apple-mail":{"macos":{"2024-01":"y"},"ios":{"2024-01":"y"}},"gmail":{"desktop-webmail":{"2024-01":"y"},"ios":{"2024-01":"y"},"android":{"2024-01":"y"},"mobile-webmail":{"2024-01":"y"}},"orange":{"desktop-webmail":{"2024-01":"u"},"ios":{"2024-01":"u"},"android":{"2024-01":"u"}},"outlook":{"windows":{"2013":"n #1","2016":"n #1","2019":"n #1","2021":"n #1"},"windows-mail":{"2024-01":"n #1"},"macos":{"2024-01":"y"},"outlook-com":{"2024-01":"y"},"ios":{"2024-01":"y"},"android":{"2024-01":"y"}},"samsung-email":{"android":{"2024-01":"y"}},"sfr":{"desktop-webmail":{"2024-03":"y"},"ios":{"2024-03":"y"},"android":{"2024-03":"y"}},"thunderbird":{"macos":{"2024-01":"y"}},"aol":{"desktop-webmail":{"2024-01":"n"},"ios":{"2024-01":"n"},"android":{"2024-01":"n"}},"yahoo":{"desktop-webmail":{"2024-01":"n"},"ios":{"2024-01":"n"},"android":{"2024-01":"n"}},"protonmail":{"desktop-webmail":{"2024-01":"y"},"ios":{"2024-01":"y"},"android":{"2024-01":"y"}},"hey":{"desktop-webmail":{"2024-01":"u"}},"mail-ru":{"desktop-webmail":{"2024-01":"n"}},"fastmail":{"desktop-webmail":{"2024-01":"u"}},"laposte":{"desktop-webmail":{"2024-01":"u"}},"free-fr":{"desktop-webmail":{"2024-01":"u"}},"t-online-de":{"desktop-webmail":{"2024-01":"y"}},"gmx":{"desktop-webmail":{"2024-01":"y"}},"web-de":{"desktop-webmail":{"2024-01":"y"}}},
"notes":null,
"notes_by_num":{"1":"Buggy. `title` attribute is removed but keeps `<acronym>` tag."}
},
@@ -3742,7 +3774,7 @@
"last_test_date":"2023-09-11",
"test_url":"https://www.caniemail.com/tests/html-dfn.html",
"test_results_url":"https://testi.at/proj/gy2dfo4j19d4176d08y",
"stats":{"apple-mail":{"macos":{"2023-09":"y"},"ios":{"2023-09":"y"}},"gmail":{"desktop-webmail":{"2023-09":"y"},"ios":{"2023-09":"y"},"android":{"2023-09":"y"},"mobile-webmail":{"2023-09":"y"}},"orange":{"desktop-webmail":{"2023-09":"u"},"ios":{"2023-09":"u"},"android":{"2023-09":"u"}},"outlook":{"windows":{"2013":"a #1","2016":"a #1","2019":"a #1","2021":"a #1"},"windows-mail":{"2023-09":"a #1"},"macos":{"16.56":"y","16.80":"y"},"outlook-com":{"2023-09":"y","2024-01":"y"},"ios":{"2023-09":"y"},"android":{"2023-09":"y"}},"samsung-email":{"android":{"2023-09":"y"}},"sfr":{"desktop-webmail":{"2024-03":"y"},"ios":{"2024-03":"y"},"android":{"2024-03":"y"}},"thunderbird":{"macos":{"2023-09":"y"}},"aol":{"desktop-webmail":{"2023-09":"y"},"ios":{"2023-09":"y"},"android":{"2023-09":"y"}},"yahoo":{"desktop-webmail":{"2023-09":"y"},"ios":{"2023-09":"y"},"android":{"2023-09":"y"}},"protonmail":{"desktop-webmail":{"2023-09":"u"},"ios":{"2023-09":"u"},"android":{"2023-09":"u"}},"hey":{"desktop-webmail":{"2023-09":"u"}},"mail-ru":{"desktop-webmail":{"2023-09":"n"}},"fastmail":{"desktop-webmail":{"2023-09":"u"}},"laposte":{"desktop-webmail":{"2023-09":"u"}},"free-fr":{"desktop-webmail":{"2023-09":"u"}},"t-online-de":{"desktop-webmail":{"2023-09":"n"}},"gmx":{"desktop-webmail":{"2023-09":"y"}},"web-de":{"desktop-webmail":{"2023-09":"y"}}},
"stats":{"apple-mail":{"macos":{"2023-09":"y"},"ios":{"2023-09":"y"}},"gmail":{"desktop-webmail":{"2023-09":"y"},"ios":{"2023-09":"y"},"android":{"2023-09":"y"},"mobile-webmail":{"2023-09":"y"}},"orange":{"desktop-webmail":{"2023-09":"u"},"ios":{"2023-09":"u"},"android":{"2023-09":"u"}},"outlook":{"windows":{"2013":"a #1","2016":"a #1","2019":"a #1","2021":"a #1"},"windows-mail":{"2023-09":"a #1"},"macos":{"16.56":"y","16.80":"y"},"outlook-com":{"2023-09":"y","2024-01":"y"},"ios":{"2023-09":"y"},"android":{"2023-09":"y"}},"samsung-email":{"android":{"2023-09":"y"}},"sfr":{"desktop-webmail":{"2024-03":"y"},"ios":{"2024-03":"y"},"android":{"2024-03":"y"}},"thunderbird":{"macos":{"2023-09":"y"}},"aol":{"desktop-webmail":{"2023-09":"y"},"ios":{"2023-09":"y"},"android":{"2023-09":"y"}},"yahoo":{"desktop-webmail":{"2023-09":"y"},"ios":{"2023-09":"y"},"android":{"2023-09":"y"}},"protonmail":{"desktop-webmail":{"2023-09":"y"},"ios":{"2023-09":"y"},"android":{"2023-09":"y"}},"hey":{"desktop-webmail":{"2023-09":"u"}},"mail-ru":{"desktop-webmail":{"2023-09":"n"}},"fastmail":{"desktop-webmail":{"2023-09":"u"}},"laposte":{"desktop-webmail":{"2023-09":"u"}},"free-fr":{"desktop-webmail":{"2023-09":"u"}},"t-online-de":{"desktop-webmail":{"2023-09":"n"}},"gmx":{"desktop-webmail":{"2023-09":"y"}},"web-de":{"desktop-webmail":{"2023-09":"y"}}},
"notes":null,
"notes_by_num":{"1":"Partial. The `title` attribute is removed."}
},
@@ -3870,7 +3902,7 @@
"last_test_date":"2024-01-26",
"test_url":"https://www.caniemail.com/tests/html-hidden-attribute.html",
"test_results_url":"https://testi.at/proj/rlpli9r9trvs62rt7p",
"stats":{"apple-mail":{"macos":{"20":"y","21":"y","22":"y","23":"y"},"ios":{"14":"y","15":"y","16":"y","17":"y"}},"gmail":{"desktop-webmail":{"2024-01":"n"},"ios":{"2024-01":"n"},"android":{"2024-01":"n"},"mobile-webmail":{"2024-01":"n"}},"orange":{"desktop-webmail":{"2024-01":"u"},"ios":{"2024-01":"u"},"android":{"2024-01":"u"}},"outlook":{"windows":{"2003":"n","2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"windows-mail":{"2024-01":"n"},"macos":{"2016":"y","2024-01":"n"},"outlook-com":{"2024-01":"n"},"ios":{"2024-01":"n"},"android":{"2024-01":"n"}},"samsung-email":{"android":{"6.1":"y"}},"sfr":{"desktop-webmail":{"2024-03":"y"},"ios":{"2024-03":"y"},"android":{"2024-03":"y"}},"thunderbird":{"macos":{"60.3":"y"}},"aol":{"desktop-webmail":{"2024-01":"n"},"ios":{"2024-01":"u"},"android":{"2024-01":"u"}},"yahoo":{"desktop-webmail":{"2024-01":"n"},"ios":{"2024-01":"n"},"android":{"2024-01":"n"}},"protonmail":{"desktop-webmail":{"2024-01":"u"},"ios":{"2024-01":"u"},"android":{"2024-01":"u"}},"hey":{"desktop-webmail":{"2024-01":"u"}},"mail-ru":{"desktop-webmail":{"2024-01":"a #1"}},"fastmail":{"desktop-webmail":{"2024-01":"u"}},"laposte":{"desktop-webmail":{"2024-01":"u"}},"gmx":{"desktop-webmail":{"2024-01":"n"},"ios":{"2024-01":"u"},"android":{"2024-01":"u"}},"web-de":{"desktop-webmail":{"2024-01":"n"},"ios":{"2024-01":"u"},"android":{"2024-01":"u"}},"ionos-1and1":{"desktop-webmail":{"2024-01":"u"},"android":{"2024-01":"u"}}},
"stats":{"apple-mail":{"macos":{"20":"y","21":"y","22":"y","23":"y"},"ios":{"14":"y","15":"y","16":"y","17":"y"}},"gmail":{"desktop-webmail":{"2024-01":"n"},"ios":{"2024-01":"n"},"android":{"2024-01":"n"},"mobile-webmail":{"2024-01":"n"}},"orange":{"desktop-webmail":{"2024-01":"u"},"ios":{"2024-01":"u"},"android":{"2024-01":"u"}},"outlook":{"windows":{"2003":"n","2007":"n","2010":"n","2013":"n","2016":"n","2019":"n"},"windows-mail":{"2024-01":"n"},"macos":{"2016":"y","2024-01":"n"},"outlook-com":{"2024-01":"n"},"ios":{"2024-01":"n"},"android":{"2024-01":"n"}},"samsung-email":{"android":{"6.1":"y"}},"sfr":{"desktop-webmail":{"2024-03":"y"},"ios":{"2024-03":"y"},"android":{"2024-03":"y"}},"thunderbird":{"macos":{"60.3":"y"}},"aol":{"desktop-webmail":{"2024-01":"n"},"ios":{"2024-01":"u"},"android":{"2024-01":"u"}},"yahoo":{"desktop-webmail":{"2024-01":"n"},"ios":{"2024-01":"n"},"android":{"2024-01":"n"}},"protonmail":{"desktop-webmail":{"2024-01":"y"},"ios":{"2024-01":"y"},"android":{"2024-01":"y"}},"hey":{"desktop-webmail":{"2024-01":"u"}},"mail-ru":{"desktop-webmail":{"2024-01":"a #1"}},"fastmail":{"desktop-webmail":{"2024-01":"u"}},"laposte":{"desktop-webmail":{"2024-01":"u"}},"gmx":{"desktop-webmail":{"2024-01":"n"},"ios":{"2024-01":"u"},"android":{"2024-01":"u"}},"web-de":{"desktop-webmail":{"2024-01":"n"},"ios":{"2024-01":"u"},"android":{"2024-01":"u"}},"ionos-1and1":{"desktop-webmail":{"2024-01":"u"},"android":{"2024-01":"u"}}},
"notes":null,
"notes_by_num":{"1":"Does not support the unquoted attribute value syntax `<div hidden></div>`"}
},
@@ -4446,9 +4478,9 @@
"last_test_date":"2023-07-27",
"test_url":"https://www.caniemail.com/tests/html-style.html",
"test_results_url":"https://app.emailonacid.com/app/acidtest/CAMb612bxbVwRWPhM4wZKNhhdcdkNxj0Rj6dtRRw6LQUO/list",
"stats":{"apple-mail":{"macos":{"10.3":"y","16.0":"y"},"ios":{"10.3":"y","12.3":"y","16.2":"y"}},"gmail":{"desktop-webmail":{"2019-06":"a #1","2023-01":"a #1"},"ios":{"2019-06":"a #1 #2","2023-01":"a #1 #2"},"android":{"2019-06":"a #1 #2"},"mobile-webmail":{"2020-02":"n","2023-01":"n"}},"orange":{"desktop-webmail":{"2019-06":"y","2021-03":"y","2023-02":"y"},"ios":{"2019-06":"y","2023-02":"y"},"android":{"2019-06":"n","2019-08":"y","2023-02":"y"}},"outlook":{"windows":{"2003":"y","2007":"a #4","2010":"a #4","2013":"a #4","2016":"a #4","2019":"a #4"},"windows-mail":{"2020-01":"a #4","2023-01":"a #4"},"macos":{"2011":"y","2016":"y","2019":"y","2021":"y","16.80":"y"},"outlook-com":{"2019-06":"y","2023-01":"y","2024-01":"y"},"ios":{"2019-06":"y","2023-01":"y"},"android":{"2019-06":"y"}},"samsung-email":{"android":{"5.0.10.2":"y","6.0":"y"}},"sfr":{"desktop-webmail":{"2019-06":"y","2023-02":"y"},"ios":{"2019-06":"n","2023-02":"n"},"android":{"2019-06":"n","2023-02":"n"}},"thunderbird":{"macos":{"60.3":"y","102.7":"y"},"windows":{"102.7":"y"}},"aol":{"desktop-webmail":{"2020-01":"y","2023-01":"y"},"ios":{"2020-01":"y","2023-01":"y"},"android":{"2020-01":"y"}},"yahoo":{"desktop-webmail":{"2019-06":"y #5","2023-01":"y"},"ios":{"2019-06":"y","2023-01":"y"},"android":{"2019-06":"a #3","2023-01":"a #3"}},"protonmail":{"desktop-webmail":{"2020-03":"n","2022-02":"y","2023-01":"y"},"ios":{"2020-03":"n","2023-01":"a #1"},"android":{"2020-03":"a #1"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-09":"y"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"y"},"ios":{"2023-02":"n"},"android":{"2023-02":"n"}},"gmx":{"desktop-webmail":{"2022-11":"y","2023-07":"n"},"ios":{"2022-11":"y"},"android":{"2022-11":"y"}},"web-de":{"desktop-webmail":{"2022-11":"y","2025-04":"n"},"ios":{"2022-11":"y"},"android":{"2022-11":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-11":"y"},"android":{"2022-11":"y"}},"rainloop":{"desktop-webmail":{"2023-02":"n"}},"wp-pl":{"desktop-webmail":{"2023-12":"y"}}},
"stats":{"apple-mail":{"macos":{"10.3":"y","16.0":"y"},"ios":{"10.3":"y","12.3":"y","16.2":"y"}},"gmail":{"desktop-webmail":{"2019-06":"a #1","2023-01":"a #1 #6"},"ios":{"2019-06":"a #1 #2","2023-01":"a #1 #2"},"android":{"2019-06":"a #1 #2"},"mobile-webmail":{"2020-02":"n","2023-01":"n"}},"orange":{"desktop-webmail":{"2019-06":"y","2021-03":"y","2023-02":"y"},"ios":{"2019-06":"y","2023-02":"y"},"android":{"2019-06":"n","2019-08":"y","2023-02":"y"}},"outlook":{"windows":{"2003":"y","2007":"a #4","2010":"a #4","2013":"a #4","2016":"a #4","2019":"a #4"},"windows-mail":{"2020-01":"a #4","2023-01":"a #4"},"macos":{"2011":"y","2016":"y","2019":"y","2021":"y","16.80":"y"},"outlook-com":{"2019-06":"y","2023-01":"y","2024-01":"y"},"ios":{"2019-06":"y","2023-01":"y"},"android":{"2019-06":"y"}},"samsung-email":{"android":{"5.0.10.2":"y","6.0":"y"}},"sfr":{"desktop-webmail":{"2019-06":"y","2023-02":"y","2025-07":"n"},"ios":{"2019-06":"n","2023-02":"n","2025-07":"n"},"android":{"2019-06":"n","2023-02":"n"}},"thunderbird":{"macos":{"60.3":"y","102.7":"y"},"windows":{"102.7":"y"}},"aol":{"desktop-webmail":{"2020-01":"y","2023-01":"y"},"ios":{"2020-01":"y","2023-01":"y"},"android":{"2020-01":"y"}},"yahoo":{"desktop-webmail":{"2019-06":"y #5","2023-01":"y"},"ios":{"2019-06":"y","2023-01":"y"},"android":{"2019-06":"a #3","2023-01":"a #3","2025-06":"y"}},"protonmail":{"desktop-webmail":{"2020-03":"n","2022-02":"y","2023-01":"y"},"ios":{"2020-03":"n","2023-01":"a #1"},"android":{"2020-03":"a #1"}},"hey":{"desktop-webmail":{"2020-06":"y"}},"mail-ru":{"desktop-webmail":{"2020-09":"y"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"y","2025-07":"n"},"ios":{"2023-02":"n","2025-07":"n"},"android":{"2023-02":"n"}},"gmx":{"desktop-webmail":{"2022-11":"y","2023-07":"n"},"ios":{"2022-11":"y"},"android":{"2022-11":"y"}},"web-de":{"desktop-webmail":{"2022-11":"y","2025-04":"n"},"ios":{"2022-11":"y"},"android":{"2022-11":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-11":"y"},"android":{"2022-11":"y"}},"rainloop":{"desktop-webmail":{"2023-02":"n"}},"wp-pl":{"desktop-webmail":{"2023-12":"y"}}},
"notes":"",
"notes_by_num":{"1":"Partial. Not supported inside the `<body>`.","2":"Partial. Not supported with non Google accounts.","3":"Buggy. The first `<head>` in the HTML is removed, so `<style>` elements need to be in a second `<head>` element.","4":"Buggy. `<style>` elements need to be declared before their rules are used.","5":"A CSS rule following a CSS comment is ignored. (See [email-bugs#25](https://github.com/hteumeuleu/email-bugs/issues/25).)"}
"notes_by_num":{"1":"Partial. Not supported inside the `<body>`.","2":"Partial. Not supported with non Google accounts.","3":"Buggy. The first `<head>` in the HTML is removed, so `<style>` elements need to be in a second `<head>` element.","4":"Buggy. `<style>` elements need to be declared before their rules are used.","5":"A CSS rule following a CSS comment is ignored. (See [email-bugs#25](https://github.com/hteumeuleu/email-bugs/issues/25).)","6":"The size of the `<style>` tag [is limited to 16 KB](https://github.com/hteumeuleu/email-bugs/issues/90)"}
},
{

View File

@@ -1,8 +1,11 @@
package htmlcheck
import (
"context"
"errors"
"fmt"
"io"
"net"
"net/http"
"net/url"
"strings"
@@ -141,19 +144,20 @@ func inlineRemoteCSS(h string) (string, error) {
attributes := link.Attr
for _, a := range attributes {
if a.Key == "href" {
if !isURL(a.Val) {
// skip invalid URL
continue
}
if config.BlockRemoteCSSAndFonts {
logger.Log().Debugf("[html-check] skip testing remote CSS content: %s (--block-remote-css-and-fonts)", a.Val)
return h, nil
}
resp, err := downloadToBytes(a.Val)
if !isValidURL(a.Val) {
// skip invalid URL
logger.Log().Warnf("[html-check] ignoring unsupported stylesheet URL: %s", a.Val)
continue
}
resp, err := downloadCSSToBytes(a.Val)
if err != nil {
logger.Log().Warnf("[html-check] failed to download %s", a.Val)
logger.Log().Warnf("[html-check] %s", err.Error())
continue
}
@@ -182,14 +186,20 @@ func inlineRemoteCSS(h string) (string, error) {
return newDoc, nil
}
// DownloadToBytes returns a []byte slice from a URL
func downloadToBytes(url string) ([]byte, error) {
client := http.Client{
Timeout: 5 * time.Second,
// DownloadCSSToBytes returns a []byte slice from a URL.
// It requires the HTTP response code to be 200 and the content-type to be text/css.
// It will download a maximum of 5MB.
func downloadCSSToBytes(url string) ([]byte, error) {
client := newSafeHTTPClient()
req, err := http.NewRequestWithContext(context.TODO(), http.MethodGet, url, nil)
if err != nil {
return nil, err
}
req.Header.Set("User-Agent", "Mailpit HTML Checker/"+config.Version)
// Get the link response data
resp, err := client.Get(url)
resp, err := client.Do(req)
if err != nil {
return nil, err
}
@@ -200,7 +210,17 @@ func downloadToBytes(url string) ([]byte, error) {
return nil, err
}
body, err := io.ReadAll(resp.Body)
ct := strings.ToLower(resp.Header.Get("content-type"))
if !strings.Contains(ct, "text/css") {
err := fmt.Errorf("invalid CSS content-type from %s: \"%s\" (expected \"text/css\")", url, ct)
return nil, err
}
// set a limit on the number of bytes to read - max 5MB
limit := int64(5242880)
limitedReader := &io.LimitedReader{R: resp.Body, N: limit}
body, err := io.ReadAll(limitedReader)
if err != nil {
return nil, err
}
@@ -208,10 +228,12 @@ func downloadToBytes(url string) ([]byte, error) {
return body, nil
}
// Test if str is a URL
func isURL(str string) bool {
// Test if the string is a supported URL.
// The URL must have the "http" or "https" scheme, and must not contain any login info (http://user:pass@<host>).
func isValidURL(str string) bool {
u, err := url.Parse(str)
return err == nil && (u.Scheme == "http" || u.Scheme == "https") && u.Host != ""
return err == nil && (u.Scheme == "http" || u.Scheme == "https") && u.Hostname() != "" && u.User.String() == ""
}
// Test the HTML for inline CSS styles and styling attributes
@@ -249,3 +271,40 @@ func testInlineStyles(doc *goquery.Document) map[string]int {
return matches
}
func newSafeHTTPClient() *http.Client {
dialer := &net.Dialer{
Timeout: 5 * time.Second,
KeepAlive: 30 * time.Second,
}
tr := &http.Transport{
Proxy: nil, // avoid env proxy surprises unless you explicitly want it
DialContext: func(ctx context.Context, network, address string) (net.Conn, error) {
return dialer.DialContext(ctx, network, address)
},
TLSHandshakeTimeout: 5 * time.Second,
ResponseHeaderTimeout: 10 * time.Second,
ExpectContinueTimeout: 1 * time.Second,
IdleConnTimeout: 30 * time.Second,
MaxIdleConns: 50,
}
client := &http.Client{
Transport: tr,
Timeout: 15 * time.Second,
CheckRedirect: func(req *http.Request, via []*http.Request) error {
// re-validate every redirect hop.
if len(via) >= 3 {
return errors.New("too many redirects")
}
if !isValidURL(req.URL.String()) {
return errors.New("invalid redirect URL")
}
return nil
},
}
return client
}

View File

@@ -163,9 +163,9 @@ func (c CanIEmail) getTest(k string) (Warning, error) {
p++
s.Support = "partial"
noteIDS := noteMatch.FindStringSubmatch(fmt.Sprintf("%s", support))
noteIDs := noteMatch.FindStringSubmatch(fmt.Sprintf("%s", support))
for _, id := range noteIDS {
for _, id := range noteIDs {
s.NoteNumber = id
}
}

View File

@@ -31,7 +31,14 @@ var (
</html>`
expectedHTMLLinks = []string{
"http://example.com", "https://example.com", "HTTPS://EXAMPLE.COM", "http://localhost", "https://localhost", "https://127.0.0.1", "http://link with spaces", "http://example.com/?blaah=yes&test=true",
"http://example.com",
"https://example.com",
"HTTPS://EXAMPLE.COM",
"http://localhost",
"https://localhost",
"https://127.0.0.1",
"http://link with spaces",
"http://example.com/?blaah=yes&test=true",
"http://remote-host/style.css", // css
"https://example.com/image.jpg", // images
}
@@ -41,10 +48,18 @@ var (
[http://localhost]
www.google.com < ignored
|||http://example.com/?some=query-string|||
// RFC2396 appendix E states angle brackets are recommended for text/plain emails to
// recognize potential spaces in between the URL
<https://example.com/ link with spaces>
`
expectedTextLinks = []string{
"http://example.com", "https://example.com", "HTTPS://EXAMPLE.COM", "http://localhost", "http://example.com/?some=query-string",
"http://example.com",
"https://example.com",
"HTTPS://EXAMPLE.COM",
"http://localhost",
"http://example.com/?some=query-string",
"https://example.com/ link with spaces",
}
)

View File

@@ -30,9 +30,28 @@ func RunTests(msg *storage.Message, followRedirects bool) (Response, error) {
}
func extractTextLinks(msg *storage.Message) []string {
testLinkRe := regexp.MustCompile(`(?im)([^<]\b)((http|https):\/\/([\-\w@:%_\+'!.~#?,&\/\/=;]+))`)
// RFC2396 appendix E states angle brackets are recommended for text/plain emails to
// recognize potential spaces in between the URL
// @see https://www.rfc-editor.org/rfc/rfc2396#appendix-E
bracketLinkRe := regexp.MustCompile(`(?im)<((http|https):\/\/([\-\w@:%_\+'!.~#?,&\/\/=;][^>]+))>`)
links := []string{}
links = append(links, linkRe.FindAllString(msg.Text, -1)...)
matches := testLinkRe.FindAllStringSubmatch(msg.Text, -1)
for _, match := range matches {
if len(match) > 0 {
links = append(links, match[2])
}
}
angleMatches := bracketLinkRe.FindAllStringSubmatch(msg.Text, -1)
for _, match := range angleMatches {
if len(match) > 0 {
link := strings.ReplaceAll(match[1], "\n", "")
links = append(links, link)
}
}
return links
}

View File

@@ -84,6 +84,43 @@ func TestPOP3(t *testing.T) {
}
}
t.Log("Checking UIDL with multiple arguments")
_, err = c.Cmd("UIDL", false, 1, 2, 3)
if err == nil {
t.Error("UIDL with multiple arguments should return an error")
return
}
t.Log("Checking UIDL without a message id")
messageIDs, err := c.Uidl(0)
if err != nil {
t.Error(err.Error())
return
}
if len(messageIDs) != 50 {
assertEqual(t, len(messageIDs), 50, "incorrect UIDL message count")
}
t.Log("Checking UIDL with a message ID")
messageIDs, err = c.Uidl(50)
if err != nil {
t.Error(err.Error())
return
}
assertEqual(t, len(messageIDs), 1, "incorrect UIDL message count")
t.Log("Checking UIDL with an invalid message ID")
if _, err := c.Uidl(51); err == nil {
t.Errorf("UIDL 51 should return an error")
return
}
t.Log("Deleting 25 messages")
for i := 1; i <= 25; i++ {

View File

@@ -215,7 +215,7 @@ func handleTransactionCommand(conn net.Conn, cmd string, args []string, messages
for _, m := range messages {
totalSize += m.Size
}
sendResponse(conn, fmt.Sprintf("+OK %d %d", len(messages), int64(totalSize)))
sendResponse(conn, fmt.Sprintf("+OK %d %d", len(messages), totalSize))
case "LIST":
totalSize := uint64(0)
for _, m := range messages {
@@ -229,21 +229,41 @@ func handleTransactionCommand(conn net.Conn, cmd string, args []string, messages
sendResponse(conn, "-ERR no such message")
return
}
sendResponse(conn, fmt.Sprintf("+OK %d %d", nr, int64(messages[nr-1].Size)))
sendResponse(conn, fmt.Sprintf("+OK %d %d", nr, messages[nr-1].Size))
} else {
sendResponse(conn, fmt.Sprintf("+OK %d messages (%d octets)", len(messages), int64(totalSize)))
sendResponse(conn, fmt.Sprintf("+OK %d messages (%d octets)", len(messages), totalSize))
for row, m := range messages {
sendResponse(conn, fmt.Sprintf("%d %d", row+1, int64(m.Size))) // Convert Size to int64 when printing
sendResponse(conn, fmt.Sprintf("%d %d", row+1, m.Size))
}
sendResponse(conn, ".")
}
case "UIDL":
sendResponse(conn, "+OK unique-id listing follows")
for row, m := range messages {
sendResponse(conn, fmt.Sprintf("%d %s", row+1, m.ID))
if len(args) > 1 {
sendResponse(conn, "-ERR UIDL takes at most one argument")
} else if len(args) == 1 {
nr, err := strconv.Atoi(args[0])
if err != nil {
sendResponse(conn, "-ERR no such message")
return
}
if nr < 1 || nr > len(messages) {
sendResponse(conn, "-ERR no such message")
return
}
m := messages[nr-1]
sendResponse(conn, fmt.Sprintf("+OK %d %s", nr, m.ID))
} else {
sendResponse(conn, "+OK unique-id listing follows")
for row, m := range messages {
sendResponse(conn, fmt.Sprintf("%d %s", row+1, m.ID))
}
sendResponse(conn, ".")
}
sendResponse(conn, ".")
case "RETR":
if len(args) != 1 {
sendResponse(conn, "-ERR no such message")

View File

@@ -32,7 +32,7 @@ var (
)
// InitMetrics initializes all Prometheus metrics
func InitMetrics() {
func initMetrics() {
// Create metrics
totalMessages = prometheus.NewGauge(prometheus.GaugeOpts{
Name: "mailpit_messages",
@@ -107,8 +107,8 @@ func InitMetrics() {
}
// UpdateMetrics updates all metrics with current values
func UpdateMetrics() {
info := stats.Load()
func updateMetrics() {
info := stats.Load(false)
totalMessages.Set(float64(info.Messages))
unreadMessages.Set(float64(info.Unread))
@@ -130,7 +130,7 @@ func UpdateMetrics() {
}
}
// Returns the Prometheus handler & disables double compression in middleware
// GetHandler returns the Prometheus handler & disables double compression in middleware
func GetHandler() http.Handler {
return promhttp.HandlerFor(Registry, promhttp.HandlerOpts{
DisableCompression: true,
@@ -139,8 +139,8 @@ func GetHandler() http.Handler {
// StartUpdater starts the periodic metrics update routine
func StartUpdater() {
InitMetrics()
UpdateMetrics()
initMetrics()
updateMetrics()
// Start periodic updates
go func() {
@@ -148,7 +148,7 @@ func StartUpdater() {
defer ticker.Stop()
for range ticker.C {
UpdateMetrics()
updateMetrics()
}
}()
}
@@ -165,8 +165,9 @@ func StartSeparateServer() {
// Create a dedicated server instance
server := &http.Server{
Addr: config.PrometheusListen,
Handler: mux,
Addr: config.PrometheusListen,
Handler: mux,
ReadHeaderTimeout: 5 * time.Second,
}
// Start HTTP server

View File

@@ -4,25 +4,31 @@ import (
"crypto/tls"
"fmt"
"net/smtp"
"os"
"strings"
"github.com/axllent/mailpit/config"
"github.com/axllent/mailpit/internal/logger"
"github.com/axllent/mailpit/internal/tools"
"github.com/pkg/errors"
)
// Wrapper to forward messages if configured
func autoForwardMessage(from string, data *[]byte) {
func autoForwardMessage(from string, data *[]byte) error {
if config.SMTPForwardConfig.Host == "" {
return
return nil
}
if err := forward(from, *data); err != nil {
logger.Log().Errorf("[forward] error: %s", err.Error())
} else {
logger.Log().Debugf("[forward] message from %s to %s via %s:%d",
from, config.SMTPForwardConfig.To, config.SMTPForwardConfig.Host, config.SMTPForwardConfig.Port)
return errors.WithMessage(err, "[forward] error: %s")
}
logger.Log().Debugf(
"[forward] message from %s to %s via %s:%d",
from, config.SMTPForwardConfig.To, config.SMTPForwardConfig.Host, config.SMTPForwardConfig.Port,
)
return nil
}
func createForwardingSMTPClient(config config.SMTPForwardConfigStruct, addr string) (*smtp.Client, error) {
@@ -50,6 +56,13 @@ func createForwardingSMTPClient(config config.SMTPForwardConfigStruct, addr stri
return nil, fmt.Errorf("error connecting to %s: %v", addr, err)
}
// Set the hostname for HELO/EHLO
if hostname, err := os.Hostname(); err == nil {
if err := client.Hello(hostname); err != nil {
return nil, fmt.Errorf("error saying HELO/EHLO to %s: %v", addr, err)
}
}
if config.STARTTLS {
tlsConf := &tls.Config{ServerName: config.Host} // #nosec
tlsConf.InsecureSkipVerify = config.AllowInsecure
@@ -100,6 +113,9 @@ func forward(from string, msg []byte) error {
for _, addr := range to {
if err = c.Rcpt(addr); err != nil {
logger.Log().Warnf("error response to RCPT command for %s: %s", addr, err.Error())
if config.SMTPForwardConfig.ForwardSMTPErrors {
return errors.WithMessagef(err, "error response to RCPT command for %s", addr)
}
}
}

View File

@@ -17,6 +17,7 @@ import (
"github.com/axllent/mailpit/internal/tools"
"github.com/axllent/mailpit/server/websockets"
"github.com/lithammer/shortuuid/v4"
"github.com/pkg/errors"
)
var (
@@ -73,10 +74,36 @@ func SaveToDatabase(origin net.Addr, from string, to []string, data []byte, smtp
}
// if enabled, this may conditionally relay the email through to the preconfigured smtp server
autoRelayMessage(from, to, &data)
if relayErr := autoRelayMessage(from, to, &data); relayErr != nil {
logger.Log().Error(relayErr.Error())
if config.SMTPRelayConfig.ForwardSMTPErrors {
for {
unwrappedErr := errors.Unwrap(relayErr)
if unwrappedErr == nil {
break
}
relayErr = unwrappedErr
}
return "", relayErr
}
}
// if enabled, this will forward a copy to preconfigured addresses
autoForwardMessage(from, &data)
if forwardErr := autoForwardMessage(from, &data); forwardErr != nil {
logger.Log().Error(forwardErr.Error())
if config.SMTPForwardConfig.ForwardSMTPErrors {
for {
unwrappedErr := errors.Unwrap(forwardErr)
if unwrappedErr == nil {
break
}
forwardErr = unwrappedErr
}
return "", forwardErr
}
}
// build array of all addresses in the header to compare to the []to array
emails, hasBccHeader := scanAddressesInHeader(msg.Header)
@@ -194,15 +221,16 @@ func listenAndServe(addr string, handler MsgIDHandler, authHandler AuthHandler)
Debug = true // to enable Mailpit logging
srv := &Server{
Addr: addr,
MsgIDHandler: handler,
HandlerRcpt: handlerRcpt,
AppName: "Mailpit",
Hostname: "",
AuthHandler: nil,
AuthRequired: false,
MaxRecipients: config.SMTPMaxRecipients,
DisableReverseDNS: DisableReverseDNS,
Addr: addr,
MsgIDHandler: handler,
HandlerRcpt: handlerRcpt,
AppName: "Mailpit",
Hostname: "",
AuthHandler: nil,
AuthRequired: false,
MaxRecipients: config.SMTPMaxRecipients,
IgnoreRejectedRecipients: config.SMTPIgnoreRejectedRecipients,
DisableReverseDNS: DisableReverseDNS,
LogRead: func(remoteIP, verb, line string) {
logger.Log().Debugf("[smtpd] %s (%s) %s", verbLogTranslator(verb), remoteIP, line)
},
@@ -224,15 +252,27 @@ func listenAndServe(addr string, handler MsgIDHandler, authHandler AuthHandler)
}
if config.SMTPAuthAllowInsecure {
srv.AuthMechs = map[string]bool{"CRAM-MD5": false, "PLAIN": true, "LOGIN": true}
srv.AuthMechs = map[string]bool{
"CRAM-MD5": false,
"PLAIN": true,
"LOGIN": true,
}
}
if auth.SMTPCredentials != nil {
srv.AuthMechs = map[string]bool{"CRAM-MD5": false, "PLAIN": true, "LOGIN": true}
srv.AuthMechs = map[string]bool{
"CRAM-MD5": false,
"PLAIN": true,
"LOGIN": true,
}
srv.AuthHandler = authHandler
srv.AuthRequired = true
} else if config.SMTPAuthAcceptAny {
srv.AuthMechs = map[string]bool{"CRAM-MD5": false, "PLAIN": true, "LOGIN": true}
srv.AuthMechs = map[string]bool{
"CRAM-MD5": false,
"PLAIN": true,
"LOGIN": true,
}
srv.AuthHandler = authHandlerAny
}

View File

@@ -2,18 +2,19 @@ package smtpd
import (
"crypto/tls"
"errors"
"fmt"
"net/smtp"
"os"
"strings"
"github.com/axllent/mailpit/config"
"github.com/axllent/mailpit/internal/logger"
"github.com/axllent/mailpit/internal/tools"
"github.com/pkg/errors"
)
// Wrapper to auto relay messages if configured
func autoRelayMessage(from string, to []string, data *[]byte) {
func autoRelayMessage(from string, to []string, data *[]byte) error {
if config.SMTPRelayConfig.BlockedRecipientsRegexp != nil {
filteredTo := []string{}
for _, address := range to {
@@ -28,16 +29,18 @@ func autoRelayMessage(from string, to []string, data *[]byte) {
}
if len(to) == 0 {
return
return nil
}
if config.SMTPRelayAll {
if err := Relay(from, to, *data); err != nil {
logger.Log().Errorf("[relay] error: %s", err.Error())
} else {
logger.Log().Debugf("[relay] sent message to %s from %s via %s:%d",
strings.Join(to, ", "), from, config.SMTPRelayConfig.Host, config.SMTPRelayConfig.Port)
return errors.WithMessage(err, "[relay] error")
}
logger.Log().Debugf(
"[relay] sent message to %s from %s via %s:%d",
strings.Join(to, ", "), from, config.SMTPRelayConfig.Host, config.SMTPRelayConfig.Port,
)
} else if config.SMTPRelayMatchingRegexp != nil {
filtered := []string{}
for _, t := range to {
@@ -47,16 +50,20 @@ func autoRelayMessage(from string, to []string, data *[]byte) {
}
if len(filtered) == 0 {
return
return nil
}
if err := Relay(from, filtered, *data); err != nil {
logger.Log().Errorf("[relay] error: %s", err.Error())
} else {
logger.Log().Debugf("[relay] auto-relay message to %s from %s via %s:%d",
strings.Join(filtered, ", "), from, config.SMTPRelayConfig.Host, config.SMTPRelayConfig.Port)
return errors.WithMessage(err, "[relay] error")
}
logger.Log().Debugf(
"[relay] auto-relay message to %s from %s via %s:%d",
strings.Join(filtered, ", "), from, config.SMTPRelayConfig.Host, config.SMTPRelayConfig.Port,
)
}
return nil
}
func createRelaySMTPClient(config config.SMTPRelayConfigStruct, addr string) (*smtp.Client, error) {
@@ -84,6 +91,13 @@ func createRelaySMTPClient(config config.SMTPRelayConfigStruct, addr string) (*s
return nil, fmt.Errorf("error connecting to %s: %v", addr, err)
}
// Set the hostname for HELO/EHLO
if hostname, err := os.Hostname(); err == nil {
if err := client.Hello(hostname); err != nil {
return nil, fmt.Errorf("error saying HELO/EHLO to %s: %v", addr, err)
}
}
if config.STARTTLS {
tlsConf := &tls.Config{ServerName: config.Host} // #nosec
tlsConf.InsecureSkipVerify = config.AllowInsecure
@@ -126,26 +140,29 @@ func Relay(from string, to []string, msg []byte) error {
}
if err = c.Mail(from); err != nil {
return fmt.Errorf("error response to MAIL command: %s", err.Error())
return errors.WithMessage(err, "error sending MAIL command")
}
for _, addr := range to {
if err = c.Rcpt(addr); err != nil {
logger.Log().Warnf("error response to RCPT command for %s: %s", addr, err.Error())
if config.SMTPRelayConfig.ForwardSMTPErrors {
return errors.WithMessagef(err, "error response to RCPT command for %s", addr)
}
}
}
w, err := c.Data()
if err != nil {
return fmt.Errorf("error response to DATA command: %s", err.Error())
return errors.WithMessage(err, "error response to DATA command")
}
if _, err := w.Write(msg); err != nil {
return fmt.Errorf("error sending message: %s", err.Error())
return errors.WithMessage(err, "error sending message")
}
if err := w.Close(); err != nil {
return fmt.Errorf("error closing connection: %s", err.Error())
return errors.WithMessage(err, "error closing connection")
}
return c.Quit()
@@ -178,7 +195,10 @@ type loginAuth struct {
// LoginAuth authentication
func LoginAuth(username, password string) smtp.Auth {
return &loginAuth{username, password}
return &loginAuth{
username,
password,
}
}
func (a *loginAuth) Start(_ *smtp.ServerInfo) (string, []byte, error) {

View File

@@ -15,6 +15,7 @@ import (
"io/fs"
"log"
"net"
"net/mail"
"os"
"regexp"
"strconv"
@@ -92,26 +93,27 @@ type LogFunc func(remoteIP, verb, line string)
// Server is an SMTP server.
type Server struct {
Addr string // TCP address to listen on, defaults to ":25" (all addresses, port 25) if empty
AppName string
AuthHandler AuthHandler
AuthMechs map[string]bool // Override list of allowed authentication mechanisms. Currently supported: LOGIN, PLAIN, CRAM-MD5. Enabling LOGIN and PLAIN will reduce RFC 4954 compliance.
AuthRequired bool // Require authentication for every command except AUTH, EHLO, HELO, NOOP, RSET or QUIT as per RFC 4954. Ignored if AuthHandler is not configured.
DisableReverseDNS bool // Disable reverse DNS lookups, enforces "unknown" hostname
Handler Handler
HandlerRcpt HandlerRcpt
Hostname string
LogRead LogFunc
LogWrite LogFunc
MaxSize int // Maximum message size allowed, in bytes
MaxRecipients int // Maximum number of recipients, defaults to 100.
MsgIDHandler MsgIDHandler
Timeout time.Duration
TLSConfig *tls.Config
TLSListener bool // Listen for incoming TLS connections only (not recommended as it may reduce compatibility). Ignored if TLS is not configured.
TLSRequired bool // Require TLS for every command except NOOP, EHLO, STARTTLS, or QUIT as per RFC 3207. Ignored if TLS is not configured.
Protocol string // Default tcp, supports unix
SocketPerm fs.FileMode // if using Unix socket, socket permissions
Addr string // TCP address to listen on, defaults to ":25" (all addresses, port 25) if empty
AppName string
AuthHandler AuthHandler
AuthMechs map[string]bool // Override list of allowed authentication mechanisms. Currently supported: LOGIN, PLAIN, CRAM-MD5. Enabling LOGIN and PLAIN will reduce RFC 4954 compliance.
AuthRequired bool // Require authentication for every command except AUTH, EHLO, HELO, NOOP, RSET or QUIT as per RFC 4954. Ignored if AuthHandler is not configured.
DisableReverseDNS bool // Disable reverse DNS lookups, enforces "unknown" hostname
Handler Handler
HandlerRcpt HandlerRcpt
Hostname string
LogRead LogFunc
LogWrite LogFunc
MaxSize int // Maximum message size allowed, in bytes
MaxRecipients int // Maximum number of recipients, defaults to 100.
MsgIDHandler MsgIDHandler
IgnoreRejectedRecipients bool // Accept emails to rejected recipients with 2xx response but silently drop them
Timeout time.Duration
TLSConfig *tls.Config
TLSListener bool // Listen for incoming TLS connections only (not recommended as it may reduce compatibility). Ignored if TLS is not configured.
TLSRequired bool // Require TLS for every command except NOOP, EHLO, STARTTLS, or QUIT as per RFC 3207. Ignored if TLS is not configured.
Protocol string // Default tcp, supports unix
SocketPerm fs.FileMode // if using Unix socket, socket permissions
inShutdown int32 // server was closed or shutdown
openSessions int32 // count of open sessions
@@ -360,9 +362,11 @@ func (s *session) serve() {
// otherwise results in a 5s timeout for each connection
defer func(c net.Conn) { _ = c.Close() }(s.conn)
var gotEHLO bool
var from string
var gotFrom bool
var gotFROM bool
var to []string
var hasRejectedRecipients bool
var buffer bytes.Buffer
// RFC 5321 specifies support for minimum of 100 recipients is required.
@@ -394,18 +398,22 @@ loop:
s.writef("250 %s greets %s", s.srv.Hostname, s.remoteName)
// RFC 2821 section 4.1.4 specifies that EHLO has the same effect as RSET, so reset for HELO too.
gotEHLO = true
from = ""
gotFrom = false
gotFROM = false
to = nil
hasRejectedRecipients = false
buffer.Reset()
case "EHLO":
s.remoteName = args
s.writef("%s", s.makeEHLOResponse())
// RFC 2821 section 4.1.4 specifies that EHLO has the same effect as RSET.
gotEHLO = true
from = ""
gotFrom = false
gotFROM = false
to = nil
hasRejectedRecipients = false
buffer.Reset()
case "MAIL":
if s.srv.TLSConfig != nil && s.srv.TLSRequired && !s.tls {
@@ -416,10 +424,22 @@ loop:
s.writef("530 5.7.0 Authentication required")
break
}
if !gotEHLO {
s.writef("503 5.5.1 Bad sequence of commands (HELO/EHLO required before MAIL)")
break
}
if to != nil {
s.writef("503 5.5.1 Bad sequence of commands (RSET/HELO/EHLO required before MAIL)")
break
}
match := mailFromRE.FindStringSubmatch(args)
match, err := extractAndValidateAddress(mailFromRE, args)
if match == nil {
s.writef("501 5.5.4 Syntax error in parameters or arguments (invalid FROM parameter)")
if err != nil {
s.writef("%s", err.Error())
} else {
s.writef("501 5.5.4 Syntax error in parameters or arguments (invalid FROM parameter)")
}
} else {
// Mailpit Chaos
if fail, code := chaos.Config.Sender.Trigger(); fail {
@@ -433,7 +453,7 @@ loop:
if sizeMatch == nil {
// ignore other parameter
from = match[1]
gotFrom = true
gotFROM = true
s.writef("250 2.1.0 Ok")
} else {
// Enforce the maximum message size if one is set.
@@ -445,18 +465,19 @@ loop:
s.writef("%s", err.Error())
} else { // SIZE ok
from = match[1]
gotFrom = true
gotFROM = true
s.writef("250 2.1.0 Ok")
}
}
} else { // No parameters after FROM
from = match[1]
gotFrom = true
gotFROM = true
s.writef("250 2.1.0 Ok")
}
}
to = nil
hasRejectedRecipients = false
buffer.Reset()
case "RCPT":
if s.srv.TLSConfig != nil && s.srv.TLSRequired && !s.tls {
@@ -467,14 +488,18 @@ loop:
s.writef("530 5.7.0 Authentication required")
break
}
if !gotFrom {
if !gotFROM {
s.writef("503 5.5.1 Bad sequence of commands (MAIL required before RCPT)")
break
}
match := rcptToRE.FindStringSubmatch(args)
match, err := extractAndValidateAddress(rcptToRE, args)
if match == nil {
s.writef("501 5.5.4 Syntax error in parameters or arguments (invalid TO parameter)")
if err != nil {
s.writef("%s", err.Error())
} else {
s.writef("501 5.5.4 Syntax error in parameters or arguments (invalid TO parameter)")
}
} else {
// Mailpit Chaos
if fail, code := chaos.Config.Recipient.Trigger(); fail {
@@ -492,6 +517,9 @@ loop:
if accept {
to = append(to, match[1])
s.writef("250 2.1.5 Ok")
} else if s.srv.IgnoreRejectedRecipients {
hasRejectedRecipients = true
s.writef("250 2.1.5 Ok")
} else {
s.writef("550 5.1.0 Requested action not taken: mailbox unavailable")
}
@@ -506,7 +534,8 @@ loop:
s.writef("530 5.7.0 Authentication required")
break
}
if !gotFrom || len(to) == 0 {
hasRecipients := len(to) > 0 || hasRejectedRecipients
if !gotFROM || !hasRecipients {
s.writef("503 5.5.1 Bad sequence of commands (MAIL & RCPT required before DATA)")
break
}
@@ -536,11 +565,13 @@ loop:
// Create Received header & write message body into buffer.
buffer.Reset()
buffer.Write(s.makeHeaders(to))
if len(to) > 0 {
buffer.Write(s.makeHeaders(to))
}
buffer.Write(data)
// Pass mail on to handler.
if s.srv.Handler != nil {
// Pass mail on to handler only if there are valid recipients.
if len(to) > 0 && s.srv.Handler != nil {
err := s.srv.Handler(s.conn.RemoteAddr(), from, to, buffer.Bytes())
if err != nil {
checkErrFormat := regexp.MustCompile(`^([2-5][0-9]{2})[\s\-](.+)$`)
@@ -552,7 +583,7 @@ loop:
break
}
s.writef("250 2.0.0 Ok: queued")
} else if s.srv.MsgIDHandler != nil {
} else if len(to) > 0 && s.srv.MsgIDHandler != nil {
msgID, err := s.srv.MsgIDHandler(s.conn.RemoteAddr(), from, to, buffer.Bytes(), s.username)
if err != nil {
checkErrFormat := regexp.MustCompile(`^([2-5][0-9]{2})[\s\-](.+)$`)
@@ -570,13 +601,21 @@ loop:
s.writef("250 2.0.0 Ok: queued")
}
} else {
if hasRejectedRecipients && Debug {
if s.srv.LogWrite != nil {
s.srv.LogWrite(s.remoteIP, "DEBUG", "Message from sender silently dropped (rejected recipients)")
} else {
log.Printf("%s DEBUG Message from sender silently dropped (rejected recipients)", s.remoteIP)
}
}
s.writef("250 2.0.0 Ok: queued")
}
// Reset for next mail.
from = ""
gotFrom = false
gotFROM = false
to = nil
hasRejectedRecipients = false
buffer.Reset()
case "QUIT":
s.writef("221 2.0.0 %s %s ESMTP Service closing transmission channel", s.srv.Hostname, s.srv.AppName)
@@ -588,8 +627,9 @@ loop:
}
s.writef("250 2.0.0 Ok")
from = ""
gotFrom = false
gotFROM = false
to = nil
hasRejectedRecipients = false
buffer.Reset()
case "NOOP":
s.writef("250 2.0.0 Ok")
@@ -664,8 +704,9 @@ loop:
// RFC 3207 specifies that the server must discard any prior knowledge obtained from the client.
s.remoteName = ""
from = ""
gotFrom = false
gotFROM = false
to = nil
hasRejectedRecipients = false
buffer.Reset()
case "AUTH":
if s.srv.TLSConfig != nil && s.srv.TLSRequired && !s.tls {
@@ -685,7 +726,7 @@ loop:
}
// RFC 4954 specifies that AUTH is not permitted during mail transactions.
if gotFrom || len(to) > 0 {
if gotFROM || len(to) > 0 {
s.writef("503 5.5.1 Bad sequence of commands (AUTH not permitted during mail transaction)")
break
}
@@ -954,6 +995,12 @@ func (s *session) handleAuthPlain(arg string) (bool, error) {
// Validate credentials.
authenticated, err := s.srv.AuthHandler(s.conn.RemoteAddr(), "PLAIN", parts[1], parts[2], nil)
if authenticated {
uname := string(parts[1])
s.username = &uname
} else {
s.username = nil
}
return authenticated, err
}
@@ -987,3 +1034,35 @@ func (s *session) handleAuthCramMD5() (bool, error) {
return authenticated, err
}
// Extract and validate email address from a regex match.
// This ensures that only RFC 5322 compliant email addresses are accepted (if set).
func extractAndValidateAddress(re *regexp.Regexp, args string) ([]string, error) {
match := re.FindStringSubmatch(args)
if match == nil {
return nil, nil
}
if strings.Contains(match[1], " ") {
return nil, errors.New("553 5.1.3 The address is not a valid RFC 5321 address")
}
// first argument will be the email address, validate it if not empty
if match[1] != "" {
a, err := mail.ParseAddress(match[1])
if err != nil {
return nil, errors.New("553 5.1.3 The address is not a valid RFC 5321 address")
}
// https://datatracker.ietf.org/doc/html/rfc5321#section-4.5.3.1
// RFC states that the local part of an email address SHOULD not exceed 64 characters
// and the domain part SHOULD not exceed 255 characters, however as per https://github.com/axllent/mailpit/issues/620
// it appears that investigated mail servers do not actually implement this limit, but rather enforce
// a much larger limit (ie: 1024 characters).
if len(a.Address) > 1024 {
return nil, errors.New("500 The address is too long")
}
}
return match, nil
}

View File

@@ -104,6 +104,19 @@ func TestCmdEHLO(t *testing.T) {
// See RFC 2821 section 4.1.4 for more detail.
cmdCode(t, conn, "MAIL FROM:<sender@example.com>", "250")
cmdCode(t, conn, "RCPT TO:<recipient@example.com>", "250")
// test invalid addresses & header injection
cmdCode(t, conn, "RCPT TO: <recipientrecipientrecipientreciprecipientrecipientrecipientreciptrecipientrecipientrecipientreciprecipientrecipientrecipientreciptrecipientrecipientrecipientreciprecipientrecipientrecipientreciptrecipientrecipientrecipientreciprecipientrecipientrecipientreciptrecipientrecipientrecipientreciprecipientrecipientrecipientreciptrecipientrecipientrecipientreciprecipientrecipientrecipientreciptrecipientrecipientrecipientreciprecipientrecipientrecipientreciptrecipientrecipientrecipientreciprecipientrecipientrecipientreciptrecipientrecipientrecipientreciprecipientrecipientrecipientreciptrecipientrecipientrecipientreciprecipientrecipientrecipientreciptrecipientrecipientrecipientreciprecipientrecipientrecipientreciptrecipientrecipientrecipientreciprecipientrecipientrecipientreciptrecipientrecipientrecipientreciprecipientrecipientrecipientreciptrecipientrecipientrecipientreciprecipientrecipientrecipientreciptrecipientrecipientrecipient@exampleexampleexampleexampleexampleexampleexampleexampleexampleexampleexampleexampleexampleexampleexampleexampleexample.com>", "500") // too long
cmdCode(t, conn, "RCPT TO:<recipientexample.com>", "553")
cmdCode(t, conn, "RCPT TO: <recipient@test@example.com>", "553")
cmdCode(t, conn, "RCPT TO: <recipient@@example.com>", "553")
cmdCode(t, conn, "RCPT TO: <recipientexample.com>", "553")
cmdCode(t, conn, "RCPT TO: <recipientexample.com>", "501")
cmdCode(t, conn, "RCPT TO:<recipient\rexample.com>", "553")
cmdCode(t, conn, "RCPT TO: <recipient\rexample.com>", "553")
cmdCode(t, conn, "RCPT TO: <recipient\rexample.com>", "501")
cmdCode(t, conn, "RCPT TO: <>", "501") // empty address not allowed here
cmdCode(t, conn, "EHLO host.example.com", "250")
cmdCode(t, conn, "DATA", "503")
@@ -111,6 +124,41 @@ func TestCmdEHLO(t *testing.T) {
_ = conn.Close()
}
func TestCmdMAILBeforeEHLO(t *testing.T) {
conn := newConn(t, &Server{})
// RFC 5321 §4.1.4 — Order of Commands states (emphasis added):
// “The SMTP client MUST issue HELO or EHLO before any other SMTP commands.”
cmdCode(t, conn, "MAIL FROM:<sender@example.com>", "503")
cmdCode(t, conn, "QUIT", "221")
_ = conn.Close()
}
func TestCmdMAILAfterRCPT(t *testing.T) {
conn := newConn(t, &Server{})
// Send EHLO, expect greeting
cmdCode(t, conn, "EHLO host.example.com", "250")
// Send MAIL FROM
cmdCode(t, conn, "MAIL FROM:<sender@example.com>", "250")
// Send RCPT TO
cmdCode(t, conn, "RCPT TO:<recipient@example.com>", "250")
// MAIL FROM must not come after RCPT TO in the same transaction
cmdCode(t, conn, "MAIL FROM:<sender2@example.com>", "503")
// RSET to clear the transaction
cmdCode(t, conn, "RSET", "250")
// Now the MAIL FROM should be accepted
cmdCode(t, conn, "MAIL FROM:<sender2@example.com>", "250")
cmdCode(t, conn, "QUIT", "221")
_ = conn.Close()
}
func TestCmdRSET(t *testing.T) {
conn := newConn(t, &Server{})
cmdCode(t, conn, "EHLO host.example.com", "250")
@@ -131,7 +179,7 @@ func TestCmdMAIL(t *testing.T) {
// MAIL with no FROM arg should return 501 syntax error
cmdCode(t, conn, "MAIL", "501")
// MAIL with empty FROM arg should return 501 syntax error
// // MAIL with empty FROM arg should return 501 syntax error
cmdCode(t, conn, "MAIL FROM:", "501")
cmdCode(t, conn, "MAIL FROM: ", "501")
cmdCode(t, conn, "MAIL FROM: ", "501")
@@ -145,6 +193,20 @@ func TestCmdMAIL(t *testing.T) {
// MAIL with seemingly valid but noncompliant FROM arg (double space after the colon) should return 501 syntax error
cmdCode(t, conn, "MAIL FROM: <sender@example.com>", "501")
// test invalid addresses & header injection
cmdCode(t, conn, "MAIL FROM: <sendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersendersender@exampleexampleexampleexampleexampleexampleexampleexampleexampleexampleexampleexampleexampleexampleexampleexampleexample.com>", "500") // too long
cmdCode(t, conn, "MAIL FROM:<sender\rexample.com>", "553")
cmdCode(t, conn, "MAIL FROM: <sender\rexample.com>", "553")
cmdCode(t, conn, "MAIL FROM: <sender\rexample.com>", "501")
cmdCode(t, conn, "MAIL FROM:<senderexample.com>", "553")
cmdCode(t, conn, "MAIL FROM: <sender@@example.com>", "553")
cmdCode(t, conn, "MAIL FROM: <sender@test@example.com>", "553")
cmdCode(t, conn, "MAIL FROM: <senderexample.com>", "553")
cmdCode(t, conn, "MAIL FROM: <senderexample.com>", "501")
cmdCode(t, conn, "MAIL FROM: < sender@example.com >", "553")
cmdCode(t, conn, "MAIL FROM: < sender@example.com>", "553")
cmdCode(t, conn, "MAIL FROM: <sender@example.com >", "553")
// MAIL with valid SIZE parameter should return 250 Ok
cmdCode(t, conn, "MAIL FROM:<sender@example.com> SIZE=1000", "250")
@@ -212,6 +274,7 @@ func TestCmdRCPT(t *testing.T) {
cmdCode(t, conn, "RCPT TO:", "501")
cmdCode(t, conn, "RCPT TO: ", "501")
cmdCode(t, conn, "RCPT TO: ", "501")
cmdCode(t, conn, "RCPT TO:<@route.example user@example.com>", "553")
// RCPT with valid TO arg should return 250 Ok
cmdCode(t, conn, "RCPT TO:<recipient@example.com>", "250")
@@ -1598,3 +1661,172 @@ func TestCmdShutdown(t *testing.T) {
_ = conn.Close()
}
type mockDropRejectedHandler struct {
handlerCalled int
lastFrom string
lastTo []string
msgIDCalled int
lastMsgIDFrom string
lastMsgIDTo []string
}
func (m *mockDropRejectedHandler) handler(remoteAddr net.Addr, from string, to []string, data []byte) error {
m.handlerCalled++
m.lastFrom = from
m.lastTo = append([]string{}, to...) // copy slice
return nil
}
func (m *mockDropRejectedHandler) msgIDHandler(remoteAddr net.Addr, from string, to []string, data []byte, username *string) (string, error) {
m.msgIDCalled++
m.lastMsgIDFrom = from
m.lastMsgIDTo = append([]string{}, to...) // copy slice
return "test-message-id", nil
}
// Test the IgnoreRejectedRecipients option
func TestIgnoreRejectedRecipients(t *testing.T) {
tests := []struct {
name string
IgnoreRejectedRecipients bool
handlerRcpt func(net.Addr, string, string) bool
rcptCommands []struct{ addr, expectedCode string }
expectedHandlerCalls int
expectedHandlerRecipients []string
useMsgIDHandler bool
}{
{
name: "Disabled_DefaultBehavior",
IgnoreRejectedRecipients: false,
handlerRcpt: func(remoteAddr net.Addr, from string, to string) bool {
return !strings.HasSuffix(to, "@rejected.com")
},
rcptCommands: []struct{ addr, expectedCode string }{
{"valid@example.com", "250"},
{"invalid@rejected.com", "550"},
},
expectedHandlerCalls: 1,
expectedHandlerRecipients: []string{"valid@example.com"},
},
{
name: "Enabled_MixedRecipients",
IgnoreRejectedRecipients: true,
handlerRcpt: func(remoteAddr net.Addr, from string, to string) bool {
return !strings.HasSuffix(to, "@rejected.com")
},
rcptCommands: []struct{ addr, expectedCode string }{
{"valid1@example.com", "250"},
{"valid2@example.com", "250"},
{"invalid1@rejected.com", "250"}, // Now accepted but dropped
{"invalid2@rejected.com", "250"}, // Now accepted but dropped
},
expectedHandlerCalls: 1,
expectedHandlerRecipients: []string{"valid1@example.com", "valid2@example.com"},
},
{
name: "Enabled_AllRejected",
IgnoreRejectedRecipients: true,
handlerRcpt: func(remoteAddr net.Addr, from string, to string) bool {
return false // Reject all
},
rcptCommands: []struct{ addr, expectedCode string }{
{"test1@example.com", "250"}, // Accepted but dropped
{"test2@example.com", "250"}, // Accepted but dropped
},
expectedHandlerCalls: 0, // No handler calls since all rejected
expectedHandlerRecipients: nil,
},
{
name: "Enabled_OnlyValid",
IgnoreRejectedRecipients: true,
handlerRcpt: func(remoteAddr net.Addr, from string, to string) bool {
return strings.HasSuffix(to, "@valid.com")
},
rcptCommands: []struct{ addr, expectedCode string }{
{"user1@valid.com", "250"},
{"user2@valid.com", "250"},
{"user3@valid.com", "250"},
},
expectedHandlerCalls: 1,
expectedHandlerRecipients: []string{"user1@valid.com", "user2@valid.com", "user3@valid.com"},
},
{
name: "Enabled_WithMsgIDHandler",
IgnoreRejectedRecipients: true,
handlerRcpt: func(remoteAddr net.Addr, from string, to string) bool {
return !strings.HasSuffix(to, "@rejected.com")
},
rcptCommands: []struct{ addr, expectedCode string }{
{"valid@example.com", "250"},
{"invalid@rejected.com", "250"}, // Accepted but dropped
},
expectedHandlerCalls: 1,
expectedHandlerRecipients: []string{"valid@example.com"},
useMsgIDHandler: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
mock := &mockDropRejectedHandler{}
server := &Server{
Hostname: "mail.example.com",
AppName: "TestMail",
MaxRecipients: 100,
HandlerRcpt: tt.handlerRcpt,
IgnoreRejectedRecipients: tt.IgnoreRejectedRecipients,
}
if tt.useMsgIDHandler {
server.MsgIDHandler = mock.msgIDHandler
} else {
server.Handler = mock.handler
}
conn := newConn(t, server)
defer func() { _ = conn.Close() }()
cmdCode(t, conn, "HELO host.example.com", "250")
cmdCode(t, conn, "MAIL FROM:<sender@example.com>", "250")
// Send RCPT commands
for _, rcpt := range tt.rcptCommands {
cmdCode(t, conn, "RCPT TO:<"+rcpt.addr+">", rcpt.expectedCode)
}
// Send DATA
cmdCode(t, conn, "DATA", "354")
cmdCode(t, conn, "Subject: Test\r\n\r\nTest message\r\n.", "250")
cmdCode(t, conn, "QUIT", "221")
// Verify handler calls
if tt.useMsgIDHandler {
if mock.msgIDCalled != tt.expectedHandlerCalls {
t.Errorf("Expected %d MsgIDHandler calls, got %d", tt.expectedHandlerCalls, mock.msgIDCalled)
}
if tt.expectedHandlerCalls > 0 {
if mock.lastMsgIDFrom != "sender@example.com" {
t.Errorf("Expected from 'sender@example.com', got '%s'", mock.lastMsgIDFrom)
}
if !reflect.DeepEqual(mock.lastMsgIDTo, tt.expectedHandlerRecipients) {
t.Errorf("Expected recipients %v, got %v", tt.expectedHandlerRecipients, mock.lastMsgIDTo)
}
}
} else {
if mock.handlerCalled != tt.expectedHandlerCalls {
t.Errorf("Expected %d handler calls, got %d", tt.expectedHandlerCalls, mock.handlerCalled)
}
if tt.expectedHandlerCalls > 0 {
if mock.lastFrom != "sender@example.com" {
t.Errorf("Expected from 'sender@example.com', got '%s'", mock.lastFrom)
}
if !reflect.DeepEqual(mock.lastTo, tt.expectedHandlerRecipients) {
t.Errorf("Expected recipients %v, got %v", tt.expectedHandlerRecipients, mock.lastTo)
}
}
}
})
}
}

View File

@@ -0,0 +1,196 @@
// Package snakeoil provides functionality to generate a temporary self-signed certificates
// for testing purposes. It generates a public and private key pair, stores them in the
// OS's temporary directory, returning the paths to these files.
package snakeoil
import (
"crypto/rand"
"crypto/rsa"
"crypto/sha256"
"crypto/x509"
"crypto/x509/pkix"
"encoding/base64"
"encoding/pem"
"errors"
"math/big"
"os"
"strings"
"time"
"github.com/axllent/mailpit/internal/logger"
"github.com/axllent/mailpit/internal/tools"
)
var keys = make(map[string]KeyPair)
// KeyPair holds the public and private key paths for a self-signed certificate.
type KeyPair struct {
Public string
Private string
}
// Certificates returns all configured self-signed certificates in use,
// used for file deletion on exit.
func Certificates() map[string]KeyPair {
return keys
}
// Public returns the path to a generated PEM-encoded RSA public key.
func Public(str string) string {
domains, key, err := parse(str)
if err != nil {
logger.Log().Errorf("[tls] failed to parse domains: %v", err)
return ""
}
if pair, ok := keys[key]; ok {
return pair.Public
}
private, public, err := generate(domains)
if err != nil {
logger.Log().Errorf("[tls] failed to generate public certificate: %v", err)
return ""
}
keys[key] = KeyPair{
Public: public,
Private: private,
}
return public
}
// Private returns the path to a generated PEM-encoded RSA private key.
func Private(str string) string {
domains, key, err := parse(str)
if err != nil {
logger.Log().Errorf("[tls] failed to parse domains: %v", err)
return ""
}
if pair, ok := keys[key]; ok {
return pair.Private
}
private, public, err := generate(domains)
if err != nil {
logger.Log().Errorf("[tls] failed to generate public certificate: %v", err)
return ""
}
keys[key] = KeyPair{
Public: public,
Private: private,
}
return private
}
// Parse takes the original string input, removes the "sans:" prefix,
// splits the result into individual domains, and returns a slice of unique domains,
// along with a unique key that is a comma-separated list of these domains.
func parse(str string) ([]string, string, error) {
// remove "sans:" prefix
str = str[5:]
var domains []string
// split the string by commas and trim whitespace
for domain := range strings.SplitSeq(str, ",") {
domain = strings.ToLower(strings.TrimSpace(domain))
if domain != "" && !tools.InArray(domain, domains) {
domains = append(domains, domain)
}
}
if len(domains) == 0 {
return domains, "", errors.New("no valid domains provided")
}
// generate sha256 hash of the domains to create a unique key
hasher := sha256.New()
hasher.Write([]byte(strings.Join(domains, ",")))
key := base64.URLEncoding.EncodeToString(hasher.Sum(nil))
return domains, key, nil
}
// Generate a new self-signed certificate and return a public & private key paths.
func generate(domains []string) (string, string, error) {
logger.Log().Infof("[tls] generating temp self-signed certificate for: %s", strings.Join(domains, ","))
key, err := rsa.GenerateKey(rand.Reader, 4096)
if err != nil {
return "", "", err
}
keyBytes := x509.MarshalPKCS1PrivateKey(key)
// PEM encoding of private key
keyPEM := pem.EncodeToMemory(
&pem.Block{
Type: "RSA PRIVATE KEY",
Bytes: keyBytes,
},
)
notBefore := time.Now()
notAfter := notBefore.Add(365 * 24 * time.Hour)
// create certificate template
template := x509.Certificate{
SerialNumber: big.NewInt(0),
Subject: pkix.Name{
CommonName: domains[0],
Organization: []string{"Mailpit self-signed certificate"},
},
DNSNames: domains,
SignatureAlgorithm: x509.SHA256WithRSA,
NotBefore: notBefore,
NotAfter: notAfter,
BasicConstraintsValid: true,
KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageKeyAgreement | x509.KeyUsageKeyEncipherment | x509.KeyUsageDataEncipherment,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth},
}
// create certificate using template
derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &key.PublicKey, key)
if err != nil {
return "", "", err
}
// PEM encoding of certificate
certPem := pem.EncodeToMemory(
&pem.Block{
Type: "CERTIFICATE",
Bytes: derBytes,
},
)
// Store the paths to the generated keys
priv, err := os.CreateTemp("", ".mailpit-*-private.pem")
if err != nil {
return "", "", err
}
if _, err := priv.Write(keyPEM); err != nil {
return "", "", err
}
if err := priv.Close(); err != nil {
return "", "", err
}
pub, err := os.CreateTemp("", ".mailpit-*-public.pem")
if err != nil {
return "", "", err
}
if _, err := pub.Write(certPem); err != nil {
return "", "", err
}
if err := pub.Close(); err != nil {
return "", "", err
}
return priv.Name(), pub.Name(), nil
}

View File

@@ -9,6 +9,7 @@ import (
"github.com/axllent/mailpit/config"
"github.com/axllent/mailpit/internal/logger"
"github.com/axllent/mailpit/internal/storage"
"github.com/axllent/mailpit/internal/tools"
)
// Stores cached version along with its expiry time and error count.
@@ -81,7 +82,7 @@ func getBackoff(errCount int) time.Duration {
}
// Load the current statistics
func Load() AppInformation {
func Load(detectLatestVersion bool) AppInformation {
info := AppInformation{}
info.Version = config.Version
@@ -98,7 +99,7 @@ func Load() AppInformation {
if config.DisableVersionCheck {
info.LatestVersion = "disabled"
} else {
} else if detectLatestVersion {
mu.RLock()
cacheValid := time.Now().Before(vCache.expiry)
cacheValue := vCache.value
@@ -146,7 +147,7 @@ func Track() {
func LogSMTPAccepted(size int) {
mu.Lock()
smtpAccepted = smtpAccepted + 1
smtpAcceptedSize = smtpAcceptedSize + uint64(size)
smtpAcceptedSize = smtpAcceptedSize + tools.SafeUint64(size)
mu.Unlock()
}

View File

@@ -60,20 +60,19 @@ func pruneMessages() {
var size float64 // use float64 for rqlite compatibility
// prune using `--max` if set
if config.MaxMessages > 0 {
total := CountTotal()
if total > uint64(config.MaxAgeInHours) {
offset := config.MaxMessages
if config.DemoMode {
offset = 500
}
q := sqlf.Select("ID, Size").
From(tenant("mailbox")).
OrderBy("Created DESC").
Limit(5000).
Offset(offset)
if config.MaxMessages > 0 && CountTotal() > uint64(config.MaxMessages) {
offset := config.MaxMessages
if config.DemoMode {
offset = 500
}
q := sqlf.Select("ID, Size").
From(tenant("mailbox")).
OrderBy("Created DESC").
Limit(5000).
Offset(offset)
if err := q.QueryAndClose(context.TODO(), db, func(row *sql.Rows) {
if err := q.QueryAndClose(
context.TODO(), db, func(row *sql.Rows) {
var id string
if err := row.Scan(&id, &size); err != nil {
@@ -83,10 +82,10 @@ func pruneMessages() {
ids = append(ids, id)
prunedSize = prunedSize + uint64(size)
}); err != nil {
logger.Log().Errorf("[db] %s", err.Error())
return
}
},
); err != nil {
logger.Log().Errorf("[db] %s", err.Error())
return
}
}

View File

@@ -108,7 +108,7 @@ func Store(body *[]byte, username *string) (string, error) {
if config.Compression > 0 {
// insert compressed raw message
compressed := dbEncoder.EncodeAll(*body, make([]byte, 0, int(size)))
compressed := dbEncoder.EncodeAll(*body, make([]byte, 0, size))
if sqlDriver == "rqlite" {
// rqlite does not support binary data in query, so we need to encode the compressed message into hexadecimal
@@ -202,7 +202,7 @@ func Store(body *[]byte, username *string) (string, error) {
BroadcastMailboxStats()
logger.Log().Debugf("[db] saved message %s (%d bytes)", id, int64(size))
logger.Log().Debugf("[db] saved message %s (%d bytes)", id, size)
return id, nil
}

View File

@@ -1,6 +1,7 @@
package storage
import (
"os"
"testing"
"time"
@@ -204,3 +205,94 @@ func BenchmarkImportMime(b *testing.B) {
}
}
func TestInlineImageContentIdHandling(t *testing.T) {
setup("")
defer Close()
t.Log("Testing inline content handling")
// Test case: Proper inline image with Content-Disposition: inline
inlineAttachment, err := os.ReadFile("testdata/inline-attachment.eml")
if err != nil {
t.Fatalf("Failed to read test email: %v", err)
}
storedMessage, err := Store(&inlineAttachment, nil)
if err != nil {
t.Fatal("Failed to store test case 1:", err)
}
msg, err := GetMessage(storedMessage)
if err != nil {
t.Fatal("Failed to retrieve test case 1:", err)
}
// Assert
if len(msg.Inline) != 1 {
t.Errorf("Test case 1: Expected 1 inline attachment, got %d", len(msg.Inline))
}
if len(msg.Attachments) != 0 {
t.Errorf("Test case 1: Expected 0 regular attachments, got %d", len(msg.Attachments))
}
if msg.Inline[0].ContentID != "test1@example.com" {
t.Errorf("Test case 1: Expected ContentID 'test1@example.com', got '%s'", msg.Inline[0].ContentID)
}
}
func TestRegularAttachmentHandling(t *testing.T) {
setup("")
defer Close()
t.Log("Testing regular attachment handling")
// Test case: Regular attachment without Content-ID
regularAttachment, err := os.ReadFile("testdata/regular-attachment.eml")
if err != nil {
t.Fatalf("Failed to read test email: %v", err)
}
storedMessage, err := Store(&regularAttachment, nil)
if err != nil {
t.Fatal("Failed to store test case 3:", err)
}
msg, err := GetMessage(storedMessage)
if err != nil {
t.Fatal("Failed to retrieve test case 3:", err)
}
// Assert
if len(msg.Inline) != 0 {
t.Errorf("Test case 3: Expected 0 inline attachments, got %d", len(msg.Inline))
}
if len(msg.Attachments) != 1 {
t.Errorf("Test case 3: Expected 1 regular attachment, got %d", len(msg.Attachments))
}
if msg.Attachments[0].ContentID != "" {
t.Errorf("Test case 3: Expected empty ContentID, got '%s'", msg.Attachments[0].ContentID)
}
}
func TestMixedAttachmentHandling(t *testing.T) {
setup("")
defer Close()
t.Log("Testing mixed attachment handling")
// Mixed scenario with both inline and regular attachment
mixedAttachment, err := os.ReadFile("testdata/mixed-attachment.eml")
if err != nil {
t.Fatalf("Failed to read test email: %v", err)
}
storedMessage, err := Store(&mixedAttachment, nil)
if err != nil {
t.Fatal("Failed to store test case 4:", err)
}
msg, err := GetMessage(storedMessage)
if err != nil {
t.Fatal("Failed to retrieve test case 4:", err)
}
// Assert: Should have 1 inline (with ContentID) and 1 attachment (without ContentID)
if len(msg.Inline) != 1 {
t.Errorf("Test case 4: Expected 1 inline attachment, got %d", len(msg.Inline))
}
if len(msg.Attachments) != 1 {
t.Errorf("Test case 4: Expected 1 regular attachment, got %d", len(msg.Attachments))
}
if msg.Inline[0].ContentID != "inline@example.com" {
t.Errorf("Test case 4: Expected inline ContentID 'inline@example.com', got '%s'", msg.Inline[0].ContentID)
}
if msg.Attachments[0].ContentID != "" {
t.Errorf("Test case 4: Expected attachment ContentID to be empty, got '%s'", msg.Attachments[0].ContentID)
}
}

View File

@@ -0,0 +1,20 @@
From: sender@example.com
To: recipient@example.com
Subject: Test inline image proper
MIME-Version: 1.0
Content-Type: multipart/related; boundary="boundary123"
--boundary123
Content-Type: text/html; charset=utf-8
<html><body><img src="cid:test1@example.com" alt="Test"/></body></html>
--boundary123
Content-Type: image/png; name="test1.png"
Content-Disposition: inline; filename="test1.png"
Content-ID: <test1@example.com>
Content-Transfer-Encoding: base64
iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8/5+hHgAHggJ/PchI7wAAAABJRU5ErkJggg==
--boundary123--

View File

@@ -0,0 +1,27 @@
From: sender@example.com
To: recipient@example.com
Subject: Test mixed attachments
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="boundary111"
--boundary111
Content-Type: text/html; charset=utf-8
<html><body><img src="cid:inline@example.com" alt="Inline"/><p>Document attached</p></body></html>
--boundary111
Content-Type: image/png; name="inline.png"
Content-Disposition: inline; filename="inline.png"
Content-ID: <inline@example.com>
Content-Transfer-Encoding: base64
iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8/5+hHgAHggJ/PchI7wAAAABJRU5ErkJggg==
--boundary111
Content-Type: application/pdf; name="document.pdf"
Content-Disposition: attachment; filename="document.pdf"
Content-Transfer-Encoding: base64
JVBERi0xLjQKJcOkw7zDtsOfCjIgMCBvYmoKPDwvTGVuZ3RoIDMgMCBSL0ZpbHRlci9GbGF0ZURlY29kZT4+CnN0cmVhbQo=
--boundary111--

View File

@@ -0,0 +1,19 @@
From: sender@example.com
To: recipient@example.com
Subject: Test regular attachment
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="boundary789"
--boundary789
Content-Type: text/html; charset=utf-8
<html><body><p>Message with regular attachment</p></body></html>
--boundary789
Content-Type: application/pdf; name="document.pdf"
Content-Disposition: attachment; filename="document.pdf"
Content-Transfer-Encoding: base64
JVBERi0xLjQKJcOkw7zDtsOfCjIgMCBvYmoKPDwvTGVuZ3RoIDMgMCBSL0ZpbHRlci9GbGF0ZURlY29kZT4+CnN0cmVhbQo=
--boundary789--

View File

@@ -9,6 +9,7 @@ import (
"github.com/axllent/mailpit/internal/html2text"
"github.com/axllent/mailpit/internal/logger"
"github.com/axllent/mailpit/internal/tools"
"github.com/jhillyerd/enmime/v2"
)
@@ -88,7 +89,7 @@ func cleanString(str string) string {
// LogMessagesDeleted logs the number of messages deleted
func logMessagesDeleted(n int) {
mu.Lock()
StatsDeleted = StatsDeleted + uint64(n)
StatsDeleted = StatsDeleted + tools.SafeUint64(n)
mu.Unlock()
}

View File

@@ -10,7 +10,7 @@ import (
var (
// Invalid tag characters regex
tagsInvalidChars = regexp.MustCompile(`[^a-zA-Z0-9\-\ \_\.]`)
tagsInvalidChars = regexp.MustCompile(`[^a-zA-Z0-9\-\ \_\.@]`)
// Regex to catch multiple spaces
multiSpaceRe = regexp.MustCompile(`(\s+)`)
@@ -19,14 +19,21 @@ var (
TagsTitleCase bool
)
// CleanTag returns a clean tag, trimming whitespace and replacing invalid characters
// CleanTag returns a clean tag, trimming whitespace and replacing invalid characters.
// If the tag is longer than 100 characters, it is truncated.
func CleanTag(s string) string {
return strings.TrimSpace(
t := strings.TrimSpace(
multiSpaceRe.ReplaceAllString(
tagsInvalidChars.ReplaceAllString(s, " "),
" ",
),
)
if len(t) > 100 {
return t[:100]
}
return t
}
// SetTagCasing returns the slice of tags, title-casing if set

View File

@@ -33,7 +33,8 @@ func TestCleanTag(t *testing.T) {
tests["thiS IS a Test :-)"] = "thiS IS a Test -"
tests[" thiS 99 IS a Test :-)"] = "thiS 99 IS a Test -"
tests["this_is-a test "] = "this_is-a test"
tests["this_is-a&^%%(*)@ test"] = "this_is-a test"
tests["this_is-a&^%%(*)@ test"] = "this_is-a @ test"
tests["this is a long tag title with more than 100 characters, which should get automatically truncated to 100 characters"] = "this is a long tag title with more than 100 characters which should get automatically truncated to 1"
for search, expected := range tests {
res := CleanTag(search)

View File

@@ -36,3 +36,22 @@ func Normalize(s string) string {
return strings.TrimSpace(s)
}
// SafeUint64 converts an int or int64 to uint64, ensuring it does not exceed the maximum value for uint64.
func SafeUint64(i any) uint64 {
switch v := i.(type) {
case int:
if v < 0 {
return 0
}
return uint64(v)
case int64:
if v < 0 {
return 0
}
return uint64(v)
default:
// only accepts int or int64
return 0
}
}

4686
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -12,7 +12,7 @@
"lint-fix": "eslint --fix && prettier --write ."
},
"dependencies": {
"axios": "^1.2.1",
"axios": "^1.11.0",
"bootstrap": "^5.2.0",
"bootstrap-icons": "^1.9.1",
"bootstrap5-tags": "^1.6.1",
@@ -30,20 +30,20 @@
"vue-router": "^4.2.4"
},
"devDependencies": {
"@eslint/compat": "^1.3.1",
"@popperjs/core": "^2.11.5",
"@types/bootstrap": "^5.2.7",
"@types/tinycon": "^0.6.3",
"@vue/compiler-sfc": "^3.2.37",
"esbuild": "^0.25.0",
"esbuild": "^0.27.2",
"esbuild-plugin-vue-next": "^0.1.4",
"esbuild-sass-plugin": "^3.0.0",
"eslint": "^9.29.0",
"eslint-config-prettier": "^10.1.5",
"eslint-plugin-vue": "^10.2.0",
"neostandard": "^0.12.1",
"prettier": "^3.5.3"
},
"prettier":{
"prettier": {
"tabWidth": 4,
"useTabs": true,
"printWidth": 120

View File

@@ -2,11 +2,14 @@
package cmd
import (
"crypto/tls"
"errors"
"fmt"
"net"
"net/mail"
"net/smtp"
"os"
"strings"
"github.com/axllent/mailpit/internal/logger"
)
@@ -27,7 +30,7 @@ func Send(addr string, from string, to []string, msg []byte) error {
}
if !isSocket {
return smtp.SendMail(addr, nil, fromAddress.Address, to, msg)
return sendMail(addr, nil, fromAddress.Address, to, msg)
}
conn, err := net.Dial("unix", socketPath)
@@ -69,3 +72,76 @@ func Send(addr string, from string, to []string, msg []byte) error {
return nil
}
func sendMail(addr string, a smtp.Auth, from string, to []string, msg []byte) error {
if err := validateLine(from); err != nil {
return err
}
for _, recipient := range to {
if err := validateLine(recipient); err != nil {
return err
}
}
c, err := smtp.Dial(addr)
if err != nil {
return err
}
defer func() { _ = c.Close() }()
if err = c.Hello(addr); err != nil {
return err
}
if ok, _ := c.Extension("STARTTLS"); ok {
config := &tls.Config{ServerName: addr, InsecureSkipVerify: true} // #nosec
if err = c.StartTLS(config); err != nil {
return err
}
}
if a != nil {
if ok, _ := c.Extension("AUTH"); !ok {
return errors.New("smtp: server doesn't support AUTH")
}
if err = c.Auth(a); err != nil {
return err
}
}
if err = c.Mail(from); err != nil {
return err
}
for _, addr := range to {
if err = c.Rcpt(addr); err != nil {
return err
}
}
w, err := c.Data()
if err != nil {
return err
}
_, err = w.Write(msg)
if err != nil {
return err
}
err = w.Close()
if err != nil {
return err
}
return c.Quit()
}
// validateLine checks to see if a line has CR or LF as per RFC 5321.
func validateLine(line string) error {
if strings.ContainsAny(line, "\n\r") {
return errors.New("smtp: A line must not contain CR or LF")
}
return nil
}

View File

@@ -28,7 +28,7 @@ func AppInfo(w http.ResponseWriter, _ *http.Request) {
// 400: ErrorResponse
w.Header().Add("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(stats.Load()); err != nil {
if err := json.NewEncoder(w).Encode(stats.Load(true)); err != nil {
httpError(w, err.Error())
}
}

View File

@@ -6,6 +6,7 @@ import (
"strings"
"github.com/axllent/mailpit/internal/storage"
"github.com/axllent/mailpit/internal/tools"
)
// MessagesSummary is a summary of a list of messages
@@ -241,9 +242,9 @@ func Search(w http.ResponseWriter, r *http.Request) {
res.Start = start
res.Messages = messages
res.Count = uint64(len(messages)) // legacy - now undocumented in API specs
res.Total = stats.Total // total messages in mailbox
res.MessagesCount = uint64(results)
res.Count = tools.SafeUint64(len(messages)) // legacy - now undocumented in API specs
res.Total = stats.Total // total messages in mailbox
res.MessagesCount = tools.SafeUint64(results)
res.Unread = stats.Unread
res.Tags = stats.Tags
@@ -253,7 +254,7 @@ func Search(w http.ResponseWriter, r *http.Request) {
return
}
res.MessagesUnreadCount = uint64(unread)
res.MessagesUnreadCount = tools.SafeUint64(unread)
w.Header().Add("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(res); err != nil {

View File

@@ -76,13 +76,14 @@ func Thumbnail(w http.ResponseWriter, r *http.Request) {
var b bytes.Buffer
foo := bufio.NewWriter(&b)
var dstImageFill *image.NRGBA
var temp image.Image
if img.Bounds().Dx() < thumbWidth || img.Bounds().Dy() < thumbHeight {
dstImageFill = imaging.Fit(img, thumbWidth, thumbHeight, imaging.Lanczos)
temp = imaging.Fit(img, thumbWidth, thumbHeight, imaging.Lanczos)
} else {
dstImageFill = imaging.Fill(img, thumbWidth, thumbHeight, imaging.Center, imaging.Lanczos)
temp = imaging.Fill(img, thumbWidth, thumbHeight, imaging.Center, imaging.Lanczos)
}
dstImageFill := imaging.Clone(temp)
// create white image and paste image over the top
// preventing black backgrounds for transparent GIF/PNG images
dst := imaging.New(thumbWidth, thumbHeight, color.White)

View File

@@ -3,32 +3,102 @@ package handlers
import (
"crypto/tls"
"encoding/base64"
"fmt"
"io"
"net/http"
"net/url"
"regexp"
"strings"
"sync"
"time"
"github.com/PuerkitoBio/goquery"
"github.com/axllent/mailpit/config"
"github.com/axllent/mailpit/internal/logger"
"github.com/axllent/mailpit/internal/storage"
"github.com/axllent/mailpit/internal/tools"
)
var linkRe = regexp.MustCompile(`(?i)^https?:\/\/`)
var (
linkRe = regexp.MustCompile(`(?i)^https?:\/\/`)
// ProxyHandler is used to proxy assets for printing
urlRe = regexp.MustCompile(`(?mU)url\(('|")?(https?:\/\/[^)'"]+)('|")?\)`)
assetsMutex sync.Mutex
assets = map[string]MessageAssets{}
)
// MessageAssets represents assets linked in a message
type MessageAssets struct {
ID string
// Created timestamp so we can expire old entries
Created time.Time
// Assets found in the message
Assets []string
}
func init() {
// Start a goroutine to clean up old asset entries every minute
go func() {
for {
time.Sleep(time.Minute)
assetsMutex.Lock()
now := time.Now()
for id, entry := range assets {
if now.Sub(entry.Created) > time.Minute {
logger.Log().Debugf("[proxy] cleaning up assets for message %s", id)
delete(assets, id)
}
}
assetsMutex.Unlock()
}
}()
}
// ProxyHandler is used to proxy assets for printing.
// It accepts a base64-encoded message-id:url string as the `data` query parameter.
func ProxyHandler(w http.ResponseWriter, r *http.Request) {
uri := strings.TrimSpace(r.URL.Query().Get("url"))
if uri == "" {
logger.Log().Warn("[proxy] URL missing")
httpError(w, "Error: URL missing")
encoded := strings.TrimSpace(r.URL.Query().Get("data"))
if encoded == "" {
logger.Log().Warn("[proxy] Data missing")
httpError(w, "Error: Data missing")
return
}
decoded, err := base64.StdEncoding.DecodeString(encoded)
if err != nil {
logger.Log().Warnf("[proxy] Data parameter corrupted: %s", err.Error())
httpError(w, "Error: invalid request")
return
}
parts := strings.SplitN(string(decoded), ":", 2)
if len(parts) != 2 {
logger.Log().Warnf("[proxy] Invalid data parameter: %s", string(decoded))
httpError(w, "Error: invalid request")
return
}
id := parts[0]
uri := parts[1]
links, err := getAssets(id)
if err != nil {
httpError(w, "Error: invalid request")
return
}
if !tools.InArray(uri, links) {
logger.Log().Warnf("[proxy] URL %s not found in message %s", uri, id)
httpError(w, "Error: invalid request")
return
}
if !linkRe.MatchString(uri) {
logger.Log().Warnf("[proxy] invalid URL %s", uri)
httpError(w, "Error: invalid URL")
logger.Log().Warnf("[proxy] invalid request %s", uri)
httpError(w, "Error: invalid request")
return
}
@@ -46,7 +116,7 @@ func ProxyHandler(w http.ResponseWriter, r *http.Request) {
req, err := http.NewRequest("GET", uri, nil)
if err != nil {
logger.Log().Warnf("[proxy] %s", err.Error())
httpError(w, err.Error())
httpError(w, "Error: invalid request")
return
}
@@ -56,23 +126,34 @@ func ProxyHandler(w http.ResponseWriter, r *http.Request) {
resp, err := client.Do(req)
if err != nil {
logger.Log().Warnf("[proxy] %s", err.Error())
httpError(w, err.Error())
httpError(w, "Error: invalid request")
return
}
defer func() { _ = resp.Body.Close() }()
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
logger.Log().Warnf("[proxy] received status code %d for %s", resp.StatusCode, uri)
httpError(w, "Error: invalid request")
return
}
ct := strings.ToLower(resp.Header.Get("content-type"))
if !supportedProxyContentType(ct) {
logger.Log().Warnf("[proxy] blocking unsupported content-type %s for %s", ct, uri)
httpError(w, "Error: invalid request")
return
}
body, err := io.ReadAll(resp.Body)
if err != nil {
logger.Log().Warnf("[proxy] %s", err.Error())
httpError(w, err.Error())
httpError(w, "Error: invalid request")
return
}
// relay common headers
if resp.Header.Get("content-type") != "" {
w.Header().Set("content-type", resp.Header.Get("content-type"))
}
w.Header().Set("content-type", ct)
if resp.Header.Get("last-modified") != "" {
w.Header().Set("last-modified", resp.Header.Get("last-modified"))
}
@@ -83,7 +164,7 @@ func ProxyHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("cache-control", resp.Header.Get("cache-control"))
}
// replace url() values with proxy address, eg: fonts & images
// replace CSS url() values with proxy address, eg: fonts & images
if strings.HasPrefix(resp.Header.Get("content-type"), "text/css") {
var re = regexp.MustCompile(`(?mi)(url\((\'|\")?([^\)\'\"]+)(\'|\")?\))`)
body = re.ReplaceAllFunc(body, func(s []byte) []byte {
@@ -100,7 +181,20 @@ func ProxyHandler(w http.ResponseWriter, r *http.Request) {
return []byte(parts[3])
}
return []byte("url(" + parts[2] + config.Webroot + "proxy?url=" + url.QueryEscape(address) + parts[4] + ")")
// store asset address against message ID
if result, ok := assets[id]; ok {
if !tools.InArray(address, result.Assets) {
assetsMutex.Lock()
result.Assets = append(result.Assets, address)
assets[id] = result
assetsMutex.Unlock()
}
}
// encode with base64 to handle any special characters and group message ID with URL
encoded := base64.StdEncoding.EncodeToString([]byte(id + ":" + address))
return []byte("url(" + parts[2] + config.Webroot + "proxy?data=" + encoded + parts[4] + ")")
})
}
@@ -114,7 +208,82 @@ func ProxyHandler(w http.ResponseWriter, r *http.Request) {
}
}
// AbsoluteURL will return a full URL regardless whether it is relative or absolute
// GetAssets retrieves and parses the message to return linked assets.
// Linked CSS files are appended to the assets list via the ProxyHandler when proxying CSS files.
func getAssets(id string) ([]string, error) {
assetsMutex.Lock()
defer assetsMutex.Unlock()
result, ok := assets[id]
if ok {
// return cached assets
return result.Assets, nil
}
msg, err := storage.GetMessage(id)
if err != nil {
return nil, err
}
links := []string{}
reader := strings.NewReader(msg.HTML)
// load the HTML document
doc, err := goquery.NewDocumentFromReader(reader)
if err != nil {
return nil, err
}
// css & font links
doc.Find("link").Each(func(_ int, s *goquery.Selection) {
if href, exists := s.Attr("href"); exists {
if linkRe.MatchString(href) && !tools.InArray(href, links) {
links = append(links, href)
}
}
})
// images
doc.Find("img").Each(func(_ int, s *goquery.Selection) {
if src, exists := s.Attr("src"); exists {
if linkRe.MatchString(src) && !tools.InArray(src, links) {
links = append(links, src)
}
}
})
// background="<>" links
doc.Find("[background]").Each(func(_ int, s *goquery.Selection) {
if bg, exists := s.Attr("background"); exists {
if linkRe.MatchString(bg) && !tools.InArray(bg, links) {
links = append(links, bg)
}
}
})
// url(<>) links in style blocks
matches := urlRe.FindAllStringSubmatch(msg.HTML, -1)
for _, match := range matches {
if len(match) >= 3 {
link := match[2]
if linkRe.MatchString(link) && !tools.InArray(link, links) {
links = append(links, link)
}
}
}
r := MessageAssets{}
r.ID = id
r.Created = time.Now()
r.Assets = links
assets[id] = r
return links, nil
}
// AbsoluteURL will return a full URL regardless whether it is relative or absolute.
// This is used to replace relative CSS url(...) links when proxying.
func absoluteURL(link, baseURL string) (string, error) {
// scheme relative links, eg <script src="//example.com/script.js">
if len(link) > 1 && link[0:2] == "//" {
@@ -156,3 +325,35 @@ func httpError(w http.ResponseWriter, msg string) {
w.Header().Set("Content-Type", "text/plain")
_, _ = fmt.Fprint(w, msg)
}
// SupportedProxyContentType checks if the content-type is supported for proxying.
// This is limited to fonts, images and css only.
func supportedProxyContentType(ct string) bool {
ct = strings.ToLower(ct)
types := []string{
"font/otf",
"font/ttf",
"font/woff",
"font/woff2",
"image/apng",
"image/avif",
"image/bmp",
"image/gif",
"image/jpeg",
"image/jpg",
"image/png",
"image/tiff",
"image/svg+xml",
"image/webp",
"text/css",
}
for _, t := range types {
if strings.HasPrefix(ct, t) {
return true
}
}
return false
}

View File

@@ -20,6 +20,7 @@ import (
"github.com/axllent/mailpit/internal/logger"
"github.com/axllent/mailpit/internal/pop3"
"github.com/axllent/mailpit/internal/prometheus"
"github.com/axllent/mailpit/internal/snakeoil"
"github.com/axllent/mailpit/internal/stats"
"github.com/axllent/mailpit/internal/storage"
"github.com/axllent/mailpit/internal/tools"
@@ -85,9 +86,6 @@ func Listen() {
r.Path(config.Webroot + "search").Handler(middleWareFunc(index)).Methods("GET")
r.Path(config.Webroot).Handler(middleWareFunc(index)).Methods("GET")
// put it all together
http.Handle("/", r)
if auth.UICredentials != nil {
logger.Log().Info("[http] enabling basic authentication")
}
@@ -99,6 +97,13 @@ func Listen() {
Addr: config.HTTPListen,
ReadTimeout: 30 * time.Second,
WriteTimeout: 30 * time.Second,
Handler: r,
}
// add temporary self-signed certificates to get deleted afterwards
for _, keyPair := range snakeoil.Certificates() {
storage.AddTempFile(keyPair.Public)
storage.AddTempFile(keyPair.Private)
}
if config.UITLSCert != "" && config.UITLSKey != "" {

View File

@@ -17,7 +17,7 @@ export default {
mixins: [CommonMixins],
watch: {
$route(to, from) {
$route() {
// hide mobile menu on URL change
this.hideNav();
},

View File

@@ -21,3 +21,4 @@ $enable-negative-margins: true;
$body-color-dark: #e7eaed;
$offcanvas-border-width: 0;
$body-color: #080808;
$btn-disabled-opacity: 0.4;

View File

@@ -314,6 +314,11 @@ body.blur {
display: none;
}
// dropdown doesn't always appear in correct position inside modals
.dropdown.form-select {
position: relative !important;
}
.message {
&.read {
> div {

View File

@@ -53,5 +53,10 @@ export default {
navigator.setAppBadge(this.mailboxUnread);
},
},
render() {
// to remove webkit warnings about missing template or render function
return false;
},
};
</script>

View File

@@ -112,5 +112,10 @@ export default {
this.favicon.href = canvas.toDataURL("image/png");
},
},
render() {
// to remove webkit warnings about missing template or render function
return false;
},
};
</script>

View File

@@ -52,7 +52,7 @@ export default {
let response;
try {
response = JSON.parse(e.data);
} catch (e) {
} catch {
return;
}
@@ -128,7 +128,7 @@ export default {
}
};
ws.onclose = (e) => {
ws.onclose = () => {
if (this.socketLastConnection === 0) {
// connection failed immediately after connecting to Mailpit implies proxy websockets aren't configured
console.log("Unable to connect to websocket, disabling websocket support");

View File

@@ -14,6 +14,9 @@ export default {
timezones,
chaosConfig: false,
chaosUpdated: false,
defaultReleaseAddressesOptions: localStorage.getItem("defaultReleaseAddresses")
? JSON.parse(localStorage.getItem("defaultReleaseAddresses"))
: [], // set with default release addresses
};
},
@@ -45,11 +48,13 @@ export default {
mounted() {
this.setTheme();
this.$nextTick(() => {
Tags.init("select.tz");
});
mailbox.skipConfirmations = !!localStorage.getItem("skip-confirmations");
mailbox.skipConfirmations = localStorage.getItem("skip-confirmations");
window.setTimeout(() => {
Tags.init("select.tz");
Tags.init("select.default-release-addresses");
}, 500);
},
methods: {
@@ -98,7 +103,7 @@ export default {
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<ul v-if="mailbox.uiConfig.ChaosEnabled" id="myTab" class="nav nav-tabs" role="tablist">
<ul id="myTab" class="nav nav-tabs" role="tablist">
<li class="nav-item" role="presentation">
<button
id="ui-tab"
@@ -113,7 +118,25 @@ export default {
Web UI
</button>
</li>
<li class="nav-item" role="presentation">
<li
v-if="mailbox.uiConfig.MessageRelay && mailbox.uiConfig.MessageRelay.Enabled"
class="nav-item"
role="presentation"
>
<button
id="relay-tab"
class="nav-link"
data-bs-toggle="tab"
data-bs-target="#relay-tab-pane"
type="button"
role="tab"
aria-controls="relay-tab-pane"
aria-selected="false"
>
Message release
</button>
</li>
<li v-if="mailbox.uiConfig.ChaosEnabled" class="nav-item" role="presentation">
<button
id="chaos-tab"
class="nav-link"
@@ -234,6 +257,50 @@ export default {
</div>
</div>
<!-- Default relay addresses -->
<div
v-if="mailbox.uiConfig.MessageRelay && mailbox.uiConfig.MessageRelay.Enabled"
id="relay-tab-pane"
class="tab-pane fade"
role="tabpanel"
aria-labelledby="relay-tab"
tabindex="0"
>
<div class="my-3 mb-5">
<label class="form-label">Default release address(es)</label>
<div class="form-text mb-2">
You can designate the default "send to" addresses here, which will automatically
populate the field in the message release dialog. This setting applies only to your
browser. If this field is left empty, it will revert to the original recipients of
the message.
</div>
<select
v-model="mailbox.defaultReleaseAddresses"
class="form-select tag-selector default-release-addresses"
multiple
data-allow-new="true"
data-clear-end="true"
data-allow-clear="true"
data-placeholder="Enter email addresses..."
data-add-on-blur="true"
data-badge-style="primary"
data-regex='^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|.(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$'
data-separator="|,|"
>
<option value="">Enter email addresses...</option>
<!-- you need at least one option with the placeholder -->
<option
v-for="t in defaultReleaseAddressesOptions"
:key="'address+' + t"
:value="t"
>
{{ t }}
</option>
</select>
<div class="invalid-feedback">Invalid email address</div>
</div>
</div>
<div
v-if="mailbox.uiConfig.ChaosEnabled"
id="chaos-tab-pane"

View File

@@ -9,7 +9,7 @@ export default {
return {
mailbox,
editableTags: [],
validTagRe: /^([a-zA-Z0-9\- ._]){1,}$/,
validTagRe: /^([a-zA-Z0-9\- ._@]){1,100}$/,
tagToDelete: false,
};
},
@@ -28,7 +28,7 @@ export default {
methods: {
validTag(t) {
if (!t.after.match(/^([a-zA-Z0-9\- _.]){1,}$/)) {
if (!t.after.match(/^([a-zA-Z0-9\- ._@]){1,100}$/)) {
return false;
}

View File

@@ -47,14 +47,14 @@ export default {
},
markAllRead() {
this.put(this.resolve(`/api/v1/messages`), { read: true }, (response) => {
this.put(this.resolve(`/api/v1/messages`), { read: true }, () => {
window.scrollInPlace = true;
this.loadMessages();
});
},
deleteAllMessages() {
this.delete(this.resolve(`/api/v1/messages`), false, (response) => {
this.delete(this.resolve(`/api/v1/messages`), false, () => {
pagination.start = 0;
this.loadMessages();
});

View File

@@ -85,8 +85,9 @@ export default {
<template>
<select
v-model="pagination.limit"
class="form-select form-select-sm d-inline w-auto me-2"
class="form-select form-select-sm d-inline w-auto me-2 me-xl-3"
:disabled="total == 0"
title="The number of messages displayed per page"
@change="changeLimit"
>
<option v-for="option in limitOptions" :key="option" :value="option">{{ option }}</option>
@@ -98,11 +99,11 @@ export default {
<small>of</small>
{{ formatNumber(total) }}
</template>
<span v-else class="text-muted">0 of 0</span>
<span v-else class="text-light">0 of 0</span>
</small>
<button
class="btn btn-outline-light ms-2 me-1"
class="btn btn-outline-light ms-2 ms-xl-3 me-1"
:disabled="!canPrev"
:title="'View previous ' + pagination.limit + ' messages'"
@click="viewPrev"

View File

@@ -28,7 +28,7 @@ export default {
if (!mailbox.selected.length) {
return false;
}
this.put(this.resolve(`/api/v1/messages`), { Read: true, IDs: mailbox.selected }, (response) => {
this.put(this.resolve(`/api/v1/messages`), { Read: true, IDs: mailbox.selected }, () => {
window.scrollInPlace = true;
this.loadMessages();
});
@@ -43,7 +43,7 @@ export default {
if (!mailbox.selected.length) {
return false;
}
this.put(this.resolve(`/api/v1/messages`), { Read: false, IDs: mailbox.selected }, (response) => {
this.put(this.resolve(`/api/v1/messages`), { Read: false, IDs: mailbox.selected }, () => {
window.scrollInPlace = true;
this.loadMessages();
});
@@ -57,7 +57,7 @@ export default {
return false;
}
this.delete(this.resolve(`/api/v1/messages`), { IDs: ids }, (response) => {
this.delete(this.resolve(`/api/v1/messages`), { IDs: ids }, () => {
window.scrollInPlace = true;
this.loadMessages();
});

View File

@@ -257,7 +257,10 @@ export default {
if (platforms) {
try {
this.platforms = JSON.parse(platforms);
} catch (e) {}
} catch {
// if parsing fails, reset to default
this.platforms = [];
}
}
// set all options

View File

@@ -153,7 +153,7 @@ export default {
this.error = error.message;
}
})
.then((result) => {
.then(() => {
// always run
this.loading = false;
});

View File

@@ -143,12 +143,12 @@ export default {
window.addEventListener("resize", this.resizeIFrames);
const headersTab = document.getElementById("nav-headers-tab");
headersTab.addEventListener("shown.bs.tab", (event) => {
headersTab.addEventListener("shown.bs.tab", () => {
this.loadHeaders = true;
});
const rawTab = document.getElementById("nav-raw-tab");
rawTab.addEventListener("shown.bs.tab", (event) => {
rawTab.addEventListener("shown.bs.tab", () => {
this.srcURI = this.resolve("/api/v1/message/" + this.message.ID + "/raw");
this.resizeIFrames();
});
@@ -180,7 +180,7 @@ export default {
this.isHTMLTabSelected();
document.querySelectorAll('button[data-bs-toggle="tab"]').forEach((listObj) => {
listObj.addEventListener("shown.bs.tab", (event) => {
listObj.addEventListener("shown.bs.tab", () => {
this.isHTMLTabSelected();
});
});
@@ -203,7 +203,9 @@ export default {
anchorEl.setAttribute("target", "_blank");
}
}
} catch (error) {}
} catch {
// ignore errors when accessing the iframe content
}
this.resizeIFrames();
}
}, 500);
@@ -280,7 +282,7 @@ export default {
Tags: this.messageTags,
};
this.put(this.resolve("/api/v1/tags"), data, (response) => {
this.put(this.resolve("/api/v1/tags"), data, () => {
window.scrollInPlace = true;
this.$emit("loadMessages");
});
@@ -290,15 +292,24 @@ export default {
textToHTML(s) {
let html = s;
// full links with http(s)
const re = /(\b(https?|ftp):\/\/[-\w@:%_+'!.~#?,&//=;]+)/gim;
html = html.replace(re, "˱˱˱a href=ˠˠˠ$&ˠˠˠ target=_blank rel=noopener˲˲˲$&˱˱˱/a˲˲˲");
// RFC2396 appendix E states angle brackets are recommended for text/plain emails to
// recognize potential spaces in between the URL
// @see https://www.rfc-editor.org/rfc/rfc2396#appendix-E
const angleLinks = /<((https?|ftp):\/\/[-\w@:%_+'!.~#?,&//=; ][^>]+)>/gim;
html = html.replace(angleLinks, "<˱˱˱a href=ˠˠˠ$1ˠˠˠ target=_blank rel=noopener˲˲˲$1˱˱˱/a˲˲˲>");
// find links without angle brackets, starting with http(s) or ftp
const regularLinks = /([^ˠ˲]\b)(((https?|ftp):\/\/[-\w@:%_+'!.~#?,&//=;]+))/gim;
html = html.replace(regularLinks, "$1˱˱˱a href=ˠˠˠ$2ˠˠˠ target=_blank rel=noopener˲˲˲$2˱˱˱/a˲˲˲");
// plain www links without https?:// prefix
const re2 = /(^|[^/])(www\.[\S]+(\b|$))/gim;
html = html.replace(re2, "$1˱˱˱a href=ˠˠˠhttp://$2ˠˠˠ target=ˠˠˠ_blankˠˠˠ rel=ˠˠˠnoopenerˠˠˠ˲˲˲$2˱˱˱/a˲˲˲");
const shortLinks = /(^|[^/])(www\.[\S]+(\b|$))/gim;
html = html.replace(
shortLinks,
"$1˱˱˱a href=ˠˠˠhttp://$2ˠˠˠ target=ˠˠˠ_blankˠˠˠ rel=ˠˠˠnoopenerˠˠˠ˲˲˲$2˱˱˱/a˲˲˲",
);
// escape to HTML & convert <>" back
// escape to HTML & convert <>" characters back
html = html
.replace(/&/g, "&amp;")
.replace(/</g, "&lt;")
@@ -456,7 +467,7 @@ export default {
data-allow-clear="true"
data-placeholder="Add tags..."
data-badge-style="secondary"
data-regex="^([a-zA-Z0-9\-\ \_\.]){1,}$"
data-regex="^([a-zA-Z0-9\-\ \_\.@]){1,100}$"
data-separator="|,|"
>
<option value="">Type a tag...</option>

View File

@@ -44,7 +44,20 @@ export default {
// include only unique email addresses, regardless of casing
this.allAddresses = JSON.parse(JSON.stringify([...new Map(a.map((ad) => [ad.toLowerCase(), ad])).values()]));
this.addresses = this.allAddresses;
// include default release addresses from mailbox settings
const defaultAddr = mailbox.defaultReleaseAddresses;
for (const i in defaultAddr) {
if (!this.allAddresses.includes(defaultAddr[i])) {
this.allAddresses.push(defaultAddr[i]);
}
}
if (defaultAddr.length === 0) {
// prefill with all addresses if no default is set
this.addresses = this.allAddresses;
} else {
this.addresses = defaultAddr;
}
},
methods: {
@@ -64,7 +77,7 @@ export default {
To: this.addresses,
};
this.post(this.resolve("/api/v1/message/" + this.message.ID + "/release"), data, (response) => {
this.post(this.resolve("/api/v1/message/" + this.message.ID + "/release"), data, () => {
this.modal("ReleaseModal").hide();
if (this.deleteAfterRelease) {
this.$emit("delete");
@@ -140,6 +153,13 @@ export default {
<option v-for="t in allAddresses" :key="'address+' + t" :value="t">{{ t }}</option>
</select>
<div class="invalid-feedback">Invalid email address</div>
<div class="form-text mt-1">
Default release addresses can be configured in
<a href="#" data-bs-toggle="modal" data-bs-target="#SettingsModal">
<i class="bi bi-gear-fill ms-1"></i>
Settings </a
>.
</div>
</div>
</div>
<div class="row mb-3">

View File

@@ -27,9 +27,13 @@ export default {
methods: {
initScreenshot() {
this.loading = 1;
const baseUrl = `${location.protocol}//${location.host}/`;
// absolute proxy URL
const proxy = new URL(this.resolve("/proxy"), baseUrl).href;
const urlRegex = /(url\(('|")?(https?:\/\/[^)'"]+)('|")?\))/gim;
// remove base tag, if set
let h = this.message.HTML.replace(/<base .*>/im, "");
const proxy = this.resolve("/proxy");
// Outlook hacks - else screenshot returns blank image
h = h.replace(/<html [^>]+>/gim, "<html>"); // remove html attributes
@@ -37,19 +41,10 @@ export default {
h = h.replace(/<o:/gm, "<"); // replace `<o:p>` tags with `<p>`
h = h.replace(/<\/o:/gm, "</"); // replace `</o:p>` tags with `</p>`
// update any inline `url(...)` absolute links
const urlRegex = /(url\(('|")?(https?:\/\/[^)'"]+)('|")?\))/gim;
h = h.replaceAll(urlRegex, (match, p1, p2, p3) => {
if (typeof p2 === "string") {
return `url(${p2}${proxy}?url=` + encodeURIComponent(this.decodeEntities(p3)) + `${p2})`;
}
return `url(${proxy}?url=` + encodeURIComponent(this.decodeEntities(p3)) + `)`;
});
// create temporary document to manipulate
const doc = document.implementation.createHTMLDocument();
doc.open();
doc.write(h);
doc.writeln(h);
doc.close();
// remove any <script> tags
@@ -58,17 +53,30 @@ export default {
i.parentNode.removeChild(i);
}
// replace any url(...) links in <style> blocks
const styles = doc.getElementsByTagName("style");
for (const i of styles) {
i.innerHTML = i.innerHTML.replaceAll(urlRegex, (match, p1, p2, p3) => {
if (typeof p2 === "string") {
// quoted URL
return (
`url(${p2}${proxy}?data=` + btoa(this.message.ID + ":" + this.decodeEntities(p3)) + `${p2})`
);
}
return `url(${proxy}?data=` + btoa(this.message.ID + ":" + this.decodeEntities(p3)) + `)`;
});
}
// replace stylesheet links with proxy links
const stylesheets = doc.getElementsByTagName("link");
for (const i of stylesheets) {
const src = i.getAttribute("href");
if (
src &&
src.match(/^https?:\/\//i) &&
src.indexOf(window.location.origin + window.location.pathname) !== 0
) {
i.setAttribute("href", `${proxy}?url=` + encodeURIComponent(this.decodeEntities(src)));
i.setAttribute("href", `${proxy}?data=` + btoa(this.message.ID + ":" + this.decodeEntities(src)));
}
}
@@ -81,7 +89,7 @@ export default {
src.match(/^https?:\/\//i) &&
src.indexOf(window.location.origin + window.location.pathname) !== 0
) {
i.setAttribute("src", `${proxy}?url=` + encodeURIComponent(this.decodeEntities(src)));
i.setAttribute("src", `${proxy}?data=` + btoa(this.message.ID + ":" + this.decodeEntities(src)));
}
}
@@ -96,7 +104,10 @@ export default {
src.indexOf(window.location.origin + window.location.pathname) !== 0
) {
// replace with proxy link
i.setAttribute("background", `${proxy}?url=` + encodeURIComponent(this.decodeEntities(src)));
i.setAttribute(
"background",
`${proxy}?data=` + btoa(this.message.ID + ":" + this.decodeEntities(src)),
);
}
}

View File

@@ -14,7 +14,7 @@ export default {
},
watch: {
"mailbox.refresh": function (v) {
"mailbox.refresh"(v) {
if (v) {
// trigger a refresh
this.loadMessages();
@@ -45,9 +45,9 @@ export default {
const params = {};
mailbox.selected = [];
params["limit"] = pagination.limit;
params.limit = pagination.limit;
if (pagination.start > 0) {
params["start"] = pagination.start;
params.start = pagination.start;
}
this.get(this.apiURI, params, (response) => {

View File

@@ -20,6 +20,9 @@ export const mailbox = reactive({
appInfo: {}, // application information
uiConfig: {}, // configuration for UI
lastMessage: false, // return scrolling
defaultReleaseAddresses: localStorage.getItem("defaultReleaseAddresses")
? JSON.parse(localStorage.getItem("defaultReleaseAddresses"))
: [], // default release addresses for released messages
// settings
showTagColors: !localStorage.getItem("hideTagColors"),
@@ -33,7 +36,7 @@ export const mailbox = reactive({
watch(
() => mailbox.count,
(v) => {
() => {
mailbox.selected = [];
},
);
@@ -82,6 +85,17 @@ watch(
},
);
watch(
() => mailbox.defaultReleaseAddresses,
(v) => {
if (v.length) {
localStorage.setItem("defaultReleaseAddresses", JSON.stringify(v));
} else {
localStorage.removeItem("defaultReleaseAddresses");
}
},
);
watch(
() => mailbox.timeZone,
(v) => {

View File

@@ -36,7 +36,7 @@ export default {
},
watch: {
$route(to, from) {
$route() {
this.loadMailbox();
},
},
@@ -176,7 +176,7 @@ export default {
</script>
<template>
<div class="navbar navbar-expand-lg navbar-dark row flex-shrink-0 bg-primary text-white d-print-none">
<div class="navbar navbar-expand-lg row flex-shrink-0 bg-primary text-white d-print-none" data-bs-theme="dark">
<div class="col-xl-2 col-md-3 col-auto pe-0">
<RouterLink to="/" class="navbar-brand text-white me-0" @click="reloadMailbox">
<img :src="resolve('/mailpit.svg')" alt="Mailpit" />

View File

@@ -28,6 +28,7 @@ export default {
mailbox,
pagination,
message: false,
loadReleaseModal: false,
errorMessage: false,
apiSideNavURI: false,
apiSideNavParams: URLSearchParams,
@@ -94,7 +95,7 @@ export default {
},
watch: {
$route(to, from) {
$route() {
this.loadMessage();
},
},
@@ -442,7 +443,11 @@ export default {
if (pagination.limit !== pagination.defaultLimit) {
p.limit = pagination.limit.toString();
}
this.$router.push("/?" + new URLSearchParams(p).toString());
if (p.start || p.limit) {
this.$router.push("/?" + new URLSearchParams(p).toString());
} else {
this.$router.push("/");
}
}
},
@@ -451,19 +456,25 @@ export default {
},
initReleaseModal() {
this.modal("ReleaseModal").show();
window.setTimeout(() => {
// delay to allow elements to load / focus
this.$refs.ReleaseRef.initTags();
document.querySelector('#ReleaseModal input[role="combobox"]').focus();
}, 500);
// reset releaseMessage to force re-render so default release addresses can be included
this.loadReleaseModal = false;
this.$nextTick(() => {
this.loadReleaseModal = true;
this.$nextTick(() => {
this.modal("ReleaseModal").show();
window.setTimeout(() => {
// delay to allow elements to load / focus
this.$refs.ReleaseRef.initTags();
}, 250);
});
});
},
},
};
</script>
<template>
<div class="navbar navbar-expand-lg navbar-dark row flex-shrink-0 bg-primary text-white d-print-none">
<div class="navbar navbar-expand-lg row flex-shrink-0 bg-primary text-white d-print-none" data-bs-theme="dark">
<div class="d-none d-xl-block col-xl-3 col-auto pe-0">
<RouterLink to="/" class="navbar-brand text-white me-0" @click="pagination.start = 0">
<img :src="resolve('/mailpit.svg')" alt="Mailpit" />
@@ -485,11 +496,11 @@ export default {
title="Release message"
@click="initReleaseModal()"
>
<i class="bi bi-send"></i>
<i class="bi bi-send me-md-2"></i>
<span class="d-none d-md-inline">Release</span>
</button>
<button class="btn btn-outline-light me-1 me-sm-2" title="Delete message" @click="deleteMessage()">
<i class="bi bi-trash-fill"></i>
<i class="bi bi-trash-fill me-md-2"></i>
<span class="d-none d-md-inline">Delete</span>
</button>
</div>
@@ -707,7 +718,7 @@ export default {
<AboutMailpit modals />
<AjaxLoader :loading="loading" />
<Release
v-if="mailbox.uiConfig.MessageRelay && message"
v-if="mailbox.uiConfig.MessageRelay && loadReleaseModal"
ref="ReleaseRef"
:message="message"
@delete="deleteMessage"

View File

@@ -36,7 +36,7 @@ export default {
},
watch: {
$route(to, from) {
$route() {
this.doSearch();
},
},
@@ -124,7 +124,7 @@ export default {
</script>
<template>
<div class="navbar navbar-expand-lg navbar-dark row flex-shrink-0 bg-primary text-white d-print-none">
<div class="navbar navbar-expand-lg row flex-shrink-0 bg-primary text-white d-print-none" data-bs-theme="dark">
<div class="col-xl-2 col-md-3 col-auto pe-0">
<RouterLink to="/" class="navbar-brand text-white me-0" @click="pagination.start = 0">
<img :src="resolve('/mailpit.svg')" alt="Mailpit" />

View File

@@ -34,8 +34,7 @@ var (
var upgrader = websocket.Upgrader{
ReadBufferSize: 1024,
WriteBufferSize: 1024,
CheckOrigin: func(r *http.Request) bool { return true }, // allow multi-domain
EnableCompression: true, // experimental compression
EnableCompression: true,
}
// Client is a middleman between the websocket connection and the hub.