|
- /**
- * 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
- };
- });
|