@@ -178,7 +178,7 @@ const computeAllowedCategories = ({
178178
179179const  defaultComponentContentModel : ContentModel  =  { 
180180  category : "instance" , 
181-   children : [ "rich-text" ,  "instance" ,   "transparent" ] , 
181+   children : [ "rich-text" ,  "instance" ] , 
182182} ; 
183183
184184const  getComponentContentModel  =  ( meta : undefined  |  WsComponentMeta )  => 
@@ -187,45 +187,29 @@ const getComponentContentModel = (meta: undefined | WsComponentMeta) =>
187187const  isComponentSatisfyingContentModel  =  ( { 
188188  metas, 
189189  component, 
190-   allowedCategories, 
190+   allowedParentCategories, 
191+   allowedAncestorCategories, 
191192} : { 
192193  metas : Metas ; 
193194  component : string ; 
194-   allowedCategories : undefined  |  string [ ] ; 
195+   allowedParentCategories : undefined  |  string [ ] ; 
196+   allowedAncestorCategories : undefined  |  string [ ] ; 
195197} )  =>  { 
196198  const  contentModel  =  getComponentContentModel ( metas . get ( component ) ) ; 
197199  return  ( 
198200    // body does not have parent 
199-     allowedCategories  ===  undefined  || 
201+     allowedParentCategories  ===  undefined  || 
200202    // parents may restrict specific components with none category 
201203    // any instances 
202204    // or nothing 
203-     allowedCategories . includes ( component )  || 
204-     allowedCategories . includes ( contentModel . category ) 
205+     allowedParentCategories . includes ( component )  || 
206+     allowedParentCategories . includes ( contentModel . category )  || 
207+     allowedAncestorCategories ?. includes ( component )  ===  true  || 
208+     allowedAncestorCategories ?. includes ( contentModel . category )  ===  true 
205209  ) ; 
206210} ; 
207211
208- const  getComponentChildrenCategories  =  ( { 
209-   metas, 
210-   component, 
211-   allowedCategories, 
212- } : { 
213-   metas : Metas ; 
214-   component : string ; 
215-   allowedCategories : undefined  |  string [ ] ; 
216- } )  =>  { 
217-   const  contentModel  =  getComponentContentModel ( metas . get ( component ) ) ; 
218-   let  childrenCategories  =  contentModel . children ; 
219-   // transparent categories makes component inherit constraints from parent 
220-   if  ( childrenCategories . includes ( "transparent" )  &&  allowedCategories )  { 
221-     childrenCategories  =  Array . from ( 
222-       new  Set ( [ ...childrenCategories ,  ...allowedCategories ] ) 
223-     ) ; 
224-   } 
225-   return  childrenCategories ; 
226- } ; 
227- 
228- const  computeAllowedComponentCategories  =  ( { 
212+ const  computeAllowedAncestorCategories  =  ( { 
229213  instances, 
230214  metas, 
231215  instanceSelector, 
@@ -234,24 +218,43 @@ const computeAllowedComponentCategories = ({
234218  metas : Metas ; 
235219  instanceSelector : InstanceSelector ; 
236220} )  =>  { 
237-   let  instance : undefined  |  Instance ; 
238221  let  allowedCategories : undefined  |  string [ ] ; 
239222  // skip selected instance for which these constraints are computed 
240223  for  ( const  instanceId  of  instanceSelector . slice ( 1 ) . reverse ( ) )  { 
241-     instance  =  instances . get ( instanceId ) ; 
224+     const   instance  =  instances . get ( instanceId ) ; 
242225    // collection item can be undefined 
243226    if  ( instance  ===  undefined )  { 
244227      continue ; 
245228    } 
246-     allowedCategories  =  getComponentChildrenCategories ( { 
247-       metas, 
248-       component : instance . component , 
249-       allowedCategories, 
250-     } ) ; 
229+     const  contentModel  =  getComponentContentModel ( 
230+       metas . get ( instance . component ) 
231+     ) ; 
232+     if  ( contentModel . descendants )  { 
233+       allowedCategories  ??=  [ ] ; 
234+       allowedCategories  =  [ ...allowedCategories ,  ...contentModel . descendants ] ; 
235+     } 
251236  } 
252237  return  allowedCategories ; 
253238} ; 
254239
240+ const  getAllowedParentCategories  =  ( { 
241+   instances, 
242+   metas, 
243+   instanceSelector, 
244+ } : { 
245+   instances : Instances ; 
246+   metas : Metas ; 
247+   instanceSelector : InstanceSelector ; 
248+ } )  =>  { 
249+   const  instanceId  =  instanceSelector [ 1 ] ; 
250+   const  instance  =  instances . get ( instanceId ) ; 
251+   if  ( instance  ===  undefined )  { 
252+     return ; 
253+   } 
254+   const  contentModel  =  getComponentContentModel ( metas . get ( instance . component ) ) ; 
255+   return  contentModel . children ; 
256+ } ; 
257+ 
255258/** 
256259 * Check all tags starting with specified instance select 
257260 * for example 
@@ -294,15 +297,17 @@ export const isTreeSatisfyingContentModel = ({
294297  instanceSelector, 
295298  onError, 
296299  _allowedCategories : allowedCategories , 
297-   _allowedComponentCategories : allowedComponentCategories , 
300+   _allowedAncestorCategories : allowedAncestorCategories , 
301+   _allowedParentCategories : allowedParentCategories , 
298302} : { 
299303  instances : Instances ; 
300304  props : Props ; 
301305  metas : Metas ; 
302306  instanceSelector : InstanceSelector ; 
303307  onError ?: ( message : string )  =>  void ; 
304308  _allowedCategories ?: string [ ] ; 
305-   _allowedComponentCategories ?: string [ ] ; 
309+   _allowedAncestorCategories ?: string [ ] ; 
310+   _allowedParentCategories ?: string [ ] ; 
306311} ) : boolean  =>  { 
307312  // compute constraints only when not passed from parent 
308313  allowedCategories  ??=  computeAllowedCategories ( { 
@@ -311,7 +316,12 @@ export const isTreeSatisfyingContentModel = ({
311316    props, 
312317    metas, 
313318  } ) ; 
314-   allowedComponentCategories  ??=  computeAllowedComponentCategories ( { 
319+   allowedParentCategories  ??=  getAllowedParentCategories ( { 
320+     instanceSelector, 
321+     instances, 
322+     metas, 
323+   } ) ; 
324+   allowedAncestorCategories  ??=  computeAllowedAncestorCategories ( { 
315325    instanceSelector, 
316326    instances, 
317327    metas, 
@@ -344,7 +354,8 @@ export const isTreeSatisfyingContentModel = ({
344354  const  isComponentSatisfying  =  isComponentSatisfyingContentModel ( { 
345355    metas, 
346356    component : instance . component , 
347-     allowedCategories : allowedComponentCategories , 
357+     allowedParentCategories, 
358+     allowedAncestorCategories, 
348359  } ) ; 
349360  if  ( isComponentSatisfying  ===  false )  { 
350361    const  [ _namespace ,  name ]  =  parseComponentName ( instance . component ) ; 
@@ -363,6 +374,16 @@ export const isTreeSatisfyingContentModel = ({
363374    } 
364375  } 
365376  let  isSatisfying  =  isTagSatisfying  &&  isComponentSatisfying ; 
377+   const  contentModel  =  getComponentContentModel ( metas . get ( instance . component ) ) ; 
378+   allowedCategories  =  getTagChildrenCategories ( tag ,  allowedCategories ) ; 
379+   allowedParentCategories  =  contentModel . children ; 
380+   if  ( contentModel . descendants )  { 
381+     allowedAncestorCategories  ??=  [ ] ; 
382+     allowedAncestorCategories  =  [ 
383+       ...allowedAncestorCategories , 
384+       ...contentModel . descendants , 
385+     ] ; 
386+   } 
366387  for  ( const  child  of  instance . children )  { 
367388    if  ( child . type  ===  "id" )  { 
368389      isSatisfying  &&=  isTreeSatisfyingContentModel ( { 
@@ -371,12 +392,9 @@ export const isTreeSatisfyingContentModel = ({
371392        metas, 
372393        instanceSelector : [ child . value ,  ...instanceSelector ] , 
373394        onError, 
374-         _allowedCategories : getTagChildrenCategories ( tag ,  allowedCategories ) , 
375-         _allowedComponentCategories : getComponentChildrenCategories ( { 
376-           metas, 
377-           component : instance . component , 
378-           allowedCategories : allowedComponentCategories , 
379-         } ) , 
395+         _allowedCategories : allowedCategories , 
396+         _allowedParentCategories : allowedParentCategories , 
397+         _allowedAncestorCategories : allowedAncestorCategories , 
380398      } ) ; 
381399    } 
382400  } 
0 commit comments