From 40dd5227964b4d138e6731cb2cabc2cb5a7450f0 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Fri, 25 Jun 2021 13:06:09 +0530 Subject: [PATCH] feat: Auto generate RTL styles using rtlcss https://github.com/MohammadYounes/rtlcss --- esbuild/esbuild.js | 25 ++++++++++- frappe/public/js/frappe/desk.js | 12 ------ frappe/utils/jinja_globals.py | 11 ++++- frappe/www/app.html | 2 +- frappe/www/app.py | 3 ++ frappe/www/printview.html | 3 -- package.json | 1 + yarn.lock | 74 +++++++++++++++++++++++++++++++++ 8 files changed, 113 insertions(+), 18 deletions(-) diff --git a/esbuild/esbuild.js b/esbuild/esbuild.js index efa1959969..a0b07abe43 100644 --- a/esbuild/esbuild.js +++ b/esbuild/esbuild.js @@ -8,6 +8,7 @@ let yargs = require("yargs"); let cliui = require("cliui")(); let chalk = require("chalk"); let html_plugin = require("./frappe-html"); +let rtlcss = require('rtlcss'); let postCssPlugin = require("esbuild-plugin-postcss2").default; let ignore_assets = require("./ignore-assets"); let sass_options = require("./sass_options"); @@ -99,6 +100,7 @@ async function execute() { let result; try { result = await build_assets_for_apps(APPS, FILES_TO_BUILD); + result = await create_rtl_assets(result); } catch (e) { log_error("There were some problems during build"); log(); @@ -260,7 +262,8 @@ async function clean_dist_folders(apps) { let public_path = get_public_path(app); let paths = [ path.resolve(public_path, "dist", "js"), - path.resolve(public_path, "dist", "css") + path.resolve(public_path, "dist", "css"), + path.resolve(public_path, "dist", "css-rtl") ]; for (let target of paths) { if (fs.existsSync(target)) { @@ -484,3 +487,23 @@ function log_rebuilt_assets(prev_assets, new_assets) { } log(); } + +async function create_rtl_assets(result) { + for (let file_path in result.metafile.outputs) { + if (file_path.endsWith('.css')) { + console.log(file_path); + let content = fs.readFileSync(file_path, {'encoding': 'utf-8'}); + let rtl_content = rtlcss.process(content); + let rtl_file_path = file_path.replace('/css/', '/css-rtl/'); + let rtl_folder_path = path.dirname(rtl_file_path); + if (fs.existsSync(rtl_file_path)) { + continue; + } + if (!fs.existsSync(rtl_folder_path)) { + fs.mkdirSync(rtl_folder_path); + } + fs.writeFileSync(rtl_file_path, rtl_content); + } + } + return result; +} \ No newline at end of file diff --git a/frappe/public/js/frappe/desk.js b/frappe/public/js/frappe/desk.js index 65c0139b65..9d106f46f4 100644 --- a/frappe/public/js/frappe/desk.js +++ b/frappe/public/js/frappe/desk.js @@ -64,8 +64,6 @@ frappe.Application = class Application { } }); - this.set_rtl(); - // page container this.make_page_container(); this.set_route(); @@ -489,16 +487,6 @@ frappe.Application = class Application { }, 100); } - set_rtl() { - if (frappe.utils.is_rtl()) { - var ls = document.createElement('link'); - ls.rel="stylesheet"; - ls.type = "text/css"; - ls.href= frappe.assets.bundled_asset("frappe-rtl.bundle.css"); - document.getElementsByTagName('head')[0].appendChild(ls); - $('body').addClass('frappe-rtl'); - } - } show_change_log() { var me = this; diff --git a/frappe/utils/jinja_globals.py b/frappe/utils/jinja_globals.py index 2c14249672..30a0e46232 100644 --- a/frappe/utils/jinja_globals.py +++ b/frappe/utils/jinja_globals.py @@ -73,8 +73,13 @@ def include_script(path): return f'' -def include_style(path): +def include_style(path, rtl=None): path = bundled_asset(path) + if rtl is None: + rtl = is_rtl() + + if rtl: + path = path.replace('/css/', '/css-rtl/') return f'' @@ -87,3 +92,7 @@ def bundled_asset(path): path = bundled_assets.get(path) or path return abs_url(path) + +def is_rtl(): + from frappe import local + return local.lang in ["ar", "he", "fa", "ps"] \ No newline at end of file diff --git a/frappe/www/app.html b/frappe/www/app.html index c8172693b9..8704ed2671 100644 --- a/frappe/www/app.html +++ b/frappe/www/app.html @@ -1,5 +1,5 @@ - + diff --git a/frappe/www/app.py b/frappe/www/app.py index 27505c8131..55992b5a55 100644 --- a/frappe/www/app.py +++ b/frappe/www/app.py @@ -6,6 +6,7 @@ import os, re import frappe from frappe import _ import frappe.sessions +from frappe.utils.jinja_globals import is_rtl def get_context(context): if frappe.session.user == "Guest": @@ -40,6 +41,8 @@ def get_context(context): "build_version": frappe.utils.get_build_version(), "include_js": hooks["app_include_js"], "include_css": hooks["app_include_css"], + "dir": "rtl" if is_rtl() else "ltr", + "lang": frappe.local.lang, "sounds": hooks["sounds"], "boot": boot if context.get("for_mobile") else boot_json, "desk_theme": desk_theme or "Light", diff --git a/frappe/www/printview.html b/frappe/www/printview.html index 8bc6e0cb80..05e85730dd 100644 --- a/frappe/www/printview.html +++ b/frappe/www/printview.html @@ -6,9 +6,6 @@ {{ title }} {{ include_style('print.bundle.css') }} - {%- if has_rtl -%} - {{ include_style('frappe-rtl.bundle.css') }} - {%- endif -%} diff --git a/package.json b/package.json index 8b22a6e92c..e84fa1b581 100644 --- a/package.json +++ b/package.json @@ -67,6 +67,7 @@ "fast-glob": "^3.2.5", "launch-editor": "^2.2.1", "md5": "^2.3.0", + "rtlcss": "^3.2.1", "yargs": "^16.2.0" }, "snyk": true diff --git a/yarn.lock b/yarn.lock index 7b1fb981dd..d031f58685 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2420,6 +2420,14 @@ find-up@^3.0.0: dependencies: locate-path "^3.0.0" +find-up@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== + dependencies: + locate-path "^6.0.0" + path-exists "^4.0.0" + follow-redirects@^1.10.0: version "1.13.3" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.13.3.tgz#e5598ad50174c1bc4e872301e82ac2cd97f90267" @@ -3697,6 +3705,13 @@ locate-path@^3.0.0: p-locate "^3.0.0" path-exists "^3.0.0" +locate-path@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== + dependencies: + p-locate "^5.0.0" + lodash.assign@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-4.2.0.tgz#0d99f3ccd7a6d261d19bdaeb9245005d285808e7" @@ -4234,6 +4249,11 @@ nanoid@^3.1.22: resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.22.tgz#b35f8fb7d151990a8aebd5aa5015c03cf726f844" integrity sha512-/2ZUaJX2ANuLtTvqTlgqBQNJoQO398KyJgZloL0PZkC0dpysjncRUPsFe3DUPzz/y3h+u7C46np8RMuvF3jsSQ== +nanoid@^3.1.23: + version "3.1.23" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.23.tgz#f744086ce7c2bc47ee0a8472574d5c78e4183a81" + integrity sha512-FiB0kzdP0FFVGDKlRLEQ1BgDzU87dy5NnzjeW9YZNt+/c3+q82EQDUwniSAUxp/F0gFNI1ZhKU1FqYsMuqZVnw== + native-request@^1.0.5: version "1.0.8" resolved "https://registry.yarnpkg.com/native-request/-/native-request-1.0.8.tgz#8f66bf606e0f7ea27c0e5995eb2f5d03e33ae6fb" @@ -4583,6 +4603,13 @@ p-limit@^2.0.0: dependencies: p-try "^2.0.0" +p-limit@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== + dependencies: + yocto-queue "^0.1.0" + p-locate@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" @@ -4590,6 +4617,13 @@ p-locate@^3.0.0: dependencies: p-limit "^2.0.0" +p-locate@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== + dependencies: + p-limit "^3.0.2" + p-map@2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/p-map/-/p-map-2.1.0.tgz#310928feef9c9ecc65b68b17693018a665cea175" @@ -4712,6 +4746,11 @@ path-exists@^3.0.0: resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + path-is-absolute@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" @@ -5170,6 +5209,15 @@ postcss@^7.0.32: source-map "^0.6.1" supports-color "^6.1.0" +postcss@^8.2.4: + version "8.3.5" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.3.5.tgz#982216b113412bc20a86289e91eb994952a5b709" + integrity sha512-NxTuJocUhYGsMiMFHDUkmjSKT3EdH4/WbGF6GCi1NDGk+vbcUTun4fpbOqaPtD8IIsztA2ilZm2DhYCuyN58gA== + dependencies: + colorette "^1.2.2" + nanoid "^3.1.23" + source-map-js "^0.6.2" + prepend-http@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" @@ -5852,6 +5900,17 @@ roarr@^2.15.3: semver-compare "^1.0.0" sprintf-js "^1.1.2" +rtlcss@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/rtlcss/-/rtlcss-3.2.1.tgz#654e55ea2f46991f9738d952ba77ba0aa94a670d" + integrity sha512-S9bh35JXwPIhfun7nFu/HjlNrwELL5nvTJqA1suLfbnqY/mauIL5sBkrJNHziVppX9PA2rJ7NV82+RtzB71mJA== + dependencies: + chalk "^4.1.0" + find-up "^5.0.0" + mkdirp "^1.0.4" + postcss "^8.2.4" + strip-json-comments "^3.1.1" + run-async@^2.4.0: version "2.4.1" resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455" @@ -6459,6 +6518,11 @@ sortablejs@^1.7.0: resolved "https://registry.yarnpkg.com/sortablejs/-/sortablejs-1.8.3.tgz#5ae908ef96300966e95440a143340f5dd565a0df" integrity sha512-AftvD4hdKcR5QlGi7L/JST506zGNGrysE8/QohDpwKXJarHWqCt+TUlrtoMk/wkECB607Q019/OZlJViyWiD6A== +source-map-js@^0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-0.6.2.tgz#0bb5de631b41cfbda6cfba8bd05a80efdfd2385e" + integrity sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug== + source-map-resolve@^0.5.2: version "0.5.3" resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a" @@ -6756,6 +6820,11 @@ strip-indent@^1.0.1: dependencies: get-stdin "^4.0.1" +strip-json-comments@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== + strip-json-comments@~2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" @@ -7568,3 +7637,8 @@ yeast@0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/yeast/-/yeast-0.1.2.tgz#008e06d8094320c372dbc2f8ed76a0ca6c8ac419" integrity sha1-AI4G2AlDIMNy28L47XagymyKxBk= + +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==