@dotcms/angular 1.5.4 → 1.5.5-next.2176

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -773,38 +773,44 @@ class DotTableBlock {
773
773
  this.blockEditorItem = DotCMSBlockEditorItemComponent;
774
774
  }
775
775
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: DotTableBlock, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
776
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.1", type: DotTableBlock, isStandalone: true, selector: "dotcms-block-editor-renderer-table", inputs: { content: "content" }, ngImport: i0, template: `
777
- <table>
778
- <thead>
779
- @for (rowNode of content?.slice(0, 1); track rowNode.type) {
780
- <tr>
781
- @for (cellNode of rowNode.content; track cellNode.type) {
782
- <th
783
- [attr.colspan]="cellNode.attrs?.['colspan'] || 1"
784
- [attr.rowspan]="cellNode.attrs?.['rowspan'] || 1">
785
- <ng-container
786
- *ngComponentOutlet="
787
- blockEditorItem;
788
- inputs: { content: cellNode.content }
789
- " />
790
- </th>
791
- }
792
- </tr>
793
- }
794
- </thead>
776
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.1", type: DotTableBlock, isStandalone: true, selector: "dotcms-block-editor-renderer-table", inputs: { content: "content", attrs: "attrs" }, ngImport: i0, template: `
777
+ <table
778
+ [attr.aria-label]="attrs?.['ariaLabel'] || null"
779
+ [attr.aria-labelledby]="attrs?.['ariaLabelledby'] || null">
780
+ @if (attrs?.['caption']) {
781
+ <caption>{{ attrs?.['caption'] }}</caption>
782
+ }
795
783
  <tbody>
