@litejs/ui 21.11.0 → 22.8.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.
@@ -115,20 +115,22 @@
115
115
  }
116
116
  }
117
117
 
118
- bindings.is = function bindingIs(node, model, path, list, state) {
118
+ bindings.is = function bindingIs(node, model, path, list, state, prefix) {
119
119
  var match
120
120
  , scope = this
121
121
  if (typeof model === "string") {
122
+ prefix = state
122
123
  state = list
123
124
  list = path
124
125
  path = model
125
126
  model = scope.model
126
127
  }
127
128
  if (model && path) {
129
+ if (!prefix) prefix = "is-"
128
130
  match = i18n.pick(state !== match ? state : model.get(path), list)
129
131
  path += "-" + list
130
- El.cls(node, node["_is-" + path], 0)
131
- El.cls(node, node["_is-" + path] = match && "is-" + match)
132
+ El.cls(node, node[prefix + path], 0)
133
+ El.cls(node, node[prefix + path] = match && prefix + match)
132
134
  }
133
135
  }
134
136
 
@@ -0,0 +1,16 @@
1
+
2
+ // .sticky { position: sticky; top: -1px; }
3
+ // .sticky.is-stuck { color: red; }
4
+
5
+ El.bindings.sticky = function sticky(el) {
6
+ ;(sticky._ob || (sticky._ob = new IntersectionObserver(function(entries) {
7
+ entries.forEach(function(entry) {
8
+ El.cls(entry.target, "is-stuck", entry.intersectionRatio < 1)
9
+ })
10
+ }, { threshold: 1 }))).observe(el)
11
+ El.cls(el, "sticky")
12
+ }
13
+
14
+ El.bindings.sticky.once = 1
15
+
16
+
package/css/grid.css CHANGED
@@ -7,8 +7,14 @@ Expects box-sizing: border-box;
7
7
  .row {
8
8
  display: block;
9
9
  clear: both;
10
+ contain: content;
11
+ *zoom: 1;
10
12
  }
11
- .row {
13
+
14
+ .grid:after,
15
+ .row:after {
16
+ content: " ";
17
+ display: block;
12
18
  clear: both;
13
19
  }
14
20
 
@@ -21,13 +27,6 @@ Expects box-sizing: border-box;
21
27
  clear: none;
22
28
  }
23
29
 
24
- .grid:after,
25
- .row:after {
26
- content: " ";
27
- display: block;
28
- clear: both;
29
- }
30
-
31
30
  .col,
32
31
  .w12, .md .md-w12, .lg .md-w12, .lg .lg-w12 { width: 100%; }
33
32
  .w11, .md .md-w11, .lg .md-w11, .lg .lg-w11 { width: 91.6667%; }
File without changes
File without changes
@@ -220,7 +220,7 @@
220
220
  }
221
221
  function set(val, e, pos) {
222
222
  load()
223
- val = (val < min ? min : val > max ? max : val).step(step)
223
+ val = (val < min ? min : val > max ? max : val || 0).step(step)
224
224
  if (value !== void 0 && (!drag || pos !== void 0)) {
225
225
  El.css(fill, vert ? "height" : "width", ((pos || (val-min)*px)+knobLen) + "px", 0)
226
226
  }
@@ -13,7 +13,7 @@
13
13
  right: 0;
14
14
  margin: 0 auto;
15
15
  top: 4%;
16
- width: 400px;
16
+ width: 600px;
17
17
  background-color: #fff;
18
18
  box-shadow: 0 2px 10px 2px rgba(255,255,255,.5);
19
19
  }
@@ -73,7 +73,7 @@
73
73
  Object.assign(scope, opts)
74
74
  scope.title = title || "Confirm?"
75
75
  if (!scope.actions) scope.actions = [
76
- { action: "close", title: "Close" }
76
+ { action: "close", title: "Close", key: "esc" }
77
77
  ]
78
78
  for (var a, i = 0; a = scope.actions[i++]; ) {
79
79
  if (typeof a == "string") a = scope.actions[i-1] = {title:a,action:a}
@@ -106,23 +106,31 @@
106
106
  var num = _num == void 0 ? e.target[El.T] : _num
107
107
  code += num
108
108
  if (num == "CLEAR" || num == "del" || num == "backspace") code = ""
109
- El.txt(El.find(el, ".js-body"), code.replace(/./g, "•") || opts.body)
110
- // if (code.length == 4 && id && !sent) next(sent = code, id, resolve, reject)
109
+ El.md(El.find(el, ".js-body"), code.replace(/./g, "•") || opts.body)
110
+ if (typeof scope.code == "number" && code.length == scope.code && id && !sent) next(sent = code, id, resolve, reject)
111
111
  }
