知识大全 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(/\\ /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 );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的语句及语法 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!JavaScript所提供的语句分为
知识大全 我是一名前端初学者,我应该怎么学才能少走弯路,适合的前端的编辑器是什么?
我是一名前端初学者,我应该怎么学才能少走弯路,适合的前端的编辑器是什么?前端的主要工作是HTML+CSS+JAVASCRIPT,我曾听到一个比喻,HTML是一个人的话,CSS和JS则是左膀右臂。提高水
语言能力的优势女性运用语言词汇的能力强于男性,在语法、造句、阅读能力等方面更为出色。一般说来,女性从事文字整理、编辑、翻译、播音员以及教育、接待洽谈工作等,更能发挥其特长。思维能力的优势女性在形象思维
怎么学好英语单词和语法。学英语语法切记不可盲目!如果你把语文的语法学通了,要学英语语法那是轻而易举的。而你只是一心要学好英语语法,却不注重将之融会贯通,那你就会越学越觉得烦、难,进而对学习英语语法、英
***正则表达式语法(字符匹配语法重复匹配语法字符定位语法转义匹配语法)******** (字符 \\ 将下一个字符标记为
学了谢孟媛的语法还要学新概念英语的语法吗我认为结合学比较好。谢孟媛文法要听细,学透。特别要学习她的做题方法哦,顶呱呱滴。新概念的就拿来多读吧,有助于提高口语。语法不是学得越多就越好,是要学得扎实、深刻
木门是家居装修的一大亮点,幽雅精致的木门,不但起到了隔离空间的作用,更为居家生活平添了几分色彩。在选购木门的时候,应注意以下几点:(1)重质量木门制造工艺的好坏直接影响着门的使用寿命,一般来说木门使用
XPath语法 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! XPath的语法 &nb
知识大全 我们现在学习的英语语法是外国人发明的,还是中国人总结
我们现在学习的英语语法是外国人发明的,还是中国人总结外国人也是人。中国人学语法,外国人怎么可能不学语法呢?中国人也不是所有人都学语法。外国人也不是所有人都学语法。语法是语言的规律,语言的规则。凡是语言