PageSourceSearch

https://haeseler-kabeltechnik.de/site/theme/assets/js/util.js

js haeseler-kabeltechnik.de collected 2026-10-08 22:04:33 UTC 12,498 bytes, 590 lines download raw bytes

1(function($) {
2
3	/**
4	 * Generate an indented list of links from a nav. Meant for use with panel().
5	 * @return {jQuery} jQuery object.
6	 */
7	$.fn.navList = function() {
8
9		var	$this = $(this);
10			$a = $this.find('a'),
11			b = [];
12
13		$a.each(function() {
14
15			var	$this = $(this),
16				indent = Math.max(0, $this.parents('li').length - 1),
17				href = $this.attr('href'),
18				target = $this.attr('target');
19
20			b.push(
21				'<a ' +
22					'class="link depth-' + indent + '"' +
23					( (typeof target !== 'undefined' && target != '') ? ' target="' + target + '"' : '') +
24					( (typeof href !== 'undefined' && href != '') ? ' href="' + href + '"' : '') +
25				'>' +
26					'<span class="indent-' + indent + '"></span>' +
27					$this.text() +
28				'</a>'
29			);
30
31		});
32
33		return b.join('');
34
35	};
36
37	/**
38	 * Panel-ify an element.
39	 * @param {object} userConfig User config.
40	 * @return {jQuery} jQuery object.
41	 */
42	$.fn.panel = function(userConfig) {
43
44		// No elements?
45			if (this.length == 0)
46				return $this;
47
48		// Multiple elements?
49			if (this.length > 1) {
50
51				for (var i=0; i < this.length; i++)
52					$(this[i]).panel(userConfig);
53
54				return $this;
55
56			}
57
58		// Vars.
59			var	$this = $(this),
60				$body = $('body'),
61				$window = $(window),
62				id = $this.attr('id'),
63				config;
64
65		// Config.
66			config = $.extend({
67
68				// Delay.
69					delay: 0,
70
71				// Hide panel on link click.
72					hideOnClick: false,
73
74				// Hide panel on escape keypress.
75					hideOnEscape: false,
76
77				// Hide panel on swipe.
78					hideOnSwipe: false,
79
80				// Reset scroll position on hide.
81					resetScroll: false,
82
83				// Reset forms on hide.
84					resetForms: false,
85
86				// Side of viewport the panel will appear.
87					side: null,
88
89				// Target element for "class".
90					target: $this,
91
92				// Class to toggle.
93					visibleClass: 'visible'
94
95			}, userConfig);
96
97			// Expand "target" if it's not a jQuery object already.
98				if (typeof config.target != 'jQuery')
99					config.target = $(config.target);
100
101		// Panel.
102
103			// Methods.
104				$this._hide = function(event) {
105
106					// Already hidden? Bail.
107						if (!config.target.hasClass(config.visibleClass))
108							return;
109
110					// If an event was provided, cancel it.
111						if (event) {
112
113							event.preventDefault();
114							event.stopPropagation();
115
116						}
117
118					// Hide.
119						config.target.removeClass(config.visibleClass);
120
121					// Post-hide stuff.
122						window.setTimeout(function() {
123
124							// Reset scroll position.
125								if (config.resetScroll)
126									$this.scrollTop(0);
127
128							// Reset forms.
129								if (config.resetForms)
130									$this.find('form').each(function() {
131										this.reset();
132									});
133
134						}, config.delay);
135
136				};
137
138			// Vendor fixes.
139				$this
140					.css('-ms-overflow-style', '-ms-autohiding-scrollbar')
141					.css('-webkit-overflow-scrolling', 'touch');
142
143			// Hide on click.
144				if (config.hideOnClick) {
145
146					$this.find('a')
147						.css('-webkit-tap-highlight-color', 'rgba(0,0,0,0)');
148
149					$this
150						.on('click', 'a', function(event) {
151
152							if(window.innerWidth < 961) {
153								return;
154							}
155							var $a = $(this),
156								href = $a.attr('href'),
157								target = $a.attr('target');
158
159							if (!href || href == '#' || href == '' || href == '#' + id)
160								return;
161
162							// Cancel original event.
163								event.preventDefault();
164								event.stopPropagation();
165
166							// Hide panel.
167								$this._hide();
168
169							// Redirect to href.
170								window.setTimeout(function() {
171
172									if (target == '_blank')
173										window.open(href);
174									else
175										window.location.href = href;
176
177								}, config.delay + 10);
178
179						});
180
181				}
182
183			// Event: Touch stuff.
184				$this.on('touchstart', function(event) {
185
186					$this.touchPosX = event.originalEvent.touches[0].pageX;
187					$this.touchPosY = event.originalEvent.touches[0].pageY;
188
189				})
190
191				$this.on('touchmove', function(event) {
192
193					if ($this.touchPosX === null
194					||	$this.touchPosY === null)
195						return;
196
197					var	diffX = $this.touchPosX - event.originalEvent.touches[0].pageX,
198						diffY = $this.touchPosY - event.originalEvent.touches[0].pageY,
199						th = $this.outerHeight(),
200						ts = ($this.get(0).scrollHeight - $this.scrollTop());
201
202					// Hide on swipe?
203						if (config.hideOnSwipe) {
204
205							var result = false,
206								boundary = 20,
207								delta = 50;
208
209							switch (config.side) {
210
211								case 'left':
212									result = (diffY < boundary && diffY >
212 (-1 * boundary)) && (diffX > delta);
213									break;
214
215								case 'right':
216									result = (diffY < boundary && diffY > (-1 * boundary)) && (diffX < (-1 * delta));
217									break;
218
219								case 'top':
220									result = (diffX < boundary && diffX > (-1 * boundary)) && (diffY > delta);
221									break;
222
223								case 'bottom':
224									result = (diffX < boundary && diffX > (-1 * boundary)) && (diffY < (-1 * delta));
225									break;
226
227								default:
228									break;
229
230							}
231
232							if (result) {
233
234								$this.touchPosX = null;
235								$this.touchPosY = null;
236								$this._hide();
237
238								return false;
239
240							}
241
242						}
243
244					// Prevent vertical scrolling past the top or bottom.
245						if (($this.scrollTop() < 0 && diffY < 0)
246						|| (ts > (th - 2) && ts < (th + 2) && diffY > 0)) {
247
248							event.preventDefault();
249							event.stopPropagation();
250
251						}
252
253				});
254
255			// Event: Prevent certain events inside the panel from bubbling.
256				$this.on('click touchend touchstart touchmove', function(event) {
257					event.stopPropagation();
258				});
259
260			// Event: Hide panel if a child anchor tag pointing to its ID is clicked.
261				$this.on('click', 'a[href="#' + id + '"]', function(event) {
262
263					event.preventDefault();
264					event.stopPropagation();
265
266					config.target.removeClass(config.visibleClass);
267
268				});
269
270		// Body.
271
272			// Event: Hide panel on body click/tap.
273				$body.on('click touchend', function(event) {
274					$this._hide(event);
275				});
276
277			// Event: Toggle.
278				$body.on('click', 'a[href="#' + id + '"]', function(event) {
279
280					event.preventDefault();
281					event.stopPropagation();
282
283					config.target.toggleClass(config.visibleClass);
284
285				});
286
287		// Window.
288
289			// Event: Hide on ESC.
290				if (config.hideOnEscape)
291					$window.on('keydown', function(event) {
292
293						if (event.keyCode == 27)
294							$this._hide(event);
295
296					});
297
298		return $this;
299
300	};
301
302	/**
303	 * Apply "placeholder" attribute polyfill to one or more forms.
304	 * @return {jQuery} jQuery object.
305	 */
306	$.fn.placeholder = function() {
307
308		// Browser natively supports placeholders? Bail.
309			if (typeof (document.createElement('input')).placeholder != 'undefined')
310				return $(this);
311
312		// No elements?
313			if (this.length == 0)
314				return $this;
315
316		// Multiple elements?
317			if (this.length > 1) {
318
319				for (var i=0; i < this.length; i++)
320					$(this[i]).placeholder();
321
322				return $this;
323
324			}
325
326		// Vars.
327			var $this = $(this);
328
329		// Text, TextArea.
330			$this.find('input[type=text],textarea')
331				.each(function() {
332
333					var i = $(this);
334
335					if (i.val() == ''
336					||  i.val() == i.attr('placeholder'))
337						i
338							.addClass('polyfill-placeholder')
339							.val(i.attr('placeholder'));
340
341				})
342				.on('blur', function() {
343
344					var i = $(this);
345
346					if (i.attr('name').match(/-polyfill-field$/))
347						return;
348
349					if (i.val() == '')
350						i
351							.addClass('polyfill-placeholder')
352							.val(i.attr('placeholder'));
353
354				})
355				.on('focus', function() {
356
357					var i = $(this);
358
359					if (i.attr('name').match(/-polyfill-field$/))
360						return;
361
362					if (i.val() == i.attr('placeholder'))
363						i
364							.removeClass('polyfill-placeholder')
365							.val('');
366
367				});
368
369		// Password.
370			$this.find('input[type=password]')
371				.each(function() {
372
373					var i = $(this);
374					var x = $(
375								$('<div>')
376									.append(i.clone())
377									.remove()
378									.html()
379									.replace(/type="password"/i, 'type="text"')
380									.replace(/type=password/i, 'type=text')
381					);
382
383					if (i.attr('id') != '')
384						x.attr('id', i.attr('id') + '-polyfill-field');
385
386					if (i.attr('name') != '')
387						x.attr('name', i.attr('name') + '-polyfill-field');
388
389					x.addClass('polyfill-placeholder')
390						.val(x.attr('placeholder')).insertAfter(i);
391
392					if (i.val() == '')
393						i.hide();
394					else
395						x.hide();
396
397					i
398						.on('blur', function(event) {
399
400							event.preventDefault();
401
402							var x = i.parent().find('input[name=' + i.attr('name') + '-polyfill-field]');
403
404							if (i.val() == '') {
405
406								i.hide();
407								x.show();
408
409							}
410
411						});
412
413					x
414						.on('focus', function(event) {
415
416							event.preventDefault();
417
418							var i = x.parent().find('input[name=' + x.attr('name').replace('-polyfill-field', '') + ']');
419
420							x.hide();
421
422							i
423								.show()
424								.focus();
425
426						})
427						.on('keypress', function(event) {
428
429							event.preventDefault();
430							x.val('');
431
432						});
433
434				});
435
436		// Events.
437			$this
438				.on('submit', function() {
439
440					$this.find('input[type=text],input[type=password],textarea')
441						.each(function(event) {
442
443							var i = $(this);
444
445							if (i.attr('name').match(/-polyfill-field$/))
446								i.attr('name', '');
447
448							if (i.val() == i.attr('placeholder')) {
449
450								i.removeClass('polyfill-placeholder');
451								i.val('');
452
453							}
454
455						});
456
457				})
458				.on('reset', function(event) {
459
460					event.preventDefault();
461
462					$this.find('select')
463						.val($('option:first').val());
464
465					$this.find('input,textarea')
466						.each(function() {
467
468							var i = $(this),
469								x;
470
471							i.removeClass('polyfill-placeholder');
472
473							switch (this.type) {
474
475								case 'submit':
476								case 'reset':
477									break;
478
479								case 'password':
480									i.val(i.attr('defaultValue'));
481
482									x = i.parent().find('input[name=' + i.attr('name') + '-polyfill-field]');
483
484									if (i.val() == '') {
485										i.hide();
486										x.show();
487									}
488									else {
489										i.show();
490										x.hide();
491									}
492
493									break;
494
495								case 'checkbox':
496								case 'radio':
497									i.attr('checked', i.attr('defaultValue'));
498									break;
499
500								case 'text':
501								case 'textarea':
502									i.val(i.attr('defaultValue'));
503
504									if (i.val() == '') {
505										i.addClass('polyfill-placeholder');
506										i.val(i.attr('placeholder'));
507									}
508
509									break;
510
511								default:
512									i.val(i.attr('defaultValue'));
513									break;
514
515							}
516						});
517
518				});
519
520		return $this;
521
522	};
523
524	/**
525	 * Moves elements to/from the first positions of their respective parents.
526	 * @param {jQuery} $elements Elements (or selector) to move.
527	 * @param {bool} condition If true, moves elements to the top. Otherwise, moves elements back to their original locations.
528	 */
529	$.prioritize = function($elements, condition) {
530
531		var key = '__prioritize';
532
533		// Expand $elements if it's not already a jQuery object.
534			if (typeof $elements != 'jQuery')
535				$elements = $($elements);
536
537		// Step through elements.
538			$elements.each(function() {
539
540				var	$e = $(this), $p,
541					$parent = $e.parent();
542
543				// No parent? Bail.
544					if ($parent.length == 0)
545						return;
546
547				// Not moved? Move it.
548					if (!$e.data(key)) {
549
550						// Condition is false? Bail.
551							if (!condition)
552								return;
553
554						// Get placeholder (which will serve as our point of reference for when this element needs to move back).
555							$p = $e.prev();
556
557							// Couldn't find anything? Means this element's already at the top, so bail.
558								if ($p.length == 0)
559									return;
560
561						// Move element to top of parent.
562							$e.prependTo($parent);
563
564						// Mark element as moved.
565							$e.data(key, $p);
566
567					}
568
569				// Moved already?
570					else {
571
572						// Condition is true? Bail.
573							if (condition)
574								return;
575
576						$p = $e.data(key);
577
578						// Move element back to its original location (using our placeholder).
579							$e.insertAfter($p);
580
581						// Unmark element as moved.
582							$e.removeData(key);
583
584					}
585
586			});
587
588	};
589
590})(jQuery);

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.