403Webshell
Server IP : 85.158.181.41  /  Your IP : 216.73.217.12
Web Server : Apache
System : Linux cloud9-vm129 6.1.178+1-ph #ph SMP PREEMPT_DYNAMIC Wed Jul 29 09:00:54 UTC 2026 x86_64
User : moncbefd ( 1024)
PHP Version : 7.3.33
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : ON  |  Sudo : OFF  |  Pkexec : OFF
Directory :  /home/moncbefd/www.moneta.at/StyleEdit3/javascript/controllers/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /home/moncbefd/www.moneta.at/StyleEdit3/javascript/controllers/EditStyleView.js
/* --------------------------------------------------------------
  EditStyleView.js 2019-06-07
  Gambio GmbH
  http://www.gambio.de
  Copyright (c) 2019 Gambio GmbH
  Released under the GNU General Public License (Version 2)
  [http://www.gnu.org/licenses/gpl-2.0.html]
  --------------------------------------------------------------*/


/* globals -Modal */

'use strict';

import JsonParser from '../libs/JsonParser';
import Modal from '../libs/Modal';
import Router from '../libs/Router';
import EventsEmitter from '../libs/EventsEmitter';
import WidgetConverter from '../libs/WidgetConverter';
import StyleApi from '../api/StyleApi';
import CacheApi from '../api/CacheApi';
import FilterBox from '../widgets/FilterBox';

/**
 * Edit Style View Controller
 *
 * This controller is responsible for the style editing view of the page. It will fetch the
 * styles configuration data from the server and display them to the UI.
 */
export default class EditStyleView {
	/**
	 * Class Constructor
	 *
	 * @param {String} styleName The style name to be edited.
	 */
	constructor(styleName) {
		StyleEdit.Validator.isString(styleName);
		
		/**
		 * The name of the loaded style.
		 *
		 * @type {String}
		 */
		this.styleName = styleName;
		
		/**
		 * Style Configuration Entity
		 *
		 * @type {StyleConfiguration}
		 */
		this.styleConfiguration = null;
		
		/**
		 * The original JSON string used for determining changes.
		 *
		 * @type {String}
		 */
		this.originalStyleJson = null;
		
		/**
		 * Contains a list with the template image file names.
		 *
		 * @type {String[]}
		 */
		this.templateImages = null;
	}
	
	/**
	 * Initialize Controller
	 *
	 * @return {jQuery.Promise} Will be resolved once the method is ready.
	 */
	initialize() {
		const deferred = $.Deferred();
		
		StyleApi.get(this.styleName).done(response => {
			// Add the template translations to the Language object. 
			StyleEdit.Language.addSection('template', response.lang);
			
			// Store the template images for future reference. 
			this.templateImages = response.images;
			
			// Parse the JSON data and display the setting widgets.
			this.styleConfiguration = JsonParser.decodeStyleConfiguration(response.config);
			
			// Store the response for future reference (see _onClickBack function).
			this.originalStyleJson = JsonParser.encodeStyleConfiguration(this.styleConfiguration);
			
			this._loadViewTemplate();
			
			EventsEmitter.triggerControllerInitialized($('.style-edit-view'), ['EditStyleView']);
			
			deferred.resolve();
		});
		
		return deferred.promise();
	}
	
	/**
	 * Destroy Controller
	 *
	 * @return {jQuery.Promise} Will be resolved once the method is ready.
	 */
	destroy() {
		const deferred = $.Deferred();
		const $styleEditView = $('.style-edit-view');
		
		$('.edit-options-container').perfectScrollbar('destroy');
		
		$styleEditView.fadeOut(300, () => {
			$styleEditView.html(''); // Remove the HTML code.
			deferred.resolve();
			EventsEmitter.triggerControllerDestroyed($styleEditView, ['EditStyleView']);
		});
		
		$('.edit-style-view, .edit-options-container .option').off();
		
		$(window)
			.off('resize')
			.off('beforeunload')
			.off('StyleEdit.CustomStylesChanged');
		
		return deferred.promise();
	}
	
