PageSourceSearch

https://khakassia.travel/assets/plugins/commerce/js/commerce.js?0.12.1

js khakassia.travel collected 2026-10-03 21:04:23 UTC 22,359 bytes, 684 lines download raw bytes

1;
2
3var Commerce = (function() {
4    var CommerceEvent = function(target, name, data) {
5        this.event = new CustomEvent(name, {
6            cancelable: true,
7            bubbles: true,
8            detail: data
9        });
10
11        target.dispatchEvent(this.event);
12
13        if (window.jQuery) {
14            this.$event = $.Event(name);
15            jQuery(target).trigger(this.$event, data);
16        }
17
18        this.isPrevented = function() {
19            if (this.event.defaultPrevented || this.event.returnValue === false) {
20                return true;
21            }
22
23            if (window.jQuery) {
24                if (this.$event.isDefaultPrevented() || typeof this.$event.result != 'undefined' && this.$event.result === false) {
25                    return true;
26                }
27            }
28
29            return false;
30        };
31
32        return this;
33    };
34
35    function triggerEvent(target, name, data) {
36        return new CommerceEvent(target, name, data);
37    }
38
39    /**
40     * Convert object to FormData, based on object-to-formdata by Parmesh Krishen
41     * @link https://github.com/therealparmesh/object-to-formdata
42     * @license MIT
43     */
44    function objectToFormData(object) {
45        function isArray(value) {
46            return Array.isArray(value);
47        }
48
49        function isBlob(value) {
50            return value &&
51                typeof value.size === 'number' &&
52                typeof value.type === 'string' &&
53                typeof value.slice === 'function';
54        }
55
56        function isFile(value) {
57            return isBlob(value) &&
58                typeof value.name === 'string' &&
59                (typeof value.lastModifiedDate === 'object' ||
60                typeof value.lastModified === 'number');
61        }
62
63        function serialize(value, fd, prefix) {
64            fd = fd || new FormData();
65
66            if (value === undefined) {
67                return fd;
68            } else if (value === null) {
69                fd.append(prefix, '');
70            } else if (typeof value === 'boolean') {
71                fd.append(prefix, value);
72            } else if (isArray(value)) {
73                if (value.length) {
74                    value.forEach(function(val, index) {
75                        serialize(val, fd, prefix + '[' + index + ']');
76                    });
77                } else {
78                    fd.append(prefix + '[]', '');
79                }
80            } else if (value instanceof Date) {
81                fd.append(prefix, value.toISOString());
82            } else if (value === Object(value) && !isFile(value) && !isBlob(value)) {
83                Object.keys(value).forEach(function(prop) {
84                    var val = value[prop];
85
86                    if (isArray(val)) {
87                        while (prop.length > 2 && prop.lastIndexOf('[]') === prop.length - 2) {
88                            prop = prop.substring(0, prop.length - 2);
89                        }
90                    }
91
92                    var key = prefix ? prefix + '[' + prop + ']' : prop;
93
94                    serialize(val, fd, key);
95                });
96            } else {
97                fd.append(prefix, value);
98            }
99
100            return fd;
101        }
102
103        return serialize(object);
104    }
105
106    /**
107     * Form serialization, based on jQuery serializeObject
108     * @copyright 2014, macek <[email protected]>
109     * @link https://github.com/macek/jquery-serialize-object
110     * @license BSD
111     */
112    function serializeForm(form) {
113        var self = this,
114            json = {},
115            push_counters = {},
116            patterns = {
117                "validate": /^[a-zA-Z][a-zA-Z0-9_]*(?:\[ *(?:\d*|[a-zA-Z0-9_]+) *\])*$/,
118                "key":      /[a-zA-Z0-9_]+|(?=\[\])/g,
119                "push":     /^$/,
120                "fixed":    /^\d+$/,
121                "named":    /^[a-zA-Z0-9_]+$/
122            };
123
124        this.build = function(base, key, value) {
125            base[key] = value;
126            return base;
127        };
128
129        this.push_counter = function(key) {
130            if (push_counters[key] === undefined) {
131                push_counters[key] = 0;
132            }
133            return push_counters[key]++;
134        };
135
136        Array.from(new FormData(form)).forEach(function(row) {
137            // Skip invalid keys
138            if (!patterns.validate.test(row[0])) {
139                return;
140            }
141
142            var k,
143                keys = row[0].match(patterns.key),
144                merge = row[1],
145                reverse_key = row[0];
146
147            while ((k = keys.pop()) !== undefined) {
148                // Adjust reverse_key
149                reverse_key = reverse_key.replace(new RegExp("\\[" + k + "\\]$"), '');
150
151                // Push
152                if (k.match(patterns.push)) {
153                    merge = self.build([], self.push_counter(reverse_key), merge);
154                }
155
156                // Fixed
157                else if (k.match(patterns.fixed)) {
158                    merge = self.build([], k, merge);
159                }
160
161                // Named
162                else if (k.match(patterns.named)) {
163                    merge = self.build({}, k, merge);
164                }
165            }
166
167            json = extendObject({}, json, merge);
168        });
169
170        return json;
171    }
172
173    function serializeDataAttributes(element) {
174        var data = {};
175
176        [].forEach.call(element.attributes, function(attr) {
177            if (/^data-/.test(attr.name)) {
178                var camelCaseName = attr.name.substr(5).replace(/-(.)/g, function ($0, $1) {
179                    return $1.toUpperCase();
180                });
181
182                data[camelCaseName] = attr.value;
183            }
184        });
185
186        return data;
187    }
188
189    function extendObject(out) {
190        out = out || {};
191
192        for (var i = 1; i < arguments.length; i++) {
193            var obj = arguments[i], key;
194
195            if (!obj) {
196                continue;
197            }
198
199            if (obj instanceof Array == true) {
200                for (key = 0; key < obj.length; key++) {
201                    if (typeof obj[key] == 'undefined') {
202                        continue;
203                    }
204
205                    if (typeof obj[key] === 'object') {
206                        out[key] = extendObject(out[key], obj[key]);
207                    } else {
208                        out[key] = obj[key];
209                    }
210                }
211            } else {
212                for (key in obj) {
213                    if (!obj.hasOwnProperty(key)) {
214                        continue;
215                    }
216
217                    if (typeof obj[key] === 'object') {
218                        out[key] = extendObject(out[key], obj[key]);
219                    } else {
220                        out[key] = obj[key];
221                    }
222                }
223            }
224        }
225
226        return out;
227    }
228
229    function markupToElement(markup) {
230        var template = document.createElement('template');
231        template.innerHTML = markup.trim();
232        return template.content.firstChild;
233    }
234
235    function getCartsHashes() {
236        var carts = document.querySelectorAll('[data-commerce-cart]'),
237            form  = document.querySelector('[data-commerce-order]'),
238            hashes = {
239                carts: []
240            };
241
242        Array.prototype.forEach.call(carts, function(cart) {
243            hashes.carts.push(cart.getAttribute('data-commerce-cart'));
244        });
245
246        if (form) {
247            hashes.form = form.getAttribute('data-commerce-order');
248        }
249
250        var event = triggerEvent(document, 'collect-hashes.commerce', {
251            hashes: hashes
252        });
253
254        if (!event.isPrevented()) {
255            return hashes;
256        }
257
258        return hashes;
259    }
260
261    function reloadMarkupFromResponse(markup) {
262        if (typeof markup.carts == 'object') {
263            for (var hash in markup.carts) {
264                var carts = document.querySelectorAll('[data-commerce-cart="' + hash + '"]');
265
266                if (carts.length) {
267                    for (var i = 0; i < carts.length; i++) {
268                        var newCart = markupToElement(markup.carts[hash]),
269                            event = triggerEvent(carts[i], 'cart-reload.commerce', {newCart: newCart});
270
271                        if (event.isPrevented()) {
272                            return;
273                        }
274
275                        carts[i].replaceWith(newCart);
276                        triggerEvent(newCart, 'cart-reloaded.commerce');
277                    }
278                }
279            }
280        }
281
282        if (typeof markup.form == 'object') {
283            var node;
284
285            if (typeof markup.form.delivery != 'undefined') {
286                node = document.querySelector('[data-commerce-deliveries]');
287
288                if (node) {
289                    node.innerHTML = markup.form.delivery;
290                }
291            }
292
293            if (typeof markup.form.payments != 'undefined') {
294                node = document.querySelector('[data-commerce-payments]');
295
296                if (node) {
297                    node.innerHTML = markup.form.payments;
298                }
299            }
300
301            triggerEvent(document.querySelector('[data-commerce-order]'), 'form-reloaded.commerce');
302        }
303    }
304
305    function handleActionEvent(e) {
306        if (this.tagName == 'FORM' && e.type != 'submit') {
307            return;
308        }
309
310        var self   = this,
311            action = self.getAttribute('data-commerce-action'),
312            row    = self.getAttribute('data-commerce-row'),
313            data   = serializeDataAttributes(self),
314            cartContainer = self.closest('[data-commerce-cart]'),
315            parent;
316
317        if (!row) {
318            parent = self.closest('[data-commerce-row]');
319
320            if (parent) {
321                row = parent.getAttribute('data-commerce-row');
322            }
323        }
324
325        var cart   = {
326            instance: self.getAttribute('data-instance') || (cartContainer ? cartContainer.getAttribute('data-instance') : null) || 'products',
327            hash: cartContainer ? cartContainer.getAttribute('data-commerce-cart') : null
328        };
329
330        if (action == 'redirect-to-payment') {
331            e.preventDefault();
332            var link = self.getAttribute('data-redirect-link');
333
334            if (link && link != '') {
335                location.href = link;
336            } else {
337                document.querySelector('form#payment_request').submit();
338            }
339
340            return;
341        }
342
343        if (action == 'add') {
344            e.preventDefault();
345
346            if (e.type == 'submit') {
347                data = serializeForm(self);
348            }
349
350            data.cart = cart;
351
352            if (data.batch && typeof data.batch == 'object') {
353                for (var i in data.batch) {
354                    if (!data.batch[i].id) {
355                        delete data.batch[i];
356                    }
357                }
358
359                Commerce.action('cart/addmultiple', data, self);
360            } else {
361                Commerce.action('cart/add', data, self);
362            }
363
364            return;
365        }
366
367        if (e.type == 'click') {
368            e.preventDefault();
369
370            switch (action) {
371                case 'increase':
372                case 'decrease': {
373                    var rowField = cartContainer.querySelector('[data-commerce-row="' + row + '"]'),
374                        countField = rowField.matches('input[name="count"]') ? rowField : rowField.querySelector('input[name="count"]');
375
376                    if (countField) {
377                        var min   = parseFloat(countField.getAttribute('data-min')),
378                            max   = parseFloat(countField.getAttribute('data-max')),
379                            count = parseFloat(countField.value) || 0,
380                            diff  = data.count ? parseFloat(data.count) || 1 : 1;
381
382                        count += action == 'increase' ? diff : -diff;
383                        count = Math.max(0, count);
384
385                        if (!count && (min !== min || min === 0)) {
386                            Commerce.action('cart/remove', {row: row, cart: cart, data: data}, self);
387                        } else if ((min !== min || count >= min) && (max !== max || count <= max )) {
388                            count.value = count;
389                            Commerce.action('cart/update', {row: row, cart: cart, data: data, attributes: {count: count}}, self);
390                        }
391                    }
392
393                    return;
394                }
395
396                case 'remove': {
397                    Commerce.action('cart/remove', {row: row, cart: cart, data: data}, self);
398                    return;
399                }
400
401                case 'clean': {
402                    Commerce.action('cart/clean', {cart: cart, data: data}, self);
403                    return;
404                }
405            }
406        }
407
408        if (e.type == 'change') {
409            switch (action) {
410                case 'recount': {
411                    var count = parseFloat(self.value) || 0,
412                        min   = parseFloat(self.getAttribute('data-min')) || 0,
413                        max   = parseFloat(self.getAttribute('data-max')) || count;
414
415                    if (count >= 0) {
416                        if (!count && !min) {
417                            Commerce.action('cart/remove', {row: row, cart: cart, data: data}, self);
418                        } else if (count >= min && count <= max) {
419                            Commerce.action('cart/update', {row: row, cart: cart, data: data, attributes: {count: count}}, self);
420                        }
421                    }
422
423                    return;
424                }
425            }
426        }
427    }
428
429    function handleOrderChange(e) {
430        if (['delivery_method', 'payment_method'].indexOf(e.target.name) !== -1) {
431            Commerce.updateOrderData(this);
432        }
433    }
434
435    function delegateEvent(events, selector, handler) {
436        if (!(events instanceof Array)) {
437            events = [events];
438        }
439
440        events.forEach(function(event) {
441            document.addEventListener(event, function(e) {
442                for (var target = e.target; target && target != this; target = target.parentNode) {
443                    if (target.matches(selector)) {
444                        handler.call(target, e);
445                        break;
446                    }
447                }
448            }, false);
449        });
450    }
451
452    function request(url, data, callback) {
453        if (!data) {
454            data = {};
455        }
456
457        fetch(url, {
458            method: 'POST',
459            body: objectToFormData(data)
460        })
461        .then(function(response) {
462            return response.json();
463        })
464        .then(function(response) {
465            Commerce.serverResponse = response;
466            callback.call(Commerce, response);
467        });
468    }
469
470    if (window.jQuery) {
471        jQuery(document).on('submit click change', '[data-commerce-action]', function(e) {
472            handleActionEvent.call(this, e);
473        });
474
475        jQuery(document).on('change', '[data-commerce-order]', function(e) {
476            handleOrderChange.call(this, e);
477        });
478    } else {
479        delegateEvent(['submit', 'click', 'change'], '[data-commerce-action]', handleActionEvent);
480
481        delegateEvent('change', '[data-commerce-order]', handleOrderChange);
482    }
483
484    delegateEvent('cart-remove-complete.commerce', '.comparison-table, .wishlist-table', function(e) {
485        window.location.reload();
486    });
487
488    document.addEventListener('DOMContentLoaded', function() {
489        if (Commerce.params.isCartPage) {
490            Commerce.reloadCarts({order_completed: true});
491        }
492    });
493
494    return {
495        params: {},
496
497        action: function(action, data, initiator) {
498            if (window.jQuery && initiator instanceof jQuery) {
499                initiator = initiator.get(0);
500            }
501
502            if (!initiator) {
503                initiator = document.body;
504            }
505
506            triggerEvent(initiator, 'action-start.commerce', {
507                action: action,
508                data: data
509            });
510
511            var matches;
512
513            if (matches = action.match(/^([a-z]+)\/([a-z]+)$/)) {
514                var eventName = matches[1].charAt(0).toUpperCase() + matches[1].slice(1) + '-' + matches[2].charAt(0).toUpperCase() + matches[2].slice(1);
515                eventName = eventName.toLowerCase();
516
517                var event = triggerEvent(initiator, eventName + '.commerce', data);
518                if (event.isPrevented()) {
519                    return;
520                }
521
522                var hashes = getCartsHashes();
523
524                (function(eventName, data, initiator) {
525                    request(Commerce.params.path + 'commerce/action', {
526                        action: action,
527                        data:   data,
528                        hashes: hashes
529                    }, function(response) {
530                        if (response.markup) {
531                            reloadMarkupFromResponse(response.markup);
532                        }
533
534                        if (!document.body.contains(initiator)) {
535                            var container = initiator;
536
537                            while (container.parentElement) {
538                                container = container.parentElement;
539                            }
540
541                            if (container.hasAttribute('data-commerce-cart')) {
542                                initiator = document.querySelector('[data-commerce-cart="' + container.getAttribute('data-commerce-cart') + '"]');
543
544                                if (!initiator) {
545                                    initiator = document.body;
546                                }
547                            }
548                        }
549
550                        triggerEvent(initiator, eventName + '-complete.commerce', {
551                            response: response,
552                            data: data
553                        });
554
555                        triggerEvent(initiator, 'action-complete.commerce', {
556                            response: response,
557                            action: action,
558                            data: data
559                        });
560                    });
561                })(eventName, data, initiator);
562            }
563        },
564
565        add: function(id, count, options) {
566            options = options || {};
567            var data = extendObject({}, options, {
568                id: id,
569                count: count || 1,
570                cart: {
571                    instance: options.instance || 'products'
572                }
573            });
574
575            return Commerce.action('cart/add', data);
576        },
577
578        remove: function(row, options) {
579            options = options || {};
580            return Commerce.action('cart/remove', {
581                row: row,
582                cart: {
583                    instance: options.instance || 'products'
584                }
585            });
586        },
587
588        clean: function(instance) {
589            return Commerce.action('cart/clean', {
590                cart: {
591                    instance: instance || 'products'
592                }
593            });
594        },
595
596        reloadCarts: function(options) {
597            if (typeof options == 'undefined') {
598                options = {};
599            }
600
601            options.hashes = getCartsHashes();
602
603            if (options.hashes.carts.length || options.hashes.form) {
604                request(Commerce.params.path + 'commerce/cart/contents', options, function(response) {
605                    if (response.status == 'success' && response.markup) {
606                        reloadMarkupFromResponse(response.markup);
607                        triggerEvent(document, 'carts-reloaded.commerce');
608                    }
609                });
610            }
611        },
612
613        updateOrderData: function(form) {
614            if (window.jQuery && form instanceof jQuery) {
615                form = form.get(0);
616            }
617
618            var data = serializeForm(form);
619
620            data.hashes = getCartsHashes();
621
622            triggerEvent(form, 'order-data-update.commerce', {
623                data: data
624            });
625
626            request(Commerce.params.path + 'commerce/data/update', data, function(response) {
627                triggerEvent(form, 'order-data-updated.commerce', {
628                    data: data,
629                    response: response
630                });
631
632                if (response.status == 'success') {
633                    if (response.markup) {
634                        reloadMarkupFromResponse(response.markup);
635                    }
636                }
637            });
638        },
639
640        setCurrency: function(code) {
641            request(Commerce.params.path + 'commerce/currency/set', {code: code}, function(response) {
642                if (response.status == 'success') {
643                    location.reload();
644                }
645            });
646        },
647
648        formatPrice: function(price) {
649            var input   = price,
650                cleaned = price.toString().replace(',', '.').replace(' ', ''),
651                number  = parseFloat(cleaned),
652                minus   = '',
653                curr    = Commerce.params.currency;
654
655            if (number != cleaned) {
656                return input;
657            }
658
659            if (number < 0) {
660                minus  = '-';
661                number = -number;
662            }
663
664            var integer = parseInt(number.toFixed(curr.decimals)) + '',
665                left    = integer.split(/(?=(?:\d{3})+$)/).join(curr.thsep),
666                right   = (curr.decimals ? curr.decsep + Math.abs(number - integer).toFixed(curr.decimals).replace(/-/, 0).slice(2) : '');
667
668            return minus + curr.left + left + right + curr.right;
669        },
670
671        getServiceFunctions: function() {
672            return {
673                objectToFormData: objectToFormData,
674                serializeForm: serializeForm,
675                serializeDataAttributes: serializeDataAttributes,
676                extendObject: extendObject,
677                markupToElement: markupToElement,
678                delegateEvent: delegateEvent,
679                triggerEvent: triggerEvent,
680                request: request,
681            };
682        }
683    };
684}());

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.