112
112
  function resolve(e, key) {
113
113
  if (el) {
114
+ var action = key || El.attr(this, "data-action")
115
+ , result = {
116
+ code: code,
117
+ input: El.val(El.find(el, ".js-input")),
118
+ inputMd: El.val(El.find(el, ".js-inputMd")),
119
+ select: El.val(El.find(el, ".js-select"))
120
+ }
114
121
  El.kill(el, "transparent")
115
122
  El.cls(blurEl, "Confirm--blur", el = 0)
116
- var action = key || El.attr(this, "data-action")
117
123
  if (action && next) {
118
- if (typeof next === "function") next(action, code)
119
- else if (typeof next[action] === "function") next[action](code)
120
- else if (next[action]) View.emit(next[action], code)
124
+ if (typeof next === "function") next(action, result)
125
+ else if (typeof next[action] === "function") next[action](result)
126
+ else if (next[action]) View.emit(next[action], result)
121
127
  }
122
128
  if (vibrate) navigator.vibrate(0)
123
129
  if (sound) sound.pause()
124
130
  }
125
131
  }
132
+ scope.resolve = resolve
133
+ View.emit("confirm:open", scope)
126
134
  })
127
135
 
128
136
  %el Confirm
@@ -130,11 +138,31 @@
130
138
  .Confirm-bg.max.abs
131
139
  .Confirm-content.Confirm--blur.grid.p2.anim
132
140
  .col.ts3 ;txt:: _(title, map)
133
- .col.js-body ;txt:: _(body, map)
141
+ .col.js-body ;md:: _(body, map)
134
142
  .row.js-numpad
135
143
  ;if: code
136
144
  ;each: num in [1,2,3,4,5,6,7,8,9,"CLEAR",0]
137
145
  .col.w4>.btn {num}
146
+ .row
147
+ ;if: input
148
+ .col>input.field.js-input
149
+ .row
150
+ ;if: data.inputMd!=null
151
+ .col
152
+ textarea.field.js-inputMd
153
+ @keyup [this.parentNode.nextSibling.nextSibling], "renderMd"
154
+ ;val: inputMd
155
+ .col.ts3 Preview
156
+ .p4
157
+ ;md: inputMd
158
+ .row
159
+ ;if: select
160
+ .col
161
+ select.field.js-select
162
+ ;list: select, [""]
163
+ option
164
+ ;val:: item.id
165
+ ;txt:: _(item.name)
138
166
  .col
139
167
  .group ;each: action in actions
140
168
  .btn.js-btn
@@ -3,12 +3,14 @@
3
3
  border: 0;
4
4
  padding: 0;
5
5
  }
