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.