PluginProbe
VikBooking Hotel Booking Engine & PMS / 1.8.16
VikBooking Hotel Booking Engine & PMS v1.8.16
1.8.16 1.8.15 1.8.14 1.8.13 1.8.12 1.8.11 1.8.10 1.8.9 1.8.6 1.8.7 1.8.8 trunk 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.7 1.6.8 1.6.9 1.7.0 1.7.1 1.7.2 All 37 releases
← All changes | admin/resources/js/system.js +779 -0 1.6.3 → 1.8.16 View file →
@@ -1,0 +1,779 @@
1 +/**
2 + * Joomla Core
3 + */
4 +
5 +function JoomlaCore() {
6 + // instantiate only once because iframe pages might invoke this method again
7 + if (!JoomlaCore.instance) {
8 + // init pagination handler
9 + this.paginations = {};
10 + // init translations handler
11 + this.JText = new JText();
12 + // init editors instances
13 + this.editors = {instances: {}};
14 +
15 + // register singleton
16 + JoomlaCore.instance = this;
17 + }
18 +
19 + return JoomlaCore.instance;
20 +}
21 +
22 +JoomlaCore.prototype.getPagination = function(prefix) {
23 + key = prefix || '__default__';
24 +
25 + if (!this.paginations.hasOwnProperty(key)) {
26 + this.paginations[key] = new JPagination();
27 + this.paginations[key].setPrefix(prefix)
28 + }
29 +
30 + return this.paginations[key];
31 +}
32 +
33 +JoomlaCore.prototype.checkAll = function(checkbox) {
34 + // Use :visible selector in order to skip hidden checkboxes.
35 + // This is helpful to ignore hidden inputs while filtering the list.
36 + jQuery('#adminForm input[name="cid[]"]:visible').prop('checked', checkbox.checked);
37 +}
38 +
39 +JoomlaCore.prototype.isChecked = function(checked) {
40 + // get toggle-all checkbox
41 + var allBox = jQuery('#adminForm thead input[type="checkbox"]');
42 +
43 + if (!checked || jQuery('#adminForm input[name="cid[]"]').length != this.hasChecked()) {
44 + allBox.prop('checked', false);
45 + } else {
46 + allBox.prop('checked', true);
47 + }
48 +}
49 +
50 +JoomlaCore.prototype.hasChecked = function() {
51 + return jQuery('#adminForm input[name="cid[]"]:checked').length;
52 +}
53 +
54 +JoomlaCore.prototype.submitform = function(task, form) {
55 + if (task && form.task) {
56 + form.task.value = task;
57 + }
58 +
59 + jQuery(form).submit();
60 +}
61 +
62 +JoomlaCore.prototype.submitbutton = function(task) {
63 + this.submitform(task, document.adminForm);
64 +}
65 +
66 +JoomlaCore.prototype.tableOrdering = function(column, direction, task, form) {
67 + if (form === undefined) {
68 + form = document.adminForm;
69 + }
70 +
71 + if (form.filter_order === undefined) {
72 + var orderInput = document.createElement('input');
73 + orderInput.type = 'hidden';
74 + orderInput.name = 'filter_order';
75 +
76 + form.appendChild(orderInput);
77 + }
78 +
79 + form.filter_order.value = column;
80 +
81 + if (form.filter_order_Dir === undefined) {
82 + var directionInput = document.createElement('input');
83 + directionInput.type = 'hidden';
84 + directionInput.name = 'filter_order_Dir';
85 +
86 + form.appendChild(directionInput);
87 + }
88 +
89 + form.filter_order_Dir.value = direction;
90 +
91 + this.submitform(task, form);
92 +}
93 +
94 +JoomlaCore.getOptions = function(key, def) {
95 + // load options if they not exists
96 + if (!JoomlaCore.optionsStorage) {
97 + JoomlaCore.loadOptions();
98 + }
99 +
100 + return JoomlaCore.optionsStorage[key] !== undefined ? JoomlaCore.optionsStorage[key] : def;
101 +};
102 +
103 +JoomlaCore.loadOptions = function(options) {
104 + if (!options) {
105 + var elements = jQuery('script.joomla-options.new');
106 + var counter = 0;
107 +
108 + for (var i = 0, l = elements.length; i < l; i++) {
109 + var element = elements[i];
110 + var str = element.text || element.textContent;
111 + var option = {};
112 +
113 + try {
114 + option = JSON.parse(str);
115 + } catch (err) {
116 + console.log(err);
117 + }
118 +
119 + if (option) {
120 + JoomlaCore.loadOptions(option);
121 + counter++;
122 + }
123 +
124 + // mark element as loaded
125 + jQuery(element).removeClass('new').addClass('loaded');
126 + }
127 +
128 + if (counter) {
129 + return;
130 + }
131 + }
132 +
133 + // initial loading
134 + if (!JoomlaCore.optionsStorage) {
135 + JoomlaCore.optionsStorage = options || {};
136 + }
137 + // Merge with existing
138 + else if (options ) {
139 + for (var p in options) {
140 + if (options.hasOwnProperty(p)) {
141 + JoomlaCore.optionsStorage[p] = options[p];
142 + }
143 + }
144 + }
145 +};
146 +
147 +JoomlaCore.isAdmin = function() {
148 + return document.location.href.match(/\/wp-admin\//i) ? true : false;
149 +}
150 +
151 +/**
152 + * Pagination
153 + */
154 +
155 +function JPagination(total, limit, start, listener) {
156 +
157 + if (total === undefined) {
158 + total = 0;
159 + }
160 +
161 + if (limit === undefined) {
162 + limit = 0;
163 + }
164 +
165 + if (start === undefined) {
166 + start = 0;
167 + }
168 +
169 + if (listener === undefined) {
170 + listener = null;
171 + }
172 +
173 + this.total = total;
174 + this.limit = limit;
175 + this.start = start;
176 + this.prefix = '';
177 +
178 + this.listener = listener;
179 +
180 + return this;
181 +}
182 +
183 +JPagination.prototype.setTotal = function(total) {
184 + this.total = total;
185 +
186 + return this;
187 +}
188 +
189 +JPagination.prototype.setLimit = function(limit) {
190 + this.limit = limit;
191 +
192 + return this;
193 +}
194 +
195 +JPagination.prototype.setStart = function(start) {
196 + this.start = start;
197 +
198 + return this;
199 +}
200 +
201 +JPagination.prototype.setListener = function(listener) {
202 + this.listener = listener;
203 +
204 + return this;
205 +}
206 +
207 +JPagination.prototype.setPrefix = function(prefix) {
208 + this.prefix = prefix || '';
209 +
210 + return this;
211 +}
212 +
213 +JPagination.prototype.submit = function() {
214 +
215 + if (this.listener[this.prefix + 'limitstart'] === undefined) {
216 + var limitstart = document.createElement('input');
217 + limitstart.type = 'hidden';
218 + limitstart.name = this.prefix + 'limitstart';
219 +
220 + this.listener.appendChild(limitstart);
221 + }
222 +
223 + if (this.listener[this.prefix + 'limit'] === undefined) {
224 + var limit = document.createElement('input');
225 + limit.type = 'hidden';
226 + limit.name = this.prefix + 'limit';
227 +
228 + this.listener.appendChild(limit);
229 + }
230 +
231 + this.listener[this.prefix + 'limitstart'].value = this.start;
232 + this.listener[this.prefix + 'limit'].value = this.limit;
233 +
234 + // submit through jQuery in order to
235 + // properly emit the "submit" event
236 + jQuery(this.listener).submit();
237 +}
238 +
239 +JPagination.prototype.first = function() {
240 + this.start = 0;
241 + this.submit();
242 +}
243 +
244 +JPagination.prototype.prev = function() {
245 + this.start -= this.limit;
246 + this.submit();
247 +}
248 +
249 +JPagination.prototype.next = function() {
250 + this.start += this.limit;
251 + this.submit();
252 +}
253 +
254 +JPagination.prototype.last = function() {
255 + this.start = (Math.ceil(this.total / this.limit) - 1) * this.limit;
256 + this.submit();
257 +}
258 +
259 +/**
260 + * Text
261 + */
262 +
263 +function JText() {
264 + this.strings = {};
265 +
266 + return this;
267 +}
268 +
269 +JText.prototype._ = function(key, def) {
270 + // check for new strings in the optionsStorage, and load them
271 + var newStrings = JoomlaCore.getOptions('joomla.jtext');
272 +
273 + if (newStrings) {
274 + this.load(newStrings);
275 +
276 + // Clean up the optionsStorage from useless data
277 + JoomlaCore.loadOptions({'joomla.jtext': null});
278 + }
279 +
280 + def = def === undefined ? '' : def;
281 + key = key.toUpperCase();
282 +
283 + return this.strings[key] !== undefined ? this.strings[key] : def;
284 +}
285 +
286 +JText.prototype.load = function(object) {
287 + for (var key in object) {
288 + if (object.hasOwnProperty(key)) {
289 + this.strings[key.toUpperCase()] = object[key];
290 + }
291 + }
292 +
293 + return this;
294 +}
295 +
296 +/*
297 + * FORM VALIDATION
298 + */
299 +
300 +function JFormValidator(form, clazz) {
301 + this.form = form;
302 +
303 + if (typeof clazz === 'undefined') {
304 + clazz = 'invalid';
305 + }
306 +
307 + this.clazz = clazz;
308 + this.labels = {};
309 +
310 + // prevent the form submission on enter keydown
311 +
312 + jQuery(this.form).on('keyup', function(e) {
313 + var keyCode = e.keyCode || e.which;
314 +
315 + if (keyCode === 13) {
316 + e.preventDefault();
317 + return false;
318 + }
319 + });
320 +
321 + this.registerFields('.required');
322 +}
323 +
324 +JFormValidator.prototype.isValid = function(input) {
325 + var val = jQuery(input).val();
326 +
327 + return val !== null && val.length > 0;
328 +}
329 +
330 +JFormValidator.prototype.registerFields = function(selector) {
331 +
332 + var _this = this;
333 +
334 + jQuery(this.form).find(selector).on('blur', function() {
335 + if (_this.isValid(this)) {
336 + _this.unsetInvalid(this);
337 + } else {
338 + _this.setInvalid(this);
339 + }
340 + });
341 +
342 + return this;
343 +}
344 +
345 +JFormValidator.prototype.unregisterFields = function(selector) {
346 +
347 + jQuery(this.form).find(selector).off('blur')
348 +
349 + return this;
350 +}
351 +
352 +JFormValidator.prototype.validate = function(callback) {
353 + var ok = true;
354 +
355 + var _this = this;
356 +
357 + this.clearInvalidTabPane();
358 +
359 + jQuery(this.form).find('.required:input').each(function() {
360 + if (_this.isValid(this)) {
361 + _this.unsetInvalid(this);
362 + } else {
363 + _this.setInvalid(this);
364 + ok = false;
365 +
366 + if (!jQuery(this).is(':visible')) {
367 + // the input is probably hidden behind
368 + // an unactive tab pane
369 + _this.setInvalidTabPane(this);
370 + }
371 + }
372 + });
373 +
374 + if (typeof callback !== 'undefined') {
375 + ok = callback() && ok;
376 + }
377 +
378 + return ok;
379 +}
380 +
381 +JFormValidator.prototype.setLabel = function(input, label) {
382 + this.labels[jQuery(input).attr('name')] = label;
383 +
384 + return this;
385 +}
386 +
387 +JFormValidator.prototype.getLabel = function(input) {
388 + var name = jQuery(input).attr('name');
389 +
390 + if (this.labels.hasOwnProperty(name)) {
391 + return jQuery(this.labels[name]);
392 + }
393 +
394 + return jQuery(input).closest('.control').children().filter('b,label');
395 +}
396 +
397 +JFormValidator.prototype.setInvalid = function(input) {
398 + jQuery(input).addClass(this.clazz);
399 + this.getLabel(input).addClass(this.clazz);
400 +
401 + return this;
402 +}
403 +
404 +JFormValidator.prototype.unsetInvalid = function(input) {
405 + jQuery(input).removeClass(this.clazz);
406 + this.getLabel(input).removeClass(this.clazz);
407 +
408 + return this;
409 +}
410 +
411 +JFormValidator.prototype.isInvalid = function(input) {
412 + return jQuery(input).hasClass(this.clazz);
413 +}
414 +
415 +JFormValidator.prototype.clearInvalidTabPane = function() {
416 + jQuery('ul.nav-tabs li a').removeClass(this.clazz);
417 +
418 + return this;
419 +}
420 +
421 +JFormValidator.prototype.setInvalidTabPane = function(input) {
422 + var pane = jQuery(input).closest('.tab-pane');
423 +
424 + if (pane.length) {
425 + var id = jQuery(pane).attr('id');
426 + var link = jQuery('ul.nav-tabs li a[href="#' + id + '"]');
427 +
428 + if (link.length) {
429 + link.addClass(this.clazz);
430 + }
431 + }
432 +
433 + return this;
434 +}
435 +
436 +/**
437 + * TRIGGER JMODAL
438 + */
439 +
440 +function wpOpenJModal(id, href, onShow, onHide) {
441 +
442 + if (onShow !== undefined)
443 + {
444 + jQuery('#jmodal-' + id).on('show', onShow);
445 + }
446 +
447 + if (onHide !== undefined)
448 + {
449 + jQuery('#jmodal-' + id).on('hide', onHide);
450 + }
451 +
452 + if (!href) {
453 + // try to extract url from modal URL input
454 + href = jQuery('#jmodal-' + id + ' > input[name="url"]').val();
455 + }
456 +
457 + var hideOnEsc = null;
458 +
459 + // check if the modal can be closed using the ESC button
460 + if (jQuery('#jmodal-' + id).data('esc') == 1) {
461 + hideOnEsc = function(event) {
462 + if (event.keyCode == 27) {
463 + // close modal when ESC is pressed
464 + wpCloseJModal(id);
465 + }
466 + };
467 +
468 + jQuery(window).on('keydown', hideOnEsc);
469 + }
470 +
471 + jQuery('#jmodal-' + id).on('hide.bs.modal', function() {
472 + // we should remove the body only whether it has been loaded asynchronously
473 + if (href) {
474 + jQuery(this).find('.modal-body').remove();
475 + }
476 +
477 + jQuery('#jmodal-' + id).off('show.bs.modal');
478 + jQuery('#jmodal-' + id).off('hide.bs.modal');
479 +
480 + if (hideOnEsc) {
481 + // turn off esc handler too after disposing the modal
482 + jQuery(window).off('keydown', hideOnEsc);
483 + }
484 + });
485 +
486 + // trigger "show" event to support external listeners
487 + jQuery('#jmodal-' + id).modal('show').trigger('show');
488 +
489 + var closeBtn = jQuery('#jmodal-' + id).find('button[data-dismiss]');
490 +
491 + // add workaround to trigger hide|hidden events also when
492 + // clicking the dismiss button of the modal
493 + closeBtn.on('click', function() {
494 + jQuery('#jmodal-' + id).trigger('hide').trigger('hidden').trigger('hide.bs.modal');
495 + });
496 +
497 + // hide on backdrop click only in case the modal is dismissable
498 + if (closeBtn.length || hideOnEsc) {
499 + jQuery('.modal-backdrop').on('click', function() {
500 + wpCloseJModal(id);
501 + });
502 + }
503 +
504 + if (href)
505 + {
506 + wpAppendModalContent('jmodal-box-' + id, href);
507 + }
508 +}
509 +
510 +function wpCloseJModal(id) {
511 + if (id.match(/^jmodal-/)) {
512 + // full ID without "#"
513 + id = "#" + id;
514 + } else if (!id.match(/^#jmodal-/)) {
515 + // modal ID only
516 + id = "#jmodal-" + id;
517 + }
518 +
519 + // close modal and trigger hide|hidden events
520 + jQuery(id).modal('hide').trigger('hide').trigger('hidden').trigger('hide.bs.modal');
521 +}
522 +
523 +function wpAppendModalContent(id, href) {
524 +
525 + var data = {};
526 +
527 + if (typeof href === 'object') {
528 + data = href.serialize();
529 + href = 'admin-ajax.php';
530 + } else if (typeof href === 'string') {
531 + href = href.replace('index.php', 'admin-ajax.php');
532 + href = href.replace('admin.php', 'admin-ajax.php');
533 + }
534 +
535 + setTimeout(function() {
536 +
537 + doAjax(
538 + href,
539 + data,
540 + function(resp) {
541 +
542 + try {
543 + resp = JSON.parse(resp);
544 +
545 + if (Array.isArray(resp)) {
546 + resp = resp.shift();
547 + }
548 + } catch (err) {
549 + // the response is already plain HTML
550 + }
551 +
552 + // tries to fix any ID conflict
553 + resp = makeResponseUnique(resp);
554 +
555 + jQuery('#' + id).html('<div class="modal-body">' + resp + '</div>');
556 +
557 + // route targets for back-end only
558 + if (JoomlaCore.isAdmin()) {
559 + // replaces any index.php with admin.php
560 + routePageTargets('#' + id);
561 + }
562 +
563 + ajaxPreventFormSubmit(id);
564 + },
565 + function(resp) {
566 + alert(Joomla.JText._('CONNECTION_LOST'));
567 + }
568 + );
569 +
570 + }, 128 + Math.random() * 512);
571 +
572 +}
573 +
574 +function makeResponseUnique(resp) {
575 + resp = resp.replace(/adminForm/g, 'innerAdminForm');
576 +
577 + return resp;
578 +}
579 +
580 +function ajaxPreventFormSubmit(id) {
581 + jQuery('#' + id).find('form').on('submit', function(e) {
582 + e.preventDefault();
583 +
584 + wpAppendModalContent(id, jQuery(this));
585 +
586 + return false;
587 + });
588 +
589 + jQuery('#' + id).find('a[target!="_blank"]').filter('a:not([href^="javascript:"],[href^="#"])').on('click', function(e) {
590 + e.preventDefault();
591 +
592 + wpAppendModalContent(id, jQuery(this).attr('href'));
593 +
594 + return false;
595 + });
596 +}
597 +
598 +function routePageTargets(container) {
599 + jQuery(container).find('a[href^="index.php"], form[action^="index.php"]').each(function() {
600 + var attr;
601 +
602 + if (jQuery(this).is('a')) {
603 + attr = 'href';
604 + } else {
605 + attr = 'action';
606 + }
607 +
608 + var value = jQuery(this).attr(attr);
609 +
610 + jQuery(this).attr(attr, value.replace(/^index\.php/, 'admin.php'));
611 + });
612 +
613 + jQuery(container).find('button[onclick^="document.location.href"]').each(function() {
614 + // get current event string
615 + var onclick = jQuery(this).attr('onclick');
616 + // replace index.php into admin.php
617 + onclick = onclick.replace(/index\.php/, 'admin.php');
618 + // update element attribute
619 + jQuery(this).attr('onclick', onclick);
620 + });
621 +}
622 +
623 +/**
624 + * Returns a promise that resolves when the specified instance
625 + * gets defined.
626 + *
627 + * @param function check The callback to invoke to check whether the instance is ready.
628 + * @param mixed threshold An optional threshold to estabilish the max number of attempts.
629 + *
630 + * @return Promise
631 + */
632 +function __isReady(check, threshold) {
633 + return new Promise((resolve, reject) => {
634 + // prepare safe counter
635 + var count = 0;
636 +
637 + var callback = function() {
638 + // increase counter
639 + count++;
640 +
641 + // check whether the instance is ready
642 + var instance = check();
643 +
644 + if (instance) {
645 + // object is now ready
646 + resolve(instance);
647 + } else {
648 + if (!threshold || count < Math.abs(threshold)) {
649 + // check again
650 + setTimeout(callback, 32 + Math.floor(Math.random() * 128));
651 + } else {
652 + // instance not ready
653 + reject();
654 + }
655 + }
656 + };
657 +
658 + // check
659 + callback();
660 + });
661 +}
662 +
663 +/**
664 + * AJAX UTILS
665 + */
666 +
667 +function normalizePostData(data) {
668 +
669 + if (data === undefined) {
670 + data = {};
671 + } else if (Array.isArray(data)) {
672 + // the form data is serialized @see jQuery.serializeArray()
673 + var form = data;
674 +
675 + data = {};
676 +
677 + for (var i = 0; i < form.length; i++) {
678 + // if the field ends with [] it should be an array
679 + if (form[i].name.endsWith("[]")) {
680 + // if the field doesn't exist yet, create a new list
681 + if (!data.hasOwnProperty(form[i].name)) {
682 + data[form[i].name] = new Array();
683 + }
684 +
685 + // append the value to the array
686 + data[form[i].name].push(form[i].value);
687 + } else {
688 + // otherwise overwrite the value (if any)
689 + data[form[i].name] = form[i].value;
690 + }
691 + }
692 + }
693 +
694 + return data;
695 +}
696 +
697 +function doAjax(url, data, success, failure, attempt) {
698 +
699 + var AJAX_MAX_ATTEMPTS = 3;
700 +
701 + if (attempt === undefined) {
702 + attempt = 1;
703 + }
704 +
705 + // return same object if data has been already normalized
706 + data = normalizePostData(data);
707 +
708 + return jQuery.ajax({
709 + type: 'post',
710 + url: url,
711 + data: data
712 + }).done(function(resp) {
713 +
714 + if (success !== undefined) {
715 + success(resp);
716 + }
717 +
718 + }).fail(function(err) {
719 + // If the error has been raised by a connection failure,
720 + // retry automatically the same request. Do not retry if the
721 + // number of attempts is higher than the maximum number allowed.
722 + if (attempt < AJAX_MAX_ATTEMPTS && isConnectionLostError(err)) {
723 +
724 + // wait 128 milliseconds before launching the request
725 + setTimeout(function() {
726 + // relaunch same action and increase number of attempts by 1
727 + doAjax(url, data, success, failure, attempt + 1);
728 + }, 128);
729 +
730 + } else {
731 +
732 + // otherwise raise the failure method
733 + if (failure !== undefined) {
734 + failure(err);
735 + }
736 +
737 + }
738 +
739 + console.log('failure', err);
740 +
741 + if (err.status == 500) {
742 + console.log(err.responseText);
743 + }
744 +
745 + });
746 +}
747 +
748 +function isConnectionLostError(err) {
749 + return (
750 + err.statusText == 'error'
751 + && err.status == 0
752 + && (err.readyState == 0 || err.readyState == 4)
753 + && (!err.hasOwnProperty('responseText') || err.responseText == '')
754 + );
755 +}
756 +
757 +/**
758 + * BROWSER BACKWARD COMPATIBILITY
759 + */
760 +
761 +if (!Array.isArray) {
762 + Array.isArray = function(arg) {
763 + return Object.prototype.toString.call(arg) === '[object Array]';
764 + }
765 +}
766 +
767 +/**
768 + * Joomla instance is now available on both admin and site sections.
769 + * In order to avoid delays with the loading of this class, maybe because of lazy-loading
770 + * techniques of the Theme with "deferred" scripts, we no longer use inline JS code.
771 + *
772 + * @since 1.4.0
773 + */
774 +if (typeof Joomla === 'undefined') {
775 + var Joomla = new JoomlaCore();
776 +} else {
777 + // reload options
778 + JoomlaCore.loadOptions();
779 +}