PageSourceSearch

https://lvejo.org/_static/??wp-includes/js/jquery/jquery-migrate.m…-frontend-language-switcher.js?m=1789532678

js lvejo.org collected 2026-09-24 10:08:41 UTC 29,683 bytes, 445 lines download raw bytes

1/*! jQuery Migrate v3.4.1 | (c) OpenJS Foundation and other contributors | jquery.org/license */
2"undefined"==typeof jQuery.migrateMute&&(jQuery.migrateMute=!0),function(t){"use strict";"function"==typeof define&&define.amd?define(["jquery"],function(e){return t(e,window)}):"object"==typeof module&&module.exports?module.exports=t(require("jquery"),window):t(jQuery,window)}(function(s,n){"use strict";function e(e){return 0<=function(e,t){for(var r=/^(\d+)\.(\d+)\.(\d+)/,n=r.exec(e)||[],o=r.exec(t)||[],a=1;a<=3;a++){if(+o[a]<+n[a])return 1;if(+n[a]<+o[a])return-1}return 0}(s.fn.jquery,e)}s.migrateVersion="3.4.1";var t=Object.create(null);s.migrateDisablePatches=function(){for(var e=0;e<arguments.length;e++)t[arguments[e]]=!0},s.migrateEnablePatches=function(){for(var e=0;e<arguments.length;e++)delete t[arguments[e]]},s.migrateIsPatchEnabled=function(e){return!t[e]},n.console&&n.console.log&&(s&&e("3.0.0")&&!e("5.0.0")||n.console.log("JQMIGRATE: jQuery 3.x-4.x REQUIRED"),s.migrateWarnings&&n.console.log("JQMIGRATE: Migrate plugin loaded multiple times"),n.console.log("JQMIGRATE: Migrate is installed"+(s.migrateMute?"":" with logging active")+", version "+s.migrateVersion));var o={};function u(e,t){var r=n.console;!s.migrateIsPatchEnabled(e)||s.migrateDeduplicateWarnings&&o[t]||(o[t]=!0,s.migrateWarnings.push(t+" ["+e+"]"),r&&r.warn&&!s.migrateMute&&(r.warn("JQMIGRATE: "+t),s.migrateTrace&&r.trace&&r.trace()))}function r(e,t,r,n,o){Object.defineProperty(e,t,{configurable:!0,enumerable:!0,get:function(){return u(n,o),r},set:function(e){u(n,o),r=e}})}function a(e,t,r,n,o){var a=e[t];e[t]=function(){return o&&u(n,o),(s.migrateIsPatchEnabled(n)?r:a||s.noop).apply(this,arguments)}}function c(e,t,r,n,o){if(!o)throw new Error("No warning message provided");return a(e,t,r,n,o),0}function i(e,t,r,n){return a(e,t,r,n),0}s.migrateDeduplicateWarnings=!0,s.migrateWarnings=[],void 0===s.migrateTrace&&(s.migrateTrace=!0),s.migrateReset=function(){o={},s.migrateWarnings.length=0},"BackCompat"===n.document.compatMode&&u("quirks","jQuery is not compatible with Quirks Mode");var d,l,p,f={},m=s.fn.init,y=s.find,h=/\[(\s*[-\w]+\s*)([~|^$*]?=)\s*([-\w#]*?#[-\w#]*)\s*\]/,g=/\[(\s*[-\w]+\s*)([~|^$*]?=)\s*([-\w#]*?#[-\w#]*)\s*\]/g,v=/^[\s\uFEFF\xA0]+|([^\s\uFEFF\xA0])[\s\uFEFF\xA0]+$/g;for(d in i(s.fn,"init",function(e){var t=Array.prototype.slice.call(arguments);return s.migrateIsPatchEnabled("selector-empty-id")&&"string"==typeof e&&"#"===e&&(u("selector-empty-id","jQuery( '#' ) is not a valid selector"),t[0]=[]),m.apply(this,t)},"selector-empty-id"),s.fn.init.prototype=s.fn,i(s,"find",function(t){var r=Array.prototype.slice.call(arguments);if("string"==typeof t&&h.test(t))try{n.document.querySelector(t)}catch(e){t=t.replace(g,function(e,t,r,n){return"["+t+r+'"'+n+'"]'});try{n.document.querySelector(t),u("selector-hash","Attribute selector with '#' must be quoted: "+r[0]),r[0]=t}catch(e){u("selector-hash","Attribute selector with '#' was not fixed: "+r[0])}}return y.apply(this,r)},"selector-hash"),y)Object.prototype.hasOwnProperty.call(y,d)&&(s.find[d]=y[d]);c(s.fn,"size",function(){return this.length},"size","jQuery.fn.size() is deprecated and removed; use the .length property"),c(s,"parseJSON",function(){return JSON.parse.apply(null,arguments)},"parseJSON","jQuery.parseJSON is deprecated; use JSON.parse"),c(s,"holdReady",s.holdReady,"holdReady","jQuery.holdReady is deprecated"),c(s,"unique",s.uniqueSort,"unique","jQuery.unique is deprecated; use jQuery.uniqueSort"),r(s.expr,"filters",s.expr.pseudos,"expr-pre-pseudos","jQuery.expr.filters is deprecated; use jQuery.expr.pseudos"),r(s.expr,":",s.expr.pseudos,"expr-pre-pseudos","jQuery.expr[':'] is deprecated; use jQuery.expr.pseudos"),e("3.1.1")&&c(s,"trim",function(e){return null==e?"":(e+"").replace(v,"$1")},"trim","jQuery.trim is deprecated; use String.prototype.trim"),e("3.2.0")&&(c(s,"nodeName",function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},"nodeName","jQuery.nodeName is deprecated"),c(s,"isArray",Array.isArray,"isArray","jQuery.isArray is deprecated; use Array.isArray")),e("3.3.0")&&(c(s,"isNumeric",function(e){var t=typeof e;return("number"==t||"string"==t)&&!isNaN(e-parseFloat(e))},"isNumeric","jQuery.isNumeric() is deprecated"),s.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(e,t){f["[object "+t+"]"]=t.toLowerCase()}),c(s,"type",function(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?f[Object.prototype.toString.call(e)]||"object":typeof e},"type","jQuery.type is deprecated"),c(s,"isFunction",function(e){return"function"==typeof e},"isFunction","jQuery.isFunction() is deprecated"),c(s,"isWindow",function(e){return null!=e&&e===e.window}
2,"isWindow","jQuery.isWindow() is deprecated")),s.ajax&&(l=s.ajax,p=/(=)\?(?=&|$)|\?\?/,i(s,"ajax",function(){var e=l.apply(this,arguments);return e.promise&&(c(e,"success",e.done,"jqXHR-methods","jQXHR.success is deprecated and removed"),c(e,"error",e.fail,"jqXHR-methods","jQXHR.error is deprecated and removed"),c(e,"complete",e.always,"jqXHR-methods","jQXHR.complete is deprecated and removed")),e},"jqXHR-methods"),e("4.0.0")||s.ajaxPrefilter("+json",function(e){!1!==e.jsonp&&(p.test(e.url)||"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&p.test(e.data))&&u("jsonp-promotion","JSON-to-JSONP auto-promotion is deprecated")}));var j=s.fn.removeAttr,b=s.fn.toggleClass,w=/\S+/g;function x(e){return e.replace(/-([a-z])/g,function(e,t){return t.toUpperCase()})}i(s.fn,"removeAttr",function(e){var r=this,n=!1;return s.each(e.match(w),function(e,t){s.expr.match.bool.test(t)&&r.each(function(){if(!1!==s(this).prop(t))return!(n=!0)}),n&&(u("removeAttr-bool","jQuery.fn.removeAttr no longer sets boolean properties: "+t),r.prop(t,!1))}),j.apply(this,arguments)},"removeAttr-bool"),i(s.fn,"toggleClass",function(t){return void 0!==t&&"boolean"!=typeof t?b.apply(this,arguments):(u("toggleClass-bool","jQuery.fn.toggleClass( boolean ) is deprecated"),this.each(function(){var e=this.getAttribute&&this.getAttribute("class")||"";e&&s.data(this,"__className__",e),this.setAttribute&&this.setAttribute("class",!e&&!1!==t&&s.data(this,"__className__")||"")}))},"toggleClass-bool");var Q,A,R=!1,C=/^[a-z]/,N=/^(?:Border(?:Top|Right|Bottom|Left)?(?:Width|)|(?:Margin|Padding)?(?:Top|Right|Bottom|Left)?|(?:Min|Max)?(?:Width|Height))$/;s.swap&&s.each(["height","width","reliableMarginRight"],function(e,t){var r=s.cssHooks[t]&&s.cssHooks[t].get;r&&(s.cssHooks[t].get=function(){var e;return R=!0,e=r.apply(this,arguments),R=!1,e})}),i(s,"swap",function(e,t,r,n){var o,a,i={};for(a in R||u("swap","jQuery.swap() is undocumented and deprecated"),t)i[a]=e.style[a],e.style[a]=t[a];for(a in o=r.apply(e,n||[]),t)e.style[a]=i[a];return o},"swap"),e("3.4.0")&&"undefined"!=typeof Proxy&&(s.cssProps=new Proxy(s.cssProps||{},{set:function(){return u("cssProps","jQuery.cssProps is deprecated"),Reflect.set.apply(this,arguments)}})),e("4.0.0")?(A={animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,gridArea:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnStart:!0,gridRow:!0,gridRowEnd:!0,gridRowStart:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},"undefined"!=typeof Proxy?s.cssNumber=new Proxy(A,{get:function(){return u("css-number","jQuery.cssNumber is deprecated"),Reflect.get.apply(this,arguments)},set:function(){return u("css-number","jQuery.cssNumber is deprecated"),Reflect.set.apply(this,arguments)}}):s.cssNumber=A):A=s.cssNumber,Q=s.fn.css,i(s.fn,"css",function(e,t){var r,n,o=this;return e&&"object"==typeof e&&!Array.isArray(e)?(s.each(e,function(e,t){s.fn.css.call(o,e,t)}),this):("number"==typeof t&&(r=x(e),n=r,C.test(n)&&N.test(n[0].toUpperCase()+n.slice(1))||A[r]||u("css-number",'Number-typed values are deprecated for jQuery.fn.css( "'+e+'", value )')),Q.apply(this,arguments))},"css-number");var S,P,k,H,E=s.data;i(s,"data",function(e,t,r){var n,o,a;if(t&&"object"==typeof t&&2===arguments.length){for(a in n=s.hasData(e)&&E.call(this,e),o={},t)a!==x(a)?(u("data-camelCase","jQuery.data() always sets/gets camelCased names: "+a),n[a]=t[a]):o[a]=t[a];return E.call(this,e,o),t}return t&&"string"==typeof t&&t!==x(t)&&(n=s.hasData(e)&&E.call(this,e))&&t in n?(u("data-camelCase","jQuery.data() always sets/gets camelCased names: "+t),2<arguments.length&&(n[t]=r),n[t]):E.apply(this,arguments)},"data-camelCase"),s.fx&&(k=s.Tween.prototype.run,H=function(e){return e},i(s.Tween.prototype,"run",function(){1<s.easing[this.easing].length&&(u("easing-one-arg","'jQuery.easing."+this.easing.toString()+"' should use only one argument"),s.easing[this.easing]=H),k.apply(this,arguments)},"easing-one-arg"),S=s.fx.interval,P="jQuery.fx.interval is deprecated",n.requestAnimationFrame&&Object.defineProperty(s.fx,"interval",{configurable:!0,enumerable:!0,get:function(){return n.document.hidden||u("fx-interval",P),s.migrateIsPatchEnabled("fx-interval")&&void 0===S?13:S},set:function(e){u("fx-interval",P),S=e}}));var M=s.fn.load,q=s.event.add,O=s.event.fix;s.event.props=[],s.event.fixHooks={}
2,r(s.event.props,"concat",s.event.props.concat,"event-old-patch","jQuery.event.props.concat() is deprecated and removed"),i(s.event,"fix",function(e){var t,r=e.type,n=this.fixHooks[r],o=s.event.props;if(o.length){u("event-old-patch","jQuery.event.props are deprecated and removed: "+o.join());while(o.length)s.event.addProp(o.pop())}if(n&&!n._migrated_&&(n._migrated_=!0,u("event-old-patch","jQuery.event.fixHooks are deprecated and removed: "+r),(o=n.props)&&o.length))while(o.length)s.event.addProp(o.pop());return t=O.call(this,e),n&&n.filter?n.filter(t,e):t},"event-old-patch"),i(s.event,"add",function(e,t){return e===n&&"load"===t&&"complete"===n.document.readyState&&u("load-after-event","jQuery(window).on('load'...) called after load event occurred"),q.apply(this,arguments)},"load-after-event"),s.each(["load","unload","error"],function(e,t){i(s.fn,t,function(){var e=Array.prototype.slice.call(arguments,0);return"load"===t&&"string"==typeof e[0]?M.apply(this,e):(u("shorthand-removed-v3","jQuery.fn."+t+"() is deprecated"),e.splice(0,0,t),arguments.length?this.on.apply(this,e):(this.triggerHandler.apply(this,e),this))},"shorthand-removed-v3")}),s.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,r){c(s.fn,r,function(e,t){return 0<arguments.length?this.on(r,null,e,t):this.trigger(r)},"shorthand-deprecated-v3","jQuery.fn."+r+"() event shorthand is deprecated")}),s(function(){s(n.document).triggerHandler("ready")}),s.event.special.ready={setup:function(){this===n.document&&u("ready-event","'ready' event is deprecated")}},c(s.fn,"bind",function(e,t,r){return this.on(e,null,t,r)},"pre-on-methods","jQuery.fn.bind() is deprecated"),c(s.fn,"unbind",function(e,t){return this.off(e,null,t)},"pre-on-methods","jQuery.fn.unbind() is deprecated"),c(s.fn,"delegate",function(e,t,r,n){return this.on(t,e,r,n)},"pre-on-methods","jQuery.fn.delegate() is deprecated"),c(s.fn,"undelegate",function(e,t,r){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",r)},"pre-on-methods","jQuery.fn.undelegate() is deprecated"),c(s.fn,"hover",function(e,t){return this.on("mouseenter",e).on("mouseleave",t||e)},"pre-on-methods","jQuery.fn.hover() is deprecated");function T(e){var t=n.document.implementation.createHTMLDocument("");return t.body.innerHTML=e,t.body&&t.body.innerHTML}var F=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi;s.UNSAFE_restoreLegacyHtmlPrefilter=function(){s.migrateEnablePatches("self-closed-tags")},i(s,"htmlPrefilter",function(e){var t,r;return(r=(t=e).replace(F,"<$1></$2>"))!==t&&T(t)!==T(r)&&u("self-closed-tags","HTML tags must be properly nested and closed: "+t),e.replace(F,"<$1></$2>")},"self-closed-tags"),s.migrateDisablePatches("self-closed-tags");var D,W,_,I=s.fn.offset;return i(s.fn,"offset",function(){var e=this[0];return!e||e.nodeType&&e.getBoundingClientRect?I.apply(this,arguments):(u("offset-valid-elem","jQuery.fn.offset() requires a valid DOM element"),arguments.length?this:void 0)},"offset-valid-elem"),s.ajax&&(D=s.param,i(s,"param",function(e,t){var r=s.ajaxSettings&&s.ajaxSettings.traditional;return void 0===t&&r&&(u("param-ajax-traditional","jQuery.param() no longer uses jQuery.ajaxSettings.traditional"),t=r),D.call(this,e,t)},"param-ajax-traditional")),c(s.fn,"andSelf",s.fn.addBack,"andSelf","jQuery.fn.andSelf() is deprecated and removed, use jQuery.fn.addBack()"),s.Deferred&&(W=s.Deferred,_=[["resolve","done",s.Callbacks("once memory"),s.Callbacks("once memory"),"resolved"],["reject","fail",s.Callbacks("once memory"),s.Callbacks("once memory"),"rejected"],["notify","progress",s.Callbacks("memory"),s.Callbacks("memory")]],i(s,"Deferred",function(e){var a=W(),i=a.promise();function t(){var o=arguments;return s.Deferred(function(n){s.each(_,function(e,t){var r="function"==typeof o[e]&&o[e];a[t[1]](function(){var e=r&&r.apply(this,arguments);e&&"function"==typeof e.promise?e.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[t[0]+"With"](this===i?n.promise():this,r?[e]:arguments)})}),o=null}).promise()}return c(a,"pipe",t,"deferred-pipe","deferred.pipe() is deprecated"),c(i,"pipe",t,"deferred-pipe","deferred.pipe() is deprecated"),e&&e.call(a,a),a},"deferred-pipe"),s.Deferred.exceptionHook=W.exceptionHook),s});
3;
4class BaseSwitcher {
5    constructor(rootEl) {
6        this.root = rootEl;
7        this.list = rootEl?.querySelector('.trp-switcher-dropdown-list') || null;
8        this.isOpen = false;
9        this._pendingFocusOnOpen = false;
10        if (!this.root || !this.list) return;
11
12        if (!this.list.id) {
13            this.list.id = `trp-list-${Math.random().toString(36).slice(2, 9)}`;
14        }
15
16        // Single transitionend handler to drop .is-transitioning and finalize hidden/inert
17        this._onTe = (e) => {
18            if (e.target !== this.list || e.propertyName !== 'max-height') return;
19
20            this.root.classList.remove('is-transitioning');
21
22            if (!this.isOpen) {
23                this.list.hidden = true;
24                this.list.setAttribute('inert', '');
25            }
25 else if (this._pendingFocusOnOpen) {
26                this._pendingFocusOnOpen = false;
27                const first = this.list.querySelector(
28                    '[role="option"], a, button, [tabindex]:not([tabindex="-1"])'
29                );
30                first?.focus?.({ preventScroll: true });
31            }
32        };
33        this.list.addEventListener('transitionend', this._onTe);
34
35        this.collapse();
36        this.setAutoWidth();
37        this.bindKeyboard();
38    }
39
40    /**
41     * Returns true if the list has a non-zero transition duration (for any property).
42     * We use this to decide whether to rely on `transitionend` or fall back to sync behavior.
43     */
44    _hasAnimatedTransition() {
45        if (!this.list) return false;
46
47        const cs = getComputedStyle(this.list);
48        const durationsRaw = cs.transitionDuration || '';
49
50        if (!durationsRaw) return false;
51
52        const durations = durationsRaw
53            .split(',')
54            .map(str => parseFloat(str) || 0);
55
56        return durations.some(d => d > 0);
57    }
58
59    collapse() {
60        this.list.hidden = true;
61        this.list.setAttribute('inert', '');
62        this.setExpanded(false);
63        this.root.classList.remove('is-transitioning');
64    }
65
66    /**
67     * If width is set to auto, fix it to the calculated width + 20px
68     * We do this in order to avoid width shift on hover
69     * */
70    setAutoWidth() {
71        const bonusWidth = 10;
72
73        const cs = getComputedStyle(this.root);
74        const declaredWidth = cs.getPropertyValue('--switcher-width').trim();
75
76        if (declaredWidth === 'auto' && this.root.querySelector('.trp-language-item-name')) { // In case trp-language-item-name is not present, we are in flags only mode - so no auto width sizing is needed
77            const initialWidth = this.root.getBoundingClientRect().width;
78
79            this.root.style.setProperty('--switcher-width', (initialWidth + bonusWidth) + 'px');
80        }
81    }
82
83    setExpanded(open) {
84        const trigger = this.root.querySelector('.trp-language-item__current[role="button"]');
85        const val = String( !!open );
86        trigger?.setAttribute('aria-expanded', val);
87        this.root.classList.toggle('is-open', !!open);
88    }
89
90    setOpen( open, { source = null } = {} ) {
91        if ( !this.root || !this.list || open === this.isOpen ) return;
92
93        const prefersReduced = window.matchMedia?.('(prefers-reduced-motion: reduce)')?.matches;
94        const hasTransition  = !prefersReduced && this._hasAnimatedTransition();
95
96        this.isOpen = open;
97
98        // No transitions (0s duration) OR reduced motion: do everything synchronously,
99        if ( !hasTransition ) {
100            if ( open ) {
101                this.list.hidden = false;
102                this.list.removeAttribute( 'inert' );
103                this.setExpanded( true );
104
105                this._pendingFocusOnOpen = ( source?.type === 'keydown' );
106                if ( this._pendingFocusOnOpen ) {
107                    this._pendingFocusOnOpen = false;
108                    const first = this.list.querySelector(
109                        '[role="option"], a, button, [tabindex]:not([tabindex="-1"])'
110                    );
111                    first?.focus?.({ preventScroll: true });
112                }
113            } else {
114                this.setExpanded( false );
115                this.list.hidden = true;
116                this.list.setAttribute( 'inert', '' );
117                this._pendingFocusOnOpen = false;
118            }
119            return;
120        }
121
122        // Animated path: rely on transitionend to remove .is-transitioning
123        if ( open ) {
124            // Must be visible for CSS transition to run
125            this.list.hidden = false;
126            this.list.removeAttribute( 'inert' );
127
128            this._pendingFocusOnOpen = ( source?.type === 'keydown' );
129
130            this.root.classList.add( 'is-transitioning' );
131            // Next frame so browser registers pre-open (max-height: 0) state
132            requestAnimationFrame( () => this.setExpanded( true ) );
133        } else {
134            this.root.classList.add( 'is-transitioning' );
135            this.setExpanded( false );
136        }
137    }
138
139    bindKeyboard() {
140        const trigger = this.root.querySelector('.trp-language-item__current[role="button"]');
141        if ( !trigger ) return;
142
143        trigger.addEventListener('keydown', (e) => {
144            const inList = !!e.target.closest?.('.trp-switcher-dropdown-list');
145
146            if ( e.key === 'Enter' || e.key === ' ' ) {
147                e.preventDefault();
148                this.setOpen(!this.isOpen, { source: e });
149                return;
150            }
151
152            if ( e.key === 'ArrowDown' && !this.isOpen ) {
153                e.preventDefault();
154                this.setOpen(true, { source: e });
155            }
156
157            if ( e.key === 'Escape' ) {
158                this.setOpen(false, { source: e });
159                trigger.focus?.();
160            }
161        });
162    }
163}
164
165class ShortcodeSwitcher extends BaseSwitcher {
166    constructor(wrapper) {
167        const overlay =
168                  wrapper.querySelector('.trp-language-switcher.trp-shortcode-overlay')
169                  || [...wrapper.querySelectorAll('.trp-language-switcher')]
170                      .find(el => el.classList.contains('trp-shortcode-overlay'));
171
172        // Overlay must be interactable; ensure no accidental hidden/inert from server
173        overlay.hidden = false;
174        overlay.removeAttribute('hidden');
175        overlay.removeAttribute('inert');
176        if ('inert' in overlay) overlay.inert = false;
177
178        super(overlay);
179
180        if (!this.root || !this.list) return;
181
182        const control = this.root.querySelector('.trp-language-item__current[role="button"]');
183        if (control && this.list && !control.hasAttribute('aria-controls')) {
184            control.setAttribute('aria-controls', this.list.id);
185        }
186
187        const isClickMode =
188                  this.root.classList.contains('trp-open-on-click') ||
189                  wrapper.dataset.openMode === 'click' ||
190                  wrapper.classList.contains('trp-open-on-click');
191
192        if (isClickMode) {
193            // Click anywhere on overlay EXCEPT inside the list
194            this.root.addEventListener('click', (e) => {
195                const inList = e.target.closest('.trp-switcher-dropdown-list');
196                if (!inList) {
197                    e.preventDefault();
198                    e.stopPropagation();
199                    this.setOpen(!this.isOpen, { source: e });
200                }
201            }, true);
202
203            // Outside click closes
204            this.onDocClick = (evt) => {
205                if (!wrapper.contains(evt.target)) this.setOpen(false, { source: evt });
206            };
207            document.addEventListener('click', this.onDocClick, true);
208
209            // Focus leaving wrapper closes
210            wrapper.addEventListener('focusout', () => {
211                setTimeout(() => {
212                    if (!wrapper.contains(document.activeElement)) {
213                        this.setOpen(false, { source: 'keyboard' });
214                    }
215                }, 0);
216            });
217        } else {
218            // Hover mode on overlay
219            this.root.addEventListener('mouseenter', (e) => this.setOpen(true,  { source: e }));
220            this.root.addEventListener('mouseleave', (e) => this.setOpen(false, { source: e }));
221        }
222    }
223}
224
225class FloaterSwitcher extends BaseSwitcher {
226    constructor(el) {
227        super(el);
228
229        el.addEventListener('mouseenter', (e) => this.setOpen(true,  { source: e }));
230        el.addEventListener('mouseleave', (e) => this.setOpen(false, { source: e }));
231
232        this.onDocClick = (evt) => { if (!el.contains(evt.target)) this.setOpen(false, { source: evt }); };
233        document.addEventListener('click', this.onDocClick, true);
234    }
235}
236
237document.addEventListener('DOMContentLoaded', () => {
238    // Front-end or classic admin
239    initLanguageSwitchers(document);
240
241    // If no wrapper and we are in Gutenberg, watch for async SSR insert
242    if (
243        inGutenberg() &&
244        !getEditorDoc().querySelector(WRAPPER)
245    ) {
246        observeWrapperUntilFound();
247    }
248
249    if ( !inGutenberg() )
250        observeShortcodeSwitcher();
251});
252
253/** For shortcode switcher
254 *  Mark the shortcodes that were initialized
255 * */
256const TRP_BOUND = new WeakSet();
257const mark = (el) => TRP_BOUND.add(el);
258const isMarked = (el) => TRP_BOUND.has(el);
259
260const WRAPPER = '.trp-shortcode-switcher__wrapper';
261const OVERLAY = '.trp-language-switcher:not(.trp-opposite-button):not(.trp-ald-language-selector)';
262
263// Helpers
264function inGutenberg() {
265    return document.body?.classList?.contains('block-editor-page')
266        || !!(window.wp?.data?.select?.('core/block-editor'));
267}
268
269// If editor uses an iframe canvas, work inside it
270function getEditorDoc() {
271    const ifr = document.querySelector('iframe[name="editor-canvas"], .editor-canvas__iframe');
272
273    return (ifr && ifr.contentDocument) ? ifr.contentDocument : document;
274}
275
276function initLanguageSwitchers(root = document) {
277    const floater = root.querySelector(
278        '.trp-language-switcher.trp-ls-dropdown:not(.trp-shortcode-switcher):not(.trp-opposite-language)'
279    );
280
281    if (floater)
282        new FloaterSwitcher(floater);
283
284    root.querySelectorAll(WRAPPER)
285        .forEach(wrapper => {
286            const overlay = wrapper.querySelector(OVERLAY);
287
288            if (overlay && !isMarked(overlay)) {
289                mark(overlay);
290                new ShortcodeSwitcher(wrapper);
291            }
292        });
293}
294
295/**
296 * Observes the document for dynamically inserted shortcode switchers and initializes them automatically when detected.
297 */
298function observeShortcodeSwitcher() {
299    const initWrapper = ( wrapper ) => {
300        if ( !wrapper )
301            return;
302
303        const overlay = wrapper.querySelector( OVERLAY );
304
305        if ( !overlay || isMarked( overlay ) )
306            return;
307
308        mark( overlay );
309
310        new ShortcodeSwitcher( wrapper );
311    }
312
313    const mo = new MutationObserver( ( mutations ) => {
314        for ( const m of mutations ) {
315            for ( const n of m.addedNodes ) {
316                if ( n.nodeType !== 1 )
317                    continue;
318
319                if ( n.matches?.( WRAPPER ) )
320                    initWrapper( n );
321
322                n.querySelectorAll?.( WRAPPER ).forEach( initWrapper );
323            }
324        }
325    });
326
327    mo.observe( document, { childList: true, subtree: true } );
328}
329
330/**
331 * Observe Gutenberg for the shortcode wrapper being inserted asynchronously.
332 *
333 * Supports both Blocks API v2 (no editor iframe; wrapper appears in the outer document)
334 * and Blocks API v3 (editor content rendered inside an iframe canvas).
335 *
336 * Strategy:
337 *  1) Check the current editor document for `.trp-shortcode-switcher__wrapper` and init immediately.
338 *  2) If an editor canvas iframe exists, watch its document (and reattach on iframe load) for the wrapper.
339 *  3) If no iframe yet, watch the outer document for either the iframe (v3) or the wrapper itself (v2).
340 *
341 * Initialization is performed once per context to avoid duplicate bindings.
342 */
343function observeWrapperUntilFound() {
344    // If wrapper already exists in current editor doc, init
345    const edDoc = getEditorDoc();
346    const existing = edDoc.querySelector(WRAPPER);
347
348    if ( existing ) {
349        initLanguageSwitchers( edDoc );
350        return;
351    }
352
353    // Helper to locate the editor canvas iframe in the OUTER document
354    const findCanvasIframe = () => document.querySelector('iframe[name="editor-canvas"], .editor-canvas__iframe');
355
356    // If iframe is already present in the outer doc, start watching inside it
357    const iframeNow = findCanvasIframe();
358    if ( iframeNow ) {
359        watchIframe( iframeNow );
360        return;
361    }
362
363    // Otherwise, observe the OUTER document until the iframe appears
364    const outerMO = new MutationObserver( ( mutations ) => {
365        for ( const m of mutations ) {
366            for ( const n of m.addedNodes ) {
367                if ( n.nodeType !== 1 ) continue;
368
369                const iframe =
370                          n.matches?.('iframe[name="editor-canvas"], .editor-canvas__iframe')
371                              ? n
372                              : n.querySelector?.('iframe[name="editor-canvas"], .editor-canvas__iframe');
373
374                if ( iframe ) {
375                    outerMO.disconnect();
376                    watchIframe( iframe );
377                    return;
378                }
379
380                // Also catch shortcode wrapper added directly to the outer document (API v2, no iframe)
381                const wrapper =
382                          n.matches?.(WRAPPER)
383                              ? n
384                              : n.querySelector?.(WRAPPER);
385
386                if ( wrapper ) {
387                    outerMO.disconnect();
388                    initLanguageSwitchers( document );
389                    return;
390                }
391
392            }
393        }
394    } );
395    outerMO.observe( document, { childList: true, subtree: true } );
396
397    function watchIframe( iframe ) {
398        // Try immediately (some builds inject srcdoc synchronously)
399        tryAttachInside();
400
401        // Also on load/navigate (Gutenberg may reload the canvas)
402        iframe.addEventListener( 'load', tryAttachInside );
403
404        function tryAttachInside() {
405            let doc;
406            try {
407                doc = iframe.contentDocument || iframe.contentWindow?.document;
408            } catch (e) {
409                console.warn('Cannot access iframe content due to cross-origin restrictions', e);
410                return;
411            }
412            if ( !doc ) return;
413
414            // If wrapper is already there, init once and stop.
415            const hit = doc.querySelector(WRAPPER);
416            if ( hit ) {
417                initLanguageSwitchers( doc );
418                return;
419            }
420
421            // Observe INSIDE the iframe until wrapper appears
422            const innerMO = new MutationObserver( ( muts ) => {
423                for ( const mm of muts ) {
424                    for ( const nn of mm.addedNodes ) {
425                        if ( nn.nodeType !== 1 ) continue;
426                        if (
427                            nn.matches?.(WRAPPER) ||
428                            nn.querySelector?.(WRAPPER)
429                        ) {
430                            innerMO.disconnect();
431                            initLanguageSwitchers( doc );
432                            return;
433                        }
434                    }
435                }
436                if ( doc.querySelector(WRAPPER) ) {
437                    innerMO.disconnect();
438                    initLanguageSwitchers( doc );
439                }
440            } );
441
442            innerMO.observe( doc, { childList: true, subtree: true } );
443        }
444    }
445};

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.