1/* global jQuery, TRX_ADDONS_STORAGE */ 2 3jQuery(document).on('action.ready_trx_addons', function() { 4 "use strict"; 5 6 // How to handle fix/unfix rows: 7 // true - Intersection observers are used 8 // false - a scroll event handler is used 9 var USE_OBSERVERS = trx_addons_apply_filters( 'trx_addons_filter_use_observers_to_fix_rows', true ) 10 && typeof IntersectionObserver != 'undefined'; 11 12 // Common objects 13 var $document = jQuery( document ), 14 $body = jQuery( 'body' ); 15 16 // Return the row 'id' or data-id (if 'id' is empty) 17 function get_id( row ) { 18 return row.attr('id') ? row.attr('id') : row.attr('data-id'); 19 } 20 21 // Handle fixed rows 22 //--------------------------------------------------------- 23 if ( ! TRX_ADDONS_STORAGE['pagebuilder_preview_mode'] && ! $body.hasClass( 'sc_layouts_row_fixed_inited' ) ) { 24 var rows = jQuery('.sc_layouts_row_fixed'), 25 rows_always = rows.filter('.sc_layouts_row_fixed_always'), 26 rows_delayed = rows.filter('.sc_layouts_row_delay_fixed'), 27 last_scroll_offset = -1; 28 // If page contain fixed rows 29 if ( rows.length > 0 ) { 30 rows.each( function( idx ) { 31 // Add placeholders after each row 32 var row = rows.eq( idx ); 33 if ( row.hasClass('sc_layouts_row_hide_unfixed' ) ) { 34 if ( ! row.prev().hasClass('sc_layouts_row_unfixed_placeholder') ) { 35 row.before( '<div class="sc_layouts_row_unfixed_placeholder">' 36 + ( USE_OBSERVERS ? '<div class="sc_layouts_row_fixed_marker_on"></div>' : '' ) 37 + '</div>'); 38 } 39 } 40 var row_next = row.next(); 41 if ( ! row_next.hasClass( 'sc_layouts_row_fixed_placeholder' ) ) { 42 if ( row_next.hasClass( 'vc_row-full-width' ) ) { // If the row is fullwide in VC - add the placeholder to the next element to keep the VC fullwide behavior 43 row_next 44 .addClass( 'sc_layouts_row_fixed_placeholder' ) 45 .css( 'background-color', row.css( 'background-color' ) ) 46 .append( '<div class="sc_layouts_row_fixed_marker_off"></div>' ); 47 } else { // Normal case 48 row.after( '<div class="sc_layouts_row_fixed_placeholder" style="background-color:' + row.css('background-color') + ';"><div class="sc_layouts_row_fixed_marker_off"></div></div>' ); 49 } 50 if ( USE_OBSERVERS && ! row.hasClass('sc_layouts_row_hide_unfixed' ) ) { 51 row.append('<div class="sc_layouts_row_fixed_marker_on"></div>'); 52 } 53 } 54 // Add class 'sc_layouts_row_fixed_with_fullscreen' to the row if it contains the element with class 'search_style_fullscreen' 55 // if ( row.find( trx_addons_apply_filters( 'trx_addons_filter_fullscreen_elements', '.search_style_fullscreen,.search_modern' ) ).length > 0 ) { 56 // row.addClass( 'sc_layouts_row_fixed_with_fullscreen' ); 57 // } 58 } ); 59 // Add handlers to fix/unfix rows 60 var timedFix = trx_addons_throttle( function() { 61 trx_addons_cpt_layouts_fix_rows( { 62 rows: rows, 63 rows_always: rows_always 64 } ); 65 last_scroll_offset = trx_addons_window_scroll_top(); 66 }, 150 ); 67 $document 68 .on('action.scroll_trx_addons', function() { 69 trx_addons_cpt_layouts_hide_fixed_rows(); 70 if ( ! USE_OBSERVERS ) { 71 trx_addons_cpt_layouts_fix_rows( { 72 rows: rows, 73 rows_always: rows_always 74 } ); 75 last_scroll_offset = trx_addons_window_scroll_top(); 76 } else { 77 timedFix(); 78 } 79 }) 80 .on('action.resize_trx_addons', function() { 81 // Update global values 82 trx_addons_cpt_layouts_check_mobile_breakpoint(); 83 trx_addons_cpt_layouts_hide_fixed_rows(); 84 trx_addons_cpt_layouts_fix_rows( { 85 rows: rows, 86 rows_always: rows_always, 87 resize: true 88 } ); 89 }); 90 // Add observer to fix/unfix rows 91 if ( USE_OBSERVERS ) { 92 var fixed_rows_observe = function() { 93 rows.each( function( idx ) { 94 var row = rows.eq( idx ); 95 var delay = trx_addons_cpt_layouts_fix_rows_delay( row ); 96 var marker_off = row.next().find( '>.sc_layouts_row_fixed_marker_off' ); 97 var marker_on = row.hasClass( 'sc_layouts_row_hide_unfixed' ) 98 ? row.prev().find( '>.sc_layouts_row_fixed_marker_on' ) 99 : row.find( '>.sc_layouts_row_fixed_marker_on' ); 100 var observer = row.data( 'trx-addons-fixed-observer' ); 101 if ( observer ) { 102 if ( marker_off.length ) observer.unobserve( marker_off.get(0) ); 103 if ( marker_on.length ) observer.unobserve( marker_on.get(0) ); 104 observer.disconnect(); 105 observer = null; 106 } 107 // Skip hidden rows without a class 'sc_layouts_row_hide_unfixed' 108 if ( row.css('display') == 'none' && ! row.hasClass('sc_layouts_row_hide_unfixed' ) ) { 109 return; 110 } 111 // On mobile devices skip rows without a class 'sc_layouts_row_fixed_always' 112 if ( trx_addons_window_width() < TRX_ADDONS_STORAGE['mobile_breakpoint_fixedrows_off'] 113 && ! row.hasClass( 'sc_layouts_row_fixed_always' ) 114 ) { 115 return; 116 } 117 var row_height = row.hasClass( 'sc_layouts_row_hide_unfixed' ) ? 0 : row.outerHeight(); 118 // Create an observer for each row (to pay account an individual settings for delay) 119 observer = new IntersectionObserver( function( entries ) { 120 var time = new Date().getTime();
121 entries.forEach( function( entry ) { 122 var marker = jQuery( entry.target ), 123 // marker_offset = marker.offset().top, 124 parent = marker.parent(), 125 row = parent; 126 if ( parent.hasClass( 'sc_layouts_row_unfixed_placeholder' ) ) { 127 row = row.next(); 128 } else if ( parent.hasClass( 'sc_layouts_row_fixed_placeholder' ) ) { 129 row = row.prev(); 130 } 131 var animation_off_timeout = trx_addons_cpt_layouts_fix_rows_off_timeout( delay, row ); 132 var last_fixed_time = row.data('trx-addons-last-fixed-time') || 0; 133 // marker_off is come in to the viewport 134 if ( row.hasClass( 'sc_layouts_row_fixed_on' ) && entry.isIntersecting ) { 135 if ( time - last_fixed_time > animation_off_timeout 136 && entry.boundingClientRect 137 && entry.rootBounds 138 && entry.boundingClientRect.top >= entry.rootBounds.top 139 ) { 140 if ( ! row.hasClass( 'sc_layouts_row_fixed_animation_off' ) ) { 141 trx_addons_cpt_layouts_fix_rows( { 142 rows: rows, 143 rows_always: rows_always, 144 force_row: row, 145 force_state: 'off' 146 } ); 147 } 148 } 149 150 // marker_on is go out from the viewport 151 } else if ( ! row.hasClass( 'sc_layouts_row_fixed_on' ) && ! entry.isIntersecting ) { 152 if ( time - last_fixed_time > animation_off_timeout 153 && entry.boundingClientRect 154 && entry.rootBounds 155 && entry.boundingClientRect.bottom < entry.rootBounds.top 156 ) { 157 trx_addons_cpt_layouts_fix_rows( { 158 rows: rows, 159 rows_always: rows_always, 160 force_row: row, 161 force_state: 'on' 162 } ); 163 } 164 } 165 } ); 166 }, { 167 root: null, 168 rootMargin: ( delay - trx_addons_fixed_rows_height() + ( ! $body.hasClass('hide_fixed_rows') && row.hasClass( 'sc_layouts_row_fixed_on' ) ? row_height : 0 ) ) + 'px 0px 0px 0px', 169 threshold: 0 170 } 171 ); 172 var marker = row.hasClass( 'sc_layouts_row_fixed_on' ) ? marker_off : marker_on; 173 observer.observe( marker.get(0) ); 174 row.data( 'trx-addons-fixed-observer', observer ); 175 } ); 176 }; 177 $document.on('action.sc_layouts_row_fixed_on action.sc_layouts_row_fixed_off', fixed_rows_observe ); 178 fixed_rows_observe(); 179 180 } 181 // Add a class to the body 182 $body.addClass( 'sc_layouts_row_fixed_inited' ); 183 } 184 } 185 186 function trx_addons_cpt_layouts_fix_rows_delay( row ) { 187 var delay = 0; 188 if ( row.hasClass( 'sc_layouts_row_delay_fixed' ) ) { 189 var coef = row.data( 'fixed-row-delay' ); 190 if ( coef && ('' + coef).indexOf('px') > 0 ) { 191 delay = Math.max( 0, parseInt( coef, 10 ) ); 192 } else { 193 if ( ! coef || isNaN( coef ) || coef <= 0 ) { 194 coef = 3 / 4; 195 } 196 delay = Math.max( 0, trx_addons_window_height() * coef ); 197 } 198 } 199 return trx_addons_apply_filters( 'trx_addons_filter_fixed_rows_delay', delay ); 200 } 201 202 function trx_addons_cpt_layouts_fix_rows_off_timeout( delay, $row ) { 203 var timeout = delay > 0 ? getComputedStyle( $row.get(0) ).getPropertyValue('--trx-addons-fixed-rows-duration') || undefined : 0; 204 if ( timeout == undefined ) { 205 timeout = 300; // Timeout must be equal to the css-animation time (see layouts.scss) 206 } 207 if ( ('' + timeout).indexOf('ms') > 0 ) { 208 timeout = parseInt( timeout, 10 ); 209 } else if ( ('' + timeout).indexOf('s') > 0 ) { 210 timeout = parseFloat( timeout ) * 1000; 211 } 212 return trx_addons_apply_filters( 'trx_addons_filter_sc_layouts_row_fixed_off_timeout', 213 delay > 0 ? timeout : 0, 214 delay 215 ); 216 } 217 218 219 // Hide fixed rows on scroll down 220 function trx_addons_cpt_layouts_hide_fixed_rows() { 221 if ( TRX_ADDONS_STORAGE['hide_fixed_rows'] > 0 && ! window.trx_addons_document_animate_to_busy ) { 222 var scroll_delta = 50; 223 var scroll_offset = trx_addons_window_scroll_top(); 224 if ( last_scroll_offset >= 0 ) { 225 var event = ''; 226 // Scroll down 227 if ( scroll_offset > last_scroll_offset + scroll_delta ) { 228 if ( scroll_offset > trx_addons_window_height() * ( rows_delayed.length > 0 ? 1.5 : 0.6667 ) && ! $body.hasClass( 'hide_fixed_rows' ) ) { 229 $body.addClass( 'hide_fixed_rows' ); 230 event = 'off'; 231 } 232 // Scroll up 233 } else if ( scroll_offset < last_scroll_offset - scroll_delta || last_scroll_offset > 0 && scroll_offset == 0) { 234 if ( $body.hasClass( 'hide_fixed_rows' ) ) { 235 $body.removeClass( 'hide_fixed_rows' ); 236 event = 'on'; 237 } 238 } 239 // Trigger event 240 if ( event ) { 241 $document.trigger( 'action.sc_layouts_row_fixed_' + event, [ rows.filter('.sc_layouts_row_fixed_on') ] ); 242 } 243 } 244 } 245 } 246 247 // Break fixing on mobile devices (except rows with class 'sc_layouts_row_fixed_always') 248 function trx_addons_cpt_layouts_check_mobile_breakpoint() { 249 if ( trx_addons_window_width() < TRX_ADDONS_STORAGE['mobile_breakpoint_fixedrows_off'] ) { 250 rows.each( function( idx ) { 251 var row = rows.eq( idx ); 252 if ( ! row.hasClass( 'sc_layouts_row_fixed_always' ) ) { 253 row.removeClass( 'sc_layouts_row_fixed_on' ).css( { 'top': 'auto' } ); 254 } 255 }); 256 } 257 } 258 259 // Fix/unfix rows 260 function trx_addons_cpt_layouts_fix_rows( args ) { 261 262 var rows = args.rows, 263 rows_always = args.rows_always, 264 resize = args.resize || false, 265 force_row = args.force_row || null, 266 force_state = args.force_state || ''; 267 268 // Break fixing on mobile devices (except rows with class 'sc_layouts_row_fixed_always') 269 if ( trx_addons_window_width() < TRX_ADDONS_STORAGE['mobile_breakpoint_fixedrows_off'] ) { 270 if ( rows_always.length === 0 ) { 271 return; 272 } else { 273 rows = rows_always; 274 } 275 } 276 277 var scroll_offset = trx_addons_window_scroll_top(), 278 scroll_intent = last_scroll_offset >= 0 ? last_scroll_offset - scroll_offset : 0; 279 var rows_offset = trx_addons_adminbar_height(); 280 281 rows.each( function( idx ) { 282 var row = rows.eq( idx ); 283 var placeholder = row.next(); 284 var h = row.outerHeight(); 285 if ( ( row.css('display') == 'none' || h === 0 ) && ! row.hasClass('sc_layouts_row_hide_unfixed' ) ) { 286 placeholder.height(0); 287 return; 288 } 289 var ph = row.hasClass( 'sc_layouts_row_fixed_on' ) ? placeholder.outerHeight() : 0; 290 var row_unfixed_placeholder = row.hasClass('sc_layouts_row_hide_unfixed' ) ? row.prev() : false;
291 var delay = trx_addons_cpt_layouts_fix_rows_delay( row ); 292 var animation_off_timeout = trx_addons_cpt_layouts_fix_rows_off_timeout( delay, row ); 293 var time = new Date().getTime(); 294 var last_fixed_time = row.data('trx-addons-last-fixed-time') || 0; 295 if ( time - last_fixed_time < animation_off_timeout ) { 296 return; 297 } 298 var offset = parseInt( row.hasClass( 'sc_layouts_row_fixed_on' ) || row.hasClass( 'sc_layouts_row_fixed_on_pre' ) 299 ? placeholder.offset().top 300 : ( row.hasClass('sc_layouts_row_hide_unfixed' ) 301 ? row_unfixed_placeholder.offset().top 302 : row.offset().top 303 ), 304 10 ); 305 if ( isNaN( offset ) ) { 306 offset = 0; 307 } 308 309 // Unfix row 310 if ( scroll_intent > 1 311 && ( ( force_state == 'off' && row.is( force_row ) ) 312 || ( ! force_state 313 && ( scroll_offset + rows_offset <= offset + delay 314 || ( scroll_offset == 0 && last_scroll_offset > 0 ) 315 || h - ph < -2 316 ) 317 && ( ! row.hasClass( 'sc_layouts_row_fixed_from_start' ) || scroll_offset > 0 ) 318 ) 319 ) 320 ) { 321 if ( row.hasClass( 'sc_layouts_row_fixed_on' ) ) { 322 row.data( 'trx-addons-last-fixed-time', time ); 323 if ( animation_off_timeout > 0 ) { 324 row.addClass( 'sc_layouts_row_fixed_animation_off' ); 325 } 326 setTimeout( function() { 327 var ph = placeholder.outerHeight(); 328 row 329 .removeClass( 'sc_layouts_row_fixed_on' 330 + ( animation_off_timeout > 0 ? ' sc_layouts_row_fixed_animation_off' : '' ) ) 331 .css( { 'top': 'auto' } ); 332 var h = row.outerHeight(); 333 if ( ph != h && ! row.hasClass( 'sc_layouts_row_hide_unfixed' ) ) { 334 ph = h; 335 placeholder.height( h ); 336 } 337 $document.trigger( 'action.sc_layouts_row_fixed_off', [ row ] ); 338 }, animation_off_timeout ); 339 } 340 341 // Fix row 342 } else { 343 if ( ! row.hasClass( 'sc_layouts_row_fixed_on' ) ) { 344 if ( scroll_intent <= 0 //< -1 || ( row.hasClass( 'sc_layouts_row_fixed_from_start' ) && scroll_intent <= 0 ) 345 && ( ( force_state == 'on' && row.is( force_row ) ) 346 || scroll_offset + rows_offset > offset + delay 347 ) 348 ) { 349 var fixed_class = 'sc_layouts_row_fixed_on' + ( ! row.hasClass( 'sc_layouts_row_fixed_from_start' ) && scroll_offset == 0 && scroll_intent == 0 ? '_pre' : '' ); 350 if ( ! row.hasClass( fixed_class ) ) { 351 if ( ! row.hasClass( 'sc_layouts_row_hide_unfixed' ) ) { 352 ph = h; 353 placeholder.height( ph ); 354 } 355 row.addClass( 'sc_layouts_row_fixed_on' + ( ! row.hasClass( 'sc_layouts_row_fixed_from_start' ) && scroll_offset == 0 && scroll_intent == 0 ? '_pre' : '' ) ) 356 .css( { 'top': rows_offset + 'px' } ); 357 h = row.outerHeight(); 358 if ( ph != h && ! row.hasClass( 'sc_layouts_row_hide_unfixed' ) ) { 359 ph = h; 360 placeholder.height( h ); 361 } 362 if ( fixed_class == 'sc_layouts_row_fixed_on' ) { 363 row.data( 'trx-addons-last-fixed-time', time ); 364 $document.trigger( 'action.sc_layouts_row_fixed_on', [ row ] ); 365 } 366 } 367 } else if ( resize ) { 368 h = row.outerHeight(); 369 if ( ph != h && ! row.hasClass( 'sc_layouts_row_hide_unfixed' ) ) { 370 ph = h; 371 placeholder.height( h ); 372 } 373 } 374 } else if ( resize && row.hasClass( 'sc_layouts_row_fixed_on' ) && row.offset().top != rows_offset ) { 375 row.css( { 'top': rows_offset + 'px' } ); 376 } 377 if ( row.css('display') != 'none' ) { 378 rows_offset += h; 379 } 380 } 381 if ( force_state && row.is( force_row ) ) { 382 force_state = ''; 383 force_row = null; 384 } 385 }); 386 } 387 388} );
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.