Skip to content

Commit

Permalink
bridge: Drop translations from manifests.js, introduce m-i18n.js
Browse files Browse the repository at this point in the history
Pages don't (shouldn't) care about manifest translations when including
`manifests.js` -- they usually do that to query for a package's
existence or some feature flags.

Only the Shell cares about the translations. So drop translations from
`manifests.js`, and support a new `manifests-i18n.js` which only the
shell uses.

This isolates translations from different pages from another.
Concretely, subscription-manager-cockpit and our systemd page both
translate "$0 important hit" differently, and even to different data
types (in s-m it results in an array, in systemd in a normal string).
This caused a page crash, and also wrong strings, as s-m's translations
are really not expected to be used on the Overview page.

This also speeds up the loading of frames, as they now don't have to go
through umpteen `cockpit.locale()` calls any more.

Note that this still leaves i18n conflicts in the shell itself, so this
isn't a full fix, just an "80%" mitigation.

Fixes #21486
  • Loading branch information
martinpitt committed Jan 14, 2025
1 parent 4e5920c commit f48fea8
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 16 deletions.
2 changes: 1 addition & 1 deletion pkg/shell/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<link href="shell.css" rel="stylesheet" />
<link href="../../static/branding.css" rel="stylesheet" />
<script src="../base1/cockpit.js"></script>
<script src="../manifests.js"></script>
<script src="../manifests-i18n.js"></script>
<script src="po.js"></script>
<script src="shell.js"></script>
</head>
Expand Down
31 changes: 17 additions & 14 deletions src/cockpit/packages.py
Original file line number Diff line number Diff line change
Expand Up @@ -516,26 +516,27 @@ def reload_hint(self):
self.reload()
self.saw_first_reload_hint = True

def load_manifests_js(self, headers: JsonObject) -> Document:
def load_manifests_js(self, headers: JsonObject, *, i18n: bool) -> Document:
logger.debug('Serving /manifests.js')

chunks: List[bytes] = []

# Send the translations required for the manifest files, from each package
locales = parse_accept_language(get_str(headers, 'Accept-Language', ''))
for name, package in self.packages.items():
if name in ['static', 'base1']:
continue
if i18n:
locales = parse_accept_language(get_str(headers, 'Accept-Language', ''))
for name, package in self.packages.items():
if name in ['static', 'base1']:
continue

# find_translation will always find at least 'en'
translation = package.load_translation('po.manifest.js', locales)
with translation.data:
if translation.content_encoding == 'gzip':
data = gzip.decompress(translation.data.read())
else:
data = translation.data.read()
# find_translation will always find at least 'en'
translation = package.load_translation('po.manifest.js', locales)
with translation.data:
if translation.content_encoding == 'gzip':
data = gzip.decompress(translation.data.read())
else:
data = translation.data.read()

chunks.append(data)
chunks.append(data)

chunks.append(b"""
(function (root, data) {
Expand Down Expand Up @@ -573,7 +574,9 @@ def load_path(self, path: str, headers: JsonObject) -> Document:
if packagename is not None:
return self.packages[packagename].load_path(filename, headers)
elif filename == 'manifests.js':
return self.load_manifests_js(headers)
return self.load_manifests_js(headers, i18n=False)
elif filename == 'manifests-i18n.js':
return self.load_manifests_js(headers, i18n=True)
elif filename == 'manifests.json':
return self.load_manifests_json()
else:
Expand Down
2 changes: 1 addition & 1 deletion test/pytest/test_packages.py
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ def test_translation(pkgdir):
assert document.data.read() == b''

# make sure the manifest translations get sent along with manifests.js
document = packages.load_path('/manifests.js', {'Accept-Language': 'de'})
document = packages.load_path('/manifests-i18n.js', {'Accept-Language': 'de'})
contents = document.data.read()
assert b'eins\n' in contents
assert b'zwo\n' in contents
Expand Down

0 comments on commit f48fea8

Please sign in to comment.