github.com/cortesi/devd@v0.0.0-20200427000907-c1a3bfba27d8/livereload/rice-box.go (about) 1 package livereload 2 3 import ( 4 "github.com/GeertJohan/go.rice/embedded" 5 "time" 6 ) 7 8 func init() { 9 10 // define files 11 file2 := &embedded.EmbeddedFile{ 12 Filename: "LICENSE", 13 FileModTime: time.Unix(1503017339, 0), 14 Content: string("// reconnecting-websocket - MIT License:\n//\n// Copyright (c) 2010-2012, Joe Walnes\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n"), 15 } 16 file3 := &embedded.EmbeddedFile{ 17 Filename: "client.js", 18 FileModTime: time.Unix(1503017339, 0), 19 Content: string("(function() {\n if (!('WebSocket' in window)) {\n return;\n }\n\n function DevdReconnectingWebSocket(url, protocols, options) {\n\n // Default settings\n var settings = {\n\n /** Whether this instance should log debug messages. */\n debug: false,\n\n /** Whether or not the websocket should attempt to connect immediately upon instantiation. */\n automaticOpen: true,\n\n /** The number of milliseconds to delay before attempting to reconnect. */\n reconnectInterval: 1000,\n /** The maximum number of milliseconds to delay a reconnection attempt. */\n maxReconnectInterval: 30000,\n /** The rate of increase of the reconnect delay. Allows reconnect attempts to back off when problems persist. */\n reconnectDecay: 1.5,\n\n /** The maximum time in milliseconds to wait for a connection to succeed before closing and retrying. */\n timeoutInterval: 2000,\n\n /** The maximum number of reconnection attempts to make. Unlimited if null. */\n maxReconnectAttempts: null,\n\n /** The binary type, possible values 'blob' or 'arraybuffer', default 'blob'. */\n binaryType: 'blob'\n }\n if (!options) {\n options = {};\n }\n\n // Overwrite and define settings with options if they exist.\n for (var key in settings) {\n if (typeof options[key] !== 'undefined') {\n this[key] = options[key];\n } else {\n this[key] = settings[key];\n }\n }\n\n // These should be treated as read-only properties\n\n /** The URL as resolved by the constructor. This is always an absolute URL. Read only. */\n this.url = url;\n\n /** The number of attempted reconnects since starting, or the last successful connection. Read only. */\n this.reconnectAttempts = 0;\n\n /**\n * The current state of the connection.\n * Can be one of: WebSocket.CONNECTING, WebSocket.OPEN, WebSocket.CLOSING, WebSocket.CLOSED\n * Read only.\n */\n this.readyState = WebSocket.CONNECTING;\n\n /**\n * A string indicating the name of the sub-protocol the server selected; this will be one of\n * the strings specified in the protocols parameter when creating the WebSocket object.\n * Read only.\n */\n this.protocol = null;\n\n // Private state variables\n\n var self = this;\n var ws;\n var forcedClose = false;\n var timedOut = false;\n var eventTarget = document.createElement('div');\n\n // Wire up \"on*\" properties as event handlers\n\n eventTarget.addEventListener('open', function(event) {\n self.onopen(event);\n });\n eventTarget.addEventListener('close', function(event) {\n self.onclose(event);\n });\n eventTarget.addEventListener('connecting', function(event) {\n self.onconnecting(event);\n });\n eventTarget.addEventListener('message', function(event) {\n self.onmessage(event);\n });\n eventTarget.addEventListener('error', function(event) {\n self.onerror(event);\n });\n\n // Expose the API required by EventTarget\n\n this.addEventListener = eventTarget.addEventListener.bind(eventTarget);\n this.removeEventListener = eventTarget.removeEventListener.bind(eventTarget);\n this.dispatchEvent = eventTarget.dispatchEvent.bind(eventTarget);\n\n /**\n * This function generates an event that is compatible with standard\n * compliant browsers and IE9 - IE11\n *\n * This will prevent the error:\n * Object doesn't support this action\n *\n * http://stackoverflow.com/questions/19345392/why-arent-my-parameters-getting-passed-through-to-a-dispatched-event/19345563#19345563\n * @param s String The name that the event should use\n * @param args Object an optional object that the event will use\n */\n function generateEvent(s, args) {\n var evt = document.createEvent(\"CustomEvent\");\n evt.initCustomEvent(s, false, false, args);\n return evt;\n };\n\n this.open = function(reconnectAttempt) {\n ws = new WebSocket(self.url, protocols || []);\n ws.binaryType = this.binaryType;\n\n if (reconnectAttempt) {\n if (this.maxReconnectAttempts && this.reconnectAttempts > this.maxReconnectAttempts) {\n return;\n }\n } else {\n eventTarget.dispatchEvent(generateEvent('connecting'));\n this.reconnectAttempts = 0;\n }\n\n if (self.debug || DevdReconnectingWebSocket.debugAll) {\n console.debug('DevdReconnectingWebSocket', 'attempt-connect', self.url);\n }\n\n var localWs = ws;\n var timeout = setTimeout(function() {\n if (self.debug || DevdReconnectingWebSocket.debugAll) {\n console.debug('DevdReconnectingWebSocket', 'connection-timeout', self.url);\n }\n timedOut = true;\n localWs.close();\n timedOut = false;\n }, self.timeoutInterval);\n\n ws.onopen = function(event) {\n clearTimeout(timeout);\n if (self.debug || DevdReconnectingWebSocket.debugAll) {\n console.debug('DevdReconnectingWebSocket', 'onopen', self.url);\n }\n self.protocol = ws.protocol;\n self.readyState = WebSocket.OPEN;\n self.reconnectAttempts = 0;\n var e = generateEvent('open');\n e.isReconnect = reconnectAttempt;\n reconnectAttempt = false;\n eventTarget.dispatchEvent(e);\n };\n\n ws.onclose = function(event) {\n clearTimeout(timeout);\n ws = null;\n if (forcedClose) {\n self.readyState = WebSocket.CLOSED;\n eventTarget.dispatchEvent(generateEvent('close'));\n } else {\n self.readyState = WebSocket.CONNECTING;\n var e = generateEvent('connecting');\n e.code = event.code;\n e.reason = event.reason;\n e.wasClean = event.wasClean;\n eventTarget.dispatchEvent(e);\n if (!reconnectAttempt && !timedOut) {\n if (self.debug || DevdReconnectingWebSocket.debugAll) {\n console.debug('DevdReconnectingWebSocket', 'onclose', self.url);\n }\n eventTarget.dispatchEvent(generateEvent('close'));\n }\n\n var timeout = self.reconnectInterval * Math.pow(self.reconnectDecay, self.reconnectAttempts);\n setTimeout(function() {\n self.reconnectAttempts++;\n self.open(true);\n }, timeout > self.maxReconnectInterval ? self.maxReconnectInterval : timeout);\n }\n };\n ws.onmessage = function(event) {\n if (self.debug || DevdReconnectingWebSocket.debugAll) {\n console.debug('DevdReconnectingWebSocket', 'onmessage', self.url, event.data);\n }\n var e = generateEvent('message');\n e.data = event.data;\n eventTarget.dispatchEvent(e);\n };\n ws.onerror = function(event) {\n if (self.debug || DevdReconnectingWebSocket.debugAll) {\n console.debug('DevdReconnectingWebSocket', 'onerror', self.url, event);\n }\n eventTarget.dispatchEvent(generateEvent('error'));\n };\n }\n\n // Whether or not to create a websocket upon instantiation\n if (this.automaticOpen == true) {\n this.open(false);\n }\n\n /**\n * Transmits data to the server over the WebSocket connection.\n *\n * @param data a text string, ArrayBuffer or Blob to send to the server.\n */\n this.send = function(data) {\n if (ws) {\n if (self.debug || DevdReconnectingWebSocket.debugAll) {\n console.debug('DevdReconnectingWebSocket', 'send', self.url, data);\n }\n return ws.send(data);\n } else {\n throw 'INVALID_STATE_ERR : Pausing to reconnect websocket';\n }\n };\n\n /**\n * Closes the WebSocket connection or connection attempt, if any.\n * If the connection is already CLOSED, this method does nothing.\n */\n this.close = function(code, reason) {\n // Default CLOSE_NORMAL code\n if (typeof code == 'undefined') {\n code = 1000;\n }\n forcedClose = true;\n if (ws) {\n ws.close(code, reason);\n }\n };\n\n /**\n * Additional public API method to refresh the connection if still open (close, re-open).\n * For example, if the app suspects bad data / missed heart beats, it can try to refresh.\n */\n this.refresh = function() {\n if (ws) {\n ws.close();\n }\n };\n }\n\n /**\n * An event listener to be called when the WebSocket connection's readyState changes to OPEN;\n * this indicates that the connection is ready to send and receive data.\n */\n DevdReconnectingWebSocket.prototype.onopen = function(event) {};\n /** An event listener to be called when the WebSocket connection's readyState changes to CLOSED. */\n DevdReconnectingWebSocket.prototype.onclose = function(event) {};\n /** An event listener to be called when a connection begins being attempted. */\n DevdReconnectingWebSocket.prototype.onconnecting = function(event) {};\n /** An event listener to be called when a message is received from the server. */\n DevdReconnectingWebSocket.prototype.onmessage = function(event) {};\n /** An event listener to be called when an error occurs. */\n DevdReconnectingWebSocket.prototype.onerror = function(event) {};\n\n /**\n * Whether all instances of DevdReconnectingWebSocket should log debug messages.\n * Setting this to true is the equivalent of setting all instances of DevdReconnectingWebSocket.debug to true.\n */\n DevdReconnectingWebSocket.debugAll = false;\n\n DevdReconnectingWebSocket.CONNECTING = WebSocket.CONNECTING;\n DevdReconnectingWebSocket.OPEN = WebSocket.OPEN;\n DevdReconnectingWebSocket.CLOSING = WebSocket.CLOSING;\n DevdReconnectingWebSocket.CLOSED = WebSocket.CLOSED;\n\n window.DevdReconnectingWebSocket = DevdReconnectingWebSocket;\n\n var proto = \"ws://\";\n if (window.location.protocol == \"https:\") {\n proto = \"wss://\";\n }\n\n ws = new DevdReconnectingWebSocket(\n proto + window.location.host + \"/.devd.livereload\",\n null,\n {\n debug: true,\n maxReconnectInterval: 3000,\n }\n )\n ws.onmessage = function(event) {\n if (event.data == \"page\") {\n ws.close();\n location.reload();\n } else if (event.data == \"css\") {\n // This snippet pinched from quickreload, under the MIT license:\n // https://github.com/bjoerge/quickreload/blob/master/client.js\n var killcache = '__devd=' + new Date().getTime();\n var stylesheets = Array.prototype.slice.call(\n document.querySelectorAll('link[rel=\"stylesheet\"]')\n );\n stylesheets.forEach(function (el) {\n var href = el.href.replace(/(&|\\?)__devd\\=\\d+/, '');\n el.href = '';\n el.href = href + (href.indexOf(\"?\") == -1 ? '?' : '&') + killcache;\n });\n }\n }\n window.addEventListener(\"beforeunload\", function(e) {\n ws.close();\n delete e.returnValue;\n return;\n });\n})();\n"), 20 } 21 22 // define dirs 23 dir1 := &embedded.EmbeddedDir{ 24 Filename: "", 25 DirModTime: time.Unix(1503017339, 0), 26 ChildFiles: []*embedded.EmbeddedFile{ 27 file2, // "LICENSE" 28 file3, // "client.js" 29 30 }, 31 } 32 33 // link ChildDirs 34 dir1.ChildDirs = []*embedded.EmbeddedDir{} 35 36 // register embeddedBox 37 embedded.RegisterEmbeddedBox(`static`, &embedded.EmbeddedBox{ 38 Name: `static`, 39 Time: time.Unix(1503017339, 0), 40 Dirs: map[string]*embedded.EmbeddedDir{ 41 "": dir1, 42 }, 43 Files: map[string]*embedded.EmbeddedFile{ 44 "LICENSE": file2, 45 "client.js": file3, 46 }, 47 }) 48 }