Simplify css and javascript minification

This commit is contained in:
Timothy Warren 2017-04-06 11:45:25 -04:00
parent f412aaad27
commit e0516e4cc0
17 changed files with 727 additions and 3555 deletions

View File

@ -18,46 +18,6 @@
return [
/*
|--------------------------------------------------------------------------
| CSS Folder
|--------------------------------------------------------------------------
|
| The folder where css files exist, in relation to the document root
|
*/
'css_root' => 'css/',
/*
|--------------------------------------------------------------------------
| Path from
|--------------------------------------------------------------------------
|
| Path fragment to rewrite in css files
|
*/
'path_from' => '',
/*
|--------------------------------------------------------------------------
| Path to
|--------------------------------------------------------------------------
|
| The path fragment replacement for the css files
|
*/
'path_to' => '',
/*
|--------------------------------------------------------------------------
| CSS Groups file
|--------------------------------------------------------------------------
|
| The file where the css groups are configured
|
*/
'css_groups_file' => __DIR__ . '/minify_css_groups.php',
/*
|--------------------------------------------------------------------------
| JS Folder
@ -70,13 +30,40 @@ return [
/*
|--------------------------------------------------------------------------
| JS Groups file
| JS Groups
|--------------------------------------------------------------------------
|
| The file where the javascript groups are configured
| Config array for javascript files to concatenate and minify
|
*/
'js_groups_file' => __DIR__ . '/minify_js_groups.php',
'groups' => [
'base' => [
'base/classList.js',
'base/AnimeClient.js',
],
'event' => [
'base/events.js',
],
'table' => [
'base/sort_tables.js',
],
'table_edit' => [
'base/sort_tables.js',
'anime_edit.js',
'manga_edit.js',
],
'edit' => [
'anime_edit.js',
'manga_edit.js',
],
'anime_collection' => [
'lib/mustache.js',
'anime_collection.js',
],
'manga_collection' => [
'lib/mustache.js',
'manga_collection.js',
],
]
];
// End of minify_config.php

View File

@ -1,40 +0,0 @@
<?php declare(strict_types=1);
/**
* Hummingbird Anime List Client
*
* An API client for Kitsu and MyAnimeList to manage anime and manga watch lists
*
* PHP version 7
*
* @package HummingbirdAnimeClient
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2015 - 2017 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 4.0
* @link https://github.com/timw4mail/HummingBirdAnimeClient
*/
// --------------------------------------------------------------------------
/**
* This is the config array for css files to concatenate and minify
*/
return [
/*-----
Css
-----*/
/*
For each group create an array like so
'my_group' => array(
'path/to/css/file1.css',
'path/to/css/file2.css'
),
*/
'base' => [
'base.css'
]
];
// End of css_groups.php

View File

@ -1,53 +0,0 @@
<?php declare(strict_types=1);
/**
* Hummingbird Anime List Client
*
* An API client for Kitsu and MyAnimeList to manage anime and manga watch lists
*
* PHP version 7
*
* @package HummingbirdAnimeClient
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2015 - 2017 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 4.0
* @link https://github.com/timw4mail/HummingBirdAnimeClient
*/
// --------------------------------------------------------------------------
/**
* This is the config array for javascript files to concatenate and minify
*/
return [
'base' => [
'base/classList.js',
'base/AnimeClient.js',
],
'event' => [
'base/events.js',
],
'table' => [
'base/sort_tables.js',
],
'table_edit' => [
'base/sort_tables.js',
'anime_edit.js',
'manga_edit.js',
],
'edit' => [
'anime_edit.js',
'manga_edit.js',
],
'anime_collection' => [
'lib/mustache.js',
'anime_collection.js',
],
'manga_collection' => [
'lib/mustache.js',
'manga_collection.js',
],
];
// End of js_groups.php

View File

@ -6,7 +6,7 @@
<meta http-equiv="cache-control" content="no-store" />
<meta http-equiv="Content-Security-Policy" content="script-src 'self'" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1, user-scalable=0" />
<link rel="stylesheet" href="<?= $urlGenerator->assetUrl('css.php/g/base/debug') ?>" />
<link rel="stylesheet" href="<?= $urlGenerator->assetUrl('css/app.min.css') ?>" />
<link rel="icon" href="<?= $urlGenerator->assetUrl('images/icons/favicon.ico') ?>" />
<link rel="apple-touch-icon" sizes="57x57" href="<?= $urlGenerator->assetUrl('images/icons/apple-icon-57x57.png') ?>">
<link rel="apple-touch-icon" sizes="60x60" href="<?= $urlGenerator->assetUrl('images/icons/apple-icon-60x60.png') ?>">
@ -21,17 +21,19 @@
<link rel="icon" type="image/png" sizes="32x32" href="<?= $urlGenerator->assetUrl('images/icons/favicon-32x32.png') ?>">
<link rel="icon" type="image/png" sizes="96x96" href="<?= $urlGenerator->assetUrl('images/icons/favicon-96x96.png') ?>">
<link rel="icon" type="image/png" sizes="16x16" href="<?= $urlGenerator->assetUrl('images/icons/favicon-16x16.png') ?>">
<link rel="manifest" href="/manifest.json">
<script defer="defer" src="<?= $urlGenerator->assetUrl('js.php/g/base') ?>"></script>
</head>
<body class="<?= $escape->attr($url_type) ?> list">
<header>
<?php include 'main-menu.php' ?>
<?php if(isset($message) && is_array($message)):
<?php
include 'main-menu.php';
if(isset($message) && is_array($message))
{
foreach($message as $m)
{
extract($m);
include 'message.php';
include 'message.php';
}
endif ?>
}
?>
</header>

