1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
/**
* 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) {
if (typeof fn === 'object') {
fn = fn[component].bind(fn);
}
if (_.isFunction(fn)) {
fn(config, el);
} else if ($(el)[component]) {
$(el)[component](config);
}
}, 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
};
});