mirror of
https://github.com/moodle/moodle.git
synced 2025-04-16 14:02:32 +02:00
Merge branch 'MDL-77979-master' of https://github.com/meirzamoodle/moodle
This commit is contained in:
commit
c81e889a8d
@ -2038,6 +2038,7 @@ class core_plugin_manager {
|
||||
'recordrtc',
|
||||
'link',
|
||||
'html',
|
||||
'noautolink',
|
||||
],
|
||||
|
||||
'theme' => array(
|
||||
|
2
lib/editor/tiny/amd/build/utils.min.js
vendored
2
lib/editor/tiny/amd/build/utils.min.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -186,17 +186,19 @@ export const addContextmenuItem = (contextmenu, ...menuitems) => {
|
||||
};
|
||||
|
||||
/**
|
||||
* Given a TinyMCE quickbars configuration, add items to the meun.
|
||||
* Given a TinyMCE quickbars configuration, add items to the menu.
|
||||
*
|
||||
* @param {string} toolbar
|
||||
* @param {string[]} menuitems
|
||||
* @param {string} quicktoolbar
|
||||
* @param {string[]} toolbaritems
|
||||
* @returns {string}
|
||||
*/
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
export const addQuickbarsToolbarItem = (toolbar, ...menuitems) => {
|
||||
// For the moment we have disabled use of this menu.
|
||||
// The configuration is left in place to allow plugins to declare that they would like to support it in the future.
|
||||
return toolbar;
|
||||
export const addQuickbarsToolbarItem = (quicktoolbar, ...toolbaritems) => {
|
||||
const quicktoolbarItems = (quicktoolbar ?? '').split(' ');
|
||||
|
||||
return quicktoolbarItems
|
||||
.concat(toolbaritems)
|
||||
.filter((item) => item !== '')
|
||||
.join(' ');
|
||||
};
|
||||
|
||||
/**
|
||||
|
3
lib/editor/tiny/plugins/noautolink/amd/build/commands.min.js
vendored
Normal file
3
lib/editor/tiny/plugins/noautolink/amd/build/commands.min.js
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
define("tiny_noautolink/commands",["exports","editor_tiny/utils","core/str","tiny_noautolink/common","tiny_noautolink/noautolink"],(function(_exports,_utils,_str,_common,_noautolink){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.getSetup=void 0;_exports.getSetup=async()=>{const[buttonText,errorInvalidURL,infoEmptySelection,infoAddSuccess,infoRemoveSuccess,buttonImage]=await Promise.all([(0,_str.get_string)("buttontitle",_common.component),(0,_str.get_string)("errorinvalidurl",_common.component),(0,_str.get_string)("infoemptyselection",_common.component),(0,_str.get_string)("infoaddsuccess",_common.component),(0,_str.get_string)("inforemovesuccess",_common.component),(0,_utils.getButtonImage)("icon",_common.component)]);return editor=>{const messages={errorInvalidURL:errorInvalidURL,infoEmptySelection:infoEmptySelection,infoAddSuccess:infoAddSuccess,infoRemoveSuccess:infoRemoveSuccess};editor.ui.registry.addIcon(_common.buttonIcon,buttonImage.html),editor.ui.registry.addToggleButton(_common.buttonName,{icon:_common.buttonIcon,tooltip:buttonText,onAction:()=>{(0,_noautolink.handleAction)(editor,messages)},onSetup:(0,_noautolink.toggleActiveState)(editor)}),editor.ui.registry.addMenuItem(_common.buttonName,{icon:_common.buttonIcon,text:buttonText,onAction:()=>{(0,_noautolink.handleAction)(editor,messages)}})}}}));
|
||||
|
||||
//# sourceMappingURL=commands.min.js.map
|
@ -0,0 +1 @@
|
||||
{"version":3,"file":"commands.min.js","sources":["../src/commands.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\nimport {getButtonImage} from 'editor_tiny/utils';\nimport {get_string as getString} from 'core/str';\nimport {component, buttonName, buttonIcon} from 'tiny_noautolink/common';\nimport {handleAction, toggleActiveState} from 'tiny_noautolink/noautolink';\n\n/**\n * Tiny noautolink commands.\n *\n * @module tiny_noautolink/commands\n * @copyright 2023 Meirza <meirza.arson@moodle.com>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nexport const getSetup = async() => {\n const [\n buttonText,\n errorInvalidURL,\n infoEmptySelection,\n infoAddSuccess,\n infoRemoveSuccess,\n buttonImage,\n ] = await Promise.all([\n getString('buttontitle', component),\n getString('errorinvalidurl', component),\n getString('infoemptyselection', component),\n getString('infoaddsuccess', component),\n getString('inforemovesuccess', component),\n getButtonImage('icon', component),\n ]);\n\n return (editor) => {\n\n const messages = {\n errorInvalidURL: errorInvalidURL,\n infoEmptySelection: infoEmptySelection,\n infoAddSuccess: infoAddSuccess,\n infoRemoveSuccess: infoRemoveSuccess\n };\n\n // Register the noautolink Icon.\n editor.ui.registry.addIcon(buttonIcon, buttonImage.html);\n\n // Register the noautolink button.\n editor.ui.registry.addToggleButton(buttonName, {\n icon: buttonIcon,\n tooltip: buttonText,\n onAction: () => {\n handleAction(editor, messages);\n },\n onSetup: toggleActiveState(editor),\n });\n\n // Register the noautolink item.\n editor.ui.registry.addMenuItem(buttonName, {\n icon: buttonIcon,\n text: buttonText,\n onAction: () => {\n handleAction(editor, messages);\n },\n });\n };\n};\n"],"names":["async","buttonText","errorInvalidURL","infoEmptySelection","infoAddSuccess","infoRemoveSuccess","buttonImage","Promise","all","component","editor","messages","ui","registry","addIcon","buttonIcon","html","addToggleButton","buttonName","icon","tooltip","onAction","onSetup","addMenuItem","text"],"mappings":"0RA4BwBA,gBAEhBC,WACAC,gBACAC,mBACAC,eACAC,kBACAC,mBACMC,QAAQC,IAAI,EAClB,mBAAU,cAAeC,oBACzB,mBAAU,kBAAmBA,oBAC7B,mBAAU,qBAAsBA,oBAChC,mBAAU,iBAAkBA,oBAC5B,mBAAU,oBAAqBA,oBAC/B,yBAAe,OAAQA,4BAGnBC,eAEEC,SAAW,CACbT,gBAAiBA,gBACjBC,mBAAoBA,mBACpBC,eAAgBA,eAChBC,kBAAmBA,mBAIvBK,OAAOE,GAAGC,SAASC,QAAQC,mBAAYT,YAAYU,MAGnDN,OAAOE,GAAGC,SAASI,gBAAgBC,mBAAY,CAC3CC,KAAMJ,mBACNK,QAASnB,WACToB,SAAU,kCACOX,OAAQC,WAEzBW,SAAS,iCAAkBZ,UAI/BA,OAAOE,GAAGC,SAASU,YAAYL,mBAAY,CACvCC,KAAMJ,mBACNS,KAAMvB,WACNoB,SAAU,kCACOX,OAAQC"}
|
3
lib/editor/tiny/plugins/noautolink/amd/build/common.min.js
vendored
Normal file
3
lib/editor/tiny/plugins/noautolink/amd/build/common.min.js
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
define("tiny_noautolink/common",["exports"],(function(_exports){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0;return _exports.default={pluginName:"tiny_noautolink/plugin",component:"tiny_noautolink",buttonName:"tiny_noautolink",buttonIcon:"tiny_noautolink"},_exports.default}));
|
||||
|
||||
//# sourceMappingURL=common.min.js.map
|
@ -0,0 +1 @@
|
||||
{"version":3,"file":"common.min.js","sources":["../src/common.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 noautolink common values.\n *\n * @module tiny_noautolink/common\n * @copyright 2023 Meirza <meirza.arson@moodle.com>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nexport default {\n pluginName: 'tiny_noautolink/plugin',\n component: 'tiny_noautolink',\n buttonName: 'tiny_noautolink',\n buttonIcon: 'tiny_noautolink',\n};\n"],"names":["pluginName","component","buttonName","buttonIcon"],"mappings":"wKAuBe,CACXA,WAAY,yBACZC,UAAW,kBACXC,WAAY,kBACZC,WAAY"}
|
3
lib/editor/tiny/plugins/noautolink/amd/build/configuration.min.js
vendored
Normal file
3
lib/editor/tiny/plugins/noautolink/amd/build/configuration.min.js
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
define("tiny_noautolink/configuration",["exports","./common","editor_tiny/utils"],(function(_exports,_common,_utils){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.configure=void 0;_exports.configure=instanceConfig=>({quickbars_selection_toolbar:(0,_utils.addQuickbarsToolbarItem)(instanceConfig.quickbars_selection_toolbar,"|",_common.component),toolbar:(0,_utils.addToolbarButton)(instanceConfig.toolbar,"content",_common.component),menu:(0,_utils.addMenubarItem)(instanceConfig.menu,"format"," | "+_common.component)})}));
|
||||
|
||||
//# sourceMappingURL=configuration.min.js.map
|
@ -0,0 +1 @@
|
||||
{"version":3,"file":"configuration.min.js","sources":["../src/configuration.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 noautolink configuration.\n *\n * @module tiny_noautolink/configuration\n * @copyright 2023 Meirza <meirza.arson@moodle.com>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport {component as buttonName} from './common';\nimport {addQuickbarsToolbarItem, addToolbarButton, addMenubarItem} from 'editor_tiny/utils';\n\nexport const configure = (instanceConfig) => {\n // Update the instance configuration to add the noautolink menu option to the menus and toolbars.\n return {\n // eslint-disable-next-line camelcase\n quickbars_selection_toolbar: addQuickbarsToolbarItem(instanceConfig.quickbars_selection_toolbar, '|', buttonName),\n toolbar: addToolbarButton(instanceConfig.toolbar, 'content', buttonName),\n menu: addMenubarItem(instanceConfig.menu, 'format', ' | ' + buttonName),\n };\n};\n"],"names":["instanceConfig","quickbars_selection_toolbar","buttonName","toolbar","menu"],"mappings":"0NA0B0BA,iBAEf,CAEHC,6BAA6B,kCAAwBD,eAAeC,4BAA6B,IAAKC,mBACtGC,SAAS,2BAAiBH,eAAeG,QAAS,UAAWD,mBAC7DE,MAAM,yBAAeJ,eAAeI,KAAM,SAAU,MAAQF"}
|
10
lib/editor/tiny/plugins/noautolink/amd/build/noautolink.min.js
vendored
Normal file
10
lib/editor/tiny/plugins/noautolink/amd/build/noautolink.min.js
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
define("tiny_noautolink/noautolink",["exports","core/pending"],(function(_exports,_pending){var obj;
|
||||
/**
|
||||
* Helper for Tiny noautolink plugin.
|
||||
*
|
||||
* @module tiny_noautolink/noautolink
|
||||
* @copyright 2023 Meirza <meirza.arson@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.toggleActiveState=_exports.handleAction=void 0,_pending=(obj=_pending)&&obj.__esModule?obj:{default:obj};_exports.handleAction=(editor,messages)=>{const toggleState=isInAnchor(editor,editor.selection.getNode()),urlString=getSelectedContent(editor);toggleState||""===urlString?toggleState?unsetNoAutoLink(editor,messages,urlString):editor.notificationManager.open({text:messages.infoEmptySelection,type:"info",timeout:2e3}):setNoAutoLink(editor,messages,urlString)};const setNoAutoLink=(editor,messages,urlString)=>{if(isValidUrl(urlString)){const pendingPromise=new _pending.default("tiny_noautolink/setNoautolink");setNoautolinkOnSelection(editor,urlString).catch((error=>{editor.notificationManager.open({text:error,type:"error",timeout:2e3})})).finally((()=>{editor.notificationManager.open({text:messages.infoAddSuccess,type:"success",timeout:2e3}),pendingPromise.resolve()}))}else editor.notificationManager.open({text:messages.errorInvalidURL,type:"error",timeout:2e3})},unsetNoAutoLink=(editor,messages)=>{const nodeString=editor.selection.getNode().outerHTML.trim(),wrapper=document.createElement("div");wrapper.innerHTML=nodeString;if(wrapper.firstChild.classList.contains("nolink")){const pendingPromise=new _pending.default("tiny_noautolink/setNoautolink");unsetNoautolinkOnSelection(editor,nodeString).catch((error=>{editor.notificationManager.open({text:error,type:"error",timeout:2e3}),pendingPromise.reject(error)})).finally((()=>{editor.notificationManager.open({text:messages.infoRemoveSuccess,type:"success",timeout:2e3}),pendingPromise.resolve()}))}},getSelectedContent=editor=>{const selection=editor.selection;let content=selection.getContent({format:"text"}).trim();if(""==content){const range=selection.getRng();if(range.startContainer.nodeType===Node.TEXT_NODE){const textContent=range.startContainer.textContent,cursorOffset=range.startOffset;let wordStart=cursorOffset;for(;wordStart>0&&/\S/.test(textContent[wordStart-1]);)wordStart--;let wordEnd=cursorOffset;for(;wordEnd<textContent.length&&/\S/.test(textContent[wordEnd]);)wordEnd++;selection.setRng({startContainer:range.startContainer,startOffset:wordStart,endContainer:range.startContainer,endOffset:wordEnd}),content=selection.getContent({format:"text"}).trim()}}return content},setNoautolinkOnSelection=async(editor,url)=>{const newContent="<".concat("span",' class="').concat("nolink",'">').concat(url,"</").concat("span",">");editor.selection.setContent(newContent);const currentNode=editor.selection.getNode(),currentDOM=editor.dom.select("".concat("span",".").concat("nolink"),currentNode);currentDOM.forEach((function(value,index){value.outerHTML!=newContent||editor.selection.select(currentDOM[index])}))},unsetNoautolinkOnSelection=async(editor,url)=>{const regex=new RegExp("</?".concat("span","[^>]*>"),"g");url=url.replace(regex,"");editor.dom.getParent(editor.selection.getNode(),"span").outerHTML=url},isValidUrl=urlString=>!!new RegExp("^((http|https):\\/\\/|www\\.)((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|((\\d{1,3}\\.){3}\\d{1,3}))(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*(\\?[;&a-z\\d%_.~+=-]*)?(\\#[-a-z\\d_]*)?$","i").test(urlString),isInAnchor=(editor,selectedElm)=>null!==((editor,selectedElm)=>(selectedElm=selectedElm||editor.selection.getNode(),editor.dom.getParent(selectedElm,"".concat("span",".").concat("nolink"))))(editor,selectedElm);_exports.toggleActiveState=editor=>api=>{const updateState=()=>api.setActive(!editor.mode.isReadOnly()&&isInAnchor(editor,editor.selection.getNode()));return updateState(),((editor,toggler)=>(editor.on("NodeChange",toggler),()=>editor.off("NodeChange",toggler)))(editor,updateState)}}));
|
||||
|
||||
//# sourceMappingURL=noautolink.min.js.map
|
File diff suppressed because one or more lines are too long
10
lib/editor/tiny/plugins/noautolink/amd/build/plugin.min.js
vendored
Normal file
10
lib/editor/tiny/plugins/noautolink/amd/build/plugin.min.js
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
define("tiny_noautolink/plugin",["exports","editor_tiny/loader","editor_tiny/utils","./common","./commands","./configuration"],(function(_exports,_loader,_utils,_common,Commands,Configuration){function _getRequireWildcardCache(nodeInterop){if("function"!=typeof WeakMap)return null;var cacheBabelInterop=new WeakMap,cacheNodeInterop=new WeakMap;return(_getRequireWildcardCache=function(nodeInterop){return nodeInterop?cacheNodeInterop:cacheBabelInterop})(nodeInterop)}function _interopRequireWildcard(obj,nodeInterop){if(!nodeInterop&&obj&&obj.__esModule)return obj;if(null===obj||"object"!=typeof obj&&"function"!=typeof obj)return{default:obj};var cache=_getRequireWildcardCache(nodeInterop);if(cache&&cache.has(obj))return cache.get(obj);var newObj={},hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj)if("default"!==key&&Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;desc&&(desc.get||desc.set)?Object.defineProperty(newObj,key,desc):newObj[key]=obj[key]}return newObj.default=obj,cache&&cache.set(obj,newObj),newObj}
|
||||
/**
|
||||
* Tiny noautolink plugin.
|
||||
*
|
||||
* @module tiny_noautolink/plugin
|
||||
* @copyright 2023 Meirza <meirza.arson@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,Commands=_interopRequireWildcard(Commands),Configuration=_interopRequireWildcard(Configuration);var _default=new Promise((async resolve=>{const[tinyMCE,setupCommands,pluginMetadata]=await Promise.all([(0,_loader.getTinyMCE)(),Commands.getSetup(),(0,_utils.getPluginMetadata)(_common.component,_common.pluginName)]);tinyMCE.PluginManager.add("".concat(_common.component,"/plugin"),(editor=>(setupCommands(editor),pluginMetadata))),resolve(["".concat(_common.component,"/plugin"),Configuration])}));return _exports.default=_default,_exports.default}));
|
||||
|
||||
//# sourceMappingURL=plugin.min.js.map
|
@ -0,0 +1 @@
|
||||
{"version":3,"file":"plugin.min.js","sources":["../src/plugin.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 noautolink plugin.\n *\n * @module tiny_noautolink/plugin\n * @copyright 2023 Meirza <meirza.arson@moodle.com>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport {getTinyMCE} from 'editor_tiny/loader';\nimport {getPluginMetadata} from 'editor_tiny/utils';\n\nimport {component, pluginName} from './common';\nimport * as Commands from './commands';\nimport * as Configuration from './configuration';\n\n// eslint-disable-next-line no-async-promise-executor\nexport default new Promise(async(resolve) => {\n const [\n tinyMCE,\n setupCommands,\n pluginMetadata,\n ] = await Promise.all([\n getTinyMCE(),\n Commands.getSetup(),\n getPluginMetadata(component, pluginName),\n ]);\n\n tinyMCE.PluginManager.add(`${component}/plugin`, (editor) => {\n // Setup the Commands (buttons, menu items, and so on).\n setupCommands(editor);\n\n return pluginMetadata;\n });\n\n // Resolve the noautolink Plugin and include configuration.\n resolve([`${component}/plugin`, Configuration]);\n});\n"],"names":["Promise","async","tinyMCE","setupCommands","pluginMetadata","all","Commands","getSetup","component","pluginName","PluginManager","add","editor","resolve","Configuration"],"mappings":";;;;;;;kMA+Be,IAAIA,SAAQC,MAAAA,gBAEnBC,QACAC,cACAC,sBACMJ,QAAQK,IAAI,EAClB,wBACAC,SAASC,YACT,4BAAkBC,kBAAWC,sBAGjCP,QAAQQ,cAAcC,cAAOH,8BAAqBI,SAE9CT,cAAcS,QAEPR,kBAIXS,QAAQ,WAAIL,6BAAoBM"}
|
77
lib/editor/tiny/plugins/noautolink/amd/src/commands.js
Normal file
77
lib/editor/tiny/plugins/noautolink/amd/src/commands.js
Normal file
@ -0,0 +1,77 @@
|
||||
// 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/>.
|
||||
|
||||
import {getButtonImage} from 'editor_tiny/utils';
|
||||
import {get_string as getString} from 'core/str';
|
||||
import {component, buttonName, buttonIcon} from 'tiny_noautolink/common';
|
||||
import {handleAction, toggleActiveState} from 'tiny_noautolink/noautolink';
|
||||
|
||||
/**
|
||||
* Tiny noautolink commands.
|
||||
*
|
||||
* @module tiny_noautolink/commands
|
||||
* @copyright 2023 Meirza <meirza.arson@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
export const getSetup = async() => {
|
||||
const [
|
||||
buttonText,
|
||||
errorInvalidURL,
|
||||
infoEmptySelection,
|
||||
infoAddSuccess,
|
||||
infoRemoveSuccess,
|
||||
buttonImage,
|
||||
] = await Promise.all([
|
||||
getString('buttontitle', component),
|
||||
getString('errorinvalidurl', component),
|
||||
getString('infoemptyselection', component),
|
||||
getString('infoaddsuccess', component),
|
||||
getString('inforemovesuccess', component),
|
||||
getButtonImage('icon', component),
|
||||
]);
|
||||
|
||||
return (editor) => {
|
||||
|
||||
const messages = {
|
||||
errorInvalidURL: errorInvalidURL,
|
||||
infoEmptySelection: infoEmptySelection,
|
||||
infoAddSuccess: infoAddSuccess,
|
||||
infoRemoveSuccess: infoRemoveSuccess
|
||||
};
|
||||
|
||||
// Register the noautolink Icon.
|
||||
editor.ui.registry.addIcon(buttonIcon, buttonImage.html);
|
||||
|
||||
// Register the noautolink button.
|
||||
editor.ui.registry.addToggleButton(buttonName, {
|
||||
icon: buttonIcon,
|
||||
tooltip: buttonText,
|
||||
onAction: () => {
|
||||
handleAction(editor, messages);
|
||||
},
|
||||
onSetup: toggleActiveState(editor),
|
||||
});
|
||||
|
||||
// Register the noautolink item.
|
||||
editor.ui.registry.addMenuItem(buttonName, {
|
||||
icon: buttonIcon,
|
||||
text: buttonText,
|
||||
onAction: () => {
|
||||
handleAction(editor, messages);
|
||||
},
|
||||
});
|
||||
};
|
||||
};
|
29
lib/editor/tiny/plugins/noautolink/amd/src/common.js
Normal file
29
lib/editor/tiny/plugins/noautolink/amd/src/common.js
Normal file
@ -0,0 +1,29 @@
|
||||
// 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/>.
|
||||
|
||||
/**
|
||||
* Tiny noautolink common values.
|
||||
*
|
||||
* @module tiny_noautolink/common
|
||||
* @copyright 2023 Meirza <meirza.arson@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
export default {
|
||||
pluginName: 'tiny_noautolink/plugin',
|
||||
component: 'tiny_noautolink',
|
||||
buttonName: 'tiny_noautolink',
|
||||
buttonIcon: 'tiny_noautolink',
|
||||
};
|
35
lib/editor/tiny/plugins/noautolink/amd/src/configuration.js
Normal file
35
lib/editor/tiny/plugins/noautolink/amd/src/configuration.js
Normal file
@ -0,0 +1,35 @@
|
||||
// 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/>.
|
||||
|
||||
/**
|
||||
* Tiny noautolink configuration.
|
||||
*
|
||||
* @module tiny_noautolink/configuration
|
||||
* @copyright 2023 Meirza <meirza.arson@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
import {component as buttonName} from './common';
|
||||
import {addQuickbarsToolbarItem, addToolbarButton, addMenubarItem} from 'editor_tiny/utils';
|
||||
|
||||
export const configure = (instanceConfig) => {
|
||||
// Update the instance configuration to add the noautolink menu option to the menus and toolbars.
|
||||
return {
|
||||
// eslint-disable-next-line camelcase
|
||||
quickbars_selection_toolbar: addQuickbarsToolbarItem(instanceConfig.quickbars_selection_toolbar, '|', buttonName),
|
||||
toolbar: addToolbarButton(instanceConfig.toolbar, 'content', buttonName),
|
||||
menu: addMenubarItem(instanceConfig.menu, 'format', ' | ' + buttonName),
|
||||
};
|
||||
};
|
236
lib/editor/tiny/plugins/noautolink/amd/src/noautolink.js
Normal file
236
lib/editor/tiny/plugins/noautolink/amd/src/noautolink.js
Normal file
@ -0,0 +1,236 @@
|
||||
// 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/>.
|
||||
|
||||
/**
|
||||
* Helper for Tiny noautolink plugin.
|
||||
*
|
||||
* @module tiny_noautolink/noautolink
|
||||
* @copyright 2023 Meirza <meirza.arson@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
import Pending from 'core/pending';
|
||||
|
||||
const noautolinkClassName = 'nolink';
|
||||
const noautolinkTagHTML = 'span';
|
||||
const notificationTimeout = 2000;
|
||||
|
||||
/**
|
||||
* Handle action.
|
||||
*
|
||||
* @param {TinyMCE} editor
|
||||
* @param {object} messages
|
||||
*/
|
||||
export const handleAction = (editor, messages) => {
|
||||
const toggleState = isInAnchor(editor, editor.selection.getNode());
|
||||
const urlString = getSelectedContent(editor);
|
||||
if (!toggleState && urlString !== '') {
|
||||
setNoAutoLink(editor, messages, urlString);
|
||||
} else if (toggleState) {
|
||||
unsetNoAutoLink(editor, messages, urlString);
|
||||
} else {
|
||||
editor.notificationManager.open({text: messages.infoEmptySelection, type: 'info', timeout: notificationTimeout});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Display notification feedback when applying the noautolink to the selected text.
|
||||
*
|
||||
* @param {TinyMCE} editor
|
||||
* @param {object} messages
|
||||
* @param {String} urlString
|
||||
*/
|
||||
const setNoAutoLink = (editor, messages, urlString) => {
|
||||
// Check whether the string is a URL. Otherwise, show an error notification.
|
||||
if (isValidUrl(urlString)) {
|
||||
const pendingPromise = new Pending('tiny_noautolink/setNoautolink');
|
||||
// Applying the auto-link prevention.
|
||||
setNoautolinkOnSelection(editor, urlString)
|
||||
.catch(error => {
|
||||
editor.notificationManager.open({text: error, type: 'error', timeout: notificationTimeout});
|
||||
})
|
||||
.finally(() => {
|
||||
editor.notificationManager.open({text: messages.infoAddSuccess, type: 'success', timeout: notificationTimeout});
|
||||
pendingPromise.resolve();
|
||||
});
|
||||
} else {
|
||||
editor.notificationManager.open({text: messages.errorInvalidURL, type: 'error', timeout: notificationTimeout});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Display notification feedback when removing the noautolink to the selected text.
|
||||
*
|
||||
* @param {TinyMCE} editor
|
||||
* @param {object} messages
|
||||
*/
|
||||
const unsetNoAutoLink = (editor, messages) => {
|
||||
const nodeString = editor.selection.getNode().outerHTML.trim();
|
||||
// Convert HTML string to DOM element to get nolink class.
|
||||
const wrapper = document.createElement('div');
|
||||
wrapper.innerHTML = nodeString;
|
||||
const tempElement = wrapper.firstChild;
|
||||
if (tempElement.classList.contains('nolink')) {
|
||||
const pendingPromise = new Pending('tiny_noautolink/setNoautolink');
|
||||
// Removing the auto-link prevention.
|
||||
unsetNoautolinkOnSelection(editor, nodeString)
|
||||
.catch(error => {
|
||||
editor.notificationManager.open({text: error, type: 'error', timeout: notificationTimeout});
|
||||
pendingPromise.reject(error); // Handle the error as needed.
|
||||
})
|
||||
.finally(() => {
|
||||
editor.notificationManager.open({text: messages.infoRemoveSuccess, type: 'success', timeout: notificationTimeout});
|
||||
pendingPromise.resolve();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the full string based on the position of the cursor within the string.
|
||||
*
|
||||
* @param {TinyMCE} editor
|
||||
* @returns {String}
|
||||
*/
|
||||
const getSelectedContent = (editor) => {
|
||||
const selection = editor.selection; // Get the selection object.
|
||||
let content = selection.getContent({format: 'text'}).trim();
|
||||
if (content == '') {
|
||||
const range = selection.getRng(); // Get the range object.
|
||||
|
||||
// Check if the cursor is within a text node.
|
||||
if (range.startContainer.nodeType === Node.TEXT_NODE) {
|
||||
const textContent = range.startContainer.textContent;
|
||||
const cursorOffset = range.startOffset;
|
||||
|
||||
// Find the word boundaries around the cursor.
|
||||
let wordStart = cursorOffset;
|
||||
while (wordStart > 0 && /\S/.test(textContent[wordStart - 1])) {
|
||||
wordStart--;
|
||||
}
|
||||
|
||||
let wordEnd = cursorOffset;
|
||||
while (wordEnd < textContent.length && /\S/.test(textContent[wordEnd])) {
|
||||
wordEnd++;
|
||||
}
|
||||
|
||||
// Set the selection range to the word.
|
||||
selection.setRng({
|
||||
startContainer: range.startContainer,
|
||||
startOffset: wordStart,
|
||||
endContainer: range.startContainer,
|
||||
endOffset: wordEnd,
|
||||
});
|
||||
content = selection.getContent({format: 'text'}).trim();
|
||||
}
|
||||
}
|
||||
return content;
|
||||
};
|
||||
|
||||
/**
|
||||
* Wrap the selection with the nolink class.
|
||||
*
|
||||
* @param {TinyMCE} editor
|
||||
* @param {String} url URL the link will point to.
|
||||
*/
|
||||
const setNoautolinkOnSelection = async(editor, url) => {
|
||||
const newContent = `<${noautolinkTagHTML} class="${noautolinkClassName}">${url}</${noautolinkTagHTML}>`;
|
||||
editor.selection.setContent(newContent);
|
||||
|
||||
// Select the new content.
|
||||
const currentNode = editor.selection.getNode();
|
||||
const currentDOM = editor.dom.select(`${noautolinkTagHTML}.${noautolinkClassName}`, currentNode);
|
||||
currentDOM.forEach(function(value, index) {
|
||||
if (value.outerHTML == newContent) {
|
||||
editor.selection.select(currentDOM[index]);
|
||||
return;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove the nolink on the selection.
|
||||
*
|
||||
* @param {TinyMCE} editor
|
||||
* @param {String} url URL the link will point to.
|
||||
*/
|
||||
const unsetNoautolinkOnSelection = async(editor, url) => {
|
||||
const regex = new RegExp(`</?${noautolinkTagHTML}[^>]*>`, "g");
|
||||
url = url.replace(regex, "");
|
||||
const currentSpan = editor.dom.getParent(editor.selection.getNode(), noautolinkTagHTML);
|
||||
currentSpan.outerHTML = url;
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if given string is a valid URL.
|
||||
*
|
||||
* @param {String} urlString URL the link will point to.
|
||||
* @returns {boolean} True is valid, otherwise false.
|
||||
*/
|
||||
const isValidUrl = urlString => {
|
||||
const urlPattern = new RegExp('^((http|https):\\/\\/|www\\.)' + // A URL must have one of these https/https/www.
|
||||
'((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|' + // Validate domain name.
|
||||
'((\\d{1,3}\\.){3}\\d{1,3}))' + // Validate ip (v4) address.
|
||||
'(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*' + // Validate port and path.
|
||||
'(\\?[;&a-z\\d%_.~+=-]*)?' + // Validate query string.
|
||||
'(\\#[-a-z\\d_]*)?$', 'i'); // Validate fragment locator.
|
||||
|
||||
return !!urlPattern.test(urlString);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get anchor element.
|
||||
*
|
||||
* @param {TinyMCE} editor
|
||||
* @param {Element} selectedElm
|
||||
* @returns {Element}
|
||||
*/
|
||||
const getAnchorElement = (editor, selectedElm) => {
|
||||
selectedElm = selectedElm || editor.selection.getNode();
|
||||
return editor.dom.getParent(selectedElm, `${noautolinkTagHTML}.${noautolinkClassName}`);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Check the current selected element is an anchor or not.
|
||||
*
|
||||
* @param {TinyMCE} editor
|
||||
* @param {Element} selectedElm
|
||||
* @returns {boolean}
|
||||
*/
|
||||
const isInAnchor = (editor, selectedElm) => getAnchorElement(editor, selectedElm) !== null;
|
||||
|
||||
/**
|
||||
* Change state of button.
|
||||
*
|
||||
* @param {TinyMCE} editor
|
||||
* @param {function()} toggler
|
||||
* @returns {function()}
|
||||
*/
|
||||
const toggleState = (editor, toggler) => {
|
||||
editor.on('NodeChange', toggler);
|
||||
return () => editor.off('NodeChange', toggler);
|
||||
};
|
||||
|
||||
/**
|
||||
* Change the active state of button.
|
||||
*
|
||||
* @param {TinyMCE} editor
|
||||
* @returns {function(*): function(): *}
|
||||
*/
|
||||
export const toggleActiveState = (editor) => (api) => {
|
||||
const updateState = () => api.setActive(!editor.mode.isReadOnly() && isInAnchor(editor, editor.selection.getNode()));
|
||||
updateState();
|
||||
return toggleState(editor, updateState);
|
||||
};
|
52
lib/editor/tiny/plugins/noautolink/amd/src/plugin.js
Normal file
52
lib/editor/tiny/plugins/noautolink/amd/src/plugin.js
Normal file
@ -0,0 +1,52 @@
|
||||
// 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/>.
|
||||
|
||||
/**
|
||||
* Tiny noautolink plugin.
|
||||
*
|
||||
* @module tiny_noautolink/plugin
|
||||
* @copyright 2023 Meirza <meirza.arson@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
import {getTinyMCE} from 'editor_tiny/loader';
|
||||
import {getPluginMetadata} from 'editor_tiny/utils';
|
||||
|
||||
import {component, pluginName} from './common';
|
||||
import * as Commands from './commands';
|
||||
import * as Configuration from './configuration';
|
||||
|
||||
// eslint-disable-next-line no-async-promise-executor
|
||||
export default new Promise(async(resolve) => {
|
||||
const [
|
||||
tinyMCE,
|
||||
setupCommands,
|
||||
pluginMetadata,
|
||||
] = await Promise.all([
|
||||
getTinyMCE(),
|
||||
Commands.getSetup(),
|
||||
getPluginMetadata(component, pluginName),
|
||||
]);
|
||||
|
||||
tinyMCE.PluginManager.add(`${component}/plugin`, (editor) => {
|
||||
// Setup the Commands (buttons, menu items, and so on).
|
||||
setupCommands(editor);
|
||||
|
||||
return pluginMetadata;
|
||||
});
|
||||
|
||||
// Resolve the noautolink Plugin and include configuration.
|
||||
resolve([`${component}/plugin`, Configuration]);
|
||||
});
|
53
lib/editor/tiny/plugins/noautolink/classes/plugininfo.php
Normal file
53
lib/editor/tiny/plugins/noautolink/classes/plugininfo.php
Normal file
@ -0,0 +1,53 @@
|
||||
<?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/>.
|
||||
|
||||
namespace tiny_noautolink;
|
||||
|
||||
use editor_tiny\plugin;
|
||||
use editor_tiny\plugin_with_buttons;
|
||||
use editor_tiny\plugin_with_menuitems;
|
||||
|
||||
/**
|
||||
* Tiny noautolink plugin.
|
||||
*
|
||||
* @package tiny_noautolink
|
||||
* @copyright 2023 Meirza <meirza.arson@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class plugininfo extends plugin implements plugin_with_buttons, plugin_with_menuitems {
|
||||
|
||||
/**
|
||||
* Get a list of the buttons provided by this plugin.
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public static function get_available_buttons(): array {
|
||||
return [
|
||||
'tiny_noautolink/tiny_noautolink_link',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of the menu items provided by this plugin.
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public static function get_available_menuitems(): array {
|
||||
return [
|
||||
'tiny_noautolink/tiny_noautolink_link',
|
||||
];
|
||||
}
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
<?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/>.
|
||||
|
||||
namespace tiny_noautolink\privacy;
|
||||
|
||||
/**
|
||||
* Privacy Subsystem for tiny_noautolink implementing null_provider.
|
||||
*
|
||||
* @package tiny_noautolink
|
||||
* @copyright 2023 Meirza <meirza.arson@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class provider implements \core_privacy\local\metadata\null_provider {
|
||||
|
||||
/**
|
||||
* Get the language string identifier with the component's language
|
||||
* file to explain why this plugin stores no data.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function get_reason() : string {
|
||||
return 'privacy:metadata';
|
||||
}
|
||||
}
|
32
lib/editor/tiny/plugins/noautolink/db/install.php
Normal file
32
lib/editor/tiny/plugins/noautolink/db/install.php
Normal file
@ -0,0 +1,32 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Tiny noautolink plugin install code.
|
||||
*
|
||||
* @package tiny_noautolink
|
||||
* @copyright 2023 Meirza <meirza.arson@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
/**
|
||||
* Install the Tiny noautolink plugin in a disabled state.
|
||||
*/
|
||||
function xmldb_tiny_noautolink_install() {
|
||||
$tinymanager = \core_plugin_manager::resolve_plugininfo_class('tiny');
|
||||
// Disabled the plugin.
|
||||
$tinymanager::enable_plugin('noautolink', 0);
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Strings for component 'tiny_noautolink', language 'en'.
|
||||
*
|
||||
* @package tiny_noautolink
|
||||
* @copyright 2023 Meirza <meirza.arson@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
$string['buttontitle'] = 'No auto-link';
|
||||
$string['errorinvalidurl'] = 'The selected content is not a URL. Please try again.';
|
||||
$string['infoaddsuccess'] = 'Added the auto-link prevention.';
|
||||
$string['infoemptyselection'] = 'Select a URL and try again.';
|
||||
$string['inforemovesuccess'] = 'Removed the auto-link prevention.';
|
||||
$string['pluginname'] = 'Tiny no auto-link';
|
||||
$string['privacy:metadata'] = 'The tiny_noautolink plugin does not store any personal data.';
|
1
lib/editor/tiny/plugins/noautolink/pix/icon.svg
Normal file
1
lib/editor/tiny/plugins/noautolink/pix/icon.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" fill="currentColor" class="bi bi-exclamation-lg" viewBox="0 0 16 16" id="IconChangeColor"> <path d="M7.005 3.1a1 1 0 1 1 1.99 0l-.388 6.35a.61.61 0 0 1-1.214 0L7.005 3.1ZM7 12a1 1 0 1 1 2 0 1 1 0 0 1-2 0Z" id="mainIconPathAttribute" stroke-width="0.5" stroke="#000000" fill="#000000"></path> </svg>
|
After Width: | Height: | Size: 363 B |
@ -0,0 +1,21 @@
|
||||
@editor @editor_tiny @tiny_noautolink
|
||||
Feature: Tiny noautolink
|
||||
To avoid auto-linking, users need to wrap the URL with the 'nolink' class.
|
||||
|
||||
@javascript
|
||||
Scenario: Insert a link, add and remove the auto-link prevention
|
||||
Given I log in as "admin"
|
||||
And I navigate to "Plugins > Text editors > TinyMCE editor > General settings" in site administration
|
||||
And I click on "Enable Tiny no auto-link" "link"
|
||||
When I open my profile in edit mode
|
||||
And I set the field "Description" to "<p>https://moodle.org</p>"
|
||||
|
||||
# Add auto-link prevention.
|
||||
And I select the "p" element in position "0" of the "Description" TinyMCE editor
|
||||
And I click on the "No auto-link" button for the "Description" TinyMCE editor
|
||||
Then the field "Description" matches value "<p><span class='nolink'>https://moodle.org</span></p>"
|
||||
|
||||
# Remove auto-link prevention.
|
||||
And I select the "span" element in position "0" of the "Description" TinyMCE editor
|
||||
And I click on the "No auto-link" button for the "Description" TinyMCE editor
|
||||
Then the field "Description" matches value "<p>https://moodle.org</p>"
|
29
lib/editor/tiny/plugins/noautolink/version.php
Normal file
29
lib/editor/tiny/plugins/noautolink/version.php
Normal file
@ -0,0 +1,29 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Tiny noautolink plugin version details.
|
||||
*
|
||||
* @package tiny_noautolink
|
||||
* @copyright 2023 Meirza <meirza.arson@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2023081600; // The current plugin version (Date: YYYYMMDDXX).
|
||||
$plugin->requires = 2023081400; // Requires this Moodle version.
|
||||
$plugin->component = 'tiny_noautolink'; // Full name of the plugin (used for diagnostics).
|
Loading…
x
Reference in New Issue
Block a user