'); } else { document.execCommand('formatBlock', false, '<' + formatTag + '>'); } RE.contentChanged({}); } RE.setJustifyLeft = function() { document.execCommand('justifyLeft', false, null); RE.contentChanged({}); } RE.setJustifyCenter = function() { document.execCommand('justifyCenter', false, null); RE.contentChanged({}); } RE.setJustifyRight = function() { document.execCommand('justifyRight', false, null); RE.contentChanged({}); } RE.setBlockquote = function(check) { if (!RE.isFocus()) { RE.focus(); } var needCheck = false; if (typeof(check) == 'undefined' || check) { needCheck = true; } // h2、block、list 不可以共存,设置其中一个都需要取消另外两个 var formatBlock = document.queryCommandValue('formatBlock'); if (RE.isCommandEnabled('insertUnorderedList') && needCheck) { RE.setUnorderedList(false); } if (formatBlock == 'h2' && needCheck) { RE.setHeading('h2',false); } var selection = window.getSelection(); var range = selection.getRangeAt(0).cloneRange(); var parentElement = range.commonAncestorContainer; var formatBlock = document.queryCommandValue('formatBlock'); if (formatBlock == 'blockquote') { document.execCommand('formatBlock', false, '
')
} else {
var inQuoteBlock = RE.isInTag(parentElement, 'blockquote');
if (inQuoteBlock.is) {
var blockquoteNode = inQuoteBlock.tagNode
var len = blockquoteNode.childNodes.length;
var preNode = blockquoteNode;
//生成一个新的不带blockquote标签的node
for (var i = 0; i < len; i++) {
tempDom = blockquoteNode.childNodes[i]
var nodeName = tempDom.nodeName.toLowerCase()
if (nodeName == '#text' || nodeName == 'br') {
var text = ''
if (nodeName == '#text') {
text = tempDom.textContent
}
if (text == '') {
text = '
'
}
tempDom = document.createElement('p')
tempDom.innerHTML = text
} else {
if (tempDom.innerText == '') {
tempDom = document.createElement('p')
tempDom.innerHTML = '
'
} else {
tempDom = tempDom.cloneNode(true)
}
}
RE.insertAfter(tempDom,preNode)
preNode = tempDom;
}
blockquoteNode.parentNode.removeChild(blockquoteNode)
//document.execCommand('formatBlock', false, '
') } else { document.execCommand('formatBlock', false, '
') } } RE.contentChanged({}); } // 生成空段落 RE.generateEmptyPara = function(){ var emptyPara = document.createElement('p'); emptyPara.innerHTML = '
'; return emptyPara; } // 插入书籍 RE.insertBook = function(id, title, author, cover) { function generateSpaceNode(){ var n = document.createTextNode('\u200D'); return n; } function generateLineBreakNode(){ var n = document.createElement('br'); return n; } // 下面两个找前后节点的方法之所以这样实现是因为 // ios里当光标在一个文字node上移动时会把它切割,例如 // 一个文字node:ABCDE,当光标从E后面往左移,会把它分割成 // ABCD,E // ABC,D,E // AB,C,D,E // A,B,C,D,E // 这样如果我在ABCDE前面插入img,img的nextSibling有可能只拿到A而拿不到整个文字node,不符合预期 function findBookNextSibling(bookItem){ var tempDom = document.createElement('div'); tempDom.innerHTML = bookItem.parentNode.innerHTML; var target = tempDom.querySelector('.re_bookItem').nextSibling; return target; } function findBookPrevSibling(bookItem){ var tempDom = document.createElement('div'); tempDom.innerHTML = bookItem.parentNode.innerHTML; var target = tempDom.querySelector('.re_bookItem').previousSibling; return target; } function resetBookItemParentNodeHtml(bookItem){ var pnode = bookItem.parentNode, tempDom = document.createElement('div'); tempDom.innerHTML = pnode.innerHTML; pnode.innerHTML = tempDom.innerHTML; } var bookItem = document.createElement('div'); bookItem.className = 're_bookItem'; bookItem.setAttribute('contenteditable', false); bookItem.setAttribute('data-id', id); // 点击相关的事件在rich_display.js里根据data-id处理 bookItem.innerHTML = '' + '' + title + '' + ''; // hack for timing setTimeout(function(){ var selection = window.getSelection(), range; if (window.getSelection().rangeCount > 0) { range = selection.getRangeAt(0); } else { range = document.createRange(); if(RE.currentSelection.startContainer == 0 || RE.currentSelection.endContainer == 0){ range.setStart(RE.editor, RE.currentSelection.startOffset); range.setEnd(RE.editor, RE.currentSelection.endOffset); }else{ range.setStart(RE.currentSelection.startContainer, RE.currentSelection.startOffset); range.setEnd(RE.currentSelection.endContainer, RE.currentSelection.endOffset); } } var rangeNode = range.endContainer; // 光标所在的node if (RE.isInTag(rangeNode, ['h1' ,'h2' ,'ul' ,'blockquote'])){ // 列表和引用内不插书籍,把书籍看成一个独立的段落处理 var inTagNode = RE.isInTag(rangeNode, ['h1' ,'h2' ,'ul' ,'blockquote']).tagNode; if (inTagNode.textContent.length == 0) { // 如果当前block没有文本,则把block删掉 inTagNode.parentNode.insertBefore(bookItem, inTagNode); if (bookItem.previousSibling.getAttribute('contenteditable') == 'false') { bookItem.parentNode.insertBefore(generateSpaceNode(), bookItem); } inTagNode.remove(); } else { RE.insertAfter(bookItem, inTagNode); } if (bookItem.nextSibling) { range.selectNodeContents(bookItem.nextSibling); range.collapse(); } else { var newEmptyLine = RE.generateEmptyPara(); RE.insertAfter(newEmptyLine, bookItem); range.selectNodeContents(newEmptyLine); range.collapse(false); } }else{ // 在第一行或者在一个p里,这里把图片和图片前后的node包个p range.collapse(false); range.insertNode(bookItem); var flagId = bookItem.getAttribute('data-id'), bookItemParentNode = bookItem.parentNode; resetBookItemParentNodeHtml(bookItem); var theBookItem = bookItemParentNode.querySelector('[data-id="'+flagId+'"]'), theBookItemPreviousSibling = null || theBookItem.previousSibling, theBookItemNextSibling = null || theBookItem.nextSibling; if(bookItemParentNode == RE.editor){ // 这是在第一行没被p包住的情况 // 图片前面包一个p if(theBookItemPreviousSibling){ if((theBookItemPreviousSibling.nodeType == 3 ) || (theBookItemPreviousSibling.nodeType == 1 && theBookItemPreviousSibling.tagName.toLowerCase() == "br")){ var newPreviousPara = document.createElement('p'); range.selectNodeContents(theBookItemPreviousSibling); range.surroundContents(newPreviousPara); } }else{ theBookItem.parentNode.insertBefore(generateSpaceNode(), theBookItem); } // 图片后面包一个p if(theBookItemNextSibling){ if((theBookItemNextSibling.nodeType == 3 ) || (theBookItemNextSibling.nodeType == 1 && theBookItemNextSibling.tagName.toLowerCase() == "br")){ var newNextPara = document.createElement('p'); range.selectNodeContents(theBookItemNextSibling); range.surroundContents(newNextPara); range.selectNodeContents(newNextPara); }else{ range.selectNodeContents(theBookItemNextSibling); range.collapse(); } }else{ var newEmptyLine = RE.generateEmptyPara(); RE.insertAfter(newEmptyLine, theBookItem); range.selectNodeContents(newEmptyLine); range.collapse(false); } }else{ // 这是在一个段落里面的 // 先把图片挪到parent外面 RE.insertAfter(theBookItem, bookItemParentNode); // 如果原来有nextSibling,则把图片原来的nextSibling包一个p并插到图片后面 if(theBookItemNextSibling && !(theBookItemNextSibling.nodeType == 1 && theBookItemNextSibling.tagName.toLowerCase() == "br")){ var newNextPara; if((theBookItemNextSibling.nodeType == 3 ) || (theBookItemNextSibling.nodeType == 1 && theBookItemNextSibling.tagName.toLowerCase() == "br")){ newNextPara = document.createElement('p'); range.selectNodeContents(theBookItemNextSibling); range.surroundContents(newNextPara); }else{ newNextPara = theBookItemNextSibling; } RE.insertAfter(newNextPara, theBookItem); } if((bookItemParentNode.childNodes.length == 0) || (bookItemParentNode.innerHTML == '
') || (bookItemParentNode.innerText == '')){ // 书和next移除出来后parent空了,移除掉 bookItemParentNode.parentNode.removeChild(bookItemParentNode); } if(theBookItem.nextSibling){ // 处理完之后重新那book的next并做相应处理 range.selectNodeContents(theBookItem.nextSibling); }else{ var newEmptyLine = RE.generateEmptyPara(); RE.insertAfter(newEmptyLine, theBookItem); range.selectNodeContents(newEmptyLine); } if(!theBookItem.previousSibling || (theBookItem.previousSibling.getAttribute('contenteditable') == 'false')){ theBookItem.parentNode.insertBefore(generateSpaceNode(), theBookItem); } } } RE.backuprange(); selection.removeAllRanges(); selection.addRange(range); selection.collapseToStart(); //插完书滚动编辑器到合适的位置 RE.calculateEditorHeightWithCaretPosition(); //判断placeholder RE.updatePlaceholder(); }, 30); } RE.getAllBookIds = function() { var books = RE.editor.querySelectorAll('.re_bookItem'), idArray = []; for (var i = 0; i < books.length; i++) { idArray.push(books[i].getAttribute('data-id')) } var bookIds = ""; if (idArray.length > 0) { bookIds = idArray.join(RE.dataSeparator); } return bookIds; } // 插入图片 /* params: [img,img,img,...] img: { url:, w:, h:, ratio:, oriw: } */ RE.insertImage = function(imgArray) { function generateSpaceNode(){ var n = document.createTextNode('\u200D'); return n; } function generateLineBreakNode(){ var n = document.createElement('br'); return n; } function findImageNextSibling(imgItem){ var tempDom = document.createElement('div'); tempDom.innerHTML = imgItem.parentNode.innerHTML; var target = tempDom.querySelector('.re_img').nextSibling; return target; } function findImagePrevSibling(imgItem){ var tempDom = document.createElement('div'); tempDom.innerHTML = imgItem.parentNode.innerHTML; var target = tempDom.querySelector('.re_img').previousSibling; return target; } function resetImageParentNodeHtml(imgItem){ var pnode = imgItem.parentNode, tempDom = document.createElement('div'); tempDom.innerHTML = pnode.innerHTML; pnode.innerHTML = tempDom.innerHTML; } var imgItem = document.createElement('p'), imgItemContent = '', flagId = ''; for(var i=0; i0 && img.h > 0)?('width="'+img.w+'" height="'+img.h+'">'):'>'); flagId += img.url; } imgItem.setAttribute('data-id', flagId); imgItem.innerHTML = imgItemContent; // hack for timing setTimeout(function(){ var selection = window.getSelection(), range; if (window.getSelection().rangeCount > 0) { range = selection.getRangeAt(0); } else { range = document.createRange(); if(RE.currentSelection.startContainer == 0 || RE.currentSelection.endContainer == 0){ range.setStart(RE.editor, RE.currentSelection.startOffset); range.setEnd(RE.editor, RE.currentSelection.endOffset); }else{ range.setStart(RE.currentSelection.startContainer, RE.currentSelection.startOffset); range.setEnd(RE.currentSelection.endContainer, RE.currentSelection.endOffset); } } var rangeNode = range.endContainer; // 光标所在的node if (RE.isInTag(rangeNode, ['h1' ,'h2' ,'ul' ,'blockquote'])){ // 列表和引用内不插书籍,把书籍看成一个独立的段落处理 var inTagNode = RE.isInTag(rangeNode, ['h1' ,'h2' ,'ul' ,'blockquote']).tagNode; imgItem.removeAttribute('data-id'); if (inTagNode.textContent.length == 0) { // 如果当前block没有文本,则把block删掉 inTagNode.parentNode.insertBefore(imgItem, inTagNode); if (imgItem.previousSibling.getAttribute('contenteditable') == 'false') { imgItem.parentNode.insertBefore(generateSpaceNode(), imgItem); } inTagNode.remove(); } else { RE.insertAfter(imgItem, inTagNode); } if (imgItem.nextSibling) { range.selectNodeContents(imgItem.nextSibling); range.collapse(); } else { var newEmptyLine = RE.generateEmptyPara(); RE.insertAfter(newEmptyLine, imgItem); range.selectNodeContents(newEmptyLine); range.collapse(false); } }else{ // 在第一行或者在一个p里,这里把图片和图片前后的node包个p range.collapse(false); range.insertNode(imgItem); var flagId = imgItem.getAttribute('data-id'), imgItemParentNode = imgItem.parentNode; resetImageParentNodeHtml(imgItem); var theImgItem = imgItemParentNode.querySelector('[data-id="'+flagId+'"]'), theImgItemPreviousSibling = null || theImgItem.previousSibling, theImgItemNextSibling = null || theImgItem.nextSibling; theImgItem.removeAttribute('data-id'); if(imgItemParentNode == RE.editor){ // 这是在第一行没被p包住的情况 // 图片前面包一个p if(theImgItemPreviousSibling){ if((theImgItemPreviousSibling.nodeType == 3 ) || (theImgItemPreviousSibling.nodeType == 1 && theImgItemPreviousSibling.tagName.toLowerCase() == "br")){ var newPreviousPara = document.createElement('p'); range.selectNodeContents(theImgItemPreviousSibling); range.surroundContents(newPreviousPara); } } // 图片后面包一个p if(theImgItemNextSibling){ if((theImgItemNextSibling.nodeType == 3 ) || (theImgItemNextSibling.nodeType == 1 && theImgItemNextSibling.tagName.toLowerCase() == "br")){ var newNextPara = document.createElement('p'); range.selectNodeContents(theImgItemNextSibling); range.surroundContents(newNextPara); range.selectNodeContents(newNextPara); }else{ range.selectNodeContents(theImgItemNextSibling); range.collapse(); } }else{ var newEmptyLine = RE.generateEmptyPara(); RE.insertAfter(newEmptyLine, theImgItem); range.selectNodeContents(newEmptyLine); range.collapse(false); } }else{ // 这是在一个段落里面的 // 先把图片挪到parent外面 RE.insertAfter(theImgItem, imgItemParentNode); // 如果原来有nextSibling,则把图片原来的nextSibling包一个p并插到图片后面 if(theImgItemNextSibling && !(theImgItemNextSibling.nodeType == 1 && theImgItemNextSibling.tagName.toLowerCase() == "br")){ var newNextPara; if((theImgItemNextSibling.nodeType == 3 ) || (theImgItemNextSibling.nodeType == 1 && theImgItemNextSibling.tagName.toLowerCase() == "br")){ newNextPara = document.createElement('p'); range.selectNodeContents(theImgItemNextSibling); range.surroundContents(newNextPara); }else{ newNextPara = theImgItemNextSibling; } RE.insertAfter(newNextPara, theImgItem); } if((imgItemParentNode.childNodes.length == 0) || (imgItemParentNode.innerHTML == '
') || (imgItemParentNode.innerText == '')){ // 书和next移除出来后parent空了,移除掉 imgItemParentNode.parentNode.removeChild(imgItemParentNode); } if(theImgItem.nextSibling){ // 处理完之后重新那img的next并做相应处理 range.selectNodeContents(theImgItem.nextSibling); }else{ var newEmptyLine = RE.generateEmptyPara(); RE.insertAfter(newEmptyLine, theImgItem); range.selectNodeContents(newEmptyLine); } } } RE.backuprange(); selection.removeAllRanges(); selection.addRange(range); //插完书滚动编辑器到合适的位置 RE.calculateEditorHeightWithCaretPosition(); selection.collapseToStart(); wereadBridge.handleWithRichEditor('onInsertImage', { 'param': '' }, '', ''); //判断placeholder RE.updatePlaceholder(); //insert dom之后,立刻滚动,未必能够得到正确的位置 var delaytime = 50; if (imgArray.length > 2) { delaytime = 100; } setTimeout(function(){ RE.calculateEditorHeightWithCaretPosition(); },delaytime); }, 50); } // 插入QQ表情 RE.insertQQEmoticon = function(url, alt, w, h) { // blur掉的时候直接操作dom,插入imgNode后更新currentSelection,app调用RE.focus会在里面restorerange var imgNode = document.createElement('img'); imgNode.setAttribute('src', url); imgNode.setAttribute('alt', alt); imgNode.className = 're_QQEmoticon'; if (w > 0 && h > 0) { imgNode.setAttribute('style', 'width: ' + h + 'px;height: ' + h + 'px;'); } // blur状态下直接从备份获取range var range = document.createRange(); range.setStart(RE.currentSelection.startContainer, RE.currentSelection.startOffset); range.setEnd(RE.currentSelection.endContainer, RE.currentSelection.endOffset); // 将node插入到range并将光标置于最新加入的node后面 range.collapse(false); range.insertNode(imgNode); range.setStartAfter(imgNode); range.collapse(true); RE.currentSelection = { 'startContainer': range.startContainer, 'startOffset': range.startOffset, 'endContainer': range.endContainer, 'endOffset': range.endOffset }; RE.calculateEditorHeightWithCaretPosition(); RE.contentChanged({}); //判断placeholder RE.updatePlaceholder(); } // https://github.com/mathiasbynens/emoji-regex RE.emojiUnicodeReg = /((?:0\u20E3|1\u20E3|2\u20E3|3\u20E3|4\u20E3|5\u20E3|6\u20E3|7\u20E3|8\u20E3|9\u20E3|#\u20E3|\*\u20E3|\uD83C(?:\uDDE6\uD83C(?:\uDDE8|\uDDE9|\uDDEA|\uDDEB|\uDDEC|\uDDEE|\uDDF1|\uDDF2|\uDDF4|\uDDF6|\uDDF7|\uDDF8|\uDDF9|\uDDFA|\uDDFC|\uDDFD|\uDDFF)|\uDDE7\uD83C(?:\uDDE6|\uDDE7|\uDDE9|\uDDEA|\uDDEB|\uDDEC|\uDDED|\uDDEE|\uDDEF|\uDDF1|\uDDF2|\uDDF3|\uDDF4|\uDDF6|\uDDF7|\uDDF8|\uDDF9|\uDDFB|\uDDFC|\uDDFE|\uDDFF)|\uDDE8\uD83C(?:\uDDE6|\uDDE8|\uDDE9|\uDDEB|\uDDEC|\uDDED|\uDDEE|\uDDF0|\uDDF1|\uDDF2|\uDDF3|\uDDF4|\uDDF5|\uDDF7|\uDDFA|\uDDFB|\uDDFC|\uDDFD|\uDDFE|\uDDFF)|\uDDE9\uD83C(?:\uDDEA|\uDDEC|\uDDEF|\uDDF0|\uDDF2|\uDDF4|\uDDFF)|\uDDEA\uD83C(?:\uDDE6|\uDDE8|\uDDEA|\uDDEC|\uDDED|\uDDF7|\uDDF8|\uDDF9|\uDDFA)|\uDDEB\uD83C(?:\uDDEE|\uDDEF|\uDDF0|\uDDF2|\uDDF4|\uDDF7)|\uDDEC\uD83C(?:\uDDE6|\uDDE7|\uDDE9|\uDDEA|\uDDEB|\uDDEC|\uDDED|\uDDEE|\uDDF1|\uDDF2|\uDDF3|\uDDF5|\uDDF6|\uDDF7|\uDDF8|\uDDF9|\uDDFA|\uDDFC|\uDDFE)|\uDDED\uD83C(?:\uDDF0|\uDDF2|\uDDF3|\uDDF7|\uDDF9|\uDDFA)|\uDDEE\uD83C(?:\uDDE8|\uDDE9|\uDDEA|\uDDF1|\uDDF2|\uDDF3|\uDDF4|\uDDF6|\uDDF7|\uDDF8|\uDDF9)|\uDDEF\uD83C(?:\uDDEA|\uDDF2|\uDDF4|\uDDF5)|\uDDF0\uD83C(?:\uDDEA|\uDDEC|\uDDED|\uDDEE|\uDDF2|\uDDF3|\uDDF5|\uDDF7|\uDDFC|\uDDFE|\uDDFF)|\uDDF1\uD83C(?:\uDDE6|\uDDE7|\uDDE8|\uDDEE|\uDDF0|\uDDF7|\uDDF8|\uDDF9|\uDDFA|\uDDFB|\uDDFE)|\uDDF2\uD83C(?:\uDDE6|\uDDE8|\uDDE9|\uDDEA|\uDDEB|\uDDEC|\uDDED|\uDDF0|\uDDF1|\uDDF2|\uDDF3|\uDDF4|\uDDF5|\uDDF6|\uDDF7|\uDDF8|\uDDF9|\uDDFA|\uDDFB|\uDDFC|\uDDFD|\uDDFE|\uDDFF)|\uDDF3\uD83C(?:\uDDE6|\uDDE8|\uDDEA|\uDDEB|\uDDEC|\uDDEE|\uDDF1|\uDDF4|\uDDF5|\uDDF7|\uDDFA|\uDDFF)|\uDDF4\uD83C\uDDF2|\uDDF5\uD83C(?:\uDDE6|\uDDEA|\uDDEB|\uDDEC|\uDDED|\uDDF0|\uDDF1|\uDDF2|\uDDF3|\uDDF7|\uDDF8|\uDDF9|\uDDFC|\uDDFE)|\uDDF6\uD83C\uDDE6|\uDDF7\uD83C(?:\uDDEA|\uDDF4|\uDDF8|\uDDFA|\uDDFC)|\uDDF8\uD83C(?:\uDDE6|\uDDE7|\uDDE8|\uDDE9|\uDDEA|\uDDEC|\uDDED|\uDDEE|\uDDEF|\uDDF0|\uDDF1|\uDDF2|\uDDF3|\uDDF4|\uDDF7|\uDDF8|\uDDF9|\uDDFB|\uDDFD|\uDDFE|\uDDFF)|\uDDF9\uD83C(?:\uDDE6|\uDDE8|\uDDE9|\uDDEB|\uDDEC|\uDDED|\uDDEF|\uDDF0|\uDDF1|\uDDF2|\uDDF3|\uDDF4|\uDDF7|\uDDF9|\uDDFB|\uDDFC|\uDDFF)|\uDDFA\uD83C(?:\uDDE6|\uDDEC|\uDDF2|\uDDF8|\uDDFE|\uDDFF)|\uDDFB\uD83C(?:\uDDE6|\uDDE8|\uDDEA|\uDDEC|\uDDEE|\uDDF3|\uDDFA)|\uDDFC\uD83C(?:\uDDEB|\uDDF8)|\uDDFD\uD83C\uDDF0|\uDDFE\uD83C(?:\uDDEA|\uDDF9)|\uDDFF\uD83C(?:\uDDE6|\uDDF2|\uDDFC)))|[\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23E9-\u23F3\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB-\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u261D\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2648-\u2653\u2660\u2663\u2665\u2666\u2668\u267B\u267F\u2692-\u2694\u2696\u2697\u2699\u269B\u269C\u26A0\u26A1\u26AA\u26AB\u26B0\u26B1\u26BD\u26BE\u26C4\u26C5\u26C8\u26CE\u26CF\u26D1\u26D3\u26D4\u26E9\u26EA\u26F0-\u26F5\u26F7-\u26FA\u26FD\u2702\u2705\u2708-\u270D\u270F\u2712\u2714\u2716\u271D\u2721\u2728\u2733\u2734\u2744\u2747\u274C\u274E\u2753-\u2755\u2757\u2763\u2764\u2795-\u2797\u27A1\u27B0\u27BF\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B50\u2B55\u3030\u303D\u3297\u3299]|\uD83C[\uDC04\uDCCF\uDD70\uDD71\uDD7E\uDD7F\uDD8E\uDD91-\uDD9A\uDE01\uDE02\uDE1A\uDE2F\uDE32-\uDE3A\uDE50\uDE51\uDF00-\uDF21\uDF24-\uDF93\uDF96\uDF97\uDF99-\uDF9B\uDF9E-\uDFF0\uDFF3-\uDFF5\uDFF7-\uDFFF]|\uD83D[\uDC00-\uDCFD\uDCFF-\uDD3D\uDD49-\uDD4E\uDD50-\uDD67\uDD6F\uDD70\uDD73-\uDD79\uDD87\uDD8A-\uDD8D\uDD90\uDD95\uDD96\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDEF\uDDF3\uDDFA-\uDE4F\uDE80-\uDEC5\uDECB-\uDED0\uDEE0-\uDEE5\uDEE9\uDEEB\uDEEC\uDEF0\uDEF3]|\uD83E[\uDD10-\uDD18\uDD80-\uDD84\uDDC0])$/g; // 表情面板中点击退格 RE.removeInQQEmoticonPanel = function() { var selection = RE.currentSelection, node = selection.endContainer, offset = selection.endOffset; if (node == RE.editor) { var theRemovedNode = node.childNodes[offset - 1]; if(theRemovedNode){ var theRemovedNodePrevSibling = theRemovedNode.previousSibling; node.removeChild(theRemovedNode); if(theRemovedNodePrevSibling){ if (theRemovedNodePrevSibling.nodeType == 3) { var range = document.createRange(); range.selectNodeContents(theRemovedNodePrevSibling); range.collapse(false); RE.currentSelection = { 'startContainer': range.startContainer, 'startOffset': range.startOffset, 'endContainer': range.endContainer, 'endOffset': range.endOffset }; } else { RE.currentSelection = { 'startContainer': node, 'startOffset': offset - 1, 'endContainer': node, 'endOffset': offset - 1 }; } } } } else if (node.nodeType == 3) { if (offset == node.length && node.length > 0) { if (new RegExp(RE.emojiUnicodeReg).exec(RE.currentSelection.endContainer.textContent)) { var lastEmojiIndex = new RegExp(RE.emojiUnicodeReg).exec(RE.currentSelection.endContainer.textContent).index; node.textContent = node.textContent.substring(0, lastEmojiIndex); } else { node.textContent = node.textContent.slice(0, -1); } var range = document.createRange(); range.selectNodeContents(node); range.collapse(false); RE.currentSelection = { 'startContainer': range.startContainer, 'startOffset': range.startOffset, 'endContainer': range.endContainer, 'endOffset': range.endOffset }; } else if (offset == 0 || node.length == 0) { var previousNode = node.previousSibling; if (previousNode.nodeType == 3 && previousNode.length > 0) { previousNode.textContent = previousNode.textContent.slice(0, -1); var range = document.createRange(); range.selectNodeContents(previousNode); range.collapse(false); RE.currentSelection = { 'startContainer': range.startContainer, 'startOffset': range.startOffset, 'endContainer': range.endContainer, 'endOffset': range.endOffset }; } else { RE.currentSelection = { 'startContainer': previousNode.parentNode, 'startOffset': RE.nodeIndexInParent(previousNode, previousNode.parentNode), 'endContainer': previousNode.parentNode, 'endOffset': RE.nodeIndexInParent(previousNode, previousNode.parentNode) }; previousNode.parentNode.removeChild(previousNode); } } else { node.textContent = node.textContent.substring(0, offset - 1) + node.textContent.substring(offset); RE.currentSelection = { 'startContainer': node, 'startOffset': offset - 1, 'endContainer': node, 'endOffset': offset - 1 }; } } else { var theRemovedNode = node.childNodes[offset - 1]; if(theRemovedNode){ var theRemovedNodePrevSibling = theRemovedNode.previousSibling; node.removeChild(theRemovedNode); if(theRemovedNodePrevSibling){ if (theRemovedNodePrevSibling.nodeType == 3) { var range = document.createRange(); range.selectNodeContents(theRemovedNodePrevSibling); range.collapse(false); RE.currentSelection = { 'startContainer': range.startContainer, 'startOffset': range.startOffset, 'endContainer': range.endContainer, 'endOffset': range.endOffset }; } else { RE.currentSelection = { 'startContainer': node, 'startOffset': offset - 1, 'endContainer': node, 'endOffset': offset - 1 }; } } } } //判断placeholder RE.updatePlaceholder(); } RE.insertHTML = function(html) { setTimeout(function(){ //blockqupte h2标签不能共存 var sel = getSelection(); var focusNode = sel.focusNode; var needRemoveFlag = false; if (typeof(focusNode) != 'undefined') { var inQuoteBlock = RE.isInTag(focusNode, 'blockquote'); if (inQuoteBlock.is) { needRemoveFlag = true; } } var formatBlock = document.queryCommandValue('formatBlock'); if (RE.isCommandEnabled('insertUnorderedList')) { needRemoveFlag = true; } if (formatBlock == 'h2') { needRemoveFlag = true; } if (needRemoveFlag) { html = RE.removeExcluedFlag(html); } else { var range = getSelection().getRangeAt(0).cloneRange() var endOffset = range.endOffset; if (endOffset != 0) {//不是起始位置 if (html.indexOf(' ') == 0) { document.execCommand('insertHTML', false, ''); } } } document.execCommand('insertHTML', false, html); RE.contentChanged({}); //判断placeholder RE.updatePlaceholder(); //RE.calculateEditorHeightWithCaretPosition(); },30); } RE.insertText = function(text) { document.execCommand('insertText', false, text); RE.contentChanged({}); } RE.removeExcluedFlag = function(str) { str = str.replace(/blockquote>/g,'p>') .replace(/h2>/g,'p>') .replace(/
/g,'') .replace(/<\/ul>/g,'') .replace(/li>/g,'p>') str = correctArticle(str, {pInQuote: true}); return str; } //光标前移动一位 RE.cursorGoBackForAtClick = function() { var curNode = getSelection().anchorNode; if (typeof(curNode) != 'undefined') { var curText = curNode.textContent; var curLen = curText.length; if (curText.length > 1) { var range = getSelection().getRangeAt(0).cloneRange(); var fixedOffset = range.startOffset - 1; if (fixedOffset > 0) { range.setStart(range.startContainer, fixedOffset); range.setEnd(range.endContainer, fixedOffset); getSelection().removeAllRanges(); getSelection().addRange(range); } } } } RE.delFieldBeforeFocus = function() { var sel = getSelection(); var focusNode = sel.focusNode; if (typeof(focusNode) != 'undefined') { var curText = focusNode.textContent; var curLen = curText.length; if (curLen >= 1 && sel.focusOffset > 0) { // 保证当前node有字符,且光标不在最前面 var range = sel.getRangeAt(0); var fixedOffset = range.startOffset - 1; var focusOffset = sel.focusOffset; var newText = curText.substr(0, focusOffset - 1); if (curLen > focusOffset) { newText = newText + curText.substr(focusOffset, curLen - focusOffset); } focusNode.textContent = newText; range.setStart(range.startContainer, fixedOffset); range.setEnd(range.endContainer, fixedOffset); getSelection().removeAllRanges(); getSelection().addRange(range); RE.backuprange(); //字符减少后光标变化,需记录 } else { focusNode.textContent = ''; } } RE.contentChanged({}); } RE.insertLink = function(text, href, title) { if (!RE.isFocus()) { RE.focusEditor(); } /* href='topic:name/at:vid' 初始状态'topic:0/at:0' title='#content#/@username' 初始状态'##/@\u00A0' 初始化后title,href在选中用户或者选择话题的时候才进行更新 */ var selection = window.getSelection(), currentNode = selection.focusNode; if (selection && selection.rangeCount > 0) { var aElement = document.createElement('a'); aElement.setAttribute('href', href ? href : ''); aElement.setAttribute('title', title ? title : ''); aElement.className = 're_link'; if (RE.currentEditingLink) { // 避免重复link aElement.innerText = text ? text : ''; RE.insertAfter(aElement, RE.currentEditingLink); var range = document.createRange(); range.selectNode(aElement); range.collapse(false); } else { // 纯文本 var range = selection.getRangeAt(0).cloneRange(); range.surroundContents(aElement); // surroundContents后link的innertText为光标选择的内容,需要重新设定为需要的text aElement.innerText = text ? text : ''; range.collapse(false); } selection.removeAllRanges(); selection.addRange(range); RE.contentChanged({}); } //判断placeholder RE.updatePlaceholder(); } // unlink光标前的link RE.unlink = function() { // document.execCommand('unlink', false, false); if (RE.currentEditingLink) { RE.unlinkFor(RE.currentEditingLink); } RE.contentChanged({}); } // unlink光标后的link RE.unlinkAfter = function() { // document.execCommand('unlink', false, false); if (RE.currentEditingAfterLink) { RE.unlinkFor(RE.currentEditingAfterLink); } RE.contentChanged({}); } // unlink指定的link RE.unlinkFor = function(link) { var parent = link.parentElement, newEl = document.createTextNode(link.innerText); var selection = window.getSelection(); var range = document.createRange(); range.selectNode(link); selection.removeAllRanges(); selection.addRange(range); document.execCommand('unlink', false, null); RE.restorerange(); RE.contentChanged({}); } RE.updateLink = function(text, href, title) { if (RE.currentEditingLink) { //replace innerhtml var currentLink = RE.currentEditingLink; currentLink.setAttribute('href', href); currentLink.setAttribute('title', title); currentLink.innerHTML = text; //move cursor var iteratorNode = currentLink; while (iteratorNode.lastChild) { iteratorNode = iteratorNode.lastChild; } var range = document.createRange(); range.selectNodeContents(iteratorNode); range.collapse(false); var len = iteratorNode.textContent.length; range.setStart(range.startContainer, len); range.setEnd(range.endContainer, len); var selection = window.getSelection(); selection.removeAllRanges(); selection.addRange(range); } RE.contentChanged({}); } RE.updateLinkAttribute = function(href, title) { if (RE.currentEditingLink) { var currentLink = RE.currentEditingLink; currentLink.setAttribute('href', href); currentLink.setAttribute('title', title); } } // 键盘监听 RE.keyupCallback = function(e) { if (e.keyCode != 0 || e.which != 0) { if (e.which != KEY_BACKSPACE_CODE) { // 若不是退格行为,则判断当前keyup后光标前一位的字符 var currentAnchorCode = window.getSelection().focusNode.textContent[window.getSelection().focusOffset - 1]; if (currentAnchorCode == KEY_AT_CHAR && e.which == KEY_AT_CODE) { RE.handleAtClick(); } else if (currentAnchorCode == KEY_HASH_CHAR && e.which == KEY_HASH_CODE) { RE.handleTopicClick(); } } } } RE.delete = function() { document.execCommand('delete', false, null); RE.contentChanged({}); } RE.setTodo = function(text) { var html = ' '; document.execCommand('insertHTML', false, html); RE.contentChanged({}); } RE.prepareInsert = function() { RE.backuprange(); } RE.backuprange = function() { var selection = window.getSelection(); if (selection.rangeCount > 0) { var range = selection.getRangeAt(0); RE.currentSelection = { 'startContainer': range.startContainer, 'startOffset': range.startOffset, 'endContainer': range.endContainer, 'endOffset': range.endOffset }; } } RE.restorerange = function() { var selection = window.getSelection(); selection.removeAllRanges(); var range = document.createRange(); range.setStart(RE.currentSelection.startContainer, RE.currentSelection.startOffset); range.setEnd(RE.currentSelection.endContainer, RE.currentSelection.endOffset); selection.addRange(range); } RE.isCommandEnabled = function(commandName) { return document.queryCommandState(commandName); } RE.removeSpecifiedLink = function(link) { var parent = link.parentElement; if (parent) { var newEl = document.createTextNode(link.innerText); parent.insertBefore(newEl, link); parent.removeChild(link); } } RE.contentChanged = function(e) { var items = []; if (RE.isCommandEnabled('bold')) { items.push('bold'); } if (RE.isCommandEnabled('italic')) { items.push('italic'); } if (RE.isCommandEnabled('insertOrderedList')) { items.push('orderedList'); } if (RE.isCommandEnabled('insertUnorderedList')) { items.push('unorderedList'); } if (RE.isCommandEnabled('justifyCenter')) { items.push('justifyCenter'); } if (RE.isCommandEnabled('justifyLeft')) { items.push('justifyLeft'); } if (RE.isCommandEnabled('justifyRight')) { items.push('justifyRight'); } var formatBlock = document.queryCommandValue('formatBlock'); if (formatBlock.length > 0) { items.push(formatBlock); } if (typeof(e) != 'undefined') { var node = RE.getSelectedNode(); if (node) { var inQuoteBlock = RE.isInTag(node, 'blockquote'); if (inQuoteBlock.is) { items.push('blockquote'); } var nodeName = node.nodeName.toLowerCase(); // Link if (RE.isSpecifiedTag(node, 'a')) { RE.currentEditingLink = node; } else if (RE.isInTag(node, 'a').is) { var plink = RE.isInTag(node, 'a').tagNode; RE.currentEditingLink = plink; } else { if (RE.currentEditingLink) { //ios 离开link的时候,需要判断Link是否还没完成 if (RE.currentEditingLink.href.indexOf('at:') == 0) { //at link var parsedTitle = RE.editor.decodeFaceStr(RE.currentEditingLink.title); if (RE.currentEditingLink.href.indexOf('at:0') == 0 || parsedTitle != RE.currentEditingLink.text) { RE.removeSpecifiedLink(RE.currentEditingLink); } } else if (RE.currentEditingLink.href.indexOf('topic:') == 0) { //ios 离开link的时候,需要判断Link是否被破坏 if (typeof(RE.currentEditingLink.innerText) == 'undefined' || RE.currentEditingLink.innerText.length < 2 || RE.currentEditingLink.innerText.indexOf('#') != 0 || RE.currentEditingLink.innerText.lastIndexOf('#') != RE.currentEditingLink.innerText.length - 1) { RE.removeSpecifiedLink(RE.currentEditingLink); } } } RE.currentEditingLink = null; } // 判断光标后面是不是link if (node.nextElementSibling || node.nextSibling) { var next = node.nextElementSibling || node.nextSibling; if (next && RE.isSpecifiedTag(next, 'a')) { RE.currentEditingAfterLink = next; var title = next.getAttribute('title'); var href = next.getAttribute('href'); if (href != undefined) { items.push('afterLink:' + href); } if (title !== undefined) { items.push('afterLink-title:' + title); } items.push('afterLink-text:' + next.innerText) items.push('afterLink-html:' + next.innerHTML) } else if (RE.isInTag(node, 'a').is) { var plink = RE.isInTag(node, 'a').tagNode; RE.currentEditingAfterLink = plink; var title = plink.getAttribute('title'); var href = plink.getAttribute('href'); if (href != undefined) { items.push('afterLink:' + href); } if (title !== undefined) { items.push('afterLink-title:' + title); } items.push('afterLink-text:' + plink.innerText); items.push('afterLink-html:' + next.innerHTML) } else { RE.currentEditingAfterLink = null; } } // Blockquote if (RE.isSpecifiedTag(node, 'blockquote')) { items.push('indent'); } // Image if (RE.isSpecifiedTag(node, 'img')) { RE.currentEditingImage = node; var src = node.getAttribute('src'); var alt = node.getAttribute('alt'); if (src != undefined) { items.push('image:' + src); } if (alt != undefined) { items.push('image-alt:' + node.getAttribute('alt')); } } else { RE.currentEditingImage = null; } } } if (RE.currentEditingLink) { //放在这里是因为保证即使是失焦,也能传递Link数据 items.push('isEditingLink:1') var title = RE.currentEditingLink.getAttribute('title'); var href = RE.currentEditingLink.getAttribute('href'); if (href != undefined) { items.push('link:' + href); } if (title !== undefined) { items.push('link-title:' + title); } items.push('link-text:' + RE.currentEditingLink.innerText); items.push('link-html:' + RE.currentEditingLink.innerHTML) } else { items.push('isEditingLink:0') } if (window.getSelection().toString().length > 0) { items.push('hasSelectedText'); } wereadBridge.handleWithRichEditor('onSelectionChange', { 'param': items.join(RE.dataSeparator) }, '', ''); } RE.handleAtClick = function() { var items = []; RE.fillEditingStatus(items); wereadBridge.handleWithRichEditor('onAtClicked', { 'param': items.join(RE.dataSeparator) }, '', ''); } RE.handleTopicClick = function() { var items = []; RE.fillEditingStatus(items); wereadBridge.handleWithRichEditor('onTopicClicked', { 'param': items.join(RE.dataSeparator) }, '', ''); } RE.fillEditingStatus = function(items) { if (RE.currentEditingLink) { items.push('isEditingLink:1') } else { items.push('isEditingLink:0') } } RE.isEditingLink = function() { if (RE.currentEditingLink) { return true; } else { return false; } } RE.isFocus = function() { return document.activeElement === RE.editor; } RE.focus = function() { // 这个focus会将光标置于编辑器的最后 if (RE.currentSelection.startContainer != 0) { //当currentSelection有值才进入,这里是为了避免ios从其他界面调回来,光标能定位到原来的位置 RE.restorerange(); RE.editor.focus(); return; } var range = document.createRange(); range.selectNodeContents(RE.editor); range.collapse(false); var selection = window.getSelection(); selection.removeAllRanges(); selection.addRange(range); RE.editor.focus(); RE.backuprange(); } RE.focusEditor = function() { // 这个focus没有有处理光标的位置 RE.editor.focus() } RE.blurEditor = function() { RE.editor.blur(); } //这里将做表情的解码 l_f_s微笑r_f_s --》[微笑] RE.editor.decodeFaceStr = function(str) { var regular = RE.faceSplitStrLeft + '.{1,3}'; regular = regular + RE.faceSplitStrRight; if (typeof(str) != 'undefined' && str) { var matchedArr = str.match(regular); if (matchedArr && matchedArr.length > 0) { for (var index = 0; index < matchedArr.length; index++) { var matchedStr = matchedArr[index] while (matchedStr && str && str.indexOf(matchedStr) != -1) { if (matchedStr && matchedStr.length > RE.faceSplitStrRight.length + RE.faceSplitStrLeft.length) { var originalStr = matchedStr.substr(RE.faceSplitStrLeft.length, matchedStr.length - RE.faceSplitStrRight.length - RE.faceSplitStrLeft.length); originalStr = '[' + originalStr; originalStr = originalStr + ']'; str = str.replace(matchedStr, originalStr); } else { break; } } } } } return str; }; RE.editor.addEventListener('paste', function(e) { e.preventDefault(); wereadBridge.handleWithRichEditor('onPaste', { 'param': '' }, '', '') }); //由于Android,@和#需要跳出页面,回来时WebView请求focus时自动滚动到顶部,因此需要重新滚动至光标处 RE.triggerCursorScroll = function() { wereadBridge.handleWithRichEditor('onCursorScroll', { 'param': 'scroll' }, '', ''); } RE.removeFormat = function() { document.execCommand('removeFormat', false, null); } // Event Listeners RE.editor.addEventListener('keyup', RE.keyupCallback); RE.editor.addEventListener('keydown', RE.keydownCallback); RE.editor.addEventListener('click', RE.contentChanged); RE.init(); RE.isHTMLChange = function() { var curHTML = RE.editor.innerHTML; if(curHTML != RE.originalHTML) return true; return false; } window.onload = function(){ RE.originalHTML= RE.editor.innerHTML; if(RE.isHTMLEmpty() || (RE.editor.innerHTML == RE.defaultHml)){ RE.editor.classList.add('re_placeholder'); }else{ RE.editor.classList.remove('re_placeholder'); } } RE.saveCurrentHTML = function () { RE.originalHTML = RE.editor.innerHTML; }