/** * Htaccess editor manager, manage adding directives, correct paths, local and * session storage for htaccess restoring * * @package JMAP::HTACCESS::administrator::components::com_jmap * @subpackage js * @author Joomla! Extensions Store * @copyright (C) 2015 Joomla! Extensions Store * @license GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html */ //'use strict'; (function($) { var Htaccess = function() { /** * Store locally the original htaccess contents to restore it later * * @access private * @var String */ var originalHtaccess = null; /** * Store the session versioning of htaccess to serve the UNDO/REDO function * * @access private * @var Array */ var versioningHtaccess = new Array(); /** * Validation snippet * * @access private * @var Object */ var validationSnippet = '<ul class="errorlist"><li class="validation label label-danger">' + COM_JMAP_HTACCESS_REQUIRED + '</li></ul>'; /** * Directive adding message snippet * * @access private * @var Object */ var messageSnippet = '<div class="htaccess_messages alert alert-success">' + '<h4 class="alert-heading">Message</h4>' + '<p>' + COM_JMAP_HTACCESS_DIRECTIVE_ADDED + '</p>' + '</div>'; /** * Directive dropdown jQobject * * @access private * @var Object */ var directiveDropdown = $('#htaccess_directive'); /** * Validate inputs required based on directive type * * @access private * @return Boolean */ var validateInputs = function() { for(var i=0; i < arguments.length; i++) { var values = arguments[i]; if(!values) { $('ul.errorlist').remove(); $('div.paths').append(validationSnippet); $('div.paths input').filter(function() { return !this.value; }).addClass('error'); return false; } } return true; }; /** * Logic for the directive adder, based on the type of directive the * path is safely corrected and appended to the htaccess * * @access private * @return Void */ var addHtaccessDirective = function() { // Retrieve the type of directive to add var directive = parseInt($('option:selected', directiveDropdown).data('directive')); var directiveType = $('option:selected', directiveDropdown).data('type'); var directiveName = null; // Populate the array of values var directiveValues = new Array(); switch (directive) { case 404: var path1 = $('#path1').val(); // Validating values if(!validateInputs(path1)) { return; } directiveValues.push(path1); directiveName = 'Redirect 404 '; break; case 301: // Retrieve values var path1 = $('#path1').val(); var path2 = $('#path2').val(); // Validating values if(!validateInputs(path1, path2)) { return; } directiveValues.push(path1); directiveValues.push(path2); directiveName = 'Redirect 301 '; break; } // Act accordingly var endSlash = ''; if(directiveType == 'folder') { endSlash = '/'; } $.each(directiveValues, function(index, value){ // Sanitize values as folder directive, trailing and ending slashes directiveValues[index] = '/' + value.characterTrim('/', '\\') + endSlash; }); // Everything is in place, now append the directive and show success message // Append text to the text area $('#htaccess_contents').val(function(_, val){ return val + '\n' + directiveName + directiveValues.join(' '); }); // Scroll to bottom the textarea $("#htaccess_contents").scrollTop($("#htaccess_contents")[0].scrollHeight); // Reset value $('div.paths input').val(''); // Show user message $('#system-message-container').html(messageSnippet); setTimeout(function(){ $('.htaccess_messages').fadeOut(500, function(){ $(this).remove(); }); },1000); }; /** * Function dummy constructor * * @access private * @param String * contextSelector * @method <<IIFE>> * @return Void */ (function __construct() { // Popover trigger $('label.hasHtaccessPopover').popover({trigger:'hover', placement:'bottom', html:1}); // Extend String Object prototype String.prototype.characterTrim = function(character, escape) { var trimRegexp = new RegExp('^' + escape + character + '+', 'i'); return this.replace(trimRegexp, ""); } // Bind the main save event $('#htaccess_save').on('click', function(){ // Store the current history version of the htaccess var currentHtaccess = $('#htaccess_contents').val(); versioningHtaccess.push(currentHtaccess); // Now serialize in the sessionStorage sessionStorage.setItem('htaccess_history', JSON.stringify(versioningHtaccess)); }); // Manage dropdown directiveDropdown.on('change', function(jqEvent) { // Hide/Show fields and change label caption based on the // directive type var directive = $('option:selected', this).data('directive'); // Single field input if (directive == '404') { $('*[data-role=extended]').hide(); $('label[data-role=basic]').text(COM_JMAP_HTACCESS_PATH); } else { // Redirect with double fields $('*[data-role=extended]').show(); $('label[data-role=basic]').text(COM_JMAP_HTACCESS_OLD_PATH); } // By default reset always validation $('div.paths input.error').removeClass('error'); $('div.paths ul.errorlist').remove(); }); // Directive adder event $('#htaccess_adder').on('click', { bind : this }, function(jqEvent) { jqEvent.preventDefault(); addHtaccessDirective.call(jqEvent.data.bind); }); // Step before, restore the previous history version of the htaccess $('#htaccess_prev_versioning').on('click', function(jqEvent){ if( window.sessionStorage !== null ) { // Discard the latest versioning, equal to the current file version if(versioningHtaccess.length) { versioningHtaccess.pop(); // Reassign/Refresh the session storage history array of versioning sessionStorage.setItem('htaccess_history', JSON.stringify(versioningHtaccess)); } var previousVersion = versioningHtaccess.pop(); // If not null restore the original version if(previousVersion) { $('#htaccess_contents').val(previousVersion); $('input[name=restored]').val(1); $('#htaccess_save').trigger('click'); } else { // We reached the bottom of the stack AKA the stack is empty, restore the original version $('#htaccess_restore').trigger('click'); } } }); // Restoration of the original session htaccess file $('#htaccess_restore').on('click', function(jqEvent){ if( window.sessionStorage !== null ) { originalHtaccess = sessionStorage.getItem('htaccess'); // If not null restore the original version if(originalHtaccess) { $('#htaccess_contents').val(originalHtaccess); $('input[name=restored]').val(1); $('#htaccess_save').trigger('click'); } // Reset the history sessionStorage.removeItem('htaccess_history'); } }); // Activation of the .htaccess file $('#htaccess_activate').on('click', function(jqEvent){ $('input[name=task]').val('htaccess.activateEntity'); $('#adminForm').submit(); }); // Bind validation reset $('div.paths input').on('keyup', function(jqEvent){ $(this).removeClass('error'); // Everything correct? if(!$('div.paths input').hasClass('error')) { $('div.paths ul.errorlist').remove(); } }); // Store the sessionStorage value of the original htaccess file before editing if( window.sessionStorage !== null ) { // Grab the current value of the htaccess textarea file, initialize it only if not available if(!sessionStorage.getItem('htaccess')) { originalHtaccess = $('#htaccess_contents').val(); sessionStorage.setItem('htaccess', originalHtaccess); } // Initialize the versioning counter if(sessionStorage.getItem('htaccess_history')) { versioningHtaccess = JSON.parse(sessionStorage.getItem('htaccess_history')); // Is there some history versions? if(!versioningHtaccess.length) { $('#htaccess_prev_versioning').attr('disabled', 'disabled'); } // Counter databind $('*[data-bind=versions_counter]').text(versioningHtaccess.length); } else { $('#htaccess_prev_versioning').attr('disabled', 'disabled'); } } // Scroll to bottom the textarea $("#htaccess_contents").scrollTop($("#htaccess_contents")[0].scrollHeight); $('#fancy_closer').on('click', function(){ parent.jQuery.fancybox.close(); return false; }); // Add desc popover $('label.hasrightPopover').popover({trigger:'hover', placement:'bottom', html:1}); }).call(this); } // On DOM Ready $(function() { window.JMapHtaccess = new Htaccess(); }); })(jQuery);