55export const AUTO_HEIGHT_BRIDGE = `(() => {
66 var GLOBAL_KEY = '__RN_SIZED_WEBVIEW__';
77 var WRAPPER_ID = '__RN_SIZED_WEBVIEW_WRAPPER__';
8+ var TRACKED_FLAG = '__RN_SIZED_WEBVIEW_MEDIA__';
89 var MESSAGE_KEY = '__AUTO_HEIGHT__';
910 var ACTIVE_DEBOUNCE_MS = 48;
1011 var IDLE_DEBOUNCE_MS = 160;
@@ -36,6 +37,19 @@ export const AUTO_HEIGHT_BRIDGE = `(() => {
3637 setTimeout(callback, 0);
3738 };
3839
40+ var once = function (fn) {
41+ var called = false;
42+
43+ return function () {
44+ if (called) {
45+ return;
46+ }
47+
48+ called = true;
49+ return fn.apply(this, arguments);
50+ };
51+ };
52+
3953 var state = {
4054 frame: null,
4155 timer: null,
@@ -48,6 +62,7 @@ export const AUTO_HEIGHT_BRIDGE = `(() => {
4862 fallbackDelay: INITIAL_FALLBACK_MS,
4963 cleanup: [],
5064 wrapper: null,
65+ mediaObserver: null,
5166 };
5267
5368 window[GLOBAL_KEY] = state;
@@ -104,6 +119,7 @@ export const AUTO_HEIGHT_BRIDGE = `(() => {
104119
105120 state.cleanup.length = 0;
106121 state.wrapper = null;
122+ state.mediaObserver = null;
107123 window[GLOBAL_KEY] = undefined;
108124 };
109125
@@ -402,6 +418,32 @@ export const AUTO_HEIGHT_BRIDGE = `(() => {
402418 });
403419 };
404420
421+ var scheduleMediaMeasure = function () {
422+ scheduleMeasure(true);
423+ requestFrame(function () {
424+ scheduleMeasure(true);
425+ });
426+ };
427+
428+ var ensureMediaObserver = function () {
429+ if (state.mediaObserver || typeof ResizeObserver !== 'function') {
430+ return state.mediaObserver;
431+ }
432+
433+ var observer = new ResizeObserver(function () {
434+ scheduleMediaMeasure();
435+ });
436+
437+ state.mediaObserver = observer;
438+
439+ addCleanup(function () {
440+ observer.disconnect();
441+ state.mediaObserver = null;
442+ });
443+
444+ return observer;
445+ };
446+
405447 var tryTrackMedia = function (element) {
406448 if (!element || typeof element.tagName !== 'string') {
407449 return;
@@ -413,16 +455,38 @@ export const AUTO_HEIGHT_BRIDGE = `(() => {
413455
414456 if (trackedMedia) {
415457 trackedMedia.add(element);
458+ } else if (element[TRACKED_FLAG]) {
459+ return;
460+ } else {
461+ try {
462+ element[TRACKED_FLAG] = true;
463+ } catch (error) {
464+ // no-op
465+ }
466+
467+ addCleanup(function () {
468+ try {
469+ delete element[TRACKED_FLAG];
470+ } catch (error) {
471+ // no-op
472+ }
473+ });
474+ }
475+
476+ var observer = ensureMediaObserver();
477+ if (observer) {
478+ try {
479+ observer.observe(element);
480+ } catch (error) {
481+ // no-op
482+ }
416483 }
417484
418485 var tag = element.tagName.toUpperCase();
419486
420487 if (tag === 'IMG') {
421488 if (element.complete && element.naturalHeight) {
422- scheduleMeasure(true);
423- requestFrame(function () {
424- scheduleMeasure(true);
425- });
489+ scheduleMediaMeasure();
426490 return;
427491 }
428492
@@ -431,18 +495,19 @@ export const AUTO_HEIGHT_BRIDGE = `(() => {
431495 var cleanupLoad = function () {};
432496 var cleanupError = function () {};
433497
434- var onSettled = function () {
498+ var finalizeImage = once( function () {
435499 cleanupLoad();
436500 cleanupError();
437501 clearLoading();
438- scheduleMeasure(true);
439- requestFrame(function () {
440- scheduleMeasure(true);
441- });
442- };
502+ scheduleMediaMeasure();
503+ });
443504
444- cleanupLoad = addEvent(element, 'load', onSettled, { once: true });
445- cleanupError = addEvent(element, 'error', onSettled, { once: true });
505+ cleanupLoad = addEvent(element, 'load', finalizeImage, { once: true });
506+ cleanupError = addEvent(element, 'error', finalizeImage, { once: true });
507+
508+ if (typeof element.decode === 'function') {
509+ element.decode().then(finalizeImage).catch(finalizeImage);
510+ }
446511
447512 return;
448513 }
@@ -453,23 +518,20 @@ export const AUTO_HEIGHT_BRIDGE = `(() => {
453518 var cleanupLoadIframe = function () {};
454519 var cleanupErrorIframe = function () {};
455520
456- var onIframe = function () {
521+ var onIframe = once( function () {
457522 cleanupLoadIframe();
458523 cleanupErrorIframe();
459524 clearLoading();
460- scheduleMeasure(true);
461- requestFrame(function () {
462- scheduleMeasure(true);
463- });
464- };
525+ scheduleMediaMeasure();
526+ });
465527
466528 cleanupLoadIframe = addEvent(element, 'load', onIframe, { once: true });
467529 cleanupErrorIframe = addEvent(element, 'error', onIframe, { once: true });
468530
469531 try {
470532 var iframeDoc = element.contentDocument;
471533 if (iframeDoc && iframeDoc.readyState === 'complete') {
472- scheduleMeasure(true );
534+ scheduleMediaMeasure( );
473535 requestFrame(onIframe);
474536 }
475537 } catch (error) {
@@ -484,10 +546,7 @@ export const AUTO_HEIGHT_BRIDGE = `(() => {
484546 typeof element.readyState === 'number' &&
485547 element.readyState >= 2
486548 ) {
487- scheduleMeasure(true);
488- requestFrame(function () {
489- scheduleMeasure(true);
490- });
549+ scheduleMediaMeasure();
491550 return;
492551 }
493552
@@ -497,16 +556,13 @@ export const AUTO_HEIGHT_BRIDGE = `(() => {
497556 var cleanupMetadata = function () {};
498557 var cleanupEnded = function () {};
499558
500- var onVideo = function () {
559+ var onVideo = once( function () {
501560 cleanupData();
502561 cleanupMetadata();
503562 cleanupEnded();
504563 clearLoading();
505- scheduleMeasure(true);
506- requestFrame(function () {
507- scheduleMeasure(true);
508- });
509- };
564+ scheduleMediaMeasure();
565+ });
510566
511567 cleanupData = addEvent(element, 'loadeddata', onVideo, { once: true });
512568 cleanupMetadata = addEvent(element, 'loadedmetadata', onVideo, {
0 commit comments