total5 0.0.1-3 → 0.0.1-30

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/api.js CHANGED
@@ -132,7 +132,7 @@ APICallProto.error = APICallProto.err = function(err, reverse) {
132
132
 
133
133
  APICallProto.callback = function($) {
134
134
  var t = this;
135
- t.$callback = typeof($) === 'function' ? $ : $.callback;
135
+ t.$callback = typeof($) === 'function' ? $ : $.callback();
136
136
  return t;
137
137
  };
138
138
 
@@ -208,7 +208,7 @@ exports.newapi('TotalAPI,TAPI', function(opt, next) {
208
208
  req.type = 'json';
209
209
  req.timeout = 60000;
210
210
  req.keepalive = true;
211
- req.headers = { 'x-token': opt.token || F.config.secret_totalapi || F.config.$tapisecret || '-', 'x-app': encodeURIComponent(F.config.name) };
211
+ req.headers = { 'x-token': opt.token || F.config.totalapi || F.config.secret_totalapi || F.config.$tapisecret || '-', 'x-app': encodeURIComponent(F.config.name) };
212
212
  req.custom = true;
213
213
 
214
214
  req.callback = function(err, response) {
@@ -279,10 +279,7 @@ exports.newapi('TotalAPI,TAPI', function(opt, next) {
279
279
 
280
280
  var writer = F.Fs.createWriteStream(opt.output);
281
281
  response.stream.pipe(writer);
282
- F.cleanup(writer, function() {
283
- opt.next(null, opt.output);
284
- });
285
-
282
+ F.cleanup(writer, () => opt.next(null, opt.output));
286
283
  };
287
284
 
288
285
  F.TUtils.request(req);
package/builders.js CHANGED
@@ -5,6 +5,7 @@
5
5
  'use strict';
6
6
 
7
7
  const REG_ARGS = /\{{1,2}[a-z0-9_.-\s]+\}{1,2}/gi;
8
+ const SESSIONSEPARATOR = '\0';
8
9
 
9
10
  var transforms = { error: {}, restbuilder: {} };
10
11
  var restbuilderupgrades = [];
@@ -23,7 +24,11 @@ Options.prototype = {
23
24
  },
24
25
 
25
26
  get websocket() {
26
- return this.controller.parent;
27
+ return this.controller && this.controller.iswebsocket ? this.controller : null;
28
+ },
29
+
30
+ get sessionid() {
31
+ return this.controller ? this.controller.sessionid : null;
27
32
  },
28
33
 
29
34
  get value() {
@@ -51,15 +56,15 @@ Options.prototype = {
51
56
  },
52
57
 
53
58
  get path() {
54
- return (this.controller ? this.controller.pathname : EMPTYARRAY);
59
+ return this.controller ? this.controller.pathname : EMPTYARRAY;
55
60
  },
56
61
 
57
62
  get split() {
58
- return (this.controller ? this.controller.split : EMPTYARRAY);
63
+ return this.controller ? this.controller.split : EMPTYARRAY;
59
64
  },
60
65
 
61
66
  get split2() {
62
- return (this.controller ? this.controller.split2 : EMPTYARRAY);
67
+ return this.controller ? this.controller.split2 : EMPTYARRAY;
63
68
  },
64
69
 
65
70
  get language() {
@@ -98,7 +103,7 @@ Options.prototype.action = function(schema, payload) {
98
103
  Options.prototype.publish = function(value) {
99
104
  var self = this;
100
105
  var name = self.id;
101
- if (F.TMS.cache.socket && F.TMS.cache.pcache[name] && F.TMS.cache.publishers[name]) {
106
+ if (F.TTMS.cache.socket && F.TTMS.cache.pcache[name]) {
102
107
 
103
108
  var tmp = {};
104
109
  if (tmp) {
@@ -109,7 +114,7 @@ Options.prototype.publish = function(value) {
109
114
  }
110
115
 
111
116
  F.stats.performance.publish++;
112
- F.TMS.cache.socket.send({ type: 'publish', id: name, data: tmp }, client => client.tmsready);
117
+ F.TTMS.cache.socket.send({ type: 'publish', id: name, data: tmp }, client => client.tmsready && client.$subscribers[name]);
113
118
  }
114
119
  return self;
115
120
  };
@@ -148,8 +153,14 @@ Options.prototype.cancel = function() {
148
153
  };
149
154
 
150
155
  Options.prototype.redirect = function(url) {
151
- this.redirect(url);
152
- this.cancel();
156
+ var self = this;
157
+ self.$callback = null;
158
+ if (self.controller) {
159
+ self.controller.redirect(url);
160
+ self.controller.destroyed = true;
161
+ }
162
+ self.cancel();
163
+ return self;
153
164
  };
154
165
 
155
166
  Options.prototype.audit = function(message, type) {
@@ -164,6 +175,16 @@ Options.prototype.success = function(value) {
164
175
  self.callback(DEF.onSuccess(value));
165
176
  };
166
177
 
178
+ Options.prototype.successful = function(callback) {
179
+ var self = this;
180
+ return function(err, a, b, c) {
181
+ if (err)
182
+ self.invalid(err);
183
+ else
184
+ callback.call(self, a, b, c);
185
+ };
186
+ };
187
+
167
188
  Options.prototype.callback = function(value) {
168
189
 
169
190
  var self = this;
@@ -182,8 +203,8 @@ Options.prototype.done = function(arg) {
182
203
  var self = this;
183
204
  return function(err, response) {
184
205
  if (err) {
185
- err && self.error.push(err);
186
- self.callback();
206
+ self.error.push(err);
207
+ self.callback(null);
187
208
  } else {
188
209
  if (self.TYPE === 'auth')
189
210
  self.callback(arg === true ? response : arg);
@@ -196,7 +217,7 @@ Options.prototype.done = function(arg) {
196
217
  Options.prototype.invalid = function(error, path, index) {
197
218
  var self = this;
198
219
  self.error.push(error, path, index);
199
- self.$callback(error);
220
+ self.$callback(true);
200
221
  };
201
222
 
202
223
  Options.prototype.cookie = function(name, value, expire, options) {
@@ -262,6 +283,11 @@ ErrorBuilder.prototype = {
262
283
  }
263
284
  };
264
285
 
286
+ ErrorBuilder.prototype.reject = function(language) {
287
+ var self = this;
288
+ return new Error(self.toString(language, ''));
289
+ };
290
+
265
291
  ErrorBuilder.prototype.push = function(err, path, index) {
266
292
  var self = this;
267
293
 
@@ -316,8 +342,10 @@ ErrorBuilder.prototype.output = function(language = 'default') {
316
342
 
317
343
  let err = m.error;
318
344
 
319
- if (err[0] == '@')
345
+ if (err == '@')
320
346
  err = F.resource(language, 'T' + (err === '@' ? m.name : err.substring(1)).hash(true).toString(36)) || 'The field "' + m.name + '" is invalid';
347
+ else if (err[0] === '@')
348
+ err = F.translate(language, err);
321
349
 
322
350
  if (self.replacer) {
323
351
  for (let key in self.replacer)
@@ -333,12 +361,12 @@ ErrorBuilder.prototype.output = function(language = 'default') {
333
361
  return output;
334
362
  };
335
363
 
336
- ErrorBuilder.prototype.toString = function(language = 'default') {
364
+ ErrorBuilder.prototype.toString = function(language = 'default', divider = '\n') {
337
365
  var self = this;
338
366
  var output = self.output(language);
339
367
  var str = '';
340
368
  for (let err of output)
341
- str += (str ? '\n' : '') + err.error;
369
+ str += (str ? divider : '') + err.error;
342
370
  return str;
343
371
  };
344
372
 
@@ -710,6 +738,9 @@ RESTP.callback = function(fn) {
710
738
 
711
739
  var self = this;
712
740
 
741
+ if (fn instanceof Options)
742
+ fn = fn.callback();
743
+
713
744
  if (typeof(fn) === 'function') {
714
745
  setImmediate(execrestbuilder, self, fn);
715
746
  return self;
@@ -1147,20 +1178,24 @@ exports.newaction = function(name, obj) {
1147
1178
  }
1148
1179
  }
1149
1180
 
1150
- F.TMS.newpublish(name, tmsschema);
1181
+ F.TTMS.newpublish(name, tmsschema);
1151
1182
  }
1152
1183
 
1153
1184
  F.makesourcemap && F.makesourcemap();
1154
1185
  return obj;
1155
1186
  };
1156
1187
 
1188
+ function ActionCallerExec(self) {
1189
+ self.exec();
1190
+ }
1191
+
1157
1192
  function ActionCaller() {
1158
1193
  var self = this;
1159
1194
  self.$ = new Options();
1160
1195
  self.error = new ErrorBuilder();
1161
1196
  self.options = {};
1162
1197
  self.actions = [];
1163
- setImmediate(self => self.exec(), self);
1198
+ setImmediate(ActionCallerExec, self);
1164
1199
  }
1165
1200
 
1166
1201
  ActionCaller.prototype.debug = function() {
@@ -1219,7 +1254,7 @@ ActionCaller.prototype.exec = function() {
1219
1254
  var type = meta.payload || (action.input ? '+' : '-');
1220
1255
  var $ = self.$;
1221
1256
 
1222
- $.id = id;
1257
+ $.id = action.id;
1223
1258
  $.error = self.error;
1224
1259
  $.controller = self.controller;
1225
1260
  $.fields = action.fields;
@@ -1272,7 +1307,8 @@ ActionCaller.prototype.exec = function() {
1272
1307
  return;
1273
1308
  }
1274
1309
  $.query = response.response;
1275
- }
1310
+ } else
1311
+ $.query = query;
1276
1312
 
1277
1313
  if (action.jsparams) {
1278
1314
  self.error.prefix = 'params.';
@@ -1283,16 +1319,18 @@ ActionCaller.prototype.exec = function() {
1283
1319
  return;
1284
1320
  }
1285
1321
  $.params = response.response;
1286
- }
1322
+ } else
1323
+ $.params = params;
1287
1324
 
1288
1325
  if (action.jsinput && type !== '-') {
1289
- response = action.jsinput.transform(payload, type === '%', self.error);
1326
+ response = action.jsinput.transform(payload, action.partial, self.error);
1290
1327
  if (response.error) {
1291
1328
  self.cancel();
1292
1329
  return;
1293
1330
  }
1294
1331
  $.payload = response.response;
1295
- }
1332
+ } else
1333
+ $.payload = payload;
1296
1334
 
1297
1335
  action.action($, $.payload);
1298
1336
  };
@@ -1363,7 +1401,7 @@ ActionCaller.prototype.promise = function($) {
1363
1401
  if ($ && $.invalid)
1364
1402
  $.invalid(err);
1365
1403
  else
1366
- reject(err);
1404
+ reject(err.reject());
1367
1405
  } else
1368
1406
  resolve(response);
1369
1407
  };
@@ -1421,15 +1459,281 @@ exports.action = function(name, payload, controller) {
1421
1459
  };
1422
1460
 
1423
1461
  exports.newschema = function(name, callback) {
1462
+
1463
+ if (name[0] === '@')
1464
+ name = name.substring(1);
1465
+
1466
+ if (typeof(callback) === 'string')
1467
+ return F.jsonschemas[name] = F.TUtils.jsonschema(callback, true);
1468
+
1424
1469
  var $ = {};
1425
1470
  $.name = name;
1426
1471
  $.actions = {};
1427
1472
  $.action = function(aname, meta) {
1428
1473
  return $.actions[aname] = F.newaction(name + '/' + aname, meta);
1429
1474
  };
1475
+
1430
1476
  callback($);
1431
1477
  };
1432
1478
 
1479
+ exports.builtinauth = function(opt) {
1480
+
1481
+ // opt.secret {String}
1482
+ // opt.ddos {Number}
1483
+ // opt.expire {String}
1484
+ // opt.cookie {String} A cookie name
1485
+ // opt.header {String} A header name
1486
+ // opt.options {Object} A cookie options
1487
+ // opt.strict {Boolean}
1488
+
1489
+ if (opt.strict == null)
1490
+ opt.strict = true;
1491
+
1492
+ // Delegates
1493
+ // opt.onddos = function($)
1494
+ // opt.onread = function({ sessionid: String, userid: String, ua: String }, callback(USER_DATA), $)
1495
+ // opt.onfree = function({ sessions: Array, users: Array })
1496
+ // opt.onlogout = function(sessionid, userid)
1497
+ // opt.onauthorize = function($) must return true for canceling of processing
1498
+
1499
+ opt.sessions = {};
1500
+ opt.blocked = {};
1501
+ opt.pending = {};
1502
+
1503
+ if (!opt.cleaner)
1504
+ opt.cleaner = 5;
1505
+
1506
+ if (!opt.secret)
1507
+ opt.secret = F.secret;
1508
+
1509
+ opt.logout = function($) {
1510
+
1511
+ var id = $;
1512
+
1513
+ if (typeof(id) === 'object')
1514
+ id = $.sessionid;
1515
+
1516
+ if (id) {
1517
+ for (var key in opt.sessions) {
1518
+ var session = opt.sessions[key];
1519
+ if (session.sessionid === id) {
1520
+ delete opt.sessions[key];
1521
+ opt.onlogout && opt.onlogout(session);
1522
+ opt.cookie && !$.controller.parent && $.controller.cookie && $.controller.cookie(opt.cookie, '', '-1 year', opt.options);
1523
+ return true;
1524
+ }
1525
+ }
1526
+ }
1527
+ };
1528
+
1529
+ opt.update = function(userid, fn) {
1530
+ var count = 0;
1531
+ for (var key in opt.sessions) {
1532
+ var session = opt.sessions[key];
1533
+ if (session.userid === userid) {
1534
+ count++;
1535
+ fn(session.data, session);
1536
+ }
1537
+ }
1538
+ return count;
1539
+ };
1540
+
1541
+ opt.refresh = function(userid, exceptsessionid) {
1542
+ var count = 0;
1543
+ for (var key in opt.sessions) {
1544
+ var session = opt.sessions[key];
1545
+ if (session.userid === userid && session.sessionid !== exceptsessionid) {
1546
+ count++;
1547
+ delete opt.sessions[key];
1548
+ }
1549
+ }
1550
+ return count;
1551
+ };
1552
+
1553
+ opt.sign = function(sessionid, userid) {
1554
+ return (sessionid + SESSIONSEPARATOR + userid + SESSIONSEPARATOR + Date.now().toString(36)).encrypt(opt.secret);
1555
+ };
1556
+
1557
+ opt.authcookie = function($, sessionid, userid, expiration, options) {
1558
+ if (!options)
1559
+ options = opt.options;
1560
+ var ctrl = $.controller ? $.controller : $;
1561
+ ctrl.cookie && !ctrl.parent && $.cookie(opt.cookie, opt.sign(sessionid, userid), expiration, options);
1562
+ };
1563
+
1564
+ if (!opt.expire)
1565
+ opt.expire = '5 minutes';
1566
+
1567
+ var callpending = function(pending, data) {
1568
+ for (var i = 0; i < pending.length; i++) {
1569
+ if (data)
1570
+ pending[i].success(data);
1571
+ else
1572
+ pending[i].invalid();
1573
+ }
1574
+ };
1575
+
1576
+ opt.auth = function($) {
1577
+
1578
+ if (opt.onauthorize && opt.onauthorize($))
1579
+ return;
1580
+
1581
+ var sessionid = opt.cookie ? $.cookie(opt.cookie) : null;
1582
+ if (!sessionid && opt.header)
1583
+ sessionid = $.controller.headers[opt.header];
1584
+
1585
+ var localize = opt.locale || opt.localize;
1586
+
1587
+ if (!sessionid) {
1588
+
1589
+ if (localize)
1590
+ $.controller.language = localize(null, $.controller);
1591
+
1592
+ $.invalid();
1593
+ return;
1594
+ }
1595
+
1596
+ var id = sessionid.decrypt(opt.secret);
1597
+ if (id) {
1598
+
1599
+ id = id.split(SESSIONSEPARATOR);
1600
+
1601
+ if (!id[0] || !id[1] || !id[2])
1602
+ id = null;
1603
+
1604
+ if (id) {
1605
+ var session = opt.sessions[id[0]];
1606
+ if (session && session.data) {
1607
+ if (!opt.strict || session.ua === $.controller.ua) {
1608
+ $.controller.session = session;
1609
+ $.controller.sessionid = session.sessionid;
1610
+ if (!opt.onsession || !opt.onsession(session, $)) {
1611
+ if (localize)
1612
+ $.controller.language = localize(session.data, $.controller);
1613
+ $.success(session.data);
1614
+ }
1615
+ } else {
1616
+
1617
+ if (localize)
1618
+ $.controller.language = localize(null, $.controller);
1619
+
1620
+ $.invalid();
1621
+ sessionid = null;
1622
+ }
1623
+ return;
1624
+ }
1625
+ }
1626
+ }
1627
+
1628
+ if (opt.ddos && opt.blocked[$.controller.ip] > opt.ddos) {
1629
+ opt.onddos && opt.onddos($);
1630
+ $.invalid();
1631
+ return;
1632
+ }
1633
+
1634
+ if (!id) {
1635
+
1636
+ if (opt.ddos) {
1637
+ if (opt.blocked[$.controller.ip])
1638
+ opt.blocked[$.controller.ip]++;
1639
+ else
1640
+ opt.blocked[$.controller.ip] = 1;
1641
+ }
1642
+
1643
+ opt.cookie && $.controller && !$.controller.parent && $.controller.cookie && $.controller.cookie(opt.cookie, '', '-1 year', opt.options);
1644
+ $.invalid();
1645
+ return;
1646
+ }
1647
+
1648
+ var meta = { ip: $.controller.ip, ua: $.controller.ua, sessionid: id[0], userid: id[1] };
1649
+
1650
+ if (opt.pending[meta.sessionid]) {
1651
+ opt.pending[meta.sessionid].push($);
1652
+ return;
1653
+ }
1654
+
1655
+ opt.pending[meta.sessionid] = [];
1656
+ opt.onread(meta, function(err, data) {
1657
+
1658
+ var pending = opt.pending[meta.sessionid];
1659
+ delete opt.pending[meta.sessionid];
1660
+
1661
+ if (!err && data) {
1662
+
1663
+ $.controller.session = opt.sessions[meta.sessionid] = { sessionid: meta.sessionid, userid: meta.userid, data: data, ua: $.controller.ua, expire: NOW.add(opt.expire) };
1664
+ $.controller.sessionid = meta.sessionid;
1665
+
1666
+ if (localize)
1667
+ $.controller.language = localize(data, $.controller);
1668
+
1669
+ if (!opt.onsession || !opt.onsession($.controller.session, $, true))
1670
+ $.success(data);
1671
+
1672
+ if (pending.length)
1673
+ setImmediate(callpending, pending, data);
1674
+
1675
+ } else {
1676
+
1677
+ if (opt.ddos) {
1678
+ if (opt.blocked[$.controller.ip])
1679
+ opt.blocked[$.controller.ip]++;
1680
+ else
1681
+ opt.blocked[$.controller.ip] = 1;
1682
+ }
1683
+
1684
+ opt.cookie && !$.controller.parent && $.controller.cookie && $.controller.cookie(opt.cookie, '', '-1 year', opt.options);
1685
+ $.invalid();
1686
+
1687
+ if (pending.length)
1688
+ setImmediate(callpending, pending);
1689
+ }
1690
+
1691
+ }, $);
1692
+
1693
+ };
1694
+
1695
+ F.def.onAuthorize = opt.auth;
1696
+
1697
+ F.on('service', function(counter) {
1698
+
1699
+ if (counter % opt.cleaner)
1700
+ return;
1701
+
1702
+ var expired = [];
1703
+ var users_expired = {};
1704
+ var users_live = {};
1705
+
1706
+ for (var key in opt.sessions) {
1707
+ var session = opt.sessions[key];
1708
+ if (session.expire < NOW) {
1709
+ expired.push(key);
1710
+ delete opt.sessions[key];
1711
+ users_expired[session.userid] = 1;
1712
+ } else
1713
+ users_live[session.userid] = 1;
1714
+ }
1715
+
1716
+ if (expired.length) {
1717
+ for (var key in users_expired) {
1718
+ if (users_live[key])
1719
+ delete users_expired[key];
1720
+ }
1721
+ }
1722
+
1723
+ if (expired.length && opt.onfree) {
1724
+ var meta = {};
1725
+ meta.sessions = expired;
1726
+ meta.users = expired.length ? Object.keys(users_expired) : null;
1727
+ opt.onfree && opt.onfree(meta);
1728
+ }
1729
+
1730
+ opt.blocked = {};
1731
+
1732
+ });
1733
+
1734
+ return opt;
1735
+ };
1736
+
1433
1737
  exports.RESTBuilder = RESTBuilder;
1434
1738
  exports.ErrorBuilder = ErrorBuilder;
1435
1739
  exports.Options = Options;
package/bundles.js CHANGED
@@ -400,7 +400,7 @@ exports.extract = function(callback, skip) {
400
400
  try {
401
401
 
402
402
  if (F.Fs.readFileSync('bundles.debug')) {
403
- F.isbundle = true;
403
+ F.isBundle = true;
404
404
  F.dir(F.path.root('/.src/'));
405
405
  callback();
406
406
  return;
@@ -428,7 +428,7 @@ exports.extract = function(callback, skip) {
428
428
  });
429
429
  }, function() {
430
430
  extract(function() {
431
- F.isbundle = true;
431
+ F.isBundle = true;
432
432
  F.dir(F.path.root('/.src/'));
433
433
  callback();
434
434
  });
@@ -436,21 +436,11 @@ exports.extract = function(callback, skip) {
436
436
  };
437
437
 
438
438
  try {
439
-
440
439
  var files = F.Fs.readdirSync(bundles);
441
440
  if (files.length)
442
441
  extractbundles();
443
442
  else
444
443
  callback();
445
-
446
- /*
447
- if (F.$bundling) {
448
- makebundle();
449
- return;
450
- } else {
451
- F.isbundle = true;
452
- F.dir(F.path.root('/.src/'));
453
- }*/
454
444
  } catch(e) {
455
445
  callback();
456
446
  }
package/cms.js CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  'use strict';
6
6
 
7
- const SKIP_CLASSES = { CMS_hidden: 1, CMS_mv: 1, CMS_mh: 1, CMS_expression: 1, CMS_multiple: 1 };
7
+ const SKIP_CLASSES = { CMS_hidden: 1, CMS_mv: 1, CMS_mh: 1, CMS_expression: 1, CMS_multiple: 1, CMS_keyword: 1, CMS_monospace: 1 };
8
8
  const VERSION = 1;
9
9
 
10
10
  function clean(html) {
@@ -22,12 +22,20 @@ function expressions_multiple(body) {
22
22
  while (true) {
23
23
 
24
24
  index = body.indexOf('CMS_multiple', index + 12);
25
-
26
25
  if (index === -1)
27
26
  break;
28
27
 
29
- var b = body.lastIndexOf('<', index);
30
- var tag = body.substring(b + 1, body.indexOf(' ', b));
28
+ var b = findstart(body, index);
29
+ if (b === -1)
30
+ break;
31
+
32
+ var end = body.indexOf(' ', b);
33
+ if (end === -1) {
34
+ index += 13;
35
+ continue;
36
+ }
37
+
38
+ var tag = body.substring(b + 1, end);
31
39
 
32
40
  var e = body.indexOf('</' + tag + '>', index);
33
41
  var size = e + 3 + tag.length;
@@ -53,6 +61,25 @@ function expressions_multiple(body) {
53
61
  return arr;
54
62
  }
55
63
 
64
+ function findstart(body, index) {
65
+
66
+ var notallowed = [';', '.', '>', ':', '\n', '\r', '\t'];
67
+
68
+ for (let i = index; i > -1; i--) {
69
+
70
+ let c = body[i];
71
+ if (c === '<')
72
+ return i;
73
+
74
+ if (notallowed.includes(c))
75
+ break;
76
+ }
77
+
78
+
79
+ return -1;
80
+
81
+ }
82
+
56
83
  function expressions(body) {
57
84
 
58
85
  var index = 0;
@@ -65,9 +92,17 @@ function expressions(body) {
65
92
  if (index === -1)
66
93
  break;
67
94
 
68
- var b = body.lastIndexOf('<', index);
69
- var tag = body.substring(b + 1, body.indexOf(' ', b));
95
+ var b = findstart(body, index);
96
+ if (b === -1)
97
+ break;
98
+
99
+ var end = body.indexOf(' ', b);
100
+ if (end === -1) {
101
+ index += 15;
102
+ continue;
103
+ }
70
104
 
105
+ var tag = body.substring(b + 1, end);
71
106
  var e = body.indexOf('</' + tag + '>', index);
72
107
  var size = e + 3 + tag.length;
73
108
  var obj = {};
@@ -90,12 +125,27 @@ function trash(body) {
90
125
 
91
126
  index = body.indexOf(t, index + t.length);
92
127
 
93
- if (index === -1) {
128
+ if (index === -1)
129
+ break;
130
+
131
+ var b = findstart(body, index);
132
+ if (b === -1)
94
133
  break;
134
+
135
+ var end = body.indexOf(' ', b);
136
+
137
+ if (end === -1) {
138
+ index += t.length + 1;
139
+ continue;
140
+ }
141
+
142
+ var tag = body.substring(b + 1, end);
143
+
144
+ if (tag.length > 10) {
145
+ index += tag.length;
146
+ continue;
95
147
  }
96
148
 
97
- var b = body.lastIndexOf('<', index);
98
- var tag = body.substring(b + 1, body.indexOf(' ', b));
99
149
  var e = body.indexOf('</' + tag + '>', index);
100
150
  var size = e + 3 + tag.length;
101
151
  body = body.replace(body.substring(b, size), '');
@@ -347,7 +397,7 @@ exports.compile = function(html, widgets, used) {
347
397
  opt.id = id;
348
398
  opt.indexer = indexer;
349
399
  opt.body = tidy(clean(body));
350
- opt.text = body.substring(body.lastIndexOf('~BEG~') + 5, body.lastIndexOf('~END~'));
400
+ opt.html = body.substring(body.lastIndexOf('~BEG~') + 5, body.lastIndexOf('~END~'));
351
401
  opt.config = config || EMPTYOBJECT;
352
402
  opt.render = widget.render;
353
403
  opt.beg = opt.body.substring(0, opt.body.indexOf('>') + 1);
@@ -577,7 +627,7 @@ CMSRender.prototype._render = function(meta, layout, callback) {
577
627
  }
578
628
 
579
629
  render(opt, function(response, replace, cache) {
580
- widgets[item.indexer] = replace === true ? response == null ? '' : (response + '').replace(/~(BEG|END)~/g, '') : (item.beg + (response || '') + item.end);
630
+ widgets[item.indexer] = replace === true ? (response == null || response == '' ? '' : (response + '').replace(/~(BEG|END)~/g, '')) : (item.beg + (response || '') + item.end);
581
631
  if (cache)
582
632
  self.cache[opt.cacheid] = widgets[item.indexer];
583
633
  next();