2
Copyright (C) 2007 Crawford Currie http://wikiring.com and Arthur Clemens
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.
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.
15
As per the GPL, removal of this notice is prohibited.
18
// The FoswikiTiny class object
22
request : null, // Container for HTTP request object
25
tml2html : new Array(), // callbacks, attached in plugins
26
html2tml : new Array(), // callbacks, attached in plugins
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);
34
return FoswikiTiny.foswikiVars[name];
37
expandVariables : function(url) {
38
for (var i in FoswikiTiny.foswikiVars) {
39
url = url.replace('%' + i + '%', FoswikiTiny.foswikiVars[i], 'g');
44
enableSave: function(enabled) {
45
var status = enabled ? null : "disabled";
46
var elm = document.getElementById("save");
48
elm.disabled = status;
50
elm = document.getElementById("preview");
52
elm.style.display = 'none'; // Item5263: broken preview
53
elm.disabled = status;
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();
67
// branch for IE/Windows ActiveX version
68
FoswikiTiny.request.req = new ActiveXObject("Microsoft.XMLHTTP");
70
// branch for native XMLHttpRequest object
71
FoswikiTiny.request.req = new XMLHttpRequest();
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);
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) {
90
if (FoswikiTiny.request.req.status == 200) {
98
FoswikiTiny.request.req.send(params);
101
initialisedFromServer : false,
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;
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;
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 ]);
128
FoswikiTiny.transform(
129
inst, "html2tml", text,
131
FoswikiTiny.enableSave(false);
132
var te = FoswikiTiny.request.editor.oldTargetElement;
133
te.value = "Please wait... retrieving page from server";
136
var te = FoswikiTiny.request.editor.oldTargetElement;
137
var text = FoswikiTiny.request.req.responseText;
139
FoswikiTiny.enableSave(true);
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
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);
153
el.style.display = "block";
155
// does not exist, create it
156
el = document.createElement('INPUT');
159
el.value = "WYSIWYG";
160
el.className = "foswikiButton";
161
el.onclick = function () {
162
tinyMCE.execCommand("mceToggleEditor", null, inst.editorId);
165
// Need to insert after to avoid knackering 'back'
166
var pel = inst.oldTargetElement.parentNode;
167
pel.insertBefore(el, inst.oldTargetElement);
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;
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,
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>");
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 ]);
201
tinyMCE.setInnerHTML(FoswikiTiny.request.editor.getBody(), text);
202
FoswikiTiny.request.editor.isNotDirty = true;
203
FoswikiTiny.enableSave(true);
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
215
// Hide the conversion button, if it exists
216
var id = editor.editorId + "_2WYSIWYG";
217
var el = document.getElementById(id);
220
el.style.display = "none";
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 ]);
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;
242
// Called on URL insertion, but not on image sources. Expand Foswiki
243
// variables in the url.
244
convertLink : function(url, node, onSave){
248
var pubUrl = FoswikiTiny.getFoswikiVar("PUBURL");
249
var vsu = FoswikiTiny.getFoswikiVar("VIEWSCRIPTURL");
250
url = FoswikiTiny.expandVariables(url);
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);
261
if (url.indexOf('/') == -1) {
262
// if it's a wikiword, make a suitable link
263
var match = /^((?:\w+\.)*)(\w+)$/.exec(url);
266
var topic = match[2];
267
if (web == null || web.length == 0) {
268
web = FoswikiTiny.getFoswikiVar("WEB");
270
web = web.replace(/\.+/g, '/');
271
web = web.replace(/\/+$/, '');
272
url = vsu + '/' + web + '/' + topic;
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){
285
var base = FoswikiTiny.getFoswikiVar("PUBURL") + '/'
286
+ FoswikiTiny.getFoswikiVar("WEB") + '/'
287
+ FoswikiTiny.getFoswikiVar("TOPIC") + '/';
288
url = FoswikiTiny.expandVariables(url);
289
if (url.indexOf('/') == -1) {
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;
310
return FoswikiTiny.metaTags[inKey];
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) + "});");
320
alert("Unable to install TinyMCE; <META name='TINYMCEPLUGIN_INIT' is missing");