PluginProbe
Polylang / 3.7.1
Polylang v3.7.1
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 / settings.js

settings.js in Polylang 3.7.1, at js/build/settings.js

436 lines 15.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /**
2 * @package Polylang
3 */
4
5 jQuery(
6 function ( $ ) {
7
8 // languages list table
9 // accessibility to row actions on focus
10 // mainly copy paste of WP code from common.js
11 var transitionTimeout;
12 $( 'table.languages' ).on(
13 { // restricted to languages list table
14 focusin: function () {
15 clearTimeout( transitionTimeout );
16 var focusedRowActions = $( this ).find( '.row-actions' );
17 // transitionTimeout is necessary for Firefox, but Chrome won't remove the CSS class without a little help.
18 $( '.row-actions' ).not( this ).removeClass( 'visible' );
19 focusedRowActions.addClass( 'visible' );
20 },
21 focusout: function () {
22 // Tabbing between post title and .row-actions links needs a brief pause, otherwise
23 // the .row-actions div gets hidden in transit in some browsers ( ahem, Firefox ).
24 transitionTimeout = setTimeout(
25 function () {
26 focusedRowActions.removeClass( 'visible' );
27 },
28 30
29 );
30 }
31 },
32 'tr'
33 ); // acts on the whole tr instead of single td as we have actions links in several columns
34
35 /**
36 * Common functions and variables for overriding languages and flags dropdown list by a jQuery UI selectmenu widget.
37 */
38
39 // Add a boolean variable to be able to check jQuery UI >= 1.12 which is introduced in WP 5.6.
40 // Backward compatibility WP < 5.6
41 var isJqueryUImin112 = $.ui.version >= '1.12.0';
42 // Allow to check if a flag list dropdown is present. Not present in the Wizard steps or other settings page.
43 var flagListExist = $( "#flag_list" ).length;
44 // Allow to check if a language list dropdown is present. Not present in other settings page.
45 var langListExist = $( "#lang_list" ).length;
46 // jQuery UI selectmenu widget width option
47 var defaultSelectmenuWidth = '95%';
48 var wizardSelectmenuWidth = '100%';
49
50 // Inject flag image when jQuery UI selectmenu is created or an item is selected.
51 // jQuery UI 1.12 introduce a wrapper inside de li tag which is necessary to selectmenu widget to work correctly.
52 // Mainly copy from the original jQuery UI 1.12 selectmenu widget _renderItem method.
53 // Note this code works fine with jQuery UI 1.11.4 too.
54 var selectmenuRenderItem = function ( ul, item ) {
55 var li = $( '<li>' );
56 var wrapper = $( '<div>');
57
58 if ( item.disabled ) {
59 this._addClass( li, null, "ui-state-disabled" );
60 }
61 // `item.label` is the original `<option>`'s label.
62 this._setText( wrapper, item.label );
63
64 // Add the flag from the data attribute in the selected element.
65 // `item.element` is the original `<option>` element, the data to prepend comes from a `data-html-flag` HTML attribute, filled by a method from `PLL_Language`.
66 wrapper.prepend( $( item.element ).data( 'flag-html' ) ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.prepend
67 wrapper.children( 'img' ).addClass( 'ui-icon' );
68
69 // `wrapper` and `ul` are safe, see above.
70 return li.append( wrapper ).appendTo( ul ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.append, WordPressVIPMinimum.JS.HTMLExecutingFunctions.appendTo
71 };
72 // Override selected item to inject flag for jQuery UI less than 1.12.
73 var selectmenuRefreshButtonText = function ( selectElement ) {
74 var buttonText = $( selectElement ).selectmenu( 'instance' ).buttonText;
75 // The data to prepend comes from a `data-html-flag` HTML attribute, filled by a method from `PLL_Language`.
76 buttonText.prepend( $( selectElement ).children( ':selected' ).data( 'flag-html' ) ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.prepend
77 buttonText.children( 'img' ).addClass( 'ui-icon' );
78 };
79 // Override selected item since jQuery UI 1.12 which introduces extension point method _renderButtonItem.
80 // @see https://api.jqueryui.com/1.12/selectmenu/#method-_renderButtonItem _renderButtonItem documentation.
81 var selectmenuRenderButtonItem = function ( selectElement ) {
82 var buttonItem = $( '<span>' );
83 this._setText( buttonItem, selectElement.label );
84 this._addClass( buttonItem, "ui-selectmenu-text" );
85
86 // Add the flag from the data attribute in the selected element.
87 // The data to prepend comes from a `data-html-flag` HTML attribute, filled by a method from `PLL_Language`.
88 buttonItem.prepend( $( selectElement.element ).data( 'flag-html' ) ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.prepend
89 buttonItem.children( 'img' ).addClass( 'ui-icon' );
90
91 return buttonItem;
92 }
93
94 /**
95 * Initialize a jQuery UI selectmenu widget on a DOM element
96 *
97 * @param {*} element - The jQuery object representing the DOM element to attach the widget with.
98 * @param {*} config - All the parameters - options and callbacks - necessary to configure the jQuery UI selectmenu widget.
99 * @return {Object} - The jQuery UI selectmenu widget object instance.
100 */
101 function initializeSelectmenuWidget( element, config ) {
102 // Create the jQuery UI selectmenu widget for flags list dropdown and return its instance.
103 var selectmenuWidgetInstance = element.selectmenu( config ).selectmenu( 'instance' );
104 // Overrides each item in the jQuery UI selectmenu list by injecting flag image.
105 selectmenuWidgetInstance._renderItem = selectmenuRenderItem;
106 // Override the selected item rendering for jQuery UI 1.12
107 if ( isJqueryUImin112 ) {
108 selectmenuWidgetInstance._renderButtonItem = selectmenuRenderButtonItem;
109 // Need to refresh to take in account the new button item rendering method after the selectmenu widget instanciaion.
110 selectmenuWidgetInstance.refresh();
111 }
112 return selectmenuWidgetInstance
113 }
114 /**
115 * Selectmenu widget common parameters for its configuration: options and callbacks.
116 */
117
118 // Selectmenu widget options
119 var selectmenuOptions = {
120 width: defaultSelectmenuWidth,
121 classes: {
122 'ui-selectmenu-menu': 'pll-selectmenu-menu',
123 'ui-selectmenu-button': 'pll-selectmenu-button',
124 }
125 };
126
127 // Selectmenu widget callbacks
128 var selectmenuFlagListCallbacks = {};
129 // Callbacks when Selectmenu widget create or select event is triggered.
130 var createSelectCallback = function ( event, ui ) {
131 selectmenuRefreshButtonText( event.target );
132 }
133
134 /**
135 * Overrides the flag dropdown list with our customized jquery ui selectmenu.
136 */
137
138 // Callbacks when Selectmenu widget change or open event is triggered.
139 // Needed to correctly refresh the selected element in the list when editing an existing language or when the value change is triggered by the language choice.
140 // jQuery UI 1.11 callback version.
141 var changeOpenCallback = function ( event, ui ) {
142 selectmenuRefreshButtonText( $( event.target ).selectmenu( 'refresh' ) );
143 }
144 // jQueryUI 1.12 callback version.
145 var changeOpenCallbackjQueryUI112 = function ( event, ui ) {
146 // Just a refresh of the menu is needed with jQuery UI 1.12 because _renderButtonItem is triggered and then inject correctly the flag.
147 $( event.target ).selectmenu( 'refresh' );
148 }
149 // There is no need to create and select callbacks with jQuery UI 1.12 because overriding _renderButtonItem method does the job.
150 if ( isJqueryUImin112 ) {
151 selectmenuFlagListCallbacks =
152 {
153 change: changeOpenCallbackjQueryUI112,
154 open: changeOpenCallbackjQueryUI112,
155 };
156 } else {
157 selectmenuFlagListCallbacks = {
158 create: createSelectCallback,
159 select: createSelectCallback,
160 change: changeOpenCallback,
161 open: changeOpenCallback,
162 };
163 }
164
165 // Create the selectmenu widget only if the field is present.
166 if ( flagListExist ) {
167 // Create the jQuery UI selectmenu widget for flags list dropdown and return its instance.
168 var selectmenuFlagList = initializeSelectmenuWidget( $( '#flag_list' ), Object.assign( {}, selectmenuOptions, selectmenuFlagListCallbacks ) );
169 $( '#lang_list' ).on(
170 'languageChanged',
171 function ( event, flag ) {
172 // Refresh the flag field
173 selectmenuFlagList.element.val( flag );
174 selectmenuFlagList._trigger( 'change' );
175 }
176 );
177 }
178
179 /**
180 * Language choice in predefined languages in Polylang Languages settings page and wizard.
181 * Overrides the predefined language dropdown list with our customized jQuery ui selectmenu widget.
182 */
183
184 /**
185 * Fill the other language form fields from the language element selected in the language list dropdown.
186 *
187 * @param {Object} language - language object of the selected element in the language list dropdown.
188 */
189 function fillLanguageFields( language ) {
190 $( '#lang_slug' ).val( language.slug );
191 $( '#lang_locale' ).val( language.locale );
192 $( 'input[name="rtl"]' ).val( language.rtl );
193 $( '#lang_name' ).val( language.name );
194 }
195
196 /**
197 * Parse selected language element in the language list dropdown.
198 *
199 * @param {object} event - jQuery triggered event.
200 * @return {object} The language object with its named properties.
201 */
202 function parseSelectedLanguage( event ) {
203 var selectedElement = $('option:selected', event.target);
204 var values = selectedElement.val().split(':')
205 return {
206 slug: values[0],
207 locale: values[1],
208 rtl: [values[2]],
209 flag: values[3],
210 name: selectedElement.text().split(' - ')[0] // At the moment there is no need of the 2nd part because it corresponds on the locale which is already known by splitting the selected element value
211 };
212 }
213
214 // Callback when selectmenu widget change event is triggered.
215 var changeCallback = function ( event, ui ) {
216 var language = parseSelectedLanguage( event );
217
218 fillLanguageFields( language );
219
220 $( event.target ).trigger( 'languageChanged', language.flag );
221 };
222
223 // Create the jQuery UI selectmenu widget languages list dropdown and return its instance.
224 var selectmenuLangListCallbacks = {};
225 // For the wizard we need a 100% width. So we override the previous defined value of selectmenuOptions.
226 if ( $( '#lang_list' ).closest( '.pll-wizard-content' ).length > 0 ) {
227 selectmenuOptions = Object.assign( selectmenuOptions, { width: wizardSelectmenuWidth } );
228 }
229
230 // There is no need to create and select callbacks with jQuery UI 1.12 because overriding _renderButtonItem method does the job.
231 if ( isJqueryUImin112 ) {
232 selectmenuLangListCallbacks = {
233 change: changeCallback,
234 };
235 } else {
236 selectmenuLangListCallbacks = {
237 create: createSelectCallback,
238 select: createSelectCallback,
239 change: changeCallback,
240 };
241 }
242 if ( langListExist ) {
243 initializeSelectmenuWidget( $( '#lang_list' ), Object.assign( {}, selectmenuOptions, selectmenuLangListCallbacks ) );
244 }
245
246 // strings translations
247 // save translations when pressing enter
248 $( '.translation input' ).on(
249 'keydown',
250 function ( event ) {
251 if ( 'Enter' === event.key ) {
252 event.preventDefault();
253 $( '#submit' ).trigger( 'click' );
254 }
255 }
256 );
257
258 // settings page
259 // click on configure link
260 $( '#the-list' ).on(
261 'click',
262 '.configure>a',
263 function () {
264 $( '.pll-configure' ).hide().prev().show();
265 $( this ).closest( 'tr' ).hide().next().show();
266 return false;
267 }
268 );
269
270 // cancel
271 $( '#the-list' ).on(
272 'click',
273 '.cancel',
274 function () {
275 $( this ).closest( 'tr' ).hide().prev().show();
276 }
277 );
278
279 // save settings
280 $( '#the-list' ).on(
281 'click',
282 '.save',
283 function () {
284 var tr = $( this ).closest( 'tr' );
285 var parts = tr.attr( 'id' ).split( '-' );
286
287 var data = {
288 action: 'pll_save_options',
289 pll_ajax_settings: true,
290 module: parts[parts.length - 1],
291 _pll_nonce: $( '#_pll_nonce' ).val()
292 };
293
294 data = tr.find( ':input' ).serialize() + '&' + $.param( data );
295
296 $.post(
297 ajaxurl,
298 data,
299 function ( response ) {
300 // Target a non existing WP HTML id to avoid a conflict with WP ajax requests.
301 var res = wpAjax.parseAjaxResponse( response, 'pll-ajax-response' );
302 $.each(
303 res.responses,
304 function () {
305 /**
306 * Fires after saving the settings, before applying changes to the DOM.
307 *
308 * @since 3.6.0
309 *
310 * @param {Object} response The response from the AJAX call.
311 * @param {HTMLElement} tr The HTML element containing the fields.
312 */
313 wp.hooks.doAction( 'pll_settings_saved', this, tr.get( 0 ) );
314
315 switch ( this.what ) {
316 case 'license-update':
317 // Data comes from `PLL_License::get_form_field()`, where everything is escaped.
318 $( '#pll-license-' + this.data ).replaceWith( this.supplemental.html ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.replaceWith
319 break;
320 case 'success':
321 tr.hide().prev().show(); // close only if there is no error
322 case 'error':
323 $( '.settings-error' ).remove(); // remove previous messages if any
324 // The data comes from `pll_add_notice()`, where message are passed through `wp_kses()`.
325 $( 'h1' ).after( this.data ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.after
326
327 // Make notices dismissible
328 // copy paste of common.js from WP 4.2.2
329 $( '.notice.is-dismissible' ).each(
330 function () {
331 var $this = $( this ),
332 $button = $( '<button type="button" class="notice-dismiss"><span class="screen-reader-text"></span></button>' ),
333 btnText = pll_settings.dismiss_notice || '';
334
335 // Ensure plain text
336 $button.find( '.screen-reader-text' ).text( btnText );
337
338 // Whitelist because of how the button is built. See above
339 $this.append( $button ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.append
340
341 $button.on(
342 'click.wp-dismiss-notice',
343 function ( event ) {
344 event.preventDefault();
345 $this.fadeTo(
346 100,
347 0,
348 function () {
349 $( this ).slideUp(
350 100,
351 function () {
352 $( this ).remove();
353 }
354 );
355 }
356 );
357 }
358 );
359 }
360 );
361 break;
362 }
363 }
364 );
365 }
366 );
367 }
368 );
369
370 // act when pressing enter or esc in configurations
371 $( '.pll-configure' ).on(
372 'keydown',
373 function ( event ) {
374 if ( 'Enter' === event.key ) {
375 event.preventDefault();
376 $( this ).find( '.save' ).trigger( 'click' );
377 }
378
379 if ( 'Escape' === event.key ) {
380 event.preventDefault();
381 $( this ).find( '.cancel' ).trigger( 'click' );
382 }
383 }
384 );
385
386 // settings URL modifications
387 // manages visibility of fields
388 $( "input[name='force_lang']" ).on(
389 'change',
390 function () {
391 function pll_toggle( a, test ) {
392 test ? a.show() : a.hide();
393 }
394
395 var value = $( this ).val();
396 pll_toggle( $( '#pll-domains-table' ), 3 == value );
397 pll_toggle( $( "#pll-hide-default" ), 3 > value );
398 pll_toggle( $( "#pll-rewrite" ), 2 > value );
399 pll_toggle( $( "#pll-redirect-lang" ), 2 > value );
400 }
401 );
402
403 // settings license
404 // deactivate button
405 $( '.pll-deactivate-license' ).on(
406 'click',
407 function () {
408 var data = {
409 action: 'pll_deactivate_license',
410 pll_ajax_settings: true,
411 id: $( this ).attr( 'id' ),
412 _pll_nonce: $( '#_pll_nonce' ).val()
413 };
414 $.post(
415 ajaxurl,
416 data,
417 function ( response ) {
418 // Data comes from `PLL_License::get_form_field()`, where everything is escaped.
419 $( '#pll-license-' + response.id ).replaceWith( response.html ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.replaceWith
420 }
421 );
422 }
423 );
424
425 // Manage closing the metabox.
426 // close postboxes that should be closed
427 $( '.if-js-closed' ).removeClass( 'if-js-closed' ).addClass( 'closed' );
428 // postboxes setup
429 if ( 'undefined' !== typeof postboxes ) {
430 postboxes.add_postbox_toggles( pagenow );
431 }
432 }
433 );
434
435
436