@litejs/ui 25.1.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.
@@ -0,0 +1,56 @@
1
+ #!/usr/bin/env node
2
+ //-
3
+ //- Usage
4
+ //- lj-extract-lang [FILE..]
5
+ //-
6
+ //- Options
7
+ //- --pretty, -p Pretty print json output
8
+ //-
9
+ //- Examples
10
+ //- lj-extract-translations translations.json
11
+ //-
12
+
13
+ var fs = require("fs")
14
+ , path = require("path")
15
+ , opts = require("@litejs/cli/opts.js").opts({
16
+ pretty: false,
17
+ version: false
18
+ })
19
+ , extractLang = require("../extract-lang.js").extractLang
20
+ , package = require("../package.json")
21
+
22
+
23
+ if (opts._unknown[0]) {
24
+ console.error("\nError: Unknown option: " + opts._unknown)
25
+ usage(true)
26
+ process.exit(1)
27
+ } else if (opts._[0]) {
28
+ readJson(opts._[0])
29
+ } else {
30
+ usage()
31
+ }
32
+
33
+ function usage(err) {
34
+ if (!err && opts.version) console.log("%s v%s", package.name, package.version)
35
+ var helpFile = module.filename
36
+ console.log(fs.readFileSync(helpFile, "utf8").match(/^\/\/-.*/gm).join("\n").replace(/^.../gm, ""))
37
+ }
38
+
39
+ function readJson(file) {
40
+ var lang
41
+ , all = require(path.resolve(file))
42
+ , i = 0
43
+ , locales = Object.keys(all.locales)
44
+
45
+ console.log("Extract translations: " + locales)
46
+
47
+ for (; lang = locales[i++]; ) {
48
+ writeJson(lang + ".json", extractLang(all, lang))
49
+ }
50
+ }
51
+
52
+ function writeJson(file, data) {
53
+ fs.writeFileSync(path.resolve(file), JSON.stringify(data, null, opts.pretty ? 2 : null) + "\n", "utf8")
54
+ }
55
+
56
+
package/el/Slider.ui ADDED
@@ -0,0 +1,229 @@
1
+
2
+ %css
3
+ .Slider,
4
+ .Toggle {
5
+ background: none;
6
+ height: 32px;
7
+ position: relative;
8
+ touch-action: none;
9
+ width: 200px;
10
+ color: #000;
11
+ font-size: 14px;
12
+ line-height: 32px;
13
+ }
14
+ .Slider-fill,
15
+ .Slider:before,
16
+ .Toggle:before {
17
+ background: rgba(0, 0, 0, .5);
18
+ border-radius: 2px;
19
+ height: 4px;
20
+ position: absolute;
21
+ top: 14px;
22
+ transition: inherit;
23
+ }
24
+ .Slider:before,
25
+ .Toggle:before {
26
+ background: #ccc;
27
+ content: "";
28
+ display: block;
29
+ width: 100%;
30
+ }
31
+ .Slider-knob,
32
+ .Toggle-knob {
33
+ border-radius: 50%;
34
+ box-shadow: 0 0 0 0 rgb(0, 0, 0, .2), 0 1px 4px rgba(0, 0, 0, .2);
35
+ height: 20px;
36
+ position: relative; /* for IE6 overflow:visible bug */
37
+ transition: inherit;
38
+ width: 20px;
39
+ }
40
+ .Slider-knob {
41
+ float: right;
42
+ margin: -8px -10px 0 0;
43
+ outline: none;
44
+ background: #f5f5f5;
45
+ }
46
+ :hover > * > .Slider-knob,
47
+ :focus > * > .Slider-knob {
48
+ box-shadow: 0 0 0 8px rgb(0, 0, 0, .2), 0 1px 4px rgba(0, 0, 0, .3);
49
+ }
50
+ .Slider-knob.is-active {
51
+ box-shadow: 0 0 0 12px rgb(0, 0, 0, .2), 0 1px 5px 5px rgba(0, 0, 0, .3);
52
+ }
53
+ /* value bubble */
54
+ .Slider-knob:before,
55
+ .Slider-knob:after {
56
+ background: inherit;
57
+ border-radius: 16px;
58
+ content: "";
59
+ height: 32px;
60
+ left: -6px;
61
+ min-width: 32px;
62
+ opacity: 0;
63
+ pointer-events: none;
64
+ position: absolute;
65
+ top: 0px;
66
+ transform: rotate(45deg);
67
+ transition: inherit;
68
+ }
69
+ .Slider-knob:after {
70
+ content: attr(data-val);
71
+ left: 10px;
72
+ padding: 0 4px;
73
+ transform: translate(-50%, 0);
74
+ }
75
+ :focus > * > .Slider-knob:before,
76
+ :hover > * > .Slider-knob:before,
77
+ .Slider-knob.is-active:before {
78
+ border-radius: 50% 50% 0 50%;
79
+ box-shadow: 3px 3px 3px 1px rgba(0, 0, 0, .3);
80
+ opacity: 1;
81
+ top: -43px;
82
+ }
83
+ :focus > * > .Slider-knob:after,
84
+ :hover > * > .Slider-knob:after,
85
+ .Slider-knob.is-active:after {
86
+ box-shadow: -4px -3px 3px -2px rgba(0, 0, 0, .15), 4px -3px 3px -2px rgba(0, 0, 0, .15);
87
+ opacity: 1;
88
+ top: -43px;
89
+ }
90
+ input:checked + .Toggle-knob {
91
+ background-color: #00a651;
92
+ left: 16px;
93
+ }
94
+ .Slider.color .Slider-fill {
95
+ background: red;
96
+ }
97
+ .Slider.color .Slider-fill+.Slider-fill {
98
+ background: green;
99
+ }
100
+ .Slider.color .Slider-fill+.Slider-fill+.Slider-fill {
101
+ background: blue;
102
+ }
103
+ .Slider.no-first > .Slider-fill:last-child {
104
+ background: #ccc;
105
+ }
106
+
107
+ %js
108
+ var elOn = El.on
109
+ , elOff = El.off
110
+ , elCls = El.cls
111
+ , elGet = El.get
112
+ El.$b.SliderInit = function(el, range) {
113
+ range = (range || elGet(el, "range") || "").split(/[^+\-\d.]/) // min:max:step:margin
114
+ var knobLen, offset, px, drag, min, max, minPx, maxPx, value
115
+ //, vert = El.hasClass(el, "is-vertical")
116
+ , vert = false
117
+ , attr = vert ? "offsetHeight" : "offsetWidth"
118
+ , fill = el.firstChild
119
+ , knob = fill.lastChild
120
+ , emit = El.rate(El.emit.bind(el, el, "change"), 500)
121
+ elOn(window, "blur", stop)
122
+ setTimeout(el.val = set, 10, value||0)
123
+ function load() {
124
+ min = +(range[0] || 0)
125
+ max = +(range[1] || 100)
126
+ knobLen = knob[attr]>>1
127
+ minPx = 0
128
+ maxPx = el[attr] - knobLen - knobLen
129
+ px = maxPx / (max - min)
130
+ }
131
+ elOn(el, "pointerdown", function(e) {
132
+ drag = true
133
+ load()
134
+ var tmp = el.getBoundingClientRect()
135
+ offset = (vert ? tmp.top + maxPx + El.scrollTop() + knobLen : tmp.left + El.scrollLeft()) + knobLen
136
+ tmp = offset - e.clientX + (value-min||0)*px
137
+ if (tmp < knobLen && tmp > -knobLen) offset -= tmp
138
+ if (el.childNodes.length > 1) {
139
+ var next
140
+ , x = maxPx
141
+ , diff = vert ? offset - e.pageY : e.pageX - offset
142
+ for (tmp = fill = el.firstChild; tmp; tmp = tmp.nextSibling) {
143
+ next = diff - tmp[attr] + knobLen
144
+ if (next < 0 ? -next <= x : next < x) {
145
+ fill = tmp
146
+ knob = tmp.firstChild
147
+ x = next < 0 ? -next : next
148
+ }
149
+ }
150
+ if (fill.previousSibling) {
151
+ maxPx = fill.previousSibling[attr] - knobLen
152
+ if (range[3]) maxPx -= px * range[3]
153
+ }
154
+ if (fill.nextSibling) {
155
+ minPx = fill.nextSibling[attr] - knobLen
156
+ if (range[3]) minPx += px * range[3]
157
+ }
158
+ }
159
+ move(e)
160
+ listen(elOn)
161
+ })
162
+ function move(e) {
163
+ var diff = vert ? offset - e.pageY : e.pageX - offset
164
+ diff = (diff > maxPx ? maxPx : (diff < minPx ? minPx : diff))
165
+ set((diff / px) + min, e, diff)
166
+ return El.stop(e)
167
+ }
168
+ function stop(e) {
169
+ if (drag) {
170
+ drag = false
171
+ listen(elOff)
172
+ set(value)
173
+ }
174
+ }
175
+ function listen(onOff) {
176
+ elCls(el, "anim", !drag)
177
+ elCls(knob, "is-active", drag)
178
+ onOff(document, "pointerup", stop)
179
+ onOff(document, "pointermove", move)
180
+ }
181
+ function set(val, e, pos) {
182
+ load()
183
+ val = El.step(val < min ? min : val > max ? max : val || 0, +(range[2] || 1))
184
+ if (value !== void 0 && (!drag || pos !== void 0)) {
185
+ El.css(fill, vert ? "height" : "width", ((pos || (val-min)*px)+knobLen) + "px", 0)
186
+ }
187
+ if (value !== val) {
188
+ el.value = value = val
189
+ if (drag && e) emit(e)
190
+ var format = elGet(el, "format")
191
+ El.set(knob, "data-val", format ? $d._(format, {val:val}) : val)
192
+ }
193
+ }
194
+ }
195
+
196
+ %el Slider
197
+ button.Slider.anim.reset ;SliderInit!
198
+ .Slider-fill
199
+ .Slider-knob[tabindex=0]
200
+
201
+ %el Slider2
202
+ button.Slider.anim.reset ;SliderInit!
203
+ .Slider-fill
204
+ .Slider-knob[tabindex=0]
205
+ .Slider-fill
206
+ .Slider-knob[tabindex=0]
207
+
208
+ %el Slider3
209
+ button.Slider.reset ;SliderInit!
210
+ .Slider-fill
211
+ .Slider-knob[tabindex=0]
212
+ .Slider-fill
213
+ .Slider-knob[tabindex=0]
214
+ .Slider-fill
215
+ .Slider-knob[tabindex=0]
216
+
217
+ %el Toggle
218
+ button.Toggle.reset ;SliderInit! "0:1"
219
+ ;css: "width","36px"
220
+ .Slider-fill.anim
221
+ .Slider-knob.anim[tabindex=0]
222
+
223
+ %el Togglea
224
+ label.Toggle.reset[tabindex=0]
225
+ input[type=checkbox].hide
226
+ ;readonly! row && !row.write
227
+ ;checked! model && (row && row.opts ? row.opts === model.get(row.path) : !!model.get(row.path))
228
+ .Toggle-knob.anim
229
+
@@ -0,0 +1,33 @@
1
+
2
+ !function(exports) {
3
+ exports.extractLang = extractLang
4
+
5
+ function extractLang(translations, lang) {
6
+ var missing = []
7
+ , out = extract(translations, "")
8
+ if (missing[0]) {
9
+ console.error("WARNING! Missing '%s' translations: %s [%s]", lang, missing.length, missing+"")
10
+ }
11
+ return out
12
+
13
+ function extract(map, path) {
14
+ var key
15
+ , out = {}
16
+ , translations = map.translations
17
+ if (!translations) return map[lang]
18
+ for (key in translations) {
19
+ out[key] = extract(translations[key], path + key + ".")
20
+ if (
21
+ out[key] === key ||
22
+ out[key] === void 0 && missing.push(path + key) ||
23
+ isObject(out[key]) && Object.keys(out[key]).length < 1
24
+ ) delete out[key]
25
+ }
26
+ return out
27
+ }
28
+ function isObject(obj) {
29
+ return obj && obj.constructor === Object
30
+ }
31
+ }
32
+ }(this) // jshint ignore:line
33
+
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@litejs/ui",
3
- "version": "25.1.0",
3
+ "version": "25.5.0",
4
4
  "description": "UI engine for LiteJS full-stack framework",
