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 / settings.js

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

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