From 07d3a385b977b518b2f727b347526c107ca970ce Mon Sep 17 00:00:00 2001 From: Zach Saucier Date: Mon, 19 Nov 2018 19:17:25 -0500 Subject: [PATCH] Added theme selector in GUI --- content_script.js | 120 ++++++++++++++++++----------- dark-styles.css | 184 ++++++++++++++++++++++++++++++++++++++++++++ default-styles.css | 8 +- manifest.json | 3 +- options.js | 30 ++++++-- required-styles.css | 2 +- 6 files changed, 291 insertions(+), 56 deletions(-) create mode 100644 dark-styles.css diff --git a/content_script.js b/content_script.js index 2ae1ab2..d28513f 100644 --- a/content_script.js +++ b/content_script.js @@ -285,20 +285,7 @@ var leavePres = false; // Given a chrome storage object add them to our local stylsheet obj function getStylesFromStorage(storage) { for(var key in storage) { - // Convert the old format into the new format - if(key === "just-read-stylesheets") { - // Save each stylesheet in the new format - for(var stylesheet in storage[key]) { - var obj = {}; - obj['jr-' + stylesheet] = storage[key][stylesheet]; - chrome.storage.sync.set(obj); - stylesheetObj[stylesheet] = storage[key][stylesheet]; - } - - // Remove the old format - removeStyleFromStorage(key); - - } else if(key.substring(0, 3) === "jr-") { // Get stylesheets in the new format + if(key.substring(0, 3) === "jr-") { // Get stylesheets in the new format stylesheetObj[key.substring(3)] = storage[key]; } else if(key === "leave-pres") { leavePres = storage[key]; @@ -633,7 +620,7 @@ function getStyles() { var needsUpdate = false; chrome.storage.sync.get('stylesheet-version', function (versionResult) { - // If the user has a version of the stylesheets and it is less than the cufrent one, update it + // If the user has a version of the stylesheets and it is less than the current one, update it if(isEmpty(versionResult) || versionResult['stylesheet-version'] < stylesheetVersion) { chrome.storage.sync.set({'stylesheet-version': stylesheetVersion}); @@ -645,7 +632,7 @@ function getStyles() { || needsUpdate) { // Update the default stylesheet if it's on a previous version // Open the default CSS file and save it to our object - var xhr = new XMLHttpRequest(); + let xhr = new XMLHttpRequest(); xhr.open('GET', chrome.extension.getURL('default-styles.css'), true); xhr.onreadystatechange = function() { if(xhr.readyState == XMLHttpRequest.DONE && xhr.status == 200) { @@ -661,6 +648,19 @@ function getStyles() { } xhr.send(); + let xhr2 = new XMLHttpRequest(); + xhr2.open('GET', chrome.extension.getURL("dark-styles.css"), true); + xhr2.onreadystatechange = function() { + if(xhr2.readyState == XMLHttpRequest.DONE && xhr2.status == 200) { + // Save the file's contents to our object + stylesheetObj["dark-styles.css"] = xhr2.responseText; + + // Save it to Chrome storage + setStylesOfStorage(); + } + } + xhr2.send(); + needsUpdate = false; return; @@ -802,7 +802,7 @@ function addExtInfo() { // Add the theme editor button var datGUI; function addGUI() { - var dat=dat||{};dat.gui=dat.gui||{},dat.utils=dat.utils||{},dat.controllers=dat.controllers||{},dat.dom=dat.dom||{},dat.color=dat.color||{},dat.utils.css=function(){return{load:function(a,b){b=b||document;var c=b.createElement("link");c.type="text/css",c.rel="stylesheet",c.href=a,b.getElementsByTagName("head")[0].appendChild(c)},inject:function(a,b){b=b||document;var c=document.createElement("style");c.type="text/css",c.innerHTML=a,b.getElementsByTagName("head")[0].appendChild(c)}}}(),dat.utils.common=function(){var a=Array.prototype.forEach,b=Array.prototype.slice;return{BREAK:{},extend:function(a){return this.each(b.call(arguments,1),function(b){for(var c in b)this.isUndefined(b[c])||(a[c]=b[c])},this),a},defaults:function(a){return this.each(b.call(arguments,1),function(b){for(var c in b)this.isUndefined(a[c])&&(a[c]=b[c])},this),a},compose:function(){var a=b.call(arguments);return function(){for(var c=b.call(arguments),d=a.length-1;0<=d;d--)c=[a[d].apply(this,c)];return c[0]}},each:function(b,c,d){if(b)if(a&&b.forEach&&b.forEach===a)b.forEach(c,d);else if(b.length===b.length+0)for(var e=0,f=b.length;ethis.__max&&(a=this.__max),void 0!==this.__step&&0!=a%this.__step&&(a=Math.round(a/this.__step)*this.__step),d.superclass.prototype.setValue.call(this,a)},min:function(a){return this.__min=a,this},max:function(a){return this.__max=a,this},step:function(a){return this.__impliedStep=this.__step=a,this.__precision=c(a),this}}),d}(dat.controllers.Controller,dat.utils.common),dat.controllers.NumberControllerBox=function(a,b,c){var d=function(a,e,f){function g(){var a=parseFloat(j.__input.value);c.isNaN(a)||j.setValue(a)}function h(a){var b=k-a.clientY;j.setValue(j.getValue()+b*j.__impliedStep),k=a.clientY}function i(){b.unbind(window,"mousemove",h),b.unbind(window,"mouseup",i)}this.__truncationSuspended=!1,d.superclass.call(this,a,e,f);var k,j=this;this.__input=document.createElement("input"),this.__input.setAttribute("type","text"),b.bind(this.__input,"change",g),b.bind(this.__input,"blur",function(){g(),j.__onFinishChange&&j.__onFinishChange.call(j,j.getValue())}),b.bind(this.__input,"mousedown",function(a){b.bind(window,"mousemove",h),b.bind(window,"mouseup",i),k=a.clientY}),b.bind(this.__input,"keydown",function(a){13===a.keyCode&&(j.__truncationSuspended=!0,this.blur(),j.__truncationSuspended=!1)}),this.updateDisplay(),this.domElement.appendChild(this.__input)};return d.superclass=a,c.extend(d.prototype,a.prototype,{updateDisplay:function(){var b,a=this.__input;if(this.__truncationSuspended)b=this.getValue();else{b=this.getValue();var c=Math.pow(10,this.__precision);b=Math.round(b*c)/c}return a.value=b,d.superclass.prototype.updateDisplay.call(this)}}),d}(dat.controllers.NumberController,dat.dom.dom,dat.utils.common),dat.controllers.NumberControllerSlider=function(a,b,c,d,e){function f(a,b,c,d,e){return d+(a-b)/(c-b)*(e-d)}var g=function(a,c,d,e,h){function i(a){a.preventDefault();var c=b.getOffset(k.__background),d=b.getWidth(k.__background);return k.setValue(f(a.clientX,c.left,c.left+d,k.__min,k.__max)),!1}function j(){b.unbind(window,"mousemove",i),b.unbind(window,"mouseup",j),k.__onFinishChange&&k.__onFinishChange.call(k,k.getValue())}g.superclass.call(this,a,c,{min:d,max:e,step:h});var k=this;this.__background=document.createElement("div"),this.__foreground=document.createElement("div"),b.bind(this.__background,"mousedown",function(a){b.bind(window,"mousemove",i),b.bind(window,"mouseup",j),i(a)}),b.addClass(this.__background,"slider"),b.addClass(this.__foreground,"slider-fg"),this.updateDisplay(),this.__background.appendChild(this.__foreground),this.domElement.appendChild(this.__background)};return g.superclass=a,g.useDefaultStyles=function(){c.inject(e)},d.extend(g.prototype,a.prototype,{updateDisplay:function(){var a=(this.getValue()-this.__min)/(this.__max-this.__min);return this.__foreground.style.width=100*a+"%",g.superclass.prototype.updateDisplay.call(this)}}),g}(dat.controllers.NumberController,dat.dom.dom,dat.utils.css,dat.utils.common,"/**\n * dat-gui JavaScript Controller Library\n * http://code.google.com/p/dat-gui\n *\n * Copyright 2011 Data Arts Team, Google Creative Lab\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n */\n\n.slider {\n box-shadow: inset 0 2px 4px rgba(0,0,0,0.15);\n height: 1em;\n border-radius: 1em;\n background-color: #eee;\n padding: 0 0.5em;\n overflow: hidden;\n}\n\n.slider-fg {\n padding: 1px 0 2px 0;\n background-color: #aaa;\n height: 1em;\n margin-left: -0.5em;\n padding-right: 0.5em;\n border-radius: 1em 0 0 1em;\n}\n\n.slider-fg:after {\n display: inline-block;\n border-radius: 1em;\n background-color: #fff;\n border: 1px solid #aaa;\n content: '';\n float: right;\n margin-right: -1em;\n margin-top: -1px;\n height: 0.9em;\n width: 0.9em;\n}"),dat.controllers.FunctionController=function(a,b,c){var d=function(a,c,e){d.superclass.call(this,a,c);var f=this;this.__button=document.createElement("div"),this.__button.innerHTML=void 0===e?"Fire":e,b.bind(this.__button,"click",function(a){return a.preventDefault(),f.fire(),!1}),b.addClass(this.__button,"button"),this.domElement.appendChild(this.__button)};return d.superclass=a,c.extend(d.prototype,a.prototype,{fire:function(){this.__onChange&&this.__onChange.call(this),this.getValue().call(this.object),this.__onFinishChange&&this.__onFinishChange.call(this,this.getValue())}}),d}(dat.controllers.Controller,dat.dom.dom,dat.utils.common),dat.controllers.BooleanController=function(a,b,c){var d=function(a,c){d.superclass.call(this,a,c);var e=this;this.__prev=this.getValue(),this.__checkbox=document.createElement("input"),this.__checkbox.setAttribute("type","checkbox"),b.bind(this.__checkbox,"change",function(){e.setValue(!e.__prev)},!1),this.domElement.appendChild(this.__checkbox),this.updateDisplay()};return d.superclass=a,c.extend(d.prototype,a.prototype,{setValue:function(a){return a=d.superclass.prototype.setValue.call(this,a),this.__onFinishChange&&this.__onFinishChange.call(this,this.getValue()),this.__prev=this.getValue(),a},updateDisplay:function(){return!0===this.getValue()?(this.__checkbox.setAttribute("checked","checked"),this.__checkbox.checked=!0):this.__checkbox.checked=!1,d.superclass.prototype.updateDisplay.call(this)}}),d}(dat.controllers.Controller,dat.dom.dom,dat.utils.common),dat.color.toString=function(a){return function(b){if(1==b.a||a.isUndefined(b.a)){for(b=b.hex.toString(16);6>b.length;)b="0"+b;return"#"+b}return"rgba("+Math.round(b.r)+","+Math.round(b.g)+","+Math.round(b.b)+","+b.a+")"}}(dat.utils.common),dat.color.interpret=function(a,b){var c,d,e=[{litmus:b.isString,conversions:{THREE_CHAR_HEX:{read:function(a){return a=a.match(/^#([A-F0-9])([A-F0-9])([A-F0-9])$/i),null!==a&&{space:"HEX",hex:parseInt("0x"+a[1].toString()+a[1].toString()+a[2].toString()+a[2].toString()+a[3].toString()+a[3].toString())}},write:a},SIX_CHAR_HEX:{read:function(a){return a=a.match(/^#([A-F0-9]{6})$/i),null!==a&&{space:"HEX",hex:parseInt("0x"+a[1].toString())}},write:a},CSS_RGB:{read:function(a){return a=a.match(/^rgb\(\s*(.+)\s*,\s*(.+)\s*,\s*(.+)\s*\)/),null!==a&&{space:"RGB",r:parseFloat(a[1]),g:parseFloat(a[2]),b:parseFloat(a[3])}},write:a},CSS_RGBA:{read:function(a){return a=a.match(/^rgba\(\s*(.+)\s*,\s*(.+)\s*,\s*(.+)\s*\,\s*(.+)\s*\)/),null!==a&&{space:"RGB",r:parseFloat(a[1]),g:parseFloat(a[2]),b:parseFloat(a[3]),a:parseFloat(a[4])}},write:a}}},{litmus:b.isNumber,conversions:{HEX:{read:function(a){return{space:"HEX",hex:a,conversionName:"HEX"}},write:function(a){return a.hex}}}},{litmus:b.isArray,conversions:{RGB_ARRAY:{read:function(a){return 3==a.length&&{space:"RGB",r:a[0],g:a[1],b:a[2]}},write:function(a){return[a.r,a.g,a.b]}},RGBA_ARRAY:{read:function(a){return 4==a.length&&{space:"RGB",r:a[0],g:a[1],b:a[2],a:a[3]}},write:function(a){return[a.r,a.g,a.b,a.a]}}}},{litmus:b.isObject,conversions:{RGBA_OBJ:{read:function(a){return!!(b.isNumber(a.r)&&b.isNumber(a.g)&&b.isNumber(a.b)&&b.isNumber(a.a))&&{space:"RGB",r:a.r,g:a.g,b:a.b,a:a.a}},write:function(a){return{r:a.r,g:a.g,b:a.b,a:a.a}}},RGB_OBJ:{read:function(a){return!!(b.isNumber(a.r)&&b.isNumber(a.g)&&b.isNumber(a.b))&&{space:"RGB",r:a.r,g:a.g,b:a.b}},write:function(a){return{r:a.r,g:a.g,b:a.b}}},HSVA_OBJ:{read:function(a){return!!(b.isNumber(a.h)&&b.isNumber(a.s)&&b.isNumber(a.v)&&b.isNumber(a.a))&&{space:"HSV",h:a.h,s:a.s,v:a.v,a:a.a}},write:function(a){return{h:a.h,s:a.s,v:a.v,a:a.a}}},HSV_OBJ:{read:function(a){return!!(b.isNumber(a.h)&&b.isNumber(a.s)&&b.isNumber(a.v))&&{space:"HSV",h:a.h,s:a.s,v:a.v}},write:function(a){return{h:a.h,s:a.s,v:a.v}}}}}];return function(){d=!1;var a=1\n\n Here\'s the new load parameter for your GUI\'s constructor:\n\n \n\n
\n\n Automatically save\n values to localStorage on exit.\n\n
The values saved to localStorage will\n override those passed to dat.GUI\'s constructor. This makes it\n easier to work incrementally, but localStorage is fragile,\n and your friends may not see the same values you do.\n \n
\n \n
\n\n',".dg {\n /** Clear list styles */\n /* Auto-place container */\n /* Auto-placed GUI's */\n /* Line items that don't contain folders. */\n /** Folder names */\n /** Hides closed items */\n /** Controller row */\n /** Name-half (left) */\n /** Controller-half (right) */\n /** Controller placement */\n /** Shorter number boxes when slider is present. */\n /** Ensure the entire boolean and function row shows a hand */ }\n .dg ul {\n list-style: none;\n margin: 0;\n padding: 0;\n width: 100%;\n clear: both; }\n .dg.ac {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n height: 0;\n z-index: 0; }\n .dg:not(.ac) .main {\n /** Exclude mains in ac so that we don't hide close button */\n overflow: hidden; }\n .dg.main {\n -webkit-transition: opacity 0.1s linear;\n -o-transition: opacity 0.1s linear;\n -moz-transition: opacity 0.1s linear;\n transition: opacity 0.1s linear; }\n .dg.main.taller-than-window {\n overflow-y: auto; }\n .dg.main.taller-than-window .close-button {\n opacity: 1;\n /* TODO, these are style notes */\n margin-top: -1px;\n border-top: 1px solid #2c2c2c; }\n .dg.main ul.closed .close-button {\n opacity: 1 !important; }\n .dg.main:hover .close-button,\n .dg.main .close-button.drag {\n opacity: 1; }\n .dg.main .close-button {\n /*opacity: 0;*/\n -webkit-transition: opacity 0.1s linear;\n -o-transition: opacity 0.1s linear;\n -moz-transition: opacity 0.1s linear;\n transition: opacity 0.1s linear;\n border: 0;\n position: absolute;\n line-height: 19px;\n height: 20px;\n /* TODO, these are style notes */\n cursor: pointer;\n text-align: center;\n background-color: #000; }\n .dg.main .close-button:hover {\n background-color: #111; }\n .dg.a {\n float: right;\n margin-right: 15px;\n overflow-x: hidden; }\n .dg.a.has-save > ul {\n margin-top: 27px; }\n .dg.a.has-save > ul.closed {\n margin-top: 0; }\n .dg.a .save-row {\n position: fixed;\n top: 0;\n z-index: 1002; }\n .dg li {\n -webkit-transition: height 0.1s ease-out;\n -o-transition: height 0.1s ease-out;\n -moz-transition: height 0.1s ease-out;\n transition: height 0.1s ease-out; }\n .dg li:not(.folder) {\n cursor: auto;\n height: 27px;\n line-height: 27px;\n overflow: hidden;\n padding: 0 4px 0 5px; }\n .dg li.folder {\n padding: 0;\n border-left: 4px solid rgba(0, 0, 0, 0); }\n .dg li.title {\n cursor: pointer;\n margin-left: -4px; }\n .dg .closed li:not(.title),\n .dg .closed ul li,\n .dg .closed ul li > * {\n height: 0;\n overflow: hidden;\n border: 0; }\n .dg .cr {\n clear: both;\n padding-left: 3px;\n height: 27px; }\n .dg .property-name {\n cursor: default;\n float: left;\n clear: left;\n width: 40%;\n overflow: hidden;\n text-overflow: ellipsis; }\n .dg .c {\n float: left;\n width: 60%; }\n .dg .c input[type=text] {\n border: 0;\n margin-top: 4px;\n padding: 3px;\n width: 100%;\n float: right; }\n .dg .has-slider input[type=text] {\n width: 30%;\n /*display: none;*/\n margin-left: 0; }\n .dg .slider {\n float: left;\n width: 66%;\n margin-left: -5px;\n margin-right: 0;\n height: 19px;\n margin-top: 4px; }\n .dg .slider-fg {\n height: 100%; }\n .dg .c input[type=checkbox] {\n margin-top: 9px; }\n .dg .c select {\n margin-top: 5px; }\n .dg .cr.function,\n .dg .cr.function .property-name,\n .dg .cr.function *,\n .dg .cr.boolean,\n .dg .cr.boolean * {\n cursor: pointer; }\n .dg .selector {\n display: none;\n position: absolute;\n margin-left: -9px;\n margin-top: 23px;\n z-index: 10; }\n .dg .c:hover .selector,\n .dg .selector.drag {\n display: block; }\n .dg li.save-row {\n padding: 0; }\n .dg li.save-row .button {\n display: inline-block;\n padding: 0px 6px; }\n .dg.dialogue {\n background-color: #222;\n width: 460px;\n padding: 15px;\n font-size: 13px;\n line-height: 15px; }\n\n/* TODO Separate style and structure */\n#dg-new-constructor {\n padding: 10px;\n color: #222;\n font-family: Monaco, monospace;\n font-size: 10px;\n border: 0;\n resize: none;\n box-shadow: inset 1px 1px 1px #888;\n word-wrap: break-word;\n margin: 12px 0;\n display: block;\n width: 440px;\n overflow-y: scroll;\n height: 100px;\n position: relative; }\n\n#dg-local-explain {\n display: none;\n font-size: 11px;\n line-height: 17px;\n border-radius: 3px;\n background-color: #333;\n padding: 8px;\n margin-top: 10px; }\n #dg-local-explain code {\n font-size: 10px; }\n\n#dat-gui-save-locally {\n display: none; }\n\n/** Main type */\n.dg {\n color: #eee;\n font: 11px 'Lucida Grande', sans-serif;\n text-shadow: 0 -1px 0 #111;\n /** Auto place */\n /* Controller row,
  • */\n /** Controllers */ }\n .dg.main {\n /** Scrollbar */ }\n .dg.main::-webkit-scrollbar {\n width: 5px;\n background: #1a1a1a; }\n .dg.main::-webkit-scrollbar-corner {\n height: 0;\n display: none; }\n .dg.main::-webkit-scrollbar-thumb {\n border-radius: 5px;\n background: #676767; }\n .dg li:not(.folder) {\n background: #1a1a1a;\n border-bottom: 1px solid #2c2c2c; }\n .dg li.save-row {\n line-height: 25px;\n background: #dad5cb;\n border: 0; }\n .dg li.save-row select {\n margin-left: 5px;\n width: 108px; }\n .dg li.save-row .button {\n margin-left: 5px;\n margin-top: 1px;\n border-radius: 2px;\n font-size: 9px;\n line-height: 7px;\n padding: 4px 4px 5px 4px;\n background: #c5bdad;\n color: #fff;\n text-shadow: 0 1px 0 #b0a58f;\n box-shadow: 0 -1px 0 #b0a58f;\n cursor: pointer; }\n .dg li.save-row .button.gears {\n background: #c5bdad url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAANCAYAAAB/9ZQ7AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAQJJREFUeNpiYKAU/P//PwGIC/ApCABiBSAW+I8AClAcgKxQ4T9hoMAEUrxx2QSGN6+egDX+/vWT4e7N82AMYoPAx/evwWoYoSYbACX2s7KxCxzcsezDh3evFoDEBYTEEqycggWAzA9AuUSQQgeYPa9fPv6/YWm/Acx5IPb7ty/fw+QZblw67vDs8R0YHyQhgObx+yAJkBqmG5dPPDh1aPOGR/eugW0G4vlIoTIfyFcA+QekhhHJhPdQxbiAIguMBTQZrPD7108M6roWYDFQiIAAv6Aow/1bFwXgis+f2LUAynwoIaNcz8XNx3Dl7MEJUDGQpx9gtQ8YCueB+D26OECAAQDadt7e46D42QAAAABJRU5ErkJggg==) 2px 1px no-repeat;\n height: 7px;\n width: 8px; }\n .dg li.save-row .button:hover {\n background-color: #bab19e;\n box-shadow: 0 -1px 0 #b0a58f; }\n .dg li.folder {\n border-bottom: 0; }\n .dg li.title {\n padding-left: 16px;\n background: black url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlI+hKgFxoCgAOw==) 6px 10px no-repeat;\n cursor: pointer;\n border-bottom: 1px solid rgba(255, 255, 255, 0.2); }\n .dg .closed li.title {\n background-image: url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlGIWqMCbWAEAOw==); }\n .dg .cr.boolean {\n border-left: 3px solid #806787; }\n .dg .cr.function {\n border-left: 3px solid #e61d5f; }\n .dg .cr.number {\n border-left: 3px solid #2fa1d6; }\n .dg .cr.number input[type=text] {\n color: #2fa1d6; }\n .dg .cr.string {\n border-left: 3px solid #1ed36f; }\n .dg .cr.string input[type=text] {\n color: #1ed36f; }\n .dg .cr.function:hover, .dg .cr.boolean:hover {\n background: #111; }\n .dg .c input[type=text] {\n background: #303030;\n outline: none; }\n .dg .c input[type=text]:hover {\n background: #3c3c3c; }\n .dg .c input[type=text]:focus {\n background: #494949;\n color: #fff; }\n .dg .c .slider {\n background: #303030;\n cursor: ew-resize; }\n .dg .c .slider-fg {\n background: #2fa1d6; }\n .dg .c .slider:hover {\n background: #3c3c3c; }\n .dg .c .slider:hover .slider-fg {\n background: #44abda; }\n",dat.controllers.factory=function(a,b,c,d,e,f,g){return function(h,i,j,k){var l=h[i];return g.isArray(j)||g.isObject(j)?new a(h,i,j):g.isNumber(l)?g.isNumber(j)&&g.isNumber(k)?new c(h,i,j,k):new b(h,i,{min:j,max:k}):g.isString(l)?new d(h,i):g.isFunction(l)?new e(h,i,""):g.isBoolean(l)?new f(h,i):void 0}}(dat.controllers.OptionController,dat.controllers.NumberControllerBox,dat.controllers.NumberControllerSlider,dat.controllers.StringController=function(a,b,c){var d=function(a,c){function e(){f.setValue(f.__input.value)}d.superclass.call(this,a,c);var f=this;this.__input=document.createElement("input"),this.__input.setAttribute("type","text"),b.bind(this.__input,"keyup",e),b.bind(this.__input,"change",e),b.bind(this.__input,"blur",function(){f.__onFinishChange&&f.__onFinishChange.call(f,f.getValue())}),b.bind(this.__input,"keydown",function(a){13===a.keyCode&&this.blur()}),this.updateDisplay(),this.domElement.appendChild(this.__input)};return d.superclass=a,c.extend(d.prototype,a.prototype,{updateDisplay:function(){return b.isActive(this.__input)||(this.__input.value=this.getValue()),d.superclass.prototype.updateDisplay.call(this)}}),d}(dat.controllers.Controller,dat.dom.dom,dat.utils.common),dat.controllers.FunctionController,dat.controllers.BooleanController,dat.utils.common),dat.controllers.Controller,dat.controllers.BooleanController,dat.controllers.FunctionController,dat.controllers.NumberControllerBox,dat.controllers.NumberControllerSlider,dat.controllers.OptionController,dat.controllers.ColorController=function(a,b,c,d,e){function f(a,b,c,d){a.style.background="",e.each(i,function(e){a.style.cssText+="background: "+e+"linear-gradient("+b+", "+c+" 0%, "+d+" 100%); "})}function g(a){a.style.background="",a.style.cssText+="background: -moz-linear-gradient(top, #ff0000 0%, #ff00ff 17%, #0000ff 34%, #00ffff 50%, #00ff00 67%, #ffff00 84%, #ff0000 100%);",a.style.cssText+="background: -webkit-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);",a.style.cssText+="background: -o-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);",a.style.cssText+="background: -ms-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);",a.style.cssText+="background: linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);"}var h=function(a,i){function j(a){n(a),b.bind(window,"mousemove",n),b.bind(window,"mouseup",k)}function k(){b.unbind(window,"mousemove",n),b.unbind(window,"mouseup",k)}function l(){var a=d(this.value);!1!==a?(p.__color.__state=a,p.setValue(p.__color.toOriginal())):this.value=p.__color.toString()}function m(){b.unbind(window,"mousemove",o),b.unbind(window,"mouseup",m)}function n(a){a.preventDefault();var c=b.getWidth(p.__saturation_field),d=b.getOffset(p.__saturation_field),e=(a.clientX-d.left+document.body.scrollLeft)/c;return a=1-(a.clientY-d.top+document.body.scrollTop)/c,1a&&(a=0),1e&&(e=0),p.__color.v=a,p.__color.s=e,p.setValue(p.__color.toOriginal()),!1}function o(a){a.preventDefault();var c=b.getHeight(p.__hue_field),d=b.getOffset(p.__hue_field);return a=1-(a.clientY-d.top+document.body.scrollTop)/c,1a&&(a=0),p.__color.h=360*a,p.setValue(p.__color.toOriginal()),!1}h.superclass.call(this,a,i),this.__color=new c(this.getValue()),this.__temp=new c(0);var p=this;this.domElement=document.createElement("div"),b.makeSelectable(this.domElement,!1),this.__selector=document.createElement("div"),this.__selector.className="selector",this.__saturation_field=document.createElement("div"),this.__saturation_field.className="saturation-field",this.__field_knob=document.createElement("div"),this.__field_knob.className="field-knob",this.__field_knob_border="2px solid ",this.__hue_knob=document.createElement("div"),this.__hue_knob.className="hue-knob",this.__hue_field=document.createElement("div"),this.__hue_field.className="hue-field",this.__input=document.createElement("input"),this.__input.type="text",this.__input_textShadow="0 1px 1px ",b.bind(this.__input,"keydown",function(a){13===a.keyCode&&l.call(this)}),b.bind(this.__input,"blur",l),b.bind(this.__selector,"mousedown",function(a){b.addClass(this,"drag").bind(window,"mouseup",function(a){b.removeClass(p.__selector,"drag")})});var q=document.createElement("div");e.extend(this.__selector.style,{width:"122px",height:"102px",padding:"3px",backgroundColor:"#222",boxShadow:"0px 1px 3px rgba(0,0,0,0.3)"}),e.extend(this.__field_knob.style,{position:"absolute",width:"12px",height:"12px",border:this.__field_knob_border+(.5>this.__color.v?"#fff":"#000"),boxShadow:"0px 1px 3px rgba(0,0,0,0.5)",borderRadius:"12px",zIndex:1}),e.extend(this.__hue_knob.style,{position:"absolute",width:"15px",height:"2px",borderRight:"4px solid #fff",zIndex:1}),e.extend(this.__saturation_field.style,{width:"100px",height:"100px",border:"1px solid #555",marginRight:"3px",display:"inline-block",cursor:"pointer"}),e.extend(q.style,{width:"100%",height:"100%",background:"none"}),f(q,"top","rgba(0,0,0,0)","#000"),e.extend(this.__hue_field.style,{width:"15px",height:"100px",display:"inline-block",border:"1px solid #555",cursor:"ns-resize"}),g(this.__hue_field),e.extend(this.__input.style,{outline:"none",textAlign:"center",color:"#fff",border:0,fontWeight:"bold",textShadow:this.__input_textShadow+"rgba(0,0,0,0.7)"}),b.bind(this.__saturation_field,"mousedown",j),b.bind(this.__field_knob,"mousedown",j),b.bind(this.__hue_field,"mousedown",function(a){o(a),b.bind(window,"mousemove",o),b.bind(window,"mouseup",m)}),this.__saturation_field.appendChild(q),this.__selector.appendChild(this.__field_knob),this.__selector.appendChild(this.__saturation_field),this.__selector.appendChild(this.__hue_field),this.__hue_field.appendChild(this.__hue_knob),this.domElement.appendChild(this.__input),this.domElement.appendChild(this.__selector),this.updateDisplay()};h.superclass=a,e.extend(h.prototype,a.prototype,{updateDisplay:function(){var a=d(this.getValue());if(!1!==a){var b=!1;e.each(c.COMPONENTS,function(c){if(!e.isUndefined(a[c])&&!e.isUndefined(this.__color.__state[c])&&a[c]!==this.__color.__state[c])return b=!0,{}},this),b&&e.extend(this.__color.__state,a)}e.extend(this.__temp.__state,this.__color.__state),this.__temp.a=1;var g=.5>this.__color.v||.5a&&(a+=1),{h:360*a,s:d/e,v:e/255})},rgb_to_hex:function(a,b,c){return a=this.hex_with_component(0,2,a),a=this.hex_with_component(a,1,b),a=this.hex_with_component(a,0,c)},component_from_hex:function(a,b){return a>>8*b&255},hex_with_component:function(b,c,d){return d<<(a=8*c)|b&~(255<this.__max&&(a=this.__max),void 0!==this.__step&&0!=a%this.__step&&(a=Math.round(a/this.__step)*this.__step),d.superclass.prototype.setValue.call(this,a)},min:function(a){return this.__min=a,this},max:function(a){return this.__max=a,this},step:function(a){return this.__impliedStep=this.__step=a,this.__precision=c(a),this}}),d}(dat.controllers.Controller,dat.utils.common),dat.controllers.NumberControllerBox=function(a,b,c){var d=function(a,e,f){function g(){var a=parseFloat(j.__input.value);c.isNaN(a)||j.setValue(a)}function h(a){var b=k-a.clientY;j.setValue(j.getValue()+b*j.__impliedStep),k=a.clientY}function i(){b.unbind(window,"mousemove",h),b.unbind(window,"mouseup",i)}this.__truncationSuspended=!1,d.superclass.call(this,a,e,f);var k,j=this;this.__input=document.createElement("input"),this.__input.setAttribute("type","text"),b.bind(this.__input,"change",g),b.bind(this.__input,"blur",function(){g(),j.__onFinishChange&&j.__onFinishChange.call(j,j.getValue())}),b.bind(this.__input,"mousedown",function(a){b.bind(window,"mousemove",h),b.bind(window,"mouseup",i),k=a.clientY}),b.bind(this.__input,"keydown",function(a){13===a.keyCode&&(j.__truncationSuspended=!0,this.blur(),j.__truncationSuspended=!1)}),this.updateDisplay(),this.domElement.appendChild(this.__input)};return d.superclass=a,c.extend(d.prototype,a.prototype,{updateDisplay:function(){var b,a=this.__input;if(this.__truncationSuspended)b=this.getValue();else{b=this.getValue();var c=Math.pow(10,this.__precision);b=Math.round(b*c)/c}return a.value=b,d.superclass.prototype.updateDisplay.call(this)}}),d}(dat.controllers.NumberController,dat.dom.dom,dat.utils.common),dat.controllers.NumberControllerSlider=function(a,b,c,d,e){function f(a,b,c,d,e){return d+(a-b)/(c-b)*(e-d)}var g=function(a,c,d,e,h){function i(a){a.preventDefault();var c=b.getOffset(k.__background),d=b.getWidth(k.__background);return k.setValue(f(a.clientX,c.left,c.left+d,k.__min,k.__max)),!1}function j(){b.unbind(window,"mousemove",i),b.unbind(window,"mouseup",j),k.__onFinishChange&&k.__onFinishChange.call(k,k.getValue())}g.superclass.call(this,a,c,{min:d,max:e,step:h});var k=this;this.__background=document.createElement("div"),this.__foreground=document.createElement("div"),b.bind(this.__background,"mousedown",function(a){b.bind(window,"mousemove",i),b.bind(window,"mouseup",j),i(a)}),b.addClass(this.__background,"slider"),b.addClass(this.__foreground,"slider-fg"),this.updateDisplay(),this.__background.appendChild(this.__foreground),this.domElement.appendChild(this.__background)};return g.superclass=a,g.useDefaultStyles=function(){c.inject(e)},d.extend(g.prototype,a.prototype,{updateDisplay:function(){var a=(this.getValue()-this.__min)/(this.__max-this.__min);return this.__foreground.style.width=100*a+"%",g.superclass.prototype.updateDisplay.call(this)}}),g}(dat.controllers.NumberController,dat.dom.dom,dat.utils.css,dat.utils.common,"/**\n * dat-gui JavaScript Controller Library\n * http://code.google.com/p/dat-gui\n *\n * Copyright 2011 Data Arts Team, Google Creative Lab\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n */\n\n.slider {\n box-shadow: inset 0 2px 4px rgba(0,0,0,0.15);\n height: 1em;\n border-radius: 1em;\n background-color: #eee;\n padding: 0 0.5em;\n overflow: hidden;\n}\n\n.slider-fg {\n padding: 1px 0 2px 0;\n background-color: #aaa;\n height: 1em;\n margin-left: -0.5em;\n padding-right: 0.5em;\n border-radius: 1em 0 0 1em;\n}\n\n.slider-fg:after {\n display: inline-block;\n border-radius: 1em;\n background-color: #fff;\n border: 1px solid #aaa;\n content: '';\n float: right;\n margin-right: -1em;\n margin-top: -1px;\n height: 0.9em;\n width: 0.9em;\n}"),dat.controllers.FunctionController=function(a,b,c){var d=function(a,c,e){d.superclass.call(this,a,c);var f=this;this.__button=document.createElement("div"),this.__button.innerHTML=void 0===e?"Fire":e,b.bind(this.__button,"click",function(a){return a.preventDefault(),f.fire(),!1}),b.addClass(this.__button,"button"),this.domElement.appendChild(this.__button)};return d.superclass=a,c.extend(d.prototype,a.prototype,{fire:function(){this.__onChange&&this.__onChange.call(this),this.getValue().call(this.object),this.__onFinishChange&&this.__onFinishChange.call(this,this.getValue())}}),d}(dat.controllers.Controller,dat.dom.dom,dat.utils.common),dat.controllers.BooleanController=function(a,b,c){var d=function(a,c){d.superclass.call(this,a,c);var e=this;this.__prev=this.getValue(),this.__checkbox=document.createElement("input"),this.__checkbox.setAttribute("type","checkbox"),b.bind(this.__checkbox,"change",function(){e.setValue(!e.__prev)},!1),this.domElement.appendChild(this.__checkbox),this.updateDisplay()};return d.superclass=a,c.extend(d.prototype,a.prototype,{setValue:function(a){return a=d.superclass.prototype.setValue.call(this,a),this.__onFinishChange&&this.__onFinishChange.call(this,this.getValue()),this.__prev=this.getValue(),a},updateDisplay:function(){return!0===this.getValue()?(this.__checkbox.setAttribute("checked","checked"),this.__checkbox.checked=!0):this.__checkbox.checked=!1,d.superclass.prototype.updateDisplay.call(this)}}),d}(dat.controllers.Controller,dat.dom.dom,dat.utils.common),dat.color.toString=function(a){return function(b){if(1==b.a||a.isUndefined(b.a)){for(b=b.hex.toString(16);6>b.length;)b="0"+b;return"#"+b}return"rgba("+Math.round(b.r)+","+Math.round(b.g)+","+Math.round(b.b)+","+b.a+")"}}(dat.utils.common),dat.color.interpret=function(a,b){var c,d,e=[{litmus:b.isString,conversions:{THREE_CHAR_HEX:{read:function(a){return a=a.match(/^#([A-F0-9])([A-F0-9])([A-F0-9])$/i),null!==a&&{space:"HEX",hex:parseInt("0x"+a[1].toString()+a[1].toString()+a[2].toString()+a[2].toString()+a[3].toString()+a[3].toString())}},write:a},SIX_CHAR_HEX:{read:function(a){return a=a.match(/^#([A-F0-9]{6})$/i),null!==a&&{space:"HEX",hex:parseInt("0x"+a[1].toString())}},write:a},CSS_RGB:{read:function(a){return a=a.match(/^rgb\(\s*(.+)\s*,\s*(.+)\s*,\s*(.+)\s*\)/),null!==a&&{space:"RGB",r:parseFloat(a[1]),g:parseFloat(a[2]),b:parseFloat(a[3])}},write:a},CSS_RGBA:{read:function(a){return a=a.match(/^rgba\(\s*(.+)\s*,\s*(.+)\s*,\s*(.+)\s*\,\s*(.+)\s*\)/),null!==a&&{space:"RGB",r:parseFloat(a[1]),g:parseFloat(a[2]),b:parseFloat(a[3]),a:parseFloat(a[4])}},write:a}}},{litmus:b.isNumber,conversions:{HEX:{read:function(a){return{space:"HEX",hex:a,conversionName:"HEX"}},write:function(a){return a.hex}}}},{litmus:b.isArray,conversions:{RGB_ARRAY:{read:function(a){return 3==a.length&&{space:"RGB",r:a[0],g:a[1],b:a[2]}},write:function(a){return[a.r,a.g,a.b]}},RGBA_ARRAY:{read:function(a){return 4==a.length&&{space:"RGB",r:a[0],g:a[1],b:a[2],a:a[3]}},write:function(a){return[a.r,a.g,a.b,a.a]}}}},{litmus:b.isObject,conversions:{RGBA_OBJ:{read:function(a){return!!(b.isNumber(a.r)&&b.isNumber(a.g)&&b.isNumber(a.b)&&b.isNumber(a.a))&&{space:"RGB",r:a.r,g:a.g,b:a.b,a:a.a}},write:function(a){return{r:a.r,g:a.g,b:a.b,a:a.a}}},RGB_OBJ:{read:function(a){return!!(b.isNumber(a.r)&&b.isNumber(a.g)&&b.isNumber(a.b))&&{space:"RGB",r:a.r,g:a.g,b:a.b}},write:function(a){return{r:a.r,g:a.g,b:a.b}}},HSVA_OBJ:{read:function(a){return!!(b.isNumber(a.h)&&b.isNumber(a.s)&&b.isNumber(a.v)&&b.isNumber(a.a))&&{space:"HSV",h:a.h,s:a.s,v:a.v,a:a.a}},write:function(a){return{h:a.h,s:a.s,v:a.v,a:a.a}}},HSV_OBJ:{read:function(a){return!!(b.isNumber(a.h)&&b.isNumber(a.s)&&b.isNumber(a.v))&&{space:"HSV",h:a.h,s:a.s,v:a.v}},write:function(a){return{h:a.h,s:a.s,v:a.v}}}}}];return function(){d=!1;var a=1\n\n Here\'s the new load parameter for your GUI\'s constructor:\n\n \n\n
    \n\n Automatically save\n values to localStorage on exit.\n\n
    The values saved to localStorage will\n override those passed to dat.GUI\'s constructor. This makes it\n easier to work incrementally, but localStorage is fragile,\n and your friends may not see the same values you do.\n \n
    \n \n
    \n\n',".dg {\n /** Clear list styles */\n /* Auto-place container */\n /* Auto-placed GUI's */\n /* Line items that don't contain folders. */\n /** Folder names */\n /** Hides closed items */\n /** Controller row */\n /** Name-half (left) */\n /** Controller-half (right) */\n /** Controller placement */\n /** Shorter number boxes when slider is present. */\n /** Ensure the entire boolean and function row shows a hand */ }\n .dg ul {\n list-style: none;\n margin: 0;\n padding: 0;\n width: 100%;\n clear: both; }\n .dg.ac {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n height: 0;\n z-index: 0; }\n .dg:not(.ac) .main {\n /** Exclude mains in ac so that we don't hide close button */\n overflow: hidden; }\n .dg.main {\n -webkit-transition: opacity 0.1s linear;\n -o-transition: opacity 0.1s linear;\n -moz-transition: opacity 0.1s linear;\n transition: opacity 0.1s linear; }\n .dg.main.taller-than-window {\n overflow-y: auto; }\n .dg.main.taller-than-window .close-button {\n opacity: 1;\n \n margin-top: -1px;\n border-top: 1px solid #2c2c2c; }\n .dg.main ul.closed .close-button {\n opacity: 1 !important; }\n .dg.main:hover .close-button,\n .dg.main .close-button.drag {\n opacity: 1; }\n .dg.main .close-button {\n /*opacity: 0;*/\n -webkit-transition: opacity 0.1s linear;\n -o-transition: opacity 0.1s linear;\n -moz-transition: opacity 0.1s linear;\n transition: opacity 0.1s linear;\n border: 0;\n position: absolute;\n line-height: 19px;\n height: 20px;\n \n cursor: pointer;\n text-align: center;\n background-color: #000; }\n .dg.main .close-button:hover {\n background-color: #111; }\n .dg.a {\n float: right;\n margin-right: 15px;\n overflow-x: hidden; }\n .dg.a.has-save > ul {\n margin-top: 27px; }\n .dg.a.has-save > ul.closed {\n margin-top: 0; }\n .dg.a .save-row {\n position: fixed;\n top: 0;\n z-index: 1002; }\n .dg li {\n -webkit-transition: height 0.1s ease-out;\n -o-transition: height 0.1s ease-out;\n -moz-transition: height 0.1s ease-out;\n transition: height 0.1s ease-out; }\n .dg li:not(.folder) {\n cursor: auto;\n height: 27px;\n line-height: 27px;\n overflow: hidden;\n padding: 0 4px 0 5px; }\n .dg li.folder {\n padding: 0;\n border-left: 4px solid rgba(0, 0, 0, 0); }\n .dg li.title {\n cursor: pointer;\n margin-left: -4px; }\n .dg .closed li:not(.title),\n .dg .closed ul li,\n .dg .closed ul li > * {\n height: 0;\n overflow: hidden;\n border: 0; }\n .dg .cr {\n clear: both;\n padding-left: 3px;\n height: 27px; }\n .dg .property-name {\n cursor: default;\n float: left;\n clear: left;\n width: 40%;\n overflow: hidden;\n text-overflow: ellipsis; }\n .dg .c {\n float: left;\n width: 60%; }\n .dg .c input[type=text] {\n border: 0;\n margin-top: 4px;\n padding: 3px;\n width: 100%;\n float: right; }\n .dg .has-slider input[type=text] {\n width: 30%;\n /*display: none;*/\n margin-left: 0; }\n .dg .slider {\n float: left;\n width: 66%;\n margin-left: -5px;\n margin-right: 0;\n height: 19px;\n margin-top: 4px; }\n .dg .slider-fg {\n height: 100%; }\n .dg .c input[type=checkbox] {\n margin-top: 9px; }\n .dg .c select {\n margin-top: 5px; }\n .dg .cr.function,\n .dg .cr.function .property-name,\n .dg .cr.function *,\n .dg .cr.boolean,\n .dg .cr.boolean * {\n cursor: pointer; }\n .dg .selector {\n display: none;\n position: absolute;\n margin-left: -9px;\n margin-top: 23px;\n z-index: 10; }\n .dg .c:hover .selector,\n .dg .selector.drag {\n display: block; }\n .dg li.save-row {\n padding: 0; }\n .dg li.save-row .button {\n display: inline-block;\n padding: 0px 6px; }\n .dg.dialogue {\n background-color: #222;\n width: 460px;\n padding: 15px;\n font-size: 13px;\n line-height: 15px; }\n\n\n#dg-new-constructor {\n padding: 10px;\n color: #222;\n font-family: Monaco, monospace;\n font-size: 10px;\n border: 0;\n resize: none;\n box-shadow: inset 1px 1px 1px #888;\n word-wrap: break-word;\n margin: 12px 0;\n display: block;\n width: 440px;\n overflow-y: scroll;\n height: 100px;\n position: relative; }\n\n#dg-local-explain {\n display: none;\n font-size: 11px;\n line-height: 17px;\n border-radius: 3px;\n background-color: #333;\n padding: 8px;\n margin-top: 10px; }\n #dg-local-explain code {\n font-size: 10px; }\n\n#dat-gui-save-locally {\n display: none; }\n\n/** Main type */\n.dg {\n color: #eee;\n font: 11px 'Lucida Grande', sans-serif;\n text-shadow: 0 -1px 0 #111;\n /** Auto place */\n /* Controller row,
  • */\n /** Controllers */ }\n .dg.main {\n /** Scrollbar */ }\n .dg.main::-webkit-scrollbar {\n width: 5px;\n background: #1a1a1a; }\n .dg.main::-webkit-scrollbar-corner {\n height: 0;\n display: none; }\n .dg.main::-webkit-scrollbar-thumb {\n border-radius: 5px;\n background: #676767; }\n .dg li:not(.folder) {\n background: #1a1a1a;\n border-bottom: 1px solid #2c2c2c; }\n .dg li.save-row {\n line-height: 25px;\n background: #dad5cb;\n border: 0; }\n .dg li.save-row select {\n margin-left: 5px;\n width: 108px; }\n .dg li.save-row .button {\n margin-left: 5px;\n margin-top: 1px;\n border-radius: 2px;\n font-size: 9px;\n line-height: 7px;\n padding: 4px 4px 5px 4px;\n background: #c5bdad;\n color: #fff;\n text-shadow: 0 1px 0 #b0a58f;\n box-shadow: 0 -1px 0 #b0a58f;\n cursor: pointer; }\n .dg li.save-row .button.gears {\n background: #c5bdad url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAANCAYAAAB/9ZQ7AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAQJJREFUeNpiYKAU/P//PwGIC/ApCABiBSAW+I8AClAcgKxQ4T9hoMAEUrxx2QSGN6+egDX+/vWT4e7N82AMYoPAx/evwWoYoSYbACX2s7KxCxzcsezDh3evFoDEBYTEEqycggWAzA9AuUSQQgeYPa9fPv6/YWm/Acx5IPb7ty/fw+QZblw67vDs8R0YHyQhgObx+yAJkBqmG5dPPDh1aPOGR/eugW0G4vlIoTIfyFcA+QekhhHJhPdQxbiAIguMBTQZrPD7108M6roWYDFQiIAAv6Aow/1bFwXgis+f2LUAynwoIaNcz8XNx3Dl7MEJUDGQpx9gtQ8YCueB+D26OECAAQDadt7e46D42QAAAABJRU5ErkJggg==) 2px 1px no-repeat;\n height: 7px;\n width: 8px; }\n .dg li.save-row .button:hover {\n background-color: #bab19e;\n box-shadow: 0 -1px 0 #b0a58f; }\n .dg li.folder {\n border-bottom: 0; }\n .dg li.title {\n padding-left: 16px;\n background: black url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlI+hKgFxoCgAOw==) 6px 10px no-repeat;\n cursor: pointer;\n border-bottom: 1px solid rgba(255, 255, 255, 0.2); }\n .dg .closed li.title {\n background-image: url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlGIWqMCbWAEAOw==); }\n .dg .cr.boolean {\n border-left: 3px solid #806787; }\n .dg .cr.function {\n border-left: 3px solid #e61d5f; }\n .dg .cr.number {\n border-left: 3px solid #2fa1d6; }\n .dg .cr.number input[type=text] {\n color: #2fa1d6; }\n .dg .cr.string {\n border-left: 3px solid #1ed36f; }\n .dg .cr.string input[type=text] {\n color: #1ed36f; }\n .dg .cr.function:hover, .dg .cr.boolean:hover {\n background: #111; }\n .dg .c input[type=text] {\n background: #303030;\n outline: none; }\n .dg .c input[type=text]:hover {\n background: #3c3c3c; }\n .dg .c input[type=text]:focus {\n background: #494949;\n color: #fff; }\n .dg .c .slider {\n background: #303030;\n cursor: ew-resize; }\n .dg .c .slider-fg {\n background: #2fa1d6; }\n .dg .c .slider:hover {\n background: #3c3c3c; }\n .dg .c .slider:hover .slider-fg {\n background: #44abda; }\n",dat.controllers.factory=function(a,b,c,d,e,f,g){return function(h,i,j,k){var l=h[i];return g.isArray(j)||g.isObject(j)?new a(h,i,j):g.isNumber(l)?g.isNumber(j)&&g.isNumber(k)?new c(h,i,j,k):new b(h,i,{min:j,max:k}):g.isString(l)?new d(h,i):g.isFunction(l)?new e(h,i,""):g.isBoolean(l)?new f(h,i):void 0}}(dat.controllers.OptionController,dat.controllers.NumberControllerBox,dat.controllers.NumberControllerSlider,dat.controllers.StringController=function(a,b,c){var d=function(a,c){function e(){f.setValue(f.__input.value)}d.superclass.call(this,a,c);var f=this;this.__input=document.createElement("input"),this.__input.setAttribute("type","text"),b.bind(this.__input,"keyup",e),b.bind(this.__input,"change",e),b.bind(this.__input,"blur",function(){f.__onFinishChange&&f.__onFinishChange.call(f,f.getValue())}),b.bind(this.__input,"keydown",function(a){13===a.keyCode&&this.blur()}),this.updateDisplay(),this.domElement.appendChild(this.__input)};return d.superclass=a,c.extend(d.prototype,a.prototype,{updateDisplay:function(){return b.isActive(this.__input)||(this.__input.value=this.getValue()),d.superclass.prototype.updateDisplay.call(this)}}),d}(dat.controllers.Controller,dat.dom.dom,dat.utils.common),dat.controllers.FunctionController,dat.controllers.BooleanController,dat.utils.common),dat.controllers.Controller,dat.controllers.BooleanController,dat.controllers.FunctionController,dat.controllers.NumberControllerBox,dat.controllers.NumberControllerSlider,dat.controllers.OptionController,dat.controllers.ColorController=function(a,b,c,d,e){function f(a,b,c,d){a.style.background="",e.each(i,function(e){a.style.cssText+="background: "+e+"linear-gradient("+b+", "+c+" 0%, "+d+" 100%); "})}function g(a){a.style.background="",a.style.cssText+="background: -moz-linear-gradient(top, #ff0000 0%, #ff00ff 17%, #0000ff 34%, #00ffff 50%, #00ff00 67%, #ffff00 84%, #ff0000 100%);",a.style.cssText+="background: -webkit-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);",a.style.cssText+="background: -o-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);",a.style.cssText+="background: -ms-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);",a.style.cssText+="background: linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);"}var h=function(a,i){function j(a){n(a),b.bind(window,"mousemove",n),b.bind(window,"mouseup",k)}function k(){b.unbind(window,"mousemove",n),b.unbind(window,"mouseup",k)}function l(){var a=d(this.value);!1!==a?(p.__color.__state=a,p.setValue(p.__color.toOriginal())):this.value=p.__color.toString()}function m(){b.unbind(window,"mousemove",o),b.unbind(window,"mouseup",m)}function n(a){a.preventDefault();var c=b.getWidth(p.__saturation_field),d=b.getOffset(p.__saturation_field),e=(a.clientX-d.left+document.body.scrollLeft)/c;return a=1-(a.clientY-d.top+document.body.scrollTop)/c,1a&&(a=0),1e&&(e=0),p.__color.v=a,p.__color.s=e,p.setValue(p.__color.toOriginal()),!1}function o(a){a.preventDefault();var c=b.getHeight(p.__hue_field),d=b.getOffset(p.__hue_field);return a=1-(a.clientY-d.top+document.body.scrollTop)/c,1a&&(a=0),p.__color.h=360*a,p.setValue(p.__color.toOriginal()),!1}h.superclass.call(this,a,i),this.__color=new c(this.getValue()),this.__temp=new c(0);var p=this;this.domElement=document.createElement("div"),b.makeSelectable(this.domElement,!1),this.__selector=document.createElement("div"),this.__selector.className="selector",this.__saturation_field=document.createElement("div"),this.__saturation_field.className="saturation-field",this.__field_knob=document.createElement("div"),this.__field_knob.className="field-knob",this.__field_knob_border="2px solid ",this.__hue_knob=document.createElement("div"),this.__hue_knob.className="hue-knob",this.__hue_field=document.createElement("div"),this.__hue_field.className="hue-field",this.__input=document.createElement("input"),this.__input.type="text",this.__input_textShadow="0 1px 1px ",b.bind(this.__input,"keydown",function(a){13===a.keyCode&&l.call(this)}),b.bind(this.__input,"blur",l),b.bind(this.__selector,"mousedown",function(a){b.addClass(this,"drag").bind(window,"mouseup",function(a){b.removeClass(p.__selector,"drag")})});var q=document.createElement("div");e.extend(this.__selector.style,{width:"122px",height:"102px",padding:"3px",backgroundColor:"#222",boxShadow:"0px 1px 3px rgba(0,0,0,0.3)"}),e.extend(this.__field_knob.style,{position:"absolute",width:"12px",height:"12px",border:this.__field_knob_border+(.5>this.__color.v?"#fff":"#000"),boxShadow:"0px 1px 3px rgba(0,0,0,0.5)",borderRadius:"12px",zIndex:1}),e.extend(this.__hue_knob.style,{position:"absolute",width:"15px",height:"2px",borderRight:"4px solid #fff",zIndex:1}),e.extend(this.__saturation_field.style,{width:"100px",height:"100px",border:"1px solid #555",marginRight:"3px",display:"inline-block",cursor:"pointer"}),e.extend(q.style,{width:"100%",height:"100%",background:"none"}),f(q,"top","rgba(0,0,0,0)","#000"),e.extend(this.__hue_field.style,{width:"15px",height:"100px",display:"inline-block",border:"1px solid #555",cursor:"ns-resize"}),g(this.__hue_field),e.extend(this.__input.style,{outline:"none",textAlign:"center",color:"#fff",border:0,fontWeight:"bold",textShadow:this.__input_textShadow+"rgba(0,0,0,0.7)"}),b.bind(this.__saturation_field,"mousedown",j),b.bind(this.__field_knob,"mousedown",j),b.bind(this.__hue_field,"mousedown",function(a){o(a),b.bind(window,"mousemove",o),b.bind(window,"mouseup",m)}),this.__saturation_field.appendChild(q),this.__selector.appendChild(this.__field_knob),this.__selector.appendChild(this.__saturation_field),this.__selector.appendChild(this.__hue_field),this.__hue_field.appendChild(this.__hue_knob),this.domElement.appendChild(this.__input),this.domElement.appendChild(this.__selector),this.updateDisplay()};h.superclass=a,e.extend(h.prototype,a.prototype,{updateDisplay:function(){var a=d(this.getValue());if(!1!==a){var b=!1;e.each(c.COMPONENTS,function(c){if(!e.isUndefined(a[c])&&!e.isUndefined(this.__color.__state[c])&&a[c]!==this.__color.__state[c])return b=!0,{}},this),b&&e.extend(this.__color.__state,a)}e.extend(this.__temp.__state,this.__color.__state),this.__temp.a=1;var g=.5>this.__color.v||.5a&&(a+=1),{h:360*a,s:d/e,v:e/255})},rgb_to_hex:function(a,b,c){return a=this.hex_with_component(0,2,a),a=this.hex_with_component(a,1,b),a=this.hex_with_component(a,0,c)},component_from_hex:function(a,b){return a>>8*b&255},hex_with_component:function(b,c,d){return d<<(a=8*c)|b&~(255< { + saved = true; + styleElem.innerHTML = stylesheetObj[value]; + s = simpleArticleIframe.styleSheets[1]; + updateEditorStyles(editor); + theme = value; + chrome.storage.sync.set({'currentTheme': theme}); + }); + let fontSize = datGUI.add(editor, "fontSize", 8, 25); + fontSize.onChange((value) => { saved = false; changeStylesheetRule(s, "body", "font-size", value); }); - var maxWidth = datGUI.add(editor, "maxWidth"); - maxWidth.onChange(function(value) { + let maxWidth = datGUI.add(editor, "maxWidth"); + maxWidth.onChange((value) => { saved = false; changeStylesheetRule(s, ".simple-container", "max-width", value); }); - var textColor = datGUI.addColor(editor, 'textColor'); - textColor.onChange(function(value) { + let textColor = datGUI.addColor(editor, 'textColor'); + textColor.onChange((value) => { saved = false; changeStylesheetRule(s, "body", "color", value); }); - var backgroundColor = datGUI.addColor(editor, 'backgroundColor'); - backgroundColor.onChange(function(value) { + let backgroundColor = datGUI.addColor(editor, 'backgroundColor'); + backgroundColor.onChange((value) => { saved = false; changeStylesheetRule(s, "body", "background-color", value); }); - var linkColor = datGUI.addColor(editor, 'linkColor'); - linkColor.onChange(function(value) { + let linkColor = datGUI.addColor(editor, 'linkColor'); + linkColor.onChange((value) => { saved = false; changeStylesheetRule(s, ".simple-author", "color", value); changeStylesheetRule(s, "a[href]", "color", value); }); - var linkHoverColor = datGUI.addColor(editor, 'linkHoverColor'); - linkHoverColor.onChange(function(value) { + let linkHoverColor = datGUI.addColor(editor, 'linkHoverColor'); + linkHoverColor.onChange((value) => { saved = false; changeStylesheetRule(s, "a[href]:hover", "color", value); }); @@ -926,11 +953,11 @@ function addGUI() { // Add the save and close buttons closeBtn = document.querySelector(".dg .close-button"); - var clone = closeBtn.cloneNode(true); + let clone = closeBtn.cloneNode(true); closeBtn.parentNode.appendChild(clone); // Switch the variables to match DOM order - var saveAndClose = closeBtn; + let saveAndClose = closeBtn; closeBtn = clone; saveAndClose.className += " saveAndClose"; @@ -946,7 +973,7 @@ function addGUI() { // Make the strings lowercase selector = selector.toLowerCase(); property = property.toLowerCase(); - + // Return it if it exists for(var i = 0; i < s.cssRules.length; i++) { var rule = s.cssRules[i]; @@ -1210,7 +1237,8 @@ function createSimplifiedOverlay() { // Fade in and move up the simple article setTimeout(function() { // See if we should add the theme editor button - if(theme.indexOf("default-styles") !== -1) { + if(theme.indexOf("default-styles") !== -1 + || theme.indexOf("dark-styles") !== -1) { uiContainer.insertBefore(addGUI(), delModeBtn); } @@ -1286,10 +1314,12 @@ function createSimplifiedOverlay() { // Loads the styles after the xhr request finishes -var theme, jrCount; +var theme, + styleElem, + jrCount; function continueLoading() { // Create a style tag and place our styles in there from localStorage - var style = document.createElement('style'); + styleElem = document.createElement('style'); chrome.storage.sync.get(['currentTheme', 'jrCount'], function(result) { if(result.currentTheme) { @@ -1298,12 +1328,12 @@ function continueLoading() { chrome.storage.sync.set({'currentTheme': "default-styles.css"}); theme = "default-styles.css"; } - style.type = 'text/css'; + styleElem.type = 'text/css'; - if(style.styleSheet) { - style.styleSheet.cssText = stylesheetObj[theme]; + if(styleElem.styleSheet) { + styleElem.styleSheet.cssText = stylesheetObj[theme]; } else { - style.appendChild(document.createTextNode(stylesheetObj[theme])); + styleElem.appendChild(document.createTextNode(stylesheetObj[theme])); } // Get how many times the user has opened Just Read @@ -1343,7 +1373,7 @@ function continueLoading() { simpleArticleIframe.location.hash = top.window.location.hash; // Append our theme styles to the overlay - simpleArticleIframe.head.appendChild(style); + simpleArticleIframe.head.appendChild(styleElem); }); } @@ -1356,7 +1386,7 @@ function continueLoading() { ///////////////////////////////////// var isPaused = false, stylesheetObj = {}, - stylesheetVersion = 1.23; // THIS NUMBER MUST BE CHANGED FOR THE STYLESHEETS TO KNOW TO UPDATE + stylesheetVersion = 1.25; // THIS NUMBER MUST BE CHANGED FOR THE STYLESHEETS TO KNOW TO UPDATE function launch() { // Detect past overlay - don't show another diff --git a/dark-styles.css b/dark-styles.css new file mode 100644 index 0000000..78ffe79 --- /dev/null +++ b/dark-styles.css @@ -0,0 +1,184 @@ +@import url('https://fonts.googleapis.com/css?family=Roboto'); + +body { + font-family: 'Roboto', BlinkMacSystemFont, sans-serif; + background-color: #222233; + line-height: 1.6; + font-size: 17px; + color: #D1D1D1; + text-rendering: optimizeLegibility; +} + +@media print { + body { color: #333; } +} + +h1, +h2 { + font-weight: 700; +} + +h1 { + font-size: 1.875em; + line-height: 1.125; +} + +h2 { + font-size: 1.45em; + line-height: 1.2625em; +} + +h3 { + font-size: 1.25em; + line-height: 1.5; +} + +hr { + height: 1px; + background-color: inherit; + border: none; + width: 100%; + margin: 0px; +} + +a[href] { + color: #64BEFA; +} + +a[href]:hover { + color: #2089d0; +} + +.simple-container { + -webkit-print-color-adjust: exact; + max-width: 600px; +} + +.simple-control, +.simple-control *, +.simple-edit * { + fill: #D1D1D1; + color: #D1D1D1; + border-color: #D1D1D1; +} + +.youtubeContainer { + position: relative; + width: 100%; + height: 0; + padding-bottom: 56.25%; + padding-top: 25px; +} +iframe[src *= "youtube.com/embed/"] { + width: 100%; + height: 100%; + position: absolute; + top: 0; + left: 0; +} + +img { + max-width: 100%; +} + +li { + line-height: 1.5em; +} + +td { + border: 1px solid black; + padding: 3px 7px; +} + +pre { + background-color: #E0E0E0; + padding: 10px; + overflow: auto; +} + +blockquote { + border-left: 4px solid; + margin-left: 0; + padding: 15px 10% 15px 8%; + margin: 1em 0; + font-size: 1.2em; + line-height: 1.4; +} +blockquote > *:first-child { + margin-top: 0; +} +blockquote > *:last-child { + margin-bottom: 0; +} + +figure { + margin: 0 0 10px; +} + figcaption { + font-size: 0.9em; + opacity: 0.7; + border: 1px solid #eee; + padding: 17px 17px 12px; +} + +table { + background: #004b7a; + margin: 10px auto; + border: none; + box-shadow: 1px 1px 1px rgba(0, 0, 0, .75); + border-spacing: 0; + font: inherit; + text-align: center; +} +table tr td, +table tr th, +table thead th { + margin: 3px; + padding: 5px; + color: #ccc; + border: 1px solid rgba(255, 255, 255, .25); + background: rgba(0, 0, 0, .1); +} + +aside, +[class *= "sidebar"], +[id *= "sidebar"] { + max-width: 90%; + margin: 0 auto; + border: 1px solid lightgrey; + padding: 5px 15px; +} + +.simple-date { + display: inline-block; + font-size: 18px; + padding-right: 15px; + padding-top: 10px; + padding-bottom: 10px; + border-right: 1px solid #d8d8d8; +} +.rtl .simple-date { + border-left: 1px solid #d8d8d8; + border-right: none; + padding-right: 0; + padding-left: 15px; +} + +.simple-author { + display: inline-block; + font-size: 18px; + color: #27AAE1; + line-height: 22px; + padding-left: 10px; + padding-top: 10px; + padding-bottom: 10px; +} +.rtl .simple-author { + padding-left: 0; + padding-right: 10px; +} + + +/* Make emojis and icons a reasonable size */ +[class *= "emoji"], +[class *= "icon"] { width: 1em; } diff --git a/default-styles.css b/default-styles.css index b3d0e9a..2411248 100644 --- a/default-styles.css +++ b/default-styles.css @@ -47,6 +47,10 @@ a[href]:hover { color: #4ECAFF; } +.simple-container { + max-width: 600px; +} + .youtubeContainer { position: relative; width: 100%; @@ -146,10 +150,6 @@ aside, padding-right: 10px; } -.simple-container { - max-width: 600px; -} - /* Make emojis and icons a reasonable size */ [class *= "emoji"], diff --git a/manifest.json b/manifest.json index b7bdc40..c5901cd 100644 --- a/manifest.json +++ b/manifest.json @@ -1,6 +1,6 @@ { "name": "Just Read", - "version": "1.3.1", + "version": "1.4.0", "manifest_version": 2, "description": "A customizable reader extension.", "homepage_url": "https://github.com/ZachSaucier/Just-Read", @@ -49,6 +49,7 @@ "print.svg", "required-styles.css", "default-styles.css", + "dark-styles.css", "hide-segments.css", "page.css", "options.js", diff --git a/options.js b/options.js index 82b3959..db3dc9c 100644 --- a/options.js +++ b/options.js @@ -37,7 +37,8 @@ var changed = false, stylesheetObj = {}, saveButton = document.getElementById("save"), defaultLiItem, - defaultStylesheet = "default-styles.css"; + defaultStylesheet = "default-styles.css", + darkStylesheet = "dark-styles.css"; function isEmpty(obj) { return Object.keys(obj).length === 0; @@ -75,8 +76,10 @@ function getStylesFromStorage(storage) { alwaysAddAR.checked = storage[key]; } else if(key === "fullscreen") { fullScrn.checked = storage[key]; - } else if(key.substring(0, 3) === "jr-") // Get the user's stylesheets + } else if(key.substring(0, 3) === "jr-") { // Get the user's stylesheets + console.log(key); stylesheetObj[key.substring(3)] = storage[key]; + } } } @@ -230,8 +233,24 @@ function styleListOnClick() { // The stuff to fire after the stylesheets have been loaded function continueLoading() { + if(typeof stylesheetObj[darkStylesheet] === "undefined") { + // If the dark theme isn't found, add it + var xhr = new XMLHttpRequest(); + xhr.open('GET', chrome.extension.getURL(darkStylesheet), true); + xhr.onreadystatechange = function() { + if(xhr.readyState == XMLHttpRequest.DONE && xhr.status == 200) { + // Save the file's contents to our object + stylesheetObj[darkStylesheet] = xhr.responseText; + // Save it to Chrome storage + setStylesOfStorage(); + } + } + xhr.send(); + } + // Get the currently used stylesheet chrome.storage.sync.get('currentTheme', function(result) { + var currTheme = result.currentTheme || defaultStylesheet; // Based on that object, populate the list values @@ -256,13 +275,14 @@ function continueLoading() { li.innerHTML += stylesheet; // Lock the default-styles.css file (prevent deletion) - if(stylesheet === defaultStylesheet) { + if(stylesheet === defaultStylesheet + || stylesheet === darkStylesheet) { defaultLiItem = li; liClassList.add("locked"); } - // Make the first one active - if(count === 0) { + // Make the current one active + if(stylesheet === currTheme) { liClassList.add("active"); var fileName = li.textContent; editor.setValue(stylesheetObj[fileName] === undefined ? "" : stylesheetObj[fileName], -1); diff --git a/required-styles.css b/required-styles.css index 093044b..46b2550 100644 --- a/required-styles.css +++ b/required-styles.css @@ -195,7 +195,7 @@ .jr-tooltip { display: none !important; } - * { overflow: auto !important; } + *:not(.simple-title *) { overflow: auto !important; } @page :first { margin-top: 0; } }