5
5
  "license": "MIT",
6
6
  "author": "Lauri Rooden <lauri@rooden.ee>",
@@ -15,15 +15,18 @@
15
15
  "main": "ui.js",
16
16
  "files": [
17
17
  "*.js",
18
+ "bin",
18
19
  "binding",
19
20
  "css",
20
21
  "el"
21
22
  ],
23
+ "bin": {
24
+ "lj-extract-lang": "./bin/extract-lang.js"
25
+ },
22
26
  "scripts": {
23
27
  "test": "lj t"
24
28
  },
25
29
  "devDependencies": {
26
- "@litejs/cli": "25.1.1",
27
- "@litejs/dom": "25.1.0"
30
+ "@litejs/cli": "25.5.0"
28
31
  }
29
32
  }
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, 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,7 +36,6 @@ 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
41
  , renderRe = /[;\s]*([-.\w$]+)(?:(!?)[ :]*((?:(["'\/])(?:\\.|[^\\])*?\4|[^;])*))?/g
@@ -54,8 +55,8 @@ console.log("LiteJS is in debug mode, but it's fine for production")
54
55
  var target = selector ? closest(e.target, selector) : el
55
56
  if (target) emit.apply(target, [elScope(el).$ui, val, e, target].concat(data))
56
57
  } :
57
- selector ? function(e, a1, a2) {
58
- 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)
59
60
  } :
60
61
  val
61
62
  })
@@ -161,7 +162,7 @@ console.log("LiteJS is in debug mode, but it's fine for production")
161
162
  }
