本身開發的MarkDown在線編輯器愈來愈完善了,內心感到高興。

先曬一下它的樣子。固然,我一開始就企圖作到這四點:隨時隨地能夠自動保存草稿內容到服務器;鍵盤快捷鍵進行Markdown格式編輯;能夠分段編輯(萬一文章比較長呢);還有就是手機上也能用大部分功能。如今這四個目標基本如今實現了。css

先讓人看看它的樣子。html

Markdown在線編輯器

第一個按鈕是新建文件。第二個按鈕是設置文件日期。第三個按鈕是插入圖片。第四個按鈕是查找替換文本。第五個按鈕是用來預覽內容。第六個按鈕是保存內容。第七個按鈕是發佈內容。第八個按鈕是返回到文檔列表。前端

我還給努力作到讓它插入圖片特別方便,能夠直接從本地硬盤中把圖片文件拖放到淡黃色區域中,也能夠複製圖片以後直接粘貼,就會用html5上傳功能自動上傳到服務器上了。html5

另外我還利用百度翻譯API和百度詞典作了鍵盤快捷鍵翻譯文檔功能(Ctrl+小鍵盤上的小數點),在淡黃色區域中雙擊一個單詞,當即顯示這個單詞的翻譯。ajax

小曬部分代碼。正則表達式

