2
2
3
3
const merge = require ( 'deepmerge' ) ;
4
4
const scriptDataLocals = require ( 'posthtml-expressions/lib/locals' ) ;
5
- const { pick, extend} = require ( 'underscore' ) ;
6
- // const {inspect} = require('util');
7
- //
8
- // const debug = true;
9
- //
10
- // const log = (object, what, method) => {
11
- // if (debug === true || method === debug) {
12
- // console.log(what, inspect(object, false, null, true));
13
- // }
14
- // };
5
+ const { pick, extend, keys, defaults, each} = require ( 'underscore' ) ;
6
+ const attributeTypes = [ 'merge' , 'computed' , 'aware' ] ;
15
7
16
8
/**
17
9
* Parse locals from attributes, globals and via script
@@ -25,81 +17,69 @@ const {pick, extend} = require('underscore');
25
17
module . exports = ( currentNode , nextNode , slotContent , options ) => {
26
18
let attributes = { ...currentNode . attrs } ;
27
19
28
- const merged = [ ] ;
29
- const computed = [ ] ;
30
- const aware = [ ] ;
31
-
32
- Object . keys ( attributes ) . forEach ( attributeName => {
33
- const newAttributeName = attributeName
34
- . replace ( 'merge:' , '' )
35
- . replace ( 'computed:' , '' )
36
- . replace ( 'aware:' , '' ) ;
37
-
38
- switch ( true ) {
39
- case attributeName . startsWith ( 'merge:' ) :
40
- attributes [ newAttributeName ] = attributes [ attributeName ] ;
41
- delete attributes [ attributeName ] ;
42
- merged . push ( newAttributeName ) ;
43
- break ;
44
-
45
- case attributeName . startsWith ( 'computed:' ) :
46
- attributes [ newAttributeName ] = attributes [ attributeName ] ;
47
- delete attributes [ attributeName ] ;
48
- computed . push ( newAttributeName ) ;
49
- break ;
20
+ const attributesByTypeName = { } ;
21
+ each ( attributeTypes , type => {
22
+ attributesByTypeName [ type ] = [ ] ;
23
+ } ) ;
50
24
51
- case attributeName . startsWith ( 'aware:' ) :
52
- attributes [ newAttributeName ] = attributes [ attributeName ] ;
53
- delete attributes [ attributeName ] ;
54
- aware . push ( newAttributeName ) ;
55
- break ;
25
+ each ( attributes , ( value , key , attrs ) => {
26
+ let newKey = key ;
27
+ each ( attributeTypes , type => {
28
+ if ( key . startsWith ( `${ type } :` ) ) {
29
+ newKey = newKey . replace ( `${ type } :` , '' ) ;
30
+ attributesByTypeName [ type ] . push ( newKey ) ;
31
+ }
32
+ } ) ;
56
33
57
- default : break ;
34
+ if ( newKey !== key ) {
35
+ attrs [ newKey ] = value ;
36
+ delete attrs [ key ] ;
58
37
}
59
38
} ) ;
60
39
61
40
// Parse JSON attributes
62
- Object . keys ( attributes ) . forEach ( attributeName => {
41
+ each ( attributes , ( value , key , attrs ) => {
63
42
try {
64
- const parsed = JSON . parse ( attributes [ attributeName ] ) ;
65
- if ( attributeName === 'locals' ) {
66
- if ( merged . includes ( attributeName ) ) {
67
- attributes = merge ( attributes , parsed ) ;
68
- merged . splice ( merged . indexOf ( 'locals' ) , 1 ) ;
69
- } else {
70
- // Override with merge see https://www.npmjs.com/package/deepmerge#arraymerge-example-overwrite-target-array
71
- Object . assign ( attributes , parsed ) ;
72
- }
73
- } else {
74
- attributes [ attributeName ] = parsed ;
75
- }
43
+ attrs [ key ] = JSON . parse ( value ) ;
76
44
} catch { }
77
45
} ) ;
78
46
79
- delete attributes . locals ;
47
+ // Merge or extend attribute locals
48
+ if ( attributes . locals ) {
49
+ if ( attributesByTypeName . merge . includes ( 'locals' ) ) {
50
+ attributesByTypeName . merge . splice ( attributesByTypeName . merge . indexOf ( 'locals' ) , 1 ) ;
51
+ attributes = merge ( attributes , attributes . locals ) ;
52
+ } else {
53
+ extend ( attributes , attributes . locals ) ;
54
+ }
55
+
56
+ delete attributes . locals ;
57
+ }
80
58
81
59
// Merge with global
82
60
attributes = merge ( options . expressions . locals , attributes ) ;
83
61
84
62
// Retrieve default locals from <script props> and merge with attributes
85
63
const { locals} = scriptDataLocals ( nextNode , { localsAttr : options . localsAttr , removeScriptLocals : true , locals : { ...attributes , $slots : slotContent } } ) ;
86
64
87
- // Merge or overrides props and attributes
88
65
if ( locals ) {
89
- if ( merged . length > 0 ) {
90
- extend ( attributes , merge ( pick ( locals , merged ) , pick ( attributes , merged ) ) ) ;
66
+ // Merge attributes
67
+ if ( attributesByTypeName . merge . length > 0 ) {
68
+ extend ( attributes , merge ( pick ( locals , attributesByTypeName . merge ) , pick ( attributes , attributesByTypeName . merge ) ) ) ;
91
69
}
92
70
93
- // Override attributes with props when is computed or attribute is not defined
94
- Object . keys ( locals ) . forEach ( attributeName => {
95
- if ( computed . includes ( attributeName ) || typeof attributes [ attributeName ] === 'undefined' ) {
96
- attributes [ attributeName ] = locals [ attributeName ] ;
97
- }
98
- } ) ;
71
+ // Override attributes with computed locals
72
+ if ( attributesByTypeName . computed . length > 0 ) {
73
+ extend ( attributes , pick ( locals , keys ( pick ( attributes , attributesByTypeName . computed ) ) ) ) ;
74
+ }
75
+
76
+ // Set attributes not defined
77
+ defaults ( attributes , locals ) ;
99
78
}
100
79
101
- if ( aware . length > 0 ) {
102
- options . aware = Object . fromEntries ( Object . entries ( attributes ) . filter ( ( [ attributeName ] ) => aware . includes ( attributeName ) ) ) ;
80
+ // Set aware attributes
81
+ if ( attributesByTypeName . aware . length > 0 ) {
82
+ options . aware = pick ( attributes , attributesByTypeName . aware ) ;
103
83
}
104
84
105
85
return { attributes, locals} ;
0 commit comments