转至繁体中文版     | 网站首页 | 图文教程 | 资源下载 | 站长博客 | 图片素材 | 武汉seo | 武汉网站优化 | 
最新公告:     敏韬网|教学资源学习资料永久免费分享站!  [mintao  2008年9月2日]        
您现在的位置: 学习笔记 >> 图文教程 >> 站长学院 >> Web开发 >> 正文
javascript实现语法分色编辑器         ★★★★

javascript实现语法分色编辑器

作者:闵涛 文章来源:闵涛的学习笔记 点击数:1561 更新时间:2009/4/23 11:23:07
 

最近一段时间忽然想到用javascript理论上可以实现一个复杂的在线编辑器,完全能够支持词法、语法方面的功能,于是试验了一下...效率和简易程度还是令人吃惊的,看来javascript比想象的还要强大...

<html>
 <head>
  <title>Silverna Demo Ver 0.01</title>
  <style>
   div.editbox{
    margin:0 0 0 0;
    padding:0 0 0 0;
    font:16/18px Arial;
    border:0px solid #000000;
   }
   p{
    margin:0 0 0 0;
    padding:0 0 0 0;
   }
  </style>
 </head>

 <body style="margin:0 0 0 0;padding:0 0 0 0;word-break:break-all;overflow-x:hidden" onload="editbox.focus()">
 <div id="editbox" class="editbox" style="width:99%;height:80%;" contentEditable="true" onkeyDown="return KeyDown()" onkeyUp="KeyUp()" onclick="getCursorPosition()">
 </div>
 <select size="10" style="display:none;position:absolute" id="methods" onkeydown="SelectMethod()" onclick="SelMethod(this)">
 </body>
</html>


</select>
<script language=JScript>
var testArray = new Array();
var testDate = new Date();
var testString = "aaa";
var testVal = 1;
var testObj = new myObj;

function myObj()
{
     myObj.prototype.testFunc = function(){};
  this.testProperty = "test";
}
function KeyDown()
{
 //alert(event.altKey);
 if(event.keyCode == 9) //TAB 键
 {
  clipboardData.setData('text','    ');
  event.srcElement.document.execCommand('paste');
  return false;  
 }
 if(event.keyCode == 8) //Backspace 键
 {
  var oSel = document.selection.createRange();
  var offset = event.srcElement.document.selection.createRange();
  offset.moveToPoint(oSel.offsetLeft, oSel.offsetTop);
  offset.moveStart('character', -4);
  if(offset.text.length < 4) return true;
  for (var i = 0; i < offset.text.length; i++)
  {
   if (offset.text.charAt(i) != " ")
   {
    return true;
   }
  }
  offset.select();
  event.srcElement.document.execCommand('Delete');
  return false;  
 }
 return true;
}

function KeyUp()
{
 var oSel, offset;
 if(event.keyCode == 13)
 {
  testStr = event.srcElement.innerText.substring(0, getCursorPosition());
  //alert(testStr);
  var space = "";
  for (var i = testStr.length - 1; i >= 0; i--)
  {
   //alert(testStr.length+":"+testStr.charAt(i) + ":" + space.length);
   if (testStr.charAt(i) == "\n") break;
   if (testStr.charAt(i) == " ")
    space += " ";
   else
    space = "";
  }
  //alert(testStr);
  clipboardData.setData('text',space);
  event.srcElement.document.execCommand('paste');
 }
 oSel = document.selection.createRange();
 var left = oSel.offsetLeft;
 var top = oSel.offsetTop;
    var token = getCurrentToken(event.srcElement);
 var chars = getCursorPosition();

 parseSyntax(event.srcElement);
 offset = event.srcElement.document.selection.createRange();
 offset.moveToPoint(left, top);
 offset.select();

 if(event.keyCode == 190) //.键
 {
  setMethods(token.posTok.slice(0, -1));
 }
}

function parseSyntax(src)  //解析当前文本
{  
 var text = src.innerHTML;
 text = text.replace(/<FONT[^<>]*>/gi, "").replace(/<\/FONT[^<>]*>/gi,"");
 text = text.replace(/<P>/gi, "\xfe").replace(/<\/P>/gi, "\xff");
 text = text.replace(/\&nbsp;/gi, "\xfd");
 text = text.replace(/\r\n/gi,"");
 
 for (var i = 0; i <SyntaxSet.All.length; i++)
 {
  var syntaxes = SyntaxSet.All[i];
  for (var j = 0; j < syntaxes.rules.All.length; j++)
  {
   syntaxes.rules.All[j].color = syntaxes.color;
   syntaxes.rules.All[j].cons = syntaxes.cons;

   text = parseRule(text, syntaxes.rules.All[j]);
  }
 }

 src.innerHTML = text.replace(/\xfc/g,"'").replace(/\xfe/g,"<P>").replace(/\xff/g,"</P>").replace(/\xfd/g,"&nbsp;");
}
function parseRule(text, rule)  //解析词法
{
 //利用正则表达式
 var newText = "";

 var idx = text.search(rule.expr);

 while (idx != -1)
 {
  var remark = text.match(rule.expr);
  //alert(text.substring(0, idx+remark[0].length));
  var subText = text.substring(0, idx + remark[0].length);

  if(rule.cons == null || (idx == 0 || rule.cons.test(text.charAt(idx-1))) && (idx + remark[0].length >= text.length || rule.cons.test(text.charAt(idx + remark[0].length))))
  {
   //alert(remark[0]);
   //alert(remark[0].replace(/<FONT[^<>]*>/gi, "").replace(/<\/FONT[^<>]*>/gi,""));
   subText = subText.replace(remark[0], "<FONT color=\xfc"+rule.color+"\xfc>" + remark[0].replace(/<FONT[^<>]*>/gi, "").replace(/<\/FONT[^<>]*>/gi,"") + "</FONT>");
   //alert(subText);
  }
  newText += subText;
  text = text.substring(idx + remark[0].length);
  idx = text.search(rule.expr);
 }
 newText += text;
 return newText;
}

