[Cleanup] Minify JavaScript and CSS to reduce sketch size

Sketch size is reduced by 5 - 6 kB
Files are extracted from original source and moved to `static` directory.
This commit is contained in:
TD-er
2018-10-31 16:25:42 +01:00
parent 1f1e47530a
commit 9eb2ebe210
12 changed files with 942 additions and 412 deletions
+82
View File
@@ -0,0 +1,82 @@
#!/bin/bash
#
# This script walks through the assets folder and minifys all JS, HTML, CSS and SVG files. It also generates
# the corresponding constants that are added to the data.h file on esp8266_deauther folder.
#
# @Author Erick B. Tedeschi < erickbt86 [at] gmail [dot] com >
# @Author Wandmalfarbe https://github.com/Wandmalfarbe
#
# See: https://github.com/letscontrolit/ESPEasy/issues/1671#issuecomment-415144898
outputfile="$(pwd)/data_h_temp"
rm $outputfile
function minify_html_css {
file=$1
curl -X POST -s --data-urlencode "input@$file" http://html-minifier.com/raw > /tmp/converter.temp
}
function minify_js {
file=$1
curl -X POST -s --data-urlencode "input@$file" https://javascript-minifier.com/raw > /tmp/converter.temp
}
function minify_svg {
file=$1
svgo -i /Users/User/Desktop/icons/tools.svg -o - > /tmp/converter.temp
}
function ascii2hexCstyle {
file_name=$(constFileName $1)
result=$(cat /tmp/converter.temp | hexdump -ve '1/1 "0x%.2x,"')
result=$(echo $result | sed 's/,$//')
echo "const char DATA_${file_name}[] PROGMEM = {$result};"
}
function constFileName {
extension=$(echo $1 | egrep -io "(json|svg|css|js|html)$" | tr "[:lower:]" "[:upper:]")
file=$(echo $1 | sed 's/\.json//' | sed 's/\.svg//' | sed 's/\.css//' | sed 's/\.html//' | sed 's/\.js//' | sed 's/\.\///' | tr '/' '_' | tr '.' '_' | tr '-' '_' | tr "[:lower:]" "[:upper:]")
underscore="_"
echo $file$underscore$extension
}
cd static
file_list=$(find . -type f)
for file in $file_list; do
echo "Processing: $file"
file_name=$(constFileName $file)
echo " Array Name: $file_name"
if [[ "$file" == *.min.js ]]; then
echo " JS already minified"
cat $file > /tmp/converter.temp
ascii2hexCstyle $file >> $outputfile
elif [[ "$file" == *.js ]]; then
echo " JS minify"
minify_js $file
ascii2hexCstyle $file >> $outputfile
elif [[ "$file" == *.min.css ]]; then
echo " CSS already minified"
cat $file > /tmp/converter.temp
ascii2hexCstyle $file >> $outputfile
elif [[ "$file" == *.html ]] || [[ "$file" == *.css ]]; then
echo " HTML and CSS minify"
minify_html_css $file
ascii2hexCstyle $file >> $outputfile
elif [[ "$file" == *.svg ]]; then
echo " SVG minify"
minify_svg $file
ascii2hexCstyle $file >> $outputfile
else
echo " without minifier"
cat $file > /tmp/converter.temp
ascii2hexCstyle $file >> $outputfile
fi
echo ""
sleep 1
done
+40 -18
View File
@@ -288,8 +288,10 @@ void sendHeadandTail(const String& tmplName, boolean Tail = false, boolean reboo
}
}
if (shouldReboot) {
//we only add this here as a seperate chucnk to prevent using too much memory at once
TXBuffer += jsReboot;
//we only add this here as a seperate chunk to prevent using too much memory at once
html_add_script(false);
TXBuffer += DATA_REBOOT_JS;
html_add_script_end();
}
}
@@ -732,7 +734,7 @@ void getWebPageTemplateVar(const String& varName )
{
TXBuffer += F("<style>");
// Send CSS per chunk to avoid sending either too short or too large strings.
TXBuffer += pgDefaultCSS;
TXBuffer += DATA_ESPEASY_DEFAULT_MIN_CSS;
TXBuffer += F("</style>");
}
}
@@ -783,7 +785,7 @@ void writeDefaultCSS(void)
log += F(" bytes)");
addLog(LOG_LEVEL_INFO, log);
}
defaultCSS= PGMT(pgDefaultCSS);
defaultCSS= PGMT(DATA_ESPEASY_DEFAULT_MIN_CSS);
f.write((const unsigned char*)defaultCSS.c_str(), defaultCSS.length()); //note: content must be in RAM - a write of F("XXX") does not work
f.close();
}
@@ -2030,7 +2032,9 @@ void handle_devices() {
// show all tasks as table
if (taskIndexNotSet)
{
TXBuffer += jsUpdateSensorValuesDevicePage;
html_add_script(true);
TXBuffer += DATA_UPDATE_SENSOR_VALUES_DEVICE_PAGE_JS;
html_add_script_end();
html_table_class_multirow();
html_TR();
html_table_header("", 70);
@@ -3180,6 +3184,19 @@ void html_add_autosubmit_form() {
"\n//--></script>");
}
void html_add_script(bool defer) {
TXBuffer += F("<script");
if (defer) {
TXBuffer += F(" defer");
}
TXBuffer += F(" type='text/JavaScript'>");
}
void html_add_script_end() {
TXBuffer += F("</script>");
}
//********************************************************************************
// Add a task select dropdown list
//********************************************************************************
@@ -3264,7 +3281,9 @@ void handle_log() {
addCheckBox(F("autoscroll"), true);
TXBuffer += F("<BR></body>");
TXBuffer += jsFetchAndParseLog;
html_add_script(true);
TXBuffer += DATA_FETCH_AND_PARSE_LOG_JS;
html_add_script_end();
sendHeadandTail_stdtemplate(_TAIL);
TXBuffer.endStream();
@@ -5212,7 +5231,7 @@ void handle_setup() {
TXBuffer += F("timedRefresh(");
TXBuffer += wait;
TXBuffer += F(");");
TXBuffer += F("</script>");
html_add_script_end();
TXBuffer += F("seconds while trying to connect");
}
refreshCount++;
@@ -5389,20 +5408,23 @@ void handle_sysinfo() {
int freeMem = ESP.getFreeHeap();
addHeader(true, TXBuffer.buf);
TXBuffer += printWebString;
TXBuffer += F("<form>");
TXBuffer += printWebString;
TXBuffer += F("<form>");
// the table header
html_table_class_normal();
html_TR();
html_table_header(F("System Info"));
TXBuffer += F("<TH align='left'>");
addCopyButton(F("copyText"), F("\\n"), F("Copy info to clipboard") );
// the table header
html_table_class_normal();
html_TR();
html_table_header(F("System Info"));
TXBuffer += F("<TH align='left'>");
addCopyButton(F("copyText"), F("\\n"), F("Copy info to clipboard") );
TXBuffer += githublogo;
TXBuffer += githublogo;
html_add_script(false);
TXBuffer += DATA_GITHUB_CLIPBOARD_JS;
html_add_script_end();
addRowLabel(F("Unit"));
TXBuffer += Settings.Unit;
addRowLabel(F("Unit"));
TXBuffer += Settings.Unit;
if (Settings.UseNTP)
{
+5 -394
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+539
View File
@@ -0,0 +1,539 @@
* {
box-sizing: border-box;
font-family: sans-serif;
font-size: 12pt;
margin: 0;
padding: 0
}
h1 {
color: #07D;
font-size: 16pt;
font-weight: 700;
margin: 8px 0
}
h2 {
background-color: #444;
color: #FFF;
font-size: 12pt;
font-weight: 700;
margin: 0 -4px;
padding: 6px
}
h3 {
background-color: #EEE;
color: #444;
font-size: 12pt;
font-weight: 700;
margin: 16px -4px 0;
padding: 4px
}
h6 {
color: #07D;
font-size: 10pt
}
pre,
xmp,
code,
kbd,
samp,
tt {
font-family: monospace, monospace;
font-size: 1em
}
.button {
background-color: #07D;
border: none;
border-radius: 4px;
color: #FFF;
margin: 4px;
padding: 4px 16px;
text-decoration: none
}
.button.link.wide {
display: inline-block;
text-align: center;
width: 100%
}
.button.link.red {
background-color: red
}
.button.help {
border-color: gray;
border-radius: 50%;
border-style: solid;
border-width: 1px;
padding: 2px 4px
}
.button:hover {
background: #369
}
input,
select,
textarea {
background-color: #eee;
border-color: gray;
border-radius: 4px;
border-style: solid;
border-width: 1px;
margin: 4px;
padding: 4px 8px
}
input:hover {
background-color: #ccc
}
input.wide {
max-width: 500px;
width: 80%
}
input.widenumber {
max-width: 500px;
width: 100px
}
#selectwidth {
max-width: 500px;
padding: 4px 8px;
width: 80%
}
select:hover {
background-color: #ccc
}
.container {
-moz-user-select: none;
-ms-user-select: none;
-webkit-user-select: none;
cursor: pointer;
display: block;
font-size: 12pt;
margin-left: 4px;
margin-top: 0;
padding-left: 35px;
position: relative;
user-select: none
}
.container input {
cursor: pointer;
opacity: 0;
position: absolute
}
.checkmark {
background-color: #eee;
border-color: gray;
border-radius: 4px;
border-style: solid;
border-width: 1px;
height: 25px;
left: 0;
position: absolute;
top: 0;
width: 25px
}
.container:hover input~.checkmark {
background-color: #ccc
}
.container input:checked~.checkmark {
background-color: #07D
}
.checkmark:after {
content: '';
display: none;
position: absolute
}
.container input:checked~.checkmark:after {
display: block
}
.container .checkmark:after {
-ms-transform: rotate(45deg);
-webkit-transform: rotate(45deg);
border: solid #fff;
border-width: 0 3px 3px 0;
height: 10px;
left: 7px;
top: 3px;
transform: rotate(45deg);
width: 5px
}
.container2 {
-moz-user-select: none;
-ms-user-select: none;
-webkit-user-select: none;
cursor: pointer;
display: block;
font-size: 12pt;
margin-bottom: 20px;
margin-left: 9px;
padding-left: 35px;
position: relative;
user-select: none
}
.container2 input {
cursor: pointer;
opacity: 0;
position: absolute
}
.dotmark {
background-color: #eee;
border-color: gray;
border-radius: 50%;
border-style: solid;
border-width: 1px;
height: 26px;
left: 0;
position: absolute;
top: 0;
width: 26px
}
.container2:hover input~.dotmark {
background-color: #ccc
}
.container2 input:checked~.dotmark {
background-color: #07D
}
.dotmark:after {
content: '';
display: none;
position: absolute
}
.container2 input:checked~.dotmark:after {
display: block
}
.container2 .dotmark:after {
background: #fff;
border-radius: 50%;
height: 8px;
left: 8px;
top: 8px;
width: 8px
}
#toastmessage {
background-color: #07D;
border-color: gray;
border-radius: 4px;
border-style: solid;
border-width: 1px;
bottom: 30%;
color: #fff;
font-size: 17px;
left: 282px;
margin-left: -125px;
min-width: 250px;
padding: 16px;
position: fixed;
text-align: center;
visibility: hidden;
z-index: 1
}
#toastmessage.show {
-webkit-animation: fadein 0.5s, fadeout .5s 2.5s;
animation: fadein 0.5s, fadeout .5s 2.5s;
visibility: visible
}
@-webkit-keyframes fadein {
from {
bottom: 20%;
opacity: 0
}
to {
bottom: 30%;
opacity: .9
}
}
@keyframes fadein {
from {
bottom: 20%;
opacity: 0
}
to {
bottom: 30%;
opacity: .9
}
}
@-webkit-keyframes fadeout {
from {
bottom: 30%;
opacity: .9
}
to {
bottom: 0;
opacity: 0
}
}
@keyframes fadeout {
from {
bottom: 30%;
opacity: .9
}
to {
bottom: 0;
opacity: 0
}
}
.level_0 {
color: #F1F1F1
}
.level_1 {
color: #FCFF95
}
.level_2 {
color: #9DCEFE
}
.level_3 {
color: #A4FC79
}
.level_4 {
color: #F2AB39
}
.level_9 {
color: #F50
}
.logviewer {
background-color: #272727;
border-color: gray;
border-style: solid;
color: #F1F1F1;
font-family: 'Lucida Console', Monaco, monospace;
height: 530px;
max-width: 1000px;
overflow: auto;
padding: 4px 8px;
width: 80%
}
textarea {
font-family: 'Lucida Console', Monaco, monospace;
max-width: 1000px;
padding: 4px 8px;
width: 80%
}
textarea:hover {
background-color: #ccc
}
table.normal th {
background-color: #444;
border-color: #888;
color: #FFF;
font-weight: 700;
padding: 6px
}
table.normal td {
height: 30px;
padding: 4px
}
table.normal tr {
padding: 4px
}
table.normal {
border-collapse: collapse;
color: #000;
min-width: 420px;
width: 100%
}
table.multirow th {
background-color: #444;
border-color: #888;
color: #FFF;
font-weight: 700;
padding: 6px
}
table.multirow td {
height: 30px;
padding: 4px;
text-align: center
}
table.multirow tr {
padding: 4px
}
table.multirow tr:nth-child(even) {
background-color: #DEE6FF
}
table.multirow {
border-collapse: collapse;
color: #000;
min-width: 420px;
width: 100%
}
tr.highlight td {
background-color: #dbff0075
}
.note {
color: #444;
font-style: italic
}
.headermenu {
background-color: #F8F8F8;
border-bottom: 1px solid #DDD;
height: 90px;
left: 0;
padding: 8px 12px;
position: fixed;
right: 0;
top: 0;
z-index: 1
}
.apheader {
background-color: #F8F8F8;
padding: 8px 12px
}
.bodymenu {
margin-top: 96px
}
.menubar {
position: inherit;
top: 55px
}
.menu {
border: solid transparent;
border-radius: 4px 4px 0 0;
border-width: 4px 1px 1px;
color: #444;
float: left;
padding: 4px 16px 8px;
text-decoration: none;
white-space: nowrap
}
.menu.active {
background-color: #FFF;
border-color: #07D #DDD #FFF;
color: #000
}
.menu:hover {
background: #DEF;
color: #000
}
.menu_button {
display: none
}
.on {
color: green
}
.off {
color: red
}
.div_l {
float: left
}
.div_r {
background-color: #080;
border-radius: 4px;
color: #fff;
float: right;
margin: 2px;
padding: 1px 10px
}
.div_br {
clear: both
}
.alert {
background-color: #f44336;
color: #fff;
margin-bottom: 15px;
padding: 20px
}
.warning {
background-color: #ffca17;
color: #fff;
margin-bottom: 15px;
padding: 20px
}
.closebtn {
color: #fff;
cursor: pointer;
float: right;
font-size: 22px;
font-weight: 700;
line-height: 20px;
margin-left: 15px;
transition: .3s
}
.closebtn:hover {
color: #000
}
section {
overflow-x: auto;
width: 100%
}
@media screen and (max-width: 960px) {
span.showmenulabel {
display: none
}
.menu {
max-width: 11vw;
max-width: 48px
}
}
File diff suppressed because one or more lines are too long
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

+121
View File
@@ -0,0 +1,121 @@
function getBrowser() {
var ua = navigator.userAgent,
tem, M = ua.match(/(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i) || [];
if (/trident/i.test(M[1])) {
tem = /\brv[ :]+(\d+)/g.exec(ua) || [];
return {
name: 'IE',
version: (tem[1] || '')
};
}
if (M[1] === 'Chrome') {
tem = ua.match(/\bOPR|Edge\/(\d+)/);
if (tem != null) {
return {
name: 'Opera',
version: tem[1]
};
}
}
M = M[2] ? [M[1], M[2]] : [navigator.appName, navigator.appVersion, '-?'];
if ((tem = ua.match(/version\/(\d+)/i)) != null) {
M.splice(1, 1, tem[1]);
}
return {
name: M[0],
version: M[1]
};
}
var browser = getBrowser();
var currentBrowser = browser.name + browser.version;
if (browser.name = 'IE' && browser.version < 12) {
textToDisplay = 'Error: ' + currentBrowser + ' is not supported! Please try a modern web browser.'
} else {
textToDisplay = 'Fetching log entries...';
}
document.getElementById('copyText_1').innerHTML = textToDisplay;
loopDeLoop(1000, 0);
var logLevel = new Array('Unused', 'Error', 'Info', 'Debug', 'Debug More', 'Undefined', 'Undefined', 'Undefined', 'Undefined', 'Debug Dev');
function loopDeLoop(timeForNext, activeRequests) {
var maximumRequests = 1;
var url = '/logjson';
if (isNaN(activeRequests)) {
activeRequests = maximumRequests;
}
if (timeForNext == null) {
timeForNext = 1000;
}
if (timeForNext <= 500) {
scrolling_type = 'auto';
} else {
scrolling_type = 'smooth';
}
var c;
var logEntriesChunk;
var currentIDtoScrollTo = '';
var check = 0;
var i = setInterval(function() {
if (check > 0) {
clearInterval(i);
return;
}
++activeRequests;
if (activeRequests > maximumRequests) {
check = 1;
} else {
fetch(url).then(function(response) {
if (response.status !== 200) {
console.log('Looks like there was a problem. Status Code: ' + response.status);
return;
}
response.json().then(function(data) {
var logEntry;
if (logEntriesChunk == null) {
logEntriesChunk = '';
}
for (c = 0; c < data.Log.nrEntries; ++c) {
try {
logEntry = data.Log.Entries[c].timestamp;
} catch (err) {
logEntry = err.name;
} finally {
if (logEntry !== "TypeError") {
currentIDtoScrollTo = data.Log.Entries[c].timestamp;
logEntriesChunk += '<div class=level_' + data.Log.Entries[c].level + ' id=' + currentIDtoScrollTo + '><font color="gray">' + data.Log.Entries[c].timestamp + ':</font> ' + data.Log.Entries[c].text + '</div>';
}
}
}
timeForNext = data.Log.TTL;
if (logEntriesChunk !== '') {
if (document.getElementById('copyText_1').innerHTML == 'Fetching log entries...') {
document.getElementById('copyText_1').innerHTML = '';
}
document.getElementById('copyText_1').innerHTML += logEntriesChunk;
}
logEntriesChunk = '';
autoscroll_on = document.getElementById('autoscroll').checked;
if (autoscroll_on == true && currentIDtoScrollTo !== '') {
document.getElementById(currentIDtoScrollTo).scrollIntoView({
behavior: scrolling_type
});
}
document.getElementById('current_loglevel').innerHTML = 'Logging: ' + logLevel[data.Log.SettingsWebLogLevel] + ' (' + data.Log.SettingsWebLogLevel + ')';
clearInterval(i);
loopDeLoop(timeForNext, 0);
return;
})
}).catch(function(err) {
document.getElementById('copyText_1').innerHTML += '<div>>> ' + err.message + ' <<</div>';
autoscroll_on = document.getElementById('autoscroll').checked;
document.getElementById('copyText_1').scrollTop = document.getElementById('copyText_1').scrollHeight;
timeForNext = 5000;
clearInterval(i);
loopDeLoop(timeForNext, 0);
return;
})
};
check = 1;
}, timeForNext);
}
+27
View File
@@ -0,0 +1,27 @@
function setGithubClipboard() {
var clipboard = 'ESP Easy | Information |\n -----|-----|\n';
max_loop = 100;
for (var i = 1; i < max_loop; i++) {
var cur_id = 'copyText_' + i;
var test = document.getElementById(cur_id);
if (test == null) {
i = max_loop + 1;
} else {
var separatorSymbol = '|';
if (i % 2 == 0) {
separatorSymbol += '\n'
}
clipboard += test.innerHTML.replace(/<[Bb][Rr]\s*\/?>/gim, '\n') + separatorSymbol;
}
}
clipboard = clipboard.replace(/<\/[Dd][Ii][Vv]\s*\/?>/gim, '\n');
clipboard = clipboard.replace(/<[^>]*>/gim, '');
var tempInput = document.createElement('textarea');
tempInput.style = 'position: absolute;left: -1000px; top: -1000px';
tempInput.innerHTML = clipboard;
document.body.appendChild(tempInput);
tempInput.select();
document.execCommand('copy');
document.body.removeChild(tempInput);
alert('Copied: "' + clipboard + '" to clipboard!')
}
+33
View File
@@ -0,0 +1,33 @@
i = document.getElementById('rbtmsg');
i.innerHTML = "Please reboot: <input id='reboot' class='button link' value='Reboot' type='submit' onclick='r()'>";
var x = new XMLHttpRequest();
//done
function d() {
i.innerHTML = '';
clearTimeout(t);
}
//keep requesting mainpage until no more errors
function c() {
i.innerHTML += '.';
x.onload = d;
x.open('GET', window.location.origin);
x.send();
}
//rebooting
function b() {
i.innerHTML = 'Rebooting..';
t = setInterval(c, 2000);
}
//request reboot
function r() {
i.innerHTML += ' (requesting)';
x.onload = b;
x.open('GET', window.location.origin + '/?cmd=reboot');
x.send();
}
+11
View File
@@ -0,0 +1,11 @@
function timedRefresh(timeoutPeriod) {
var timer = setInterval(function() {
if (timeoutPeriod > 0) {
timeoutPeriod -= 1;
document.getElementById('countdown').innerHTML = timeoutPeriod + '..' + '<br />';
} else {
clearInterval(timer);
window.location.href = window.location.href;
};
}, 1000);
};
@@ -0,0 +1,75 @@
loopDeLoop(1000, 0);
function loopDeLoop(timeForNext, activeRequests) {
var maximumRequests = 1;
var c;
var k;
var err = '';
var url = '/json?view=sensorupdate';
var check = 0;
if (isNaN(activeRequests)) {
activeRequests = maximumRequests;
}
if (timeForNext == null) {
timeForNext = 1000;
}
var i = setInterval(function() {
if (check > 0) {
clearInterval(i);
return;
}
++activeRequests;
if (activeRequests > maximumRequests) {
check = 1;
} else {
fetch(url).then(function(response) {
var valueEntry;
if (response.status !== 200) {
console.log('Looks like there was a problem. Status Code: ' + response.status);
return;
}
response.json().then(function(data) {
timeForNext = data.TTL;
for (c = 0; c < data.Sensors.length; c++) {
if (data.Sensors[c].hasOwnProperty('TaskValues')) {
for (k = 0; k < data.Sensors[c].TaskValues.length; k++) {
try {
valueEntry = data.Sensors[c].TaskValues[k].Value;
} catch (err) {
valueEntry = err.name;
} finally {
if (valueEntry !== 'TypeError') {
tempValue = data.Sensors[c].TaskValues[k].Value;
decimalsValue = data.Sensors[c].TaskValues[k].NrDecimals;
tempValue = parseFloat(tempValue).toFixed(decimalsValue);
var valueID = 'value_' + (data.Sensors[c].TaskNumber - 1) + '_' + (data.Sensors[c].TaskValues[k].ValueNumber - 1);
var valueNameID = 'valuename_' + (data.Sensors[c].TaskNumber - 1) + '_' + (data.Sensors[c].TaskValues[k].ValueNumber - 1);
var valueElement = document.getElementById(valueID);
var valueNameElement = document.getElementById(valueNameID);
if (valueElement !== null) {
valueElement.innerHTML = tempValue;
}
if (valueNameElement !== null) {
valueNameElement.innerHTML = data.Sensors[c].TaskValues[k].Name + ':';
}
}
}
}
}
}
timeForNext = data.TTL;
clearInterval(i);
loopDeLoop(timeForNext, 0);
return;
});
}).catch(function(err) {
console.log(err.message);
timeForNext = 5000;
clearInterval(i);
loopDeLoop(timeForNext, 0);
return;
});
check = 1;
}
}, timeForNext);
}