editor.js
398 lines
| 1 | /** |
| 2 | * Initialize all modules |
| 3 | */ |
| 4 | ;(function($, window, document, undefined){ |
| 5 | |
| 6 | $( window ).on( 'elementor:init', function() { |
| 7 | |
| 8 | // Add auxin specific css class to elementor body |
| 9 | $('.elementor-editor-active').addClass('auxin'); |
| 10 | |
| 11 | // Make our custom css visible in the panel's front-end |
| 12 | if( typeof elementorPro == 'undefined' ) { |
| 13 | elementor.hooks.addFilter( 'editor/style/styleText', function( css, context ){ |
| 14 | if ( ! context ) { |
| 15 | return; |
| 16 | } |
| 17 | |
| 18 | var model = context.model, |
| 19 | customCSS = model.get('settings').get('custom_css'); |
| 20 | var selector = '.elementor-element.elementor-element-' + model.get('id'); |
| 21 | |
| 22 | if ('document' === model.get('elType')) { |
| 23 | selector = elementor.config.document.settings.cssWrapperSelector; |
| 24 | } |
| 25 | |
| 26 | if (customCSS) { |
| 27 | css += customCSS.replace(/selector/g, selector); |
| 28 | } |
| 29 | |
| 30 | return css; |
| 31 | }); |
| 32 | } |
| 33 | |
| 34 | var AuxControlBaseDataView = elementor.modules.controls.BaseData; |
| 35 | |
| 36 | /*! |
| 37 | * ================== Auxin Visual Select Controller =================== |
| 38 | **/ |
| 39 | var AuxControlVisualSelectItemView = AuxControlBaseDataView.extend( { |
| 40 | onReady: function() { |
| 41 | this.ui.select.avertaVisualSelect(); |
| 42 | }, |
| 43 | onBeforeDestroy: function() { |
| 44 | this.ui.select.avertaVisualSelect( 'destroy' ); |
| 45 | } |
| 46 | } ); |
| 47 | elementor.addControlView( 'aux-visual-select', AuxControlVisualSelectItemView ); |
| 48 | |
| 49 | |
| 50 | /*! |
| 51 | * ================== Auxin Media Select Controller =================== |
| 52 | **/ |
| 53 | var AuxControlMediaSelectItemView = AuxControlBaseDataView.extend( { |
| 54 | ui: function() { |
| 55 | var ui = AuxControlBaseDataView.prototype.ui.apply( this, arguments ); |
| 56 | |
| 57 | ui.controlMedia = '.aux-elementor-control-media'; |
| 58 | ui.mediaImage = '.aux-elementor-control-media-attachment'; |
| 59 | ui.frameOpeners = '.aux-elementor-control-media-upload-button, .aux-elementor-control-media-attachment'; |
| 60 | ui.deleteButton = '.aux-elementor-control-media-delete'; |
| 61 | |
| 62 | return ui; |
| 63 | }, |
| 64 | |
| 65 | events: function() { |
| 66 | return _.extend( AuxControlBaseDataView.prototype.events.apply( this, arguments ), { |
| 67 | 'click @ui.frameOpeners': 'openFrame', |
| 68 | 'click @ui.deleteButton': 'deleteImage' |
| 69 | } ); |
| 70 | }, |
| 71 | |
| 72 | applySavedValue: function() { |
| 73 | var control = this.getControlValue(); |
| 74 | |
| 75 | this.ui.mediaImage.css( 'background-image', control.img ? 'url(' + control.img + ')' : '' ); |
| 76 | |
| 77 | this.ui.controlMedia.toggleClass( 'elementor-media-empty', ! control.img ); |
| 78 | }, |
| 79 | |
| 80 | openFrame: function() { |
| 81 | if ( ! this.frame ) { |
| 82 | this.initFrame(); |
| 83 | } |
| 84 | |
| 85 | this.frame.open(); |
| 86 | }, |
| 87 | |
| 88 | deleteImage: function() { |
| 89 | this.setValue( { |
| 90 | url: '', |
| 91 | img: '', |
| 92 | id : '' |
| 93 | } ); |
| 94 | |
| 95 | this.applySavedValue(); |
| 96 | }, |
| 97 | |
| 98 | /** |
| 99 | * Create a media modal select frame, and store it so the instance can be reused when needed. |
| 100 | */ |
| 101 | initFrame: function() { |
| 102 | this.frame = wp.media( { |
| 103 | button: { |
| 104 | text: elementor.translate( 'insert_media' ) |
| 105 | }, |
| 106 | states: [ |
| 107 | new wp.media.controller.Library( { |
| 108 | title: elementor.translate( 'insert_media' ), |
| 109 | library: wp.media.query( { type: this.ui.controlMedia.data('media-type') } ), |
| 110 | multiple: false, |
| 111 | date: false |
| 112 | } ) |
| 113 | ] |
| 114 | } ); |
| 115 | |
| 116 | // When a file is selected, run a callback. |
| 117 | this.frame.on( 'insert select', this.select.bind( this ) ); |
| 118 | }, |
| 119 | |
| 120 | /** |
| 121 | * Callback handler for when an attachment is selected in the media modal. |
| 122 | * Gets the selected image information, and sets it within the control. |
| 123 | */ |
| 124 | select: function() { |
| 125 | this.trigger( 'before:select' ); |
| 126 | |
| 127 | // Get the attachment from the modal frame. |
| 128 | var attachment = this.frame.state().get( 'selection' ).first().toJSON(); |
| 129 | |
| 130 | if ( attachment.url ) { |
| 131 | this.setValue( { |
| 132 | url: attachment.url, |
| 133 | img: attachment.image.src, |
| 134 | id : attachment.id |
| 135 | } ); |
| 136 | |
| 137 | this.applySavedValue(); |
| 138 | } |
| 139 | |
| 140 | this.trigger( 'after:select' ); |
| 141 | }, |
| 142 | |
| 143 | onBeforeDestroy: function() { |
| 144 | this.$el.remove(); |
| 145 | } |
| 146 | } ); |
| 147 | elementor.addControlView( 'aux-media', AuxControlMediaSelectItemView ); |
| 148 | |
| 149 | /*! |
| 150 | * ================== Auxin Icon Select Controller =================== |
| 151 | **/ |
| 152 | var AuxControlSelect2 = elementor.modules.controls.Select2; |
| 153 | |
| 154 | var ControlIconSelectItemView = AuxControlSelect2.extend( { |
| 155 | initialize: function() { |
| 156 | AuxControlSelect2View.prototype.initialize.apply( this, arguments ); |
| 157 | |
| 158 | this.filterIcons(); |
| 159 | }, |
| 160 | |
| 161 | filterIcons: function() { |
| 162 | var icons = this.model.get( 'options' ), |
| 163 | include = this.model.get( 'include' ), |
| 164 | exclude = this.model.get( 'exclude' ); |
| 165 | |
| 166 | if ( include ) { |
| 167 | var filteredIcons = {}; |
| 168 | |
| 169 | _.each( include, function( iconKey ) { |
| 170 | filteredIcons[ iconKey ] = icons[ iconKey ]; |
| 171 | } ); |
| 172 | |
| 173 | this.model.set( 'options', filteredIcons ); |
| 174 | return; |
| 175 | } |
| 176 | |
| 177 | if ( exclude ) { |
| 178 | _.each( exclude, function( iconKey ) { |
| 179 | delete icons[ iconKey ]; |
| 180 | } ); |
| 181 | } |
| 182 | }, |
| 183 | |
| 184 | iconsList: function( icon ) { |
| 185 | if ( ! icon.id ) { |
| 186 | return icon.text; |
| 187 | } |
| 188 | |
| 189 | return jQuery( |
| 190 | '<span><i class="' + icon.id + '"></i> ' + icon.text + '</span>' |
| 191 | ); |
| 192 | }, |
| 193 | |
| 194 | getSelect2Options: function() { |
| 195 | return { |
| 196 | allowClear: true, |
| 197 | templateResult: this.iconsList.bind( this ), |
| 198 | templateSelection: this.iconsList.bind( this ) |
| 199 | }; |
| 200 | } |
| 201 | } ); |
| 202 | elementor.addControlView( 'aux-icon', ControlIconSelectItemView ); |
| 203 | |
| 204 | // ControlSelect2View prototype |
| 205 | var AuxControlSelect2View = AuxControlSelect2.extend( { |
| 206 | getSelect2Options: function() { |
| 207 | return { |
| 208 | dir: elementor.config.is_rtl ? 'rtl' : 'ltr' |
| 209 | }; |
| 210 | }, |
| 211 | |
| 212 | templateHelpers: function() { |
| 213 | var helpers = AuxControlSelect2View.prototype.templateHelpers.apply( this, arguments ), |
| 214 | fonts = this.model.get( 'options' ); |
| 215 | |
| 216 | helpers.getFontsByGroups = function( groups ) { |
| 217 | var filteredFonts = {}; |
| 218 | |
| 219 | _.each( fonts, function( fontType, fontName ) { |
| 220 | if ( _.isArray( groups ) && _.contains( groups, fontType ) || fontType === groups ) { |
| 221 | filteredFonts[ fontName ] = fontName; |
| 222 | } |
| 223 | } ); |
| 224 | |
| 225 | return filteredFonts; |
| 226 | }; |
| 227 | |
| 228 | console.log(helpers); |
| 229 | |
| 230 | return helpers; |
| 231 | } |
| 232 | } ); |
| 233 | |
| 234 | /*! |
| 235 | * ================== Auxin Query Controller =================== |
| 236 | **/ |
| 237 | var ControlQueryPostsItemView = AuxControlSelect2.extend( { |
| 238 | cache: null, |
| 239 | |
| 240 | isTitlesReceived: false, |
| 241 | |
| 242 | getSelect2Placeholder: function getSelect2Placeholder() { |
| 243 | return { |
| 244 | id: '', |
| 245 | text: 'All' |
| 246 | }; |
| 247 | }, |
| 248 | |
| 249 | getControlValueByName: function getControlValueByName(controlName) { |
| 250 | var name = this.model.get('group_prefix') + controlName; |
| 251 | return this.elementSettingsModel.attributes[name]; |
| 252 | }, |
| 253 | |
| 254 | getSelect2DefaultOptions: function getSelect2DefaultOptions() { |
| 255 | var self = this; |
| 256 | |
| 257 | return jQuery.extend(AuxControlSelect2.prototype.getSelect2DefaultOptions.apply(this, arguments), { |
| 258 | ajax: { |
| 259 | transport: function transport(params, success, failure) { |
| 260 | var data = { |
| 261 | q: params.data.q, |
| 262 | filter_type: self.model.get('filter_type'), |
| 263 | object_type: self.model.get('object_type'), |
| 264 | include_type: self.model.get('include_type'), |
| 265 | query: self.model.get('query') |
| 266 | }; |
| 267 | |
| 268 | if ('cpt_taxonomies' === data.filter_type) { |
| 269 | data.query = { |
| 270 | post_type: self.getControlValueByName('post_type') |
| 271 | }; |
| 272 | } |
| 273 | |
| 274 | return elementorCommon.ajax.addRequest('panel_posts_control_filter_autocomplete', { |
| 275 | data: data, |
| 276 | success: success, |
| 277 | error: failure |
| 278 | }); |
| 279 | }, |
| 280 | data: function data(params) { |
| 281 | return { |
| 282 | q: params.term, |
| 283 | page: params.page |
| 284 | }; |
| 285 | }, |
| 286 | cache: true |
| 287 | }, |
| 288 | escapeMarkup: function escapeMarkup(markup) { |
| 289 | return markup; |
| 290 | }, |
| 291 | minimumInputLength: 1 |
| 292 | }); |
| 293 | }, |
| 294 | |
| 295 | getValueTitles: function getValueTitles() { |
| 296 | var self = this, |
| 297 | ids = this.getControlValue(), |
| 298 | filterType = this.model.get('filter_type'); |
| 299 | |
| 300 | if (!ids || !filterType) { |
| 301 | return; |
| 302 | } |
| 303 | |
| 304 | if (!_.isArray(ids)) { |
| 305 | ids = [ids]; |
| 306 | } |
| 307 | |
| 308 | elementorCommon.ajax.loadObjects({ |
| 309 | action: 'query_control_value_titles', |
| 310 | ids: ids, |
| 311 | data: { |
| 312 | filter_type: filterType, |
| 313 | object_type: self.model.get('object_type'), |
| 314 | include_type: self.model.get('include_type'), |
| 315 | unique_id: '' + self.cid + filterType, |
| 316 | query: self.model.get('query') |
| 317 | }, |
| 318 | before: function before() { |
| 319 | self.addControlSpinner(); |
| 320 | }, |
| 321 | success: function success(data) { |
| 322 | self.isTitlesReceived = true; |
| 323 | |
| 324 | self.model.set('options', data); |
| 325 | |
| 326 | self.render(); |
| 327 | } |
| 328 | }); |
| 329 | }, |
| 330 | |
| 331 | addControlSpinner: function addControlSpinner() { |
| 332 | this.ui.select.prop('disabled', true); |
| 333 | this.$el.find('.elementor-control-title').after('<span class="elementor-control-spinner"> <i class="fa fa-spinner fa-spin"></i> </span>'); |
| 334 | }, |
| 335 | |
| 336 | onReady: function onReady() { |
| 337 | // Safari takes it's time to get the original select width |
| 338 | setTimeout(AuxControlSelect2.prototype.onReady.bind(this)); |
| 339 | |
| 340 | if (!this.isTitlesReceived) { |
| 341 | this.getValueTitles(); |
| 342 | } |
| 343 | } |
| 344 | } ); |
| 345 | elementor.addControlView( 'aux-query', ControlQueryPostsItemView ); |
| 346 | |
| 347 | /*! |
| 348 | * ================== Auxin Featured Color Controller =================== |
| 349 | **/ |
| 350 | var AuxControlFeaturedColorItemView = AuxControlBaseDataView.extend( { |
| 351 | |
| 352 | onReady: function() { |
| 353 | this.ui.select.AuxFeaturedColor(); |
| 354 | }, |
| 355 | |
| 356 | } ); |
| 357 | elementor.addControlView( 'aux-featured-color', AuxControlFeaturedColorItemView ); |
| 358 | |
| 359 | /*! |
| 360 | * ================== Others =================== |
| 361 | **/ |
| 362 | // Enables the live preview for tranistions in Elementor Editor |
| 363 | function auxOnGlobalOpenEditorForTranistions ( panel, model, view ) { |
| 364 | view.listenTo( model.get( 'settings' ), 'change', function( changedModel ){ |
| 365 | |
| 366 | // Force to re-render the element if the Entrance Animation enabled for first time |
| 367 | if( '' !== model.getSetting('aux_animation_name') && !view.$el.hasClass('aux-animated') ){ |
| 368 | view.render(); |
| 369 | view.$el.addClass('aux-animated'); |
| 370 | view.$el.addClass('aux-animated-once'); |
| 371 | } |
| 372 | |
| 373 | // Check the changed setting value |
| 374 | for( settingName in changedModel.changed ) { |
| 375 | if ( changedModel.changed.hasOwnProperty( settingName ) ) { |
| 376 | |
| 377 | // Replay the animation if an animation option changed (except the animation name) |
| 378 | if( settingName !== "aux_animation_name" && ( -1 !== settingName.indexOf("aux_animation_") || -1 !== settingName.indexOf("_custom") ) ){ |
| 379 | // Reply the animation |
| 380 | view.$el.removeClass( model.getSetting('aux_animation_name') ); |
| 381 | |
| 382 | setTimeout( function() { |
| 383 | view.$el.addClass( model.getSetting('aux_animation_name') ); |
| 384 | }, ( model.getSetting('aux_animation_delay') || 300 ) ); // Animation Delay |
| 385 | } |
| 386 | } |
| 387 | } |
| 388 | |
| 389 | }, view ); |
| 390 | } |
| 391 | elementor.hooks.addAction( 'panel/open_editor/section', auxOnGlobalOpenEditorForTranistions ); |
| 392 | elementor.hooks.addAction( 'panel/open_editor/column' , auxOnGlobalOpenEditorForTranistions ); |
| 393 | elementor.hooks.addAction( 'panel/open_editor/widget' , auxOnGlobalOpenEditorForTranistions ); |
| 394 | |
| 395 | } ); |
| 396 | |
| 397 | })(jQuery, window, document); |
| 398 |