~kosova/+junk/tuxfamily-twiki

« back to all changes in this revision

Viewing changes to foswiki/pub/System/TinyMCEPlugin/foswiki_tiny_src.js

  • Committer: James Michael DuPont
  • Date: 2009-07-18 19:58:49 UTC
  • Revision ID: jamesmikedupont@gmail.com-20090718195849-vgbmaht2ys791uo2
added foswiki

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
  Copyright (C) 2007 Crawford Currie http://wikiring.com and Arthur Clemens
 
3
  All Rights Reserved.
 
4
 
 
5
  This program is free software; you can redistribute it and/or
 
6
  modify it under the terms of the GNU General Public License
 
7
  as published by the Free Software Foundation; either version 2
 
8
  of the License, or (at your option) any later version. For
 
9
  more details read LICENSE in the root of the Foswiki distribution.
 
10
 
 
11
  This program is distributed in the hope that it will be useful,
 
12
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
14
 
 
15
  As per the GPL, removal of this notice is prohibited.
 
16
*/
 
17
 
 
18
// The FoswikiTiny class object
 
19
var FoswikiTiny = {
 
20
 
 
21
    foswikiVars : null,
 
22
    request : null, // Container for HTTP request object
 
23
    metaTags : null,
 
24
 
 
25
    tml2html : new Array(), // callbacks, attached in plugins
 
26
    html2tml : new Array(), // callbacks, attached in plugins
 
27
 
 
28
    // Get a Foswiki variable from the set passed
 
29
    getFoswikiVar : function (name) {
 
30
        if (FoswikiTiny.foswikiVars == null) {
 
31
            var sets = tinyMCE.getParam("foswiki_vars", "");
 
32
            FoswikiTiny.foswikiVars = eval(sets);
 
33
        }
 
34
        return FoswikiTiny.foswikiVars[name];
 
35
    },
 
36
 
 
37
    expandVariables : function(url) {
 
38
        for (var i in FoswikiTiny.foswikiVars) {
 
39
            url = url.replace('%' + i + '%', FoswikiTiny.foswikiVars[i], 'g');
 
40
        }
 
41
        return url;
 
42
    },
 
43
 
 
44
    enableSave: function(enabled) {
 
45
        var status = enabled ? null : "disabled";
 
46
        var elm = document.getElementById("save");
 
47
        if (elm) {
 
48
            elm.disabled = status;
 
49
        }
 
50
        elm = document.getElementById("preview");
 
51
        if (elm) {
 
52
            elm.style.display = 'none'; // Item5263: broken preview
 
53
            elm.disabled = status;
 
54
        }
 
55
    },
 
56
 
 
57
    transform : function(editor, handler, text, onReadyToSend, onReply, onFail) {
 
58
        // Work out the rest URL from the location
 
59
        var url = FoswikiTiny.getFoswikiVar("SCRIPTURL");
 
60
        var suffix = FoswikiTiny.getFoswikiVar("SCRIPTSUFFIX");
 
61
        if (suffix == null) suffix = '';
 
62
        url += "/rest" + suffix + "/WysiwygPlugin/" + handler;
 
63
        var path = FoswikiTiny.getFoswikiVar("WEB") + '.'
 
64
        + FoswikiTiny.getFoswikiVar("TOPIC");
 
65
        FoswikiTiny.request = new Object();
 
66
        if (tinyMCE.isIE) {
 
67
            // branch for IE/Windows ActiveX version
 
68
            FoswikiTiny.request.req = new ActiveXObject("Microsoft.XMLHTTP");
 
69
        } else {
 
70
            // branch for native XMLHttpRequest object
 
71
            FoswikiTiny.request.req = new XMLHttpRequest();
 
72
        }
 
73
        FoswikiTiny.request.editor = editor;
 
74
        FoswikiTiny.request.req.open("POST", url, true);
 
75
        FoswikiTiny.request.req.setRequestHeader(
 
76
            "Content-type", "application/x-www-form-urlencoded");
 
77
        var params = "nocache=" + encodeURIComponent((new Date()).getTime())
 
78
        + "&topic=" + encodeURIComponent(path)
 
79
        + "&text=" + encodeURIComponent(text);
 
80
    
 
81
        FoswikiTiny.request.req.setRequestHeader(
 
82
            "Content-length", params.length);
 
83
        /* Banjaxes NTLM - see http://foswiki.org/Tasks/Item5859 for analysis
 
84
           FoswikiTiny.request.req.setRequestHeader("Connection", "close"); */
 
85
        FoswikiTiny.request.req.onreadystatechange = function() {
 
86
            // Callback for XMLHttpRequest
 
87
            // only if FoswikiTiny.request.req shows "complete"
 
88
            if (FoswikiTiny.request.req.readyState == 4) {
 
89
                // only if "OK"
 
90
                if (FoswikiTiny.request.req.status == 200) {
 
91
                    onReply();
 
92
                } else {
 
93
                    onFail();
 
94
                }
 
95
            }
 
96
        };
 
97
        onReadyToSend();
 
98
        FoswikiTiny.request.req.send(params);
 
99
    },
 
100
 
 
101
    initialisedFromServer : false,
 
102
 
 
103
    // Set up content for the initial edit
 
104
    setUpContent : function(editor_id, body, doc) {
 
105
        // If we haven't done it before, then transform from TML
 
106
        // to HTML. We need this test so that pressing the 'back'
 
107
        // button from a failed save doesn't banjax the old content.
 
108
        if (FoswikiTiny.initialisedFromServer) return;
 
109
        var editor = tinyMCE.getInstanceById(editor_id);
 
110
        FoswikiTiny.switchToWYSIWYG(editor);
 
111
        FoswikiTiny.initialisedFromServer = true;
 
112
    },
 
113
 
 
114
    // Convert HTML content to textarea. Called from the WYSIWYG->raw switch
 
115
    switchToRaw : function (inst) {
 
116
        // As shown by OliverKrueger in Item5138, trivial text may include
 
117
        // UTF-8 chars. These need to be encoded to entities before we can
 
118
        // pass the string back to the server. This is done in triggerSave,
 
119
        // but note that it requires cleanup:true to work.
 
120
        inst.triggerSave(false, true);
 
121
        var text = inst.oldTargetElement.value;
 
122
 
 
123
        // Evaluate post-processors
 
124
        for (var i = 0; i < FoswikiTiny.html2tml.length; i++) {
 
125
            var cb = FoswikiTiny.html2tml[i];
 
126
            text = cb.apply(inst, [ inst, text ]);
 
127
        }
 
128
        FoswikiTiny.transform(
 
129
            inst, "html2tml", text,
 
130
            function () {
 
131
                FoswikiTiny.enableSave(false);
 
132
                var te = FoswikiTiny.request.editor.oldTargetElement;
 
133
                te.value = "Please wait... retrieving page from server";
 
134
            },
 
135
            function () {
 
136
                var te = FoswikiTiny.request.editor.oldTargetElement;
 
137
                var text = FoswikiTiny.request.req.responseText;
 
138
                te.value = text;
 
139
                FoswikiTiny.enableSave(true);
 
140
            },
 
141
            function () {
 
142
                var te = FoswikiTiny.request.editor.oldTargetElement;
 
143
                te.value = "There was a problem retrieving the page: "
 
144
                    + FoswikiTiny.request.req.statusText;
 
145
                //FoswikiTiny.enableSave(true); leave it disabled
 
146
            });
 
147
        // Add the button for the switch back to WYSIWYG mode
 
148
        var eid = inst.editorId;
 
149
        var id = eid + "_2WYSIWYG";
 
150
        var el = document.getElementById(id);
 
151
        if (el) {
 
152
            // exists, unhide it
 
153
            el.style.display = "block";
 
154
        } else {
 
155
            // does not exist, create it
 
156
            el = document.createElement('INPUT');
 
157
            el.id = id;
 
158
            el.type = "button";
 
159
            el.value = "WYSIWYG";
 
160
            el.className = "foswikiButton";
 
161
            el.onclick = function () {
 
162
                tinyMCE.execCommand("mceToggleEditor", null, inst.editorId);
 
163
                return false;
 
164
            }
 
165
            // Need to insert after to avoid knackering 'back'
 
166
            var pel = inst.oldTargetElement.parentNode;
 
167
            pel.insertBefore(el, inst.oldTargetElement);
 
168
        }
 
169
        // SMELL: what if there is already an onchange handler?
 
170
        inst.oldTargetElement.onchange = function() {
 
171
            var inst = tinyMCE.getInstanceById(eid);
 
172
            inst.isNotDirty = false;
 
173
            return true;
 
174
        }
 
175
    },
 
176
 
 
177
    // Convert textarea content to HTML. This is invoked from the content
 
178
    // setup handler, and also from the raw->WYSIWYG switch
 
179
    switchToWYSIWYG : function (editor) {
 
180
        // Kill the change handler to avoid excess fires
 
181
        editor.oldTargetElement.onchange = null;
 
182
        // Need to tinyMCE.execCommand("mceToggleEditor", null, editor_id);
 
183
        FoswikiTiny.transform(
 
184
            editor, "tml2html", editor.oldTargetElement.value,
 
185
            function () {
 
186
                // Before send
 
187
                FoswikiTiny.enableSave(false);
 
188
                var editor = FoswikiTiny.request.editor;
 
189
                tinyMCE.setInnerHTML(
 
190
                    FoswikiTiny.request.editor.getBody(),
 
191
                    "<span class='foswikiAlert'>Please wait... retrieving page from server.</span>");
 
192
            },
 
193
            function () {
 
194
                // Handle the reply
 
195
                var text = FoswikiTiny.request.req.responseText;
 
196
                // Evaluate any registered pre-processors
 
197
                for (var i = 0; i < FoswikiTiny.tml2html.length; i++) {
 
198
                    var cb = FoswikiTiny.tml2html[i];
 
199
                    text = cb.apply(editor, [ editor, text ]);
 
200
                }
 
201
                tinyMCE.setInnerHTML(FoswikiTiny.request.editor.getBody(), text);
 
202
                FoswikiTiny.request.editor.isNotDirty = true;
 
203
                FoswikiTiny.enableSave(true);
 
204
            },
 
205
            function () {
 
206
                // Handle a failure
 
207
                tinyMCE.setInnerHTML(
 
208
                    FoswikiTiny.request.editor.getBody(),
 
209
                    "<div class='foswikiAlert'>"
 
210
                    + "There was a problem retrieving the page: "
 
211
                    + FoswikiTiny.request.req.statusText + "</div>");
 
212
                //FoswikiTiny.enableSave(true); leave save disabled
 
213
            });
 
214
 
 
215
        // Hide the conversion button, if it exists
 
216
        var id = editor.editorId + "_2WYSIWYG";
 
217
        var el = document.getElementById(id);
 
218
        if (el) {
 
219
            // exists, hide it
 
220
            el.style.display = "none";
 
221
        }
 
222
    },
 
223
 
 
224
    // Callback on save. Make sure the WYSIWYG flag ID is there.
 
225
    saveCallback : function(editor_id, html, body) {
 
226
        // Evaluate any registered post-processors
 
227
        var editor = tinyMCE.getInstanceById(editor_id);
 
228
        for (var i = 0; i < FoswikiTiny.html2tml.length; i++) {
 
229
            var cb = FoswikiTiny.html2tml[i];
 
230
            html = cb.apply(editor, [ editor, html ]);
 
231
        }
 
232
        var secret_id = tinyMCE.getParam('foswiki_secret_id');
 
233
        if (secret_id != null && html.indexOf(
 
234
                '<!--' + secret_id + '-->') == -1) {
 
235
            // Something ate the ID. Probably IE. Add it back.
 
236
            html = '<!--' + secret_id + '-->' + html;
 
237
        }
 
238
        return html;
 
239
    },
 
240
 
 
241
    // Called 
 
242
    // Called on URL insertion, but not on image sources. Expand Foswiki
 
243
    // variables in the url.
 
244
    convertLink : function(url, node, onSave){
 
245
        if(onSave == null)
 
246
            onSave = false;
 
247
        var orig = url;
 
248
        var pubUrl = FoswikiTiny.getFoswikiVar("PUBURL");
 
249
        var vsu = FoswikiTiny.getFoswikiVar("VIEWSCRIPTURL");
 
250
        url = FoswikiTiny.expandVariables(url);
 
251
        if (onSave) {
 
252
            if ((url.indexOf(pubUrl + '/') != 0) &&
 
253
                (url.indexOf(vsu + '/') == 0)) {
 
254
                url = url.substr(vsu.length + 1);
 
255
                url = url.replace(/\/+/g, '.');
 
256
                if (url.indexOf(FoswikiTiny.getFoswikiVar('WEB') + '.') == 0) {
 
257
                    url = url.substr(FoswikiTiny.getFoswikiVar('WEB').length + 1);
 
258
                }
 
259
            }
 
260
        } else {
 
261
            if (url.indexOf('/') == -1) {
 
262
                // if it's a wikiword, make a suitable link
 
263
                var match = /^((?:\w+\.)*)(\w+)$/.exec(url);
 
264
                if (match != null) {
 
265
                    var web = match[1];
 
266
                    var topic = match[2];
 
267
                    if (web == null || web.length == 0) {
 
268
                        web = FoswikiTiny.getFoswikiVar("WEB");
 
269
                    }
 
270
                    web = web.replace(/\.+/g, '/');
 
271
                    web = web.replace(/\/+$/, '');
 
272
                    url = vsu + '/' + web + '/' + topic;
 
273
                }
 
274
            }
 
275
        }
 
276
        return url;
 
277
    },
 
278
 
 
279
    // Called from Insert Image, when the image is inserted. The resultant
 
280
    // URL is only used when displaying the image in the picture dialog. It
 
281
    // is thrown away (reverts to the typed address) when the image is
 
282
    // actually inserted, at which time convertLink is called.
 
283
    convertPubURL : function(url){
 
284
        var orig = url;
 
285
        var base = FoswikiTiny.getFoswikiVar("PUBURL") + '/'
 
286
        + FoswikiTiny.getFoswikiVar("WEB") + '/'
 
287
        + FoswikiTiny.getFoswikiVar("TOPIC") + '/';
 
288
        url = FoswikiTiny.expandVariables(url);
 
289
        if (url.indexOf('/') == -1) {
 
290
            url = base + url;
 
291
        }
 
292
        return url;
 
293
    },
 
294
 
 
295
    getMetaTag : function(inKey) {
 
296
        if (FoswikiTiny.metaTags == null || FoswikiTiny.metaTags.length == 0) {
 
297
            // Do this the brute-force way because of the Firefox problem
 
298
            // seen sporadically on Bugs where the DOM appears complete, but
 
299
            // the META tags are not all found by getElementsByTagName
 
300
            var head = document.getElementsByTagName("META");
 
301
            head = head[0].parentNode.childNodes;
 
302
            FoswikiTiny.metaTags = new Array();
 
303
            for (var i = 0; i < head.length; i++) {
 
304
                if (head[i].tagName != null &&
 
305
                    head[i].tagName.toUpperCase() == 'META') {
 
306
                    FoswikiTiny.metaTags[head[i].name] = head[i].content;
 
307
                }
 
308
            }
 
309
        }
 
310
        return FoswikiTiny.metaTags[inKey]; 
 
311
    },
 
312
    
 
313
    install : function() {
 
314
        // find the TINYMCEPLUGIN_INIT META
 
315
        var tmce_init = FoswikiTiny.getMetaTag('TINYMCEPLUGIN_INIT');
 
316
        if (tmce_init != null) {
 
317
            eval("tinyMCE.init({" + unescape(tmce_init) + "});");
 
318
            return;
 
319
        }
 
320
        alert("Unable to install TinyMCE; <META name='TINYMCEPLUGIN_INIT' is missing"); 
 
321
    }
 
322
};