1/* 2 * Copyright (c) 2022-2023 Shenzhen Kaihong Digital Industry Development Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16const { AttributeArea } = require('./attr/AttributeArea'); 17const { ModifyNode } = require('./hcs/ModifyNode'); 18const { DataType, NodeType } = require('./hcs/NodeTools'); 19const { NodeTools } = require('./hcs/NodeTools'); 20const INT64_MAX = 9223372036854775807n; 21const INT64_MIN = -9223372036854775808n; 22const CASE_DELETE = 5; 23const CASE_QUOTE = 4; 24const CASE_BOOL = 3; 25const CASE_ARRAY = 2; 26const CASE_CHARACTER_STR = 1; 27const CASE_INTEGER = 0; 28 29class AttrEditor { 30 constructor() { 31 AttributeArea.gi().registRecvCallback(this.onChange); 32 this.files_ = []; 33 this.callback_ = null; 34 } 35 setFiles(files) { 36 this.files_ = files; 37 } 38 freshEditor(fn, node) { 39 this.filePoint_ = fn; 40 this.node_ = node; 41 if (fn in this.files_) { 42 this.root_ = this.files_[fn]; 43 } 44 45 AttributeArea.gi().clear(); 46 if (this.node_ !== null && this.node_ !== undefined) { 47 AttributeArea.gi().addTitle(this.node_.name_); 48 switch (this.node_.type_) { 49 case DataType.NODE: 50 switch (this.node_.nodeType_) { 51 case NodeType.DATA: 52 this.freshDataNodeNotInheritEditor(this.node_); 53 break; 54 case NodeType.COPY: 55 case NodeType.REFERENCE: 56 case NodeType.INHERIT: 57 this.freshcopyNodeEditor(this.node_); 58 break; 59 case NodeType.DELETE: 60 this.freshdeleteNodeEditor(this.node_); 61 break; 62 case NodeType.TEMPLETE: 63 this.freshTempletNodeEditor(this.node_); 64 break; 65 default: 66 break; 67 } 68 break; 69 case DataType.ATTR: 70 this.freshDefineAttributeEditor(this.node_); 71 break; 72 } 73 } else { 74 AttributeArea.gi().addTitle('Property editing area'); 75 } 76 77 AttributeArea.gi().flush(); 78 } 79 80 freshDataNodeNotInheritEditor(node) { 81 AttributeArea.gi().addDotLine(); 82 AttributeArea.gi().addTopInput( 83 'name', 84 'Node Name', 85 node.name_, 86 this.root_ == this.node_ 87 ); 88 AttributeArea.gi().addSelect( 89 'node_type', 90 'Node Type', 91 AttrEditor.NODE_TYPE_STR, 92 AttrEditor.NODE_TYPE_STR[node.nodeType_], 93 this.root_ == this.node_ 94 ); 95 } 96 changeDataNodeNotInherit(searchId, type, value) { 97 if (searchId === 'node_type') { 98 AttrEditor.gi().changeNodeType(value); 99 } else if (searchId === 'name' && this.node_.name_ !== value) { 100 ModifyNode.modifyName(this.files_, this.root_, this.node_, value); 101 } else if (searchId === 'add_child_node') { 102 this.node_.isOpen_ = true; 103 let newNode = ModifyNode.addChildNode(this.root_, this.node_); 104 this.callCallback('change_current_select', newNode); 105 } else if (searchId === 'add_child_attr') { 106 this.node_.isOpen_ = true; 107 let newNode = ModifyNode.addChildAttr(this.root_, this.node_); 108 this.callCallback('change_current_select', newNode); 109 } else if (searchId === 'delete') { 110 ModifyNode.deleteNode(this.node_); 111 this.freshEditor(); 112 } 113 } 114 freshcopyNodeEditor(node) { 115 AttributeArea.gi().addDotLine(); 116 AttributeArea.gi().addTopInput('name', 'Node Name', node.name_); 117 AttributeArea.gi().addSelect( 118 'node_type', 119 'Node Type', 120 AttrEditor.NODE_TYPE_STR, 121 AttrEditor.NODE_TYPE_STR[node.nodeType_], 122 this.root_ == this.node_ 123 ); 124 let btnName = node.ref_; 125 if (btnName === 'unknow') { 126 switch (node.nodeType_) { 127 case NodeType.COPY: 128 btnName = '取消复制'; 129 break; 130 case NodeType.INHERIT: 131 btnName = '取消继承'; 132 break; 133 case NodeType.REFERENCE: 134 btnName = '取消引用'; 135 break; 136 } 137 } 138 AttributeArea.gi().addLabelButton( 139 'change_target', 140 btnName, 141 'Original Node' 142 ); 143 } 144 145 changecopyNode(searchId, type, value) { 146 if (searchId === 'name' && this.node_.name_ !== value) { 147 ModifyNode.modifyName(this.files_, this.root_, this.node_, value); 148 } else if (searchId === 'change_target') { 149 if (this.node_.ref_ === 'unknow') { 150 ModifyNode.modifyNodeType(this.files_, this.root_, this.node_, 0); 151 this.freshEditor(this.filePoint_, this.node_); 152 this.callCallback('cancel_change_target', this.node_); 153 } else { 154 this.callCallback('change_target', this.node_); 155 } 156 } else if (searchId === 'node_type') { 157 AttrEditor.gi().changeNodeType(value); 158 } else if (searchId === 'add_child_node') { 159 ModifyNode.addChildNode(this.root_, this.node_); 160 } else if (searchId === 'add_child_attr') { 161 ModifyNode.addChildAttr(this.root_, this.node_); 162 } else if (searchId === 'delete') { 163 ModifyNode.deleteNode(this.node_); 164 this.freshEditor(); 165 } 166 } 167 168 freshdeleteNodeEditor(node) { 169 AttributeArea.gi().addTopInput('name', 'Node Name', node.name_); 170 AttributeArea.gi().addSelect( 171 'node_type', 172 'Node Type', 173 AttrEditor.NODE_TYPE_STR, 174 AttrEditor.NODE_TYPE_STR[node.nodeType_], 175 this.root_ == this.node_ 176 ); 177 } 178 179 changeNodeType(value) { 180 ModifyNode.modifyNodeType( 181 this.files_, 182 this.root_, 183 this.node_, 184 AttrEditor.NODE_TYPE_STR.indexOf(value) 185 ); 186 this.freshEditor(this.filePoint_, this.node_); 187 if ( 188 this.node_.nodeType_ === NodeType.COPY || 189 this.node_.nodeType_ === NodeType.INHERIT || 190 this.node_.nodeType_ === NodeType.REFERENCE 191 ) { 192 this.callCallback('change_target', this.node_); 193 } 194 } 195 changedeleteNode(searchId, type, value) { 196 if (searchId === 'name' && this.node_.name_ !== value) { 197 ModifyNode.modifyName(this.files_, this.root_, this.node_, value); 198 } else if (searchId === 'delete') { 199 ModifyNode.deleteNode(this.node_); 200 this.freshEditor(); 201 } else if (searchId === 'node_type') { 202 AttrEditor.gi().changeNodeType(value); 203 } 204 } 205 freshTempletNodeEditor(node) { 206 AttributeArea.gi().addDotLine(); 207 AttributeArea.gi().addTopInput('name', 'Node Name', node.name_); 208 AttributeArea.gi().addSelect( 209 'node_type', 210 'Node Type', 211 AttrEditor.NODE_TYPE_STR, 212 AttrEditor.NODE_TYPE_STR[node.nodeType_], 213 this.root_ == this.node_ 214 ); 215 } 216 changeTempletNode(searchId, type, value) { 217 if (searchId === 'name') { 218 ModifyNode.modifyName(this.files_, this.root_, this.node_, value); 219 } else if (searchId === 'add_child_node') { 220 ModifyNode.addChildNode(this.root_, this.node_); 221 } else if (searchId === 'add_child_attr') { 222 ModifyNode.addChildAttr(this.root_, this.node_); 223 } else if (searchId === 'delete') { 224 ModifyNode.deleteNode(this.node_); 225 this.freshEditor(); 226 } else if (searchId === 'node_type') { 227 AttrEditor.gi().changeNodeType(value); 228 } 229 } 230 231 freshDefineAttributeEditor(node) { 232 let v = node.value_; 233 AttributeArea.gi().addTopInput('name', 'Name', node.name_); 234 235 if ( 236 v.type_ === DataType.INT8 || 237 v.type_ === DataType.INT16 || 238 v.type_ === DataType.INT32 || 239 v.type_ === DataType.INT64) { 240 AttributeArea.gi().addSelect('value_type', 'Type', AttrEditor.ATTR_TYPE_STR, AttrEditor.ATTR_TYPE_STR[CASE_INTEGER]); 241 AttributeArea.gi().addValidatorInput( 242 'value', 'Attribute Value', NodeTools.jinZhi10ToX(v.value_, v.jinzhi_), false, '请输入整数'); 243 } else if (v.type_ === DataType.STRING) { 244 AttributeArea.gi().addSelect('value_type', 'Type', AttrEditor.ATTR_TYPE_STR, AttrEditor.ATTR_TYPE_STR[CASE_CHARACTER_STR]); 245 AttributeArea.gi().addInput('value', 'Attribute Value', v.value_); 246 } else if (v.type_ === DataType.ARRAY) { 247 AttributeArea.gi().addSelect('value_type', 'Type', AttrEditor.ATTR_TYPE_STR, AttrEditor.ATTR_TYPE_STR[CASE_ARRAY]); 248 AttributeArea.gi().addTextArea('value', 'Attribute Value', NodeTools.arrayToString(v, 20)); 249 } else if (v.type_ === DataType.BOOL) { 250 AttributeArea.gi().addSelect('value_type', 'Type', AttrEditor.ATTR_TYPE_STR, AttrEditor.ATTR_TYPE_STR[CASE_BOOL]); 251 AttributeArea.gi().addSelect('value', 'Attribute Value', [true, false], v.value_ == 1); 252 } else if (v.type_ === DataType.REFERENCE) { 253 AttributeArea.gi().addSelect('value_type', 'Type', AttrEditor.ATTR_TYPE_STR, AttrEditor.ATTR_TYPE_STR[CASE_QUOTE]); 254 AttributeArea.gi().addLabelButton('change_target', v.value_, 'Original Node'); 255 } else if (v.type_ === DataType.DELETE) { 256 AttributeArea.gi().addSelect('value_type', 'Type', AttrEditor.ATTR_TYPE_STR, AttrEditor.ATTR_TYPE_STR[CASE_DELETE]); 257 } 258 } 259 260 getNodeValue(v, value) { 261 switch (AttrEditor.ATTR_TYPE_STR.indexOf(value)) { 262 case CASE_INTEGER: 263 v.type_ = DataType.INT8; 264 v.value_ = 0; 265 v.jinzhi_ = 10; 266 break; 267 case CASE_CHARACTER_STR: 268 v.type_ = DataType.STRING; 269 v.value_ = ''; 270 break; 271 case CASE_ARRAY: 272 v.type_ = DataType.ARRAY; 273 v.value_ = []; 274 break; 275 case CASE_BOOL: 276 v.type_ = DataType.BOOL; 277 v.value_ = 1; 278 break; 279 case CASE_QUOTE: 280 v.type_ = DataType.REFERENCE; 281 v.value_ = 'unknow'; 282 break; 283 case CASE_DELETE: 284 v.type_ = DataType.DELETE; 285 break; 286 } 287 this.freshEditor(this.filePoint_, this.node_); 288 } 289 290 validateNumber(value) { 291 let validRes = {}; 292 validRes.errMsg = ''; 293 let ret = NodeTools.jinZhiXTo10(value); 294 if (ret[0] === undefined) { 295 validRes.errMsg = '请输入整数'; 296 } 297 298 if (ret[0] > INT64_MAX || ret[0] < INT64_MIN) { 299 validRes.errMsg = '数字大小不能超出Int64范围'; 300 } 301 validRes.value = ret[0]; 302 validRes.base = ret[1]; 303 return validRes; 304 } 305 306 changeDefineAttribute(searchId, type, value) { 307 let v = this.node_.value_; 308 if (searchId === 'name' && value !== this.node_.name_) { 309 ModifyNode.modifyName(this.files_, this.root_, this.node_, value); 310 } 311 if (searchId === 'value_type') { 312 this.getNodeValue(v, value); 313 } 314 if (searchId === 'change_target') { 315 this.callCallback('change_target', v); 316 } 317 if (searchId === 'value') { 318 if ( 319 v.type_ === DataType.INT8 || 320 v.type_ === DataType.INT16 || 321 v.type_ === DataType.INT32 || 322 v.type_ === DataType.INT64 323 ) { 324 let validRes = this.validateNumber(value); 325 let validatorLabel = document.getElementById('valid_' + searchId); 326 if (validRes.errMsg === '') { 327 validatorLabel.style.display = 'none'; 328 v.value_ = validRes.value; 329 v.jinzhi_ = validRes.base; 330 } else { 331 validatorLabel.innerText = validRes.errMsg; 332 validatorLabel.style.display = ''; 333 } 334 } else if (v.type_ === DataType.STRING) { 335 v.value_ = value; 336 } else if (v.type_ === DataType.ARRAY) { 337 v.value_ = NodeTools.stringToArray(value); 338 } else if (v.type_ === DataType.BOOL) { 339 v.value_ = value === 'true' ? 1 : 0; 340 } 341 } 342 if (searchId === 'delete') { 343 ModifyNode.deleteNode(this.node_); 344 this.freshEditor(); 345 } 346 } 347 onChange(searchId, type, value) { 348 let pattr = AttrEditor.gi(); 349 if (pattr.node_ !== null) { 350 AttributeArea.gi().addTitle(pattr.node_.name_); 351 switch (pattr.node_.type_) { 352 case DataType.NODE: 353 switch (pattr.node_.nodeType_) { 354 case NodeType.DATA: 355 pattr.changeDataNodeNotInherit(searchId, type, value); 356 break; 357 case NodeType.COPY: 358 case NodeType.REFERENCE: 359 case NodeType.INHERIT: 360 pattr.changecopyNode(searchId, type, value); 361 break; 362 case NodeType.DELETE: 363 pattr.changedeleteNode(searchId, type, value); 364 break; 365 case NodeType.TEMPLETE: 366 pattr.changeTempletNode(searchId, type, value); 367 break; 368 default: 369 break; 370 } 371 break; 372 case DataType.ATTR: 373 pattr.changeDefineAttribute(searchId, type, value); 374 break; 375 } 376 pattr.callCallback('writefile'); 377 } 378 } 379 380 callCallback(type, value) { 381 if (this.callback_ !== null) { 382 this.callback_(type, value); 383 } 384 } 385 registCallback(func) { 386 this.callback_ = func; 387 } 388} 389 390AttrEditor.NODE_TYPE_STR = [ 391 '数据类不继承', 392 '复制类', 393 '引用修改类', 394 '删除类', 395 '模板类', 396 '数据类继承', 397]; 398AttrEditor.ATTR_CLASS = ['定义类属性', '删除类属性', '引用类属性']; 399 400AttrEditor.ATTR_TYPE_STR = ['整数', '字符串', '数组', '布尔', '引用', '删除']; 401 402AttrEditor.pInstance_ = null; 403AttrEditor.gi = function () { 404 if (AttrEditor.pInstance_ === null) { 405 AttrEditor.pInstance_ = new AttrEditor(); 406 } 407 return AttrEditor.pInstance_; 408}; 409 410module.exports = { 411 AttrEditor, 412}; 413