tinymce粘贴时自动加链接

来源:互联网 发布:广州淘宝摄影培训班 编辑:程序博客网 时间:2024/06/05 16:29

  firefox 3之后,出于安全考虑,浏览器禁止了js从剪贴板获取数据,但是很多时候,我们需要对粘贴的数据进行处理。对其自动加超链接便是其中最常见的要求之一。那么该如何去实现呢?

    tinymce有一个插件,叫linkautodetect的,它可以在用户输入类似Url、email地址时,用于判断是否自动为其添加超链接。但是该插件只有在按空格(space)建以及回车(enter)时,才会为其添加超链接。

   tinymce还有一个插件,叫paste的,用于处理从word或其他地方粘贴数据时进行处理。(本文的解决办法将不使用paste插件。因其可能导致中文乱码问题(个人猜测))。

 

   综合以上两个插件,一个不算完美但可应用的简化版 paste时自动添加超链接功能实现如下:

  思路: 在paste动作将内容粘贴之前,建一个div层做容器,用于接收内容,将光标移动至容器层。系统动作paste发生之后,我们获取到的容器层内的innerHTML即为粘贴的内容。取出粘贴的内容,利用replace正则替换内容中的Url、email地址。并将新内容替换旧内容。

  难点: 1、光标位置操作

             2、替换的正则匹配(如何排除已添加的,正确处理开始、结尾处等)

 

解决如下: 在tinymce编辑器的环境中,初始化编辑器时

在editor的初始化参数setup中添加

      setup : function (ed){

        .....
          ed.onPaste.add(function (ed, e){
              //mark the paste
              mark_paste_content(ed, e);
              //execute the check url after paste
              setTimeout(function(){
                  paste_link_detect(ed);
              }, 100);
          });     

         ....
      }

 

函数  mark_paste_content 定义如下:

 //construct a containner for pasteing 
function mark_paste_content(ed, ev){
     var marker, dom = ed.dom, sel = ed.selection, markerId = 'paste_marker';
    
     //To add a marker into the content
    var insert_marker = function (){
        var h = '<div id="paste_marker">&nbsp;</div>';
        var skip_undo = true;
        // First delete the contents seems to work better on WebKit
        if (!ed.selection.isCollapsed())
            ed.getDoc().execCommand('Delete', false, null);
        // It's better to use the insertHTML method on Gecko since it will combine paragraphs correctly before inserting the contents
        ed.execCommand(tinymce.isGecko ? 'insertHTML' : 'mceInsertContent', false, h, {skip_undo : skip_undo});    
    }
    // Insert a marker for the caret position
    insert_marker();
    //record the cursor position
    marker = dom.get(markerId);
    rng = sel.getRng();
    rng.setStart(marker, 0);
    rng.setEnd(marker, 1);
    sel.setRng(rng);
    console.log(ed.getContent());
}

 

 

 

函数  paste_link_detect定义如下:

//To add hyperlink to url address automatically when doing paste.
function paste_link_detect(ed){
     var marker, dom = ed.dom, sel = ed.selection, markerId = 'paste_marker';
     
    //Used for detecting url on paste
    var PRE_email = /([^a-z0-9_=@\-\"\':]|^)([a-z0-9_\-]+(\.[_a-z0-9\-]+)*@([_a-z0-9\-]+\.)+([a-z]{2}|aero|arpa|biz|com|coop|edu|gov|info|int|jobs|mil|museum|name|nato|net|org|pro|travel))($|(?=[^a-z0-9]))/gim;
    var PRE_url   = /([^a-z0-9=@\-\"\'\\\/\.]|^)((https?|ftp|news):\/\/)?(([a-z]([a-z0-9\-]*\.)+([a-z]{2}|aero|arpa|biz|com|coop|edu|gov|info|int|jobs|mil|museum|name|nato|net|org|pro|travel)|(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))(\/[a-z0-9_\-\.~]+)*(\/([a-z0-9_\-\.]*))?(\?[a-z0-9+_\-\.%=&amp;]*)?(#[a-z][a-z0-9_]*)?)($|(?=[^a-z0-9#?&%+\-@=]))/gim;    
    
    var detectPasteLink = function(htmlstr){
        htmlstr = htmlstr.replace(PRE_url, '$1<a href="$2$4" target="_blank">$2$4</a>$16');
        htmlstr = htmlstr.replace(PRE_email, '$1<a href="mailto:$2">$2</a>$6');
    
        return htmlstr;
    }

    node = dom.get(markerId);
    pnode = node.parentNode;
    //replace url
    var htmlstr = node.innerHTML;
    //fix a bug on firefox: firefox automatically add a br to marker span
    if('<br>' == htmlstr.substring(htmlstr.length-4)){
        htmlstr = htmlstr.substring(0, htmlstr.length-4);
    }
    console.log(htmlstr);
    html_pasted = detectPasteLink(htmlstr);
    //cross the empty anchor and useless anchor
    html_pasted = html_pasted.replace(/<a([^>]*)><a[^>]*>(.*?)<\/a><\/a>/gim, '<a$1>$2</a>');
    html_pasted = html_pasted.replace(/<a[^>]*>[\s\r\n\t\f]*<\/a>/gim, '');
    //check if the content changed
    var rng = sel.getRng();
    var frag = rng.createContextualFragment(html_pasted);
    //Use a div to wrap the pasted content. Or it will have problem under safari and chrome
    var new_node = document.createElement('div');
    new_node.appendChild(frag);
    var nextsibling = node.nextSibling;
    while(nextsibling && nextsibling.nodeType !=1){
        nextsibling = nextsibling.nextSibling;
    }
    //replace the content
    pnode.replaceChild(new_node, node);
        //var needtoremovenext = false;
    if(!nextsibling){
        //needtoremovenext = true;
        nextsibling = document.createElement('span');
        nextsibling.innerHTML = '&nbsp;';
        pnode.appendChild(nextsibling);
    }    
    //reset the cursor position
    rng.setStartAfter(nextsibling);
    rng.setEndAfter(nextsibling);
    sel.setRng(rng);
    //if(needtoremovenext){
    //    dom.remove(nextsibling);
    //}

    // Remove marker if it's left
    while (elm = dom.get(markerId))
        dom.remove(elm);
    
}