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