From 3243bb1b7e82e79162e137e856377dfa179047bf Mon Sep 17 00:00:00 2001 From: SilviaAmAm Date: Wed, 19 Oct 2022 13:20:17 +0200 Subject: [PATCH] :construction: [#1924] Dark scheme for django-tinymce --- src/openforms/js/index.js | 2 +- src/openforms/js/initTinymce.js | 91 +++++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+), 1 deletion(-) create mode 100644 src/openforms/js/initTinymce.js diff --git a/src/openforms/js/index.js b/src/openforms/js/index.js index f881ac852c..9738775e6d 100644 --- a/src/openforms/js/index.js +++ b/src/openforms/js/index.js @@ -1,5 +1,5 @@ import {Formio} from 'react-formio'; - +import './initTinymce'; import './components'; import OpenForms from './formio_module'; diff --git a/src/openforms/js/initTinymce.js b/src/openforms/js/initTinymce.js new file mode 100644 index 0000000000..a3336bedbb --- /dev/null +++ b/src/openforms/js/initTinymce.js @@ -0,0 +1,91 @@ +// Taken from https://github.com/jazzband/django-tinymce/blob/master/tinymce/static/django_tinymce/init_tinymce.js +// Updated to add dark theme detection (L35-44) + +'use strict'; + +{ + function initTinyMCE(el) { + if (el.closest('.empty-form') === null) { // Don't do empty inlines + var mce_conf = JSON.parse(el.dataset.mceConf); + + // There is no way to pass a JavaScript function as an option + // because all options are serialized as JSON. + const fns = [ + 'color_picker_callback', + 'file_browser_callback', + 'file_picker_callback', + 'images_dataimg_filter', + 'images_upload_handler', + 'paste_postprocess', + 'paste_preprocess', + 'setup', + 'urlconverter_callback', + ]; + fns.forEach((fn_name) => { + if (typeof mce_conf[fn_name] != 'undefined') { + if (mce_conf[fn_name].includes('(')) { + mce_conf[fn_name] = eval('(' + mce_conf[fn_name] + ')'); + } + else { + mce_conf[fn_name] = window[mce_conf[fn_name]]; + } + } + }); + + // TODO Django 4.2: use explicit theme names rather than the media query approach: + // https://github.com/django/django/blob/main/django/contrib/admin/static/admin/css/dark_mode.css#L36 + const useDarkMode = window.matchMedia('(prefers-color-scheme: dark)').matches; + mce_conf = { + ...mce_conf, + ...{ + skin: useDarkMode ? 'oxide-dark' : 'oxide', + content_css: useDarkMode ? 'dark' : 'default', + } + } + + const id = el.id; + if ('elements' in mce_conf && mce_conf['mode'] == 'exact') { + mce_conf['elements'] = id; + } + if (el.dataset.mceGzConf) { + tinyMCE_GZ.init(JSON.parse(el.dataset.mceGzConf)); + } + if (!tinyMCE.get(id)) { + tinyMCE.init(mce_conf); + } + } + } + + // Call function fn when the DOM is loaded and ready. If it is already + // loaded, call the function now. + // https://youmightnotneedjquery.com/#ready + function ready(fn) { + if (document.readyState !== 'loading') { + fn(); + } else { + document.addEventListener('DOMContentLoaded', fn); + } + } + + function initializeTinyMCE(element, formsetName) { + Array.from(element.querySelectorAll('.tinymce')).forEach(area => initTinyMCE(area)); + } + + ready(function() { + // initialize the TinyMCE editors on load + initializeTinyMCE(document); + + // initialize the TinyMCE editor after adding an inline in the django admin context. + if (typeof(django) !== 'undefined' && typeof(django.jQuery) !== 'undefined') { + django.jQuery(document).on('formset:added', (event, $row, formsetName) => { + if (event.detail && event.detail.formsetName) { + // Django >= 4.1 + initializeTinyMCE(event.target); + } else { + // Django < 4.1, use $row + initializeTinyMCE($row.get(0)); + } + }); + } + }); +}