From 6e3013723cf730ee22771f5dd89386771e44edc7 Mon Sep 17 00:00:00 2001 From: GermanBluefox Date: Mon, 16 Jun 2025 14:34:19 +0300 Subject: [PATCH 1/4] Take only available languages: https://github.com/ioBroker/ioBroker.javascript/issues/1497 --- src-editor/public/vs/configure.js | 19 ++++++++-------- .../Components/ScriptEditorVanilaMonaco.tsx | 22 +++++++++---------- 2 files changed, 20 insertions(+), 21 deletions(-) diff --git a/src-editor/public/vs/configure.js b/src-editor/public/vs/configure.js index 7086b6a74..cede9c9db 100644 --- a/src-editor/public/vs/configure.js +++ b/src-editor/public/vs/configure.js @@ -6,34 +6,35 @@ // Set the correct root path require.config({ paths: { 'vs': 'vs' }}); -// Allow localisation +// Allow localization // All languages in monaco-editor -var availableLanguages = ['de', 'en', 'fr', 'es', 'it', 'ja', 'ru', 'ko', 'zh-tw', 'zh-cn']; +const availableLanguages = ['de', 'en', 'fr', 'es', 'it', 'ru', 'zh-cn']; // find the best match function findLanguage() { - if (window.sysLang !== undefined) { + if (window.sysLang !== undefined && availableLanguages.includes(window.sysLang)) { return window.sysLang; // this variable will be set via info.js } if (navigator.languages && Array.isArray(navigator.languages)) { - return navigator.languages.find(function (lang) {return availableLanguages.indexOf(lang) > -1}); + return navigator.languages.find(lang => availableLanguages.includes(lang)) || 'en'; } - var lang = navigator.language || navigator.userLanguage; + let lang = navigator.language || navigator.userLanguage; if (typeof lang === 'string') { // first try the long version - if (availableLanguages.indexOf(lang) > -1) { + if (availableLanguages.includes(lang)) { return lang; } // then the short one - lang = lang.substr(0, 2); - if (availableLanguages.indexOf(lang) > -1) { + lang = lang.substring(0, 2); + if (availableLanguages.includes(lang)) { return lang; } } + return 'en'; } -var language = findLanguage(); +const language = findLanguage(); // if we have a match, configure the editor if (language !== undefined && language !== null && language !== 'en') { require.config({ diff --git a/src-editor/src/Components/ScriptEditorVanilaMonaco.tsx b/src-editor/src/Components/ScriptEditorVanilaMonaco.tsx index 69057df4e..36b9d7439 100644 --- a/src-editor/src/Components/ScriptEditorVanilaMonaco.tsx +++ b/src-editor/src/Components/ScriptEditorVanilaMonaco.tsx @@ -129,8 +129,8 @@ class ScriptEditor extends React.Component if (this.monacoCounter >= 20) { console.error('Cannot load monaco!'); } - } else { - cb && cb(); + } else if (cb) { + cb(); } } @@ -173,17 +173,15 @@ class ScriptEditor extends React.Component } if (!this.editor && monacoLoaded && this.monaco) { console.log('Init editor'); - if (this.props.onRegisterSelect) { - this.props.onRegisterSelect((): string | undefined => { - if (this.editor) { - const selection = this.editor.getSelection(); - if (selection) { - return this.editor.getModel()?.getValueInRange(selection); - } + this.props.onRegisterSelect?.((): string | undefined => { + if (this.editor) { + const selection = this.editor.getSelection(); + if (selection) { + return this.editor.getModel()?.getValueInRange(selection); } - return undefined; - }); - } + } + return undefined; + }); // For some reason, we have to get the original compiler options // and assign new properties one by one const compilerOptions = this.monaco.languages.typescript.typescriptDefaults.getCompilerOptions(); From 5c3f7d88dbdf4eb230c252bb7a0d04cc7675833a Mon Sep 17 00:00:00 2001 From: GermanBluefox Date: Mon, 16 Jun 2025 16:48:49 +0300 Subject: [PATCH 2/4] Corrected import of blocks: https://github.com/ioBroker/ioBroker.javascript/issues/1890 --- src-editor/src/Components/BlocklyEditor.tsx | 7 ++- src-editor/src/Components/BlocklyEditorTS.tsx | 12 ++--- .../field-colour/src/blocks/colourBlend.ts | 45 +----------------- .../field-colour/src/blocks/colourPicker.ts | 45 +----------------- .../field-colour/src/blocks/colourRandom.ts | 43 +---------------- .../field-colour/src/blocks/colourRgb.ts | 43 +---------------- .../src/blocks/textMultiline.ts | 47 ++----------------- .../src/Components/blockly-plugins/index.ts | 1 + src-editor/src/Dialogs/Import.tsx | 19 ++++++-- src-editor/src/i18n/de.json | 1 + src-editor/src/i18n/en.json | 1 + src-editor/src/i18n/es.json | 1 + src-editor/src/i18n/fr.json | 1 + src-editor/src/i18n/it.json | 1 + src-editor/src/i18n/nl.json | 1 + src-editor/src/i18n/pl.json | 1 + src-editor/src/i18n/pt.json | 1 + src-editor/src/i18n/ru.json | 1 + src-editor/src/i18n/uk.json | 1 + src-editor/src/i18n/zh-cn.json | 1 + 20 files changed, 44 insertions(+), 229 deletions(-) diff --git a/src-editor/src/Components/BlocklyEditor.tsx b/src-editor/src/Components/BlocklyEditor.tsx index e20c5f533..91e4bc144 100644 --- a/src-editor/src/Components/BlocklyEditor.tsx +++ b/src-editor/src/Components/BlocklyEditor.tsx @@ -483,12 +483,10 @@ class BlocklyEditor extends React.Component { this.setState({ importText: false }); this.onImportBlocks(text); diff --git a/src-editor/src/Components/BlocklyEditorTS.tsx b/src-editor/src/Components/BlocklyEditorTS.tsx index 6094a6d0b..c5dfde653 100644 --- a/src-editor/src/Components/BlocklyEditorTS.tsx +++ b/src-editor/src/Components/BlocklyEditorTS.tsx @@ -4,15 +4,17 @@ import React from 'react'; import { I18n, Message as DialogMessage, type ThemeType } from '@iobroker/adapter-react-v5'; -import DialogError from '../Dialogs/Error'; -import DialogExport from '../Dialogs/Export'; -import DialogImport from '../Dialogs/Import'; + import * as BlocklyTS from 'blockly/core'; import type { WorkspaceSvg } from 'blockly/core/workspace_svg'; import type { BlockSvg } from 'blockly/core/block_svg'; import { javascriptGenerator } from 'blockly/javascript'; import type { FlyoutDefinition } from 'blockly/core/utils/toolbox'; +import DialogError from '../Dialogs/Error'; +import DialogExport from '../Dialogs/Export'; +import DialogImport from '../Dialogs/Import'; + let languageBlocklyLoaded = false; let languageOwnLoaded = false; let toolboxText: string | null = null; @@ -496,11 +498,9 @@ class BlocklyEditor extends React.Component> >>> - RELATIONAL = 8, // < <= > >= - // eslint-disable-next-line @typescript-eslint/no-duplicate-enum-values - IN = 8, // in - // eslint-disable-next-line @typescript-eslint/no-duplicate-enum-values - INSTANCEOF = 8, // instanceof - EQUALITY = 9, // == != === !== - BITWISE_AND = 10, // & - BITWISE_XOR = 11, // ^ - BITWISE_OR = 12, // | - LOGICAL_AND = 13, // && - LOGICAL_OR = 14, // || - CONDITIONAL = 15, // ?: - ASSIGNMENT = 16, // = += -= **= *= /= %= <<= >>= ... - YIELD = 17, // yield - COMMA = 18, // , - NONE = 99, -} - /** The name this block is registered under. */ export const BLOCK_NAME = 'colour_blend'; @@ -86,13 +45,13 @@ const jsonDefinition = { }; /** - * Javascript block generator function. + * JavaScript block generator function. * * @param block The Block instance to generate code for. * @param generator The JavascriptGenerator calling the function. * @returns A tuple containing the code string and precedence. */ -export function toJavascript(block: Block, generator: JavascriptGenerator): [string, JavascriptOrder] { +export function toJavascript(block: Block, generator: JavascriptGenerator): [string, number] { // Blend two colours together. const colour1 = generator.valueToCode(block, 'COLOUR1', 99 /* JavascriptOrder.NONE */) || "'#000000'"; const colour2 = generator.valueToCode(block, 'COLOUR2', 99 /* JavascriptOrder.NONE */) || "'#000000'"; diff --git a/src-editor/src/Components/blockly-plugins/field-colour/src/blocks/colourPicker.ts b/src-editor/src/Components/blockly-plugins/field-colour/src/blocks/colourPicker.ts index ace74e4fb..7414d6097 100644 --- a/src-editor/src/Components/blockly-plugins/field-colour/src/blocks/colourPicker.ts +++ b/src-editor/src/Components/blockly-plugins/field-colour/src/blocks/colourPicker.ts @@ -9,47 +9,6 @@ import type { JavascriptGenerator } from 'blockly/javascript'; import { type Generators } from './generatorsType'; import { registerFieldColour } from '../field_colour'; -declare enum JavascriptOrder { - ATOMIC = 0, // 0 "" ... - NEW = 1.1, // new - MEMBER = 1.2, // . [] - FUNCTION_CALL = 2, // () - INCREMENT = 3, // ++ - // eslint-disable-next-line @typescript-eslint/no-duplicate-enum-values - DECREMENT = 3, // -- - BITWISE_NOT = 4.1, // ~ - UNARY_PLUS = 4.2, // + - UNARY_NEGATION = 4.3, // - - LOGICAL_NOT = 4.4, // ! - TYPEOF = 4.5, // typeof - VOID = 4.6, // void - DELETE = 4.7, // delete - AWAIT = 4.8, // await - EXPONENTIATION = 5, // ** - MULTIPLICATION = 5.1, // * - DIVISION = 5.2, // / - MODULUS = 5.3, // % - SUBTRACTION = 6.1, // - - ADDITION = 6.2, // + - BITWISE_SHIFT = 7, // << >> >>> - RELATIONAL = 8, // < <= > >= - // eslint-disable-next-line @typescript-eslint/no-duplicate-enum-values - IN = 8, // in - // eslint-disable-next-line @typescript-eslint/no-duplicate-enum-values - INSTANCEOF = 8, // instanceof - EQUALITY = 9, // == != === !== - BITWISE_AND = 10, // & - BITWISE_XOR = 11, // ^ - BITWISE_OR = 12, // | - LOGICAL_AND = 13, // && - LOGICAL_OR = 14, // || - CONDITIONAL = 15, // ?: - ASSIGNMENT = 16, // = += -= **= *= /= %= <<= >>= ... - YIELD = 17, // yield - COMMA = 18, // , - NONE = 99, -} - /** The name this block is registered under. */ export const BLOCK_NAME = 'colour_picker'; @@ -72,13 +31,13 @@ const jsonDefinition = { }; /** - * Javascript block generator function. + * JavaScript block generator function. * * @param block The Block instance to generate code for. * @param generator The JavascriptGenerator calling the function. * @returns A tuple containing the code string and precedence. */ -export function toJavascript(block: Block, generator: JavascriptGenerator): [string, JavascriptOrder] { +export function toJavascript(block: Block, generator: JavascriptGenerator): [string, number] { // Colour picker. const code = generator.quote_(block.getFieldValue('COLOUR')); return [code, 0 /* JavascriptOrder.ATOMIC */]; diff --git a/src-editor/src/Components/blockly-plugins/field-colour/src/blocks/colourRandom.ts b/src-editor/src/Components/blockly-plugins/field-colour/src/blocks/colourRandom.ts index df99241eb..bca0c3067 100644 --- a/src-editor/src/Components/blockly-plugins/field-colour/src/blocks/colourRandom.ts +++ b/src-editor/src/Components/blockly-plugins/field-colour/src/blocks/colourRandom.ts @@ -9,47 +9,6 @@ import type { JavascriptGenerator } from 'blockly/javascript'; import { type Generators } from './generatorsType'; import { registerFieldColour } from '../field_colour'; -declare enum JavascriptOrder { - ATOMIC = 0, // 0 "" ... - NEW = 1.1, // new - MEMBER = 1.2, // . [] - FUNCTION_CALL = 2, // () - INCREMENT = 3, // ++ - // eslint-disable-next-line @typescript-eslint/no-duplicate-enum-values - DECREMENT = 3, // -- - BITWISE_NOT = 4.1, // ~ - UNARY_PLUS = 4.2, // + - UNARY_NEGATION = 4.3, // - - LOGICAL_NOT = 4.4, // ! - TYPEOF = 4.5, // typeof - VOID = 4.6, // void - DELETE = 4.7, // delete - AWAIT = 4.8, // await - EXPONENTIATION = 5, // ** - MULTIPLICATION = 5.1, // * - DIVISION = 5.2, // / - MODULUS = 5.3, // % - SUBTRACTION = 6.1, // - - ADDITION = 6.2, // + - BITWISE_SHIFT = 7, // << >> >>> - RELATIONAL = 8, // < <= > >= - // eslint-disable-next-line @typescript-eslint/no-duplicate-enum-values - IN = 8, // in - // eslint-disable-next-line @typescript-eslint/no-duplicate-enum-values - INSTANCEOF = 8, // instanceof - EQUALITY = 9, // == != === !== - BITWISE_AND = 10, // & - BITWISE_XOR = 11, // ^ - BITWISE_OR = 12, // | - LOGICAL_AND = 13, // && - LOGICAL_OR = 14, // || - CONDITIONAL = 15, // ?: - ASSIGNMENT = 16, // = += -= **= *= /= %= <<= >>= ... - YIELD = 17, // yield - COMMA = 18, // , - NONE = 99, -} - /** The name this block is registered under. */ export const BLOCK_NAME = 'colour_random'; @@ -70,7 +29,7 @@ const jsonDefinition = { * @param generator The JavascriptGenerator calling the function. * @returns A tuple containing the code string and precedence. */ -export function toJavascript(block: Block, generator: JavascriptGenerator): [string, JavascriptOrder] { +export function toJavascript(block: Block, generator: JavascriptGenerator): [string, number] { // Generate a random colour. const functionName = generator.provideFunction_( 'colourRandom', diff --git a/src-editor/src/Components/blockly-plugins/field-colour/src/blocks/colourRgb.ts b/src-editor/src/Components/blockly-plugins/field-colour/src/blocks/colourRgb.ts index d407d3e67..d1290527f 100644 --- a/src-editor/src/Components/blockly-plugins/field-colour/src/blocks/colourRgb.ts +++ b/src-editor/src/Components/blockly-plugins/field-colour/src/blocks/colourRgb.ts @@ -9,47 +9,6 @@ import type { JavascriptGenerator } from 'blockly/javascript'; import { type Generators } from './generatorsType'; import { registerFieldColour } from '../field_colour'; -declare enum JavascriptOrder { - ATOMIC = 0, // 0 "" ... - NEW = 1.1, // new - MEMBER = 1.2, // . [] - FUNCTION_CALL = 2, // () - INCREMENT = 3, // ++ - // eslint-disable-next-line @typescript-eslint/no-duplicate-enum-values - DECREMENT = 3, // -- - BITWISE_NOT = 4.1, // ~ - UNARY_PLUS = 4.2, // + - UNARY_NEGATION = 4.3, // - - LOGICAL_NOT = 4.4, // ! - TYPEOF = 4.5, // typeof - VOID = 4.6, // void - DELETE = 4.7, // delete - AWAIT = 4.8, // await - EXPONENTIATION = 5, // ** - MULTIPLICATION = 5.1, // * - DIVISION = 5.2, // / - MODULUS = 5.3, // % - SUBTRACTION = 6.1, // - - ADDITION = 6.2, // + - BITWISE_SHIFT = 7, // << >> >>> - RELATIONAL = 8, // < <= > >= - // eslint-disable-next-line @typescript-eslint/no-duplicate-enum-values - IN = 8, // in - // eslint-disable-next-line @typescript-eslint/no-duplicate-enum-values - INSTANCEOF = 8, // instanceof - EQUALITY = 9, // == != === !== - BITWISE_AND = 10, // & - BITWISE_XOR = 11, // ^ - BITWISE_OR = 12, // | - LOGICAL_AND = 13, // && - LOGICAL_OR = 14, // || - CONDITIONAL = 15, // ?: - ASSIGNMENT = 16, // = += -= **= *= /= %= <<= >>= ... - YIELD = 17, // yield - COMMA = 18, // , - NONE = 99, -} - /** The name this block is registered under. */ export const BLOCK_NAME = 'colour_rgb'; @@ -90,7 +49,7 @@ const jsonDefinition = { * @param generator The JavascriptGenerator calling the function. * @returns A tuple containing the code string and precedence. */ -export function toJavascript(block: Block, generator: JavascriptGenerator): [string, JavascriptOrder] { +export function toJavascript(block: Block, generator: JavascriptGenerator): [string, number] { // Compose a colour from RGB components expressed as percentages. const red = generator.valueToCode(block, 'RED', 99 /* JavascriptOrder.NONE */) || 0; const green = generator.valueToCode(block, 'GREEN', 99 /* JavascriptOrder.NONE */) || 0; diff --git a/src-editor/src/Components/blockly-plugins/field-multilineinput/src/blocks/textMultiline.ts b/src-editor/src/Components/blockly-plugins/field-multilineinput/src/blocks/textMultiline.ts index e7a551f68..d8bcfe476 100644 --- a/src-editor/src/Components/blockly-plugins/field-multilineinput/src/blocks/textMultiline.ts +++ b/src-editor/src/Components/blockly-plugins/field-multilineinput/src/blocks/textMultiline.ts @@ -9,47 +9,6 @@ import type { JavascriptGenerator } from 'blockly/javascript'; import { type Generators } from './generatorsType'; import { registerFieldMultilineInput } from '../field_multilineinput'; -declare enum JavascriptOrder { - ATOMIC = 0, // 0 "" ... - NEW = 1.1, // new - MEMBER = 1.2, // . [] - FUNCTION_CALL = 2, // () - INCREMENT = 3, // ++ - // eslint-disable-next-line @typescript-eslint/no-duplicate-enum-values - DECREMENT = 3, // -- - BITWISE_NOT = 4.1, // ~ - UNARY_PLUS = 4.2, // + - UNARY_NEGATION = 4.3, // - - LOGICAL_NOT = 4.4, // ! - TYPEOF = 4.5, // typeof - VOID = 4.6, // void - DELETE = 4.7, // delete - AWAIT = 4.8, // await - EXPONENTIATION = 5, // ** - MULTIPLICATION = 5.1, // * - DIVISION = 5.2, // / - MODULUS = 5.3, // % - SUBTRACTION = 6.1, // - - ADDITION = 6.2, // + - BITWISE_SHIFT = 7, // << >> >>> - RELATIONAL = 8, // < <= > >= - // eslint-disable-next-line @typescript-eslint/no-duplicate-enum-values - IN = 8, // in - // eslint-disable-next-line @typescript-eslint/no-duplicate-enum-values - INSTANCEOF = 8, // instanceof - EQUALITY = 9, // == != === !== - BITWISE_AND = 10, // & - BITWISE_XOR = 11, // ^ - BITWISE_OR = 12, // | - LOGICAL_AND = 13, // && - LOGICAL_OR = 14, // || - CONDITIONAL = 15, // ?: - ASSIGNMENT = 16, // = += -= **= *= /= %= <<= >>= ... - YIELD = 17, // yield - COMMA = 18, // , - NONE = 99, -} - /** The name this block is registered under. */ export const BLOCK_NAME = 'text_multiline'; @@ -88,16 +47,16 @@ const jsonDefinition = { }; /** - * Javascript block generator function. + * JavaScript block generator function. * * @param block The Block instance to generate code for. * @param generator The JavascriptGenerator calling the function. * @returns A tuple containing the code string and precedence. */ -export function toJavascript(block: Block, generator: JavascriptGenerator): [string, JavascriptOrder] { +export function toJavascript(block: Block, generator: JavascriptGenerator): [string, number] { // Text value. const code = generator.multiline_quote_(block.getFieldValue('TEXT')); - const order = code.indexOf('+') !== -1 ? JavascriptOrder.ADDITION : JavascriptOrder.ATOMIC; + const order = code.indexOf('+') !== -1 ? 6.2 /* JavascriptOrder.ADDITION */ : 0 /* JavascriptOrder.ATOMIC */; return [code, order]; } diff --git a/src-editor/src/Components/blockly-plugins/index.ts b/src-editor/src/Components/blockly-plugins/index.ts index f69ece227..a8ca0451e 100644 --- a/src-editor/src/Components/blockly-plugins/index.ts +++ b/src-editor/src/Components/blockly-plugins/index.ts @@ -42,6 +42,7 @@ export interface BlocklyType { blockToDom: (block: BlockType, opt_noId?: boolean) => Element | DocumentFragment; domToPrettyText: (dom: Node) => string; domToWorkspace: (xml: Element, workspace: WorkspaceSvg) => string[]; + appendDomToWorkspace: (xml: Element, workspace: WorkspaceSvg) => string[]; }; svgResize: (workspace: WorkspaceSvg) => void; INPUT_VALUE: ConnectionType.INPUT_VALUE; diff --git a/src-editor/src/Dialogs/Import.tsx b/src-editor/src/Dialogs/Import.tsx index c373704eb..50b0585ed 100644 --- a/src-editor/src/Dialogs/Import.tsx +++ b/src-editor/src/Dialogs/Import.tsx @@ -6,15 +6,18 @@ import { Button, DialogTitle, DialogContent, DialogActions, Dialog } from '@mui/ import { Check as IconOk, Cancel as IconCancel } from '@mui/icons-material'; import { MdFileUpload as IconUpload, MdCancel as IconNo, MdAdd as IconPlus } from 'react-icons/md'; -import { I18n } from '@iobroker/adapter-react-v5'; +import { I18n, type ThemeType } from '@iobroker/adapter-react-v5'; const styles: Record = { textArea: { width: 'calc(100% - 10px)', - height: '80%', + height: 'calc(80% - 20px)', resize: 'none', fontFamily: 'monospace', fontSize: '1em', + backgroundColor: 'transparent', + borderRadius: 4, + outline: 'none', }, dropzone: { marginTop: 20, @@ -40,8 +43,9 @@ const styles: Record = { borderColor: '#17cd02', }, icon: { - height: '30%', - width: '30%', + height: '80%', + width: '80%', + opacity: 0.3, color: '#eeeeee', position: 'absolute', top: '50%', @@ -74,6 +78,7 @@ const styles: Record = { interface DialogImportProps { onClose: (text?: string) => void; + themeType: ThemeType; } interface DialogImportState { @@ -183,7 +188,11 @@ class DialogImport extends React.Component