162
163
 
163
164
  function asEmitter(obj) {
164
- obj.on = on
165
+ obj.on = wrap(on)
165
166
  obj.off = off
166
167
  obj.one = one
167
168
  obj.emit = wrap(emit)
@@ -173,14 +174,14 @@ console.log("LiteJS is in debug mode, but it's fine for production")
173
174
  }
174
175
  }
175
176
 
176
- function on(type, fn, scope, _origin) {
177
- var emitter = this === window ? emptyArr : this
178
- , events = emitter._e || (emitter._e = create(NUL))
179
- if (type && fn) {
177
+ function on(emitter, type, fn, scope, _origin) {
178
+ if (emitter && type && fn) {
179
+ if (emitter === window) emitter = emptyArr
180
180
  emit(emitter, "newListener", type, fn, scope, _origin)
181
+ var events = emitter._e || (emitter._e = create(NUL))
181
182
  ;(events[type] || (events[type] = [])).unshift(scope, _origin, fn)
182
183
  }
183
- return this
184
+ return emitter
184
185
  }
185
186
 
186
187
  function off(type, fn, scope) {
@@ -206,8 +207,8 @@ console.log("LiteJS is in debug mode, but it's fine for production")
206
207
  off.call(emitter, type, fn, scope)
207
208
  off.call(emitter, type, remove, scope)
208
209
  }
209
- on.call(emitter, type, remove, scope)
210
- on.call(emitter, type, fn, scope)
210
+ on(emitter, type, remove, scope)
211
+ on(emitter, type, fn, scope)
211
212
  return this
212
213
  }
213
214
 
@@ -224,18 +225,24 @@ console.log("LiteJS is in debug mode, but it's fine for production")
224
225
  return _e / 3
225
226
  }
