aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcus Eibrink-Lunzenauer <lunzenauer@elan-ev.de>2022-09-06 08:17:41 +0000
committerElmar Ludwig <elmar.ludwig@uni-osnabrueck.de>2022-09-06 08:17:41 +0000
commit5d79d3eaaa9c66126cafb20ff50d2782c926faf3 (patch)
treeb0066794efa87ee06f12e7d1d34f664240637085
parent8c5a90d52e8f3ea8edb4ee2e24275c96119e07aa (diff)
Remove WYSIWYG toolbar icon to disable WYSIWYG, fixes #1495
Closes #1495 Merge request studip/studip!946
-rw-r--r--app/controllers/wysiwyg.php329
-rw-r--r--resources/assets/javascripts/chunks/wysiwyg.js3
-rw-r--r--resources/assets/javascripts/cke/StudipSettings.js138
3 files changed, 0 insertions, 470 deletions
diff --git a/app/controllers/wysiwyg.php b/app/controllers/wysiwyg.php
index 88e640c..cb07e6f 100644
--- a/app/controllers/wysiwyg.php
+++ b/app/controllers/wysiwyg.php
@@ -120,333 +120,4 @@ class WysiwygController extends AuthenticatedController
}
$this->render_json($response); // send HTTP response to client
}
-
- /**
- * Store or retrieve settings.
- *
- * Settings are further subdivided into groups. For example: global,
- * seminar- and user-specific settings (see below).
- *
- * HTTP GET
- * returns a JSON object with current settings.
- *
- * HTTP PUT
- * expects a JSON object with settings to store and returns
- * updated settings as a JSON object. Some settings are read-only,
- * others can only be set if the user has the necessary access level.
- *
- * Currently only the following basic features are supported:
- *
- * HTTP GET wysiwyg/settings/global
- * Always returns:
- * {
- * "upload": {
- * "permission": "autor",
- * "folder": {
- * "name": "Wysiwyg Uploads",
- * "description": "Vom WYSIWYG Editor hochgeladene Dateien."
- * }
- * }
- * }
- * }
- *
- * HTTP GET wysiwyg/settings/users/current
- * Always returns following setting for the authenticated user:
- * {
- * "disabled": false | true
- * }
- *
- * HTTP PUT wysiwyg/settings/users/current
- * Allows only to reset or set the disabled state with:
- * {
- * "disabled": false | true
- * }
- *
- * Below is a specification of possible future extensions to this
- * interface, that are based on current feature requests by users
- * (mainly people from ELMO, ELAN and ECULT).
- *
- * wysiwyg/settings/global
- * Common settings for all WYSIWYG editors throughout Stud.IP.
- * wysiwyg/settings/seminars
- * Settings of all seminars.
- * Listed seminars depend on access level:
- * root => full access to all seminars
- * dozent, tutor of a seminar => full access to those seminars
- * others => read-access to seminars they are a member of
- * wysiwyg/settings/seminars/ID
- * Settings of the seminar with the given ID.
- * Access permissions: see above.
- * wysiwyg/settings/seminars/ID/users
- * Seminar's settings for all its users.
- * Access permissions: see above.
- * wysiwyg/settings/seminars/ID/users/ID
- * Seminar's settings for a specific user in that seminar.
- * Access permissions: see above.
- * wysiwyg/settings/users
- * Settings of all users.
- * Listed users depend on access level:
- * root => full access to all users
- * not root => full access to own settings only
- * wysiwyg/settings/users/ID
- * Settings of the user with the given ID.
- * Access permissions: see above.
- * wysiwyg/settings/users/ID/seminars
- * User's settings for all seminars the user is a member of.
- * Access permissions: see above.
- * wysiwyg/settings/users/ID/seminars/ID
- * User's settings for the seminar with the given ID.
- * Access permissions: see above.
- *
- * The difference of seminar's settings for a user and user's settings
- * for a seminar:
- *
- * A seminar's teacher may want to set the upload directory for each user
- * to a separate one, which should not be overwritable by a user, in
- * order to make sure that users cannot see other users uploads (there
- * are other ways to do this, but it's just an example).
- *
- * A user might want to have a specific upload directory in order to
- * collaborate better with other users in the same seminar (e.g. when
- * students form a study group).
- *
- * For example the ELMO module needs such settings.
- *
- * JSON scheme for access to wysiwyg/settings:
- * {
- * "global": { "SETTING": ..., ... },
- * "seminars": {
- * "ID": {
- * "users": { "ID": {...}, ... },
- * "SETTING": ...,
- * ...
- * },
- * "ID": {...},
- * ...
- * },
- * "users": {
- * "ID": {
- * "seminars": { "ID": {...}, ... },
- * "SETTING": ...,
- * ...
- * },
- * "ID": {...},
- * ...
- * }
- * }
- *
- * When accessing a sub-resource that resource's branch of the JSON scheme
- * will be returned.
- */
- public function settings_action()
- {
- try {
- if (!Request::isGet() && !Request::isPut()) {
- throw new WysiwygHttpExceptionMethodNotAllowed(
- _('Nur die HTTP-Methoden GET und PUT sind erlaubt.')
- );
- }
-
- $arguments = func_get_args();
- $settingsGroup = array_shift($arguments);
-
- if (Request::isPut()) {
- $this->setSettings($settingsGroup, $arguments);
- }
- $this->render_json($this->objectToArray(
- $this->getSettings($settingsGroup, $arguments)
- ));
- } catch (WysiwygHttpException $e) {
- $this->set_status($e->getCode());
- $this->set_content_type('text/plain; charset=utf-8');
- $this->render_text($e->getMessage());
- }
- }
-
- public function a11yhelp_action()
- {
- // nothing to do
- PageLayout::setTitle(_('Hilfe zur Bedienung des Editors'));
- }
-
- /**
- * Set WYSIWYG settings for a specific group.
- *
- * Dummy implementation: Currently only accepts setting the
- * disabled flag for wysiwyg/settings/users/current.
- *
- * The HTTP request's body must contain a JSON document of the form:
- * {
- * "disabled": true | false
- * }
- *
- * If the JSON contains other additional values they will be ignored.
- *
- * @param string $group Must be set to 'users'.
- * @param array $arguments Must contain exactly one entry: 'current'.
- */
- private function setSettings($group, $arguments) {
- $user = array_shift($arguments);
- if ($group !== 'users' || $user !== 'current') {
- throw new WysiwygHttpExceptionForbidden(
- _('Zugriff verweigert')
- );
- }
-
- $subgroup = array_shift($arguments);
- if (($subgroup !== null && $subgroup !== '') || count($arguments) > 0) {
- throw new WysiwygHttpExceptionNotFound(
- _('Die Benutzereinstellungen enthalten keine Untergruppen.')
- );
- }
-
- $data = json_decode(file_get_contents('php://input'));
- if (isset($data->disabled)) {
- $config = $GLOBALS['user']->cfg;
- //$config->WYSIWYG_DISABLED = (boolean)$data->disabled;
- $config->store(
- 'WYSIWYG_DISABLED',
- (boolean)$data->disabled
- );
- } else {
- throw new WysiwygHttpExceptionBadRequest(
- _('Die Anfrage enthält ungültige Werte.')
- );
- }
- // all unknown parameters are ignored
- }
-
- /**
- * Return WYSIWYG settings for a specific group.
- *
- * @param $group string The requested settings group: 'user', 'seminar',
- * 'global' or 'all'. If the group is set to 'all' then all levels will be
- * returned. If the group is unknown an error will be thrown.
- *
- * @return object Settings for the requested group.
- */
- private function getSettings($group, $arguments)
- {
- switch ($group) {
- case null: return $this->getAllSettings();
- case 'global': return $this->getGlobalSettings($arguments);
- case 'users': return $this->getUserSettings($arguments);
- }
- throw new WysiwygHttpExceptionNotFound(
- _('Die angeforderte Gruppe von Einstellungen existiert nicht.')
- );
- }
-
- /**
- * Return all WYSIWYG settings.
- *
- * Returns an object with properties named after settings groups,
- * containing the respective group's settings. For example:
- *
- * {
- * "global": {...}
- * "seminars": {...},
- * "users": {...},
- * }
- *
- * @return object All settings.
- */
- private function getAllSettings()
- {
- $settings = new stdClass;
- $settings->global = $this->getGlobalSettings();
- $settings->users = $this->getUserSettings();
- return $settings;
- }
-
- /**
- * Return global WYSIWYG settings.
- *
- * @return object Global settings.
- */
- private function getGlobalSettings($arguments = [])
- {
- $subgroup = array_shift($arguments);
- if (($subgroup !== null && $subgroup !== '') || count($arguments) > 0) {
- throw new WysiwygHttpExceptionNotFound(_('Die globalen Einstellungen enthalten keine Untergruppen.'));
- }
- $settings = new stdClass;
- $settings->disabled = !\Config::get()->WYSIWYG;
- $settings->upload = new stdClass;
- $settings->upload->permission = self::UPLOAD_PERMISSION;
- $settings->upload->folder = new stdClass;
- $settings->upload->folder->name = self::FOLDER_NAME;
- $settings->upload->folder->description = self::FOLDER_DESCRIPTION;
- return $settings;
- }
-
- /**
- * Return current user's WYSIWYG settings.
- *
- * @return object User's settings.
- */
- private function getUserSettings($arguments = [])
- {
- // NOTE simulate a list of users containing only the current
- // user until this is implemented correctly
- $settings = new stdClass;
- $settings->current = $this->getCurrentUserSettings();
-
- $userId = array_shift($arguments);
- if ($userId === null || $userId === '' && count($arguments) === 0) {
- return $settings;
- }
-
- if ($userId === 'current') {
- $subgroup = array_shift($arguments);
- if (($subgroup !== null && $subgroup !== '') || count($arguments) > 0) {
- throw new WysiwygHttpExceptionNotFound(
- _('Die Benutzereinstellungen enthalten keine Untergruppen.')
- );
- }
- return $settings->current;
- }
-
- throw new WysiwygHttpExceptionForbidden(
- _('Zugriff verweigert.')
- );
- }
-
- /**
- * Return current user's WYSIWYG settings.
- *
- * @return object User's settings.
- */
- public function getCurrentUserSettings()
- {
- $config = $GLOBALS['user']->cfg;
- $settings = new stdClass;
- $settings->disabled = (boolean)$config->WYSIWYG_DISABLED;
- return $settings;
- }
-
- /**
- * Recursively convert objects to associative arrays.
- *
- * Workaround for broken StudipController::render_json.
- *
- * If the data is neither object nor array then it will be
- * returned unchanged.
- *
- * @param mixed $data Data to convert.
- *
- * @return mixed Converted data.
- */
- private function objectToArray($data)
- {
- if (gettype($data) === 'object') {
- $data = (array)$data;
- }
- if (gettype($data) === 'array') {
- foreach ($data as $key => $value) {
- $data[$key] = $this->objectToArray($value);
- }
- }
- return $data;
- }
}
diff --git a/resources/assets/javascripts/chunks/wysiwyg.js b/resources/assets/javascripts/chunks/wysiwyg.js
index bc3f172..0ac0e4d 100644
--- a/resources/assets/javascripts/chunks/wysiwyg.js
+++ b/resources/assets/javascripts/chunks/wysiwyg.js
@@ -53,7 +53,6 @@ import Mathematics from 'ckeditor5-math/src/math';
import StudipA11YDialog, { updateVoiceLabel } from '../cke/studip-a11y-dialog/a11y-dialog.js';
import StudipBlockQuote from '../cke/studip-quote/StudipBlockQuote.js';
import StudipUpload from '../cke/StudipUpload.js';
-import { StudipSettings } from '../cke/StudipSettings.js';
import StudipWikiLink from '../cke/wiki-link/wiki-link.js';
import SpecialCharactersEmojiFood from '../cke/special_characters/SpecialCharactersEmojiFood.js';
import SpecialCharactersEmojiNature from '../cke/special_characters/SpecialCharactersEmojiNature.js';
@@ -124,7 +123,6 @@ ClassicEditor.builtinPlugins = [
Underline,
FileRepository,
StudipA11YDialog,
- StudipSettings,
StudipWikiLink,
];
@@ -198,7 +196,6 @@ ClassicEditor.defaultConfig = {
'outdent',
'indent',
'|',
- 'studipSettings',
'open-a11y-dialog',
],
shouldNotGroupWhenFull: true,
diff --git a/resources/assets/javascripts/cke/StudipSettings.js b/resources/assets/javascripts/cke/StudipSettings.js
deleted file mode 100644
index f498a1e..0000000
--- a/resources/assets/javascripts/cke/StudipSettings.js
+++ /dev/null
@@ -1,138 +0,0 @@
-import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
-import { createDropdown, ButtonView, View } from 'ckeditor5/src/ui';
-import { $gettext } from '../lib/gettext.js';
-
-const settings = {
- url: STUDIP.URLHelper.getURL('dispatch.php/wysiwyg/settings/users/current'),
- save: function (data) {
- return $.ajax({
- url: this.url,
- type: 'PUT',
- contentType: 'application/json',
- data: JSON.stringify(data),
- });
- },
-};
-
-const gearsIcon =
- '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 54 54"><path d="M50.58,22.76l-.95-.4a3.12,3.12,0,0,1,0-5.8l.95-.41h0a.69.69,0,0,0,.37-.89h0l-.7-1.69-1.13-2.75A.71.71,0,0,0,49,10.6a.67.67,0,0,0-.74-.15h0l-.95.39a3.05,3.05,0,0,1-3.43-.65,3.15,3.15,0,0,1-.65-3.45l.4-1a.69.69,0,0,0-.36-.89L38.82,3.05a.67.67,0,0,0-.88.37l-.41,1a3.08,3.08,0,0,1-5.75,0l-.41-1a.68.68,0,0,0-.89-.37L26.07,4.9a.68.68,0,0,0-.37.89l.39,1A3.1,3.1,0,0,1,22,10.85h0l-.95-.4a.68.68,0,0,0-.89.37l-1.83,4.44a.69.69,0,0,0,.37.89l1,.41a3.12,3.12,0,0,1,0,5.79l-.95.42a.69.69,0,0,0-.38.89l1.83,4.44a.7.7,0,0,0,.89.37l1-.4a3.05,3.05,0,0,1,3.42.65,3.12,3.12,0,0,1,.64,3.45h0l-.4,1a.68.68,0,0,0,.37.89l4.41,1.84a.68.68,0,0,0,.89-.36l.4-1a3.08,3.08,0,0,1,5.76,0l.4,1a.68.68,0,0,0,.89.36L43.23,34a.68.68,0,0,0,.37-.89l-.4-1h0a3.15,3.15,0,0,1,.65-3.45,3.06,3.06,0,0,1,3.42-.65h0l.95.4a.69.69,0,0,0,.89-.37L51,23.65A.69.69,0,0,0,50.58,22.76ZM36.89,24.9a5.84,5.84,0,0,1-7.65-3.19A5.91,5.91,0,0,1,32.41,14a5.84,5.84,0,0,1,7.65,3.18A5.91,5.91,0,0,1,36.89,24.9Z"/><path d="M25.82,37.11H25.1a2.14,2.14,0,0,1-2-1.33,2.21,2.21,0,0,1,.5-2.41l.51-.51a.5.5,0,0,0,0-.68l-2.36-2.38a.46.46,0,0,0-.67,0l-.52.52a2.16,2.16,0,0,1-2.39.5,2.19,2.19,0,0,1-1.33-2.06V28a.47.47,0,0,0-.47-.48H13a.48.48,0,0,0-.48.47v.73a2.16,2.16,0,0,1-3.72,1.56h0l-.51-.52a.46.46,0,0,0-.67,0L5.24,32.17a.48.48,0,0,0,0,.68l.5.51a2.19,2.19,0,0,1,.5,2.41,2.14,2.14,0,0,1-2,1.33H3.48a.48.48,0,0,0-.48.48V41a.48.48,0,0,0,.48.48H4.2a2.15,2.15,0,0,1,2,1.34,2.17,2.17,0,0,1-.5,2.4h0l-.51.52a.48.48,0,0,0,0,.67l2.36,2.38a.46.46,0,0,0,.67,0l.52-.51a2.16,2.16,0,0,1,2.39-.5A2.18,2.18,0,0,1,12.5,49.8v.72h0A.49.49,0,0,0,13,51h3.34a.47.47,0,0,0,.48-.48h0V49.8a2.18,2.18,0,0,1,1.33-2.06,2.16,2.16,0,0,1,2.39.5l.51.52a.46.46,0,0,0,.67,0l2.37-2.38a.48.48,0,0,0,0-.67l-.51-.53a2.19,2.19,0,0,1-.5-2.4,2.15,2.15,0,0,1,2-1.34h.72A.48.48,0,0,0,26.3,41V37.59A.47.47,0,0,0,25.82,37.11ZM14.65,43.39a4.12,4.12,0,1,1,4.09-4.12A4.1,4.1,0,0,1,14.65,43.39Z"/></svg>';
-
-export class StudipSettings extends Plugin {
- init() {
- this.editor.ui.componentFactory.add('studipSettings', (locale) => {
- const dropdownView = createDropdown(locale);
-
- dropdownView.buttonView.set({
- label: $gettext('Stud.IP Einstellungen'),
- icon: gearsIcon,
- tooltip: true,
- });
-
- dropdownView.render();
-
- const studipSettingsView = new StudipSettingsView(locale);
- dropdownView.panelView.children.add(studipSettingsView);
- studipSettingsView.on('wysiwyg:change', (eventInfo, disabled) => {
- this._save(studipSettingsView, disabled).then(() => (dropdownView.isOpen = false));
- });
-
- return dropdownView;
- });
- }
-
- _save(view, disabled) {
- view.functional = false;
-
- return settings
- .save({ disabled })
- .fail(function (xhr) {
- console.error("couldn't save changes");
- })
- .always(() => {
- view.functional = true;
- });
- }
-}
-
-class StudipSettingsView extends View {
- constructor(locale) {
- super(locale);
-
- const bind = this.bindTemplate;
- this.set({
- checked: false,
- functional: true,
- });
-
- const button = createButton();
- this.button = button;
- button.on('execute', () => {
- this.fire('wysiwyg:change', this.checked);
- });
-
- this.on('checking', (...args) => {
- this.checked = !this.checked;
- });
-
- this.setTemplate({
- tag: 'form',
- attributes: {
- class: ['default ck-studip-settings-form'],
- tabindex: '-1',
- style: 'max-width: 20em; padding: 1em;',
- },
- children: [createCheckbox(), createHelpText(), button],
- });
-
- function createCheckbox() {
- return {
- tag: 'label',
- children: [
- {
- tag: 'input',
- attributes: {
- id: 'disable',
- type: 'checkbox',
- checked: bind.to('checked'),
- style: 'margin-right: 0.5em'
- },
- on: {
- change: bind.to('checking'),
- },
- },
- {
- text: $gettext('WYSIWYG Editor ausschalten'),
- },
- ],
- };
- }
-
- function createHelpText() {
- return {
- tag: 'p',
- attributes: {
- style: 'white-space: normal; font-size: 1em; line-height: 1.5em; margin-bottom: 1em;',
- },
- children: [
- {
- text: $gettext(
- 'Mit dieser Einstellung können Sie den WYSIWYG Editor ausschalten. Dadurch müssen Sie gegebenenfalls Texte in HTML schreiben. Der Editor wird erst vollständig entfernt, wenn die Seite neu geladen wird.'
- ),
- },
- ],
- };
- }
-
- function createButton() {
- const button = new ButtonView(locale);
-
- button.set({
- label: $gettext('Speichern'),
- withText: true,
- isEnabled: bind.to('functional'),
- });
-
- return button;
- }
- }
-}