PageSourceSearch

https://demonwiki.org/lib/ajax/autosave.js

js demonwiki.org collected 2026-09-25 02:04:55 UTC 9,002 bytes, 233 lines download raw bytes

1var auto_save_submit = false;
2var sending_auto_save = false;
3var auto_save_debug = false;    // for development use
4
5function remove_save(editorId, autoSaveId) {
6    if (typeof editorId !== 'string' || !editorId || !autoSaveId || auto_save_submit) {
7        return;    // seems to get jQuery events arriving here or has been submitted before
8    }
9    if (sending_auto_save) {    // wait if autosaving
10        setTimeout(function () { remove_save(editorId, autoSaveId); }, 100);
11    }
12    auto_save_submit = true;
13    $.ajax({
14        url: $.service("autosave", "delete"),
15        data: {
16            editor_id: editorId,
17            referer: autoSaveId
18        },
19        type: "POST",
20        async: false,    // called on form submit (save or cancel) so need to wait otherwise the call gets cancelled
21        // good callback
22        success: function(data) {
23            // act casual?
24        },
25        // bad callback - no good info in the params :(
26        error: function(req, status, error) {
27            if (error && auto_save_debug) {
28                alert(tr("Auto Save removal returned an error: ") + error);
29            }
30        }
31    });
32}
33
34function toggle_autosaved(editorId, autoSaveId) {
35    if (typeof autoSaveId === 'undefined') { autoSaveId = ''; }
36    var output = '', prefix = '';
37    var $textarea = $('#' + editorId);
38    var textareaEditor = syntaxHighlighter.get($textarea);
39    var cked = typeof CKEDITOR !== 'undefined' ? CKEDITOR.instances[editorId] : null;
40    if (!$textarea.data("original")) {    // no save version already?
41        if (cked) { prefix = 'cke_contents_'; }
42        ajaxLoadingShow(prefix + editorId);
43
44        $.getJSON( $.service("autosave", "get"), {
45                editor_id: editorId,
46                referer: autoSaveId
47            },
48            function(data) {
49                output = data.data;
50                // back up current
51                $textarea.data("original", $textarea.val());
52                if (cked) {
53                    cked.setData(output);
54                } else if (textareaEditor) {
55                    textareaEditor.setValue(output);
56                } else if ($("#"+editorId).length) {    // wiki editor
57                    $textarea.val(output);
58                }
59                ajaxLoadingHide();
60            }
61        );
62
63    } else {    // toggle back to original
64        syntaxHighlighter.sync($textarea);
65
66        output = $textarea.data("original");
67        if (cked) {
68            cked.setData(output);    // cked leaves the original content in the ta
69        } else if (textareaEditor) {
70            textareaEditor.setValue(output);
71        } else if ($("#"+editorId).length) {    // wiki editor
72            $("#"+editorId).val(output);
73        }
74        $textarea.data("original", "");
75    }
76    // swap the messages around (fixed to first textarea only for now)
77    var msg = $(".autosave_message_2").first().text();
78    $(".autosave_message_2").first().text($(".autosave_message").first().text());
79    $(".autosave_message").first().text(msg);
80
81    return output;
82}
83
84function auto_save_allowHtml(form) {
85    const $hiddenInput = $("input[name=allowhtml][type=hidden]", form);
86    if ($hiddenInput.length) {
87        if ($hiddenInput.val() === "on" || parseInt($hiddenInput.val())) {
88            return 1;
89        } else {
90            return 0;
91        }
92    } else {
93        return $("input[name=allowhtml]:checked", form).length;
94    }
95}
96
97function auto_save( editorId ) {
98
99    if (!editorId && auto_save_debug) { alert(tr("Auto save: No editorId set")); }
100
101    if ( !auto_save_submit && !sending_auto_save) {
102
103        var $textarea = $('#' + editorId);
104        var autoSaveId = $textarea.data("autoSaveId");
105
106        syntaxHighlighter.sync($textarea);
107
108        var data = $textarea.val();
109        var allowHtml = auto_save_allowHtml($textarea.prop("form"));
110
111        if (data !== $textarea.data("original") || $textarea.data("last") !== data || $textarea.data("old_allowhtml") != allowHtml) {
112            $textarea.data("last", data);
113            sending_auto_save = true;
114            $.ajax({
115                url: $.service("autosave", "save"),
116                data: {
117                    editor_id: editorId,
118                    referer: autoSaveId,
119                    data: data
120                },
121                type: "POST",
122                // good callback
123                success: function(data) {
124                    // update button when it's there (TODO)
125                    if (ajaxPreviewWindow && typeof ajaxPreviewWindow.get_new_preview === 'function') {
126                         ajaxPreviewWindow.get_new_preview();
127                    } else {
128                        ajax_preview( editorId, autoSaveId, true );
129                    }
130                    $textarea.data("old_allowhtml", allowHtml);
131                    sending_auto_save = false;
132                },
133                // bad callback - no good info in the params :(
134                error: function(req, status, error) {
135                    if (error) {
136                        if (error == "Forbidden") {
137                            error = req.responseText.replace(/(<([^>]+)>)/ig,"");
138                        }
139                        // If autosave desabled, generate an normal alert in the page to inform the user
140                        if ($("input[name=alert_content]").val()) {
141		                    $("#tiki_autosave_alert").empty();
142		                    $("#tiki_autosave_alert").append($("input[name=alert_content]").val());
143		                    $("#tiki_autosave_alert").show();
144                        } else {
145                        	alert(tr("Auto Save error: ") + error);
146                        }
147                    }
148                    sending_auto_save = false;
149                }
150            });
151        } else {    // not changed, reset timeout
152        }
153    }
154}
155
156function register_id( editorId, autoSaveId ) {
157    var $textarea = $('#' + editorId);
158    $textarea.data("autoSaveId", autoSaveId);
159    if (typeof syntaxHighlighter.sync === 'function') {
160        syntaxHighlighter.sync($textarea);
161    }
162    $textarea.parents('form').on("submit", function() { remove_save(editorId, autoSaveId); });
163    $textarea.on("change", function () { auto_save( editorId ); });
164}
165
166var ajaxPreviewWindow;
167
168function ajax_preview(editorId, autoSaveId, inPage) {
169    if (editorId) {
170        var $textarea = $('#' + editorId);
171        var $autosavepreview = $("#autosave_preview");
172        syntaxHighlighter.sync($textarea);
173        const allowHtml = auto_save_allowHtml($textarea.prop("form")),
174            is_markdown = $("input[name=syntax]").val() === "markdown" ? 1 : 0;
175        if (!ajaxPreviewWindow) {
176            if (inPage) {
177                var $prvw = $("#autosave_preview:visible");
178                if ($prvw.length) {
179                    ajaxLoadingShow($autosavepreview);
180                    var h = location.search.match(/&hdr=(\d?)/);
181                    h = h && h.length ? h[1] : "";
182                    $.get($.service("edit", "preview"), {
183                        editor_id: editorId,
184                        autoSaveId: autoSaveId,
185                        inPage: 1,
186                        hdr: h,
187                        allowHtml: allowHtml,
188                        is_markdown: is_markdown
189                    }, function(data) {
190                        // remove JS and disarm links
191                        data = data.replace(/\shref/gi, " tiki_href").
192                                replace(/\sonclick/gi, " tiki_onclick").
193                                replace(/<script[.\s\S]*?<\/script>/mgi, "");
194                        $(".preview_contents", $autosavepreview).html(data);
195                        $("#preview_diff_style").val(function(){return getCookie("preview_diff_style","preview","");});
196                        ajaxLoadingHide();
197                    });
198                }
199            } else {
200                initPreviewWindow(editorId, autoSaveId, allowHtml, is_markdown);
201            }
202        } else {
203            if (typeof ajaxPreviewWindow.get_new_preview === 'function') {
204                ajaxPreviewWindow.get_new_preview();
205                ajaxPreviewWindow.focus();
206            } else {
207                initPreviewWindow(editorId, autoSaveId, allowHtml, is_markdown);
208            }
209        }
210    } else {
211        if (auto_save_debug) {
212            alert("Auto save data not found");
213        }
214    }
215
216}
217
218function initPreviewWindow (editorId, autoSaveId, allowHtml, is_markdown) {
219    var features = 'menubar=no,toolbar=no,fullscreen=no,titlebar=no,status=no,width=600';
220    var url = $.service("edit", "preview", {
221        editor_id: editorId,
222        autoSaveId: autoSaveId,
223        allowHtml: allowHtml,
224        is_markdown: is_markdown
225    });
226    window.open(url, "_blank", features);
227}
228
229$(window).on("pagehide", function () {
230    if (ajaxPreviewWindow && typeof ajaxPreviewWindow.get_new_preview === 'function') {
231        ajaxPreviewWindow.close();
232    }
233});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.