PluginProbe
Polylang / trunk
Polylang vtrunk
3.8.9 3.8.8 3.8.7 3.8.6 3.8.5 3.8.4 3.8.3 2.7 2.7.0.1 2.7.1 2.7.2 2.7.3 2.7.4 2.8 2.8.1 2.8.2 2.8.3 2.8.4 2.9 2.9.1 2.9.2 3.0 3.0.1 3.0.2 3.0.3 All 233 releases
polylang / js / build / widgets.js

widgets.js in Polylang trunk, at js/build/widgets.js

235 lines 6.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /**
2 * Handles the options in the language switcher widget.
3 */
4 const pllWidget = {
5 /**
6 * Init.
7 */
8 init: () => {
9 if ( document.readyState !== 'loading' ) {
10 pllWidget.ready();
11 } else {
12 document.addEventListener( 'DOMContentLoaded', pllWidget.ready );
13 }
14 },
15
16 /**
17 * Called when the DOM is ready. Attaches the events to the wrapper.
18 */
19 ready: () => {
20 if (
21 window.pll_widgets?.flags &&
22 'object' === typeof window.pll_widgets.flags
23 ) {
24 pllWidget.displayFlags.flags = window.pll_widgets.flags;
25 }
26 document
27 .querySelectorAll(
28 // Widgets page without Classic Widgets, Widgets page with Classic Widgets, Customizer page.
29 '#widgets-editor, .widget-liquid-right #widgets-right, #customize-theme-controls'
30 )
31 .forEach( ( wrapper ) => {
32 wrapper.addEventListener( 'change', ( event ) => {
33 if (
34 event.target.closest(
35 '.polylang-language-switcher-widget-content select, .polylang-language-switcher-widget-content input'
36 )
37 ) {
38 pllWidget.manageRowsAndValues.handleEvent( event );
39 return;
40 }
41
42 if (
43 ! pllWidget.displayFlags.flags.length ||
44 'customize-theme-controls' === wrapper.id
45 ) {
46 // No flags for the customizer.
47 return;
48 }
49
50 if (
51 event.target.closest(
52 '.wp-block-legacy-widget__edit-form .pll-lang-choice'
53 )
54 ) {
55 // Without Classic Widgets.
56 pllWidget.displayFlags.handleEvent(
57 event,
58 '.wp-block-legacy-widget__edit-form',
59 '.wp-block-legacy-widget__edit-form-title'
60 );
61 } else if (
62 event.target.closest( '.widget .pll-lang-choice' )
63 ) {
64 // With Classic Widgets.
65 pllWidget.displayFlags.handleEvent(
66 event,
67 '.widget',
68 '.widget-top .widget-title h3'
69 );
70 }
71 } );
72
73 if ( 'customize-theme-controls' !== wrapper.id ) {
74 // No flags for the customizer.
75 if (
76 wrapper.classList.contains( 'blocks-widgets-container' )
77 ) {
78 // Without Classic Widgets: wait a second that everything is inserted into the page by WP.
79 setTimeout( () => {
80 pllWidget.displayFlags.triggerChange( wrapper );
81 }, 1000 );
82 } else {
83 pllWidget.displayFlags.triggerChange( wrapper );
84 }
85 }
86 } );
87 },
88
89 /**
90 * Display or hide rows, depending on the value of other settings.
91 */
92 manageRowsAndValues: {
93 /**
94 * Event callback that hides rows and forbids disabling both flag and name/code.
95 *
96 * @param {Event} event The event.
97 */
98 handleEvent: ( event ) => {
99 let value = '';
100
101 if ( 'SELECT' === event.target.nodeName ) {
102 value = event.target.value;
103 } else if (
104 'INPUT' === event.target.nodeName &&
105 'checkbox' === event.target.type
106 ) {
107 value = event.target.checked;
108 } else {
109 return;
110 }
111
112 const wrapper = event.target.closest(
113 '.polylang-language-switcher-widget-content'
114 );
115
116 if ( ! wrapper ) {
117 return;
118 }
119
120 const key = event.target.getAttribute( 'data-key' );
121
122 // Show/Hide rows.
123 wrapper
124 .querySelectorAll(
125 `:scope [class*="pll-hidden-if-${ key }-"]:not(.pll-hidden-if-${ key }-${ value })` // phpcs:ignore Squiz.ControlStructures.ControlSignature.SpaceAfterKeyword, Generic.ControlStructures.InlineControlStructure.NotAllowed, PHPCS detects `-if-` like a `if(`.
126 )
127 .forEach( ( row ) => {
128 row.classList.remove( `pll-hidden-by-${ key }` );
129 } );
130 wrapper
131 .querySelectorAll( `:scope .pll-hidden-if-${ key }-${ value }` ) // phpcs:ignore Squiz.ControlStructures.ControlSignature.SpaceAfterKeyword, Generic.ControlStructures.InlineControlStructure.NotAllowed, PHPCS detects `-if-` like a `if(`.
132 .forEach( ( row ) => {
133 row.classList.add( `pll-hidden-by-${ key }` );
134 } );
135
136 // Forbid disabling both flag and name/code.
137 if ( 'show_labels' === key && '' === value ) {
138 const otherInput = wrapper.querySelector(
139 '[data-key="show_flags"]'
140 );
141
142 if ( true !== otherInput.checked ) {
143 otherInput.checked = true;
144 otherInput.dispatchEvent(
145 new Event( 'change', { bubbles: true } )
146 );
147 }
148 } else if ( 'show_flags' === key && false === value ) {
149 const otherInput = wrapper.querySelector(
150 '[data-key="show_labels"]'
151 );
152
153 if ( '' === otherInput.value ) {
154 otherInput.value = 'names';
155 otherInput.dispatchEvent(
156 new Event( 'change', { bubbles: true } )
157 );
158 }
159 }
160 },
161 },
162
163 /**
164 * Display a flag in front of a widget title, depending on the language the widget should be displayed for.
165 */
166 displayFlags: {
167 /**
168 * Flags (markup), with language slug as property names.
169 *
170 * @member {Object}
171 */
172 flags: {},
173
174 /**
175 * Event callback that adds or removes the flag.
176 *
177 * @param {Event} event The event.
178 * @param {string} widgetSelector Selector for the widget wrapper, relative to the event target.
179 * @param {string} titleSelector Selector for the title, relative to the wrapper.
180 */
181 handleEvent: ( event, widgetSelector, titleSelector ) => {
182 const wrapper = event.target.closest( widgetSelector );
183
184 if ( ! wrapper ) {
185 return;
186 }
187
188 const title = wrapper.querySelector( titleSelector );
189
190 if ( ! title ) {
191 return;
192 }
193
194 const langSlug = event.target.value;
195 const icon =
196 langSlug &&
197 pllWidget.displayFlags.flags.hasOwnProperty( langSlug )
198 ? pllWidget.displayFlags.flags[ langSlug ]
199 : null;
200 const currentFlag = title.querySelector( '.pll-lang' );
201
202 if ( icon ) {
203 if ( currentFlag ) {
204 currentFlag.innerHTML = `${ icon }   `; // `icon` comes from `PLL_Admin_Base::add_inline_scripts()`.
205 } else {
206 const newFlag = document.createElement( 'span' );
207 newFlag.classList.add( 'pll-lang' );
208 newFlag.innerHTML = `${ icon }   `; // `icon` comes from `PLL_Admin_Base::add_inline_scripts()`.
209 title.prepend( newFlag ); // `newFlag` is a new element we just created with safe data.
210 }
211 } else if ( currentFlag ) {
212 currentFlag.remove();
213 }
214 },
215
216 /**
217 * Triggers a language selection.
218 *
219 * @param {HTMLElement} wrapper Wrapper.
220 */
221 triggerChange: ( wrapper ) => {
222 wrapper
223 .querySelectorAll( ':scope .pll-lang-choice' )
224 .forEach( ( select ) => {
225 select.dispatchEvent(
226 new Event( 'change', { bubbles: true } )
227 );
228 } );
229 },
230 },
231 };
232
233 pllWidget.init();
234
235