js,html編輯器

  <html>
 <head>
  <title>Silverna Demo Ver 0.01</title>
  <style>
   div.silverna__ctr__editbox{
    margin:0 0 0 0;
    padding:0 0 0 0;
    font:16/18px Arial;
    width:99%;
    height:480px;
    border:1px solid #000000;
    overflow-y:auto;
   }
   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" οnlοad="__silverna__ctr__editbox.focus()">
 <div id="__silverna__ctr__editbox" class="silverna__ctr__editbox" contentEditable="true" onkeyDown="return KeyDown()" onkeyUp="KeyUp()" οnmοuseup="__silverna__ctr__methods.style.display='none';getCursorPosition();">
 </div>
 <select size="6" style="display:none;position:absolute" id="__silverna__ctr__methods" οnkeyup="SelectMethod()" οnclick="SelMethod(this)">
 </body>
</html>


</select>
<script language=JScript>
function KeyDown()
{
 if(__silverna__ctr__methods.style.display != 'none')
 {
  if (event.keyCode == 38 || event.keyCode == 40 || event.keyCode == 13
   || event.keyCode == 33 || event.keyCode == 34)
  {
   __silverna__ctr__methods.focus();
  }
  else
   __silverna__ctr__methods.style.display = 'none';
 }
 if(event.keyCode == 9)
 {
  clipboardData.setData('text','    ');
  event.srcElement.document.execCommand('paste');
  return false;  
 }
 if(event.keyCode == 8)
 {
  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());
  var space = null;
  for (var i = testStr.length - 1; i >= 0; i--)
  {
   if (testStr.charAt(i) == "/n") break;
   if (testStr.charAt(i) == " ")
   {
    if(space != null) space += " ";
   }
   else
   {
    space = "";
   }
  }
  var backupData = clipboardData.getData('text');
  if(space != null)
  {
   clipboardData.clearData();
   clipboardData.setData('text',space);
   event.srcElement.document.execCommand('paste');
  }
  if(backupData != null)
  {
   clipboardData.setData('text',backupData);
  }
 }
 oSel = document.selection.createRange();
 var left = oSel.offsetLeft;
 var top = oSel.offsetTop;
    var token = getCurrentToken(event.srcElement);
 var chars = getCursorPosition();

 if (event.keyCode == 38 || event.keyCode == 40
  || event.keyCode == 33 || event.keyCode == 34)
 {
  return true;
 }
 parseSyntax(event.srcElement);
 offset = event.srcElement.document.selection.createRange();
 offset.moveToPoint(left, top);
 offset.select();

 if(!event.shiftKey && event.keyCode == 190)
 {
  setMethods(token.posSent.slice(0, -1)); 
 }
}

