PageSourceSearch

https://shopdrexelu.com/mm5/json.mvc?Store_Code=MSRH&Function=Java…=mmx-image-across&T=e9451a8d

js shopdrexelu.com collected 2026-10-06 19:14:16 UTC 5,443 bytes, 248 lines download raw bytes

1/**
2 * MMX / IMAGE ACROSS
3 */
4class MMX_ImageAcross extends MMX_Element {
5	#auto_image_height;
6	#scroll_position;
7	#resize_observer;
8	#intersection_observer;
9
10	static get props() {
11		return {
12			align: {
13				options: [
14					'left',
15					'center',
16					'right'
17				],
18				default: 'center'
19			},
20			size: {
21				options: [
22					'auto',
23					's',
24					'm',
25					'l'
26				],
27				allowAny: true,
28				default: 'auto'
29			},
30			images: {
31				allowAny: true,
32				default: null
33			},
34			columns: {
35				options: [
36					'auto',
37					'1',
38					'2',
39					'3',
40					'4',
41					'5',
42					'6',
43					'7',
44					'8'
45				],
46				allowAny: true,
47				default: 'auto',
48				max: 8
49			},
50			overflow: {
51				options: [
52					'scroll',
53					'wrap'
54				],
55				default: 'scroll'
56			}
57		};
58	}
59
60	styleResourceCodes = ['mmx-base', 'mmx-button', 'mmx-hero', 'mmx-image-across'];
61
62	constructor() {
63		super();
64		this.makeShadow();
65		this.#scroll_position		= 0;
66		this.#resize_observer		= new ResizeObserver(entries => this.setScrollPosition());
67		this.#intersection_observer	= new IntersectionObserver(entries => {this.calculateScrollPosition();}, { rootMargin: '100% 0%', threshold: 0 });
68	}
69
70	render() {
71		return /*html*/`
72			<div part="wrapper" class="mmx-image-across">
73				<div part="title" class="mmx-image-across__title">
74					<slot name="title"></slot>
75				</div>
76				<div part="images" class="mmx-image-across__images mmx-image-across__images-columns--${this.maxColumns()} mmx-image-across__images-overflow--${this.getPropValue('overflow')}">
77					${this.renderImages()}
78					<slot name="image"></slot>
79				</div>
80			</div>
81		`;
82	}
83
84	afterRender() {
85		this.setImageHeight();
86		this.#resize_observer.observe(this.shadowImagesContainer());
87		this.slottedImages().forEach(image => {this.#intersection_observer.observe(image);});
88	}
89
90	styles() {
91		return /*css*/`
92			:host {
93				--mmx-image-across__text-align: ${this.getPropValue('align')};
94				--mmx-image-across__columns: ${this.maxColumns()};
95				--mmx-image-across__image-count: ${this.getImageCount()};
96			}
97		`;
98	}
99
100	images() {
101		return this.loadPropertyData('images') || [];
102	}
103
104	slottedImages() {
105		return this.querySelectorAll(':scope > [slot="image"]');
106	}
107
108	shadowImages() {
109		return this.shadowRoot.querySelectorAll('[part="image"]');
110	}
111
112	shadowImagesContainer() {
113		return this.shadowRoot.querySelector('[part="images"]');
114	}
115
116	imageElements() {
117		return [...this.shadowImages(), ...this.slottedImages()];
118	}
119
120	renderImages() {
121		return this.images().map((image => {
122			return this.createElement({
123				type: 'mmx-hero',
124				attributes: {
125					part: 'image',
126					...image
127				}
128			}).outerHTML;
129		})).join('');
130	}
131
132	getImageCount() {
133		const slottedImageCount = this.slottedImages().length;
134		return this.images().length + slottedImageCount;
135	}
136
137	maxColumns() {
138		const columns = this.getPropValue('columns');
139
140		if (columns !== 'auto') {
141			return isNaN(columns) ? columns : Number(columns);
142		}
143
144		const imageCount = this.getImageCount();
145		if (imageCount < this.constructor.props.columns.max) {
146			return imageCount;
147		}
148
149		return this.constructor.props.columns.max;
150	}
151
152	getSize() {
153		const size = this.getPropValue('size');
154		if (size === 'auto') {
155			return this.#auto_image_height + 'px';
156		} else {
157			return size;
158		}
159	}
160
161	setImageHeight() {
162		if (this.getPropValue('size') !== 'auto') {
163			return this.updateImageHeight(this.getPropValue('size'));
164		}
165
166		this.#auto_image_height = 0;
167
168		this.imageElements().forEach(image => {
169			const img = image?.slottedImage?.() ?? image?.shadowImage?.();
170
171			if (img?.complete) {
172				return this.checkLoadedImage(img);
173			}
174
175			image.addEventListener('img:load', this.#event_image_load);
176		});
177	}
178
179	#event_image_load = (e) => {
180		this.checkLoadedImage(e.detail.element);
181	};
182
183	checkLoadedImage(image) {
184		const last_auto_image_height = this.#auto_image_height;
185
186		this.calculateMinImageHeight(this.getResponsiveImageHeight(image));
187
188		if (last_auto_image_height !== this.#auto_image_height) {
189			this.updateImageHeight(this.#auto_image_height + 'px');
190		}
191
192		this.#updateRenderStatus();
193	}
194
195	#updateRenderStatus() {
196		if (this.imageLoadedCount === this.getImageCount()) {
197			this.classList.add('mmx-image-across--images-loaded');
198		} else {
199			this.classList.remove('mmx-image-across--images-loaded');
200		}
201	}
202
203	get imageLoadedCount() {
204		const loadedImages = this.imageElements().filter(image => {
205			const img = image?.slottedImage?.() ?? image?.shadowImage?.();
206			return img?.complete;
207		});
208
209		return loadedImages.length;
210	}
211
212	updateImageHeight(size) {
213		this.imageElements().forEach(image => {
214			image.setAttribute('data-size', size);
215		});
216	}
217
218	calculateMinImageHeight(height)
219	{
220		if (this.#auto_image_height === 0) {
221			this.#auto_image_height = height;
222		}
223		else if (height < this.#auto_image_height) {
224			this.#auto_image_height = height;
225		}
226	}
227
228	calculateScrollPosition()
229	{
230		const image_container	= this.shadowImagesContainer().scrollWidth;
231		const image_position	= this.shadowImagesContainer().scrollLeft;
232		const position_percent	= image_position / image_container;
233
234		this.#scroll_position = position_percent;
235	}
236
237	setScrollPosition()
238	{
239		const image_container	= this.shadowImagesContainer().scrollWidth;
240		const new_position 		= this.#scroll_position * image_container;
241
242		this.shadowImagesContainer().scrollLeft	= new_position;
243	}
244}
245
246if (!customElements.get('mmx-image-across')){
247	customElements.define('mmx-image-across', MMX_ImageAcross);
248}

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.