@litejs/ui 24.11.0 → 25.5.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.
package/shim.js CHANGED
@@ -17,11 +17,12 @@
17
17
  /* c8 ignore start */
18
18
  !function(window, Date, Function, Infinity, P) {
19
19
 
20
- // Array#flat() - Chrome69, Edge79, Firefox62, Safari12
21
- // window.PointerEvent - Chrome55, Edge12, Firefox59, Safari13, IE11
22
- // navigator.sendBeacon - Chrome39, Edge14, Firefox31, Safari11.1
23
- // Object.fromEntries - Chrome73, Edge79, Firefox63, Safari12.1, Opera60, Node.js12.0.0
24
- // queueMicrotask - Chrome71, Edge79, Firefox69, Safari12.1
20
+ // Array#flat() - Chrome69, Firefox62, Safari12
21
+ // window.PointerEvent - Chrome55, Firefox59, Safari13, IE11
22
+ // navigator.sendBeacon - Chrome39, Firefox31, Safari11.1
23
+ // Object.fromEntries - Chrome73, Firefox63, Safari12.1, Opera60, Node.js12.0.0
24
+ // queueMicrotask - Chrome71, Firefox69, Safari12.1
25
+ // "".at(), [].at() - Chrome92, Firefox90, Safari15.4
25
26
 
26
27
  var UNDEF, isArray, oKeys
27
28
  , O = window
@@ -35,7 +36,7 @@
35
36
  , IS_NODE = !window.document
36
37
  , document = patch("document", {body:{},documentElement:{}})
37
38
  , location = patch("location", {href:""})
38
- , navigator = patch("navigator")
39
+ , navigator = patch("navigator", {})
39
40
  /*/
40
41
  , document = window.document
41
42
  , IS_NODE = false
@@ -384,8 +385,11 @@
384
385
  patch("flatMap", "return X.apply(t,A).flat()", 0, O.map)
385
386
  //patch("entries", "a=this;b=-1;return{next:function(){c=a.length<=++b;return{done:c,value:c?void 0:a[b]}}}")
386
387
 
388
+ a = "b=t.length;a=a<0?b+a|0:a|0;return a>=b||a<0?X:t"
389
+ patch("at", a + "[a]")
387
390
 
388
391
  O = String[P]
392
+ patch("at", a + ".charAt(a)")
389
393
  patch("endsWith", "return(a+='')===t.slice(-a.length)")
390
394
  patch("startsWith", "return t.lastIndexOf(a,0)===0")
391
395
  patch("trim", "return t.replace(/^\\s+|\\s+$/g,'')")
@@ -522,7 +526,6 @@
522
526
  return !force && O[key] || (O[patched.push(key_), key] = (
523
527
  isStr(src) ?
524
528
  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) :
525
- src === UNDEF ? {} :
526
529
  src
527
530
  ))
528
531
  }
package/ui.js CHANGED
@@ -1,7 +1,7 @@
1
1
 
2
2
  /* litejs.com/MIT-LICENSE.txt */
3
3
 
4
- /* global escape, navigator, xhr */
4
+ /* global escape, navigator, xhr, addEventListener */
5
5
 
6
6
  /*** debug ***/
7
7
  console.log("LiteJS is in debug mode, but it's fine for production")
@@ -11,8 +11,10 @@ console.log("LiteJS is in debug mode, but it's fine for production")
11
11
  window.El = El
12
12
  asEmitter(window.LiteJS = LiteJS)
13
13
 
14
- var UNDEF, lastExp, parser, pushBase, styleNode
14
+ var UNDEF, parser, pushBase, styleNode, canCapture
15
15
  , NUL = null
16
+ // THIS will be undefined in strict mode and window in sloppy mode
17
+ , THIS = this
16
18
  , html = document.documentElement
17
19
  , body = document.body
18
20
  , splitRe = /[,\s]+/
@@ -34,13 +36,10 @@ console.log("LiteJS is in debug mode, but it's fine for production")
34
36
  // http://webreflection.blogspot.com/2009/01/32-bytes-to-know-if-your-browser-is-ie.html
35
37
  , ie678 = !+"\v1" // jshint ignore:line
36
38
 
37
- , BIND_ATTR = "data-bind"
38
39
  , elSeq = 0
39
40
  , elCache = {}
40
- , formatRe = /{((?:("|')(?:\\.|[^\\])*?\2|.)+?)}/g
41
- , renderRe = /[;\s]*([-.\w$]+)(?:([ :!])((?:(["'\/])(?:\\.|[^\\])*?\4|[^;])*))?/g
41
+ , renderRe = /[;\s]*([-.\w$]+)(?:(!?)[ :]*((?:(["'\/])(?:\\.|[^\\])*?\4|[^;])*))?/g
42
42
  , selectorRe = /([.#:[])([-\w]+)(?:([~^$*|]?)=(("|')(?:\\.|[^\\])*?\5|[-\w]+))?]?/g
43
- , templateRe = /([ \t]*)(%?)((?:("|')(?:\\.|[^\\])*?\4|[-\w:.#[\]~^$*|]=?)*) ?([\/>+=@^;]|)(([\])}]?).*?([[({]?))(?=\x1f|\n|$)+/g
44
43
  , fnCache = {}
45
44
  , fnRe = /('|")(?:\\.|[^\\])*?\1|\/(?:\\.|[^\\])+?\/[gim]*|\$el\b|\$[aos]\b|\b(?:false|in|if|new|null|this|true|typeof|void|function|var|else|return)\b|\.\w+|\w+:/g
46
45
  , wordRe = /[a-z_$][\w$]*/ig
@@ -56,8 +55,8 @@ console.log("LiteJS is in debug mode, but it's fine for production")
56
55
  var target = selector ? closest(e.target, selector) : el
57
56
  if (target) emit.apply(target, [elScope(el).$ui, val, e, target].concat(data))
58
57
  } :
59
- selector ? function(e, a1, a2) {
60
- if (matches(e.target, selector)) val(e, a1, a2)
58
+ selector ? function(e, touchEv, touchEl) {
59
+ if (matches(touchEl = e.target, selector)) val(e, touchEv, touchEl, data)
61
60
  } :
62
61
  val
63
62
  })
@@ -68,10 +67,8 @@ console.log("LiteJS is in debug mode, but it's fine for production")
68
67
  set: acceptMany(setAttr),
69
68
  txt: elTxt,
70
69
  val: elVal,
71
- view: function(el, url) {
72
- setAttr(el, "href", (pushBase || "#") + expand(url || ""))
73
- }
74
70
  }
71
+ , bindOnce = []
75
72
  , globalScope = {
76
73
  El: El,
77
74
  $b: bindings
@@ -152,7 +149,7 @@ console.log("LiteJS is in debug mode, but it's fine for production")
152
149
  el.setAttributeNS("http://www.w3.org/1999/xlink", "xlink:href", href)
153
150
  }
154
151
  if (window.SVGElement) {
155
- each("animate animateMotion animateTransform circle clipPath defs desc ellipse feBlend feColorMatrix feComponentTransfer feComposite feConvolveMatrix feDiffuseLighting feDisplacementMap feDistantLight feDropShadow feFlood feFuncA feFuncB feFuncG feFuncR feGaussianBlur feImage feMerge feMergeNode feMorphology feOffset fePointLight feSpecularLighting feSpotLight feTile feTurbulence filter foreignObject g image line linearGradient marker mask metadata mpath path pattern polygon polyline radialGradient rect script set stop svg switch symbol text textPath tspan use view", function(name) {
152
+ each("animate animateMotion animateTransform circle clipPath defs ellipse feBlend feColorMatrix feComponentTransfer feComposite feConvolveMatrix feDiffuseLighting feDisplacementMap feDistantLight feDropShadow feFlood feFuncA feFuncB feFuncG feFuncR feGaussianBlur feImage feMerge feMergeNode feMorphology feOffset fePointLight feSpecularLighting feSpotLight feTile feTurbulence g image line linearGradient marker mask mpath path pattern polygon polyline radialGradient rect set stop svg text textPath tspan use", function(name) {
156
153
  elCache[name] = document.createElementNS("http://www.w3.org/2000/svg", name)
157
154
  })
158
155
  // a style title
@@ -165,7 +162,7 @@ console.log("LiteJS is in debug mode, but it's fine for production")
165
162
  }
166
163
 
167
164
  function asEmitter(obj) {
168
- obj.on = on
165
+ obj.on = wrap(on)
169
166
  obj.off = off
170
167
  obj.one = one
171
168
  obj.emit = wrap(emit)
@@ -177,14 +174,14 @@ console.log("LiteJS is in debug mode, but it's fine for production")
177
174
  }
178
175
  }
179
176
 
180
- function on(type, fn, scope, _origin) {
181
- var emitter = this === window ? emptyArr : this
182
- , events = emitter._e || (emitter._e = create(NUL))
183
- if (type && fn) {
177
+ function on(emitter, type, fn, scope, _origin) {
178
+ if (emitter && type && fn) {
179
+ if (emitter === window) emitter = emptyArr
184
180
  emit(emitter, "newListener", type, fn, scope, _origin)
181
+ var events = emitter._e || (emitter._e = create(NUL))
185
182
  ;(events[type] || (events[type] = [])).unshift(scope, _origin, fn)
186
183
  }
187
- return this
184
+ return emitter
188
185
  }
189
186
 
190
187
  function off(type, fn, scope) {
@@ -205,12 +202,13 @@ console.log("LiteJS is in debug mode, but it's fine for production")
205
202
 
206
203
  function one(type, fn, scope) {
207
204
  var emitter = this === window ? emptyArr : this
205
+
208
206
  function remove() {
209
207
  off.call(emitter, type, fn, scope)
210
208
  off.call(emitter, type, remove, scope)
211
209
  }
212
- on.call(emitter, type, remove, scope)
213
- on.call(emitter, type, fn, scope)
210
+ on(emitter, type, remove, scope)
211
+ on(emitter, type, fn, scope)
214
212
  return this
215
213
  }
216
214
 
@@ -227,18 +225,24 @@ console.log("LiteJS is in debug mode, but it's fine for production")
227
225
  return _e / 3
228
226
  }
229
227
 
228
+ try {
229
+ addEventListener("t", NUL, { get capture() { canCapture = 1 }})
230
+ } catch(e){}
231
+
230
232
  function addEvent(el, ev, fn, opts) {
231
233
  var fn2 = fixFn[ev] && fixFn[ev](el, fn, ev) || fn
232
234
  , ev2 = fixEv[ev] || ev
233
235
 
234
236
  if (ev2 !== "" && "on" + ev2 in el) {
235
237
  // polyfilled addEventListener returns patched function
236
- // Since Chrome 56 touchstart/move have the { passive: true } by default.
237
- // preventDefault() won't work unless you set passive to false.
238
- fn2 = html.addEventListener.call(el, ev2, fn2, opts != UNDEF ? opts : false) || fn2
238
+ // useCapture defaults to false
239
+ // Chrome56 touchstart/move sets {passive:true} by default; use {passive:false} to enable preventDefault()
240
+ fn2 = html.addEventListener.call(
241
+ el, ev2, fn2, !canCapture && isObj(opts) ? !!opts.capture : opts || false
242
+ ) || fn2
239
243
  }
240
244
 
241
- on.call(el, ev, fn2, el, fn)
245
+ on(el, ev, fn2, el, fn)
242
246
  }
243
247
 
244
248
  function rmEvent(el, ev, fn) {
@@ -287,7 +291,7 @@ console.log("LiteJS is in debug mode, but it's fine for production")
287
291
  return view
288
292
  }
289
293
  view = this
290
- if (!(view instanceof View)) return new View(route, el, parent)
294
+ if (view === THIS) return new View(route, el, parent)
291
295
  views[view.r = route] = view
292
296
  view.e = isStr(el) ? find(html, el) : el
293
297
  view.p = parent && View(parent)
@@ -346,7 +350,7 @@ console.log("LiteJS is in debug mode, but it's fine for production")
346
350
  },
347
351
  parse: (parser = viewParse),
348
352
  ping: function(view, fn) {
349
- View(view).on("ping", fn)
353
+ on(View(view), "ping", fn)
350
354
  },
351
355
  show: viewShow
352
356
  })
@@ -374,7 +378,9 @@ console.log("LiteJS is in debug mode, but it's fine for production")
374
378
  render(view.o)
375
379
  viewEmit(parent, "openChild", view, close)
376
380
  viewEmit(view, "open", params)
381
+ /*** kb ***/
377
382
  addKb(view.kb)
383
+ /**/
378
384
  params._c = UNDEF
379
385
  }
380
386
  if ((params._d = params._v = view.c)) {
@@ -392,7 +398,9 @@ console.log("LiteJS is in debug mode, but it's fine for production")
392
398
  viewClose(view.c)
393
399
  elKill(view.o)
394
400
  view.o = UNDEF
401
+ /*** kb ***/
395
402
  rmKb(view.kb)
403
+ /**/
396
404
  viewEmit(view, "close")
397
405
  }
398
406
  }
@@ -432,6 +440,7 @@ console.log("LiteJS is in debug mode, but it's fine for production")
432
440
  var parent = El("div")
433
441
  , stack = [-1]
434
442
  , parentStack = []
443
+ , templateRe = /([ \t]*)(%?)((?:("|')(?:\\.|[^\\])*?\4|[-\w:.#[\]~^$*|]=?)*) ?([\/>=@^;]|)(([\])}]?).*?([[({]?))(?=\x1f|$)/gm
435
444
 
436
445
  function work(all, indent, plugin, sel, q, op, text, mapEnd, mapStart, offset) {
437
446
  if (offset && all === indent) return
@@ -466,8 +475,8 @@ console.log("LiteJS is in debug mode, but it's fine for production")
466
475
  append(parent, parent = El(sel))
467
476
  }
468
477
  if (text && op != "/") {
469
- if (op === ">" || op === "+") {
470
- replace(indent + (op === "+" ? text : " " + text), templateRe, work)
478
+ if (op === ">") {
479
+ replace(indent + " " + text, templateRe, work)
471
480
  } else if (op === "=") {
472
481
  append(parent, text) // + "\n")
473
482
  } else {
@@ -539,7 +548,7 @@ console.log("LiteJS is in debug mode, but it's fine for production")
539
548
  var params = $d.params = { _t: Date.now() }
540
549
  , view = viewGet(url, params)
541
550
  if (!view.o || lastUrl !== url) {
542
- $d.url = lastExp = lastUrl = url
551
+ $d.url = lastUrl = expand(url)
543
552
  viewPing(view, params)
544
553
  }
545
554
  }
@@ -628,7 +637,7 @@ console.log("LiteJS is in debug mode, but it's fine for production")
628
637
  addPlugin("view", {
629
638
  c: 1,
630
639
  d: function(plugin) {
631
- var expr = getAttr(plugin.e, BIND_ATTR)
640
+ var expr = getAttr(plugin.e, "_b")
632
641
  , view = View(plugin.n, usePluginContent(plugin), plugin.x)
633
642
  if (expr) {
634
643
  viewEval(replace(expr, renderRe, function(_, name, op, args) {
@@ -739,7 +748,7 @@ console.log("LiteJS is in debug mode, but it's fine for production")
739
748
  values.push(a)
740
749
  return "#"
741
750
  })
742
- return str != key && t[key] ? replace(t[key], /#/g, bind(values.shift, values)) : str
751
+ return str != key ? replace(iGet(t, key, str), /#/g, bind(values.shift, values)) : str
743
752
  },
744
753
  pick: function(val, word) {
745
754
  for (var t = translations["?"] || {}, arr = replace((t[word] || word), /([^;=,]+?)\?/g, "$1=$1;").split(/[;=,]/), i = 1|arr.length; i > 0; ) {
@@ -896,17 +905,35 @@ console.log("LiteJS is in debug mode, but it's fine for production")
896
905
  }
897
906
  })
898
907
  function format(str, data, getter) {
899
- return replace(str, formatRe, function(all, path) {
900
- return getter(data, path, "")
901
- })
908
+ for (var char, inQuote, inExpr, depth = 0, pos = 0, len = str.length; pos < len; ) {
909
+ char = str.charAt(pos++)
910
+ if (char == "'" || char == "\"") { // '"
911
+ inQuote = (!inExpr || char === inQuote) ? "" : char
912
+ } else if (inQuote) {
913
+ if (char == "\\") pos++
914
+ } else if (char == "{" && depth++ < 1) {
915
+ inExpr = pos
916
+ } else if (char == "}" && inExpr && --depth < 1) {
917
+ char = getter(data, str.slice(inExpr, pos - 1), "")
918
+ str = str.slice(0, inExpr - 1) + char + str.slice(pos)
919
+ pos = inExpr + char.length - 1
920
+ len = str.length
921
+ }
922
+ }
923
+ return str
902
924
  }
903
- function iGet(obj, path, fallback) {
925
+ function iGet(obj, path, fallback, tmp) {
904
926
  return isStr(path) ? (
905
927
  isStr(obj[path]) ? obj[path] :
928
+ isStr(obj[tmp = path.toLowerCase()]) ? (
929
+ path.slice(1) === tmp.slice(1) ? obj[tmp].charAt(0).toUpperCase() + obj[tmp].slice(1) :
930
+ path === tmp.toUpperCase() ? obj[tmp].toUpperCase() :
931
+ obj[tmp]
932
+ ) :
906
933
  (path = path.split("."))[1] && isObj(obj = obj[path[0]]) && isStr(obj[path[1]]) ? obj[path[1]] :
907
934
  fallback
908
935
  ) :
909
- isArr(path) ? iGet(obj, path[0]) || iGet(obj, path[1]) || iGet(obj, path[2], fallback) :
936
+ isArr(path) ? iGet(obj, path[0], tmp) || iGet(obj, path[1], tmp) || iGet(obj, path[2], fallback) :
910
937
  fallback
911
938
  }
912
939
  /*/
@@ -1065,7 +1092,7 @@ console.log("LiteJS is in debug mode, but it's fine for production")
1065
1092
  subScope.$i = pos++
1066
1093
  subScope.$len = list.length
1067
1094
  subScope[name] = item
1068
- clone[BIND_ATTR] = el[BIND_ATTR]
1095
+ clone._b = el._b
1069
1096
  /*** debug ***/
1070
1097
  clone._li = up
1071
1098
  /**/
@@ -1081,7 +1108,7 @@ console.log("LiteJS is in debug mode, but it's fine for production")
1081
1108
  tag = elCache[tag] ? tag : fallback
1082
1109
  if (el._el !== tag) {
1083
1110
  var child = El(tag)
1084
- , tmp = child._elb = el._el ? el._elb : el[BIND_ATTR]
1111
+ , tmp = child._elb = el._el ? el._elb : el._b
1085
1112
  if (tmp) appendBind(child, tmp, ";", "^")
1086
1113
  child.$s = el.$s
1087
1114
  child._el = tag
@@ -1093,29 +1120,35 @@ console.log("LiteJS is in debug mode, but it's fine for production")
1093
1120
  },
1094
1121
  "if": function(el, enabled) {
1095
1122
  if (enabled) {
1096
- elReplace(el._if, el)
1123
+ elReplace(el._r, el)
1097
1124
  } else {
1098
- elReplace(el, el._if || (el._if = Comm("if", bind(render, el, el, this))))
1125
+ elReplace(el, el._r || (el._r = Comm("if", bind(render, el, el, this))))
1099
1126
  return true
1100
1127
  }
1101
1128
  },
1102
1129
  is: function(el, val, opts, prefix) {
1103
- if (!prefix) prefix = "is-"
1130
+ if (!isStr(prefix)) prefix = "is-"
1104
1131
  var match = elScope(el)._.ext.pick(val, opts)
1105
1132
  cls(el, el[prefix + opts], 0)
1106
1133
  cls(el, el[prefix + opts] = match && prefix + match)
1107
1134
  },
1135
+ name: function(el, name) {
1136
+ setAttr(el, "name", expand(name, 1))
1137
+ },
1108
1138
  ref: function(el, name) {
1109
1139
  this[name] = el
1110
1140
  },
1111
1141
  $s: function(el) {
1112
- var scope = elScope(el, el)
1142
+ var scope = this
1113
1143
  each(slice.call(arguments, 1), function(args) {
1114
1144
  each(args, function(arg, i) {
1115
1145
  if (isStr(i)) scope[i] = arg
1116
1146
  else scope[arg] = setAttr(el, arg, "")
1117
1147
  })
1118
1148
  })
1149
+ },
1150
+ view: function(el, url) {
1151
+ setAttr(el, "href", (pushBase || "#") + expand(url || ""))
1119
1152
  }
1120
1153
  }),
1121
1154
  $d: globalScope,
@@ -1128,8 +1161,6 @@ console.log("LiteJS is in debug mode, but it's fine for production")
1128
1161
  hasClass: hasClass,
1129
1162
  matches: matches,
1130
1163
  nearest: nearest,
1131
- next: bind(walk, El, "nextSibling"),
1132
- prev: bind(walk, El, "previousSibling"),
1133
1164
  rate: rate,
1134
1165
  replace: elReplace,
1135
1166
  scope: elScope,
@@ -1210,8 +1241,8 @@ console.log("LiteJS is in debug mode, but it's fine for production")
1210
1241
  }
1211
1242
 
1212
1243
  function appendBind(el, val, sep, q) {
1213
- var current = getAttr(el, BIND_ATTR)
1214
- setAttr(el, BIND_ATTR, (current ? (
1244
+ var current = getAttr(el, "_b")
1245
+ setAttr(el, "_b", (current ? (
1215
1246
  q === "^" ?
1216
1247
  val + sep + current :
1217
1248
  current + sep + val
@@ -1277,6 +1308,7 @@ console.log("LiteJS is in debug mode, but it's fine for production")
1277
1308
  elRm(el)
1278
1309
  if (el.nodeType < 2) {
1279
1310
  el.$s = UNDEF
1311
+ elKill(el._r) // Replacement element like comment from if binding
1280
1312
  elEmpty(el)
1281
1313
  if (el.valObject !== UNDEF) {
1282
1314
  el.valObject = UNDEF
@@ -1385,7 +1417,7 @@ console.log("LiteJS is in debug mode, but it's fine for production")
1385
1417
  }
1386
1418
  /**/
1387
1419
 
1388
- if (hydrate(node, BIND_ATTR, scope)) return
1420
+ if (hydrate(node, "_b", scope)) return
1389
1421
  for (el = node.firstChild; el; el = next) {
1390
1422
  next = el.nextSibling
1391
1423
  render(el, scope)
@@ -1398,20 +1430,16 @@ console.log("LiteJS is in debug mode, but it's fine for production")
1398
1430
  , expr = node[attr] || (node[attr] = setAttr(node, attr, "") || true)
1399
1431
  if (expr !== true) try {
1400
1432
  fn = fnCache[expr] || (fnCache[expr] = makeFn(expr))
1401
- return fn(node, scope, attr, fn.o)
1433
+ return fn(node, scope, attr, bindOnce)
1402
1434
  } catch (e) {
1403
1435
  throw e + "\n" + attr + ": " + expr
1404
1436
  }
1405
1437
  }
1406
- function makeFn(fn, raw) {
1407
- var i = 0
1408
- , bindOnce = []
1438
+ function makeFn(fn, raw, i) {
1409
1439
  fn = raw || "$s&&(" + replace(fn, renderRe, function(match, name, op, args) {
1410
1440
  return (
1411
- (op === "!" && (bindOnce[i] = match)) ?
1412
- "($el[$a]=$el[$a].replace($o[" + (i++)+ "],''),0)||" :
1413
- ""
1414
- ) + "$b['" + (bindings[name] ? name + "'].call($s,$el" : "set']($el,'" + name + "'") + (args ? "," + replace(args, /^\s*(\w+) in /,"'$1',") : "") + ")||"
1441
+ op ? "($el[$a]=$el[$a].replace($o[" + (i = bindOnce.indexOf(match), i < 0 ? bindOnce.push(match) - 1 : i)+ "],''),0)||" : ""
1442
+ ) + "$b['" + (bindings[name] ? name + "'].call($s" + (name == "$s" ? "=El.scope($el,$el)": "") + ",$el" : "set']($el,'" + name + "'") + (args ? "," + args : "") + ")||"
1415
1443
  }) + "$r)"
1416
1444
  var vars = replace(fn, fnRe, "").match(wordRe) || []
1417
1445
  for (i = vars.length; i--; ) {
@@ -1419,7 +1447,6 @@ console.log("LiteJS is in debug mode, but it's fine for production")
1419
1447
  else vars[i] += "=$s." + vars[i]
1420
1448
  }
1421
1449
  fn = Function("$el,$s,$a,$o,$r", (vars[0] ? "var " + vars : "") + ";return " + fn)
1422
- fn.o = bindOnce
1423
1450
  return fn
1424
1451
  }
1425
1452
 
@@ -1488,8 +1515,8 @@ console.log("LiteJS is in debug mode, but it's fine for production")
1488
1515
  , touches = []
1489
1516
  , touchEv = {}
1490
1517
 
1491
- // tap, swipe + left/right/up/down
1492
- each("pan pinch rotate tap", function(name) {
1518
+ // swipe + left/right/up/down
1519
+ each("hold pan pinch rotate tap", function(name) {
1493
1520
  fixEv[name] = fixEv[name + START] = fixEv[name + END] = ""
1494
1521
  fixFn[name] = touchInit
1495
1522
  })
@@ -1509,7 +1536,7 @@ console.log("LiteJS is in debug mode, but it's fine for production")
1509
1536
  emit(touchEl, touchMode ? touchMode + END : "tap", e2, touchEv, touchEl)
1510
1537
  touchMode = UNDEF
1511
1538
  }
1512
- if (len < 0) {
1539
+ if (len < 1) {
1513
1540
  touchEl = UNDEF
1514
1541
  }
1515
1542
  if (len === 1) {
@@ -1520,7 +1547,7 @@ console.log("LiteJS is in debug mode, but it's fine for production")
1520
1547
  touchPos("left", "offsetWidth")
1521
1548
  touchPos("top", "offsetHeight")
1522
1549
  if (e.button === 2 || matches(touchEl, "INPUT,TEXTAREA,SELECT,.no-drag")) return
1523
- touchTick = setTimeout(moveOne, 1500, e, 1)
1550
+ touchTick = setTimeout(moveOne, LiteJS.holdDelay || 800, e, 1)
1524
1551
  }
1525
1552
  moveOne(e || touches[0])
1526
1553
  }
@@ -1554,8 +1581,9 @@ console.log("LiteJS is in debug mode, but it's fine for production")
1554
1581
  function touchWheel(e) {
1555
1582
  // IE10 enabled pinch-to-zoom gestures from multi-touch trackpad’s as mousewheel event with ctrlKey.
1556
1583
  // Chrome M35 and Firefox 55 followed up.
1584
+ // alt+wheel may be OS level zoom, use shiftKey as alternative
1557
1585
  if (!touches[0]) {
1558
- var ev = e.ctrlKey ? "pinch" : e.altKey ? "rotate" : UNDEF
1586
+ var ev = e.ctrlKey ? "pinch" : e.altKey || e.shiftKey ? "rotate" : UNDEF
1559
1587
  if (ev && emit(e.currentTarget || e.target, ev, e, e.deltaY/20, 0)) {
1560
1588
  return eventStop(e)
1561
1589
  }
@@ -1623,23 +1651,16 @@ console.log("LiteJS is in debug mode, but it's fine for production")
1623
1651
  function nearest(el, sel) {
1624
1652
  return el ? find(el, sel) || nearest(el.parentNode, sel) : NUL
1625
1653
  }
1626
- function walk(attr, el, sel) {
1627
- for (; el && !matches(el = el[attr], sel); );
1628
- return el
1629
- }
1630
1654
  function acceptMany(fn, prepareVal) {
1631
1655
  return function f(el, name, val, selector, delay, data) {
1632
1656
  if (el && name) {
1633
- var i = arguments.length
1634
- if (i > 3 && i < 6) {
1635
- if (isArr(selector)) {
1636
- data = selector
1637
- delay = selector = UNDEF
1638
- } else if (isNum(selector)) {
1639
- data = delay
1640
- delay = selector
1641
- selector = UNDEF
1642
- }
1657
+ if (isNum(selector)) {
1658
+ data = delay
1659
+ delay = selector
1660
+ selector = UNDEF
1661
+ } else if (isArr(selector) || isObj(selector)) {
1662
+ data = selector
1663
+ delay = selector = UNDEF
1643
1664
  }
1644
1665
  if (delay > 0) {
1645
1666
  setTimeout(f, delay, el, name, val, selector, 0, data)
@@ -1647,16 +1668,15 @@ console.log("LiteJS is in debug mode, but it's fine for production")
1647
1668
  }
1648
1669
  if (isObj(name)) {
1649
1670
  for (delay in name) if (hasOwn(name, delay)) {
1650
- f(el, delay, name[delay], selector, 0, data)
1671
+ f(el, delay, name[delay], val, 0, data)
1651
1672
  }
1652
1673
  return
1653
1674
  }
1654
1675
  if (prepareVal) val = prepareVal(el, val, selector, data)
1655
1676
  selector = !prepareVal && selector ? findAll(el, selector) : isArr(el) ? el : [ el ]
1656
- var arr = ("" + name).split(splitRe), len = arr.length
1657
1677
  for (delay = 0; (el = selector[delay++]); ) {
1658
- for (i = 0; i < len; ) {
1659
- if (arr[i]) fn(el, arr[i++], isArr(val) ? val[i - 1] : val)
1678
+ for (var arr = ("" + name).split(splitRe), i = 0, len = arr.length; i < len; ) {
1679
+ if (arr[i]) fn(el, arr[i++], isArr(val) ? val[i - 1] : val, data)
1660
1680
  }
1661
1681
  }
1662
1682
  }
@@ -1672,9 +1692,7 @@ console.log("LiteJS is in debug mode, but it's fine for production")
1672
1692
  function blur() {
1673
1693
  // IE8 can throw on accessing document.activeElement.
1674
1694
  try {
1675
- var el = document.activeElement
1676
- , tag = el.tagName
1677
- if (tag === "A" || tag === "BUTTON") el.blur()
1695
+ document.activeElement.blur()
1678
1696
  } catch(e) {}
1679
1697
  }
1680
1698
  function camelFn(_, a) {
@@ -1687,13 +1705,14 @@ console.log("LiteJS is in debug mode, but it's fine for production")
1687
1705
  else for (key in arr) if (hasOwn(arr, key)) fn.call(scope, arr[key], key, arr)
1688
1706
  }
1689
1707
  }
1690
- function expand(str) {
1708
+ function expand(str, ns) {
1691
1709
  var first = str.charAt(0)
1692
1710
  , rest = str.slice(1)
1711
+ , lastExp = expand[ns]
1693
1712
  return (
1694
1713
  first === "+" ? lastExp + rest :
1695
1714
  first === "%" ? ((first = lastExp.lastIndexOf(rest.charAt(0))), (first > 0 ? lastExp.slice(0, first) : lastExp)) + rest :
1696
- (lastExp = str)
1715
+ (expand[ns] = str)
1697
1716
  )
1698
1717
  }
1699
1718
  function injectCss(cssText) {