@plotdb/form 0.1.2 → 0.2.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/index.js CHANGED
@@ -1,60 +1,170 @@
1
1
  // Generated by LiveScript 1.6.0
2
2
  (function(){
3
- var form, ref$, wordLen, countOps;
3
+ var form, ref$, wordLen, countOps, slice$ = [].slice;
4
4
  form = {};
5
+ form.value = {
6
+ toString: function(v){
7
+ var list2str, parts;
8
+ list2str = function(list){
9
+ if (list[0] && list[0].key != null && list[0].value != null) {
10
+ return list.map(function(it){
11
+ return form.value.toString(it.value);
12
+ }).join(' / ');
13
+ } else {
14
+ return list.map(function(it){
15
+ return form.value.toString(it);
16
+ }).join(' / ');
17
+ }
18
+ };
19
+ if (typeof v === 'string') {
20
+ return v;
21
+ } else if (v == null) {
22
+ return '';
23
+ } else if (Array.isArray(v)) {
24
+ return list2str(v);
25
+ } else if (v.filename) {
26
+ return v.filename;
27
+ } else if (v.key != null && v.value != null) {
28
+ return form.value.toString(v.value);
29
+ } else if (v.list && v.other) {
30
+ parts = (v.list || []).map(function(it){
31
+ return form.value.toString(it);
32
+ });
33
+ if (v.other.enabled && v.other.text) {
34
+ parts = parts.concat([v.other.text]);
35
+ }
36
+ return parts.join(' / ');
37
+ } else if (v.list && Array.isArray(v.list)) {
38
+ return list2str(v.list);
39
+ } else if (v.v != null) {
40
+ return form.value.toString(v.v);
41
+ } else {
42
+ return JSON.stringify(v);
43
+ }
44
+ }
45
+ };
46
+ form.utils = {
47
+ lexCompare: function(a, b){
48
+ var i$, to$, i;
49
+ for (i$ = 0, to$ = Math.max(a.length, b.length); i$ < to$; ++i$) {
50
+ i = i$;
51
+ if (a[i] == null && b[i] != null) {
52
+ return -1;
53
+ }
54
+ if (a[i] != null && b[i] == null) {
55
+ return 1;
56
+ }
57
+ if (a[i] == null && b[i] == null) {
58
+ return 0;
59
+ }
60
+ if (a[i] !== b[i]) {
61
+ return a[i] - b[i];
62
+ }
63
+ }
64
+ return 0;
65
+ },
66
+ mergeExports: function(records){
67
+ var uidMap, headers, k, v, rows;
68
+ uidMap = {};
69
+ records.map(function(cols){
70
+ return cols.map(function(col){
71
+ if (!uidMap[col.uid]) {
72
+ return uidMap[col.uid] = {
73
+ uid: col.uid,
74
+ header: col.header,
75
+ sortKey: col.sortKey
76
+ };
77
+ }
78
+ });
79
+ });
80
+ headers = (function(){
81
+ var ref$, results$ = [];
82
+ for (k in ref$ = uidMap) {
83
+ v = ref$[k];
84
+ results$.push({
85
+ k: k,
86
+ v: v
87
+ });
88
+ }
89
+ return results$;
90
+ }()).sort(function(a, b){
91
+ return form.utils.lexCompare(a.v.sortKey, b.v.sortKey);
92
+ });
93
+ rows = records.map(function(cols){
94
+ var valMap;
95
+ valMap = {};
96
+ cols.map(function(it){
97
+ return valMap[it.uid] = it.value;
98
+ });
99
+ return headers.map(function(it){
100
+ return valMap[it.k] || '';
101
+ });
102
+ });
103
+ return {
104
+ headers: headers.map(function(it){
105
+ return it.v.header;
106
+ }),
107
+ rows: rows
108
+ };
109
+ }
110
+ };
5
111
  form.condctrl = function(opt){
6
- var ref$;
112
+ var ref$, this$ = this;
7
113
  opt == null && (opt = {});
8
114
  ref$ = this._ || (this._ = {});
9
115
  ref$.hash = {};
10
116
  ref$.enabled = {};
11
117
  ref$.manager = opt.manager;
12
118
  ref$.list = opt.conditions || [];
119
+ ref$.autorun = false;
13
120
  ref$.applyBaseRule = opt.baseRule || function(){};
121
+ this._.manager.on('change', function(){
122
+ if (this$._.autorun) {
123
+ return this$.run();
124
+ }
125
+ });
14
126
  return this;
15
127
  };
16
128
  form.condctrl.prototype = (ref$ = Object.create(Object.prototype), ref$.isEnabled = function(it){
17
129
  return this._.enabled[it];
18
130
  }, ref$.get = function(it){
19
131
  return this._.hash[it];
20
- }, ref$.fields = function(){
21
- return this._.manager._ws.w;
22
- }, ref$.subcond = function(arg$){
23
- var path, active, config, itf, ms;
24
- path = arg$.path, active = arg$.active, config = arg$.config;
25
- if (!((itf = this._.manager.widget(path)) && !itf.disabled() && (ms = itf.manager({
26
- depth: 1
27
- }) || []).length)) {
28
- return;
29
- }
30
- return ms.map(function(m){
31
- var cond;
32
- cond = m.condition();
33
- cond.apply(import$({
34
- active: active
35
- }, config));
36
- return cond.run();
37
- });
38
132
  }, ref$.reset = function(opt){
39
- var fields, i$, to$, i, cond, results$ = [];
133
+ var fields, ref$, i$, to$, i, cond, results$ = [];
40
134
  opt == null && (opt = {});
135
+ this._.autorun = opt.autorun != null && !opt.autorun ? false : true;
41
136
  this._.list = opt.conditions || this._.list || [];
42
- fields = this.fields();
137
+ fields = this._.manager.widgets();
138
+ ref$ = this._ || (this._ = {});
139
+ ref$.hash = {};
140
+ ref$.enabled = {};
43
141
  for (i$ = 0, to$ = this._.list.length; i$ < to$; ++i$) {
44
142
  i = i$;
45
143
  cond = this._.list[i];
46
- cond.id = cond.id || (i + 1) + "";
144
+ cond.id = cond.id || "_" + (i + 1);
47
145
  this._.hash[cond.id] = cond;
48
146
  if (!Array.isArray(cond.config)) {
49
147
  cond.config = [cond.config];
50
148
  }
51
- results$.push(cond.config.map(fn$));
149
+ cond.config = cond.config.map(fn$);
150
+ results$.push(cond.config.forEach(fn1$));
52
151
  }
53
152
  return results$;
54
- function fn$(cfg){
153
+ function fn$(it){
154
+ var ref$;
155
+ return ref$ = import$({}, JSON.parse(JSON.stringify(it))), ref$.src = cond.src, ref$.func = cond.func, ref$;
156
+ }
157
+ function fn1$(cfg){
55
158
  var k, v;
56
- cfg.src = cond.src;
57
- cfg.func = cond.func;
159
+ if (!cfg.path && cfg.targets) {
160
+ cfg.path = cfg.targets;
161
+ }
162
+ if (!cfg.value && cfg.values) {
163
+ cfg.value = cfg.values;
164
+ }
165
+ if (!cfg.tag && cfg.tags) {
166
+ cfg.tag = cfg.tags;
167
+ }
58
168
  return cfg.path = Array.from(new Set((cfg.prefix
59
169
  ? cfg.prefix
60
170
  : []).concat(cfg.path || [], (function(){
@@ -81,21 +191,40 @@
81
191
  return it.k;
82
192
  }))));
83
193
  }
194
+ }, ref$.subcond = function(arg$){
195
+ var path, active, config, itf, ms;
196
+ path = arg$.path, active = arg$.active, config = arg$.config;
197
+ if (!((itf = this._.manager.widget(path)) && !itf.disabled() && (ms = itf.manager({
198
+ depth: 1
199
+ }) || []).length)) {
200
+ return;
201
+ }
202
+ return ms.forEach(function(m){
203
+ var cond;
204
+ cond = m.condition();
205
+ cond.apply(import$({
206
+ active: active
207
+ }, config));
208
+ return cond.run();
209
+ });
84
210
  }, ref$.apply = function(opt){
85
211
  var path, active, enabled, isRequired, readonly, widget, curMeta, newMeta;
86
212
  opt == null && (opt = {});
87
213
  path = opt.path, active = opt.active, enabled = opt.enabled, isRequired = opt.isRequired, readonly = opt.readonly;
88
- if (Array.isArray(path) && path[1]) {
89
- return this.subcond({
90
- path: path[0],
91
- active: active,
92
- config: {
93
- path: path.slice(1),
94
- enabled: enabled,
95
- isRequired: isRequired,
96
- readonly: readonly
97
- }
98
- });
214
+ if (Array.isArray(path)) {
215
+ if (path[1]) {
216
+ return this.subcond({
217
+ path: path[0],
218
+ active: active,
219
+ config: {
220
+ path: path.slice(1),
221
+ enabled: enabled,
222
+ isRequired: isRequired,
223
+ readonly: readonly
224
+ }
225
+ });
226
+ }
227
+ path = path[0];
99
228
  }
100
229
  if (enabled != null) {
101
230
  this._.enabled[path] = !(!enabled !== !active && (enabled || active));
@@ -126,25 +255,25 @@
126
255
  });
127
256
  }
128
257
  }, ref$._run = function(cfg, precond){
129
- var src, values, path, isRequired, enabled, readonly, func, result, i$, len$, p, active, ref$, itf, content;
258
+ var src, values, paths, isRequired, enabled, readonly, func, result, i$, len$, path, active, ref$, itf, content;
130
259
  cfg == null && (cfg = {});
131
- src = cfg.src, values = cfg.values, path = cfg.path, isRequired = cfg.isRequired, enabled = cfg.enabled, readonly = cfg.readonly, func = cfg.func;
260
+ src = cfg.src, values = cfg.value, paths = cfg.path, isRequired = cfg.isRequired, enabled = cfg.enabled, readonly = cfg.readonly, func = cfg.func;
132
261
  if (func) {
133
262
  result = true;
134
- for (i$ = 0, len$ = path.length; i$ < len$; ++i$) {
135
- p = path[i$];
136
- active = !!func.apply(this, [(ref$ = import$({}, cfg), ref$.path = p, ref$)]) && !(precond != null && !precond);
263
+ for (i$ = 0, len$ = paths.length; i$ < len$; ++i$) {
264
+ path = paths[i$];
265
+ active = !!func.apply(this, [(ref$ = import$({}, cfg), ref$.path = path, ref$)]) && !(precond != null && !precond);
137
266
  result = result && active;
138
- if (Array.isArray(p) && p[1]) {
267
+ if (Array.isArray(path) && path[1]) {
139
268
  this.subcond({
140
- path: p[0],
141
- config: (ref$ = import$({}, cfg), ref$.path = p.slice(1), ref$),
269
+ path: path[0],
270
+ config: (ref$ = import$({}, cfg), ref$.path = path.slice(1), ref$),
142
271
  active: active
143
272
  });
144
273
  continue;
145
274
  }
146
275
  this.apply({
147
- path: p[0],
276
+ path: path,
148
277
  enabled: enabled,
149
278
  active: active,
150
279
  isRequired: isRequired,
@@ -152,36 +281,34 @@
152
281
  });
153
282
  }
154
283
  } else {
284
+ values = Array.isArray(values)
285
+ ? values
286
+ : [values];
155
287
  if (!(itf = this._.manager.widget(src))) {
156
- console.error("[@plotdb/form] condctrl: run with nonexisted fields '" + src + "'");
157
- return;
288
+ return console.error("[@plotdb/form] condctrl: field '" + src + "' not found");
158
289
  }
159
290
  content = itf.content();
160
291
  content = Array.isArray(content)
161
292
  ? content
162
293
  : [content];
163
- active = !!content.filter(function(c){
164
- if (Array.isArray(values)) {
165
- return in$(c, values);
166
- } else {
167
- return c === values;
168
- }
294
+ active = !!content.filter(function(it){
295
+ return in$(it, values);
169
296
  }).length;
170
297
  if (precond != null && !precond) {
171
298
  active = false;
172
299
  }
173
- for (i$ = 0, len$ = path.length; i$ < len$; ++i$) {
174
- p = path[i$];
175
- if (Array.isArray(p) && p[1]) {
300
+ for (i$ = 0, len$ = paths.length; i$ < len$; ++i$) {
301
+ path = paths[i$];
302
+ if (Array.isArray(path) && path[1]) {
176
303
  this.subcond({
177
- path: p[0],
178
- config: (ref$ = import$({}, cfg), ref$.path = p.slice(1), ref$),
304
+ path: path[0],
305
+ config: (ref$ = import$({}, cfg), ref$.path = path.slice(1), ref$),
179
306
  active: active
180
307
  });
181
308
  continue;
182
309
  }
183
310
  this.apply({
184
- path: p,
311
+ path: path,
185
312
  enabled: enabled,
186
313
  active: active,
187
314
  isRequired: isRequired,
@@ -194,8 +321,9 @@
194
321
  }, ref$.run = function(){
195
322
  var result, _, this$ = this;
196
323
  result = {};
197
- _ = function(list){
198
- var i$, to$, i, lresult$, cond, j$, ref$, len$, cfg, results$ = [];
324
+ _ = function(list, ref){
325
+ var i$, to$, i, lresult$, cond, j$, ref$, len$, cfg, r, results$ = [];
326
+ ref == null && (ref = []);
199
327
  for (i$ = 0, to$ = list.length; i$ < to$; ++i$) {
200
328
  i = i$;
201
329
  lresult$ = [];
@@ -204,11 +332,16 @@
204
332
  continue;
205
333
  }
206
334
  if (cond.precond && this$._.hash[cond.precond]) {
207
- _([this$._.hash[cond.precond]]);
335
+ if (in$(cond.id, ref)) {
336
+ console.error("[@plotdb/form] condctrl: circular ref id " + cond.id);
337
+ } else {
338
+ _([this$._.hash[cond.precond]], ref.concat([cond.id]));
339
+ }
208
340
  }
209
341
  for (j$ = 0, len$ = (ref$ = cond.config).length; j$ < len$; ++j$) {
210
342
  cfg = ref$[j$];
211
- lresult$.push(result[cond.id] = this$._run(cfg, result[cond.precond]));
343
+ r = this$._run(cfg, result[cond.precond]);
344
+ lresult$.push(result[cond.id] = result[cond.id] != null ? result[cond.id] && r : r);
212
345
  }
213
346
  results$.push(lresult$);
214
347
  }
@@ -216,6 +349,214 @@
216
349
  };
217
350
  return _(this._.list || []);
218
351
  }, ref$);
352
+ form.conditor = function(opt){
353
+ var this$ = this;
354
+ opt == null && (opt = {});
355
+ this._ = {
356
+ manager: opt.manager,
357
+ conditions: [],
358
+ results: {},
359
+ virtual: {}
360
+ };
361
+ this._.manager.on('change', debounce(50, function(){
362
+ return this$.run();
363
+ }));
364
+ return this;
365
+ };
366
+ form.conditor.prototype = (ref$ = Object.create(Object.prototype), ref$.init = function(conditions){
367
+ conditions == null && (conditions = []);
368
+ this._.conditions = conditions.map(function(c, i){
369
+ var ref$;
370
+ return ref$ = import$({}, c), ref$.id = c.id || "_c" + i, ref$;
371
+ });
372
+ this._.results = {};
373
+ return this;
374
+ }, ref$.eval = function(cond){
375
+ var sub, cached, src, widgets, vals, terms, this$ = this;
376
+ if (cond == null) {
377
+ return Promise.resolve(false);
378
+ }
379
+ if (typeof cond === 'function') {
380
+ return Promise.resolve().then(function(){
381
+ return !!cond.call(this$);
382
+ });
383
+ }
384
+ if (Array.isArray(cond)) {
385
+ return Promise.all(cond.map(function(it){
386
+ return this$.eval(it);
387
+ })).then(function(it){
388
+ return it.every(function(it){
389
+ return it;
390
+ });
391
+ });
392
+ }
393
+ if (cond.logic) {
394
+ sub = Array.isArray(cond.cond)
395
+ ? cond.cond
396
+ : [cond.cond];
397
+ return Promise.all(sub.map(function(it){
398
+ return this$.eval(it);
399
+ })).then(function(rs){
400
+ switch (cond.logic) {
401
+ case 'and':
402
+ return rs.every(function(it){
403
+ return it;
404
+ });
405
+ case 'or':
406
+ return rs.some(function(it){
407
+ return it;
408
+ });
409
+ case 'xor':
410
+ return rs.filter(function(it){
411
+ return it;
412
+ }).length === 1;
413
+ case 'not':
414
+ return !rs[0];
415
+ default:
416
+ return false;
417
+ }
418
+ });
419
+ }
420
+ if (cond.src != null && typeof cond.src === 'string' && (cached = this._.results[cond.src]) != null) {
421
+ return Promise.resolve(cached);
422
+ }
423
+ if (cond.func != null) {
424
+ return Promise.resolve().then(function(){
425
+ return !!cond.func.call(this$);
426
+ });
427
+ }
428
+ if (cond.src != null) {
429
+ src = Array.isArray(cond.src)
430
+ ? cond.src
431
+ : [cond.src];
432
+ widgets = this._.manager.resolve(src);
433
+ if (!widgets.length) {
434
+ return Promise.resolve(false);
435
+ }
436
+ if (widgets.some(function(w){
437
+ return w.disabled();
438
+ })) {
439
+ return Promise.resolve(false);
440
+ }
441
+ if (cond.values != null) {
442
+ vals = Array.isArray(cond.values)
443
+ ? cond.values
444
+ : [cond.values];
445
+ return Promise.resolve(widgets.every(function(w){
446
+ var content;
447
+ content = w.content();
448
+ content = Array.isArray(content)
449
+ ? content
450
+ : [content];
451
+ return content.some(function(it){
452
+ return in$(it, vals);
453
+ });
454
+ }));
455
+ }
456
+ if (cond.term && cond.term.length) {
457
+ terms = cond.term.map(function(t){
458
+ if (t instanceof form.term) {
459
+ return t;
460
+ } else {
461
+ return new form.term(t);
462
+ }
463
+ });
464
+ return Promise.all(widgets.map(function(w){
465
+ var v;
466
+ v = w.content();
467
+ return Promise.all(terms.map(function(t){
468
+ return t.validate(v);
469
+ })).then(function(it){
470
+ return it.every(function(it){
471
+ return it !== false;
472
+ });
473
+ });
474
+ })).then(function(it){
475
+ return it.every(function(it){
476
+ return it;
477
+ });
478
+ });
479
+ }
480
+ return Promise.resolve(widgets.every(function(w){
481
+ return !w.isEmpty();
482
+ }));
483
+ }
484
+ return Promise.resolve(false);
485
+ }, ref$.apply = function(effect, active){
486
+ var targets, i$, len$, target, lresult$, path, j$, ref$, len1$, w, cur, next, changed, results$ = [];
487
+ targets = effect.targets || (effect.target
488
+ ? [effect.target]
489
+ : []);
490
+ for (i$ = 0, len$ = targets.length; i$ < len$; ++i$) {
491
+ target = targets[i$];
492
+ lresult$ = [];
493
+ path = Array.isArray(target)
494
+ ? target
495
+ : [target];
496
+ if (typeof path[0] === 'string' && path[0].startsWith('$')) {
497
+ this._.virtual[path[0]] = active;
498
+ continue;
499
+ }
500
+ for (j$ = 0, len1$ = (ref$ = this._.manager.resolve(path)).length; j$ < len1$; ++j$) {
501
+ w = ref$[j$];
502
+ cur = w.serialize();
503
+ next = JSON.parse(JSON.stringify(cur));
504
+ if (effect.enabled != null) {
505
+ next.disabled = !!(!effect.enabled !== !active && (effect.enabled || active));
506
+ }
507
+ if (effect.isRequired != null) {
508
+ next.isRequired = !(!effect.isRequired !== !active && (effect.isRequired || active));
509
+ }
510
+ if (effect.readonly != null) {
511
+ next.readonly = !(!effect.readonly !== !active && (effect.readonly || active));
512
+ }
513
+ changed = !!cur.disabled !== !!next.disabled || !!cur.isRequired !== !!next.isRequired || !!cur.readonly !== !!next.readonly;
514
+ if (changed) {
515
+ w.deserialize(next, {
516
+ init: true
517
+ });
518
+ }
519
+ if (effect.value != null && active) {
520
+ lresult$.push(w.value(effect.value));
521
+ }
522
+ }
523
+ results$.push(lresult$);
524
+ }
525
+ return results$;
526
+ }, ref$.run = function(){
527
+ var results, evalWithDeps, this$ = this;
528
+ results = this._.results = {};
529
+ evalWithDeps = function(cond){
530
+ var pre, parent;
531
+ if (results[cond.id] != null) {
532
+ return Promise.resolve(results[cond.id]);
533
+ }
534
+ pre = Promise.resolve();
535
+ if (cond.precond) {
536
+ parent = this$._.conditions.find(function(it){
537
+ return it.id === cond.precond;
538
+ });
539
+ if (parent) {
540
+ pre = evalWithDeps(parent);
541
+ }
542
+ }
543
+ return pre.then(function(){
544
+ if (cond.precond != null && !results[cond.precond]) {
545
+ return results[cond.id] = false;
546
+ }
547
+ return this$.eval(cond.when).then(function(active){
548
+ results[cond.id] = active;
549
+ if (cond.effect) {
550
+ this$.apply(cond.effect, active);
551
+ }
552
+ return active;
553
+ });
554
+ });
555
+ };
556
+ return Promise.all(this._.conditions.map(function(c){
557
+ return evalWithDeps(c);
558
+ }));
559
+ }, ref$);
219
560
  form.manager = function(o){
220
561
  var this$ = this;
221
562
  o == null && (o = {});
@@ -345,6 +686,9 @@
345
686
  delete this._ws.w[o.path];
346
687
  return ref1$ = (ref$ = this._ws.l)[key$ = o.path], delete ref$[key$], ref1$;
347
688
  },
689
+ widgets: function(){
690
+ return import$({}, this._ws.w || {});
691
+ },
348
692
  widget: function(p){
349
693
  return this._ws.w[p];
350
694
  },
@@ -666,6 +1010,8 @@
666
1010
  if (ms.length) {
667
1011
  child = {};
668
1012
  ms.map(fn$);
1013
+ } else {
1014
+ child = null;
669
1015
  }
670
1016
  opt = {
671
1017
  idx: 0
@@ -686,6 +1032,44 @@
686
1032
  _(this, obj = {});
687
1033
  return obj;
688
1034
  },
1035
+ 'export': function(){
1036
+ var nodeIdx, cols, k, ref$, v, opt, domIdx;
1037
+ nodeIdx = function(r, n, opt){
1038
+ var i$, to$, i, v;
1039
+ opt.idx++;
1040
+ if (r === n) {
1041
+ return true;
1042
+ }
1043
+ if (!(r && r.childNodes)) {
1044
+ return;
1045
+ }
1046
+ for (i$ = 0, to$ = r.childNodes.length; i$ < to$; ++i$) {
1047
+ i = i$;
1048
+ v = nodeIdx(r.childNodes[i], n, opt);
1049
+ if (v) {
1050
+ return true;
1051
+ }
1052
+ }
1053
+ };
1054
+ cols = [];
1055
+ for (k in ref$ = this._ws.w) {
1056
+ v = ref$[k];
1057
+ opt = {
1058
+ idx: 0
1059
+ };
1060
+ nodeIdx(document.body, v._root, opt);
1061
+ domIdx = opt.idx;
1062
+ cols = cols.concat(v['export']().map(fn$));
1063
+ }
1064
+ return cols.sort(function(a, b){
1065
+ return form.utils.lexCompare(a.sortKey, b.sortKey);
1066
+ });
1067
+ function fn$(col){
1068
+ col.sortKey = [domIdx].concat(col.sortKey);
1069
+ col.uid = col.uid ? k + "|" + col.uid : k;
1070
+ return col;
1071
+ }
1072
+ },
689
1073
  manager: function(opt){
690
1074
  var ret, k, ref$, s, w, mgrs;
691
1075
  ret = [];
@@ -708,6 +1092,43 @@
708
1092
  });
709
1093
  }
710
1094
  return ret;
1095
+ },
1096
+ resolve: function(path){
1097
+ var head, tail, w;
1098
+ if (!path || !path.length) {
1099
+ return [];
1100
+ }
1101
+ head = path[0], tail = slice$.call(path, 1);
1102
+ w = this._ws.w[head];
1103
+ if (!w) {
1104
+ return [];
1105
+ }
1106
+ if (!tail.length) {
1107
+ return [w];
1108
+ }
1109
+ return w.resolve(tail);
1110
+ },
1111
+ paths: function(path){
1112
+ var k, v, head, tail, w;
1113
+ if (!path || !path.length) {
1114
+ return (function(){
1115
+ var ref$, results$ = [];
1116
+ for (k in ref$ = this._ws.w) {
1117
+ v = ref$[k];
1118
+ results$.push({
1119
+ id: k,
1120
+ name: v._meta.title || k
1121
+ });
1122
+ }
1123
+ return results$;
1124
+ }.call(this));
1125
+ }
1126
+ head = path[0], tail = slice$.call(path, 1);
1127
+ w = this._ws.w[head];
1128
+ if (!w) {
1129
+ return [];
1130
+ }
1131
+ return w.paths(tail);
711
1132
  }
712
1133
  });
713
1134
  form.op = function(opt){
@@ -720,6 +1141,13 @@
720
1141
  return this;
721
1142
  };
722
1143
  form.op.prototype = import$(Object.create(Object.prototype), {
1144
+ getConfig: function(valspec){
1145
+ if (typeof this.config === 'function') {
1146
+ return this.config(valspec);
1147
+ } else {
1148
+ return this.config;
1149
+ }
1150
+ },
723
1151
  validate: function(val, cfg){
724
1152
  var ret;
725
1153
  cfg == null && (cfg = {});
@@ -732,10 +1160,10 @@
732
1160
  return Promise.resolve(!!ret);
733
1161
  }
734
1162
  },
735
- configDefault: function(){
1163
+ configDefault: function(valspec){
736
1164
  var cfg, k, ref$, v;
737
1165
  cfg = {};
738
- for (k in ref$ = this.config) {
1166
+ for (k in ref$ = this.getConfig(valspec)) {
739
1167
  v = ref$[k];
740
1168
  cfg[k] = v['default'];
741
1169
  }
@@ -749,6 +1177,7 @@
749
1177
  this.id = opt.id;
750
1178
  this.i18n = opt.i18n;
751
1179
  this.convert = opt.convert;
1180
+ this.valdef = opt.valdef || null;
752
1181
  this.ops = {};
753
1182
  ops = Array.isArray(opt.ops)
754
1183
  ? opt.ops.map(function(it){
@@ -823,10 +1252,28 @@
823
1252
  return (it.id || it.name) === id;
824
1253
  })[0];
825
1254
  };
826
- form.opset.list = function(){
827
- return (this._list || []).map(function(it){
1255
+ form.opset.list = function(opt){
1256
+ var list, vd;
1257
+ opt == null && (opt = {});
1258
+ list = (this._list || []).map(function(it){
828
1259
  return it;
829
1260
  });
1261
+ if (!opt.valdef) {
1262
+ return list;
1263
+ }
1264
+ vd = Array.isArray(opt.valdef)
1265
+ ? opt.valdef
1266
+ : [opt.valdef];
1267
+ return list.filter(function(os){
1268
+ if (!os.valdef) {
1269
+ return !vd.length || vd.some(function(it){
1270
+ return !it || it === "@plotdb/form:valdef/generic";
1271
+ });
1272
+ }
1273
+ return vd.some(function(v){
1274
+ return in$(v, os.valdef);
1275
+ });
1276
+ });
830
1277
  };
831
1278
  wordLen = function(v, method){
832
1279
  v == null && (v = "");
@@ -945,7 +1392,8 @@
945
1392
  i18n: {
946
1393
  "zh-TW": {
947
1394
  "file": "檔案",
948
- "size-limit": "檔案大小上限",
1395
+ "max-size": "檔案大小上限(位元數)",
1396
+ "min-size": "檔案大小下限(位元數)",
949
1397
  "count-limit": "檔案數量上限",
950
1398
  "extension": "副檔名限制",
951
1399
  "count-max": "檔案數量上限",
@@ -954,7 +1402,8 @@
954
1402
  },
955
1403
  "en": {
956
1404
  "file": "File",
957
- "size-limit": "Maximal File Size",
1405
+ "max-size": "Max File Size (bytes)",
1406
+ "min-size": "Min File Size (bytes)",
958
1407
  "count-limit": "Max File Count",
959
1408
  "extension": "File Extension",
960
1409
  "count-max": "Max File Count",
@@ -974,14 +1423,17 @@
974
1423
  func: function(v, c){
975
1424
  c == null && (c = {});
976
1425
  return !v.filter(function(it){
977
- return it.size > c.val;
1426
+ return it.size > c.val && (!it.min || it.min < c.val);
978
1427
  }).length;
979
1428
  },
980
1429
  config: {
981
- val: {
1430
+ size: {
1431
+ type: 'number',
1432
+ name: 'max-size'
1433
+ },
1434
+ min: {
982
1435
  type: 'number',
983
- name: 'size-limit',
984
- hint: "maximal size"
1436
+ name: 'min-size'
985
1437
  }
986
1438
  }
987
1439
  },
@@ -1072,7 +1524,7 @@
1072
1524
  max: {
1073
1525
  type: 'number',
1074
1526
  name: 'max-size',
1075
- hint: "minimal size"
1527
+ hint: "maximal size"
1076
1528
  }
1077
1529
  }
1078
1530
  };
@@ -1159,18 +1611,24 @@
1159
1611
  id: 'length',
1160
1612
  i18n: {
1161
1613
  "zh-TW": {
1162
- length: "長度",
1614
+ length: "字串長度",
1163
1615
  lte: "≦ 小於或等於",
1164
1616
  range: "範圍",
1165
1617
  number: "數字",
1618
+ method: "計算方式",
1619
+ char: "字元",
1620
+ "simple-word": "簡易計字/詞",
1166
1621
  "minimal length": "長度下限",
1167
1622
  "maximal length": "長度上限"
1168
1623
  },
1169
1624
  "en": {
1170
- length: "Length",
1625
+ length: "String Length",
1171
1626
  lte: "≦",
1172
1627
  range: "Range",
1173
1628
  number: "Number",
1629
+ method: "Method",
1630
+ char: "By Character",
1631
+ "simple-word": "Count Word",
1174
1632
  "minimal length": "Min Length",
1175
1633
  "maximal length": "Max Length"
1176
1634
  }
@@ -1395,6 +1853,154 @@
1395
1853
  }
1396
1854
  }
1397
1855
  }
1856
+ }, {
1857
+ id: 'choice',
1858
+ valdef: ['@plotdb/form:valdef/choice'],
1859
+ i18n: {
1860
+ "zh-TW": {
1861
+ choice: "選擇",
1862
+ is: "選了",
1863
+ "is-not": "沒選",
1864
+ "is-any": "選了其中一個",
1865
+ val: "選項值",
1866
+ vals: "選項值(任一)"
1867
+ },
1868
+ "en": {
1869
+ choice: "Choice",
1870
+ is: "Is",
1871
+ "is-not": "Is Not",
1872
+ "is-any": "Is Any Of",
1873
+ val: "Option value",
1874
+ vals: "Option values (any)"
1875
+ }
1876
+ },
1877
+ convert: function(v){
1878
+ var toKey, list;
1879
+ toKey = function(item){
1880
+ if (typeof item === 'string') {
1881
+ return item;
1882
+ } else {
1883
+ return item.key || item.value || '';
1884
+ }
1885
+ };
1886
+ if (!v) {
1887
+ return {
1888
+ list: [],
1889
+ other: {}
1890
+ };
1891
+ }
1892
+ if (typeof v === 'string') {
1893
+ return {
1894
+ list: v
1895
+ ? [v]
1896
+ : [],
1897
+ other: {}
1898
+ };
1899
+ }
1900
+ list = (v.list || v || []).filter(function(it){
1901
+ return it;
1902
+ }).map(toKey);
1903
+ return {
1904
+ list: list,
1905
+ other: v.other || {}
1906
+ };
1907
+ },
1908
+ ops: {
1909
+ is: {
1910
+ func: function(v, c){
1911
+ c == null && (c = {});
1912
+ return !!(c.val && in$(c.val, v.list));
1913
+ },
1914
+ config: function(valspec){
1915
+ var values;
1916
+ values = ((valspec != null ? valspec.values : void 8) || []).map(function(v){
1917
+ return {
1918
+ value: v.key || v.value || v,
1919
+ name: v.label || v.value || v.key || v
1920
+ };
1921
+ });
1922
+ return {
1923
+ val: values.length
1924
+ ? {
1925
+ type: 'choice',
1926
+ name: 'val',
1927
+ values: values
1928
+ }
1929
+ : {
1930
+ type: 'text',
1931
+ name: 'val'
1932
+ }
1933
+ };
1934
+ }
1935
+ },
1936
+ "is-not": {
1937
+ func: function(v, c){
1938
+ c == null && (c = {});
1939
+ return !(c.val && in$(c.val, v.list));
1940
+ },
1941
+ config: function(valspec){
1942
+ var values;
1943
+ values = ((valspec != null ? valspec.values : void 8) || []).map(function(v){
1944
+ return {
1945
+ value: v.key || v.value || v,
1946
+ name: v.label || v.value || v.key || v
1947
+ };
1948
+ });
1949
+ return {
1950
+ val: values.length
1951
+ ? {
1952
+ type: 'choice',
1953
+ name: 'val',
1954
+ values: values
1955
+ }
1956
+ : {
1957
+ type: 'text',
1958
+ name: 'val'
1959
+ }
1960
+ };
1961
+ }
1962
+ },
1963
+ "is-any": {
1964
+ func: function(v, c){
1965
+ var vals;
1966
+ c == null && (c = {});
1967
+ vals = Array.isArray(c.vals)
1968
+ ? c.vals
1969
+ : typeof c.vals === 'string'
1970
+ ? c.vals.split(',').map(function(it){
1971
+ return it.trim();
1972
+ }).filter(function(it){
1973
+ return it;
1974
+ })
1975
+ : [];
1976
+ return vals.some(function(it){
1977
+ return in$(it, v.list);
1978
+ });
1979
+ },
1980
+ config: function(valspec){
1981
+ var values;
1982
+ values = ((valspec != null ? valspec.values : void 8) || []).map(function(v){
1983
+ return {
1984
+ value: v.key || v.value || v,
1985
+ name: v.label || v.value || v.key || v
1986
+ };
1987
+ });
1988
+ return {
1989
+ vals: values.length
1990
+ ? {
1991
+ type: 'choice',
1992
+ name: 'vals',
1993
+ values: values
1994
+ }
1995
+ : {
1996
+ type: 'text',
1997
+ name: 'vals',
1998
+ hint: "comma separated"
1999
+ }
2000
+ };
2001
+ }
2002
+ }
2003
+ }
1398
2004
  }
1399
2005
  ];
1400
2006
  form.opset['default'].map(function(it){
@@ -1411,6 +2017,9 @@
1411
2017
  form.term = function(opt){
1412
2018
  opt == null && (opt = {});
1413
2019
  import$((this.enabled = true, this.opset = null, this.op = null, this.config = {}, this), opt);
2020
+ if (!this.id) {
2021
+ this.id = Math.random().toString(36).substring(2);
2022
+ }
1414
2023
  this.setOpset(opt.opset, opt.op, opt.config);
1415
2024
  return this;
1416
2025
  };
@@ -1455,6 +2064,7 @@
1455
2064
  },
1456
2065
  serialize: function(){
1457
2066
  return {
2067
+ id: this.id,
1458
2068
  enabled: this.enabled,
1459
2069
  opset: this.opset.id,
1460
2070
  op: this.op.id,
@@ -1663,7 +2273,7 @@
1663
2273
  return this._errors;
1664
2274
  },
1665
2275
  value: function(v, opt){
1666
- var _v, this$ = this;
2276
+ var _v, _vs, p, this$ = this;
1667
2277
  opt == null && (opt = {});
1668
2278
  if (arguments.length === 0) {
1669
2279
  return this._value != null
@@ -1673,16 +2283,21 @@
1673
2283
  if (this.isEqual(v, this._value)) {
1674
2284
  return Promise.resolve();
1675
2285
  }
1676
- _v = v != null ? JSON.parse(JSON.stringify(v)) : v;
2286
+ _v = v != null ? JSON.parse(_vs = JSON.stringify(v)) : v;
1677
2287
  this._value = _v;
1678
2288
  this._empty = this.isEmpty(_v);
1679
- return this.validate({
1680
- init: opt.init
1681
- }).then(function(){
1682
- if (opt.fromSource) {
1683
- return;
1684
- }
1685
- return this$.fire('change', this$._value != null ? JSON.parse(JSON.stringify(this$._value)) : undefined);
2289
+ p = this.mod && this.mod.value
2290
+ ? Promise.resolve(this.mod.value.call(this, JSON.parse(_vs)))
2291
+ : Promise.resolve();
2292
+ return p.then(function(){
2293
+ return this$.validate({
2294
+ init: opt.init
2295
+ }).then(function(){
2296
+ if (opt.fromSource) {
2297
+ return;
2298
+ }
2299
+ return this$.fire('change', this$._value != null ? JSON.parse(JSON.stringify(this$._value)) : undefined);
2300
+ });
1686
2301
  });
1687
2302
  },
1688
2303
  disabled: function(){
@@ -1734,18 +2349,47 @@
1734
2349
  return v;
1735
2350
  }
1736
2351
  },
2352
+ valdef: function(){
2353
+ if (this.mod && this.mod.valdef) {
2354
+ if (typeof this.mod.valdef === 'function') {
2355
+ return this.mod.valdef.call(this);
2356
+ }
2357
+ return this.mod.valdef;
2358
+ }
2359
+ return null;
2360
+ },
2361
+ valspec: function(){
2362
+ if (this.mod && this.mod.valspec) {
2363
+ if (typeof this.mod.valspec === 'function') {
2364
+ return this.mod.valspec.call(this);
2365
+ }
2366
+ return this.mod.valspec;
2367
+ }
2368
+ return null;
2369
+ },
1737
2370
  validate: function(opt){
1738
- var v, this$ = this;
2371
+ var lc, getVal, this$ = this;
1739
2372
  opt == null && (opt = {});
1740
- v = this.content();
2373
+ lc = {
2374
+ v: null,
2375
+ _value: this._value
2376
+ };
2377
+ getVal = function(){
2378
+ if (lc.v) {
2379
+ return lc.v;
2380
+ } else {
2381
+ return lc.v = this$.content();
2382
+ }
2383
+ };
1741
2384
  return Promise.resolve().then(function(){
1742
2385
  if (this$.mod && this$.mod.validate) {
1743
2386
  return this$.mod.validate.call(this$, opt);
1744
2387
  }
1745
2388
  if (this$._validate) {
1746
- return this$._validate(v);
2389
+ return this$._validate(getVal());
1747
2390
  }
1748
2391
  }).then(function(ret){
2392
+ var ref$;
1749
2393
  ret == null && (ret = []);
1750
2394
  if (ret.status === 3) {
1751
2395
  this$._errors = ret.errors || [];
@@ -1771,19 +2415,18 @@
1771
2415
  return this$._errors = [];
1772
2416
  }
1773
2417
  }
1774
- return Promise.all(this$._meta.term.filter(function(t){
2418
+ return Promise.all((((ref$ = this$._meta) != null ? ref$.term : void 8) || []).filter(function(t){
1775
2419
  return t.enabled;
1776
2420
  }).map(function(t){
1777
- return t.validate(v).then(function(v){
2421
+ return t.validate(getVal()).then(function(v){
1778
2422
  return [t, v];
1779
2423
  });
1780
- })).then(function(it){
1781
- var nv;
1782
- nv = this$.content();
1783
- if (!this$.isEqual(nv, v)) {
2424
+ })).then(function(ret){
2425
+ var ref$, ref1$;
2426
+ if (((ref$ = this$._meta) != null && ((ref1$ = ref$.term) != null && ref1$.length)) && lc._value !== this$._value) {
1784
2427
  return;
1785
2428
  }
1786
- this$._errors = it.filter(function(it){
2429
+ this$._errors = ret.filter(function(it){
1787
2430
  return !it[1];
1788
2431
  }).map(function(it){
1789
2432
  return it[0].msg || 'error';
@@ -1844,6 +2487,31 @@
1844
2487
  if (this.mod && this.mod.ctrl) {
1845
2488
  return this.mod.ctrl.apply(this, args);
1846
2489
  }
2490
+ },
2491
+ resolve: function(path){
2492
+ if (this.mod && this.mod.resolve) {
2493
+ return this.mod.resolve.apply(this, [path]);
2494
+ } else {
2495
+ return [];
2496
+ }
2497
+ },
2498
+ paths: function(path){
2499
+ if (this.mod && this.mod.paths) {
2500
+ return this.mod.paths.apply(this, [path]);
2501
+ } else {
2502
+ return [];
2503
+ }
2504
+ },
2505
+ 'export': function(){
2506
+ if (this.mod && this.mod['export']) {
2507
+ return this.mod['export'].apply(this);
2508
+ }
2509
+ return [{
2510
+ uid: "",
2511
+ header: this._meta.title || "",
2512
+ sortKey: [],
2513
+ value: form.value.toString(this.value())
2514
+ }];
1847
2515
  }
1848
2516
  });
1849
2517
  if (typeof module != 'undefined' && module !== null) {