1/**
2 * Javascript for DokuWiki Plugin BlogTNG
3 */
4var blogtng = {
5
6    /**
7     * Attach the validation checking to the comment form
8     *
9     * @author Michael Klier <chi@chimeric.de>
10     */
11    validate_attach: function(obj) {
12        if(!obj) return;
13        jQuery(obj).on('click', function() { return blogtng.validate(); });
14    },
15
16    /**
17     * Validates the comment form inputs and highlights
18     * missing fields on client side
19     *
20     * @author Michael Klier <chi@chimeric.de>
21     */
22    validate: function() {
23        let inputs = ['blogtng__comment_name',
24            'blogtng__comment_mail',
25            'wiki__text'];
26
27        for(let i = 0; i < inputs.length; i++) {
28            let input = jQuery("#" + inputs[i]).get(0);
29            if(input) {
30                if(!input.value) {
31                    input.className = 'edit error';
32                    input.focus();
33                    return false;
34                } else {
35                    input.className = 'edit';
36                }
37            }
38        }
39        return true;
40    },
41
42    /**
43     * Attach the AJAX preview action to the comment form
44     *
45     * @author Michael Klier <chi@chimeric.de>
46     */
47    preview_attach: function(obj, wrap, previewid) {
48        if(!obj) return;
49        if(!wrap) return;
50
51        jQuery(obj).on('click',function(e) {
52            blogtng.preview(wrap,previewid);
53            e.preventDefault();
54            e.stopPropagation();
55            return false;
56        });
57    },
58
59    /**
60     * Uses AJAX to render and preview the comment before submitting
61     *
62     * @author Michael Klier <chi@chimeric.de>
63     */
64    preview: function(wrap,previewid) {
65        if(!blogtng.validate()) return false;
66
67        let preview = jQuery("#"+previewid).get(0);
68        if(!preview){
69            if(!wrap) return false;
70
71            preview = document.createElement('div');
72            preview.id = previewid;
73            wrap.appendChild(preview);
74        }
75
76        preview.innerHTML = '<img src="'+DOKU_BASE+'/lib/images/throbber.gif" />';
77
78        let params = {
79            call:    'blogtng__comment_preview',
80            tplname: jQuery('#blogtng__comment_form').data('tplname')
81        };
82
83        let $name = jQuery('#blogtng__comment_name');
84        let $email = jQuery('#blogtng__comment_mail');
85        let $web = jQuery('#blogtng__comment_web');
86        let $text = jQuery('#wiki__text');
87
88        if($name.length > 0)  params.name = $name.val();
89        if($email.length > 0) params.mail = $email.val();
90        if($web.length > 0)   params.web  = $web.val();
91        if($text.length > 0)  params.text = $text.val();
92
93        jQuery.post(DOKU_BASE + 'lib/exe/ajax.php', params,
94        function(data){
95            if(data === '') return;
96            preview.innerHTML = data;
97        });
98
99        return false;
100    },
101
102    /**
103     * Attach the reply action to the comment numbers and add tooltip
104     * previews to reply syntax markers.
105     *
106     * @author Gina Haeussge <osd@foosel.net>
107     */
108    reply_attach: function() {
109        // attach reply action
110        let objs = jQuery('a.blogtng_num');
111        for (let i = 0; i < objs.length; i++) {
112            objs[i].title = LANG['plugins']['blogtng']['reply'];
113            jQuery(objs[i]).on('click', function(e) {
114                insertAtCarret('wiki__text','@#'+this.href.substring(this.href.lastIndexOf('#')+'#comment_'.length)+': ');
115
116                e.preventDefault();
117                e.stopPropagation();
118                return false;
119            });
120        }
121
122        // make "footnotes" from comment references
123        objs = jQuery('a.blogtng_reply');
124        for (let i = 0; i < objs.length; i++) {
125            jQuery(objs[i]).on('mouseover', function(e) {
126                commentPopup(e, this.href.substring(this.href.lastIndexOf('#')+'#comment_'.length));
127            });
128        }
129    },
130
131    /**
132     * Attach and handle the check-all checkbox.
133     */
134    insert_checkall_checkbox: function() {
135        if(jQuery('#blogtng__admin').length === 0) return;
136        let th = jQuery('#blogtng__admin_checkall_th').get(0);
137        if(th) {
138            th.innerHTML = '<input type="checkbox" id="blogtng__admin_checkall" />';
139            let checkbox = jQuery('#blogtng__admin_checkall').get(0);
140            jQuery(checkbox).on('click', function(e) {
141                blogtng.checkall();
142            });
143        }
144    },
145
146    /**
147     * Set all checkboxes to checked.
148     */
149    checkall: function() {
150        let objs = jQuery('input.comment_cid');
151        if(objs) {
152            let num = objs.length;
153            for(let i=0;i<num;i++) {
154                objs[i].checked = !objs[i].checked;
155            }
156        }
157    }
158};
159
160/**
161 * Display an insitu comment popup. Heavily copied from the footnote insitu
162 * popup.
163 *
164 * FIXME: make the footnote one wrap a generic function to define popups?
165 *
166 * @author Andreas Gohr <andi@splitbrain.org>
167 * @author Chris Smith <chris@jalakai.co.uk>
168 * @author Gina Haeussge <gina@foosel.net>
169 */
170function commentPopup(e, id){
171    let obj = e.target;
172
173    // get or create the comment popup div
174    let comment_div = jQuery('#insitu__comment').get(0);
175    if(!comment_div){
176        comment_div = document.createElement('div');
177        comment_div.id        = 'insitu__comment';
178        comment_div.className = 'insitu-footnote JSpopup dokuwiki';
179
180        // autoclose on mouseout - ignoring bubbled up events
181        jQuery(comment_div).on('mouseout', function(e){
182            if(e.target != comment_div){
183                e.stopPropagation();
184                return;
185            }
186            // check if the element was really left
187            if(e.pageX){        // Mozilla
188                let bx1 = findPosX(comment_div);
189                let bx2 = bx1 + comment_div.offsetWidth;
190                let by1 = findPosY(comment_div);
191                let by2 = by1 + comment_div.offsetHeight;
192                let x = e.pageX;
193                let y = e.pageY;
194                if(x > bx1 && x < bx2 && y > by1 && y < by2){
195                    // we're still inside boundaries
196                    e.stopPropagation();
197                    return;
198                }
199            }else{              // IE
200                if(e.offsetX > 0 && e.offsetX < comment_div.offsetWidth-1 &&
201                   e.offsetY > 0 && e.offsetY < comment_div.offsetHeight-1){
202                    // we're still inside boundaries
203                    e.stopPropagation();
204                    return;
205                }
206            }
207            // okay, hide it
208            comment_div.style.display='none';
209        });
210        document.body.appendChild(comment_div);
211    }
212
213    // locate the comment anchor element
214    let a = jQuery("#comment_" + id).get(0);
215    if (!a){ return; }
216
217    // anchor parent is the footnote container, get its innerHTML
218    let content = String(a.innerHTML);
219
220    // prefix ids on any elements with "insitu__" to ensure they remain unique
221    content = content.replace(/\bid="(.*?)"/gi,'id="insitu__$1"');
222
223    // now put the content into the wrapper
224    comment_div.innerHTML = content;
225    // position the div and make it visible
226    let x, y;
227    if(e.pageX){        // Mozilla
228        x = e.pageX;
229        y = e.pageY;
230    }else{              // IE
231        x = e.offsetX;
232        y = e.offsetY;
233    }
234    comment_div.style.position = 'absolute';
235    comment_div.style.left = (x+2)+'px';
236    comment_div.style.top  = (y+2)+'px';
237    comment_div.style.display = '';
238}
239
240/**
241 * Attach events
242 */
243jQuery(function() {
244    blogtng.validate_attach(jQuery('#blogtng__comment_submit').get(0));
245    blogtng.preview_attach(jQuery('#blogtng__preview_submit').get(0),jQuery('#blogtng__comment_form_wrap').get(0),'blogtng__comment_preview');
246    blogtng.reply_attach();
247    blogtng.insert_checkall_checkbox();
248});
249