View File

28
public/css.js Normal file
View File

@ -0,0 +1,28 @@
/**
* Script for optimizing css
*/
const fs = require('fs');
const postcss = require('postcss');
const atImport = require('postcss-import');
const cssNext = require('postcss-cssnext');
const cssNano = require('cssnano');
const css = fs.readFileSync('css/base.css', 'utf8');
postcss()
.use(atImport())
.use(cssNext({
warnForDuplicates: false
}))
.use(cssNano({
options: {
sourcemap: false
}
}))
.process(css, {
from: 'css/base.css',
to: 'css/app.min.css'
}).then(result => {
fs.writeFileSync('css/app.min.css', result.css);
fs.writeFileSync('css/app.min.css.map', result.map);
});

View File

@ -1,180 +0,0 @@
<?php declare(strict_types=1);
/**
* Hummingbird Anime List Client
*
* An API client for Kitsu and MyAnimeList to manage anime and manga watch lists
*
* PHP version 7
*
* @package HummingbirdAnimeClient
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2015 - 2017 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 4.0
* @link https://github.com/timw4mail/HummingBirdAnimeClient
*/
namespace Aviat\EasyMin;
require_once('./min.php');
/**
* Simple CSS Minifier
*/
class CSSMin extends BaseMin {
protected $cssRoot;
protected $pathFrom;
protected $pathTo;
protected $group;
protected $lastModified;
protected $requestedTime;
public function __construct(array $config, array $groups)
{
$group = $_GET['g'];
$this->cssRoot = $config['css_root'];
$this->pathFrom = $config['path_from'];
$this->pathTo = $config['path_to'];
$this->group = $groups[$group];
$this->lastModified = $this->getLastModified();
$this->send();
}
/**
* Send the CSS
*
* @return void
*/
protected function send()
{
if($this->lastModified >= $this->getIfModified() && $this->isNotDebug())
{
throw new FileNotChangedException();
}
$css = ( ! array_key_exists('debug', $_GET))
? $this->compress($this->getCss())
: $this->getCss();
$this->output($css);
}
/**
* Function for compressing the CSS as tightly as possible
*
* @param string $buffer
* @return string
*/
protected function compress($buffer)
{
//Remove CSS comments
$buffer = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $buffer);
//Remove tabs, spaces, newlines, etc.
$buffer = preg_replace('`\s+`', ' ', $buffer);
$replace = [
' )' => ')',
') ' => ')',
' }' => '}',
'} ' => '}',
' {' => '{',
'{ ' => '{',
', ' => ',',
': ' => ':',
'; ' => ';',
];
//Eradicate every last space!
$buffer = trim(strtr($buffer, $replace));
$buffer = str_replace('{ ', '{', $buffer);
$buffer = str_replace('} ', '}', $buffer);
return $buffer;
}
/**
* Get the most recent file modification date
*
* @return int
*/
protected function getLastModified()
{
$modified = [];
// Get all the css files, and concatenate them together
if(isset($this->group))
{
foreach($this->group as $file)
{
$newFile = realpath("{$this->cssRoot}{$file}");
$modified[] = filemtime($newFile);
}
}
//Add this page for last modified check
$modified[] = filemtime(__FILE__);
//Get the latest modified date
rsort($modified);
return array_shift($modified);
}
/**
* Get the css to display
*
* @return string
*/
protected function getCss()
{
$css = '';
foreach($this->group as $file)
{
$newFile = realpath("{$this->cssRoot}{$file}");
$css .= file_get_contents($newFile);
}
// Correct paths that have changed due to concatenation
// based on rules in the config file
$css = str_replace($this->pathFrom, $this->pathTo, $css);
return $css;
}
/**
* Output the CSS
*
* @return void
*/
protected function output($css)
{
$this->sendFinalOutput($css, 'text/css', $this->lastModified);
}
}
// --------------------------------------------------------------------------
// ! Start Minifying
// --------------------------------------------------------------------------
//Get config files
$config = require('../app/appConf/minify_config.php');
$groups = require($config['css_groups_file']);
if ( ! array_key_exists($_GET['g'], $groups))
{
throw new InvalidArgumentException('You must specify a css group that exists');
}
try
{
new CSSMin($config, $groups);
}
catch (FileNotChangedException $e)
{
BaseMin::send304();
}
//End of css.php

1
public/css/app.min.css vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
undefined

File diff suppressed because it is too large Load Diff

View File

