Compare commits

...

4 Commits

Author SHA1 Message Date
78af3300c2 refactoring and cleanup...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
2023-12-26 04:54:08 +03:00
9348afd5c8 made system attrs safe from being overwritten from code directly...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
2023-12-26 04:30:09 +03:00
06f22772f5 cleanup...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
2023-12-26 04:18:28 +03:00
c85531dc12 more work on attr support... still need testing...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
2023-12-26 02:07:04 +03:00
2 changed files with 71 additions and 43 deletions

View File

@ -203,15 +203,14 @@ var plugin = {
var attributes = { var attributes = {
__proto__: plugin, __proto__: plugin,
// XXX should attr settings be set here or in the Outline???
// ...this includes .__block_attrs__ and .__system_attrs__
// //
// Parse attrs... // Parse attrs...
// .parseBlockAttrs(<text>[, <elem>]) // .parseBlockAttrs(<text>[, <elem>])
// -> [<elem>, <attrs>, <sys-attrs>] // -> [<elem>, <attrs>, <sys-attrs>]
// //
// XXX where should we get .__block_attrs__???
// ...editor (current), plugin, ...???
// XXX might be a good idea to split out the actual code handler to
// be overloadable by other plugins...
parseBlockAttrs: function(editor, text, elem={}){ parseBlockAttrs: function(editor, text, elem={}){
var system = editor.__block_attrs__ var system = editor.__block_attrs__
var attrs = '' var attrs = ''
@ -229,18 +228,29 @@ var attributes = {
.split(/(?:[\t ]*::[\t ]*|[\t ]*\n[\t ]*)/g) .split(/(?:[\t ]*::[\t ]*|[\t ]*\n[\t ]*)/g)
while(match.length > 0){ while(match.length > 0){
var [name, val] = match.splice(0, 2) var [name, val] = match.splice(0, 2)
// ignore non-settable attrs...
if(editor.__system_attrs__.includes(name)){
continue }
elem[name] = elem[name] =
val == 'true' ? val == 'true' ?
true true
: val == 'false' ? : val == 'false' ?
false false
: val : val }
// keep non-system attrs...
if(!(name in system)){
attrs += `\n${name}::${val}`
} else {
sysattrs += `\n${name}::${val}` } }
return ws }) return ws })
// build the attr strings...
// NOTE: we are not doing this in the loop above to include all
// the attributes that are in the elem but not explicitly
// given in code...
for(var name in elem){
// ignore non-settable attrs...
if(editor.__system_attrs__.includes(name)){
continue }
var val = elem[name]
if(!(name in system)){
attrs += `\n${name}::${val}`
} else {
sysattrs += `\n${name}::${val}` } }
return [ return [
elem, elem,
attrs, attrs,
@ -248,26 +258,46 @@ var attributes = {
] }, ] },
// generate code... // generate code...
//
// this is controlled by the value of editor.__code_attrs__:
// false / undefined - strip attrs
// true - add attrs to code if available
// 'all' - add attrs, including system attrs to
// code if available,
__parse_code__: function(code, editor, elem){ __parse_code__: function(code, editor, elem){
var [elem, attrs, system] = this.parseBlockAttrs(editor, code, elem) var [elem, attrs, system] = this.parseBlockAttrs(editor, code, elem)
return !editor.__code_attrs__ ? return !editor.__code_attrs__ ?
elem.text elem.text
: editor.__code_attrs__ == 'all' ? : editor.__code_attrs__ == 'all' ?
elem.text +'\n'+ attrs +'\n'+ system elem.text
: elem.text +'\n'+ attrs }, + (attrs.length > 0 ?
'\n'+ attrs
: '')
+ (system.length > 0 ?
'\n'+ system
: '')
: attrs.length > 0 ?
elem.text +'\n'+ attrs
: elem.text },
// generate view... // generate view...
//
// this is controlled by the value of editor.__view_attrs__:
// false / undefined - strip attrs
// true - call the handler XXX
__pre_parse__: function(text, editor, elem){ __pre_parse__: function(text, editor, elem){
// NOTE: we are intentionally neglecting system attrs here...
var [elem, attrs, system] = this.parseBlockAttrs(editor, text, elem) var [elem, attrs, system] = this.parseBlockAttrs(editor, text, elem)
// XXX use filter handler here... if(editor.__view_attrs__
return !editor.__view_attrs__ ? && attrs.length > 0){
elem.text attrs = editor.threadPlugins('__parse_attrs__', attrs, editor, elem)
: elem.text +'\n'+ attrs if(attrs && attrs.length > 0){
}, return text +'\n'+ attrs } }
return elem.text },
// XXX // XXX
__parse_attrs__: function(){ //__parse_attrs__: function(attrs, editor, elem){
// XXX // return attrs }
}
} }
@ -903,12 +933,17 @@ var JSONOutline = {
__code_attrs__: false, __code_attrs__: false,
__view_attrs__: false, __view_attrs__: false,
__system_attrs__: [
'text',
'children',
],
__block_attrs__: { __block_attrs__: {
id: 'attr', id: 'attr',
collapsed: 'attr', collapsed: 'attr',
focused: 'cls', focused: 'cls',
}, },
// Plugins... // Plugins...
// //
// The order of plugins can be significant in the following cases: // The order of plugins can be significant in the following cases:
@ -1175,6 +1210,7 @@ var JSONOutline = {
// XXX add plugin hooks... // XXX add plugin hooks...
// XXX add option to customize indent size... // XXX add option to customize indent size...
text: function(node, indent, level){ text: function(node, indent, level){
var that = this
// .text(<indent>, <level>) // .text(<indent>, <level>)
if(typeof(node) == 'string'){ if(typeof(node) == 'string'){
;[node, indent=' ', level=''] = [undefined, ...arguments] } ;[node, indent=' ', level=''] = [undefined, ...arguments] }
@ -1190,8 +1226,7 @@ var JSONOutline = {
// attrs... // attrs...
+ (Object.keys(elem) + (Object.keys(elem)
.reduce(function(res, attr){ .reduce(function(res, attr){
return (attr == 'text' return that.__system_attrs__.includes(attr) ?
|| attr == 'children') ?
res res
: res : res
+ (elem[attr] ? + (elem[attr] ?
@ -1217,7 +1252,7 @@ var JSONOutline = {
var attrs = [] var attrs = []
for(var [attr, value] of Object.entries({...data, ...parsed})){ for(var [attr, value] of Object.entries({...data, ...parsed})){
if(attr == 'children' || attr == 'text'){ if(this.__system_attrs__.includes(attr)){
continue } continue }
var i var i
var type = this.__block_attrs__[attr] var type = this.__block_attrs__[attr]
@ -1640,9 +1675,13 @@ var Outline = {
//this._syncTextSize(code, html) } //this._syncTextSize(code, html) }
for(var [attr, value] of Object.entries({...data, ...parsed})){ for(var [attr, value] of Object.entries({...data, ...parsed})){
if(attr == 'children' || attr == 'text'){ if(this.__system_attrs__.includes(attr)){
continue } continue }
// quoted value...
if(value && /^\s*([`'"])([^\1]*)\1\s*$/.test(value)){
value = value.replace(/^\s*([`'"])([^\1]*)\1\s*$/, '$2') }
var type = this.__block_attrs__[attr] var type = this.__block_attrs__[attr]
if(type == 'cls'){ if(type == 'cls'){
value ? value ?
@ -1658,6 +1697,7 @@ var Outline = {
: node.removeAttribute(attr) : node.removeAttribute(attr)
// dataset... // dataset...
} else { } else {
// remove attr...
if(value == null if(value == null
|| value == 'null' || value == 'null'
|| value == 'undefined'){ || value == 'undefined'){

View File

@ -143,27 +143,14 @@ var setup = function(){
- -
- ## ToDo: - ## ToDo:
- ASAP: expand sub-tree on follow link... - ASAP: expand sub-tree on follow link...
- ASAP: attributes: finalize base mechanics: - ASAP TEST: attributes: finalize base mechanics...
- code filtering
```
.__code_attrs__(attrs, code, elem)
-> true
-> false
```
_system attrs are always hidden, the client can control whether the code is shown or not_
- view filtering
```
.__view_attrs__(attrs, code, elem)
-> str
-> undefined
```
- might be a good idea to change `.parseBlockAttrs(..)` to return an array of text and attrs (str) and handle the above `.__code_attrs__(..)` and `.__view_attrs__(..)` in the respective handlers...
- attributes: need to show/hide the attributes -- option? - attributes: need to show/hide the attributes -- option?
attr::value attr::value
- `.__parse_code__(..)`: add data attributes to code if missing... - DONE `.__parse_code__(..)`: add data attributes to code if missing...
- do we need `.__code_attrs__` / `.__view_attrs__`??? - DONE do we need `.__code_attrs__` / `.__view_attrs__`??? -- YES
- handle attr delete correctly -- i.e. if shown attr removed from code -> delete attr... - DONE delete attr from code -- by setting it to `"null"` or `"undefined"`...
- BUG? can't set `''` as attr value -- parser?? - delete attr from code -- by removing it from attr list (when shown)...
- DONE BUG? can't set `''` as attr value -- parser??
- TOC: tweaking: add args like depth, ... -- as attributes... - TOC: tweaking: add args like depth, ... -- as attributes...
- TOC: should it be persistently generated as code and be serializable? - TOC: should it be persistently generated as code and be serializable?
- simple use strategies: - simple use strategies:
@ -289,6 +276,7 @@ var setup = function(){
- `<editable/>` -- field marker - `<editable/>` -- field marker
- each child node will copy the template and allow editing of only fields - each child node will copy the template and allow editing of only fields
- not clear how to handle template changes... - not clear how to handle template changes...
- DONE attributes: might be a good idea to prevent setting `.text` and `.children` attrs...
- DONE TOC: Q: should we have both manual and auto headings??? - DONE TOC: Q: should we have both manual and auto headings???
collapsed:: true collapsed:: true
- IMHO: no... - IMHO: no...