@automattic/jetpack-image-guide 0.1.1 → 0.2.0
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/CHANGELOG.md +16 -0
- package/build/MeasurableImage.d.ts +1 -1
- package/build/index.asset.php +1 -0
- package/build/index.js +1 -4
- package/package.json +6 -3
- package/src/MeasurableImage.ts +1 -1
- package/src/find-image-elements.ts +1 -0
- package/webpack.config.cjs +34 -0
- package/build/MeasurableImage.js +0 -103
- package/build/MeasurableImage.js.map +0 -1
- package/build/find-image-elements.js +0 -110
- package/build/find-image-elements.js.map +0 -1
- package/build/index.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,20 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.2.0] - 2023-01-19
|
|
9
|
+
### Changed
|
|
10
|
+
- Bundle the package to make it easy to consume [#28429]
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
- Clean up JavaScript eslint issues. [#28441]
|
|
14
|
+
|
|
15
|
+
## [0.1.2] - 2023-01-17
|
|
16
|
+
### Added
|
|
17
|
+
- Fixed an issue that would break the release process [#28186]
|
|
18
|
+
|
|
19
|
+
### Fixed
|
|
20
|
+
- Adding prepare script back to package.json, was needed for an ESlint test [#28103]
|
|
21
|
+
|
|
8
22
|
## [0.1.1] - 2022-12-26
|
|
9
23
|
### Added
|
|
10
24
|
- Turn on auto-publish [#28032]
|
|
@@ -19,4 +33,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
19
33
|
### Removed
|
|
20
34
|
- Minor package.json change - removing private entry.
|
|
21
35
|
|
|
36
|
+
[0.2.0]: https://github.com/Automattic/jetpack-image-guide/compare/v0.1.2...v0.2.0
|
|
37
|
+
[0.1.2]: https://github.com/Automattic/jetpack-image-guide/compare/v0.1.1...v0.1.2
|
|
22
38
|
[0.1.1]: https://github.com/Automattic/jetpack-image-guide/compare/v0.1.0...v0.1.1
|
|
@@ -37,7 +37,7 @@ export declare class MeasurableImage {
|
|
|
37
37
|
* the image size on page has to be multiplied by the device pixel ratio.
|
|
38
38
|
*
|
|
39
39
|
* @param {Dimensions} sizeOnPage - The size of the image on the page.
|
|
40
|
-
* @returns {
|
|
40
|
+
* @returns {object} - The expected size of the image.
|
|
41
41
|
*/
|
|
42
42
|
getExpectedSize(sizeOnPage: Dimensions): {
|
|
43
43
|
width: number;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<?php return array('dependencies' => array(), 'version' => 'e6fb4ce0f7b08187a456');
|
package/build/index.js
CHANGED
|
@@ -1,4 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import { getMeasurableImages } from './find-image-elements';
|
|
3
|
-
export { MeasurableImage, getMeasurableImages };
|
|
4
|
-
//# sourceMappingURL=index.js.map
|
|
1
|
+
!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ImageGuideLibrary=e():t.ImageGuideLibrary=e()}(self,(()=>(()=>{"use strict";var t={38:(t,e,n)=>{n.d(e,{z:()=>i});var r=function(t,e,n,r){return new(n||(n=Promise))((function(o,i){function u(t){try{c(r.next(t))}catch(t){i(t)}}function a(t){try{c(r.throw(t))}catch(t){i(t)}}function c(t){var e;t.done?o(t.value):(e=t.value,e instanceof n?e:new n((function(t){t(e)}))).then(u,a)}c((r=r.apply(t,e||[])).next())}))},o=function(t,e){var n,r,o,i,u={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:a(0),throw:a(1),return:a(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function a(i){return function(a){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;u;)try{if(n=1,r&&(o=2&i[0]?r.return:i[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,i[1])).done)return o;switch(r=0,o&&(i=[2&i[0],o.value]),i[0]){case 0:case 1:o=i;break;case 4:return u.label++,{value:i[1],done:!1};case 5:u.label++,r=i[1],i=[0];continue;case 7:i=u.ops.pop(),u.trys.pop();continue;default:if(!(o=u.trys,(o=o.length>0&&o[o.length-1])||6!==i[0]&&2!==i[0])){u=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]<o[3])){u.label=i[1];break}if(6===i[0]&&u.label<o[1]){u.label=o[1],o=i;break}if(o&&u.label<o[2]){u.label=o[2],u.ops.push(i);break}o[2]&&u.ops.pop(),u.trys.pop();continue}i=e.call(t,u)}catch(t){i=[6,t],r=0}finally{n=o=0}if(5&i[0])throw i[1];return{value:i[0]?i[1]:void 0,done:!0}}([i,a])}}},i=function(){function t(t,e){this.node=t,this.getURLCallback=e}return t.prototype.getURL=function(){return this.getURLCallback(this.node)},t.prototype.getSizeOnPage=function(){var t=this.node.getBoundingClientRect(),e=t.width,n=t.height;return{width:Math.round(e),height:Math.round(n)}},t.prototype.getFileSize=function(t){return r(this,void 0,void 0,(function(){var e,n,r,i,u;return o(this,(function(o){switch(o.label){case 0:return[4,Promise.all([this.fetchFileWeight(t),this.fetchFileDimensions(t)])];case 1:return e=o.sent(),n=e[0],r=e[1],i=r.width,u=r.height,[2,{width:i,height:u,weight:n}]}}))}))},t.prototype.getPotentialSavings=function(t,e){var n=this.getOversizedRatio(t,e);return n<=1?null:Math.round(t.weight-t.weight/n)},t.prototype.getExpectedSize=function(t){var e=window.devicePixelRatio||1;return{width:Math.round(t.width*e),height:Math.round(t.height*e)}},t.prototype.getOversizedRatio=function(t,e){var n=this.getExpectedSize(e),r=n.width,o=n.height;return t.width*t.height/(r*o)},t.prototype.fetchFileWeight=function(t){return r(this,void 0,void 0,(function(){var e,n;return o(this,(function(r){switch(r.label){case 0:return[4,fetch(t,{method:"HEAD",mode:"no-cors"})];case 1:return(e=r.sent()).url?(n=e.headers.get("content-length"))?[2,parseInt(n,10)/1024]:[2,-1]:(console.log("Can't get image size for ".concat(t," likely due to a CORS error.")),[2,-1])}}))}))},t.prototype.fetchFileDimensions=function(t){return r(this,void 0,void 0,(function(){var e;return o(this,(function(n){return(e=new Image).src=t,[2,new Promise((function(t){e.onload=function(){t({width:Math.round(e.width),height:Math.round(e.height)})},e.onerror=function(){t({width:-1,height:-1})}}))]}))}))},t}()},705:(t,e,n)=>{n.d(e,{RK:()=>u});var r=n(38);function o(t){return a(t.currentSrc)?t.currentSrc:a(t.src)?t.src:null}function i(t){var e=getComputedStyle(t).backgroundImage.match(/url\(.?(.*?).?\)/i);return e&&e[1]&&a(e[1])?e[1]:null}function u(t){return function(t){return t.filter((function(t){return t instanceof HTMLImageElement||t instanceof HTMLElement&&"none"!==getComputedStyle(t).backgroundImage}))}(t).map((function(t){return t instanceof HTMLImageElement?new r.z(t,o):t instanceof HTMLElement&&i(t)?new r.z(t,i):null})).filter((function(t){return null!==t}))}function a(t){if(t.startsWith("/"))return!t.split("?")[0].endsWith(".svg");try{var e=new URL(t);return"http:"===e.protocol||"https:"===e.protocol}catch(t){return!1}}}},e={};function n(r){var o=e[r];if(void 0!==o)return o.exports;var i=e[r]={exports:{}};return t[r](i,i.exports,n),i.exports}n.d=(t,e)=>{for(var r in e)n.o(e,r)&&!n.o(t,r)&&Object.defineProperty(t,r,{enumerable:!0,get:e[r]})},n.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),n.r=t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})};var r={};return(()=>{n.r(r),n.d(r,{MeasurableImage:()=>t.z,getMeasurableImages:()=>e.RK});var t=n(38),e=n(705)})(),r})()));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@automattic/jetpack-image-guide",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Go through the dom to analyze image size on screen vs actual file size.",
|
|
5
5
|
"homepage": "https://github.com/Automattic/jetpack/tree/HEAD/projects/js-packages/image-guide/#readme",
|
|
6
6
|
"type": "module",
|
|
@@ -15,7 +15,8 @@
|
|
|
15
15
|
"license": "GPL-2.0-or-later",
|
|
16
16
|
"author": "Automattic",
|
|
17
17
|
"scripts": {
|
|
18
|
-
"
|
|
18
|
+
"prepare": "[ -e ./build/index.js ] || pnpm build",
|
|
19
|
+
"build": "pnpm run clean && webpack",
|
|
19
20
|
"clean": "rm -rf build/",
|
|
20
21
|
"watch": "pnpm run build && pnpm webpack watch",
|
|
21
22
|
"test-coverage": "pnpm run test --coverageDirectory=\"$COVERAGE_DIR\" --coverage --coverageReporters=clover",
|
|
@@ -26,9 +27,11 @@
|
|
|
26
27
|
"@typescript-eslint/parser": "5.36.1",
|
|
27
28
|
"eslint": "8.22.0",
|
|
28
29
|
"jest": "29.3.1",
|
|
30
|
+
"ts-loader": "9.4.2",
|
|
29
31
|
"typescript": "4.8.2",
|
|
30
32
|
"webpack": "5.72.1",
|
|
31
33
|
"webpack-cli": "4.9.1"
|
|
32
34
|
},
|
|
33
|
-
"main": "./build/index.js"
|
|
35
|
+
"main": "./build/index.js",
|
|
36
|
+
"types": "./build/index.d.ts"
|
|
34
37
|
}
|
package/src/MeasurableImage.ts
CHANGED
|
@@ -61,7 +61,7 @@ export class MeasurableImage {
|
|
|
61
61
|
* the image size on page has to be multiplied by the device pixel ratio.
|
|
62
62
|
*
|
|
63
63
|
* @param {Dimensions} sizeOnPage - The size of the image on the page.
|
|
64
|
-
* @returns {
|
|
64
|
+
* @returns {object} - The expected size of the image.
|
|
65
65
|
*/
|
|
66
66
|
public getExpectedSize( sizeOnPage: Dimensions ) {
|
|
67
67
|
const dpr = window.devicePixelRatio || 1;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
const path = require( 'path' );
|
|
2
|
+
const jetpackWebpackConfig = require( '@automattic/jetpack-webpack-config/webpack' );
|
|
3
|
+
|
|
4
|
+
module.exports = {
|
|
5
|
+
entry: './src/index.ts',
|
|
6
|
+
mode: jetpackWebpackConfig.mode,
|
|
7
|
+
devtool: jetpackWebpackConfig.isProduction ? false : 'source-map',
|
|
8
|
+
module: {
|
|
9
|
+
strictExportPresence: true,
|
|
10
|
+
rules: [
|
|
11
|
+
{
|
|
12
|
+
test: /\.ts?$/,
|
|
13
|
+
use: 'ts-loader',
|
|
14
|
+
exclude: /node_modules/,
|
|
15
|
+
},
|
|
16
|
+
],
|
|
17
|
+
},
|
|
18
|
+
optimization: {
|
|
19
|
+
...jetpackWebpackConfig.optimization,
|
|
20
|
+
},
|
|
21
|
+
resolve: {
|
|
22
|
+
...jetpackWebpackConfig.resolve,
|
|
23
|
+
},
|
|
24
|
+
output: {
|
|
25
|
+
...jetpackWebpackConfig.output,
|
|
26
|
+
path: path.resolve( __dirname, 'build' ),
|
|
27
|
+
filename: 'index.js',
|
|
28
|
+
library: {
|
|
29
|
+
name: 'ImageGuideLibrary',
|
|
30
|
+
type: 'umd',
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
plugins: [ ...jetpackWebpackConfig.StandardPlugins() ],
|
|
34
|
+
};
|
package/build/MeasurableImage.js
DELETED
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* A class that represents a DOM Element that
|
|
3
|
-
* has an image that should be measured and
|
|
4
|
-
* provides measurement utilities.
|
|
5
|
-
*/
|
|
6
|
-
export class MeasurableImage {
|
|
7
|
-
node;
|
|
8
|
-
getURLCallback;
|
|
9
|
-
/**
|
|
10
|
-
* Constructor.
|
|
11
|
-
*
|
|
12
|
-
* @param {HTMLElement | HTMLImageElement} node - The DOM Element that contains the image.
|
|
13
|
-
* @param {SourceCallbackFn} getURL - A function that takes in the node and returns the URL of the image.
|
|
14
|
-
*/
|
|
15
|
-
constructor(node, getURL) {
|
|
16
|
-
this.node = node;
|
|
17
|
-
this.getURLCallback = getURL;
|
|
18
|
-
}
|
|
19
|
-
getURL() {
|
|
20
|
-
return this.getURLCallback(this.node);
|
|
21
|
-
}
|
|
22
|
-
getSizeOnPage() {
|
|
23
|
-
const { width, height } = this.node.getBoundingClientRect();
|
|
24
|
-
return {
|
|
25
|
-
width: Math.round(width),
|
|
26
|
-
height: Math.round(height),
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
async getFileSize(url) {
|
|
30
|
-
const [weight, { width, height }] = await Promise.all([
|
|
31
|
-
this.fetchFileWeight(url),
|
|
32
|
-
this.fetchFileDimensions(url),
|
|
33
|
-
]);
|
|
34
|
-
return {
|
|
35
|
-
width,
|
|
36
|
-
height,
|
|
37
|
-
weight,
|
|
38
|
-
};
|
|
39
|
-
}
|
|
40
|
-
getPotentialSavings(fileSize, sizeOnPage) {
|
|
41
|
-
const oversizedRatio = this.getOversizedRatio(fileSize, sizeOnPage);
|
|
42
|
-
if (oversizedRatio <= 1) {
|
|
43
|
-
return null;
|
|
44
|
-
}
|
|
45
|
-
return Math.round(fileSize.weight - fileSize.weight / oversizedRatio);
|
|
46
|
-
}
|
|
47
|
-
/**
|
|
48
|
-
* To get the expected size of the image,
|
|
49
|
-
* the image size on page has to be multiplied by the device pixel ratio.
|
|
50
|
-
*
|
|
51
|
-
* @param {Dimensions} sizeOnPage - The size of the image on the page.
|
|
52
|
-
* @returns {Object} - The expected size of the image.
|
|
53
|
-
*/
|
|
54
|
-
getExpectedSize(sizeOnPage) {
|
|
55
|
-
const dpr = window.devicePixelRatio || 1;
|
|
56
|
-
return {
|
|
57
|
-
width: Math.round(sizeOnPage.width * dpr),
|
|
58
|
-
height: Math.round(sizeOnPage.height * dpr),
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
|
-
getOversizedRatio(fileSize, sizeOnPage) {
|
|
62
|
-
const { width, height } = this.getExpectedSize(sizeOnPage);
|
|
63
|
-
return (fileSize.width * fileSize.height) / (width * height);
|
|
64
|
-
}
|
|
65
|
-
/**
|
|
66
|
-
* Fetches the weight of the image at the given URL,
|
|
67
|
-
* by reading the Content-Length header.
|
|
68
|
-
*
|
|
69
|
-
* @param {string} url - string The URL of the image.
|
|
70
|
-
*/
|
|
71
|
-
async fetchFileWeight(url) {
|
|
72
|
-
const response = await fetch(url, { method: 'HEAD', mode: 'no-cors' });
|
|
73
|
-
if (!response.url) {
|
|
74
|
-
// eslint-disable-next-line no-console
|
|
75
|
-
console.log(`Can't get image size for ${url} likely due to a CORS error.`);
|
|
76
|
-
return -1;
|
|
77
|
-
}
|
|
78
|
-
const size = response.headers.get('content-length');
|
|
79
|
-
if (size) {
|
|
80
|
-
return parseInt(size, 10) / 1024;
|
|
81
|
-
}
|
|
82
|
-
return -1;
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* Fetches the dimensions of the image at the given URL,
|
|
86
|
-
* This creates a new image element and loads the image.
|
|
87
|
-
*
|
|
88
|
-
* @param {string} url - image url
|
|
89
|
-
*/
|
|
90
|
-
async fetchFileDimensions(url) {
|
|
91
|
-
const img = new Image();
|
|
92
|
-
img.src = url;
|
|
93
|
-
return new Promise(resolve => {
|
|
94
|
-
img.onload = () => {
|
|
95
|
-
resolve({ width: Math.round(img.width), height: Math.round(img.height) });
|
|
96
|
-
};
|
|
97
|
-
img.onerror = () => {
|
|
98
|
-
resolve({ width: -1, height: -1 });
|
|
99
|
-
};
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
//# sourceMappingURL=MeasurableImage.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"MeasurableImage.js","sourceRoot":"","sources":["../src/MeasurableImage.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
import { MeasurableImage } from './MeasurableImage';
|
|
2
|
-
/**
|
|
3
|
-
* Get elements that either are image tags or have a background image.
|
|
4
|
-
*
|
|
5
|
-
* @param {Element[]} nodes - A list of nodes to filter
|
|
6
|
-
* @returns {HTMLElement[] | HTMLImageElement[]} - A list of nodes that are either image tags or have a background image.
|
|
7
|
-
*/
|
|
8
|
-
export function findMeasurableElements(nodes) {
|
|
9
|
-
return nodes.filter((el) => {
|
|
10
|
-
if (el instanceof HTMLImageElement) {
|
|
11
|
-
return true;
|
|
12
|
-
}
|
|
13
|
-
if (el instanceof HTMLElement) {
|
|
14
|
-
const style = getComputedStyle(el);
|
|
15
|
-
return 'none' !== style.backgroundImage;
|
|
16
|
-
}
|
|
17
|
-
return false;
|
|
18
|
-
});
|
|
19
|
-
}
|
|
20
|
-
/**
|
|
21
|
-
* Get the current image source from a node.
|
|
22
|
-
*
|
|
23
|
-
* @param {HTMLImageElement} node - HTMLImageElement
|
|
24
|
-
* @returns {string | null} - The URL of the image or null if it can't be determined.
|
|
25
|
-
*/
|
|
26
|
-
export function imageTagSource(node) {
|
|
27
|
-
if (imageLikeURL(node.currentSrc)) {
|
|
28
|
-
return node.currentSrc;
|
|
29
|
-
}
|
|
30
|
-
if (imageLikeURL(node.src)) {
|
|
31
|
-
return node.src;
|
|
32
|
-
}
|
|
33
|
-
return null;
|
|
34
|
-
}
|
|
35
|
-
/**
|
|
36
|
-
* Get the background image URL from a node.
|
|
37
|
-
*
|
|
38
|
-
* @param {HTMLImageElement} node - HTMLElement
|
|
39
|
-
* @returns {string | null} - The URL of the image or null if it can't be determined.
|
|
40
|
-
*/
|
|
41
|
-
export function backgroundImageSource(node) {
|
|
42
|
-
const src = getComputedStyle(node).backgroundImage;
|
|
43
|
-
const url = src.match(/url\(.?(.*?).?\)/i);
|
|
44
|
-
if (url && url[1] && imageLikeURL(url[1])) {
|
|
45
|
-
return url[1];
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
/**
|
|
49
|
-
* Create MeasurableImage objects from a list of nodes
|
|
50
|
-
* and remove any nodes that can't be measured.
|
|
51
|
-
*
|
|
52
|
-
* @param {Element[]} domNodes - A list of nodes to measure
|
|
53
|
-
* @returns {MeasurableImage[]} - A list of MeasurableImage objects.
|
|
54
|
-
*/
|
|
55
|
-
export function getMeasurableImages(domNodes) {
|
|
56
|
-
const nodes = findMeasurableElements(domNodes);
|
|
57
|
-
return nodes
|
|
58
|
-
.map(node => {
|
|
59
|
-
if (node instanceof HTMLImageElement) {
|
|
60
|
-
return new MeasurableImage(node, imageTagSource);
|
|
61
|
-
}
|
|
62
|
-
else if (node instanceof HTMLElement) {
|
|
63
|
-
if (!backgroundImageSource(node)) {
|
|
64
|
-
/**
|
|
65
|
-
* Background elements that have no valid URL
|
|
66
|
-
* shouldn't be measured.
|
|
67
|
-
*/
|
|
68
|
-
return null;
|
|
69
|
-
}
|
|
70
|
-
return new MeasurableImage(node, backgroundImageSource);
|
|
71
|
-
}
|
|
72
|
-
return null;
|
|
73
|
-
})
|
|
74
|
-
.filter(image => image !== null);
|
|
75
|
-
}
|
|
76
|
-
/**
|
|
77
|
-
* isImageLikeURL - a helper function to determine if URL could be an image.
|
|
78
|
-
*
|
|
79
|
-
* This function ensures that the value passed in looks like a URL.
|
|
80
|
-
* This is because `background: url(...)` and `src="..."` can
|
|
81
|
-
* contain various values that are not URLs, like:
|
|
82
|
-
* - none
|
|
83
|
-
* - linear-gradient(...)
|
|
84
|
-
* - data:image/png;base64,...
|
|
85
|
-
* - ...
|
|
86
|
-
*
|
|
87
|
-
* For the purposes of analyzing image sizes,
|
|
88
|
-
* we also don't consider SVGs to be images.
|
|
89
|
-
*
|
|
90
|
-
* @param {string} value - string to check
|
|
91
|
-
* @returns {boolean} - true if the value looks like a URL
|
|
92
|
-
*/
|
|
93
|
-
function imageLikeURL(value) {
|
|
94
|
-
// Look for relative URLs that are not SVGs
|
|
95
|
-
// Intentionally not using an allow-list because images may
|
|
96
|
-
// be served from weird URLs like /images/1234?size=large
|
|
97
|
-
if (value.startsWith('/')) {
|
|
98
|
-
// Remove query string parameters
|
|
99
|
-
const path = value.split('?')[0];
|
|
100
|
-
return !path.endsWith('.svg');
|
|
101
|
-
}
|
|
102
|
-
try {
|
|
103
|
-
const url = new URL(value);
|
|
104
|
-
return url.protocol === 'http:' || url.protocol === 'https:';
|
|
105
|
-
}
|
|
106
|
-
catch (e) {
|
|
107
|
-
return false;
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
//# sourceMappingURL=find-image-elements.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"find-image-elements.js","sourceRoot":"","sources":["../src/find-image-elements.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEpD;;;;;GAKG;AACH,MAAM,UAAU,sBAAsB,CAAE,KAAgB;IACvD,OAAO,KAAK,CAAC,MAAM,CAAE,CAAE,EAAE,EAAyC,EAAE;QACnE,IAAK,EAAE,YAAY,gBAAgB,EAAG;YACrC,OAAO,IAAI,CAAC;SACZ;QACD,IAAK,EAAE,YAAY,WAAW,EAAG;YAChC,MAAM,KAAK,GAAG,gBAAgB,CAAE,EAAE,CAAE,CAAC;YACrC,OAAO,MAAM,KAAK,KAAK,CAAC,eAAe,CAAC;SACxC;QACD,OAAO,KAAK,CAAC;IACd,CAAC,CAAE,CAAC;AACL,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAE,IAAsB;IACrD,IAAK,YAAY,CAAE,IAAI,CAAC,UAAU,CAAE,EAAG;QACtC,OAAO,IAAI,CAAC,UAAU,CAAC;KACvB;IACD,IAAK,YAAY,CAAE,IAAI,CAAC,GAAG,CAAE,EAAG;QAC/B,OAAO,IAAI,CAAC,GAAG,CAAC;KAChB;IAED,OAAO,IAAI,CAAC;AACb,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CAAE,IAAiB;IACvD,MAAM,GAAG,GAAG,gBAAgB,CAAE,IAAI,CAAE,CAAC,eAAe,CAAC;IACrD,MAAM,GAAG,GAAG,GAAG,CAAC,KAAK,CAAE,mBAAmB,CAAE,CAAC;IAC7C,IAAK,GAAG,IAAI,GAAG,CAAE,CAAC,CAAE,IAAI,YAAY,CAAE,GAAG,CAAE,CAAC,CAAE,CAAE,EAAG;QAClD,OAAO,GAAG,CAAE,CAAC,CAAE,CAAC;KAChB;AACF,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,mBAAmB,CAAE,QAAmB;IACvD,MAAM,KAAK,GAAG,sBAAsB,CAAE,QAAQ,CAAE,CAAC;IACjD,OAAO,KAAK;SACV,GAAG,CAAE,IAAI,CAAC,EAAE;QACZ,IAAK,IAAI,YAAY,gBAAgB,EAAG;YACvC,OAAO,IAAI,eAAe,CAAE,IAAI,EAAE,cAAc,CAAE,CAAC;SACnD;aAAM,IAAK,IAAI,YAAY,WAAW,EAAG;YACzC,IAAK,CAAE,qBAAqB,CAAE,IAAI,CAAE,EAAG;gBACtC;;;mBAGG;gBACH,OAAO,IAAI,CAAC;aACZ;YAED,OAAO,IAAI,eAAe,CAAE,IAAI,EAAE,qBAAqB,CAAE,CAAC;SAC1D;QAED,OAAO,IAAI,CAAC;IACb,CAAC,CAAE;SACF,MAAM,CAAE,KAAK,CAAC,EAAE,CAAC,KAAK,KAAK,IAAI,CAAE,CAAC;AACrC,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,SAAS,YAAY,CAAE,KAAa;IACnC,2CAA2C;IAC3C,2DAA2D;IAC3D,yDAAyD;IACzD,IAAK,KAAK,CAAC,UAAU,CAAE,GAAG,CAAE,EAAG;QAC9B,iCAAiC;QACjC,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAE,GAAG,CAAE,CAAE,CAAC,CAAE,CAAC;QACrC,OAAO,CAAE,IAAI,CAAC,QAAQ,CAAE,MAAM,CAAE,CAAC;KACjC;IAED,IAAI;QACH,MAAM,GAAG,GAAG,IAAI,GAAG,CAAE,KAAK,CAAE,CAAC;QAC7B,OAAO,GAAG,CAAC,QAAQ,KAAK,OAAO,IAAI,GAAG,CAAC,QAAQ,KAAK,QAAQ,CAAC;KAC7D;IAAC,OAAQ,CAAC,EAAG;QACb,OAAO,KAAK,CAAC;KACb;AACF,CAAC"}
|
package/build/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,eAAe,EAAU,MAAM,mBAAmB,CAAC;AACxE,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAE5D,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,CAAC"}
|