796
- @for (rowNode of content?.slice(1); track rowNode.type) {
784
+ @for (rowNode of content; track $index) {
797
785
  <tr>
798
- @for (cellNode of rowNode.content; track cellNode.type) {
799
- <td
800
- [attr.colspan]="cellNode.attrs?.['colspan'] || 1"
801
- [attr.rowspan]="cellNode.attrs?.['rowspan'] || 1">
802
- <ng-container
803
- *ngComponentOutlet="
804
- blockEditorItem;
805
- inputs: { content: cellNode.content }
806
- " />
807
- </td>
786
+ @for (cellNode of rowNode.content; track $index) {
787
+ <!--
788
+ Cell type — not row index — decides th vs td. Matches the
789
+ VTL renderer (storyblock/render.vtl) so headless markup
790
+ stays consistent with server-rendered pages.
791
+ -->
792
+ @if (cellNode.type === 'tableHeader') {
793
+ <th
794
+ [attr.colspan]="cellNode.attrs?.['colspan'] || 1"
795
+ [attr.rowspan]="cellNode.attrs?.['rowspan'] || 1"
796
+ [attr.scope]="cellNode.attrs?.['scope'] || null">
797
+ <ng-container
798
+ *ngComponentOutlet="
799
+ blockEditorItem;
800
+ inputs: { content: cellNode.content }
801
+ " />
802
+ </th>
803
+ } @else {
804
+ <td
805
+ [attr.colspan]="cellNode.attrs?.['colspan'] || 1"
806
+ [attr.rowspan]="cellNode.attrs?.['rowspan'] || 1">
807
+ <ng-container
808
+ *ngComponentOutlet="
809
+ blockEditorItem;
810
+ inputs: { content: cellNode.content }
811
+ " />
812
+ </td>
813
+ }
808
814
  }
809
815
  </tr>
810
816
  }
@@ -818,37 +824,43 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImpor
818
824
  selector: 'dotcms-block-editor-renderer-table',
819
825
  imports: [NgComponentOutlet],
820
826
  template: `
821
- <table>
822
- <thead>
823
- @for (rowNode of content?.slice(0, 1); track rowNode.type) {
824
- <tr>
825
- @for (cellNode of rowNode.content; track cellNode.type) {
826
- <th
827
- [attr.colspan]="cellNode.attrs?.['colspan'] || 1"
828
- [attr.rowspan]="cellNode.attrs?.['rowspan'] || 1">
829
- <ng-container
830
- *ngComponentOutlet="
831
- blockEditorItem;
832
- inputs: { content: cellNode.content }
833
- " />
834
- </th>
835
- }
836
- </tr>
837
- }
838
- </thead>
827
+ <table
828
+ [attr.aria-label]="attrs?.['ariaLabel'] || null"
829
+ [attr.aria-labelledby]="attrs?.['ariaLabelledby'] || null">
830
+ @if (attrs?.['caption']) {
831
+ <caption>{{ attrs?.['caption'] }}</caption>
832
+ }
839
833
  <tbody>
840
- @for (rowNode of content?.slice(1); track rowNode.type) {
834
+ @for (rowNode of content; track $index) {
841
835
  <tr>
842
- @for (cellNode of rowNode.content; track cellNode.type) {
843
- <td
844
- [attr.colspan]="cellNode.attrs?.['colspan'] || 1"
845
- [attr.rowspan]="cellNode.attrs?.['rowspan'] || 1">
846
- <ng-container
847
- *ngComponentOutlet="
848
- blockEditorItem;
849
- inputs: { content: cellNode.content }
850
- " />
851
- </td>
836
+ @for (cellNode of rowNode.content; track $index) {
837
+ <!--
838
+ Cell type — not row index — decides th vs td. Matches the
839
+ VTL renderer (storyblock/render.vtl) so headless markup
840
+ stays consistent with server-rendered pages.
841
+ -->
842
+ @if (cellNode.type === 'tableHeader') {
843
+ <th
844
+ [attr.colspan]="cellNode.attrs?.['colspan'] || 1"
845
+ [attr.rowspan]="cellNode.attrs?.['rowspan'] || 1"
846
+ [attr.scope]="cellNode.attrs?.['scope'] || null">
847
+ <ng-container
848
+ *ngComponentOutlet="
849
+ blockEditorItem;
850
+ inputs: { content: cellNode.content }
851
+ " />
852
+ </th>
853
+ } @else {
854
+ <td
855
+ [attr.colspan]="cellNode.attrs?.['colspan'] || 1"
856
+ [attr.rowspan]="cellNode.attrs?.['rowspan'] || 1">
857
+ <ng-container
858
+ *ngComponentOutlet="
859
+ blockEditorItem;
860
+ inputs: { content: cellNode.content }
861
+ " />
862
+ </td>
863
+ }
852
864
  }
853
865
  </tr>
854
866
  }
@@ -858,6 +870,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImpor
858
870
  }]
859
871
  }], propDecorators: { content: [{
860
872
  type: Input
873
+ }], attrs: [{
874
+ type: Input
861
875
  }] } });
862
876
 
863
877
  class DotParagraphBlock {
@@ -1217,7 +1231,7 @@ class DotCMSBlockEditorItemComponent {
1217
1231
  this.BLOCKS = BlockEditorDefaultBlocks;
1218
1232
  }
1219
1233
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: DotCMSBlockEditorItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1220
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.1", type: DotCMSBlockEditorItemComponent, isStandalone: true, selector: "dotcms-block-editor-renderer-block", inputs: { content: "content", customRenderers: "customRenderers" }, ngImport: i0, template: "@for (node of content; track node) {\n @if (customRenderers?.[node.type]) {\n <ng-container\n *ngTemplateOutlet=\"\n customRender;\n context: { customRender: customRenderers?.[node.type], node: node }\n \" />\n } @else {\n @switch (node.type) {\n @case (BLOCKS.PARAGRAPH) {\n <dotcms-block-editor-renderer-paragraph [style]=\"node.attrs\">\n <dotcms-block-editor-renderer-block\n [content]=\"node.content\"\n [customRenderers]=\"customRenderers\" />\n </dotcms-block-editor-renderer-paragraph>\n }\n\n @case (BLOCKS.TEXT) {\n <dotcms-block-editor-renderer-text [marks]=\"node.marks\" [text]=\"node.text || ''\" />\n }\n\n @case (BLOCKS.HEADING) {\n <dotcms-block-editor-renderer-heading\n [style]=\"node.attrs || {}\"\n [level]=\"node.attrs?.['level'] || '1'\">\n <dotcms-block-editor-renderer-block\n [content]=\"node.content\"\n [customRenderers]=\"customRenderers\" />\n </dotcms-block-editor-renderer-heading>\n }\n\n @case (BLOCKS.BULLET_LIST) {\n <dotcms-block-editor-renderer-bullet-list>\n <dotcms-block-editor-renderer-block\n [content]=\"node.content\"\n [customRenderers]=\"customRenderers\" />\n </dotcms-block-editor-renderer-bullet-list>\n }\n\n @case (BLOCKS.ORDERED_LIST) {\n <dotcms-block-editor-renderer-ordered-list>\n <dotcms-block-editor-renderer-block\n [content]=\"node.content\"\n [customRenderers]=\"customRenderers\" />\n </dotcms-block-editor-renderer-ordered-list>\n }\n\n @case (BLOCKS.LIST_ITEM) {\n <dotcms-block-editor-renderer-list-item>\n <dotcms-block-editor-renderer-block\n [content]=\"node.content\"\n [customRenderers]=\"customRenderers\" />\n </dotcms-block-editor-renderer-list-item>\n }\n\n @case (BLOCKS.BLOCK_QUOTE) {\n <dotcms-block-editor-renderer-block-quote>\n <dotcms-block-editor-renderer-block\n [content]=\"node.content\"\n [customRenderers]=\"customRenderers\" />\n </dotcms-block-editor-renderer-block-quote>\n }\n\n @case (BLOCKS.CODE_BLOCK) {\n <dotcms-block-editor-renderer-code-block>\n <dotcms-block-editor-renderer-block\n [content]=\"node.content\"\n [customRenderers]=\"customRenderers\" />\n </dotcms-block-editor-renderer-code-block>\n }\n\n @case (BLOCKS.HARDBREAK) {\n <br />\n }\n\n @case (BLOCKS.HORIZONTAL_RULE) {\n <hr />\n }\n\n @case (BLOCKS.DOT_IMAGE) {\n <dotcms-block-editor-renderer-image [attrs]=\"node.attrs || {}\" />\n }\n\n @case (BLOCKS.DOT_VIDEO) {\n <dotcms-block-editor-renderer-video [attrs]=\"node.attrs || {}\" />\n }\n\n @case (BLOCKS.TABLE) {\n <dotcms-block-editor-renderer-table [content]=\"node.content\" />\n }\n\n @case (BLOCKS.GRID_BLOCK) {\n <dotcms-block-editor-renderer-grid-block\n [node]=\"node\"\n [customRenderers]=\"customRenderers\" />\n }\n\n @case (BLOCKS.DOT_CONTENT) {\n <dotcms-block-editor-renderer-contentlet\n [node]=\"node\"\n [customRenderers]=\"customRenderers\" />\n }\n\n @default {\n <dotcms-block-editor-renderer-unknown [node]=\"node\" />\n }\n }\n }\n}\n\n<ng-template #customRender let-customRender=\"customRender\" let-node=\"node\">\n <ng-container *ngComponentOutlet=\"customRender | async; inputs: { node: node }\" />\n</ng-template>\n", styles: [""], dependencies: [{ kind: "component", type: DotCMSBlockEditorItemComponent, selector: "dotcms-block-editor-renderer-block", inputs: ["content", "customRenderers"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule"], exportAs: ["ngComponentOutlet"] }, { kind: "component", type: DotParagraphBlock, selector: "dotcms-block-editor-renderer-paragraph" }, { kind: "component", type: DotTextBlock, selector: "dotcms-block-editor-renderer-text", inputs: ["marks", "text"] }, { kind: "component", type: DotHeadingBlock, selector: "dotcms-block-editor-renderer-heading", inputs: ["level"] }, { kind: "component", type: DotBulletList, selector: "dotcms-block-editor-renderer-bullet-list" }, { kind: "component", type: DotOrdererList, selector: "dotcms-block-editor-renderer-ordered-list" }, { kind: "component", type: DotListItem, selector: "dotcms-block-editor-renderer-list-item" }, { kind: "component", type: DotCodeBlock, selector: "dotcms-block-editor-renderer-code-block" }, { kind: "component", type: DotBlockQuote, selector: "dotcms-block-editor-renderer-block-quote" }, { kind: "component", type: DotImageBlock, selector: "dotcms-block-editor-renderer-image", inputs: ["attrs"] }, { kind: "component", type: DotVideoBlock, selector: "dotcms-block-editor-renderer-video", inputs: ["attrs"] }, { kind: "component", type: DotTableBlock, selector: "dotcms-block-editor-renderer-table", inputs: ["content"] }, { kind: "component", type: DotGridBlock, selector: "dotcms-block-editor-renderer-grid-block", inputs: ["node", "customRenderers"] }, { kind: "component", type: DotContentletBlock, selector: "dotcms-block-editor-renderer-contentlet", inputs: ["customRenderers", "node"] }, { kind: "component", type: DotUnknownBlockComponent, selector: "dotcms-block-editor-renderer-unknown", inputs: ["node"] }, { kind: "pipe", type: AsyncPipe, name: "async" }] }); }
1234
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.1", type: DotCMSBlockEditorItemComponent, isStandalone: true, selector: "dotcms-block-editor-renderer-block", inputs: { content: "content", customRenderers: "customRenderers" }, ngImport: i0, template: "@for (node of content; track node) {\n @if (customRenderers?.[node.type]) {\n <ng-container\n *ngTemplateOutlet=\"\n customRender;\n context: { customRender: customRenderers?.[node.type], node: node }\n \" />\n } @else {\n @switch (node.type) {\n @case (BLOCKS.PARAGRAPH) {\n <dotcms-block-editor-renderer-paragraph [style]=\"node.attrs\">\n <dotcms-block-editor-renderer-block\n [content]=\"node.content\"\n [customRenderers]=\"customRenderers\" />\n </dotcms-block-editor-renderer-paragraph>\n }\n\n @case (BLOCKS.TEXT) {\n <dotcms-block-editor-renderer-text [marks]=\"node.marks\" [text]=\"node.text || ''\" />\n }\n\n @case (BLOCKS.HEADING) {\n <dotcms-block-editor-renderer-heading\n [style]=\"node.attrs || {}\"\n [level]=\"node.attrs?.['level'] || '1'\">\n <dotcms-block-editor-renderer-block\n [content]=\"node.content\"\n [customRenderers]=\"customRenderers\" />\n </dotcms-block-editor-renderer-heading>\n }\n\n @case (BLOCKS.BULLET_LIST) {\n <dotcms-block-editor-renderer-bullet-list>\n <dotcms-block-editor-renderer-block\n [content]=\"node.content\"\n [customRenderers]=\"customRenderers\" />\n </dotcms-block-editor-renderer-bullet-list>\n }\n\n @case (BLOCKS.ORDERED_LIST) {\n <dotcms-block-editor-renderer-ordered-list>\n <dotcms-block-editor-renderer-block\n [content]=\"node.content\"\n [customRenderers]=\"customRenderers\" />\n </dotcms-block-editor-renderer-ordered-list>\n }\n\n @case (BLOCKS.LIST_ITEM) {\n <dotcms-block-editor-renderer-list-item>\n <dotcms-block-editor-renderer-block\n [content]=\"node.content\"\n [customRenderers]=\"customRenderers\" />\n </dotcms-block-editor-renderer-list-item>\n }\n\n @case (BLOCKS.BLOCK_QUOTE) {\n <dotcms-block-editor-renderer-block-quote>\n <dotcms-block-editor-renderer-block\n [content]=\"node.content\"\n [customRenderers]=\"customRenderers\" />\n </dotcms-block-editor-renderer-block-quote>\n }\n\n @case (BLOCKS.CODE_BLOCK) {\n <dotcms-block-editor-renderer-code-block>\n <dotcms-block-editor-renderer-block\n [content]=\"node.content\"\n [customRenderers]=\"customRenderers\" />\n </dotcms-block-editor-renderer-code-block>\n }\n\n @case (BLOCKS.HARDBREAK) {\n <br />\n }\n\n @case (BLOCKS.HORIZONTAL_RULE) {\n <hr />\n }\n\n @case (BLOCKS.DOT_IMAGE) {\n <dotcms-block-editor-renderer-image [attrs]=\"node.attrs || {}\" />\n }\n\n @case (BLOCKS.DOT_VIDEO) {\n <dotcms-block-editor-renderer-video [attrs]=\"node.attrs || {}\" />\n }\n\n @case (BLOCKS.TABLE) {\n <dotcms-block-editor-renderer-table [content]=\"node.content\" [attrs]=\"node.attrs\" />\n }\n\n @case (BLOCKS.GRID_BLOCK) {\n <dotcms-block-editor-renderer-grid-block\n [node]=\"node\"\n [customRenderers]=\"customRenderers\" />\n }\n\n @case (BLOCKS.DOT_CONTENT) {\n <dotcms-block-editor-renderer-contentlet\n [node]=\"node\"\n [customRenderers]=\"customRenderers\" />\n }\n\n @default {\n <dotcms-block-editor-renderer-unknown [node]=\"node\" />\n }\n }\n }\n}\n\n<ng-template #customRender let-customRender=\"customRender\" let-node=\"node\">\n <ng-container *ngComponentOutlet=\"customRender | async; inputs: { node: node }\" />\n</ng-template>\n", styles: [""], dependencies: [{ kind: "component", type: DotCMSBlockEditorItemComponent, selector: "dotcms-block-editor-renderer-block", inputs: ["content", "customRenderers"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule"], exportAs: ["ngComponentOutlet"] }, { kind: "component", type: DotParagraphBlock, selector: "dotcms-block-editor-renderer-paragraph" }, { kind: "component", type: DotTextBlock, selector: "dotcms-block-editor-renderer-text", inputs: ["marks", "text"] }, { kind: "component", type: DotHeadingBlock, selector: "dotcms-block-editor-renderer-heading", inputs: ["level"] }, { kind: "component", type: DotBulletList, selector: "dotcms-block-editor-renderer-bullet-list" }, { kind: "component", type: DotOrdererList, selector: "dotcms-block-editor-renderer-ordered-list" }, { kind: "component", type: DotListItem, selector: "dotcms-block-editor-renderer-list-item" }, { kind: "component", type: DotCodeBlock, selector: "dotcms-block-editor-renderer-code-block" }, { kind: "component", type: DotBlockQuote, selector: "dotcms-block-editor-renderer-block-quote" }, { kind: "component", type: DotImageBlock, selector: "dotcms-block-editor-renderer-image", inputs: ["attrs"] }, { kind: "component", type: DotVideoBlock, selector: "dotcms-block-editor-renderer-video", inputs: ["attrs"] }, { kind: "component", type: DotTableBlock, selector: "dotcms-block-editor-renderer-table", inputs: ["content", "attrs"] }, { kind: "component", type: DotGridBlock, selector: "dotcms-block-editor-renderer-grid-block", inputs: ["node", "customRenderers"] }, { kind: "component", type: DotContentletBlock, selector: "dotcms-block-editor-renderer-contentlet", inputs: ["customRenderers", "node"] }, { kind: "component", type: DotUnknownBlockComponent, selector: "dotcms-block-editor-renderer-unknown", inputs: ["node"] }, { kind: "pipe", type: AsyncPipe, name: "async" }] }); }
1221
1235
  }
1222
1236
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: DotCMSBlockEditorItemComponent, decorators: [{
1223
1237
  type: Component,
@@ -1239,7 +1253,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImpor
1239
1253
  DotGridBlock,
1240
1254
  DotContentletBlock,
1241
1255
  DotUnknownBlockComponent
1242
- ], template: "@for (node of content; track node) {\n @if (customRenderers?.[node.type]) {\n <ng-container\n *ngTemplateOutlet=\"\n customRender;\n context: { customRender: customRenderers?.[node.type], node: node }\n \" />\n } @else {\n @switch (node.type) {\n @case (BLOCKS.PARAGRAPH) {\n <dotcms-block-editor-renderer-paragraph [style]=\"node.attrs\">\n <dotcms-block-editor-renderer-block\n [content]=\"node.content\"\n [customRenderers]=\"customRenderers\" />\n </dotcms-block-editor-renderer-paragraph>\n }\n\n @case (BLOCKS.TEXT) {\n <dotcms-block-editor-renderer-text [marks]=\"node.marks\" [text]=\"node.text || ''\" />\n }\n\n @case (BLOCKS.HEADING) {\n <dotcms-block-editor-renderer-heading\n [style]=\"node.attrs || {}\"\n [level]=\"node.attrs?.['level'] || '1'\">\n <dotcms-block-editor-renderer-block\n [content]=\"node.content\"\n [customRenderers]=\"customRenderers\" />\n </dotcms-block-editor-renderer-heading>\n }\n\n @case (BLOCKS.BULLET_LIST) {\n <dotcms-block-editor-renderer-bullet-list>\n <dotcms-block-editor-renderer-block\n [content]=\"node.content\"\n [customRenderers]=\"customRenderers\" />\n </dotcms-block-editor-renderer-bullet-list>\n }\n\n @case (BLOCKS.ORDERED_LIST) {\n <dotcms-block-editor-renderer-ordered-list>\n <dotcms-block-editor-renderer-block\n [content]=\"node.content\"\n [customRenderers]=\"customRenderers\" />\n </dotcms-block-editor-renderer-ordered-list>\n }\n\n @case (BLOCKS.LIST_ITEM) {\n <dotcms-block-editor-renderer-list-item>\n <dotcms-block-editor-renderer-block\n [content]=\"node.content\"\n [customRenderers]=\"customRenderers\" />\n </dotcms-block-editor-renderer-list-item>\n }\n\n @case (BLOCKS.BLOCK_QUOTE) {\n <dotcms-block-editor-renderer-block-quote>\n <dotcms-block-editor-renderer-block\n [content]=\"node.content\"\n [customRenderers]=\"customRenderers\" />\n </dotcms-block-editor-renderer-block-quote>\n }\n\n @case (BLOCKS.CODE_BLOCK) {\n <dotcms-block-editor-renderer-code-block>\n <dotcms-block-editor-renderer-block\n [content]=\"node.content\"\n [customRenderers]=\"customRenderers\" />\n </dotcms-block-editor-renderer-code-block>\n }\n\n @case (BLOCKS.HARDBREAK) {\n <br />\n }\n\n @case (BLOCKS.HORIZONTAL_RULE) {\n <hr />\n }\n\n @case (BLOCKS.DOT_IMAGE) {\n <dotcms-block-editor-renderer-image [attrs]=\"node.attrs || {}\" />\n }\n\n @case (BLOCKS.DOT_VIDEO) {\n <dotcms-block-editor-renderer-video [attrs]=\"node.attrs || {}\" />\n }\n\n @case (BLOCKS.TABLE) {\n <dotcms-block-editor-renderer-table [content]=\"node.content\" />\n }\n\n @case (BLOCKS.GRID_BLOCK) {\n <dotcms-block-editor-renderer-grid-block\n [node]=\"node\"\n [customRenderers]=\"customRenderers\" />\n }\n\n @case (BLOCKS.DOT_CONTENT) {\n <dotcms-block-editor-renderer-contentlet\n [node]=\"node\"\n [customRenderers]=\"customRenderers\" />\n }\n\n @default {\n <dotcms-block-editor-renderer-unknown [node]=\"node\" />\n }\n }\n }\n}\n\n<ng-template #customRender let-customRender=\"customRender\" let-node=\"node\">\n <ng-container *ngComponentOutlet=\"customRender | async; inputs: { node: node }\" />\n</ng-template>\n" }]
1256
+ ], template: "@for (node of content; track node) {\n @if (customRenderers?.[node.type]) {\n <ng-container\n *ngTemplateOutlet=\"\n customRender;\n context: { customRender: customRenderers?.[node.type], node: node }\n \" />\n } @else {\n @switch (node.type) {\n @case (BLOCKS.PARAGRAPH) {\n <dotcms-block-editor-renderer-paragraph [style]=\"node.attrs\">\n <dotcms-block-editor-renderer-block\n [content]=\"node.content\"\n [customRenderers]=\"customRenderers\" />\n </dotcms-block-editor-renderer-paragraph>\n }\n\n @case (BLOCKS.TEXT) {\n <dotcms-block-editor-renderer-text [marks]=\"node.marks\" [text]=\"node.text || ''\" />\n }\n\n @case (BLOCKS.HEADING) {\n <dotcms-block-editor-renderer-heading\n [style]=\"node.attrs || {}\"\n [level]=\"node.attrs?.['level'] || '1'\">\n <dotcms-block-editor-renderer-block\n [content]=\"node.content\"\n [customRenderers]=\"customRenderers\" />\n </dotcms-block-editor-renderer-heading>\n }\n\n @case (BLOCKS.BULLET_LIST) {\n <dotcms-block-editor-renderer-bullet-list>\n <dotcms-block-editor-renderer-block\n [content]=\"node.content\"\n [customRenderers]=\"customRenderers\" />\n </dotcms-block-editor-renderer-bullet-list>\n }\n\n @case (BLOCKS.ORDERED_LIST) {\n <dotcms-block-editor-renderer-ordered-list>\n <dotcms-block-editor-renderer-block\n [content]=\"node.content\"\n [customRenderers]=\"customRenderers\" />\n </dotcms-block-editor-renderer-ordered-list>\n }\n\n @case (BLOCKS.LIST_ITEM) {\n <dotcms-block-editor-renderer-list-item>\n <dotcms-block-editor-renderer-block\n [content]=\"node.content\"\n [customRenderers]=\"customRenderers\" />\n </dotcms-block-editor-renderer-list-item>\n }\n\n @case (BLOCKS.BLOCK_QUOTE) {\n <dotcms-block-editor-renderer-block-quote>\n <dotcms-block-editor-renderer-block\n [content]=\"node.content\"\n [customRenderers]=\"customRenderers\" />\n </dotcms-block-editor-renderer-block-quote>\n }\n\n @case (BLOCKS.CODE_BLOCK) {\n <dotcms-block-editor-renderer-code-block>\n <dotcms-block-editor-renderer-block\n [content]=\"node.content\"\n [customRenderers]=\"customRenderers\" />\n </dotcms-block-editor-renderer-code-block>\n }\n\n @case (BLOCKS.HARDBREAK) {\n <br />\n }\n\n @case (BLOCKS.HORIZONTAL_RULE) {\n <hr />\n }\n\n @case (BLOCKS.DOT_IMAGE) {\n <dotcms-block-editor-renderer-image [attrs]=\"node.attrs || {}\" />\n }\n\n @case (BLOCKS.DOT_VIDEO) {\n <dotcms-block-editor-renderer-video [attrs]=\"node.attrs || {}\" />\n }\n\n @case (BLOCKS.TABLE) {\n <dotcms-block-editor-renderer-table [content]=\"node.content\" [attrs]=\"node.attrs\" />\n }\n\n @case (BLOCKS.GRID_BLOCK) {\n <dotcms-block-editor-renderer-grid-block\n [node]=\"node\"\n [customRenderers]=\"customRenderers\" />\n }\n\n @case (BLOCKS.DOT_CONTENT) {\n <dotcms-block-editor-renderer-contentlet\n [node]=\"node\"\n [customRenderers]=\"customRenderers\" />\n }\n\n @default {\n <dotcms-block-editor-renderer-unknown [node]=\"node\" />\n }\n }\n }\n}\n\n<ng-template #customRender let-customRender=\"customRender\" let-node=\"node\">\n <ng-container *ngComponentOutlet=\"customRender | async; inputs: { node: node }\" />\n</ng-template>\n" }]
1243
1257
  }], propDecorators: { content: [{
1244
1258
  type: Input
1245
1259
  }], customRenderers: [{
@@ -1261,6 +1275,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImpor
1261
1275
  * [customRenderers]="myCustomRenderers">
1262
1276
  * </dotcms-block-editor-renderer>
1263
1277
  * ```
1278
+ *
1279
+ * @deprecated Use {@link DotCMSBlockEditorRendererNativeComponent}
1280
+ * (`<dotcms-block-editor-renderer-native>`) for accessible, semantic DOM output.
1281
+ * This component wraps every semantic tag in a custom element (e.g. a dispatcher
1282
+ * element sits between `<ul>` and its `<li>` children), which breaks the
1283
+ * `list → listitem` relationship required by the HTML spec and assistive technology.
1284
+ * The native renderer keeps the identical public input API — migration is just
1285
+ * swapping the tag and import. This component is retained for backward compatibility
1286
+ * and will be removed in a future major version.
1264
1287
  */
1265
1288
  class DotCMSBlockEditorRendererComponent {
1266
1289
  constructor() {
@@ -1290,6 +1313,240 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImpor
1290
1313
  type: Input
1291
1314
  }] } });
