rack-livereload 0.3.0 → 0.3.1

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.
data/js/livereload.js CHANGED
@@ -1,804 +1,926 @@
1
1
  (function() {
2
- var __customevents = {}, __protocol = {}, __connector = {}, __timer = {}, __options = {}, __reloader = {}, __livereload = {}, __startup = {};
2
+ var __customevents = {}, __protocol = {}, __connector = {}, __timer = {}, __options = {}, __reloader = {}, __livereload = {}, __less = {}, __startup = {};
3
3
 
4
4
  // customevents
5
- (function() {
6
- var CustomEvents;
7
- CustomEvents = {
8
- bind: function(element, eventName, handler) {
9
- if (element.addEventListener) {
10
- return element.addEventListener(eventName, handler, false);
11
- } else if (element.attachEvent) {
12
- element[eventName] = 1;
13
- return element.attachEvent('onpropertychange', function(event) {
14
- if (event.propertyName === eventName) {
15
- return handler();
16
- }
17
- });
18
- } else {
19
- throw new Error("Attempt to attach custom event " + eventName + " to something which isn't a DOMElement");
20
- }
21
- },
22
- fire: function(element, eventName) {
23
- var event;
24
- if (element.addEventListener) {
25
- event = document.createEvent('HTMLEvents');
26
- event.initEvent(eventName, true, true);
27
- return document.dispatchEvent(event);
28
- } else if (element.attachEvent) {
29
- if (element[eventName]) {
30
- return element[eventName]++;
5
+ var CustomEvents;
6
+ CustomEvents = {
7
+ bind: function(element, eventName, handler) {
8
+ if (element.addEventListener) {
9
+ return element.addEventListener(eventName, handler, false);
10
+ } else if (element.attachEvent) {
11
+ element[eventName] = 1;
12
+ return element.attachEvent('onpropertychange', function(event) {
13
+ if (event.propertyName === eventName) {
14
+ return handler();
31
15
  }
32
- } else {
33
- throw new Error("Attempt to fire custom event " + eventName + " on something which isn't a DOMElement");
16
+ });
17
+ } else {
18
+ throw new Error("Attempt to attach custom event " + eventName + " to something which isn't a DOMElement");
19
+ }
20
+ },
21
+ fire: function(element, eventName) {
22
+ var event;
23
+ if (element.addEventListener) {
24
+ event = document.createEvent('HTMLEvents');
25
+ event.initEvent(eventName, true, true);
26
+ return document.dispatchEvent(event);
27
+ } else if (element.attachEvent) {
28
+ if (element[eventName]) {
29
+ return element[eventName]++;
34
30
  }
31
+ } else {
32
+ throw new Error("Attempt to fire custom event " + eventName + " on something which isn't a DOMElement");
35
33
  }
36
- };
37
- __customevents.bind = CustomEvents.bind;
38
- __customevents.fire = CustomEvents.fire;
39
- }).call(this);
34
+ }
35
+ };
36
+ __customevents.bind = CustomEvents.bind;
37
+ __customevents.fire = CustomEvents.fire;
40
38
 
41
39
  // protocol
42
- (function() {
43
- var PROTOCOL_6, PROTOCOL_7, Parser, ProtocolError;
44
- var __indexOf = Array.prototype.indexOf || function(item) {
45
- for (var i = 0, l = this.length; i < l; i++) {
46
- if (this[i] === item) return i;
47
- }
48
- return -1;
49
- };
50
- __protocol.PROTOCOL_6 = PROTOCOL_6 = 'http://livereload.com/protocols/official-6';
51
- __protocol.PROTOCOL_7 = PROTOCOL_7 = 'http://livereload.com/protocols/official-7';
52
- __protocol.ProtocolError = ProtocolError = (function() {
53
- function ProtocolError(reason, data) {
54
- this.message = "LiveReload protocol error (" + reason + ") after receiving data: \"" + data + "\".";
55
- }
56
- return ProtocolError;
57
- })();
58
- __protocol.Parser = Parser = (function() {
59
- function Parser(handlers) {
60
- this.handlers = handlers;
61
- this.reset();
62
- }
63
- Parser.prototype.reset = function() {
64
- return this.protocol = null;
65
- };
66
- Parser.prototype.process = function(data) {
67
- var command, message, options, _ref;
68
- try {
69
- if (!(this.protocol != null)) {
70
- if (data.match(/^!!ver:([\d.]+)$/)) {
40
+ var PROTOCOL_6, PROTOCOL_7, Parser, ProtocolError;
41
+ var __indexOf = Array.prototype.indexOf || function(item) {
42
+ for (var i = 0, l = this.length; i < l; i++) {
43
+ if (this[i] === item) return i;
44
+ }
45
+ return -1;
46
+ };
47
+ __protocol.PROTOCOL_6 = PROTOCOL_6 = 'http://livereload.com/protocols/official-6';
48
+ __protocol.PROTOCOL_7 = PROTOCOL_7 = 'http://livereload.com/protocols/official-7';
49
+ __protocol.ProtocolError = ProtocolError = (function() {
50
+ function ProtocolError(reason, data) {
51
+ this.message = "LiveReload protocol error (" + reason + ") after receiving data: \"" + data + "\".";
52
+ }
53
+ return ProtocolError;
54
+ })();
55
+ __protocol.Parser = Parser = (function() {
56
+ function Parser(handlers) {
57
+ this.handlers = handlers;
58
+ this.reset();
59
+ }
60
+ Parser.prototype.reset = function() {
61
+ return this.protocol = null;
62
+ };
63
+ Parser.prototype.process = function(data) {
64
+ var command, message, options, _ref;
65
+ try {
66
+ if (!(this.protocol != null)) {
67
+ if (data.match(/^!!ver:([\d.]+)$/)) {
68
+ this.protocol = 6;
69
+ } else if (message = this._parseMessage(data, ['hello'])) {
70
+ if (!message.protocols.length) {
71
+ throw new ProtocolError("no protocols specified in handshake message");
72
+ } else if (__indexOf.call(message.protocols, PROTOCOL_7) >= 0) {
73
+ this.protocol = 7;
74
+ } else if (__indexOf.call(message.protocols, PROTOCOL_6) >= 0) {
71
75
  this.protocol = 6;
72
- } else if (message = this._parseMessage(data, ['hello'])) {
73
- if (!message.protocols.length) {
74
- throw new ProtocolError("no protocols specified in handshake message");
75
- } else if (__indexOf.call(message.protocols, PROTOCOL_7) >= 0) {
76
- this.protocol = 7;
77
- } else if (__indexOf.call(message.protocols, PROTOCOL_6) >= 0) {
78
- this.protocol = 6;
79
- } else {
80
- throw new ProtocolError("no supported protocols found");
81
- }
82
- }
83
- return this.handlers.connected(this.protocol);
84
- } else if (this.protocol === 6) {
85
- message = JSON.parse(data);
86
- if (!message.length) {
87
- throw new ProtocolError("protocol 6 messages must be arrays");
88
- }
89
- command = message[0], options = message[1];
90
- if (command !== 'refresh') {
91
- throw new ProtocolError("unknown protocol 6 command");
76
+ } else {
77
+ throw new ProtocolError("no supported protocols found");
92
78
  }
93
- return this.handlers.message({
94
- command: 'reload',
95
- path: options.path,
96
- liveCSS: (_ref = options.apply_css_live) != null ? _ref : true
97
- });
98
- } else {
99
- message = this._parseMessage(data, ['reload', 'alert']);
100
- return this.handlers.message(message);
101
- }
102
- } catch (e) {
103
- if (e instanceof ProtocolError) {
104
- return this.handlers.error(e);
105
- } else {
106
- throw e;
107
79
  }
108
- }
109
- };
110
- Parser.prototype._parseMessage = function(data, validCommands) {
111
- var message, _ref;
112
- try {
80
+ return this.handlers.connected(this.protocol);
81
+ } else if (this.protocol === 6) {
113
82
  message = JSON.parse(data);
114
- } catch (e) {
115
- throw new ProtocolError('unparsable JSON', data);
116
- }
117
- if (!message.command) {
118
- throw new ProtocolError('missing "command" key', data);
119
- }
120
- if (_ref = message.command, __indexOf.call(validCommands, _ref) < 0) {
121
- throw new ProtocolError("invalid command '" + message.command + "', only valid commands are: " + (validCommands.join(', ')) + ")", data);
122
- }
123
- return message;
124
- };
125
- return Parser;
126
- })();
127
- }).call(this);
128
-
129
- // connector
130
- (function() {
131
- var Connector, PROTOCOL_6, PROTOCOL_7, Parser, _ref;
132
- var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
133
- _ref = __protocol, Parser = _ref.Parser, PROTOCOL_6 = _ref.PROTOCOL_6, PROTOCOL_7 = _ref.PROTOCOL_7;
134
- __connector.Connector = Connector = (function() {
135
- function Connector(options, WebSocket, Timer, handlers) {
136
- this.options = options;
137
- this.WebSocket = WebSocket;
138
- this.Timer = Timer;
139
- this.handlers = handlers;
140
- this._uri = "ws://" + this.options.host + ":" + this.options.port + "/livereload";
141
- this._nextDelay = this.options.mindelay;
142
- this._connectionDesired = false;
143
- this.protocolParser = new Parser({
144
- connected: __bind(function(protocol) {
145
- this._handshakeTimeout.stop();
146
- this._nextDelay = this.options.mindelay;
147
- this._disconnectionReason = 'broken';
148
- return this.handlers.connected(protocol);
149
- }, this),
150
- error: __bind(function(e) {
151
- this.handlers.error(e);
152
- return this._closeOnError();
153
- }, this),
154
- message: __bind(function(message) {
155
- return this.handlers.message(message);
156
- }, this)
157
- });
158
- this._handshakeTimeout = new Timer(__bind(function() {
159
- if (!this._isSocketConnected()) {
160
- return;
83
+ if (!message.length) {
84
+ throw new ProtocolError("protocol 6 messages must be arrays");
161
85
  }
162
- this._disconnectionReason = 'handshake-timeout';
163
- return this.socket.close();
164
- }, this));
165
- this._reconnectTimer = new Timer(__bind(function() {
166
- if (!this._connectionDesired) {
167
- return;
86
+ command = message[0], options = message[1];
87
+ if (command !== 'refresh') {
88
+ throw new ProtocolError("unknown protocol 6 command");
168
89
  }
169
- return this.connect();
170
- }, this));
171
- this.connect();
172
- }
173
- Connector.prototype._isSocketConnected = function() {
174
- return this.socket && this.socket.readyState === this.WebSocket.OPEN;
175
- };
176
- Connector.prototype.connect = function() {
177
- this._connectionDesired = true;
178
- if (this._isSocketConnected()) {
179
- return;
90
+ return this.handlers.message({
91
+ command: 'reload',
92
+ path: options.path,
93
+ liveCSS: (_ref = options.apply_css_live) != null ? _ref : true
94
+ });
95
+ } else {
96
+ message = this._parseMessage(data, ['reload', 'alert']);
97
+ return this.handlers.message(message);
180
98
  }
181
- if (this._reconnectTimer) {
182
- clearTimeout(this._reconnectTimer);
99
+ } catch (e) {
100
+ if (e instanceof ProtocolError) {
101
+ return this.handlers.error(e);
102
+ } else {
103
+ throw e;
183
104
  }
184
- this._disconnectionReason = 'cannot-connect';
185
- this.protocolParser.reset();
186
- this.handlers.connecting();
187
- this.socket = new this.WebSocket(this._uri);
188
- this.socket.onopen = __bind(function(e) {
189
- return this._onopen(e);
190
- }, this);
191
- this.socket.onclose = __bind(function(e) {
192
- return this._onclose(e);
193
- }, this);
194
- this.socket.onmessage = __bind(function(e) {
195
- return this._onmessage(e);
196
- }, this);
197
- return this.socket.onerror = __bind(function(e) {
198
- return this._onerror(e);
199
- }, this);
200
- };
201
- Connector.prototype.disconnect = function() {
202
- this._connectionDesired = false;
203
- this._reconnectTimer.stop();
105
+ }
106
+ };
107
+ Parser.prototype._parseMessage = function(data, validCommands) {
108
+ var message, _ref;
109
+ try {
110
+ message = JSON.parse(data);
111
+ } catch (e) {
112
+ throw new ProtocolError('unparsable JSON', data);
113
+ }
114
+ if (!message.command) {
115
+ throw new ProtocolError('missing "command" key', data);
116
+ }
117
+ if (_ref = message.command, __indexOf.call(validCommands, _ref) < 0) {
118
+ throw new ProtocolError("invalid command '" + message.command + "', only valid commands are: " + (validCommands.join(', ')) + ")", data);
119
+ }
120
+ return message;
121
+ };
122
+ return Parser;
123
+ })();
124
+
125
+ // connector
126
+ var Connector, PROTOCOL_6, PROTOCOL_7, Parser, Version, _ref;
127
+ var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
128
+ _ref = __protocol, Parser = _ref.Parser, PROTOCOL_6 = _ref.PROTOCOL_6, PROTOCOL_7 = _ref.PROTOCOL_7;
129
+ Version = '2.0.3';
130
+ __connector.Connector = Connector = (function() {
131
+ function Connector(options, WebSocket, Timer, handlers) {
132
+ this.options = options;
133
+ this.WebSocket = WebSocket;
134
+ this.Timer = Timer;
135
+ this.handlers = handlers;
136
+ this._uri = "ws://" + this.options.host + ":" + this.options.port + "/livereload";
137
+ this._nextDelay = this.options.mindelay;
138
+ this._connectionDesired = false;
139
+ this.protocol = 0;
140
+ this.protocolParser = new Parser({
141
+ connected: __bind(function(protocol) {
142
+ this.protocol = protocol;
143
+ this._handshakeTimeout.stop();
144
+ this._nextDelay = this.options.mindelay;
145
+ this._disconnectionReason = 'broken';
146
+ return this.handlers.connected(protocol);
147
+ }, this),
148
+ error: __bind(function(e) {
149
+ this.handlers.error(e);
150
+ return this._closeOnError();
151
+ }, this),
152
+ message: __bind(function(message) {
153
+ return this.handlers.message(message);
154
+ }, this)
155
+ });
156
+ this._handshakeTimeout = new Timer(__bind(function() {
204
157
  if (!this._isSocketConnected()) {
205
158
  return;
206
159
  }
207
- this._disconnectionReason = 'manual';
160
+ this._disconnectionReason = 'handshake-timeout';
208
161
  return this.socket.close();
209
- };
210
- Connector.prototype._scheduleReconnection = function() {
162
+ }, this));
163
+ this._reconnectTimer = new Timer(__bind(function() {
211
164
  if (!this._connectionDesired) {
212
165
  return;
213
166
  }
214
- if (!this._reconnectTimer.running) {
215
- this._reconnectTimer.start(this._nextDelay);
216
- return this._nextDelay = Math.min(this.options.maxdelay, this._nextDelay * 2);
217
- }
218
- };
219
- Connector.prototype.sendCommand = function(command) {
220
- if (this.protocol == null) {
221
- return;
222
- }
223
- return this._sendCommand(command);
224
- };
225
- Connector.prototype._sendCommand = function(command) {
226
- return this.socket.send(JSON.stringify(command));
227
- };
228
- Connector.prototype._closeOnError = function() {
229
- this._handshakeTimeout.stop();
230
- this._disconnectionReason = 'error';
231
- return this.socket.close();
232
- };
233
- Connector.prototype._onopen = function(e) {
234
- this.handlers.socketConnected();
235
- this._disconnectionReason = 'handshake-failed';
236
- this._sendCommand({
237
- command: 'hello',
238
- protocols: [PROTOCOL_6, PROTOCOL_7]
239
- });
240
- return this._handshakeTimeout.start(this.options.handshake_timeout);
241
- };
242
- Connector.prototype._onclose = function(e) {
243
- this.handlers.disconnected(this._disconnectionReason, this._nextDelay);
244
- return this._scheduleReconnection();
245
- };
246
- Connector.prototype._onerror = function(e) {};
247
- Connector.prototype._onmessage = function(e) {
248
- return this.protocolParser.process(e.data);
249
- };
250
- return Connector;
251
- })();
252
- }).call(this);
167
+ return this.connect();
168
+ }, this));
169
+ this.connect();
170
+ }
171
+ Connector.prototype._isSocketConnected = function() {
172
+ return this.socket && this.socket.readyState === this.WebSocket.OPEN;
173
+ };
174
+ Connector.prototype.connect = function() {
175
+ this._connectionDesired = true;
176
+ if (this._isSocketConnected()) {
177
+ return;
178
+ }
179
+ if (this._reconnectTimer) {
180
+ clearTimeout(this._reconnectTimer);
181
+ }
182
+ this._disconnectionReason = 'cannot-connect';
183
+ this.protocolParser.reset();
184
+ this.handlers.connecting();
185
+ this.socket = new this.WebSocket(this._uri);
186
+ this.socket.onopen = __bind(function(e) {
187
+ return this._onopen(e);
188
+ }, this);
189
+ this.socket.onclose = __bind(function(e) {
190
+ return this._onclose(e);
191
+ }, this);
192
+ this.socket.onmessage = __bind(function(e) {
193
+ return this._onmessage(e);
194
+ }, this);
195
+ return this.socket.onerror = __bind(function(e) {
196
+ return this._onerror(e);
197
+ }, this);
198
+ };
199
+ Connector.prototype.disconnect = function() {
200
+ this._connectionDesired = false;
201
+ this._reconnectTimer.stop();
202
+ if (!this._isSocketConnected()) {
203
+ return;
204
+ }
205
+ this._disconnectionReason = 'manual';
206
+ return this.socket.close();
207
+ };
208
+ Connector.prototype._scheduleReconnection = function() {
209
+ if (!this._connectionDesired) {
210
+ return;
211
+ }
212
+ if (!this._reconnectTimer.running) {
213
+ this._reconnectTimer.start(this._nextDelay);
214
+ return this._nextDelay = Math.min(this.options.maxdelay, this._nextDelay * 2);
215
+ }
216
+ };
217
+ Connector.prototype.sendCommand = function(command) {
218
+ if (this.protocol == null) {
219
+ return;
220
+ }
221
+ return this._sendCommand(command);
222
+ };
223
+ Connector.prototype._sendCommand = function(command) {
224
+ return this.socket.send(JSON.stringify(command));
225
+ };
226
+ Connector.prototype._closeOnError = function() {
227
+ this._handshakeTimeout.stop();
228
+ this._disconnectionReason = 'error';
229
+ return this.socket.close();
230
+ };
231
+ Connector.prototype._onopen = function(e) {
232
+ var hello;
233
+ this.handlers.socketConnected();
234
+ this._disconnectionReason = 'handshake-failed';
235
+ hello = {
236
+ command: 'hello',
237
+ protocols: [PROTOCOL_6, PROTOCOL_7]
238
+ };
239
+ hello.ver = Version;
240
+ if (this.options.ext) {
241
+ hello.ext = this.options.ext;
242
+ }
243
+ if (this.options.extver) {
244
+ hello.extver = this.options.extver;
245
+ }
246
+ if (this.options.snipver) {
247
+ hello.snipver = this.options.snipver;
248
+ }
249
+ this._sendCommand(hello);
250
+ return this._handshakeTimeout.start(this.options.handshake_timeout);
251
+ };
252
+ Connector.prototype._onclose = function(e) {
253
+ this.protocol = 0;
254
+ this.handlers.disconnected(this._disconnectionReason, this._nextDelay);
255
+ return this._scheduleReconnection();
256
+ };
257
+ Connector.prototype._onerror = function(e) {};
258
+ Connector.prototype._onmessage = function(e) {
259
+ return this.protocolParser.process(e.data);
260
+ };
261
+ return Connector;
262
+ })();
253
263
 
254
264
  // timer
255
- (function() {
256
- var Timer;
257
- var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
258
- __timer.Timer = Timer = (function() {
259
- function Timer(func) {
260
- this.func = func;
265
+ var Timer;
266
+ var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
267
+ __timer.Timer = Timer = (function() {
268
+ function Timer(func) {
269
+ this.func = func;
270
+ this.running = false;
271
+ this.id = null;
272
+ this._handler = __bind(function() {
261
273
  this.running = false;
262
274
  this.id = null;
263
- this._handler = __bind(function() {
264
- this.running = false;
265
- this.id = null;
266
- return this.func();
267
- }, this);
268
- }
269
- Timer.prototype.start = function(timeout) {
270
- if (this.running) {
271
- clearTimeout(this.id);
272
- }
273
- this.id = setTimeout(this._handler, timeout);
274
- return this.running = true;
275
- };
276
- Timer.prototype.stop = function() {
277
- if (this.running) {
278
- clearTimeout(this.id);
279
- this.running = false;
280
- return this.id = null;
281
- }
282
- };
283
- return Timer;
284
- })();
285
- Timer.start = function(timeout, func) {
286
- return setTimeout(func, timeout);
275
+ return this.func();
276
+ }, this);
277
+ }
278
+ Timer.prototype.start = function(timeout) {
279
+ if (this.running) {
280
+ clearTimeout(this.id);
281
+ }
282
+ this.id = setTimeout(this._handler, timeout);
283
+ return this.running = true;
284
+ };
285
+ Timer.prototype.stop = function() {
286
+ if (this.running) {
287
+ clearTimeout(this.id);
288
+ this.running = false;
289
+ return this.id = null;
290
+ }
287
291
  };
288
- }).call(this);
292
+ return Timer;
293
+ })();
294
+ Timer.start = function(timeout, func) {
295
+ return setTimeout(func, timeout);
296
+ };
289
297
 
290
298
  // options
291
- (function() {
292
- var Options;
293
- __options.Options = Options = (function() {
294
- function Options() {
295
- this.host = null;
296
- this.port = 35729;
297
- this.snipver = null;
298
- this.ext = null;
299
- this.extver = null;
300
- this.mindelay = 1000;
301
- this.maxdelay = 60000;
302
- this.handshake_timeout = 5000;
303
- }
304
- Options.prototype.set = function(name, value) {
305
- switch (typeof this[name]) {
306
- case 'undefined':
307
- break;
308
- case 'number':
309
- return this[name] = +value;
310
- default:
311
- return this[name] = value;
312
- }
313
- };
314
- return Options;
315
- })();
316
- Options.extract = function(document) {
317
- var element, keyAndValue, m, mm, options, pair, src, _i, _j, _len, _len2, _ref, _ref2;
318
- _ref = document.getElementsByTagName('script');
319
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
320
- element = _ref[_i];
321
- if ((src = element.src) && (m = src.match(/^[^:]+:\/\/(.*)\/z?livereload\.js(?:\?(.*))?$/))) {
322
- options = new Options();
323
- if (mm = m[1].match(/^([^\/:]+)(?::(\d+))?$/)) {
324
- options.host = mm[1];
325
- if (mm[2]) {
326
- options.port = parseInt(mm[2], 10);
327
- }
299
+ var Options;
300
+ __options.Options = Options = (function() {
301
+ function Options() {
302
+ this.host = null;
303
+ this.port = 35729;
304
+ this.snipver = null;
305
+ this.ext = null;
306
+ this.extver = null;
307
+ this.mindelay = 1000;
308
+ this.maxdelay = 60000;
309
+ this.handshake_timeout = 5000;
310
+ }
311
+ Options.prototype.set = function(name, value) {
312
+ switch (typeof this[name]) {
313
+ case 'undefined':
314
+ break;
315
+ case 'number':
316
+ return this[name] = +value;
317
+ default:
318
+ return this[name] = value;
319
+ }
320
+ };
321
+ return Options;
322
+ })();
323
+ Options.extract = function(document) {
324
+ var element, keyAndValue, m, mm, options, pair, src, _i, _j, _len, _len2, _ref, _ref2;
325
+ _ref = document.getElementsByTagName('script');
326
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
327
+ element = _ref[_i];
328
+ if ((src = element.src) && (m = src.match(/^[^:]+:\/\/(.*)\/z?livereload\.js(?:\?(.*))?$/))) {
329
+ options = new Options();
330
+ if (mm = m[1].match(/^([^\/:]+)(?::(\d+))?$/)) {
331
+ options.host = mm[1];
332
+ if (mm[2]) {
333
+ options.port = parseInt(mm[2], 10);
328
334
  }
329
- if (m[2]) {
330
- _ref2 = m[2].split('&');
331
- for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) {
332
- pair = _ref2[_j];
333
- if ((keyAndValue = pair.split('=')).length > 1) {
334
- options.set(keyAndValue[0].replace(/-/g, '_'), keyAndValue.slice(1).join('='));
335
- }
335
+ }
336
+ if (m[2]) {
337
+ _ref2 = m[2].split('&');
338
+ for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) {
339
+ pair = _ref2[_j];
340
+ if ((keyAndValue = pair.split('=')).length > 1) {
341
+ options.set(keyAndValue[0].replace(/-/g, '_'), keyAndValue.slice(1).join('='));
336
342
  }
337
343
  }
338
- return options;
339
344
  }
345
+ return options;
340
346
  }
341
- return null;
342
- };
343
- }).call(this);
347
+ }
348
+ return null;
349
+ };
344
350
 
345
351
  // reloader
346
- (function() {
347
- var IMAGE_STYLES, Reloader, numberOfMatchingSegments, pathFromUrl, pathsMatch, pickBestMatch, splitUrl;
348
- var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
349
- splitUrl = function(url) {
350
- var hash, index, params;
351
- if ((index = url.indexOf('#')) >= 0) {
352
- hash = url.slice(index);
353
- url = url.slice(0, index);
354
- } else {
355
- hash = '';
356
- }
357
- if ((index = url.indexOf('?')) >= 0) {
358
- params = url.slice(index);
359
- url = url.slice(0, index);
360
- } else {
361
- params = '';
362
- }
363
- return {
364
- url: url,
365
- params: params,
366
- hash: hash
367
- };
352
+ var IMAGE_STYLES, Reloader, numberOfMatchingSegments, pathFromUrl, pathsMatch, pickBestMatch, splitUrl;
353
+ var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
354
+ splitUrl = function(url) {
355
+ var hash, index, params;
356
+ if ((index = url.indexOf('#')) >= 0) {
357
+ hash = url.slice(index);
358
+ url = url.slice(0, index);
359
+ } else {
360
+ hash = '';
361
+ }
362
+ if ((index = url.indexOf('?')) >= 0) {
363
+ params = url.slice(index);
364
+ url = url.slice(0, index);
365
+ } else {
366
+ params = '';
367
+ }
368
+ return {
369
+ url: url,
370
+ params: params,
371
+ hash: hash
368
372
  };
369
- pathFromUrl = function(url) {
370
- var path;
371
- url = splitUrl(url).url;
372
- if (url.indexOf('file://') === 0) {
373
- path = url.replace(/^file:\/\/(localhost)?/, '');
374
- } else {
375
- path = url.replace(/^([^:]+:)?\/\/([^:\/]+)(:\d*)?\//, '/');
373
+ };
374
+ pathFromUrl = function(url) {
375
+ var path;
376
+ url = splitUrl(url).url;
377
+ if (url.indexOf('file://') === 0) {
378
+ path = url.replace(/^file:\/\/(localhost)?/, '');
379
+ } else {
380
+ path = url.replace(/^([^:]+:)?\/\/([^:\/]+)(:\d*)?\//, '/');
381
+ }
382
+ return decodeURIComponent(path);
383
+ };
384
+ pickBestMatch = function(path, objects, pathFunc) {
385
+ var bestMatch, object, score, _i, _len;
386
+ bestMatch = {
387
+ score: 0
388
+ };
389
+ for (_i = 0, _len = objects.length; _i < _len; _i++) {
390
+ object = objects[_i];
391
+ score = numberOfMatchingSegments(path, pathFunc(object));
392
+ if (score > bestMatch.score) {
393
+ bestMatch = {
394
+ object: object,
395
+ score: score
396
+ };
376
397
  }
377
- return decodeURIComponent(path);
398
+ }
399
+ if (bestMatch.score > 0) {
400
+ return bestMatch;
401
+ } else {
402
+ return null;
403
+ }
404
+ };
405
+ numberOfMatchingSegments = function(path1, path2) {
406
+ var comps1, comps2, eqCount, len;
407
+ path1 = path1.replace(/^\/+/, '').toLowerCase();
408
+ path2 = path2.replace(/^\/+/, '').toLowerCase();
409
+ if (path1 === path2) {
410
+ return 10000;
411
+ }
412
+ comps1 = path1.split('/').reverse();
413
+ comps2 = path2.split('/').reverse();
414
+ len = Math.min(comps1.length, comps2.length);
415
+ eqCount = 0;
416
+ while (eqCount < len && comps1[eqCount] === comps2[eqCount]) {
417
+ ++eqCount;
418
+ }
419
+ return eqCount;
420
+ };
421
+ pathsMatch = function(path1, path2) {
422
+ return numberOfMatchingSegments(path1, path2) > 0;
423
+ };
424
+ IMAGE_STYLES = [
425
+ {
426
+ selector: 'background',
427
+ styleNames: ['backgroundImage']
428
+ }, {
429
+ selector: 'border',
430
+ styleNames: ['borderImage', 'webkitBorderImage', 'MozBorderImage']
431
+ }
432
+ ];
433
+ __reloader.Reloader = Reloader = (function() {
434
+ function Reloader(window, console, Timer) {
435
+ this.window = window;
436
+ this.console = console;
437
+ this.Timer = Timer;
438
+ this.document = this.window.document;
439
+ this.stylesheetGracePeriod = 200;
440
+ this.importCacheWaitPeriod = 200;
441
+ this.plugins = [];
442
+ }
443
+ Reloader.prototype.addPlugin = function(plugin) {
444
+ return this.plugins.push(plugin);
378
445
  };
379
- pickBestMatch = function(path, objects, pathFunc) {
380
- var bestMatch, object, score, _i, _len;
381
- bestMatch = {
382
- score: 0
383
- };
384
- for (_i = 0, _len = objects.length; _i < _len; _i++) {
385
- object = objects[_i];
386
- score = numberOfMatchingSegments(path, pathFunc(object));
387
- if (score > bestMatch.score) {
388
- bestMatch = {
389
- object: object,
390
- score: score
391
- };
446
+ Reloader.prototype.analyze = function(callback) {
447
+ return results;
448
+ };
449
+ Reloader.prototype.reload = function(path, options) {
450
+ var plugin, _i, _len, _ref;
451
+ _ref = this.plugins;
452
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
453
+ plugin = _ref[_i];
454
+ if (plugin.reload && plugin.reload(path, options)) {
455
+ return;
392
456
  }
393
457
  }
394
- if (bestMatch.score > 0) {
395
- return bestMatch;
396
- } else {
397
- return null;
398
- }
399
- };
400
- numberOfMatchingSegments = function(path1, path2) {
401
- var comps1, comps2, eqCount, len;
402
- path1 = path1.replace(/^\/+/, '').toLowerCase();
403
- path2 = path2.replace(/^\/+/, '').toLowerCase();
404
- if (path1 === path2) {
405
- return 10000;
406
- }
407
- comps1 = path1.split('/').reverse();
408
- comps2 = path2.split('/').reverse();
409
- len = Math.min(comps1.length, comps2.length);
410
- eqCount = 0;
411
- while (eqCount < len && comps1[eqCount] === comps2[eqCount]) {
412
- ++eqCount;
413
- }
414
- return eqCount;
415
- };
416
- pathsMatch = function(path1, path2) {
417
- return numberOfMatchingSegments(path1, path2) > 0;
418
- };
419
- IMAGE_STYLES = [
420
- {
421
- selector: 'background',
422
- styleNames: ['backgroundImage']
423
- }, {
424
- selector: 'border',
425
- styleNames: ['borderImage', 'webkitBorderImage', 'MozBorderImage']
426
- }
427
- ];
428
- __reloader.Reloader = Reloader = (function() {
429
- function Reloader(window, console, Timer) {
430
- this.window = window;
431
- this.console = console;
432
- this.Timer = Timer;
433
- this.document = this.window.document;
434
- this.stylesheetGracePeriod = 200;
435
- this.importCacheWaitPeriod = 200;
436
- }
437
- Reloader.prototype.reload = function(path, options) {
438
- if (options.liveCSS) {
439
- if (path.match(/\.css$/i)) {
440
- if (this.reloadStylesheet(path)) {
441
- return;
442
- }
443
- }
444
- if (path.match(/\.less$/i) && this.window.less && this.window.less.refresh) {
445
- this.window.less.refresh(true);
458
+ if (options.liveCSS) {
459
+ if (path.match(/\.css$/i)) {
460
+ if (this.reloadStylesheet(path)) {
446
461
  return;
447
462
  }
448
463
  }
449
- if (options.liveImg) {
450
- if (path.match(/\.(jpe?g|png|gif)$/i)) {
451
- this.reloadImages(path);
452
- return;
453
- }
464
+ }
465
+ if (options.liveImg) {
466
+ if (path.match(/\.(jpe?g|png|gif)$/i)) {
467
+ this.reloadImages(path);
468
+ return;
454
469
  }
455
- return this.reloadPage();
456
- };
457
- Reloader.prototype.reloadPage = function() {
458
- return this.window.document.location.reload();
459
- };
460
- Reloader.prototype.reloadImages = function(path) {
461
- var expando, img, selector, styleNames, styleSheet, _i, _j, _k, _l, _len, _len2, _len3, _len4, _ref, _ref2, _ref3, _ref4, _results;
462
- expando = this.generateUniqueString();
463
- _ref = this.document.images;
464
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
465
- img = _ref[_i];
466
- if (pathsMatch(path, pathFromUrl(img.src))) {
467
- img.src = this.generateCacheBustUrl(img.src, expando);
470
+ }
471
+ return this.reloadPage();
472
+ };
473
+ Reloader.prototype.reloadPage = function() {
474
+ return this.window.document.location.reload();
475
+ };
476
+ Reloader.prototype.reloadImages = function(path) {
477
+ var expando, img, selector, styleNames, styleSheet, _i, _j, _k, _l, _len, _len2, _len3, _len4, _ref, _ref2, _ref3, _ref4, _results;
478
+ expando = this.generateUniqueString();
479
+ _ref = this.document.images;
480
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
481
+ img = _ref[_i];
482
+ if (pathsMatch(path, pathFromUrl(img.src))) {
483
+ img.src = this.generateCacheBustUrl(img.src, expando);
484
+ }
485
+ }
486
+ if (this.document.querySelectorAll) {
487
+ for (_j = 0, _len2 = IMAGE_STYLES.length; _j < _len2; _j++) {
488
+ _ref2 = IMAGE_STYLES[_j], selector = _ref2.selector, styleNames = _ref2.styleNames;
489
+ _ref3 = this.document.querySelectorAll("[style*=" + selector + "]");
490
+ for (_k = 0, _len3 = _ref3.length; _k < _len3; _k++) {
491
+ img = _ref3[_k];
492
+ this.reloadStyleImages(img.style, styleNames, path, expando);
468
493
  }
469
494
  }
470
- if (this.document.querySelectorAll) {
471
- for (_j = 0, _len2 = IMAGE_STYLES.length; _j < _len2; _j++) {
472
- _ref2 = IMAGE_STYLES[_j], selector = _ref2.selector, styleNames = _ref2.styleNames;
473
- _ref3 = this.document.querySelectorAll("[style*=" + selector + "]");
474
- for (_k = 0, _len3 = _ref3.length; _k < _len3; _k++) {
475
- img = _ref3[_k];
476
- this.reloadStyleImages(img.style, styleNames, path, expando);
495
+ }
496
+ if (this.document.styleSheets) {
497
+ _ref4 = this.document.styleSheets;
498
+ _results = [];
499
+ for (_l = 0, _len4 = _ref4.length; _l < _len4; _l++) {
500
+ styleSheet = _ref4[_l];
501
+ _results.push(this.reloadStylesheetImages(styleSheet, path, expando));
502
+ }
503
+ return _results;
504
+ }
505
+ };
506
+ Reloader.prototype.reloadStylesheetImages = function(styleSheet, path, expando) {
507
+ var rule, rules, styleNames, _i, _j, _len, _len2;
508
+ try {
509
+ rules = styleSheet != null ? styleSheet.cssRules : void 0;
510
+ } catch (e) {
511
+
512
+ }
513
+ if (!rules) {
514
+ return;
515
+ }
516
+ for (_i = 0, _len = rules.length; _i < _len; _i++) {
517
+ rule = rules[_i];
518
+ switch (rule.type) {
519
+ case CSSRule.IMPORT_RULE:
520
+ this.reloadStylesheetImages(rule.styleSheet, path, expando);
521
+ break;
522
+ case CSSRule.STYLE_RULE:
523
+ for (_j = 0, _len2 = IMAGE_STYLES.length; _j < _len2; _j++) {
524
+ styleNames = IMAGE_STYLES[_j].styleNames;
525
+ this.reloadStyleImages(rule.style, styleNames, path, expando);
526
+ }
527
+ break;
528
+ case CSSRule.MEDIA_RULE:
529
+ this.reloadStylesheetImages(rule, path, expando);
530
+ }
531
+ }
532
+ };
533
+ Reloader.prototype.reloadStyleImages = function(style, styleNames, path, expando) {
534
+ var newValue, styleName, value, _i, _len;
535
+ for (_i = 0, _len = styleNames.length; _i < _len; _i++) {
536
+ styleName = styleNames[_i];
537
+ value = style[styleName];
538
+ if (typeof value === 'string') {
539
+ newValue = value.replace(/\burl\s*\(([^)]*)\)/, __bind(function(match, src) {
540
+ if (pathsMatch(path, pathFromUrl(src))) {
541
+ return "url(" + (this.generateCacheBustUrl(src, expando)) + ")";
542
+ } else {
543
+ return match;
477
544
  }
545
+ }, this));
546
+ if (newValue !== value) {
547
+ style[styleName] = newValue;
478
548
  }
479
549
  }
480
- if (this.document.styleSheets) {
481
- _ref4 = this.document.styleSheets;
482
- _results = [];
483
- for (_l = 0, _len4 = _ref4.length; _l < _len4; _l++) {
484
- styleSheet = _ref4[_l];
485
- _results.push(this.reloadStylesheetImages(styleSheet, path, expando));
550
+ }
551
+ };
552
+ Reloader.prototype.reloadStylesheet = function(path) {
553
+ var imported, link, links, match, style, _i, _j, _k, _len, _len2, _len3, _ref;
554
+ links = (function() {
555
+ var _i, _len, _ref, _results;
556
+ _ref = this.document.getElementsByTagName('link');
557
+ _results = [];
558
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
559
+ link = _ref[_i];
560
+ if (link.rel === 'stylesheet' && !link.__LiveReload_pendingRemoval) {
561
+ _results.push(link);
486
562
  }
487
- return _results;
488
563
  }
489
- };
490
- Reloader.prototype.reloadStylesheetImages = function(styleSheet, path, expando) {
491
- var rule, rules, styleNames, _i, _j, _len, _len2;
492
- try {
493
- rules = styleSheet != null ? styleSheet.cssRules : void 0;
494
- } catch (e) {
495
-
564
+ return _results;
565
+ }).call(this);
566
+ imported = [];
567
+ _ref = this.document.getElementsByTagName('style');
568
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
569
+ style = _ref[_i];
570
+ if (style.sheet) {
571
+ this.collectImportedStylesheets(style, style.sheet, imported);
496
572
  }
497
- if (!rules) {
498
- return;
573
+ }
574
+ for (_j = 0, _len2 = links.length; _j < _len2; _j++) {
575
+ link = links[_j];
576
+ this.collectImportedStylesheets(link, link.sheet, imported);
577
+ }
578
+ this.console.log("LiveReload found " + links.length + " LINKed stylesheets, " + imported.length + " @imported stylesheets");
579
+ match = pickBestMatch(path, links.concat(imported), function(l) {
580
+ return pathFromUrl(l.href);
581
+ });
582
+ if (match) {
583
+ if (match.object.rule) {
584
+ this.console.log("LiveReload is reloading imported stylesheet: " + match.object.href);
585
+ this.reattachImportedRule(match.object);
586
+ } else {
587
+ this.console.log("LiveReload is reloading stylesheet: " + match.object.href);
588
+ this.reattachStylesheetLink(match.object);
589
+ }
590
+ } else {
591
+ this.console.log("LiveReload will reload all stylesheets because path '" + path + "' did not match any specific one");
592
+ for (_k = 0, _len3 = links.length; _k < _len3; _k++) {
593
+ link = links[_k];
594
+ this.reattachStylesheetLink(link);
499
595
  }
500
- for (_i = 0, _len = rules.length; _i < _len; _i++) {
501
- rule = rules[_i];
596
+ }
597
+ return true;
598
+ };
599
+ Reloader.prototype.collectImportedStylesheets = function(link, styleSheet, result) {
600
+ var index, rule, rules, _len;
601
+ try {
602
+ rules = styleSheet != null ? styleSheet.cssRules : void 0;
603
+ } catch (e) {
604
+
605
+ }
606
+ if (rules && rules.length) {
607
+ for (index = 0, _len = rules.length; index < _len; index++) {
608
+ rule = rules[index];
502
609
  switch (rule.type) {
610
+ case CSSRule.CHARSET_RULE:
611
+ continue;
503
612
  case CSSRule.IMPORT_RULE:
504
- this.reloadStylesheetImages(rule.styleSheet, path, expando);
613
+ result.push({
614
+ link: link,
615
+ rule: rule,
616
+ index: index,
617
+ href: rule.href
618
+ });
619
+ this.collectImportedStylesheets(link, rule.styleSheet, result);
505
620
  break;
506
- case CSSRule.STYLE_RULE:
507
- for (_j = 0, _len2 = IMAGE_STYLES.length; _j < _len2; _j++) {
508
- styleNames = IMAGE_STYLES[_j].styleNames;
509
- this.reloadStyleImages(rule.style, styleNames, path, expando);
510
- }
621
+ default:
511
622
  break;
512
- case CSSRule.MEDIA_RULE:
513
- this.reloadStylesheetImages(rule, path, expando);
514
623
  }
515
624
  }
516
- };
517
- Reloader.prototype.reloadStyleImages = function(style, styleNames, path, expando) {
518
- var newValue, styleName, value, _i, _len;
519
- for (_i = 0, _len = styleNames.length; _i < _len; _i++) {
520
- styleName = styleNames[_i];
521
- value = style[styleName];
522
- if (typeof value === 'string') {
523
- newValue = value.replace(/\burl\s*\(([^)]*)\)/, __bind(function(match, src) {
524
- if (pathsMatch(path, pathFromUrl(src))) {
525
- return "url(" + (this.generateCacheBustUrl(src, expando)) + ")";
526
- } else {
527
- return match;
528
- }
529
- }, this));
530
- if (newValue !== value) {
531
- style[styleName] = newValue;
532
- }
533
- }
534
- }
535
- };
536
- Reloader.prototype.reloadStylesheet = function(path) {
537
- var imported, link, links, match, _i, _j, _len, _len2;
538
- links = (function() {
539
- var _i, _len, _ref, _results;
540
- _ref = this.document.getElementsByTagName('link');
541
- _results = [];
542
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
543
- link = _ref[_i];
544
- if (link.rel === 'stylesheet' && !link.__LiveReload_pendingRemoval) {
545
- _results.push(link);
546
- }
547
- }
548
- return _results;
549
- }).call(this);
550
- imported = [];
551
- for (_i = 0, _len = links.length; _i < _len; _i++) {
552
- link = links[_i];
553
- this.collectImportedStylesheets(link, link.sheet, imported);
554
- }
555
- this.console.log("LiveReload found " + links.length + " LINKed stylesheets, " + imported.length + " @imported stylesheets");
556
- match = pickBestMatch(path, links.concat(imported), function(l) {
557
- return pathFromUrl(l.href);
558
- });
559
- if (match) {
560
- if (match.object.rule) {
561
- this.console.log("LiveReload is reloading imported stylesheet: " + match.object.href);
562
- this.reattachImportedRule(match.object);
563
- } else {
564
- this.console.log("LiveReload is reloading stylesheet: " + match.object.href);
565
- this.reattachStylesheetLink(match.object);
566
- }
567
- } else {
568
- this.console.log("LiveReload will reload all stylesheets because path '" + path + "' did not match any specific one");
569
- for (_j = 0, _len2 = links.length; _j < _len2; _j++) {
570
- link = links[_j];
571
- this.reattachStylesheetLink(link);
572
- }
573
- }
574
- return true;
575
- };
576
- Reloader.prototype.collectImportedStylesheets = function(link, styleSheet, result) {
577
- var index, rule, rules, _len;
578
- try {
579
- rules = styleSheet != null ? styleSheet.cssRules : void 0;
580
- } catch (e) {
581
-
625
+ }
626
+ };
627
+ Reloader.prototype.reattachStylesheetLink = function(link) {
628
+ var clone, parent, timer;
629
+ if (link.__LiveReload_pendingRemoval) {
630
+ return;
631
+ }
632
+ link.__LiveReload_pendingRemoval = true;
633
+ clone = link.cloneNode(false);
634
+ clone.href = this.generateCacheBustUrl(link.href);
635
+ parent = link.parentNode;
636
+ if (parent.lastChild === link) {
637
+ parent.appendChild(clone);
638
+ } else {
639
+ parent.insertBefore(clone, link.nextSibling);
640
+ }
641
+ timer = new this.Timer(function() {
642
+ if (link.parentNode) {
643
+ return link.parentNode.removeChild(link);
582
644
  }
583
- if (rules && rules.length) {
584
- for (index = 0, _len = rules.length; index < _len; index++) {
585
- rule = rules[index];
586
- switch (rule.type) {
587
- case CSSRule.CHARSET_RULE:
588
- continue;
589
- case CSSRule.IMPORT_RULE:
590
- result.push({
591
- link: link,
592
- rule: rule,
593
- index: index,
594
- href: rule.href
595
- });
596
- this.collectImportedStylesheets(link, rule.styleSheet, result);
597
- break;
598
- default:
599
- break;
600
- }
601
- }
645
+ });
646
+ return timer.start(this.stylesheetGracePeriod);
647
+ };
648
+ Reloader.prototype.reattachImportedRule = function(_arg) {
649
+ var href, index, link, media, newRule, parent, rule, tempLink;
650
+ rule = _arg.rule, index = _arg.index, link = _arg.link;
651
+ parent = rule.parentStyleSheet;
652
+ href = this.generateCacheBustUrl(rule.href);
653
+ media = rule.media.length ? [].join.call(rule.media, ', ') : '';
654
+ newRule = "@import url(\"" + href + "\") " + media + ";";
655
+ rule.__LiveReload_newHref = href;
656
+ tempLink = this.document.createElement("link");
657
+ tempLink.rel = 'stylesheet';
658
+ tempLink.href = href;
659
+ tempLink.__LiveReload_pendingRemoval = true;
660
+ if (link.parentNode) {
661
+ link.parentNode.insertBefore(tempLink, link);
662
+ }
663
+ return this.Timer.start(this.importCacheWaitPeriod, __bind(function() {
664
+ if (tempLink.parentNode) {
665
+ tempLink.parentNode.removeChild(tempLink);
602
666
  }
603
- };
604
- Reloader.prototype.reattachStylesheetLink = function(link) {
605
- var clone, parent, timer;
606
- if (link.__LiveReload_pendingRemoval) {
667
+ if (rule.__LiveReload_newHref !== href) {
607
668
  return;
608
669
  }
609
- link.__LiveReload_pendingRemoval = true;
610
- clone = link.cloneNode(false);
611
- clone.href = this.generateCacheBustUrl(link.href);
612
- parent = link.parentNode;
613
- if (parent.lastChild === link) {
614
- parent.appendChild(clone);
615
- } else {
616
- parent.insertBefore(clone, link.nextSibling);
617
- }
618
- timer = new this.Timer(function() {
619
- if (link.parentNode) {
620
- return link.parentNode.removeChild(link);
621
- }
622
- });
623
- return timer.start(this.stylesheetGracePeriod);
624
- };
625
- Reloader.prototype.reattachImportedRule = function(_arg) {
626
- var href, index, link, media, newRule, parent, rule, tempLink;
627
- rule = _arg.rule, index = _arg.index, link = _arg.link;
628
- parent = rule.parentStyleSheet;
629
- href = this.generateCacheBustUrl(rule.href);
630
- media = rule.media.length ? [].join.call(rule.media, ', ') : '';
631
- newRule = "@import url(\"" + href + "\") " + media + ";";
670
+ parent.insertRule(newRule, index);
671
+ parent.deleteRule(index + 1);
672
+ rule = parent.cssRules[index];
632
673
  rule.__LiveReload_newHref = href;
633
- tempLink = this.document.createElement("link");
634
- tempLink.rel = 'stylesheet';
635
- tempLink.href = href;
636
- tempLink.__LiveReload_pendingRemoval = true;
637
- if (link.parentNode) {
638
- link.parentNode.insertBefore(tempLink, link);
639
- }
640
674
  return this.Timer.start(this.importCacheWaitPeriod, __bind(function() {
641
- if (tempLink.parentNode) {
642
- tempLink.parentNode.removeChild(tempLink);
643
- }
644
675
  if (rule.__LiveReload_newHref !== href) {
645
676
  return;
646
677
  }
647
678
  parent.insertRule(newRule, index);
648
- parent.deleteRule(index + 1);
649
- rule = parent.cssRules[index];
650
- rule.__LiveReload_newHref = href;
651
- return this.Timer.start(this.importCacheWaitPeriod, __bind(function() {
652
- if (rule.__LiveReload_newHref !== href) {
653
- return;
654
- }
655
- parent.insertRule(newRule, index);
656
- return parent.deleteRule(index + 1);
657
- }, this));
679
+ return parent.deleteRule(index + 1);
658
680
  }, this));
659
- };
660
- Reloader.prototype.generateUniqueString = function() {
661
- return 'livereload=' + Date.now();
662
- };
663
- Reloader.prototype.generateCacheBustUrl = function(url, expando) {
664
- var hash, oldParams, params, _ref;
665
- if (expando == null) {
666
- expando = this.generateUniqueString();
681
+ }, this));
682
+ };
683
+ Reloader.prototype.generateUniqueString = function() {
684
+ return 'livereload=' + Date.now();
685
+ };
686
+ Reloader.prototype.generateCacheBustUrl = function(url, expando) {
687
+ var hash, oldParams, params, _ref;
688
+ if (expando == null) {
689
+ expando = this.generateUniqueString();
690
+ }
691
+ _ref = splitUrl(url), url = _ref.url, hash = _ref.hash, oldParams = _ref.params;
692
+ params = oldParams.replace(/(\?|&)livereload=(\d+)/, function(match, sep) {
693
+ return "" + sep + expando;
694
+ });
695
+ if (params === oldParams) {
696
+ if (oldParams.length === 0) {
697
+ params = "?" + expando;
698
+ } else {
699
+ params = "" + oldParams + "&" + expando;
667
700
  }
668
- _ref = splitUrl(url), url = _ref.url, hash = _ref.hash, oldParams = _ref.params;
669
- params = oldParams.replace(/(\?|&)livereload=(\d+)/, function(match, sep) {
670
- return "" + sep + expando;
671
- });
672
- if (params === oldParams) {
673
- if (oldParams.length === 0) {
674
- params = "?" + expando;
701
+ }
702
+ return url + params + hash;
703
+ };
704
+ return Reloader;
705
+ })();
706
+
707
+ // livereload
708
+ var Connector, LiveReload, Options, Reloader, Timer;
709
+ var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
710
+ Connector = __connector.Connector;
711
+ Timer = __timer.Timer;
712
+ Options = __options.Options;
713
+ Reloader = __reloader.Reloader;
714
+ __livereload.LiveReload = LiveReload = (function() {
715
+ function LiveReload(window) {
716
+ this.window = window;
717
+ this.listeners = {};
718
+ this.plugins = [];
719
+ this.pluginIdentifiers = {};
720
+ this.console = this.window.console && this.window.console.log && this.window.console.error ? this.window.console : {
721
+ log: function() {},
722
+ error: function() {}
723
+ };
724
+ if (!(this.WebSocket = this.window.WebSocket || this.window.MozWebSocket)) {
725
+ console.error("LiveReload disabled because the browser does not seem to support web sockets");
726
+ return;
727
+ }
728
+ if (!(this.options = Options.extract(this.window.document))) {
729
+ console.error("LiveReload disabled because it could not find its own <SCRIPT> tag");
730
+ return;
731
+ }
732
+ this.reloader = new Reloader(this.window, this.console, Timer);
733
+ this.connector = new Connector(this.options, this.WebSocket, Timer, {
734
+ connecting: __bind(function() {}, this),
735
+ socketConnected: __bind(function() {}, this),
736
+ connected: __bind(function(protocol) {
737
+ var _base;
738
+ if (typeof (_base = this.listeners).connect === "function") {
739
+ _base.connect();
740
+ }
741
+ this.log("LiveReload is connected to " + this.options.host + ":" + this.options.port + " (protocol v" + protocol + ").");
742
+ return this.analyze();
743
+ }, this),
744
+ error: __bind(function(e) {
745
+ if (e instanceof ProtocolError) {
746
+ return console.log("" + e.message + ".");
675
747
  } else {
676
- params = "" + oldParams + "&" + expando;
748
+ return console.log("LiveReload internal error: " + e.message);
677
749
  }
678
- }
679
- return url + params + hash;
680
- };
681
- return Reloader;
682
- })();
683
- }).call(this);
750
+ }, this),
751
+ disconnected: __bind(function(reason, nextDelay) {
752
+ var _base;
753
+ if (typeof (_base = this.listeners).disconnect === "function") {
754
+ _base.disconnect();
755
+ }
756
+ switch (reason) {
757
+ case 'cannot-connect':
758
+ return this.log("LiveReload cannot connect to " + this.options.host + ":" + this.options.port + ", will retry in " + nextDelay + " sec.");
759
+ case 'broken':
760
+ return this.log("LiveReload disconnected from " + this.options.host + ":" + this.options.port + ", reconnecting in " + nextDelay + " sec.");
761
+ case 'handshake-timeout':
762
+ return this.log("LiveReload cannot connect to " + this.options.host + ":" + this.options.port + " (handshake timeout), will retry in " + nextDelay + " sec.");
763
+ case 'handshake-failed':
764
+ return this.log("LiveReload cannot connect to " + this.options.host + ":" + this.options.port + " (handshake failed), will retry in " + nextDelay + " sec.");
765
+ case 'manual':
766
+ break;
767
+ case 'error':
768
+ break;
769
+ default:
770
+ return this.log("LiveReload disconnected from " + this.options.host + ":" + this.options.port + " (" + reason + "), reconnecting in " + nextDelay + " sec.");
771
+ }
772
+ }, this),
773
+ message: __bind(function(message) {
774
+ switch (message.command) {
775
+ case 'reload':
776
+ return this.performReload(message);
777
+ case 'alert':
778
+ return this.performAlert(message);
779
+ }
780
+ }, this)
781
+ });
782
+ }
783
+ LiveReload.prototype.on = function(eventName, handler) {
784
+ return this.listeners[eventName] = handler;
785
+ };
786
+ LiveReload.prototype.log = function(message) {
787
+ return this.console.log("" + message);
788
+ };
789
+ LiveReload.prototype.performReload = function(message) {
790
+ var _ref, _ref2;
791
+ this.log("LiveReload received reload request for " + message.path + ".");
792
+ return this.reloader.reload(message.path, {
793
+ liveCSS: (_ref = message.liveCSS) != null ? _ref : true,
794
+ liveImg: (_ref2 = message.liveImg) != null ? _ref2 : true,
795
+ originalPath: message.originalPath || ''
796
+ });
797
+ };
798
+ LiveReload.prototype.performAlert = function(message) {
799
+ return alert(message.message);
800
+ };
801
+ LiveReload.prototype.shutDown = function() {
802
+ var _base;
803
+ this.connector.disconnect();
804
+ this.log("LiveReload disconnected.");
805
+ return typeof (_base = this.listeners).shutdown === "function" ? _base.shutdown() : void 0;
806
+ };
807
+ LiveReload.prototype.hasPlugin = function(identifier) {
808
+ return !!this.pluginIdentifiers[identifier];
809
+ };
810
+ LiveReload.prototype.addPlugin = function(pluginClass) {
811
+ var plugin;
812
+ if (this.hasPlugin(pluginClass.identifier)) {
813
+ return;
814
+ }
815
+ this.pluginIdentifiers[pluginClass.identifier] = true;
816
+ plugin = new pluginClass(this.window, {
817
+ _livereload: this,
818
+ _reloader: this.reloader,
819
+ _connector: this.connector,
820
+ console: this.console,
821
+ Timer: Timer,
822
+ generateCacheBustUrl: __bind(function(url) {
823
+ return this.reloader.generateCacheBustUrl(url);
824
+ }, this)
825
+ });
826
+ this.plugins.push(plugin);
827
+ this.reloader.addPlugin(plugin);
828
+ };
829
+ LiveReload.prototype.analyze = function() {
830
+ var plugin, pluginData, pluginsData, _i, _len, _ref;
831
+ if (!(this.connector.protocol >= 7)) {
832
+ return;
833
+ }
834
+ pluginsData = {};
835
+ _ref = this.plugins;
836
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
837
+ plugin = _ref[_i];
838
+ pluginsData[plugin.constructor.identifier] = pluginData = (typeof plugin.analyze === "function" ? plugin.analyze() : void 0) || {};
839
+ pluginData.version = plugin.constructor.version;
840
+ }
841
+ this.connector.sendCommand({
842
+ command: 'info',
843
+ plugins: pluginsData,
844
+ url: this.window.location.href
845
+ });
846
+ };
847
+ return LiveReload;
848
+ })();
684
849
 
685
- // livereload
686
- (function() {
687
- var Connector, LiveReload, Options, Reloader, Timer;
688
- var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
689
- Connector = __connector.Connector;
690
- Timer = __timer.Timer;
691
- Options = __options.Options;
692
- Reloader = __reloader.Reloader;
693
- __livereload.LiveReload = LiveReload = (function() {
694
- function LiveReload(window) {
695
- this.window = window;
696
- this.listeners = {};
697
- this.console = this.window.console && this.window.console.log && this.window.console.error ? this.window.console : {
698
- log: function() {},
699
- error: function() {}
700
- };
701
- if (!(this.WebSocket = this.window.WebSocket || this.window.MozWebSocket)) {
702
- console.error("LiveReload disabled because the browser does not seem to support web sockets");
703
- return;
850
+ // less
851
+ var LessPlugin;
852
+ __less = LessPlugin = (function() {
853
+ LessPlugin.identifier = 'less';
854
+ LessPlugin.version = '1.0';
855
+ function LessPlugin(window, host) {
856
+ this.window = window;
857
+ this.host = host;
858
+ }
859
+ LessPlugin.prototype.reload = function(path, options) {
860
+ if (this.window.less && this.window.less.refresh) {
861
+ if (path.match(/\.less$/i)) {
862
+ return this.reloadLess(path);
863
+ }
864
+ if (options.originalPath.match(/\.less$/i)) {
865
+ return this.reloadLess(options.originalPath);
704
866
  }
705
- if (!(this.options = Options.extract(this.window.document))) {
706
- console.error("LiveReload disabled because it could not find its own <SCRIPT> tag");
707
- return;
867
+ }
868
+ return false;
869
+ };
870
+ LessPlugin.prototype.reloadLess = function(path) {
871
+ var link, links, _i, _len;
872
+ links = (function() {
873
+ var _i, _len, _ref, _results;
874
+ _ref = document.getElementsByTagName('link');
875
+ _results = [];
876
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
877
+ link = _ref[_i];
878
+ if (link.href && link.rel === 'stylesheet/less' || (link.rel.match(/stylesheet/) && link.type.match(/^text\/(x-)?less$/))) {
879
+ _results.push(link);
880
+ }
708
881
  }
709
- this.reloader = new Reloader(this.window, this.console, Timer);
710
- this.connector = new Connector(this.options, this.WebSocket, Timer, {
711
- connecting: __bind(function() {}, this),
712
- socketConnected: __bind(function() {}, this),
713
- connected: __bind(function(protocol) {
714
- var _base;
715
- if (typeof (_base = this.listeners).connect === "function") {
716
- _base.connect();
717
- }
718
- return this.log("LiveReload is connected to " + this.options.host + ":" + this.options.port + " (protocol v" + protocol + ").");
719
- }, this),
720
- error: __bind(function(e) {
721
- if (e instanceof ProtocolError) {
722
- return console.log("" + e.message + ".");
723
- } else {
724
- return console.log("LiveReload internal error: " + e.message);
725
- }
726
- }, this),
727
- disconnected: __bind(function(reason, nextDelay) {
728
- var _base;
729
- if (typeof (_base = this.listeners).disconnect === "function") {
730
- _base.disconnect();
731
- }
732
- switch (reason) {
733
- case 'cannot-connect':
734
- return this.log("LiveReload cannot connect to " + this.options.host + ":" + this.options.port + ", will retry in " + nextDelay + " sec.");
735
- case 'broken':
736
- return this.log("LiveReload disconnected from " + this.options.host + ":" + this.options.port + ", reconnecting in " + nextDelay + " sec.");
737
- case 'handshake-timeout':
738
- return this.log("LiveReload cannot connect to " + this.options.host + ":" + this.options.port + " (handshake timeout), will retry in " + nextDelay + " sec.");
739
- case 'handshake-failed':
740
- return this.log("LiveReload cannot connect to " + this.options.host + ":" + this.options.port + " (handshake failed), will retry in " + nextDelay + " sec.");
741
- case 'manual':
742
- break;
743
- case 'error':
744
- break;
745
- default:
746
- return this.log("LiveReload disconnected from " + this.options.host + ":" + this.options.port + " (" + reason + "), reconnecting in " + nextDelay + " sec.");
747
- }
748
- }, this),
749
- message: __bind(function(message) {
750
- switch (message.command) {
751
- case 'reload':
752
- return this.performReload(message);
753
- case 'alert':
754
- return this.performAlert(message);
755
- }
756
- }, this)
757
- });
882
+ return _results;
883
+ })();
884
+ if (links.length === 0) {
885
+ return false;
758
886
  }
759
- LiveReload.prototype.on = function(eventName, handler) {
760
- return this.listeners[eventName] = handler;
761
- };
762
- LiveReload.prototype.log = function(message) {
763
- return this.console.log("" + message);
764
- };
765
- LiveReload.prototype.performReload = function(message) {
766
- var _ref, _ref2;
767
- this.log("LiveReload received reload request for " + message.path + ".");
768
- return this.reloader.reload(message.path, {
769
- liveCSS: (_ref = message.liveCSS) != null ? _ref : true,
770
- liveImg: (_ref2 = message.liveImg) != null ? _ref2 : true
771
- });
772
- };
773
- LiveReload.prototype.performAlert = function(message) {
774
- return alert(message.message);
775
- };
776
- LiveReload.prototype.shutDown = function() {
777
- var _base;
778
- this.connector.disconnect();
779
- this.log("LiveReload disconnected.");
780
- return typeof (_base = this.listeners).shutdown === "function" ? _base.shutdown() : void 0;
887
+ for (_i = 0, _len = links.length; _i < _len; _i++) {
888
+ link = links[_i];
889
+ link.href = this.host.generateCacheBustUrl(link.href);
890
+ }
891
+ this.host.console.log("LiveReload is asking LESS to recompile all stylesheets");
892
+ this.window.less.refresh(true);
893
+ return true;
894
+ };
895
+ LessPlugin.prototype.analyze = function() {
896
+ return {
897
+ disable: !!(this.window.less && this.window.less.refresh)
781
898
  };
782
- return LiveReload;
783
- })();
784
- }).call(this);
899
+ };
900
+ return LessPlugin;
901
+ })();
785
902
 
786
903
  // startup
787
- (function() {
788
- var CustomEvents, LiveReload;
789
- CustomEvents = __customevents;
790
- LiveReload = window.LiveReload = new (__livereload.LiveReload)(window);
791
- LiveReload.on('shutdown', function() {
792
- return delete window.LiveReload;
793
- });
794
- LiveReload.on('connect', function() {
795
- return CustomEvents.fire(document, 'LiveReloadConnect');
796
- });
797
- LiveReload.on('disconnect', function() {
798
- return CustomEvents.fire(document, 'LiveReloadDisconnect');
799
- });
800
- CustomEvents.bind(document, 'LiveReloadShutDown', function() {
801
- return LiveReload.shutDown();
802
- });
803
- }).call(this);
904
+ var CustomEvents, LiveReload, k, v;
905
+ CustomEvents = __customevents;
906
+ LiveReload = window.LiveReload = new (__livereload.LiveReload)(window);
907
+ for (k in window) {
908
+ v = window[k];
909
+ if (k.match(/^LiveReloadPlugin/)) {
910
+ LiveReload.addPlugin(v);
911
+ }
912
+ }
913
+ LiveReload.addPlugin(__less);
914
+ LiveReload.on('shutdown', function() {
915
+ return delete window.LiveReload;
916
+ });
917
+ LiveReload.on('connect', function() {
918
+ return CustomEvents.fire(document, 'LiveReloadConnect');
919
+ });
920
+ LiveReload.on('disconnect', function() {
921
+ return CustomEvents.fire(document, 'LiveReloadDisconnect');
922
+ });
923
+ CustomEvents.bind(document, 'LiveReloadShutDown', function() {
924
+ return LiveReload.shutDown();
925
+ });
804
926
  })();