	/**
	 * Event: Save Button Click
	 *
	 * Save the current style configuration settings and display a success notification.
	 *
	 * @private
	 */
	_onClickSave() {
		StyleApi.save(this.styleConfiguration).done(() => {
			// Display dialog with success message.
			const title = StyleEdit.Language.translate('title_style_saved_successfully', 'style_edit');
			const message = StyleEdit.Language.translate('message_style_saved_successfully', 'style_edit');
			let interval;
			
			Modal.message(title, message).done(() => {
				clearInterval(interval);
			});
			
			// The modal will close automatically in 3 seconds. 
			const $modal = $('.style-edit-modal:visible');
			const buttonText = $modal.find('.btn.ok').text();
			let secondsLeft = 3;
			
			$modal.find('.btn.ok').text(buttonText + ' (' + secondsLeft + ')');
			
			interval = setInterval(() => {
				secondsLeft--;
				
				if (secondsLeft === 0) {
					$modal.find('.btn.ok').click();
					return;
				}
				
				$modal.find('.btn.ok').text(buttonText + ' (' + secondsLeft + ')');
			}, 1000);
			
			// Save a copy of the current style for later use.
			this.originalStyleJson = JsonParser.encodeStyleConfiguration(this.styleConfiguration);
			
			// We need to clear the cache of the saved style. This can only be done by making a GET request to the 
			// "gm_dynamic.css.php" with the "renew_cache" parameter. Once the request is done the iframe preview 
			// needs to be reloaded.
			const mainCssUrl = StyleEdit.Config.get('previewUrl') + '/'
				+ $('#main-css', $('.style-edit-preview iframe').contents()).attr('href');
			
			CacheApi.renew(mainCssUrl, this.styleConfiguration.getName()).done(() => {
				this._reloadTemplatePreview(this.styleConfiguration.getName());
			});
			
			// If the current style is active, refresh its cache through another GET request. 
			if (this.styleConfiguration.isActive()) {
				CacheApi.renew(mainCssUrl);
			}
		});
	}
	
	/**
	 * Event: Preview Button Click
	 *
	 * This callback must refresh the template preview based on the current settings.
	 *
	 * @private
	 */
	_onClickPreview() {
		StyleApi.save(this.styleConfiguration, StyleEdit.Config.get('tempStyleName')).done(() => {
			const mainCssUrl = StyleEdit.Config.get('previewUrl') + '/'
				+ $('#main-css', $('.style-edit-preview iframe').contents()).attr('href');
			CacheApi.renew(mainCssUrl, StyleEdit.Config.get('tempStyleName')).done(() => {
				this._reloadTemplatePreview(StyleEdit.Config.get('tempStyleName'));
			});
		});
	}
	
	/**
	 * Event: Back Button Click
	 *
	 * This method must return the StyleEdit back to the styles list view. It must display a warning
	 * if the user has unsaved changes.
	 *
	 * @private
	 */
	_onClickBack() {
		this._validateUnsavedChanges().done(() => this._goBackToMyStylesView());
	}
	
	/**
	 * Event: Add Custom CSS Click
	 *
	 * This callback must display the custom styles modal where the user is able to write
	 * his own CSS or SASS to be included in the template styling.
	 *
	 * @private
	 */
	_onClickAddCustomCss() {
		Router.load('CustomStylesModal', [this.styleConfiguration.getCustomStyles()]);
	}
	
	/**
	 * Event: Activate Button Click
	 *
	 * This button must activate the current style.
	 *
	 * @param {jQuery.Event} event
	 *
	 * @private
	 */
	_onClickActivate(event) {
		const $element = $(event.currentTarget);
		
		StyleApi.activate(this.styleName).done(() => {
			const html = `<span class="status">${StyleEdit.Language.translate('label_active', 'style_edit')}</span>`;
			$('.edit-style-view .headline .date-status').append(html);
			$element
				.add($element.siblings('.action.delete'))
				.remove();
		});
	}
	
	/**
	 * Event: Delete Button Click
	 *
	 * Delete the current style. This callback must display a modal prompt to the user before
	 * removing the style.
	 *
	 * @private
	 */
	_onClickDelete() {
		const title = StyleEdit.Language.translate('title_delete_style_modal', 'style_edit');
		const message = StyleEdit.Language.translate('message_delete_style_modal', 'style_edit');
		
		Modal.prompt(title, message).done(() => {
			StyleApi.delete(this.styleName).done(response => {
				EventsEmitter.triggerStyleDeleted($('.edit-style-view'), [response]);
				this.destroy().done(() => Router.load('MyStylesView'));
			});
		});
	}
	
	/**
	 * Event: Option Group Bar Click
	 *
	 * @param {jQuery.Event} event
	 *
	 * @private
	 */
	_onClickOptionGroupBar(event) {
		$(event.currentTarget).parent().toggleClass('open');
		$('.edit-options-container').perfectScrollbar('update');
	}
	
	/**
	 * Event: Window Resize
	 *
	 * @private
	 */
	_onWindowResize() {
		this._resizeOptionsContainer();
	}
	
	/**
	 * Event: On Window Before Unload
	 *
	 * Check if there are unsaved changes.
	 *
	 * @param {jQuery.Event} event
	 *
	 * @private
	 */
	_onWindowBeforeUnload(event) {
		const currentStyleJson = JsonParser.encodeStyleConfiguration(this.styleConfiguration);
		
		if (currentStyleJson !== this.originalStyleJson) {
			const message = StyleEdit.Language.translate('message_unsaved_changes', 'style_edit');
			event.returnValue = message;
			return message;
		}
	}
	
