blob: 3c24b5ddba2da713f5e7a1ca29f3473cd623cb4c [file] [log] [blame]
Leo Repp58b9f112021-11-22 11:57:47 +01001(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
2(function() {
3 var Connector, PROTOCOL_6, PROTOCOL_7, Parser, Version, ref;
4
5 ref = require('./protocol'), Parser = ref.Parser, PROTOCOL_6 = ref.PROTOCOL_6, PROTOCOL_7 = ref.PROTOCOL_7;
6
7 Version = "2.4.0";
8
9 exports.Connector = Connector = (function() {
10 function Connector(options, WebSocket, Timer, handlers) {
11 var path;
12 this.options = options;
13 this.WebSocket = WebSocket;
14 this.Timer = Timer;
15 this.handlers = handlers;
16 path = this.options.path ? "" + this.options.path : "livereload";
17 this._uri = "ws" + (this.options.https ? "s" : "") + "://" + this.options.host + ":" + this.options.port + "/" + path;
18 this._nextDelay = this.options.mindelay;
19 this._connectionDesired = false;
20 this.protocol = 0;
21 this.protocolParser = new Parser({
22 connected: (function(_this) {
23 return function(protocol) {
24 _this.protocol = protocol;
25 _this._handshakeTimeout.stop();
26 _this._nextDelay = _this.options.mindelay;
27 _this._disconnectionReason = 'broken';
28 return _this.handlers.connected(_this.protocol);
29 };
30 })(this),
31 error: (function(_this) {
32 return function(e) {
33 _this.handlers.error(e);
34 return _this._closeOnError();
35 };
36 })(this),
37 message: (function(_this) {
38 return function(message) {
39 return _this.handlers.message(message);
40 };
41 })(this)
42 });
43 this._handshakeTimeout = new this.Timer((function(_this) {
44 return function() {
45 if (!_this._isSocketConnected()) {
46 return;
47 }
48 _this._disconnectionReason = 'handshake-timeout';
49 return _this.socket.close();
50 };
51 })(this));
52 this._reconnectTimer = new this.Timer((function(_this) {
53 return function() {
54 if (!_this._connectionDesired) {
55 return;
56 }
57 return _this.connect();
58 };
59 })(this));
60 this.connect();
61 }
62
63 Connector.prototype._isSocketConnected = function() {
64 return this.socket && this.socket.readyState === this.WebSocket.OPEN;
65 };
66
67 Connector.prototype.connect = function() {
68 this._connectionDesired = true;
69 if (this._isSocketConnected()) {
70 return;
71 }
72 this._reconnectTimer.stop();
73 this._disconnectionReason = 'cannot-connect';
74 this.protocolParser.reset();
75 this.handlers.connecting();
76 this.socket = new this.WebSocket(this._uri);
77 this.socket.onopen = (function(_this) {
78 return function(e) {
79 return _this._onopen(e);
80 };
81 })(this);
82 this.socket.onclose = (function(_this) {
83 return function(e) {
84 return _this._onclose(e);
85 };
86 })(this);
87 this.socket.onmessage = (function(_this) {
88 return function(e) {
89 return _this._onmessage(e);
90 };
91 })(this);
92 return this.socket.onerror = (function(_this) {
93 return function(e) {
94 return _this._onerror(e);
95 };
96 })(this);
97 };
98
99 Connector.prototype.disconnect = function() {
100 this._connectionDesired = false;
101 this._reconnectTimer.stop();
102 if (!this._isSocketConnected()) {
103 return;
104 }
105 this._disconnectionReason = 'manual';
106 return this.socket.close();
107 };
108
109 Connector.prototype._scheduleReconnection = function() {
110 if (!this._connectionDesired) {
111 return;
112 }
113 if (!this._reconnectTimer.running) {
114 this._reconnectTimer.start(this._nextDelay);
115 return this._nextDelay = Math.min(this.options.maxdelay, this._nextDelay * 2);
116 }
117 };
118
119 Connector.prototype.sendCommand = function(command) {
120 if (this.protocol == null) {
121 return;
122 }
123 return this._sendCommand(command);
124 };
125
126 Connector.prototype._sendCommand = function(command) {
127 return this.socket.send(JSON.stringify(command));
128 };
129
130 Connector.prototype._closeOnError = function() {
131 this._handshakeTimeout.stop();
132 this._disconnectionReason = 'error';
133 return this.socket.close();
134 };
135
136 Connector.prototype._onopen = function(e) {
137 var hello;
138 this.handlers.socketConnected();
139 this._disconnectionReason = 'handshake-failed';
140 hello = {
141 command: 'hello',
142 protocols: [PROTOCOL_6, PROTOCOL_7]
143 };
144 hello.ver = Version;
145 if (this.options.ext) {
146 hello.ext = this.options.ext;
147 }
148 if (this.options.extver) {
149 hello.extver = this.options.extver;
150 }
151 if (this.options.snipver) {
152 hello.snipver = this.options.snipver;
153 }
154 this._sendCommand(hello);
155 return this._handshakeTimeout.start(this.options.handshake_timeout);
156 };
157
158 Connector.prototype._onclose = function(e) {
159 this.protocol = 0;
160 this.handlers.disconnected(this._disconnectionReason, this._nextDelay);
161 return this._scheduleReconnection();
162 };
163
164 Connector.prototype._onerror = function(e) {};
165
166 Connector.prototype._onmessage = function(e) {
167 return this.protocolParser.process(e.data);
168 };
169
170 return Connector;
171
172 })();
173
174}).call(this);
175
176},{"./protocol":6}],2:[function(require,module,exports){
177(function() {
178 var CustomEvents;
179
180 CustomEvents = {
181 bind: function(element, eventName, handler) {
182 if (element.addEventListener) {
183 return element.addEventListener(eventName, handler, false);
184 } else if (element.attachEvent) {
185 element[eventName] = 1;
186 return element.attachEvent('onpropertychange', function(event) {
187 if (event.propertyName === eventName) {
188 return handler();
189 }
190 });
191 } else {
192 throw new Error("Attempt to attach custom event " + eventName + " to something which isn't a DOMElement");
193 }
194 },
195 fire: function(element, eventName) {
196 var event;
197 if (element.addEventListener) {
198 event = document.createEvent('HTMLEvents');
199 event.initEvent(eventName, true, true);
200 return document.dispatchEvent(event);
201 } else if (element.attachEvent) {
202 if (element[eventName]) {
203 return element[eventName]++;
204 }
205 } else {
206 throw new Error("Attempt to fire custom event " + eventName + " on something which isn't a DOMElement");
207 }
208 }
209 };
210
211 exports.bind = CustomEvents.bind;
212
213 exports.fire = CustomEvents.fire;
214
215}).call(this);
216
217},{}],3:[function(require,module,exports){
218(function() {
219 var LessPlugin;
220
221 module.exports = LessPlugin = (function() {
222 LessPlugin.identifier = 'less';
223
224 LessPlugin.version = '1.0';
225
226 function LessPlugin(window, host) {
227 this.window = window;
228 this.host = host;
229 }
230
231 LessPlugin.prototype.reload = function(path, options) {
232 if (this.window.less && this.window.less.refresh) {
233 if (path.match(/\.less$/i)) {
234 return this.reloadLess(path);
235 }
236 if (options.originalPath.match(/\.less$/i)) {
237 return this.reloadLess(options.originalPath);
238 }
239 }
240 return false;
241 };
242
243 LessPlugin.prototype.reloadLess = function(path) {
244 var i, len, link, links;
245 links = (function() {
246 var i, len, ref, results;
247 ref = document.getElementsByTagName('link');
248 results = [];
249 for (i = 0, len = ref.length; i < len; i++) {
250 link = ref[i];
251 if (link.href && link.rel.match(/^stylesheet\/less$/i) || (link.rel.match(/stylesheet/i) && link.type.match(/^text\/(x-)?less$/i))) {
252 results.push(link);
253 }
254 }
255 return results;
256 })();
257 if (links.length === 0) {
258 return false;
259 }
260 for (i = 0, len = links.length; i < len; i++) {
261 link = links[i];
262 link.href = this.host.generateCacheBustUrl(link.href);
263 }
264 this.host.console.log("LiveReload is asking LESS to recompile all stylesheets");
265 this.window.less.refresh(true);
266 return true;
267 };
268
269 LessPlugin.prototype.analyze = function() {
270 return {
271 disable: !!(this.window.less && this.window.less.refresh)
272 };
273 };
274
275 return LessPlugin;
276
277 })();
278
279}).call(this);
280
281},{}],4:[function(require,module,exports){
282(function() {
283 var Connector, LiveReload, Options, ProtocolError, Reloader, Timer,
284 hasProp = {}.hasOwnProperty;
285
286 Connector = require('./connector').Connector;
287
288 Timer = require('./timer').Timer;
289
290 Options = require('./options').Options;
291
292 Reloader = require('./reloader').Reloader;
293
294 ProtocolError = require('./protocol').ProtocolError;
295
296 exports.LiveReload = LiveReload = (function() {
297 function LiveReload(window1) {
298 var k, ref, v;
299 this.window = window1;
300 this.listeners = {};
301 this.plugins = [];
302 this.pluginIdentifiers = {};
303 this.console = this.window.console && this.window.console.log && this.window.console.error ? this.window.location.href.match(/LR-verbose/) ? this.window.console : {
304 log: function() {},
305 error: this.window.console.error.bind(this.window.console)
306 } : {
307 log: function() {},
308 error: function() {}
309 };
310 if (!(this.WebSocket = this.window.WebSocket || this.window.MozWebSocket)) {
311 this.console.error("LiveReload disabled because the browser does not seem to support web sockets");
312 return;
313 }
314 if ('LiveReloadOptions' in window) {
315 this.options = new Options();
316 ref = window['LiveReloadOptions'];
317 for (k in ref) {
318 if (!hasProp.call(ref, k)) continue;
319 v = ref[k];
320 this.options.set(k, v);
321 }
322 } else {
323 this.options = Options.extract(this.window.document);
324 if (!this.options) {
325 this.console.error("LiveReload disabled because it could not find its own <SCRIPT> tag");
326 return;
327 }
328 }
329 this.reloader = new Reloader(this.window, this.console, Timer);
330 this.connector = new Connector(this.options, this.WebSocket, Timer, {
331 connecting: (function(_this) {
332 return function() {};
333 })(this),
334 socketConnected: (function(_this) {
335 return function() {};
336 })(this),
337 connected: (function(_this) {
338 return function(protocol) {
339 var base;
340 if (typeof (base = _this.listeners).connect === "function") {
341 base.connect();
342 }
343 _this.log("LiveReload is connected to " + _this.options.host + ":" + _this.options.port + " (protocol v" + protocol + ").");
344 return _this.analyze();
345 };
346 })(this),
347 error: (function(_this) {
348 return function(e) {
349 if (e instanceof ProtocolError) {
350 if (typeof console !== "undefined" && console !== null) {
351 return console.log(e.message + ".");
352 }
353 } else {
354 if (typeof console !== "undefined" && console !== null) {
355 return console.log("LiveReload internal error: " + e.message);
356 }
357 }
358 };
359 })(this),
360 disconnected: (function(_this) {
361 return function(reason, nextDelay) {
362 var base;
363 if (typeof (base = _this.listeners).disconnect === "function") {
364 base.disconnect();
365 }
366 switch (reason) {
367 case 'cannot-connect':
368 return _this.log("LiveReload cannot connect to " + _this.options.host + ":" + _this.options.port + ", will retry in " + nextDelay + " sec.");
369 case 'broken':
370 return _this.log("LiveReload disconnected from " + _this.options.host + ":" + _this.options.port + ", reconnecting in " + nextDelay + " sec.");
371 case 'handshake-timeout':
372 return _this.log("LiveReload cannot connect to " + _this.options.host + ":" + _this.options.port + " (handshake timeout), will retry in " + nextDelay + " sec.");
373 case 'handshake-failed':
374 return _this.log("LiveReload cannot connect to " + _this.options.host + ":" + _this.options.port + " (handshake failed), will retry in " + nextDelay + " sec.");
375 case 'manual':
376 break;
377 case 'error':
378 break;
379 default:
380 return _this.log("LiveReload disconnected from " + _this.options.host + ":" + _this.options.port + " (" + reason + "), reconnecting in " + nextDelay + " sec.");
381 }
382 };
383 })(this),
384 message: (function(_this) {
385 return function(message) {
386 switch (message.command) {
387 case 'reload':
388 return _this.performReload(message);
389 case 'alert':
390 return _this.performAlert(message);
391 }
392 };
393 })(this)
394 });
395 this.initialized = true;
396 }
397
398 LiveReload.prototype.on = function(eventName, handler) {
399 return this.listeners[eventName] = handler;
400 };
401
402 LiveReload.prototype.log = function(message) {
403 return this.console.log("" + message);
404 };
405
406 LiveReload.prototype.performReload = function(message) {
407 var ref, ref1, ref2;
408 this.log("LiveReload received reload request: " + (JSON.stringify(message, null, 2)));
409 return this.reloader.reload(message.path, {
410 liveCSS: (ref = message.liveCSS) != null ? ref : true,
411 liveImg: (ref1 = message.liveImg) != null ? ref1 : true,
412 reloadMissingCSS: (ref2 = message.reloadMissingCSS) != null ? ref2 : true,
413 originalPath: message.originalPath || '',
414 overrideURL: message.overrideURL || '',
415 serverURL: "http://" + this.options.host + ":" + this.options.port
416 });
417 };
418
419 LiveReload.prototype.performAlert = function(message) {
420 return alert(message.message);
421 };
422
423 LiveReload.prototype.shutDown = function() {
424 var base;
425 if (!this.initialized) {
426 return;
427 }
428 this.connector.disconnect();
429 this.log("LiveReload disconnected.");
430 return typeof (base = this.listeners).shutdown === "function" ? base.shutdown() : void 0;
431 };
432
433 LiveReload.prototype.hasPlugin = function(identifier) {
434 return !!this.pluginIdentifiers[identifier];
435 };
436
437 LiveReload.prototype.addPlugin = function(pluginClass) {
438 var plugin;
439 if (!this.initialized) {
440 return;
441 }
442 if (this.hasPlugin(pluginClass.identifier)) {
443 return;
444 }
445 this.pluginIdentifiers[pluginClass.identifier] = true;
446 plugin = new pluginClass(this.window, {
447 _livereload: this,
448 _reloader: this.reloader,
449 _connector: this.connector,
450 console: this.console,
451 Timer: Timer,
452 generateCacheBustUrl: (function(_this) {
453 return function(url) {
454 return _this.reloader.generateCacheBustUrl(url);
455 };
456 })(this)
457 });
458 this.plugins.push(plugin);
459 this.reloader.addPlugin(plugin);
460 };
461
462 LiveReload.prototype.analyze = function() {
463 var i, len, plugin, pluginData, pluginsData, ref;
464 if (!this.initialized) {
465 return;
466 }
467 if (!(this.connector.protocol >= 7)) {
468 return;
469 }
470 pluginsData = {};
471 ref = this.plugins;
472 for (i = 0, len = ref.length; i < len; i++) {
473 plugin = ref[i];
474 pluginsData[plugin.constructor.identifier] = pluginData = (typeof plugin.analyze === "function" ? plugin.analyze() : void 0) || {};
475 pluginData.version = plugin.constructor.version;
476 }
477 this.connector.sendCommand({
478 command: 'info',
479 plugins: pluginsData,
480 url: this.window.location.href
481 });
482 };
483
484 return LiveReload;
485
486 })();
487
488}).call(this);
489
490},{"./connector":1,"./options":5,"./protocol":6,"./reloader":7,"./timer":9}],5:[function(require,module,exports){
491(function() {
492 var Options;
493
494 exports.Options = Options = (function() {
495 function Options() {
496 this.https = false;
497 this.host = null;
498 this.port = 35729;
499 this.snipver = null;
500 this.ext = null;
501 this.extver = null;
502 this.mindelay = 1000;
503 this.maxdelay = 60000;
504 this.handshake_timeout = 5000;
505 }
506
507 Options.prototype.set = function(name, value) {
508 if (typeof value === 'undefined') {
509 return;
510 }
511 if (!isNaN(+value)) {
512 value = +value;
513 }
514 return this[name] = value;
515 };
516
517 return Options;
518
519 })();
520
521 Options.extract = function(document) {
522 var element, i, j, keyAndValue, len, len1, m, mm, options, pair, ref, ref1, src;
523 ref = document.getElementsByTagName('script');
524 for (i = 0, len = ref.length; i < len; i++) {
525 element = ref[i];
526 if ((src = element.src) && (m = src.match(/^[^:]+:\/\/(.*)\/z?livereload\.js(?:\?(.*))?$/))) {
527 options = new Options();
528 options.https = src.indexOf("https") === 0;
529 if (mm = m[1].match(/^([^\/:]+)(?::(\d+))?(\/+.*)?$/)) {
530 options.host = mm[1];
531 if (mm[2]) {
532 options.port = parseInt(mm[2], 10);
533 }
534 }
535 if (m[2]) {
536 ref1 = m[2].split('&');
537 for (j = 0, len1 = ref1.length; j < len1; j++) {
538 pair = ref1[j];
539 if ((keyAndValue = pair.split('=')).length > 1) {
540 options.set(keyAndValue[0].replace(/-/g, '_'), keyAndValue.slice(1).join('='));
541 }
542 }
543 }
544 return options;
545 }
546 }
547 return null;
548 };
549
550}).call(this);
551
552},{}],6:[function(require,module,exports){
553(function() {
554 var PROTOCOL_6, PROTOCOL_7, Parser, ProtocolError,
555 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; };
556
557 exports.PROTOCOL_6 = PROTOCOL_6 = 'http://livereload.com/protocols/official-6';
558
559 exports.PROTOCOL_7 = PROTOCOL_7 = 'http://livereload.com/protocols/official-7';
560
561 exports.ProtocolError = ProtocolError = (function() {
562 function ProtocolError(reason, data) {
563 this.message = "LiveReload protocol error (" + reason + ") after receiving data: \"" + data + "\".";
564 }
565
566 return ProtocolError;
567
568 })();
569
570 exports.Parser = Parser = (function() {
571 function Parser(handlers) {
572 this.handlers = handlers;
573 this.reset();
574 }
575
576 Parser.prototype.reset = function() {
577 return this.protocol = null;
578 };
579
580 Parser.prototype.process = function(data) {
581 var command, e, error, message, options, ref;
582 try {
583 if (this.protocol == null) {
584 if (data.match(/^!!ver:([\d.]+)$/)) {
585 this.protocol = 6;
586 } else if (message = this._parseMessage(data, ['hello'])) {
587 if (!message.protocols.length) {
588 throw new ProtocolError("no protocols specified in handshake message");
589 } else if (indexOf.call(message.protocols, PROTOCOL_7) >= 0) {
590 this.protocol = 7;
591 } else if (indexOf.call(message.protocols, PROTOCOL_6) >= 0) {
592 this.protocol = 6;
593 } else {
594 throw new ProtocolError("no supported protocols found");
595 }
596 }
597 return this.handlers.connected(this.protocol);
598 } else if (this.protocol === 6) {
599 message = JSON.parse(data);
600 if (!message.length) {
601 throw new ProtocolError("protocol 6 messages must be arrays");
602 }
603 command = message[0], options = message[1];
604 if (command !== 'refresh') {
605 throw new ProtocolError("unknown protocol 6 command");
606 }
607 return this.handlers.message({
608 command: 'reload',
609 path: options.path,
610 liveCSS: (ref = options.apply_css_live) != null ? ref : true
611 });
612 } else {
613 message = this._parseMessage(data, ['reload', 'alert']);
614 return this.handlers.message(message);
615 }
616 } catch (error) {
617 e = error;
618 if (e instanceof ProtocolError) {
619 return this.handlers.error(e);
620 } else {
621 throw e;
622 }
623 }
624 };
625
626 Parser.prototype._parseMessage = function(data, validCommands) {
627 var e, error, message, ref;
628 try {
629 message = JSON.parse(data);
630 } catch (error) {
631 e = error;
632 throw new ProtocolError('unparsable JSON', data);
633 }
634 if (!message.command) {
635 throw new ProtocolError('missing "command" key', data);
636 }
637 if (ref = message.command, indexOf.call(validCommands, ref) < 0) {
638 throw new ProtocolError("invalid command '" + message.command + "', only valid commands are: " + (validCommands.join(', ')) + ")", data);
639 }
640 return message;
641 };
642
643 return Parser;
644
645 })();
646
647}).call(this);
648
649},{}],7:[function(require,module,exports){
650(function() {
651 var IMAGE_STYLES, Reloader, numberOfMatchingSegments, pathFromUrl, pathsMatch, pickBestMatch, splitUrl;
652
653 splitUrl = function(url) {
654 var comboSign, hash, index, params;
655 if ((index = url.indexOf('#')) >= 0) {
656 hash = url.slice(index);
657 url = url.slice(0, index);
658 } else {
659 hash = '';
660 }
661 comboSign = url.indexOf('??');
662 if (comboSign >= 0) {
663 if (comboSign + 1 !== url.lastIndexOf('?')) {
664 index = url.lastIndexOf('?');
665 }
666 } else {
667 index = url.indexOf('?');
668 }
669 if (index >= 0) {
670 params = url.slice(index);
671 url = url.slice(0, index);
672 } else {
673 params = '';
674 }
675 return {
676 url: url,
677 params: params,
678 hash: hash
679 };
680 };
681
682 pathFromUrl = function(url) {
683 var path;
684 url = splitUrl(url).url;
685 if (url.indexOf('file://') === 0) {
686 path = url.replace(/^file:\/\/(localhost)?/, '');
687 } else {
688 path = url.replace(/^([^:]+:)?\/\/([^:\/]+)(:\d*)?\//, '/');
689 }
690 return decodeURIComponent(path);
691 };
692
693 pickBestMatch = function(path, objects, pathFunc) {
694 var bestMatch, i, len1, object, score;
695 bestMatch = {
696 score: 0
697 };
698 for (i = 0, len1 = objects.length; i < len1; i++) {
699 object = objects[i];
700 score = numberOfMatchingSegments(path, pathFunc(object));
701 if (score > bestMatch.score) {
702 bestMatch = {
703 object: object,
704 score: score
705 };
706 }
707 }
708 if (bestMatch.score > 0) {
709 return bestMatch;
710 } else {
711 return null;
712 }
713 };
714
715 numberOfMatchingSegments = function(path1, path2) {
716 var comps1, comps2, eqCount, len;
717 path1 = path1.replace(/^\/+/, '').toLowerCase();
718 path2 = path2.replace(/^\/+/, '').toLowerCase();
719 if (path1 === path2) {
720 return 10000;
721 }
722 comps1 = path1.split('/').reverse();
723 comps2 = path2.split('/').reverse();
724 len = Math.min(comps1.length, comps2.length);
725 eqCount = 0;
726 while (eqCount < len && comps1[eqCount] === comps2[eqCount]) {
727 ++eqCount;
728 }
729 return eqCount;
730 };
731
732 pathsMatch = function(path1, path2) {
733 return numberOfMatchingSegments(path1, path2) > 0;
734 };
735
736 IMAGE_STYLES = [
737 {
738 selector: 'background',
739 styleNames: ['backgroundImage']
740 }, {
741 selector: 'border',
742 styleNames: ['borderImage', 'webkitBorderImage', 'MozBorderImage']
743 }
744 ];
745
746 exports.Reloader = Reloader = (function() {
747 function Reloader(window, console, Timer) {
748 this.window = window;
749 this.console = console;
750 this.Timer = Timer;
751 this.document = this.window.document;
752 this.importCacheWaitPeriod = 200;
753 this.plugins = [];
754 }
755
756 Reloader.prototype.addPlugin = function(plugin) {
757 return this.plugins.push(plugin);
758 };
759
760 Reloader.prototype.analyze = function(callback) {
761 return results;
762 };
763
764 Reloader.prototype.reload = function(path, options) {
765 var base, i, len1, plugin, ref;
766 this.options = options;
767 if ((base = this.options).stylesheetReloadTimeout == null) {
768 base.stylesheetReloadTimeout = 15000;
769 }
770 ref = this.plugins;
771 for (i = 0, len1 = ref.length; i < len1; i++) {
772 plugin = ref[i];
773 if (plugin.reload && plugin.reload(path, options)) {
774 return;
775 }
776 }
777 if (options.liveCSS && path.match(/\.css(?:\.map)?$/i)) {
778 if (this.reloadStylesheet(path)) {
779 return;
780 }
781 }
782 if (options.liveImg && path.match(/\.(jpe?g|png|gif)$/i)) {
783 this.reloadImages(path);
784 return;
785 }
786 if (options.isChromeExtension) {
787 this.reloadChromeExtension();
788 return;
789 }
790 return this.reloadPage();
791 };
792
793 Reloader.prototype.reloadPage = function() {
794 return this.window.document.location.reload();
795 };
796
797 Reloader.prototype.reloadChromeExtension = function() {
798 return this.window.chrome.runtime.reload();
799 };
800
801 Reloader.prototype.reloadImages = function(path) {
802 var expando, i, img, j, k, len1, len2, len3, len4, m, ref, ref1, ref2, ref3, results1, selector, styleNames, styleSheet;
803 expando = this.generateUniqueString();
804 ref = this.document.images;
805 for (i = 0, len1 = ref.length; i < len1; i++) {
806 img = ref[i];
807 if (pathsMatch(path, pathFromUrl(img.src))) {
808 img.src = this.generateCacheBustUrl(img.src, expando);
809 }
810 }
811 if (this.document.querySelectorAll) {
812 for (j = 0, len2 = IMAGE_STYLES.length; j < len2; j++) {
813 ref1 = IMAGE_STYLES[j], selector = ref1.selector, styleNames = ref1.styleNames;
814 ref2 = this.document.querySelectorAll("[style*=" + selector + "]");
815 for (k = 0, len3 = ref2.length; k < len3; k++) {
816 img = ref2[k];
817 this.reloadStyleImages(img.style, styleNames, path, expando);
818 }
819 }
820 }
821 if (this.document.styleSheets) {
822 ref3 = this.document.styleSheets;
823 results1 = [];
824 for (m = 0, len4 = ref3.length; m < len4; m++) {
825 styleSheet = ref3[m];
826 results1.push(this.reloadStylesheetImages(styleSheet, path, expando));
827 }
828 return results1;
829 }
830 };
831
832 Reloader.prototype.reloadStylesheetImages = function(styleSheet, path, expando) {
833 var e, error, i, j, len1, len2, rule, rules, styleNames;
834 try {
835 rules = styleSheet != null ? styleSheet.cssRules : void 0;
836 } catch (error) {
837 e = error;
838 }
839 if (!rules) {
840 return;
841 }
842 for (i = 0, len1 = rules.length; i < len1; i++) {
843 rule = rules[i];
844 switch (rule.type) {
845 case CSSRule.IMPORT_RULE:
846 this.reloadStylesheetImages(rule.styleSheet, path, expando);
847 break;
848 case CSSRule.STYLE_RULE:
849 for (j = 0, len2 = IMAGE_STYLES.length; j < len2; j++) {
850 styleNames = IMAGE_STYLES[j].styleNames;
851 this.reloadStyleImages(rule.style, styleNames, path, expando);
852 }
853 break;
854 case CSSRule.MEDIA_RULE:
855 this.reloadStylesheetImages(rule, path, expando);
856 }
857 }
858 };
859
860 Reloader.prototype.reloadStyleImages = function(style, styleNames, path, expando) {
861 var i, len1, newValue, styleName, value;
862 for (i = 0, len1 = styleNames.length; i < len1; i++) {
863 styleName = styleNames[i];
864 value = style[styleName];
865 if (typeof value === 'string') {
866 newValue = value.replace(/\burl\s*\(([^)]*)\)/, (function(_this) {
867 return function(match, src) {
868 if (pathsMatch(path, pathFromUrl(src))) {
869 return "url(" + (_this.generateCacheBustUrl(src, expando)) + ")";
870 } else {
871 return match;
872 }
873 };
874 })(this));
875 if (newValue !== value) {
876 style[styleName] = newValue;
877 }
878 }
879 }
880 };
881
882 Reloader.prototype.reloadStylesheet = function(path) {
883 var i, imported, j, k, len1, len2, len3, len4, link, links, m, match, ref, ref1, style;
884 links = (function() {
885 var i, len1, ref, results1;
886 ref = this.document.getElementsByTagName('link');
887 results1 = [];
888 for (i = 0, len1 = ref.length; i < len1; i++) {
889 link = ref[i];
890 if (link.rel.match(/^stylesheet$/i) && !link.__LiveReload_pendingRemoval) {
891 results1.push(link);
892 }
893 }
894 return results1;
895 }).call(this);
896 imported = [];
897 ref = this.document.getElementsByTagName('style');
898 for (i = 0, len1 = ref.length; i < len1; i++) {
899 style = ref[i];
900 if (style.sheet) {
901 this.collectImportedStylesheets(style, style.sheet, imported);
902 }
903 }
904 for (j = 0, len2 = links.length; j < len2; j++) {
905 link = links[j];
906 this.collectImportedStylesheets(link, link.sheet, imported);
907 }
908 if (this.window.StyleFix && this.document.querySelectorAll) {
909 ref1 = this.document.querySelectorAll('style[data-href]');
910 for (k = 0, len3 = ref1.length; k < len3; k++) {
911 style = ref1[k];
912 links.push(style);
913 }
914 }
915 this.console.log("LiveReload found " + links.length + " LINKed stylesheets, " + imported.length + " @imported stylesheets");
916 match = pickBestMatch(path, links.concat(imported), (function(_this) {
917 return function(l) {
918 return pathFromUrl(_this.linkHref(l));
919 };
920 })(this));
921 if (match) {
922 if (match.object.rule) {
923 this.console.log("LiveReload is reloading imported stylesheet: " + match.object.href);
924 this.reattachImportedRule(match.object);
925 } else {
926 this.console.log("LiveReload is reloading stylesheet: " + (this.linkHref(match.object)));
927 this.reattachStylesheetLink(match.object);
928 }
929 } else {
930 if (this.options.reloadMissingCSS) {
931 this.console.log("LiveReload will reload all stylesheets because path '" + path + "' did not match any specific one. To disable this behavior, set 'options.reloadMissingCSS' to 'false'.");
932 for (m = 0, len4 = links.length; m < len4; m++) {
933 link = links[m];
934 this.reattachStylesheetLink(link);
935 }
936 } else {
937 this.console.log("LiveReload will not reload path '" + path + "' because the stylesheet was not found on the page and 'options.reloadMissingCSS' was set to 'false'.");
938 }
939 }
940 return true;
941 };
942
943 Reloader.prototype.collectImportedStylesheets = function(link, styleSheet, result) {
944 var e, error, i, index, len1, rule, rules;
945 try {
946 rules = styleSheet != null ? styleSheet.cssRules : void 0;
947 } catch (error) {
948 e = error;
949 }
950 if (rules && rules.length) {
951 for (index = i = 0, len1 = rules.length; i < len1; index = ++i) {
952 rule = rules[index];
953 switch (rule.type) {
954 case CSSRule.CHARSET_RULE:
955 continue;
956 case CSSRule.IMPORT_RULE:
957 result.push({
958 link: link,
959 rule: rule,
960 index: index,
961 href: rule.href
962 });
963 this.collectImportedStylesheets(link, rule.styleSheet, result);
964 break;
965 default:
966 break;
967 }
968 }
969 }
970 };
971
972 Reloader.prototype.waitUntilCssLoads = function(clone, func) {
973 var callbackExecuted, executeCallback, poll;
974 callbackExecuted = false;
975 executeCallback = (function(_this) {
976 return function() {
977 if (callbackExecuted) {
978 return;
979 }
980 callbackExecuted = true;
981 return func();
982 };
983 })(this);
984 clone.onload = (function(_this) {
985 return function() {
986 _this.console.log("LiveReload: the new stylesheet has finished loading");
987 _this.knownToSupportCssOnLoad = true;
988 return executeCallback();
989 };
990 })(this);
991 if (!this.knownToSupportCssOnLoad) {
992 (poll = (function(_this) {
993 return function() {
994 if (clone.sheet) {
995 _this.console.log("LiveReload is polling until the new CSS finishes loading...");
996 return executeCallback();
997 } else {
998 return _this.Timer.start(50, poll);
999 }
1000 };
1001 })(this))();
1002 }
1003 return this.Timer.start(this.options.stylesheetReloadTimeout, executeCallback);
1004 };
1005
1006 Reloader.prototype.linkHref = function(link) {
1007 return link.href || link.getAttribute('data-href');
1008 };
1009
1010 Reloader.prototype.reattachStylesheetLink = function(link) {
1011 var clone, parent;
1012 if (link.__LiveReload_pendingRemoval) {
1013 return;
1014 }
1015 link.__LiveReload_pendingRemoval = true;
1016 if (link.tagName === 'STYLE') {
1017 clone = this.document.createElement('link');
1018 clone.rel = 'stylesheet';
1019 clone.media = link.media;
1020 clone.disabled = link.disabled;
1021 } else {
1022 clone = link.cloneNode(false);
1023 }
1024 clone.href = this.generateCacheBustUrl(this.linkHref(link));
1025 parent = link.parentNode;
1026 if (parent.lastChild === link) {
1027 parent.appendChild(clone);
1028 } else {
1029 parent.insertBefore(clone, link.nextSibling);
1030 }
1031 return this.waitUntilCssLoads(clone, (function(_this) {
1032 return function() {
1033 var additionalWaitingTime;
1034 if (/AppleWebKit/.test(navigator.userAgent)) {
1035 additionalWaitingTime = 5;
1036 } else {
1037 additionalWaitingTime = 200;
1038 }
1039 return _this.Timer.start(additionalWaitingTime, function() {
1040 var ref;
1041 if (!link.parentNode) {
1042 return;
1043 }
1044 link.parentNode.removeChild(link);
1045 clone.onreadystatechange = null;
1046 return (ref = _this.window.StyleFix) != null ? ref.link(clone) : void 0;
1047 });
1048 };
1049 })(this));
1050 };
1051
1052 Reloader.prototype.reattachImportedRule = function(arg) {
1053 var href, index, link, media, newRule, parent, rule, tempLink;
1054 rule = arg.rule, index = arg.index, link = arg.link;
1055 parent = rule.parentStyleSheet;
1056 href = this.generateCacheBustUrl(rule.href);
1057 media = rule.media.length ? [].join.call(rule.media, ', ') : '';
1058 newRule = "@import url(\"" + href + "\") " + media + ";";
1059 rule.__LiveReload_newHref = href;
1060 tempLink = this.document.createElement("link");
1061 tempLink.rel = 'stylesheet';
1062 tempLink.href = href;
1063 tempLink.__LiveReload_pendingRemoval = true;
1064 if (link.parentNode) {
1065 link.parentNode.insertBefore(tempLink, link);
1066 }
1067 return this.Timer.start(this.importCacheWaitPeriod, (function(_this) {
1068 return function() {
1069 if (tempLink.parentNode) {
1070 tempLink.parentNode.removeChild(tempLink);
1071 }
1072 if (rule.__LiveReload_newHref !== href) {
1073 return;
1074 }
1075 parent.insertRule(newRule, index);
1076 parent.deleteRule(index + 1);
1077 rule = parent.cssRules[index];
1078 rule.__LiveReload_newHref = href;
1079 return _this.Timer.start(_this.importCacheWaitPeriod, function() {
1080 if (rule.__LiveReload_newHref !== href) {
1081 return;
1082 }
1083 parent.insertRule(newRule, index);
1084 return parent.deleteRule(index + 1);
1085 });
1086 };
1087 })(this));
1088 };
1089
1090 Reloader.prototype.generateUniqueString = function() {
1091 return 'livereload=' + Date.now();
1092 };
1093
1094 Reloader.prototype.generateCacheBustUrl = function(url, expando) {
1095 var hash, oldParams, originalUrl, params, ref;
1096 if (expando == null) {
1097 expando = this.generateUniqueString();
1098 }
1099 ref = splitUrl(url), url = ref.url, hash = ref.hash, oldParams = ref.params;
1100 if (this.options.overrideURL) {
1101 if (url.indexOf(this.options.serverURL) < 0) {
1102 originalUrl = url;
1103 url = this.options.serverURL + this.options.overrideURL + "?url=" + encodeURIComponent(url);
1104 this.console.log("LiveReload is overriding source URL " + originalUrl + " with " + url);
1105 }
1106 }
1107 params = oldParams.replace(/(\?|&)livereload=(\d+)/, function(match, sep) {
1108 return "" + sep + expando;
1109 });
1110 if (params === oldParams) {
1111 if (oldParams.length === 0) {
1112 params = "?" + expando;
1113 } else {
1114 params = oldParams + "&" + expando;
1115 }
1116 }
1117 return url + params + hash;
1118 };
1119
1120 return Reloader;
1121
1122 })();
1123
1124}).call(this);
1125
1126},{}],8:[function(require,module,exports){
1127(function() {
1128 var CustomEvents, LiveReload, k;
1129
1130 CustomEvents = require('./customevents');
1131
1132 LiveReload = window.LiveReload = new (require('./livereload').LiveReload)(window);
1133
1134 for (k in window) {
1135 if (k.match(/^LiveReloadPlugin/)) {
1136 LiveReload.addPlugin(window[k]);
1137 }
1138 }
1139
1140 LiveReload.addPlugin(require('./less'));
1141
1142 LiveReload.on('shutdown', function() {
1143 return delete window.LiveReload;
1144 });
1145
1146 LiveReload.on('connect', function() {
1147 return CustomEvents.fire(document, 'LiveReloadConnect');
1148 });
1149
1150 LiveReload.on('disconnect', function() {
1151 return CustomEvents.fire(document, 'LiveReloadDisconnect');
1152 });
1153
1154 CustomEvents.bind(document, 'LiveReloadShutDown', function() {
1155 return LiveReload.shutDown();
1156 });
1157
1158}).call(this);
1159
1160},{"./customevents":2,"./less":3,"./livereload":4}],9:[function(require,module,exports){
1161(function() {
1162 var Timer;
1163
1164 exports.Timer = Timer = (function() {
1165 function Timer(func1) {
1166 this.func = func1;
1167 this.running = false;
1168 this.id = null;
1169 this._handler = (function(_this) {
1170 return function() {
1171 _this.running = false;
1172 _this.id = null;
1173 return _this.func();
1174 };
1175 })(this);
1176 }
1177
1178 Timer.prototype.start = function(timeout) {
1179 if (this.running) {
1180 clearTimeout(this.id);
1181 }
1182 this.id = setTimeout(this._handler, timeout);
1183 return this.running = true;
1184 };
1185
1186 Timer.prototype.stop = function() {
1187 if (this.running) {
1188 clearTimeout(this.id);
1189 this.running = false;
1190 return this.id = null;
1191 }
1192 };
1193
1194 return Timer;
1195
1196 })();
1197
1198 Timer.start = function(timeout, func) {
1199 return setTimeout(func, timeout);
1200 };
1201
1202}).call(this);
1203
1204},{}]},{},[8]);