zoukankan      html  css  js  c++  java
  • 前端代码编辑器ace 语法验证

    本文主要是介绍实际项目中如何加入语法检测功能。官方文档链接https://github.com/ajaxorg/ace/wiki/Syntax-validation


          代码编辑器ace,使用webworker进行实时语法检查。目前支持JavaScript,json,php,coffeescript,css,xquery模式。
          根据官方https://ace.c9.io/#nav=higlighter的例子,在项目开发中,新增了Formula的语法高亮,下面是定义Mode并增加语法高亮的部分代码
          //parserNet是parser模块,在发生错误的时候会主动调用parseError方法

          至于怎么实现语法检测的功能,比较复杂,涉及到编译原理,语法词法分析的知识。这个我了解的也只是入门,有时间的时候再介绍吧

    ace.define("ace/mode/formula", ["require", "exports", "module", "ace/lib/oop", "ace/mode/text", "ace/mode/formula_highlight_rules"], function (acequire, exports, module) {
    
        var oop = acequire("../lib/oop");
        var TextMode = acequire("./text").Mode;
        var FormulaHighlightRules = acequire("./formula_highlight_rules").FormulaHighlightRules;
    
        var Mode = function () {
            this.HighlightRules = FormulaHighlightRules;
            this.$behaviour = this.$defaultBehaviour;
        };
        oop.inherits(Mode, TextMode);
    
        (function () {
            this.lineCommentStart = "//";
            this.$id = "ace/mode/formula";
    
            this.createWorker = function (session) {
                var worker = {
                    //编辑器销毁或修改模式的时候
                    terminate: function () {
                        session.clearAnnotations(); //清除错误信息
                        this.$worker = null;
                        if (this.$doc)
                            this.$doc.off("change", this.changeListener);
                        this.changeListener = null;
                        this.$doc = null;
                    },
                    //文档变化的回调
                    _changeListener: function () {
                        if (!this.$doc) return;
                        var val = this.$doc.getValue();
                        if (val.trim() === "") {
                            session.clearAnnotations(); //清除错误信息
                            return;
                        }
                        var res = [];
                        //重写parserNet.parseError方法,收集错误信息
                        parserNet.parseError = function (str, obj) {
                            var column = obj.loc ? obj.loc.first_column : 0;
                            res.push({
                                column: column,
                                raw: str,
                                row: obj.line,
                                text: str,
                                type: "error"
                            })
                        }
                        try {
                            //parserNet.parse实时检测代码功能
                            parserNet.parse(val);
                        } catch (e) {
                        }
                        session.setAnnotations(res)//显示错误信息
                    },
                    //绑定文档对象的时候
                    attachToDocument(doc) {
                        if (this.$doc)
                            this.terminate();
                        this.$doc = doc;
                        this.changeListener = _.debounce(this._changeListener.bind(this), 500);
                        this.changeListener();
                        //绑定change文档事件
                        doc.on("change", this.changeListener);
                    },
                    //响应weoker中发出的消息,this.sender.emit("annotate",[])消息,也可以定义其他的消息名称
                    annotate(results) {
                        session.setAnnotations(results);
                    }
                };
    //绑定文档 worker.attachToDocument(session.getDocument());
    return worker; }; }).call(Mode.prototype);

            在实际项目中,有可能是给ace已存在的高亮增加语法检测,下面是webpack打包项目中的写法,主要参考怎么引用已存在的ace模式

    import 'brace/mode/mysql.js'
    import {parserMySql} from '../mysql/mysqlParser.js';
    var MysqlMode = ace.acequire("ace/mode/mysql").Mode;
    (function () {
        this.createWorker = function (session) {
            var worker = {
                terminate: function () {
                    session.clearAnnotations();
                    this.$worker = null;
                    if (this.$doc)
                        this.$doc.off("change", this.changeListener);
                    this.changeListener = null;
                    this.$doc = null;
                },
                _changeListener: function () {
                    if (!this.$doc) return;
                    var val = this.$doc.getValue();
                    var res = [];
                    parserMySql.parseError = function (str, obj) {
                        var column = obj.loc ? obj.loc.first_column : 0;
                        res.push({
                            column: column,
                            raw: str,
                            row: obj.line,
                            text: str,
                            type: "error"
                        })
                    }
                    if (val.trim().length === 0) {
                        res.push({
                            column: 0,
                            raw: "该字段不能为空",
                            row: 0,
                            text: "该字段不能为空",
                            type: "error"
                        })
                    } else {
                        try {
                            parserMySql.parse(val);
                        } catch (e) {
                        }
                    }
                    session.setAnnotations(res)
                },
                attachToDocument(doc) {
                    if (this.$doc)
                        this.terminate();
                    this.$doc = doc;
                    this.changeListener = _.debounce(this._changeListener.bind(this), 500);
                    this.changeListener();
                    doc.on("change", this.changeListener);
                },
                annotate(results) {
                    session.setAnnotations(results);
                }
            };
            worker.attachToDocument(session.getDocument());
            return worker;
        };
    }).call(MysqlMode.prototype);
  • 相关阅读:
    VMware6.0-vCenter的安装准备及安装
    VeeamBackup9.5安装与配置
    VeeamOne(Free Edition 9.5 )-安装与配置
    UIDatePicker
    UIImagePicker照片选择器
    UIImageView
    UILabel
    UIScrollView 期本使用方法
    UISegment
    UISlide
  • 原文地址:https://www.cnblogs.com/legu/p/8330947.html
Copyright © 2011-2022 走看看