blob: 37733d7e8309d6ad24b69b7564f4edba843a2e6e [file] [log] [blame]
Leo Repp58b9f112021-11-22 11:57:47 +01001(function() {
2 var PROTOCOL_6, PROTOCOL_7, Parser, ProtocolError,
3 indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
4
5 exports.PROTOCOL_6 = PROTOCOL_6 = 'http://livereload.com/protocols/official-6';
6
7 exports.PROTOCOL_7 = PROTOCOL_7 = 'http://livereload.com/protocols/official-7';
8
9 exports.ProtocolError = ProtocolError = (function() {
10 function ProtocolError(reason, data) {
11 this.message = "LiveReload protocol error (" + reason + ") after receiving data: \"" + data + "\".";
12 }
13
14 return ProtocolError;
15
16 })();
17
18 exports.Parser = Parser = (function() {
19 function Parser(handlers) {
20 this.handlers = handlers;
21 this.reset();
22 }
23
24 Parser.prototype.reset = function() {
25 return this.protocol = null;
26 };
27
28 Parser.prototype.process = function(data) {
29 var command, e, error, message, options, ref;
30 try {
31 if (this.protocol == null) {
32 if (data.match(/^!!ver:([\d.]+)$/)) {
33 this.protocol = 6;
34 } else if (message = this._parseMessage(data, ['hello'])) {
35 if (!message.protocols.length) {
36 throw new ProtocolError("no protocols specified in handshake message");
37 } else if (indexOf.call(message.protocols, PROTOCOL_7) >= 0) {
38 this.protocol = 7;
39 } else if (indexOf.call(message.protocols, PROTOCOL_6) >= 0) {
40 this.protocol = 6;
41 } else {
42 throw new ProtocolError("no supported protocols found");
43 }
44 }
45 return this.handlers.connected(this.protocol);
46 } else if (this.protocol === 6) {
47 message = JSON.parse(data);
48 if (!message.length) {
49 throw new ProtocolError("protocol 6 messages must be arrays");
50 }
51 command = message[0], options = message[1];
52 if (command !== 'refresh') {
53 throw new ProtocolError("unknown protocol 6 command");
54 }
55 return this.handlers.message({
56 command: 'reload',
57 path: options.path,
58 liveCSS: (ref = options.apply_css_live) != null ? ref : true
59 });
60 } else {
61 message = this._parseMessage(data, ['reload', 'alert']);
62 return this.handlers.message(message);
63 }
64 } catch (error) {
65 e = error;
66 if (e instanceof ProtocolError) {
67 return this.handlers.error(e);
68 } else {
69 throw e;
70 }
71 }
72 };
73
74 Parser.prototype._parseMessage = function(data, validCommands) {
75 var e, error, message, ref;
76 try {
77 message = JSON.parse(data);
78 } catch (error) {
79 e = error;
80 throw new ProtocolError('unparsable JSON', data);
81 }
82 if (!message.command) {
83 throw new ProtocolError('missing "command" key', data);
84 }
85 if (ref = message.command, indexOf.call(validCommands, ref) < 0) {
86 throw new ProtocolError("invalid command '" + message.command + "', only valid commands are: " + (validCommands.join(', ')) + ")", data);
87 }
88 return message;
89 };
90
91 return Parser;
92
93 })();
94
95}).call(this);