115 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
		
			Executable File
		
	
	
			
		
		
	
	
			115 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
		
			Executable File
		
	
	
/**
 | 
						|
 * Copyright © Magento, Inc. All rights reserved.
 | 
						|
 * See COPYING.txt for license details.
 | 
						|
 */
 | 
						|
 | 
						|
define([
 | 
						|
    'underscore',
 | 
						|
    'jquery',
 | 
						|
    './scripts'
 | 
						|
], function (_, $, processScripts) {
 | 
						|
    'use strict';
 | 
						|
 | 
						|
    var dataAttr = 'data-mage-init',
 | 
						|
        nodeSelector = '[' + dataAttr + ']';
 | 
						|
 | 
						|
    /**
 | 
						|
     * Initializes components assigned to a specified element via data-* attribute.
 | 
						|
     *
 | 
						|
     * @param {HTMLElement} el - Element to initialize components with.
 | 
						|
     * @param {Object|String} config - Initial components' config.
 | 
						|
     * @param {String} component - Components' path.
 | 
						|
     */
 | 
						|
    function init(el, config, component) {
 | 
						|
        require([component], function (fn) {
 | 
						|
            var $el;
 | 
						|
 | 
						|
            if (typeof fn === 'object') {
 | 
						|
                fn = fn[component].bind(fn);
 | 
						|
            }
 | 
						|
 | 
						|
            if (_.isFunction(fn)) {
 | 
						|
                fn = fn.bind(null, config, el);
 | 
						|
            } else {
 | 
						|
                $el = $(el);
 | 
						|
 | 
						|
                if ($el[component]) {
 | 
						|
                    // eslint-disable-next-line jquery-no-bind-unbind
 | 
						|
                    fn = $el[component].bind($el, config);
 | 
						|
                }
 | 
						|
            }
 | 
						|
            // Init module in separate task to prevent blocking main thread.
 | 
						|
            setTimeout(fn);
 | 
						|
        }, function (error) {
 | 
						|
            if ('console' in window && typeof window.console.error === 'function') {
 | 
						|
                console.error(error);
 | 
						|
            }
 | 
						|
 | 
						|
            return true;
 | 
						|
        });
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Parses elements 'data-mage-init' attribute as a valid JSON data.
 | 
						|
     * Note: data-mage-init attribute will be removed.
 | 
						|
     *
 | 
						|
     * @param {HTMLElement} el - Element whose attribute should be parsed.
 | 
						|
     * @returns {Object}
 | 
						|
     */
 | 
						|
    function getData(el) {
 | 
						|
        var data = el.getAttribute(dataAttr);
 | 
						|
 | 
						|
        el.removeAttribute(dataAttr);
 | 
						|
 | 
						|
        return {
 | 
						|
            el: el,
 | 
						|
            data: JSON.parse(data)
 | 
						|
        };
 | 
						|
    }
 | 
						|
 | 
						|
    return {
 | 
						|
        /**
 | 
						|
         * Initializes components assigned to HTML elements via [data-mage-init].
 | 
						|
         *
 | 
						|
         * @example Sample 'data-mage-init' declaration.
 | 
						|
         *      data-mage-init='{"path/to/component": {"foo": "bar"}}'
 | 
						|
         */
 | 
						|
        apply: function (context) {
 | 
						|
            var virtuals = processScripts(!context ? document : context),
 | 
						|
                nodes = document.querySelectorAll(nodeSelector);
 | 
						|
 | 
						|
            _.toArray(nodes)
 | 
						|
                .map(getData)
 | 
						|
                .concat(virtuals)
 | 
						|
                .forEach(function (itemContainer) {
 | 
						|
                    var element = itemContainer.el;
 | 
						|
 | 
						|
                    _.each(itemContainer.data, function (obj, key) {
 | 
						|
                            if (obj.mixins) {
 | 
						|
                                require(obj.mixins, function () { //eslint-disable-line max-nested-callbacks
 | 
						|
                                    var i, len;
 | 
						|
 | 
						|
                                    for (i = 0, len = arguments.length; i < len; i++) {
 | 
						|
                                        $.extend(
 | 
						|
                                            true,
 | 
						|
                                            itemContainer.data[key],
 | 
						|
                                            arguments[i](itemContainer.data[key], element)
 | 
						|
                                        );
 | 
						|
                                    }
 | 
						|
 | 
						|
                                    delete obj.mixins;
 | 
						|
                                    init.call(null, element, obj, key);
 | 
						|
                                });
 | 
						|
                            } else {
 | 
						|
                                init.call(null, element, obj, key);
 | 
						|
                            }
 | 
						|
 | 
						|
                        }
 | 
						|
                    );
 | 
						|
 | 
						|
                });
 | 
						|
        },
 | 
						|
        applyFor: init
 | 
						|
    };
 | 
						|
});
 |