226
227
 
228
+ try {
229
+ addEventListener("t", NUL, { get capture() { canCapture = 1 }})
230
+ } catch(e){}
231
+
227
232
  function addEvent(el, ev, fn, opts) {
228
233
  var fn2 = fixFn[ev] && fixFn[ev](el, fn, ev) || fn
229
234
  , ev2 = fixEv[ev] || ev
230
235
 
231
236
  if (ev2 !== "" && "on" + ev2 in el) {
232
237
  // polyfilled addEventListener returns patched function
233
- // Since Chrome 56 touchstart/move have the { passive: true } by default.
234
- // preventDefault() won't work unless you set passive to false.
235
- 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
236
243
  }
237
244
 
238
- on.call(el, ev, fn2, el, fn)
245
+ on(el, ev, fn2, el, fn)
239
246
  }
240
247
 
241
248
  function rmEvent(el, ev, fn) {
@@ -284,7 +291,7 @@ console.log("LiteJS is in debug mode, but it's fine for production")
284
291
  return view
285
292
  }
286
293
  view = this
287
- if (!(view instanceof View)) return new View(route, el, parent)
294
+ if (view === THIS) return new View(route, el, parent)
288
295
  views[view.r = route] = view
289
296
  view.e = isStr(el) ? find(html, el) : el
290
297
  view.p = parent && View(parent)
@@ -343,7 +350,7 @@ console.log("LiteJS is in debug mode, but it's fine for production")
343
350
  },
