Vlad Kurkin (b_vladi) wrote in changelog,
Vlad Kurkin
b_vladi
changelog

[livejournal] r20361: LJSV-1832: RTE not saving edits

Committer: vkurkin
LJSV-1832: RTE not saving edits
LJSV-1828: Double-click to open context menu
LJSV-1862: Wizard in HTML-mode
LJSV-1860: RTE image wizard is not working for images
LJSV-1719: Users can type text in ljilike field in new RTE and lj-like block as result not showed in posted entry
LJSUP-9955: Incorrect working button "Link" in RTE
LJSUP-9949: Js error when click lj-cut in IE7 (with paragraph)
LJSUP-9919: Incorrect working lj-like wizard
LJSUP-9877: RTE - selected block
LJSUP-9802: Need disable auto formatting for RTE editor
U   trunk/htdocs/js/ck/config.js
U   trunk/htdocs/js/ck/contents.css
U   trunk/htdocs/js/ck/plugins/livejournal/plugin.js
U   trunk/htdocs/js/poll.js
Modified: trunk/htdocs/js/ck/config.js
===================================================================
--- trunk/htdocs/js/ck/config.js	2011-10-18 11:21:44 UTC (rev 20360)
+++ trunk/htdocs/js/ck/config.js	2011-10-18 11:34:13 UTC (rev 20361)
@@ -99,9 +99,9 @@
 		'NumberedList',
 		'BulletedList',
 		'-',
-		'JustifyLeft',
-		'JustifyCenter',
-		'JustifyRight',
+		'LJJustifyLeft',
+		'LJJustifyCenter',
+		'LJJustifyRight',
 		'-',
 		'Undo',
 		'Redo');

Modified: trunk/htdocs/js/ck/contents.css
===================================================================
--- trunk/htdocs/js/ck/contents.css	2011-10-18 11:21:44 UTC (rev 20360)
+++ trunk/htdocs/js/ck/contents.css	2011-10-18 11:34:13 UTC (rev 20361)
@@ -6,10 +6,10 @@
 
 BODY {
 	position: relative;
-	background: #FFF;
 	font: 12px/16px 'Arial', sans-serif;
 	color: #222;
 	}
+
 ol, ul, dl {
 /* IE7: reset rtl list margin. (#7334) */
 	*margin-right: 0px; /* preserved spaces for rtl list item bullets. (#6249)*/
@@ -96,18 +96,6 @@
 	height: 8px;
 }
 
-.ljembed {
-	background-color: #CCCCCC;
-	border: 1px solid #CCCCCC;
-}
-
-form.ljpoll {
-	display: block;
-	border: #000 1px dotted;
-	background-color: #d2d2d2;
-	font-style: italic;
-}
-
 /* Note popup */
 .note {
 	position: fixed;
@@ -125,60 +113,41 @@
 		}
 
 /* LJ Like buttons */
