openrat-cms

OpenRat Content Management System
git clone http://git.code.weiherhei.de/openrat-cms.git
Log | Files | Refs

commit 7d650ae4700c01105cb8b4fd7268687f0108d3bb
parent f27aa3f9e9561aeb8ca6ca6e48b9ee24da37d19e
Author: Jan Dankert <develop@jandankert.de>
Date:   Mon, 24 Aug 2020 22:58:32 +0200

New: Browser should warn, if the application should be closed while there are unsaved changes.

Diffstat:
modules/cms/ui/themes/default/script/openrat.js | 27+++++++++++++++++++++++++--
modules/cms/ui/themes/default/script/openrat.min.js | 7++++---
modules/cms/ui/themes/default/script/openrat/common.js | 5+++--
modules/cms/ui/themes/default/script/openrat/workbench.js | 22++++++++++++++++++++++
4 files changed, 54 insertions(+), 7 deletions(-)

diff --git a/modules/cms/ui/themes/default/script/openrat.js b/modules/cms/ui/themes/default/script/openrat.js @@ -1984,11 +1984,33 @@ Openrat.Workbench = new function() // Initialze Ping timer. this.initializePingTimer(); + this.initializeDirtyWarning(); this.initializeState(); this.openModalDialog(); } + this.initializeDirtyWarning = function () { + + // If the application should be closed, inform the user about unsaved changes. + window.addEventListener('beforeunload', function (e) { + + // Are there views in the dirty state? + if ( $('.view.dirty').length > 0 ) { + + e.preventDefault(); // Cancel the event + + // This text is replaced by modern browsers with a common message. + return 'Unsaved content will be lost.'; + } + else { + // Let the browser quitting the page. + // Do NOT logout here, because there could be other windows/tabs with the same session. + return undefined; // nothing to do. + } + }); + } + /** * Starts a dialog, if necessary. */ @@ -2647,8 +2669,8 @@ Openrat.Workbench.afterViewLoadedHandler.add( function(viewEl ) { // Bei Änderungen in der View das Tab als 'dirty' markieren - $(viewEl).find('input').change( function() { - $(this).parent('div.view').addClass('dirty'); + $(viewEl).find('input,select,textarea').change( function() { + $(this).closest('.view').addClass('dirty'); }); // Theme-Auswahl mit Preview @@ -2834,6 +2856,7 @@ function startDialog( name,action,method,id,params ) if ( $('div#dialog').hasClass('modal') ) return; + $('#dialog .view').removeClass('dirty'); $('#dialog .view').html(''); $('#dialog').removeClass('is-open').addClass('is-closed'); // Dialog schließen diff --git a/modules/cms/ui/themes/default/script/openrat.min.js b/modules/cms/ui/themes/default/script/openrat.min.js @@ -1177,11 +1177,12 @@ else{};return url}}; else{let url='./api/';this.setLoadStatus(!0);url+='';data.output='json';if(e==modes.closeAfterSubmit)this.close();let form=this;$.ajax({'type':'POST',url:url,data:data,success:function(t,s,o){form.setLoadStatus(!1);$(status).remove();form.doResponse(t,s,form.element,function(){if(e==modes.closeAfterSuccess){form.close();$(form.element).closest('div.panel').find('div.header ul.views li.action.active').removeClass('dirty')};let afterSuccess=$(form.element).data('afterSuccess');let async=$(form.element).data('async');if(afterSuccess){if(afterSuccess=='reloadAll'){Openrat.Workbench.reloadAll()}} else{if(async);else Openrat.Workbench.reloadViews()}})},error:function(e,t,s){form.setLoadStatus(!1);$(status).remove();try{let error=jQuery.parseJSON(e.responseText);Openrat.Workbench.notify('','','error',error.error,[error.description])}catch(o){let msg=e.responseText;Openrat.Workbench.notify('','','error','Server Error',[msg])}}});$(form.element).fadeIn()}};this.doResponse=function(e,t,s,onSuccess=$.noop){if(t!='success'){alert('Server error: '+t);return};let form=this;$.each(e['notices'],function(t,e){let notifyBrowser=$(s).data('async');Openrat.Workbench.notify(e.type,e.name,e.status,e.text,e.log,notifyBrowser);if(e.status=='ok'){onSuccess();Openrat.Workbench.dataChangedHandler.fire()} else{}});$.each(e['errors'],function(e,t){$('input[name='+t+']').addClass('error').parent().addClass('error').parents('fieldset').removeClass('closed').addClass('show').addClass('open')});if(e.control.redirect)window.location.href=e.control.redirect}}; -;Openrat.Workbench=new function(){'use strict';this.state={};this.initialize=function(){this.initializePingTimer();this.initializeState();this.openModalDialog()};this.openModalDialog=function(){if($('#dialog').data('action')){startDialog('',$('#dialog').data('action'),$('#dialog').data('action'),0,{})}};this.initializeState=function(){let parts=window.location.hash.split('/');let state={action:'index',id:0};if(parts.length>=2)state.action=parts[1].toLowerCase();if(parts.length>=3)state.id=parts[2].replace(/[^0-9_]/gim,'');Openrat.Workbench.state=state;$('#editor').attr('data-action',state.action);$('#editor').attr('data-id',state.id);$('#editor').attr('data-extra','{}');Openrat.Navigator.toActualHistory(state)};this.initializePingTimer=function(){let ping=function(){let pingPromise=$.getJSON(Openrat.View.createUrl('profile','ping',0,{},!0));pingPromise.fail(function(){console.warn('The server ping has failed.')})};let timeoutMinutes=5;window.setInterval(ping,timeoutMinutes*60*1000)};this.loadNewActionState=function(t){Openrat.Workbench.state=t;Openrat.Workbench.loadNewAction(t.action,t.id,t.data);this.afterNewActionHandler.fire()};this.afterNewActionHandler=$.Callbacks();this.loadNewAction=function(t,e,i){$('#editor').attr('data-action',t);$('#editor').attr('data-id',e);$('#editor').attr('data-extra',JSON.stringify(i));this.reloadViews()};this.reloadViews=function(){$('#workbench section.closed .view-loader').empty();Openrat.Workbench.loadViews($('#workbench section.open .view-loader'))};this.reloadAll=function(){$('#workbench .view').empty();Openrat.Workbench.loadViews($('#workbench .view.view-loader, #workbench .view.view-static'));this.loadUserStyle();this.loadLanguage();this.loadUISettings()};this.loadUserStyle=function(){let url=Openrat.View.createUrl('profile','userinfo',0,{},!0);$.getJSON(url,function(t){let style=t.output['style'];Openrat.Workbench.setUserStyle(style);let color=t.output['theme-color'];Openrat.Workbench.setThemeColor(color)})};this.settings={};this.language={};this.loadLanguage=function(){let url=Openrat.View.createUrl('profile','language',0,{},!0);$.getJSON(url,function(t){Openrat.Workbench.language=t.output.language})};this.loadUISettings=function(){let url=Openrat.View.createUrl('profile','uisettings',0,{},!0);$.getJSON(url,function(t){Openrat.Workbench.settings=t.output.settings.settings})};this.loadViews=function(t){t.each(function(t){let $targetDOMElement=$(this);Openrat.Workbench.loadNewActionIntoElement($targetDOMElement)})};this.loadNewActionIntoElement=function(t){let action;if(t.is('.view-static'))action=t.attr('data-action');else action=$('#editor').attr('data-action');let id=$('#editor').attr('data-id');let params=$('#editor').attr('data-extra');let method=t.data('method');let view=new Openrat.View(action,method,id,params);view.start(t)};this.setUserStyle=function(t){var e=$('html'),i=e.attr('class').split(/\s+/);$.each(i,function(t,i){if(i.startsWith('theme-')){e.removeClass(i)}});e.addClass('theme-'+t.toLowerCase())};this.setThemeColor=function(t){$('#theme-color').attr('content',t)};let notifyBrowser=function(t){if(!('Notification' in window)){return} +;Openrat.Workbench=new function(){'use strict';this.state={};this.initialize=function(){this.initializePingTimer();this.initializeDirtyWarning();this.initializeState();this.openModalDialog()};this.initializeDirtyWarning=function(){window.addEventListener('beforeunload',function(t){if($('.view.dirty').length>0){t.preventDefault();return'Unsaved content will be lost.'} +else{return undefined}})};this.openModalDialog=function(){if($('#dialog').data('action')){startDialog('',$('#dialog').data('action'),$('#dialog').data('action'),0,{})}};this.initializeState=function(){let parts=window.location.hash.split('/');let state={action:'index',id:0};if(parts.length>=2)state.action=parts[1].toLowerCase();if(parts.length>=3)state.id=parts[2].replace(/[^0-9_]/gim,'');Openrat.Workbench.state=state;$('#editor').attr('data-action',state.action);$('#editor').attr('data-id',state.id);$('#editor').attr('data-extra','{}');Openrat.Navigator.toActualHistory(state)};this.initializePingTimer=function(){let ping=function(){let pingPromise=$.getJSON(Openrat.View.createUrl('profile','ping',0,{},!0));pingPromise.fail(function(){console.warn('The server ping has failed.')})};let timeoutMinutes=5;window.setInterval(ping,timeoutMinutes*60*1000)};this.loadNewActionState=function(t){Openrat.Workbench.state=t;Openrat.Workbench.loadNewAction(t.action,t.id,t.data);this.afterNewActionHandler.fire()};this.afterNewActionHandler=$.Callbacks();this.loadNewAction=function(t,i,e){$('#editor').attr('data-action',t);$('#editor').attr('data-id',i);$('#editor').attr('data-extra',JSON.stringify(e));this.reloadViews()};this.reloadViews=function(){$('#workbench section.closed .view-loader').empty();Openrat.Workbench.loadViews($('#workbench section.open .view-loader'))};this.reloadAll=function(){$('#workbench .view').empty();Openrat.Workbench.loadViews($('#workbench .view.view-loader, #workbench .view.view-static'));this.loadUserStyle();this.loadLanguage();this.loadUISettings()};this.loadUserStyle=function(){let url=Openrat.View.createUrl('profile','userinfo',0,{},!0);$.getJSON(url,function(t){let style=t.output['style'];Openrat.Workbench.setUserStyle(style);let color=t.output['theme-color'];Openrat.Workbench.setThemeColor(color)})};this.settings={};this.language={};this.loadLanguage=function(){let url=Openrat.View.createUrl('profile','language',0,{},!0);$.getJSON(url,function(t){Openrat.Workbench.language=t.output.language})};this.loadUISettings=function(){let url=Openrat.View.createUrl('profile','uisettings',0,{},!0);$.getJSON(url,function(t){Openrat.Workbench.settings=t.output.settings.settings})};this.loadViews=function(t){t.each(function(t){let $targetDOMElement=$(this);Openrat.Workbench.loadNewActionIntoElement($targetDOMElement)})};this.loadNewActionIntoElement=function(t){let action;if(t.is('.view-static'))action=t.attr('data-action');else action=$('#editor').attr('data-action');let id=$('#editor').attr('data-id');let params=$('#editor').attr('data-extra');let method=t.data('method');let view=new Openrat.View(action,method,id,params);view.start(t)};this.setUserStyle=function(t){var i=$('html'),e=i.attr('class').split(/\s+/);$.each(e,function(t,e){if(e.startsWith('theme-')){i.removeClass(e)}});i.addClass('theme-'+t.toLowerCase())};this.setThemeColor=function(t){$('#theme-color').attr('content',t)};let notifyBrowser=function(t){if(!('Notification' in window)){return} else if(Notification.permission==='granted'){let notification=new Notification(t)} -else if(Notification.permission!=='denied'){Notification.requestPermission(function(e){if(e==='granted'){let notification=new Notification(t)}})}};this.notify=function(t,i,e,o,log=[],notifyTheBrowser=!1){if(notifyTheBrowser)notifyBrowser(o);let notice=$('<div class="notice '+e+'"></div>');let toolbar=$('<div class="or-notice-toolbar"></div>');if(log.length)$(toolbar).append('<i class="or-action-full image-icon image-icon--menu-fullscreen"></i>');$(toolbar).append('<i class="or-action-close image-icon image-icon--menu-close"></i>');$(notice).append(toolbar);let id=0;if(i)$(notice).append('<div class="name clickable"><a href="" data-type="open" data-action="'+t+'" data-id="'+id+'"><i class="or-action-full image-icon image-icon--action-'+t+'"></i> '+i+'</a></div>');$(notice).append('<div class="text">'+htmlEntities(o)+'</div>');if(log.length){let logLi=log.reduce((result,item)=>{result+='<li><pre>'+htmlEntities(item)+'</pre></li>';return result},'');$(notice).append('<div class="log"><ul>'+logLi+'</ul></div>')};$('#noticebar').prepend(notice);$(notice).orLinkify();$(notice).find('.or-action-full').click(function(){$(notice).toggleClass('full')});$(notice).find('.or-action-close').click(function(){$(notice).fadeOut('fast',function(){$(notice).remove()})});let timeout=1;if(e=='ok')timeout=20;if(e=='info')timeout=60;if(e=='warning')timeout=120;if(e=='error')timeout=120;if(timeout>0)setTimeout(function(){$(notice).fadeOut('slow',function(){$(this).remove()})},timeout*1000)};this.dataChangedHandler=$.Callbacks();this.dataChangedHandler.add(function(){if(popupWindow!==undefined)popupWindow.location.reload()});this.afterViewLoadedHandler=$.Callbacks();let afterViewFunctions=[];this.registerAfterViewLoaded=function(t){afterViewFunctions.push(t)};this.afterViewLoaded=function(t){afterViewFunctions.forEach(function(e){e(t)})}}; +else if(Notification.permission!=='denied'){Notification.requestPermission(function(i){if(i==='granted'){let notification=new Notification(t)}})}};this.notify=function(t,e,i,n,log=[],notifyTheBrowser=!1){if(notifyTheBrowser)notifyBrowser(n);let notice=$('<div class="notice '+i+'"></div>');let toolbar=$('<div class="or-notice-toolbar"></div>');if(log.length)$(toolbar).append('<i class="or-action-full image-icon image-icon--menu-fullscreen"></i>');$(toolbar).append('<i class="or-action-close image-icon image-icon--menu-close"></i>');$(notice).append(toolbar);let id=0;if(e)$(notice).append('<div class="name clickable"><a href="" data-type="open" data-action="'+t+'" data-id="'+id+'"><i class="or-action-full image-icon image-icon--action-'+t+'"></i> '+e+'</a></div>');$(notice).append('<div class="text">'+htmlEntities(n)+'</div>');if(log.length){let logLi=log.reduce((result,item)=>{result+='<li><pre>'+htmlEntities(item)+'</pre></li>';return result},'');$(notice).append('<div class="log"><ul>'+logLi+'</ul></div>')};$('#noticebar').prepend(notice);$(notice).orLinkify();$(notice).find('.or-action-full').click(function(){$(notice).toggleClass('full')});$(notice).find('.or-action-close').click(function(){$(notice).fadeOut('fast',function(){$(notice).remove()})});let timeout=1;if(i=='ok')timeout=20;if(i=='info')timeout=60;if(i=='warning')timeout=120;if(i=='error')timeout=120;if(timeout>0)setTimeout(function(){$(notice).fadeOut('slow',function(){$(this).remove()})},timeout*1000)};this.dataChangedHandler=$.Callbacks();this.dataChangedHandler.add(function(){if(popupWindow!==undefined)popupWindow.location.reload()});this.afterViewLoadedHandler=$.Callbacks();let afterViewFunctions=[];this.registerAfterViewLoaded=function(t){afterViewFunctions.push(t)};this.afterViewLoaded=function(t){afterViewFunctions.forEach(function(i){i(t)})}}; ;Openrat.Navigator=new function(){'use strict';this.navigateTo=function(t){Openrat.Workbench.loadNewActionState(t)};this.navigateToNew=function(t){this.navigateTo(t);window.history.pushState(t,t.name,this.createShortUrl(t.action,t.id))};this.toActualHistory=function(t){window.history.replaceState(t,t.name,this.createShortUrl(t.action,t.id))};this.createShortUrl=function(t,i){return'./#/'+t+(i?'/'+i:'')}}; -;var OR_THEMES_EXT_DIR='modules/cms-ui/themes/';$(function(){$('html').removeClass('nojs');$('.initial-hidden').removeClass('initial-hidden');function e(){function e(e){$(e).closest('div.panel').fadeOut('fast',function(){$(this).toggleClass('fullscreen').fadeIn('fast')})};$('div.header').dblclick(function(){e(this)})};e();window.onpopstate=function(e){Openrat.Navigator.navigateTo(e.state)};Openrat.Workbench.initialize();Openrat.Workbench.reloadAll();let registerWorkbenchGlobalEvents=function(){$('.keystroke').each(function(){let keystrokeElement=$(this);let keystroke=keystrokeElement.text();if(keystroke.length==0)return;let keyaction=function(){keystrokeElement.click()};$(document).bind('keydown',keystroke,keyaction)});$('section.toggle-open-close .on-click-open-close').click(function(){var t=$(this).closest('section');if(t.hasClass('disabled'))return;var e=t.find('div.view-loader');if(e.children().length==0)Openrat.Workbench.loadNewActionIntoElement(e)})};$('.or-initial-notice').each(function(){Openrat.Workbench.notify('','','info',$(this).text());$(this).remove()});registerWorkbenchGlobalEvents();let closeMenu=function(){$('body').click(function(){$('.toolbar-icon.menu').parents('.or-menu').removeClass('open')})};closeMenu();Openrat.Workbench.afterNewActionHandler.add(function(){let url='./api/?action=tree&subaction=path&id='+Openrat.Workbench.state.id+'&type='+Openrat.Workbench.state.action+'&output=json';$.getJSON(url,function(e){$('nav .or-navtree-node').removeClass('or-navtree-node--selected');let output=e['output'];$.each(output.path,function(e,t){$nav=$('nav .or-navtree-node[data-type='+t.type+'][data-id='+t.id+'].or-navtree-node--is-closed .or-navtree-node-control');$nav.click()});if(output.actual)$('nav .or-navtree-node[data-type='+output.actual.type+'][data-id='+output.actual.id+']').addClass('or-navtree-node--selected');let $breadcrumb=$('.or-breadcrumb').empty();let items=[];$.each(output.path.concat(output.actual),function(e,t){items.push('<li class="or-breadcrumb-item clickable" tabindex="0"><a href="'+Openrat.Navigator.createShortUrl(t.action,t.id)+'" data-type="open" data-action="'+t.action+'" data-id="'+t.id+'"><i class="image-icon image-icon--action-'+t.action+'" />'+t.name+'</a></li>')});$breadcrumb.append(items.join('<li><i class="tree-icon image-icon image-icon--node-closed"></i></li>'));$('.or-breadcrumb .clickable').orLinkify()}).fail(function(e){console.warn(e);console.warn('failed to load path from '+url)}).always(function(){})})});let filterMenus=function(){let action=Openrat.Workbench.state.action;let id=Openrat.Workbench.state.id;$('div.clickable').addClass('active');$('div.clickable.filtered').removeClass('active').addClass('inactive');$('div.clickable.filtered.on-action-'+action).addClass('active').removeClass('inactive');$('div.clickable.filtered a').attr('data-id',id)};$('#title.view').data('afterViewLoaded',function(){filterMenus()});Openrat.Workbench.afterNewActionHandler.add(function(){filterMenus()});Openrat.Workbench.afterViewLoadedHandler.add(function(e){if(typeof popupWindow!='undefined')$(e).find('a[data-type=\'popup\']').each(function(){popupWindow.location.href=$(this).attr('data-url')})});Openrat.Workbench.afterViewLoadedHandler.add(function(e){var t=$(e).closest('section');t.toggleClass('is-empty',$(e).is(':empty'));if(!$(e).is(':empty'))t.slideDown('fast');else t.slideUp('fast');$(e).closest('div.panel').find('div.header div.dropdown div.entry.perview').remove();$(e).find('.toggle-nav-open-close').click(function(){$('nav').toggleClass('open')});$(e).find('.toggle-nav-small').click(function(){$('nav').toggleClass('small')});$(e).find('div.headermenu > a').each(function(e,t){});$(e).find('div.header > a.back').each(function(t,n){$(n).removeClass('button').wrap('<div class="entry perview" />').parent().appendTo($(e).closest('div.panel').find('div.header div.dropdown').first())});$(e).find('div.selector.tree').each(function(){var e=this;$(this).orTree({type:'project',selectable:$(e).attr('data-types').split(','),id:$(e).attr('data-init-folderid'),onSelect:function(t,n,a){var i=$(e).parent();$(i).find('input[type=text]').attr('value',t);$(i).find('input[type=hidden]').attr('value',a)}})});n(e);$(e).find('input').change(function(){$(this).parent('div.view').addClass('dirty')});$(e).find('.or-theme-chooser').change(function(){Openrat.Workbench.setUserStyle(this.value)});function a(e){$(e).find('.toolbar-icon.menu').click(function(e){e.stopPropagation();$(this).parents('.or-menu').toggleClass('open')});$(e).find('.toolbar-icon.menu').mouseover(function(){$(this).parents('.or-menu').find('.toolbar-icon.menu').removeClass('open');$(this).addClass('open')})};function i(e){$(e).find('.search input').orSearch({dropdown:'#title div.search div.dropdown',select:function(e){openNewAction(e.name,e.action,e.id)}})};function o(e){$(e).find('.selector input').orSearch({dropdown:'.dropdown',select:function(t){$(e).find('.or-selector-link-value').val(t.id);$(e).find('.or-selector-link-name').val(t.name).attr('placeholder',t.name)}})};function l(e){$(e).find('.or-navtree-node').orTree()};a(e);i(e);o(e);l(e);function n(e){registerDraggable(e);registerDroppable(e)};n(e)});function registerDraggable(e){$(e).find('.or-draggable').draggable({helper:'clone',opacity:0.7,zIndex:2,distance:10,cursor:'move',revert:'false'})};function registerTreeBranchEvents(e){registerDraggable(e)};function registerDroppable(e){$(e).find('.or-droppable').droppable({accept:'.or-draggable',hoverClass:'or-droppable--hover',activeClass:'or-droppable--active',drop:function(e,t){let dropped=t.draggable;let id=dropped.data('id');let name=dropped.data('name');if(!name)name=id;$(this).find('.or-selector-link-value').val(id);$(this).find('.or-selector-link-name').val(name).attr('placeholder',name)}})};function startDialog(e,t,n,a,i){if(!t)t=$('#editor').attr('data-action');if(!a)a=$('#editor').attr('data-id');let view=new Openrat.View(t,n,a,i);view.before=function(){$('#dialog > .view').html('<div class="header"><img class="icon" title="" src="./themes/default/images/icon/'+n+'.png" />'+e+'</div>');$('#dialog > .view').data('id',a);$('#dialog').removeClass('is-closed').addClass('is-open');let view=this;this.escapeKeyClosingHandler=function(e){if(e.keyCode==27){view.close();$(document).off('keyup')}};$(document).keyup(this.escapeKeyClosingHandler);$('#dialog .filler').click(function(){view.close()})};view.close=function(){if($('div#dialog').hasClass('modal'))return;$('#dialog .view').html('');$('#dialog').removeClass('is-open').addClass('is-closed');$(document).unbind('keyup',this.escapeKeyClosingHandler)};view.start($('div#dialog > .view'))};function setTitle(e){if(e)$('head > title').text(e+' - '+$('head > title').data('default'));else $('head > title').text($('head > title').data('default'))};function openNewAction(e,t,n){$('nav').removeClass('open');setTitle(e);Openrat.Navigator.navigateToNew({'action':t,'id':n})};function insert(e,t,a){var n=document.forms[0].elements[e];n.focus();if(typeof document.selection!='undefined'){var l=document.selection.createRange(),i=l.text;l.text=t+i+a;l=document.selection.createRange();if(i.length==0){l.move('character',-a.length)} +;var OR_THEMES_EXT_DIR='modules/cms-ui/themes/';$(function(){$('html').removeClass('nojs');$('.initial-hidden').removeClass('initial-hidden');function e(){function e(e){$(e).closest('div.panel').fadeOut('fast',function(){$(this).toggleClass('fullscreen').fadeIn('fast')})};$('div.header').dblclick(function(){e(this)})};e();window.onpopstate=function(e){Openrat.Navigator.navigateTo(e.state)};Openrat.Workbench.initialize();Openrat.Workbench.reloadAll();let registerWorkbenchGlobalEvents=function(){$('.keystroke').each(function(){let keystrokeElement=$(this);let keystroke=keystrokeElement.text();if(keystroke.length==0)return;let keyaction=function(){keystrokeElement.click()};$(document).bind('keydown',keystroke,keyaction)});$('section.toggle-open-close .on-click-open-close').click(function(){var t=$(this).closest('section');if(t.hasClass('disabled'))return;var e=t.find('div.view-loader');if(e.children().length==0)Openrat.Workbench.loadNewActionIntoElement(e)})};$('.or-initial-notice').each(function(){Openrat.Workbench.notify('','','info',$(this).text());$(this).remove()});registerWorkbenchGlobalEvents();let closeMenu=function(){$('body').click(function(){$('.toolbar-icon.menu').parents('.or-menu').removeClass('open')})};closeMenu();Openrat.Workbench.afterNewActionHandler.add(function(){let url='./api/?action=tree&subaction=path&id='+Openrat.Workbench.state.id+'&type='+Openrat.Workbench.state.action+'&output=json';$.getJSON(url,function(e){$('nav .or-navtree-node').removeClass('or-navtree-node--selected');let output=e['output'];$.each(output.path,function(e,t){$nav=$('nav .or-navtree-node[data-type='+t.type+'][data-id='+t.id+'].or-navtree-node--is-closed .or-navtree-node-control');$nav.click()});if(output.actual)$('nav .or-navtree-node[data-type='+output.actual.type+'][data-id='+output.actual.id+']').addClass('or-navtree-node--selected');let $breadcrumb=$('.or-breadcrumb').empty();let items=[];$.each(output.path.concat(output.actual),function(e,t){items.push('<li class="or-breadcrumb-item clickable" tabindex="0"><a href="'+Openrat.Navigator.createShortUrl(t.action,t.id)+'" data-type="open" data-action="'+t.action+'" data-id="'+t.id+'"><i class="image-icon image-icon--action-'+t.action+'" />'+t.name+'</a></li>')});$breadcrumb.append(items.join('<li><i class="tree-icon image-icon image-icon--node-closed"></i></li>'));$('.or-breadcrumb .clickable').orLinkify()}).fail(function(e){console.warn(e);console.warn('failed to load path from '+url)}).always(function(){})})});let filterMenus=function(){let action=Openrat.Workbench.state.action;let id=Openrat.Workbench.state.id;$('div.clickable').addClass('active');$('div.clickable.filtered').removeClass('active').addClass('inactive');$('div.clickable.filtered.on-action-'+action).addClass('active').removeClass('inactive');$('div.clickable.filtered a').attr('data-id',id)};$('#title.view').data('afterViewLoaded',function(){filterMenus()});Openrat.Workbench.afterNewActionHandler.add(function(){filterMenus()});Openrat.Workbench.afterViewLoadedHandler.add(function(e){if(typeof popupWindow!='undefined')$(e).find('a[data-type=\'popup\']').each(function(){popupWindow.location.href=$(this).attr('data-url')})});Openrat.Workbench.afterViewLoadedHandler.add(function(e){var t=$(e).closest('section');t.toggleClass('is-empty',$(e).is(':empty'));if(!$(e).is(':empty'))t.slideDown('fast');else t.slideUp('fast');$(e).closest('div.panel').find('div.header div.dropdown div.entry.perview').remove();$(e).find('.toggle-nav-open-close').click(function(){$('nav').toggleClass('open')});$(e).find('.toggle-nav-small').click(function(){$('nav').toggleClass('small')});$(e).find('div.headermenu > a').each(function(e,t){});$(e).find('div.header > a.back').each(function(t,n){$(n).removeClass('button').wrap('<div class="entry perview" />').parent().appendTo($(e).closest('div.panel').find('div.header div.dropdown').first())});$(e).find('div.selector.tree').each(function(){var e=this;$(this).orTree({type:'project',selectable:$(e).attr('data-types').split(','),id:$(e).attr('data-init-folderid'),onSelect:function(t,n,a){var i=$(e).parent();$(i).find('input[type=text]').attr('value',t);$(i).find('input[type=hidden]').attr('value',a)}})});n(e);$(e).find('input,select,textarea').change(function(){$(this).closest('.view').addClass('dirty')});$(e).find('.or-theme-chooser').change(function(){Openrat.Workbench.setUserStyle(this.value)});function a(e){$(e).find('.toolbar-icon.menu').click(function(e){e.stopPropagation();$(this).parents('.or-menu').toggleClass('open')});$(e).find('.toolbar-icon.menu').mouseover(function(){$(this).parents('.or-menu').find('.toolbar-icon.menu').removeClass('open');$(this).addClass('open')})};function i(e){$(e).find('.search input').orSearch({dropdown:'#title div.search div.dropdown',select:function(e){openNewAction(e.name,e.action,e.id)}})};function o(e){$(e).find('.selector input').orSearch({dropdown:'.dropdown',select:function(t){$(e).find('.or-selector-link-value').val(t.id);$(e).find('.or-selector-link-name').val(t.name).attr('placeholder',t.name)}})};function l(e){$(e).find('.or-navtree-node').orTree()};a(e);i(e);o(e);l(e);function n(e){registerDraggable(e);registerDroppable(e)};n(e)});function registerDraggable(e){$(e).find('.or-draggable').draggable({helper:'clone',opacity:0.7,zIndex:2,distance:10,cursor:'move',revert:'false'})};function registerTreeBranchEvents(e){registerDraggable(e)};function registerDroppable(e){$(e).find('.or-droppable').droppable({accept:'.or-draggable',hoverClass:'or-droppable--hover',activeClass:'or-droppable--active',drop:function(e,t){let dropped=t.draggable;let id=dropped.data('id');let name=dropped.data('name');if(!name)name=id;$(this).find('.or-selector-link-value').val(id);$(this).find('.or-selector-link-name').val(name).attr('placeholder',name)}})};function startDialog(e,t,n,a,i){if(!t)t=$('#editor').attr('data-action');if(!a)a=$('#editor').attr('data-id');let view=new Openrat.View(t,n,a,i);view.before=function(){$('#dialog > .view').html('<div class="header"><img class="icon" title="" src="./themes/default/images/icon/'+n+'.png" />'+e+'</div>');$('#dialog > .view').data('id',a);$('#dialog').removeClass('is-closed').addClass('is-open');let view=this;this.escapeKeyClosingHandler=function(e){if(e.keyCode==27){view.close();$(document).off('keyup')}};$(document).keyup(this.escapeKeyClosingHandler);$('#dialog .filler').click(function(){view.close()})};view.close=function(){if($('div#dialog').hasClass('modal'))return;$('#dialog .view').removeClass('dirty');$('#dialog .view').html('');$('#dialog').removeClass('is-open').addClass('is-closed');$(document).unbind('keyup',this.escapeKeyClosingHandler)};view.start($('div#dialog > .view'))};function setTitle(e){if(e)$('head > title').text(e+' - '+$('head > title').data('default'));else $('head > title').text($('head > title').data('default'))};function openNewAction(e,t,n){$('nav').removeClass('open');setTitle(e);Openrat.Navigator.navigateToNew({'action':t,'id':n})};function insert(e,t,a){var n=document.forms[0].elements[e];n.focus();if(typeof document.selection!='undefined'){var l=document.selection.createRange(),i=l.text;l.text=t+i+a;l=document.selection.createRange();if(i.length==0){l.move('character',-a.length)} else{l.moveStart('character',t.length+i.length+a.length)};l.select()} else if(typeof n.selectionStart!='undefined'){var r=n.selectionStart,c=n.selectionEnd,i=n.value.substring(r,c);n.value=n.value.substr(0,r)+t+i+a+n.value.substr(c);var o;if(i.length==0){o=r+t.length} else{o=r+t.length+i.length+a.length};n.selectionStart=o;n.selectionEnd=o} diff --git a/modules/cms/ui/themes/default/script/openrat/common.js b/modules/cms/ui/themes/default/script/openrat/common.js @@ -260,8 +260,8 @@ Openrat.Workbench.afterViewLoadedHandler.add( function(viewEl ) { // Bei Änderungen in der View das Tab als 'dirty' markieren - $(viewEl).find('input').change( function() { - $(this).parent('div.view').addClass('dirty'); + $(viewEl).find('input,select,textarea').change( function() { + $(this).closest('.view').addClass('dirty'); }); // Theme-Auswahl mit Preview @@ -447,6 +447,7 @@ function startDialog( name,action,method,id,params ) if ( $('div#dialog').hasClass('modal') ) return; + $('#dialog .view').removeClass('dirty'); $('#dialog .view').html(''); $('#dialog').removeClass('is-open').addClass('is-closed'); // Dialog schließen diff --git a/modules/cms/ui/themes/default/script/openrat/workbench.js b/modules/cms/ui/themes/default/script/openrat/workbench.js @@ -15,11 +15,33 @@ Openrat.Workbench = new function() // Initialze Ping timer. this.initializePingTimer(); + this.initializeDirtyWarning(); this.initializeState(); this.openModalDialog(); } + this.initializeDirtyWarning = function () { + + // If the application should be closed, inform the user about unsaved changes. + window.addEventListener('beforeunload', function (e) { + + // Are there views in the dirty state? + if ( $('.view.dirty').length > 0 ) { + + e.preventDefault(); // Cancel the event + + // This text is replaced by modern browsers with a common message. + return 'Unsaved content will be lost.'; + } + else { + // Let the browser quitting the page. + // Do NOT logout here, because there could be other windows/tabs with the same session. + return undefined; // nothing to do. + } + }); + } + /** * Starts a dialog, if necessary. */