@ -1,652 +0,0 @@
@import "./marx.myth.css";
:root {
--link-shadow: 1px 1px 1px #000;
--shadow: 1px 2px 1px rgba(0, 0, 0, 0.85);
--title-overlay: rgba(0, 0, 0, 0.45);
--title-overlay-fallback: #000;
--text-color: #ffffff;
--normal-padding: 0.25em 0.125em;
--link-hover-color: #7d12db;
--edit-link-hover-color: #db7d12;
--edit-link-color: #12db18;
--radius: 5px;
}
template, [hidden="hidden"], .media[hidden] {display:none}
body {margin: 0.5em;}
button {
background:rgba(255,255,255,0.65);
margin: 0;
}
table {
min-width:85%;
margin: 0 auto;
}
td {
padding:1em;
padding:1rem;
}
thead td, thead th {
padding:0.5em;
padding:0.5rem;
}
input[type=number] {
width: 4em;
}
tbody > tr:nth-child(odd) {
background: #ddd;
}
a:hover, a:active {
color: var(--link-hover-color)
}
/* -----------------------------------------------------------------------------
Utility classes
------------------------------------------------------------------------------*/
.bracketed {
color: var(--edit-link-color);
}
.bracketed, h1 a {
text-shadow: var(--link-shadow);
}
.bracketed:before {content: '[\00a0'}
.bracketed:after {content: '\00a0]'}
.bracketed:hover, .bracketed:active {
color: var(--edit-link-hover-color)
}
.grow-1 {flex-grow: 1}
.flex-wrap {flex-wrap: wrap}
.flex-no-wrap {flex-wrap: nowrap}
.flex-align-end {align-items: flex-end}
.flex-align-space-around {align-content: space-around}
.flex-justify-space-around {justify-content: space-around}
.flex-self-center {align-self:center}
.flex {display: flex}
.small-font {
font-size:1.6rem;
}
.justify {text-align:justify}
.align_center {text-align:center !important}
.align_left {text-align:left !important}
.align_right {text-align:right !important}
.valign_top {vertical-align:top}
.no_border {border:none}
.media-wrap {
text-align:center;
margin:0 auto;
}
.danger {
background-color: #ff4136;
border-color: #924949;
color:#fff;
}
.danger:hover, .danger:active {
background-color: #924949;
border-color: #ff4136;
color:#fff;
}
.user-btn {
border-color: var(--edit-link-color);
color: var(--edit-link-color);
text-shadow: var(--link-shadow);
padding:0 0.5em;
padding:0 0.5rem;
}
.user-btn:hover, .user-btn:active {
border-color: var(--edit-link-hover-color);
background-color: var(--edit-link-hover-color);
}
.full_width {
width: 100%;
}
/* -----------------------------------------------------------------------------
CSS loading icon
------------------------------------------------------------------------------*/
.cssload-loader {
position: relative;
left: calc(50% - 31px);
width: 62px;
height: 62px;
border-radius: 50%;
perspective: 780px;
}
.cssload-inner {
position: absolute;
width: 100%;
height: 100%;
box-sizing: border-box;
border-radius: 50%;
}
.cssload-inner.cssload-one {
left: 0%;
top: 0%;
animation: cssload-rotate-one 1.15s linear infinite;
border-bottom: 3px solid rgb(0,0,0);
}
.cssload-inner.cssload-two {
right: 0%;
top: 0%;
animation: cssload-rotate-two 1.15s linear infinite;
border-right: 3px solid rgb(0,0,0);
}
.cssload-inner.cssload-three {
right: 0%;
bottom: 0%;
animation: cssload-rotate-three 1.15s linear infinite;
border-top: 3px solid rgb(0,0,0);
}
@keyframes cssload-rotate-one {
0% {
transform: rotateX(35deg) rotateY(-45deg) rotateZ(0deg);
}
100% {
transform: rotateX(35deg) rotateY(-45deg) rotateZ(360deg);
}
}
@keyframes cssload-rotate-two {
0% {
transform: rotateX(50deg) rotateY(10deg) rotateZ(0deg);
}
100% {
transform: rotateX(50deg) rotateY(10deg) rotateZ(360deg);
}
}
@keyframes cssload-rotate-three {
0% {
transform: rotateX(35deg) rotateY(55deg) rotateZ(0deg);
}
100% {
transform: rotateX(35deg) rotateY(55deg) rotateZ(360deg);
}
}
/* -----------------------------------------------------------------------------
Table sorting and form styles
------------------------------------------------------------------------------*/
.sorting,
.sorting_asc,
.sorting_desc {
vertical-align:text-bottom;
}
.sorting::before {
content: " ↕\00a0";
}
.sorting_asc::before {
content: " ↑\00a0";
}
.sorting_desc::before {
content: " ↓\00a0";
}
.form { width:100%; }
.form thead th, .form thead tr {
background: inherit;
border:0;
}
.form tr > td:nth-child(odd) {
text-align:right;
min-width:25px;
max-width:30%;
}
.form tr > td:nth-child(even) {
text-align:left;
width:70%;
}
.invisible tbody > tr:nth-child(odd) {
background: inherit;
}
.invisible tr, .invisible td, .invisible th {
border:0;
}
/* -----------------------------------------------------------------------------
Message boxes
------------------------------------------------------------------------------*/
.message{
position:relative;
margin:0.5em auto;
padding:0.5em;
width:95%;
}
.message .close{
width:1em;
height:1em;
position:absolute;
right:0.5em;
top:0.5em;
text-align:center;
vertical-align:middle;
line-height:1em;
}
.message:hover .close:after {
content: '☒';
}
.message:hover {
cursor:pointer;
}
.message .icon{
left:0.5em;
top:0.5em;
margin-right:1em;
}
.message.error{
border:1px solid #924949;
background: #f3e6e6;
}
.message.error .icon::after {
content: '✘';
}
.message.success{
border:1px solid #1f8454;
background: #70dda9;
}
.message.success .icon::after {
content: '✔'
}
.message.info{
border:1px solid #bfbe3a;
background: #FFFFCC;
}
.message.info .icon::after {
content: '⚠';
}
/* -----------------------------------------------------------------------------
Base list styles
------------------------------------------------------------------------------*/
.media, .character, .small_character {
position:relative;
vertical-align:top;
display:inline-block;
text-align:center;
width:220px;
height:311px;
margin: var(--normal-padding);
}
.media > img,
.character > img,
.small_character > img {
width: 100%;
}
.media .edit_buttons > button {
margin:0.5em auto;
}
.name,
.media_metadata > div,
.medium_metadata > div,
.row {
text-shadow: var(--shadow);
background: var(--title-overlay-fallback);
background: var(--title-overlay);
color: var(--text-color);
padding: var(--normal-padding);
text-align:right;
}
.media_type, .age_rating {
text-align:left;
}
.media > .media_metadata {
position:absolute;
bottom:0;
right:0;
}
.media > .medium_metadata {
position:absolute;
bottom: 0;
left:0;
}
.media > .name {
position:absolute;
top: 0;
}
.small_character:hover > .name,
.character:hover > .name,
.media:hover > .name,
.media:hover > .media_metadata > div,
.media:hover > .medium_metadata > div,
.media:hover > .table .row
{
transition: .25s ease;
background:rgba(0,0,0,0.75);
}
.media:hover > button[hidden],
.media:hover > .edit_buttons[hidden]
{
transition: .25s ease;
display:block;
}
.small_character > .name a,
.small_character > .name a small,
.character > .name a,
.character > .name a small,
.media > .name a,
.media > .name a small
{
background:none;
color:#fff;
text-shadow: var(--shadow);
}
/* -----------------------------------------------------------------------------
Anime-list-specific styles
------------------------------------------------------------------------------*/
.anime .name, .manga .name {
text-align:center;
width:100%;
padding:0.5em 0.25em;
}
.anime .media_type,
.anime .airing_status,
.anime .user_rating,
.anime .completion,
.anime .age_rating,
.anime .edit,
.anime .delete {
background: none;
text-align:center;
}
.anime .table, .manga .table {
position:absolute;
bottom:0;
left:0;
width:100%;
}
.anime .row, .manga .row {
width:100%;
background: var(--title-overlay-fallback);
background: var(--title-overlay);
display: flex;
align-content: space-around;
justify-content: space-around;
text-align:center;
padding:0 inherit;
}
.anime .row > span, .manga .row > span {
text-align:left;
}
.anime .row > div, .manga .row > div {
font-size:0.8em;
display:flex-item;
align-self:center;
text-align:center;
vertical-align:middle;
}
.anime .media > button.plus_one {
position:absolute;
top: 138px;
top: calc(50% - 21.5px);
left: 44px;
left: calc(50% - 66.5px);
}
/* -----------------------------------------------------------------------------
Manga-list-specific styles
------------------------------------------------------------------------------*/
.manga .row {
padding:1px;
}
.manga .media {
border:1px solid #ddd;
height:310px;
margin:0.25em;
}
.manga .media > .edit_buttons {
position:absolute;
top: 86px;
top: calc(50% - 58.5px);
left: 43.5px;
left: calc(50% - 66.5px);
}
/* -----------------------------------------------------------------------------
Search page styles
------------------------------------------------------------------------------*/
.media.search > .name {
background-color:#555;
background-color: rgba(000,000,000,0.35);
background-size: cover;
background-size: contain;
background-repeat: no-repeat;
}
.big-check {
display:none;
}
.big-check:checked + label {
transition: .25s ease;
background:rgba(0,0,0,0.75);
}
.big-check:checked + label:after {
content: '✓';
font-size: 15em;
font-size: 15rem;
text-align:center;
color: greenyellow;
position:absolute;
top:147px;
left:0;
height:100%;
width:100%;
}
#series_list article.media {
position:relative;
}
#series_list .name, #series_list .name label {
position:absolute;
display:block;
top:0;
left:0;
height:100%;
width:100%;
vertical-align:middle;
line-height: 1.25em;
}
#series_list .name small {
color: #fff;
}
/* ----------------------------------------------------------------------------
Details page styles
-----------------------------------------------------------------------------*/
.details {
margin: 1.5rem auto 0 auto;
padding:1rem;
font-size:inherit;
}
.description {
max-width:80rem;
}
.fixed {
max-width:93rem;
}
.details .cover {
display: block;
width: 284px;
/* height: 402px; */
}
.details h2 {
margin-top: 0;
}
.details .flex > div {
margin: 1rem;
}
.details .media_details {
max-width:300px;
}
.details .media_details td {
padding:0 1.5rem;
}
.details p {
text-align:justify;
}
.details .media_details td:nth-child(odd) {
width:1%;
white-space:nowrap;
text-align:right;
}
.details .media_details td:nth-child(even) {
text-align:left;
}
.character,
.small_character {
background: rgba(0,0,0,0.5);
width: 225px;
height: 350px;
vertical-align: middle;
white-space: nowrap;
}
.small_character a {
display:inline-block;
width: 100%;
height: 100%;
}
.small_character .name,
.character .name {
position: absolute;
bottom: 0;
left: 0;
z-index: 10;
}
.small_character img,
.character img {
position: relative;
top: 50%;
transform: translateY(-50%);
z-index: 5;
width: 100%;
}
.min-table {
min-width: 0;
margin-left: 0;
}
/* ----------------------------------------------------------------------------
User page styles
-----------------------------------------------------------------------------*/
.small_character {
width: 160px;
height: 250px;
}
.user-page .media-wrap {
text-align: left;
}
.media a {
display: inline-block;
width: 100%;
height: 100%;
}
/* ----------------------------------------------------------------------------
Viewport-based styles
-----------------------------------------------------------------------------*/
@media screen and (max-width: 40em) {
nav a {
line-height:4em;
line-height:4rem;
}
.media {
margin:2px 0;
}
main {
padding:0 0,5em 0.5em;
padding:0 0.5rem 0.5rem;
}
}
/* ----------------------------------------------------------------------------
Images / Logos
-----------------------------------------------------------------------------*/
.streaming-logo {
width: 50px;
height: 50px;
vertical-align:middle;
}
.cover_streaming_link .streaming-logo {
width: 20px;
height: 20px;
}

