Bug 291956
| Summary: | i18n placeholder bugs | ||
|---|---|---|---|
| Product: | WebKit | Reporter: | lcohen |
| Component: | WebKit Extensions | Assignee: | Nobody <webkit-unassigned> |
| Status: | NEW | ||
| Severity: | Normal | CC: | alexeiatyahoodotcom, carlosj-webkit-bugzilla, timothy, webkit-bug-importer |
| Priority: | P2 | Keywords: | InRadar |
| Version: | Safari 18 | ||
| Hardware: | Mac (Apple Silicon) | ||
| OS: | macOS 15 | ||
| See Also: | https://bugs.webkit.org/show_bug.cgi?id=306492 | ||
lcohen
I've noticed two bugs when using placeholders with i18n.getMessage():
1) When two placeholders surround a word without intervening spaces (i.e. "$START_LINK_TAG$here$END_LINK_TAG"), the substitution is incorrect (doesn't include the inner word and includes the placeholder title instead of the placeholder content). Spaces need to be added in between the placeholders and inner word for the substitution to be correct, but that workaround causes other minor issues.
2) If you pass an integer as a placeholder (i.e. chrome.i18n.getMessage("example_message", [intValue]), the placeholder is missing from the resulting message. This can be worked around by casting the numeric placeholder value to string first, but Webkit should handle this case.
Neither of these issues occur in Chrome or Firefox.
Steps to reproduce:
- Add the following code to these Safari Web Extension files (or use this demo extension: https://github.com/lenacohen/Safari-Test-Extensions/tree/main/dnr-placeholder-bugs/i18n%20Placeholder%20Bugs)
_locales/en/messages.json:
"popup_instructions_original": {
"message": "Integer placeholders don't appear instead of being cast as strings. Placeholders surrounding a word break unless there's at least one inner space: $COUNT$ potential $LINK_START$trackers$LINK_END$ blocked",
"description": "Popup message shown when at least one tracker was blocked.",
"placeholders": {
"count": {
"content": "$1",
"example": "15"
},
"link_start": {
"content": "$2",
"example": "<a href='https://privacybadger.org/#What-is-a-third-party-tracker'>"
},
"link_end": {
"content": "</a>"
}
}
},
popup.js:
document.addEventListener('DOMContentLoaded', () => {
const msg = chrome.i18n.getMessage("popup_instructions_original", [
5,
"<a target='_blank' title='What is a third-party tracker?' href='https://privacybadger.org/#What-is-a-third-party-tracker'>",
"</a>"
]);
document.getElementById('placeholder-test-original').innerHTML = msg;
});
popup.html:
<p id="placeholder-test-original"></p>
Expected Result:
Popup contains the phrase "5 potential trackers blocked" ("trackers" is linked to https://privacybadger.org/#What-is-a-third-party-tracker)
Actual result:
The popup instead says: " potential LINK_END$ blocked"
Workarounds:
We've resorted to adding an extra space between the word and its surrounding placeholders (i.e. “… $LINK_START$ trackers $LINK_END$ …”, “… $LINK_START$trackers $LINK_END$ …”, or “… $LINK_START$ trackers$LINK_END$ …”
The problem with this workaround is:
1) it's difficult to manage with translators who will likely remove the space
2) it is an issue in some locales (e.g. Chinese) where characters should be next to each other with no spaces and we don't want to introduce a weird space
| Attachments | ||
|---|---|---|
| Add attachment proposed patch, testcase, etc. |
Radar WebKit Bug Importer
<rdar://problem/149855718>
Carlos J.
Simplified cross-browser demo extension:
https://jeurissen.co/webext-demos/i18n-placeholders
Alexei
This is still a problem with Safari 26.3
Additionally, we discovered a variant of this bug where two consecutive placeholders result in garbled output.
For example:
"widget_placeholder_pb_has_replaced": {
"message": "Privacy Badger заменил $START_ANCHOR_TAG$ виджет $WIDGET$ $END_ANCHOR_TAG$",
"description": "...",
"placeholders": {
"widget": {
"content": "$1",
"example": "Google reCAPTCHA"
},
"start_anchor_tag": {
"content": "$2",
"example": "<a href='...'>"
},
"end_anchor_tag": {
"content": "$3",
"example": "</a>"
}
}
},
Expected:
Privacy Badger заменил <a href="...">виджет Facebook Video </a>
Actual:
Privacy Badger заменил <a href="...">виджет Facebook Video $</a>ivacy Badger заменил <a href="...">виджет Facebook Video $3
Carlos J.
Updated the demo extension to clearly indicate the incorrect results mentioned by Alexei above:
https://jeurissen.co/webext-demos/i18n-placeholders
The extension highlights expected vs actual.