includes/clientside/tinymce/tiny_mce_src.js
changeset 395 fa4c5ecb7c9a
parent 335 67bd3121a12e
child 459 31c23016ab62
equal deleted inserted replaced
394:fbfdcea634a7 395:fa4c5ecb7c9a
     1 
     1 
     2 /* file:jscripts/tiny_mce/classes/tinymce.js */
     2 /* file:jscripts/tiny_mce/classes/tinymce.js */
     3 
     3 
     4 var tinymce = {
     4 var tinymce = {
     5 	majorVersion : '3',
     5 	majorVersion : '3',
     6 	minorVersion : '0b3',
     6 	minorVersion : '0',
     7 	releaseDate : '2007-12-14',
     7 	releaseDate : '2008-01-30',
     8 
     8 
     9 	_init : function() {
     9 	_init : function() {
    10 		var t = this, ua = navigator.userAgent, i, nl, n, base;
    10 		var t = this, ua = navigator.userAgent, i, nl, n, base;
    11 
    11 
    12 		// Browser checks
    12 		// Browser checks
   451 			// Relative path
   451 			// Relative path
   452 			if (u.indexOf('://') === -1 && u.indexOf('//') !== 0)
   452 			if (u.indexOf('://') === -1 && u.indexOf('//') !== 0)
   453 				u = (s.base_uri.protocol || 'http') + '://mce_host' + t.toAbsPath(s.base_uri.path, u);
   453 				u = (s.base_uri.protocol || 'http') + '://mce_host' + t.toAbsPath(s.base_uri.path, u);
   454 
   454 
   455 			// Parse URL (Credits goes to Steave, http://blog.stevenlevithan.com/archives/parseuri)
   455 			// Parse URL (Credits goes to Steave, http://blog.stevenlevithan.com/archives/parseuri)
       
   456 			u = u.replace(/@@/g, '(mce_at)'); // Zope 3 workaround, they use @@something
   456 			u = /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/.exec(u);
   457 			u = /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/.exec(u);
   457 			each(["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"], function(v, i) {
   458 			each(["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"], function(v, i) {
   458 				t[v] = u[i];
   459 				var s = u[i];
       
   460 
       
   461 				// Zope 3 workaround, they use @@something
       
   462 				if (s)
       
   463 					s = s.replace(/\(mce_at\)/g, '@@');
       
   464 
       
   465 				t[v] = s;
   459 			});
   466 			});
   460 
   467 
   461 			if (b = s.base_uri) {
   468 			if (b = s.base_uri) {
   462 				if (!t.protocol)
   469 				if (!t.protocol)
   463 					t.protocol = b.protocol;
   470 					t.protocol = b.protocol;
   675 
   682 
   676 			this.set(n, o, e, p, d, s);
   683 			this.set(n, o, e, p, d, s);
   677 		},
   684 		},
   678 
   685 
   679 		get : function(n) {
   686 		get : function(n) {
   680 			var c = document.cookie, e, p = n + "=", b = c.indexOf("; " + p);
   687 			var c = document.cookie, e, p = n + "=", b;
       
   688 
       
   689 			// Strict mode
       
   690 			if (!c)
       
   691 				return;
       
   692 
       
   693 			b = c.indexOf("; " + p);
   681 
   694 
   682 			if (b == -1) {
   695 			if (b == -1) {
   683 				b = c.indexOf(p);
   696 				b = c.indexOf(p);
   684 
   697 
   685 				if (b != 0)
   698 				if (b != 0)
   904 			t.counter = 0;
   917 			t.counter = 0;
   905 			t.boxModel = !tinymce.isIE || d.compatMode == "CSS1Compat"; 
   918 			t.boxModel = !tinymce.isIE || d.compatMode == "CSS1Compat"; 
   906 
   919 
   907 			this.settings = s = tinymce.extend({
   920 			this.settings = s = tinymce.extend({
   908 				keep_values : false,
   921 				keep_values : false,
   909 				hex_colors : 1
   922 				hex_colors : 1,
       
   923 				process_html : 1
   910 			}, s);
   924 			}, s);
   911 
   925 
   912 			// Fix IE6SP2 flicker and check it failed for pre SP2
   926 			// Fix IE6SP2 flicker and check it failed for pre SP2
   913 			if (tinymce.isIE6) {
   927 			if (tinymce.isIE6) {
   914 				try {
   928 				try {
   944 				h : w.innerHeight || b.clientHeight
   958 				h : w.innerHeight || b.clientHeight
   945 			};
   959 			};
   946 		},
   960 		},
   947 
   961 
   948 		getRect : function(e) {
   962 		getRect : function(e) {
   949 			var p, t = this;
   963 			var p, t = this, w, h;
   950 
   964 
   951 			e = t.get(e);
   965 			e = t.get(e);
   952 			p = t.getPos(e);
   966 			p = t.getPos(e);
       
   967 			w = t.getStyle(e, 'width');
       
   968 			h = t.getStyle(e, 'height');
       
   969 
       
   970 			// Non pixel value, then force offset/clientWidth
       
   971 			if (w.indexOf('px') === -1)
       
   972 				w = 0;
       
   973 
       
   974 			// Non pixel value, then force offset/clientWidth
       
   975 			if (h.indexOf('px') === -1)
       
   976 				h = 0;
   953 
   977 
   954 			return {
   978 			return {
   955 				x : p.x,
   979 				x : p.x,
   956 				y : p.y,
   980 				y : p.y,
   957 				w : parseInt(t.getStyle(e, 'width')) || e.offsetWidth || e.clientWidth,
   981 				w : parseInt(w) || e.offsetWidth || e.clientWidth,
   958 				h : parseInt(t.getStyle(e, 'height')) || e.offsetHeight || e.clientHeight
   982 				h : parseInt(h) || e.offsetHeight || e.clientHeight
   959 			};
   983 			};
   960 		},
   984 		},
   961 
   985 
   962 		getParent : function(n, f, r) {
   986 		getParent : function(n, f, r) {
   963 			var na;
   987 			var na, se = this.settings;
   964 
   988 
   965 			n = this.get(n);
   989 			n = this.get(n);
   966 
   990 
   967 			if (this.settings.strict_root)
   991 			if (se.strict_root)
   968 				r = r || this.getRoot();
   992 				r = r || this.getRoot();
   969 
   993 
   970 			// Wrap node name as func
   994 			// Wrap node name as func
   971 			if (is(f, 'string')) {
   995 			if (is(f, 'string')) {
   972 				na = f.toUpperCase();
   996 				na = f.toUpperCase();
   979 						s = true;
  1003 						s = true;
   980 						return false;
  1004 						return false;
   981 					}
  1005 					}
   982 
  1006 
   983 					each(na.split(','), function(v) {
  1007 					each(na.split(','), function(v) {
   984 						if (n.nodeType == 1 && n.nodeName == v) {
  1008 						if (n.nodeType == 1 && ((se.strict && n.nodeName.toUpperCase() == v) || n.nodeName == v)) {
   985 							s = true;
  1009 							s = true;
   986 							return false; // Break loop
  1010 							return false; // Break loop
   987 						}
  1011 						}
   988 					});
  1012 					});
   989 
  1013 
  1016 		select : function(pa, s) {
  1040 		select : function(pa, s) {
  1017 			var t = this, cs, c, pl, o = [], x, i, l, n;
  1041 			var t = this, cs, c, pl, o = [], x, i, l, n;
  1018 
  1042 
  1019 			s = t.get(s) || t.doc;
  1043 			s = t.get(s) || t.doc;
  1020 
  1044 
       
  1045 			if (t.settings.strict) {
       
  1046 				function get(s, n) {
       
  1047 					return s.getElementsByTagName(n.toLowerCase());
       
  1048 				};
       
  1049 			} else {
       
  1050 				function get(s, n) {
       
  1051 					return s.getElementsByTagName(n);
       
  1052 				};
       
  1053 			}
       
  1054 
  1021 			// Simple element pattern. For example: "p" or "*"
  1055 			// Simple element pattern. For example: "p" or "*"
  1022 			if (t.elmPattern.test(pa)) {
  1056 			if (t.elmPattern.test(pa)) {
  1023 				x = s.getElementsByTagName(pa);
  1057 				x = get(s, pa);
  1024 
  1058 
  1025 				for (i = 0, l = x.length; i<l; i++)
  1059 				for (i = 0, l = x.length; i<l; i++)
  1026 					o.push(x[i]);
  1060 					o.push(x[i]);
  1027 
  1061 
  1028 				return o;
  1062 				return o;
  1029 			}
  1063 			}
  1030 
  1064 
  1031 			// Simple class pattern. For example: "p.class" or ".class"
  1065 			// Simple class pattern. For example: "p.class" or ".class"
  1032 			if (t.elmClassPattern.test(pa)) {
  1066 			if (t.elmClassPattern.test(pa)) {
  1033 				pl = t.elmClassPattern.exec(pa);
  1067 				pl = t.elmClassPattern.exec(pa);
  1034 				x = s.getElementsByTagName(pl[1] || '*');
  1068 				x = get(s, pl[1] || '*');
  1035 				c = ' ' + pl[2] + ' ';
  1069 				c = ' ' + pl[2] + ' ';
  1036 
  1070 
  1037 				for (i = 0, l = x.length; i<l; i++) {
  1071 				for (i = 0, l = x.length; i<l; i++) {
  1038 					n = x[i];
  1072 					n = x[i];
  1039 
  1073 
  1057 					o.push(n);
  1091 					o.push(n);
  1058 				}
  1092 				}
  1059 			};
  1093 			};
  1060 
  1094 
  1061 			function find(n, f, r) {
  1095 			function find(n, f, r) {
  1062 				var i, l, nl = r.getElementsByTagName(n);
  1096 				var i, l, nl = get(r, n);
  1063 
  1097 
  1064 				for (i = 0, l = nl.length; i < l; i++)
  1098 				for (i = 0, l = nl.length; i < l; i++)
  1065 					f(nl[i]);
  1099 					f(nl[i]);
  1066 			};
  1100 			};
  1067 
  1101 
  1068 			each(pa.split(','), function(v, i) {
  1102 			each(pa.split(','), function(v, i) {
  1069 				v = tinymce.trim(v);
  1103 				v = tinymce.trim(v);
  1070 
  1104 
  1071 				// Simple element pattern, most common in TinyMCE
  1105 				// Simple element pattern, most common in TinyMCE
  1072 				if (t.elmPattern.test(v)) {
  1106 				if (t.elmPattern.test(v)) {
  1073 					each(s.getElementsByTagName(v), function(n) {
  1107 					each(get(s, v), function(n) {
  1074 						collect(n);
  1108 						collect(n);
  1075 					});
  1109 					});
  1076 
  1110 
  1077 					return;
  1111 					return;
  1078 				}
  1112 				}
  1079 
  1113 
  1080 				// Simple element pattern with class, fairly common in TinyMCE
  1114 				// Simple element pattern with class, fairly common in TinyMCE
  1081 				if (t.elmClassPattern.test(v)) {
  1115 				if (t.elmClassPattern.test(v)) {
  1082 					x = t.elmClassPattern.exec(v);
  1116 					x = t.elmClassPattern.exec(v);
  1083 
  1117 
  1084 					each(s.getElementsByTagName(x[1]), function(n) {
  1118 					each(get(s, x[1]), function(n) {
  1085 						if (t.hasClass(n, x[2]))
  1119 						if (t.hasClass(n, x[2]))
  1086 							collect(n);
  1120 							collect(n);
  1087 					});
  1121 					});
  1088 
  1122 
  1089 					return;
  1123 					return;
  1168 
  1202 
  1169 				if (h) {
  1203 				if (h) {
  1170 					if (h.nodeType)
  1204 					if (h.nodeType)
  1171 						e.appendChild(h);
  1205 						e.appendChild(h);
  1172 					else
  1206 					else
  1173 						e.innerHTML = h;
  1207 						t.setHTML(e, h);
  1174 				}
  1208 				}
  1175 
  1209 
  1176 				return !c ? p.appendChild(e) : e;
  1210 				return !c ? p.appendChild(e) : e;
  1177 			});
  1211 			});
  1178 		},
  1212 		},
  1217 		},
  1251 		},
  1218 
  1252 
  1219 		// #if !jquery
  1253 		// #if !jquery
  1220 
  1254 
  1221 		setStyle : function(n, na, v) {
  1255 		setStyle : function(n, na, v) {
  1222 			return this.run(n, function(e) {
  1256 			var t = this;
       
  1257 
       
  1258 			return t.run(n, function(e) {
  1223 				var s, i;
  1259 				var s, i;
  1224 
  1260 
  1225 				s = e.style;
  1261 				s = e.style;
  1226 
  1262 
  1227 				// Camelcase it, if needed
  1263 				// Camelcase it, if needed
  1228 				na = na.replace(/-(\D)/g, function(a, b){
  1264 				na = na.replace(/-(\D)/g, function(a, b){
  1229 					return b.toUpperCase();
  1265 					return b.toUpperCase();
  1230 				});
  1266 				});
  1231 
  1267 
  1232 				// Default px suffix on these
  1268 				// Default px suffix on these
  1233 				if (this.pixelStyles.test(na) && (tinymce.is(v, 'number') || /^[\-0-9\.]+$/.test(v)))
  1269 				if (t.pixelStyles.test(na) && (tinymce.is(v, 'number') || /^[\-0-9\.]+$/.test(v)))
  1234 					v += 'px';
  1270 					v += 'px';
  1235 
  1271 
  1236 				switch (na) {
  1272 				switch (na) {
  1237 					case 'opacity':
  1273 					case 'opacity':
  1238 						// IE specific opacity
  1274 						// IE specific opacity
  1250 					case 'float':
  1286 					case 'float':
  1251 						isIE ? s.styleFloat = v : s.cssFloat = v;
  1287 						isIE ? s.styleFloat = v : s.cssFloat = v;
  1252 						break;
  1288 						break;
  1253 				}
  1289 				}
  1254 
  1290 
  1255 				s[na] = v;
  1291 				s[na] = v || '';
       
  1292 
       
  1293 				// Force update of the style data
       
  1294 				if (t.settings.update_styles)
       
  1295 					t.setAttrib(e, 'mce_style');
  1256 			});
  1296 			});
  1257 		},
  1297 		},
  1258 
  1298 
  1259 		getStyle : function(n, na, c) {
  1299 		getStyle : function(n, na, c) {
  1260 			n = this.get(n);
  1300 			n = this.get(n);
  1291 
  1331 
  1292 			return n.style[na];
  1332 			return n.style[na];
  1293 		},
  1333 		},
  1294 
  1334 
  1295 		setStyles : function(e, o) {
  1335 		setStyles : function(e, o) {
  1296 			var t = this;
  1336 			var t = this, s = t.settings, ol;
       
  1337 
       
  1338 			ol = s.update_styles;
       
  1339 			s.update_styles = 0;
  1297 
  1340 
  1298 			each(o, function(v, n) {
  1341 			each(o, function(v, n) {
  1299 				t.setStyle(e, n, v);
  1342 				t.setStyle(e, n, v);
  1300 			});
  1343 			});
       
  1344 
       
  1345 			// Update style info
       
  1346 			s.update_styles = ol;
       
  1347 			if (s.update_styles)
       
  1348 				t.setAttrib(e, s.cssText);
  1301 		},
  1349 		},
  1302 
  1350 
  1303 		setAttrib : function(e, n, v) {
  1351 		setAttrib : function(e, n, v) {
  1304 			var t = this;
  1352 			var t = this;
       
  1353 
       
  1354 			// Strict XML mode
       
  1355 			if (t.settings.strict)
       
  1356 				n = n.toLowerCase();
  1305 
  1357 
  1306 			return this.run(e, function(e) {
  1358 			return this.run(e, function(e) {
  1307 				var s = t.settings;
  1359 				var s = t.settings;
  1308 
  1360 
  1309 				switch (n) {
  1361 				switch (n) {
  1363 
  1415 
  1364 			if (!is(dv))
  1416 			if (!is(dv))
  1365 				dv = "";
  1417 				dv = "";
  1366 
  1418 
  1367 			// Try the mce variant for these
  1419 			// Try the mce variant for these
  1368 			if (/^(src|href|style)$/.test(n)) {
  1420 			if (/^(src|href|style|coords)$/.test(n)) {
  1369 				v = t.getAttrib(e, "mce_" + n);
  1421 				v = e.getAttribute("mce_" + n);
  1370 
  1422 
  1371 				if (v)
  1423 				if (v)
  1372 					return v;
  1424 					return v;
  1373 			}
  1425 			}
  1374 
  1426 
  1399 
  1451 
  1400 					break;
  1452 					break;
  1401 			}
  1453 			}
  1402 
  1454 
  1403 			// Remove Apple and WebKit stuff
  1455 			// Remove Apple and WebKit stuff
  1404 			if (isWebKit && n == "class" && v)
  1456 			if (isWebKit && n === "class" && v)
  1405 				v = v.replace(/(apple|webkit)\-[a-z\-]+/gi, '');
  1457 				v = v.replace(/(apple|webkit)\-[a-z\-]+/gi, '');
  1406 
  1458 
  1407 			// Handle IE issues
  1459 			// Handle IE issues
  1408 			if (isIE) {
  1460 			if (isIE) {
  1409 				switch (n) {
  1461 				switch (n) {
  1434 						if (v === 32768)
  1486 						if (v === 32768)
  1435 							v = '';
  1487 							v = '';
  1436 
  1488 
  1437 						break;
  1489 						break;
  1438 
  1490 
       
  1491 					case 'shape':
       
  1492 						v = v.toLowerCase();
       
  1493 						break;
       
  1494 
  1439 					default:
  1495 					default:
  1440 						// IE has odd anonymous function for event attributes
  1496 						// IE has odd anonymous function for event attributes
  1441 						if (n.indexOf('on') === 0 && v)
  1497 						if (n.indexOf('on') === 0 && v)
  1442 							v = ('' + v).replace(/^function\s+anonymous\(\)\s+\{\s+(.*)\s+\}$/, '$1');
  1498 							v = ('' + v).replace(/^function\s+anonymous\(\)\s+\{\s+(.*)\s+\}$/, '$1');
  1443 				}
  1499 				}
  1445 
  1501 
  1446 			return (v && v != '') ? '' + v : dv;
  1502 			return (v && v != '') ? '' + v : dv;
  1447 		},
  1503 		},
  1448 
  1504 
  1449 		getPos : function(n) {
  1505 		getPos : function(n) {
  1450 			var t = this, x = 0, y = 0, e, d = t.doc;
  1506 			var t = this, x = 0, y = 0, e, d = t.doc, r;
  1451 
  1507 
  1452 			n = t.get(n);
  1508 			n = t.get(n);
  1453 
  1509 
  1454 			// Use getBoundingClientRect on IE, Opera has it but it's not perfect
  1510 			// Use getBoundingClientRect on IE, Opera has it but it's not perfect
  1455 			if (n && isIE) {
  1511 			if (n && isIE) {
  1460 				n.top += window.self != window.top ? 2 : 0; // IE adds some strange extra cord if used in a frameset
  1516 				n.top += window.self != window.top ? 2 : 0; // IE adds some strange extra cord if used in a frameset
  1461 
  1517 
  1462 				return {x : n.left + e.scrollLeft - x, y : n.top + e.scrollTop - x};
  1518 				return {x : n.left + e.scrollLeft - x, y : n.top + e.scrollTop - x};
  1463 			}
  1519 			}
  1464 
  1520 
  1465 			while (n) {
  1521 			r = n;
  1466 				x += n.offsetLeft || 0;
  1522 			while (r) {
  1467 				y += n.offsetTop || 0;
  1523 				x += r.offsetLeft || 0;
  1468 				x -= n.scrollLeft || 0;
  1524 				y += r.offsetTop || 0;
  1469 				y -= n.scrollTop || 0;
  1525 
  1470 				n = n.offsetParent;
  1526 				r = r.offsetParent;
       
  1527 			}
       
  1528 
       
  1529 			r = n;
       
  1530 			while (r) {
       
  1531 				x -= r.scrollLeft || 0;
       
  1532 				y -= r.scrollTop || 0;
       
  1533 
       
  1534 				r = r.parentNode;
       
  1535 
       
  1536 				if (r == d.body)
       
  1537 					break;
  1471 			}
  1538 			}
  1472 
  1539 
  1473 			return {x : x, y : y};
  1540 			return {x : x, y : y};
  1474 		},
  1541 		},
  1475 
  1542 
  1557 			compress("border", "-color", "border-color");
  1624 			compress("border", "-color", "border-color");
  1558 			compress("border", "-style", "border-style");
  1625 			compress("border", "-style", "border-style");
  1559 			compress("padding", "", "padding");
  1626 			compress("padding", "", "padding");
  1560 			compress("margin", "", "margin");
  1627 			compress("margin", "", "margin");
  1561 			compress2('border', 'border-width', 'border-style', 'border-color');
  1628 			compress2('border', 'border-width', 'border-style', 'border-color');
       
  1629 
       
  1630 			if (isIE) {
       
  1631 				// Remove pointless border
       
  1632 				if (o.border == 'medium none')
       
  1633 					o.border = '';
       
  1634 			}
  1562 
  1635 
  1563 			return o;
  1636 			return o;
  1564 		},
  1637 		},
  1565 
  1638 
  1566 		serializeStyle : function(o) {
  1639 		serializeStyle : function(o) {
  1669 
  1742 
  1670 		setHTML : function(e, h) {
  1743 		setHTML : function(e, h) {
  1671 			var t = this;
  1744 			var t = this;
  1672 
  1745 
  1673 			return this.run(e, function(e) {
  1746 			return this.run(e, function(e) {
       
  1747 				var x;
       
  1748 
  1674 				h = t.processHTML(h);
  1749 				h = t.processHTML(h);
  1675 
  1750 
  1676 				if (isIE) {
  1751 				if (isIE) {
  1677 					// Fix for IE bug, first node comments gets stripped
  1752 					try {
  1678 					e.innerHTML = '<br />' + h;
  1753 						// IE will remove comments from the beginning
  1679 					e.removeChild(e.firstChild);
  1754 						// unless you padd the contents with something
       
  1755 						e.innerHTML = '<br />' + h;
       
  1756 						e.removeChild(e.firstChild);
       
  1757 					} catch (ex) {
       
  1758 						// IE sometimes produces an unknown runtime error on innerHTML
       
  1759 						// This seems to fix this issue, don't know why.
       
  1760 						x = t.create('div');
       
  1761 						x.innerHTML = '<br />' + h;
       
  1762 
       
  1763 						each (x.childNodes, function(n, i) {
       
  1764 							// Skip the BR
       
  1765 							if (i > 1)
       
  1766 								e.appendChild(n);
       
  1767 						});
       
  1768 					}
  1680 				} else
  1769 				} else
  1681 					e.innerHTML = h;
  1770 					e.innerHTML = h;
  1682 
  1771 
  1683 				return h;
  1772 				return h;
  1684 			});
  1773 			});
  1685 		},
  1774 		},
  1686 
  1775 
  1687 		processHTML : function(h) {
  1776 		processHTML : function(h) {
  1688 			var t = this, s = t.settings;
  1777 			var t = this, s = t.settings;
       
  1778 
       
  1779 			if (!s.process_html)
       
  1780 				return h;
  1689 
  1781 
  1690 			// Convert strong and em to b and i in FF since it can't handle them
  1782 			// Convert strong and em to b and i in FF since it can't handle them
  1691 			if (tinymce.isGecko) {
  1783 			if (tinymce.isGecko) {
  1692 				h = h.replace(/<(\/?)strong>|<strong( [^>]+)>/gi, '<$1b$2>');
  1784 				h = h.replace(/<(\/?)strong>|<strong( [^>]+)>/gi, '<$1b$2>');
  1693 				h = h.replace(/<(\/?)em>|<em( [^>]+)>/gi, '<$1i$2>');
  1785 				h = h.replace(/<(\/?)em>|<em( [^>]+)>/gi, '<$1i$2>');
  1694 			}
  1786 			}
  1695 
  1787 
       
  1788 			// Fix some issues
       
  1789 			h = h.replace(/<a( )([^>]+)\/>|<a\/>/gi, '<a$1$2></a>'); // Force open
       
  1790 
  1696 			// Store away src and href in mce_src and mce_href since browsers mess them up
  1791 			// Store away src and href in mce_src and mce_href since browsers mess them up
  1697 			if (s.keep_values) {
  1792 			if (s.keep_values) {
       
  1793 				// Wrap scripts in comments for serialization purposes
       
  1794 				if (h.indexOf('<script') !== -1) {
       
  1795 					h = h.replace(/<script>/g, '<script type="text/javascript">');
       
  1796 					h = h.replace(/<script(|[^>]+)>(\s*<!--|\/\/\s*<\[CDATA\[)?[\r\n]*/g, '<mce:script$1><!--\n');
       
  1797 					h = h.replace(/\s*(\/\/\s*-->|\/\/\s*]]>)?<\/script>/g, '\n// --></mce:script>');
       
  1798 					h = h.replace(/<mce:script(|[^>]+)><!--\n\/\/ --><\/mce:script>/g, '<mce:script$1></mce:script>');
       
  1799 				}
       
  1800 
  1698 				// Process all tags with src, href or style
  1801 				// Process all tags with src, href or style
  1699 				h = h.replace(/<([\w:]+) [^>]*(src|href|style)[^>]*>/gi, function(a, n) {
  1802 				h = h.replace(/<([\w:]+) [^>]*(src|href|style|coords)[^>]*>/gi, function(a, n) {
  1700 					function handle(m, b, c) {
  1803 					function handle(m, b, c) {
  1701 						var u = c;
  1804 						var u = c;
  1702 
  1805 
  1703 						// Tag already got a mce_ version
  1806 						// Tag already got a mce_ version
  1704 						if (a.indexOf('mce_' + b) != -1)
  1807 						if (a.indexOf('mce_' + b) != -1)
  1718 							if (s.url_converter) {
  1821 							if (s.url_converter) {
  1719 								u = u.replace(/url\([\'\"]?([^\)\'\"]+)\)/g, function(x, c) {
  1822 								u = u.replace(/url\([\'\"]?([^\)\'\"]+)\)/g, function(x, c) {
  1720 									return 'url(' + t.encode(s.url_converter.call(s.url_converter_scope || t, t.decode(c), b, n)) + ')';
  1823 									return 'url(' + t.encode(s.url_converter.call(s.url_converter_scope || t, t.decode(c), b, n)) + ')';
  1721 								});
  1824 								});
  1722 							}
  1825 							}
  1723 						} else {
  1826 						} else if (b != 'coords') {
  1724 							if (s.url_converter)
  1827 							if (s.url_converter)
  1725 								u = t.encode(s.url_converter.call(s.url_converter_scope || t, t.decode(c), b, n));
  1828 								u = t.encode(s.url_converter.call(s.url_converter_scope || t, t.decode(c), b, n));
  1726 						}
  1829 						}
  1727 
  1830 
  1728 						return ' ' + b + '="' + c + '" mce_' + b + '="' + u + '"';
  1831 						return ' ' + b + '="' + c + '" mce_' + b + '="' + u + '"';
  1729 					};
  1832 					};
  1730 
  1833 
  1731 					a = a.replace(/ (src|href|style)=[\"]([^\"]+)[\"]/gi, handle); // W3C
  1834 					a = a.replace(/ (src|href|style|coords)=[\"]([^\"]+)[\"]/gi, handle); // W3C
  1732 					a = a.replace(/ (src|href|style)=[\']([^\']+)[\']/gi, handle); // W3C
  1835 					a = a.replace(/ (src|href|style|coords)=[\']([^\']+)[\']/gi, handle); // W3C
  1733 
  1836 
  1734 					return a.replace(/ (src|href|style)=([^\s\"\'>]+)/gi, handle); // IE
  1837 					return a.replace(/ (src|href|style|coords)=([^\s\"\'>]+)/gi, handle); // IE
  1735 				});
  1838 				});
  1736 			}
  1839 			}
  1737 
  1840 
  1738 			return h;
  1841 			return h;
  1739 		},
  1842 		},
  1994 		*/
  2097 		*/
  1995 
  2098 
  1996 		});
  2099 		});
  1997 
  2100 
  1998 	// Setup page DOM
  2101 	// Setup page DOM
  1999 	tinymce.DOM = new tinymce.dom.DOMUtils(document);
  2102 	tinymce.DOM = new tinymce.dom.DOMUtils(document, {process_html : 0});
  2000 })();
  2103 })();
  2001 
  2104 
  2002 /* file:jscripts/tiny_mce/classes/dom/Event.js */
  2105 /* file:jscripts/tiny_mce/classes/dom/Event.js */
  2003 
  2106 
  2004 (function() {
  2107 (function() {
  2396 				wb = ' ';
  2499 				wb = ' ';
  2397 
  2500 
  2398 			if (/\s+$/.test(e.innerHTML))
  2501 			if (/\s+$/.test(e.innerHTML))
  2399 				wa = ' ';
  2502 				wa = ' ';
  2400 
  2503 
       
  2504 			s.getInner = true;
       
  2505 
  2401 			return t.isCollapsed() ? '' : wb + t.serializer.serialize(e, s) + wa;
  2506 			return t.isCollapsed() ? '' : wb + t.serializer.serialize(e, s) + wa;
  2402 		},
  2507 		},
  2403 
  2508 
  2404 		setContent : function(h, s) {
  2509 		setContent : function(h, s) {
  2405 			var t = this, r = t.getRng(), d;
  2510 			var t = this, r = t.getRng(), d;
  2408 			s.set = true;
  2513 			s.set = true;
  2409 			h = t.dom.processHTML(h);
  2514 			h = t.dom.processHTML(h);
  2410 
  2515 
  2411 			if (r.insertNode) {
  2516 			if (r.insertNode) {
  2412 				d = t.win.document;
  2517 				d = t.win.document;
       
  2518 
       
  2519 				// Gecko has a bug where if you insert &nbsp; using InsertHTML it will insert a space instead
       
  2520 				// So we simply check if the input is HTML or text and then insert text using the insertNode method
       
  2521 				if (tinymce.isGecko && h.indexOf('<') == -1) {
       
  2522 					r.deleteContents();
       
  2523 					r.insertNode(t.getRng().createContextualFragment(h + '<span id="__caret">_</span>'));
       
  2524 					t.select(t.dom.get('__caret'));
       
  2525 					t.getRng().deleteContents();
       
  2526 					return;
       
  2527 				}
  2413 
  2528 
  2414 				// Use insert HTML if it exists (places cursor after content)
  2529 				// Use insert HTML if it exists (places cursor after content)
  2415 				if (d.queryCommandEnabled('InsertHTML'))
  2530 				if (d.queryCommandEnabled('InsertHTML'))
  2416 					return d.execCommand('InsertHTML', false, h);
  2531 					return d.execCommand('InsertHTML', false, h);
  2417 
  2532 
  2659 					} catch (ex2) {
  2774 					} catch (ex2) {
  2660 						return true;
  2775 						return true;
  2661 					}
  2776 					}
  2662 				}
  2777 				}
  2663 
  2778 
  2664 				r.select();
  2779 				try {
       
  2780 					r.select();
       
  2781 				} catch (ex) {
       
  2782 					// Needed for some odd IE bug #1843306
       
  2783 				}
  2665 
  2784 
  2666 				return true;
  2785 				return true;
  2667 			}
  2786 			}
  2668 
  2787 
  2669 			// Handle W3C
  2788 			// Handle W3C
  2751 
  2870 
  2752 			return n;
  2871 			return n;
  2753 		},
  2872 		},
  2754 
  2873 
  2755 		isCollapsed : function() {
  2874 		isCollapsed : function() {
  2756 			var t = this, r = t.getRng();
  2875 			var t = this, r = t.getRng(), s = t.getSel();
  2757 
  2876 
  2758 			if (!r || r.item)
  2877 			if (!r || r.item)
  2759 				return false;
  2878 				return false;
  2760 
  2879 
  2761 			return r.boundingWidth == 0 || t.getSel().isCollapsed;
  2880 			return !s || r.boundingWidth == 0 || s.isCollapsed;
  2762 		},
  2881 		},
  2763 
  2882 
  2764 		collapse : function(b) {
  2883 		collapse : function(b) {
  2765 			var t = this, r = t.getRng(), n;
  2884 			var t = this, r = t.getRng(), n;
  2766 
  2885 
  2782 		},
  2901 		},
  2783 
  2902 
  2784 		getRng : function() {
  2903 		getRng : function() {
  2785 			var t = this, s = t.getSel(), r;
  2904 			var t = this, s = t.getSel(), r;
  2786 
  2905 
  2787 			if (!s)
       
  2788 				return null;
       
  2789 
       
  2790 			try {
  2906 			try {
  2791 				r = s.rangeCount > 0 ? s.getRangeAt(0) : (s.createRange ? s.createRange() : t.win.document.createRange());
  2907 				if (s)
       
  2908 					r = s.rangeCount > 0 ? s.getRangeAt(0) : (s.createRange ? s.createRange() : t.win.document.createRange());
  2792 			} catch (ex) {
  2909 			} catch (ex) {
  2793 				// IE throws unspecified error here if TinyMCE is placed in a frame/iframe
  2910 				// IE throws unspecified error here if TinyMCE is placed in a frame/iframe
  2794 				// So lets create just an empty range for now to keep it happy
  2911 			}
  2795 				r = this.win.document.body.createTextRange();
  2912 
  2796 			}
  2913 			// No range found then create an empty one
       
  2914 			// This can occur when the editor is placed in a hidden container element on Gecko
       
  2915 			// Or on IE when there was an exception
       
  2916 			if (!r)
       
  2917 				r = isIE ? t.win.document.body.createTextRange() : t.win.document.createRange();
  2797 
  2918 
  2798 			return r;
  2919 			return r;
  2799 		},
  2920 		},
  2800 
  2921 
  2801 		setRng : function(r) {
  2922 		setRng : function(r) {
  2802 			var s;
  2923 			var s;
  2803 
  2924 
  2804 			if (!isIE) {
  2925 			if (!isIE) {
  2805 				s = this.getSel();
  2926 				s = this.getSel();
  2806 				s.removeAllRanges();
  2927 
  2807 				s.addRange(r);
  2928 				if (s) {
  2808 			} else
  2929 					s.removeAllRanges();
  2809 				r.select();
  2930 					s.addRange(r);
       
  2931 				}
       
  2932 			} else {
       
  2933 				try {
       
  2934 					r.select();
       
  2935 				} catch (ex) {
       
  2936 					// Needed for some odd IE bug #1843306
       
  2937 				}
       
  2938 			}
  2810 		},
  2939 		},
  2811 
  2940 
  2812 		setNode : function(n) {
  2941 		setNode : function(n) {
  2813 			var t = this;
  2942 			var t = this;
  2814 
  2943 
  2923 
  3052 
  2924 		getContent : function() {
  3053 		getContent : function() {
  2925 			var h;
  3054 			var h;
  2926 
  3055 
  2927 			h = this.doc.xml || new XMLSerializer().serializeToString(this.doc);
  3056 			h = this.doc.xml || new XMLSerializer().serializeToString(this.doc);
  2928 			h = h.replace(/<\?[^?]+\?>|<html>|<\/html>|<html\/>/g, '');
  3057 			h = h.replace(/<\?[^?]+\?>|<html>|<\/html>|<html\/>|<!DOCTYPE[^>]+>/g, '');
  2929 			h = h.replace(/ ?\/>/g, ' />');
  3058 			h = h.replace(/ ?\/>/g, ' />');
  2930 
  3059 
  2931 			// Since Opera doesn't escape > into &gt; we need to do it our self
  3060 			// Since Opera doesn't escape > into &gt; we need to do it our self to normalize the output for all browsers
  2932 			if (tinymce.isOpera)
  3061 			if (tinymce.isOpera)
  2933 				h = h.replace(/\|>/g, '&gt;');
  3062 				h = h.replace(/\|>/g, '&gt;');
  2934 
  3063 
  2935 			return h;
  3064 			return h;
  2936 		}
  3065 		}
  3076 					}));
  3205 					}));
  3077 				});
  3206 				});
  3078 			}
  3207 			}
  3079 		},
  3208 		},
  3080 
  3209 
  3081 		encode : function(o) {
       
  3082 			var t = this, s = t.settings, l;
       
  3083 
       
  3084 			if (s.entity_encoding.indexOf('named') != -1) {
       
  3085 				t.setEntities(s.entities);
       
  3086 				l = t.entityLookup;
       
  3087 
       
  3088 				if (o.format == 'html') {
       
  3089 					o.content = o.content.replace(t.entitiesRE, function(a) {
       
  3090 						var v;
       
  3091 
       
  3092 						if (v = l[a])
       
  3093 							a = '&' + v + ';';
       
  3094 
       
  3095 						return a;
       
  3096 					});
       
  3097 				}
       
  3098 			}
       
  3099 
       
  3100 			if (s.entity_encoding.indexOf('numeric') != -1) {
       
  3101 				if (o.format == 'html') {
       
  3102 					o.content = o.content.replace(/[\u007E-\uFFFF]/g, function(a) {
       
  3103 						return '&#' + a.charCodeAt(0) + ';';
       
  3104 					});
       
  3105 				}
       
  3106 			}
       
  3107 		},
       
  3108 
       
  3109 		setEntities : function(s) {
  3210 		setEntities : function(s) {
  3110 			var a, i, l = {}, re = '', v;
  3211 			var t = this, a, i, l = {}, re = '', v;
  3111 
  3212 
  3112 			// No need to setup more than once
  3213 			// No need to setup more than once
  3113 			if (this.entityLookup)
  3214 			if (t.entityLookup)
  3114 				return;
  3215 				return;
  3115 
  3216 
  3116 			// Build regex and lookup array
  3217 			// Build regex and lookup array
  3117 			a = s.split(',');
  3218 			a = s.split(',');
  3118 			for (i = 0; i < a.length; i += 2) {
  3219 			for (i = 0; i < a.length; i += 2) {
  3126 
  3227 
  3127 				v = parseInt(a[i]).toString(16);
  3228 				v = parseInt(a[i]).toString(16);
  3128 				re += '\\u' + '0000'.substring(v.length) + v;
  3229 				re += '\\u' + '0000'.substring(v.length) + v;
  3129 			}
  3230 			}
  3130 
  3231 
  3131 			this.entitiesRE = new RegExp('[' + re + ']', 'g');
  3232 			if (!re) {
  3132 			this.entityLookup = l;
  3233 				t.settings.entity_encoding = 'raw';
       
  3234 				return;
       
  3235 			}
       
  3236 
       
  3237 			t.entitiesRE = new RegExp('[' + re + ']', 'g');
       
  3238 			t.entityLookup = l;
  3133 		},
  3239 		},
  3134 
  3240 
  3135 		setValidChildRules : function(s) {
  3241 		setValidChildRules : function(s) {
  3136 			this.childRules = null;
  3242 			this.childRules = null;
  3137 			this.addValidChildRules(s);
  3243 			this.addValidChildRules(s);
  3435 			o.content = t.writer.getContent();
  3541 			o.content = t.writer.getContent();
  3436 
  3542 
  3437 			if (!o.no_events)
  3543 			if (!o.no_events)
  3438 				t.onPostProcess.dispatch(t, o);
  3544 				t.onPostProcess.dispatch(t, o);
  3439 
  3545 
  3440 			t.encode(o);
       
  3441 			t.indent(o);
       
  3442 			t._postProcess(o);
  3546 			t._postProcess(o);
  3443 
       
  3444 			o.node = null;
  3547 			o.node = null;
  3445 
  3548 
  3446 			return tinymce.trim(o.content);
  3549 			return tinymce.trim(o.content);
  3447 		},
  3550 		},
  3448 
  3551 
  3449 		indent : function(o) {
  3552 		// Internal functions
  3450 			var t = this, s = t.settings, h = o.content, sc = [], p;
  3553 
  3451 
  3554 		_postProcess : function(o) {
  3452 			// Remove whitespace to normalize browsers
  3555 			var t = this, s = t.settings, h = o.content, sc = [], p, l;
       
  3556 
  3453 			if (o.format == 'html') {
  3557 			if (o.format == 'html') {
  3454 				// Protect some elements
  3558 				// Protect some elements
  3455 				p = t._protect({
  3559 				p = t._protect({
  3456 					content : h,
  3560 					content : h,
  3457 					patterns : [
  3561 					patterns : [
  3458 						/<script[^>]*>(.*?)<\/script>/g,
  3562 						/(<script[^>]*>)(.*?)(<\/script>)/g,
  3459 						/<style[^>]*>(.*?)<\/style>/g,
  3563 						/(<style[^>]*>)(.*?)(<\/style>)/g,
  3460 						/<pre[^>]*>(.*?)<\/pre>/g
  3564 						/(<pre[^>]*>)(.*?)(<\/pre>)/g
  3461 					]
  3565 					]
  3462 				});
  3566 				});
  3463 
  3567 
  3464 				h = p.content;
  3568 				h = p.content;
  3465 
  3569 
       
  3570 				// Entity encode
       
  3571 				if (s.entity_encoding !== 'raw') {
       
  3572 					if (s.entity_encoding.indexOf('named') != -1) {
       
  3573 						t.setEntities(s.entities);
       
  3574 						l = t.entityLookup;
       
  3575 
       
  3576 						h = h.replace(t.entitiesRE, function(a) {
       
  3577 							var v;
       
  3578 
       
  3579 							if (v = l[a])
       
  3580 								a = '&' + v + ';';
       
  3581 
       
  3582 							return a;
       
  3583 						});
       
  3584 					}
       
  3585 
       
  3586 					if (s.entity_encoding.indexOf('numeric') != -1) {
       
  3587 						h = h.replace(/[\u007E-\uFFFF]/g, function(a) {
       
  3588 							return '&#' + a.charCodeAt(0) + ';';
       
  3589 						});
       
  3590 					}
       
  3591 				}
       
  3592 
       
  3593 				// Use BR instead of &nbsp; padded P elements inside editor and use <p>&nbsp;</p> outside editor
       
  3594 				if (o.set)
       
  3595 					h = h.replace(/<p>\s+(&nbsp;|&#160;|\u00a0|<br \/>)\s+<\/p>/g, '<p><br /></p>');
       
  3596 				else
       
  3597 					h = h.replace(/<p>\s+(&nbsp;|&#160;|\u00a0|<br \/>)\s+<\/p>/g, '<p>$1</p>');
       
  3598 
  3466 				// Since Gecko and Safari keeps whitespace in the DOM we need to
  3599 				// Since Gecko and Safari keeps whitespace in the DOM we need to
  3467 				// remove it inorder to match other browsers. But I think Gecko and Safari is right.
  3600 				// remove it inorder to match other browsers. But I think Gecko and Safari is right.
  3468 				if (s.remove_linebreaks) {
  3601 				// This process is only done when getting contents out from the editor.
  3469 					h = h.replace(/(<[^>]+>)\s+/g, '$1 ');
  3602 				if (!o.set) {
  3470 					h = h.replace(/\s+(<\/[^>]+>)/g, ' $1');
  3603 					if (s.remove_linebreaks) {
  3471 					h = h.replace(/<(p|h[1-6]|hr|div|table|tbody|tr|td|body|head|html|title|meta|style|pre|script|link|object) ([^>]+)>\s+/g, '<$1 $2>'); // Trim block start
  3604 						h = h.replace(/(<[^>]+>)\s+/g, '$1 ');
  3472 					h = h.replace(/<(p|h[1-6]|hr|div|table|tbody|tr|td|body|head|html|title|meta|style|pre|script|link|object)>\s+/g, '<$1>'); // Trim block start
  3605 						h = h.replace(/\s+(<\/[^>]+>)/g, ' $1');
  3473 					h = h.replace(/\s+<\/(p|h[1-6]|hr|div|table|tbody|tr|td|body|head|html|title|meta|style|pre|script|link|object)>/g, '</$1>'); // Trim block end
  3606 						h = h.replace(/<(p|h[1-6]|hr|div|table|tbody|tr|td|body|head|html|title|meta|style|pre|script|link|object) ([^>]+)>\s+/g, '<$1 $2>'); // Trim block start
  3474 				}
  3607 						h = h.replace(/<(p|h[1-6]|hr|div|table|tbody|tr|td|body|head|html|title|meta|style|pre|script|link|object)>\s+/g, '<$1>'); // Trim block start
  3475 
  3608 						h = h.replace(/\s+<\/(p|h[1-6]|hr|div|table|tbody|tr|td|body|head|html|title|meta|style|pre|script|link|object)>/g, '</$1>'); // Trim block end
  3476 				// Simple indentation
  3609 					}
  3477 				if (s.apply_source_formatting && s.indent_mode == 'simple') {
  3610 
  3478 					// Add line breaks before and after block elements
  3611 					// Simple indentation
  3479 					h = h.replace(/<(\/?)(ul|hr|table|meta|link|tbody|tr|object|body|head|html)(|[^>]+)>\s*/g, '\n<$1$2$3>\n');
  3612 					if (s.apply_source_formatting && s.indent_mode == 'simple') {
  3480 					h = h.replace(/<(p|h[1-6]|div|title|style|pre|script|td|li)(|[^>]+)>/g, '\n<$1$2>');
  3613 						// Add line breaks before and after block elements
  3481 					h = h.replace(/<\/(p|h[1-6]|div|title|style|pre|script|td|li)>/g, '</$1>\n');
  3614 						h = h.replace(/<(\/?)(ul|hr|table|meta|link|tbody|tr|object|body|head|html|map)(|[^>]+)>\s*/g, '\n<$1$2$3>\n');
  3482 					h = h.replace(/\n\n/g, '\n');
  3615 						h = h.replace(/\s*<(p|h[1-6]|div|title|style|pre|script|td|li|area)(|[^>]+)>/g, '\n<$1$2>');
       
  3616 						h = h.replace(/<\/(p|h[1-6]|div|title|style|pre|script|td|li)>\s*/g, '</$1>\n');
       
  3617 						h = h.replace(/\n\n/g, '\n');
       
  3618 					}
  3483 				}
  3619 				}
  3484 
  3620 
  3485 				h = t._unprotect(h, p);
  3621 				h = t._unprotect(h, p);
  3486 			}
  3622 			}
  3487 
  3623 
  3488 			o.content = h;
  3624 			o.content = h;
  3489 		},
  3625 		},
  3490 
       
  3491 		// Internal functions
       
  3492 
  3626 
  3493 		_serializeNode : function(n, inn) {
  3627 		_serializeNode : function(n, inn) {
  3494 			var t = this, s = t.settings, w = t.writer, hc, el, cn, i, l, a, at, no, v, nn, ru, ar, iv;
  3628 			var t = this, s = t.settings, w = t.writer, hc, el, cn, i, l, a, at, no, v, nn, ru, ar, iv;
  3495 
  3629 
  3496 			if (!s.node_filter || s.node_filter(n)) {
  3630 			if (!s.node_filter || s.node_filter(n)) {
  3499 						if (n.hasAttribute ? n.hasAttribute('mce_bogus') : n.getAttribute('mce_bogus'))
  3633 						if (n.hasAttribute ? n.hasAttribute('mce_bogus') : n.getAttribute('mce_bogus'))
  3500 							return;
  3634 							return;
  3501 
  3635 
  3502 						iv = false;
  3636 						iv = false;
  3503 						hc = n.hasChildNodes();
  3637 						hc = n.hasChildNodes();
  3504 
       
  3505 						nn = n.getAttribute('mce_name') || n.nodeName.toLowerCase();
  3638 						nn = n.getAttribute('mce_name') || n.nodeName.toLowerCase();
  3506 
  3639 
  3507 						// Add correct prefix on IE
  3640 						// Add correct prefix on IE
  3508 						if (isIE) {
  3641 						if (isIE) {
  3509 							if (n.scopeName !== 'HTML')
  3642 							if (n.scopeName !== 'HTML' && n.scopeName !== 'html')
  3510 								nn = n.scopeName + ':' + nn;
  3643 								nn = n.scopeName + ':' + nn;
  3511 						}
  3644 						}
  3512 
  3645 
  3513 						// Remove mce prefix on IE needed for the abbr element
  3646 						// Remove mce prefix on IE needed for the abbr element
  3514 						if (nn.indexOf('mce:') === 0)
  3647 						if (nn.indexOf('mce:') === 0)
  3668 					return '\r';
  3801 					return '\r';
  3669 				});
  3802 				});
  3670 			};
  3803 			};
  3671 
  3804 
  3672 			each(o.patterns, function(p) {
  3805 			each(o.patterns, function(p) {
  3673 				o.content = dec(enc(o.content).replace(p, function(a) {
  3806 				o.content = dec(enc(o.content).replace(p, function(x, a, b, c) {
  3674 					o.items.push(dec(a));
  3807 					o.items.push(dec(b));
  3675 					return '<!--mce:' + (o.items.length - 1) + '-->';
  3808 					return a + '<!--mce:' + (o.items.length - 1) + '-->' + c;
  3676 				}));
  3809 				}));
  3677 			});
  3810 			});
  3678 
  3811 
  3679 			return o;
  3812 			return o;
  3680 		},
  3813 		},
  3685 			});
  3818 			});
  3686 
  3819 
  3687 			o.items = [];
  3820 			o.items = [];
  3688 
  3821 
  3689 			return h;
  3822 			return h;
  3690 		},
       
  3691 
       
  3692 		_postProcess : function(o) {
       
  3693 			var s = this.settings, h;
       
  3694 
       
  3695 			if (o.format == 'html') {
       
  3696 				h = o.content;
       
  3697 
       
  3698 				// Use BR instead of &nbsp; padded P elements inside editor and use <p>&nbsp;</p> outside editor
       
  3699 				if (o.set)
       
  3700 					h = h.replace(/<p>\s+(&nbsp;|&#160;|\u00a0|<br \/>)\s+<\/p>/g, '<p><br /></p>');
       
  3701 				else
       
  3702 					h = h.replace(/<p>\s+(&nbsp;|&#160;|\u00a0|<br \/>)\s+<\/p>/g, '<p>$1</p>');
       
  3703 
       
  3704 				o.content = h;
       
  3705 			}
       
  3706 		},
  3823 		},
  3707 
  3824 
  3708 		_setup : function() {
  3825 		_setup : function() {
  3709 			var t = this, s = this.settings;
  3826 			var t = this, s = this.settings;
  3710 
  3827 
  3822 
  3939 
  3823 			return o;
  3940 			return o;
  3824 		},
  3941 		},
  3825 
  3942 
  3826 		load : function(u, cb, s) {
  3943 		load : function(u, cb, s) {
  3827 			var o;
  3944 			var t = this, o;
       
  3945 
       
  3946 			function loadScript(u) {
       
  3947 				if (tinymce.dom.Event.domLoaded || t.settings.strict_mode) {
       
  3948 					tinymce.util.XHR.send({
       
  3949 						url : u,
       
  3950 						error : t.settings.error,
       
  3951 						async : false,
       
  3952 						success : function(co) {
       
  3953 							t.eval(co);
       
  3954 						}
       
  3955 					});
       
  3956 				} else
       
  3957 					document.write('<script type="text/javascript" src="' + u + '"></script>');
       
  3958 			};
  3828 
  3959 
  3829 			if (!tinymce.is(u, 'string')) {
  3960 			if (!tinymce.is(u, 'string')) {
  3830 				o = [];
       
  3831 
       
  3832 				each(u, function(u) {
  3961 				each(u, function(u) {
  3833 					o.push({state : 0, url : u});
  3962 					loadScript(u);
  3834 				});
  3963 				});
  3835 
  3964 
  3836 				this.loadScripts(o, cb, s);
  3965 				if (cb)
  3837 			} else
  3966 					cb.call(s || t);
  3838 				this.loadScripts([{state : 0, url : u}], cb, s);
  3967 			} else {
       
  3968 				loadScript(u);
       
  3969 
       
  3970 				if (cb)
       
  3971 					cb.call(s || t);
       
  3972 			}
  3839 		},
  3973 		},
  3840 
  3974 
  3841 		loadQueue : function(cb, s) {
  3975 		loadQueue : function(cb, s) {
  3842 			var t = this;
  3976 			var t = this;
  3843 
  3977 
  4062 
  4196 
  4063 		renderHTML : function() {
  4197 		renderHTML : function() {
  4064 		},
  4198 		},
  4065 
  4199 
  4066 		renderTo : function(n) {
  4200 		renderTo : function(n) {
  4067 			n.innerHTML = this.renderHTML();
  4201 			DOM.setHTML(n, this.renderHTML());
  4068 		},
  4202 		},
  4069 
  4203 
  4070 		postRender : function() {
  4204 		postRender : function() {
  4071 			var t = this, b;
  4205 			var t = this, b;
  4072 
  4206 
  4265 			s.container = s.container || document.body;
  4399 			s.container = s.container || document.body;
  4266 			s.offset_x = s.offset_x || 0;
  4400 			s.offset_x = s.offset_x || 0;
  4267 			s.offset_y = s.offset_y || 0;
  4401 			s.offset_y = s.offset_y || 0;
  4268 			s.vp_offset_x = s.vp_offset_x || 0;
  4402 			s.vp_offset_x = s.vp_offset_x || 0;
  4269 			s.vp_offset_y = s.vp_offset_y || 0;
  4403 			s.vp_offset_y = s.vp_offset_y || 0;
       
  4404 
       
  4405 			if (is(s.icons) && !s.icons)
       
  4406 				s['class'] += ' noIcons';
       
  4407 
  4270 			this.parent(id, s);
  4408 			this.parent(id, s);
  4271 			this.onHideMenu = new tinymce.util.Dispatcher(this);
  4409 			this.onHideMenu = new tinymce.util.Dispatcher(this);
  4272 			this.classPrefix = 'mceMenu';
  4410 			this.classPrefix = 'mceMenu';
  4273 		},
  4411 		},
  4274 
  4412 
  4359 			t.mouseClickFunc = Event.add(co, 'click', function(e) {
  4497 			t.mouseClickFunc = Event.add(co, 'click', function(e) {
  4360 				var m;
  4498 				var m;
  4361 
  4499 
  4362 				e = e.target;
  4500 				e = e.target;
  4363 
  4501 
  4364 				if (e && (e = DOM.getParent(e, 'TR'))) {
  4502 				if (e && (e = DOM.getParent(e, 'TR')) && !DOM.hasClass(e, 'mceMenuItemSub')) {
  4365 					m = t.items[e.id];
  4503 					m = t.items[e.id];
  4366 
  4504 
  4367 					if (m.isDisabled())
  4505 					if (m.isDisabled())
  4368 						return;
  4506 						return;
  4369 
  4507 
  4407 					}
  4545 					}
  4408 				});
  4546 				});
  4409 			}
  4547 			}
  4410 		},
  4548 		},
  4411 
  4549 
  4412 		hideMenu : function() {
  4550 		hideMenu : function(c) {
  4413 			var t = this, co = DOM.get('menu_' + t.id), e;
  4551 			var t = this, co = DOM.get('menu_' + t.id), e;
  4414 
  4552 
  4415 			if (!t.isMenuVisible)
  4553 			if (!t.isMenuVisible)
  4416 				return;
  4554 				return;
  4417 
  4555 
  4418 			Event.remove(co, 'mouseover', t.mouseOverFunc);
  4556 			Event.remove(co, 'mouseover', t.mouseOverFunc);
  4419 			Event.remove(co, 'click', t.mouseClickFunc);
  4557 			Event.remove(co, 'click', t.mouseClickFunc);
  4420 			DOM.hide(co);
  4558 			DOM.hide(co);
  4421 			t.isMenuVisible = 0;
  4559 			t.isMenuVisible = 0;
  4422 
  4560 
       
  4561 			if (!c)
       
  4562 				t.collapse(1);
       
  4563 
  4423 			if (t.element)
  4564 			if (t.element)
  4424 				t.element.hide();
  4565 				t.element.hide();
  4425 
  4566 
  4426 			if (e = DOM.get(t.id))
  4567 			if (e = DOM.get(t.id))
  4427 				DOM.removeClass(e.firstChild, 'mceMenuItemActive');
  4568 				DOM.removeClass(e.firstChild, 'mceMenuItemActive');
  4440 			return o;
  4581 			return o;
  4441 		},
  4582 		},
  4442 
  4583 
  4443 		collapse : function(d) {
  4584 		collapse : function(d) {
  4444 			this.parent(d);
  4585 			this.parent(d);
  4445 			this.hideMenu();
  4586 			this.hideMenu(1);
  4446 		},
  4587 		},
  4447 
  4588 
  4448 		remove : function(o) {
  4589 		remove : function(o) {
  4449 			DOM.remove(o.id);
  4590 			DOM.remove(o.id);
  4450 
  4591 
  4847 			t.onPostRender.dispatch(t, DOM.get(t.id));
  4988 			t.onPostRender.dispatch(t, DOM.get(t.id));
  4848 		}
  4989 		}
  4849 
  4990 
  4850 		});
  4991 		});
  4851 })();
  4992 })();
  4852 /* file:jscripts/tiny_mce/classes/ui/SplitButton.js */
  4993 /* file:jscripts/tiny_mce/classes/ui/MenuButton.js */
  4853 
  4994 
  4854 (function() {
  4995 (function() {
  4855 	var DOM = tinymce.DOM, Event = tinymce.dom.Event, each = tinymce.each;
  4996 	var DOM = tinymce.DOM, Event = tinymce.dom.Event, each = tinymce.each;
  4856 
  4997 
  4857 	tinymce.create('tinymce.ui.SplitButton:tinymce.ui.Button', {
  4998 	tinymce.create('tinymce.ui.MenuButton:tinymce.ui.Button', {
  4858 		SplitButton : function(id, s) {
  4999 		MenuButton : function(id, s) {
  4859 			this.parent(id, s);
  5000 			this.parent(id, s);
  4860 			this.classPrefix = 'mceSplitButton';
       
  4861 			this.onRenderMenu = new tinymce.util.Dispatcher(this);
  5001 			this.onRenderMenu = new tinymce.util.Dispatcher(this);
  4862 			s.menu_container = s.menu_container || document.body;
  5002 			s.menu_container = s.menu_container || document.body;
  4863 		},
  5003 		},
  4864 
  5004 
  4865 		showMenu : function() {
  5005 		showMenu : function() {
  4882 			m.settings.vp_offset_x = p2.x;
  5022 			m.settings.vp_offset_x = p2.x;
  4883 			m.settings.vp_offset_y = p2.y;
  5023 			m.settings.vp_offset_y = p2.y;
  4884 			m.showMenu(0, e.clientHeight);
  5024 			m.showMenu(0, e.clientHeight);
  4885 
  5025 
  4886 			Event.add(document, 'mousedown', t.hideMenu, t);
  5026 			Event.add(document, 'mousedown', t.hideMenu, t);
  4887 			DOM.addClass(t.id, 'mceSplitButtonSelected');
  5027 			t.setState('Selected', 1);
  4888 		},
  5028 		},
  4889 
  5029 
  4890 		renderMenu : function() {
  5030 		renderMenu : function() {
  4891 			var t = this, m;
  5031 			var t = this, m;
  4892 
  5032 
  4893 			m = t.settings.control_manager.createDropMenu(t.id + '_menu', {
  5033 			m = t.settings.control_manager.createDropMenu(t.id + '_menu', {
  4894 				menu_line : 1,
  5034 				menu_line : 1,
  4895 				'class' : 'mceSplitButtonMenu'
  5035 				'class' : this.classPrefix + 'Menu',
       
  5036 				icons : t.settings.icons
  4896 			});
  5037 			});
  4897 
  5038 
  4898 			m.onHideMenu.add(t.hideMenu, t);
  5039 			m.onHideMenu.add(t.hideMenu, t);
  4899 
  5040 
  4900 			t.onRenderMenu.dispatch(t, m);
  5041 			t.onRenderMenu.dispatch(t, m);
  4903 
  5044 
  4904 		hideMenu : function(e) {
  5045 		hideMenu : function(e) {
  4905 			var t = this;
  5046 			var t = this;
  4906 
  5047 
  4907 			if (!e || !DOM.getParent(e.target, function(n) {return DOM.hasClass(n, 'mceMenu');})) {
  5048 			if (!e || !DOM.getParent(e.target, function(n) {return DOM.hasClass(n, 'mceMenu');})) {
  4908 				DOM.removeClass(t.id, 'mceSplitButtonSelected');
  5049 				t.setState('Selected', 0);
  4909 				Event.remove(document, 'mousedown', t.hideMenu, t);
  5050 				Event.remove(document, 'mousedown', t.hideMenu, t);
  4910 				if (t.menu)
  5051 				if (t.menu)
  4911 					t.menu.hideMenu();
  5052 					t.menu.hideMenu();
  4912 			}
  5053 			}
       
  5054 		},
       
  5055 
       
  5056 		postRender : function() {
       
  5057 			var t = this, s = t.settings;
       
  5058 
       
  5059 			Event.add(t.id, 'click', function() {
       
  5060 				if (!t.isDisabled()) {
       
  5061 					if (s.onclick)
       
  5062 						s.onclick(t.value);
       
  5063 
       
  5064 					t.showMenu();
       
  5065 				}
       
  5066 			});
       
  5067 		}
       
  5068 
       
  5069 		});
       
  5070 })();
       
  5071 
       
  5072 /* file:jscripts/tiny_mce/classes/ui/SplitButton.js */
       
  5073 
       
  5074 (function() {
       
  5075 	var DOM = tinymce.DOM, Event = tinymce.dom.Event, each = tinymce.each;
       
  5076 
       
  5077 	tinymce.create('tinymce.ui.SplitButton:tinymce.ui.MenuButton', {
       
  5078 		SplitButton : function(id, s) {
       
  5079 			this.parent(id, s);
       
  5080 			this.classPrefix = 'mceSplitButton';
  4913 		},
  5081 		},
  4914 
  5082 
  4915 		renderHTML : function() {
  5083 		renderHTML : function() {
  4916 			var h, t = this, s = t.settings, h1;
  5084 			var h, t = this, s = t.settings, h1;
  4917 
  5085 
  5050 				});
  5218 				});
  5051 			});
  5219 			});
  5052 
  5220 
  5053 			if (s.more_colors_func) {
  5221 			if (s.more_colors_func) {
  5054 				n = DOM.add(tb, 'tr');
  5222 				n = DOM.add(tb, 'tr');
  5055 				n = DOM.add(n, 'td', {colSpan : s.grid_width, 'class' : 'morecolors'});
  5223 				n = DOM.add(n, 'td', {colspan : s.grid_width, 'class' : 'morecolors'});
  5056 				n = DOM.add(n, 'a', {href : 'javascript:;', onclick : 'return false;', 'class' : 'morecolors'}, s.more_colors_title);
  5224 				n = DOM.add(n, 'a', {href : 'javascript:;', onclick : 'return false;', 'class' : 'morecolors'}, s.more_colors_title);
  5057 
  5225 
  5058 				Event.add(n, 'click', function(e) {
  5226 				Event.add(n, 'click', function(e) {
  5059 					s.more_colors_func.call(s.more_colors_scope || this);
  5227 					s.more_colors_func.call(s.more_colors_scope || this);
  5060 					return Event.cancel(e); // Cancel to fix onbeforeunload problem
  5228 					return Event.cancel(e); // Cancel to fix onbeforeunload problem
  5086 
  5254 
  5087 /* file:jscripts/tiny_mce/classes/ui/Toolbar.js */
  5255 /* file:jscripts/tiny_mce/classes/ui/Toolbar.js */
  5088 
  5256 
  5089 tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
  5257 tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
  5090 	renderHTML : function() {
  5258 	renderHTML : function() {
  5091 		var h = '', c = 'mceToolbarEnd', co, dom = tinymce.DOM;
  5259 		var t = this, h = '', c = 'mceToolbarEnd', co, dom = tinymce.DOM, s = t.settings;
  5092 
  5260 
  5093 		h += dom.createHTML('td', {'class' : 'mceToolbarStart'}, dom.createHTML('span', null, '<!-- IE -->'));
  5261 		h += dom.createHTML('td', {'class' : 'mceToolbarStart'}, dom.createHTML('span', null, '<!-- IE -->'));
  5094 
  5262 
  5095 		tinymce.each(this.controls, function(c) {
  5263 		tinymce.each(t.controls, function(c) {
  5096 			h += '<td>' + c.renderHTML() + '</td>';
  5264 			h += '<td>' + c.renderHTML() + '</td>';
  5097 		});
  5265 		});
  5098 
  5266 
  5099 		co = this.controls[this.controls.length - 1].constructor;
  5267 		co = t.controls[t.controls.length - 1].constructor;
  5100 
  5268 
  5101 		if (co === tinymce.ui.Button)
  5269 		if (co === tinymce.ui.Button)
  5102 			c += ' mceToolbarEndButton';
  5270 			c += ' mceToolbarEndButton';
  5103 		else if (co === tinymce.ui.SplitButton)
  5271 		else if (co === tinymce.ui.SplitButton)
  5104 			c += ' mceToolbarEndSplitButton';
  5272 			c += ' mceToolbarEndSplitButton';
  5105 		else if (co === tinymce.ui.ListBox)
  5273 		else if (co === tinymce.ui.ListBox)
  5106 			c += ' mceToolbarEndListBox';
  5274 			c += ' mceToolbarEndListBox';
  5107 
  5275 
  5108 		h += dom.createHTML('td', {'class' : c}, dom.createHTML('span', null, '<!-- IE -->'));
  5276 		h += dom.createHTML('td', {'class' : c}, dom.createHTML('span', null, '<!-- IE -->'));
  5109 
  5277 
  5110 		return dom.createHTML('table', {'class' : 'mceToolbar', cellpadding : '0', cellspacing : '0', align : this.settings.align}, '<tbody><tr>' + h + '</tr></tbody>');
  5278 		return dom.createHTML('table', {id : t.id, 'class' : 'mceToolbar' + (s['class'] ? ' ' + s['class'] : ''), cellpadding : '0', cellspacing : '0', align : t.settings.align || ''}, '<tbody><tr>' + h + '</tr></tbody>');
  5111 	}
  5279 	}
  5112 
  5280 
  5113 	});
  5281 	});
  5114 
  5282 
  5115 /* file:jscripts/tiny_mce/classes/AddOnManager.js */
  5283 /* file:jscripts/tiny_mce/classes/AddOnManager.js */
  5194 				return f.apply(s || this, Array.prototype.slice.call(arguments, 2));
  5362 				return f.apply(s || this, Array.prototype.slice.call(arguments, 2));
  5195 			};
  5363 			};
  5196 
  5364 
  5197 			s = extend({
  5365 			s = extend({
  5198 				theme : "simple",
  5366 				theme : "simple",
  5199 				language : "en"
  5367 				language : "en",
       
  5368 				strict_loading_mode : document.contentType == 'application/xhtml+xml'
  5200 			}, s);
  5369 			}, s);
  5201 
  5370 
  5202 			t.settings = s;
  5371 			t.settings = s;
  5203 
  5372 
  5204 			// If page not loaded and strict mode isn't enabled then load them
  5373 			// If page not loaded and strict mode isn't enabled then load them
  5450 		}
  5619 		}
  5451 
  5620 
  5452 		});
  5621 		});
  5453 
  5622 
  5454 	// Setup some URLs where the editor API is located and where the document is
  5623 	// Setup some URLs where the editor API is located and where the document is
  5455 	tinymce.documentBaseURL = document.location.href.replace(/[\?#].*$/, '').replace(/[\/\\][\w.]+$/, '');
  5624 	tinymce.documentBaseURL = window.location.href.replace(/[\?#].*$/, '').replace(/[\/\\][^\/]+$/, '');
  5456 	if (!/[\/\\]$/.test(tinymce.documentBaseURL))
  5625 	if (!/[\/\\]$/.test(tinymce.documentBaseURL))
  5457 		tinymce.documentBaseURL += '/';
  5626 		tinymce.documentBaseURL += '/';
  5458 
  5627 
  5459 	tinymce.baseURL = new tinymce.util.URI(tinymce.documentBaseURL).toAbsolute(tinymce.baseURL);
  5628 	tinymce.baseURL = new tinymce.util.URI(tinymce.documentBaseURL).toAbsolute(tinymce.baseURL);
  5460 	tinymce.EditorManager.baseURI = new tinymce.util.URI(tinymce.baseURL);
  5629 	tinymce.EditorManager.baseURI = new tinymce.util.URI(tinymce.baseURL);
  5555 				convert_fonts_to_spans : true,
  5724 				convert_fonts_to_spans : true,
  5556 				font_size_style_values : 'xx-small,x-small,small,medium,large,x-large,xx-large',
  5725 				font_size_style_values : 'xx-small,x-small,small,medium,large,x-large,xx-large',
  5557 				apply_source_formatting : 1,
  5726 				apply_source_formatting : 1,
  5558 				directionality : 'ltr',
  5727 				directionality : 'ltr',
  5559 				forced_root_block : 'p',
  5728 				forced_root_block : 'p',
  5560 				valid_elements : '@[id|class|style|title|dir<ltr?rtl|lang|xml::lang|onclick|ondblclick|onmousedown|onmouseup|onmouseover|onmousemove|onmouseout|onkeypress|onkeydown|onkeyup],a[rel|rev|charset|hreflang|tabindex|accesskey|type|name|href|target|title|class|onfocus|onblur],strong/b,em/i,strike,u,#p[align],-ol[type|compact],-ul[type|compact],-li,br,img[longdesc|usemap|src|border|alt=|title|hspace|vspace|width|height|align],-sub,-sup,-blockquote,-table[border=0|cellspacing|cellpadding|width|frame|rules|height|align|summary|bgcolor|background|bordercolor],-tr[rowspan|width|height|align|valign|bgcolor|background|bordercolor],tbody,thead,tfoot,#td[colspan|rowspan|width|height|align|valign|bgcolor|background|bordercolor|scope],#th[colspan|rowspan|width|height|align|valign|scope],caption,-div,-span,-pre,address,-h1,-h2,-h3,-h4,-h5,-h6,hr[size|noshade],-font[face|size|color],dd,dl,dt,cite,abbr,acronym,del[datetime|cite],ins[datetime|cite],object[classid|width|height|codebase|*],param[name|value|_value],embed[type|width|height|src|*]',
  5729 				valid_elements : '@[id|class|style|title|dir<ltr?rtl|lang|xml::lang|onclick|ondblclick|onmousedown|onmouseup|onmouseover|onmousemove|onmouseout|onkeypress|onkeydown|onkeyup],a[rel|rev|charset|hreflang|tabindex|accesskey|type|name|href|target|title|class|onfocus|onblur],strong/b,em/i,strike,u,#p[align],-ol[type|compact],-ul[type|compact],-li,br,img[longdesc|usemap|src|border|alt=|title|hspace|vspace|width|height|align],-sub,-sup,-blockquote,-table[border=0|cellspacing|cellpadding|width|frame|rules|height|align|summary|bgcolor|background|bordercolor],-tr[rowspan|width|height|align|valign|bgcolor|background|bordercolor],tbody,thead,tfoot,#td[colspan|rowspan|width|height|align|valign|bgcolor|background|bordercolor|scope],#th[colspan|rowspan|width|height|align|valign|scope],caption,-div,-span,-pre,address,-h1,-h2,-h3,-h4,-h5,-h6,hr[size|noshade],-font[face|size|color],dd,dl,dt,cite,abbr,acronym,del[datetime|cite],ins[datetime|cite],object[classid|width|height|codebase|*],param[name|value|_value],embed[type|width|height|src|*],script[type],map[name],area[shape|coords|href|alt|target]',
  5561 				hidden_input : 1,
  5730 				hidden_input : 1,
  5562 				padd_empty_editor : 1,
  5731 				padd_empty_editor : 1,
  5563 				render_ui : 1,
  5732 				render_ui : 1,
  5564 				init_theme : 1
  5733 				init_theme : 1,
       
  5734 				indentation : '30px'
  5565 			}, s);
  5735 			}, s);
  5566 
  5736 
  5567 			// Setup URIs
  5737 			// Setup URIs
  5568 			t.documentBaseURI = new tinymce.util.URI(s.document_base_url || tinymce.documentBaseURL, {
  5738 			t.documentBaseURI = new tinymce.util.URI(s.document_base_url || tinymce.documentBaseURL, {
  5569 				base_uri : tinyMCE.baseURI
  5739 				base_uri : tinyMCE.baseURI
  5575 		},
  5745 		},
  5576 
  5746 
  5577 		render : function() {
  5747 		render : function() {
  5578 			var t = this, s = t.settings, id = t.id, sl = tinymce.ScriptLoader;
  5748 			var t = this, s = t.settings, id = t.id, sl = tinymce.ScriptLoader;
  5579 
  5749 
       
  5750 			// Element not found, then skip initialization
       
  5751 			if (!t.getElement())
       
  5752 				return;
       
  5753 
       
  5754 			if (s.strict_loading_mode) {
       
  5755 				sl.settings.strict_mode = s.strict_loading_mode;
       
  5756 				tinymce.DOM.settings.strict = 1;
       
  5757 			}
       
  5758 
  5580 			// Add hidden input for non input elements inside form elements
  5759 			// Add hidden input for non input elements inside form elements
  5581 			if (!/TEXTAREA|INPUT/i.test(t.getElement().nodeName) && s.hidden_input && DOM.getParent(id, 'form'))
  5760 			if (!/TEXTAREA|INPUT/i.test(t.getElement().nodeName) && s.hidden_input && DOM.getParent(id, 'form'))
  5582 				DOM.insertAfter(DOM.create('input', {type : 'hidden', name : id}), id);
  5761 				DOM.insertAfter(DOM.create('input', {type : 'hidden', name : id}), id);
  5583 
       
  5584 			if (s.strict_loading_mode)
       
  5585 				sl.settings.strict_mode = s.strict_loading_mode;
       
  5586 
  5762 
  5587 			t.windowManager = new tinymce.WindowManager(t);
  5763 			t.windowManager = new tinymce.WindowManager(t);
  5588 
  5764 
  5589 			if (s.encoding == 'xml') {
  5765 			if (s.encoding == 'xml') {
  5590 				t.onGetContent.add(function(ed, o) {
  5766 				t.onGetContent.add(function(ed, o) {
  5592 						o.content = DOM.encode(o.content);
  5768 						o.content = DOM.encode(o.content);
  5593 				});
  5769 				});
  5594 			}
  5770 			}
  5595 
  5771 
  5596 			if (s.add_form_submit_trigger) {
  5772 			if (s.add_form_submit_trigger) {
  5597 				t.onSubmit.add(function() {
  5773 				t.onSubmit.addToTop(function() {
  5598 					if (t.initialized) {
  5774 					if (t.initialized) {
  5599 						t.save();
  5775 						t.save();
  5600 						t.isNotDirty = 1;
  5776 						t.isNotDirty = 1;
  5601 					}
  5777 					}
  5602 				});
  5778 				});
  5668 
  5844 
  5669 						Event.add(t.id, 'focus', ask);
  5845 						Event.add(t.id, 'focus', ask);
  5670 						return;
  5846 						return;
  5671 					}
  5847 					}
  5672 
  5848 
  5673 					t.init();
  5849 					if (!t.removed)
       
  5850 						t.init();
  5674 				});
  5851 				});
  5675 			};
  5852 			};
  5676 
  5853 
  5677 			// Load compat2x first
  5854 			// Load compat2x first
  5678 			if (s.plugins.indexOf('compat2x') != -1) {
  5855 			if (s.plugins.indexOf('compat2x') != -1) {
  5777 					width : w,
  5954 					width : w,
  5778 					height : h,
  5955 					height : h,
  5779 					deltaWidth : s.delta_width,
  5956 					deltaWidth : s.delta_width,
  5780 					deltaHeight : s.delta_height
  5957 					deltaHeight : s.delta_height
  5781 				});
  5958 				});
       
  5959 
       
  5960 				t.editorContainer = o.editorContainer;
  5782 			}
  5961 			}
  5783 
  5962 
  5784 			
  5963 			
  5785 			// Resize editor
  5964 			// Resize editor
  5786 			DOM.setStyles(o.sizeContainer || o.editorContainer, {
  5965 			DOM.setStyles(o.sizeContainer || o.editorContainer, {
  5787 				width : w,
  5966 				width : w,
  5788 				height : h
  5967 				height : h
  5789 			});
  5968 			});
  5790 
  5969 
  5791 			function createIfr() {
  5970 			h = (o.iframeHeight || h) + ((h + '').indexOf('%') == -1 ? (o.deltaHeight || 0) : '');
  5792 				h = (o.iframeHeight || h) + ((h + '').indexOf('%') == -1 ? (o.deltaHeight || 0) : '');
  5971 			if (h < 100)
  5793 				if (h < 100)
  5972 				h = 100;
  5794 					h = 100;
  5973 
  5795 
  5974 			// Create iframe
  5796 				// Create iframe
  5975 			n = DOM.add(o.iframeContainer, 'iframe', {
  5797 				n = DOM.add(o.iframeContainer, 'iframe', {
  5976 				id : s.id + "_ifr",
  5798 					id : s.id + "_ifr",
  5977 				src : 'javascript:""', // Workaround for HTTPS warning in IE6/7
  5799 					src : 'javascript:""', // Workaround for HTTPS warning in IE6/7
  5978 				frameBorder : '0',
  5800 					frameBorder : '0',
  5979 				style : {
  5801 					style : {
  5980 					width : '100%',
  5802 						width : '100%',
  5981 					height : h
  5803 						height : h
  5982 				}
  5804 					}
  5983 			});
  5805 				});
  5984 
  5806 
  5985 			t.contentAreaContainer = o.iframeContainer;
  5807 				t.contentAreaContainer = o.iframeContainer;
  5986 			DOM.get(o.editorContainer).style.display = t.orgDisplay;
  5808 				DOM.get(o.editorContainer).style.display = t.orgDisplay;
  5987 			DOM.get(s.id).style.display = 'none';
  5809 				DOM.get(s.id).style.display = 'none';
  5988 
  5810 
  5989 			// Safari 2.x requires us to wait for the load event and load a real HTML doc
  5811 				// Safari 2.x requires us to wait for the load event and load a real HTML doc
  5990 			if (tinymce.isOldWebKit) {
  5812 				if (tinymce.isOldWebKit) {
  5991 				Event.add(n, 'load', t.setupIframe, t);
  5813 					Event.add(n, 'load', t.setupIframe, t);
  5992 				n.src = tinymce.baseURL + '/plugins/safari/blank.htm';
  5814 					n.src = tinymce.baseURL + '/plugins/safari/blank.htm';
  5993 			} else {
  5815 				} else {
  5994 				t.setupIframe();
  5816 					t.setupIframe();
  5995 				e = n = o = null; // Cleanup
  5817 					e = n = o = null; // Cleanup
  5996 			}
  5818 				}
       
  5819 			};
       
  5820 
       
  5821 			// Waits for the editor to become visible, then it will run the init
       
  5822 			// This method is somewhat ugly but this is the best way to deal with it without
       
  5823 			// forcing the user to add some logic to their application.
       
  5824 			if (isGecko) {
       
  5825 				function check() {
       
  5826 					var hi;
       
  5827 
       
  5828 					DOM.getParent(t.id, function(e) {
       
  5829 						if (DOM.getStyle(e, 'display', true) == 'none') {
       
  5830 							hi = 1;
       
  5831 							return true;
       
  5832 						}
       
  5833 					});
       
  5834 
       
  5835 					return hi;
       
  5836 				};
       
  5837 
       
  5838 				if (check()) {
       
  5839 					ti = window.setInterval(function() {
       
  5840 						if (!check()) {
       
  5841 							createIfr();
       
  5842 							window.clearInterval(ti);
       
  5843 						}
       
  5844 					}, 300);
       
  5845 
       
  5846 					return;
       
  5847 				}
       
  5848 			}
       
  5849 
       
  5850 			createIfr();
       
  5851 		},
  5997 		},
  5852 
  5998 
  5853 		setupIframe : function() {
  5999 		setupIframe : function() {
  5854 			var t = this, s = t.settings, e = DOM.get(s.id), d = t.getDoc();
  6000 			var t = this, s = t.settings, e = DOM.get(s.id), d = t.getDoc();
  5855 
       
  5856 			// Design mode needs to be added here Ctrl+A will fail otherwise
       
  5857 			if (!isIE)
       
  5858 				d.designMode = 'On';
       
  5859 
  6001 
  5860 			// Setup body
  6002 			// Setup body
  5861 			d.open();
  6003 			d.open();
  5862 			d.write(s.doctype + '<html><head xmlns="http://www.w3.org/1999/xhtml"><base href="' + t.documentBaseURI.getURI() + '" /><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /></head><body id="tinymce" class="mceContentBody"></body></html>');
  6004 			d.write(s.doctype + '<html><head xmlns="http://www.w3.org/1999/xhtml"><base href="' + t.documentBaseURI.getURI() + '" /><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /></head><body id="tinymce" class="mceContentBody"></body></html>');
  5863 			d.close();
  6005 			d.close();
       
  6006 
       
  6007 			// Design mode needs to be added here Ctrl+A will fail otherwise
       
  6008 			if (!isIE) {
       
  6009 				try {
       
  6010 					d.designMode = 'On';
       
  6011 				} catch (ex) {
       
  6012 					// Will fail on Gecko if the editor is placed in an hidden container element
       
  6013 					// The design mode will be set ones the editor is focused
       
  6014 				}
       
  6015 			}
  5864 
  6016 
  5865 			// IE needs to use contentEditable or it will display non secure items for HTTPS
  6017 			// IE needs to use contentEditable or it will display non secure items for HTTPS
  5866 			if (isIE)
  6018 			if (isIE)
  5867 				t.getBody().contentEditable = true;
  6019 				t.getBody().contentEditable = true;
  5868 
  6020 
  5870 			t.dom = new tinymce.DOM.DOMUtils(t.getDoc(), {
  6022 			t.dom = new tinymce.DOM.DOMUtils(t.getDoc(), {
  5871 				keep_values : true,
  6023 				keep_values : true,
  5872 				url_converter : t.convertURL,
  6024 				url_converter : t.convertURL,
  5873 				url_converter_scope : t,
  6025 				url_converter_scope : t,
  5874 				hex_colors : s.force_hex_style_colors,
  6026 				hex_colors : s.force_hex_style_colors,
  5875 				class_filter : s.class_filter
  6027 				class_filter : s.class_filter,
       
  6028 				update_styles : 1
  5876 			});
  6029 			});
  5877 
  6030 
  5878 			t.serializer = new tinymce.dom.Serializer({
  6031 			t.serializer = new tinymce.dom.Serializer({
  5879 				entity_encoding : s.entity_encoding,
  6032 				entity_encoding : s.entity_encoding,
  5880 				entities : s.entities,
  6033 				entities : s.entities,
  5953 					if (o.initial)
  6106 					if (o.initial)
  5954 						o.content = o.content.replace(/\r?\n/g, '<br />');
  6107 						o.content = o.content.replace(/\r?\n/g, '<br />');
  5955 				});
  6108 				});
  5956 			}
  6109 			}
  5957 
  6110 
       
  6111 			if (s.fix_nesting && isIE) {
       
  6112 				t.onBeforeSetContent.add(function(ed, o) {
       
  6113 					o.content = t._fixNesting(o.content);
       
  6114 				});
       
  6115 			}
       
  6116 
  5958 			if (s.preformatted) {
  6117 			if (s.preformatted) {
  5959 				t.onPostProcess.add(function(ed, o) {
  6118 				t.onPostProcess.add(function(ed, o) {
  5960 					o.content = o.content.replace(/^\s*<pre.*?>/, '');
  6119 					o.content = o.content.replace(/^\s*<pre.*?>/, '');
  5961 					o.content = o.content.replace(/<\/pre>\s*$/, '');
  6120 					o.content = o.content.replace(/<\/pre>\s*$/, '');
  5962 
  6121 
  5997 
  6156 
  5998 			if (s.inline_styles)
  6157 			if (s.inline_styles)
  5999 				t._convertInlineElements();
  6158 				t._convertInlineElements();
  6000 
  6159 
  6001 			if (s.cleanup_callback) {
  6160 			if (s.cleanup_callback) {
  6002 				t.onSetContent.add(function(ed, o) {
  6161 				t.onBeforeSetContent.add(function(ed, o) {
  6003 					if (o.initial) {
  6162 					o.content = t.execCallback('cleanup_callback', 'insert_to_editor', o.content, o);
  6004 						t.setContent(t.execCallback('cleanup_callback', 'insert_to_editor', o.content, o), {format : 'raw', no_events : true});
       
  6005 						t.execCallback('cleanup_callback', 'insert_to_editor_dom', t.getDoc(), o);
       
  6006 					}
       
  6007 				});
  6163 				});
  6008 
  6164 
  6009 				t.onPreProcess.add(function(ed, o) {
  6165 				t.onPreProcess.add(function(ed, o) {
  6010 					if (o.set)
  6166 					if (o.set)
  6011 						t.execCallback('cleanup_callback', 'insert_to_editor_dom', o.node, o);
  6167 						t.execCallback('cleanup_callback', 'insert_to_editor_dom', o.node, o);
  6046 			});
  6202 			});
  6047 
  6203 
  6048 			// Remove empty contents
  6204 			// Remove empty contents
  6049 			if (s.padd_empty_editor) {
  6205 			if (s.padd_empty_editor) {
  6050 				t.onPostProcess.add(function(ed, o) {
  6206 				t.onPostProcess.add(function(ed, o) {
  6051 					o.content = o.content.replace(/^<p>(&nsbp;|#160;|\s)<\/p>$/, '');
  6207 					o.content = o.content.replace(/^<p>(&nbsp;|#160;|\s)<\/p>$/, '');
  6052 				});
  6208 				});
  6053 			}
  6209 			}
  6054 
  6210 
  6055 			t.load({initial : true, format : (s.cleanup_on_startup ? 'html' : 'raw')});
  6211 			if (isGecko) {
  6056 			t.startContent = t.getContent({format : 'raw'});
  6212 				try {
  6057 			t.undoManager.add({initial : true});
  6213 					// Design mode must be set here once again to fix a bug where
  6058 
  6214 					// Ctrl+A/Delete/Backspace didn't work if the editor was added using mceAddControl then removed then added again
  6059 			t.initialized = true;
  6215 					d.designMode = 'Off';
  6060 
  6216 					d.designMode = 'On';
  6061 			t.onInit.dispatch(t);
  6217 				} catch (ex) {
  6062 			t.execCallback('setupcontent_callback', t.id, t.getBody(), t.getDoc());
  6218 					// Will fail on Gecko if the editor is placed in an hidden container element
  6063 			t.execCallback('init_instance_callback', t);
  6219 					// The design mode will be set ones the editor is focused
  6064 			t.focus(true);
  6220 				}
  6065 			t.nodeChanged({initial : 1});
  6221 			}
  6066 
  6222 
  6067 			// Load specified content CSS last
  6223 			// A small timeout was needed since firefox will remove. Bug: #1838304
  6068 			if (s.content_css) {
  6224 			setTimeout(function () {
  6069 				tinymce.each(s.content_css.split(','), function(u) {
  6225 				if (t.removed)
  6070 					t.dom.loadCSS(t.documentBaseURI.toAbsolute(u));
  6226 					return;
  6071 				});
  6227 
  6072 			}
  6228 				t.load({initial : true, format : (s.cleanup_on_startup ? 'html' : 'raw')});
  6073 
  6229 				t.startContent = t.getContent({format : 'raw'});
  6074 			// Handle auto focus
  6230 				t.undoManager.add({initial : true});
  6075 			if (s.auto_focus) {
  6231 				t.initialized = true;
  6076 				setTimeout(function () {
  6232 
  6077 					var ed = EditorManager.get(s.auto_focus);
  6233 				t.onInit.dispatch(t);
  6078 
  6234 				t.execCallback('setupcontent_callback', t.id, t.getBody(), t.getDoc());
  6079 					ed.selection.select(ed.getBody(), 1);
  6235 				t.execCallback('init_instance_callback', t);
  6080 					ed.selection.collapse(1);
  6236 				t.focus(true);
  6081 					ed.getWin().focus();
  6237 				t.nodeChanged({initial : 1});
  6082 				}, 100);
  6238 
  6083 			}
  6239 				// Load specified content CSS last
  6084 
  6240 				if (s.content_css) {
       
  6241 					tinymce.each(s.content_css.split(','), function(u) {
       
  6242 						t.dom.loadCSS(t.documentBaseURI.toAbsolute(u));
       
  6243 					});
       
  6244 				}
       
  6245 
       
  6246 				// Handle auto focus
       
  6247 				if (s.auto_focus) {
       
  6248 					setTimeout(function () {
       
  6249 						var ed = EditorManager.get(s.auto_focus);
       
  6250 
       
  6251 						ed.selection.select(ed.getBody(), 1);
       
  6252 						ed.selection.collapse(1);
       
  6253 						ed.getWin().focus();
       
  6254 					}, 100);
       
  6255 				}
       
  6256 			}, 1);
       
  6257 	
  6085 			e = null;
  6258 			e = null;
  6086 		},
  6259 		},
  6087 
  6260 
  6088 		
  6261 		
  6089 		focus : function(sf) {
  6262 		focus : function(sf) {
  6229 			});
  6402 			});
  6230 
  6403 
  6231 			return true;
  6404 			return true;
  6232 		},
  6405 		},
  6233 
  6406 
  6234 		execCommand : function(cmd, ui, val) {
  6407 		execCommand : function(cmd, ui, val, a) {
  6235 			var t = this, s = 0, o;
  6408 			var t = this, s = 0, o;
  6236 
  6409 
  6237 			if (!/^(mceAddUndoLevel|mceEndUndoLevel|mceBeginUndoLevel|mceRepaint)$/.test(cmd))
  6410 			if (!/^(mceAddUndoLevel|mceEndUndoLevel|mceBeginUndoLevel|mceRepaint|SelectAll)$/.test(cmd) && (!a || !a.skip_focus))
  6238 				t.focus();
  6411 				t.focus();
  6239 
  6412 
  6240 			o = {};
  6413 			o = {};
  6241 			t.onBeforeExecCommand.dispatch(t, cmd, ui, val, o);
  6414 			t.onBeforeExecCommand.dispatch(t, cmd, ui, val, o);
  6242 			if (o.terminate)
  6415 			if (o.terminate)
  6243 				return false;
  6416 				return false;
  6244 
  6417 
  6245 			// Comamnd callback
  6418 			// Comamnd callback
  6246 			if (t.execCallback('execcommand_callback', null, t.id, t.selection.getNode(), cmd, ui, val)) {
  6419 			if (t.execCallback('execcommand_callback', t.id, t.selection.getNode(), cmd, ui, val)) {
  6247 				t.onExecCommand.dispatch(t, cmd, ui, val);
  6420 				t.onExecCommand.dispatch(t, cmd, ui, val);
  6248 				return true;
  6421 				return true;
  6249 			}
  6422 			}
  6250 
  6423 
  6251 			// Registred commands
  6424 			// Registred commands
  6285 		},
  6458 		},
  6286 
  6459 
  6287 		queryCommandState : function(c) {
  6460 		queryCommandState : function(c) {
  6288 			var t = this, o;
  6461 			var t = this, o;
  6289 
  6462 
       
  6463 			// Is hidden then return undefined
       
  6464 			if (t._isHidden())
       
  6465 				return;
       
  6466 
  6290 			// Registred commands
  6467 			// Registred commands
  6291 			if (o = t.queryStateCommands[c])
  6468 			if (o = t.queryStateCommands[c])
  6292 				return o.func.call(o.scope);
  6469 				return o.func.call(o.scope);
  6293 
  6470 
  6294 			// Registred commands
  6471 			// Registred commands
  6301 		},
  6478 		},
  6302 
  6479 
  6303 		queryCommandValue : function(c) {
  6480 		queryCommandValue : function(c) {
  6304 			var t = this, o;
  6481 			var t = this, o;
  6305 
  6482 
       
  6483 			// Is hidden then return undefined
       
  6484 			if (t._isHidden())
       
  6485 				return;
       
  6486 
  6306 			// Registred commands
  6487 			// Registred commands
  6307 			if (o = t.queryValueCommands[c])
  6488 			if (o = t.queryValueCommands[c])
  6308 				return o.func.call(o.scope);
  6489 				return o.func.call(o.scope);
  6309 
  6490 
  6310 			// Registred commands
  6491 			// Registred commands
  6323 			DOM.hide(t.id);
  6504 			DOM.hide(t.id);
  6324 			t.load();
  6505 			t.load();
  6325 		},
  6506 		},
  6326 
  6507 
  6327 		hide : function() {
  6508 		hide : function() {
  6328 			var t = this, s = t.settings;
  6509 			var t = this, s = t.settings, d = t.getDoc();
  6329 
  6510 
  6330 			// Fixed bug where IE has a blinking cursor left from the editor
  6511 			// Fixed bug where IE has a blinking cursor left from the editor
  6331 			if (isIE)
  6512 			if (isIE && d)
  6332 				t.execCommand('SelectAll');
  6513 				d.execCommand('SelectAll');
  6333 
  6514 
  6334 			DOM.hide(t.getContainer());
  6515 			DOM.hide(t.getContainer());
  6335 			DOM.setStyle(s.id, 'display', t.orgDisplay);
  6516 			DOM.setStyle(s.id, 'display', t.orgDisplay);
  6336 			t.save();
  6517 			t.save();
  6337 		},
  6518 		},
  6382 			return h;
  6563 			return h;
  6383 		},
  6564 		},
  6384 
  6565 
  6385 		save : function(o) {
  6566 		save : function(o) {
  6386 			var t = this, e = t.getElement(), h, f;
  6567 			var t = this, e = t.getElement(), h, f;
       
  6568 
       
  6569 			if (!t.initialized)
       
  6570 				return;
  6387 
  6571 
  6388 			o = o || {};
  6572 			o = o || {};
  6389 			o.save = true;
  6573 			o.save = true;
  6390 
  6574 
  6391 			o.element = e;
  6575 			o.element = e;
  6428 				t.onBeforeSetContent.dispatch(t, o);
  6612 				t.onBeforeSetContent.dispatch(t, o);
  6429 
  6613 
  6430 			// Padd empty content in Gecko and Safari. Commands will otherwise fail on the content
  6614 			// Padd empty content in Gecko and Safari. Commands will otherwise fail on the content
  6431 			// It will also be impossible to place the caret in the editor unless there is a BR element present
  6615 			// It will also be impossible to place the caret in the editor unless there is a BR element present
  6432 			if (!tinymce.isIE && (h.length === 0 || /^\s+$/.test(h))) {
  6616 			if (!tinymce.isIE && (h.length === 0 || /^\s+$/.test(h))) {
  6433 				o.content = t.dom.setHTML(t.getBody(), '<br mce_bogus="1" />');
  6617 				o.content = t.dom.setHTML(t.getBody(), '<br mce_bogus="1" />', 1);
  6434 				o.format = 'raw';
  6618 				o.format = 'raw';
  6435 			}
  6619 			}
  6436 
  6620 
  6437 			o.content = t.dom.setHTML(t.getBody(), o.content);
  6621 			o.content = t.dom.setHTML(t.getBody(), tinymce.trim(o.content));
  6438 
  6622 
  6439 			if (o.format != 'raw' && t.settings.cleanup) {
  6623 			if (o.format != 'raw' && t.settings.cleanup) {
  6440 				o.getInner = true;
  6624 				o.getInner = true;
  6441 				o.content = t.dom.setHTML(t.getBody(), t.serializer.serialize(t.getBody(), o));
  6625 				o.content = t.dom.setHTML(t.getBody(), t.serializer.serialize(t.getBody(), o));
  6442 			}
  6626 			}
  6478 
  6662 
  6479 		getContainer : function() {
  6663 		getContainer : function() {
  6480 			var t = this;
  6664 			var t = this;
  6481 
  6665 
  6482 			if (!t.container)
  6666 			if (!t.container)
  6483 				t.container = DOM.get(t.id + "_parent");
  6667 				t.container = DOM.get(t.editorContainer || t.id + '_parent');
  6484 
  6668 
  6485 			return t.container;
  6669 			return t.container;
  6486 		},
  6670 		},
  6487 
  6671 
  6488 		getContentAreaContainer : function() {
  6672 		getContentAreaContainer : function() {
  6492 		getElement : function() {
  6676 		getElement : function() {
  6493 			return DOM.get(this.settings.content_element || this.id);
  6677 			return DOM.get(this.settings.content_element || this.id);
  6494 		},
  6678 		},
  6495 
  6679 
  6496 		getWin : function() {
  6680 		getWin : function() {
  6497 			var t = this;
  6681 			var t = this, e;
  6498 
  6682 
  6499 			if (!t.contentWindow)
  6683 			if (!t.contentWindow) {
  6500 				t.contentWindow = DOM.get(t.id + "_ifr").contentWindow;
  6684 				e = DOM.get(t.id + "_ifr");
       
  6685 
       
  6686 				if (e)
       
  6687 					t.contentWindow = e.contentWindow;
       
  6688 			}
  6501 
  6689 
  6502 			return t.contentWindow;
  6690 			return t.contentWindow;
  6503 		},
  6691 		},
  6504 
  6692 
  6505 		getDoc : function() {
  6693 		getDoc : function() {
  6506 			var t = this;
  6694 			var t = this, w;
  6507 
  6695 
  6508 			if (!t.contentDocument)
  6696 			if (!t.contentDocument) {
  6509 				t.contentDocument = this.getWin().document;
  6697 				w = this.getWin();
       
  6698 
       
  6699 				if (w)
       
  6700 					t.contentDocument = w.document;
       
  6701 			}
  6510 
  6702 
  6511 			return t.contentDocument;
  6703 			return t.contentDocument;
  6512 		},
  6704 		},
  6513 
  6705 
  6514 		getBody : function() {
  6706 		getBody : function() {
  6596 			};
  6788 			};
  6597 
  6789 
  6598 			function eventHandler(e, o) {
  6790 			function eventHandler(e, o) {
  6599 				var ty = e.type;
  6791 				var ty = e.type;
  6600 
  6792 
       
  6793 				// Don't fire events when it's removed
       
  6794 				if (t.removed)
       
  6795 					return;
       
  6796 
  6601 				// Generic event handler
  6797 				// Generic event handler
  6602 				if (t.onEvent.dispatch(t, e, o) !== false) {
  6798 				if (t.onEvent.dispatch(t, e, o) !== false) {
  6603 					// Specific event handler
  6799 					// Specific event handler
  6604 					t[lo[e.fakeType || e.type]].dispatch(t, e, o);
  6800 					t[lo[e.fakeType || e.type]].dispatch(t, e, o);
  6605 				}
  6801 				}
  6686 			if (isGecko) {
  6882 			if (isGecko) {
  6687 				function setOpts() {
  6883 				function setOpts() {
  6688 					var t = this, d = t.getDoc(), s = t.settings;
  6884 					var t = this, d = t.getDoc(), s = t.settings;
  6689 
  6885 
  6690 					if (isGecko) {
  6886 					if (isGecko) {
       
  6887 						if (t._isHidden()) {
       
  6888 							try {
       
  6889 								d.designMode = 'On';
       
  6890 							} catch (ex) {
       
  6891 								// Fails if it's hidden
       
  6892 							}
       
  6893 						}
       
  6894 
  6691 						try {
  6895 						try {
  6692 							// Try new Gecko method
  6896 							// Try new Gecko method
  6693 							d.execCommand("styleWithCSS", 0, false);
  6897 							d.execCommand("styleWithCSS", 0, false);
  6694 						} catch (ex) {
  6898 						} catch (ex) {
  6695 							// Use old
  6899 							// Use old method
  6696 							d.execCommand("useCSS", 0, true);
  6900 							if (!t._isHidden())
       
  6901 								d.execCommand("useCSS", 0, true);
  6697 						}
  6902 						}
  6698 
  6903 
  6699 						if (!s.table_inline_editing)
  6904 						if (!s.table_inline_editing)
  6700 							try {d.execCommand('enableInlineTableEditing', false, false);} catch (ex) {}
  6905 							try {d.execCommand('enableInlineTableEditing', false, false);} catch (ex) {}
  6701 
  6906 
  6728 				};
  6933 				};
  6729 
  6934 
  6730 				function tabHandler(ed, e) {
  6935 				function tabHandler(ed, e) {
  6731 					var v, f, el;
  6936 					var v, f, el;
  6732 
  6937 
       
  6938 					function find(d) {
       
  6939 						f = DOM.getParent(ed.id, 'form'), el = f.elements;
       
  6940 
       
  6941 						if (f) {
       
  6942 							each(f.elements, function(e, i) {
       
  6943 								if (e.id == ed.id) {
       
  6944 									i = i + d;
       
  6945 
       
  6946 									if (i < 0 || i > el.length)
       
  6947 										return;
       
  6948 
       
  6949 									el = el[i];
       
  6950 								}
       
  6951 							});
       
  6952 						}
       
  6953 
       
  6954 						return el;
       
  6955 					};
       
  6956 
  6733 					if (e.keyCode === 9) {
  6957 					if (e.keyCode === 9) {
  6734 						v = ed.getParam('tab_focus');
  6958 						v = ed.getParam('tab_focus').split(',');
  6735 
  6959 
  6736 						if (v == ':next') {
  6960 						if (v.length == 1) {
  6737 							f = DOM.getParent(ed.id, 'form');
  6961 							v[1] = v[0];
  6738 
  6962 							v[0] = ':prev';
  6739 							if (f) {
  6963 						}
  6740 								each(f.elements, function(e, i) {
  6964 
  6741 									if (e.id == ed.id)
  6965 						// Find element to focus
  6742 										el = f.elements[i + 1];
  6966 						if (e.shiftKey) {
  6743 								});
  6967 							if (v[0] == ':prev')
  6744 							}
  6968 								el = find(-1);
  6745 						} else
  6969 							else
  6746 							el = DOM.get(v);
  6970 								el = DOM.get(v[0]);
       
  6971 						} else {
       
  6972 							if (v[1] == ':next')
       
  6973 								el = find(1);
       
  6974 							else
       
  6975 								el = DOM.get(v[1]);
       
  6976 						}
  6747 
  6977 
  6748 						if (el) {
  6978 						if (el) {
  6749 							window.setTimeout(function() {window.focus();el.focus();}, 10);
  6979 							if (ed = EditorManager.get(el.id || el.name))
       
  6980 								ed.focus();
       
  6981 							else
       
  6982 								window.setTimeout(function() {window.focus();el.focus();}, 10);
       
  6983 
  6750 							return Event.cancel(e);
  6984 							return Event.cancel(e);
  6751 						}
  6985 						}
  6752 					}
  6986 					}
  6753 				};
  6987 				};
  6754 
  6988 
  6882 							}
  7116 							}
  6883 					}
  7117 					}
  6884 				});
  7118 				});
  6885 			}
  7119 			}
  6886 
  7120 
       
  7121 			if (tinymce.isOpera) {
       
  7122 				t.onClick.add(function(ed, e) {
       
  7123 					Event.prevent(e);
       
  7124 				});
       
  7125 			}
       
  7126 
  6887 			// Add custom undo/redo handlers
  7127 			// Add custom undo/redo handlers
  6888 			if (s.custom_undo_redo) {
  7128 			if (s.custom_undo_redo) {
  6889 				function addUndo() {
  7129 				function addUndo() {
  6890 					t.undoManager.typing = 0;
  7130 					t.undoManager.typing = 0;
  6891 					t.undoManager.add();
  7131 					t.undoManager.add();
  6905 								addUndo();
  7145 								addUndo();
  6906 						}
  7146 						}
  6907 					});
  7147 					});
  6908 				} else {
  7148 				} else {
  6909 					Event.add(t.getDoc(), 'blur', function() {
  7149 					Event.add(t.getDoc(), 'blur', function() {
  6910 						if (!t.removed)
  7150 						if (t.selection && !t.removed)
  6911 							addUndo();
  7151 							addUndo();
  6912 					});
  7152 					});
  6913 				}
  7153 				}
  6914 
  7154 
  6915 				t.onMouseDown.add(addUndo);
  7155 				t.onMouseDown.add(addUndo);
  6957 		},
  7197 		},
  6958 
  7198 
  6959 		_convertInlineElements : function() {
  7199 		_convertInlineElements : function() {
  6960 			var t = this, s = t.settings, dom = t.dom;
  7200 			var t = this, s = t.settings, dom = t.dom;
  6961 
  7201 
  6962 			t.onPreProcess.add(function(ed, o) {
  7202 			function convert(ed, o) {
  6963 				if (!s.inline_styles)
  7203 				if (!s.inline_styles)
  6964 					return;
  7204 					return;
  6965 
  7205 
  6966 				if (o.get) {
  7206 				if (o.get) {
  6967 					each(t.dom.select('table,u,strike', o.node), function(n) {
  7207 					each(t.dom.select('table,u,strike', o.node), function(n) {
  6989 								dom.setAttrib(n, 'height', v.replace(/[^0-9%]+/g, ''));
  7229 								dom.setAttrib(n, 'height', v.replace(/[^0-9%]+/g, ''));
  6990 						} else {
  7230 						} else {
  6991 							// Convert spans to elements
  7231 							// Convert spans to elements
  6992 							if (n.style.textDecoration == 'underline')
  7232 							if (n.style.textDecoration == 'underline')
  6993 								dom.replace(dom.create('u'), n, 1);
  7233 								dom.replace(dom.create('u'), n, 1);
  6994 							else if (n.style.textDecoration == 'strikethrough')
  7234 							else if (n.style.textDecoration == 'line-through')
  6995 								dom.replace(dom.create('strike'), n, 1);
  7235 								dom.replace(dom.create('strike'), n, 1);
  6996 						}
  7236 						}
  6997 					});
  7237 					});
  6998 				}
  7238 				}
  6999 			});
  7239 			};
       
  7240 
       
  7241 			t.onPreProcess.add(convert);
       
  7242 
       
  7243 			if (!s.cleanup_on_startup) {
       
  7244 				t.onInit.add(function() {
       
  7245 					convert(t, {node : t.getBody(), set : 1});
       
  7246 				});
       
  7247 			}
  7000 		},
  7248 		},
  7001 
  7249 
  7002 		_convertFonts : function() {
  7250 		_convertFonts : function() {
  7003 			var t = this, s = t.settings, dom = t.dom, sl, cl, fz, fzn, v, i;
  7251 			var t = this, s = t.settings, dom = t.dom, sl, cl, fz, fzn, v, i;
  7004 
  7252 
  7069 
  7317 
  7070 						dom.replace(sp, n, 1);
  7318 						dom.replace(sp, n, 1);
  7071 					});
  7319 					});
  7072 				}
  7320 				}
  7073 			});
  7321 			});
       
  7322 		},
       
  7323 
       
  7324 		_isHidden : function() {
       
  7325 			var s;
       
  7326 
       
  7327 			if (!isGecko)
       
  7328 				return 0;
       
  7329 
       
  7330 			// Weird, wheres that cursor selection?
       
  7331 			s = this.selection.getSel();
       
  7332 			return (!s || !s.rangeCount || s.rangeCount == 0);
       
  7333 		},
       
  7334 
       
  7335 		_fixNesting : function(s) {
       
  7336 			var d = [], i;
       
  7337 
       
  7338 			s = s.replace(/<(\/)?([^\s>]+)[^>]*?>/g, function(a, b, c) {
       
  7339 				var e;
       
  7340 
       
  7341 				// Handle end element
       
  7342 				if (b === '/') {
       
  7343 					if (!d.length)
       
  7344 						return '';
       
  7345 
       
  7346 					if (c !== d[d.length - 1].tag) {
       
  7347 						for (i=d.length - 1; i>=0; i--) {
       
  7348 							if (d[i].tag === c) {
       
  7349 								d[i].close = 1;
       
  7350 								break;
       
  7351 							}
       
  7352 						}
       
  7353 
       
  7354 						return '';
       
  7355 					} else {
       
  7356 						d.pop();
       
  7357 
       
  7358 						if (d.length && d[d.length - 1].close) {
       
  7359 							a = a + '</' + d[d.length - 1].tag + '>';
       
  7360 							d.pop();
       
  7361 						}
       
  7362 					}
       
  7363 				} else {
       
  7364 					// Ignore these
       
  7365 					if (/^(br|hr|input|meta|img|link|param)$/i.test(c))
       
  7366 						return a;
       
  7367 
       
  7368 					// Ignore closed ones
       
  7369 					if (/\/>$/.test(a))
       
  7370 						return a;
       
  7371 
       
  7372 					d.push({tag : c}); // Push start element
       
  7373 				}
       
  7374 
       
  7375 				return a;
       
  7376 			});
       
  7377 
       
  7378 			// End all open tags
       
  7379 			for (i=d.length - 1; i>=0; i--)
       
  7380 				s += '</' + d[i].tag + '>';
       
  7381 
       
  7382 			return s;
  7074 		}
  7383 		}
  7075 
  7384 
  7076 		});
  7385 		});
  7077 })();
  7386 })();
  7078 
  7387 
  7141 
  7450 
  7142 			return false;
  7451 			return false;
  7143 		},
  7452 		},
  7144 
  7453 
  7145 		Indent : function() {
  7454 		Indent : function() {
  7146 			var ed = this.editor, d = ed.dom, s = ed.selection, e;
  7455 			var ed = this.editor, d = ed.dom, s = ed.selection, e, iv, iu;
       
  7456 
       
  7457 			// Setup indent level
       
  7458 			iv = ed.settings.indentation;
       
  7459 			iu = /[a-z%]+$/i.exec(iv);
       
  7460 			iv = parseInt(iv);
  7147 
  7461 
  7148 			if (ed.settings.inline_styles && (!this.queryStateInsertUnorderedList() && !this.queryStateInsertOrderedList())) {
  7462 			if (ed.settings.inline_styles && (!this.queryStateInsertUnorderedList() && !this.queryStateInsertOrderedList())) {
  7149 				each(this._getSelectedBlocks(), function(e) {
  7463 				each(this._getSelectedBlocks(), function(e) {
  7150 					d.setStyle(e, 'paddingLeft', (parseInt(e.style.paddingLeft || 0) + 30) + 'px');
  7464 					d.setStyle(e, 'paddingLeft', (parseInt(e.style.paddingLeft || 0) + iv) + iu);
  7151 				});
  7465 				});
  7152 
  7466 
  7153 				return;
  7467 				return;
  7154 			}
  7468 			}
  7155 
  7469 
  7163 				});
  7477 				});
  7164 			}
  7478 			}
  7165 		},
  7479 		},
  7166 
  7480 
  7167 		Outdent : function() {
  7481 		Outdent : function() {
  7168 			var ed = this.editor, d = ed.dom, s = ed.selection, e, v;
  7482 			var ed = this.editor, d = ed.dom, s = ed.selection, e, v, iv, iu;
       
  7483 
       
  7484 			// Setup indent level
       
  7485 			iv = ed.settings.indentation;
       
  7486 			iu = /[a-z%]+$/i.exec(iv);
       
  7487 			iv = parseInt(iv);
  7169 
  7488 
  7170 			if (ed.settings.inline_styles && (!this.queryStateInsertUnorderedList() && !this.queryStateInsertOrderedList())) {
  7489 			if (ed.settings.inline_styles && (!this.queryStateInsertUnorderedList() && !this.queryStateInsertOrderedList())) {
  7171 				each(this._getSelectedBlocks(), function(e) {
  7490 				each(this._getSelectedBlocks(), function(e) {
  7172 					v = Math.max(0, parseInt(e.style.paddingLeft || 0) - 30);
  7491 					v = Math.max(0, parseInt(e.style.paddingLeft || 0) - iv);
  7173 					d.setStyle(e, 'paddingLeft', v ? v + 'px' : '');
  7492 					d.setStyle(e, 'paddingLeft', v ? v + iu : '');
  7174 				});
  7493 				});
  7175 
  7494 
  7176 				return;
  7495 				return;
  7177 			}
  7496 			}
  7178 
  7497 
  7721 
  8040 
  7722 			if (tinymce.isGecko) {
  8041 			if (tinymce.isGecko) {
  7723 				try {
  8042 				try {
  7724 					s = e.selection;
  8043 					s = e.selection;
  7725 					b = s.getBookmark(true);
  8044 					b = s.getBookmark(true);
  7726 					s.getSel().selectAllChildren(e.getBody());
  8045 
       
  8046 					if (s.getSel())
       
  8047 						s.getSel().selectAllChildren(e.getBody());
       
  8048 
  7727 					s.collapse(true);
  8049 					s.collapse(true);
  7728 					s.moveToBookmark(b);
  8050 					s.moveToBookmark(b);
  7729 				} catch (ex) {
  8051 				} catch (ex) {
  7730 					// Ignore
  8052 					// Ignore
  7731 				}
  8053 				}
  7866 		t.onUndo = new Dispatcher(this);
  8188 		t.onUndo = new Dispatcher(this);
  7867 		t.onRedo = new Dispatcher(this);
  8189 		t.onRedo = new Dispatcher(this);
  7868 	},
  8190 	},
  7869 
  8191 
  7870 	add : function(l) {
  8192 	add : function(l) {
  7871 		var t = this, i, ed = t.editor, b, s = ed.settings;
  8193 		var t = this, i, ed = t.editor, b, s = ed.settings, la;
  7872 
  8194 
  7873 		l = l || {};
  8195 		l = l || {};
  7874 		l.content = l.content || ed.getContent({format : 'raw', no_events : 1});
  8196 		l.content = l.content || ed.getContent({format : 'raw', no_events : 1});
  7875 
  8197 
  7876 		// Add undo level if needed
  8198 		// Add undo level if needed
  7877 		l.content = l.content.replace(/^\s*|\s*$/g, '');
  8199 		l.content = l.content.replace(/^\s*|\s*$/g, '');
  7878 		if (!l.initial && l.content == t.data[t.index > 0 ? t.index - 1 : 0].content)
  8200 		la = t.data[t.index > 0 ? t.index - 1 : 0];
       
  8201 		if (!l.initial && la && l.content == la.content)
  7879 			return null;
  8202 			return null;
  7880 
  8203 
  7881 		// Time to compress
  8204 		// Time to compress
  7882 		if (s.custom_undo_redo_levels) {
  8205 		if (s.custom_undo_redo_levels) {
  7883 			if (t.data.length > s.custom_undo_redo_levels) {
  8206 			if (t.data.length > s.custom_undo_redo_levels) {
  7905 		// Set initial bookmark use first real undo level
  8228 		// Set initial bookmark use first real undo level
  7906 		if (t.data.length == 2 && t.data[0].initial)
  8229 		if (t.data.length == 2 && t.data[0].initial)
  7907 			t.data[0].bookmark = b;
  8230 			t.data[0].bookmark = b;
  7908 
  8231 
  7909 		t.onAdd.dispatch(t, l);
  8232 		t.onAdd.dispatch(t, l);
       
  8233 		ed.isNotDirty = 0;
  7910 
  8234 
  7911 		//console.dir(t.data);
  8235 		//console.dir(t.data);
  7912 
  8236 
  7913 		return l;
  8237 		return l;
  7914 	},
  8238 	},
  8002 				force_p_newlines : true
  8326 				force_p_newlines : true
  8003 			}, ed.settings);
  8327 			}, ed.settings);
  8004 
  8328 
  8005 			ed.onPreInit.add(t.setup, t);
  8329 			ed.onPreInit.add(t.setup, t);
  8006 
  8330 
  8007 			if (!isIE) {
  8331 			function padd(ed, o) {
  8008 				ed.onSetContent.add(function(ed, o) {
  8332 				if (isOpera)
  8009 					o.content = o.content.replace(/<p>[\s\u00a0]+<\/p>/g, '<p><br /></p>');
  8333 					o.content = o.content.replace(/(\u00a0|&#160;|&nbsp;)<\/p>/gi, '</p>');
  8010 				});
  8334 
  8011 			}
  8335 				o.content = o.content.replace(/<p( )([^>]+)><\/p>|<p( )([^>]+)\/>|<p( )([^>]+)>\s+<\/p>|<p><\/p>|<p\/>|<p>\s+<\/p>/gi, '<p$1$2$3$4$5$6>\u00a0</p>');
  8012 
  8336 
  8013 			ed.onPostProcess.add(function(ed, o) {
  8337 				if (!isIE && o.set) {
  8014 				o.content = o.content.replace(/<p><\/p>/g, '<p>\u00a0</p>');
  8338 					// Use &nbsp; instead of BR in padded paragraphs
  8015 
  8339 					o.content = o.content.replace(/<p( )([^>]+)>[\s\u00a0]+<\/p>|<p>[\s\u00a0]+<\/p>/gi, '<p$1$2><br /></p>');
  8016 				// Use BR instead of &nbsp; padded paragraphs
  8340 				} else {
  8017 				o.content = o.content.replace(/<p>\s*<br \/>\s*<\/p>/g, '<p>\u00a0</p>');
  8341 					o.content = o.content.replace(/<p( )([^>]+)>\s*<br \/>\s*<\/p>|<p>\s*<br \/>\s*<\/p>/gi, '<p$1$2>\u00a0</p>');
  8018 				o.content = o.content.replace(/\s*<br \/>\s*<\/p>/g, '</p>');
  8342 					o.content = o.content.replace(/\s*<br \/>\s*<\/p>/gi, '</p>');
  8019 			});
  8343 				}
       
  8344 			};
       
  8345 
       
  8346 			ed.onBeforeSetContent.add(padd);
       
  8347 			ed.onPostProcess.add(padd);
  8020 
  8348 
  8021 			if (s.forced_root_block) {
  8349 			if (s.forced_root_block) {
  8022 				ed.onInit.add(t.forceRoots, t);
  8350 				ed.onInit.add(t.forceRoots, t);
  8023 				ed.onSetContent.add(t.forceRoots, t);
  8351 				ed.onSetContent.add(t.forceRoots, t);
  8024 				ed.onBeforeGetContent.add(t.forceRoots, t);
  8352 				ed.onBeforeGetContent.add(t.forceRoots, t);
  8033 				ed.onKeyUp.add(t.forceRoots, t);
  8361 				ed.onKeyUp.add(t.forceRoots, t);
  8034 				ed.onPreProcess.add(t.forceRoots, t);
  8362 				ed.onPreProcess.add(t.forceRoots, t);
  8035 			}
  8363 			}
  8036 
  8364 
  8037 			if (s.force_br_newlines) {
  8365 			if (s.force_br_newlines) {
  8038 				ed.onKeyPress.add(function(ed, e) {
  8366 				// Force IE to produce BRs on enter
  8039 					var n, s = ed.selection;
  8367 				if (isIE) {
  8040 
  8368 					ed.onKeyPress.add(function(ed, e) {
  8041 					if (e.keyCode == 13) {
  8369 						var n, s = ed.selection;
  8042 						s.setContent('<br id="__" /> ', {format : 'raw'});
  8370 
  8043 						n = ed.dom.get('__');
  8371 						if (e.keyCode == 13) {
  8044 						n.removeAttribute('id');
  8372 							s.setContent('<br id="__" /> ', {format : 'raw'});
  8045 						s.select(n);
  8373 							n = ed.dom.get('__');
  8046 						s.collapse();
  8374 							n.removeAttribute('id');
  8047 						return Event.cancel(e);
  8375 							s.select(n);
  8048 					}
  8376 							s.collapse();
  8049 				});
  8377 							return Event.cancel(e);
       
  8378 						}
       
  8379 					});
       
  8380 				}
  8050 
  8381 
  8051 				return;
  8382 				return;
  8052 			}
  8383 			}
  8053 
  8384 
  8054 			if (!isIE && s.force_p_newlines) {
  8385 			if (!isIE && s.force_p_newlines) {
  8094 			}
  8425 			}
  8095 
  8426 
  8096 			return -1;
  8427 			return -1;
  8097 		},
  8428 		},
  8098 
  8429 
  8099 		forceRoots : function() {
  8430 		forceRoots : function(ed, e) {
  8100 			var t = this, ed = t.editor, b = ed.getBody(), d = ed.getDoc(), se = ed.selection, s = se.getSel(), r = se.getRng(), si = -2, ei, so, eo, tr, c = -0xFFFFFF;
  8431 			var t = this, ed = t.editor, b = ed.getBody(), d = ed.getDoc(), se = ed.selection, s = se.getSel(), r = se.getRng(), si = -2, ei, so, eo, tr, c = -0xFFFFFF;
  8101 			var nx, bl, bp, sp, le, nl = b.childNodes, i;
  8432 			var nx, bl, bp, sp, le, nl = b.childNodes, i;
       
  8433 
       
  8434 			// Fix for bug #1863847
       
  8435 			if (e && e.keyCode == 13)
       
  8436 				return true;
  8102 
  8437 
  8103 			// Wrap non blocks into blocks
  8438 			// Wrap non blocks into blocks
  8104 			for (i = nl.length - 1; i >= 0; i--) {
  8439 			for (i = nl.length - 1; i >= 0; i--) {
  8105 				nx = nl[i];
  8440 				nx = nl[i];
  8106 
  8441 
  8135 								}
  8470 								}
  8136 							}
  8471 							}
  8137 
  8472 
  8138 							bl = ed.dom.create(t.settings.forced_root_block);
  8473 							bl = ed.dom.create(t.settings.forced_root_block);
  8139 							bl.appendChild(nx.cloneNode(1));
  8474 							bl.appendChild(nx.cloneNode(1));
  8140 							b.replaceChild(bl, nx);
  8475 							nx.parentNode.replaceChild(bl, nx);
  8141 						}
  8476 						}
  8142 					} else {
  8477 					} else {
  8143 						if (bl.hasChildNodes())
  8478 						if (bl.hasChildNodes())
  8144 							bl.insertBefore(nx, bl.firstChild);
  8479 							bl.insertBefore(nx, bl.firstChild);
  8145 						else
  8480 						else
  8165 					if (ei != -1)
  8500 					if (ei != -1)
  8166 						r.setEnd(t.find(b, 1, ei), eo);
  8501 						r.setEnd(t.find(b, 1, ei), eo);
  8167 					else
  8502 					else
  8168 						r.setEnd(bl, 0);
  8503 						r.setEnd(bl, 0);
  8169 
  8504 
  8170 					s.removeAllRanges();
  8505 					if (s) {
  8171 					s.addRange(r);
  8506 						s.removeAllRanges();
       
  8507 						s.addRange(r);
       
  8508 					}
  8172 				} else {
  8509 				} else {
  8173 					try {
  8510 					try {
  8174 						r = s.createRange();
  8511 						r = s.createRange();
  8175 						r.moveToElementText(b);
  8512 						r.moveToElementText(b);
  8176 						r.collapse(1);
  8513 						r.collapse(1);
  8194 			var t = this, ed = t.editor, d = ed.getDoc(), se = t.settings, s = ed.selection.getSel(), r = s.getRangeAt(0), b = d.body;
  8531 			var t = this, ed = t.editor, d = ed.getDoc(), se = t.settings, s = ed.selection.getSel(), r = s.getRangeAt(0), b = d.body;
  8195 			var rb, ra, dir, sn, so, en, eo, sb, eb, bn, bef, aft, sc, ec, n;
  8532 			var rb, ra, dir, sn, so, en, eo, sb, eb, bn, bef, aft, sc, ec, n;
  8196 
  8533 
  8197 			function isEmpty(n) {
  8534 			function isEmpty(n) {
  8198 				n = n.innerHTML;
  8535 				n = n.innerHTML;
  8199 				n = n.replace(/<img|hr|table/g, 'd'); // Keep these
  8536 				n = n.replace(/<(img|hr|table)/gi, '-'); // Keep these convert them to - chars
  8200 				n = n.replace(/<[^>]+>/g, ''); // Remove all tags
  8537 				n = n.replace(/<[^>]+>/g, ''); // Remove all tags
  8201 
  8538 
  8202 				return n.replace(/[ \t\r\n]+/g, '') == '';
  8539 				return n.replace(/[ \t\r\n]+/g, '') == '';
  8203 			};
  8540 			};
  8204 
  8541 
  8205 			// If root blocks are forced then use Operas default behavior since it's really good
  8542 			// If root blocks are forced then use Operas default behavior since it's really good
  8206 			if (se.forced_root_block && isOpera)
  8543 // Removed due to bug: #1853816
  8207 				return true;
  8544 //			if (se.forced_root_block && isOpera)
       
  8545 //				return true;
  8208 
  8546 
  8209 			// Setup before range
  8547 			// Setup before range
  8210 			rb = d.createRange();
  8548 			rb = d.createRange();
  8211 
  8549 
  8212 			// If is before the first block element and in body, then move it into first block element
  8550 			// If is before the first block element and in body, then move it into first block element
  8345 			// Padd empty blocks
  8683 			// Padd empty blocks
  8346 			if (isEmpty(bef))
  8684 			if (isEmpty(bef))
  8347 				bef.innerHTML = '<br />';
  8685 				bef.innerHTML = '<br />';
  8348 
  8686 
  8349 			if (isEmpty(aft))
  8687 			if (isEmpty(aft))
  8350 				aft.innerHTML = isOpera ? ' <br />' : '<br />'; // Extra space for Opera
  8688 				aft.innerHTML = isOpera ? '&nbsp;' : '<br />'; // Extra space for Opera so that the caret can move there
  8351 
  8689 
  8352 			// Opera needs this one backwards
  8690 			// Opera needs this one backwards
  8353 			if (isOpera) {
  8691 			if (isOpera) {
  8354 				r.insertNode(bef);
  8692 				r.insertNode(bef);
  8355 				r.insertNode(aft);
  8693 				r.insertNode(aft);
  8366 			r = d.createRange();
  8704 			r = d.createRange();
  8367 			r.selectNodeContents(aft);
  8705 			r.selectNodeContents(aft);
  8368 			r.collapse(1);
  8706 			r.collapse(1);
  8369 			s.removeAllRanges();
  8707 			s.removeAllRanges();
  8370 			s.addRange(r);
  8708 			s.addRange(r);
  8371 			aft.scrollIntoView(0);
  8709 
       
  8710 			// Safari bug fix, http://bugs.webkit.org/show_bug.cgi?id=16117
       
  8711 			if (tinymce.isWebKit)
       
  8712 				ed.getWin().scrollTo(0, ed.dom.getPos(aft).y);
       
  8713 			else
       
  8714 				aft.scrollIntoView(0);
  8372 
  8715 
  8373 			return false;
  8716 			return false;
  8374 		},
  8717 		},
  8375 
  8718 
  8376 		backspaceDelete : function(e, bs) {
  8719 		backspaceDelete : function(e, bs) {
  8575 
  8918 
  8576 			return t.add(c);
  8919 			return t.add(c);
  8577 		},
  8920 		},
  8578 
  8921 
  8579 		createButton : function(id, s) {
  8922 		createButton : function(id, s) {
  8580 			var t = this, ed = t.editor, o;
  8923 			var t = this, ed = t.editor, o, c;
  8581 
  8924 
  8582 			if (t.get(id))
  8925 			if (t.get(id))
  8583 				return null;
  8926 				return null;
  8584 
  8927 
  8585 			s.title = ed.translate(s.title);
  8928 			s.title = ed.translate(s.title);
  8586 			s.scope = s.scope || ed;
  8929 			s.scope = s.scope || ed;
  8587 
  8930 
  8588 			if (!s.onclick) {
  8931 			if (!s.onclick && !s.menu_button) {
  8589 				s.onclick = function() {
  8932 				s.onclick = function() {
  8590 					ed.execCommand(s.cmd, s.ui || false, s.value);
  8933 					ed.execCommand(s.cmd, s.ui || false, s.value);
  8591 				};
  8934 				};
  8592 			}
  8935 			}
  8593 
  8936 
  8594 			s = extend({
  8937 			s = extend({
  8595 				title : s.title,
  8938 				title : s.title,
  8596 				'class' : id,
  8939 				'class' : id,
  8597 				unavailable_prefix : ed.getLang('unavailable', ''),
  8940 				unavailable_prefix : ed.getLang('unavailable', ''),
  8598 				scope : s.scope
  8941 				scope : s.scope,
       
  8942 				control_manager : t
  8599 			}, s);
  8943 			}, s);
  8600 
  8944 
  8601 			id = t.prefix + id;
  8945 			id = t.prefix + id;
  8602 
  8946 
  8603 			return t.add(new tinymce.ui.Button(id, s));
  8947 			if (s.menu_button) {
       
  8948 				c = new tinymce.ui.MenuButton(id, s);
       
  8949 				ed.onMouseDown.add(c.hideMenu, c);
       
  8950 			} else
       
  8951 				c = new tinymce.ui.Button(id, s);
       
  8952 
       
  8953 			return t.add(c);
       
  8954 		},
       
  8955 
       
  8956 		createMenuButton : function(id, s) {
       
  8957 			s = s || {};
       
  8958 			s.menu_button = 1;
       
  8959 
       
  8960 			return this.createButton(id, s);
  8604 		},
  8961 		},
  8605 
  8962 
  8606 		createSplitButton : function(id, s) {
  8963 		createSplitButton : function(id, s) {
  8607 			var t = this, ed = t.editor, cmd, c;
  8964 			var t = this, ed = t.editor, cmd, c;
  8608 
  8965 
  8673 
  9030 
  8674 			return t.add(c);
  9031 			return t.add(c);
  8675 		},
  9032 		},
  8676 
  9033 
  8677 		createToolbar : function(id, s) {
  9034 		createToolbar : function(id, s) {
  8678 			var c = new tinymce.ui.Toolbar(id, s);
  9035 			var c, t = this;
  8679 
  9036 
  8680 			if (this.get(id))
  9037 			id = t.prefix + id;
       
  9038 			c = new tinymce.ui.Toolbar(id, s);
       
  9039 
       
  9040 			if (t.get(id))
  8681 				return null;
  9041 				return null;
  8682 
  9042 
  8683 			return this.add(c);
  9043 			return t.add(c);
  8684 		},
  9044 		},
  8685 
  9045 
  8686 		createSeparator : function() {
  9046 		createSeparator : function() {
  8687 			return new tinymce.ui.Separator();
  9047 			return new tinymce.ui.Separator();
  8688 		}
  9048 		}