zoukankan      html  css  js  c++  java
  • Javascript 编辑器(html版)

    <html>
    <head>
    <title>Silverna Demo Ver 0.01</title>
    <style>
    div.editbox
    {
    margin
    :0 0 0 0;
    padding
    :0 0 0 0;
    font
    :16/18px Arial;
    border
    :0px solid #000000;
    }

    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" onLoad="editbox.focus()">
    <div id="editbox" class="editbox" style="99%;height:80%;" contentEditable="true" onkeyDown="return KeyDown()" onkeyUp="KeyUp()">
    </div>
    <select size="10" style="display:none;position:absolute" id="methods" onkeydown="SelectMethod()" onclick="SelMethod(this)" onClick="getCursorPosition()">
    </select> 
    <script language=Jscript>
    var testArray = new Array();
    var testDate = new Date();
    var testString = "aaa";
    var testVal = 1;
    var testObj = new myObj;

    function myObj()
    {
        myObj.prototype.testFunc 
    = function(){};
        
    this.testProperty = "test";
    }

    function KeyDown()
    {
        
    ////alert(event.altKey);
        if(event.keyCode == 9//TAB 键
        {
            clipboardData.setData('text',' ');
            event.srcElement.document.execCommand('paste');
            
    return false
        }

        
    if(event.keyCode == 8//Backspace 键
        {
            
    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 < 4return 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());
            
    //alert(testStr);
            var space = "";
            
    for (var i = testStr.length - 1; i >= 0; 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 == 190//.键
        {
            setMethods(token.posTok.slice(
    0-1));
        }

    }

    //
    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 = 0; i <SyntaxSet.All.length; i++)
        
    {
            
    var syntaxes = SyntaxSet.All[i];
            
    for (var j = 0; j < syntaxes.rules.All.length; j++)
            
    {
                syntaxes.rules.All[j].color 
    = syntaxes.color;
                syntaxes.rules.All[j].cons 
    = syntaxes.cons;
                
                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 != -1)
        
    {
            
    var remark = text.match(rule.expr);
            
    //alert(text.substring(0, idx+remark[0].length));
            var subText = text.substring(0, idx + remark[0].length);
            
    //        if(idx == 0 && rule.cons.test(text.charAt(idx-1)))// && (idx + remark[0].length >= text.length rule.cons.test(text.charAt(idx + remark[0].length))))
    //
            {
    //
                //alert(remark[0]);
    //
                //alert(remark[0].replace(/<FONT[^<>]*>/gi, "").replace(/<\/FONT[^<>]*>/gi,""));
    //
                subText = subText.replace(remark[0], "<FONT color=\xfc"+rule.color+"\xfc>" + remark[0].replace(/<FONT[^<>]*>/gi, "").replace(/<\/FONT[^<>]*>/gi,"") + "</FONT>");
    //
                //alert(subText);
    //
            }
            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 tokens = offset.text.split(/[\s\+\-\*\/]/); //token由连续字母数字、下划线、点号、括号、引号构成
        var currentToken = tokens[tokens.length - 1];
        
        
    var idx = offset.text.length;
        
        
    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;
        
        
    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]);
            }

        }

    }

        
    var now = new Date(); //测试用
        var a = 33.3333//测试用
        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,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)
        
    {
        methods.options.length 
    = 0;
        
    for (var i = 0; i < methodList.length; i++)
        
    {
        methods.options.add(
    new Option(methodList[i])); 
        }

        
    if (methods.options.length > 10)
        
    {
        methods.size 
    = 10;
        }

        
    else
        
    {
        methods.size 
    = methods.options.length;
        }

        methods.style.top 
    = oSel.offsetTop;
        methods.style.left 
    = oSel.offsetLeft;
        methods.style.display 
    = "";
        methods.options[
    0].selected = true;
        methods.focus();
        }

        }

        
    catch(e){}
    }


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


    if(event.keyCode == 27 && event.keyCode == 8 && event.keyCode == 32//---------------------------edit
    {
    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 = 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);
    //src.document.execCommand("ForeColor",false,"#ff0000");
    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) //针对token返回rule
    {
    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, cons) //词法规则组(同组规则用一种颜色标记)
    {
    this.name = name; //规则组名称
    this.color = color; //标记该语法的颜色
    this.rules = new Array(); //语法规则(以次序决定优先级)
    this.rules.All = new Array();
    this.cons = 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);
    }

    RegExprX.prototype.concat 
    = 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为\xff
    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",/(trycatchthrow)/));
    SyntaxSet[
    "keywords"].addRule(new SyntaxRule("Condition",/(ifelseswitch)/));
    SyntaxSet[
    "keywords"].addRule(new SyntaxRule("Cycle",/(forwhiledo)/));
    SyntaxSet[
    "keywords"].addRule(new SyntaxRule("Type",/(intdoublefloatvoidchar)/));
    SyntaxSet[
    "keywords"].addRule(new SyntaxRule("Right",/(publicprivateprotectedstatic)/));
    SyntaxSet[
    "keywords"].addRule(new SyntaxRule("Constant",/(nullundefinedNaNInfinity)/));
    SyntaxSet[
    "keywords"].addRule(new SyntaxRule("Construct",/(newdelete)/));

    SyntaxSet.add(
    new Syntaxes("objects""#FF0000"/[\s\.\xfe\xff\xfd\(\{\}\)\;\,]/)); //词法?对象?红色
    SyntaxSet["objects"].addRule(new SyntaxRule("Object",/(ArrayargumentsBooleanDateErrorFunctionObjectNumberMathRegExpString)/));

    SyntaxSet.add(
    new Syntaxes("global""#800000"/[\s\.\xfe\xff\xfd\(\{\}\)\;\,]/)); //词法?系统函数?红色
    SyntaxSet["global"].addRule(new SyntaxRule("SystemFunc",/(alertparseFloatparseIntevaldecodeURIdecodeURIComponentencodeURIencodeURIComponentescapeevalisFiniteisNaNunescape)/));

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

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

    function Grammars() //语法规则
    {
    }

    </script>
    </body>
    </html>


  • 相关阅读:
    07.31《jQuery》——3.2文件上传、添加删除文件域
    07.31《jQuery》——3.1jQuery实现DOM节点的增删改
    07.30《jQuery》——2.2使用键盘上下左右键控制div框
    07.30《jQuery》——2.1div框的移动
    07.30《jQuery》——2.1隔行换色_简单的选择器练习
    【leetcode 530】刷题问题
    数据库基本概念之事务与并发控制
    我的LaTeX中文文档模板
    vim的使用与配置
    LaTeX简单使用方法
  • 原文地址:https://www.cnblogs.com/shengshuai/p/jseditor.html
Copyright © 2011-2022 走看看