@oasiz/sdk 1.5.4 → 1.5.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/index.cjs +130 -17
- package/dist/index.js +130 -17
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -196,11 +196,11 @@ private onGameOver(): void {
|
|
|
196
196
|
|
|
197
197
|
### Layout
|
|
198
198
|
|
|
199
|
-
Use the runtime safe-area value instead of hardcoded top offsets. The SDK returns the top inset as **a percentage of the viewport height (0–100)**. If the host exposes CSS pixels via `window.getSafeAreaTop()` or `window.__OASIZ_SAFE_AREA_TOP__`, the SDK converts using `window.innerHeight
|
|
199
|
+
Use the runtime safe-area value instead of hardcoded top offsets. The SDK returns the top inset as **a percentage of the active viewport height (0–100)**. If the host exposes CSS pixels via `window.getSafeAreaTop()` or `window.__OASIZ_SAFE_AREA_TOP__`, the SDK converts using `window.visualViewport.height` when available, then `window.innerHeight`, then document height. The host may instead set **`window.getSafeAreaTopPercent()`** or **`window.__OASIZ_SAFE_AREA_TOP_PERCENT__`** (0–100) and that value is used directly. When no host bridge is available, the SDK falls back to CSS `env(safe-area-inset-top)` / `constant(safe-area-inset-top)`.
|
|
200
200
|
|
|
201
201
|
#### `oasiz.getSafeAreaTop(): number`
|
|
202
202
|
|
|
203
|
-
Returns the top inset as a percentage of viewport height (0–100). To get pixels in JavaScript,
|
|
203
|
+
Returns the top inset as a percentage of viewport height (0–100). To get pixels in JavaScript, multiply by `window.visualViewport?.height || window.innerHeight`. In CSS, the same value matches **`vh`** units (for example `12.5vh` for 12.5% of the viewport height). Unsupported hosts return `0`.
|
|
204
204
|
|
|
205
205
|
```ts
|
|
206
206
|
const safeTopPct = oasiz.getSafeAreaTop();
|
package/dist/index.cjs
CHANGED
|
@@ -1319,31 +1319,130 @@ function warnMissingBridge6(methodName) {
|
|
|
1319
1319
|
);
|
|
1320
1320
|
}
|
|
1321
1321
|
}
|
|
1322
|
-
function
|
|
1322
|
+
function toFiniteNumber(value) {
|
|
1323
1323
|
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
1324
|
+
if (typeof value !== "string") {
|
|
1325
|
+
return void 0;
|
|
1326
|
+
}
|
|
1327
|
+
const parsed = Number.parseFloat(value.trim());
|
|
1328
|
+
if (!Number.isFinite(parsed)) {
|
|
1329
|
+
return void 0;
|
|
1330
|
+
}
|
|
1331
|
+
return parsed;
|
|
1332
|
+
}
|
|
1333
|
+
return value;
|
|
1334
|
+
}
|
|
1335
|
+
function clampSafeAreaTopPixels(value) {
|
|
1336
|
+
const numeric = toFiniteNumber(value);
|
|
1337
|
+
if (typeof numeric === "undefined") {
|
|
1324
1338
|
return 0;
|
|
1325
1339
|
}
|
|
1326
|
-
return Math.max(0,
|
|
1340
|
+
return Math.max(0, numeric);
|
|
1327
1341
|
}
|
|
1328
1342
|
function normalizeSafeAreaTopPercent(value) {
|
|
1329
|
-
|
|
1330
|
-
|
|
1343
|
+
const numeric = toFiniteNumber(value);
|
|
1344
|
+
if (typeof numeric === "undefined") {
|
|
1345
|
+
return void 0;
|
|
1331
1346
|
}
|
|
1332
|
-
return Math.min(100, Math.max(0,
|
|
1347
|
+
return Math.min(100, Math.max(0, numeric));
|
|
1333
1348
|
}
|
|
1334
|
-
function
|
|
1335
|
-
const
|
|
1336
|
-
if (typeof
|
|
1349
|
+
function getViewportHeight(bridge) {
|
|
1350
|
+
const visualViewportHeight = bridge.visualViewport?.height;
|
|
1351
|
+
if (typeof visualViewportHeight === "number" && Number.isFinite(visualViewportHeight) && visualViewportHeight > 0) {
|
|
1352
|
+
return visualViewportHeight;
|
|
1353
|
+
}
|
|
1354
|
+
const innerHeight = bridge.innerHeight;
|
|
1355
|
+
if (typeof innerHeight === "number" && Number.isFinite(innerHeight) && innerHeight > 0) {
|
|
1356
|
+
return innerHeight;
|
|
1357
|
+
}
|
|
1358
|
+
const documentHeight = bridge.document?.documentElement?.clientHeight;
|
|
1359
|
+
if (typeof documentHeight === "number" && Number.isFinite(documentHeight) && documentHeight > 0) {
|
|
1360
|
+
return documentHeight;
|
|
1361
|
+
}
|
|
1362
|
+
const bodyHeight = bridge.document?.body?.clientHeight;
|
|
1363
|
+
if (typeof bodyHeight === "number" && Number.isFinite(bodyHeight) && bodyHeight > 0) {
|
|
1364
|
+
return bodyHeight;
|
|
1365
|
+
}
|
|
1366
|
+
return 0;
|
|
1367
|
+
}
|
|
1368
|
+
function readCssSafeAreaValue(bridge, cssValue) {
|
|
1369
|
+
const doc = bridge.document;
|
|
1370
|
+
const root = doc?.body ?? doc?.documentElement;
|
|
1371
|
+
if (!doc || !root || typeof doc.createElement !== "function" || typeof root.appendChild !== "function" || typeof bridge.getComputedStyle !== "function") {
|
|
1337
1372
|
return 0;
|
|
1338
1373
|
}
|
|
1339
|
-
|
|
1374
|
+
const probe = doc.createElement("div");
|
|
1375
|
+
probe.style.position = "fixed";
|
|
1376
|
+
probe.style.top = "0";
|
|
1377
|
+
probe.style.left = "0";
|
|
1378
|
+
probe.style.width = "0";
|
|
1379
|
+
probe.style.height = "0";
|
|
1380
|
+
probe.style.visibility = "hidden";
|
|
1381
|
+
probe.style.pointerEvents = "none";
|
|
1382
|
+
probe.style.paddingTop = cssValue;
|
|
1383
|
+
root.appendChild(probe);
|
|
1384
|
+
try {
|
|
1385
|
+
return clampSafeAreaTopPixels(bridge.getComputedStyle(probe).paddingTop);
|
|
1386
|
+
} finally {
|
|
1387
|
+
if (typeof probe.remove === "function") {
|
|
1388
|
+
probe.remove();
|
|
1389
|
+
} else {
|
|
1390
|
+
probe.parentNode?.removeChild(probe);
|
|
1391
|
+
}
|
|
1392
|
+
}
|
|
1393
|
+
}
|
|
1394
|
+
function readCssSafeAreaTopPixels(bridge) {
|
|
1395
|
+
const envPixels = readCssSafeAreaValue(bridge, "env(safe-area-inset-top)");
|
|
1396
|
+
if (envPixels > 0) {
|
|
1397
|
+
return envPixels;
|
|
1398
|
+
}
|
|
1399
|
+
return readCssSafeAreaValue(bridge, "constant(safe-area-inset-top)");
|
|
1400
|
+
}
|
|
1401
|
+
function getDevicePixelRatio(bridge) {
|
|
1402
|
+
const dpr = bridge.devicePixelRatio;
|
|
1403
|
+
if (typeof dpr !== "number" || !Number.isFinite(dpr) || dpr <= 0) {
|
|
1404
|
+
return 1;
|
|
1405
|
+
}
|
|
1406
|
+
return dpr;
|
|
1407
|
+
}
|
|
1408
|
+
function roughlyEqualPixels(a, b) {
|
|
1409
|
+
return Math.abs(a - b) <= 2;
|
|
1410
|
+
}
|
|
1411
|
+
function normalizeSafeAreaTopPixels(value, bridge) {
|
|
1412
|
+
const pixels = clampSafeAreaTopPixels(value);
|
|
1413
|
+
const cssEnvPixels = readCssSafeAreaTopPixels(bridge);
|
|
1414
|
+
if (pixels <= 0) {
|
|
1415
|
+
return cssEnvPixels;
|
|
1416
|
+
}
|
|
1417
|
+
const dpr = getDevicePixelRatio(bridge);
|
|
1418
|
+
if (cssEnvPixels > 0 && dpr > 1 && roughlyEqualPixels(pixels / dpr, cssEnvPixels)) {
|
|
1419
|
+
return cssEnvPixels;
|
|
1420
|
+
}
|
|
1421
|
+
return pixels;
|
|
1340
1422
|
}
|
|
1341
1423
|
function pixelsTopToPercentOfViewport(pixels, bridge) {
|
|
1342
|
-
const h =
|
|
1424
|
+
const h = getViewportHeight(bridge);
|
|
1343
1425
|
if (h <= 0) {
|
|
1344
1426
|
return 0;
|
|
1345
1427
|
}
|
|
1346
|
-
return normalizeSafeAreaTopPercent(pixels / h * 100);
|
|
1428
|
+
return normalizeSafeAreaTopPercent(pixels / h * 100) ?? 0;
|
|
1429
|
+
}
|
|
1430
|
+
function cssSafeAreaTopPercent(bridge) {
|
|
1431
|
+
return pixelsTopToPercentOfViewport(readCssSafeAreaTopPixels(bridge), bridge);
|
|
1432
|
+
}
|
|
1433
|
+
function resolvePercentValue(value, bridge) {
|
|
1434
|
+
const percent = normalizeSafeAreaTopPercent(value);
|
|
1435
|
+
if (typeof percent === "undefined") {
|
|
1436
|
+
return void 0;
|
|
1437
|
+
}
|
|
1438
|
+
return percent > 0 ? percent : cssSafeAreaTopPercent(bridge);
|
|
1439
|
+
}
|
|
1440
|
+
function resolvePixelValue(value, bridge) {
|
|
1441
|
+
const numeric = toFiniteNumber(value);
|
|
1442
|
+
if (typeof numeric === "undefined") {
|
|
1443
|
+
return void 0;
|
|
1444
|
+
}
|
|
1445
|
+
return pixelsTopToPercentOfViewport(normalizeSafeAreaTopPixels(numeric, bridge), bridge);
|
|
1347
1446
|
}
|
|
1348
1447
|
function getSafeAreaTop() {
|
|
1349
1448
|
const bridge = getBridgeWindow8();
|
|
@@ -1351,18 +1450,32 @@ function getSafeAreaTop() {
|
|
|
1351
1450
|
return 0;
|
|
1352
1451
|
}
|
|
1353
1452
|
if (typeof bridge.getSafeAreaTopPercent === "function") {
|
|
1354
|
-
|
|
1453
|
+
const percent = resolvePercentValue(bridge.getSafeAreaTopPercent(), bridge);
|
|
1454
|
+
if (typeof percent !== "undefined") {
|
|
1455
|
+
return percent;
|
|
1456
|
+
}
|
|
1355
1457
|
}
|
|
1356
1458
|
if (typeof bridge.__OASIZ_SAFE_AREA_TOP_PERCENT__ !== "undefined") {
|
|
1357
|
-
|
|
1459
|
+
const percent = resolvePercentValue(bridge.__OASIZ_SAFE_AREA_TOP_PERCENT__, bridge);
|
|
1460
|
+
if (typeof percent !== "undefined") {
|
|
1461
|
+
return percent;
|
|
1462
|
+
}
|
|
1358
1463
|
}
|
|
1359
1464
|
if (typeof bridge.getSafeAreaTop === "function") {
|
|
1360
|
-
const
|
|
1361
|
-
|
|
1465
|
+
const percent = resolvePixelValue(bridge.getSafeAreaTop(), bridge);
|
|
1466
|
+
if (typeof percent !== "undefined") {
|
|
1467
|
+
return percent;
|
|
1468
|
+
}
|
|
1362
1469
|
}
|
|
1363
1470
|
if (typeof bridge.__OASIZ_SAFE_AREA_TOP__ !== "undefined") {
|
|
1364
|
-
const
|
|
1365
|
-
|
|
1471
|
+
const percent = resolvePixelValue(bridge.__OASIZ_SAFE_AREA_TOP__, bridge);
|
|
1472
|
+
if (typeof percent !== "undefined") {
|
|
1473
|
+
return percent;
|
|
1474
|
+
}
|
|
1475
|
+
}
|
|
1476
|
+
const cssPercent = cssSafeAreaTopPercent(bridge);
|
|
1477
|
+
if (cssPercent > 0) {
|
|
1478
|
+
return cssPercent;
|
|
1366
1479
|
}
|
|
1367
1480
|
warnMissingBridge6("getSafeAreaTop");
|
|
1368
1481
|
return 0;
|
package/dist/index.js
CHANGED
|
@@ -1269,31 +1269,130 @@ function warnMissingBridge6(methodName) {
|
|
|
1269
1269
|
);
|
|
1270
1270
|
}
|
|
1271
1271
|
}
|
|
1272
|
-
function
|
|
1272
|
+
function toFiniteNumber(value) {
|
|
1273
1273
|
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
1274
|
+
if (typeof value !== "string") {
|
|
1275
|
+
return void 0;
|
|
1276
|
+
}
|
|
1277
|
+
const parsed = Number.parseFloat(value.trim());
|
|
1278
|
+
if (!Number.isFinite(parsed)) {
|
|
1279
|
+
return void 0;
|
|
1280
|
+
}
|
|
1281
|
+
return parsed;
|
|
1282
|
+
}
|
|
1283
|
+
return value;
|
|
1284
|
+
}
|
|
1285
|
+
function clampSafeAreaTopPixels(value) {
|
|
1286
|
+
const numeric = toFiniteNumber(value);
|
|
1287
|
+
if (typeof numeric === "undefined") {
|
|
1274
1288
|
return 0;
|
|
1275
1289
|
}
|
|
1276
|
-
return Math.max(0,
|
|
1290
|
+
return Math.max(0, numeric);
|
|
1277
1291
|
}
|
|
1278
1292
|
function normalizeSafeAreaTopPercent(value) {
|
|
1279
|
-
|
|
1280
|
-
|
|
1293
|
+
const numeric = toFiniteNumber(value);
|
|
1294
|
+
if (typeof numeric === "undefined") {
|
|
1295
|
+
return void 0;
|
|
1281
1296
|
}
|
|
1282
|
-
return Math.min(100, Math.max(0,
|
|
1297
|
+
return Math.min(100, Math.max(0, numeric));
|
|
1283
1298
|
}
|
|
1284
|
-
function
|
|
1285
|
-
const
|
|
1286
|
-
if (typeof
|
|
1299
|
+
function getViewportHeight(bridge) {
|
|
1300
|
+
const visualViewportHeight = bridge.visualViewport?.height;
|
|
1301
|
+
if (typeof visualViewportHeight === "number" && Number.isFinite(visualViewportHeight) && visualViewportHeight > 0) {
|
|
1302
|
+
return visualViewportHeight;
|
|
1303
|
+
}
|
|
1304
|
+
const innerHeight = bridge.innerHeight;
|
|
1305
|
+
if (typeof innerHeight === "number" && Number.isFinite(innerHeight) && innerHeight > 0) {
|
|
1306
|
+
return innerHeight;
|
|
1307
|
+
}
|
|
1308
|
+
const documentHeight = bridge.document?.documentElement?.clientHeight;
|
|
1309
|
+
if (typeof documentHeight === "number" && Number.isFinite(documentHeight) && documentHeight > 0) {
|
|
1310
|
+
return documentHeight;
|
|
1311
|
+
}
|
|
1312
|
+
const bodyHeight = bridge.document?.body?.clientHeight;
|
|
1313
|
+
if (typeof bodyHeight === "number" && Number.isFinite(bodyHeight) && bodyHeight > 0) {
|
|
1314
|
+
return bodyHeight;
|
|
1315
|
+
}
|
|
1316
|
+
return 0;
|
|
1317
|
+
}
|
|
1318
|
+
function readCssSafeAreaValue(bridge, cssValue) {
|
|
1319
|
+
const doc = bridge.document;
|
|
1320
|
+
const root = doc?.body ?? doc?.documentElement;
|
|
1321
|
+
if (!doc || !root || typeof doc.createElement !== "function" || typeof root.appendChild !== "function" || typeof bridge.getComputedStyle !== "function") {
|
|
1287
1322
|
return 0;
|
|
1288
1323
|
}
|
|
1289
|
-
|
|
1324
|
+
const probe = doc.createElement("div");
|
|
1325
|
+
probe.style.position = "fixed";
|
|
1326
|
+
probe.style.top = "0";
|
|
1327
|
+
probe.style.left = "0";
|
|
1328
|
+
probe.style.width = "0";
|
|
1329
|
+
probe.style.height = "0";
|
|
1330
|
+
probe.style.visibility = "hidden";
|
|
1331
|
+
probe.style.pointerEvents = "none";
|
|
1332
|
+
probe.style.paddingTop = cssValue;
|
|
1333
|
+
root.appendChild(probe);
|
|
1334
|
+
try {
|
|
1335
|
+
return clampSafeAreaTopPixels(bridge.getComputedStyle(probe).paddingTop);
|
|
1336
|
+
} finally {
|
|
1337
|
+
if (typeof probe.remove === "function") {
|
|
1338
|
+
probe.remove();
|
|
1339
|
+
} else {
|
|
1340
|
+
probe.parentNode?.removeChild(probe);
|
|
1341
|
+
}
|
|
1342
|
+
}
|
|
1343
|
+
}
|
|
1344
|
+
function readCssSafeAreaTopPixels(bridge) {
|
|
1345
|
+
const envPixels = readCssSafeAreaValue(bridge, "env(safe-area-inset-top)");
|
|
1346
|
+
if (envPixels > 0) {
|
|
1347
|
+
return envPixels;
|
|
1348
|
+
}
|
|
1349
|
+
return readCssSafeAreaValue(bridge, "constant(safe-area-inset-top)");
|
|
1350
|
+
}
|
|
1351
|
+
function getDevicePixelRatio(bridge) {
|
|
1352
|
+
const dpr = bridge.devicePixelRatio;
|
|
1353
|
+
if (typeof dpr !== "number" || !Number.isFinite(dpr) || dpr <= 0) {
|
|
1354
|
+
return 1;
|
|
1355
|
+
}
|
|
1356
|
+
return dpr;
|
|
1357
|
+
}
|
|
1358
|
+
function roughlyEqualPixels(a, b) {
|
|
1359
|
+
return Math.abs(a - b) <= 2;
|
|
1360
|
+
}
|
|
1361
|
+
function normalizeSafeAreaTopPixels(value, bridge) {
|
|
1362
|
+
const pixels = clampSafeAreaTopPixels(value);
|
|
1363
|
+
const cssEnvPixels = readCssSafeAreaTopPixels(bridge);
|
|
1364
|
+
if (pixels <= 0) {
|
|
1365
|
+
return cssEnvPixels;
|
|
1366
|
+
}
|
|
1367
|
+
const dpr = getDevicePixelRatio(bridge);
|
|
1368
|
+
if (cssEnvPixels > 0 && dpr > 1 && roughlyEqualPixels(pixels / dpr, cssEnvPixels)) {
|
|
1369
|
+
return cssEnvPixels;
|
|
1370
|
+
}
|
|
1371
|
+
return pixels;
|
|
1290
1372
|
}
|
|
1291
1373
|
function pixelsTopToPercentOfViewport(pixels, bridge) {
|
|
1292
|
-
const h =
|
|
1374
|
+
const h = getViewportHeight(bridge);
|
|
1293
1375
|
if (h <= 0) {
|
|
1294
1376
|
return 0;
|
|
1295
1377
|
}
|
|
1296
|
-
return normalizeSafeAreaTopPercent(pixels / h * 100);
|
|
1378
|
+
return normalizeSafeAreaTopPercent(pixels / h * 100) ?? 0;
|
|
1379
|
+
}
|
|
1380
|
+
function cssSafeAreaTopPercent(bridge) {
|
|
1381
|
+
return pixelsTopToPercentOfViewport(readCssSafeAreaTopPixels(bridge), bridge);
|
|
1382
|
+
}
|
|
1383
|
+
function resolvePercentValue(value, bridge) {
|
|
1384
|
+
const percent = normalizeSafeAreaTopPercent(value);
|
|
1385
|
+
if (typeof percent === "undefined") {
|
|
1386
|
+
return void 0;
|
|
1387
|
+
}
|
|
1388
|
+
return percent > 0 ? percent : cssSafeAreaTopPercent(bridge);
|
|
1389
|
+
}
|
|
1390
|
+
function resolvePixelValue(value, bridge) {
|
|
1391
|
+
const numeric = toFiniteNumber(value);
|
|
1392
|
+
if (typeof numeric === "undefined") {
|
|
1393
|
+
return void 0;
|
|
1394
|
+
}
|
|
1395
|
+
return pixelsTopToPercentOfViewport(normalizeSafeAreaTopPixels(numeric, bridge), bridge);
|
|
1297
1396
|
}
|
|
1298
1397
|
function getSafeAreaTop() {
|
|
1299
1398
|
const bridge = getBridgeWindow8();
|
|
@@ -1301,18 +1400,32 @@ function getSafeAreaTop() {
|
|
|
1301
1400
|
return 0;
|
|
1302
1401
|
}
|
|
1303
1402
|
if (typeof bridge.getSafeAreaTopPercent === "function") {
|
|
1304
|
-
|
|
1403
|
+
const percent = resolvePercentValue(bridge.getSafeAreaTopPercent(), bridge);
|
|
1404
|
+
if (typeof percent !== "undefined") {
|
|
1405
|
+
return percent;
|
|
1406
|
+
}
|
|
1305
1407
|
}
|
|
1306
1408
|
if (typeof bridge.__OASIZ_SAFE_AREA_TOP_PERCENT__ !== "undefined") {
|
|
1307
|
-
|
|
1409
|
+
const percent = resolvePercentValue(bridge.__OASIZ_SAFE_AREA_TOP_PERCENT__, bridge);
|
|
1410
|
+
if (typeof percent !== "undefined") {
|
|
1411
|
+
return percent;
|
|
1412
|
+
}
|
|
1308
1413
|
}
|
|
1309
1414
|
if (typeof bridge.getSafeAreaTop === "function") {
|
|
1310
|
-
const
|
|
1311
|
-
|
|
1415
|
+
const percent = resolvePixelValue(bridge.getSafeAreaTop(), bridge);
|
|
1416
|
+
if (typeof percent !== "undefined") {
|
|
1417
|
+
return percent;
|
|
1418
|
+
}
|
|
1312
1419
|
}
|
|
1313
1420
|
if (typeof bridge.__OASIZ_SAFE_AREA_TOP__ !== "undefined") {
|
|
1314
|
-
const
|
|
1315
|
-
|
|
1421
|
+
const percent = resolvePixelValue(bridge.__OASIZ_SAFE_AREA_TOP__, bridge);
|
|
1422
|
+
if (typeof percent !== "undefined") {
|
|
1423
|
+
return percent;
|
|
1424
|
+
}
|
|
1425
|
+
}
|
|
1426
|
+
const cssPercent = cssSafeAreaTopPercent(bridge);
|
|
1427
|
+
if (cssPercent > 0) {
|
|
1428
|
+
return cssPercent;
|
|
1316
1429
|
}
|
|
1317
1430
|
warnMissingBridge6("getSafeAreaTop");
|
|
1318
1431
|
return 0;
|