1 /* global ajaxurl, wpAjax */ |
1 /* global ajaxurl, wpAjax */ |
2 (function($) { |
2 |
3 var fs = {add:'ajaxAdd',del:'ajaxDel',dim:'ajaxDim',process:'process',recolor:'recolor'}, wpList; |
3 /** |
4 |
4 * @param {jQuery} $ jQuery object. |
|
5 */ |
|
6 ( function( $ ) { |
|
7 var functions = { |
|
8 add: 'ajaxAdd', |
|
9 del: 'ajaxDel', |
|
10 dim: 'ajaxDim', |
|
11 process: 'process', |
|
12 recolor: 'recolor' |
|
13 }, wpList; |
|
14 |
|
15 /** |
|
16 * @namespace |
|
17 */ |
5 wpList = { |
18 wpList = { |
|
19 |
|
20 /** |
|
21 * @member {object} |
|
22 */ |
6 settings: { |
23 settings: { |
7 url: ajaxurl, type: 'POST', |
24 |
|
25 /** |
|
26 * URL for Ajax requests. |
|
27 * |
|
28 * @member {string} |
|
29 */ |
|
30 url: ajaxurl, |
|
31 |
|
32 /** |
|
33 * The HTTP method to use for Ajax requests. |
|
34 * |
|
35 * @member {string} |
|
36 */ |
|
37 type: 'POST', |
|
38 |
|
39 /** |
|
40 * ID of the element the parsed Ajax response will be stored in. |
|
41 * |
|
42 * @member {string} |
|
43 */ |
8 response: 'ajax-response', |
44 response: 'ajax-response', |
9 |
45 |
|
46 /** |
|
47 * The type of list. |
|
48 * |
|
49 * @member {string} |
|
50 */ |
10 what: '', |
51 what: '', |
11 alt: 'alternate', altOffset: 0, |
52 |
12 addColor: null, delColor: null, dimAddColor: null, dimDelColor: null, |
53 /** |
13 |
54 * CSS class name for alternate styling. |
|
55 * |
|
56 * @member {string} |
|
57 */ |
|
58 alt: 'alternate', |
|
59 |
|
60 /** |
|
61 * Offset to start alternate styling from. |
|
62 * |
|
63 * @member {number} |
|
64 */ |
|
65 altOffset: 0, |
|
66 |
|
67 /** |
|
68 * Color used in animation when adding an element. |
|
69 * |
|
70 * Can be 'none' to disable the animation. |
|
71 * |
|
72 * @member {string} |
|
73 */ |
|
74 addColor: '#ffff33', |
|
75 |
|
76 /** |
|
77 * Color used in animation when deleting an element. |
|
78 * |
|
79 * Can be 'none' to disable the animation. |
|
80 * |
|
81 * @member {string} |
|
82 */ |
|
83 delColor: '#faafaa', |
|
84 |
|
85 /** |
|
86 * Color used in dim add animation. |
|
87 * |
|
88 * Can be 'none' to disable the animation. |
|
89 * |
|
90 * @member {string} |
|
91 */ |
|
92 dimAddColor: '#ffff33', |
|
93 |
|
94 /** |
|
95 * Color used in dim delete animation. |
|
96 * |
|
97 * Can be 'none' to disable the animation. |
|
98 * |
|
99 * @member {string} |
|
100 */ |
|
101 dimDelColor: '#ff3333', |
|
102 |
|
103 /** |
|
104 * Callback that's run before a request is made. |
|
105 * |
|
106 * @callback wpList~confirm |
|
107 * @param {object} this |
|
108 * @param {HTMLElement} list The list DOM element. |
|
109 * @param {object} settings Settings for the current list. |
|
110 * @param {string} action The type of action to perform: 'add', 'delete', or 'dim'. |
|
111 * @param {string} backgroundColor Background color of the list's DOM element. |
|
112 * @returns {boolean} Whether to proceed with the action or not. |
|
113 */ |
14 confirm: null, |
114 confirm: null, |
15 addBefore: null, addAfter: null, |
115 |
16 delBefore: null, delAfter: null, |
116 /** |
17 dimBefore: null, dimAfter: null |
117 * Callback that's run before an item gets added to the list. |
18 }, |
118 * |
19 |
119 * Allows to cancel the request. |
20 nonce: function(e,s) { |
120 * |
21 var url = wpAjax.unserialize(e.attr('href')); |
121 * @callback wpList~addBefore |
22 return s.nonce || url._ajax_nonce || $('#' + s.element + ' input[name="_ajax_nonce"]').val() || url._wpnonce || $('#' + s.element + ' input[name="_wpnonce"]').val() || 0; |
122 * @param {object} settings Settings for the Ajax request. |
23 }, |
123 * @returns {object|boolean} Settings for the Ajax request or false to abort. |
24 |
124 */ |
25 parseData: function(e,t) { |
125 addBefore: null, |
26 var d = [], wpListsData; |
126 |
|
127 /** |
|
128 * Callback that's run after an item got added to the list. |
|
129 * |
|
130 * @callback wpList~addAfter |
|
131 * @param {XML} returnedResponse Raw response returned from the server. |
|
132 * @param {object} settings Settings for the Ajax request. |
|
133 * @param {jqXHR} settings.xml jQuery XMLHttpRequest object. |
|
134 * @param {string} settings.status Status of the request: 'success', 'notmodified', 'nocontent', 'error', |
|
135 * 'timeout', 'abort', or 'parsererror'. |
|
136 * @param {object} settings.parsed Parsed response object. |
|
137 */ |
|
138 addAfter: null, |
|
139 |
|
140 /** |
|
141 * Callback that's run before an item gets deleted from the list. |
|
142 * |
|
143 * Allows to cancel the request. |
|
144 * |
|
145 * @callback wpList~delBefore |
|
146 * @param {object} settings Settings for the Ajax request. |
|
147 * @param {HTMLElement} list The list DOM element. |
|
148 * @returns {object|boolean} Settings for the Ajax request or false to abort. |
|
149 */ |
|
150 delBefore: null, |
|
151 |
|
152 /** |
|
153 * Callback that's run after an item got deleted from the list. |
|
154 * |
|
155 * @callback wpList~delAfter |
|
156 * @param {XML} returnedResponse Raw response returned from the server. |
|
157 * @param {object} settings Settings for the Ajax request. |
|
158 * @param {jqXHR} settings.xml jQuery XMLHttpRequest object. |
|
159 * @param {string} settings.status Status of the request: 'success', 'notmodified', 'nocontent', 'error', |
|
160 * 'timeout', 'abort', or 'parsererror'. |
|
161 * @param {object} settings.parsed Parsed response object. |
|
162 */ |
|
163 delAfter: null, |
|
164 |
|
165 /** |
|
166 * Callback that's run before an item gets dim'd. |
|
167 * |
|
168 * Allows to cancel the request. |
|
169 * |
|
170 * @callback wpList~dimBefore |
|
171 * @param {object} settings Settings for the Ajax request. |
|
172 * @returns {object|boolean} Settings for the Ajax request or false to abort. |
|
173 */ |
|
174 dimBefore: null, |
|
175 |
|
176 /** |
|
177 * Callback that's run after an item got dim'd. |
|
178 * |
|
179 * @callback wpList~dimAfter |
|
180 * @param {XML} returnedResponse Raw response returned from the server. |
|
181 * @param {object} settings Settings for the Ajax request. |
|
182 * @param {jqXHR} settings.xml jQuery XMLHttpRequest object. |
|
183 * @param {string} settings.status Status of the request: 'success', 'notmodified', 'nocontent', 'error', |
|
184 * 'timeout', 'abort', or 'parsererror'. |
|
185 * @param {object} settings.parsed Parsed response object. |
|
186 */ |
|
187 dimAfter: null |
|
188 }, |
|
189 |
|
190 /** |
|
191 * Finds a nonce. |
|
192 * |
|
193 * 1. Nonce in settings. |
|
194 * 2. `_ajax_nonce` value in element's href attribute. |
|
195 * 3. `_ajax_nonce` input field that is a descendant of element. |
|
196 * 4. `_wpnonce` value in element's href attribute. |
|
197 * 5. `_wpnonce` input field that is a descendant of element. |
|
198 * 6. 0 if none can be found. |
|
199 * |
|
200 * @param {jQuery} element Element that triggered the request. |
|
201 * @param {object} settings Settings for the Ajax request. |
|
202 * @returns {string|number} Nonce |
|
203 */ |
|
204 nonce: function( element, settings ) { |
|
205 var url = wpAjax.unserialize( element.attr( 'href' ) ), |
|
206 $element = $( '#' + settings.element ); |
|
207 |
|
208 return settings.nonce || url._ajax_nonce || $element.find( 'input[name="_ajax_nonce"]' ).val() || url._wpnonce || $element.find( 'input[name="_wpnonce"]' ).val() || 0; |
|
209 }, |
|
210 |
|
211 /** |
|
212 * Extract list item data from a DOM element. |
|
213 * |
|
214 * Example 1: data-wp-lists="delete:the-comment-list:comment-{comment_ID}:66cc66:unspam=1" |
|
215 * Example 2: data-wp-lists="dim:the-comment-list:comment-{comment_ID}:unapproved:e7e7d3:e7e7d3:new=approved" |
|
216 * |
|
217 * Returns an unassociated array with the following data: |
|
218 * data[0] - Data identifier: 'list', 'add', 'delete', or 'dim'. |
|
219 * data[1] - ID of the corresponding list. If data[0] is 'list', the type of list ('comment', 'category', etc). |
|
220 * data[2] - ID of the parent element of all inputs necessary for the request. |
|
221 * data[3] - Hex color to be used in this request. If data[0] is 'dim', dim class. |
|
222 * data[4] - Additional arguments in query syntax that are added to the request. Example: 'post_id=1234'. |
|
223 * If data[0] is 'dim', dim add color. |
|
224 * data[5] - Only available if data[0] is 'dim', dim delete color. |
|
225 * data[6] - Only available if data[0] is 'dim', additional arguments in query syntax that are added to the request. |
|
226 * |
|
227 * Result for Example 1: |
|
228 * data[0] - delete |
|
229 * data[1] - the-comment-list |
|
230 * data[2] - comment-{comment_ID} |
|
231 * data[3] - 66cc66 |
|
232 * data[4] - unspam=1 |
|
233 * |
|
234 * @param {HTMLElement} element The DOM element. |
|
235 * @param {string} type The type of data to look for: 'list', 'add', 'delete', or 'dim'. |
|
236 * @returns {Array} Extracted list item data. |
|
237 */ |
|
238 parseData: function( element, type ) { |
|
239 var data = [], wpListsData; |
27 |
240 |
28 try { |
241 try { |
29 wpListsData = $(e).attr('data-wp-lists') || ''; |
242 wpListsData = $( element ).data( 'wp-lists' ) || ''; |
30 wpListsData = wpListsData.match(new RegExp(t+':[\\S]+')); |
243 wpListsData = wpListsData.match( new RegExp( type + ':[\\S]+' ) ); |
31 |
244 |
32 if ( wpListsData ) |
245 if ( wpListsData ) { |
33 d = wpListsData[0].split(':'); |
246 data = wpListsData[0].split( ':' ); |
34 } catch(r) {} |
247 } |
35 |
248 } catch ( error ) {} |
36 return d; |
249 |
37 }, |
250 return data; |
38 |
251 }, |
39 pre: function(e,s,a) { |
252 |
40 var bg, r; |
253 /** |
41 |
254 * Calls a confirm callback to verify the action that is about to be performed. |
42 s = $.extend( {}, this.wpList.settings, { |
255 * |
|
256 * @param {HTMLElement} list The DOM element. |
|
257 * @param {object} settings Settings for this list. |
|
258 * @param {string} action The type of action to perform: 'add', 'delete', or 'dim'. |
|
259 * @returns {object|boolean} Settings if confirmed, false if not. |
|
260 */ |
|
261 pre: function( list, settings, action ) { |
|
262 var $element, backgroundColor, confirmed; |
|
263 |
|
264 settings = $.extend( {}, this.wpList.settings, { |
43 element: null, |
265 element: null, |
44 nonce: 0, |
266 nonce: 0, |
45 target: e.get(0) |
267 target: list.get( 0 ) |
46 }, s || {} ); |
268 }, settings || {} ); |
47 |
269 |
48 if ( $.isFunction( s.confirm ) ) { |
270 if ( $.isFunction( settings.confirm ) ) { |
49 if ( 'add' != a ) { |
271 $element = $( '#' + settings.element ); |
50 bg = $('#' + s.element).css('backgroundColor'); |
272 |
51 $('#' + s.element).css('backgroundColor', '#FF9966'); |
273 if ( 'add' !== action ) { |
52 } |
274 backgroundColor = $element.css( 'backgroundColor' ); |
53 r = s.confirm.call(this, e, s, a, bg); |
275 $element.css( 'backgroundColor', '#ff9966' ); |
54 |
276 } |
55 if ( 'add' != a ) |
277 |
56 $('#' + s.element).css('backgroundColor', bg ); |
278 confirmed = settings.confirm.call( this, list, settings, action, backgroundColor ); |
57 |
279 |
58 if ( !r ) |
280 if ( 'add' !== action ) { |
|
281 $element.css( 'backgroundColor', backgroundColor ); |
|
282 } |
|
283 |
|
284 if ( ! confirmed ) { |
59 return false; |
285 return false; |
60 } |
286 } |
61 |
287 } |
62 return s; |
288 |
63 }, |
289 return settings; |
64 |
290 }, |
65 ajaxAdd: function( e, s ) { |
291 |
66 e = $(e); |
292 /** |
67 s = s || {}; |
293 * Adds an item to the list via AJAX. |
68 var list = this, data = wpList.parseData(e,'add'), es, valid, formData, res, rres; |
294 * |
69 |
295 * @param {HTMLElement} element The DOM element. |
70 s = wpList.pre.call( list, e, s, 'add' ); |
296 * @param {object} settings Settings for this list. |
71 |
297 * @returns {boolean} Whether the item was added. |
72 s.element = data[2] || e.attr( 'id' ) || s.element || null; |
298 */ |
73 |
299 ajaxAdd: function( element, settings ) { |
74 if ( data[3] ) |
300 var list = this, |
75 s.addColor = '#' + data[3]; |
301 $element = $( element ), |
76 else |
302 data = wpList.parseData( $element, 'add' ), |
77 s.addColor = s.addColor || '#FFFF33'; |
303 formValues, formData, parsedResponse, returnedResponse; |
78 |
304 |
79 if ( !s ) |
305 settings = settings || {}; |
|
306 settings = wpList.pre.call( list, $element, settings, 'add' ); |
|
307 |
|
308 settings.element = data[2] || $element.prop( 'id' ) || settings.element || null; |
|
309 settings.addColor = data[3] ? '#' + data[3] : settings.addColor; |
|
310 |
|
311 if ( ! settings ) { |
80 return false; |
312 return false; |
81 |
313 } |
82 if ( !e.is('[id="' + s.element + '-submit"]') ) |
314 |
83 return !wpList.add.call( list, e, s ); |
315 if ( ! $element.is( '[id="' + settings.element + '-submit"]' ) ) { |
84 |
316 return ! wpList.add.call( list, $element, settings ); |
85 if ( !s.element ) |
317 } |
|
318 |
|
319 if ( ! settings.element ) { |
86 return true; |
320 return true; |
87 |
321 } |
88 s.action = 'add-' + s.what; |
322 |
89 |
323 settings.action = 'add-' + settings.what; |
90 s.nonce = wpList.nonce(e,s); |
324 settings.nonce = wpList.nonce( $element, settings ); |
91 |
325 |
92 es = $('#' + s.element + ' :input').not('[name="_ajax_nonce"], [name="_wpnonce"], [name="action"]'); |
326 if ( ! wpAjax.validateForm( '#' + settings.element ) ) { |
93 valid = wpAjax.validateForm( '#' + s.element ); |
|
94 |
|
95 if ( !valid ) |
|
96 return false; |
327 return false; |
97 |
328 } |
98 s.data = $.param( $.extend( { _ajax_nonce: s.nonce, action: s.action }, wpAjax.unserialize( data[4] || '' ) ) ); |
329 |
99 formData = $.isFunction(es.fieldSerialize) ? es.fieldSerialize() : es.serialize(); |
330 settings.data = $.param( $.extend( { |
100 |
331 _ajax_nonce: settings.nonce, |
101 if ( formData ) |
332 action: settings.action |
102 s.data += '&' + formData; |
333 }, wpAjax.unserialize( data[4] || '' ) ) ); |
103 |
334 |
104 if ( $.isFunction(s.addBefore) ) { |
335 formValues = $( '#' + settings.element + ' :input' ).not( '[name="_ajax_nonce"], [name="_wpnonce"], [name="action"]' ); |
105 s = s.addBefore( s ); |
336 formData = $.isFunction( formValues.fieldSerialize ) ? formValues.fieldSerialize() : formValues.serialize(); |
106 if ( !s ) |
337 |
|
338 if ( formData ) { |
|
339 settings.data += '&' + formData; |
|
340 } |
|
341 |
|
342 if ( $.isFunction( settings.addBefore ) ) { |
|
343 settings = settings.addBefore( settings ); |
|
344 |
|
345 if ( ! settings ) { |
107 return true; |
346 return true; |
108 } |
347 } |
109 |
348 } |
110 if ( !s.data.match(/_ajax_nonce=[a-f0-9]+/) ) |
349 |
|
350 if ( ! settings.data.match( /_ajax_nonce=[a-f0-9]+/ ) ) { |
111 return true; |
351 return true; |
112 |
352 } |
113 s.success = function(r) { |
353 |
114 res = wpAjax.parseAjaxResponse(r, s.response, s.element); |
354 settings.success = function( response ) { |
115 |
355 parsedResponse = wpAjax.parseAjaxResponse( response, settings.response, settings.element ); |
116 rres = r; |
356 returnedResponse = response; |
117 |
357 |
118 if ( !res || res.errors ) |
358 if ( ! parsedResponse || parsedResponse.errors ) { |
119 return false; |
359 return false; |
120 |
360 } |
121 if ( true === res ) |
361 |
|
362 if ( true === parsedResponse ) { |
122 return true; |
363 return true; |
123 |
364 } |
124 jQuery.each( res.responses, function() { |
365 |
125 wpList.add.call( list, this.data, $.extend( {}, s, { // this.firstChild.nodevalue |
366 $.each( parsedResponse.responses, function() { |
126 pos: this.position || 0, |
367 wpList.add.call( list, this.data, $.extend( {}, settings, { // this.firstChild.nodevalue |
127 id: this.id || 0, |
368 position: this.position || 0, |
128 oldId: this.oldId || null |
369 id: this.id || 0, |
|
370 oldId: this.oldId || null |
129 } ) ); |
371 } ) ); |
130 } ); |
372 } ); |
131 |
373 |
132 list.wpList.recolor(); |
374 list.wpList.recolor(); |
133 $(list).trigger( 'wpListAddEnd', [ s, list.wpList ] ); |
375 $( list ).trigger( 'wpListAddEnd', [ settings, list.wpList ] ); |
134 wpList.clear.call(list,'#' + s.element); |
376 wpList.clear.call( list, '#' + settings.element ); |
135 }; |
377 }; |
136 |
378 |
137 s.complete = function(x, st) { |
379 settings.complete = function( jqXHR, status ) { |
138 if ( $.isFunction(s.addAfter) ) { |
380 if ( $.isFunction( settings.addAfter ) ) { |
139 var _s = $.extend( { xml: x, status: st, parsed: res }, s ); |
381 settings.addAfter( returnedResponse, $.extend( { |
140 s.addAfter( rres, _s ); |
382 xml: jqXHR, |
|
383 status: status, |
|
384 parsed: parsedResponse |
|
385 }, settings ) ); |
141 } |
386 } |
142 }; |
387 }; |
143 |
388 |
144 $.ajax( s ); |
389 $.ajax( settings ); |
|
390 |
145 return false; |
391 return false; |
146 }, |
392 }, |
147 |
393 |
148 ajaxDel: function( e, s ) { |
394 /** |
149 e = $(e); |
395 * Delete an item in the list via AJAX. |
150 s = s || {}; |
396 * |
151 var list = this, data = wpList.parseData(e,'delete'), element, res, rres; |
397 * @param {HTMLElement} element A DOM element containing item data. |
152 |
398 * @param {object} settings Settings for this list. |
153 s = wpList.pre.call( list, e, s, 'delete' ); |
399 * @returns {boolean} Whether the item was deleted. |
154 |
400 */ |
155 s.element = data[2] || s.element || null; |
401 ajaxDel: function( element, settings ) { |
156 |
402 var list = this, |
157 if ( data[3] ) |
403 $element = $( element ), |
158 s.delColor = '#' + data[3]; |
404 data = wpList.parseData( $element, 'delete' ), |
159 else |
405 $eventTarget, parsedResponse, returnedResponse; |
160 s.delColor = s.delColor || '#faa'; |
406 |
161 |
407 settings = settings || {}; |
162 if ( !s || !s.element ) |
408 settings = wpList.pre.call( list, $element, settings, 'delete' ); |
|
409 |
|
410 settings.element = data[2] || settings.element || null; |
|
411 settings.delColor = data[3] ? '#' + data[3] : settings.delColor; |
|
412 |
|
413 if ( ! settings || ! settings.element ) { |
163 return false; |
414 return false; |
164 |
415 } |
165 s.action = 'delete-' + s.what; |
416 |
166 |
417 settings.action = 'delete-' + settings.what; |
167 s.nonce = wpList.nonce(e,s); |
418 settings.nonce = wpList.nonce( $element, settings ); |
168 |
419 |
169 s.data = $.extend( |
420 settings.data = $.extend( { |
170 { action: s.action, id: s.element.split('-').pop(), _ajax_nonce: s.nonce }, |
421 _ajax_nonce: settings.nonce, |
171 wpAjax.unserialize( data[4] || '' ) |
422 action: settings.action, |
172 ); |
423 id: settings.element.split( '-' ).pop() |
173 |
424 }, wpAjax.unserialize( data[4] || '' ) ); |
174 if ( $.isFunction(s.delBefore) ) { |
425 |
175 s = s.delBefore( s, list ); |
426 if ( $.isFunction( settings.delBefore ) ) { |
176 if ( !s ) |
427 settings = settings.delBefore( settings, list ); |
|
428 |
|
429 if ( ! settings ) { |
177 return true; |
430 return true; |
178 } |
431 } |
179 |
432 } |
180 if ( !s.data._ajax_nonce ) |
433 |
|
434 if ( ! settings.data._ajax_nonce ) { |
181 return true; |
435 return true; |
182 |
436 } |
183 element = $('#' + s.element); |
437 |
184 |
438 $eventTarget = $( '#' + settings.element ); |
185 if ( 'none' != s.delColor ) { |
439 |
186 element.css( 'backgroundColor', s.delColor ).fadeOut( 350, function(){ |
440 if ( 'none' !== settings.delColor ) { |
|
441 $eventTarget.css( 'backgroundColor', settings.delColor ).fadeOut( 350, function() { |
187 list.wpList.recolor(); |
442 list.wpList.recolor(); |
188 $(list).trigger( 'wpListDelEnd', [ s, list.wpList ] ); |
443 $( list ).trigger( 'wpListDelEnd', [ settings, list.wpList ] ); |
189 }); |
444 } ); |
190 } else { |
445 } else { |
191 list.wpList.recolor(); |
446 list.wpList.recolor(); |
192 $(list).trigger( 'wpListDelEnd', [ s, list.wpList ] ); |
447 $( list ).trigger( 'wpListDelEnd', [ settings, list.wpList ] ); |
193 } |
448 } |
194 |
449 |
195 s.success = function(r) { |
450 settings.success = function( response ) { |
196 res = wpAjax.parseAjaxResponse(r, s.response, s.element); |
451 parsedResponse = wpAjax.parseAjaxResponse( response, settings.response, settings.element ); |
197 rres = r; |
452 returnedResponse = response; |
198 |
453 |
199 if ( !res || res.errors ) { |
454 if ( ! parsedResponse || parsedResponse.errors ) { |
200 element.stop().stop().css( 'backgroundColor', '#faa' ).show().queue( function() { list.wpList.recolor(); $(this).dequeue(); } ); |
455 $eventTarget.stop().stop().css( 'backgroundColor', '#faa' ).show().queue( function() { |
|
456 list.wpList.recolor(); |
|
457 $( this ).dequeue(); |
|
458 } ); |
|
459 |
201 return false; |
460 return false; |
202 } |
461 } |
203 }; |
462 }; |
204 |
463 |
205 s.complete = function(x, st) { |
464 settings.complete = function( jqXHR, status ) { |
206 if ( $.isFunction(s.delAfter) ) { |
465 if ( $.isFunction( settings.delAfter ) ) { |
207 element.queue( function() { |
466 $eventTarget.queue( function() { |
208 var _s = $.extend( { xml: x, status: st, parsed: res }, s ); |
467 settings.delAfter( returnedResponse, $.extend( { |
209 s.delAfter( rres, _s ); |
468 xml: jqXHR, |
210 }).dequeue(); |
469 status: status, |
|
470 parsed: parsedResponse |
|
471 }, settings ) ); |
|
472 } ).dequeue(); |
211 } |
473 } |
212 }; |
474 }; |
213 |
475 |
214 $.ajax( s ); |
476 $.ajax( settings ); |
|
477 |
215 return false; |
478 return false; |
216 }, |
479 }, |
217 |
480 |
218 ajaxDim: function( e, s ) { |
481 /** |
219 if ( $(e).parent().css('display') == 'none' ) // Prevent hidden links from being clicked by hotkeys |
482 * Dim an item in the list via AJAX. |
|
483 * |
|
484 * @param {HTMLElement} element A DOM element containing item data. |
|
485 * @param {object} settings Settings for this list. |
|
486 * @returns {boolean} Whether the item was dim'ed. |
|
487 */ |
|
488 ajaxDim: function( element, settings ) { |
|
489 var list = this, |
|
490 $element = $( element ), |
|
491 data = wpList.parseData( $element, 'dim' ), |
|
492 $eventTarget, isClass, color, dimColor, parsedResponse, returnedResponse; |
|
493 |
|
494 // Prevent hidden links from being clicked by hotkeys. |
|
495 if ( 'none' === $element.parent().css( 'display' ) ) { |
220 return false; |
496 return false; |
221 |
497 } |
222 e = $(e); |
498 |
223 s = s || {}; |
499 settings = settings || {}; |
224 |
500 settings = wpList.pre.call( list, $element, settings, 'dim' ); |
225 var list = this, data = wpList.parseData(e,'dim'), element, isClass, color, dimColor, res, rres; |
501 |
226 |
502 settings.element = data[2] || settings.element || null; |
227 s = wpList.pre.call( list, e, s, 'dim' ); |
503 settings.dimClass = data[3] || settings.dimClass || null; |
228 |
504 settings.dimAddColor = data[4] ? '#' + data[4] : settings.dimAddColor; |
229 s.element = data[2] || s.element || null; |
505 settings.dimDelColor = data[5] ? '#' + data[5] : settings.dimDelColor; |
230 s.dimClass = data[3] || s.dimClass || null; |
506 |
231 |
507 if ( ! settings || ! settings.element || ! settings.dimClass ) { |
232 if ( data[4] ) |
|
233 s.dimAddColor = '#' + data[4]; |
|
234 else |
|
235 s.dimAddColor = s.dimAddColor || '#FFFF33'; |
|
236 |
|
237 if ( data[5] ) |
|
238 s.dimDelColor = '#' + data[5]; |
|
239 else |
|
240 s.dimDelColor = s.dimDelColor || '#FF3333'; |
|
241 |
|
242 if ( !s || !s.element || !s.dimClass ) |
|
243 return true; |
508 return true; |
244 |
509 } |
245 s.action = 'dim-' + s.what; |
510 |
246 |
511 settings.action = 'dim-' + settings.what; |
247 s.nonce = wpList.nonce(e,s); |
512 settings.nonce = wpList.nonce( $element, settings ); |
248 |
513 |
249 s.data = $.extend( |
514 settings.data = $.extend( { |
250 { action: s.action, id: s.element.split('-').pop(), dimClass: s.dimClass, _ajax_nonce : s.nonce }, |
515 _ajax_nonce: settings.nonce, |
251 wpAjax.unserialize( data[6] || '' ) |
516 action: settings.action, |
252 ); |
517 id: settings.element.split( '-' ).pop(), |
253 |
518 dimClass: settings.dimClass |
254 if ( $.isFunction(s.dimBefore) ) { |
519 }, wpAjax.unserialize( data[6] || '' ) ); |
255 s = s.dimBefore( s ); |
520 |
256 if ( !s ) |
521 if ( $.isFunction( settings.dimBefore ) ) { |
|
522 settings = settings.dimBefore( settings ); |
|
523 |
|
524 if ( ! settings ) { |
257 return true; |
525 return true; |
258 } |
526 } |
259 |
527 } |
260 element = $('#' + s.element); |
528 |
261 isClass = element.toggleClass(s.dimClass).is('.' + s.dimClass); |
529 $eventTarget = $( '#' + settings.element ); |
262 color = wpList.getColor( element ); |
530 isClass = $eventTarget.toggleClass( settings.dimClass ).is( '.' + settings.dimClass ); |
263 element.toggleClass( s.dimClass ); |
531 color = wpList.getColor( $eventTarget ); |
264 dimColor = isClass ? s.dimAddColor : s.dimDelColor; |
532 dimColor = isClass ? settings.dimAddColor : settings.dimDelColor; |
265 |
533 $eventTarget.toggleClass( settings.dimClass ); |
266 if ( 'none' != dimColor ) { |
534 |
267 element |
535 if ( 'none' !== dimColor ) { |
|
536 $eventTarget |
268 .animate( { backgroundColor: dimColor }, 'fast' ) |
537 .animate( { backgroundColor: dimColor }, 'fast' ) |
269 .queue( function() { element.toggleClass(s.dimClass); $(this).dequeue(); } ) |
538 .queue( function() { |
270 .animate( { backgroundColor: color }, { complete: function() { |
539 $eventTarget.toggleClass( settings.dimClass ); |
271 $(this).css( 'backgroundColor', '' ); |
540 $( this ).dequeue(); |
272 $(list).trigger( 'wpListDimEnd', [ s, list.wpList ] ); |
541 } ) |
|
542 .animate( { backgroundColor: color }, { |
|
543 complete: function() { |
|
544 $( this ).css( 'backgroundColor', '' ); |
|
545 $( list ).trigger( 'wpListDimEnd', [ settings, list.wpList ] ); |
273 } |
546 } |
274 }); |
547 } ); |
275 } else { |
548 } else { |
276 $(list).trigger( 'wpListDimEnd', [ s, list.wpList ] ); |
549 $( list ).trigger( 'wpListDimEnd', [ settings, list.wpList ] ); |
277 } |
550 } |
278 |
551 |
279 if ( !s.data._ajax_nonce ) |
552 if ( ! settings.data._ajax_nonce ) { |
280 return true; |
553 return true; |
281 |
554 } |
282 s.success = function(r) { |
555 |
283 res = wpAjax.parseAjaxResponse(r, s.response, s.element); |
556 settings.success = function( response ) { |
284 rres = r; |
557 parsedResponse = wpAjax.parseAjaxResponse( response, settings.response, settings.element ); |
285 |
558 returnedResponse = response; |
286 if ( !res || res.errors ) { |
559 |
287 element.stop().stop().css( 'backgroundColor', '#FF3333' )[isClass?'removeClass':'addClass'](s.dimClass).show().queue( function() { list.wpList.recolor(); $(this).dequeue(); } ); |
560 if ( true === parsedResponse ) { |
|
561 return true; |
|
562 } |
|
563 |
|
564 if ( ! parsedResponse || parsedResponse.errors ) { |
|
565 $eventTarget.stop().stop().css( 'backgroundColor', '#ff3333' )[isClass ? 'removeClass' : 'addClass']( settings.dimClass ).show().queue( function() { |
|
566 list.wpList.recolor(); |
|
567 $( this ).dequeue(); |
|
568 } ); |
|
569 |
288 return false; |
570 return false; |
289 } |
571 } |
|
572 |
|
573 /** @property {string} comment_link Link of the comment to be dimmed. */ |
|
574 if ( 'undefined' !== typeof parsedResponse.responses[0].supplemental.comment_link ) { |
|
575 var $submittedOn = $element.find( '.submitted-on' ), |
|
576 $commentLink = $submittedOn.find( 'a' ); |
|
577 |
|
578 // Comment is approved; link the date field. |
|
579 if ( '' !== parsedResponse.responses[0].supplemental.comment_link ) { |
|
580 $submittedOn.html( $('<a></a>').text( $submittedOn.text() ).prop( 'href', parsedResponse.responses[0].supplemental.comment_link ) ); |
|
581 |
|
582 // Comment is not approved; unlink the date field. |
|
583 } else if ( $commentLink.length ) { |
|
584 $submittedOn.text( $commentLink.text() ); |
|
585 } |
|
586 } |
290 }; |
587 }; |
291 |
588 |
292 s.complete = function(x, st) { |
589 settings.complete = function( jqXHR, status ) { |
293 if ( $.isFunction(s.dimAfter) ) { |
590 if ( $.isFunction( settings.dimAfter ) ) { |
294 element.queue( function() { |
591 $eventTarget.queue( function() { |
295 var _s = $.extend( { xml: x, status: st, parsed: res }, s ); |
592 settings.dimAfter( returnedResponse, $.extend( { |
296 s.dimAfter( rres, _s ); |
593 xml: jqXHR, |
297 }).dequeue(); |
594 status: status, |
|
595 parsed: parsedResponse |
|
596 }, settings ) ); |
|
597 } ).dequeue(); |
298 } |
598 } |
299 }; |
599 }; |
300 |
600 |
301 $.ajax( s ); |
601 $.ajax( settings ); |
|
602 |
302 return false; |
603 return false; |
303 }, |
604 }, |
304 |
605 |
305 getColor: function( el ) { |
606 /** |
306 var color = jQuery(el).css('backgroundColor'); |
607 * Returns the background color of the passed element. |
307 |
608 * |
308 return color || '#ffffff'; |
609 * @param {jQuery|string} element Element to check. |
309 }, |
610 * @returns {string} Background color value in HEX. Default: '#ffffff'. |
310 |
611 */ |
311 add: function( e, s ) { |
612 getColor: function( element ) { |
312 if ( 'string' == typeof e ) { |
613 return $( element ).css( 'backgroundColor' ) || '#ffffff'; |
313 e = $( $.trim( e ) ); // Trim leading whitespaces |
614 }, |
314 } else { |
615 |
315 e = $( e ); |
616 /** |
316 } |
617 * Adds something. |
317 |
618 * |
318 var list = $(this), old = false, _s = { pos: 0, id: 0, oldId: null }, ba, ref, color; |
619 * @param {HTMLElement} element A DOM element containing item data. |
319 |
620 * @param {object} settings Settings for this list. |
320 if ( 'string' == typeof s ) |
621 * @returns {boolean} Whether the item was added. |
321 s = { what: s }; |
622 */ |
322 |
623 add: function( element, settings ) { |
323 s = $.extend(_s, this.wpList.settings, s); |
624 var $list = $( this ), |
324 |
625 $element = $( element ), |
325 if ( !e.size() || !s.what ) |
626 old = false, |
|
627 position, reference; |
|
628 |
|
629 if ( 'string' === typeof settings ) { |
|
630 settings = { what: settings }; |
|
631 } |
|
632 |
|
633 settings = $.extend( { position: 0, id: 0, oldId: null }, this.wpList.settings, settings ); |
|
634 |
|
635 if ( ! $element.length || ! settings.what ) { |
326 return false; |
636 return false; |
327 |
637 } |
328 if ( s.oldId ) |
638 |
329 old = $('#' + s.what + '-' + s.oldId); |
639 if ( settings.oldId ) { |
330 |
640 old = $( '#' + settings.what + '-' + settings.oldId ); |
331 if ( s.id && ( s.id != s.oldId || !old || !old.size() ) ) |
641 } |
332 $('#' + s.what + '-' + s.id).remove(); |
642 |
333 |
643 if ( settings.id && ( settings.id !== settings.oldId || ! old || ! old.length ) ) { |
334 if ( old && old.size() ) { |
644 $( '#' + settings.what + '-' + settings.id ).remove(); |
335 old.before(e); |
645 } |
|
646 |
|
647 if ( old && old.length ) { |
|
648 old.before( $element ); |
336 old.remove(); |
649 old.remove(); |
337 } else if ( isNaN(s.pos) ) { |
650 |
338 ba = 'after'; |
651 } else if ( isNaN( settings.position ) ) { |
339 |
652 position = 'after'; |
340 if ( '-' == s.pos.substr(0,1) ) { |
653 |
341 s.pos = s.pos.substr(1); |
654 if ( '-' === settings.position.substr( 0, 1 ) ) { |
342 ba = 'before'; |
655 settings.position = settings.position.substr( 1 ); |
343 } |
656 position = 'before'; |
344 |
657 } |
345 ref = list.find( '#' + s.pos ); |
658 |
346 |
659 reference = $list.find( '#' + settings.position ); |
347 if ( 1 === ref.size() ) |
660 |
348 ref[ba](e); |
661 if ( 1 === reference.length ) { |
349 else |
662 reference[position]( $element ); |
350 list.append(e); |
|
351 |
|
352 } else if ( 'comment' != s.what || 0 === $('#' + s.element).length ) { |
|
353 if ( s.pos < 0 ) { |
|
354 list.prepend(e); |
|
355 } else { |
663 } else { |
356 list.append(e); |
664 $list.append( $element ); |
357 } |
665 } |
358 } |
666 |
359 |
667 } else if ( 'comment' !== settings.what || 0 === $( '#' + settings.element ).length ) { |
360 if ( s.alt ) { |
668 if ( settings.position < 0 ) { |
361 if ( ( list.children(':visible').index( e[0] ) + s.altOffset ) % 2 ) { e.removeClass( s.alt ); } |
669 $list.prepend( $element ); |
362 else { e.addClass( s.alt ); } |
670 } else { |
363 } |
671 $list.append( $element ); |
364 |
672 } |
365 if ( 'none' != s.addColor ) { |
673 } |
366 color = wpList.getColor( e ); |
674 |
367 e.css( 'backgroundColor', s.addColor ).animate( { backgroundColor: color }, { complete: function() { $(this).css( 'backgroundColor', '' ); } } ); |
675 if ( settings.alt ) { |
368 } |
676 $element.toggleClass( settings.alt, ( $list.children( ':visible' ).index( $element[0] ) + settings.altOffset ) % 2 ); |
369 list.each( function() { this.wpList.process( e ); } ); |
677 } |
370 return e; |
678 |
371 }, |
679 if ( 'none' !== settings.addColor ) { |
372 |
680 $element.css( 'backgroundColor', settings.addColor ).animate( { backgroundColor: wpList.getColor( $element ) }, { |
373 clear: function(e) { |
681 complete: function() { |
374 var list = this, t, tag; |
682 $( this ).css( 'backgroundColor', '' ); |
375 |
683 } |
376 e = $(e); |
684 } ); |
377 |
685 } |
378 if ( list.wpList && e.parents( '#' + list.id ).size() ) |
686 |
|
687 // Add event handlers. |
|
688 $list.each( function( index, list ) { |
|
689 list.wpList.process( $element ); |
|
690 } ); |
|
691 |
|
692 return $element; |
|
693 }, |
|
694 |
|
695 /** |
|
696 * Clears all input fields within the element passed. |
|
697 * |
|
698 * @param {string} elementId ID of the element to check, including leading #. |
|
699 */ |
|
700 clear: function( elementId ) { |
|
701 var list = this, |
|
702 $element = $( elementId ), |
|
703 type, tagName; |
|
704 |
|
705 // Bail if we're within the list. |
|
706 if ( list.wpList && $element.parents( '#' + list.id ).length ) { |
379 return; |
707 return; |
380 |
708 } |
381 e.find(':input').each( function() { |
709 |
382 if ( $(this).parents('.form-no-clear').size() ) |
710 // Check each input field. |
|
711 $element.find( ':input' ).each( function( index, input ) { |
|
712 |
|
713 // Bail if the form was marked to not to be cleared. |
|
714 if ( $( input ).parents( '.form-no-clear' ).length ) { |
383 return; |
715 return; |
384 |
716 } |
385 t = this.type.toLowerCase(); |
717 |
386 tag = this.tagName.toLowerCase(); |
718 type = input.type.toLowerCase(); |
387 |
719 tagName = input.tagName.toLowerCase(); |
388 if ( 'text' == t || 'password' == t || 'textarea' == tag ) |
720 |
389 this.value = ''; |
721 if ( 'text' === type || 'password' === type || 'textarea' === tagName ) { |
390 else if ( 'checkbox' == t || 'radio' == t ) |
722 input.value = ''; |
391 this.checked = false; |
723 |
392 else if ( 'select' == tag ) |
724 } else if ( 'checkbox' === type || 'radio' === type ) { |
393 this.selectedIndex = null; |
725 input.checked = false; |
394 }); |
726 |
395 }, |
727 } else if ( 'select' === tagName ) { |
396 |
728 input.selectedIndex = null; |
397 process: function(el) { |
729 } |
398 var list = this, |
730 } ); |
399 $el = $(el || document); |
731 }, |
400 |
732 |
401 $el.delegate( 'form[data-wp-lists^="add:' + list.id + ':"]', 'submit', function(){ |
733 /** |
402 return list.wpList.add(this); |
734 * Registers event handlers to add, delete, and dim items. |
403 }); |
735 * |
404 |
736 * @param {string} elementId |
405 $el.delegate( 'a[data-wp-lists^="add:' + list.id + ':"], input[data-wp-lists^="add:' + list.id + ':"]', 'click', function(){ |
737 */ |
406 return list.wpList.add(this); |
738 process: function( elementId ) { |
407 }); |
739 var list = this, |
408 |
740 $element = $( elementId || document ); |
409 $el.delegate( '[data-wp-lists^="delete:' + list.id + ':"]', 'click', function(){ |
741 |
410 return list.wpList.del(this); |
742 $element.on( 'submit', 'form[data-wp-lists^="add:' + list.id + ':"]', function() { |
411 }); |
743 return list.wpList.add( this ); |
412 |
744 } ); |
413 $el.delegate( '[data-wp-lists^="dim:' + list.id + ':"]', 'click', function(){ |
745 |
414 return list.wpList.dim(this); |
746 $element.on( 'click', 'a[data-wp-lists^="add:' + list.id + ':"], input[data-wp-lists^="add:' + list.id + ':"]', function() { |
415 }); |
747 return list.wpList.add( this ); |
416 }, |
748 } ); |
417 |
749 |
|
750 $element.on( 'click', '[data-wp-lists^="delete:' + list.id + ':"]', function() { |
|
751 return list.wpList.del( this ); |
|
752 } ); |
|
753 |
|
754 $element.on( 'click', '[data-wp-lists^="dim:' + list.id + ':"]', function() { |
|
755 return list.wpList.dim( this ); |
|
756 } ); |
|
757 }, |
|
758 |
|
759 /** |
|
760 * Updates list item background colors. |
|
761 */ |
418 recolor: function() { |
762 recolor: function() { |
419 var list = this, items, eo; |
763 var list = this, |
420 |
764 evenOdd = [':even', ':odd'], |
421 if ( !list.wpList.settings.alt ) |
765 items; |
|
766 |
|
767 // Bail if there is no alternate class name specified. |
|
768 if ( ! list.wpList.settings.alt ) { |
422 return; |
769 return; |
423 |
770 } |
424 items = $('.list-item:visible', list); |
771 |
425 |
772 items = $( '.list-item:visible', list ); |
426 if ( !items.size() ) |
773 |
427 items = $(list).children(':visible'); |
774 if ( ! items.length ) { |
428 |
775 items = $( list ).children( ':visible' ); |
429 eo = [':even',':odd']; |
776 } |
430 |
777 |
431 if ( list.wpList.settings.altOffset % 2 ) |
778 if ( list.wpList.settings.altOffset % 2 ) { |
432 eo.reverse(); |
779 evenOdd.reverse(); |
433 |
780 } |
434 items.filter(eo[0]).addClass(list.wpList.settings.alt).end().filter(eo[1]).removeClass(list.wpList.settings.alt); |
781 |
435 }, |
782 items.filter( evenOdd[0] ).addClass( list.wpList.settings.alt ).end(); |
436 |
783 items.filter( evenOdd[1] ).removeClass( list.wpList.settings.alt ); |
|
784 }, |
|
785 |
|
786 /** |
|
787 * Sets up `process()` and `recolor()` functions. |
|
788 */ |
437 init: function() { |
789 init: function() { |
438 var lists = this; |
790 var $list = this; |
439 |
791 |
440 lists.wpList.process = function(a) { |
792 $list.wpList.process = function( element ) { |
441 lists.each( function() { |
793 $list.each( function() { |
442 this.wpList.process(a); |
794 this.wpList.process( element ); |
443 } ); |
795 } ); |
444 }; |
796 }; |
445 |
797 |
446 lists.wpList.recolor = function() { |
798 $list.wpList.recolor = function() { |
447 lists.each( function() { |
799 $list.each( function() { |
448 this.wpList.recolor(); |
800 this.wpList.recolor(); |
449 } ); |
801 } ); |
450 }; |
802 }; |
451 } |
803 } |
452 }; |
804 }; |
453 |
805 |
|
806 /** |
|
807 * Initializes wpList object. |
|
808 * |
|
809 * @param {Object} settings |
|
810 * @param {string} settings.url URL for ajax calls. Default: ajaxurl. |
|
811 * @param {string} settings.type The HTTP method to use for Ajax requests. Default: 'POST'. |
|
812 * @param {string} settings.response ID of the element the parsed ajax response will be stored in. |
|
813 * Default: 'ajax-response'. |
|
814 * |
|
815 * @param {string} settings.what Default: ''. |
|
816 * @param {string} settings.alt CSS class name for alternate styling. Default: 'alternate'. |
|
817 * @param {number} settings.altOffset Offset to start alternate styling from. Default: 0. |
|
818 * @param {string} settings.addColor Hex code or 'none' to disable animation. Default: '#ffff33'. |
|
819 * @param {string} settings.delColor Hex code or 'none' to disable animation. Default: '#faafaa'. |
|
820 * @param {string} settings.dimAddColor Hex code or 'none' to disable animation. Default: '#ffff33'. |
|
821 * @param {string} settings.dimDelColor Hex code or 'none' to disable animation. Default: '#ff3333'. |
|
822 * |
|
823 * @param {wpList~confirm} settings.confirm Callback that's run before a request is made. Default: null. |
|
824 * @param {wpList~addBefore} settings.addBefore Callback that's run before an item gets added to the list. |
|
825 * Default: null. |
|
826 * @param {wpList~addAfter} settings.addAfter Callback that's run after an item got added to the list. |
|
827 * Default: null. |
|
828 * @param {wpList~delBefore} settings.delBefore Callback that's run before an item gets deleted from the list. |
|
829 * Default: null. |
|
830 * @param {wpList~delAfter} settings.delAfter Callback that's run after an item got deleted from the list. |
|
831 * Default: null. |
|
832 * @param {wpList~dimBefore} settings.dimBefore Callback that's run before an item gets dim'd. Default: null. |
|
833 * @param {wpList~dimAfter} settings.dimAfter Callback that's run after an item got dim'd. Default: null. |
|
834 * @returns {$.fn} wpList API function. |
|
835 */ |
454 $.fn.wpList = function( settings ) { |
836 $.fn.wpList = function( settings ) { |
455 this.each( function() { |
837 this.each( function( index, list ) { |
456 var _this = this; |
838 list.wpList = { |
457 |
839 settings: $.extend( {}, wpList.settings, { what: wpList.parseData( list, 'list' )[1] || '' }, settings ) |
458 this.wpList = { settings: $.extend( {}, wpList.settings, { what: wpList.parseData(this,'list')[1] || '' }, settings ) }; |
840 }; |
459 $.each( fs, function(i,f) { _this.wpList[i] = function( e, s ) { return wpList[f].call( _this, e, s ); }; } ); |
841 |
|
842 $.each( functions, function( func, callback ) { |
|
843 list.wpList[func] = function( element, setting ) { |
|
844 return wpList[callback].call( list, element, setting ); |
|
845 }; |
|
846 } ); |
460 } ); |
847 } ); |
461 |
848 |
462 wpList.init.call(this); |
849 wpList.init.call( this ); |
463 |
|
464 this.wpList.process(); |
850 this.wpList.process(); |
465 |
851 |
466 return this; |
852 return this; |
467 }; |
853 }; |
468 |
854 } ) ( jQuery ); |
469 })(jQuery); |
|