function getCurrentToken(src)
{
 var oSel = document.selection.createRange();
 var offset = src.document.selection.createRange();
 offset.moveToPoint(oSel.offsetLeft, oSel.offsetTop);
 offset.moveStart("character", -99999);

 var tokens = offset.text.split(/[\s\+\-\*\/]/);  //token由连续字母数字、下划线、点号、括号、引号构成
 var currentToken = tokens[tokens.length - 1];

 var idx = offset.text.length;

 var fullToken = src.innerText.substring(idx);
 fullToken = fullToken.replace(/[\s\+\-\*\/]/,"@@@@");

 idx = fullToken.indexOf("@@@@");
 if(idx != -1)
  fullToken = fullToken.substring(0, idx);

 var token = new Array();

 token.currentToken = currentToken + fullToken;
 token.posTok = currentToken;

 return token;
}
Array.prototype.pushDistinct = function(obj)
{
 for (var i = 0; i < this.length; i++)
 {
  if (this[i] == obj)
  {
   return null;
  }
 }
 this.push(obj);
 return obj;
}

function putMethods(methodList, obj, methods)  //将方法添加到方法列表
{
 var list = methods.split(",");

 for (var i = 0; i < list.length; i++)
 {
  if (obj[list[i]] != null)
  {
   methodList.pushDistinct(list[i]);
  }
 }
}
var now = new Date(); //测试用
var a = 33.3333; //测试用
var __expr = new RegExp("tt"); //测试用
function setMethods(objStr)
{
  var oSel = document.selection.createRange();

  try
  {
   if (objStr == "alert") return;
   var methodList = new Array();
   var obj = eval(objStr);

   if (obj.prototype != null)
   {
    methodList.pushDistinct("prototype");
   }
   if (obj != null)
   {

    //基本Object方法
    putMethods(methodList, obj,"constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf");
    
    //基本Array方法
    putMethods(methodList, obj,"concat,join,length,pop,push,reverse,shift,slice,sort,splice,unshift");     

    //基本Date方法
    putMethods(methodList,obj,"getDate,getUTCDate,getDay,getUTCDay,getFullYear,getUTCFullYear,getHours,getUTCHours,getMilliseconds,getUTCMilliseconds,getMinutes,getUTCMinutes,getMonth,getUTCMonth,getSeconds,getUTCSeconds,getTime,getTimezoneoffset,getYear");

    putMethods(methodList,obj,"setDate,setUTCDate,setFullYear,setUTCFullYear,setHours,setUTCHours,setMilliseconds,setUTCMilliseconds,setMinutes,setUTCMinutes,setMonth,setUTCMonth,setSeconds,setUTCSeconds,setTime,setYear,toDateString,toGMTString,toLocaleDateString,toLocaleTimeString,toString,toTimeString,toUTCString,valueOf,parse,UTC");

    //基本Math方法
    putMethods(methodList,obj,"E,LN10,LN2,LOG10E,LOG2E,PI,SQRT1_2,SQRT2");
    putMethods(methodList,obj,"abs,acos,asin,atan,atan2,ceil,cos,exp,floor,log,max,min,pow,random,round,sin,sqrt,tan");

    //基本Function方法
    putMethods(methodList,obj,"arguments,caller,length,prototype,apply,call,toString");
    
    //基本Number方法
    putMethods(methodList,obj,"MAX_VALUE,MIN_VALUE,NaN

[1] [2]  下一页


没有相关教程
教程录入:mintao    责任编辑:mintao 
  • 上一篇教程:

  • 下一篇教程:
  • 【字体: 】【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
      注:本站部分文章源于互联网,版权归原作者所有!如有侵权,请原作者与本站联系,本站将立即删除! 本站文章除特别注明外均可转载,但需注明出处! [MinTao学以致用网]
      网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)

    同类栏目
    · Web开发  · 网页制作
    · 平面设计  · 网站运营
    · 网站推广  · 搜索优化
    · 建站心得  · 站长故事
    · 互联动态
    更多内容
    热门推荐 更多内容
  • 没有教程
  • 赞助链接
    更多内容
    闵涛博文 更多关于武汉SEO的内容
    500 - 内部服务器错误。

    500 - 内部服务器错误。

    您查找的资源存在问题,因而无法显示。

    | 设为首页 |加入收藏 | 联系站长 | 友情链接 | 版权申明 | 广告服务
    MinTao学以致用网

    Copyright @ 2007-2012 敏韬网(敏而好学,文韬武略--MinTao.Net)(学习笔记) Inc All Rights Reserved.
    闵涛 投放广告、内容合作请Q我! E_mail:admin@mintao.net(欢迎提供学习资源)

    站长:MinTao ICP备案号:鄂ICP备11006601号-18

    闵涛站盟:医药大全-武穴网A打造BCD……
    咸宁网络警察报警平台