Committer: vkurkin
LJSV-1478: Inserting a link in the Rich Text editor in IE9 fails\nLJSUP-9351: Change icons for new RTE\nLJSUP-9251: Update RTE: hint for edit embeds on mouseover\nLJSUP-8974: RTE: Ability to add and display lj-like buttonsU trunk/bin/upgrading/en.dat U trunk/cgi-bin/LJ/Widget/EntryForm.pm U trunk/htdocs/js/ck/config.js U trunk/htdocs/js/ck/plugins/livejournal/plugin.js U trunk/htdocs/js/poll.js
Modified: trunk/bin/upgrading/en.dat =================================================================== --- trunk/bin/upgrading/en.dat 2011-08-01 09:43:26 UTC (rev 19550) +++ trunk/bin/upgrading/en.dat 2011-08-02 01:05:16 UTC (rev 19551) @@ -2697,7 +2697,28 @@ fcklang.ljlike.button.give=10 Give +fcklang.ljlike.wizardnotice=Likes must be edited inside the Like Wizard +fcklang.ljlike.wizardnoticelink=Go to like wizard + +fcklang.ljlike.faq=FAQ + + +fcklang.ljuser.wizardnotice=User must be edited inside the User Wizard + +fcklang.ljuser.wizardnoticelink=Go to user wizard + + +fcklang.ljlink.wizardnotice=Link must be edited inside the Link Wizard + +fcklang.ljlink.wizardnoticelink=Go to link wizard + + +fcklang.ljimage.wizardnotice=Image must be edited inside the Link Wizard + +fcklang.ljimage.wizardnoticelink=Go to Image wizard + + fcklang.videoprompt=Please enter the YouTube, PhotoBucket, or Google Video URL: feeds.link=syndicated feeds Modified: trunk/cgi-bin/LJ/Widget/EntryForm.pm =================================================================== --- trunk/cgi-bin/LJ/Widget/EntryForm.pm 2011-08-01 09:43:26 UTC (rev 19550) +++ trunk/cgi-bin/LJ/Widget/EntryForm.pm 2011-08-02 01:05:16 UTC (rev 19551) @@ -1462,6 +1462,15 @@ 'LJLike_button_vkontakte' => 'ljlike.button.vkontakte', 'LJLike_button_twitter' => 'ljlike.button.twitter', 'LJLike_button_give' => 'ljlike.button.give', + 'LJLike_WizardNotice' => 'ljlike.wizardnotice', + 'LJLike_WizardNoticeLink' => 'ljlike.wizardnoticelink', + 'LJLike_FAQ' => 'ljlike.faq', + 'LJUser_WizardNotice' => 'ljuser.wizardnotice', + 'LJUser_WizardNoticeLink' => 'ljuser.wizardnoticelink', + 'LJLink_WizardNotice' => 'ljlink.wizardnotice', + 'LJLink_WizardNoticeLink' => 'ljlink.wizardnoticelink', + 'LJImage_WizardNotice' => 'ljimage.wizardnotice', + 'LJImage_WizardNoticeLink' => 'ljimage.wizardnoticelink', ); my %langmap_translated = map { $_ => BML::ml("fcklang.$langmap{$_}") } Modified: trunk/htdocs/js/ck/config.js =================================================================== --- trunk/htdocs/js/ck/config.js 2011-08-01 09:43:26 UTC (rev 19550) +++ trunk/htdocs/js/ck/config.js 2011-08-02 01:05:16 UTC (rev 19551) @@ -4,13 +4,6 @@ */ CKEDITOR.editorConfig = function(config){ - - var ljItems = ['LJUserLink','LJImage']; - if(top.Site.media_embed_enabled){ - ljItems.push('LJEmbedLink'); - } - ljItems.push('LJPollLink', 'LJCutLink', 'LJCut', 'LJLike', 'Table'); - config.language = 'ru'; config.autoParagraph = false; config.autoUpdateElement = false; @@ -37,12 +30,12 @@ //'flash,' + 'font,' + 'format,' + - 'forms,' + - 'horizontalrule,' + + //'forms,' + + //'horizontalrule,' + 'htmldataprocessor,' + - 'iframedialog,' + - //'image,' + - 'indent,' + + //'iframedialog,' + + 'image,' + + //'indent,' + 'justify,' + 'keystrokes,' + 'link,' + @@ -50,26 +43,26 @@ 'liststyle,' + //'maximize,' + //'newpage,' + - 'pagebreak,' + - 'pastefromword,' + - 'pastetext,' + + //'pagebreak,' + + //'pastefromword,' + + //'pastetext,' + //'popup,' + //'preview,' + //'print,' + - 'removeformat,' + - 'resize,' + + //'removeformat,' + + //'resize,' + //'save,' + //'smiley,' + //'showblocks,' + - 'showborders,' + - 'sourcearea,' + - 'stylescombo,' + + //'showborders,' + + //'sourcearea,' + + //'stylescombo,' + //'scayt,' + - 'table,' + - 'tabletools,' + + //'table,' + + //'tabletools,' + 'specialchar,' + 'tab,' + - 'templates,' + + //'templates,' + 'toolbar,' + 'undo,' + 'wysiwygarea,'/* + @@ -84,7 +77,7 @@ config.entities_additional = '#39'; config.entities_greek = true; config.entities_latin = true; - config.fillEmptyBlocks = true; + config.fillEmptyBlocks = false; config.emailProtection = 'mt(NAME,DOMAIN,SUBJECT,BODY)'; config.startupFocus = false; config.forcePasteAsPlainText = false; @@ -93,24 +86,45 @@ config.tabSpaces = 2; config.startupShowBorders = false; config.toolbarStartupExpanded = true; - config.toolbarCanCollapse = true; + config.toolbarCanCollapse = false; config.ignoreEmptyParagraph = true; config.baseFloatZIndex = 10000; config.htmlEncodeOutput = false; config.templates_replaceContent = true; config.toolbarLocation = 'top'; config.toolbar_Full = [ - ['Bold','Italic','Underline','Strike','TextColor','FontSize'], - ['Link', 'Unlink'], - ljItems, - ['Outdent','Indent'], - ['UnorderedList','OrderedList','NumberedList','BulletedList'], - ['JustifyLeft','JustifyCenter','JustifyRight'], - ['Undo', 'Redo'] + ['Bold', + 'Italic', + 'Underline', + 'Strike', + 'TextColor', + 'FontSize', + '-', + 'Link', + 'LJUserLink', + 'LJImage'] ]; - config.toolbar_Basic = [ - ['Bold','Italic','-','OrderedList','UnorderedList','-','Link','Unlink','-','About'] - ]; + + if(top.Site.media_embed_enabled){ + config.toolbar_Full[0].push('LJEmbedLink'); + } + config.toolbar_Full[0].push('LJPollLink', + 'LJCutLink', + 'LJCut', + 'LJLike', + '-', + 'UnorderedList', + 'OrderedList', + 'NumberedList', + 'BulletedList', + '-', + 'JustifyLeft', + 'JustifyCenter', + 'JustifyRight', + '-', + 'Undo', + 'Redo'); + config.toolbar = 'Full'; config.enterMode = CKEDITOR.ENTER_BR; config.forceEnterMode = false; @@ -140,9 +154,8 @@ !window.opera && config.keystrokes.push([ CKEDITOR.CTRL + 66 /*B*/, 'Bold' ]); // LIVEJOURNAL SPECIFIC, LJSUP-4442 - config.browserContextMenuOnCtrl = false; + config.browserContextMenuOnCtrl = true; config.colorButton_colors = '000000,993300,333300,003300,003366,000080,333399,333333,800000,FF6600,808000,808080,008080,0000FF,666699,808080,FF0000,FF9900,99CC00,339966,33CCCC,3366FF,800080,999999,FF00FF,FFCC00,FFFF00,00FF00,00FFFF,00CCFF,993366,C0C0C0,FF99CC,FFCC99,FFFF99,CCFFCC,CCFFFF,99CCFF,CC99FF,FFFFFF'; - config.font_names = 'Arial;Comic Sans MS;Courier New;Tahoma;Times New Roman;Verdana'; config.fontSize_sizes = 'smaller;larger;xx-small;x-small;small;medium;large;x-large;xx-large'; config.disableObjectResizing = true; config.disableNativeTableHandles = true; @@ -152,17 +165,17 @@ config.fontSize_defaultLabel = ''; config.removeFormatTags = 'b,big,code,del,dfn,em,font,i,ins,kbd,q,samp,small,span,strike,strong,sub,sup,tt,u,var'; config.removeFormatAttributes = 'class,style,lang,width,height,align,hspace,valign'; - config.stylesSet = [{ - name: 'Red Title', - element : 'h3', - styles : { - color:'red' - } - }]; - config.coreStyles_bold = { element : 'b', overrides : 'strong' }; - config.coreStyles_italic = { element : 'i', overrides : 'em' }; + config.coreStyles_bold = { + element: 'b', + overrides: 'strong' + }; + config.coreStyles_italic = { + element: 'i', + overrides:'em' + }; + config.indentClasses = []; - config.indentOffset = 40; + config.indentOffset = 0; config.indentUnit = 'px'; config.dialog_backgroundCoverColor = '#ffffff'; Modified: trunk/htdocs/js/ck/plugins/livejournal/plugin.js =================================================================== --- trunk/htdocs/js/ck/plugins/livejournal/plugin.js 2011-08-01 09:43:26 UTC (rev 19550) +++ trunk/htdocs/js/ck/plugins/livejournal/plugin.js 2011-08-02 01:05:16 UTC (rev 19551) @@ -5,41 +5,123 @@ label: top.CKLang.LJLike_button_facebook, id: 'facebook', abbr: 'fb', - html: '<div class="lj-like-item lj-like-gag">' + top.CKLang.LJLike_button_facebook + '</div>' + html: '<div class="lj-like-item lj-like-gag fb">' + top.CKLang.LJLike_button_facebook + '</div>', + htmlOpt: '<li class="like-fb"><input type="checkbox" id="like-fb" /><label for="like-fb">' + top.CKLang + .LJLike_button_facebook + '</label></li>' }, { label: top.CKLang.LJLike_button_twitter, id: 'twitter', abbr: 'tw', - html: '<div class="lj-like-item lj-like-gag">' + top.CKLang.LJLike_button_twitter + '</div>' + html: '<div class="lj-like-item lj-like-gag tw">' + top.CKLang.LJLike_button_twitter + '</div>', + htmlOpt: '<li class="like-tw"><input type="checkbox" id="like-tw" /><label for="like-tw">' + top.CKLang + .LJLike_button_twitter + '</label></li>' }, { label: top.CKLang.LJLike_button_google, id: 'google', abbr: 'go', - html: '<div class="lj-like-item lj-like-gag">' + top.CKLang.LJLike_button_google + '</div>' - }, - { + html: '<div class="lj-like-item lj-like-gag go">' + top.CKLang.LJLike_button_google + '</div>', + htmlOpt: '<li class="like-go"><input type="checkbox" id="like-go" /><label for="like-go">' + top.CKLang + .LJLike_button_google + '</label></li>' + } + ]; + + if(window.isSupUser){ + likeButtons.push({ label: top.CKLang.LJLike_button_vkontakte, id: 'vkontakte', abbr: 'vk', - html: '<div class="lj-like-item lj-like-gag">' + top.CKLang.LJLike_button_vkontakte + '</div>' + html: '<div class="lj-like-item lj-like-gag vk">' + top.CKLang.LJLike_button_vkontakte + '</div>', + htmlOpt: '<li class="like-vk"><input type="checkbox" id="like-vk" /><label for="like-vk">' + top.CKLang + .LJLike_button_vkontakte + '</label></li>' + }); + } + + likeButtons.push({ + label: top.CKLang.LJLike_button_give, + id: 'livejournal', + abbr: 'lj', + html: '<div class="lj-like-item lj-like-gag lj">' + top.CKLang.LJLike_button_give + '</div>', + htmlOpt: '<li class="like-lj"><input type="checkbox" id="like-lj" /><label for="like-lj">' + top.CKLang + .LJLike_button_give + '</label></li>' + }); + + var note; + + var ljNoteData = { + LJPollLink: { + html: encodeURIComponent(top.CKLang.Poll_PollWizardNotice + '<br /><a href="#">' + top.CKLang.Poll_PollWizardNoticeLink + '</a>') }, - { - label: top.CKLang.LJLike_button_give, - id: 'livejournal', - abbr: 'lj', - html: '<div class="lj-like-item lj-like-gag">' + top.CKLang.LJLike_button_give + '</div>' + LJLikeCommand: { + html: encodeURIComponent(top.CKLang.LJLike_WizardNotice + '<br /><a href="#">' + top.CKLang.LJLike_WizardNoticeLink + '</a>') + }, + LJUserLink: { + html: encodeURIComponent(top.CKLang.LJUser_WizardNotice + '<br /><a href="#">' + top.CKLang.LJUser_WizardNoticeLink + '</a>') + }, + LJLink: { + html: encodeURIComponent(top.CKLang.LJLink_WizardNotice + '<br /><a href="#">' + top.CKLang.LJLink_WizardNoticeLink + '</a>') + }, + LJImage: { + html: encodeURIComponent(top.CKLang.LJImage_WizardNotice + '<br /><a href="#">' + top.CKLang.LJImage_WizardNoticeLink + '</a>') } - ]; + }; var ljUsers = {}; + var currentNoteNode; CKEDITOR.plugins.add('livejournal', { init: function(editor){ + function onFindCmd(evt){ + var cmd; + + if(evt.name == 'mouseout'){ + note.hide(); + return; + } + + var isMouseOver = evt.name == 'mouseover'; + var node = isMouseOver ? evt.data.getTarget() : editor.getSelection().getStartElement(); + var isNote; + var actNode; + + while(node){ + + if(!attr){ + if(node.is('img')){ + node.setAttribute('lj-cmd', 'LJImage'); + } else if(node.is('a')){ + node.setAttribute('lj-cmd', 'LJLink'); + } + } + + var attr = node.getAttribute('lj-cmd'); + + if(isMouseOver && node.getName() == 'lj-note'){ + isNote = true; + } + + if(attr && !isNote){ + cmd = attr; + actNode = node; + } + node = node.getParent(); + } + + if(!isNote){ + if(!isNote && cmd && ljNoteData.hasOwnProperty(cmd)){ + if(!isMouseOver){ + ljNoteData[cmd].node = actNode; + } + note.show(ljNoteData[cmd].html, cmd, actNode); + } else { + note.hide(); + } + } + } + editor.dataProcessor.toHtml = function(html, fixForBody){ - html = html - .replace(/<((?!br)[^\s>]+)([^\/>]+)?\/>/gi, '<$1$2></$1>') + html = html.replace(/<((?!br)[^\s>]+)([^\/>]+)?\/>/gi, '<$1$2></$1>') .replace(/<lj-template name=['"]video['"]>(\S+?)<\/lj-template>/g, '<div class="ljvideo" url="$1"><img src="' + Site .statprefix + '/fck/editor/plugins/livejournal/ljvideo.gif" /></div>') .replace(/<lj-embed\s*(?:id="(\d*)")?\s*>([\s\S]*?)<\/lj-embed>/gi, '<div class="ljembed" embedid="$1">$2</div>') @@ -112,8 +194,6 @@ html = html.replace(/\t/g, ' '); html = html.replace(/>\n\s*(?!\s)([^<]+)</g, '>$1<'); - // rte fix, http://dev.fckeditor.net/ticket/3023 - // type="_moz" for Safari 4.0.11 if(!CKEDITOR.env.ie){ html = html.replace(/<br (type="_moz" )? ?\/>$/, ''); if(CKEDITOR.env.webkit){ @@ -121,9 +201,10 @@ } } - html = html.replace(/<form.*?class="ljpoll" data="([^"]*)"[\s\S]*?<\/form>/gi, function(form, data){ - return unescape(data); - }).replace(/<\/lj>/g, ''); + html = html.replace(/<form.*?class="ljpoll" data="([^"]*)"[\s\S]*?<\/form>/gi, + function(form, data){ + return unescape(data); + }).replace(/<\/lj>/g, ''); html = html .replace(/<div(?=[^>]*class="ljvideo")[^>]*url="(\S+)"[^>]*><img.+?\/><\/div>/g, '<lj-template name="video">$1</lj-template>') @@ -149,39 +230,203 @@ return html; }; + editor.on('dataReady', function(){ + + editor.document.on('mouseover', onFindCmd); + editor.document.on('mouseout', onFindCmd); + editor.document.on('keyup', onFindCmd); + editor.document.on('click', onFindCmd); + + if(!note){ + var timer, + state, + currentData = {}, + tempData = {}, + noteNode = document.createElement('lj-note'), + isIE = typeof(document.body.style.opacity) != 'string'; + + var animate = (function(){ + var + fps = 60, + totalTime = 100, + steps = totalTime * fps / 1000, + timeOuts = [], + type; + + function apply(){ + var data = timeOuts.shift(); + var currentStep = (type ? data.time / totalTime : -(data.time / totalTime - 1)).toFixed(1); + + if(!timeOuts.length){ + currentStep = type ? 1 : 0; + } + + if(isIE){ + noteNode.style.filter = (currentStep >= 1) ? null : 'progid:DXImageTransform.Microsoft.Alpha(opacity=' + (currentStep * 100) + ')'; + } else { + noteNode.style.opacity = currentStep; + } + + if(currentStep == 0 && noteNode && noteNode.parentNode){ + noteNode.parentNode.removeChild(noteNode); + } + } + + return function(animateType){ + type = animateType; + + if(type && noteNode.parentNode){ + if(isIE){ + noteNode.style.filter = null; + } else { + noteNode.style.opacity = 1; + } + } else { + for(var i = 1; i <= steps; i++){ + var time = Math.floor(1000 / fps) * i; + timeOuts.push({ + time: time, + timer: setTimeout(apply, time) + }); + } + } + + document.body.appendChild(noteNode); + noteNode.style.marginTop = -noteNode.offsetHeight / 2 + 'px'; + noteNode.style.marginLeft = -noteNode.offsetWidth / 2 + 'px'; + } + })(); + + noteNode.className = 'note'; + noteNode.style.backgroundColor = '#ccc'; + noteNode.style.border = '#f000 1px solid'; + noteNode.style.position = 'absolute'; + noteNode.style.left = '50%'; + noteNode.style.top = '50%'; + + noteNode.onmouseout = function(){ + if(!currentData.cmd) { + note.hide(); + } + }; + + noteNode.onmouseover = function(){ + if(timer && !state){ + state = 1; + clearTimeout(timer); + timer = null; + } + }; + + if(isIE){ + noteNode.style.filter = 'progid:DXImageTransform.Microsoft.Alpha(opacity=0)'; + } else { + noteNode.style.opacity = 0; + } + + function callCmd(){ + if(currentData.cmd){ + currentNoteNode = ljNoteData[currentData.cmd].node = currentData.node; + editor.getCommand(currentData.cmd).exec(); + } + return false; + } + + function applyNote(){ + if(state){ + currentData.cmd = tempData.cmd; + currentData.data = tempData.data; + currentData.node = tempData.node; + + delete tempData.node; + delete tempData.cmd; + delete tempData.data; + + noteNode.innerHTML = decodeURIComponent(currentData.data); + + var link = noteNode.getElementsByTagName('a')[0]; + if(link && currentData.cmd){ + link.onclick = callCmd; + } + } else { + delete currentData.node; + delete currentData.cmd; + delete currentData.data; + + currentNoteNode = null; + } + + animate(state); + + timer = null; + } + + note = { + show: function(data, cmd, node){ + if(data == tempData.data && cmd == tempData.cmd && node === tempData.node){ + return; + } + + if(timer){ + clearTimeout(timer); + timer = null; + } + + state = 1; + timer = setTimeout(applyNote, 1000); + + tempData.data = data; + tempData.cmd = cmd; + tempData.node = node; + }, + hide: function(isNow){ + if(state){ + state = 0; + + if(timer){ + clearTimeout(timer); + timer = null; + } + + if(noteNode.parentNode){ + isNow === true ? applyNote() : timer = setTimeout(applyNote, 500); + } + } + } + }; + } + + }); + ////////// LJ User Button ////////////// - var url = top.Site.siteroot + '/tools/endpoints/ljuser.bml', - LJUserNode; + var url = top.Site.siteroot + '/tools/endpoints/ljuser.bml'; editor.attachStyleStateChange(new CKEDITOR.style({ element: 'span' }), function(){ var selectNode = editor.getSelection().getStartElement().getAscendant('span', true); var isUserLink = selectNode && selectNode.hasClass('ljuser'); - LJUserNode = isUserLink ? selectNode : null; + ljNoteData.LJUserLink.node = isUserLink ? selectNode : null; editor.getCommand('LJUserLink').setState(isUserLink ? CKEDITOR.TRISTATE_ON : CKEDITOR.TRISTATE_OFF); }); editor.on('doubleclick', function(evt){ var command = editor.getCommand('LJUserLink'); - LJUserNode = evt.data.element.getAscendant('span', true); - if(LJUserNode && LJUserNode.hasClass('ljuser')){ - command.setState(CKEDITOR.TRISTATE_ON); + if(command.state == CKEDITOR.TRISTATE_ON){ command.exec(); - evt.data.dialog = ''; - } else { - command.setState(CKEDITOR.TRISTATE_OFF); } + + evt.data.dialog = ''; }); editor.addCommand('LJUserLink', { exec : function(editor){ var userName = '', selection = editor.getSelection(), - LJUser = LJUserNode; + LJUser = ljNoteData.LJUserLink.node; - if(this.state == CKEDITOR.TRISTATE_ON && LJUserNode){ - userName = prompt(top.CKLang.UserPrompt, LJUserNode.getElementsByTag('b').getItem(0).getText()); + if(ljNoteData.LJUserLink.node){ + userName = prompt(top.CKLang.UserPrompt, ljNoteData.LJUserLink.node.getElementsByTag('b').getItem(0).getText()); } else if(selection.getType() == 2){ userName = selection.getSelectedText(); } @@ -210,12 +455,17 @@ } data.ljuser = data.ljuser.replace('<span class="useralias-value">*</span>', ''); + ljUsers[userName] = data.ljuser; + + var tmpNode = editor.document.createElement('div'); + tmpNode.setHtml(data.ljuser); + ljNoteData.LJUserLink.node = tmpNode.getFirst(); + ljNoteData.LJUserLink.node.setAttribute('lj-cmd', 'LJUserLink'); + if(LJUser){ - LJUser.setHtml(data.ljuser); - LJUser.insertBeforeMe(LJUser.getFirst()); - LJUser.remove(); + LJUser.$.parentNode.replaceChild(ljNoteData.LJUserLink.node.$, LJUser.$); } else { - editor.insertHtml(data.ljuser); + editor.insertElement(ljNoteData.LJUserLink.node); } } }); @@ -233,16 +483,70 @@ if(ljphotoEnabled){ // call LJImage } else { + if(ljNoteData.LJImage.node){ + editor.getSelection().selectElement(ljNoteData.LJImage.node); + } editor.getCommand('image').exec(); } } }); + editor.attachStyleStateChange(new CKEDITOR.style({ + element: 'img' + }), function(state){ + if(state == CKEDITOR.TRISTATE_OFF && !currentNoteNode){ + delete ljNoteData.LJImage.node; + } + editor.getCommand('LJImage').setState(state); + }); + + editor.on('doubleclick', function(evt){ + var command = editor.getCommand('LJImage'); + if(command.state == CKEDITOR.TRISTATE_ON){ + command.exec(); + } + + evt.data.dialog = ''; + }); + editor.ui.addButton('LJImage', { label: editor.lang.common.imageButton, command: 'LJImage' }); + ////////// LJ Link Button ////////////// + editor.addCommand('LJLink', { + exec : function(editor){ + if(ljNoteData.LJLink.node){ + editor.getSelection().selectElement(ljNoteData.LJLink.node); + } + editor.getCommand('link').exec(); + } + }); + + editor.attachStyleStateChange(new CKEDITOR.style({ + element: 'a' + }), function(state){ + if(state == CKEDITOR.TRISTATE_OFF && !currentNoteNode){ + delete ljNoteData.LJLink.node; + } + editor.getCommand('LJLink').setState(state); + }); + + editor.on('doubleclick', function(evt){ + var command = editor.getCommand('LJLink'); + if(command.state == CKEDITOR.TRISTATE_ON){ + command.exec(); + } + + evt.data.dialog = ''; + }); + + editor.ui.addButton('LJLink', { + label: editor.lang.link.tollbar, + command: 'LJLink' + }); + ////////// LJ Embed Media Button ////////////// editor.addCommand('LJEmbedLink', { exec: function(){ @@ -274,23 +578,14 @@ editor.attachStyleStateChange(new CKEDITOR.style({ element: 'lj-cut' }), function(state){ - var command = editor.getCommand('LJCut'); - command.setState(state); - if(state == CKEDITOR.TRISTATE_ON){ - ljCutNode = this.getSelection().getStartElement().getAscendant('lj-cut', true); - } else { - ljCutNode = null; - } + ljCutNode = state == CKEDITOR.TRISTATE_ON && this.getSelection().getStartElement().getAscendant('lj-cut', true); + editor.getCommand('LJCut').setState(state); }); editor.on('doubleclick', function(evt){ var command = editor.getCommand('LJCut'); - ljCutNode = evt.data.element.getAscendant('lj-cut', true); - if(ljCutNode){ - command.setState(CKEDITOR.TRISTATE_ON); + if(command.state == CKEDITOR.TRISTATE_ON){ command.exec(); - } else { - command.setState(CKEDITOR.TRISTATE_OFF); } }); @@ -327,10 +622,7 @@ ////////// LJ Poll Button ////////////// if(top.canmakepoll){ - var currentPollForm, currentPoll; - var noticeHtml = top.CKLang - .Poll_PollWizardNotice + '<br /><a href="#" onclick="CKEDITOR.instances.draft.getCommand(\'LJPollLink\').exec(); return false;">' + window - .parent.CKLang.Poll_PollWizardNoticeLink + '</a>'; + var currentPoll; editor.attachStyleStateChange(new CKEDITOR.style({ element: 'form', @@ -338,24 +630,17 @@ 'class': 'ljpoll' } }), function(state){ - var command = editor.getCommand('LJPollLink'); - command.setState(state); - currentPollForm = this.getSelection().getStartElement().getAscendant('form', true); - currentPollForm = currentPollForm && currentPollForm.hasClass('ljpoll') ? currentPollForm : null; - if(state == CKEDITOR.TRISTATE_ON){ - parent.LJ_IPPU.showNote(noticeHtml, editor.container.$).centerOnWidget(editor.container.$); + if(state == CKEDITOR.TRISTATE_OFF && !currentNoteNode){ + delete ljNoteData.LJPollLink.node; } + editor.getCommand('LJPollLink').setState(state); }); editor.on('doubleclick', function(evt){ var command = editor.getCommand('LJPollLink'); - currentPollForm = evt.data.element.getAscendant('form', true); - if(currentPollForm && currentPollForm.hasClass('ljpoll')){ - command.setState(CKEDITOR.TRISTATE_ON); + if(command.state == CKEDITOR.TRISTATE_ON){ command.exec(); evt.data.dialog = ''; - } else { - command.setState(CKEDITOR.TRISTATE_OFF); } }); @@ -367,7 +652,7 @@ this.removeListener('load', onLoadPollPage); } if(isAllFrameLoad && okButtonNode){ - currentPoll = new Poll(currentPollForm && unescape(currentPollForm.getAttribute('data')), questionsWindow + currentPoll = new Poll(ljNoteData.LJPollLink.node && unescape(ljNoteData.LJPollLink.node.getAttribute('data')), questionsWindow .document, setupWindow.document, questionsWindow.Questions); questionsWindow.ready(currentPoll); @@ -385,7 +670,7 @@ height : 270, onShow: function(){ if(isAllFrameLoad){ - currentPoll = new Poll(currentPollForm && unescape(currentPollForm + currentPoll = new Poll(ljNoteData.LJPollLink.node && unescape(ljNoteData.LJPollLink.node .getAttribute('data')), questionsWindow.document, setupWindow.document, questionsWindow.Questions); questionsWindow.ready(currentPoll); @@ -446,16 +731,17 @@ evt.data.dialog.hide(); var pollSource = new Poll(currentPoll, questionsWindow.document, setupWindow.document, questionsWindow .Questions).outputHTML(); + if(pollSource.length > 0){ - if(currentPollForm){ - var node = document.createElement('div'); - node.innerHTML = pollSource; - currentPollForm.$.parentNode.insertBefore(node.firstChild, currentPollForm.$); - currentPollForm.remove(); + if(ljNoteData.LJPollLink.node){ + var node = editor.document.createElement('div'); + node.setHtml(pollSource); + ljNoteData.LJPollLink.node.insertBeforeMe(node); + ljNoteData.LJPollLink.node.remove(); } else { editor.insertHtml(pollSource); } - currentPollForm = null; + ljNoteData.LJPollLink.node = null; } } }), CKEDITOR.dialog.cancelButton] @@ -465,9 +751,8 @@ editor.addCommand('LJPollLink', new CKEDITOR.dialogCommand('LJPollDialog')); } else { editor.addCommand('LJPollLink', { - exec: function(editor){ - var notice = top.LJ_IPPU.showNote(top.CKLang.Poll_AccountLevelNotice, editor.container.$); - notice.centerOnWidget(editor.container.$); + exec: function(){ + note.show(top.CKLang.Poll_AccountLevelNotice); } }); @@ -481,37 +766,23 @@ ////////// LJ Like Button ////////////// var buttonsLength = likeButtons.length; - var dialogContents = []; - var currentLjLikeNode, currentLjLikeButton; + var dialogContent = '<ul class="likes">'; likeButtons.defaultButtons = []; for(var i = 0; i < buttonsLength; i++){ var button = likeButtons[i]; likeButtons[button.id] = likeButtons[button.abbr] = button; likeButtons.defaultButtons.push(button.id); - dialogContents.push({ - type: 'checkbox', - label: button.label, - id: 'LJLike_' + button.id - }); + dialogContent += button.htmlOpt; } - dialogContents.unshift({ - type: 'html', - html: top.CKLang.LJLike_dialogText - }); + dialogContent += '</ul><a href="/support/faqbrowse.bml?faqid=344" class="helplink" target="_blank"><img src="/img/help.gif" alt="Help" title="Help" width="14" height="14" border="0"> ' + top.CKLang.LJLike_FAQ + '</a>'; - var countChanges = 0, ljLikeDialog; + var countChanges = 0, ljLikeDialog, ljLikeInputs; function onChangeLike(){ - if('isChanged' in this){ - ljLikeDialog = ljLikeDialog || this.getDialog(); - countChanges += this.isChanged() ? 1 : -1; - } else { - countChanges += this.$.checked ? 1 : -1; - } - var command = editor.getCommand('LJLikeCommand'); if(command.state == CKEDITOR.TRISTATE_OFF){ + this.$.checked ? countChanges++ : countChanges--; ljLikeDialog.getButton('LJLike_Ok').getElement()[countChanges == 0 ? 'hide' : 'show'](); } } @@ -519,63 +790,64 @@ CKEDITOR.dialog.add('LJLikeDialog', function(){ return { title : top.CKLang.LJLike_name, - width : 200, - height : 150, + width : 130, + height : 180, resizable: false, contents : [ { id: 'LJLike_Options', - elements: dialogContents + elements: [{ + type: 'html', + html: dialogContent + }] } ], buttons : [new CKEDITOR.ui.button({ type : 'button', id : 'LJLike_Ok', label : editor.lang.common.ok, - onClick : function(evt){ - var dialog = evt.data.dialog, attr = []; - var likeNode = currentLjLikeNode || new CKEDITOR.dom.element('div'); - likeNode.remove(); - likeNode.setHtml(''); + onClick : function(){ + var attr = [], likeHtml = ''; + ljNoteData.LJLikeCommand.node && ljNoteData.LJLikeCommand.node.remove(); + for(var i = 0; i < buttonsLength; i++){ var button = likeButtons[i]; - var buttonNode = dialog.getContentElement('LJLike_Options', 'LJLike_' + button.id); - if(buttonNode.getValue('checked')){ + if(ljLikeInputs.$[i].checked){ attr.push(button.id); - likeNode.appendHtml(button.html); - likeNode.getLast().addClass(button.abbr); + likeHtml += button.html; } } if(attr.length){ - likeNode.setAttribute('buttons', attr.join(',')); - likeNode.setAttribute('class', 'lj-like'); - editor.insertElement(likeNode); + editor.insertHtml('<div class="lj-like" lj-cmd="LJLikeCommand" buttons="' + attr.join(',') + '">' + likeHtml + '</div>'); // IE7 fix } - dialog.hide(); + + ljLikeDialog.hide(); } }), CKEDITOR.dialog.cancelButton], onShow: function(){ var command = editor.getCommand('LJLikeCommand'); - var i = countChanges = 0; - if(command.state == CKEDITOR.TRISTATE_ON){ - var buttons = currentLjLikeNode.getAttribute('buttons').split(','); - for(var l = buttons.length; i < l; i++){ - this.getContentElement('LJLike_Options', 'LJLike_' + likeButtons[buttons[i]].id) - .setValue('checked', false); + var i = countChanges = 0, + isOn = command.state == CKEDITOR.TRISTATE_ON, + buttons = ljNoteData.LJLikeCommand.node && ljNoteData.LJLikeCommand.node.getAttribute('buttons'); + + for(; i < buttonsLength; i++){ + var isChecked = buttons ? !!(buttons.indexOf(likeButtons[i].abbr) + 1 || buttons.indexOf(likeButtons[i] + .id) + 1) : true; + + if(isChecked && !isOn){ + countChanges++; } - } else { - for(; i < buttonsLength; i++){ - this.getContentElement('LJLike_Options', 'LJLike_' + likeButtons[i].id).setValue('checked', false); - } + + ljLikeInputs.$[i].checked = isChecked; } }, onLoad: function(){ + ljLikeDialog = this; + ljLikeInputs = ljLikeDialog.parts.contents.getElementsByTag('input'); for(var i = 0; i < buttonsLength; i++){ - var uiElement = this.getContentElement('LJLike_Options', 'LJLike_' + likeButtons[i].id); - uiElement.on('change', onChangeLike); - uiElement.getInputElement().on('change', onChangeLike); + ljLikeInputs.getItem(i).on('change', onChangeLike); } } } @@ -584,22 +856,21 @@ editor.attachStyleStateChange(new CKEDITOR.style({ element: 'div' }), function(){ - currentLjLikeNode = this.getSelection().getStartElement(); - if(currentLjLikeButton){ - currentLjLikeButton.setStyle('border-color', '#999999'); - currentLjLikeButton = null; - } - while(currentLjLikeNode){ - if(currentLjLikeNode.hasClass('lj-like-item')){ - currentLjLikeButton = currentLjLikeNode; - currentLjLikeButton.setStyle('border-color', '#ff0000'); - } else if(currentLjLikeNode.hasClass('lj-like')){ + var ljLikeNode = this.getSelection().getStartElement(); + + while(ljLikeNode){ + if(ljLikeNode.hasClass('lj-like')){ + ljNoteData.LJLikeCommand.node = ljLikeNode; break; } - currentLjLikeNode = currentLjLikeNode.getParent(); + ljLikeNode = ljLikeNode.getParent(); } - editor.getCommand('LJLikeCommand').setState(currentLjLikeNode ? CKEDITOR.TRISTATE_ON : CKEDITOR.TRISTATE_OFF); + if(!ljLikeNode && !currentNoteNode){ + delete ljNoteData.LJLikeCommand.node; + } + + editor.getCommand('LJLikeCommand').setState(ljLikeNode ? CKEDITOR.TRISTATE_ON : CKEDITOR.TRISTATE_OFF); }); editor.on('doubleclick', function(){ @@ -609,81 +880,8 @@ } }); - /*editor.on('dataReady', function(){ - editor.document.on('keypress', function(evt){ - var key = evt.data.getKey(); - if(editor.getCommand('LJLikeCommand').state == CKEDITOR.TRISTATE_ON){ - if(key == 46 || key == 8){ - if(currentLjLikeButton){ - editor.getCommand('LJLike_remove').exec(); - } - - if(!currentLjLikeNode.getChildCount()){ - editor.getCommand('LJLike_removeAll').exec(); - } - - console.log(editor.getSelection().getRanges()); - evt.data.preventDefault(); - } - } - }); - });*/ - editor.addCommand('LJLikeCommand', new CKEDITOR.dialogCommand('LJLikeDialog')); - editor.addCommand('LJLike_remove', { - exec : function(){ - var newButtons = currentLjLikeNode.getAttribute('buttons').split(','); - newButtons.splice(currentLjLikeButton.getIndex(), 1); - currentLjLikeNode.setAttribute('buttons', newButtons.join(',')); - currentLjLikeButton.remove(); - } - }); - - editor.addCommand('LJLike_removeAll', { - exec : function(){ - currentLjLikeNode.remove(); - } - }); - - editor.addMenuGroup('LJLike', 5); - - editor.addMenuItems({ - LJLike_remove: { - label : 'Delete button', - command : 'LJLike_remove', - group : 'LJLike', - order : 5 - }, - LJLike_removeAll: { - label : 'Delete all buttons', - command : 'LJLike_removeAll', - group : 'LJLike', - order : 5 - } - }); - - var execCommandDefinition = { - LJLike_remove : CKEDITOR.TRISTATE_ON, - LJLike_removeAll : CKEDITOR.TRISTATE_ON - }; - - editor.contextMenu.addListener(function(element){ - if(!element || element.isReadOnly()){ - return null; - } - - var elementPath = new CKEDITOR.dom.elementPath(element); - currentLjLikeButton = elementPath.block; - - if(currentLjLikeButton && currentLjLikeButton.hasClass('lj-like-item')){ - return execCommandDefinition; - } - - - return null; - }); - editor.ui.addButton('LJLike', { label: top.CKLang.LJLike_name, command: 'LJLikeCommand' @@ -730,6 +928,7 @@ var fakeElement = new CKEDITOR.htmlParser.element('div'); fakeElement.attributes['class'] = 'lj-like'; + fakeElement.attributes['lj-cmd'] = 'LJLikeCommand'; var currentButtons = element.attributes.buttons && element.attributes.buttons.split(',') || likeButtons .defaultButtons; @@ -740,7 +939,6 @@ var button = likeButtons[buttonName]; if(button){ var buttonNode = new CKEDITOR.htmlParser.fragment.fromHtml(button.html).children[0]; - buttonNode.attributes['class'] += (' ' + button.abbr); fakeElement.add(buttonNode); attr.push(buttonName); } @@ -759,7 +957,10 @@ var cacheName = ljUserTitle ? ljUserName + ':' + ljUserTitle : ljUserName; if(ljUsers.hasOwnProperty(cacheName)){ - return (new CKEDITOR.htmlParser.fragment.fromHtml(ljUsers[cacheName])).children[0]; + var ljTag = (new CKEDITOR.htmlParser.fragment.fromHtml(ljUsers[cacheName])).children[0]; + + ljTag.attributes['lj-cmd'] = 'LJUserLink'; + return ljTag; } else { var onSuccess = function(data){ ljUsers[cacheName] = data.ljuser; @@ -782,7 +983,9 @@ var userTitle = ljTag.getAttribute('title'); if(cacheName == userTitle ? userName + ':' + userTitle : userName){ ljTag.setHtml(ljUsers[cacheName]); - ljTag.insertBeforeMe(ljTag.getFirst()); + var newLjTag = ljTag.getFirst(); + newLjTag.setAttribute('lj-cmd', 'LJUserLink'); + ljTag.insertBeforeMe(newLjTag); ljTag.remove(); } } @@ -808,6 +1011,12 @@ onData: onSuccess }); } + }, + a: function(element){ + element.attributes['lj-cmd'] = 'LJLink'; + }, + img: function(element){ + element.attributes['lj-cmd'] = 'LJImage'; } } }, 5); @@ -817,18 +1026,7 @@ 'div': function(element){ if(element.attributes['class'] == 'lj-like'){ var ljLikeNode = new CKEDITOR.htmlParser.element('lj-like'); - - var childs = element.children, attr = []; - for(var i = 0; i < childs.length; i++){ - var abbr = /.*?([a-z]{2})$/.exec(childs[i].attributes['class'])[1]; - if(abbr && likeButtons.hasOwnProperty(abbr)){ - attr.push(abbr); - } - } - - if(attr.length){ - ljLikeNode.attributes.buttons = attr.join(','); - } + ljLikeNode.attributes.buttons = element.attributes.buttons; ljLikeNode.isEmpty = true; ljLikeNode.isOptionalClose = true; return ljLikeNode; @@ -845,14 +1043,20 @@ ljUserNode.attributes.title = userTitle; } - ljUserNode.isEmpty = true; - ljUserNode.isOptionalClose = true; + ljUserNode.isOptionalClose = ljUserNode.isEmpty = true; return ljUserNode; } + }, + 'lj-note': function(){ + return false; } + }, + attributes: { + 'lj-cmd': function(){ + return false; + } } }); - }, requires : [ 'fakeobjects' ] Modified: trunk/htdocs/js/poll.js =================================================================== --- trunk/htdocs/js/poll.js 2011-08-01 09:43:26 UTC (rev 19550) +++ trunk/htdocs/js/poll.js 2011-08-02 01:05:16 UTC (rev 19551) @@ -74,7 +74,7 @@ // Poll method to generate HTML for RTE Poll.prototype.outputHTML = function(){ - var html = '<form action="#" class="ljpoll" data="' + escape(this.outputLJtags()) + '"><b>Poll #xxxx</b>'; + var html = '<form action="#" lj-cmd="LJPollLink" class="ljpoll" data="' + escape(this.outputLJtags()) + '"><b>Poll #xxxx</b>'; if(this.name){ html += ' <i>' + this.name + '</i>';