代码改变世界

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 < 4return 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>