Add: live-reload
This commit is contained in:
parent
cb23f89b6a
commit
8c374db353
|
@ -44,8 +44,15 @@ h1 small {
|
|||
margin: 15px 0;
|
||||
}
|
||||
|
||||
.actions > * {
|
||||
display: inline-block;
|
||||
.live-reload {
|
||||
width: fit-content;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin: 0.5em auto;
|
||||
}
|
||||
|
||||
.live-reload input {
|
||||
margin: 0 0.5em 0 0;
|
||||
}
|
||||
|
||||
.external {
|
||||
|
@ -68,3 +75,7 @@ button.install {
|
|||
font-family: monospace;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
.main {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
|
|
@ -4,17 +4,6 @@
|
|||
|
||||
let pendingResource;
|
||||
|
||||
function fetchText(url) {
|
||||
return new Promise((resolve, reject) => {
|
||||
// you can't use fetch in Chrome under 'file:' protocol
|
||||
const xhr = new XMLHttpRequest();
|
||||
xhr.open('GET', url);
|
||||
xhr.addEventListener('load', () => resolve(xhr.responseText));
|
||||
xhr.addEventListener('error', () => reject(xhr));
|
||||
xhr.send();
|
||||
});
|
||||
}
|
||||
|
||||
function install(style) {
|
||||
const request = Object.assign(style, {
|
||||
method: 'saveUsercss',
|
||||
|
@ -22,11 +11,12 @@ function install(style) {
|
|||
updateUrl: location.href
|
||||
});
|
||||
return communicate(request)
|
||||
.then(() => {
|
||||
.then(result => {
|
||||
$$('.warning')
|
||||
.forEach(el => el.remove());
|
||||
$('button.install').textContent = 'Installed';
|
||||
$('button.install').disabled = true;
|
||||
window.dispatchEvent(new CustomEvent('installed', {detail: result}));
|
||||
})
|
||||
.catch(err => {
|
||||
alert(chrome.i18n.getMessage('styleInstallFailed', String(err)));
|
||||
|
@ -62,7 +52,7 @@ function getAppliesTo(style) {
|
|||
return result;
|
||||
}
|
||||
|
||||
function initInstallPage({style, dup}) {
|
||||
function initInstallPage({style, dup}, sourceLoader) {
|
||||
return pendingResource.then(() => {
|
||||
const versionTest = dup && semverCompare(style.version, dup.version);
|
||||
document.body.innerHTML = '';
|
||||
|
@ -88,8 +78,10 @@ function initInstallPage({style, dup}) {
|
|||
<a href="${style.supportURL}" target="_blank">Support</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="main">
|
||||
<div class="code"></div>
|
||||
</div>
|
||||
</div>
|
||||
`));
|
||||
if (versionTest < 0) {
|
||||
// FIXME: i18n
|
||||
|
@ -109,9 +101,64 @@ function initInstallPage({style, dup}) {
|
|||
install(style);
|
||||
}
|
||||
};
|
||||
|
||||
if (location.protocol === 'file:') {
|
||||
initLiveReload(sourceLoader);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function initLiveReload(sourceLoader) {
|
||||
let installed;
|
||||
const watcher = sourceLoader.watch(source => {
|
||||
$('.code').textContent = source;
|
||||
return communicate({
|
||||
method: 'saveUsercss',
|
||||
id: installed.id,
|
||||
source: source
|
||||
}).then(() => {
|
||||
$$('.main .warning').forEach(e => e.remove());
|
||||
}).catch(err => {
|
||||
const oldWarning = $('.main .warning');
|
||||
// FIXME: i18n
|
||||
const warning = tHTML(`
|
||||
<div class="warning">
|
||||
Stylus failed to parse usercss:
|
||||
<pre>${err}</pre>
|
||||
</div>
|
||||
`);
|
||||
if (oldWarning) {
|
||||
oldWarning.replaceWith(warning);
|
||||
} else {
|
||||
$('.main').prepend(warning);
|
||||
}
|
||||
});
|
||||
});
|
||||
window.addEventListener('installed', ({detail: {style}}) => {
|
||||
installed = style;
|
||||
if ($('.live-reload-checkbox').checked) {
|
||||
watcher.start();
|
||||
}
|
||||
});
|
||||
// FIXME: i18n
|
||||
$('.actions').append(tHTML(`
|
||||
<label class="live-reload">
|
||||
<input type="checkbox" class="live-reload-checkbox">
|
||||
<span>Live reload</span>
|
||||
</label>
|
||||
`));
|
||||
$('.live-reload-checkbox').onchange = e => {
|
||||
if (!installed) {
|
||||
return;
|
||||
}
|
||||
if (e.target.checked) {
|
||||
watcher.start();
|
||||
} else {
|
||||
watcher.stop();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function initErrorPage(err, source) {
|
||||
return pendingResource.then(() => {
|
||||
document.body.innerHTML = '';
|
||||
|
@ -127,8 +174,65 @@ function initErrorPage(err, source) {
|
|||
});
|
||||
}
|
||||
|
||||
function initUsercssInstall() {
|
||||
function createSourceLoader() {
|
||||
let source;
|
||||
|
||||
function fetchText(url) {
|
||||
return new Promise((resolve, reject) => {
|
||||
// you can't use fetch in Chrome under 'file:' protocol
|
||||
const xhr = new XMLHttpRequest();
|
||||
xhr.open('GET', url);
|
||||
xhr.addEventListener('load', () => resolve(xhr.responseText));
|
||||
xhr.addEventListener('error', () => reject(xhr));
|
||||
xhr.send();
|
||||
});
|
||||
}
|
||||
|
||||
function load() {
|
||||
return fetchText(location.href)
|
||||
.then(_source => {
|
||||
source = _source;
|
||||
return source;
|
||||
});
|
||||
}
|
||||
|
||||
function watch(cb) {
|
||||
let timer;
|
||||
const DELAY = 1000;
|
||||
|
||||
function start() {
|
||||
if (timer) {
|
||||
return;
|
||||
}
|
||||
timer = setTimeout(check, DELAY);
|
||||
}
|
||||
|
||||
function stop() {
|
||||
clearTimeout(timer);
|
||||
timer = null;
|
||||
}
|
||||
|
||||
function check() {
|
||||
fetchText(location.href)
|
||||
.then(_source => {
|
||||
if (source !== _source) {
|
||||
source = _source;
|
||||
return cb(source);
|
||||
}
|
||||
})
|
||||
.catch(console.log)
|
||||
.then(() => {
|
||||
timer = setTimeout(check, DELAY);
|
||||
});
|
||||
}
|
||||
|
||||
return {start, stop};
|
||||
}
|
||||
|
||||
return {load, watch, source: () => source};
|
||||
}
|
||||
|
||||
function initUsercssInstall() {
|
||||
pendingResource = communicate({
|
||||
method: 'injectResource',
|
||||
resources: [
|
||||
|
@ -139,17 +243,18 @@ function initUsercssInstall() {
|
|||
'/content/install-user-css.css'
|
||||
]
|
||||
});
|
||||
fetchText(location.href)
|
||||
.then(_source => {
|
||||
source = _source;
|
||||
return communicate({
|
||||
|
||||
const sourceLoader = createSourceLoader();
|
||||
sourceLoader.load()
|
||||
.then(() =>
|
||||
communicate({
|
||||
method: 'filterUsercss',
|
||||
source,
|
||||
source: sourceLoader.source(),
|
||||
checkDup: true
|
||||
});
|
||||
})
|
||||
.then(initInstallPage)
|
||||
.catch(err => initErrorPage(err, source));
|
||||
)
|
||||
.then(result => initInstallPage(result, sourceLoader))
|
||||
.catch(err => initErrorPage(err, sourceLoader.source()));
|
||||
}
|
||||
|
||||
function isUsercss() {
|
||||
|
|
Loading…
Reference in New Issue
Block a user