mirror of https://github.com/zombieFox/voltTab.git
add project files
This commit is contained in:
parent
29d9e2e9b5
commit
f8df65f2dc
|
@ -0,0 +1,24 @@
|
|||
name: gh-pages-deploy
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
build-and-deploy:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2.3.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Install and Build
|
||||
run: |
|
||||
npm install
|
||||
npm run build
|
||||
- name: Deploy
|
||||
uses: JamesIves/github-pages-deploy-action@4.1.3
|
||||
with:
|
||||
branch: gh-pages
|
||||
folder: dist/web
|
|
@ -0,0 +1,3 @@
|
|||
.DS_Store
|
||||
dist
|
||||
node_modules
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,43 @@
|
|||
{
|
||||
"name": "Volt Tab",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"start": "webpack serve --open --config webpack.dev.js",
|
||||
"build": "webpack --config webpack.prod.js"
|
||||
},
|
||||
"keywords": [
|
||||
"startpage",
|
||||
"start-page",
|
||||
"newtabpage",
|
||||
"new-tab-page",
|
||||
"tab",
|
||||
"chrome-extension",
|
||||
"extension",
|
||||
"bookmarks",
|
||||
"links",
|
||||
"gridTab"
|
||||
],
|
||||
"author": "zombieFox",
|
||||
"license": "GPL-3",
|
||||
"bugs": {
|
||||
"url": "https://github.com/zombieFox/gridTab/issues"
|
||||
},
|
||||
"homepage": "https://github.com/zombieFox/gridTab#readme",
|
||||
"devDependencies": {
|
||||
"copy-webpack-plugin": "^11.0.0",
|
||||
"css-loader": "^6.7.1",
|
||||
"css-minimizer-webpack-plugin": "^4.0.0",
|
||||
"html-webpack-plugin": "^5.5.0",
|
||||
"mini-css-extract-plugin": "^2.6.0",
|
||||
"sortablejs": "^1.15.0",
|
||||
"style-loader": "^3.3.1",
|
||||
"webfontloader": "^1.6.28",
|
||||
"webpack": "^5.72.1",
|
||||
"webpack-cli": "^4.9.2",
|
||||
"webpack-dev-server": "^4.9.0",
|
||||
"webpack-merge": "^5.8.0",
|
||||
"zip-webpack-plugin": "^4.0.1"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
.app {
|
||||
min-width: 100vw;
|
||||
min-height: 100vh;
|
||||
display: grid;
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
import { Base } from '../component/Base';
|
||||
import { Body } from '../component/Body';
|
||||
import { Background } from '../component/Background';
|
||||
import { Bookmark } from '../component/Bookmark';
|
||||
import { Theme } from '../component/Theme';
|
||||
import { Fontawesome } from '../component/Fontawesome';
|
||||
|
||||
import './index.css';
|
||||
|
||||
export const App = function() {
|
||||
|
||||
this.node = {
|
||||
app: document.createElement('div')
|
||||
}
|
||||
|
||||
this.base = new Base();
|
||||
|
||||
this.body = new Body();
|
||||
|
||||
this.theme = new Theme();
|
||||
|
||||
this.fontawesome = new Fontawesome();
|
||||
|
||||
this.background = new Background();
|
||||
|
||||
this.bookmark = new Bookmark();
|
||||
|
||||
this.render = () => {
|
||||
|
||||
this.node.app.classList.add('app');
|
||||
|
||||
this.theme.render();
|
||||
|
||||
this.background.render(this.node.app);
|
||||
|
||||
this.bookmark.render(this.node.app);
|
||||
|
||||
document.querySelector('body').appendChild(this.node.app);
|
||||
|
||||
}
|
||||
|
||||
};
|
|
@ -0,0 +1,45 @@
|
|||
:root {
|
||||
--background-color-hsl:
|
||||
var(--background-color-hsl-h),
|
||||
calc(var(--background-color-hsl-s) * 1%),
|
||||
calc(var(--background-color-hsl-l) * 1%);
|
||||
}
|
||||
|
||||
.background {
|
||||
display: block;
|
||||
position: relative;
|
||||
grid-column: 1 / -1;
|
||||
grid-row: 1 / -1;
|
||||
pointer-events: none;
|
||||
z-index: var(--z-index-background);
|
||||
}
|
||||
|
||||
.background-color,
|
||||
.background-image,
|
||||
.background-gradient {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.background-color {
|
||||
background-color: hsl(var(--background-color-hsl));
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.background-image {
|
||||
background-image: var(--background-image-url);
|
||||
background-attachment: fixed;
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
opacity: var(--background-image-opacity);
|
||||
filter: blur(calc(var(--background-image-blur) * 1px)) grayscale(var(--background-image-grayscale));
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.background-gradient {
|
||||
background: linear-gradient(var(--background-gradient-degree), var(--background-gradient-color));
|
||||
z-index: 3;
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
import { config } from '../../config';
|
||||
import { isValidString } from '../utility/isValidString';
|
||||
import { applyCSSVar } from '../utility/applyCSSVar';
|
||||
|
||||
import './index.css';
|
||||
|
||||
export const Background = function() {
|
||||
|
||||
this.node = {
|
||||
background: document.createElement('div'),
|
||||
color: document.createElement('div'),
|
||||
image: document.createElement('div'),
|
||||
gradient: document.createElement('div')
|
||||
}
|
||||
|
||||
this.style = () => {
|
||||
|
||||
applyCSSVar('--background-color-hsl-h', config.background.color.hsl[0]);
|
||||
applyCSSVar('--background-color-hsl-s', config.background.color.hsl[1]);
|
||||
applyCSSVar('--background-color-hsl-l', config.background.color.hsl[2]);
|
||||
|
||||
if (isValidString(config.background.image.url)) {
|
||||
|
||||
applyCSSVar('--background-image-url', `url(${config.background.image.url})`);
|
||||
|
||||
applyCSSVar('--background-image-opacity', config.background.image.opacity);
|
||||
|
||||
applyCSSVar('--background-image-grayscale', config.background.image.grayscale);
|
||||
|
||||
applyCSSVar('--background-image-blur', config.background.image.blur);
|
||||
|
||||
}
|
||||
|
||||
if (config.background.gradient.color.length > 0) {
|
||||
|
||||
applyCSSVar('--background-gradient-degree', `${config.background.gradient.degree}deg`);
|
||||
|
||||
let gradientColor = '';
|
||||
|
||||
config.background.gradient.color.forEach((gradientColorItem, index) => {
|
||||
|
||||
gradientColor = gradientColor + `hsla(${gradientColorItem.hsla[0]}, ${gradientColorItem.hsla[1]}%, ${gradientColorItem.hsla[2]}%, ${gradientColorItem.hsla[3]}) ${gradientColorItem.position}%`;
|
||||
|
||||
if (index < config.background.gradient.color.length - 1) {
|
||||
|
||||
gradientColor = gradientColor + ', ';
|
||||
|
||||
};
|
||||
|
||||
});
|
||||
|
||||
applyCSSVar('--background-gradient-color', gradientColor);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
this.render = (element) => {
|
||||
|
||||
this.style();
|
||||
|
||||
this.node.background.classList.add('background');
|
||||
|
||||
this.node.color.classList.add('background-color');
|
||||
|
||||
this.node.image.classList.add('background-image');
|
||||
|
||||
this.node.gradient.classList.add('background-gradient');
|
||||
|
||||
this.node.background.appendChild(this.node.color);
|
||||
|
||||
this.node.background.appendChild(this.node.image);
|
||||
|
||||
this.node.background.appendChild(this.node.gradient);
|
||||
|
||||
element.appendChild(this.node.background);
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
// must be loaded first
|
||||
import '../../style/reset/index.css';
|
||||
|
||||
// base styles for all components
|
||||
import '../../style/typography/index.css';
|
||||
import '../../style/zindex/index.css';
|
||||
|
||||
export const Base = function() {}
|
|
@ -0,0 +1,28 @@
|
|||
:root {
|
||||
--font-size: calc(var(--theme-scale) * 0.025vmax);
|
||||
}
|
||||
|
||||
::selection {
|
||||
background-color: rgb(var(--theme-accent));
|
||||
color: hsl(var(--theme-text));
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
background-color: hsl(var(--background-color-hsl));
|
||||
font-size: var(--font-size);
|
||||
line-height: 1.6;
|
||||
font-family: var(--theme-font);
|
||||
font-weight: var(--theme-font-ui-weight);
|
||||
font-style: var(--theme-font-ui-style);
|
||||
color: hsl(var(--theme-text));
|
||||
transition: background-color var(--layout-transition-extra-fast);
|
||||
}
|
||||
|
||||
body {
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
import './index.css';
|
||||
|
||||
export const Body = function() {}
|
|
@ -0,0 +1,22 @@
|
|||
.bookmark {
|
||||
grid-column: 1 / -1;
|
||||
grid-row: 1 / -1;
|
||||
display: grid;
|
||||
grid-template-columns: calc(var(--bookmark-panel-size) * 1vmax) 1fr;
|
||||
align-items: center;
|
||||
z-index: var(--z-index-bookmark);
|
||||
}
|
||||
|
||||
.bookmark-panel {
|
||||
/* margin: 2em 0 2em 2em; */
|
||||
/* border-radius: 1em; */
|
||||
grid-column: 1 / 2;
|
||||
grid-row: 1 / -1;
|
||||
align-self: normal;
|
||||
background-color:
|
||||
hsla(var(--theme-bookmark-background-color-hsla-h),
|
||||
calc(var(--theme-bookmark-background-color-hsla-s) * 1%),
|
||||
calc(var(--theme-bookmark-background-color-hsla-l) * 1%),
|
||||
var(--theme-bookmark-background-color-hsla-a));
|
||||
backdrop-filter: blur(calc(var(--theme-bookmark-group-background-blur) * 1px));
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
import { config } from '../../config';
|
||||
import { BookmarkGroup } from '../BookmarkGroup';
|
||||
import { applyCSSVar } from '../utility/applyCSSVar';
|
||||
|
||||
import './index.css';
|
||||
|
||||
export const Bookmark = function() {
|
||||
|
||||
this.node = {
|
||||
bookmark: document.createElement('div'),
|
||||
group: document.createElement('div'),
|
||||
panel: document.createElement('div'),
|
||||
allGroup: []
|
||||
}
|
||||
|
||||
this.style = () => {
|
||||
|
||||
applyCSSVar('--bookmark-panel-size', config.bookmark.panel.size);
|
||||
|
||||
}
|
||||
|
||||
this.populateGroup = () => {
|
||||
|
||||
config.bookmark.group.set.forEach(groupItem => {
|
||||
|
||||
const bookmarkGroup = new BookmarkGroup(groupItem, this.node.allGroup);
|
||||
|
||||
bookmarkGroup.render();
|
||||
|
||||
this.node.allGroup.push(bookmarkGroup);
|
||||
|
||||
this.node.group.appendChild(bookmarkGroup.group());
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
this.render = (element) => {
|
||||
|
||||
this.style();
|
||||
|
||||
this.populateGroup();
|
||||
|
||||
this.node.bookmark.classList.add('bookmark');
|
||||
|
||||
this.node.group.classList.add('bookmark-group');
|
||||
|
||||
this.node.group.addEventListener('mouseleave', () => {
|
||||
|
||||
config.bookmark.group.set.forEach(bookmarkGroup => {
|
||||
|
||||
bookmarkGroup.active = false;
|
||||
|
||||
});
|
||||
|
||||
this.node.allGroup.forEach(group => {
|
||||
|
||||
group.renderActive();
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
this.node.panel.classList.add('bookmark-panel');
|
||||
|
||||
this.node.bookmark.appendChild(this.node.panel);
|
||||
|
||||
this.node.bookmark.appendChild(this.node.group);
|
||||
|
||||
element.appendChild(this.node.bookmark);
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,125 @@
|
|||
.bookmark-group {
|
||||
grid-column: 1 / -1;
|
||||
grid-row: 1 / -1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 3em;
|
||||
padding: 3em 0;
|
||||
}
|
||||
|
||||
.bookmark-group-item {
|
||||
display: grid;
|
||||
grid-template-columns: calc(var(--bookmark-panel-size) * 1vmax) 1fr;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.bookmark-group-tab {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
text-align: right;
|
||||
color: hsl(var(--bookmark-group-color-primary-hsl-h),
|
||||
calc(var(--bookmark-group-color-primary-hsl-s) * 1%),
|
||||
calc(var(--bookmark-group-color-primary-hsl-l) * 1%));
|
||||
gap: 3em;
|
||||
padding: 0 3em;
|
||||
}
|
||||
|
||||
.bookmark-group-label {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
overflow: hidden;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.bookmark-group-name {
|
||||
font-size: 2em;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: "Ubuntu", sans-serif;
|
||||
font-weight: 100;
|
||||
color: hsl(var(--bookmark-group-color-primary-hsl-h),
|
||||
calc((var(--bookmark-group-color-primary-hsl-s) - 30) * 1%),
|
||||
calc((var(--bookmark-group-color-primary-hsl-l) - 20) * 1%));
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
transition: color var(--theme-transition-fast-ease);
|
||||
}
|
||||
|
||||
.bookmark-group-active .bookmark-group-name {
|
||||
color: hsl(var(--bookmark-group-color-primary-hsl-h),
|
||||
calc(var(--bookmark-group-color-primary-hsl-s) * 1%),
|
||||
calc(var(--bookmark-group-color-primary-hsl-l) * 1%));
|
||||
}
|
||||
|
||||
.bookmark-group-description {
|
||||
font-size: 1em;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: "Ubuntu", sans-serif;
|
||||
font-weight: 500;
|
||||
color: hsl(var(--bookmark-group-color-secondary-hsl-h),
|
||||
calc((var(--bookmark-group-color-secondary-hsl-s) - 30) * 1%),
|
||||
calc((var(--bookmark-group-color-secondary-hsl-l) - 20) * 1%));
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
transition: color var(--theme-transition-fast-ease);
|
||||
}
|
||||
|
||||
.bookmark-group-active .bookmark-group-description {
|
||||
color: hsl(var(--bookmark-group-color-secondary-hsl-h),
|
||||
calc(var(--bookmark-group-color-secondary-hsl-s) * 1%),
|
||||
calc(var(--bookmark-group-color-secondary-hsl-l) * 1%));
|
||||
}
|
||||
|
||||
.bookmark-group-indicator {
|
||||
flex-shrink: 0;
|
||||
position: relative;
|
||||
display: block;
|
||||
width: 0.25em;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.bookmark-group-indicator-top,
|
||||
.bookmark-group-indicator-bottom {
|
||||
width: 100%;
|
||||
height: 0;
|
||||
display: block;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
border-radius: 1em;
|
||||
transform: translateX(-50%);
|
||||
background-color: hsl(var(--bookmark-group-color-secondary-hsl-h),
|
||||
calc((var(--bookmark-group-color-secondary-hsl-s) - 30) * 1%),
|
||||
calc((var(--bookmark-group-color-secondary-hsl-l) - 20) * 1%));
|
||||
transition: height var(--theme-transition-fast-ease), background-color var(--theme-transition-medium-ease);
|
||||
}
|
||||
|
||||
.bookmark-group-indicator-top {
|
||||
bottom: calc(50% + 1.5em);
|
||||
}
|
||||
|
||||
.bookmark-group-indicator-bottom {
|
||||
top: calc(50% + 1.5em);
|
||||
}
|
||||
|
||||
.bookmark-group-item:focus-within .bookmark-group-indicator-top,
|
||||
.bookmark-group-item:focus-within .bookmark-group-indicator-bottom,
|
||||
.bookmark-group-active .bookmark-group-indicator-top,
|
||||
.bookmark-group-active .bookmark-group-indicator-bottom {
|
||||
background-color: hsl(var(--bookmark-group-color-secondary-hsl-h),
|
||||
calc(var(--bookmark-group-color-secondary-hsl-s) * 1%),
|
||||
calc(var(--bookmark-group-color-secondary-hsl-l) * 1%));
|
||||
height: 50%;
|
||||
transition: height var(--theme-transition-medium-bounce) calc((var(--theme-transition-speed-xfast) / 2) * 1s), background-color var(--theme-transition-medium-ease);
|
||||
}
|
||||
|
||||
.bookmark-group-list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 1em;
|
||||
padding: 0 1em;
|
||||
align-items: center;
|
||||
}
|
|
@ -0,0 +1,134 @@
|
|||
import { config } from '../../config';
|
||||
import { BookmarkLink } from '../BookmarkLink';
|
||||
import { BookmarkOpenAll } from '../BookmarkOpenAll';
|
||||
|
||||
import './index.css';
|
||||
|
||||
export const BookmarkGroup = function(bookmarkGroupData, allBookmarkGroup) {
|
||||
|
||||
this.node = {
|
||||
groupItem: document.createElement('div'),
|
||||
tab: document.createElement('div'),
|
||||
label: document.createElement('div'),
|
||||
name: document.createElement('p'),
|
||||
description: document.createElement('p'),
|
||||
indicator: document.createElement('div'),
|
||||
indicatorTop: document.createElement('span'),
|
||||
indicatorBottom: document.createElement('span'),
|
||||
list: document.createElement('div'),
|
||||
openAll: null,
|
||||
allList: []
|
||||
}
|
||||
|
||||
this.style = () => {
|
||||
|
||||
this.node.groupItem.style.setProperty('--bookmark-group-color-primary-hsl-h', bookmarkGroupData.color.primary.hsl[0]);
|
||||
this.node.groupItem.style.setProperty('--bookmark-group-color-primary-hsl-s', bookmarkGroupData.color.primary.hsl[1]);
|
||||
this.node.groupItem.style.setProperty('--bookmark-group-color-primary-hsl-l', bookmarkGroupData.color.primary.hsl[2]);
|
||||
|
||||
this.node.groupItem.style.setProperty('--bookmark-group-color-secondary-hsl-h', bookmarkGroupData.color.secondary.hsl[0]);
|
||||
this.node.groupItem.style.setProperty('--bookmark-group-color-secondary-hsl-s', bookmarkGroupData.color.secondary.hsl[1]);
|
||||
this.node.groupItem.style.setProperty('--bookmark-group-color-secondary-hsl-l', bookmarkGroupData.color.secondary.hsl[2]);
|
||||
|
||||
}
|
||||
|
||||
this.toggleActiveState = () => {
|
||||
|
||||
config.bookmark.group.set.forEach(bookmarkGroup => {
|
||||
|
||||
bookmarkGroup.active = false;
|
||||
|
||||
});
|
||||
|
||||
bookmarkGroupData.active = true;
|
||||
|
||||
|
||||
}
|
||||
|
||||
this.renderActive = () => {
|
||||
|
||||
bookmarkGroupData.active ? this.node.groupItem.classList.add('bookmark-group-active') : this.node.groupItem.classList.remove('bookmark-group-active');
|
||||
|
||||
}
|
||||
|
||||
this.render = () => {
|
||||
|
||||
this.node.groupItem.classList.add('bookmark-group-item');
|
||||
|
||||
this.node.groupItem.addEventListener('mouseenter', () => {
|
||||
|
||||
this.toggleActiveState();
|
||||
|
||||
allBookmarkGroup.forEach(group => {
|
||||
|
||||
group.renderActive();
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
this.node.tab.classList.add('bookmark-group-tab');
|
||||
|
||||
this.node.list.classList.add('bookmark-group-list');
|
||||
|
||||
this.node.tab.href = "#";
|
||||
|
||||
this.renderActive();
|
||||
|
||||
this.style();
|
||||
|
||||
this.node.label.classList.add('bookmark-group-label');
|
||||
|
||||
this.node.name.classList.add('bookmark-group-name');
|
||||
|
||||
this.node.description.classList.add('bookmark-group-description');
|
||||
|
||||
this.node.indicator.classList.add('bookmark-group-indicator');
|
||||
|
||||
this.node.indicatorTop.classList.add('bookmark-group-indicator-top');
|
||||
|
||||
this.node.indicatorBottom.classList.add('bookmark-group-indicator-bottom');
|
||||
|
||||
this.node.name.textContent = bookmarkGroupData.name;
|
||||
|
||||
this.node.description.textContent = bookmarkGroupData.description;
|
||||
|
||||
bookmarkGroupData.list.forEach((listItem, index) => {
|
||||
|
||||
const bookmarkLink = new BookmarkLink(listItem, (bookmarkGroupData.list.length - index));
|
||||
|
||||
bookmarkLink.render();
|
||||
|
||||
this.node.allList.push(bookmarkLink.link());
|
||||
|
||||
this.node.list.appendChild(bookmarkLink.link());
|
||||
|
||||
});
|
||||
|
||||
this.node.openAll = new BookmarkOpenAll(bookmarkGroupData);
|
||||
|
||||
this.node.openAll.render();
|
||||
|
||||
this.node.label.appendChild(this.node.name);
|
||||
|
||||
this.node.label.appendChild(this.node.description);
|
||||
|
||||
this.node.tab.appendChild(this.node.label);
|
||||
|
||||
this.node.indicator.appendChild(this.node.openAll.button());
|
||||
|
||||
this.node.indicator.appendChild(this.node.indicatorTop);
|
||||
|
||||
this.node.indicator.appendChild(this.node.indicatorBottom);
|
||||
|
||||
this.node.tab.appendChild(this.node.indicator);
|
||||
|
||||
this.node.groupItem.appendChild(this.node.tab);
|
||||
|
||||
this.node.groupItem.appendChild(this.node.list);
|
||||
|
||||
}
|
||||
|
||||
this.group = () => this.node.groupItem;
|
||||
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
.bookmark-link:link,
|
||||
.bookmark-link:visited,
|
||||
.bookmark-link:hover,
|
||||
.bookmark-link:focus,
|
||||
.bookmark-link:active {
|
||||
color: hsl(var(--bookmark-group-color-primary-hsl-h),
|
||||
calc(var(--bookmark-group-color-primary-hsl-s) * 1%),
|
||||
calc(var(--bookmark-group-color-primary-hsl-l) * 1%));
|
||||
text-decoration: none;
|
||||
transform: scale(0);
|
||||
transition: transform var(--theme-transition-medium-ease) calc(var(--bookmark-link-delay) * 1s);
|
||||
}
|
||||
|
||||
.bookmark-group-item:focus-within .bookmark-link,
|
||||
.bookmark-group-active .bookmark-link {
|
||||
transform: scale(1);
|
||||
transition: transform var(--theme-transition-xslow-bounce) 0s;
|
||||
}
|
||||
|
||||
.bookmark-group-item:focus-within .bookmark-link:hover,
|
||||
.bookmark-group-item:focus-within .bookmark-link:focus,
|
||||
.bookmark-group-active .bookmark-link:hover,
|
||||
.bookmark-group-active .bookmark-link:focus {
|
||||
transform: scale(1.4);
|
||||
transition: transform var(--theme-transition-fast-bounce);
|
||||
}
|
||||
|
||||
.bookmark-group-item:focus-within .bookmark-link:active,
|
||||
.bookmark-group-active .bookmark-link:active {
|
||||
transform: scale(1);
|
||||
transition: transform var(--theme-transition-fast-bounce);
|
||||
}
|
||||
|
||||
.bookmark-visual {
|
||||
font-size: 2em;
|
||||
min-width: 2em;
|
||||
min-height: 2em;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.bookmark-letter {
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.bookmark-image {
|
||||
max-height: 1em;
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
import { config } from '../../config';
|
||||
|
||||
import './index.css';
|
||||
|
||||
export const BookmarkLink = function(linkData, delay) {
|
||||
|
||||
this.node = {
|
||||
link: document.createElement('a'),
|
||||
visual: document.createElement('div'),
|
||||
letter: document.createElement('div'),
|
||||
icon: document.createElement('span'),
|
||||
image: document.createElement('img')
|
||||
}
|
||||
|
||||
this.render = () => {
|
||||
|
||||
this.node.link.classList.add('bookmark-link');
|
||||
|
||||
this.node.link.style.setProperty('--bookmark-link-delay', (delay / 20));
|
||||
|
||||
this.node.link.href = linkData.url;
|
||||
|
||||
if (config.bookmark.newTab) {
|
||||
|
||||
this.node.link.setAttribute('target', '_blank');
|
||||
|
||||
};
|
||||
|
||||
this.node.visual.classList.add('bookmark-visual');
|
||||
|
||||
this.node.letter.classList.add('bookmark-letter');
|
||||
|
||||
this.node.icon.classList.add('bookmark-icon');
|
||||
|
||||
this.node.image.classList.add('bookmark-image');
|
||||
|
||||
if ('letter' in linkData) {
|
||||
|
||||
this.node.letter.textContent = linkData.letter;
|
||||
|
||||
this.node.visual.appendChild(this.node.letter);
|
||||
|
||||
};
|
||||
|
||||
if ('icon' in linkData) {
|
||||
|
||||
const iconClassList = linkData.icon.split(' ');
|
||||
|
||||
iconClassList.forEach(className => {
|
||||
|
||||
this.node.icon.classList.add(className);
|
||||
|
||||
});
|
||||
|
||||
this.node.visual.appendChild(this.node.icon);
|
||||
|
||||
};
|
||||
|
||||
if ('image' in linkData) {
|
||||
|
||||
this.node.image.src = linkData.image;
|
||||
|
||||
this.node.visual.appendChild(this.node.image);
|
||||
|
||||
};
|
||||
|
||||
this.node.link.appendChild(this.node.visual);
|
||||
|
||||
}
|
||||
|
||||
this.link = () => this.node.link;
|
||||
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
.bookmark-open-all {
|
||||
background-color: transparent;
|
||||
border: 0;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
font-size: 1.5em;
|
||||
color: hsl(var(--bookmark-group-color-secondary-hsl-h),
|
||||
calc(var(--bookmark-group-color-secondary-hsl-s) * 1%),
|
||||
calc(var(--bookmark-group-color-secondary-hsl-l) * 1%));
|
||||
cursor: pointer;
|
||||
transform-origin: center;
|
||||
transform: translate(-50%, -50%) scale(0);
|
||||
transition: color var(--theme-transition-xfast-ease), transform var(--theme-transition-fast-ease) calc(var(--theme-transition-speed-fast) * 1s);
|
||||
}
|
||||
|
||||
.bookmark-group-item:focus-within .bookmark-open-all,
|
||||
.bookmark-group-active .bookmark-open-all {
|
||||
transform: translate(-50%, -50%) scale(1);
|
||||
transition: color var(--theme-transition-xfast-ease), transform var(--theme-transition-xslow-bounce) 0s;
|
||||
}
|
||||
|
||||
.bookmark-group-item:focus-within .bookmark-open-all:hover,
|
||||
.bookmark-group-item:focus-within .bookmark-open-all:focus,
|
||||
.bookmark-group-active .bookmark-open-all:hover,
|
||||
.bookmark-group-active .bookmark-open-all:focus {
|
||||
outline: none;
|
||||
transform: translate(-50%, -50%) scale(1.4);
|
||||
transition: transform var(--theme-transition-fast-bounce);
|
||||
}
|
||||
|
||||
.bookmark-group-item:focus-within .bookmark-open-all:active,
|
||||
.bookmark-group-active .bookmark-open-all:active {
|
||||
transform: translate(-50%, -50%) scale(1);
|
||||
transition: transform var(--theme-transition-fast-bounce);
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
import { config } from '../../config';
|
||||
|
||||
import './index.css';
|
||||
|
||||
export const BookmarkOpenAll = function(bookmarkGroupData) {
|
||||
|
||||
this.node = {
|
||||
button: document.createElement('button'),
|
||||
icon: document.createElement('span')
|
||||
}
|
||||
|
||||
this.open = () => {
|
||||
|
||||
if ('tabs' in chrome) {
|
||||
|
||||
if (config.bookmark.newTab) {
|
||||
|
||||
bookmarkGroupData.list.forEach(item => {
|
||||
chrome.tabs.create({ url: item.url, active: false });
|
||||
});
|
||||
|
||||
} else {
|
||||
|
||||
const first = bookmarkGroupData.list.shift();
|
||||
|
||||
bookmarkGroupData.list.forEach(item => {
|
||||
chrome.tabs.create({ url: item.url, active: false });
|
||||
});
|
||||
|
||||
window.location.href = first.url;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
this.render = () => {
|
||||
|
||||
this.node.button.classList.add('bookmark-open-all');
|
||||
|
||||
this.node.button.addEventListener('click', () => {
|
||||
|
||||
this.open();
|
||||
|
||||
});
|
||||
|
||||
this.node.icon.classList.add('fa-bolt');
|
||||
|
||||
this.node.icon.classList.add('fa-solid');
|
||||
|
||||
this.node.button.appendChild(this.node.icon);
|
||||
|
||||
}
|
||||
|
||||
this.button = () => this.node.button;
|
||||
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
:root {
|
||||
--theme-accent:
|
||||
hsl(var(--theme-accent-hsl-h),
|
||||
calc(var(--theme-accent-hsl-s) * 1%),
|
||||
calc(var(--theme-accent-hsl-l) * 1%));
|
||||
--theme-text:
|
||||
hsl(var(--theme-text-hsl-h),
|
||||
calc(var(--theme-text-hsl-s) * 1%),
|
||||
calc(var(--theme-text-hsl-l) * 1%));
|
||||
}
|
||||
|
||||
:root {
|
||||
--theme-transition-xfast-bounce: calc(var(--theme-transition-speed-xfast) * 1s) cubic-bezier(var(--theme-easing-bounce));
|
||||
--theme-transition-fast-bounce: calc(var(--theme-transition-speed-fast) * 1s) cubic-bezier(var(--theme-easing-bounce));
|
||||
--theme-transition-medium-bounce: calc(var(--theme-transition-speed-medium) * 1s) cubic-bezier(var(--theme-easing-bounce));
|
||||
--theme-transition-slow-bounce: calc(var(--theme-transition-speed-slow) * 1s) cubic-bezier(var(--theme-easing-bounce));
|
||||
--theme-transition-xslow-bounce: calc(var(--theme-transition-speed-xslow) * 1s) cubic-bezier(var(--theme-easing-bounce));
|
||||
}
|
||||
|
||||
:root {
|
||||
--theme-transition-xfast-ease: calc(var(--theme-transition-speed-xfast) * 1s) ease-in-out;
|
||||
--theme-transition-fast-ease: calc(var(--theme-transition-speed-fast) * 1s) ease-in-out;
|
||||
--theme-transition-medium-ease: calc(var(--theme-transition-speed-medium) * 1s) ease-in-out;
|
||||
--theme-transition-slow-ease: calc(var(--theme-transition-speed-slow) * 1s) ease-in-out;
|
||||
--theme-transition-xslow-ease: calc(var(--theme-transition-speed-xslow) * 1s) ease-in-out;
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
import { config } from '../../config';
|
||||
import { applyCSSVar } from '../utility/applyCSSVar';
|
||||
import { trimString } from '../utility/trimString';
|
||||
|
||||
import WebFont from 'webfontloader';
|
||||
|
||||
import './index.css';
|
||||
|
||||
export const Theme = function() {
|
||||
|
||||
this.node = {
|
||||
html: document.querySelector('html')
|
||||
}
|
||||
|
||||
this.style = () => {
|
||||
|
||||
applyCSSVar('--theme-scale', config.theme.scale);
|
||||
applyCSSVar('--theme-scale', config.theme.scale);
|
||||
|
||||
applyCSSVar('--theme-text-hsl-h', config.theme.text.hsl[0]);
|
||||
applyCSSVar('--theme-text-hsl-s', config.theme.text.hsl[1]);
|
||||
applyCSSVar('--theme-text-hsl-l', config.theme.text.hsl[2]);
|
||||
|
||||
applyCSSVar('--theme-accent-hsl-h', config.theme.accent.hsl[0]);
|
||||
applyCSSVar('--theme-accent-hsl-s', config.theme.accent.hsl[1]);
|
||||
applyCSSVar('--theme-accent-hsl-l', config.theme.accent.hsl[2]);
|
||||
|
||||
applyCSSVar('--theme-transition-speed-xfast', (config.theme.transition.speed.xfast / 100));
|
||||
applyCSSVar('--theme-transition-speed-fast', (config.theme.transition.speed.fast / 100));
|
||||
applyCSSVar('--theme-transition-speed-medium', (config.theme.transition.speed.medium / 100));
|
||||
applyCSSVar('--theme-transition-speed-slow', (config.theme.transition.speed.slow / 100));
|
||||
applyCSSVar('--theme-transition-speed-xslow', (config.theme.transition.speed.xslow / 100));
|
||||
|
||||
applyCSSVar('--theme-easing-bounce', `${config.theme.easing.bounce[0]}, ${config.theme.easing.bounce[1]}, ${config.theme.easing.bounce[2]}, ${config.theme.easing.bounce[3]}`);
|
||||
|
||||
applyCSSVar('--theme-font', config.theme.font);
|
||||
|
||||
applyCSSVar('--theme-bookmark-background-color-hsla-h', config.theme.bookmark.background.color.hsla[0]);
|
||||
applyCSSVar('--theme-bookmark-background-color-hsla-s', config.theme.bookmark.background.color.hsla[1]);
|
||||
applyCSSVar('--theme-bookmark-background-color-hsla-l', config.theme.bookmark.background.color.hsla[2]);
|
||||
applyCSSVar('--theme-bookmark-background-color-hsla-a', config.theme.bookmark.background.color.hsla[3]);
|
||||
|
||||
applyCSSVar('--theme-bookmark-group-background-blur', config.theme.bookmark.background.blur);
|
||||
|
||||
}
|
||||
|
||||
this.render = () => {
|
||||
|
||||
this.style();
|
||||
|
||||
WebFont.load({
|
||||
// fontloading: (familyName, fvd) => { console.log('fontloading:', familyName); },
|
||||
google: { families: [trimString(config.theme.font) + ':100,100i,200,200i,300,300i,400,400i,500,500i,600,600i,700,700i,800,800i,900,900i'] }
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,3 @@
|
|||
import './index.css';
|
||||
|
||||
export const Fontawesome = function() {}
|
|
@ -0,0 +1,7 @@
|
|||
export const applyCSSVar = (name, value) => {
|
||||
|
||||
const html = document.querySelector('html');
|
||||
|
||||
html.style.setProperty(name, value);
|
||||
|
||||
};
|
|
@ -0,0 +1,9 @@
|
|||
export const averageColor = function(rgb1, rgb2) {
|
||||
|
||||
return {
|
||||
r: Math.round(Math.sqrt(Math.pow(rgb1.r, 1.75) + Math.pow(rgb2.r, 1.75) / 2)),
|
||||
g: Math.round(Math.sqrt(Math.pow(rgb1.g, 1.75) + Math.pow(rgb2.g, 1.75) / 2)),
|
||||
b: Math.round(Math.sqrt(Math.pow(rgb1.b, 1.75) + Math.pow(rgb2.b, 1.75) / 2))
|
||||
};
|
||||
|
||||
};
|
|
@ -0,0 +1,7 @@
|
|||
export const clearChildNode = (element) => {
|
||||
|
||||
while (element.lastChild) {
|
||||
element.removeChild(element.lastChild);
|
||||
}
|
||||
|
||||
};
|
|
@ -0,0 +1,61 @@
|
|||
export const complexNode = ({
|
||||
tag = 'div',
|
||||
text = false,
|
||||
complexText = false,
|
||||
attr = [],
|
||||
node = []
|
||||
} = {}) => {
|
||||
|
||||
const element = document.createElement(tag);
|
||||
|
||||
if (text) {
|
||||
|
||||
if (complexText) {
|
||||
|
||||
element.innerHTML = text;
|
||||
|
||||
} else {
|
||||
|
||||
let textNode = document.createTextNode(text);
|
||||
|
||||
element.appendChild(textNode);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (attr.length > 0) {
|
||||
attr.forEach((item) => {
|
||||
|
||||
if ('key' in item && 'value' in item) {
|
||||
element.setAttribute(item.key, item.value);
|
||||
} else if ('key' in item) {
|
||||
element.setAttribute(item.key, '');
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
if (node) {
|
||||
if (typeof node != 'string') {
|
||||
if (node.length > 0) {
|
||||
|
||||
node.forEach((item) => {
|
||||
if (item instanceof HTMLElement) {
|
||||
element.appendChild(item);
|
||||
}
|
||||
});
|
||||
|
||||
} else {
|
||||
|
||||
if (node instanceof HTMLElement) {
|
||||
element.appendChild(node);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return element;
|
||||
|
||||
};
|
|
@ -0,0 +1,147 @@
|
|||
export const convertColor = {
|
||||
rgb: {},
|
||||
hsl: {},
|
||||
hex: {}
|
||||
};
|
||||
|
||||
convertColor.rgb.hsl = (rgb) => {
|
||||
var r = rgb.r / 255;
|
||||
var g = rgb.g / 255;
|
||||
var b = rgb.b / 255;
|
||||
var min = Math.min(r, g, b);
|
||||
var max = Math.max(r, g, b);
|
||||
var delta = max - min;
|
||||
var h;
|
||||
var s;
|
||||
|
||||
if (max === min) {
|
||||
h = 0;
|
||||
} else if (r === max) {
|
||||
h = (g - b) / delta;
|
||||
} else if (g === max) {
|
||||
h = 2 + (b - r) / delta;
|
||||
} else if (b === max) {
|
||||
h = 4 + (r - g) / delta;
|
||||
}
|
||||
|
||||
h = Math.min(h * 60, 360);
|
||||
|
||||
if (h < 0) {
|
||||
h += 360;
|
||||
}
|
||||
|
||||
var l = (min + max) / 2;
|
||||
|
||||
if (max === min) {
|
||||
s = 0;
|
||||
} else if (l <= 0.5) {
|
||||
s = delta / (max + min);
|
||||
} else {
|
||||
s = delta / (2 - max - min);
|
||||
}
|
||||
|
||||
return {
|
||||
h: Math.round(h),
|
||||
s: Math.round(s * 100),
|
||||
l: Math.round(l * 100)
|
||||
};
|
||||
};
|
||||
|
||||
convertColor.rgb.hex = (args) => {
|
||||
var integer = ((Math.round(args.r) & 0xFF) << 16) +
|
||||
((Math.round(args.g) & 0xFF) << 8) +
|
||||
(Math.round(args.b) & 0xFF);
|
||||
|
||||
var string = integer.toString(16);
|
||||
|
||||
return '#' + '000000'.substring(string.length) + string;
|
||||
};
|
||||
|
||||
convertColor.hsl.rgb = (hsl) => {
|
||||
var h = hsl.h / 360;
|
||||
var s = hsl.s / 100;
|
||||
var l = hsl.l / 100;
|
||||
var t2;
|
||||
var t3;
|
||||
var val;
|
||||
|
||||
if (s === 0) {
|
||||
val = l * 255;
|
||||
return {
|
||||
r: Math.round(val),
|
||||
g: Math.round(val),
|
||||
b: Math.round(val)
|
||||
};
|
||||
}
|
||||
|
||||
if (l < 0.5) {
|
||||
t2 = l * (1 + s);
|
||||
} else {
|
||||
t2 = l + s - l * s;
|
||||
}
|
||||
|
||||
var t1 = 2 * l - t2;
|
||||
|
||||
var rgb = [0, 0, 0];
|
||||
|
||||
for (var i = 0; i < 3; i++) {
|
||||
t3 = h + 1 / 3 * -(i - 1);
|
||||
|
||||
if (t3 < 0) {
|
||||
t3++;
|
||||
}
|
||||
|
||||
if (t3 > 1) {
|
||||
t3--;
|
||||
}
|
||||
|
||||
if (6 * t3 < 1) {
|
||||
val = t1 + (t2 - t1) * 6 * t3;
|
||||
} else if (2 * t3 < 1) {
|
||||
val = t2;
|
||||
} else if (3 * t3 < 2) {
|
||||
val = t1 + (t2 - t1) * (2 / 3 - t3) * 6;
|
||||
} else {
|
||||
val = t1;
|
||||
}
|
||||
|
||||
rgb[i] = val * 255;
|
||||
}
|
||||
|
||||
return {
|
||||
r: Math.round(rgb[0]),
|
||||
g: Math.round(rgb[1]),
|
||||
b: Math.round(rgb[2])
|
||||
};
|
||||
};
|
||||
|
||||
convertColor.hex.rgb = (args) => {
|
||||
var match = args.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i);
|
||||
|
||||
if (!match) {
|
||||
return {
|
||||
r: 0,
|
||||
g: 0,
|
||||
b: 0
|
||||
};
|
||||
}
|
||||
|
||||
var colorString = match[0];
|
||||
|
||||
if (match[0].length === 3) {
|
||||
colorString = colorString.split('').map((char) => {
|
||||
return char + char;
|
||||
}).join('');
|
||||
}
|
||||
|
||||
var integer = parseInt(colorString, 16);
|
||||
var r = (integer >> 16) & 0xFF;
|
||||
var g = (integer >> 8) & 0xFF;
|
||||
var b = integer & 0xFF;
|
||||
|
||||
return {
|
||||
r: r,
|
||||
g: g,
|
||||
b: b
|
||||
};
|
||||
};
|
|
@ -0,0 +1,21 @@
|
|||
export const dateTime = () => {
|
||||
|
||||
const date = new Date();
|
||||
|
||||
const month = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
|
||||
|
||||
return {
|
||||
// string: date.constructor(),
|
||||
// time: date.getTime(),
|
||||
date: date.getDate(),
|
||||
day: date.getDay(),
|
||||
year: date.getFullYear(),
|
||||
hours: date.getHours(),
|
||||
milliseconds: date.getMilliseconds(),
|
||||
minutes: date.getMinutes(),
|
||||
month: date.getMonth(),
|
||||
monthString: month[date.getMonth()],
|
||||
seconds: date.getSeconds()
|
||||
};
|
||||
|
||||
};
|
|
@ -0,0 +1,48 @@
|
|||
import { makePath } from './makePath.js';
|
||||
|
||||
export const get = ({
|
||||
object = null,
|
||||
path = null
|
||||
} = {}) => {
|
||||
|
||||
const address = makePath(path);
|
||||
|
||||
const getValue = () => {
|
||||
|
||||
while (address.length > 1) {
|
||||
|
||||
// shift off and store the first key
|
||||
let currentKey = address.shift();
|
||||
|
||||
// if the key is not found make a new object
|
||||
if (!(currentKey in object)) {
|
||||
// make an empty object in the current object level
|
||||
if (isNaN(currentKey)) {
|
||||
object[currentKey] = {};
|
||||
} else {
|
||||
object[currentKey] = [];
|
||||
}
|
||||
}
|
||||
|
||||
// drill down the object with the first key
|
||||
object = object[currentKey];
|
||||
|
||||
}
|
||||
|
||||
let finalKey = address.shift();
|
||||
|
||||
if (!(finalKey in object)) {
|
||||
return '';
|
||||
} else {
|
||||
return object[finalKey];
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
if (object != null && path != null) {
|
||||
return getValue();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
};
|
|
@ -0,0 +1,31 @@
|
|||
export const isElementVisible = (element) => {
|
||||
|
||||
var rect = element.getBoundingClientRect();
|
||||
|
||||
const vWidth = window.innerWidth;
|
||||
|
||||
const vHeight = window.innerHeight;
|
||||
|
||||
const efp = (x, y) => {
|
||||
return document.elementFromPoint(x, y);
|
||||
};
|
||||
|
||||
// Return false if element is not in the viewport
|
||||
if (
|
||||
rect.right < 0 ||
|
||||
rect.bottom < 0 ||
|
||||
rect.left > vWidth ||
|
||||
rect.top > vHeight
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Return true if any of the element four corners are visible
|
||||
return (
|
||||
element.contains(efp(rect.left, rect.top)) ||
|
||||
element.contains(efp(rect.right, rect.top)) ||
|
||||
element.contains(efp(rect.right, rect.bottom)) ||
|
||||
element.contains(efp(rect.left, rect.bottom))
|
||||
);
|
||||
|
||||
};
|
|
@ -0,0 +1,11 @@
|
|||
export const isJson = (string) => {
|
||||
|
||||
try {
|
||||
JSON.parse(string);
|
||||
} catch (error) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
};
|
|
@ -0,0 +1,12 @@
|
|||
export const isValidString = (value) => {
|
||||
let result = false;
|
||||
|
||||
if (typeof value == 'string') {
|
||||
value = value.trim().replace(/\s/g, '');
|
||||
if (value != '') {
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
|
@ -0,0 +1,34 @@
|
|||
export const makePath = (string) => {
|
||||
|
||||
if (string) {
|
||||
|
||||
let array;
|
||||
|
||||
if (string.indexOf('[') != -1 && string.indexOf(']') != -1) {
|
||||
|
||||
array = string.split('.').join(',').split('[').join(',').split(']').join(',').split(',');
|
||||
|
||||
for (var i = 0; i < array.length; i++) {
|
||||
if (array[i] == '') {
|
||||
array.splice(i, 1);
|
||||
}
|
||||
if (!isNaN(parseInt(array[i], 10))) {
|
||||
array[i] = parseInt(array[i], 10);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
array = string.split('.');
|
||||
|
||||
}
|
||||
|
||||
return array;
|
||||
|
||||
} else {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
};
|
|
@ -0,0 +1,25 @@
|
|||
export const minMax = ({
|
||||
min = 0,
|
||||
max = 0,
|
||||
value = 0
|
||||
} = {}) => {
|
||||
|
||||
if (value > max) {
|
||||
|
||||
return max;
|
||||
|
||||
} else if (value < min) {
|
||||
|
||||
return min;
|
||||
|
||||
} else if (isNaN(value)) {
|
||||
|
||||
return min;
|
||||
|
||||
} else {
|
||||
|
||||
return value;
|
||||
|
||||
}
|
||||
|
||||
};
|
|
@ -0,0 +1,110 @@
|
|||
export const node = (string, node) => {
|
||||
|
||||
// set element
|
||||
let tag;
|
||||
|
||||
if (string.indexOf('|') > 0) {
|
||||
tag = string.slice(0, string.indexOf('|'));
|
||||
} else {
|
||||
tag = string;
|
||||
}
|
||||
|
||||
let text = false;
|
||||
|
||||
if (tag.indexOf(':') > 0) {
|
||||
// regex
|
||||
// find all : and split
|
||||
// ignore all \:
|
||||
let pair = tag.split(/:(?!.*:\\)/);
|
||||
tag = pair[0];
|
||||
// replace \: with :
|
||||
text = pair[1].replace('\\', ':');
|
||||
}
|
||||
|
||||
let element = document.createElement(tag);
|
||||
|
||||
if (text && text != '') {
|
||||
element.innerHTML = text;
|
||||
}
|
||||
|
||||
let attributes = string.slice(string.indexOf('|') + 1, string.length).split(',');
|
||||
|
||||
// set attributes
|
||||
if (string.indexOf('|') > 0 && string.indexOf('|') < string.length - 1) {
|
||||
|
||||
attributes.forEach((item, i) => {
|
||||
if (item.indexOf(':') > 0) {
|
||||
// if key and value
|
||||
var pair = item.substring(0, item.indexOf(':')) + ',' + item.substring(item.indexOf(':') + 1, item.length);
|
||||
pair = pair.split(',');
|
||||
attributes[i] = {
|
||||
key: pair[0],
|
||||
value: pair[1]
|
||||
};
|
||||
} else {
|
||||
// if key only
|
||||
attributes[i] = {
|
||||
key: item,
|
||||
value: undefined
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
attributes.forEach((item) => {
|
||||
if ('key' in item && item.key != undefined && 'value' in item && item.value != undefined) {
|
||||
element.setAttribute(item.key, item.value);
|
||||
} else if ('key' in item && item.key != undefined) {
|
||||
element.setAttribute(item.key, '');
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
if (node) {
|
||||
|
||||
if (typeof node != 'string') {
|
||||
|
||||
if (node.length > 0) {
|
||||
|
||||
node.forEach((item) => {
|
||||
|
||||
if (item instanceof HTMLElement) {
|
||||
|
||||
element.appendChild(item);
|
||||
|
||||
} else {
|
||||
|
||||
let div = document.createElement('div');
|
||||
|
||||
div.innerHTML = item;
|
||||
|
||||
element.appendChild(div.firstChild);
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
} else {
|
||||
|
||||
if (node instanceof HTMLElement) {
|
||||
|
||||
element.appendChild(node);
|
||||
|
||||
} else {
|
||||
|
||||
let div = document.createElement('div');
|
||||
|
||||
div.innerHTML = node;
|
||||
|
||||
element.appendChild(div.firstChild);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return element;
|
||||
};
|
|
@ -0,0 +1,21 @@
|
|||
export const ordinalNumber = (number) => {
|
||||
|
||||
var j = number % 10;
|
||||
|
||||
var k = number % 100;
|
||||
|
||||
if (j == 1 && k != 11) {
|
||||
return number + 'st';
|
||||
}
|
||||
|
||||
if (j == 2 && k != 12) {
|
||||
return number + 'nd';
|
||||
}
|
||||
|
||||
if (j == 3 && k != 13) {
|
||||
return number + 'rd';
|
||||
}
|
||||
|
||||
return number + 'th';
|
||||
|
||||
};
|
|
@ -0,0 +1,44 @@
|
|||
export const ordinalWord = (word) => {
|
||||
|
||||
const endsWithDoubleZeroPattern = /(hundred|thousand|(m|b|tr|quadr)illion)$/;
|
||||
|
||||
const endsWithTeenPattern = /teen$/;
|
||||
|
||||
const endsWithYPattern = /y$/;
|
||||
|
||||
const endsWithZeroThroughTwelvePattern = /(Zero|One|Two|Three|Four|Five|Six|Seven|Eight|Nine|Ten|Eleven|Twelve)$/;
|
||||
|
||||
const ordinalLessThanThirteen = {
|
||||
Zero: 'Zeroth',
|
||||
One: 'First',
|
||||
Two: 'Second',
|
||||
Three: 'Third',
|
||||
Four: 'Fourth',
|
||||
Five: 'Fifth',
|
||||
Six: 'Sixth',
|
||||
Seven: 'Seventh',
|
||||
Eight: 'Eighth',
|
||||
Nine: 'Ninth',
|
||||
Ten: 'Tenth',
|
||||
Eleven: 'Eleventh',
|
||||
Twelve: 'Twelfth'
|
||||
};
|
||||
|
||||
const replaceWithOrdinalVariant = (match, numberWord) => {
|
||||
return ordinalLessThanThirteen[numberWord];
|
||||
};
|
||||
|
||||
// Ends with *00 (100, 1000, etc.) or *teen (13, 14, 15, 16, 17, 18, 19)
|
||||
if (endsWithDoubleZeroPattern.test(word) || endsWithTeenPattern.test(word)) {
|
||||
return word + 'th';
|
||||
// Ends with *y (20, 30, 40, 50, 60, 70, 80, 90)
|
||||
} else if (endsWithYPattern.test(word)) {
|
||||
return word.replace(endsWithYPattern, 'ieth');
|
||||
// Ends with one through twelve
|
||||
} else if (endsWithZeroThroughTwelvePattern.test(word)) {
|
||||
return word.replace(endsWithZeroThroughTwelvePattern, replaceWithOrdinalVariant);
|
||||
}
|
||||
|
||||
return word;
|
||||
|
||||
};
|
|
@ -0,0 +1,5 @@
|
|||
export const randomNumber = (min, max) => {
|
||||
|
||||
return Math.floor(Math.random() * (max - min + 1) + min);
|
||||
|
||||
};
|
|
@ -0,0 +1,162 @@
|
|||
export const randomString = ({
|
||||
letter = false,
|
||||
adjectivesCount = false
|
||||
} = {}) => {
|
||||
|
||||
const alphabet = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'];
|
||||
|
||||
const adjectives = {
|
||||
a: ['Aback', 'Abaft', 'Abandoned', 'Abashed', 'Aberrant', 'Abhorrent', 'Abiding', 'Abject', 'Ablaze', 'Able', 'Abnormal', 'Aboriginal', 'Abortive', 'Abounding', 'Abrasive', 'Abrupt', 'Absent', 'Absorbed', 'Absorbing', 'Abstracted', 'Absurd', 'Abundant', 'Abusive', 'Acceptable', 'Accessible', 'Accidental', 'Accurate', 'Acid', 'Acidic', 'Acoustic', 'Acrid', 'Adamant', 'Adaptable', 'Adhesive', 'Adjoining', 'Adorable', 'Adventurous', 'Afraid', 'Aggressive', 'Agonizing', 'Agreeable', 'Ahead', 'Ajar', 'Alert', 'Alike', 'Alive', 'Alleged', 'Alluring', 'Aloof', 'Amazing', 'Ambiguous', 'Ambitious', 'Amuck', 'Amused', 'Amusing', 'Ancient', 'Angry', 'Animated', 'Annoyed', 'Annoying', 'Anxious', 'Apathetic', 'Aquatic', 'Aromatic', 'Arrogant', 'Ashamed', 'Aspiring', 'Assorted', 'Astonishing', 'Attractive', 'Auspicious', 'Automatic', 'Available', 'Average', 'Aware', 'Awesome', 'Axiomatic'],
|
||||
b: ['Bad', 'Barbarous', 'Bashful', 'Bawdy', 'Beautiful', 'Befitting', 'Belligerent', 'Beneficial', 'Bent', 'Berserk', 'Bewildered', 'Big', 'Billowy', 'Bitter', 'Bizarre', 'Black', 'Bloody', 'Blue', 'Blushing', 'Boiling', 'Boorish', 'Bored', 'Boring', 'Bouncy', 'Boundless', 'Brainy', 'Brash', 'Brave', 'Brawny', 'Breakable', 'Breezy', 'Brief', 'Bright', 'Broad', 'Broken', 'Brown', 'Bumpy', 'Burly', 'Bustling', 'Busy'],
|
||||
c: ['Cagey', 'Calculating', 'Callous', 'Calm', 'Capable', 'Capricious', 'Careful', 'Careless', 'Caring', 'Cautious', 'Ceaseless', 'Certain', 'Changeable', 'Charming', 'Cheap', 'Cheerful', 'Chemical', 'Chief', 'Childlike', 'Chilly', 'Chivalrous', 'Chubby', 'Chunky', 'Clammy', 'Classy', 'Clean', 'Clear', 'Clever', 'Cloistered', 'Cloudy', 'Closed', 'Clumsy', 'Cluttered', 'Coherent', 'Cold', 'Colorful', 'Colossal', 'Combative', 'Comfortable', 'Common', 'Complete', 'Complex', 'Concerned', 'Condemned', 'Confused', 'Conscious', 'Cooing', 'Cool', 'Cooperative', 'Coordinated', 'Courageous', 'Cowardly', 'Crabby', 'Craven', 'Crazy', 'Creepy', 'Crooked', 'Crowded', 'Cruel', 'Cuddly', 'Cultured', 'Cumbersome', 'Curious', 'Curly', 'Curved', 'Curvy', 'Cut', 'Cute', 'Cynical'],
|
||||
d: ['Daffy', 'Daily', 'Damaged', 'Damaging', 'Damp', 'Dangerous', 'Dapper', 'Dark', 'Dashing', 'Dazzling', 'Deadpan', 'Deafening', 'Dear', 'Debonair', 'Decisive', 'Decorous', 'Deep', 'Deeply', 'Defeated', 'Defective', 'Defiant', 'Delicate', 'Delicious', 'Delightful', 'Demonic', 'Delirious', 'Dependent', 'Depressed', 'Deranged', 'Descriptive', 'Deserted', 'Detailed', 'Determined', 'Devilish', 'Didactic', 'Different', 'Difficult', 'Diligent', 'Direful', 'Dirty', 'Disagreeable', 'Disastrous', 'Discreet', 'Disgusted', 'Disgusting', 'Disillusioned', 'Dispensable', 'Distinct', 'Disturbed', 'Divergent', 'Dizzy', 'Domineering', 'Doubtful', 'Drab', 'Draconian', 'Dramatic', 'Dreary', 'Drunk', 'Dry', 'Dull', 'Dusty', 'Dynamic', 'Dysfunctional'],
|
||||
e: ['Eager', 'Early', 'Earsplitting', 'Earthy', 'Easy', 'Eatable', 'Economic', 'Educated', 'Efficacious', 'Efficient', 'Elastic', 'Elated', 'Elderly', 'Electric', 'Elegant', 'Elfin', 'Elite', 'Embarrassed', 'Eminent', 'Empty', 'Enchanted', 'Enchanting', 'Encouraging', 'Endurable', 'Energetic', 'Enormous', 'Entertaining', 'Enthusiastic', 'Envious', 'Equable', 'Equal', 'Erratic', 'Ethereal', 'Evanescent', 'Evasive', 'Even', 'Excellent', 'Excited', 'Exciting', 'Exclusive', 'Exotic', 'Expensive', 'Exuberant', 'Exultant'],
|
||||
f: ['Fabulous', 'Faded', 'Faint', 'Fair', 'Faithful', 'Fallacious', 'False', 'Familiar', 'Famous', 'Fanatical', 'Fancy', 'Fantastic', 'Far', 'Fascinated', 'Fast', 'Fat', 'Faulty', 'Fearful', 'Fearless', 'Feeble', 'Feigned', 'Fertile', 'Festive', 'Few', 'Fierce', 'Filthy', 'Fine', 'Finicky', 'First', 'Fixed', 'Flagrant', 'Flaky', 'Flashy', 'Flat', 'Flawless', 'Flimsy', 'Flippant', 'Flowery', 'Fluffy', 'Fluttering', 'Foamy', 'Foolish', 'Foregoing', 'Forgetful', 'Fortunate', 'Frail', 'Fragile', 'Frantic', 'Free', 'Freezing', 'Frequent', 'Fresh', 'Fretful', 'Friendly', 'Frightened', 'Frightening', 'Full', 'Fumbling', 'Functional', 'Funny', 'Furry', 'Furtive', 'Future', 'Futuristic', 'Fuzzy'],
|
||||
g: ['Gabby', 'Gainful', 'Gamy', 'Garrulous', 'Gaudy', 'General', 'Gentle', 'Giant', 'Giddy', 'Gifted', 'Gigantic', 'Glamorous', 'Gleaming', 'Glib', 'Glistening', 'Glorious', 'Glossy', 'Good', 'Goofy', 'Gorgeous', 'Graceful', 'Grandiose', 'Grateful', 'Gratis', 'Gray', 'Greasy', 'Great', 'Greedy', 'Green', 'Grey', 'Grieving', 'Groovy', 'Grotesque', 'Grouchy', 'Grubby', 'Gruesome', 'Grumpy', 'Guarded', 'Guiltless', 'Gullible', 'Gusty', 'Guttural'],
|
||||
h: ['Habitual', 'Half', 'Hallowed', 'Halting', 'Handsome', 'Handy', 'Hapless', 'Happy', 'Hard', 'Harmonious', 'Harsh', 'Hateful', 'Heady', 'Healthy', 'Heartbreaking', 'Heavenly', 'Heavy', 'Hellish', 'Helpful', 'Helpless', 'Hesitant', 'Hideous', 'High', 'Highfalutin', 'Hilarious', 'Hissing', 'Historical', 'Holistic', 'Hollow', 'Homeless', 'Homely', 'Honorable', 'Horrible', 'Hospitable', 'Hot', 'Huge', 'Hulking', 'Humdrum', 'Humorous', 'Hungry', 'Hurried', 'Hurt', 'Hushed', 'Husky', 'Hypnotic', 'Hysterical'],
|
||||
i: ['Icky', 'Icy', 'Idiotic', 'Ignorant', 'Ill', 'Illegal', 'Illustrious', 'Imaginary', 'Immense', 'Imminent', 'Impartial', 'Imperfect', 'Impolite', 'Important', 'Imported', 'Impossible', 'Incandescent', 'Incompetent', 'Inconclusive', 'Industrious', 'Incredible', 'Inexpensive', 'Infamous', 'Innate', 'Innocent', 'Inquisitive', 'Insidious', 'Instinctive', 'Intelligent', 'Interesting', 'Internal', 'Invincible', 'Irate', 'Irritating', 'Itchy'],
|
||||
j: ['Jaded', 'Jagged', 'Jazzy', 'Jealous', 'Jesting', 'Jinxed', 'Jittery', 'Jobless', 'Jolly', 'Joyous', 'Judicious', 'Juicy', 'Jumbled', 'Jumpy', 'Juvenile'],
|
||||
k: ['Keen', 'Kind', 'Kindhearted', 'Kindly', 'Knotty', 'Knowing', 'Knowledgeable', 'Known'],
|
||||
l: ['Labored', 'Lackadaisical', 'Lacking', 'Lame', 'Lamentable', 'Languid', 'Large', 'Last', 'Late', 'Laughable', 'Lavish', 'Lazy', 'Lean', 'Learned', 'Left', 'Legal', 'Lethal', 'Level', 'Lewd', 'Light', 'Like', 'Likeable', 'Limping', 'Literate', 'Little', 'Lively', 'Living', 'Lonely', 'Long', 'Longing', 'Loose', 'Lopsided', 'Loud', 'Loutish', 'Lovely', 'Loving', 'Low', 'Lowly', 'Lucky', 'Ludicrous', 'Lumpy', 'Lush', 'Luxuriant', 'Lying', 'Lyrical'],
|
||||
m: ['Macabre', 'Macho', 'Maddening', 'Madly', 'Magenta', 'Magical', 'Magnificent', 'Majestic', 'Makeshift', 'Malicious', 'Mammoth', 'Maniacal', 'Many', 'Marked', 'Massive', 'Married', 'Marvelous', 'Material', 'Materialistic', 'Mature', 'Mean', 'Measly', 'Meaty', 'Medical', 'Meek', 'Mellow', 'Melodic', 'Melted', 'Merciful', 'Mere', 'Messy', 'Mighty', 'Military', 'Milky', 'Mindless', 'Miniature', 'Minor', 'Miscreant', 'Misty', 'Mixed', 'Moaning', 'Modern', 'Moldy', 'Momentous', 'Motionless', 'Mountainous', 'Muddled', 'Mundane', 'Murky', 'Mushy', 'Mute', 'Mysterious'],
|
||||
n: ['Naive', 'Nappy', 'Narrow', 'Nasty', 'Natural', 'Naughty', 'Nauseating', 'Near', 'Neat', 'Nebulous', 'Necessary', 'Needless', 'Needy', 'Neighborly', 'Nervous', 'New', 'Next', 'Nice', 'Nifty', 'Nimble', 'Nippy', 'Noiseless', 'Noisy', 'Nonchalant', 'Nondescript', 'Nonstop', 'Normal', 'Nostalgic', 'Nosy', 'Noxious', 'Numberless', 'Numerous', 'Nutritious', 'Nutty'],
|
||||
o: ['Oafish', 'Obedient', 'Obeisant', 'Obese', 'Obnoxious', 'Obscene', 'Obsequious', 'Observant', 'Obsolete', 'Obtainable', 'Oceanic', 'Odd', 'Offbeat', 'Old', 'Omniscient', 'Onerous', 'Open', 'Opposite', 'Optimal', 'Orange', 'Ordinary', 'Organic', 'Ossified', 'Outgoing', 'Outrageous', 'Outstanding', 'Oval', 'Overconfident', 'Overjoyed', 'Overrated', 'Overt', 'Overwrought'],
|
||||
p: ['Painful', 'Painstaking', 'Pale', 'Paltry', 'Panicky', 'Panoramic', 'Parallel', 'Parched', 'Parsimonious', 'Past', 'Pastoral', 'Pathetic', 'Peaceful', 'Penitent', 'Perfect', 'Periodic', 'Permissible', 'Perpetual', 'Petite', 'Phobic', 'Physical', 'Picayune', 'Pink', 'Piquant', 'Placid', 'Plain', 'Plant', 'Plastic', 'Plausible', 'Pleasant', 'Plucky', 'Pointless', 'Poised', 'Polite', 'Political', 'Poor', 'Possessive', 'Possible', 'Powerful', 'Precious', 'Premium', 'Present', 'Pretty', 'Previous', 'Pricey', 'Prickly', 'Private', 'Probable', 'Productive', 'Profuse', 'Protective', 'Proud', 'Psychedelic', 'Psychotic', 'Public', 'Puffy', 'Pumped', 'Puny', 'Purple', 'Purring', 'Pushy', 'Puzzled', 'Puzzling'],
|
||||
q: ['Quaint', 'Quality', 'Quarrelsome', 'Questionable', 'Questioning', 'Quick', 'Quiet', 'Quirky', 'Quixotic', 'Quizzical'],
|
||||
r: ['Rabid', 'Ragged', 'Rainy', 'Rambunctious', 'Rampant', 'Rapid', 'Rare', 'Raspy', 'Ratty', 'Ready', 'Real', 'Rebel', 'Receptive', 'Recondite', 'Red', 'Redundant', 'Reflective', 'Regular', 'Relieved', 'Remarkable', 'Reminiscent', 'Repulsive', 'Resolute', 'Resonant', 'Responsible', 'Rhetorical', 'Rich', 'Right', 'Righteous', 'Rightful', 'Rigid', 'Ripe', 'Ritzy', 'Roasted', 'Robust', 'Romantic', 'Roomy', 'Rotten', 'Rough', 'Round', 'Royal', 'Ruddy', 'Rude', 'Rural', 'Rustic', 'Ruthless'],
|
||||
s: ['Sable', 'Sad', 'Safe', 'Salty', 'Same', 'Sassy', 'Satisfying', 'Savory', 'Scandalous', 'Scarce', 'Scared', 'Scary', 'Scattered', 'Scientific', 'Scintillating', 'Scrawny', 'Screeching', 'Second', 'Secret', 'Secretive', 'Sedate', 'Seemly', 'Selective', 'Selfish', 'Separate', 'Serious', 'Shaggy', 'Shaky', 'Shallow', 'Sharp', 'Shiny', 'Shivering', 'Shocking', 'Short', 'Shrill', 'Shut', 'Shy', 'Sick', 'Silent', 'Silky', 'Silly', 'Simple', 'Simplistic', 'Sincere', 'Skillful', 'Skinny', 'Sleepy', 'Slim', 'Slimy', 'Slippery', 'Sloppy', 'Slow', 'Small', 'Smart', 'Smelly', 'Smiling', 'Smoggy', 'Smooth', 'Sneaky', 'Snobbish', 'Snotty', 'Soft', 'Soggy', 'Solid', 'Somber', 'Sophisticated', 'Sordid', 'Sore', 'Sour', 'Sparkling', 'Special', 'Spectacular', 'Spicy', 'Spiffy', 'Spiky', 'Spiritual', 'Spiteful', 'Splendid', 'Spooky', 'Spotless', 'Spotted', 'Spotty', 'Spurious', 'Squalid', 'Square', 'Squealing', 'Squeamish', 'Staking', 'Stale', 'Standing', 'Statuesque', 'Steadfast', 'Steady', 'Steep', 'Stereotyped', 'Sticky', 'Stiff', 'Stimulating', 'Stingy', 'Stormy', 'Straight', 'Strange', 'Striped', 'Strong', 'Stupendous', 'Sturdy', 'Subdued', 'Subsequent', 'Substantial', 'Successful', 'Succinct', 'Sudden', 'Sulky', 'Super', 'Superb', 'Superficial', 'Supreme', 'Swanky', 'Sweet', 'Sweltering', 'Swift', 'Symptomatic', 'Synonymous'],
|
||||
t: ['Taboo', 'Tacit', 'Tacky', 'Talented', 'Tall', 'Tame', 'Tan', 'Tangible', 'Tangy', 'Tart', 'Tasteful', 'Tasteless', 'Tasty', 'Tawdry', 'Tearful', 'Tedious', 'Teeny', 'Telling', 'Temporary', 'Ten', 'Tender', 'Tense', 'Tenuous', 'Terrific', 'Tested', 'Testy', 'Thankful', 'Therapeutic', 'Thick', 'Thin', 'Thinkable', 'Third', 'Thirsty', 'Thoughtful', 'Thoughtless', 'Threatening', 'Thundering', 'Tidy', 'Tight', 'Tightfisted', 'Tiny', 'Tired', 'Tiresome', 'Toothsome', 'Torpid', 'Tough', 'Towering', 'Tranquil', 'Trashy', 'Tremendous', 'Tricky', 'Trite', 'Troubled', 'Truculent', 'True', 'Truthful', 'Typical'],
|
||||
u: ['Ubiquitous', 'Ultra', 'Unable', 'Unaccountable', 'Unadvised', 'Unarmed', 'Unbecoming', 'Unbiased', 'Uncovered', 'Understood', 'Undesirable', 'Unequal', 'Unequaled', 'Uneven', 'Unhealthy', 'Uninterested', 'Unique', 'Unkempt', 'Unknown', 'Unnatural', 'Unruly', 'Unsightly', 'Unsuitable', 'Untidy', 'Unused', 'Unusual', 'Unwieldy', 'Unwritten', 'Upbeat', 'Uppity', 'Upset', 'Uptight', 'Used', 'Useful', 'Useless', 'Utopian'],
|
||||
v: ['Vacuous', 'Vagabond', 'Vague', 'Valuable', 'Various', 'Vast', 'Vengeful', 'Venomous', 'Verdant', 'Versed', 'Victorious', 'Vigorous', 'Violent', 'Violet', 'Vivacious', 'Voiceless', 'Volatile', 'Voracious', 'Vulgar'],
|
||||
w: ['Wacky', 'Waggish', 'Waiting', 'Wakeful', 'Wandering', 'Wanting', 'Warlike', 'Warm', 'Wary', 'Wasteful', 'Watery', 'Weak', 'Wealthy', 'Weary', 'Wet', 'Whimsical', 'Whispering', 'White', 'Whole', 'Wholesale', 'Wicked', 'Wide', 'Wiggly', 'Wild', 'Willing', 'Windy', 'Wiry', 'Wise', 'Wistful', 'Witty', 'Woebegone', 'Wonderful', 'Wooden', 'Woozy', 'Workable', 'Worried', 'Worthless', 'Wrathful', 'Wretched', 'Wrong', 'Wry'],
|
||||
x: ['Xenial', 'Xenodochial', 'Xenophobic'],
|
||||
y: ['Yellow', 'Yielding', 'Young', 'Youthful', 'Yummy'],
|
||||
z: ['Zany', 'Zealous', 'Zesty', 'Zippy', 'Zombiesque', 'Zombie', 'Zonked']
|
||||
};
|
||||
|
||||
const animals = {
|
||||
a: ['Aardvark', 'Albatross', 'Alligator', 'Alpaca', 'Ant', 'Anteater', 'Antelope', 'Ape', 'Armadillo'],
|
||||
b: ['Baboon', 'Badger', 'Barracuda', 'Bat', 'Bear', 'Beaver', 'Bee', 'Bison', 'Boar', 'Buffalo', 'Butterfly'],
|
||||
c: ['Camel', 'Capybara', 'Caribou', 'Cassowary', 'Cat', 'Caterpillar', 'Cattle', 'Chamois', 'Cheetah', 'Chicken', 'Chimpanzee', 'Chinchilla', 'Chough', 'Clam', 'Cobra', 'Cockroach', 'Cod', 'Cormorant', 'Coyote', 'Crab', 'Crane', 'Crocodile', 'Crow', 'Curlew'],
|
||||
d: ['Deer', 'Dinosaur', 'Dog', 'Dogfish', 'Dolphin', 'Donkey', 'Dotterel', 'Dove', 'Dragonfly', 'Duck', 'Dugong', 'Dunlin'],
|
||||
e: ['Eagle', 'Echidna', 'Eel', 'Eland', 'Elephant', 'Elephant Seal', 'Elk', 'Emu'],
|
||||
f: ['Falcon', 'Ferret', 'Finch', 'Fish', 'Flamingo', 'Fly', 'Fox', 'Frog'],
|
||||
g: ['Gaur', 'Gazelle', 'Gerbil', 'Giant Panda', 'Giraffe', 'Gnat', 'Gnu', 'Goat', 'Goose', 'Goldfinch', 'Goldfish', 'Gorilla', 'Goshawk', 'Grasshopper', 'Grouse', 'Guanaco', 'Guinea Fowl', 'Guinea Pig', 'Gull'],
|
||||
h: ['Hamster', 'Hare', 'Hawk', 'Hedgehog', 'Heron', 'Herring', 'Hippopotamus', 'Hornet', 'Horse', 'Human', 'Hummingbird', 'Hyena'],
|
||||
i: ['Ibex', 'Ibis', 'Iguana', 'Impala', 'Isopod'],
|
||||
j: ['Jackal', 'Jaguar', 'Jay', 'Jellyfish'],
|
||||
k: ['Kangaroo', 'Kingfisher', 'Koala', 'Komodo Dragon', 'Kookabura', 'Kouprey', 'Kudu'],
|
||||
l: ['Lapwing', 'Lark', 'Lemur', 'Leopard', 'Lima', 'Lion', 'Llama', 'Lobster', 'Locust', 'Loris', 'Louse', 'Lyrebird'],
|
||||
m: ['Magpie', 'Mallard', 'Manatee', 'Mandrill', 'Mantis', 'Marten', 'Meerkat', 'Mink', 'Mole', 'Mongoose', 'Monkey', 'Moose', 'Mouse', 'Mosquito', 'Mule'],
|
||||
n: ['Narwhal', 'Newt', 'Nightingale', 'Nyala'],
|
||||
o: ['Octopus', 'Okapi', 'Opossum', 'Oryx', 'Ostrich', 'Otter', 'Owl', 'Ox', 'Oyster'],
|
||||
p: ['Panther', 'Parrot', 'Partridge', 'Peafowl', 'Pelican', 'Penguin', 'Pheasant', 'Pig', 'Pigeon', 'Polar Bear', 'Pony', 'Porcupine', 'Porpoise'],
|
||||
q: ['Quail', 'Quelea', 'Quetzal'],
|
||||
r: ['Rabbit', 'Raccoon', 'Rail', 'Ram', 'Rat', 'Raven', 'Red Deer', 'Red Panda', 'Reindeer', 'Rhinoceros', 'Rook'],
|
||||
s: ['Salamander', 'Salmon', 'Sand Dollar', 'Sandpiper', 'Sardine', 'Scorpion', 'Sea Lion', 'Sea Urchin', 'Seahorse', 'Seal', 'Shark', 'Sheep', 'Shrew', 'Skunk', 'Snail', 'Snake', 'Sparrow', 'Spider', 'Spoonbill', 'Squid', 'Squirrel', 'Starling', 'Stingray', 'Stinkbug', 'Stork', 'Swallow', 'Swan'],
|
||||
t: ['Tapir', 'Tarsier', 'Termite', 'Tiger', 'Toad', 'Trout', 'Turkey', 'Turtle'],
|
||||
u: ['Uakari', 'Unau', 'Urial', 'Urchin', 'Umbrellabird', 'Unicornfish', 'Uromastyx', 'Uguisu'],
|
||||
v: ['Vampire Bat', 'Viper', 'Vole', 'Vulture'],
|
||||
w: ['Wallaby', 'Walrus', 'Wasp', 'Weasel', 'Whale', 'Wolf', 'Wolverine', 'Wombat', 'Woodcock', 'Woodpecker', 'Worm', 'Wren'],
|
||||
x: ['Xaviers Greenbul', 'Xeme', 'Xingu Corydoras', 'Xolo'],
|
||||
y: ['Yabby', 'Yak', 'Yellowhammer', 'Yellowjacket'],
|
||||
z: ['Zebra', 'Zebu', 'Zokor', 'Zorilla']
|
||||
};
|
||||
|
||||
const action = {
|
||||
alliteration: {
|
||||
short: () => {
|
||||
|
||||
const randomAdjective = adjectives[letter.toLowerCase()][Math.floor(Math.random() * adjectives[letter.toLowerCase()].length)];
|
||||
|
||||
const randomAnimal = animals[letter.toLowerCase()][Math.floor(Math.random() * animals[letter.toLowerCase()].length)];
|
||||
|
||||
return randomAdjective + ' ' + randomAnimal;
|
||||
|
||||
},
|
||||
long: () => {
|
||||
|
||||
let randomAdjective = '';
|
||||
|
||||
for (let i = 1; i <= adjectivesCount; i++) {
|
||||
|
||||
if (adjectives[letter.toLowerCase()].length > 0) {
|
||||
if (randomAdjective.length > 0) {
|
||||
randomAdjective = randomAdjective + ' ';
|
||||
}
|
||||
randomAdjective = randomAdjective + adjectives[letter.toLowerCase()].splice(Math.floor(Math.random() * adjectives[letter.toLowerCase()].length), 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const randomAnimal = animals[letter.toLowerCase()][Math.floor(Math.random() * animals[letter.toLowerCase()].length)];
|
||||
|
||||
return randomAdjective + ' ' + randomAnimal;
|
||||
}
|
||||
},
|
||||
mix: {
|
||||
short: () => {
|
||||
|
||||
const adjectivesSeed = alphabet[Math.floor(Math.random() * (alphabet.length - 1))];
|
||||
|
||||
const animalsSeed = alphabet[Math.floor(Math.random() * (alphabet.length - 1))];
|
||||
|
||||
const randomAdjective = adjectives[adjectivesSeed][Math.floor(Math.random() * adjectives[adjectivesSeed].length)];
|
||||
|
||||
const randomAnimal = animals[animalsSeed][Math.floor(Math.random() * animals[animalsSeed].length)];
|
||||
|
||||
return randomAdjective + ' ' + randomAnimal;
|
||||
|
||||
},
|
||||
long: () => {
|
||||
|
||||
var randomAdjective = '';
|
||||
|
||||
for (let i = 1; i <= adjectivesCount; i++) {
|
||||
|
||||
var adjectiveLetter = alphabet[Math.floor(Math.random() * (alphabet.length - 1))];
|
||||
|
||||
if (adjectiveLetter in adjectives && adjectives[adjectiveLetter].length > 0) {
|
||||
|
||||
if (randomAdjective.length > 0) {
|
||||
randomAdjective = randomAdjective + ' ';
|
||||
}
|
||||
|
||||
randomAdjective = randomAdjective + adjectives[adjectiveLetter].splice(Math.floor(Math.random() * adjectives[adjectiveLetter].length), 1);
|
||||
|
||||
if (adjectives[adjectiveLetter].length == 0) {
|
||||
delete adjectives[adjectiveLetter];
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
var randomAnimalArray = animals[alphabet[Math.floor(Math.random() * (alphabet.length - 1))]];
|
||||
|
||||
var randomAnimal = randomAnimalArray[Math.floor(Math.random() * (randomAnimalArray.length - 1))];
|
||||
|
||||
return randomAdjective + ' ' + randomAnimal;
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (letter && alphabet.includes(letter.toLowerCase())) {
|
||||
|
||||
if (adjectivesCount && adjectivesCount > 0) {
|
||||
return action.alliteration.long();
|
||||
} else {
|
||||
return action.alliteration.short();
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if (adjectivesCount && adjectivesCount > 0) {
|
||||
return action.mix.long();
|
||||
} else {
|
||||
return action.mix.short();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
|
@ -0,0 +1,45 @@
|
|||
import { makePath } from './makePath.js';
|
||||
|
||||
export const set = ({
|
||||
object = null,
|
||||
path = null,
|
||||
value = null
|
||||
} = {}) => {
|
||||
|
||||
const address = makePath(path);
|
||||
|
||||
const setValue = () => {
|
||||
|
||||
while (address.length > 1) {
|
||||
|
||||
// shift off and store the first
|
||||
let currentKey = address.shift();
|
||||
|
||||
// if the key is not found make a new object
|
||||
if (!(currentKey in object)) {
|
||||
// make an empty object in the current object level
|
||||
if (isNaN(currentKey)) {
|
||||
object[currentKey] = {};
|
||||
} else {
|
||||
object[currentKey] = [];
|
||||
}
|
||||
}
|
||||
|
||||
// drill down the object with the first key
|
||||
object = object[currentKey];
|
||||
|
||||
}
|
||||
|
||||
let finalKey = address.shift();
|
||||
|
||||
object[finalKey] = value;
|
||||
|
||||
};
|
||||
|
||||
if (object != null && path != null && value != null) {
|
||||
setValue();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
};
|
|
@ -0,0 +1,37 @@
|
|||
import { get } from './get';
|
||||
|
||||
export const sortArrayOfObject = (array, key) => {
|
||||
|
||||
array.sort((a, b) => {
|
||||
|
||||
let textA = get({
|
||||
object: a,
|
||||
path: key
|
||||
});
|
||||
|
||||
if (typeof textA == 'string') {
|
||||
textA = textA.toLowerCase();
|
||||
}
|
||||
|
||||
let textB = get({
|
||||
object: b,
|
||||
path: key
|
||||
});
|
||||
|
||||
if (typeof textB == 'string') {
|
||||
textB = textB.toLowerCase();
|
||||
}
|
||||
|
||||
if (textA < textB) {
|
||||
return -1;
|
||||
} else if (textA > textB) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
return array;
|
||||
|
||||
};
|
|
@ -0,0 +1,9 @@
|
|||
export const trimString = (value) => {
|
||||
|
||||
if (typeof value == 'string') {
|
||||
return value.trim().replace(/\s\s+/g, ' ');
|
||||
} else {
|
||||
return value;
|
||||
}
|
||||
|
||||
};
|
|
@ -0,0 +1,87 @@
|
|||
export const wordNumber = (number) => {
|
||||
|
||||
const ten = 10;
|
||||
|
||||
const oneHundred = 100;
|
||||
|
||||
const oneThousand = 1000;
|
||||
|
||||
const oneMillion = 1000000;
|
||||
|
||||
const oneBillion = 1000000000; // 1,000,000,000 (9)
|
||||
|
||||
const oneTrillion = 1000000000000; // 1,000,000,000,000 (12)
|
||||
|
||||
const oneQuadrillion = 1000000000000000; // 1,000,000,000,000,000 (15)
|
||||
|
||||
const max = 9007199254740992; // 9,007,199,254,740,992 (15)
|
||||
|
||||
const lessThanTwenty = ['Zero', 'One', 'Two', 'Three', 'Four', 'Five', 'Six', 'Seven', 'Eight', 'Nine', 'Ten', 'Eleven', 'Twelve', 'Thirteen', 'Fourteen', 'Fifteen', 'Sixteen', 'Seventeen', 'Eighteen', 'Nineteen'];
|
||||
|
||||
const tenthsLessThanHundred = ['Zero', 'Ten', 'Twenty', 'Thirty', 'Forty', 'Fifty', 'Sixty', 'Seventy', 'Eighty', 'Ninety'];
|
||||
|
||||
|
||||
const generateWords = function(number) {
|
||||
|
||||
let remainder;
|
||||
|
||||
let word;
|
||||
|
||||
let words = arguments[1];
|
||||
|
||||
// We’re done
|
||||
if (number === 0) {
|
||||
return !words ? 'Zero' : words.join(' ').replace(/,$/, '');
|
||||
}
|
||||
|
||||
// First run
|
||||
if (!words) {
|
||||
words = [];
|
||||
}
|
||||
|
||||
// If negative, prepend “minus”
|
||||
if (number < 0) {
|
||||
words.push('minus');
|
||||
number = Math.abs(number);
|
||||
}
|
||||
|
||||
if (number < 20) {
|
||||
remainder = 0;
|
||||
word = lessThanTwenty[number];
|
||||
} else if (number < oneHundred) {
|
||||
remainder = number % ten;
|
||||
word = tenthsLessThanHundred[Math.floor(number / ten)];
|
||||
// In case of remainder, we need to handle it here to be able to add the “-”
|
||||
if (remainder) {
|
||||
word += '-' + lessThanTwenty[remainder];
|
||||
remainder = 0;
|
||||
}
|
||||
} else if (number < oneThousand) {
|
||||
remainder = number % oneHundred;
|
||||
word = generateWords(Math.floor(number / oneHundred)) + ' Hundred';
|
||||
} else if (number < oneMillion) {
|
||||
remainder = number % oneThousand;
|
||||
word = generateWords(Math.floor(number / oneThousand)) + ' Thousand,';
|
||||
} else if (number < oneBillion) {
|
||||
remainder = number % oneMillion;
|
||||
word = generateWords(Math.floor(number / oneMillion)) + ' Million,';
|
||||
} else if (number < oneTrillion) {
|
||||
remainder = number % oneBillion;
|
||||
word = generateWords(Math.floor(number / oneBillion)) + ' Billion,';
|
||||
} else if (number < oneQuadrillion) {
|
||||
remainder = number % oneTrillion;
|
||||
word = generateWords(Math.floor(number / oneTrillion)) + ' Trillion,';
|
||||
} else if (number <= max) {
|
||||
remainder = number % oneQuadrillion;
|
||||
word = generateWords(Math.floor(number / oneQuadrillion)) + ' Quadrillion,';
|
||||
}
|
||||
|
||||
words.push(word);
|
||||
|
||||
return generateWords(remainder, words);
|
||||
};
|
||||
|
||||
var num = parseInt(number, 10);
|
||||
|
||||
return generateWords(num);
|
||||
};
|
|
@ -0,0 +1,75 @@
|
|||
export const config = {
|
||||
bookmark: {
|
||||
newTab: true,
|
||||
panel: { size: 35 },
|
||||
group: {
|
||||
set: [{
|
||||
active: false,
|
||||
name: 'Productivity',
|
||||
description: 'Daily apps',
|
||||
color: { primary: { hsl: [0, 0, 100] }, secondary: { hsl: [200, 60, 70] } },
|
||||
list: [
|
||||
{ icon: 'fa-solid fa-envelope', url: 'https://mail.google.com/' },
|
||||
{ icon: 'fa-brands fa-slack', url: 'https://slack.com/signin/' },
|
||||
{ icon: 'fa-brands fa-github', url: 'https://github.com/' },
|
||||
{ icon: 'fa-brands fa-codepen', url: 'https://codepen.io/' },
|
||||
{ icon: 'fa-solid fa-diamond', url: 'https://whimsical.com/login/' },
|
||||
{ icon: 'fa-brands fa-figma', url: 'https://figma.com/' },
|
||||
{ icon: 'fa-brands fa-dropbox', url: 'https://dropbox.com/' },
|
||||
{ icon: 'fa-brands fa-google-drive', url: 'https://drive.google.com/' },
|
||||
{ icon: 'fa-solid fa-calendar-day', url: 'https://calendar.google.com/calendar/' },
|
||||
]
|
||||
}, {
|
||||
active: false,
|
||||
name: 'Cool stuff',
|
||||
description: 'Downtime and media',
|
||||
color: { primary: { hsl: [0, 0, 100] }, secondary: { hsl: [250, 60, 70] } },
|
||||
list: [
|
||||
{ icon: 'fa-brands fa-reddit-alien', url: 'https://reddit.com/' },
|
||||
{ icon: 'fa-brands fa-deviantart', url: 'https://www.deviantart.com/' },
|
||||
{ icon: 'fa-brands fa-discord', url: 'https://discord.com/' },
|
||||
{ icon: 'fa-solid fa-paperclip', url: 'https://www.decisionproblem.com/paperclips/' },
|
||||
{ icon: 'fa-solid fa-dice-d20', url: 'https://zombiefox.github.io/diceRoller/' },
|
||||
{ icon: 'fa-brands fa-dribbble', url: 'https://dribbble.com/' },
|
||||
]
|
||||
}, {
|
||||
active: false,
|
||||
name: 'Entertainment',
|
||||
description: 'Films and videos',
|
||||
color: { primary: { hsl: [0, 0, 100] }, secondary: { hsl: [0, 60, 70] } },
|
||||
list: [
|
||||
{ icon: 'fa-brands fa-vimeo', url: 'https://vimeo.com/' },
|
||||
{ icon: 'fa-brands fa-youtube', url: 'https://youtube.com/' },
|
||||
{ icon: 'fa-solid fa-clapperboard', url: 'https://netflix.com/' },
|
||||
{ icon: 'fa-brands fa-twitch', url: 'https://www.twitch.tv/' },
|
||||
]
|
||||
}, {
|
||||
active: false,
|
||||
name: 'Ref',
|
||||
description: 'Docs, code + specs',
|
||||
color: { primary: { hsl: [0, 0, 100] }, secondary: { hsl: [40, 60, 70] } },
|
||||
list: [
|
||||
{ icon: 'fa-solid fa-code', url: 'https://devdocs.io/' },
|
||||
{ icon: 'fa-brands fa-css3-alt', url: 'https://developer.mozilla.org/en-US/docs/Learn/CSS/' },
|
||||
{ icon: 'fa-brands fa-stack-overflow', url: 'https://stackoverflow.com/' },
|
||||
{ icon: 'fa-brands fa-bootstrap', url: 'https://getbootstrap.com/docs/5.2/getting-started/introduction/' },
|
||||
{ icon: 'fa-brands fa-npm', url: 'https://www.npmjs.com/' },
|
||||
]
|
||||
}]
|
||||
}
|
||||
},
|
||||
theme: {
|
||||
scale: 38,
|
||||
accent: { hsl: [204, 100, 72] },
|
||||
text: { hsl: [0, 0, 0] },
|
||||
font: 'Ubuntu',
|
||||
transition: { speed: { xfast: 10, fast: 20, medium: 30, slow: 40, xslow: 50 } },
|
||||
easing: { bounce: [0.8, 0.5, 0.2, 2] },
|
||||
bookmark: { background: { blur: 14, color: { hsla: [200, 180, 25, 0.2] } } }
|
||||
},
|
||||
background: {
|
||||
color: { hsl: [220, 30, 50] },
|
||||
image: { url: 'https://i.redd.it/niecy4jmlmh81.png', opacity: 1, grayscale: 0.1, blur: 0 },
|
||||
gradient: { degree: 90, color: [{ hsla: [220, 80, 18, 0.6], position: 30 }, { hsla: [240, 85, 25, 0.4], position: 40 }, { hsla: [280, 40, 25, 0.1], position: 100 }] }
|
||||
}
|
||||
};
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,5 @@
|
|||
<svg width="16" height="16" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M9.52158 6.99999H13.0087C13.4246 6.99999 13.7999 7.25936 13.9188 7.64686C14.0908 8.03749 13.9813 8.47811 13.6686 8.75311L5.66231 15.7531C5.30891 16.0594 4.79194 16.0844 4.41414 15.8094C4.03603 15.5344 3.89843 15.0344 4.08263 14.6062L6.48795 8.99999H2.9727C2.58396 8.99999 2.21063 8.74061 2.06399 8.35311C1.91734 7.96249 2.02804 7.52186 2.34189 7.24686L10.3472 0.247427C10.7006 -0.0600103 11.2167 -0.0834165 11.5951 0.191052C11.9735 0.465615 12.1111 0.964677 11.9266 1.39405L9.52158 6.99999Z"
|
||||
fill="#85C2E0"/>
|
||||
</svg>
|
After Width: | Height: | Size: 633 B |
Binary file not shown.
After Width: | Height: | Size: 1.9 KiB |
Binary file not shown.
After Width: | Height: | Size: 373 B |
Binary file not shown.
After Width: | Height: | Size: 859 B |
Binary file not shown.
After Width: | Height: | Size: 8.7 KiB |
|
@ -0,0 +1,35 @@
|
|||
<svg viewBox="0 0 512 512" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
||||
<style>
|
||||
.cross {
|
||||
fill: #939BAE;
|
||||
}
|
||||
.hex {
|
||||
fill: #252931;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
.cross {
|
||||
fill: #939BAE;
|
||||
}
|
||||
.hex {
|
||||
fill: #252931;
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.cross {
|
||||
fill: #252931;
|
||||
}
|
||||
.hex {
|
||||
fill: #939BAE;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M507.885 271.42C513.372 261.948 513.372 250.263 507.885 240.79L395.206 46.2423C389.742 36.8083 379.665 31 368.763 31H143.237C132.335 31 122.258 36.8083 116.794 46.2423L4.11494 240.79C-1.37164 250.263 -1.37165 261.948 4.11494 271.42L116.794 465.968C122.258 475.402 132.335 481.21 143.237 481.21H368.763C379.665 481.21 389.742 475.402 395.206 465.968L507.885 271.42Z"
|
||||
class="hex"/>
|
||||
<path d="M374 224H138C132.477 224 128 228.477 128 234V278C128 283.523 132.477 288 138 288H374C379.523 288 384 283.523 384 278V234C384 228.477 379.523 224 374 224Z" class="cross"/>
|
||||
<path d="M278 128H234C228.477 128 224 132.477 224 138V374C224 379.523 228.477 384 234 384H278C283.523 384 288 379.523 288 374V138C288 132.477 283.523 128 278 128Z" class="cross"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.2 KiB |
|
@ -0,0 +1,15 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
|
||||
<title>Volt Tab</title>
|
||||
<link rel="icon" type="image/svg+xml" href="icon/favicon.svg"/>
|
||||
<style media="screen" type="text/css">html,body {background-color: rgb(0, 0, 0);}</style>
|
||||
|
||||
</head>
|
||||
|
||||
<body></body>
|
||||
|
||||
</html>
|
|
@ -0,0 +1,5 @@
|
|||
import { App } from './app';
|
||||
|
||||
const app = new App();
|
||||
|
||||
app.render();
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"name": "Volt Tab",
|
||||
"short_name": "Volt Tab",
|
||||
"description": "",
|
||||
"version": "1.0.0",
|
||||
"manifest_version": 2,
|
||||
"chrome_url_overrides": {
|
||||
"newtab": "index.html"
|
||||
},
|
||||
"icons": {
|
||||
"16": "icon/icon-16.png",
|
||||
"48": "icon/icon-48.png",
|
||||
"128": "icon/icon-128.png",
|
||||
"512": "icon/icon-512.png"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,313 @@
|
|||
*,
|
||||
*::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);
|
||||
}
|
||||
|
||||
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: #000;
|
||||
}
|
||||
|
||||
[tabindex="-1"]:focus {
|
||||
outline: none !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: none;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
|
@ -0,0 +1,179 @@
|
|||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
margin: 0 0 1em 0;
|
||||
font-weight: normal;
|
||||
line-height: 1.6;
|
||||
color: hsl(var(--theme-primary-text-010));
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 1.5em;
|
||||
font-family: var(--theme-font-display-name);
|
||||
font-weight: var(--theme-font-display-weight);
|
||||
font-style: var(--theme-font-display-style);
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 1.3em;
|
||||
font-family: var(--theme-font-display-name);
|
||||
font-weight: var(--theme-font-display-weight);
|
||||
font-style: var(--theme-font-display-style);
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 1.1em;
|
||||
font-family: var(--theme-font-ui-name);
|
||||
font-weight: var(--theme-font-ui-weight);
|
||||
font-style: var(--theme-font-ui-style);
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: 1em;
|
||||
font-family: var(--theme-font-ui-name);
|
||||
font-weight: var(--theme-font-ui-weight);
|
||||
font-style: var(--theme-font-ui-style);
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: 1em;
|
||||
font-family: var(--theme-font-ui-name);
|
||||
font-weight: var(--theme-font-ui-weight);
|
||||
font-style: var(--theme-font-ui-style);
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
h6 {
|
||||
font-size: 0.75em;
|
||||
font-family: var(--theme-font-ui-name);
|
||||
font-weight: var(--theme-font-ui-weight);
|
||||
font-style: var(--theme-font-ui-style);
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
p {
|
||||
color: hsl(var(--theme-primary-text-010));
|
||||
margin: 0;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
hr {
|
||||
border: 0;
|
||||
border-top: var(--layout-horizontal-rule-small);
|
||||
border-radius: calc(var(--theme-radius) * 0.01em);
|
||||
margin: calc(var(--wrap-space) * 2) 0;
|
||||
clear: both;
|
||||
transition: border-color var(--layout-transition-extra-fast);
|
||||
}
|
||||
|
||||
b,
|
||||
caption,
|
||||
strong {
|
||||
color: hsl(var(--theme-primary-text-010));
|
||||
font-family: var(--theme-font-ui-name);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
i {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
a {
|
||||
color: hsl(var(--theme-primary-text-010));
|
||||
text-decoration: underline;
|
||||
transition: text-decoration var(--layout-transition-extra-fast);
|
||||
}
|
||||
|
||||
a:link,
|
||||
a:visited {
|
||||
color: hsl(var(--theme-primary-text-010));
|
||||
}
|
||||
|
||||
a:focus {
|
||||
text-decoration-color: hsl(var(--theme-primary-text-010));
|
||||
outline: none;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: hsl(var(--theme-primary-text-010));
|
||||
text-decoration-color: rgb(var(--theme-accent));
|
||||
}
|
||||
|
||||
a:active {
|
||||
color: hsl(var(--theme-primary-text-010));
|
||||
text-decoration-color: hsl(var(--theme-primary-text-010));
|
||||
}
|
||||
|
||||
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: hsl(var(--theme-primary-030));
|
||||
border: 0;
|
||||
border-bottom: 1px solid hsl(var(--theme-primary-040));
|
||||
padding: 0.5em;
|
||||
margin: 0;
|
||||
text-align: left;
|
||||
font-family: var(--theme-font-ui-name);
|
||||
font-weight: var(--theme-font-ui-weight);
|
||||
font-style: var(--theme-font-ui-style);
|
||||
font-weight: bold;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
table tr:nth-child(odd) {
|
||||
background-color: hsl(var(--theme-primary-020));
|
||||
}
|
||||
|
||||
table tbody tr td,
|
||||
table tbody tr th {
|
||||
padding: 0.25em 0.5em;
|
||||
margin: 0;
|
||||
border: 0;
|
||||
text-align: left;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
code {
|
||||
background-color: hsl(var(--theme-primary-040));
|
||||
padding: 0.2em 0.5em;
|
||||
border-radius: calc(var(--theme-radius) * 0.01em);
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
:root {
|
||||
--z-index-background: 1000;
|
||||
--z-index-bookmark: 2000;
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
const path = require('path');
|
||||
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
||||
const CopyPlugin = require('copy-webpack-plugin');
|
||||
|
||||
module.exports = {
|
||||
entry: {
|
||||
index: path.resolve(__dirname, 'src', 'index.js')
|
||||
},
|
||||
output: {
|
||||
filename: '[name].[contenthash].js',
|
||||
path: path.resolve(__dirname, 'dist/web'),
|
||||
clean: true
|
||||
},
|
||||
module: {
|
||||
rules: [{
|
||||
test: /\.css$/i,
|
||||
use: ['style-loader', 'css-loader']
|
||||
}, {
|
||||
test: /\.(ttf|woff|woff2)$/,
|
||||
type: 'asset/resource',
|
||||
generator: {
|
||||
filename: 'font/[name][ext]',
|
||||
}
|
||||
}, {
|
||||
test: /\.(jpe?g|png|gif|svg)$/i,
|
||||
type: 'asset/resource',
|
||||
generator: {
|
||||
filename: 'image/[name][ext]',
|
||||
}
|
||||
}]
|
||||
},
|
||||
plugins: [
|
||||
new HtmlWebpackPlugin({
|
||||
template: './src/index.html'
|
||||
}),
|
||||
new CopyPlugin({
|
||||
patterns: [{
|
||||
from: './src/manifest.json',
|
||||
to: './manifest.json'
|
||||
}, {
|
||||
from: './src/icon/',
|
||||
to: './icon/'
|
||||
}]
|
||||
})
|
||||
]
|
||||
};
|
|
@ -0,0 +1,7 @@
|
|||
const { merge } = require('webpack-merge');
|
||||
const common = require('./webpack.common.js');
|
||||
|
||||
module.exports = merge(common, {
|
||||
mode: 'development',
|
||||
devtool: 'inline-source-map'
|
||||
});
|
|
@ -0,0 +1,45 @@
|
|||
const { merge } = require('webpack-merge');
|
||||
const common = require('./webpack.common.js');
|
||||
const path = require('path');
|
||||
const ZipPlugin = require('zip-webpack-plugin');
|
||||
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
|
||||
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
||||
const TerserPlugin = require('terser-webpack-plugin');
|
||||
|
||||
const version = require('./src/manifest.json').version;
|
||||
const name = require('./src/manifest.json').name;
|
||||
|
||||
module.exports = merge(common, {
|
||||
mode: 'production',
|
||||
optimization: {
|
||||
minimize: true,
|
||||
minimizer: [
|
||||
new CssMinimizerPlugin({
|
||||
minify: CssMinimizerPlugin.cleanCssMinify
|
||||
}),
|
||||
new TerserPlugin({
|
||||
terserOptions: {
|
||||
format: {
|
||||
comments: false,
|
||||
},
|
||||
},
|
||||
extractComments: false,
|
||||
})
|
||||
]
|
||||
},
|
||||
module: {
|
||||
rules: [{
|
||||
test: /\.css$/i,
|
||||
use: [MiniCssExtractPlugin.loader, 'css-loader'],
|
||||
}],
|
||||
},
|
||||
plugins: [
|
||||
new MiniCssExtractPlugin({
|
||||
filename: '[name].[contenthash].css'
|
||||
}),
|
||||
new ZipPlugin({
|
||||
path: path.resolve(__dirname, 'dist/extension'),
|
||||
filename: name + ' ' + version + '.zip'
|
||||
})
|
||||
]
|
||||
});
|
Loading…
Reference in New Issue