mirror of
https://github.com/moodle/moodle.git
synced 2025-03-22 08:30:04 +01:00
Merge branch 'MDL-76474-401-2' of https://github.com/HuongNV13/moodle into MOODLE_401_STABLE
This commit is contained in:
commit
d24c201b6d
2
lib/editor/tiny/amd/build/options.min.js
vendored
2
lib/editor/tiny/amd/build/options.min.js
vendored
@ -1,3 +1,3 @@
|
||||
define("editor_tiny/options",["exports"],(function(_exports){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.register=_exports.getPluginOptionName=_exports.getMoodleLang=_exports.getInitialPluginConfiguration=_exports.getFilepickers=_exports.getFilePicker=_exports.getDraftItemId=_exports.getCurrentLanguage=_exports.getContextId=void 0;_exports.register=(editor,options)=>{const registerOption=editor.options.register,setOption=editor.options.set;registerOption("moodle:contextid",{processor:"number",default:0}),setOption("moodle:contextid",options.context),registerOption("moodle:filepickers",{processor:"object",default:{}}),setOption("moodle:filepickers",options.filepicker),registerOption("moodle:draftitemid",{processor:"number",default:0}),setOption("moodle:draftitemid",options.draftitemid),registerOption("moodle:currentLanguage",{processor:"string",default:"en"}),setOption("moodle:currentLanguage",options.currentLanguage),registerOption("moodle:language",{processor:"object",default:{}}),setOption("moodle:language",options.language)};_exports.getContextId=editor=>editor.options.get("moodle:contextid");_exports.getDraftItemId=editor=>editor.options.get("moodle:draftitemid");const getFilepickers=editor=>editor.options.get("moodle:filepickers");_exports.getFilepickers=getFilepickers;_exports.getFilePicker=(editor,type)=>getFilepickers(editor)[type];_exports.getMoodleLang=editor=>editor.options.get("moodle:language");_exports.getCurrentLanguage=editor=>editor.options.get("moodle:currentLanguage");_exports.getInitialPluginConfiguration=options=>{const config={};return Object.entries(options.plugins).forEach((_ref=>{var _pluginConfig$config;let[pluginName,pluginConfig]=_ref;Object.entries(null!==(_pluginConfig$config=pluginConfig.config)&&void 0!==_pluginConfig$config?_pluginConfig$config:{}).forEach((_ref2=>{let[optionName,value]=_ref2;config[getPluginOptionName(pluginName,optionName)]=value}))})),config};const getPluginOptionName=(pluginName,optionName)=>"".concat(pluginName,":").concat(optionName);_exports.getPluginOptionName=getPluginOptionName}));
|
||||
define("editor_tiny/options",["exports"],(function(_exports){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.registerPlaceholderSelectors=_exports.register=_exports.getPluginOptionName=_exports.getPlaceholderSelectors=_exports.getMoodleLang=_exports.getInitialPluginConfiguration=_exports.getFilepickers=_exports.getFilePicker=_exports.getDraftItemId=_exports.getCurrentLanguage=_exports.getContextId=void 0;_exports.register=(editor,options)=>{const registerOption=editor.options.register,setOption=editor.options.set;registerOption("moodle:contextid",{processor:"number",default:0}),setOption("moodle:contextid",options.context),registerOption("moodle:filepickers",{processor:"object",default:{}}),setOption("moodle:filepickers",options.filepicker),registerOption("moodle:draftitemid",{processor:"number",default:0}),setOption("moodle:draftitemid",options.draftitemid),registerOption("moodle:currentLanguage",{processor:"string",default:"en"}),setOption("moodle:currentLanguage",options.currentLanguage),registerOption("moodle:language",{processor:"object",default:{}}),setOption("moodle:language",options.language),registerOption("moodle:placeholderSelectors",{processor:"array",default:[]}),setOption("moodle:placeholderSelectors",options.placeholderSelectors)};_exports.getContextId=editor=>editor.options.get("moodle:contextid");_exports.getDraftItemId=editor=>editor.options.get("moodle:draftitemid");const getFilepickers=editor=>editor.options.get("moodle:filepickers");_exports.getFilepickers=getFilepickers;_exports.getFilePicker=(editor,type)=>getFilepickers(editor)[type];_exports.getMoodleLang=editor=>editor.options.get("moodle:language");_exports.getCurrentLanguage=editor=>editor.options.get("moodle:currentLanguage");_exports.getInitialPluginConfiguration=options=>{const config={};return Object.entries(options.plugins).forEach((_ref=>{var _pluginConfig$config;let[pluginName,pluginConfig]=_ref;Object.entries(null!==(_pluginConfig$config=pluginConfig.config)&&void 0!==_pluginConfig$config?_pluginConfig$config:{}).forEach((_ref2=>{let[optionName,value]=_ref2;config[getPluginOptionName(pluginName,optionName)]=value}))})),config};const getPluginOptionName=(pluginName,optionName)=>"".concat(pluginName,":").concat(optionName);_exports.getPluginOptionName=getPluginOptionName;const getPlaceholderSelectors=editor=>editor.options.get("moodle:placeholderSelectors");_exports.getPlaceholderSelectors=getPlaceholderSelectors;_exports.registerPlaceholderSelectors=(editor,selectors)=>{if(selectors.length){let existingData=getPlaceholderSelectors(editor);existingData=existingData.concat(selectors),editor.options.set("moodle:placeholderSelectors",existingData)}}}));
|
||||
|
||||
//# sourceMappingURL=options.min.js.map
|
File diff suppressed because one or more lines are too long
@ -26,6 +26,7 @@ const optionDraftItemId = 'moodle:draftitemid';
|
||||
const filePickers = 'moodle:filepickers';
|
||||
const optionsMoodleLang = 'moodle:language';
|
||||
const currentLanguage = 'moodle:currentLanguage';
|
||||
const optionPlaceholderSelectors = 'moodle:placeholderSelectors';
|
||||
|
||||
export const register = (editor, options) => {
|
||||
const registerOption = editor.options.register;
|
||||
@ -61,6 +62,12 @@ export const register = (editor, options) => {
|
||||
"default": {},
|
||||
});
|
||||
setOption(optionsMoodleLang, options.language);
|
||||
|
||||
registerOption(optionPlaceholderSelectors, {
|
||||
processor: 'array',
|
||||
"default": [],
|
||||
});
|
||||
setOption(optionPlaceholderSelectors, options.placeholderSelectors);
|
||||
};
|
||||
|
||||
export const getContextId = (editor) => editor.options.get(optionContextId);
|
||||
@ -97,3 +104,25 @@ export const getInitialPluginConfiguration = (options) => {
|
||||
* @returns {string}
|
||||
*/
|
||||
export const getPluginOptionName = (pluginName, optionName) => `${pluginName}:${optionName}`;
|
||||
|
||||
/**
|
||||
* Get the placeholder selectors.
|
||||
*
|
||||
* @param {TinyMCE} editor
|
||||
* @returns {array}
|
||||
*/
|
||||
export const getPlaceholderSelectors = (editor) => editor.options.get(optionPlaceholderSelectors);
|
||||
|
||||
/**
|
||||
* Register placeholder selectos.
|
||||
*
|
||||
* @param {TinyMCE} editor
|
||||
* @param {array} selectors
|
||||
*/
|
||||
export const registerPlaceholderSelectors = (editor, selectors) => {
|
||||
if (selectors.length) {
|
||||
let existingData = getPlaceholderSelectors(editor);
|
||||
existingData = existingData.concat(selectors);
|
||||
editor.options.set(optionPlaceholderSelectors, existingData);
|
||||
}
|
||||
};
|
||||
|
@ -183,10 +183,24 @@ class editor extends \texteditor {
|
||||
'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),
|
||||
];
|
||||
|
||||
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.
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -25,6 +25,7 @@ import {component} from './common';
|
||||
import * as Modal from 'core/modal_factory';
|
||||
import * as ModalEvents from 'core/modal_events';
|
||||
import ColorBase from './colorbase';
|
||||
import {getPlaceholderSelectors} from 'editor_tiny/options';
|
||||
|
||||
/**
|
||||
* @typedef ProblemDetail
|
||||
@ -48,6 +49,11 @@ export default class {
|
||||
this.editor = editor;
|
||||
this.colorBase = new ColorBase();
|
||||
this.modal = null;
|
||||
this.placeholderSelectors = null;
|
||||
const placeholders = getPlaceholderSelectors(this.editor);
|
||||
if (placeholders.length) {
|
||||
this.placeholderSelectors = placeholders.join(', ');
|
||||
}
|
||||
}
|
||||
|
||||
destroy() {
|
||||
@ -247,7 +253,14 @@ export default class {
|
||||
nodeData: [],
|
||||
};
|
||||
|
||||
warning.nodeData = [...nodes].map((node) => {
|
||||
warning.nodeData = [...nodes].filter((node) => {
|
||||
// If the failed node is a placeholder element. We should remove it from the list.
|
||||
if (node !== this.editor && this.placeholderSelectors) {
|
||||
return node.matches(this.placeholderSelectors) === false;
|
||||
}
|
||||
|
||||
return node;
|
||||
}).map((node) => {
|
||||
const describedNode = getEventualNode(node);
|
||||
|
||||
// Find the index of the node within the type of node.
|
||||
|
@ -1,4 +1,4 @@
|
||||
@editor @editor_tiny
|
||||
@editor @editor_tiny @tiny_accessibilitychecker
|
||||
Feature: Tiny editor accessibility checker
|
||||
To write accessible content in Tiny, I need to check for accessibility warnings.
|
||||
|
||||
@ -43,3 +43,11 @@ Feature: Tiny editor accessibility checker
|
||||
When I press "Save image"
|
||||
And I click on the "Tools > Accessibility checker" menu item for the "Description" TinyMCE editor
|
||||
Then I should see "Congratulations, no accessibility issues found!" in the "Accessibility checker" "dialogue"
|
||||
|
||||
@javascript
|
||||
Scenario: Placeholder element will not be assessed by accessibility checker
|
||||
Given I log in as "admin"
|
||||
And I open my profile in edit mode
|
||||
When I set the field "Description" to "<p>Some plain text</p><img src='/broken-image' width='1' height='1' class='behat-tinymce-placeholder'/><p>Some more text</p>"
|
||||
And I click on the "Tools > Accessibility checker" menu item for the "Description" TinyMCE editor
|
||||
Then I should see "Congratulations, no accessibility issues found!" in the "Accessibility checker" "dialogue"
|
||||
|
7
lib/editor/tiny/plugins/accessibilitychecker/upgrade.txt
Normal file
7
lib/editor/tiny/plugins/accessibilitychecker/upgrade.txt
Normal file
@ -0,0 +1,7 @@
|
||||
This files describes API changes in tiny_accessibilitychecker - TinyMCE Accessibility checker plugin,
|
||||
information provided here is intended especially for developers.
|
||||
|
||||
=== 4.1.1 ===
|
||||
|
||||
* The placeholder elements which were registered in placeholderSelectors in editor_tiny/options will not be
|
||||
assessed by the accessibility checker plugin.
|
@ -1,3 +1,3 @@
|
||||
define("tiny_h5p/filtercontent",["exports"],(function(_exports){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.setup=void 0;_exports.setup=async editor=>{editor.on("PreInit",(()=>{editor.formatter.register("h5p",{inline:"div",classes:"h5p-placeholder"})})),editor.on("SetContent",(()=>{editor.getBody().querySelectorAll(".h5p-placeholder:not([contenteditable])").forEach((node=>{node.contentEditable=!1}))}))}}));
|
||||
define("tiny_h5p/filtercontent",["exports","editor_tiny/options"],(function(_exports,_options){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.setup=void 0;_exports.setup=async editor=>{const classSelector=".".concat("h5p-placeholder");(0,_options.registerPlaceholderSelectors)(editor,[classSelector]),editor.on("PreInit",(()=>{editor.formatter.register("h5p",{inline:"div",classes:"h5p-placeholder"})})),editor.on("SetContent",(()=>{editor.getBody().querySelectorAll("".concat(classSelector,":not([contenteditable])")).forEach((node=>{node.contentEditable=!1}))}))}}));
|
||||
|
||||
//# sourceMappingURL=filtercontent.min.js.map
|
@ -1 +1 @@
|
||||
{"version":3,"file":"filtercontent.min.js","sources":["../src/filtercontent.js"],"sourcesContent":["// 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 <http://www.gnu.org/licenses/>.\n\n/**\n * Tiny H5P Content configuration.\n *\n * @module tiny_h5p/filtercontent\n * @copyright 2022 Andrew Lyons <andrew@nicols.co.uk>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nexport const setup = async(editor) => {\n // Register the H5P Formatter for use in all buttons.\n editor.on('PreInit', () => {\n editor.formatter.register('h5p', {\n inline: 'div',\n classes: 'h5p-placeholder',\n });\n });\n\n editor.on('SetContent', () => {\n // Listen to the SetContent event on the editor and update any h5p-placeholder to not be editable.\n // Doing this means that the inner content of the placeholder cannot be changed without using the dialogue.\n // The SetContent event is called whenever content is changed by actions such as initial load, paste, undo, etc.\n editor.getBody().querySelectorAll('.h5p-placeholder:not([contenteditable])').forEach((node) => {\n node.contentEditable = false;\n });\n });\n};\n"],"names":["async","editor","on","formatter","register","inline","classes","getBody","querySelectorAll","forEach","node","contentEditable"],"mappings":"6JAuBqBA,MAAAA,SAEjBC,OAAOC,GAAG,WAAW,KACjBD,OAAOE,UAAUC,SAAS,MAAO,CAC7BC,OAAQ,MACRC,QAAS,uBAIjBL,OAAOC,GAAG,cAAc,KAIpBD,OAAOM,UAAUC,iBAAiB,2CAA2CC,SAASC,OAClFA,KAAKC,iBAAkB"}
|
||||
{"version":3,"file":"filtercontent.min.js","sources":["../src/filtercontent.js"],"sourcesContent":["// 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 <http://www.gnu.org/licenses/>.\n\n/**\n * Tiny H5P Content configuration.\n *\n * @module tiny_h5p/filtercontent\n * @copyright 2022 Andrew Lyons <andrew@nicols.co.uk>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport {registerPlaceholderSelectors} from 'editor_tiny/options';\n\nexport const setup = async(editor) => {\n const className = 'h5p-placeholder';\n const classSelector = `.${className}`;\n // Register the H5P Formatter to the placeholder selector list.\n registerPlaceholderSelectors(editor, [classSelector]);\n // Register the H5P Formatter for use in all buttons.\n editor.on('PreInit', () => {\n editor.formatter.register('h5p', {\n inline: 'div',\n classes: className,\n });\n });\n\n editor.on('SetContent', () => {\n // Listen to the SetContent event on the editor and update any h5p-placeholder to not be editable.\n // Doing this means that the inner content of the placeholder cannot be changed without using the dialogue.\n // The SetContent event is called whenever content is changed by actions such as initial load, paste, undo, etc.\n editor.getBody().querySelectorAll(`${classSelector}:not([contenteditable])`).forEach((node) => {\n node.contentEditable = false;\n });\n });\n};\n"],"names":["async","classSelector","editor","on","formatter","register","inline","classes","getBody","querySelectorAll","forEach","node","contentEditable"],"mappings":"4LAyBqBA,MAAAA,eAEXC,yBADY,6DAGWC,OAAQ,CAACD,gBAEtCC,OAAOC,GAAG,WAAW,KACjBD,OAAOE,UAAUC,SAAS,MAAO,CAC7BC,OAAQ,MACRC,QARU,uBAYlBL,OAAOC,GAAG,cAAc,KAIpBD,OAAOM,UAAUC,2BAAoBR,0CAAwCS,SAASC,OAClFA,KAAKC,iBAAkB"}
|
@ -21,12 +21,18 @@
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
import {registerPlaceholderSelectors} from 'editor_tiny/options';
|
||||
|
||||
export const setup = async(editor) => {
|
||||
const className = 'h5p-placeholder';
|
||||
const classSelector = `.${className}`;
|
||||
// Register the H5P Formatter to the placeholder selector list.
|
||||
registerPlaceholderSelectors(editor, [classSelector]);
|
||||
// Register the H5P Formatter for use in all buttons.
|
||||
editor.on('PreInit', () => {
|
||||
editor.formatter.register('h5p', {
|
||||
inline: 'div',
|
||||
classes: 'h5p-placeholder',
|
||||
classes: className,
|
||||
});
|
||||
});
|
||||
|
||||
@ -34,7 +40,7 @@ export const setup = async(editor) => {
|
||||
// Listen to the SetContent event on the editor and update any h5p-placeholder to not be editable.
|
||||
// Doing this means that the inner content of the placeholder cannot be changed without using the dialogue.
|
||||
// The SetContent event is called whenever content is changed by actions such as initial load, paste, undo, etc.
|
||||
editor.getBody().querySelectorAll('.h5p-placeholder:not([contenteditable])').forEach((node) => {
|
||||
editor.getBody().querySelectorAll(`${classSelector}:not([contenteditable])`).forEach((node) => {
|
||||
node.contentEditable = false;
|
||||
});
|
||||
});
|
||||
|
10
lib/editor/tiny/upgrade.txt
Normal file
10
lib/editor/tiny/upgrade.txt
Normal file
@ -0,0 +1,10 @@
|
||||
This files describes API changes in /lib/editor/tiny/* - TinyMCE editor,
|
||||
information provided here is intended especially for developers.
|
||||
|
||||
=== 4.1.1 ===
|
||||
|
||||
* A list of placeholder selectors was created and can be accessed by placeholderSelectors options. The purpose of this list
|
||||
is to indicate the contents that are only shown in the editor and not to the users, by that way, we can decide to apply or
|
||||
not to apply rules, styles, etc... to these contents.
|
||||
Other Tiny plugins can register their placeholder elements to placeholderSelectors list
|
||||
by calling editor_tiny/options::registerPlaceholderSelectors.
|
Loading…
x
Reference in New Issue
Block a user