UNPKG

simple-autoreload-server

Version:

Simple Web Server with live/autoreload features without browser extensions.

471 lines (469 loc) 16.6 kB
<script type="text/javascript"> //<![CDATA[ /* * simple-autoreload-server v0.2.15 - 2021-05-22 * <https://github.com/cytb/simple-autoreload-server> * * Copyright (c) 2021 cytb * * Licensed under the MIT License. */ (function(){ var AutoreloadClient, slice$ = [].slice, split$ = ''.split, join$ = [].join; AutoreloadClient = (function(){ AutoreloadClient.displayName = 'AutoreloadClient'; var ref$, LazyQueryString, Manipulator, prototype = AutoreloadClient.prototype, constructor = AutoreloadClient; AutoreloadClient.getDefaultOption = function(){ var x$; x$ = { log: false, expose: false, keepalive: false, overrideOption: true, dispatchEvent: true, timestamp: '_tsAccessed', location: window.location }; x$.scan = function(it){ var i$, x$, len$, j$, ref$, len1$, tag, k$, ref1$, len2$, attribute, l$, ref2$, len3$, method, results$ = []; for (i$ = 0, len$ = it.length; i$ < len$; ++i$) { x$ = it[i$]; for (j$ = 0, len1$ = (ref$ = x$[0]).length; j$ < len1$; ++j$) { tag = ref$[j$]; for (k$ = 0, len2$ = (ref1$ = x$[1]).length; k$ < len2$; ++k$) { attribute = ref1$[k$]; for (l$ = 0, len3$ = (ref2$ = x$[2]).length; l$ < len3$; ++l$) { method = ref2$[l$]; results$.push({ tag: tag, attribute: attribute, method: method }); } } } } return results$; }( [[['link'], ['href'], ['update']], [['audio', 'img', 'video', 'embed', 'object'], ['src'], ['update']], [['script'], ['src'], ['replace']]]); return x$; }; AutoreloadClient.WebSocket = window.WebSocket || window.MozWebSocket; AutoreloadClient.URL = (((ref$ = window.URL) != null ? ref$.prototype : void 8) != null && in$("href", window.URL.prototype) && window.URL) || (function(){ var prototype = constructor.prototype; function constructor(uri, base){ var newBase, x$, link, i$, y$, ref$, len$; newBase = document.createElement('base'); newBase.href = base; x$ = document.head; x$.insertBefore(newBase, x$.firstChild); link = document.createElement('a'); link.href = uri; for (i$ = 0, len$ = (ref$ = ['origin', 'protocol', 'username', 'password', 'host', 'hostname', 'port', 'pathname', 'search', 'hash', 'href']).length; i$ < len$; ++i$) { y$ = ref$[i$]; this[y$] = link[y$] != null ? link[y$].toString() : ''; } newBase.parentNode.removeChild(newBase); } prototype.toString = function(){ return this.href; }; Object.defineProperty(prototype, 'href', { get: function(){ var password, auth; password = (this.password != null && ":" + this.password || '') + ""; auth = (this.username && this.username + "" + password + "@" || '') + ""; return this.protocol + "//" + auth + this.host + this.pathname + this.search + this.hash; }, set: function(x){}, configurable: true, enumerable: true }); return constructor; }()); AutoreloadClient.CustomEvent = window.CustomEvent || (function(superclass){ var prototype = extend$(import$(constructor, superclass), superclass).prototype; function constructor(ename, arg$){ var ref$, bubbles, ref1$, cancelable, detail, x$; ref$ = arg$ != null ? arg$ : { bubbles: false, cancelable: false }, bubbles = (ref1$ = ref$.bubbles) != null ? ref1$ : false, cancelable = (ref1$ = ref$.cancelable) != null ? ref1$ : false, detail = ref$.detail; x$ = document.createEvent('CustomEvent'); x$.initCustomEvent(ename, bubbles, cancelable, detail); return x$; } return constructor; }(window.Event)); AutoreloadClient.dispatcher = curry$(function(command, handler, data){ var eventDetail, ref$, x$; this.log(command + ""); if (this.options.dispatchEvent) { eventDetail = { cancelable: true, detail: (ref$ = import$({}, data), ref$.client = this, ref$) }; x$ = new constructor.CustomEvent(constructor.name + "." + command, eventDetail); if (!window.dispatchEvent(x$)) { return; } } return handler.call(this, data); }); function AutoreloadClient(options){ this.options = options != null ? options : constructor.getDefaultOption(); window.addEventListener('unload', bind$(this, 'onDispose')); } prototype.log = function(){ var args; args = slice$.call(arguments); if (!this.options.log) { return; } return console.debug.apply(console, ["AutoreloadClient:"].concat(args)); }; prototype.resolve = function(it){ return new (constructor.URL)(it, document.baseURI); }; prototype.urlMatches = function(a, b){ return ['origin', 'protocol', 'username', 'password', 'host', 'hostname', 'port', 'pathname'].every(function(it){ return a[it] === b[it]; }); }; prototype.addScan = function(arg$){ var tag, attribute, method, ref$, filter; tag = arg$.tag, attribute = arg$.attribute, method = (ref$ = arg$.method) != null ? ref$ : 'update', filter = (ref$ = arg$.filter) != null ? ref$ : function(){ return true; }; switch (false) { case !(arguments.length > 1): return this.addScan({ tag: arguments[0], attribute: arguments[1], method: arguments[2], filter: arguments[3] }); case !!(tag != null && (typeof attr != 'undefined' && attr !== null)): return false; default: return this.options.scan.push({ tag: tag, attribute: attribute, method: method, filter: filter }); } }; prototype.removeScan = function(tag, attribute, method){ var ref$; method == null && (method = null); return (ref$ = this.options).scan = ref$.scan.filter(function(it){ var key, ref$, val; for (key in ref$ = { tag: tag, attribute: attribute }) { val = ref$[key]; if (it[key] !== val) { return true; } } return method != null && it.method !== method; }); }; prototype.postMessage = function(type, data){ switch (false) { case typeof type === 'string': return this.onMessage.apply(this, arguments); default: return this.onMessage(import$({ type: type }, data)); } }; prototype.connect = function(){ return this.postMessage({ type: 'connect' }); }; prototype.close = function(){ return this.postMessage({ type: 'close' }); }; /* events */ prototype.onConnect = AutoreloadClient.dispatcher('connect', function(){ var x$, y$; x$ = this.options.location; y$ = this.websocket = new constructor.WebSocket("ws://" + x$.host + x$.pathname); y$.onmessage = compose$(function(it){ return it.data; }, bind$(JSON, 'parse'), bind$(this, 'onMessage')); y$.onclose = bind$(this, 'onClose'); return x$; }); prototype.onScan = AutoreloadClient.dispatcher('scan', function(data){ var i$, x$, ref$, len$, method, results$ = [], this$ = this; for (i$ = 0, len$ = (ref$ = data.scan).length; i$ < len$; ++i$) { x$ = ref$[i$]; if (typeof x$.tag !== 'string' || typeof x$.attribute !== 'string') { continue; } method = constructor.Manipulator[x$.method] != null && bind$(constructor.Manipulator, x$.method) || x$.method; if (typeof method !== 'function') { continue; } results$.push(constructor.Manipulator.find(x$.tag, x$.attribute, fn$)); } return results$; function fn$(target, attribute, value){ var x$, ref$; x$ = (ref$ = import$({}, data), ref$.targetUrl = this$.resolve(value), ref$.target = target, ref$.attribute = attribute, ref$.value = value, ref$.method = method, ref$); switch (false) { case !!this$.urlMatches(x$.targetUrl, x$.url): return target; case !data.reload: this$.onReload(x$); break; default: this$.onRefresh(x$); } return x$; } }); prototype.onClose = AutoreloadClient.dispatcher('close', function(){ var ref$; if ((ref$ = this.websocket) != null) { ref$.close(); } if (!this.disposed && this.options.keepalive) { return this.connect(); } }); prototype.onOpen = AutoreloadClient.dispatcher('open', function(data){ var name; if (this.options.overrideOption) { import$(this.options, data.options); } if (name = this.options.expose) { if (typeof name !== 'string') { name = constructor.displayName; } window[name] = this; return this.log(constructor.displayName + " instance exposed as window['" + name + "']"); } }); prototype.onMessage = AutoreloadClient.dispatcher('message', function(data){ var handler, that, ref$; handler = data.type.replace(/^./, function(it){ return it.toUpperCase(); }); if ((that = data.path) != null) { data.url = this.resolve(that); } return this["on" + handler]((ref$ = import$({}, data), ref$.location = this.resolve(this.options.location), ref$.url = data.path && this.resolve(data.path) || null, ref$)); }); prototype.onRefresh = AutoreloadClient.dispatcher('refresh', function(data){ var newUrl, x$; newUrl = this.resolve(data.targetUrl.href); x$ = constructor.QueryString.parse(newUrl.search); x$[this.options.timestamp] = Date.now(); newUrl.search = "?" + constructor.QueryString.stringify(x$); return data.method(data.target, data.attribute, newUrl.href); }); prototype.onReload = AutoreloadClient.dispatcher('reload', function(data){ switch (false) { case !!data.reload: return this.onRefresh(data); default: this.onDispose(); return window.location.reload(); } }); prototype.onUpdate = AutoreloadClient.dispatcher('update', function(data){ var x$, ref$; x$ = (ref$ = import$({}, data), ref$.url = this.resolve(data.path, { method: function(){} }), ref$); if (this.urlMatches(x$.location, x$.url)) { this.onReload((ref$ = import$({}, x$), ref$.reload = true, ref$.self = true, ref$)); } else { this.onScan((ref$ = import$({}, x$), ref$.scan = this.options.scan.map(function(it){ return import$({}, it); }), ref$)); } return x$; }); prototype.onDispose = function(){ var ref$; this.disposed = true; return (ref$ = this.websocket) != null ? ref$.close() : void 8; }; /* utils */; AutoreloadClient.QueryString = LazyQueryString = (function(){ LazyQueryString.displayName = 'LazyQueryString'; var isArray, prototype = LazyQueryString.prototype, constructor = LazyQueryString; isArray = (function(it){ return it instanceof Array; }); LazyQueryString.parse = function(qs){ var object, i$, x$, ref$, len$, ref1$, key, value, that; qs == null && (qs = ''); if (typeof qs !== "string") { qs = qs.search; } object = {}; for (i$ = 0, len$ = (ref$ = split$.call((/^\?*([^#]*)$/.exec(qs != null ? qs : ''))[1], '&')).length; i$ < len$; ++i$) { x$ = ref$[i$]; ref1$ = /^([^=]*)(=(.*))?$/.exec(x$), key = ref1$[1], value = ref1$[3]; object[key] = (fn$()); } return object; function fn$(){ var ref$; switch (ref$ = [object[key]], false) { case !function(it){ return it == null; }(ref$[0]): return value; case !(that = isArray(ref$[0])): return that.concat(value); default: return [that]; } } }; LazyQueryString.stringify = function(queryobject){ var key, val; queryobject == null && (queryobject = {}); return (function(it){ return join$.call(it, '&'); })((function(){ var ref$, results$ = []; for (key in ref$ = queryobject) { val = ref$[key]; switch (false) { case !!key: continue; case val != null: results$.push(key + ""); break; case !isArray(val): results$.push((fn$)( val.map(fn1$))); break; default: results$.push(key + "=" + val); } } return results$; function fn$(it){ return join$.call(it, '&'); } function fn1$(it){ return key + "=" + it; } }())); }; function LazyQueryString(){} return LazyQueryString; }()); AutoreloadClient.Manipulator = Manipulator = (function(){ Manipulator.displayName = 'Manipulator'; var prototype = Manipulator.prototype, constructor = Manipulator; Manipulator.find = function(tag, attribute, functor){ var i$, x$, ref$, len$, that, results$ = []; functor == null && (functor = function(){}); for (i$ = 0, len$ = (ref$ = document.getElementsByTagName(tag)).length; i$ < len$; ++i$) { x$ = ref$[i$]; if ((that = x$.getAttribute(attribute)) != null) { results$.push(functor(x$, attribute, that)); } } return results$; }; Manipulator.move = function(src, dest){ var i$, x$, ref$, len$, y$; dest == null && (dest = document.createElement(src.tagName)); for (i$ = 0, len$ = (ref$ = src.attributes).length; i$ < len$; ++i$) { x$ = ref$[i$]; dest.setAttribute(x$.nodeName, x$.nodeValue); } for (i$ = 0, len$ = (ref$ = src.childNodes).length; i$ < len$; ++i$) { y$ = ref$[i$]; dest.appendChild(src.childNodes.firstChild); } return dest; }; Manipulator.update = function(element, name, value){ element.setAttribute(name, value); return element; }; Manipulator.replace = function(target, name, value){ var copied, x$; copied = this.move(target, null); this.update(copied, name, value); x$ = target; x$.parentNode.insertBefore(copied, x$); x$.parentNode.removeChild(x$); return x$; }; function Manipulator(){} return Manipulator; }()); return AutoreloadClient; }()); /* main */ new AutoreloadClient(null).connect(); function in$(x, xs){ var i = -1, l = xs.length >>> 0; while (++i < l) if (x === xs[i]) return true; return false; } function extend$(sub, sup){ function fun(){} fun.prototype = (sub.superclass = sup).prototype; (sub.prototype = new fun).constructor = sub; if (typeof sup.extended == 'function') sup.extended(sub); return sub; } function import$(obj, src){ var own = {}.hasOwnProperty; for (var key in src) if (own.call(src, key)) obj[key] = src[key]; return obj; } function curry$(f, bound){ var context, _curry = function(args) { return f.length > 1 ? function(){ var params = args ? args.concat() : []; context = bound ? context || this : this; return params.push.apply(params, arguments) < f.length && arguments.length ? _curry.call(context, params) : f.apply(context, params); } : f; }; return _curry(); } function bind$(obj, key, target){ return function(){ return (target || obj)[key].apply(obj, arguments) }; } function compose$() { var functions = arguments; return function() { var i, result; result = functions[0].apply(this, arguments); for (i = 1; i < functions.length; ++i) { result = functions[i](result); } return result; }; } }).call(this); //]]> </script>