efront 3.12.5 → 3.13.3

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.
Files changed (54) hide show
  1. package/apps/pivot/api.yml +8 -0
  2. package/apps/pivot/home/welcome.html +1 -1
  3. package/apps/pivot/home/welcome.js +6 -9
  4. package/apps/pivot/log/boot.html +2 -0
  5. package/apps/pivot/log/boot.js +39 -0
  6. package/apps/pivot/log/boot.less +11 -0
  7. package/apps/pivot/log/count.html +5 -0
  8. package/apps/pivot/log/count.js +22 -0
  9. package/apps/pivot/log/count.less +16 -0
  10. package/apps/pivot/main.js +9 -10
  11. package/apps/pivot/menu.yml +7 -1
  12. package/apps/pivot/share/list.less +0 -4
  13. package/apps/pivot/user/edit.js +1 -0
  14. package/apps/pivot/user/list.js +4 -0
  15. package/apps/pivot/user/tag/edit.js +1 -0
  16. package/apps/pivot/user/tag/list.js +3 -0
  17. package/coms/basic/cross_.js +8 -1
  18. package/coms/basic/parseURL_test.js +2 -0
  19. package/coms/basic/parseYML.js +1 -1
  20. package/coms/basic/renderExpress.js +1 -1
  21. package/coms/frame/route.js +4 -0
  22. package/coms/pivot/plist.js +1 -1
  23. package/coms/zimoli/AudioContext_test.html +1 -1
  24. package/coms/zimoli/AudioContext_test.js +3 -3
  25. package/coms/zimoli/bind.js +4 -2
  26. package/coms/zimoli/cloneVisible.js +9 -2
  27. package/coms/zimoli/data.js +18 -2
  28. package/coms/zimoli/drag.js +3 -2
  29. package/coms/zimoli/field.html +15 -10
  30. package/coms/zimoli/menu.js +33 -13
  31. package/coms/zimoli/menu.less +31 -9
  32. package/coms/zimoli/menuItem.js +1 -1
  33. package/coms/zimoli/menuList.html +5 -3
  34. package/coms/zimoli/menuList.js +63 -28
  35. package/coms/zimoli/menuList.less +5 -0
  36. package/coms/zimoli/model.js +22 -2
  37. package/coms/zimoli/on.js +5 -3
  38. package/coms/zimoli/picture.js +30 -335
  39. package/coms/zimoli/picture_.js +356 -0
  40. package/coms/zimoli/prompt.js +3 -1
  41. package/coms/zimoli/render.js +22 -10
  42. package/coms/zimoli/renderDefaults.js +1 -0
  43. package/coms/zimoli/search.js +5 -4
  44. package/coms/zimoli/select.js +9 -5
  45. package/coms/zimoli/selectList.js +12 -9
  46. package/coms/zimoli/selectListEdit.js +1 -1
  47. package/coms/zimoli/success.js +4 -0
  48. package/coms/zimoli/success.less +13 -0
  49. package/coms/zimoli/table.html +6 -8
  50. package/coms/zimoli/table.js +25 -2
  51. package/coms/zimoli/table.less +24 -4
  52. package/coms/zimoli/view.less +4 -0
  53. package/package.json +1 -1
  54. package/public/efront.js +1 -1
@@ -10,3 +10,11 @@
10
10
  invoke: options ::invoke-:key?:params
11
11
  version: options ::version
12
12
  uptime: options ::uptime
13
+ count: options ::count
14
+ bootlog: options ::similar
15
+ https://www.ip.cn/ :
16
+ iplocation: get https://www.ip.cn/api/index?ip=:ip&type=1
17
+ # https://ipchaxun.com/ :
18
+ # iplocation: get:[].info%20label:nth-child(n+2)>span:nth-child(2) :ip/
19
+ # https://www.ip138.com/:
20
+ # iplocation: get:head>script:nth-last-child(1) iplookup.asp?ip=:ip&action=2
@@ -25,4 +25,4 @@
25
25
  <padding>
26
26
  启动时间&nbsp;&nbsp;<span -text="filterTime(hrtime)"></span>
