@sitecore-jss/sitecore-jss-angular 20.2.3 → 20.3.0-canary.2
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.
- package/LICENSE.txt +202 -202
- package/README.md +8 -8
- package/dist/README.md +8 -8
- package/dist/bundles/sitecore-jss-sitecore-jss-angular.umd.js +1448 -1444
- package/dist/bundles/sitecore-jss-sitecore-jss-angular.umd.js.map +1 -1
- package/dist/bundles/sitecore-jss-sitecore-jss-angular.umd.min.js +2 -2
- package/dist/bundles/sitecore-jss-sitecore-jss-angular.umd.min.js.map +1 -1
- package/dist/components/date.directive.d.ts +17 -17
- package/dist/components/file.directive.d.ts +14 -14
- package/dist/components/generic-link.directive.d.ts +18 -18
- package/dist/components/hidden-rendering.component.d.ts +4 -4
- package/dist/components/image.directive.d.ts +32 -32
- package/dist/components/link.directive.d.ts +22 -22
- package/dist/components/missing-component.component.d.ts +4 -4
- package/dist/components/placeholder-loading.directive.d.ts +5 -5
- package/dist/components/placeholder.component.d.ts +46 -46
- package/dist/components/placeholder.token.d.ts +31 -31
- package/dist/components/raw.component.d.ts +9 -9
- package/dist/components/render-component.component.d.ts +31 -31
- package/dist/components/render-each.directive.d.ts +5 -5
- package/dist/components/render-empty.directive.d.ts +5 -5
- package/dist/components/rendering-field.d.ts +40 -40
- package/dist/components/rendering.d.ts +5 -5
- package/dist/components/rich-text.directive.d.ts +12 -12
- package/dist/components/router-link.directive.d.ts +16 -16
- package/dist/components/text.directive.d.ts +13 -13
- package/dist/esm2015/components/date.directive.js +52 -52
- package/dist/esm2015/components/file.directive.js +44 -44
- package/dist/esm2015/components/generic-link.directive.js +57 -57
- package/dist/esm2015/components/hidden-rendering.component.js +16 -16
- package/dist/esm2015/components/image.directive.js +122 -122
- package/dist/esm2015/components/link.directive.js +101 -101
- package/dist/esm2015/components/missing-component.component.js +12 -12
- package/dist/esm2015/components/placeholder-loading.directive.js +14 -14
- package/dist/esm2015/components/placeholder.component.js +197 -197
- package/dist/esm2015/components/placeholder.token.js +21 -21
- package/dist/esm2015/components/raw.component.js +36 -36
- package/dist/esm2015/components/render-component.component.js +88 -88
- package/dist/esm2015/components/render-each.directive.js +14 -14
- package/dist/esm2015/components/render-empty.directive.js +14 -14
- package/dist/esm2015/components/rendering-field.js +1 -1
- package/dist/esm2015/components/rendering.js +7 -7
- package/dist/esm2015/components/rich-text.directive.js +40 -40
- package/dist/esm2015/components/router-link.directive.js +43 -43
- package/dist/esm2015/components/text.directive.js +53 -53
- package/dist/esm2015/jss-component-factory.service.js +87 -87
- package/dist/esm2015/lib.module.js +114 -114
- package/dist/esm2015/public_api.js +19 -18
- package/dist/esm2015/sitecore-jss-sitecore-jss-angular.js +13 -13
- package/dist/fesm2015/sitecore-jss-sitecore-jss-angular.js +1051 -1050
- package/dist/fesm2015/sitecore-jss-sitecore-jss-angular.js.map +1 -1
- package/dist/jss-component-factory.service.d.ts +21 -21
- package/dist/lib.module.d.ts +24 -24
- package/dist/package.json +2 -2
- package/dist/public_api.d.ts +19 -18
- package/dist/sitecore-jss-sitecore-jss-angular.d.ts +13 -13
- package/dist/sitecore-jss-sitecore-jss-angular.metadata.json +1 -1
- package/package.json +3 -3
- package/typings/README.md +2 -2
|
@@ -8,923 +8,924 @@ import { takeWhile } from 'rxjs/operators';
|
|
|
8
8
|
import { DatePipe, CommonModule } from '@angular/common';
|
|
9
9
|
export { GraphQLDictionaryService, RestDictionaryService } from '@sitecore-jss/sitecore-jss/i18n';
|
|
10
10
|
export { GraphQLLayoutService, RestLayoutService, getChildPlaceholder, getFieldValue } from '@sitecore-jss/sitecore-jss/layout';
|
|
11
|
+
export { DefaultRetryStrategy } from '@sitecore-jss/sitecore-jss/graphql';
|
|
11
12
|
export { constants } from '@sitecore-jss/sitecore-jss';
|
|
12
13
|
export { handleEditorAnchors, isEditorActive, isExperienceEditorActive, isServer, resetEditorChromes, resetExperienceEditorChromes } from '@sitecore-jss/sitecore-jss/utils';
|
|
13
14
|
|
|
14
|
-
/**
|
|
15
|
-
* File fields cannot be managed via the EE. We never output "editable."
|
|
16
|
-
*/
|
|
17
|
-
class FileDirective {
|
|
18
|
-
constructor(viewContainer, templateRef) {
|
|
19
|
-
this.viewContainer = viewContainer;
|
|
20
|
-
this.templateRef = templateRef;
|
|
21
|
-
}
|
|
22
|
-
ngOnChanges(changes) {
|
|
23
|
-
if (changes.field) {
|
|
24
|
-
if (!this.viewRef) {
|
|
25
|
-
this.viewContainer.clear();
|
|
26
|
-
this.viewRef = this.viewContainer.createEmbeddedView(this.templateRef);
|
|
27
|
-
}
|
|
28
|
-
this.updateView();
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
updateView() {
|
|
32
|
-
const field = this.field;
|
|
33
|
-
if (!field || (!field.value && !field.src)) {
|
|
34
|
-
return;
|
|
35
|
-
}
|
|
36
|
-
const file = field.src ? field : field.value;
|
|
37
|
-
this.viewRef.rootNodes.forEach((node) => {
|
|
38
|
-
if (!file)
|
|
39
|
-
return;
|
|
40
|
-
node.href = file.src;
|
|
41
|
-
if (node.innerHTML === '') {
|
|
42
|
-
node.innerHTML = file.title || file.displayName;
|
|
43
|
-
}
|
|
44
|
-
});
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
FileDirective.decorators = [
|
|
48
|
-
{ type: Directive, args: [{ selector: '[scFile]' },] }
|
|
49
|
-
];
|
|
50
|
-
FileDirective.ctorParameters = () => [
|
|
51
|
-
{ type: ViewContainerRef },
|
|
52
|
-
{ type: TemplateRef }
|
|
53
|
-
];
|
|
54
|
-
FileDirective.propDecorators = {
|
|
55
|
-
field: [{ type: Input, args: ['scFile',] }]
|
|
15
|
+
/**
|
|
16
|
+
* File fields cannot be managed via the EE. We never output "editable."
|
|
17
|
+
*/
|
|
18
|
+
class FileDirective {
|
|
19
|
+
constructor(viewContainer, templateRef) {
|
|
20
|
+
this.viewContainer = viewContainer;
|
|
21
|
+
this.templateRef = templateRef;
|
|
22
|
+
}
|
|
23
|
+
ngOnChanges(changes) {
|
|
24
|
+
if (changes.field) {
|
|
25
|
+
if (!this.viewRef) {
|
|
26
|
+
this.viewContainer.clear();
|
|
27
|
+
this.viewRef = this.viewContainer.createEmbeddedView(this.templateRef);
|
|
28
|
+
}
|
|
29
|
+
this.updateView();
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
updateView() {
|
|
33
|
+
const field = this.field;
|
|
34
|
+
if (!field || (!field.value && !field.src)) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
const file = field.src ? field : field.value;
|
|
38
|
+
this.viewRef.rootNodes.forEach((node) => {
|
|
39
|
+
if (!file)
|
|
40
|
+
return;
|
|
41
|
+
node.href = file.src;
|
|
42
|
+
if (node.innerHTML === '') {
|
|
43
|
+
node.innerHTML = file.title || file.displayName;
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
FileDirective.decorators = [
|
|
49
|
+
{ type: Directive, args: [{ selector: '[scFile]' },] }
|
|
50
|
+
];
|
|
51
|
+
FileDirective.ctorParameters = () => [
|
|
52
|
+
{ type: ViewContainerRef },
|
|
53
|
+
{ type: TemplateRef }
|
|
54
|
+
];
|
|
55
|
+
FileDirective.propDecorators = {
|
|
56
|
+
field: [{ type: Input, args: ['scFile',] }]
|
|
56
57
|
};
|
|
57
58
|
|
|
58
|
-
class ImageDirective {
|
|
59
|
-
constructor(viewContainer, templateRef, renderer, elementRef) {
|
|
60
|
-
this.viewContainer = viewContainer;
|
|
61
|
-
this.templateRef = templateRef;
|
|
62
|
-
this.renderer = renderer;
|
|
63
|
-
this.elementRef = elementRef;
|
|
64
|
-
this.inlineRef = null;
|
|
65
|
-
this.editable = true;
|
|
66
|
-
this.urlParams = {};
|
|
67
|
-
this.attrs = {};
|
|
68
|
-
}
|
|
69
|
-
ngOnChanges(changes) {
|
|
70
|
-
if (changes.field || changes.editable || changes.urlParams || changes.attrs) {
|
|
71
|
-
this.viewContainer.clear();
|
|
72
|
-
if (this.inlineRef) {
|
|
73
|
-
this.inlineRef.remove();
|
|
74
|
-
this.inlineRef = null;
|
|
75
|
-
}
|
|
76
|
-
this.updateView();
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
updateView() {
|
|
80
|
-
const overrideAttrs = Object.assign(Object.assign({}, this.getElementAttrs()), this.attrs);
|
|
81
|
-
const media = this.field;
|
|
82
|
-
if (!media || (!media.editable && !media.value && !media.src)) {
|
|
83
|
-
return;
|
|
84
|
-
}
|
|
85
|
-
let attrs = {};
|
|
86
|
-
// we likely have an experience editor value, should be a string
|
|
87
|
-
if (this.editable && media.editable) {
|
|
88
|
-
const foundImg = mediaApi.findEditorImageTag(media.editable);
|
|
89
|
-
if (!foundImg) {
|
|
90
|
-
return this.renderInlineWrapper(media.editable);
|
|
91
|
-
}
|
|
92
|
-
attrs = this.getImageAttrs(foundImg.attrs, overrideAttrs, this.urlParams);
|
|
93
|
-
if (!attrs) {
|
|
94
|
-
return this.renderInlineWrapper(media.editable);
|
|
95
|
-
}
|
|
96
|
-
const tempImg = this.renderer.createElement('img');
|
|
97
|
-
Object.entries(attrs).forEach(([key, attrValue]) => tempImg.setAttribute(key, attrValue));
|
|
98
|
-
const editableMarkup = media.editable.replace(foundImg.imgTag, tempImg.outerHTML);
|
|
99
|
-
return this.renderInlineWrapper(editableMarkup);
|
|
100
|
-
}
|
|
101
|
-
// some wise-guy/gal is passing in a 'raw' image object value
|
|
102
|
-
const img = media.src ? media : media.value;
|
|
103
|
-
if (!img) {
|
|
104
|
-
return null;
|
|
105
|
-
}
|
|
106
|
-
attrs = this.getImageAttrs(img, overrideAttrs, this.urlParams);
|
|
107
|
-
if (attrs) {
|
|
108
|
-
this.renderTemplate(attrs);
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
getImageAttrs(fieldAttrs, parsedAttrs, imageParams) {
|
|
112
|
-
const combinedAttrs = Object.assign(Object.assign({}, fieldAttrs), parsedAttrs);
|
|
113
|
-
// eslint-disable-next-line prefer-const
|
|
114
|
-
let { src, srcSet } = combinedAttrs, otherAttrs = __rest(combinedAttrs, ["src", "srcSet"]);
|
|
115
|
-
if (!src) {
|
|
116
|
-
return null;
|
|
117
|
-
}
|
|
118
|
-
const newAttrs = Object.assign({}, otherAttrs);
|
|
119
|
-
// update image URL for jss handler and image rendering params
|
|
120
|
-
src = mediaApi.updateImageUrl(src, imageParams, this.mediaUrlPrefix);
|
|
121
|
-
if (srcSet) {
|
|
122
|
-
// replace with HTML-formatted srcset, including updated image URLs
|
|
123
|
-
newAttrs.srcSet = mediaApi.getSrcSet(src, srcSet, imageParams, this.mediaUrlPrefix);
|
|
124
|
-
}
|
|
125
|
-
else {
|
|
126
|
-
newAttrs.src = src;
|
|
127
|
-
}
|
|
128
|
-
return newAttrs;
|
|
129
|
-
}
|
|
130
|
-
renderTemplate(imageProps) {
|
|
131
|
-
const viewRef = this.viewContainer.createEmbeddedView(this.templateRef);
|
|
132
|
-
viewRef.rootNodes.forEach((node) => {
|
|
133
|
-
Object.entries(imageProps).forEach(([key, imgPropVal]) => this.renderer.setAttribute(node, key, imgPropVal));
|
|
134
|
-
});
|
|
135
|
-
}
|
|
136
|
-
getElementAttrs() {
|
|
137
|
-
const view = this.templateRef.createEmbeddedView(null);
|
|
138
|
-
const element = view.rootNodes[0];
|
|
139
|
-
if (!element) {
|
|
140
|
-
return {};
|
|
141
|
-
}
|
|
142
|
-
const attrs = {};
|
|
143
|
-
for (let i = 0; i < element.attributes.length; i++) {
|
|
144
|
-
const attr = element.attributes.item(i);
|
|
145
|
-
if (attr) {
|
|
146
|
-
attrs[attr.name] = attr.value;
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
return attrs;
|
|
150
|
-
}
|
|
151
|
-
renderInlineWrapper(editable) {
|
|
152
|
-
const span = this.renderer.createElement('span');
|
|
153
|
-
span.className = 'sc-image-wrapper';
|
|
154
|
-
span.innerHTML = editable;
|
|
155
|
-
const parentNode = this.renderer.parentNode(this.elementRef.nativeElement);
|
|
156
|
-
this.renderer.insertBefore(parentNode, span, this.elementRef.nativeElement);
|
|
157
|
-
parentNode.removeChild(this.elementRef.nativeElement);
|
|
158
|
-
this.inlineRef = span;
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
ImageDirective.decorators = [
|
|
162
|
-
{ type: Directive, args: [{ selector: '[scImage]' },] }
|
|
163
|
-
];
|
|
164
|
-
ImageDirective.ctorParameters = () => [
|
|
165
|
-
{ type: ViewContainerRef },
|
|
166
|
-
{ type: TemplateRef },
|
|
167
|
-
{ type: Renderer2 },
|
|
168
|
-
{ type: ElementRef }
|
|
169
|
-
];
|
|
170
|
-
ImageDirective.propDecorators = {
|
|
171
|
-
field: [{ type: Input, args: ['scImage',] }],
|
|
172
|
-
editable: [{ type: Input, args: ['scImageEditable',] }],
|
|
173
|
-
mediaUrlPrefix: [{ type: Input, args: ['scImageMediaUrlPrefix',] }],
|
|
174
|
-
urlParams: [{ type: Input, args: ['scImageUrlParams',] }],
|
|
175
|
-
attrs: [{ type: Input, args: ['scImageAttrs',] }]
|
|
59
|
+
class ImageDirective {
|
|
60
|
+
constructor(viewContainer, templateRef, renderer, elementRef) {
|
|
61
|
+
this.viewContainer = viewContainer;
|
|
62
|
+
this.templateRef = templateRef;
|
|
63
|
+
this.renderer = renderer;
|
|
64
|
+
this.elementRef = elementRef;
|
|
65
|
+
this.inlineRef = null;
|
|
66
|
+
this.editable = true;
|
|
67
|
+
this.urlParams = {};
|
|
68
|
+
this.attrs = {};
|
|
69
|
+
}
|
|
70
|
+
ngOnChanges(changes) {
|
|
71
|
+
if (changes.field || changes.editable || changes.urlParams || changes.attrs) {
|
|
72
|
+
this.viewContainer.clear();
|
|
73
|
+
if (this.inlineRef) {
|
|
74
|
+
this.inlineRef.remove();
|
|
75
|
+
this.inlineRef = null;
|
|
76
|
+
}
|
|
77
|
+
this.updateView();
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
updateView() {
|
|
81
|
+
const overrideAttrs = Object.assign(Object.assign({}, this.getElementAttrs()), this.attrs);
|
|
82
|
+
const media = this.field;
|
|
83
|
+
if (!media || (!media.editable && !media.value && !media.src)) {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
let attrs = {};
|
|
87
|
+
// we likely have an experience editor value, should be a string
|
|
88
|
+
if (this.editable && media.editable) {
|
|
89
|
+
const foundImg = mediaApi.findEditorImageTag(media.editable);
|
|
90
|
+
if (!foundImg) {
|
|
91
|
+
return this.renderInlineWrapper(media.editable);
|
|
92
|
+
}
|
|
93
|
+
attrs = this.getImageAttrs(foundImg.attrs, overrideAttrs, this.urlParams);
|
|
94
|
+
if (!attrs) {
|
|
95
|
+
return this.renderInlineWrapper(media.editable);
|
|
96
|
+
}
|
|
97
|
+
const tempImg = this.renderer.createElement('img');
|
|
98
|
+
Object.entries(attrs).forEach(([key, attrValue]) => tempImg.setAttribute(key, attrValue));
|
|
99
|
+
const editableMarkup = media.editable.replace(foundImg.imgTag, tempImg.outerHTML);
|
|
100
|
+
return this.renderInlineWrapper(editableMarkup);
|
|
101
|
+
}
|
|
102
|
+
// some wise-guy/gal is passing in a 'raw' image object value
|
|
103
|
+
const img = media.src ? media : media.value;
|
|
104
|
+
if (!img) {
|
|
105
|
+
return null;
|
|
106
|
+
}
|
|
107
|
+
attrs = this.getImageAttrs(img, overrideAttrs, this.urlParams);
|
|
108
|
+
if (attrs) {
|
|
109
|
+
this.renderTemplate(attrs);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
getImageAttrs(fieldAttrs, parsedAttrs, imageParams) {
|
|
113
|
+
const combinedAttrs = Object.assign(Object.assign({}, fieldAttrs), parsedAttrs);
|
|
114
|
+
// eslint-disable-next-line prefer-const
|
|
115
|
+
let { src, srcSet } = combinedAttrs, otherAttrs = __rest(combinedAttrs, ["src", "srcSet"]);
|
|
116
|
+
if (!src) {
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
const newAttrs = Object.assign({}, otherAttrs);
|
|
120
|
+
// update image URL for jss handler and image rendering params
|
|
121
|
+
src = mediaApi.updateImageUrl(src, imageParams, this.mediaUrlPrefix);
|
|
122
|
+
if (srcSet) {
|
|
123
|
+
// replace with HTML-formatted srcset, including updated image URLs
|
|
124
|
+
newAttrs.srcSet = mediaApi.getSrcSet(src, srcSet, imageParams, this.mediaUrlPrefix);
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
newAttrs.src = src;
|
|
128
|
+
}
|
|
129
|
+
return newAttrs;
|
|
130
|
+
}
|
|
131
|
+
renderTemplate(imageProps) {
|
|
132
|
+
const viewRef = this.viewContainer.createEmbeddedView(this.templateRef);
|
|
133
|
+
viewRef.rootNodes.forEach((node) => {
|
|
134
|
+
Object.entries(imageProps).forEach(([key, imgPropVal]) => this.renderer.setAttribute(node, key, imgPropVal));
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
getElementAttrs() {
|
|
138
|
+
const view = this.templateRef.createEmbeddedView(null);
|
|
139
|
+
const element = view.rootNodes[0];
|
|
140
|
+
if (!element) {
|
|
141
|
+
return {};
|
|
142
|
+
}
|
|
143
|
+
const attrs = {};
|
|
144
|
+
for (let i = 0; i < element.attributes.length; i++) {
|
|
145
|
+
const attr = element.attributes.item(i);
|
|
146
|
+
if (attr) {
|
|
147
|
+
attrs[attr.name] = attr.value;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
return attrs;
|
|
151
|
+
}
|
|
152
|
+
renderInlineWrapper(editable) {
|
|
153
|
+
const span = this.renderer.createElement('span');
|
|
154
|
+
span.className = 'sc-image-wrapper';
|
|
155
|
+
span.innerHTML = editable;
|
|
156
|
+
const parentNode = this.renderer.parentNode(this.elementRef.nativeElement);
|
|
157
|
+
this.renderer.insertBefore(parentNode, span, this.elementRef.nativeElement);
|
|
158
|
+
parentNode.removeChild(this.elementRef.nativeElement);
|
|
159
|
+
this.inlineRef = span;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
ImageDirective.decorators = [
|
|
163
|
+
{ type: Directive, args: [{ selector: '[scImage]' },] }
|
|
164
|
+
];
|
|
165
|
+
ImageDirective.ctorParameters = () => [
|
|
166
|
+
{ type: ViewContainerRef },
|
|
167
|
+
{ type: TemplateRef },
|
|
168
|
+
{ type: Renderer2 },
|
|
169
|
+
{ type: ElementRef }
|
|
170
|
+
];
|
|
171
|
+
ImageDirective.propDecorators = {
|
|
172
|
+
field: [{ type: Input, args: ['scImage',] }],
|
|
173
|
+
editable: [{ type: Input, args: ['scImageEditable',] }],
|
|
174
|
+
mediaUrlPrefix: [{ type: Input, args: ['scImageMediaUrlPrefix',] }],
|
|
175
|
+
urlParams: [{ type: Input, args: ['scImageUrlParams',] }],
|
|
176
|
+
attrs: [{ type: Input, args: ['scImageAttrs',] }]
|
|
176
177
|
};
|
|
177
178
|
|
|
178
|
-
class LinkDirective {
|
|
179
|
-
constructor(viewContainer, templateRef, renderer, elementRef) {
|
|
180
|
-
this.viewContainer = viewContainer;
|
|
181
|
-
this.templateRef = templateRef;
|
|
182
|
-
this.renderer = renderer;
|
|
183
|
-
this.elementRef = elementRef;
|
|
184
|
-
this.inlineRef = null;
|
|
185
|
-
this.editable = true;
|
|
186
|
-
this.attrs = {};
|
|
187
|
-
}
|
|
188
|
-
ngOnChanges(changes) {
|
|
189
|
-
if (changes.field || changes.editable || changes.attrs) {
|
|
190
|
-
this.viewContainer.clear();
|
|
191
|
-
if (this.inlineRef) {
|
|
192
|
-
this.inlineRef.remove();
|
|
193
|
-
this.inlineRef = null;
|
|
194
|
-
}
|
|
195
|
-
this.updateView();
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
updateView() {
|
|
199
|
-
var _a, _b;
|
|
200
|
-
const field = this.field;
|
|
201
|
-
if (this.editable && field && field.editableFirstPart && field.editableLastPart) {
|
|
202
|
-
this.renderInlineWrapper(field.editableFirstPart, field.editableLastPart);
|
|
203
|
-
}
|
|
204
|
-
else if (field && (field.href || field.value)) {
|
|
205
|
-
const props = field.href ? field : field.value;
|
|
206
|
-
const linkText = field.text || ((_a = field.value) === null || _a === void 0 ? void 0 : _a.text) || field.href || ((_b = field.value) === null || _b === void 0 ? void 0 : _b.href);
|
|
207
|
-
const mergedAttrs = Object.assign(Object.assign({}, props), this.attrs);
|
|
208
|
-
this.renderTemplate(mergedAttrs, linkText);
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
renderTemplate(props, linkText) {
|
|
212
|
-
const viewRef = this.viewContainer.createEmbeddedView(this.templateRef);
|
|
213
|
-
viewRef.rootNodes.forEach((node) => {
|
|
214
|
-
Object.entries(props).forEach(([key, propValue]) => {
|
|
215
|
-
if (typeof propValue !== 'string')
|
|
216
|
-
return;
|
|
217
|
-
if (key === 'href') {
|
|
218
|
-
const isInvalidLink = !propValue || /^https?:\/\/$/.test(propValue);
|
|
219
|
-
if (isInvalidLink) {
|
|
220
|
-
if (!node.href) {
|
|
221
|
-
return;
|
|
222
|
-
}
|
|
223
|
-
propValue = node.href;
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
if (key === 'class' && node.className) {
|
|
227
|
-
propValue += ` ${node.className}`;
|
|
228
|
-
}
|
|
229
|
-
this.renderer.setAttribute(node, key, propValue);
|
|
230
|
-
});
|
|
231
|
-
if (node.childNodes && node.childNodes.length === 0 && linkText) {
|
|
232
|
-
node.textContent = linkText;
|
|
233
|
-
}
|
|
234
|
-
});
|
|
235
|
-
}
|
|
236
|
-
renderInlineWrapper(editableFirstPart, editableLastPart) {
|
|
237
|
-
const span = this.renderer.createElement('span');
|
|
238
|
-
span.className = 'sc-link-wrapper';
|
|
239
|
-
span.innerHTML = editableFirstPart + editableLastPart;
|
|
240
|
-
// assign attributes from template to inline wrapper
|
|
241
|
-
const attrs = Object.assign(Object.assign({}, this.getElementAttrs()), this.attrs);
|
|
242
|
-
Object.entries(attrs).forEach(([key, attrValue]) => this.renderer.setAttribute(span, key, attrValue));
|
|
243
|
-
this.viewContainer.createEmbeddedView(this.templateRef);
|
|
244
|
-
const parentNode = this.renderer.parentNode(this.elementRef.nativeElement);
|
|
245
|
-
this.renderer.insertBefore(parentNode, span, this.elementRef.nativeElement);
|
|
246
|
-
this.inlineRef = span;
|
|
247
|
-
}
|
|
248
|
-
getElementAttrs() {
|
|
249
|
-
const view = this.templateRef.createEmbeddedView(null);
|
|
250
|
-
const element = view.rootNodes[0];
|
|
251
|
-
if (!element) {
|
|
252
|
-
return {};
|
|
253
|
-
}
|
|
254
|
-
const attrs = {};
|
|
255
|
-
for (let i = 0; i < element.attributes.length; i++) {
|
|
256
|
-
const attr = element.attributes.item(i);
|
|
257
|
-
if (attr) {
|
|
258
|
-
attrs[attr.name] = attr.value;
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
return attrs;
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
LinkDirective.decorators = [
|
|
265
|
-
{ type: Directive, args: [{ selector: '[scLink]' },] }
|
|
266
|
-
];
|
|
267
|
-
LinkDirective.ctorParameters = () => [
|
|
268
|
-
{ type: ViewContainerRef },
|
|
269
|
-
{ type: TemplateRef },
|
|
270
|
-
{ type: Renderer2 },
|
|
271
|
-
{ type: ElementRef }
|
|
272
|
-
];
|
|
273
|
-
LinkDirective.propDecorators = {
|
|
274
|
-
editable: [{ type: Input, args: ['scLinkEditable',] }],
|
|
275
|
-
attrs: [{ type: Input, args: ['scLinkAttrs',] }],
|
|
276
|
-
field: [{ type: Input, args: ['scLink',] }]
|
|
179
|
+
class LinkDirective {
|
|
180
|
+
constructor(viewContainer, templateRef, renderer, elementRef) {
|
|
181
|
+
this.viewContainer = viewContainer;
|
|
182
|
+
this.templateRef = templateRef;
|
|
183
|
+
this.renderer = renderer;
|
|
184
|
+
this.elementRef = elementRef;
|
|
185
|
+
this.inlineRef = null;
|
|
186
|
+
this.editable = true;
|
|
187
|
+
this.attrs = {};
|
|
188
|
+
}
|
|
189
|
+
ngOnChanges(changes) {
|
|
190
|
+
if (changes.field || changes.editable || changes.attrs) {
|
|
191
|
+
this.viewContainer.clear();
|
|
192
|
+
if (this.inlineRef) {
|
|
193
|
+
this.inlineRef.remove();
|
|
194
|
+
this.inlineRef = null;
|
|
195
|
+
}
|
|
196
|
+
this.updateView();
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
updateView() {
|
|
200
|
+
var _a, _b;
|
|
201
|
+
const field = this.field;
|
|
202
|
+
if (this.editable && field && field.editableFirstPart && field.editableLastPart) {
|
|
203
|
+
this.renderInlineWrapper(field.editableFirstPart, field.editableLastPart);
|
|
204
|
+
}
|
|
205
|
+
else if (field && (field.href || field.value)) {
|
|
206
|
+
const props = field.href ? field : field.value;
|
|
207
|
+
const linkText = field.text || ((_a = field.value) === null || _a === void 0 ? void 0 : _a.text) || field.href || ((_b = field.value) === null || _b === void 0 ? void 0 : _b.href);
|
|
208
|
+
const mergedAttrs = Object.assign(Object.assign({}, props), this.attrs);
|
|
209
|
+
this.renderTemplate(mergedAttrs, linkText);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
renderTemplate(props, linkText) {
|
|
213
|
+
const viewRef = this.viewContainer.createEmbeddedView(this.templateRef);
|
|
214
|
+
viewRef.rootNodes.forEach((node) => {
|
|
215
|
+
Object.entries(props).forEach(([key, propValue]) => {
|
|
216
|
+
if (typeof propValue !== 'string')
|
|
217
|
+
return;
|
|
218
|
+
if (key === 'href') {
|
|
219
|
+
const isInvalidLink = !propValue || /^https?:\/\/$/.test(propValue);
|
|
220
|
+
if (isInvalidLink) {
|
|
221
|
+
if (!node.href) {
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
propValue = node.href;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
if (key === 'class' && node.className) {
|
|
228
|
+
propValue += ` ${node.className}`;
|
|
229
|
+
}
|
|
230
|
+
this.renderer.setAttribute(node, key, propValue);
|
|
231
|
+
});
|
|
232
|
+
if (node.childNodes && node.childNodes.length === 0 && linkText) {
|
|
233
|
+
node.textContent = linkText;
|
|
234
|
+
}
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
renderInlineWrapper(editableFirstPart, editableLastPart) {
|
|
238
|
+
const span = this.renderer.createElement('span');
|
|
239
|
+
span.className = 'sc-link-wrapper';
|
|
240
|
+
span.innerHTML = editableFirstPart + editableLastPart;
|
|
241
|
+
// assign attributes from template to inline wrapper
|
|
242
|
+
const attrs = Object.assign(Object.assign({}, this.getElementAttrs()), this.attrs);
|
|
243
|
+
Object.entries(attrs).forEach(([key, attrValue]) => this.renderer.setAttribute(span, key, attrValue));
|
|
244
|
+
this.viewContainer.createEmbeddedView(this.templateRef);
|
|
245
|
+
const parentNode = this.renderer.parentNode(this.elementRef.nativeElement);
|
|
246
|
+
this.renderer.insertBefore(parentNode, span, this.elementRef.nativeElement);
|
|
247
|
+
this.inlineRef = span;
|
|
248
|
+
}
|
|
249
|
+
getElementAttrs() {
|
|
250
|
+
const view = this.templateRef.createEmbeddedView(null);
|
|
251
|
+
const element = view.rootNodes[0];
|
|
252
|
+
if (!element) {
|
|
253
|
+
return {};
|
|
254
|
+
}
|
|
255
|
+
const attrs = {};
|
|
256
|
+
for (let i = 0; i < element.attributes.length; i++) {
|
|
257
|
+
const attr = element.attributes.item(i);
|
|
258
|
+
if (attr) {
|
|
259
|
+
attrs[attr.name] = attr.value;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
return attrs;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
LinkDirective.decorators = [
|
|
266
|
+
{ type: Directive, args: [{ selector: '[scLink]' },] }
|
|
267
|
+
];
|
|
268
|
+
LinkDirective.ctorParameters = () => [
|
|
269
|
+
{ type: ViewContainerRef },
|
|
270
|
+
{ type: TemplateRef },
|
|
271
|
+
{ type: Renderer2 },
|
|
272
|
+
{ type: ElementRef }
|
|
273
|
+
];
|
|
274
|
+
LinkDirective.propDecorators = {
|
|
275
|
+
editable: [{ type: Input, args: ['scLinkEditable',] }],
|
|
276
|
+
attrs: [{ type: Input, args: ['scLinkAttrs',] }],
|
|
277
|
+
field: [{ type: Input, args: ['scLink',] }]
|
|
277
278
|
};
|
|
278
279
|
|
|
279
|
-
class RouterLinkDirective extends LinkDirective {
|
|
280
|
-
constructor(viewContainer, templateRef, renderer, elementRef, router) {
|
|
281
|
-
super(viewContainer, templateRef, renderer, elementRef);
|
|
282
|
-
this.router = router;
|
|
283
|
-
this.editable = true;
|
|
284
|
-
this.attrs = {};
|
|
285
|
-
}
|
|
286
|
-
renderTemplate(props, linkText) {
|
|
287
|
-
const viewRef = this.viewContainer.createEmbeddedView(this.templateRef);
|
|
288
|
-
viewRef.rootNodes.forEach((node) => {
|
|
289
|
-
Object.entries(props).forEach(([key, propValue]) => {
|
|
290
|
-
this.renderer.setAttribute(node, key, propValue);
|
|
291
|
-
if (key === 'href') {
|
|
292
|
-
this.renderer.listen(node, 'click', (event) => {
|
|
293
|
-
this.router.navigateByUrl(propValue);
|
|
294
|
-
event.preventDefault();
|
|
295
|
-
});
|
|
296
|
-
}
|
|
297
|
-
});
|
|
298
|
-
if (node.childNodes && node.childNodes.length === 0 && linkText) {
|
|
299
|
-
node.textContent = linkText;
|
|
300
|
-
}
|
|
301
|
-
});
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
RouterLinkDirective.decorators = [
|
|
305
|
-
{ type: Directive, args: [{ selector: '[scRouterLink]' },] }
|
|
306
|
-
];
|
|
307
|
-
RouterLinkDirective.ctorParameters = () => [
|
|
308
|
-
{ type: ViewContainerRef },
|
|
309
|
-
{ type: TemplateRef },
|
|
310
|
-
{ type: Renderer2 },
|
|
311
|
-
{ type: ElementRef },
|
|
312
|
-
{ type: Router }
|
|
313
|
-
];
|
|
314
|
-
RouterLinkDirective.propDecorators = {
|
|
315
|
-
editable: [{ type: Input, args: ['scRouterLinkEditable',] }],
|
|
316
|
-
attrs: [{ type: Input, args: ['scRouterLinkAttrs',] }],
|
|
317
|
-
field: [{ type: Input, args: ['scRouterLink',] }]
|
|
280
|
+
class RouterLinkDirective extends LinkDirective {
|
|
281
|
+
constructor(viewContainer, templateRef, renderer, elementRef, router) {
|
|
282
|
+
super(viewContainer, templateRef, renderer, elementRef);
|
|
283
|
+
this.router = router;
|
|
284
|
+
this.editable = true;
|
|
285
|
+
this.attrs = {};
|
|
286
|
+
}
|
|
287
|
+
renderTemplate(props, linkText) {
|
|
288
|
+
const viewRef = this.viewContainer.createEmbeddedView(this.templateRef);
|
|
289
|
+
viewRef.rootNodes.forEach((node) => {
|
|
290
|
+
Object.entries(props).forEach(([key, propValue]) => {
|
|
291
|
+
this.renderer.setAttribute(node, key, propValue);
|
|
292
|
+
if (key === 'href') {
|
|
293
|
+
this.renderer.listen(node, 'click', (event) => {
|
|
294
|
+
this.router.navigateByUrl(propValue);
|
|
295
|
+
event.preventDefault();
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
});
|
|
299
|
+
if (node.childNodes && node.childNodes.length === 0 && linkText) {
|
|
300
|
+
node.textContent = linkText;
|
|
301
|
+
}
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
RouterLinkDirective.decorators = [
|
|
306
|
+
{ type: Directive, args: [{ selector: '[scRouterLink]' },] }
|
|
307
|
+
];
|
|
308
|
+
RouterLinkDirective.ctorParameters = () => [
|
|
309
|
+
{ type: ViewContainerRef },
|
|
310
|
+
{ type: TemplateRef },
|
|
311
|
+
{ type: Renderer2 },
|
|
312
|
+
{ type: ElementRef },
|
|
313
|
+
{ type: Router }
|
|
314
|
+
];
|
|
315
|
+
RouterLinkDirective.propDecorators = {
|
|
316
|
+
editable: [{ type: Input, args: ['scRouterLinkEditable',] }],
|
|
317
|
+
attrs: [{ type: Input, args: ['scRouterLinkAttrs',] }],
|
|
318
|
+
field: [{ type: Input, args: ['scRouterLink',] }]
|
|
318
319
|
};
|
|
319
320
|
|
|
320
|
-
class GenericLinkDirective extends LinkDirective {
|
|
321
|
-
constructor(viewContainer, templateRef, renderer, elementRef, router) {
|
|
322
|
-
super(viewContainer, templateRef, renderer, elementRef);
|
|
323
|
-
this.router = router;
|
|
324
|
-
this.editable = true;
|
|
325
|
-
this.attrs = {};
|
|
326
|
-
}
|
|
327
|
-
renderTemplate(props, linkText) {
|
|
328
|
-
const viewRef = this.viewContainer.createEmbeddedView(this.templateRef);
|
|
329
|
-
viewRef.rootNodes.forEach((node) => {
|
|
330
|
-
Object.entries(props).forEach(([key, propValue]) => {
|
|
331
|
-
if (key === 'href' && !this.isAbsoluteUrl(propValue)) {
|
|
332
|
-
const urlTree = this.router.createUrlTree([propValue], this.extras);
|
|
333
|
-
this.renderer.setAttribute(node, key, this.router.serializeUrl(urlTree));
|
|
334
|
-
this.renderer.listen(node, 'click', (event) => {
|
|
335
|
-
this.router.navigate([propValue], this.extras);
|
|
336
|
-
event.preventDefault();
|
|
337
|
-
});
|
|
338
|
-
}
|
|
339
|
-
else {
|
|
340
|
-
this.renderer.setAttribute(node, key, propValue);
|
|
341
|
-
}
|
|
342
|
-
});
|
|
343
|
-
if (node.childNodes && node.childNodes.length === 0 && linkText) {
|
|
344
|
-
node.textContent = linkText;
|
|
345
|
-
}
|
|
346
|
-
});
|
|
347
|
-
}
|
|
348
|
-
isAbsoluteUrl(url) {
|
|
349
|
-
if (url === null) {
|
|
350
|
-
return false;
|
|
351
|
-
}
|
|
352
|
-
if (typeof url !== 'string') {
|
|
353
|
-
throw new TypeError('Expected a string');
|
|
354
|
-
}
|
|
355
|
-
return /^[a-z][a-z0-9+.-]*:/.test(url);
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
GenericLinkDirective.decorators = [
|
|
359
|
-
{ type: Directive, args: [{ selector: '[scGenericLink]' },] }
|
|
360
|
-
];
|
|
361
|
-
GenericLinkDirective.ctorParameters = () => [
|
|
362
|
-
{ type: ViewContainerRef },
|
|
363
|
-
{ type: TemplateRef },
|
|
364
|
-
{ type: Renderer2 },
|
|
365
|
-
{ type: ElementRef },
|
|
366
|
-
{ type: Router }
|
|
367
|
-
];
|
|
368
|
-
GenericLinkDirective.propDecorators = {
|
|
369
|
-
editable: [{ type: Input, args: ['scGenericLinkEditable',] }],
|
|
370
|
-
attrs: [{ type: Input, args: ['scGenericLinkAttrs',] }],
|
|
371
|
-
field: [{ type: Input, args: ['scGenericLink',] }],
|
|
372
|
-
extras: [{ type: Input, args: ['scGenericLinkExtras',] }]
|
|
321
|
+
class GenericLinkDirective extends LinkDirective {
|
|
322
|
+
constructor(viewContainer, templateRef, renderer, elementRef, router) {
|
|
323
|
+
super(viewContainer, templateRef, renderer, elementRef);
|
|
324
|
+
this.router = router;
|
|
325
|
+
this.editable = true;
|
|
326
|
+
this.attrs = {};
|
|
327
|
+
}
|
|
328
|
+
renderTemplate(props, linkText) {
|
|
329
|
+
const viewRef = this.viewContainer.createEmbeddedView(this.templateRef);
|
|
330
|
+
viewRef.rootNodes.forEach((node) => {
|
|
331
|
+
Object.entries(props).forEach(([key, propValue]) => {
|
|
332
|
+
if (key === 'href' && !this.isAbsoluteUrl(propValue)) {
|
|
333
|
+
const urlTree = this.router.createUrlTree([propValue], this.extras);
|
|
334
|
+
this.renderer.setAttribute(node, key, this.router.serializeUrl(urlTree));
|
|
335
|
+
this.renderer.listen(node, 'click', (event) => {
|
|
336
|
+
this.router.navigate([propValue], this.extras);
|
|
337
|
+
event.preventDefault();
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
else {
|
|
341
|
+
this.renderer.setAttribute(node, key, propValue);
|
|
342
|
+
}
|
|
343
|
+
});
|
|
344
|
+
if (node.childNodes && node.childNodes.length === 0 && linkText) {
|
|
345
|
+
node.textContent = linkText;
|
|
346
|
+
}
|
|
347
|
+
});
|
|
348
|
+
}
|
|
349
|
+
isAbsoluteUrl(url) {
|
|
350
|
+
if (url === null) {
|
|
351
|
+
return false;
|
|
352
|
+
}
|
|
353
|
+
if (typeof url !== 'string') {
|
|
354
|
+
throw new TypeError('Expected a string');
|
|
355
|
+
}
|
|
356
|
+
return /^[a-z][a-z0-9+.-]*:/.test(url);
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
GenericLinkDirective.decorators = [
|
|
360
|
+
{ type: Directive, args: [{ selector: '[scGenericLink]' },] }
|
|
361
|
+
];
|
|
362
|
+
GenericLinkDirective.ctorParameters = () => [
|
|
363
|
+
{ type: ViewContainerRef },
|
|
364
|
+
{ type: TemplateRef },
|
|
365
|
+
{ type: Renderer2 },
|
|
366
|
+
{ type: ElementRef },
|
|
367
|
+
{ type: Router }
|
|
368
|
+
];
|
|
369
|
+
GenericLinkDirective.propDecorators = {
|
|
370
|
+
editable: [{ type: Input, args: ['scGenericLinkEditable',] }],
|
|
371
|
+
attrs: [{ type: Input, args: ['scGenericLinkAttrs',] }],
|
|
372
|
+
field: [{ type: Input, args: ['scGenericLink',] }],
|
|
373
|
+
extras: [{ type: Input, args: ['scGenericLinkExtras',] }]
|
|
373
374
|
};
|
|
374
375
|
|
|
375
|
-
/** Registers a statically loaded component */
|
|
376
|
-
class ComponentNameAndType {
|
|
377
|
-
}
|
|
378
|
-
/**
|
|
379
|
-
* @param {unknown} object
|
|
380
|
-
*/
|
|
381
|
-
function instanceOfComponentNameAndType(object) {
|
|
382
|
-
return typeof object === 'object' && object !== null && 'type' in object;
|
|
383
|
-
}
|
|
384
|
-
/**
|
|
385
|
-
* @param {unknown} object
|
|
386
|
-
*/
|
|
387
|
-
function instanceOfComponentNameAndModule(object) {
|
|
388
|
-
return typeof object === 'object' && object !== null && 'module' in object;
|
|
389
|
-
}
|
|
390
|
-
const PLACEHOLDER_COMPONENTS = new InjectionToken('Sc.placeholder.components');
|
|
391
|
-
const PLACEHOLDER_LAZY_COMPONENTS = new InjectionToken('Sc.placeholder.lazyComponents');
|
|
392
|
-
const PLACEHOLDER_MISSING_COMPONENT_COMPONENT = new InjectionToken('Sc.placeholder.missingComponentComponent');
|
|
393
|
-
const PLACEHOLDER_HIDDEN_RENDERING_COMPONENT = new InjectionToken('Sc.placeholder.hiddenRenderingComponent');
|
|
376
|
+
/** Registers a statically loaded component */
|
|
377
|
+
class ComponentNameAndType {
|
|
378
|
+
}
|
|
379
|
+
/**
|
|
380
|
+
* @param {unknown} object
|
|
381
|
+
*/
|
|
382
|
+
function instanceOfComponentNameAndType(object) {
|
|
383
|
+
return typeof object === 'object' && object !== null && 'type' in object;
|
|
384
|
+
}
|
|
385
|
+
/**
|
|
386
|
+
* @param {unknown} object
|
|
387
|
+
*/
|
|
388
|
+
function instanceOfComponentNameAndModule(object) {
|
|
389
|
+
return typeof object === 'object' && object !== null && 'module' in object;
|
|
390
|
+
}
|
|
391
|
+
const PLACEHOLDER_COMPONENTS = new InjectionToken('Sc.placeholder.components');
|
|
392
|
+
const PLACEHOLDER_LAZY_COMPONENTS = new InjectionToken('Sc.placeholder.lazyComponents');
|
|
393
|
+
const PLACEHOLDER_MISSING_COMPONENT_COMPONENT = new InjectionToken('Sc.placeholder.missingComponentComponent');
|
|
394
|
+
const PLACEHOLDER_HIDDEN_RENDERING_COMPONENT = new InjectionToken('Sc.placeholder.hiddenRenderingComponent');
|
|
394
395
|
const DYNAMIC_COMPONENT = new InjectionToken('Sc.placeholder.dynamicComponent');
|
|
395
396
|
|
|
396
|
-
class RawComponent {
|
|
397
|
-
constructor(renderer, elementRef) {
|
|
398
|
-
this.renderer = renderer;
|
|
399
|
-
this.elementRef = elementRef;
|
|
400
|
-
}
|
|
401
|
-
ngOnInit() {
|
|
402
|
-
const el = this.renderer.createElement(this.rendering.name);
|
|
403
|
-
const contents = this.renderer.createText(this.rendering.contents || '');
|
|
404
|
-
const attributes = this.rendering.attributes;
|
|
405
|
-
for (const attr in attributes) {
|
|
406
|
-
// eslint-disable-next-line no-prototype-builtins
|
|
407
|
-
if (attributes.hasOwnProperty(attr)) {
|
|
408
|
-
const value = attributes[attr];
|
|
409
|
-
this.renderer.setAttribute(el, attr, value || '');
|
|
410
|
-
}
|
|
411
|
-
}
|
|
412
|
-
this.renderer.appendChild(el, contents);
|
|
413
|
-
const parentNode = this.renderer.parentNode(this.elementRef.nativeElement);
|
|
414
|
-
this.renderer.insertBefore(parentNode, el, this.elementRef.nativeElement);
|
|
415
|
-
parentNode.removeChild(this.elementRef.nativeElement);
|
|
416
|
-
}
|
|
417
|
-
}
|
|
418
|
-
RawComponent.decorators = [
|
|
419
|
-
{ type: Component, args: [{
|
|
420
|
-
selector: 'sc-raw',
|
|
421
|
-
template: ''
|
|
422
|
-
},] }
|
|
423
|
-
];
|
|
424
|
-
RawComponent.ctorParameters = () => [
|
|
425
|
-
{ type: Renderer2 },
|
|
426
|
-
{ type: ElementRef }
|
|
427
|
-
];
|
|
428
|
-
RawComponent.propDecorators = {
|
|
429
|
-
rendering: [{ type: Input }]
|
|
397
|
+
class RawComponent {
|
|
398
|
+
constructor(renderer, elementRef) {
|
|
399
|
+
this.renderer = renderer;
|
|
400
|
+
this.elementRef = elementRef;
|
|
401
|
+
}
|
|
402
|
+
ngOnInit() {
|
|
403
|
+
const el = this.renderer.createElement(this.rendering.name);
|
|
404
|
+
const contents = this.renderer.createText(this.rendering.contents || '');
|
|
405
|
+
const attributes = this.rendering.attributes;
|
|
406
|
+
for (const attr in attributes) {
|
|
407
|
+
// eslint-disable-next-line no-prototype-builtins
|
|
408
|
+
if (attributes.hasOwnProperty(attr)) {
|
|
409
|
+
const value = attributes[attr];
|
|
410
|
+
this.renderer.setAttribute(el, attr, value || '');
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
this.renderer.appendChild(el, contents);
|
|
414
|
+
const parentNode = this.renderer.parentNode(this.elementRef.nativeElement);
|
|
415
|
+
this.renderer.insertBefore(parentNode, el, this.elementRef.nativeElement);
|
|
416
|
+
parentNode.removeChild(this.elementRef.nativeElement);
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
RawComponent.decorators = [
|
|
420
|
+
{ type: Component, args: [{
|
|
421
|
+
selector: 'sc-raw',
|
|
422
|
+
template: ''
|
|
423
|
+
},] }
|
|
424
|
+
];
|
|
425
|
+
RawComponent.ctorParameters = () => [
|
|
426
|
+
{ type: Renderer2 },
|
|
427
|
+
{ type: ElementRef }
|
|
428
|
+
];
|
|
429
|
+
RawComponent.propDecorators = {
|
|
430
|
+
rendering: [{ type: Input }]
|
|
430
431
|
};
|
|
431
432
|
|
|
432
|
-
/**
|
|
433
|
-
* @param {HtmlElementRendering | ComponentRendering} rendering
|
|
434
|
-
*/
|
|
435
|
-
function isRawRendering(rendering) {
|
|
436
|
-
return (!rendering.componentName &&
|
|
437
|
-
rendering.name !== undefined);
|
|
433
|
+
/**
|
|
434
|
+
* @param {HtmlElementRendering | ComponentRendering} rendering
|
|
435
|
+
*/
|
|
436
|
+
function isRawRendering(rendering) {
|
|
437
|
+
return (!rendering.componentName &&
|
|
438
|
+
rendering.name !== undefined);
|
|
438
439
|
}
|
|
439
440
|
|
|
440
|
-
class JssComponentFactoryService {
|
|
441
|
-
constructor(injector, compiler, components, lazyComponents) {
|
|
442
|
-
this.injector = injector;
|
|
443
|
-
this.compiler = compiler;
|
|
444
|
-
this.components = components;
|
|
445
|
-
this.lazyComponents = lazyComponents;
|
|
446
|
-
this.componentMap = new Map();
|
|
447
|
-
this.lazyComponentMap = new Map();
|
|
448
|
-
this.components.forEach((c) => this.componentMap.set(c.name, c.type));
|
|
449
|
-
if (this.lazyComponents) {
|
|
450
|
-
this.lazyComponents.forEach((c) => this.lazyComponentMap.set(c.path, c));
|
|
451
|
-
}
|
|
452
|
-
}
|
|
453
|
-
loadModuleFactory(lazyComponent) {
|
|
454
|
-
return lazyComponent.loadChildren().then((loaded) => {
|
|
455
|
-
if (loaded instanceof NgModuleFactory) {
|
|
456
|
-
return loaded;
|
|
457
|
-
}
|
|
458
|
-
else {
|
|
459
|
-
return this.compiler.compileModuleAsync(loaded);
|
|
460
|
-
}
|
|
461
|
-
});
|
|
462
|
-
}
|
|
463
|
-
getComponent(component) {
|
|
464
|
-
const loadedComponent = this.componentMap.get(component.componentName);
|
|
465
|
-
if (loadedComponent) {
|
|
466
|
-
return Promise.resolve({
|
|
467
|
-
componentDefinition: component,
|
|
468
|
-
componentImplementation: this.componentMap.get(component.componentName),
|
|
469
|
-
});
|
|
470
|
-
}
|
|
471
|
-
const lazyComponent = this.lazyComponentMap.get(component.componentName);
|
|
472
|
-
if (lazyComponent) {
|
|
473
|
-
return this.loadModuleFactory(lazyComponent).then((ngModuleFactory) => {
|
|
474
|
-
let componentType = null;
|
|
475
|
-
const moduleRef = ngModuleFactory.create(this.injector);
|
|
476
|
-
const dynamicComponentType = moduleRef.injector.get(DYNAMIC_COMPONENT);
|
|
477
|
-
if (!dynamicComponentType) {
|
|
478
|
-
throw new Error(`JssComponentFactoryService: Lazy load module for component "${lazyComponent.path}" missing DYNAMIC_COMPONENT provider. Missing JssModule.forChild()?`);
|
|
479
|
-
}
|
|
480
|
-
if (component.componentName in dynamicComponentType) {
|
|
481
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
482
|
-
componentType = dynamicComponentType[component.componentName];
|
|
483
|
-
}
|
|
484
|
-
else {
|
|
485
|
-
if (typeof dynamicComponentType === 'function') {
|
|
486
|
-
componentType = dynamicComponentType;
|
|
487
|
-
}
|
|
488
|
-
else {
|
|
489
|
-
throw new Error(`JssComponentFactoryService: Lazy load module for component "${lazyComponent.path}" missing DYNAMIC_COMPONENT provider. Missing JssModule.forChild()?`);
|
|
490
|
-
}
|
|
491
|
-
}
|
|
492
|
-
return {
|
|
493
|
-
componentDefinition: component,
|
|
494
|
-
componentImplementation: componentType,
|
|
495
|
-
componentFactory: moduleRef.componentFactoryResolver.resolveComponentFactory(componentType),
|
|
496
|
-
};
|
|
497
|
-
});
|
|
498
|
-
}
|
|
499
|
-
return Promise.resolve({
|
|
500
|
-
componentDefinition: component,
|
|
501
|
-
});
|
|
502
|
-
}
|
|
503
|
-
getComponents(components) {
|
|
504
|
-
// acquire all components and keep them in order while handling their potential async-ness
|
|
505
|
-
return Promise.all(components.map((component) => isRawRendering(component) ? this.getRawComponent(component) : this.getComponent(component)));
|
|
506
|
-
}
|
|
507
|
-
getRawComponent(component) {
|
|
508
|
-
return Promise.resolve({
|
|
509
|
-
componentImplementation: RawComponent,
|
|
510
|
-
componentDefinition: component,
|
|
511
|
-
});
|
|
512
|
-
}
|
|
513
|
-
}
|
|
514
|
-
JssComponentFactoryService.decorators = [
|
|
515
|
-
{ type: Injectable }
|
|
516
|
-
];
|
|
517
|
-
JssComponentFactoryService.ctorParameters = () => [
|
|
518
|
-
{ type: Injector },
|
|
519
|
-
{ type: Compiler },
|
|
520
|
-
{ type: Array, decorators: [{ type: Inject, args: [PLACEHOLDER_COMPONENTS,] }] },
|
|
521
|
-
{ type: Array, decorators: [{ type: Inject, args: [PLACEHOLDER_LAZY_COMPONENTS,] }] }
|
|
441
|
+
class JssComponentFactoryService {
|
|
442
|
+
constructor(injector, compiler, components, lazyComponents) {
|
|
443
|
+
this.injector = injector;
|
|
444
|
+
this.compiler = compiler;
|
|
445
|
+
this.components = components;
|
|
446
|
+
this.lazyComponents = lazyComponents;
|
|
447
|
+
this.componentMap = new Map();
|
|
448
|
+
this.lazyComponentMap = new Map();
|
|
449
|
+
this.components.forEach((c) => this.componentMap.set(c.name, c.type));
|
|
450
|
+
if (this.lazyComponents) {
|
|
451
|
+
this.lazyComponents.forEach((c) => this.lazyComponentMap.set(c.path, c));
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
loadModuleFactory(lazyComponent) {
|
|
455
|
+
return lazyComponent.loadChildren().then((loaded) => {
|
|
456
|
+
if (loaded instanceof NgModuleFactory) {
|
|
457
|
+
return loaded;
|
|
458
|
+
}
|
|
459
|
+
else {
|
|
460
|
+
return this.compiler.compileModuleAsync(loaded);
|
|
461
|
+
}
|
|
462
|
+
});
|
|
463
|
+
}
|
|
464
|
+
getComponent(component) {
|
|
465
|
+
const loadedComponent = this.componentMap.get(component.componentName);
|
|
466
|
+
if (loadedComponent) {
|
|
467
|
+
return Promise.resolve({
|
|
468
|
+
componentDefinition: component,
|
|
469
|
+
componentImplementation: this.componentMap.get(component.componentName),
|
|
470
|
+
});
|
|
471
|
+
}
|
|
472
|
+
const lazyComponent = this.lazyComponentMap.get(component.componentName);
|
|
473
|
+
if (lazyComponent) {
|
|
474
|
+
return this.loadModuleFactory(lazyComponent).then((ngModuleFactory) => {
|
|
475
|
+
let componentType = null;
|
|
476
|
+
const moduleRef = ngModuleFactory.create(this.injector);
|
|
477
|
+
const dynamicComponentType = moduleRef.injector.get(DYNAMIC_COMPONENT);
|
|
478
|
+
if (!dynamicComponentType) {
|
|
479
|
+
throw new Error(`JssComponentFactoryService: Lazy load module for component "${lazyComponent.path}" missing DYNAMIC_COMPONENT provider. Missing JssModule.forChild()?`);
|
|
480
|
+
}
|
|
481
|
+
if (component.componentName in dynamicComponentType) {
|
|
482
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
483
|
+
componentType = dynamicComponentType[component.componentName];
|
|
484
|
+
}
|
|
485
|
+
else {
|
|
486
|
+
if (typeof dynamicComponentType === 'function') {
|
|
487
|
+
componentType = dynamicComponentType;
|
|
488
|
+
}
|
|
489
|
+
else {
|
|
490
|
+
throw new Error(`JssComponentFactoryService: Lazy load module for component "${lazyComponent.path}" missing DYNAMIC_COMPONENT provider. Missing JssModule.forChild()?`);
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
return {
|
|
494
|
+
componentDefinition: component,
|
|
495
|
+
componentImplementation: componentType,
|
|
496
|
+
componentFactory: moduleRef.componentFactoryResolver.resolveComponentFactory(componentType),
|
|
497
|
+
};
|
|
498
|
+
});
|
|
499
|
+
}
|
|
500
|
+
return Promise.resolve({
|
|
501
|
+
componentDefinition: component,
|
|
502
|
+
});
|
|
503
|
+
}
|
|
504
|
+
getComponents(components) {
|
|
505
|
+
// acquire all components and keep them in order while handling their potential async-ness
|
|
506
|
+
return Promise.all(components.map((component) => isRawRendering(component) ? this.getRawComponent(component) : this.getComponent(component)));
|
|
507
|
+
}
|
|
508
|
+
getRawComponent(component) {
|
|
509
|
+
return Promise.resolve({
|
|
510
|
+
componentImplementation: RawComponent,
|
|
511
|
+
componentDefinition: component,
|
|
512
|
+
});
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
JssComponentFactoryService.decorators = [
|
|
516
|
+
{ type: Injectable }
|
|
517
|
+
];
|
|
518
|
+
JssComponentFactoryService.ctorParameters = () => [
|
|
519
|
+
{ type: Injector },
|
|
520
|
+
{ type: Compiler },
|
|
521
|
+
{ type: Array, decorators: [{ type: Inject, args: [PLACEHOLDER_COMPONENTS,] }] },
|
|
522
|
+
{ type: Array, decorators: [{ type: Inject, args: [PLACEHOLDER_LAZY_COMPONENTS,] }] }
|
|
522
523
|
];
|
|
523
524
|
|
|
524
|
-
class HiddenRenderingComponent {
|
|
525
|
-
get style() {
|
|
526
|
-
return 'display: block; height: 100px; background-image: linear-gradient(45deg, #ffffff 25%, #dcdcdc 25%, #dcdcdc 50%, #ffffff 50%, #ffffff 75%, #dcdcdc 75%, #dcdcdc 100%); background-size: 3px 3px;';
|
|
527
|
-
}
|
|
528
|
-
}
|
|
529
|
-
HiddenRenderingComponent.decorators = [
|
|
530
|
-
{ type: Component, args: [{
|
|
531
|
-
selector: 'sc-hidden-rendering',
|
|
532
|
-
template: ''
|
|
533
|
-
},] }
|
|
534
|
-
];
|
|
535
|
-
HiddenRenderingComponent.propDecorators = {
|
|
536
|
-
style: [{ type: HostBinding, args: ['style',] }]
|
|
537
|
-
};
|
|
525
|
+
class HiddenRenderingComponent {
|
|
526
|
+
get style() {
|
|
527
|
+
return 'display: block; height: 100px; background-image: linear-gradient(45deg, #ffffff 25%, #dcdcdc 25%, #dcdcdc 50%, #ffffff 50%, #ffffff 75%, #dcdcdc 75%, #dcdcdc 100%); background-size: 3px 3px;';
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
HiddenRenderingComponent.decorators = [
|
|
531
|
+
{ type: Component, args: [{
|
|
532
|
+
selector: 'sc-hidden-rendering',
|
|
533
|
+
template: ''
|
|
534
|
+
},] }
|
|
535
|
+
];
|
|
536
|
+
HiddenRenderingComponent.propDecorators = {
|
|
537
|
+
style: [{ type: HostBinding, args: ['style',] }]
|
|
538
|
+
};
|
|
538
539
|
const HIDDEN_RENDERING_NAME = 'Hidden Rendering';
|
|
539
540
|
|
|
540
|
-
class PlaceholderLoadingDirective {
|
|
541
|
-
constructor(templateRef) {
|
|
542
|
-
this.templateRef = templateRef;
|
|
543
|
-
}
|
|
544
|
-
}
|
|
545
|
-
PlaceholderLoadingDirective.decorators = [
|
|
546
|
-
{ type: Directive, args: [{
|
|
547
|
-
selector: '[scPlaceholderLoading]',
|
|
548
|
-
},] }
|
|
549
|
-
];
|
|
550
|
-
PlaceholderLoadingDirective.ctorParameters = () => [
|
|
551
|
-
{ type: TemplateRef }
|
|
541
|
+
class PlaceholderLoadingDirective {
|
|
542
|
+
constructor(templateRef) {
|
|
543
|
+
this.templateRef = templateRef;
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
PlaceholderLoadingDirective.decorators = [
|
|
547
|
+
{ type: Directive, args: [{
|
|
548
|
+
selector: '[scPlaceholderLoading]',
|
|
549
|
+
},] }
|
|
550
|
+
];
|
|
551
|
+
PlaceholderLoadingDirective.ctorParameters = () => [
|
|
552
|
+
{ type: TemplateRef }
|
|
552
553
|
];
|
|
553
554
|
|
|
554
|
-
class RenderEachDirective {
|
|
555
|
-
constructor(templateRef) {
|
|
556
|
-
this.templateRef = templateRef;
|
|
557
|
-
}
|
|
558
|
-
}
|
|
559
|
-
RenderEachDirective.decorators = [
|
|
560
|
-
{ type: Directive, args: [{
|
|
561
|
-
selector: '[renderEach]',
|
|
562
|
-
},] }
|
|
563
|
-
];
|
|
564
|
-
RenderEachDirective.ctorParameters = () => [
|
|
565
|
-
{ type: TemplateRef }
|
|
555
|
+
class RenderEachDirective {
|
|
556
|
+
constructor(templateRef) {
|
|
557
|
+
this.templateRef = templateRef;
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
RenderEachDirective.decorators = [
|
|
561
|
+
{ type: Directive, args: [{
|
|
562
|
+
selector: '[renderEach]',
|
|
563
|
+
},] }
|
|
564
|
+
];
|
|
565
|
+
RenderEachDirective.ctorParameters = () => [
|
|
566
|
+
{ type: TemplateRef }
|
|
566
567
|
];
|
|
567
568
|
|
|
568
|
-
class RenderEmptyDirective {
|
|
569
|
-
constructor(templateRef) {
|
|
570
|
-
this.templateRef = templateRef;
|
|
571
|
-
}
|
|
572
|
-
}
|
|
573
|
-
RenderEmptyDirective.decorators = [
|
|
574
|
-
{ type: Directive, args: [{
|
|
575
|
-
selector: '[renderEmpty]',
|
|
576
|
-
},] }
|
|
577
|
-
];
|
|
578
|
-
RenderEmptyDirective.ctorParameters = () => [
|
|
579
|
-
{ type: TemplateRef }
|
|
569
|
+
class RenderEmptyDirective {
|
|
570
|
+
constructor(templateRef) {
|
|
571
|
+
this.templateRef = templateRef;
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
RenderEmptyDirective.decorators = [
|
|
575
|
+
{ type: Directive, args: [{
|
|
576
|
+
selector: '[renderEmpty]',
|
|
577
|
+
},] }
|
|
578
|
+
];
|
|
579
|
+
RenderEmptyDirective.ctorParameters = () => [
|
|
580
|
+
{ type: TemplateRef }
|
|
580
581
|
];
|
|
581
582
|
|
|
582
|
-
/* eslint-disable @angular-eslint/no-conflicting-lifecycle */
|
|
583
|
-
/**
|
|
584
|
-
* @param {ComponentRendering} rendering
|
|
585
|
-
* @param {string} name
|
|
586
|
-
*/
|
|
587
|
-
function getPlaceholder(rendering, name) {
|
|
588
|
-
if (rendering && rendering.placeholders && Object.keys(rendering.placeholders).length > 0) {
|
|
589
|
-
return rendering.placeholders[name];
|
|
590
|
-
}
|
|
591
|
-
return null;
|
|
592
|
-
}
|
|
593
|
-
class PlaceholderComponent {
|
|
594
|
-
constructor(componentFactoryResolver, differs, componentFactory, changeDetectorRef, elementRef, renderer, missingComponentComponent, hiddenRenderingComponent) {
|
|
595
|
-
this.componentFactoryResolver = componentFactoryResolver;
|
|
596
|
-
this.differs = differs;
|
|
597
|
-
this.componentFactory = componentFactory;
|
|
598
|
-
this.changeDetectorRef = changeDetectorRef;
|
|
599
|
-
this.elementRef = elementRef;
|
|
600
|
-
this.renderer = renderer;
|
|
601
|
-
this.missingComponentComponent = missingComponentComponent;
|
|
602
|
-
this.hiddenRenderingComponent = hiddenRenderingComponent;
|
|
603
|
-
this._componentInstances = [];
|
|
604
|
-
this.destroyed = false;
|
|
605
|
-
this.parentStyleAttribute = '';
|
|
606
|
-
this.isLoading = true;
|
|
607
|
-
this.loaded = new EventEmitter();
|
|
608
|
-
}
|
|
609
|
-
set inputs(value) {
|
|
610
|
-
this._inputs = value;
|
|
611
|
-
if (!this._differ && value) {
|
|
612
|
-
this._differ = this.differs.find(value).create();
|
|
613
|
-
}
|
|
614
|
-
}
|
|
615
|
-
ngOnInit() {
|
|
616
|
-
// just to ensure the element exists
|
|
617
|
-
const elem = this.elementRef.nativeElement;
|
|
618
|
-
if (elem) {
|
|
619
|
-
const attributes = elem.attributes;
|
|
620
|
-
for (let i = 0; i < attributes.length; i++) {
|
|
621
|
-
const attr = attributes.item(i);
|
|
622
|
-
if (attr && attr.name.indexOf('_ngcontent') !== -1) {
|
|
623
|
-
this.parentStyleAttribute = attr.name;
|
|
624
|
-
}
|
|
625
|
-
}
|
|
626
|
-
}
|
|
627
|
-
}
|
|
628
|
-
ngOnDestroy() {
|
|
629
|
-
this.destroyed = true;
|
|
630
|
-
this._componentInstances = [];
|
|
631
|
-
}
|
|
632
|
-
ngOnChanges(changes) {
|
|
633
|
-
if (changes.rendering || changes.renderings) {
|
|
634
|
-
this._render();
|
|
635
|
-
}
|
|
636
|
-
}
|
|
637
|
-
ngDoCheck() {
|
|
638
|
-
if (!this._differ || !this._inputs || this._componentInstances.length === 0) {
|
|
639
|
-
return;
|
|
640
|
-
}
|
|
641
|
-
const changes = this._differ.diff(this._inputs);
|
|
642
|
-
if (!changes) {
|
|
643
|
-
return;
|
|
644
|
-
}
|
|
645
|
-
const updates = {};
|
|
646
|
-
changes.forEachRemovedItem((change) => (updates[change.key] = null));
|
|
647
|
-
changes.forEachAddedItem((change) => (updates[change.key] = change.currentValue));
|
|
648
|
-
changes.forEachChangedItem((change) => (updates[change.key] = change.currentValue));
|
|
649
|
-
this._componentInstances.forEach((componentInstance) => this._setComponentInputs(componentInstance, updates));
|
|
650
|
-
}
|
|
651
|
-
_setComponentInputs(componentInstance, inputs) {
|
|
652
|
-
Object.entries(inputs).forEach(([input, inputValue]) => (componentInstance[input] = inputValue));
|
|
653
|
-
}
|
|
654
|
-
_subscribeComponentOutputs(componentInstance, outputs) {
|
|
655
|
-
Object.keys(outputs)
|
|
656
|
-
.filter((output) => componentInstance[output] && componentInstance[output] instanceof Observable)
|
|
657
|
-
.forEach((output) => componentInstance[output]
|
|
658
|
-
.pipe(takeWhile(() => !this.destroyed))
|
|
659
|
-
.subscribe(outputs[output]));
|
|
660
|
-
}
|
|
661
|
-
_render() {
|
|
662
|
-
this._componentInstances = [];
|
|
663
|
-
this.view.clear();
|
|
664
|
-
if (!this.rendering && !this.renderings) {
|
|
665
|
-
return;
|
|
666
|
-
}
|
|
667
|
-
if (!this.name && !this.renderings) {
|
|
668
|
-
console.warn('Placeholder name was not specified, and explicit renderings array was not passed. Placeholder requires either name and rendering, or renderings.');
|
|
669
|
-
this.isLoading = false;
|
|
670
|
-
return;
|
|
671
|
-
}
|
|
672
|
-
const placeholder = this.renderings || getPlaceholder(this.rendering, this.name || '');
|
|
673
|
-
if (!placeholder) {
|
|
674
|
-
console.warn(`Placeholder '${this.name}' was not found in the current rendering data`, JSON.stringify(this.rendering, null, 2));
|
|
675
|
-
this.isLoading = false;
|
|
676
|
-
return;
|
|
677
|
-
}
|
|
678
|
-
// if the placeholder is empty (contains only raw renderings), then we may need to use the empty template if it's defined
|
|
679
|
-
const placeholderIsEmpty = placeholder.every((rendering) => isRawRendering(rendering));
|
|
680
|
-
if (this.renderEmptyTemplate && placeholderIsEmpty) {
|
|
681
|
-
this.view.createEmbeddedView(this.renderEmptyTemplate.templateRef, {
|
|
682
|
-
renderings: placeholder,
|
|
683
|
-
});
|
|
684
|
-
this.isLoading = false;
|
|
685
|
-
}
|
|
686
|
-
else {
|
|
687
|
-
this.componentFactory
|
|
688
|
-
.getComponents(placeholder)
|
|
689
|
-
.then((components) => components.forEach((rendering, index) => {
|
|
690
|
-
if (this.renderEachTemplate && !isRawRendering(rendering.componentDefinition)) {
|
|
691
|
-
this._renderTemplatedComponent(rendering.componentDefinition, index);
|
|
692
|
-
}
|
|
693
|
-
else {
|
|
694
|
-
this._renderEmbeddedComponent(rendering, index);
|
|
695
|
-
}
|
|
696
|
-
this.isLoading = false;
|
|
697
|
-
}))
|
|
698
|
-
.then(() => {
|
|
699
|
-
this.changeDetectorRef.markForCheck();
|
|
700
|
-
this.loaded.emit(this.name);
|
|
701
|
-
});
|
|
702
|
-
}
|
|
703
|
-
}
|
|
704
|
-
_renderTemplatedComponent(rendering, index) {
|
|
705
|
-
// the render-each template takes care of all component mapping etc
|
|
706
|
-
// generally using <sc-render-component> which is about like _renderEmbeddedComponent()
|
|
707
|
-
// as a separate component
|
|
708
|
-
this.view.createEmbeddedView(this.renderEachTemplate.templateRef, {
|
|
709
|
-
rendering,
|
|
710
|
-
index,
|
|
711
|
-
});
|
|
712
|
-
}
|
|
713
|
-
_renderEmbeddedComponent(rendering, index) {
|
|
714
|
-
if (rendering.componentDefinition.componentName === HIDDEN_RENDERING_NAME) {
|
|
715
|
-
rendering.componentImplementation = this.hiddenRenderingComponent;
|
|
716
|
-
}
|
|
717
|
-
if (!rendering.componentImplementation) {
|
|
718
|
-
const componentName = rendering.componentDefinition.componentName;
|
|
583
|
+
/* eslint-disable @angular-eslint/no-conflicting-lifecycle */
|
|
584
|
+
/**
|
|
585
|
+
* @param {ComponentRendering} rendering
|
|
586
|
+
* @param {string} name
|
|
587
|
+
*/
|
|
588
|
+
function getPlaceholder(rendering, name) {
|
|
589
|
+
if (rendering && rendering.placeholders && Object.keys(rendering.placeholders).length > 0) {
|
|
590
|
+
return rendering.placeholders[name];
|
|
591
|
+
}
|
|
592
|
+
return null;
|
|
593
|
+
}
|
|
594
|
+
class PlaceholderComponent {
|
|
595
|
+
constructor(componentFactoryResolver, differs, componentFactory, changeDetectorRef, elementRef, renderer, missingComponentComponent, hiddenRenderingComponent) {
|
|
596
|
+
this.componentFactoryResolver = componentFactoryResolver;
|
|
597
|
+
this.differs = differs;
|
|
598
|
+
this.componentFactory = componentFactory;
|
|
599
|
+
this.changeDetectorRef = changeDetectorRef;
|
|
600
|
+
this.elementRef = elementRef;
|
|
601
|
+
this.renderer = renderer;
|
|
602
|
+
this.missingComponentComponent = missingComponentComponent;
|
|
603
|
+
this.hiddenRenderingComponent = hiddenRenderingComponent;
|
|
604
|
+
this._componentInstances = [];
|
|
605
|
+
this.destroyed = false;
|
|
606
|
+
this.parentStyleAttribute = '';
|
|
607
|
+
this.isLoading = true;
|
|
608
|
+
this.loaded = new EventEmitter();
|
|
609
|
+
}
|
|
610
|
+
set inputs(value) {
|
|
611
|
+
this._inputs = value;
|
|
612
|
+
if (!this._differ && value) {
|
|
613
|
+
this._differ = this.differs.find(value).create();
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
ngOnInit() {
|
|
617
|
+
// just to ensure the element exists
|
|
618
|
+
const elem = this.elementRef.nativeElement;
|
|
619
|
+
if (elem) {
|
|
620
|
+
const attributes = elem.attributes;
|
|
621
|
+
for (let i = 0; i < attributes.length; i++) {
|
|
622
|
+
const attr = attributes.item(i);
|
|
623
|
+
if (attr && attr.name.indexOf('_ngcontent') !== -1) {
|
|
624
|
+
this.parentStyleAttribute = attr.name;
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
ngOnDestroy() {
|
|
630
|
+
this.destroyed = true;
|
|
631
|
+
this._componentInstances = [];
|
|
632
|
+
}
|
|
633
|
+
ngOnChanges(changes) {
|
|
634
|
+
if (changes.rendering || changes.renderings) {
|
|
635
|
+
this._render();
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
ngDoCheck() {
|
|
639
|
+
if (!this._differ || !this._inputs || this._componentInstances.length === 0) {
|
|
640
|
+
return;
|
|
641
|
+
}
|
|
642
|
+
const changes = this._differ.diff(this._inputs);
|
|
643
|
+
if (!changes) {
|
|
644
|
+
return;
|
|
645
|
+
}
|
|
646
|
+
const updates = {};
|
|
647
|
+
changes.forEachRemovedItem((change) => (updates[change.key] = null));
|
|
648
|
+
changes.forEachAddedItem((change) => (updates[change.key] = change.currentValue));
|
|
649
|
+
changes.forEachChangedItem((change) => (updates[change.key] = change.currentValue));
|
|
650
|
+
this._componentInstances.forEach((componentInstance) => this._setComponentInputs(componentInstance, updates));
|
|
651
|
+
}
|
|
652
|
+
_setComponentInputs(componentInstance, inputs) {
|
|
653
|
+
Object.entries(inputs).forEach(([input, inputValue]) => (componentInstance[input] = inputValue));
|
|
654
|
+
}
|
|
655
|
+
_subscribeComponentOutputs(componentInstance, outputs) {
|
|
656
|
+
Object.keys(outputs)
|
|
657
|
+
.filter((output) => componentInstance[output] && componentInstance[output] instanceof Observable)
|
|
658
|
+
.forEach((output) => componentInstance[output]
|
|
659
|
+
.pipe(takeWhile(() => !this.destroyed))
|
|
660
|
+
.subscribe(outputs[output]));
|
|
661
|
+
}
|
|
662
|
+
_render() {
|
|
663
|
+
this._componentInstances = [];
|
|
664
|
+
this.view.clear();
|
|
665
|
+
if (!this.rendering && !this.renderings) {
|
|
666
|
+
return;
|
|
667
|
+
}
|
|
668
|
+
if (!this.name && !this.renderings) {
|
|
669
|
+
console.warn('Placeholder name was not specified, and explicit renderings array was not passed. Placeholder requires either name and rendering, or renderings.');
|
|
670
|
+
this.isLoading = false;
|
|
671
|
+
return;
|
|
672
|
+
}
|
|
673
|
+
const placeholder = this.renderings || getPlaceholder(this.rendering, this.name || '');
|
|
674
|
+
if (!placeholder) {
|
|
675
|
+
console.warn(`Placeholder '${this.name}' was not found in the current rendering data`, JSON.stringify(this.rendering, null, 2));
|
|
676
|
+
this.isLoading = false;
|
|
677
|
+
return;
|
|
678
|
+
}
|
|
679
|
+
// if the placeholder is empty (contains only raw renderings), then we may need to use the empty template if it's defined
|
|
680
|
+
const placeholderIsEmpty = placeholder.every((rendering) => isRawRendering(rendering));
|
|
681
|
+
if (this.renderEmptyTemplate && placeholderIsEmpty) {
|
|
682
|
+
this.view.createEmbeddedView(this.renderEmptyTemplate.templateRef, {
|
|
683
|
+
renderings: placeholder,
|
|
684
|
+
});
|
|
685
|
+
this.isLoading = false;
|
|
686
|
+
}
|
|
687
|
+
else {
|
|
688
|
+
this.componentFactory
|
|
689
|
+
.getComponents(placeholder)
|
|
690
|
+
.then((components) => components.forEach((rendering, index) => {
|
|
691
|
+
if (this.renderEachTemplate && !isRawRendering(rendering.componentDefinition)) {
|
|
692
|
+
this._renderTemplatedComponent(rendering.componentDefinition, index);
|
|
693
|
+
}
|
|
694
|
+
else {
|
|
695
|
+
this._renderEmbeddedComponent(rendering, index);
|
|
696
|
+
}
|
|
697
|
+
this.isLoading = false;
|
|
698
|
+
}))
|
|
699
|
+
.then(() => {
|
|
700
|
+
this.changeDetectorRef.markForCheck();
|
|
701
|
+
this.loaded.emit(this.name);
|
|
702
|
+
});
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
_renderTemplatedComponent(rendering, index) {
|
|
706
|
+
// the render-each template takes care of all component mapping etc
|
|
707
|
+
// generally using <sc-render-component> which is about like _renderEmbeddedComponent()
|
|
708
|
+
// as a separate component
|
|
709
|
+
this.view.createEmbeddedView(this.renderEachTemplate.templateRef, {
|
|
710
|
+
rendering,
|
|
711
|
+
index,
|
|
712
|
+
});
|
|
713
|
+
}
|
|
714
|
+
_renderEmbeddedComponent(rendering, index) {
|
|
715
|
+
if (rendering.componentDefinition.componentName === HIDDEN_RENDERING_NAME) {
|
|
716
|
+
rendering.componentImplementation = this.hiddenRenderingComponent;
|
|
717
|
+
}
|
|
718
|
+
if (!rendering.componentImplementation) {
|
|
719
|
+
const componentName = rendering.componentDefinition.componentName;
|
|
719
720
|
console.error(`Placeholder ${this.name} contains unknown component ${componentName}.`, `Ensure component is mapped, like:
|
|
720
721
|
JssModule.withComponents([
|
|
721
722
|
{ name: '${componentName}', type: ${componentName}Component }
|
|
722
|
-
])`);
|
|
723
|
-
rendering.componentImplementation = this.missingComponentComponent;
|
|
724
|
-
}
|
|
725
|
-
const componentFactory = rendering.componentFactory ||
|
|
726
|
-
this.componentFactoryResolver.resolveComponentFactory(rendering.componentImplementation);
|
|
727
|
-
// apply the parent style attribute _ngcontent
|
|
728
|
-
// work-around for https://github.com/angular/angular/issues/12215
|
|
729
|
-
const createdComponentRef = this.view.createComponent(componentFactory, index);
|
|
730
|
-
if (this.parentStyleAttribute) {
|
|
731
|
-
this.renderer.setAttribute(createdComponentRef.location.nativeElement, this.parentStyleAttribute, '');
|
|
732
|
-
}
|
|
733
|
-
const componentInstance = createdComponentRef.instance;
|
|
734
|
-
componentInstance.rendering = rendering.componentDefinition;
|
|
735
|
-
if (this._inputs) {
|
|
736
|
-
this._setComponentInputs(componentInstance, this._inputs);
|
|
737
|
-
}
|
|
738
|
-
if (this.outputs) {
|
|
739
|
-
this._subscribeComponentOutputs(componentInstance, this.outputs);
|
|
740
|
-
}
|
|
741
|
-
this._componentInstances.push(componentInstance);
|
|
742
|
-
}
|
|
743
|
-
}
|
|
744
|
-
PlaceholderComponent.decorators = [
|
|
745
|
-
{ type: Component, args: [{
|
|
746
|
-
selector: 'sc-placeholder,[sc-placeholder]',
|
|
723
|
+
])`);
|
|
724
|
+
rendering.componentImplementation = this.missingComponentComponent;
|
|
725
|
+
}
|
|
726
|
+
const componentFactory = rendering.componentFactory ||
|
|
727
|
+
this.componentFactoryResolver.resolveComponentFactory(rendering.componentImplementation);
|
|
728
|
+
// apply the parent style attribute _ngcontent
|
|
729
|
+
// work-around for https://github.com/angular/angular/issues/12215
|
|
730
|
+
const createdComponentRef = this.view.createComponent(componentFactory, index);
|
|
731
|
+
if (this.parentStyleAttribute) {
|
|
732
|
+
this.renderer.setAttribute(createdComponentRef.location.nativeElement, this.parentStyleAttribute, '');
|
|
733
|
+
}
|
|
734
|
+
const componentInstance = createdComponentRef.instance;
|
|
735
|
+
componentInstance.rendering = rendering.componentDefinition;
|
|
736
|
+
if (this._inputs) {
|
|
737
|
+
this._setComponentInputs(componentInstance, this._inputs);
|
|
738
|
+
}
|
|
739
|
+
if (this.outputs) {
|
|
740
|
+
this._subscribeComponentOutputs(componentInstance, this.outputs);
|
|
741
|
+
}
|
|
742
|
+
this._componentInstances.push(componentInstance);
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
PlaceholderComponent.decorators = [
|
|
746
|
+
{ type: Component, args: [{
|
|
747
|
+
selector: 'sc-placeholder,[sc-placeholder]',
|
|
747
748
|
template: `
|
|
748
749
|
<ng-template
|
|
749
750
|
*ngIf="isLoading"
|
|
750
751
|
[ngTemplateOutlet]="placeholderLoading?.templateRef"
|
|
751
752
|
></ng-template>
|
|
752
753
|
<ng-template #view></ng-template>
|
|
753
|
-
`
|
|
754
|
-
},] }
|
|
755
|
-
];
|
|
756
|
-
PlaceholderComponent.ctorParameters = () => [
|
|
757
|
-
{ type: ComponentFactoryResolver },
|
|
758
|
-
{ type: KeyValueDiffers },
|
|
759
|
-
{ type: JssComponentFactoryService },
|
|
760
|
-
{ type: ChangeDetectorRef },
|
|
761
|
-
{ type: ElementRef },
|
|
762
|
-
{ type: Renderer2 },
|
|
763
|
-
{ type: Type, decorators: [{ type: Inject, args: [PLACEHOLDER_MISSING_COMPONENT_COMPONENT,] }] },
|
|
764
|
-
{ type: Type, decorators: [{ type: Inject, args: [PLACEHOLDER_HIDDEN_RENDERING_COMPONENT,] }] }
|
|
765
|
-
];
|
|
766
|
-
PlaceholderComponent.propDecorators = {
|
|
767
|
-
name: [{ type: Input }],
|
|
768
|
-
rendering: [{ type: Input }],
|
|
769
|
-
renderings: [{ type: Input }],
|
|
770
|
-
outputs: [{ type: Input }],
|
|
771
|
-
loaded: [{ type: Output }],
|
|
772
|
-
view: [{ type: ViewChild, args: ['view', { read: ViewContainerRef, static: true },] }],
|
|
773
|
-
renderEachTemplate: [{ type: ContentChild, args: [RenderEachDirective, { static: true },] }],
|
|
774
|
-
renderEmptyTemplate: [{ type: ContentChild, args: [RenderEmptyDirective, { static: true },] }],
|
|
775
|
-
placeholderLoading: [{ type: ContentChild, args: [PlaceholderLoadingDirective, { static: true },] }],
|
|
776
|
-
inputs: [{ type: Input }]
|
|
754
|
+
`
|
|
755
|
+
},] }
|
|
756
|
+
];
|
|
757
|
+
PlaceholderComponent.ctorParameters = () => [
|
|
758
|
+
{ type: ComponentFactoryResolver },
|
|
759
|
+
{ type: KeyValueDiffers },
|
|
760
|
+
{ type: JssComponentFactoryService },
|
|
761
|
+
{ type: ChangeDetectorRef },
|
|
762
|
+
{ type: ElementRef },
|
|
763
|
+
{ type: Renderer2 },
|
|
764
|
+
{ type: Type, decorators: [{ type: Inject, args: [PLACEHOLDER_MISSING_COMPONENT_COMPONENT,] }] },
|
|
765
|
+
{ type: Type, decorators: [{ type: Inject, args: [PLACEHOLDER_HIDDEN_RENDERING_COMPONENT,] }] }
|
|
766
|
+
];
|
|
767
|
+
PlaceholderComponent.propDecorators = {
|
|
768
|
+
name: [{ type: Input }],
|
|
769
|
+
rendering: [{ type: Input }],
|
|
770
|
+
renderings: [{ type: Input }],
|
|
771
|
+
outputs: [{ type: Input }],
|
|
772
|
+
loaded: [{ type: Output }],
|
|
773
|
+
view: [{ type: ViewChild, args: ['view', { read: ViewContainerRef, static: true },] }],
|
|
774
|
+
renderEachTemplate: [{ type: ContentChild, args: [RenderEachDirective, { static: true },] }],
|
|
775
|
+
renderEmptyTemplate: [{ type: ContentChild, args: [RenderEmptyDirective, { static: true },] }],
|
|
776
|
+
placeholderLoading: [{ type: ContentChild, args: [PlaceholderLoadingDirective, { static: true },] }],
|
|
777
|
+
inputs: [{ type: Input }]
|
|
777
778
|
};
|
|
778
779
|
|
|
779
|
-
class RichTextDirective {
|
|
780
|
-
constructor(viewContainer, templateRef) {
|
|
781
|
-
this.viewContainer = viewContainer;
|
|
782
|
-
this.templateRef = templateRef;
|
|
783
|
-
this.editable = true;
|
|
784
|
-
}
|
|
785
|
-
ngOnChanges(changes) {
|
|
786
|
-
if (changes.field || changes.editable) {
|
|
787
|
-
if (!this.viewRef) {
|
|
788
|
-
this.viewContainer.clear();
|
|
789
|
-
this.viewRef = this.viewContainer.createEmbeddedView(this.templateRef);
|
|
790
|
-
}
|
|
791
|
-
this.updateView();
|
|
792
|
-
}
|
|
793
|
-
}
|
|
794
|
-
updateView() {
|
|
795
|
-
const field = this.field;
|
|
796
|
-
if (!field || (!field.editable && !field.value)) {
|
|
797
|
-
return;
|
|
798
|
-
}
|
|
799
|
-
const html = field.editable && this.editable ? field.editable : field.value;
|
|
800
|
-
this.viewRef.rootNodes.forEach((node) => {
|
|
801
|
-
node.innerHTML = html;
|
|
802
|
-
});
|
|
803
|
-
}
|
|
804
|
-
}
|
|
805
|
-
RichTextDirective.decorators = [
|
|
806
|
-
{ type: Directive, args: [{
|
|
807
|
-
selector: '[scRichText]',
|
|
808
|
-
},] }
|
|
809
|
-
];
|
|
810
|
-
RichTextDirective.ctorParameters = () => [
|
|
811
|
-
{ type: ViewContainerRef },
|
|
812
|
-
{ type: TemplateRef }
|
|
813
|
-
];
|
|
814
|
-
RichTextDirective.propDecorators = {
|
|
815
|
-
editable: [{ type: Input, args: ['scRichTextEditable',] }],
|
|
816
|
-
field: [{ type: Input, args: ['scRichText',] }]
|
|
780
|
+
class RichTextDirective {
|
|
781
|
+
constructor(viewContainer, templateRef) {
|
|
782
|
+
this.viewContainer = viewContainer;
|
|
783
|
+
this.templateRef = templateRef;
|
|
784
|
+
this.editable = true;
|
|
785
|
+
}
|
|
786
|
+
ngOnChanges(changes) {
|
|
787
|
+
if (changes.field || changes.editable) {
|
|
788
|
+
if (!this.viewRef) {
|
|
789
|
+
this.viewContainer.clear();
|
|
790
|
+
this.viewRef = this.viewContainer.createEmbeddedView(this.templateRef);
|
|
791
|
+
}
|
|
792
|
+
this.updateView();
|
|
793
|
+
}
|
|
794
|
+
}
|
|
795
|
+
updateView() {
|
|
796
|
+
const field = this.field;
|
|
797
|
+
if (!field || (!field.editable && !field.value)) {
|
|
798
|
+
return;
|
|
799
|
+
}
|
|
800
|
+
const html = field.editable && this.editable ? field.editable : field.value;
|
|
801
|
+
this.viewRef.rootNodes.forEach((node) => {
|
|
802
|
+
node.innerHTML = html;
|
|
803
|
+
});
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
RichTextDirective.decorators = [
|
|
807
|
+
{ type: Directive, args: [{
|
|
808
|
+
selector: '[scRichText]',
|
|
809
|
+
},] }
|
|
810
|
+
];
|
|
811
|
+
RichTextDirective.ctorParameters = () => [
|
|
812
|
+
{ type: ViewContainerRef },
|
|
813
|
+
{ type: TemplateRef }
|
|
814
|
+
];
|
|
815
|
+
RichTextDirective.propDecorators = {
|
|
816
|
+
editable: [{ type: Input, args: ['scRichTextEditable',] }],
|
|
817
|
+
field: [{ type: Input, args: ['scRichText',] }]
|
|
817
818
|
};
|
|
818
819
|
|
|
819
|
-
class TextDirective {
|
|
820
|
-
constructor(viewContainer, templateRef) {
|
|
821
|
-
this.viewContainer = viewContainer;
|
|
822
|
-
this.templateRef = templateRef;
|
|
823
|
-
this.editable = true;
|
|
824
|
-
this.encode = true;
|
|
825
|
-
}
|
|
826
|
-
ngOnChanges(changes) {
|
|
827
|
-
if (changes.field || changes.editable || changes.encode) {
|
|
828
|
-
if (!this.viewRef) {
|
|
829
|
-
this.viewContainer.clear();
|
|
830
|
-
this.viewRef = this.viewContainer.createEmbeddedView(this.templateRef);
|
|
831
|
-
}
|
|
832
|
-
this.updateView();
|
|
833
|
-
}
|
|
834
|
-
}
|
|
835
|
-
updateView() {
|
|
836
|
-
const field = this.field;
|
|
837
|
-
let editable = this.editable;
|
|
838
|
-
if (!field || (!field.editable && (field.value === undefined || field.value === ''))) {
|
|
839
|
-
return;
|
|
840
|
-
}
|
|
841
|
-
// can't use editable value if we want to output unencoded
|
|
842
|
-
if (!this.encode) {
|
|
843
|
-
editable = false;
|
|
844
|
-
}
|
|
845
|
-
const html = field.editable && editable ? field.editable : field.value;
|
|
846
|
-
const setDangerously = (field.editable && editable) || !this.encode;
|
|
847
|
-
this.viewRef.rootNodes.forEach((node) => {
|
|
848
|
-
if (setDangerously) {
|
|
849
|
-
node.innerHTML = html;
|
|
850
|
-
}
|
|
851
|
-
else {
|
|
852
|
-
node.textContent = html;
|
|
853
|
-
}
|
|
854
|
-
});
|
|
855
|
-
}
|
|
856
|
-
}
|
|
857
|
-
TextDirective.decorators = [
|
|
858
|
-
{ type: Directive, args: [{
|
|
859
|
-
selector: '[scText]',
|
|
860
|
-
},] }
|
|
861
|
-
];
|
|
862
|
-
TextDirective.ctorParameters = () => [
|
|
863
|
-
{ type: ViewContainerRef },
|
|
864
|
-
{ type: TemplateRef }
|
|
865
|
-
];
|
|
866
|
-
TextDirective.propDecorators = {
|
|
867
|
-
editable: [{ type: Input, args: ['scTextEditable',] }],
|
|
868
|
-
encode: [{ type: Input, args: ['scTextEncode',] }],
|
|
869
|
-
field: [{ type: Input, args: ['scText',] }]
|
|
820
|
+
class TextDirective {
|
|
821
|
+
constructor(viewContainer, templateRef) {
|
|
822
|
+
this.viewContainer = viewContainer;
|
|
823
|
+
this.templateRef = templateRef;
|
|
824
|
+
this.editable = true;
|
|
825
|
+
this.encode = true;
|
|
826
|
+
}
|
|
827
|
+
ngOnChanges(changes) {
|
|
828
|
+
if (changes.field || changes.editable || changes.encode) {
|
|
829
|
+
if (!this.viewRef) {
|
|
830
|
+
this.viewContainer.clear();
|
|
831
|
+
this.viewRef = this.viewContainer.createEmbeddedView(this.templateRef);
|
|
832
|
+
}
|
|
833
|
+
this.updateView();
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
updateView() {
|
|
837
|
+
const field = this.field;
|
|
838
|
+
let editable = this.editable;
|
|
839
|
+
if (!field || (!field.editable && (field.value === undefined || field.value === ''))) {
|
|
840
|
+
return;
|
|
841
|
+
}
|
|
842
|
+
// can't use editable value if we want to output unencoded
|
|
843
|
+
if (!this.encode) {
|
|
844
|
+
editable = false;
|
|
845
|
+
}
|
|
846
|
+
const html = field.editable && editable ? field.editable : field.value;
|
|
847
|
+
const setDangerously = (field.editable && editable) || !this.encode;
|
|
848
|
+
this.viewRef.rootNodes.forEach((node) => {
|
|
849
|
+
if (setDangerously) {
|
|
850
|
+
node.innerHTML = html;
|
|
851
|
+
}
|
|
852
|
+
else {
|
|
853
|
+
node.textContent = html;
|
|
854
|
+
}
|
|
855
|
+
});
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
TextDirective.decorators = [
|
|
859
|
+
{ type: Directive, args: [{
|
|
860
|
+
selector: '[scText]',
|
|
861
|
+
},] }
|
|
862
|
+
];
|
|
863
|
+
TextDirective.ctorParameters = () => [
|
|
864
|
+
{ type: ViewContainerRef },
|
|
865
|
+
{ type: TemplateRef }
|
|
866
|
+
];
|
|
867
|
+
TextDirective.propDecorators = {
|
|
868
|
+
editable: [{ type: Input, args: ['scTextEditable',] }],
|
|
869
|
+
encode: [{ type: Input, args: ['scTextEncode',] }],
|
|
870
|
+
field: [{ type: Input, args: ['scText',] }]
|
|
870
871
|
};
|
|
871
872
|
|
|
872
|
-
class DateDirective {
|
|
873
|
-
constructor(viewContainer, templateRef, datePipe) {
|
|
874
|
-
this.viewContainer = viewContainer;
|
|
875
|
-
this.templateRef = templateRef;
|
|
876
|
-
this.datePipe = datePipe;
|
|
877
|
-
this.editable = true;
|
|
878
|
-
}
|
|
879
|
-
ngOnChanges(changes) {
|
|
880
|
-
if (changes.field || changes.format) {
|
|
881
|
-
if (!this.viewRef) {
|
|
882
|
-
this.viewContainer.clear();
|
|
883
|
-
this.viewRef = this.viewContainer.createEmbeddedView(this.templateRef);
|
|
884
|
-
}
|
|
885
|
-
this.updateView();
|
|
886
|
-
}
|
|
887
|
-
}
|
|
888
|
-
updateView() {
|
|
889
|
-
const field = this.field;
|
|
890
|
-
if (!field || (!field.editable && !field.value)) {
|
|
891
|
-
return;
|
|
892
|
-
}
|
|
893
|
-
const html = field.editable && this.editable ? field.editable : field.value;
|
|
894
|
-
const setDangerously = field.editable && this.editable;
|
|
895
|
-
this.viewRef.rootNodes.forEach((node) => {
|
|
896
|
-
if (setDangerously) {
|
|
897
|
-
node.innerHTML = html;
|
|
898
|
-
}
|
|
899
|
-
else {
|
|
900
|
-
node.textContent = this.datePipe.transform(html, this.format, this.timezone, this.locale);
|
|
901
|
-
}
|
|
902
|
-
});
|
|
903
|
-
}
|
|
904
|
-
}
|
|
905
|
-
DateDirective.decorators = [
|
|
906
|
-
{ type: Directive, args: [{
|
|
907
|
-
selector: '[scDate]',
|
|
908
|
-
},] }
|
|
909
|
-
];
|
|
910
|
-
DateDirective.ctorParameters = () => [
|
|
911
|
-
{ type: ViewContainerRef },
|
|
912
|
-
{ type: TemplateRef },
|
|
913
|
-
{ type: DatePipe }
|
|
914
|
-
];
|
|
915
|
-
DateDirective.propDecorators = {
|
|
916
|
-
format: [{ type: Input, args: ['scDateFormat',] }],
|
|
917
|
-
timezone: [{ type: Input, args: ['scDateTimezone',] }],
|
|
918
|
-
locale: [{ type: Input, args: ['scDateLocale',] }],
|
|
919
|
-
editable: [{ type: Input, args: ['scDateEditable',] }],
|
|
920
|
-
field: [{ type: Input, args: ['scDate',] }]
|
|
873
|
+
class DateDirective {
|
|
874
|
+
constructor(viewContainer, templateRef, datePipe) {
|
|
875
|
+
this.viewContainer = viewContainer;
|
|
876
|
+
this.templateRef = templateRef;
|
|
877
|
+
this.datePipe = datePipe;
|
|
878
|
+
this.editable = true;
|
|
879
|
+
}
|
|
880
|
+
ngOnChanges(changes) {
|
|
881
|
+
if (changes.field || changes.format) {
|
|
882
|
+
if (!this.viewRef) {
|
|
883
|
+
this.viewContainer.clear();
|
|
884
|
+
this.viewRef = this.viewContainer.createEmbeddedView(this.templateRef);
|
|
885
|
+
}
|
|
886
|
+
this.updateView();
|
|
887
|
+
}
|
|
888
|
+
}
|
|
889
|
+
updateView() {
|
|
890
|
+
const field = this.field;
|
|
891
|
+
if (!field || (!field.editable && !field.value)) {
|
|
892
|
+
return;
|
|
893
|
+
}
|
|
894
|
+
const html = field.editable && this.editable ? field.editable : field.value;
|
|
895
|
+
const setDangerously = field.editable && this.editable;
|
|
896
|
+
this.viewRef.rootNodes.forEach((node) => {
|
|
897
|
+
if (setDangerously) {
|
|
898
|
+
node.innerHTML = html;
|
|
899
|
+
}
|
|
900
|
+
else {
|
|
901
|
+
node.textContent = this.datePipe.transform(html, this.format, this.timezone, this.locale);
|
|
902
|
+
}
|
|
903
|
+
});
|
|
904
|
+
}
|
|
905
|
+
}
|
|
906
|
+
DateDirective.decorators = [
|
|
907
|
+
{ type: Directive, args: [{
|
|
908
|
+
selector: '[scDate]',
|
|
909
|
+
},] }
|
|
910
|
+
];
|
|
911
|
+
DateDirective.ctorParameters = () => [
|
|
912
|
+
{ type: ViewContainerRef },
|
|
913
|
+
{ type: TemplateRef },
|
|
914
|
+
{ type: DatePipe }
|
|
915
|
+
];
|
|
916
|
+
DateDirective.propDecorators = {
|
|
917
|
+
format: [{ type: Input, args: ['scDateFormat',] }],
|
|
918
|
+
timezone: [{ type: Input, args: ['scDateTimezone',] }],
|
|
919
|
+
locale: [{ type: Input, args: ['scDateLocale',] }],
|
|
920
|
+
editable: [{ type: Input, args: ['scDateEditable',] }],
|
|
921
|
+
field: [{ type: Input, args: ['scDate',] }]
|
|
921
922
|
};
|
|
922
923
|
|
|
923
|
-
class MissingComponentComponent {
|
|
924
|
-
}
|
|
925
|
-
MissingComponentComponent.decorators = [
|
|
926
|
-
{ type: Component, args: [{
|
|
927
|
-
selector: 'sc-missing-component',
|
|
924
|
+
class MissingComponentComponent {
|
|
925
|
+
}
|
|
926
|
+
MissingComponentComponent.decorators = [
|
|
927
|
+
{ type: Component, args: [{
|
|
928
|
+
selector: 'sc-missing-component',
|
|
928
929
|
template: `
|
|
929
930
|
<div
|
|
930
931
|
style="background: darkorange; outline: 5px solid orange; padding: 10px; color: white; max-width: 500px;"
|
|
@@ -932,196 +933,196 @@ MissingComponentComponent.decorators = [
|
|
|
932
933
|
<h2>{{ rendering.componentName }}</h2>
|
|
933
934
|
<p>JSS component is missing Angular component implementation.</p>
|
|
934
935
|
</div>
|
|
935
|
-
`
|
|
936
|
-
},] }
|
|
937
|
-
];
|
|
938
|
-
MissingComponentComponent.propDecorators = {
|
|
939
|
-
rendering: [{ type: Input }]
|
|
936
|
+
`
|
|
937
|
+
},] }
|
|
938
|
+
];
|
|
939
|
+
MissingComponentComponent.propDecorators = {
|
|
940
|
+
rendering: [{ type: Input }]
|
|
940
941
|
};
|
|
941
942
|
|
|
942
|
-
/**
|
|
943
|
-
* Renders a single JSS component given a rendering definition.
|
|
944
|
-
* Useful inside templated placeholders.
|
|
945
|
-
*/
|
|
946
|
-
class RenderComponentComponent {
|
|
947
|
-
constructor(componentFactoryResolver, differs, componentFactory, missingComponentComponent) {
|
|
948
|
-
this.componentFactoryResolver = componentFactoryResolver;
|
|
949
|
-
this.differs = differs;
|
|
950
|
-
this.componentFactory = componentFactory;
|
|
951
|
-
this.missingComponentComponent = missingComponentComponent;
|
|
952
|
-
this.destroyed = false;
|
|
953
|
-
}
|
|
954
|
-
set inputs(value) {
|
|
955
|
-
this._inputs = value;
|
|
956
|
-
if (!this._differ && value) {
|
|
957
|
-
this._differ = this.differs.find(value).create();
|
|
958
|
-
}
|
|
959
|
-
}
|
|
960
|
-
ngOnChanges(changes) {
|
|
961
|
-
if (changes.rendering) {
|
|
962
|
-
this._render();
|
|
963
|
-
}
|
|
964
|
-
}
|
|
965
|
-
_setComponentInputs(componentInstance, inputs) {
|
|
966
|
-
Object.entries(inputs).forEach(([input, inputValue]) => (componentInstance[input] = inputValue));
|
|
967
|
-
}
|
|
968
|
-
_subscribeComponentOutputs(componentInstance, outputs) {
|
|
969
|
-
Object.keys(outputs)
|
|
970
|
-
.filter((output) => componentInstance[output] && componentInstance[output] instanceof Observable)
|
|
971
|
-
.forEach((output) => componentInstance[output]
|
|
972
|
-
.pipe(takeWhile(() => !this.destroyed))
|
|
973
|
-
.subscribe(outputs[output]));
|
|
974
|
-
}
|
|
975
|
-
_render() {
|
|
976
|
-
this.view.clear();
|
|
977
|
-
if (!this.rendering) {
|
|
978
|
-
return;
|
|
979
|
-
}
|
|
980
|
-
const resolveComponent = isRawRendering(this.rendering)
|
|
981
|
-
? Promise.resolve({
|
|
982
|
-
componentImplementation: RawComponent,
|
|
983
|
-
componentDefinition: this.rendering,
|
|
984
|
-
})
|
|
985
|
-
: this.componentFactory.getComponent(this.rendering);
|
|
986
|
-
resolveComponent.then((rendering) => {
|
|
987
|
-
if (!rendering.componentImplementation) {
|
|
988
|
-
const componentName = rendering.componentDefinition.componentName;
|
|
943
|
+
/**
|
|
944
|
+
* Renders a single JSS component given a rendering definition.
|
|
945
|
+
* Useful inside templated placeholders.
|
|
946
|
+
*/
|
|
947
|
+
class RenderComponentComponent {
|
|
948
|
+
constructor(componentFactoryResolver, differs, componentFactory, missingComponentComponent) {
|
|
949
|
+
this.componentFactoryResolver = componentFactoryResolver;
|
|
950
|
+
this.differs = differs;
|
|
951
|
+
this.componentFactory = componentFactory;
|
|
952
|
+
this.missingComponentComponent = missingComponentComponent;
|
|
953
|
+
this.destroyed = false;
|
|
954
|
+
}
|
|
955
|
+
set inputs(value) {
|
|
956
|
+
this._inputs = value;
|
|
957
|
+
if (!this._differ && value) {
|
|
958
|
+
this._differ = this.differs.find(value).create();
|
|
959
|
+
}
|
|
960
|
+
}
|
|
961
|
+
ngOnChanges(changes) {
|
|
962
|
+
if (changes.rendering) {
|
|
963
|
+
this._render();
|
|
964
|
+
}
|
|
965
|
+
}
|
|
966
|
+
_setComponentInputs(componentInstance, inputs) {
|
|
967
|
+
Object.entries(inputs).forEach(([input, inputValue]) => (componentInstance[input] = inputValue));
|
|
968
|
+
}
|
|
969
|
+
_subscribeComponentOutputs(componentInstance, outputs) {
|
|
970
|
+
Object.keys(outputs)
|
|
971
|
+
.filter((output) => componentInstance[output] && componentInstance[output] instanceof Observable)
|
|
972
|
+
.forEach((output) => componentInstance[output]
|
|
973
|
+
.pipe(takeWhile(() => !this.destroyed))
|
|
974
|
+
.subscribe(outputs[output]));
|
|
975
|
+
}
|
|
976
|
+
_render() {
|
|
977
|
+
this.view.clear();
|
|
978
|
+
if (!this.rendering) {
|
|
979
|
+
return;
|
|
980
|
+
}
|
|
981
|
+
const resolveComponent = isRawRendering(this.rendering)
|
|
982
|
+
? Promise.resolve({
|
|
983
|
+
componentImplementation: RawComponent,
|
|
984
|
+
componentDefinition: this.rendering,
|
|
985
|
+
})
|
|
986
|
+
: this.componentFactory.getComponent(this.rendering);
|
|
987
|
+
resolveComponent.then((rendering) => {
|
|
988
|
+
if (!rendering.componentImplementation) {
|
|
989
|
+
const componentName = rendering.componentDefinition.componentName;
|
|
989
990
|
console.error(`Attempted to render unknown component ${componentName}.`, `Ensure component is mapped, like:
|
|
990
991
|
JssModule.withComponents([
|
|
991
992
|
{ name: '${componentName}', type: ${componentName}Component }
|
|
992
|
-
])`);
|
|
993
|
-
rendering.componentImplementation = this.missingComponentComponent;
|
|
994
|
-
}
|
|
995
|
-
const componentFactory = rendering.componentFactory ||
|
|
996
|
-
this.componentFactoryResolver.resolveComponentFactory(rendering.componentImplementation);
|
|
997
|
-
const componentInstance = this.view.createComponent(componentFactory, 0).instance;
|
|
998
|
-
componentInstance.rendering = rendering.componentDefinition;
|
|
999
|
-
if (this._inputs) {
|
|
1000
|
-
this._setComponentInputs(componentInstance, this._inputs);
|
|
1001
|
-
}
|
|
1002
|
-
if (this.outputs) {
|
|
1003
|
-
this._subscribeComponentOutputs(componentInstance, this.outputs);
|
|
1004
|
-
}
|
|
1005
|
-
});
|
|
1006
|
-
}
|
|
1007
|
-
}
|
|
1008
|
-
RenderComponentComponent.decorators = [
|
|
1009
|
-
{ type: Component, args: [{
|
|
1010
|
-
selector: 'sc-render-component',
|
|
993
|
+
])`);
|
|
994
|
+
rendering.componentImplementation = this.missingComponentComponent;
|
|
995
|
+
}
|
|
996
|
+
const componentFactory = rendering.componentFactory ||
|
|
997
|
+
this.componentFactoryResolver.resolveComponentFactory(rendering.componentImplementation);
|
|
998
|
+
const componentInstance = this.view.createComponent(componentFactory, 0).instance;
|
|
999
|
+
componentInstance.rendering = rendering.componentDefinition;
|
|
1000
|
+
if (this._inputs) {
|
|
1001
|
+
this._setComponentInputs(componentInstance, this._inputs);
|
|
1002
|
+
}
|
|
1003
|
+
if (this.outputs) {
|
|
1004
|
+
this._subscribeComponentOutputs(componentInstance, this.outputs);
|
|
1005
|
+
}
|
|
1006
|
+
});
|
|
1007
|
+
}
|
|
1008
|
+
}
|
|
1009
|
+
RenderComponentComponent.decorators = [
|
|
1010
|
+
{ type: Component, args: [{
|
|
1011
|
+
selector: 'sc-render-component',
|
|
1011
1012
|
template: `
|
|
1012
1013
|
<ng-template #view></ng-template>
|
|
1013
|
-
`
|
|
1014
|
-
},] }
|
|
1015
|
-
];
|
|
1016
|
-
RenderComponentComponent.ctorParameters = () => [
|
|
1017
|
-
{ type: ComponentFactoryResolver },
|
|
1018
|
-
{ type: KeyValueDiffers },
|
|
1019
|
-
{ type: JssComponentFactoryService },
|
|
1020
|
-
{ type: Type, decorators: [{ type: Inject, args: [PLACEHOLDER_MISSING_COMPONENT_COMPONENT,] }] }
|
|
1021
|
-
];
|
|
1022
|
-
RenderComponentComponent.propDecorators = {
|
|
1023
|
-
rendering: [{ type: Input }],
|
|
1024
|
-
outputs: [{ type: Input }],
|
|
1025
|
-
view: [{ type: ViewChild, args: ['view', { read: ViewContainerRef, static: true },] }],
|
|
1026
|
-
inputs: [{ type: Input }]
|
|
1014
|
+
`
|
|
1015
|
+
},] }
|
|
1016
|
+
];
|
|
1017
|
+
RenderComponentComponent.ctorParameters = () => [
|
|
1018
|
+
{ type: ComponentFactoryResolver },
|
|
1019
|
+
{ type: KeyValueDiffers },
|
|
1020
|
+
{ type: JssComponentFactoryService },
|
|
1021
|
+
{ type: Type, decorators: [{ type: Inject, args: [PLACEHOLDER_MISSING_COMPONENT_COMPONENT,] }] }
|
|
1022
|
+
];
|
|
1023
|
+
RenderComponentComponent.propDecorators = {
|
|
1024
|
+
rendering: [{ type: Input }],
|
|
1025
|
+
outputs: [{ type: Input }],
|
|
1026
|
+
view: [{ type: ViewChild, args: ['view', { read: ViewContainerRef, static: true },] }],
|
|
1027
|
+
inputs: [{ type: Input }]
|
|
1027
1028
|
};
|
|
1028
1029
|
|
|
1029
|
-
class JssModule {
|
|
1030
|
-
/**
|
|
1031
|
-
* Instantiates the JSS module with no component factory.
|
|
1032
|
-
* Useful for using it from libraries. Most of the time you'd want withComponents()
|
|
1033
|
-
* @returns {ModuleWithProviders<JssModule>} module
|
|
1034
|
-
*/
|
|
1035
|
-
static forRoot() {
|
|
1036
|
-
return {
|
|
1037
|
-
ngModule: JssModule,
|
|
1038
|
-
providers: [DatePipe, JssComponentFactoryService],
|
|
1039
|
-
};
|
|
1040
|
-
}
|
|
1041
|
-
/**
|
|
1042
|
-
* Instantiates a module for a lazy-loaded JSS component
|
|
1043
|
-
* @param {Type<unknown>} component
|
|
1044
|
-
* @returns {ModuleWithProviders<JssModule>} module
|
|
1045
|
-
*/
|
|
1046
|
-
static forChild(component) {
|
|
1047
|
-
return {
|
|
1048
|
-
ngModule: JssModule,
|
|
1049
|
-
providers: [
|
|
1050
|
-
{ provide: ANALYZE_FOR_ENTRY_COMPONENTS, useValue: component, multi: true },
|
|
1051
|
-
{ provide: ROUTES, useValue: [], multi: true },
|
|
1052
|
-
{ provide: DYNAMIC_COMPONENT, useValue: component },
|
|
1053
|
-
],
|
|
1054
|
-
};
|
|
1055
|
-
}
|
|
1056
|
-
/**
|
|
1057
|
-
* Instantiates the JSS module and specifies the mapping from component name to component implementation.
|
|
1058
|
-
* Appropriate when defining the set of JSS components that your app is aware of.
|
|
1059
|
-
* @param {ComponentNameAndType[]} components
|
|
1060
|
-
* @param {ComponentNameAndModule[]} [lazyComponents]
|
|
1061
|
-
* @returns {ModuleWithProviders<JssModule>} module
|
|
1062
|
-
*/
|
|
1063
|
-
static withComponents(components, lazyComponents) {
|
|
1064
|
-
return {
|
|
1065
|
-
ngModule: JssModule,
|
|
1066
|
-
providers: [
|
|
1067
|
-
{
|
|
1068
|
-
provide: ANALYZE_FOR_ENTRY_COMPONENTS,
|
|
1069
|
-
useValue: components,
|
|
1070
|
-
multi: true,
|
|
1071
|
-
},
|
|
1072
|
-
{ provide: PLACEHOLDER_COMPONENTS, useValue: components },
|
|
1073
|
-
{ provide: PLACEHOLDER_LAZY_COMPONENTS, useValue: lazyComponents || [] },
|
|
1074
|
-
{ provide: ROUTES, useValue: lazyComponents || [], multi: true },
|
|
1075
|
-
{ provide: PLACEHOLDER_MISSING_COMPONENT_COMPONENT, useValue: MissingComponentComponent },
|
|
1076
|
-
{ provide: PLACEHOLDER_HIDDEN_RENDERING_COMPONENT, useValue: HiddenRenderingComponent },
|
|
1077
|
-
...JssModule.forRoot().providers,
|
|
1078
|
-
],
|
|
1079
|
-
};
|
|
1080
|
-
}
|
|
1081
|
-
}
|
|
1082
|
-
JssModule.decorators = [
|
|
1083
|
-
{ type: NgModule, args: [{
|
|
1084
|
-
imports: [CommonModule],
|
|
1085
|
-
declarations: [
|
|
1086
|
-
FileDirective,
|
|
1087
|
-
ImageDirective,
|
|
1088
|
-
LinkDirective,
|
|
1089
|
-
RouterLinkDirective,
|
|
1090
|
-
GenericLinkDirective,
|
|
1091
|
-
DateDirective,
|
|
1092
|
-
RenderEachDirective,
|
|
1093
|
-
RenderEmptyDirective,
|
|
1094
|
-
PlaceholderLoadingDirective,
|
|
1095
|
-
RenderComponentComponent,
|
|
1096
|
-
PlaceholderComponent,
|
|
1097
|
-
RawComponent,
|
|
1098
|
-
RichTextDirective,
|
|
1099
|
-
TextDirective,
|
|
1100
|
-
MissingComponentComponent,
|
|
1101
|
-
HiddenRenderingComponent,
|
|
1102
|
-
],
|
|
1103
|
-
exports: [
|
|
1104
|
-
FileDirective,
|
|
1105
|
-
ImageDirective,
|
|
1106
|
-
DateDirective,
|
|
1107
|
-
LinkDirective,
|
|
1108
|
-
RouterLinkDirective,
|
|
1109
|
-
GenericLinkDirective,
|
|
1110
|
-
RenderEachDirective,
|
|
1111
|
-
RenderEmptyDirective,
|
|
1112
|
-
RenderComponentComponent,
|
|
1113
|
-
PlaceholderComponent,
|
|
1114
|
-
HiddenRenderingComponent,
|
|
1115
|
-
PlaceholderLoadingDirective,
|
|
1116
|
-
RichTextDirective,
|
|
1117
|
-
TextDirective,
|
|
1118
|
-
],
|
|
1119
|
-
entryComponents: [RawComponent, MissingComponentComponent],
|
|
1120
|
-
},] }
|
|
1030
|
+
class JssModule {
|
|
1031
|
+
/**
|
|
1032
|
+
* Instantiates the JSS module with no component factory.
|
|
1033
|
+
* Useful for using it from libraries. Most of the time you'd want withComponents()
|
|
1034
|
+
* @returns {ModuleWithProviders<JssModule>} module
|
|
1035
|
+
*/
|
|
1036
|
+
static forRoot() {
|
|
1037
|
+
return {
|
|
1038
|
+
ngModule: JssModule,
|
|
1039
|
+
providers: [DatePipe, JssComponentFactoryService],
|
|
1040
|
+
};
|
|
1041
|
+
}
|
|
1042
|
+
/**
|
|
1043
|
+
* Instantiates a module for a lazy-loaded JSS component
|
|
1044
|
+
* @param {Type<unknown>} component
|
|
1045
|
+
* @returns {ModuleWithProviders<JssModule>} module
|
|
1046
|
+
*/
|
|
1047
|
+
static forChild(component) {
|
|
1048
|
+
return {
|
|
1049
|
+
ngModule: JssModule,
|
|
1050
|
+
providers: [
|
|
1051
|
+
{ provide: ANALYZE_FOR_ENTRY_COMPONENTS, useValue: component, multi: true },
|
|
1052
|
+
{ provide: ROUTES, useValue: [], multi: true },
|
|
1053
|
+
{ provide: DYNAMIC_COMPONENT, useValue: component },
|
|
1054
|
+
],
|
|
1055
|
+
};
|
|
1056
|
+
}
|
|
1057
|
+
/**
|
|
1058
|
+
* Instantiates the JSS module and specifies the mapping from component name to component implementation.
|
|
1059
|
+
* Appropriate when defining the set of JSS components that your app is aware of.
|
|
1060
|
+
* @param {ComponentNameAndType[]} components
|
|
1061
|
+
* @param {ComponentNameAndModule[]} [lazyComponents]
|
|
1062
|
+
* @returns {ModuleWithProviders<JssModule>} module
|
|
1063
|
+
*/
|
|
1064
|
+
static withComponents(components, lazyComponents) {
|
|
1065
|
+
return {
|
|
1066
|
+
ngModule: JssModule,
|
|
1067
|
+
providers: [
|
|
1068
|
+
{
|
|
1069
|
+
provide: ANALYZE_FOR_ENTRY_COMPONENTS,
|
|
1070
|
+
useValue: components,
|
|
1071
|
+
multi: true,
|
|
1072
|
+
},
|
|
1073
|
+
{ provide: PLACEHOLDER_COMPONENTS, useValue: components },
|
|
1074
|
+
{ provide: PLACEHOLDER_LAZY_COMPONENTS, useValue: lazyComponents || [] },
|
|
1075
|
+
{ provide: ROUTES, useValue: lazyComponents || [], multi: true },
|
|
1076
|
+
{ provide: PLACEHOLDER_MISSING_COMPONENT_COMPONENT, useValue: MissingComponentComponent },
|
|
1077
|
+
{ provide: PLACEHOLDER_HIDDEN_RENDERING_COMPONENT, useValue: HiddenRenderingComponent },
|
|
1078
|
+
...JssModule.forRoot().providers,
|
|
1079
|
+
],
|
|
1080
|
+
};
|
|
1081
|
+
}
|
|
1082
|
+
}
|
|
1083
|
+
JssModule.decorators = [
|
|
1084
|
+
{ type: NgModule, args: [{
|
|
1085
|
+
imports: [CommonModule],
|
|
1086
|
+
declarations: [
|
|
1087
|
+
FileDirective,
|
|
1088
|
+
ImageDirective,
|
|
1089
|
+
LinkDirective,
|
|
1090
|
+
RouterLinkDirective,
|
|
1091
|
+
GenericLinkDirective,
|
|
1092
|
+
DateDirective,
|
|
1093
|
+
RenderEachDirective,
|
|
1094
|
+
RenderEmptyDirective,
|
|
1095
|
+
PlaceholderLoadingDirective,
|
|
1096
|
+
RenderComponentComponent,
|
|
1097
|
+
PlaceholderComponent,
|
|
1098
|
+
RawComponent,
|
|
1099
|
+
RichTextDirective,
|
|
1100
|
+
TextDirective,
|
|
1101
|
+
MissingComponentComponent,
|
|
1102
|
+
HiddenRenderingComponent,
|
|
1103
|
+
],
|
|
1104
|
+
exports: [
|
|
1105
|
+
FileDirective,
|
|
1106
|
+
ImageDirective,
|
|
1107
|
+
DateDirective,
|
|
1108
|
+
LinkDirective,
|
|
1109
|
+
RouterLinkDirective,
|
|
1110
|
+
GenericLinkDirective,
|
|
1111
|
+
RenderEachDirective,
|
|
1112
|
+
RenderEmptyDirective,
|
|
1113
|
+
RenderComponentComponent,
|
|
1114
|
+
PlaceholderComponent,
|
|
1115
|
+
HiddenRenderingComponent,
|
|
1116
|
+
PlaceholderLoadingDirective,
|
|
1117
|
+
RichTextDirective,
|
|
1118
|
+
TextDirective,
|
|
1119
|
+
],
|
|
1120
|
+
entryComponents: [RawComponent, MissingComponentComponent],
|
|
1121
|
+
},] }
|
|
1121
1122
|
];
|
|
1122
1123
|
|
|
1123
|
-
/**
|
|
1124
|
-
* Generated bundle index. Do not edit.
|
|
1124
|
+
/**
|
|
1125
|
+
* Generated bundle index. Do not edit.
|
|
1125
1126
|
*/
|
|
1126
1127
|
|
|
1127
1128
|
export { ComponentNameAndType, DYNAMIC_COMPONENT, FileDirective, GenericLinkDirective, ImageDirective, JssModule, LinkDirective, PlaceholderComponent, PlaceholderLoadingDirective, RichTextDirective, RouterLinkDirective, TextDirective, isRawRendering, PLACEHOLDER_COMPONENTS as ɵb, PLACEHOLDER_LAZY_COMPONENTS as ɵc, PLACEHOLDER_MISSING_COMPONENT_COMPONENT as ɵd, PLACEHOLDER_HIDDEN_RENDERING_COMPONENT as ɵe, RenderEachDirective as ɵf, RenderEmptyDirective as ɵg, JssComponentFactoryService as ɵh, DateDirective as ɵi, RenderComponentComponent as ɵj, RawComponent as ɵk, MissingComponentComponent as ɵl, HiddenRenderingComponent as ɵm };
|