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