diff --git a/CHANGELOG.md b/CHANGELOG.md index 5dc98806..d9e23d63 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +# v1.10.49.1 +## 09/03/2025 + +1. [](#bugfix) + * Fixed several JS issues with Notifications and Scheduler + # v1.10.49 ## 08/25/2025 diff --git a/blueprints.yaml b/blueprints.yaml index 6d3d93b5..2a6b0384 100644 --- a/blueprints.yaml +++ b/blueprints.yaml @@ -1,7 +1,7 @@ name: Admin Panel slug: admin type: plugin -version: 1.10.49 +version: 1.10.49.1 description: Adds an advanced administration panel to manage your site icon: empire author: diff --git a/themes/grav/app/forms/state.js b/themes/grav/app/forms/state.js index 01d069f9..4356e3d6 100644 --- a/themes/grav/app/forms/state.js +++ b/themes/grav/app/forms/state.js @@ -13,8 +13,15 @@ const DOMBehaviors = { preventUnload() { let selector = '[name="task"][value^="save"], [data-delete-action], [data-flex-safe-action]'; - if ($._data(window, 'events') && ($._data(window, 'events').beforeunload || []).filter((event) => event.namespace === '_grav').length) { - return; + // jQuery 3.x removed $._data, use $._data only if available (jQuery < 3.0) + // or check with jQuery's internal data store for jQuery >= 3.0 + try { + const hasData = typeof $._data === 'function'; + if (hasData && $._data(window, 'events') && ($._data(window, 'events').beforeunload || []).filter((event) => event.namespace === '_grav').length) { + return; + } + } catch (e) { + // $._data not available in jQuery 3.x+, continue with adding event handler } // Allow some elements to leave the page without native confirmation @@ -33,8 +40,15 @@ const DOMBehaviors = { preventClickAway() { let selector = 'a[href]:not([href^="#"]):not([target="_blank"]):not([href^="javascript:"])'; - if ($._data($(selector).get(0), 'events') && ($._data($(selector).get(0), 'events').click || []).filter((event) => event.namespace === '_grav')) { - return; + // jQuery 3.x removed $._data, use $._data only if available (jQuery < 3.0) + try { + const hasData = typeof $._data === 'function'; + const element = $(selector).get(0); + if (element && hasData && $._data(element, 'events') && ($._data(element, 'events').click || []).filter((event) => event.namespace === '_grav')) { + return; + } + } catch (e) { + // $._data not available in jQuery 3.x+, continue with adding event handler } // Prevent clicking away if the form state is dirty diff --git a/themes/grav/app/updates/index.js b/themes/grav/app/updates/index.js index 31f5151e..6284e6de 100644 --- a/themes/grav/app/updates/index.js +++ b/themes/grav/app/updates/index.js @@ -99,7 +99,7 @@ export default class Updates { if (!this.payload.resources.total) { return this; } [plugins, themes].forEach(function(resources, index) { - if (!resources || Array.isArray(resources)) { return; } + if (!resources || Array.isArray(resources) || typeof resources !== 'object') { return; } let length = Object.keys(resources).length; let type = map[index]; diff --git a/themes/grav/app/updates/update.js b/themes/grav/app/updates/update.js index 851486a8..5878beda 100644 --- a/themes/grav/app/updates/update.js +++ b/themes/grav/app/updates/update.js @@ -7,7 +7,18 @@ import { Instance as Update } from './index'; // Dashboard update and Grav update $(document).on('click.remodal', '[data-remodal-id="update-grav"] [data-remodal-action="confirm"]', () => { const element = $('#grav-update-button'); - element.html(`${translations.PLUGIN_ADMIN.UPDATING_PLEASE_WAIT} ${formatBytes(Update.payload.grav.assets['grav-update'].size)}..`); + + // Safely get the file size with fallback + let sizeText = ''; + if (Update.payload && + Update.payload.grav && + Update.payload.grav.assets && + Update.payload.grav.assets['grav-update'] && + Update.payload.grav.assets['grav-update'].size) { + sizeText = ` ${formatBytes(Update.payload.grav.assets['grav-update'].size)}`; + } + + element.html(`${translations.PLUGIN_ADMIN.UPDATING_PLEASE_WAIT}${sizeText}..`); element.attr('disabled', 'disabled').find('> .fa').removeClass('fa-cloud-download').addClass('fa-refresh fa-spin'); diff --git a/themes/grav/app/utils/request.js b/themes/grav/app/utils/request.js index 2b7911f3..b5a2f0ee 100644 --- a/themes/grav/app/utils/request.js +++ b/themes/grav/app/utils/request.js @@ -12,7 +12,9 @@ let request = function(url, options = {}, callback = () => true) { let data = new FormData(); options.body = Object.assign({ 'admin-nonce': config.admin_nonce }, options.body || {}); - Object.keys(options.body).map((key) => data.append(key, options.body[key])); + if (options.body && typeof options.body === 'object') { + Object.keys(options.body).map((key) => data.append(key, options.body[key])); + } options.body = data; } diff --git a/themes/grav/app/utils/response.js b/themes/grav/app/utils/response.js index 9cb8d059..6bcde807 100644 --- a/themes/grav/app/utils/response.js +++ b/themes/grav/app/utils/response.js @@ -73,7 +73,7 @@ export function userFeedback(response) { break; } - if (settings) { + if (settings && typeof settings === 'object' && settings !== null) { backup = Object.assign({}, toastr.options); Object.keys(settings).forEach((key) => { toastr.options[key] = settings[key]; }); } diff --git a/themes/grav/js/admin.min.js b/themes/grav/js/admin.min.js index 56b2d190..77c17049 100644 --- a/themes/grav/js/admin.min.js +++ b/themes/grav/js/admin.min.js @@ -704,6 +704,7 @@ const external_GravAdmin_namespaceObject = GravAdmin; var trim = __webpack_require__(35814); var trim_default = /*#__PURE__*/__webpack_require__.n(trim); ;// CONCATENATED MODULE: ./app/utils/response.js +function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } @@ -770,7 +771,7 @@ function userFeedback(response) { message = message || 'Invalid AJAX response.'; break; } - if (settings) { + if (settings && _typeof(settings) === 'object' && settings !== null) { backup = Object.assign({}, utils_toastr.options); Object.keys(settings).forEach(function (key) { utils_toastr.options[key] = settings[key]; @@ -796,6 +797,7 @@ external_jQuery_default()(__webpack_require__.g).on('beforeunload._ajax', functi UNLOADING = true; }); ;// CONCATENATED MODULE: ./app/utils/request.js +function request_typeof(o) { "@babel/helpers - typeof"; return request_typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, request_typeof(o); } var raw; @@ -813,9 +815,11 @@ var request = function request(url) { options.body = Object.assign({ 'admin-nonce': external_GravAdmin_namespaceObject.config.admin_nonce }, options.body || {}); - Object.keys(options.body).map(function (key) { - return data.append(key, options.body[key]); - }); + if (options.body && request_typeof(options.body) === 'object') { + Object.keys(options.body).map(function (key) { + return data.append(key, options.body[key]); + }); + } options.body = data; } options = Object.assign({ @@ -833,12 +837,12 @@ var request = function request(url) { }; /* harmony default export */ const utils_request = (request); ;// CONCATENATED MODULE: ./app/forms/fields/files.js -function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } +function files_typeof(o) { "@babel/helpers - typeof"; return files_typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, files_typeof(o); } function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); } function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } } function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; } -function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; } -function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } +function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == files_typeof(i) ? i : i + ""; } +function _toPrimitive(t, r) { if ("object" != files_typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != files_typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } // import EXIF from 'exif-js'; @@ -1692,7 +1696,13 @@ function formatBytes(bytes, decimals) { // Dashboard update and Grav update external_jQuery_default()(document).on('click.remodal', '[data-remodal-id="update-grav"] [data-remodal-action="confirm"]', function () { var element = external_jQuery_default()('#grav-update-button'); - element.html("".concat(external_GravAdmin_namespaceObject.translations.PLUGIN_ADMIN.UPDATING_PLEASE_WAIT, " ").concat(formatBytes(updates_Instance.payload.grav.assets['grav-update'].size), "..")); + + // Safely get the file size with fallback + var sizeText = ''; + if (updates_Instance.payload && updates_Instance.payload.grav && updates_Instance.payload.grav.assets && updates_Instance.payload.grav.assets['grav-update'] && updates_Instance.payload.grav.assets['grav-update'].size) { + sizeText = " ".concat(formatBytes(updates_Instance.payload.grav.assets['grav-update'].size)); + } + element.html("".concat(external_GravAdmin_namespaceObject.translations.PLUGIN_ADMIN.UPDATING_PLEASE_WAIT).concat(sizeText, "..")); element.attr('disabled', 'disabled').find('> .fa').removeClass('fa-cloud-download').addClass('fa-refresh fa-spin'); utils_request(updates_Instance.updateURL, function (response) { if (response.type === 'updategrav') { @@ -1824,7 +1834,7 @@ var Updates = /*#__PURE__*/function () { return this; } [plugins, themes].forEach(function (resources, index) { - if (!resources || Array.isArray(resources)) { + if (!resources || Array.isArray(resources) || updates_typeof(resources) !== 'object') { return; } var length = Object.keys(resources).length; @@ -4225,10 +4235,17 @@ var DOMBehaviors = { }, preventUnload: function preventUnload() { var selector = '[name="task"][value^="save"], [data-delete-action], [data-flex-safe-action]'; - if (external_jQuery_default()._data(window, 'events') && (external_jQuery_default()._data(window, 'events').beforeunload || []).filter(function (event) { - return event.namespace === '_grav'; - }).length) { - return; + // jQuery 3.x removed $._data, use $._data only if available (jQuery < 3.0) + // or check with jQuery's internal data store for jQuery >= 3.0 + try { + var hasData = typeof (external_jQuery_default())._data === 'function'; + if (hasData && external_jQuery_default()._data(window, 'events') && (external_jQuery_default()._data(window, 'events').beforeunload || []).filter(function (event) { + return event.namespace === '_grav'; + }).length) { + return; + } + } catch (e) { + // $._data not available in jQuery 3.x+, continue with adding event handler } // Allow some elements to leave the page without native confirmation @@ -4245,10 +4262,18 @@ var DOMBehaviors = { }, preventClickAway: function preventClickAway() { var selector = 'a[href]:not([href^="#"]):not([target="_blank"]):not([href^="javascript:"])'; - if (external_jQuery_default()._data(external_jQuery_default()(selector).get(0), 'events') && (external_jQuery_default()._data(external_jQuery_default()(selector).get(0), 'events').click || []).filter(function (event) { - return event.namespace === '_grav'; - })) { - return; + + // jQuery 3.x removed $._data, use $._data only if available (jQuery < 3.0) + try { + var hasData = typeof (external_jQuery_default())._data === 'function'; + var element = external_jQuery_default()(selector).get(0); + if (element && hasData && external_jQuery_default()._data(element, 'events') && (external_jQuery_default()._data(element, 'events').click || []).filter(function (event) { + return event.namespace === '_grav'; + })) { + return; + } + } catch (e) { + // $._data not available in jQuery 3.x+, continue with adding event handler } // Prevent clicking away if the form state is dirty