From f4a015d9b19a8765ce6daca16a7b8694c794a8d6 Mon Sep 17 00:00:00 2001 From: savindi7 Date: Wed, 18 Dec 2024 15:42:21 +0530 Subject: [PATCH 1/8] Add build script to convert css files into RTL --- modules/theme/package.json | 1 + modules/theme/scripts/build.js | 20 +++- pnpm-lock.yaml | 212 +++++++++++++++++---------------- 3 files changed, 131 insertions(+), 102 deletions(-) diff --git a/modules/theme/package.json b/modules/theme/package.json index b709d8f58d4..88464e78060 100644 --- a/modules/theme/package.json +++ b/modules/theme/package.json @@ -51,6 +51,7 @@ "rc-tree": "^4.0.0-beta.2", "replace": "^1.1.5", "rimraf": "^3.0.2", + "rtlcss": "^4.3.0", "semantic-ui-css": "^2.4.1", "semantic-ui-less": "^2.4.1", "ts-jest": "^29.1.2", diff --git a/modules/theme/scripts/build.js b/modules/theme/scripts/build.js index 4d3e86a8834..05aaea972ca 100644 --- a/modules/theme/scripts/build.js +++ b/modules/theme/scripts/build.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2020, WSO2 LLC. (https://www.wso2.com). All Rights Reserved. + * Copyright (c) 2020, WSO2 LLC. (https://www.wso2.com). * * WSO2 LLC. licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file except @@ -25,6 +25,7 @@ const fs = require("fs-extra"); const lessToJson = require("less-to-json"); const mergeFiles = require("merge-files"); const replace = require("replace"); +const rtlcss = require("rtlcss"); const { Theme } = require("../src/theme"); /** @@ -147,6 +148,16 @@ const writeFile = (theme, file, content) => { log.info(theme + "/" + "theme" + file + " generated."); }; +/** + * Generates RTL CSS files using rtlcss. + * + * @param {string} ltrCss - LTR CSS content. + * @returns {string} RTL-compatible CSS content. + */ +const generateRTLCSS = (ltrCss) => { + return rtlcss.process(ltrCss); +}; + /* * Copy semantic.js files to each theme to make them self contained * @@ -253,10 +264,15 @@ const generateThemes = () => { return Theme.compile(themeIndexFile, {}).then((output) => { const minifiedOutput = new CleanCSS().minify(output.css); + const rtlCSS = generateRTLCSS(output.css); // Generate RTL CSS + const rtlMinCSS = new CleanCSS().minify(rtlCSS); // Minify RTL CSS + const files = { ".css": output.css, ".css.map": output.map, - ".min.css": minifiedOutput.styles + ".min.css": minifiedOutput.styles, + ".rtl.css": rtlCSS, + ".rtl.min.css": rtlMinCSS.styles }; Object.keys(files).map((key) => { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 421d1c3ad1d..c47baa64a26 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -21042,6 +21042,9 @@ importers: rimraf: specifier: ^3.0.2 version: 3.0.2 + rtlcss: + specifier: ^4.3.0 + version: 4.3.0 semantic-ui-css: specifier: ^2.4.1 version: 2.5.0 @@ -21251,10 +21254,10 @@ packages: '@babel/helpers': 7.26.0 '@babel/parser': 7.26.2 '@babel/template': 7.25.9 - '@babel/traverse': 7.25.9 + '@babel/traverse': 7.25.9(supports-color@5.5.0) '@babel/types': 7.26.0 convert-source-map: 1.9.0 - debug: 4.3.7(supports-color@6.1.0) + debug: 4.3.7(supports-color@5.5.0) gensync: 1.0.0-beta.2 json5: 2.2.3 lodash: 4.17.21 @@ -21276,10 +21279,10 @@ packages: '@babel/helpers': 7.26.0 '@babel/parser': 7.26.2 '@babel/template': 7.25.9 - '@babel/traverse': 7.25.9 + '@babel/traverse': 7.25.9(supports-color@5.5.0) '@babel/types': 7.26.0 convert-source-map: 2.0.0 - debug: 4.3.7(supports-color@6.1.0) + debug: 4.3.7(supports-color@5.5.0) gensync: 1.0.0-beta.2 json5: 2.2.3 semver: 6.3.1 @@ -21306,7 +21309,7 @@ packages: resolution: {integrity: sha512-C47lC7LIDCnz0h4vai/tpNOI95tCd5ZT3iBt/DBH5lXKHZsyNQv18yf1wIIg2ntiQNgmAvA+DgZ82iW8Qdym8g==} engines: {node: '>=6.9.0'} dependencies: - '@babel/traverse': 7.25.9 + '@babel/traverse': 7.25.9(supports-color@5.5.0) '@babel/types': 7.26.0 transitivePeerDependencies: - supports-color @@ -21333,7 +21336,7 @@ packages: '@babel/helper-optimise-call-expression': 7.25.9 '@babel/helper-replace-supers': 7.25.9(@babel/core@7.26.0) '@babel/helper-skip-transparent-expression-wrappers': 7.25.9 - '@babel/traverse': 7.25.9 + '@babel/traverse': 7.25.9(supports-color@5.5.0) semver: 6.3.1 transitivePeerDependencies: - supports-color @@ -21356,10 +21359,10 @@ packages: dependencies: '@babel/core': 7.26.0 '@babel/helper-compilation-targets': 7.25.9 - '@babel/helper-module-imports': 7.25.9 + '@babel/helper-module-imports': 7.25.9(supports-color@5.5.0) '@babel/helper-plugin-utils': 7.25.9 - '@babel/traverse': 7.25.9 - debug: 4.3.7(supports-color@6.1.0) + '@babel/traverse': 7.25.9(supports-color@5.5.0) + debug: 4.3.7(supports-color@5.5.0) lodash.debounce: 4.0.8 resolve: 1.22.8 semver: 6.3.1 @@ -21374,7 +21377,7 @@ packages: '@babel/core': 7.26.0 '@babel/helper-compilation-targets': 7.25.9 '@babel/helper-plugin-utils': 7.25.9 - debug: 4.3.7(supports-color@6.1.0) + debug: 4.3.7(supports-color@5.5.0) lodash.debounce: 4.0.8 resolve: 1.22.8 transitivePeerDependencies: @@ -21384,16 +21387,7 @@ packages: resolution: {integrity: sha512-wbfdZ9w5vk0C0oyHqAJbc62+vet5prjj01jjJ8sKn3j9h3MQQlflEdXYvuqRWjHnM12coDEqiC1IRCi0U/EKwQ==} engines: {node: '>=6.9.0'} dependencies: - '@babel/traverse': 7.25.9 - '@babel/types': 7.26.0 - transitivePeerDependencies: - - supports-color - - /@babel/helper-module-imports@7.25.9: - resolution: {integrity: sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/traverse': 7.25.9 + '@babel/traverse': 7.25.9(supports-color@5.5.0) '@babel/types': 7.26.0 transitivePeerDependencies: - supports-color @@ -21406,7 +21400,6 @@ packages: '@babel/types': 7.26.0 transitivePeerDependencies: - supports-color - dev: false /@babel/helper-module-transforms@7.26.0(@babel/core@7.12.9): resolution: {integrity: sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==} @@ -21415,9 +21408,9 @@ packages: '@babel/core': ^7.0.0 dependencies: '@babel/core': 7.12.9 - '@babel/helper-module-imports': 7.25.9 + '@babel/helper-module-imports': 7.25.9(supports-color@5.5.0) '@babel/helper-validator-identifier': 7.25.9 - '@babel/traverse': 7.25.9 + '@babel/traverse': 7.25.9(supports-color@5.5.0) transitivePeerDependencies: - supports-color @@ -21428,9 +21421,9 @@ packages: '@babel/core': ^7.0.0 dependencies: '@babel/core': 7.26.0 - '@babel/helper-module-imports': 7.25.9 + '@babel/helper-module-imports': 7.25.9(supports-color@5.5.0) '@babel/helper-validator-identifier': 7.25.9 - '@babel/traverse': 7.25.9 + '@babel/traverse': 7.25.9(supports-color@5.5.0) transitivePeerDependencies: - supports-color @@ -21456,7 +21449,7 @@ packages: '@babel/core': 7.26.0 '@babel/helper-annotate-as-pure': 7.25.9 '@babel/helper-wrap-function': 7.25.9 - '@babel/traverse': 7.25.9 + '@babel/traverse': 7.25.9(supports-color@5.5.0) transitivePeerDependencies: - supports-color @@ -21469,7 +21462,7 @@ packages: '@babel/core': 7.26.0 '@babel/helper-member-expression-to-functions': 7.25.9 '@babel/helper-optimise-call-expression': 7.25.9 - '@babel/traverse': 7.25.9 + '@babel/traverse': 7.25.9(supports-color@5.5.0) transitivePeerDependencies: - supports-color @@ -21477,7 +21470,7 @@ packages: resolution: {integrity: sha512-c6WHXuiaRsJTyHYLJV75t9IqsmTbItYfdj99PnzYGQZkYKvan5/2jKJ7gu31J3/BJ/A18grImSPModuyG/Eo0Q==} engines: {node: '>=6.9.0'} dependencies: - '@babel/traverse': 7.25.9 + '@babel/traverse': 7.25.9(supports-color@5.5.0) '@babel/types': 7.26.0 transitivePeerDependencies: - supports-color @@ -21486,7 +21479,7 @@ packages: resolution: {integrity: sha512-K4Du3BFa3gvyhzgPcntrkDgZzQaq6uozzcpGbOO1OEJaI+EJdqWIMTLgFgQf6lrfiDFo5FU+BxKepI9RmZqahA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/traverse': 7.25.9 + '@babel/traverse': 7.25.9(supports-color@5.5.0) '@babel/types': 7.26.0 transitivePeerDependencies: - supports-color @@ -21508,7 +21501,7 @@ packages: engines: {node: '>=6.9.0'} dependencies: '@babel/template': 7.25.9 - '@babel/traverse': 7.25.9 + '@babel/traverse': 7.25.9(supports-color@5.5.0) '@babel/types': 7.26.0 transitivePeerDependencies: - supports-color @@ -21545,7 +21538,7 @@ packages: dependencies: '@babel/core': 7.26.0 '@babel/helper-plugin-utils': 7.25.9 - '@babel/traverse': 7.25.9 + '@babel/traverse': 7.25.9(supports-color@5.5.0) transitivePeerDependencies: - supports-color @@ -21588,7 +21581,7 @@ packages: dependencies: '@babel/core': 7.26.0 '@babel/helper-plugin-utils': 7.25.9 - '@babel/traverse': 7.25.9 + '@babel/traverse': 7.25.9(supports-color@5.5.0) transitivePeerDependencies: - supports-color @@ -21934,7 +21927,7 @@ packages: '@babel/core': 7.26.0 '@babel/helper-plugin-utils': 7.25.9 '@babel/helper-remap-async-to-generator': 7.25.9(@babel/core@7.26.0) - '@babel/traverse': 7.25.9 + '@babel/traverse': 7.25.9(supports-color@5.5.0) transitivePeerDependencies: - supports-color @@ -21945,7 +21938,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.26.0 - '@babel/helper-module-imports': 7.25.9 + '@babel/helper-module-imports': 7.25.9(supports-color@5.5.0) '@babel/helper-plugin-utils': 7.25.9 '@babel/helper-remap-async-to-generator': 7.25.9(@babel/core@7.26.0) transitivePeerDependencies: @@ -22004,7 +21997,7 @@ packages: '@babel/helper-compilation-targets': 7.25.9 '@babel/helper-plugin-utils': 7.25.9 '@babel/helper-replace-supers': 7.25.9(@babel/core@7.26.0) - '@babel/traverse': 7.25.9 + '@babel/traverse': 7.25.9(supports-color@5.5.0) globals: 11.12.0 transitivePeerDependencies: - supports-color @@ -22118,7 +22111,7 @@ packages: '@babel/core': 7.26.0 '@babel/helper-compilation-targets': 7.25.9 '@babel/helper-plugin-utils': 7.25.9 - '@babel/traverse': 7.25.9 + '@babel/traverse': 7.25.9(supports-color@5.5.0) transitivePeerDependencies: - supports-color @@ -22193,7 +22186,7 @@ packages: '@babel/helper-module-transforms': 7.26.0(@babel/core@7.26.0) '@babel/helper-plugin-utils': 7.25.9 '@babel/helper-validator-identifier': 7.25.9 - '@babel/traverse': 7.25.9 + '@babel/traverse': 7.25.9(supports-color@5.5.0) transitivePeerDependencies: - supports-color @@ -22379,7 +22372,7 @@ packages: dependencies: '@babel/core': 7.26.0 '@babel/helper-annotate-as-pure': 7.25.9 - '@babel/helper-module-imports': 7.25.9 + '@babel/helper-module-imports': 7.25.9(supports-color@5.5.0) '@babel/helper-plugin-utils': 7.25.9 '@babel/plugin-syntax-jsx': 7.25.9(@babel/core@7.26.0) '@babel/types': 7.26.0 @@ -22432,7 +22425,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.26.0 - '@babel/helper-module-imports': 7.25.9 + '@babel/helper-module-imports': 7.25.9(supports-color@5.5.0) '@babel/helper-plugin-utils': 7.25.9 babel-plugin-polyfill-corejs2: 0.4.11(@babel/core@7.26.0) babel-plugin-polyfill-corejs3: 0.10.6(@babel/core@7.26.0) @@ -22716,20 +22709,6 @@ packages: '@babel/parser': 7.26.2 '@babel/types': 7.26.0 - /@babel/traverse@7.25.9: - resolution: {integrity: sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/code-frame': 7.26.2 - '@babel/generator': 7.26.2 - '@babel/parser': 7.26.2 - '@babel/template': 7.25.9 - '@babel/types': 7.26.0 - debug: 4.3.7(supports-color@6.1.0) - globals: 11.12.0 - transitivePeerDependencies: - - supports-color - /@babel/traverse@7.25.9(supports-color@5.5.0): resolution: {integrity: sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw==} engines: {node: '>=6.9.0'} @@ -22743,7 +22722,6 @@ packages: globals: 11.12.0 transitivePeerDependencies: - supports-color - dev: false /@babel/types@7.26.0: resolution: {integrity: sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==} @@ -22993,7 +22971,7 @@ packages: /@emotion/babel-plugin@11.12.0: resolution: {integrity: sha512-y2WQb+oP8Jqvvclh8Q55gLUyb7UFvgv7eJfsj7td5TToBrIUtPay2kMrZi4xjq9qw2vD0ZR5fSho0yqoFgX7Rw==} dependencies: - '@babel/helper-module-imports': 7.25.9 + '@babel/helper-module-imports': 7.25.9(supports-color@5.5.0) '@babel/runtime': 7.26.0 '@emotion/hash': 0.9.2 '@emotion/memoize': 0.9.0 @@ -23330,7 +23308,7 @@ packages: engines: {node: ^10.12.0 || >=12.0.0} dependencies: ajv: 6.12.6 - debug: 4.3.7(supports-color@6.1.0) + debug: 4.3.7(supports-color@5.5.0) espree: 7.3.1 globals: 13.24.0 ignore: 4.0.6 @@ -23347,7 +23325,7 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: ajv: 6.12.6 - debug: 4.3.7(supports-color@6.1.0) + debug: 4.3.7(supports-color@5.5.0) espree: 9.6.1 globals: 13.24.0 ignore: 5.3.2 @@ -23416,7 +23394,7 @@ packages: deprecated: Use @eslint/config-array instead dependencies: '@humanwhocodes/object-schema': 2.0.3 - debug: 4.3.7(supports-color@6.1.0) + debug: 4.3.7(supports-color@5.5.0) minimatch: 3.1.2 transitivePeerDependencies: - supports-color @@ -23427,7 +23405,7 @@ packages: deprecated: Use @eslint/config-array instead dependencies: '@humanwhocodes/object-schema': 1.2.1 - debug: 4.3.7(supports-color@6.1.0) + debug: 4.3.7(supports-color@5.5.0) minimatch: 3.1.2 transitivePeerDependencies: - supports-color @@ -24984,7 +24962,7 @@ packages: dependencies: '@open-draft/until': 1.0.3 '@xmldom/xmldom': 0.7.13 - debug: 4.3.7(supports-color@6.1.0) + debug: 4.3.7(supports-color@5.5.0) headers-utils: 3.0.2 outvariant: 1.4.3 strict-event-emitter: 0.2.8 @@ -26997,7 +26975,7 @@ packages: optional: true dependencies: '@babel/core': 7.26.0 - '@babel/helper-module-imports': 7.25.9 + '@babel/helper-module-imports': 7.25.9(supports-color@5.5.0) '@rollup/pluginutils': 3.1.0(rollup@2.79.2) rollup: 2.79.2 transitivePeerDependencies: @@ -28566,7 +28544,7 @@ packages: '@babel/parser': 7.26.2 '@babel/plugin-transform-react-jsx': 7.25.9(@babel/core@7.26.0) '@babel/preset-env': 7.26.0(@babel/core@7.26.0) - '@babel/traverse': 7.25.9 + '@babel/traverse': 7.25.9(supports-color@5.5.0) '@babel/types': 7.26.0 '@storybook/csf': 0.0.2--canary.4566f4d.1 '@storybook/mdx1-csf': 0.0.1(@babel/core@7.26.0) @@ -28584,7 +28562,7 @@ packages: dependencies: '@babel/generator': 7.26.2 '@babel/parser': 7.26.2 - '@babel/traverse': 7.25.9 + '@babel/traverse': 7.25.9(supports-color@5.5.0) '@babel/types': 7.26.0 '@storybook/csf': 0.1.11 '@storybook/types': 7.6.9 @@ -28904,7 +28882,7 @@ packages: typescript: '>= 3.x' webpack: 5.84.1 dependencies: - debug: 4.3.7(supports-color@6.1.0) + debug: 4.3.7(supports-color@5.5.0) endent: 2.1.0 find-cache-dir: 3.3.2 flat-cache: 3.2.0 @@ -28923,7 +28901,7 @@ packages: typescript: '>= 4.x' webpack: 5.84.1 dependencies: - debug: 4.3.7(supports-color@6.1.0) + debug: 4.3.7(supports-color@5.5.0) endent: 2.1.0 find-cache-dir: 3.3.2 flat-cache: 3.2.0 @@ -29801,7 +29779,7 @@ packages: '@swc-node/sourcemap-support': 0.3.0 '@swc/core': 1.3.99(@swc/helpers@0.5.9) colorette: 2.0.20 - debug: 4.3.7(supports-color@6.1.0) + debug: 4.3.7(supports-color@5.5.0) pirates: 4.0.6 tslib: 2.8.0 typescript: 5.1.6 @@ -30985,7 +30963,7 @@ packages: '@typescript-eslint/type-utils': 6.5.0(eslint@7.32.0)(typescript@5.1.6) '@typescript-eslint/utils': 6.5.0(eslint@7.32.0)(typescript@5.1.6) '@typescript-eslint/visitor-keys': 6.5.0 - debug: 4.3.7(supports-color@6.1.0) + debug: 4.3.7(supports-color@5.5.0) eslint: 7.32.0 graphemer: 1.4.0 ignore: 5.3.2 @@ -31014,7 +30992,7 @@ packages: '@typescript-eslint/type-utils': 6.5.0(eslint@8.46.0)(typescript@4.9.5) '@typescript-eslint/utils': 6.5.0(eslint@8.46.0)(typescript@4.9.5) '@typescript-eslint/visitor-keys': 6.5.0 - debug: 4.3.7(supports-color@6.1.0) + debug: 4.3.7(supports-color@5.5.0) eslint: 8.46.0 graphemer: 1.4.0 ignore: 5.3.2 @@ -31040,7 +31018,7 @@ packages: '@typescript-eslint/types': 6.5.0 '@typescript-eslint/typescript-estree': 6.5.0(typescript@5.1.6) '@typescript-eslint/visitor-keys': 6.5.0 - debug: 4.3.7(supports-color@6.1.0) + debug: 4.3.7(supports-color@5.5.0) eslint: 7.32.0 typescript: 5.1.6 transitivePeerDependencies: @@ -31061,7 +31039,7 @@ packages: '@typescript-eslint/types': 6.5.0 '@typescript-eslint/typescript-estree': 6.5.0(typescript@4.9.5) '@typescript-eslint/visitor-keys': 6.5.0 - debug: 4.3.7(supports-color@6.1.0) + debug: 4.3.7(supports-color@5.5.0) eslint: 8.46.0 typescript: 4.9.5 transitivePeerDependencies: @@ -31096,7 +31074,7 @@ packages: dependencies: '@typescript-eslint/typescript-estree': 6.5.0(typescript@5.1.6) '@typescript-eslint/utils': 6.5.0(eslint@7.32.0)(typescript@5.1.6) - debug: 4.3.7(supports-color@6.1.0) + debug: 4.3.7(supports-color@5.5.0) eslint: 7.32.0 ts-api-utils: 1.4.0(typescript@5.1.6) typescript: 5.1.6 @@ -31116,7 +31094,7 @@ packages: dependencies: '@typescript-eslint/typescript-estree': 6.5.0(typescript@4.9.5) '@typescript-eslint/utils': 6.5.0(eslint@8.46.0)(typescript@4.9.5) - debug: 4.3.7(supports-color@6.1.0) + debug: 4.3.7(supports-color@5.5.0) eslint: 8.46.0 ts-api-utils: 1.4.0(typescript@4.9.5) typescript: 4.9.5 @@ -31145,7 +31123,7 @@ packages: dependencies: '@typescript-eslint/types': 5.62.0 '@typescript-eslint/visitor-keys': 5.62.0 - debug: 4.3.7(supports-color@6.1.0) + debug: 4.3.7(supports-color@5.5.0) globby: 11.1.0 is-glob: 4.0.3 semver: 7.6.3 @@ -31166,7 +31144,7 @@ packages: dependencies: '@typescript-eslint/types': 6.5.0 '@typescript-eslint/visitor-keys': 6.5.0 - debug: 4.3.7(supports-color@6.1.0) + debug: 4.3.7(supports-color@5.5.0) globby: 11.1.0 is-glob: 4.0.3 semver: 7.6.3 @@ -31187,7 +31165,7 @@ packages: dependencies: '@typescript-eslint/types': 6.5.0 '@typescript-eslint/visitor-keys': 6.5.0 - debug: 4.3.7(supports-color@6.1.0) + debug: 4.3.7(supports-color@5.5.0) globby: 11.1.0 is-glob: 4.0.3 semver: 7.6.3 @@ -31567,7 +31545,7 @@ packages: resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} engines: {node: '>= 6.0.0'} dependencies: - debug: 4.3.7(supports-color@6.1.0) + debug: 4.3.7(supports-color@5.5.0) transitivePeerDependencies: - supports-color dev: true @@ -32318,7 +32296,7 @@ packages: '@babel/core': 7.26.0 '@babel/helper-plugin-utils': 7.25.9 '@babel/plugin-syntax-typescript': 7.25.9(@babel/core@7.26.0) - '@babel/traverse': 7.25.9 + '@babel/traverse': 7.25.9(supports-color@5.5.0) transitivePeerDependencies: - supports-color dev: true @@ -34677,7 +34655,6 @@ packages: dependencies: ms: 2.1.3 supports-color: 5.5.0 - dev: false /debug@4.3.7(supports-color@6.1.0): resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==} @@ -35000,7 +34977,7 @@ packages: hasBin: true dependencies: address: 1.2.2 - debug: 4.3.7(supports-color@6.1.0) + debug: 4.3.7(supports-color@5.5.0) transitivePeerDependencies: - supports-color @@ -35569,7 +35546,7 @@ packages: peerDependencies: esbuild: '>=0.12 <1' dependencies: - debug: 4.3.7(supports-color@6.1.0) + debug: 4.3.7(supports-color@5.5.0) esbuild: 0.18.20 transitivePeerDependencies: - supports-color @@ -36060,7 +36037,7 @@ packages: ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.3 - debug: 4.3.7(supports-color@6.1.0) + debug: 4.3.7(supports-color@5.5.0) doctrine: 3.0.0 enquirer: 2.4.1 escape-string-regexp: 4.0.0 @@ -36114,7 +36091,7 @@ packages: ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.3 - debug: 4.3.7(supports-color@6.1.0) + debug: 4.3.7(supports-color@5.5.0) doctrine: 3.0.0 escape-string-regexp: 4.0.0 eslint-scope: 7.2.2 @@ -36200,7 +36177,7 @@ packages: resolution: {integrity: sha512-YNF+mZ/Wu2FU/gvmzuWtYc8rloubL7wfXCTgouFrnjGVXPA/EeYYA7pupXWrb3Iv1cTBeSSxxJIbK23l4MRNqg==} engines: {node: '>=8.3.0'} dependencies: - '@babel/traverse': 7.25.9 + '@babel/traverse': 7.25.9(supports-color@5.5.0) '@babel/types': 7.26.0 c8: 7.14.0 transitivePeerDependencies: @@ -38179,7 +38156,7 @@ packages: dependencies: '@tootallnate/once': 1.1.2 agent-base: 6.0.2 - debug: 4.3.7(supports-color@6.1.0) + debug: 4.3.7(supports-color@5.5.0) transitivePeerDependencies: - supports-color dev: true @@ -38190,7 +38167,7 @@ packages: dependencies: '@tootallnate/once': 2.0.0 agent-base: 6.0.2 - debug: 4.3.7(supports-color@6.1.0) + debug: 4.3.7(supports-color@5.5.0) transitivePeerDependencies: - supports-color dev: true @@ -38272,7 +38249,7 @@ packages: engines: {node: '>= 6.0.0'} dependencies: agent-base: 5.1.1 - debug: 4.3.7(supports-color@6.1.0) + debug: 4.3.7(supports-color@5.5.0) transitivePeerDependencies: - supports-color @@ -38281,7 +38258,7 @@ packages: engines: {node: '>= 6'} dependencies: agent-base: 6.0.2 - debug: 4.3.7(supports-color@6.1.0) + debug: 4.3.7(supports-color@5.5.0) transitivePeerDependencies: - supports-color dev: true @@ -39226,7 +39203,7 @@ packages: resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==} engines: {node: '>=10'} dependencies: - debug: 4.3.7(supports-color@6.1.0) + debug: 4.3.7(supports-color@5.5.0) istanbul-lib-coverage: 3.2.2 source-map: 0.6.1 transitivePeerDependencies: @@ -39703,7 +39680,7 @@ packages: resolution: {integrity: sha512-kPKUrQtc8aYwBV7CqBg5pu+tmYXlvFlSFYn18ev4gPFtrRzB15N2gW/Roew3187q2w2eHuu0MU9TJz6w0/nPEg==} engines: {node: '>= 10.14.2'} dependencies: - '@babel/traverse': 7.25.9 + '@babel/traverse': 7.25.9(supports-color@5.5.0) '@jest/environment': 26.6.2 '@jest/source-map': 26.6.2 '@jest/test-result': 26.6.2 @@ -40917,8 +40894,6 @@ packages: peerDependenciesMeta: webpack: optional: true - webpack-sources: - optional: true dependencies: webpack: 5.84.1(@swc/core@1.3.99)(esbuild@0.18.20)(webpack-cli@4.10.0) webpack-sources: 3.2.3 @@ -41128,7 +41103,7 @@ packages: deprecated: 4.x is no longer supported. Please upgrade to 6.x or higher. dependencies: date-format: 2.1.0 - debug: 4.3.7(supports-color@6.1.0) + debug: 4.3.7(supports-color@5.5.0) flatted: 2.0.2 rfdc: 1.4.1 streamroller: 1.0.6 @@ -41762,7 +41737,7 @@ packages: resolution: {integrity: sha512-o/sd0nMof8kYff+TqcDx3VSrgBTcZpSvYcAHIfHhv5VAuNmisCxjhx6YmxS8PFEpb9z5WKWKPdzf0jM23ro3RQ==} dependencies: '@types/debug': 4.1.12 - debug: 4.3.7(supports-color@6.1.0) + debug: 4.3.7(supports-color@5.5.0) decode-named-character-reference: 1.0.2 devlop: 1.1.0 micromark-core-commonmark: 2.0.1 @@ -44649,7 +44624,7 @@ packages: engines: {node: '>=8.16.0'} dependencies: '@types/mime-types': 2.1.4 - debug: 4.3.7(supports-color@6.1.0) + debug: 4.3.7(supports-color@5.5.0) extract-zip: 1.7.0 https-proxy-agent: 4.0.0 mime: 2.6.0 @@ -44951,7 +44926,7 @@ packages: engines: {node: '>=16.14.0'} dependencies: '@babel/core': 7.26.0 - '@babel/traverse': 7.25.9 + '@babel/traverse': 7.25.9(supports-color@5.5.0) '@babel/types': 7.26.0 '@types/babel__core': 7.20.5 '@types/babel__traverse': 7.20.6 @@ -46320,6 +46295,17 @@ packages: resolution: {integrity: sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==} engines: {node: 6.* || >= 7.*} + /rtlcss@4.3.0: + resolution: {integrity: sha512-FI+pHEn7Wc4NqKXMXFM+VAYKEj/mRIcW4h24YVwVtyjI+EqGrLc2Hx/Ny0lrZ21cBWU2goLy36eqMcNj3AQJig==} + engines: {node: '>=12.0.0'} + hasBin: true + dependencies: + escalade: 3.2.0 + picocolors: 1.1.1 + postcss: 8.4.47 + strip-json-comments: 3.1.1 + dev: true + /run-async@2.4.1: resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==} engines: {node: '>=0.12.0'} @@ -46818,7 +46804,7 @@ packages: /simple-git@1.132.0: resolution: {integrity: sha512-xauHm1YqCTom1sC9eOjfq3/9RKiUA9iPnxBbrY2DdL8l4ADMu0jjM5l5lphQP5YWNqAL2aXC/OeuQ76vHtW5fg==} dependencies: - debug: 4.3.7(supports-color@6.1.0) + debug: 4.3.7(supports-color@5.5.0) transitivePeerDependencies: - supports-color dev: true @@ -46935,7 +46921,7 @@ packages: engines: {node: '>= 10'} dependencies: agent-base: 6.0.2 - debug: 4.3.7(supports-color@6.1.0) + debug: 4.3.7(supports-color@5.5.0) socks: 2.8.3 transitivePeerDependencies: - supports-color @@ -47104,6 +47090,19 @@ packages: /spdx-license-ids@3.0.20: resolution: {integrity: sha512-jg25NiDV/1fLtSgEgyvVyDunvaNHbuwF9lfNV17gSmPFAlYzdfNBlLtLzXTevwkPj7DhGbmN9VnmJIgLnhvaBw==} + /spdy-transport@3.0.0: + resolution: {integrity: sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==} + dependencies: + debug: 4.3.7(supports-color@5.5.0) + detect-node: 2.1.0 + hpack.js: 2.1.6 + obuf: 1.1.2 + readable-stream: 3.6.2 + wbuf: 1.7.3 + transitivePeerDependencies: + - supports-color + dev: true + /spdy-transport@3.0.0(supports-color@6.1.0): resolution: {integrity: sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==} dependencies: @@ -47116,6 +47115,19 @@ packages: transitivePeerDependencies: - supports-color + /spdy@4.0.2: + resolution: {integrity: sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==} + engines: {node: '>=6.0.0'} + dependencies: + debug: 4.3.7(supports-color@5.5.0) + handle-thing: 2.0.1 + http-deceiver: 1.2.7 + select-hose: 2.0.0 + spdy-transport: 3.0.0 + transitivePeerDependencies: + - supports-color + dev: true + /spdy@4.0.2(supports-color@6.1.0): resolution: {integrity: sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==} engines: {node: '>=6.0.0'} @@ -47669,7 +47681,7 @@ packages: hasBin: true dependencies: '@adobe/css-tools': 4.4.0 - debug: 4.3.7(supports-color@6.1.0) + debug: 4.3.7(supports-color@5.5.0) glob: 7.2.3 sax: 1.2.4 source-map: 0.7.4 @@ -48338,7 +48350,7 @@ packages: bs-logger: 0.2.6 esbuild: 0.18.20 fast-json-stable-stringify: 2.1.0 - jest: 29.7.0(@types/node@13.13.52)(ts-node@8.10.2) + jest: 29.7.0(@types/node@18.11.9) jest-util: 29.7.0 json5: 2.2.3 lodash.memoize: 4.1.2 @@ -49457,7 +49469,7 @@ packages: selfsigned: 2.4.1 serve-index: 1.9.1(supports-color@6.1.0) sockjs: 0.3.24 - spdy: 4.0.2(supports-color@6.1.0) + spdy: 4.0.2 webpack: 5.84.1(@swc/core@1.3.99)(esbuild@0.18.20)(webpack-cli@4.10.0) webpack-cli: 4.10.0(webpack-bundle-analyzer@4.10.2)(webpack-dev-server@3.11.3)(webpack@5.84.1) webpack-dev-middleware: 5.3.4(webpack@5.84.1) From 1699288032271909f28f0df8501c873a73966826 Mon Sep 17 00:00:00 2001 From: savindi7 Date: Fri, 3 Jan 2025 17:29:54 +0530 Subject: [PATCH 2/8] Update theme selection logic based on language direction --- .../main/resources/LanguageOptions.properties | 3 +- .../src/main/webapp/includes/header.jsp | 64 ++++++++++++++++++- .../main/resources/LanguageOptions.properties | 3 +- .../src/main/webapp/includes/header.jsp | 63 +++++++++++++++++- 4 files changed, 128 insertions(+), 5 deletions(-) diff --git a/identity-apps-core/apps/authentication-portal/src/main/resources/LanguageOptions.properties b/identity-apps-core/apps/authentication-portal/src/main/resources/LanguageOptions.properties index 838b3e4ddd5..e4e7fd5235a 100644 --- a/identity-apps-core/apps/authentication-portal/src/main/resources/LanguageOptions.properties +++ b/identity-apps-core/apps/authentication-portal/src/main/resources/LanguageOptions.properties @@ -19,7 +19,8 @@ # -------------------------------------------------------------------------------------- # This file contains the language switcher configurations -# The format of the file is =, +# The format of the file is =,,text direction(rtl/ltr) +# The default text direction is set to "ltr". lang.switch.en_US=us,English - United States lang.switch.fr_FR=fr,Français - France lang.switch.es_ES=es,Español - España diff --git a/identity-apps-core/apps/authentication-portal/src/main/webapp/includes/header.jsp b/identity-apps-core/apps/authentication-portal/src/main/webapp/includes/header.jsp index 2e119c677d7..4f8299c4219 100644 --- a/identity-apps-core/apps/authentication-portal/src/main/webapp/includes/header.jsp +++ b/identity-apps-core/apps/authentication-portal/src/main/webapp/includes/header.jsp @@ -19,6 +19,8 @@ <%@ page import="org.apache.commons.text.StringEscapeUtils" %> <%@ page import="org.wso2.carbon.identity.application.authentication.endpoint.util.AuthenticationEndpointUtil" %> <%@ page import="java.io.File" %> +<%@ page import="java.io.BufferedReader" %> +<%@ page import="java.io.FileReader" %> <%-- Include tenant context --%> @@ -29,18 +31,72 @@ <%-- Branding Preferences --%> - <%-- Extract the name of the stylesheet--%> <% String themeName = "wso2is"; + String language = "en"; // Default language + Cookie[] userCookies = request.getCookies(); + if (userCookies != null) { + for (Cookie cookie : userCookies) { + if ("ui_lang".equals(cookie.getName())) { + language = cookie.getValue(); + break; + } + } + } + + // Specify the file path + String filePath = application.getRealPath("/") + "/WEB-INF/classes/LanguageOptions.properties"; + + // Create a Map to store the language direction + Map languageDirectionMap = new HashMap<>(); + + // Use a BufferedReader to read the file content + try (BufferedReader bufferedReader = new BufferedReader(new FileReader(filePath))) { + String line; + while ((line = bufferedReader.readLine()) != null) { + // Ignore comments and empty lines + if (!line.trim().startsWith("#") && !line.trim().isEmpty()) { + // Split the line into key and value using '=' + String[] keyValue = line.split("="); + if (keyValue.length == 2) { // Ensure valid format + // Extract the language code from the key + String[] keyParts = keyValue[0].split("\\."); + String languageCode = keyParts[keyParts.length - 1]; + + // Split the value into components (languageCode, languageName, direction) + String[] valueParts = keyValue[1].split(","); + if (valueParts.length >= 3) { // Ensure the value has at least 3 parts + String direction = valueParts[2].trim(); + languageDirectionMap.put(languageCode, direction); + } else { + languageDirectionMap.put(languageCode, "ltr"); // Default to LTR if direction is missing + } + } + } + } + } catch (Exception e) { + throw e; + } + + // Get the current language's direction + String direction = languageDirectionMap.getOrDefault(language, "ltr"); + out.write(""); + + String themeSuffix = ""; + if ("rtl".equals(languageDirectionMap.get(language))) { + themeSuffix = ".rtl"; + } + File themeDir = new File(request.getSession().getServletContext().getRealPath("/") + "/" + "libs/themes/" + themeName + "/"); String[] fileNames = themeDir.list(); String themeFileName = ""; for(String file: fileNames) { - if(file.endsWith("min.css")) { + if(file.endsWith(themeSuffix + ".min.css")) { themeFileName = file; + break; } } %> @@ -109,3 +165,7 @@ } } + + diff --git a/identity-apps-core/apps/recovery-portal/src/main/resources/LanguageOptions.properties b/identity-apps-core/apps/recovery-portal/src/main/resources/LanguageOptions.properties index 838b3e4ddd5..e4e7fd5235a 100644 --- a/identity-apps-core/apps/recovery-portal/src/main/resources/LanguageOptions.properties +++ b/identity-apps-core/apps/recovery-portal/src/main/resources/LanguageOptions.properties @@ -19,7 +19,8 @@ # -------------------------------------------------------------------------------------- # This file contains the language switcher configurations -# The format of the file is =, +# The format of the file is =,,text direction(rtl/ltr) +# The default text direction is set to "ltr". lang.switch.en_US=us,English - United States lang.switch.fr_FR=fr,Français - France lang.switch.es_ES=es,Español - España diff --git a/identity-apps-core/apps/recovery-portal/src/main/webapp/includes/header.jsp b/identity-apps-core/apps/recovery-portal/src/main/webapp/includes/header.jsp index 3d060ca40e9..cdecce2f1df 100644 --- a/identity-apps-core/apps/recovery-portal/src/main/webapp/includes/header.jsp +++ b/identity-apps-core/apps/recovery-portal/src/main/webapp/includes/header.jsp @@ -20,6 +20,8 @@ <%@ page import="org.wso2.carbon.identity.mgt.endpoint.util.IdentityManagementEndpointUtil" %> <%@ page import="org.owasp.encoder.Encode" %> <%@ page import="java.io.File" %> +<%@ page import="java.io.BufferedReader" %> +<%@ page import="java.io.FileReader" %> <%-- Localization --%> @@ -33,14 +35,69 @@ <% String themeName = "wso2is"; + String language = "en"; // Default language + Cookie[] userCookies = request.getCookies(); + if (userCookies != null) { + for (Cookie cookie : userCookies) { + if ("ui_lang".equals(cookie.getName())) { + language = cookie.getValue(); + break; + } + } + } + + // Specify the file path + String filePath = application.getRealPath("/") + "/WEB-INF/classes/LanguageOptions.properties"; + + // Create a Map to store the language direction + Map languageDirectionMap = new HashMap<>(); + + // Use a BufferedReader to read the file content + try (BufferedReader bufferedReader = new BufferedReader(new FileReader(filePath))) { + String line; + while ((line = bufferedReader.readLine()) != null) { + // Ignore comments and empty lines + if (!line.trim().startsWith("#") && !line.trim().isEmpty()) { + // Split the line into key and value using '=' + String[] keyValue = line.split("="); + if (keyValue.length == 2) { // Ensure valid format + // Extract the language code from the key + String[] keyParts = keyValue[0].split("\\."); + String languageCode = keyParts[keyParts.length - 1]; + + // Split the value into components (languageCode, languageName, direction) + String[] valueParts = keyValue[1].split(","); + if (valueParts.length >= 3) { // Ensure the value has at least 3 parts + String direction = valueParts[2].trim(); + languageDirectionMap.put(languageCode, direction); + } else { + languageDirectionMap.put(languageCode, "ltr"); // Default to LTR if direction is missing + } + } + } + } + } catch (Exception e) { + throw e; + } + + // Get the current language's direction + String direction = languageDirectionMap.getOrDefault(language, "ltr"); + out.write(""); + + String themeSuffix = ""; + if ("rtl".equals(languageDirectionMap.get(language))) { + themeSuffix = ".rtl"; + } + File themeDir = new File(request.getSession().getServletContext().getRealPath("/") + "/" + "libs/themes/" + themeName + "/"); String[] fileNames = themeDir.list(); String themeFileName = ""; for(String file: fileNames) { - if(file.endsWith("min.css")) { + if(file.endsWith(themeSuffix + ".min.css")) { themeFileName = file; + break; } } %> @@ -96,3 +153,7 @@ <% } %> + + From 2b4f5e240882d86aa2fb38d72b2c90e7941a1a2f Mon Sep 17 00:00:00 2001 From: savindi7 Date: Fri, 3 Jan 2025 22:51:00 +0530 Subject: [PATCH 3/8] Remove redundant code and add null check --- .../src/main/webapp/includes/header.jsp | 8 +++++--- .../recovery-portal/src/main/webapp/includes/header.jsp | 8 +++++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/identity-apps-core/apps/authentication-portal/src/main/webapp/includes/header.jsp b/identity-apps-core/apps/authentication-portal/src/main/webapp/includes/header.jsp index 4f8299c4219..175fc069ecf 100644 --- a/identity-apps-core/apps/authentication-portal/src/main/webapp/includes/header.jsp +++ b/identity-apps-core/apps/authentication-portal/src/main/webapp/includes/header.jsp @@ -81,7 +81,6 @@ // Get the current language's direction String direction = languageDirectionMap.getOrDefault(language, "ltr"); - out.write(""); String themeSuffix = ""; if ("rtl".equals(languageDirectionMap.get(language))) { @@ -166,6 +165,9 @@ } - diff --git a/identity-apps-core/apps/recovery-portal/src/main/webapp/includes/header.jsp b/identity-apps-core/apps/recovery-portal/src/main/webapp/includes/header.jsp index cdecce2f1df..d853cad2ac8 100644 --- a/identity-apps-core/apps/recovery-portal/src/main/webapp/includes/header.jsp +++ b/identity-apps-core/apps/recovery-portal/src/main/webapp/includes/header.jsp @@ -82,7 +82,6 @@ // Get the current language's direction String direction = languageDirectionMap.getOrDefault(language, "ltr"); - out.write(""); String themeSuffix = ""; if ("rtl".equals(languageDirectionMap.get(language))) { @@ -154,6 +153,9 @@ } %> - From 9556875aff180ee4677b0816388dbe05ff09974a Mon Sep 17 00:00:00 2001 From: savindi7 Date: Mon, 6 Jan 2025 13:38:49 +0530 Subject: [PATCH 4/8] Remove redundant comments and update lock file --- .../src/main/webapp/includes/header.jsp | 27 +++++++++-------- .../src/main/webapp/includes/header.jsp | 27 +++++++++-------- pnpm-lock.yaml | 29 ++++++++++++------- 3 files changed, 45 insertions(+), 38 deletions(-) diff --git a/identity-apps-core/apps/authentication-portal/src/main/webapp/includes/header.jsp b/identity-apps-core/apps/authentication-portal/src/main/webapp/includes/header.jsp index 175fc069ecf..8e07ee36da6 100644 --- a/identity-apps-core/apps/authentication-portal/src/main/webapp/includes/header.jsp +++ b/identity-apps-core/apps/authentication-portal/src/main/webapp/includes/header.jsp @@ -34,10 +34,13 @@ <%-- Extract the name of the stylesheet--%> <% String themeName = "wso2is"; - String language = "en"; // Default language + String language = "en"; Cookie[] userCookies = request.getCookies(); + if (userCookies != null) { + for (Cookie cookie : userCookies) { + if ("ui_lang".equals(cookie.getName())) { language = cookie.getValue(); break; @@ -45,32 +48,28 @@ } } - // Specify the file path String filePath = application.getRealPath("/") + "/WEB-INF/classes/LanguageOptions.properties"; - // Create a Map to store the language direction Map languageDirectionMap = new HashMap<>(); - // Use a BufferedReader to read the file content try (BufferedReader bufferedReader = new BufferedReader(new FileReader(filePath))) { String line; + while ((line = bufferedReader.readLine()) != null) { - // Ignore comments and empty lines + if (!line.trim().startsWith("#") && !line.trim().isEmpty()) { - // Split the line into key and value using '=' String[] keyValue = line.split("="); - if (keyValue.length == 2) { // Ensure valid format - // Extract the language code from the key + + if (keyValue.length == 2) { String[] keyParts = keyValue[0].split("\\."); String languageCode = keyParts[keyParts.length - 1]; - - // Split the value into components (languageCode, languageName, direction) String[] valueParts = keyValue[1].split(","); - if (valueParts.length >= 3) { // Ensure the value has at least 3 parts + + if (valueParts.length >= 3) { String direction = valueParts[2].trim(); languageDirectionMap.put(languageCode, direction); } else { - languageDirectionMap.put(languageCode, "ltr"); // Default to LTR if direction is missing + languageDirectionMap.put(languageCode, "ltr"); } } } @@ -79,7 +78,7 @@ throw e; } - // Get the current language's direction + // Get the selected language's direction. String direction = languageDirectionMap.getOrDefault(language, "ltr"); String themeSuffix = ""; @@ -93,7 +92,7 @@ String themeFileName = ""; for(String file: fileNames) { - if(file.endsWith(themeSuffix + ".min.css")) { + if (file.endsWith(themeSuffix + ".min.css")) { themeFileName = file; break; } diff --git a/identity-apps-core/apps/recovery-portal/src/main/webapp/includes/header.jsp b/identity-apps-core/apps/recovery-portal/src/main/webapp/includes/header.jsp index d853cad2ac8..cf7110c8cee 100644 --- a/identity-apps-core/apps/recovery-portal/src/main/webapp/includes/header.jsp +++ b/identity-apps-core/apps/recovery-portal/src/main/webapp/includes/header.jsp @@ -35,10 +35,13 @@ <% String themeName = "wso2is"; - String language = "en"; // Default language + String language = "en"; Cookie[] userCookies = request.getCookies(); + if (userCookies != null) { + for (Cookie cookie : userCookies) { + if ("ui_lang".equals(cookie.getName())) { language = cookie.getValue(); break; @@ -46,32 +49,28 @@ } } - // Specify the file path String filePath = application.getRealPath("/") + "/WEB-INF/classes/LanguageOptions.properties"; - // Create a Map to store the language direction Map languageDirectionMap = new HashMap<>(); - // Use a BufferedReader to read the file content try (BufferedReader bufferedReader = new BufferedReader(new FileReader(filePath))) { String line; + while ((line = bufferedReader.readLine()) != null) { - // Ignore comments and empty lines + if (!line.trim().startsWith("#") && !line.trim().isEmpty()) { - // Split the line into key and value using '=' String[] keyValue = line.split("="); - if (keyValue.length == 2) { // Ensure valid format - // Extract the language code from the key + + if (keyValue.length == 2) { String[] keyParts = keyValue[0].split("\\."); String languageCode = keyParts[keyParts.length - 1]; - - // Split the value into components (languageCode, languageName, direction) String[] valueParts = keyValue[1].split(","); - if (valueParts.length >= 3) { // Ensure the value has at least 3 parts + + if (valueParts.length >= 3) { String direction = valueParts[2].trim(); languageDirectionMap.put(languageCode, direction); } else { - languageDirectionMap.put(languageCode, "ltr"); // Default to LTR if direction is missing + languageDirectionMap.put(languageCode, "ltr"); } } } @@ -80,7 +79,7 @@ throw e; } - // Get the current language's direction + // Get the selected language's direction String direction = languageDirectionMap.getOrDefault(language, "ltr"); String themeSuffix = ""; @@ -94,7 +93,7 @@ String themeFileName = ""; for(String file: fileNames) { - if(file.endsWith(themeSuffix + ".min.css")) { + if (file.endsWith(themeSuffix + ".min.css")) { themeFileName = file; break; } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0eb3ea7dab7..b1fdb8a30a6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -20965,7 +20965,7 @@ packages: dependencies: '@babel/core': 7.26.0 '@babel/helper-compilation-targets': 7.25.9 - '@babel/helper-module-imports': 7.25.9(supports-color@5.5.0) + '@babel/helper-module-imports': 7.25.9 '@babel/helper-plugin-utils': 7.25.9 '@babel/traverse': 7.26.4 debug: 4.4.0(supports-color@6.1.0) @@ -21024,7 +21024,7 @@ packages: '@babel/core': ^7.0.0 dependencies: '@babel/core': 7.12.9 - '@babel/helper-module-imports': 7.25.9(supports-color@5.5.0) + '@babel/helper-module-imports': 7.25.9 '@babel/helper-validator-identifier': 7.25.9 '@babel/traverse': 7.26.4 transitivePeerDependencies: @@ -21037,7 +21037,7 @@ packages: '@babel/core': ^7.0.0 dependencies: '@babel/core': 7.26.0 - '@babel/helper-module-imports': 7.25.9(supports-color@5.5.0) + '@babel/helper-module-imports': 7.25.9 '@babel/helper-validator-identifier': 7.25.9 '@babel/traverse': 7.26.4 transitivePeerDependencies: @@ -21545,7 +21545,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.26.0 - '@babel/helper-module-imports': 7.25.9(supports-color@5.5.0) + '@babel/helper-module-imports': 7.25.9 '@babel/helper-plugin-utils': 7.25.9 '@babel/helper-remap-async-to-generator': 7.25.9(@babel/core@7.26.0) transitivePeerDependencies: @@ -21975,7 +21975,7 @@ packages: dependencies: '@babel/core': 7.26.0 '@babel/helper-annotate-as-pure': 7.25.9 - '@babel/helper-module-imports': 7.25.9(supports-color@5.5.0) + '@babel/helper-module-imports': 7.25.9 '@babel/helper-plugin-utils': 7.25.9 '@babel/plugin-syntax-jsx': 7.25.9(@babel/core@7.26.0) '@babel/types': 7.26.3 @@ -22028,7 +22028,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.26.0 - '@babel/helper-module-imports': 7.25.9(supports-color@5.5.0) + '@babel/helper-module-imports': 7.25.9 '@babel/helper-plugin-utils': 7.25.9 babel-plugin-polyfill-corejs2: 0.4.12(@babel/core@7.26.0) babel-plugin-polyfill-corejs3: 0.10.6(@babel/core@7.26.0) @@ -22589,7 +22589,7 @@ packages: /@emotion/babel-plugin@11.13.5: resolution: {integrity: sha512-pxHCpT2ex+0q+HH91/zsdHkw/lXd468DIN2zvfvLtPKLLMo6gQj7oLObq8PhkrxOZb/gGCq03S3Z7PDhS8pduQ==} dependencies: - '@babel/helper-module-imports': 7.25.9(supports-color@5.5.0) + '@babel/helper-module-imports': 7.25.9 '@babel/runtime': 7.26.0 '@emotion/hash': 0.9.2 '@emotion/memoize': 0.9.0 @@ -26605,7 +26605,7 @@ packages: optional: true dependencies: '@babel/core': 7.26.0 - '@babel/helper-module-imports': 7.25.9(supports-color@5.5.0) + '@babel/helper-module-imports': 7.25.9 '@rollup/pluginutils': 3.1.0(rollup@2.79.2) rollup: 2.79.2 transitivePeerDependencies: @@ -40638,8 +40638,6 @@ packages: peerDependenciesMeta: webpack: optional: true - webpack-sources: - optional: true dependencies: webpack: 5.84.1(@swc/core@1.3.99)(esbuild@0.18.20)(webpack-cli@4.10.0) webpack-sources: 3.2.3 @@ -46101,6 +46099,17 @@ packages: resolution: {integrity: sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==} engines: {node: 6.* || >= 7.*} + /rtlcss@4.3.0: + resolution: {integrity: sha512-FI+pHEn7Wc4NqKXMXFM+VAYKEj/mRIcW4h24YVwVtyjI+EqGrLc2Hx/Ny0lrZ21cBWU2goLy36eqMcNj3AQJig==} + engines: {node: '>=12.0.0'} + hasBin: true + dependencies: + escalade: 3.2.0 + picocolors: 1.1.1 + postcss: 8.4.49 + strip-json-comments: 3.1.1 + dev: true + /run-async@2.4.1: resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==} engines: {node: '>=0.12.0'} From 664b1ec3c513595cdcc91216af4371dbe70ab996 Mon Sep 17 00:00:00 2001 From: savindi7 Date: Mon, 6 Jan 2025 13:47:27 +0530 Subject: [PATCH 5/8] Add Changeset --- .changeset/hip-melons-crash.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changeset/hip-melons-crash.md diff --git a/.changeset/hip-melons-crash.md b/.changeset/hip-melons-crash.md new file mode 100644 index 00000000000..761a3cddb84 --- /dev/null +++ b/.changeset/hip-melons-crash.md @@ -0,0 +1,6 @@ +--- +"@wso2is/identity-apps-core": minor +"@wso2is/theme": minor +--- + +Add RTL support. From d110fed7bac9d7fba0b3f97b89c40c70c5c18309 Mon Sep 17 00:00:00 2001 From: savindi7 Date: Mon, 6 Jan 2025 13:51:54 +0530 Subject: [PATCH 6/8] Remove redundant comments. --- modules/theme/scripts/build.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/theme/scripts/build.js b/modules/theme/scripts/build.js index 05aaea972ca..3c475d73da3 100644 --- a/modules/theme/scripts/build.js +++ b/modules/theme/scripts/build.js @@ -264,8 +264,8 @@ const generateThemes = () => { return Theme.compile(themeIndexFile, {}).then((output) => { const minifiedOutput = new CleanCSS().minify(output.css); - const rtlCSS = generateRTLCSS(output.css); // Generate RTL CSS - const rtlMinCSS = new CleanCSS().minify(rtlCSS); // Minify RTL CSS + const rtlCSS = generateRTLCSS(output.css); + const rtlMinCSS = new CleanCSS().minify(rtlCSS); const files = { ".css": output.css, From 0d0db77e0aae8a9bafbf2eaa86ba0f1204e07ba0 Mon Sep 17 00:00:00 2001 From: savindi7 Date: Mon, 6 Jan 2025 18:32:36 +0530 Subject: [PATCH 7/8] Remove unnecessary new lines --- .../src/main/webapp/includes/header.jsp | 5 +---- .../apps/recovery-portal/src/main/webapp/includes/header.jsp | 5 +---- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/identity-apps-core/apps/authentication-portal/src/main/webapp/includes/header.jsp b/identity-apps-core/apps/authentication-portal/src/main/webapp/includes/header.jsp index 8e07ee36da6..69598b8ad78 100644 --- a/identity-apps-core/apps/authentication-portal/src/main/webapp/includes/header.jsp +++ b/identity-apps-core/apps/authentication-portal/src/main/webapp/includes/header.jsp @@ -38,9 +38,7 @@ Cookie[] userCookies = request.getCookies(); if (userCookies != null) { - for (Cookie cookie : userCookies) { - if ("ui_lang".equals(cookie.getName())) { language = cookie.getValue(); break; @@ -56,7 +54,6 @@ String line; while ((line = bufferedReader.readLine()) != null) { - if (!line.trim().startsWith("#") && !line.trim().isEmpty()) { String[] keyValue = line.split("="); @@ -80,8 +77,8 @@ // Get the selected language's direction. String direction = languageDirectionMap.getOrDefault(language, "ltr"); - String themeSuffix = ""; + if ("rtl".equals(languageDirectionMap.get(language))) { themeSuffix = ".rtl"; } diff --git a/identity-apps-core/apps/recovery-portal/src/main/webapp/includes/header.jsp b/identity-apps-core/apps/recovery-portal/src/main/webapp/includes/header.jsp index cf7110c8cee..855106aeab6 100644 --- a/identity-apps-core/apps/recovery-portal/src/main/webapp/includes/header.jsp +++ b/identity-apps-core/apps/recovery-portal/src/main/webapp/includes/header.jsp @@ -39,9 +39,7 @@ Cookie[] userCookies = request.getCookies(); if (userCookies != null) { - for (Cookie cookie : userCookies) { - if ("ui_lang".equals(cookie.getName())) { language = cookie.getValue(); break; @@ -57,7 +55,6 @@ String line; while ((line = bufferedReader.readLine()) != null) { - if (!line.trim().startsWith("#") && !line.trim().isEmpty()) { String[] keyValue = line.split("="); @@ -81,8 +78,8 @@ // Get the selected language's direction String direction = languageDirectionMap.getOrDefault(language, "ltr"); - String themeSuffix = ""; + if ("rtl".equals(languageDirectionMap.get(language))) { themeSuffix = ".rtl"; } From 573d6bbf11b1c2b455c1b132566903177c362dac Mon Sep 17 00:00:00 2001 From: savindi7 Date: Wed, 8 Jan 2025 12:56:39 +0530 Subject: [PATCH 8/8] Fix spacing and add localization example --- .../src/main/resources/LanguageOptions.properties | 1 + .../src/main/webapp/includes/header.jsp | 5 ++++- .../src/main/resources/LanguageOptions.properties | 1 + .../apps/recovery-portal/src/main/webapp/includes/header.jsp | 5 ++++- 4 files changed, 10 insertions(+), 2 deletions(-) diff --git a/identity-apps-core/apps/authentication-portal/src/main/resources/LanguageOptions.properties b/identity-apps-core/apps/authentication-portal/src/main/resources/LanguageOptions.properties index e4e7fd5235a..274cf7cc18c 100644 --- a/identity-apps-core/apps/authentication-portal/src/main/resources/LanguageOptions.properties +++ b/identity-apps-core/apps/authentication-portal/src/main/resources/LanguageOptions.properties @@ -21,6 +21,7 @@ # This file contains the language switcher configurations # The format of the file is =,,text direction(rtl/ltr) # The default text direction is set to "ltr". +# Example: lang.switch.ar_AR=ar,Arabic - العربية,rtl lang.switch.en_US=us,English - United States lang.switch.fr_FR=fr,Français - France lang.switch.es_ES=es,Español - España diff --git a/identity-apps-core/apps/authentication-portal/src/main/webapp/includes/header.jsp b/identity-apps-core/apps/authentication-portal/src/main/webapp/includes/header.jsp index 69598b8ad78..501e5502c17 100644 --- a/identity-apps-core/apps/authentication-portal/src/main/webapp/includes/header.jsp +++ b/identity-apps-core/apps/authentication-portal/src/main/webapp/includes/header.jsp @@ -41,6 +41,7 @@ for (Cookie cookie : userCookies) { if ("ui_lang".equals(cookie.getName())) { language = cookie.getValue(); + break; } } @@ -88,9 +89,10 @@ String[] fileNames = themeDir.list(); String themeFileName = ""; - for(String file: fileNames) { + for (String file: fileNames) { if (file.endsWith(themeSuffix + ".min.css")) { themeFileName = file; + break; } } @@ -163,6 +165,7 @@