27
27
  </padding>
28
- </block>
28
+ </block>
@@ -6,15 +6,12 @@ function main() {
6
6
  version: data.from("version"),
7
7
  hrtime: data.from("uptime", a => Date.now() - a * 1000),
8
8
  filterTime,
9
- async run(id, target) {
10
- target.setAttribute('pending', '')
11
- try {
12
- var info = await data.from("run", {
13
- run: id
14
- }).loading_promise;
15
- if (info) alert(info, 'pass');
16
- } catch { }
17
- target.removeAttribute('pending');
9
+ async run(id) {
10
+ await new Promise(ok => setTimeout(ok, 2000));
11
+ var info = await data.from("run", {
12
+ run: id
13
+ }).loading_promise;
14
+ if (info) alert(info, 'pass');
18
15
  },
19
16
  async logout() {
20
17
  data.setSource({});
@@ -0,0 +1,2 @@
1
+ <table -src="[fields,items]">
2
+ </talbe>
@@ -0,0 +1,39 @@
1
+ var fields = refilm`
2
+ 地址/ip
3
+ 地理位置/ip ${function (e) {
4
+ var ip = e.data[e.field.key];
5
+ var m = /(\d+\.){3}\d+$/.exec(ip);
6
+ if (m) {
7
+ data.from("iplocation", { ip: m[0] }, function (a) {
8
+ var l = document.createElement('label');
9
+ l.innerText = a.address;
10
+ appendChild(e, l);
11
+ });
12
+ }
13
+ return e;
14
+ }}
15
+ 启动时间/time ${function (e) {
16
+ e.innerHTML = filterTime(e.data[e.field.key]);
17
+ }}
18
+ 端口/port input
19
+ 版本/version
20
+ 进程/pid
21
+ `;
22
+ function main() {
23
+ var page = div();
24
+ page.innerHTML = template;
25
+ var items = data.from("bootlog", datas => {
26
+ datas.forEach(a => {
27
+ var [v, p] = a.ppid.split("/");
28
+ a.version = v;
29
+ a.pid = p;
30
+ });
31
+ datas.sort((a, b) => b.time - a.time);
32
+ return datas;
33
+ });
34
+ renderWithDefaults(page, {
35
+ items,
36
+ fields
37
+ });
38
+ return page;
39
+ }
@@ -0,0 +1,11 @@
1
+ & {
2
+ height: 100%;
3
+ }
4
+
5
+ model {
6
+ label {
7
+ display: inline-block;
8
+ color: #666;
9
+ font-size: 9px;
10
+ }
11
+ }
@@ -0,0 +1,5 @@
1
+ <div class="searchbox">
2
+ <input @input="filter" -model="searchText" />
3
+ </div>
4
+ <table -src="[fields,items]">
5
+ </talbe>
@@ -0,0 +1,22 @@
1
+ var fields = refilm`
2
+ 路径/path html
3
+ 访问量/count
4
+ `;
5
+ function main() {
6
+ var page = div();
7
+ page.innerHTML = template;
8
+ var items = data.from("count", a => {
9
+ return Object.keys(a).map(b => ({ path: b, count: a[b] }));
10
+ });
11
+ renderWithDefaults(page, {
12
+ items,
13
+ searchText: "",
14
+ filter() {
15
+ var text = this.searchText;
16
+ if (!text) return this.items = items;
17
+ this.items = search(text, items, 'path');
18
+ },
19
+ fields
20
+ });
21
+ return page;
22
+ }
@@ -0,0 +1,16 @@
1
+ & {
2
+ height: 100%;
3
+
4
+ }
5
+
6
+ .searchbox {
7
+ position: absolute;
8
+ top: 0;
9
+ right: 0;
10
+ z-index: 2;
11
+ padding: 8px 16px;
12
+
13
+ >input {
14
+ background: #eee;
15
+ }
16
+ }
@@ -7,16 +7,15 @@ cross.addReform(async function ({ status, url, headers }, reform, reject) {
7
7
  var base1 = protocol + "//" + host + "/";
8
8
  if (base !== base1) {
9
9
  data.setSource(base1, null);
10
- var page = await popup("/auth/login", base1);
11
- care(page, "login", function (info) {
12
- data.setSource(base1, info);
13
- headers.authorization = info;
14
- reform();
15
- });
16
- on("remove")(page, reject);
17
- return false;
18
10
  }
19
- location.reload();
11
+ var page = await popup("/auth/login", base1);
12
+ care(page, "login", function (info) {
13
+ data.setSource(base1, info);
14
+ headers.authorization = info;
15
+ reform();
16
+ });
17
+ on("remove")(page, reject);
18
+ return false;
20
19
  }
21
20
  })
22
21
  data.setReporter(function (m, t) {
@@ -27,7 +26,7 @@ data.bindInstance("base", async function (base) {
27
26
  cross.addDirect(base.base);
28
27
  var apimap = await data.getConfig();
29
28
  for (var k in apimap) {
30
- apimap[k].base = base.base;
29
+ if (apimap[k].method === 'options') apimap[k].base = base.base;
31
30
  }
32
31
  });
33
32
  var base = data.getInstance('base').base;
@@ -8,4 +8,10 @@ WEB:
8
8
  密钥管理: /token/list
9
9
  任务建立: /task/list
10
10
  定期执行: /tick/list
11
- # 用户列表: /user/list
11
+ 用户:
12
+ 账号列表: /user/list
13
+ 标签管理: /user/tag/list
14
+ 服务器日志:
15
+ 访问计数: /log/count
16
+ 启动记录: /log/boot
17
+ # 并发记忆: /log/lock
@@ -1,7 +1,3 @@
1
- >table {
2
- width: 100%;
3
- }
4
-
5
1
  & {
6
2
  height: 100%;
7
3
  }
@@ -0,0 +1 @@
1
+ pedit.bind(null, "用户信息", "user");
@@ -0,0 +1,4 @@
1
+ plist.bind(null, '用户管理', "user", refilm`
2
+ *用户ID/key 100
3
+ 用户名/name input/300
4
+ `, "/user/edit");
@@ -0,0 +1 @@
1
+ pedit.bind(null, "标签", "tag");
@@ -0,0 +1,3 @@
1
+ plist.bind(null, '标签', "tag", refilm`
2
+ *标签/key 100
3
+ `, "/user/tag/edit");
@@ -180,7 +180,14 @@ function cross_(jsonp, digest = noop, method, url, headers) {
180
180
  };
181
181
  xhr.form = function (data) {
182
182
  xhr.data(data);
183
- if (FormData) {
183
+ var hasFile = false;
184
+ if (FormData) for (var k in jsondata) {
185
+ if (isFile(jsondata[k])) {
186
+ hasFile = true;
187
+ break;
188
+ }
189
+ }
190
+ if (hasFile) {
184
191
  datas = new FormData;
185
192
  for (var k in jsondata) {
186
193
  datas.append(k, jsondata[k]);
@@ -12,6 +12,8 @@ test('http://yunxu1019@live.cn@github.com/?a', 'username', 'yunxu1019@live.cn')
12
12
  test('localhost', 'host', 'localhost')
13
13
  test('localhost:80', 'port', '80')
14
14
  test('localhost:80/', 'port', '80')
15
+ test('efront.cc', 'host', 'efront.cc')
16
+ test('127.0.0.1', 'host', '127.0.0.1')
15
17
  test(':80', 'port', '80')
16
18
  test('80', 'port', '80')
17
19
  test('/80', 'pathname', '/80')
@@ -207,7 +207,7 @@ var scan = function (text) {
207
207
  }
208
208
  }
209
209
 
210
- if (row === "|") {
210
+ if (row === "|" || row === ">") {
211
211
  rowtype = "|"
212
212
  continue;
213
213
  }
@@ -3,7 +3,7 @@ function createSeek(express) {
3
3
  express.forEach(function (search) {
4
4
  if (dist) {
5
5
  if (/[\=]/.test(dist)) dist = `(${dist})`;
6
- dist = `${dist}!==void 0&&${dist}!==null?${dist}${search}:''`
6
+ dist = `typeof ${dist}!=='undefined'&&${dist}!==null?${dist}${search}:''`
7
7
  } else {
8
8
  dist = search;
9
9
  }
@@ -75,6 +75,7 @@
75
75
  if (/,/.test(name)) {
76
76
 
77
77
  }
78
+ item.closed = true;
78
79
  return item;
79
80
  });
80
81
  return items;
@@ -114,6 +115,7 @@
114
115
  actived = mmap[opened.active] || actived;
115
116
  if (actived) {
116
117
  if (actived_value === historys.length) {
118
+ setActive(actived, true);
117
119
  result.active = actived;
118
120
  };
119
121
  }
@@ -123,6 +125,7 @@
123
125
  var setActive = function (p, active) {
124
126
  while (p) {
125
127
  p.active = active;
128
+ if (active) p.closed = false;
126
129
  p = p.parent;
127
130
  }
128
131
  };
@@ -195,6 +198,7 @@
195
198
  result.then = then;
196
199
  return result;
197
200
  };
201
+ result.parse = parseMenuList;
198
202
  var then = function (ok, oh) {
199
203
  if (this.loading_promise) {
200
204
  return this.loading_promise.then(ok, oh);
@@ -2,7 +2,7 @@
2
2
  function main(title, type, fields, edit_ref, options) {
3
3
  return frame$list(title, {
4
4
  load() {
5
- return data.from("list", { type }, a => JSAM.parse(encode62.timedecode(a)));
5
+ return data.from("list", { type }, a => JSAM.parse(encode62.timedecode(a || '')));
6
6
  },
7
7
  remove(o) {
8
8
  return data.from("edit", { type, key: encode62.timeencode(o.key), value: encode62.timeencode("") }).loading_promise;
@@ -1,5 +1,5 @@
1
1
  <div ng-class="{even:i%2===1,odd:i%2===0}" v-for="(r,i) in rates" hz:='r[5]'>
2
- <span ng-if="i%2===0" v-bind="i/2 -2"></span>
2
+ <span ng-if="i%2===0" v-bind="i/2 -8"></span>
3
3
  <button ng-repeat="o in r" _rate=o>
4
4
  <span ng-bind="format(o)"></span>
5
5
  </button>
@@ -2,8 +2,8 @@ function piano() {
2
2
  var res = [];
3
3
  var yin = [1, 3, 5, 7, 8, 10, 12].reverse();
4
4
  var yue = [2, 4, 6, 9, 11].reverse();
5
- var c=a => 440 * Math.pow(2, cx + (3 - a) / 12);
6
- for (var cx = -6, dx = 8; cx < dx; cx++) {
5
+ var c = a => 440 * Math.pow(2, cx + (3 - a) / 12);
6
+ for (var cx = -12, dx = 8; cx < dx; cx++) {
7
7
  var yinjie1 = yin.map(c);
8
8
  var yinjie2 = yue.map(c);
9
9
  res.push(yinjie1, yinjie2);
@@ -23,7 +23,7 @@ function main() {
23
23
  oscillator.connect(gainNode);
24
24
  gainNode.connect(audioCtx.destination);
25
25
  oscillator.type = 'sine';
26
- oscillator.frequency.value = hz;
26
+ oscillator.frequency.value = -hz;
27
27
  gainNode.gain.setValueAtTime(0, audioCtx.currentTime);
28
28
  gainNode.gain.linearRampToValueAtTime(65536 / Math.log2(hz), audioCtx.currentTime + 0.01);
29
29
  oscillator.start(audioCtx.currentTime);
@@ -1,10 +1,12 @@
1
1
  function bind(eventName, bindTo = window) {
2
2
  return function (target, eventListener) {
3
3
  var off;
4
- var off1 = on("append")(target, function () {
4
+ var mount = function () {
5
5
  if (off) off();
6
6
  off = on(eventName).call(bindTo, target, eventListener);
7
- });
7
+ };
8
+ if (isMounted(target)) mount();
9
+ var off1 = on("append")(target, mount);
8
10
  var off2 = on("remove")(target, function () {
9
11
  if (off) off();
10
12
  off = null;
@@ -1,5 +1,5 @@
1
1
  var cloneProperties = "fontWeight,fontSize,fontFamily,color,textShadow,opacity,writingMode,blockSize,wordSpacing,letterSpacing,whiteSpace".split(",");
2
- var cloneProperties2 = "position,float,clear,margin,color,verticalAlign,textAlign,textShadow,opacity,boxShadow,overflow,writingMode,blockSize,wordSpacing,letterSpacing,textIndent,lineHeight,display,appearance,webkitAppearance,MozAppearance".split(",");
2
+ var cloneProperties2 = "position,backdropFilter,float,clear,margin,color,verticalAlign,textAlign,textShadow,opacity,boxShadow,overflow,writingMode,blockSize,wordSpacing,letterSpacing,textIndent,lineHeight,display,appearance,webkitAppearance,MozAppearance".split(",");
3
3
  var pushProperty = function (key, props) {
4
4
  props.split(",").forEach(k => {
5
5
  cloneProperties2.push(key + k);
@@ -86,7 +86,13 @@ var isMaybeVisible = function (node) {
86
86
  if (style.overflow === "hidden") {
87
87
  if (node.offsetHeight === 0 || node.offsetWidth === 0) return;
88
88
  }
89
- if (node.offsetParent && !overlap(node, node.offsetParent)) return;
89
+ if (node.offsetParent) {
90
+ var parent = node.offsetParent;
91
+ return !(node.offsetLeft + node.offsetWidth - parent.scrollLeft <= parent.clientLeft ||
92
+ node.offsetTop + node.offsetHeight - parent.scrollTop <= parent.clientTop ||
93
+ node.offsetLeft - parent.scrollLeft >= (parent.clientWidth || parent.offsetWidth) ||
94
+ node.offsetTop - parent.scrollTop >= (parent.clientHeight || parent.offsetHeight));
95
+ }
90
96
  return true;
91
97
  }
92
98
  var clonePseudo = function (node, pseudo) {
@@ -173,6 +179,7 @@ var cloneVisible = function (td) {
173
179
  };
174
180
  clone(td);
175
181
  extend(result.style, {
182
+ zIndex: getComputedStyle(td).zIndex,
176
183
  position: "absolute",
177
184
  left: _left + "px",
178
185
  top: _top + "px",
@@ -75,8 +75,24 @@ const formulaters = {
75
75
  var seekFromSource = function (obj, base) {
76
76
  var source = dataSourceMap;
77
77
  if (base && base in dataSourceMap) source = source[base];
78
- obj = seek(source, obj);
79
- if (isObject(obj)) for (var k in obj) if (obj[k] === dataSourceMap) delete obj[k];
78
+ if (isObject(obj)) {
79
+ var dist = {};
80
+ for (var k in obj) {
81
+ var v = obj[k];
82
+ if (/^\:/.test(k)) {
83
+ k = seek(source, k.slice(1));
84
+ }
85
+ if (v === '') {
86
+ if (source !== dataSourceMap) v = source;
87
+ else v = seek(source, k);
88
+ }
89
+ else if (/^\:/.test(v)) {
90
+ v = seek(source, v.slice(1));
91
+ }
92
+ dist[k] = v;
93
+ }
94
+ obj = dist;
95
+ }
80
96
  return obj;
81
97
  };
82
98
  function getErrorMessage(error = this) {
@@ -61,8 +61,9 @@ function drag(target, initialEvent, preventOverflow, isMovingSource) {
61
61
  saved_delta.x += clone_left - target_left;
62
62
  saved_delta.y += clone_top - target_top;
63
63
  if (clone.style) {
64
- clone.style.zIndex = zIndex();
65
- extraClones.map(e => e.style.zIndex = clone.style.zIndex);
64
+ var z = zIndex();
65
+ clone.style.zIndex = z + (+clone.style.zIndex || 0);
66
+ extraClones.map(e => e.style.zIndex = z + (+e.style.zIndex || 0));
66
67
  }
67
68
  }
68
69
  drag.target = clone;
@@ -1,11 +1,16 @@
1
- <div class="head">
2
- <span ng-bind=field.name></span>
3
- <span class="required" ng-if="field.required">*</span>
4
- </div>
5
- <div class="body">
1
+ <template v-if='field?.key'>
2
+ <div class="head">
3
+ <span ng-bind=field.name></span>
4
+ <span class="required" ng-if="field.required">*</span>
5
+ </div>
6
+ <div class="body">
7
+ <model _data=data _field=field></model>
8
+ <span class="error" ng-bind="error"></span>
9
+ </div>
10
+ <div class="foot" ng-if="field.msg">
11
+ <span ng-bind=field.msg></span>
12
+ </div>
13
+ </template>
14
+ <template v-else>
6
15
  <model _data=data _field=field></model>
7
- <span class="error" ng-bind="error"></span>
8
- </div>
9
- <div class="foot" ng-if="field.msg">
10
- <span ng-bind=field.msg></span>
11
- </div>
16
+ </template>
@@ -101,23 +101,34 @@ function main(elem, mode) {
101
101
  // }
102
102
  // elem.setAttribute('browser', os);
103
103
  var mode = elem.getAttribute('mode') || elem.getAttribute('type');
104
+ if (!mode) {
105
+ if (elem.hasAttribute("inline")) mode = 'inline';
106
+ else if (elem.hasAttribute("vertical")) mode = "vertical";
107
+ else if (elem.hasAttribute("horizonal")) mode = "horizonal";
108
+ else if (
109
+ elem.hasAttribute("toolbar")
110
+ || elem.hasAttribute('tool')
111
+ || elem.hasAttribute('tools')
112
+ || elem.hasAttribute('bar')
113
+ ) mode = "toolbar";
114
+ }
104
115
  if (!mode) {
105
116
  if (/^[xyhvtci]/i.test(elem.tagName)) {
106
117
  mode = elem.tagName.slice(0, 1);
118
+ if (/^t$/i.test(mode)) mode = elem.tagName.slice(0, 2);
107
119
  }
108
- else if (/[xyhvtci]$/i.test(elem.tagName)) {
109
- mode = elem.tagName.slice(0, 1);
120
+ else if (/[xyhvci]$/i.test(elem.tagName)) {
121
+ mode = elem.tagName.slice(elem.tagName.length - 1);
110
122
  }
111
123
  }
112
124
  mode = mode ? mode.toLowerCase() : "horizonal";
113
-
125
+ var direction;
114
126
  switch (mode) {
127
+ case "tr":
115
128
  case "i":
116
129
  case "c":
117
130
  case "inline":
118
- case "t":
119
- case "tree":
120
- mode = "tree";
131
+ mode = "inline";
121
132
  if (elem) {
122
133
  var generator = getGenerator(elem, 'menu-item');
123
134
  tree(elem, function (index, item) {
@@ -145,22 +156,31 @@ function main(elem, mode) {
145
156
  elem = inlineMenu.call(elem, nodes);
146
157
  }
147
158
  break;
159
+ case "to":
160
+ case "t":
161
+ case "b":
162
+ case "tool":
163
+ case "tools":
164
+ case "bar":
165
+ case "toolbar":
166
+ direction = 't';
167
+ mode = "toolbar";
148
168
  case "h":
149
169
  case "x":
150
170
  case "horizonal":
151
- var direction = 'x';
152
- mode = "horizonal";
171
+ if (!direction) {
172
+ direction = 'x';
173
+ mode = "horizonal";
174
+ }
153
175
  case "v":
154
176
  case "y":
155
177
  case "vertical":
178
+ if (!direction) mode = "vertical", direction = 'y';
156
179
  var emit = function (item, target) {
157
180
  active(elem, item.value, item, target);
158
181
  };
159
182
  if ("$src" in elem) {
160
183
  getGenerator(elem, 'menu-item');
161
- on("append")(elem, function () {
162
- elem.registerAsRoot();
163
- });
164
184
  var src0 = [];
165
185
  menuList(elem, src0, emit, direction);
166
186
  care(elem, function (src) {
@@ -177,7 +197,6 @@ function main(elem, mode) {
177
197
  var nodes = getArrayNodes(elem);
178
198
  remove(elem.children);
179
199
  elem = menuList(elem, nodes, emit, direction);
180
- elem.registerAsRoot();
181
200
  }
182
201
  break;
183
202
  default:
@@ -187,7 +206,8 @@ function main(elem, mode) {
187
206
  mode = mode || "horizonal";
188
207
  elem = menu.apply(null, arguments);
189
208
  }
190
- elem.setAttribute('mode', mode);
209
+ if (!elem.hasAttribute('mode')) elem.setAttribute('mode', mode);
210
+ if (!elem.hasAttribute(mode)) elem.setAttribute(mode, '');
191
211
  return elem;
192
212
 
193
213
  }
@@ -82,13 +82,11 @@ body:active & {
82
82
  width: 100%;
83
83
  }
84
84
 
85
- &[mode=vertical],
86
- &[type=vertical] {
85
+ &[vertical] {
87
86
  display: block;
88
87
  }
89
88
 
90
- &[mode=horizonal],
91
- &[type=horizonal] {
89
+ &[horizonal] {
92
90
  display: block;
93
91
  overflow: hidden;
94
92
  text-overflow: hidden;
@@ -115,11 +113,35 @@ body:active & {
115
113
 
116
114
  }
117
115
 
118
- &[mode=tree],
119
- &[mode=tree],
120
- &[type=tree],
121
- &[mode=inline],
122
- &[type=inline] {
116
+ &[toolbar] {
117
+ >menu-item{
118
+ padding-left: 6px;
119
+ padding-right: 6px;
120
+ text-align: center;
121
+ }
122
+ >menu-item.has-children {
123
+ &::after {
124
+ display: block;
125
+ content: "";
126
+ width: 0;
127
+ height: 0;
128
+ font-size: 0;
129
+ transform: none;
130
+ border: 2px solid;
131
+ border-top-color: transparent;
132
+ border-left-color: transparent;
133
+ position: absolute;
134
+ right: 3px;
135
+ bottom: 3px;
136
+ box-sizing: border-box;
137
+ line-height: 0;
138
+ top: auto;
139
+ margin: 0;
140
+ }
141
+ }
142
+ }
143
+
144
+ &[inline] {
123
145
  height: auto;
124
146
  box-shadow: none;
125
147
  padding: 0;
@@ -11,7 +11,7 @@ function main(elem, scope, hasIcon) {
11
11
  var name = scope.name;
12
12
  var icon = scope.icon;
13
13
  if (hasIcon === undefined) hasIcon = !!icon;
14
- render(item.children, { useIcon: hasIcon, hasIcon, name, icon });
14
+ render(item.children, scope, hasIcon instanceof Array ? hasIcon : [{ useIcon: hasIcon, hasIcon, name, icon }]);
15
15
  if (scope.line) item.setAttribute("line", ''), on("click")(item, preventDefault);
16
16
  return item;
17
17
  }
@@ -1,4 +1,6 @@
1
- <menu-item ng-repeat="menu in menus" ng-if="!menu.hidden" ng-click="open.call(this)"
2
- ng-mouseleave="cancel()" ng-mouseenter="popMenu.call(this)"
3
- ng-class="{'has-children':menu.children&&menu.children.length,'warn':menu.type==='danger'||menu.type==='warn'||menu.type==='red'}">
1
+ <menu-item ng-repeat="menu in menus" ng-if="!menu.hidden" ng-click="open.call(this)" ng-mouseleave="cancel()"
2
+ ng-mouseenter="popMenu.call(this)" ng-mousedown="popMenu1.call(this,event)" ng-class="{'has-children':menu.children&&menu.children.length,
3
+ 'warn':menu.type==='danger'||menu.type==='warn'||menu.type==='red',
4
+ 'selected':menu.selected
5
+ }">
4
6
  </menu-item>