View File

@ -1,6 +1,7 @@
:root
{
--default-font-list:'Open Sans', 'Nimbus Sans L', 'Helvetica Neue', Helvetica, 'Lucida Grande', sans-serif;
:root {
--default-font-list:system-ui,sans-serif;
--monospace-font-list:'Anonymous Pro','Fira Code',Menlo,Monaco,Consolas,'Courier New',monospace;
--serif-font-list:Georgia,Times,'Times New Roman',serif;
-ms-text-size-adjust:100%;
-webkit-text-size-adjust:100%;
box-sizing:border-box;
@ -9,48 +10,41 @@
line-height:1.4;
overflow-y:scroll;
text-size-adjust:100%;
scroll-behavior: smooth;
scroll-behavior:smooth;
}
audio:not([controls])
{
audio:not([controls]) {
display:none;
}
details
{
details {
display:block;
}
input[type=search]
{
input[type=search] {
-webkit-appearance:textfield;
}
input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration
{
input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration {
-webkit-appearance:none;
}
main
{
main {
display:block;
margin:0 auto;
padding:0 1.6em 1.6em;
padding:0 1.6rem 1.6rem;
}
summary
{
summary {
display:block;
}
pre
{
pre {
background:#efefef;
color:#444;
display:block;
font-family:Menlo, Monaco, Consolas, 'Courier New', monospace;
font-family:var(--monospace-font-list);
font-size:1.4em;
font-size:1.4rem;
margin:1.6em 0;
@ -62,29 +56,24 @@ pre
word-wrap:break-word;
}
progress
{
progress {
display:inline-block;
}
small
{
small {
color:#777;
font-size:75%;
}
big
{
big {
font-size:125%;
}
template
{
template {
display:none;
}
textarea
{
textarea {
border:.1rem solid #ccc;
border-radius:0;
display:block;
@ -95,55 +84,47 @@ textarea
vertical-align:middle;
}
[hidden]
{
[hidden] {
display:none;
}
[unselectable]
{
[unselectable] {
-moz-user-select:none;
-ms-user-select:none;
-webkit-user-select:none;
user-select:none;
}
*,::before,::after
{
*,::before,::after {
border-style:solid;
border-width:0;
box-sizing:inherit;
}
*
{
* {
font-size:inherit;
line-height:inherit;
margin:0;
padding:0;
}
::before,::after
{
::before,::after {
text-decoration:inherit;
vertical-align:inherit;
}
a
{
a {
-webkit-transition:.25s ease;
color:#1271db;
text-decoration:none;
transition:.25s ease;
}
audio,canvas,iframe,img,svg,video
{
audio,canvas,iframe,img,svg,video {
vertical-align:middle;
}
button,input,select,textarea
{
button,input,select,textarea {
border:.1rem solid #ccc;
color:inherit;
font-family:inherit;
@ -152,37 +133,31 @@ button,input,select,textarea
min-height:1.4em;
}
code,kbd,pre,samp
{
font-family:Menlo, Monaco, Consolas, 'Courier New', monospace, monospace;
code,kbd,pre,samp {
font-family:var(--monospace-font-list);
}
table
{
table {
border-collapse:collapse;
border-spacing:0;
margin-bottom:1.6rem;
}
::-moz-selection
{
::-moz-selection {
background-color:#b3d4fc;
text-shadow:none;
}
::selection
{
::selection {
background-color:#b3d4fc;
text-shadow:none;
}
button::-moz-focus-inner
{
button::-moz-focus-inner {
border:0;
}
body
{
body {
color:#444;
font-family:var(--default-font-list);
font-size:1.6rem;
@ -191,20 +166,17 @@ body
padding:0;
}
p
{
p {
margin:0 0 1.6rem;
}
h1,h2,h3,h4,h5,h6
{
font-family:Lato, var(--default-font-list);
h1,h2,h3,h4,h5,h6 {
font-family:var(--default-font-list);
margin:2em 0 1.6em;
margin:2rem 0 1.6rem;
}
h1
{
h1 {
border-bottom:.1rem solid rgba(0,0,0,0.2);
font-size:3.6em;
font-size:3.6rem;
@ -212,16 +184,14 @@ h1
font-weight:500;
}
h2
{
h2 {
font-size:3em;
font-size:3rem;
font-style:normal;
font-weight:500;
}
h3
{
h3 {
font-size:2.4em;
font-size:2.4rem;
font-style:normal;
@ -229,8 +199,7 @@ h3
margin:1.6rem 0 .4rem;
}
h4
{
h4 {
font-size:1.8em;
font-size:1.8rem;
font-style:normal;
@ -238,8 +207,7 @@ h4
margin:1.6rem 0 .4rem;
}
h5
{
h5 {
font-size:1.6em;
font-size:1.6rem;
font-style:normal;
@ -247,8 +215,7 @@ h5
margin:1.6rem 0 .4rem;
}
h6
{
h6 {
color:#777;
font-size:1.4em;
font-size:1.4rem;
@ -257,66 +224,56 @@ h6
margin:1.6rem 0 .4rem;
}
code
{
code {
background:#efefef;
color:#444;
font-family:Menlo, Monaco, Consolas, 'Courier New', monospace;
font-family:var(--monospace-font-list);
font-size:1.4rem;
word-break:break-all;
word-wrap:break-word;
}
a:hover,a:focus
{
a:hover,a:focus {
text-decoration:none;
}
dl
{
dl {
margin-bottom:1.6rem;
}
dd
{
dd {
margin-left:4rem;
}
ul,ol
{
ul,ol {
margin-bottom:.8rem;
padding-left:2rem;
}
blockquote
{
blockquote {
border-left:.2rem solid #1271db;
font-family:Georgia, Times, 'Times New Roman', serif;
font-family:var(--serif-font-list);
font-style:italic;
margin:1.6rem 0;
padding-left:1.6rem;
}
figcaption
{
font-family:Georgia, Times, 'Times New Roman', serif;
figcaption {
font-family:var(--serif-font-list);
}
html
{
html {
font-size:62.5%;
}
main,header,footer,article,section,aside,details,summary
{
main,header,footer,article,section,aside,details,summary {
display:block;
height:auto;
margin:0 auto;
width:100%;
}
footer
{
footer {
border-top:.1rem solid rgba(0,0,0,0.2);
clear:both;
display:inline-block;
@ -326,23 +283,20 @@ footer
text-align:center;
}
hr
{
hr {
border-top:.1rem solid rgba(0,0,0,0.2);
display:block;
margin-bottom:1.6rem;
width:100%;
}
img
{
img {
height:auto;
/* max-width:100%; */
/* max-width:100%; */
vertical-align:baseline;
}
input[type=text],input[type=password],input[type=email],input[type=url],input[type=date],input[type=month],input[type=time],input[type=datetime],input[type=datetime-local],input[type=week],input[type=number],input[type=search],input[type=tel],input[type=color],select
{
input[type=text],input[type=password],input[type=email],input[type=url],input[type=date],input[type=month],input[type=time],input[type=datetime],input[type=datetime-local],input[type=week],input[type=number],input[type=search],input[type=tel],input[type=color],select {
border:.1rem solid #ccc;
border-radius:0;
display:inline-block;
@ -350,8 +304,7 @@ input[type=text],input[type=password],input[type=email],input[type=url],input[ty
vertical-align:middle;
}
input:not([type])
{
input:not([type]) {
-webkit-appearance:none;
background-clip:padding-box;
background-color:#fff;
@ -363,88 +316,73 @@ input:not([type])
text-align:left;
}
input[type=color]
{
input[type=color] {
padding:.8rem 1.6rem;
}
input[type=text]:focus,input[type=password]:focus,input[type=email]:focus,input[type=url]:focus,input[type=date]:focus,input[type=month]:focus,input[type=time]:focus,input[type=datetime]:focus,input[type=datetime-local]:focus,input[type=week]:focus,input[type=number]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=color]:focus,select:focus,textarea:focus
{
input[type=text]:focus,input[type=password]:focus,input[type=email]:focus,input[type=url]:focus,input[type=date]:focus,input[type=month]:focus,input[type=time]:focus,input[type=datetime]:focus,input[type=datetime-local]:focus,input[type=week]:focus,input[type=number]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=color]:focus,select:focus,textarea:focus {
border-color:#b3d4fc;
}
input:not([type]):focus
{
input:not([type]):focus {
border-color:#b3d4fc;
}
input[type=radio],input[type=checkbox]
{
input[type=radio],input[type=checkbox] {
vertical-align:middle;
}
input[type=file]:focus,input[type=radio]:focus,input[type=checkbox]:focus
{
input[type=file]:focus,input[type=radio]:focus,input[type=checkbox]:focus {
outline:.1rem solid thin #444;
}
input[type=text][disabled],input[type=password][disabled],input[type=email][disabled],input[type=url][disabled],input[type=date][disabled],input[type=month][disabled],input[type=time][disabled],input[type=datetime][disabled],input[type=datetime-local][disabled],input[type=week][disabled],input[type=number][disabled],input[type=search][disabled],input[type=tel][disabled],input[type=color][disabled],select[disabled],textarea[disabled]
{
input[type=text][disabled],input[type=password][disabled],input[type=email][disabled],input[type=url][disabled],input[type=date][disabled],input[type=month][disabled],input[type=time][disabled],input[type=datetime][disabled],input[type=datetime-local][disabled],input[type=week][disabled],input[type=number][disabled],input[type=search][disabled],input[type=tel][disabled],input[type=color][disabled],select[disabled],textarea[disabled] {
background-color:#efefef;
color:#777;
cursor:not-allowed;
}
input:not([type])[disabled]
{
input:not([type])[disabled] {
background-color:#efefef;
color:#777;
cursor:not-allowed;
}
input[readonly],select[readonly],textarea[readonly]
{
input[readonly],select[readonly],textarea[readonly] {
background-color:#efefef;
border-color:#ccc;
color:#777;
}
input:focus:invalid,textarea:focus:invalid,select:focus:invalid
{
input:focus:invalid,textarea:focus:invalid,select:focus:invalid {
border-color:#e9322d;
color:#b94a48;
}
input[type=file]:focus:invalid:focus,input[type=radio]:focus:invalid:focus,input[type=checkbox]:focus:invalid:focus
{
input[type=file]:focus:invalid:focus,input[type=radio]:focus:invalid:focus,input[type=checkbox]:focus:invalid:focus {
outline-color:#ff4136;
}
select
{
select {
background-color:#fff;
border:.1rem solid #ccc;
}
select[multiple]
{
select[multiple] {
height:auto;
}
label
{
label {
line-height:2;
}
fieldset
{
fieldset {
border:0;
margin:0;
padding:.8rem 0;
}
legend
{
legend {
border-bottom:.1rem solid #ccc;
color:#444;
display:block;
@ -453,8 +391,7 @@ legend
width:100%;
}
input[type=submit],button
{
input[type=submit],button {
-moz-user-select:none;
-ms-user-select:none;
-webkit-transition:.25s ease;
@ -476,62 +413,52 @@ input[type=submit],button
vertical-align:baseline;
}
input[type=submit] a,button a
{
input[type=submit] a,button a {
color:#444;
}
input[type=submit]::-moz-focus-inner,button::-moz-focus-inner
{
input[type=submit]::-moz-focus-inner,button::-moz-focus-inner {
padding:0;
}
input[type=submit]:hover,button:hover
{
input[type=submit]:hover,button:hover {
background:#444;
border-color:#444;
color:#fff;
}
input[type=submit]:hover a,button:hover a
{
input[type=submit]:hover a,button:hover a {
color:#fff;
}
input[type=submit]:active,button:active
{
input[type=submit]:active,button:active {
background:#6a6a6a;
border-color:#6a6a6a;
color:#fff;
}
input[type=submit]:active a,button:active a
{
input[type=submit]:active a,button:active a {
color:#fff;
}
input[type=submit]:disabled,button:disabled
{
input[type=submit]:disabled,button:disabled {
box-shadow:none;
cursor:not-allowed;
opacity:.40;
opacity:.4;
}
nav ul
{
nav ul {
list-style:none;
margin:0;
padding:0;
text-align:center;
}
nav ul li
{
nav ul li {
display:inline;
}
nav a
{
nav a {
-webkit-transition:.25s ease;
border-bottom:.2rem solid transparent;
color:#444;
@ -540,48 +467,40 @@ nav a
transition:.25s ease;
}
nav a:hover,nav li.selected a
{
nav a:hover,nav li.selected a {
border-color:rgba(0,0,0,0.2);
}
nav a:active
{
nav a:active {
border-color:rgba(0,0,0,0.56);
}
caption
{
caption {
padding:.8rem 0;
}
thead th
{
thead th {
background:#efefef;
color:#444;
}
tr
{
tr {
background:#fff;
margin-bottom:.8rem;
}
th,td
{
th,td {
border:.1rem solid #ccc;
padding:.8rem 1.6rem;
text-align:center;
vertical-align:inherit;
}
tfoot tr
{
tfoot tr {
background:none;
}
tfoot td
{
tfoot td {
color:#efefef;
font-size:.8rem;
font-style:italic;
@ -589,28 +508,24 @@ tfoot td
}
@media screen {
[hidden~=screen]
{
[hidden~=screen] {
display:inherit;
}
[hidden~=screen]:not(:active):not(:focus):not(:target)
{
[hidden~=screen]:not(:active):not(:focus):not(:target) {
clip:rect(0000)!important;
position:absolute!important;
}
}
@media screen and max-width 40rem {
article,section,aside
{
article,section,aside {
clear:both;
display:block;
max-width:100%;
}
img
{
img {
margin-right:1.6rem;
}
}

3
public/cssfilter.js Normal file
View File

@ -0,0 +1,3 @@
module.exports = function filter(filename) {
return ! String(filename).includes('min');
}

View File

@ -22,29 +22,48 @@ use Aviat\Ion\Json;
// Include guzzle
require_once('../vendor/autoload.php');
require_once('./min.php');
//Creative rewriting of /g/groupname to ?g=groupname
$pi = $_SERVER['PATH_INFO'];
$pia = explode('/', $pi);
$piaLen = count($pia);
$i = 1;
while($i < $piaLen)
{
$j = $i+1;
$j = (isset($pia[$j])) ? $j : $i;
$_GET[$pia[$i]] = $pia[$j];
$i = $j + 1;
};
class FileNotChangedException extends \Exception {}
/**
* Simple Javascript minfier, using google closure compiler
*/
class JSMin extends BaseMin {
class JSMin {
protected $jsRoot;
protected $jsGroup;
protected $jsGroupsFile;
protected $configFile;
protected $cacheFile;
protected $lastModified;
protected $requestedTime;
protected $cacheModified;
public function __construct(array $config, array $groups)
public function __construct(array $config, string $configFile)
{
$group = $_GET['g'];
$groups = $config['groups'];
$this->jsRoot = $config['js_root'];
$this->jsGroup = $groups[$group];
$this->jsGroupsFile = $config['js_groups_file'];
$this->configFile = $configFile;
$this->cacheFile = "{$this->jsRoot}cache/{$group}";
$this->lastModified = $this->getLastModified();
@ -99,7 +118,7 @@ class JSMin extends BaseMin {
protected function closureCall(array $options)
{
$formFields = http_build_query($options);
$request = (new Request)
->setMethod('POST')
->setUri('http://closure-compiler.appspot.com/compile')
@ -109,7 +128,7 @@ class JSMin extends BaseMin {
'Content-type' => 'application/x-www-form-urlencoded'
])
->setBody($formFields);
$response = wait((new Client)->request($request, [
Client::OP_AUTO_ENCODING => false
]));
@ -128,7 +147,7 @@ class JSMin extends BaseMin {
$errorRes = $this->closureCall($options);
$errorJson = $errorRes->getBody();
$errorObj = Json::decode($errorJson) ?: (object)[];
// Show error if exists
if ( ! empty($errorObj->errors) || ! empty($errorObj->serverErrors))
@ -178,7 +197,7 @@ class JSMin extends BaseMin {
//Add this page too, as well as the groups file
$modified[] = filemtime(__FILE__);
$modified[] = filemtime($this->jsGroupsFile);
$modified[] = filemtime($this->configFile);
rsort($modified);
$lastModified = $modified[0];
@ -227,14 +246,97 @@ class JSMin extends BaseMin {
{
$this->sendFinalOutput($js, 'application/javascript', $this->lastModified);
}
/**
* Get value of the if-modified-since header
*
* @return int - timestamp to compare for cache control
*/
protected function getIfModified()
{
return (array_key_exists('HTTP_IF_MODIFIED_SINCE', $_SERVER))
? strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE'])
: time();
}
/**
* Get value of etag to compare to hash of output
*
* @return string - the etag to compare
*/
protected function getIfNoneMatch()
{
return (array_key_exists('HTTP_IF_NONE_MATCH', $_SERVER))
? $_SERVER['HTTP_IF_NONE_MATCH']
: '';
}
/**
* Determine whether or not to send debug version
*
* @return boolean
*/
protected function isNotDebug()
{
return ! $this->isDebugCall();
}
/**
* Determine whether or not to send debug version
*
* @return boolean
*/
protected function isDebugCall()
{
return array_key_exists('debug', $_GET);
}
/**
* Send actual output to browser
*
* @param string $content - the body of the response
* @param string $mimeType - the content type
* @param int $lastModified - the last modified date
* @return void
*/
protected function sendFinalOutput($content, $mimeType, $lastModified)
{
//This GZIPs the CSS for transmission to the user
//making file size smaller and transfer rate quicker
ob_start("ob_gzhandler");
$expires = $lastModified + 691200;
$lastModifiedDate = gmdate('D, d M Y H:i:s', $lastModified);
$expiresDate = gmdate('D, d M Y H:i:s', $expires);
header("Content-Type: {$mimeType}; charset=utf8");
header("Cache-control: public, max-age=691200, must-revalidate");
header("Last-Modified: {$lastModifiedDate} GMT");
header("Expires: {$expiresDate} GMT");
echo $content;
ob_end_flush();
}
/**
* Send a 304 Not Modified header
*
* @return void
*/
public static function send304()
{
header("status: 304 Not Modified", true, 304);
}
}
// --------------------------------------------------------------------------
// ! Start Minifying
// --------------------------------------------------------------------------
$config = require_once('../app/appConf/minify_config.php');
$groups = require_once($config['js_groups_file']);
$configFile = realpath(__DIR__ . '/../app/appConf/minify_config.php');
$config = require_once($configFile);
$groups = $config['groups'];
$cacheDir = "{$config['js_root']}cache";
if ( ! is_dir($cacheDir))
@ -249,11 +351,11 @@ if ( ! array_key_exists($_GET['g'], $groups))
try
{
new JSMin($config, $groups);
new JSMin($config, $configFile);
}
catch (FileNotChangedException $e)
{
BaseMin::send304();
JSMin::send304();
}
//end of js.php

View File

@ -1,121 +0,0 @@
<?php declare(strict_types=1);
/**
* Hummingbird Anime List Client
*
* An API client for Kitsu and MyAnimeList to manage anime and manga watch lists
*
* PHP version 7
*
* @package HummingbirdAnimeClient
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2015 - 2017 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 4.0
* @link https://github.com/timw4mail/HummingBirdAnimeClient
*/
namespace Aviat\EasyMin;
//Creative rewriting of /g/groupname to ?g=groupname
$pi = $_SERVER['PATH_INFO'];
$pia = explode('/', $pi);
$piaLen = count($pia);
$i = 1;
while($i < $piaLen)
{
$j = $i+1;
$j = (isset($pia[$j])) ? $j : $i;
$_GET[$pia[$i]] = $pia[$j];
$i = $j + 1;
};
class FileNotChangedException extends \Exception {}
class BaseMin {
/**
* Get value of the if-modified-since header
*
* @return int - timestamp to compare for cache control
*/
protected function getIfModified()
{
return (array_key_exists('HTTP_IF_MODIFIED_SINCE', $_SERVER))
? strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE'])
: time();
}
/**
* Get value of etag to compare to hash of output
*
* @return string - the etag to compare
*/
protected function getIfNoneMatch()
{
return (array_key_exists('HTTP_IF_NONE_MATCH', $_SERVER))
? $_SERVER['HTTP_IF_NONE_MATCH']
: '';
}
/**
* Determine whether or not to send debug version
*
* @return boolean
*/
protected function isNotDebug()
{
return ! $this->isDebugCall();
}
/**
* Determine whether or not to send debug version
*
* @return boolean
*/
protected function isDebugCall()
{
return array_key_exists('debug', $_GET);
}
/**
* Send actual output to browser
*
* @param string $content - the body of the response
* @param string $mimeType - the content type
* @param int $lastModified - the last modified date
* @return void
*/
protected function sendFinalOutput($content, $mimeType, $lastModified)
{
//This GZIPs the CSS for transmission to the user
//making file size smaller and transfer rate quicker
ob_start("ob_gzhandler");
$expires = $lastModified + 691200;
$lastModifiedDate = gmdate('D, d M Y H:i:s', $lastModified);
$expiresDate = gmdate('D, d M Y H:i:s', $expires);
header("Content-Type: {$mimeType}; charset=utf8");
header("Cache-control: public, max-age=691200, must-revalidate");
header("Last-Modified: {$lastModifiedDate} GMT");
header("Expires: {$expiresDate} GMT");
echo $content;
ob_end_flush();
}
/**
* Send a 304 Not Modified header
*
* @return void
*/
public static function send304()
{
header("status: 304 Not Modified", true, 304);
}
}

View File

@ -1,14 +1,13 @@
{
"scripts": {
"build": "postcss -u postcss-import --autoprefixer.browsers \"> 5%\" -u postcss-cssnext -o css/base.css css/base.myth.css",
"watch": "postcss -u postcss-import --autoprefixer.browsers \"> 5%\" -u postcss-cssnext -w -o css/base.css css/base.myth.css"
"build": "node ./css.js",
"watch": "watch 'npm run build' --filter=./cssfilter.js"
},
"devDependencies": {
"autoprefixer": "^6.6.1",
"npm-run-all": "^4.0.0",
"cssnano": "^3.10.0",
"postcss-cachify": "^1.3.1",
"postcss-cli": "^3.1",
"postcss-cssnext": "^2.9.0",
"postcss-import": "^9.0.0"
"postcss-import": "^9.0.0",
"watch": "^1.0.2"
}
}

File diff suppressed because it is too large Load Diff