/*##################################################|*/ /* #CMS# */ (function($) { // CMS.$ will be passed for $ $(document).ready(function () { /*! * Toolbar * Handles all features related to the toolbar */ CMS.Toolbar = new CMS.Class({ implement: [CMS.API.Helpers], options: { 'preventSwitch': false, 'preventSwitchMessage': 'Switching is disabled.', 'messageDelay': 2000 }, initialize: function (options) { this.container = $('#cms_toolbar'); this.options = $.extend(true, {}, this.options, options); this.config = CMS.config; this.settings = CMS.settings; // elements this.body = $('html'); this.toolbar = this.container.find('.cms_toolbar').hide(); this.toolbarTrigger = this.container.find('.cms_toolbar-trigger'); this.navigations = this.container.find('.cms_toolbar-item-navigation'); this.buttons = this.container.find('.cms_toolbar-item-buttons'); this.switcher = this.container.find('.cms_toolbar-item_switch'); this.messages = this.container.find('.cms_messages'); this.screenBlock = this.container.find('.cms_screenblock'); // states this.click = 'click.cms'; this.timer = function () {}; this.lockToolbar = false; // setup initial stuff this._setup(); // setup events this._events(); }, // initial methods _setup: function () { // setup toolbar visibility, we need to reverse the options to set the correct state (this.settings.toolbar === 'expanded') ? this._showToolbar(0, true) : this._hideToolbar(0, true); // hide publish button var publishBtn = $('.cms_btn-publish').parent(); publishBtn.hide(); if($('.cms_btn-publish-active').length) publishBtn.show(); // check if debug is true if(CMS.config.debug) this._debug(); // check if there are messages and display them if(CMS.config.messages) this.openMessage(CMS.config.messages); // check if there are error messages and display them if(CMS.config.error) this.showError(CMS.config.error); // enforce open state if user is not logged in but requests the toolbar if(!CMS.config.auth || CMS.config.settings.version !== this.settings.version) { this.toggleToolbar(true); this.settings = this.setSettings(CMS.config.settings); } // should switcher indicate that there is an unpublished page? if(CMS.config.publisher) { this.openMessage(CMS.config.publisher, 'right'); setInterval(function () { CMS.$('.cms_toolbar-item_switch').toggleClass('cms_toolbar-item_switch-highlight'); }, this.options.messageDelay); } // open sideframe if it was previously opened if(this.settings.sideframe.url) { var sideframe = new CMS.Sideframe(); sideframe.open(this.settings.sideframe.url, false); } // if there is a screenblock, do some resize magic if(this.screenBlock.length) this._screenBlock(); // add toolbar ready class to body and fire event this.body.addClass('cms-ready'); $(document).trigger('cms-ready'); }, _events: function () { var that = this; // attach event to the trigger handler this.toolbarTrigger.bind(this.click, function (e) { e.preventDefault(); that.toggleToolbar(); }); // attach event to the navigation elements this.navigations.each(function () { var item = $(this); var lists = item.find('li'); var root = 'cms_toolbar-item-navigation'; var hover = 'cms_toolbar-item-navigation-hover'; var disabled = 'cms_toolbar-item-navigation-disabled'; var children = 'cms_toolbar-item-navigation-children'; // remove events from first level item.find('a').bind(that.click, function (e) { e.preventDefault(); if($(this).attr('href') !== '' && $(this).attr('href') !== '#' && !$(this).parent().hasClass(disabled) && !$(this).parent().hasClass(disabled)) { that._delegate($(this)); reset(); return false; } }); // handle click states lists.bind(that.click, function (e) { e.stopPropagation(); var el = $(this); // close if el is first item if(el.parent().hasClass(root) && el.hasClass(hover) || el.hasClass(disabled)) { reset(); return false; } else { reset(); el.addClass(hover); } // activate hover selection item.find('> li').bind('mouseenter', function () { // cancel if item is already active if($(this).hasClass(hover)) return false; $(this).trigger(that.click); }); // create the document event $(document).bind(that.click, reset); }); // attach hover lists.find('li').bind('mouseenter mouseleave', function () { var el = $(this); var parent = el.closest('.cms_toolbar-item-navigation-children').add(el.parents('.cms_toolbar-item-navigation-children')); var hasChildren = el.hasClass(children) || parent.length; // do not attach hover effect if disabled // cancel event if element has already hover class if(el.hasClass(disabled) || el.hasClass(hover)) return false; // reset lists.find('li').removeClass(hover); // add hover effect el.addClass(hover); // handle children elements if(hasChildren) { el.find('> ul').show(); // add parent class parent.addClass(hover); } else { lists.find('ul ul').hide(); } // Remove stale submenus el.siblings().find('> ul').hide(); }); // fix leave event lists.find('> ul').bind('mouseleave', function () { lists.find('li').removeClass(hover); }); // removes classes and events function reset() { lists.removeClass(hover); lists.find('ul ul').hide(); item.find('> li').unbind('mouseenter'); $(document).unbind(that.click); } }); // attach event to the switcher elements this.switcher.each(function () { $(this).bind(that.click, function (e) { e.preventDefault(); that._setSwitcher($(e.currentTarget)); }); }); // attach event for first page publish this.buttons.each(function () { var btn = $(this); // in case the button has a data-rel attribute if(btn.find('a').attr('data-rel')) { btn.on('click', function (e) { e.preventDefault(); that._delegate($(this).find('a')); }) } // in case of the publish button btn.find('.cms_publish-page').bind(that.click, function (e) { if(!confirm(that.config.lang.publish)) e.preventDefault(); }); }); }, // public methods toggleToolbar: function (show) { // overwrite state when provided if(show) this.settings.toolbar = 'collapsed'; // toggle bar (this.settings.toolbar === 'collapsed') ? this._showToolbar(200) : this._hideToolbar(200); }, openMessage: function (msg, dir, delay, error) { // set toolbar freeze this._lock(true); // add content to element this.messages.find('.cms_messages-inner').html(msg); // clear timeout clearTimeout(this.timer); // determine width var that = this; var width = 320; var height = this.messages.outerHeight(true); var top = this.toolbar.outerHeight(true); var close = this.messages.find('.cms_messages-close'); close.hide(); close.bind(this.click, function () { that.closeMessage(); }); // set top to 0 if toolbar is collapsed if(this.settings.toolbar === 'collapsed') top = 0; // do we need to add debug styles? if(this.config.debug) top = top + 5; // set correct position and show this.messages.css('top', -height).show(); // error handling this.messages.removeClass('cms_messages-error'); if(error) this.messages.addClass('cms_messages-error'); // dir should be left, center, right dir = dir || 'center'; // set correct direction and animation switch(dir) { case 'left': this.messages.css({ 'top': top, 'left': -width, 'right': 'auto', 'margin-left': 0 }); this.messages.animate({ 'left': 0 }); break; case 'right': this.messages.css({ 'top': top, 'right': -width, 'left': 'auto', 'margin-left': 0 }); this.messages.animate({ 'right': 0 }); break; default: this.messages.css({ 'left': '50%', 'right': 'auto', 'margin-left': -(width / 2) }); this.messages.animate({ 'top': top }); } // cancel autohide if delay is 0 if(delay === 0) { close.show(); return false } // add delay to hide this.timer = setTimeout(function () { that.closeMessage(); }, delay || this.options.messageDelay); }, closeMessage: function () { this.messages.fadeOut(300); // unlock toolbar this._lock(false); }, openAjax: function (url, post, text, callback, onSuccess) { var that = this; // check if we have a confirmation text var question = (text) ? confirm(text) : true; // cancel if question has been denied if(!question) return false; // set loader this._loader(true); $.ajax({ 'type': 'POST', 'url': url, 'data': (post) ? JSON.parse(post) : {}, 'success': function (response) { CMS.API.locked = false; if(callback) { callback(that, response); that._loader(false); } else if(onSuccess) { CMS.API.Helpers.reloadBrowser(onSuccess, false, true); } else { // reload CMS.API.Helpers.reloadBrowser(false, false, true); } }, 'error': function (jqXHR) { CMS.API.locked = false; that.showError(jqXHR.response + ' | ' + jqXHR.status + ' ' + jqXHR.statusText); } }); }, showError: function (msg, reload) { this.openMessage(msg, 'center', 0, true); // force reload if param is passed if(reload) CMS.API.Helpers.reloadBrowser(false, this.options.messageDelay); }, // private methods _showToolbar: function (speed, init) { this.toolbarTrigger.addClass('cms_toolbar-trigger-expanded'); this.toolbar.slideDown(speed); // animate html this.body.animate({ 'margin-top': (this.config.debug) ? 35 : 30 }, (init) ? 0 : speed, function () { $(this).addClass('cms-toolbar-expanded') }); // set messages top to toolbar height this.messages.css('top', 31); // set new settings this.settings.toolbar = 'expanded'; if(!init) this.settings = this.setSettings(this.settings); }, _hideToolbar: function (speed, init) { // cancel if sideframe is active if(this.lockToolbar) return false; this.toolbarTrigger.removeClass('cms_toolbar-trigger-expanded'); this.toolbar.slideUp(speed); // animate html this.body.removeClass('cms-toolbar-expanded').animate({ 'margin-top': (this.config.debug) ? 5 : 0 }, speed); // set messages top to 0 this.messages.css('top', 0); // set new settings this.settings.toolbar = 'collapsed'; if(!init) this.settings = this.setSettings(this.settings); }, _setSwitcher: function (el) { // save local vars var active = el.hasClass('cms_toolbar-item_switch-active'); var anchor = el.find('a'); var knob = el.find('.cms_toolbar-item_switch-knob'); var duration = 300; // prevent if switchopstion is passed if(this.options.preventSwitch) { this.openMessage(this.options.preventSwitchMessage, 'right'); return false; } // determin what to trigger if(active) { knob.animate({ 'right': anchor.outerWidth(true) - (knob.outerWidth(true) + 2) }, duration); // move anchor behind the knob anchor.css('z-index', 1).animate({ 'padding-top': 6, 'padding-right': 14, 'padding-bottom': 4, 'padding-left': 28 }, duration); } else { knob.animate({ 'left': anchor.outerWidth(true) - (knob.outerWidth(true) + 2) }, duration); // move anchor behind the knob anchor.css('z-index', 1).animate({ 'padding-top': 6, 'padding-right': 28, 'padding-bottom': 4, 'padding-left': 14 }, duration); } // reload setTimeout(function () { window.location.href = anchor.attr('href'); }, duration); }, _delegate: function (el) { // save local vars var target = el.data('rel'); switch(target) { case 'modal': var modal = new CMS.Modal({'onClose': el.data('on-close')}); modal.open(el.attr('href'), el.data('name')); break; case 'message': this.openMessage(el.data('text')); break; case 'sideframe': var sideframe = new CMS.Sideframe({'onClose': el.data('on-close')}); sideframe.open(el.attr('href'), true); break; case 'ajax': this.openAjax(el.attr('href'), JSON.stringify(el.data('post')), el.data('text'), null, el.data('on-success')); break; default: window.location.href = el.attr('href'); } }, _lock: function (lock) { if(lock) { this.lockToolbar = true; // make button look disabled this.toolbarTrigger.css('opacity', 0.2); } else { this.lockToolbar = false; // make button look disabled this.toolbarTrigger.css('opacity', 1); } }, _loader: function (loader) { if(loader) { this.toolbarTrigger.addClass('cms_toolbar-loader'); } else { this.toolbarTrigger.removeClass('cms_toolbar-loader'); } }, _debug: function () { var that = this; var timeout = 1000; var timer = function () {}; // bind message event var debug = this.container.find('.cms_debug-bar'); debug.bind('mouseenter mouseleave', function (e) { clearTimeout(timer); if(e.type === 'mouseenter') { timer = setTimeout(function () { that.openMessage(that.config.lang.debug); }, timeout); } }); }, _screenBlock: function () { var interval = 20; var blocker = this.screenBlock; var sideframe = $('.cms_sideframe'); // automatically resize screenblock window according to given attributes $(window).on('resize.cms.screenblock', function () { var width = $(this).width() - sideframe.width(); blocker.css({ 'width': width, 'height': $(window).height() }); }).trigger('resize'); // set update interval setInterval(function () { $(window).trigger('resize.cms.screenblock'); }, interval); } }); }); })(CMS.$);