@@ -4,6 +4,7 @@ const fs = require('fs');
4
4
const path = require ( 'path' ) ;
5
5
const { inspect} = require ( 'util' ) ;
6
6
const { sha256} = require ( 'js-sha256' ) ;
7
+ const styleToObject = require ( 'style-to-object' ) ;
7
8
const expressions = require ( 'posthtml-expressions' ) ;
8
9
const scriptDataLocals = require ( 'posthtml-expressions/lib/locals' ) ;
9
10
const { parser : parseToPostHtml } = require ( 'posthtml-parser' ) ;
@@ -12,6 +13,7 @@ const parseAttrs = require('posthtml-attrs-parser');
12
13
const { match} = require ( 'posthtml/lib/api' ) ;
13
14
const merge = require ( 'deepmerge' ) ;
14
15
const findPathFromTagName = require ( './find-path' ) ;
16
+ // const posthtml = require('posthtml');
15
17
16
18
const debug = true ;
17
19
@@ -63,7 +65,7 @@ function processNodes(tree, options, messages) {
63
65
options . expressions . locals = { ...options . locals , ...options . aware } ;
64
66
65
67
const defaultSlotName = sha256 ( filePath ) ;
66
- const slotsLocals = parseSlotsLocals ( options . slotTagName , html , node . content , defaultSlotName ) ;
68
+ const slotsLocals = parseSlotsLocals ( options . fillTagName , html , node . content , defaultSlotName ) ;
67
69
const { attributes, locals} = parseLocals ( options , slotsLocals , node , html ) ;
68
70
69
71
options . expressions . locals = attributes ;
@@ -74,33 +76,9 @@ function processNodes(tree, options, messages) {
74
76
const layoutTree = processNodes ( applyPluginsToTree ( html , plugins ) , options , messages ) ;
75
77
76
78
node . tag = false ;
77
- node . content = mergeSlots ( layoutTree , node , options . strict , options , defaultSlotName ) ;
78
-
79
- const index = node . content . findIndex ( content => typeof content === 'object' ) ;
80
-
81
- if ( index !== - 1 ) {
82
- // Map component attributes that it's not defined
83
- // as locals to first element of node
84
- // for now only class and style
85
- const nodeAttrs = parseAttrs ( node . content [ index ] . attrs ) ;
86
-
87
- Object . keys ( attributes ) . forEach ( attr => {
88
- if ( typeof locals [ attr ] === 'undefined' ) {
89
- if ( [ 'class' ] . includes ( attr ) ) {
90
- if ( typeof nodeAttrs [ attr ] === 'undefined' ) {
91
- nodeAttrs [ attr ] = [ ] ;
92
- }
93
-
94
- nodeAttrs [ attr ] . push ( attributes [ attr ] ) ;
95
- } else if ( [ 'style' ] . includes ( attr ) ) {
96
- // Append style ?
97
- nodeAttrs [ attr ] = attributes [ attr ] ;
98
- }
99
- }
100
- } ) ;
79
+ node . content = mergeSlots ( layoutTree , node , options , defaultSlotName ) ;
101
80
102
- node . content [ index ] . attrs = nodeAttrs . compose ( ) ;
103
- }
81
+ parseAttributes ( node , attributes , locals , options ) ;
104
82
105
83
messages . push ( {
106
84
type : 'dependency' ,
@@ -266,26 +244,77 @@ function parseSlotsLocals(tag, html, content, defaultSlotName) {
266
244
return slots ;
267
245
}
268
246
247
+ /**
248
+ * Map component attributes that it's not defined as locals to first element of node
249
+ * @param {Object } node
250
+ * @param {Object } attributes
251
+ * @param {Object } locals
252
+ * @param {Object } options
253
+ * @return {void }
254
+ */
255
+ function parseAttributes ( node , attributes , locals , options ) {
256
+ const index = node . content . findIndex ( content => typeof content === 'object' ) ;
257
+
258
+ if ( index !== - 1 ) {
259
+ const nodeAttrs = parseAttrs ( node . content [ index ] . attrs , options . attrsParserRules ) ;
260
+
261
+ Object . keys ( attributes ) . forEach ( attr => {
262
+ if ( typeof locals [ attr ] === 'undefined' ) {
263
+ if ( [ 'class' ] . includes ( attr ) ) {
264
+ // Merge class
265
+ if ( typeof nodeAttrs . class === 'undefined' ) {
266
+ nodeAttrs . class = [ ] ;
267
+ }
268
+
269
+ nodeAttrs . class . push ( attributes . class ) ;
270
+
271
+ delete attributes . class ;
272
+ } else if ( [ 'override:class' ] . includes ( attr ) ) {
273
+ // Override class
274
+ nodeAttrs . class = attributes [ 'override:class' ] ;
275
+
276
+ delete attributes [ 'override:class' ] ;
277
+ } else if ( [ 'style' ] . includes ( attr ) ) {
278
+ // Merge style
279
+ if ( typeof nodeAttrs . style === 'undefined' ) {
280
+ nodeAttrs . style = { } ;
281
+ }
282
+
283
+ nodeAttrs . style = Object . assign ( nodeAttrs . style , styleToObject ( attributes . style ) ) ;
284
+ delete attributes . style ;
285
+ } else if ( [ 'override:style' ] . includes ( attr ) ) {
286
+ // Override style
287
+ nodeAttrs . style = attributes [ 'override:style' ] ;
288
+ delete attributes [ 'override:style' ] ;
289
+ }
290
+ }
291
+ } ) ;
292
+
293
+ node . content [ index ] . attrs = nodeAttrs . compose ( ) ;
294
+ }
295
+ }
296
+
269
297
/**
270
298
* Merge slots content
271
299
* @param {Object } tree
272
300
* @param {Object } node
273
301
* @param {Boolean } strict
274
302
* @param {String } slotTagName
303
+ * @param {String } fillTagName
275
304
* @param {Boolean|String } fallbackSlotTagName
276
305
* @param defaultSlotName
277
306
* @return {Object } tree
278
307
*/
279
- function mergeSlots ( tree , node , strict , { slotTagName, fallbackSlotTagName} , defaultSlotName ) {
308
+ function mergeSlots ( tree , node , { strict, slotTagName, fillTagName , fallbackSlotTagName} , defaultSlotName ) {
280
309
const slots = getSlots ( slotTagName , tree , defaultSlotName , fallbackSlotTagName ) ; // Slot in component.html
281
- const fillSlots = getSlots ( slotTagName , node . content , defaultSlotName ) ; // Slot in page.html
310
+ const fillSlots = getSlots ( fillTagName , node . content , defaultSlotName ) ; // Slot in page.html
282
311
const clean = content => content . replace ( / ( \n | \t ) / g, '' ) . trim ( ) ;
283
312
284
313
// Retrieve main content, means everything that is not inside slots
285
314
if ( node . content ) {
286
- const contentOutsideSlots = node . content . filter ( content => ( content . tag !== slotTagName ) ) ;
315
+ const contentOutsideSlots = node . content . filter ( content => ( content . tag !== fillTagName ) ) ;
287
316
if ( contentOutsideSlots . filter ( c => typeof c !== 'string' || clean ( c ) !== '' ) . length > 0 ) {
288
- fillSlots [ defaultSlotName ] = [ { tag : slotTagName , attrs : { name : defaultSlotName } , content : [ ...contentOutsideSlots ] } ] ;
317
+ fillSlots [ defaultSlotName ] = [ { tag : fillTagName , attrs : { name : defaultSlotName } , content : [ ...contentOutsideSlots ] } ] ;
289
318
}
290
319
291
320
// Replace <content> with <block>
@@ -429,6 +458,12 @@ function applyPluginsToTree(tree, plugins) {
429
458
} , tree ) ;
430
459
}
431
460
461
+ // function processWithPostHtml(html, options = {}, plugins = []) {
462
+ // return posthtml(plugins)
463
+ // .process(html, options)
464
+ // .then(result => result.tree);
465
+ // }
466
+
432
467
module . exports = ( options = { } ) => {
433
468
options = {
434
469
...{
@@ -441,6 +476,7 @@ module.exports = (options = {}) => {
441
476
tagPrefix : 'x-' ,
442
477
tagRegExp : new RegExp ( `^${ options . tagPrefix || 'x-' } ` , 'i' ) ,
443
478
slotTagName : 'slot' ,
479
+ fillTagName : 'slot' ,
444
480
// Used for compatibility with modules plugin <content> slot, set to true only if you have migrated from modules plugin
445
481
fallbackSlotTagName : false ,
446
482
tagName : 'component' ,
@@ -452,7 +488,8 @@ module.exports = (options = {}) => {
452
488
encoding : 'utf8' ,
453
489
scriptLocalAttribute : 'props' ,
454
490
matcher : [ ] ,
455
- strict : true
491
+ strict : true ,
492
+ attrsParserRules : { }
456
493
} ,
457
494
...options
458
495
} ;
0 commit comments