mirror of
https://github.com/flynx/pWiki.git
synced 2025-10-29 18:10:09 +00:00
sorting mostly done -- still rough corners remaining...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
parent
b4b39b4de9
commit
23c3c3ad4f
@ -558,25 +558,16 @@ object.Constructor('BasePage', {
|
|||||||
|
|
||||||
// sorting...
|
// sorting...
|
||||||
//
|
//
|
||||||
// XXX should this be page-level (current) store level???
|
sort: async function(...cmp){
|
||||||
// XXX when this is async, should this return a promise????
|
// normalize to path...
|
||||||
sort: async function(cmp){
|
|
||||||
// not sorting single pages...
|
|
||||||
//if(this.length <= 1){
|
|
||||||
if(!this.isPattern){
|
|
||||||
return this }
|
|
||||||
// sort...
|
|
||||||
this.metadata =
|
this.metadata =
|
||||||
{ order: (await this.each())
|
{ order: await this.store.sort(this.path, ...cmp) }
|
||||||
.sort(...arguments)
|
|
||||||
.map(function(p){
|
|
||||||
return p.path }) }
|
|
||||||
return this },
|
return this },
|
||||||
reverse: async function(){
|
reverse: async function(){
|
||||||
// not sorting single pages...
|
// not sorting single pages...
|
||||||
if(this.length <= 1){
|
if(this.length <= 1){
|
||||||
return this }
|
return this }
|
||||||
this.metadata = { order: (await this.match()).reverse() }
|
this.sort('reverse')
|
||||||
return this },
|
return this },
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|||||||
@ -643,6 +643,7 @@ module.BaseStore = {
|
|||||||
//*/
|
//*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// .exists(<path>)
|
// .exists(<path>)
|
||||||
// -> <normalized-path>
|
// -> <normalized-path>
|
||||||
@ -689,6 +690,83 @@ module.BaseStore = {
|
|||||||
return false }
|
return false }
|
||||||
return pwpath.joinArgs(res, args) },
|
return pwpath.joinArgs(res, args) },
|
||||||
//*/
|
//*/
|
||||||
|
|
||||||
|
// XXX EXPERIMENTAL...
|
||||||
|
// XXX should we handle undefined attr values???
|
||||||
|
// XXX BUG: chains still not working correctly...
|
||||||
|
sort: function(paths, ...by){
|
||||||
|
var that = this
|
||||||
|
paths =
|
||||||
|
(paths.includes('*')
|
||||||
|
|| paths.includes('**')) ?
|
||||||
|
this.match(paths).iter()
|
||||||
|
: paths
|
||||||
|
var _async = false
|
||||||
|
return paths
|
||||||
|
// pre-fetch all the needed data...
|
||||||
|
// XXX we can try and make this lazy and only get the data
|
||||||
|
// we need when we need it (in sort)...
|
||||||
|
// ...not sure if this is worth it...
|
||||||
|
.map(function(p, i){
|
||||||
|
var d
|
||||||
|
var res = []
|
||||||
|
for(var cmp of by){
|
||||||
|
res.push(
|
||||||
|
(cmp == 'path'
|
||||||
|
|| cmp == 'location') ?
|
||||||
|
p
|
||||||
|
: cmp == 'dir' ?
|
||||||
|
pwpath.dirname(p)
|
||||||
|
: cmp == 'name' ?
|
||||||
|
pwpath.basename(p)
|
||||||
|
: cmp == 'title' ?
|
||||||
|
pwpath.decodeElem(
|
||||||
|
pwpath.basename(p))
|
||||||
|
: cmp == 'depth' ?
|
||||||
|
pwpath.split(p).length
|
||||||
|
// async attr...
|
||||||
|
: typeof(cmp) == 'string' ?
|
||||||
|
// NOTE: we only get page data once per page...
|
||||||
|
(d = d ?? that.get(p))
|
||||||
|
.then(function(data){
|
||||||
|
return data[cmp] })
|
||||||
|
: null) }
|
||||||
|
_async = _async || !!d
|
||||||
|
return d ?
|
||||||
|
// wait for data to resolve...
|
||||||
|
Promise.all([i, p, Promise.all(res)])
|
||||||
|
: [i, p, res] })
|
||||||
|
// NOTE: if one of the sort attrs is async we need to wrap the
|
||||||
|
// whole thing in a promise...
|
||||||
|
.run(function(){
|
||||||
|
return _async ?
|
||||||
|
Promise.all(this).iter()
|
||||||
|
: this })
|
||||||
|
.sort(function([ia, a, ca], [ib, b, cb]){
|
||||||
|
for(var [i, cmp] of by.entries()){
|
||||||
|
var res =
|
||||||
|
typeof(cmp) == 'string' ?
|
||||||
|
((ca[i] == null
|
||||||
|
&& cb[i] == null) ?
|
||||||
|
0
|
||||||
|
: (cb[i] == null
|
||||||
|
|| ca[i] < cb[i]) ?
|
||||||
|
-1
|
||||||
|
: (ca[i] == null
|
||||||
|
|| ca[i] > cb[i]) ?
|
||||||
|
1
|
||||||
|
: 0)
|
||||||
|
: typeof(cmp) == 'function' ?
|
||||||
|
cmp(a, b)
|
||||||
|
: 0
|
||||||
|
// got a non equal...
|
||||||
|
if(res != 0){
|
||||||
|
return res } }
|
||||||
|
// keep positions if all comparisons are equal...
|
||||||
|
return ia - ib })
|
||||||
|
.map(function([_, p]){
|
||||||
|
return p }) },
|
||||||
|
|
||||||
// find the closest existing alternative path...
|
// find the closest existing alternative path...
|
||||||
find: async function(path, strict=false){
|
find: async function(path, strict=false){
|
||||||
var {path, args} = pwpath.splitArgs(path)
|
var {path, args} = pwpath.splitArgs(path)
|
||||||
@ -709,7 +787,6 @@ module.BaseStore = {
|
|||||||
: '/'+p
|
: '/'+p
|
||||||
if(pages.has(p)){
|
if(pages.has(p)){
|
||||||
return p+args } } },
|
return p+args } } },
|
||||||
|
|
||||||
//
|
//
|
||||||
// Resolve page for path
|
// Resolve page for path
|
||||||
// .match(<path>)
|
// .match(<path>)
|
||||||
@ -802,19 +879,20 @@ module.BaseStore = {
|
|||||||
// pattern match * / **
|
// pattern match * / **
|
||||||
if(path.includes('*')
|
if(path.includes('*')
|
||||||
|| path.includes('**')){
|
|| path.includes('**')){
|
||||||
var order = (this.metadata(path) ?? {}).order || []
|
|
||||||
|
|
||||||
var {path, args} = pwpath.splitArgs(path)
|
var {path, args} = pwpath.splitArgs(path)
|
||||||
|
path = pwpath.sanitize(path)
|
||||||
|
|
||||||
var all = args.all
|
var all = args.all
|
||||||
|
var sort = args.sort
|
||||||
var test = await this.__match_args(args)
|
var test = await this.__match_args(args)
|
||||||
args = pwpath.joinArgs('', args)
|
args = pwpath.joinArgs('', args)
|
||||||
|
|
||||||
|
var order = (await this.metadata(path) ?? {}).order || []
|
||||||
|
|
||||||
// NOTE: we are matching full paths only here so leading and
|
// NOTE: we are matching full paths only here so leading and
|
||||||
// trainling '/' are optional...
|
// trainling '/' are optional...
|
||||||
var pattern = new RegExp(`^\\/?`
|
var pattern = new RegExp(`^\\/?`
|
||||||
+RegExp.quoteRegExp(
|
+RegExp.quoteRegExp(path)
|
||||||
// remove leading/trailing '/'
|
|
||||||
path.replace(/^\/|\/$/g, ''))
|
|
||||||
// pattern: **
|
// pattern: **
|
||||||
.replace(/\\\*\\\*/g, '(.*)')
|
.replace(/\\\*\\\*/g, '(.*)')
|
||||||
// pattern: *
|
// pattern: *
|
||||||
@ -860,7 +938,13 @@ module.BaseStore = {
|
|||||||
m[0].slice(1)
|
m[0].slice(1)
|
||||||
: m[0])
|
: m[0])
|
||||||
return res }, new Set())]
|
return res }, new Set())]
|
||||||
.sortAs(order)
|
// handle live sort...
|
||||||
|
.run(function(){
|
||||||
|
return (sort && sort !== true) ?
|
||||||
|
that
|
||||||
|
.sort(this, ...sort.split(/\s*[,\s]+/g))
|
||||||
|
:this
|
||||||
|
.sortAs(order) })
|
||||||
.map(function(p){
|
.map(function(p){
|
||||||
return p+args })}
|
return p+args })}
|
||||||
// direct search...
|
// direct search...
|
||||||
|
|||||||
@ -36,8 +36,12 @@
|
|||||||
* -
|
* -
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* XXX sort: define a generic sort path argument...
|
* XXX sort: define a generic sort path argument... DONE-ish
|
||||||
* ...this will unify all interfaces (macros/patterns/etc)
|
* XXX sort chains still not totally correct...
|
||||||
|
* This correctly shows Doc and WikiHome first
|
||||||
|
* await pwiki.store.sort('*', 'tags')
|
||||||
|
* This mixes them back up:
|
||||||
|
* await pwiki.store.sort('*', 'tags', 'ctime')
|
||||||
* XXX macros: else/default macro args essentially mean the same thing, should we
|
* XXX macros: else/default macro args essentially mean the same thing, should we
|
||||||
* unify them to use the same name???
|
* unify them to use the same name???
|
||||||
* XXX parser: error handling: revise page quoting...
|
* XXX parser: error handling: revise page quoting...
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user