MDL-29701 editor: mform disableif doesn't work on editor element
authorJake Hau <phuchau1509@gmail.com>
Tue, 17 Jul 2018 03:24:09 +0000 (10:24 +0700)
committerJake Hau <phuchau1509@gmail.com>
Thu, 19 Jul 2018 04:38:26 +0000 (11:38 +0700)
12 files changed:
lib/editor/atto/tests/behat/disablecontrol.feature [new file with mode: 0644]
lib/editor/atto/yui/build/moodle-editor_atto-editor/moodle-editor_atto-editor-debug.js
lib/editor/atto/yui/build/moodle-editor_atto-editor/moodle-editor_atto-editor-min.js
lib/editor/atto/yui/build/moodle-editor_atto-editor/moodle-editor_atto-editor.js
lib/editor/atto/yui/src/editor/js/editor.js [changed mode: 0644->0755]
lib/editor/tests/fixtures/disable_control_example.php [new file with mode: 0644]
lib/editor/tests/fixtures/editor_form.php [new file with mode: 0644]
lib/editor/textarea/lib.php [changed mode: 0644->0755]
lib/editor/textarea/tests/behat/disablecontrol.feature [new file with mode: 0644]
lib/editor/tinymce/module.js [changed mode: 0644->0755]
lib/editor/tinymce/tests/behat/disablecontrol.feature [new file with mode: 0644]
lib/form/form.js [changed mode: 0644->0755]

