@automattic/jetpack-image-guide 0.3.0 → 0.5.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 +20 -0
- package/build/MeasurableImage.d.ts +11 -1
- package/build/find-image-elements.d.ts +3 -2
- package/build/index.asset.php +1 -1
- package/build/index.js +1 -1
- package/package.json +1 -1
- package/src/MeasurableImage.ts +32 -11
- package/src/find-image-elements.ts +30 -22
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,23 @@ 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.5.0] - 2023-07-07
|
|
9
|
+
### Added
|
|
10
|
+
- Boost: exclude small images from Image Size Analysis [#31504]
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
- Return an error when an image is missing, instead of -1 by -1 dimensions. [#31632]
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
- Check response.url, not response.ok to verify a response worked [#31538]
|
|
17
|
+
|
|
18
|
+
## [0.4.0] - 2023-06-23
|
|
19
|
+
### Added
|
|
20
|
+
- Jetpack Boost: add a proxy to Image Guide so it can load remote images. [#31145]
|
|
21
|
+
|
|
22
|
+
### Fixed
|
|
23
|
+
- Improved image url validation for background image source. [#31410]
|
|
24
|
+
|
|
8
25
|
## 0.3.0 - 2023-05-11
|
|
9
26
|
### Changed
|
|
10
27
|
- Set `exports` in package.json. This will break directly requiring files from within the package in environments that respect `exports`. [#30313]
|
|
@@ -41,3 +58,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
41
58
|
|
|
42
59
|
### Removed
|
|
43
60
|
- Minor package.json change - removing private entry.
|
|
61
|
+
|
|
62
|
+
[0.5.0]: https://github.com/Automattic/jetpack-image-guide/compare/v0.4.0...v0.5.0
|
|
63
|
+
[0.4.0]: https://github.com/Automattic/jetpack-image-guide/compare/v0.3.0...v0.4.0
|
|
@@ -6,6 +6,7 @@ export type Dimensions = {
|
|
|
6
6
|
export type Weight = {
|
|
7
7
|
weight: number;
|
|
8
8
|
};
|
|
9
|
+
export type FetchFn = (input: URL | RequestInfo, init?: RequestInit) => Promise<Response>;
|
|
9
10
|
/**
|
|
10
11
|
* A class that represents a DOM Element that
|
|
11
12
|
* has an image that should be measured and
|
|
@@ -14,13 +15,15 @@ export type Weight = {
|
|
|
14
15
|
export declare class MeasurableImage {
|
|
15
16
|
readonly node: HTMLElement | HTMLImageElement;
|
|
16
17
|
private getURLCallback;
|
|
18
|
+
fetch: FetchFn;
|
|
17
19
|
/**
|
|
18
20
|
* Constructor.
|
|
19
21
|
*
|
|
20
22
|
* @param {HTMLElement | HTMLImageElement} node - The DOM Element that contains the image.
|
|
21
23
|
* @param {SourceCallbackFn} getURL - A function that takes in the node and returns the URL of the image.
|
|
24
|
+
* @param {FetchFn} fetchFn - A function that fetches a URL and returns a Promise.
|
|
22
25
|
*/
|
|
23
|
-
constructor(node: HTMLElement | HTMLImageElement, getURL: SourceCallbackFn);
|
|
26
|
+
constructor(node: HTMLElement | HTMLImageElement, getURL: SourceCallbackFn, fetchFn?: FetchFn | null);
|
|
24
27
|
getURL(): string;
|
|
25
28
|
getSizeOnPage(): {
|
|
26
29
|
width: number;
|
|
@@ -58,4 +61,11 @@ export declare class MeasurableImage {
|
|
|
58
61
|
* @param {string} url - image url
|
|
59
62
|
*/
|
|
60
63
|
private fetchFileDimensions;
|
|
64
|
+
/**
|
|
65
|
+
* Checks if the image is too small and should be ignored. Will return false on images
|
|
66
|
+
* that don't load at all - we can't establish they're tiny!
|
|
67
|
+
*
|
|
68
|
+
* @returns {boolean} - if the image is smaller than 65 pixels width and height return true
|
|
69
|
+
*/
|
|
70
|
+
isImageTiny(): Promise<boolean>;
|
|
61
71
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { MeasurableImage } from './MeasurableImage';
|
|
1
|
+
import { FetchFn, MeasurableImage } from './MeasurableImage';
|
|
2
2
|
/**
|
|
3
3
|
* Get elements that either are image tags or have a background image.
|
|
4
4
|
*
|
|
@@ -25,6 +25,7 @@ export declare function backgroundImageSource(node: HTMLElement): string;
|
|
|
25
25
|
* and remove any nodes that can't be measured.
|
|
26
26
|
*
|
|
27
27
|
* @param {Element[]} domNodes - A list of nodes to measure
|
|
28
|
+
* @param {(input: string, init?: Array) => Promise<Response>} fetchFn - A function that fetches a URL and returns a Promise.
|
|
28
29
|
* @returns {MeasurableImage[]} - A list of MeasurableImage objects.
|
|
29
30
|
*/
|
|
30
|
-
export declare function getMeasurableImages(domNodes: Element[]): MeasurableImage[]
|
|
31
|
+
export declare function getMeasurableImages(domNodes: Element[], fetchFn?: FetchFn | null): Promise<MeasurableImage[]>;
|
package/build/index.asset.php
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
<?php return array('dependencies' => array(), 'version' => '
|
|
1
|
+
<?php return array('dependencies' => array(), 'version' => '001cd98ea4ed0b8489db');
|
package/build/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
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(a){return function(c){return function(a){if(n)throw new TypeError("Generator is already executing.");for(;i&&(i=0,a[0]&&(u=0)),u;)try{if(n=1,r&&(o=2&a[0]?r.return:a[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,a[1])).done)return o;switch(r=0,o&&(a=[2&a[0],o.value]),a[0]){case 0:case 1:o=a;break;case 4:return u.label++,{value:a[1],done:!1};case 5:u.label++,r=a[1],a=[0];continue;case 7:a=u.ops.pop(),u.trys.pop();continue;default:if(!(o=u.trys,(o=o.length>0&&o[o.length-1])||6!==a[0]&&2!==a[0])){u=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]<o[3])){u.label=a[1];break}if(6===a[0]&&u.label<o[1]){u.label=o[1],o=a;break}if(o&&u.label<o[2]){u.label=o[2],u.ops.push(a);break}o[2]&&u.ops.pop(),u.trys.pop();continue}a=e.call(t,u)}catch(t){a=[6,t],r=0}finally{n=o=0}if(5&a[0])throw a[1];return{value:a[0]?a[1]:void 0,done:!0}}([a,c])}}},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
|
|
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(a){return function(c){return function(a){if(n)throw new TypeError("Generator is already executing.");for(;i&&(i=0,a[0]&&(u=0)),u;)try{if(n=1,r&&(o=2&a[0]?r.return:a[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,a[1])).done)return o;switch(r=0,o&&(a=[2&a[0],o.value]),a[0]){case 0:case 1:o=a;break;case 4:return u.label++,{value:a[1],done:!1};case 5:u.label++,r=a[1],a=[0];continue;case 7:a=u.ops.pop(),u.trys.pop();continue;default:if(!(o=u.trys,(o=o.length>0&&o[o.length-1])||6!==a[0]&&2!==a[0])){u=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]<o[3])){u.label=a[1];break}if(6===a[0]&&u.label<o[1]){u.label=o[1],o=a;break}if(o&&u.label<o[2]){u.label=o[2],u.ops.push(a);break}o[2]&&u.ops.pop(),u.trys.pop();continue}a=e.call(t,u)}catch(t){a=[6,t],r=0}finally{n=o=0}if(5&a[0])throw a[1];return{value:a[0]?a[1]:void 0,done:!0}}([a,c])}}},i=function(){function t(t,e,n){void 0===n&&(n=null),this.node=t,this.getURLCallback=e,this.fetch=null!=n?n:window.fetch.bind(window)}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;return o(this,(function(n){switch(n.label){case 0:return[4,this.fetch(t)];case 1:return(e=n.sent()).ok?[2,parseInt(e.headers.get("content-length"),10)/1024]:(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,n){e.onload=function(){t({width:Math.round(e.width),height:Math.round(e.height)})},e.onerror=function(){n("Unable to load image.")}}))]}))}))},t.prototype.isImageTiny=function(){return r(this,void 0,void 0,(function(){var t,e;return o(this,(function(n){switch(n.label){case 0:return n.trys.push([0,2,,3]),t=65,[4,this.fetchFileDimensions(this.getURL())];case 1:return[2,(e=n.sent()).width<t||e.height<t];case 2:return n.sent(),[2,!1];case 3:return[2]}}))}))},t}()},705:(t,e,n)=>{n.d(e,{RK:()=>c});var r=n(38),o=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())}))},i=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(a){return function(c){return function(a){if(n)throw new TypeError("Generator is already executing.");for(;i&&(i=0,a[0]&&(u=0)),u;)try{if(n=1,r&&(o=2&a[0]?r.return:a[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,a[1])).done)return o;switch(r=0,o&&(a=[2&a[0],o.value]),a[0]){case 0:case 1:o=a;break;case 4:return u.label++,{value:a[1],done:!1};case 5:u.label++,r=a[1],a=[0];continue;case 7:a=u.ops.pop(),u.trys.pop();continue;default:if(!(o=u.trys,(o=o.length>0&&o[o.length-1])||6!==a[0]&&2!==a[0])){u=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]<o[3])){u.label=a[1];break}if(6===a[0]&&u.label<o[1]){u.label=o[1],o=a;break}if(o&&u.label<o[2]){u.label=o[2],u.ops.push(a);break}o[2]&&u.ops.pop(),u.trys.pop();continue}a=e.call(t,u)}catch(t){a=[6,t],r=0}finally{n=o=0}if(5&a[0])throw a[1];return{value:a[0]?a[1]:void 0,done:!0}}([a,c])}}};function u(t){return l(t.currentSrc)?t.currentSrc:l(t.src)?t.src:null}function a(t){var e=getComputedStyle(t).backgroundImage.match(/url\(\s*(['"])(.*?)\1\s*\)/i),n=window.location.href.split("#")[0];return e&&e[2]&&e[2]!==n&&l(e[2])?e[2]:null}function c(t,e){return void 0===e&&(e=null),o(this,void 0,void 0,(function(){var n;return i(this,(function(o){return n=function(t){return t.filter((function(t){return t instanceof HTMLImageElement||t instanceof HTMLElement&&"none"!==getComputedStyle(t).backgroundImage}))}(t),[2,n.map((function(t){return t instanceof HTMLImageElement?new r.z(t,u,e):t instanceof HTMLElement&&a(t)?new r.z(t,a):null}))]}))}))}function l(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.5.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",
|
package/src/MeasurableImage.ts
CHANGED
|
@@ -2,6 +2,8 @@ export type SourceCallbackFn = ( node: HTMLElement ) => string | null;
|
|
|
2
2
|
export type Dimensions = { width: number; height: number };
|
|
3
3
|
export type Weight = { weight: number };
|
|
4
4
|
|
|
5
|
+
export type FetchFn = ( input: URL | RequestInfo, init?: RequestInit ) => Promise< Response >;
|
|
6
|
+
|
|
5
7
|
/**
|
|
6
8
|
* A class that represents a DOM Element that
|
|
7
9
|
* has an image that should be measured and
|
|
@@ -11,15 +13,23 @@ export class MeasurableImage {
|
|
|
11
13
|
readonly node: HTMLElement | HTMLImageElement;
|
|
12
14
|
private getURLCallback: SourceCallbackFn;
|
|
13
15
|
|
|
16
|
+
public fetch: FetchFn;
|
|
17
|
+
|
|
14
18
|
/**
|
|
15
19
|
* Constructor.
|
|
16
20
|
*
|
|
17
21
|
* @param {HTMLElement | HTMLImageElement} node - The DOM Element that contains the image.
|
|
18
22
|
* @param {SourceCallbackFn} getURL - A function that takes in the node and returns the URL of the image.
|
|
23
|
+
* @param {FetchFn} fetchFn - A function that fetches a URL and returns a Promise.
|
|
19
24
|
*/
|
|
20
|
-
constructor(
|
|
25
|
+
constructor(
|
|
26
|
+
node: HTMLElement | HTMLImageElement,
|
|
27
|
+
getURL: SourceCallbackFn,
|
|
28
|
+
fetchFn: FetchFn | null = null
|
|
29
|
+
) {
|
|
21
30
|
this.node = node;
|
|
22
31
|
this.getURLCallback = getURL;
|
|
32
|
+
this.fetch = fetchFn ?? window.fetch.bind( window );
|
|
23
33
|
}
|
|
24
34
|
|
|
25
35
|
public getURL() {
|
|
@@ -83,19 +93,14 @@ export class MeasurableImage {
|
|
|
83
93
|
* @param {string} url - string The URL of the image.
|
|
84
94
|
*/
|
|
85
95
|
private async fetchFileWeight( url: string ) {
|
|
86
|
-
const response = await fetch( url
|
|
87
|
-
if ( ! response.
|
|
96
|
+
const response = await this.fetch( url );
|
|
97
|
+
if ( ! response.ok ) {
|
|
88
98
|
// eslint-disable-next-line no-console
|
|
89
99
|
console.log( `Can't get image size for ${ url } likely due to a CORS error.` );
|
|
90
100
|
return -1;
|
|
91
101
|
}
|
|
92
102
|
|
|
93
|
-
|
|
94
|
-
if ( size ) {
|
|
95
|
-
return parseInt( size, 10 ) / 1024;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
return -1;
|
|
103
|
+
return parseInt( response.headers.get( 'content-length' ), 10 ) / 1024;
|
|
99
104
|
}
|
|
100
105
|
|
|
101
106
|
/**
|
|
@@ -107,13 +112,29 @@ export class MeasurableImage {
|
|
|
107
112
|
private async fetchFileDimensions( url: string ) {
|
|
108
113
|
const img = new Image();
|
|
109
114
|
img.src = url;
|
|
110
|
-
return new Promise< { width: number; height: number } >( resolve => {
|
|
115
|
+
return new Promise< { width: number; height: number } >( ( resolve, reject ) => {
|
|
111
116
|
img.onload = () => {
|
|
112
117
|
resolve( { width: Math.round( img.width ), height: Math.round( img.height ) } );
|
|
113
118
|
};
|
|
114
119
|
img.onerror = () => {
|
|
115
|
-
|
|
120
|
+
reject( 'Unable to load image.' );
|
|
116
121
|
};
|
|
117
122
|
} );
|
|
118
123
|
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Checks if the image is too small and should be ignored. Will return false on images
|
|
127
|
+
* that don't load at all - we can't establish they're tiny!
|
|
128
|
+
*
|
|
129
|
+
* @returns {boolean} - if the image is smaller than 65 pixels width and height return true
|
|
130
|
+
*/
|
|
131
|
+
public async isImageTiny(): Promise< boolean > {
|
|
132
|
+
try {
|
|
133
|
+
const minSize = 65;
|
|
134
|
+
const dimensions = await this.fetchFileDimensions( this.getURL() );
|
|
135
|
+
return dimensions.width < minSize || dimensions.height < minSize;
|
|
136
|
+
} catch ( err ) {
|
|
137
|
+
return false;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
119
140
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { MeasurableImage } from './MeasurableImage';
|
|
1
|
+
import { FetchFn, MeasurableImage } from './MeasurableImage';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Get elements that either are image tags or have a background image.
|
|
@@ -44,9 +44,13 @@ export function imageTagSource( node: HTMLImageElement ) {
|
|
|
44
44
|
*/
|
|
45
45
|
export function backgroundImageSource( node: HTMLElement ) {
|
|
46
46
|
const src = getComputedStyle( node ).backgroundImage;
|
|
47
|
-
const url = src.match( /url\(
|
|
48
|
-
|
|
49
|
-
|
|
47
|
+
const url = src.match( /url\(\s*(['"])(.*?)\1\s*\)/i );
|
|
48
|
+
|
|
49
|
+
// If background image is `url('')`, the computed value becomes the current page URL. So we need to check for that.
|
|
50
|
+
const currentUrlWithoutHash = window.location.href.split( '#' )[ 0 ];
|
|
51
|
+
|
|
52
|
+
if ( url && url[ 2 ] && url[ 2 ] !== currentUrlWithoutHash && imageLikeURL( url[ 2 ] ) ) {
|
|
53
|
+
return url[ 2 ];
|
|
50
54
|
}
|
|
51
55
|
return null;
|
|
52
56
|
}
|
|
@@ -56,29 +60,33 @@ export function backgroundImageSource( node: HTMLElement ) {
|
|
|
56
60
|
* and remove any nodes that can't be measured.
|
|
57
61
|
*
|
|
58
62
|
* @param {Element[]} domNodes - A list of nodes to measure
|
|
63
|
+
* @param {(input: string, init?: Array) => Promise<Response>} fetchFn - A function that fetches a URL and returns a Promise.
|
|
59
64
|
* @returns {MeasurableImage[]} - A list of MeasurableImage objects.
|
|
60
65
|
*/
|
|
61
|
-
export function getMeasurableImages(
|
|
66
|
+
export async function getMeasurableImages(
|
|
67
|
+
domNodes: Element[],
|
|
68
|
+
fetchFn: FetchFn | null = null
|
|
69
|
+
): Promise< MeasurableImage[] > {
|
|
62
70
|
const nodes = findMeasurableElements( domNodes );
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
return null;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
return new MeasurableImage( node, backgroundImageSource );
|
|
71
|
+
const images = nodes.map( node => {
|
|
72
|
+
if ( node instanceof HTMLImageElement ) {
|
|
73
|
+
return new MeasurableImage( node, imageTagSource, fetchFn );
|
|
74
|
+
} else if ( node instanceof HTMLElement ) {
|
|
75
|
+
if ( ! backgroundImageSource( node ) ) {
|
|
76
|
+
/**
|
|
77
|
+
* Background elements that have no valid URL
|
|
78
|
+
* shouldn't be measured.
|
|
79
|
+
*/
|
|
80
|
+
return null;
|
|
77
81
|
}
|
|
78
82
|
|
|
79
|
-
return
|
|
80
|
-
}
|
|
81
|
-
|
|
83
|
+
return new MeasurableImage( node, backgroundImageSource );
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return null;
|
|
87
|
+
} );
|
|
88
|
+
|
|
89
|
+
return images;
|
|
82
90
|
}
|
|
83
91
|
|
|
84
92
|
/**
|