PluginProbe
Polylang / 2.9.1
Polylang v2.9.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 / admin.js

admin.js in Polylang 2.9.1, at js/admin.js

410 lines 13.7 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 orginal 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 this._setText( wrapper, item.label );
62
63 // Add the flag from the data attribute in the selected element.
64 wrapper.prepend( $( item.element ).data( 'flag-html' ) );
65 wrapper.children( 'img' ).addClass( 'ui-icon' );
66
67 return li.append( wrapper ).appendTo( ul );
68 };
69 // Override selected item to inject flag for jQuery UI less than 1.12.
70 var selectmenuRefreshButtonText = function( selectElement ) {
71 var buttonText = $( selectElement ).selectmenu( 'instance' ).buttonText;
72 buttonText.prepend( $( selectElement ).children( ':selected' ).data( 'flag-html' ) );
73 buttonText.children( 'img' ).addClass( 'ui-icon' );
74 };
75 // Override selected item since jQuery UI 1.12 which introduces extension point method _renderButtonItem.
76 // @see https://api.jqueryui.com/1.12/selectmenu/#method-_renderButtonItem _renderButtonItem documentation.
77 var selectmenuRenderButtonItem = function ( selectElement ) {
78 var buttonItem = $( '<span>' );
79 this._setText( buttonItem, selectElement.label );
80 this._addClass( buttonItem, "ui-selectmenu-text" );
81
82 // Add the flag from the data attribute in the selected element.
83 buttonItem.prepend( $( selectElement.element ).data( 'flag-html' ) );
84 buttonItem.children( 'img' ).addClass( 'ui-icon' );
85
86 return buttonItem;
87 }
88
89 /**
90 * Initialize a jQuery UI selectmenu widget on a DOM element
91 *
92 * @param {*} element - The jQuery object representing the DOM element to attach the widget with.
93 * @param {*} config - All the parameters - options and callbacks - necessary to configure the jQuery UI selectmenu widget.
94 * @return {Object} - The jQuery UI selectmenu widget object instance.
95 */
96 function initializeSelectmenuWidget( element, config ) {
97 // Create the jQuery UI selectmenu widget for flags list dropdown and return its instance.
98 var selectmenuWidgetInstance = element.selectmenu( config ).selectmenu( 'instance' );
99 // Overrides each item in the jQuery UI selectmenu list by injecting flag image.
100 selectmenuWidgetInstance._renderItem = selectmenuRenderItem;
101 // Override the selected item rendering for jQuery UI 1.12
102 if ( isJqueryUImin112 ) {
103 selectmenuWidgetInstance._renderButtonItem = selectmenuRenderButtonItem;
104 // Need to refresh to take in account the new button item rendering method after the selectmenu widget instanciaion.
105 selectmenuWidgetInstance.refresh();
106 }
107 return selectmenuWidgetInstance
108 }
109 /**
110 * Selectmenu widget common parameters for its configuration: options and callbacks.
111 */
112
113 // Selectmenu widget options
114 var selectmenuOptions = { width: defaultSelectmenuWidth };
115
116 // Selectmenu widget callbacks
117 var selectmenuFlagListCallbacks = {};
118 // Callbacks when Selectmenu widget create or select event is triggered.
119 var createSelectCallback = function( event, ui ) {
120 selectmenuRefreshButtonText( event.target );
121 }
122
123 /**
124 * Overrides the flag dropdown list with our customized jquery ui selectmenu.
125 */
126
127 // Callbacks when Selectmenu widget change or open event is triggered.
128 // 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.
129 // jQuery UI 1.11 callback version.
130 var changeOpenCallback = function( event, ui ){
131 selectmenuRefreshButtonText( $( event.target ).selectmenu( 'refresh' ) );
132 }
133 // jQueryUI 1.12 callback version.
134 var changeOpenCallbackjQueryUI112 = function( event, ui ){
135 // Just a refresh of the menu is needed with jQuery UI 1.12 because _renderButtonItem is triggered and then inject correctly the flag.
136 $( event.target ).selectmenu( 'refresh' );
137 }
138 // There is no need of create and select callbacks with jQuery UI 1.12 because overriding _renderButtonItem method do the job.
139 if ( isJqueryUImin112 ) {
140 selectmenuFlagListCallbacks =
141 {
142 change: changeOpenCallbackjQueryUI112,
143 open: changeOpenCallbackjQueryUI112,
144 };
145 } else {
146 selectmenuFlagListCallbacks = {
147 create: createSelectCallback,
148 select: createSelectCallback,
149 change: changeOpenCallback,
150 open: changeOpenCallback,
151 };
152 }
153
154 // Create the selectmenu widget only if the field is present.
155 if ( flagListExist ) {
156 // Create the jQuery UI selectmenu widget for flags list dropdown and return its instance.
157 var selectmenuFlagList = initializeSelectmenuWidget( $( '#flag_list' ), Object.assign( {}, selectmenuOptions, selectmenuFlagListCallbacks ) );
158 $( '#lang_list' ).on(
159 'languageChanged',
160 function( event, flag ) {
161 // Refresh the flag field
162 selectmenuFlagList.element.val( flag );
163 selectmenuFlagList._trigger( 'change' );
164 }
165 );
166 }
167
168 /**
169 * Language choice in predefined languages in Polylang Languages settings page and wizard.
170 * Overrides the predefined language dropdown list with our customized jQuery ui selectmenu widget.
171 */
172
173 /**
174 * Fill the other language form fields from the language element selected in the language list dropdown.
175 *
176 * @param {Object} language - language object of the selected element in the language list dropdown.
177 */
178 function fillLanguageFields( language ) {
179 $( '#lang_slug' ).val( language.slug );
180 $( '#lang_locale' ).val( language.locale );
181 $( 'input[name="rtl"]' ).val( language.rtl );
182 $( '#lang_name' ).val( language.name );
183 }
184
185 /**
186 * Parse selected language element in the language list dropdown.
187 *
188 * @param {object} event - jQuery triggered event.
189 * @return {object} The language object with its named properties.
190 */
191 function parseSelectedLanguage( event ) {
192 var selectedElement = $('option:selected', event.target);
193 var values = selectedElement.val().split(':')
194 return {
195 slug: values[0],
196 locale: values[1],
197 rtl: [values[2]],
198 flag: values[3],
199 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
200 };
201 }
202
203 // Callback when selectmenu widget change event is triggered.
204 var changeCallback = function( event, ui ) {
205 var language = parseSelectedLanguage( event );
206
207 fillLanguageFields( language );
208
209 $( event.target ).trigger( 'languageChanged', language.flag );
210 };
211
212 // Create the jQuery UI selectmenu widget languages list dropdown and return its instance.
213 var selectmenuLangListCallbacks = {};
214 // For the wizard we need a 100% width. So we override the previous defined value of selectmenuOptions.
215 if( $( '#lang_list' ).closest( '.pll-wizard-content' ).length > 0 ) {
216 selectmenuOptions = Object.assign( selectmenuOptions, { width: wizardSelectmenuWidth } );
217 }
218
219 // There is no need of create and select callbacks with jQuery UI 1.12 because overrinding _renderButtonItem method do the job.
220 if ( isJqueryUImin112 ) {
221 selectmenuLangListCallbacks = {
222 change: changeCallback,
223 };
224 } else {
225 selectmenuLangListCallbacks = {
226 create: createSelectCallback,
227 select: createSelectCallback,
228 change: changeCallback,
229 };
230 }
231 if ( langListExist ) {
232 initializeSelectmenuWidget( $( '#lang_list' ), Object.assign( {}, selectmenuOptions, selectmenuLangListCallbacks ) );
233 }
234
235 // strings translations
236 // save translations when pressing enter
237 $( '.translation input' ).on(
238 'keydown',
239 function( event ){
240 if ( 'Enter' === event.key ) {
241 event.preventDefault();
242 $( '#submit' ).trigger( 'click' );
243 }
244 }
245 );
246
247 // settings page
248 // click on configure link
249 $( '#the-list' ).on(
250 'click',
251 '.configure>a',
252 function(){
253 $( '.pll-configure' ).hide().prev().show();
254 $( this ).closest( 'tr' ).hide().next().show();
255 return false;
256 }
257 );
258
259 // cancel
260 $( '#the-list' ).on(
261 'click',
262 '.cancel',
263 function(){
264 $( this ).closest( 'tr' ).hide().prev().show();
265 }
266 );
267
268 // save settings
269 $( '#the-list' ).on(
270 'click',
271 '.save',
272 function(){
273 var tr = $( this ).closest( 'tr' );
274 var parts = tr.attr( 'id' ).split( '-' );
275
276 var data = {
277 action: 'pll_save_options',
278 pll_ajax_settings: true,
279 module: parts[parts.length - 1],
280 _pll_nonce: $( '#_pll_nonce' ).val()
281 };
282
283 data = tr.find( ':input' ).serialize() + '&' + $.param( data );
284
285 $.post(
286 ajaxurl,
287 data,
288 function( response ) {
289 var res = wpAjax.parseAjaxResponse( response, 'ajax-response' );
290 $.each(
291 res.responses,
292 function() {
293 switch ( this.what ) {
294 case 'license-update':
295 $( '#pll-license-' + this.data ).replaceWith( this.supplemental.html );
296 break;
297 case 'success':
298 tr.hide().prev().show(); // close only if there is no error
299 case 'error':
300 $( '.settings-error' ).remove(); // remove previous messages if any
301 $( 'h1' ).after( this.data );
302
303 // Make notices dismissible
304 // copy paste of common.js from WP 4.2.2
305 $( '.notice.is-dismissible' ).each(
306 function() {
307 var $this = $( this ),
308 $button = $( '<button type="button" class="notice-dismiss"><span class="screen-reader-text"></span></button>' ),
309 btnText = pll_dismiss_notice || '';
310
311 // Ensure plain text
312 $button.find( '.screen-reader-text' ).text( btnText );
313
314 // Whitelist because of how the button is built. See above
315 $this.append( $button ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.append
316
317 $button.on(
318 'click.wp-dismiss-notice',
319 function( event ) {
320 event.preventDefault();
321 $this.fadeTo(
322 100,
323 0,
324 function() {
325 $( this ).slideUp(
326 100,
327 function() {
328 $( this ).remove();
329 }
330 );
331 }
332 );
333 }
334 );
335 }
336 );
337 break;
338 }
339 }
340 );
341 }
342 );
343 }
344 );
345
346 // act when pressing enter or esc in configurations
347 $( '.pll-configure' ).on(
348 'keydown',
349 function( event ){
350 if ( 'Enter' === event.key ) {
351 event.preventDefault();
352 $( this ).find( '.save' ).trigger( 'click' );
353 }
354
355 if ( 'Escape' === event.key ) {
356 event.preventDefault();
357 $( this ).find( '.cancel' ).trigger( 'click' );
358 }
359 }
360 );
361
362 // settings URL modifications
363 // manages visibility of fields
364 $( "input[name='force_lang']" ).on(
365 'change',
366 function() {
367 function pll_toggle( a, test ) {
368 test ? a.show() : a.hide();
369 }
370
371 var value = $( this ).val();
372 pll_toggle( $( '#pll-domains-table' ), 3 == value );
373 pll_toggle( $( "#pll-hide-default" ), 3 > value );
374 pll_toggle( $( "#pll-rewrite" ), 2 > value );
375 pll_toggle( $( "#pll-redirect-lang" ), 2 > value );
376 }
377 );
378
379 // settings license
380 // deactivate button
381 $( '.pll-deactivate-license' ).on(
382 'click',
383 function() {
384 var data = {
385 action: 'pll_deactivate_license',
386 pll_ajax_settings: true,
387 id: $( this ).attr( 'id' ),
388 _pll_nonce: $( '#_pll_nonce' ).val()
389 };
390 $.post(
391 ajaxurl,
392 data,
393 function( response ){
394 $( '#pll-license-' + response.id ).replaceWith( response.html );
395 }
396 );
397 }
398 );
399
400 // Manage closing the metabox.
401 // close postboxes that should be closed
402 $( '.if-js-closed' ).removeClass( 'if-js-closed' ).addClass( 'closed' );
403 // postboxes setup
404 if ( 'undefined' !== typeof postboxes ) {
405 postboxes.add_postbox_toggles( pagenow );
406 }
407 }
408 );
409
410