[init] adding project files

This commit is contained in:
zombieFox 2018-12-26 00:45:53 -07:00
commit 213b23cb46
83 changed files with 19015 additions and 0 deletions

1
README.md Normal file
View File

@ -0,0 +1 @@
# nightTab

66
css/base.css Normal file
View File

@ -0,0 +1,66 @@
:root {
--black: #222222;
--white: #ffffff;
--gray-01: #262831;
--gray-02: #2f333e;
--gray-03: #393e4b;
--gray-04: #434958;
--gray-05: #4d5465;
--gray-06: #575f72;
--gray-07: #616a7f;
--gray-08: #6b758c;
--gray-09: #758099;
--gray-10: #7f8ba6;
--gray-11: #8997b4;
--gray-12: #95a2bb;
--gray-13: #a2adc3;
--gray-14: #aeb8cb;
--gray-15: #bbc3d3;
--gray-16: #c7ceda;
--gray-17: #d4d9e2;
--gray-18: #e0e4ea;
--gray-19: #edeff2;
--gray-20: #fafafa;
--root-font-size: 16px;
--radius: 2px;
--accent: 255, 170, 51;
--background: var(--gray-01);
--animation-speed-fast: 0.1s;
--animation-speed-medium: 0.2s;
--animation-speed-slow: 0.3s;
--link-height: 7em;
--url-height: 20%;
--edit-height: 30%;
--font-regular: "Open Sans Regular", sans-serif;
--font-bold: "Open Sans Bold", sans-serif;
--font-light: "Open Sans Light", sans-serif;
--font-fjalla: "Fjalla One Regular", sans-serif;
}
@media (min-width: 700px) {
:root {
--link-height: 9em;
}
}
::selection {
background-color: rgb(var(--accent));
color: var(--white);
}
html {
font-size: var(--root-font-size);
}
body {
background-color: var(--background);
color: var(--white);
font-size: 1rem;
width: 100vw;
height: 100vh;
font-family: var(--font-regular);
}
* {
box-sizing: border-box;
}

119
css/button.css Normal file
View File

@ -0,0 +1,119 @@
button,
.button,
input[type="button"],
input[type="reset"],
input[type="submit"] {
background-color: var(--gray-02);
padding: 0.25em 1em;
margin: 0 0 1em 0;
color: var(--gray-16);
font-size: 1em;
font-family: var(--font-regular);
min-height: 2.5em;
line-height: 1;
border: 0;
border-top-width: 2px;
border-bottom-width: 2px;
border-style: solid;
border-color: transparent;
border-radius: var(--radius);
text-align: center;
text-decoration: none;
white-space: nowrap;
cursor: pointer;
box-shadow: none;
transition: all var(--animation-speed-medium) ease-in-out;
display: inline-flex;
flex-direction: row;
justify-content: center;
align-items: center;
}
.button.active {
border-top-width: 3px;
border-bottom-width: 3px;
border-bottom-color: rgb(var(--accent));
}
button [class^="icon-"],
button [class*=" icon-"],
.button [class^="icon-"],
.button [class*=" icon-"] {
font-size: 1.5em;
line-height: 1;
}
.button-small {
font-size: 0.8em;
}
.button-group {
margin: 0 0 1em 0;
display: flex;
justify-content: center;
align-items: stretch;
}
.button-group button,
.button-group .button {
margin: 0;
border-radius: 0;
}
.button-group button:first-child,
.button-group .button:first-child {
border-radius: var(--radius) 0 0 var(--radius);
}
.button-group button:last-child,
.button-group .button:last-child {
border-radius: 0 var(--radius) var(--radius) 0;
}
button:hover,
button:focus,
.button:hover,
.button:focus,
input[type="button"]:hover,
input[type="button"]:focus,
input[type="reset"]:hover,
input[type="reset"]:focus,
input[type="submit"]:hover,
input[type="submit"]:focus {
background-color: var(--gray-03);
border-bottom-color: rgb(var(--accent));
color: var(--white);
outline: 0;
}
button:active,
.button:active,
input[type="button"]:active,
input[type="reset"]:active,
input[type="submit"]:active {
background-color: var(--gray-04);
color: var(--white);
transition: none;
}
button [class^="button-"],
button [class*=" button-"],
.button [class^="button-"],
.button [class*=" button-"] {
margin-left: 0.25em;
margin-right: 0.25em;
}
button [class^="button-"]:first-child,
button [class*=" button-"]:first-child,
.button [class^="button-"]:first-child,
.button [class*=" button-"]:first-child {
margin-left: 0;
}
button [class^="button-"]:last-child,
button [class*=" button-"]:last-child,
.button [class^="button-"]:last-child,
.button [class*=" button-"]:last-child {
margin-right: 0;
}

26
css/clock.css Normal file
View File

@ -0,0 +1,26 @@
.clock {
margin: 0;
padding: 0;
min-width: 6em;
font-family: var(--font-fjalla);
font-size: 1.5em;
color: var(--white);
text-align: center;
transition: all var(--animation-speed-medium) ease-in-out;
}
.clock-seperator {
color: rgb(var(--accent));
}
.clock-hour {
color: var(--white);
}
.clock-minutes {
color: var(--gray-16);
}
.clock-seconds {
color: var(--gray-12);
}

96
css/fonts.css Normal file
View File

@ -0,0 +1,96 @@
/* open sans */
@font-face {
font-family: "Open Sans Bold";
src: url("../fonts/open-sans/open-sans-bold.eot");
src: url("../fonts/open-sans/open-sans-bold.eot?#iefix") format("embedded-opentype"), url("../fonts/open-sans/open-sans-bold.woff2") format("woff2"), url("../fonts/open-sans/open-sans-bold.woff") format("woff"), url("../fonts/open-sans/open-sans-bold.ttf") format("truetype");
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: "Open Sans Regular";
src: url("../fonts/open-sans/open-sans-regular.eot");
src: url("../fonts/open-sans/open-sans-regular.eot?#iefix") format("embedded-opentype"), url("../fonts/open-sans/open-sans-regular.woff2") format("woff2"), url("../fonts/open-sans/open-sans-regular.woff") format("woff"), url("../fonts/open-sans/open-sans-regular.ttf") format("truetype");
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: "Open Sans Light";
src: url("../fonts/open-sans/open-sans-light.eot");
src: url("../fonts/open-sans/open-sans-light.eot?#iefix") format("embedded-opentype"), url("../fonts/open-sans/open-sans-light.woff2") format("woff2"), url("../fonts/open-sans/open-sans-light.woff") format("woff"), url("../fonts/open-sans/open-sans-light.ttf") format("truetype");
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: "Open Sans Bold Italic";
src: url("../fonts/open-sans/open-sans-bold-italic.eot");
src: url("../fonts/open-sans/open-sans-bold-italic.eot?#iefix") format("embedded-opentype"), url("../fonts/open-sans/open-sans-bold-italic.woff2") format("woff2"), url("../fonts/open-sans/open-sans-bold-italic.woff") format("woff"), url("../fonts/open-sans/open-sans-bold-italic.ttf") format("truetype");
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: "Open Sans Italic";
src: url("../fonts/open-sans/open-sans-italic.eot");
src: url("../fonts/open-sans/open-sans-italic.eot?#iefix") format("embedded-opentype"), url("../fonts/open-sans/open-sans-italic.woff2") format("woff2"), url("../fonts/open-sans/open-sans-italic.woff") format("woff"), url("../fonts/open-sans/open-sans-italic.ttf") format("truetype");
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: "Open Sans Light Italic";
src: url("../fonts/open-sans/open-sans-light-italic.eot");
src: url("../fonts/open-sans/open-sans-light-italic.eot?#iefix") format("embedded-opentype"), url("../fonts/open-sans/open-sans-light-italic.woff2") format("woff2"), url("../fonts/open-sans/open-sans-light-italic.woff") format("woff"), url("../fonts/open-sans/open-sans-light-italic.ttf") format("truetype");
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: "Open Sans Semi Bold Italic";
src: url("../fonts/open-sans/open-sans-semi-bold-italic.eot");
src: url("../fonts/open-sans/open-sans-semi-bold-italic.eot?#iefix") format("embedded-opentype"), url("../fonts/open-sans/open-sans-semi-bold-italic.woff2") format("woff2"), url("../fonts/open-sans/open-sans-semi-bold-italic.woff") format("woff"), url("../fonts/open-sans/open-sans-semi-bold-italic.ttf") format("truetype");
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: "Open Sans Semi Bold";
src: url("../fonts/open-sans/open-sans-semi-bold.eot");
src: url("../fonts/open-sans/open-sans-semi-bold.eot?#iefix") format("embedded-opentype"), url("../fonts/open-sans/open-sans-semi-bold.woff2") format("woff2"), url("../fonts/open-sans/open-sans-semi-bold.woff") format("woff"), url("../fonts/open-sans/open-sans-semi-bold.ttf") format("truetype");
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: "Open Sans Condensed Bold";
src: url("../fonts/open-sans/open-sans-condensed-bold.eot");
src: url("../fonts/open-sans/open-sans-condensed-bold.eot?#iefix") format("embedded-opentype"), url("../fonts/open-sans/open-sans-condensed-bold.woff2") format("woff2"), url("../fonts/open-sans/open-sans-condensed-bold.woff") format("woff"), url("../fonts/open-sans/open-sans-condensed-bold.ttf") format("truetype");
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: "Open Sans Condensed Light Italic";
src: url("../fonts/open-sans/open-sans-condensed-light-italic.eot");
src: url("../fonts/open-sans/open-sans-condensed-light-italic.eot?#iefix") format("embedded-opentype"), url("../fonts/open-sans/open-sans-condensed-light-italic.woff2") format("woff2"), url("../fonts/open-sans/open-sans-condensed-light-italic.woff") format("woff"), url("../fonts/open-sans/open-sans-condensed-light-italic.ttf") format("truetype");
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: "Open Sans Condensed Light";
src: url("../fonts/open-sans/open-sans-condensed-light.eot");
src: url("../fonts/open-sans/open-sans-condensed-light.eot?#iefix") format("embedded-opentype"), url("../fonts/open-sans/open-sans-condensed-light.woff2") format("woff2"), url("../fonts/open-sans/open-sans-condensed-light.woff") format("woff"), url("../fonts/open-sans/open-sans-condensed-light.ttf") format("truetype");
font-weight: normal;
font-style: normal;
}
/* fjalla one */
@font-face {
font-family: "Fjalla One Regular";
src: url("../fonts/fjalla-one/fjalla-one-regular.woff2") format("woff2"), url("../fonts/fjalla-one/fjalla-one-regular.woff") format("woff"), url("../fonts/fjalla-one/fjalla-one-regular.ttf") format("truetype");
font-weight: normal;
font-style: normal;
}

