webpack-plugin-serve
Version:
A Development Server in a Webpack Plugin
171 lines (141 loc) • 3.97 kB
JavaScript
/*
Copyright © 2018 Andrew Powell, Matheus Gonçalves da Silva
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of this Source Code Form.
*/
const { addCss, addHtml } = require('./util');
const ns = 'wps-progress';
const css = `
#${ns}{
width: 200px;
height: 200px;
position: fixed;
right: 5%;
top: 5%;
transition: opacity .25s ease-in-out;
z-index: 2147483645;
}
#${ns}-bg {
fill: #282d35;
}
#${ns}-fill {
fill: rgba(0, 0, 0, 0);
stroke: rgb(186, 223, 172);
stroke-dasharray: 219.99078369140625;
stroke-dashoffset: -219.99078369140625;
stroke-width: 10;
transform: rotate(90deg)translate(0px, -80px);
}
#${ns}-percent {
font-family: 'Open Sans';
font-size: 18px;
fill: #ffffff;
}
#${ns}-percent-value {
dominant-baseline: middle;
text-anchor: middle;
}
#${ns}-percent-super {
fill: #bdc3c7;
font-size: .45em;
baseline-shift: 10%;
}
.${ns}-noselect {
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
cursor: default;
}
@keyframes ${ns}-fade {
0% {
opacity: 1;
transform: scale(1);
-webkit-transform: scale(1);
}
100% {
opacity: 0;
transform: scale(0);
-webkit-transform: scale(0);
}
}
.${ns}-disappear {
animation: ${ns}-fade .3s;
animation-fill-mode:forwards;
animation-delay: .5s;
}
.${ns}-hidden {
display: none;
}
/* Put google web font at the end, or you'll see FOUC in Firefox */
@import url('https://fonts.googleapis.com/css?family=Open+Sans:400,700');
`;
const html = `
<svg id="${ns}" class="${ns}-noselect ${ns}-hidden" x="0px" y="0px" viewBox="0 0 80 80">
<circle id="${ns}-bg" cx="50%" cy="50%" r="35"></circle>
<path id="${ns}-fill" d="M5,40a35,35 0 1,0 70,0a35,35 0 1,0 -70,0" />
<text id="${ns}-percent" x="50%" y="51%"><tspan id="${ns}-percent-value">0</tspan><tspan id="${ns}-percent-super">%</tspan></text>
</svg>
`;
let hideOnPageVisible = false;
const update = (percent) => {
const max = -219.99078369140625;
const value = document.querySelector(`#${ns}-percent-value`);
const track = document.querySelector(`#${ns}-fill`);
const offset = ((100 - percent) / 100) * max;
track.setAttribute('style', `stroke-dashoffset: ${offset}`);
value.innerHTML = percent.toString();
};
const reset = (svg) => {
svg.classList.add(`${ns}-disappear`);
};
const init = (options, socket) => {
if (options.firstInstance) {
document.addEventListener('DOMContentLoaded', () => {
addCss(css);
addHtml(html);
// Reset progress to zero after disappear animation
const svg = document.querySelector(`#${ns}`);
svg.addEventListener('animationend', () => {
update(0);
svg.classList.add(`${ns}-hidden`);
});
});
document.addEventListener('visibilitychange', () => {
if (!document.hidden && hideOnPageVisible) {
const svg = document.querySelector(`#${ns}`);
reset(svg);
hideOnPageVisible = false;
}
});
}
socket.addEventListener('message', (message) => {
const { action, data } = JSON.parse(message.data);
if (action !== 'progress') {
return;
}
const percent = Math.floor(data.percent * 100);
const svg = document.querySelector(`#${ns}`);
if (!svg) {
return;
}
// we can safely call this even if it doesn't have the class
svg.classList.remove(`${ns}-disappear`, `${ns}-hidden`);
if (data.percent === 1) {
if (document.hidden) {
hideOnPageVisible = true;
} else {
reset(svg);
}
} else {
hideOnPageVisible = false;
}
update(percent);
});
};
module.exports = { init };