Merge pull request #13084 from ahocevar/normalize-urls

Normalize relative sprite and glyph urls for style url
This commit is contained in:
Andreas Hocevar
2021-12-04 17:35:09 +01:00
committed by GitHub
2 changed files with 53 additions and 16 deletions
+34 -15
View File
@@ -35,13 +35,14 @@ export function getMapboxPath(url) {
* Turns mapbox:// sprite URLs into resolvable URLs. * Turns mapbox:// sprite URLs into resolvable URLs.
* @param {string} url The sprite URL. * @param {string} url The sprite URL.
* @param {string} token The access token. * @param {string} token The access token.
* @param {string} styleUrl The style URL.
* @return {string} A resolvable URL. * @return {string} A resolvable URL.
* @private * @private
*/ */
export function normalizeSpriteUrl(url, token) { export function normalizeSpriteUrl(url, token, styleUrl) {
const mapboxPath = getMapboxPath(url); const mapboxPath = getMapboxPath(url);
if (!mapboxPath) { if (!mapboxPath) {
return url; return decodeURI(new URL(url, styleUrl).href);
} }
const startsWith = 'sprites/'; const startsWith = 'sprites/';
if (mapboxPath.indexOf(startsWith) !== 0) { if (mapboxPath.indexOf(startsWith) !== 0) {
@@ -56,13 +57,14 @@ export function normalizeSpriteUrl(url, token) {
* Turns mapbox:// glyphs URLs into resolvable URLs. * Turns mapbox:// glyphs URLs into resolvable URLs.
* @param {string} url The glyphs URL. * @param {string} url The glyphs URL.
* @param {string} token The access token. * @param {string} token The access token.
* @param {string} styleUrl The style URL.
* @return {string} A resolvable URL. * @return {string} A resolvable URL.
* @private * @private
*/ */
export function normalizeGlyphsUrl(url, token) { export function normalizeGlyphsUrl(url, token, styleUrl) {
const mapboxPath = getMapboxPath(url); const mapboxPath = getMapboxPath(url);
if (!mapboxPath) { if (!mapboxPath) {
return url; return decodeURI(new URL(url, styleUrl).href);
} }
const startsWith = 'fonts/'; const startsWith = 'fonts/';
if (mapboxPath.indexOf(startsWith) !== 0) { if (mapboxPath.indexOf(startsWith) !== 0) {
@@ -83,7 +85,7 @@ export function normalizeGlyphsUrl(url, token) {
export function normalizeStyleUrl(url, token) { export function normalizeStyleUrl(url, token) {
const mapboxPath = getMapboxPath(url); const mapboxPath = getMapboxPath(url);
if (!mapboxPath) { if (!mapboxPath) {
return url; return decodeURI(new URL(url, location.href).href);
} }
const startsWith = 'styles/'; const startsWith = 'styles/';
if (mapboxPath.indexOf(startsWith) !== 0) { if (mapboxPath.indexOf(startsWith) !== 0) {
@@ -99,16 +101,17 @@ export function normalizeStyleUrl(url, token) {
* @param {string} url The source URL. * @param {string} url The source URL.
* @param {string} token The access token. * @param {string} token The access token.
* @param {string} tokenParam The access token key. * @param {string} tokenParam The access token key.
* @param {string} styleUrl The style URL.
* @return {string} A vector tile template. * @return {string} A vector tile template.
* @private * @private
*/ */
export function normalizeSourceUrl(url, token, tokenParam) { export function normalizeSourceUrl(url, token, tokenParam, styleUrl) {
const urlObject = new URL(url, styleUrl);
const mapboxPath = getMapboxPath(url); const mapboxPath = getMapboxPath(url);
if (!mapboxPath) { if (!mapboxPath) {
if (!token) { if (!token) {
return url; return decodeURI(urlObject.href);
} }
const urlObject = new URL(url, location.href);
urlObject.searchParams.set(tokenParam, token); urlObject.searchParams.set(tokenParam, token);
return decodeURI(urlObject.href); return decodeURI(urlObject.href);
} }
@@ -336,7 +339,7 @@ class MapboxVectorLayer extends VectorTileLayer {
return response.json(); return response.json();
}) })
.then((style) => { .then((style) => {
this.onStyleLoad(style); this.onStyleLoad(style, url.startsWith('data:') ? location.href : url);
}) })
.catch((error) => { .catch((error) => {
this.handleError(error); this.handleError(error);
@@ -346,9 +349,10 @@ class MapboxVectorLayer extends VectorTileLayer {
/** /**
* Handle the loaded style object. * Handle the loaded style object.
* @param {StyleObject} style The loaded style. * @param {StyleObject} style The loaded style.
* @param {string} styleUrl The URL of the style.
* @protected * @protected
*/ */
onStyleLoad(style) { onStyleLoad(style, styleUrl) {
let sourceId; let sourceId;
let sourceIdOrLayersList; let sourceIdOrLayersList;
if (this.layers) { if (this.layers) {
@@ -394,11 +398,19 @@ class MapboxVectorLayer extends VectorTileLayer {
} }
if (style.sprite) { if (style.sprite) {
style.sprite = normalizeSpriteUrl(style.sprite, this.accessToken); style.sprite = normalizeSpriteUrl(
style.sprite,
this.accessToken,
styleUrl
);
} }
if (style.glyphs) { if (style.glyphs) {
style.glyphs = normalizeGlyphsUrl(style.glyphs, this.accessToken); style.glyphs = normalizeGlyphsUrl(
style.glyphs,
this.accessToken,
styleUrl
);
} }
const styleSource = style.sources[sourceId]; const styleSource = style.sources[sourceId];
@@ -416,7 +428,8 @@ class MapboxVectorLayer extends VectorTileLayer {
normalizeSourceUrl( normalizeSourceUrl(
styleSource.url, styleSource.url,
this.accessToken, this.accessToken,
this.accessTokenParam_ this.accessTokenParam_,
styleUrl
) )
); );
applyStyle(this, style, sourceIdOrLayersList) applyStyle(this, style, sourceIdOrLayersList)
@@ -430,7 +443,12 @@ class MapboxVectorLayer extends VectorTileLayer {
// TileJSON url, let ol-mapbox-style handle it // TileJSON url, let ol-mapbox-style handle it
if (styleSource.tiles) { if (styleSource.tiles) {
styleSource.tiles = styleSource.tiles.map((url) => styleSource.tiles = styleSource.tiles.map((url) =>
normalizeSourceUrl(url, this.accessToken, this.accessTokenParam_) normalizeSourceUrl(
url,
this.accessToken,
this.accessTokenParam_,
styleUrl
)
); );
} }
setupVectorSource( setupVectorSource(
@@ -439,7 +457,8 @@ class MapboxVectorLayer extends VectorTileLayer {
? normalizeSourceUrl( ? normalizeSourceUrl(
styleSource.url, styleSource.url,
this.accessToken, this.accessToken,
this.accessTokenParam_ this.accessTokenParam_,
styleUrl
) )
: undefined : undefined
).then((source) => { ).then((source) => {
@@ -63,12 +63,30 @@ describe('ol/layer/MapboxVector', () => {
url: 'https://example.com/sprite', url: 'https://example.com/sprite',
expected: 'https://example.com/sprite', expected: 'https://example.com/sprite',
}, },
{
url: '../sprite',
expected: 'https://example.com:8000/sprite',
},
{
url: '/sprite',
expected: 'https://example.com:8000/sprite',
},
{
url: './sprite',
expected: 'https://example.com:8000/mystyle/sprite',
},
]; ];
const token = 'test-token'; const token = 'test-token';
for (const c of cases) { for (const c of cases) {
it(`works for ${c.url}`, () => { it(`works for ${c.url}`, () => {
expect(normalizeSpriteUrl(c.url, token)).to.be(c.expected); expect(
normalizeSpriteUrl(
c.url,
token,
'https://example.com:8000/mystyle/style.json'
)
).to.be(c.expected);
}); });
} }
}); });