344
351
  parse: (parser = viewParse),
345
352
  ping: function(view, fn) {
346
- View(view).on("ping", fn)
353
+ on(View(view), "ping", fn)
347
354
  },
348
355
  show: viewShow
349
356
  })
@@ -630,7 +637,7 @@ console.log("LiteJS is in debug mode, but it's fine for production")
630
637
  addPlugin("view", {
631
638
  c: 1,
632
639
  d: function(plugin) {
633
- var expr = getAttr(plugin.e, BIND_ATTR)
640
+ var expr = getAttr(plugin.e, "_b")
634
641
  , view = View(plugin.n, usePluginContent(plugin), plugin.x)
635
642
  if (expr) {
636
643
  viewEval(replace(expr, renderRe, function(_, name, op, args) {
@@ -741,7 +748,7 @@ console.log("LiteJS is in debug mode, but it's fine for production")
741
748
  values.push(a)
742
749
  return "#"
743
750
  })
744
- 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
745
752
  },
746
753
  pick: function(val, word) {
747
754
  for (var t = translations["?"] || {}, arr = replace((t[word] || word), /([^;=,]+?)\?/g, "$1=$1;").split(/[;=,]/), i = 1|arr.length; i > 0; ) {
@@ -915,13 +922,18 @@ console.log("LiteJS is in debug mode, but it's fine for production")
915
922
  }
916
923
  return str
917
924
  }
918
- function iGet(obj, path, fallback) {
925
+ function iGet(obj, path, fallback, tmp) {
919
926
  return isStr(path) ? (
920
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
+ ) :
921
933
  (path = path.split("."))[1] && isObj(obj = obj[path[0]]) && isStr(obj[path[1]]) ? obj[path[1]] :
922
934
  fallback
923
935
  ) :
924
- 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) :
925
937
  fallback
926
938
  }
927
939
  /*/
@@ -1080,7 +1092,7 @@ console.log("LiteJS is in debug mode, but it's fine for production")
1080
1092
  subScope.$i = pos++
1081
1093
  subScope.$len = list.length
1082
1094
  subScope[name] = item
1083
- clone[BIND_ATTR] = el[BIND_ATTR]
1095
+ clone._b = el._b
1084
1096
  /*** debug ***/
1085
1097
  clone._li = up
1086
1098
  /**/
@@ -1096,7 +1108,7 @@ console.log("LiteJS is in debug mode, but it's fine for production")
1096
1108
  tag = elCache[tag] ? tag : fallback
1097
1109
  if (el._el !== tag) {
1098
1110
  var child = El(tag)
1099
- , tmp = child._elb = el._el ? el._elb : el[BIND_ATTR]
1111
+ , tmp = child._elb = el._el ? el._elb : el._b
1100
1112
  if (tmp) appendBind(child, tmp, ";", "^")
1101
1113
  child.$s = el.$s
1102
1114
  child._el = tag
@@ -1115,7 +1127,7 @@ console.log("LiteJS is in debug mode, but it's fine for production")
1115
1127
  }
1116
1128
  },
1117
1129
  is: function(el, val, opts, prefix) {
1118
- if (!prefix) prefix = "is-"
1130
+ if (!isStr(prefix)) prefix = "is-"
1119
1131
  var match = elScope(el)._.ext.pick(val, opts)
1120
1132
  cls(el, el[prefix + opts], 0)
1121
1133
  cls(el, el[prefix + opts] = match && prefix + match)
@@ -1229,8 +1241,8 @@ console.log("LiteJS is in debug mode, but it's fine for production")
1229
1241
  }
1230
1242
 
1231
1243
  function appendBind(el, val, sep, q) {
1232
- var current = getAttr(el, BIND_ATTR)
1233
- setAttr(el, BIND_ATTR, (current ? (
1244
+ var current = getAttr(el, "_b")
1245
+ setAttr(el, "_b", (current ? (
1234
1246
  q === "^" ?
1235
1247
  val + sep + current :
1236
1248
  current + sep + val
@@ -1405,7 +1417,7 @@ console.log("LiteJS is in debug mode, but it's fine for production")
1405
1417
  }
1406
1418
  /**/
1407
1419
 
1408
- if (hydrate(node, BIND_ATTR, scope)) return
1420
+ if (hydrate(node, "_b", scope)) return
1409
1421
  for (el = node.firstChild; el; el = next) {
1410
1422
  next = el.nextSibling
1411
1423
  render(el, scope)
@@ -1503,8 +1515,8 @@ console.log("LiteJS is in debug mode, but it's fine for production")
1503
1515
  , touches = []
1504
1516
  , touchEv = {}
1505
1517
 
1506
- // tap, swipe + left/right/up/down
1507
- each("pan pinch rotate tap", function(name) {
1518
+ // swipe + left/right/up/down
1519
+ each("hold pan pinch rotate tap", function(name) {
1508
1520
  fixEv[name] = fixEv[name + START] = fixEv[name + END] = ""
1509
1521
  fixFn[name] = touchInit
1510
1522
  })
@@ -1524,7 +1536,7 @@ console.log("LiteJS is in debug mode, but it's fine for production")
1524
1536
  emit(touchEl, touchMode ? touchMode + END : "tap", e2, touchEv, touchEl)
1525
1537
  touchMode = UNDEF
1526
1538
  }
1527
- if (len < 0) {
1539
+ if (len < 1) {
1528
1540
  touchEl = UNDEF
1529
1541
  }
1530
1542
  if (len === 1) {
@@ -1535,7 +1547,7 @@ console.log("LiteJS is in debug mode, but it's fine for production")
1535
1547
  touchPos("left", "offsetWidth")
1536
1548
  touchPos("top", "offsetHeight")
1537
1549
  if (e.button === 2 || matches(touchEl, "INPUT,TEXTAREA,SELECT,.no-drag")) return
1538
- touchTick = setTimeout(moveOne, 1500, e, 1)
1550
+ touchTick = setTimeout(moveOne, LiteJS.holdDelay || 800, e, 1)
1539
1551
  }
1540
1552
  moveOne(e || touches[0])
1541
1553
  }
@@ -1642,16 +1654,13 @@ console.log("LiteJS is in debug mode, but it's fine for production")
1642
1654
  function acceptMany(fn, prepareVal) {
1643
1655
  return function f(el, name, val, selector, delay, data) {
1644
1656
  if (el && name) {
1645
- var i = arguments.length
1646
- if (i > 3 && i < 6) {
1647
- if (isArr(selector)) {
1648
- data = selector
1649
- delay = selector = UNDEF
1650
- } else if (isNum(selector)) {
1651
- data = delay
1652
- delay = selector
1653
- selector = UNDEF
1654
- }
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
1655
1664
  }
1656
1665
  if (delay > 0) {
1657
1666
  setTimeout(f, delay, el, name, val, selector, 0, data)
@@ -1659,16 +1668,15 @@ console.log("LiteJS is in debug mode, but it's fine for production")
1659
1668
  }
1660
1669
  if (isObj(name)) {
1661
1670
  for (delay in name) if (hasOwn(name, delay)) {
1662
- f(el, delay, name[delay], selector, 0, data)
1671
+ f(el, delay, name[delay], val, 0, data)
1663
1672
  }
1664
1673
  return
1665
1674
  }
1666
1675
  if (prepareVal) val = prepareVal(el, val, selector, data)
1667
1676
  selector = !prepareVal && selector ? findAll(el, selector) : isArr(el) ? el : [ el ]
1668
- var arr = ("" + name).split(splitRe), len = arr.length
1669
1677
  for (delay = 0; (el = selector[delay++]); ) {
1670
- for (i = 0; i < len; ) {
1671
- 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)
1672
1680
  }
1673
1681
  }
1674
1682
  }
package/el/Slider.tpl DELETED
@@ -1,269 +0,0 @@
1
-
2
- %css
3
- .Slider {
4
- width: 200px;
5
- background: transparent;
6
- touch-action: none;
7
- }
8
- .Slider.is-vertical {
9
- width: auto;
10
- height: 200px;
11
- }
12
- .is-vertical > .Slider-track {
13
- margin: 0 14px;
14
- width: 4px;
15
- height: 100%;
16
- }
17
- .is-vertical > * > .Slider-fill {
18
- top: auto;
19
- bottom: 0;
20
- width: 4px;
21
- }
22
- .is-vertical > * > * > .Slider-knob {
23
- margin: -10px -8px 0 0;
24
- }
25
- .Slider-track {
26
- position: relative;
27
- margin: 14px 0;
28
- }
29
- .Slider-track,
30
- .Slider-fill {
31
- height: 4px;
32
- border-radius: 2px;
33
- overflow: visible;
34
- background: #999;
35
- }
36
- .Slider-fill {
37
- background: rgba(0,0,0,.5);
38
- }
39
- .Slider-knob,
40
- .Toggle-knob {
41
- position: relative; /* for IE6 overflow:visible bug */
42
- width: 20px;
43
- height: 20px;
44
- border-radius: 50%;
45
- box-shadow:
46
- 0 0 0 0 rgb(0, 0, 0, .2),
47
- 0 1px 4px rgba(0, 0, 0, .2);
48
- }
49
- .Slider-knob {
50
- float: right;
51
- margin: -8px -10px 0 0;
52
- outline: none;
53
- background: #f5f5f5;
54
- background-color: rgb(245, 245, 245);
55
- }
56
- :hover > * > * > .Slider-knob,
57
- :focus > * > * > .Slider-knob,
58
- :focus > .Toggle-knob,
59
- :hover > .Toggle-knob {
60
- box-shadow:
61
- 0 0 0 8px rgb(0, 0, 0, .2),
62
- 0 1px 4px rgba(0, 0, 0, .3);
63
- }
64
- .Slider-knob.is-active {
65
- box-shadow:
66
- 0 0 0 12px rgb(0, 0, 0, .2),
67
- 0 1px 5px 5px rgba(0, 0, 0, .3);
68
- }
69
- /* value bubble */
70
- .Slider-knob.is-active:before,
71
- .Slider-knob.is-active:after {
72
- position: absolute;
73
- width: 32px;
74
- height: 32px;
75
- left: -6px;
76
- display: block;
77
- top: -44px;
78
- animation: .1s linear 0s 1 forwards Slider-active;
79
- }
80
- .Slider-knob.is-active:before {
81
- content: "";
82
- border-radius: 50% 50% 50% 0;
83
- transform: rotate(-45deg);
84
- background: inherit;
85
- box-shadow:
86
- 0 1px 4px rgba(0, 0, 0, .2);
87
- }
88
- .Slider-knob.is-active:after {
89
- content: attr(data-val);
90
- color: #000;
91
- font-size: 14px;
92
- line-height: 32px;
93
- text-align: center;
94
- }
95
- .Toggle {
96
- position: relative;
97
- display: block;
98
- width: 36px;
99
- height: 22px;
100
- -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
101
- }
102
- .Toggle:before {
103
- display: block;
104
- content: "";
105
- background: #bdbdbd;
106
- position: absolute;
107
- width: 36px;
108
- height: 14px;
109
- top: 4px;
110
- border-radius: 7px;
111
- -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
112
- }
113
- .Toggle-knob {
114
- background-color: #666;
115
- top: 1px;
116
- left: 0px;
117
- }
118
- input:checked + .Toggle-knob {
119
- background-color: #00a651;
120
- left: 16px;
121
- }
122
- @keyframes Slider-active {
123
- 0% {
124
- top: 0px;
125
- opacity: 0;
126
- }
127
- to {
128
- top: -44px;
129
- opacity: 1;
130
- }
131
- }
132
- /*
133
- .Slider.color .Slider-fill {
134
- background: red;
135
- }
136
- .Slider.color .Slider-fill+.Slider-fill {
137
- background: green;
138
- }
139
- .Slider.color .Slider-fill+.Slider-fill+.Slider-fill {
140
- background: blue;
141
- }
142
- .Slider.no-first > .Slider-track > .Slider-fill:last-child {
143
- background: #666;
144
- }
145
- */
146
-
147
- %js
148
- var on = El.on
149
- , off = El.off
150
- El.$b.SliderInit = function(el) {
151
- var attr, range, knobLen, offset, px, drag, min, max, step, minPx, maxPx, value
152
- , vert = El.hasClass(el, "is-vertical")
153
- , track = el.firstChild
154
- , fill = track.firstChild
155
- , knob = fill.lastChild
156
- , emit = El.rate(El.emit.bind(el, el, "change"), 500)
157
- on(window, "blur", stop)
158
- on(el, "pointerdown", start)
159
- el.val = set
160
- setTimeout(function() { set(value||0) }, 10)
161
- function load() {
162
- attr = vert ? "offsetHeight" : "offsetWidth"
163
- range = (El.get(el, "range") || "").split(/[^+\-\d.]/) // min:max:step:margin
164
- min = +(range[0] || 0)
165
- max = +(range[1] || 100)
166
- step = +(range[2] || 1)
167
- knobLen = knob[attr]>>1
168
- minPx = 0
169
- maxPx = track[attr] - knobLen - knobLen
170
- px = maxPx / (max - min)
171
- }
172
- function start(e) {
173
- drag = true
174
- load()
175
- var tmp = el.getBoundingClientRect()
176
- offset = (vert ? tmp.top + maxPx + El.scrollTop() + knobLen : tmp.left + El.scrollLeft()) + knobLen
177
- tmp = offset - e.clientX + (value-min||0)*px
178
- if (tmp < knobLen && tmp > -knobLen) offset -= tmp
179
- if (track.childNodes.length > 1) {
180
- fill = track.firstChild
181
- var next
182
- , x = maxPx
183
- , tmp = fill
184
- , diff = vert ? offset - e.pageY : e.pageX - offset
185
- for (; tmp; tmp = tmp.nextSibling) {
186
- next = diff - tmp[attr] + knobLen
187
- if (next < 0 ? -next <= x : next < x) {
188
- fill = tmp
189
- knob = fill.firstChild
190
- x = next < 0 ? -next : next
191
- }
192
- }
193
- if (fill.previousSibling) {
194
- maxPx = fill.previousSibling[attr] - knobLen
195
- if (range[3]) maxPx -= px * range[3]
196
- }
197
- if (fill.nextSibling) {
198
- minPx = fill.nextSibling[attr] - knobLen
199
- if (range[3]) minPx += px * range[3]
200
- }
201
- }
202
- move(e)
203
- listen(on)
204
- }
205
- function move(e) {
206
- var diff = vert ? offset - e.pageY : e.pageX - offset
207
- diff = (diff > maxPx ? maxPx : (diff < minPx ? minPx : diff))
208
- set((diff / px) + min, e, diff)
209
- return El.stop(e)
210
- }
211
- function stop(e) {
212
- if (drag) {
213
- drag = false
214
- listen(off)
215
- set(value)
216
- }
217
- }
218
- function listen(on) {
219
- El.cls(fill, "anim", !drag)
220
- El.cls(knob, "is-active", drag)
221
- on(document, "pointerup", stop)
222
- on(document, "pointermove", move)
223
- }
224
- function set(val, e, pos) {
225
- load()
226
- val = El.step(val < min ? min : val > max ? max : val || 0, step)
227
- if (value !== void 0 && (!drag || pos !== void 0)) {
228
- El.css(fill, vert ? "height" : "width", ((pos || (val-min)*px)+knobLen) + "px", 0)
229
- }
230
- if (value !== val) {
231
- el.value = value = val
232
- if (drag && e) emit(e)
233
- var format = El.get(el, "format")
234
- El.set(knob, "data-val", format ? _(format, {val:val}) : val)
235
- }
236
- }
237
- }
238
-
239
- %el Slider
240
- button.Slider.reset ;SliderInit!
241
- .Slider-track
242
- .Slider-fill.abs.anim
243
- .Slider-knob.anim[tabindex=0]
244
-
245
- /%el Slider2
246
- / button.Slider.reset ;SliderInit!
247
- / .Slider-track
248
- / .Slider-fill.abs.anim
249
- / .Slider-knob.anim[tabindex=0]
250
- / .Slider-fill.abs.anim
251
- / .Slider-knob.anim[tabindex=0]
252
- /
253
- /%el Slider3
254
- / button.Slider.reset ;SliderInit!
255
- / .Slider-track
256
- / .Slider-fill.abs.anim
257
- / .Slider-knob.anim[tabindex=0]
258
- / .Slider-fill.abs.anim
259
- / .Slider-knob.anim[tabindex=0]
260
- / .Slider-fill.abs.anim
261
- / .Slider-knob.anim[tabindex=0]
262
-
263
- %el Toggle
264
- label.Toggle.reset[tabindex=0]
265
- input[type=checkbox].hide
266
- ;readonly! row && !row.write
267
- ;checked! model && (row && row.opts ? row.opts === model.get(row.path) : !!model.get(row.path))
268
- .Toggle-knob.anim
269
-