1/** 2 * DokuWiki Plugin TagSections (JavaScript Component) 3 * 4 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 5 * @author gamma 6 */ 7 8(function(jQuery) { 9 10 var currentNamespace = JSINFO['namespace']; 11 var $currentButton = null; 12 var init = function() { 13 14 jQuery('form.sectiontag__form').submit(function(event){ 15 16 $currentButton = jQuery(this); 17 request({availableTags: true, tagsForSection: true}, showTagSelection); 18 return false; 19 20 // Move the Tag button up to the header. Or close to it. 21 }).parent().css('margin-top', function(){ 22 23 var $tgt = jQuery(this), 24 nr = $tgt.attr('class').match(/(\s+|^)editbutton_(\d+)(\s+|$)/)[2], 25 $highlight = jQuery(); 26 27 // Walk the dom tree in reverse to find the sibling which is or contains the section edit marker 28 while($tgt.length > 0 && !($tgt.hasClass('sectionedit' + nr) || $tgt.find('.sectionedit' + nr).length)) { 29 $tgt = $tgt.prev(); 30 $highlight = $highlight.add($tgt); 31 } 32 // insert the section highlight wrapper before the last element added to $highlight 33 return ($tgt.offset()||{top:0}).top - ($highlight.filter(':last').offset()||{top:0}).top; 34 }); 35 }; 36 37 var showTagSelection = function(data) { 38 39 data = JSON.parse(data); 40 var $dialog = getDialog('open').html(''); 41 var $accordeon = jQuery('<div class="tagsections__accordeon"/>').appendTo($dialog); 42 data.availableTags = jQuery.extend( true, data.availableTags, data.tagsForSection); 43 44 if ( typeof data.availableTags[''] == 'undefined' ) { 45 data.availableTags[''] = {}; 46 } 47 48 var needsEmptySection = true; 49 jQuery.each(data.availableTags, function(namespace, entries){ 50 // namespaces 51 52 var $accordeonContent = jQuery('<div/>'); 53 54 needsEmptySection = false; 55 var checked = 0; 56 jQuery.each(entries, function(tag){ 57 58 var check = typeof data.tagsForSection != 'undefined' && 59 typeof data.tagsForSection[namespace] != 'undefined' && 60 typeof data.tagsForSection[namespace][tag] != 'undefined'; 61 creeateCheckBox(namespace, tag, check).appendTo($accordeonContent); 62 checked += check ? 1 : 0; 63 }); 64 65 // Add an input box to add new tags 66 additionalRows(namespace, $accordeonContent); 67 68 // Add new accordeon entry 69 $accordeon.append(createHeader(namespace, checked, Object.keys(entries).length)); 70 $accordeonContent.appendTo($accordeon); 71 }); 72 73 if ( needsEmptySection ) { 74 $accordeon.append(createHeader(null, 0, 0)); 75 76 var $content = jQuery('<div/>').appendTo($accordeon); 77 additionalRows(null, $content); 78 } 79 80 $accordeon.accordion({heightStyle: 'content',collapsible:true}); 81 }; 82 83 var createHeader = function(namespace, checked, entries) { 84 return jQuery('<h3/>').text(((namespace||LANG.plugins.tagsections['empty namespace']) + ' ' + checked + '/'+entries).trim() ); 85 }; 86 87 var creeateCheckBox = function(namespace, tag, checked) { 88 var tagName = (namespace||'').length > 0 ? namespace+':'+tag : tag; 89 var $element = jQuery('<input type="checkbox" class="tagsections__tag"/>').attr('name', tagName).val('1').attr('id', tagName).prop('checked', checked); 90 return jQuery('<label/>').attr('for', tagName).text(tag).append($element); 91 }; 92 93 var additionalRows = function(namespace, $root) { 94 95 var $newTagLine = jQuery('<hr/>').appendTo($root); 96 var $element = jQuery('<input class="tagsections__tag__new"/>').attr('id', namespace + '_newTag'); 97 var $button = jQuery('<input class="edit" type="submit"/>').val(LANG.plugins.tagsections['add']); 98 var $form = jQuery('<form/>').append($element).append($button); 99 jQuery('<label class="newTag"/>').attr('for', namespace + '_newTag').text(LANG.plugins.tagsections['new tag']).append($form).appendTo($root); 100 101 $form.submit(function(){ 102 103 var tag = $element.val(); 104 $newTagLine.before(creeateCheckBox(namespace, tag, true)); 105 $element.val(''); 106 107 return false; 108 }); 109 }; 110 111 var request = function(data, success) { 112 data['call'] = 'tagsections'; 113 data['id'] = JSINFO['id']; 114 data['ns'] = currentNamespace; 115 data['range'] = $currentButton.find('input.sectiontag_button').attr('range'); 116 return jQuery.post(DOKU_BASE + 'lib/exe/ajax.php', data, success); 117 }; 118 119 var saveTags = function() { 120 121 var newTags = []; 122 var elements = getDialog().find(".tagsections__accordeon input:checked").toArray(); 123 for(var i=0;typeof(elements[i])!='undefined';newTags.push(elements[i++].getAttribute('name'))); 124 125 request({tags:newTags, saveTags:true}, function(){ 126 request({contentOfPage:true}, function(data){ 127 128 var $toRemove = $currentButton.parent().parent().children(), 129 $tmpWrap = jQuery('<div style="display:none"></div>').html(data); // temporary wrapper 130 131 // insert the section highlight wrapper before the last element added to $tmpStore 132 $toRemove.filter(':last').before($tmpWrap); 133 // and remove the elements 134 $toRemove.detach(); 135 136 // Now remove the content again 137 $tmpWrap.before($tmpWrap.children().detach()); 138 // ...and remove the section highlight wrapper 139 $tmpWrap.detach(); 140 141 // Close Dialog. 142 getDialog('close').detach(); 143 // Re-Init the page for edit buttons. 144 initJQuery(); 145 }); 146 }); 147 }; 148 149 var initJQuery = function() { 150 151 jQuery('script[src]').each(function(){ 152 var $xchange = jQuery(this); 153 var $new = jQuery('<script/>').attr('type', $xchange.attr('type')).attr('defer', 'true'); 154 $xchange.before($new).detach(); 155 $new.attr('src', $xchange.attr('src')); 156 }); 157 }; 158 159 var getDialog = function(action) { 160 161 if(!jQuery('#tagsections__dilaog').length){ 162 jQuery('body').append('<div id="tagsections__dilaog" position="absolute" border=1 height="800px"><div id="tagsections__dialog_div"></div></div>'); 163 jQuery( "#tagsections__dilaog" ).dialog({title:LANG.plugins.tagsections['choose tags'], 164 height:600, 165 width: Math.min(700,jQuery(window).width()-50), 166 autoOpen:true, 167 buttons:[ 168 {text:LANG.plugins.tagsections['closeDialog'],click: function() { getDialog('close') }}, 169 {text:LANG.plugins.tagsections['save'],click: saveTags}, 170 ], 171 }); 172 } 173 174 if ( action ) { 175 return jQuery('#tagsections__dilaog').dialog(action); 176 } 177 178 return jQuery('#tagsections__dilaog'); 179 }; 180 181 jQuery(document).ready(init); 182})(jQuery); 183