diff --git a/lib/editor/atto/tests/behat/disablecontrol.feature b/lib/editor/atto/tests/behat/disablecontrol.feature
new file mode 100644 (file)
index 0000000..491e6e1
--- /dev/null
@@ -0,0 +1,45 @@
+@editor @editor_atto @atto @editor_moodleform
+Feature: Atto with enable/disable function.
+  In order to test enable/disable function
+  I create a sample page to test this feature.
+  As a user
+  I need to enable/disable all buttons/plugins and content of editor if "enable/disable" feature enabled.
+
+  Background:
+    Given the following "courses" exist:
+      | fullname | shortname | format |
+      | Course 1 | C1        | topics |
+    And the following "activities" exist:
+      | activity | name | intro                                                                                              | course | idnumber |
+      | label    | L1   | <a href="../lib/editor/tests/fixtures/disable_control_example.php">Control Enable/Disable Atto</a> | C1     | label1   |
+    And I log in as "admin"
+    And I am on "Course 1" course homepage
+    And I follow "Control Enable/Disable Atto"
+
+  @javascript
+  Scenario: Check disable Atto editor.
+    When I set the field "mycontrol" to "Disable"
+    Then the "disabled" attribute of "button.atto_collapse_button" "css_element" should contain "disabled"
+    And the "disabled" attribute of "button.atto_title_button" "css_element" should contain "disabled"
+    And the "disabled" attribute of "button.atto_bold_button_bold" "css_element" should contain "disabled"
+    And the "disabled" attribute of "button.atto_italic_button_italic" "css_element" should contain "disabled"
+    And the "disabled" attribute of "button.atto_unorderedlist_button_insertUnorderedList" "css_element" should contain "disabled"
+    And the "disabled" attribute of "button.atto_orderedlist_button_insertOrderedList" "css_element" should contain "disabled"
+    And the "disabled" attribute of "button.atto_link_button" "css_element" should contain "disabled"
+    And the "disabled" attribute of "button.atto_link_button_unlink" "css_element" should contain "disabled"
+    And the "disabled" attribute of "button.atto_image_button" "css_element" should contain "disabled"
+    And the "contenteditable" attribute of "div#id_myeditoreditable" "css_element" should contain "false"
+
+  @javascript
+  Scenario: Check enable Atto editor.
+    When I set the field "mycontrol" to "Enable"
+    Then "button.atto_collapse_button[disabled]" "css_element" should not exist
+    And "button.atto_title_button[disabled]" "css_element" should not exist
+    And "button.atto_bold_button_bold[disabled]" "css_element" should not exist
+    And "button.atto_italic_button_italic[disabled]" "css_element" should not exist
+    And "button.atto_unorderedlist_button_insertUnorderedList[disabled]" "css_element" should not exist
+    And "button.atto_orderedlist_button_insertOrderedList[disabled]" "css_element" should not exist
+    And "button.atto_link_button[disabled]" "css_element" should not exist
+    And "button.atto_link_button_unlink[disabled]" "css_element" should not exist
+    And "button.atto_image_button[disabled]" "css_element" should not exist
+    And the "contenteditable" attribute of "div#id_myeditoreditable" "css_element" should contain "true"
index 90e0996..9fce41e 100644 (file)
Binary files a/lib/editor/atto/yui/build/moodle-editor_atto-editor/moodle-editor_atto-editor-debug.js and b/lib/editor/atto/yui/build/moodle-editor_atto-editor/moodle-editor_atto-editor-debug.js differ
index 22df82b..0bb1434 100644 (file)
Binary files a/lib/editor/atto/yui/build/moodle-editor_atto-editor/moodle-editor_atto-editor-min.js and b/lib/editor/atto/yui/build/moodle-editor_atto-editor/moodle-editor_atto-editor-min.js differ
index 1b88fea..cf12f6c 100644 (file)
Binary files a/lib/editor/atto/yui/build/moodle-editor_atto-editor/moodle-editor_atto-editor.js and b/lib/editor/atto/yui/build/moodle-editor_atto-editor/moodle-editor_atto-editor.js differ
old mode 100644 (file)
new mode 100755 (executable)
index a28e936..b846bcd
@@ -225,6 +225,12 @@ Y.extend(Editor, Y.Base, {
         // Hide the old textarea.
         this.textarea.hide();
 
+        // Set up custom event for editor updated.
+        Y.mix(Y.Node.DOM_EVENTS, {'form:editorUpdated': true});
+        this.textarea.on('form:editorUpdated', function() {
+            this.updateEditorState();
+        }, this);
+
         // Copy the text to the contenteditable div.
         this.updateFromTextArea();
 
@@ -387,6 +393,20 @@ Y.extend(Editor, Y.Base, {
         }
     },
 
+    /**
+     * Update the state of the editor.
+     */
+    updateEditorState: function() {
+        var disabled = this.textarea.hasAttribute('readonly'),
+            editorfield = Y.one('#' + this.get('elementid') + 'editable');
+        // Enable/Disable all plugins.
+        this._setPluginState(!disabled);
+        // Enable/Disable content of editor.
+        if (editorfield) {
+            editorfield.setAttribute('contenteditable', !disabled);
+        }
+    },
+
     /**
      * Register an event handle for disposal in the destructor.
      *
diff --git a/lib/editor/tests/fixtures/disable_control_example.php b/lib/editor/tests/fixtures/disable_control_example.php
new file mode 100644 (file)
index 0000000..752c0bc
--- /dev/null
@@ -0,0 +1,47 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Demonstrates use of editor with enable/disable function.
+ *
+ * This fixture is only used by the Behat test.
+ *
+ * @package core_editor
+ * @copyright 2018 Jake Hau <phuchau1509@gmail.com>
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+require(__DIR__ . '/../../../../config.php');
+require_once('./editor_form.php');
+
+// Behat test fixture only.
+defined('BEHAT_SITE_RUNNING') || die('Only available on Behat test server');
+
+// Require login.
+require_login();
+
+$PAGE->set_url('/lib/editor/tests/fixtures/disable_control_example.php');
+$PAGE->set_context(context_system::instance());
+
+// Create moodle form.
+$mform = new editor_form();
+
+echo $OUTPUT->header();
+
+// Display moodle form.
+$mform->display();
+
+echo $OUTPUT->footer();
diff --git a/lib/editor/tests/fixtures/editor_form.php b/lib/editor/tests/fixtures/editor_form.php
new file mode 100644 (file)
index 0000000..645728a
--- /dev/null
@@ -0,0 +1,62 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Provides {@link lib/editor/tests/fixtures/editor_form} class.
+ *
+ * @package core_editor
+ * @copyright 2018 Jake Hau <phuchau1509@gmail.com>
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+global $CFG;
+require_once($CFG->libdir.'/formslib.php');
+
+/**
+ * Class editor_form
+ *
+ * Demonstrates use of editor with disabledIf function.
+ * This fixture is only used by the Behat test.
+ *
+ * @package core_editor
+ * @copyright 2018 Jake Hau <phuchau1509@gmail.com>
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class editor_form extends moodleform {
+
+    /**
+     * Form definition. Abstract method - always override!
+     */
+    protected function definition() {
+        $mform = $this->_form;
+        $editoroptions = $this->_customdata['editoroptions'];
+
+        // Add header.
+        $mform->addElement('header', 'myheader', 'Editor in Moodle form');
+
+        // Add element control.
+        $mform->addElement('select', 'mycontrol', 'My control', ['Enable', 'Disable']);
+
+        // Add editor.
+        $mform->addElement('editor', 'myeditor', 'My Editor', null, $editoroptions);
+        $mform->setType('myeditor', PARAM_RAW);
+
+        // Add control.
+        $mform->disabledIf('myeditor', 'mycontrol', 'eq', 1);
+    }
+}
old mode 100644 (file)
new mode 100755 (executable)
diff --git a/lib/editor/textarea/tests/behat/disablecontrol.feature b/lib/editor/textarea/tests/behat/disablecontrol.feature
new file mode 100644 (file)
index 0000000..0d82331
--- /dev/null
@@ -0,0 +1,31 @@
+@editor @editor_textarea @texarea @editor_moodleform
+Feature: Text area with enable/disable function.
+  In order to test enable/disable function
+  I set default editor is Text area editor, and I create a sample page to test this feature.
+  As a user
+  I need to enable/disable content of editor if "enable/disable" feature enabled.
+
+  Background:
+    Given the following "courses" exist:
+      | fullname | shortname | format |
+      | Course 1 | C1        | topics |
+    And the following "activities" exist:
+      | activity | name | intro                                                                                                   | course | idnumber |
+      | label    | L1   | <a href="../lib/editor/tests/fixtures/disable_control_example.php">Control Enable/Disable Text area</a> | C1     | label1   |
+    And I log in as "admin"
+    And I follow "Preferences" in the user menu
+    And I follow "Editor preferences"
+    And I set the field "Text editor" to "Plain text area"
+    And I press "Save changes"
+    And I am on "Course 1" course homepage
+    And I follow "Control Enable/Disable Text area"
+
+  @javascript
+  Scenario: Check disable Text area editor.
+    When I set the field "mycontrol" to "Disable"
+    Then the "readonly" attribute of "textarea#id_myeditor" "css_element" should contain "readonly"
+
+  @javascript
+  Scenario: Check enable Text area editor.
+    When I set the field "mycontrol" to "Enable"
+    Then "textarea#id_myeditor[readonly]" "css_element" should not exist
old mode 100644 (file)
new mode 100755 (executable)
index b7b7904..0bcfd47
@@ -96,6 +96,10 @@ M.editor_tinymce.init_editor = function(Y, editorid, options) {
     if (item) {
         item.parentNode.removeChild(item);
     }
+
+    document.getElementById(editorid).addEventListener('form:editorUpdated', function() {
+        M.editor_tinymce.updateEditorState(editorid);
+    });
 };
 
 M.editor_tinymce.init_callback = function() {
@@ -110,6 +114,25 @@ M.editor_tinymce.toggle = function(id) {
     tinyMCE.execCommand('mceToggleEditor', false, id);
 };
 
+/**
+ * Update the state of the editor.
+ * @param {String} id
+ */
+M.editor_tinymce.updateEditorState = function(id) {
+    var instance = window.tinyMCE.get(id),
+        content = instance.getBody(),
+        controls = instance.controlManager.controls,
+        disabled = instance.getElement().readOnly;
+    // Enable/Disable all plugins.
+    for (var key in controls) {
+        if (controls.hasOwnProperty(key)) {
+            controls[key].setDisabled(disabled);
+        }
+    }
+    // Enable/Disable body content.
+    content.setAttribute('contenteditable', !disabled);
+};
+
 M.editor_tinymce.filepicker_callback = function(args) {
 };
 
diff --git a/lib/editor/tinymce/tests/behat/disablecontrol.feature b/lib/editor/tinymce/tests/behat/disablecontrol.feature
new file mode 100644 (file)
index 0000000..d8cc6da
--- /dev/null
@@ -0,0 +1,55 @@
+@editor @editor_tinymce @tinymce @editor_moodleform
+Feature: Tinymce with enable/disable function.
+  In order to test enable/disable function
+  I set default editor is Tinymce editor, and I create a sample page to test this feature.
+  As a user
+  I need to enable/disable all buttons/plugins and content of editor if "enable/disable" feature enabled.
+
+  Background:
+    Given the following "courses" exist:
+      | fullname | shortname | format |
+      | Course 1 | C1        | topics |
+    And the following "activities" exist:
+      | activity | name | intro                                                                                                 | course | idnumber |
+      | label    | L1   | <a href="../lib/editor/tests/fixtures/disable_control_example.php">Control Enable/Disable Tinymce</a> | C1     | label1   |
+    And I log in as "admin"
+    And I follow "Preferences" in the user menu
+    And I follow "Editor preferences"
+    And I set the field "Text editor" to "TinyMCE HTML editor"
+    And I press "Save changes"
+    And I am on "Course 1" course homepage
+    And I follow "Control Enable/Disable Tinymce"
+
+  @javascript
+  Scenario: Check disable Tinymce editor.
+    When I click on "option[value=1]" "css_element" in the "select#id_mycontrol" "css_element"
+    Then the "class" attribute of "a#id_myeditor_pdw_toggle" "css_element" should contain "mceButtonDisabled"
+    And the "class" attribute of "table#id_myeditor_formatselect" "css_element" should contain "mceListBoxDisabled"
+    And the "class" attribute of "a#id_myeditor_bold" "css_element" should contain "mceButtonDisabled"
+    And the "class" attribute of "a#id_myeditor_italic" "css_element" should contain "mceButtonDisabled"
+    And the "class" attribute of "a#id_myeditor_bullist" "css_element" should contain "mceButtonDisabled"
+    And the "class" attribute of "a#id_myeditor_numlist" "css_element" should contain "mceButtonDisabled"
+    And the "class" attribute of "a#id_myeditor_link" "css_element" should contain "mceButtonDisabled"
+    And the "class" attribute of "a#id_myeditor_unlink" "css_element" should contain "mceButtonDisabled"
+    And the "class" attribute of "a#id_myeditor_moodlenolink" "css_element" should contain "mceButtonDisabled"
+    And the "class" attribute of "a#id_myeditor_image" "css_element" should contain "mceButtonDisabled"
+    And the "class" attribute of "a#id_myeditor_moodlemedia" "css_element" should contain "mceButtonDisabled"
+    And I switch to "id_myeditor_ifr" iframe
+    And the "contenteditable" attribute of "body" "css_element" should contain "false"
+
+  @javascript
+  Scenario: Check enable Tinymce editor.
+    When I click on "option[value=0]" "css_element" in the "select#id_mycontrol" "css_element"
+    Then the "class" attribute of "a#id_myeditor_pdw_toggle" "css_element" should contain "mceButtonEnabled"
+    And the "class" attribute of "table#id_myeditor_formatselect" "css_element" should contain "mceListBoxEnabled"
+    And the "class" attribute of "a#id_myeditor_bold" "css_element" should contain "mceButtonEnabled"
+    And the "class" attribute of "a#id_myeditor_italic" "css_element" should contain "mceButtonEnabled"
+    And the "class" attribute of "a#id_myeditor_bullist" "css_element" should contain "mceButtonEnabled"
+    And the "class" attribute of "a#id_myeditor_numlist" "css_element" should contain "mceButtonEnabled"
+    And the "class" attribute of "a#id_myeditor_link" "css_element" should contain "mceButtonDisabled"
+    And the "class" attribute of "a#id_myeditor_unlink" "css_element" should contain "mceButtonDisabled"
+    And the "class" attribute of "a#id_myeditor_moodlenolink" "css_element" should contain "mceButtonDisabled"
+    And the "class" attribute of "a#id_myeditor_image" "css_element" should contain "mceButtonEnabled"
+    And the "class" attribute of "a#id_myeditor_moodlemedia" "css_element" should contain "mceButtonEnabled"
+    And I switch to "id_myeditor_ifr" iframe
+    And the "contenteditable" attribute of "body" "css_element" should contain "true"
old mode 100644 (file)
new mode 100755 (executable)
index 50f5960..1c6dacc
@@ -250,8 +250,10 @@ if (typeof M.form.dependencyManager === 'undefined') {
          * @param {Boolean} disabled True to disable, false to enable.
          */
         _disableElement: function(name, disabled) {
-            var els = this.elementsByName(name);
-            var filepicker = this.isFilePicker(name);
+            var els = this.elementsByName(name),
+                filepicker = this.isFilePicker(name),
+                editors = this.get('form').all('.fitem [data-fieldtype="editor"] textarea[name="' + name + '[text]"]');
+
             els.each(function(node) {
                 if (disabled) {
                     node.setAttribute('disabled', 'disabled');
@@ -271,6 +273,14 @@ if (typeof M.form.dependencyManager === 'undefined') {
                     }
                 }
             });
+            editors.each(function(editor) {
+                if (disabled) {
+                    editor.setAttribute('readonly', 'readonly');
+                } else {
+                    editor.removeAttribute('readonly', 'readonly');
+                }
+                editor.getDOMNode().dispatchEvent(new Event('form:editorUpdated'));
+            });
         },
         /**
          * Hides or shows all form elements with the given name.