total5 0.0.6-4 → 0.0.6-6

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/builders.js CHANGED
@@ -134,6 +134,8 @@ Options.prototype.promisify = function(fn, a, b, c) {
134
134
  });
135
135
  };
136
136
 
137
+ Options.prototype.status = function() {};
138
+
137
139
  Options.prototype.publish = function(value) {
138
140
  var self = this;
139
141
  var name = self.id;
@@ -1254,6 +1256,11 @@ ActionCaller.prototype.params = function(value) {
1254
1256
  return this;
1255
1257
  };
1256
1258
 
1259
+ ActionCaller.prototype.status = function(fn) {
1260
+ this.options.status = fn;
1261
+ return this;
1262
+ };
1263
+
1257
1264
  ActionCaller.prototype.exec = function() {
1258
1265
 
1259
1266
  var self = this;
@@ -1379,6 +1386,7 @@ ActionCaller.prototype.exec = function() {
1379
1386
  } else
1380
1387
  $.payload = payload;
1381
1388
 
1389
+ $.status = self.options.status;
1382
1390
  action.action($, $.payload);
1383
1391
  };
1384
1392
 
package/cache.js CHANGED
@@ -12,7 +12,7 @@ exports.set = function(key, value, expire = '5 minutes') {
12
12
  exports.read = exports.get = function(key, def) {
13
13
  var item = F.temporary.cache[key];
14
14
  global.NOW = new Date();
15
- if (item && item.expire < global.NOW)
15
+ if (item && item.expire > global.NOW)
16
16
  return item.value;
17
17
  else
18
18
  return def;
package/changelog.txt CHANGED
@@ -13,6 +13,21 @@
13
13
  - added `Image` global variable
14
14
  - added `Utils.filestreamer(filename, onbuffer(buffer, next), onend, [buffer_size])`
15
15
  - fix image bug in the `Image.measureWEBP()` method by [Marek Mraz](https://github.com/Mrazbb)
16
+ - added `action.status(fn)` for handling and `$.status(value)` for calling in actions
17
+ - added HTTP auto-redirect for `WebSocketClient`
18
+ - added support for WebSocket redirections in the remote edit
19
+ - fixed `CACHE.read()`
20
+ - added a new argument `size {Number}` to the `WebSocket.on('message', function(client, msg, [size]))` event
21
+ - fixed `@{href()}` command in the ViewEngine
22
+ - improved config & resource parser by adding support for `=` between key and value and for `#` as a comment
23
+ - removed `@{url()}` method and added `@{url}` property
24
+ - added `@{hostname([url])}`
25
+ - added `controller.href()` method
26
+ - extended `HTMLParser` by adding selector for prefixes, example: `node.find('xsd:')`
27
+ - fixed parsing attributes with the `_` character in the `HTMLParser`
28
+ - fixed parsing unpair XML elements in the `HTMLParser`
29
+ - improved Markdown parser
30
+ - added a test functionality for testing Flow components
16
31
 
17
32
  ========================
18
33
  0.0.5
package/controller.js CHANGED
@@ -39,7 +39,7 @@ function Controller(req, res) {
39
39
  ctrl.ext = ctrl.uri.ext;
40
40
  ctrl.split = ctrl.uri.split;
41
41
  ctrl.split2 = [];
42
- ctrl.url = ctrl.uri.key;
42
+ ctrl.url = ctrl.uri.pathname;
43
43
  ctrl.released = false;
44
44
  ctrl.downloaded = false;
45
45
  ctrl.protocol = req.connection.encrypted || (req.headers['x-forwarded-protocol'] || req.headers['x-forwarded-proto']) === 'https' ? 'https' : 'http';
@@ -1034,6 +1034,10 @@ Controller.prototype.$route = function() {
1034
1034
 
1035
1035
  };
1036
1036
 
1037
+ Controller.prototype.href = function(key, value) {
1038
+ return F.TViewEngine.prototype.href.call(this, key, value);
1039
+ };
1040
+
1037
1041
  function readfile(filename, callback) {
1038
1042
  F.stats.performance.open++;
1039
1043
  F.Fs.lstat(filename, function(err, stats) {
@@ -1766,4 +1770,4 @@ HttpFile.prototype.fs = function(storage, fileid, callback, custom, expire) {
1766
1770
  return F.filestorage(storage).save(fileid, this.filename, this.path, callback, custom, expire);
1767
1771
  };
1768
1772
 
1769
- exports.Controller = Controller;
1773
+ exports.Controller = Controller;
package/edit.js CHANGED
@@ -16,16 +16,30 @@ exports.init = function(url) {
16
16
  client.options.reconnect = 10000;
17
17
  client.options.reconnectserver = true;
18
18
 
19
+ var initilaized = false;
20
+
19
21
  client.on('message', function(msg) {
20
22
 
23
+ if (msg.TYPE === 'redirect') {
24
+ if (msg.url) {
25
+ client.close(3001);
26
+ exports.init(msg.url);
27
+ }
28
+ return;
29
+ }
30
+
21
31
  if (msg.TYPE === 'init') {
22
32
  console.log(DIVIDER);
23
33
  console.log(HEADER + ': Welcome to "' + msg.name + ' (' + msg.version + ')"');
24
34
  console.log('> Project: "' + msg.project + '"');
25
35
  console.log(DIVIDER);
36
+ initilaized = true;
26
37
  return;
27
38
  }
28
39
 
40
+ if (!initilaized)
41
+ return;
42
+
29
43
  F.action('editor', msg).callback(function(err, response) {
30
44
 
31
45
  if (err) {
@@ -45,6 +59,8 @@ exports.init = function(url) {
45
59
 
46
60
  client.on('close', function(e) {
47
61
 
62
+ initilaized = false;
63
+
48
64
  if (e === 4004) {
49
65
  console.log(HEADER + ': 404 project not found');
50
66
  // Tries again in 10 second interval
@@ -2648,8 +2648,10 @@ function MAKEFLOWSTREAM(meta) {
2648
2648
 
2649
2649
  var sendstatusforce = function(instance) {
2650
2650
  instance.$statusdelay = null;
2651
- if (instance.$status != null && flow.proxy.online)
2651
+ if (instance.$status != null) {
2652
2652
  flow.proxy.online && flow.proxy.send({ TYPE: 'flow/status', id: instance.id, data: instance.$status });
2653
+ flow.$events.status && flow.emit('status', instance, instance.$status);
2654
+ }
2653
2655
  };
2654
2656
 
2655
2657
  // component.status() will execute this method
@@ -2663,22 +2665,24 @@ function MAKEFLOWSTREAM(meta) {
2663
2665
  if (delay) {
2664
2666
  if (!instance.$statusdelay)
2665
2667
  instance.$statusdelay = setTimeout(sendstatusforce, delay || 1000, instance);
2666
- } else if (instance.$status != null && flow.proxy.online)
2667
- flow.proxy.online && flow.proxy.send({ TYPE: 'flow/status', id: instance.id, data: instance.$status });
2668
+ } else
2669
+ sendstatusforce(instance);
2668
2670
  };
2669
2671
 
2670
2672
  // component.dashboard() will execute this method
2671
- flow.ondashboard = function(status) {
2673
+ flow.ondashboard = function(data) {
2672
2674
 
2673
2675
  var instance = this;
2674
2676
 
2675
- if (status == null)
2676
- status = instance.$dashboard;
2677
+ if (data == null)
2678
+ data = instance.$dashboard;
2677
2679
  else
2678
- instance.$dashboard = status;
2680
+ instance.$dashboard = data;
2679
2681
 
2680
- if (status != null && flow.proxy.online)
2681
- flow.proxy.online && flow.proxy.send({ TYPE: 'flow/dashboard', id: instance.id, data: status });
2682
+ if (data != null) {
2683
+ flow.proxy.online && flow.proxy.send({ TYPE: 'flow/dashboard', id: instance.id, data: data });
2684
+ flow.$events.dashboard && flow.emit('dashboard', instance, instance.data);
2685
+ }
2682
2686
 
2683
2687
  };
2684
2688
 
package/flow-test.js ADDED
@@ -0,0 +1,141 @@
1
+ exports.load = function(name, source, config, init) {
2
+
3
+ if (typeof(config) === 'function') {
4
+ init = config;
5
+ config = {};
6
+ }
7
+
8
+ let schema = {};
9
+
10
+ schema.id = 'test';
11
+ schema.name = 'Test';
12
+ schema.paused = false;
13
+ schema.cloning = true;
14
+ schema.design = {};
15
+ schema.components = {};
16
+ schema.components.dummy = `<script total>
17
+ exports.id = 'dummy';
18
+ exports.name = 'Dummy';
19
+ exports.inputs = [{ id: 'input', name: 'Input' }];
20
+ exports.make = function(instance) {
21
+
22
+ instance.refresh = function() {
23
+ // somethings happens e.g. reconfiguration
24
+ instance.main.refresh2 && instance.main.refresh2();
25
+ };
26
+
27
+ instance.message = function($) {
28
+ instance.main.test.message && instance.main.test.message($, $.data);
29
+ instance.main.test.output && instance.main.test.output($, $.data);
30
+ };
31
+ };
32
+ </script>`;
33
+
34
+ schema.components[name] = source;
35
+ schema.variables = {};
36
+
37
+ schema.design.dummy = {
38
+ id: 'dummy',
39
+ component: 'dummy',
40
+ connections: {}
41
+ };
42
+
43
+ schema.design.component = {
44
+ id: 'component',
45
+ component: name,
46
+ config: config || {},
47
+ connections: {}
48
+ };
49
+
50
+ var Test = {};
51
+
52
+ Test.variables = function(variables) {
53
+ Test.flow.variables(variables);
54
+ };
55
+
56
+ Test.input = Test.send = function(name, data) {
57
+ let msg = Test.dummy.newmessage(data);
58
+ setImmediate(() => msg.send(name));
59
+ return msg;
60
+ };
61
+
62
+ Test.assert = function(ok, message) {
63
+ if (ok)
64
+ Test.ok(message);
65
+ else
66
+ Test.fail(message);
67
+ };
68
+
69
+ Test.ok = function(message = name) {
70
+ console.log(new Date().format('yyyy-MM-dd HH:mm:ss:ms') + ' [OK]: ' + message);
71
+ };
72
+
73
+ Test.fail = function(message = 'Unexpected problem') {
74
+ console.warn(new Date().format('yyyy-MM-dd HH:mm:ss:ms') + ' [NO]: ' + message);
75
+ throw new Error(message);
76
+ };
77
+
78
+ Test.trigger = function(data) {
79
+ Flow.test.component.trigger(data);
80
+ };
81
+
82
+ Test.reconfigure = function(value) {
83
+ Test.flow.reconfigure('component', value);
84
+ };
85
+
86
+ Flow.load(schema, function(err, instance) {
87
+
88
+ var skip = false;
89
+
90
+ instance.flow.refresh2 = function() {
91
+
92
+ if (skip)
93
+ return;
94
+
95
+ let component = instance.flow.meta.flow.component;
96
+ let outputs = component.outputs || instance.flow.meta.components[name].outputs || [];
97
+ let inputs = component.inputs || instance.flow.meta.components[name].inputs || [];
98
+
99
+ instance.flow.meta.flow.component.connections = {};
100
+ instance.flow.meta.flow.dummy.connections = {};
101
+
102
+ for (let m of outputs)
103
+ instance.flow.meta.flow.component.connections[m.id] = [{ id: 'dummy', index: 'input' }];
104
+
105
+ for (let m of inputs)
106
+ instance.flow.meta.flow.dummy.connections[m.id] = [{ id: 'component', index: m.id }];
107
+ };
108
+
109
+ Test.flow = instance;
110
+ Test.component = instance.flow.meta.flow.component;
111
+ Test.dummy = instance.flow.meta.flow.dummy;
112
+
113
+ instance.flow.onreconfigure = function(component) {
114
+ Test.configure && setImmediate(() => Test.configure(component.config));
115
+ };
116
+
117
+ instance.flow.test = Test;
118
+ instance.flow.refresh2();
119
+
120
+ instance.flow.on('debug', function(a, b, c, d) {
121
+ Test.debug && Test.debug(a, b, c, d);
122
+ });
123
+
124
+ instance.flow.on('status', function(instance, status) {
125
+ Test.status && Test.status(status);
126
+ });
127
+
128
+ instance.flow.on('error', function(a, b, c, d) {
129
+ Test.error && Test.error(a, b, c, d);
130
+ });
131
+
132
+ instance.flow.on('dashboard', function(instance, data) {
133
+ Test.dashboard && Test.dashboard(data);
134
+ });
135
+
136
+ instance.onerror = () => process.exit(1);
137
+ init && init(Test);
138
+
139
+ });
140
+
141
+ };
package/flow.js CHANGED
@@ -16,6 +16,7 @@ FS.worker = false;
16
16
  FS.instances = {};
17
17
  FS.onerror = function(err, source, id, componentid, stack) {
18
18
 
19
+ throw new Error('FET');
19
20
  var flow = FS.db[this.id];
20
21
  var empty = '---';
21
22
  var output = '';
@@ -168,6 +169,7 @@ FS.load = function(flow, callback) {
168
169
  FS.$events.load && FS.emit('load', instance, flow);
169
170
  callback && callback(err, err ? null : instance);
170
171
  };
172
+
171
173
  });
172
174
 
173
175
  };
@@ -229,6 +231,10 @@ FS.ping = function() {
229
231
  }
230
232
  };
231
233
 
234
+ FS.test = function(name, source, config, init) {
235
+ require('./flow-test.js').load(name, source, config, init);
236
+ };
237
+
232
238
  global.Flow = FS;
233
239
  global.FlowStream = exports;
234
240
 
package/flowstream.js CHANGED
@@ -380,6 +380,7 @@ MP.send = function(outputindex, data, clonedata) {
380
380
  return count;
381
381
  }
382
382
 
383
+
383
384
  var meta = self.main.meta;
384
385
  var now = Date.now();
385
386
 
@@ -930,11 +931,13 @@ FP.onreconfigure = function(instance, init) {
930
931
  */
931
932
 
932
933
  FP.ondashboard = function(a, b, c, d) {
934
+ // Flow uses only the "a {Object}" argument
933
935
  // this == instance
934
936
  this.main.$events.dashboard && this.main.emit('dashboard', this, a, b, c, d);
935
937
  };
936
938
 
937
939
  FP.onstatus = function(a, b, c, d) {
940
+ // Flow uses only the "a {Object}" argument
938
941
  // this == instance
939
942
  this.main.$events.status && this.main.emit('status', this, a, b, c, d);
940
943
  };
package/htmlparser.js CHANGED
@@ -67,7 +67,12 @@ function parseRule(selector, output) {
67
67
  }
68
68
 
69
69
  selector = selector.trim();
70
- rule.tagName = selector[0] === '*' ? '' : selector.toUpperCase();
70
+
71
+ if (selector[selector.length - 1] === ':') {
72
+ rule.prefix = selector.toUpperCase();
73
+ rule.tagName = '';
74
+ } else
75
+ rule.tagName = selector[0] === '*' ? '' : selector.toUpperCase();
71
76
 
72
77
  return rule;
73
78
  }
@@ -168,6 +173,9 @@ HTMLElement.prototype.find = function(selector, reverse) {
168
173
  if (rule.tagName && rule.tagName !== node.tagName)
169
174
  skip = true;
170
175
 
176
+ if (rule.prefix && rule.prefix !== node.prefix)
177
+ skip = true;
178
+
171
179
  if (rule.attrs.length && !skip) {
172
180
  for (var attr of rule.attrs) {
173
181
  switch (attr.id) {
@@ -439,6 +447,7 @@ HTMLElement.prototype.toString = HTMLElement.prototype.html = function(formatted
439
447
  builder.push(indent + item.textContent);
440
448
  break;
441
449
  default:
450
+ tag = item.raw;
442
451
  if (item.unpair) {
443
452
  builder.push(indent + '<' + tag + (attrs.length ? (' ' + attrs.join(' ')) : '') + ' />');
444
453
  } else {
@@ -490,7 +499,7 @@ function parseHTML(html, trim, onerror, isxml) {
490
499
  };
491
500
 
492
501
  var parseAttrs = function(str) {
493
- var attrs = str.match(/[a-z-0-9A-Z\:]+(=("|').*?("|'))?/g);
502
+ var attrs = str.match(/[a-z-0-9A-Z\:_-]+(=("|').*?("|'))?/g);
494
503
  var obj = {};
495
504
  if (attrs) {
496
505
  for (var m of attrs) {
@@ -566,6 +575,11 @@ function parseHTML(html, trim, onerror, isxml) {
566
575
  }
567
576
 
568
577
  dom.tagName = tag.toUpperCase();
578
+ index = dom.tagName.indexOf(':');
579
+
580
+ if (index !== -1)
581
+ dom.prefix = dom.tagName.substring(0, index + 1);
582
+
569
583
  dom.children = [];
570
584
  dom.attrs = node ? parseAttrs(node) : {};
571
585
  dom.raw = tag;
@@ -575,7 +589,10 @@ function parseHTML(html, trim, onerror, isxml) {
575
589
  str = str.substring(end + 1);
576
590
 
577
591
  // Unpair tags
578
- if (!isxml) {
592
+ if (isxml) {
593
+ if (dom.unpair)
594
+ return str;
595
+ } else {
579
596
  switch (dom.tagName) {
580
597
  case 'BR':
581
598
  case 'HR':
package/index.js CHANGED
@@ -650,7 +650,7 @@ F.loadresource = function(name, value) {
650
650
 
651
651
  let index = line.indexOf(':');
652
652
  if (index === -1) {
653
- index = line.indexOf('\t:');
653
+ index = line.indexOf('=');
654
654
  if (index === -1)
655
655
  continue;
656
656
  }
package/markdown.js CHANGED
@@ -9,7 +9,7 @@ const REG_ICONS = /(^|[^\w]):((fab|far|fas|fal|fad|fa|ti)\s(fa|ti)-)?[a-z-]+:([^
9
9
  const REG_KEYWORDS = /\{.*?\}\(.*?\)/g;
10
10
  const REG_LINKEXTERNAL = /(https|http):\/\//;
11
11
  const REG_FORMAT = /__.*?__|_.*?_|\*\*.*?\*\*|\*.*?\*|~~.*?~~|~.*?~/g;
12
- const REG_ORDERED = /^[a-z|0-9]{1,3}\.\s|^-\s/i;
12
+ const REG_ORDERED = /^[a-z|0-9]{1,3}\.\s|^(-|\*|\+)\s/i;
13
13
  const REG_ORDEREDSIZE = /^(\s|\t)+/;
14
14
  const REG_CODE = /`.*?`/g;
15
15
  const REG_ENCODETAGS = /<|>/g;
@@ -732,7 +732,8 @@ String.prototype.markdown = function(opt, nested) {
732
732
  else
733
733
  size = 0;
734
734
 
735
- var ultype = tmpline.charAt(0) === '-' ? 'ul' : 'ol';
735
+ var c = tmpline.charAt(0);
736
+ var ultype = c === '-' || c === '*' || c === '+' ? 'ul' : 'ol';
736
737
  var tmpstr = (ultype === 'ol' ? tmpline.substring(tmpline.indexOf('.') + 1) : tmpline.substring(2));
737
738
  var istask = false;
738
739
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "total5",
3
- "version": "0.0.6-4",
3
+ "version": "0.0.6-6",
4
4
  "description": "Total.js framework v5",
5
5
  "main": "index.js",
6
6
  "directories": {
package/utils.js CHANGED
@@ -3218,7 +3218,7 @@ SP.parseConfig = function(def, onerr) {
3218
3218
 
3219
3219
  index = str.indexOf(':');
3220
3220
  if (index === -1) {
3221
- index = str.indexOf('\t:');
3221
+ index = str.indexOf('=');
3222
3222
  if (index === -1)
3223
3223
  continue;
3224
3224
  }
package/viewengine.js CHANGED
@@ -591,6 +591,8 @@ function View(controller) {
591
591
  self.language = controller?.language || '';
592
592
  self.repository = { layout: 'layout' };
593
593
  self.islayout = false;
594
+ self.url = controller?.url || '';
595
+ self.query = controller?.query || {};
594
596
  }
595
597
 
596
598
  View.prototype.ota = function(obj) {
@@ -655,29 +657,23 @@ View.prototype.keywords = function(value) {
655
657
  return '';
656
658
  };
657
659
 
658
- function querystring_encode(value, def, key) {
659
-
660
- if (value instanceof Array) {
661
- var tmp = '';
662
- for (var i = 1; i < value.length; i++)
663
- tmp += (tmp ? '&' : '') + key + '=' + querystring_encode(value[i], def);
664
- return querystring_encode(value[0], def) + (tmp ? tmp : '');
665
- }
666
-
667
- return value != null ? value instanceof Date ? encodeURIComponent(value.format()) : typeof(value) === 'string' ? encodeURIComponent(value) : (value + '') : def || '';
668
- }
669
-
660
+ // @{href({ key1: 1, key2: 2 })}
661
+ // @{href('key', 'value')}
670
662
  // @{href({ key1: 1, key2: 2 })}
671
663
  // @{href('key', 'value')}
672
664
  View.prototype.href = function(key, value) {
673
665
 
674
666
  var self = this;
667
+ var query = self.query;
675
668
 
676
669
  if (!arguments.length) {
677
- let val = F.TUtils.toURLEncode(self.query);
670
+ let val = F.TUtils.toURLEncode(query);
678
671
  return val ? '?' + val : '';
679
672
  }
680
673
 
674
+ if (!self.repository)
675
+ self.repository = {};
676
+
681
677
  var type = typeof(key);
682
678
  var obj;
683
679
 
@@ -688,18 +684,21 @@ View.prototype.href = function(key, value) {
688
684
 
689
685
  if (!str) {
690
686
 
691
- obj = F.TUtils.copy(self.query);
687
+ obj = {};
688
+
689
+ for (let key in query)
690
+ obj[key] = query[key];
692
691
 
693
- for (var i = 2; i < arguments.length; i++)
692
+ for (let i = 2; i < arguments.length; i++)
694
693
  obj[arguments[i]] = undefined;
695
694
 
696
695
  obj[key] = '\0';
697
696
 
698
- for (var m in obj) {
697
+ for (let m in obj) {
699
698
  var val = obj[m];
700
699
  if (val !== undefined) {
701
700
  if (val instanceof Array) {
702
- for (var j = 0; j < val.length; j++)
701
+ for (let j = 0; j < val.length; j++)
703
702
  str += (str ? '&' : '') + m + '=' + (key === m ? '\0' : querystring_encode(val[j]));
704
703
  } else
705
704
  str += (str ? '&' : '') + m + '=' + (key === m ? '\0' : querystring_encode(val));
@@ -708,22 +707,25 @@ View.prototype.href = function(key, value) {
708
707
  self.repository[cachekey] = str;
709
708
  }
710
709
 
711
- str = str.replace('\0', querystring_encode(value, self.query[key], key));
710
+ str = str.replace('\0', querystring_encode(value, query[key], key));
712
711
 
713
- for (var i = 2; i < arguments.length; i++) {
714
- var beg = str.indexOf(arguments[i] + '=');
712
+ for (let i = 2; i < arguments.length; i++) {
713
+ let beg = str.indexOf(arguments[i] + '=');
715
714
  if (beg === -1)
716
715
  continue;
717
- var end = str.indexOf('&', beg);
716
+ let end = str.indexOf('&', beg);
718
717
  str = str.substring(0, beg) + str.substring(end === -1 ? str.length : end + 1);
719
718
  }
720
719
 
721
- return str ? '?' + str : '';
720
+ return str ? ('?' + str) : '';
722
721
  }
723
722
 
724
723
  if (value) {
725
- obj = F.TUtils.copy(self.query);
726
- F.TUtils.extend(obj, value);
724
+ obj = {};
725
+ for (let key in query)
726
+ obj[key] = query[key];
727
+ for (let key in value)
728
+ obj[key] = value[key];
727
729
  }
728
730
 
729
731
  if (value != null)
@@ -737,6 +739,18 @@ View.prototype.href = function(key, value) {
737
739
  return self.url + (obj ? '?' + obj : '');
738
740
  };
739
741
 
742
+ function querystring_encode(value, def, key) {
743
+
744
+ if (value instanceof Array) {
745
+ var tmp = '';
746
+ for (var i = 1; i < value.length; i++)
747
+ tmp += (tmp ? '&' : '') + key + '=' + querystring_encode(value[i], def);
748
+ return querystring_encode(value[0], def) + (tmp ? tmp : '');
749
+ }
750
+
751
+ return value != null ? value instanceof Date ? encodeURIComponent(value.format()) : typeof(value) === 'string' ? encodeURIComponent(value) : (value + '') : def || '';
752
+ }
753
+
740
754
  function makehtmlmeta(self) {
741
755
 
742
756
  var builder = '';
@@ -850,9 +864,9 @@ View.prototype.section = function(name, value, replace) {
850
864
  return self;
851
865
  };
852
866
 
853
- View.prototype.url = function(hostname = false) {
867
+ View.prototype.hostname = function(url) {
854
868
  var self = this;
855
- return hostname ? (self.controller ? self.controller.hostname(self.controller.url) : '') : (self.controller ? self.controller.url : '');
869
+ return self.controller ? self.controller.hostname(url == null ? self.controller.url : url) : (url || '');
856
870
  };
857
871
 
858
872
  View.prototype.set = function() {
package/websocket.js CHANGED
@@ -411,14 +411,15 @@ Controller.prototype.decode = function() {
411
411
 
412
412
  var ctrl = this;
413
413
  var data = ctrl.current.body;
414
+ var size = data.length;
414
415
 
415
416
  F.stats.performance.message++;
416
- F.stats.performance.download += data.length / 1024 / 1024;
417
+ F.stats.performance.download += size / 1024 / 1024;
417
418
 
418
419
  switch (ctrl.datatype) {
419
420
 
420
421
  case 'binary':
421
- ctrl.parent.$events.message && ctrl.parent.emit('message', ctrl, data);
422
+ ctrl.parent.$events.message && ctrl.parent.emit('message', ctrl, data, size);
422
423
  break;
423
424
 
424
425
  case 'json':
@@ -440,7 +441,7 @@ Controller.prototype.decode = function() {
440
441
  tmp = tmp.replace(REG_EMPTYBUFFER, '');
441
442
 
442
443
  if (tmp !== undefined && ctrl.parent.$events.message)
443
- ctrl.parent.emit('message', this, tmp);
444
+ ctrl.parent.emit('message', this, tmp, size);
444
445
  }
445
446
  break;
446
447
 
@@ -458,7 +459,7 @@ Controller.prototype.decode = function() {
458
459
  if (REG_EMPTYBUFFER_TEST.test(data))
459
460
  data = data.replace(REG_EMPTYBUFFER, '');
460
461
 
461
- ctrl.parent.$events.message && ctrl.parent.emit('message', ctrl, data);
462
+ ctrl.parent.$events.message && ctrl.parent.emit('message', ctrl, data, size);
462
463
  break;
463
464
  }
464
465
 
@@ -1272,6 +1273,11 @@ WebSocketClient.prototype.connectforce = function(self, url, protocol, origin) {
1272
1273
 
1273
1274
  self.req.on('response', function(res) {
1274
1275
 
1276
+ if (res.statusCode === 301 || res.statusCode === 302) {
1277
+ self.connect(res.headers.location, self.protocol, self.origin);
1278
+ return;
1279
+ }
1280
+
1275
1281
  self.$events.error && self.emit('error', new Error('Unexpected server response (' + res.statusCode + ')'));
1276
1282
 
1277
1283
  if (self.options.reconnectserver) {
@@ -1529,13 +1535,14 @@ WebSocketClient.prototype.decode = function() {
1529
1535
 
1530
1536
  var self = this;
1531
1537
  var data = self.current.body;
1538
+ var size = data.length;
1532
1539
 
1533
1540
  F.stats.performance.message++;
1534
1541
 
1535
1542
  switch (self.options.type) {
1536
1543
 
1537
1544
  case 'binary':
1538
- self.emit('message', data);
1545
+ self.emit('message', data, size);
1539
1546
  break;
1540
1547
 
1541
1548
  case 'json':
@@ -1552,7 +1559,7 @@ WebSocketClient.prototype.decode = function() {
1552
1559
  if (data.isJSON()) {
1553
1560
  var tmp = data.parseJSON(true);
1554
1561
  if (tmp !== undefined)
1555
- self.emit('message', tmp);
1562
+ self.emit('message', tmp, size);
1556
1563
  }
1557
1564
  break;
1558
1565
 
@@ -1567,7 +1574,7 @@ WebSocketClient.prototype.decode = function() {
1567
1574
  if (self.options.encrypt)
1568
1575
  data = F.TUtils.decrypt_data(data, self.options.encrypt);
1569
1576
 
1570
- self.emit('message', data);
1577
+ self.emit('message', data, size);
1571
1578
  break;
1572
1579
  }
1573
1580