function parseSyntax(src) 
{  
 var text = src.innerHTML;
 text = text.replace(/<FONT[^<>]*>/gi, "").replace(/<//FONT[^<>]*>/gi,"");
 text = text.replace(/<BR>/gi,"/xff/xfe");
 text = text.replace(/<P>/gi, "/xfe").replace(/<//P>/gi, "/xff");
 text = text.replace(//&nbsp;/gi, "/xfd");
 text = text.replace(//&lt;/gi, "/xdf");
 text = text.replace(//&gt;/gi, "/xdd");
 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++)
  {
   text = parseRule(text, syntaxes.rules.All[j]);
  }
 }

 src.innerHTML = text.replace(//xde/g,"").replace(//xfc/g,"'").replace(//xfe/g,"<P>").replace(//xff/g,"</P>").replace(//xfd/g,"&nbsp;").replace(//xdf/g,"&lt;").replace(//xdd/g,"&gt");
}
function parseRule(text, rule) 
{
 var newText = "";

 var idx = text.search(rule.expr);
  
 while (idx != -1)
 {
  var remark = text.match(rule.expr);
  var subText = text.substring(0, idx + remark[0].length);
  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))))
  {
   var subToken = remark[0].replace(/<FONT[^<>]*>/gi, "").replace(/<//FONT[^<>]*>/gi,"");
   for (var i = 0; i < rule.subRules.length; i++)
   {
    subToken = parseRule(subToken, rule.subRules[i]);
   }
   subText = subText.replace(remark[0], "<FONT /xdecolor=/xfc"+rule.parent.color+"/xfc>" + subToken + "</FONT>");
  }
  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 sentences = offset.text.split(/[;}{]/g);
 var currentSentence = sentences[sentences.length - 1];

 var tokens = offset.text.split(/[/s/+/-/*//]/);
 var currentToken = tokens[tokens.length - 1];

 var idx = offset.text.length;

 var fullSentence = src.innerText.substring(idx);
 fullToken = fullSentence.replace(/[/n$]/,"@@@@");
 idx = fullSentence.indexOf("@@@@");
 if(idx != -1)
  fullSentence = fullSentence.substring(0, idx);

 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;

 token.posSent = currentSentence;
 token.currentSentence = currentSentence + fullSentence;

 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]);
  }
 }
}
function parseObj(objStr) 
{
 var cont = 0; 
 var sont = 0; 
 for (var i = objStr.length - 1; i >= 0; i--)
 {
  if (objStr.charAt(i) == ")")
   cont ++;
  if (objStr.charAt(i) == "(")
   cont --;
  if (objStr.charAt(i) == "]")
   sont ++;
  if (objStr.charAt(i) == "[")
   sont --;
  if (cont == 0 && sont == 0 && /[/+/-/*///=/,/;/&/|/>/<]/.test(objStr.charAt(i)))
   break;
  if (cont < 0 || sont < 0)
   break;
 }
 return objStr.substring(i+1);
}
//將對象的方法放到Select Object中顯示出來,並且初始化不可列舉方法
function setMethods(objStr)
{
  var oSel = document.selection.createRange();
  objStr = parseObj(objStr);
  objStr = objStr.replace(/alert/g,"Object");
  var funs = getObjects(event.srcElement);
  var vars = getVariables(event.srcElement);

  for (var __silverna_i = 0; __silverna_i < funs.length; __silverna_i++)
  {
   try{eval(funs[__silverna_i]);} catch(e){};
  }
  for (var __silverna_i = 0; __silverna_i < vars.length; __silverna_i++)
  {
   try{eval(vars[__silverna_i]);}catch(e){};
  }
  if(event.srcElement.style.display == 'none')
  {
   event.srcElement.style.display = '';
   event.srcElement.focus();
  }
  try
  {
   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,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 > 0)
   {
    __silverna__ctr__methods.options.length = 0;
    for (var __silverna_i = 0; __silverna_i < methodList.length; __silverna_i++)
    {
     __silverna__ctr__methods.options.add(new Option(methodList[__silverna_i])); 
    }
    if (__silverna__ctr__methods.options.length > 6)
    {
     __silverna__ctr__methods.size = 6;
    }
    else
    {
     __silverna__ctr__methods.size = __silverna__ctr__methods.options.length;
    }
    __silverna__ctr__methods.style.top = oSel.offsetTop;
    __silverna__ctr__methods.style.left = oSel.offsetLeft;
    __silverna__ctr__methods.style.display = "";
    __silverna__ctr__methods.options[0].selected = true;
   }
   return true;
  }
  catch(e){return false;}
}

function SelectMethod()
{
 var src = event.srcElement;
 if(event.keyCode == 13 || event.keyCode == 32)
 {
  SelMethod(src);
 }

 if(event.keyCode == 27 || event.keyCode == 8)
 {
  src.style.display = "none";
  __silverna__ctr__editbox.focus();
 }
}
function SelMethod(src)
{
 var backupData = clipboardData.getData('text');
 clipboardData.setData('text',src.options[src.selectedIndex].text);
 __silverna__ctr__editbox.focus();
 __silverna__ctr__editbox.document.execCommand('paste');
 src.style.display = "none";
 getCursorPosition();
 if(backupData != null)
 {
  clipboardData.setData('text',backupData);
 }
}

function getPos(text)
{
 var rows = 1;
 var cols = 1;
 var idx = 0;
 var subText = text;
 while((idx = subText.indexOf("/n")) != -1)
 {
  subText = subText.substring(idx + 1);
  rows++;
 }
 return new Array(rows, subText.length + 1);
}
function getNullRows(src,oSel)
{
 var rows = 0;

 var offsetEnd = src.document.selection.createRange();

 var oldTop = 2;
 var oldLeft = 2;

 while(1)
 {
  offsetEnd.moveToPoint(oSel.offsetLeft, oSel.offsetTop);
  offsetEnd.moveStart("character",-1-rows);

  if (offsetEnd.text.length > 0 || 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", -99999);
 var rowSpans = offset.getClientRects();

 var pos = getPos(offset.text);
        
 var charCodes = offset.text.length;
 var chars = offset.text.replace(//r/n/g,"").length + 1;

 var extRows = getNullRows(src,oSel);
 if(extRows > 0)
 {
  pos[0] += extRows;
  pos[1] = 1;
 }
 window.status = "行: " + pos[0] +", 列: " + pos[1] + ", 第 " + chars + " 個字符" + "  ("+ oSel.offsetTop +","+
 oSel.offsetLeft +")";
 return charCodes;
}

var SyntaxSet = new Array();
SyntaxSet.All = new Array();

SyntaxSet.parse = function(token)  
{
 for (var i = 0; i < this.All.length; i++)
 {
  var syntaxes = this.All[i];
  for (var j = 0; j < syntaxes.rules.All.length; j++)
  {
   if (syntaxes.rules.All[j].test(token))
   {
    syntaxes.rules.All[j].color = syntaxes.color;
    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, fcons, bcons)
{
 this.name = name;
 this.color = color;
 this.rules = new Array(); 
 this.rules.All = new Array();
 this.fcons = fcons; 
 if(bcons != null)
  this.bcons = bcons;
 else
  this.bcons = fcons; 

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

function SyntaxRule(name, regExp) 
{
 this.name = name;   
    this.expr = regExp; 
 this.subRules = new Array();  
 SyntaxRule.prototype.test = function(token)
 {
  return this.expr.test(token);
 }
 SyntaxRule.prototype.addSubRule = function(rule)
 {
  this.subRules.push(rule);
  if (rule.parent == null)
   rule.parent = this;
 }
}

SyntaxSet.add(new Syntaxes("keywords", "#0000ff", /[/;/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",/(true|false|null|undefined|NaN|Infinity)/));
SyntaxSet["keywords"].addRule(new SyntaxRule("Construct",/(new|delete)/));

SyntaxSet.add(new Syntaxes("objects", "#FF0000", /[/;/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", "#800000", /[/;/s/./xfe/xff/xfd/[/]/(/{/}/)/;/,]/));  //詞法·系統函數·紅色
SyntaxSet["global"].addRule(new SyntaxRule("SystemFunc",/(alert|parseFloat|parseInt|eval|decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|escape|eval|isFinite|isNaN|unescape)/));

///xdf < /xdd >
SyntaxSet.add(new Syntaxes("tag","#0000ff")); //詞法·標籤
SyntaxSet["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/));
SyntaxSet["tag"].addRule(new SyntaxRule("endTag",//xdf//[^/xdd/'/"///s/xfd/xff/xfe/xdf/?/!/%]+/xdd/));

var subRule = new Syntaxes("sub_tok","#808000",/[/xdf//]/,/./);
subRule.addRule(new SyntaxRule("tagName",//w+/));
SyntaxSet["tag"].rules["startTag"].addSubRule(subRule.rules["tagName"]);
SyntaxSet["tag"].rules["endTag"].addSubRule(subRule.rules["tagName"]);

var subRule_2 = new Syntaxes("sub_tok_2","#800080",/[/xdd/xfd/s/=/+/-/*////]/);
subRule_2.addRule(new SyntaxRule("attribute",//w+/));
SyntaxSet["tag"].rules["startTag"].addSubRule(subRule_2.rules["attribute"]);

SyntaxSet.add(new Syntaxes("String", "#ff00ff", /[/s/./xfe/xff/xfd/[/]/(/{/}/)/;/,/+/-/*///=/xdd]/));  //詞法·字符串·粉色
SyntaxSet["String"].addRule(new SyntaxRule("String",
       /('((///')|[^'/xff])*([^///']|(///'/xff))')|("((///")|[^"/xff])*([^///"/xff]|(///"))")/));

SyntaxSet.add(new Syntaxes("remarks", "#008000")); //詞法·註釋·綠色
SyntaxSet["remarks"].addRule(new SyntaxRule("ShortRemark",/////[^/xff]*/));
SyntaxSet["remarks"].addRule(new SyntaxRule("LongRemark",////*((.*/*//)|(.*$))/));
SyntaxSet["remarks"].addRule(new SyntaxRule("HTMLRemark",//xdf!--(.(?!--/xdd))*.--/xdd/));

function RegExprX(exprStr) 
{
 this.expr = exprStr;
}

function getObjects(src) 
{
 var text = src.innerText;
 var funs = null;
 var funList = new Array();

 while((funs = text.match(funDef)) != null)
 {
  
  var stIndex = funs.index + funs[0].length;
  var bont = 1;
  
  for (var i = stIndex; bont > 0 && i < text.length; i++)  
  {
   if (text.charAt(i) == "{") bont ++;
   else if (text.charAt(i) == "}") bont--;
  }
  
  funList.push(text.substring(funs.index, i));

  text = text.substring(i);
 }
 return funList;
}

function getVariables(src)
{
 var text = src.innerText;
 var vars = null;
 var varList = new Array();

 while((vars = text.match(assignment)) != null)
 {

  var stIndex = vars.index + vars[0].length;
  var variable = text.substring(vars.index, stIndex);
  if (variable.indexOf(".") == -1)
   variable = "var " + variable;
  varList.push(variable);

  text = text.substring(stIndex);
  varList;
 }
 return varList;
}

var funDef = /function(([/s/xfd/n]*)|([/s/xfd/n]+[^/s/xfd/n]+))/(.*/)[/s/xfd/n]*{/;
var objDef = /new[/s/xfd/n]+[^/s/xfd/n$/;]+/g;
var funCall = /[^/s/xfd/n/+/-/*///=]+[/s/xfd]*/(.*/)/g;
var assignment = /[^/s/xfd/n/=/;]+[/s/xfd/n]*[=][^/;/xdd/xdf]+/;
</script>

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章