now writing to direct actions like './name' works...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2022-09-19 00:18:23 +03:00
parent 39582485f7
commit d73de66ac7
3 changed files with 102 additions and 49 deletions

View File

@ -211,10 +211,19 @@ object.Constructor('BasePage', {
// XXX should these be writable??? // XXX should these be writable???
get name(){ get name(){
return pwpath.basename(this.path) }, return pwpath.basename(this.path) },
//set name(value){ }, set name(value){
this.move(
/^[\\\/]/.test(value) ?
value
: '../'+value) },
get dir(){ get dir(){
return pwpath.dirname(this.path) }, return pwpath.dirname(this.path) },
//set dir(value){ }, set dir(value){
var to = pwpath.join(value, this.name)
this.move(
/^[\\\/]/.test(to) ?
to
: '../'+to) },
/*/ XXX TITLE... /*/ XXX TITLE...
// NOTE: .__title is intentionally not persistent... // NOTE: .__title is intentionally not persistent...
@ -315,7 +324,25 @@ object.Constructor('BasePage', {
res.bind(this) res.bind(this)
: res }).call(this) }, : res }).call(this) },
set data(value){ set data(value){
this.__update__(value) }, if(this.actions
&& this.actions[this.name]){
var name =
this.actions[this.name] === true ?
this.name
: this.actions[this.name]
var page = this.get('..')
// NOTE: this can return a promise, as we'll need to assign
// we do not care about it as long as it's not a function...
// XXX not sure if this is a good idea...
var res = page[name]
// set...
typeof(res) == 'function' ?
page[name](value.text ?? value)
: (page[name] = value.text ?? value)
// normal update...
} else {
this.__update__(value) } },
// metadata... // metadata...
// //
@ -1413,7 +1440,7 @@ object.Constructor('Page', BasePage, {
.flat()) .flat())
: data.text )}).call(this) }, : data.text )}).call(this) },
set raw(value){ set raw(value){
this.__update__({text: value}) }, this.data = {text: value} },
//this.onTextUpdate(value) }, //this.onTextUpdate(value) },
// iterate matches or content list as pages... // iterate matches or content list as pages...
@ -1510,7 +1537,7 @@ object.Constructor('Page', BasePage, {
renderer: this, renderer: this,
}) }).call(this) }, }) }).call(this) },
set text(value){ set text(value){
this.__update__({text: value}) }, this.data = {text: value} },
//this.onTextUpdate(value) }, //this.onTextUpdate(value) },
// pass on .renderer to clones... // pass on .renderer to clones...
@ -1788,12 +1815,12 @@ module.System = {
// XXX all of these should support pattern pages... // XXX all of these should support pattern pages...
_text: { _text: {
text: '@include(.:$ARGS isolated join="@source(file-separator)")' }, text: '@include(.:$ARGS isolated join="@source(file-separator)")' },
// XXX /rootpath here is not relative -- makes reuse harder...
_view: { _view: {
text: object.doc` text: object.doc`
<slot name="header"> <slot name="header">
<a href="#/list">&#9776</a> <a href="#/list">&#9776</a>
@source(./location/!) @source(./location/!)
<a href="javascript:refresh()">&#10227;</a>
<a href="#@source(./path/!)/edit">&#9998;</a> <a href="#@source(./path/!)/edit">&#9998;</a>
</slot> </slot>
<hr> <hr>
@ -1825,7 +1852,7 @@ module.System = {
+'<pre class="editor" ' +'<pre class="editor" '
+'wikiwords="no" ' +'wikiwords="no" '
+'contenteditable ' +'contenteditable '
+'oninput="saveContent(\'@source(./path)\', this.innerText)">' +'oninput="saveLiveContent(\'@source(./path)\', this.innerText)">'
+'<quote filter="quote-tags" src="."/>' +'<quote filter="quote-tags" src="."/>'
+'</pre>' +'</pre>'
+'</macro>' +'</macro>'
@ -1839,13 +1866,13 @@ module.System = {
+'<h1 ' +'<h1 '
+'contenteditable ' +'contenteditable '
// XXX need to make this savable... // XXX need to make this savable...
+'oninput="saveContent(\'@source(./path)/name\')">' +'oninput="saveLiveContent(\'@source(./path)/name\')">'
+'@source(./name)' +'@source(./name)'
+'</h1>' +'</h1>'
+'<pre class="editor" ' +'<pre class="editor" '
+'wikiwords="no" ' +'wikiwords="no" '
+'contenteditable ' +'contenteditable '
+'oninput="saveContent(\'@source(./path)\', this.innerText)">' +'oninput="saveLiveContent(\'@source(./path)\', this.innerText)">'
+'<quote filter="quote-tags" src="."/>' +'<quote filter="quote-tags" src="."/>'
+'</pre>' +'</pre>'
+'</macro>'}, +'</macro>'},
@ -1858,13 +1885,13 @@ module.System = {
<macro src=".." join="@source(file-separator)"> <macro src=".." join="@source(file-separator)">
<h1 class="title-editor" <h1 class="title-editor"
contenteditable contenteditable
oninput="saveContent(\'@source(./path)/name\')"> oninput="saveContent(\'@source(./path)/name\', this.innerText)">
@source(./name) @source(./name)
</h1> </h1>
<pre class="editor" <pre class="editor"
wikiwords="no" wikiwords="no"
contenteditable contenteditable
oninput="saveContent(\'@source(./path)\', this.innerText)" oninput="saveLiveContent(\'@source(./path)\', this.innerText)"
><quote filter="quote-tags" src="."/></pre> ><quote filter="quote-tags" src="."/></pre>
</macro> </macro>
</slot>`}, </slot>`},
@ -1967,20 +1994,16 @@ module.System = {
// page actions... // page actions...
// //
// XXX broken...
// XXX this does not work as energetic... // XXX this does not work as energetic...
time: async function(){ time: async function(){
var t = Date.now() var t = Date.now()
var text = await this.get('../_text').text var text = await this.get('../_text').text
var time = Date.now() - t var time = Date.now() - t
console.log('RENDER TIME:', time) console.log('RENDER TIME:', time)
return object.doc` return object.doc`
Time to render: ${time}ms <br> Time to render: ${time}ms <br>
<ht> <hr>
${text}`}, ${text}`},
//*/
// XXX EXPERIMENTAL -- page types... // XXX EXPERIMENTAL -- page types...
isAction: async function(){ isAction: async function(){
@ -2040,9 +2063,9 @@ module.System = {
&& this.renderer.refresh() && this.renderer.refresh()
// XXX returning undefined will stop the redirect... // XXX returning undefined will stop the redirect...
return '' }, return '' },
// XXX copy/move/... // NOTE: this moves relative to the basedir and not relative to the
// XXX do we need this as a page action??? // page...
move: function(){ move: async function(){
var from = this.get('..') var from = this.get('..')
// XXX this is ugly... // XXX this is ugly...
// ...need to standardize how we get arguments when rendering.... // ...need to standardize how we get arguments when rendering....
@ -2050,19 +2073,25 @@ module.System = {
|| (this.renderer || {args:{}}).args.to || (this.renderer || {args:{}}).args.to
console.log('MOVE:', from.path, to) console.log('MOVE:', from.path, to)
// XXX
if(to){ to
// XXX move... && await from.move(
} /^[\\\/]/.test(to[0]) ?
to
: pwpath.join('..', to))
// redirect... // redirect...
this.renderer this.renderer
&& (this.renderer.location = this.referrer) && to
//&& (this.renderer.location = this.referrer)
&& (this.renderer.location = from.path)
// XXX this should not be needed... // XXX this should not be needed...
&& this.renderer.refresh() && this.renderer.refresh()
// XXX if we return undefined here this will not fully redirect, // XXX if we return undefined here this will not fully redirect,
// keeping the move page open but setting the url to the // keeping the move page open but setting the url to the
// redirected page... // redirected page...
return '' }, return '' },
// XXX copy/...
// XXX System/back // XXX System/back
// XXX System/forward // XXX System/forward

View File

@ -173,22 +173,41 @@ require.config({
// Editor -- save changes... // Editor -- save changes...
// XXX versioning?? // XXX versioning??
var SAVE_TIMEOUT = 5000 var SAVE_LIVE_TIMEOUT = 5000
var SAVE_LIVE_QUEUE = {}
var saveLiveContent =
function(path, text){
SAVE_LIVE_QUEUE[path] = text
// clear editor page cache...
pwiki.cache = null }
var SAVE_QUEUE = {} var SAVE_QUEUE = {}
var saveContent = var saveContent =
function(path, text){ function(path, text){
SAVE_QUEUE[path] = text SAVE_QUEUE[path] = text
// clear editor page cache... }
pwiki.cache = null }
var saveNow = var saveAll =
function(){ function(){
saveNow()
var queue = Object.entries(SAVE_QUEUE) var queue = Object.entries(SAVE_QUEUE)
SAVE_QUEUE = {} SAVE_QUEUE = {}
queue queue
.forEach(function([path, text]){ .forEach(function([path, text]){
console.log('saving changes to:', path) console.log('saving changes to:', path)
pwiki.get(path).raw = text }) } pwiki.get(path).raw = text }) }
setInterval(saveNow, 5000)
var saveNow =
function(){
var queue = Object.entries(SAVE_LIVE_QUEUE)
SAVE_LIVE_QUEUE = {}
NEW_TITLE = undefined
queue
.forEach(function([path, text]){
console.log('saving changes to:', path)
pwiki.get(path).raw = text }) }
setInterval(saveNow, SAVE_LIVE_TIMEOUT)
@ -206,8 +225,6 @@ window.stopSpinner = function(){
//--------------------------------------------------------------------- //---------------------------------------------------------------------
// General setup... // General setup...
REFRESH_DELAY = 20
document.pwikiloaded = new Event('pwikiloaded') document.pwikiloaded = new Event('pwikiloaded')
var logTime = async function(promise, msg=''){ var logTime = async function(promise, msg=''){
@ -223,6 +240,16 @@ var logTime = async function(promise, msg=''){
return res } return res }
REFRESH_DELAY = 20
var refresh = async function(){
startSpinner()
setTimeout(function(){
logTime(
pwiki.refresh(),
pwiki.location) }, REFRESH_DELAY) }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// start loading pWiki... // start loading pWiki...
require(['./browser'], function(browser){ require(['./browser'], function(browser){
@ -248,7 +275,7 @@ require(['./browser'], function(browser){
pwiki.location = [path, hash] }, REFRESH_DELAY) }) pwiki.location = [path, hash] }, REFRESH_DELAY) })
pwiki pwiki
.onBeforeNavigate(function(){ .onBeforeNavigate(function(){
saveNow() }) saveAll() })
.onNavigate(async function(){ .onNavigate(async function(){
// NOTE: we do not need to directly update location.hash here as // NOTE: we do not need to directly update location.hash here as
// that will push an extra history item... // that will push an extra history item...
@ -279,12 +306,7 @@ require(['./browser'], function(browser){
// NOTE: we need to do this as hashchange is only triggered // NOTE: we need to do this as hashchange is only triggered
// when the hash is actually changed... // when the hash is actually changed...
for(var lnk of this.dom.querySelectorAll(`a[href="${location.hash}"]`)){ for(var lnk of this.dom.querySelectorAll(`a[href="${location.hash}"]`)){
lnk.addEventListener('click', function(evt){ lnk.addEventListener('click', refresh) } })
startSpinner()
setTimeout(function(){
logTime(
that.refresh(),
that.location) }, REFRESH_DELAY) }) } })
// wait for stuff to finish... // wait for stuff to finish...
browser.setup.then(function(){ browser.setup.then(function(){

View File

@ -55,6 +55,8 @@
* i.e. a way to pass tags through path... * i.e. a way to pass tags through path...
* /some/path:tags=a,b,c * /some/path:tags=a,b,c
* XXX FEATURE images... * XXX FEATURE images...
* XXX generalize html/dom api...
* ...see refresh() in pwiki2.html
* XXX async/live render... * XXX async/live render...
* might be fun to push the async parts of the render to the dom... * might be fun to push the async parts of the render to the dom...
* ...i.e. return a partially rendered DOM with handlers to fill * ...i.e. return a partially rendered DOM with handlers to fill