-.lj-like {
-	overflow: hidden;
-	padding: 13px 20px;
-	margin-top: 20px;
-	background: #D2D2D2;
-	border: 1px dotted #000;
+.lj-like-item {
+	display: inline-block;
+	margin-right: 15px;
+	background: url(/js/ck/images/lj-like-buttons.png) no-repeat;
+	vertical-align: middle;
+	font-size: 0;
+	cursor: pointer;
 	}
-	.lj-like .lj-like-item {
-		display: inline-block;
-		margin-right: 15px;
-		background: url(/js/ck/images/lj-like-buttons.png) no-repeat;
-		vertical-align: middle;
-		font-size: 0;
-		cursor: pointer;
-		}
-	.lj-like .fb {
-		width: 93px;
-		height: 20px;
-		background-position: 0 0;
-		}
-	.lj-like .tw {
-		width: 55px;
-		height: 20px;
-		background-position: 0 -46px;
-		}
-	.lj-like .go {
-		width: 32px;
-		height: 20px;
-		background-position: 0 -90px;
-		}
-	.lj-like .vk {
-		width: 40px;
-		height: 22px;
-		background-position: 0 -67px;
-		}
-	.lj-like .lj {
-		width: 67px;
-		height: 24px;
-		background-position: 0 -21px;
-		}
-.lj-like-selected {
-	background-color: #C4E0F7;
-	border: 1px solid #6EA9DF;
+.fb {
+	width: 93px;
+	height: 20px;
+	background-position: 0 0;
 	}
+.tw {
+	width: 55px;
+	height: 20px;
+	background-position: 0 -46px;
+	}
+.go {
+	width: 32px;
+	height: 20px;
+	background-position: 0 -90px;
+	}
+.vk {
+	width: 40px;
+	height: 22px;
+	background-position: 0 -67px;
+	}
+.lj {
+	width: 67px;
+	height: 24px;
+	background-position: 0 -21px;
+	}
 
 /* LJ map */
-.lj-map {
-	overflow: hidden;
-	min-height: 13px;
-	margin-top: 20px;
-	background: #D2D2D2;
-	border: 1px dotted #000;
-	text-align: center;
-	}
 	.lj-map P {
 		position: relative;
 		top: 45%;

Modified: trunk/htdocs/js/ck/plugins/livejournal/plugin.js
===================================================================
--- trunk/htdocs/js/ck/plugins/livejournal/plugin.js	2011-10-18 11:21:44 UTC (rev 20360)
+++ trunk/htdocs/js/ck/plugins/livejournal/plugin.js	2011-10-18 11:34:13 UTC (rev 20361)
@@ -1,7 +1,4 @@
 (function() {
-	// For IE 8-
-	document.namespaces && document.namespaces.add('lj', 'livejournal');
-
 	var dtd = CKEDITOR.dtd;
 
 	dtd.$block['lj:template'] = 1;
@@ -41,7 +38,7 @@
 			label: top.CKLang.LJLike_button_facebook,
 			id: 'facebook',
 			abbr: 'fb',
-			html: '<span class="lj-like-item lj-like-gag fb">' + top.CKLang.LJLike_button_facebook + '</span>',
+			html: '<span class="lj-like-item fb">' + top.CKLang.LJLike_button_facebook + '</span>',
 			htmlOpt: '<li class="like-fb"><input type="checkbox" id="like-fb" /><label for="like-fb">' + top.CKLang
 				.LJLike_button_facebook + '</label></li>'
 		},
@@ -49,7 +46,7 @@
 			label: top.CKLang.LJLike_button_twitter,
 			id: 'twitter',
 			abbr: 'tw',
-			html: '<span class="lj-like-item lj-like-gag tw">' + top.CKLang.LJLike_button_twitter + '</span>',
+			html: '<span class="lj-like-item tw">' + top.CKLang.LJLike_button_twitter + '</span>',
 			htmlOpt: '<li class="like-tw"><input type="checkbox" id="like-tw" /><label for="like-tw">' + top.CKLang
 				.LJLike_button_twitter + '</label></li>'
 		},
@@ -57,7 +54,7 @@
 			label: top.CKLang.LJLike_button_google,
 			id: 'google',
 			abbr: 'go',
-			html: '<span class="lj-like-item lj-like-gag go">' + top.CKLang.LJLike_button_google + '</span>',
+			html: '<span class="lj-like-item go">' + top.CKLang.LJLike_button_google + '</span>',
 			htmlOpt: '<li class="like-go"><input type="checkbox" id="like-go" /><label for="like-go">' + top.CKLang
 				.LJLike_button_google + '</label></li>'
 		},
@@ -65,7 +62,7 @@
 			label: top.CKLang.LJLike_button_vkontakte,
 			id: 'vkontakte',
 			abbr: 'vk',
-			html: '<span class="lj-like-item lj-like-gag vk">' + top.CKLang.LJLike_button_vkontakte + '</span>',
+			html: '<span class="lj-like-item vk">' + top.CKLang.LJLike_button_vkontakte + '</span>',
 			htmlOpt: window
 				.isSupUser ? '<li class="like-vk"><input type="checkbox" id="like-vk" /><label for="like-vk">' + top.CKLang
 				.LJLike_button_vkontakte + '</label></li>' : ''
@@ -74,7 +71,7 @@
 			label: top.CKLang.LJLike_button_give,
 			id: 'livejournal',
 			abbr: 'lj',
-			html: '<span class="lj-like-item lj-like-gag lj">' + top.CKLang.LJLike_button_give + '</span>',
+			html: '<span class="lj-like-item lj">' + top.CKLang.LJLike_button_give + '</span>',
 			htmlOpt: '<li class="like-lj"><input type="checkbox" id="like-lj" /><label for="like-lj">' + top.CKLang
 				.LJLike_button_give + '</label></li>'
 		}
@@ -100,17 +97,18 @@
 				.LJLink_WizardNoticeLink + '</a>')
 		},
 		image: {
-			html: encodeURIComponent(top.CKLang.LJImage_WizardNotice + '<br /><a href="#" lj-cmd="LJImage">' + top.CKLang
+			html: encodeURIComponent(top.CKLang.LJImage_WizardNotice + '<br /><a href="#" lj-cmd="image">' + top.CKLang
 				.LJImage_WizardNoticeLink + '</a>')
 		},
-		LJCut :{
+		LJCut: {
 			html: encodeURIComponent(top.CKLang.LJCut_WizardNotice + '<br /><a href="#" lj-cmd="LJCut">' + top.CKLang
 				.LJCut_WizardNoticeLink + '</a>')
 		}
 	};
 
 	var ljUsers = {};
-	var currentNoteNode;
+	var activeCmdName,
+		execFromEditor;
 
 	function createNote(editor) {
 		var timer,
@@ -177,7 +175,7 @@
 		noteNode.className = 'note-popup';
 
 		noteNode.onmouseout = function() {
-			if (!currentData.cmd) {
+			if (!currentData || !currentData.cmd) {
 				note.hide();
 			}
 		};
@@ -199,9 +197,10 @@
 		function callCmd() {
 			var cmd = this.getAttribute('lj-cmd');
 			if (currentData.hasOwnProperty(cmd)) {
-				currentNoteNode = ljTagsData[cmd].node = currentData[cmd].node;
+				ljTagsData[cmd].node = currentData[cmd].node;
 				var selection = new CKEDITOR.dom.selection(editor.document);
 				selection.selectElement(ljTagsData[cmd].node);
+				execFromEditor = true;
 				editor.execCommand(cmd);
 				note.hide(true);
 			}
@@ -209,6 +208,9 @@
 		}
 
 		function applyNote() {
+			if(!window.switchedRteOn){
+				return;
+			}
 			if (state) {
 				currentData = tempData;
 				tempData = null;
@@ -230,7 +232,7 @@
 					}
 				}
 			} else {
-				currentData = currentNoteNode = null;
+				currentData = null;
 			}
 
 			animate(state);
@@ -240,7 +242,7 @@
 
 		note = {
 			show: function(data, isNow) {
-				if (!isNow && data == tempData) {
+				if ((!isNow && data == tempData) || window.swi) {
 					return;
 				}
 
@@ -276,24 +278,68 @@
 
 	CKEDITOR.plugins.add('livejournal', {
 		init: function(editor) {
+			editor.addCss('.lj_selected {' +
+				'background-color: #C4E0F7 !important;' +
+				'border: 1px solid #6EA9DF !important;' +
+			'}');
 
+			function onClickFrame(evt) {
+				if (this.$ != editor.document.$) {
+					var frame = this.frameElement;
+					var cmdName = frame.getAttribute('lj-cmd');
+					if(cmdName){
+						editor.getCommand(cmdName).setState(CKEDITOR.TRISTATE_ON);
+					}
+					evt.editor = editor;
+					new CKEDITOR.dom.selection(editor.document).selectElement(frame);
+					frame.addClass('lj_selected');
+				}
+				evt.data.getKey() == 1 && evt.data.preventDefault();
+			}
+
+			function onPressFrame(evt) {
+				if(evt.data.getKey() == 46){
+					this.frameElement.remove();
+				}
+			}
+
 			function findLJTags(evt) {
 				var noteData,
-					isSelection = evt.name == 'selectionChange',
-					node = isSelection ? evt.data.element : evt.data.getTarget();
+					isSelection = evt.name == 'selectionChange' || evt.name == 'click',
+					target = evt.data.element || evt.data.getTarget();
 
-				if (node.type != 1) {
-					node = node.getParent();
+				if (evt.name == 'click' && (evt.data.getKey() == 1 || evt.data.$.button == 0)) {
+					evt.data.preventDefault();
 				}
 
+				if (target.type != 1) {
+					target = target.getParent();
+				}
+
+				var node = target,
+					command;
+
+				if(isSelection){
+					var frames = editor.document.getElementsByTag('iframe');
+					for(var i = 0, l = frames.count(); i < l; i++){
+						var item = frames.getItem(i);
+						if(item.$ !== target.$){
+							item.removeClass('lj_selected');
+						}
+					}
+					if(CKEDITOR.env.ie && node.is('iframe')){
+						node.addClass('lj_selected');
+					}
+				}
 				while (node) {
 					var attr = node.getAttribute('lj-cmd');
 
 					if (!attr && node.type == 1) {
-						if (node.is('img') && node.getParent().getParent() && node.getParent().getParent().getAttribute('contentEditable') != 'false') {
+						if (node.is('img') && node.getParent().getParent() && !node.getParent().getParent()
+							.hasAttribute('lj:user')) {
 							attr = 'image';
 							node.setAttribute('lj-cmd', attr);
-						} else if (node.is('a') && node.getParent().getAttribute('contentEditable') != 'false') {
+						} else if (node.is('a') && !node.getParent().hasAttribute('lj:user')) {
 							attr = 'LJLink';
 							node.setAttribute('lj-cmd', attr);
 						}
@@ -303,6 +349,7 @@
 						if (isSelection) {
 							ljTagsData[attr].node = node;
 							editor.getCommand(attr).setState(CKEDITOR.TRISTATE_ON);
+							activeCmdName = attr;
 						}
 						(noteData || (noteData = {}))[attr] = {
 							content: ljTagsData[attr].html,
@@ -315,34 +362,40 @@
 
 				noteData ? note.show(noteData) : note.hide();
 
-				for (var command in ljTagsData) {
+				for (command in ljTagsData) {
 					if (ljTagsData.hasOwnProperty(command) && isSelection && (!noteData || !noteData.hasOwnProperty(command))) {
-						delete ljTagsData[command].node;
+						if (ljTagsData[command].node) {
+							delete ljTagsData[command].node;
+						}
 						editor.getCommand(command).setState(CKEDITOR.TRISTATE_OFF);
 					}
 				}
 			}
 
 			editor.dataProcessor.toHtml = function(html, fixForBody) {
-				html = html
-					.replace(/(<lj [^>]+)(?!\/)>/gi, '$1 />')
-					.replace(/(<lj-map[^>]+)(?!\/)>/gi, '$1 />')
-					.replace(/(<lj-template[^>]*)(?!\/)>/gi, '$1 />')
-					.replace(/<((?!br)[^\s>]+)([^>]*?)\/>/gi, '<$1$2></$1>')
+				html = html.replace(/(<lj [^>]+)(?!\/)>/gi, '$1 />').replace(/(<lj-map[^>]+)(?!\/)>/gi, '$1 />')
+					.replace(/(<lj-template[^>]*)(?!\/)>/gi, '$1 />').replace(/<((?!br)[^\s>]+)([^>]*?)\/>/gi, '<$1$2></$1>')
 					.replace(/<lj-poll .*?>[\s\S]*?<\/lj-poll>/gi, function(ljtags) {
-						return new Poll(ljtags).outputHTML();
-					});
+					var poll = new Poll(ljtags);
+					return '<iframe class="lj-poll" frameborder="0" allowTransparency="true" lj-cmd="LJPollLink" lj-data="' + poll
+						.outputLJtags() + '" lj-content="' + poll.outputHTML() + '"></iframe>';
+				});
 
+				html = html.replace(/<lj-embed(.*?)>([\s\S]*?)<\/lj-embed>/gi, function(result, attrs, data) {
+					return '<iframe' + attrs + ' class="lj-embed" lj-data="' + encodeURIComponent(data) + '" frameborder="0" allowTransparency="true"></iframe>';
+				});
+
 				if (!$('event_format').checked) {
-					html = html
-						.replace(/(<lj-raw.*?>)([\s\S]*?)(<\/lj-raw>)/gi, function(result, open, content, close) {
+					html = html.replace(/(<lj-raw.*?>)([\s\S]*?)(<\/lj-raw>)/gi,
+						function(result, open, content, close) {
 							return open + content.replace(/\n/g, '') + close;
-						})
-						.replace(/\n/g, '<br />');
+						}).replace(/\n/g, '<br />');
 				}
 
 				html = CKEDITOR.htmlDataProcessor.prototype.toHtml.call(this, html, fixForBody);
-
+				if(CKEDITOR.env.ie){
+					html = '<xml:namespace ns="livejournal" prefix="lj" />' + html;
+				}
 				return html;
 			};
 
@@ -361,28 +414,9 @@
 			editor.dataProcessor.writer.indentationChars = '';
 			editor.dataProcessor.writer.lineBreakChars = '';
 
-			function checkLastLine(evt) {
-				if(evt && evt.name == 'click'){
-					evt.data.preventDefault();
-					evt.data.stopPropagation();
-				}
-				var body = editor.document.getBody();
-				var last = body.$.lastChild;
-				if (!last || last.nodeType != 1 || last.nodeName.toLowerCase() != 'br') {
-					// IE fix: LJSUP-9871;
-					var selection = editor.document.getSelection();
-					var bookmark = selection && selection.createBookmarks();
-					body.appendHtml('<br />');
-					selection && selection.selectBookmarks(bookmark);
-				}
+			function onDoubleClick(evt) {
+				var node = evt.data.element || evt.data.getTarget();
 
-				currentNoteNode = null;
-			}
-
-			editor.on('selectionChange', findLJTags);
-			editor.on('doubleclick', function(evt) {
-				var node = evt.data.element;
-
 				if (node.type != 1) {
 					node = node.getParent();
 				}
@@ -393,29 +427,78 @@
 						var cmd = editor.getCommand(cmdName);
 						if (cmd.state == CKEDITOR.TRISTATE_ON) {
 							var selection = new CKEDITOR.dom.selection(editor.document);
-							selection.selectElement(node);
-							currentNoteNode = node;
+							ljTagsData[cmdName].node = node.is('body') ? new CKEDITOR.dom.element.get(node.getWindow().$
+								.frameElement) : node;
+							selection.selectElement(ljTagsData[cmdName].node);
 							evt.data.dialog = '';
+							execFromEditor = true;
 							cmd.exec();
-							return;
+							break;
 						}
 					}
 					node = node.getParent();
 				}
+			}
 
-				currentNoteNode = null;
+			var styleSheet = '';
+
+			CKEDITOR.ajax.load(editor.config.contentsCss, function(data){
+				styleSheet = data;
 			});
 
+			function onLoadFrame() {
+				var win = this.$.contentWindow;
+				var doc = win.document;
+				if(win.frameElement.getAttribute('lj-cmd') && doc.body.scrollHeight){
+					this.setStyle('height', doc.body.scrollHeight + 'px');
+				}
+
+				var body = new CKEDITOR.dom.element.get(doc.body);
+				body.on('dblclick', onDoubleClick);
+				body.on('click', onClickFrame);
+
+				doc = new CKEDITOR.dom.element.get(doc);
+				doc.on('keyup', onPressFrame);
+
+				doc.frameElement = body.frameElement = this;
+			}
+
+			function updateFrames() {
+				execFromEditor = false;
+				var frames = editor.document.getElementsByTag('iframe');
+				var length = frames.count();
+
+				while (length--) {
+					var iFrameCss = 'widht: 100%; margin: 0; padding 0; overflow-y: hidden;',
+						frame = frames.getItem(length),
+						cmd = frame.getAttribute('lj-cmd'),
+						frameWin = frame.$.contentWindow,
+						doc = frameWin.document,
+						ljStyle = frame.getAttribute('lj-style');
+
+					if (ljStyle) {
+						iFrameCss += ljStyle;
+					}
+
+					frame.removeListener('load', onLoadFrame);
+					frame.on('load', onLoadFrame);
+					doc.open();
+					doc.write('<!DOCTYPE html><html style="' + iFrameCss + '"><head><style type="text/css">' + styleSheet + '</style></head><body style="' + iFrameCss + '" ' + (cmd ? ('lj-cmd="' + cmd + '"') : '') + '>' + decodeURIComponent(frame.getAttribute('lj-content') || '&nbsp;' ) + '</body></html>');
+					doc.close();
+				}
+			}
+
+			editor.on('selectionChange', findLJTags);
+			editor.on('doubleclick', onDoubleClick);
+			editor.on('afterCommandExec', updateFrames);
+			editor.on('dialogHide', updateFrames);
 			editor.on('dataReady', function() {
 				note = note || createNote(editor);
-
-				checkLastLine();
+				editor.document.on('click', findLJTags);
 				editor.document.on('mouseout', note.hide);
 				editor.document.on('mouseover', findLJTags);
-				editor.document.on('keydown', checkLastLine);
-				editor.document.on('click', checkLastLine);
-				editor.document.on('selectionChange', checkLastLine);
-				editor.document.on('afterCommandExec', checkLastLine);
+
+				updateFrames();
 			});
 
 			//////////  LJ User Button //////////////
@@ -425,12 +508,13 @@
 				exec: function(editor) {
 					var userName = '',
 						selection = new CKEDITOR.dom.selection(editor.document),
-						LJUser = ljTagsData.LJUserLink.node;
+						LJUser = ljTagsData.LJUserLink.node,
+						currentUserName;
 
 					if (LJUser) {
 						note.hide(true);
-						userName = prompt(top.CKLang.UserPrompt, ljTagsData.LJUserLink.node.getElementsByTag('b').getItem(0)
-							.getText());
+						currentUserName = ljTagsData.LJUserLink.node.getElementsByTag('b').getItem(0).getText();
+						userName = prompt(top.CKLang.UserPrompt, currentUserName);
 					} else if (selection.getType() == 2) {
 						userName = selection.getSelectedText();
 					}
@@ -439,7 +523,7 @@
 						userName = prompt(top.CKLang.UserPrompt, userName);
 					}
 
-					if (!userName) {
+					if (!userName || currentUserName == userName) {
 						return;
 					}
 
@@ -462,11 +546,10 @@
 							ljUsers[userName] = data.ljuser;
 
 							var tmpNode = new CKEDITOR.dom.element.createFromHtml(data.ljuser);
-							tmpNode.setAttribute('contentEditable', 'false');
 							tmpNode.setAttribute('lj-cmd', 'LJUserLink');
 
 							if (LJUser) {
-								LJUser.$.parentNode.replaceChild(tmpNode, LJUser.$);
+								LJUser.$.parentNode.replaceChild(tmpNode.$, LJUser.$);
 							} else {
 								editor.insertElement(tmpNode);
 							}
@@ -481,28 +564,29 @@
 			});
 
 			//////////  LJ Image Button //////////////
+
 			editor.ui.addButton('image', {
-				label: top.CKLang.LJImage_title,
+				label: editor.lang.common.imageButton,
 				command: 'image'
 			});
 
-			if (window.ljphotoEnabled) {
+			if(window.ljphotoEnabled){
 				editor.addCommand('LJImage_beta', {
 					exec: function(editor) {
-						jQuery('#updateForm').photouploader({
-							type: 'upload'
-						}).photouploader('show').bind('htmlready', function (event) {
-							var html = event.htmlStrings;
-							for (var i = 0, l = html.length; i < l; i++) {
-								editor.insertElement(new CKEDITOR.dom.element.createFromHtml(html[i], editor.document));
-							}
-						});
+							jQuery('#updateForm').photouploader({
+								type: 'upload'
+							}).photouploader('show').bind('htmlready', function (event) {
+								var html = event.htmlStrings;
+								for (var i = 0, l = html.length; i < l; i++) {
+									editor.insertElement(new CKEDITOR.dom.element.createFromHtml(html[i], editor.document));
+								}
+							});
 					},
 					editorFocus: false
 				});
 
 				editor.ui.addButton('LJImage_beta', {
-					label: top.CKLang.LJImage_beta_title,
+					label: editor.lang.common.imageButton,
 					command: 'LJImage_beta'
 				});
 			}
@@ -510,17 +594,9 @@
 			//////////  LJ Link Button //////////////
 			editor.addCommand('LJLink', {
 				exec: function(editor) {
-					var state = editor.getCommand('LJLink').state;
-
-					if (currentNoteNode && ljTagsData.LJLink.node) {
-						editor.openDialog('link');
-					} else if (state === CKEDITOR.TRISTATE_OFF) {
-						editor.openDialog('link');
-					} else if (state === CKEDITOR.TRISTATE_ON) {
-						editor.execCommand('unlink')
-					}
+					!execFromEditor && this.state == CKEDITOR.TRISTATE_ON ? editor.execCommand('unlink') : editor
+						.openDialog('link');
 					note.hide(true);
-
 				},
 				editorFocus: false
 			});
@@ -530,24 +606,96 @@
 				command: 'LJLink'
 			});
 
-			//////////  LJ Justify //////////////
-			(function() {
-				function getState(editor, path) {
-					var firstBlock = path.block || path.blockLimit;
+			//////////  LJ Embed Media Button //////////////
+			editor.addCommand('LJEmbedLink', {
+				exec: function() {
+					top.LJ_IPPU.textPrompt(top.CKLang.LJEmbedPromptTitle, top.CKLang.LJEmbedPrompt, doEmbed, {
+						width: '350px'
+					});
+				}
+			});
 
-					if (!firstBlock || firstBlock.getName() == 'body') {
-						return CKEDITOR.TRISTATE_OFF;
+			editor.ui.addButton('LJEmbedLink', {
+				label: top.CKLang.LJEmbed,
+				command: 'LJEmbedLink'
+			});
+
+			editor.addCss('.lj-embed {' + 'background: #CCCCCC url(' + CKEDITOR.getUrl(this
+				.path + 'images/placeholder_flash.png') + ') no-repeat center center;' + 'border: 1px dotted #000000;' + 'height: 80px;' + 'width: 100%;' + '}');
+
+			function doEmbed(content) {
+				if (content && content.length) {
+					if (window.switchedRteOn) {
+						var iframe = new CKEDITOR.dom.element('iframe', editor.document);
+						iframe.setAttribute('lj-data', encodeURIComponent(content));
+						iframe.setAttribute('class', 'lj-embed');
+						iframe.setAttribute('frameBorder', 0);
+						iframe.setAttribute('allowTransparency', 'true');
+						editor.insertElement(iframe);
+						updateFrames();
 					}
-
-					return ( getAlignment(firstBlock, editor.config.useComputedState) == this.value ) ? CKEDITOR
-						.TRISTATE_ON : CKEDITOR.TRISTATE_OFF;
 				}
+			}
 
+			//////////  LJ Cut Button //////////////
+			editor.addCommand('LJCut', {
+				exec: function() {
+					var text;
+					if (ljTagsData.LJCut.node) {
+						text = prompt(top.CKLang.CutPrompt, ljTagsData.LJCut.node.getAttribute('text') || top.CKLang.ReadMore);
+						if (text) {
+							if (text == top.CKLang.ReadMore) {
+								ljTagsData.LJCut.node.removeAttribute('text');
+							} else {
+								ljTagsData.LJCut.node.setAttribute('text', text);
+							}
+						}
+					} else {
+						text = prompt(top.CKLang.CutPrompt, top.CKLang.ReadMore);
+						if (text) {
+							var selection = new CKEDITOR.dom.selection(editor.document);
+
+							ljTagsData.LJCut.node = new CKEDITOR.dom.element.get(editor.document.$.createElement('lj:cut'));
+							ljTagsData.LJCut.node.setAttribute('lj-cmd', 'LJCut');
+							if (text != top.CKLang.ReadMore) {
+								ljTagsData.LJCut.node.setAttribute('text', text);
+							}
+
+							var ranges = selection.getRanges();
+							var fragment = editor.document.$.createDocumentFragment();
+							selection.lock();
+							for (var i = 0, l = ranges.length; i < l; i++) {
+								var range = ranges[i];
+								var content = range.extractContents();
+								fragment.appendChild(content.$);
+							}
+							editor.insertElement(ljTagsData.LJCut.node);
+							ljTagsData.LJCut.node.$.appendChild(fragment);
+							selection.unlock();
+							selection.selectElement(ljTagsData.LJCut.node);
+						}
+						note.hide(true);
+					}
+				},
+				editorFocus: false
+			});
+
+			editor.ui.addButton('LJCut', {
+				label: top.CKLang.LJCut,
+				command: 'LJCut'
+			});
+
+			//////////  LJ Justify //////////////
+			(function() {
 				function getAlignment(element, useComputedState) {
 					useComputedState = useComputedState === undefined || useComputedState;
 
-					var align;
-					if (useComputedState) {
+					var align,
+						LJLike = ljTagsData.LJLike.node;
+					if (LJLike) {
+						var attr = element.getAttribute('lj-style');
+						align = attr ? attr.replace(/text-align:\s*(left|right|center)/i, '$1') : 'left';
+					} else if (useComputedState) {
 						align = element.getComputedStyle('text-align');
 					} else {
 						while (!element.hasAttribute || !( element.hasAttribute('align') || element.getStyle('text-align') )) {
@@ -572,12 +720,21 @@
 						return;
 					}
 
-					var command = evt.editor.getCommand(this.name);
-					command.state = getState.call(this, evt.editor, evt.data.path);
+					var command = evt.editor.getCommand(this.name),
+						element = evt.data.element,
+						cmd = element.hasAttribute('lj-cmd') && element.getAttribute('lj-cmd');
+					if(cmd == 'LJLike'){
+						command.state = (getAlignment(element, editor.config.useComputedState) == this.value) ? CKEDITOR.TRISTATE_ON : CKEDITOR.TRISTATE_OFF;
+					} else if(!element || element.getName() == 'body' || element.getName() == 'iframe'){
+						command.state = CKEDITOR.TRISTATE_OFF;
+					} else {
+						command.state = getAlignment(element, editor.config.useComputedState) == this.value ? CKEDITOR.TRISTATE_ON : CKEDITOR.TRISTATE_OFF;
+					}
+
 					command.fire('state');
 				}
 
-				function JustifyCommand(editor, name, value) {
+				function justifyCommand(editor, name, value) {
 					this.name = name;
 					this.value = value;
 
@@ -646,171 +803,108 @@
 					}
 				}
 
-				JustifyCommand.prototype = {
+				justifyCommand.prototype = {
 					exec : function(editor) {
-						var LJNode = ljTagsData.LJLike.node || ljTagsData.LJUserLink.node;
-						var selection = new CKEDITOR.dom.selection(editor.document);
-						if (LJNode) {
-							LJNode.removeAttribute('contenteditable');
-							selection.selectElement(LJNode);
-						}
+						var selection = editor.getSelection(),
+							enterMode = editor.config.enterMode;
 
-						var enterMode = editor.config.enterMode;
-
 						if (!selection) {
 							return;
 						}
 
-						var bookmarks = selection.createBookmarks(),
-							ranges = selection.getRanges(true);
+						var bookmarks = selection.createBookmarks();
 
-						var cssClassName = this.cssClassName,
-							iterator,
-							block;
+						if (ljTagsData.LJLike.node) {
+							ljTagsData.LJLike.node.setAttribute('lj-style', 'text-align: ' + this.value);
+						} else {
+							var ranges = selection.getRanges(true);
 
-						var useComputedState = editor.config.useComputedState;
-						useComputedState = useComputedState === undefined || useComputedState;
+							var cssClassName = this.cssClassName,
+								iterator,
+								block;
 
-						for (var i = ranges.length - 1; i >= 0; i--) {
-							iterator = ranges[ i ].createIterator();
-							iterator.enlargeBr = enterMode != CKEDITOR.ENTER_BR;
+							var useComputedState = editor.config.useComputedState;
+							useComputedState = useComputedState === undefined || useComputedState;
 
-							while (( block = iterator.getNextParagraph(enterMode == CKEDITOR.ENTER_P ? 'p' : 'div') )) {
-								block.removeAttribute('align');
-								block.removeStyle('text-align');
+							for (var i = ranges.length - 1; i >= 0; i--) {
+								var range = ranges[i];
+								var encloseNode = range.getEnclosedNode();
+								if(encloseNode && encloseNode.is('iframe')){
+									return;
+								}
 
-								// Remove any of the alignment classes from the className.
-								var className = cssClassName && ( block.$.className = CKEDITOR.tools.ltrim(block.$.className
-									.replace(this.cssClassRegex, '')) );
+								iterator = range.createIterator();
+								iterator.enlargeBr = enterMode != CKEDITOR.ENTER_BR;
+								while (( block = iterator.getNextParagraph(enterMode == CKEDITOR.ENTER_P ? 'p' : 'div') )) {
+									block.removeAttribute('align');
+									block.removeStyle('text-align');
 
-								var apply = ( this.state == CKEDITOR
-									.TRISTATE_OFF ) && ( !useComputedState || ( getAlignment(block, true) != this.value ) );
+									// Remove any of the alignment classes from the className.
+									var className = cssClassName && ( block.$.className = CKEDITOR.tools.ltrim(block.$.className
+										.replace(this.cssClassRegex, '')) );
 
-								if (cssClassName) {
-									// Append the desired class name.
-									if (apply) {
-										block.addClass(cssClassName);
-									} else if (!className) {
-										block.removeAttribute('class');
+									var apply = ( this.state == CKEDITOR
+										.TRISTATE_OFF ) && ( !useComputedState || ( getAlignment(block, true) != this.value ) );
+
+									if (cssClassName) {
+										// Append the desired class name.
+										if (apply) {
+											block.addClass(cssClassName);
+										} else if (!className) {
+											block.removeAttribute('class');
+										}
+									} else if (apply) {
+										block.setStyle('text-align', this.value);
 									}
-								} else if (apply) {
-									block.setStyle('text-align', this.value);
 								}
+
 							}
-
 						}
 
 						editor.focus();
 						editor.forceNextSelectionCheck();
 						selection.selectBookmarks(bookmarks);
-
-						if (LJNode) {
-							LJNode.setAttribute('contenteditable', 'false');
-						}
 					}
 				};
 
-				var left = new JustifyCommand(editor, 'justifyleft', 'left'),
-					center = new JustifyCommand(editor, 'justifycenter', 'center'),
-					right = new JustifyCommand(editor, 'justifyright', 'right');
+				var left = new justifyCommand(editor, 'LJJustifyLeft', 'left'),
+					center = new justifyCommand(editor, 'LJJustifyCenter', 'center'),
+					right = new justifyCommand(editor, 'LJJustifyRight', 'right');
 
-				editor.addCommand('justifyleft', left);
-				editor.addCommand('justifycenter', center);
-				editor.addCommand('justifyright', right);
+				editor.addCommand('LJJustifyLeft', left);
+				editor.addCommand('LJJustifyCenter', center);
+				editor.addCommand('LJJustifyRight', right);
 
-				editor.ui.addButton('JustifyLeft', {
+				editor.ui.addButton('LJJustifyLeft', {
 					label : editor.lang.justify.left,
-					command : 'justifyleft'
+					command : 'LJJustifyLeft'
 				});
-				editor.ui.addButton('JustifyCenter', {
+				editor.ui.addButton('LJJustifyCenter', {
 					label : editor.lang.justify.center,
-					command : 'justifycenter'
+					command : 'LJJustifyCenter'
 				});
-				editor.ui.addButton('JustifyRight', {
+				editor.ui.addButton('LJJustifyRight', {
 					label : editor.lang.justify.right,
-					command : 'justifyright'
+					command : 'LJJustifyRight'
 				});
 
 				editor.on('selectionChange', CKEDITOR.tools.bind(onSelectionChange, left));
 				editor.on('selectionChange', CKEDITOR.tools.bind(onSelectionChange, right));
 				editor.on('selectionChange', CKEDITOR.tools.bind(onSelectionChange, center));
 				editor.on('dirChanged', onDirChanged);
-
 			})();
 
-			//////////  LJ Embed Media Button //////////////
-			editor.addCommand('LJEmbedLink', {
-				exec: function() {
-					top.LJ_IPPU.textPrompt(top.CKLang.LJEmbedPromptTitle, top.CKLang.LJEmbedPrompt, doEmbed, {
-						width: '350px'
-					});
-				}
-			});
-
-			editor.ui.addButton('LJEmbedLink', {
-				label: top.CKLang.LJEmbed,
-				command: 'LJEmbedLink'
-			});
-
-			editor.addCss('.lj-embed {' + 'background: #CCCCCC url(' + CKEDITOR.getUrl(this
-				.path + 'images/placeholder_flash.png') + ') no-repeat center center;' + 'border: 1px dotted #000000;' + 'height: 80px;' + 'width: 100%;' + '}');
-
-			function doEmbed(content) {
-				if (content && content.length) {
-					if (window.switchedRteOn) {
-						editor.insertElement(new CKEDITOR.dom.element.createFromHtml('<div class="lj-embed" contentEditable="false">' + content + '</div><br/>', editor.document));
-					}
-				}
-			}
-
-			//////////  LJ Cut Button //////////////
-			editor.addCommand('LJCut', {
-				exec: function() {
-					var text;
-					if (ljTagsData.LJCut.node) {
-						text = prompt(top.CKLang.CutPrompt, ljTagsData.LJCut.node.getAttribute('text') || top.CKLang.ReadMore);
-						if (text) {
-							if (text == top.CKLang.ReadMore) {
-								ljTagsData.LJCut.node.removeAttribute('text');
-							} else {
-								ljTagsData.LJCut.node.setAttribute('text', text);
-							}
-						}
-					} else {
-						text = prompt(top.CKLang.CutPrompt, top.CKLang.ReadMore);
-						if (text) {
-							var selection = new CKEDITOR.dom.selection(editor.document);
-
-							ljTagsData.LJCut.node = new CKEDITOR.dom.element.get(document.createElement('lj:cut'));
-							ljTagsData.LJCut.node.setAttribute('lj-cmd', 'LJCut');
-							if (text != top.CKLang.ReadMore) {
-								ljTagsData.LJCut.node.setAttribute('text', text);
-							}
-
-							var ranges = selection.getRanges();
-							selection.lock();
-							for (var i = 0, l = ranges.length; i < l; i++) {
-								var range = ranges[i];
-								range.cloneContents().appendTo(ljTagsData.LJCut.node);
-							}
-							selection.unlock();
-							editor.insertElement(ljTagsData.LJCut.node);
-							selection.selectElement(ljTagsData.LJCut.node);
-						}
-						note.hide(true);
-					}
-				}
-			});
-
-			editor.ui.addButton('LJCut', {
-				label: top.CKLang.LJCut,
-				command: 'LJCut'
-			});
-
 			//////////  LJ Poll Button //////////////
 			if (top.canmakepoll) {
 				var currentPoll;
 
+				editor.addCss('.lj-poll {' +
+					'width:100%;' +
+					'border: #000 1px dotted;' +
+					'background-color: #d2d2d2;' +
+					'font-style: italic;' +
+					'}');
+
 				CKEDITOR.dialog.add('LJPollDialog', function() {
 					var isAllFrameLoad = 0, okButtonNode, questionsWindow, setupWindow;
 
@@ -820,12 +914,13 @@
 						}
 						if (isAllFrameLoad && okButtonNode) {
 							currentPoll = new Poll(ljTagsData.LJPollLink.node && decodeURIComponent(ljTagsData.LJPollLink.node
-								.getAttribute('data')), questionsWindow.document, setupWindow.document, questionsWindow.Questions);
+								.getAttribute('lj-data')), questionsWindow.document, setupWindow.document, questionsWindow.Questions);
 
 							questionsWindow.ready(currentPoll);
 							setupWindow.ready(currentPoll);
 
 							okButtonNode.style.display = 'block';
+							note.hide(true);
 						} else {
 							isAllFrameLoad++;
 						}
@@ -837,19 +932,27 @@
 						label: editor.lang.common.ok,
 						onClick: function(evt) {
 							evt.data.dialog.hide();
-							var pollSource = new Poll(currentPoll, questionsWindow.document, setupWindow.document, questionsWindow
-								.Questions).outputHTML();
+							var poll = new Poll(currentPoll, questionsWindow.document, setupWindow.document, questionsWindow
+								.Questions);
+							var pollSource = poll.outputHTML();
+							var pollLJTags = poll.outputLJtags();
 
 							if (pollSource.length > 0) {
 								if (ljTagsData.LJPollLink.node) {
-									var node = editor.document.createElement('div');
-									node.$.innerHTML = pollSource;
-									ljTagsData.LJPollLink.node.insertBeforeMe(node);
-									ljTagsData.LJPollLink.node.remove();
+									ljTagsData.LJPollLink.node.setAttribute('lj-content', pollSource);
+									ljTagsData.LJPollLink.node.setAttribute('lj-data', pollLJTags);
 								} else {
-									editor.insertElement(new CKEDITOR.dom.element.createFromHtml(pollSource, editor.document));
+									var node = new CKEDITOR.dom.element('iframe', editor.document);
+									node.setAttribute('lj-content', pollSource);
+									node.setAttribute('lj-cmd', 'LJPollLink');
+									node.setAttribute('lj-data', pollLJTags);
+									node.setAttribute('class', 'lj-poll');
+									node.setAttribute('frameBorder', 0);
+									node.setAttribute('allowTransparency', 'true');
+									editor.insertElement(node);
 								}
 								ljTagsData.LJPollLink.node = null;
+								updateFrames();
 							}
 						}
 					}), CKEDITOR.dialog.cancelButton];
@@ -862,7 +965,6 @@
 						height: 270,
 						resizable: false,
 						onShow: function() {
-							note.hide(true);
 							if (isAllFrameLoad) {
 								currentPoll = new Poll(ljTagsData.LJPollLink.node && unescape(ljTagsData.LJPollLink.node
 									.getAttribute('data')), questionsWindow.document, setupWindow.document, questionsWindow.Questions);
@@ -942,6 +1044,17 @@
 			var dialogContent = '<div class="cke-dialog-likes"><ul class="cke-dialog-likes-list">';
 			likeButtons.defaultButtons = [];
 
+			editor
+				.addCss('.lj-like {' +
+					'overflow: hidden;' +
+					'padding: 0;' +
+					'margin: 0;' +
+					'background: #D2D2D2;' +
+					'border: 1px dotted #000;' +
+					'width: 100%;' +
+					'height: 24px;' +
+				'}');
+
 			for (var i = 0; i < buttonsLength; i++) {
 				var button = likeButtons[i];
 				likeButtons[button.id] = likeButtons[button.abbr] = button;
@@ -990,11 +1103,16 @@
 						if (attr.length) {
 							if (likeNode) {
 								ljTagsData.LJLike.node.setAttribute('buttons', attr.join(','));
-								ljTagsData.LJLike.node.setHtml(likeHtml);
+								ljTagsData.LJLike.node.setAttribute('lj-content', encodeURIComponent(likeHtml));
 							} else {
-								editor.insertElement(new CKEDITOR.dom.element
-									.createFromHtml('<div contentEditable="false" class="lj-like" lj-cmd="LJLike" buttons="' + attr
-									.join(',') + '">' + likeHtml + '</div><br/>', editor.document));
+								likeNode = new CKEDITOR.dom.element('iframe', editor.document);
+								likeNode.setAttribute('class', 'lj-like');
+								likeNode.setAttribute('buttons', attr.join(','));
+								likeNode.setAttribute('lj-content', encodeURIComponent(likeHtml));
+								likeNode.setAttribute('lj-cmd', 'LJLike');
+								likeNode.setAttribute('frameBorder', 0);
+								likeNode.setAttribute('allowTransparency', 'true');
+								editor.insertElement(likeNode);
 							}
 						} else if (likeNode) {
 							ljTagsData.LJLike.node.remove();
@@ -1066,31 +1184,35 @@
 				label: top.CKLang.LJLike_name,
 				command: 'LJLike'
 			});
+
+			//////////  LJ Map Button //////////////
+			editor
+				.addCss('.lj-map {' +
+					'overflow: hidden;' +
+					'min-height: 13px;' +
+					'margin-top: 20px;' +
+					'background: #D2D2D2;' +
+					'border: 1px dotted #000;' +
+					'text-align: center;' +
+				'}');
 		},
 		afterInit: function(editor) {
 			var dataProcessor = editor.dataProcessor;
 
 			dataProcessor.dataFilter.addRules({
 				elements: {
-					'lj-embed': function(element) {
-						var fakeElement = new CKEDITOR.htmlParser.element('div');
-						fakeElement.attributes.contentEditable = 'false';
-						fakeElement.attributes['class'] = 'lj-embed';
-						fakeElement.attributes.embedid = element.attributes.id;
-						if (element.attributes.hasOwnProperty('source_user')) {
-							fakeElement.attributes.source_user = element.attributes.source_user;
-						}
-						fakeElement.children = element.children;
-
-						return fakeElement;
-					},
 					'lj-like': function(element) {
 						var attr = [];
 
-						var fakeElement = new CKEDITOR.htmlParser.element('div');
-						fakeElement.attributes.contentEditable = 'false';
+						var fakeElement = new CKEDITOR.htmlParser.element('iframe');
 						fakeElement.attributes['class'] = 'lj-like';
+						if (element.attributes.hasOwnProperty('style')) {
+							fakeElement.attributes['lj-style'] = element.attributes.style;
+						}
 						fakeElement.attributes['lj-cmd'] = 'LJLike';
+						fakeElement.attributes['lj-content'] = '';
+						fakeElement.attributes['frameBorder'] = 0;
+						fakeElement.attributes['allowTransparency'] = 'true';
 
 						var currentButtons = element.attributes.buttons && element.attributes.buttons.split(',') || likeButtons
 							.defaultButtons;
@@ -1100,90 +1222,108 @@
 							var buttonName = currentButtons[i].replace(/^\s*([a-z]{2,})\s*$/i, '$1');
 							var button = likeButtons[buttonName];
 							if (button) {
-								var buttonNode = new CKEDITOR.htmlParser.fragment.fromHtml(button.html).children[0];
-								fakeElement.add(buttonNode);
+								fakeElement.attributes['lj-content'] += encodeURIComponent(button.html);
 								attr.push(buttonName);
 							}
 						}
 
 						fakeElement.attributes.buttons = attr.join(',');
-						fakeElement.attributes.style = element.attributes.style;
 						return fakeElement;
 					},
-					'lj': function(element) {
-						var ljUserName = element.attributes.user;
-						if (!ljUserName || !ljUserName.length) {
-							return;
-						}
+					'lj': (function(){
+						function updateUser(name){
+							var ljTags = editor.document.getElementsByTag('lj');
 
-						var ljUserTitle = element.attributes.title;
-						var cacheName = ljUserTitle ? ljUserName + ':' + ljUserTitle : ljUserName;
+							for(var i = 0, l = ljTags.count(); i < l; i++){
+								var ljTag = ljTags.getItem(i);
 
-						if (ljUsers.hasOwnProperty(cacheName)) {
-							var ljTag = (new CKEDITOR.htmlParser.fragment.fromHtml(ljUsers[cacheName])).children[0];
+								var userName = ljTag.getAttribute('user');
+								var userTitle = ljTag.getAttribute('title');
+								if(name == (userTitle ? userName + ':' + userTitle : userName)){
+									var newLjTag = new CKEDITOR.dom.element.createFromHtml(ljUsers[name], editor.document);
+									newLjTag.setAttribute('lj-cmd', 'LJUserLink');
+									ljTag.insertBeforeMe(newLjTag);
+									ljTag.remove();
+								}
+							}
 
-							ljTag.attributes['lj-cmd'] = 'LJUserLink';
-							ljTag.attributes.contentEditable = 'false';
-							return ljTag;
-						} else {
-							var postData = {
-								username: ljUserName
-							};
+							editor.removeListener('dataReady', updateUser);
+						}
 
-							if (ljUserTitle) {
-								postData.usertitle = ljUserTitle;
+						return function(element){
+							var ljUserName = element.attributes.user;
+							if(!ljUserName || !ljUserName.length){
+								return;
 							}
 
-							HTTPReq.getJSON({
-								data: HTTPReq.formEncoded(postData),
-								method: 'POST',
-								url: Site.siteroot + '/tools/endpoints/ljuser.bml',
-								onError: function(err) {
-									alert(err + ' "' + ljUserName + '"');
-								},
-								onData: function(data) {
-									if (data.error) {
-										return alert(data.error + ' "' + username + '"');
-									}
+							var ljUserTitle = element.attributes.title;
+							var cacheName = ljUserTitle ? ljUserName + ':' + ljUserTitle : ljUserName;
 
-									if (!data.success) {
-										return;
-									}
+							if(ljUsers.hasOwnProperty(cacheName)){
+								var ljTag = (new CKEDITOR.htmlParser.fragment.fromHtml(ljUsers[cacheName])).children[0];
 
-									ljUsers[cacheName] = data.ljuser;
+								ljTag.attributes['lj-cmd'] = 'LJUserLink';
+								return ljTag;
+							} else {
+								var postData = {
+									username: ljUserName
+								};
 
-									data.ljuser = data.ljuser.replace('<span class="useralias-value">*</span>', '');
+								if(ljUserTitle){
+									postData.usertitle = ljUserTitle;
+								}
 
-									var ljTags = editor.document.getElementsByTag('lj');
+								HTTPReq.getJSON({
+									data: HTTPReq.formEncoded(postData),
+									method: 'POST',
+									url: Site.siteroot + '/tools/endpoints/ljuser.bml',
+									onError: function(err){
+										alert(err + ' "' + ljUserName + '"');
+									},
+									onData: function(data){
+										if(data.error){
+											return alert(data.error + ' "' + username + '"');
+										}
 
-									for (var i = 0, l = ljTags.count(); i < l; i++) {
-										var ljTag = ljTags.getItem(i);
+										if(!data.success){
+											return;
+										}
 
-										var userName = ljTag.getAttribute('user');
-										var userTitle = ljTag.getAttribute('title');
-										if (cacheName == (userTitle ? userName + ':' + userTitle : userName)) {
-											var newLjTag = new CKEDITOR.dom.element.createFromHtml(ljUsers[cacheName], editor.document);
-											newLjTag.setAttribute('lj-cmd', 'LJUserLink');
-											newLjTag.setAttribute('contentEditable', 'false');
-											ljTag.insertBeforeMe(newLjTag);
-											ljTag.remove();
+										ljUsers[cacheName] = data.ljuser;
+
+										data.ljuser = data.ljuser.replace('<span class="useralias-value">*</span>', '');
+
+										if(editor.document){
+											updateUser(cacheName);
+										} else {
+											editor.on('dataReady', function(){
+												updateUser(cacheName);
+											});
 										}
 									}
-								}
-							});
-						}
-					},
+								});
+							}
+						};
+					})(),
 					'lj-map': function(element) {
-						return new CKEDITOR.htmlParser.fragment.fromHtml('' + '<div style="' + 'width: ' + (isNaN(element.attributes
-							.width) ? 500 : element.attributes.width) + 'px;' + 'height: ' + (isNaN(element.attributes
-							.height) ? 350 : element.attributes
-							.height) + 'px;"' + 'contentEditable="false"' + 'lj-url="' + (encodeURIComponent(element.attributes
-							.url) || '') + '"' + 'class="lj-map"><p>map</p>' + '</div>').children[0];
+						var fakeElement = new CKEDITOR.htmlParser.element('iframe');
+						fakeElement.attributes.style = '' + 'width:' + (isNaN(element.attributes.width) ? 500 : element.attributes
+							.width) + 'px;' + 'height:' + (isNaN(element.attributes.height) ? 350 : element.attributes
+							.height) + 'px;';
+
+						fakeElement.attributes['lj-url'] = element.attributes.url ? encodeURIComponent(element.attributes.url) : '';
+						fakeElement.attributes['class'] = 'lj-map';
+						fakeElement.attributes['lj-content'] = '<p>map</p>';
+						fakeElement.attributes['frameBorder'] = 0;
+						fakeElement.attributes['allowTransparency'] = 'true';
+
+						return fakeElement;
 					},
 					'lj-repost': function(element) {
 						var fakeElement = new CKEDITOR.htmlParser.element('input');
 						fakeElement.attributes.type = 'button';
-						fakeElement.attributes.value = (element.attributes && element.attributes.button) || top.CKLang.LJRepost_Value;
+						fakeElement.attributes.value = (element.attributes && element.attributes.button) || top.CKLang
+							.LJRepost_Value;
 						fakeElement.attributes['class'] = 'lj-repost';
 						return fakeElement;
 					},
@@ -1197,24 +1337,23 @@
 					'lj-wishlist': function(element) {
 						element.name = 'lj:wishlist';
 					},
-					'lj-template': function(element){
+					'lj-template': function(element) {
 						element.name = 'lj:template';
-						element.attributes.contentEditable = 'false';
 						element.children.length = 0;
 					},
 					a: function(element) {
-						if(element.parent.attributes && element.parent.attributes.contentEditable != 'false'){
+						if (element.parent.attributes && !element.parent.attributes['lj:user']) {
 							element.attributes['lj-cmd'] = 'LJLink';
 						}
 					},
 					img: function(element) {
 						var parent = element.parent.parent;
-						if (!parent || !parent.attributes || parent.attributes.contentEditable != 'false') {
+						if (!parent || !parent.attributes || !parent.attributes['lj:user']) {
 							element.attributes['lj-cmd'] = 'image';
 						}
 					},
-					div: function(element){
-						if(element.attributes && element.attributes['class'] == 'ljcut'){
+					div: function(element) {
+						if (element.attributes && element.attributes['class'] == 'ljcut') {
 							var newElement = new CKEDITOR.htmlParser.element('lj:cut');
 							newElement.attributes['lj-cmd'] = 'LJCut';
 							newElement.children = element.children;
@@ -1226,36 +1365,43 @@
 
 			dataProcessor.htmlFilter.addRules({
 				elements: {
-					div: function(element) {
+					iframe: function(element) {
 						var newElement = element;
-						switch (element.attributes['class']) {
+						var className = /lj-[a-z]+/i.exec(element.attributes['class'])[0];
+						switch (className) {
 							case 'lj-like':
 								newElement = new CKEDITOR.htmlParser.element('lj-like');
 								newElement.attributes.buttons = element.attributes.buttons;
-								if (element.attributes.style) {
-									newElement.attributes.style = element.attributes.style;
+								if (element.attributes.hasOwnProperty('lj-style')) {
+									newElement.attributes.style = element.attributes['lj-style'];
 								}
 								newElement.isEmpty = true;
 								newElement.isOptionalClose = true;
 								break;
 							case 'lj-embed':
 								newElement = new CKEDITOR.htmlParser.element('lj-embed');
-								newElement.attributes.id = element.attributes.embedid;
+								newElement.attributes.id = element.attributes.id;
 								if (element.attributes.hasOwnProperty('source_user')) {
 									newElement.attributes.source_user = element.attributes.source_user;
 								}
-								newElement.children = element.children;
+								newElement.children = new CKEDITOR.htmlParser.fragment.fromHtml(decodeURIComponent(element
+									.attributes['lj-data'])).children;
 								newElement.isOptionalClose = true;
 								break;
 							case 'lj-map':
 								newElement = new CKEDITOR.htmlParser.element('lj-map');
 								newElement.attributes.url = decodeURIComponent(element.attributes['lj-url']);
-								element.attributes.style && element.attributes.style.replace(/([a-z-]+):(.*?);/gi, function(relust, name, value) {
+								element.attributes.style && (element.attributes.style + ';')
+									.replace(/([a-z-]+):(.*?);/gi, function(result, name, value) {
 									newElement.attributes[name.toLowerCase()] = parseInt(value);
 								});
 
 								newElement.isOptionalClose = newElement.isEmpty = true;
 								break;
+							case 'lj-poll':
+								newElement = new CKEDITOR.htmlParser.fragment.fromHtml(decodeURIComponent(element
+									.attributes['lj-data'])).children[0];
+								break;
 							default:
 								if (!element.children.length) {
 									newElement = false;
@@ -1269,38 +1415,43 @@
 						if (userName) {
 							var ljUserNode = new CKEDITOR.htmlParser.element('lj');
 							ljUserNode.attributes.user = userName;
-							var userTitle = element.children[1].children[0].children[0].value;
 
+							try {
+								var userTitle = element.children[1].children[0].children[0].value;
+							} catch(e) {
+								return false;
+							}
+
 							if (userTitle && userTitle != userName) {
 								ljUserNode.attributes.title = userTitle;
 							}
 
 							ljUserNode.isOptionalClose = ljUserNode.isEmpty = true;
 							return ljUserNode;
-						} else if(element.attributes.style == 'display: none;'){
+						} else if (element.attributes.style == 'display: none;' || !element.children.length) {
 							return false;
 						}
 					},
 					input: function(element) {
 						if (element.attributes['class'] == 'lj-repost') {
 							var newElement = new CKEDITOR.htmlParser.element('lj-repost');
-							if(element.attributes.value != top.CKLang.LJRepost_Value){
+							if (element.attributes.value != top.CKLang.LJRepost_Value) {
 								newElement.attributes.button = element.attributes.value;
 							}
 							newElement.isOptionalClose = newElement.isEmpty = true;
 							return newElement;
 						}
 					},
-					form: function(element) {
-						if (element.attributes['class'] == 'ljpoll') {
-							return new CKEDITOR.htmlParser.fragment.fromHtml(unescape(element.attributes.data)).children[0];
+					div: function(element){
+						if(!element.children.length){
+							return false;
 						}
 					},
-					'lj:template': function(element){
+					'lj:template': function(element) {
 						element.name = 'lj-template';
 						element.isOptionalClose = element.isEmpty = true;
 					},
-					'lj:cut': function(element){
+					'lj:cut': function(element) {
 						element.name = 'lj-cut'
 					},
 					'lj:raw': function(element) {

Modified: trunk/htdocs/js/poll.js
===================================================================
--- trunk/htdocs/js/poll.js	2011-10-18 11:21:44 UTC (rev 20360)
+++ trunk/htdocs/js/poll.js	2011-10-18 11:34:13 UTC (rev 20361)
@@ -26,18 +26,16 @@
 		this.questions = [];
 
 		selectPoll.find(tagPrefix + 'pq').each(function(i, pq){
-			pq = jQuery(pq);
-			var name = pq.html().match(/^\s*(.*?)\s*(?:<lj:pi>|$)/);
 			var question = {
-				name: (name && name[1]) || '',
-				type: pq.attr('type'),
+				name: pq.firstChild.nodeValue || '',
+				type: pq.getAttribute('type'),
 				answers: []
 			};
 
 			if(!/^check|drop|radio|scale|text$/.test(question.type)){
 				return;
 			}
-
+			pq = jQuery(pq);
 			if(/^check|drop|radio$/.test(question.type)){
 				pq.find(tagPrefix + 'pi').each(function(){
 					question.answers.push(jQuery(this).html())
@@ -74,7 +72,7 @@
 
 // Poll method to generate HTML for RTE
 Poll.prototype.outputHTML = function(){
-	var html = '<form action="#" lj-cmd="LJPollLink" class="ljpoll" data="' + escape(this.outputLJtags()) + '" contentEditable="false"><b>Poll #xxxx</b>';
+	var html = '<form action="#"><b>Poll #xxxx</b>';
 
 	if(this.name){
 		html += ' <i>' + this.name + '</i>';
@@ -109,7 +107,7 @@
 	}
 
 	html += '<input type="submit" value="Submit Poll"/></form>';
-	return html;
+	return encodeURIComponent(html);
 };
 
 // Poll method to generate LJ Poll tags
@@ -126,18 +124,18 @@
 			extrargs = ' from="' + this.questions[i].from + '"' + ' to="' + this.questions[i].to + '"' + ' by="' + this
 				.questions[i].by + '"';
 		}
-		tags += '<lj-pq type="' + this.questions[i].type + '"' + extrargs + '>' + this.questions[i].name;
+		tags += '<lj-pq type="' + this.questions[i].type + '"' + extrargs + '>' + this.questions[i].name + '<br />';
 		if(/^check|drop|radio$/.test(this.questions[i].type)){
 			for(var j = 0; j < this.questions[i].answers.length; j++){
-				tags += '<br /><lj-pi>' + this.questions[i].answers[j] + '</lj-pi>';
+				tags += '<lj-pi>' + this.questions[i].answers[j] + '</lj-pi><br />';
 			}
 		}
-		tags += '<br /></lj-pq>';
+		tags += '</lj-pq><br />';
 	}
 
-	tags += '<br /></lj-poll>';
+	tags += '</lj-poll>';
 
-	return tags;
+	return encodeURIComponent(tags);
 };
 
 // Answer Object Constructor

Tags: b_vladi, css, js, livejournal, vkurkin
Subscribe
  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

  • 0 comments