code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

	<title>{#advlink_dlg.title}</title>

	<link href="css/advlink.css" rel="stylesheet" type="text/css" />

	{#advlink_dlg.title}
	<form onsubmit="insertAction();return false;" action="#">

{#advlink_dlg.general_tab}

{#advlink_dlg.popup_tab}

{#advlink_dlg.events_tab}

{#advlink_dlg.advanced_tab}

				<fieldset>
					<legend>{#advlink_dlg.general_props}</legend>

							{#advlink_dlg.url}

								<input id="href" name="href" type="text" class="mceFocus" value="" onchange="selectByValue(this.form,'linklisthref',this.value);" aria-required="true" />

							{#advlink_dlg.list}
							<select id="linklisthref"><option value=""></option></select>

							{#advlink_dlg.anchor_names}
							<select id="anchorlist"><option value=""></option></select>

							{#advlink_dlg.target}
							<select id="targetlist"><option value=""></option></select>

							{#advlink_dlg.titlefield}
							<input id="title" name="title" type="text" value="" />

							{#class_name}

								 <select id="classlist" name="classlist" onchange="changeClass();">
									<option value="" selected="selected">{#not_set}</option>
								 </select>

				</fieldset>

				<fieldset>
					<legend>{#advlink_dlg.popup_props}</legend>

					<input type="checkbox" id="ispopup" name="ispopup" class="radio" onclick="setPopupControlsDisabled(!this.checked);buildOnClick();" />
					{#advlink_dlg.popup}

							{#advlink_dlg.popup_url}

										<input type="text" name="popupurl" id="popupurl" value="" onchange="buildOnClick();" />

							{#advlink_dlg.popup_name}
							<input type="text" name="popupname" id="popupname" value="" onchange="buildOnClick();" />

							{#advlink_dlg.popup_size}

								{#advlink_dlg.width}
								<input type="text" id="popupwidth" name="popupwidth" value="" onchange="buildOnClick();" aria-labelledby="width_voiceLabel" /> x
								{#advlink_dlg.height}
								<input type="text" id="popupheight" name="popupheight" value="" onchange="buildOnClick();" aria-labelledby="height_voiceLabel" /> px

							{#advlink_dlg.popup_position}

								X
								<input type="text" id="popupleft" name="popupleft" value="" onchange="buildOnClick();" aria-labelledby="x_voiceLabel" /> /
								Y
								<input type="text" id="popuptop" name="popuptop" value="" onchange="buildOnClick();" aria-labelledby="y_voiceLabel" /> (c /c = center)

					<fieldset>
						<legend>{#advlink_dlg.popup_opts}</legend>

								<input type="checkbox" id="popuplocation" name="popuplocation" class="checkbox" onchange="buildOnClick();" />
								{#advlink_dlg.popup_location}
								<input type="checkbox" id="popupscrollbars" name="popupscrollbars" class="checkbox" onchange="buildOnClick();" />
								{#advlink_dlg.popup_scrollbars}

								<input type="checkbox" id="popupmenubar" name="popupmenubar" class="checkbox" onchange="buildOnClick();" />
								{#advlink_dlg.popup_menubar}
								<input type="checkbox" id="popupresizable" name="popupresizable" class="checkbox" onchange="buildOnClick();" />
								{#advlink_dlg.popup_resizable}

								<input type="checkbox" id="popuptoolbar" name="popuptoolbar" class="checkbox" onchange="buildOnClick();" />
								{#advlink_dlg.popup_toolbar}
								<input type="checkbox" id="popupdependent" name="popupdependent" class="checkbox" onchange="buildOnClick();" />
								{#advlink_dlg.popup_dependent}

								<input type="checkbox" id="popupstatus" name="popupstatus" class="checkbox" onchange="buildOnClick();" />
								{#advlink_dlg.popup_statusbar}
								<input type="checkbox" id="popupreturn" name="popupreturn" class="checkbox" onchange="buildOnClick();" checked="checked" />
								{#advlink_dlg.popup_return}

					</fieldset>
				</fieldset>

			<fieldset>
					<legend>{#advlink_dlg.advanced_props}</legend>

							{#advlink_dlg.id}
							<input id="id" name="id" type="text" value="" />

							{#advlink_dlg.style}
							<input type="text" id="style" name="style" value="" />

							{#advlink_dlg.classes}
							<input type="text" id="classes" name="classes" value="" onchange="selectByValue(this.form,'classlist',this.value,true);" />

							{#advlink_dlg.target_name}
							<input type="text" id="target" name="target" value="" onchange="selectByValue(this.form,'targetlist',this.value,true);" />

							{#advlink_dlg.langdir}

								<select id="dir" name="dir">
										<option value="">{#not_set}</option>
										<option value="ltr">{#advlink_dlg.ltr}</option>
										<option value="rtl">{#advlink_dlg.rtl}</option>
								</select>

							{#advlink_dlg.target_langcode}
							<input type="text" id="hreflang" name="hreflang" value="" />

							{#advlink_dlg.langcode}

								<input id="lang" name="lang" type="text" value="" />

							{#advlink_dlg.encoding}
							<input type="text" id="charset" name="charset" value="" />

							{#advlink_dlg.mime}
							<input type="text" id="type" name="type" value="" />

							{#advlink_dlg.rel}
							<select id="rel" name="rel">
									<option value="">{#not_set}</option>
									<option value="lightbox">Lightbox</option>
									<option value="alternate">Alternate</option>
									<option value="designates">Designates</option>
									<option value="stylesheet">Stylesheet</option>
									<option value="start">Start</option>
									<option value="next">Next</option>
									<option value="prev">Prev</option>
									<option value="contents">Contents</option>
									<option value="index">Index</option>
									<option value="glossary">Glossary</option>
									<option value="copyright">Copyright</option>
									<option value="chapter">Chapter</option>
									<option value="subsection">Subsection</option>
									<option value="appendix">Appendix</option>
									<option value="help">Help</option>
									<option value="bookmark">Bookmark</option>
									<option value="nofollow">No Follow</option>
									<option value="tag">Tag</option>
								</select>

							{#advlink_dlg.rev}
							<select id="rev" name="rev">
									<option value="">{#not_set}</option>
									<option value="alternate">Alternate</option>
									<option value="designates">Designates</option>
									<option value="stylesheet">Stylesheet</option>
									<option value="start">Start</option>
									<option value="next">Next</option>
									<option value="prev">Prev</option>
									<option value="contents">Contents</option>
									<option value="index">Index</option>
									<option value="glossary">Glossary</option>
									<option value="copyright">Copyright</option>
									<option value="chapter">Chapter</option>
									<option value="subsection">Subsection</option>
									<option value="appendix">Appendix</option>
									<option value="help">Help</option>
									<option value="bookmark">Bookmark</option>
								</select>

							{#advlink_dlg.tabindex}
							<input type="text" id="tabindex" name="tabindex" value="" />

							{#advlink_dlg.accesskey}
							<input type="text" id="accesskey" name="accesskey" value="" />

				</fieldset>

			<fieldset>
					<legend>{#advlink_dlg.event_props}</legend>

							onfocus
							<input id="onfocus" name="onfocus" type="text" value="" />

							onblur
							<input id="onblur" name="onblur" type="text" value="" />

							onclick
							<input id="onclick" name="onclick" type="text" value="" />

							ondblclick
							<input id="ondblclick" name="ondblclick" type="text" value="" />

							onmousedown
							<input id="onmousedown" name="onmousedown" type="text" value="" />

							onmouseup
							<input id="onmouseup" name="onmouseup" type="text" value="" />

							onmouseover
							<input id="onmouseover" name="onmouseover" type="text" value="" />

							onmousemove
							<input id="onmousemove" name="onmousemove" type="text" value="" />

							onmouseout
							<input id="onmouseout" name="onmouseout" type="text" value="" />

							onkeypress
							<input id="onkeypress" name="onkeypress" type="text" value="" />

							onkeydown
							<input id="onkeydown" name="onkeydown" type="text" value="" />

							onkeyup
							<input id="onkeyup" name="onkeyup" type="text" value="" />

				</fieldset>

			<input type="submit" id="insert" name="insert" value="{#insert}" />
			<input type="button" id="cancel" name="cancel" value="{#cancel}" onclick="tinyMCEPopup.close();" />

	</form>


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 each = tinymce.each;

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

			t.editor = ed;

			function buildFormats(str) {
				var formats = [];

				each(str.split(/,/), function(type) {
					formats.push({
						title : 'advlist.' + (type == 'default' ? 'def' : type.replace(/-/g, '_')),
						styles : {
							listStyleType : type == 'default' ? '' : type
						}
					});
				});

				return formats;
			};

			// Setup number formats from config or default
			t.numlist = ed.getParam("advlist_number_styles") || buildFormats("default,lower-alpha,lower-greek,lower-roman,upper-alpha,upper-roman");
			t.bullist = ed.getParam("advlist_bullet_styles") || buildFormats("default,circle,disc,square");

			if (tinymce.isIE && /MSIE [2-7]/.test(navigator.userAgent))
				t.isIE7 = true;
		},

		createControl: function(name, cm) {
			var t = this, btn, format;

			if (name == 'numlist' || name == 'bullist') {
				// Default to first item if it's a default item
				if (t[name][0].title == 'advlist.def')
					format = t[name][0];

				function hasFormat(node, format) {
					var state = true;

					each(format.styles, function(value, name) {
						// Format doesn't match
						if (t.editor.dom.getStyle(node, name) != value) {
							state = false;
							return false;
						}
					});

					return state;
				};

				function applyListFormat() {
					var list, ed = t.editor, dom = ed.dom, sel = ed.selection;

					// Check for existing list element
					list = dom.getParent(sel.getNode(), 'ol,ul');

					// Switch/add list type if needed
					if (!list || list.nodeName == (name == 'bullist' ? 'OL' : 'UL') || hasFormat(list, format))
						ed.execCommand(name == 'bullist' ? 'InsertUnorderedList' : 'InsertOrderedList');

					// Append styles to new list element
					if (format) {
						list = dom.getParent(sel.getNode(), 'ol,ul');
						if (list) {
							dom.setStyles(list, format.styles);
							list.removeAttribute('data-mce-style');
						}
					}
					ed.focus();
				};

				btn = cm.createSplitButton(name, {
					title : 'advanced.' + name + '_desc',
					'class' : 'mce_' + name,
					onclick : function() {
						applyListFormat();
					}
				});

				btn.onRenderMenu.add(function(btn, menu) {
					menu.onShowMenu.add(function() {
						var dom = t.editor.dom, list = dom.getParent(t.editor.selection.getNode(), 'ol,ul'), fmtList;

						if (list || format) {
							fmtList = t[name];

							// Unselect existing items
							each(menu.items, function(item) {
								var state = true;

								item.setSelected(0);

								if (list && !item.isDisabled()) {
									each(fmtList, function(fmt) {
										if (fmt.id == item.id) {
											if (!hasFormat(list, fmt)) {
												state = false;
												return false;
											}
										}
									});

									if (state)
										item.setSelected(1);
								}
							});

							// Select the current format
							if (!list)
								menu.items[format.id].setSelected(1);
						}
					});

					menu.add({id : t.editor.dom.uniqueId(), title : 'advlist.types', 'class' : 'mceMenuItemTitle', titleItem: true}).setDisabled(1);

					each(t[name], function(item) {
						// IE<8 doesn't support lower-greek, skip it
						if (t.isIE7 && item.styles.listStyleType == 'lower-greek')
							return;

						item.id = t.editor.dom.uniqueId();

						menu.add({id : item.id, title : item.title, onclick : function() {
							format = item;
							applyListFormat();
						}});
					});
				});

				return btn;
			}
		},

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

	// Register plugin
	tinymce.PluginManager.add('advlist', tinymce.plugins.AdvListPlugin);
})();

license: mit


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() {
	tinymce.create('tinymce.plugins.AutolinkPlugin', {
	/**
	* Initializes the plugin, this will be executed after the plugin has been created.
	* This call is done before the editor instance has finished it's initialization so use the onInit event
	* of the editor instance to intercept that event.
	*
	* @param {tinymce.Editor} ed Editor instance that the plugin is initialized in.
	* @param {string} url Absolute URL to where the plugin is located.
	*/

	init : function(ed, url) {
		var t = this;

		// Internet Explorer has built-in automatic linking
		if (tinyMCE.isIE)
			return;

		// Add a key down handler
		ed.onKeyDown.add(function(ed, e) {
			if (e.keyCode == 13)
				return t.handleEnter(ed);
			});

		ed.onKeyPress.add(function(ed, e) {
			if (e.which == 41)
				return t.handleEclipse(ed);
		});

		// Add a key up handler
		ed.onKeyUp.add(function(ed, e) {
			if (e.keyCode == 32)
				return t.handleSpacebar(ed);
			});
	       },

		handleEclipse : function(ed) {
			this.parseCurrentLine(ed, -1, '(', true);
		},

		handleSpacebar : function(ed) {
			 this.parseCurrentLine(ed, 0, '', true);
		 },

		handleEnter : function(ed) {
			this.parseCurrentLine(ed, -1, '', false);
		},

		parseCurrentLine : function(ed, end_offset, delimiter, goback) {
			var r, end, start, endContainer, bookmark, text, matches, prev, len;

			// We need at least five characters to form a URL,
			// hence, at minimum, five characters from the beginning of the line.
			r = ed.selection.getRng().cloneRange();
			if (r.startOffset < 5) {
				// During testing, the caret is placed inbetween two text nodes.
				// The previous text node contains the URL.
				prev = r.endContainer.previousSibling;
				if (prev == null) {
					if (r.endContainer.firstChild == null || r.endContainer.firstChild.nextSibling == null)
						return;

					prev = r.endContainer.firstChild.nextSibling;
				}
				len = prev.length;
				r.setStart(prev, len);
				r.setEnd(prev, len);

				if (r.endOffset < 5)
					return;

				end = r.endOffset;
				endContainer = prev;
			} else {
				endContainer = r.endContainer;

				// Get a text node
				if (endContainer.nodeType != 3 && endContainer.firstChild) {
					while (endContainer.nodeType != 3 && endContainer.firstChild)
						endContainer = endContainer.firstChild;

					r.setStart(endContainer, 0);
					r.setEnd(endContainer, endContainer.nodeValue.length);
				}

				if (r.endOffset == 1)
					end = 2;
				else
					end = r.endOffset - 1 - end_offset;
			}

			start = end;

			do
			{
				// Move the selection one character backwards.
				r.setStart(endContainer, end - 2);
				r.setEnd(endContainer, end - 1);
				end -= 1;

				// Loop until one of the following is found: a blank space,  , delimeter, (end-2) >= 0
			} while (r.toString() != ' ' && r.toString() != '' && r.toString().charCodeAt(0) != 160 && (end -2) >= 0 && r.toString() != delimiter);

			if (r.toString() == delimiter || r.toString().charCodeAt(0) == 160) {
				r.setStart(endContainer, end);
				r.setEnd(endContainer, start);
				end += 1;
			} else if (r.startOffset == 0) {
				r.setStart(endContainer, 0);
				r.setEnd(endContainer, start);
			}
			else {
				r.setStart(endContainer, end);
				r.setEnd(endContainer, start);
			}

			text = r.toString();
			matches = text.match(/^(https?:\/\/|ssh:\/\/|ftp:\/\/|file:\/|www\.)(.+)$/i);

			if (matches) {
				if (matches[1] == 'www.') {
					matches[1] = 'http://www.';
				}

				bookmark = ed.selection.getBookmark();

				ed.selection.setRng(r);
				tinyMCE.execCommand('mceInsertLink',false, matches[1] + matches[2]);
				ed.selection.moveToBookmark(bookmark);

				// TODO: Determine if this is still needed.
				if (tinyMCE.isWebKit) {
					// move the caret to its original position
					ed.selection.collapse(false);
					var max = Math.min(endContainer.length, start + 1);
					r.setStart(endContainer, max);
					r.setEnd(endContainer, max);
					ed.selection.setRng(r);
				}
			}
		},

		/**
		* Returns information about the plugin as a name/value array.
		* The current keys are longname, author, authorurl, infourl and version.
		*
		* @return {Object} Name/value array containing information about the plugin.
		*/
		getInfo : function() {
			return {
				longname : 'Autolink',
				author : 'Moxiecode Systems AB',
				authorurl : 'http://tinymce.moxiecode.com',
				infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/autolink',
				version : tinymce.majorVersion + "." + tinymce.minorVersion
			};
		}
	});

	// Register plugin
	tinymce.PluginManager.add('autolink', tinymce.plugins.AutolinkPlugin);
})();


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() {
	/**
	 * Auto Resize
	 *
	 * This plugin automatically resizes the content area to fit its content height.
	 * It will retain a minimum height, which is the height of the content area when
	 * it's initialized.
	 */
	tinymce.create('tinymce.plugins.AutoResizePlugin', {
		/**
		 * Initializes the plugin, this will be executed after the plugin has been created.
		 * This call is done before the editor instance has finished it's initialization so use the onInit event
		 * of the editor instance to intercept that event.
		 *
		 * @param {tinymce.Editor} ed Editor instance that the plugin is initialized in.
		 * @param {string} url Absolute URL to where the plugin is located.
		 */
		init : function(ed, url) {
			var t = this, oldSize = 0;

			if (ed.getParam('fullscreen_is_enabled'))
				return;

			/**
			 * This method gets executed each time the editor needs to resize.
			 */
			function resize() {
				var d = ed.getDoc(), b = d.body, de = d.documentElement, DOM = tinymce.DOM, resizeHeight = t.autoresize_min_height, myHeight;

				// Get height differently depending on the browser used
				myHeight = tinymce.isIE ? b.scrollHeight : d.body.offsetHeight;

				// Don't make it smaller than the minimum height
				if (myHeight > t.autoresize_min_height)
					resizeHeight = myHeight;

				// If a maximum height has been defined don't exceed this height
				if (t.autoresize_max_height && myHeight > t.autoresize_max_height) {
					resizeHeight = t.autoresize_max_height;
					ed.getBody().style.overflowY = "auto";
				} else
					ed.getBody().style.overflowY = "hidden";

				// Resize content element
				if (resizeHeight !== oldSize) {
					DOM.setStyle(DOM.get(ed.id + '_ifr'), 'height', resizeHeight + 'px');
					oldSize = resizeHeight;
				}

				// if we're throbbing, we'll re-throb to match the new size
				if (t.throbbing) {
					ed.setProgressState(false);
					ed.setProgressState(true);
				}
			};

			t.editor = ed;

			// Define minimum height
			t.autoresize_min_height = parseInt( ed.getParam('autoresize_min_height', ed.getElement().offsetHeight) );

			// Define maximum height
			t.autoresize_max_height = parseInt( ed.getParam('autoresize_max_height', 0) );

			// Add padding at the bottom for better UX
			ed.onInit.add(function(ed){
				ed.dom.setStyle(ed.getBody(), 'paddingBottom', ed.getParam('autoresize_bottom_margin', 50) + 'px');
			});

			// Add appropriate listeners for resizing content area
			ed.onChange.add(resize);
			ed.onSetContent.add(resize);
			ed.onPaste.add(resize);
			ed.onKeyUp.add(resize);
			ed.onPostRender.add(resize);

			if (ed.getParam('autoresize_on_init', true)) {
				// Things to do when the editor is ready
				ed.onInit.add(function(ed, l) {
					// Show throbber until content area is resized properly
					ed.setProgressState(true);
					t.throbbing = true;

					// Hide scrollbars
					ed.getBody().style.overflowY = "hidden";
				});

				ed.onLoadContent.add(function(ed, l) {
					resize();

					// Because the content area resizes when its content CSS loads,
					// and we can't easily add a listener to its onload event,
					// we'll just trigger a resize after a short loading period
					setTimeout(function() {
						resize();

						// Disable throbber
						ed.setProgressState(false);
						t.throbbing = false;
					}, 1250);
				});
			}

			// Register the command so that it can be invoked by using tinyMCE.activeEditor.execCommand('mceExample');
			ed.addCommand('mceAutoResize', resize);
		},

		/**
		 * Returns information about the plugin as a name/value array.
		 * The current keys are longname, author, authorurl, infourl and version.
		 *
		 * @return {Object} Name/value array containing information about the plugin.
		 */
		getInfo : function() {
			return {
				longname : 'Auto Resize',
				author : 'Moxiecode Systems AB',
				authorurl : 'http://tinymce.moxiecode.com',
				infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/autoresize',
				version : tinymce.majorVersion + "." + tinymce.minorVersion
			};
		}
	});

	// Register plugin
	tinymce.PluginManager.add('autoresize', tinymce.plugins.AutoResizePlugin);
})();


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
 *
 * Adds auto-save capability to the TinyMCE text editor to rescue content
 * inadvertently lost. This plugin was originally developed by Speednet
 * and that project can be found here: http://code.google.com/p/tinyautosave/
 *
 * TECHNOLOGY DISCUSSION:
 *
 * The plugin attempts to use the most advanced features available in the current browser to save
 * as much content as possible.  There are a total of four different methods used to autosave the
 * content.  In order of preference, they are:
 *
 * 1. localStorage - A new feature of HTML 5, localStorage can store megabytes of data per domain
 * on the client computer. Data stored in the localStorage area has no expiration date, so we must
 * manage expiring the data ourselves.  localStorage is fully supported by IE8, and it is supposed
 * to be working in Firefox 3 and Safari 3.2, but in reality is is flaky in those browsers.  As
 * HTML 5 gets wider support, the AutoSave plugin will use it automatically. In Windows Vista/7,
 * localStorage is stored in the following folder:
 * C:\Users\[username]\AppData\Local\Microsoft\Internet Explorer\DOMStore\[tempFolder]
 *
 * 2. sessionStorage - A new feature of HTML 5, sessionStorage works similarly to localStorage,
 * except it is designed to expire after a certain amount of time.  Because the specification
 * around expiration date/time is very loosely-described, it is preferrable to use locaStorage and
 * manage the expiration ourselves.  sessionStorage has similar storage characteristics to
 * localStorage, although it seems to have better support by Firefox 3 at the moment.  (That will
 * certainly change as Firefox continues getting better at HTML 5 adoption.)
 *
 * 3. UserData - A very under-exploited feature of Microsoft Internet Explorer, UserData is a
 * way to store up to 128K of data per "document", or up to 1MB of data per domain, on the client
 * computer.  The feature is available for IE 5+, which makes it available for every version of IE
 * supported by TinyMCE.  The content is persistent across browser restarts and expires on the
 * date/time specified, just like a cookie.  However, the data is not cleared when the user clears
 * cookies on the browser, which makes it well-suited for rescuing autosaved content.  UserData,
 * like other Microsoft IE browser technologies, is implemented as a behavior attached to a
 * specific DOM object, so in this case we attach the behavior to the same DOM element that the
 * TinyMCE editor instance is attached to.
 */

(function(tinymce) {
	// Setup constants to help the compressor to reduce script size
	var PLUGIN_NAME = 'autosave',
		RESTORE_DRAFT = 'restoredraft',
		TRUE = true,
		undefined,
		unloadHandlerAdded,
		Dispatcher = tinymce.util.Dispatcher;

	/**
	 * This plugin adds auto-save capability to the TinyMCE text editor to rescue content
	 * inadvertently lost. By using localStorage.
	 *
	 * @class tinymce.plugins.AutoSave
	 */
	tinymce.create('tinymce.plugins.AutoSave', {
		/**
		 * Initializes the plugin, this will be executed after the plugin has been created.
		 * This call is done before the editor instance has finished it's initialization so use the onInit event
		 * of the editor instance to intercept that event.
		 *
		 * @method init
		 * @param {tinymce.Editor} ed Editor instance that the plugin is initialized in.
		 * @param {string} url Absolute URL to where the plugin is located.
		 */
		init : function(ed, url) {
			var self = this, settings = ed.settings;

			self.editor = ed;

			// Parses the specified time string into a milisecond number 10m, 10s etc.
			function parseTime(time) {
				var multipels = {
					s : 1000,
					m : 60000
				};

				time = /^(\d+)([ms]?)$/.exec('' + time);

				return (time[2] ? multipels[time[2]] : 1) * parseInt(time);
			};

			// Default config
			tinymce.each({
				ask_before_unload : TRUE,
				interval : '30s',
				retention : '20m',
				minlength : 50
			}, function(value, key) {
				key = PLUGIN_NAME + '_' + key;

				if (settings[key] === undefined)
					settings[key] = value;
			});

			// Parse times
			settings.autosave_interval = parseTime(settings.autosave_interval);
			settings.autosave_retention = parseTime(settings.autosave_retention);

			// Register restore button
			ed.addButton(RESTORE_DRAFT, {
				title : PLUGIN_NAME + ".restore_content",
				onclick : function() {
					if (ed.getContent({draft: true}).replace(/\s| |<\/?p[^>]*>|<br[^>]*>/gi, "").length > 0) {
						// Show confirm dialog if the editor isn't empty
						ed.windowManager.confirm(
							PLUGIN_NAME + ".warning_message",
							function(ok) {
								if (ok)
									self.restoreDraft();
							}
						);
					} else
						self.restoreDraft();
				}
			});

			// Enable/disable restoredraft button depending on if there is a draft stored or not
			ed.onNodeChange.add(function() {
				var controlManager = ed.controlManager;

				if (controlManager.get(RESTORE_DRAFT))
					controlManager.setDisabled(RESTORE_DRAFT, !self.hasDraft());
			});

			ed.onInit.add(function() {
				// Check if the user added the restore button, then setup auto storage logic
				if (ed.controlManager.get(RESTORE_DRAFT)) {
					// Setup storage engine
					self.setupStorage(ed);

					// Auto save contents each interval time
					setInterval(function() {
						self.storeDraft();
						ed.nodeChanged();
					}, settings.autosave_interval);
				}
			});

			/**
			 * This event gets fired when a draft is stored to local storage.
			 *
			 * @event onStoreDraft
			 * @param {tinymce.plugins.AutoSave} sender Plugin instance sending the event.
			 * @param {Object} draft Draft object containing the HTML contents of the editor.
			 */
			self.onStoreDraft = new Dispatcher(self);

			/**
			 * This event gets fired when a draft is restored from local storage.
			 *
			 * @event onStoreDraft
			 * @param {tinymce.plugins.AutoSave} sender Plugin instance sending the event.
			 * @param {Object} draft Draft object containing the HTML contents of the editor.
			 */
			self.onRestoreDraft = new Dispatcher(self);

			/**
			 * This event gets fired when a draft removed/expired.
			 *
			 * @event onRemoveDraft
			 * @param {tinymce.plugins.AutoSave} sender Plugin instance sending the event.
			 * @param {Object} draft Draft object containing the HTML contents of the editor.
			 */
			self.onRemoveDraft = new Dispatcher(self);

			// Add ask before unload dialog only add one unload handler
			if (!unloadHandlerAdded) {
				window.onbeforeunload = tinymce.plugins.AutoSave._beforeUnloadHandler;
				unloadHandlerAdded = TRUE;
			}
		},

		/**
		 * Returns information about the plugin as a name/value array.
		 * The current keys are longname, author, authorurl, infourl and version.
		 *
		 * @method getInfo
		 * @return {Object} Name/value array containing information about the plugin.
		 */
		getInfo : function() {
			return {
				longname : 'Auto save',
				author : 'Moxiecode Systems AB',
				authorurl : 'http://tinymce.moxiecode.com',
				infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/autosave',
				version : tinymce.majorVersion + "." + tinymce.minorVersion
			};
		},

		/**
		 * Returns an expiration date UTC string.
		 *
		 * @method getExpDate
		 * @return {String} Expiration date UTC string.
		 */
		getExpDate : function() {
			return new Date(
				new Date().getTime() + this.editor.settings.autosave_retention
			).toUTCString();
		},

		/**
		 * This method will setup the storage engine. If the browser has support for it.
		 *
		 * @method setupStorage
		 */
		setupStorage : function(ed) {
			var self = this, testKey = PLUGIN_NAME + '_test', testVal = "OK";

			self.key = PLUGIN_NAME + ed.id;

			// Loop though each storage engine type until we find one that works
			tinymce.each([
				function() {
					// Try HTML5 Local Storage
					if (localStorage) {
						localStorage.setItem(testKey, testVal);

						if (localStorage.getItem(testKey) === testVal) {
							localStorage.removeItem(testKey);

							return localStorage;
						}
					}
				},

				function() {
					// Try HTML5 Session Storage
					if (sessionStorage) {
						sessionStorage.setItem(testKey, testVal);

						if (sessionStorage.getItem(testKey) === testVal) {
							sessionStorage.removeItem(testKey);

							return sessionStorage;
						}
					}
				},

				function() {
					// Try IE userData
					if (tinymce.isIE) {
						ed.getElement().style.behavior = "url('#default#userData')";

						// Fake localStorage on old IE
						return {
							autoExpires : TRUE,

							setItem : function(key, value) {
								var userDataElement = ed.getElement();

								userDataElement.setAttribute(key, value);
								userDataElement.expires = self.getExpDate();

								try {
									userDataElement.save("TinyMCE");
								} catch (e) {
									// Ignore, saving might fail if "Userdata Persistence" is disabled in IE
								}
							},

							getItem : function(key) {
								var userDataElement = ed.getElement();

								try {
									userDataElement.load("TinyMCE");
									return userDataElement.getAttribute(key);
								} catch (e) {
									// Ignore, loading might fail if "Userdata Persistence" is disabled in IE
									return null;
								}
							},

							removeItem : function(key) {
								ed.getElement().removeAttribute(key);
							}
						};
					}
				},
			], function(setup) {
				// Try executing each function to find a suitable storage engine
				try {
					self.storage = setup();

					if (self.storage)
						return false;
				} catch (e) {
					// Ignore
				}
			});
		},

		/**
		 * This method will store the current contents in the the storage engine.
		 *
		 * @method storeDraft
		 */
		storeDraft : function() {
			var self = this, storage = self.storage, editor = self.editor, expires, content;

			// Is the contents dirty
			if (storage) {
				// If there is no existing key and the contents hasn't been changed since
				// it's original value then there is no point in saving a draft
				if (!storage.getItem(self.key) && !editor.isDirty())
					return;

				// Store contents if the contents if longer than the minlength of characters
				content = editor.getContent({draft: true});
				if (content.length > editor.settings.autosave_minlength) {
					expires = self.getExpDate();

					// Store expiration date if needed IE userData has auto expire built in
					if (!self.storage.autoExpires)
						self.storage.setItem(self.key + "_expires", expires);

					self.storage.setItem(self.key, content);
					self.onStoreDraft.dispatch(self, {
						expires : expires,
						content : content
					});
				}
			}
		},

		/**
		 * This method will restore the contents from the storage engine back to the editor.
		 *
		 * @method restoreDraft
		 */
		restoreDraft : function() {
			var self = this, storage = self.storage;

			if (storage) {
				content = storage.getItem(self.key);

				if (content) {
					self.editor.setContent(content);
					self.onRestoreDraft.dispatch(self, {
						content : content
					});
				}
			}
		},

		/**
		 * This method will return true/false if there is a local storage draft available.
		 *
		 * @method hasDraft
		 * @return {boolean} true/false state if there is a local draft.
		 */
		hasDraft : function() {
			var self = this, storage = self.storage, expDate, exists;

			if (storage) {
				// Does the item exist at all
				exists = !!storage.getItem(self.key);
				if (exists) {
					// Storage needs autoexpire
					if (!self.storage.autoExpires) {
						expDate = new Date(storage.getItem(self.key + "_expires"));

						// Contents hasn't expired
						if (new Date().getTime() < expDate.getTime())
							return TRUE;

						// Remove it if it has
						self.removeDraft();
					} else
						return TRUE;
				}
			}

			return false;
		},

		/**
		 * Removes the currently stored draft.
		 *
		 * @method removeDraft
		 */
		removeDraft : function() {
			var self = this, storage = self.storage, key = self.key, content;

			if (storage) {
				// Get current contents and remove the existing draft
				content = storage.getItem(key);
				storage.removeItem(key);
				storage.removeItem(key + "_expires");

				// Dispatch remove event if we had any contents
				if (content) {
					self.onRemoveDraft.dispatch(self, {
						content : content
					});
				}
			}
		},

		"static" : {
			// Internal unload handler will be called before the page is unloaded
			_beforeUnloadHandler : function(e) {
				var msg;

				tinymce.each(tinyMCE.editors, function(ed) {
					// Store a draft for each editor instance
					if (ed.plugins.autosave)
						ed.plugins.autosave.storeDraft();

					// Never ask in fullscreen mode
					if (ed.getParam("fullscreen_is_enabled"))
						return;

					// Setup a return message if the editor is dirty
					if (!msg && ed.isDirty() && ed.getParam("autosave_ask_before_unload"))
						msg = ed.getLang("autosave.unload_msg");
				});

				return msg;
			}
		}
	});

	tinymce.PluginManager.add('autosave', tinymce.plugins.AutoSave);
})(tinymce);


code:
tinyMCE.addI18n('en.autosave',{
restore_content: "Restore auto-saved content",
warning_message: "If you restore the saved content, you will lose all the content that is currently in the editor.\n\nAre you sure you want to restore the saved content?"
});


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.BBCodePlugin', {
		init : function(ed, url) {
			var t = this, dialect = ed.getParam('bbcode_dialect', 'punbb').toLowerCase();

			ed.onBeforeSetContent.add(function(ed, o) {
				o.content = t['_' + dialect + '_bbcode2html'](o.content);
			});

			ed.onPostProcess.add(function(ed, o) {
				if (o.set)
					o.content = t['_' + dialect + '_bbcode2html'](o.content);

				if (o.get)
					o.content = t['_' + dialect + '_html2bbcode'](o.content);
			});
		},

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

		// Private methods

		// HTML -> BBCode in PunBB dialect
		_punbb_html2bbcode : function(s) {
			s = tinymce.trim(s);

			function rep(re, str) {
				s = s.replace(re, str);
			};

			// example:  to [b]
			rep(/(.*?)<\/a>/gi,"[url=$1]$2[/url]");
			rep(/(.*?)<\/font>/gi,"[code][color=$1]$2[/color][/code]");
			rep(/(.*?)<\/font>/gi,"[quote][color=$1]$2[/color][/quote]");
			rep(/(.*?)<\/font>/gi,"[code][color=$1]$2[/color][/code]");
			rep(/(.*?)<\/font>/gi,"[quote][color=$1]$2[/color][/quote]");
			rep(/(.*?)<\/span>/gi,"[color=$1]$2[/color]");
			rep(/(.*?)<\/font>/gi,"[color=$1]$2[/color]");
			rep(/(.*?)<\/span>/gi,"[size=$1]$2[/size]");
			rep(/(.*?)<\/font>/gi,"$1");
			rep(//gi,"[img]$1[/img]");
			rep(/(.*?)<\/span>/gi,"[code]$1[/code]");
			rep(/(.*?)<\/span>/gi,"[quote]$1[/quote]");
			rep(/(.*?)<\/strong>/gi,"[code][b]$1[/b][/code]");
			rep(/(.*?)<\/strong>/gi,"[quote][b]$1[/b][/quote]");
			rep(/(.*?)<\/em>/gi,"[code][i]$1[/i][/code]");
			rep(/(.*?)<\/em>/gi,"[quote][i]$1[/i][/quote]");
			rep(/(.*?)<\/u>/gi,"[code][u]$1[/u][/code]");
			rep(/(.*?)<\/u>/gi,"[quote][u]$1[/u][/quote]");
			rep(/<\/(strong|b)>/gi,"[/b]");
			rep(/<(strong|b)>/gi,"[b]");
			rep(/<\/(em|i)>/gi,"[/i]");
			rep(/<(em|i)>/gi,"[i]");
			rep(/<\/u>/gi,"[/u]");
			rep(/(.*?)<\/span>/gi,"[u]$1[/u]");
			rep(//gi,"[u]");
			rep(/
]*>/gi,"[quote]");
			rep(/<\/blockquote>/gi,"[/quote]");
			rep(/
/gi,"\n");
			rep(/
/gi,"\n");
			rep(/
/gi,"\n");
			rep(/
/gi,"");
			rep(/<\/p>/gi,"\n");
			rep(/ |\u00a0/gi," ");
			rep(/"/gi,"\"");
			rep(/</gi,"<");
			rep(/>/gi,">");
			rep(/&/gi,"&");

			return s;
		},

		// BBCode -> HTML from PunBB dialect
		_punbb_bbcode2html : function(s) {
			s = tinymce.trim(s);

			function rep(re, str) {
				s = s.replace(re, str);
			};

			// example: [b] to
			rep(/\n/gi,"
");
			rep(/\[b\]/gi,"");
			rep(/\[\/b\]/gi,"");
			rep(/\[i\]/gi,"");
			rep(/\[\/i\]/gi,"");
			rep(/\[u\]/gi,"");
			rep(/\[\/u\]/gi,"");
			rep(/\[url=([^\]]+)\](.*?)\[\/url\]/gi,"$2");
			rep(/\[url\](.*?)\[\/url\]/gi,"$1");
			rep(/\[img\](.*?)\[\/img\]/gi,"");
			rep(/\[color=(.*?)\](.*?)\[\/color\]/gi,"$2");
			rep(/\[code\](.*?)\[\/code\]/gi,"$1 ");
			rep(/\[quote.*?\](.*?)\[\/quote\]/gi,"$1 ");

			return s;
		}
	});

	// Register plugin
	tinymce.PluginManager.add('bbcode', tinymce.plugins.BBCodePlugin);
})();


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 Event = tinymce.dom.Event, each = tinymce.each, DOM = tinymce.DOM;

	/**
	 * This plugin a context menu to TinyMCE editor instances.
	 *
	 * @class tinymce.plugins.ContextMenu
	 */
	tinymce.create('tinymce.plugins.ContextMenu', {
		/**
		 * Initializes the plugin, this will be executed after the plugin has been created.
		 * This call is done before the editor instance has finished it's initialization so use the onInit event
		 * of the editor instance to intercept that event.
		 *
		 * @method init
		 * @param {tinymce.Editor} ed Editor instance that the plugin is initialized in.
		 * @param {string} url Absolute URL to where the plugin is located.
		 */
		init : function(ed) {
			var t = this, showMenu, contextmenuNeverUseNative, realCtrlKey;

			t.editor = ed;

			contextmenuNeverUseNative = ed.settings.contextmenu_never_use_native;

			/**
			 * This event gets fired when the context menu is shown.
			 *
			 * @event onContextMenu
			 * @param {tinymce.plugins.ContextMenu} sender Plugin instance sending the event.
			 * @param {tinymce.ui.DropMenu} menu Drop down menu to fill with more items if needed.
			 */
			t.onContextMenu = new tinymce.util.Dispatcher(this);

			showMenu = ed.onContextMenu.add(function(ed, e) {
				// Block TinyMCE menu on ctrlKey and work around Safari issue
				if ((realCtrlKey !== 0 ? realCtrlKey : e.ctrlKey) && !contextmenuNeverUseNative)
					return;

				Event.cancel(e);

				// Select the image if it's clicked. WebKit would other wise expand the selection
				if (e.target.nodeName == 'IMG')
					ed.selection.select(e.target);

				t._getMenu(ed).showMenu(e.clientX || e.pageX, e.clientY || e.pageY);
				Event.add(ed.getDoc(), 'click', function(e) {
					hide(ed, e);
				});

				ed.nodeChanged();
			});

			ed.onRemove.add(function() {
				if (t._menu)
					t._menu.removeAll();
			});

			function hide(ed, e) {
				realCtrlKey = 0;

				// Since the contextmenu event moves
				// the selection we need to store it away
				if (e && e.button == 2) {
					realCtrlKey = e.ctrlKey;
					return;
				}

				if (t._menu) {
					t._menu.removeAll();
					t._menu.destroy();
					Event.remove(ed.getDoc(), 'click', hide);
				}
			};

			ed.onMouseDown.add(hide);
			ed.onKeyDown.add(hide);
			ed.onKeyDown.add(function(ed, e) {
				if (e.shiftKey && !e.ctrlKey && !e.altKey && e.keyCode === 121) {
					Event.cancel(e);
					showMenu(ed, e);
				}
			});
		},

		/**
		 * Returns information about the plugin as a name/value array.
		 * The current keys are longname, author, authorurl, infourl and version.
		 *
		 * @method getInfo
		 * @return {Object} Name/value array containing information about the plugin.
		 */
		getInfo : function() {
			return {
				longname : 'Contextmenu',
				author : 'Moxiecode Systems AB',
				authorurl : 'http://tinymce.moxiecode.com',
				infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/contextmenu',
				version : tinymce.majorVersion + "." + tinymce.minorVersion
			};
		},

		_getMenu : function(ed) {
			var t = this, m = t._menu, se = ed.selection, col = se.isCollapsed(), el = se.getNode() || ed.getBody(), am, p;

			if (m) {
				m.removeAll();
				m.destroy();
			}

			p = DOM.getPos(ed.getContentAreaContainer());

			m = ed.controlManager.createDropMenu('contextmenu', {
				offset_x : p.x + ed.getParam('contextmenu_offset_x', 0),
				offset_y : p.y + ed.getParam('contextmenu_offset_y', 0),
				constrain : 1,
				keyboard_focus: true
			});

			t._menu = m;

			m.add({title : 'advanced.cut_desc', icon : 'cut', cmd : 'Cut'}).setDisabled(col);
			m.add({title : 'advanced.copy_desc', icon : 'copy', cmd : 'Copy'}).setDisabled(col);
			m.add({title : 'advanced.paste_desc', icon : 'paste', cmd : 'Paste'});

			if ((el.nodeName == 'A' && !ed.dom.getAttrib(el, 'name')) || !col) {
				m.addSeparator();
				m.add({title : 'advanced.link_desc', icon : 'link', cmd : ed.plugins.advlink ? 'mceAdvLink' : 'mceLink', ui : true});
				m.add({title : 'advanced.unlink_desc', icon : 'unlink', cmd : 'UnLink'});
			}

			m.addSeparator();
			m.add({title : 'advanced.image_desc', icon : 'image', cmd : ed.plugins.advimage ? 'mceAdvImage' : 'mceImage', ui : true});

			m.addSeparator();
			am = m.addMenu({title : 'contextmenu.align'});
			am.add({title : 'contextmenu.left', icon : 'justifyleft', cmd : 'JustifyLeft'});
			am.add({title : 'contextmenu.center', icon : 'justifycenter', cmd : 'JustifyCenter'});
			am.add({title : 'contextmenu.right', icon : 'justifyright', cmd : 'JustifyRight'});
			am.add({title : 'contextmenu.full', icon : 'justifyfull', cmd : 'JustifyFull'});

			t.onContextMenu.dispatch(t, m, el, col);

			return m;
		}
	});

	// Register plugin
	tinymce.PluginManager.add('contextmenu', tinymce.plugins.ContextMenu);
})();


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.Directionality', {
		init : function(ed, url) {
			var t = this;

			t.editor = ed;

			ed.addCommand('mceDirectionLTR', function() {
				var e = ed.dom.getParent(ed.selection.getNode(), ed.dom.isBlock);

				if (e) {
					if (ed.dom.getAttrib(e, "dir") != "ltr")
						ed.dom.setAttrib(e, "dir", "ltr");
					else
						ed.dom.setAttrib(e, "dir", "");
				}

				ed.nodeChanged();
			});

			ed.addCommand('mceDirectionRTL', function() {
				var e = ed.dom.getParent(ed.selection.getNode(), ed.dom.isBlock);

				if (e) {
					if (ed.dom.getAttrib(e, "dir") != "rtl")
						ed.dom.setAttrib(e, "dir", "rtl");
					else
						ed.dom.setAttrib(e, "dir", "");
				}

				ed.nodeChanged();
			});

			ed.addButton('ltr', {title : 'directionality.ltr_desc', cmd : 'mceDirectionLTR'});
			ed.addButton('rtl', {title : 'directionality.rtl_desc', cmd : 'mceDirectionRTL'});

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

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

		// Private methods

		_nodeChange : function(ed, cm, n) {
			var dom = ed.dom, dir;

			n = dom.getParent(n, dom.isBlock);
			if (!n) {
				cm.setDisabled('ltr', 1);
				cm.setDisabled('rtl', 1);
				return;
			}

			dir = dom.getAttrib(n, 'dir');
			cm.setActive('ltr', dir == "ltr");
			cm.setDisabled('ltr', 0);
			cm.setActive('rtl', dir == "rtl");
			cm.setDisabled('rtl', 0);
		}
	});

	// Register plugin
	tinymce.PluginManager.add('directionality', tinymce.plugins.Directionality);
})();


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) {
	tinymce.create('tinymce.plugins.EmotionsPlugin', {
		init : function(ed, url) {
			// Register commands
			ed.addCommand('mceEmotion', function() {
				ed.windowManager.open({
					file : url + '/emotions.htm',
					width : 250 + parseInt(ed.getLang('emotions.delta_width', 0)),
					height : 160 + parseInt(ed.getLang('emotions.delta_height', 0)),
					inline : 1
				}, {
					plugin_url : url
				});
			});

			// Register buttons
			ed.addButton('emotions', {title : 'emotions.emotions_desc', cmd : 'mceEmotion'});
		},

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

	// Register plugin
	tinymce.PluginManager.add('emotions', tinymce.plugins.EmotionsPlugin);
})(tinymce);


code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

	<title>{#emotions_dlg.title}</title>

{#emotions_dlg.title}

{#emotions_dlg.title}:


code:
tinyMCEPopup.requireLangPack();

var EmotionsDialog = {
	init : function(ed) {
		tinyMCEPopup.resizeToInnerSize();
	},

	insert : function(file, title) {
		var ed = tinyMCEPopup.editor, dom = ed.dom;

		tinyMCEPopup.execCommand('mceInsertContent', false, dom.createHTML('img', {
			src : tinyMCEPopup.getWindowArg('plugin_url') + '/img/' + file,
			alt : ed.getLang(title),
			title : ed.getLang(title),
			border : 0
		}));

		tinyMCEPopup.close();
	}
};

tinyMCEPopup.onInit.add(EmotionsDialog.init, EmotionsDialog);


code:
tinyMCE.addI18n('en.emotions_dlg',{
title:"Insert emotion",
desc:"Emotions",
cool:"Cool",
cry:"Cry",
embarassed:"Embarassed",
foot_in_mouth:"Foot in mouth",
frown:"Frown",
innocent:"Innocent",
kiss:"Kiss",
laughing:"Laughing",
money_mouth:"Money mouth",
sealed:"Sealed",
smile:"Smile",
surprised:"Surprised",
tongue_out:"Tongue out",
undecided:"Undecided",
wink:"Wink",
yell:"Yell"
});


code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

	<title>{#example_dlg.title}</title>

<form onsubmit="ExampleDialog.insert();return false;" action="#">

Here is a example dialog.

Selected text: <input id="someval" name="someval" type="text" class="text" />

Custom arg: <input id="somearg" name="somearg" type="text" class="text" />

		<input type="button" id="insert" name="insert" value="{#insert}" onclick="ExampleDialog.insert();" />
		<input type="button" id="cancel" name="cancel" value="{#cancel}" onclick="tinyMCEPopup.close();" />

</form>


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() {
	// Load plugin specific language pack
	tinymce.PluginManager.requireLangPack('example');

	tinymce.create('tinymce.plugins.ExamplePlugin', {
		/**
		 * Initializes the plugin, this will be executed after the plugin has been created.
		 * This call is done before the editor instance has finished it's initialization so use the onInit event
		 * of the editor instance to intercept that event.
		 *
		 * @param {tinymce.Editor} ed Editor instance that the plugin is initialized in.
		 * @param {string} url Absolute URL to where the plugin is located.
		 */
		init : function(ed, url) {
			// Register the command so that it can be invoked by using tinyMCE.activeEditor.execCommand('mceExample');
			ed.addCommand('mceExample', function() {
				ed.windowManager.open({
					file : url + '/dialog.htm',
					width : 320 + parseInt(ed.getLang('example.delta_width', 0)),
					height : 120 + parseInt(ed.getLang('example.delta_height', 0)),
					inline : 1
				}, {
					plugin_url : url, // Plugin absolute URL
					some_custom_arg : 'custom arg' // Custom argument
				});
			});

			// Register example button
			ed.addButton('example', {
				title : 'example.desc',
				cmd : 'mceExample',
				image : url + '/img/example.gif'
			});

			// Add a node change handler, selects the button in the UI when a image is selected
			ed.onNodeChange.add(function(ed, cm, n) {
				cm.setActive('example', n.nodeName == 'IMG');
			});
		},

		/**
		 * Creates control instances based in the incomming name. This method is normally not
		 * needed since the addButton method of the tinymce.Editor class is a more easy way of adding buttons
		 * but you sometimes need to create more complex controls like listboxes, split buttons etc then this
		 * method can be used to create those.
		 *
		 * @param {String} n Name of the control to create.
		 * @param {tinymce.ControlManager} cm Control manager to use inorder to create new control.
		 * @return {tinymce.ui.Control} New control instance or null if no control was created.
		 */
		createControl : function(n, cm) {
			return null;
		},

		/**
		 * Returns information about the plugin as a name/value array.
		 * The current keys are longname, author, authorurl, infourl and version.
		 *
		 * @return {Object} Name/value array containing information about the plugin.
		 */
		getInfo : function() {
			return {
				longname : 'Example plugin',
				author : 'Some author',
				authorurl : 'http://tinymce.moxiecode.com',
				infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/example',
				version : "1.0"
			};
		}
	});

	// Register plugin
	tinymce.PluginManager.add('example', tinymce.plugins.ExamplePlugin);
})();


code:
tinyMCEPopup.requireLangPack();

var ExampleDialog = {
	init : function() {
		var f = document.forms[0];

		// Get the selected contents as text and place it in the input
		f.someval.value = tinyMCEPopup.editor.selection.getContent({format : 'text'});
		f.somearg.value = tinyMCEPopup.getWindowArg('some_custom_arg');
	},

	insert : function() {
		// Insert the contents from the input into the document
		tinyMCEPopup.editor.execCommand('mceInsertContent', false, document.forms[0].someval.value);
		tinyMCEPopup.close();
	}
};

tinyMCEPopup.onInit.add(ExampleDialog.init, ExampleDialog);


code:
tinyMCE.addI18n('en.example',{
	desc : 'This is just a template button'
});


code:
tinyMCE.addI18n('en.example_dlg',{
	title : 'This is just a example title'
});


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.ExampleDependencyPlugin', {
		/**
		 * Initializes the plugin, this will be executed after the plugin has been created.
		 * This call is done before the editor instance has finished it's initialization so use the onInit event
		 * of the editor instance to intercept that event.
		 *
		 * @param {tinymce.Editor} ed Editor instance that the plugin is initialized in.
		 * @param {string} url Absolute URL to where the plugin is located.
		 */
		init : function(ed, url) {
		},

		/**
		 * Returns information about the plugin as a name/value array.
		 * The current keys are longname, author, authorurl, infourl and version.
		 *
		 * @return {Object} Name/value array containing information about the plugin.
		 */
		getInfo : function() {
			return {
				longname : 'Example Dependency plugin',
				author : 'Some author',
				authorurl : 'http://tinymce.moxiecode.com',
				infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/example_dependency',
				version : "1.0"
			};
		}
	});

	/**
	 * Register the plugin, specifying the list of the plugins that this plugin depends on.  They are specified in a list, with the list loaded in order.
	 * plugins in this list will be initialised when this plugin is initialized. (before the init method is called).
	 * plugins in a depends list should typically be specified using the short name).  If neccesary this can be done
	 * with an object which has the url to the plugin and the shortname.
	 */
	tinymce.PluginManager.add('example_dependency', tinymce.plugins.ExampleDependencyPlugin, ['example']);
})();


code:
/* Hide the advanced tab */
#advanced_tab {
	display: none;
}

#metatitle, #metakeywords, #metadescription, #metaauthor, #metacopyright {
	width: 280px;
}

#doctype, #docencoding {
	width: 200px;
}

#langcode {
	width: 30px;
}

#bgimage {
	width: 220px;
}

#fontface {
	width: 240px;
}

#leftmargin, #rightmargin, #topmargin, #bottommargin {
	width: 50px;
}

.panel_wrapper div.current {
	height: 400px;
}

#stylesheet, #style {
	width: 240px;
}

#doctypes {
	width: 200px;
}

/* Head list classes */

.headlistwrapper {
	width: 100%;
}

.selected {
	border: 1px solid #0A246A;
	background-color: #B6BDD2;
}

.toolbar {
	width: 100%;
}

#headlist {
	width: 100%;
	margin-top: 3px;
	font-size: 11px;
}

#info, #title_element, #meta_element, #script_element, #style_element, #base_element, #link_element, #comment_element, #unknown_element {
	display: none;
}

#addmenu {
	position: absolute;
	border: 1px solid gray;
	display: none;
	z-index: 100;
	background-color: white;
}

#addmenu a {
	display: block;
	width: 100%;
	line-height: 20px;
	text-decoration: none;
	background-color: white;
}

#addmenu a:hover {
	background-color: #B6BDD2;
	color: black;
}

#addmenu span {
	padding-left: 10px;
	padding-right: 10px;
}

#updateElementPanel {
	display: none;
}

#script_element .panel_wrapper div.current {
	height: 108px;
}

#style_element .panel_wrapper div.current {
	height: 108px;
}

#link_element  .panel_wrapper div.current {
	height: 140px;
}

#element_script_value {
	width: 100%;
	height: 100px;
}

#element_comment_value {
	width: 100%;
	height: 120px;
}

#element_style_value {
	width: 100%;
	height: 100px;
}

#element_title, #element_script_src, #element_meta_name, #element_meta_content, #element_base_href, #element_link_href, #element_link_title {
	width: 250px;
}

.updateElementButton {
	margin-top: 3px;
}

/* MSIE specific styles */

* html .addbutton, * html .removebutton, * html .moveupbutton, * html .movedownbutton {
	width: 22px;
	height: 22px;
}

textarea {
	height: 55px;
}

.panel_wrapper div.current {height:420px;}


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 each = tinymce.each, Node = tinymce.html.Node;

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

			t.editor = ed;

			// Register commands
			ed.addCommand('mceFullPageProperties', function() {
				ed.windowManager.open({
					file : url + '/fullpage.htm',
					width : 430 + parseInt(ed.getLang('fullpage.delta_width', 0)),
					height : 495 + parseInt(ed.getLang('fullpage.delta_height', 0)),
					inline : 1
				}, {
					plugin_url : url,
					data : t._htmlToData()
				});
			});

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

			ed.onBeforeSetContent.add(t._setContent, t);
			ed.onGetContent.add(t._getContent, t);
		},

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

		// Private plugin internal methods

		_htmlToData : function() {
			var headerFragment = this._parseHeader(), data = {}, nodes, elm, matches, editor = this.editor;

			function getAttr(elm, name) {
				var value = elm.attr(name);

				return value || '';
			};

			// Default some values
			data.fontface = editor.getParam("fullpage_default_fontface", "");
			data.fontsize = editor.getParam("fullpage_default_fontsize", "");

			// Parse XML PI
			elm = headerFragment.firstChild;
			if (elm.type == 7) {
				data.xml_pi = true;
				matches = /encoding="([^"]+)"/.exec(elm.value);
				if (matches)
					data.docencoding = matches[1];
			}

			// Parse doctype
			elm = headerFragment.getAll('#doctype')[0];
			if (elm)
				data.doctype = '<!DOCTYPE' + elm.value + ">";

			// Parse title element
			elm = headerFragment.getAll('title')[0];
			if (elm && elm.firstChild) {
				data.metatitle = elm.firstChild.value;
			}

			// Parse meta elements
			each(headerFragment.getAll('meta'), function(meta) {
				var name = meta.attr('name'), httpEquiv = meta.attr('http-equiv'), matches;

				if (name)
					data['meta' + name.toLowerCase()] = meta.attr('content');
				else if (httpEquiv == "Content-Type") {
					matches = /charset\s*=\s*(.*)\s*/gi.exec(meta.attr('content'));

					if (matches)
						data.docencoding = matches[1];
				}
			});

			// Parse html attribs
			elm = headerFragment.getAll('html')[0];
			if (elm)
				data.langcode = getAttr(elm, 'lang') || getAttr(elm, 'xml:lang');

			// Parse stylesheet
			elm = headerFragment.getAll('link')[0];
			if (elm && elm.attr('rel') == 'stylesheet')
				data.stylesheet = elm.attr('href');

			// Parse body parts
			elm = headerFragment.getAll('body')[0];
			if (elm) {
				data.langdir = getAttr(elm, 'dir');
				data.style = getAttr(elm, 'style');
				data.visited_color = getAttr(elm, 'vlink');
				data.link_color = getAttr(elm, 'link');
				data.active_color = getAttr(elm, 'alink');
			}

			return data;
		},

		_dataToHtml : function(data) {
			var headerFragment, headElement, html, elm, value, dom = this.editor.dom;

			function setAttr(elm, name, value) {
				elm.attr(name, value ? value : undefined);
			};

			function addHeadNode(node) {
				if (headElement.firstChild)
					headElement.insert(node, headElement.firstChild);
				else
					headElement.append(node);
			};

			headerFragment = this._parseHeader();
			headElement = headerFragment.getAll('head')[0];
			if (!headElement) {
				elm = headerFragment.getAll('html')[0];
				headElement = new Node('head', 1);

				if (elm.firstChild)
					elm.insert(headElement, elm.firstChild, true);
				else
					elm.append(headElement);
			}

			// Add/update/remove XML-PI
			elm = headerFragment.firstChild;
			if (data.xml_pi) {
				value = 'version="1.0"';

				if (data.docencoding)
					value += ' encoding="' + data.docencoding + '"';

				if (elm.type != 7) {
					elm = new Node('xml', 7);
					headerFragment.insert(elm, headerFragment.firstChild, true);
				}

				elm.value = value;
			} else if (elm && elm.type == 7)
				elm.remove();

			// Add/update/remove doctype
			elm = headerFragment.getAll('#doctype')[0];
			if (data.doctype) {
				if (!elm) {
					elm = new Node('#doctype', 10);

					if (data.xml_pi)
						headerFragment.insert(elm, headerFragment.firstChild);
					else
						addHeadNode(elm);
				}

				elm.value = data.doctype.substring(9, data.doctype.length - 1);
			} else if (elm)
				elm.remove();

			// Add/update/remove title
			elm = headerFragment.getAll('title')[0];
			if (data.metatitle) {
				if (!elm) {
					elm = new Node('title', 1);
					elm.append(new Node('#text', 3)).value = data.metatitle;
					addHeadNode(elm);
				}
			}

			// Add meta encoding
			if (data.docencoding) {
				elm = null;
				each(headerFragment.getAll('meta'), function(meta) {
					if (meta.attr('http-equiv') == 'Content-Type')
						elm = meta;
				});

				if (!elm) {
					elm = new Node('meta', 1);
					elm.attr('http-equiv', 'Content-Type');
					elm.shortEnded = true;
					addHeadNode(elm);
				}

				elm.attr('content', 'text/html; charset=' + data.docencoding);
			}

			// Add/update/remove meta
			each('keywords,description,author,copyright,robots'.split(','), function(name) {
				var nodes = headerFragment.getAll('meta'), i, meta, value = data['meta' + name];

				for (i = 0; i < nodes.length; i++) {
					meta = nodes[i];

					if (meta.attr('name') == name) {
						if (value)
							meta.attr('content', value);
						else
							meta.remove();

						return;
					}
				}

				if (value) {
					elm = new Node('meta', 1);
					elm.attr('name', name);
					elm.attr('content', value);
					elm.shortEnded = true;

					addHeadNode(elm);
				}
			});

			// Add/update/delete link
			elm = headerFragment.getAll('link')[0];
			if (elm && elm.attr('rel') == 'stylesheet') {
				if (data.stylesheet)
					elm.attr('href', data.stylesheet);
				else
					elm.remove();
			} else if (data.stylesheet) {
				elm = new Node('link', 1);
				elm.attr({
					rel : 'stylesheet',
					text : 'text/css',
					href : data.stylesheet
				});
				elm.shortEnded = true;

				addHeadNode(elm);
			}

			// Update body attributes
			elm = headerFragment.getAll('body')[0];
			if (elm) {
				setAttr(elm, 'dir', data.langdir);
				setAttr(elm, 'style', data.style);
				setAttr(elm, 'vlink', data.visited_color);
				setAttr(elm, 'link', data.link_color);
				setAttr(elm, 'alink', data.active_color);

				// Update iframe body as well
				dom.setAttribs(this.editor.getBody(), {
					style : data.style,
					dir : data.dir,
					vLink : data.visited_color,
					link : data.link_color,
					aLink : data.active_color
				});
			}

			// Set html attributes
			elm = headerFragment.getAll('html')[0];
			if (elm) {
				setAttr(elm, 'lang', data.langcode);
				setAttr(elm, 'xml:lang', data.langcode);
			}

			// Serialize header fragment and crop away body part
			html = new tinymce.html.Serializer({
				validate: false,
				indent: true,
				apply_source_formatting : true,
				indent_before: 'head,html,body,meta,title,script,link,style',
				indent_after: 'head,html,body,meta,title,script,link,style'
			}).serialize(headerFragment);

			this.head = html.substring(0, html.indexOf(''));
		},

		_parseHeader : function() {
			// Parse the contents with a DOM parser
			return new tinymce.html.DomParser({
				validate: false,
				root_name: '#document'
			}).parse(this.head);
		},

		_setContent : function(ed, o) {
			var self = this, startPos, endPos, content = o.content, headerFragment, styles = '', dom = self.editor.dom, elm;

			function low(s) {
				return s.replace(/<\/?[A-Z]+/g, function(a) {
					return a.toLowerCase();
				})
			};

			// Ignore raw updated if we already have a head, this will fix issues with undo/redo keeping the head/foot separate
			if (o.format == 'raw' && self.head)
				return;

			if (o.source_view && ed.getParam('fullpage_hide_in_source_view'))
				return;

			// Parse out head, body and footer
			content = content.replace(/<(\/?)BODY/gi, '<$1body');
			startPos = content.indexOf('', startPos);
				self.head = low(content.substring(0, startPos + 1));

				endPos = content.indexOf('</body', startPos);
				if (endPos == -1)
					endPos = content.length;

				o.content = content.substring(startPos + 1, endPos);
				self.foot = low(content.substring(endPos));
			} else {
				self.head = this._getDefaultHeader();
				self.foot = '\n\n';
			}

			// Parse header and update iframe
			headerFragment = self._parseHeader();
			each(headerFragment.getAll('style'), function(node) {
				if (node.firstChild)
					styles += node.firstChild.value;
			});

			elm = headerFragment.getAll('body')[0];
			if (elm) {
				dom.setAttribs(self.editor.getBody(), {
					style : elm.attr('style') || '',
					dir : elm.attr('dir') || '',
					vLink : elm.attr('vlink') || '',
					link : elm.attr('link') || '',
					aLink : elm.attr('alink') || ''
				});
			}

			if (styles)
				dom.add(self.editor.getDoc().getElementsByTagName('head')[0], 'style', {id : 'fullpage_styles'}, styles);
			else
				dom.remove('fullpage_styles');
		},

		_getDefaultHeader : function() {
			var header = '', editor = this.editor, value, styles = '';

			if (editor.getParam('fullpage_default_xml_pi'))
				header += '<?xml version="1.0" encoding="' + editor.getParam('fullpage_default_encoding', 'ISO-8859-1') + '" ?>\n';

			header += editor.getParam('fullpage_default_doctype', '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">');
			header += '\n\n\n';

			if (value = editor.getParam('fullpage_default_title'))
				header += '<title>' + value + '</title>\n';

			if (value = editor.getParam('fullpage_default_encoding'))
				header += '<meta http-equiv="Content-Type" content="text/html; charset=' + value + '" />\n';

			if (value = editor.getParam('fullpage_default_font_family'))
				styles += 'font-family: ' + value + ';';

			if (value = editor.getParam('fullpage_default_font_size'))
				styles += 'font-size: ' + value + ';';

			if (value = editor.getParam('fullpage_default_text_color'))
				styles += 'color: ' + value + ';';

			header += '\n\n';

			return header;
		},

		_getContent : function(ed, o) {
			var self = this;

			if (!o.source_view || !ed.getParam('fullpage_hide_in_source_view'))
				o.content = tinymce.trim(self.head) + '\n' + tinymce.trim(o.content) + '\n' + tinymce.trim(self.foot);
		}
	});

	// Register plugin
	tinymce.PluginManager.add('fullpage', tinymce.plugins.FullPagePlugin);
})();


code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

	<title>{#fullpage_dlg.title}</title>

	<link href="css/fullpage.css" rel="stylesheet" type="text/css" />

<form onsubmit="FullPageDialog.update();return false;" name="fullpage" action="#">

{#fullpage_dlg.meta_tab}

{#fullpage_dlg.appearance_tab}

				<fieldset>
					<legend>{#fullpage_dlg.meta_props}</legend>

							{#fullpage_dlg.meta_title}
							<input type="text" id="metatitle" name="metatitle" value="" class="mceFocus" />

							{#fullpage_dlg.meta_keywords}
							<textarea id="metakeywords" name="metakeywords" rows="4"></textarea>

							{#fullpage_dlg.meta_description}
							<textarea id="metadescription" name="metadescription" rows="4"></textarea>

							{#fullpage_dlg.author}
							<input type="text" id="metaauthor" name="metaauthor" value="" />

							{#fullpage_dlg.copyright}
							<input type="text" id="metacopyright" name="metacopyright" value="" />

							{#fullpage_dlg.meta_robots}

								<select id="metarobots" name="metarobots">
											<option value="">{#not_set}</option>
											<option value="index,follow">{#fullpage_dlg.meta_index_follow}</option>
											<option value="index,nofollow">{#fullpage_dlg.meta_index_nofollow}</option>
											<option value="noindex,follow">{#fullpage_dlg.meta_noindex_follow}</option>
											<option value="noindex,nofollow">{#fullpage_dlg.meta_noindex_nofollow}</option>
								</select>

				</fieldset>

				<fieldset>
					<legend>{#fullpage_dlg.langprops}</legend>

							{#fullpage_dlg.encoding}

								<select id="docencoding" name="docencoding">
										<option value="">{#not_set}</option>
								</select>

							{#fullpage_dlg.doctypes}

								<select id="doctype" name="doctype">
										<option value="">{#not_set}</option>
								</select>

							{#fullpage_dlg.langcode}
							<input type="text" id="langcode" name="langcode" value="" />

							{#fullpage_dlg.langdir}

								<select id="langdir" name="langdir">
										<option value="">{#not_set}</option>
										<option value="ltr">{#fullpage_dlg.ltr}</option>
										<option value="rtl">{#fullpage_dlg.rtl}</option>
								</select>

							{#fullpage_dlg.xml_pi}
							<input type="checkbox" id="xml_pi" name="xml_pi" class="checkbox" />

				</fieldset>

				<fieldset>
					<legend>{#fullpage_dlg.appearance_textprops}</legend>

							{#fullpage_dlg.fontface}

								<select id="fontface" name="fontface" onchange="FullPageDialog.changedStyleProp();">
										<option value="">{#not_set}</option>
								</select>

							{#fullpage_dlg.fontsize}

								<select id="fontsize" name="fontsize" onchange="FullPageDialog.changedStyleProp();">
										<option value="">{#not_set}</option>
								</select>

							{#fullpage_dlg.textcolor}

										<input id="textcolor" name="textcolor" type="text" value="" size="9" onchange="updateColor('textcolor_pick','textcolor');FullPageDialog.changedStyleProp();" />

				</fieldset>

				<fieldset>
					<legend>{#fullpage_dlg.appearance_bgprops}</legend>

							{#fullpage_dlg.bgimage}

										<input id="bgimage" name="bgimage" type="text" value="" onchange="FullPageDialog.changedStyleProp();" />

							{#fullpage_dlg.bgcolor}

										<input id="bgcolor" name="bgcolor" type="text" value="" size="9" onchange="updateColor('bgcolor_pick','bgcolor');FullPageDialog.changedStyleProp();" />

				</fieldset>

				<fieldset>
					<legend>{#fullpage_dlg.appearance_marginprops}</legend>

							{#fullpage_dlg.left_margin}
							<input id="leftmargin" name="leftmargin" type="text" value="" onchange="FullPageDialog.changedStyleProp();" />
							{#fullpage_dlg.right_margin}
							<input id="rightmargin" name="rightmargin" type="text" value="" onchange="FullPageDialog.changedStyleProp();" />

							{#fullpage_dlg.top_margin}
							<input id="topmargin" name="topmargin" type="text" value="" onchange="FullPageDialog.changedStyleProp();" />
							{#fullpage_dlg.bottom_margin}
							<input id="bottommargin" name="bottommargin" type="text" value="" onchange="FullPageDialog.changedStyleProp();" />

				</fieldset>

				<fieldset>
					<legend>{#fullpage_dlg.appearance_linkprops}</legend>

							{#fullpage_dlg.link_color}

										<input id="link_color" name="link_color" type="text" value="" size="9" onchange="updateColor('link_color_pick','link_color');FullPageDialog.changedStyleProp();" />

							{#fullpage_dlg.visited_color}

										<input id="visited_color" name="visited_color" type="text" value="" size="9" onchange="updateColor('visited_color_pick','visited_color');FullPageDialog.changedStyleProp();" />

							{#fullpage_dlg.active_color}

										<input id="active_color" name="active_color" type="text" value="" size="9" onchange="updateColor('active_color_pick','active_color');FullPageDialog.changedStyleProp();" />

				</fieldset>

				<fieldset>
					<legend>{#fullpage_dlg.appearance_style}</legend>

							{#fullpage_dlg.stylesheet}

										<input id="stylesheet" name="stylesheet" type="text" value="" />

							{#fullpage_dlg.style}
							<input id="style" name="style" type="text" value="" onchange="FullPageDialog.changedStyle();" />

				</fieldset>

			<input type="submit" id="insert" name="update" value="{#update}" />
			<input type="button" id="cancel" name="cancel" value="{#cancel}" onclick="tinyMCEPopup.close();" />

</form>


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

(function() {
	tinyMCEPopup.requireLangPack();

	var defaultDocTypes =
		'XHTML 1.0 Transitional=<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">,' +
		'XHTML 1.0 Frameset=<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">,' +
		'XHTML 1.0 Strict=<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">,' +
		'XHTML 1.1=<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">,' +
		'HTML 4.01 Transitional=<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">,' +
		'HTML 4.01 Strict=<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">,' +
		'HTML 4.01 Frameset=<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">';

	var defaultEncodings =
		'Western european (iso-8859-1)=iso-8859-1,' +
		'Central European (iso-8859-2)=iso-8859-2,' +
		'Unicode (UTF-8)=utf-8,' +
		'Chinese traditional (Big5)=big5,' +
		'Cyrillic (iso-8859-5)=iso-8859-5,' +
		'Japanese (iso-2022-jp)=iso-2022-jp,' +
		'Greek (iso-8859-7)=iso-8859-7,' +
		'Korean (iso-2022-kr)=iso-2022-kr,' +
		'ASCII (us-ascii)=us-ascii';

	var defaultFontNames = 'Arial=arial,helvetica,sans-serif;Courier New=courier new,courier,monospace;Georgia=georgia,times new roman,times,serif;Tahoma=tahoma,arial,helvetica,sans-serif;Times New Roman=times new roman,times,serif;Verdana=verdana,arial,helvetica,sans-serif;Impact=impact;WingDings=wingdings';
	var defaultFontSizes = '10px,11px,12px,13px,14px,15px,16px';

	function setVal(id, value) {
		var elm = document.getElementById(id);

		if (elm) {
			value = value || '';

			if (elm.nodeName == "SELECT")
				selectByValue(document.forms[0], id, value);
			else if (elm.type == "checkbox")
				elm.checked = !!value;
			else
				elm.value = value;
		}
	};

	function getVal(id) {
		var elm = document.getElementById(id);

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

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

		return elm.value;
	};

	window.FullPageDialog = {
		changedStyle : function() {
			var val, styles = tinyMCEPopup.editor.dom.parseStyle(getVal('style'));

			setVal('fontface', styles['font-face']);
			setVal('fontsize', styles['font-size']);
			setVal('textcolor', styles['color']);

			if (val = styles['background-image'])
				setVal('bgimage', val.replace(new RegExp("url\\('?([^']*)'?\\)", 'gi'), "$1"));
			else
				setVal('bgimage', '');

			setVal('bgcolor', styles['background-color']);

			// Reset margin form elements
			setVal('topmargin', '');
			setVal('rightmargin', '');
			setVal('bottommargin', '');
			setVal('leftmargin', '');

			// Expand margin
			if (val = styles['margin']) {
				val = val.split(' ');
				styles['margin-top'] = val[0] || '';
				styles['margin-right'] = val[1] || val[0] || '';
				styles['margin-bottom'] = val[2] || val[0] || '';
				styles['margin-left'] = val[3] || val[0] || '';
			}

			if (val = styles['margin-top'])
				setVal('topmargin', val.replace(/px/, ''));

			if (val = styles['margin-right'])
				setVal('rightmargin', val.replace(/px/, ''));

			if (val = styles['margin-bottom'])
				setVal('bottommargin', val.replace(/px/, ''));

			if (val = styles['margin-left'])
				setVal('leftmargin', val.replace(/px/, ''));

			updateColor('bgcolor_pick', 'bgcolor');
			updateColor('textcolor_pick', 'textcolor');
		},

		changedStyleProp : function() {
			var val, dom = tinyMCEPopup.editor.dom, styles = dom.parseStyle(getVal('style'));

			styles['font-face'] = getVal('fontface');
			styles['font-size'] = getVal('fontsize');
			styles['color'] = getVal('textcolor');
			styles['background-color'] = getVal('bgcolor');

			if (val = getVal('bgimage'))
				styles['background-image'] = "url('" + val + "')";
			else
				styles['background-image'] = '';

			delete styles['margin'];

			if (val = getVal('topmargin'))
				styles['margin-top'] = val + "px";
			else
				styles['margin-top'] = '';

			if (val = getVal('rightmargin'))
				styles['margin-right'] = val + "px";
			else
				styles['margin-right'] = '';

			if (val = getVal('bottommargin'))
				styles['margin-bottom'] = val + "px";
			else
				styles['margin-bottom'] = '';

			if (val = getVal('leftmargin'))
				styles['margin-left'] = val + "px";
			else
				styles['margin-left'] = '';

			// Serialize, parse and reserialize this will compress redundant styles
			setVal('style', dom.serializeStyle(dom.parseStyle(dom.serializeStyle(styles))));
			this.changedStyle();
		},

		update : function() {
			var data = {};

			tinymce.each(tinyMCEPopup.dom.select('select,input,textarea'), function(node) {
				data[node.id] = getVal(node.id);
			});

			tinyMCEPopup.editor.plugins.fullpage._dataToHtml(data);
			tinyMCEPopup.close();
		}
	};

	function init() {
		var form = document.forms[0], i, item, list, editor = tinyMCEPopup.editor;

		// Setup doctype select box
		list = editor.getParam("fullpage_doctypes", defaultDocTypes).split(',');
		for (i = 0; i < list.length; i++) {
			item = list[i].split('=');

			if (item.length > 1)
				addSelectValue(form, 'doctype', item[0], item[1]);
		}

		// Setup fonts select box
		list = editor.getParam("fullpage_fonts", defaultFontNames).split(';');
		for (i = 0; i < list.length; i++) {
			item = list[i].split('=');

			if (item.length > 1)
				addSelectValue(form, 'fontface', item[0], item[1]);
		}

		// Setup fontsize select box
		list = editor.getParam("fullpage_fontsizes", defaultFontSizes).split(',');
		for (i = 0; i < list.length; i++)
			addSelectValue(form, 'fontsize', list[i], list[i]);

		// Setup encodings select box
		list = editor.getParam("fullpage_encodings", defaultEncodings).split(',');
		for (i = 0; i < list.length; i++) {
			item = list[i].split('=');

			if (item.length > 1)
				addSelectValue(form, 'docencoding', item[0], item[1]);
		}

		// Setup color pickers
		document.getElementById('bgcolor_pickcontainer').innerHTML = getColorPickerHTML('bgcolor_pick','bgcolor');
		document.getElementById('link_color_pickcontainer').innerHTML = getColorPickerHTML('link_color_pick','link_color');
		document.getElementById('visited_color_pickcontainer').innerHTML = getColorPickerHTML('visited_color_pick','visited_color');
		document.getElementById('active_color_pickcontainer').innerHTML = getColorPickerHTML('active_color_pick','active_color');
		document.getElementById('textcolor_pickcontainer').innerHTML = getColorPickerHTML('textcolor_pick','textcolor');
		document.getElementById('stylesheet_browsercontainer').innerHTML = getBrowserHTML('stylesheetbrowser','stylesheet','file','fullpage');
		document.getElementById('bgimage_pickcontainer').innerHTML = getBrowserHTML('bgimage_browser','bgimage','image','fullpage');

		// Resize some elements
		if (isVisible('stylesheetbrowser'))
			document.getElementById('stylesheet').style.width = '220px';

		if (isVisible('link_href_browser'))
			document.getElementById('element_link_href').style.width = '230px';

		if (isVisible('bgimage_browser'))
			document.getElementById('bgimage').style.width = '210px';

		// Update form
		tinymce.each(tinyMCEPopup.getWindowArg('data'), function(value, key) {
			setVal(key, value);
		});

		FullPageDialog.changedStyle();

		// Update colors
		updateColor('textcolor_pick', 'textcolor');
		updateColor('bgcolor_pick', 'bgcolor');
		updateColor('visited_color_pick', 'visited_color');
		updateColor('active_color_pick', 'active_color');
		updateColor('link_color_pick', 'link_color');
	};

	tinyMCEPopup.onInit.add(init);
})();


code:
tinyMCE.addI18n('en.fullpage_dlg',{
title:"Document properties",
meta_tab:"General",
appearance_tab:"Appearance",
advanced_tab:"Advanced",
meta_props:"Meta information",
langprops:"Language and encoding",
meta_title:"Title",
meta_keywords:"Keywords",
meta_description:"Description",
meta_robots:"Robots",
doctypes:"Doctype",
langcode:"Language code",
langdir:"Language direction",
ltr:"Left to right",
rtl:"Right to left",
xml_pi:"XML declaration",
encoding:"Character encoding",
appearance_bgprops:"Background properties",
appearance_marginprops:"Body margins",
appearance_linkprops:"Link colors",
appearance_textprops:"Text properties",
bgcolor:"Background color",
bgimage:"Background image",
left_margin:"Left margin",
right_margin:"Right margin",
top_margin:"Top margin",
bottom_margin:"Bottom margin",
text_color:"Text color",
font_size:"Font size",
font_face:"Font face",
link_color:"Link color",
hover_color:"Hover color",
visited_color:"Visited color",
active_color:"Active color",
textcolor:"Color",
fontsize:"Font size",
fontface:"Font family",
meta_index_follow:"Index and follow the links",
meta_index_nofollow:"Index and don't follow the links",
meta_noindex_follow:"Do not index but follow the links",
meta_noindex_nofollow:"Do not index and don\'t follow the links",
appearance_style:"Stylesheet and style properties",
stylesheet:"Stylesheet",
style:"Style",
author:"Author",
copyright:"Copyright",
add:"Add new element",
remove:"Remove selected element",
moveup:"Move selected element up",
movedown:"Move selected element down",
head_elements:"Head elements",
info:"Information",
add_title:"Title element",
add_meta:"Meta element",
add_script:"Script element",
add_style:"Style element",
add_link:"Link element",
add_base:"Base element",
add_comment:"Comment node",
title_element:"Title element",
script_element:"Script element",
style_element:"Style element",
base_element:"Base element",
link_element:"Link element",
meta_element:"Meta element",
comment_element:"Comment",
src:"Src",
language:"Language",
href:"Href",
target:"Target",
type:"Type",
charset:"Charset",
defer:"Defer",
media:"Media",
properties:"Properties",
name:"Name",
value:"Value",
content:"Content",
rel:"Rel",
rev:"Rev",
hreflang:"Href lang",
general_props:"General",
advanced_props:"Advanced"
});


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;

	tinymce.create('tinymce.plugins.FullScreenPlugin', {
		init : function(ed, url) {
			var t = this, s = {}, vp, posCss;

			t.editor = ed;

			// Register commands
			ed.addCommand('mceFullScreen', function() {
				var win, de = DOM.doc.documentElement;

				if (ed.getParam('fullscreen_is_enabled')) {
					if (ed.getParam('fullscreen_new_window'))
						closeFullscreen(); // Call to close in new window
					else {
						DOM.win.setTimeout(function() {
							tinymce.dom.Event.remove(DOM.win, 'resize', t.resizeFunc);
							tinyMCE.get(ed.getParam('fullscreen_editor_id')).setContent(ed.getContent({format : 'raw'}), {format : 'raw'});
							tinyMCE.remove(ed);
							DOM.remove('mce_fullscreen_container');
							de.style.overflow = ed.getParam('fullscreen_html_overflow');
							DOM.setStyle(DOM.doc.body, 'overflow', ed.getParam('fullscreen_overflow'));
							DOM.win.scrollTo(ed.getParam('fullscreen_scrollx'), ed.getParam('fullscreen_scrolly'));
							tinyMCE.settings = tinyMCE.oldSettings; // Restore old settings
						}, 10);
					}

					return;
				}

				if (ed.getParam('fullscreen_new_window')) {
					win = DOM.win.open(url + "/fullscreen.htm", "mceFullScreenPopup", "fullscreen=yes,menubar=no,toolbar=no,scrollbars=no,resizable=yes,left=0,top=0,width=" + screen.availWidth + ",height=" + screen.availHeight);
					try {
						win.resizeTo(screen.availWidth, screen.availHeight);
					} catch (e) {
						// Ignore
					}
				} else {
					tinyMCE.oldSettings = tinyMCE.settings; // Store old settings
					s.fullscreen_overflow = DOM.getStyle(DOM.doc.body, 'overflow', 1) || 'auto';
					s.fullscreen_html_overflow = DOM.getStyle(de, 'overflow', 1);
					vp = DOM.getViewPort();
					s.fullscreen_scrollx = vp.x;
					s.fullscreen_scrolly = vp.y;

					// Fixes an Opera bug where the scrollbars doesn't reappear
					if (tinymce.isOpera && s.fullscreen_overflow == 'visible')
						s.fullscreen_overflow = 'auto';

					// Fixes an IE bug where horizontal scrollbars would appear
					if (tinymce.isIE && s.fullscreen_overflow == 'scroll')
						s.fullscreen_overflow = 'auto';

					// Fixes an IE bug where the scrollbars doesn't reappear
					if (tinymce.isIE && (s.fullscreen_html_overflow == 'visible' || s.fullscreen_html_overflow == 'scroll'))
						s.fullscreen_html_overflow = 'auto';

					if (s.fullscreen_overflow == '0px')
						s.fullscreen_overflow = '';

					DOM.setStyle(DOM.doc.body, 'overflow', 'hidden');
					de.style.overflow = 'hidden'; //Fix for IE6/7
					vp = DOM.getViewPort();
					DOM.win.scrollTo(0, 0);

					if (tinymce.isIE)
						vp.h -= 1;

					// Use fixed position if it exists
					if (tinymce.isIE6)
						posCss = 'absolute;top:' + vp.y;
					else
						posCss = 'fixed;top:0';

					n = DOM.add(DOM.doc.body, 'div', {
						id : 'mce_fullscreen_container',
						style : 'position:' + posCss + ';left:0;width:' + vp.w + 'px;height:' + vp.h + 'px;z-index:200000;'});
					DOM.add(n, 'div', {id : 'mce_fullscreen'});

					tinymce.each(ed.settings, function(v, n) {
						s[n] = v;
					});

					s.id = 'mce_fullscreen';
					s.width = n.clientWidth;
					s.height = n.clientHeight - 15;
					s.fullscreen_is_enabled = true;
					s.fullscreen_editor_id = ed.id;
					s.theme_advanced_resizing = false;
					s.save_onsavecallback = function() {
						ed.setContent(tinyMCE.get(s.id).getContent({format : 'raw'}), {format : 'raw'});
						ed.execCommand('mceSave');
					};

					tinymce.each(ed.getParam('fullscreen_settings'), function(v, k) {
						s[k] = v;
					});

					if (s.theme_advanced_toolbar_location === 'external')
						s.theme_advanced_toolbar_location = 'top';

					t.fullscreenEditor = new tinymce.Editor('mce_fullscreen', s);
					t.fullscreenEditor.onInit.add(function() {
						t.fullscreenEditor.setContent(ed.getContent());
						t.fullscreenEditor.focus();
					});

					t.fullscreenEditor.render();

					t.fullscreenElement = new tinymce.dom.Element('mce_fullscreen_container');
					t.fullscreenElement.update();
					//document.body.overflow = 'hidden';

					t.resizeFunc = tinymce.dom.Event.add(DOM.win, 'resize', function() {
						var vp = tinymce.DOM.getViewPort(), fed = t.fullscreenEditor, outerSize, innerSize;

						// Get outer/inner size to get a delta size that can be used to calc the new iframe size
						outerSize = fed.dom.getSize(fed.getContainer().firstChild);
						innerSize = fed.dom.getSize(fed.getContainer().getElementsByTagName('iframe')[0]);

						fed.theme.resizeTo(vp.w - outerSize.w + innerSize.w, vp.h - outerSize.h + innerSize.h);
					});
				}
			});

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

			ed.onNodeChange.add(function(ed, cm) {
				cm.setActive('fullscreen', ed.getParam('fullscreen_is_enabled'));
			});
		},

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

	// Register plugin
	tinymce.PluginManager.add('fullscreen', tinymce.plugins.FullScreenPlugin);
})();


code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
	<title></title>
	<script type="text/javascript" src="../../tiny_mce.js"></script>
	<script type="text/javascript">
		function patchCallback(settings, key) {
			if (settings[key])
				settings[key] = "window.opener." + settings[key];
		}

		var settings = {}, paSe = window.opener.tinyMCE.activeEditor.settings, oeID = window.opener.tinyMCE.activeEditor.id;

		// Clone array
		for (var n in paSe)
			settings[n] = paSe[n];

		// Override options for fullscreen
		for (var n in paSe.fullscreen_settings)
			settings[n] = paSe.fullscreen_settings[n];

		// Patch callbacks, make them point to window.opener
		patchCallback(settings, 'urlconverter_callback');
		patchCallback(settings, 'insertlink_callback');
		patchCallback(settings, 'insertimage_callback');
		patchCallback(settings, 'setupcontent_callback');
		patchCallback(settings, 'save_callback');
		patchCallback(settings, 'onchange_callback');
		patchCallback(settings, 'init_instance_callback');
		patchCallback(settings, 'file_browser_callback');
		patchCallback(settings, 'cleanup_callback');
		patchCallback(settings, 'execcommand_callback');
		patchCallback(settings, 'oninit');

		// Set options
		delete settings.id;
		settings['mode'] = 'exact';
		settings['elements'] = 'fullscreenarea';
		settings['add_unload_trigger'] = false;
		settings['ask'] = false;
		settings['document_base_url'] = window.opener.tinyMCE.activeEditor.documentBaseURI.getURI();
		settings['fullscreen_is_enabled'] = true;
		settings['fullscreen_editor_id'] = oeID;
		settings['theme_advanced_resizing'] = false;
		settings['strict_loading_mode'] = true;

		settings.save_onsavecallback = function() {
			window.opener.tinyMCE.get(oeID).setContent(tinyMCE.get('fullscreenarea').getContent({format : 'raw'}), {format : 'raw'});
			window.opener.tinyMCE.get(oeID).execCommand('mceSave');
			window.close();
		};

		function unloadHandler(e) {
			moveContent();
		}

		function moveContent() {
			window.opener.tinyMCE.get(oeID).setContent(tinyMCE.activeEditor.getContent());
		}

		function closeFullscreen() {
			moveContent();
			window.close();
		}

		function doParentSubmit() {
			moveContent();

			if (window.opener.tinyMCE.selectedInstance.formElement.form)
				window.opener.tinyMCE.selectedInstance.formElement.form.submit();

			window.close();

			return false;
		}

		function render() {
			var e = document.getElementById('fullscreenarea'), vp, ed, ow, oh, dom = tinymce.DOM;

			e.value = window.opener.tinyMCE.get(oeID).getContent();

			vp = dom.getViewPort();
			settings.width = vp.w;
			settings.height = vp.h - 15;

			tinymce.dom.Event.add(window, 'resize', function() {
				var vp = dom.getViewPort();

				tinyMCE.activeEditor.theme.resizeTo(vp.w, vp.h);
			});

			tinyMCE.init(settings);
		}

		// Add onunload
		tinymce.dom.Event.add(window, "beforeunload", unloadHandler);
	</script>
</head>
<body style="margin:0;overflow:hidden;width:100%;height:100%" scrolling="no" scroll="no">
<form onsubmit="doParentSubmit();">
<textarea id="fullscreenarea" style="width:100%; height:100%"></textarea>
</form>

<script type="text/javascript">
	render();
</script>

</body>
</html>


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.IESpell', {
		init : function(ed, url) {
			var t = this, sp;

			if (!tinymce.isIE)
				return;

			t.editor = ed;

			// Register commands
			ed.addCommand('mceIESpell', function() {
				try {
					sp = new ActiveXObject("ieSpell.ieSpellExtension");
					sp.CheckDocumentNode(ed.getDoc().documentElement);
				} catch (e) {
					if (e.number == -2146827859) {
						ed.windowManager.confirm(ed.getLang("iespell.download"), function(s) {
							if (s)
								window.open('http://www.iespell.com/download.php', 'ieSpellDownload', '');
						});
					} else
						ed.windowManager.alert("Error Loading ieSpell: Exception " + e.number);
				}
			});

			// Register buttons
			ed.addButton('iespell', {title : 'iespell.iespell_desc', cmd : 'mceIESpell'});
		},

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

	// Register plugin
	tinymce.PluginManager.add('iespell', tinymce.plugins.IESpell);
})();