diff --git a/filter/glossary/amd/build/autolinker.min.js b/filter/glossary/amd/build/autolinker.min.js new file mode 100644 index 00000000000..7876a798a7f --- /dev/null +++ b/filter/glossary/amd/build/autolinker.min.js @@ -0,0 +1,10 @@ +define("filter_glossary/autolinker",["exports","core/ajax","core/modal_cancel","core/templates","core/str"],(function(_exports,_ajax,_modal_cancel,_templates,_str){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}} +/** + * Module for auto-linking glossary entries. + * + * @module filter_glossary/autolinker + * @copyright 2023 Mihail Geshoski + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,_ajax=_interopRequireDefault(_ajax),_modal_cancel=_interopRequireDefault(_modal_cancel),_templates=_interopRequireDefault(_templates);const Selectors_glossaryEntryAutoLink="a.glossary.autolink.concept",showGlossaryEntry=async entryId=>{const entryData=await fetchGlossaryEntry(entryId),{html:html,js:js}=await _templates.default.renderForPromise("filter_glossary/linked_glossary_entry",{definition:entryData.entry.definition,taglistdata:await generateTagListData(entryData.entry.tags),hasattachments:Boolean(entryData.entry.attachment),attachments:entryData.entry.attachments}),modal=await _modal_cancel.default.create({title:entryData.entry.concept,body:html,isVerticallyCentered:!0,buttons:{cancel:await(0,_str.getString)("ok")}});return _templates.default.runTemplateJS(js),modal.show(),modal},fetchGlossaryEntry=entryId=>{const request={methodname:"mod_glossary_get_entry_by_id",args:{id:entryId}};return _ajax.default.call([request])[0]},glossaryEntryViewed=entryId=>{const request={methodname:"mod_glossary_view_entry",args:{id:entryId}};return _ajax.default.call([request])[0]},generateTagListData=async tags=>{const hasOverflow=tags.length>10;if(hasOverflow)for(let i=10;i{document.addEventListener("click",(async e=>{const glossaryEntryAutoLink=e.target.closest(Selectors_glossaryEntryAutoLink);if(glossaryEntryAutoLink){e.preventDefault();const entryId=glossaryEntryAutoLink.dataset.entryid;await showGlossaryEntry(entryId),await glossaryEntryViewed(entryId)}}))}})); + +//# sourceMappingURL=autolinker.min.js.map \ No newline at end of file diff --git a/filter/glossary/amd/build/autolinker.min.js.map b/filter/glossary/amd/build/autolinker.min.js.map new file mode 100644 index 00000000000..16cba74f989 --- /dev/null +++ b/filter/glossary/amd/build/autolinker.min.js.map @@ -0,0 +1 @@ +{"version":3,"file":"autolinker.min.js","sources":["../src/autolinker.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 .\n\n/**\n * Module for auto-linking glossary entries.\n *\n * @module filter_glossary/autolinker\n * @copyright 2023 Mihail Geshoski \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport Ajax from 'core/ajax';\nimport ModalCancel from \"core/modal_cancel\";\nimport Templates from 'core/templates';\nimport {getString} from 'core/str';\n\n/** @constant {Object} The object containing the relevant selectors. */\nconst Selectors = {\n glossaryEntryAutoLink: 'a.glossary.autolink.concept',\n};\n\n/**\n * Register the event listeners for the glossary entry auto-linker.\n *\n * @return {void}\n */\nconst registerEventListeners = () => {\n document.addEventListener('click', async(e) => {\n const glossaryEntryAutoLink = e.target.closest(Selectors.glossaryEntryAutoLink);\n if (glossaryEntryAutoLink) {\n e.preventDefault();\n const entryId = glossaryEntryAutoLink.dataset.entryid;\n await showGlossaryEntry(entryId);\n await glossaryEntryViewed(entryId);\n }\n });\n};\n\n/**\n * Show the linked glossary entry in a modal.\n *\n * @method showGlossaryEntry\n * @param {int} entryId The id of the linked glossary entry.\n * @returns {Promise} The modal promise.\n */\nconst showGlossaryEntry = async(entryId) => {\n const entryData = await fetchGlossaryEntry(entryId);\n // Obtain the HTML and JS used for rendering the auto-linked glossary entry.\n const {html, js} = await Templates.renderForPromise('filter_glossary/linked_glossary_entry', {\n definition: entryData.entry.definition,\n taglistdata: await generateTagListData(entryData.entry.tags),\n hasattachments: Boolean(entryData.entry.attachment),\n attachments: entryData.entry.attachments\n });\n // Create the modal.\n const modal = await ModalCancel.create({\n title: entryData.entry.concept,\n body: html,\n isVerticallyCentered: true,\n buttons: {\n cancel: await getString('ok')\n }\n });\n // Execute the JS code returned from the template once the modal is created.\n Templates.runTemplateJS(js);\n // Display the modal.\n modal.show();\n\n return modal;\n};\n\n/**\n * Fetch the linked glossary entry.\n *\n * @method fetchGlossaryEntry\n * @param {int} entryId The id of the linked glossary entry.\n * @returns {Promise} The glossary entry promise.\n */\nconst fetchGlossaryEntry = (entryId) => {\n const request = {\n methodname: 'mod_glossary_get_entry_by_id',\n args: {\n id: entryId,\n },\n };\n return Ajax.call([request])[0];\n};\n\n/**\n * Notify that the linked glossary entry was viewed.\n *\n * @method glossaryEntryViewed\n * @param {int} entryId The id of the linked glossary entry.\n * @returns {Promise} The promise object.\n */\nconst glossaryEntryViewed = (entryId) => {\n const request = {\n methodname: 'mod_glossary_view_entry',\n args: {\n id: entryId,\n },\n };\n return Ajax.call([request])[0];\n};\n\n/**\n * Generates an object that contains the data required to render a tag list.\n *\n * @method generateTagListData\n * @param {array} tags The array containing the tags related to the linked glossary entry.\n * @returns {Object} The data required to render a tag list.\n */\nconst generateTagListData = async(tags) => {\n // Define the number of initially displayed tags.\n const limit = 10;\n const hasOverflow = tags.length > limit;\n // If the total number of tags exceeds the defined limit, then we need to mark all the excess tags as over the limit.\n // By specifying this, these tags will be initially hidden.\n if (hasOverflow) {\n for (let i = limit; i < tags.length; i++) {\n tags[i].overlimit = true;\n }\n }\n\n return {\n tags: tags,\n tagscount: tags.length,\n overflow: hasOverflow,\n label: await getString('tags')\n };\n};\n\n/**\n * Initialize the module.\n */\nexport const init = () => {\n registerEventListeners();\n};\n"],"names":["Selectors","showGlossaryEntry","async","entryData","fetchGlossaryEntry","entryId","html","js","Templates","renderForPromise","definition","entry","taglistdata","generateTagListData","tags","hasattachments","Boolean","attachment","attachments","modal","ModalCancel","create","title","concept","body","isVerticallyCentered","buttons","cancel","runTemplateJS","show","request","methodname","args","id","Ajax","call","glossaryEntryViewed","hasOverflow","length","i","overlimit","tagscount","overflow","label","document","addEventListener","glossaryEntryAutoLink","e","target","closest","preventDefault","dataset","entryid"],"mappings":";;;;;;;8NA6BMA,gCACqB,8BA2BrBC,kBAAoBC,MAAAA,gBAChBC,gBAAkBC,mBAAmBC,UAErCC,KAACA,KAADC,GAAOA,UAAYC,mBAAUC,iBAAiB,wCAAyC,CACzFC,WAAYP,UAAUQ,MAAMD,WAC5BE,kBAAmBC,oBAAoBV,UAAUQ,MAAMG,MACvDC,eAAgBC,QAAQb,UAAUQ,MAAMM,YACxCC,YAAaf,UAAUQ,MAAMO,cAG3BC,YAAcC,sBAAYC,OAAO,CACnCC,MAAOnB,UAAUQ,MAAMY,QACvBC,KAAMlB,KACNmB,sBAAsB,EACtBC,QAAS,CACLC,aAAc,kBAAU,mCAItBC,cAAcrB,IAExBY,MAAMU,OAECV,OAULf,mBAAsBC,gBAClByB,QAAU,CACZC,WAAY,+BACZC,KAAM,CACFC,GAAI5B,iBAGL6B,cAAKC,KAAK,CAACL,UAAU,IAU1BM,oBAAuB/B,gBACnByB,QAAU,CACZC,WAAY,0BACZC,KAAM,CACFC,GAAI5B,iBAGL6B,cAAKC,KAAK,CAACL,UAAU,IAU1BjB,oBAAsBX,MAAAA,aAGlBmC,YAAcvB,KAAKwB,OADX,MAIVD,gBACK,IAAIE,EALC,GAKUA,EAAIzB,KAAKwB,OAAQC,IACjCzB,KAAKyB,GAAGC,WAAY,QAIrB,CACH1B,KAAMA,KACN2B,UAAW3B,KAAKwB,OAChBI,SAAUL,YACVM,YAAa,kBAAU,wBAOX,KA5GhBC,SAASC,iBAAiB,SAAS3C,MAAAA,UACzB4C,sBAAwBC,EAAEC,OAAOC,QAAQjD,oCAC3C8C,sBAAuB,CACvBC,EAAEG,uBACI7C,QAAUyC,sBAAsBK,QAAQC,cACxCnD,kBAAkBI,eAClB+B,oBAAoB/B"} \ No newline at end of file diff --git a/filter/glossary/amd/src/autolinker.js b/filter/glossary/amd/src/autolinker.js new file mode 100644 index 00000000000..83913571e07 --- /dev/null +++ b/filter/glossary/amd/src/autolinker.js @@ -0,0 +1,150 @@ +// 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 . + +/** + * Module for auto-linking glossary entries. + * + * @module filter_glossary/autolinker + * @copyright 2023 Mihail Geshoski + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +import Ajax from 'core/ajax'; +import ModalCancel from "core/modal_cancel"; +import Templates from 'core/templates'; +import {getString} from 'core/str'; + +/** @constant {Object} The object containing the relevant selectors. */ +const Selectors = { + glossaryEntryAutoLink: 'a.glossary.autolink.concept', +}; + +/** + * Register the event listeners for the glossary entry auto-linker. + * + * @return {void} + */ +const registerEventListeners = () => { + document.addEventListener('click', async(e) => { + const glossaryEntryAutoLink = e.target.closest(Selectors.glossaryEntryAutoLink); + if (glossaryEntryAutoLink) { + e.preventDefault(); + const entryId = glossaryEntryAutoLink.dataset.entryid; + await showGlossaryEntry(entryId); + await glossaryEntryViewed(entryId); + } + }); +}; + +/** + * Show the linked glossary entry in a modal. + * + * @method showGlossaryEntry + * @param {int} entryId The id of the linked glossary entry. + * @returns {Promise} The modal promise. + */ +const showGlossaryEntry = async(entryId) => { + const entryData = await fetchGlossaryEntry(entryId); + // Obtain the HTML and JS used for rendering the auto-linked glossary entry. + const {html, js} = await Templates.renderForPromise('filter_glossary/linked_glossary_entry', { + definition: entryData.entry.definition, + taglistdata: await generateTagListData(entryData.entry.tags), + hasattachments: Boolean(entryData.entry.attachment), + attachments: entryData.entry.attachments + }); + // Create the modal. + const modal = await ModalCancel.create({ + title: entryData.entry.concept, + body: html, + isVerticallyCentered: true, + buttons: { + cancel: await getString('ok') + } + }); + // Execute the JS code returned from the template once the modal is created. + Templates.runTemplateJS(js); + // Display the modal. + modal.show(); + + return modal; +}; + +/** + * Fetch the linked glossary entry. + * + * @method fetchGlossaryEntry + * @param {int} entryId The id of the linked glossary entry. + * @returns {Promise} The glossary entry promise. + */ +const fetchGlossaryEntry = (entryId) => { + const request = { + methodname: 'mod_glossary_get_entry_by_id', + args: { + id: entryId, + }, + }; + return Ajax.call([request])[0]; +}; + +/** + * Notify that the linked glossary entry was viewed. + * + * @method glossaryEntryViewed + * @param {int} entryId The id of the linked glossary entry. + * @returns {Promise} The promise object. + */ +const glossaryEntryViewed = (entryId) => { + const request = { + methodname: 'mod_glossary_view_entry', + args: { + id: entryId, + }, + }; + return Ajax.call([request])[0]; +}; + +/** + * Generates an object that contains the data required to render a tag list. + * + * @method generateTagListData + * @param {array} tags The array containing the tags related to the linked glossary entry. + * @returns {Object} The data required to render a tag list. + */ +const generateTagListData = async(tags) => { + // Define the number of initially displayed tags. + const limit = 10; + const hasOverflow = tags.length > limit; + // If the total number of tags exceeds the defined limit, then we need to mark all the excess tags as over the limit. + // By specifying this, these tags will be initially hidden. + if (hasOverflow) { + for (let i = limit; i < tags.length; i++) { + tags[i].overlimit = true; + } + } + + return { + tags: tags, + tagscount: tags.length, + overflow: hasOverflow, + label: await getString('tags') + }; +}; + +/** + * Initialize the module. + */ +export const init = () => { + registerEventListeners(); +}; diff --git a/filter/glossary/filter.php b/filter/glossary/filter.php index 1f2591836a1..65f9186e8a4 100644 --- a/filter/glossary/filter.php +++ b/filter/glossary/filter.php @@ -38,11 +38,7 @@ class filter_glossary extends moodle_text_filter { public function setup($page, $context) { if ($page->requires->should_create_one_time_item_now('filter_glossary_autolinker')) { - $page->requires->yui_module( - 'moodle-filter_glossary-autolinker', - 'M.filter_glossary.init_filter_autolinking', - array(array('courseid' => 0))); - $page->requires->strings_for_js(array('ok'), 'moodle'); + $page->requires->js_call_amd('filter_glossary/autolinker', 'init', []); } } @@ -145,7 +141,9 @@ class filter_glossary extends moodle_text_filter { $attributes = array( 'href' => $link, 'title' => str_replace('&', '&', $title), // Undo the s() mangling. - 'class' => 'glossary autolink concept glossaryid' . $concept->glossaryid); + 'class' => 'glossary autolink concept glossaryid' . $concept->glossaryid, + 'data-entryid' => $concept->id, + ); } // This flag is optionally set by resource_pluginfile() diff --git a/filter/glossary/lang/en/filter_glossary.php b/filter/glossary/lang/en/filter_glossary.php index d7917afb25c..ee75e57f570 100644 --- a/filter/glossary/lang/en/filter_glossary.php +++ b/filter/glossary/lang/en/filter_glossary.php @@ -29,3 +29,4 @@ $string['glossarycategory'] = '{$a->glossary}: Category {$a->category}'; $string['glossaryconcept'] = '{$a->glossary}: {$a->concept}'; $string['filtername'] = 'Glossary auto-linking'; $string['privacy:metadata'] = 'The Glossary auto-linking plugin does not store any personal data.'; +$string['attachments'] = 'Attachments'; diff --git a/filter/glossary/templates/linked_glossary_entry.mustache b/filter/glossary/templates/linked_glossary_entry.mustache new file mode 100644 index 00000000000..a96e25ad546 --- /dev/null +++ b/filter/glossary/templates/linked_glossary_entry.mustache @@ -0,0 +1,74 @@ +{{! + 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 . +}} +{{! + @template filter_glossary/linked_glossary_entry + + Renders the linked glossary entry. + + Context variables required for this template: + * definition - The definition of the linked glossary entry. + * taglistdata - The data for the tag list related to the linked glossary entry. + * hasattachments - Whether the linked glossary entry has attachments. + * attachments - The data for the attachments related to the linked glossary entry. + + Example context (json): + { + "definition": 1, + "taglistdata": { + "tags": [ + { + "id": 1, + "name": "Cats", + "viewurl": "http://moodle.org/tag/index.php?tag=Cats", + "isstandard": true, + "flag": 0 + } + ], + "label": "Tags", + "tagscount": 1, + "overflow": false + }, + "hasattachments": true, + "attachments": [ + { + "filename": "example.jpg", + "fileurl": "www.example.com/example.jpg", + "icon": "f/image" + } + ] + } +}} + +

{{{definition}}}

+{{#taglistdata}} +
+ {{> core_tag/taglist }} +
+{{/taglistdata}} +{{#hasattachments}} + {{#str}} attachments, filter_glossary {{/str}}: +
    + {{#attachments}} +
  • + {{#pix}} {{icon}}, core {{/pix}} + + {{filename}} + +
  • + {{/attachments}} +
+{{/hasattachments}} diff --git a/filter/glossary/yui/build/moodle-filter_glossary-autolinker/moodle-filter_glossary-autolinker-debug.js b/filter/glossary/yui/build/moodle-filter_glossary-autolinker/moodle-filter_glossary-autolinker-debug.js deleted file mode 100644 index 81f03933b08..00000000000 --- a/filter/glossary/yui/build/moodle-filter_glossary-autolinker/moodle-filter_glossary-autolinker-debug.js +++ /dev/null @@ -1,193 +0,0 @@ -YUI.add('moodle-filter_glossary-autolinker', function (Y, NAME) { - -var AUTOLINKERNAME = 'Glossary filter autolinker', - WIDTH = 'width', - HEIGHT = 'height', - MENUBAR = 'menubar', - LOCATION = 'location', - SCROLLBARS = 'scrollbars', - RESIZEABLE = 'resizable', - TOOLBAR = 'toolbar', - STATUS = 'status', - DIRECTORIES = 'directories', - FULLSCREEN = 'fullscreen', - DEPENDENT = 'dependent', - AUTOLINKER; - -AUTOLINKER = function() { - AUTOLINKER.superclass.constructor.apply(this, arguments); -}; -Y.extend(AUTOLINKER, Y.Base, { - overlay: null, - alertpanels: {}, - initializer: function() { - var self = this; - require(['core/event'], function(event) { - Y.delegate('click', function(e) { - e.preventDefault(); - - // display a progress indicator - var title = '', - content = Y.Node.create('
' + - '
'), - o = new Y.Overlay({ - headerContent: title, - bodyContent: content - }), - fullurl, - cfg; - - window.require(['core/templates'], function(Templates) { - Templates.renderPix('i/loading', 'core').then(function(html) { - content.append(html); - }); - }); - - self.overlay = o; - o.render(Y.one(document.body)); - - // Switch over to the ajax url and fetch the glossary item - fullurl = this.getAttribute('href').replace('showentry.php', 'showentry_ajax.php'); - cfg = { - method: 'get', - context: self, - on: { - success: function(id, o) { - this.display_callback(o.responseText, event); - }, - failure: function(id, o) { - var debuginfo = o.statusText; - if (M.cfg.developerdebug) { - o.statusText += ' (' + fullurl + ')'; - } - new M.core.exception({message: debuginfo}); - } - } - }; - Y.io(fullurl, cfg); - - }, Y.one(document.body), 'a.glossary.autolink.concept'); - }); - }, - /** - * @method display_callback - * @param {String} content - Content to display - * @param {Object} event The amd event module used to fire events for jquery and yui. - */ - display_callback: function(content, event) { - var data, - key, - alertpanel, - alertpanelid, - definition, - position; - try { - data = Y.JSON.parse(content); - if (data.success) { - this.overlay.hide(); // hide progress indicator - - for (key in data.entries) { - definition = data.entries[key].definition + data.entries[key].attachments; - alertpanel = new M.core.alert({title: data.entries[key].concept, draggable: true, - message: definition, modal: false, yesLabel: M.util.get_string('ok', 'moodle')}); - // Notify the filters about the modified nodes. - event.notifyFilterContentUpdated(alertpanel.get('boundingBox').getDOMNode()); - Y.Node.one('#id_yuialertconfirm-' + alertpanel.get('COUNT')).focus(); - - // Register alertpanel for stacking. - alertpanelid = '#moodle-dialogue-' + alertpanel.get('COUNT'); - alertpanel.on('complete', this._deletealertpanel, this, alertpanelid); - - // We already have some windows opened, so set the right position... - if (!Y.Object.isEmpty(this.alertpanels)) { - position = this._getLatestWindowPosition(); - Y.Node.one(alertpanelid).setXY([position[0] + 10, position[1] + 10]); - } - - this.alertpanels[alertpanelid] = Y.Node.one(alertpanelid).getXY(); - } - - return true; - } else if (data.error) { - new M.core.ajaxException(data); - } - } catch (e) { - new M.core.exception(e); - } - return false; - }, - _getLatestWindowPosition: function() { - var lastPosition = [0, 0]; - Y.Object.each(this.alertpanels, function(position) { - if (position[0] > lastPosition[0]) { - lastPosition = position; - } - }); - return lastPosition; - }, - _deletealertpanel: function(ev, alertpanelid) { - delete this.alertpanels[alertpanelid]; - } -}, { - NAME: AUTOLINKERNAME, - ATTRS: { - url: { - validator: Y.Lang.isString, - value: M.cfg.wwwroot + '/mod/glossary/showentry.php' - }, - name: { - validator: Y.Lang.isString, - value: 'glossaryconcept' - }, - options: { - getter: function() { - return { - width: this.get(WIDTH), - height: this.get(HEIGHT), - menubar: this.get(MENUBAR), - location: this.get(LOCATION), - scrollbars: this.get(SCROLLBARS), - resizable: this.get(RESIZEABLE), - toolbar: this.get(TOOLBAR), - status: this.get(STATUS), - directories: this.get(DIRECTORIES), - fullscreen: this.get(FULLSCREEN), - dependent: this.get(DEPENDENT) - }; - }, - readOnly: true - }, - width: {value: 600}, - height: {value: 450}, - menubar: {value: false}, - location: {value: false}, - scrollbars: {value: true}, - resizable: {value: true}, - toolbar: {value: true}, - status: {value: true}, - directories: {value: false}, - fullscreen: {value: false}, - dependent: {value: true} - } -}); - -M.filter_glossary = M.filter_glossary || {}; -M.filter_glossary.init_filter_autolinking = function(config) { - return new AUTOLINKER(config); -}; - - -}, '@VERSION@', { - "requires": [ - "base", - "node", - "io-base", - "json-parse", - "event-delegate", - "overlay", - "moodle-core-event", - "moodle-core-notification-alert", - "moodle-core-notification-exception", - "moodle-core-notification-ajaxexception" - ] -}); diff --git a/filter/glossary/yui/build/moodle-filter_glossary-autolinker/moodle-filter_glossary-autolinker-min.js b/filter/glossary/yui/build/moodle-filter_glossary-autolinker/moodle-filter_glossary-autolinker-min.js deleted file mode 100644 index 20d23ce17fb..00000000000 --- a/filter/glossary/yui/build/moodle-filter_glossary-autolinker/moodle-filter_glossary-autolinker-min.js +++ /dev/null @@ -1 +0,0 @@ -YUI.add("moodle-filter_glossary-autolinker",function(c,e){var t=function(){t.superclass.constructor.apply(this,arguments)};c.extend(t,c.Base,{overlay:null,alertpanels:{},initializer:function(){var i=this;require(["core/event"],function(o){c.delegate("click",function(e){e.preventDefault();var n,t=c.Node.create('
'),e=new c.Overlay({headerContent:"",bodyContent:t});window.require(["core/templates"],function(e){e.renderPix("i/loading","core").then(function(e){t.append(e)})}),(i.overlay=e).render(c.one(document.body)),n=this.getAttribute("href").replace("showentry.php","showentry_ajax.php"),c.io(n,{method:"get",context:i,on:{success:function(e,t){this.display_callback(t.responseText,o)},failure:function(e,t){var o=t.statusText;M.cfg.developerdebug&&(t.statusText+=" ("+n+")"),new M.core.exception({message:o})}}})},c.one(document.body),"a.glossary.autolink.concept")})},display_callback:function(e,t){var o,n,i,r,a,l;try{if((o=c.JSON.parse(e)).success){for(n in this.overlay.hide(),o.entries)a=o.entries[n].definition+o.entries[n].attachments,i=new M.core.alert({title:o.entries[n].concept,draggable:!0,message:a,modal:!1,yesLabel:M.util.get_string("ok","moodle")}),t.notifyFilterContentUpdated(i.get("boundingBox").getDOMNode()),c.Node.one("#id_yuialertconfirm-"+i.get("COUNT")).focus(),r="#moodle-dialogue-"+i.get("COUNT"),i.on("complete",this._deletealertpanel,this,r),c.Object.isEmpty(this.alertpanels)||(l=this._getLatestWindowPosition(),c.Node.one(r).setXY([l[0]+10,l[1]+10])),this.alertpanels[r]=c.Node.one(r).getXY();return!0}o.error&&new M.core.ajaxException(o)}catch(s){new M.core.exception(s)}return!1},_getLatestWindowPosition:function(){var t=[0,0];return c.Object.each(this.alertpanels,function(e){e[0]>t[0]&&(t=e)}),t},_deletealertpanel:function(e,t){delete this.alertpanels[t]}},{NAME:"Glossary filter autolinker",ATTRS:{url:{validator:c.Lang.isString,value:M.cfg.wwwroot+"/mod/glossary/showentry.php"},name:{validator:c.Lang.isString,value:"glossaryconcept"},options:{getter:function(){return{width:this.get("width"),height:this.get("height"),menubar:this.get("menubar"),location:this.get("location"),scrollbars:this.get("scrollbars"),resizable:this.get("resizable"),toolbar:this.get("toolbar"),status:this.get("status"),directories:this.get("directories"),fullscreen:this.get("fullscreen"),dependent:this.get("dependent")}},readOnly:!0},width:{value:600},height:{value:450},menubar:{value:!1},location:{value:!1},scrollbars:{value:!0},resizable:{value:!0},toolbar:{value:!0},status:{value:!0},directories:{value:!1},fullscreen:{value:!1},dependent:{value:!0}}}),M.filter_glossary=M.filter_glossary||{},M.filter_glossary.init_filter_autolinking=function(e){return new t(e)}},"@VERSION@",{requires:["base","node","io-base","json-parse","event-delegate","overlay","moodle-core-event","moodle-core-notification-alert","moodle-core-notification-exception","moodle-core-notification-ajaxexception"]}); \ No newline at end of file diff --git a/filter/glossary/yui/build/moodle-filter_glossary-autolinker/moodle-filter_glossary-autolinker.js b/filter/glossary/yui/build/moodle-filter_glossary-autolinker/moodle-filter_glossary-autolinker.js deleted file mode 100644 index 81f03933b08..00000000000 --- a/filter/glossary/yui/build/moodle-filter_glossary-autolinker/moodle-filter_glossary-autolinker.js +++ /dev/null @@ -1,193 +0,0 @@ -YUI.add('moodle-filter_glossary-autolinker', function (Y, NAME) { - -var AUTOLINKERNAME = 'Glossary filter autolinker', - WIDTH = 'width', - HEIGHT = 'height', - MENUBAR = 'menubar', - LOCATION = 'location', - SCROLLBARS = 'scrollbars', - RESIZEABLE = 'resizable', - TOOLBAR = 'toolbar', - STATUS = 'status', - DIRECTORIES = 'directories', - FULLSCREEN = 'fullscreen', - DEPENDENT = 'dependent', - AUTOLINKER; - -AUTOLINKER = function() { - AUTOLINKER.superclass.constructor.apply(this, arguments); -}; -Y.extend(AUTOLINKER, Y.Base, { - overlay: null, - alertpanels: {}, - initializer: function() { - var self = this; - require(['core/event'], function(event) { - Y.delegate('click', function(e) { - e.preventDefault(); - - // display a progress indicator - var title = '', - content = Y.Node.create('
' + - '
'), - o = new Y.Overlay({ - headerContent: title, - bodyContent: content - }), - fullurl, - cfg; - - window.require(['core/templates'], function(Templates) { - Templates.renderPix('i/loading', 'core').then(function(html) { - content.append(html); - }); - }); - - self.overlay = o; - o.render(Y.one(document.body)); - - // Switch over to the ajax url and fetch the glossary item - fullurl = this.getAttribute('href').replace('showentry.php', 'showentry_ajax.php'); - cfg = { - method: 'get', - context: self, - on: { - success: function(id, o) { - this.display_callback(o.responseText, event); - }, - failure: function(id, o) { - var debuginfo = o.statusText; - if (M.cfg.developerdebug) { - o.statusText += ' (' + fullurl + ')'; - } - new M.core.exception({message: debuginfo}); - } - } - }; - Y.io(fullurl, cfg); - - }, Y.one(document.body), 'a.glossary.autolink.concept'); - }); - }, - /** - * @method display_callback - * @param {String} content - Content to display - * @param {Object} event The amd event module used to fire events for jquery and yui. - */ - display_callback: function(content, event) { - var data, - key, - alertpanel, - alertpanelid, - definition, - position; - try { - data = Y.JSON.parse(content); - if (data.success) { - this.overlay.hide(); // hide progress indicator - - for (key in data.entries) { - definition = data.entries[key].definition + data.entries[key].attachments; - alertpanel = new M.core.alert({title: data.entries[key].concept, draggable: true, - message: definition, modal: false, yesLabel: M.util.get_string('ok', 'moodle')}); - // Notify the filters about the modified nodes. - event.notifyFilterContentUpdated(alertpanel.get('boundingBox').getDOMNode()); - Y.Node.one('#id_yuialertconfirm-' + alertpanel.get('COUNT')).focus(); - - // Register alertpanel for stacking. - alertpanelid = '#moodle-dialogue-' + alertpanel.get('COUNT'); - alertpanel.on('complete', this._deletealertpanel, this, alertpanelid); - - // We already have some windows opened, so set the right position... - if (!Y.Object.isEmpty(this.alertpanels)) { - position = this._getLatestWindowPosition(); - Y.Node.one(alertpanelid).setXY([position[0] + 10, position[1] + 10]); - } - - this.alertpanels[alertpanelid] = Y.Node.one(alertpanelid).getXY(); - } - - return true; - } else if (data.error) { - new M.core.ajaxException(data); - } - } catch (e) { - new M.core.exception(e); - } - return false; - }, - _getLatestWindowPosition: function() { - var lastPosition = [0, 0]; - Y.Object.each(this.alertpanels, function(position) { - if (position[0] > lastPosition[0]) { - lastPosition = position; - } - }); - return lastPosition; - }, - _deletealertpanel: function(ev, alertpanelid) { - delete this.alertpanels[alertpanelid]; - } -}, { - NAME: AUTOLINKERNAME, - ATTRS: { - url: { - validator: Y.Lang.isString, - value: M.cfg.wwwroot + '/mod/glossary/showentry.php' - }, - name: { - validator: Y.Lang.isString, - value: 'glossaryconcept' - }, - options: { - getter: function() { - return { - width: this.get(WIDTH), - height: this.get(HEIGHT), - menubar: this.get(MENUBAR), - location: this.get(LOCATION), - scrollbars: this.get(SCROLLBARS), - resizable: this.get(RESIZEABLE), - toolbar: this.get(TOOLBAR), - status: this.get(STATUS), - directories: this.get(DIRECTORIES), - fullscreen: this.get(FULLSCREEN), - dependent: this.get(DEPENDENT) - }; - }, - readOnly: true - }, - width: {value: 600}, - height: {value: 450}, - menubar: {value: false}, - location: {value: false}, - scrollbars: {value: true}, - resizable: {value: true}, - toolbar: {value: true}, - status: {value: true}, - directories: {value: false}, - fullscreen: {value: false}, - dependent: {value: true} - } -}); - -M.filter_glossary = M.filter_glossary || {}; -M.filter_glossary.init_filter_autolinking = function(config) { - return new AUTOLINKER(config); -}; - - -}, '@VERSION@', { - "requires": [ - "base", - "node", - "io-base", - "json-parse", - "event-delegate", - "overlay", - "moodle-core-event", - "moodle-core-notification-alert", - "moodle-core-notification-exception", - "moodle-core-notification-ajaxexception" - ] -}); diff --git a/filter/glossary/yui/src/autolinker/build.json b/filter/glossary/yui/src/autolinker/build.json deleted file mode 100644 index e6e0e90ad47..00000000000 --- a/filter/glossary/yui/src/autolinker/build.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "name": "moodle-filter_glossary-autolinker", - "builds": { - "moodle-filter_glossary-autolinker": { - "jsfiles": [ - "autolinker.js" - ] - } - } -} diff --git a/filter/glossary/yui/src/autolinker/js/autolinker.js b/filter/glossary/yui/src/autolinker/js/autolinker.js deleted file mode 100644 index 8aea8fdfa41..00000000000 --- a/filter/glossary/yui/src/autolinker/js/autolinker.js +++ /dev/null @@ -1,175 +0,0 @@ -var AUTOLINKERNAME = 'Glossary filter autolinker', - WIDTH = 'width', - HEIGHT = 'height', - MENUBAR = 'menubar', - LOCATION = 'location', - SCROLLBARS = 'scrollbars', - RESIZEABLE = 'resizable', - TOOLBAR = 'toolbar', - STATUS = 'status', - DIRECTORIES = 'directories', - FULLSCREEN = 'fullscreen', - DEPENDENT = 'dependent', - AUTOLINKER; - -AUTOLINKER = function() { - AUTOLINKER.superclass.constructor.apply(this, arguments); -}; -Y.extend(AUTOLINKER, Y.Base, { - overlay: null, - alertpanels: {}, - initializer: function() { - var self = this; - require(['core/event'], function(event) { - Y.delegate('click', function(e) { - e.preventDefault(); - - // display a progress indicator - var title = '', - content = Y.Node.create('
' + - '
'), - o = new Y.Overlay({ - headerContent: title, - bodyContent: content - }), - fullurl, - cfg; - - window.require(['core/templates'], function(Templates) { - Templates.renderPix('i/loading', 'core').then(function(html) { - content.append(html); - }); - }); - - self.overlay = o; - o.render(Y.one(document.body)); - - // Switch over to the ajax url and fetch the glossary item - fullurl = this.getAttribute('href').replace('showentry.php', 'showentry_ajax.php'); - cfg = { - method: 'get', - context: self, - on: { - success: function(id, o) { - this.display_callback(o.responseText, event); - }, - failure: function(id, o) { - var debuginfo = o.statusText; - if (M.cfg.developerdebug) { - o.statusText += ' (' + fullurl + ')'; - } - new M.core.exception({message: debuginfo}); - } - } - }; - Y.io(fullurl, cfg); - - }, Y.one(document.body), 'a.glossary.autolink.concept'); - }); - }, - /** - * @method display_callback - * @param {String} content - Content to display - * @param {Object} event The amd event module used to fire events for jquery and yui. - */ - display_callback: function(content, event) { - var data, - key, - alertpanel, - alertpanelid, - definition, - position; - try { - data = Y.JSON.parse(content); - if (data.success) { - this.overlay.hide(); // hide progress indicator - - for (key in data.entries) { - definition = data.entries[key].definition + data.entries[key].attachments; - alertpanel = new M.core.alert({title: data.entries[key].concept, draggable: true, - message: definition, modal: false, yesLabel: M.util.get_string('ok', 'moodle')}); - // Notify the filters about the modified nodes. - event.notifyFilterContentUpdated(alertpanel.get('boundingBox').getDOMNode()); - Y.Node.one('#id_yuialertconfirm-' + alertpanel.get('COUNT')).focus(); - - // Register alertpanel for stacking. - alertpanelid = '#moodle-dialogue-' + alertpanel.get('COUNT'); - alertpanel.on('complete', this._deletealertpanel, this, alertpanelid); - - // We already have some windows opened, so set the right position... - if (!Y.Object.isEmpty(this.alertpanels)) { - position = this._getLatestWindowPosition(); - Y.Node.one(alertpanelid).setXY([position[0] + 10, position[1] + 10]); - } - - this.alertpanels[alertpanelid] = Y.Node.one(alertpanelid).getXY(); - } - - return true; - } else if (data.error) { - new M.core.ajaxException(data); - } - } catch (e) { - new M.core.exception(e); - } - return false; - }, - _getLatestWindowPosition: function() { - var lastPosition = [0, 0]; - Y.Object.each(this.alertpanels, function(position) { - if (position[0] > lastPosition[0]) { - lastPosition = position; - } - }); - return lastPosition; - }, - _deletealertpanel: function(ev, alertpanelid) { - delete this.alertpanels[alertpanelid]; - } -}, { - NAME: AUTOLINKERNAME, - ATTRS: { - url: { - validator: Y.Lang.isString, - value: M.cfg.wwwroot + '/mod/glossary/showentry.php' - }, - name: { - validator: Y.Lang.isString, - value: 'glossaryconcept' - }, - options: { - getter: function() { - return { - width: this.get(WIDTH), - height: this.get(HEIGHT), - menubar: this.get(MENUBAR), - location: this.get(LOCATION), - scrollbars: this.get(SCROLLBARS), - resizable: this.get(RESIZEABLE), - toolbar: this.get(TOOLBAR), - status: this.get(STATUS), - directories: this.get(DIRECTORIES), - fullscreen: this.get(FULLSCREEN), - dependent: this.get(DEPENDENT) - }; - }, - readOnly: true - }, - width: {value: 600}, - height: {value: 450}, - menubar: {value: false}, - location: {value: false}, - scrollbars: {value: true}, - resizable: {value: true}, - toolbar: {value: true}, - status: {value: true}, - directories: {value: false}, - fullscreen: {value: false}, - dependent: {value: true} - } -}); - -M.filter_glossary = M.filter_glossary || {}; -M.filter_glossary.init_filter_autolinking = function(config) { - return new AUTOLINKER(config); -}; diff --git a/filter/glossary/yui/src/autolinker/meta/autolinker.json b/filter/glossary/yui/src/autolinker/meta/autolinker.json deleted file mode 100644 index 36f0fea5ef9..00000000000 --- a/filter/glossary/yui/src/autolinker/meta/autolinker.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "moodle-filter_glossary-autolinker": { - "requires": [ - "base", - "node", - "io-base", - "json-parse", - "event-delegate", - "overlay", - "moodle-core-event", - "moodle-core-notification-alert", - "moodle-core-notification-exception", - "moodle-core-notification-ajaxexception" - ] - } -} diff --git a/mod/glossary/db/services.php b/mod/glossary/db/services.php index 2614b9143c5..5ddce771e64 100644 --- a/mod/glossary/db/services.php +++ b/mod/glossary/db/services.php @@ -50,6 +50,7 @@ $functions = array( 'methodname' => 'view_entry', 'description' => 'Notify a glossary entry as being viewed.', 'type' => 'write', + 'ajax' => true, 'capabilities' => 'mod/glossary:view', 'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE) ), @@ -149,6 +150,7 @@ $functions = array( 'methodname' => 'get_entry_by_id', 'description' => 'Get an entry by ID', 'type' => 'read', + 'ajax' => true, 'capabilities' => 'mod/glossary:view', 'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE) ),