/* * ====================================================================== * Accordion Slider Admin * ====================================================================== */ (function( $ ) { var AccordionSliderAdmin = { /** * Stores the data for all panels in the accordion. * * @since 1.0.0 * * @type {Array} */ panels: [], /** * Keeps a count for the panels in the accordion. * * @since 1.0.0 * * @type {Int} */ panelCounter: 0, /** * Stores all posts names and their taxonomies. * * @since 1.0.0 * * @type {Object} */ postsData: {}, /** * Indicates if the preview images from the panels * can be resized. * This prevents resizing the images too often. * * @since 1.0.0 * * @type {Boolean} */ allowPanelImageResize: true, /** * Initializes the functionality for a single accordion page * or for the page that contains all the accordions. * * @since 1.0.0 */ init: function() { if ( as_js_vars.page === 'single' ) { this.initSingleAccordionPage(); } else if ( as_js_vars.page === 'all' ) { this.initAllAccordionsPage(); } }, /* * ====================================================================== * Accordion functions * ====================================================================== */ /** * Initializes the functionality for a single accordion page * by adding all the necessary event listeners. * * @since 1.0.0 */ initSingleAccordionPage: function() { var that = this; this.initPanels(); if ( parseInt( as_js_vars.id, 10 ) !== -1 ) { this.loadAccordionData( function() { that.checkBackgroundImageSize(); }); } $( 'form' ).on( 'submit', function( event ) { event.preventDefault(); that.saveAccordion(); that.checkBackgroundImageSize(); }); $( '.preview-accordion' ).on( 'click', function( event ) { event.preventDefault(); that.previewAccordion(); }); $( '.add-panel' ).on( 'click', function( event ) { event.preventDefault(); that.addImagePanels(); }); $( '.postbox .hndle, .postbox .handlediv' ).on( 'click', function() { var postbox = $( this ).parent( '.postbox' ); if ( postbox.hasClass( 'closed' ) === true ) { postbox.removeClass( 'closed' ); } else { postbox.addClass( 'closed' ); } }); $( '.sidebar-settings' ).on( 'mouseover', 'label', function() { that.showInfo( $( this ) ); }); $( window ).resize(function() { if ( that.allowPanelImageResize === true ) { that.resizePanelImages(); that.allowPanelImageResize = false; setTimeout( function() { that.resizePanelImages(); that.allowPanelImageResize = true; }, 250 ); } }); }, /** * Initializes the functionality for the page that contains * all the accordions by adding all the necessary event listeners. * * @since 1.0.0 */ initAllAccordionsPage: function() { var that = this; $( '.accordions-list' ).on( 'click', '.preview-accordion', function( event ) { event.preventDefault(); that.previewAccordionAll( $( this ) ); }); $( '.accordions-list' ).on( 'click', '.delete-accordion', function( event ) { event.preventDefault(); that.deleteAccordion( $( this ) ); }); $( '.accordions-list' ).on( 'click', '.duplicate-accordion', function( event ) { event.preventDefault(); that.duplicateAccordion( $( this ) ); }); $( '.clear-all-cache' ).on( 'click', function( event ) { event.preventDefault(); $( '.clear-cache-spinner' ).css( { 'display': 'inline-block', 'visibility': 'visible' } ); var nonce = $( this ).attr( 'data-nonce' ); $.ajax({ url: as_js_vars.ajaxurl, type: 'post', data: { action: 'accordion_slider_lite_clear_all_cache', nonce: nonce }, complete: function( data ) { $( '.clear-cache-spinner' ).css( { 'display': '', 'visibility': '' } ); } }); }); }, /** * Load the accordion accordion data. * * Send an AJAX request with the accordion id and the nonce, and * retrieve all the accordion's database data. Then, assign the * data to the panels. * * @since 1.0.0 */ loadAccordionData: function( callback ) { var that = this; $( '.panel-spinner' ).css( { 'display': 'inline-block', 'visibility': 'visible' } ); $.ajax({ url: as_js_vars.ajaxurl, type: 'get', data: { action: 'accordion_slider_lite_get_accordion_data', id: as_js_vars.id, nonce: as_js_vars.lad_nonce }, complete: function( data ) { var accordionData = $.parseJSON( data.responseText ); $.each( accordionData.panels, function( index, panel ) { var panelData = { background: {}, layers: panel.layers, html: panel.html, settings: $.isArray( panel.settings ) ? {} : panel.settings }; $.each( panel, function( settingName, settingValue ) { if ( settingName.indexOf( 'background' ) !== -1 ) { panelData.background[ settingName ] = settingValue; } }); that.getPanel( index ).setData( 'all', panelData ); }); $( '.panel-spinner' ).css( { 'display': '', 'visibility': '' } ); callback(); } }); }, /** * Save the accordion's data. * * Get the accordion's data and send it to the server with AJAX. If * a new accordion was created, redirect to the accordion's edit page. * * @since 1.0.0 */ saveAccordion: function() { var accordionData = this.getAccordionData(); accordionData[ 'nonce' ] = as_js_vars.sa_nonce; accordionData[ 'action' ] = 'save'; var accordionDataString = JSON.stringify( accordionData ); var spinner = $( '.update-spinner' ).css( { 'display': 'inline-block', 'visibility': 'visible' } ); $.ajax({ url: as_js_vars.ajaxurl, type: 'post', data: { action: 'accordion_slider_lite_save_accordion', data: accordionDataString }, complete: function( data ) { spinner.css( { 'display': '', 'visibility': '' } ); if ( parseInt( as_js_vars.id, 10 ) === -1 && isNaN( data.responseText ) === false ) { $( 'h2' ).after( '
' + as_js_vars.accordion_create + '
' + as_js_vars.accordion_update + '
' + as_js_vars.accordion_delete + '
' + ' ' + '' + as_js_vars.panel_delete + '
' + ' ' + '' + as_js_vars.no_image + '
' ).appendTo( panelPreview ); } this.$panel.removeClass( 'dynamic-panel' ); } }, /** * Resize the preview image, after it has loaded. * * @since 1.0.0 */ resizeImage: function() { var panelPreview = this.$panel.find( '.panel-preview' ), panelImage = this.$panel.find( '.panel-preview > img' ); if ( panelImage.length ) { var checkImage = setInterval(function() { if ( panelImage[0].complete === true ) { clearInterval( checkImage ); if ( panelImage.width() / panelImage.height() > panelPreview.width() / panelPreview.height() ) { panelImage.css( { width: 'auto', height: '100%' } ); } else { panelImage.css( { width: '100%', height: 'auto' } ); } } }, 100 ); } }, /** * Add an event listener to the panel. * * @since 1.0.0 * * @param {String} type The event name. * @param {Function} handler The callback function. */ on: function( type, handler ) { this.events.on( type, handler ); }, /** * Remove an event listener from the panel. * * @since 1.0.0 * * @param {String} type The event name. */ off: function( type ) { this.events.off( type ); }, /** * Triggers an event. * * @since 1.0.0 * * @param {String} type The event name. */ trigger: function( type ) { this.events.triggerHandler( type ); } }; /* * ====================================================================== * Media loader * ====================================================================== */ var MediaLoader = { /** * Open the WordPress media loader and pass the * information of the selected images to the * callback function. * * The passed that is the image's url, alt, title, * width and height. * * @since 1.0.0 */ open: function( callback ) { var selection = [], insertReference = wp.media.editor.insert; wp.media.editor.send.attachment = function( props, attachment ) { var image = typeof attachment.sizes[ props.size ] !== 'undefined' ? attachment.sizes[ props.size ] : attachment.sizes[ 'full' ], url = image.url, width = image.width, height = image.height, alt = attachment.alt, title = attachment.title, link = props.link === 'custom' ? props.linkUrl : ''; selection.push( { url: url, alt: alt, title: title, width: width, height: height, link: link } ); }; wp.media.editor.insert = function( prop ) { callback.call( this, selection ); wp.media.editor.insert = insertReference; }; wp.media.editor.open( 'media-loader' ); } }; /* * ====================================================================== * Preview window * ====================================================================== */ var PreviewWindow = { /** * Reference to the modal window. * * @since 1.0.0 * * @type {jQuery Object} */ previewWindow: null, /** * Reference to the accordion slider instance. * * @since 1.0.0 * * @type {jQuery Object} */ accordion: null, /** * The accordion's data. * * @since 1.0.0 * * @type {Object} */ accordionData: null, /** * Open the preview window and pass the accordion's data, * which consists of accordion settings and each panel's * settings and content. * * Send an AJAX request with the data and receive the * accordion's HTML markup and inline JavaScript. * * @since 1.0.0 * * @param {Object} data The data of the accordion */ open: function( data ) { this.accordionData = data; var that = this, spinner = $( '.preview-spinner' ).css( { 'display': 'inline-block', 'visibility': 'visible' } ); $.ajax({ url: as_js_vars.ajaxurl, type: 'post', data: { action: 'accordion_slider_lite_preview_accordion', data: JSON.stringify( data ) }, complete: function( data ) { $( 'body' ).append( data.responseText ); that.init(); spinner.css( { 'display': '', 'visibility': '' } ); } }); }, /** * Initialize the preview. * * Detect when the window is resized and resize the preview * window accordingly, and also based on the accordion's set * width. * * @since 1.0.0 */ init: function() { var that = this; $( '.modal-window-container' ).css( 'top', $( window ).scrollTop() ); this.previewWindow = $( '.preview-window .modal-window' ); this.accordion = this.previewWindow.find( '.accordion-slider' ); this.previewWindow.find( '.close-x' ).on( 'click', function( event ) { that.close(); }); var accordionWidth = this.accordionData[ 'settings' ][ 'width' ], accordionHeight = this.accordionData[ 'settings' ][ 'height' ], isPercetageWidth = accordionWidth.indexOf( '%' ) !== -1, isPercetageHeight = accordionHeight.indexOf( '%' ) !== -1; if ( isPercetageWidth === true ) { this.accordion.accordionSlider('width', '100%'); } else { accordionWidth = parseInt( accordionWidth, 10 ); } if ( isPercetageHeight === true ) { this.accordion.accordionSlider('height', '100%'); } $( window ).on( 'resize.accordionSlider', function() { if ( isPercetageWidth === true ) { that.previewWindow.css( 'width', $( window ).width() * ( parseInt( accordionWidth, 10 ) / 100 ) - 100 ); } else if ( accordionWidth >= $( window ).width() - 100 ) { that.previewWindow.css( 'width', $( window ).width() - 100 ); } else { that.previewWindow.css( 'width', accordionWidth ); } if ( isPercetageHeight === true ) { that.previewWindow.css( 'height', $( window ).height() * ( parseInt( accordionHeight, 10 ) / 100 ) - 200 ); } }); $( window ).trigger( 'resize' ); $( window ).trigger( 'resize' ); }, /** * Close the preview window. * * Remove event listeners and elements. * * @since 1.0.0 */ close: function() { this.previewWindow.find( '.close-x' ).off( 'click' ); $( window ).off( 'resize.accordionSlider' ); this.accordion.accordionSlider( 'destroy' ); $( 'body' ).find( '.modal-overlay, .modal-window-container' ).remove(); } }; $( document ).ready(function() { AccordionSliderAdmin.init(); }); })( jQuery ); /* * ====================================================================== * LightSortable * ====================================================================== */ ;(function( $ ) { var LightSortable = function( instance, options ) { this.options = options; this.$container = $( instance ); this.$selectedChild = null; this.$placeholder = null; this.currentMouseX = 0; this.currentMouseY = 0; this.panelInitialX = 0; this.panelInitialY = 0; this.initialMouseX = 0; this.initialMouseY = 0; this.isDragging = false; this.checkHover = 0; this.uid = new Date().valueOf(); this.events = $( {} ); this.startPosition = 0; this.endPosition = 0; this.init(); }; LightSortable.prototype = { init: function() { this.settings = $.extend( {}, this.defaults, this.options ); this.$container.on( 'mousedown.lightSortable' + this.uid, $.proxy( this._onDragStart, this ) ); $( document ).on( 'mousemove.lightSortable.' + this.uid, $.proxy( this._onDragging, this ) ); $( document ).on( 'mouseup.lightSortable.' + this.uid, $.proxy( this._onDragEnd, this ) ); }, _onDragStart: function( event ) { if ( event.which !== 1 || $( event.target ).is( 'select' ) || $( event.target ).is( 'input' ) ) { return; } this.$selectedChild = $( event.target ).is( this.settings.children ) ? $( event.target ) : $( event.target ).parents( this.settings.children ); if ( this.$selectedChild.length === 1 ) { this.initialMouseX = event.pageX; this.initialMouseY = event.pageY; this.panelInitialX = this.$selectedChild.position().left; this.panelInitialY = this.$selectedChild.position().top; this.startPosition = this.$selectedChild.index(); event.preventDefault(); } }, _onDragging: function( event ) { if ( this.$selectedChild === null || this.$selectedChild.length === 0 ) return; event.preventDefault(); this.currentMouseX = event.pageX; this.currentMouseY = event.pageY; if ( ! this.isDragging ) { this.isDragging = true; this.trigger( { type: 'sortStart' } ); if ( $.isFunction( this.settings.sortStart ) ) { this.settings.sortStart.call( this, { type: 'sortStart' } ); } var tag = this.$container.is( 'ul' ) || this.$container.is( 'ol' ) ? 'li' : 'div'; this.$placeholder = $( '<' + tag + '>' ).addClass( 'ls-ignore ' + this.settings.placeholder ) .insertAfter( this.$selectedChild ); if ( this.$placeholder.width() === 0 ) { this.$placeholder.css( 'width', this.$selectedChild.outerWidth() ); } if ( this.$placeholder.height() === 0 ) { this.$placeholder.css( 'height', this.$selectedChild.outerHeight() ); } this.$selectedChild.css( { 'pointer-events': 'none', 'position': 'absolute', left: this.$selectedChild.position().left, top: this.$selectedChild.position().top, width: this.$selectedChild.width(), height: this.$selectedChild.height() } ) .addClass( 'ls-ignore' ); this.$container.append( this.$selectedChild ); $( 'body' ).css( 'user-select', 'none' ); var that = this; this.checkHover = setInterval( function() { that.$container.find( that.settings.children ).not( '.ls-ignore' ).each( function() { var $currentChild = $( this ); if ( that.currentMouseX > $currentChild.offset().left && that.currentMouseX < $currentChild.offset().left + $currentChild.width() && that.currentMouseY > $currentChild.offset().top && that.currentMouseY < $currentChild.offset().top + $currentChild.height() ) { if ( $currentChild.index() >= that.$placeholder.index() ) that.$placeholder.insertAfter( $currentChild ); else that.$placeholder.insertBefore( $currentChild ); } }); }, 200 ); } this.$selectedChild.css( { 'left': this.currentMouseX - this.initialMouseX + this.panelInitialX, 'top': this.currentMouseY - this.initialMouseY + this.panelInitialY } ); }, _onDragEnd: function() { if ( this.isDragging ) { this.isDragging = false; $( 'body' ).css( 'user-select', ''); this.$selectedChild.css( { 'position': '', left: '', top: '', width: '', height: '', 'pointer-events': '' } ) .removeClass( 'ls-ignore' ) .insertAfter( this.$placeholder ); this.$placeholder.remove(); clearInterval( this.checkHover ); this.endPosition = this.$selectedChild.index(); this.trigger( { type: 'sortEnd' } ); if ( $.isFunction( this.settings.sortEnd ) ) { this.settings.sortEnd.call( this, { type: 'sortEnd', startPosition: this.startPosition, endPosition: this.endPosition } ); } } this.$selectedChild = null; }, destroy: function() { this.$container.removeData( 'lightSortable' ); if ( this.isDragging ) { this._onDragEnd(); } this.$container.off( 'mousedown.lightSortable.' + this.uid ); $( document ).off( 'mousemove.lightSortable.' + this.uid ); $( document ).off( 'mouseup.lightSortable.' + this.uid ); }, on: function( type, callback ) { return this.events.on( type, callback ); }, off: function( type ) { return this.events.off( type ); }, trigger: function( data ) { return this.events.triggerHandler( data ); }, defaults: { placeholder: '', sortStart: function() {}, sortEnd: function() {} } }; $.fn.lightSortable = function( options ) { var args = Array.prototype.slice.call( arguments, 1 ); return this.each(function() { if ( typeof $( this ).data( 'lightSortable' ) === 'undefined' ) { var newInstance = new LightSortable( this, options ); $( this ).data( 'lightSortable', newInstance ); } else if ( typeof options !== 'undefined' ) { var currentInstance = $( this ).data( 'lightSortable' ); if ( typeof currentInstance[ options ] === 'function' ) { currentInstance[ options ].apply( currentInstance, args ); } else { $.error( options + ' does not exist in lightSortable.' ); } } }); }; })( jQuery ); /* * ====================================================================== * lightURLParse * ====================================================================== */ ;(function( $ ) { $.lightURLParse = function( url ) { var urlArray = url.split( '?' )[1].split( '&' ), result = []; $.each( urlArray, function( index, element ) { var elementArray = element.split( '=' ); result[ elementArray[ 0 ] ] = elementArray[ 1 ]; }); return result; }; })( jQuery );