function onKeydown(e){
  if(e.ctrlKey && e.keyCode == 80){ // Ctrl+P 保存併發布
    e.preventDefault();save();
    }
    if(e.ctrlKey && e.keyCode == 83){ // Ctrl+S 保存草稿
    e.preventDefault();save();
    }
  if(e.ctrlKey && e.keyCode ==110) { // translate
    e.preventDefault();translate();
    }
    if(e.ctrlKey&&e.keyCode==73){ // Ctrl+B
    e.preventDefault();toggleT('*','*',true);
        }
    if(e.ctrlKey&&e.keyCode==66){ // Ctrl+I
        e.preventDefault();toggleT('**','**',true);
        }
    if(e.ctrlKey&&e.keyCode==80){
        e.preventDefault();showPreview();
        }
    if(e.ctrlKey&&e.keyCode==89){ // Ctrl+Y
        e.preventDefault();toggleT('`','`',true);
        }
    if(e.ctrlKey&&e.keyCode==70){ // Ctrl+F
        e.preventDefault();toggleFind();
        }
    if(e.shiftKey&&e.keyCode==13){
    insertT('\n','\n',false);
    return false;
    };
    if(e.ctrlKey&&e.keyCode==13){
    insertT('\n','\n',false);
    return false;
    };
    if(e.keyCode==13){  // Enter
        var startPos=Editor.selectionStart,endPos=Editor.selectionEnd;
        var tmpStr = Editor.value;
        var str1=tmpStr.substring(0,startPos);
        var ss=str1.lastIndexOf('\n')+1;
        var str2=str1.substr(ss);
        //if(!/^[\s]+/.test(str2))return true;
        if(/^(> )?\s*?\d+\.\s\s*/.test(str2)){
        var str3=str2.match(/^(> )?\s*?\d+\.\s\s*/)[0];
        if(str3==str2){Editor.value=tmpStr.substring(0,ss)+tmpStr.substr(startPos);
        Editor.selectionStart=Editor.selectionEnd=startPos+1-str3.length;return false;}; // 點兩次回車終止自行加前綴符
        var ss2=str3.match(/\d+/),ss3=parseInt(ss2);ss3++
        str3=str3.replace(/\d+/g,ss3);
        Editor.value=str1+'\r\n'+str3+tmpStr.substr(startPos);
        Editor.selectionStart=Editor.selectionEnd=startPos+1+str3.length;
        return false;
        }
        if(/^(> )?[-*]\s\s*/.test(str2)){
        str3=str2.match(/^(> )?[-*]\s\s*/)[0];
        //console.log('[['+str2+']]');
        if(str2==str3){Editor.value=tmpStr.substring(0,ss)+tmpStr.substr(startPos);
        Editor.selectionStart=Editor.selectionEnd=startPos+1-str3.length;return false;}// 點兩次回車終止自行加前綴符
        Editor.value=str1+'\r\n'+str3+tmpStr.substr(startPos);
        Editor.selectionStart=Editor.selectionEnd=startPos+1+str3.length;
           return false;
        }
        if(/^> /.test(str2)){
        str3=str2.match(/^> /)[0];
        if(str2==str3){Editor.value=tmpStr.substring(0,ss-1)+'\r\n'+tmpStr.substr(startPos);
        if(/^\n\n/.test(tmpStr.substr(startPos)))Editor.selectionStart=Editor.selectionEnd=startPos-1;
        else Editor.selectionStart=Editor.selectionEnd=startPos-3;
        return false;}// 點兩次回車終止自行加前綴符
        Editor.value=str1+'\r\n'+str3+'\r\n'+str3+tmpStr.substr(startPos);
        Editor.selectionStart=Editor.selectionEnd=startPos+2+str3.length*2;
        return false;
        }
        }
    if(e.shiftKey&&e.keyCode==9){  // Shift+Tab
      e.preventDefault();
        var startPos=Editor.selectionStart,endPos=Editor.selectionEnd;
        var tmpStr = Editor.value;
        var str1=tmpStr.substring(0,startPos);
        var ss=str1.lastIndexOf('\n')+1;
        if(startPos==endPos){
            var str2=str1.substr(ss);
            str2=str2.match(/^\s*/)[0];
            if(str2.length>=2){
                    Editor.value=tmpStr.substring(0,ss)+tmpStr.substr(ss+2);
                    Editor.selectionStart=Editor.selectionEnd=startPos-2;
                }else if(str2.length==1){
                    Editor.value=tmpStr.substring(0,ss)+tmpStr.substr(ss+1);
                    Editor.selectionStart=Editor.selectionEnd=startPos-1;
                }
            }
        else{
            var str2=tmpStr.substring(ss,endPos);
            //console.log(str2);
            str2=str2.replace(/^\s{1,2}/,'').replace(/\n\s{1,2}/g,'\n')
            Editor.value=tmpStr.substring(0,ss)+str2+tmpStr.substr(endPos);
            Editor.selectionStart=ss;
            Editor.selectionEnd=ss+str2.length;
            }
        //if(!/^[\s]+/.test(str2))return true;
        }
    else if(e.keyCode == 9){ // Tab
    e.preventDefault();
        var startPos=Editor.selectionStart,endPos=Editor.selectionEnd;
        var tmpStr = Editor.value;
        var str1=tmpStr.substring(0,startPos);
        var ss=str1.lastIndexOf('\n')+1;
        if(startPos==endPos){
            Editor.value=tmpStr.substring(0,ss)+'  '+tmpStr.substr(ss);
            Editor.selectionStart=Editor.selectionEnd=startPos+2;
            }
        else{
            var str2=tmpStr.substring(ss,endPos);
            var ss2=/\n/g.test(str2)?str2.match(/\n/g).length:0;
            str2=str2.replace(/\n/g,"\n  ");
            Editor.value=tmpStr.substring(0,ss)+'  '+str2+tmpStr.substr(endPos);
            Editor.selectionStart=startPos+2;
            Editor.selectionEnd=endPos+2+ss2*2;
        //cursorPos=Editor.selectionEnd;
        //insertT('  ','',false);
        }
        }
    else if(e.ctrlKey&&e.keyCode==222){ // Ctrl+'
    e.preventDefault();
    var startPos=Editor.selectionStart,endPos=Editor.selectionEnd;
        var tmpStr = Editor.value;
        var str1=tmpStr.substring(0,startPos);
        var ss=str1.lastIndexOf('\n')+1;
        var ss2=tmpStr.substring(0,endPos).lastIndexOf('\n')+1
        if(ss==ss2){
        if(str1.substr(ss,2)=='> '){
        Editor.value=tmpStr.substring(0,ss)+tmpStr.substr(ss+2);
        Editor.selectionStart=startPos-2<ss?startPos-2:ss;
        Editor.selectionEnd=endPos-2;
        }
        else{
        Editor.value=tmpStr.substring(0,ss)+'> '+tmpStr.substr(ss);
        Editor.selectionStart=startPos+2;
        Editor.selectionEnd=endPos+2;
        }
        }
        else{
        if(str1.substr(ss,2)=='> '){
        var str2=tmpStr.substring(ss,endPos);
        var ss3=/\n> /g.test(str2)?str2.match(/\n> /g).length:0;
        str2=str2.replace(/\n> /g,"\n");
        str2=str2.substr(2);
        Editor.value=tmpStr.substring(0,ss)+str2+tmpStr.substr(endPos);
        Editor.selectionStart=ss?startPos-2:ss;
        Editor.selectionEnd=endPos-ss3*2-2;
        }
        else{
        var str2=tmpStr.substring(ss,endPos);
        var ss3=/\n/g.test(str2)?str2.match(/\n/g).length:0;
        str2=str2.replace(/\n/g,"\n> ");
        Editor.value=tmpStr.substring(0,ss)+'> '+str2+tmpStr.substr(endPos);
        Editor.selectionStart=startPos+2;
        Editor.selectionEnd=endPos+ss3*2+2;
        }
        
        }
    }
    }
