From fdde53588e0f570b649621dafad6045f56cc001d Mon Sep 17 00:00:00 2001 From: Alicia Sykes Date: Mon, 31 May 2021 15:17:54 +0100 Subject: [PATCH] Adds custom CSS functionality --- README.md | 1 + src/App.vue | 25 ++++++- .../Configuration/ConfigContainer.vue | 5 ++ src/components/Configuration/CustomCss.vue | 67 +++++++++++++++++++ src/router.js | 9 ++- 5 files changed, 104 insertions(+), 3 deletions(-) create mode 100644 src/components/Configuration/CustomCss.vue diff --git a/README.md b/README.md index a2b055fa..4fbd8a24 100644 --- a/README.md +++ b/README.md @@ -95,6 +95,7 @@ All fields are optional, unless otherwise stated. - `backgroundImg` - String: Path to an optional full-screen app background image. This can be either remote (http) or local (/). Note that this will slow down initial load - `enableFontAwesome` - Boolean: Where `true` is enabled, if left blank font-awesome will be enabled only if required by 1 or more icons - `fontAwesomeKey` - String: If you have a font-awesome key, then you can use it here and make use of premium icons. It is a 10-digit alpha-numeric string from you're FA kit URL (e.g. `13014ae648`) +- `customCss` - String: Raw CSS that will be applied to the page. Please minify it first. - `theme`- String: The default theme for first load (you can change this later from the UI) - `cssThemes` - String[]: An array of custom theme names which can be used in the theme switcher dropdown - _See **theming** below_ - `externalStyleSheet` - String or String[] - Either a URL to an external stylesheet or an array or URLs, which can be applied as themes within the UI diff --git a/src/App.vue b/src/App.vue index c5aad223..d6446210 100644 --- a/src/App.vue +++ b/src/App.vue @@ -20,11 +20,21 @@ export default { }, data: () => ({ // pageInfo: this.getPageInfo(conf.pageInfo), - appConfig: conf.appConfig || Defaults.appConfig, showFooter: Defaults.visibleComponents.footer, }), computed: { - pageInfo: function pi() { return this.getPageInfo(conf.pageInfo); }, + pageInfo() { + return this.getPageInfo(conf.pageInfo); + }, + appConfig() { + if (localStorage[localStorageKeys.APP_CONFIG]) { + return JSON.parse(localStorage[localStorageKeys.APP_CONFIG]); + } else if (conf.appConfig) { + return conf.appConfig; + } else { + return Defaults.appConfig; + } + }, }, methods: { /* Returns either page info from the config, or default values */ @@ -53,6 +63,17 @@ export default { } return ''; }, + injectCustomStyles(usersCss) { + const style = document.createElement('style'); + style.textContent = usersCss; + document.head.append(style); + }, + }, + mounted() { + if (this.appConfig.customCss) { + const cleanedCss = this.appConfig.customCss.replace(/<\/?[^>]+(>|$)/g, ''); + this.injectCustomStyles(cleanedCss); + } }, }; diff --git a/src/components/Configuration/ConfigContainer.vue b/src/components/Configuration/ConfigContainer.vue index fc33f100..f0dd9622 100644 --- a/src/components/Configuration/ConfigContainer.vue +++ b/src/components/Configuration/ConfigContainer.vue @@ -49,6 +49,9 @@ + + + @@ -58,6 +61,7 @@ import JsonToYaml from '@/utils/JsonToYaml'; import { localStorageKeys, modalNames } from '@/utils/defaults'; import EditSiteMeta from '@/components/Configuration/EditSiteMeta'; import JsonEditor from '@/components/Configuration/JsonEditor'; +import CustomCssEditor from '@/components/Configuration/CustomCss'; import DownloadIcon from '@/assets/interface-icons/config-download-file.svg'; import DeleteIcon from '@/assets/interface-icons/config-delete-local.svg'; import EditIcon from '@/assets/interface-icons/config-edit-json.svg'; @@ -83,6 +87,7 @@ export default { components: { EditSiteMeta, JsonEditor, + CustomCssEditor, DownloadIcon, DeleteIcon, EditIcon, diff --git a/src/components/Configuration/CustomCss.vue b/src/components/Configuration/CustomCss.vue new file mode 100644 index 00000000..c3d4dd2a --- /dev/null +++ b/src/components/Configuration/CustomCss.vue @@ -0,0 +1,67 @@ + + + + + diff --git a/src/router.js b/src/router.js index a4b53067..7c30c54a 100644 --- a/src/router.js +++ b/src/router.js @@ -14,6 +14,13 @@ try { localPageInfo = undefined; } +let localAppConfig; +try { + localAppConfig = JSON.parse(localStorage[localStorageKeys.APP_CONFIG]); +} catch (e) { + localAppConfig = undefined; +} + const router = new Router({ routes: [ { @@ -23,7 +30,7 @@ const router = new Router({ props: { sections: sections || [], pageInfo: localPageInfo || pageInfo || defaultPageInfo, - appConfig: appConfig || {}, + appConfig: localAppConfig || appConfig || {}, }, meta: { title: 'Home Page',