efront 3.10.3 → 3.11.0

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.
@@ -9,3 +9,4 @@
9
9
  params: options ::params-:key
10
10
  invoke: options ::invoke-:key?:params
11
11
  version: options ::version
12
+ uptime: options ::uptime
@@ -20,4 +20,9 @@
20
20
  <padding>
21
21
  服务器版本&nbsp;&nbsp;<span -text="String(version)"></span>
22
22
  </padding>
23
- </block>
23
+ </block>
24
+ <block>
25
+ <padding>
26
+ 启动时间&nbsp;&nbsp;<span -text="filterTime(hrtime)"></span>
27
+ </padding>
28
+ </block>
@@ -4,6 +4,8 @@ function main() {
4
4
  renderWithDefaults(page, {
5
5
  status: [],
6
6
  version: data.from("version"),
7
+ hrtime: data.from("uptime", a => Date.now() - a * 1000),
8
+ filterTime,
7
9
  async run(id, target) {
8
10
  target.setAttribute('pending', '')
9
11
  try {
@@ -42,10 +42,13 @@ var getCrossUrl = function (domain, headers) {
42
42
  .replace(domainReg, base + `*${/^(https\:|s\/\/)/i.test(domain) ? "*" : ""}$2${_headers}/$3$4`);
43
43
  };
44
44
  function noop() { }
45
-
45
+ function toResponse() {
46
+ if (this.responseType === 'json') return JSON.stringify(this.response);
47
+ return this.response;
48
+ }
46
49
  function _cross(jsonp, digest = noop, method, url, headers) {
47
50
  var originDomain = getDomainPath(url);
48
- if (!originDomain) throw new Error("Unsupposed url format!");
51
+ if (!originDomain) throw new Error("路径格式错误!");
49
52
  var _cookies = getCookies(originDomain);
50
53
  var _headers = {};
51
54
  if (_cookies) {
@@ -59,24 +62,24 @@ function _cross(jsonp, digest = noop, method, url, headers) {
59
62
  method = method.slice(1);
60
63
  }
61
64
  var loaded, errored;
62
- var onload = function (xhr) {
65
+ var onload = function (data) {
63
66
  removeFromList(requests, xhr);
64
67
  if (xhr.decoder) {
65
- xhr = xhr.decoder(xhr);
68
+ data = xhr.decoder(data);
66
69
  }
67
- loaded = xhr;
70
+ loaded = data;
68
71
  flush();
69
72
  digest();
70
73
  };
71
74
  var onerror1 = function (e) {
72
- removeFromList(requests, e);
75
+ removeFromList(requests, xhr);
73
76
  errored = e || "未知错误!";
74
77
  flush();
75
78
  digest();
76
79
  };
77
80
  var onerror = async function (e) {
78
81
  if (e.type === 'error') {
79
- e = { status: "无法访问服务器" };
82
+ e = { response: "无法访问服务器", toString: toResponse };
80
83
  }
81
84
  for (var r of reforms) {
82
85
  var r = await reform(r, { method, url, status: xhr.status, headers: _headers }, fire, onerror1, e);
@@ -103,23 +106,28 @@ function _cross(jsonp, digest = noop, method, url, headers) {
103
106
  });
104
107
  var xhr = jsonp(url, {
105
108
  [cb](a) {
106
- xhr.response = xhr.responseText = JSON.stringify(a);
107
- onload(xhr);
109
+ onload({ status: 200, response: JSON.stringify(a), toString: toResponse });
108
110
  }
109
111
  });
110
112
  xhr.onerror = onerror;
111
113
  }
112
114
  else {
113
115
  var nocross = notCross(url);
114
- var callback = function (status, response) {
115
- if (xhr.getResponseHeader && !nocross) {
116
- var cookie = xhr.getResponseHeader("efront-cookie");
117
- addCookie(cookie, originDomain);
116
+ var callback = function () {
117
+ var exposeHeaders = xhr.getResponseHeader("access-control-expose-headers");
118
+ var exposeMap = {};
119
+ if (exposeHeaders) exposeHeaders.split(",").forEach(h => exposeMap[h.toLowerCase()] = true);
120
+ if (xhr.getResponseHeader) {
121
+ var exposekey = nocross ? "set-cookie" : "efront-cookie";
122
+ if (exposeMap[exposekey]) {
123
+ var cookie = xhr.getResponseHeader(exposekey);
124
+ addCookie(cookie, originDomain);
125
+ }
118
126
  }
119
- switch (status) {
127
+ switch (xhr.status) {
120
128
  case 0:
121
- if (!response) {
122
- onerror({ status: "无法访问服务器" });
129
+ if (!xhr.response) {
130
+ onerror({ status: 0, response: "无法访问服务器", toString: toResponse });
123
131
  break;
124
132
  }
125
133
  case 200:
@@ -130,8 +138,9 @@ function _cross(jsonp, digest = noop, method, url, headers) {
130
138
  case 307:
131
139
  case 302:
132
140
  case 301:
133
- if (xhr.isRedirected > 2 || nocross) break;
134
- var location = xhr.getResponseHeader("efront-location");
141
+ if (xhr.isRedirected > 2) break;
142
+ var exposekey = nocross ? "location" : "efront-location";
143
+ var location = exposeMap[exposekey] && xhr.getResponseHeader(exposekey);
135
144
  if (!domainReg.test(location)) {
136
145
  if (/^\//.test(location)) {
137
146
  location = originDomain.replace(/\/.*$/, location);
@@ -152,6 +161,7 @@ function _cross(jsonp, digest = noop, method, url, headers) {
152
161
  var cross = this;
153
162
  var xhr = cross(callback, onerror);
154
163
  var send = xhr.send;
164
+ xhr.toString = toResponse;
155
165
  xhr.json = xhr.data = xhr.send = function (data, value) {
156
166
  if (!jsondata && !(isEmpty(data) && isEmpty(value))) jsondata = data instanceof Array ? [] : {};
157
167
  if (FormData && data instanceof FormData) {
@@ -24,6 +24,7 @@ var parseCookieFromText = function (cookie) {
24
24
 
25
25
  function addCookie(cookie_text, originDomain = "") {
26
26
  if (!cookie_text) return;
27
+ if (cookie_text instanceof Array) cookie_text = cookie_text.join(",");
27
28
  var cookies = cookie_text.replace(/(^|;|,)\s*(expires)=(\w*),([^=]*)(;|$)/ig, "$1$2=$3.$4$5")
28
29
  .split(/,\s*/).map(parseCookieFromText);
29
30
  for (var cookie of cookies) {
@@ -167,6 +167,9 @@ var createScoped = function (parsed) {
167
167
  case STRAP:
168
168
  var s = o.text;
169
169
  switch (s) {
170
+ case "return":
171
+ funcbody.return = true;
172
+ break;
170
173
  case "await":
171
174
  funcbody.async = funcbody.await = true;
172
175
  break;
@@ -374,6 +374,9 @@ class Program extends Array {
374
374
  get await() {
375
375
  return this.scoped.await;
376
376
  }
377
+ get return() {
378
+ return this.scoped.return;
379
+ }
377
380
  get scoped() {
378
381
  if (this._scoped) return this._scoped;
379
382
  return this._scoped = createScoped(this);
@@ -33,7 +33,6 @@
33
33
  };
34
34
  var parseMenuList = function (items) {
35
35
  if (items instanceof Array) {
36
- console.log(items)
37
36
  return items;
38
37
  }
39
38
  if (items instanceof Object) {
@@ -1,17 +1,45 @@
1
1
  return _cross.bind(function (callback, onerror) {
2
- var response;
2
+ var response, responseObject, responseType = "", error;
3
3
  var xhr = {
4
4
  status: 0,
5
+ readyState: 0,
5
6
  method: null,
6
7
  url: null,
7
8
  http: null,
8
9
  headers: {},
9
- response: null,
10
+ responseHeaders: {},
11
+ get response() {
12
+ if (responseType === "" || responseType === "text") {
13
+ if (this.readyState !== 4) return '';
14
+ return String(response);
15
+ }
16
+ else if (error) return null;
17
+ if (responseObject !== null) return responseObject;
18
+ switch (responseType) {
19
+ case "arraybuffer":
20
+ return response.buffer;
21
+ case "json":
22
+ if (!response) return null;
23
+ responseObject = JSON.parse(String(response));
24
+ return responseObject;
25
+ }
26
+ return responseObject;
27
+
28
+ },
29
+ set response(v) {
30
+ response = v;
31
+ },
10
32
  getResponseHeader(key) {
11
- return response.headers[key];
33
+ key = String(key).toLowerCase();
34
+ if (this.responseHeaders[key]) return this.responseHeaders[key];
35
+ if (key === "access-control-expose-headers") {
36
+ return 'set-cookie,location';
37
+ }
38
+ return null;
12
39
  },
13
40
  send(data) {
14
41
  var { hostname, port, path, auth } = parseURL(this.url);
42
+ if (data instanceof FormData) data = String(data);
15
43
  if (data) {
16
44
  data = Buffer.from(data);
17
45
  this.headers["Content-Length"] = data.length;
@@ -25,24 +53,25 @@ return _cross.bind(function (callback, onerror) {
25
53
  headers: this.headers,
26
54
  }, function (res) {
27
55
  var data = [];
28
- var session_text = res.headers["set-cookie"];
29
- if (session_text instanceof Array) session_text.forEach(t => cookie.addCookie(t));
30
- else if (typeof session_text === "string") cookie.addCookie(session_text);
31
56
  xhr.status = res.statusCode;
32
- xhr.response = res;
57
+ xhr.responseHeaders = res.headers;
33
58
  res.on("data", function (chunk) {
59
+ xhr.readyState = 4;
34
60
  data.push(chunk);
35
61
  });
36
62
  res.on("end", function () {
37
- data = Buffer.concat(data);
38
- xhr.response = data;
39
- callback(res.statusCode, data);
40
- console.log(String(data), res.statusCode);
63
+ response = Buffer.concat(data);
64
+ xhr.readyState = 4;
65
+ callback();
41
66
  });
42
67
  res.on("error", function (e) {
68
+ xhr.readyState = 4;
69
+ error = e;
43
70
  onerror(e);
44
71
  });
72
+ this.readyState = 2;
45
73
  });
74
+ this.readyState = 1;
46
75
  if (data) req.end(data);
47
76
  else req.end();
48
77
  },
@@ -50,6 +79,10 @@ return _cross.bind(function (callback, onerror) {
50
79
  this.method = method;
51
80
  this.url = url;
52
81
  this.status = 0;
82
+ this.readyState = 0;
83
+ response = null;
84
+ responseObject = null;
85
+ error = null;
53
86
  var http;
54
87
  if (/^https?\:/i.test(url)) {
55
88
  http = require("http");
@@ -59,6 +92,14 @@ return _cross.bind(function (callback, onerror) {
59
92
  }
60
93
  this.http = http;
61
94
  },
95
+ get responseType() {
96
+ return responseType;
97
+ },
98
+ set responseType(v) {
99
+ if (v === "document") return;
100
+ if (this.status !== 0) throw new Error("状态错误");
101
+ responseType = v;
102
+ },
62
103
  setRequestHeader(key, value) {
63
104
  this.headers[key] = value;
64
105
  },
@@ -1,8 +1,12 @@
1
1
  // 激活 自定义的 active 事件
2
- function active(target, value, item) {
2
+ function active(target, value, item, targetElement) {
3
3
  var activeEvent = createEvent("active");
4
4
  activeEvent.item = item;
5
5
  activeEvent.value = value;
6
+ if (targetElement) {
7
+ if (Object.defineProperty) Object.defineProperty(activeEvent, 'currentTarget', { value: targetElement });
8
+ else activeEvent.currentTarget = targetElement;
9
+ }
6
10
  activeEvent = dispatch(target, activeEvent);
7
11
  return activeEvent && !activeEvent.defaultPrevented;
8
12
  }
@@ -13,10 +13,9 @@ on("keydown")(window, function (event) {
13
13
  if (event.altKey) {
14
14
  var key = String.fromCharCode(which);
15
15
  var element = keyMap[key];
16
-
17
16
  if (element) {
18
17
  if (isMounted(element)) {
19
- dispatch(window, 'mousedown');
18
+ event.preventDefault();
20
19
  element.click();
21
20
  } else {
22
21
  delete keyMap[key];
@@ -254,13 +254,15 @@ function stringify(color) {
254
254
  }
255
255
  }
256
256
  function doWith(manager, color, args) {
257
- var c = parse(color);
257
+ var isparsed = color instanceof Array,
258
+ c = isparsed ? color : parse(color);
258
259
  if (!c) {
259
260
  console.warn(`颜色数据不正确:${color}`);
260
261
  return color;
261
262
  }
262
263
  c = manager(c, args);
263
- return stringify(c);
264
+ if (!isparsed) c = stringify(c);
265
+ return c;
264
266
  }
265
267
 
266
268
  function normal([r, g, b]) {
@@ -41,7 +41,7 @@ var cross = _cross.bind(function (callback, onerror) {
41
41
  }
42
42
  break;
43
43
  default:
44
- callback(xhr.status, xhr.response);
44
+ callback();
45
45
  }
46
46
  saveCookie();
47
47
  }
@@ -962,7 +962,7 @@ var data = {
962
962
  instanceDataMap[instanceId] = data;
963
963
  }
964
964
  setItem(instanceId, data, rememberWithStorage);
965
- fireListener(instanceId);
965
+ fireListener(instanceId, data);
966
966
  return instanceDataMap[instanceId];
967
967
  },
968
968
  patchInstance(instanceId, data, rememberWithStorage = 0) {
@@ -999,7 +999,7 @@ var data = {
999
999
  if (!~listeners.indexOf(callback)) {
1000
1000
  listeners.push(callback);
1001
1001
  }
1002
- callback(this.getInstance(instanceId));
1002
+ if (hasItem(instanceId)) callback(getItem(instanceId));
1003
1003
  },
1004
1004
  unbindInstance(instanceId, callback) {
1005
1005
  if (!instanceListenerMap[instanceId]) return;
@@ -1047,12 +1047,15 @@ function getItem(instanceId, onlyFromLocalStorage = false) {
1047
1047
  }
1048
1048
  return data;
1049
1049
  }
1050
+ function hasItem(instanceId) {
1051
+ const storageId = userPrefix + instanceId + pagePathName;
1052
+ return sessionStorage.getItem(storageId) || localStorage.getItem(storageId);
1053
+ }
1050
1054
  var instanceListenerMap = {};
1051
- var fireListener = function (instanceId) {
1055
+ var fireListener = function (instanceId, data) {
1052
1056
  var listeners = instanceListenerMap[instanceId];
1053
1057
  if (!listeners) return;
1054
- var instance = instanceDataMap[instanceId];
1055
- listeners.forEach(a => a(instance));
1058
+ listeners.forEach(a => a(data));
1056
1059
  };
1057
1060
  data.setItem = data.setInstance;
1058
1061
  data.getItem = data.getInstance;
@@ -148,20 +148,22 @@ function main(elem, mode) {
148
148
  case "x":
149
149
  case "horizonal":
150
150
  var direction = 'x';
151
+ mode = "horizonal";
151
152
  case "v":
152
153
  case "y":
153
154
  case "vertical":
154
- var emit = function (item) {
155
- active(elem, item, item.value);
155
+ var emit = function (item, target) {
156
+ active(elem, item, item.value, target);
156
157
  };
157
158
  if ("$src" in elem) {
158
159
  getGenerator(elem);
159
160
  care(elem, function (src) {
160
161
  menuList(elem, getTreeFromData(src), emit, direction);
161
162
  });
162
- } else {
163
+ }
164
+ else {
163
165
  var nodes = getArrayNodes(elem);
164
- elem = menuList(elem, nodes, emit);
166
+ elem = menuList(elem, nodes, emit, direction);
165
167
  }
166
168
  break;
167
169
  default:
@@ -94,10 +94,17 @@ body:active & {
94
94
  text-overflow: hidden;
95
95
  height: 40px;
96
96
  position: relative;
97
- border: 1px solid #18333c;
98
- background-color: #18333c;
99
- box-shadow: inset 0 0 12px #51ddf6, inset 0px -120px 120px -120px #51ddf6;
100
- border-right: none;
97
+ border-bottom: 1px solid #18333c;
98
+ padding: 0;
99
+
100
+ menu-item {
101
+ display: inline-block;
102
+
103
+ &.has-children:after {
104
+ padding-top: 3px;
105
+ content: "﹀";
106
+ }
107
+ }
101
108
 
102
109
  >div {
103
110
  vertical-align: top;
@@ -1,3 +1,3 @@
1
- <i ng-class="menu.icon" ng-if='useIcon||hasIcon||menu.icon'></i>
2
- <span ng-model="menu.name"></span>
1
+ <i ng-class="icon" ng-if='useIcon||hasIcon'></i>
2
+ <span ng-html="name"></span>
3
3
  <s></s>
@@ -1,11 +1,15 @@
1
1
  function main(elem, scope, hasIcon) {
2
2
  var item = elem || document.createElement('menu-item');
3
3
  item.innerHTML = menuItem;
4
- if (isObject(scope) && scope !== elem.$scope) {
5
- render(item, { menu: scope, useIcon: hasIcon, hasIcon })
4
+ if (isObject(scope) && scope !== item.$scope) {
6
5
  }
7
6
  else {
8
- extendIfNeeded(elem.$scope, { useIcon: false, hasIcon: false })
7
+ var scope = item.$scope;
9
8
  }
9
+ if (scope.menu) scope = scope.menu;
10
+ var name = scope.name;
11
+ var icon = scope.icon;
12
+ if (hasIcon === undefined) hasIcon = !!icon;
13
+ render(item.children, { useIcon: hasIcon, hasIcon, name, icon });
10
14
  return item;
11
15
  }
@@ -1,4 +1,4 @@
1
- <menu-item ng-repeat="menu in menus" ng-if="!menu.hidden" ng-click="open(menu,event)"
2
- ng-mouseleave="clearTimeout(popTimer)" ng-mouseenter="popTimer=popMenu(menu,event)"
1
+ <menu-item ng-repeat="menu in menus" ng-if="!menu.hidden" ng-click="open(menu,this)"
2
+ ng-mouseleave="clearTimeout(popTimer)" ng-mouseenter="popTimer=popMenu(menu,this)"
3
3
  ng-class="{'has-children':menu.children&&menu.children.length,'warn':menu.type==='danger'||menu.type==='warn'||menu.type==='red'}">
4
4
  </menu-item>
@@ -8,38 +8,52 @@ var release = function () {
8
8
  var clear = function () {
9
9
  clearTimeout(releaseTimer);
10
10
  };
11
+ var unfocus = function () {
12
+ remove(mounted_menus);
13
+ this.ispop = false;
14
+ };
11
15
  function main(page, items, active, direction = 'y') {
12
16
  if (!isNode(page)) {
13
17
  var page = div();
14
18
  }
15
19
  var main = this;
16
- function popMenu(item, event) {
20
+ if (direction !== 'x') page.ispop = true;
21
+ function popMenu(item, target) {
17
22
  if (page.active) {
18
23
  clear();
19
24
  remove(page.active);
20
25
  }
21
26
  if (!item.children || !item.children.length) return;
22
27
  var clone = template.cloneNode();
28
+ clone.$parentScopes = page.$parentScopes;
29
+ clone.$src = src;
23
30
  clone.innerHTML = template.innerHTML;
24
31
  var menu = main(clone, item.children, active);
25
32
  mounted_menus.push(menu);
26
-
27
33
  page.active = menu;
28
- popup(menu, event.target);
29
- var offleave0 = on("mouseleave")(event.target, release);
30
- var offenter0 = on("mouseenter")(event.target, clear);
31
- var offleave1 = on("mouseleave")(menu, release);
32
- var offenter1 = on("mouseenter")(menu, clear);
34
+ menu.root = page.root || page;
35
+ popup(menu, target);
36
+ if (page.ispop === true) {
37
+ var offleave0 = on("mouseleave")(target, release);
38
+ var offleave1 = on("mouseleave")(menu, release);
39
+ var offenter0 = on("mouseenter")(target, clear);
40
+ var offenter1 = on("mouseenter")(menu, clear);
41
+ } else {
42
+ page.ispop = 1;
43
+ page.tabIndex = 0;
44
+ page.focus();
45
+ }
46
+ on("mousedown")(menu, e => e.preventDefault());
33
47
  once("remove")(menu, function () {
34
- removeFromList(mounted_menus, page.active);
35
- offleave0();
36
- offenter0();
37
- offleave1();
38
- offenter1();
48
+ removeFromList(mounted_menus, this);
49
+ if (offleave0) offleave0();
50
+ if (offleave1) offleave1();
51
+ if (offenter0) offenter0();
52
+ if (offenter1) offenter1();
39
53
  });
40
54
  }
41
-
42
- var template = page.tempalte || page.cloneNode();
55
+ if (!page.ispop) on("blur")(page, unfocus);
56
+ var template = page.tempalte || document.createElement("ylist");
43
57
  if (!page.tempalte) {
44
58
  template.className = '';
45
59
  template.removeAttribute('mode');
@@ -47,7 +61,6 @@ function main(page, items, active, direction = 'y') {
47
61
  page.tempalte = template;
48
62
  }
49
63
  if (!page.children.length || page.menutype === 1) {
50
- page.innerHTML = menuList;
51
64
  page.menutype = 1;
52
65
  var hasIcon = function () {
53
66
  var menus = items;
@@ -58,26 +71,78 @@ function main(page, items, active, direction = 'y') {
58
71
  }
59
72
  return false;
60
73
  };
61
- render(page, {
62
- "menu-item": function () {
74
+ var $scope = {
75
+ "menu-item": function (e, s) {
63
76
  return button(
64
- menuItem.apply(null, arguments)
77
+ menuItem(e, s)
65
78
  );
66
79
  },
67
80
  menus: items,
68
81
  hasIcon: hasIcon(),
69
- open(menu, event) {
70
- active(menu, event);
82
+ open(menu, elem) {
83
+ var pop = active(menu, elem);
84
+ if (pop === false) return;
85
+ var root = page.root || page;
86
+ if (root.ispop === 1) root.ispop = false;
87
+ if (!mounted_menus.length) {
88
+ popMenu.apply(this, arguments);
89
+ }
90
+ else {
91
+ unfocus.call(page);
92
+ }
71
93
  },
72
94
  popTimer: 0,
73
95
  popMenu() {
96
+ if (!page.ispop) return;
74
97
  var args = arguments;
75
98
  return setTimeout(function () {
76
99
  popMenu.apply(null, args);
77
100
  }, 60);
78
101
  },
79
- });
80
- vbox(page);
102
+ };
103
+ if (page.$src) {
104
+ var src = page.$src;
105
+ var parentScopes = page.$parentScopes;
106
+ var itemName = src.itemName;
107
+ var className = `{'has-children':${itemName}.children&&${itemName}.children.length,'warn':${itemName}.type==='danger'||${itemName}.type==='warn'||${itemName}.type==='red'}`;
108
+ var notHidden = `!${itemName}.hidden`;
109
+ list(page, function (index) {
110
+ var item = items[index];
111
+ if (!item) return;
112
+ var a = menuItem(null, item, $scope.hasIcon);
113
+ var scope = {};
114
+ if (item instanceof Item) item = item.value;
115
+ if (src.itemName) scope[src.itemName] = item;
116
+ else scope.$item = item;
117
+ if (src.keyName) scope[src.keyName] = index;
118
+ else scope.$key = index;
119
+ if (src.indexName) scope[src.indexName] = index;
120
+ else scope.$index = index;
121
+ if (src.srcName) scope[src.srcName] = items;
122
+ if (src.itemName) a.setAttribute("e-if", notHidden);
123
+ on("mouseleave")(a, function () {
124
+ clearTimeout($scope.popTimer);
125
+ });
126
+ on("mouseenter")(a, function () {
127
+ $scope.popTimer = $scope.popMenu(item, this);
128
+ });
129
+ on("click")(a, function () {
130
+ $scope.open(items[index], this);
131
+ });
132
+ a.setAttribute("e-class", className);
133
+ a = button(a);
134
+ render(a, scope, parentScopes);
135
+ return a;
136
+ });
137
+ on("append")(page, function () {
138
+ this.go(0);
139
+ })
140
+ }
141
+ else {
142
+ page.innerHTML = menuList;
143
+ render(page, $scope);
144
+ vbox(page);
145
+ }
81
146
  page.renders.unshift(function () {
82
147
  this.$scope.hasIcon = hasIcon();
83
148
  });
@@ -86,11 +151,20 @@ function main(page, items, active, direction = 'y') {
86
151
  list(page, function (index) {
87
152
  var elem = generator(index);
88
153
  if (!elem) return;
89
- on("mouseenter")(elem, function (event) {
90
- popMenu(this.src[index], event);
154
+ on("mouseenter")(elem, function () {
155
+ if (page.ispop) popMenu(this.src[index], this);
91
156
  });
92
- on("click")(elem, function (event) {
93
- active(this.src[index], event);
157
+ on("click")(elem, function () {
158
+ var pop = active(this.src[index], this);
159
+ if (pop === false) return;
160
+ var root = page.root || page;
161
+ if (root.ispop === 1) root.ispop = false;
162
+ if (!mounted_menus.length) {
163
+ popMenu(this.src[index], this);
164
+ }
165
+ else {
166
+ unfocus.call(page);
167
+ }
94
168
  });
95
169
  return elem;
96
170
  }, direction);