├── src ├── app │ ├── module │ │ ├── news │ │ │ ├── module.html │ │ │ ├── _example.html │ │ │ ├── module.css │ │ │ └── module.js │ │ ├── settings │ │ │ ├── module.html │ │ │ ├── module.css │ │ │ ├── _example.html │ │ │ └── module.js │ │ ├── clock │ │ │ ├── _example.html │ │ │ ├── module.html │ │ │ ├── module.css │ │ │ └── module.js │ │ ├── header │ │ │ ├── _example.html │ │ │ ├── module.html │ │ │ ├── module.css │ │ │ └── module.js │ │ ├── set-alarm │ │ │ ├── _example.html │ │ │ ├── module.html │ │ │ ├── module.css │ │ │ └── module.js │ │ └── ambient │ │ │ └── module.js │ ├── core │ │ ├── app.data.js │ │ ├── app.css │ │ ├── app.layout.json │ │ └── app.js │ └── resources │ │ ├── icons │ │ ├── -128.ico │ │ ├── -128.png │ │ ├── -16.png │ │ ├── -256.png │ │ ├── -32.png │ │ └── -64.png │ │ └── fonts │ │ ├── icomoon.eot │ │ ├── icomoon.ttf │ │ ├── icomoon.woff │ │ ├── DIGITALDREAM-webfont.ttf │ │ ├── DIGITALDREAM-webfont.woff │ │ ├── fonts.css │ │ ├── icomoon.svg │ │ └── DIGITALDREAM-webfont.svg ├── index.html └── package.json ├── .gitignore ├── imgs ├── dark-alarm.png ├── dark-clock.png ├── light-alarm.png └── light-clock.png ├── package.json ├── license.md └── README.md /src/app/module/news/module.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /bower_components/ 2 | /node_modules/ 3 | .brackets.json 4 | /build 5 | /cache/ 6 | -------------------------------------------------------------------------------- /src/app/module/settings/module.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /imgs/dark-alarm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RIAEvangelist/insane-alarm/HEAD/imgs/dark-alarm.png -------------------------------------------------------------------------------- /imgs/dark-clock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RIAEvangelist/insane-alarm/HEAD/imgs/dark-clock.png -------------------------------------------------------------------------------- /imgs/light-alarm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RIAEvangelist/insane-alarm/HEAD/imgs/light-alarm.png -------------------------------------------------------------------------------- /imgs/light-clock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RIAEvangelist/insane-alarm/HEAD/imgs/light-clock.png -------------------------------------------------------------------------------- /src/app/core/app.data.js: -------------------------------------------------------------------------------- 1 | //app.data is an empty object you can use that all modules will have access to. 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/app/module/settings/module.css: -------------------------------------------------------------------------------- 1 | /* 2 | CSS for the settings module. 3 | Do not leave file empty. 4 | */ 5 | -------------------------------------------------------------------------------- /src/app/resources/icons/-128.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RIAEvangelist/insane-alarm/HEAD/src/app/resources/icons/-128.ico -------------------------------------------------------------------------------- /src/app/resources/icons/-128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RIAEvangelist/insane-alarm/HEAD/src/app/resources/icons/-128.png -------------------------------------------------------------------------------- /src/app/resources/icons/-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RIAEvangelist/insane-alarm/HEAD/src/app/resources/icons/-16.png -------------------------------------------------------------------------------- /src/app/resources/icons/-256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RIAEvangelist/insane-alarm/HEAD/src/app/resources/icons/-256.png -------------------------------------------------------------------------------- /src/app/resources/icons/-32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RIAEvangelist/insane-alarm/HEAD/src/app/resources/icons/-32.png -------------------------------------------------------------------------------- /src/app/resources/icons/-64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RIAEvangelist/insane-alarm/HEAD/src/app/resources/icons/-64.png -------------------------------------------------------------------------------- /src/app/resources/fonts/icomoon.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RIAEvangelist/insane-alarm/HEAD/src/app/resources/fonts/icomoon.eot -------------------------------------------------------------------------------- /src/app/resources/fonts/icomoon.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RIAEvangelist/insane-alarm/HEAD/src/app/resources/fonts/icomoon.ttf -------------------------------------------------------------------------------- /src/app/resources/fonts/icomoon.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RIAEvangelist/insane-alarm/HEAD/src/app/resources/fonts/icomoon.woff -------------------------------------------------------------------------------- /src/app/resources/fonts/DIGITALDREAM-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RIAEvangelist/insane-alarm/HEAD/src/app/resources/fonts/DIGITALDREAM-webfont.ttf -------------------------------------------------------------------------------- /src/app/resources/fonts/DIGITALDREAM-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RIAEvangelist/insane-alarm/HEAD/src/app/resources/fonts/DIGITALDREAM-webfont.woff -------------------------------------------------------------------------------- /src/app/module/clock/_example.html: -------------------------------------------------------------------------------- 1 |
5 | -------------------------------------------------------------------------------- /src/app/module/header/_example.html: -------------------------------------------------------------------------------- 1 |
5 | -------------------------------------------------------------------------------- /src/app/module/news/_example.html: -------------------------------------------------------------------------------- 1 |
5 | -------------------------------------------------------------------------------- /src/app/module/settings/_example.html: -------------------------------------------------------------------------------- 1 |
5 | -------------------------------------------------------------------------------- /src/app/module/set-alarm/_example.html: -------------------------------------------------------------------------------- 1 |
5 | -------------------------------------------------------------------------------- /src/app/module/settings/module.js: -------------------------------------------------------------------------------- 1 | ( 2 | function(){ 3 | var moduleName='settings'; 4 | 5 | function render(el){ 6 | 7 | } 8 | 9 | exports(moduleName,render); 10 | } 11 | )(); 12 | -------------------------------------------------------------------------------- /src/app/module/news/module.css: -------------------------------------------------------------------------------- 1 | /* 2 | CSS for the news module. 3 | Do not leave file empty. 4 | */ 5 | 6 | .news-module{ 7 | position:absolute; 8 | top:30px; 9 | left:0; 10 | padding:10px 20px; 11 | width:calc(100% - 40px); 12 | font-size:20px; 13 | font:helvetica, ubuntu, arial; 14 | cursor:pointer; 15 | } 16 | -------------------------------------------------------------------------------- /src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/app/module/clock/module.html: -------------------------------------------------------------------------------- 1 | 2 |
4 | 0 5 |
6 |
8 | : 9 |
10 |
12 | 0 13 |
14 | 15 |
17 | Awake 18 |
19 |
21 | Snooze 22 |
23 | -------------------------------------------------------------------------------- /src/app/module/header/module.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
5 | X 6 |
7 | 8 |
10 | [ _ ] 11 |
12 | 13 |
15 | _ 16 |
17 | 18 |
19 |
20 | 21 |
22 |
23 | 24 |
25 |
26 | -------------------------------------------------------------------------------- /src/app/core/app.css: -------------------------------------------------------------------------------- 1 | html, 2 | body{ 3 | margin:0; 4 | padding:0; 5 | height:100%; 6 | width:100%; 7 | background:rgb(0,0,0); 8 | color:rgb(200,200,200); 9 | overflow:hidden; 10 | font-family:arial; 11 | } 12 | 13 | body{ 14 | box-shadow:inset 0 0 28px rgb(100,100,100); 15 | -webkit-transition:background-color 500ms; 16 | transition:background-color 500ms; 17 | } 18 | 19 | body * { 20 | position:relative; 21 | } 22 | 23 | .hidden{ 24 | display:none; 25 | } 26 | -------------------------------------------------------------------------------- /src/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name" : "InsaneAlarm", 3 | "version" : "0.0.1", 4 | "main" : "index.html", 5 | "webkit": { 6 | "plugin": true 7 | }, 8 | "window":{ 9 | "title" : "Insane Alarm", 10 | "icon" : "app/resources/icons/-128.png", 11 | "height" : 700, 12 | "width" : 1000, 13 | "toolbar": false, 14 | "frame" : false 15 | }, 16 | "chromium-args": "--ppapi-flash-path=/opt/google/chrome-beta/PepperFlash/libpepflashplayer.so" 17 | } 18 | -------------------------------------------------------------------------------- /src/app/module/set-alarm/module.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
5 |
6 | Hour 7 |
8 | 12 |
13 | 14 |
16 |
17 | Minute 18 |
19 | 23 |
24 | 25 | 30 | 31 | 36 | -------------------------------------------------------------------------------- /src/app/module/header/module.css: -------------------------------------------------------------------------------- 1 | /* 2 | CSS for the header module. 3 | Do not leave file empty. 4 | */ 5 | 6 | .header-module{ 7 | -webkit-app-region: drag; 8 | height:30px; 9 | width:100%; 10 | cursor:pointer; 11 | background:rgba(40,40,40,.7); 12 | position:fixed; 13 | top:0; 14 | left:0; 15 | z-index:10000; 16 | } 17 | 18 | .header-module div{ 19 | -webkit-app-region: no-drag; 20 | float:right; 21 | background:rgb(100,100,100); 22 | color:rgb(0,0,0); 23 | border:none; 24 | height:20px; 25 | width:20px; 26 | line-height:20px; 27 | margin:5px; 28 | text-align:center; 29 | border-radius:5px; 30 | } 31 | 32 | .header-module .icon-cog{ 33 | display:none; 34 | } 35 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "insane-alarm", 3 | "version": "1.0.0", 4 | "description": "Alarm which will wake you up no matter what!", 5 | "main": "./src/", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "https://github.com/RIAEvangelist/insane-alarm.git" 12 | }, 13 | "keywords": [ 14 | "alarm", 15 | "insane", 16 | "loud", 17 | "clock", 18 | "wake", 19 | "up" 20 | ], 21 | "author": "Brandon Noazaki Miller", 22 | "license": "DBAD", 23 | "bugs": { 24 | "url": "https://github.com/RIAEvangelist/insane-alarm/issues" 25 | }, 26 | "homepage": "https://github.com/RIAEvangelist/insane-alarm", 27 | "dependencies": { 28 | "nw-builder": "^2.0.2" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/app/module/header/module.js: -------------------------------------------------------------------------------- 1 | ( 2 | function(){ 3 | var moduleName='header'; 4 | 5 | function render(el){ 6 | el.addEventListener( 7 | 'click', 8 | function(e){ 9 | if( 10 | !win[e.target.id] && 11 | e.target.id != 'setAlarm' && 12 | e.target.id != 'settings' && 13 | e.target.id != 'home' 14 | ){ 15 | return; 16 | } 17 | 18 | switch(e.target.id){ 19 | case 'setAlarm' : 20 | case 'settings' : 21 | case 'home' : 22 | app.navigate(e.target.id); 23 | break; 24 | default : 25 | win[e.target.id](); 26 | } 27 | } 28 | ); 29 | } 30 | 31 | exports(moduleName,render); 32 | } 33 | )(); 34 | -------------------------------------------------------------------------------- /src/app/core/app.layout.json: -------------------------------------------------------------------------------- 1 | { 2 | "startAt":"home", 3 | "lib" : [ 4 | { 5 | "path":"app/core/app.css", 6 | "type":"css" 7 | }, 8 | { 9 | "path":"app/resources/fonts/fonts.css", 10 | "type":"css" 11 | }, 12 | { 13 | "path":"app/core/app.data.js", 14 | "type":"js" 15 | }, 16 | { 17 | "path":"app/core/app.layout.js", 18 | "type":"js" 19 | } 20 | ], "modules":{ 21 | "logic":[ 22 | "ambient" 23 | ], 24 | "ui" : { 25 | "home" : { 26 | "header" : {}, 27 | "clock" : {}, 28 | "news" : {} 29 | }, 30 | "setAlarm" : { 31 | "header" : {}, 32 | "set-alarm": {} 33 | }, 34 | "settings" : { 35 | "header" : {}, 36 | "settings": {} 37 | } 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /license.md: -------------------------------------------------------------------------------- 1 | # DON'T BE A DICK PUBLIC LICENSE 2 | 3 | > Version 1, December 2009 4 | 5 | > Copyright (C) 2009 Philip Sturgeon 6 | 7 | Everyone is permitted to copy and distribute verbatim or modified 8 | copies of this license document, and changing it is allowed as long 9 | as the name is changed. 10 | 11 | > DON'T BE A DICK PUBLIC LICENSE 12 | > TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 13 | 14 | 1. Do whatever you like with the original work, just don't be a dick. 15 | 16 | Being a dick includes - but is not limited to - the following instances: 17 | 18 | 1a. Outright copyright infringement - Don't just copy this and change the name. 19 | 1b. Selling the unmodified original with no work done what-so-ever, that's REALLY being a dick. 20 | 1c. Modifying the original work to contain hidden harmful content. That would make you a PROPER dick. 21 | 22 | 2. If you become rich through modifications, related works/services, or supporting the original work, 23 | share the love. Only a dick would make loads off this work and not buy the original work's 24 | creator(s) a pint. 25 | 26 | 3. Code is provided with no warranty. Using somebody else's code and bitching when it goes wrong makes 27 | you a DONKEY dick. Fix the problem yourself. A non-dick would submit the fix back. 28 | -------------------------------------------------------------------------------- /src/app/resources/fonts/fonts.css: -------------------------------------------------------------------------------- 1 | /* Generated by Font Squirrel (http://www.fontsquirrel.com) on May 27, 2013 03:28:33 PM America/New_York */ 2 | body{ 3 | /* Better Font Rendering =========== */ 4 | -webkit-font-smoothing: antialiased; 5 | } 6 | 7 | 8 | @font-face { 9 | font-family: 'DigitaldreamRegular'; 10 | src: url('DIGITALDREAM-webfont.woff') format('woff'), 11 | url('DIGITALDREAM-webfont.ttf') format('truetype'), 12 | url('DIGITALDREAM-webfont.svg#DigitaldreamRegular') format('svg'); 13 | font-weight: normal; 14 | font-style: normal; 15 | 16 | } 17 | 18 | @font-face { 19 | font-family: 'icomoon'; 20 | src:url('icomoon.eot?-1110p'); 21 | src:url('icomoon.eot?#iefix-1110p') format('embedded-opentype'), 22 | url('icomoon.woff?-1110p') format('woff'), 23 | url('icomoon.ttf?-1110p') format('truetype'), 24 | url('icomoon.svg?-1110p#icomoon') format('svg'); 25 | font-weight: normal; 26 | font-style: normal; 27 | } 28 | 29 | [class^="icon-"], [class*=" icon-"] { 30 | font-family: 'icomoon'; 31 | speak: none; 32 | font-style: normal; 33 | font-weight: normal; 34 | font-variant: normal; 35 | text-transform: none; 36 | line-height: 1; 37 | } 38 | 39 | .icon-clock:before { 40 | content: "\e602"; 41 | } 42 | .icon-bell:before { 43 | content: "\e600"; 44 | } 45 | .icon-cog:before { 46 | content: "\e601"; 47 | } 48 | -------------------------------------------------------------------------------- /src/app/module/clock/module.css: -------------------------------------------------------------------------------- 1 | /* 2 | CSS for the clock module. 3 | Do not leave file empty. 4 | */ 5 | 6 | .clock-module{ 7 | font-size: 200px; 8 | font-family: 'DigitaldreamRegular'; 9 | color: rgb(255, 75, 75); 10 | text-align: center; 11 | padding: 50px; 12 | height:100%; 13 | } 14 | 15 | .clock-module .hour, 16 | .clock-module .minute, 17 | .clock-module .seperator{ 18 | width:calc(50% - 50px); 19 | position:absolute; 20 | top:calc(50% - 150px); 21 | } 22 | .clock-module .hour{ 23 | left:0; 24 | width:calc(50% - 70px); 25 | text-align:right; 26 | } 27 | .clock-module .seperator{ 28 | left:calc(50% - 70px); 29 | width:140px; 30 | text-align:center; 31 | } 32 | .clock-module .minute{ 33 | right:0; 34 | width:calc(50% - 70px); 35 | text-align:left; 36 | } 37 | 38 | .clock-module .snooze, 39 | .clock-module .awake{ 40 | font-size: 40px; 41 | padding: 20px; 42 | background: rgba(130,130,130,.7); 43 | margin: 20px; 44 | position: absolute; 45 | border-radius: 20px; 46 | box-shadow: 0 0 20px rgba(255,0,0,.7); 47 | color: rgb(255,0,0); 48 | text-shadow: 0 0 6px rgb(0,0,0); 49 | bottom:100px; 50 | display:none; 51 | } 52 | 53 | .clock-module.waitingToBeKilled .snooze, 54 | .clock-module.waitingToBeKilled .awake{ 55 | display:block; 56 | } 57 | 58 | .clock-module .snooze{ 59 | left:0; 60 | } 61 | 62 | .clock-module .awake{ 63 | right:0; 64 | } 65 | -------------------------------------------------------------------------------- /src/app/module/set-alarm/module.css: -------------------------------------------------------------------------------- 1 | /* 2 | CSS for the set-alarm module. 3 | Do not leave file empty. 4 | */ 5 | .set-alarm-module{ 6 | position:absolute; 7 | top:30px; 8 | width:100%; 9 | height:calc(100% - 30px); 10 | } 11 | 12 | .set-alarm-module ul{ 13 | list-style:none; 14 | margin:0; 15 | padding:0; 16 | } 17 | 18 | .set-alarm-module .setHours{ 19 | position:absolute; 20 | width:46%; 21 | height:100%; 22 | left:2%; 23 | } 24 | 25 | .set-alarm-module .setMins{ 26 | position:absolute; 27 | width:46%; 28 | height:100%; 29 | left:52%; 30 | } 31 | 32 | .set-alarm-module .title{ 33 | height:20px; 34 | line-height:20px; 35 | font-size:18px; 36 | } 37 | 38 | .set-alarm-module ul{ 39 | height:calc(100% - 20px); 40 | } 41 | 42 | .set-alarm-module .setHours li{ 43 | width:23%; 44 | height:14%; 45 | margin:1%; 46 | display:inline-block; 47 | background:rgb(50,50,50); 48 | text-align:center; 49 | line-height:65px; 50 | font-size:30px; 51 | overflow:hidden; 52 | cursor:pointer; 53 | transition:color 300ms, background-color 300ms; 54 | } 55 | 56 | .set-alarm-module .setMins li{ 57 | width:13%; 58 | height:7.6%; 59 | margin:1%; 60 | display:inline-block; 61 | background:rgb(50,50,50); 62 | text-align:center; 63 | line-height:40px; 64 | font-size:24px; 65 | overflow:hidden; 66 | cursor:pointer; 67 | transition:color 300ms, background-color 300ms; 68 | } 69 | 70 | .set-alarm-module li:hover{ 71 | background:rgb(180,200,180); 72 | color:rgb(50,50,50); 73 | } 74 | 75 | .set-alarm-module li.selected{ 76 | background:rgb(100,150,100); 77 | } 78 | -------------------------------------------------------------------------------- /src/app/module/clock/module.js: -------------------------------------------------------------------------------- 1 | ( 2 | function(){ 3 | var moduleName='clock'; 4 | 5 | function render(el){ 6 | setInterval( 7 | showTime, 8 | 1000 9 | ); 10 | 11 | showTime(); 12 | 13 | setTimeout( 14 | function(){ 15 | Object.observe( 16 | app.data.alarm, 17 | function(data){ 18 | for(var val of data){ 19 | var clock=document.getElementById('clock-module'); 20 | if(!val.object.waitingToBeKilled){ 21 | clock.classList.remove('waitingToBeKilled'); 22 | return; 23 | } 24 | clock.classList.add('waitingToBeKilled'); 25 | } 26 | } 27 | ); 28 | }, 29 | 100 30 | ) 31 | 32 | el.addEventListener( 33 | 'click', 34 | function(e){ 35 | switch(e.target.id){ 36 | case 'snooze' : 37 | app.trigger('snooze'); 38 | break; 39 | case 'awake' : 40 | app.trigger('awake'); 41 | break; 42 | default : 43 | return; 44 | } 45 | } 46 | ); 47 | } 48 | 49 | function showTime(){ 50 | var date=new Date(); 51 | var hour=date.getHours(); 52 | var min=date.getMinutes(); 53 | 54 | app.data.time={ 55 | hour: hour, 56 | min : min 57 | } 58 | 59 | if(hour>12 && !app.data.military) 60 | hour=hour-12; 61 | 62 | document.getElementById('hour').innerHTML=hour; 63 | document.getElementById('minute').innerHTML=('0'+min).slice(-2); 64 | } 65 | 66 | exports(moduleName,render); 67 | } 68 | )(); 69 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Insane Alarm! 2 | This is a desktop port (nw.js) of my very first chrome app programmed one night when my wife was away. I had spent a night out with the boys and drank a bit too much but needed to be up in the morning. I realised that my phone was dead and I didn't have a charger, and my internet was unreliable at the time so none of the apps out there seemed like they would wake me up reliably. 3 | 4 | So I naturally did what any programmer would do, I programmed my own, with the LOUDEST alarm based off of an emergency alarm from when I was in the military. I couldn't find a good sound to match it in my intoxicated state... so I made my own using the Web Audio Context and Oscillator nodes. 5 | 6 | It supports Windows, Mac and Linux. 7 | 8 | ## Download Alarm 9 | Download the program or binaries for your system from our [insane alarm releases](https://github.com/RIAEvangelist/insane-alarm/releases) 10 | 11 | ## Support by Purchasing alarm 12 | #### [insane alarm](https://gum.co/insane-alarm) on gumroad.com 13 | If this alarm has saved your but, woken you, your spouse, children, animals and or neighbors up, please take a moment to show this app is worth a dollar to you! Its just a buck, you probably have lost 10x that much between the center console and your seat in the car. Show some love! 14 | 15 | ## Features 16 | 1. Loud as hell! 17 | 2. Adjusts brightness and colors based on ambient light. 18 | 3. Easy to use alarm settings. 19 | 4. Displays news headlines from CNN. 20 | 21 | ## Alarm screenshots 22 | ![Dark clock](https://github.com/RIAEvangelist/insane-alarm/blob/master/imgs/dark-clock.png) 23 | ![Dark alarm](https://github.com/RIAEvangelist/insane-alarm/blob/master/imgs/dark-alarm.png) 24 | ![Light clock](https://github.com/RIAEvangelist/insane-alarm/blob/master/imgs/light-clock.png) 25 | ![Light alarm](https://github.com/RIAEvangelist/insane-alarm/blob/master/imgs/light-alarm.png) 26 | 27 | ## Building from src 28 | 1. You will need nodejs installed. 29 | 2. run ` npm install ` from the insane-alarm directory (not the src directory). This should ` npm install nw-builder ` for the build script 30 | 3. run ` node build.js ` from the insane alarm directory. 31 | 4. run your build from the build folder created! 32 | 33 | ## Licensed under DBAD license 34 | See the [DBAD license](https://github.com/philsturgeon/dbad) in your language or our [licence.md](https://github.com/RIAEvangelist/insane-alarm/blob/master/license.md) file. 35 | -------------------------------------------------------------------------------- /src/app/resources/fonts/icomoon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Generated by IcoMoon 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/app/module/ambient/module.js: -------------------------------------------------------------------------------- 1 | ( 2 | function(){ 3 | var moduleName='ambient'; 4 | 5 | navigator.getUserMedia = ( navigator.getUserMedia || 6 | navigator.webkitGetUserMedia || 7 | navigator.mozGetUserMedia || 8 | navigator.msGetUserMedia); 9 | 10 | function render(el){ 11 | window.video = document.createElement('video'), 12 | window.canvas = document.createElement('canvas'), 13 | window.ctx = canvas.getContext('2d'); 14 | 15 | var constraints={ 16 | video: { 17 | mandatory: { 18 | maxHeight : 1, 19 | maxWidth : 1, 20 | maxFrameRate : 1 21 | } 22 | } 23 | } 24 | 25 | navigator.getUserMedia( 26 | constraints, 27 | function(localMediaStream){ 28 | window.localMediaStream=localMediaStream; 29 | video.src = window.URL.createObjectURL(window.localMediaStream); 30 | video.play(); 31 | }, 32 | function(err){ 33 | console.log(err); 34 | } 35 | ); 36 | 37 | setTimeout( 38 | renderAmbient, 39 | 100 40 | ); 41 | 42 | setInterval( 43 | renderAmbient, 44 | 1000 45 | ); 46 | } 47 | 48 | function renderAmbient(){ 49 | ctx.drawImage(video, 0, 0); 50 | 51 | var frame = ctx.getImageData(0, 0, canvas.width, canvas.height); 52 | 53 | var brightness=Math.floor( 54 | ( 55 | frame.data[0]+ 56 | frame.data[1]+ 57 | frame.data[2] 58 | )/3 59 | ); 60 | 61 | var use=240; 62 | var text=0; 63 | 64 | if(brightness<180){ 65 | use=100; 66 | } 67 | 68 | if(brightness<110){ 69 | use=0; 70 | color=130; 71 | } 72 | 73 | if(brightness<70){ 74 | use=0; 75 | color=40; 76 | } 77 | 78 | var rgb='rgb('+(new Array(4).join(use+',').slice(0,-1))+')'; 79 | var rgbText='rgb('+(new Array(4).join(color+',').slice(0,-1))+')'; 80 | 81 | app.data.ambient={ 82 | rgb:rgb, 83 | rgbText:rgbText 84 | } 85 | 86 | document.querySelector('body').style.backgroundColor=rgb; 87 | document.querySelector('.clock-module').style.color= 88 | document.querySelector('.news-module').style.color=rgbText; 89 | 90 | return; 91 | } 92 | 93 | 94 | exports(moduleName,render); 95 | } 96 | )(); 97 | -------------------------------------------------------------------------------- /src/app/module/news/module.js: -------------------------------------------------------------------------------- 1 | ( 2 | function(){ 3 | var moduleName='news'; 4 | var newsTimer=false; 5 | var news=false; 6 | 7 | function render(el){ 8 | fetchCNN(); 9 | el.addEventListener( 10 | 'click', 11 | function(e){ 12 | Window.open( 13 | e.target.getAttribute('href'), 14 | { 15 | frame:true, 16 | toolbar:true, 17 | focus:true 18 | } 19 | ); 20 | } 21 | ); 22 | 23 | setInterval( 24 | fetchCNN, 25 | 1200000//20 min 26 | ); 27 | } 28 | 29 | function fetchCNN(){ 30 | news=document.getElementById('news-module'); 31 | if(!navigator.onLine){ 32 | news.innerHTML='CNN not available in offline mode...'; 33 | return; 34 | } 35 | 36 | clearInterval( 37 | newsTimer 38 | ); 39 | 40 | var xhr = new XMLHttpRequest(); 41 | xhr.onload = function(e) { 42 | var jss = xmlToJson(e.target.responseXML.documentElement); 43 | news.innerHTML=jss.channel.title['#text']; 44 | var currentNews=0; 45 | 46 | news.setAttribute('href',jss.channel.item[currentNews].link['#text']); 47 | news.innerHTML='CNN : '+jss.channel.item[currentNews].title['#text']; 48 | newsTimer=setInterval( 49 | function(){ 50 | var index=currentNews++ % jss.channel.item.length; 51 | news.setAttribute('href',jss.channel.item[index].link['#text']); 52 | news.innerHTML='CNN : '+jss.channel.item[index].title['#text']; 53 | }, 54 | 25000 55 | ) 56 | 57 | } 58 | xhr.open("GET", "http://rss.cnn.com/rss/cnn_latest.rss"); 59 | xhr.send(); 60 | } 61 | 62 | function xmlToJson(xml) { 63 | 64 | var obj = {}; 65 | 66 | if (xml.nodeType == 1) { 67 | if (xml.attributes.length > 0) { 68 | obj["@attributes"] = {}; 69 | for (var j = 0; j < xml.attributes.length; j++) { 70 | var attribute = xml.attributes.item(j); 71 | obj["@attributes"][attribute.nodeName] = attribute.value; 72 | } 73 | } 74 | } else if (xml.nodeType == 3) { // text 75 | obj = xml.nodeValue; 76 | } 77 | 78 | if (xml.hasChildNodes()) { 79 | for(var i = 0; i < xml.childNodes.length; i++) { 80 | var item = xml.childNodes.item(i); 81 | var nodeName = item.nodeName; 82 | if (typeof(obj[nodeName]) == "undefined") { 83 | obj[nodeName] = xmlToJson(item); 84 | } else { 85 | if (typeof(obj[nodeName].push) == "undefined") { 86 | var old = obj[nodeName]; 87 | obj[nodeName] = []; 88 | obj[nodeName].push(old); 89 | } 90 | obj[nodeName].push(xmlToJson(item)); 91 | } 92 | } 93 | } 94 | return obj; 95 | }; 96 | 97 | exports(moduleName,render); 98 | } 99 | )(); 100 | -------------------------------------------------------------------------------- /src/app/module/set-alarm/module.js: -------------------------------------------------------------------------------- 1 | ( 2 | function(){ 3 | var moduleName='set-alarm'; 4 | app.data.alarm={}; 5 | 6 | window.AudioContext = ( 7 | window.AudioContext || 8 | window.webkitAudioContext 9 | ); 10 | 11 | window.alarm= 12 | alarm={}; 13 | alarm.context=new AudioContext(); 14 | alarm.mainVolume=alarm.context.createGain(); 15 | alarm.mainVolume.connect(alarm.context.destination); 16 | 17 | alarm.toneLength=1000; 18 | alarm.toneBreakLength=300; 19 | alarm.sound={ 20 | low: { 21 | hertz : 200 22 | }, 23 | mid: { 24 | hertz : 500 25 | }, 26 | high: { 27 | hertz : 1000 28 | } 29 | }; 30 | 31 | function render(el){ 32 | var hourOptions=document.getElementById('hourOptions'); 33 | var minOptions=document.getElementById('minOptions'); 34 | 35 | el.addEventListener( 36 | 'click', 37 | function(e){ 38 | if(!e.target.tagName.toLowerCase()=='li') 39 | return; 40 | 41 | var currentSelection=e.target.parentElement.querySelector('.selected') 42 | 43 | if(currentSelection) 44 | currentSelection.classList.remove('selected'); 45 | 46 | e.target.classList.add('selected'); 47 | 48 | setAlarm(); 49 | } 50 | ); 51 | 52 | for(var i=0; i<24; i++){ 53 | var hour=i; 54 | 55 | if(hour==0) 56 | hour=12; 57 | 58 | if(i<12) 59 | hour+='AM' 60 | 61 | if(i>11){ 62 | if(i>12) 63 | hour=i-12; 64 | hour+='PM' 65 | } 66 | 67 | var option=app.template( 68 | 'hour-option', 69 | { 70 | hour:i, 71 | hourDisplay:hour 72 | } 73 | ) 74 | 75 | hourOptions.appendChild( 76 | option 77 | ) 78 | } 79 | 80 | for(var i=0; i<60; i++){ 81 | var option=app.template( 82 | 'min-option', 83 | { 84 | min:i 85 | } 86 | ) 87 | 88 | minOptions.appendChild( 89 | option 90 | ) 91 | } 92 | 93 | setTimeout( 94 | initAlarm, 95 | 100 96 | ); 97 | } 98 | 99 | function loadPrefrences(){ 100 | app.storage.get( 101 | null, 102 | function(data){ 103 | app.data.alarm=data; 104 | app.data.alarm.killed=false; 105 | if(!app.data.alarm.hour) 106 | app.data.alarm.hour=7; 107 | 108 | if(!app.data.alarm.min) 109 | app.data.alarm.min=30; 110 | 111 | //chrome.power.requestKeepAwake("system"); 112 | } 113 | ); 114 | } 115 | loadPrefrences(); 116 | 117 | function initAlarm(){ 118 | if( 119 | !!!app.data.alarm.hour || 120 | !!!app.data.alarm.min 121 | ){ 122 | return; 123 | } 124 | 125 | document.querySelector('[hour="'+app.data.alarm.hour+'"]').classList.add('selected'); 126 | document.querySelector('[min="'+app.data.alarm.min+'"]').classList.add('selected'); 127 | 128 | setInterval( 129 | checkAlarm, 130 | alarm.toneLength+alarm.toneBreakLength 131 | ); 132 | 133 | } 134 | 135 | function setAlarm(){ 136 | var times=document.querySelectorAll('.selected'); 137 | if(times.length<2) 138 | return; 139 | 140 | var alarmData={ 141 | hour: times[0].getAttribute('hour'), 142 | min : times[1].getAttribute('min') 143 | } 144 | 145 | app.storage.set( 146 | alarmData 147 | ); 148 | 149 | app.data.alarm.hour=alarmData.hour; 150 | app.data.alarm.min=alarmData.min; 151 | } 152 | 153 | function checkAlarm(){ 154 | document.body.style.backgroundColor=app.data.ambient.rgb; 155 | if( 156 | ( 157 | !app.data.alarm.waitingToBeKilled && 158 | ( 159 | Number(app.data.time.hour)!= Number(app.data.alarm.hour) || 160 | Number(app.data.time.min) != Number(app.data.alarm.min) 161 | ) 162 | ) || 163 | app.data.alarm.killed 164 | ){ 165 | return; 166 | } 167 | 168 | document.body.style.backgroundColor='rgb(255,255,255)'; 169 | 170 | app.data.alarm.waitingToBeKilled=true; 171 | app.data.alarm.killed=false; 172 | 173 | app.navigate('home'); 174 | 175 | win.focus(); 176 | win.enterFullscreen(); 177 | 178 | //chrome.power.requestKeepAwake("display"); 179 | 180 | for (i in alarm.sound) { 181 | if(!alarm.oscillators) 182 | break; 183 | var oscillator=alarm.oscillators[i]; 184 | if(!oscillator) 185 | continue; 186 | if(!oscillator.tone) 187 | continue; 188 | oscillator.tone.stop(0); 189 | }; 190 | 191 | alarm.oscillators={}; 192 | 193 | for (var i in alarm.sound) { 194 | var oscillator, 195 | tone=alarm.sound[i]; 196 | 197 | alarm.oscillators[i]={}; 198 | oscillator=alarm.oscillators[i]; 199 | oscillator.tone=alarm.context.createOscillator(); 200 | oscillator.volume=alarm.context.createGain(); 201 | oscillator.tone.type=0; 202 | oscillator.tone.frequency.value=tone.hertz; 203 | oscillator.tone.connect(oscillator.volume); 204 | oscillator.volume.connect(alarm.mainVolume); 205 | } 206 | 207 | for (i in alarm.sound) { 208 | var oscillator=alarm.oscillators[i]; 209 | oscillator.tone.start(0); 210 | } 211 | 212 | clearTimeout(alarm.beat); 213 | alarm.beat=setTimeout( 214 | function(){ 215 | for (i in alarm.sound) { 216 | var oscillator=alarm.oscillators[i]; 217 | if(!oscillator) 218 | continue; 219 | if(!oscillator.tone) 220 | continue; 221 | oscillator.tone.stop(0); 222 | }; 223 | document.body.style.backgroundColor=app.data.ambient.rgb; 224 | }, 225 | alarm.toneLength 226 | ); 227 | } 228 | 229 | function killAlarm(){ 230 | app.data.alarm.killed=true; 231 | app.data.alarm.waitingToBeKilled=false; 232 | resetAlarm(true); 233 | } 234 | 235 | function snoozeAlarm(){ 236 | app.data.alarm.killed=true; 237 | app.data.alarm.waitingToBeKilled=false; 238 | app.data.alarm.min=Number(app.data.alarm.min)+5; 239 | if(app.data.alarm.min>59){ 240 | app.data.alarm.hour=Number(app.data.alarm.hour)+1; 241 | if(app.data.alarm.hour>23) 242 | app.data.alarm.hour=0; 243 | 244 | app.data.alarm.min-=60; 245 | } 246 | resetAlarm(); 247 | } 248 | 249 | function resetAlarm(hardReset){ 250 | setTimeout( 251 | function(){ 252 | app.data.alarm.killed=false; 253 | }, 254 | 55000 255 | ); 256 | 257 | if(!hardReset) 258 | return; 259 | 260 | setTimeout( 261 | loadPrefrences, 262 | 60000 263 | ); 264 | } 265 | 266 | app.on( 267 | 'awake', 268 | killAlarm 269 | ); 270 | 271 | app.on( 272 | 'snooze', 273 | snoozeAlarm 274 | ) 275 | 276 | exports(moduleName,render); 277 | } 278 | )(); 279 | -------------------------------------------------------------------------------- /src/app/resources/fonts/DIGITALDREAM-webfont.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | This is a custom SVG webfont generated by Font Squirrel. 6 | Copyright : c Jakob Fischer at wwwpizzadudedk DO NOT DISTRIBUTE WITHOUT AUTHORS PERMISSION 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | -------------------------------------------------------------------------------- /src/app/core/app.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileOverview app framework 3 | * @module core 4 | */ 5 | 6 | /** 7 | * check for chrome variable to be defnined (safary) 8 | */ 9 | if (typeof chrome === 'undefined') { 10 | chrome = false; 11 | } 12 | 13 | /** 14 | * @class app 15 | * @type Function|app_L10.appAnonym$2 16 | */ 17 | var app = ( 18 | function(){ 19 | 20 | /************\ 21 | Scope 22 | \************/ 23 | var config={ 24 | corePath: 'app/core/', 25 | modulesPath : 'app/module/', 26 | }; 27 | 28 | 29 | var modules, 30 | constructors={}, 31 | moduleQueue = {}, 32 | events=[], 33 | dataStore={ 34 | hasWebkitSpeech:(document.createElement('input').hasOwnProperty('webkitSpeech')), 35 | hasSpeech:(document.createElement('input').hasOwnProperty('speech')), 36 | HTML:{}, 37 | JS:{}, 38 | CSS:{} 39 | }; 40 | 41 | if (!history) { 42 | history = {}; 43 | } 44 | 45 | if (!history.pushState) { 46 | history.pushState = function (stateObject, screen) { 47 | history.state = stateObject; 48 | }; 49 | history.state = {}; 50 | } 51 | 52 | /** 53 | * set config object base on user config properties 54 | * 55 | * @memberOf app 56 | * @function setConfig 57 | * @param {object} userConfig 58 | * @returns {void} 59 | */ 60 | function setConfig(userConfig) { 61 | for (var property in userConfig) { 62 | if (userConfig.hasOwnProperty('property')) { 63 | config[property] = userConfig[property]; 64 | } else { 65 | return; 66 | } 67 | } 68 | } 69 | 70 | /************\ 71 | Modules 72 | \************/ 73 | /** 74 | * get module list base on html class element 75 | * 76 | * @memberOf app 77 | * @function getModules 78 | * @returns {void} 79 | */ 80 | function getModules() { 81 | modules = document.getElementsByClassName('appModule'); 82 | } 83 | 84 | /** 85 | * method to build modules 86 | * 87 | * @memberOf app 88 | * @function buildModules 89 | * @param {object} elements 90 | * @returns {void} 91 | */ 92 | function buildModules(elements) { 93 | if (!elements) { 94 | elements = modules; 95 | if (!elements) { 96 | elements = []; 97 | } 98 | } 99 | 100 | if (!elements[0]) { 101 | elements = [elements]; 102 | } 103 | 104 | if( !elements[0].getAttribute) { 105 | return; 106 | } 107 | 108 | var moduleCount=elements.length; 109 | 110 | for(var i=0; i-1){ 315 | modules[i].classList.remove('hidden'); 316 | continue; 317 | } 318 | 319 | modules[i].classList.add('hidden'); 320 | } 321 | 322 | triggerEvent( 323 | 'app.navigated', 324 | stateObject 325 | ); 326 | 327 | history.pushState( 328 | stateObject, 329 | screen, 330 | '#'+screen 331 | ); 332 | } 333 | 334 | // if app.navigate event triggered, we want to show module group 335 | registerEvent('app.navigate', showModuleGroup); 336 | 337 | window.addEventListener( 338 | 'popstate', 339 | function(e){ 340 | var state = e.state; 341 | if (!state) { 342 | state = {}; 343 | } 344 | 345 | if (!state.screen) { 346 | state.screen = document.location.hash.slice(1); 347 | } 348 | 349 | showModuleGroup(state.screen, state); 350 | } 351 | ); 352 | 353 | /** 354 | * initialize layout base on the layout object injected 355 | * 356 | * @memberOf app 357 | * @function layoutAppt 358 | * @param {object} layout object that represent layout and logic 359 | * @returns {void} 360 | * @see app.layout.json 361 | * @see loadLayout 362 | */ 363 | function layoutApp(layout) { 364 | 365 | if (!layout.lib) { 366 | layout.lib = []; 367 | } 368 | 369 | if (!layout.modules) { 370 | layout.modules = {}; 371 | } 372 | 373 | for (var i = 0; i < layout.lib.length; i++) { 374 | var lib; 375 | switch (layout.lib[i].type) { 376 | case 'css' : 377 | lib = document.createElement('link'); 378 | lib.setAttribute('href', layout.lib[i].path); 379 | lib.setAttribute('rel', 'stylesheet'); 380 | dataStore.CSS[layout.lib[i].path] = lib.outerHTML; 381 | break; 382 | case 'js': 383 | lib = document.createElement('script'); 384 | lib.setAttribute('async', true); 385 | lib.setAttribute('src', layout.lib[i].path); 386 | dataStore.JS[layout.lib[i].path] = lib.outerHTML; 387 | break; 388 | } 389 | document.head.appendChild(lib); 390 | } 391 | 392 | // building logic modules 393 | for (var j = 0; j < layout.modules.logic.length; j++) { 394 | appendDOMNode( 395 | createModuleElement(layout.modules.logic[j], 'false', 'false') 396 | ); 397 | } 398 | 399 | // check if dataStore compiled is set, if not try to retrieve it from the html element 400 | dataStore.compiled = document.querySelector('html').classList.contains('compiled-app'); 401 | if(dataStore.compiled) { 402 | return; 403 | } 404 | 405 | var fullList = {}; 406 | var screenList = Object.keys(layout.modules.ui); 407 | for (var k = 0; k < screenList.length; k++) { 408 | var screenModules = Object.keys( layout.modules.ui[screenList[k]] ); 409 | for (var l = 0; l < screenModules.length; l++) { 410 | fullList[screenModules[l]] = true; 411 | } 412 | } 413 | 414 | var layoutModules = Object.keys(fullList); 415 | for (var n = 0; n < layoutModules.length; n++) { 416 | var tempNewModule = createModuleElement( layoutModules[n] ); 417 | appendDOMNode(tempNewModule); 418 | } 419 | } 420 | 421 | /** 422 | * method to create html module element 423 | * 424 | * @memberOf app 425 | * @function createModuleElement 426 | * @param {string} name modurle name 427 | * @param {string} html html for the module 428 | * @param {string} css css file 429 | * @returns {app_L14.createModuleElement.newModule|Element} 430 | */ 431 | function createModuleElement(name, html, css) { 432 | var newModule = document.createElement('div'); 433 | if(!html) { 434 | html='true'; 435 | } 436 | if(!css) { 437 | css='true'; 438 | } 439 | newModule.id=name+'-module'; 440 | newModule.classList.add( 441 | 'appModule', 442 | 'hidden', 443 | name+'-module' 444 | ); 445 | 446 | newModule.setAttribute( 447 | 'data-dompath', 448 | 'body' 449 | ); 450 | newModule.setAttribute( 451 | 'data-moduletype', 452 | name 453 | ); 454 | newModule.setAttribute( 455 | 'data-html', 456 | html 457 | ); 458 | newModule.setAttribute( 459 | 'data-css', 460 | css 461 | ); 462 | 463 | return newModule; 464 | } 465 | 466 | /** 467 | * @memberOf app 468 | * @param {string} moduleType 469 | * @returns {Boolean} 470 | */ 471 | function checkModuleExists(moduleType){ 472 | return !!!constructors[moduleType]; 473 | } 474 | 475 | /** 476 | * @memberOf app 477 | * @param {object} parent 478 | * @returns {void} 479 | */ 480 | function findAndInitDynamicModules(parent){ 481 | buildModules(parent.querySelectorAll('[data-moduletype]')); 482 | } 483 | 484 | /** 485 | * @memberOf app 486 | * @function addConstructor 487 | * @param {string} type 488 | * @param {function} moduleInit 489 | * @returns {void} 490 | */ 491 | function addConstructor(type, moduleInit){ 492 | if(constructors[type]) { 493 | return; 494 | } 495 | 496 | constructors[type] = moduleInit; 497 | if(document.readyState == 'complete') { 498 | deferredLoad(type); 499 | } 500 | } 501 | 502 | /** 503 | * @memberOf app 504 | * @function initModules 505 | * @returns {void} 506 | */ 507 | function initModules(){ 508 | switch(document.readyState){ 509 | case 'interactive' : 510 | //dom not yet ready 511 | break; 512 | case 'complete' : 513 | getModules(); 514 | buildModules(); 515 | break; 516 | } 517 | } 518 | 519 | /************\ 520 | Utils 521 | \************/ 522 | 523 | /* 524 | * @memberOf app 525 | * @function fillTemplate 526 | * @param {string} id of element to fetch innerHTML as contents for template or raw string to be used as template if rawString set to true 527 | * @param {object} values should contain the key value pairs for all template Data 528 | * @param {bool} rawString use id as a raw html string 529 | * @param {bool} asString return as string or not 530 | * @returns {DomElement|string} if asString is false or not specified will return Filled out Template Element, if asString is true will return a filled out template string 531 | */ 532 | function fillTemplate(id, values, rawString, asString) { 533 | var template = id; 534 | 535 | if (!id) { 536 | throw new AppError('Templates must specify either id or a string+rawString flag', 'app.template'); 537 | } 538 | if(!rawString) { 539 | template=document.getElementById(id).innerHTML; 540 | } 541 | 542 | var keys=Object.keys(values); 543 | for(var i=0; i'; 574 | 575 | if (type === 'test') { 576 | defaults += '' + 577 | '' + 578 | '' + 579 | '' + 580 | ''; 581 | } 582 | 583 | this.body=''; 584 | this.head=''; 585 | var list=[ 586 | 'HTML', 587 | 'CSS', 588 | 'JS' 589 | ]; 590 | 591 | /** 592 | * compile module 593 | * @param {string} name 594 | * @param {string} content 595 | * @returns {void} 596 | */ 597 | function compileModule(name, content){ 598 | 599 | var module=createModuleElement(name); 600 | module.innerHTML=content; 601 | this.body+=module.outerHTML; 602 | } 603 | 604 | for(var j=0; j