@mts-pjsc/image-optimize 1.0.3 → 1.0.6
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/dist/es5/components/Image.d.ts +34 -12
- package/dist/es5/components/Image.js +140 -97
- package/dist/es5/components/Image.js.map +1 -1
- package/dist/es5/helpers/check-webp-feature.js +7 -7
- package/dist/es5/helpers/check-webp-feature.js.map +1 -1
- package/dist/es5/helpers/get-format-features.d.ts +3 -0
- package/dist/es5/helpers/get-format-features.js +43 -0
- package/dist/es5/helpers/get-format-features.js.map +1 -0
- package/dist/es5/index.js +3 -3
- package/dist/es5/index.js.map +1 -1
- package/dist/esnext/components/Image.d.ts +34 -12
- package/dist/esnext/components/Image.js +99 -68
- package/dist/esnext/components/Image.js.map +1 -1
- package/dist/esnext/helpers/check-webp-feature.js +7 -7
- package/dist/esnext/helpers/check-webp-feature.js.map +1 -1
- package/dist/esnext/helpers/get-format-features.d.ts +3 -0
- package/dist/esnext/helpers/get-format-features.js +28 -0
- package/dist/esnext/helpers/get-format-features.js.map +1 -0
- package/package.json +12 -12
|
@@ -9,30 +9,52 @@ export interface IImageOptions {
|
|
|
9
9
|
}
|
|
10
10
|
export declare class Image<P extends IImageOptions> extends React.Component<P> {
|
|
11
11
|
static isShowDiagnostic: boolean;
|
|
12
|
-
static
|
|
13
|
-
static
|
|
12
|
+
static controlPoints: number[];
|
|
13
|
+
private static isAvif;
|
|
14
|
+
private static isWebP;
|
|
14
15
|
/**
|
|
15
16
|
* Change for local development.
|
|
16
17
|
*
|
|
17
18
|
* The server microservice will not be able to make a request to your localhost.
|
|
18
|
-
* Therefore, when developing locally, you must specify a
|
|
19
|
+
* Therefore, when developing locally, you must specify a production or development server origin.
|
|
20
|
+
*
|
|
21
|
+
* Example:
|
|
22
|
+
* https://tb.mts.ru
|
|
19
23
|
*
|
|
20
24
|
*/
|
|
21
|
-
static
|
|
25
|
+
static imgOrigin: string;
|
|
22
26
|
resultUrl: string;
|
|
23
27
|
resizeCheckTimeout: number;
|
|
24
28
|
thisComponent: HTMLImageElement | null;
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
protected sourceUrl: string;
|
|
30
|
+
protected readonly extensionsRegexp: RegExp;
|
|
31
|
+
protected readonly windowResizeHandler: EventListenerOrEventListenerObject;
|
|
32
|
+
protected lastOptimalSize: number;
|
|
33
|
+
/**
|
|
34
|
+
* Serves to prevent recursion when resizing images to determine the optimal size.
|
|
35
|
+
* This recursion can be caught with poor layout that does not take into account the scaling of images.
|
|
36
|
+
*/
|
|
37
|
+
protected checks: number;
|
|
31
38
|
constructor(props: P);
|
|
32
39
|
componentDidMount(): void;
|
|
33
40
|
shouldComponentUpdate(props: P): boolean;
|
|
34
41
|
componentWillUnmount(): void;
|
|
35
42
|
render(): JSX.Element;
|
|
36
|
-
|
|
37
|
-
|
|
43
|
+
protected checkImage(isResize?: boolean): Promise<void>;
|
|
44
|
+
protected processImage(isResize: boolean): void;
|
|
45
|
+
protected onWindowResize(): void;
|
|
46
|
+
protected getContainerSize(): number;
|
|
47
|
+
protected getOptimalSize(containerSize: number): number;
|
|
48
|
+
protected makeResultUrl(optimalSize: number): URL;
|
|
49
|
+
protected extractImageFormat(path: string): string;
|
|
50
|
+
protected applyResultUrl(url: URL): void;
|
|
51
|
+
/**
|
|
52
|
+
* This function should motivate the developer to make a layout that does not cause resizing.
|
|
53
|
+
*
|
|
54
|
+
* @param {boolean} isResize
|
|
55
|
+
* @param {number} optimalSize
|
|
56
|
+
*/
|
|
57
|
+
protected showWarningOnResize(isResize: boolean, optimalSize: number): void;
|
|
58
|
+
protected showResultInLog(containerSize: number, optimalSize: number): void;
|
|
59
|
+
protected initImageFormats(): Promise<void>;
|
|
38
60
|
}
|
|
@@ -4,18 +4,21 @@ exports.Image = void 0;
|
|
|
4
4
|
var tslib_1 = require("tslib");
|
|
5
5
|
var jsx_runtime_1 = require("react/jsx-runtime");
|
|
6
6
|
var react_1 = require("react");
|
|
7
|
-
var
|
|
8
|
-
var check_webp_feature_1 = require("../helpers/check-webp-feature");
|
|
7
|
+
var get_format_features_1 = require("../helpers/get-format-features");
|
|
9
8
|
var Image = /** @class */ (function (_super) {
|
|
10
|
-
|
|
9
|
+
tslib_1.__extends(Image, _super);
|
|
11
10
|
function Image(props) {
|
|
12
11
|
var _this = _super.call(this, props) || this;
|
|
13
12
|
_this.resultUrl = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
|
|
14
13
|
_this.resizeCheckTimeout = 0;
|
|
14
|
+
_this.thisComponent = null;
|
|
15
15
|
_this.sourceUrl = "";
|
|
16
16
|
_this.extensionsRegexp = /\.\w+$/u;
|
|
17
|
-
_this.
|
|
18
|
-
|
|
17
|
+
_this.lastOptimalSize = 0;
|
|
18
|
+
/**
|
|
19
|
+
* Serves to prevent recursion when resizing images to determine the optimal size.
|
|
20
|
+
* This recursion can be caught with poor layout that does not take into account the scaling of images.
|
|
21
|
+
*/
|
|
19
22
|
_this.checks = 0;
|
|
20
23
|
_this.windowResizeHandler = function () { return _this.onWindowResize(); };
|
|
21
24
|
return _this;
|
|
@@ -29,6 +32,7 @@ var Image = /** @class */ (function (_super) {
|
|
|
29
32
|
if (this.sourceUrl !== props.src) {
|
|
30
33
|
this.sourceUrl = props.src;
|
|
31
34
|
this.checks = 0;
|
|
35
|
+
// Raf for correct image position after redraw outer components
|
|
32
36
|
requestAnimationFrame(function () { return _this.checkImage(); });
|
|
33
37
|
return true;
|
|
34
38
|
}
|
|
@@ -43,110 +47,38 @@ var Image = /** @class */ (function (_super) {
|
|
|
43
47
|
var _a, _b;
|
|
44
48
|
_this.thisComponent = elem;
|
|
45
49
|
(_b = (_a = _this.props).setRef) === null || _b === void 0 ? void 0 : _b.call(_a, elem);
|
|
46
|
-
}, src: this.resultUrl }
|
|
50
|
+
}, src: this.resultUrl }));
|
|
47
51
|
};
|
|
48
|
-
// eslint-disable-next-line max-statements, complexity, max-lines-per-function
|
|
49
52
|
Image.prototype.checkImage = function (isResize) {
|
|
50
|
-
var _a;
|
|
51
53
|
if (isResize === void 0) { isResize = false; }
|
|
52
|
-
return
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
switch (_b.label) {
|
|
54
|
+
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
55
|
+
return tslib_1.__generator(this, function (_a) {
|
|
56
|
+
switch (_a.label) {
|
|
56
57
|
case 0:
|
|
57
|
-
if (!this.thisComponent) {
|
|
58
|
-
return [2 /*return*/];
|
|
59
|
-
}
|
|
60
58
|
if (this.checks > 1) {
|
|
61
59
|
return [2 /*return*/];
|
|
62
60
|
}
|
|
63
|
-
|
|
64
|
-
return [
|
|
61
|
+
this.checks += 1;
|
|
62
|
+
if (!(Image.isAvif === null || Image.isWebP === null)) return [3 /*break*/, 2];
|
|
63
|
+
return [4 /*yield*/, this.initImageFormats()];
|
|
65
64
|
case 1:
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
// eslint-disable-next-line require-atomic-updates
|
|
69
|
-
Image.isAvif = result;
|
|
70
|
-
this.checkImage();
|
|
71
|
-
return [2 /*return*/];
|
|
65
|
+
_a.sent();
|
|
66
|
+
_a.label = 2;
|
|
72
67
|
case 2:
|
|
73
|
-
|
|
74
|
-
return [4 /*yield*/, (0, check_webp_feature_1.checkWebpFeature)()];
|
|
75
|
-
case 3:
|
|
76
|
-
result = _b.sent();
|
|
77
|
-
// eslint-disable-next-line require-atomic-updates
|
|
78
|
-
Image.isWebP = result;
|
|
79
|
-
this.checkImage();
|
|
80
|
-
return [2 /*return*/];
|
|
81
|
-
case 4:
|
|
82
|
-
// Checks +1 after check webp support
|
|
83
|
-
this.checks += 1;
|
|
84
|
-
containerSize = 0;
|
|
85
|
-
element = this.thisComponent;
|
|
86
|
-
while (containerSize < 2 && Boolean(element)) {
|
|
87
|
-
containerSize = element.getBoundingClientRect().width ||
|
|
88
|
-
Number.parseFloat(getComputedStyle(element).width) || 0;
|
|
89
|
-
// eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style
|
|
90
|
-
element = element.parentElement;
|
|
91
|
-
}
|
|
92
|
-
containerSize *= window.devicePixelRatio;
|
|
93
|
-
indexOptimalSize = this.controlPoints
|
|
94
|
-
.findIndex(function (width) { return containerSize <= width; });
|
|
95
|
-
if (indexOptimalSize < 0) { // If bigger then maximum size or NaN
|
|
96
|
-
indexOptimalSize = this.controlPoints.length - 1;
|
|
97
|
-
}
|
|
98
|
-
indexOptimalSize += (_a = this.props.offset) !== null && _a !== void 0 ? _a : 0;
|
|
99
|
-
if (indexOptimalSize < 0) {
|
|
100
|
-
indexOptimalSize = 0;
|
|
101
|
-
}
|
|
102
|
-
else if (indexOptimalSize >= this.controlPoints.length) {
|
|
103
|
-
indexOptimalSize = this.controlPoints.length - 1;
|
|
104
|
-
}
|
|
105
|
-
if (!isResize && this.lastOptimalSize >= 0 && this.lastOptimalSize !== indexOptimalSize) {
|
|
106
|
-
// eslint-disable-next-line no-console
|
|
107
|
-
console.warn("New image size", this.controlPoints[this.lastOptimalSize], this.controlPoints[indexOptimalSize], this.sourceUrl);
|
|
108
|
-
}
|
|
109
|
-
this.lastOptimalSize = indexOptimalSize;
|
|
110
|
-
sourceUrl = new URL(this.sourceUrl, Image.domain);
|
|
111
|
-
url = new URL("/optimizer/optimize", location.origin);
|
|
112
|
-
url.searchParams.set("src", sourceUrl.toString());
|
|
113
|
-
url.searchParams.set("size", String(this.controlPoints[indexOptimalSize]));
|
|
114
|
-
if (typeof this.props.quality === "number") {
|
|
115
|
-
url.searchParams.set("quality", String(this.props.quality));
|
|
116
|
-
}
|
|
117
|
-
match = this.extensionsRegexp.exec(sourceUrl.pathname);
|
|
118
|
-
format = "";
|
|
119
|
-
if (Image.isAvif) {
|
|
120
|
-
format = "avif";
|
|
121
|
-
}
|
|
122
|
-
else if (Image.isWebP === true) {
|
|
123
|
-
format = "webp";
|
|
124
|
-
}
|
|
125
|
-
else {
|
|
126
|
-
format = String(match === null || match === void 0 ? void 0 : match[0])
|
|
127
|
-
.replace(".", "")
|
|
128
|
-
.replace("jpg", "jpeg");
|
|
129
|
-
}
|
|
130
|
-
url.searchParams.set("format", format);
|
|
131
|
-
resultUrl = url.toString();
|
|
132
|
-
if (this.resultUrl !== resultUrl) {
|
|
133
|
-
this.resultUrl = resultUrl;
|
|
134
|
-
this.thisComponent.src = this.resultUrl;
|
|
135
|
-
if (process.env.NODE_ENV !== "production" && Image.isShowDiagnostic) {
|
|
136
|
-
// eslint-disable-next-line no-console
|
|
137
|
-
console.log([
|
|
138
|
-
"🏄 Image optimization:",
|
|
139
|
-
"Container size ".concat(containerSize, "px,"),
|
|
140
|
-
"optimal size ".concat(this.controlPoints[indexOptimalSize], ","),
|
|
141
|
-
"image ".concat(this.sourceUrl)
|
|
142
|
-
].join(" "));
|
|
143
|
-
}
|
|
144
|
-
}
|
|
68
|
+
this.processImage(isResize);
|
|
145
69
|
return [2 /*return*/];
|
|
146
70
|
}
|
|
147
71
|
});
|
|
148
72
|
});
|
|
149
73
|
};
|
|
74
|
+
Image.prototype.processImage = function (isResize) {
|
|
75
|
+
var containerSize = this.getContainerSize();
|
|
76
|
+
var optimalSize = this.getOptimalSize(containerSize);
|
|
77
|
+
this.showWarningOnResize(isResize, optimalSize);
|
|
78
|
+
var url = this.makeResultUrl(optimalSize);
|
|
79
|
+
this.applyResultUrl(url);
|
|
80
|
+
this.showResultInLog(containerSize, optimalSize);
|
|
81
|
+
};
|
|
150
82
|
Image.prototype.onWindowResize = function () {
|
|
151
83
|
var _this = this;
|
|
152
84
|
if (this.resizeCheckTimeout) {
|
|
@@ -157,17 +89,128 @@ var Image = /** @class */ (function (_super) {
|
|
|
157
89
|
_this.checkImage(true);
|
|
158
90
|
}, 500);
|
|
159
91
|
};
|
|
92
|
+
Image.prototype.getContainerSize = function () {
|
|
93
|
+
var containerSize = 0;
|
|
94
|
+
var element = this.thisComponent;
|
|
95
|
+
while (containerSize < 2 && element) {
|
|
96
|
+
containerSize = element.getBoundingClientRect().width ||
|
|
97
|
+
Number.parseFloat(getComputedStyle(element).width) || 0;
|
|
98
|
+
element = element.parentElement;
|
|
99
|
+
}
|
|
100
|
+
return containerSize * window.devicePixelRatio;
|
|
101
|
+
};
|
|
102
|
+
Image.prototype.getOptimalSize = function (containerSize) {
|
|
103
|
+
var _a;
|
|
104
|
+
var index = Image.controlPoints
|
|
105
|
+
.findIndex(function (width) { return containerSize <= width; });
|
|
106
|
+
// If bigger then maximum size or NaN
|
|
107
|
+
if (index < 0) {
|
|
108
|
+
index = Image.controlPoints.length - 1;
|
|
109
|
+
}
|
|
110
|
+
// Make manual more or less size
|
|
111
|
+
index += (_a = this.props.offset) !== null && _a !== void 0 ? _a : 0;
|
|
112
|
+
// If offset make out of boundary
|
|
113
|
+
if (index < 0) {
|
|
114
|
+
index = 0;
|
|
115
|
+
}
|
|
116
|
+
else if (index >= Image.controlPoints.length) {
|
|
117
|
+
index = Image.controlPoints.length - 1;
|
|
118
|
+
}
|
|
119
|
+
return Image.controlPoints[index];
|
|
120
|
+
};
|
|
121
|
+
Image.prototype.makeResultUrl = function (optimalSize) {
|
|
122
|
+
var sourceUrl = new URL(this.sourceUrl, Image.imgOrigin);
|
|
123
|
+
var url = new URL("/optimizer/optimize", location.origin);
|
|
124
|
+
url.searchParams.set("src", sourceUrl.toString());
|
|
125
|
+
url.searchParams.set("size", String(optimalSize));
|
|
126
|
+
if (typeof this.props.quality === "number") {
|
|
127
|
+
url.searchParams.set("quality", String(this.props.quality));
|
|
128
|
+
}
|
|
129
|
+
var format = this.extractImageFormat(sourceUrl.pathname);
|
|
130
|
+
url.searchParams.set("format", format);
|
|
131
|
+
return url;
|
|
132
|
+
};
|
|
133
|
+
Image.prototype.extractImageFormat = function (path) {
|
|
134
|
+
var format = "";
|
|
135
|
+
var match = this.extensionsRegexp.exec(path);
|
|
136
|
+
if (Image.isAvif === true) {
|
|
137
|
+
format = "avif";
|
|
138
|
+
}
|
|
139
|
+
else if (Image.isWebP === true) {
|
|
140
|
+
format = "webp";
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
format = String(match === null || match === void 0 ? void 0 : match[0])
|
|
144
|
+
.replace(".", "")
|
|
145
|
+
.replace("jpg", "jpeg");
|
|
146
|
+
}
|
|
147
|
+
return format;
|
|
148
|
+
};
|
|
149
|
+
Image.prototype.applyResultUrl = function (url) {
|
|
150
|
+
var resultUrl = url.toString();
|
|
151
|
+
if (this.resultUrl !== resultUrl && this.thisComponent) {
|
|
152
|
+
this.resultUrl = resultUrl;
|
|
153
|
+
this.thisComponent.src = this.resultUrl;
|
|
154
|
+
}
|
|
155
|
+
};
|
|
156
|
+
/**
|
|
157
|
+
* This function should motivate the developer to make a layout that does not cause resizing.
|
|
158
|
+
*
|
|
159
|
+
* @param {boolean} isResize
|
|
160
|
+
* @param {number} optimalSize
|
|
161
|
+
*/
|
|
162
|
+
Image.prototype.showWarningOnResize = function (isResize, optimalSize) {
|
|
163
|
+
if (!isResize &&
|
|
164
|
+
this.lastOptimalSize >= 0 &&
|
|
165
|
+
this.lastOptimalSize !== optimalSize) {
|
|
166
|
+
// eslint-disable-next-line no-console
|
|
167
|
+
console.warn("New image size", this.lastOptimalSize, optimalSize, this.sourceUrl);
|
|
168
|
+
}
|
|
169
|
+
this.lastOptimalSize = optimalSize;
|
|
170
|
+
};
|
|
171
|
+
Image.prototype.showResultInLog = function (containerSize, optimalSize) {
|
|
172
|
+
if (process.env.NODE_ENV !== "production" && Image.isShowDiagnostic) {
|
|
173
|
+
// eslint-disable-next-line no-console
|
|
174
|
+
console.log([
|
|
175
|
+
"🏄 Image optimization:",
|
|
176
|
+
"Container size ".concat(containerSize, "px,"),
|
|
177
|
+
"optimal size ".concat(optimalSize, ","),
|
|
178
|
+
"image ".concat(this.sourceUrl)
|
|
179
|
+
].join(" "));
|
|
180
|
+
}
|
|
181
|
+
};
|
|
182
|
+
Image.prototype.initImageFormats = function () {
|
|
183
|
+
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
184
|
+
var format;
|
|
185
|
+
return tslib_1.__generator(this, function (_a) {
|
|
186
|
+
switch (_a.label) {
|
|
187
|
+
case 0: return [4 /*yield*/, (0, get_format_features_1.getFormatFeatures)()];
|
|
188
|
+
case 1:
|
|
189
|
+
format = _a.sent();
|
|
190
|
+
if (Image.isAvif === null || Image.isWebP === null) {
|
|
191
|
+
Image.isAvif = format === "avif";
|
|
192
|
+
Image.isWebP = format === "webp";
|
|
193
|
+
}
|
|
194
|
+
return [2 /*return*/];
|
|
195
|
+
}
|
|
196
|
+
});
|
|
197
|
+
});
|
|
198
|
+
};
|
|
160
199
|
Image.isShowDiagnostic = false;
|
|
200
|
+
Image.controlPoints = [160, 320, 640, 1280, 1920];
|
|
161
201
|
Image.isAvif = null;
|
|
162
202
|
Image.isWebP = null;
|
|
163
203
|
/**
|
|
164
204
|
* Change for local development.
|
|
165
205
|
*
|
|
166
206
|
* The server microservice will not be able to make a request to your localhost.
|
|
167
|
-
* Therefore, when developing locally, you must specify a
|
|
207
|
+
* Therefore, when developing locally, you must specify a production or development server origin.
|
|
208
|
+
*
|
|
209
|
+
* Example:
|
|
210
|
+
* https://tb.mts.ru
|
|
168
211
|
*
|
|
169
212
|
*/
|
|
170
|
-
Image.
|
|
213
|
+
Image.imgOrigin = location.origin;
|
|
171
214
|
return Image;
|
|
172
215
|
}(react_1.default.Component));
|
|
173
216
|
exports.Image = Image;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Image.js","sourceRoot":"","sources":["../../../src/components/Image.tsx"],"names":[],"mappings":";;;;;AAAA,+BAA0B;AAC1B,
|
|
1
|
+
{"version":3,"file":"Image.js","sourceRoot":"","sources":["../../../src/components/Image.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.checkWebpFeature = void 0;
|
|
4
|
+
var kTestImages = {
|
|
5
|
+
lossy: "UklGRiIAAABXRUJQVlA4IBYAAAAwAQCdASoBAAEADsD+JaQAA3AAAAAA",
|
|
6
|
+
lossless: "UklGRhoAAABXRUJQVlA4TA0AAAAvAAAAEAcQERGIiP4HAA==",
|
|
7
|
+
alpha: "UklGRkoAAABXRUJQVlA4WAoAAAAQAAAAAAAAAAAAQUxQSAwAAAARBxAR/Q9ERP8DAABWUDggGAAAABQBAJ0BKgEAAQAAAP4AAA3AAP7mtQAAAA==",
|
|
8
|
+
animation: "UklGRlIAAABXRUJQVlA4WAoAAAASAAAAAAAAAAAAQU5JTQYAAAD/////" +
|
|
9
|
+
"AABBTk1GJgAAAAAAAAAAAAAAAAAAAGQAAABWUDhMDQAAAC8AAAAQBxAREYiI/gcA"
|
|
10
|
+
};
|
|
4
11
|
var checkWebpFeature = function () { return new Promise(function (resolve) {
|
|
5
|
-
var kTestImages = {
|
|
6
|
-
lossy: "UklGRiIAAABXRUJQVlA4IBYAAAAwAQCdASoBAAEADsD+JaQAA3AAAAAA",
|
|
7
|
-
lossless: "UklGRhoAAABXRUJQVlA4TA0AAAAvAAAAEAcQERGIiP4HAA==",
|
|
8
|
-
alpha: "UklGRkoAAABXRUJQVlA4WAoAAAAQAAAAAAAAAAAAQUxQSAwAAAARBxAR/Q9ERP8DAABWUDggGAAAABQBAJ0BKgEAAQAAAP4AAA3AAP7mtQAAAA==",
|
|
9
|
-
animation: "UklGRlIAAABXRUJQVlA4WAoAAAASAAAAAAAAAAAAQU5JTQYAAAD/////" +
|
|
10
|
-
"AABBTk1GJgAAAAAAAAAAAAAAAAAAAGQAAABWUDhMDQAAAC8AAAAQBxAREYiI/gcA"
|
|
11
|
-
};
|
|
12
12
|
var img = new Image();
|
|
13
13
|
img.onload = function () {
|
|
14
14
|
var result = (img.width > 0) && (img.height > 0);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"check-webp-feature.js","sourceRoot":"","sources":["../../../src/helpers/check-webp-feature.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"check-webp-feature.js","sourceRoot":"","sources":["../../../src/helpers/check-webp-feature.ts"],"names":[],"mappings":";;;AAAA,IAAM,WAAW,GAAG;IAChB,KAAK,EAAE,0DAA0D;IACjE,QAAQ,EAAE,kDAAkD;IAC5D,KAAK,EAAE,kHAAkH;IACzH,SAAS,EAAE,0DAA0D;QACjE,kEAAkE;CACzE,CAAC;AAEK,IAAM,gBAAgB,GAAG,cAAwB,OAAA,IAAI,OAAO,CAAU,UAAC,OAAkC;IAC5G,IAAM,GAAG,GAAG,IAAI,KAAK,EAAE,CAAC;IACxB,GAAG,CAAC,MAAM,GAAG;QACT,IAAM,MAAM,GAAG,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACnD,OAAO,CAAC,MAAM,CAAC,CAAC;IACpB,CAAC,CAAC;IACF,GAAG,CAAC,OAAO,GAAG;QACV,OAAO,CAAC,KAAK,CAAC,CAAC;IACnB,CAAC,CAAC;IACF,GAAG,CAAC,GAAG,GAAG,iCAA0B,WAAW,CAAC,QAAQ,CAAE,CAAC;AAC/D,CAAC,CAAC,EAVsD,CAUtD,CAAC;AAVU,QAAA,gBAAgB,oBAU1B"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getFormatFeatures = void 0;
|
|
4
|
+
var tslib_1 = require("tslib");
|
|
5
|
+
var check_avif_feature_1 = require("./check-avif-feature");
|
|
6
|
+
var check_webp_feature_1 = require("./check-webp-feature");
|
|
7
|
+
var promisesPool = [];
|
|
8
|
+
var resolvePromises = function (format) {
|
|
9
|
+
promisesPool.forEach(function (resolve) { return resolve(format); });
|
|
10
|
+
};
|
|
11
|
+
var checkFormats = function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
|
|
12
|
+
var isAvif, isWebp;
|
|
13
|
+
return tslib_1.__generator(this, function (_a) {
|
|
14
|
+
switch (_a.label) {
|
|
15
|
+
case 0: return [4 /*yield*/, (0, check_avif_feature_1.checkAvifFeature)()];
|
|
16
|
+
case 1:
|
|
17
|
+
isAvif = _a.sent();
|
|
18
|
+
if (isAvif) {
|
|
19
|
+
resolvePromises("avif");
|
|
20
|
+
return [2 /*return*/];
|
|
21
|
+
}
|
|
22
|
+
return [4 /*yield*/, (0, check_webp_feature_1.checkWebpFeature)()];
|
|
23
|
+
case 2:
|
|
24
|
+
isWebp = _a.sent();
|
|
25
|
+
if (isWebp) {
|
|
26
|
+
resolvePromises("webp");
|
|
27
|
+
return [2 /*return*/];
|
|
28
|
+
}
|
|
29
|
+
resolvePromises(null);
|
|
30
|
+
return [2 /*return*/];
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
}); };
|
|
34
|
+
var getFormatFeatures = function () {
|
|
35
|
+
if (promisesPool.length === 0) {
|
|
36
|
+
checkFormats();
|
|
37
|
+
}
|
|
38
|
+
return new Promise(function (resolve) {
|
|
39
|
+
promisesPool.push(resolve);
|
|
40
|
+
});
|
|
41
|
+
};
|
|
42
|
+
exports.getFormatFeatures = getFormatFeatures;
|
|
43
|
+
//# sourceMappingURL=get-format-features.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-format-features.js","sourceRoot":"","sources":["../../../src/helpers/get-format-features.ts"],"names":[],"mappings":";;;;AACA,2DAAsD;AACtD,2DAAsD;AAKtD,IAAM,YAAY,GAAoC,EAAE,CAAC;AAEzD,IAAM,eAAe,GAAG,UAAC,MAAkB;IACvC,YAAY,CAAC,OAAO,CAAC,UAAC,OAAO,IAAK,OAAA,OAAO,CAAC,MAAM,CAAC,EAAf,CAAe,CAAC,CAAC;AACvD,CAAC,CAAC;AAEF,IAAM,YAAY,GAAG;;;;oBACF,qBAAM,IAAA,qCAAgB,GAAE,EAAA;;gBAAjC,MAAM,GAAG,SAAwB;gBACvC,IAAI,MAAM,EAAE;oBACR,eAAe,CAAC,MAAM,CAAC,CAAC;oBACxB,sBAAO;iBACV;gBAEc,qBAAM,IAAA,qCAAgB,GAAE,EAAA;;gBAAjC,MAAM,GAAG,SAAwB;gBACvC,IAAI,MAAM,EAAE;oBACR,eAAe,CAAC,MAAM,CAAC,CAAC;oBACxB,sBAAO;iBACV;gBAED,eAAe,CAAC,IAAI,CAAC,CAAC;;;;KACzB,CAAC;AAEK,IAAM,iBAAiB,GAAG;IAC7B,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE;QAC3B,YAAY,EAAE,CAAC;KAClB;IAED,OAAO,IAAI,OAAO,CAAC,UAAC,OAAO;QACvB,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC/B,CAAC,CAAC,CAAC;AACP,CAAC,CAAC;AARW,QAAA,iBAAiB,qBAQ5B"}
|
package/dist/es5/index.js
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
var tslib_1 = require("tslib");
|
|
4
4
|
// Components
|
|
5
|
-
|
|
5
|
+
tslib_1.__exportStar(require("./components/Image"), exports);
|
|
6
6
|
// Helpers
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
tslib_1.__exportStar(require("./helpers/check-avif-feature"), exports);
|
|
8
|
+
tslib_1.__exportStar(require("./helpers/check-webp-feature"), exports);
|
|
9
9
|
//# sourceMappingURL=index.js.map
|
package/dist/es5/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;AAAA,aAAa;AACb,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;AAAA,aAAa;AACb,6DAAmC;AAEnC,UAAU;AACV,uEAA6C;AAC7C,uEAA6C"}
|
|
@@ -9,30 +9,52 @@ export interface IImageOptions {
|
|
|
9
9
|
}
|
|
10
10
|
export declare class Image<P extends IImageOptions> extends React.Component<P> {
|
|
11
11
|
static isShowDiagnostic: boolean;
|
|
12
|
-
static
|
|
13
|
-
static
|
|
12
|
+
static controlPoints: number[];
|
|
13
|
+
private static isAvif;
|
|
14
|
+
private static isWebP;
|
|
14
15
|
/**
|
|
15
16
|
* Change for local development.
|
|
16
17
|
*
|
|
17
18
|
* The server microservice will not be able to make a request to your localhost.
|
|
18
|
-
* Therefore, when developing locally, you must specify a
|
|
19
|
+
* Therefore, when developing locally, you must specify a production or development server origin.
|
|
20
|
+
*
|
|
21
|
+
* Example:
|
|
22
|
+
* https://tb.mts.ru
|
|
19
23
|
*
|
|
20
24
|
*/
|
|
21
|
-
static
|
|
25
|
+
static imgOrigin: string;
|
|
22
26
|
resultUrl: string;
|
|
23
27
|
resizeCheckTimeout: number;
|
|
24
28
|
thisComponent: HTMLImageElement | null;
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
protected sourceUrl: string;
|
|
30
|
+
protected readonly extensionsRegexp: RegExp;
|
|
31
|
+
protected readonly windowResizeHandler: EventListenerOrEventListenerObject;
|
|
32
|
+
protected lastOptimalSize: number;
|
|
33
|
+
/**
|
|
34
|
+
* Serves to prevent recursion when resizing images to determine the optimal size.
|
|
35
|
+
* This recursion can be caught with poor layout that does not take into account the scaling of images.
|
|
36
|
+
*/
|
|
37
|
+
protected checks: number;
|
|
31
38
|
constructor(props: P);
|
|
32
39
|
componentDidMount(): void;
|
|
33
40
|
shouldComponentUpdate(props: P): boolean;
|
|
34
41
|
componentWillUnmount(): void;
|
|
35
42
|
render(): JSX.Element;
|
|
36
|
-
|
|
37
|
-
|
|
43
|
+
protected checkImage(isResize?: boolean): Promise<void>;
|
|
44
|
+
protected processImage(isResize: boolean): void;
|
|
45
|
+
protected onWindowResize(): void;
|
|
46
|
+
protected getContainerSize(): number;
|
|
47
|
+
protected getOptimalSize(containerSize: number): number;
|
|
48
|
+
protected makeResultUrl(optimalSize: number): URL;
|
|
49
|
+
protected extractImageFormat(path: string): string;
|
|
50
|
+
protected applyResultUrl(url: URL): void;
|
|
51
|
+
/**
|
|
52
|
+
* This function should motivate the developer to make a layout that does not cause resizing.
|
|
53
|
+
*
|
|
54
|
+
* @param {boolean} isResize
|
|
55
|
+
* @param {number} optimalSize
|
|
56
|
+
*/
|
|
57
|
+
protected showWarningOnResize(isResize: boolean, optimalSize: number): void;
|
|
58
|
+
protected showResultInLog(containerSize: number, optimalSize: number): void;
|
|
59
|
+
protected initImageFormats(): Promise<void>;
|
|
38
60
|
}
|
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import React from "react";
|
|
3
|
-
import {
|
|
4
|
-
import { checkWebpFeature } from "../helpers/check-webp-feature";
|
|
3
|
+
import { getFormatFeatures } from "../helpers/get-format-features";
|
|
5
4
|
export class Image extends React.Component {
|
|
6
5
|
constructor(props) {
|
|
7
6
|
super(props);
|
|
8
7
|
this.resultUrl = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
|
|
9
8
|
this.resizeCheckTimeout = 0;
|
|
9
|
+
this.thisComponent = null;
|
|
10
10
|
this.sourceUrl = "";
|
|
11
11
|
this.extensionsRegexp = /\.\w+$/u;
|
|
12
|
-
this.
|
|
13
|
-
|
|
12
|
+
this.lastOptimalSize = 0;
|
|
13
|
+
/**
|
|
14
|
+
* Serves to prevent recursion when resizing images to determine the optimal size.
|
|
15
|
+
* This recursion can be caught with poor layout that does not take into account the scaling of images.
|
|
16
|
+
*/
|
|
14
17
|
this.checks = 0;
|
|
15
18
|
this.windowResizeHandler = () => this.onWindowResize();
|
|
16
19
|
}
|
|
@@ -22,6 +25,7 @@ export class Image extends React.Component {
|
|
|
22
25
|
if (this.sourceUrl !== props.src) {
|
|
23
26
|
this.sourceUrl = props.src;
|
|
24
27
|
this.checks = 0;
|
|
28
|
+
// Raf for correct image position after redraw outer components
|
|
25
29
|
requestAnimationFrame(() => this.checkImage());
|
|
26
30
|
return true;
|
|
27
31
|
}
|
|
@@ -34,72 +38,79 @@ export class Image extends React.Component {
|
|
|
34
38
|
return (_jsx("img", { alt: this.props.alt, className: this.props.className, onLoad: () => requestAnimationFrame(() => this.checkImage()), ref: (elem) => {
|
|
35
39
|
this.thisComponent = elem;
|
|
36
40
|
this.props.setRef?.(elem);
|
|
37
|
-
}, src: this.resultUrl }
|
|
41
|
+
}, src: this.resultUrl }));
|
|
38
42
|
}
|
|
39
|
-
// eslint-disable-next-line max-statements, complexity, max-lines-per-function
|
|
40
43
|
async checkImage(isResize = false) {
|
|
41
|
-
if (!this.thisComponent) {
|
|
42
|
-
return;
|
|
43
|
-
}
|
|
44
44
|
if (this.checks > 1) {
|
|
45
45
|
return;
|
|
46
46
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
// eslint-disable-next-line require-atomic-updates
|
|
51
|
-
Image.isAvif = result;
|
|
52
|
-
this.checkImage();
|
|
53
|
-
return;
|
|
47
|
+
this.checks += 1;
|
|
48
|
+
if (Image.isAvif === null || Image.isWebP === null) {
|
|
49
|
+
await this.initImageFormats();
|
|
54
50
|
}
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
51
|
+
this.processImage(isResize);
|
|
52
|
+
}
|
|
53
|
+
processImage(isResize) {
|
|
54
|
+
const containerSize = this.getContainerSize();
|
|
55
|
+
const optimalSize = this.getOptimalSize(containerSize);
|
|
56
|
+
this.showWarningOnResize(isResize, optimalSize);
|
|
57
|
+
const url = this.makeResultUrl(optimalSize);
|
|
58
|
+
this.applyResultUrl(url);
|
|
59
|
+
this.showResultInLog(containerSize, optimalSize);
|
|
60
|
+
}
|
|
61
|
+
onWindowResize() {
|
|
62
|
+
if (this.resizeCheckTimeout) {
|
|
63
|
+
clearTimeout(this.resizeCheckTimeout);
|
|
61
64
|
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
+
this.resizeCheckTimeout = window.setTimeout(() => {
|
|
66
|
+
this.checks = 0;
|
|
67
|
+
this.checkImage(true);
|
|
68
|
+
}, 500);
|
|
69
|
+
}
|
|
70
|
+
getContainerSize() {
|
|
65
71
|
let containerSize = 0;
|
|
66
72
|
let element = this.thisComponent;
|
|
67
|
-
while (containerSize < 2 &&
|
|
73
|
+
while (containerSize < 2 && element) {
|
|
68
74
|
containerSize = element.getBoundingClientRect().width ||
|
|
69
75
|
Number.parseFloat(getComputedStyle(element).width) || 0;
|
|
70
|
-
// eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style
|
|
71
76
|
element = element.parentElement;
|
|
72
77
|
}
|
|
73
|
-
containerSize
|
|
74
|
-
|
|
78
|
+
return containerSize * window.devicePixelRatio;
|
|
79
|
+
}
|
|
80
|
+
getOptimalSize(containerSize) {
|
|
81
|
+
let index = Image.controlPoints
|
|
75
82
|
.findIndex((width) => containerSize <= width);
|
|
76
|
-
|
|
77
|
-
|
|
83
|
+
// If bigger then maximum size or NaN
|
|
84
|
+
if (index < 0) {
|
|
85
|
+
index = Image.controlPoints.length - 1;
|
|
78
86
|
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
87
|
+
// Make manual more or less size
|
|
88
|
+
index += this.props.offset ?? 0;
|
|
89
|
+
// If offset make out of boundary
|
|
90
|
+
if (index < 0) {
|
|
91
|
+
index = 0;
|
|
82
92
|
}
|
|
83
|
-
else if (
|
|
84
|
-
|
|
85
|
-
}
|
|
86
|
-
if (!isResize && this.lastOptimalSize >= 0 && this.lastOptimalSize !== indexOptimalSize) {
|
|
87
|
-
// eslint-disable-next-line no-console
|
|
88
|
-
console.warn("New image size", this.controlPoints[this.lastOptimalSize], this.controlPoints[indexOptimalSize], this.sourceUrl);
|
|
93
|
+
else if (index >= Image.controlPoints.length) {
|
|
94
|
+
index = Image.controlPoints.length - 1;
|
|
89
95
|
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
96
|
+
return Image.controlPoints[index];
|
|
97
|
+
}
|
|
98
|
+
makeResultUrl(optimalSize) {
|
|
99
|
+
const sourceUrl = new URL(this.sourceUrl, Image.imgOrigin);
|
|
94
100
|
const url = new URL("/optimizer/optimize", location.origin);
|
|
95
101
|
url.searchParams.set("src", sourceUrl.toString());
|
|
96
|
-
url.searchParams.set("size", String(
|
|
102
|
+
url.searchParams.set("size", String(optimalSize));
|
|
97
103
|
if (typeof this.props.quality === "number") {
|
|
98
104
|
url.searchParams.set("quality", String(this.props.quality));
|
|
99
105
|
}
|
|
100
|
-
const
|
|
106
|
+
const format = this.extractImageFormat(sourceUrl.pathname);
|
|
107
|
+
url.searchParams.set("format", format);
|
|
108
|
+
return url;
|
|
109
|
+
}
|
|
110
|
+
extractImageFormat(path) {
|
|
101
111
|
let format = "";
|
|
102
|
-
|
|
112
|
+
const match = this.extensionsRegexp.exec(path);
|
|
113
|
+
if (Image.isAvif === true) {
|
|
103
114
|
format = "avif";
|
|
104
115
|
}
|
|
105
116
|
else if (Image.isWebP === true) {
|
|
@@ -110,42 +121,62 @@ export class Image extends React.Component {
|
|
|
110
121
|
.replace(".", "")
|
|
111
122
|
.replace("jpg", "jpeg");
|
|
112
123
|
}
|
|
113
|
-
|
|
114
|
-
|
|
124
|
+
return format;
|
|
125
|
+
}
|
|
126
|
+
applyResultUrl(url) {
|
|
115
127
|
const resultUrl = url.toString();
|
|
116
|
-
if (this.resultUrl !== resultUrl) {
|
|
128
|
+
if (this.resultUrl !== resultUrl && this.thisComponent) {
|
|
117
129
|
this.resultUrl = resultUrl;
|
|
118
130
|
this.thisComponent.src = this.resultUrl;
|
|
119
|
-
if (process.env.NODE_ENV !== "production" && Image.isShowDiagnostic) {
|
|
120
|
-
// eslint-disable-next-line no-console
|
|
121
|
-
console.log([
|
|
122
|
-
"🏄 Image optimization:",
|
|
123
|
-
`Container size ${containerSize}px,`,
|
|
124
|
-
`optimal size ${this.controlPoints[indexOptimalSize]},`,
|
|
125
|
-
`image ${this.sourceUrl}`
|
|
126
|
-
].join(" "));
|
|
127
|
-
}
|
|
128
131
|
}
|
|
129
132
|
}
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
+
/**
|
|
134
|
+
* This function should motivate the developer to make a layout that does not cause resizing.
|
|
135
|
+
*
|
|
136
|
+
* @param {boolean} isResize
|
|
137
|
+
* @param {number} optimalSize
|
|
138
|
+
*/
|
|
139
|
+
showWarningOnResize(isResize, optimalSize) {
|
|
140
|
+
if (!isResize &&
|
|
141
|
+
this.lastOptimalSize >= 0 &&
|
|
142
|
+
this.lastOptimalSize !== optimalSize) {
|
|
143
|
+
// eslint-disable-next-line no-console
|
|
144
|
+
console.warn("New image size", this.lastOptimalSize, optimalSize, this.sourceUrl);
|
|
145
|
+
}
|
|
146
|
+
this.lastOptimalSize = optimalSize;
|
|
147
|
+
}
|
|
148
|
+
showResultInLog(containerSize, optimalSize) {
|
|
149
|
+
if (process.env.NODE_ENV !== "production" && Image.isShowDiagnostic) {
|
|
150
|
+
// eslint-disable-next-line no-console
|
|
151
|
+
console.log([
|
|
152
|
+
"🏄 Image optimization:",
|
|
153
|
+
`Container size ${containerSize}px,`,
|
|
154
|
+
`optimal size ${optimalSize},`,
|
|
155
|
+
`image ${this.sourceUrl}`
|
|
156
|
+
].join(" "));
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
async initImageFormats() {
|
|
160
|
+
const format = await getFormatFeatures();
|
|
161
|
+
if (Image.isAvif === null || Image.isWebP === null) {
|
|
162
|
+
Image.isAvif = format === "avif";
|
|
163
|
+
Image.isWebP = format === "webp";
|
|
133
164
|
}
|
|
134
|
-
this.resizeCheckTimeout = window.setTimeout(() => {
|
|
135
|
-
this.checks = 0;
|
|
136
|
-
this.checkImage(true);
|
|
137
|
-
}, 500);
|
|
138
165
|
}
|
|
139
166
|
}
|
|
140
167
|
Image.isShowDiagnostic = false;
|
|
168
|
+
Image.controlPoints = [160, 320, 640, 1280, 1920];
|
|
141
169
|
Image.isAvif = null;
|
|
142
170
|
Image.isWebP = null;
|
|
143
171
|
/**
|
|
144
172
|
* Change for local development.
|
|
145
173
|
*
|
|
146
174
|
* The server microservice will not be able to make a request to your localhost.
|
|
147
|
-
* Therefore, when developing locally, you must specify a
|
|
175
|
+
* Therefore, when developing locally, you must specify a production or development server origin.
|
|
176
|
+
*
|
|
177
|
+
* Example:
|
|
178
|
+
* https://tb.mts.ru
|
|
148
179
|
*
|
|
149
180
|
*/
|
|
150
|
-
Image.
|
|
181
|
+
Image.imgOrigin = location.origin;
|
|
151
182
|
//# sourceMappingURL=Image.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Image.js","sourceRoot":"","sources":["../../../src/components/Image.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAC,
|
|
1
|
+
{"version":3,"file":"Image.js","sourceRoot":"","sources":["../../../src/components/Image.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
+
const kTestImages = {
|
|
2
|
+
lossy: "UklGRiIAAABXRUJQVlA4IBYAAAAwAQCdASoBAAEADsD+JaQAA3AAAAAA",
|
|
3
|
+
lossless: "UklGRhoAAABXRUJQVlA4TA0AAAAvAAAAEAcQERGIiP4HAA==",
|
|
4
|
+
alpha: "UklGRkoAAABXRUJQVlA4WAoAAAAQAAAAAAAAAAAAQUxQSAwAAAARBxAR/Q9ERP8DAABWUDggGAAAABQBAJ0BKgEAAQAAAP4AAA3AAP7mtQAAAA==",
|
|
5
|
+
animation: "UklGRlIAAABXRUJQVlA4WAoAAAASAAAAAAAAAAAAQU5JTQYAAAD/////" +
|
|
6
|
+
"AABBTk1GJgAAAAAAAAAAAAAAAAAAAGQAAABWUDhMDQAAAC8AAAAQBxAREYiI/gcA"
|
|
7
|
+
};
|
|
1
8
|
export const checkWebpFeature = () => new Promise((resolve) => {
|
|
2
|
-
const kTestImages = {
|
|
3
|
-
lossy: "UklGRiIAAABXRUJQVlA4IBYAAAAwAQCdASoBAAEADsD+JaQAA3AAAAAA",
|
|
4
|
-
lossless: "UklGRhoAAABXRUJQVlA4TA0AAAAvAAAAEAcQERGIiP4HAA==",
|
|
5
|
-
alpha: "UklGRkoAAABXRUJQVlA4WAoAAAAQAAAAAAAAAAAAQUxQSAwAAAARBxAR/Q9ERP8DAABWUDggGAAAABQBAJ0BKgEAAQAAAP4AAA3AAP7mtQAAAA==",
|
|
6
|
-
animation: "UklGRlIAAABXRUJQVlA4WAoAAAASAAAAAAAAAAAAQU5JTQYAAAD/////" +
|
|
7
|
-
"AABBTk1GJgAAAAAAAAAAAAAAAAAAAGQAAABWUDhMDQAAAC8AAAAQBxAREYiI/gcA"
|
|
8
|
-
};
|
|
9
9
|
const img = new Image();
|
|
10
10
|
img.onload = () => {
|
|
11
11
|
const result = (img.width > 0) && (img.height > 0);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"check-webp-feature.js","sourceRoot":"","sources":["../../../src/helpers/check-webp-feature.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"check-webp-feature.js","sourceRoot":"","sources":["../../../src/helpers/check-webp-feature.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,GAAG;IAChB,KAAK,EAAE,0DAA0D;IACjE,QAAQ,EAAE,kDAAkD;IAC5D,KAAK,EAAE,kHAAkH;IACzH,SAAS,EAAE,0DAA0D;QACjE,kEAAkE;CACzE,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAG,GAAqB,EAAE,CAAC,IAAI,OAAO,CAAU,CAAC,OAAkC,EAAE,EAAE;IAChH,MAAM,GAAG,GAAG,IAAI,KAAK,EAAE,CAAC;IACxB,GAAG,CAAC,MAAM,GAAG,GAAS,EAAE;QACpB,MAAM,MAAM,GAAG,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACnD,OAAO,CAAC,MAAM,CAAC,CAAC;IACpB,CAAC,CAAC;IACF,GAAG,CAAC,OAAO,GAAG,GAAS,EAAE;QACrB,OAAO,CAAC,KAAK,CAAC,CAAC;IACnB,CAAC,CAAC;IACF,GAAG,CAAC,GAAG,GAAG,0BAA0B,WAAW,CAAC,QAAQ,EAAE,CAAC;AAC/D,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { checkAvifFeature } from "./check-avif-feature";
|
|
2
|
+
import { checkWebpFeature } from "./check-webp-feature";
|
|
3
|
+
const promisesPool = [];
|
|
4
|
+
const resolvePromises = (format) => {
|
|
5
|
+
promisesPool.forEach((resolve) => resolve(format));
|
|
6
|
+
};
|
|
7
|
+
const checkFormats = async () => {
|
|
8
|
+
const isAvif = await checkAvifFeature();
|
|
9
|
+
if (isAvif) {
|
|
10
|
+
resolvePromises("avif");
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
const isWebp = await checkWebpFeature();
|
|
14
|
+
if (isWebp) {
|
|
15
|
+
resolvePromises("webp");
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
resolvePromises(null);
|
|
19
|
+
};
|
|
20
|
+
export const getFormatFeatures = () => {
|
|
21
|
+
if (promisesPool.length === 0) {
|
|
22
|
+
checkFormats();
|
|
23
|
+
}
|
|
24
|
+
return new Promise((resolve) => {
|
|
25
|
+
promisesPool.push(resolve);
|
|
26
|
+
});
|
|
27
|
+
};
|
|
28
|
+
//# sourceMappingURL=get-format-features.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-format-features.js","sourceRoot":"","sources":["../../../src/helpers/get-format-features.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,gBAAgB,EAAC,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAC,gBAAgB,EAAC,MAAM,sBAAsB,CAAC;AAKtD,MAAM,YAAY,GAAoC,EAAE,CAAC;AAEzD,MAAM,eAAe,GAAG,CAAC,MAAkB,EAAQ,EAAE;IACjD,YAAY,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;AACvD,CAAC,CAAC;AAEF,MAAM,YAAY,GAAG,KAAK,IAAmB,EAAE;IAC3C,MAAM,MAAM,GAAG,MAAM,gBAAgB,EAAE,CAAC;IACxC,IAAI,MAAM,EAAE;QACR,eAAe,CAAC,MAAM,CAAC,CAAC;QACxB,OAAO;KACV;IAED,MAAM,MAAM,GAAG,MAAM,gBAAgB,EAAE,CAAC;IACxC,IAAI,MAAM,EAAE;QACR,eAAe,CAAC,MAAM,CAAC,CAAC;QACxB,OAAO;KACV;IAED,eAAe,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAwB,EAAE;IACvD,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE;QAC3B,YAAY,EAAE,CAAC;KAClB;IAED,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC3B,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC/B,CAAC,CAAC,CAAC;AACP,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mts-pjsc/image-optimize",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.6",
|
|
4
4
|
"description": "React component for image optimizer",
|
|
5
5
|
"main": "dist/es5/index.js",
|
|
6
6
|
"module": "dist/esnext/index.js",
|
|
7
7
|
"esnext": "dist/esnext/index.js",
|
|
8
8
|
"scripts": {
|
|
9
9
|
"eslint": "eslint --fix -c .eslintrc.js --ext .tsx,.ts,.jsx,.js ./src/",
|
|
10
|
-
"test": "echo \"Error: no test specified\" && exit 1",
|
|
10
|
+
"test": "echo \"Error: no test specified. For test need deployed microservice part\" && exit 1",
|
|
11
11
|
"build:esnext": "tsc --project tsconfig.json",
|
|
12
12
|
"build:commonjs": "tsc --project tsconfig.es5.json",
|
|
13
|
-
"build": "rm -rf dist/ && npm run build:esnext && npm run build:commonjs"
|
|
13
|
+
"build": "rm -rf dist/ && npm run build:esnext && npm run build:commonjs",
|
|
14
|
+
"prepare": "husky install"
|
|
14
15
|
},
|
|
15
16
|
"repository": {
|
|
16
17
|
"type": "git",
|
|
@@ -31,16 +32,15 @@
|
|
|
31
32
|
"url": "https://github.com/MobileTeleSystems/image-optimize-react/issues"
|
|
32
33
|
},
|
|
33
34
|
"homepage": "https://github.com/MobileTeleSystems/image-optimize-react#readme",
|
|
34
|
-
"
|
|
35
|
-
"react": "
|
|
36
|
-
"renamer": "^4.0.0"
|
|
35
|
+
"peerDependencies": {
|
|
36
|
+
"react": ">=16.0.0"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
|
-
"@labeg/code-style": "^2.0.
|
|
40
|
-
"@types/node": "^
|
|
41
|
-
"@types/react": "^
|
|
42
|
-
"husky": "^
|
|
43
|
-
"lint-staged": "^
|
|
44
|
-
"typescript": "^4.
|
|
39
|
+
"@labeg/code-style": "^2.0.42",
|
|
40
|
+
"@types/node": "^18.0.0",
|
|
41
|
+
"@types/react": "^18.0.14",
|
|
42
|
+
"husky": "^8.0.1",
|
|
43
|
+
"lint-staged": "^13.0.3",
|
|
44
|
+
"typescript": "^4.7.4"
|
|
45
45
|
}
|
|
46
46
|
}
|