22
33const fs = require ( 'fs' ) ;
44const path = require ( 'path' ) ;
5+ const { inspect} = require ( 'util' ) ;
6+ const { sha256} = require ( 'js-sha256' ) ;
57const expressions = require ( 'posthtml-expressions' ) ;
68const scriptDataLocals = require ( 'posthtml-expressions/lib/locals' ) ;
79const { parser : parseToPostHtml } = require ( 'posthtml-parser' ) ;
@@ -11,8 +13,13 @@ const {match} = require('posthtml/lib/api');
1113const merge = require ( 'deepmerge' ) ;
1214const findPathFromTagName = require ( './find-path' ) ;
1315
14- // Used for slot without name
15- const defaultSlotName = '__default-slot' ;
16+ const debug = true ;
17+
18+ const log = ( object , what ) => {
19+ if ( debug ) {
20+ console . log ( what , inspect ( object , false , null , true ) ) ;
21+ }
22+ } ;
1623
1724const defaultSlotType = 'replace' ;
1825
@@ -55,7 +62,8 @@ function processNodes(tree, options, messages) {
5562
5663 options . expressions . locals = { ...options . locals , ...options . aware } ;
5764
58- const slotsLocals = parseSlotsLocals ( options . slotTagName , html , node . content ) ;
65+ const defaultSlotName = sha256 ( filePath ) ;
66+ const slotsLocals = parseSlotsLocals ( options . slotTagName , html , node . content , defaultSlotName ) ;
5967 const { attributes, locals} = parseLocals ( options , slotsLocals , node , html ) ;
6068
6169 options . expressions . locals = attributes ;
@@ -66,7 +74,7 @@ function processNodes(tree, options, messages) {
6674 const layoutTree = processNodes ( applyPluginsToTree ( html , plugins ) , options , messages ) ;
6775
6876 node . tag = false ;
69- node . content = mergeSlots ( layoutTree , node , options . strict , options ) ;
77+ node . content = mergeSlots ( layoutTree , node , options . strict , options , defaultSlotName ) ;
7078
7179 const index = node . content . findIndex ( content => typeof content === 'object' ) ;
7280
@@ -199,13 +207,18 @@ function parseLocals(options, slotsLocals, {attrs}, html) {
199207 * @param {String } tag
200208 * @param html
201209 * @param {Object } content
210+ * @param {String } defaultSlotName
202211 * @return {Object }
203212 */
204- function parseSlotsLocals ( tag , html , content = [ ] ) {
213+ function parseSlotsLocals ( tag , html , content , defaultSlotName ) {
205214 const slots = { } ;
206215
207216 const getNodeName = node => {
208- let name = node . attrs && node . attrs . name ;
217+ if ( ! node . attrs ) {
218+ node . attrs = { } ;
219+ }
220+
221+ let { name} = node . attrs ;
209222
210223 if ( ! name ) {
211224 name = Object . keys ( { ...node . attrs } ) . find ( name => ! Object . keys ( slotTypes ) . includes ( name ) && name !== 'type' && name !== defaultSlotType ) ;
@@ -260,11 +273,12 @@ function parseSlotsLocals(tag, html, content = []) {
260273 * @param {Boolean } strict
261274 * @param {String } slotTagName
262275 * @param {Boolean|String } fallbackSlotTagName
276+ * @param defaultSlotName
263277 * @return {Object } tree
264278 */
265- function mergeSlots ( tree , node , strict , { slotTagName, fallbackSlotTagName} ) {
266- const slots = getSlots ( slotTagName , tree , fallbackSlotTagName ) ; // Slot in component.html
267- const fillSlots = getSlots ( slotTagName , node . content ) ; // Slot in page.html
279+ function mergeSlots ( tree , node , strict , { slotTagName, fallbackSlotTagName} , defaultSlotName ) {
280+ const slots = getSlots ( slotTagName , tree , defaultSlotName , fallbackSlotTagName ) ; // Slot in component.html
281+ const fillSlots = getSlots ( slotTagName , node . content , defaultSlotName ) ; // Slot in page.html
268282 const clean = content => content . replace ( / ( \n | \t ) / g, '' ) . trim ( ) ;
269283
270284 // Retrieve main content, means everything that is not inside slots
@@ -273,6 +287,18 @@ function mergeSlots(tree, node, strict, {slotTagName, fallbackSlotTagName}) {
273287 if ( contentOutsideSlots . filter ( c => typeof c !== 'string' || clean ( c ) !== '' ) . length > 0 ) {
274288 fillSlots [ defaultSlotName ] = [ { tag : slotTagName , attrs : { name : defaultSlotName } , content : [ ...contentOutsideSlots ] } ] ;
275289 }
290+
291+ // Replace <content> with <block>
292+ // required only when using extend + module syntax
293+ if ( fallbackSlotTagName && slots [ defaultSlotName ] ) {
294+ slots [ defaultSlotName ] . map ( slot => {
295+ if ( slot . tag === ( fallbackSlotTagName === true ? 'content' : fallbackSlotTagName ) ) {
296+ slot . tag = slotTagName ;
297+ }
298+
299+ return slot ;
300+ } ) ;
301+ }
276302 }
277303
278304 for ( const slotName of Object . keys ( slots ) ) {
@@ -351,10 +377,11 @@ function mergeContent(slotContent, defaultContent, slotType) {
351377 * Get all slots from content
352378 * @param {String } tag
353379 * @param {Object } content
380+ * @param defaultSlotName
354381 * @param {Boolean|String } fallbackSlotTagName
355382 * @return {Object }
356383 */
357- function getSlots ( tag , content = [ ] , fallbackSlotTagName = false ) {
384+ function getSlots ( tag , content , defaultSlotName , fallbackSlotTagName = false ) {
358385 const slots = { } ;
359386
360387 // For compatibility with module slot name <content>
@@ -486,6 +513,10 @@ module.exports = (options = {}) => {
486513 options . locals = { ...options . expressions . locals } ;
487514 options . aware = { } ;
488515
516+ // options.locals.$isUndefined = value => value === void 0
517+
518+ log ( debug , 'Debug enabled?' ) ;
519+
489520 return function ( tree ) {
490521 tree = processNodes ( tree , options , tree . messages ) ;
491522
0 commit comments