https://www.esri.com/etc.clientlibs/esri-sites/components/core/emb…/experience-builder/clientlibs.js
1/** 2 * @file experience-builder.js 3 * @component Experience Builder Embed 4 * 5 * @description 6 * Initializes the Experience Builder embedded iFrame and synchronizes its 7 * language code with the current page's locale. On DOMContentLoaded, the 8 * routine locates the embed wrapper, extracts the iFrame src, and checks 9 * whether the authored src contains a recognized lang-code path segment. 10 * If it does, the page URL is checked for a matching lang-code segment and 11 * the iFrame src is rewritten to match. If the src has no lang-code segment, 12 * no changes are made. 13 * 14 * @routine DOMContentLoaded 15 * 16 * @variables 17 * @var {Element} xprBuilder - DOM element matching '.experience-builder'. Entry point for 18 * all subsequent queries within this component instance. 19 * @var {string|undefined} mapSrc - The raw src attribute value from the iFrame inside xprBuilder. 20 * Undefined if no matching iframe[src] is found. 21 * @var {Set<string>} validLangCodes - Allowlist of supported BCP-47 locale strings used to 22 * identify lang segments within URL paths. 23 * @var {Function} escapeRegExp - Escapes special regex characters in a string so it can be 24 * safely used inside a RegExp constructor. 25 * @var {Function} replaceSrcLangCode - Replaces the first matching lang-code path segment in a 26 * src URL, preserving surrounding slashes and query strings. 27 * @var {string|undefined} srcLangCode - Language code found in the iFrame src path (e.g. 'fr-fr'). 28 * Undefined if no lang segment is present; triggers early return. 29 * @var {string|undefined} pageLangCode - Language code found in the current page URL. 30 * When present, used to rewrite the iFrame src. 31 * @var {Element} iframe - The iframe[src] element re-queried from xprBuilder when a 32 * lang code swap is needed; avoids stale reference from mapSrc. 33 * @var {string} newSrc - Rewritten src value after substituting srcLangCode â pageLangCode. 34 * 35 * @logic 36 * 1. Query '.experience-builder'; bail early if not present on the page. 37 * 2. Read the iFrame src via optional chaining; bail early if no src found. 38 * 3. Scan the src path segments against validLangCodes to identify the embedded locale. 39 * If no lang segment is found in the src, bail early â nothing to update. 40 * 4. Set a 'lang' attribute on xprBuilder for accessibility and downstream targeting. 41 * 5. Extract the page locale from window.location.href using the same validLangCodes set. 42 * 6. When pageLangCode is resolved, rewrite the iFrame src using replaceSrcLangCode â 43 * a regex that matches the lang segment bounded by slashes, '?', or '#' to avoid
44 * false matches on similar substrings elsewhere in the URL. Update 'lang' attribute 45 * to reflect the new locale. 46 */ 47document.addEventListener('DOMContentLoaded', () => { 48 const xprBuilder = document.querySelector('.experience-builder'); 49 if (!xprBuilder) { 50 return; 51 } 52 53 const mapSrc = xprBuilder.querySelector('iframe[src]')?.getAttribute('src'); 54 if (!mapSrc) { 55 return; 56 } 57 58 const validLangCodes = new Set([ 59 'en', 60 'en-us', 61 'ar-sa', 62 'zh-cn', 63 'fr-fr', 64 'de-de', 65 'it-it', 66 'ja-jp', 67 'ko-kr', 68 'pl-pl', 69 'pt-br', 70 'ru-ru', 71 'es-es', 72 'nl-nl', 73 'he-il', 74 'id-id', 75 'sv-se', 76 'bs-ba', 77 'ca-es', 78 'cs-cz', 79 'da-dk', 80 'fi-fi', 81 'hu-hu', 82 'nb-no', 83 'el-gr', 84 'et-ee', 85 'hr-hr', 86 'lt-lt', 87 'lv-lv', 88 'pt-pt', 89 'ro-ro', 90 'sl-sl', 91 'sr-rs', 92 'th-th', 93 'tr-tr', 94 'vi-vn', 95 'zh-hk', 96 'zh-tw', 97 'uk-ua', 98 ]); 99 const escapeRegExp = value => value.replace(/[.*+?^${}()|[\]\\]/g, String.raw`\$&`); 100 const replaceSrcLangCode = (src, currentLangCode, newLangCode) => { 101 const langCodePattern = new RegExp(`(^|/)${escapeRegExp(currentLangCode)}(?=$|[/?#])`, 'i'); 102 103 return src.replace(langCodePattern, `$1${newLangCode}`); 104 }; 105 106 const srcLangCode = mapSrc.split('/').find(part => validLangCodes.has(part.toLowerCase())); 107 if (!srcLangCode) { 108 return; 109 } 110 111 xprBuilder.setAttribute('lang', srcLangCode); 112 113 const pageLangCode = globalThis.location.href.split('/').find(part => validLangCodes.has(part.toLowerCase())); 114 if (pageLangCode) { 115 const iframe = xprBuilder.querySelector('iframe[src]'); 116 if (iframe) { 117 const newSrc = replaceSrcLangCode(iframe.getAttribute('src'), srcLangCode, pageLangCode); 118 iframe.setAttribute('src', newSrc); 119 xprBuilder.setAttribute('lang', pageLangCode); 120 } 121 } 122});
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.