From c68095f97aa5dc266ada4e68364cc7f19eabff61 Mon Sep 17 00:00:00 2001 From: "Alex A. Naanou" Date: Sun, 25 Sep 2022 19:22:32 +0300 Subject: [PATCH] refactoring + fixes... Signed-off-by: Alex A. Naanou --- pwiki/page.js | 8 ++++++- pwiki/path.js | 63 +++++++++++++++++++++++++++++++++++++-------------- pwiki2.html | 18 ++++++++------- pwiki2.js | 1 - 4 files changed, 63 insertions(+), 27 deletions(-) diff --git a/pwiki/page.js b/pwiki/page.js index 2dc6b7b..754f169 100755 --- a/pwiki/page.js +++ b/pwiki/page.js @@ -161,9 +161,9 @@ object.Constructor('BasePage', { && this.__beforenavigate__(location) }), onNavigate: types.event.Event('navigate', function(handle, location){ + var {path, args} = pwpath.splitArgs(location) this.onBeforeNavigate(location) this.referrer = this.location - var {path, args} = pwpath.splitArgs(location) var cur = this.__location = this.resolvePathVars( // NOTE: this is done instead of simply assigning @@ -213,6 +213,8 @@ object.Constructor('BasePage', { get name(){ return pwpath.basename(this.path) }, set name(value){ + if(pwpath.normalize(value) == ''){ + return } this.move( /^[\\\/]/.test(value) ? value @@ -405,6 +407,8 @@ object.Constructor('BasePage', { // XXX should these be implemented here or proxy to .store??? // XXX do we sanity check to no not contain '*'??? copy: async function(to, base=true){ + if(this.get(to).path == this.path){ + return this } // copy children... if(this.isPattern){ var base = this.path.split('*')[0] @@ -422,6 +426,8 @@ object.Constructor('BasePage', { return this }, move: async function(to, base=true){ var from = this.path + if(this.get(to).path == this.path){ + return this } await this.copy(to, base) this.delete(from, base) return this }, diff --git a/pwiki/path.js b/pwiki/path.js index 52a31b3..2ccd602 100755 --- a/pwiki/path.js +++ b/pwiki/path.js @@ -10,6 +10,34 @@ var types = require('ig-types') +//--------------------------------------------------------------------- + +var makeEncoder = function(name, chars){ + var pattern_attr = '__'+name+'_pattern' + return function(str){ + var pattern = this[pattern_attr] = + this[pattern_attr] + ?? RegExp(`[${ + this[chars] + .replace(/\\/g, '\\\\') }]`, 'g') + return str + .replace(pattern, + function(s){ + return ('%'+s.charCodeAt().toString(16)).toUpperCase() }) } } +var makeDecoder = function(name, encode, chars){ + var pattern_attr = '__'+name+'_pattern' + return function(str){ + var pattern = this[pattern_attr] = + this[pattern_attr] + ?? RegExp(`%(${ + this[encode](this[chars]) + .slice(1) + .replace(/%/g, '|') })`, 'gi') + return str + .replace(pattern, function(_, c){ + return String.fromCharCode('0x'+c) }) } } + + //--------------------------------------------------------------------- // Path... @@ -50,20 +78,20 @@ module = { SYSTEM_PATH: '/.system', // XXX EXPERIMENTAL - encode: function(str){ - return str - .replace(/[#:*%]/g, - function(s){ - return '%'+s.charCodeAt().toString(16) }) }, - decode: function(str){ - return decodeURIComponent(str) }, - encodeElem: function(str){ - return str - .replace(/[#:*%\\\/]/g, - function(s){ - return '%'+s.charCodeAt().toString(16) }) }, - decodeElem: function(str){ - return decodeURIComponent(str) }, + + ENCODED_PATH: '#:*%', + encode: makeEncoder('encode', 'ENCODED_PATH'), + decode: makeDecoder('decode', 'encode', 'ENCODED_PATH'), + + ENCODED_ELEM: '#:*%\\/', + encodeElem: makeEncoder('encode_elem', 'ENCODED_ELEM'), + decodeElem: makeDecoder('decode_elem', 'encodeElem', 'ENCODED_ELEM'), + + // chars we keep in path as-is -- decode on normalize... + // + UNENCODED_PATH: '\'"', + quote: makeEncoder('quote', 'UNENCODED_PATH'), + unquote: makeDecoder('unquote', 'quote', 'UNENCODED_PATH'), /*/ XXX NORMCACHE... __normalized_cache_threshold: 100, @@ -104,9 +132,10 @@ module = { : format var root = path[0] == '' || path[0] == '/' - path = (path instanceof Array ? - path.join('/') - : path) + path = this.unquote( + path instanceof Array ? + path.join('/') + : path) // NOTE: this will also trim the path elements... .split(/\s*[\\\/]+\s*/) .reduce(function(res, e, i, L){ diff --git a/pwiki2.html b/pwiki2.html index 8be6011..6d02fd1 100755 --- a/pwiki2.html +++ b/pwiki2.html @@ -102,6 +102,15 @@ body.loading .page.spinner span { } } +[contenteditable] { + outline: 0px solid transparent; +} +[contenteditable]:empty:after { + display: block; + content: 'Empty'; + opacity: 0.3; +} + @@ -178,9 +187,6 @@ var SAVE_LIVE_QUEUE = {} var saveLiveContent = function(path, text){ - path = path - .replace(/%22/g, '"') - .replace(/%27/g, "'") SAVE_LIVE_QUEUE[path] = text // clear editor page cache... pwiki.cache = null } @@ -188,11 +194,7 @@ function(path, text){ var SAVE_QUEUE = {} var saveContent = function(path, text){ - path = path - .replace(/%22/g, '"') - .replace(/%27/g, "'") - SAVE_QUEUE[path] = text -} + SAVE_QUEUE[path] = text } var saveAll = function(){ diff --git a/pwiki2.js b/pwiki2.js index 646a496..f93d620 100755 --- a/pwiki2.js +++ b/pwiki2.js @@ -15,7 +15,6 @@ * pwiki.path = '/tree' // reports about ~2sec * await pwiki.get('/Test/Subtree/Page2').delete() // fast * pwiki.path = '/tree' // reports about ~2sec -* XXX FEATURE would be nice to have a deleteAll action... * XXX macros: should we add the pattern path to .depends instead of the * final path... * ...would also need a fast way to pattern match...