	/**
	 * Event: Re-order the box settings.
	 *
	 * This method will update the position of the box settings.
	 *
	 * @param {jQuery.Event} event
	 * 
	 * @private
	 */
	_onUpdateBoxPositions(event) {
		$(event.currentTarget).find('.form-group').each((index, formGroup) => {
			const $element = $(formGroup);
			
			$.each(this.styleConfiguration.getSettings(), (index, collection) => {
				if (collection.getType() === 'boxes') {
					$.each(collection.getEntries(), (index, boxSetting) => {
						if (boxSetting.getName() === $element.find('input:checkbox').attr('id')) {
							boxSetting.setPosition($element.index() + 1);
						}
					});
				}
			});
		});
	}
	
	/**
	 * Event: Custom Styles Changed
	 *
	 * @param {jQuery.Event} event
	 * @param {String} customStyles Contains the new custom CSS.
	 *
	 * @private
	 */
	_onCustomStylesChanged(event, customStyles) {
		StyleEdit.Validator.isString(customStyles);
		this.styleConfiguration.setCustomStyles(customStyles);
	}
	
	/**
	 * Navigates back to MyStylesView controller.
	 *
	 * @private
	 */
	_goBackToMyStylesView() {
		this.destroy().done(() => Router.load('MyStylesView', [this.styleName]));
	}
	
	/**
	 * Reload the template preview.
	 *
	 * @param {String} styleName Style name will be provided as a GET parameter to the shop.
	 *
	 * @private
	 */
	_reloadTemplatePreview(styleName) {
		StyleEdit.Validator.isString(styleName);
		
		let url = $('.style-edit-preview iframe').get(0).contentWindow.location.href;
		const parameter = 'style_edit_style_name=' + encodeURIComponent(styleName);
		
		if (url.indexOf('style_edit_style_name=') > -1) {
			url = url.replace(/style_edit_style_name=.*/g, parameter);
		} else if (url.indexOf('?') === -1) {
			url += '?' + parameter;
		} else {
			url += '&' + parameter;
		}
		
		$('.style-edit-preview iframe').get(0).contentWindow.location.href = url;
		
		EventsEmitter.triggerPreviewReloaded($('.edit-style-view'), [styleName]);
	}
	
	/**
	 * Bind event handlers for the settings view.
	 *
	 * @private
	 */
	_bindEventHandlers() {
		$('.edit-style-view')
			.off('click')
			.on('click', '.btn.save', () => this._onClickSave())
			.on('click', '.btn.preview', () => this._onClickPreview())
			.on('click', '.btn.back', () => this._onClickBack())
			.on('click', '.action.activate', event => this._onClickActivate(event))
			.on('click', '.action.delete', () => this._onClickDelete())
			.on('click', '.action.add-custom-css', () => this._onClickAddCustomCss())
			.on('sortupdate', '.dropdown-menu.ui-sortable', event => this._onUpdateBoxPositions(event));
		
		$('.edit-options-container .option')
			.off('click')
			.on('click', '.icon, .info, .dropdown-icon', event => this._onClickOptionGroupBar(event));
		
		$(window)
			.on('resize', () => this._onWindowResize())
			.on('beforeunload', event => this._onWindowBeforeUnload(event))
			.on('StyleEdit.CustomStylesChanged', (event, customStyles) => this._onCustomStylesChanged(event, customStyles));
	}
	
	/**
	 * Resize Options Container
	 *
	 * @private
	 */
	_resizeOptionsContainer() {
		const editOptionsContainerHeight = window.innerHeight
			- $('.style-edit-headline').outerHeight()
			- $('.edit-style-view .headline').outerHeight()
			- $('.edit-style-view .footer-container').outerHeight();
		$('.edit-options-container').height(editOptionsContainerHeight);
	}
	
	/**
	 * Set Local Storage Color Palette
	 *
	 * The colorpicker widgets share their palette through the "style_edit_color_palette" item in the
	 * browser's local storage.
	 *
	 * @param {String} colorPalette Contains the colors to be written in local storage.
	 *
	 * @private
	 */
	_setLocalStorageColorPalette(colorPalette) {
		StyleEdit.Validator.isObject(colorPalette);
		
		if (window.localStorage === undefined) {
			StyleEdit.Debug.warn('Local storage is not supported, no color palette will be set.');
			return; // local storage is not supported
		}
		
		const storageKey = StyleEdit.Config.get('localStorageColorPalette');
		localStorage.removeItem(storageKey);
		localStorage.setItem(storageKey, ';' + colorPalette.join(';'));
	}
	
