tweaking, debugging and dusting off...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2022-04-07 21:07:53 +03:00
parent daf2114508
commit 01d602ad9a
4 changed files with 118 additions and 153 deletions

View File

@ -36,7 +36,7 @@
<script src="ext-lib/pouchdb.min.js"></script> <script src="ext-lib/pouchdb.min.js"></script>
<script src="ext-lib/peer.min.js"></script> <script src="ext-lib/peer.min.js"></script>
<script data-main="ui" src="ext-lib/require.js"></script> <!--script data-main="ui" src="ext-lib/require.js"></script-->
<script src="bootstrap.js"></script> <script src="bootstrap.js"></script>
<script src="wiki.js"></script> <script src="wiki.js"></script>

View File

@ -52,17 +52,17 @@ var exportZip = function(){
zip.generateAsync({type:"blob"}) zip.generateAsync({type:"blob"})
.then(function(content) { .then(function(content) {
// see FileSaver.js // see FileSaver.js
saveAs(content, "pWiki.zip") saveAs(content, "pWiki.zip") }) }
})
}
$(function(){requirejs(['pwiki'], function(pwiki){ $(function(){requirejs(['pwiki'], function(pwiki){
var wiki = Object.create(pwiki.pWikiData) var wiki = Object.create(pwiki.pWikiData)
var page = window.page = new pwiki.pWikiPage({
wiki: wiki, var page = window.page =
}) new pwiki.pWikiPage({
wiki: wiki,
})
// XXX load data... // XXX load data...
var data = wiki.__data = {} var data = wiki.__data = {}
@ -70,16 +70,17 @@ $(function(){requirejs(['pwiki'], function(pwiki){
// load bootstrap data... // load bootstrap data...
if(window.Bootstrap){ if(window.Bootstrap){
Bootstrap.__proto__ = pwiki.BaseData Bootstrap.__proto__ = pwiki.BaseData
data.__proto__ = Bootstrap data.__proto__ = Bootstrap }
}
var client = window.client = new pwiki.pWikiClient() var client = window.client =
new pwiki.pWikiClient()
client.page = page client.page = page
client.dom = $('.wiki') client.dom = $('.wiki')
// get the base url... // get the base url...
var url = window.location.hash.slice(1) var url = window.location.hash.slice(1)
url = url != '' ? url url = url != '' ?
url
// XXX get and load page location... // XXX get and load page location...
// XXX // XXX
: 'WikiHome' : 'WikiHome'
@ -100,9 +101,8 @@ $(function(){requirejs(['pwiki'], function(pwiki){
// open page... // open page...
} else { } else {
client.location(path) client.location(path) } })
}
})
})}) })})
</script> </script>

216
macro.js
View File

@ -18,17 +18,17 @@ var setWikiWords = function(text, show_brackets, skip){
function(l){ function(l){
// check if WikiWord is escaped... // check if WikiWord is escaped...
if(l[0] == '\\'){ if(l[0] == '\\'){
return l.slice(1) return l.slice(1) }
}
var path = l[0] == '[' ? l.slice(1, -1) : l var path = l[0] == '[' ?
l.slice(1, -1)
: l
var i = [].slice.call(arguments).slice(-2)[0] var i = [].slice.call(arguments).slice(-2)[0]
// XXX HACK check if we are inside a tag... // XXX HACK check if we are inside a tag...
var rest = text.slice(i+1) var rest = text.slice(i+1)
if(rest.indexOf('>') < rest.indexOf('<')){ if(rest.indexOf('>') < rest.indexOf('<')){
return l return l }
}
return skip.indexOf(l) < 0 ? return skip.indexOf(l) < 0 ?
('<a ' ('<a '
@ -39,9 +39,7 @@ var setWikiWords = function(text, show_brackets, skip){
+'>' +'>'
+ (!!show_brackets ? path : l) + (!!show_brackets ? path : l)
+'</a>') +'</a>')
: l : l })}
})}
@ -50,8 +48,7 @@ var setWikiWords = function(text, show_brackets, skip){
function Macro(doc, args, func){ function Macro(doc, args, func){
func.doc = doc func.doc = doc
func.macro_args = args func.macro_args = args
return func return func }
}
@ -110,11 +107,11 @@ module = {
"pwiki-comment": Macro('hide in pWiki', "pwiki-comment": Macro('hide in pWiki',
[], [],
function(context, elem, state){ function(context, elem, state){
return '' return '' }),
}),
now: Macro('Create a now id', now: Macro('Create a now id',
[], [],
function(context, elem, state){ return ''+Date.now() }), function(context, elem, state){
return ''+Date.now() }),
// select filter to post-process text... // select filter to post-process text...
filter: Macro('Filter to post-process text', filter: Macro('Filter to post-process text',
['name'], ['name'],
@ -127,8 +124,7 @@ module = {
// normal -- tail... // normal -- tail...
: state.filters.push(filter) : state.filters.push(filter)
return '' return '' }),
}),
// include page/slot... // include page/slot...
// //
@ -145,8 +141,7 @@ module = {
.push([elem, context.get(path)]) .push([elem, context.get(path)])
// return the marker... // return the marker...
return this.__include_marker__ return this.__include_marker__ }),
}),
// NOTE: this is similar to include, the difference is that this // NOTE: this is similar to include, the difference is that this
// includes the page source to the current context while // includes the page source to the current context while
@ -158,8 +153,7 @@ module = {
return context.get(path) return context.get(path)
.map(function(page){ return page.raw() }) .map(function(page){ return page.raw() })
.join('\n') .join('\n') }),
}),
quote: Macro('Include quoted page source (without parsing)', quote: Macro('Include quoted page source (without parsing)',
['src'], ['src'],
@ -172,9 +166,7 @@ module = {
return elem return elem
.clone() .clone()
.attr('src', page.path()) .attr('src', page.path())
.text(page.raw())[0] .text(page.raw())[0] })) }),
}))
}),
/* /*
// fill/define slot (stage 1)... // fill/define slot (stage 1)...
@ -199,9 +191,7 @@ module = {
} else if(name in state.slots){ } else if(name in state.slots){
state.slots[name] = text state.slots[name] = text
return '' return '' } }),
}
}),
//*/ //*/
// convert @ macro to html-like + parse content... // convert @ macro to html-like + parse content...
slot: Macro('Define/fill slot', slot: Macro('Define/fill slot',
@ -220,8 +210,7 @@ module = {
elem.attr('text', null) elem.attr('text', null)
//elem.html(text) //elem.html(text)
return elem return elem }),
}),
// XXX revise macro definition rules -- see inside... // XXX revise macro definition rules -- see inside...
// XXX do we need macro namespaces or context isolation (for inculdes)??? // XXX do we need macro namespaces or context isolation (for inculdes)???
@ -248,9 +237,7 @@ module = {
state.templates[name] = elem.clone() state.templates[name] = elem.clone()
} else if(name in state.templates) { } else if(name in state.templates) {
elem = state.templates[name] elem = state.templates[name] } }
}
}
// fill macro... // fill macro...
if(path){ if(path){
@ -262,8 +249,7 @@ module = {
.find('else').first().clone() .find('else').first().clone()
.attr('src', path) .attr('src', path)
parse(e, context) parse(e, context)
return e return e }
}
// see if we need to overload attrs... // see if we need to overload attrs...
sort = sort == null ? (elem.attr('sort') || '') : sort sort = sort == null ? (elem.attr('sort') || '') : sort
@ -284,12 +270,9 @@ module = {
var e = elem.clone() var e = elem.clone()
.attr('src', page.path()) .attr('src', page.path())
parse(e, page) parse(e, page)
return e[0] return e[0] })) }
}))
}
return '' return '' })
})
}, },
// Post macros... // Post macros...
@ -300,10 +283,10 @@ module = {
[], [],
function(context, elem, state, parse, match){ function(context, elem, state, parse, match){
if(match != null){ if(match != null){
return match[0] == '\\' ? match.slice(1) : match return match[0] == '\\' ?
} match.slice(1)
return elem : match }
}), return elem }),
/* /*
_slot: Macro('', _slot: Macro('',
['name'], ['name'],
@ -314,9 +297,7 @@ module = {
return $(elem).html() return $(elem).html()
} else if(name in state.slots){ } else if(name in state.slots){
return state.slots[name] return state.slots[name] } }),
}
}),
//*/ //*/
/* /*
@ -326,15 +307,13 @@ module = {
function(context, elem, state){ function(context, elem, state){
elem = $(elem) elem = $(elem)
return elem.html(context.get(elem.attr('src')).text) return elem.html(context.get(elem.attr('src')).text) }),
}),
'page-raw': Macro('', 'page-raw': Macro('',
['src'], ['src'],
function(context, elem, state){ function(context, elem, state){
elem = $(elem) elem = $(elem)
return elem.text(context.get(elem.attr('src')).text) return elem.text(context.get(elem.attr('src')).text) }),
}),
//*/ //*/
}, },
@ -346,11 +325,12 @@ module = {
filter: { filter: {
default: 'html', default: 'html',
html: function(context, elem){ return $(elem) }, html: function(context, elem){
return $(elem) },
text: function(context, elem){ return $('<span>') text: function(context, elem){
.append($('<pre>') return $('<span>')
.html($(elem).html())) }, .append($('<pre>')
.html($(elem).html())) },
// XXX expperimental... // XXX expperimental...
json: function(context, elem){ return $('<span>') json: function(context, elem){ return $('<span>')
.html($(elem).text() .html($(elem).text()
@ -359,7 +339,10 @@ module = {
// XXX // XXX
nl2br: function(context, elem){ nl2br: function(context, elem){
return $('<div>').html($(elem).html().replace(/\n/g, '<br>\n')) }, return $('<div>')
.html($(elem)
.html()
.replace(/\n/g, '<br>\n')) },
wikiword: function(context, elem){ wikiword: function(context, elem){
return $('<span>') return $('<span>')
@ -396,8 +379,7 @@ module = {
.parent() .parent()
.addClass('checked') .addClass('checked')
.end() .end()
.end() .end() },
},
}, },
@ -414,8 +396,7 @@ module = {
post_filter: { post_filter: {
noscript: function(context, elem){ noscript: function(context, elem){
// XXX // XXX
return elem return elem },
},
// Setup the page title and .title element... // Setup the page title and .title element...
// //
@ -432,11 +413,9 @@ module = {
// show first H1 as title... // show first H1 as title...
if(elem.find('.text').text().trim().indexOf(title.text().trim()) == 0){ if(elem.find('.text').text().trim().indexOf(title.text().trim()) == 0){
title.detach() title.detach()
elem.find('.title').html(title.html()) elem.find('.title').html(title.html()) }
}
return elem return elem },
},
// XXX this needs save/reload... // XXX this needs save/reload...
editor: function(context, elem){ editor: function(context, elem){
// XXX title // XXX title
@ -445,8 +424,7 @@ module = {
// XXX raw // XXX raw
// XXX checkbox // XXX checkbox
return elem return elem },
},
}, },
@ -485,7 +463,8 @@ module = {
state.seen = state.seen || [] state.seen = state.seen || []
//pattern = pattern || RegExp('@([a-zA-Z-_]+)\\(([^)]*)\\)', 'mg') //pattern = pattern || RegExp('@([a-zA-Z-_]+)\\(([^)]*)\\)', 'mg')
pattern = pattern || RegExp.apply(null, this.__macro__pattern__) pattern = pattern
|| RegExp.apply(null, this.__macro__pattern__)
// XXX need to quote regexp chars... // XXX need to quote regexp chars...
var include_marker = RegExp(this.__include_marker__, 'g') var include_marker = RegExp(this.__include_marker__, 'g')
@ -498,9 +477,8 @@ module = {
return text.replace(pattern, function(match){ return text.replace(pattern, function(match){
// quoted macro... // quoted macro...
if(match[0] == '\\' && macro['*'] == null){ if(match[0] == '\\' && macro['*'] == null){
return match.slice(1) return match.slice(1) }
//return match //return match }
}
// XXX parse match... // XXX parse match...
var d = match.match(/@([a-zA-Z-_:]*)\(([^)]*)\)/) var d = match.match(/@([a-zA-Z-_:]*)\(([^)]*)\)/)
@ -510,22 +488,30 @@ module = {
if(name in macro || '*' in macro){ if(name in macro || '*' in macro){
var elem = $('<'+name+'/>') var elem = $('<'+name+'/>')
name = name in macro ? name : '*' name = name in macro ?
name
: '*'
// format positional args.... // format positional args....
var a = d[2] var a = d[2]
.split(/((['"]).*?\2)|\s+/g) .split(/((['"]).*?\2)|\s+/g)
// cleanup... // cleanup...
.filter(function(e){ return e && e != '' && !/^['"]$/.test(e)}) .filter(function(e){
return e
&& e != ''
&& !/^['"]$/.test(e)})
// remove quotes... // remove quotes...
.map(function(e){ return /^(['"]).*\1$/.test(e) ? e.slice(1, -1) : e }) .map(function(e){
return /^(['"]).*\1$/.test(e) ?
e.slice(1, -1)
: e })
// add the attrs to the element... // add the attrs to the element...
name != '*' name != '*'
&& a.forEach(function(e, i){ && a.forEach(function(e, i){
var k = ((macro[name] || {}).macro_args || [])[i] var k = ((macro[name] || {}).macro_args || [])[i]
k && elem.attr(k, e) k
}) && elem.attr(k, e) })
// call macro... // call macro...
var res = macro[name] var res = macro[name]
@ -539,35 +525,29 @@ module = {
res.map(function(i, e){ return e.outerHTML }) res.map(function(i, e){ return e.outerHTML })
.toArray() .toArray()
.join('\n') .join('\n')
: typeof(res) != typeof('str') ? res.outerHTML : typeof(res) != typeof('str') ?
: res res.outerHTML
} : res }
return match return match }) }
})
}
// NOTE: this modifies parsed in-place... // NOTE: this modifies parsed in-place...
var _parse = function(context, parsed, macro){ var _parse = function(context, parsed, macro){
$(parsed).contents().each(function(_, e){ $(parsed).contents().each(function(_, e){
// #text / comment node -> parse the @... macros... // #text / comment node -> parse the @... macros...
if(e.nodeType == e.TEXT_NODE || e.nodeType == e.COMMENT_NODE){ if(e.nodeType == e.TEXT_NODE
|| e.nodeType == e.COMMENT_NODE){
// get actual element content... // get actual element content...
var text = e.nodeValue // NOTE: we need to do this like this to avoid
// unparsing special characters...
var text = $('<div>').append($(e).clone()).html()
// conditional comment... // conditional comment...
if(e.nodeType == e.COMMENT_NODE){ if(e.nodeType == e.COMMENT_NODE
text = /^<!--\s*\[pWiki\[(.|\n)*\]\]\s*-->$/.test(text) ? && /^<!--\s*\[pWiki\[(.|\n)*\]\]\s*-->$/.test(text)){
text text = text
.replace(/^<!--\s*\[pWiki\[/, '') .replace(/^<!--\s*\[pWiki\[/, '')
.replace(/\]\]\s*-->$/, '') .replace(/\]\]\s*-->$/, '') }
: ('<!--'+ text +'-->')
}
/*
var t = _parseText(context, text, macro)
text != t
&& $(e).replaceWith(t)
//*/
$(e).replaceWith(_parseText(context, text, macro)) $(e).replaceWith(_parseText(context, text, macro))
// node -> html-style + attrs... // node -> html-style + attrs...
@ -578,8 +558,7 @@ module = {
for(var i=0; i < e.attributes.length; i++){ for(var i=0; i < e.attributes.length; i++){
var attr = e.attributes[i] var attr = e.attributes[i]
attr.value = _parseText(context, attr.value, macro) attr.value = _parseText(context, attr.value, macro) }
}
// macro match -> call macro... // macro match -> call macro...
if(name in macro){ if(name in macro){
@ -590,13 +569,9 @@ module = {
// normal tag -> sub-tree... // normal tag -> sub-tree...
} else { } else {
_parse(context, e, macro) _parse(context, e, macro) } } })
}
}
})
return parsed return parsed }
}
var _filter = function(lst, filters){ var _filter = function(lst, filters){
lst lst
// unique -- leave last occurance.. // unique -- leave last occurance..
@ -605,8 +580,7 @@ module = {
// filter dupplicates... // filter dupplicates...
&& lst.slice(i+1).indexOf(k) == -1 && lst.slice(i+1).indexOf(k) == -1
// filter disabled... // filter disabled...
&& lst.slice(0, i).indexOf('-' + k) == -1 && lst.slice(0, i).indexOf('-' + k) == -1 })
})
// unique -- leave first occurance.. // unique -- leave first occurance..
//.filter(function(k, i, lst){ return lst.slice(0, i).indexOf(k) == -1 }) //.filter(function(k, i, lst){ return lst.slice(0, i).indexOf(k) == -1 })
// apply the filters... // apply the filters...
@ -616,17 +590,13 @@ module = {
var seen = [] var seen = []
while(typeof(k) == typeof('str') && seen.indexOf(k) == -1){ while(typeof(k) == typeof('str') && seen.indexOf(k) == -1){
seen.push(k) seen.push(k)
k = filters[k] k = filters[k] }
}
// could not find the filter... // could not find the filter...
if(!k){ if(!k){
//console.warn('Unknown filter:', f) //console.warn('Unknown filter:', f)
return return }
}
// use the filter... // use the filter...
parsed = k.call(that, context, parsed) parsed = k.call(that, context, parsed) }) }
})
}
// macro stage... // macro stage...
_parse(context, parsed, this.macro) _parse(context, parsed, this.macro)
@ -649,8 +619,7 @@ module = {
var seen = state.seen.slice() var seen = state.seen.slice()
if(seen.indexOf(page.path()) >= 0){ if(seen.indexOf(page.path()) >= 0){
return elem.html() return elem.html() }
}
seen.push(page.path()) seen.push(page.path())
return page.map(function(page){ return page.map(function(page){
@ -669,11 +638,10 @@ module = {
!isolated))) !isolated)))
//true))) //true)))
.html() .html()
}).join('\n') }).join('\n') }))
}))
// XXX DEBUG... // XXX DEBUG...
console.log('<<<', context.path(),'TIME:', Date.now() - t) //console.log('<<<', context.path(),'TIME:', Date.now() - t)
// post processing... // post processing...
if(!skip_post){ if(!skip_post){
@ -690,15 +658,14 @@ module = {
// ...check if it prevents correct slot parsing // ...check if it prevents correct slot parsing
// within an isolated include... // within an isolated include...
if(e.parents('[isolated="true"]').length > 0){ if(e.parents('[isolated="true"]').length > 0){
return return }
}
var n = e.attr('name') var n = e.attr('name')
n in slots && e.detach() n in slots
&& e.detach()
slots[n] = e slots[n] = e })
})
// place slots... // place slots...
parsed.find('slot') parsed.find('slot')
.each(function(i, e){ .each(function(i, e){
@ -708,13 +675,11 @@ module = {
// ...check if it prevents correct slot parsing // ...check if it prevents correct slot parsing
// within an isolated include... // within an isolated include...
if(e.parents('[isolated="true"]').length > 0){ if(e.parents('[isolated="true"]').length > 0){
return return }
}
var n = e.attr('name') var n = e.attr('name')
e.replaceWith(slots[n]) e.replaceWith(slots[n]) })
})
// post-macro... // post-macro...
// XXX for some odd reason this clears the backslash from // XXX for some odd reason this clears the backslash from
@ -728,8 +693,7 @@ module = {
_filter(this.__post_filters__, this.post_filter) _filter(this.__post_filters__, this.post_filter)
// XXX shuld we get rid of the root span??? // XXX shuld we get rid of the root span???
return parsed.contents() return parsed.contents() },
},
} }

View File

@ -184,9 +184,11 @@ module.BaseData = {
// Page modifiers/actions... // Page modifiers/actions...
// XXX these needs redirecting... // XXX these needs redirecting...
//'System/sort': function(){ return this.get('..').sort() }, 'System/sort': function(){
//'System/reverse': function(){ return this.get('..').reverse() }, return this.get('..').sort() },
/* 'System/reverse': function(){
return this.get('..').reverse() },
'System/delete': function(){ 'System/delete': function(){
var p = this.dir var p = this.dir
delete this.__wiki_data[p] delete this.__wiki_data[p]
@ -422,7 +424,8 @@ module.pWikiBase = actions.Actions({
// XXX should this be local/dump??? // XXX should this be local/dump???
json: ['', function(){ }], json: ['',
function(){ }],
// Location and path API... // Location and path API...
@ -1056,7 +1059,6 @@ module.pWikiMacros = actions.Actions(pWikiBase, {
// parse macros... // parse macros...
: (this.__macro_parser__ || pWikiMacros.__macro_parser__) : (this.__macro_parser__ || pWikiMacros.__macro_parser__)
.parse(this, this.raw())) .parse(this, this.raw()))
// set... // set...
: this : this
// clear cached stuff related to text... // clear cached stuff related to text...
@ -1274,13 +1276,16 @@ var pWikiLocalStorage = pWikiFeatures.Feature({
'update', 'update',
'clear', 'clear',
], ],
function(){ this.save() }], function(){
this.save() }],
[[ [[
'path', 'path',
'data', 'data',
], ],
function(){ arguments.length > 1 && this.save() }], function(){
arguments.length > 1
&& this.save() }],
], ],
}) })
@ -1372,10 +1377,7 @@ var pWikiUIActions = actions.Actions({
client.reload() }) client.reload() })
/* XXX this messes up history for some reason... $('title').text(elems.first().text()) },
$('title').text(elems.first().text())
//*/
},
// raw text editor... // raw text editor...
'.raw': function(elems){ '.raw': function(elems){
var client = this var client = this
@ -1468,8 +1470,7 @@ var pWikiUIActions = actions.Actions({
(this.dom (this.dom
.find('#'+hash+', a[name="'+hash+'"]').first() .find('#'+hash+', a[name="'+hash+'"]').first()
.offset() || {}).top || 0) .offset() || {}).top || 0)
&& console.log('HASH:', hash) && console.log('HASH:', hash) }],
}],
reload: ['', reload: ['',
function(){ function(){
var that = this var that = this