2019-07-03 02:42:41 +02:00
|
|
|
|
import Router from '../router'
|
|
|
|
|
|
2019-11-11 04:24:53 +01:00
|
|
|
|
export default function initializeBuildWatcher() {
|
2019-07-03 02:42:41 +02:00
|
|
|
|
const shadowHost = document.createElement('div')
|
|
|
|
|
shadowHost.id = '__next-prerender-indicator'
|
|
|
|
|
// Make sure container is fixed and on a high zIndex so it shows
|
|
|
|
|
shadowHost.style.position = 'fixed'
|
|
|
|
|
shadowHost.style.bottom = '20px'
|
|
|
|
|
shadowHost.style.right = '10px'
|
|
|
|
|
shadowHost.style.width = 0
|
|
|
|
|
shadowHost.style.height = 0
|
|
|
|
|
shadowHost.style.zIndex = 99998
|
|
|
|
|
shadowHost.style.transition = 'all 100ms ease'
|
|
|
|
|
|
|
|
|
|
document.body.appendChild(shadowHost)
|
|
|
|
|
|
|
|
|
|
let shadowRoot
|
|
|
|
|
let prefix = ''
|
|
|
|
|
|
|
|
|
|
if (shadowHost.attachShadow) {
|
|
|
|
|
shadowRoot = shadowHost.attachShadow({ mode: 'open' })
|
|
|
|
|
} else {
|
|
|
|
|
// If attachShadow is undefined then the browser does not support
|
|
|
|
|
// the Shadow DOM, we need to prefix all the names so there
|
|
|
|
|
// will be no conflicts
|
|
|
|
|
shadowRoot = shadowHost
|
|
|
|
|
prefix = '__next-prerender-indicator-'
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Container
|
|
|
|
|
const container = createContainer(prefix)
|
|
|
|
|
shadowRoot.appendChild(container)
|
|
|
|
|
|
|
|
|
|
// CSS
|
|
|
|
|
const css = createCss(prefix)
|
|
|
|
|
shadowRoot.appendChild(css)
|
|
|
|
|
|
2019-09-15 23:18:11 +02:00
|
|
|
|
const expandEl = container.querySelector('a')
|
|
|
|
|
const closeEl = container.querySelector(`#${prefix}close`)
|
|
|
|
|
|
2019-07-03 02:42:41 +02:00
|
|
|
|
// State
|
2019-09-15 23:18:11 +02:00
|
|
|
|
const dismissKey = '__NEXT_DISMISS_PRERENDER_INDICATOR'
|
|
|
|
|
const dismissUntil = parseInt(window.localStorage.getItem(dismissKey), 10)
|
|
|
|
|
const dismissed = dismissUntil > new Date().getTime()
|
|
|
|
|
|
|
|
|
|
let isVisible = !dismissed && window.__NEXT_DATA__.nextExport
|
2019-07-03 02:42:41 +02:00
|
|
|
|
|
2019-11-11 04:24:53 +01:00
|
|
|
|
function updateContainer() {
|
2019-07-03 02:42:41 +02:00
|
|
|
|
if (isVisible) {
|
|
|
|
|
container.classList.add(`${prefix}visible`)
|
|
|
|
|
} else {
|
|
|
|
|
container.classList.remove(`${prefix}visible`)
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-09-15 23:18:11 +02:00
|
|
|
|
const expandedClass = `${prefix}expanded`
|
|
|
|
|
let toggleTimeout
|
|
|
|
|
|
|
|
|
|
const toggleExpand = (expand = true) => {
|
|
|
|
|
clearTimeout(toggleTimeout)
|
|
|
|
|
|
|
|
|
|
toggleTimeout = setTimeout(() => {
|
|
|
|
|
if (expand) {
|
|
|
|
|
expandEl.classList.add(expandedClass)
|
|
|
|
|
closeEl.style.display = 'flex'
|
|
|
|
|
} else {
|
|
|
|
|
expandEl.classList.remove(expandedClass)
|
|
|
|
|
closeEl.style.display = 'none'
|
|
|
|
|
}
|
|
|
|
|
}, 50)
|
|
|
|
|
}
|
2019-07-03 02:42:41 +02:00
|
|
|
|
|
2019-09-15 23:18:11 +02:00
|
|
|
|
closeEl.addEventListener('click', () => {
|
|
|
|
|
const oneHourAway = new Date().getTime() + 1 * 60 * 60 * 1000
|
|
|
|
|
window.localStorage.setItem(dismissKey, oneHourAway + '')
|
|
|
|
|
isVisible = false
|
|
|
|
|
updateContainer()
|
2019-07-03 02:42:41 +02:00
|
|
|
|
})
|
2019-09-15 23:18:11 +02:00
|
|
|
|
closeEl.addEventListener('mouseenter', () => toggleExpand())
|
|
|
|
|
closeEl.addEventListener('mouseleave', () => toggleExpand(false))
|
|
|
|
|
expandEl.addEventListener('mouseenter', () => toggleExpand())
|
|
|
|
|
expandEl.addEventListener('mouseleave', () => toggleExpand(false))
|
2019-07-03 02:42:41 +02:00
|
|
|
|
|
|
|
|
|
Router.events.on('routeChangeComplete', () => {
|
|
|
|
|
isVisible = window.next.isPrerendered
|
|
|
|
|
updateContainer()
|
|
|
|
|
})
|
|
|
|
|
updateContainer()
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-11 04:24:53 +01:00
|
|
|
|
function createContainer(prefix) {
|
2019-07-03 02:42:41 +02:00
|
|
|
|
const container = document.createElement('div')
|
|
|
|
|
container.id = `${prefix}container`
|
|
|
|
|
container.innerHTML = `
|
2019-09-15 23:18:11 +02:00
|
|
|
|
<button id="${prefix}close" title="Hide indicator for session">
|
|
|
|
|
<span>×</span>
|
|
|
|
|
</button>
|
2020-03-12 16:23:58 +01:00
|
|
|
|
<a href="https://nextjs.org/docs#automatic-static-optimization-indicator" target="_blank" rel="noreferrer">
|
2019-09-15 23:18:11 +02:00
|
|
|
|
<div id="${prefix}icon-wrapper">
|
|
|
|
|
<svg width="15" height="20" viewBox="0 0 60 80" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
|
|
|
<path d="M36 3L30.74 41H8L36 3Z" fill="black"/>
|
|
|
|
|
<path d="M25 77L30.26 39H53L25 77Z" fill="black"/>
|
|
|
|
|
<path d="M13.5 33.5L53 39L47.5 46.5L7 41.25L13.5 33.5Z" fill="black"/>
|
|
|
|
|
</svg>
|
|
|
|
|
Prerendered Page
|
|
|
|
|
</div>
|
|
|
|
|
</a>
|
2019-07-03 02:42:41 +02:00
|
|
|
|
`
|
|
|
|
|
return container
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-11 04:24:53 +01:00
|
|
|
|
function createCss(prefix) {
|
2019-07-03 02:42:41 +02:00
|
|
|
|
const css = document.createElement('style')
|
|
|
|
|
css.textContent = `
|
|
|
|
|
#${prefix}container {
|
|
|
|
|
position: absolute;
|
2019-09-15 23:18:11 +02:00
|
|
|
|
display: none;
|
2019-07-03 02:42:41 +02:00
|
|
|
|
bottom: 10px;
|
|
|
|
|
right: 15px;
|
2019-09-15 23:18:11 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#${prefix}close {
|
|
|
|
|
top: -10px;
|
|
|
|
|
right: -10px;
|
|
|
|
|
border: none;
|
|
|
|
|
width: 18px;
|
|
|
|
|
height: 18px;
|
|
|
|
|
color: #333333;
|
|
|
|
|
font-size: 16px;
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
display: none;
|
|
|
|
|
position: absolute;
|
|
|
|
|
background: #ffffff;
|
|
|
|
|
border-radius: 100%;
|
|
|
|
|
align-items: center;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#${prefix}container a {
|
|
|
|
|
color: inherit;
|
|
|
|
|
text-decoration: none;
|
2019-07-03 02:42:41 +02:00
|
|
|
|
width: 15px;
|
|
|
|
|
height: 23px;
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
|
|
|
|
|
border-radius: 3px;
|
|
|
|
|
background: #fff;
|
|
|
|
|
color: #000;
|
|
|
|
|
font: initial;
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
letter-spacing: initial;
|
|
|
|
|
text-shadow: initial;
|
|
|
|
|
text-transform: initial;
|
|
|
|
|
visibility: initial;
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
|
|
|
|
|
|
|
|
|
|
padding: 4px 2px;
|
|
|
|
|
align-items: center;
|
|
|
|
|
box-shadow: 0 11px 40px 0 rgba(0, 0, 0, 0.25), 0 2px 10px 0 rgba(0, 0, 0, 0.12);
|
|
|
|
|
|
2019-09-15 23:18:11 +02:00
|
|
|
|
display: flex;
|
2019-07-03 02:42:41 +02:00
|
|
|
|
transition: opacity 0.1s ease, bottom 0.1s ease, width 0.3s ease;
|
|
|
|
|
animation: ${prefix}fade-in 0.1s ease-in-out;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#${prefix}icon-wrapper {
|
|
|
|
|
width: 140px;
|
|
|
|
|
height: 20px;
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-shrink: 0;
|
|
|
|
|
align-items: center;
|
2019-09-15 23:18:11 +02:00
|
|
|
|
position: relative;
|
2019-07-03 02:42:41 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#${prefix}icon-wrapper svg {
|
|
|
|
|
flex-shrink: 0;
|
|
|
|
|
margin-right: 3px;
|
|
|
|
|
}
|
|
|
|
|
|
2019-09-15 23:18:11 +02:00
|
|
|
|
#${prefix}container a.${prefix}expanded {
|
|
|
|
|
width: 135px;
|
2019-07-03 02:42:41 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#${prefix}container.${prefix}visible {
|
|
|
|
|
display: flex;
|
|
|
|
|
bottom: 10px;
|
|
|
|
|
opacity: 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@keyframes ${prefix}fade-in {
|
|
|
|
|
from {
|
|
|
|
|
bottom: 0px;
|
|
|
|
|
opacity: 0;
|
|
|
|
|
}
|
|
|
|
|
to {
|
|
|
|
|
bottom: 10px;
|
|
|
|
|
opacity: 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
`
|
|
|
|
|
|
|
|
|
|
return css
|
|
|
|
|
}
|