Created
November 30, 2011 13:37
-
-
Save spudtrooper/1409077 to your computer and use it in GitHub Desktop.
A bookmarklet to monitor a Jenkins build page, and play the theme from golden girls when the build breaks and play the theme from arrested development when the build is fixed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <a href='javascript:(function(){function k(r,q){for(var p in q){r.style[p]=q[p]}}function c(r,q){var p=document.createTextNode(r);if(q){q.appendChild(p)}return p}function e(p,s,r){var q=document.createElement(p);if(s){s.appendChild(q)}if(r){k(q,r)}return q}function j(q){try{console.log(q)}catch(p){}}function l(p){while(p.childNodes.length>0){p.removeChild(p.firstChild)}}function m(p){this.name=p;this.callbacks=[]}m.prototype={addListener:function(p){this.callbacks.push(p)},notifyListeners:function(r){var p=this.callbacks;j("notify "+p.length+" ["+this.name+"]("+r+")");for(var q=0;q<p.length;q++){p[q](r)}}};var n={None:"None",Success:"Success",Fail:"Fail",Pending:"Pending"};function d(){this.lastState=n.None;this.state=n.None;this.stateChangeEvent=new m("Change")}d.prototype={setState:function(p){this.lastState=this.state;this.state=p;j(this.lastState+" -> "+this.state);if(this.lastState!=this.state){this.stateChangeEvent.notifyListeners(this)}},getState:function(){return this.state},getLastState:function(){return this.lastState},getStateChangeEvent:function(){return this.stateChangeEvent},};function a(){var y={position:"fixed",bottom:"10px",right:"10px",backgroundColor:"#ddd",border:"1px solid black",padding:"5px",zIndez:"1000000000"};var t=this;var q=e("div",document.body,y);var z=e("div",q);var s=e("button",z);s.innerHTML="Success";s.addEventListener("click",function(){t.changeStateEvent.notifyListeners(n.Success)},true);var p=e("button",z);p.innerHTML="Fail";p.addEventListener("click",function(){t.changeStateEvent.notifyListeners(n.Fail)},true);var x=e("button",z);x.innerHTML="None";x.addEventListener("click",function(){t.changeStateEvent.notifyListeners(n.None)},true);var v={minWidth:"250px",minHeight:"250px",backgroundColor:"#aa7788",textAlign:"center"};var r=e("div",q,v);var u={fontSize:"48pt",color:"#000000",fontFamily:"Arial",paddingTop:"80px",};var w=e("div",r,u);this.el=q;this.mainDiv=r;this.mainText=w;this.changeStateEvent=new m("Change State")}a.prototype={Color:{None:"#000077",Success:"#007700",Fail:"#770000",Pending:"#770077"},updateWithState:function(q,t){var r=t;var s=this.Color;var p=s.None;if(r==n.Success){p=s.Success}else{if(r==n.Fail){p=s.Fail}else{if(r==n.Pending){p=s.Pending}}}this.mainDiv.style.backgroundColor=p;this.mainText.innerHTML=String(r)},getChangeStateEvent:function(){return this.changeStateEvent}};function o(r){var p;if(!r){p=""}else{p="http://www.youtube.com/v/"+r+"&hl=en&fs=1&autoplay=1"}j("playUrl: "+p);var r="__playUrlId__";var q=document.getElementById(r);if(!q){q=document.createElement("div");q.id=r;document.body.appendChild(q)}q.innerHTML="<object width=0 height=0><param name=autoplay value=true><param name=movie value="+p+"></param><param name=allowFullScreen value=true></param><param name=allowscriptaccess value=always></param><embed src="+p+" type=application/x-shockwave-flash allowscriptaccess=always allowfullscreen=true width=0 height=0></embed></object>";q.style.width="0px";q.style.height="0px"}function b(){}b.prototype={updateWithState:function(p,r){if(p==r){return}j("Playing for "+r);var q=r;if(q==n.None){this.playNone()}else{if(q==n.Success){this.playSuccess()}else{if(q==n.Fail){this.playFail()}}}},playNone:function(){o("")},playFail:function(){o("zYqPs0LInls")},playSuccess:function(){o("QFl7r2dUmTA")}};function h(t,r,u){this.model=t;this.view=r;this.player=u;var w=this;var q=this.model;var s=this.view;var x=this.player;s.getChangeStateEvent().addListener(function(p){q.setState(p)});q.getStateChangeEvent().addListener(function(v){var p=v.getLastState();var y=v.getState();s.updateWithState(p,y);x.updateWithState(p,y)})}h.prototype={showMenu:function(){this.view.updateWithState(this.model.getLastState(),this.model.getState())},updateState:function(p){this.model.setState(p)},};function f(p){var q=this;this.controller=p}const i=30*1000;f.prototype={go:function(){this.controller.showMenu();var p=this;p.checkState();setInterval(function(){p.checkState()},i)},checkState:function(){j("checkState");var t=document.getElementsByTagName("IMG");for(var q=0;q<t.length;q++){var p=t[q];if(!p.src){continue}var s=p.src;var r=null;if(s.match(/blue.png/)){r=n.Success}else{if(s.match(/red.png/)){r=n.Fail}else{if(s.match(/grey.png/)||s.match(/blue_anime.gif/)){r=n.None}}}if(!!r){this.controller.updateState(r);break}}}};function g(){var q=new a();var r=new d();var s=new b();var p=new h(r,q,s);var t=new f(p);t.go()}g()})();'>jenkins</a> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| (function() { | |
| function setStyle(el,style) { | |
| for (var i in style) { | |
| el.style[i] = style[i]; | |
| } | |
| } | |
| function createTextElement(text,onto) { | |
| var res = document.createTextNode(text); | |
| if (onto) onto.appendChild(res); | |
| return res; | |
| } | |
| function createElement(tag,onto,style) { | |
| var res = document.createElement(tag); | |
| if (onto) onto.appendChild(res); | |
| if (style) setStyle(res,style); | |
| return res; | |
| } | |
| function log(msg) { | |
| try { | |
| console.log(msg); | |
| } catch (e) {} | |
| } | |
| function removeChildren(el) { | |
| while (el.childNodes.length > 0) { | |
| el.removeChild(el.firstChild); | |
| } | |
| } | |
| function EventNotifier(name) { | |
| this.name = name; | |
| this.callbacks = []; | |
| } | |
| EventNotifier.prototype = { | |
| addListener: function(callback) { | |
| this.callbacks.push(callback); | |
| }, | |
| notifyListeners: function(value) { | |
| var cbs = this.callbacks; | |
| log("notify " + cbs.length + " [" + this.name + "](" + value + ")"); | |
| for (var i=0; i<cbs.length; i++) { | |
| cbs[i](value); | |
| } | |
| } | |
| }; | |
| var State = { | |
| None: "None", | |
| Success: "Success", | |
| Fail: "Fail", | |
| Pending: "Pending" | |
| } | |
| function Model() { | |
| this.lastState = State.None; | |
| this.state = State.None; | |
| this.stateChangeEvent = new EventNotifier("Change"); | |
| } | |
| Model.prototype = { | |
| /** State -> Void */ | |
| setState: function(newState) { | |
| this.lastState = this.state; | |
| this.state = newState; | |
| log(this.lastState + " -> " + this.state); | |
| if (this.lastState != this.state) { | |
| this.stateChangeEvent.notifyListeners(this); | |
| } | |
| }, | |
| /** Void -> State */ | |
| getState: function() { | |
| return this.state; | |
| }, | |
| /** Void -> State */ | |
| getLastState: function() { | |
| return this.lastState; | |
| }, | |
| /** Void -> EventNotifier(Model) */ | |
| getStateChangeEvent: function() { | |
| return this.stateChangeEvent; | |
| }, | |
| }; | |
| function View() { | |
| var elStyle = { | |
| "position": "fixed", | |
| "bottom": "10px", | |
| "right": "10px", | |
| "backgroundColor": "#ddd", | |
| "border": "1px solid black", | |
| "padding": "5px", | |
| "zIndez": "1000000000" | |
| }; | |
| var thiz = this; | |
| var el = createElement("div",document.body,elStyle); | |
| var row = createElement("div",el); | |
| var successButton = createElement("button",row); | |
| successButton.innerHTML = "Success"; | |
| successButton.addEventListener("click", | |
| function() { | |
| thiz.changeStateEvent. | |
| notifyListeners(State.Success); | |
| }, true); | |
| var failButton = createElement("button",row); | |
| failButton.innerHTML = "Fail"; | |
| failButton.addEventListener("click", | |
| function() { | |
| thiz.changeStateEvent. | |
| notifyListeners(State.Fail); | |
| }, true); | |
| var noneButton = createElement("button",row); | |
| noneButton.innerHTML = "None"; | |
| noneButton.addEventListener("click", | |
| function() { | |
| thiz.changeStateEvent. | |
| notifyListeners(State.None); | |
| }, true); | |
| var mainDivStyle = { | |
| "minWidth": "250px", | |
| "minHeight": "250px", | |
| "backgroundColor": "#aa7788", | |
| "textAlign": "center" | |
| }; | |
| var mainDiv = createElement("div",el,mainDivStyle); | |
| var mainTextStyle = { | |
| "fontSize": "48pt", | |
| "color": "#000000", | |
| "fontFamily": "Arial", | |
| "paddingTop": "80px", | |
| }; | |
| var mainText = createElement("div",mainDiv,mainTextStyle); | |
| this.el = el; | |
| this.mainDiv = mainDiv; | |
| this.mainText = mainText; | |
| this.changeStateEvent = new EventNotifier("Change State"); | |
| } | |
| View.prototype = { | |
| Color : { | |
| None: "#000077", | |
| Success: "#007700", | |
| Fail: "#770000", | |
| Pending: "#770077" | |
| }, | |
| updateWithState: function(oldState,newState) { | |
| var state = newState; | |
| var Color = this.Color; | |
| var color = Color.None; | |
| if (state == State.Success) { | |
| color = Color.Success; | |
| } else if (state == State.Fail) { | |
| color = Color.Fail; | |
| } else if (state == State.Pending) { | |
| color = Color.Pending; | |
| } | |
| this.mainDiv.style.backgroundColor = color; | |
| this.mainText.innerHTML = String(state); | |
| }, | |
| /** Void -> EventNotifier(State) */ | |
| getChangeStateEvent: function() { | |
| return this.changeStateEvent; | |
| } | |
| }; | |
| function playUrl(id) { | |
| var url; | |
| if (!id) { | |
| url = ""; | |
| } else { | |
| url = "http://www.youtube.com/v/" + id + "&hl=en&fs=1&autoplay=1"; | |
| } | |
| log("playUrl: " + url); | |
| var id = "__playUrlId__"; | |
| var div = document.getElementById(id); | |
| if (!div) { | |
| div = document.createElement("div"); | |
| div.id = id; | |
| document.body.appendChild(div); | |
| } | |
| div.innerHTML = "<object width=0 height=0><param name=autoplay value=true><param name=movie value=" | |
| + url | |
| + "></param><param name=allowFullScreen value=true></param><param name=allowscriptaccess value=always></param><embed src=" | |
| + url | |
| + " type=application/x-shockwave-flash allowscriptaccess=always allowfullscreen=true width=0 height=0></embed></object>" | |
| ; | |
| div.style.width = "0px"; | |
| div.style.height = "0px"; | |
| } | |
| function Player() { | |
| } | |
| Player.prototype = { | |
| updateWithState: function(oldState,newState) { | |
| if (oldState == newState) return; | |
| log("Playing for " + newState); | |
| var state = newState; | |
| if (state == State.None) { | |
| this.playNone(); | |
| } else if (state == State.Success) { | |
| this.playSuccess(); | |
| } else if (state == State.Fail) { | |
| this.playFail(); | |
| } | |
| }, | |
| playNone: function() { | |
| playUrl(""); | |
| }, | |
| playFail: function() { | |
| playUrl("zYqPs0LInls"); | |
| }, | |
| playSuccess: function() { | |
| playUrl("QFl7r2dUmTA"); | |
| } | |
| }; | |
| function Controller(model,view,player) { | |
| this.model = model; | |
| this.view = view; | |
| this.player = player; | |
| var thiz = this; | |
| var m = this.model; | |
| var v = this.view; | |
| var p = this.player; | |
| v.getChangeStateEvent().addListener(function(state) { | |
| m.setState(state); | |
| }); | |
| m.getStateChangeEvent().addListener(function(model) { | |
| var oldState = model.getLastState(); | |
| var newState = model.getState(); | |
| v.updateWithState(oldState,newState); | |
| p.updateWithState(oldState,newState); | |
| }); | |
| } | |
| Controller.prototype = { | |
| /** Void -> Void */ | |
| showMenu: function() { | |
| this.view.updateWithState(this.model.getLastState(), | |
| this.model.getState()); | |
| }, | |
| updateState: function(state) { | |
| this.model.setState(state); | |
| }, | |
| }; | |
| function App(controller) { | |
| var thiz = this; | |
| this.controller = controller; | |
| } | |
| const LOOP_PERIOD_MILLIS = 30 * 1000; | |
| App.prototype = { | |
| go: function() { | |
| this.controller.showMenu(); | |
| var thiz = this; | |
| thiz.checkState(); | |
| setInterval(function(){thiz.checkState();},LOOP_PERIOD_MILLIS); | |
| }, | |
| checkState: function() { | |
| log("checkState"); | |
| var imgs = document.getElementsByTagName("IMG"); | |
| for (var i=0; i<imgs.length; i++) { | |
| var img = imgs[i]; | |
| if (!img.src) continue; | |
| var src = img.src; | |
| var state = null; | |
| if (src.match(/blue.png/)) { | |
| state = State.Success | |
| } else if (src.match(/red.png/)) { | |
| state = State.Fail; | |
| } else if (src.match(/grey.png/) || src.match(/blue_anime.gif/)) { | |
| state = State.None; | |
| } | |
| if (!!state) { | |
| this.controller.updateState(state); | |
| break; | |
| } | |
| } | |
| } | |
| }; | |
| function main() { | |
| var view = new View(); | |
| var model = new Model(); | |
| var player = new Player(); | |
| var controller = new Controller(model,view,player); | |
| var app = new App(controller); | |
| app.go(); | |
| } | |
| main(); | |
| })(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment