PluginProbe
Polylang / 0.7
Polylang v0.7
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 +180 -409 2.90.7 View file →
@@ -1,409 +1,180 @@
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 -
1 +jQuery(document).ready(function($) {
2 +
3 + // collect taxonomies - code partly copied from WordPress
4 + var taxonomies = new Array();
5 + $('.categorydiv').each( function(){
6 + var this_id = $(this).attr('id'), taxonomyParts, taxonomy;
7 +
8 + taxonomyParts = this_id.split('-');
9 + taxonomyParts.shift();
10 + taxonomy = taxonomyParts.join('-');
11 + taxonomies.push(taxonomy); // store the taxonomy for future use
12 +
13 + // add our hidden field in the new category form - for each hierarchical taxonomy
14 + jQuery('#' + taxonomy + '-add-submit').before($('<input />')
15 + .attr('type', 'hidden')
16 + .attr('id', taxonomy + '-lang')
17 + .attr('name', 'term_lang_choice')
18 + .attr('value', jQuery('#post_lang_choice').attr('value'))
19 + );
20 + });
21 +
22 + // ajax for post metabox
23 + jQuery('#post_lang_choice').change( function() {
24 + var data = {
25 + action: 'post_lang_choice',
26 + lang: jQuery(this).attr('value'),
27 + taxonomies: taxonomies,
28 + post_id: jQuery('#post_ID').attr('value')
29 + }
30 +
31 + jQuery.post(ajaxurl, data , function(response) {
32 + var res = wpAjax.parseAjaxResponse(response, 'ajax-response');
33 + $.each(res.responses, function() {
34 + switch (this.what) {
35 + case 'translations': // translations fields
36 + jQuery('#post-translations').html(this.data);
37 + break;
38 + case 'taxonomy': // categories metabox for posts
39 + var tax = this.data;
40 + jQuery('#' + tax + 'checklist').html(this.supplemental.all);
41 + jQuery('#' + tax + 'checklist-pop').html(this.supplemental.populars);
42 + jQuery('#new' + tax + '_parent').replaceWith(this.supplemental.dropdown);
43 + jQuery('#' + tax + '-lang').val(jQuery('#post_lang_choice').attr('value')); // hidden field
44 + break;
45 + case 'pages': // parent dropdown list for pages
46 + jQuery('#parent_id').replaceWith(this.data);
47 + break;
48 + default:
49 + break;
50 + }
51 + });
52 +
53 + // modifies the language in the tag cloud
54 + jQuery('.polylang-tagcloud-link').each(function() {
55 + var id = $(this).attr('id');
56 + pll_tagbox(id, 0);
57 + });
58 +
59 + // modifies the language in the tags suggestion input
60 + pll_suggest();
61 + });
62 + });
63 +
64 + // replace WP class by our own
65 + jQuery('a.tagcloud-link').addClass('polylang-tagcloud-link');
66 + jQuery('a.tagcloud-link').removeClass('tagcloud-link');
67 +
68 + // copy paste WP code and just call our pll_tagbox instead of tagbox.get
69 + jQuery('.polylang-tagcloud-link').click( function() {
70 + var id = $(this).attr('id');
71 + pll_tagbox(id, 1);
72 +
73 + $(this).unbind().click(function(){
74 + $(this).siblings('.the-tagcloud').toggle();
75 + return false;
76 + });
77 + return false;
78 + });
79 +
80 + // now copy paste WP code
81 + // add the language in the $_POST variable
82 + // add an if else condition to allow modifying the tags outputed when switching the language
83 + function pll_tagbox(id, a) {
84 + var tax = id.substr(id.indexOf('-')+1);
85 +
86 + var data = {
87 + action: 'get-tagcloud',
88 + lang: jQuery('#post_lang_choice').attr('value'),
89 + tax: tax
90 + }
91 +
92 + $.post(ajaxurl, data, function(r, stat) {
93 + if ( 0 == r || 'success' != stat )
94 + r = wpAjax.broken;
95 +
96 + r = $('<p id="tagcloud-'+tax+'" class="the-tagcloud">'+r+'</p>');
97 + $('a', r).click(function(){
98 + tagBox.flushTags( $(this).closest('.inside').children('.tagsdiv'), this);
99 + return false;
100 + });
101 +
102 + if (a == 1)
103 + $('#'+id).after(r);
104 + else {
105 + v = $('.the-tagcloud').css('display');
106 + $('.the-tagcloud').replaceWith(r);
107 + $('.the-tagcloud').css('display', v);
108 + }
109 + });
110 + }
111 +
112 + // replace WP class by our own
113 + jQuery('input.newtag').addClass('polylang-newtag');
114 + jQuery('input.newtag').removeClass('newtag');
115 + pll_suggest();
116 +
117 + // now copy paste WP code
118 + // add the language in the $_GET variable
119 + // add the unbind function to allow calling the function when the language is modified
120 + function pll_suggest() {
121 + ajaxtag = $('div.ajaxtag');
122 + $('input.polylang-newtag', ajaxtag).unbind().blur(function() {
123 + if ( this.value == '' )
124 + $(this).parent().siblings('.taghint').css('visibility', '');
125 + }).focus(function(){
126 + $(this).parent().siblings('.taghint').css('visibility', 'hidden');
127 + }).keyup(function(e){
128 + if ( 13 == e.which ) {
129 + tagBox.flushTags( $(this).closest('.tagsdiv') );
130 + return false;
131 + }
132 + }).keypress(function(e){
133 + if ( 13 == e.which ) {
134 + e.preventDefault();
135 + return false;
136 + }
137 + }).each(function(){
138 + var lang = jQuery('#post_lang_choice').attr('value');
139 + var tax = $(this).closest('div.tagsdiv').attr('id');
140 + $(this).suggest( ajaxurl + '?action=polylang-ajax-tag-search&lang=' + lang + '&tax=' + tax, { delay: 500, minchars: 2, multiple: true, multipleSep: "," } );
141 + });
142 + }
143 +
144 + // ajax for term edit
145 + jQuery('#term_lang_choice').change(function() {
146 + var data = {
147 + action: 'term_lang_choice',
148 + lang: jQuery(this).attr('value'),
149 + term_id: jQuery("input[name='tag_ID']").attr('value'),
150 + taxonomy: jQuery("input[name='taxonomy']").attr('value')
151 + }
152 +
153 + jQuery.post(ajaxurl, data, function(response) {
154 + var res = wpAjax.parseAjaxResponse(response, 'ajax-response');
155 + $.each(res.responses, function() {
156 + switch (this.what) {
157 + case 'translations': // translations fields
158 + jQuery("#term-translations").html(this.data);
159 + break;
160 + case 'parent': // parent dropdown list for hierarchical taxonomies
161 + jQuery('#parent').replaceWith(this.data);
162 + break;
163 + default:
164 + break;
165 + }
166 + });
167 + });
168 + });
169 +
170 + // languages form
171 + // fills the fields based on dropdown list choice
172 + jQuery('#lang_list').change(function() {
173 + value = jQuery(this).attr('value').split('-');
174 + jQuery('input[name="slug"]').val(value[0]);
175 + jQuery('input[name="description"]').val(value[1]);
176 + jQuery('input[name="rtl"]').val([value[2]]);
177 + jQuery('input[name="name"]').val($("select option:selected").text());
178 + });
179 +
180 +});