1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 | import util from '../util.js';
|
19 | import autoStyle from '../autostyle.js';
|
20 |
|
21 | export default class ModifierUtil {
|
22 | |
23 |
|
24 |
|
25 |
|
26 | static diff(last, current) {
|
27 | last = makeDict(('' + last).trim());
|
28 | current = makeDict(('' + current).trim());
|
29 |
|
30 | const removed = Object.keys(last).reduce((result, token) => {
|
31 | if (!current[token]) {
|
32 | result.push(token);
|
33 | }
|
34 | return result;
|
35 | }, []);
|
36 |
|
37 | const added = Object.keys(current).reduce((result, token) => {
|
38 | if (!last[token]) {
|
39 | result.push(token);
|
40 | }
|
41 | return result;
|
42 | }, []);
|
43 |
|
44 | return {added, removed};
|
45 |
|
46 | function makeDict(modifier) {
|
47 | const dict = {};
|
48 | ModifierUtil.split(modifier).forEach(token => dict[token] = token);
|
49 | return dict;
|
50 | }
|
51 | }
|
52 |
|
53 | |
54 |
|
55 |
|
56 |
|
57 |
|
58 |
|
59 |
|
60 | static applyDiffToClassList(diff, classList, template) {
|
61 | diff.added
|
62 | .map(modifier => template.replace(/\*/g, modifier))
|
63 | .forEach(klass => klass.split(/\s+/).forEach(k => classList.add(k)));
|
64 |
|
65 | diff.removed
|
66 | .map(modifier => template.replace(/\*/g, modifier))
|
67 | .forEach(klass => klass.split(/\s+/).forEach(k => classList.remove(k)));
|
68 | }
|
69 |
|
70 | |
71 |
|
72 |
|
73 |
|
74 |
|
75 |
|
76 |
|
77 | static applyDiffToElement(diff, element, scheme) {
|
78 | Object.keys(scheme).forEach(selector => {
|
79 | const targetElements = !selector || util.match(element, selector)
|
80 | ? [element]
|
81 | : Array.prototype.filter.call(
|
82 | element.querySelectorAll(selector),
|
83 | targetElement => !util.findParent(targetElement, element.tagName, parent => parent === element)
|
84 | );
|
85 |
|
86 | for (let i = 0; i < targetElements.length; i++) {
|
87 | ModifierUtil.applyDiffToClassList(diff, targetElements[i].classList, scheme[selector]);
|
88 | }
|
89 | });
|
90 | }
|
91 |
|
92 | |
93 |
|
94 |
|
95 |
|
96 |
|
97 |
|
98 | static onModifierChanged(last, current, element, scheme) {
|
99 | ModifierUtil.applyDiffToElement(ModifierUtil.diff(last, current), element, scheme);
|
100 | autoStyle.restoreModifier(element);
|
101 | }
|
102 |
|
103 | static refresh(element, scheme) {
|
104 | ModifierUtil.applyDiffToElement(ModifierUtil.diff('', element.getAttribute('modifier') || ''), element, scheme);
|
105 | }
|
106 |
|
107 | |
108 |
|
109 |
|
110 |
|
111 | static initModifier(element, scheme) {
|
112 | const modifier = element.getAttribute('modifier');
|
113 | if (typeof modifier !== 'string') {
|
114 | return;
|
115 | }
|
116 |
|
117 | ModifierUtil.applyDiffToElement({
|
118 | removed: [],
|
119 | added: ModifierUtil.split(modifier)
|
120 | }, element, scheme);
|
121 | }
|
122 |
|
123 | static split(modifier) {
|
124 | if (typeof modifier !== 'string') {
|
125 | return [];
|
126 | }
|
127 |
|
128 | return modifier.trim().split(/ +/).filter(token => token !== '');
|
129 | }
|
130 |
|
131 | |
132 |
|
133 |
|
134 | static addModifier(element, modifierToken) {
|
135 | if (!element.hasAttribute('modifier')) {
|
136 | element.setAttribute('modifier', modifierToken);
|
137 | } else {
|
138 | const tokens = ModifierUtil.split(element.getAttribute('modifier'));
|
139 | if (tokens.indexOf(modifierToken) == -1) {
|
140 | tokens.push(modifierToken);
|
141 | element.setAttribute('modifier', tokens.join(' '));
|
142 | }
|
143 | }
|
144 | }
|
145 |
|
146 | |
147 |
|
148 |
|
149 | static removeModifier(element, modifierToken) {
|
150 | if (element.hasAttribute('modifier')) {
|
151 | const tokens = ModifierUtil.split(element.getAttribute('modifier'));
|
152 | const index = tokens.indexOf(modifierToken);
|
153 | if (index !== -1) {
|
154 | tokens.splice(index, 1);
|
155 | element.setAttribute('modifier', tokens.join(' '));
|
156 | }
|
157 | }
|
158 | }
|
159 | }
|