github.com/marinho/drone@v0.2.1-0.20140504195434-d3ba962e89a7/cmd/droned/assets/js/main.js (about) 1 ;// Format ANSI to HTML 2 3 if(typeof(Drone) === 'undefined') { Drone = {}; } 4 5 (function() { 6 Drone.LineFormatter = function() {}; 7 8 Drone.LineFormatter.prototype = { 9 regex: /\u001B\[([0-9]+;?)*[Km]/g, 10 styles: [], 11 12 format: function(s) { 13 // Check for newline and early exit? 14 s = s.replace(/</g, "<"); 15 s = s.replace(/>/g, ">"); 16 17 var output = ""; 18 var current = 0; 19 while (m = this.regex.exec(s)) { 20 var part = s.substring(current, m.index); 21 current = this.regex.lastIndex; 22 23 var token = s.substr(m.index, this.regex.lastIndex - m.index); 24 var code = token.substr(2, token.length-2); 25 26 var pre = ""; 27 var post = ""; 28 29 switch (code) { 30 case 'm': 31 case '0m': 32 var len = this.styles.length; 33 for (var i=0; i < len; i++) { 34 this.styles.pop(); 35 post += "</span>" 36 } 37 break; 38 case '30;42m': pre = '<span style="color:black;background:lime">'; break; 39 case '36m': 40 case '36;1m': pre = '<span style="color:cyan;">'; break; 41 case '31m': 42 case '31;31m': pre = '<span style="color:red;">'; break; 43 case '33m': 44 case '33;33m': pre = '<span style="color:yellow;">'; break; 45 case '32m': 46 case '0;32m': pre = '<span style="color:lime;">'; break; 47 case '90m': pre = '<span style="color:gray;">'; break; 48 case 'K': 49 case '0K': 50 case '1K': 51 case '2K': break; 52 } 53 54 if (pre !== "") { 55 this.styles.push(pre); 56 } 57 58 output += part + pre + post; 59 } 60 61 var part = s.substring(current, s.length); 62 output += part; 63 return output; 64 } 65 }; 66 })(); 67 ;// Live commit updates 68 69 if(typeof(Drone) === 'undefined') { Drone = {}; } 70 71 (function () { 72 Drone.CommitUpdates = function(socket) { 73 if(typeof(socket) === "string") { 74 var url = [(window.location.protocol == 'https:' ? 'wss' : 'ws'), 75 '://', 76 window.location.host, 77 socket].join('') 78 this.socket = new WebSocket(url); 79 } else { 80 this.socket = socket; 81 } 82 83 this.lineFormatter = new Drone.LineFormatter(); 84 this.attach(); 85 } 86 87 Drone.CommitUpdates.prototype = { 88 lineBuffer: "", 89 autoFollow: false, 90 91 startOutput: function(el) { 92 if(typeof(el) === 'string') { 93 this.el = document.getElementById(el); 94 } else { 95 this.el = el; 96 } 97 98 if(!this.reqId) { 99 this.updateScreen(); 100 } 101 }, 102 103 stopOutput: function() { 104 this.stoppingRefresh = true; 105 }, 106 107 attach: function() { 108 this.socket.onopen = this.onOpen; 109 this.socket.onerror = this.onError; 110 this.socket.onmessage = this.onMessage.bind(this); 111 this.socket.onclose = this.onClose; 112 }, 113 114 updateScreen: function() { 115 if(this.lineBuffer.length > 0) { 116 this.el.innerHTML += this.lineBuffer; 117 this.lineBuffer = ''; 118 119 if (this.autoFollow) { 120 window.scrollTo(0, document.body.scrollHeight); 121 } 122 } 123 124 if(this.stoppingRefresh) { 125 this.stoppingRefresh = false; 126 } else { 127 window.requestAnimationFrame(this.updateScreen.bind(this)); 128 } 129 }, 130 131 onOpen: function() { 132 console.log('output websocket open'); 133 }, 134 135 onError: function(e) { 136 console.log('websocket error: ' + e); 137 }, 138 139 onMessage: function(e) { 140 this.lineBuffer += this.lineFormatter.format(e.data); 141 }, 142 143 onClose: function(e) { 144 console.log('output websocket closed: ' + JSON.stringify(e)); 145 window.location.reload(); 146 } 147 }; 148 149 // Polyfill rAF for older browsers 150 window.requestAnimationFrame = window.requestAnimationFrame || 151 window.webkitRequestAnimationFrame || 152 function(callback, element) { 153 return window.setTimeout(function() { 154 callback(+new Date()); 155 }, 1000 / 60); 156 }; 157 158 window.cancelRequestAnimationFrame = window.cancelRequestAnimationFrame || 159 window.cancelWebkitRequestAnimationFrame || 160 function(fn) { 161 window.clearTimeout(fn); 162 }; 163 164 })();