@@ -26856,10 +26856,14 @@ var System = (0,_core_system_js__WEBPACK_IMPORTED_MODULE_0__.registerSystem)('ma
2685626856 *
2685726857 * @param {string|Element} src - URL or element
2685826858 * @param {object} data - Relevant texture properties
26859- * @param {function} cb - Callback to pass texture to
26859+ * @param {function} cb - Callback that receives the texture, or null if image loading failed
2686026860 */
2686126861 loadTexture: function (src, data, cb) {
2686226862 this.loadTextureSource(src, function sourceLoaded(source) {
26863+ if (source === null) {
26864+ cb(null);
26865+ return;
26866+ }
2686326867 var texture = (0,_utils_material_js__WEBPACK_IMPORTED_MODULE_2__.createCompatibleTexture)(source);
2686426868 (0,_utils_material_js__WEBPACK_IMPORTED_MODULE_2__.setTextureProperties)(texture, data);
2686526869 cb(texture);
@@ -26869,14 +26873,16 @@ var System = (0,_core_system_js__WEBPACK_IMPORTED_MODULE_0__.registerSystem)('ma
2686926873 * Determine whether `src` is an image or video. Then try to load the asset, then call back.
2687026874 *
2687126875 * @param {string|Element} src - URL or element.
26872- * @param {function} cb - Callback to pass texture source to .
26876+ * @param {function} cb - Callback that receives the texture source, or null if image loading failed .
2687326877 */
2687426878 loadTextureSource: function (src, cb) {
2687526879 var self = this;
2687626880 var sourceCache = this.sourceCache;
2687726881 var hash = this.hash(src);
2687826882 if (sourceCache[hash]) {
26879- sourceCache[hash].then(cb);
26883+ sourceCache[hash].then(cb, function () {
26884+ cb(null);
26885+ });
2688026886 return;
2688126887 }
2688226888
@@ -26897,7 +26903,9 @@ var System = (0,_core_system_js__WEBPACK_IMPORTED_MODULE_0__.registerSystem)('ma
2689726903 }
2689826904 function sourceLoaded(sourcePromise) {
2689926905 sourceCache[hash] = Promise.resolve(sourcePromise);
26900- sourceCache[hash].then(cb);
26906+ sourceCache[hash].then(cb, function () {
26907+ cb(null);
26908+ });
2690126909 }
2690226910 },
2690326911 /**
@@ -27009,7 +27017,8 @@ function loadImageUrl(src) {
2700927017 function doLoadImageUrl(resolve, reject) {
2701027018 // Request and load texture from src string. THREE will create underlying element.
2701127019 ImageLoader.load(src, resolveSource, function () {/* no-op */}, function (xhr) {
27012- error('`$s` could not be fetched (Error code: %s; Response: %s)', xhr.status, xhr.statusText);
27020+ error('`%s` could not be fetched (Error code: %s; Response: %s)', src, xhr.status, xhr.statusText);
27021+ reject(new Error('Failed to load image: ' + src));
2701327022 });
2701427023 function resolveSource(data) {
2701527024 resolve(new three__WEBPACK_IMPORTED_MODULE_3__.Source(data));
@@ -29335,6 +29344,16 @@ function parseUrl(src) {
2933529344 }
2933629345 return parsedSrc[1];
2933729346}
29347+ var IMAGE_EXTENSIONS = ['jpg', 'jpeg', 'png', 'webp', 'avif'];
29348+
29349+ /**
29350+ * Get file extension from URL (without query string or hash).
29351+ */
29352+ function getExtension(src) {
29353+ var pathname = src.split('?')[0].split('#')[0];
29354+ var ext = pathname.split('.').pop().toLowerCase();
29355+ return ext;
29356+ }
2933829357
2933929358/**
2934029359 * Call back whether `src` is an image.
@@ -29344,10 +29363,18 @@ function parseUrl(src) {
2934429363 */
2934529364function checkIsImage(src, onResult) {
2934629365 var request;
29366+ var ext;
2934729367 if (src.tagName) {
2934829368 onResult(src.tagName === 'IMG');
2934929369 return;
2935029370 }
29371+
29372+ // Check file extension first to avoid HEAD request for common image extensions.
29373+ ext = getExtension(src);
29374+ if (IMAGE_EXTENSIONS.indexOf(ext) !== -1) {
29375+ onResult(true);
29376+ return;
29377+ }
2935129378 request = new XMLHttpRequest();
2935229379
2935329380 // Try to send HEAD request to check if image first.
@@ -29358,20 +29385,31 @@ function checkIsImage(src, onResult) {
2935829385 contentType = request.getResponseHeader('Content-Type');
2935929386 if (contentType == null) {
2936029387 checkIsImageFallback(src, onResult);
29388+ } else if (contentType.startsWith('image')) {
29389+ onResult(true);
2936129390 } else {
29362- if (contentType.startsWith('image')) {
29363- onResult(true);
29364- } else {
29365- onResult(false);
29366- }
29391+ onResult(false);
2936729392 }
2936829393 } else {
29394+ // Non-success status (3xx redirects, 404, 405, etc.) - try loading via Image tag
29395+ // as it handles redirects and the server might not support HEAD requests.
2936929396 checkIsImageFallback(src, onResult);
2937029397 }
2937129398 request.abort();
2937229399 });
29400+ request.addEventListener('error', function () {
29401+ // Network error (CORS, etc.) - try loading via Image tag.
29402+ checkIsImageFallback(src, onResult);
29403+ });
2937329404 request.send();
2937429405}
29406+
29407+ /**
29408+ * Try loading src as an image to determine if it's an image.
29409+ *
29410+ * @param {string} src - URL to test.
29411+ * @param {function} onResult - Callback with result.
29412+ */
2937529413function checkIsImageFallback(src, onResult) {
2937629414 var tester = new Image();
2937729415 tester.addEventListener('load', onLoad);
@@ -61623,7 +61661,7 @@ if (_utils_index_js__WEBPACK_IMPORTED_MODULE_16__.device.isBrowserEnvironment) {
6162361661 window.logs = debug;
6162461662 __webpack_require__(/*! ./style/aframe.css */ "./src/style/aframe.css");
6162561663}
61626- console.log('A-Frame Version: 1.7.1 (Date 2025-12-18, Commit #835aac4c )');
61664+ console.log('A-Frame Version: 1.7.1 (Date 2025-12-18, Commit #be93909a )');
6162761665console.log('THREE Version (https://github.com/supermedium/three.js):', _lib_three_js__WEBPACK_IMPORTED_MODULE_1__["default"].REVISION);
6162861666
6162961667// Wait for ready state, unless user asynchronously initializes A-Frame.
0 commit comments