94
css/form.css Normal file
View File

@ -0,0 +1,94 @@
input[type="email"],
input[type="number"],
input[type="password"],
input[type="search"],
input[type="tel"],
input[type="text"] {
background-color: var(--gray-16);
padding: 0 0.5em;
margin: 0 0 1em 0;
color: var(--black);
font-size: 1em;
font-family: var(--font-regular);
line-height: 2.5em;
height: 2.5em;
width: 100%;
border-width: 2px;
border-style: solid;
border-color: transparent;
border-radius: var(--radius);
cursor: text;
transition: all var(--animation-speed-medium) ease-in-out;
-moz-appearance: textfield;
}
input[type="email"]:hover,
input[type="number"]:hover,
input[type="password"]:hover,
input[type="search"]:hover,
input[type="tel"]:hover,
input[type="text"]:hover {
border-color: rgb(var(--accent));
color: var(--black);
outline: 0;
}
input[type="email"]:focus,
input[type="number"]:focus,
input[type="password"]:focus,
input[type="search"]:focus,
input[type="tel"]:focus,
input[type="text"]:focus {
background-color: var(--white);
border-color: rgb(var(--accent));
color: var(--black);
box-shadow: inset 0 0 0 0 rgba(0, 0, 0, 0), 0 0 0 2px rgb(var(--accent));
outline: 0;
z-index: 2;
}
input[type="email"]::placeholder,
input[type="number"]::placeholder,
input[type="password"]::placeholder,
input[type="search"]::placeholder,
input[type="tel"]::placeholder,
input[type="text"]::placeholder {
color: var(--gray-10);
transition: all var(--animation-speed-medium) ease-in-out;
}
input[type="email"]:focus::placeholder,
input[type="number"]:focus::placeholder,
input[type="password"]:focus::placeholder,
input[type="search"]:focus::placeholder,
input[type="tel"]:focus::placeholder,
input[type="text"]:focus::placeholder {
color: var(--gray-14);
}
label {
color: var(--gray-18);
font-size: 1em;
display: inline-block;
}
input[type="color"] {
border: 0;
height: 2.5em;
min-width: 2.5em;
display: block;
cursor: pointer;
-webkit-appearance: none;
}
input[type="color"]:focus {
outline: 0;
}
input[type="color"]::-webkit-color-swatch-wrapper {
padding: 0;
}
input[type="color"]::-webkit-color-swatch {
border: 0;
}

69
css/grid.css Normal file
View File

@ -0,0 +1,69 @@
.grid {
height: 100vh;
width: 100vw;
display: grid;
grid-template-columns: 100%;
grid-template-rows: auto 1fr;
grid-gap: 0;
justify-content: center;
align-items: start;
}
.grid-item-head {
padding: 4em 2em 2em 2em;
width: 100%;
}
.grid-item-body {
padding: 2em 2em 25vh 2em;
width: 100%;
max-height: 100%;
overflow-y: scroll;
display: grid;
grid-template-columns: repeat(2, minmax(1em, 1fr));
grid-auto-rows: 1fr;
grid-gap: 1em;
}
@media (min-width: 700px) {
.grid-item-body {
grid-template-columns: repeat(3, minmax(1em, 1fr));
}
}
@media (min-width: 1000px) {
.grid-item-head,
.grid-item-body {
padding-left: 15vw;
padding-right: 15vw;
}
.grid-item-body {
grid-template-columns: repeat(4, minmax(1em, 1fr));
}
}
@media (min-width: 1300px) {
.grid-item-body {
grid-template-columns: repeat(5, minmax(1em, 1fr));
}
}
@media (min-width: 1600px) {
.grid-item-body {
grid-template-columns: repeat(6, minmax(1em, 1fr));
}
}
@media (min-width: 1900px) {
.grid-item-body {
grid-template-columns: repeat(7, minmax(1em, 1fr));
}
}
@media (min-width: 2200px) {
.grid-item-body {
grid-template-columns: repeat(8, minmax(1em, 1fr));
}
}

32
css/head.css Normal file
View File

@ -0,0 +1,32 @@
.head {
margin: 0;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: center;
}
.head-item {
margin-left: 0.5em;
margin-right: 0.5em;
display: flex;
flex-wrap: nowrap;
justify-content: center;
align-items: center;
}
.head-item:first-child {
margin-left: 0;
}
.head-item:last-child {
margin-right: 0;
}
.head-item-shrink {
flex-shrink: 0;
}
.head-item-grow {
flex-grow: 1;
}

116
css/icons.css Executable file
View File

