Test Failed
Push — master ( 357bf5...71cdad )
by Russell
03:53
created

external-content/javascript/external_tiny_mce_improvements.js   F

Complexity

Total Complexity 176
Complexity/F 2.79

Size

Lines of Code 872
Function Count 63

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
wmc 176
eloc 550
c 0
b 0
f 0
dl 0
loc 872
rs 2
mnd 113
bc 113
fnc 63
bpm 1.7936
cpm 2.7936
noi 100

How to fix   Complexity   

Complexity

Complex classes like external-content/javascript/external_tiny_mce_improvements.js often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
ToolbarForm = Class.create();
2
ToolbarForm.prototype = {
3
	toggle: function(ed) {
4
		if(this.style.display == 'block') this.close(ed);
5
		else this.open(ed);
6
	},
7
	close: function(ed) {
8
		if(this.style.display == 'block') {
9
			this.style.display = 'none';
10
			window.onresize();
11
		}
12
	},
13
	open: function(ed) {
14
		if(this.style.display != 'block') {
15
			this.style.display = 'block';
16
			window.onresize();
17
		}
18
	},
19
	onsubmit: function() {
20
		return false;
21
	}
22
}
23
24
LinkForm = Class.extend('ToolbarForm');
25
LinkForm.prototype = {
26
	initialize: function() {
27
		var i,item;
28
		for(i=0;item=this.elements.LinkType[i];i++) {
29
			item.parentForm = this;
30
			item.onclick = this.linkTypeChanged.bind(this);
31
		}
32
	},
33
34
	destroy: function() {
35
		this.ToolbarForm = null;
36
		this.onsubmit = null;
37
38
		var i,item;
39
		for(i=0;item=this.elements.LinkType[i];i++) {
40
			item.parentForm = null;
41
			item.onclick = null;
42
		}
43
	},
44
45
	linkTypeChanged: function(setDefaults) {
46
		var linkType = Form.Element.getValue(this.elements.LinkType);
47
		var list =  ['internal', 'external', 'file', 'externalcontent', 'email'];
48
		var i,item;
49
		for(i=0;item=list[i];i++) {
50
			$(item).style.display = (item == linkType) ? '' : 'none';
51
		}
52
		$('Anchor').style.display = (linkType == 'internal' || linkType == 'anchor') ? '' : 'none';
53
 		if($('Form_EditorToolbarLinkForm_TargetBlank')) {
54
 		    $('Form_EditorToolbarLinkForm_TargetBlank').disabled = (linkType == 'email');
55
 		    if(typeof setDefaults == 'undefined' || setDefaults) {
56
 			$('Form_EditorToolbarLinkForm_TargetBlank').checked = (linkType == 'file');
57
 		    }
58
		}
59
	},
60
61
	toggle: function(ed) {
62
		this.ToolbarForm.toggle(ed);
63
		this.respondToNodeChange(ed);
64
	},
65
66
	open: function(ed) {
67
		this.ToolbarForm.open();
68
69
		this.originalSelection = null;
70
		var mceInst = tinyMCE.activeEditor;
71
	},
72
73
	updateSelection: function(ed) {
74
		if(ed.selection.getRng()) {
75
		    this.originalSelection = ed.selection.getRng();
76
	    }
77
    },
78
79
	respondToNodeChange: function(ed) {
80
	    if(ed == null) ed = tinyMCE.activeEditor;
81
82
		if(this.style.display == 'block') {
83
			var i,data = this.getCurrentLink(ed);
84
85
			if(data) {
86
				for(i in data) {
87
					if(this.elements[i]) {
88
						Form.Element.setValue(this.elements[i], data[i]);
89
					}
90
				}
91
92
			// If we haven't selected an existing link, then just make sure we default to "internal" for the link
93
			// type.
94
			} else {
95
				if(!Form.Element.getValue(this.elements.LinkType)) Form.Element.setValue(this.elements.LinkType, 'internal');
96
			}
97
			this.linkTypeChanged(data ? false : true);
98
		}
99
	},
100
101
	handleaction_insert: function() {
102
		var href;
103
		var target = null;
104
105
		switch(Form.Element.getValue(this.elements.LinkType)) {
106
			case 'internal':
107
				href = '[sitetree_link id=' + this.elements.internal.value + ']';
108
				if(this.elements.Anchor.value) href += '#' + this.elements.Anchor.value;
109
				if($('Form_EditorToolbarLinkForm_TargetBlank')) {
110
					if($('Form_EditorToolbarLinkForm_TargetBlank').checked) target = '_blank';
111
				}
112
				break;
113
114
			case 'anchor':
115
				href = '#' + this.elements.Anchor.value;
116
				if($('Form_EditorToolbarLinkForm_TargetBlank')) {
117
					if($('Form_EditorToolbarLinkForm_TargetBlank').checked) target = '_blank';
118
				}
119
				break;
120
121
			case 'file':
122
				href = this.elements.file.value;
123
				target = '_blank';
124
				break;
125
126
			case 'externalcontent':
127
				href = this.elements.externalcontent.value;
128
				target = '_blank';
129
				break;
130
131
			case 'email':
132
				href = 'mailto:' + this.elements.email.value;
133
				break;
134
135
			case 'external':
136
			default:
137
				href = this.elements.external.value;
138
				if($('Form_EditorToolbarLinkForm_TargetBlank')) {
139
				    if($('Form_EditorToolbarLinkForm_TargetBlank').checked) target = '_blank';
140
				}
141
				break;
142
		}
143
144
		if(this.originalSelection) {
145
		    tinyMCE.activeEditor.selection.setRng(this.originalSelection);
146
		}
147
		/*
148
			 else {
149
				var mceInst = tinyMCE.activeEditor;
150
				var sel = mceInst.getSel();
151
				if(sel.addRange && sel.removeAllRanges) {
152
					sel.removeAllRanges();
153
					sel.addRange(this.originalSelection);
154
				}
155
				mceInst.selectedElement = mceInst.getFocusElement();
156
			}
157
		}
158
		*/
159
160
		var attributes = {
161
		    href : href,
162
		    target : target,
163
		    title : this.elements.Description.value,
164
		    innerHTML : this.elements.LinkText.value ? this.elements.LinkText.value : "Your Link"
165
		};
166
167
        // Remove the old link while preserving the selection
168
        if(tinyMCE.activeEditor.selection.getContent() != "") {
169
            var rng = tinyMCE.activeEditor.selection.getRng();
170
            tinyMCE.activeEditor.selection.setRng(rng);
171
            tinyMCE.activeEditor.execCommand('unlink');
172
            tinyMCE.activeEditor.selection.setRng(rng);
173
        }
174
175
        // Add the new link
176
		this.ssInsertLink(tinyMCE.activeEditor, attributes);
177
	},
178
179
	/**
180
	 * Insert a link into the given editor.
181
	 * Replaces mceInsertLink in that innerHTML can also be set
182
	 */
183
	ssInsertLink: function(ed, attributes) {
184
	    var v = attributes;
185
		var s = ed.selection, e = ed.dom.getParent(s.getNode(), 'A');
186
187
		if (tinymce.is(attributes, 'string'))
188
			attributes = {href : attributes};
189
190
		function set(e) {
191
			tinymce.each(attributes, function(v, k) {
192
			    if(k == 'innerHTML') e.innerHTML = v;
193
				else ed.dom.setAttrib(e, k, v);
194
			});
195
		};
196
197
	    if(attributes.innerHTML && !ed.selection.getContent()) {
198
            if(tinymce.isIE) var rng = ed.selection.getRng();
199
	        e = ed.getDoc().createElement('a');
200
	        e.innerHTML = attributes.innerHTML;
201
	        e.href = attributes.href;
202
	        s.setNode(e);
203
	        if(tinymce.isIE) tinyMCE.activeEditor.selection.setRng(rng);
204
        }
205
		if (!e) {
206
			ed.execCommand('CreateLink', false, 'javascript:mctmp(0);');
207
			tinymce.each(ed.dom.select('a'), function(e) {
208
				if (e.href == 'javascript:mctmp(0);') set(e);
209
			});
210
		} else {
211
			if (attributes.href)
212
				set(e);
213
			else
214
				ed.dom.remove(e, 1);
215
		}
216
217
		this.respondToNodeChange(ed);
218
	},
219
220
	handleaction_remove: function() {
221
		tinyMCE.activeEditor.execCommand('unlink', false);
222
	},
223
224
	/**
225
	 * Return information about the currently selected link, suitable for population of the link
226
	 * form.
227
	 */
228
	getCurrentLink: function(ed) {
229
	    if(ed == null) ed = tinyMCE.activeEditor;
230
231
		var selectedText = "";
232
	    selectedText = ed.selection.getContent({format : 'text'});
233
	    var selectedElement = ed.selection.getNode();
234
235
        /*
236
		if ((selectedElement.nodeName.toLowerCase() != "img") && (selectedText.length <= 0)) {
237
		    return {};
238
	    }
239
	    */
240
241
		var href = "", target = "", title = "", onclick = "", action = "insert", style_class = "";
242
243
		// We use a separate field for linkDataSource from tinyMCE.linkElement.
244
		// If we have selected beyond the range of an <a> element, then use use that <a> element to get the link data source,
245
		// but we don't use it as the destination for the link insertion
246
		var linkDataSource = null;
247
248
		if(selectedElement && (selectedElement.nodeName.toLowerCase() == "a")) {
249
			linkDataSource = selectedElement;
250
    		ed.selection.select(linkDataSource);
251
		} else if(selectedElement && (selectedElement.getElementsByTagName('a').length > 0)) {
252
		    if(selectedElement.getElementsByTagName('a')[0]) {
253
		    	linkDataSource = selectedElement.getElementsByTagName('a')[0];
254
		    }
255
		} else {
256
			var sel = selectedElement;
257
			if(sel) {
258
				while((sel = sel.parentNode) && sel.tagName && sel.tagName.toLowerCase() != 'body') {
259
					if(sel.tagName.toLowerCase() == 'a') {
260
						linkDataSource = selectedElement = sel;
261
	            	ed.selection.select(linkDataSource);
262
						break;
263
					}
264
				}
265
			}
266
		}
267
268
		// Is anchor not a link
269
		if (linkDataSource != null && tinymce.DOM.getAttrib(linkDataSource, 'href') == "")
270
			linkDataSource = null;
271
272
		if (linkDataSource) {
273
			href = tinymce.DOM.getAttrib(linkDataSource, 'href');
274
			target = tinymce.DOM.getAttrib(linkDataSource, 'target');
275
			title = tinymce.DOM.getAttrib(linkDataSource, 'title');
276
              onclick = tinymce.DOM.getAttrib(linkDataSource, 'onclick');
277
			style_class = tinymce.DOM.getAttrib(linkDataSource, 'class');
278
279
			// Try old onclick to if copy/pasted content
280
			if (onclick == "")
281
				onclick = tinymce.DOM.getAttrib(linkDataSource, 'onclick');
282
283
            /*
284
			onclick = tinyMCE.cleanupEventStr(onclick);
285
			*/
286
287
            /*
288
			// Fix for drag-drop/copy paste bug in Mozilla
289
			mceRealHref = tinymce.DOM.getAttrib(linkDataSource, 'mce_real_href');
290
			if (mceRealHref != "")
291
				href = mceRealHref;
292
			*/
293
294
			href = eval(tinyMCE.settings['urlconverter_callback'] + "(href, linkDataSource, true);");
295
			action = "update";
296
		}
297
298
		// Turn into relative
299
		if(href.match(new RegExp('^' + tinyMCE.settings['document_base_url'] + '(.*)$'))) {
300
			href = RegExp.$1;
301
		}
302
303
		var linkText = ed.selection.getContent({format : 'html'}).replace(/<\/?a[^>]*>/ig,'');
304
305
		if(href.match(/^mailto:(.*)$/)) {
306
			return {
307
				LinkType: 'email',
308
				email: RegExp.$1,
309
				LinkText: linkText,
310
				Description: title
311
			}
312
		} else if(href.match(/^(assets\/.*)$/)) {
313
			return {
314
				LinkType: 'file',
315
				file: RegExp.$1,
316
				LinkText: linkText,
317
				Description: title
318
			}
319
		} else if(href.match(/^#(.*)$/)) {
320
			return {
321
				LinkType: 'anchor',
322
				Anchor: RegExp.$1,
323
				LinkText: linkText,
324
				Description: title,
325
				TargetBlank: target ? true : false
326
			}
327
		} else if(href.match(/^\[sitetree_link id=([0-9]+)\]?(#.*)?$/)) {
328
			return {
329
				LinkType: 'internal',
330
				internal: RegExp.$1,
331
				Anchor: RegExp.$2 ? RegExp.$2.substr(1) : '',
332
				LinkText: linkText,
333
				Description: title,
334
				TargetBlank: target ? true : false
335
			}
336
		} else if(href) {
337
			return {
338
				LinkType: 'external',
339
				external: href,
340
				LinkText: linkText,
341
				Description: title,
342
				TargetBlank: target ? true : false
343
			}
344
		} else {
345
		    return {
346
				LinkType: 'internal',
347
		        LinkText: linkText
348
		    }
349
		}
350
	}
351
352
}
353
354
SideFormAction = Class.create();
355
SideFormAction.prototype = {
356
	initialize: function() {
357
		this.parentForm = this.parentNode;
358
		while(this.parentForm && this.parentForm.tagName.toLowerCase() != 'form') {
359
			this.parentForm = this.parentForm.parentNode;
360
		}
361
	},
362
	destroy: function() {
363
		this.parentForm = null;
364
		this.onclick = null;
365
366
	},
367
	onclick: function() {
368
		if(this.parentForm['handle' + this.name]) {
369
			try {
370
				this.parentForm['handle' + this.name]();
371
			} catch(er) {
372
				alert("An error occurred.  Please try again, or reload the CMS if the problem persists.\n\nError details: " + er.message);
373
			}
374
		} else {
375
			alert("Couldn't find form method handle" + this.name);
376
		}
377
		return false;
378
	}
379
}
380
381
ImageForm = Class.extend('ToolbarForm');
382
ImageForm.prototype = {
383
	initialize: function() {
384
		var __form = this;
385
386
		this.elements.AltText.onkeyup = function() {
387
			__form.update_params('AltText');
388
		};
389
		this.elements.ImageTitle.onkeyup = function() {
390
			__form.update_params('ImageTitle');
391
		};
392
		this.elements.ImageTitle.onkeyup = function() {
393
			__form.update_params('ImageTitle');
394
		};
395
		this.elements.Width.onchange = function() {
396
			__form.update_params('Width');
397
		};
398
		this.elements.Height.onchange = function() {
399
			__form.update_params('Height');
400
		};
401
	},
402
	destroy: function() {
403
		this.ToolbarForm = null;
404
		this.onsubmit = null;
405
406
		this.elements.AltText.onkeyup = null;
407
		this.elements.ImageTitle.onkeyup = null;
408
		this.elements.CSSClass.onkeyup = null;
409
		this.elements.CSSClass.onclick = null;
410
		this.elements.Width.onchange = null;
411
		this.elements.Height.onchange = null;
412
	},
413
	update_params: function(updatedFieldName) {
414
		if(tinyMCE.imgElement) {
415
			tinyMCE.imgElement.alt = this.elements.AltText.value;
416
			tinyMCE.imgElement.title = this.elements.ImageTitle.value;
417
			tinyMCE.imgElement.className = this.elements.CSSClass.value;
418
419
			// Proportionate updating of heights
420
			if(updatedFieldName == 'Width') {
421
				tinyMCE.imgElement.width = this.elements.Width.value;
422
				tinyMCE.imgElement.removeAttribute('height');
423
				this.elements.Height.value = tinyMCE.imgElement.height;
424
425
			} else if(updatedFieldName == 'Height') {
426
				tinyMCE.imgElement.height = this.elements.Height.value;
427
				tinyMCE.imgElement.removeAttribute('width');
428
				this.elements.Width.value = tinyMCE.imgElement.width;
429
			}
430
		}
431
	},
432
	respondToNodeChange: function() {
433
		if(tinyMCE.imgElement) {
434
			this.elements.AltText.value = tinyMCE.imgElement.alt;
435
			this.elements.ImageTitle.value = tinyMCE.imgElement.title;
436
			this.elements.CSSClass.value = tinyMCE.imgElement.className;
437
			this.elements.Width.value = tinyMCE.imgElement.style.width ? parseInt(tinyMCE.imgElement.style.width) : tinyMCE.imgElement.width;
438
			this.elements.Height.value = tinyMCE.imgElement.style.height ? parseInt(tinyMCE.imgElement.style.height) : tinyMCE.imgElement.height;
439
		} else {
440
			this.elements.AltText.value = '';
441
			this.elements.ImageTitle.value = '';
442
			this.elements.CSSClass.value = 'left';
443
		}
444
	},
445
446
	selectImage: function(image) {
447
		if(this.selectedImage) {
448
			this.selectedImage.setAttribute("class", "");
449
			this.selectedImage.className = "";
450
		}
451
		this.selectedImage = image;
452
		this.selectedImage.setAttribute("class", "selectedImage");
453
		this.selectedImage.className = "selectedImage";
454
455
		try {
456
			var imgTag = image.getElementsByTagName('img')[0];
457
			$('Form_EditorToolbarImageForm_Width').value = imgTag.className.match(/destwidth=([0-9.\-]+)([, ]|$)/) ? RegExp.$1 : null;
458
			$('Form_EditorToolbarImageForm_Height').value = imgTag.className.match(/destheight=([0-9.\-]+)([, ]|$)/) ? RegExp.$1 : null;
459
		} catch(er) {
460
		}
461
	},
462
463
	handleaction_insertimage: function() {
464
		if(this.selectedImage) {
465
			this.selectedImage.insert();
466
		}
467
	},
468
469
	handleaction_editimage: function() {
470
		if(this.selectedImage) {
471
			this.selectedImage.edit();
472
		}
473
	}
474
}
475
476
ImageThumbnail = Class.create();
477
ImageThumbnail.prototype = {
478
	destroy: function() {
479
		this.onclick = null;
480
	},
481
482
	onclick: function(e) {
483
		$('Form_EditorToolbarImageForm').selectImage(this);
484
		return false;
485
	},
486
487
	edit: function() {
488
		var windowWidth = Element.getDimensions(window.top.document.body).width;
489
       var windowHeight = Element.getDimensions(window.top.document.body).height;
490
		var iframe = window.top.document.getElementById('imageEditorIframe');
491
		if(iframe != null) {
492
			iframe.parentNode.removeChild(iframe);
493
		}
494
		iframe = window.top.document.createElement('iframe');
495
		var fileToEdit = this.href;
496
		iframe.setAttribute("src","admin/ImageEditor?fileToEdit=" + fileToEdit);
497
		iframe.id = 'imageEditorIframe';
498
		iframe.style.width = windowWidth - 6 + 'px';
499
		iframe.style.height = windowHeight + 10 + 'px';
500
		iframe.style.zIndex = "1000";
501
		iframe.style.position = "absolute";
502
		iframe.style.top = "8px";
503
		iframe.style.left = "8px";
504
		window.top.document.body.appendChild(iframe);
505
		var divLeft = window.top.document.createElement('div');
506
		var divRight = window.top.document.createElement('div');
507
        divLeft.style.width = "8px";
508
        divLeft.style.height = "300%";
509
        divLeft.style.zIndex = "1000";
510
        divLeft.style.top = "0";
511
        divLeft.style.position = "absolute";
512
        divRight.style.width = "10px";
513
        divRight.style.height = "300%";
514
        divRight.style.zIndex = "1000";
515
        divRight.style.top = "0";
516
        divRight.style.position = "absolute";
517
        divRight.style.left = Element.getDimensions(divLeft).width + Element.getDimensions(iframe).width - 4 + 'px';
518
		window.top.document.body.appendChild(divLeft);
519
		window.top.document.body.appendChild(divRight);
520
		return;
521
	},
522
523
	insert: function() {
524
		var formObj = $('Form_EditorToolbarImageForm');
525
		var altText = formObj.elements.AltText.value;
526
		var titleText = formObj.elements.ImageTitle.value;
527
		var cssClass = formObj.elements.CSSClass.value;
528
		var baseURL = document.getElementsByTagName('base')[0].href;
529
		var relativeHref = this.href.substr(baseURL.length);
530
		var captionText = formObj.elements.CaptionText.value;
531
532
		if(!tinyMCE.selectedInstance) tinyMCE.selectedInstance = tinyMCE.activeEditor;
533
		if(tinyMCE.selectedInstance.contentWindow.focus) tinyMCE.selectedInstance.contentWindow.focus();
534
535
		this.ssInsertImage(tinyMCE.activeEditor, {
536
			'src' : relativeHref,
537
			'alt' : altText,
538
			'width' : $('Form_EditorToolbarImageForm_Width').value,
539
			'height' : $('Form_EditorToolbarImageForm_Height').value,
540
			'title' : titleText,
541
			'class' : cssClass
542
		}, captionText);
543
544
		return false;
545
	},
546
547
	/**
548
	 * Insert an image with the given attributes
549
	 */
550
	 ssInsertImage: function(ed, attributes, captionText) {
551
		el = ed.selection.getNode();
552
		var html;
553
554
		if(captionText) {
555
			html = '<div style="width: ' + attributes.width + 'px;" class="captionImage ' + attributes['class'] + '">';
556
			html += '<img id="__mce_tmp" />';
557
			html += '<p class="caption">' + captionText + '</p>';
558
			html += '</div>';
559
		} else {
560
			html = '<img id="__mce_tmp" />';
561
		}
562
563
		if(el && el.nodeName == 'IMG') {
564
			ed.dom.setAttribs(el, attributes);
565
		} else {
566
			ed.execCommand('mceInsertContent', false, html, {
567
				skip_undo : 1
568
			});
569
570
			ed.dom.setAttribs('__mce_tmp', attributes);
571
			ed.dom.setAttrib('__mce_tmp', 'id', '');
572
			ed.undoManager.add();
573
		}
574
	}
575
576
}
577
578
var selectedimage = false;
579
580
function reselectImage(transport) {
581
		if(selectedimage) {
582
			links = $('Image').getElementsByTagName('a');
583
			for(i =0; link = links[i]; i++) {
584
				var quesmark = link.href.lastIndexOf('?');
585
				image = link.href.substring(0, quesmark);
586
				if(image == selectedimage) {
587
					link.className = 'selectedImage';
588
					$('Form_EditorToolbarImageForm').selectedImage = link;
589
					break;
590
				}
591
			}
592
		}
593
594
		$('Image').reapplyBehaviour();
595
      this.addToTinyMCE = this.addToTinyMCE.bind(this);
596
      var childNodes = $('Image').childNodes[0].childNodes;
597
      var newImages = $A(childNodes).slice(childNodes.length - this.filesUploaded);
598
      newImages.each(function(item) {
599
          tinyMCEImageEnhancement.addToTinyMCE(item.childNodes[0]);
600
      });
601
      tinyMCEImageEnhancement.processInProgress = false;
602
}
603
604
function imageEditorClosed() {
605
	if(self.refreshAsset) {
606
		refreshAsset();
607
	}
608
	if($('Form_EditorToolbarImageForm')) {
609
		if($('Form_EditorToolbarImageForm').style.display != "none") {
610
			// FInd the selected image
611
			links = $('Image').getElementsByTagName('a');
612
			for(i =0; link = links[i]; i++) {
613
				if(link.className == 'selectedImage') {
614
					var quesmark = link.href.lastIndexOf('?');
615
					selectedimage = link.href.substring(0, quesmark);
616
					break;
617
				}
618
			}
619
620
			// Trick the folder dropdown into registering a change, so the image thumbnails are reloaded
621
			folderID = $('Form_EditorToolbarImageForm_FolderID').value;
622
			$('Image').ajaxGetFiles(folderID, null, reselectImage);
623
		}
624
	}
625
}
626
627
FlashForm = Class.extend('ToolbarForm');
628
FlashForm.prototype = {
629
	initialize: function() {
630
	},
631
	destroy: function() {
632
		this.ToolbarForm = null;
633
		this.onsubmit = null;
634
635
	},
636
	update_params: function(event) {
637
		if(tinyMCE.imgElement) {
638
		}
639
	},
640
	respondToNodeChange: function() {
641
		if(tinyMCE.imgElement) {
642
		} else {
643
		}
644
	},
645
	selectFlash: function(flash) {
646
		if(this.selectedFlash) {
647
			this.selectedFlash.setAttribute("class", "");
648
		}
649
		this.selectedFlash = flash;
650
		this.selectedFlash.setAttribute("class", "selectedFlash");
651
	},
652
	handleaction_insertflash: function() {
653
		if(this.selectedFlash) {
654
			this.selectedFlash.insert();
655
		}
656
	}
657
}
658
659
FlashThumbnail = Class.create();
660
FlashThumbnail.prototype = {
661
	destroy: function() {
662
		this.onclick = null;
663
	},
664
665
	onclick: function(e) {
666
		$('Form_EditorToolbarFlashForm').selectFlash(this);
667
		return false;
668
	},
669
670
	insert: function() {
671
		var formObj = $('Form_EditorToolbarFlashForm');
672
		var html = '';
673
		var baseURL = document.getElementsByTagName('base')[0].href;
674
		var relativeHref = this.href.substr(baseURL.length)
675
		var width = formObj.elements.Width.value;
676
		var height = formObj.elements.Height.value;
677
678
		if(!tinyMCE.selectedInstance) tinyMCE.selectedInstance = tinyMCE.activeEditor;
679
		if(tinyMCE.selectedInstance.contentWindow.focus) tinyMCE.selectedInstance.contentWindow.focus();
680
681
		if (width == "") width = 100;
682
		if (height == "") height = 100;
683
684
		html = '';
685
		html += '<object width="' + width +'" height="' + height +'" type="application/x-shockwave-flash" data="'+ relativeHref +'">';
686
		html += '<param value="'+ relativeHref +'" name="movie">';
687
		html += '</object>';
688
689
		tinyMCE.selectedInstance.execCommand("mceInsertContent", false, html);
690
		tinyMCE.selectedInstance.execCommand('mceRepaint');
691
	//	ed.execCommand('mceInsertContent', false, html, {skip_undo : 1});
692
		return false;
693
	}
694
}
695
696
LinkForm.applyTo('#Form_EditorToolbarLinkForm');
697
SideFormAction.applyTo('#Form_EditorToolbarLinkForm .Actions input');
698
699
ImageForm.applyTo('#Form_EditorToolbarImageForm');
700
ImageThumbnail.applyTo('#Form_EditorToolbarImageForm div.thumbnailstrip a');
701
SideFormAction.applyTo('#Form_EditorToolbarImageForm .Actions input');
702
703
FlashForm.applyTo('#Form_EditorToolbarFlashForm');
704
FlashThumbnail.applyTo('#Form_EditorToolbarFlashForm div.thumbnailstrip a');
705
SideFormAction.applyTo('#Form_EditorToolbarFlashForm .Actions input');
706
707
/**
708
 * Image resizing
709
 */
710
MCEImageResizer = Class.create();
711
MCEImageResizer.prototype = {
712
	initialize: function() {
713
		//TinyMCE.prototype.addEvent(this, 'click', this._onclick);
714
	},
715
	_onclick: function() {
716
		var form = $('Form_EditorToolbarImageForm');
717
		if(form) {
718
			form.elements.AltText.value = this.alt;
719
			form.elements.ImageTitle.value = this.title;
720
			form.elements.CSSClass.value = this.className;
721
		}
722
	},
723
	onresizestart: function() {
724
		this.prepareForResize();
725
		this.heightDiff = 0;
726
	},
727
	onresizeend: function() {
728
		this.resizeTo(this.style.width, this.style.height);
729
	},
730
	onmouseup: function() {
731
		if(this.parentNode.parentNode.className.match(/(^|\b)specialImage($|\b)/)) {
732
			this.ownerDoc().setActive();
733
			this.parentNode.parentNode.setActive();
734
		}
735
	},
736
	prepareForResize: function() {
737
		if(this.aspectRatio == null) {
738
			this.aspectRatio = this.height / this.width;
739
		}
740
741
		this.originalWidth = this.width;
742
		this.originalHeight = this.height;
743
	},
744
745
	ownerDoc: function() {
746
		var f =this.parentNode;
747
		while(f && f.tagName.toLowerCase() != 'body') f = f.parentNode;
748
		return f;
749
	},
750
751
	resizeTo: function(width, height) {
752
		var newWidth = parseInt(height);
753
		var newHeight = parseInt(height) - this.heightDiff;
754
		if(isNaN(newWidth)) newWidth = this.width;
755
		if(isNaN(newHeight)) newHeight = this.height;
756
757
		// Constrain to width of the window
758
		if((this.offsetLeft + this.offsetWidth + 20) > this.ownerDoc().offsetWidth)
759
			newWidth += (this.ownerDoc().offsetWidth - this.offsetLeft - this.offsetWidth - 20);
760
761
		if(this.aspectRatio) {
762
			// Figure out which dimension we have altered more
763
			var heightChange = this.originalHeight / this.height;
764
			if(heightChange < 1) heightChange = 1/heightChange;
765
766
			var widthChange = this.originalWidth / this.width;
767
			if(widthChange < 1) widthChange = 1/widthChange;
768
769
			// Scale by the more constant dimension (so if you edit the height, change width to suit)
770
			if(widthChange > heightChange)
771
				newHeight = newWidth * this.aspectRatio;
772
			else
773
				newWidth = newHeight / this.aspectRatio;
774
		}
775
776
		this.style.width = newWidth + 'px';
777
		this.style.height = newHeight + 'px';
778
		this.width = newWidth;
779
		this.height = newHeight;
780
781
		// Auto-size special image holders
782
		if(this.parentNode.parentNode.className.match(/(^|\b)specialImage($|\b)/)) {
783
			this.parentNode.parentNode.style.width = newWidth + 'px';
784
		}
785
	}
786
}
787
788
MCEDLResizer = Class.extend('MCEImageResize');
789
MCEDLResizer.prototype = {
790
	onresizestart: function() {
791
		var img = this.getElementsByTagName('img')[0];
792
		img.prepareForResize();
793
		img.heightDiff = this.offsetHeight - img.height;
794
	},
795
	onresizeend: function() {
796
		this.getElementsByTagName('img')[0].resizeTo(this.style.width, this.style.height);
797
	}
798
}
799
800
/**
801
 * These callback hook it into tinymce.  They need to be referenced in the TinyMCE config.
802
 */
803
function sapphiremce_setupcontent(editor_id, body, doc) {
804
	var allImages = body.getElementsByTagName('img');
805
	var i,img;
806
	for(i=0;img=allImages[i];i++) {
807
		behaveAs(img, MCEImageResizer);
808
	}
809
810
	var allDLs = body.getElementsByTagName('img');
811
	for(i=0;img=allDLs[i];i++) {
812
		if(img.className.match(/(^|\b)specialImage($|\b)/)) {
813
			behaveAs(img, MCEDLResizer);
814
		}
815
	}
816
}
817
818
function sapphiremce_cleanup(type, value) {
819
	if(type == 'get_from_editor') {
820
		// replace indented text with a <blockquote>
821
		value = value.replace(/<p [^>]*margin-left[^>]*>([^\n|\n\015|\015\n]*)<\/p>/ig,"<blockquote><p>$1</p></blockquote>");
822
823
		// replace VML pixel image references with image tags - experimental
824
		value = value.replace(/<[a-z0-9]+:imagedata[^>]+src="?([^> "]+)"?[^>]*>/ig,"<img src=\"$1\">");
825
826
		// Word comments
827
		value = value.replace(new RegExp('<(!--)([^>]*)(--)>', 'g'), "");
828
829
		// kill class=mso??? and on mouse* tags
830
		value = value.replace(/([ \f\r\t\n\'\"])class=mso[a-z0-9]+[^ >]+/ig, "$1");
831
		value = value.replace(/([ \f\r\t\n\'\"]class=")mso[a-z0-9]+[^ ">]+ /ig, "$1");
832
		value = value.replace(/([ \f\r\t\n\'\"])class="mso[a-z0-9]+[^">]+"/ig, "$1");
833
		value = value.replace(/([ \f\r\t\n\'\"])on[a-z]+=[^ >]+/ig, "$1");
834
		value = value.replace(/ >/ig, ">");
835
836
		// remove everything that's in a closing tag
837
		value = value.replace(/<(\/[A-Za-z0-9]+)[ \f\r\t\n]+[^>]*>/ig,"<$1>");
838
	}
839
840
	if(type == 'get_from_editor_dom') {
841
		var allImages =value.getElementsByTagName('img');
842
		var i,img;
843
844
		for(i=0;img=allImages[i];i++) {
845
			img.onresizestart = null;
846
			img.onresizeend = null;
847
			img.removeAttribute('onresizestart');
848
			img.removeAttribute('onresizeend');
849
		}
850
851
		var allDLs =value.getElementsByTagName('img');
852
		for(i=0;img=allDLs[i];i++) {
853
			if(img.className.match(/(^|\b)specialImage($|\b)/)) {
854
				img.onresizestart = null;
855
				img.onresizeend = null;
856
				img.removeAttribute('onresizestart');
857
				img.removeAttribute('onresizeend');
858
			}
859
		}
860
861
	}
862
	return value;
863
}
864
865
contentPanelCloseButton = Class.create();
866
contentPanelCloseButton.prototype = {
867
	onclick: function() {
868
	    tinyMCE.activeEditor.execCommand('ssclosesidepanel');
869
	}
870
}
871
872
contentPanelCloseButton.applyTo('#contentPanel h2 img');
873