]> git.mxchange.org Git - friendica-addons.git/blob - jappixmini/jappix/js/privacy.js
01675f7f26080d840a0e8877fd8d39a69293bc74
[friendica-addons.git] / jappixmini / jappix / js / privacy.js
1 /*
2
3 Jappix - An open social platform
4 These are the privacy JS scripts for Jappix
5
6 -------------------------------------------------
7
8 License: AGPL
9 Author: Vanaryon
10 Last revision: 23/06/11
11
12 */
13
14 // Opens the privacy popup
15 function openPrivacy() {
16         // Popup HTML content
17         var html = 
18         '<div class="top">' + _e("Privacy") + '</div>' + 
19         
20         '<div class="content">' + 
21                 '<div class="privacy-head">' + 
22                         '<div class="list-left">' + 
23                                 '<span>' + _e("Choose") + '</span>' + 
24                                 '<select disabled=""></select>' + 
25                                 '<a href="#" class="list-remove one-button talk-images" title="' + _e("Remove") + '"></a>' + 
26                         '</div>' + 
27                         
28                         '<div class="list-center"></div>' + 
29                         
30                         '<div class="list-right">' + 
31                                 '<span>' + _e("Add") + '</span>' + 
32                                 '<input type="text" placeholder="' + _e("List name") + '" />' + 
33                         '</div>' + 
34                 '</div>' + 
35                 
36                 '<div class="privacy-item">' + 
37                         '<span>' + _e("Item") + '</span>' + 
38                         '<select disabled=""></select>' + 
39                         '<a href="#" class="item-add one-button talk-images" title="' + _e("Add") + '"></a>' + 
40                         '<a href="#" class="item-remove one-button talk-images" title="' + _e("Remove") + '"></a>' + 
41                         '<a href="#" class="item-save one-button talk-images">' + _e("Save") + '</a>' + 
42                         
43                         '<div class="clear"></div>' + 
44                 '</div>' + 
45                 
46                 '<div class="privacy-form">' + 
47                         '<div class="privacy-first">' + 
48                                 '<label><input type="radio" name="action" value="allow" disabled="" />' + _e("Allow") + '</label>' + 
49                                 '<label><input type="radio" name="action" value="deny" disabled="" />' + _e("Deny") + '</label>' + 
50                         '</div>' + 
51                         
52                         '<div class="privacy-second">' + 
53                                 '<label><input type="radio" name="type" value="jid" disabled="" />' + _e("Address") + '</label>' + 
54                                 '<input type="text" name="jid" disabled="" />' + 
55                                 
56                                 '<label><input type="radio" name="type" value="group" disabled="" />' + _e("Group") + '</label>' + 
57                                 '<select name="group" disabled="">' + groupsToHtmlPrivacy() + '</select>' + 
58                                 
59                                 '<label><input type="radio" name="type" value="subscription" disabled="" />' + _e("Subscription") + '</label>' + 
60                                 '<select name="subscription" disabled="">' + 
61                                         '<option value="none">' + _e("None") + '</option>' + 
62                                         '<option value="both">' + _e("Both") + '</option>' + 
63                                         '<option value="from">' + _e("From") + '</option>' + 
64                                         '<option value="to">' + _e("To") + '</option>' + 
65                                 '</select>' + 
66                                 
67                                 '<label><input type="radio" name="type" value="everybody" disabled="" />' + _e("Everybody") + '</label>' + 
68                         '</div>' + 
69                         
70                         '<div class="privacy-third">' + 
71                                 '<label><input type="checkbox" name="send-messages" disabled="" />' + _e("Send messages") + '</label>' + 
72                                 '<label><input type="checkbox" name="send-queries" disabled="" />' + _e("Send queries") + '</label>' + 
73                                 '<label><input type="checkbox" name="see-status" disabled="" />' + _e("See my status") + '</label>' + 
74                                 '<label><input type="checkbox" name="send-status" disabled="" />' + _e("Send his/her status") + '</label>' + 
75                                 '<label><input type="checkbox" name="everything" disabled="" />' + _e("Everything") + '</label>' + 
76                         '</div>' + 
77                         
78                         '<div class="clear"></div>' + 
79                 '</div>' + 
80                 
81                 '<div class="privacy-active">' + 
82                         '<label>' + _e("Order") + '<input type="text" name="order" value="1" disabled="" /></label>' + 
83                         
84                         '<div class="privacy-active-elements">' + 
85                                 '<label><input type="checkbox" name="active" disabled="" />' + _e("Active for this session") + '</label>' + 
86                                 '<label><input type="checkbox" name="default" disabled="" />' + _e("Always active") + '</label>' + 
87                         '</div>' + 
88                 '</div>' + 
89         '</div>' + 
90         
91         '<div class="bottom">' + 
92                 '<div class="wait wait-medium"></div>' + 
93                 
94                 '<a href="#" class="finish">' + _e("Close") + '</a>' + 
95         '</div>';
96         
97         // Create the popup
98         createPopup('privacy', html);
99         
100         // Associate the events
101         launchPrivacy();
102         
103         // Display the available privacy lists
104         displayListsPrivacy();
105         
106         // Get the first list items
107         displayItemsPrivacy();
108         
109         return false;
110 }
111
112 // Quits the privacy popup
113 function closePrivacy() {
114         // Destroy the popup
115         destroyPopup('privacy');
116         
117         return false;
118 }
119
120 // Sets the received state for privacy block list
121 function receivedPrivacy() {
122         // Store marker
123         setDB('privacy-marker', 'available', 'true');
124         
125         // Show privacy elements
126         $('.privacy-hidable').show();
127 }
128
129 // Gets available privacy lists
130 function listPrivacy() {
131         // Build query
132         var iq = new JSJaCIQ();
133         iq.setType('get');
134         
135         iq.setQuery(NS_PRIVACY);
136         
137         con.send(iq, handleListPrivacy);
138         
139         logThis('Getting available privacy list(s)...');
140 }
141
142 // Handles available privacy lists
143 function handleListPrivacy(iq) {
144         // Error?
145         if(iq.getType() == 'error')
146                 return logThis('Privacy lists not supported!', 2);
147         
148         // Get IQ query content
149         var iqQuery = iq.getQuery();
150         
151         // Save the content
152         setDB('privacy-lists', 'available', xmlToString(iqQuery));
153         
154         // Any block list?
155         if($(iqQuery).find('list[name=block]').size()) {
156                 // Not the default one?
157                 if(!$(iqQuery).find('default[name=block]').size())
158                         changePrivacy('block', 'default');
159                 else
160                         setDB('privacy-marker', 'default', 'block');
161                 
162                 // Not the active one?
163                 if(!$(iqQuery).find('active[name=block]').size())
164                         changePrivacy('block', 'active');
165                 else
166                         setDB('privacy-marker', 'active', 'block');
167                 
168                 // Get the block list rules
169                 getPrivacy('block');
170         }
171         
172         // Apply the received marker here
173         else
174                 receivedPrivacy();
175         
176         logThis('Got available privacy list(s).', 3);
177 }
178
179 // Gets privacy lists
180 function getPrivacy(list) {
181         // Build query
182         var iq = new JSJaCIQ();
183         iq.setType('get');
184         
185         // Privacy query
186         var iqQuery = iq.setQuery(NS_PRIVACY);
187         iqQuery.appendChild(iq.buildNode('list', {'xmlns': NS_PRIVACY, 'name': list}));
188         
189         con.send(iq, handleGetPrivacy);
190         
191         // Must show the wait item?
192         if(exists('#privacy'))
193                 $('#privacy .wait').show();
194         
195         logThis('Getting privacy list(s): ' + list);
196 }
197
198 // Handles privacy lists
199 function handleGetPrivacy(iq) {
200         // Apply a "received" marker
201         receivedPrivacy();
202         
203         // Store the data for each list
204         $(iq.getQuery()).find('list').each(function() {
205                 // Read list name
206                 var list_name = $(this).attr('name');
207                 
208                 // Store list content
209                 setDB('privacy', list_name, xmlToString(this));
210                 
211                 // Is this a block list?
212                 if(list_name == 'block') {
213                         // Reset buddies
214                         $('#buddy-list .buddy').removeClass('blocked');
215                         
216                         // XID types
217                         $(this).find('item[action=deny][type=jid]').each(function() {
218                                 $('#buddy-list .buddy[data-xid=' + escape($(this).attr('value')) + ']').addClass('blocked');
219                         });
220                         
221                         // Group types
222                         $(this).find('item[action=deny][type=group]').each(function() {
223                                 $('#buddy-list .group' + hex_md5($(this).attr('value')) + ' .buddy').addClass('blocked');
224                         });
225                 }
226         });
227         
228         // Must display it to the popup?
229         if(exists('#privacy')) {
230                 displayItemsPrivacy();
231                 
232                 $('#privacy .wait').hide();
233         }
234         
235         logThis('Got privacy list(s).', 3);
236 }
237
238 // Sets a privacy list
239 function setPrivacy(list, types, values, actions, orders, presence_in, presence_out, msg, iq_p) {
240         // Build query
241         var iq = new JSJaCIQ();
242         iq.setType('set');
243         
244         // Privacy query
245         var iqQuery = iq.setQuery(NS_PRIVACY);
246         var iqList = iqQuery.appendChild(iq.buildNode('list', {'xmlns': NS_PRIVACY, 'name': list}));
247         
248         // Build the item elements
249         if(types && types.length) {
250                 for(var i = 0; i < types.length; i++) {
251                         // Item element
252                         var iqItem = iqList.appendChild(iq.buildNode('item', {'xmlns': NS_PRIVACY}));
253                         
254                         // Item attributes
255                         if(types[i])
256                                 iqItem.setAttribute('type', types[i]);
257                         if(values[i])
258                                 iqItem.setAttribute('value', values[i]);
259                         if(actions[i])
260                                 iqItem.setAttribute('action', actions[i]);
261                         if(orders[i])
262                                 iqItem.setAttribute('order', orders[i]);
263                         
264                         // Child elements
265                         if(presence_in[i])
266                                 iqItem.appendChild(iq.buildNode('presence-in', {'xmlns': NS_PRIVACY}));
267                         if(presence_out[i])
268                                 iqItem.appendChild(iq.buildNode('presence-out', {'xmlns': NS_PRIVACY}));
269                         if(msg[i])
270                                 iqItem.appendChild(iq.buildNode('message', {'xmlns': NS_PRIVACY}));
271                         if(iq_p[i])
272                                 iqItem.appendChild(iq.buildNode('iq', {'xmlns': NS_PRIVACY}));
273                 }
274         }
275         
276         con.send(iq);
277         
278         logThis('Sending privacy list: ' + list);
279 }
280
281 // Push a privacy list item to a list
282 function pushPrivacy(list, type, value, action, order, presence_in, presence_out, msg, iq_p, hash, special_action) {
283         // Read the stored elements (to add them)
284         var stored = XMLFromString(getDB('privacy', list));
285         
286         // Read the first value
287         var first_val = value[0];
288         
289         // Must remove the given value?
290         if(special_action == 'remove') {
291                 type = [];
292                 value = [];
293                 action = [];
294                 order = [];
295                 presence_in = [];
296                 presence_out = [];
297                 iq_p = [];
298         }
299         
300         // Serialize them to an array
301         $(stored).find('item').each(function() {
302                 // Attributes
303                 var c_type = $(this).attr('type');
304                 var c_value = $(this).attr('value');
305                 var c_action = $(this).attr('action');
306                 var c_order = $(this).attr('order');
307                 
308                 // Generate hash
309                 var c_hash = hex_md5(c_type + c_value + c_action + c_order);
310                 
311                 // Do not push it twice!
312                 if(((c_hash != hash) && (special_action != 'roster')) || ((first_val != c_value) && (special_action == 'roster'))) {
313                         if(!c_type)
314                                 c_type = '';
315                         if(!c_value)
316                                 c_value = '';
317                         if(!c_action)
318                                 c_action = '';
319                         if(!c_order)
320                                 c_order = '';
321                         
322                         type.push(c_type);
323                         value.push(c_value);
324                         action.push(c_action);
325                         order.push(c_order);
326                         
327                         // Child elements
328                         if($(this).find('presence-in').size())
329                                 presence_in.push(true);
330                         else
331                                 presence_in.push(false);
332                         
333                         if($(this).find('presence-out').size())
334                                 presence_out.push(true);
335                         else
336                                 presence_out.push(false);
337                         
338                         if($(this).find('message').size())
339                                 msg.push(true);
340                         else
341                                 msg.push(false);
342                         
343                         if($(this).find('iq').size())
344                                 iq_p.push(true);
345                         else
346                                 iq_p.push(false);
347                 }
348         });
349         
350         // Send it!
351         setPrivacy(list, type, value, action, order, presence_in, presence_out, msg, iq_p);
352 }
353
354 // Change a privacy list status
355 function changePrivacy(list, status) {
356         // Yet sent?
357         if(getDB('privacy-marker', status) == list)
358                 return;
359         
360         // Write a marker
361         setDB('privacy-marker', status, list);
362         
363         // Build query
364         var iq = new JSJaCIQ();
365         iq.setType('set');
366         
367         // Privacy query
368         var iqQuery = iq.setQuery(NS_PRIVACY);
369         var iqStatus = iqQuery.appendChild(iq.buildNode(status, {'xmlns': NS_PRIVACY}));
370         
371         // Can add a "name" attribute?
372         if(list)
373                 iqStatus.setAttribute('name', list);
374         
375         con.send(iq);
376         
377         logThis('Changing privacy list status: ' + list + ' to: ' + status);
378 }
379
380 // Checks the privacy status (action) of a value
381 function statusPrivacy(list, value) {
382         return $(XMLFromString(getDB('privacy', list))).find('item[value=' + value + ']').attr('action');
383 }
384
385 // Converts the groups array into a <option /> string
386 function groupsToHtmlPrivacy() {
387         var groups = getAllGroups();
388         var html = '';
389         
390         // Generate HTML
391         for(i in groups) {
392                 html += '<option value="' + encodeQuotes(groups[i]) +'">' + groups[i].htmlEnc() + '</option>';
393         }
394         
395         return html;
396 }
397
398 // Displays the privacy lists
399 function displayListsPrivacy() {
400         // Initialize
401         var code = '';
402         var select = $('#privacy .privacy-head .list-left select');
403         var data = XMLFromString(getDB('privacy-lists', 'available'));
404         
405         // Parse the XML data!
406         $(data).find('list').each(function() {
407                 var list_name = $(this).attr('name');
408                 
409                 if(list_name)
410                         code += '<option value="' + encodeQuotes(list_name) + '">' + list_name.htmlEnc() + '</option>';
411         });
412         
413         // Apply HTML code
414         select.html(code);
415         
416         // Not empty?
417         if(code)
418                 select.removeAttr('disabled');
419         else
420                 select.attr('disabled', true);
421         
422         return true;
423 }
424
425 // Displays the privacy items for a list
426 function displayItemsPrivacy() {
427         // Reset the form
428         clearFormPrivacy();
429         disableFormPrivacy();
430         
431         // Initialize
432         var code = '';
433         var select = $('#privacy .privacy-item select');
434         var list = $('#privacy .privacy-head .list-left select').val();
435         
436         // Reset the item select
437         select.html('');
438         
439         // No list?
440         if(!list)
441                 return false;
442         
443         // Reset the list status
444         $('#privacy .privacy-active input[type=checkbox]').removeAttr('checked');
445         
446         // Display the list status
447         var status = ['active', 'default'];
448         
449         for(s in status) {
450                 if(getDB('privacy-marker', status[s]) == list)
451                         $('#privacy .privacy-active input[name=' + status[s] + ']').attr('checked', true);
452         }
453         
454         // Try to read the stored items
455         var items = XMLFromString(getDB('privacy', list));
456         
457         // Must retrieve the data?
458         if(!items) {
459                 select.attr('disabled', true);
460                 
461                 return getPrivacy(list);
462         }
463         
464         else
465                 select.removeAttr('disabled');
466         
467         // Parse the XML data!
468         $(items).find('item').each(function() {
469                 // Read attributes
470                 var item_type = $(this).attr('type');
471                 var item_value = $(this).attr('value');
472                 var item_action = $(this).attr('action');
473                 var item_order = $(this).attr('order');
474                 
475                 // Generate hash
476                 var item_hash = hex_md5(item_type + item_value + item_action + item_order);
477                 
478                 // Read sub-elements
479                 var item_presencein = $(this).find('presence-in').size();
480                 var item_presenceout = $(this).find('presence-out').size();
481                 var item_message = $(this).find('message').size();
482                 var item_iq = $(this).find('iq').size();
483                 
484                 // Apply default values (if missing)
485                 if(!item_type)
486                         item_type = '';
487                 if(!item_value)
488                         item_value = '';
489                 if(!item_action)
490                         item_action = 'allow';
491                 if(!item_order)
492                         item_order = '1';
493                 
494                 // Apply sub-elements values
495                 if(item_presencein)
496                         item_presencein = 'true';
497                 else
498                         item_presencein = 'false';
499                 
500                 if(item_presenceout)
501                         item_presenceout = 'true';
502                 else
503                         item_presenceout = 'false';
504                 
505                 if(item_message)
506                         item_message = 'true';
507                 else
508                         item_message = 'false';
509                 
510                 if(item_iq)
511                         item_iq = 'true';
512                 else
513                         item_iq = 'false';
514                 
515                 // Generate item description
516                 var desc = '';
517                 var desc_arr = [item_type, item_value, item_action, item_order];
518                 
519                 for(d in desc_arr) {
520                         // Nothing to display?
521                         if(!desc_arr[d])
522                                 continue;
523                         
524                         if(desc)
525                                 desc += ' - ';
526                         
527                         desc += desc_arr[d];
528                 }
529                 
530                 // Add the select option
531                 code += '<option data-type="' + encodeQuotes(item_type) + '" data-value="' + encodeQuotes(item_value) + '" data-action="' + encodeQuotes(item_action) + '" data-order="' + encodeQuotes(item_order) + '" data-presence_in="' + encodeQuotes(item_presencein) + '" data-presence_out="' + encodeQuotes(item_presenceout) + '" data-message="' + encodeQuotes(item_message) + '" data-iq="' + encodeQuotes(item_iq) + '" data-hash="' + encodeQuotes(item_hash) + '">' + 
532                                 desc + 
533                         '</option>';
534         });
535         
536         // Append the code
537         select.append(code);
538         
539         // Display the first item form
540         var first_item = select.find('option:first');
541         displayFormPrivacy(
542                            first_item.attr('data-type'),
543                            first_item.attr('data-value'),
544                            first_item.attr('data-action'),
545                            first_item.attr('data-order'),
546                            first_item.attr('data-presence_in'),
547                            first_item.attr('data-presence_out'),
548                            first_item.attr('data-message'),
549                            first_item.attr('data-iq')
550                           );
551         
552         return true;
553 }
554
555 // Displays the privacy form for an item
556 function displayFormPrivacy(type, value, action, order, presence_in, presence_out, message, iq) {
557         // Reset the form
558         clearFormPrivacy();
559         
560         // Apply the action
561         $('#privacy .privacy-first input[name=action][value=' + action + ']').attr('checked', true);
562         
563         // Apply the type & value
564         var privacy_second = '#privacy .privacy-second';
565         var privacy_type = privacy_second + ' input[name=type]';
566         var type_check, value_input;
567         
568         switch(type) {
569                 case 'jid':
570                         type_check = privacy_type + '[value=jid]';
571                         value_input = privacy_second + ' input[type=text][name=jid]';
572                         
573                         break;
574                 
575                 case 'group':
576                         type_check = privacy_type + '[value=group]';
577                         value_input = privacy_second + ' select[name=group]';
578                         
579                         break;
580                 
581                 case 'subscription':
582                         type_check = privacy_type + '[value=subscription]';
583                         value_input = privacy_second + ' select[name=subscription]';
584                         
585                         break;
586                 
587                 default:
588                         type_check = privacy_type + '[value=everybody]';
589                         
590                         break;
591         }
592         
593         // Check the target
594         $(type_check).attr('checked', true);
595         
596         // Can apply a value?
597         if(value_input)
598                 $(value_input).val(value);
599         
600         // Apply the things to do
601         var privacy_do = '#privacy .privacy-third input[type=checkbox]';
602         
603         if(presence_in == 'true')
604                 $(privacy_do + '[name=send-status]').attr('checked', true);
605         if(presence_out == 'true')
606                 $(privacy_do + '[name=see-status]').attr('checked', true);
607         if(message == 'true')
608                 $(privacy_do + '[name=send-messages]').attr('checked', true);
609         if(iq == 'true')
610                 $(privacy_do + '[name=send-queries]').attr('checked', true);
611         
612         if(!$(privacy_do).filter(':checked').size())
613                 $(privacy_do + '[name=everything]').attr('checked', true);
614         
615         // Apply the order
616         $('#privacy .privacy-active input[name=order]').val(order);
617         
618         // Enable the forms
619         $('#privacy .privacy-form input, #privacy .privacy-form select, #privacy .privacy-active input').removeAttr('disabled');
620 }
621
622 // Clears the privacy list form
623 function clearFormPrivacy() {
624         // Uncheck checkboxes & radio inputs
625         $('#privacy .privacy-form input[type=checkbox], #privacy .privacy-form input[type=radio]').removeAttr('checked');
626         
627         // Reset select
628         $('#privacy .privacy-form select option').removeAttr('selected');
629         $('#privacy .privacy-form select option:first').attr('selected', true);
630         
631         // Reset text input
632         $('#privacy .privacy-form input[type=text]').val('');
633         
634         // Reset order input
635         $('#privacy .privacy-active input[name=order]').val('1');
636 }
637
638 // Disables the privacy list form
639 function disableFormPrivacy() {
640         $('#privacy .privacy-form input, #privacy .privacy-form select, #privacy .privacy-active input').attr('disabled', true);
641 }
642
643 // Enables the privacy list form
644 function enableFormPrivacy(rank) {
645         $('#privacy .privacy-' + rank + ' input, #privacy .privacy-' + rank + ' select').removeAttr('disabled');
646 }
647
648 // Plugin launcher
649 function launchPrivacy() {
650         // Click events
651         $('#privacy .bottom .finish').click(closePrivacy);
652         
653         // Placeholder events
654         $('#privacy input[placeholder]').placeholder();
655         
656         // Form events
657         $('#privacy .privacy-head a.list-remove').click(function() {
658                 // Get list name
659                 var list = $('#privacy .privacy-head .list-left select').val();
660                 
661                 // No value?
662                 if(!list)
663                         return false;
664                 
665                 // Remove it from popup
666                 $('#privacy .privacy-head .list-left select option[value=' + list + ']').remove();
667                 
668                 // Nothing remaining?
669                 if(!exists('#privacy .privacy-head .list-left select option'))
670                         $('#privacy .privacy-head .list-left select option').attr('disabled', true);
671                 
672                 // Empty the item select
673                 $('#privacy .privacy-item select').attr('disabled', true).html('');
674                 
675                 // Disable this list before removing it
676                 var status = ['active', 'default'];
677                 
678                 for(s in status) {
679                         if(getDB('privacy-marker', status[s]) == list)
680                                 changePrivacy('', status[s]);
681                 }
682                 
683                 // Remove from server
684                 setPrivacy(list);
685                 
686                 // Reset the form
687                 clearFormPrivacy();
688                 disableFormPrivacy();
689                 
690                 return false;
691         });
692         
693         $('#privacy .privacy-head .list-right input').keyup(function(e) {
694                 // Not enter?
695                 if(e.keyCode != 13)
696                         return;
697                 
698                 // Get list name
699                 var list = $('#privacy .privacy-head .list-right input').val();
700                 var select = '#privacy .privacy-head .list-left select';
701                 var existed = true;
702                 
703                 // Create the new element
704                 if(!exists(select + ' option[value=' + list + ']')) {
705                         // Marker
706                         existed = false;
707                         
708                         // Create a new option
709                         $(select).append('<option value="' + encodeQuotes(list) + '">' + list.htmlEnc() + '</option>');
710                         
711                         // Reset the item select
712                         $('#privacy .privacy-item select').attr('disabled', true).html('');
713                 }
714                 
715                 // Change the select value & enable it
716                 $(select).val(list).removeAttr('disabled');
717                 
718                 // Reset its value
719                 $(this).val('');
720                 
721                 // Reset the form
722                 clearFormPrivacy();
723                 disableFormPrivacy();
724                 
725                 // Must reload the list items?
726                 if(existed) {
727                         displayItemsPrivacy();
728                         $('#privacy .privacy-item select').removeAttr('disabled');
729                 }
730         });
731         
732         $('#privacy .privacy-head .list-left select').change(displayItemsPrivacy);
733         
734         $('#privacy .privacy-item select').change(function() {
735                 // Get the selected item
736                 var item = $(this).find('option:selected');
737                 
738                 // Display the data!
739                 displayFormPrivacy(
740                            item.attr('data-type'),
741                            item.attr('data-value'),
742                            item.attr('data-action'),
743                            item.attr('data-order'),
744                            item.attr('data-presence_in'),
745                            item.attr('data-presence_out'),
746                            item.attr('data-message'),
747                            item.attr('data-iq')
748                           );
749         });
750         
751         $('#privacy .privacy-item a.item-add').click(function() {
752                 // Cannot add anything?
753                 if(!exists('#privacy .privacy-head .list-left select option:selected'))
754                         return false;
755                 
756                 // Disable item select
757                 $('#privacy .privacy-item select').attr('disabled', true);
758                 
759                 // Reset the form
760                 clearFormPrivacy();
761                 disableFormPrivacy();
762                 
763                 // Enable first form item
764                 enableFormPrivacy('first');
765                 enableFormPrivacy('active');
766                 
767                 return false;
768         });
769         
770         $('#privacy .privacy-item a.item-remove').click(function() {
771                 // Cannot add anything?
772                 if(!exists('#privacy .privacy-head .list-left select option:selected'))
773                         return false;
774                 
775                 // Get values
776                 var list = $('#privacy .privacy-head .list-left select').val();
777                 var selected = $('#privacy .privacy-item select option:selected');
778                 var item = selected.attr('data-value');
779                 var hash = selected.attr('data-hash');
780                 
781                 // Remove it from popup
782                 $('#privacy .privacy-item select option:selected').remove();
783                 
784                 // No more items in this list?
785                 if(!exists('#privacy .privacy-item select option')) {
786                         // Disable this select
787                         $('#privacy .privacy-item select').attr('disabled', true);
788                         
789                         // Remove the privacy list select item
790                         $('#privacy .privacy-head .list-left select option[value=' + list + ']').remove();
791                         
792                         // No more privacy lists?
793                         if(!exists('#privacy .privacy-head .list-left select option'))
794                                 $('#privacy .privacy-head .list-left select').attr('disabled', true);
795                         
796                         // Disable this list before removing it
797                         var status = ['active', 'default'];
798                         
799                         for(s in status) {
800                                 if(getDB('privacy-marker', status[s]) == list)
801                                         changePrivacy('', status[s]);
802                         }
803                 }
804                 
805                 // Synchronize it with server
806                 pushPrivacy(list, [], [item], [], [], [], [], [], [], hash, 'remove');
807                 
808                 // Reset the form
809                 clearFormPrivacy();
810                 disableFormPrivacy();
811                 
812                 return false;
813         });
814         
815         $('#privacy .privacy-item a.item-save').click(function() {
816                 // Canot push item?
817                 if(exists('#privacy .privacy-form input:disabled'))
818                         return false;
819                 
820                 // Get the hash
821                 var item_hash = '';
822                 
823                 if(!$('#privacy .privacy-item select').is(':disabled'))
824                         item_hash = $('#privacy .privacy-item select option:selected').attr('data-hash');
825                 
826                 // Read the form
827                 var privacy_second = '#privacy .privacy-second';
828                 var item_list = $('#privacy .privacy-head .list-left select').val();
829                 var item_action = $('#privacy .privacy-first input[name=action]').filter(':checked').val();
830                 var item_type = $(privacy_second + ' input[name=type]').filter(':checked').val();
831                 var item_order = $('#privacy .privacy-active input[name=order]').val();
832                 var item_value = '';
833                 
834                 // Switch the type to get the value
835                 switch(item_type) {
836                         case 'jid':
837                                 item_value = $(privacy_second + ' input[type=text][name=jid]').val();
838                                 
839                                 break;
840                         
841                         case 'group':
842                                 item_value = $(privacy_second + ' select[name=group]').val();
843                                 
844                                 break;
845                         
846                         case 'subscription':
847                                 item_value = $(privacy_second + ' select[name=subscription]').val();
848                                 
849                                 break;
850                         
851                         default:
852                                 item_type = '';
853                                 
854                                 break;
855                 }
856                 
857                 // Get the selected things to do
858                 var privacy_third_cb = '#privacy .privacy-third input[type=checkbox]';
859                 var item_prin = false;
860                 var item_prout = false;
861                 var item_msg = false;
862                 var item_iq = false;
863                 
864                 // Individual select?
865                 if(!$(privacy_third_cb + '[name=everything]').filter(':checked').size()) {
866                         if($(privacy_third_cb + '[name=send-messages]').filter(':checked').size())
867                                 item_msg = true;
868                         if($(privacy_third_cb + '[name=send-queries]').filter(':checked').size())
869                                 item_iq = true;
870                         if($(privacy_third_cb + '[name=send-queries]').filter(':checked').size())
871                                 item_iq = true;
872                         if($(privacy_third_cb + '[name=see-status]').filter(':checked').size())
873                                 item_prout = true;
874                         if($(privacy_third_cb + '[name=send-status]').filter(':checked').size())
875                                 item_prin = true;
876                 }
877                 
878                 // Push item to the server!
879                 pushPrivacy(
880                             item_list,
881                             [item_type],
882                             [item_value],
883                             [item_action],
884                             [item_order],
885                             [item_prin],
886                             [item_prout],
887                             [item_msg],
888                             [item_iq],
889                             item_hash
890                            );
891                 
892                 return false;
893         });
894         
895         $('#privacy .privacy-first input').change(function() {
896                 enableFormPrivacy('second');
897         });
898         
899         $('#privacy .privacy-second input').change(function() {
900                 enableFormPrivacy('third');
901         });
902         
903         $('#privacy .privacy-third input[type=checkbox]').change(function() {
904                 // Target
905                 var target = '#privacy .privacy-third input[type=checkbox]';
906                 
907                 // Must tick "everything" checkbox?
908                 if(!$(target).filter(':checked').size())
909                         $(target + '[name=everything]').attr('checked', true);
910                 
911                 // Must untick the other checkboxes?
912                 else if($(this).is('[name=everything]'))
913                         $(target + ':not([name=everything])').removeAttr('checked');
914                 
915                 // Must untick "everything" checkbox?
916                 else
917                         $(target + '[name=everything]').removeAttr('checked');
918         });
919         
920         $('#privacy .privacy-active input[name=order]').keyup(function() {
921                 // Get the value
922                 var value = $(this).val();
923                 
924                 // No value?
925                 if(!value)
926                         return;
927                 
928                 // Not a number?
929                 if(isNaN(value))
930                         value = 1;
931                 else
932                         value = parseInt(value);
933                 
934                 // Negative?            
935                 if(value < 0)
936                         value = value * -1;
937                 
938                 // Apply the filtered value
939                 $(this).val(value);
940         })
941         
942         .blur(function() {
943                 // No value?
944                 if(!$(this).val())
945                         $(this).val('1');
946         });
947         
948         $('#privacy .privacy-active .privacy-active-elements input').change(function() {
949                 // Get the values
950                 var list_name = $('#privacy .privacy-head .list-left select').val();
951                 var state_name = $(this).attr('name');
952                 
953                 // Cannot continue?
954                 if(!list_name || !state_name)
955                         return;
956                 
957                 // Change the current list status
958                 if($(this).filter(':checked').size())
959                         changePrivacy(list_name, state_name);
960                 else
961                         changePrivacy('', state_name);
962         });
963 }