diff --git a/example/package.json b/example/package.json index bf089e8..a21116e 100644 --- a/example/package.json +++ b/example/package.json @@ -10,10 +10,10 @@ }, "dependencies": { "@expo/metro-runtime": "~6.1.2", - "expo": "~54.0.21", + "expo": "~54.0.23", "expo-status-bar": "~3.0.8", - "react": "19.1.0", - "react-dom": "19.1.0", + "react": "19.1.1", + "react-dom": "19.1.1", "react-native": "0.81.5", "react-native-safe-area-context": "^5.6.2", "react-native-web": "~0.21.2", @@ -21,7 +21,7 @@ }, "private": true, "devDependencies": { - "react-native-builder-bob": "^0.40.14", + "react-native-builder-bob": "^0.40.15", "react-native-monorepo-config": "^0.3.0" } } diff --git a/package.json b/package.json index d1d4fdc..2d71266 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-native-sized-webview", - "version": "1.0.13", + "version": "1.0.14", "description": "React Native WebView that auto-sizes to match its HTML content—whether you load local HTML or full external websites—without manual measurements, timers, or layout flicker.", "main": "./lib/module/index.js", "module": "./lib/module/index.js", diff --git a/src/constants/autoHeightBridge.ts b/src/constants/autoHeightBridge.ts index aca5f30..f421492 100644 --- a/src/constants/autoHeightBridge.ts +++ b/src/constants/autoHeightBridge.ts @@ -57,7 +57,6 @@ export const AUTO_HEIGHT_BRIDGE = `(() => { microtask: false, pendingLoads: 0, lastHeight: 0, - lastCssHeight: 0, anomalyCount: 0, fallbackTimer: null, fallbackDelay: INITIAL_FALLBACK_MS, @@ -173,13 +172,62 @@ export const AUTO_HEIGHT_BRIDGE = `(() => { return id; }; + var RENDERABLE_MEDIA_TAGS = { + IMG: true, + IFRAME: true, + VIDEO: true, + SVG: true, + CANVAS: true, + PICTURE: true, + OBJECT: true, + EMBED: true, + AUDIO: true, + }; + + var hasRenderableContent = function (node) { + if (!node || !node.childNodes || !node.childNodes.length) { + return false; + } + + var child = node.firstChild; + while (child) { + if (child.nodeType === 3) { + if (child.textContent && child.textContent.trim()) { + return true; + } + } else if (child.nodeType === 1) { + var tag = (child.tagName || '').toUpperCase(); + if (tag === 'BR') { + child = child.nextSibling; + continue; + } + + if (RENDERABLE_MEDIA_TAGS[tag]) { + return true; + } + + if (hasRenderableContent(child)) { + return true; + } + } + + child = child.nextSibling; + } + + return false; + }; + var pruneTrailingNodes = function (container) { if (!container) { return; } var isWhitespaceText = function (node) { - return node && node.nodeType === 3 && (!node.textContent || !node.textContent.trim()); + return ( + node && + node.nodeType === 3 && + (!node.textContent || !node.textContent.trim()) + ); }; var isTrimmableElement = function (node) { @@ -193,7 +241,7 @@ export const AUTO_HEIGHT_BRIDGE = `(() => { } if (tag === 'P') { - return !node.textContent || !node.textContent.trim(); + return !hasRenderableContent(node); } return false; @@ -231,66 +279,70 @@ export const AUTO_HEIGHT_BRIDGE = `(() => { } }; - var readRectHeight = function (element) { - if (!element || typeof element.getBoundingClientRect !== 'function') { + var readElementHeight = function (element) { + if (!element) { return 0; } - var rect = element.getBoundingClientRect(); - return typeof rect.height === 'number' ? rect.height : 0; - }; - - var readMaxValue = function (values) { - var max = 0; - - for (var index = 0; index < values.length; index += 1) { - var value = values[index]; - if (typeof value === 'number' && value > max) { - max = value; - } + var rectHeight = 0; + if (typeof element.getBoundingClientRect === 'function') { + var rect = element.getBoundingClientRect(); + rectHeight = rect && typeof rect.height === 'number' ? rect.height : 0; } - return max; + return Math.max( + 0, + rectHeight, + element.scrollHeight || 0, + element.offsetHeight || 0, + element.clientHeight || 0 + ); }; var measureHeight = function () { var html = document.documentElement; var body = document.body; var wrapper = ensureWrapper(); + var scrollingElement = document.scrollingElement; pruneTrailingNodes(wrapper); - var values = []; + var targets = []; - var collect = function (element) { - if (!element) { - return; - } + if (wrapper) { + targets.push(wrapper); + } - values.push( - readRectHeight(element), - element.scrollHeight || 0, - element.offsetHeight || 0, - element.clientHeight || 0 - ); - }; + if (body && targets.indexOf(body) === -1) { + targets.push(body); + } - if (wrapper) { - collect(wrapper); - } else { - if (body) { - collect(body); - } - if (html && html !== body) { - collect(html); - } + if (html && targets.indexOf(html) === -1) { + targets.push(html); + } + + if ( + scrollingElement && + scrollingElement !== body && + scrollingElement !== html && + targets.indexOf(scrollingElement) === -1 + ) { + targets.push(scrollingElement); } - if (!values.length) { + if (!targets.length) { return 0; } - return Math.max(0, Math.ceil(readMaxValue(values))); + var maxHeight = 0; + for (var index = 0; index < targets.length; index += 1) { + var value = readElementHeight(targets[index]); + if (value > maxHeight) { + maxHeight = value; + } + } + + return Math.max(0, Math.ceil(maxHeight)); }; var postHeight = function (height) { @@ -298,8 +350,6 @@ export const AUTO_HEIGHT_BRIDGE = `(() => { return; } - state.lastCssHeight = height; - var sanitized = Math.ceil(height); if (!isFinite(sanitized) || sanitized <= 0) { diff --git a/yarn.lock b/yarn.lock index 88380c1..5d7b851 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1929,9 +1929,9 @@ __metadata: languageName: node linkType: hard -"@expo/cli@npm:54.0.14": - version: 54.0.14 - resolution: "@expo/cli@npm:54.0.14" +"@expo/cli@npm:54.0.16": + version: 54.0.16 + resolution: "@expo/cli@npm:54.0.16" dependencies: "@0no-co/graphql.web": ^1.0.8 "@expo/code-signing-certificates": ^0.0.5 @@ -1941,9 +1941,9 @@ __metadata: "@expo/env": ~2.0.7 "@expo/image-utils": ^0.8.7 "@expo/json-file": ^10.0.7 - "@expo/mcp-tunnel": ~0.0.7 + "@expo/mcp-tunnel": ~0.1.0 "@expo/metro": ~54.1.0 - "@expo/metro-config": ~54.0.8 + "@expo/metro-config": ~54.0.9 "@expo/osascript": ^2.3.7 "@expo/package-manager": ^1.9.8 "@expo/plist": ^0.4.7 @@ -1966,7 +1966,7 @@ __metadata: connect: ^3.7.0 debug: ^4.3.4 env-editor: ^0.4.1 - expo-server: ^1.0.3 + expo-server: ^1.0.4 freeport-async: ^2.0.0 getenv: ^2.0.0 glob: ^10.4.2 @@ -2008,7 +2008,7 @@ __metadata: optional: true bin: expo-internal: build/bin/cli - checksum: aa051779deb94347e2fc45572a470b1c5459d53bd2eaff18dfe1b46cab670f010e2627fa1eefbc50ccf7145c823ff00c0494ca501ff40fd693d0fa15e3d1cbe5 + checksum: b603f2604df2bdc70f9b9fc63a8080729bdd876d38edfe697258407a7b04bdc9ca2ab1304d42fb61d049156c3ede31fb3fed90b5ee2ee2c3bb4f7cee93495ad1 languageName: node linkType: hard @@ -2113,9 +2113,9 @@ __metadata: languageName: node linkType: hard -"@expo/fingerprint@npm:0.15.2": - version: 0.15.2 - resolution: "@expo/fingerprint@npm:0.15.2" +"@expo/fingerprint@npm:0.15.3": + version: 0.15.3 + resolution: "@expo/fingerprint@npm:0.15.3" dependencies: "@expo/spawn-async": ^1.7.2 arg: ^5.0.2 @@ -2130,7 +2130,7 @@ __metadata: semver: ^7.6.0 bin: fingerprint: bin/cli.js - checksum: 5af7ce89c3f0d13e6f38013da5f190d91327b6cbc8ba1633a7e919feea6704c65e5d6daa2289f10f32c475ae0718a13bdbb5e05a304f8cb92d838c88ecf318e7 + checksum: ab2d8febf63de45bc9974616d73840bd5a612fbe8de46ecf49d9f137250724ff3efc9dfbd72924d283a88e29d74983e05f9e8ce517a56cf5df09c85a9ed58f72 languageName: node linkType: hard @@ -2162,9 +2162,9 @@ __metadata: languageName: node linkType: hard -"@expo/mcp-tunnel@npm:~0.0.7": - version: 0.0.8 - resolution: "@expo/mcp-tunnel@npm:0.0.8" +"@expo/mcp-tunnel@npm:~0.1.0": + version: 0.1.0 + resolution: "@expo/mcp-tunnel@npm:0.1.0" dependencies: ws: ^8.18.3 zod: ^3.25.76 @@ -2174,13 +2174,13 @@ __metadata: peerDependenciesMeta: "@modelcontextprotocol/sdk": optional: true - checksum: f3ec8933a7a33d5d54cbb98e4c59cb923b3b0a444aadd31378495b60a3cdd2d0a1229571fd8e2b2eec984eb94d02012953c396758c45e09c259dc5fa7bd057d5 + checksum: ebc0d2cfc9e945b57a5ad62cc4d43cdc989ec8195d218c524761e88384bebb69ab55ea65b3795d9d7970356a0fd1c4aba5b72e110c502cfdba3d054c8f9d454b languageName: node linkType: hard -"@expo/metro-config@npm:54.0.8, @expo/metro-config@npm:~54.0.8": - version: 54.0.8 - resolution: "@expo/metro-config@npm:54.0.8" +"@expo/metro-config@npm:54.0.9, @expo/metro-config@npm:~54.0.9": + version: 54.0.9 + resolution: "@expo/metro-config@npm:54.0.9" dependencies: "@babel/code-frame": ^7.20.0 "@babel/core": ^7.20.0 @@ -2208,7 +2208,7 @@ __metadata: peerDependenciesMeta: expo: optional: true - checksum: fa96c208c76d10f55ed26044b9b8b49ffb3e81acf85ff6acd3f865304d4410f4c3a7ce4f40d75c8a271fafc0dcb161f20e29ec4b59c5db68be33365847034d37 + checksum: c4186badd61008ca9bf220ecd5b66259bc7059161eef4879c1ab3a9b3d34e116139bcd0ddb0990b421b3c4c1d7a8018bd128b305848656c59143605f14ba0149 languageName: node linkType: hard @@ -4918,9 +4918,9 @@ __metadata: languageName: node linkType: hard -"babel-preset-expo@npm:~54.0.6": - version: 54.0.6 - resolution: "babel-preset-expo@npm:54.0.6" +"babel-preset-expo@npm:~54.0.7": + version: 54.0.7 + resolution: "babel-preset-expo@npm:54.0.7" dependencies: "@babel/helper-module-imports": ^7.25.9 "@babel/plugin-proposal-decorators": ^7.12.9 @@ -4953,7 +4953,7 @@ __metadata: optional: true expo: optional: true - checksum: 914db23267c1b32430faeac50992e76b20f1ec5ac2bfc6778483226df0d8a486adc7115f294493b5719a738954f4a787f8a2d5dfd4b84ad2d17883f7ad3a636b + checksum: b45071a65c720fd98543712f30db727e874a8a310c198675bcb75533bd3a0798e253069025d3cc7e1a1746a9e2e0b1594fbe5a2164013924bf4082f41beb71fb languageName: node linkType: hard @@ -6993,38 +6993,37 @@ __metadata: languageName: node linkType: hard -"expo-modules-autolinking@npm:3.0.19": - version: 3.0.19 - resolution: "expo-modules-autolinking@npm:3.0.19" +"expo-modules-autolinking@npm:3.0.21": + version: 3.0.21 + resolution: "expo-modules-autolinking@npm:3.0.21" dependencies: "@expo/spawn-async": ^1.7.2 chalk: ^4.1.0 commander: ^7.2.0 - glob: ^10.4.2 require-from-string: ^2.0.2 resolve-from: ^5.0.0 bin: expo-modules-autolinking: bin/expo-modules-autolinking.js - checksum: 4cd4c2f310a6fafcf830d1e92083b57edf068f00da31de458a8338063fe3c1164a459a52ea0fc8fb3441dff88d58837f3802dc8d627ad1a4aefbea30a6374769 + checksum: 50fd61a01b70bda5e879faa6c29fe4473da4ab851b3ef56e298648324a126ed73b0992e9cbd6270ee6a5e0507d9102f6916651b4ff5ce89c41b8a92aed0659b8 languageName: node linkType: hard -"expo-modules-core@npm:3.0.23": - version: 3.0.23 - resolution: "expo-modules-core@npm:3.0.23" +"expo-modules-core@npm:3.0.25": + version: 3.0.25 + resolution: "expo-modules-core@npm:3.0.25" dependencies: invariant: ^2.2.4 peerDependencies: react: "*" react-native: "*" - checksum: 6e5c873987b2cca1e9b2bf4aa642361773938daf49fe43a7ec1a06db9e3c2076cbd40f560a3752a51f5aba4fc11f4579329b8a0eaa23064543f223643dff504d + checksum: 360fa2f7295c5e2e9db403fb1e32aeb2e5c3d42964a3007b6305a8795cdb66f9c1d36d23bc62197c66319897f8b13bc0f2fc6fb88920a7ba0b13eb3422ed8201 languageName: node linkType: hard -"expo-server@npm:^1.0.3": - version: 1.0.3 - resolution: "expo-server@npm:1.0.3" - checksum: cddfd7625fb20681c5398982460d2dfd0a165f0e316b668837cedba186bb716f8186cfc9cc38041a2b2bec23000db1f7614c73c6be1c69627ae9ceff3476d4bd +"expo-server@npm:^1.0.4": + version: 1.0.4 + resolution: "expo-server@npm:1.0.4" + checksum: 830b6c16583ed2e593d3369ae45b380ca66e5861173636cee0ec36108640982813893e070db1e1f2710aef0f9382be1730344e9f22d05bb7fb5278fea001eca9 languageName: node linkType: hard @@ -7040,28 +7039,28 @@ __metadata: languageName: node linkType: hard -"expo@npm:~54.0.21": - version: 54.0.21 - resolution: "expo@npm:54.0.21" +"expo@npm:~54.0.23": + version: 54.0.23 + resolution: "expo@npm:54.0.23" dependencies: "@babel/runtime": ^7.20.0 - "@expo/cli": 54.0.14 + "@expo/cli": 54.0.16 "@expo/config": ~12.0.10 "@expo/config-plugins": ~54.0.2 "@expo/devtools": 0.1.7 - "@expo/fingerprint": 0.15.2 + "@expo/fingerprint": 0.15.3 "@expo/metro": ~54.1.0 - "@expo/metro-config": 54.0.8 + "@expo/metro-config": 54.0.9 "@expo/vector-icons": ^15.0.3 "@ungap/structured-clone": ^1.3.0 - babel-preset-expo: ~54.0.6 + babel-preset-expo: ~54.0.7 expo-asset: ~12.0.9 expo-constants: ~18.0.10 expo-file-system: ~19.0.17 expo-font: ~14.0.9 expo-keep-awake: ~15.0.7 - expo-modules-autolinking: 3.0.19 - expo-modules-core: 3.0.23 + expo-modules-autolinking: 3.0.21 + expo-modules-core: 3.0.25 pretty-format: ^29.7.0 react-refresh: ^0.14.2 whatwg-url-without-unicode: 8.0.0-3 @@ -7082,7 +7081,7 @@ __metadata: expo: bin/cli expo-modules-autolinking: bin/autolinking fingerprint: bin/fingerprint - checksum: c928fea530134ad9ff8a508ba8f529620e36ac08b1099c9b13dbeb581597920296acf5db8e11874fcaa8beaf5e49a2e06bf6a429c322decfc46dfc9e466d4f1b + checksum: 0509035d1234f04c57fe8082879df2ae4f85858def352da7f8c46fc5ed12ebd85b61f68d71adf1a46b1fe52f530367d1533c527b6394fc0392fea98771cf3fa2 languageName: node linkType: hard @@ -11688,14 +11687,14 @@ __metadata: languageName: node linkType: hard -"react-dom@npm:19.1.0": - version: 19.1.0 - resolution: "react-dom@npm:19.1.0" +"react-dom@npm:19.1.1": + version: 19.1.1 + resolution: "react-dom@npm:19.1.1" dependencies: scheduler: ^0.26.0 peerDependencies: - react: ^19.1.0 - checksum: 1d154b6543467095ac269e61ca59db546f34ef76bcdeb90f2dad41d682cd210aae492e70c85010ed5d0a2caea225e9a55139ebc1a615ee85bf197d7f99678cdf + react: ^19.1.1 + checksum: 71d63df955e99bb58470c6ae12ebb82fa80e2a73147c387b73a31c17bcff803ce8aded52ae0c4391c9b413be0aa449249d8be7d063136826d1f0caba9720a907 languageName: node linkType: hard @@ -11752,6 +11751,38 @@ __metadata: languageName: node linkType: hard +"react-native-builder-bob@npm:^0.40.15": + version: 0.40.15 + resolution: "react-native-builder-bob@npm:0.40.15" + dependencies: + "@babel/core": ^7.25.2 + "@babel/plugin-transform-flow-strip-types": ^7.26.5 + "@babel/plugin-transform-strict-mode": ^7.24.7 + "@babel/preset-env": ^7.25.2 + "@babel/preset-react": ^7.24.7 + "@babel/preset-typescript": ^7.24.7 + arktype: ^2.1.15 + babel-plugin-syntax-hermes-parser: ^0.28.0 + browserslist: ^4.20.4 + cross-spawn: ^7.0.3 + dedent: ^0.7.0 + del: ^6.1.1 + escape-string-regexp: ^4.0.0 + fs-extra: ^10.1.0 + glob: ^8.0.3 + is-git-dirty: ^2.0.1 + json5: ^2.2.1 + kleur: ^4.1.4 + prompts: ^2.4.2 + react-native-monorepo-config: ^0.1.8 + which: ^2.0.2 + yargs: ^17.5.1 + bin: + bob: bin/bob + checksum: abe76dfce15679da3c8c475d39127bc1cb970118be3bd964b63bb6aeabe8d3eb42698f5d86b05386af12ba378f924a7a1e4e22194ca400c92e6961d2000dc682 + languageName: node + linkType: hard + "react-native-is-edge-to-edge@npm:^1.2.1": version: 1.2.1 resolution: "react-native-is-edge-to-edge@npm:1.2.1" @@ -11797,12 +11828,12 @@ __metadata: resolution: "react-native-sized-webview-example@workspace:example" dependencies: "@expo/metro-runtime": ~6.1.2 - expo: ~54.0.21 + expo: ~54.0.23 expo-status-bar: ~3.0.8 - react: 19.1.0 - react-dom: 19.1.0 + react: 19.1.1 + react-dom: 19.1.1 react-native: 0.81.5 - react-native-builder-bob: ^0.40.14 + react-native-builder-bob: ^0.40.15 react-native-monorepo-config: ^0.3.0 react-native-safe-area-context: ^5.6.2 react-native-web: ~0.21.2 @@ -12007,6 +12038,13 @@ __metadata: languageName: node linkType: hard +"react@npm:19.1.1": + version: 19.1.1 + resolution: "react@npm:19.1.1" + checksum: f2f18fea5deac87b1167365bd5160bcba64d383c26a37afa905b714ca424f423ef97d8daf53f041ab9ac25a06357fafcf0b5d3b6b84c9d1eace0e621bfeae629 + languageName: node + linkType: hard + "read-package-up@npm:^11.0.0": version: 11.0.0 resolution: "read-package-up@npm:11.0.0"