PluginProbe
Polylang / 2.5
Polylang v2.5
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
← All changes | js/admin.js +162 -382 3.02.5 View file →
@@ -1,415 +1,195 @@
1 -/**
2 - * @package Polylang
3 - */
1 +jQuery( document ).ready(function( $ ) {
2 + var transitionTimeout;
4 3
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;
4 + // languages list table
5 + // accessibility to row actions on focus
6 + // mainly copy paste of WP code from common.js
7 + $( 'table.languages' ).on({ // restricted to languages list table
8 + focusin: function() {
9 + clearTimeout( transitionTimeout );
10 + focusedRowActions = $( this ).find( '.row-actions' );
11 + // transitionTimeout is necessary for Firefox, but Chrome won't remove the CSS class without a little help.
12 + $( '.row-actions' ).not( this ).removeClass( 'visible' );
13 + focusedRowActions.addClass( 'visible' );
14 + },
15 + focusout: function() {
16 + // Tabbing between post title and .row-actions links needs a brief pause, otherwise
17 + // the .row-actions div gets hidden in transit in some browsers ( ahem, Firefox ).
18 + transitionTimeout = setTimeout(function() {
19 + focusedRowActions.removeClass( 'visible' );
20 + }, 30 );
87 21 }
22 + }, 'tr' ); // acts on the whole tr instead of single td as we have actions links in several columns
88 23
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 - */
24 + // extends selectmenu to add flags in menu items
25 + $.widget( "custom.iconselectmenu", $.ui.selectmenu, {
26 + _renderItem: function( ul, item ) {
27 + var li = $( "<li>", { text: item.label } );
28 + var el = $( item.element );
29 + var url = el.data( "url" );
112 30
113 - // Selectmenu widget options
114 - var selectmenuOptions = {
115 - width: defaultSelectmenuWidth,
116 - classes: {
117 - 'ui-selectmenu-menu': 'pll-selectmenu-menu',
118 - 'ui-selectmenu-button': 'pll-selectmenu-button',
119 - }
120 - };
31 + if ( url ) {
32 + var w = el.data( "width" );
33 + var h = el.data( "height" );
34 + $( "<img class='ui-icon' />" ).prop( "src", url ).prop( "width", w ).prop( "height", h ).appendTo( li );
35 + }
121 36
122 - // Selectmenu widget callbacks
123 - var selectmenuFlagListCallbacks = {};
124 - // Callbacks when Selectmenu widget create or select event is triggered.
125 - var createSelectCallback = function( event, ui ) {
126 - selectmenuRefreshButtonText( event.target );
37 + return li.appendTo( ul );
127 38 }
39 + });
128 40
129 - /**
130 - * Overrides the flag dropdown list with our customized jquery ui selectmenu.
131 - */
41 + // allows to display the flag for the selected menu item
42 + function add_icon( event, ui ) {
43 + var sel = $( this ).find( ":selected" );
44 + var url = sel.data( "url" );
132 45
133 - // Callbacks when Selectmenu widget change or open event is triggered.
134 - // 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.
135 - // jQuery UI 1.11 callback version.
136 - var changeOpenCallback = function( event, ui ){
137 - selectmenuRefreshButtonText( $( event.target ).selectmenu( 'refresh' ) );
46 + if ( url ) {
47 + var txt = $( this ).iconselectmenu( "widget" ).children( ":last" );
48 + var w = sel.data( "width" );
49 + var h = sel.data( "height" );
50 + $( "<img class='ui-icon' />" ).prop( "src", url ).prop( "width", w ).prop( "height", h ).appendTo( txt );
138 51 }
139 - // jQueryUI 1.12 callback version.
140 - var changeOpenCallbackjQueryUI112 = function( event, ui ){
141 - // Just a refresh of the menu is needed with jQuery UI 1.12 because _renderButtonItem is triggered and then inject correctly the flag.
142 - $( event.target ).selectmenu( 'refresh' );
143 - }
144 - // There is no need of create and select callbacks with jQuery UI 1.12 because overriding _renderButtonItem method do the job.
145 - if ( isJqueryUImin112 ) {
146 - selectmenuFlagListCallbacks =
147 - {
148 - change: changeOpenCallbackjQueryUI112,
149 - open: changeOpenCallbackjQueryUI112,
150 - };
151 - } else {
152 - selectmenuFlagListCallbacks = {
153 - create: createSelectCallback,
154 - select: createSelectCallback,
155 - change: changeOpenCallback,
156 - open: changeOpenCallback,
157 - };
158 - }
52 + }
159 53
160 - // Create the selectmenu widget only if the field is present.
161 - if ( flagListExist ) {
162 - // Create the jQuery UI selectmenu widget for flags list dropdown and return its instance.
163 - var selectmenuFlagList = initializeSelectmenuWidget( $( '#flag_list' ), Object.assign( {}, selectmenuOptions, selectmenuFlagListCallbacks ) );
164 - $( '#lang_list' ).on(
165 - 'languageChanged',
166 - function( event, flag ) {
167 - // Refresh the flag field
168 - selectmenuFlagList.element.val( flag );
169 - selectmenuFlagList._trigger( 'change' );
170 - }
171 - );
172 - }
54 + // overrides the flag dropdown list with our customized jquery ui selectmenu
55 + $( "#flag_list" ).iconselectmenu({
56 + create: add_icon,
57 + select: add_icon,
58 + });
173 59
174 - /**
175 - * Language choice in predefined languages in Polylang Languages settings page and wizard.
176 - * Overrides the predefined language dropdown list with our customized jQuery ui selectmenu widget.
177 - */
60 + // languages form
61 + // fills the fields based on the language dropdown list choice
62 + $( '#lang_list' ).change(function() {
63 + var value = $( this ).val().split( ':' );
64 + var selected = $( "option:selected", this ).text().split( ' - ' );
65 + $( '#lang_slug' ).val( value[0] );
66 + $( '#lang_locale' ).val( value[1] );
67 + $( 'input[name="rtl"]' ).val( [value[2]] );
68 + $( '#lang_name' ).val( selected[0] );
69 + $( '#flag_list option[value="' + value[3] + '"]' ).attr( 'selected', 'selected' );
178 70
179 - /**
180 - * Fill the other language form fields from the language element selected in the language list dropdown.
181 - *
182 - * @param {Object} language - language object of the selected element in the language list dropdown.
183 - */
184 - function fillLanguageFields( language ) {
185 - $( '#lang_slug' ).val( language.slug );
186 - $( '#lang_locale' ).val( language.locale );
187 - $( 'input[name="rtl"]' ).val( language.rtl );
188 - $( '#lang_name' ).val( language.name );
189 - }
71 + // recreate the jquery ui selectmenu
72 + $( "#flag_list" ).iconselectmenu( 'destroy' ).iconselectmenu({
73 + create: add_icon,
74 + select: add_icon,
75 + })
76 + });
190 77
191 - /**
192 - * Parse selected language element in the language list dropdown.
193 - *
194 - * @param {object} event - jQuery triggered event.
195 - * @return {object} The language object with its named properties.
196 - */
197 - function parseSelectedLanguage( event ) {
198 - var selectedElement = $('option:selected', event.target);
199 - var values = selectedElement.val().split(':')
200 - return {
201 - slug: values[0],
202 - locale: values[1],
203 - rtl: [values[2]],
204 - flag: values[3],
205 - 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
206 - };
78 + // strings translations
79 + // save translations when pressing enter
80 + $( '.translation input' ).keypress(function( event ){
81 + if ( 13 === event.keyCode ) {
82 + event.preventDefault();
83 + $( '#submit' ).click();
207 84 }
85 + });
208 86
209 - // Callback when selectmenu widget change event is triggered.
210 - var changeCallback = function( event, ui ) {
211 - var language = parseSelectedLanguage( event );
87 + // settings page
88 + // click on configure link
89 + $( '#the-list' ).on( 'click', '.configure>a', function(){
90 + $( '.pll-configure' ).hide().prev().show();
91 + $( this ).closest( 'tr' ).hide().next().show();
92 + return false;
93 + });
212 94
213 - fillLanguageFields( language );
95 + // cancel
96 + $( '#the-list' ).on( 'click', '.cancel', function(){
97 + $( this ).closest( 'tr' ).hide().prev().show();
98 + });
214 99
215 - $( event.target ).trigger( 'languageChanged', language.flag );
216 - };
100 + // save settings
101 + $( '#the-list' ).on( 'click', '.save', function(){
102 + var tr = $( this ).closest( 'tr' );
103 + var parts = tr.attr( 'id' ).split( '-' );
217 104
218 - // Create the jQuery UI selectmenu widget languages list dropdown and return its instance.
219 - var selectmenuLangListCallbacks = {};
220 - // For the wizard we need a 100% width. So we override the previous defined value of selectmenuOptions.
221 - if( $( '#lang_list' ).closest( '.pll-wizard-content' ).length > 0 ) {
222 - selectmenuOptions = Object.assign( selectmenuOptions, { width: wizardSelectmenuWidth } );
105 + var data = {
106 + action: 'pll_save_options',
107 + pll_ajax_settings: true,
108 + module: parts[parts.length - 1],
109 + _pll_nonce: $( '#_pll_nonce' ).val()
223 110 }
224 111
225 - // There is no need of create and select callbacks with jQuery UI 1.12 because overrinding _renderButtonItem method do the job.
226 - if ( isJqueryUImin112 ) {
227 - selectmenuLangListCallbacks = {
228 - change: changeCallback,
229 - };
230 - } else {
231 - selectmenuLangListCallbacks = {
232 - create: createSelectCallback,
233 - select: createSelectCallback,
234 - change: changeCallback,
235 - };
236 - }
237 - if ( langListExist ) {
238 - initializeSelectmenuWidget( $( '#lang_list' ), Object.assign( {}, selectmenuOptions, selectmenuLangListCallbacks ) );
239 - }
112 + data = tr.find( ':input' ).serialize() + '&' + $.param( data );
240 113
241 - // strings translations
242 - // save translations when pressing enter
243 - $( '.translation input' ).on(
244 - 'keydown',
245 - function( event ){
246 - if ( 'Enter' === event.key ) {
247 - event.preventDefault();
248 - $( '#submit' ).trigger( 'click' );
249 - }
250 - }
251 - );
114 + $.post( ajaxurl, data, function( response ) {
115 + var res = wpAjax.parseAjaxResponse( response, 'ajax-response' );
116 + $.each( res.responses, function() {
117 + switch ( this.what ) {
118 + case 'license-update':
119 + $( '#pll-license-' + this.data ).replaceWith( this.supplemental.html );
120 + break;
121 + case 'success':
122 + tr.hide().prev().show(); // close only if there is no error
123 + case 'error':
124 + $( '.settings-error' ).remove(); // remove previous messages if any
125 + $( 'h1' ).after( this.data );
252 126
253 - // settings page
254 - // click on configure link
255 - $( '#the-list' ).on(
256 - 'click',
257 - '.configure>a',
258 - function(){
259 - $( '.pll-configure' ).hide().prev().show();
260 - $( this ).closest( 'tr' ).hide().next().show();
261 - return false;
262 - }
263 - );
127 + // Make notices dismissible
128 + // copy paste of common.js from WP 4.2.2
129 + $( '.notice.is-dismissible' ).each(function() {
130 + var $this = $( this ),
131 + $button = $( '<button type="button" class="notice-dismiss"><span class="screen-reader-text"></span></button>' ),
132 + btnText = commonL10n.dismiss || '';
264 133
265 - // cancel
266 - $( '#the-list' ).on(
267 - 'click',
268 - '.cancel',
269 - function(){
270 - $( this ).closest( 'tr' ).hide().prev().show();
271 - }
272 - );
134 + // Ensure plain text
135 + $button.find( '.screen-reader-text' ).text( btnText );
273 136
274 - // save settings
275 - $( '#the-list' ).on(
276 - 'click',
277 - '.save',
278 - function(){
279 - var tr = $( this ).closest( 'tr' );
280 - var parts = tr.attr( 'id' ).split( '-' );
137 + $this.append( $button );
281 138
282 - var data = {
283 - action: 'pll_save_options',
284 - pll_ajax_settings: true,
285 - module: parts[parts.length - 1],
286 - _pll_nonce: $( '#_pll_nonce' ).val()
287 - };
288 -
289 - data = tr.find( ':input' ).serialize() + '&' + $.param( data );
290 -
291 - $.post(
292 - ajaxurl,
293 - data,
294 - function( response ) {
295 - var res = wpAjax.parseAjaxResponse( response, 'ajax-response' );
296 - $.each(
297 - res.responses,
298 - function() {
299 - switch ( this.what ) {
300 - case 'license-update':
301 - $( '#pll-license-' + this.data ).replaceWith( this.supplemental.html );
302 - break;
303 - case 'success':
304 - tr.hide().prev().show(); // close only if there is no error
305 - case 'error':
306 - $( '.settings-error' ).remove(); // remove previous messages if any
307 - $( 'h1' ).after( this.data );
308 -
309 - // Make notices dismissible
310 - // copy paste of common.js from WP 4.2.2
311 - $( '.notice.is-dismissible' ).each(
312 - function() {
313 - var $this = $( this ),
314 - $button = $( '<button type="button" class="notice-dismiss"><span class="screen-reader-text"></span></button>' ),
315 - btnText = pll_admin.dismiss_notice || '';
316 -
317 - // Ensure plain text
318 - $button.find( '.screen-reader-text' ).text( btnText );
319 -
320 - // Whitelist because of how the button is built. See above
321 - $this.append( $button ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.append
322 -
323 - $button.on(
324 - 'click.wp-dismiss-notice',
325 - function( event ) {
326 - event.preventDefault();
327 - $this.fadeTo(
328 - 100,
329 - 0,
330 - function() {
331 - $( this ).slideUp(
332 - 100,
333 - function() {
334 - $( this ).remove();
335 - }
336 - );
337 - }
338 - );
339 - }
340 - );
341 - }
342 - );
343 - break;
344 - }
345 - }
346 - );
347 - }
348 - );
349 - }
350 - );
351 -
352 - // act when pressing enter or esc in configurations
353 - $( '.pll-configure' ).on(
354 - 'keydown',
355 - function( event ){
356 - if ( 'Enter' === event.key ) {
357 - event.preventDefault();
358 - $( this ).find( '.save' ).trigger( 'click' );
139 + $button.on( 'click.wp-dismiss-notice', function( event ) {
140 + event.preventDefault();
141 + $this.fadeTo( 100 , 0, function() {
142 + $( this ).slideUp( 100, function() {
143 + $( this ).remove();
144 + });
145 + });
146 + });
147 + });
148 + break;
359 149 }
150 + });
151 + });
152 + });
360 153
361 - if ( 'Escape' === event.key ) {
362 - event.preventDefault();
363 - $( this ).find( '.cancel' ).trigger( 'click' );
364 - }
365 - }
366 - );
154 + // act when pressing enter or esc in configurations
155 + $( '.pll-configure' ).keypress(function( event ){
156 + if ( 13 === event.keyCode ) {
157 + event.preventDefault();
158 + $( this ).find( '.save' ).click();
159 + }
367 160
368 - // settings URL modifications
369 - // manages visibility of fields
370 - $( "input[name='force_lang']" ).on(
371 - 'change',
372 - function() {
373 - function pll_toggle( a, test ) {
374 - test ? a.show() : a.hide();
375 - }
161 + if ( 27 === event.keyCode ) {
162 + event.preventDefault();
163 + $( this ).find( '.cancel' ).click();
164 + }
165 + });
376 166
377 - var value = $( this ).val();
378 - pll_toggle( $( '#pll-domains-table' ), 3 == value );
379 - pll_toggle( $( "#pll-hide-default" ), 3 > value );
380 - pll_toggle( $( "#pll-rewrite" ), 2 > value );
381 - pll_toggle( $( "#pll-redirect-lang" ), 2 > value );
382 - }
383 - );
167 + // settings URL modifications
168 + // manages visibility of fields
169 + $( "input[name='force_lang']" ).change(function() {
170 + function pll_toggle( a, test ) {
171 + test ? a.show() : a.hide();
172 + }
384 173
385 - // settings license
386 - // deactivate button
387 - $( '.pll-deactivate-license' ).on(
388 - 'click',
389 - function() {
390 - var data = {
391 - action: 'pll_deactivate_license',
392 - pll_ajax_settings: true,
393 - id: $( this ).attr( 'id' ),
394 - _pll_nonce: $( '#_pll_nonce' ).val()
395 - };
396 - $.post(
397 - ajaxurl,
398 - data,
399 - function( response ){
400 - $( '#pll-license-' + response.id ).replaceWith( response.html );
401 - }
402 - );
403 - }
404 - );
174 + var value = $( this ).val();
175 + pll_toggle( $( '#pll-domains-table' ), 3 == value );
176 + pll_toggle( $( "#pll-hide-default" ), 3 > value );
177 + pll_toggle( $( "#pll-rewrite" ), 2 > value );
178 + pll_toggle( $( "#pll-redirect-lang" ), 2 > value );
179 + });
405 180
406 - // Manage closing the metabox.
407 - // close postboxes that should be closed
408 - $( '.if-js-closed' ).removeClass( 'if-js-closed' ).addClass( 'closed' );
409 - // postboxes setup
410 - if ( 'undefined' !== typeof postboxes ) {
411 - postboxes.add_postbox_toggles( pagenow );
181 + // settings license
182 + // deactivate button
183 + $( '.pll-deactivate-license' ).on( 'click', function() {
184 + var data = {
185 + action: 'pll_deactivate_license',
186 + pll_ajax_settings: true,
187 + id: $( this ).attr( 'id' ),
188 + _pll_nonce: $( '#_pll_nonce' ).val()
412 189 }
413 - }
414 -);
190 + $.post( ajaxurl, data , function( response ){
191 + $( '#pll-license-' + response.id ).replaceWith( response.html );
192 + });
193 + });
415 194
195 +});