// SupportPal global namespace, we use App because the help widget uses SupportPal. var App = (function () { 'use strict'; // Create a public methods object var modules = { env: $('meta[name="environment"]').prop('content') || "production" }; /** * Add a module or function to the namespace. * * @param {String} name The name of the module. * @param {Object} obj The module object. */ modules.extend = function (name, obj) { if (typeof modules[name] !== "undefined") { throw new Error("A module with name '" + name + "' already exists."); } modules[name] = obj; }; // Return public methods object return modules; })(); // Disable jQuery migrate in production. if (App.env === "production") { $.migrateMute = true; } // flatpickr. if (typeof Lang !== 'undefined') { flatpickr.localize({ weekdays: { shorthand: [ Lang.get('general.sun'), Lang.get('general.mon'), Lang.get('general.tue'), Lang.get('general.wed'), Lang.get('general.thu'), Lang.get('general.fri'), Lang.get('general.sat') ], longhand: [ Lang.get('general.sunday'), Lang.get('general.monday'), Lang.get('general.tuesday'), Lang.get('general.wednesday'), Lang.get('general.thursday'), Lang.get('general.friday'), Lang.get('general.saturday'), ] }, months: { shorthand: [ Lang.get('general.jan'), Lang.get('general.feb'), Lang.get('general.mar'), Lang.get('general.apr'), Lang.get('general.may'), Lang.get('general.jun'), Lang.get('general.jul'), Lang.get('general.aug'), Lang.get('general.sep'), Lang.get('general.oct'), Lang.get('general.nov'), Lang.get('general.dec'), ], longhand: [ Lang.get('general.january'), Lang.get('general.february'), Lang.get('general.march'), Lang.get('general.april'), Lang.get('general.may'), Lang.get('general.june'), Lang.get('general.july'), Lang.get('general.august'), Lang.get('general.september'), Lang.get('general.october'), Lang.get('general.november'), Lang.get('general.december') ] }, firstDayOfWeek: 1, ordinal: function (nth) { var s = nth % 100; if (s > 3 && s < 21) return Lang.get('general.ordinal_th'); switch (s % 10) { case 1: return Lang.get('general.ordinal_st'); case 2: return Lang.get('general.ordinal_nd'); case 3: return Lang.get('general.ordinal_rd'); default: return Lang.get('general.ordinal_th'); } }, rangeSeparator: Lang.get('general.range_separator'), weekAbbreviation: Lang.get('general.week_abbr'), scrollTitle: Lang.get('general.scroll_to_increment'), toggleTitle: Lang.get('general.click_to_toggle'), amPM: [Lang.get('general.am'), Lang.get('general.pm')], yearAriaLabel: Lang.choice('general.year', 1), hourAriaLabel: Lang.choice('general.hour', 1), minuteAriaLabel: Lang.choice('general.min', 1), time_24hr: true }); } // Date picker. $.fn.datepicker = function (options) { var defaults = { // Convert from PHP date format to flatpickr format. dateFormat: $('meta[name=date_format]').prop('content') .replace('jS', 'J') .replace(/([^a-zA-Z])/g, "\\\\$1") }; return $(this).each(function () { // Quick fix to stop flatpickr being loaded twice on an input if (this.className.indexOf('flatpickr-input') === -1) { $(this).flatpickr( $.extend(true, defaults, options) ) } }); }; // Time picker. $.fn.timepicker = function (options) { var defaults = { // Convert from PHP date format to flatpickr format. dateFormat: $('meta[name=time_format]').prop('content').replace('g', 'h') .replace('a', 'K') .replace('A', 'K') .replace(/([^a-zA-Z])/g, "\\\\$1"), enableTime: true, noCalendar: true, time_24hr: ! ($('meta[name=time_format]').prop('content').indexOf('g') > -1), }; return $(this).each(function () { // Quick fix to stop flatpickr being loaded twice on an input if (this._flatpickr === undefined) { $(this).flatpickr( $.extend(true, defaults, options) ) } }); }; // Polyfill for matches, closest and find (IE11), needed for tippy.js // https://developer.mozilla.org/en-US/docs/Web/API/Element/matches#Polyfill if (!Element.prototype.matches) { Element.prototype.matches = Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector; } // https://developer.mozilla.org/en-US/docs/Web/API/Element/closest#Polyfill if (!Element.prototype.closest) { Element.prototype.closest = function (s) { var el = this; do { if (el.matches(s)) return el; el = el.parentElement || el.parentNode; } while (el !== null && el.nodeType === 1); return null; }; } // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find#Polyfill if (!Array.prototype.find) { Object.defineProperty(Array.prototype, 'find', { value: function(predicate) { // 1. Let O be ? ToObject(this value). if (this == null) { throw TypeError('"this" is null or not defined'); } var o = Object(this); // 2. Let len be ? ToLength(? Get(O, "length")). var len = o.length >>> 0; // 3. If IsCallable(predicate) is false, throw a TypeError exception. if (typeof predicate !== 'function') { throw TypeError('predicate must be a function'); } // 4. If thisArg was supplied, let T be thisArg; else let T be undefined. var thisArg = arguments[1]; // 5. Let k be 0. var k = 0; // 6. Repeat, while k < len while (k < len) { // a. Let Pk be ! ToString(k). // b. Let kValue be ? Get(O, Pk). // c. Let testResult be ToBoolean(? Call(predicate, T, « kValue, k, O »)). // d. If testResult is true, return kValue. var kValue = o[k]; if (predicate.call(thisArg, kValue, k, o)) { return kValue; } // e. Increase k by 1. k++; } // 7. Return undefined. return undefined; }, configurable: true, writable: true }); } // Reverse items in selector. // https://www.mail-archive.com/discuss@jquery.com/msg04272.html $.fn.reverse = function () { return this.pushStack(this.get().reverse(), arguments); }; /** * Add a new item to DOM container. This function expects a classname:input[name$="[id]"] to be present * for every unique DOM item within the container. * * @param className * @param container * @returns {number} */ function addNewItem(className, container) { // Clone the element var newElem = $(className + ':first').clone(); // Clear the input values from the cloned DOM newElem.removeClass('first'); // Update the index.. god damn you Laravel // Longwinded but ensures a unique key // Find the highest index first and add one var re = /^\w+\[(\d+)?]\[\w+]?$/; var m, index = 0; $(className + ' :input[name$="[id]"]').each(function () { if ((m = re.exec($(this).attr('name'))) !== null) { if (typeof m[1] != 'undefined') { if ((m = parseInt(m[1])) >= index) { index = m + 1; } } } }); // Update all the indexes in the new element newElem.find(':input, label').each(function () { var elem = $(this); elem.prop('disabled', false); [ 'name', 'for', 'id' ].map(function (attribute) { var attr = elem.attr(attribute); if (/^\w+\[(\d+)?](\[[\w:-]+])*(\[\])?$/g.test(attr)) { elem.attr(attribute, attr.replace(/\[(\d+)?]/, '[' + index + ']')); } }); }); // Where do we want to put it? if (typeof container !== 'undefined') { // Append cloned DOM to the end of the parent container $(container).append(newElem); } else { // Append cloned DOM to the end of the list $(className + ':last').after(newElem); } // Make it visible newElem.removeClass('sp-hidden'); // Auto select first option of dropdowns - fix for firefox newElem.find('select').each(function () { $(this).find('option:first').prop('selected', 'selected'); }); return index; } // Wait for DOM to load before running the below. $(function () { // Tooltip - tippy.js tippy.delegate(document.body, { content: function (reference) { var title = reference.getAttribute('title'); reference.removeAttribute('title'); reference.setAttribute('data-tippy-content', title); return title; }, onShow: function (instance) { return instance.reference.hasAttribute('data-tippy-content') && ! instance.reference.classList.contains('tox-edit-area__iframe') && ! instance.reference.classList.contains('tox-collection__item') && instance.reference.getAttribute('data-tippy-content').length > 0; }, target: '[title]', touch: ['hold', 500], zIndex: 10052, }); // Logout handler. $('.logout-link').on('click', function (e) { e.preventDefault(); var $form = $('