function imgReader(item){
    if(item.kind=='file'&&item.type.indexOf('image')==0){
      var file = item.getAsFile(),reader = new FileReader();
         reader.onload = function(e){
        //var img = new Image();img.src = e.target.result;document.body.appendChild( img );
        var filename=file.name?file.name:'';
        //$.post(_uploadUrl,{'upload':e.target.result},function(data){insertT('![',filename+']('+data+')\n',false);});
        uploadFile(e.target.result,filename);
        };
        reader.readAsDataURL(file);
        }
  }
function textReader(file){
  //var sText=file.name+'Date'+file.lastModifiedDate+'content'+file.contents;
  var reader=new FileReader();
  reader.onload=function(e){
      insertT('',e.target.result,false);
      }
  reader.readAsBinaryString(file)
  //insertT('',sText,false);
  }
function onDblClick(e){
  var startPos=Editor.selectionStart,endPos=Editor.selectionEnd;
        var tmpStr = Editor.value;
        var word=tmpStr.substring(startPos,endPos);
        if(/^[a-zA-Z]*$/.test(word))
        {
        word=word.toLowerCase();
        var x=e.pageX,y=e.pageY;
        y=Math.floor((y-6)/24)*24+20;
        x=x-100;x<0?x=1:x;
        $('#fanyi').css({left:x,top:y+10}).show().text(word);
            $.ajax({
    type : "get",
    async : true,
    dataType : "jsonp",
    url : "http://openapi.baidu.com/public/2.0/translate/dict/simple",
    data: {"client_id":"tSg0IcodQGIpm9U8neWsQ11g","from":"en","to":"zh","q":word},
    success : function(data){  
            //$("#showcontent").text("Result:"+data.result)
            if(data.data.length==0)return false;
            if(data.data.symbols.length==0)return false;
            var dst=data.data.symbols[0].parts;
            var str='<span style="color:#c00;font-weight:bold;font-family:Cambria">'+data.data.word_name+'</span>'
            if(data.data.symbols[0].ph_am)str+='<br />`en-us`['+data.data.symbols[0].ph_am+']';
            for(var i=0;i<dst.length;i++){
            dst[i].part?str=str+'<br />'+dst[i].part+','+dst[i].means.join(','):str=str+'<br />'+dst[i].means.join(',');
            
            }
            $('#fanyi').html(str);
        },  
    })
        }
        else
        $('#fanyi').hide();
}
function onPaste(e){
   var Data=window.clipboardData||e.originalEvent.clipboardData;
   if(!Data)return true;
   if(Data.types.length==1&&Data.types[0]=='text/plain')return true;
   else if((Data.types.length==2&&Data.types[1]=='text/html')||(Data.types.length==3&&Data.types[2]=='text/rtf')){
   e.preventDefault();
   var html=Data.getData('text/html');
   html=html.replace(/<html>(\r?\n)+<body>(\r?\n)+<!--StartFragment-->(.*?)<!--EndFragment-->(\r?\n)+<\/body>(\r?\n)+<\/html>/,"$3");
   //var _div=$(document.createElement('div')).appendTo(document.body);_div.text(html);
   html=toMarkdown(html);
   insertT(html,'',false);
   }
   else if((Data.types.length==2&&Data.types[1]=='text/rtf')||(Data.types.length==3&&Data.types[2]=='text/rtf')){
   e.preventDefault();
     html=Data.getData('text/plain');
     //html=html.replace(/■+/g,'-').replace(/'/g,'\'');
    insertT(html,'',false);
       }
   else if(Data.types=='text/html,Files'){
    e.preventDefault();imgReader(Data.items[1])
       }
    else if(Data.types=='Files'){
       e.preventDefault();imgReader(Data.items[0]);
    }
  }
