From e7386e20cf90cbc8e7c59938c2a78cd66c0f8bf5 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Thu, 28 Jul 2016 11:51:06 -0400 Subject: [PATCH] closes #4505 --- public/language/en_GB/global.json | 4 +- public/src/admin/appearance/customise.js | 4 ++ public/src/admin/manage/category.js | 4 ++ public/src/admin/settings.js | 9 ++++ public/src/ajaxify.js | 62 +++++++++++++++--------- public/src/modules/settings.js | 9 ++++ src/views/admin/header.tpl | 3 +- 7 files changed, 70 insertions(+), 25 deletions(-) diff --git a/public/language/en_GB/global.json b/public/language/en_GB/global.json index 226589b8af..6641c28261 100644 --- a/public/language/en_GB/global.json +++ b/public/language/en_GB/global.json @@ -116,5 +116,7 @@ "enter_page_number": "Enter page number", "upload_file": "Upload file", "upload": "Upload", - "allowed-file-types": "Allowed file types are %1" + "allowed-file-types": "Allowed file types are %1", + + "unsaved-changes": "You have unsaved changes. Are you sure you wish to navigate away?" } diff --git a/public/src/admin/appearance/customise.js b/public/src/admin/appearance/customise.js index a135a240fe..a85fd663ad 100644 --- a/public/src/admin/appearance/customise.js +++ b/public/src/admin/appearance/customise.js @@ -16,6 +16,8 @@ define('admin/appearance/customise', ['admin/settings'], function(Settings) { customCSS.getSession().setMode("ace/mode/css"); customCSS.on('change', function(e) { + app.flags = app.flags || {}; + app.flags._unsaved = true; $('#customCSS-holder').val(customCSS.getValue()); }); @@ -23,6 +25,8 @@ define('admin/appearance/customise', ['admin/settings'], function(Settings) { customHTML.getSession().setMode("ace/mode/html"); customHTML.on('change', function(e) { + app.flags = app.flags || {}; + app.flags._unsaved = true; $('#customHTML-holder').val(customHTML.getValue()); }); }); diff --git a/public/src/admin/manage/category.js b/public/src/admin/manage/category.js index b58d3295b9..8288610e73 100644 --- a/public/src/admin/manage/category.js +++ b/public/src/admin/manage/category.js @@ -18,6 +18,9 @@ define('admin/manage/category', [ if (cid) { modified_categories[cid] = modified_categories[cid] || {}; modified_categories[cid][$(el).attr('data-name')] = $(el).val(); + + app.flags = app.flags || {}; + app.flags._unsaved = true; } } @@ -31,6 +34,7 @@ define('admin/manage/category', [ } if (result && result.length) { + app.flags._unsaved = false; app.alert({ title: 'Updated Categories', message: 'Category IDs ' + result.join(', ') + ' was successfully updated.', diff --git a/public/src/admin/settings.js b/public/src/admin/settings.js index 0c341151e1..9e616cfe80 100644 --- a/public/src/admin/settings.js +++ b/public/src/admin/settings.js @@ -27,6 +27,12 @@ define('admin/settings', ['uploader'], function(uploader) { revertBtn = $('#revert'), x, key, inputType, field; + // Handle unsaved changes + $(fields).on('change', function() { + app.flags = app.flags || {}; + app.flags._unsaved = true; + }); + for (x = 0; x < numFields; x++) { field = fields.eq(x); key = field.attr('data-field'); @@ -77,6 +83,9 @@ define('admin/settings', ['uploader'], function(uploader) { type: 'danger' }); } + + app.flags._unsaved = false; + app.alert({ alert_id: 'config_status', timeout: 2500, diff --git a/public/src/ajaxify.js b/public/src/ajaxify.js index 211cbb15e4..7280de01ed 100644 --- a/public/src/ajaxify.js +++ b/public/src/ajaxify.js @@ -1,11 +1,9 @@ "use strict"; +/*global app, bootbox, templates, socket, config, RELATIVE_PATH*/ var ajaxify = ajaxify || {}; $(document).ready(function() { - - /*global app, templates, socket, config, RELATIVE_PATH*/ - var location = document.location || window.location; var rootUrl = location.protocol + '//' + (location.hostname || location.host) + (location.port ? ':' + location.port : ''); var apiXHR = null; @@ -295,6 +293,32 @@ $(document).ready(function() { // Enhancing all anchors to ajaxify... $(document.body).on('click', 'a', function (e) { + var _self = this; + var process = function() { + if (!e.ctrlKey && !e.shiftKey && !e.metaKey && e.which === 1) { + if (internalLink) { + var pathname = this.href.replace(rootUrl + RELATIVE_PATH + '/', ''); + + // Special handling for urls with hashes + if (window.location.pathname === this.pathname && this.hash.length) { + window.location.hash = this.hash; + } else { + if (ajaxify.go(pathname)) { + e.preventDefault(); + } + } + } else if (window.location.pathname !== '/outgoing') { + if (config.openOutgoingLinksInNewTab) { + window.open(this.href, '_blank'); + e.preventDefault(); + } else if (config.useOutgoingLinksPage) { + ajaxify.go('outgoing?url=' + encodeURIComponent(this.href)); + e.preventDefault(); + } + } + } + }; + if (this.target !== '' || (this.protocol !== 'http:' && this.protocol !== 'https:')) { return; } @@ -311,6 +335,7 @@ $(document).ready(function() { } } + // Default behaviour for rss feeds if (internalLink && $(this).attr('href').endsWith('.rss')) { return; } @@ -319,28 +344,19 @@ $(document).ready(function() { return e.preventDefault(); } - if (!e.ctrlKey && !e.shiftKey && !e.metaKey && e.which === 1) { - if (internalLink) { - var pathname = this.href.replace(rootUrl + RELATIVE_PATH + '/', ''); - - // Special handling for urls with hashes - if (window.location.pathname === this.pathname && this.hash.length) { - window.location.hash = this.hash; - } else { - if (ajaxify.go(pathname)) { - e.preventDefault(); + if (app.flags && app.flags.hasOwnProperty('_unsaved') && app.flags._unsaved === true) { + translator.translate('[[global:unsaved-changes]]', function(text) { + bootbox.confirm(text, function(navigate) { + if (navigate) { + app.flags._unsaved = false; + process.call(_self); } - } - } else if (window.location.pathname !== '/outgoing') { - if (config.openOutgoingLinksInNewTab) { - window.open(this.href, '_blank'); - e.preventDefault(); - } else if (config.useOutgoingLinksPage) { - ajaxify.go('outgoing?url=' + encodeURIComponent(this.href)); - e.preventDefault(); - } - } + }); + }); + return e.preventDefault(); } + + process.call(_self); }); } diff --git a/public/src/modules/settings.js b/public/src/modules/settings.js index 652398f539..79c150854d 100644 --- a/public/src/modules/settings.js +++ b/public/src/modules/settings.js @@ -473,6 +473,12 @@ define('settings', function () { }); $(window).trigger('action:admin.settingsLoaded'); + // Handle unsaved changes + $(formEl).on('change', 'input, select, textarea', function() { + app.flags = app.flags || {}; + app.flags._unsaved = true; + }); + callback(null, values); }); }, @@ -498,6 +504,9 @@ define('settings', function () { hash: hash, values: values }, function (err) { + // Remove unsaved flag to re-enable ajaxify + app.flags._unsaved = false; + if (typeof callback === 'function') { callback(); } else { diff --git a/src/views/admin/header.tpl b/src/views/admin/header.tpl index 03cab80005..3d797ed5be 100644 --- a/src/views/admin/header.tpl +++ b/src/views/admin/header.tpl @@ -15,7 +15,8 @@ var app = { template: "{template.name}", user: JSON.parse('{{userJSON}}'), - config: JSON.parse(decodeURIComponent("{{adminConfigJSON}}")) + config: JSON.parse(decodeURIComponent("{{adminConfigJSON}}")), + flags: {} };