···88import { ICommandPalette } from '@jupyterlab/apputils';
99import { IFileBrowserFactory } from '@jupyterlab/filebrowser';
1010import { ILauncher } from '@jupyterlab/launcher';
1111+import { ITranslator } from '@jupyterlab/translation';
1212+import { ISettingRegistry } from '@jupyterlab/settingregistry';
11131214import { BlocklyEditorFactory } from './factory';
1315import { IBlocklyManager } from './token';
···2729}
28302931/**
3232+ * The id of the translation plugin.
3333+ */
3434+const PLUGIN_ID = '@jupyterlab/translation-extension:plugin';
3535+3636+/**
3037 * Initialization data for the jupyterlab-blocky extension.
3138 */
3239const plugin: JupyterFrontEndPlugin<IBlocklyManager> = {
3340 id: 'jupyterlab-blocky:plugin',
3441 autoStart: true,
3535- requires: [ILayoutRestorer, IRenderMimeRegistry, IFileBrowserFactory],
4242+ requires: [
4343+ ILayoutRestorer,
4444+ IRenderMimeRegistry,
4545+ IFileBrowserFactory,
4646+ ISettingRegistry,
4747+ ITranslator
4848+ ],
3649 optional: [ILauncher, ICommandPalette],
3750 provides: IBlocklyManager,
3851 activate: (
···4053 restorer: ILayoutRestorer,
4154 rendermime: IRenderMimeRegistry,
4255 browserFactory: IFileBrowserFactory,
5656+ settings: ISettingRegistry,
5757+ translator: ITranslator,
4358 launcher: ILauncher | null,
4459 palette: ICommandPalette | null
4560 ): IBlocklyManager => {
···82978398 // The rendermime instance, necessary to render the outputs
8499 // after a code execution.
8585- rendermime: rendermime
100100+ rendermime: rendermime,
101101+102102+ // The translator instance, used for the internalization of the plugin.
103103+ translator: translator
86104 });
8710588106 // Add the widget to the tracker when it's created
···98116 });
99117 // Registering the widget factory
100118 app.docRegistry.addWidgetFactory(widgetFactory);
119119+120120+ function getSetting(setting: ISettingRegistry.ISettings): string {
121121+ // Read the settings and convert to the correct type
122122+ const currentLocale: string = setting.get('locale').composite as string;
123123+ return currentLocale;
124124+ }
125125+126126+ // Wait for the application to be restored and
127127+ // for the settings for this plugin to be loaded
128128+ settings.load(PLUGIN_ID).then(setting => {
129129+ // Read the settings
130130+ const currentLocale = getSetting(setting);
131131+132132+ // Listen for our plugin setting changes using Signal
133133+ setting.changed.connect(getSetting);
134134+135135+ // Get new language and call the function that modifies the language name accordingly.
136136+ // Also, make the transformation to have the name of the language package as in Blockly.
137137+ const language =
138138+ currentLocale[currentLocale.length - 2].toUpperCase() +
139139+ currentLocale[currentLocale.length - 1].toLowerCase();
140140+ console.log(`Current Language : '${language}'`);
141141+142142+ // Transmitting the current language to the manager.
143143+ widgetFactory.manager.setlanguage(language);
144144+ });
101145102146 commands.addCommand(command, {
103147 label: args =>
+14
src/layout.ts
···11import { SimplifiedOutputArea, OutputAreaModel } from '@jupyterlab/outputarea';
22import { IRenderMimeRegistry } from '@jupyterlab/rendermime';
33import { ISessionContext } from '@jupyterlab/apputils';
44+// import { ITranslator } from '@jupyterlab/translation';
4556import { Message } from '@lumino/messaging';
67import { PartialJSONValue } from '@lumino/coreutils';
78import { PanelLayout, Widget } from '@lumino/widgets';
89import { IIterator, ArrayIterator } from '@lumino/algorithm';
1010+import { Signal } from '@lumino/signaling';
9111012import * as Blockly from 'blockly';
1113···2022 private _manager: BlocklyManager;
2123 private _workspace: Blockly.WorkspaceSvg;
2224 private _sessionContext: ISessionContext;
2525+ // private _translator: ITranslator;
2326 private _outputArea: SimplifiedOutputArea;
24272528 /**
···3033 manager: BlocklyManager,
3134 sessionContext: ISessionContext,
3235 rendermime: IRenderMimeRegistry
3636+ // translator: ITranslator
3337 ) {
3438 super();
3539 this._manager = manager;
3640 this._sessionContext = sessionContext;
4141+ // this._translator = translator;
37423843 // Creating the container for the Blockly editor
3944 // and the output area to render the execution replies.
···6469 * Dispose of the resources held by the widget.
6570 */
6671 dispose(): void {
7272+ this._manager.changed.disconnect(this._resizeWorkspace, this);
7373+ Signal.clearData(this);
6774 this._workspace.dispose();
6875 super.dispose();
6976 }
···137144 toolbox: this._manager.toolbox,
138145 theme: THEME
139146 });
147147+148148+ // let categories: string;
149149+150150+ // Loading the ITranslator
151151+ // const trans = this._translator.load('jupyterlab-blockly');
152152+153153+ // categories = trans.__('Category');
140154 }
141155142156 private _resizeWorkspace(): void {
+135
src/manager.ts
···11import { JSONObject } from '@lumino/coreutils';
22+import { ISignal, Signal } from '@lumino/signaling';
2334import * as Blockly from 'blockly';
4556import BlocklyPy from 'blockly/python';
77+import * as En from 'blockly/msg/en';
6879import { IBlocklyManager } from './token';
810import { TOOLBOX } from './utils';
···1113 private _toolbox: JSONObject;
1214 private _activeGenerator: Blockly.Generator;
1315 private _generators: Map<string, Blockly.Generator>;
1616+ private _language: string;
1717+ private _changed: Signal<BlocklyManager, void>;
14181519 /**
1620 * Constructor of BlocklyEditorFactory.
···2125 this._toolbox = TOOLBOX;
2226 this._activeGenerator = BlocklyPy;
2327 this._generators = new Map<string, Blockly.Generator>();
2828+ this._language = 'En'; // By default we choose English.
2929+ this._changed = new Signal<BlocklyManager, void>(this);
2430 }
25312632 get toolbox(): JSONObject {
···3541 return this._activeGenerator;
3642 }
37434444+ get changed(): ISignal<BlocklyManager, void> {
4545+ return this._changed;
4646+ }
4747+4848+ set language(language: string) {
4949+ this._language = language;
5050+ }
5151+5252+ get language(): string {
5353+ return this._language;
5454+ }
5555+3856 registerToolbox(value: JSONObject): void {
3957 this._toolbox = value;
4058 }
···45634664 registerGenerator(kernel: string, generator: Blockly.Generator): void {
4765 this._generators.set(kernel, generator);
6666+ }
6767+6868+ setlanguage(language: string): void {
6969+ this.language = language;
7070+ Private.importLanguageModule(language);
7171+ }
7272+}
7373+7474+// Dynamically importing the language modules needed for each respective
7575+// user, in order to change the Blockly language in accordance to the
7676+// JL one.
7777+namespace Private {
7878+ export async function importLanguageModule(language: string) {
7979+ let module: Promise<any>;
8080+ switch (language) {
8181+ case 'En':
8282+ module = import('blockly/msg/en');
8383+ break;
8484+ case 'Es':
8585+ module = import('blockly/msg/es');
8686+ break;
8787+ case 'Fr':
8888+ module = import('blockly/msg/fr');
8989+ break;
9090+ case 'Sa' || 'Ar':
9191+ module = import('blockly/msg/ar');
9292+ break;
9393+ case 'Cz':
9494+ module = import('blockly/msg/cs');
9595+ break;
9696+ case 'Dk':
9797+ module = import('blockly/msg/da');
9898+ break;
9999+ case 'De':
100100+ module = import('blockly/msg/de');
101101+ break;
102102+ case 'Gr':
103103+ module = import('blockly/msg/el');
104104+ break;
105105+ case 'Ee':
106106+ module = import('blockly/msg/et');
107107+ break;
108108+ case 'Fi':
109109+ module = import('blockly/msg/fi');
110110+ break;
111111+ case 'Il':
112112+ module = import('blockly/msg/he');
113113+ break;
114114+ case 'Hu':
115115+ module = import('blockly/msg/hu');
116116+ break;
117117+ case 'Am':
118118+ module = import('blockly/msg/hy');
119119+ break;
120120+ case 'Id':
121121+ module = import('blockly/msg/id');
122122+ break;
123123+ case 'It':
124124+ module = import('blockly/msg/it');
125125+ break;
126126+ case 'Jp':
127127+ module = import('blockly/msg/ja');
128128+ break;
129129+ case 'Kr':
130130+ module = import('blockly/msg/ko');
131131+ break;
132132+ case 'Lt':
133133+ module = import('blockly/msg/lt');
134134+ break;
135135+ case 'Nl':
136136+ module = import('blockly/msg/nl');
137137+ break;
138138+ case 'Pl':
139139+ module = import('blockly/msg/pl');
140140+ break;
141141+ case 'Br':
142142+ module = import('blockly/msg/pt');
143143+ break;
144144+ case 'Ro':
145145+ module = import('blockly/msg/ro');
146146+ break;
147147+ case 'Ru':
148148+ module = import('blockly/msg/ru');
149149+ break;
150150+ case 'Lk':
151151+ module = import('blockly/msg/si');
152152+ break;
153153+ case 'Tr':
154154+ module = import('blockly/msg/tr');
155155+ break;
156156+ case 'Ua':
157157+ module = import('blockly/msg/uk');
158158+ break;
159159+ case 'Vn':
160160+ module = import('blockly/msg/vi');
161161+ break;
162162+ case 'Tw':
163163+ module = import('blockly/msg/zh-hant');
164164+ break;
165165+ case 'Cn':
166166+ module = import('blockly/msg/zh-hans');
167167+ break;
168168+ // Complete with all the cases taken from: (last updates June 2022)
169169+ // List of languages in blockly: https://github.com/google/blockly/tree/master/msg/js
170170+ // List of languages in Lab: https://github.com/jupyterlab/language-packs/tree/master/language-packs
171171+ default:
172172+ console.warn('Language not found. Loading english');
173173+ module = Promise.resolve(En);
174174+ break;
175175+ }
176176+177177+ // Setting the current language in Blockly.
178178+ module.then(lang => {
179179+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
180180+ // @ts-ignore
181181+ Blockly.setLocale(lang);
182182+ });
48183 }
49184}
+9-2
src/widget.ts
···66import { ToolbarButton } from '@jupyterlab/apputils';
77import { IRenderMimeRegistry } from '@jupyterlab/rendermime';
88import { runIcon } from '@jupyterlab/ui-components';
99+// import { ITranslator } from '@jupyterlab/translation';
9101011import { Panel } from '@lumino/widgets';
1112import { Signal } from '@lumino/signaling';
···2021 constructor(options: DocumentWidget.IOptions<BlocklyPanel, DocumentModel>) {
2122 super(options);
22232424+ // Loading the ITranslator
2525+ // const trans = this.translator.load('jupyterlab');
2626+2327 // Create and add a button to the toolbar to execute
2428 // the code.
2529 const runCode = () => {
2630 (this.content.layout as BlocklyLayout).run();
2731 };
2832 const button = new ToolbarButton({
2929- label: 'Run Code',
3333+ label: '',
3034 icon: runIcon,
3135 className: 'jp-blockly-button',
3236 onClick: runCode,
···3438 });
3539 button.addClass('jp-blockly-runButton');
3640 this.toolbar.addItem('run', button);
4141+ // button.title.label = trans.__('Run Code');
3742 }
38433944 /**
···5964 constructor(
6065 context: DocumentRegistry.IContext<DocumentModel>,
6166 manager: BlocklyManager,
6262- rendermime: IRenderMimeRegistry
6767+ rendermime: IRenderMimeRegistry,
6868+ language: string
6969+ // translator: ITranslator
6370 ) {
6471 super({
6572 layout: new BlocklyLayout(manager, context.sessionContext, rendermime)