To check out this repository please hg clone the following URL, or open the URL using EasyMercurial or your preferred Mercurial client.

Statistics Download as Zip
| Branch: | Tag: | Revision:

root / .svn / pristine / 3e / 3ecbdf2b380b8b58c6f31309dfb99930076f3961.svn-base @ 1298:4f746d8966dd

History | View | Annotate | Download (10.9 KB)

1 1295:622f24f53b42 Chris
/* ***** BEGIN LICENSE BLOCK *****
2
 * This file is part of DotClear.
3
 * Copyright (c) 2005 Nicolas Martin & Olivier Meunier and contributors. All
4
 * rights reserved.
5
 *
6
 * DotClear is free software; you can redistribute it and/or modify
7
 * it under the terms of the GNU General Public License as published by
8
 * the Free Software Foundation; either version 2 of the License, or
9
 * (at your option) any later version.
10
 *
11
 * DotClear 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.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with DotClear; if not, write to the Free Software
18
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
 *
20
 * ***** END LICENSE BLOCK *****
21
*/
22
23
/* Modified by JP LANG for textile formatting */
24
25
function jsToolBar(textarea) {
26
	if (!document.createElement) { return; }
27
28
	if (!textarea) { return; }
29
30
	if ((typeof(document["selection"]) == "undefined")
31
	&& (typeof(textarea["setSelectionRange"]) == "undefined")) {
32
		return;
33
	}
34
35
	this.textarea = textarea;
36
37
	this.editor = document.createElement('div');
38
	this.editor.className = 'jstEditor';
39
40
	this.textarea.parentNode.insertBefore(this.editor,this.textarea);
41
	this.editor.appendChild(this.textarea);
42
43
	this.toolbar = document.createElement("div");
44
	this.toolbar.className = 'jstElements';
45
	this.editor.parentNode.insertBefore(this.toolbar,this.editor);
46
47
	// Dragable resizing
48
	if (this.editor.addEventListener && navigator.appVersion.match(/\bMSIE\b/))
49
	{
50
		this.handle = document.createElement('div');
51
		this.handle.className = 'jstHandle';
52
		var dragStart = this.resizeDragStart;
53
		var This = this;
54
		this.handle.addEventListener('mousedown',function(event) { dragStart.call(This,event); },false);
55
		// fix memory leak in Firefox (bug #241518)
56
		window.addEventListener('unload',function() {
57
				var del = This.handle.parentNode.removeChild(This.handle);
58
				delete(This.handle);
59
		},false);
60
61
		this.editor.parentNode.insertBefore(this.handle,this.editor.nextSibling);
62
	}
63
64
	this.context = null;
65
	this.toolNodes = {}; // lorsque la toolbar est dessinée , cet objet est garni
66
					// de raccourcis vers les éléments DOM correspondants aux outils.
67
}
68
69
function jsButton(title, fn, scope, className) {
70
    if(typeof jsToolBar.strings == 'undefined') {
71
      this.title = title || null;
72
    } else {
73
      this.title = jsToolBar.strings[title] || title || null;
74
    }
75
	this.fn = fn || function(){};
76
	this.scope = scope || null;
77
	this.className = className || null;
78
}
79
jsButton.prototype.draw = function() {
80
	if (!this.scope) return null;
81
82
	var button = document.createElement('button');
83
	button.setAttribute('type','button');
84
	button.tabIndex = 200;
85
	if (this.className) button.className = this.className;
86
	button.title = this.title;
87
	var span = document.createElement('span');
88
	span.appendChild(document.createTextNode(this.title));
89
	button.appendChild(span);
90
91
	if (this.icon != undefined) {
92
		button.style.backgroundImage = 'url('+this.icon+')';
93
	}
94
	if (typeof(this.fn) == 'function') {
95
		var This = this;
96
		button.onclick = function() { try { This.fn.apply(This.scope, arguments) } catch (e) {} return false; };
97
	}
98
	return button;
99
}
100
101
function jsSpace(id) {
102
	this.id = id || null;
103
	this.width = null;
104
}
105
jsSpace.prototype.draw = function() {
106
	var span = document.createElement('span');
107
	if (this.id) span.id = this.id;
108
	span.appendChild(document.createTextNode(String.fromCharCode(160)));
109
	span.className = 'jstSpacer';
110
	if (this.width) span.style.marginRight = this.width+'px';
111
112
	return span;
113
}
114
115
function jsCombo(title, options, scope, fn, className) {
116
	this.title = title || null;
117
	this.options = options || null;
118
	this.scope = scope || null;
119
	this.fn = fn || function(){};
120
	this.className = className || null;
121
}
122
jsCombo.prototype.draw = function() {
123
	if (!this.scope || !this.options) return null;
124
125
	var select = document.createElement('select');
126
	if (this.className) select.className = className;
127
	select.title = this.title;
128
129
	for (var o in this.options) {
130
		//var opt = this.options[o];
131
		var option = document.createElement('option');
132
		option.value = o;
133
		option.appendChild(document.createTextNode(this.options[o]));
134
		select.appendChild(option);
135
	}
136
137
	var This = this;
138
	select.onchange = function() {
139
		try {
140
			This.fn.call(This.scope, this.value);
141
		} catch (e) { alert(e); }
142
143
		return false;
144
	}
145
146
	return select;
147
}
148
149
150
jsToolBar.prototype = {
151
	base_url: '',
152
	mode: 'wiki',
153
	elements: {},
154
	help_link: '',
155
156
	getMode: function() {
157
		return this.mode;
158
	},
159
160
	setMode: function(mode) {
161
		this.mode = mode || 'wiki';
162
	},
163
164
	switchMode: function(mode) {
165
		mode = mode || 'wiki';
166
		this.draw(mode);
167
	},
168
169
	setHelpLink: function(link) {
170
		this.help_link = link;
171
	},
172
173
	button: function(toolName) {
174
		var tool = this.elements[toolName];
175
		if (typeof tool.fn[this.mode] != 'function') return null;
176
		var b = new jsButton(tool.title, tool.fn[this.mode], this, 'jstb_'+toolName);
177
		if (tool.icon != undefined) b.icon = tool.icon;
178
		return b;
179
	},
180
	space: function(toolName) {
181
		var tool = new jsSpace(toolName)
182
		if (this.elements[toolName].width !== undefined)
183
			tool.width = this.elements[toolName].width;
184
		return tool;
185
	},
186
	combo: function(toolName) {
187
		var tool = this.elements[toolName];
188
		var length = tool[this.mode].list.length;
189
190
		if (typeof tool[this.mode].fn != 'function' || length == 0) {
191
			return null;
192
		} else {
193
			var options = {};
194
			for (var i=0; i < length; i++) {
195
				var opt = tool[this.mode].list[i];
196
				options[opt] = tool.options[opt];
197
			}
198
			return new jsCombo(tool.title, options, this, tool[this.mode].fn);
199
		}
200
	},
201
	draw: function(mode) {
202
		this.setMode(mode);
203
204
		// Empty toolbar
205
		while (this.toolbar.hasChildNodes()) {
206
			this.toolbar.removeChild(this.toolbar.firstChild)
207
		}
208
		this.toolNodes = {}; // vide les raccourcis DOM/**/
209
210
		// Draw toolbar elements
211
		var b, tool, newTool;
212
213
		for (var i in this.elements) {
214
			b = this.elements[i];
215
216
			var disabled =
217
			b.type == undefined || b.type == ''
218
			|| (b.disabled != undefined && b.disabled)
219
			|| (b.context != undefined && b.context != null && b.context != this.context);
220
221
			if (!disabled && typeof this[b.type] == 'function') {
222
				tool = this[b.type](i);
223
				if (tool) newTool = tool.draw();
224
				if (newTool) {
225
					this.toolNodes[i] = newTool; //mémorise l'accès DOM pour usage éventuel ultérieur
226
					this.toolbar.appendChild(newTool);
227
				}
228
			}
229
		}
230
	},
231
232
	singleTag: function(stag,etag) {
233
		stag = stag || null;
234
		etag = etag || stag;
235
236
		if (!stag || !etag) { return; }
237
238
		this.encloseSelection(stag,etag);
239
	},
240
241
	encloseLineSelection: function(prefix, suffix, fn) {
242
		this.textarea.focus();
243
244
		prefix = prefix || '';
245
		suffix = suffix || '';
246
247
		var start, end, sel, scrollPos, subst, res;
248
249
		if (typeof(document["selection"]) != "undefined") {
250
			sel = document.selection.createRange().text;
251
		} else if (typeof(this.textarea["setSelectionRange"]) != "undefined") {
252
			start = this.textarea.selectionStart;
253
			end = this.textarea.selectionEnd;
254
			scrollPos = this.textarea.scrollTop;
255
			// go to the start of the line
256
			start = this.textarea.value.substring(0, start).replace(/[^\r\n]*$/g,'').length;
257
			// go to the end of the line
258
            end = this.textarea.value.length - this.textarea.value.substring(end, this.textarea.value.length).replace(/^[^\r\n]*/, '').length;
259
			sel = this.textarea.value.substring(start, end);
260
		}
261
262
		if (sel.match(/ $/)) { // exclude ending space char, if any
263
			sel = sel.substring(0, sel.length - 1);
264
			suffix = suffix + " ";
265
		}
266
267
		if (typeof(fn) == 'function') {
268
			res = (sel) ? fn.call(this,sel) : fn('');
269
		} else {
270
			res = (sel) ? sel : '';
271
		}
272
273
		subst = prefix + res + suffix;
274
275
		if (typeof(document["selection"]) != "undefined") {
276
			document.selection.createRange().text = subst;
277
			var range = this.textarea.createTextRange();
278
			range.collapse(false);
279
			range.move('character', -suffix.length);
280
			range.select();
281
		} else if (typeof(this.textarea["setSelectionRange"]) != "undefined") {
282
			this.textarea.value = this.textarea.value.substring(0, start) + subst +
283
			this.textarea.value.substring(end);
284
			if (sel) {
285
				this.textarea.setSelectionRange(start + subst.length, start + subst.length);
286
			} else {
287
				this.textarea.setSelectionRange(start + prefix.length, start + prefix.length);
288
			}
289
			this.textarea.scrollTop = scrollPos;
290
		}
291
	},
292
293
	encloseSelection: function(prefix, suffix, fn) {
294
		this.textarea.focus();
295
296
		prefix = prefix || '';
297
		suffix = suffix || '';
298
299
		var start, end, sel, scrollPos, subst, res;
300
301
		if (typeof(document["selection"]) != "undefined") {
302
			sel = document.selection.createRange().text;
303
		} else if (typeof(this.textarea["setSelectionRange"]) != "undefined") {
304
			start = this.textarea.selectionStart;
305
			end = this.textarea.selectionEnd;
306
			scrollPos = this.textarea.scrollTop;
307
			sel = this.textarea.value.substring(start, end);
308
		}
309
310
		if (sel.match(/ $/)) { // exclude ending space char, if any
311
			sel = sel.substring(0, sel.length - 1);
312
			suffix = suffix + " ";
313
		}
314
315
		if (typeof(fn) == 'function') {
316
			res = (sel) ? fn.call(this,sel) : fn('');
317
		} else {
318
			res = (sel) ? sel : '';
319
		}
320
321
		subst = prefix + res + suffix;
322
323
		if (typeof(document["selection"]) != "undefined") {
324
			document.selection.createRange().text = subst;
325
			var range = this.textarea.createTextRange();
326
			range.collapse(false);
327
			range.move('character', -suffix.length);
328
			range.select();
329
//			this.textarea.caretPos -= suffix.length;
330
		} else if (typeof(this.textarea["setSelectionRange"]) != "undefined") {
331
			this.textarea.value = this.textarea.value.substring(0, start) + subst +
332
			this.textarea.value.substring(end);
333
			if (sel) {
334
				this.textarea.setSelectionRange(start + subst.length, start + subst.length);
335
			} else {
336
				this.textarea.setSelectionRange(start + prefix.length, start + prefix.length);
337
			}
338
			this.textarea.scrollTop = scrollPos;
339
		}
340
	},
341
342
	stripBaseURL: function(url) {
343
		if (this.base_url != '') {
344
			var pos = url.indexOf(this.base_url);
345
			if (pos == 0) {
346
				url = url.substr(this.base_url.length);
347
			}
348
		}
349
350
		return url;
351
	}
352
};
353
354
/** Resizer
355
-------------------------------------------------------- */
356
jsToolBar.prototype.resizeSetStartH = function() {
357
	this.dragStartH = this.textarea.offsetHeight + 0;
358
};
359
jsToolBar.prototype.resizeDragStart = function(event) {
360
	var This = this;
361
	this.dragStartY = event.clientY;
362
	this.resizeSetStartH();
363
	document.addEventListener('mousemove', this.dragMoveHdlr=function(event){This.resizeDragMove(event);}, false);
364
	document.addEventListener('mouseup', this.dragStopHdlr=function(event){This.resizeDragStop(event);}, false);
365
};
366
367
jsToolBar.prototype.resizeDragMove = function(event) {
368
	this.textarea.style.height = (this.dragStartH+event.clientY-this.dragStartY)+'px';
369
};
370
371
jsToolBar.prototype.resizeDragStop = function(event) {
372
	document.removeEventListener('mousemove', this.dragMoveHdlr, false);
373
	document.removeEventListener('mouseup', this.dragStopHdlr, false);
374
};