mirror of
https://github.com/moodle/moodle.git
synced 2025-04-20 07:56:06 +02:00
MDL-78294 filter_glossary: Replace YUI with an AMD module
Replaces the existing YUI module in the glossary filter with an AMD module. The auto-linked glossary entries are now obtained through the existing webservices in mod_glossary and displayed within a modal utilizing the core/modal js module.
This commit is contained in:
parent
5f10f82301
commit
df1cc4ac93
10
filter/glossary/amd/build/autolinker.min.js
vendored
Normal file
10
filter/glossary/amd/build/autolinker.min.js
vendored
Normal file
@ -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 <mihail@moodle.com>
|
||||
* @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<tags.length;i++)tags[i].overlimit=!0;return{tags:tags,tagscount:tags.length,overflow:hasOverflow,label:await(0,_str.getString)("tags")}};_exports.init=()=>{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
|
1
filter/glossary/amd/build/autolinker.min.js.map
Normal file
1
filter/glossary/amd/build/autolinker.min.js.map
Normal file
File diff suppressed because one or more lines are too long
150
filter/glossary/amd/src/autolinker.js
Normal file
150
filter/glossary/amd/src/autolinker.js
Normal file
@ -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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Module for auto-linking glossary entries.
|
||||
*
|
||||
* @module filter_glossary/autolinker
|
||||
* @copyright 2023 Mihail Geshoski <mihail@moodle.com>
|
||||
* @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();
|
||||
};
|
@ -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()
|
||||
|
@ -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';
|
||||
|
74
filter/glossary/templates/linked_glossary_entry.mustache
Normal file
74
filter/glossary/templates/linked_glossary_entry.mustache
Normal file
@ -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 <http://www.gnu.org/licenses/>.
|
||||
}}
|
||||
{{!
|
||||
@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"
|
||||
}
|
||||
]
|
||||
}
|
||||
}}
|
||||
|
||||
<p>{{{definition}}}</p>
|
||||
{{#taglistdata}}
|
||||
<div class="mb-2">
|
||||
{{> core_tag/taglist }}
|
||||
</div>
|
||||
{{/taglistdata}}
|
||||
{{#hasattachments}}
|
||||
<b>{{#str}} attachments, filter_glossary {{/str}}:</b>
|
||||
<ul>
|
||||
{{#attachments}}
|
||||
<li>
|
||||
{{#pix}} {{icon}}, core {{/pix}}
|
||||
<a href="{{{fileurl}}}">
|
||||
{{filename}}
|
||||
</a>
|
||||
</li>
|
||||
{{/attachments}}
|
||||
</ul>
|
||||
{{/hasattachments}}
|
@ -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('<div id="glossaryfilteroverlayprogress">' +
|
||||
'</div>'),
|
||||
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"
|
||||
]
|
||||
});
|
@ -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('<div id="glossaryfilteroverlayprogress"></div>'),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"]});
|
@ -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('<div id="glossaryfilteroverlayprogress">' +
|
||||
'</div>'),
|
||||
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"
|
||||
]
|
||||
});
|
@ -1,10 +0,0 @@
|
||||
{
|
||||
"name": "moodle-filter_glossary-autolinker",
|
||||
"builds": {
|
||||
"moodle-filter_glossary-autolinker": {
|
||||
"jsfiles": [
|
||||
"autolinker.js"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
175
filter/glossary/yui/src/autolinker/js/autolinker.js
vendored
175
filter/glossary/yui/src/autolinker/js/autolinker.js
vendored
@ -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('<div id="glossaryfilteroverlayprogress">' +
|
||||
'</div>'),
|
||||
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);
|
||||
};
|
@ -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"
|
||||
]
|
||||
}
|
||||
}
|
@ -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)
|
||||
),
|
||||
|
Loading…
x
Reference in New Issue
Block a user