cuxml 1.0.4 → 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -72,10 +72,6 @@ function onthing(ctrl){
72
72
  ```
73
73
  or
74
74
  ```bash
75
- cuxml # if install cuxml global
76
- ```
77
- or
78
- ```bash
79
75
  node ./node_modules/cuxml/index.js # last choice……
80
76
  ```
81
77
  > 更多命令行参数请查看 --help 选项.
@@ -85,11 +81,22 @@ function onthing(ctrl){
85
81
 
86
82
  **输出结果到文件时,保险起见,最好输出到临时文件,避免覆盖你已经写好的文件。**
87
83
 
88
- ## Issues
89
-
90
- UBW😄
91
-
92
- 1. [cuxml issues]()
84
+ ## 最新更新
85
+
86
+ 1. check仅输出有'问题'的 Element。
87
+ 2. callback :
88
+ + id 为空的 Element 会被忽略。
89
+ + 匹配属性的回调函数返回值类型,在注释中标明。
90
+ + JS 函数的注释中,添加了回调函数对应的 XML 元素属性。
91
+ + 生成的 JS 函数只有一个参数,即 RibbonUI 对象。**不必添加多余的参数,目前 WPS Office Client 传参数时只有一个!**
92
+ ```js
93
+ // RibbonUI 对象成员大概如下:
94
+ {
95
+ Id: "test1", // 当前元素的 id 属性
96
+ content:{...},
97
+ Tag: "",// 如果你在 XML 中设置了 tag 属性,这里就会有值。
98
+ }
99
+ ```
93
100
 
94
101
  ## Bug
95
102
 
@@ -130,10 +137,4 @@ UBW, 😄
130
137
  <group id="test1" getVisible="new nothing"></group>
131
138
  ```
132
139
 
133
- ```js
134
- myRibbon.nothing(ctrl); // myRibbon={nothing:function(ctrl){}};
135
- a.b.c.nothing(ctrl); // a.b.c={nothing:function(ctrl){}};
136
- new nothing(ctrl); // class nothing{constructor(ctrl){}};
137
- ```
138
-
139
140
  所以……如果你需要将 XML 中的诸如以上的回调函数转换为 JS 函数,也许你得自己写一些代码了。
package/cbfTypes.json CHANGED
@@ -1,7 +1,7 @@
1
1
  [
2
2
  {
3
3
  "n": "getVisible",
4
- "t": "string"
4
+ "t": "boolean"
5
5
  },
6
6
  {
7
7
  "n": "getDescription",
@@ -9,7 +9,7 @@
9
9
  },
10
10
  {
11
11
  "n": "getEnabled",
12
- "t": "string"
12
+ "t": "boolean"
13
13
  },
14
14
  {
15
15
  "n": "getImage",
@@ -29,15 +29,15 @@
29
29
  },
30
30
  {
31
31
  "n": "getShowImage",
32
- "t": "string"
32
+ "t": "boolean"
33
33
  },
34
34
  {
35
35
  "n": "getShowLabel",
36
- "t": "string"
36
+ "t": "boolean"
37
37
  },
38
38
  {
39
39
  "n": "getSize",
40
- "t": "string"
40
+ "t": "number"
41
41
  },
42
42
  {
43
43
  "n": "getSupertip",
@@ -45,15 +45,15 @@
45
45
  },
46
46
  {
47
47
  "n": "onAction",
48
- "t": "string"
48
+ "t": "void"
49
49
  },
50
50
  {
51
51
  "n": "getPressed",
52
- "t": "string"
52
+ "t": "boolean"
53
53
  },
54
54
  {
55
55
  "n": "getItemCount",
56
- "t": "string"
56
+ "t": "number"
57
57
  },
58
58
  {
59
59
  "n": "getItemID",
@@ -81,7 +81,7 @@
81
81
  },
82
82
  {
83
83
  "n": "onChange",
84
- "t": "string"
84
+ "t": "void"
85
85
  },
86
86
  {
87
87
  "n": "loadImage",
@@ -89,7 +89,7 @@
89
89
  },
90
90
  {
91
91
  "n": "onLoad",
92
- "t": "string"
92
+ "t": "void"
93
93
  },
94
94
  {
95
95
  "n": "getSelectedItemID",
@@ -97,7 +97,7 @@
97
97
  },
98
98
  {
99
99
  "n": "getSelectedItemIndex",
100
- "t": "string"
100
+ "t": "number"
101
101
  },
102
102
  {
103
103
  "n": "getContent",
@@ -105,11 +105,11 @@
105
105
  },
106
106
  {
107
107
  "n": "getItemHeight",
108
- "t": "string"
108
+ "t": "number"
109
109
  },
110
110
  {
111
111
  "n": "getItemWidth",
112
- "t": "string"
112
+ "t": "number"
113
113
  },
114
114
  {
115
115
  "n": "getTitle",
package/check.js CHANGED
@@ -39,7 +39,6 @@ const clash = require('./clashAttributes.json').crashs;
39
39
  * - `unknownAttribute {array|undefined}` - unknown attributes.
40
40
  * - `duplicateAttributes {array|undefined}` - duplicate attributes.
41
41
  * - `hasClashAttributes {array|undefined}` - clash attributes.
42
- * - `unInvokeAttributes {array|undefined}` - unInvoke attributes.
43
42
  * - `emptyValueOfAttributes {array|undefined}` - emptty value of attributes.
44
43
  */
45
44
  function customUI_Ribbon_xml_node_Check(xmlObj) {
package/cxml_w.js CHANGED
@@ -5,7 +5,7 @@ const chokidar = require('chokidar');
5
5
  const xmljs = require('xml-js');
6
6
 
7
7
  module.exports = (arg1, arg2, opt) => {
8
- if (!arg1.endsWith('.xml')) throw new Error('The first argument must be a XML file');
8
+ if (!arg1.endsWith('.xml')) throw new Error('缺少 XML 文件!');
9
9
  let xmlContent;
10
10
  try {
11
11
  xmlContent = fs.readFileSync(arg1, 'utf-8');
@@ -13,7 +13,7 @@ module.exports = (arg1, arg2, opt) => {
13
13
  throw new Error(e);
14
14
  }
15
15
  // 空文件不处理,且不监听的话,直接返回
16
- if(xmlContent.trim() === ""&&!opt.watch) return;
16
+ if (xmlContent.trim() === "" && !opt.watch) return;
17
17
  let xml2jsonContent = xmljs.xml2js(xmlContent, { compact: false, spaces: 4 }, (err, res) => {
18
18
  if (err) {
19
19
  console.error(err);
@@ -23,11 +23,24 @@ module.exports = (arg1, arg2, opt) => {
23
23
  });
24
24
 
25
25
  let xmlFlattenRes = xmlFlatten(xml2jsonContent);
26
-
27
- let realFile = fs.existsSync(arg2);
28
-
29
- function doit(){
30
- if(!realFile){
26
+
27
+ let realFile;
28
+ console.log([arg1,arg2,opt])
29
+ if (arg2!==undefined) {
30
+ try {
31
+ realFile = fs.existsSync(arg2);
32
+ if (!realFile) {
33
+ fs.writeFileSync(arg2, '');
34
+ }
35
+ } catch (e) {
36
+ throw new Error(e);
37
+ }
38
+ }else{realFile = false}
39
+
40
+ function doit() {
41
+ if(xmlFlattenRes.length === 0) return;
42
+ // 清空文件
43
+ if (realFile) {
31
44
  fs.writeFileSync(arg2, '');
32
45
  }
33
46
  xmlFlattenRes.forEach(o => {
@@ -37,18 +50,29 @@ module.exports = (arg1, arg2, opt) => {
37
50
  oItem_attributes = o.attributes;
38
51
  }
39
52
  let iTemCheckResult = checker({ name: oItem_name, attributes: oItem_attributes, xmlpath: o.xmlpath });
40
- if(realFile){
41
- console.log(iTemCheckResult);
42
- fs.writeFileSync(arg2, JSON.stringify(iTemCheckResult)+'\n',{flag:'a'});
43
- }else{
44
- console.log(iTemCheckResult);
53
+ let isOk = [
54
+ "unKnownElement",
55
+ "unknownAttribute",
56
+ "duplicateAttributes",
57
+ "hasClashAttributes",
58
+ "emptyValueOfAttributes"].some(e => Object.keys(iTemCheckResult).includes(e))
59
+ if (isOk){
60
+ if (realFile) {
61
+
62
+ fs.writeFileSync(arg2, JSON.stringify(iTemCheckResult) + '\n', { flag: 'a' });
63
+ console.log(iTemCheckResult);
64
+ } else {
65
+ console.log(iTemCheckResult);
66
+ }
45
67
  }
46
- })
68
+ });
47
69
  };
48
- if(opt.watch){
70
+ // Need Watch XML?
71
+ if (opt.watch) {
49
72
  let wcer = chokidar.watch(arg1);
73
+ console.log('watching...')
50
74
  wcer.on('change', doit);
51
- }else{
75
+ } else {
52
76
  doit();
53
77
  }
54
78
  }
package/index.js CHANGED
@@ -9,21 +9,21 @@ program
9
9
  .description(pkg.description)
10
10
  .version(pkg.version);
11
11
  program.command('check')
12
- .description('Check XML file against a schema')
13
- .argument('<xmlFile>', 'XML file to check')
14
- .argument('[outFile]', 'Output file')
15
- .option('-w, --watch', 'Watch the file for changes')
12
+ .description('检查 XML 文件是否符合规范(CustomUI for MS Office 2006/2007……)仅输出有问题的 Element。')
13
+ .argument('<xmlFile>', '要检查的 XML 文件')
14
+ .argument('[outFile]', '输出检查结果到文件 [outFile]')
15
+ .option('-w, --watch', '监视 <xmlFile> 文件')
16
16
  .action((xmlFile, outFile, options) => {
17
- //console.log(JSON.stringify([options, xmlFile, outFile]));
17
+ console.log(JSON.stringify([options, xmlFile, outFile]));
18
18
  require('./cxml_w.js')(xmlFile, outFile, options)
19
19
  });
20
20
  program.command('callback')
21
- .description('Add a callbackFunction to the <jsFile>')
22
- .argument('<xmlFile>', 'XML file to load')
23
- .argument('<jsFile>', 'JavaScript file to Append the callbackFunction')
24
- .option('-w, --write', 'Rewrite the file <jsFile>')
25
- .option('-a, --append', 'Append the file <jsFile>')
26
- .option('-watch, --watch', 'Watch the <xmlFile> file for changes')
21
+ .description('生成 XML CustomUI 元素设置的回调属性为 JavaScript Function 并写入 <jsFile>')
22
+ .argument('<xmlFile>', 'customUI XML 文件')
23
+ .argument('<jsFile>', '要写入的 JavaScript 文件')
24
+ .option('-w, --write', '写入方式: 覆盖 JS 文件 <jsFile>')
25
+ .option('-a, --append', '写入方式: 追加到 <jsFile> 文件末尾')
26
+ .option('-watch, --watch', '监视 <xmlFile> 文件')
27
27
  .action((xmlFile, jsFile, options) => {
28
28
  //console.log(JSON.stringify([options, xmlFile, jsFile]));
29
29
  if(options.watch){
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cuxml",
3
- "version": "1.0.4",
3
+ "version": "1.0.5",
4
4
  "description": "A tool to help use ribbon UI for your WPS Office Client JS add-in project.",
5
5
  "keywords": [
6
6
  "wps office",
package/xml2cbFn.js CHANGED
@@ -6,11 +6,12 @@ const clashes = require('./clashAttributes.json').crashs;
6
6
  const SDT = require('./StDelegate.json');
7
7
  const chokidar = require('chokidar');
8
8
  const xmljs = require('xml-js');
9
+ const callbackType = require('./cbfTypes.json');
9
10
 
10
11
  module.exports = (arg1, arg2, flag) => {
11
- if (!arg1.endsWith('.xml')) throw new Error('The first argument must be a XML file');
12
- if (!arg2.endsWith('.js')) throw new Error('The second argument must be a JS file');
13
- if (fs.existsSync(arg1) === false) throw new Error('The first argument file does not exist');
12
+ if (!arg1.endsWith('.xml')) throw new Error('The first argument must be a XML file!');
13
+ if (!arg2.endsWith('.js')) throw new Error('The second argument must be a JS file!');
14
+ if (fs.existsSync(arg1) === false) throw new Error('The XML file does not exist');
14
15
 
15
16
  let xmlContent = fs.readFileSync(arg1, 'utf-8');
16
17
  if (xmlContent.trim() === "") {
@@ -48,6 +49,7 @@ module.exports = (arg1, arg2, flag) => {
48
49
  }
49
50
  });
50
51
  attrs = lodash.compact(attrs);
52
+ if(attrs.length === 0) return;
51
53
  // 提取出所有的回调函数名
52
54
  let callbackFunctionNames = attrs.map(o => {
53
55
  let attrNames = Object.keys(o.a);
@@ -60,14 +62,15 @@ module.exports = (arg1, arg2, flag) => {
60
62
  callbackFunctionNames = lodash.flattenDeep(callbackFunctionNames);
61
63
  // 去重
62
64
  callbackFunctionNames = lodash.uniq(callbackFunctionNames);
65
+ if(callbackFunctionNames.length === 0) return;
63
66
  // console.log(callbackFunctionNames);
64
67
  // 用回调函数名获取 attrs 对象;
65
68
  let attrsObj = callbackFunctionNames.map(cb => {
66
69
  let z = lodash.map(attrs, o => {
67
70
  let s = [];
68
71
  Object.keys(o.a).forEach(k => {
69
- if (o.a[k] === cb) {
70
- s.push ({fn:cb,xmlPath:o.p,id:o.a.id})
72
+ if (o.a[k] === cb && o.a.id !== "") {
73
+ s.push ({fn:cb,xmlPath:o.p,id:o.a.id,cbAttr:k})
71
74
  }
72
75
  });
73
76
  return s;
@@ -75,9 +78,10 @@ module.exports = (arg1, arg2, flag) => {
75
78
  return lodash.compact(z);
76
79
  });
77
80
  attrsObj = lodash.flattenDeep(attrsObj);
81
+ if(attrsObj.length===0) return;
78
82
  //console.log(attrsObj);
79
83
  let fnGroup = lodash.groupBy(attrsObj, 'fn'); // 按照回调函数名分组
80
- console.log(fnGroup);
84
+ // console.log(fnGroup);
81
85
  // console.log(callbackFunctionNames);
82
86
  // console.log(callbackFunctionNames);
83
87
  // 检查JS文件是否存在,不存在就创建。
@@ -99,34 +103,26 @@ module.exports = (arg1, arg2, flag) => {
99
103
  }
100
104
  });
101
105
  function cbTemplete(attrValue) {
106
+ if(!fnGroup[attrValue]) return;
102
107
  let infos = fnGroup[attrValue];
103
- let cases = infos.map(o =>`// xmlPath: ${o.xmlPath}\n case "${o.id}":\n break;`);
108
+ let cases = infos.map(o =>infos.length>1?`// xmlPath: ${o.xmlPath}\n case "${o.id}":\n break;` : `// xmlPath: ${o.xmlPath}[id=${o.id}]\n`);
109
+ // 回调函数的属性名
110
+ let callbackAttr= infos[0].cbAttr;
111
+ // 回调函数的类型
112
+ let cbType = lodash.filter(callbackType, ['n', callbackAttr])[0].t;
113
+ let spaceReapts = (len)=>" ".repeat(len);
104
114
  return `
105
115
  /**
106
- * @param {RibbonUI} ctrl 你不需要关心这个参数,它代表一个菜单控件元素对象。比如 button、group 等。
107
- * @note
108
- * - 这是控件的回调函数,你不应该在其他 JS 文件中调用这个函数。
109
- * - 通用模版而已,你可以根据需要自行修改。
110
- * - 这里的回调函数都是异步的,你不应该在这里写长耗时同步的代码,否则可能会导致 UI 卡死。(AI 说的)
111
- *
116
+ * Callback function for ${callbackAttr}
117
+ * @param {RibbonUI} ctrl 菜单控件对象
118
+ * @returns {${cbType}}
119
+ *
112
120
  * Time: ${new Date()}
113
121
  */
114
122
  function ${attrValue}(ctrl){
115
-
116
- // 以下代码只是通用模版,你可以根据需要自行修改
117
- // 通过 ctrl.Id 来判断当前元素
118
- // use ctrl.Id to judge the current element
119
-
120
- switch(ctrl.Id){
121
- ${cases.join('\n')}
122
- default:
123
- break;
124
- };
125
-
126
- // 避免 UI 报错,总是返回 true
127
- // Need return value of true
128
-
129
- return true;
123
+ // 目前,所有回调都只支持一个参数,多出来的一律 undefined。ctrl 的成员如下👇🏻:
124
+ // ctrl={Id:'string', content:{...}, Tag:'string'}
125
+ ${cases.length > 1 ? `switch(ctrl.Id){\n${spaceReapts(8)}${cases.join('\n')}\ndefault:\n${spaceReapts(8)}break;\n${cbType=='void'?`${spaceReapts(8)}return true;//动作、事件类回调需要返回 true};`:``}` : `${cases.join('\n')}\n//根据回调属性返回准确的类型`}
130
126
  }`;
131
127
  }
132
128
  }