PageSourceSearch

https://www.berlinstory.de/wp-content/themes/enfold/js/avia-snippet-fold-unfold.js?ver=8.1

js berlinstory.de collected 2026-09-24 09:39:50 UTC 8,558 bytes, 368 lines download raw bytes

1/*
2 * Support to fold/unfold various elements:
3 *		- Textblock
4 *		- Grid Row
5 *		- Sections
6 *
7 *	HTML for fold container is placed before section to fold. This section is moved inside with js in init()
8 *
9 * @since 5.6			added
10 * @by Günter
11 */
12
13"use strict";
14
15//	global namespace
16var avia_js_shortcodes = avia_js_shortcodes || {};
17var aviaJS = aviaJS || {};
18
19(function()
20{
21	if( ! avia_js_shortcodes.aviaFoldUnfoldSection )
22	{
23		class avFoldUnfoldSection
24		{
25			container = null;		//	container element
26			id = '';
27			settings = {};
28			button = [];
29			foldContainer = [];
30			folded = false;
31			preview = false;
32			innerDimension = {};
33
34			//	element specific data
35			textblock = [];
36			multiColumsTextblock = false;
37			gridRow = [];
38			colorSection = [];
39			column = [];
40
41			constructor( container )
42			{
43				this.container = container;
44				this.container.avFoldUnfoldSection = this;
45				this.id = container.getAttribute('id');
46
47				this.init();
48			}
49
50			init()
51			{
52				this.settings = JSON.parse( this.container.dataset.fold_unfold );
53				this.preview = document.getElementById( 'av-admin-preview' ) != null;
54
55				this.moveIntoFoldContainer();
56
57				//	fallback due to missing containers
58				if( ! this.button.length || ! this.foldContainer.length || this.checkMissingInnerContainers() )
59				{
60					return;
61				}
62
63				/**
64				 * Currently we do not allow nesting.
65				 * Remove this to check if we can allow it on complex pages
66				 */
67				if( this.isNested() )
68				{
69					this.container.classList.remove( 'avia-fold-init' );
70					this.foldContainer[0].classList.remove( 'unfolded', 'folded' );
71					this.foldContainer[0].style['max-height'] = 'unset';
72					this.button[0].remove();
73					return;
74				}
75
76				//	ensure initially folded (max-height should be set by post css to avoid jumping of content)
77				this.foldContainer[0].style['max-height'] = this.settings.height + 'px';
78				this.foldContainer[0].classList.add( 'folded' );
79				this.foldContainer[0].classList.remove( 'unfolded' );
80				this.folded = true;
81
82				this.container.classList.add( 'avia-fold-init-done' );
83
84				this.getMaxHeight();
85				this.foldChanged();
86				this.bindEvents();
87
88				this.container.classList.remove( 'avia-fold-init' );
89			}
90
91			moveIntoFoldContainer()
92			{
93				// query child nodes to allow nested elements (e.g. textblock)
94				if( this.container.hasChildNodes() )
95				{
96					let children = this.container.childNodes;
97					for( const child of children )
98					{
99						if( child.classList )
100						{
101							if( child.classList.contains( 'av-fold-unfold-container' ) )
102							{
103								this.foldContainer[0] = child;
104							}
105
106							if( child.classList.contains( 'av-fold-button-wrapper' ) )
107							{
108								const btn = child.getElementsByClassName( 'av-fold-button-container' );
109								if( btn.length )
110								{
111									this.button[0] = btn[0];
112								}
113							}
114						}
115					}
116				}
117
118				let move = null;
119
120				if( this.settings.context == 'avia_sc_text' )
121				{
122					let el = this.foldContainer[0].nextSibling;
123
124					while( el )
125					{
126						if( el.classList && el.classList.contains( 'avia_textblock' ) )
127						{
128							move = el;
129							break;
130						}
131
132						el = el.nextSibling;
133					}
134				}
135				else if( this.settings.context == 'avia_sc_columns' )
136				{
137					let el = this.foldContainer[0].nextSibling;
138					this.column = this.foldContainer[0].getElementsByClassName( 'av-fold-unfold-inner' );
139
140					if( this.column.length )
141					{
142						while( el )
143						{
144							if( el.classList && el.classList.contains( 'av-fold-button-wrapper' ) )
145							{
146								el = el.nextSibling;
147							}
148							else
149							{
150								const next = el.nextSibling;
151								this.column[0].append( el );
152								el = next;
153							}
154						}
155					}
156				}
157				else
158				{
159					const el = this.container.nextSibling;
160					if( el )
161					{
162						move = el;
163					}
164				}
165
166				if( move )
167				{
168					this.foldContainer[0].append( move );
169				}
170			}
171
172			checkMissingInnerContainers()
173			{
174				let retVal = false;
175
176				switch( this.settings.context )
177				{
178					case 'avia_sc_text':
179						this.textblock = this.container.getElementsByClassName( 'avia_textblock' );
180
181						if( this.textblock.length == 0 )
182						{
183							retVal = true;
184						}
185						else
186						{
187							this.multiColumsTextblock = this.textblock[0].classList.contains( 'av_multi_colums' );
188						}
189						break;
190					case 'avia_sc_grid_row':
191						this.gridRow = this.container.getElementsByClassName( 'av-layout-grid-container' );
192
193						if( this.gridRow.length == 0 )
194						{
195							retVal = true;
196						}
197						break;
198					case 'avia_sc_section':
199						this.colorSection = this.container.getElementsByClassName( 'avia-section' );
200
201						if( this.colorSection.length == 0 )
202						{
203							retVal = true;
204						}
205						break;
206					case 'avia_sc_columns':
207						if( ! this.column[0].childNodes.length )
208						{
209							retVal = true;
210						}
211						break;
212					default:
213						//	if we encounter a not supported container we ignore it
214						retVal = true;
215				}
216
217				return retVal;
218			}
219
220			isNested()
221			{
222				const parent = this.container.parentElement;
223
224				if( null == parent )
225				{
226					return false;
227				}
228
229				let closest = parent.closest( '.avia-fold-unfold-section' );
230
231				if( closest == parent )
232				{
233					closest = null;
234				}
235				return closest != null;
236			}
237
238			bindEvents()
239			{
240				this.container.addEventListener( 'transitionend', this.onTransitionEnd.bind( this ) );
241				this.container.addEventListener( 'webkitTransitionEnd', this.onTransitionEnd.bind( this ) );
242
243				this.button[0].addEventListener( 'click', this.onClickFoldUnfold.bind( this ) );
244				window.addEventListener( 'avia_fold_unfold_changed', this.onFoldUnfoldChanged.bind( this ) );
245				window.addEventListener( 'resize', aviaJS.aviaJSHelpers.debounce( this.onResize.bind( this ), 200 ) );
246			}
247
248			getMaxHeight()
249			{
250				switch( this.settings.context )
251				{
252					case 'avia_sc_text':
253						this.innerDimension = this.textblock[0].getBoundingClientRect();
254						break;
255					case 'avia_sc_grid_row':
256						this.innerDimension = this.gridRow[0].getBoundingClientRect();
257						break;
258					case 'avia_sc_section':
259						this.innerDimension = this.colorSection[0].getBoundingClientRect();
260						break;
261					case 'avia_sc_columns':
262						this.innerDimension = this.column[0].getBoundingClientRect();
263						break;
264				}
265			}
266
267			foldChanged()
268			{
269				let btnText = '',
270					btnLink = '';
271
272				if( this.folded )
273				{
274					this.foldContainer[0].style['max-height'] = this.settings.height + 'px';
275					btnText = this.settings.more;
276					btnLink = '#';
277				}
278				else
279				{
280					this.getMaxHeight();
281
282					// add some extra space to be on the safe side
283					this.foldContainer[0].style['max-height'] = Math.ceil( this.innerDimension.height ) + 200 + 'px';
284					btnText = this.settings.less;
285					btnLink += '#' + this.id;
286				}
287
288				this.button[0].setAttribute( 'href', btnLink );
289				this.button[0].textContent = btnText;
290
291				this.triggerHeightChange();
292			}
293
294			onClickFoldUnfold( event )
295			{
296				event.preventDefault();
297				event.stopPropagation();
298
299				if( this.foldContainer[0].classList.contains( 'folded' ) )
300				{
301					this.foldContainer[0].classList.remove( 'folded' );
302					this.foldContainer[0].classList.add( 'unfolded' );
303					this.folded = false;
304				}
305				else
306				{
307					this.foldContainer[0].classList.remove( 'unfolded' );
308					this.foldContainer[0].classList.add( 'folded' );
309					this.folded = true;
310				}
311
312				this.foldChanged();
313
314				let obj = this;
315
316				setTimeout( function()
317				{
318					const opt = {
319								'bubbles':		true,
320								'cancelable':	true,
321								detail:			{ caller: obj }
322							};
323
324					const event = new CustomEvent( 'avia_fold_unfold_changed', opt );
325					obj.container.dispatchEvent( event );
326				}, 500 );
327			}
328
329			onTransitionEnd( event )
330			{
331				//	removes max-height to allow smooth expanding on page load
332				this.container.classList.remove( 'avia-fold-init-done' );
333
334				this.triggerHeightChange();
335			}
336
337			onResize( event )
338			{
339				this.foldChanged();
340			}
341
342			onFoldUnfoldChanged( event )
343			{
344				this.foldChanged();
345			}
346
347			triggerHeightChange()
348			{
349				const opt = {
350							'bubbles':		true,
351							'cancelable':	true
352						};
353
354				const event = new CustomEvent( 'avia_height_change', opt );
355				window.dispatchEvent( event );
356			}
357		}
358
359		//	class factory
360		avia_js_shortcodes.aviaFoldUnfoldSection = function( container )
361		{
362			return new avFoldUnfoldSection( container );
363		};
364
365		aviaJS.aviaPlugins.register( avia_js_shortcodes.aviaFoldUnfoldSection, '.avia-fold-unfold-section' );
366	}
367
368})();

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.