UNPKG

@oat-sa/tao-core-sdk

Version:
175 lines (163 loc) 6.83 kB
define(['jquery', 'lodash'], function ($, _) { 'use strict'; $ = $ && Object.prototype.hasOwnProperty.call($, 'default') ? $['default'] : $; _ = _ && Object.prototype.hasOwnProperty.call(_, 'default') ? _['default'] : _; /** * This program 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; under version 2 * of the License (non-upgradable). * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * Copyright (c) 2013-2019 (original work) Open Assessment Technologies SA ; */ /** * Abstract plugin used to provide common behavior to the plugins */ const basePlugin = { /** * Set options of the plugin * * @example $('selector').pluginName('options', { key: value }); * @param {String} dataNs - the data namespace * @param {String} ns - the event namespace * @param {Object} options - the options to set * @returns {jQuery} */ options(dataNs, ns, options) { return this.each(function () { const $elt = $(this); const currentOptions = $elt.data(dataNs); if (currentOptions) { $elt.data(dataNs, _.merge(currentOptions, options)); } }); }, /** * Disable the component. * * It can be called prior to the plugin initilization. * * Called the jQuery way once registered by the Pluginifier. * @example $('selector').pluginName('disable'); * @param {String} dataNs - the data namespace * @param {String} ns - the event namespace * @returns {jQuery} * @fires basePlugin#disable.ns */ disable(dataNs, ns) { return this.each(function () { const $elt = $(this); const options = $elt.data(dataNs); if (options) { $elt.addClass(options.disableClass || 'disabled').trigger(`disable.${ns}`); } }); }, /** * Enable the component. * * Called the jQuery way once registered by the Pluginifier. * @example $('selector').pluginName('enable'); * @param {String} dataNs - the data namespace * @param {String} ns - the event namespace * @returns {jQuery} * @fires basePlugin#enable.ns */ enable(dataNs, ns) { return this.each(function () { const $elt = $(this); const options = $elt.data(dataNs); if (options) { $elt.removeClass(options.disableClass || 'disabled').trigger(`enable.${ns}`); } }); } }; /** * Helps you to create a jQuery plugin, the Cards way * @exports core/pluginifer */ const Pluginifier = { /** * Register a new jQuery plugin, the Cards way * @param {string} pluginName - the name of the plugin to register. ie $('selector').pluginName(); * @param {Object} plugin - the plugin as a plain object * @param {Function} plugin.init - the entry point of the plugin is always an init method * @param {Object} [config] - plugin configuration * @param {String} [config.ns = pluginName] - plugin namespace (used for events and data-attr) * @param {String} [config.dataNs = ui.pluginName] - plugin namespace (used for events and data-attr) * @param {Array<String>} [config.expose] - list of methods to expose * @returns {*} */ register(pluginName, plugin, config) { config = config || {}; const ns = config.ns || pluginName.toLowerCase(); const dataNs = config.dataNs || `ui.${ns}`; const expose = config.expose || []; //checks if (_.isFunction($.fn[pluginName])) { return $.error(`A plugin named ${pluginName} is already registered`); } if (!_.isPlainObject(plugin) || !_.isFunction(plugin.init)) { return $.error('The object to register as a jQuery plugin must be a plain object with an `init` method.'); } //configure and augments the plugin _.assign(plugin, _.transform(basePlugin, function (result, prop, key) { if (_.isFunction(prop)) { result[key] = _.partial(basePlugin[key], dataNs, ns); } })); //set up public methods to wrap privates the jquery way _.forEach(expose, function (toExposeName) { let privateMethod = toExposeName; let publicMethod = toExposeName; if (!/^_/.test(expose)) { privateMethod = `_${privateMethod}`; } else { publicMethod = publicMethod.replace(/^_/, ''); } //do not override if exists if (_.isFunction(plugin[privateMethod]) && !_.isFunction(plugin[publicMethod])) { plugin[publicMethod] = function () { for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } let returnValue; this.each(function () { //call plugin._method($element, [remainingArgs...]); returnValue = plugin[privateMethod]($(this), ...args); }); return returnValue || this; }; } }); // map $('selector').pluginName() to plugin.init // map $('selector').pluginName('method', params) to plugin.method(params) to plugin._method($elt, params); // disable direct call to private (starting with _) methods $.fn[pluginName] = function (method) { for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) { args[_key2 - 1] = arguments[_key2]; } if (plugin[method]) { if (/^_/.test(method)) { $.error(`Trying to call a private method \`${method}\``); } else { return plugin[method].apply(this, args); } } else if (typeof method === 'object' || !method) { return plugin.init.call(this, method, ...args); } $.error(`Method ${method} does not exist on plugin`); }; } }; return Pluginifier; });