Merge branch 'MDL-75268-master' of https://github.com/davewoloszyn/moodle

This commit is contained in:
Andrew Nicols 2023-09-05 11:39:41 +08:00
commit b3d8c1a862
No known key found for this signature in database
GPG Key ID: 6D1E3157C8CFBF14
23 changed files with 644 additions and 6 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -58,9 +58,10 @@ export const displayFilepicker = (editor, filetype) => new Promise((resolve, rej
* @param {object} toolbar
* @param {string} section
* @param {string} button
* @param {string|null} [after=null]
* @returns {object} The toolbar configuration
*/
export const addToolbarButton = (toolbar, section, button) => {
export const addToolbarButton = (toolbar, section, button, after = null) => {
if (!toolbar) {
return [{
name: section,
@ -71,7 +72,16 @@ export const addToolbarButton = (toolbar, section, button) => {
const mutatedToolbar = JSON.parse(JSON.stringify(toolbar));
return mutatedToolbar.map((item) => {
if (item.name === section) {
item.items.push(button);
if (after) {
// Insert new button after the specified button.
let index = item.items.findIndex(value => value == after);
if (index !== -1) {
item.items.splice(index + 1, 0, button);
}
} else {
// Append button to end of button section.
item.items.push(button);
}
}
return item;
@ -148,9 +158,10 @@ export const addToolbarSection = (toolbar, name, relativeTo, append = true) => {
* @param {object} menubar
* @param {string} section
* @param {string} menuitem
* @param {string|null} [after=null]
* @returns {object}
*/
export const addMenubarItem = (menubar, section, menuitem) => {
export const addMenubarItem = (menubar, section, menuitem, after = null) => {
if (!menubar) {
const emptyMenubar = {};
emptyMenubar[section] = {
@ -162,7 +173,17 @@ export const addMenubarItem = (menubar, section, menuitem) => {
const mutatedMenubar = JSON.parse(JSON.stringify(menubar));
Array.from(Object.entries(mutatedMenubar)).forEach(([name, menu]) => {
if (name === section) {
menu.items = `${menu.items} ${menuitem}`;
if (after) {
// Insert new item after the specified menu item.
let index = menu.items.indexOf(after);
if (index !== -1) {
index += after.length;
menu.items = menu.items.slice(0, index) + ` ${menuitem}` + menu.items.slice(index);
}
} else {
// Append item to end of the menu section.
menu.items = `${menu.items} ${menuitem}`;
}
}
});

View File

@ -0,0 +1,3 @@
define("tiny_premium/common",["exports"],(function(_exports){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0;return _exports.default={pluginName:"tiny_premium/plugin",component:"tiny_premium"},_exports.default}));
//# sourceMappingURL=common.min.js.map

View File

@ -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 Premium common values.\n *\n * @module tiny_premium/common\n * @copyright 2023 David Woloszyn <david.woloszyn@moodle.com>\n * @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nexport default {\n pluginName: 'tiny_premium/plugin',\n component: 'tiny_premium',\n};\n"],"names":["pluginName","component"],"mappings":"qKAuBe,CACXA,WAAY,sBACZC,UAAW"}

View File

@ -0,0 +1,3 @@
define("tiny_premium/configuration",["exports","editor_tiny/utils"],(function(_exports,_utils){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.configure=void 0;_exports.configure=instanceConfig=>{let plugins=instanceConfig.plugins,menu=instanceConfig.menu,toolbar=(toolbar=>(toolbar=(0,_utils.addToolbarSection)(toolbar,"premium_a","advanced",!0),(0,_utils.addToolbarSection)(toolbar,"premium_b","formatting",!0)))(instanceConfig.toolbar),contextmenu=instanceConfig.contextmenu;return plugins+=" advtable",menu=(0,_utils.addMenubarItem)(menu,"table","| advtablerownumbering","advtablesort"),plugins+=" editimage",toolbar=(0,_utils.addToolbarButton)(toolbar,"content","editimage","tiny_media_image"),instanceConfig.editimage_toolbar="rotateleft rotateright flipv fliph editimage",plugins+=" export",menu=(0,_utils.addMenubarItem)(menu,"tools","| export"),plugins+=" pageembed",toolbar=(0,_utils.addToolbarButton)(toolbar,"content","pageembed","tiny_media_video"),plugins+=" typography",toolbar=(0,_utils.addToolbarButton)(toolbar,"premium_b","typography"),plugins+=" casechange",toolbar=(0,_utils.addToolbarButton)(toolbar,"premium_a","casechange"),plugins+=" checklist",toolbar=(0,_utils.addToolbarButton)(toolbar,"lists","checklist"),plugins+=" tinymcespellchecker",menu=(0,_utils.addMenubarItem)(menu,"tools","spellcheckdialog","spellcheckerlanguage"),contextmenu=(0,_utils.addContextmenuItem)(contextmenu,"spellchecker"),toolbar=(0,_utils.addToolbarButton)(toolbar,"premium_a","spellcheckdialog"),plugins+=" autocorrect",menu=(0,_utils.addMenubarItem)(menu,"tools","| autocorrect capitalization","spellcheckdialog"),plugins+=" permanentpen",menu=(0,_utils.addMenubarItem)(menu,"format","| permanentpen configurepermanentpen"),toolbar=(0,_utils.addToolbarButton)(toolbar,"premium_a","permanentpen"),contextmenu=(0,_utils.addContextmenuItem)(contextmenu,"configurepermanentpen"),plugins+=" formatpainter",toolbar=(0,_utils.addToolbarButton)(toolbar,"premium_a","formatpainter"),plugins+=" linkchecker",contextmenu=(0,_utils.addContextmenuItem)(contextmenu,"linkchecker"),plugins+=" tableofcontents",toolbar=(0,_utils.addToolbarButton)(toolbar,"premium_a","tableofcontents"),plugins+=" footnotes",toolbar=(0,_utils.addToolbarButton)(toolbar,"premium_a","footnotes"),menu=(0,_utils.addMenubarItem)(menu,"insert","footnotes","tableofcontents"),plugins+=" powerpaste",{plugins:plugins,toolbar:toolbar,menu:menu,contextmenu:contextmenu}}}));
//# sourceMappingURL=configuration.min.js.map

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,10 @@
define("tiny_premium/external",["exports","core/ajax"],(function(_exports,_ajax){var obj;
/**
* Helper to get external content for Tiny Premium plugin.
*
* @module tiny_premium/external
* @copyright 2023 David Woloszyn <david.woloszyn@moodle.com>
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.getApiKey=void 0,_ajax=(obj=_ajax)&&obj.__esModule?obj:{default:obj};_exports.getApiKey=contextId=>{const request={methodname:"tiny_premium_get_api_key",args:{contextid:contextId}};return _ajax.default.call([request])[0]}}));
//# sourceMappingURL=external.min.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"external.min.js","sources":["../src/external.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 * Helper to get external content for Tiny Premium plugin.\n *\n * @module tiny_premium/external\n * @copyright 2023 David Woloszyn <david.woloszyn@moodle.com>\n * @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport Ajax from 'core/ajax';\n\n/**\n * Due to the order items are initialise, options.js will not work in getting the API key.\n * This external method is used to get the API key in time.\n *\n * @param {Number} contextId The context id\n * @return {Promise}\n */\nexport const getApiKey = (contextId) => {\n const request = {\n methodname: 'tiny_premium_get_api_key',\n args: {\n contextid: contextId\n }\n };\n return Ajax.call([request])[0];\n};\n"],"names":["contextId","request","methodname","args","contextid","Ajax","call"],"mappings":";;;;;;;8JAgC0BA,kBAChBC,QAAU,CACZC,WAAY,2BACZC,KAAM,CACFC,UAAWJ,mBAGZK,cAAKC,KAAK,CAACL,UAAU"}

View File

@ -0,0 +1,10 @@
define("tiny_premium/plugin",["exports","editor_tiny/loader","editor_tiny/utils","tiny_premium/common","tiny_premium/configuration","tiny_premium/external","core/config"],(function(_exports,_loader,_utils,_common,Configuration,_external,_config){var obj;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)}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,Configuration=function(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]}newObj.default=obj,cache&&cache.set(obj,newObj);return newObj}
/**
* Tiny Premium plugin for Moodle.
*
* @module tiny_premium/plugin
* @copyright 2023 David Woloszyn <david.woloszyn@moodle.com>
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/(Configuration);const currentContextId=(_config=(obj=_config)&&obj.__esModule?obj:{default:obj}).default.contextid;var _default=new Promise((async resolve=>{const[tinyMCE,pluginMetadata,externalData]=await Promise.all([(0,_loader.getTinyMCE)(),(0,_utils.getPluginMetadata)(_common.component,_common.pluginName),(0,_external.getApiKey)(currentContextId)]);tinyMCE.PluginManager.add("".concat(_common.component,"/plugin"),(()=>pluginMetadata)),await getTinyPremium(externalData.apikey),resolve(["".concat(_common.component,"/plugin"),Configuration])}));let tinyPremiumPromise;_exports.default=_default;const getTinyPremium=apikey=>tinyPremiumPromise||(tinyPremiumPromise=new Promise(((resolve,reject)=>{const head=document.querySelector("head"),script=document.createElement("script");script.dataset.tinymce="premium",script.src="https://cdn.tiny.cloud/1/".concat(apikey,"/tinymce/6/plugins.min.js"),script.referrerpolicy="origin",script.addEventListener("load",(()=>{resolve()}),!1),script.addEventListener("error",(err=>{reject(err)}),!1),head.append(script)})),tinyPremiumPromise);return _exports.default}));
//# sourceMappingURL=plugin.min.js.map

View File

@ -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 Premium plugin for Moodle.\n *\n * @module tiny_premium/plugin\n * @copyright 2023 David Woloszyn <david.woloszyn@moodle.com>\n * @license https://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';\nimport {component, pluginName} from 'tiny_premium/common';\nimport * as Configuration from 'tiny_premium/configuration';\nimport {getApiKey} from 'tiny_premium/external';\nimport Config from 'core/config';\n\nconst currentContextId = Config.contextid;\n\n// eslint-disable-next-line no-async-promise-executor\nexport default new Promise(async(resolve) => {\n const [\n tinyMCE,\n pluginMetadata,\n externalData\n ] = await Promise.all([\n getTinyMCE(),\n getPluginMetadata(component, pluginName),\n getApiKey(currentContextId)\n ]);\n\n tinyMCE.PluginManager.add(`${component}/plugin`, () => {\n return pluginMetadata;\n });\n\n // Load the Tiny Premium script using the provided API key.\n await getTinyPremium(externalData.apikey);\n\n resolve([`${component}/plugin`, Configuration]);\n});\n\nlet tinyPremiumPromise;\n\n/**\n * Promise for Tiny Premium plugins script.\n *\n * @param {string} apikey\n * @return {Promise}\n */\nconst getTinyPremium = (apikey) => {\n if (tinyPremiumPromise) {\n return tinyPremiumPromise;\n }\n\n tinyPremiumPromise = new Promise((resolve, reject) => {\n const head = document.querySelector('head');\n const script = document.createElement('script');\n script.dataset.tinymce = 'premium';\n script.src = `https://cdn.tiny.cloud/1/${apikey}/tinymce/6/plugins.min.js`;\n script.referrerpolicy = \"origin\";\n\n script.addEventListener('load', () => {\n resolve();\n }, false);\n\n script.addEventListener('error', (err) => {\n reject(err);\n }, false);\n\n head.append(script);\n });\n\n return tinyPremiumPromise;\n};\n"],"names":["currentContextId","contextid","Promise","async","tinyMCE","pluginMetadata","externalData","all","component","pluginName","PluginManager","add","getTinyPremium","apikey","resolve","Configuration","tinyPremiumPromise","reject","head","document","querySelector","script","createElement","dataset","tinymce","src","referrerpolicy","addEventListener","err","append"],"mappings":";;;;;;;2BA8BMA,mFAA0BC,uBAGjB,IAAIC,SAAQC,MAAAA,gBAEnBC,QACAC,eACAC,oBACMJ,QAAQK,IAAI,EAClB,yBACA,4BAAkBC,kBAAWC,qBAC7B,uBAAUT,oBAGdI,QAAQM,cAAcC,cAAOH,8BAAoB,IACtCH,uBAILO,eAAeN,aAAaO,QAElCC,QAAQ,WAAIN,6BAAoBO,uBAGhCC,mDAQEJ,eAAkBC,QAChBG,qBAIJA,mBAAqB,IAAId,SAAQ,CAACY,QAASG,gBACjCC,KAAOC,SAASC,cAAc,QAC9BC,OAASF,SAASG,cAAc,UACtCD,OAAOE,QAAQC,QAAU,UACzBH,OAAOI,uCAAkCZ,oCACzCQ,OAAOK,eAAiB,SAExBL,OAAOM,iBAAiB,QAAQ,KAC5Bb,aACD,GAEHO,OAAOM,iBAAiB,SAAUC,MAC9BX,OAAOW,QACR,GAEHV,KAAKW,OAAOR,WAGTL"}

View File

@ -0,0 +1,27 @@
// 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 Premium common values.
*
* @module tiny_premium/common
* @copyright 2023 David Woloszyn <david.woloszyn@moodle.com>
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
export default {
pluginName: 'tiny_premium/plugin',
component: 'tiny_premium',
};

View File

@ -0,0 +1,121 @@
// 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 Premium configuration.
*
* @module tiny_premium/configuration
* @copyright 2023 David Woloszyn <david.woloszyn@moodle.com>
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
import {
addToolbarButton,
addMenubarItem,
addToolbarSection,
addContextmenuItem
} from 'editor_tiny/utils';
const configureToolbar = (toolbar) => {
// Add premium toolbar sections to house all the plugins with no natural home.
toolbar = addToolbarSection(toolbar, 'premium_a', 'advanced', true);
toolbar = addToolbarSection(toolbar, 'premium_b', 'formatting', true);
return toolbar;
};
export const configure = (instanceConfig) => {
// There is some manipulating of the plugin menu, toolbar, context and quickbar items.
// This was necessary to enhance user experience and closer align to the Tiny demo site.
let plugins = instanceConfig.plugins;
let menu = instanceConfig.menu;
let toolbar = configureToolbar(instanceConfig.toolbar);
let contextmenu = instanceConfig.contextmenu;
let pluginsettings = {};
// Advanced Table.
plugins += ` advtable`;
menu = addMenubarItem(menu, 'table', '| advtablerownumbering', 'advtablesort');
// Enhanced Image Editing.
plugins += ` editimage`;
toolbar = addToolbarButton(toolbar, 'content', 'editimage', 'tiny_media_image');
// Remove the duplicate image button from the quickbar toolbar by redefining the values without 'imageoptions'.
// eslint-disable-next-line camelcase
instanceConfig.editimage_toolbar = 'rotateleft rotateright flipv fliph editimage';
// Export.
plugins += ` export`;
menu = addMenubarItem(menu, 'tools', '| export');
// Page Embed.
plugins += ` pageembed`;
toolbar = addToolbarButton(toolbar, 'content', 'pageembed', 'tiny_media_video');
// Advanced Typography.
plugins += ` typography`;
toolbar = addToolbarButton(toolbar, 'premium_b', 'typography');
// Case Change.
plugins += ` casechange`;
toolbar = addToolbarButton(toolbar, 'premium_a', 'casechange');
// Checklist.
plugins += ` checklist`;
toolbar = addToolbarButton(toolbar, 'lists', 'checklist');
// Spell Checker Pro.
plugins += ` tinymcespellchecker`;
menu = addMenubarItem(menu, 'tools', 'spellcheckdialog', 'spellcheckerlanguage');
contextmenu = addContextmenuItem(contextmenu, 'spellchecker');
toolbar = addToolbarButton(toolbar, 'premium_a', 'spellcheckdialog');
// Spelling Autocorrect.
plugins += ` autocorrect`;
menu = addMenubarItem(menu, 'tools', '| autocorrect capitalization', 'spellcheckdialog');
// Permanent Pen.
plugins += ` permanentpen`;
menu = addMenubarItem(menu, 'format', '| permanentpen configurepermanentpen');
toolbar = addToolbarButton(toolbar, 'premium_a', 'permanentpen');
contextmenu = addContextmenuItem(contextmenu, 'configurepermanentpen');
// Format Painter.
plugins += ` formatpainter`;
toolbar = addToolbarButton(toolbar, 'premium_a', 'formatpainter');
// Link Checker.
plugins += ` linkchecker`;
contextmenu = addContextmenuItem(contextmenu, 'linkchecker');
// Table of Contents.
plugins += ` tableofcontents`;
toolbar = addToolbarButton(toolbar, 'premium_a', 'tableofcontents');
// Footnotes.
plugins += ` footnotes`;
toolbar = addToolbarButton(toolbar, 'premium_a', 'footnotes');
menu = addMenubarItem(menu, 'insert', 'footnotes', 'tableofcontents');
// Powerpaste.
plugins += ` powerpaste`;
return {
plugins,
toolbar,
menu,
contextmenu,
...pluginsettings
};
};

View File

@ -0,0 +1,41 @@
// 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 to get external content for Tiny Premium plugin.
*
* @module tiny_premium/external
* @copyright 2023 David Woloszyn <david.woloszyn@moodle.com>
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
import Ajax from 'core/ajax';
/**
* Due to the order items are initialise, options.js will not work in getting the API key.
* This external method is used to get the API key in time.
*
* @param {Number} contextId The context id
* @return {Promise}
*/
export const getApiKey = (contextId) => {
const request = {
methodname: 'tiny_premium_get_api_key',
args: {
contextid: contextId
}
};
return Ajax.call([request])[0];
};

View File

@ -0,0 +1,87 @@
// 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 Premium plugin for Moodle.
*
* @module tiny_premium/plugin
* @copyright 2023 David Woloszyn <david.woloszyn@moodle.com>
* @license https://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 'tiny_premium/common';
import * as Configuration from 'tiny_premium/configuration';
import {getApiKey} from 'tiny_premium/external';
import Config from 'core/config';
const currentContextId = Config.contextid;
// eslint-disable-next-line no-async-promise-executor
export default new Promise(async(resolve) => {
const [
tinyMCE,
pluginMetadata,
externalData
] = await Promise.all([
getTinyMCE(),
getPluginMetadata(component, pluginName),
getApiKey(currentContextId)
]);
tinyMCE.PluginManager.add(`${component}/plugin`, () => {
return pluginMetadata;
});
// Load the Tiny Premium script using the provided API key.
await getTinyPremium(externalData.apikey);
resolve([`${component}/plugin`, Configuration]);
});
let tinyPremiumPromise;
/**
* Promise for Tiny Premium plugins script.
*
* @param {string} apikey
* @return {Promise}
*/
const getTinyPremium = (apikey) => {
if (tinyPremiumPromise) {
return tinyPremiumPromise;
}
tinyPremiumPromise = new Promise((resolve, reject) => {
const head = document.querySelector('head');
const script = document.createElement('script');
script.dataset.tinymce = 'premium';
script.src = `https://cdn.tiny.cloud/1/${apikey}/tinymce/6/plugins.min.js`;
script.referrerpolicy = "origin";
script.addEventListener('load', () => {
resolve();
}, false);
script.addEventListener('error', (err) => {
reject(err);
}, false);
head.append(script);
});
return tinyPremiumPromise;
};

View File

@ -0,0 +1,78 @@
<?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_premium\external;
use context;
use core_external\external_api;
use core_external\external_function_parameters;
use core_external\external_single_structure;
use core_external\external_value;
/**
* External API for Tiny Premium.
*
* @package tiny_premium
* @copyright 2023 David Woloszyn <david.woloszyn@moodle.com>
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class get_api_key extends external_api {
/**
* Describes the parameters for Tiny Premium API key.
*
* @return external_function_parameters
* @since Moodle 4.3
*/
public static function execute_parameters(): external_function_parameters {
return new external_function_parameters([
'contextid' => new external_value(PARAM_INT, 'The current context ID.', VALUE_REQUIRED),
]);
}
/**
* External function to get the Tiny Premium API key.
*
* @param int $contextid
* @return array
* @since Moodle 4.3
*/
public static function execute(int $contextid): array {
[
'contextid' => $contextid,
] = self::validate_parameters(self::execute_parameters(), [
'contextid' => $contextid,
]);
$context = context::instance_by_id($contextid);
self::validate_context($context);
return [
'apikey' => get_config('tiny_premium', 'apikey'),
];
}
/**
* Describes the data returned from the external function.
*
* @return external_single_structure
* @since Moodle 4.3
*/
public static function execute_returns(): external_single_structure {
return new external_single_structure([
'apikey' => new external_value(PARAM_ALPHANUM, 'The API key for Tiny Premium'),
]);
}
}

View File

@ -0,0 +1,49 @@
<?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_premium;
use context;
use editor_tiny\editor;
use editor_tiny\plugin;
/**
* Tiny Premium plugin.
*
* @package tiny_premium
* @copyright 2023 David Woloszyn <david.woloszyn@moodle.com>
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class plugininfo extends plugin {
/**
* Determine if the plugin should be enabled by checking if the Tiny Premium API key is set.
*
* @param context $context The context that the editor is used within
* @param array $options The options passed in when requesting the editor
* @param array $fpoptions The filepicker options passed in when requesting the editor
* @param editor $editor The editor instance in which the plugin is initialised
* @return bool
*/
public static function is_enabled(
context $context,
array $options,
array $fpoptions,
?editor $editor = null
): bool {
return get_config('tiny_premium', 'apikey') != false;
}
}

View File

@ -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_premium\privacy;
/**
* Privacy Subsystem implementation for the Premium plugin for TinyMCE.
*
* @package tiny_premium
* @copyright 2023 David Woloszyn <david.woloszyn@moodle.com>
* @license https://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';
}
}

View File

@ -0,0 +1,36 @@
<?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 Premium external functions and service definitions.
*
* @package tiny_premium
* @copyright 2023 David Woloszyn <david.woloszyn@moodle.com>
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$functions = [
'tiny_premium_get_api_key' => [
'classname' => 'tiny_premium\external\get_api_key',
'methodname' => 'execute',
'description' => 'Get the Tiny Premium API key from Moodle',
'type' => 'read',
'capabilities' => '',
'ajax' => true,
],
];

View File

@ -0,0 +1,31 @@
<?php
// This file is part of Moodle - https://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 <https://www.gnu.org/licenses/>.
/**
* Strings for component 'tiny_premium', language 'en'.
*
* @package tiny_premium
* @category string
* @copyright 2023 David Woloszyn <david.woloszyn@moodle.com>
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$string['pluginname'] = 'Tiny Premium';
$string['apikey'] = 'API Key';
$string['apikey_desc'] = 'Your Tiny Premium API Key requires a paid subscription. You can obtain your key by accessing your Tiny Cloud account page.';
$string['privacy:metadata'] = 'The Tiny Premium plugin for TinyMCE does not store any personal data.';

View File

@ -0,0 +1,12 @@
Instructions for updating the Tiny Premium plugin for Moodle.
A request to Tiny Cloud is made in the plugin.js file of this plugin.
This request passes the Tiny Premium API key as part of a URL.
The URL also contains the major version of Tiny and may need to be updated.
The URL looks like this: https://cdn.tiny.cloud/1/YOUR_API_KEY/tinymce/6/plugins.min.js
Notice that the version (6) is baked into the URL and may need revision.
When upgrading, check Tiny Cloud's documentation regarding the correct API URL
to use. Go to https://www.tiny.cloud/docs/tinymce

View File

@ -0,0 +1,39 @@
<?php
// This file is part of Moodle - https://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 <https://www.gnu.org/licenses/>.
/**
* Settings for the Tiny Premium plugin.
*
* @package tiny_premium
* @category admin
* @copyright 2023 David Woloszyn <david.woloszyn@moodle.com>
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
if ($hassiteconfig) {
// phpcs:ignore Generic.CodeAnalysis.EmptyStatement.DetectedIf
if ($ADMIN->fulltree) {
$setting = new admin_setting_configpasswordunmask(
'tiny_premium/apikey',
get_string('apikey', 'tiny_premium'),
get_string('apikey_desc', 'tiny_premium'),
'',
);
$settings->add($setting);
}
}

View File

@ -0,0 +1,29 @@
<?php
// This file is part of Moodle - https://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 <https://www.gnu.org/licenses/>.
/**
* Plugin version and other meta-data are defined here.
*
* @package tiny_premium
* @copyright 2023 David Woloszyn <david.woloszyn@moodle.com>
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2023082200;
$plugin->requires = 2021051700;
$plugin->component = 'tiny_premium';