@ -0,0 +1,116 @@
@font-face {
font-family: "icons";
src: url("../fonts/icons/icons.eot?4e687y");
src: url("../fonts/icons/icons.eot?4e687y#iefix") format("embedded-opentype"),
url("../fonts/icons/icons.ttf?4e687y") format("truetype"),
url("../fonts/icons/icons.woff?4e687y") format("woff"),
url("../fonts/icons/icons.svg?4e687y#icons") format("svg");
font-weight: normal;
font-style: normal;
}
[class^="icon-"],
[class*=" icon-"] {
/* use !important to prevent issues with browser extensions that change fonts */
font-family: "icons" !important;
speak: none;
font-style: normal;
font-weight: normal;
font-variant: normal;
text-transform: none;
line-height: 1;
/* Better Font Rendering =========== */
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.icon-add:before {
content: "\e145";
}
.icon-arrow-back:before {
content: "\e5c4";
}
.icon-arrow-downward:before {
content: "\e5db";
}
.icon-arrow-forward:before {
content: "\e5c8";
}
.icon-arrow-upward:before {
content: "\e5d8";
}
.icon-check:before {
content: "\e5ca";
}
.icon-check-box-checked:before {
content: "\e834";
}
.icon-check-box-unchecked:before {
content: "\e835";
}
.icon-check-box-indeterminate:before {
content: "\e909";
}
.icon-close:before {
content: "\e5cd";
}
.icon-edit:before {
content: "\e254";
}
.icon-done:before {
content: "\e876";
}
.icon-arrow-down:before {
content: "\e313";
}
.icon-arrow-left:before {
content: "\e314";
}
.icon-arrow-right:before {
content: "\e315";
}
.icon-arrow-up:before {
content: "\e316";
}
.icon-more-horiz:before {
content: "\e5d3";
}
.icon-more-vert:before {
content: "\e5d4";
}
.icon-radio-unchecked:before {
content: "\e836";
}
.icon-radio-checked:before {
content: "\e837";
}
.icon-remove:before {
content: "\e15b";
}
.icon-unfold-less:before {
content: "\e5d6";
}
.icon-unfold-more:before {
content: "\e5d7";
}

202
css/links.css Normal file
View File

@ -0,0 +1,202 @@
.link-item {
width: 100%;
height: var(--link-height);
font-size: 1em;
position: relative;
display: block;
transform: scale(1);
transition: all var(--animation-speed-medium) ease-in-out;
}
.link-item:focus,
.link-item:hover {
transform: scale(1.06);
}
.link-item:active {
transform: scale(1.04);
transition: none;
}
.link-panel-front {
background-color: var(--gray-02);
border-radius: var(--radius);
padding: 0 1em;
width: 100%;
height: calc(100% - 2px);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
z-index: 3;
position: relative;
user-select: none;
transition: all var(--animation-speed-medium) ease-in-out;
}
.link-panel-front:focus {
background-color: var(--gray-03);
outline: 0;
}
.link-item:hover .link-panel-front,
.link-item:focus .link-panel-front {
text-decoration: none;
outline: 0;
background-color: var(--gray-03);
height: calc(100% - var(--url-height));
box-shadow: 0 2px 1em 0 rgba(0, 0, 0, 0.4);
}
.link-panel-back {
display: flex;
flex-direction: column;
justify-content: flex-end;
align-items: stretch;
width: 100%;
height: 100%;
position: absolute;
bottom: 0;
left: 0;
z-index: 2;
}
.link-panel-back:before {
content: "";
background-color: rgb(var(--accent));
border-radius: var(--radius);
width: calc(100% - 0.5em);
height: calc(100% - 0.25em);
position: absolute;
bottom: 0;
left: 0.25em;
z-index: -1;
transition: all var(--animation-speed-medium) ease-in-out;
}
.link-control {
margin: 0 0.25em;
height: 0;
display: flex;
overflow: hidden;
flex-direction: row;
align-items: stretch;
justify-content: center;
transition: all var(--animation-speed-medium) ease-in-out;
}
.link-control-item {
background-color: transparent;
margin-bottom: 0;
border: 0;
padding-left: 0;
padding-right: 0;
color: var(--gray-02);
flex-grow: 1;
flex-basis: 50%;
}
.link-control-item:first-child {
border-radius: 0 0 0 var(--radius);
}
.link-control-item:last-child {
border-radius: 0 0 var(--radius) 0
}
.link-control-item:focus,
.link-control-item:hover {
color: var(--black);
background-color: rgba(255, 255, 255, 0.2);
}
.link-control-item:active {
color: var(--black);
background-color: rgba(255, 255, 255, 0.4);
transition: none;
}
.link-url {
padding: 0 1em;
width: 100%;
height: 0;
overflow: hidden;
display: flex;
justify-content: center;
align-items: center;
transition: all var(--animation-speed-medium) ease-in-out;
}
.link-item:hover .link-url,
.link-item:focus .link-url {
height: var(--url-height);
}
.link-url-text {
margin: 0;
font-size: 0.7em;
text-align: center;
color: var(--black);
font-family: var(--font-regular);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.link-letter {
margin: 0;
font-size: 2em;
text-align: center;
font-family: var(--font-fjalla);
color: rgb(var(--accent));
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
transition: all var(--animation-speed-medium) ease-in-out;
}
.link-item:hover .link-letter,
.link-item:focus .link-letter {
color: var(--white);
}
.link-name {
margin: 0;
font-size: 0.9em;
text-align: center;
font-family: var(--font-regular);
color: var(--gray-08);
white-space: nowrap;
overflow: hidden;
opacity: 1;
text-overflow: ellipsis;
transition: all var(--animation-speed-medium) ease-in-out;
}
.link-item:hover .link-name,
.link-item:focus .link-name {
color: var(--white);
}
.is-edit .link-panel-front,
.is-edit .link-item:hover .link-panel-front,
.is-edit .link-item:focus .link-panel-front {
height: calc(100% - var(--edit-height));
box-shadow: 0 2px 1em 0 rgba(0, 0, 0, 0.4);
}
.is-edit .link-control {
height: var(--edit-height);
}
.is-edit .link-item:hover .link-url,
.is-edit .link-item:focus .link-url {
height: 0;
}
height: var(--edit-height);
}
.is-edit .link-control-item {
pointer-events: all;
}

81
css/modal.css Normal file
View File

@ -0,0 +1,81 @@
.modal {
position: fixed;
top: 50%;
left: 50%;
font-size: 1em;
z-index: 2000;
width: 45em;
max-width: calc(100% - 6em);
min-width: 10em;
transform: translate(-50%, -50%);
opacity: 0;
perspective: 1000px;
transition: opacity var(--animation-speed-slow);
}
.modal-large {
width: 65em;
max-width: calc(100% - 2em);
}
.modal-small {
width: 25em;
}
.modal-wrapper {
box-sizing: border-box;
position: relative;
transition: all var(--animation-speed-fast);
}
.modal-wrapper .container {
max-width: 100%;
}
.is-transition-end .modal-wrapper {
transition: all var(--animation-speed-medium);
}
.modal-body {
background-color: var(--gray-02);
border-radius: var(--radius) var(--radius) 0 0;
border-bottom: 1em solid transparent;
border-bottom-color: var(--gray-02);
padding: 2em;
max-height: calc(90vh - 3.6666666667em);
overflow: scroll;
box-sizing: border-box;
z-index: 1;
position: relative;
}
.modal-heading {}
.modal-heading:focus {
outline: 0;
}
.modal-controls {
background-color: var(--gray-02);
margin: -1em 0 0;
position: relative;
z-index: 2;
border-radius: 0 0 var(--radius) var(--radius);
display: flex;
}
.modal-controls .button {
border-radius: 0;
margin: 0;
padding-top: 1.5em;
padding-bottom: 1.5em;
flex-basis: 50%;
}
.modal-controls .button:first-child {
border-radius: 0 0 0 var(--radius);
}
.modal-controls .button:last-child {
border-radius: 0 0 var(--radius) 0
}

317
css/reset.css Normal file
View File

@ -0,0 +1,317 @@
*,
*::before,
*::after {
box-sizing: border-box;
}
html {
font-family: sans-serif;
line-height: 1.15;
-webkit-text-size-adjust: 100%;
-ms-overflow-style: scrollbar;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
@-ms-viewport {
width: device-width;
}
article, aside, figcaption, figure, footer, header, hgroup, main, nav, section {
display: block;
}
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, Noto Sans, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
font-size: 1rem;
font-weight: 400;
line-height: 1.5;
color: #212529;
text-align: left;
background-color: #fff;
}
[tabindex="-1"]:focus {
outline: 0 !important;
}
hr {
box-sizing: content-box;
height: 0;
overflow: visible;
}
h1, h2, h3, h4, h5, h6 {
margin-top: 0;
margin-bottom: 0.5rem;
}
p {
margin-top: 0;
margin-bottom: 1rem;
}
abbr[title],
abbr[data-original-title] {
text-decoration: underline;
-webkit-text-decoration: underline dotted;
text-decoration: underline dotted;
cursor: help;
border-bottom: 0;
text-decoration-skip-ink: none;
}
address {
margin-bottom: 1rem;
font-style: normal;
line-height: inherit;
}
ol,
ul,
dl {
margin-top: 0;
margin-bottom: 1rem;
}
ol ol,
ul ul,
ol ul,
ul ol {
margin-bottom: 0;
}
dt {
font-weight: 700;
}
dd {
margin-bottom: .5rem;
margin-left: 0;
}
blockquote {
margin: 0 0 1rem;
}
b,
strong {
font-weight: bolder;
}
small {
font-size: 80%;
}
sub,
sup {
position: relative;
font-size: 75%;
line-height: 0;
vertical-align: baseline;
}
sub {
bottom: -.25em;
}
sup {
top: -.5em;
}
a {
color: #007bff;
text-decoration: none;
background-color: transparent;
}
a:hover {
color: #0056b3;
text-decoration: underline;
}
a:not([href]):not([tabindex]) {
color: inherit;
text-decoration: none;
}
a:not([href]):not([tabindex]):hover, a:not([href]):not([tabindex]):focus {
color: inherit;
text-decoration: none;
}
a:not([href]):not([tabindex]):focus {
outline: 0;
}
pre,
code,
kbd,
samp {
font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
font-size: 1em;
}
pre {
margin-top: 0;
margin-bottom: 1rem;
overflow: auto;
-ms-overflow-style: scrollbar;
}
figure {
margin: 0 0 1rem;
}
img {
vertical-align: middle;
border-style: none;
}
svg {
overflow: hidden;
vertical-align: middle;
}
table {
border-collapse: collapse;
}
caption {
padding-top: 0.75rem;
padding-bottom: 0.75rem;
color: #6c757d;
text-align: left;
caption-side: bottom;
}
th {
text-align: inherit;
}
label {
display: inline-block;
margin-bottom: 0.5rem;
}
button {
border-radius: 0;
}
button:focus {
outline: 1px dotted;
outline: 5px auto -webkit-focus-ring-color;
}
input,
button,
select,
optgroup,
textarea {
margin: 0;
font-family: inherit;
font-size: inherit;
line-height: inherit;
}
button,
input {
overflow: visible;
}
button,
select {
text-transform: none;
}
button,
[type="button"],
[type="reset"],
[type="submit"] {
-webkit-appearance: button;
}
button::-moz-focus-inner,
[type="button"]::-moz-focus-inner,
[type="reset"]::-moz-focus-inner,
[type="submit"]::-moz-focus-inner {
padding: 0;
border-style: none;
}
input[type="radio"],
input[type="checkbox"] {
box-sizing: border-box;
padding: 0;
}
input[type="date"],
input[type="time"],
input[type="datetime-local"],
input[type="month"] {
-webkit-appearance: listbox;
}
textarea {
overflow: auto;
resize: vertical;
}
fieldset {
min-width: 0;
padding: 0;
margin: 0;
border: 0;
}
legend {
display: block;
width: 100%;
max-width: 100%;
padding: 0;
margin-bottom: .5rem;
font-size: 1.5rem;
line-height: inherit;
color: inherit;
white-space: normal;
}
progress {
vertical-align: baseline;
}
[type="number"]::-webkit-inner-spin-button,
[type="number"]::-webkit-outer-spin-button {
height: auto;
}
[type="search"] {
outline-offset: -2px;
-webkit-appearance: none;
}
[type="search"]::-webkit-search-decoration {
-webkit-appearance: none;
}
::-webkit-file-upload-button {
font: inherit;
-webkit-appearance: button;
}
output {
display: inline-block;
}
summary {
display: list-item;
cursor: pointer;
}
template {
display: none;
}
[hidden] {
display: none !important;
}

3
css/search.css Normal file
View File

@ -0,0 +1,3 @@
.search {
width: 100%;
}

19
css/shade.css Normal file
View File

@ -0,0 +1,19 @@
.m-shade {
background-color: rgba(var(--accent), 0.5);
position: fixed;
top: -1em;
left: -1em;
width: calc(100% + 2em);
height: calc(100% + 2em);
opacity: 0.5;
z-index: 1000;
transition: opacity var(--animation-speed-slow);
}
@media (min-width: $screen-sm) {}
@media (min-width: $screen-md) {}
@media (min-width: $screen-lg) {}
@media (min-width: $screen-xl) {}

30
css/theme.css Normal file
View File

@ -0,0 +1,30 @@
.theme {
position: relative;
}
.theme-label.button {
position: relative;
padding-right: 2.25em;
}
.theme-label:before {
background-color: rgb(var(--accent));
content: "";
border-radius: 50%;
position: absolute;
right: 0.5em;
width: 1em;
height: 1em;
z-index: 1;
box-shadow: 0 0 0.25em 0 rgba(var(--accent), 0.6), 0 0 0.5em 0 rgba(var(--accent), 0.4);
}
.theme-input[type="color"] {
opacity: 0;
width: 2px;
min-width: 2px;
height: 2px;
position: absolute;
top: 0;
left: 0;
}

145
css/typography.css Normal file
View File

@ -0,0 +1,145 @@
h1,
h2,
h3,
h4,
h5,
h6 {
margin: 0 0 1em 0;
font-weight: normal;
line-height: 1.5;
}
h1 {
font-size: 1.5em;
font-family: var(--font-light);
}
h2 {
font-size: 1.5em;
font-family: var(--font-light);
}
h3 {
font-size: 1.5em;
font-family: var(--font-regular);
}
h4 {
font-size: 1.25em;
font-family: var(--font-bold);
}
h5 {
font-size: 1em;
font-family: var(--font-bold);
}
h6 {
font-size: 0.75em;
font-family: var(--font-bold);
}
p {
color: var(--black);
margin: 0;
line-height: 1.5;
}
hr {
border: 0;
border: 1px solid var(--gray-08);
margin: 1em 0;
clear: both;
}
b,
caption,
strong {
font-family: var(--font-bold);
}
a {
color: var(--gray-16);
text-decoration: none;
}
a:link,
a:visited {
color: var(--gray-16);
}
a:focus {
text-decoration: none;
outline: 0;
}
a:hover {
color: var(--white);
text-decoration: underline;
}
a:active {
color: var(--white);
}
ol,
ul {
margin: 0;
padding: 0 0 0 1.5em;
}
ol:not(:last-child),
ul:not(:last-child) {
margin-bottom: 1em;
}
li {
margin: 0;
}
li>ul,
li>ol {
margin: 0;
}
li:not(:last-child) {
margin-bottom: 0.5em;
}
li>ul:not(:last-child),
li>ol:not(:last-child) {
margin-bottom: 0.5em;
}
table {
border: 0;
margin: 0 0 1em;
padding: 0;
width: 100%;
border-spacing: 0;
}
table thead tr td,
table thead tr th {
background-color: var(--gray-03);
border: 0;
border-bottom: 1px solid var(--gray-04);
padding: 0.5em;
margin: 0;
text-align: left;
font-family: var(--font-bold);
box-sizing: border-box;
}
table tr:nth-child(odd) {
background-color: var(--gray-02);
}
table tbody tr td,
table tbody tr th {
padding: 0.25em 0.5em;
margin: 0;
border: 0;
text-align: left;
box-sizing: border-box;
}

55
css/utilities.css Normal file
View File

@ -0,0 +1,55 @@
.margin-top-0 {
margin-top: 0 !important;
}
.margin-right-0 {
margin-right: 0 !important;
}
.margin-bottom-0 {
margin-bottom: 0 !important;
}
.margin-left-0 {
margin-left: 0 !important;
}
.is-hidden {
display: none !important;
}
.is-inline-block {
display: inline-block !important;
}
.is-block {
display: block !important;
}
.is-transparent {
opacity: 0 !important;
}
.is-opaque {
opacity: 1 !important;
}
.is-invisible {
visibility: hidden !important;
}
.is-visible {
visibility: visible !important;
}
.is-scrolll-disabled {
overflow: hidden !important;
}
.is-small {
transform: scale(0.5) !important;
}
.is-large {
transform: scale(1.5) !important;
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
fonts/icons/icons.eot Executable file

Binary file not shown.

16250
fonts/icons/icons.json Normal file

File diff suppressed because it is too large Load Diff

33
fonts/icons/icons.svg Executable file
View File

@ -0,0 +1,33 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
<svg xmlns="http://www.w3.org/2000/svg">
<metadata>Generated by IcoMoon</metadata>
<defs>
<font id="icomoon" horiz-adv-x="1024">
<font-face units-per-em="1024" ascent="960" descent="-64" />
<missing-glyph horiz-adv-x="1024" />
<glyph unicode="&#x20;" horiz-adv-x="512" d="" />
<glyph unicode="&#xe145;" glyph-name="add" d="M810 384.667h-256v-256h-84v256h-256v84h256v256h84v-256h256v-84z" />
<glyph unicode="&#xe15b;" glyph-name="remove" d="M810 384.667h-596v84h596v-84z" />
<glyph unicode="&#xe254;" glyph-name="mode_edit" d="M884 638.667l-78-78-160 160 78 78c16 16 44 16 60 0l100-100c16-16 16-44 0-60zM128 202.667l472 472 160-160-472-472h-160v160z" />
<glyph unicode="&#xe313;" glyph-name="keyboard_arrow_down" d="M316 604.667l196-196 196 196 60-60-256-256-256 256z" />
<glyph unicode="&#xe314;" glyph-name="keyboard_arrow_left" d="M658 252.667l-60-60-256 256 256 256 60-60-196-196z" />
<glyph unicode="&#xe315;" glyph-name="keyboard_arrow_right" d="M366 240.667l196 196-196 196 60 60 256-256-256-256z" />
<glyph unicode="&#xe316;" glyph-name="keyboard_arrow_up" d="M316 280.667l-60 60 256 256 256-256-60-60-196 196z" />
<glyph unicode="&#xe5c4;" glyph-name="arrow_back" d="M854 468.667v-84h-520l238-240-60-60-342 342 342 342 60-60-238-240h520z" />
<glyph unicode="&#xe5c8;" glyph-name="arrow_forward" d="M512 768.667l342-342-342-342-60 60 238 240h-520v84h520l-238 240z" />
<glyph unicode="&#xe5ca;" glyph-name="check" d="M384 248.667l452 452 60-60-512-512-238 238 60 60z" />
<glyph unicode="&#xe5cd;" glyph-name="close" d="M810 664.667l-238-238 238-238-60-60-238 238-238-238-60 60 238 238-238 238 60 60 238-238 238 238z" />
<glyph unicode="&#xe5d3;" glyph-name="more_horiz" d="M512 512.667c46 0 86-40 86-86s-40-86-86-86-86 40-86 86 40 86 86 86zM768 512.667c46 0 86-40 86-86s-40-86-86-86-86 40-86 86 40 86 86 86zM256 512.667c46 0 86-40 86-86s-40-86-86-86-86 40-86 86 40 86 86 86z" />
<glyph unicode="&#xe5d4;" glyph-name="more_vert" d="M512 256.667c46 0 86-40 86-86s-40-86-86-86-86 40-86 86 40 86 86 86zM512 512.667c46 0 86-40 86-86s-40-86-86-86-86 40-86 86 40 86 86 86zM512 596.667c-46 0-86 40-86 86s40 86 86 86 86-40 86-86-40-86-86-86z" />
<glyph unicode="&#xe5d6;" glyph-name="unfold_less" d="M708 708.667l-196-196-196 196 60 60 136-136 136 136zM316 144.667l196 196 196-196-60-60-136 136-136-136z" />
<glyph unicode="&#xe5d7;" glyph-name="unfold_more" d="M512 162.667l136 136 60-60-196-196-196 196 60 60zM512 690.667l-136-136-60 60 196 196 196-196-60-60z" />
<glyph unicode="&#xe5d8;" glyph-name="arrow_upward" d="M170 426.667l342 342 342-342-62-60-238 238v-520h-84v520l-240-238z" />
<glyph unicode="&#xe5db;" glyph-name="arrow_downward" d="M854 426.667l-342-342-342 342 62 60 238-238v520h84v-520l240 238z" />
<glyph unicode="&#xe834;" glyph-name="check_box" d="M426 212.667l384 384-60 62-324-324-152 152-60-60zM810 810.667c48 0 86-40 86-86v-596c0-46-38-86-86-86h-596c-48 0-86 40-86 86v596c0 46 38 86 86 86h596z" />
<glyph unicode="&#xe835;" glyph-name="check_box_outline_blank" d="M810 810.667c46 0 86-40 86-86v-596c0-46-40-86-86-86h-596c-46 0-86 40-86 86v596c0 46 40 86 86 86h596zM810 724.667h-596v-596h596v596z" />
<glyph unicode="&#xe836;" glyph-name="radio_button_unchecked" d="M512 84.667c188 0 342 154 342 342s-154 342-342 342-342-154-342-342 154-342 342-342zM512 852.667c236 0 426-190 426-426s-190-426-426-426-426 190-426 426 190 426 426 426z" />
<glyph unicode="&#xe837;" glyph-name="radio_button_checked" d="M512 84.667c188 0 342 154 342 342s-154 342-342 342-342-154-342-342 154-342 342-342zM512 852.667c236 0 426-190 426-426s-190-426-426-426-426 190-426 426 190 426 426 426zM512 640.667c118 0 214-96 214-214s-96-214-214-214-214 96-214 214 96 214 214 214z" />
<glyph unicode="&#xe876;" glyph-name="done" d="M384 246.667l452 454 60-60-512-512-238 238 58 60z" />
<glyph unicode="&#xe909;" glyph-name="indeterminate_check_box" d="M726 384.667v84h-428v-84h428zM810 810.667c46 0 86-40 86-86v-596c0-46-40-86-86-86h-596c-46 0-86 40-86 86v596c0 46 40 86 86 86h596z" />
</font></defs></svg>

After

Width:  |  Height:  |  Size: 4.0 KiB

BIN
fonts/icons/icons.ttf Executable file

Binary file not shown.

BIN
fonts/icons/icons.woff Executable file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

86
index.html Normal file
View File

@ -0,0 +1,86 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<title>New Tab</title>
<link rel="stylesheet" href="css/reset.css">
<link rel="stylesheet" href="css/fonts.css">
<link rel="stylesheet" href="css/icons.css">
<link rel="stylesheet" href="css/utilities.css">
<link rel="stylesheet" href="css/base.css">
<link rel="stylesheet" href="css/theme.css">
<link rel="stylesheet" href="css/typography.css">
<link rel="stylesheet" href="css/grid.css">
<link rel="stylesheet" href="css/button.css">
<link rel="stylesheet" href="css/form.css">
<link rel="stylesheet" href="css/shade.css">
<link rel="stylesheet" href="css/modal.css">
<link rel="stylesheet" href="css/head.css">
<link rel="stylesheet" href="css/clock.css">
<link rel="stylesheet" href="css/search.css">
<link rel="stylesheet" href="css/links.css">
</head>
<body>
<div class="grid">
<div class="grid-item-head">
<div class="head">
<div class="head-item">
<p class="clock"></p>
</div>
<div class="head-item head-item-grow">
<form class="search" action="http://www.google.com/search" method="get">
<input class="search-input margin-bottom-0" type="text" placeholder="Find bookmarks or search" tabindex="1" name="q" autocomplete="off" tabindex="1">
<input type="submit" value="Search" class="is-hidden">
</form>
</div>
<div class="head-item search-clear is-hidden">
<button class="button margin-bottom-0" tabindex="1">
<span class="icon-close"></span>
</button>
</div>
<div class="head-item">
<button class="button margin-bottom-0 control-add" tabindex="1">
<span class="button-text">Add</span>
</button>
</div>
<div class="head-item">
<button class="button margin-bottom-0 control-edit" tabindex="1">
<span class="button-text">Edit</span>
</button>
</div>
<div class="head-item">
<form class="theme">
<label class="button margin-bottom-0 theme-label" for="accent-picker">
<span class="button-text">Accent</span>
</label>
<input id="accent-picker" type="color" class="theme-input" value="#ffaa33" tabindex="1">
</form>
</div>
</div>
</div>
<div class="grid-item-body"></div>
</div>
</body>
<script src="js/helper.js"></script>
<script src="js/control.js"></script>
<script src="js/bookmarks.js"></script>
<script src="js/modal.js"></script>
<script src="js/shade.js"></script>
<script src="js/theme.js"></script>
<script src="js/clock.js"></script>
<script src="js/search.js"></script>
<script src="js/state.js"></script>
<script src="js/data.js"></script>
<script src="js/links.js"></script>
<script src="js/init.js"></script>
</html>

138
js/bookmarks.js Normal file
View File

@ -0,0 +1,138 @@
var bookmarks = (function() {
var all = [{
url: "https://www.reddit.com/r/Android/",
name: "/r/Android/",
letter: "AN"
}, {
url: "https://analytics.google.com/",
name: "Analytics",
letter: "ANA"
}, {
url: "https://zombiefox.github.io/awesomeSheet/",
name: "awesomeSheet",
letter: "AS"
}, {
url: "https://www.amazon.co.uk/",
name: "Amazon",
letter: "AZ"
}, {
url: "https://app.box.com/login/",
name: "Box",
letter: "BX"
}, {
url: "https://www.google.com/calendar/",
name: "Calendar",
letter: "CAL"
}, {
url: "https://citymapper.com/london/superrouter",
name: "Citymapper",
letter: "CM"
}, {
url: "https://contacts.google.com/",
name: "Contacts",
letter: "CO"
}, {
url: "https://www.reddit.com/r/chromeos/",
name: "/r/chromeos/",
letter: "COS"
}, {
url: "https://drive.google.com/drive/",
name: "Drive",
letter: "DR"
}, {
url: "http://devdocs.io/",
name: "Devdocs",
letter: "DEV"
}, {
url: "https://www.facebook.com/",
name: "Facebook",
letter: "FB"
}, {
url: "https://github.com/login",
name: "Github",
letter: "GIT"
}, {
url: "https://mail.google.com/",
name: "Gmail",
letter: "GM"
}, {
url: "https://www.reddit.com/r/gameofthrones/",
name: "/r/gameofthrones/",
letter: "GOT"
}, {
url: "https://keep.google.com/",
name: "Keep",
letter: "KP"
}, {
url: "https://www.google.co.uk/maps",
name: "Maps",
letter: "M"
}, {
url: "https://www.reddit.com/r/monsterhunter/",
name: "/r/monsterhunter/",
letter: "MHW"
}, {
url: "https://www.netflix.com/",
name: "Netflix",
letter: "N"
}, {
url: "https://www.reddit.com/r/opendirectories/",
name: "/r/opendirectories/",
letter: "OD"
}, {
url: "https://photos.google.com/",
name: "Photos",
letter: "P"
}, {
url: "https://www.reddit.com/r/Pathfinder_RPG/",
name: "/r/Pathfinder_RPG/",
letter: "PRG"
}, {
url: "https://www.reddit.com/",
name: "Reddit",
letter: "R"
}, {
url: "http://content.tfl.gov.uk/standard-tube-map.pdf",
name: "TFL Map",
letter: "TFL"
}, {
url: "https://www.reddit.com/r/videos/",
name: "/r/videos/",
letter: "V"
}, {
url: "https://www.youtube.com/",
name: "Youtube",
letter: "YT"
}];
var get = function() {
return all;
};
var add = function(object) {
all.push(object);
};
var edit = function(object, index) {
all[index] = object;
};
var remove = function(index) {
all.splice(index, 1);
};
var restore = function(array) {
all = array;
};
// exposed methods
return {
get: get,
add: add,
edit: edit,
remove: remove,
restore: restore
};
})();

60
js/clock.js Normal file
View File

@ -0,0 +1,60 @@
var clock = (function() {
var clear = function() {
var clock = helper.e(".clock")
while (clock.lastChild) {
clock.removeChild(clock.lastChild);
};
};
var render = function() {
var time = helper.getDateTime();
if (time.minutes < 10) {
time.minutes = "0" + time.minutes;
};
if (time.seconds < 10) {
time.seconds = "0" + time.seconds;
};
// if (time.hours > 12) {
// time.hours = time.hours - 12;
// };
var hour = document.createElement("span");
hour.setAttribute("class", "clock-hour");
hour.textContent = time.hours;
var minutes = document.createElement("span");
minutes.setAttribute("class", "clock-minutes");
minutes.textContent = time.minutes;
var seconds = document.createElement("span");
seconds.setAttribute("class", "clock-seconds");
seconds.textContent = time.seconds;
var seperator1 = document.createElement("span");
seperator1.setAttribute("class", "clock-seperator");
seperator1.textContent = " : ";
var seperator2 = document.createElement("span");
seperator2.setAttribute("class", "clock-seperator");
seperator2.textContent = " : ";
var clock = helper.e(".clock");
clock.appendChild(hour);
clock.appendChild(seperator1);
clock.appendChild(minutes);
clock.appendChild(seperator2);
clock.appendChild(seconds);
};
var init = function() {
clear();
render();
window.setInterval(function() {
clear();
render();
}, 1000);
};
// exposed methods
return {
init: init,
render: render,
clear: clear
};
})();

48
js/control.js Normal file
View File

@ -0,0 +1,48 @@
var control = (function() {
var state = {
edit: false
};
var bind = function() {
var controlAdd = helper.e(".control-add");
var controlEdit = helper.e(".control-edit");
controlAdd.addEventListener("click", function() {
_add();
}, false);
controlEdit.addEventListener("click", function() {
_edit();
}, false);
};
var _add = function() {
links.add();
};
var _edit = function() {
var body = helper.e("body");
var controlEdit = helper.e(".control-edit");
if (state.edit) {
helper.removeClass(body, "is-edit");
helper.removeClass(controlEdit, "active");
state.edit = false;
links.tabindex();
} else {
helper.addClass(body, "is-edit");
helper.addClass(controlEdit, "active");
state.edit = true;
links.tabindex();
};
};
var init = function() {
bind();
};
// exposed methods
return {
init: init,
state: state
};
})();

46
js/data.js Normal file
View File

@ -0,0 +1,46 @@
var data = (function() {
var saveName = "nitghTab";
var set = function(key, data) {
localStorage.setItem(key, data);
};
var get = function(key) {
return localStorage.getItem(key);
};
var clear = function(key) {
localStorage.removeItem(key);
};
var save = function() {
set(saveName, JSON.stringify(state.get()));
console.log(saveName + " saved");
};
var restore = function() {
var data = JSON.parse(get(saveName));
bookmarks.restore(data.bookmarks);
theme.restore(data.accent);
console.log(saveName + " restored");
};
var init = function() {
if (get(saveName)) {
restore();
} else {
save();
};
};
return {
init: init,
save: save,
clear: clear,
set: set,
get: get,
restore: restore
};
})();

111
js/helper.js Normal file
View File

@ -0,0 +1,111 @@
var helper = (function() {
// methods on this object
function e(selector) {
return document.querySelector(selector);
};
function eA(selector) {
return document.querySelectorAll(selector);
};
function toggleClass(element, theClassName) {
element.classList.toggle(theClassName);
};
function addClass(element, theClassName) {
element.classList.add(theClassName);
};
function removeClass(element, theClassName) {
element.classList.remove(theClassName);
};
function getDateTime() {
var dateStamp = new Date();
var object = {
// string: dateStamp.constructor(),
// time: dateStamp.getTime()
date: dateStamp.getDate(),
day: dateStamp.getDay(),
year: dateStamp.getFullYear(),
hours: dateStamp.getHours(),
milliseconds: dateStamp.getMilliseconds(),
minutes: dateStamp.getMinutes(),
month: dateStamp.getMonth(),
seconds: dateStamp.getSeconds()
}
return object;
};
var sortObject = function(object, key) {
object.sort(function(a, b) {
var textA = a[key].toLowerCase();
var textB = b[key].toLowerCase();
if (textA < textB) {
return -1;
} else if (textA > textB) {
return 1;
} else {
return 0;
};
});
return object;
};
function applyOptions(defaultOptions, options) {
if (defaultOptions && options) {
if (options) {
for (var key in options) {
if (key in defaultOptions) {
defaultOptions[key] = options[key];
};
};
};
return defaultOptions;
} else {
return null;
};
};
function hexToRgb(hex) {
var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
if (result) {
result = {
r: parseInt(result[1], 16),
g: parseInt(result[2], 16),
b: parseInt(result[3], 16)
};
} else {
result = null;
}
return result;
};
function rgbToHex(rgbObject) {
var componentToHex = function(hexPart) {
hexPart = hexPart.toString(16);
if (hexPart.length == 1) {
hexPart = "0" + hexPart
};
return hexPart;
};
var result = "#" + componentToHex(rgbObject.r) + componentToHex(rgbObject.g) + componentToHex(rgbObject.b);
return result;
};
// exposed methods
return {
e: e,
eA: eA,
toggleClass: toggleClass,
addClass: addClass,
removeClass: removeClass,
getDateTime: getDateTime,
sortObject: sortObject,
applyOptions: applyOptions,
hexToRgb: hexToRgb,
rgbToHex: rgbToHex
};
})();

10
js/init.js Normal file
View File

@ -0,0 +1,10 @@
// look for and restore data
data.init();
// render theme
theme.init();
// render links
links.init();
// other init
control.init();
search.init();
clock.init();

424
js/links.js Normal file
View File

@ -0,0 +1,424 @@
var links = (function() {
var _bind = function(override) {
var options = {
element: null,
action: null
};
if (override) {
options = helper.applyOptions(options, override);
}
var action = {
edit: function() {
options.element.addEventListener("click", function() {
edit(this);
}, false);
},
delete: function() {
options.element.addEventListener("click", function() {
remove(this);
}, false);
}
};
if (options.element != null) {
action[options.action]();
}
};
var currentEditIndex = null;
var currentAction = null;
var add = function() {
currentAction = "add";
var form = _makeLinkForm();
modal.render({
heading: "Add a new bookmark",
action: save,
actionText: "Add",
size: "small",
content: form
});
};
var edit = function(button) {
currentAction = "edit";
currentEditIndex = parseInt(button.closest(".link-item").dataset.index, 10);
var currentBookmark = bookmarks.get()[currentEditIndex];
var form = _makeLinkForm();
form.querySelector(".link-form-input-letter").value = currentBookmark.letter;
form.querySelector(".link-form-input-name").value = currentBookmark.name;
form.querySelector(".link-form-input-url").value = currentBookmark.url;
modal.render({
heading: "Edit " + currentBookmark.name,
action: save,
actionText: "Save",
size: "small",
content: form
});
};
var save = function(button) {
var action = {
add: function(newLinkData) {
bookmarks.add(newLinkData);
},
edit: function(newLinkData) {
bookmarks.edit(newLinkData, currentEditIndex);
}
};
var form = helper.e(".link-form");
var newLinkData = {
letter: form.querySelector(".link-form-input-letter").value,
name: form.querySelector(".link-form-input-name").value,
url: form.querySelector(".link-form-input-url").value
};
action[currentAction](newLinkData);
currentEditIndex = null;
currentAction = null;
clear();
render();
data.save();
};
var remove = function(button) {
var index = parseInt(button.closest(".link-item").dataset.index, 10);
bookmarks.remove(index);
clear();
render();
data.save();
};
var _makeElement = function(override) {
var options = {
tag: null,
classes: null,
text: null,
url: null,
index: null,
attr: null
};
if (override) {
options = helper.applyOptions(options, override);
};
var element = document.createElement(options.tag);
if (options.text != null) {
element.textContent = options.text;
};
if (options.attr != null) {
options.attr.forEach(function(arrayItem, index) {
if ("key" in arrayItem && "value" in arrayItem) {
element.setAttribute(arrayItem.key, arrayItem.value);
} else if ("key" in arrayItem) {
element.setAttribute(arrayItem.key, "");
}
});
};
return element;
};
var _makeLinkForm = function() {
var form = _makeElement({
tag: "form",
attr: [{
key: "class",
value: "link-form"
}]
});
var fieldset = _makeElement({
tag: "fieldset"
});
var letterLabel = _makeElement({
tag: "label",
text: "Letters",
attr: [{
key: "for",
value: "letters"
}]
});
var letterInput = _makeElement({
tag: "input",
attr: [{
key: "type",
value: "text"
}, {
key: "class",
value: "link-form-input-letter"
}, {
key: "id",
value: "letters"
}, {
key: "placeholder",
value: "E"
}, {
key: "tabindex",
value: "1"
}, {
key: "autocomplete",
value: "off"
}]
});
var nameLabel = _makeElement({
tag: "label",
text: "Name",
attr: [{
key: "for",
value: "name"
}]
});
var nameInput = _makeElement({
tag: "input",
attr: [{
key: "type",
value: "text"
}, {
key: "class",
value: "link-form-input-name"
}, {
key: "id",
value: "name"
}, {
key: "placeholder",
value: "Example"
}, {
key: "tabindex",
value: "1"
}, {
key: "autocomplete",
value: "off"
}]
});
var urlLabel = _makeElement({
tag: "label",
text: "URL",
attr: [{
key: "for",
value: "url"
}]
});
var urlInput = _makeElement({
tag: "input",
attr: [{
key: "type",
value: "text"
}, {
key: "class",
value: "link-form-input-url"
}, {
key: "id",
value: "url"
}, {
key: "placeholder",
value: "https://www.example.com/"
}, {
key: "tabindex",
value: "1"
}, {
key: "autocomplete",
value: "off"
}]
});
fieldset.appendChild(letterLabel);
fieldset.appendChild(letterInput);
fieldset.appendChild(nameLabel);
fieldset.appendChild(nameInput);
fieldset.appendChild(urlLabel);
fieldset.appendChild(urlInput);
form.appendChild(fieldset);
return form;
};
var render = function(array) {
var makeLinks = function(arrayOflinks) {
arrayOflinks.forEach(function(item, index) {
var gridItemBody = helper.e(".grid-item-body");
var linkItem = _makeElement({
tag: "div",
attr: [{
key: "class",
value: "link-item"
}, {
key: "data-index",
value: index
}]
});
var linkPanelFront = _makeElement({
tag: "a",
attr: [{
key: "class",
value: "link-panel-front"
}, {
key: "href",
value: item.url
}, {
key: "tabindex",
value: 1
}]
});
var linkPanelBack = _makeElement({
tag: "div",
attr: [{
key: "class",
value: "link-panel-back"
}]
});
var linkLetter = _makeElement({
tag: "p",
text: item.letter,
attr: [{
key: "class",
value: "link-letter"
}, {
key: "data-index",
value: item.url
}]
});
var linkName = _makeElement({
tag: "p",
text: item.name,
attr: [{
key: "class",
value: "link-name"
}]
});
var linkUrl = _makeElement({
tag: "div",
attr: [{
key: "class",
value: "link-url"
}]
});
var linkUrlText = _makeElement({
tag: "p",
text: item.url.replace(/^https?\:\/\//i, "").replace(/\/$/, ""),
attr: [{
key: "class",
value: "link-url-text"
}]
});
var linkControl = _makeElement({
tag: "div",
attr: [{
key: "class",
value: "link-control"
}]
});
var linkEdit = _makeElement({
tag: "button",
attr: [{
key: "class",
value: "button button-small link-control-item link-edit"
}, {
key: "tabindex",
value: -1
}]
});
// var linkEditText = _makeElement({
// tag: "span",
// text: "Edit",
// attr: [{
// key: "class",
// value: "button-text"
// }]
// });
var linkEditIcon = _makeElement({
tag: "span",
attr: [{
key: "class",
value: "button-icon icon-edit"
}]
});
var linkDelete = _makeElement({
tag: "button",
attr: [{
key: "class",
value: "button button-small link-control-item link-delete"
}, {
key: "tabindex",
value: -1
}]
});
// var linkDeleteText = _makeElement({
// tag: "span",
// text: "Delete",
// attr: [{
// key: "class",
// value: "button-text"
// }]
// });
var linkDeleteIcon = _makeElement({
tag: "span",
attr: [{
key: "class",
value: "button-icon icon-close"
}]
});
_bind({
element: linkEdit,
action: "edit"
});
_bind({
element: linkDelete,
action: "delete"
});
linkPanelFront.appendChild(linkLetter);
linkPanelFront.appendChild(linkName);
linkEdit.appendChild(linkEditIcon);
// linkEdit.appendChild(linkEditText);
linkDelete.appendChild(linkDeleteIcon);
// linkDelete.appendChild(linkDeleteText);
linkControl.appendChild(linkEdit);
linkControl.appendChild(linkDelete);
linkUrl.appendChild(linkUrlText);
linkPanelBack.appendChild(linkUrl);
linkPanelBack.appendChild(linkControl);
linkItem.appendChild(linkPanelFront);
linkItem.appendChild(linkPanelBack);
gridItemBody.appendChild(linkItem);
});
};
if (array) {
makeLinks(array);
} else {
makeLinks(bookmarks.get());
};
};
var tabindex = function() {
var allLinkControlItem = helper.eA(".link-control-item");
if (control.state.edit) {
allLinkControlItem.forEach(function(arrayItem, index) {
arrayItem.tabIndex = 1;
});
} else {
allLinkControlItem.forEach(function(arrayItem, index) {
arrayItem.tabIndex = -1;
});
};
};
var clear = function() {
var gridItemBody = helper.e(".grid-item-body");
while (gridItemBody.lastChild) {
gridItemBody.removeChild(gridItemBody.lastChild);
};
};
var init = function() {
render();
};
// exposed methods
return {
init: init,
clear: clear,
add: add,
edit: edit,
save: save,
remove: remove,
render: render,
tabindex: tabindex
};
})();

129
js/modal.js Normal file
View File

@ -0,0 +1,129 @@
var modal = (function() {
var previousModal = null;
function destroy() {
var all_modal = helper.eA(".modal");
if (all_modal[0]) {
for (var i = 0; i < all_modal.length; i++) {
all_modal[i].destroy();
};
};
};
function render(options) {
var defaultOptions = {
heading: "Modal",
content: "Body",
action: null,
actionText: "OK",
cancelText: "Cancel",
size: "medium"
};
if (options) {
defaultOptions = helper.applyOptions(defaultOptions, options);
};
var makeModal = function() {
var body = helper.e("body");
body.dataset.modal = true;
var modalWrapper = document.createElement("div");
modalWrapper.setAttribute("class", "modal-wrapper");
var modal = document.createElement("div");
if (defaultOptions.size == "large") {
modal.setAttribute("class", "modal modal-large");
} else if (defaultOptions.size == "small") {
modal.setAttribute("class", "modal modal-small");
} else if (defaultOptions.size) {
modal.setAttribute("class", "modal");
};
modal.destroy = function() {
if (modal.classList.contains("is-opaque")) {
helper.removeClass(modal, "is-opaque");
helper.addClass(modal, "is-transparent");
helper.addClass(modalWrapper, "is-droping-down");
} else {
modal.remove();
};
body.dataset.modal = false;
};
var modalBody = document.createElement("div");
modalBody.setAttribute("class", "modal-body");
var modalControls = document.createElement("div");
modalControls.setAttribute("class", "modal-controls");
var actionButton = document.createElement("button");
actionButton.setAttribute("tabindex", "1");
actionButton.setAttribute("class", "button button-primary button-block button-large");
actionButton.textContent = defaultOptions.actionText;
var cancelButton = document.createElement("button");
cancelButton.setAttribute("tabindex", "1");
cancelButton.setAttribute("class", "button button-primary button-block button-large");
cancelButton.textContent = defaultOptions.cancelText;
modalControls.appendChild(cancelButton);
modalControls.appendChild(actionButton);
if (defaultOptions.heading != null) {
var modalHeading = document.createElement("h1");
modalHeading.setAttribute("tabindex", "1");
modalHeading.setAttribute("class", "modal-heading");
modalHeading.textContent = defaultOptions.heading;
modalBody.appendChild(modalHeading);
};
if (defaultOptions.content) {
if (typeof defaultOptions.content == "string") {
var container = document.createElement("div");
container.setAttribute("class", "container");
var para = document.createElement("p");
para.textContent = defaultOptions.content;
container.appendChild(para);
modalBody.appendChild(container);
} else {
modalBody.appendChild(defaultOptions.content);
};
};
modalWrapper.appendChild(modalBody);
modalWrapper.appendChild(modalControls);
modal.appendChild(modalWrapper);
modal.addEventListener("transitionend", function(event, elapsed) {
if (event.propertyName === "opacity" && getComputedStyle(this).opacity == 0) {
this.parentElement.removeChild(this);
};
if (event.propertyName === "opacity" && getComputedStyle(this).opacity == 1) {
helper.addClass(this, "is-transition-end");
};
}.bind(modal), false);
actionButton.addEventListener("click", function(event) {
this.destroy();
shade.destroy();
if (defaultOptions.action) {
defaultOptions.action();
};
}.bind(modal), false);
cancelButton.addEventListener("click", function(event) {
this.destroy();
shade.destroy();
}.bind(modal), false);
previousModal = modal;
shade.render({
action: function() {
modal.destroy();
},
includeHeader: true
});
body.appendChild(modal);
getComputedStyle(modal).opacity;
helper.removeClass(modal, "is-transparent");
helper.addClass(modal, "is-opaque");
modalHeading.focus(this);
};
if (previousModal != null) {
destroy();
};
makeModal();
};
// exposed methods
return {
destroy: destroy,
render: render
};
})();

59
js/search.js Normal file
View File

@ -0,0 +1,59 @@
var search = (function() {
var bind = function() {
var searchInput = helper.e(".search-input");
var searchClear = helper.e(".search-clear");
searchClear.addEventListener("click", function() {
if (search.value != "") {
searchInput.value = "";
};
updateSearchClear();
searchInput.focus();
links.clear();
links.render();
}, false);
searchInput.addEventListener("input", function() {
_findResults(this.value);
}, false);
searchInput.addEventListener("keyup", function() {
updateSearchClear();
}, false);
};
var updateSearchClear = function() {
var searchInput = helper.e(".search-input");
var searchClear = helper.e(".search-clear");
if (searchInput.value != "") {
helper.removeClass(searchClear, "is-hidden");
} else {
helper.addClass(searchClear, "is-hidden");
}
};
var _findResults = function(string) {
var searchResult = [];
bookmarks.get().forEach(function(arrayItem, index) {
if (arrayItem.url.replace(/^https?\:\/\//i, "").replace(/\/$/, "").toLowerCase().includes(string.toLowerCase()) || arrayItem.name.toLowerCase().includes(string.toLowerCase())) {
searchResult.push(arrayItem);
};
links.clear();
links.render(searchResult);
});
};
var clear = function() {};
var render = function() {};
var init = function() {
bind();
};
// exposed methods
return {
init: init,
render: render,
clear: clear
};
})();

72
js/shade.js Normal file
View File

@ -0,0 +1,72 @@
var shade = (function() {
var previousShade = null;
function destroy() {
var all_shade = helper.eA(".js-shade");
if (all_shade[0]) {
for (var i = 0; i < all_shade.length; i++) {
all_shade[i].destroy();
};
};
};
function render(options) {
var defaultOptions = {
action: null,
includeHeader: false
};
if (options) {
defaultOptions = helper.applyOptions(defaultOptions, options);
};
var _destroy_previousShade = function() {
if (previousShade != null) {
destroy();
};
};
var _render_shade = function() {
var body = helper.e("body");
var shade = document.createElement("div");
shade.setAttribute("class", "m-shade js-shade");
if (defaultOptions.includeHeader) {
helper.addClass(shade, "m-shade-top");
};
shade.destroy = function() {
if (shade.classList.contains("is-opaque")) {
helper.removeClass(shade, "is-opaque");
helper.addClass(shade, "is-transparent");
} else {
shade.remove();
};
};
shade.addEventListener("transitionend", function(event, elapsed) {
if (event.propertyName === "opacity" && getComputedStyle(this).opacity == 0) {
this.parentElement.removeChild(this);
};
if (event.propertyName === "opacity" && getComputedStyle(this).opacity == 1) {
helper.addClass(this, "is-transition-end");
};
}.bind(shade), false);
shade.addEventListener("click", function() {
this.destroy();
if (defaultOptions.action) {
defaultOptions.action();
};
}, false);
previousShade = shade;
body.appendChild(shade);
getComputedStyle(shade).opacity;
helper.removeClass(shade, "is-transparent");
helper.addClass(shade, "is-opaque");
};
_destroy_previousShade();
_render_shade();
};
// exposed methods
return {
destroy: destroy,
render: render
};
})();

15
js/state.js Normal file
View File

@ -0,0 +1,15 @@
var state = (function() {
var get = function() {
var current = {
bookmarks: bookmarks.get(),
accent: theme.get()
};
return current;
};
return {
get: get
};
})();

54
js/theme.js Normal file
View File

@ -0,0 +1,54 @@
var theme = (function() {
var accent = {
r: 255,
g: 170,
b: 51,
};
var get = function() {
return accent;
};
var bind = function() {
var themeAccent = helper.e(".theme-input");
themeAccent.addEventListener("change", function() {
_updateAcent(this);
render();
data.save();
});
};
var _updateAcent = function(input) {
accent = helper.hexToRgb(input.value);
};
var _updateInput = function() {
var themeAccent = helper.e(".theme-input");
themeAccent.value = helper.rgbToHex(accent);
};
var render = function(input) {
var html = helper.e("html");
html.style.setProperty("--accent", accent.r + "," + accent.g + "," + accent.b);
};
var restore = function(object) {
accent = object;
_updateInput();
render();
};
var init = function() {
bind();
};
// exposed methods
return {
init: init,
get: get,
restore: restore,
render: render
};
})();

9
manifest.json Normal file
View File

@ -0,0 +1,9 @@
{
"name": "nightTab",
"description": "",
"version": "1.0",
"manifest_version": 2,
"chrome_url_overrides": {
"newtab": "index.html"
}
}