6
- .Form1-del {
6
+ .Form1-del.right {
7
7
  display: block;
8
8
  margin: -10px -10px 0 0;
9
+ opacity: .2;
10
+ }
11
+ .Form1-del {
9
12
  font-size: 20px;
10
13
  font-weight: 700;
11
- opacity: .2;
12
14
  border: 1px solid transparent;
13
15
  line-height: 16px;
14
16
  width: 20px;
@@ -28,7 +30,6 @@
28
30
  display: block;
29
31
  border-radius: 4px;
30
32
  border: 1px solid #aaa;
31
- overflow: auto;
32
33
  }
33
34
  .field {
34
35
  width: 100%;
@@ -93,9 +94,11 @@
93
94
  opacity: .6;
94
95
  pointer-events: none;
95
96
  }
97
+ .group {
98
+ overflow: auto;
99
+ }
96
100
  .group > .btn {
97
101
  border-radius: 0;
98
- margin-left: -1px;
99
102
  float: left;
100
103
  }
101
104
  .group > .btn:first-child {
@@ -225,7 +228,7 @@
225
228
 
226
229
  %el form1-array
227
230
  .col
228
- .input.p13
231
+ .input.p13.cf
229
232
  .left
230
233
  = _(title||name)
231
234
  .input__hint
@@ -237,10 +240,11 @@
237
240
  @click: data.add
238
241
 
239
242
  %el form1-array-item
240
- .input.p3.m2b.js-del
243
+ .input.p3.m2b.cf.js-del
241
244
  a.right.Form1-del.hand ×
242
245
  ;if: !data.noAdd
243
- ;on: "click", data.del
246
+ ;data:: "tooltip", _("Delete")
247
+ @click: data.del
244
248
  b
245
249
  ;if: title
246
250
  ;txt: title
@@ -202,8 +202,8 @@
202
202
  El.near = near
203
203
  function near(source, target, x, y, margin) {
204
204
  var rect = target.getBoundingClientRect()
205
- , top = rect.top
206
- , left = rect.left
205
+ , top = rect.top + El.scrollTop()
206
+ , left = rect.left + El.scrollLeft()
207
207
  // svg elements dont have offsetWidth, IE8 does not have rect.width
208
208
  , width = rect.width || target.offsetWidth || 0
209
209
  , height = rect.height || target.offsetHeight || 0
@@ -229,12 +229,15 @@
229
229
  } else if (y == "bottom") {
230
230
  top += height + margin
231
231
  y = " -50%"
232
+ setTimeout(function(){
233
+ //document.scrollingElement.scrollHeight
234
+ var overflow = top + source.offsetHeight - El.scrollTop() - document.documentElement.offsetHeight
235
+ if (overflow > 0) scrollBy({ top: overflow, left: 0, behavior: "smooth" })
236
+ }, 400)
232
237
  } else {
233
238
  top += (height / 2) - (source.offsetHeight/2)
234
239
  y = " 50%"
235
240
  }
236
- left += El.scrollLeft()
237
- top += El.scrollTop()
238
241
  El.css(source, {
239
242
  "transform-origin": x + y,
240
243
  top: (top < 0 ? 0 : top) + "px",
@@ -271,7 +274,8 @@
271
274
  }
272
275
  function openVisible(tag, target) {
273
276
  var el = typeof tag == "string" ? El(tag) : tag
274
- El.scope(el, El.scope(target))
277
+ , scope = El.scope(el, El.scope(target))
278
+ scope.openTarget = target
275
279
  El.render(el)
276
280
  El.append(document.body, el)
277
281
  El.cls(el, "is-visible", 1, 5)
@@ -296,7 +300,7 @@
296
300
  El.cls(menuTarget, "is-active", menuEl = menuTarget = null)
297
301
  }
298
302
  }
299
- View.on("resize", closeMenu)
303
+ View.on("ping", closeMenu)
300
304
  View.on("closeMenu", closeMenu)
301
305
  View.on("showMenu", function(e, target, menu, x, y, margin) {
302
306
  Event.stop(e)
package/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*
2
- * @version 21.11.0
2
+ * @version 22.8.0
3
3
  * @author Lauri Rooden <lauri@rooden.ee>
4
4
  * @license MIT License
5
5
  */
@@ -347,26 +347,6 @@
347
347
  Fn.wait = wait
348
348
 
349
349
 
350
- // Function extensions
351
- // -------------------
352
-
353
- F.extend = function() {
354
- var arg
355
- , fn = this
356
- , i = 0
357
-
358
- function wrapper() {
359
- return fn.apply(this, arguments)
360
- }
361
-
362
- for (wrapper[P] = Object.create(fn[P]); arg = arguments[i++]; ) {
363
- Object.assign(wrapper[P], arg)
364
- }
365
- wrapper[P].constructor = wrapper
366
- return wrapper
367
- }
368
-
369
-
370
350
  // Non-standard
371
351
  Object.each = function(obj, fn, scope, key) {
372
352
  if (obj) for (key in obj) {
@@ -555,7 +535,8 @@
555
535
  for (k in obj) if (typeof obj[k] == "function" && ignore.indexOf(k) < 0) !function(k) {
556
536
  hooked.push(k, hasOwn.call(obj, k) && obj[k])
557
537
  obj[k] = function() {
558
- hooks.push(k, arguments)
538
+ if (hooks === null) obj[k].apply(this, arguments)
539
+ else hooks.push(k, arguments)
559
540
  return obj
560
541
  }
561
542
  }(k)
@@ -648,9 +629,9 @@
648
629
  , emitter = this === exports ? empty : this
649
630
  , _e = emitter._e
650
631
  , arr = _e ? (_e[type] || empty).concat(_e["*"] || empty) : empty
651
- if (i = _e = arr.length) {
652
- for (args = arr.slice.call(arguments, 1); i--; ) {
653
- arr[i--].apply(arr[--i] || emitter, args)
632
+ if ((_e = arr.length)) {
633
+ for (i = _e - 1, args = arr.slice.call(arguments, 1); i > 1; i -= 3) {
634
+ arr[i] && arr[i].apply(arr[i - 2] || emitter, args)
654
635
  }
655
636
  }
656
637
  return _e / 3
@@ -831,7 +812,7 @@
831
812
  var key, name
832
813
  , opts = Object.assign({}, defaults, _opts)
833
814
  for (key in opts) if (hasOwn.call(opts, key)) {
834
- if (typeof View[key] == "function") {
815
+ if (typeof View[key] === "function") {
835
816
  for (name in opts[key]) if (hasOwn.call(opts[key], name)) {
836
817
  View[key](name, opts[key][name])
837
818
  }
@@ -858,7 +839,7 @@
858
839
  view.el = el
859
840
  view.parent = parent && View(parent)
860
841
 
861
- if (route.charAt(0) != "#") {
842
+ if (route.charAt(0) !== "#") {
862
843
  var params = "m[" + (view.seq = capture++) + "]?("
863
844
  , _re = route.replace(parseRe, function(_, key) {
864
845
  return key ?
@@ -881,13 +862,14 @@
881
862
  , close = view.isOpen && view
882
863
 
883
864
  View.route = view.route
865
+ emit(view, "init")
884
866
 
885
867
  for (; tmp; tmp = parent) {
886
868
  emit(syncResume = params._v = tmp, "ping", params, View)
887
869
  syncResume = null
888
- if (lastParams != params) return
870
+ if (lastParams !== params) return
889
871
  if (parent = tmp.parent) {
890
- if (parent.child && parent.child != tmp) {
872
+ if (parent.child && parent.child !== tmp) {
891
873
  close = parent.child
892
874
  }
893
875
  parent.child = tmp
@@ -901,7 +883,7 @@
901
883
  view.wait(tmp.file = null)
902
884
  )
903
885
  } else {
904
- if (tmp.route == "404") {
886
+ if (tmp.route === "404") {
905
887
  El.txt(tmp = El("h3"), "# Error 404")
906
888
  View("404", tmp, "#body")
907
889
  }
@@ -913,7 +895,7 @@
913
895
 
914
896
  if (view !== close) emit(view, "change", close)
915
897
 
916
- for (tmp in params) if (tmp.charAt(0) != "_") {
898
+ for (tmp in params) if (tmp.charAt(0) !== "_") {
917
899
  if (syncResume = hasOwn.call(paramCb, tmp) && paramCb[tmp] || paramCb["*"]) {
918
900
  syncResume.call(view, params[tmp], tmp, params)
919
901
  syncResume = null
@@ -926,7 +908,7 @@
926
908
  var params = lastParams
927
909
  params._p = 1 + (params._p | 0)
928
910
  return function() {
929
- if (--params._p || lastParams != params || syncResume) return
911
+ if (--params._p || lastParams !== params || syncResume) return
930
912
  if (params._d) {
931
913
  bubbleDown(params)
932
914
  } else if (params._v) {
@@ -959,7 +941,7 @@
959
941
  if (params._d = params._v = view.child) {
960
942
  bubbleDown(params, close)
961
943
  }
962
- if (lastView == view) {
944
+ if (lastView === view) {
963
945
  emit(view, "show", params)
964
946
  blur()
965
947
  }
@@ -1007,7 +989,7 @@
1007
989
  }
1008
990
  var params = _params || {}
1009
991
  , view = get(url, params)
1010
- if (!view.isOpen || lastUrl != url) {
992
+ if (!view.isOpen || lastUrl !== url) {
1011
993
  params._u = lastUrl = url
1012
994
  view.show(El.data.params = params)
1013
995
  }
@@ -1058,20 +1040,20 @@
1058
1040
  /* litejs.com/MIT-LICENSE.txt */
1059
1041
 
1060
1042
 
1061
- !function(window, document, Object, Event, protoStr) {
1043
+ !function(window, document, Object, Event, P) {
1062
1044
  var UNDEF, styleNode
1063
1045
  , BIND_ATTR = "data-bind"
1064
1046
  , isArray = Array.isArray
1065
1047
  , seq = 0
1066
1048
  , elCache = El.cache = {}
1067
- , wrapProto = ElWrap[protoStr] = []
1049
+ , wrapProto = ElWrap[P] = []
1068
1050
  , slice = wrapProto.slice
1069
1051
  , hasOwn = elCache.hasOwnProperty
1070
1052
  , body = document.body
1071
1053
  , root = document.documentElement
1072
1054
  , txtAttr = El.T = "textContent" in body ? "textContent" : "innerText"
1073
1055
  , templateRe = /([ \t]*)(%?)((?:("|')(?:\\?.)*?\4|[-\w:.#[\]]=?)*)[ \t]*([>^;@|\\\/]|!?=|)(([\])}]?).*?([[({]?))(?=\x1f+|\n+|$)/g
1074
- , renderRe = /[;\s]*(\w+)(?:\s*(:?):((?:(["'\/])(?:\\?.)*?\3|[^;])*))?/g
1056
+ , renderRe = /[;\s]*(\w+)(?:(::?| )((?:(["'\/])(?:\\?.)*?\3|[^;])*))?/g
1075
1057
  , selectorRe = /([.#:[])([-\w]+)(?:\((.+?)\)|([~^$*|]?)=(("|')(?:\\?.)*?\6|[-\w]+))?]?/g
1076
1058
  , splitRe = /[,\s]+/
1077
1059
  , camelRe = /\-([a-z])/g
@@ -1089,6 +1071,11 @@
1089
1071
  html: function(el, html) {
1090
1072
  el.innerHTML = html
1091
1073
  },
1074
+ md: El.md = function(el, txt) {
1075
+ txt = txt.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;")
1076
+ txt = txt.replace(/\n/g, "<br>")
1077
+ el.innerHTML = txt
1078
+ },
1092
1079
  ref: function(el, name) {
1093
1080
  this[name] = el
1094
1081
  },
@@ -1168,14 +1155,14 @@
1168
1155
  pres = 1
1169
1156
  val = quotation ? val.slice(1, -1) : val || key
1170
1157
  pre[op =
1171
- op == "." ?
1158
+ op === "." ?
1172
1159
  (fn = "~", "class") :
1173
- op == "#" ?
1160
+ op === "#" ?
1174
1161
  "id" :
1175
1162
  key
1176
1163
  ] = fn && pre[op] ?
1177
- fn == "^" ? val + pre[op] :
1178
- pre[op] + (fn == "~" ? " " : "") + val :
1164
+ fn === "^" ? val + pre[op] :
1165
+ pre[op] + (fn === "~" ? " " : "") + val :
1179
1166
  val
1180
1167
  return ""
1181
1168
  }) || "div"
@@ -1256,11 +1243,11 @@
1256
1243
 
1257
1244
  /*** ie8 ***/
1258
1245
  // istanbul ignore next: IE fix
1259
- if (ie67 && (key == "id" || key == "name" || key == "checked")) {
1246
+ if (ie67 && (key === "id" || key === "name" || key === "checked")) {
1260
1247
  el.mergeAttributes(document.createElement('<INPUT ' + key + '="' + val + '">'), false)
1261
1248
  } else
1262
1249
  /**/
1263
- if (key == "class") {
1250
+ if (key === "class") {
1264
1251
  cls(el, val)
1265
1252
  } else if (val || val === 0) {
1266
1253
  if (current != val) {
@@ -1272,6 +1259,7 @@
1272
1259
  }
1273
1260
 
1274
1261
  function valFn(el, val) {
1262
+ if (!el) return ""
1275
1263
  var input, step, key, value
1276
1264
  , i = 0
1277
1265
  , type = el.type
@@ -1346,7 +1334,7 @@
1346
1334
  , i = 0
1347
1335
  , tmp = typeof child
1348
1336
  if (child) {
1349
- if (tmp == "string" || tmp == "number") child = document.createTextNode(child)
1337
+ if (tmp === "string" || tmp === "number") child = document.createTextNode(child)
1350
1338
  else if ( !("nodeType" in child) && "length" in child ) {
1351
1339
  // document.createDocumentFragment is unsupported in IE5.5
1352
1340
  // fragment = "createDocumentFragment" in document ? document.createDocumentFragment() : El("div")
@@ -1371,7 +1359,7 @@
1371
1359
  /**/
1372
1360
  tmp.insertBefore(child,
1373
1361
  (before === true ? tmp.firstChild :
1374
- typeof before == "number" ? tmp.childNodes[
1362
+ typeof before === "number" ? tmp.childNodes[
1375
1363
  before < 0 ? tmp.childNodes.length - before - 2 : before
1376
1364
  ] : before) || null
1377
1365
  )
@@ -1524,14 +1512,14 @@
1524
1512
 
1525
1513
  function bindingOn(el, events, selector, data, handler, delay) {
1526
1514
  var argi = arguments.length
1527
- if (argi == 3 || argi == 4 && typeof data == "number") {
1515
+ if (argi == 3 || argi == 4 && typeof data === "number") {
1528
1516
  delay = data
1529
1517
  handler = selector
1530
1518
  selector = data = null
1531
- } else if (argi == 4 || argi == 5 && typeof handler == "number") {
1519
+ } else if (argi == 4 || argi == 5 && typeof handler === "number") {
1532
1520
  delay = handler
1533
1521
  handler = data
1534
- if (typeof selector == "string") {
1522
+ if (typeof selector === "string") {
1535
1523
  data = null
1536
1524
  } else {
1537
1525
  data = selector
@@ -1543,7 +1531,7 @@
1543
1531
  return
1544
1532
  }
1545
1533
  var fn = (
1546
- typeof handler == "string" ? function(e) {
1534
+ typeof handler === "string" ? function(e) {
1547
1535
  var target = selector ? El.closest(e.target, selector) : el
1548
1536
  if (target) View.emit.apply(View, [handler, e, target].concat(data))
1549
1537
  } :
@@ -1628,6 +1616,7 @@
1628
1616
  }
1629
1617
 
1630
1618
  function render(node, _scope) {
1619
+ if (!node) return
1631
1620
  var bind, fn
1632
1621
  , scope = elScope(node, 0, _scope)
1633
1622
  , i = 0
@@ -1648,7 +1637,7 @@
1648
1637
  scope._m[i] = match
1649
1638
  match = bindings[name]
1650
1639
  return (
1651
- (op == ":" || match && hasOwn.call(match, "once")) ?
1640
+ (op === "::" || match && hasOwn.call(match, "once")) ?
1652
1641
  "s(this,B,data._t=data._t.replace(data._m[" + (i++)+ "],''))||" :
1653
1642
  ""
1654
1643
  ) + (
@@ -1678,7 +1667,7 @@
1678
1667
  render(bind, scope)
1679
1668
  }
1680
1669
  /*** ie8 ***/
1681
- if (ie678 && node.tagName == "SELECT") {
1670
+ if (ie678 && node.tagName === "SELECT") {
1682
1671
  node.parentNode.insertBefore(node, node)
1683
1672
  }
1684
1673
  /**/
@@ -1760,16 +1749,16 @@
1760
1749
  append(parent, parent = q = El(name))
1761
1750
  }
1762
1751
  if (text && op != "/") {
1763
- if (op == ">") {
1752
+ if (op === ">") {
1764
1753
  (indent + " " + text).replace(templateRe, work)
1765
- } else if (op == "|" || op == "\\") {
1754
+ } else if (op === "|" || op === "\\") {
1766
1755
  append(parent, text) // + "\n")
1767
1756
  } else {
1768
- if (op == "@") {
1757
+ if (op === "@") {
1769
1758
  text = text.replace(/(\w+):?/, "on:'$1',")
1770
1759
  } else if (op != ";" && op != "^") {
1771
- text = (parent.tagName == "INPUT" ? "val" : "txt") + (
1772
- op == "=" ? ":" + text.replace(/'/g, "\\'") :
1760
+ text = (parent.tagName === "INPUT" ? "val" : "txt") + (
1761
+ op === "=" ? ":" + text.replace(/'/g, "\\'") :
1773
1762
  ":_('" + text.replace(/'/g, "\\'") + "', data)"
1774
1763
  )
1775
1764
  }
@@ -1785,7 +1774,7 @@
1785
1774
  function appendBind(el, val, sep, q) {
1786
1775
  var current = getAttr(el, BIND_ATTR)
1787
1776
  setAttr(el, BIND_ATTR, (current ? (
1788
- q == "^" ?
1777
+ q === "^" ?
1789
1778
  val + sep + current :
1790
1779
  current + sep + val
1791
1780
  ) : val))
@@ -1799,7 +1788,7 @@
1799
1788
  t.el.plugin = t
1800
1789
  }
1801
1790
 
1802
- plugin[protoStr] = {
1791
+ plugin[P] = {
1803
1792
  _done: function() {
1804
1793
  var t = this
1805
1794
  , childNodes = t.el.childNodes
@@ -1832,15 +1821,15 @@
1832
1821
  t.a = attr1
1833
1822
  }
1834
1823
 
1835
- js[protoStr].done = Fn("Function(this.txt)()")
1824
+ js[P].done = Fn("Function(this.txt)()")
1836
1825
 
1837
1826
  El.plugins = {
1838
- binding: js.extend({
1827
+ binding: extend(js, {
1839
1828
  done: function() {
1840
1829
  Object.assign(bindings, Function("return({" + this.txt + "})")())
1841
1830
  }
1842
1831
  }),
1843
- child: plugin.extend({
1832
+ child: extend(plugin, {
1844
1833
  done: function() {
1845
1834
  var key = "@child-" + (++seq)
1846
1835
  , root = append(this.parent, document.createComment(key))
@@ -1849,13 +1838,13 @@
1849
1838
  root._cp = root.childNodes.length - 1
1850
1839
  }
1851
1840
  }),
1852
- css: js.extend({
1841
+ css: extend(js, {
1853
1842
  done: Fn("xhr.css(this.txt)")
1854
1843
  }),
1855
- def: js.extend({
1844
+ def: extend(js, {
1856
1845
  done: Fn("View.def(this.params||this.txt)")
1857
1846
  }),
1858
- each: js.extend({
1847
+ each: extend(js, {
1859
1848
  done: function() {
1860
1849
  var txt = this.txt
1861
1850
 
@@ -1867,7 +1856,7 @@
1867
1856
  }),
1868
1857
  el: plugin,
1869
1858
  js: js,
1870
- map: js.extend({
1859
+ map: extend(js, {
1871
1860
  done: function() {
1872
1861
  var self = this
1873
1862
  , txt = (self.params + self.txt)
@@ -1879,7 +1868,7 @@
1879
1868
  }
1880
1869
  }),
1881
1870
  template: plugin,
1882
- view: plugin.extend({
1871
+ view: extend(plugin,{
1883
1872
  done: function() {
1884
1873
  var fn
1885
1874
  , t = this
@@ -1889,7 +1878,7 @@
1889
1878
  if (bind) {
1890
1879
  fn = bind.replace(renderRe, function(match, name, op, args) {
1891
1880
  return "(this['" + name + "']" + (
1892
- typeof view[name] == "function" ?
1881
+ typeof view[name] === "function" ?
1893
1882
  "(" + (args || "") + ")" :
1894
1883
  "=" + args
1895
1884
  ) + "),"
@@ -1898,7 +1887,7 @@
1898
1887
  }
1899
1888
  }
1900
1889
  }),
1901
- "view-link": plugin.extend({
1890
+ "view-link": extend(plugin, {
1902
1891
  done: function() {
1903
1892
  var t = this
1904
1893
  , arr = t.name.split(splitRe)
@@ -2049,4 +2038,14 @@
2049
2038
  addEvent(window, "orientationchange", setBreakpointsRated)
2050
2039
  addEvent(window, "load", setBreakpointsRated)
2051
2040
  /**/
2041
+
2042
+ function extend(fn, opts) {
2043
+ function wrapper() {
2044
+ return fn.apply(this, arguments)
2045
+ }
2046
+ wrapper[P] = Object.create(fn[P])
2047
+ Object.assign(wrapper[P], opts)
2048
+ wrapper[P].constructor = wrapper
2049
+ return wrapper
2050
+ }
2052
2051
  }(window, document, Object, Event, "prototype")
package/load.js CHANGED
@@ -28,7 +28,7 @@
28
28
  // MSXML 6.0 has improved XSD, deprecated several legacy features
29
29
  // What's New in MSXML 6.0: https://msdn.microsoft.com/en-us/library/ms753751.aspx
30
30
 
31
- !function(window, Function) {
31
+ !function(window, Function, setTimeout) {
32
32
  xhr._s = new Date
33
33
  var loaded = {}
34
34
  , urlEscRe = /[+#\s]+/g
@@ -275,5 +275,5 @@
275
275
  /**/
276
276
 
277
277
  function nop() {}
278
- }(this, Function)
278
+ }(this, Function, setTimeout)
279
279
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@litejs/ui",
3
- "version": "21.11.0",
3
+ "version": "22.8.0",
4
4
  "description": "UI engine for LiteJS full-stack framework",
5
5
  "license": "MIT",
6
6
  "author": "Lauri Rooden <lauri@rooden.ee>",
@@ -17,9 +17,9 @@
17
17
  "files": [
18
18
  "*.js",
19
19
  "binding",
20
- "component",
21
- "polyfill",
22
- "css"
20
+ "css",
21
+ "el",
22
+ "polyfill"
23
23
  ],
24
24
  "litejs": {
25
25
  "build": "lj b --out=test/index.html test/dev.html"
package/polyfill/index.js CHANGED
@@ -200,7 +200,7 @@
200
200
  /**/
201
201
  var data = {
202
202
  setItem: function(id, val) {
203
- return data[id] = String(val)
203
+ return data[id] = "" + val
204
204
  },
205
205
  getItem: function(id) {
206
206
  return data[id]
@@ -239,15 +239,14 @@
239
239
  },
240
240
  stringify: function stringify(o) {
241
241
  // IE 8 serializes `undefined` as `"undefined"`
242
- var c = typeof o
243
242
  return (
244
- c == "string" ? '"' + o.replace(jsonRe, jsonFn) + '"' :
245
- o && c == "object" ? (
243
+ isStr(o) ? '"' + o.replace(jsonRe, jsonFn) + '"' :
244
+ o && typeof o == "object" ? (
246
245
  isFn(o.toJSON) ? stringify(o.toJSON()) :
247
246
  isArr(o) ? "[" + o.map(stringify) + "]" :
248
247
  "{" + oKeys(o).map(function(a){return stringify(a) + ":" + stringify(o[a])}) + "}"
249
248
  ) :
250
- c == "number" && !isFinite(o) ? "null" :
249
+ typeof o == "number" && !isFinite(o) ? "null" :
251
250
  "" + o
252
251
  )
253
252
  }
@@ -290,6 +289,7 @@
290
289
  a = "c=[];for(b in a)o.call(a,b)&&c.push("
291
290
  b = ");return c"
292
291
  patch("entries", a + "[b,a[b]]" + b)
292
+ patch("hasOwn", "return!!(a&&o.call(a,b))")
293
293
  oKeys = patch("keys", a + "b" + b)
294
294
  patch("values", a + "a[b]" + b)
295
295
  //patch("fromEntries", "for(a=a.entries(),c={};!(b=a.next()).done;c[b[0]]=b[1]" + b)
@@ -303,7 +303,7 @@
303
303
 
304
304
  // TODO:2021-02-25:lauri:Accept iterable objects
305
305
  //patch("from", "a=S.call(a);return b?a.map(b,c):a")
306
- patch("from", "a=typeof a==='string'?a.split(''):b?a:S.call(a);return b?a.map(b,c):a")
306
+ patch("from", "a=X(a)?a.split(''):b?a:S.call(a);return b?a.map(b,c):a", 0, isStr)
307
307
  patch("of", "return S.call(A)")
308
308
 
309
309
  O = O[P]
@@ -329,6 +329,7 @@
329
329
  patch("some", b + "return!0;return!1")
330
330
 
331
331
  patch("flat", "return a<1?S.call(t):(b=t.concat.apply([],t))&&a>1&&b.some(X)?b.flat(a-1):b", 0, isArr)
332
+ patch("flatMap", "return X.apply(t,A).flat()", 0, O.map)
332
333
  //patch("entries", "a=this;b=-1;return{next:function(){c=a.length<=++b;return{done:c,value:c?void 0:a[b]}}}")
333
334
 
334
335
 
@@ -406,7 +407,7 @@
406
407
  }
407
408
  function walk(el, by, sel, first, nextFn) {
408
409
  var out = []
409
- if (typeof sel !== "function") sel = selectorFn(sel)
410
+ if (!isFn(sel)) sel = selectorFn(sel)
410
411
  for (; el; el = el[by] || nextFn && nextFn(el)) if (sel(el)) {
411
412
  if (first === 1) return el
412
413
  out.push(el)
@@ -423,7 +424,7 @@
423
424
 
424
425
  // ie6789
425
426
  // The documentMode is an IE only property, supported from IE8.
426
- if (ie678 || document.documentMode <= 9) {
427
+ if (ie678) {
427
428
  try {
428
429
  // Remove background image flickers on hover in IE6
429
430
  // You could also use CSS
@@ -432,15 +433,18 @@
432
433
  } catch(e){}
433
434
  }
434
435
 
435
- function isFn(f) {
436
- return typeof f === "function"
436
+ function isFn(value) {
437
+ return typeof value === "function"
438
+ }
439
+ function isStr(value) {
440
+ return typeof value === "string"
437
441
  }
438
442
  function nop() {}
439
443
 
440
444
  function patch(key_, src, force, arg1, arg2) {
441
445
  var key = key_.split(":").pop()
442
446
  return !force && O[key] || (O[patched.push(key_), key] = (
443
- typeof src === "string" ?
447
+ isStr(src) ?
444
448
  Function("o,O,P,S,F,X,Y", "return function(a,b,c){var t=this,A=arguments;" + src + "}")(hasOwn, O[key], P, patched.slice, force, arg1, arg2) :
445
449
  src || {}
446
450
  ))
package/schema-apply.js CHANGED
@@ -46,6 +46,9 @@
46
46
  } else if (type == "string") {
47
47
  if (type !== actualType) data = "" + data
48
48
  } else if (type === "number" || type == "integer") {
49
+ if (schema["ui:el"] == "date-time") {
50
+ data = Date.parse(data)
51
+ }
49
52
  data = (data + "").replace(",", ".")
50
53
  data = type === "number" ? parseFloat(data) : parseInt(data, 10)
51
54
 
@@ -75,7 +78,7 @@
75
78
  return memo
76
79
  }, []) :
77
80
  null
78
- } else {
81
+ } else if (data) {
79
82
  var reqArr = Array.isArray(schema.required) && schema.required
80
83
  Object.each(schema.properties, function(propSchema, prop) {
81
84
  if (data[prop] !== void 0) {