html/js编辑器
2006-08-13 21:24 清炒白菜 阅读(802) 评论(0) 编辑 收藏 举报
在找JS的POP,PUSH用法的时候,无意中发现的,感觉还不错,收藏一下.
1<html>
2 <head>
3 <title>Silverna Demo Ver 0.01</title>
4 <style>
5 div.silverna__ctr__editbox{
6 margin:0 0 0 0;
7 padding:0 0 0 0;
8 font:16/18px Arial;
9 width:99%;
10 height:480px;
11 border:1px solid #000000;
12 overflow-y:scroll;
13 }
14 p{
15 margin:0 0 0 0;
16 padding:0 0 0 0;
17 }
18 </style>
19 </head>
20
21 <body style="margin:0 0 0 0;padding:0 0 0 0;word-break:break-all;overflow-x:hidden" onload="__silverna__ctr__editbox.focus()">
22 <div id="__silverna__ctr__editbox" class="silverna__ctr__editbox" contentEditable="true" onkeyDown="return KeyDown()" onkeyUp="KeyUp()" onmouseup="__silverna__ctr__methods.style.display='none';getCursorPosition();">
23 </div>
24 <select size="6" style="display:none;position:absolute" id="__silverna__ctr__methods" onkeyup="SelectMethod()" onclick="SelMethod(this)">
25 </body>
26</html>
27
28
29</select>
30<script language=JScript>
31function KeyDown()
32{
33 if(__silverna__ctr__methods.style.display != 'none')
34 {
35 if (event.keyCode == 38 || event.keyCode == 40 || event.keyCode == 13
36 || event.keyCode == 33 || event.keyCode == 34)
37 {
38 __silverna__ctr__methods.focus();
39 }
40 else
41 __silverna__ctr__methods.style.display = 'none';
42 }
43 if(event.keyCode == 9)
44 {
45 clipboardData.setData('text',' ');
46 event.srcElement.document.execCommand('paste');
47 return false;
48 }
49 if(event.keyCode == 8)
50 {
51 var oSel = document.selection.createRange();
52 var offset = event.srcElement.document.selection.createRange();
53 offset.moveToPoint(oSel.offsetLeft, oSel.offsetTop);
54 offset.moveStart('character', -4);
55 if(offset.text.length < 4) return true;
56 for (var i = 0; i < offset.text.length; i++)
57 {
58 if (offset.text.charAt(i) != " ")
59 {
60 return true;
61 }
62 }
63 offset.select();
64 event.srcElement.document.execCommand('Delete');
65 return false;
66 }
67 return true;
68}
69
70function KeyUp()
71{
72 var oSel, offset;
73 if(event.keyCode == 13)
74 {
75 testStr = event.srcElement.innerText.substring(0, getCursorPosition());
76 var space = null;
77 for (var i = testStr.length - 1; i >= 0; i--)
78 {
79 if (testStr.charAt(i) == "\n") break;
80 if (testStr.charAt(i) == " ")
81 {
82 if(space != null) space += " ";
83 }
84 else
85 {
86 space = "";
87 }
88 }
89 var backupData = clipboardData.getData('text');
90 if(space != null)
91 {
92 clipboardData.clearData();
93 clipboardData.setData('text',space);
94 event.srcElement.document.execCommand('paste');
95 }
96 if(backupData != null)
97 {
98 clipboardData.setData('text',backupData);
99 }
100 }
101 oSel = document.selection.createRange();
102 var left = oSel.offsetLeft;
103 var top = oSel.offsetTop;
104var token = getCurrentToken(event.srcElement);
105 var chars = getCursorPosition();
106
107 if (event.keyCode == 38 || event.keyCode == 40
108 || event.keyCode == 33 || event.keyCode == 34)
109 {
110 return true;
111 }
112 parseSyntax(event.srcElement);
113 offset = event.srcElement.document.selection.createRange();
114 offset.moveToPoint(left, top);
115 offset.select();
116
117 if(!event.shiftKey && event.keyCode == 190)
118 {
119 setMethods(token.posSent.slice(0, -1));
120 }
121}
122
123function parseSyntax(src)
124{
125 var text = src.innerHTML;
126 text = text.replace(/<FONT[^<>]*>/gi, "").replace(/<\/FONT[^<>]*>/gi,"");
127 text = text.replace(/<BR>/gi,"\xff\xfe");
128 text = text.replace(/<P>/gi, "\xfe").replace(/<\/P>/gi, "\xff");
129 text = text.replace(/\ /gi, "\xfd");
130 text = text.replace(/\</gi, "\xdf");
131 text = text.replace(/\>/gi, "\xdd");
132 text = text.replace(/\r\n/gi,"");
133
134 for (var i = 0; i <SyntaxSet.All.length; i++)
135 {
136 var syntaxes = SyntaxSet.All[i];
137 for (var j = 0; j < syntaxes.rules.All.length; j++)
138 {
139 text = parseRule(text, syntaxes.rules.All[j]);
140 }
141 }
142
143 src.innerHTML = text.replace(/\xde/g,"").replace(/\xfc/g,"'").replace(/\xfe/g,"<P>").replace(/\xff/g,"</P>").replace(/\xfd/g," ").replace(/\xdf/g,"<").replace(/\xdd/g,">");
144}
145function parseRule(text, rule)
146{
147 var newText = "";
148
149 var idx = text.search(rule.expr);
150
151 while (idx != -1)
152 {
153 var remark = text.match(rule.expr);
154 var subText = text.substring(0, idx + remark[0].length);
155 if(rule.parent.fcons == null || (idx == 0 || rule.parent.fcons.test(text.charAt(idx-1))) && (idx + remark[0].length >= text.length || rule.parent.bcons.test(text.charAt(idx + remark[0].length))))
156 {
157 var subToken = remark[0].replace(/<FONT[^<>]*>/gi, "").replace(/<\/FONT[^<>]*>/gi,"");
158 for (var i = 0; i < rule.subRules.length; i++)
159 {
160 subToken = parseRule(subToken, rule.subRules[i]);
161 }
162 subText = subText.replace(remark[0], "<FONT \xdecolor=\xfc"+rule.parent.color+"\xfc>" + subToken + "</FONT>");
163 }
164 newText += subText;
165 text = text.substring(idx + remark[0].length);
166 idx = text.search(rule.expr);
167 }
168 newText += text;
169 return newText;
170}
171
172function getCurrentToken(src)
173{
174 var oSel = document.selection.createRange();
175 var offset = src.document.selection.createRange();
176 offset.moveToPoint(oSel.offsetLeft, oSel.offsetTop);
177 offset.moveStart("character", -99999);
178
179 var sentences = offset.text.split(/[;}{]/g);
180 var currentSentence = sentences[sentences.length - 1];
181
182 var tokens = offset.text.split(/[\s\+\-\*\/]/);
183 var currentToken = tokens[tokens.length - 1];
184
185 var idx = offset.text.length;
186
187 var fullSentence = src.innerText.substring(idx);
188 fullToken = fullSentence.replace(/[\n$]/,"@@@@");
189 idx = fullSentence.indexOf("@@@@");
190 if(idx != -1)
191 fullSentence = fullSentence.substring(0, idx);
192
193 var fullToken = src.innerText.substring(idx);
194 fullToken = fullToken.replace(/[\s\+\-\*\/$]/,"@@@@");
195 idx = fullToken.indexOf("@@@@");
196 if(idx != -1)
197 fullToken = fullToken.substring(0, idx);
198
199 var token = new Array();
200
201 token.currentToken = currentToken + fullToken;
202 token.posTok = currentToken;
203
204 token.posSent = currentSentence;
205 token.currentSentence = currentSentence + fullSentence;
206
207 return token;
208}
209Array.prototype.pushDistinct = function(obj)
210{
211 for (var i = 0; i < this.length; i++)
212 {
213 if (this[i] == obj)
214 {
215 return null;
216 }
217 }
218 this.push(obj);
219 return obj;
220}
221
222function putMethods(methodList, obj, methods)
223{
224 var list = methods.split(",");
225
226 for (var i = 0; i < list.length; i++)
227 {
228 if (obj[list[i]] != null)
229 {
230 methodList.pushDistinct(list[i]);
231 }
232 }
233}
234function parseObj(objStr)
235{
236 var cont = 0;
237 var sont = 0;
238 for (var i = objStr.length - 1; i >= 0; i--)
239 {
240 if (objStr.charAt(i) == ")")
241 cont ++;
242 if (objStr.charAt(i) == "(")
243 cont --;
244 if (objStr.charAt(i) == "]")
245 sont ++;
246 if (objStr.charAt(i) == "[")
247 sont --;
248 if (cont == 0 && sont == 0 && /[\+\-\*\/\=\,\;\&\|\>\<]/.test(objStr.charAt(i)))
249 break;
250 if (cont < 0 || sont < 0)
251 break;
252 }
253 return objStr.substring(i+1);
254}
255//将对象的方法放到Select Object中显示出来,并且初始化不可列举方法
256function setMethods(objStr)
257{
258 var oSel = document.selection.createRange();
259 objStr = parseObj(objStr);
260 objStr = objStr.replace(/alert/g,"Object");
261 var funs = getObjects(event.srcElement);
262 var vars = getVariables(event.srcElement);
263
264 for (var __silverna_i = 0; __silverna_i < funs.length; __silverna_i++)
265 {
266 try{eval(funs[__silverna_i]);} catch(e){};
267 }
268 for (var __silverna_i = 0; __silverna_i < vars.length; __silverna_i++)
269 {
270 try{eval(vars[__silverna_i]);}catch(e){};
271 }
272 if(event.srcElement.style.display == 'none')
273 {
274 event.srcElement.style.display = '';
275 event.srcElement.focus();
276 }
277 try
278 {
279 var methodList = new Array();
280 var obj = eval(objStr);
281
282 if (obj.prototype != null)
283 {
284 methodList.pushDistinct("prototype");
285 }
286 if (obj != null)
287 {
288
289 //基本Object方法
290 putMethods(methodList, obj,"constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf");
291
292 //基本Array方法
293 putMethods(methodList, obj,"concat,join,length,pop,push,reverse,shift,slice,sort,splice,unshift");
294
295 //基本Date方法
296 putMethods(methodList,obj,"getDate,getUTCDate,getDay,getUTCDay,getFullYear,getUTCFullYear,getHours,getUTCHours,getMilliseconds,getUTCMilliseconds,getMinutes,getUTCMinutes,getMonth,getUTCMonth,getSeconds,getUTCSeconds,getTime,getTimezoneoffset,getYear");
297
298 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");
299
300 //基本Math方法
301 putMethods(methodList,obj,"E,LN10,LN2,LOG10E,LOG2E,PI,SQRT1_2,SQRT2");
302 putMethods(methodList,obj,"abs,acos,asin,atan,atan2,ceil,cos,exp,floor,log,max,min,pow,random,round,sin,sqrt,tan");
303
304 //基本Function方法
305 putMethods(methodList,obj,"arguments,caller,length,prototype,apply,call,toString");
306
307 //基本Number方法
308 putMethods(methodList,obj,"MAX_VALUE,MIN_VALUE,NaN,NEGATIVE_INFINITY,POSITIVE_INFINITY");
309 putMethods(methodList,obj,"toString,toLocalString,toFixed,toExponential,toPrecision");
310
311 //基本RegExp方法
312 putMethods(methodList,obj,"global,ignoreCase,lastIndex,multiline,source,exec,test");
313
314 //基本String方法
315 putMethods(methodList,obj,"charAt,charCodeAt,contact,indexOf,lastIndexOf,match,replace,search,slice,split,substring,substr,toLowerCase,toString,toUpperCase,valueOf,fromCharCode");
316 putMethods(methodList,obj,"anchor,big,blink,bold,fixed,fontcolor,fontsize,italics,link,small,strike,sub,sup");
317
318 }
319 for (each in obj)
320 {
321 methodList.pushDistinct(each);
322 }
323 methodList.sort();
324
325 if (methodList.length > 0)
326 {
327 __silverna__ctr__methods.options.length = 0;
328 for (var __silverna_i = 0; __silverna_i < methodList.length; __silverna_i++)
329 {
330 __silverna__ctr__methods.options.add(new Option(methodList[__silverna_i]));
331 }
332 if (__silverna__ctr__methods.options.length > 6)
333 {
334 __silverna__ctr__methods.size = 6;
335 }
336 else
337 {
338 __silverna__ctr__methods.size = __silverna__ctr__methods.options.length;
339 }
340 __silverna__ctr__methods.style.top = oSel.offsetTop;
341 __silverna__ctr__methods.style.left = oSel.offsetLeft;
342 __silverna__ctr__methods.style.display = "";
343 __silverna__ctr__methods.options[0].selected = true;
344 }
345 return true;
346 }
347 catch(e){return false;}
348}
349
350function SelectMethod()
351{
352 var src = event.srcElement;
353 if(event.keyCode == 13 || event.keyCode == 32)
354 {
355 SelMethod(src);
356 }
357
358 if(event.keyCode == 27 || event.keyCode == 8)
359 {
360 src.style.display = "none";
361 __silverna__ctr__editbox.focus();
362 }
363}
364function SelMethod(src)
365{
366 var backupData = clipboardData.getData('text');
367 clipboardData.setData('text',src.options[src.selectedIndex].text);
368 __silverna__ctr__editbox.focus();
369 __silverna__ctr__editbox.document.execCommand('paste');
370 src.style.display = "none";
371 getCursorPosition();
372 if(backupData != null)
373 {
374 clipboardData.setData('text',backupData);
375 }
376}
377
378function getPos(text)
379{
380 var rows = 1;
381 var cols = 1;
382 var idx = 0;
383 var subText = text;
384 while((idx = subText.indexOf("\n")) != -1)
385 {
386 subText = subText.substring(idx + 1);
387 rows++;
388 }
389 return new Array(rows, subText.length + 1);
390}
391function getNullRows(src,oSel)
392{
393 var rows = 0;
394
395 var offsetEnd = src.document.selection.createRange();
396
397 var oldTop = 2;
398 var oldLeft = 2;
399
400 while(1)
401 {
402 offsetEnd.moveToPoint(oSel.offsetLeft, oSel.offsetTop);
403 offsetEnd.moveStart("character",-1-rows);
404
405 if (offsetEnd.text.length > 0 || offsetEnd.offsetTop == oldTop && offsetEnd.offsetLeft == oldLeft)
406 {
407 break;
408 }
409
410 rows ++;
411 oldTop = offsetEnd.offsetTop;
412 oldLeft = offsetEnd.offsetLeft;
413 }
414
415 return rows;
416}
417function getCursorPosition()
418{
419 var src = event.srcElement;
420 var offset = src.document.selection.createRange();
421 var oSel = document.selection.createRange();
422
423 var textLength = src.innerText.length;
424
425 offset.moveToPoint(oSel.offsetLeft, oSel.offsetTop);
426 offset.moveStart("character", -99999);
427 var rowSpans = offset.getClientRects();
428
429 var pos = getPos(offset.text);
430
431 var charCodes = offset.text.length;
432 var chars = offset.text.replace(/\r\n/g,"").length + 1;
433
434 var extRows = getNullRows(src,oSel);
435 if(extRows > 0)
436 {
437 pos[0] += extRows;
438 pos[1] = 1;
439 }
440 window.status = "行: " + pos[0] +", 列: " + pos[1] + ", 第 " + chars + " 个字符" + " ("+ oSel.offsetTop +","+
441 oSel.offsetLeft +")";
442 return charCodes;
443}
444
445var SyntaxSet = new Array();
446SyntaxSet.All = new Array();
447
448SyntaxSet.parse = function(token)
449{
450 for (var i = 0; i < this.All.length; i++)
451 {
452 var syntaxes = this.All[i];
453 for (var j = 0; j < syntaxes.rules.All.length; j++)
454 {
455 if (syntaxes.rules.All[j].test(token))
456 {
457 syntaxes.rules.All[j].color = syntaxes.color;
458 return syntaxes.rules.All[j];
459 }
460 }
461 }
462
463 return null;
464}
465
466SyntaxSet.add = function(syntaxes)
467{
468 if(this[syntaxes.name] != null)
469 return;
470 this[syntaxes.name] = syntaxes;
471 this.All.push(syntaxes);
472}
473
474function Syntaxes(name, color, fcons, bcons)
475{
476 this.name = name;
477 this.color = color;
478 this.rules = new Array();
479 this.rules.All = new Array();
480 this.fcons = fcons;
481 if(bcons != null)
482 this.bcons = bcons;
483 else
484 this.bcons = fcons;
485
486 Syntaxes.prototype.addRule = function(rule)
487 {
488 if(this.rules[rule.name] != null)
489 return;
490 this.rules[rule.name] = rule;
491 this.rules.All.push(rule);
492 rule.parent = this;
493 }
494}
495
496function SyntaxRule(name, regExp)
497{
498 this.name = name;
499this.expr = regExp;
500 this.subRules = new Array();
501 SyntaxRule.prototype.test = function(token)
502 {
503 return this.expr.test(token);
504 }
505 SyntaxRule.prototype.addSubRule = function(rule)
506 {
507 this.subRules.push(rule);
508 if (rule.parent == null)
509 rule.parent = this;
510 }
511}
512
513SyntaxSet.add(new Syntaxes("keywords", "#0000ff", /[\;\s\.\xfe\xff\xfd\[\]\(\{\}\)\;\,]/)); //词法·关键词·蓝色
514SyntaxSet["keywords"].addRule(new SyntaxRule("Function",/function/));
515SyntaxSet["keywords"].addRule(new SyntaxRule("Variable",/var/));
516SyntaxSet["keywords"].addRule(new SyntaxRule("Return",/return/));
517SyntaxSet["keywords"].addRule(new SyntaxRule("Exception",/(try|catch|throw)/));
518SyntaxSet["keywords"].addRule(new SyntaxRule("Condition",/(if|else|switch)/));
519SyntaxSet["keywords"].addRule(new SyntaxRule("Cycle",/(for|while|do)/));
520SyntaxSet["keywords"].addRule(new SyntaxRule("Type",/(int|double|float|void|char)/));
521SyntaxSet["keywords"].addRule(new SyntaxRule("Right",/(public|private|protected|static)/));
522SyntaxSet["keywords"].addRule(new SyntaxRule("Constant",/(true|false|null|undefined|NaN|Infinity)/));
523SyntaxSet["keywords"].addRule(new SyntaxRule("Construct",/(new|delete)/));
524
525SyntaxSet.add(new Syntaxes("objects", "#FF0000", /[\;\s\.\xfe\xff\xfd\[\]\(\{\}\)\;\,]/)); //词法·对象·红色
526SyntaxSet["objects"].addRule(new SyntaxRule("Object",/(Array|arguments|Boolean|Date|Error|Function|Object|Number|Math|RegExp|String)/));
527
528SyntaxSet.add(new Syntaxes("global", "#800000", /[\;\s\.\xfe\xff\xfd\[\]\(\{\}\)\;\,]/)); //词法·系统函数·红色
529SyntaxSet["global"].addRule(new SyntaxRule("SystemFunc",/(alert|parseFloat|parseInt|eval|decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|escape|eval|isFinite|isNaN|unescape)/));
530
531//\xdf < \xdd >
532SyntaxSet.add(new Syntaxes("tag","#0000ff")); //词法·标签
533SyntaxSet["tag"].addRule(new SyntaxRule("startTag",/\xdf[^\xdd\'\"\/\s\xfd\xff\xfe\xdf\?\!\%]+([\s\xfd]+[^\xdd\'\"\/\s\xfd\xff\xfe\xdf\?\!\%]+([\s\xfd\=](\'[^\']*\')|(\"[^\"]*\"))?)*[\s\xfd]*[\/]?\xdd/));
534SyntaxSet["tag"].addRule(new SyntaxRule("endTag",/\xdf\/[^\xdd\'\"\/\s\xfd\xff\xfe\xdf\?\!\%]+\xdd/));
535
536var subRule = new Syntaxes("sub_tok","#808000",/[\xdf\/]/,/./);
537subRule.addRule(new SyntaxRule("tagName",/\w+/));
538SyntaxSet["tag"].rules["startTag"].addSubRule(subRule.rules["tagName"]);
539SyntaxSet["tag"].rules["endTag"].addSubRule(subRule.rules["tagName"]);
540
541var subRule_2 = new Syntaxes("sub_tok_2","#800080",/[\xdd\xfd\s\=\+\-\*\/\/]/);
542subRule_2.addRule(new SyntaxRule("attribute",/\w+/));
543SyntaxSet["tag"].rules["startTag"].addSubRule(subRule_2.rules["attribute"]);
544
545SyntaxSet.add(new Syntaxes("String", "#ff00ff", /[\s\.\xfe\xff\xfd\[\]\(\{\}\)\;\,\+\-\*\/\=\xdd]/)); //词法·字符串·粉色
546SyntaxSet["String"].addRule(new SyntaxRule("String",
547 /('((\\\')|[^'\xff])*([^\\\']|(\\\'\xff))')|("((\\\")|[^"\xff])*([^\\\"\xff]|(\\\"))")/));
548
549SyntaxSet.add(new Syntaxes("remarks", "#008000")); //词法·注释·绿色
550SyntaxSet["remarks"].addRule(new SyntaxRule("ShortRemark",/\/\/[^\xff]*/));
551SyntaxSet["remarks"].addRule(new SyntaxRule("LongRemark",/\/\*((.*\*\/)|(.*$))/));
552SyntaxSet["remarks"].addRule(new SyntaxRule("HTMLRemark",/\xdf!--(.(?!--\xdd))*.--\xdd/));
553
554function RegExprX(exprStr)
555{
556 this.expr = exprStr;
557}
558
559function getObjects(src)
560{
561 var text = src.innerText;
562 var funs = null;
563 var funList = new Array();
564
565 while((funs = text.match(funDef)) != null)
566 {
567
568 var stIndex = funs.index + funs[0].length;
569 var bont = 1;
570
571 for (var i = stIndex; bont > 0 && i < text.length; i++)
572 {
573 if (text.charAt(i) == "{") bont ++;
574 else if (text.charAt(i) == "}") bont--;
575 }
576
577 funList.push(text.substring(funs.index, i));
578
579 text = text.substring(i);
580 }
581 return funList;
582}
583
584function getVariables(src)
585{
586 var text = src.innerText;
587 var vars = null;
588 var varList = new Array();
589
590 while((vars = text.match(assignment)) != null)
591 {
592
593 var stIndex = vars.index + vars[0].length;
594 var variable = text.substring(vars.index, stIndex);
595 if (variable.indexOf(".") == -1)
596 variable = "var " + variable;
597 varList.push(variable);
598
599 text = text.substring(stIndex);
600 varList;
601 }
602 return varList;
603}
604
605var funDef = /function(([\s\xfd\n]*)|([\s\xfd\n]+[^\s\xfd\n]+))\(.*\)[\s\xfd\n]*{/;
606var objDef = /new[\s\xfd\n]+[^\s\xfd\n$\;]+/g;
607var funCall = /[^\s\xfd\n\+\-\*\/\=]+[\s\xfd]*\(.*\)/g;
608var assignment = /[^\s\xfd\n\=\;]+[\s\xfd\n]*[=][^\;\xdd\xdf]+/;
609</script>
2 <head>
3 <title>Silverna Demo Ver 0.01</title>
4 <style>
5 div.silverna__ctr__editbox{
6 margin:0 0 0 0;
7 padding:0 0 0 0;
8 font:16/18px Arial;
9 width:99%;
10 height:480px;
11 border:1px solid #000000;
12 overflow-y:scroll;
13 }
14 p{
15 margin:0 0 0 0;
16 padding:0 0 0 0;
17 }
18 </style>
19 </head>
20
21 <body style="margin:0 0 0 0;padding:0 0 0 0;word-break:break-all;overflow-x:hidden" onload="__silverna__ctr__editbox.focus()">
22 <div id="__silverna__ctr__editbox" class="silverna__ctr__editbox" contentEditable="true" onkeyDown="return KeyDown()" onkeyUp="KeyUp()" onmouseup="__silverna__ctr__methods.style.display='none';getCursorPosition();">
23 </div>
24 <select size="6" style="display:none;position:absolute" id="__silverna__ctr__methods" onkeyup="SelectMethod()" onclick="SelMethod(this)">
25 </body>
26</html>
27
28
29</select>
30<script language=JScript>
31function KeyDown()
32{
33 if(__silverna__ctr__methods.style.display != 'none')
34 {
35 if (event.keyCode == 38 || event.keyCode == 40 || event.keyCode == 13
36 || event.keyCode == 33 || event.keyCode == 34)
37 {
38 __silverna__ctr__methods.focus();
39 }
40 else
41 __silverna__ctr__methods.style.display = 'none';
42 }
43 if(event.keyCode == 9)
44 {
45 clipboardData.setData('text',' ');
46 event.srcElement.document.execCommand('paste');
47 return false;
48 }
49 if(event.keyCode == 8)
50 {
51 var oSel = document.selection.createRange();
52 var offset = event.srcElement.document.selection.createRange();
53 offset.moveToPoint(oSel.offsetLeft, oSel.offsetTop);
54 offset.moveStart('character', -4);
55 if(offset.text.length < 4) return true;
56 for (var i = 0; i < offset.text.length; i++)
57 {
58 if (offset.text.charAt(i) != " ")
59 {
60 return true;
61 }
62 }
63 offset.select();
64 event.srcElement.document.execCommand('Delete');
65 return false;
66 }
67 return true;
68}
69
70function KeyUp()
71{
72 var oSel, offset;
73 if(event.keyCode == 13)
74 {
75 testStr = event.srcElement.innerText.substring(0, getCursorPosition());
76 var space = null;
77 for (var i = testStr.length - 1; i >= 0; i--)
78 {
79 if (testStr.charAt(i) == "\n") break;
80 if (testStr.charAt(i) == " ")
81 {
82 if(space != null) space += " ";
83 }
84 else
85 {
86 space = "";
87 }
88 }
89 var backupData = clipboardData.getData('text');
90 if(space != null)
91 {
92 clipboardData.clearData();
93 clipboardData.setData('text',space);
94 event.srcElement.document.execCommand('paste');
95 }
96 if(backupData != null)
97 {
98 clipboardData.setData('text',backupData);
99 }
100 }
101 oSel = document.selection.createRange();
102 var left = oSel.offsetLeft;
103 var top = oSel.offsetTop;
104var token = getCurrentToken(event.srcElement);
105 var chars = getCursorPosition();
106
107 if (event.keyCode == 38 || event.keyCode == 40
108 || event.keyCode == 33 || event.keyCode == 34)
109 {
110 return true;
111 }
112 parseSyntax(event.srcElement);
113 offset = event.srcElement.document.selection.createRange();
114 offset.moveToPoint(left, top);
115 offset.select();
116
117 if(!event.shiftKey && event.keyCode == 190)
118 {
119 setMethods(token.posSent.slice(0, -1));
120 }
121}
122
123function parseSyntax(src)
124{
125 var text = src.innerHTML;
126 text = text.replace(/<FONT[^<>]*>/gi, "").replace(/<\/FONT[^<>]*>/gi,"");
127 text = text.replace(/<BR>/gi,"\xff\xfe");
128 text = text.replace(/<P>/gi, "\xfe").replace(/<\/P>/gi, "\xff");
129 text = text.replace(/\ /gi, "\xfd");
130 text = text.replace(/\</gi, "\xdf");
131 text = text.replace(/\>/gi, "\xdd");
132 text = text.replace(/\r\n/gi,"");
133
134 for (var i = 0; i <SyntaxSet.All.length; i++)
135 {
136 var syntaxes = SyntaxSet.All[i];
137 for (var j = 0; j < syntaxes.rules.All.length; j++)
138 {
139 text = parseRule(text, syntaxes.rules.All[j]);
140 }
141 }
142
143 src.innerHTML = text.replace(/\xde/g,"").replace(/\xfc/g,"'").replace(/\xfe/g,"<P>").replace(/\xff/g,"</P>").replace(/\xfd/g," ").replace(/\xdf/g,"<").replace(/\xdd/g,">");
144}
145function parseRule(text, rule)
146{
147 var newText = "";
148
149 var idx = text.search(rule.expr);
150
151 while (idx != -1)
152 {
153 var remark = text.match(rule.expr);
154 var subText = text.substring(0, idx + remark[0].length);
155 if(rule.parent.fcons == null || (idx == 0 || rule.parent.fcons.test(text.charAt(idx-1))) && (idx + remark[0].length >= text.length || rule.parent.bcons.test(text.charAt(idx + remark[0].length))))
156 {
157 var subToken = remark[0].replace(/<FONT[^<>]*>/gi, "").replace(/<\/FONT[^<>]*>/gi,"");
158 for (var i = 0; i < rule.subRules.length; i++)
159 {
160 subToken = parseRule(subToken, rule.subRules[i]);
161 }
162 subText = subText.replace(remark[0], "<FONT \xdecolor=\xfc"+rule.parent.color+"\xfc>" + subToken + "</FONT>");
163 }
164 newText += subText;
165 text = text.substring(idx + remark[0].length);
166 idx = text.search(rule.expr);
167 }
168 newText += text;
169 return newText;
170}
171
172function getCurrentToken(src)
173{
174 var oSel = document.selection.createRange();
175 var offset = src.document.selection.createRange();
176 offset.moveToPoint(oSel.offsetLeft, oSel.offsetTop);
177 offset.moveStart("character", -99999);
178
179 var sentences = offset.text.split(/[;}{]/g);
180 var currentSentence = sentences[sentences.length - 1];
181
182 var tokens = offset.text.split(/[\s\+\-\*\/]/);
183 var currentToken = tokens[tokens.length - 1];
184
185 var idx = offset.text.length;
186
187 var fullSentence = src.innerText.substring(idx);
188 fullToken = fullSentence.replace(/[\n$]/,"@@@@");
189 idx = fullSentence.indexOf("@@@@");
190 if(idx != -1)
191 fullSentence = fullSentence.substring(0, idx);
192
193 var fullToken = src.innerText.substring(idx);
194 fullToken = fullToken.replace(/[\s\+\-\*\/$]/,"@@@@");
195 idx = fullToken.indexOf("@@@@");
196 if(idx != -1)
197 fullToken = fullToken.substring(0, idx);
198
199 var token = new Array();
200
201 token.currentToken = currentToken + fullToken;
202 token.posTok = currentToken;
203
204 token.posSent = currentSentence;
205 token.currentSentence = currentSentence + fullSentence;
206
207 return token;
208}
209Array.prototype.pushDistinct = function(obj)
210{
211 for (var i = 0; i < this.length; i++)
212 {
213 if (this[i] == obj)
214 {
215 return null;
216 }
217 }
218 this.push(obj);
219 return obj;
220}
221
222function putMethods(methodList, obj, methods)
223{
224 var list = methods.split(",");
225
226 for (var i = 0; i < list.length; i++)
227 {
228 if (obj[list[i]] != null)
229 {
230 methodList.pushDistinct(list[i]);
231 }
232 }
233}
234function parseObj(objStr)
235{
236 var cont = 0;
237 var sont = 0;
238 for (var i = objStr.length - 1; i >= 0; i--)
239 {
240 if (objStr.charAt(i) == ")")
241 cont ++;
242 if (objStr.charAt(i) == "(")
243 cont --;
244 if (objStr.charAt(i) == "]")
245 sont ++;
246 if (objStr.charAt(i) == "[")
247 sont --;
248 if (cont == 0 && sont == 0 && /[\+\-\*\/\=\,\;\&\|\>\<]/.test(objStr.charAt(i)))
249 break;
250 if (cont < 0 || sont < 0)
251 break;
252 }
253 return objStr.substring(i+1);
254}
255//将对象的方法放到Select Object中显示出来,并且初始化不可列举方法
256function setMethods(objStr)
257{
258 var oSel = document.selection.createRange();
259 objStr = parseObj(objStr);
260 objStr = objStr.replace(/alert/g,"Object");
261 var funs = getObjects(event.srcElement);
262 var vars = getVariables(event.srcElement);
263
264 for (var __silverna_i = 0; __silverna_i < funs.length; __silverna_i++)
265 {
266 try{eval(funs[__silverna_i]);} catch(e){};
267 }
268 for (var __silverna_i = 0; __silverna_i < vars.length; __silverna_i++)
269 {
270 try{eval(vars[__silverna_i]);}catch(e){};
271 }
272 if(event.srcElement.style.display == 'none')
273 {
274 event.srcElement.style.display = '';
275 event.srcElement.focus();
276 }
277 try
278 {
279 var methodList = new Array();
280 var obj = eval(objStr);
281
282 if (obj.prototype != null)
283 {
284 methodList.pushDistinct("prototype");
285 }
286 if (obj != null)
287 {
288
289 //基本Object方法
290 putMethods(methodList, obj,"constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf");
291
292 //基本Array方法
293 putMethods(methodList, obj,"concat,join,length,pop,push,reverse,shift,slice,sort,splice,unshift");
294
295 //基本Date方法
296 putMethods(methodList,obj,"getDate,getUTCDate,getDay,getUTCDay,getFullYear,getUTCFullYear,getHours,getUTCHours,getMilliseconds,getUTCMilliseconds,getMinutes,getUTCMinutes,getMonth,getUTCMonth,getSeconds,getUTCSeconds,getTime,getTimezoneoffset,getYear");
297
298 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");
299
300 //基本Math方法
301 putMethods(methodList,obj,"E,LN10,LN2,LOG10E,LOG2E,PI,SQRT1_2,SQRT2");
302 putMethods(methodList,obj,"abs,acos,asin,atan,atan2,ceil,cos,exp,floor,log,max,min,pow,random,round,sin,sqrt,tan");
303
304 //基本Function方法
305 putMethods(methodList,obj,"arguments,caller,length,prototype,apply,call,toString");
306
307 //基本Number方法
308 putMethods(methodList,obj,"MAX_VALUE,MIN_VALUE,NaN,NEGATIVE_INFINITY,POSITIVE_INFINITY");
309 putMethods(methodList,obj,"toString,toLocalString,toFixed,toExponential,toPrecision");
310
311 //基本RegExp方法
312 putMethods(methodList,obj,"global,ignoreCase,lastIndex,multiline,source,exec,test");
313
314 //基本String方法
315 putMethods(methodList,obj,"charAt,charCodeAt,contact,indexOf,lastIndexOf,match,replace,search,slice,split,substring,substr,toLowerCase,toString,toUpperCase,valueOf,fromCharCode");
316 putMethods(methodList,obj,"anchor,big,blink,bold,fixed,fontcolor,fontsize,italics,link,small,strike,sub,sup");
317
318 }
319 for (each in obj)
320 {
321 methodList.pushDistinct(each);
322 }
323 methodList.sort();
324
325 if (methodList.length > 0)
326 {
327 __silverna__ctr__methods.options.length = 0;
328 for (var __silverna_i = 0; __silverna_i < methodList.length; __silverna_i++)
329 {
330 __silverna__ctr__methods.options.add(new Option(methodList[__silverna_i]));
331 }
332 if (__silverna__ctr__methods.options.length > 6)
333 {
334 __silverna__ctr__methods.size = 6;
335 }
336 else
337 {
338 __silverna__ctr__methods.size = __silverna__ctr__methods.options.length;
339 }
340 __silverna__ctr__methods.style.top = oSel.offsetTop;
341 __silverna__ctr__methods.style.left = oSel.offsetLeft;
342 __silverna__ctr__methods.style.display = "";
343 __silverna__ctr__methods.options[0].selected = true;
344 }
345 return true;
346 }
347 catch(e){return false;}
348}
349
350function SelectMethod()
351{
352 var src = event.srcElement;
353 if(event.keyCode == 13 || event.keyCode == 32)
354 {
355 SelMethod(src);
356 }
357
358 if(event.keyCode == 27 || event.keyCode == 8)
359 {
360 src.style.display = "none";
361 __silverna__ctr__editbox.focus();
362 }
363}
364function SelMethod(src)
365{
366 var backupData = clipboardData.getData('text');
367 clipboardData.setData('text',src.options[src.selectedIndex].text);
368 __silverna__ctr__editbox.focus();
369 __silverna__ctr__editbox.document.execCommand('paste');
370 src.style.display = "none";
371 getCursorPosition();
372 if(backupData != null)
373 {
374 clipboardData.setData('text',backupData);
375 }
376}
377
378function getPos(text)
379{
380 var rows = 1;
381 var cols = 1;
382 var idx = 0;
383 var subText = text;
384 while((idx = subText.indexOf("\n")) != -1)
385 {
386 subText = subText.substring(idx + 1);
387 rows++;
388 }
389 return new Array(rows, subText.length + 1);
390}
391function getNullRows(src,oSel)
392{
393 var rows = 0;
394
395 var offsetEnd = src.document.selection.createRange();
396
397 var oldTop = 2;
398 var oldLeft = 2;
399
400 while(1)
401 {
402 offsetEnd.moveToPoint(oSel.offsetLeft, oSel.offsetTop);
403 offsetEnd.moveStart("character",-1-rows);
404
405 if (offsetEnd.text.length > 0 || offsetEnd.offsetTop == oldTop && offsetEnd.offsetLeft == oldLeft)
406 {
407 break;
408 }
409
410 rows ++;
411 oldTop = offsetEnd.offsetTop;
412 oldLeft = offsetEnd.offsetLeft;
413 }
414
415 return rows;
416}
417function getCursorPosition()
418{
419 var src = event.srcElement;
420 var offset = src.document.selection.createRange();
421 var oSel = document.selection.createRange();
422
423 var textLength = src.innerText.length;
424
425 offset.moveToPoint(oSel.offsetLeft, oSel.offsetTop);
426 offset.moveStart("character", -99999);
427 var rowSpans = offset.getClientRects();
428
429 var pos = getPos(offset.text);
430
431 var charCodes = offset.text.length;
432 var chars = offset.text.replace(/\r\n/g,"").length + 1;
433
434 var extRows = getNullRows(src,oSel);
435 if(extRows > 0)
436 {
437 pos[0] += extRows;
438 pos[1] = 1;
439 }
440 window.status = "行: " + pos[0] +", 列: " + pos[1] + ", 第 " + chars + " 个字符" + " ("+ oSel.offsetTop +","+
441 oSel.offsetLeft +")";
442 return charCodes;
443}
444
445var SyntaxSet = new Array();
446SyntaxSet.All = new Array();
447
448SyntaxSet.parse = function(token)
449{
450 for (var i = 0; i < this.All.length; i++)
451 {
452 var syntaxes = this.All[i];
453 for (var j = 0; j < syntaxes.rules.All.length; j++)
454 {
455 if (syntaxes.rules.All[j].test(token))
456 {
457 syntaxes.rules.All[j].color = syntaxes.color;
458 return syntaxes.rules.All[j];
459 }
460 }
461 }
462
463 return null;
464}
465
466SyntaxSet.add = function(syntaxes)
467{
468 if(this[syntaxes.name] != null)
469 return;
470 this[syntaxes.name] = syntaxes;
471 this.All.push(syntaxes);
472}
473
474function Syntaxes(name, color, fcons, bcons)
475{
476 this.name = name;
477 this.color = color;
478 this.rules = new Array();
479 this.rules.All = new Array();
480 this.fcons = fcons;
481 if(bcons != null)
482 this.bcons = bcons;
483 else
484 this.bcons = fcons;
485
486 Syntaxes.prototype.addRule = function(rule)
487 {
488 if(this.rules[rule.name] != null)
489 return;
490 this.rules[rule.name] = rule;
491 this.rules.All.push(rule);
492 rule.parent = this;
493 }
494}
495
496function SyntaxRule(name, regExp)
497{
498 this.name = name;
499this.expr = regExp;
500 this.subRules = new Array();
501 SyntaxRule.prototype.test = function(token)
502 {
503 return this.expr.test(token);
504 }
505 SyntaxRule.prototype.addSubRule = function(rule)
506 {
507 this.subRules.push(rule);
508 if (rule.parent == null)
509 rule.parent = this;
510 }
511}
512
513SyntaxSet.add(new Syntaxes("keywords", "#0000ff", /[\;\s\.\xfe\xff\xfd\[\]\(\{\}\)\;\,]/)); //词法·关键词·蓝色
514SyntaxSet["keywords"].addRule(new SyntaxRule("Function",/function/));
515SyntaxSet["keywords"].addRule(new SyntaxRule("Variable",/var/));
516SyntaxSet["keywords"].addRule(new SyntaxRule("Return",/return/));
517SyntaxSet["keywords"].addRule(new SyntaxRule("Exception",/(try|catch|throw)/));
518SyntaxSet["keywords"].addRule(new SyntaxRule("Condition",/(if|else|switch)/));
519SyntaxSet["keywords"].addRule(new SyntaxRule("Cycle",/(for|while|do)/));
520SyntaxSet["keywords"].addRule(new SyntaxRule("Type",/(int|double|float|void|char)/));
521SyntaxSet["keywords"].addRule(new SyntaxRule("Right",/(public|private|protected|static)/));
522SyntaxSet["keywords"].addRule(new SyntaxRule("Constant",/(true|false|null|undefined|NaN|Infinity)/));
523SyntaxSet["keywords"].addRule(new SyntaxRule("Construct",/(new|delete)/));
524
525SyntaxSet.add(new Syntaxes("objects", "#FF0000", /[\;\s\.\xfe\xff\xfd\[\]\(\{\}\)\;\,]/)); //词法·对象·红色
526SyntaxSet["objects"].addRule(new SyntaxRule("Object",/(Array|arguments|Boolean|Date|Error|Function|Object|Number|Math|RegExp|String)/));
527
528SyntaxSet.add(new Syntaxes("global", "#800000", /[\;\s\.\xfe\xff\xfd\[\]\(\{\}\)\;\,]/)); //词法·系统函数·红色
529SyntaxSet["global"].addRule(new SyntaxRule("SystemFunc",/(alert|parseFloat|parseInt|eval|decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|escape|eval|isFinite|isNaN|unescape)/));
530
531//\xdf < \xdd >
532SyntaxSet.add(new Syntaxes("tag","#0000ff")); //词法·标签
533SyntaxSet["tag"].addRule(new SyntaxRule("startTag",/\xdf[^\xdd\'\"\/\s\xfd\xff\xfe\xdf\?\!\%]+([\s\xfd]+[^\xdd\'\"\/\s\xfd\xff\xfe\xdf\?\!\%]+([\s\xfd\=](\'[^\']*\')|(\"[^\"]*\"))?)*[\s\xfd]*[\/]?\xdd/));
534SyntaxSet["tag"].addRule(new SyntaxRule("endTag",/\xdf\/[^\xdd\'\"\/\s\xfd\xff\xfe\xdf\?\!\%]+\xdd/));
535
536var subRule = new Syntaxes("sub_tok","#808000",/[\xdf\/]/,/./);
537subRule.addRule(new SyntaxRule("tagName",/\w+/));
538SyntaxSet["tag"].rules["startTag"].addSubRule(subRule.rules["tagName"]);
539SyntaxSet["tag"].rules["endTag"].addSubRule(subRule.rules["tagName"]);
540
541var subRule_2 = new Syntaxes("sub_tok_2","#800080",/[\xdd\xfd\s\=\+\-\*\/\/]/);
542subRule_2.addRule(new SyntaxRule("attribute",/\w+/));
543SyntaxSet["tag"].rules["startTag"].addSubRule(subRule_2.rules["attribute"]);
544
545SyntaxSet.add(new Syntaxes("String", "#ff00ff", /[\s\.\xfe\xff\xfd\[\]\(\{\}\)\;\,\+\-\*\/\=\xdd]/)); //词法·字符串·粉色
546SyntaxSet["String"].addRule(new SyntaxRule("String",
547 /('((\\\')|[^'\xff])*([^\\\']|(\\\'\xff))')|("((\\\")|[^"\xff])*([^\\\"\xff]|(\\\"))")/));
548
549SyntaxSet.add(new Syntaxes("remarks", "#008000")); //词法·注释·绿色
550SyntaxSet["remarks"].addRule(new SyntaxRule("ShortRemark",/\/\/[^\xff]*/));
551SyntaxSet["remarks"].addRule(new SyntaxRule("LongRemark",/\/\*((.*\*\/)|(.*$))/));
552SyntaxSet["remarks"].addRule(new SyntaxRule("HTMLRemark",/\xdf!--(.(?!--\xdd))*.--\xdd/));
553
554function RegExprX(exprStr)
555{
556 this.expr = exprStr;
557}
558
559function getObjects(src)
560{
561 var text = src.innerText;
562 var funs = null;
563 var funList = new Array();
564
565 while((funs = text.match(funDef)) != null)
566 {
567
568 var stIndex = funs.index + funs[0].length;
569 var bont = 1;
570
571 for (var i = stIndex; bont > 0 && i < text.length; i++)
572 {
573 if (text.charAt(i) == "{") bont ++;
574 else if (text.charAt(i) == "}") bont--;
575 }
576
577 funList.push(text.substring(funs.index, i));
578
579 text = text.substring(i);
580 }
581 return funList;
582}
583
584function getVariables(src)
585{
586 var text = src.innerText;
587 var vars = null;
588 var varList = new Array();
589
590 while((vars = text.match(assignment)) != null)
591 {
592
593 var stIndex = vars.index + vars[0].length;
594 var variable = text.substring(vars.index, stIndex);
595 if (variable.indexOf(".") == -1)
596 variable = "var " + variable;
597 varList.push(variable);
598
599 text = text.substring(stIndex);
600 varList;
601 }
602 return varList;
603}
604
605var funDef = /function(([\s\xfd\n]*)|([\s\xfd\n]+[^\s\xfd\n]+))\(.*\)[\s\xfd\n]*{/;
606var objDef = /new[\s\xfd\n]+[^\s\xfd\n$\;]+/g;
607var funCall = /[^\s\xfd\n\+\-\*\/\=]+[\s\xfd]*\(.*\)/g;
608var assignment = /[^\s\xfd\n\=\;]+[\s\xfd\n]*[=][^\;\xdd\xdf]+/;
609</script>