PageSourceSearch

https://www.cookshack.com/mm5/json.mvc?Store_Code=CS&Function=Java…JavaScriptResource_Code=mmx-text&T=805101bc

js cookshack.com collected 2026-09-26 02:31:49 UTC 6,225 bytes, 316 lines download raw bytes

1/**
2 * MMX / TEXT
3 */
4class MMX_Text extends MMX_Element {
5
6	static get props() {
7		return {
8			align: {
9				options: [
10					'left',
11					'center',
12					'right'
13				],
14				default: 'unset'
15			},
16			tag: {
17				options: [
18					'h1',
19					'h2',
20					'h3',
21					'h4',
22					'h5',
23					'h6',
24					'p',
25					'div',
26					'span'
27				],
28				default: 'div'
29			},
30			theme: {
31				allowAny: true,
32				isBoolean: true,
33				default: false
34			},
35			'theme-class': {
36				allowAny: true,
37				default: ''
38			},
39			style: {
40				options: [
41					'display-1',
42					'display-2',
43					'display-3',
44					'title-1',
45					'title-2',
46					'title-3',
47					'title-4',
48					'subheading-l',
49					'subheading-s',
50					'subheading-xs',
51					'paragraph-l',
52					'paragraph-s',
53					'paragraph-xs',
54					'call-to-action'
55				],
56				allowAny: true,
57				default: 'paragraph-s'
58			},
59			'chars-per-line': {
60				options: [
61					'auto',
62					'ideal',
63					'none'
64				],
65				default: 'auto',
66				allowAny: true
67			},
68			'max-words': {
69				allowAny: true,
70				isNumeric: true
71			},
72			'max-chars': {
73				allowAny: true,
74				isNumeric: true
75			},
76			'trim-suffix': {
77				options: [
78					'',
79					'...'
80				],
81				default: '',
82				allowAny: true
83			},
84			dom: {
85				options: ['light', 'shadow'],
86				default: 'light'
87			},
88			source: {
89				options: ['markdown'],
90				default: '',
91				allowAny: true
92			},
93			'hide-on-empty': {
94				allowAny: true,
95				isBoolean: true,
96				default: true
97			},
98			spacing: {
99				options: ['auto', 'none'],
100				default: 'auto'
101			}
102		};
103	}
104
105	styleResourceCodes = ['mmx-base', 'mmx-text', 'mm-theme-styles'];
106
107	copyTypes = [
108		'paragraph-l',
109		'paragraph-s',
110		'paragraph-xs',
111		'call-to-action'
112	];
113
114	headingTagToStyle = {
115		h1: 'display-2',
116		h2: 'display-3',
117		h3: 'title-1',
118		h4: 'title-2',
119		h5: 'title-3',
120		h6: 'title-4'
121	};
122
123	idealCharsPerLine = 28; // An ideal count for larger fonts like headings & promo content
124
125	constructor() {
126		super();
127		this.makeComponent();
128	}
129
130	render() {
131		const theme = this.getPropValue('theme');
132
133		if (theme)	return this.#renderTheme();
134		else		return this.#renderLegacy();
135	}
136
137	get hideOnEmpty() {
138		return this.getPropValue('hide-on-empty');
139	}
140
141	#renderLegacy() {
142		const tag = this.getPropValue('tag');
143		const legacy_styles = this.#renderLegacyStyles();
144
145		if (legacy_styles?.length) {
146			this.setAttribute('style', legacy_styles);
147		}
148
149		return /*html*/`
150			<${tag} class="mmx-text type-${this.getStyleProp()}
150 ${this.getStyleState()} ${this.#getSpacingClass()}" part="text" ${this.inheritAttrs()}>
151				<span class="mmx-text__inner" part="text__inner">
152					${this.renderContent()}
153				</span>
154			</${tag}>
155		`;
156	}
157
158	#renderLegacyStyles() {
159		return this.querySelector(':scope > template[data-legacy-styles]')?.content?.textContent?.trim?.() ?? '';
160	}
161
162	#renderTheme() {
163		const tag = this.getPropValue('tag');
164		const theme_class = this.getPropValue('theme-class');
165
166		return /*html*/`
167			${this.#renderThemeStylesheet()}
168			<${tag} class="mmx-theme-text ${MMX.encodeEntities(theme_class)} ${this.#getSpacingClass()}" ${this.inheritAttrs()}>
169				<span class="mmx-text__inner" part="text__inner">
170					${this.renderContent()}
171				</span>
172			</${tag}>
173		`;
174	}
175
176	#renderThemeStylesheet() {
177		const theme_stylesheet = this.querySelector(':scope > template[data-theme-stylesheet]');
178
179		if (!theme_stylesheet) {
180			return '';
181		}
182
183		return /*html*/`
184			<style type="text/css">
185				${theme_stylesheet.content.textContent}
186			</style>
187		`;
188	}
189
190	styles() {
191		return /*css*/`
192			:host {
193				--mmx-text__inner--max-width: ${this.getInnerMaxWidth()};
194				--mmx-text__text-align: ${this.getPropValue('align')};
195			}
196
197			${this.shadowDomStyles()}
198		`;
199	}
200
201	shadowDomStyles() {
202		const style = this.getAttribute('style');
203
204		if (!style || !this.shouldRenderInShadowDom()) {
205			return '';
206		}
207
208		return /*css*/`
209			:where(h1, h2, h3, h4, h5, h6) {
210				${style};
211			}
212		`;
213	}
214
215	renderContent() {
216		const maxChars = this.getPropValue('max-chars');
217		const maxWords = this.getPropValue('max-words');
218
219		if (typeof maxChars === 'number') {
220			return this.renderContentByMaxChars(maxChars);
221		}
222
223		return this.renderContentByMaxWords(maxWords);
224	}
225
226	renderContentByMaxChars(maxChars) {
227		return this.renderMaxContent(maxChars, '', '');
228	}
229
230	renderContentByMaxWords(maxWords) {
231		return this.renderMaxContent(maxWords, /\s+/, ' ');
232	}
233
234	renderMaxContent(maxCount = 0, splitOn = '', joinWith = '') {
235		const parts = this.textContent.trim().split(splitOn);
236		if (typeof maxCount === 'undefined' || maxCount === 0 || parts.length <= maxCount) {
237			return this.renderSlottedContent();
238		}
239
240		const trimmedParts = parts.slice(0, maxCount).join(joinWith);
241		return trimmedParts + this.getPropValue('trim-suffix');
242	}
243
244	shouldRenderInShadowDom() {
245		return this.getPropValue('source') === 'markdown' || this.getPropValue('dom') === 'shadow';
246	}
247
248	renderSlottedContent() {
249		if (this.shouldRenderInShadowDom()) {
250			return this.innerHTML;
251		}
252
253		return '<slot></slot>';
254	}
255
256	getInnerMaxWidth() {
257		const charsPerLine = this.getPropValue('chars-per-line');
258
259		if (charsPerLine === 'none') {
260			return 'unset';
261		}
262		else if (charsPerLine === 'ideal') {
263			return this.idealCharsPerLine + 'ch';
264		}
265		else if (charsPerLine === 'auto') {
266			const type = this.getPropValue('style');
267			const isCopyType = this.copyTypes.includes(type);
268
269			if (isCopyType) {
270				return 'unset';
271			} else {
272				return this.idealCharsPerLine + 'ch';
273			}
274		}
275		else if (!isNaN(charsPerLine)) {
276			return charsPerLine + 'ch';
277		}
278
279		return charsPerLine;
280	}
281
282	getStyleWithoutDefault() {
283		if (this.hasPropValue('style')) {
284			return this.getPropValue('style');
285		}
286
287		if (this.hasPropValue('tag')) {
288			const tag = this.getPropValue('tag');
289			if (tag in this.headingTagToStyle) {
290				return this.headingTagToStyle[tag];
291			}
292		}
293
294		return '';
295	}
296
297	getStyleProp() {
298		return this.getStyleWithoutDefault() || MMX_Text.props.style.default;
299	}
300
301	getStyleState() {
302		if (this.getStyleWithoutDefault()) {
303			return 'mmx-text--styled';
304		}
305
306		return 'mmx-text--unstyled';
307	}
308
309	#getSpacingClass() {
310		return 'mmx-text__spacing--' + this.getPropValue('spacing');
311	}
312}
313
314if (!customElements.get('mmx-text')) {
315	customElements.define('mmx-text', MMX_Text);
316}

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.