@@ -10,6 +10,22 @@ const {match} = require('posthtml/lib/api');
1010const merge = require ( 'deepmerge' ) ;
1111const findPathFromTagName = require ( './find-path' ) ;
1212
13+ // Used for slot without name
14+ const defaultSlotName = '___default__slot__name___' ;
15+
16+ const defaultSlotType = 'replace' ;
17+
18+ const slotTypes = {
19+ append : 'append' ,
20+ prepend : 'prepend'
21+ } ;
22+
23+ /**
24+ * Process tree's nodes
25+ * @param {Object } tree - posthtml tree
26+ * @param {Object } options - plugin options
27+ * @param {Object } messages - posthtml tree messages
28+ */
1329function processNodes ( tree , options , messages ) {
1430 tree = applyPluginsToTree ( tree , options . plugins ) ;
1531
@@ -71,6 +87,13 @@ function processNodes(tree, options, messages) {
7187 return tree ;
7288}
7389
90+ /**
91+ * Parse locals from attributes, globals and via script
92+ * @param {Object } tree - posthtml tree
93+ * @param {Object } options - plugin options
94+ * @param {Object } html - posthtml tree
95+ * @return {Object } merged locals and default
96+ */
7497function parseLocals ( options , { attrs} , html ) {
7598 let attributes = { ...attrs } ;
7699
@@ -96,6 +119,14 @@ function parseLocals(options, {attrs}, html) {
96119 return { attributes, defaultLocals} ;
97120}
98121
122+ /**
123+ * Merge slots content
124+ * @param {Object } tree
125+ * @param {Object } component
126+ * @param {Boolean } strict
127+ * @param {String } slotTagName
128+ * @return {Object } tree
129+ */
99130function mergeSlots ( tree , component , strict , slotTagName ) {
100131 const slots = getSlots ( slotTagName , tree ) ; // Slot in component.html
101132 const fillSlots = getSlots ( slotTagName , component . content ) ; // Slot in page.html
@@ -114,9 +145,8 @@ function mergeSlots(tree, component, strict, slotTagName) {
114145 continue ;
115146 }
116147
117- const slotType = [ 'replace' , 'prepend' , 'append' ] . includes ( ( ( slotNode . attrs && slotNode . attrs . type ) || '' ) . toLowerCase ( ) ) ?
118- ( ( slotNode . attrs && slotNode . attrs . type ) || '' ) . toLowerCase ( ) :
119- 'replace' ;
148+ let slotType = slotTypes [ ( slotNode . attrs . type || defaultSlotType ) . toLowerCase ( ) ] || defaultSlotType ;
149+ slotType = typeof slotNode . attrs . append === 'undefined' ? ( typeof slotNode . attrs . prepend === 'undefined' ? slotType : slotTypes . prepend ) : slotTypes . append ;
120150
121151 const layoutBlockNodeList = slots [ slotName ] ;
122152 for ( const layoutBlockNode of layoutBlockNodeList ) {
@@ -145,25 +175,48 @@ function mergeSlots(tree, component, strict, slotTagName) {
145175 return tree ;
146176}
147177
178+ /**
179+ * Prepend, append or replace slot content
180+ * @param {Object } slotContent
181+ * @param {Object } defaultContent
182+ * @param {String } slotType
183+ * @return {Object }
184+ */
148185function mergeContent ( slotContent , defaultContent , slotType ) {
149186 slotContent = slotContent || [ ] ;
150187 defaultContent = defaultContent || [ ] ;
151188
152- if ( ! [ 'append' , 'prepend' ] . includes ( slotType ) ) {
189+ // Replace
190+ if ( ! Object . keys ( slotTypes ) . includes ( slotType ) ) {
153191 return slotContent ;
154192 }
155193
156- return slotType === 'prepend' ?
194+ // Prepend or append
195+ return slotType === slotTypes . prepend ?
157196 slotContent . concat ( defaultContent ) :
158197 defaultContent . concat ( slotContent ) ;
159198}
160199
200+ /**
201+ * Get all slots from content
202+ * @param {String } tag
203+ * @param {Object } content
204+ * @return {Object }
205+ */
161206function getSlots ( tag , content = [ ] ) {
162207 const slots = { } ;
163208
164209 match . call ( content , { tag} , node => {
165- if ( ! node . attrs || ! node . attrs . name ) {
166- throw new Error ( '[components] Missing slot name' ) ;
210+ if ( ! node . attrs ) {
211+ node . attrs = { } ;
212+ }
213+
214+ if ( ! node . attrs . name ) {
215+ node . attrs . name = Object . keys ( { ...node . attrs } ) . find ( name => ! Object . keys ( slotTypes ) . includes ( name ) && name !== 'type' ) ;
216+ }
217+
218+ if ( ! node . attrs . name ) {
219+ node . attrs . name = defaultSlotName ;
167220 }
168221
169222 const { name} = node . attrs ;
@@ -180,6 +233,12 @@ function getSlots(tag, content = []) {
180233 return slots ;
181234}
182235
236+ /**
237+ * Apply plugins to tree
238+ * @param {Object } tree
239+ * @param {Array } plugins
240+ * @return {Object }
241+ */
183242function applyPluginsToTree ( tree , plugins ) {
184243 return plugins . reduce ( ( tree , plugin ) => {
185244 tree = plugin ( tree ) ;
0 commit comments