Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions packages/core/src/browser/common-frontend-contribution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -291,10 +291,16 @@ export class CommonFrontendContribution implements FrontendApplicationContributi
}

onStart(): void {
this.setupHtmlLanguageAttributes(document.documentElement);
this.storageService.getData<{ recent: Command[] }>(RECENT_COMMANDS_STORAGE_KEY, { recent: [] })
.then(tasks => this.commandRegistry.recent = tasks.recent);
}

protected setupHtmlLanguageAttributes(element: HTMLElement): void {
nls.setHtmlLang(element);
nls.setHtmlNoTranslate(element);
}

onStop(): void {
const recent = this.commandRegistry.recent;
this.storageService.setData<{ recent: Command[] }>(RECENT_COMMANDS_STORAGE_KEY, { recent });
Expand Down
8 changes: 8 additions & 0 deletions packages/core/src/browser/secondary-window-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { Emitter } from '../common/event';
import { isSecondaryWindow, SecondaryWindowRootWidget, SecondaryWindowService } from './window/secondary-window-service';
import { KeybindingRegistry } from './keybinding';
import { MAIN_AREA_ID, TheiaDockPanel } from './shell/theia-dock-panel';
import { nls } from '../common/nls';

/** Widgets to be contained inside a DockPanel in the secondary window. */
class SecondaryWindowDockPanelWidget extends SecondaryWindowRootWidget {
Expand Down Expand Up @@ -180,6 +181,8 @@ export class SecondaryWindowHandler {
// See https://html.spec.whatwg.org/multipage/dom.html#document.title
newWindow.document.title = `${widget.title.label} — ${mainWindowTitle}`;

this.setupHtmlLanguageAttributes(newWindow.document.documentElement);

const element = newWindow.document.getElementById('widget-host');
if (!element) {
console.error('Could not find dom element to attach to in secondary window');
Expand Down Expand Up @@ -218,6 +221,11 @@ export class SecondaryWindowHandler {
});
}

protected setupHtmlLanguageAttributes(element: HTMLElement): void {
nls.setHtmlLang(element);
nls.setHtmlNoTranslate(element);
}

private onWidgetRemove(widget: Widget, newWindow: Window, rootWidget: SecondaryWindowRootWidget): void {
// Close the window if the widget is disposed, e.g. by a command closing all widgets.
this.onWillRemoveWidgetEmitter.fire([widget, newWindow]);
Expand Down
25 changes: 25 additions & 0 deletions packages/core/src/common/nls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,31 @@ export namespace nls {
export function setLocale(id: string): void {
window.localStorage.setItem(localeId, id);
}

/**
* Sets the 'lang' attribute on the given HTML element based on the current locale.
* If no locale is set, defaults to 'en' (English).
* Typically used with document.documentElement (the <html> tag) to set the page language.
*
* @param element The HTML element to set the language attribute on
*/
export function setHtmlLang(element: HTMLElement): void {
const lang = locale?.split('_').at(0) || 'en';
element.setAttribute('lang', lang);
}

/**
* Sets the 'translate' attribute to 'no' and adds the 'notranslate' class
* to the given HTML element. This prevents translation tools from translating
* the content of the element.
* Typically used with document.documentElement (the <html> tag) to disable page translation.
*
* @param element The HTML element to set translation attributes on
*/
export function setHtmlNoTranslate(element: HTMLElement): void {
element.setAttribute('translate', 'no');
element.classList.add('notranslate');
}
}

interface NlsKeys {
Expand Down
Loading