PageSourceSearch

https://www.hamk.fi/wp-content/themes/hamk/hyphenopoly/Hyphenopoly_Loader.js?ver=4.12.0

js hamk.fi collected 2026-09-24 09:16:01 UTC 8,090 bytes, 345 lines download raw bytes

1/**
2 * @license Hyphenopoly_Loader 5.3.0 - client side hyphenation
3 * ©2024  Mathias Nater, Güttingen (mathiasnater at gmail dot com)
4 * https://github.com/mnater/Hyphenopoly
5 *
6 * Released under the MIT license
7 * http://mnater.github.io/Hyphenopoly/LICENSE
8 */
9/* globals Hyphenopoly:readonly */
10window.Hyphenopoly = {};
11
12((w, d, H, o) => {
13	'use strict';
14
15	/**
16	 * Shortcut for new Map
17	 * @param {any} init - initialiser for new Map
18	 * @returns {Map}
19	 */
20	const mp = (init) => {
21		return new Map(init);
22	};
23
24	const scriptName = 'Hyphenopoly_Loader.js';
25	const thisScript = d.currentScript.src;
26	const store = sessionStorage;
27	let mainScriptLoaded = false;
28
29	/**
30	 * The main function runs the feature test and loads Hyphenopoly if
31	 * necessary.
32	 */
33	const main = () => {
34		const shortcuts = {
35			ac: 'appendChild',
36			ce: 'createElement',
37			ct: 'createTextNode',
38		};
39
40		/**
41		 * Create deferred Promise
42		 *
43		 * From http://lea.verou.me/2016/12/resolve-promises-externally-with-
44		 * this-one-weird-trick/
45		 * @return {promise}
46		 */
47		const defProm = () => {
48			let res = null;
49			let rej = null;
50			const promise = new Promise((resolve, reject) => {
51				res = resolve;
52				rej = reject;
53			});
54			promise.resolve = res;
55			promise.reject = rej;
56			return promise;
57		};
58
59		H.ac = new AbortController();
60		const fetchOptions = {
61			credentials: H.s.CORScredentials,
62			signal: H.ac.signal,
63		};
64
65		let stylesNode = null;
66
67		/**
68		 * Define function H.hide.
69		 * This function hides (state = 1) or unhides (state = 0)
70		 * the whole document (mode == 0) or
71		 * each selected element (mode == 1) or
72		 * text of each selected element (mode == 2) or
73		 * nothing (mode == -1)
74		 * @param {integer} state - State
75		 * @param {integer} mode  - Mode
76		 */
77		H.hide = (state, mode) => {
78			if (state) {
79				let vis = '{visibility:hidden!important}';
80				stylesNode = d[shortcuts.ce]('style');
81				let myStyle = '';
82				if (mode === 0) {
83					myStyle = 'html' + vis;
84				} else if (mode !== -1) {
85					if (mode === 2) {
86						vis = '{color:transparent!important}';
87					}
88					o.keys(H.s.selectors).forEach((sel) => {
89						myStyle += sel + vis;
90					});
91				}
92				stylesNode[shortcuts.ac](d[shortcuts.ct](myStyle));
93				d.head[shortcuts.ac](stylesNode);
94			} else if (stylesNode) {
95				stylesNode.remove();
96			}
97		};
98
99		const tester = (() => {
100			let fakeBody = null;
101			return {
102				/**
103				 * Append fakeBody with tests to document
104				 * @returns {Object|null} The body element or null, if no tests
105				 */
106				ap: () => {
107					if (fakeBody) {
108						d.documentElement[shortcuts.ac](fakeBody);
109						return fakeBody;
110					}
111					return null;
112				},
113
114				/**
115				 * Remove fakeBody
116				 * @returns {undefined}
117				 */
118				cl: () => {
119					if (fakeBody) {
120						fakeBody.remove();
121					}
122				},
123
124				/**
125				 * Create and append div with CSS-hyphenated word
126				 * @param {string} lang Language
127				 * @returns {undefined}
128				 */
129				cr: (lang) => {
130					if (H.cf.langs.has(lang)) {
131						return;
132					}
133					fakeBody ||= d[shortcuts.ce]('body');
134					const testDiv = d[shortcuts.ce]('div');
135					const ha = 'hyphens:auto';
136					testDiv.lang = lang;
137					testDiv.style.cssText = `visibility:hidden;-webkit-${ha};-ms-${ha};${ha};width:48px;font-size:12px;line-height:12px;border:none;padding:0;word-wrap:normal`;
138					testDiv[shortcuts.ac](
139						d[shortcuts.ct](H.lrq.get(lang).wo.toLowerCase())
140					);
141					fakeBody[shortcuts.ac](testDiv);
142				},
143			};
144		})();
145
146		/**
147		 * Checks if hyphens (ev.prefixed) is set to auto for the element.
148		 * @param {Object} elm - the element
149		 * @returns {Boolean} result of the check
150		 */
151		const checkCSSHyphensSupport = (elmStyle) => {
152			const h =
153				elmStyle.hyphens ||
154				elmStyle.webkitHyphens ||
155				elmStyle.msHyphens;
156			return h === 'auto';
157		};
158
159		H.res = {
160			he: mp(),
161		};
162
163		/**
164		 * Load hyphenEngines to H.res.he
165		 *
166		 * Make sure each .wasm is loaded exactly once, even for fallbacks
167		 * Store a list of languages to by hyphenated with each .wasm
168		 * @param {string} lang The language
169		 * @returns {undefined}
170		 */
171		const loadhyphenEngine = (lang) => {
172			const fn = H.lrq.get(lang).fn;
173			H.cf.pf = true;
174			H.cf.langs.set(lang, 'H9Y');
175			if (H.res.he.has(fn)) {
176				H.res.he.get(fn).l.push(lang);
177			} else {
178				H.res.he.set(fn, {
179					l: [lang],
180					w: w.fetch(H.paths.patterndir + fn + '.wasm', fetchOptions),
181				});
182			}
183		};
184		H.lrq.forEach((value, lang) => {
185			if (
186				value.wo === 'FORCEHYPHENOPOLY' ||
187				H.cf.langs.get(lang) === 'H9Y'
188			) {
189				loadhyphenEngine(lang);
190			} else {
191				tester.cr(lang);
192			}
193		});
vendor: 1,335 bytes, lines 194-245
194		const testContainer = tester.ap();
195		if (testContainer) {
196			testContainer.querySelectorAll('div').forEach((n) => {
197				if (checkCSSHyphensSupport(n.style) && n.offsetHeight > 12) {
198					H.cf.langs.set(n.lang, 'CSS');
199				} else {
200					loadhyphenEngine(n.lang);
201				}
202			});
203			tester.cl();
204		}
205		const hev = H.hev;
206		if (H.cf.pf) {
207			H.res.DOM = new Promise((res) => {
208				if (d.readyState === 'loading') {
209					d.addEventListener('DOMContentLoaded', res, {
210						once: true,
211						passive: true,
212					});
213				} else {
214					res();
215				}
216			});
217			H.hide(1, H.s.hide);
218			H.timeOutHandler = w.setTimeout(() => {
219				H.hide(0, null);
220				// eslint-disable-next-line no-bitwise
221				if (H.s.timeout & 1) {
222					H.ac.abort();
223				}
224				// eslint-disable-next-line no-console
225				console.info(scriptName + ' timed out.');
226			}, H.s.timeout);
227			if (mainScriptLoaded) {
228				H.main();
229			} else {
230				// Load main script
231				fetch(H.paths.maindir + 'Hyphenopoly.js', fetchOptions).then(
232					(response) => {
233						if (response.ok) {
234							response.blob().then((blb) => {
235								const script = d[shortcuts.ce]('script');
236								script.src = URL.createObjectURL(blb);
237								d.head[shortcuts.ac](script);
238								mainScriptLoaded = true;
239								URL.revokeObjectURL(script.src);
240							});
241						}
242					}
243				);
244			}
245			H.hy6ors = mp();
246			H.cf.langs.forEach((langDef, lang) => {
247				if (langDef === 'H9Y') {
248					H.hy6ors.set(lang, defProm());
249				}
250			});
251			H.hy6ors.set('HTML', defProm());
252			H.hyphenators = new Proxy(H.hy6ors, {
253				get: (target, key) => {
254					return target.get(key);
255				},
256				set: () => {
257					// Inhibit setting of hyphenators
258					return true;
259				},
260			});
261			(() => {
262				if (hev && hev.polyfill) {
263					hev.polyfill();
264				}
265			})();
266		} else {
267			(() => {
268				if (hev && hev.tearDown) {
269					hev.tearDown();
270				}
271				w.Hyphenopoly = null;
272			})();
273		}
274		(() => {
275			if (H.cft) {
276				store.setItem(
277					scriptName,
278					JSON.stringify({
279						langs: [...H.cf.langs.entries()],
280						pf: H.cf.pf,
281					})
282				);
283			}
284		})();
285	};
286
287	H.config = (c) => {
288		/**
289		 * Sets default properties for an Object
290		 * @param {object} obj - The object to set defaults to
291		 * @param {object} defaults - The defaults to set
292		 * @returns {object}
293		 */
294		const setDefaults = (obj, defaults) => {
295			if (obj) {
296				o.entries(defaults).forEach(([k, v]) => {
297					// eslint-disable-next-line security/detect-object-injection
298					obj[k] ||= v;
299				});
300				return obj;
301			}
302			return defaults;
303		};
304
305		H.cft = Boolean(c.cacheFeatureTests);
306		if (H.cft && store.getItem(scriptName)) {
307			H.cf = JSON.parse(store.getItem(scriptName));
308			H.cf.langs = mp(H.cf.langs);
309		} else {
310			H.cf = {
311				langs: mp(),
312				pf: false,
313			};
314		}
315
316		const maindir = thisScript.slice(0, thisScript.lastIndexOf('/') + 1);
317		const patterndir = maindir + 'patterns/';
318		H.paths = setDefaults(c.paths, {
319			maindir,
320			patterndir,
321		});
322		H.s = setDefaults(c.setup, {
323			CORScredentials: 'include',
324			hide: 'all',
325			selectors: { '.hyphenate': {} },
326			timeout: 1000,
327		});
328		// Change mode string to mode int
329		H.s.hide = ['all', 'element', 'text'].indexOf(H.s.hide);
330		if (c.handleEvent) {
331			H.hev = c.handleEvent;
332		}
333
334		const fallbacks = mp(o.entries(c.fallbacks || {}));
335		H.lrq = mp();
336		o.entries(c.require).forEach(([lang, wo]) => {
337			H.lrq.set(lang.toLowerCase(), {
338				fn: fallbacks.get(lang) || lang,
339				wo,
340			});
341		});
342
343		main();
344	};
345})(window, document, Hyphenopoly, Object);

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.