diff --git a/amd/build/editor.min.js b/amd/build/editor.min.js
index dccd8b9..8685ae5 100644
--- a/amd/build/editor.min.js
+++ b/amd/build/editor.min.js
@@ -1,3 +1,3 @@
-define("mod_newsletter/editor",["exports"],(function(_exports){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.loadCss=void 0;_exports.loadCss=async function(){var select=document.querySelector("#id_stylesheetid");function change_stylesheet(){console.log("config")}select&&select.addEventListener("change",change_stylesheet),new Promise((resolve=>{!function checkIfLoaded(){window.tinyMCE?resolve(window.tinyMCE):setTimeout(checkIfLoaded,100)}()})).then((tinyMCE=>{console.log("tinyMCE is loaded:",tinyMCE);const existingEditor=tinyMCE.EditorManager.get("id_htmlcontent");existingEditor&&console.log(existingEditor),change_stylesheet()}))}}));
+define("mod_newsletter/editor",["exports"],(function(_exports){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.loadCss=void 0;_exports.loadCss=async function(editorconfig){var select=document.querySelector("#id_stylesheetid");function change_stylesheet(){console.log("config")}select&&select.addEventListener("change",change_stylesheet),new Promise((resolve=>{!function checkIfLoaded(){window.tinyMCE?resolve(window.tinyMCE):setTimeout(checkIfLoaded,100)}()})).then((tinyMCE=>{console.log("tinyMCE is loaded:",tinyMCE);const existingEditor=tinyMCE.add("id_htmlcontent");existingEditor&&console.log(existingEditor),tinyMCE.init(editorconfig),change_stylesheet()}))}}));
//# sourceMappingURL=editor.min.js.map
\ No newline at end of file
diff --git a/amd/build/editor.min.js.map b/amd/build/editor.min.js.map
index c5c638d..48e3a2d 100644
--- a/amd/build/editor.min.js.map
+++ b/amd/build/editor.min.js.map
@@ -1 +1 @@
-{"version":3,"file":"editor.min.js","sources":["../src/editor.js"],"sourcesContent":["/* eslint-disable no-console */\n// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n// import {setupForElementId} from 'editor_tiny/editor';\n\nexport const loadCss = async function() {\n var select = document.querySelector('#id_stylesheetid');\n if (select) {\n select.addEventListener('change', change_stylesheet);\n }\n /**\n * Function to wait until tinyMCE is loaded\n * @returns {Promise}\n */\n function waitUntilTinyMCELoaded() {\n return new Promise((resolve) => {\n /**\n * Check if tinyMCE object is available\n */\n function checkIfLoaded() {\n if (window.tinyMCE) {\n // If tinyMCE is available, resolve the promise\n resolve(window.tinyMCE);\n } else {\n // If not, wait and check again\n setTimeout(checkIfLoaded, 100); // Check every 100 milliseconds\n }\n }\n\n checkIfLoaded();\n });\n }\n\n /**\n * Function to change CSS for the content inside TinyMCE\n */\n waitUntilTinyMCELoaded()\n .then((tinyMCE) => {\n console.log('tinyMCE is loaded:', tinyMCE);\n const existingEditor = tinyMCE.EditorManager.get('id_htmlcontent');\n if(existingEditor) {\n console.log(existingEditor);\n }\n // Call function to change CSS for TinyMCE content\n change_stylesheet();\n });\n\n // var Tiny = setupForElementId({\n // elementId: \"id_htmlcontent\",\n // options: {},\n // });\n\n /**\n * Changes the stylesheet based on the selected option.\n */\n function change_stylesheet() {\n console.log('config');\n }\n};\n"],"names":["async","select","document","querySelector","change_stylesheet","console","log","addEventListener","Promise","resolve","checkIfLoaded","window","tinyMCE","setTimeout","then","existingEditor","EditorManager","get"],"mappings":"gKAkBuBA,qBACfC,OAASC,SAASC,cAAc,6BAiD3BC,oBACLC,QAAQC,IAAI,UAjDZL,QACAA,OAAOM,iBAAiB,SAAUH,mBAO3B,IAAII,SAASC,oBAIPC,gBACDC,OAAOC,QAEPH,QAAQE,OAAOC,SAGfC,WAAWH,cAAe,KAIlCA,MAQHI,MAAMF,UACHP,QAAQC,IAAI,qBAAsBM,eAC5BG,eAAiBH,QAAQI,cAAcC,IAAI,kBAC9CF,gBACCV,QAAQC,IAAIS,gBAGhBX"}
\ No newline at end of file
+{"version":3,"file":"editor.min.js","sources":["../src/editor.js"],"sourcesContent":["/* eslint-disable no-console */\n// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\nexport const loadCss = async function(editorconfig) {\n var select = document.querySelector('#id_stylesheetid');\n if (select) {\n select.addEventListener('change', change_stylesheet);\n }\n /**\n * Function to wait until tinyMCE is loaded\n * @returns {Promise}\n */\n function waitUntilTinyMCELoaded() {\n return new Promise((resolve) => {\n /**\n * Check if tinyMCE object is available\n */\n function checkIfLoaded() {\n if (window.tinyMCE) {\n // If tinyMCE is available, resolve the promise\n resolve(window.tinyMCE);\n } else {\n // If not, wait and check again\n setTimeout(checkIfLoaded, 100); // Check every 100 milliseconds\n }\n }\n checkIfLoaded();\n });\n }\n\n /**\n * Function to change CSS for the content inside TinyMCE\n */\n waitUntilTinyMCELoaded()\n .then((tinyMCE) => {\n console.log('tinyMCE is loaded:', tinyMCE);\n const existingEditor = tinyMCE.add('id_htmlcontent');\n if(existingEditor) {\n console.log(existingEditor);\n }\n // Call function to change CSS for TinyMCE content\n tinyMCE.init(editorconfig);\n change_stylesheet();\n });\n\n /**\n * Changes the stylesheet based on the selected option.\n */\n function change_stylesheet() {\n console.log('config');\n }\n};\n"],"names":["async","editorconfig","select","document","querySelector","change_stylesheet","console","log","addEventListener","Promise","resolve","checkIfLoaded","window","tinyMCE","setTimeout","then","existingEditor","add","init"],"mappings":"gKAgBuBA,eAAeC,kBAC9BC,OAASC,SAASC,cAAc,6BA4C3BC,oBACLC,QAAQC,IAAI,UA5CZL,QACAA,OAAOM,iBAAiB,SAAUH,mBAO3B,IAAII,SAASC,oBAIPC,gBACDC,OAAOC,QAEPH,QAAQE,OAAOC,SAGfC,WAAWH,cAAe,KAGlCA,MAQHI,MAAMF,UACHP,QAAQC,IAAI,qBAAsBM,eAC5BG,eAAiBH,QAAQI,IAAI,kBAChCD,gBACCV,QAAQC,IAAIS,gBAGhBH,QAAQK,KAAKjB,cACbI"}
\ No newline at end of file
diff --git a/amd/src/editor.js b/amd/src/editor.js
index c1b0e52..defb06c 100755
--- a/amd/src/editor.js
+++ b/amd/src/editor.js
@@ -14,9 +14,13 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see .
-// import {setupForElementId} from 'editor_tiny/editor';
-
-export const loadCss = async function() {
+/**
+ * This is obsolete. To be deleted in the future. Maybe if Moodle does a better integration of Tiny 6, it could be used again.
+ *
+ * @param editorconfig
+ * @returns {Promise}
+ */
+export const loadCss = async function(editorconfig) {
var select = document.querySelector('#id_stylesheetid');
if (select) {
select.addEventListener('change', change_stylesheet);
@@ -39,7 +43,6 @@ export const loadCss = async function() {
setTimeout(checkIfLoaded, 100); // Check every 100 milliseconds
}
}
-
checkIfLoaded();
});
}
@@ -50,19 +53,15 @@ export const loadCss = async function() {
waitUntilTinyMCELoaded()
.then((tinyMCE) => {
console.log('tinyMCE is loaded:', tinyMCE);
- const existingEditor = tinyMCE.EditorManager.get('id_htmlcontent');
+ const existingEditor = tinyMCE.add('id_htmlcontent');
if(existingEditor) {
console.log(existingEditor);
}
// Call function to change CSS for TinyMCE content
+ tinyMCE.init(editorconfig);
change_stylesheet();
});
- // var Tiny = setupForElementId({
- // elementId: "id_htmlcontent",
- // options: {},
- // });
-
/**
* Changes the stylesheet based on the selected option.
*/
diff --git a/classes/newsletter.php b/classes/newsletter.php
index 9fd55cd..b7934fb 100644
--- a/classes/newsletter.php
+++ b/classes/newsletter.php
@@ -29,6 +29,7 @@
use context_module;
use core\event\user_created;
use core_user;
+use editor_tiny\editor;
use editor_tiny\manager;
use mod_newsletter_instance_store;
use newsletter_section_list;
@@ -831,49 +832,8 @@ private function view_edit_issue_page(array $params) {
'filename',
false
);
- $cssurls = [];
- $cssurls[NEWSLETTER_DEFAULT_STYLESHEET] = "{$CFG->wwwroot}/mod/newsletter/reset.css";
- if (!empty($files)) {
- foreach ($files as $file) {
- $url = "{$CFG->wwwroot}/pluginfile.php/{$file->get_contextid()}/mod_newsletter/" . NEWSLETTER_FILE_AREA_STYLESHEET;
- $cssurls[$file->get_id()] = $url . $file->get_filepath() . $file->get_itemid() . '/' . $file->get_filename();
- }
- }
- $editormanager = new manager();
- $siteconfig = get_config('editor_tiny');
- $editorconfig = json_encode([
- 'context' => $context->id,
-
- // File picker options.
- 'filepicker' => [],
-
- 'currentLanguage' => current_language(),
-
- 'branding' => property_exists($siteconfig, 'branding') ? !empty($siteconfig->branding) : true,
-
- // Language options.
- 'language' => [
- 'currentlang' => current_language(),
- 'installed' => get_string_manager()->get_list_of_translations(true),
- 'available' => get_string_manager()->get_list_of_languages()
- ],
-
- // Placeholder selectors.
- // Some contents (Example: placeholder elements) are only shown in the editor, and not to users. It is unrelated to the
- // real display. We created a list of placeholder selectors, so we can decide to or not to apply rules, styles... to
- // these elements.
- // The default of this list will be empty.
- // Other plugins can register their placeholder elements to placeholderSelectors list by calling
- // editor_tiny/options::registerPlaceholderSelectors.
- 'placeholderSelectors' => [],
-
- // Nest menu inside parent DOM.
- 'nestedmenu' => true,
- ]);
- $plugins = json_encode($editormanager->get_plugin_configuration($context));
- $PAGE->requires->js_call_amd('mod_newsletter/editor', 'loadCss',
- [$cssurls, $issue->stylesheetid, $editorconfig, $plugins]);
-
+ $editor = new newsletter_editor();
+ $editor->use_editor('id_htmlcontent', ['context' => $this->context], null, $issue, $files);
$mform = new issue_form(
null,
array('newsletter' => $this, 'issue' => $issue, 'context' => $context)
diff --git a/classes/newsletter_editor.php b/classes/newsletter_editor.php
new file mode 100644
index 0000000..8252783
--- /dev/null
+++ b/classes/newsletter_editor.php
@@ -0,0 +1,131 @@
+.
+
+namespace mod_newsletter;
+use editor_tiny\editor;
+
+/**
+ * Add custom css to the default editor. This is quite a hack due to the hacky implementation of Tiny 6 editor in Moodle.
+ */
+class newsletter_editor extends editor {
+ /**
+ * Use this editor for given element.
+ *
+ * @param string $elementid
+ * @param array $options
+ * @param null $fpoptions
+ * @param null $issue
+ */
+ public function use_editor($elementid, array $options = null, $fpoptions = null, $issue = null, array $files = []) {
+ global $PAGE, $CFG;
+ // Ensure that the default configuration is set.
+ self::reset_default_configuration();
+ self::set_default_configuration($this->manager);
+
+ if ($fpoptions === null) {
+ $fpoptions = [];
+ }
+
+ $context = $PAGE->context;
+
+ if (isset($options['context']) && ($options['context'] instanceof \context)) {
+ // A different context was provided.
+ // Use that instead.
+ $context = $options['context'];
+ }
+
+ $cssurls = [];
+ $cssurls[NEWSLETTER_DEFAULT_STYLESHEET] = "{$CFG->wwwroot}/mod/newsletter/reset.css";
+ if (!empty($files)) {
+ foreach ($files as $file) {
+ $url = "{$CFG->wwwroot}/pluginfile.php/{$file->get_contextid()}/mod_newsletter/" . NEWSLETTER_FILE_AREA_STYLESHEET;
+ $cssurls[$file->get_id()] = $url . $file->get_filepath() . $file->get_itemid() . '/' . $file->get_filename();
+ }
+ }
+ // Generate the configuration for this editor.
+ $siteconfig = get_config('editor_tiny');
+ $config = (object) [
+ // The URL to the CSS file for the editor.
+ 'css' => $cssurls[$issue->stylesheetid],
+
+ // The current context for this page or editor.
+ 'context' => $context->id,
+
+ // File picker options.
+ 'filepicker' => $fpoptions,
+
+ 'currentLanguage' => current_language(),
+
+ 'branding' => property_exists($siteconfig, 'branding') ? !empty($siteconfig->branding) : true,
+
+ // Language options.
+ 'language' => [
+ 'currentlang' => current_language(),
+ 'installed' => get_string_manager()->get_list_of_translations(true),
+ 'available' => get_string_manager()->get_list_of_languages()
+ ],
+
+ // Placeholder selectors.
+ // Some contents (Example: placeholder elements) are only shown in the editor, and not to users. It is unrelated to the
+ // real display. We created a list of placeholder selectors, so we can decide to or not to apply rules, styles... to
+ // these elements.
+ // The default of this list will be empty.
+ // Other plugins can register their placeholder elements to placeholderSelectors list by calling
+ // editor_tiny/options::registerPlaceholderSelectors.
+ 'placeholderSelectors' => [],
+
+ // Plugin configuration.
+ 'plugins' => $this->manager->get_plugin_configuration($context, $options, $fpoptions, $this),
+
+ // Nest menu inside parent DOM.
+ 'nestedmenu' => true,
+ ];
+
+ if (defined('BEHAT_SITE_RUNNING') && BEHAT_SITE_RUNNING) {
+ // Add sample selectors for Behat test.
+ $config->placeholderSelectors = ['.behat-tinymce-placeholder'];
+ }
+
+ foreach ($fpoptions as $fp) {
+ // Guess the draftitemid for the editor.
+ // Note: This is the best we can do at the moment.
+ if (!empty($fp->itemid)) {
+ $config->draftitemid = $fp->itemid;
+ break;
+ }
+ }
+
+ $configoptions = json_encode(convert_to_array($config));
+
+ // Note: This is not ideal but the editor does not have control over any HTML output.
+ // The Editor API only allows you to run JavaScript.
+ // In the future we will extend the editor API to allow it to generate the textarea, or attributes to use in the
+ // textarea or its wrapper.
+ // For now we cannot use the `js_call_amd()` API call because it warns if the parameters passed exceed a
+ // relatively low character limit.
+ $inlinejs = << {
+ Tiny.setupForElementId({
+ elementId: "${elementid}",
+ options: ${configoptions},
+ });
+ M.util.js_complete('editor_tiny/editor');
+ });
+ EOF;
+ $PAGE->requires->js_amd_inline($inlinejs);
+ }
+}
\ No newline at end of file
diff --git a/classes/task/._send_newsletter.php b/classes/task/._send_newsletter.php
deleted file mode 100644
index 85ee0ec..0000000
Binary files a/classes/task/._send_newsletter.php and /dev/null differ
diff --git a/lang/de/._newsletter.php b/lang/de/._newsletter.php
deleted file mode 100644
index be5ea9f..0000000
Binary files a/lang/de/._newsletter.php and /dev/null differ
diff --git a/lang/de/newsletter.php b/lang/de/newsletter.php
index d7afdca..d80744d 100644
--- a/lang/de/newsletter.php
+++ b/lang/de/newsletter.php
@@ -103,7 +103,7 @@
$string['health_2'] = 'Blacklisted';
$string['health_4'] = 'Abgemeldet';
$string['issue_htmlcontent'] = 'HTML Inhalt';
-$string['issue_stylesheet'] = 'Stylesheet-Datei für HTML Inhalt';
+$string['issue_stylesheet'] = 'Stylesheet-Datei für HTML Inhalt. ';
$string['issue_title'] = 'Ausgabentitel';
$string['issue_title_help'] = 'Geben Sie hier den Titel der Ausgabe ein (erforderlich).';
$string['manage_subscriptions'] = 'Abonnements verwalten';
diff --git a/lang/en/._newsletter.php b/lang/en/._newsletter.php
deleted file mode 100644
index b687a55..0000000
Binary files a/lang/en/._newsletter.php and /dev/null differ
diff --git a/lang/en/newsletter.php b/lang/en/newsletter.php
index e04cfdd..221c7dc 100644
--- a/lang/en/newsletter.php
+++ b/lang/en/newsletter.php
@@ -55,7 +55,7 @@
$string['issue_title_help'] = 'Type in the title of this issue. Required.';
$string['issue_htmlcontent'] = 'HTML content';
-$string['issue_stylesheet'] = 'Stylesheet file for HTML content';
+$string['issue_stylesheet'] = 'Stylesheet-Datei für HTML-Inhalte. Um korrekt gestyltes HTML beim Bearbeiten zu sehen, müssen Sie die Ausgabe zuerst speichern und dann erneut bearbeiten. Eine Änderung des Stylesheets während des Editierens ist derzeit nicht möglich.';
$string['mode_group_by_year'] = 'Group issues by year';
$string['mode_group_by_month'] = 'Group issues by month';
diff --git a/version.php b/version.php
index 2af4cb5..c40f289 100644
--- a/version.php
+++ b/version.php
@@ -24,8 +24,8 @@
defined('MOODLE_INTERNAL') || die();
-$plugin->version = 2024032900;
+$plugin->version = 2024042500;
$plugin->requires = 2022041900;
$plugin->maturity = MATURITY_STABLE;
-$plugin->release = 'v2.4.0-UkrainskaPravda'; // Already used names: Der Standard, Le Monde Diplomatique, NewYorkTimes.
+$plugin->release = 'v2.4.1-UkrainskaPravda'; // Already used names: Der Standard, Le Monde Diplomatique, NewYorkTimes.
$plugin->component = 'mod_newsletter';