@claspo/components 1.6.2 → 1.7.0-components-build-perf
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/package.json +6 -4
- package/script/SysButtonComponent/SysButton.manifest.js +126 -0
- package/script/SysButtonComponent/SysButton.styles.js +64 -0
- package/script/SysButtonComponent/SysButtonComponent.js +231 -0
- package/script/SysColumnComponent/SysColumn.manifest.js +17 -0
- package/script/SysColumnComponent/SysColumnComponent.js +107 -0
- package/script/SysColumnsComponent/SysColumns.manifest.js +17 -0
- package/script/SysColumnsComponent/SysColumnsComponent.js +53 -0
- package/script/SysColumnsComponent/getStyleElement.js +23 -0
- package/script/SysContainerComponent/SysBaseContainerComponent.js +41 -0
- package/script/SysContainerComponent/SysContainer.manifest.js +18 -0
- package/script/SysContainerComponent/SysContainerComponent.js +86 -0
- package/script/SysImageComponent/SysImage.manifest.js +18 -0
- package/script/SysImageComponent/SysImageComponent.js +378 -0
- package/script/SysImageComponent/getStyleElement.js +18 -0
- package/script/SysInputComponent/EmailSuggesting.js +252 -0
- package/script/SysInputComponent/InputFormControl.js +136 -0
- package/script/SysInputComponent/SysInput.manifest.js +728 -0
- package/script/SysInputComponent/SysInputComponent.js +84 -0
- package/script/SysInputComponent/emailProvidersList.js +158 -0
- package/script/SysInputComponent/getOverlayStyles.js +220 -0
- package/script/SysInputComponent/getStyleElement.js +69 -0
- package/script/SysInputComponent/inputValidators.js +293 -0
- package/script/SysTextComponent/SysText.manifest.js +29 -0
- package/script/SysTextComponent/SysTextComponent.js +147 -0
- package/script/SysTextComponent/TextRoller.js +298 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import WcElement from '@claspo/renderer/sdk/WcElement';
|
|
2
|
+
|
|
3
|
+
class SysBaseContainerComponent extends WcElement {
|
|
4
|
+
manifest = {
|
|
5
|
+
name: 'SysContainerComponent'
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
getComponentName = () => {
|
|
9
|
+
return this.manifest.name;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
connectedCallback() {
|
|
13
|
+
super.connectedCallback();
|
|
14
|
+
this.processStyles();
|
|
15
|
+
|
|
16
|
+
this.observeProps((prev, next) => {
|
|
17
|
+
this.applyAutoAdaptiveStyles(next.adaptiveStyles, next.styles);
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
disconnectedCallback() {
|
|
22
|
+
super.disconnectedCallback();
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
processStyles = () => {
|
|
26
|
+
this.innerHTML += `
|
|
27
|
+
<style>
|
|
28
|
+
[cl-component="${this.getComponentName()}"] {
|
|
29
|
+
position: relative;
|
|
30
|
+
min-width: 50px;
|
|
31
|
+
min-height: 50px;
|
|
32
|
+
}
|
|
33
|
+
</style>`;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export { SysBaseContainerComponent as default };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import '@claspo/renderer/sdk/ManifestUtils';
|
|
2
|
+
|
|
3
|
+
var SysContainerManifest = {
|
|
4
|
+
"name": "SysContainerComponent",
|
|
5
|
+
"componentType": "CONTAINER",
|
|
6
|
+
"version": "1.0.0",
|
|
7
|
+
"events": {
|
|
8
|
+
"dispatch": [],
|
|
9
|
+
"listen": []
|
|
10
|
+
},
|
|
11
|
+
"i18nPropPaths": ["handlers,[id],actions,[id],params,link", "handlers,[id],actions,[id],params,customData"],
|
|
12
|
+
"waitForResourcesLoad": true,
|
|
13
|
+
"resourcesPropPaths": [["adaptiveStyles", ":ENV", "styleAttributes", "background"]],
|
|
14
|
+
"syncEnabled": true,
|
|
15
|
+
"stylesImitationEnabled": true
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export { SysContainerManifest as default };
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import SysContainerManifest from './SysContainer.manifest.js';
|
|
2
|
+
import SysBaseContainerComponent from './SysBaseContainerComponent.js';
|
|
3
|
+
import insertHtmlIntoElement from '@claspo/common/dom/insertHtmlIntoElement';
|
|
4
|
+
|
|
5
|
+
class SysContainerComponent extends SysBaseContainerComponent {
|
|
6
|
+
static define = {
|
|
7
|
+
name: 'sys-container',
|
|
8
|
+
model: SysContainerManifest.name,
|
|
9
|
+
manifest: SysContainerManifest
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
manifest = SysContainerManifest;
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
connectedCallback() {
|
|
16
|
+
super.connectedCallback();
|
|
17
|
+
this.appendResponsiveStyles();
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
this.observeProps((_, next) => {
|
|
21
|
+
if (next.isResponsive) {
|
|
22
|
+
this.updateResponsiveRules(this.getResponsiveStyleElement());
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
if (this.getProps().isResponsive) {
|
|
27
|
+
this.connectResizeObserver();
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
disconnectedCallback() {
|
|
32
|
+
super.disconnectedCallback();
|
|
33
|
+
this.resizeObserver?.disconnect();
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
connectResizeObserver() {
|
|
37
|
+
this.resizeObserver = new ResizeObserver((entries) => {
|
|
38
|
+
|
|
39
|
+
for (const entry of entries) {
|
|
40
|
+
|
|
41
|
+
if (entry.contentRect) {
|
|
42
|
+
this.updateResponsiveRules(this.getResponsiveStyleElement());
|
|
43
|
+
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
});
|
|
48
|
+
this.resizeObserver.observe(this.getWidgetContainerNode());
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
updateResponsiveRules(styleElement) {
|
|
52
|
+
if (!this.getProps().isResponsive) {
|
|
53
|
+
insertHtmlIntoElement({
|
|
54
|
+
element: styleElement,
|
|
55
|
+
html: '',
|
|
56
|
+
});
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const parentNode = this.getWidgetContainerNode();
|
|
61
|
+
const {width, height} = parentNode.getBoundingClientRect();
|
|
62
|
+
|
|
63
|
+
if (height / width > 1.6) {
|
|
64
|
+
styleElement.innerHTML = `[cl-component="${this.getComponentName()}"] {flex-direction: column !important;}`;
|
|
65
|
+
} else {
|
|
66
|
+
styleElement.innerHTML = `[cl-component="${this.getComponentName()}"] {flex-direction: row !important;}`;
|
|
67
|
+
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
getResponsiveStyleElement() {
|
|
74
|
+
return [...this.children]
|
|
75
|
+
.find(child => child.getAttribute('name') === 'responsive-styles');
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
appendResponsiveStyles() {
|
|
80
|
+
this.innerHTML += `<style name="responsive-styles">
|
|
81
|
+
[cl-component="${this.getComponentName()}"] {}
|
|
82
|
+
</style>`;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export { SysContainerComponent as default };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import '@claspo/renderer/sdk/ManifestUtils';
|
|
2
|
+
|
|
3
|
+
var SysImageManifest = {
|
|
4
|
+
"name": "SysImageComponent",
|
|
5
|
+
"componentType": "IMAGE",
|
|
6
|
+
"version": "1.0.0",
|
|
7
|
+
"i18nPropPaths": ["handlers,[id],actions,[id],params,link", "handlers,[id],actions,[id],params,customData", "control,altText"],
|
|
8
|
+
"events": {
|
|
9
|
+
"dispatch": [],
|
|
10
|
+
"listen": []
|
|
11
|
+
},
|
|
12
|
+
"waitForResourcesLoad": true,
|
|
13
|
+
"resourcesPropPaths": [["control", "imageSource", "url"]],
|
|
14
|
+
"syncEnabled": true,
|
|
15
|
+
"stylesImitationEnabled": true
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export { SysImageManifest as default };
|
|
@@ -0,0 +1,378 @@
|
|
|
1
|
+
import addEventListenerToElement from '@claspo/common/utils/addEventListener';
|
|
2
|
+
import SysImageManifest from './SysImage.manifest.js';
|
|
3
|
+
import WcElement from '@claspo/renderer/sdk/WcElement';
|
|
4
|
+
import getStyleElement from './getStyleElement.js';
|
|
5
|
+
import omitKeys from '@claspo/common/object/omitKeys';
|
|
6
|
+
import { getAdaptiveStylesForPlatform, replaceStyleAttributes } from '@claspo/renderer/sdk/ModelStyleUtils';
|
|
7
|
+
|
|
8
|
+
const VerticalPosition = {
|
|
9
|
+
TOP: 'top',
|
|
10
|
+
CENTER: 'center',
|
|
11
|
+
BOTTOM: 'bottom'
|
|
12
|
+
};
|
|
13
|
+
const HorizontalPosition = {
|
|
14
|
+
LEFT: 'left',
|
|
15
|
+
CENTER: 'center',
|
|
16
|
+
RIGHT: 'right'
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const PositioningModes = {
|
|
20
|
+
FIXED: 'fixed',
|
|
21
|
+
STICKY: 'sticky',
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
class SysImageComponent extends WcElement {
|
|
25
|
+
static define = {
|
|
26
|
+
name: 'sys-image',
|
|
27
|
+
model: SysImageManifest.name,
|
|
28
|
+
manifest: SysImageManifest,
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
constructor() {
|
|
33
|
+
super();
|
|
34
|
+
this.originalApplyAutoAdaptiveStyles = this.applyAutoAdaptiveStyles;
|
|
35
|
+
this.applyAutoAdaptiveStyles = this.applyStylesRespectingRelativePositioning;
|
|
36
|
+
this.getRootElement().innerHTML = `
|
|
37
|
+
${getStyleElement()}
|
|
38
|
+
<img cl-element="image" draggable="false" alt="">
|
|
39
|
+
`;
|
|
40
|
+
/**
|
|
41
|
+
* height: auto; is a fix for webkit browsers that overrides the height of the host element, for more details
|
|
42
|
+
* @see: https://stackoverflow.com/questions/8468066/child-inside-parent-with-min-height-100-not-inheriting-height
|
|
43
|
+
*/
|
|
44
|
+
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
connectedCallback() {
|
|
48
|
+
super.connectedCallback();
|
|
49
|
+
this.skipGameBlur = !this._isFloating();
|
|
50
|
+
|
|
51
|
+
this.componentResourceManager.getPending().increment();
|
|
52
|
+
this.recalculateStylesAfterImageLoad();
|
|
53
|
+
|
|
54
|
+
this.observeProps((prev, next) => {
|
|
55
|
+
this.applyAutoAdaptiveStyles(next.adaptiveStyles);
|
|
56
|
+
this.applyAltText(next);
|
|
57
|
+
|
|
58
|
+
const imageElement = this.getElement('image');
|
|
59
|
+
|
|
60
|
+
if (
|
|
61
|
+
next.control?.imageSource.url
|
|
62
|
+
&& imageElement
|
|
63
|
+
// possible fix for TypeError: Cannot set properties of undefined (setting 'src')
|
|
64
|
+
&& 'src' in imageElement
|
|
65
|
+
) {
|
|
66
|
+
imageElement.src = next.control.imageSource.url;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const nextUrl = next.control.imageSource.url;
|
|
70
|
+
const prevUrl = prev && prev.control.imageSource.url;
|
|
71
|
+
|
|
72
|
+
const nextInlineSVGUrl = String(next.control.imageSource.url).endsWith('.svg') ? next.control.imageSource.url : null;
|
|
73
|
+
const prevInlineSVGUrl = prev && String(prev.control.imageSource.url).endsWith('.svg') ? prev.control.imageSource.url : null;
|
|
74
|
+
|
|
75
|
+
if (nextInlineSVGUrl) {
|
|
76
|
+
|
|
77
|
+
if (nextInlineSVGUrl === prevInlineSVGUrl) {
|
|
78
|
+
this.applyAdaptiveStyles(next);
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
this.deleteElementIfPresent(this.getRootElement(), 'img');
|
|
83
|
+
this.upsertSvg(this.getRootElement(), nextInlineSVGUrl).then(() => {
|
|
84
|
+
this.applyAltText(next);
|
|
85
|
+
this.applyAdaptiveStyles(next);
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
} else if (nextUrl) {
|
|
89
|
+
|
|
90
|
+
if (nextUrl === prevUrl) {
|
|
91
|
+
this.applyAdaptiveStyles(next);
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
this.deleteElementIfPresent(this.getRootElement(), '.svgOverflowContainer');
|
|
96
|
+
this.upsertImage(this.getRootElement(), nextUrl)
|
|
97
|
+
.then(() => {
|
|
98
|
+
this.applyAltText(next);
|
|
99
|
+
this.applyAdaptiveStyles(next);
|
|
100
|
+
// this.componentResourceManager.getPending().decrement();
|
|
101
|
+
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
} else {
|
|
106
|
+
|
|
107
|
+
this.deleteElementIfPresent(this.getRootElement(), '.svgOverflowContainer');
|
|
108
|
+
this.upsertImage(this.getRootElement(), this.assets('img/image-placeholder.svg'))
|
|
109
|
+
.then(() => {
|
|
110
|
+
this.applyAltText(next);
|
|
111
|
+
this.applyAdaptiveStyles(next);
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
disconnectedCallback() {
|
|
122
|
+
super.disconnectedCallback();
|
|
123
|
+
this.resourcesLoadedListener?.off();
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
applyAltText(props) {
|
|
127
|
+
const imageElement = this.getElement('image');
|
|
128
|
+
if (!imageElement) return;
|
|
129
|
+
const altText = props.control?.altText || '';
|
|
130
|
+
if (imageElement.nodeName === 'IMG') {
|
|
131
|
+
imageElement.alt = altText;
|
|
132
|
+
} else {
|
|
133
|
+
imageElement.setAttribute('aria-label', altText);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
applyStylesRespectingRelativePositioning() {
|
|
138
|
+
const adaptiveStyles = this.processPositioningStyles(this.getProps());
|
|
139
|
+
this.originalApplyAutoAdaptiveStyles(adaptiveStyles);
|
|
140
|
+
this.fixFloatingImageSize(adaptiveStyles);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
recalculateStylesAfterImageLoad() {
|
|
144
|
+
this.resourcesLoadedListener = this.services.eventEmitter.on('VIEW_COMPONENT_RESOURCES_LOADED', () => {
|
|
145
|
+
requestAnimationFrame(() => {
|
|
146
|
+
this.applyAdaptiveStyles(this.getProps());
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
processPositioningStyles(props) {
|
|
152
|
+
const adaptiveStyles = props.adaptiveStyles;
|
|
153
|
+
const mode = props.control?.positioningMode || PositioningModes.FIXED;
|
|
154
|
+
|
|
155
|
+
if (mode === PositioningModes.FIXED) {
|
|
156
|
+
return adaptiveStyles
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
const environment = this.getEnvironment();
|
|
160
|
+
const positioning = props.control?.positioning?.[environment] || {};
|
|
161
|
+
const diff = positioning?.diff || {};
|
|
162
|
+
const hasDiff = Boolean('x' in diff && 'y' in diff);
|
|
163
|
+
|
|
164
|
+
if (!hasDiff) {
|
|
165
|
+
return adaptiveStyles;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
const { styleAttributes } = getAdaptiveStylesForPlatform(adaptiveStyles, environment, 'host');
|
|
169
|
+
const { width, height } = this._getHostNewDimensionsWithStyles(styleAttributes);
|
|
170
|
+
const newStyleAttributes = omitKeys(styleAttributes, ['left', 'right', 'top', 'bottom']);
|
|
171
|
+
|
|
172
|
+
// process x
|
|
173
|
+
const xCenter = width / 2;
|
|
174
|
+
const shiftedX = diff.x - xCenter;
|
|
175
|
+
if (positioning.horizontalPosition === HorizontalPosition.LEFT) {
|
|
176
|
+
newStyleAttributes.left = `${shiftedX}px`;
|
|
177
|
+
newStyleAttributes.right = 'auto';
|
|
178
|
+
} else if (positioning.horizontalPosition === HorizontalPosition.RIGHT) {
|
|
179
|
+
newStyleAttributes.right = `${-width - shiftedX}px`;
|
|
180
|
+
newStyleAttributes.left = 'auto';
|
|
181
|
+
} else {
|
|
182
|
+
newStyleAttributes.left = `calc(50% + ${shiftedX}px)`;
|
|
183
|
+
newStyleAttributes.right = 'auto';
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// process y
|
|
187
|
+
const yCenter = height / 2;
|
|
188
|
+
const shiftedY = diff.y - yCenter;
|
|
189
|
+
if (positioning.verticalPosition === VerticalPosition.TOP) {
|
|
190
|
+
newStyleAttributes.top = `${shiftedY}px`;
|
|
191
|
+
newStyleAttributes.bottom = 'auto';
|
|
192
|
+
} else if (positioning.verticalPosition === VerticalPosition.BOTTOM) {
|
|
193
|
+
newStyleAttributes.bottom = `${-height - shiftedY}px`;
|
|
194
|
+
newStyleAttributes.top = 'auto';
|
|
195
|
+
} else {
|
|
196
|
+
newStyleAttributes.top = `calc(50% + ${shiftedY}px)`;
|
|
197
|
+
newStyleAttributes.bottom = 'auto';
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
return replaceStyleAttributes(adaptiveStyles, environment, 'host', newStyleAttributes);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
deleteElementIfPresent(rootElement, cssSelector) {
|
|
204
|
+
const element = rootElement.querySelector(cssSelector);
|
|
205
|
+
if (element) {
|
|
206
|
+
element.remove();
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
upsertSvg(rootElement, inlineSVGUrl) {
|
|
211
|
+
const alreadyPresent = rootElement.querySelector('svg');
|
|
212
|
+
|
|
213
|
+
// if we have the same SVG then we do not have to redraw
|
|
214
|
+
if (alreadyPresent && alreadyPresent.getAttribute('inline-svg-url') === inlineSVGUrl) {
|
|
215
|
+
return Promise.resolve();
|
|
216
|
+
|
|
217
|
+
// if we have different SVG, then we have to redraw
|
|
218
|
+
} else if (alreadyPresent) {
|
|
219
|
+
this.deleteElementIfPresent(this.getRootElement(), '.svgOverflowContainer');
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
return fetch(inlineSVGUrl).then(r => r.text()).then((inlineSVG) => {
|
|
223
|
+
const htmlTemplateElement = document.createElement('template');
|
|
224
|
+
const containerWithOverflow = document.createElement('div');
|
|
225
|
+
containerWithOverflow.style.overflow = 'hidden';
|
|
226
|
+
containerWithOverflow.style.width = '100%';
|
|
227
|
+
containerWithOverflow.style.height = 'inherit';
|
|
228
|
+
containerWithOverflow.classList.add('svgOverflowContainer');
|
|
229
|
+
|
|
230
|
+
htmlTemplateElement.append(containerWithOverflow);
|
|
231
|
+
htmlTemplateElement.firstChild.innerHTML = inlineSVG.trim();
|
|
232
|
+
|
|
233
|
+
const svgElementContainer = htmlTemplateElement.firstChild;
|
|
234
|
+
const svgNode = svgElementContainer.querySelector('svg');
|
|
235
|
+
svgNode.setAttribute('cl-element', 'image');
|
|
236
|
+
svgNode.setAttribute('inline-svg-url', inlineSVGUrl);
|
|
237
|
+
|
|
238
|
+
this.componentResourceManager.getPending().decrement();
|
|
239
|
+
rootElement.append(svgElementContainer);
|
|
240
|
+
return rootElement;
|
|
241
|
+
}).catch((err) => {
|
|
242
|
+
console.error(err);
|
|
243
|
+
this.upsertImage(rootElement, null);
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
upsertImage(rootElement, imgUrl) {
|
|
249
|
+
const alreadyPresentImgElement = rootElement.querySelector('img');
|
|
250
|
+
if (alreadyPresentImgElement) {
|
|
251
|
+
alreadyPresentImgElement.src = imgUrl;
|
|
252
|
+
addEventListenerToElement(alreadyPresentImgElement, 'load', () => {
|
|
253
|
+
this.componentResourceManager.getPending().decrement();
|
|
254
|
+
});
|
|
255
|
+
addEventListenerToElement(alreadyPresentImgElement, 'error', () => {
|
|
256
|
+
this.componentResourceManager.onResourceLoadFailure(alreadyPresentImgElement.src);
|
|
257
|
+
});
|
|
258
|
+
return Promise.resolve();
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
const imageElement = new Image();
|
|
262
|
+
imageElement.setAttribute('cl-element', 'image');
|
|
263
|
+
imageElement.src = imgUrl;
|
|
264
|
+
addEventListenerToElement(imageElement, 'load', () => {
|
|
265
|
+
this.componentResourceManager.getPending().decrement();
|
|
266
|
+
});
|
|
267
|
+
addEventListenerToElement(imageElement, 'error', () => {
|
|
268
|
+
this.componentResourceManager.onResourceLoadFailure(imageElement.src);
|
|
269
|
+
});
|
|
270
|
+
rootElement.append(imageElement);
|
|
271
|
+
|
|
272
|
+
return Promise.resolve();
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
applyAdaptiveStyles(next) {
|
|
276
|
+
this.applyAutoAdaptiveStyles(next.adaptiveStyles);
|
|
277
|
+
|
|
278
|
+
const environment = this.getEnvironment();
|
|
279
|
+
|
|
280
|
+
const envModels = next.adaptiveStyles[environment];
|
|
281
|
+
const hostElementModel = envModels.find(e => e.element === 'host');
|
|
282
|
+
const imageElementModel = envModels.find(e => e.element === 'image');
|
|
283
|
+
const imageElement = this.getElement('image');
|
|
284
|
+
|
|
285
|
+
const svgObjectFitMapper = {
|
|
286
|
+
cover: 'xMidYMid slice', contain: 'xMidYMid meet', none: '',
|
|
287
|
+
};
|
|
288
|
+
|
|
289
|
+
const isImageNodeSVG = imageElement && imageElement.nodeName === 'svg';
|
|
290
|
+
const elementModelHasObjectFit = imageElementModel?.styleAttributes?.objectFit && svgObjectFitMapper.hasOwnProperty(imageElementModel.styleAttributes.objectFit);
|
|
291
|
+
|
|
292
|
+
if (isImageNodeSVG && elementModelHasObjectFit) {
|
|
293
|
+
imageElement.setAttribute('preserveAspectRatio', svgObjectFitMapper[imageElementModel.styleAttributes.objectFit]);
|
|
294
|
+
|
|
295
|
+
if (imageElementModel.styleAttributes.objectFit === 'none') {
|
|
296
|
+
imageElement.setAttribute('width', imageElement.viewBox.baseVal.width + 'px');
|
|
297
|
+
imageElement.setAttribute('height', imageElement.viewBox.baseVal.height + 'px');
|
|
298
|
+
} else {
|
|
299
|
+
const aspectRatio = imageElement.viewBox.baseVal.width / imageElement.viewBox.baseVal.height;
|
|
300
|
+
|
|
301
|
+
if (hostElementModel.styleAttributes.width !== 'auto' && hostElementModel.styleAttributes.height !== 'auto') {
|
|
302
|
+
imageElement.setAttribute('height', '100%');
|
|
303
|
+
imageElement.setAttribute('width', '100%');
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
if (hostElementModel.styleAttributes.width === 'auto' && hostElementModel.styleAttributes.height === 'auto') {
|
|
308
|
+
imageElement.setAttribute('width', imageElement.viewBox.baseVal.width + 'px');
|
|
309
|
+
imageElement.setAttribute('height', imageElement.viewBox.baseVal.height + 'px');
|
|
310
|
+
return;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
if (hostElementModel.styleAttributes.width === 'auto') {
|
|
314
|
+
imageElement.setAttribute('height', '100%');
|
|
315
|
+
|
|
316
|
+
if (hostElementModel.styleAttributes.height !== '100%' && hostElementModel.styleAttributes.height !== 'calc(100% - 0px)') {
|
|
317
|
+
imageElement.setAttribute('width', `${Math.round(parseInt(hostElementModel.styleAttributes.height, 10) * aspectRatio)}px`);
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
if (hostElementModel.styleAttributes.height === 'auto') {
|
|
322
|
+
imageElement.setAttribute('width', '100%');
|
|
323
|
+
|
|
324
|
+
if (hostElementModel.styleAttributes.width !== '100%' && hostElementModel.styleAttributes.width !== 'calc(100% - 0px)') {
|
|
325
|
+
imageElement.setAttribute('height', `${Math.round(parseInt(hostElementModel.styleAttributes.width, 10) / aspectRatio)}px`);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
fixFloatingImageSize(adaptiveStyles) {
|
|
333
|
+
const imageElement = this.getElement('image');
|
|
334
|
+
|
|
335
|
+
// svg image
|
|
336
|
+
if (!imageElement) {
|
|
337
|
+
return;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
if (!this._isFloating()) {
|
|
341
|
+
imageElement.style.width = '100%';
|
|
342
|
+
return;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
const imageStyles = getAdaptiveStylesForPlatform(adaptiveStyles, this.getEnvironment(), 'host');
|
|
346
|
+
|
|
347
|
+
// when <img> has width 100% and floating host has width auto it causes image to change size depending on image position in widget:
|
|
348
|
+
// the closer image to the left side of a widget, the smaller it gets. We could not find source of the issue,
|
|
349
|
+
// it persists even at 10.11.23 revisions, so it's looks like browsers changed behaviour in recent versions
|
|
350
|
+
if (imageStyles.styleAttributes.width === 'auto') {
|
|
351
|
+
imageElement.style.width = '';
|
|
352
|
+
} else {
|
|
353
|
+
imageElement.style.width = '100%';
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
_getHostNewDimensionsWithStyles(styleAttributes = {}) {
|
|
358
|
+
const host = this.getHostElement();
|
|
359
|
+
const dimensionalStyleNames = ['height', 'width', 'minHeight', 'minWidth', 'maxHeight', 'maxWidth', 'display'];
|
|
360
|
+
dimensionalStyleNames.forEach((style) => {
|
|
361
|
+
if (styleAttributes[style]) {
|
|
362
|
+
host.style[style] = styleAttributes[style];
|
|
363
|
+
} else if (host.style[style]) {
|
|
364
|
+
host.style[style] = '';
|
|
365
|
+
}
|
|
366
|
+
});
|
|
367
|
+
const { offsetWidth: width, offsetHeight: height } = host;
|
|
368
|
+
return { width, height };
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
_isFloating() {
|
|
372
|
+
return this.getProps().floating
|
|
373
|
+
// for backward compatibility
|
|
374
|
+
|| this.getModel().floating;
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
export { HorizontalPosition, PositioningModes, VerticalPosition, SysImageComponent as default };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
function getStyleElement() {
|
|
2
|
+
return `
|
|
3
|
+
<style>
|
|
4
|
+
:host {
|
|
5
|
+
transform: rotate(var(--rotation, 0deg));
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
img {
|
|
9
|
+
display: block;
|
|
10
|
+
max-height: inherit;
|
|
11
|
+
height: inherit;
|
|
12
|
+
min-height: inherit;
|
|
13
|
+
}
|
|
14
|
+
</style>
|
|
15
|
+
`;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export { getStyleElement as default };
|