@litejs/ui 23.3.1 → 23.3.2

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/css/base.css CHANGED
@@ -231,13 +231,24 @@ button,
231
231
  float: right !important;
232
232
  }
233
233
 
234
+ .sm .sm-t-left,
235
+ .md .md-t-left,
236
+ .lg .md-t-left,
237
+ .lg .lg-t-left,
234
238
  .t-left {
235
239
  text-align: left;
236
240
  }
237
-
241
+ .sm .sm-t-center,
242
+ .md .md-t-center,
243
+ .lg .md-t-center,
244
+ .lg .lg-t-center,
238
245
  .t-center {
239
246
  text-align: center;
240
247
  }
248
+ .sm .sm-t-right,
249
+ .md .md-t-right,
250
+ .lg .md-t-right,
251
+ .lg .lg-t-right,
241
252
  .t-right {
242
253
  text-align: right;
243
254
  }
package/index.js CHANGED
@@ -506,6 +506,8 @@
506
506
  , templateRe = /([ \t]*)(%?)((?:("|')(?:\\\4|.)*?\4|[-\w:.#[\]]=?)*)[ \t]*([>^;@|\\\/]|!?=|)(([\])}]?).*?([[({]?))(?=\x1f|\n|$)+/g
507
507
  , renderRe = /[;\s]*(\w+)(?:(::?| )((?:(["'\/])(?:\\\3|.)*?\3|[^;])*))?/g
508
508
  , selectorRe = /([.#:[])([-\w]+)(?:\(((?:[^()]|\([^)]+\))+?)\)|([~^$*|]?)=(("|')(?:\\.|[^\\])*?\6|[-\w]+))?]?/g
509
+ , fnRe = /('|")(?:\\\1|.)*?\1|\/(?:\\?.)+?\/[gim]*|\b(?:n|data|b|s|B|r|false|in|new|null|this|true|typeof|void|function|var|if|else|return)\b|\.\w+|\w+:/g
510
+ , wordRe = /\b[a-z_$][\w$]*/ig
509
511
  , splitRe = /[,\s]+/
510
512
  , camelRe = /\-([a-z])/g
511
513
  , bindings = El.bindings = {
@@ -616,7 +618,8 @@
616
618
 
617
619
  // NOTE: IE-s cloneNode consolidates the two text nodes together as one
618
620
  // http://brooknovak.wordpress.com/2009/08/23/ies-clonenode-doesnt-actually-clone/
619
- el = (elCache[name] || (elCache[name] = document.createElement(name))).cloneNode(true)
621
+ el = (name = elCache[name] || (elCache[name] = document.createElement(name))).cloneNode(true)
622
+ el._s = name._s
620
623
 
621
624
  if (pres) {
622
625
  setAttr(el, pre)
@@ -723,7 +726,7 @@
723
726
  // Read-only checkboxes can be changed by the user
724
727
 
725
728
  for (opts = {}; (input = el.elements[i++]); ) if (!input.disabled && (key = input.name || input.id)) {
726
- value = valFn(input)
729
+ value = valFn(input, val != UNDEF ? val[key] : UNDEF)
727
730
  if (value !== UNDEF) {
728
731
  step = opts
729
732
  key.replace(/\[(.*?)\]/g, replacer)
@@ -734,7 +737,7 @@
734
737
  return opts
735
738
  }
736
739
 
737
- if (arguments.length > 1) {
740
+ if (val !== UNDEF) {
738
741
  if (opts) {
739
742
  value = (isArray(val) ? val : [ val ]).map(String)
740
743
  for (; (input = opts[i++]); ) {
@@ -795,8 +798,12 @@
795
798
 
796
799
  if (child.nodeType) {
797
800
  tmp = el.insertBefore ? el : el[el.length - 1]
798
- if ((i = getAttr(tmp, "data-child"))) {
799
- before = findCom(tmp, i) || tmp
801
+ if ((i = getAttr(child, "slot"))) {
802
+ child.removeAttribute("slot")
803
+ before = findCom(tmp, "%slot-" + i) || tmp
804
+ tmp = before.parentNode
805
+ } else if ((i = getAttr(tmp, "data-slot"))) {
806
+ before = findCom(tmp, "%slot-" + i) || tmp
800
807
  tmp = before.parentNode
801
808
  // TODO:2016-07-05:lauri:handle numeric befores
802
809
  }
@@ -1068,14 +1075,30 @@
1068
1075
  if (!node) return
1069
1076
  var bind, fn
1070
1077
  , scope = elScope(node, 0, _scope)
1071
- , i = 0
1072
1078
 
1073
1079
  if (node.nodeType != 1) {
1074
1080
  if (node.render) node.render(scope)
1075
1081
  return
1076
1082
  }
1077
1083
 
1078
- if ((bind = getAttr(node, BIND_ATTR))) {
1084
+ hydrate(node, BIND_ATTR, scope)
1085
+ for (bind = node.firstChild; bind; bind = fn) {
1086
+ fn = bind.nextSibling
1087
+ render(bind, scope)
1088
+ }
1089
+ hydrate(node, "data-out", scope)
1090
+
1091
+ /*** ie8 ***/
1092
+ if (ie678 && node.tagName === "SELECT") {
1093
+ node.parentNode.insertBefore(node, node)
1094
+ }
1095
+ /**/
1096
+ }
1097
+
1098
+ function hydrate(node, attr, scope) {
1099
+ var bind, fn
1100
+ , i = 0
1101
+ if ((bind = getAttr(node, attr))) {
1079
1102
  scope._m = bindMatch
1080
1103
  scope._t = bind
1081
1104
  // i18n(bind, lang).format(scope)
@@ -1097,7 +1120,13 @@
1097
1120
  }) + "r)"
1098
1121
 
1099
1122
  try {
1100
- if (Function("n,data,b,s,B,r", "with(data||{})return " + fn).call(node, node, scope, bindings, setAttr, BIND_ATTR)) {
1123
+ var vars = fn.replace(fnRe, "").match(wordRe) || []
1124
+ for (i = vars.length; i--; ) if (vars.indexOf(vars[i]) !== i) vars.splice(i, 1)
1125
+ if (Function(
1126
+ "n,data,b,s,B,r",
1127
+ (vars[0] ? "var " + vars.join("='',") + "='';" : "") +
1128
+ "with(data||{})return " + fn
1129
+ ).call(node, node, scope, bindings, setAttr, attr)) {
1101
1130
  return
1102
1131
  }
1103
1132
  } catch (e) {
@@ -1110,21 +1139,17 @@
1110
1139
  }
1111
1140
  }
1112
1141
  }
1113
-
1114
- for (bind = node.firstChild; bind; bind = fn) {
1115
- fn = bind.nextSibling
1116
- render(bind, scope)
1117
- }
1118
- /*** ie8 ***/
1119
- if (ie678 && node.tagName === "SELECT") {
1120
- node.parentNode.insertBefore(node, node)
1121
- }
1122
- /**/
1123
1142
  }
1124
1143
 
1144
+
1125
1145
  El.empty = empty
1126
1146
  El.kill = kill
1127
1147
  El.render = render
1148
+ El.replace = replace
1149
+ function replace(oldEl, newEl) {
1150
+ var parent = oldEl && oldEl.parentNode
1151
+ if (parent && newEl) return parent.replaceChild(oldEl, newEl)
1152
+ }
1128
1153
 
1129
1154
  for (var key in El) wrap(key)
1130
1155
 
@@ -1145,10 +1170,8 @@
1145
1170
 
1146
1171
  wrapProto.append = function(el) {
1147
1172
  var elWrap = this
1148
- if (elWrap._ca > -1) {
1149
- append(elWrap[elWrap._ca], el)
1150
- // } else if (elWrap._cb > -1) {
1151
- // elWrap.splice(elWrap._cb, 0, el)
1173
+ if (elWrap._s) {
1174
+ append(elWrap[elWrap._s[getAttr(el, "slot") || elWrap._s._] || 0], el)
1152
1175
  } else {
1153
1176
  elWrap.push(el)
1154
1177
  }
@@ -1157,8 +1180,7 @@
1157
1180
 
1158
1181
  wrapProto.cloneNode = function(deep) {
1159
1182
  deep = new ElWrap(this, deep)
1160
- deep._ca = this._ca
1161
- //deep._cb = this._cb
1183
+ deep._s = this._s
1162
1184
  return deep
1163
1185
  }
1164
1186
 
@@ -1210,8 +1232,8 @@
1210
1232
  text = text.replace(/(\w+):?/, "on:'$1',")
1211
1233
  } else if (op != ";" && op != "^") {
1212
1234
  text = (parent.tagName === "INPUT" ? "val" : "txt") + (
1213
- op === "=" ? ":" + text.replace(/\\|'/g, "\\$&") :
1214
- ":_('" + text.replace(/\\|'/g, "\\$&") + "',data)"
1235
+ op === "=" ? ":" + text.replace(/'/g, "\\'") :
1236
+ ":_('" + text.replace(/'/g, "\\'") + "',data)"
1215
1237
  )
1216
1238
  }
1217
1239
  appendBind(parent, text, ";", op)
@@ -1248,8 +1270,10 @@
1248
1270
  , el = childNodes[1] ? new ElWrap(childNodes) : childNodes[0]
1249
1271
 
1250
1272
  if (i > -1) {
1251
- if (childNodes[i].nodeType == 1) setAttr(childNodes[el._ca = i], "data-child", t.el._ck)
1252
- // else el._cb = i
1273
+ if (childNodes[i].nodeType == 1 && t.el._sk) {
1274
+ setAttr(childNodes[i], "data-slot", t.el._sk)
1275
+ }
1276
+ el._s = t.el._s
1253
1277
  }
1254
1278
 
1255
1279
  t.el.plugin = t.el = t.parent = null
@@ -1281,12 +1305,14 @@
1281
1305
  Object.assign(bindings, Function("return({" + this.txt + "})")())
1282
1306
  }
1283
1307
  }),
1284
- child: extend(plugin, {
1308
+ slot: extend(plugin, {
1285
1309
  done: function() {
1286
- var key = "@child-" + (++seq)
1310
+ var name = this.name || ++seq
1311
+ var key = "%slot-" + name
1287
1312
  , root = append(this.parent, document.createComment(key))
1288
1313
  for (; root.parentNode; root = root.parentNode);
1289
- root._ck = key
1314
+ ;(root._s || (root._s = {}))[name] = root.childNodes.length - 1
1315
+ if (!this.name) root._s._ = root._sk = name
1290
1316
  root._cp = root.childNodes.length - 1
1291
1317
  }
1292
1318
  }),
@@ -1352,6 +1378,7 @@
1352
1378
  }
1353
1379
  })
1354
1380
  }
1381
+ El.plugins.child = El.plugins.slot
1355
1382
 
1356
1383
  xhr.view = xhr.tpl = El.tpl = parseTemplate
1357
1384
  xhr.css = function(str) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@litejs/ui",
3
- "version": "23.3.1",
3
+ "version": "23.3.2",
4
4
  "description": "UI engine for LiteJS full-stack framework",
5
5
  "license": "MIT",
6
6
  "author": "Lauri Rooden <lauri@rooden.ee>",
@@ -25,7 +25,7 @@
25
25
  "test": "TZ='Europe/Tallinn' lj test test/index.js --brief --coverage && jshint --verbose *.js src/*.js binding/*.js polyfill/*.js"
26
26
  },
27
27
  "devDependencies": {
28
- "@litejs/cli": "23.3.0",
28
+ "@litejs/cli": "23.3.2",
29
29
  "jshint": "2.13.6"
30
30
  },
31
31
  "litejs": {
@@ -1 +0,0 @@
1
- El.tpl('%css .Segment7 { position: relative; height: 1em; width: .5em; margin-right: 8px; } .Seg-V, .Seg-H { position: absolute; top: 0; left: .105em; height: .098em; width: .28em; background-color: currentColor; } .Seg-V + .Seg-V { top: .392em; } .Seg-V + .Seg-V + .Seg-V { top: .784em; } .Seg:before, .Seg:after { position: absolute; content: ""; border: .049em solid transparent; } .Seg-V:before { left: -.098em; border-right-color: currentColor; } .Seg-V:after { right: -.098em; border-left-color: currentColor; } .Seg-H:before { top: -.098em; border-bottom-color: currentColor; } .Seg-H:after { bottom: -.098em; border-top-color: currentColor; } .Seg-H { top: .105em; left: 0; height: .28em; width: .098em; } .Seg-H + .Seg-H { left: .392em; } .Seg-H + .Seg-H + .Seg-H { top: .497em; } .Seg-H + .Seg-H + .Seg-H + .Seg-H { left: 0; } [data-value="0"]>[off~="0"], [data-value="1"]>[off~="1"], [data-value="2"]>[off~="2"], [data-value="3"]>[off~="3"], [data-value="4"]>[off~="4"], [data-value="5"]>[off~="5"], [data-value="6"]>[off~="6"], [data-value="7"]>[off~="7"], [data-value="8"]>[off~="8"], [data-value="9"]>[off~="9"], [data-value="a"]>[off~="a"], [data-value="b"]>[off~="b"], [data-value="c"]>[off~="c"], [data-value="d"]>[off~="d"], [data-value="e"]>[off~="e"], [data-value="f"]>[off~="f"] { color: rgba(0,0,0,0.07); }%el Segment7 .Segment7.left .Seg.Seg-V.Seg-A[off="1 4 b d"] .Seg.Seg-V.Seg-G[off="0 1 7 c"] .Seg.Seg-V.Seg-D[off="1 4 7 a f"] .Seg.Seg-H.Seg-F[off="1 2 3 7 d"] .Seg.Seg-H.Seg-B[off="5 6 b c e f"] .Seg.Seg-H.Seg-C[off="2 c e f"] .Seg.Seg-H.Seg-E[off="1 3 4 5 7 9"]')
package/el/confirm.tpl.js DELETED
@@ -1 +0,0 @@
1
- El.tpl('%css .Confirm { z-index: 9; } .Confirm-bg { backdrop-filter: blur(5px); background-color: rgba(0, 0, 0, .6); } .Confirm-content { position: absolute; left: 0; right: 0; margin: 0 auto; top: 4%; width: 600px; background-color: #fff; box-shadow: 0 2px 10px 2px rgba(255,255,255,.5); } .sm .Confirm-content { width: 94%; } .Confirm--blur { transform: scale(.85); transform-origin: 50% 100vh; }// reverse animation: x1, y1, x2, y2 -> (1 - x2), (1 - y2), (1 - x1), (1 - y1)// https://developer.mozilla.org/en-US/docs/Web/API/Notification// https://developers.google.com/web/fundamentals/push-notifications/display-a-notification// var n = new Notification(title, options);// {// "//": "Visual Options",// "body": "Did you make a $1,000,000 purchase at Dr. Evil...",// "icon": "images/ccard.png", // 192px or more is a safe bet// "image": "<URL String>", // width 1350px or more, ratio of 4:3 for desktop and Android will crop the image// "badge": "<URL String>", // 72px or more should be good// "vibrate": "<Array of Integers>",// "sound": "<URL String>",// "dir": "<String of \'auto\' | \'ltr\' | \'rtl\'>",// "//": "Behavioural Options",// "tag": "<String>", // group messages so that any old notifications that are currently displayed will be closed if they have the same tag as a new notification.// "data": "<Anything>",// "requireInteraction": "<boolean>", // for Chrome on desktop// "renotify": "<Boolean>",// "silent": "<Boolean>",// "//": "Both Visual & Behavioural Options",// "actions": "<Array of Strings>",// "//": "Information Option. No visual affect.",// "timestamp": "<Long>" // ms// }// Star Wars shamelessly taken from the awesome Peter Beverloo// https://tests.peter.sh/notification-generator/// "vibrate": [500,110,500,110,450,110,200,110,170,40,450,110,200,110,170,40,500]// "actions": [// { "action": "yes", "title": "Yes", "icon": "images/yes.png" },// { "action": "no", "title": "No", "icon": "images/no.png" }// ]%js View.on("confirm", function(title, opts, next) { View.blur() if (!next && typeof opts === "function") { next = opts opts = null } var sound, vibrate , code = "" , el = El("Confirm") , scope = El.scope(el, El.data) , kbMap = {} , body = document.body , blurEl = body.lastChild Object.assign(scope, opts) scope.title = title || "Confirm?" if (!scope.actions) scope.actions = [ { action: "close", title: "Close", key: "esc" } ] for (var a, i = 0; a = scope.actions[i++]; ) { if (typeof a == "string") a = scope.actions[i-1] = {title:a,action:a} if (a.key) kbMap[a.key] = resolve.bind(el, el, a.action) } El.cls(blurEl, "Confirm--blur") El.cls(el.lastChild, "Confirm--blur", 0, 1) El.append(body, el) El.render(el, scope) if (scope.code) { El.findAll(el, ".js-numpad").on("click", numpad) kbMap.backspace = kbMap.del = kbMap.num = numpad } El.addKb(kbMap, el) El.findAll(el, ".js-btn").on("click", resolve) View.one("navigation", resolve) if (scope.bgClose) El.on(el, "click", resolve) El.on(el, "wheel", Event.stop) El.on(el.lastChild, "click", Event.stop) if (scope.vibrate && navigator.vibrate) { vibrate = navigator.vibrate(scope.vibrate) } if (scope.sound && window.Audio) { sound = new Audio(scope.sound) sound.play() } function numpad(e, _num) { // Enter pressed on focused element if (_num == void 0 && e.clientX == 0) return var num = _num == void 0 ? e.target[El.T] : _num code += num if (num == "CLEAR" || num == "del" || num == "backspace") code = "" El.md(El.find(el, ".js-body"), code.replace(/./g, "•") || opts.body) if (typeof scope.code == "number" && code.length == scope.code && id && !sent) next(sent = code, id, resolve, reject) } function resolve(e, key) { if (el) { var action = key || El.attr(this, "data-action") , result = { code: code, input: El.val(El.find(el, ".js-input")), inputMd: El.val(El.find(el, ".js-inputMd")), select: El.val(El.find(el, ".js-select")) } El.kill(el, "transparent") El.cls(blurEl, "Confirm--blur", el = 0) if (action && next) { if (typeof next === "function") next(action, result) else if (typeof next[action] === "function") next[action](result) else if (next[action]) View.emit(next[action], result) } if (vibrate) navigator.vibrate(0) if (sound) sound.pause() } } scope.resolve = resolve View.emit("confirm:open", scope) })%el Confirm .Confirm.max.fix.anim .Confirm-bg.max.abs .Confirm-content.Confirm--blur.grid.p2.anim .col.ts3 ;txt:: _(title, map) .col.js-body ;md:: _(body, map) .row.js-numpad ;if: code ;each: num in [1,2,3,4,5,6,7,8,9,"CLEAR",0] .col.w4>.btn {num} .row ;if: input .col>input.field.js-input .row ;if: data.inputMd!=null .col textarea.field.js-inputMd @keyup [this.parentNode.nextSibling.nextSibling], "renderMd" ;val: inputMd .col.ts3 Preview .p4 ;md: inputMd .row ;if: select .col select.field.js-select ;list: select, [""] option ;val:: item.id ;txt:: _(item.name) .col .group ;each: action in actions .btn.js-btn ;txt:: _(action.title) ;class:: "w" + (12/actions.length) ;nop: this.focus() ;data: "action", action.action ;class:: "is-" + action.action, action.action')
package/el/form1.tpl.js DELETED
@@ -1 +0,0 @@
1
- El.tpl('%css ::-moz-focus-inner { border: 0; padding: 0; } .Form1-del.right { display: block; margin: -10px -10px 0 0; opacity: .2; } .Form1-del { font-size: 20px; font-weight: 700; border: 1px solid transparent; line-height: 16px; width: 20px; height: 20px; text-align: center; border-radius: 4px; } .Form1-del:hover { opacity: 1; border: 1px solid #aaa; background-image: linear-gradient(to bottom, #ddd, #888); } /** * 1. avoid ios styling the submit button */ .input { display: block; border-radius: 4px; border: 1px solid #aaa; } .field { width: 100%; } .btn, input, select, textarea { display: block; border-radius: 4px; border: 1px solid #aaa; font-size: 14px; font-weight: 400; line-height: 30px; height: 32px; padding: 0 8px; margin: 0; } input[type=checkbox] { height: auto; } input[type=time] { padding: 0 0 0 8px; } textarea { height: 64px; padding: 8px; margin: 0; line-height: 1.1; } select { padding-right: 0; } select[multiple] { height: auto; padding: 0; } input[type=radio], input[type=checkbox] { width: auto; display: inline; margin-top: -2px; } .btn, input[type=submit] { /* 1 */ -webkit-appearance: none; /* 1 */ position: relative; padding: 0px 14px; text-align: center; text-decoration: none; /* default look */ background-color: #ddd; color: #444; cursor: pointer; } option[disabled], .btn.disabled, .btn[disabled] { box-shadow: none; cursor: not-allowed; font-style: italic; opacity: .6; pointer-events: none; } .group { overflow: auto; } .group > .btn { border-radius: 0; float: left; } .group > .btn:first-child { border-top-left-radius: 4px; border-bottom-left-radius: 4px; } .group > .btn:last-child { border-top-right-radius: 4px; border-bottom-right-radius: 4px; } .btn--narrow { line-height: 1.6; margin: .7em 0; } .btn__spacer { height: 33px; } .md .input__label, .lg .input__label { padding-right: 8px; text-align: right; line-height: 28px; } .input__hint { text-align: right; color: #444; } input[type=checkbox]+.input__hint { display: inline-block; margin-left: 8px; } .btn:active, .btn:focus, input:active, input:focus, select:active, select:focus, textarea:active, textarea:focus { border-color: #257; outline: 0 none; box-shadow: 0 2px 5px rgba(0, 0, 0, .5) inset, 0 0 2px 2px #6ae; z-index: 1; } .btn:hover, .btn:focus { filter: brightness(1.3) saturate(1.2); text-decoration: none; } .btn:active, .btn.is-active { box-shadow: inset 0 0 8px rgba(0, 0, 0, .5); }%el form1-row label.row .col.md-w4.input__label = _(title||name) .col.md-w8 %child .input__hint = _(description) ;if: description%el form1-subheader .col = _(title)%el form1-fieldset fieldset.grid.b2 legend = _(schema.title || _link.title || "")%el form1 form1-row input.field%el form1-ro form1-row>span ;txt: value%el form1-hidden div>input.field[type=hidden]%el form1-boolean form1-row input.field[type=checkbox] ;value: value%el form1-boolean-ro form1-row>span = _(!!value)%el form1-password form1-row input.field[type=password]%el form1-new-password form1-row input.field[type=password][autocomplete=new-password]%el form1-text form1-row textarea.field%el form1-text-ro form1-ro%el form1-enum form1-row select.field ;each:val in data["enum"] option ;val:: val = _("" + val)%el form1-enum-ro form1-ro%el form1-list form1-row select.field ;list: api(resourceCollection.format(data.params, data)), required ? 0 : [""], value option ;val:: item.id ;txt:: _(item.name)%el form1-list-ro form1-row>span = _(item.name)%el form1-array .col .input.p13.cf .left = _(title||name) .input__hint = _(description) .js-items.cf a.btn.right ;if: !data.noAdd ;txt: _(data.name + ".Add") @click: data.add%el form1-array-item .input.p3.m2b.cf.js-del a.right.Form1-del.hand × ;if: !data.noAdd ;data:: "tooltip", _("Delete") @click: data.del b ;if: title ;txt: title .grid.b2.js-item')