知识大全 javascript实现语法分色编辑器

Posted 词法

篇首语:树高千尺有根,水流万里有源。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 javascript实现语法分色编辑器相关的知识,希望对你有一定的参考价值。

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

  <> <head>  <title>Silverna Demo Ver </title>  <style>   div editbox    margin: ;    padding: ;    font: / px Arial;    border: px solid # ;      p    margin: ;    padding: ;     </style> </head>

  <body onload= editbox focus() > <div id= editbox class= editbox contentEditable= true onkeyDown= return KeyDown() onkeyUp= KeyUp() onclick= getCursorPosition() > </div> <select size= id= methods onkeydown= SelectMethod() onclick= SelMethod(this) > </body></>

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

  function myObj()     myObj prototype testFunc = function();  this testProperty = test ;function KeyDown() //alert(event altKey); if(event keyCode == ) //TAB 键   clipboardData setData( text     );   event srcElement document execCommand( paste );   return false;    if(event keyCode == ) //Backspace 键   var oSel = document selection createRange();  var offset = event srcElement document selection createRange();  offset moveToPoint(oSel offsetLeft oSel offsetTop);  offset moveStart( character );  if(offset text length < ) return true;  for (var i = ; 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 == )   testStr = event srcElement innerText substring( getCursorPosition());  //alert(testStr);  var space = ;  for (var i = testStr length ; i >= ; 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 == ) // 键   setMethods(token posTok slice( )); 

  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 = ; i <SyntaxSet All length; i++)   var syntaxes = SyntaxSet All[i];  for (var j = ; j < syntaxes rules All length; j++)     syntaxes rules All[lor = lor;   syntaxes rules All[ns = ns;

  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 != )   var remark = text match(rule expr);  //alert(text substring( idx+remark[ ] length));  var subText = text substring( idx + remark[ ] length);

  if(ns == null || (idx == || ns test(text charAt(idx ))) && (idx + remark[ ] length >= text length || ns test(text charAt(idx + remark[ ] length))))     //alert(remark[ ]);   //alert(remark[ ] replace(/<FONT[^<>]*>/gi ) replace(/<\\/FONT[^<>]*>/gi ));   subText = subText replace(remark[ ] <FONT color=\\xfc +lor+ \\xfc> + remark[ ] replace(/<FONT[^<>]*>/gi ) replace(/<\\/FONT[^<>]*>/gi ) + </FONT> );   //alert(subText);    newText += subText;  text = text substring(idx + remark[ ] 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 );

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

  var idx = offset text length;

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

  idx = fullToken indexOf( @@@@ ); if(idx != )  fullToken = fullToken substring( idx);

  var token = new Array();

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

  return token;Array prototype pushDistinct = function(obj) for (var i = ; 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 = ; i < list length; i++)   if (obj[list[i]] != null)     methodList pushDistinct(list[i]);   var now = new Date(); //测试用var a = ; //测试用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 LN LN LOG E LOG E PI SQRT _ SQRT );    putMethods(methodList obj abs acos asin atan atan 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 NEGATIVE_INFINITY POSITIVE_INFINITY );    putMethods(methodList obj toString toLocalString toFixed toExponential toPrecision );

  //基本RegExp方法    putMethods(methodList obj global ignoreCase lastIndex multiline source exec test );

  //基本String方法    putMethods(methodList obj charAt charCodeAt contact indexOf lastIndexOf match replace search slice split substring substr toLowerCase toString toUpperCase valueOf fromCharCode );    putMethods(methodList obj anchor big blink bold fixed fontcolor fontsize italics link small strike sub sup );

     for (each in obj)       methodList pushDistinct(each);      methodList sort();

  if (methodList length > )       methods options length = ;    for (var i = ; i < methodList length; i++)         methods options add(new Option(methodList[i]));         if (methods options length > )         methods size = ;        else         methods size = methods options length;        methods style top = oSel offsetTop;    methods style left = oSel offsetLeft;    methods style display = ;    methods options[ ] selected = true;    methods focus();       catch(e)

  function SelectMethod() var src = event srcElement; if(event keyCode == )   SelMethod(src); 

  if(event keyCode == || event keyCode == || event keyCode == )   src style display = none ;  editbox focus(); 

  function SelMethod(src) clipboardData setData( text src options[src selectedIndex] text); editbox focus(); editbox document execCommand( paste );  src style display = none ; getCursorPosition();function getPos(text) //计算行数 列数 var rows = ; var cols = ; var idx = ; var subText = text; while((idx = subText indexOf( \\n )) != )   subText = subText substring(idx + );  rows++;  return new Array(rows subText length + );function getNullRows(src oSel) //计算空行 var rows = ;

  var offsetEnd = src document selection createRange();

  var oldTop = ; var oldLeft = ;

  while( )   offsetEnd moveToPoint(oSel offsetLeft oSel offsetTop);  offsetEnd moveStart( character rows);

  if (offsetEnd text length > || offsetEnd offsetTop == oldTop && offsetEnd offsetLeft == oldLeft)     break;  

  rows ++;  oldTop = offsetEnd offsetTop;  oldLeft = offsetEnd offsetLeft;   return rows;function getCursorPosition() var src = event srcElement; var offset = src document selection createRange(); var oSel = document selection createRange();

  var textLength = src innerText length;

  offset moveToPoint(oSel offsetLeft oSel offsetTop); offset moveStart( character ); //src document execCommand( ForeColor false #ff ); var rowSpans = offset getClientRects();

  var pos = getPos(offset text);   var charCodes = offset text length; //字符总数 var chars = offset text replace(/\\r\\n/g ) length + ; //字符

  var extRows = getNullRows(src oSel); if(extRows > )   pos[ ] += extRows;  pos[ ] = ;  window status = 行: + pos[ ] + 列: + pos[ ] + 第 + chars + 个字符 +   ( + oSel offsetTop + +  oSel offsetLeft + ) ; return charCodes;

  ///词法解析过程 /// ///

  var SyntaxSet = new Array(); //词法规则集合SyntaxSet All = new Array();

  SyntaxSet parse = function(token)   //针对token返回rule for (var i = ; i < this All length; i++)   var syntaxes = this All[i];  for (var j = ; j < syntaxes rules All length; j++)     if (syntaxes rules All[j] test(token))       syntaxes rules All[lor = lor;    return syntaxes rules All[j];      

  return null;

  SyntaxSet add = function(syntaxes) if(this[syntaxes name] != null)  return; this[syntaxes name] = syntaxes; this All push(syntaxes);

  function Syntaxes(name color cons) //词法规则组(同组规则用一种颜色标记) this name = name; //规则组名称 lor = color;  //标记该语法的颜色 this rules = new Array();  //语法规则(以次序决定优先级) this rules All = new Array(); ns = cons;  //边界约束

  Syntaxes prototype addRule = function(rule)   if(this rules[rule name] != null)   return;  this rules[rule name] = rule;  this rules All push(rule); 

  function SyntaxRule(name regExp)  //词法规则 this name = name;    //规则名称    this expr = regExp;  //规则描述 (正则表达式) SyntaxRule prototype test = function(token)   return this expr test(token); 

  function RegExprX(exprStr)  //扩展正则表达式的功能 支持定义嵌套 this expr = exprStr;RegExprX prototype getPattern = function(tag)  //获取正则表达式对象 if (tag == null)  return new RegExp(this expr); else  return new RegExp(this expr tag);Rencat = function(expr rule)  //连接两个正则表达式串 if (rule == null)  this expr += expr;  //直接连接 else if (rule == union )  //联合  this expr = ( + this expr + ) + | + ( + expr + ) ;   else if (rule == cons ) //约束  this expr = this expr + (?= + expr + ) ; return this expr;

  //为保证正确计算偏移量需要替换回车\\n\\r为\\xffSyntaxSet add(new Syntaxes( keywords # ff /[\\s\\ \\xfe\\xff\\xfd\\(\\\\\\)\\;\\ ]/));  //词法?关键词?蓝色SyntaxSet[ keywords ] addRule(new SyntaxRule( Function /function/));SyntaxSet[ keywords ] addRule(new SyntaxRule( Variable /var/));SyntaxSet[ keywords ] addRule(new SyntaxRule( Return /return/));SyntaxSet[ keywords ] addRule(new SyntaxRule( Exception /(try|catch|throw)/));SyntaxSet[ keywords ] addRule(new SyntaxRule( Condition /(if|else|switch)/));SyntaxSet[ keywords ] addRule(new SyntaxRule( Cycle /(for|while|do)/));SyntaxSet[ keywords ] addRule(new SyntaxRule( Type /(int|double|float|void|char)/));SyntaxSet[ keywords ] addRule(new SyntaxRule( Right /(public|private|protected|static)/));SyntaxSet[ keywords ] addRule(new SyntaxRule( Constant /(null|undefined|NaN|Infinity)/));SyntaxSet[ keywords ] addRule(new SyntaxRule( Construct /(new|delete)/));

  SyntaxSet add(new Syntaxes( objects #FF /[\\s\\ \\xfe\\xff\\xfd\\(\\\\\\)\\;\\ ]/));  //词法?对象?红色SyntaxSet[ objects ] addRule(new SyntaxRule( Object /(Array|arguments|Boolean|Date|Error|Function|Object|Number|Math|RegExp|String)/));

  SyntaxSet add(new Syntaxes( global # /[\\s\\ \\xfe\\xff\\xfd\\(\\\\\\)\\;\\ ]/));  //词法?系统函数?红色SyntaxSet[ global ] addRule(new SyntaxRule( SystemFunc /(alert|parseFloat|parseInt|eval|decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|escape|eval|isFinite|isNaN|unescape)/));

  SyntaxSet add(new Syntaxes( String #ff ff /[\\s\\ \\xfe\\xff\\xfd\\(\\\\\\)\\;\\ \\+\\ \\*\\/]/));  //词法?字符串?粉色SyntaxSet[ String ] addRule(new SyntaxRule( String        /( ((\\\\\\ )|[^\\xff\\ ])*([^\\\\\\ ]|(\\\\\\ )) )|( ((\\\\\\ )|[^\\xff\\ ])*([^\\\\\\ ]|(\\\\\\ )) )/));

  SyntaxSet add(new Syntaxes( remarks # )); //词法?注释?绿色SyntaxSet[ remarks ] addRule(new SyntaxRule( ShortRemark /\\/\\/[^\\xff]*/));SyntaxSet[ remarks ] addRule(new SyntaxRule( LongRemark /\\/\\*(( *\\*\\/)|( *$))/));

cha138/Article/program/Java/JSP/201311/19446

相关参考

知识大全 JavaScript获取FCK编辑器信息的具体方法

JavaScript获取FCK编辑器信息的具体方法  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!这

知识大全 JS的语句及语法

JS的语句及语法  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!JavaScript所提供的语句分为

知识大全 我是一名前端初学者,我应该怎么学才能少走弯路,适合的前端的编辑器是什么?

我是一名前端初学者,我应该怎么学才能少走弯路,适合的前端的编辑器是什么?前端的主要工作是HTML+CSS+JAVASCRIPT,我曾听到一个比喻,HTML是一个人的话,CSS和JS则是左膀右臂。提高水

知识大全 女孩子的面试优势

语言能力的优势女性运用语言词汇的能力强于男性,在语法、造句、阅读能力等方面更为出色。一般说来,女性从事文字整理、编辑、翻译、播音员以及教育、接待洽谈工作等,更能发挥其特长。思维能力的优势女性在形象思维

知识大全 怎么学好英语单词和语法。

怎么学好英语单词和语法。学英语语法切记不可盲目!如果你把语文的语法学通了,要学英语语法那是轻而易举的。而你只是一心要学好英语语法,却不注重将之融会贯通,那你就会越学越觉得烦、难,进而对学习英语语法、英

知识大全 正则表达式语法及实例整理

  ***正则表达式语法(字符匹配语法重复匹配语法字符定位语法转义匹配语法)********  (字符  \\      将下一个字符标记为

知识大全 学了谢孟媛的语法还要学新概念英语的语法吗

学了谢孟媛的语法还要学新概念英语的语法吗我认为结合学比较好。谢孟媛文法要听细,学透。特别要学习她的做题方法哦,顶呱呱滴。新概念的就拿来多读吧,有助于提高口语。语法不是学得越多就越好,是要学得扎实、深刻

如何选购木门?

木门是家居装修的一大亮点,幽雅精致的木门,不但起到了隔离空间的作用,更为居家生活平添了几分色彩。在选购木门的时候,应注意以下几点:(1)重质量木门制造工艺的好坏直接影响着门的使用寿命,一般来说木门使用

知识大全 XPath语法

XPath语法  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  XPath的语法 &nb

知识大全 我们现在学习的英语语法是外国人发明的,还是中国人总结

我们现在学习的英语语法是外国人发明的,还是中国人总结外国人也是人。中国人学语法,外国人怎么可能不学语法呢?中国人也不是所有人都学语法。外国人也不是所有人都学语法。语法是语言的规律,语言的规则。凡是语言