this should do it

pull/8868/head
Simon Holthausen 3 years ago
parent 015b7ae7d7
commit 5b4356c9b3

@ -74,9 +74,11 @@ let src_url_equal_anchor;
* @returns {boolean} * @returns {boolean}
*/ */
export function src_url_equal(element_src, url) { export function src_url_equal(element_src, url) {
if (element_src === url) return true;
if (!src_url_equal_anchor) { if (!src_url_equal_anchor) {
src_url_equal_anchor = document.createElement('a'); src_url_equal_anchor = document.createElement('a');
} }
// This is actually faster than doing URL(..).href
src_url_equal_anchor.href = url; src_url_equal_anchor.href = url;
return element_src === src_url_equal_anchor.href; return element_src === src_url_equal_anchor.href;
} }
@ -89,7 +91,7 @@ export function src_url_equal(element_src, url) {
export function srcset_url_equal(element_srcset, srcset) { export function srcset_url_equal(element_srcset, srcset) {
/** @param {string} _srcset */ /** @param {string} _srcset */
function split(_srcset) { function split(_srcset) {
return _srcset.split(',').map((src) => src.trim().split(' ')[0]); return _srcset.split(',').map((src) => src.trim().split(' ').filter(Boolean));
} }
const element_urls = split(element_srcset.srcset); const element_urls = split(element_srcset.srcset);
@ -97,7 +99,14 @@ export function srcset_url_equal(element_srcset, srcset) {
return ( return (
urls.length === element_urls.length && urls.length === element_urls.length &&
urls.every((url, i) => src_url_equal(element_urls[i], url)) urls.every(
([url, width], i) =>
width === element_urls[i][1] &&
// We need to test both ways because Vite/imagetools (but not other tools) will create an absolute URL
// for the client, and the relative URLs inside srcset are not automatically resolved to absolute URLs
// by browsers (in contrast to img.src). This means both SSR and DOM code could contain relative or absolute URLs.
(src_url_equal(element_urls[i][0], url) || src_url_equal(url, element_urls[i][0]))
)
); );
} }

@ -1,4 +1,4 @@
import { assert, describe, it } from 'vitest'; import { afterAll, assert, beforeAll, describe, it } from 'vitest';
import '../../src/compiler/compile/nodes/Slot.js'; // this needs to come first to force ESM to load things in a specific order to prevent circular dependency errors import '../../src/compiler/compile/nodes/Slot.js'; // this needs to come first to force ESM to load things in a specific order to prevent circular dependency errors
import { import {
CONTENTEDITABLE_BINDINGS, CONTENTEDITABLE_BINDINGS,
@ -9,7 +9,7 @@ import {
} from '../../src/compiler/compile/utils/contenteditable.js'; } from '../../src/compiler/compile/utils/contenteditable.js';
import get_name_from_filename from '../../src/compiler/compile/utils/get_name_from_filename.js'; import get_name_from_filename from '../../src/compiler/compile/utils/get_name_from_filename.js';
import { trim_end, trim_start } from '../../src/compiler/utils/trim.js'; import { trim_end, trim_start } from '../../src/compiler/utils/trim.js';
import { split_css_unit } from '../../src/runtime/internal/utils.js'; import { split_css_unit, srcset_url_equal } from '../../src/runtime/internal/utils.js';
describe('utils', () => { describe('utils', () => {
describe('trim', () => { describe('trim', () => {
@ -116,4 +116,51 @@ describe('utils', () => {
}); });
}); });
}); });
describe('srcset_url_equal', () => {
function create_element(srcset) {
return /** @type {HTMLImageElement} */ ({
srcset
});
}
beforeAll(() => {
let host = 'https://svelte.dev';
let _href = '';
// @ts-ignore
global.document = {
createElement: () =>
/** @type {any} */ ({
get href() {
return _href;
},
set href(value) {
_href = host + value;
}
})
};
});
afterAll(() => {
// @ts-ignore
delete global.document;
});
it('should return true if urls are equal', () => {
assert.ok(srcset_url_equal(create_element('a'), 'a'));
assert.ok(srcset_url_equal(create_element('a 1x'), 'a 1x'));
assert.ok(srcset_url_equal(create_element('a 1x, b 2x'), 'a 1x, b 2x'));
assert.ok(srcset_url_equal(create_element('a 1x, b 2x'), 'a 1x, b 2x'));
});
it('should return true if urls are equal (abs/rel URLs)', () => {
assert.ok(srcset_url_equal(create_element('https://svelte.dev/a'), '/a'));
assert.ok(srcset_url_equal(create_element('/a'), 'https://svelte.dev/a'));
});
it('should return false if urls are different', () => {
assert.notOk(srcset_url_equal(create_element('a 1x'), 'b 1x'));
assert.notOk(srcset_url_equal(create_element('a 2x'), 'a 1x'));
});
});
}); });

Loading…
Cancel
Save