fomantic / Fomantic-UI

Fomantic-UI is the official community fork of Semantic-UI
https://fomantic-ui.com
MIT License
3.56k stars 331 forks source link

[factory] Allow to build settings using a custom function #2526

Open mvorisek opened 2 years ago

mvorisek commented 2 years ago

Feature Request

Currently it is not easily possible to patch/override module params/settings.

In atk4/ui we currently override some global defaults like:

const fomanticServicesMap = {
    api: apiService,
    form: formService,
    modal: modalService,
    popup: popupService,
    accordion: accordionService,
};

$.extend = $.fn.extend = new Proxy($.fn.extend, { // eslint-disable-line no-multi-assign
    apply: function (target, thisArg, args) {
        // https://github.com/fomantic/Fomantic-UI/blob/c30ed51ca12fc1762b04c2fd1a83d087c0124d07/src/definitions/behaviors/api.js#L48
        const firstIndex = args[0] === true ? 1 : 0;
        const secondIndex = args[0] === true ? 2 : 1;
        if (args.length === (args[0] === true ? 4 : 2)
            && $.isPlainObject(args[firstIndex]) && $.isEmptyObject(args[firstIndex])
            && $.isPlainObject(args[secondIndex])
        ) {
            let name = null;
            Object.keys(fomanticServicesMap).forEach((n) => {
                if (args[secondIndex] === $.fn[n].settings) {
                    name = n;
                }
            });
            if (name !== null) {
                return fomanticServicesMap[name].buildFomanticSettings(args[firstIndex + 1]);
            }
        }

        return target.call(thisArg, ...args);
    },
});

at the app start relying on https://github.com/fomantic/Fomantic-UI/blob/c30ed51ca12fc1762b04c2fd1a83d087c0124d07/src/definitions/behaviors/api.js#L48 specific $.extend({}, $.fn.xxx.settings) usage.

This is a feature request to add function like to each $.fn.xxx:

`$.fn.xxx.createSettings = function (settings, parameters) { return $.extend(true, {}, $.fn.api.settings, parameters); }`

which can be replaced globally much more easier than patching jQuery extend function.


It would be great if module functions/methods would be possible to patch globally as well.

The module like in https://github.com/fomantic/Fomantic-UI/blob/c30ed51ca12fc1762b04c2fd1a83d087c0124d07/src/definitions/behaviors/api.js#L86 is burried/created inside.

$.fn.xxx.createModule = function (module) { return module; }

would allow customization/patching released versions like:

$.fn.modal.createModule = function (element, module) {
    module.save.focus = (function () { /* replace completely or tweak slightly and call module.save.focus() here */ }).bind(element);
    return module;
}

I am not sure if this is reasonably feasible as all functions need to be called with correct/element's scope (in code above I used element param for it and bind), maybe the module itself can carry these the scope like module.element...

lubber-de commented 2 years ago

There exists a behavior 'setting' for all modules to adjust a setting after initialization. Does this help?

$('.ui.modal').modal('setting','debug', true);

mvorisek commented 2 years ago

"after initialization" is too late

we need some global settings overrides like https://github.com/atk4/ui/blob/c535b9b45804394905e27506dae7c3df31f9f6d3/js/src/setup-fomantic-ui.js#L24 + https://github.com/atk4/ui/blob/c535b9b45804394905e27506dae7c3df31f9f6d3/js/src/services/api.service.js#L13

and soon in atk4/ui we will even enforce some settings via https://github.com/atk4/ui/commit/a2bbc2f7f8c672a97ddf96fb8e9a196bb9766046#diff-4ee6ef1d42ce1223b376e95fd6a65e834bc3632e1b27894f8b99866aca4ac26eR54

if $.fn.api.settings would be proxied directly (before $.extend call made by Fomantic-UI for specific module), it will have no effect, as the base object is no longer the proxied object, but instead a new object {} passed to extend by Fomantic-UI

lubber-de commented 2 years ago

There also exists a behavior 'internal' to override internal methods

$('.ui.modal').modal('internal','show', function(){console.log('I killed the modal show function!')});

but this will also be applied to the already instantiated module :(

lubber-de commented 2 years ago

What about

$.fn.api.settings.onRequest = function() {/*whatever*/};
$.fn.api.settings.encodeParameters = false;
mvorisek commented 1 year ago

one example is https://github.com/fomantic/Fomantic-UI/blob/2.9.0/src/definitions/modules/modal.js#L692 which is called in https://github.com/fomantic/Fomantic-UI/blob/2.9.0/src/definitions/modules/modal.js#L449

we use allowMultiple = true, but when user click the dimmer, we need to close only the topmost modal, ie. to replace the hideAll with function (module) { return module.hide(); }, what is currently the easiest way to do it?