function onDrop(e){
  e.stopPropagation();e.preventDefault();
  if(e.type=='drop'&& e.dataTransfer.types=='Files'){
        Editor.selectionStart=Editor.selectionEnd
        for(var i=0;i<e.dataTransfer.items.length;i++){
        if(e.dataTransfer.items[i].type.indexOf('image')==0)imgReader(e.dataTransfer.items[i]);
        //else if(e.dataTransfer.items[i].type.indexOf('text')==0)textReader(e.dataTransfer.items[i].getAsFile());
            }
        }
    }
function find(isdesc){
  var startPos=Editor.selectionStart,endPos=Editor.selectionEnd;
  var str=document.se.find.value;
  if(str=='')return false;
  var tmpStr=Editor.value,len=str.length;
  if(tmpStr=='')return false;
  //console.log(startPos+','+endPos+','+tmpStr.length);
  if(!isdesc){
  if(startPos==tmpStr.length)startPos=Editor.selectionStart=endPos=Editor.selectionEnd=0;
  var ss=tmpStr.indexOf(str,endPos);
  if(ss>-1){Editor.selectionStart=ss;Editor.selectionEnd=ss+len;}else {alert('已搜到底部');Editor.selectionStart=Editor.selectionEnd=0;}
  }
  else{
  var ss=tmpStr.lastIndexOf(str,startPos-len);
  if(ss>-1){Editor.selectionStart=ss;Editor.selectionEnd=ss+len;}else{alert('已搜到頂部');Editor.selectionStart=Editor.selectionEnd=tmpStr.length;}
  }
}
function replace(isall){
    var str=document.se.find.value,str2=document.se.for.value;
    if(str=='')return false;
    var tmpStr=Editor.value,len=str.length;
    if(tmpStr=='')return false;
    if(isall){
        Editor.value=tmpStr.replace(new RegExp(str,"g"),str2);
        Editor.selectionStart=Editor.selectionEnd=0;
        }
    else{
        var startPos=Editor.selectionStart,endPos=Editor.selectionEnd;
        var ss=tmpStr.indexOf(str,startPos);
          if(ss>-1){
            Editor.value=tmpStr.substring(0,ss)+str2+tmpStr.substr(ss+str.length);
            Editor.selectionStart=ss;Editor.selectionEnd=ss+str2.length;}else {alert('已搜到底部');Editor.selectionStart=Editor.selectionEnd=0;
            }
        
        }
    }

function translate(){
  var startPos=Editor.selectionStart,endPos=Editor.selectionEnd;
    var tmpStr = Editor.value;
    var q=tmpStr.substring(startPos,endPos);
    q=q.replace(/[\*_#`]/g,'').replace(/!?\[(.*?)\](.*?)/g,'$1');
    //alert(q);
    $.ajax({
    type : "get",
    async : true,
    dataType : "jsonp",
    url : "http://openapi.baidu.com/public/2.0/bmt/translate",
    data: {"client_id":"tSg0IcodQGIpm9U8neWsQ11g","from":"en","to":"zh","q":q},
    success : function(data){  
            //$("#showcontent").text("Result:"+data.result)  
            var dst=data.trans_result[0].dst;
            Editor.value=tmpStr.substring(0,endPos)+dst+tmpStr.substr(endPos);
            Editor.selectionStart=Editor.selectionEnd=endPos;
        },  
    })
    //alert(dest);
  }

如今這個文件editor.js文件內容已經超過21K了,全都是我本身動腦筋寫出來的,沒有抄襲任何人。以前我看到有個MarkDown在線編輯器 http://lab.lepture.com/editor/,以爲很喜歡。可是又以爲它不夠完美。如今我本身設計出了本身想要的在線編輯器,editor.js文件的大小隻有http://lab.lepture.com/editor/的editor.js的十分之一。可是它有的功能我基本都作了,並且還作了不少它不具有的功能,好比說Ctrl+.翻譯文章,以及雙擊一個單詞給出它的詞典釋義。json

我打算用它好好翻譯點資料,特別是跟HTML5 API和SVG、其它前端開發方面的資料,以提高本身。我以爲爲了翻譯資料,不得不常常地把文字拷貝到百度翻譯裏,再從百度翻譯拷貝到本身的文本框中,挺費時費力的。api

再放一張這個在線編輯器點下「Ctrl+F」或者點下那個放大鏡按鈕以後產生的結果:服務器

Markdown在線編輯器搜索替換功能

惋惜這個在線編輯器目前還不能用正則表達式搜索替換。併發

相關文章
相關標籤/搜索