1/**
2 * @date 20130405 Leo Eibler <dokuwiki@sprossenwanne.at> \n
3 *                replace old sack() method with new jQuery method and use post instead of get - see https://www.dokuwiki.org/devel:jqueryfaq \n
4 * @date 20130407 Leo Eibler <dokuwiki@sprossenwanne.at> \n
5 *                use jQuery for finding the elements \n
6 * @date 20130408 Christian Marg <marg@rz.tu-clausthal.de> \n
7 *                change only the clicked todoitem instead of all items with the same text \n
8 * @date 20130408 Leo Eibler <dokuwiki@sprossenwanne.at> \n
9 *                migrate changes made by Christian Marg to current version of plugin (use jQuery) \n
10 * @date 20130410 by Leo Eibler <dokuwiki@sprossenwanne.at> / http://www.eibler.at \n
11 *                bugfix: encoding html code (security risk <todo><script>alert('hi')</script></todo>) - bug reported by Andreas \n
12 * @date 20130413 Christian Marg <marg@rz.tu-clausthal.de> \n
13 *                bugfix: chk.attr('checked') returns checkbox state from html - use chk.is(':checked') - see http://www.unforastero.de/jquery/checkbox-angehakt.php \n
14 * @date 20130413 by Leo Eibler <dokuwiki@sprossenwanne.at> / http://www.eibler.at \n
15 *                bugfix: config option Strikethrough \n
16 */
17
18/**
19 * html-layout:
20 *
21 * +input[checkbox].todocheckbox
22 * +span.todotext
23 * -del
24 * --span.todoinnertext
25 * ---anchor with text or text only
26 */
27
28var ToDoPlugin = {
29    /**
30     * lock to prevent simultanous requests
31     */
32    locked: false,
33
34    /**
35     * @brief onclick method for input element
36     *
37     * @param {jQuery} $chk the jQuery input element
38     */
39    todo: function ($chk) {
40        //skip when locked
41        if (ToDoPlugin.locked) {
42            return;
43        }
44        //set lock
45        ToDoPlugin.locked = true;
46
47        var $spanTodoinnertext = $chk.nextAll("span.todotext:first").find("span.todoinnertext"),
48            param = $chk.data(), // contains: index, pageid, date, strikethrough
49            checked = !$chk.is(':checked');
50
51        // if the data-index attribute is set, this is a call from the page where the todos are defined
52        if (param.index === undefined) param.index = -1;
53
54        if ($spanTodoinnertext.length) {
55            /**
56             * Callback function update the todoitem when save request succeed
57             *
58             * @param {Array} data returned by ajax request
59             */
60            var whenCompleted = function (data) {
61                //update date after edit and show alert when needed
62                if (data.date) {
63                    jQuery('input.todocheckbox').data('date', data.date);
64                }
65                if (data.message) {
66                    alert(data.message);
67                }
68                //apply styling, or undo checking checkbox
69                if (data.succeed) {
70                    $chk.prop('checked', checked);
71
72                    if (checked) {
73                        if (param.strikethrough && !$spanTodoinnertext.parent().is("del")) {
74                            $spanTodoinnertext.wrap("<del></del>");
75                        }
76                    } else {
77                        if ($spanTodoinnertext.parent().is("del")) {
78                            $spanTodoinnertext.unwrap();
79                        }
80                    }
81                }
82
83                //release lock
84                ToDoPlugin.locked = false;
85            };
86
87            jQuery.post(
88                DOKU_BASE + 'lib/exe/ajax.php',
89                {
90                    call: 'plugin_todo',
91                    mode: 'checkbox',
92                    index: param.index,
93                    pageid: param.pageid,
94                    checked: checked ? "1" : "0",
95                    date: param.date
96                },
97                whenCompleted,
98                'json'
99            );
100        } else {
101            alert("Appropriate javascript element not found.\nReverting checkmark.");
102        }
103    },
104
105    uncheckall: function () {
106        if (ToDoPlugin.locked) {
107            return;
108        }
109        ToDoPlugin.locked = true;
110
111        var whenCompleted = function () {
112            jQuery('input.todocheckbox').each(function() {
113                jQuery(this).prop('checked', false);
114            });
115
116            jQuery('span.todoinnertext').each(function () {
117                if (jQuery(this).parent().is("del")) {
118                    jQuery(this).unwrap();
119                }
120            });
121
122            jQuery('span.todouser').each(function () {
123                jQuery(this).remove();
124            });
125
126            ToDoPlugin.locked = false;
127        };
128
129        jQuery.post(
130            DOKU_BASE + 'lib/exe/ajax.php',
131            {
132                call: 'plugin_todo',
133                mode: 'uncheckall',
134                pageid: jQuery('input.todocheckbox:first').data().pageid
135            },
136        whenCompleted, 'json');
137    }
138};
139
140jQuery(function () {
141    // add handler to checkbox
142    jQuery('input.todocheckbox').click(function (e) {
143        e.preventDefault();
144        e.stopPropagation();
145
146        var $this = jQuery(this);
147        // undo checking the checkbox
148        $this.prop('checked', !$this.is(':checked'));
149
150        ToDoPlugin.todo($this);
151    });
152
153    // add click handler to todotext spans when marked with 'clickabletodo'
154    jQuery('span.todotext.clickabletodo').click(function () {
155        //Find the checkbox node we need
156        var $chk = jQuery(this).prevAll('input.todocheckbox:first');
157
158        ToDoPlugin.todo($chk);
159    });
160
161    // add click handler to button to uncheck all todos on its page
162    jQuery('button.todouncheckall').click(function () {
163        ToDoPlugin.uncheckall();
164    });
165});