pWiki/pwiki2.html

272 lines
6.3 KiB
HTML
Raw Normal View History

<!DOCTYPE html>
<html>
<!--html manifest="pwiki.appcache"-->
<head>
<title>pWiki</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<link rel="manifest" href="manifest.json">
<link rel="prefetch" href="css/fonts/Open_Sans/OpenSans-Bold.ttf">
<link rel="prefetch" href="css/fonts/Open_Sans/OpenSans-BoldItalic.ttf">
<link rel="prefetch" href="css/fonts/Open_Sans/OpenSans-ExtraBold.ttf">
<link rel="prefetch" href="css/fonts/Open_Sans/OpenSans-ExtraBoldItalic.ttf">
<link rel="prefetch" href="css/fonts/Open_Sans/OpenSans-Italic.ttf">
<link rel="prefetch" href="css/fonts/Open_Sans/OpenSans-Light.ttf">
<link rel="prefetch" href="css/fonts/Open_Sans/OpenSans-LightItalic.ttf">
<link rel="prefetch" href="css/fonts/Open_Sans/OpenSans-Regular.ttf">
<link rel="prefetch" href="css/fonts/Open_Sans/OpenSans-Semibold.ttf">
<link rel="prefetch" href="css/fonts/Open_Sans/OpenSans-SemiboldItalic.ttf">
<link rel="stylesheet" href="css/fonts.css">
</head>
<style>
body {
font-size: 1.1em;
}
a {
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
.show-on-hover {
opacity: 0;
}
:hover>.show-on-hover {
opacity: 0.4;
}
.show-on-hover:hover {
opacity: 0.8;
}
/* Spinner... */
.spinner {
position: absolute;
display: flex;
text-align: center;
left: 50%;
top: 50%;
width: 100px;
height: 100px;
margin-top: -50px;
margin-left: -50px;
white-space: nowrap;
animation: fadein 2s 1;
}
.spinner span {
position: relative;
display: inline-block;
font-size: 2em;
animation: loading 2s infinite ;
animation-delay: calc(0.2s * var(--i));
}
@keyframes fadein {
from {
opacity: 0;
}
50% {
opacity: 0.8;
}
to {
opacity: 1;
}
}
@keyframes loading {
0%, 60% {
transform: rotateY(360deg);
}
}
</style>
<!-- XXX do we need this??? -->
<script src="bootstrap.js"></script>
<!--script data-main="pwiki2" src="ext-lib/require.js"></script-->
<script src="ext-lib/require.js"></script>
<script>
var DEBUG = true
var makeFallbacks =
function(paths, search=['lib']){
return Object.entries(paths)
.map(function([key, path]){
// package...
if(path.endsWith('/')){
return [key, path] }
return [
key,
[
path,
...search
.map(function(base){
return base +'/'+ path.split(/[\\\/]+/g).pop() }),
]
] })
.reduce(function(res, [key, value]){
res[key] = value
return res }, {}) }
require.config({
paths: {
...makeFallbacks({
'ig-doc': 'node_modules/ig-doc/doc',
'ig-stoppable': 'node_modules/ig-stoppable/stoppable',
'object-run': 'node_modules/object-run/run',
'ig-object': 'node_modules/ig-object/object',
}),
// packages...
'ig-types': [
'node_modules/ig-types',
'lib/types',
],
// external stuff...
...makeFallbacks({
'jszip': 'node_modules/jszip/dist/jszip',
'pouchdb': 'node_modules/pouchdb/dist/pouchdb',
'showdown': 'node_modules/showdown/dist/showdown',
}, ['ext-lib']),
},
packages: [
'ig-types',
]
})
document.pwikiloaded = new Event('pwikiloaded')
// start loading pWiki...
require(['./browser'], function(browser){
pwiki = window.pwiki = browser.pwiki
pwiki.dom = document.querySelector('#pWiki')
// handle location.hash/history (both directions)
window.addEventListener('hashchange', function(evt){
evt.preventDefault()
var [path, hash] = decodeURI(location.hash).slice(1).split('#')
path = path.trim() == '' ?
pwiki.location
//'/'
: path
// treat links as absolute unless explicitly relative...
path = /^\.\.?([\\\/].*)?$/.test(path) ?
path
: '/'+path
pwiki.location = [path, hash] })
pwiki
.onBeforeNavigate(function(){
saveNow() })
.onNavigate(function(){
// NOTE: we do not need to directly update location.hash here as
// that will push an extra history item...
history.replaceState(
{path: this.location},
this.title,
'#'+this.location
+(this.hash ?
'#'+this.hash
: ''))
// NOTE: we are intentionally not awaiting for this -- this
// separates the navigate and load events...
var t = Date.now()
this.refresh()
.then(function(){
DEBUG
&& console.log(`## ${pwiki.path} (${Date.now() - t}ms)`) }) })
.onLoad(function(evt){
var that = this
// handle title...
document.querySelector('title').innerHTML = this.title
// scroll to anchor element...
this.hash
&& this.dom
.querySelector('#'+ this.hash)
.scrollIntoView()
// handle refresh...
// NOTE: we need to do this as hashchange is only triggered
// when the hash is actually changed...
for(var lnk of this.dom.querySelectorAll(`a[href="${location.hash}"]`)){
lnk.addEventListener('click', function(evt){
that.refresh() }) } })
// wait for stuff to finish...
browser.setup.then(function(){
// show current page...
pwiki.location = decodeURI(location.hash).slice(1)
}) })
// XXX make this a 2 stage save -- first cache and then save to store...
// XXX versioning???
var SAVE_TIMEOUT = 5000
var SAVE_QUEUE = {}
var saveContent = function(path, text){
SAVE_QUEUE[path] = text
// clear editor page cache...
pwiki.cache = null }
var saveNow = function(){
var queue = Object.entries(SAVE_QUEUE)
SAVE_QUEUE = {}
queue
.forEach(function([path, text]){
console.log('saving changes to:', path)
pwiki.get(path).raw = text }) }
setInterval(saveNow, 5000)
// XXX
var exportData = async function(){
var blob = new Blob([await pwiki.store.json(true)], {type: "text/plain;charset=utf-8"});
var a = document.createElement('a')
var blobURL = a.href = URL.createObjectURL(blob)
a.download = 'pWiki-dump.json'
//document.body.appendChild(a)
a.dispatchEvent(new MouseEvent("click"))
//document.body.removeChild(a)
//URL.revokeObjectURL(blobURL)
}
</script>
<body>
<!-- XXX need to add something passive but animated here... -->
<div id="pWiki">
<div class="spinner">
<span style="--i:0">p</span>
<span style="--i:1">W</span>
<span style="--i:2">i</span>
<span style="--i:3">k</span>
<span style="--i:4">i</span>
</div>
</div>
</body>
</html>
<!-- vim:set sw=4 ts=4 : -->