Bläddra i källkod

Merge pull request #208 from PatrickNausha/handle-uri-extensions

Handle URL parameters and fragments.
Garrett Johnson 4 år sedan
förälder
incheckning
d0d97e3e6b

Filskillnaden har hållts tillbaka eftersom den är för stor
+ 1 - 0
example/data/tileset-external-with-url-params.json


+ 4 - 2
src/base/TilesRendererBase.js

@@ -1,5 +1,6 @@
 import path from 'path-browserify';
 import { urlJoin } from '../utilities/urlJoin.js';
+import { getUrlExtension } from '../utilities/urlExtension.js';
 import { LRUCache } from '../utilities/LRUCache.js';
 import { PriorityQueue } from '../utilities/PriorityQueue.js';
 import { determineFrustumSet, toggleTiles, skipTraversal, markUsedSetLeaves, traverseSet } from './traverseFunctions.js';
@@ -219,7 +220,8 @@ export class TilesRendererBase {
 		if ( uri ) {
 
 			// "content" should only indicate loadable meshes, not external tile sets
-			const isExternalTileSet = /\.json$/i.test( tile.content.uri );
+			const extension = getUrlExtension( tile.content.uri );
+			const isExternalTileSet = extension && extension.toLowerCase() === 'json';
 			tile.__externalTileSet = isExternalTileSet;
 			tile.__contentEmpty = isExternalTileSet;
 
@@ -556,7 +558,7 @@ export class TilesRendererBase {
 						}
 
 						const uri = parseTile.content.uri;
-						const extension = uri.split( /\./g ).pop();
+						const extension = getUrlExtension( uri );
 
 						return this.parseTile( buffer, parseTile, extension );
 

+ 32 - 0
src/utilities/urlExtension.js

@@ -0,0 +1,32 @@
+/**
+ * Returns the file extension of the path component of a URL
+ * @param {string} url
+ * @returns {string} null if no extension found
+ */
+export function getUrlExtension( url ) {
+
+	let parsedUrl;
+	try {
+
+		parsedUrl = new URL( url, 'http://fakehost.com/' );
+
+	} catch ( _ ) {
+
+		// Ignore invalid URLs
+		return null;
+
+	}
+
+	const filename = parsedUrl.pathname.split( '/' ).pop();
+	const dotIndex = filename.lastIndexOf( '.' );
+	if ( dotIndex === - 1 || dotIndex === filename.length - 1 ) {
+
+		// Has no extension or has trailing . character
+		return null;
+
+	}
+
+	const extension = filename.substring( dotIndex + 1 );
+	return extension;
+
+}

+ 44 - 0
test/urlExtension.test.js

@@ -0,0 +1,44 @@
+import { getUrlExtension } from '../src/utilities/urlExtension.js';
+
+describe( 'getUrlExtension', () => {
+
+	it.each( [
+		'https://nasa.gov/foo/bar.baz/tileset.json',
+		'https://nasa.gov/foo/bar.baz/tileset.json?foo=bar',
+		'https://nasa.gov/foo/bar.baz/tileset.json?a.b=c.d',
+		'https://nasa.gov/foo/bar.baz/tileset.json?a.b=c.d#e.f',
+		'https://nasa.gov/tileset.json',
+		'https://nasa.gov//tileset.json',
+		'file:///Users/JaneScientist/code/3DTilesRendererJS/example/b3dmExample.json',
+		'foo.json',
+		'/foo/bar.json',
+		'foo.json?a=b',
+		'/foo.json',
+		'/foo/bar.json',
+		'png.svg.json'
+	] )( 'parses extensions (%s)', url => {
+
+		expect( getUrlExtension( url ) ).toBe( 'json' );
+
+	} );
+
+	it.each( [
+		'https://nasa.gov',
+		'https://nasa.gov/',
+		'https://nasa.gov/tileset',
+		'https://nasa.gov/foo/bar.baz/tileset?foo=bar',
+		'https://nasa.gov/foo/bar.baz/tileset?a.b=c.d',
+		'https://nasa.gov/tileset',
+		'https://nasa.gov/tileset.',
+		'Pleiades',
+		'.',
+		'..',
+		'',
+		undefined,
+	] )( 'returns null for values that are not URLs with extensions (%s)', url => {
+
+		expect( getUrlExtension( url ) ).toBeNull();
+
+	} );
+
+} );