5 label: top.CKLang.LJLike_button_facebook,
8 html: '<span class="lj-like-item lj-like-gag fb">' + top.CKLang.LJLike_button_facebook + '</span>',
9 htmlOpt: '<li class="like-fb"><input type="checkbox" id="like-fb" /><label for="like-fb">' + top.CKLang
10 .LJLike_button_facebook + '</label></li>'
13 label: top.CKLang.LJLike_button_twitter,
16 html: '<span class="lj-like-item lj-like-gag tw">' + top.CKLang.LJLike_button_twitter + '</span>',
17 htmlOpt: '<li class="like-tw"><input type="checkbox" id="like-tw" /><label for="like-tw">' + top.CKLang
18 .LJLike_button_twitter + '</label></li>'
21 label: top.CKLang.LJLike_button_google,
24 html: '<span class="lj-like-item lj-like-gag go">' + top.CKLang.LJLike_button_google + '</span>',
25 htmlOpt: '<li class="like-go"><input type="checkbox" id="like-go" /><label for="like-go">' + top.CKLang
26 .LJLike_button_google + '</label></li>'
29 label: top.CKLang.LJLike_button_vkontakte,
32 html: '<span class="lj-like-item lj-like-gag vk">' + top.CKLang.LJLike_button_vkontakte + '</span>',
34 .isSupUser ? '<li class="like-vk"><input type="checkbox" id="like-vk" /><label for="like-vk">' + top.CKLang
35 .LJLike_button_vkontakte + '</label></li>' : ''
38 label: top.CKLang.LJLike_button_give,
41 html: '<span class="lj-like-item lj-like-gag lj">' + top.CKLang.LJLike_button_give + '</span>',
42 htmlOpt: '<li class="like-lj"><input type="checkbox" id="like-lj" /><label for="like-lj">' + top.CKLang
43 .LJLike_button_give + '</label></li>'
51 html: encodeURIComponent(top.CKLang.Poll_PollWizardNotice + '<br /><a href="#">' + top.CKLang
52 .Poll_PollWizardNoticeLink + '</a>')
55 html: encodeURIComponent(top.CKLang.LJLike_WizardNotice + '<br /><a href="#">' + top.CKLang
56 .LJLike_WizardNoticeLink + '</a>')
59 html: encodeURIComponent(top.CKLang.LJUser_WizardNotice + '<br /><a href="#">' + top.CKLang
60 .LJUser_WizardNoticeLink + '</a>')
63 html: encodeURIComponent(top.CKLang.LJLink_WizardNotice + '<br /><a href="#">' + top.CKLang
64 .LJLink_WizardNoticeLink + '</a>')
67 html: encodeURIComponent(top.CKLang.LJImage_WizardNotice + '<br /><a href="#">' + top.CKLang
68 .LJImage_WizardNoticeLink + '</a>')
71 html: encodeURIComponent(top.CKLang.LJCut_WizardNotice + '<br /><a href="#">' + top.CKLang
72 .LJCut_WizardNoticeLink + '</a>')
79 CKEDITOR.plugins.add('livejournal', {
80 init: function(editor) {
81 function onFindCmd(evt) {
84 if (evt.name == 'mouseout') {
89 var node = evt.data.getTarget();
91 var isNoMouseOver = evt.name != 'mouseover';
94 node = node.getParent();
99 if (node.type == 1 && node.is('img')) {
100 node.setAttribute('lj-cmd', 'LJImage');
101 } else if (node.is('a')) {
102 node.setAttribute('lj-cmd', 'LJLink');
106 var attr = node.getAttribute('lj-cmd');
112 node = node.getParent();
115 if (cmd && ljNoteData.hasOwnProperty(cmd)) {
117 ljNoteData[cmd].node = actNode;
118 editor.getCommand(cmd).setState(CKEDITOR.TRISTATE_ON);
120 note.show(ljNoteData[cmd].html, cmd, actNode);
126 for (var command in ljNoteData) {
127 if (ljNoteData.hasOwnProperty(command) && (!cmd || cmd != command)) {
128 delete ljNoteData[command].node;
129 editor.getCommand(command).setState(CKEDITOR.TRISTATE_OFF);
135 editor.dataProcessor.toHtml = function(html, fixForBody) {
136 html = html.replace(/<((?!br)[^\s>]+)((?!\/>).*?)\/>/gi, '<$1$2></$1>')
137 .replace(/<lj-template name=['"]video['"]>(\S+?)<\/lj-template>/g, '<div class="ljvideo" url="$1"><img src="' + Site
138 .statprefix + '/fck/editor/plugins/livejournal/ljvideo.gif" /></div>')
139 .replace(/<lj-poll .*?>[^\b]*?<\/lj-poll>/gm,
141 return new Poll(ljtags).outputHTML();
142 }).replace(/<lj-template(.*?)><\/lj-template>/g, "<lj-template$1 />");
144 // IE custom tags. http://msdn.microsoft.com/en-us/library/ms531076%28VS.85%29.aspx
145 if (CKEDITOR.env.ie) {
146 html = html.replace(/<([\/])?lj-raw>/g, '<$1lj:raw>').replace(/<([\/])?lj-wishlist>/g, '<$1lj:wishlist>')
147 .replace(/(<lj [^>]*)> /g, '$1> '); // IE merge spaces
149 // close <lj user> tags
150 html = html.replace(/(<lj [^>]*[^\/])>/g, '$1/> ');
152 if (!$('event_format').checked) {
153 html = '<pre>' + html + '</pre>';
156 html = CKEDITOR.htmlDataProcessor.prototype.toHtml.call(this, html, fixForBody);
158 if (!$('event_format').checked) {
159 html = html.replace(/<\/?pre>/g, '');
160 html = html.replace(/\n/g, '<br\/>');
166 editor.dataProcessor.toDataFormat = function(html, fixForBody) {
167 html = html.replace(/^<pre>\n*([\s\S]*?)\n*<\/pre>\n*$/, '$1');
169 html = CKEDITOR.htmlDataProcessor.prototype.toDataFormat.call(this, html, fixForBody);
171 html = html.replace(/\t/g, ' ');
172 html = html.replace(/>\n\s*(?!\s)([^<]+)</g, '>$1<');
173 if (!CKEDITOR.env.ie) {
174 html = html.replace(/<br (type="_moz" )? ?\/>$/, '');
175 if (CKEDITOR.env.webkit) {
176 html = html.replace(/<br type="_moz" \/>/, '');
180 html = html.replace(/<form.*?class="ljpoll".*?data="([^"]*)"[\s\S]*?<\/form>/gi,
181 function(form, data) {
182 return unescape(data);
183 }).replace(/<\/lj>/g, '');
186 .replace(/<div(?=[^>]*class="ljvideo")[^>]*url="(\S+)"[^>]*><img.+?\/><\/div>/g, '<lj-template name="video">$1</lj-template>')
187 .replace(/<div(?=[^>]*class="ljvideo")[^>]*url="\S+"[^>]*>([\s\S]+?)<\/div>/g, '<p>$1</p>')
188 .replace(/<div([^>]*)qotdid="(\d+)"([^>]*)>[^\b]*<\/div>(<br \/>)*/g, '<lj-template id="$2"$1$3 /><br />')// div tag and qotdid attrib
189 .replace(/(<lj-template id="\d+" )([^>]*)class="ljqotd"?([^>]*\/>)/g, '$1name="qotd" $2$3')// class attrib
190 .replace(/(<lj-template id="\d+" name="qotd" )[^>]*(lang="\w+")[^>]*\/>/g, '$1$2 \/>'); // lang attrib
192 if (!$('event_format').checked && !window.switchedRteOn) {
193 html = html.replace(/\n?\s*<br \/>\n?/g, '\n');
197 if (CKEDITOR.env.ie) {
198 html = html.replace(/<lj:cut([^>]*)>/g, '<lj-cut$1>').replace(/<\/lj:cut>/g, '</lj-cut>')
199 .replace(/<([\/])?lj:wishlist>/g, '<$1lj-wishlist>').replace(/<([\/])?lj:raw>/g, '<$1lj-raw>');
202 html = html.replace(/><\/lj-template>/g, '/>');// remove null pointer.replace(/\ufeff/g, '');
207 function addLastTag() {
208 var body = editor.document.getBody();
209 var last = body.getLast();
210 if (last && last.type == 1 && !last.is('br')) {
211 body.appendHtml('<br />');
215 editor.on('dataReady', function() {
217 editor.document.on('mouseover', onFindCmd);
218 editor.document.on('mouseout', onFindCmd);
219 editor.document.on('keyup', onFindCmd);
220 editor.document.on('click', onFindCmd);
222 editor.document.on('keyup', addLastTag);
223 editor.document.on('click', addLastTag);
230 noteNode = document.createElement('lj-note'),
231 isIE = typeof(document.body.style.opacity) != 'string';
233 var animate = (function() {
236 steps = totalTime * fps / 1000,
239 parentContainer = document.getElementById('draft-container') || document.body;
242 var data = timeOuts.shift();
243 var currentStep = (type ? data.time / totalTime : -(data.time / totalTime - 1)).toFixed(1);
245 if (!timeOuts.length) {
246 currentStep = type ? 1 : 0;
251 .filter = (currentStep >= 1) ? null : 'progid:DXImageTransform.Microsoft.Alpha(opacity=' + (currentStep * 100) + ')';
253 noteNode.style.opacity = currentStep;
256 if (currentStep == 0 && noteNode && noteNode.parentNode) {
257 noteNode.parentNode.removeChild(noteNode);
261 return function(animateType) {
264 if (type && noteNode.parentNode) {
266 noteNode.style.filter = null;
268 noteNode.style.opacity = 1;
271 for (var i = 1; i <= steps; i++) {
272 var time = Math.floor(1000 / fps) * i;
275 timer: setTimeout(apply, time)
280 parentContainer.appendChild(noteNode);
281 noteNode.style.marginTop = -noteNode.offsetHeight / 2 + 'px';
282 noteNode.style.marginLeft = -noteNode.offsetWidth / 2 + 'px';
286 noteNode.className = 'note-popup';
288 noteNode.onmouseout = function() {
289 if (!currentData.cmd) {
294 noteNode.onmouseover = function() {
295 if (timer && !state) {
303 noteNode.style.filter = 'progid:DXImageTransform.Microsoft.Alpha(opacity=0)';
305 noteNode.style.opacity = 0;
309 if (currentData.cmd) {
310 currentNoteNode = ljNoteData[currentData.cmd].node = currentData.node;
311 editor.execCommand(currentData.cmd);
316 function applyNote() {
318 currentData.cmd = tempData.cmd;
319 currentData.data = tempData.data;
320 currentData.node = tempData.node;
322 delete tempData.node;
324 delete tempData.data;
326 noteNode.innerHTML = decodeURIComponent(currentData.data);
328 var link = noteNode.getElementsByTagName('a')[0];
329 if (link && currentData.cmd) {
330 link.onclick = callCmd;
333 delete currentData.node;
334 delete currentData.cmd;
335 delete currentData.data;
337 currentNoteNode = null;
346 show: function(data, cmd, node) {
347 if (data == tempData.data && cmd == tempData.cmd && node === tempData.node) {
357 timer = setTimeout(applyNote, 1000);
359 tempData.data = data;
361 tempData.node = node;
363 hide: function(isNow) {
372 if (noteNode.parentNode) {
373 isNow === true ? applyNote() : timer = setTimeout(applyNote, 500);
382 ////////// LJ User Button //////////////
383 var url = top.Site.siteroot + '/tools/endpoints/ljuser.bml';
385 editor.on('doubleclick', function(evt) {
386 var command = editor.getCommand('LJUserLink');
387 if (command.state == CKEDITOR.TRISTATE_ON) {
391 evt.data.dialog = '';
394 editor.addCommand('LJUserLink', {
395 exec: function(editor) {
397 selection = editor.getSelection(),
398 LJUser = ljNoteData.LJUserLink.node;
400 if (ljNoteData.LJUserLink.node) {
401 userName = prompt(top.CKLang.UserPrompt, ljNoteData.LJUserLink.node.getElementsByTag('b').getItem(0)
403 } else if (selection.getType() == 2) {
404 userName = selection.getSelectedText();
407 if (userName == '') {
408 userName = prompt(top.CKLang.UserPrompt, userName);
415 parent.HTTPReq.getJSON({
416 data: parent.HTTPReq.formEncoded({
421 onData: function(data) {
429 data.ljuser = data.ljuser.replace('<span class="useralias-value">*</span>', '');
431 ljUsers[userName] = data.ljuser;
433 var tmpNode = editor.document.createElement('div');
434 tmpNode.setHtml(data.ljuser);
435 ljNoteData.LJUserLink.node = tmpNode.getFirst();
436 ljNoteData.LJUserLink.node.setAttribute('lj-cmd', 'LJUserLink');
439 LJUser.$.parentNode.replaceChild(ljNoteData.LJUserLink.node.$, LJUser.$);
441 editor.insertElement(ljNoteData.LJUserLink.node);
448 editor.ui.addButton('LJUserLink', {
449 label: top.CKLang.LJUser,
450 command: 'LJUserLink'
453 ////////// LJ Image Button //////////////
454 editor.addCommand('LJImage', {
455 exec: function(editor) {
456 if (ljNoteData.LJImage.node) {
457 editor.openDialog('image');
458 } else if (window.ljphotoEnabled) {
459 jQuery('#updateForm').photouploader({
461 }).photouploader('show').bind('htmlready', function (event, html) {
462 editor.insertHtml(html);
465 InOb.handleInsertImage();
471 editor.on('doubleclick', function() {
472 if (ljNoteData.LJImage.node){
473 editor.execCommand('LJImage');
477 editor.ui.addButton('LJImage', {
478 label: editor.lang.common.imageButton,
482 ////////// LJ Link Button //////////////
483 editor.addCommand('LJLink', {
484 exec: function(editor) {
485 editor.openDialog('link');
490 editor.on('doubleclick', function(evt) {
491 if (ljNoteData.LJLink.node) {
492 editor.openDialog('link');
496 editor.ui.addButton('LJLink', {
497 label: editor.lang.link.tollbar,
501 ////////// LJ Justify //////////////
503 function getState(editor, path) {
504 var firstBlock = path.block || path.blockLimit;
506 if (!firstBlock || firstBlock.getName() == 'body')
507 return CKEDITOR.TRISTATE_OFF;
509 return ( getAlignment(firstBlock, editor.config.useComputedState) == this.value ) ? CKEDITOR
510 .TRISTATE_ON : CKEDITOR.TRISTATE_OFF;
513 function getAlignment(element, useComputedState) {
514 useComputedState = useComputedState === undefined || useComputedState;
517 if (useComputedState)
518 align = element.getComputedStyle('text-align'); else {
519 while (!element.hasAttribute || !( element.hasAttribute('align') || element.getStyle('text-align') )) {
520 var parent = element.getParent();
525 align = element.getStyle('text-align') || element.getAttribute('align') || '';
528 align && ( align = align.replace(/-moz-|-webkit-|start|auto/i, '') );
530 !align && useComputedState && ( align = element.getComputedStyle('direction') == 'rtl' ? 'right' : 'left' );
535 function onSelectionChange(evt) {
536 if (evt.editor.readOnly)
539 var command = evt.editor.getCommand(this.name);
540 command.state = getState.call(this, evt.editor, evt.data.path);
541 command.fire('state');
544 function JustifyCommand(editor, name, value) {
548 var classes = editor.config.justifyClasses;
552 this.cssClassName = classes[0];
555 this.cssClassName = classes[1];
558 this.cssClassName = classes[2];
561 this.cssClassName = classes[3];
565 this.cssClassRegex = new RegExp('(?:^|\\s+)(?:' + classes.join('|') + ')(?=$|\\s)');
569 function onDirChanged(e) {
570 var editor = e.editor;
572 var range = new CKEDITOR.dom.range(editor.document);
573 range.setStartBefore(e.data.node);
574 range.setEndAfter(e.data.node);
576 var walker = new CKEDITOR.dom.walker(range),
579 while (( node = walker.next() )) {
580 if (node.type == CKEDITOR.NODE_ELEMENT) {
581 // A child with the defined dir is to be ignored.
582 if (!node.equals(e.data.node) && node.getDirection()) {
583 range.setStartAfter(node);
584 walker = new CKEDITOR.dom.walker(range);
588 // Switch the alignment.
589 var classes = editor.config.justifyClasses;
591 // The left align class.
592 if (node.hasClass(classes[ 0 ])) {
593 node.removeClass(classes[ 0 ]);
594 node.addClass(classes[ 2 ]);
596 // The right align class.
597 else if (node.hasClass(classes[ 2 ])) {
598 node.removeClass(classes[ 2 ]);
599 node.addClass(classes[ 0 ]);
603 // Always switch CSS margins.
604 var style = 'text-align';
605 var align = node.getStyle(style);
608 node.setStyle(style, 'right'); else if (align == 'right')
609 node.setStyle(style, 'left');
614 JustifyCommand.prototype = {
615 exec : function(editor) {
616 if(ljNoteData.LJLike.node){
617 ljNoteData.LJLike.node.removeAttribute('contenteditable');
618 editor.getSelection().selectElement(ljNoteData.LJLike.node);
621 var selection = editor.getSelection(),
622 enterMode = editor.config.enterMode;
627 var bookmarks = selection.createBookmarks(),
628 ranges = selection.getRanges(true);
630 var cssClassName = this.cssClassName,
634 var useComputedState = editor.config.useComputedState;
635 useComputedState = useComputedState === undefined || useComputedState;
637 for (var i = ranges.length - 1; i >= 0; i--) {
638 iterator = ranges[ i ].createIterator();
639 iterator.enlargeBr = enterMode != CKEDITOR.ENTER_BR;
641 while (( block = iterator.getNextParagraph(enterMode == CKEDITOR.ENTER_P ? 'p' : 'div') )) {
642 block.removeAttribute('align');
643 block.removeStyle('text-align');
645 // Remove any of the alignment classes from the className.
646 var className = cssClassName && ( block.$.className = CKEDITOR.tools.ltrim(block.$.className
647 .replace(this.cssClassRegex, '')) );
649 var apply = ( this.state == CKEDITOR
650 .TRISTATE_OFF ) && ( !useComputedState || ( getAlignment(block, true) != this.value ) );
653 // Append the desired class name.
655 block.addClass(cssClassName); else if (!className)
656 block.removeAttribute('class');
658 block.setStyle('text-align', this.value);
664 editor.forceNextSelectionCheck();
665 selection.selectBookmarks(bookmarks);
667 if (ljNoteData.LJLike.node) {
668 ljNoteData.LJLike.node.setAttribute('contenteditable', 'false');
673 var left = new JustifyCommand(editor, 'justifyleft', 'left'),
674 center = new JustifyCommand(editor, 'justifycenter', 'center'),
675 right = new JustifyCommand(editor, 'justifyright', 'right'),
676 justify = new JustifyCommand(editor, 'justifyblock', 'justify');
678 editor.addCommand('justifyleft', left);
679 editor.addCommand('justifycenter', center);
680 editor.addCommand('justifyright', right);
681 editor.addCommand('justifyblock', justify);
683 editor.ui.addButton('JustifyLeft', {
684 label : editor.lang.justify.left,
685 command : 'justifyleft'
687 editor.ui.addButton('JustifyCenter', {
688 label : editor.lang.justify.center,
689 command : 'justifycenter'
691 editor.ui.addButton('JustifyRight', {
692 label : editor.lang.justify.right,
693 command : 'justifyright'
695 editor.ui.addButton('JustifyBlock', {
696 label : editor.lang.justify.block,
697 command : 'justifyblock'
700 editor.on('selectionChange', CKEDITOR.tools.bind(onSelectionChange, left));
701 editor.on('selectionChange', CKEDITOR.tools.bind(onSelectionChange, right));
702 editor.on('selectionChange', CKEDITOR.tools.bind(onSelectionChange, center));
703 editor.on('selectionChange', CKEDITOR.tools.bind(onSelectionChange, justify));
704 editor.on('dirChanged', onDirChanged);
709 ////////// LJ Embed Media Button //////////////
710 editor.addCommand('LJEmbedLink', {
712 top.LJ_IPPU.textPrompt(top.CKLang.LJEmbedPromptTitle, top.CKLang.LJEmbedPrompt, doEmbed, {
718 editor.ui.addButton('LJEmbedLink', {
719 label: top.CKLang.LJEmbed,
720 command: 'LJEmbedLink'
723 editor.addCss('.lj-embed' + '{'
724 + 'background-image: url(' + CKEDITOR.getUrl(this.path + 'images/placeholder_flash.png') + ');'
725 + 'background-position: center center;'
726 + 'background-repeat: no-repeat;'
727 + 'background-color: #CCCCCC;'
728 + 'border: 1px dotted #000000;'
729 + 'min-height: 80px;'
732 function doEmbed(content) {
733 if (content && content.length) {
734 if (window.switchedRteOn) {
735 editor.insertHtml('<div class="lj-embed" contentEditable="false">' + content + '</div><br/>');
740 ////////// LJ Cut Button //////////////
741 editor.on('doubleclick', function(evt) {
742 var command = editor.getCommand('LJCut');
743 if (command.state == CKEDITOR.TRISTATE_ON) {
748 editor.addCommand('LJCut', {
751 if (ljNoteData.LJCut.node) {
752 text = prompt(top.CKLang.CutPrompt, ljNoteData.LJCut.node.getAttribute('text') || top.CKLang.ReadMore);
754 if (text == top.CKLang.ReadMore) {
755 ljNoteData.LJCut.node.removeAttribute('text');
757 ljNoteData.LJCut.node.setAttribute('text', text);
761 text = prompt(top.CKLang.CutPrompt, top.CKLang.ReadMore);
763 ljNoteData.LJCut.node = editor.document.createElement('lj-cut');
764 ljNoteData.LJCut.node.setAttribute('lj-cmd', 'LJCut');
765 if (text != top.CKLang.ReadMore) {
766 ljNoteData.LJCut.node.setAttribute('text', text);
768 editor.getSelection().getRanges()[0].extractContents().appendTo(ljNoteData.LJCut.node);
769 editor.insertElement(ljNoteData.LJCut.node);
770 var range = new CKEDITOR.dom.range(editor.document);
771 range.selectNodeContents(ljNoteData.LJCut.node);
772 editor.getSelection().selectRanges([range]);
778 editor.ui.addButton('LJCut', {
779 label: top.CKLang.LJCut,
783 ////////// LJ Poll Button //////////////
784 if (top.canmakepoll) {
787 editor.on('doubleclick', function(evt) {
788 var command = editor.getCommand('LJPollLink');
789 if (command.state == CKEDITOR.TRISTATE_ON) {
791 evt.data.dialog = '';
795 CKEDITOR.dialog.add('LJPollDialog', function() {
796 var isAllFrameLoad = 0, okButtonNode, questionsWindow, setupWindow;
798 var onLoadPollPage = function() {
799 if (this.removeListener) {
800 this.removeListener('load', onLoadPollPage);
802 if (isAllFrameLoad && okButtonNode) {
803 currentPoll = new Poll(ljNoteData.LJPollLink.node && unescape(ljNoteData.LJPollLink.node
804 .getAttribute('data')), questionsWindow.document, setupWindow.document, questionsWindow.Questions);
806 questionsWindow.ready(currentPoll);
807 setupWindow.ready(currentPoll);
809 okButtonNode.style.display = 'block';
815 var buttonsDefinition = [new CKEDITOR.ui.button({
818 label: editor.lang.common.ok,
819 onClick: function(evt) {
820 evt.data.dialog.hide();
821 var pollSource = new Poll(currentPoll, questionsWindow.document, setupWindow.document, questionsWindow
822 .Questions).outputHTML();
824 if (pollSource.length > 0) {
825 if (ljNoteData.LJPollLink.node) {
826 var node = editor.document.createElement('div');
827 node.setHtml(pollSource);
828 ljNoteData.LJPollLink.node.insertBeforeMe(node);
829 ljNoteData.LJPollLink.node.remove();
831 editor.insertHtml(pollSource);
833 ljNoteData.LJPollLink.node = null;
836 }), CKEDITOR.dialog.cancelButton];
838 CKEDITOR.env.mac && buttonsDefinition.reverse();
841 title: top.CKLang.Poll_PollWizardTitle,
846 if (isAllFrameLoad) {
847 currentPoll = new Poll(ljNoteData.LJPollLink.node && unescape(ljNoteData.LJPollLink.node
848 .getAttribute('data')), questionsWindow.document, setupWindow.document, questionsWindow.Questions);
850 questionsWindow.ready(currentPoll);
851 setupWindow.ready(currentPoll);
862 html: '<iframe src="/tools/ck_poll_setup.bml" allowTransparency="true" frameborder="0" style="width:100%; height:320px;"></iframe>',
863 onShow: function(data) {
865 (okButtonNode = document.getElementById(data.sender.getButton('LJPool_Ok').domId).parentNode)
866 .style.display = 'none';
868 var iframe = this.getElement('iframe');
869 setupWindow = iframe.$.contentWindow;
870 if (setupWindow.ready) {
873 iframe.on('load', onLoadPollPage);
880 id: 'LJPool_Questions',
886 html: '<iframe src="/tools/ck_poll_questions.bml" allowTransparency="true" frameborder="0" style="width:100%; height:320px;"></iframe>',
888 var iframe = this.getElement('iframe');
889 questionsWindow = iframe.$.contentWindow;
890 if (questionsWindow.ready) {
893 iframe.on('load', onLoadPollPage);
900 buttons: buttonsDefinition
904 editor.addCommand('LJPollLink', new CKEDITOR.dialogCommand('LJPollDialog'));
906 editor.addCommand('LJPollLink', {
908 note.show(top.CKLang.Poll_AccountLevelNotice);
912 editor.getCommand('LJPollLink').setState(CKEDITOR.TRISTATE_DISABLED);
915 editor.ui.addButton('LJPollLink', {
916 label: top.CKLang.Poll,
917 command: 'LJPollLink'
920 ////////// LJ Like Button //////////////
921 var buttonsLength = likeButtons.length;
922 var dialogContent = '<div class="cke-dialog-likes"><ul class="cke-dialog-likes-list">';
923 likeButtons.defaultButtons = [];
925 for (var i = 0; i < buttonsLength; i++) {
926 var button = likeButtons[i];
927 likeButtons[button.id] = likeButtons[button.abbr] = button;
928 likeButtons.defaultButtons.push(button.id);
929 dialogContent += button.htmlOpt;
932 dialogContent += '</ul><p class="cke-dialog-likes-faq">' + window.faqLink + '</p></div>';
934 var countChanges = 0, ljLikeDialog, ljLikeInputs;
936 function onChangeLike() {
937 var command = editor.getCommand('LJLike');
938 if (command.state == CKEDITOR.TRISTATE_OFF) {
939 this.$.checked ? countChanges++ : countChanges--;
940 ljLikeDialog.getButton('LJLike_Ok')
941 .getElement()[countChanges == 0 ? 'addClass' : 'removeClass']('btn-disabled');
945 CKEDITOR.dialog.add('LJLikeDialog', function() {
946 var buttonsDefinition = [new CKEDITOR.ui.button({
949 label: editor.lang.common.ok,
950 onClick: function() {
951 if (ljLikeDialog.getButton('LJLike_Ok').getElement().hasClass('btn-disabled')) {
957 likeNode = ljNoteData.LJLike.node;
959 for (var i = 0; i < buttonsLength; i++) {
960 var button = likeButtons[i];
961 var input = document.getElementById('like-' + button.abbr);
962 var currentBtn = likeNode && likeNode.getAttribute('buttons');
963 if ((input && input.checked) || (currentBtn && !button.htmlOpt && (currentBtn.indexOf(button
964 .abbr) + 1 || currentBtn.indexOf(button.id) + 1))) {
965 attr.push(button.id);
966 likeHtml += button.html;
972 ljNoteData.LJLike.node.setAttribute('buttons', attr.join(','));
973 ljNoteData.LJLike.node.setHtml(likeHtml);
975 editor.insertHtml('<div contentEditable="false" class="lj-like" lj-cmd="LJLike" buttons="' + attr
976 .join(',') + '">' + likeHtml + '</div><br />');
978 } else if (likeNode) {
979 ljNoteData.LJLike.node.remove();
984 }), CKEDITOR.dialog.cancelButton];
986 CKEDITOR.env.mac && buttonsDefinition.reverse();
989 title: top.CKLang.LJLike_name,
991 height: window.isSupUser ? 180 : 145,
995 id: 'LJLike_Options',
1004 onShow: function() {
1005 var command = editor.getCommand('LJLike');
1006 var i = countChanges = 0,
1007 isOn = command.state == CKEDITOR.TRISTATE_ON,
1008 buttons = ljNoteData.LJLike.node && ljNoteData.LJLike.node.getAttribute('buttons');
1010 for (; i < buttonsLength; i++) {
1011 var isChecked = buttons ? !!(buttons.indexOf(likeButtons[i].abbr) + 1 || buttons.indexOf(likeButtons[i]
1014 var input = document.getElementById('like-' + likeButtons[i].abbr);
1017 if (isChecked && !isOn) {
1021 input.checked = isChecked;
1025 if (countChanges > 0) {
1026 ljLikeDialog.getButton('LJLike_Ok').getElement().removeClass('btn-disabled');
1029 onLoad: function() {
1030 ljLikeDialog = this;
1031 ljLikeInputs = ljLikeDialog.parts.contents.getElementsByTag('input');
1032 for (var i = 0; i < buttonsLength; i++) {
1033 var item = ljLikeInputs.getItem(i);
1034 item && item.on('click', onChangeLike);
1037 buttons: buttonsDefinition
1041 editor.on('doubleclick', function() {
1042 var command = editor.getCommand('LJLike');
1043 if (command.state == CKEDITOR.TRISTATE_ON) {
1048 editor.addCommand('LJLike', new CKEDITOR.dialogCommand('LJLikeDialog'));
1050 editor.ui.addButton('LJLike', {
1051 label: top.CKLang.LJLike_name,
1055 afterInit: function(editor) {
1056 var dataProcessor = editor.dataProcessor;
1058 dataProcessor.dataFilter.addRules({
1060 'lj-cut': function(element) {
1061 element.attributes['lj-cmd'] = 'LJCut';
1063 'lj-embed': function(element){
1064 var fakeElement = new CKEDITOR.htmlParser.element('div');
1065 fakeElement.attributes.contentEditable = 'false';
1066 fakeElement.attributes['class'] = 'lj-embed';
1067 fakeElement.attributes['embedid'] = element.attributes.id;
1068 fakeElement.children = element.children;
1072 'lj-like': function(element) {
1075 var fakeElement = new CKEDITOR.htmlParser.element('div');
1076 fakeElement.attributes.contentEditable = 'false';
1077 fakeElement.attributes['class'] = 'lj-like';
1078 fakeElement.attributes['lj-cmd'] = 'LJLike';
1080 var currentButtons = element.attributes.buttons && element.attributes.buttons.split(',') || likeButtons
1083 var length = currentButtons.length;
1084 for (var i = 0; i < length; i++) {
1085 var buttonName = currentButtons[i].replace(/^\s*([a-z]{2,})\s*$/i, '$1');
1086 var button = likeButtons[buttonName];
1088 var buttonNode = new CKEDITOR.htmlParser.fragment.fromHtml(button.html).children[0];
1089 fakeElement.add(buttonNode);
1090 attr.push(buttonName);
1094 fakeElement.attributes.buttons = attr.join(',');
1095 fakeElement.attributes.style = element.attributes.style;
1098 'lj': function(element) {
1099 var ljUserName = element.attributes.user;
1100 if (!ljUserName || !ljUserName.length) {
1104 var ljUserTitle = element.attributes.title;
1105 var cacheName = ljUserTitle ? ljUserName + ':' + ljUserTitle : ljUserName;
1107 if (ljUsers.hasOwnProperty(cacheName)) {
1108 var ljTag = (new CKEDITOR.htmlParser.fragment.fromHtml(ljUsers[cacheName])).children[0];
1110 ljTag.attributes['lj-cmd'] = 'LJUserLink';
1113 var onSuccess = function(data) {
1114 ljUsers[cacheName] = data.ljuser;
1117 return alert(data.error + ' "' + username + '"');
1119 if (!data.success) {
1123 data.ljuser = data.ljuser.replace('<span class="useralias-value">*</span>', '');
1125 var ljTags = editor.document.getElementsByTag('lj');
1127 for (var i = 0, l = ljTags.count(); i < l; i++) {
1128 var ljTag = ljTags.getItem(i);
1130 var userName = ljTag.getAttribute('user');
1131 var userTitle = ljTag.getAttribute('title');
1132 if (cacheName == userTitle ? userName + ':' + userTitle : userName) {
1133 ljTag.setHtml(ljUsers[cacheName]);
1134 var newLjTag = ljTag.getFirst();
1135 newLjTag.setAttribute('lj-cmd', 'LJUserLink');
1136 ljTag.insertBeforeMe(newLjTag);
1142 var onError = function(err) {
1143 alert(err + ' "' + ljUserName + '"');
1147 username: ljUserName
1151 postData.usertitle = ljUserTitle;
1155 data: HTTPReq.formEncoded(postData),
1157 url: Site.siteroot + '/tools/endpoints/ljuser.bml',
1163 'lj-map': function(element){
1164 return new CKEDITOR.htmlParser.fragment.fromHtml('' + '<div style="' + 'width: ' + (isNaN(element.attributes
1165 .width) ? 100 : element.attributes.width) + 'px;' + 'height: ' + (isNaN(element.attributes
1166 .height) ? 100 : element.attributes
1167 .height) + 'px;"' + 'contentEditable="false"' + 'lj-url="' + (encodeURIComponent(element.attributes
1168 .url) || '') + '"' + 'class="lj-map"><p>map</p>' + '</div>').children[0];
1170 a: function(element) {
1171 element.attributes['lj-cmd'] = 'LJLink';
1173 img: function(element) {
1174 element.attributes['lj-cmd'] = 'LJImage';
1179 dataProcessor.htmlFilter.addRules({
1181 div: function(element) {
1182 if (element.attributes['class'] == 'lj-like') {
1183 var ljLikeNode = new CKEDITOR.htmlParser.element('lj-like');
1184 ljLikeNode.attributes.buttons = element.attributes.buttons;
1185 if (element.attributes.style) {
1186 ljLikeNode.attributes.style = element.attributes.style;
1188 ljLikeNode.isEmpty = true;
1189 ljLikeNode.isOptionalClose = true;
1191 } else if(element.attributes['class'] == 'lj-embed'){
1192 var ljEmbedNode = new CKEDITOR.htmlParser.element('lj-embed');
1193 ljEmbedNode.attributes.id = element.attributes.embedid;
1194 ljEmbedNode.children = element.children;
1197 } else if (element.attributes['class'] == 'lj-map') {
1198 var ljMapNode = new CKEDITOR.htmlParser.element('lj-map');
1199 ljMapNode.attributes.url = decodeURIComponent(element.attributes['lj-url']);
1200 element.attributes.style.replace(/([a-z-]+):(.*?);/gi, function(relust, name, value){
1201 ljMapNode.attributes[name] = parseInt(value);
1204 ljMapNode.isOptionalClose = ljMapNode.isEmpty = true;
1206 } else if (!element.children.length) {
1210 span: function(element) {
1211 var userName = element.attributes['lj:user'];
1213 var ljUserNode = new CKEDITOR.htmlParser.element('lj');
1214 ljUserNode.attributes.user = userName;
1215 var userTitle = element.children[1].children[0].children[0].value;
1217 if (userTitle && userTitle != userName) {
1218 ljUserNode.attributes.title = userTitle;
1221 ljUserNode.isOptionalClose = ljUserNode.isEmpty = true;
1227 'lj-cmd': function() {
1230 'contenteditable': function(){
1237 requires: ['fakeobjects', 'domiterator']