1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 | 'use strict';
|
7 |
|
8 | function elementEvent(domElement, eventName, moduleName, detail) {
|
9 | if (detail === void 0) { detail = {}; }
|
10 | var fullEventName = eventName + ".ph." + moduleName;
|
11 | domElement.dispatchEvent(new CustomEvent(fullEventName, { detail: detail }));
|
12 | }
|
13 | function pageEvent(eventName, pageName, detail) {
|
14 | if (detail === void 0) { detail = {}; }
|
15 | var fullEventName = pageName + "." + eventName;
|
16 | window.dispatchEvent(new CustomEvent(fullEventName, { detail: detail }));
|
17 | document.dispatchEvent(new CustomEvent(fullEventName, { detail: detail }));
|
18 | }
|
19 | function winDocEvent(eventName, moduleName, detail) {
|
20 | if (detail === void 0) { detail = {}; }
|
21 | var fullEventName = eventName + ".ph." + moduleName;
|
22 | window.dispatchEvent(new CustomEvent(fullEventName, { detail: detail }));
|
23 | document.dispatchEvent(new CustomEvent(fullEventName, { detail: detail }));
|
24 | }
|
25 | var dispatch = {
|
26 | elementEvent: elementEvent,
|
27 | pageEvent: pageEvent,
|
28 | winDocEvent: winDocEvent,
|
29 | };
|
30 |
|
31 | function onError() {
|
32 | if (typeof window === 'undefined') {
|
33 | return;
|
34 | }
|
35 | window.addEventListener('error', function (event) {
|
36 | console.error('-- Phonon Error --');
|
37 | console.error('An error has occured!'
|
38 | + ' ' + 'You can pen an issue here: https://github.com/quark-dev/Phonon-Framework/issues');
|
39 | console.error(JSON.stringify(event));
|
40 | });
|
41 | }
|
42 |
|
43 | var availableEvents = ['mousedown', 'mousemove', 'mouseup'];
|
44 | var touchScreen = false;
|
45 | if (typeof window !== 'undefined') {
|
46 | if (('ontouchstart' in window) || window.DocumentTouch
|
47 | && document instanceof window.DocumentTouch) {
|
48 | touchScreen = true;
|
49 | availableEvents = ['touchstart', 'touchmove', 'touchend', 'touchcancel'];
|
50 | }
|
51 | if (window.navigator.pointerEnabled) {
|
52 | availableEvents = ['pointerdown', 'pointermove', 'pointerup', 'pointercancel'];
|
53 | }
|
54 | else if (window.navigator.msPointerEnabled) {
|
55 | availableEvents = ['MSPointerDown', 'MSPointerMove', 'MSPointerUp', 'MSPointerCancel'];
|
56 | }
|
57 | }
|
58 | var transitions = [
|
59 | { name: 'transition', start: 'transitionstart', end: 'transitionend' },
|
60 | { name: 'MozTransition', start: 'transitionstart', end: 'transitionend' },
|
61 | { name: 'msTransition', start: 'msTransitionStart', end: 'msTransitionEnd' },
|
62 | { name: 'WebkitTransition', start: 'webkitTransitionStart', end: 'webkitTransitionEnd' },
|
63 | ];
|
64 | var animations = [
|
65 | { name: 'animation', start: 'animationstart', end: 'animationend' },
|
66 | { name: 'MozAnimation', start: 'animationstart', end: 'animationend' },
|
67 | { name: 'msAnimation', start: 'msAnimationStart', end: 'msAnimationEnd' },
|
68 | { name: 'WebkitAnimation', start: 'webkitAnimationStart', end: 'webkitAnimationEnd' },
|
69 | ];
|
70 | var el = window.document.createElement('div');
|
71 | var transition = transitions.find(function (t) { return typeof el.style[t.name] !== 'undefined'; });
|
72 | var animation = animations.find(function (t) { return typeof el.style[t.name] !== 'undefined'; });
|
73 | var transitionStart = transition ? transition.start : 'transitionstart';
|
74 | var transitionEnd = transition ? transition.end : 'transitionend';
|
75 | var animationStart = animation ? animation.start : 'animationstart';
|
76 | var animationEnd = animation ? animation.end : 'animationend';
|
77 | var events = {
|
78 | TOUCH_SCREEN: touchScreen,
|
79 | NETWORK_ONLINE: 'online',
|
80 | NETWORK_OFFLINE: 'offline',
|
81 | NETWORK_RECONNECTING: 'reconnecting',
|
82 | NETWORK_RECONNECTING_SUCCESS: 'reconnect.success',
|
83 | NETWORK_RECONNECTING_FAILURE: 'reconnect.failure',
|
84 | SHOW: 'show',
|
85 | SHOWN: 'shown',
|
86 | HIDE: 'hide',
|
87 | HIDDEN: 'hidden',
|
88 | HASH: 'hash',
|
89 | START: availableEvents[0],
|
90 | MOVE: availableEvents[1],
|
91 | END: availableEvents[2],
|
92 | CANCEL: typeof availableEvents[3] === 'undefined' ? null : availableEvents[3],
|
93 | CLICK: 'click',
|
94 | TRANSITION_START: transitionStart,
|
95 | TRANSITION_END: transitionEnd,
|
96 | ANIMATION_START: animationStart,
|
97 | ANIMATION_END: animationEnd,
|
98 | ITEM_SELECTED: 'itemSelected',
|
99 | };
|
100 |
|
101 | function closest(element, selector) {
|
102 | if (!Element.prototype.matches) ;
|
103 | var el = element;
|
104 | do {
|
105 | if (el.matches(selector)) {
|
106 | return el;
|
107 | }
|
108 | el = (el.parentElement || el.parentNode);
|
109 | } while (el !== null && el.nodeType === 1);
|
110 | return null;
|
111 | }
|
112 | function attrConfig(element) {
|
113 | if (!element) {
|
114 | return null;
|
115 | }
|
116 | var attr = element.getAttribute('data-config');
|
117 | if (!attr) {
|
118 | return null;
|
119 | }
|
120 | try {
|
121 | var config = JSON.parse(attr);
|
122 | return config;
|
123 | }
|
124 | catch (e) {
|
125 | }
|
126 | var keys = (attr.match(/(\w+)\s*:\s*(["'])?/igm) || [])
|
127 | .map(function (e) { return e.replace(/(\w+)\s*:\s*(["'])?/igm, '$1'); });
|
128 | var values = attr.match(/[^:]+(?=,|$)/igm) || [];
|
129 | var json = {};
|
130 | keys.forEach(function (key, i) {
|
131 | var value = values[i].replace(/ /g, '').replace(/\'|"/g, '');
|
132 | var convertedValue = '';
|
133 | if (value === 'true' || value === 'false') {
|
134 | convertedValue = value === 'true';
|
135 | }
|
136 | else if (!isNaN(value)) {
|
137 | convertedValue = parseFloat(value);
|
138 | }
|
139 | else {
|
140 | convertedValue = value;
|
141 | }
|
142 | json[key] = convertedValue;
|
143 | });
|
144 | return json;
|
145 | }
|
146 | function removeClasses(element, classList, prefix) {
|
147 | if (prefix === void 0) { prefix = null; }
|
148 | classList.forEach(function (className) {
|
149 | var cName = prefix ? prefix + "-" + className : className;
|
150 | if (element.classList.contains(cName)) {
|
151 | element.classList.remove(cName);
|
152 | }
|
153 | });
|
154 | }
|
155 | function isElement(node) {
|
156 | return node.nodeType === 1
|
157 | && typeof node.className === 'string';
|
158 | }
|
159 | var selector = {
|
160 | attrConfig: attrConfig,
|
161 | removeClasses: removeClasses,
|
162 | closest: closest,
|
163 | isElement: isElement,
|
164 | };
|
165 |
|
166 | var components = {};
|
167 | function getName(component) {
|
168 | if (typeof component === 'string') {
|
169 | return component.toLowerCase();
|
170 | }
|
171 | return component.constructor.name.toLowerCase();
|
172 | }
|
173 | function addComponent(component) {
|
174 | var name = getName(component);
|
175 | if (!components[name]) {
|
176 | components[name] = [];
|
177 | }
|
178 | components[name].push(component);
|
179 | }
|
180 | function removeComponent(componentName, element) {
|
181 | var name = getName(componentName);
|
182 | var index = (components[name] || []).findIndex(function (c) { return c.getElement() === element; });
|
183 | if (index === -1) {
|
184 | return;
|
185 | }
|
186 | var component = components[name][index];
|
187 | component.destroy();
|
188 | components[name].splice(index, 1);
|
189 | }
|
190 | function getComponent(component, options) {
|
191 | var className = getName(component);
|
192 | var element = options.element;
|
193 | if (!element) {
|
194 | return null;
|
195 | }
|
196 | var selector = typeof element === 'string' ? document.querySelector(element) : element;
|
197 | var existingComponent = (components[className] || [])
|
198 | .find(function (c) { return c.getElement() === selector; });
|
199 | if (!existingComponent) {
|
200 | return null;
|
201 | }
|
202 | if (options) {
|
203 | existingComponent.setProps(options);
|
204 | }
|
205 | return existingComponent;
|
206 | }
|
207 | var stack = {
|
208 | addComponent: addComponent,
|
209 | getComponent: getComponent,
|
210 | removeComponent: removeComponent,
|
211 | };
|
212 |
|
213 | var mutatorSubscribers = [];
|
214 | function subscribe(subscriber) {
|
215 | mutatorSubscribers.push(subscriber);
|
216 | if (document.body) {
|
217 | Array.from(document.body.querySelectorAll("." + subscriber.componentClass) || [])
|
218 | .filter(function (component) { return component.getAttribute('data-no-boot') === null; })
|
219 | .forEach(function (component) {
|
220 | dispatchChangeEvent(subscriber, 'onAdded', component, stack.addComponent);
|
221 | });
|
222 | }
|
223 | }
|
224 | function dispatchChangeEvent(subscriber, eventName) {
|
225 | var args = [];
|
226 | for (var _i = 2; _i < arguments.length; _i++) {
|
227 | args[_i - 2] = arguments[_i];
|
228 | }
|
229 | var callback = subscriber[eventName];
|
230 | if (!callback) {
|
231 | return;
|
232 | }
|
233 | callback.apply(callback, args);
|
234 | }
|
235 | function nodeFn(element, added) {
|
236 | if (added === void 0) { added = true; }
|
237 | if (element.getAttribute('data-no-boot') !== null) {
|
238 | return;
|
239 | }
|
240 | var elementClasses = element.className.split(' ');
|
241 | var subscriber = mutatorSubscribers.find(function (l) { return elementClasses.indexOf(l.componentClass) > -1; });
|
242 | if (!subscriber) {
|
243 | return;
|
244 | }
|
245 | var eventName = added ? 'onAdded' : 'onRemoved';
|
246 | var args = added ? [element, stack.addComponent] : [element, stack.removeComponent];
|
247 | dispatchChangeEvent.apply(void 0, [subscriber, eventName].concat(args));
|
248 | }
|
249 | function apply(node, added) {
|
250 | if (added === void 0) { added = true; }
|
251 | nodeFn(node, added);
|
252 | var nextNode = node.firstElementChild;
|
253 | while (nextNode) {
|
254 | var next = nextNode.nextElementSibling;
|
255 | if (isElement(nextNode)) {
|
256 | apply(nextNode, added);
|
257 | }
|
258 | nextNode = next;
|
259 | }
|
260 | }
|
261 | function getElements(nodes) {
|
262 | return Array
|
263 | .from(nodes)
|
264 | .filter(function (node) { return isElement(node); });
|
265 | }
|
266 | function observe() {
|
267 | (new MutationObserver(function (mutations) { return mutations.forEach(function (mutation) {
|
268 | if (mutation.type === 'attributes') {
|
269 | return;
|
270 | }
|
271 | var addedNodes = mutation.addedNodes, removedNodes = mutation.removedNodes;
|
272 | getElements(addedNodes).forEach(function (node) { return apply(node, true); });
|
273 | getElements(removedNodes).forEach(function (node) { return apply(node, false); });
|
274 | }); })).observe(document, {
|
275 | childList: true,
|
276 | subtree: true,
|
277 | characterData: true,
|
278 | attributes: true,
|
279 | });
|
280 | }
|
281 | function boot() {
|
282 | if (!('MutationObserver' in window)) {
|
283 | return;
|
284 | }
|
285 | if (document.body) {
|
286 | observe();
|
287 | }
|
288 | else {
|
289 | var obs_1 = new MutationObserver(function () {
|
290 | if (document.body) {
|
291 | obs_1.disconnect();
|
292 | observe();
|
293 | }
|
294 | });
|
295 | obs_1.observe(document, { childList: true, subtree: true });
|
296 | }
|
297 | }
|
298 | boot();
|
299 | var observer = {
|
300 | subscribe: subscribe,
|
301 | getComponent: stack.getComponent,
|
302 | };
|
303 |
|
304 | var sleep = (function (timeout) {
|
305 | return new Promise(function (resolve) {
|
306 | setTimeout(resolve, timeout);
|
307 | });
|
308 | });
|
309 |
|
310 | onError();
|
311 | var utils = {
|
312 | sleep: sleep,
|
313 | Event: events,
|
314 | Dispatch: dispatch,
|
315 | Selector: selector,
|
316 | Observer: observer,
|
317 | };
|
318 |
|
319 |
|
320 |
|
321 |
|
322 |
|
323 |
|
324 |
|
325 |
|
326 |
|
327 |
|
328 |
|
329 | module.exports = utils;
|
330 |
|