vendor: 11,407 bytes, lines 1-349
1/** 2 * @license Hyphenopoly_Loader 5.1.0 - client side hyphenation 3 * ©2023 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 === 0) { 79 if (stylesNode) { 80 stylesNode.remove(); 81 } 82 } else { 83 let vis = "{visibility:hidden!important}"; 84 stylesNode = d[shortcuts.ce]("style"); 85 let myStyle = ""; 86 if (mode === 0) { 87 myStyle = "html" + vis; 88 } else if (mode !== -1) { 89 if (mode === 2) { 90 vis = "{color:transparent!important}"; 91 } 92 o.keys(H.s.selectors).forEach((sel) => { 93 myStyle += sel + vis; 94 }); 95 } 96 stylesNode[shortcuts.ac](d[shortcuts.ct](myStyle)); 97 d.head[shortcuts.ac](stylesNode); 98 } 99 }; 100 101 const tester = (() => { 102 let fakeBody = null; 103 return { 104 105 /** 106 * Append fakeBody with tests to document 107 * @returns {Object|null} The body element or null, if no tests 108 */ 109 "ap": () => { 110 if (fakeBody) { 111 d.documentElement[shortcuts.ac](fakeBody); 112 return fakeBody; 113 } 114 return null; 115 }, 116 117 /** 118 * Remove fakeBody 119 * @returns {undefined} 120 */ 121 "cl": () => { 122 if (fakeBody) { 123 fakeBody.remove(); 124 } 125 }, 126 127 /** 128 * Create and append div with CSS-hyphenated word 129 * @param {string} lang Language 130 * @returns {undefined} 131 */ 132 "cr": (lang) => { 133 if (H.cf.langs.has(lang)) { 134 return; 135 } 136 fakeBody = fakeBody || d[shortcuts.ce]("body"); 137 const testDiv = d[shortcuts.ce]("div"); 138 const ha = "hyphens:auto"; 139 testDiv.lang = lang; 140 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`; 141 testDiv[shortcuts.ac]( 142 d[shortcuts.ct](H.lrq.get(lang).wo.toLowerCase()) 143 ); 144 fakeBody[shortcuts.ac](testDiv); 145 } 146 }; 147 })(); 148 149 /** 150 * Checks if hyphens (ev.prefixed) is set to auto for the element. 151 * @param {Object} elm - the element 152 * @returns {Boolean} result of the check 153 */ 154 const checkCSSHyphensSupport = (elmStyle) => { 155 const h = elmStyle.hyphens || 156 elmStyle.webkitHyphens || 157 elmStyle.msHyphens; 158 return (h === "auto"); 159 }; 160 161 H.res = { 162 "he": mp() 163 }; 164 165 /** 166 * Load hyphenEngines to H.res.he 167 * 168 * Make sure each .wasm is loaded exactly once, even for fallbacks 169 * Store a list of languages to by hyphenated with each .wasm 170 * @param {string} lang The language 171 * @returns {undefined} 172 */ 173 const loadhyphenEngine = (lang) => { 174 const fn = H.lrq.get(lang).fn; 175 H.cf.pf = true; 176 H.cf.langs.set(lang, "H9Y"); 177 if (H.res.he.has(fn)) { 178 H.res.he.get(fn).l.push(lang); 179 } else { 180 H.res.he.set( 181 fn, 182 { 183 "l": [lang], 184 "w": w.fetch(H.paths.patterndir + fn + ".wasm", fetchOptions) 185 } 186 ); 187 } 188 }; 189 H.lrq.forEach((value, lang) => { 190 if (value.wo === "FORCEHYPHENOPOLY" || H.cf.langs.get(lang) === "H9Y") { 191 loadhyphenEngine(lang); 192 } else { 193 tester.cr(lang); 194 } 195 }); 196 const testContainer = tester.ap(); 197 if (testContainer) { 198 testContainer.querySelectorAll("div").forEach((n) => { 199 if (checkCSSHyphensSupport(n.style) && n.offsetHeight > 12) { 200 H.cf.langs.set(n.lang, "CSS"); 201 } else { 202 loadhyphenEngine(n.lang); 203 } 204 }); 205 tester.cl(); 206 } 207 const hev = H.hev; 208 if (H.cf.pf) { 209 H.res.DOM = new Promise((res) => { 210 if (d.readyState === "loading") { 211 d.addEventListener( 212 "DOMContentLoaded", 213 res, 214 { 215 "once": true, 216 "passive": true 217 } 218 ); 219 } else { 220 res(); 221 } 222 }); 223 H.hide(1, H.s.hide); 224 H.timeOutHandler = w.setTimeout(() => { 225 H.hide(0, null); 226 // eslint-disable-next-line no-bitwise 227 if (H.s.timeout & 1) { 228 H.ac.abort(); 229 } 230 // eslint-disable-next-line no-console 231 console.info(scriptName + " timed out."); 232 }, H.s.timeout); 233 if (mainScriptLoaded) { 234 H.main(); 235 } else { 236 // Load main script 237 fetch(H.paths.maindir + "Hyphenopoly.js", fetchOptions). 238 then((response) => { 239 if (response.ok) { 240 response.blob().then((blb) => { 241 const script = d[shortcuts.ce]("script"); 242 script.src = URL.createObjectURL(blb); 243 d.head[shortcuts.ac](script); 244 mainScriptLoaded = true; 245 URL.revokeObjectURL(script.src); 246 }); 247 } 248 }); 249 } 250 H.hy6ors = mp(); 251 H.cf.langs.forEach((langDef, lang) => { 252 if (langDef === "H9Y") { 253 H.hy6ors.set(lang, defProm()); 254 } 255 }); 256 H.hy6ors.set("HTML", defProm()); 257 H.hyphenators = new Proxy(H.hy6ors, { 258 "get": (target, key) => { 259 return target.get(key); 260 }, 261 "set": () => { 262 // Inhibit setting of hyphenators 263 return true; 264 } 265 }); 266 (() => { 267 if (hev && hev.polyfill) { 268 hev.polyfill(); 269 } 270 })(); 271 } else { 272 (() => { 273 if (hev && hev.tearDown) { 274 hev.tearDown(); 275 } 276 w.Hyphenopoly = null; 277 })(); 278 } 279 (() => { 280 if (H.cft) { 281 store.setItem(scriptName, JSON.stringify( 282 { 283 "langs": [...H.cf.langs.entries()], 284 "pf": H.cf.pf 285 } 286 )); 287 } 288 })(); 289 }); 290 291 H.config = (c) => { 292 /** 293 * Sets default properties for an Object 294 * @param {object} obj - The object to set defaults to 295 * @param {object} defaults - The defaults to set 296 * @returns {object} 297 */ 298 const setDefaults = (obj, defaults) => { 299 if (obj) { 300 o.entries(defaults).forEach(([k, v]) => { 301 // eslint-disable-next-line security/detect-object-injection 302 obj[k] = obj[k] || v; 303 }); 304 return obj; 305 } 306 return defaults; 307 }; 308 309 H.cft = Boolean(c.cacheFeatureTests); 310 if (H.cft && store.getItem(scriptName)) { 311 H.cf = JSON.parse(store.getItem(scriptName)); 312 H.cf.langs = mp(H.cf.langs); 313 } else { 314 H.cf = { 315 "langs": mp(), 316 "pf": false 317 }; 318 } 319 320 const maindir = thisScript.slice(0, (thisScript.lastIndexOf("/") + 1)); 321 const patterndir = maindir + "patterns/"; 322 H.paths = setDefaults(c.paths, { 323 maindir, 324 patterndir 325 }); 326 H.s = setDefaults(c.setup, { 327 "CORScredentials": "include", 328 "hide": "all", 329 "selectors": {".hyphenate": {}}, 330 "timeout": 1000 331 }); 332 // Change mode string to mode int 333 H.s.hide = ["all", "element", "text"].indexOf(H.s.hide); 334 if (c.handleEvent) { 335 H.hev = c.handleEvent; 336 } 337 338 const fallbacks = mp(o.entries(c.fallbacks || {})); 339 H.lrq = mp(); 340 o.entries(c.require).forEach(([lang, wo]) => { 341 H.lrq.set(lang.toLowerCase(), { 342 "fn": fallbacks.get(lang) || lang, 343 wo 344 }); 345 }); 346 347 main(); 348 }; 349})(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.