1292
1315
 
1316
+ /**
1317
+ * Internal semantic block components for the accessible Block Editor renderer.
1318
+ *
1319
+ * Each component uses an **attribute selector** so the host element *is* the real
1320
+ * semantic tag (`<ul>`, `<ol>`, `<li>`, ...). The template is just `<ng-content />`,
1321
+ * so no extra wrapper element is added to the DOM and the
1322
+ * `list → listitem` relationship required by the HTML spec and assistive
1323
+ * technology is preserved.
1324
+ *
1325
+ * These are not exported from the SDK; they are an implementation detail of
1326
+ * {@link DotCMSBlockEditorRendererNativeComponent}.
1327
+ *
1328
+ * @internal
1329
+ */
1330
+ class DotSemanticBulletList {
1331
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: DotSemanticBulletList, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1332
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.1", type: DotSemanticBulletList, isStandalone: true, selector: "ul[dotBulletList]", ngImport: i0, template: `
1333
+ <ng-content />
1334
+ `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1335
+ }
1336
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: DotSemanticBulletList, decorators: [{
1337
+ type: Component,
1338
+ args: [{
1339
+ selector: 'ul[dotBulletList]',
1340
+ changeDetection: ChangeDetectionStrategy.OnPush,
1341
+ template: `
1342
+ <ng-content />
1343
+ `
1344
+ }]
1345
+ }] });
1346
+ class DotSemanticOrderedList {
1347
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: DotSemanticOrderedList, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1348
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.1", type: DotSemanticOrderedList, isStandalone: true, selector: "ol[dotOrderedList]", ngImport: i0, template: `
1349
+ <ng-content />
1350
+ `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1351
+ }
1352
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: DotSemanticOrderedList, decorators: [{
1353
+ type: Component,
1354
+ args: [{
1355
+ selector: 'ol[dotOrderedList]',
1356
+ changeDetection: ChangeDetectionStrategy.OnPush,
1357
+ template: `
1358
+ <ng-content />
1359
+ `
1360
+ }]
1361
+ }] });
1362
+ class DotSemanticListItem {
1363
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: DotSemanticListItem, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1364
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.1", type: DotSemanticListItem, isStandalone: true, selector: "li[dotListItem]", ngImport: i0, template: `
1365
+ <ng-content />
1366
+ `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1367
+ }
1368
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: DotSemanticListItem, decorators: [{
1369
+ type: Component,
1370
+ args: [{
1371
+ selector: 'li[dotListItem]',
1372
+ changeDetection: ChangeDetectionStrategy.OnPush,
1373
+ template: `
1374
+ <ng-content />
1375
+ `
1376
+ }]
1377
+ }] });
1378
+ class DotSemanticParagraph {
1379
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: DotSemanticParagraph, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1380
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.1", type: DotSemanticParagraph, isStandalone: true, selector: "p[dotParagraph]", ngImport: i0, template: `
1381
+ <ng-content />
1382
+ `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1383
+ }
1384
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: DotSemanticParagraph, decorators: [{
1385
+ type: Component,
1386
+ args: [{
1387
+ selector: 'p[dotParagraph]',
1388
+ changeDetection: ChangeDetectionStrategy.OnPush,
1389
+ template: `
1390
+ <ng-content />
1391
+ `
1392
+ }]
1393
+ }] });
1394
+ class DotSemanticBlockQuote {
1395
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: DotSemanticBlockQuote, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1396
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.1", type: DotSemanticBlockQuote, isStandalone: true, selector: "blockquote[dotBlockQuote]", ngImport: i0, template: `
1397
+ <ng-content />
1398
+ `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1399
+ }
1400
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: DotSemanticBlockQuote, decorators: [{
1401
+ type: Component,
1402
+ args: [{
1403
+ selector: 'blockquote[dotBlockQuote]',
1404
+ changeDetection: ChangeDetectionStrategy.OnPush,
1405
+ template: `
1406
+ <ng-content />
1407
+ `
1408
+ }]
1409
+ }] });
1410
+ class DotSemanticCodeBlock {
1411
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: DotSemanticCodeBlock, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1412
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.1", type: DotSemanticCodeBlock, isStandalone: true, selector: "pre[dotCodeBlock]", ngImport: i0, template: `
1413
+ <code><ng-content /></code>
1414
+ `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1415
+ }
1416
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: DotSemanticCodeBlock, decorators: [{
1417
+ type: Component,
1418
+ args: [{
1419
+ selector: 'pre[dotCodeBlock]',
1420
+ changeDetection: ChangeDetectionStrategy.OnPush,
1421
+ template: `
1422
+ <code><ng-content /></code>
1423
+ `
1424
+ }]
1425
+ }] });
1426
+
1427
+ /**
1428
+ * An accessible component that renders content from DotCMS's Block Editor field.
1429
+ *
1430
+ * This is the semantic-DOM successor to {@link DotCMSBlockEditorRendererComponent}.
1431
+ * It emits clean semantic HTML — `<ul><li><p>…</p></li></ul>` — with no custom
1432
+ * wrapper elements between semantic tags, so the `list → listitem` relationship
1433
+ * required by the HTML spec and assistive technology is preserved. The recursive
1434
+ * dispatch is performed with `ng-template` outlets, whose host `<ng-container>`s
1435
+ * render as HTML comment nodes (invisible to the accessibility tree).
1436
+ *
1437
+ * It exposes the **identical public input API** and the same `customRenderers`
1438
+ * contract as the deprecated renderer, so migration is just swapping the tag and
1439
+ * import.
1440
+ *
1441
+ * For more information about Block Editor, see {@link https://dev.dotcms.com/docs/block-editor}
1442
+ *
1443
+ * @example
1444
+ * ```html
1445
+ * <dotcms-block-editor-renderer-native
1446
+ * [blocks]="myBlockEditorContent"
1447
+ * [customRenderers]="myCustomRenderers">
1448
+ * </dotcms-block-editor-renderer-native>
1449
+ * ```
1450
+ */
1451
+ class DotCMSBlockEditorRendererNativeComponent {
1452
+ constructor() {
1453
+ /** The Block Editor `doc` node to render. */
1454
+ this.blocks = input(...(ngDevMode ? [undefined, { debugName: "blocks" }] : []));
1455
+ /** Map of `node.type` → component to override the built-in render path. */
1456
+ this.customRenderers = input(undefined, ...(ngDevMode ? [{ debugName: "customRenderers" }] : []));
1457
+ /**
1458
+ * CSS class on the wrapper element. Aliased as `class` so consumers can
1459
+ * pass `[class]="…"` like a normal Angular class binding.
1460
+ */
1461
+ this.cssClass = input(undefined, { ...(ngDevMode ? { debugName: "cssClass" } : {}), alias: 'class' });
1462
+ /** Inline style on the wrapper element. */
1463
+ this.style = input(undefined, ...(ngDevMode ? [{ debugName: "style" }] : []));
1464
+ this.$blockEditorState = signal({ error: null }, ...(ngDevMode ? [{ debugName: "$blockEditorState" }] : []));
1465
+ this.$isInEditMode = signal(getUVEState()?.mode === UVE_MODE.EDIT, ...(ngDevMode ? [{ debugName: "$isInEditMode" }] : []));
1466
+ this.BLOCKS = BlockEditorDefaultBlocks;
1467
+ }
1468
+ ngOnInit() {
1469
+ // `isValidBlocks` declares `blocks: BlockEditorNode` but its first guard
1470
+ // handles `undefined` — the cast lines up the types without changing the
1471
+ // published `@dotcms/uve` signature.
1472
+ const state = isValidBlocks(this.blocks());
1473
+ if (state.error) {
1474
+ console.error('Error in dotcms-block-editor-renderer-native: ', state.error);
1475
+ }
1476
+ this.$blockEditorState.set(state);
1477
+ }
1478
+ /**
1479
+ * Normalizes a heading `level` attribute (which may be a number such as `6`
1480
+ * or a string such as `'6'`) to a string for use in the heading `@switch`.
1481
+ * Returns `''` for missing or out-of-range levels so the template falls
1482
+ * through to the safe `@default` case (`<h2>`).
1483
+ */
1484
+ asLevel(level) {
1485
+ const normalized = level != null ? String(level) : '';
1486
+ return /^[1-6]$/.test(normalized) ? normalized : '';
1487
+ }
1488
+ /** The marks after the current (outermost) one — used to recurse inward. */
1489
+ restMarks(marks) {
1490
+ return marks?.slice(1) ?? [];
1491
+ }
1492
+ /** The attributes of the current (outermost) mark. */
1493
+ markAttrs(marks) {
1494
+ return marks?.[0]?.attrs ?? {};
1495
+ }
1496
+ /**
1497
+ * Wrapper style for a `dotImage` `<figure>`, derived from the node's
1498
+ * `textWrap` (float left/right) or `textAlign` attribute.
1499
+ */
1500
+ imageStyle(attrs) {
1501
+ const textWrap = attrs?.['textWrap'];
1502
+ const textAlign = attrs?.['textAlign'];
1503
+ if (textWrap === 'left') {
1504
+ return { float: 'left', width: '50%', margin: '0 1rem 1rem 0' };
1505
+ }
1506
+ if (textWrap === 'right') {
1507
+ return { float: 'right', width: '50%', margin: '0 0 1rem 1rem' };
1508
+ }
1509
+ if (textAlign) {
1510
+ return { 'text-align': textAlign };
1511
+ }
1512
+ return {};
1513
+ }
1514
+ /** Poster URL for a `dotVideo` `<video>` (from `attrs.data.thumbnail`). */
1515
+ videoPoster(attrs) {
1516
+ return attrs?.['data']?.['thumbnail'];
1517
+ }
1518
+ /**
1519
+ * The column span (1–12) for a grid column. Falls back to `6` for malformed
1520
+ * `columns` attrs or for an out-of-range column index, matching the legacy
1521
+ * renderer.
1522
+ */
1523
+ columnSpan(attrs, index) {
1524
+ const rawCols = Array.isArray(attrs?.['columns']) ? attrs['columns'] : [6, 6];
1525
+ const valid = rawCols.length === 2 &&
1526
+ rawCols.every((v) => typeof v === 'number' && Number.isFinite(v));
1527
+ const span = valid ? rawCols[index] : 6;
1528
+ return typeof span === 'number' ? span : 6;
1529
+ }
1530
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: DotCMSBlockEditorRendererNativeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1531
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.1", type: DotCMSBlockEditorRendererNativeComponent, isStandalone: true, selector: "dotcms-block-editor-renderer-native", inputs: { blocks: { classPropertyName: "blocks", publicName: "blocks", isSignal: true, isRequired: false, transformFunction: null }, customRenderers: { classPropertyName: "customRenderers", publicName: "customRenderers", isSignal: true, isRequired: false, transformFunction: null }, cssClass: { classPropertyName: "cssClass", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, style: { classPropertyName: "style", publicName: "style", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if ($blockEditorState().error && $isInEditMode()) {\n <div data-testid=\"invalid-blocks-message\">\n {{ $blockEditorState().error }}\n </div>\n} @else if (!$blockEditorState().error) {\n <div [class]=\"cssClass()\" [style]=\"style()\">\n <ng-container *ngTemplateOutlet=\"nodeList; context: { $implicit: blocks()?.content }\" />\n </div>\n}\n\n<!-- Renders a list of nodes by dispatching each one. -->\n<ng-template #nodeList let-content>\n @for (node of content; track node) {\n <ng-container *ngTemplateOutlet=\"dispatch; context: { $implicit: node }\" />\n }\n</ng-template>\n\n<!--\n Dispatches a single node to its semantic tag. The host ng-container of each\n ngTemplateOutlet renders as an HTML comment node, so a list item stays a true\n DOM child of its list element \u2014 the property that makes this AT-proof.\n-->\n<ng-template #dispatch let-node>\n @if (customRenderers()?.[node.type]) {\n <ng-container\n *ngTemplateOutlet=\"\n customRender;\n context: { customRender: customRenderers()?.[node.type], node: node }\n \" />\n } @else {\n @switch (node.type) {\n @case (BLOCKS.PARAGRAPH) {\n <p dotParagraph [style.text-align]=\"node.attrs?.['textAlign'] || null\">\n <ng-container\n *ngTemplateOutlet=\"nodeList; context: { $implicit: node.content }\" />\n </p>\n }\n\n @case (BLOCKS.TEXT) {\n <ng-container\n *ngTemplateOutlet=\"\n textRun;\n context: { marks: node.marks, text: node.text || '' }\n \" />\n }\n\n @case (BLOCKS.HEADING) {\n @switch (asLevel(node.attrs?.['level'])) {\n @case ('1') {\n <h1 [style.text-align]=\"node.attrs?.['textAlign'] || null\">\n <ng-container\n *ngTemplateOutlet=\"\n nodeList;\n context: { $implicit: node.content }\n \" />\n </h1>\n }\n @case ('2') {\n <h2 [style.text-align]=\"node.attrs?.['textAlign'] || null\">\n <ng-container\n *ngTemplateOutlet=\"\n nodeList;\n context: { $implicit: node.content }\n \" />\n </h2>\n }\n @case ('3') {\n <h3 [style.text-align]=\"node.attrs?.['textAlign'] || null\">\n <ng-container\n *ngTemplateOutlet=\"\n nodeList;\n context: { $implicit: node.content }\n \" />\n </h3>\n }\n @case ('4') {\n <h4 [style.text-align]=\"node.attrs?.['textAlign'] || null\">\n <ng-container\n *ngTemplateOutlet=\"\n nodeList;\n context: { $implicit: node.content }\n \" />\n </h4>\n }\n @case ('5') {\n <h5 [style.text-align]=\"node.attrs?.['textAlign'] || null\">\n <ng-container\n *ngTemplateOutlet=\"\n nodeList;\n context: { $implicit: node.content }\n \" />\n </h5>\n }\n @case ('6') {\n <h6 [style.text-align]=\"node.attrs?.['textAlign'] || null\">\n <ng-container\n *ngTemplateOutlet=\"\n nodeList;\n context: { $implicit: node.content }\n \" />\n </h6>\n }\n @default {\n <!--\n Unknown level: fall back to <h2>, not <h1>. An\n unexpected <h1> in an article tanks the heading\n outline that assistive technology relies on, and\n articles typically already have a page <h1>.\n -->\n <h2 [style.text-align]=\"node.attrs?.['textAlign'] || null\">\n <ng-container\n *ngTemplateOutlet=\"\n nodeList;\n context: { $implicit: node.content }\n \" />\n </h2>\n }\n }\n }\n\n @case (BLOCKS.BULLET_LIST) {\n <ul dotBulletList>\n <ng-container\n *ngTemplateOutlet=\"nodeList; context: { $implicit: node.content }\" />\n </ul>\n }\n\n @case (BLOCKS.ORDERED_LIST) {\n <ol dotOrderedList>\n <ng-container\n *ngTemplateOutlet=\"nodeList; context: { $implicit: node.content }\" />\n </ol>\n }\n\n @case (BLOCKS.LIST_ITEM) {\n <li dotListItem>\n <ng-container\n *ngTemplateOutlet=\"nodeList; context: { $implicit: node.content }\" />\n </li>\n }\n\n @case (BLOCKS.BLOCK_QUOTE) {\n <blockquote dotBlockQuote>\n <ng-container\n *ngTemplateOutlet=\"nodeList; context: { $implicit: node.content }\" />\n </blockquote>\n }\n\n @case (BLOCKS.CODE_BLOCK) {\n <pre dotCodeBlock>\n <ng-container\n *ngTemplateOutlet=\"nodeList; context: { $implicit: node.content }\" /></pre>\n }\n\n @case (BLOCKS.HARDBREAK) {\n <br />\n }\n\n @case (BLOCKS.HORIZONTAL_RULE) {\n <hr />\n }\n\n @case (BLOCKS.DOT_IMAGE) {\n <figure [style]=\"imageStyle(node.attrs)\">\n <img\n [alt]=\"node.attrs?.['alt']\"\n [src]=\"node.attrs?.['src']\"\n style=\"max-width: 100%; height: auto\" />\n </figure>\n }\n\n @case (BLOCKS.DOT_VIDEO) {\n <video\n [controls]=\"true\"\n preload=\"metadata\"\n [poster]=\"videoPoster(node.attrs)\"\n [width]=\"node.attrs?.['width']\"\n [height]=\"node.attrs?.['height']\">\n <track default kind=\"captions\" srclang=\"en\" />\n <source [src]=\"node.attrs?.['src']\" [type]=\"node.attrs?.['mimeType']\" />\n Your browser does not support the\n <code>video</code>\n element.\n </video>\n }\n\n @case (BLOCKS.TABLE) {\n <table>\n <thead>\n @for (rowNode of node.content?.slice(0, 1); track $index) {\n <tr>\n @for (cellNode of rowNode.content; track $index) {\n <th\n [attr.colspan]=\"cellNode.attrs?.['colspan'] || 1\"\n [attr.rowspan]=\"cellNode.attrs?.['rowspan'] || 1\">\n <ng-container\n *ngTemplateOutlet=\"\n nodeList;\n context: { $implicit: cellNode.content }\n \" />\n </th>\n }\n </tr>\n }\n </thead>\n <tbody>\n @for (rowNode of node.content?.slice(1); track $index) {\n <tr>\n @for (cellNode of rowNode.content; track $index) {\n <td\n [attr.colspan]=\"cellNode.attrs?.['colspan'] || 1\"\n [attr.rowspan]=\"cellNode.attrs?.['rowspan'] || 1\">\n <ng-container\n *ngTemplateOutlet=\"\n nodeList;\n context: { $implicit: cellNode.content }\n \" />\n </td>\n }\n </tr>\n }\n </tbody>\n </table>\n }\n\n @case (BLOCKS.GRID_BLOCK) {\n <div\n data-type=\"gridBlock\"\n class=\"grid-block\"\n style=\"display: grid; grid-template-columns: repeat(12, 1fr); gap: 1rem\">\n @for (column of node.content; track $index) {\n <div\n data-type=\"gridColumn\"\n class=\"grid-block__column\"\n [style.grid-column]=\"'span ' + columnSpan(node.attrs, $index)\">\n <ng-container\n *ngTemplateOutlet=\"\n nodeList;\n context: { $implicit: column.content }\n \" />\n </div>\n }\n </div>\n }\n\n @case (BLOCKS.DOT_CONTENT) {\n <dotcms-block-editor-renderer-contentlet\n [node]=\"node\"\n [customRenderers]=\"customRenderers()\" />\n }\n\n @default {\n <dotcms-block-editor-renderer-unknown [node]=\"node\" />\n }\n }\n }\n</ng-template>\n\n<ng-template #customRender let-customRender=\"customRender\" let-node=\"node\">\n <ng-container *ngComponentOutlet=\"customRender | async; inputs: { node: node }\" />\n</ng-template>\n\n<!--\n Renders a text node and its marks as native inline elements (<strong>, <u>,\n <em>, <a>, ...) with no wrapper element. Recurses through itself (rendered as a\n comment node) one mark at a time, so stacked marks nest directly:\n <u><strong>text</strong></u>.\n-->\n<ng-template #textRun let-marks=\"marks\" let-text=\"text\">\n @switch (marks?.[0]?.type) {\n @case ('link') {\n @if (markAttrs(marks)['href']) {\n <a\n [attr.href]=\"markAttrs(marks)['href']\"\n [attr.target]=\"markAttrs(marks)['target'] || null\"\n [attr.title]=\"markAttrs(marks)['title'] || null\"\n [attr.aria-label]=\"markAttrs(marks)['aria-label'] || null\"\n [attr.rel]=\"\n markAttrs(marks)['rel'] ||\n (markAttrs(marks)['target'] === '_blank' ? 'noopener noreferrer' : null)\n \"\n [class]=\"markAttrs(marks)['class'] || null\">\n <ng-container\n *ngTemplateOutlet=\"\n textRun;\n context: { marks: restMarks(marks), text: text }\n \" />\n </a>\n } @else {\n <!--\n Malformed link mark with no href: a hrefless <a> isn't a\n link to assistive tech (no role, not focusable). Skip the\n element and recurse \u2014 any remaining marks (bold, etc.)\n still render around the text.\n -->\n <ng-container\n *ngTemplateOutlet=\"textRun; context: { marks: restMarks(marks), text: text }\" />\n }\n }\n @case ('bold') {\n <strong>\n <ng-container\n *ngTemplateOutlet=\"textRun; context: { marks: restMarks(marks), text: text }\" />\n </strong>\n }\n @case ('underline') {\n <u>\n <ng-container\n *ngTemplateOutlet=\"textRun; context: { marks: restMarks(marks), text: text }\" />\n </u>\n }\n @case ('italic') {\n <em>\n <ng-container\n *ngTemplateOutlet=\"textRun; context: { marks: restMarks(marks), text: text }\" />\n </em>\n }\n @case ('strike') {\n <s>\n <ng-container\n *ngTemplateOutlet=\"textRun; context: { marks: restMarks(marks), text: text }\" />\n </s>\n }\n @case ('superscript') {\n <sup>\n <ng-container\n *ngTemplateOutlet=\"textRun; context: { marks: restMarks(marks), text: text }\" />\n </sup>\n }\n @case ('subscript') {\n <sub>\n <ng-container\n *ngTemplateOutlet=\"textRun; context: { marks: restMarks(marks), text: text }\" />\n </sub>\n }\n @default {\n @if (marks?.length) {\n <!-- Unknown mark type: skip it but keep rendering any marks beneath. -->\n <ng-container\n *ngTemplateOutlet=\"textRun; context: { marks: restMarks(marks), text: text }\" />\n } @else {\n {{ text }}\n }\n }\n }\n</ng-template>\n", dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule"], exportAs: ["ngComponentOutlet"] }, { kind: "component", type: DotSemanticParagraph, selector: "p[dotParagraph]" }, { kind: "component", type: DotSemanticBulletList, selector: "ul[dotBulletList]" }, { kind: "component", type: DotSemanticOrderedList, selector: "ol[dotOrderedList]" }, { kind: "component", type: DotSemanticListItem, selector: "li[dotListItem]" }, { kind: "component", type: DotSemanticBlockQuote, selector: "blockquote[dotBlockQuote]" }, { kind: "component", type: DotSemanticCodeBlock, selector: "pre[dotCodeBlock]" }, { kind: "component", type: DotContentletBlock, selector: "dotcms-block-editor-renderer-contentlet", inputs: ["customRenderers", "node"] }, { kind: "component", type: DotUnknownBlockComponent, selector: "dotcms-block-editor-renderer-unknown", inputs: ["node"] }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1532
+ }
1533
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: DotCMSBlockEditorRendererNativeComponent, decorators: [{
1534
+ type: Component,
1535
+ args: [{ selector: 'dotcms-block-editor-renderer-native', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
1536
+ NgTemplateOutlet,
1537
+ NgComponentOutlet,
1538
+ AsyncPipe,
1539
+ DotSemanticParagraph,
1540
+ DotSemanticBulletList,
1541
+ DotSemanticOrderedList,
1542
+ DotSemanticListItem,
1543
+ DotSemanticBlockQuote,
1544
+ DotSemanticCodeBlock,
1545
+ DotContentletBlock,
1546
+ DotUnknownBlockComponent
1547
+ ], template: "@if ($blockEditorState().error && $isInEditMode()) {\n <div data-testid=\"invalid-blocks-message\">\n {{ $blockEditorState().error }}\n </div>\n} @else if (!$blockEditorState().error) {\n <div [class]=\"cssClass()\" [style]=\"style()\">\n <ng-container *ngTemplateOutlet=\"nodeList; context: { $implicit: blocks()?.content }\" />\n </div>\n}\n\n<!-- Renders a list of nodes by dispatching each one. -->\n<ng-template #nodeList let-content>\n @for (node of content; track node) {\n <ng-container *ngTemplateOutlet=\"dispatch; context: { $implicit: node }\" />\n }\n</ng-template>\n\n<!--\n Dispatches a single node to its semantic tag. The host ng-container of each\n ngTemplateOutlet renders as an HTML comment node, so a list item stays a true\n DOM child of its list element \u2014 the property that makes this AT-proof.\n-->\n<ng-template #dispatch let-node>\n @if (customRenderers()?.[node.type]) {\n <ng-container\n *ngTemplateOutlet=\"\n customRender;\n context: { customRender: customRenderers()?.[node.type], node: node }\n \" />\n } @else {\n @switch (node.type) {\n @case (BLOCKS.PARAGRAPH) {\n <p dotParagraph [style.text-align]=\"node.attrs?.['textAlign'] || null\">\n <ng-container\n *ngTemplateOutlet=\"nodeList; context: { $implicit: node.content }\" />\n </p>\n }\n\n @case (BLOCKS.TEXT) {\n <ng-container\n *ngTemplateOutlet=\"\n textRun;\n context: { marks: node.marks, text: node.text || '' }\n \" />\n }\n\n @case (BLOCKS.HEADING) {\n @switch (asLevel(node.attrs?.['level'])) {\n @case ('1') {\n <h1 [style.text-align]=\"node.attrs?.['textAlign'] || null\">\n <ng-container\n *ngTemplateOutlet=\"\n nodeList;\n context: { $implicit: node.content }\n \" />\n </h1>\n }\n @case ('2') {\n <h2 [style.text-align]=\"node.attrs?.['textAlign'] || null\">\n <ng-container\n *ngTemplateOutlet=\"\n nodeList;\n context: { $implicit: node.content }\n \" />\n </h2>\n }\n @case ('3') {\n <h3 [style.text-align]=\"node.attrs?.['textAlign'] || null\">\n <ng-container\n *ngTemplateOutlet=\"\n nodeList;\n context: { $implicit: node.content }\n \" />\n </h3>\n }\n @case ('4') {\n <h4 [style.text-align]=\"node.attrs?.['textAlign'] || null\">\n <ng-container\n *ngTemplateOutlet=\"\n nodeList;\n context: { $implicit: node.content }\n \" />\n </h4>\n }\n @case ('5') {\n <h5 [style.text-align]=\"node.attrs?.['textAlign'] || null\">\n <ng-container\n *ngTemplateOutlet=\"\n nodeList;\n context: { $implicit: node.content }\n \" />\n </h5>\n }\n @case ('6') {\n <h6 [style.text-align]=\"node.attrs?.['textAlign'] || null\">\n <ng-container\n *ngTemplateOutlet=\"\n nodeList;\n context: { $implicit: node.content }\n \" />\n </h6>\n }\n @default {\n <!--\n Unknown level: fall back to <h2>, not <h1>. An\n unexpected <h1> in an article tanks the heading\n outline that assistive technology relies on, and\n articles typically already have a page <h1>.\n -->\n <h2 [style.text-align]=\"node.attrs?.['textAlign'] || null\">\n <ng-container\n *ngTemplateOutlet=\"\n nodeList;\n context: { $implicit: node.content }\n \" />\n </h2>\n }\n }\n }\n\n @case (BLOCKS.BULLET_LIST) {\n <ul dotBulletList>\n <ng-container\n *ngTemplateOutlet=\"nodeList; context: { $implicit: node.content }\" />\n </ul>\n }\n\n @case (BLOCKS.ORDERED_LIST) {\n <ol dotOrderedList>\n <ng-container\n *ngTemplateOutlet=\"nodeList; context: { $implicit: node.content }\" />\n </ol>\n }\n\n @case (BLOCKS.LIST_ITEM) {\n <li dotListItem>\n <ng-container\n *ngTemplateOutlet=\"nodeList; context: { $implicit: node.content }\" />\n </li>\n }\n\n @case (BLOCKS.BLOCK_QUOTE) {\n <blockquote dotBlockQuote>\n <ng-container\n *ngTemplateOutlet=\"nodeList; context: { $implicit: node.content }\" />\n </blockquote>\n }\n\n @case (BLOCKS.CODE_BLOCK) {\n <pre dotCodeBlock>\n <ng-container\n *ngTemplateOutlet=\"nodeList; context: { $implicit: node.content }\" /></pre>\n }\n\n @case (BLOCKS.HARDBREAK) {\n <br />\n }\n\n @case (BLOCKS.HORIZONTAL_RULE) {\n <hr />\n }\n\n @case (BLOCKS.DOT_IMAGE) {\n <figure [style]=\"imageStyle(node.attrs)\">\n <img\n [alt]=\"node.attrs?.['alt']\"\n [src]=\"node.attrs?.['src']\"\n style=\"max-width: 100%; height: auto\" />\n </figure>\n }\n\n @case (BLOCKS.DOT_VIDEO) {\n <video\n [controls]=\"true\"\n preload=\"metadata\"\n [poster]=\"videoPoster(node.attrs)\"\n [width]=\"node.attrs?.['width']\"\n [height]=\"node.attrs?.['height']\">\n <track default kind=\"captions\" srclang=\"en\" />\n <source [src]=\"node.attrs?.['src']\" [type]=\"node.attrs?.['mimeType']\" />\n Your browser does not support the\n <code>video</code>\n element.\n </video>\n }\n\n @case (BLOCKS.TABLE) {\n <table>\n <thead>\n @for (rowNode of node.content?.slice(0, 1); track $index) {\n <tr>\n @for (cellNode of rowNode.content; track $index) {\n <th\n [attr.colspan]=\"cellNode.attrs?.['colspan'] || 1\"\n [attr.rowspan]=\"cellNode.attrs?.['rowspan'] || 1\">\n <ng-container\n *ngTemplateOutlet=\"\n nodeList;\n context: { $implicit: cellNode.content }\n \" />\n </th>\n }\n </tr>\n }\n </thead>\n <tbody>\n @for (rowNode of node.content?.slice(1); track $index) {\n <tr>\n @for (cellNode of rowNode.content; track $index) {\n <td\n [attr.colspan]=\"cellNode.attrs?.['colspan'] || 1\"\n [attr.rowspan]=\"cellNode.attrs?.['rowspan'] || 1\">\n <ng-container\n *ngTemplateOutlet=\"\n nodeList;\n context: { $implicit: cellNode.content }\n \" />\n </td>\n }\n </tr>\n }\n </tbody>\n </table>\n }\n\n @case (BLOCKS.GRID_BLOCK) {\n <div\n data-type=\"gridBlock\"\n class=\"grid-block\"\n style=\"display: grid; grid-template-columns: repeat(12, 1fr); gap: 1rem\">\n @for (column of node.content; track $index) {\n <div\n data-type=\"gridColumn\"\n class=\"grid-block__column\"\n [style.grid-column]=\"'span ' + columnSpan(node.attrs, $index)\">\n <ng-container\n *ngTemplateOutlet=\"\n nodeList;\n context: { $implicit: column.content }\n \" />\n </div>\n }\n </div>\n }\n\n @case (BLOCKS.DOT_CONTENT) {\n <dotcms-block-editor-renderer-contentlet\n [node]=\"node\"\n [customRenderers]=\"customRenderers()\" />\n }\n\n @default {\n <dotcms-block-editor-renderer-unknown [node]=\"node\" />\n }\n }\n }\n</ng-template>\n\n<ng-template #customRender let-customRender=\"customRender\" let-node=\"node\">\n <ng-container *ngComponentOutlet=\"customRender | async; inputs: { node: node }\" />\n</ng-template>\n\n<!--\n Renders a text node and its marks as native inline elements (<strong>, <u>,\n <em>, <a>, ...) with no wrapper element. Recurses through itself (rendered as a\n comment node) one mark at a time, so stacked marks nest directly:\n <u><strong>text</strong></u>.\n-->\n<ng-template #textRun let-marks=\"marks\" let-text=\"text\">\n @switch (marks?.[0]?.type) {\n @case ('link') {\n @if (markAttrs(marks)['href']) {\n <a\n [attr.href]=\"markAttrs(marks)['href']\"\n [attr.target]=\"markAttrs(marks)['target'] || null\"\n [attr.title]=\"markAttrs(marks)['title'] || null\"\n [attr.aria-label]=\"markAttrs(marks)['aria-label'] || null\"\n [attr.rel]=\"\n markAttrs(marks)['rel'] ||\n (markAttrs(marks)['target'] === '_blank' ? 'noopener noreferrer' : null)\n \"\n [class]=\"markAttrs(marks)['class'] || null\">\n <ng-container\n *ngTemplateOutlet=\"\n textRun;\n context: { marks: restMarks(marks), text: text }\n \" />\n </a>\n } @else {\n <!--\n Malformed link mark with no href: a hrefless <a> isn't a\n link to assistive tech (no role, not focusable). Skip the\n element and recurse \u2014 any remaining marks (bold, etc.)\n still render around the text.\n -->\n <ng-container\n *ngTemplateOutlet=\"textRun; context: { marks: restMarks(marks), text: text }\" />\n }\n }\n @case ('bold') {\n <strong>\n <ng-container\n *ngTemplateOutlet=\"textRun; context: { marks: restMarks(marks), text: text }\" />\n </strong>\n }\n @case ('underline') {\n <u>\n <ng-container\n *ngTemplateOutlet=\"textRun; context: { marks: restMarks(marks), text: text }\" />\n </u>\n }\n @case ('italic') {\n <em>\n <ng-container\n *ngTemplateOutlet=\"textRun; context: { marks: restMarks(marks), text: text }\" />\n </em>\n }\n @case ('strike') {\n <s>\n <ng-container\n *ngTemplateOutlet=\"textRun; context: { marks: restMarks(marks), text: text }\" />\n </s>\n }\n @case ('superscript') {\n <sup>\n <ng-container\n *ngTemplateOutlet=\"textRun; context: { marks: restMarks(marks), text: text }\" />\n </sup>\n }\n @case ('subscript') {\n <sub>\n <ng-container\n *ngTemplateOutlet=\"textRun; context: { marks: restMarks(marks), text: text }\" />\n </sub>\n }\n @default {\n @if (marks?.length) {\n <!-- Unknown mark type: skip it but keep rendering any marks beneath. -->\n <ng-container\n *ngTemplateOutlet=\"textRun; context: { marks: restMarks(marks), text: text }\" />\n } @else {\n {{ text }}\n }\n }\n }\n</ng-template>\n" }]
1548
+ }], propDecorators: { blocks: [{ type: i0.Input, args: [{ isSignal: true, alias: "blocks", required: false }] }], customRenderers: [{ type: i0.Input, args: [{ isSignal: true, alias: "customRenderers", required: false }] }], cssClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], style: [{ type: i0.Input, args: [{ isSignal: true, alias: "style", required: false }] }] } });
1549
+
1293
1550
  /**
1294
1551
  * @description This component is used to display a message when a page is missing the required `layout.body` property.
1295
1552
  * @internal
@@ -2008,5 +2265,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImpor
2008
2265
  * Generated bundle index. Do not edit.
2009
2266
  */
2010
2267
 
2011
- export { DotCMSBlockEditorRendererComponent, DotCMSClient, DotCMSEditablePageService, DotCMSEditableTextComponent, DotCMSLayoutBodyComponent, DotCMSShowWhenDirective, provideDotCMSClient, provideDotCMSImageLoader };
2268
+ export { DotCMSBlockEditorRendererComponent, DotCMSBlockEditorRendererNativeComponent, DotCMSClient, DotCMSEditablePageService, DotCMSEditableTextComponent, DotCMSLayoutBodyComponent, DotCMSShowWhenDirective, provideDotCMSClient, provideDotCMSImageLoader };
2012
2269
  //# sourceMappingURL=dotcms-angular.mjs.map