	/**
	 * Validated whether there are unsaved changes.
	 *
	 * Use this method before leaving the EditStyleView to validate whether there are unsaved changes.
	 *
	 * @return {jQuery.Promise} Returns a promise that will be resolved if the user really wants to leave the page.
	 *
	 * @private
	 */
	_validateUnsavedChanges() {
		// Workaround for quickly checking if there are any changes is to encode the "styleConfiguration" 
		// and the "originalStyleJson".
		const currentStyleJson = JsonParser.encodeStyleConfiguration(this.styleConfiguration);
		let promise;
		
		if (currentStyleJson !== this.originalStyleJson) {
			const title = StyleEdit.Language.translate('title_unsaved_changes', 'style_edit');
			const message = StyleEdit.Language.translate('message_unsaved_changes', 'style_edit');
			promise = Modal.prompt(title, message);
		} else {
			promise = $.Deferred().resolve(); // Nothing was changed.
		}
		
		return promise;
	}
	
	/**
	 * Load the settings template view.
	 *
	 * This method will create the correct HTML for the style settings by using the
	 * StyleConfiguration object.
	 *
	 * @private
	 */
	_loadViewTemplate() {
		if (this.styleConfiguration === null) {
			throw new Error('The controller was not initialized properly! There is no style configuration set.');
		}
		
		const template = $('#edit-style-view-template').html();
		const data = JsonParser.encodeStyleConfiguration(this.styleConfiguration, false);
		let newEntriesArray;
		const widgetInstances = [];
		const colorPalette = [];
		const dateFormat = StyleEdit.Config.get('languageCode') === 'de' ? 'dd.MM.yyyy' : 'MM.dd.yyyy'; 
		
		// Add translations and other labels. 
		data.label_active = StyleEdit.Language.translate('label_active', 'style_edit');
		data.option_add_custom_css = StyleEdit.Language.translate('option_add_custom_css', 'style_edit');
		data.option_activate = StyleEdit.Language.translate('option_activate', 'style_edit');
		data.option_delete = StyleEdit.Language.translate('option_delete', 'style_edit');
		data.modificationDate = Date.parse(data.modificationDate).toString(dateFormat);
		data.option_save = StyleEdit.Language.translate('option_save', 'style_edit');
		data.option_preview = StyleEdit.Language.translate('option_preview', 'style_edit');
		data.option_back = StyleEdit.Language.translate('option_back', 'style_edit');
		
		$.each(data.settings, (index, collection) => {
			collection.title = StyleEdit.Language.translate(collection.name, 'template');
			newEntriesArray = []; // reset array
			
			if (collection.type === 'boxes') {
				collection.entries.sort((a, b) => {
					if (a.position < b.position) {
						return -1;
					} else if (a.position > b.position) {
						return 1;
					}
					return 0;
				});
			}
			
			$.each(collection.entries, (index, entry) => {
				// Check if the setting is a color and if it belongs in the color palette.
				if (data.colorPalette) {
					$.each(data.colorPalette, (index, variableName) => {
						if (variableName === entry.name && entry.type === 'color') {
							colorPalette.push(entry.value);
						}
					});
				}
				
				// Create the setting instance.
				try {
					const widgetInstance = WidgetConverter.convertSettingToWidget(entry, this.styleConfiguration,
						this.templateImages);
					// Push the instances to their respective arrays.
					newEntriesArray.push(widgetInstance);
					widgetInstances.push(widgetInstance);
				} catch (exception) {
					StyleEdit.Debug.error('StyleEdit Error: ', exception);
					return true; // continue
				}
			});
			
			collection.entries = newEntriesArray;
		});
		
		// Render the template and bind the event handlers.
		$('.style-edit-view').html(Mustache.render(template, data)).fadeIn();
		this._bindEventHandlers();
		
		// Initialize the widgets 
		$.each(widgetInstances, (index, widget) => {
			widget.initialize(); // will bind the event handlers 
		});
		
		// Set the local storage color palette so that wall the colorpickers share the same palette.
		this._setLocalStorageColorPalette(colorPalette);
		
		// Add material design effects to new objects. 
		$.material.init();
		
		// Add sortable functionality to boxes. 
		$('.style-edit-view .form-group .fa-bars')
			.parents('.dropdown-menu')
			.sortable({
				axis: 'y',
				opacity: 0.5,
				containment: 'parent'
			});
		
		// Add scrollbars.
		this._resizeOptionsContainer();
		$('.edit-options-container').perfectScrollbar();
		
		// Initialize the filter box widget. 
		this.filterBox = new FilterBox($('.filter-box-wrapper'), $('.edit-options'), $('.edit-options-container'), 
			this.styleConfiguration);
		this.filterBox.initialize();
	}
}

Youez - 2016 - github.com/yon3zu
LinuXploit