123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545 |
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="utf-8" />
- <title></title>
- <!--jquery-->
- <script src="./extra/jquery/jquery.min.js"></script>
- <!--ztree-->
- <link href="./extra/ztree/css/zTreeStyle/zTreeStyle.css" rel="stylesheet" />
- <script src="./extra/ztree/js/jquery.ztree.all.min.js"></script>
- <script src="./extra/ztree/js/jquery.ztree.exhide.min.js"></script>
- <script src="extra/layer/layer.min.js"></script>
- <!--zlExpressEditor-->
- <link href="./css/ExpressEditor.css" rel="stylesheet" />
- <script src="./monaco-editor/min/vs/loader.min.js"></script>
- <script src="./js/EnvironmentHelper.js"></script>
- <script src="./js/ExpressEditor.js"></script>
- <script src="./js/ExpressExecutor.js"></script>
- <script>
- //测试代码
- (function () {
- //编辑器配置信息
- let setting = {
- //初始化的时候需要设置的值
- "value": "",
- //编辑器语言
- "language": "javascript",
- //是否只读
- "readonly": false,
- //是否显示左侧资源树
- "showResource": true,
- //显示资源树的部件页卡
- "showPartResource": true,
- //左侧资源树的第一个页卡的名称
- "partResourceTabName": "部件",
- //显示函数资源树页卡
- "showFunctionResource": true,
- //显示参数资源树部件页卡
- "showParameterResource": true,
- //是否显示校验按钮
- "showCheckButton": false,
- //是否开起缩略图
- "minimap": false,
- //表达式返回值类型
- "returnType": EnvironmentHelper.PropertyType.Any,
- //资源信息[第一个页卡,可能没有]
- "resource": [
- {
- //必填,且必须满足JS的变量定义规则
- "id": "id",
- //显示名,必填,用于在表达式编辑器显示用的名称
- "name": "部件1",
- /**
- 节点类型
- path:表示参与路径提示(如例子中的“属性”);
- group:表示不参与路径(如例子中的“方法”);
- property:表示该节点是个属性;
- method:表示该节点表示一个方法;
- property和method只能出现在叶子节点;
- */
- "nodetype": EnvironmentHelper.ResourceNodeType.Path,
- "nodes": [
- {
- "id": "properties",
- "name": "属性",
- "nodetype": EnvironmentHelper.ResourceNodeType.Path,
- "nodes": [
- {
- "id": "P_BJID",
- "name": "部件ID",
- "nodetype": EnvironmentHelper.ResourceNodeType.Property,
- //描述信息,当用户鼠标悬停或进行“.”操作的时候出现提示
- "note": "描述信息",
- //根据nodetype的不同,有不同的description
- "description": {
- //默认值,进行表达式校验的时候使用的值,可以不指定,而后系统以给定类型虚拟一个默认值进行校验
- "value": 123,
- //必填:属性(property)的数据类型,用于校验返回结果类型
- "type": EnvironmentHelper.PropertyType.Number,
- }
- },
- {
- "id": "P_BJMC",
- "name": "部件名称",
- "nodetype": "property",
- "note": "描述信息",
- "description": {
- "value": "text",
- "type": "string",
- }
- },
- {
- "id": "P_CS",
- "name": "选项测试",
- "nodetype": EnvironmentHelper.ResourceNodeType.Property,
- "note": "描述信息",
- "description": {
- "value": [
- { display: "枚举Key1", value: "枚举Value1" },
- { display: "枚举Key2", value: "枚举Value2" },
- { display: "枚举Key3", value: "枚举Value3" }
- ],
- "type": EnvironmentHelper.PropertyType.Enum,
- "selItemMode": "value",//或:display(选择“选项明细”返回name)
- "showMode": "表达式编辑"//或:选项值域选择(不显示运算符)
- }
- },
- {
- "id": "P_CS2",
- "name": "选项测试2",
- "nodetype": EnvironmentHelper.ResourceNodeType.Property,
- "note": "描述信息",
- "description": {
- "value": function (pid) {
- //xxxx
- return [
- { display: 1, value: 1 },
- { display: 2, value: 2 },
- { display: 3, value: 2 }
- ];
- },
- "type": EnvironmentHelper.PropertyType.Enum,
- "selItemMode": "value",//或:display(选择“选项明细”返回name)
- "showMode": "表达式编辑"//或:选项值域选择(不显示运算符)
- }
- }
- ]
- },
- {
- "id": "methods",
- "name": "方法",
- //group:表示该节点仅用于分组,即弹出式表达式的左侧树形界面的分组,在实际使用中,并不参数路径精算。例如本例中,是直接通过"部件1.getSelection()"进行访问该方法,绕开“方法”两个字
- "nodetype": "group",
- "nodes": [
- {
- "id": "getSelection",
- "name": "获取焦点行",
- "nodetype": "method",
- "note": "描述信息",
- "description": {
- "content": function () { },
- //方法的默认返回值,若没有返回值,则根据返回类型(returnType)虚拟一个默认返回值
- "returnValue": "text",
- //返回类型
- "returnType": "string",
- //参数信息,数组类型,每个参数按给定顺序输入
- "argsInfo": [{
- //参数名
- "argName": "arg1",
- //参数的类型
- "argType": "string",
- //参数的描述信息,在用户输入参数的时候进行提示
- "argNote": "第1个参数的描述信息"
- },
- {
- "argName": "arg2",
- "argType": "number",
- "argNote": "第2个参数的描述信息"
- }]
- }
- }
- ]
- }
- ]
- }
- ],
- //扩展的其他函数方法
- "extension": [
- {
- //名称需要唯一
- "name": "ComponentBase",
- //通过文件的方式装载
- "type": "file",
- //基于跟目录的绝对路径的JS文件[文件路径必须使用正斜杠]
- "filePath": "/component/ComponentBase.js",
- //是否加入左侧资源树[可以不传,默认是true]
- "addInResource": true
- },
- {
- //名称需要唯一
- "name": "own",
- //通过实例的方式装载
- "type": "instance",
- //实例对象
- "instance": new Object()
- },
- {
- //名称需要唯一
- "name": "selfDefined",
- //直接通过写代码引用
- "type": "code",
- //基于跟目录的绝对路径的JS文件[文件路径必须使用正斜杠]
- "jsCode": "var _self = new TableControl();"
- }
- ],
- //是否启用公共函数库,公共函数库的路径在"./extra/CommonFunctions.js",该文件内定义的所有方法都将被添加到控件的智能提示库
- "useCommonFunctions": true,
- //扩展参数[参数页卡],配置信息与上方资源信息(resource)相视,但不允许出现method类型的节点
- "parameters": [
- {
- "id": "id",
- "name": "系统参数",
- "nodetype": "group",
- "nodes": [{
- "id": "id1",
- "name": "系统参数1",
- "nodetype": "property",
- "description": {
- "value": "text",
- "type": "string",
- }
- }, {
- "id": "id2",
- "name": "系统参数2",
- "nodetype": "property",
- "description": {
- "value": "text",
- "type": "string",
- }
- }],
- },
- {
- "id": "id",
- "name": "环境参数",
- "nodetype": "group",
- "nodes": [{
- "id": "id1",
- "name": "环境参数1",
- "nodetype": "property",
- "description": {
- "value": "text",
- "type": "string",
- }
- }],
- }
- ],
- //提示词(用于自动补全的词语)
- "promptWords":["测试1","麻醉中"]
- }
- window.onload = function () {
- init_demo = function () {
- InitEditor(setting);
- }
- }
- })();
- function init_demo() {
- }
- </script>
- </head>
- <body>
- <div class="container-fluid">
- <div class="row mt-1">
- <div class="zl-side">
- <ul class="nav nav-tabs" id="myTab" role="tablist">
- <li class="nav-item">
- <a class="nav-link active" id="first-tab" data-toggle="tab" href="#first" role="tab" aria-controls="first" aria-selected="true">
- <h6 id="tabPartName">部件</h6>
- </a>
- </li>
- <li class="nav-item">
- <a class="nav-link" id="second-tab" data-toggle="tab" href="#second" role="tab" aria-controls="second" aria-selected="false">
- <h6>函数</h6>
- </a>
- </li>
- <li class="nav-item">
- <a class="nav-link" id="third-tab" data-toggle="tab" href="#third" role="tab" aria-controls="third" aria-selected="false">
- <h6>参数</h6>
- </a>
- </li>
- </ul>
- <div class="tab-content" id="myTabContent">
- <div class="tab-pane fade show active" id="first" role="tabpanel" aria-labelledby="first-tab">
- <div class="row" style="height:40px;">
- <div class="col col-12">
- <div class="app-property-search">
- <div style="display:flex;">
- <i style="display: flex; align-content: center; justify-content: center; flex-wrap: wrap;">
- <svg style="width:20px;height:20px;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
- <circle cx="11" cy="11" r="8"></circle>
- <line x1="21" y1="21" x2="16.65" y2="16.65"></line>
- </svg>
- </i>
- <input type="text" autocomplete="off" class="search" name="search" placeholder="输入名称进行搜索..." value="" />
- </div>
- </div>
- </div>
- </div>
- <div class="row" style="height:calc(100% - 40px)">
- <div class="col-12 nav-height-item">
- <div id="resource-tree" class="ztree"></div>
- </div>
- </div>
- </div>
- <div class="tab-pane fade" id="second" role="tabpanel" aria-labelledby="tabpanel-tab">
- <div class="row" style="height:40px;">
- <div class="col col-12">
- <div class="app-property-search">
- <div>
- <i style="display: flex; align-content: center; justify-content: center; flex-wrap: wrap;">
- <svg style="width:20px;height:20px;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
- <circle cx="11" cy="11" r="8"></circle>
- <line x1="21" y1="21" x2="16.65" y2="16.65"></line>
- </svg>
- </i>
- <input type="text" autocomplete="off" class="search" name="search" placeholder="输入名称进行搜索..." value="" />
- </div>
- </div>
- </div>
- </div>
- <div class="row" style="height:calc(100% - 40px)">
- <div class="col-12 nav-height-item">
- <div id="function-tree" class="ztree"></div>
- </div>
- </div>
- </div>
- <div class="tab-pane fade" id="third" role="tabpanel" aria-labelledby="tabpanel-tab">
- <div class="row" style="height:40px;">
- <div class="col col-12">
- <div class="app-property-search">
- <div>
- <i style="display: flex; align-content: center; justify-content: center; flex-wrap: wrap;">
- <svg style="width:20px;height:20px;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
- <circle cx="11" cy="11" r="8"></circle>
- <line x1="21" y1="21" x2="16.65" y2="16.65"></line>
- </svg>
- </i>
- <input type="text" autocomplete="off" class="search" name="search" placeholder="输入名称进行搜索..." value="" />
- </div>
- </div>
- </div>
- </div>
- <div class="row" style="height:calc(100% - 40px)">
- <div class="col-12 nav-height-item">
- <div id="parameter-tree" class="ztree"></div>
- </div>
- </div>
- </div>
- </div>
- </div>
- <div class="zl-side-splitter side-splitter-tb">
- <button class="zl-side-btn-svg" type="button" aria-expanded="true" title="折叠">
- <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Layer_1" x="0px" y="0px" width="8px" height="24px" viewBox="0 0 8 24" enable-background="new 0 0 8 24" xml:space="preserve"><g opacity="0.8"> <polygon fill="#231F20" points="2,12 6,8 6,16 " /></g></svg>
- </button>
- </div>
- <div class="zl-main nav-height-editor">
- <div class="editor-btn px-3 editor-test-button" style="text-align: right;">
- <button class="btn btn-info btn-sm btn-editor" id="editor-test">校验</button>
- </div>
- <div id="editor" class="editor-style"></div>
- <div class="lay-message">
- <div class="lay-message-title" id="messageTitle">
- <span class="message-title-name">输出信息:</span>
- <span class="message-title-icon"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" class="message-icon" x="0px" y="0px" width="8px" height="24px" viewBox="0 0 8 24" enable-background="new 0 0 8 24" xml:space="preserve"><g opacity="0.8"> <polygon fill="#231F20" points="2,12 6,8 6,16 "></polygon></g></svg></span>
- </div>
- <div class="lay-message-value" id="debug-message">
- </div>
- </div>
- </div>
- </div>
- <div class="row">
- <div class="col-sm-12 mt-1">
- <div id="text">
- </div>
- </div>
- </div>
- </div>
- <script>
- (function () {
- //消息折叠展开
- $('#messageTitle').click(function (e) {
- if ($(".lay-message").hasClass("message-close")) {
- $(".lay-message").removeClass("message-close");
- } else {
- $(".lay-message").addClass("message-close");
- }
- });
- //分割功能
- Divsions({
- dDom: document.querySelector('.zl-side-splitter'),
- direction: 'vertical',
- foldDir: 'left',
- minSize: [{
- direction: 'prev',
- minisize: 144,
- opt: 'fold'
- }],
- //拖动结束后执行
- dropEnd() {
- if (editor) {
- editor.layout();
- }
- }
- })
- // 分割功能
- function Divsions(opt) {
- let dDom = opt.dDom // 分割线条
- let initX = 0; // 设置偏移量
- let fx = opt.direction // 设置分割方向 vertical(左右) crosswise(上下分割)
- let minsize = opt.minSize // 设置限制[{direction: 'prev', minisize: 200, opt:'fold'}]
- let prSize = null // 记录原始大小
- let foldDir = opt.foldDir // 折叠方向
- let dropEnd = opt.dropEnd;
- dDom.addEventListener('mousedown', BindDivisionClickEvent);
- dDom.querySelector('button').addEventListener('click', function (e) {
- e.stopPropagation()
- if (e.button !== 0) return
- Flod();
- });
- /**绑定分割条的事件(左右) */
- function BindDivisionClickEvent(e) {
- e.preventDefault()
- if (e.button !== 0) return
- initX = fx === 'vertical' ? e.clientX : e.clientY;
- fx === 'vertical' ? dDom.prOffsetLeft = dDom.offsetLeft : dDom.prOffsetTop = dDom.offsetTop
- dDom.style.position = 'relative';
- document.addEventListener('mousemove', BindDivsionMoveEvent);
- document.addEventListener('mouseup', BindDivsionUpMouseEvent);
- }
- function BindDivsionMoveEvent(e) {
- if (e.button !== 0) return
- e.preventDefault();
- if (!dDom) return;
- fx === 'vertical' ? dDom.style.left = (e.clientX - initX) + 'px' : dDom.style.top = (e.clientY - initX) + 'px';
- }
- function BindDivsionUpMouseEvent(e) {
- document.removeEventListener('mousemove', BindDivsionMoveEvent);
- document.removeEventListener('mouseup', BindDivsionUpMouseEvent);
- CalcDomWidth();
- typeof dropEnd === 'function' && dropEnd()
- }
- /**计算dom 宽度 */
- function CalcDomWidth() {
- CalcMiniSize()
- dDom.style.position = ''; // 清除分割条的定位样式
- dDom.style[fx === 'vertical' ? 'left' : 'top'] = '';
- }
- /**设置大小 */
- function setSize(size) {
- fx === 'vertical' ? (function () {
- dDom.previousElementSibling.style.width = size.prev; // 设置前一个的dom宽度
- dDom.nextElementSibling.style.width = size.next; // 设置后者的宽度
- })() : (function () {
- dDom.previousElementSibling.style.height = size.prev; // 设置前一个的dom宽度
- dDom.nextElementSibling.style.height = size.next; // 设置后者的宽度
- })()
- }
- /**获取上一级的大小 */
- function getPrevSize() {
- let cx = fx === 'vertical' ? dDom.offsetLeft : dDom.offsetTop; // 当前鼠标距离左边框距离
- if ((fx === 'vertical' ? dDom.prOffsetLeft : dDom.prOffsetTop) === cx) return; // 未发生位置偏移时,停止操作
- return cx
- }
- /**获取总宽度 */
- function getAllSize() {
- return fx === 'vertical' ? dDom.parentElement.clientWidth : dDom.parentElement.clientHeight;
- }
- /**折叠 */
- function Flod() {
- if (dDom.classList.contains('is-flod')) {
- foldDir === 'left' || foldDir === 'top' ? dDom.previousElementSibling.style.display = '' : dDom.nextElementSibling.style.display = '';
- setSize(prSize)
- dDom.classList.remove('is-flod')
- } else {
- prSize = {
- prev: fx === 'vertical' ? dDom.previousElementSibling.style.width : dDom.previousElementSibling.style.height,
- next: fx === 'vertical' ? dDom.nextElementSibling.style.width : dDom.nextElementSibling.style.height
- }
- // 折叠
- // 获取折叠方向
- if (foldDir === 'left' || foldDir === 'top') {
- dDom.previousElementSibling.style.display = 'none';
- dDom.nextElementSibling.style[fx === 'vertical' ? 'width' : 'height'] = 'calc(100% - 10px)'
- } else {
- dDom.nextElementSibling.style.display = 'none';
- dDom.previousElementSibling.style[fx === 'vertical' ? 'width' : 'height'] = 'calc(100% - 10px)'
- }
- dDom.classList.add('is-flod')
- }
- if (editor) {
- editor.layout();
- console.log("enter");
- }
- }
- /**计算最小问题 */
- function CalcMiniSize() {
- let pSize = getPrevSize()
- if (pSize === undefined) return
- let aSize = getAllSize()
- let nSize = aSize - pSize
- let psize = getMinSize('prev') // 获取前一个dom的最小值
- let nsize = getMinSize('next') // 获取后一个dom的最小值
- let pState = psize && pSize < psize.minisize && psize.opt
- let nState = nsize && nSize < nsize.minisize && nsize.opt
- // 折叠
- if (pState === 'fold' || nState === 'fold') {
- Flod()
- } else {
- dDom.previousElementSibling.style.display === 'none' ? dDom.previousElementSibling.style.display = '' : '';
- dDom.nextElementSibling.style.display === 'none' ? dDom.nextElementSibling.style.display = '' : '';
- let f = (pSize / aSize).toFixed(2) // 算出比例
- // 剩下则是正常执行
- setSize({
- prev: `calc(${f * 100}% - 5px)`,
- next: `calc(${(1 - f) * 100}% - 5px)`
- })
- dDom.classList.remove('is-flod')
- }
- }
- /**获取最小宽度 */
- function getMinSize(d) {
- return minsize.find(a => a.direction === d);
- }
- }
- })()
- </script>
- </body>
- </html>
|