code:
/**
 * editor_plugin_src.js
 *
 * Copyright 2009, Moxiecode Systems AB
 * Released under LGPL License.
 *
 * License: http://tinymce.moxiecode.com/license
 * Contributing: http://tinymce.moxiecode.com/contributing
 */

(function() {
	var DOM = tinymce.DOM, Element = tinymce.dom.Element, Event = tinymce.dom.Event, each = tinymce.each, is = tinymce.is;

	tinymce.create('tinymce.plugins.InlinePopups', {
		init : function(ed, url) {
			// Replace window manager
			ed.onBeforeRenderUI.add(function() {
				ed.windowManager = new tinymce.InlineWindowManager(ed);
				DOM.loadCSS(url + '/skins/' + (ed.settings.inlinepopups_skin || 'clearlooks2') + "/window.css");
			});
		},

		getInfo : function() {
			return {
				longname : 'InlinePopups',
				author : 'Moxiecode Systems AB',
				authorurl : 'http://tinymce.moxiecode.com',
				infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/inlinepopups',
				version : tinymce.majorVersion + "." + tinymce.minorVersion
			};
		}
	});

	tinymce.create('tinymce.InlineWindowManager:tinymce.WindowManager', {
		InlineWindowManager : function(ed) {
			var t = this;

			t.parent(ed);
			t.zIndex = 300000;
			t.count = 0;
			t.windows = {};
		},

		open : function(f, p) {
			var t = this, id, opt = '', ed = t.editor, dw = 0, dh = 0, vp, po, mdf, clf, we, w, u, parentWindow;

			f = f || {};
			p = p || {};

			// Run native windows
			if (!f.inline)
				return t.parent(f, p);

			parentWindow = t._frontWindow();
			if (parentWindow && DOM.get(parentWindow.id + '_ifr')) {
				parentWindow.focussedElement = DOM.get(parentWindow.id + '_ifr').contentWindow.document.activeElement;
			}

			// Only store selection if the type is a normal window
			if (!f.type)
				t.bookmark = ed.selection.getBookmark(1);

			id = DOM.uniqueId();
			vp = DOM.getViewPort();
			f.width = parseInt(f.width || 320);
			f.height = parseInt(f.height || 240) + (tinymce.isIE ? 8 : 0);
			f.min_width = parseInt(f.min_width || 150);
			f.min_height = parseInt(f.min_height || 100);
			f.max_width = parseInt(f.max_width || 2000);
			f.max_height = parseInt(f.max_height || 2000);
			f.left = f.left || Math.round(Math.max(vp.x, vp.x + (vp.w / 2.0) - (f.width / 2.0)));
			f.top = f.top || Math.round(Math.max(vp.y, vp.y + (vp.h / 2.0) - (f.height / 2.0)));
			f.movable = f.resizable = true;
			p.mce_width = f.width;
			p.mce_height = f.height;
			p.mce_inline = true;
			p.mce_window_id = id;
			p.mce_auto_focus = f.auto_focus;

			// Transpose
//			po = DOM.getPos(ed.getContainer());
//			f.left -= po.x;
//			f.top -= po.y;

			t.features = f;
			t.params = p;
			t.onOpen.dispatch(t, f, p);

			if (f.type) {
				opt += ' mceModal';

				if (f.type)
					opt += ' mce' + f.type.substring(0, 1).toUpperCase() + f.type.substring(1);

				f.resizable = false;
			}

			if (f.statusbar)
				opt += ' mceStatusbar';

			if (f.resizable)
				opt += ' mceResizable';

			if (f.minimizable)
				opt += ' mceMinimizable';

			if (f.maximizable)
				opt += ' mceMaximizable';

			if (f.movable)
				opt += ' mceMovable';

			// Create DOM objects
			t._addAll(DOM.doc.body,
				['div', {id : id, role : 'dialog', 'aria-labelledby': f.type ? id + '_content' : id + '_title', 'class' : (ed.settings.inlinepopups_skin || 'clearlooks2') + (tinymce.isIE && window.getSelection ? ' ie9' : ''), style : 'width:100px;height:100px'},
					['div', {id : id + '_wrapper', 'class' : 'mceWrapper' + opt},
						['div', {id : id + '_top', 'class' : 'mceTop'},
							['div', {'class' : 'mceLeft'}],
							['div', {'class' : 'mceCenter'}],
							['div', {'class' : 'mceRight'}],
							['span', {id : id + '_title'}, f.title || '']
						],

						['div', {id : id + '_middle', 'class' : 'mceMiddle'},
							['div', {id : id + '_left', 'class' : 'mceLeft', tabindex : '0'}],
							['span', {id : id + '_content'}],
							['div', {id : id + '_right', 'class' : 'mceRight', tabindex : '0'}]
						],

						['div', {id : id + '_bottom', 'class' : 'mceBottom'},
							['div', {'class' : 'mceLeft'}],
							['div', {'class' : 'mceCenter'}],
							['div', {'class' : 'mceRight'}],
							['span', {id : id + '_status'}, 'Content']
						],

						['a', {'class' : 'mceMove', tabindex : '-1', href : 'javascript:;'}],
						['a', {'class' : 'mceMin', tabindex : '-1', href : 'javascript:;', onmousedown : 'return false;'}],
						['a', {'class' : 'mceMax', tabindex : '-1', href : 'javascript:;', onmousedown : 'return false;'}],
						['a', {'class' : 'mceMed', tabindex : '-1', href : 'javascript:;', onmousedown : 'return false;'}],
						['a', {'class' : 'mceClose', tabindex : '-1', href : 'javascript:;', onmousedown : 'return false;'}],
						['a', {id : id + '_resize_n', 'class' : 'mceResize mceResizeN', tabindex : '-1', href : 'javascript:;'}],
						['a', {id : id + '_resize_s', 'class' : 'mceResize mceResizeS', tabindex : '-1', href : 'javascript:;'}],
						['a', {id : id + '_resize_w', 'class' : 'mceResize mceResizeW', tabindex : '-1', href : 'javascript:;'}],
						['a', {id : id + '_resize_e', 'class' : 'mceResize mceResizeE', tabindex : '-1', href : 'javascript:;'}],
						['a', {id : id + '_resize_nw', 'class' : 'mceResize mceResizeNW', tabindex : '-1', href : 'javascript:;'}],
						['a', {id : id + '_resize_ne', 'class' : 'mceResize mceResizeNE', tabindex : '-1', href : 'javascript:;'}],
						['a', {id : id + '_resize_sw', 'class' : 'mceResize mceResizeSW', tabindex : '-1', href : 'javascript:;'}],
						['a', {id : id + '_resize_se', 'class' : 'mceResize mceResizeSE', tabindex : '-1', href : 'javascript:;'}]
					]
				]
			);

			DOM.setStyles(id, {top : -10000, left : -10000});

			// Fix gecko rendering bug, where the editors iframe messed with window contents
			if (tinymce.isGecko)
				DOM.setStyle(id, 'overflow', 'auto');

			// Measure borders
			if (!f.type) {
				dw += DOM.get(id + '_left').clientWidth;
				dw += DOM.get(id + '_right').clientWidth;
				dh += DOM.get(id + '_top').clientHeight;
				dh += DOM.get(id + '_bottom').clientHeight;
			}

			// Resize window
			DOM.setStyles(id, {top : f.top, left : f.left, width : f.width + dw, height : f.height + dh});

			u = f.url || f.file;
			if (u) {
				if (tinymce.relaxedDomain)
					u += (u.indexOf('?') == -1 ? '?' : '&') + 'mce_rdomain=' + tinymce.relaxedDomain;

				u = tinymce._addVer(u);
			}

			if (!f.type) {
				DOM.add(id + '_content', 'iframe', {id : id + '_ifr', src : 'javascript:""', frameBorder : 0, style : 'border:0;width:10px;height:10px'});
				DOM.setStyles(id + '_ifr', {width : f.width, height : f.height});
				DOM.setAttrib(id + '_ifr', 'src', u);
			} else {
				DOM.add(id + '_wrapper', 'a', {id : id + '_ok', 'class' : 'mceButton mceOk', href : 'javascript:;', onmousedown : 'return false;'}, 'Ok');

				if (f.type == 'confirm')
					DOM.add(id + '_wrapper', 'a', {'class' : 'mceButton mceCancel', href : 'javascript:;', onmousedown : 'return false;'}, 'Cancel');

				DOM.add(id + '_middle', 'div', {'class' : 'mceIcon'});
				DOM.setHTML(id + '_content', f.content.replace('\n', '<br />'));

				Event.add(id, 'keyup', function(evt) {
					var VK_ESCAPE = 27;
					if (evt.keyCode === VK_ESCAPE) {
						f.button_func(false);
						return Event.cancel(evt);
					}
				});

				Event.add(id, 'keydown', function(evt) {
					var cancelButton, VK_TAB = 9;
					if (evt.keyCode === VK_TAB) {
						cancelButton = DOM.select('a.mceCancel', id + '_wrapper')[0];
						if (cancelButton && cancelButton !== evt.target) {
							cancelButton.focus();
						} else {
							DOM.get(id + '_ok').focus();
						}
						return Event.cancel(evt);
					}
				});
			}

			// Register events
			mdf = Event.add(id, 'mousedown', function(e) {
				var n = e.target, w, vp;

				w = t.windows[id];
				t.focus(id);

				if (n.nodeName == 'A' || n.nodeName == 'a') {
					if (n.className == 'mceMax') {
						w.oldPos = w.element.getXY();
						w.oldSize = w.element.getSize();

						vp = DOM.getViewPort();

						// Reduce viewport size to avoid scrollbars
						vp.w -= 2;
						vp.h -= 2;

						w.element.moveTo(vp.x, vp.y);
						w.element.resizeTo(vp.w, vp.h);
						DOM.setStyles(id + '_ifr', {width : vp.w - w.deltaWidth, height : vp.h - w.deltaHeight});
						DOM.addClass(id + '_wrapper', 'mceMaximized');
					} else if (n.className == 'mceMed') {
						// Reset to old size
						w.element.moveTo(w.oldPos.x, w.oldPos.y);
						w.element.resizeTo(w.oldSize.w, w.oldSize.h);
						w.iframeElement.resizeTo(w.oldSize.w - w.deltaWidth, w.oldSize.h - w.deltaHeight);

						DOM.removeClass(id + '_wrapper', 'mceMaximized');
					} else if (n.className == 'mceMove')
						return t._startDrag(id, e, n.className);
					else if (DOM.hasClass(n, 'mceResize'))
						return t._startDrag(id, e, n.className.substring(13));
				}
			});

			clf = Event.add(id, 'click', function(e) {
				var n = e.target;

				t.focus(id);

				if (n.nodeName == 'A' || n.nodeName == 'a') {
					switch (n.className) {
						case 'mceClose':
							t.close(null, id);
							return Event.cancel(e);

						case 'mceButton mceOk':
						case 'mceButton mceCancel':
							f.button_func(n.className == 'mceButton mceOk');
							return Event.cancel(e);
					}
				}
			});

			// Make sure the tab order loops within the dialog.
			Event.add([id + '_left', id + '_right'], 'focus', function(evt) {
				var iframe = DOM.get(id + '_ifr');
				if (iframe) {
					var body = iframe.contentWindow.document.body;
					var focusable = DOM.select(':input:enabled,*[tabindex=0]', body);
					if (evt.target.id === (id + '_left')) {
						focusable[focusable.length - 1].focus();
					} else {
						focusable[0].focus();
					}
				} else {
					DOM.get(id + '_ok').focus();
				}
			});

			// Add window
			w = t.windows[id] = {
				id : id,
				mousedown_func : mdf,
				click_func : clf,
				element : new Element(id, {blocker : 1, container : ed.getContainer()}),
				iframeElement : new Element(id + '_ifr'),
				features : f,
				deltaWidth : dw,
				deltaHeight : dh
			};

			w.iframeElement.on('focus', function() {
				t.focus(id);
			});

			// Setup blocker
			if (t.count == 0 && t.editor.getParam('dialog_type', 'modal') == 'modal') {
				DOM.add(DOM.doc.body, 'div', {
					id : 'mceModalBlocker',
					'class' : (t.editor.settings.inlinepopups_skin || 'clearlooks2') + '_modalBlocker',
					style : {zIndex : t.zIndex - 1}
				});

				DOM.show('mceModalBlocker'); // Reduces flicker in IE
				DOM.setAttrib(DOM.doc.body, 'aria-hidden', 'true');
			} else
				DOM.setStyle('mceModalBlocker', 'z-index', t.zIndex - 1);

			if (tinymce.isIE6 || /Firefox\/2\./.test(navigator.userAgent) || (tinymce.isIE && !DOM.boxModel))
				DOM.setStyles('mceModalBlocker', {position : 'absolute', left : vp.x, top : vp.y, width : vp.w - 2, height : vp.h - 2});

			DOM.setAttrib(id, 'aria-hidden', 'false');
			t.focus(id);
			t._fixIELayout(id, 1);

			// Focus ok button
			if (DOM.get(id + '_ok'))
				DOM.get(id + '_ok').focus();
			t.count++;

			return w;
		},

		focus : function(id) {
			var t = this, w;

			if (w = t.windows[id]) {
				w.zIndex = this.zIndex++;
				w.element.setStyle('zIndex', w.zIndex);
				w.element.update();

				id = id + '_wrapper';
				DOM.removeClass(t.lastId, 'mceFocus');
				DOM.addClass(id, 'mceFocus');
				t.lastId = id;

				if (w.focussedElement) {
					w.focussedElement.focus();
				} else if (DOM.get(id + '_ok')) {
					DOM.get(w.id + '_ok').focus();
				} else if (DOM.get(w.id + '_ifr')) {
					DOM.get(w.id + '_ifr').focus();
				}
			}
		},

		_addAll : function(te, ne) {
			var i, n, t = this, dom = tinymce.DOM;

			if (is(ne, 'string'))
				te.appendChild(dom.doc.createTextNode(ne));
			else if (ne.length) {
				te = te.appendChild(dom.create(ne[0], ne[1]));

				for (i=2; i<ne.length; i++)
					t._addAll(te, ne[i]);
			}
		},

		_startDrag : function(id, se, ac) {
			var t = this, mu, mm, d = DOM.doc, eb, w = t.windows[id], we = w.element, sp = we.getXY(), p, sz, ph, cp, vp, sx, sy, sex, sey, dx, dy, dw, dh;

			// Get positons and sizes
//			cp = DOM.getPos(t.editor.getContainer());
			cp = {x : 0, y : 0};
			vp = DOM.getViewPort();

			// Reduce viewport size to avoid scrollbars while dragging
			vp.w -= 2;
			vp.h -= 2;

			sex = se.screenX;
			sey = se.screenY;
			dx = dy = dw = dh = 0;

			// Handle mouse up
			mu = Event.add(d, 'mouseup', function(e) {
				Event.remove(d, 'mouseup', mu);
				Event.remove(d, 'mousemove', mm);

				if (eb)
					eb.remove();

				we.moveBy(dx, dy);
				we.resizeBy(dw, dh);
				sz = we.getSize();
				DOM.setStyles(id + '_ifr', {width : sz.w - w.deltaWidth, height : sz.h - w.deltaHeight});
				t._fixIELayout(id, 1);

				return Event.cancel(e);
			});

			if (ac != 'Move')
				startMove();

			function startMove() {
				if (eb)
					return;

				t._fixIELayout(id, 0);

				// Setup event blocker
				DOM.add(d.body, 'div', {
					id : 'mceEventBlocker',
					'class' : 'mceEventBlocker ' + (t.editor.settings.inlinepopups_skin || 'clearlooks2'),
					style : {zIndex : t.zIndex + 1}
				});

				if (tinymce.isIE6 || (tinymce.isIE && !DOM.boxModel))
					DOM.setStyles('mceEventBlocker', {position : 'absolute', left : vp.x, top : vp.y, width : vp.w - 2, height : vp.h - 2});

				eb = new Element('mceEventBlocker');
				eb.update();

				// Setup placeholder
				p = we.getXY();
				sz = we.getSize();
				sx = cp.x + p.x - vp.x;
				sy = cp.y + p.y - vp.y;
				DOM.add(eb.get(), 'div', {id : 'mcePlaceHolder', 'class' : 'mcePlaceHolder', style : {left : sx, top : sy, width : sz.w, height : sz.h}});
				ph = new Element('mcePlaceHolder');
			};

			// Handle mouse move/drag
			mm = Event.add(d, 'mousemove', function(e) {
				var x, y, v;

				startMove();

				x = e.screenX - sex;
				y = e.screenY - sey;

				switch (ac) {
					case 'ResizeW':
						dx = x;
						dw = 0 - x;
						break;

					case 'ResizeE':
						dw = x;
						break;

					case 'ResizeN':
					case 'ResizeNW':
					case 'ResizeNE':
						if (ac == "ResizeNW") {
							dx = x;
							dw = 0 - x;
						} else if (ac == "ResizeNE")
							dw = x;

						dy = y;
						dh = 0 - y;
						break;

					case 'ResizeS':
					case 'ResizeSW':
					case 'ResizeSE':
						if (ac == "ResizeSW") {
							dx = x;
							dw = 0 - x;
						} else if (ac == "ResizeSE")
							dw = x;

						dh = y;
						break;

					case 'mceMove':
						dx = x;
						dy = y;
						break;
				}

				// Boundary check
				if (dw < (v = w.features.min_width - sz.w)) {
					if (dx !== 0)
						dx += dw - v;

					dw = v;
				}

				if (dh < (v = w.features.min_height - sz.h)) {
					if (dy !== 0)
						dy += dh - v;

					dh = v;
				}

				dw = Math.min(dw, w.features.max_width - sz.w);
				dh = Math.min(dh, w.features.max_height - sz.h);
				dx = Math.max(dx, vp.x - (sx + vp.x));
				dy = Math.max(dy, vp.y - (sy + vp.y));
				dx = Math.min(dx, (vp.w + vp.x) - (sx + sz.w + vp.x));
				dy = Math.min(dy, (vp.h + vp.y) - (sy + sz.h + vp.y));

				// Move if needed
				if (dx + dy !== 0) {
					if (sx + dx < 0)
						dx = 0;

					if (sy + dy < 0)
						dy = 0;

					ph.moveTo(sx + dx, sy + dy);
				}

				// Resize if needed
				if (dw + dh !== 0)
					ph.resizeTo(sz.w + dw, sz.h + dh);

				return Event.cancel(e);
			});

			return Event.cancel(se);
		},

		resizeBy : function(dw, dh, id) {
			var w = this.windows[id];

			if (w) {
				w.element.resizeBy(dw, dh);
				w.iframeElement.resizeBy(dw, dh);
			}
		},

		close : function(win, id) {
			var t = this, w, d = DOM.doc, fw, id;

			id = t._findId(id || win);

			// Probably not inline
			if (!t.windows[id]) {
				t.parent(win);
				return;
			}

			t.count--;

			if (t.count == 0) {
				DOM.remove('mceModalBlocker');
				DOM.setAttrib(DOM.doc.body, 'aria-hidden', 'false');
				t.editor.focus();
			}

			if (w = t.windows[id]) {
				t.onClose.dispatch(t);
				Event.remove(d, 'mousedown', w.mousedownFunc);
				Event.remove(d, 'click', w.clickFunc);
				Event.clear(id);
				Event.clear(id + '_ifr');

				DOM.setAttrib(id + '_ifr', 'src', 'javascript:""'); // Prevent leak
				w.element.remove();
				delete t.windows[id];

				fw = t._frontWindow();

				if (fw)
					t.focus(fw.id);
			}
		},

		// Find front most window
		_frontWindow : function() {
			var fw, ix = 0;
			// Find front most window and focus that
			each (this.windows, function(w) {
				if (w.zIndex > ix) {
					fw = w;
					ix = w.zIndex;
				}
			});
			return fw;
		},

		setTitle : function(w, ti) {
			var e;

			w = this._findId(w);

			if (e = DOM.get(w + '_title'))
				e.innerHTML = DOM.encode(ti);
		},

		alert : function(txt, cb, s) {
			var t = this, w;

			w = t.open({
				title : t,
				type : 'alert',
				button_func : function(s) {
					if (cb)
						cb.call(s || t, s);

					t.close(null, w.id);
				},
				content : DOM.encode(t.editor.getLang(txt, txt)),
				inline : 1,
				width : 400,
				height : 130
			});
		},

		confirm : function(txt, cb, s) {
			var t = this, w;

			w = t.open({
				title : t,
				type : 'confirm',
				button_func : function(s) {
					if (cb)
						cb.call(s || t, s);

					t.close(null, w.id);
				},
				content : DOM.encode(t.editor.getLang(txt, txt)),
				inline : 1,
				width : 400,
				height : 130
			});
		},

		// Internal functions

		_findId : function(w) {
			var t = this;

			if (typeof(w) == 'string')
				return w;

			each(t.windows, function(wo) {
				var ifr = DOM.get(wo.id + '_ifr');

				if (ifr && w == ifr.contentWindow) {
					w = wo.id;
					return false;
				}
			});

			return w;
		},

		_fixIELayout : function(id, s) {
			var w, img;

			if (!tinymce.isIE6)
				return;

			// Fixes the bug where hover flickers and does odd things in IE6
			each(['n','s','w','e','nw','ne','sw','se'], function(v) {
				var e = DOM.get(id + '_resize_' + v);

				DOM.setStyles(e, {
					width : s ? e.clientWidth : '',
					height : s ? e.clientHeight : '',
					cursor : DOM.getStyle(e, 'cursor', 1)
				});

				DOM.setStyle(id + "_bottom", 'bottom', '-1px');

				e = 0;
			});

			// Fixes graphics glitch
			if (w = this.windows[id]) {
				// Fixes rendering bug after resize
				w.element.hide();
				w.element.show();

				// Forced a repaint of the window
				//DOM.get(id).style.filter = '';

				// IE has a bug where images used in CSS won't get loaded
				// sometimes when the cache in the browser is disabled
				// This fix tries to solve it by loading the images using the image object
				each(DOM.select('div,a', id), function(e, i) {
					if (e.currentStyle.backgroundImage != 'none') {
						img = new Image();
						img.src = e.currentStyle.backgroundImage.replace(/url\(\"(.+)\"\)/, '$1');
					}
				});

				DOM.get(id).style.filter = '';
			}
		}
	});

	// Register plugin
	tinymce.PluginManager.add('inlinepopups', tinymce.plugins.InlinePopups);
})();


code:
/* Clearlooks 2 */

/* Reset */
.clearlooks2, .clearlooks2 div, .clearlooks2 span, .clearlooks2 a {vertical-align:baseline; text-align:left; position:absolute; border:0; padding:0; margin:0; background:transparent; font-family:Arial,Verdana; font-size:11px; color:#000; text-decoration:none; font-weight:normal; width:auto; height:auto; overflow:hidden; display:block}

/* General */
.clearlooks2 {position:absolute; direction:ltr}
.clearlooks2 .mceWrapper {position:static}
.mceEventBlocker {position:fixed; left:0; top:0; background:url(img/horizontal.gif) no-repeat 0 -75px; width:100%; height:100%}
.clearlooks2 .mcePlaceHolder {border:1px solid #000; background:#888; top:0; left:0; opacity:0.5; -ms-filter:'alpha(opacity=50)'; filter:alpha(opacity=50)}
.clearlooks2_modalBlocker {position:fixed; left:0; top:0; width:100%; height:100%; background:#FFF; opacity:0.6; -ms-filter:'alpha(opacity=60)'; filter:alpha(opacity=60); display:none}

/* Top */
.clearlooks2 .mceTop, .clearlooks2 .mceTop div {top:0; width:100%; height:23px}
.clearlooks2 .mceTop .mceLeft {width:6px; background:url(img/corners.gif)}
.clearlooks2 .mceTop .mceCenter {right:6px; width:100%; height:23px; background:url(img/horizontal.gif) 12px 0; clip:rect(auto auto auto 12px)}
.clearlooks2 .mceTop .mceRight {right:0; width:6px; height:23px; background:url(img/corners.gif) -12px 0}
.clearlooks2 .mceTop span {width:100%; text-align:center; vertical-align:middle; line-height:23px; font-weight:bold}
.clearlooks2 .mceFocus .mceTop .mceLeft {background:url(img/corners.gif) -6px 0}
.clearlooks2 .mceFocus .mceTop .mceCenter {background:url(img/horizontal.gif) 0 -23px}
.clearlooks2 .mceFocus .mceTop .mceRight {background:url(img/corners.gif) -18px 0}
.clearlooks2 .mceFocus .mceTop span {color:#FFF}

/* Middle */
.clearlooks2 .mceMiddle, .clearlooks2 .mceMiddle div {top:0}
.clearlooks2 .mceMiddle {width:100%; height:100%; clip:rect(23px auto auto auto)}
.clearlooks2 .mceMiddle .mceLeft {left:0; width:5px; height:100%; background:url(img/vertical.gif) -5px 0}
.clearlooks2 .mceMiddle span {top:23px; left:5px; width:100%; height:100%; background:#FFF}
.clearlooks2 .mceMiddle .mceRight {right:0; width:5px; height:100%; background:url(img/vertical.gif)}

/* Bottom */
.clearlooks2 .mceBottom, .clearlooks2 .mceBottom div {height:6px}
.clearlooks2 .mceBottom {left:0; bottom:0; width:100%}
.clearlooks2 .mceBottom div {top:0}
.clearlooks2 .mceBottom .mceLeft {left:0; width:5px; background:url(img/corners.gif) -34px -6px}
.clearlooks2 .mceBottom .mceCenter {left:5px; width:100%; background:url(img/horizontal.gif) 0 -46px}
.clearlooks2 .mceBottom .mceRight {right:0; width:5px; background: url(img/corners.gif) -34px 0}
.clearlooks2 .mceBottom span {display:none}
.clearlooks2 .mceStatusbar .mceBottom, .clearlooks2 .mceStatusbar .mceBottom div {height:23px}
.clearlooks2 .mceStatusbar .mceBottom .mceLeft {background:url(img/corners.gif) -29px 0}
.clearlooks2 .mceStatusbar .mceBottom .mceCenter {background:url(img/horizontal.gif) 0 -52px}
.clearlooks2 .mceStatusbar .mceBottom .mceRight {background:url(img/corners.gif) -24px 0}
.clearlooks2 .mceStatusbar .mceBottom span {display:block; left:7px; font-family:Arial, Verdana; font-size:11px; line-height:23px}

/* Actions */
.clearlooks2 a {width:29px; height:16px; top:3px;}
.clearlooks2 .mceClose {right:6px; background:url(img/buttons.gif) -87px 0}
.clearlooks2 .mceMin {display:none; right:68px; background:url(img/buttons.gif) 0 0}
.clearlooks2 .mceMed {display:none; right:37px; background:url(img/buttons.gif) -29px 0}
.clearlooks2 .mceMax {display:none; right:37px; background:url(img/buttons.gif) -58px 0}
.clearlooks2 .mceMove {display:none;width:100%;cursor:move;background:url(img/corners.gif) no-repeat -100px -100px}
.clearlooks2 .mceMovable .mceMove {display:block}
.clearlooks2 .mceFocus .mceClose {right:6px; background:url(img/buttons.gif) -87px -16px}
.clearlooks2 .mceFocus .mceMin {right:68px; background:url(img/buttons.gif) 0 -16px}
.clearlooks2 .mceFocus .mceMed {right:37px; background:url(img/buttons.gif) -29px -16px}
.clearlooks2 .mceFocus .mceMax {right:37px; background:url(img/buttons.gif) -58px -16px}
.clearlooks2 .mceFocus .mceClose:hover {right:6px; background:url(img/buttons.gif) -87px -32px}
.clearlooks2 .mceFocus .mceClose:hover {right:6px; background:url(img/buttons.gif) -87px -32px}
.clearlooks2 .mceFocus .mceMin:hover {right:68px; background:url(img/buttons.gif) 0 -32px}
.clearlooks2 .mceFocus .mceMed:hover {right:37px; background:url(img/buttons.gif) -29px -32px}
.clearlooks2 .mceFocus .mceMax:hover {right:37px; background:url(img/buttons.gif) -58px -32px}

/* Resize */
.clearlooks2 .mceResize {top:auto; left:auto; display:none; width:5px; height:5px; background:url(img/horizontal.gif) no-repeat 0 -75px}
.clearlooks2 .mceResizable .mceResize {display:block}
.clearlooks2 .mceResizable .mceMin, .clearlooks2 .mceMax {display:none}
.clearlooks2 .mceMinimizable .mceMin {display:block}
.clearlooks2 .mceMaximizable .mceMax {display:block}
.clearlooks2 .mceMaximized .mceMed {display:block}
.clearlooks2 .mceMaximized .mceMax {display:none}
.clearlooks2 a.mceResizeN {top:0; left:0; width:100%; cursor:n-resize}
.clearlooks2 a.mceResizeNW {top:0; left:0; cursor:nw-resize}
.clearlooks2 a.mceResizeNE {top:0; right:0; cursor:ne-resize}
.clearlooks2 a.mceResizeW {top:0; left:0; height:100%; cursor:w-resize;}
.clearlooks2 a.mceResizeE {top:0; right:0; height:100%; cursor:e-resize}
.clearlooks2 a.mceResizeS {bottom:0; left:0; width:100%; cursor:s-resize}
.clearlooks2 a.mceResizeSW {bottom:0; left:0; cursor:sw-resize}
.clearlooks2 a.mceResizeSE {bottom:0; right:0; cursor:se-resize}

/* Alert/Confirm */
.clearlooks2 .mceButton {font-weight:bold; bottom:10px; width:80px; height:30px; background:url(img/button.gif); line-height:30px; vertical-align:middle; text-align:center; outline:0}
.clearlooks2 .mceMiddle .mceIcon {left:15px; top:35px; width:32px; height:32px}
.clearlooks2 .mceAlert .mceMiddle span, .clearlooks2 .mceConfirm .mceMiddle span {background:transparent;left:60px; top:35px; width:320px; height:50px; font-weight:bold; overflow:auto; white-space:normal}
.clearlooks2 a:hover {font-weight:bold;}
.clearlooks2 .mceAlert .mceMiddle, .clearlooks2 .mceConfirm .mceMiddle {background:#D6D7D5}
.clearlooks2 .mceAlert .mceOk {left:50%; top:auto; margin-left: -40px}
.clearlooks2 .mceAlert .mceIcon {background:url(img/alert.gif)}
.clearlooks2 .mceConfirm .mceOk {left:50%; top:auto; margin-left: -90px}
.clearlooks2 .mceConfirm .mceCancel {left:50%; top:auto}
.clearlooks2 .mceConfirm .mceIcon {background:url(img/confirm.gif)}

license: mit


code:
<title>Template for dialogs</title>
<link rel="stylesheet" type="text/css" href="skins/clearlooks2/window.css" />

				Blured

				Content

				Statusbar text.

				Focused

				Content

				Statusbar text.

				Statusbar

				Content

				Statusbar text.

				Statusbar, Resizable

				Content

				Statusbar text.

				Resizable, Maximizable

				Content

				Statusbar text.

				Blurred, Maximizable, Statusbar, Resizable

				Content

				Statusbar text.

				Maximized, Maximizable, Minimizable

				Content

				Statusbar text.

				Blured

				Content

				Statusbar text.

				Alert

					This is a very long error message. This is a very long error message.
					This is a very long error message. This is a very long error message.
					This is a very long error message. This is a very long error message.
					This is a very long error message. This is a very long error message.
					This is a very long error message. This is a very long error message.
					This is a very long error message. This is a very long error message.

			Ok

				Confirm

					This is a very long error message. This is a very long error message.
					This is a very long error message. This is a very long error message.
					This is a very long error message. This is a very long error message.
					This is a very long error message. This is a very long error message.
					This is a very long error message. This is a very long error message.
					This is a very long error message. This is a very long error message.

			Ok
			Cancel


code:
/**
 * editor_plugin_src.js
 *
 * Copyright 2009, Moxiecode Systems AB
 * Released under LGPL License.
 *
 * License: http://tinymce.moxiecode.com/license
 * Contributing: http://tinymce.moxiecode.com/contributing
 */

(function() {
	tinymce.create('tinymce.plugins.InsertDateTime', {
		init : function(ed, url) {
			var t = this;

			t.editor = ed;

			ed.addCommand('mceInsertDate', function() {
				var str = t._getDateTime(new Date(), ed.getParam("plugin_insertdate_dateFormat", ed.getLang('insertdatetime.date_fmt')));

				ed.execCommand('mceInsertContent', false, str);
			});

			ed.addCommand('mceInsertTime', function() {
				var str = t._getDateTime(new Date(), ed.getParam("plugin_insertdate_timeFormat", ed.getLang('insertdatetime.time_fmt')));

				ed.execCommand('mceInsertContent', false, str);
			});

			ed.addButton('insertdate', {title : 'insertdatetime.insertdate_desc', cmd : 'mceInsertDate'});
			ed.addButton('inserttime', {title : 'insertdatetime.inserttime_desc', cmd : 'mceInsertTime'});
		},

		getInfo : function() {
			return {
				longname : 'Insert date/time',
				author : 'Moxiecode Systems AB',
				authorurl : 'http://tinymce.moxiecode.com',
				infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/insertdatetime',
				version : tinymce.majorVersion + "." + tinymce.minorVersion
			};
		},

		// Private methods

		_getDateTime : function(d, fmt) {
			var ed = this.editor;

			function addZeros(value, len) {
				value = "" + value;

				if (value.length < len) {
					for (var i=0; i<(len-value.length); i++)
						value = "0" + value;
				}

				return value;
			};

			fmt = fmt.replace("%D", "%m/%d/%y");
			fmt = fmt.replace("%r", "%I:%M:%S %p");
			fmt = fmt.replace("%Y", "" + d.getFullYear());
			fmt = fmt.replace("%y", "" + d.getYear());
			fmt = fmt.replace("%m", addZeros(d.getMonth()+1, 2));
			fmt = fmt.replace("%d", addZeros(d.getDate(), 2));
			fmt = fmt.replace("%H", "" + addZeros(d.getHours(), 2));
			fmt = fmt.replace("%M", "" + addZeros(d.getMinutes(), 2));
			fmt = fmt.replace("%S", "" + addZeros(d.getSeconds(), 2));
			fmt = fmt.replace("%I", "" + ((d.getHours() + 11) % 12 + 1));
			fmt = fmt.replace("%p", "" + (d.getHours() < 12 ? "AM" : "PM"));
			fmt = fmt.replace("%B", "" + ed.getLang("insertdatetime.months_long").split(',')[d.getMonth()]);
			fmt = fmt.replace("%b", "" + ed.getLang("insertdatetime.months_short").split(',')[d.getMonth()]);
			fmt = fmt.replace("%A", "" + ed.getLang("insertdatetime.day_long").split(',')[d.getDay()]);
			fmt = fmt.replace("%a", "" + ed.getLang("insertdatetime.day_short").split(',')[d.getDay()]);
			fmt = fmt.replace("%%", "%");

			return fmt;
		}
	});

	// Register plugin
	tinymce.PluginManager.add('insertdatetime', tinymce.plugins.InsertDateTime);
})();


code:
/**
 * editor_plugin_src.js
 *
 * Copyright 2009, Moxiecode Systems AB
 * Released under LGPL License.
 *
 * License: http://tinymce.moxiecode.com/license
 * Contributing: http://tinymce.moxiecode.com/contributing
 */

(function() {
	tinymce.create('tinymce.plugins.Layer', {
		init : function(ed, url) {
			var t = this;

			t.editor = ed;

			// Register commands
			ed.addCommand('mceInsertLayer', t._insertLayer, t);

			ed.addCommand('mceMoveForward', function() {
				t._move(1);
			});

			ed.addCommand('mceMoveBackward', function() {
				t._move(-1);
			});

			ed.addCommand('mceMakeAbsolute', function() {
				t._toggleAbsolute();
			});

			// Register buttons
			ed.addButton('moveforward', {title : 'layer.forward_desc', cmd : 'mceMoveForward'});
			ed.addButton('movebackward', {title : 'layer.backward_desc', cmd : 'mceMoveBackward'});
			ed.addButton('absolute', {title : 'layer.absolute_desc', cmd : 'mceMakeAbsolute'});
			ed.addButton('insertlayer', {title : 'layer.insertlayer_desc', cmd : 'mceInsertLayer'});

			ed.onInit.add(function() {
				if (tinymce.isIE)
					ed.getDoc().execCommand('2D-Position', false, true);
			});

			ed.onNodeChange.add(t._nodeChange, t);
			ed.onVisualAid.add(t._visualAid, t);
		},

		getInfo : function() {
			return {
				longname : 'Layer',
				author : 'Moxiecode Systems AB',
				authorurl : 'http://tinymce.moxiecode.com',
				infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/layer',
				version : tinymce.majorVersion + "." + tinymce.minorVersion
			};
		},

		// Private methods

		_nodeChange : function(ed, cm, n) {
			var le, p;

			le = this._getParentLayer(n);
			p = ed.dom.getParent(n, 'DIV,P,IMG');

			if (!p) {
				cm.setDisabled('absolute', 1);
				cm.setDisabled('moveforward', 1);
				cm.setDisabled('movebackward', 1);
			} else {
				cm.setDisabled('absolute', 0);
				cm.setDisabled('moveforward', !le);
				cm.setDisabled('movebackward', !le);
				cm.setActive('absolute', le && le.style.position.toLowerCase() == "absolute");
			}
		},

		// Private methods

		_visualAid : function(ed, e, s) {
			var dom = ed.dom;

			tinymce.each(dom.select('div,p', e), function(e) {
				if (/^(absolute|relative|static)$/i.test(e.style.position)) {
					if (s)
						dom.addClass(e, 'mceItemVisualAid');
					else
						dom.removeClass(e, 'mceItemVisualAid');
				}
			});
		},

		_move : function(d) {
			var ed = this.editor, i, z = [], le = this._getParentLayer(ed.selection.getNode()), ci = -1, fi = -1, nl;

			nl = [];
			tinymce.walk(ed.getBody(), function(n) {
				if (n.nodeType == 1 && /^(absolute|relative|static)$/i.test(n.style.position))
					nl.push(n);
			}, 'childNodes');

			// Find z-indexes
			for (i=0; i<nl.length; i++) {
				z[i] = nl[i].style.zIndex ? parseInt(nl[i].style.zIndex) : 0;

				if (ci < 0 && nl[i] == le)
					ci = i;
			}

			if (d < 0) {
				// Move back

				// Try find a lower one
				for (i=0; i<z.length; i++) {
					if (z[i] < z[ci]) {
						fi = i;
						break;
					}
				}

				if (fi > -1) {
					nl[ci].style.zIndex = z[fi];
					nl[fi].style.zIndex = z[ci];
				} else {
					if (z[ci] > 0)
						nl[ci].style.zIndex = z[ci] - 1;
				}
			} else {
				// Move forward

				// Try find a higher one
				for (i=0; i<z.length; i++) {
					if (z[i] > z[ci]) {
						fi = i;
						break;
					}
				}

				if (fi > -1) {
					nl[ci].style.zIndex = z[fi];
					nl[fi].style.zIndex = z[ci];
				} else
					nl[ci].style.zIndex = z[ci] + 1;
			}

			ed.execCommand('mceRepaint');
		},

		_getParentLayer : function(n) {
			return this.editor.dom.getParent(n, function(n) {
				return n.nodeType == 1 && /^(absolute|relative|static)$/i.test(n.style.position);
			});
		},

		_insertLayer : function() {
			var ed = this.editor, p = ed.dom.getPos(ed.dom.getParent(ed.selection.getNode(), '*'));

			ed.dom.add(ed.getBody(), 'div', {
				style : {
					position : 'absolute',
					left : p.x,
					top : (p.y > 20 ? p.y : 20),
					width : 100,
					height : 100
				},
				'class' : 'mceItemVisualAid'
			}, ed.selection.getContent() || ed.getLang('layer.content'));
		},

		_toggleAbsolute : function() {
			var ed = this.editor, le = this._getParentLayer(ed.selection.getNode());

			if (!le)
				le = ed.dom.getParent(ed.selection.getNode(), 'DIV,P,IMG');

			if (le) {
				if (le.style.position.toLowerCase() == "absolute") {
					ed.dom.setStyles(le, {
						position : '',
						left : '',
						top : '',
						width : '',
						height : ''
					});

					ed.dom.removeClass(le, 'mceItemVisualAid');
				} else {
					if (le.style.left == "")
						le.style.left = 20 + 'px';

					if (le.style.top == "")
						le.style.top = 20 + 'px';

					if (le.style.width == "")
						le.style.width = le.width ? (le.width + 'px') : '100px';

					if (le.style.height == "")
						le.style.height = le.height ? (le.height + 'px') : '100px';

					le.style.position = "absolute";

					ed.dom.setAttrib(le, 'data-mce-style', '');
					ed.addVisual(ed.getBody());
				}

				ed.execCommand('mceRepaint');
				ed.nodeChanged();
			}
		}
	});

	// Register plugin
	tinymce.PluginManager.add('layer', tinymce.plugins.Layer);
})();


code:
/**
 * editor_plugin_src.js
 *
 * Copyright 2009, Moxiecode Systems AB
 * Released under LGPL License.
 *
 * License: http://tinymce.moxiecode.com/license
 * Contributing: http://tinymce.moxiecode.com/contributing
 *
 * This plugin will force TinyMCE to produce deprecated legacy output such as font elements, u elements, align
 * attributes and so forth. There are a few cases where these old items might be needed for example in email applications or with Flash
 *
 * However you should NOT use this plugin if you are building some system that produces web contents such as a CMS. All these elements are
 * not apart of the newer specifications for HTML and XHTML.
 */

(function(tinymce) {
	// Override inline_styles setting to force TinyMCE to produce deprecated contents
	tinymce.onAddEditor.addToTop(function(tinymce, editor) {
		editor.settings.inline_styles = false;
	});

	// Create the legacy ouput plugin
	tinymce.create('tinymce.plugins.LegacyOutput', {
		init : function(editor) {
			editor.onInit.add(function() {
				var alignElements = 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li,table,img',
					fontSizes = tinymce.explode(editor.settings.font_size_style_values),
					schema = editor.schema;

				// Override some internal formats to produce legacy elements and attributes
				editor.formatter.register({
					// Change alignment formats to use the deprecated align attribute
					alignleft : {selector : alignElements, attributes : {align : 'left'}},
					aligncenter : {selector : alignElements, attributes : {align : 'center'}},
					alignright : {selector : alignElements, attributes : {align : 'right'}},
					alignfull : {selector : alignElements, attributes : {align : 'justify'}},

					// Change the basic formatting elements to use deprecated element types
					bold : [
						{inline : 'b', remove : 'all'},
						{inline : 'strong', remove : 'all'},
						{inline : 'span', styles : {fontWeight : 'bold'}}
					],
					italic : [
						{inline : 'i', remove : 'all'},
						{inline : 'em', remove : 'all'},
						{inline : 'span', styles : {fontStyle : 'italic'}}
					],
					underline : [
						{inline : 'u', remove : 'all'},
						{inline : 'span', styles : {textDecoration : 'underline'}, exact : true}
					],
					strikethrough : [
						{inline : 'strike', remove : 'all'},
						{inline : 'span', styles : {textDecoration: 'line-through'}, exact : true}
					],

					// Change font size and font family to use the deprecated font element
					fontname : {inline : 'font', attributes : {face : '%value'}},
					fontsize : {
						inline : 'font',
						attributes : {
							size : function(vars) {
								return tinymce.inArray(fontSizes, vars.value) + 1;
							}
						}
					},

					// Setup font elements for colors as well
					forecolor : {inline : 'font', styles : {color : '%value'}},
					hilitecolor : {inline : 'font', styles : {backgroundColor : '%value'}}
				});

				// Check that deprecated elements are allowed if not add them
				tinymce.each('b,i,u,strike'.split(','), function(name) {
					schema.addValidElements(name + '[*]');
				});

				// Add font element if it's missing
				if (!schema.getElementRule("font"))
					schema.addValidElements("font[face|size|color|style]");

				// Add the missing and depreacted align attribute for the serialization engine
				tinymce.each(alignElements.split(','), function(name) {
					var rule = schema.getElementRule(name), found;

					if (rule) {
						if (!rule.attributes.align) {
							rule.attributes.align = {};
							rule.attributesOrder.push('align');
						}
					}
				});

				// Listen for the onNodeChange event so that we can do special logic for the font size and font name drop boxes
				editor.onNodeChange.add(function(editor, control_manager) {
					var control, fontElm, fontName, fontSize;

					// Find font element get it's name and size
					fontElm = editor.dom.getParent(editor.selection.getNode(), 'font');
					if (fontElm) {
						fontName = fontElm.face;
						fontSize = fontElm.size;
					}

					// Select/unselect the font name in droplist
					if (control = control_manager.get('fontselect')) {
						control.select(function(value) {
							return value == fontName;
						});
					}

					// Select/unselect the font size in droplist
					if (control = control_manager.get('fontsizeselect')) {
						control.select(function(value) {
							var index = tinymce.inArray(fontSizes, value.fontSize);

							return index + 1 == fontSize;
						});
					}
				});
			});
		},

		getInfo : function() {
			return {
				longname : 'LegacyOutput',
				author : 'Moxiecode Systems AB',
				authorurl : 'http://tinymce.moxiecode.com',
				infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/legacyoutput',
				version : tinymce.majorVersion + "." + tinymce.minorVersion
			};
		}
	});

	// Register plugin
	tinymce.PluginManager.add('legacyoutput', tinymce.plugins.LegacyOutput);
})(tinymce);


code:
/**
 * editor_plugin_src.js
 *
 * Copyright 2011, Moxiecode Systems AB
 * Released under LGPL License.
 *
 * License: http://tinymce.moxiecode.com/license
 * Contributing: http://tinymce.moxiecode.com/contributing
 */

(function() {
	var each = tinymce.each, Event = tinymce.dom.Event, bookmark;

	// Skips text nodes that only contain whitespace since they aren't semantically important.
	function skipWhitespaceNodes(e, next) {
		while (e && (e.nodeType === 8 || (e.nodeType === 3 && /^[ \t\n\r]*$/.test(e.nodeValue)))) {
			e = next(e);
		}
		return e;
	}

	function skipWhitespaceNodesBackwards(e) {
		return skipWhitespaceNodes(e, function(e) { return e.previousSibling; });
	}

	function skipWhitespaceNodesForwards(e) {
		return skipWhitespaceNodes(e, function(e) { return e.nextSibling; });
	}

	function hasParentInList(ed, e, list) {
		return ed.dom.getParent(e, function(p) {
			return tinymce.inArray(list, p) !== -1;
		});
	}

	function isList(e) {
		return e && (e.tagName === 'OL' || e.tagName === 'UL');
	}

	function splitNestedLists(element, dom) {
		var tmp, nested, wrapItem;
		tmp = skipWhitespaceNodesBackwards(element.lastChild);
		while (isList(tmp)) {
			nested = tmp;
			tmp = skipWhitespaceNodesBackwards(nested.previousSibling);
		}
		if (nested) {
			wrapItem = dom.create('li', { style: 'list-style-type: none;'});
			dom.split(element, nested);
			dom.insertAfter(wrapItem, nested);
			wrapItem.appendChild(nested);
			wrapItem.appendChild(nested);
			element = wrapItem.previousSibling;
		}
		return element;
	}

	function attemptMergeWithAdjacent(e, allowDifferentListStyles, mergeParagraphs) {
		e = attemptMergeWithPrevious(e, allowDifferentListStyles, mergeParagraphs);
		return attemptMergeWithNext(e, allowDifferentListStyles, mergeParagraphs);
	}

	function attemptMergeWithPrevious(e, allowDifferentListStyles, mergeParagraphs) {
		var prev = skipWhitespaceNodesBackwards(e.previousSibling);
		if (prev) {
			return attemptMerge(prev, e, allowDifferentListStyles ? prev : false, mergeParagraphs);
		} else {
			return e;
		}
	}

	function attemptMergeWithNext(e, allowDifferentListStyles, mergeParagraphs) {
		var next = skipWhitespaceNodesForwards(e.nextSibling);
		if (next) {
			return attemptMerge(e, next, allowDifferentListStyles ? next : false, mergeParagraphs);
		} else {
			return e;
		}
	}

	function attemptMerge(e1, e2, differentStylesMasterElement, mergeParagraphs) {
		if (canMerge(e1, e2, !!differentStylesMasterElement, mergeParagraphs)) {
			return merge(e1, e2, differentStylesMasterElement);
		} else if (e1 && e1.tagName === 'LI' && isList(e2)) {
			// Fix invalidly nested lists.
			e1.appendChild(e2);
		}
		return e2;
	}

	function canMerge(e1, e2, allowDifferentListStyles, mergeParagraphs) {
		if (!e1 || !e2) {
			return false;
		} else if (e1.tagName === 'LI' && e2.tagName === 'LI') {
			return e2.style.listStyleType === 'none' || containsOnlyAList(e2);
		} else if (isList(e1)) {
			return (e1.tagName === e2.tagName && (allowDifferentListStyles || e1.style.listStyleType === e2.style.listStyleType)) || isListForIndent(e2);
		} else if (mergeParagraphs && e1.tagName === 'P' && e2.tagName === 'P') {
			return true;
		} else {
			return false;
		}
	}

	function isListForIndent(e) {
		var firstLI = skipWhitespaceNodesForwards(e.firstChild), lastLI = skipWhitespaceNodesBackwards(e.lastChild);
		return firstLI && lastLI && isList(e) && firstLI === lastLI && (isList(firstLI) || firstLI.style.listStyleType === 'none'  || containsOnlyAList(firstLI));
	}

	function containsOnlyAList(e) {
		var firstChild = skipWhitespaceNodesForwards(e.firstChild), lastChild = skipWhitespaceNodesBackwards(e.lastChild);
		return firstChild && lastChild && firstChild === lastChild && isList(firstChild);
	}

	function merge(e1, e2, masterElement) {
		var lastOriginal = skipWhitespaceNodesBackwards(e1.lastChild), firstNew = skipWhitespaceNodesForwards(e2.firstChild);
		if (e1.tagName === 'P') {
			e1.appendChild(e1.ownerDocument.createElement('br'));
		}
		while (e2.firstChild) {
			e1.appendChild(e2.firstChild);
		}
		if (masterElement) {
			e1.style.listStyleType = masterElement.style.listStyleType;
		}
		e2.parentNode.removeChild(e2);
		attemptMerge(lastOriginal, firstNew, false);
		return e1;
	}

	function findItemToOperateOn(e, dom) {
		var item;
		if (!dom.is(e, 'li,ol,ul')) {
			item = dom.getParent(e, 'li');
			if (item) {
				e = item;
			}
		}
		return e;
	}

	tinymce.create('tinymce.plugins.Lists', {
		init: function(ed, url) {
			var enterDownInEmptyList = false;

			function isTriggerKey(e) {
				return e.keyCode === 9 && (ed.queryCommandState('InsertUnorderedList') || ed.queryCommandState('InsertOrderedList'));
			};

			function isEnterInEmptyListItem(ed, e) {
				var sel = ed.selection, n;
				if (e.keyCode === 13) {
					n = sel.getStart();

					// Get start will return BR if the LI only contains a BR
					if (n.tagName == 'BR' && n.parentNode.tagName == 'LI')
						n = n.parentNode;

					// Check for empty LI or a LI with just one BR since Gecko and WebKit uses BR elements to place the caret
					enterDownInEmptyList = sel.isCollapsed() && n && n.tagName === 'LI' && (n.childNodes.length === 0 || (n.firstChild.nodeName == 'BR' && n.childNodes.length === 1));
					return enterDownInEmptyList;
				}
			};

			function cancelKeys(ed, e) {
				if (isTriggerKey(e) || isEnterInEmptyListItem(ed, e)) {
					return Event.cancel(e);
				}
			};

			function imageJoiningListItem(ed, e) {
				if (!tinymce.isGecko)
					return;

				var n = ed.selection.getStart();
				if (e.keyCode != 8 || n.tagName !== 'IMG')
					return;

				function lastLI(node) {
					var child = node.firstChild;
					var li = null;
					do {
						if (!child)
							break;

						if (child.tagName === 'LI')
							li = child;
					} while (child = child.nextSibling);

					return li;
				}

				function addChildren(parentNode, destination) {
					while (parentNode.childNodes.length > 0)
						destination.appendChild(parentNode.childNodes[0]);
				}

				var ul;
				if (n.parentNode.previousSibling.tagName === 'UL' || n.parentNode.previousSibling.tagName === 'OL')
					ul = n.parentNode.previousSibling;
				else if (n.parentNode.previousSibling.previousSibling.tagName === 'UL' || n.parentNode.previousSibling.previousSibling.tagName === 'OL')
					ul = n.parentNode.previousSibling.previousSibling;
				else
					return;

				var li = lastLI(ul);

				// move the caret to the end of the list item
				var rng = ed.dom.createRng();
				rng.setStart(li, 1);
				rng.setEnd(li, 1);
				ed.selection.setRng(rng);
				ed.selection.collapse(true);

				// save a bookmark at the end of the list item
				var bookmark = ed.selection.getBookmark();

				// copy the image an its text to the list item
				var clone = n.parentNode.cloneNode(true);
				if (clone.tagName === 'P' || clone.tagName === 'DIV')
					addChildren(clone, li);
				else
					li.appendChild(clone);

				// remove the old copy of the image
				n.parentNode.parentNode.removeChild(n.parentNode);

				// move the caret where we saved the bookmark
				ed.selection.moveToBookmark(bookmark);
			}

			this.ed = ed;
			ed.addCommand('Indent', this.indent, this);
			ed.addCommand('Outdent', this.outdent, this);
			ed.addCommand('InsertUnorderedList', function() {
				this.applyList('UL', 'OL');
			}, this);
			ed.addCommand('InsertOrderedList', function() {
				this.applyList('OL', 'UL');
			}, this);

			ed.onInit.add(function() {
				ed.editorCommands.addCommands({
					'outdent': function() {
						var sel = ed.selection, dom = ed.dom;
						function hasStyleIndent(n) {
							n = dom.getParent(n, dom.isBlock);
							return n && (parseInt(ed.dom.getStyle(n, 'margin-left') || 0, 10) + parseInt(ed.dom.getStyle(n, 'padding-left') || 0, 10)) > 0;
						}
						return hasStyleIndent(sel.getStart()) || hasStyleIndent(sel.getEnd()) || ed.queryCommandState('InsertOrderedList') || ed.queryCommandState('InsertUnorderedList');
					}
				}, 'state');
			});

			ed.onKeyUp.add(function(ed, e) {
				var n, rng;
				if (isTriggerKey(e)) {
					ed.execCommand(e.shiftKey ? 'Outdent' : 'Indent', true, null);
					return Event.cancel(e);
				} else if (enterDownInEmptyList && isEnterInEmptyListItem(ed, e)) {
					if (ed.queryCommandState('InsertOrderedList')) {
						ed.execCommand('InsertOrderedList');
					} else {
						ed.execCommand('InsertUnorderedList');
					}
					n = ed.selection.getStart();
					if (n && n.tagName === 'LI') {
						// Fix the caret position on IE since it jumps back up to the previous list item.
						n = ed.dom.getParent(n, 'ol,ul').nextSibling;
						if (n && n.tagName === 'P') {
							if (!n.firstChild) {
								n.appendChild(ed.getDoc().createTextNode(''));
							}
							rng = ed.dom.createRng();
							rng.setStart(n.firstChild, 1);
							rng.setEnd(n.firstChild, 1);
							ed.selection.setRng(rng);
						}
					}
					return Event.cancel(e);
				}
			});
			ed.onKeyPress.add(cancelKeys);
			ed.onKeyDown.add(cancelKeys);
			ed.onKeyDown.add(imageJoiningListItem);
		},

		applyList: function(targetListType, oppositeListType) {
			var t = this, ed = t.ed, dom = ed.dom, applied = [], hasSameType = false, hasOppositeType = false, hasNonList = false, actions,
				selectedBlocks = ed.selection.getSelectedBlocks();

			function cleanupBr(e) {
				if (e && e.tagName === 'BR') {
					dom.remove(e);
				}
			}

			function makeList(element) {
				var list = dom.create(targetListType), li;
				function adjustIndentForNewList(element) {
					// If there's a margin-left, outdent one level to account for the extra list margin.
					if (element.style.marginLeft || element.style.paddingLeft) {
						t.adjustPaddingFunction(false)(element);
					}
				}

				if (element.tagName === 'LI') {
					// No change required.
				} else if (element.tagName === 'P' || element.tagName === 'DIV' || element.tagName === 'BODY') {
					processBrs(element, function(startSection, br, previousBR) {
						doWrapList(startSection, br, element.tagName === 'BODY' ? null : startSection.parentNode);
						li = startSection.parentNode;
						adjustIndentForNewList(li);
						cleanupBr(br);
					});
					if (element.tagName === 'P' || selectedBlocks.length > 1) {
						dom.split(li.parentNode.parentNode, li.parentNode);
					}
					attemptMergeWithAdjacent(li.parentNode, true);
					return;
				} else {
					// Put the list around the element.
					li = dom.create('li');
					dom.insertAfter(li, element);
					li.appendChild(element);
					adjustIndentForNewList(element);
					element = li;
				}
				dom.insertAfter(list, element);
				list.appendChild(element);
				attemptMergeWithAdjacent(list, true);
				applied.push(element);
			}

			function doWrapList(start, end, template) {
				var li, n = start, tmp, i;
				while (!dom.isBlock(start.parentNode) && start.parentNode !== dom.getRoot()) {
					start = dom.split(start.parentNode, start.previousSibling);
					start = start.nextSibling;
					n = start;
				}
				if (template) {
					li = template.cloneNode(true);
					start.parentNode.insertBefore(li, start);
					while (li.firstChild) dom.remove(li.firstChild);
					li = dom.rename(li, 'li');
				} else {
					li = dom.create('li');
					start.parentNode.insertBefore(li, start);
				}
				while (n && n != end) {
					tmp = n.nextSibling;
					li.appendChild(n);
					n = tmp;
				}
				if (li.childNodes.length === 0) {
					li.innerHTML = '<br _mce_bogus="1" />';
				}
				makeList(li);
			}

			function processBrs(element, callback) {
				var startSection, previousBR, END_TO_START = 3, START_TO_END = 1,
					breakElements = 'br,ul,ol,p,div,h1,h2,h3,h4,h5,h6,table,blockquote,address,pre,form,center,dl';
				function isAnyPartSelected(start, end) {
					var r = dom.createRng(), sel;
					bookmark.keep = true;
					ed.selection.moveToBookmark(bookmark);
					bookmark.keep = false;
					sel = ed.selection.getRng(true);
					if (!end) {
						end = start.parentNode.lastChild;
					}
					r.setStartBefore(start);
					r.setEndAfter(end);
					return !(r.compareBoundaryPoints(END_TO_START, sel) > 0 || r.compareBoundaryPoints(START_TO_END, sel) <= 0);
				}
				function nextLeaf(br) {
					if (br.nextSibling)
						return br.nextSibling;
					if (!dom.isBlock(br.parentNode) && br.parentNode !== dom.getRoot())
						return nextLeaf(br.parentNode);
				}
				// Split on BRs within the range and process those.
				startSection = element.firstChild;
				// First mark the BRs that have any part of the previous section selected.
				var trailingContentSelected = false;
				each(dom.select(breakElements, element), function(br) {
					var b;
					if (br.hasAttribute && br.hasAttribute('_mce_bogus')) {
						return true; // Skip the bogus Brs that are put in to appease Firefox and Safari.
					}
					if (isAnyPartSelected(startSection, br)) {
						dom.addClass(br, '_mce_tagged_br');
						startSection = nextLeaf(br);
					}
				});
				trailingContentSelected = (startSection && isAnyPartSelected(startSection, undefined));
				startSection = element.firstChild;
				each(dom.select(breakElements, element), function(br) {
					// Got a section from start to br.
					var tmp = nextLeaf(br);
					if (br.hasAttribute && br.hasAttribute('_mce_bogus')) {
						return true; // Skip the bogus Brs that are put in to appease Firefox and Safari.
					}
					if (dom.hasClass(br, '_mce_tagged_br')) {
						callback(startSection, br, previousBR);
						previousBR = null;
					} else {
						previousBR = br;
					}
					startSection = tmp;
				});
				if (trailingContentSelected) {
					callback(startSection, undefined, previousBR);
				}
			}

			function wrapList(element) {
				processBrs(element, function(startSection, br, previousBR) {
					// Need to indent this part
					doWrapList(startSection, br);
					cleanupBr(br);
					cleanupBr(previousBR);
				});
			}

			function changeList(element) {
				if (tinymce.inArray(applied, element) !== -1) {
					return;
				}
				if (element.parentNode.tagName === oppositeListType) {
					dom.split(element.parentNode, element);
					makeList(element);
					attemptMergeWithNext(element.parentNode, false);
				}
				applied.push(element);
			}

			function convertListItemToParagraph(element) {
				var child, nextChild, mergedElement, splitLast;
				if (tinymce.inArray(applied, element) !== -1) {
					return;
				}
				element = splitNestedLists(element, dom);
				while (dom.is(element.parentNode, 'ol,ul,li')) {
					dom.split(element.parentNode, element);
				}
				// Push the original element we have from the selection, not the renamed one.
				applied.push(element);
				element = dom.rename(element, 'p');
				mergedElement = attemptMergeWithAdjacent(element, false, ed.settings.force_br_newlines);
				if (mergedElement === element) {
					// Now split out any block elements that can't be contained within a P.
					// Manually iterate to ensure we handle modifications correctly (doesn't work with tinymce.each)
					child = element.firstChild;
					while (child) {
						if (dom.isBlock(child)) {
							child = dom.split(child.parentNode, child);
							splitLast = true;
							nextChild = child.nextSibling && child.nextSibling.firstChild;
						} else {
							nextChild = child.nextSibling;
							if (splitLast && child.tagName === 'BR') {
								dom.remove(child);
							}
							splitLast = false;
						}
						child = nextChild;
					}
				}
			}

			each(selectedBlocks, function(e) {
				e = findItemToOperateOn(e, dom);
				if (e.tagName === oppositeListType || (e.tagName === 'LI' && e.parentNode.tagName === oppositeListType)) {
					hasOppositeType = true;
				} else if (e.tagName === targetListType || (e.tagName === 'LI' && e.parentNode.tagName === targetListType)) {
					hasSameType = true;
				} else {
					hasNonList = true;
				}
			});

			if (hasNonList || hasOppositeType || selectedBlocks.length === 0) {
				actions = {
					'LI': changeList,
					'H1': makeList,
					'H2': makeList,
					'H3': makeList,
					'H4': makeList,
					'H5': makeList,
					'H6': makeList,
					'P': makeList,
					'BODY': makeList,
					'DIV': selectedBlocks.length > 1 ? makeList : wrapList,
					defaultAction: wrapList
				};
			} else {
				actions = {
					defaultAction: convertListItemToParagraph
				};
			}
			this.process(actions);
		},

		indent: function() {
			var ed = this.ed, dom = ed.dom, indented = [];

			function createWrapItem(element) {
				var wrapItem = dom.create('li', { style: 'list-style-type: none;'});
				dom.insertAfter(wrapItem, element);
				return wrapItem;
			}

			function createWrapList(element) {
				var wrapItem = createWrapItem(element),
					list = dom.getParent(element, 'ol,ul'),
					listType = list.tagName,
					listStyle = dom.getStyle(list, 'list-style-type'),
					attrs = {},
					wrapList;
				if (listStyle !== '') {
					attrs.style = 'list-style-type: ' + listStyle + ';';
				}
				wrapList = dom.create(listType, attrs);
				wrapItem.appendChild(wrapList);
				return wrapList;
			}

			function indentLI(element) {
				if (!hasParentInList(ed, element, indented)) {
					element = splitNestedLists(element, dom);
					var wrapList = createWrapList(element);
					wrapList.appendChild(element);
					attemptMergeWithAdjacent(wrapList.parentNode, false);
					attemptMergeWithAdjacent(wrapList, false);
					indented.push(element);
				}
			}

			this.process({
				'LI': indentLI,
				defaultAction: this.adjustPaddingFunction(true)
			});

		},

		outdent: function() {
			var t = this, ed = t.ed, dom = ed.dom, outdented = [];

			function outdentLI(element) {
				var listElement, targetParent, align;
				if (!hasParentInList(ed, element, outdented)) {
					if (dom.getStyle(element, 'margin-left') !== '' || dom.getStyle(element, 'padding-left') !== '') {
						return t.adjustPaddingFunction(false)(element);
					}
					align = dom.getStyle(element, 'text-align', true);
					if (align === 'center' || align === 'right') {
						dom.setStyle(element, 'text-align', 'left');
						return;
					}
					element = splitNestedLists(element, dom);
					listElement = element.parentNode;
					targetParent = element.parentNode.parentNode;
					if (targetParent.tagName === 'P') {
						dom.split(targetParent, element.parentNode);
					} else {
						dom.split(listElement, element);
						if (targetParent.tagName === 'LI') {
							// Nested list, need to split the LI and go back out to the OL/UL element.
							dom.split(targetParent, element);
						} else if (!dom.is(targetParent, 'ol,ul')) {
							dom.rename(element, 'p');
						}
					}
					outdented.push(element);
				}
			}

			this.process({
				'LI': outdentLI,
				defaultAction: this.adjustPaddingFunction(false)
			});

			each(outdented, attemptMergeWithAdjacent);
		},

		process: function(actions) {
			var t = this, sel = t.ed.selection, dom = t.ed.dom, selectedBlocks, r;
			function processElement(element) {
				dom.removeClass(element, '_mce_act_on');
				if (!element || element.nodeType !== 1) {
					return;
				}
				element = findItemToOperateOn(element, dom);
				var action = actions[element.tagName];
				if (!action) {
					action = actions.defaultAction;
				}
				action(element);
			}
			function recurse(element) {
				t.splitSafeEach(element.childNodes, processElement);
			}
			function brAtEdgeOfSelection(container, offset) {
				return offset >= 0 && container.hasChildNodes() && offset < container.childNodes.length &&
						container.childNodes[offset].tagName === 'BR';
			}
			selectedBlocks = sel.getSelectedBlocks();
			if (selectedBlocks.length === 0) {
				selectedBlocks = [ dom.getRoot() ];
			}

			r = sel.getRng(true);
			if (!r.collapsed) {
				if (brAtEdgeOfSelection(r.endContainer, r.endOffset - 1)) {
					r.setEnd(r.endContainer, r.endOffset - 1);
					sel.setRng(r);
				}
				if (brAtEdgeOfSelection(r.startContainer, r.startOffset)) {
					r.setStart(r.startContainer, r.startOffset + 1);
					sel.setRng(r);
				}
			}
			bookmark = sel.getBookmark();
			actions.OL = actions.UL = recurse;
			t.splitSafeEach(selectedBlocks, processElement);
			sel.moveToBookmark(bookmark);
			bookmark = null;
			// Avoids table or image handles being left behind in Firefox.
			t.ed.execCommand('mceRepaint');
		},

		splitSafeEach: function(elements, f) {
			if (tinymce.isGecko && (/Firefox\/[12]\.[0-9]/.test(navigator.userAgent) ||
					/Firefox\/3\.[0-4]/.test(navigator.userAgent))) {
				this.classBasedEach(elements, f);
			} else {
				each(elements, f);
			}
		},

		classBasedEach: function(elements, f) {
			var dom = this.ed.dom, nodes, element;
			// Mark nodes
			each(elements, function(element) {
				dom.addClass(element, '_mce_act_on');
			});
			nodes = dom.select('._mce_act_on');
			while (nodes.length > 0) {
				element = nodes.shift();
				dom.removeClass(element, '_mce_act_on');
				f(element);
				nodes = dom.select('._mce_act_on');
			}
		},

		adjustPaddingFunction: function(isIndent) {
			var indentAmount, indentUnits, ed = this.ed;
			indentAmount = ed.settings.indentation;
			indentUnits = /[a-z%]+/i.exec(indentAmount);
			indentAmount = parseInt(indentAmount, 10);
			return function(element) {
				var currentIndent, newIndentAmount;
				currentIndent = parseInt(ed.dom.getStyle(element, 'margin-left') || 0, 10) + parseInt(ed.dom.getStyle(element, 'padding-left') || 0, 10);
				if (isIndent) {
					newIndentAmount = currentIndent + indentAmount;
				} else {
					newIndentAmount = currentIndent - indentAmount;
				}
				ed.dom.setStyle(element, 'padding-left', '');
				ed.dom.setStyle(element, 'margin-left', newIndentAmount > 0 ? newIndentAmount + indentUnits : '');
			};
		},

		getInfo: function() {
			return {
				longname : 'Lists',
				author : 'Moxiecode Systems AB',
				authorurl : 'http://tinymce.moxiecode.com',
				infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/lists',
				version : tinymce.majorVersion + "." + tinymce.minorVersion
			};
		}
	});
	tinymce.PluginManager.add("lists", tinymce.plugins.Lists);
}());


code:
#id, #name, #hspace, #vspace, #class_name, #align { width: 100px }
#hspace, #vspace { width: 50px }
#flash_quality, #flash_align, #flash_scale, #flash_salign, #flash_wmode { width: 100px }
#flash_base, #flash_flashvars, #html5_altsource1, #html5_altsource2, #html5_poster { width: 240px }
#width, #height { width: 40px }
#src, #media_type { width: 250px }
#class { width: 120px }
#prev { margin: 0; border: 1px solid black; width: 380px; height: 260px; overflow: auto }
.panel_wrapper div.current { height: 420px; overflow: auto }
#flash_options, #shockwave_options, #qt_options, #wmp_options, #rmp_options { display: none }
.mceAddSelectValue { background-color: #DDDDDD }
#qt_starttime, #qt_endtime, #qt_fov, #qt_href, #qt_moveid, #qt_moviename, #qt_node, #qt_pan, #qt_qtsrc, #qt_qtsrcchokespeed, #qt_target, #qt_tilt, #qt_urlsubstituten, #qt_volume { width: 70px }
#wmp_balance, #wmp_baseurl, #wmp_captioningid, #wmp_currentmarker, #wmp_currentposition, #wmp_defaultframe, #wmp_playcount, #wmp_rate, #wmp_uimode, #wmp_volume { width: 70px }
#rmp_console, #rmp_numloop, #rmp_controls, #rmp_scriptcallbacks { width: 70px }
#shockwave_swvolume, #shockwave_swframe, #shockwave_swurl, #shockwave_swstretchvalign, #shockwave_swstretchhalign, #shockwave_swstretchstyle { width: 90px }
#qt_qtsrc { width: 200px }
iframe {border: 1px solid gray}


code:
/**
 * editor_plugin_src.js
 *
 * Copyright 2009, Moxiecode Systems AB
 * Released under LGPL License.
 *
 * License: http://tinymce.moxiecode.com/license
 * Contributing: http://tinymce.moxiecode.com/contributing
 */

(function() {
	var rootAttributes = tinymce.explode('id,name,width,height,style,align,class,hspace,vspace,bgcolor,type'), excludedAttrs = tinymce.makeMap(rootAttributes.join(',')), Node = tinymce.html.Node,
		mediaTypes, scriptRegExp, JSON = tinymce.util.JSON, mimeTypes;

	// Media types supported by this plugin
	mediaTypes = [
		// Type, clsid:s, mime types, codebase
		["Flash", "d27cdb6e-ae6d-11cf-96b8-444553540000", "application/x-shockwave-flash", "http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"],
		["ShockWave", "166b1bca-3f9c-11cf-8075-444553540000", "application/x-director", "http://download.macromedia.com/pub/shockwave/cabs/director/sw.cab#version=8,5,1,0"],
		["WindowsMedia", "6bf52a52-394a-11d3-b153-00c04f79faa6,22d6f312-b0f6-11d0-94ab-0080c74c7e95,05589fa1-c356-11ce-bf01-00aa0055595a", "application/x-mplayer2", "http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=5,1,52,701"],
		["QuickTime", "02bf25d5-8c17-4b23-bc80-d3488abddc6b", "video/quicktime", "http://www.apple.com/qtactivex/qtplugin.cab#version=6,0,2,0"],
		["RealMedia", "cfcdaa03-8be4-11cf-b84b-0020afbbccfa", "audio/x-pn-realaudio-plugin", "http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"],
		["Java", "8ad9c840-044e-11d1-b3e9-00805f499d93", "application/x-java-applet", "http://java.sun.com/products/plugin/autodl/jinstall-1_5_0-windows-i586.cab#Version=1,5,0,0"],
		["Silverlight", "dfeaf541-f3e1-4c24-acac-99c30715084a", "application/x-silverlight-2"],
		["Iframe"],
		["Video"]
	];

	function toArray(obj) {
		var undef, out, i;

		if (obj && !obj.splice) {
			out = [];

			for (i = 0; true; i++) {
				if (obj[i])
					out[i] = obj[i];
				else
					break;
			}

			return out;
		}

		return obj;
	};

	tinymce.create('tinymce.plugins.MediaPlugin', {
		init : function(ed, url) {
			var self = this, lookup = {}, i, y, item, name;

			function isMediaImg(node) {
				return node && node.nodeName === 'IMG' && ed.dom.hasClass(node, 'mceItemMedia');
			};

			self.editor = ed;
			self.url = url;

			// Parse media types into a lookup table
			scriptRegExp = '';
			for (i = 0; i < mediaTypes.length; i++) {
				name = mediaTypes[i][0];

				item = {
					name : name,
					clsids : tinymce.explode(mediaTypes[i][1] || ''),
					mimes : tinymce.explode(mediaTypes[i][2] || ''),
					codebase : mediaTypes[i][3]
				};

				for (y = 0; y < item.clsids.length; y++)
					lookup['clsid:' + item.clsids[y]] = item;

				for (y = 0; y < item.mimes.length; y++)
					lookup[item.mimes[y]] = item;

				lookup['mceItem' + name] = item;
				lookup[name.toLowerCase()] = item;

				scriptRegExp += (scriptRegExp ? '|' : '') + name;
			}

			// Handle the media_types setting
			tinymce.each(ed.getParam("media_types",
				"video=mp4,m4v,ogv,webm;" +
				"silverlight=xap;" +
				"flash=swf,flv;" +
				"shockwave=dcr;" +
				"quicktime=mov,qt,mpg,mp3,mpeg;" +
				"shockwave=dcr;" +
				"windowsmedia=avi,wmv,wm,asf,asx,wmx,wvx;" +
				"realmedia=rm,ra,ram;" +
				"java=jar"
			).split(';'), function(item) {
				var i, extensions, type;

				item = item.split(/=/);
				extensions = tinymce.explode(item[1].toLowerCase());
				for (i = 0; i < extensions.length; i++) {
					type = lookup[item[0].toLowerCase()];

					if (type)
						lookup[extensions[i]] = type;
				}
			});

			scriptRegExp = new RegExp('write(' + scriptRegExp + ')\\(([^)]+)\\)');
			self.lookup = lookup;

			ed.onPreInit.add(function() {
				// Allow video elements
				ed.schema.addValidElements('object[id|style|width|height|classid|codebase|*],param[name|value],embed[id|style|width|height|type|src|*],video[*],audio[*],source[*]');

				// Convert video elements to image placeholder
				ed.parser.addNodeFilter('object,embed,video,audio,script,iframe', function(nodes) {
					var i = nodes.length;

					while (i--)
						self.objectToImg(nodes[i]);
				});

				// Convert image placeholders to video elements
				ed.serializer.addNodeFilter('img', function(nodes, name, args) {
					var i = nodes.length, node;

					while (i--) {
						node = nodes[i];
						if ((node.attr('class') || '').indexOf('mceItemMedia') !== -1)
							self.imgToObject(node, args);
					}
				});
			});

			ed.onInit.add(function() {
				// Display "media" instead of "img" in element path
				if (ed.theme && ed.theme.onResolveName) {
					ed.theme.onResolveName.add(function(theme, path_object) {
						if (path_object.name === 'img' && ed.dom.hasClass(path_object.node, 'mceItemMedia'))
							path_object.name = 'media';
					});
				}

				// Add contect menu if it's loaded
				if (ed && ed.plugins.contextmenu) {
					ed.plugins.contextmenu.onContextMenu.add(function(plugin, menu, element) {
						if (element.nodeName === 'IMG' && element.className.indexOf('mceItemMedia') !== -1)
							menu.add({title : 'media.edit', icon : 'media', cmd : 'mceMedia'});
					});
				}
			});

			// Register commands
			ed.addCommand('mceMedia', function() {
				var data, img;

				img = ed.selection.getNode();
				if (isMediaImg(img)) {
					data = ed.dom.getAttrib(img, 'data-mce-json');
					if (data) {
						data = JSON.parse(data);

						// Add some extra properties to the data object
						tinymce.each(rootAttributes, function(name) {
							var value = ed.dom.getAttrib(img, name);

							if (value)
								data[name] = value;
						});

						data.type = self.getType(img.className).name.toLowerCase();
					}
				}

				if (!data) {
					data = {
						type : 'flash',
						video: {sources:[]},
						params: {}
					};
				}

				ed.windowManager.open({
					file : url + '/media.htm',
					width : 430 + parseInt(ed.getLang('media.delta_width', 0)),
					height : 500 + parseInt(ed.getLang('media.delta_height', 0)),
					inline : 1
				}, {
					plugin_url : url,
					data : data
				});
			});

			// Register buttons
			ed.addButton('media', {title : 'media.desc', cmd : 'mceMedia'});

			// Update media selection status
			ed.onNodeChange.add(function(ed, cm, node) {
				cm.setActive('media', isMediaImg(node));
			});
		},

		convertUrl : function(url, force_absolute) {
			var self = this, editor = self.editor, settings = editor.settings,
				urlConverter = settings.url_converter,
				urlConverterScope = settings.url_converter_scope || self;

			if (!url)
				return url;

			if (force_absolute)
				return editor.documentBaseURI.toAbsolute(url);

			return urlConverter.call(urlConverterScope, url, 'src', 'object');
		},

		getInfo : function() {
			return {
				longname : 'Media',
				author : 'Moxiecode Systems AB',
				authorurl : 'http://tinymce.moxiecode.com',
				infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/media',
				version : tinymce.majorVersion + "." + tinymce.minorVersion
			};
		},

		/**
		 * Converts the JSON data object to an img node.
		 */
		dataToImg : function(data, force_absolute) {
			var self = this, editor = self.editor, baseUri = editor.documentBaseURI, sources, attrs, img, i;

			data.params.src = self.convertUrl(data.params.src, force_absolute);

			attrs = data.video.attrs;
			if (attrs)
				attrs.src = self.convertUrl(attrs.src, force_absolute);

			if (attrs)
				attrs.poster = self.convertUrl(attrs.poster, force_absolute);

			sources = toArray(data.video.sources);
			if (sources) {
				for (i = 0; i < sources.length; i++)
					sources[i].src = self.convertUrl(sources[i].src, force_absolute);
			}

			img = self.editor.dom.create('img', {
				id : data.id,
				style : data.style,
				align : data.align,
				src : self.editor.theme.url + '/img/trans.gif',
				'class' : 'mceItemMedia mceItem' + self.getType(data.type).name,
				'data-mce-json' : JSON.serialize(data, "'")
			});

			img.width = data.width || "320";
			img.height = data.height || "240";

			return img;
		},

		/**
		 * Converts the JSON data object to a HTML string.
		 */
		dataToHtml : function(data, force_absolute) {
			return this.editor.serializer.serialize(this.dataToImg(data, force_absolute), {forced_root_block : '', force_absolute : force_absolute});
		},

		/**
		 * Converts the JSON data object to a HTML string.
		 */
		htmlToData : function(html) {
			var fragment, img, data;

			data = {
				type : 'flash',
				video: {sources:[]},
				params: {}
			};

			fragment = this.editor.parser.parse(html);
			img = fragment.getAll('img')[0];

			if (img) {
				data = JSON.parse(img.attr('data-mce-json'));
				data.type = this.getType(img.attr('class')).name.toLowerCase();

				// Add some extra properties to the data object
				tinymce.each(rootAttributes, function(name) {
					var value = img.attr(name);

					if (value)
						data[name] = value;
				});
			}

			return data;
		},

		/**
		 * Get type item by extension, class, clsid or mime type.
		 *
		 * @method getType
		 * @param {String} value Value to get type item by.
		 * @return {Object} Type item object or undefined.
		 */
		getType : function(value) {
			var i, values, typeItem;

			// Find type by checking the classes
			values = tinymce.explode(value, ' ');
			for (i = 0; i < values.length; i++) {
				typeItem = this.lookup[values[i]];

				if (typeItem)
					return typeItem;
			}
		},

		/**
		 * Converts a tinymce.html.Node image element to video/object/embed.
		 */
		imgToObject : function(node, args) {
			var self = this, editor = self.editor, video, object, embed, iframe, name, value, data,
				source, sources, params, param, typeItem, i, item, mp4Source, replacement,
				posterSrc, style;

			// Adds the flash player
			function addPlayer(video_src, poster_src) {
				var baseUri, flashVars, flashVarsOutput, params, flashPlayer;

				flashPlayer = editor.getParam('flash_video_player_url', self.convertUrl(self.url + '/moxieplayer.swf'));
				if (flashPlayer) {
					baseUri = editor.documentBaseURI;
					data.params.src = flashPlayer;

					// Convert the movie url to absolute urls
					if (editor.getParam('flash_video_player_absvideourl', true)) {
						video_src = baseUri.toAbsolute(video_src || '', true);
						poster_src = baseUri.toAbsolute(poster_src || '', true);
					}

					// Generate flash vars
					flashVarsOutput = '';
					flashVars = editor.getParam('flash_video_player_flashvars', {url : '$url', poster : '$poster'});
					tinymce.each(flashVars, function(value, name) {
						// Replace $url and $poster variables in flashvars value
						value = value.replace(/\$url/, video_src || '');
						value = value.replace(/\$poster/, poster_src || '');

						if (value.length > 0)
							flashVarsOutput += (flashVarsOutput ? '&' : '') + name + '=' + escape(value);
					});

					if (flashVarsOutput.length)
						data.params.flashvars = flashVarsOutput;

					params = editor.getParam('flash_video_player_params', {
						allowfullscreen: true,
						allowscriptaccess: true
					});

					tinymce.each(params, function(value, name) {
						data.params[name] = "" + value;
					});
				}
			};

			data = node.attr('data-mce-json');
			if (!data)
				return;

			data = JSON.parse(data);
			typeItem = this.getType(node.attr('class'));

			style = node.attr('data-mce-style')
			if (!style) {
				style = node.attr('style');

				if (style)
					style = editor.dom.serializeStyle(editor.dom.parseStyle(style, 'img'));
			}

			// Handle iframe
			if (typeItem.name === 'Iframe') {
				replacement = new Node('iframe', 1);

				tinymce.each(rootAttributes, function(name) {
					var value = node.attr(name);

					if (name == 'class' && value)
						value = value.replace(/mceItem.+ ?/g, '');

					if (value && value.length > 0)
						replacement.attr(name, value);
				});

				for (name in data.params)
					replacement.attr(name, data.params[name]);

				replacement.attr({
					style: style,
					src: data.params.src
				});

				node.replace(replacement);

				return;
			}

			// Handle scripts
			if (this.editor.settings.media_use_script) {
				replacement = new Node('script', 1).attr('type', 'text/javascript');

				value = new Node('#text', 3);
				value.value = 'write' + typeItem.name + '(' + JSON.serialize(tinymce.extend(data.params, {
					width: node.attr('width'),
					height: node.attr('height')
				})) + ');';

				replacement.append(value);
				node.replace(replacement);

				return;
			}

			// Add HTML5 video element
			if (typeItem.name === 'Video' && data.video.sources[0]) {
				// Create new object element
				video = new Node('video', 1).attr(tinymce.extend({
					id : node.attr('id'),
					width: node.attr('width'),
					height: node.attr('height'),
					style : style
				}, data.video.attrs));

				// Get poster source and use that for flash fallback
				if (data.video.attrs)
					posterSrc = data.video.attrs.poster;

				sources = data.video.sources = toArray(data.video.sources);
				for (i = 0; i < sources.length; i++) {
					if (/\.mp4$/.test(sources[i].src))
						mp4Source = sources[i].src;
				}

				if (!sources[0].type) {
					video.attr('src', sources[0].src);
					sources.splice(0, 1);
				}

				for (i = 0; i < sources.length; i++) {
					source = new Node('source', 1).attr(sources[i]);
					source.shortEnded = true;
					video.append(source);
				}

				// Create flash fallback for video if we have a mp4 source
				if (mp4Source) {
					addPlayer(mp4Source, posterSrc);
					typeItem = self.getType('flash');
				} else
					data.params.src = '';
			}

			// Do we have a params src then we can generate object
			if (data.params.src) {
				// Is flv movie add player for it
				if (/\.flv$/i.test(data.params.src))
					addPlayer(data.params.src, '');

				if (args && args.force_absolute)
					data.params.src = editor.documentBaseURI.toAbsolute(data.params.src);

				// Create new object element
				object = new Node('object', 1).attr({
					id : node.attr('id'),
					width: node.attr('width'),
					height: node.attr('height'),
					style : style
				});

				tinymce.each(rootAttributes, function(name) {
					if (data[name] && name != 'type')
						object.attr(name, data[name]);
				});

				// Add params
				for (name in data.params) {
					param = new Node('param', 1);
					param.shortEnded = true;
					value = data.params[name];

					// Windows media needs to use url instead of src for the media URL
					if (name === 'src' && typeItem.name === 'WindowsMedia')
						name = 'url';

					param.attr({name: name, value: value});
					object.append(param);
				}

				// Setup add type and classid if strict is disabled
				if (this.editor.getParam('media_strict', true)) {
					object.attr({
						data: data.params.src,
						type: typeItem.mimes[0]
					});
				} else {
					object.attr({
						classid: "clsid:" + typeItem.clsids[0],
						codebase: typeItem.codebase
					});

					embed = new Node('embed', 1);
					embed.shortEnded = true;
					embed.attr({
						id: node.attr('id'),
						width: node.attr('width'),
						height: node.attr('height'),
						style : style,
						type: typeItem.mimes[0]
					});

					for (name in data.params)
						embed.attr(name, data.params[name]);

					tinymce.each(rootAttributes, function(name) {
						if (data[name] && name != 'type')
							embed.attr(name, data[name]);
					});

					object.append(embed);
				}

				// Insert raw HTML
				if (data.object_html) {
					value = new Node('#text', 3);
					value.raw = true;
					value.value = data.object_html;
					object.append(value);
				}

				// Append object to video element if it exists
				if (video)
					video.append(object);
			}

			if (video) {
				// Insert raw HTML
				if (data.video_html) {
					value = new Node('#text', 3);
					value.raw = true;
					value.value = data.video_html;
					video.append(value);
				}
			}

			if (video || object)
				node.replace(video || object);
			else
				node.remove();
		},

		/**
		 * Converts a tinymce.html.Node video/object/embed to an img element.
		 *
		 * The video/object/embed will be converted into an image placeholder with a JSON data attribute like this:
		 * <img class="mceItemMedia mceItemFlash" width="100" height="100" data-mce-json="{..}" />
		 *
		 * The JSON structure will be like this:
		 * {'params':{'flashvars':'something','quality':'high','src':'someurl'}, 'video':{'sources':[{src: 'someurl', type: 'video/mp4'}]}}
		 */
		objectToImg : function(node) {
			var object, embed, video, iframe, img, name, id, width, height, style, i, html,
				param, params, source, sources, data, type, lookup = this.lookup,
				matches, attrs, urlConverter = this.editor.settings.url_converter,
				urlConverterScope = this.editor.settings.url_converter_scope;

			function getInnerHTML(node) {
				return new tinymce.html.Serializer({
					inner: true,
					validate: false
				}).serialize(node);
			};

			// If node isn't in document
			if (!node.parent)
				return;

			// Handle media scripts
			if (node.name === 'script') {
				if (node.firstChild)
					matches = scriptRegExp.exec(node.firstChild.value);

				if (!matches)
					return;

				type = matches[1];
				data = {video : {}, params : JSON.parse(matches[2])};
				width = data.params.width;
				height = data.params.height;
			}

			// Setup data objects
			data = data || {
				video : {},
				params : {}
			};

			// Setup new image object
			img = new Node('img', 1);
			img.attr({
				src : this.editor.theme.url + '/img/trans.gif'
			});

			// Video element
			name = node.name;
			if (name === 'video') {
				video = node;
				object = node.getAll('object')[0];
				embed = node.getAll('embed')[0];
				width = video.attr('width');
				height = video.attr('height');
				id = video.attr('id');
				data.video = {attrs : {}, sources : []};

				// Get all video attributes
				attrs = data.video.attrs;
				for (name in video.attributes.map)
					attrs[name] = video.attributes.map[name];

				source = node.attr('src');
				if (source)
					data.video.sources.push({src : urlConverter.call(urlConverterScope, source, 'src', 'video')});

				// Get all sources
				sources = video.getAll("source");
				for (i = 0; i < sources.length; i++) {
					source = sources[i].remove();

					data.video.sources.push({
						src: urlConverter.call(urlConverterScope, source.attr('src'), 'src', 'source'),
						type: source.attr('type'),
						media: source.attr('media')
					});
				}

				// Convert the poster URL
				if (attrs.poster)
					attrs.poster = urlConverter.call(urlConverterScope, attrs.poster, 'poster', 'video');
			}

			// Object element
			if (node.name === 'object') {
				object = node;
				embed = node.getAll('embed')[0];
			}

			// Embed element
			if (node.name === 'embed')
				embed = node;

			// Iframe element
			if (node.name === 'iframe') {
				iframe = node;
				type = 'Iframe';
			}

			if (object) {
				// Get width/height
				width = width || object.attr('width');
				height = height || object.attr('height');
				style = style || object.attr('style');
				id = id || object.attr('id');

				// Get all object params
				params = object.getAll("param");
				for (i = 0; i < params.length; i++) {
					param = params[i];
					name = param.remove().attr('name');

					if (!excludedAttrs[name])
						data.params[name] = param.attr('value');
				}

				data.params.src = data.params.src || object.attr('data');
			}

			if (embed) {
				// Get width/height
				width = width || embed.attr('width');
				height = height || embed.attr('height');
				style = style || embed.attr('style');
				id = id || embed.attr('id');

				// Get all embed attributes
				for (name in embed.attributes.map) {
					if (!excludedAttrs[name] && !data.params[name])
						data.params[name] = embed.attributes.map[name];
				}
			}

			if (iframe) {
				// Get width/height
				width = iframe.attr('width');
				height = iframe.attr('height');
				style = style || iframe.attr('style');
				id = iframe.attr('id');

				tinymce.each(rootAttributes, function(name) {
					img.attr(name, iframe.attr(name));
				});

				// Get all iframe attributes
				for (name in iframe.attributes.map) {
					if (!excludedAttrs[name] && !data.params[name])
						data.params[name] = iframe.attributes.map[name];
				}
			}

			// Use src not movie
			if (data.params.movie) {
				data.params.src = data.params.src || data.params.movie;
				delete data.params.movie;
			}

			// Convert the URL to relative/absolute depending on configuration
			if (data.params.src)
				data.params.src = urlConverter.call(urlConverterScope, data.params.src, 'src', 'object');

			if (video)
				type = lookup.video.name;

			if (object && !type)
				type = (lookup[(object.attr('clsid') || '').toLowerCase()] || lookup[(object.attr('type') || '').toLowerCase()] || {}).name;

			if (embed && !type)
				type = (lookup[(embed.attr('type') || '').toLowerCase()] || {}).name;

			// Replace the video/object/embed element with a placeholder image containing the data
			node.replace(img);

			// Remove embed
			if (embed)
				embed.remove();

			// Serialize the inner HTML of the object element
			if (object) {
				html = getInnerHTML(object.remove());

				if (html)
					data.object_html = html;
			}

			// Serialize the inner HTML of the video element
			if (video) {
				html = getInnerHTML(video.remove());

				if (html)
					data.video_html = html;
			}

			// Set width/height of placeholder
			img.attr({
				id : id,
				'class' : 'mceItemMedia mceItem' + (type || 'Flash'),
				style : style,
				width : width || "320",
				height : height || "240",
				"data-mce-json" : JSON.serialize(data, "'")
			});
		}
	});

	// Register plugin
	tinymce.PluginManager.add('media', tinymce.plugins.MediaPlugin);
})();


code:
/**
 * This script contains embed functions for common plugins. This scripts are complety free to use for any purpose.
 */

function writeFlash(p) {
	writeEmbed(
		'D27CDB6E-AE6D-11cf-96B8-444553540000',
		'http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0',
		'application/x-shockwave-flash',
		p
	);
}

function writeShockWave(p) {
	writeEmbed(
	'166B1BCA-3F9C-11CF-8075-444553540000',
	'http://download.macromedia.com/pub/shockwave/cabs/director/sw.cab#version=8,5,1,0',
	'application/x-director',
		p
	);
}

function writeQuickTime(p) {
	writeEmbed(
		'02BF25D5-8C17-4B23-BC80-D3488ABDDC6B',
		'http://www.apple.com/qtactivex/qtplugin.cab#version=6,0,2,0',
		'video/quicktime',
		p
	);
}

function writeRealMedia(p) {
	writeEmbed(
		'CFCDAA03-8BE4-11cf-B84B-0020AFBBCCFA',
		'http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0',
		'audio/x-pn-realaudio-plugin',
		p
	);
}

function writeWindowsMedia(p) {
	p.url = p.src;
	writeEmbed(
		'6BF52A52-394A-11D3-B153-00C04F79FAA6',
		'http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=5,1,52,701',
		'application/x-mplayer2',
		p
	);
}

function writeEmbed(cls, cb, mt, p) {
	var h = '', n;

	h += '<object classid="clsid:' + cls + '" codebase="' + cb + '"';
	h += typeof(p.id) != "undefined" ? 'id="' + p.id + '"' : '';
	h += typeof(p.name) != "undefined" ? 'name="' + p.name + '"' : '';
	h += typeof(p.width) != "undefined" ? 'width="' + p.width + '"' : '';
	h += typeof(p.height) != "undefined" ? 'height="' + p.height + '"' : '';
	h += typeof(p.align) != "undefined" ? 'align="' + p.align + '"' : '';
	h += '>';

	for (n in p)
		h += '<param name="' + n + '" value="' + p[n] + '">';

	h += '<embed type="' + mt + '"';

	for (n in p)
		h += n + '="' + p[n] + '" ';

	h += '></embed></object>';

	document.write(h);
}


code:
(function() {
	var url;

	if (url = tinyMCEPopup.getParam("media_external_list_url"))
		document.write('<script language="javascript" type="text/javascript" src="' + tinyMCEPopup.editor.documentBaseURI.toAbsolute(url) + '"></script>');

	function get(id) {
		return document.getElementById(id);
	}

	function getVal(id) {
		var elm = get(id);

		if (elm.nodeName == "SELECT")
			return elm.options[elm.selectedIndex].value;

		if (elm.type == "checkbox")
			return elm.checked;

		return elm.value;
	}

	function setVal(id, value, name) {
		if (typeof(value) != 'undefined') {
			var elm = get(id);

			if (elm.nodeName == "SELECT")
				selectByValue(document.forms[0], id, value);
			else if (elm.type == "checkbox") {
				if (typeof(value) == 'string') {
					value = value.toLowerCase();
					value = (!name && value === 'true') || (name && value === name.toLowerCase());
				}
				elm.checked = !!value;
			} else
				elm.value = value;
		}
	}

	window.Media = {
		init : function() {
			var html, editor;

			this.editor = editor = tinyMCEPopup.editor;

			// Setup file browsers and color pickers
			get('filebrowsercontainer').innerHTML = getBrowserHTML('filebrowser','src','media','media');
			get('qtsrcfilebrowsercontainer').innerHTML = getBrowserHTML('qtsrcfilebrowser','quicktime_qtsrc','media','media');
			get('bgcolor_pickcontainer').innerHTML = getColorPickerHTML('bgcolor_pick','bgcolor');
			get('video_altsource1_filebrowser').innerHTML = getBrowserHTML('filebrowser_altsource1','video_altsource1','media','media');
			get('video_altsource2_filebrowser').innerHTML = getBrowserHTML('filebrowser_altsource2','video_altsource2','media','media');
			get('video_poster_filebrowser').innerHTML = getBrowserHTML('filebrowser_poster','video_poster','media','image');

			html = this.getMediaListHTML('medialist', 'src', 'media', 'media');
			if (html == "")
				get("linklistrow").style.display = 'none';
			else
				get("linklistcontainer").innerHTML = html;

			if (isVisible('filebrowser'))
				get('src').style.width = '230px';

			if (isVisible('filebrowser_altsource1'))
				get('video_altsource1').style.width = '220px';

			if (isVisible('filebrowser_altsource2'))
				get('video_altsource2').style.width = '220px';

			if (isVisible('filebrowser_poster'))
				get('video_poster').style.width = '220px';

			this.data = tinyMCEPopup.getWindowArg('data');
			this.dataToForm();
			this.preview();
		},

		insert : function() {
			var editor = tinyMCEPopup.editor;

			this.formToData();
			editor.execCommand('mceRepaint');
			tinyMCEPopup.restoreSelection();
			editor.selection.setNode(editor.plugins.media.dataToImg(this.data));
			tinyMCEPopup.close();
		},

		preview : function() {
			get('prev').innerHTML = this.editor.plugins.media.dataToHtml(this.data, true);
		},

		moveStates : function(to_form, field) {
			var data = this.data, editor = this.editor, data = this.data,
				mediaPlugin = editor.plugins.media, ext, src, typeInfo, defaultStates, src;

			defaultStates = {
				// QuickTime
				quicktime_autoplay : true,
				quicktime_controller : true,

				// Flash
				flash_play : true,
				flash_loop : true,
				flash_menu : true,

				// WindowsMedia
				windowsmedia_autostart : true,
				windowsmedia_enablecontextmenu : true,
				windowsmedia_invokeurls : true,

				// RealMedia
				realmedia_autogotourl : true,
				realmedia_imagestatus : true
			};

			function parseQueryParams(str) {
				var out = {};

				if (str) {
					tinymce.each(str.split('&'), function(item) {
						var parts = item.split('=');

						out[unescape(parts[0])] = unescape(parts[1]);
					});
				}

				return out;
			};

			function setOptions(type, names) {
				var i, name, formItemName, value, list;

				if (type == data.type || type == 'global') {
					names = tinymce.explode(names);
					for (i = 0; i < names.length; i++) {
						name = names[i];
						formItemName = type == 'global' ? name : type + '_' + name;

						if (type == 'global')
							list = data;
						else if (type == 'video') {
							list = data.video.attrs;

							if (!list && !to_form)
								data.video.attrs = list = {};
						} else
							list = data.params;

						if (list) {
							if (to_form) {
								setVal(formItemName, list[name], type == 'video' ? name : '');
							} else {
								delete list[name];

								value = getVal(formItemName);
								if (type == 'video' && value === true)
									value = name;

								if (defaultStates[formItemName]) {
									if (value !== defaultStates[formItemName]) {
										value = "" + value;
										list[name] = value;
									}
								} else if (value) {
									value = "" + value;
									list[name] = value;
								}
							}
						}
					}
				}
			}

			if (!to_form) {
				data.type = get('media_type').options[get('media_type').selectedIndex].value;
				data.width = getVal('width');
				data.height = getVal('height');

				// Switch type based on extension
				src = getVal('src');
				if (field == 'src') {
					ext = src.replace(/^.*\.([^.]+)$/, '$1');
					if (typeInfo = mediaPlugin.getType(ext))
						data.type = typeInfo.name.toLowerCase();

					setVal('media_type', data.type);
				}

				if (data.type == "video") {
					if (!data.video.sources)
						data.video.sources = [];

					data.video.sources[0] = {src: getVal('src')};
				}
			}

			// Hide all fieldsets and show the one active
			get('video_options').style.display = 'none';
			get('flash_options').style.display = 'none';
			get('quicktime_options').style.display = 'none';
			get('shockwave_options').style.display = 'none';
			get('windowsmedia_options').style.display = 'none';
			get('realmedia_options').style.display = 'none';

			if (get(data.type + '_options'))
				get(data.type + '_options').style.display = 'block';

			setVal('media_type', data.type);

			setOptions('flash', 'play,loop,menu,swliveconnect,quality,scale,salign,wmode,base,flashvars');
			setOptions('quicktime', 'loop,autoplay,cache,controller,correction,enablejavascript,kioskmode,autohref,playeveryframe,targetcache,scale,starttime,endtime,target,qtsrcchokespeed,volume,qtsrc');
			setOptions('shockwave', 'sound,progress,autostart,swliveconnect,swvolume,swstretchstyle,swstretchhalign,swstretchvalign');
			setOptions('windowsmedia', 'autostart,enabled,enablecontextmenu,fullscreen,invokeurls,mute,stretchtofit,windowlessvideo,balance,baseurl,captioningid,currentmarker,currentposition,defaultframe,playcount,rate,uimode,volume');
			setOptions('realmedia', 'autostart,loop,autogotourl,center,imagestatus,maintainaspect,nojava,prefetch,shuffle,console,controls,numloop,scriptcallbacks');
			setOptions('video', 'poster,autoplay,loop,preload,controls');
			setOptions('global', 'id,name,vspace,hspace,bgcolor,align,width,height');

			if (to_form) {
				if (data.type == 'video') {
					if (data.video.sources[0])
						setVal('src', data.video.sources[0].src);

					src = data.video.sources[1];
					if (src)
						setVal('video_altsource1', src.src);

					src = data.video.sources[2];
					if (src)
						setVal('video_altsource2', src.src);
				} else {
					// Check flash vars
					if (data.type == 'flash') {
						tinymce.each(editor.getParam('flash_video_player_flashvars', {url : '$url', poster : '$poster'}), function(value, name) {
							if (value == '$url')
								data.params.src = parseQueryParams(data.params.flashvars)[name] || data.params.src;
						});
					}

					setVal('src', data.params.src);
				}
			} else {
				src = getVal("src");

				// YouTube
				if (src.match(/youtube.com(.+)v=([^&]+)/)) {
					data.width = 425;
					data.height = 350;
					data.params.frameborder = '0';
					data.type = 'iframe';
					src = 'http://www.youtube.com/embed/' + src.match(/v=([^&]+)/)[1];
					setVal('src', src);
					setVal('media_type', data.type);
				}

				// Google video
				if (src.match(/video.google.com(.+)docid=([^&]+)/)) {
					data.width = 425;
					data.height = 326;
					data.type = 'flash';
					src = 'http://video.google.com/googleplayer.swf?docId=' + src.match(/docid=([^&]+)/)[1] + '&hl=en';
					setVal('src', src);
					setVal('media_type', data.type);
				}

				if (data.type == 'video') {
					if (!data.video.sources)
						data.video.sources = [];

					data.video.sources[0] = {src : src};

					src = getVal("video_altsource1");
					if (src)
						data.video.sources[1] = {src : src};

					src = getVal("video_altsource2");
					if (src)
						data.video.sources[2] = {src : src};
				} else
					data.params.src = src;

				// Set default size
				setVal('width', data.width || 320);
				setVal('height', data.height || 240);
			}
		},

		dataToForm : function() {
			this.moveStates(true);
		},

		formToData : function(field) {
			if (field == "width" || field == "height")
				this.changeSize(field);

			if (field == 'source') {
				this.moveStates(false, field);
				setVal('source', this.editor.plugins.media.dataToHtml(this.data));
				this.panel = 'source';
			} else {
				if (this.panel == 'source') {
					this.data = this.editor.plugins.media.htmlToData(getVal('source'));
					this.dataToForm();
					this.panel = '';
				}

				this.moveStates(false, field);
				this.preview();
			}
		},

		beforeResize : function() {
			this.width = parseInt(getVal('width') || "320", 10);
			this.height = parseInt(getVal('height') || "240", 10);
		},

		changeSize : function(type) {
			var width, height, scale, size;

			if (get('constrain').checked) {
				width = parseInt(getVal('width') || "320", 10);
				height = parseInt(getVal('height') || "240", 10);

				if (type == 'width') {
					this.height = Math.round((width / this.width) * height);
					setVal('height', this.height);
				} else {
					this.width = Math.round((height / this.height) * width);
					setVal('width', this.width);
				}
			}
		},

		getMediaListHTML : function() {
			if (typeof(tinyMCEMediaList) != "undefined" && tinyMCEMediaList.length > 0) {
				var html = "";

				html += '<select id="linklist" name="linklist" style="width: 250px" onchange="this.form.src.value=this.options[this.selectedIndex].value;Media.formToData(\'src\');">';
				html += '<option value="">---</option>';

				for (var i=0; i<tinyMCEMediaList.length; i++)
					html += '<option value="' + tinyMCEMediaList[i][1] + '">' + tinyMCEMediaList[i][0] + '</option>';

				html += '</select>';

				return html;
			}

			return "";
		}
	};

	tinyMCEPopup.requireLangPack();
	tinyMCEPopup.onInit.add(function() {
		Media.init();
	});
})();