White-label: make the hide-branding toggle name nobody (#292)

It read 'Hide "ScreenTinker" branding', and the brand substitution turned that into
'Hide "Acme" branding' on Acme's own instance — backwards, because the toggle hides the
PLATFORM's attribution rather than the operator's own name. bold-media-group asked for
generic wording, which is the better call.

Now "Hide platform branding", and the equivalent in the six other translated locales.
The test that requires {brandName} in the branded strings deliberately excludes this
one and asserts the opposite: that it names neither the product nor the operator.

⚠️ The non-English wordings are my translations, not a translator's — they are short
and mechanical, but worth a native reader's glance before anyone leans on them.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014kfhrUPit5MCqxeTQyqr56
This commit is contained in:
ScreenTinker 2026-08-18 23:18:47 -05:00
parent c4b19494fb
commit 05c5edf278
8 changed files with 29 additions and 8 deletions

View file

@ -448,7 +448,7 @@ export default {
'settings.custom_domain': 'Benutzerdefinierte Domain',
'settings.favicon_url': 'Favicon-URL',
'settings.custom_css': 'Benutzerdefiniertes CSS (optional)',
'settings.hide_branding': '„{brandName}"-Branding ausblenden',
'settings.hide_branding': 'Plattform-Branding ausblenden',
'settings.save_branding': 'Branding speichern',
'settings.preview': 'Vorschau',
'settings.white_label_enterprise_only': 'Benutzerdefiniertes Branding ist im Enterprise-Plan verfügbar',

View file

@ -922,7 +922,7 @@ export default {
'settings.custom_domain': 'Custom Domain',
'settings.favicon_url': 'Favicon URL',
'settings.custom_css': 'Custom CSS (optional)',
'settings.hide_branding': 'Hide "{brandName}" branding',
'settings.hide_branding': 'Hide platform branding',
'settings.save_branding': 'Save Branding',
'settings.preview': 'Preview',
'settings.white_label_enterprise_only': 'Custom branding is available on the Enterprise plan',

View file

@ -478,7 +478,7 @@ export default {
'settings.custom_domain': 'Dominio personalizado',
'settings.favicon_url': 'URL del favicon',
'settings.custom_css': 'CSS personalizado (opcional)',
'settings.hide_branding': 'Ocultar la marca "{brandName}"',
'settings.hide_branding': 'Ocultar la marca de la plataforma',
'settings.save_branding': 'Guardar branding',
'settings.preview': 'Previsualizar',
'settings.white_label_enterprise_only': 'El branding personalizado está disponible en el plan Enterprise',

View file

@ -448,7 +448,7 @@ export default {
'settings.custom_domain': 'Domaine personnalisé',
'settings.favicon_url': 'URL du favicon',
'settings.custom_css': 'CSS personnalisé (facultatif)',
'settings.hide_branding': 'Masquer la marque « {brandName} »',
'settings.hide_branding': 'Masquer la marque de la plateforme',
'settings.save_branding': 'Enregistrer le branding',
'settings.preview': 'Aperçu',
'settings.white_label_enterprise_only': 'Le branding personnalisé est disponible sur le plan Enterprise',

View file

@ -424,7 +424,7 @@ export default {
'settings.custom_domain': 'Dominio Personalizzato',
'settings.favicon_url': 'URL Favicon',
'settings.custom_css': 'CSS Personalizzato (opzionale)',
'settings.hide_branding': 'Nascondi marchio "{brandName}"',
'settings.hide_branding': 'Nascondi il marchio della piattaforma',
'settings.save_branding': 'Salva Marchio',
'settings.preview': 'Anteprima',
'settings.white_label_enterprise_only': 'Il marchio personalizzato è disponibile solo nel piano Enterprise',

View file

@ -846,7 +846,7 @@ export default {
'settings.custom_domain': "カスタム ドメイン",
'settings.favicon_url': "ファビコンURL",
'settings.custom_css': "カスタム CSS (オプション)",
'settings.hide_branding': "「{brandName}」ブランドを非表示にする",
'settings.hide_branding': 'プラットフォームのブランドを非表示にする',
'settings.save_branding': "ブランディングを保存",
'settings.preview': "プレビュー",
'settings.white_label_enterprise_only': "Enterprise プランではカスタム ブランドが利用可能です",

View file

@ -448,7 +448,7 @@ export default {
'settings.custom_domain': 'Domínio personalizado',
'settings.favicon_url': 'URL do favicon',
'settings.custom_css': 'CSS personalizado (opcional)',
'settings.hide_branding': 'Ocultar marca "{brandName}"',
'settings.hide_branding': 'Ocultar a marca da plataforma',
'settings.save_branding': 'Salvar branding',
'settings.preview': 'Pré-visualizar',
'settings.white_label_enterprise_only': 'Branding personalizado disponível no plano Enterprise',

View file

@ -31,7 +31,6 @@ const BRANDED_KEYS = [
'device.owner_provision.constraints',
'device.terminal.welcome',
'settings.signin_err_link_already_used',
'settings.hide_branding',
'settings.setup_step_1',
'settings.import.invalid_file',
'onboarding.step.welcome.title',
@ -39,6 +38,16 @@ const BRANDED_KEYS = [
const localeFiles = () => fs.readdirSync(I18N_DIR).filter((f) => f.endsWith('.js'));
/*
* DELIBERATELY NOT IN THE LIST ABOVE.
*
* settings.hide_branding used to read 'Hide "ScreenTinker" branding', and substituting the brand
* turned it into 'Hide "Acme" branding' on Acme's own instance which is backwards: the toggle
* hides the PLATFORM's attribution, not the operator's own name. The reporter of #292 asked for
* generic wording instead, so this string names nobody at all.
*/
const GENERIC_KEY = 'settings.hide_branding';
test('no locale hardcodes the product name in a white-labelled string', () => {
const offences = [];
for (const file of localeFiles()) {
@ -123,3 +132,15 @@ test('the interpolation resolves, and falls back to the product name', async ()
delete globalThis.localStorage;
if (!priorNavigator) delete globalThis.navigator;
});
test('the hide-branding toggle names nobody', () => {
// Neither the upstream product (the original bug) nor the operator's own brand (which would read
// as "Hide Acme branding" on Acme's instance).
for (const file of localeFiles()) {
const src = fs.readFileSync(path.join(I18N_DIR, file), 'utf8');
const line = src.split('\n').find((l) => l.includes(`'${GENERIC_KEY}'`));
if (!line) continue;
assert.ok(!line.includes('ScreenTinker'), `${file}: ${GENERIC_KEY} still names the product`);
assert.ok(!line.includes('{brandName}'), `${file}: ${GENERIC_KEY} should be generic wording`);
}
});