-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: new DOM HandleVisualViewportFeature
This feature uses the new VisualViewport API, and requires a recent browser.
- Loading branch information
Showing
2 changed files
with
95 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import script from './HandleVisualViewportFeature.webjs'; | ||
import { FeatureBuilder } from '../FeatureBuilder'; | ||
import type { RectSize } from './types'; | ||
import { FeatureConstructor } from '../Feature'; | ||
import { PropDefinition } from '../types'; | ||
|
||
/** | ||
* An object describing the visual viewport of the `WebView`. | ||
* | ||
* @public | ||
*/ | ||
export interface VisualViewportDimensions { | ||
/** | ||
* The visual viewport scale. Because this API is quite recent, we have a | ||
* fallback strategy to compute scale. | ||
* | ||
* @remarks | ||
* The other values in this object are already in React Native dpi units. | ||
*/ | ||
scale: number; | ||
/** | ||
* window.visualViewport.width and window.visualViewport.height | ||
*/ | ||
visualViewport: RectSize; | ||
/** | ||
* `false` when these values are coming from the VisualViewport API and | ||
* `true` when they are "best guess". In legacy mode, be warned that you will | ||
* not receive frequent updates when the user pinch-zoom. | ||
*/ | ||
isLegacy: boolean; | ||
} | ||
|
||
/** | ||
* This feature adds a handler triggered when the visual viewport changes. It | ||
* requires VisualViewport API support on browsers (iOS Safari 13 and Android | ||
* WebView 62). | ||
* See {@link https://developer.mozilla.org/en-US/docs/Web/API/VisualViewport | VisualViewport API}. | ||
* | ||
* @beta | ||
*/ | ||
export const HandleVisualViewportFeature: FeatureConstructor< | ||
{}, | ||
[ | ||
PropDefinition<{ | ||
onDOMVisualViewport?: (d: VisualViewportDimensions) => void; | ||
}> | ||
] | ||
> = new FeatureBuilder({ | ||
script, | ||
defaultOptions: {}, | ||
className: 'HandleVisualViewportFeature', | ||
featureIdentifier: 'org.formidable-webview/webshell.handle-visual-viewport' | ||
}) | ||
.withEventHandlerProp<VisualViewportDimensions, 'onDOMVisualViewport'>( | ||
'onDOMVisualViewport' | ||
) | ||
.build(); |
38 changes: 38 additions & 0 deletions
38
packages/core/src/features/HandleVisualViewportFeature.webjs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
function HandleVisualViewportFeature(context) { | ||
var postMessage = context.postMessage; | ||
var options = context.options || {}; | ||
var isLegacy = !window.visualViewport; | ||
var postSize = context.makeCallbackSafe(function () { | ||
var scale = !isLegacy | ||
? window.visualViewport.scale | ||
: screen.availWidth && window.innerWidth | ||
? screen.availWidth / window.innerWidth | ||
: screen.width / window.innerWidth; | ||
var viewportRect = document.documentElement.getBoundingClientRect(); | ||
var layoutViewport = { | ||
width: viewportRect.width, | ||
height: viewportRect.height | ||
}; | ||
var visualViewport = { | ||
width: isLegacy | ||
? layoutViewport.width / scale | ||
: window.visualViewport.width, | ||
height: isLegacy | ||
? layoutViewport.height / scale | ||
: window.visualViewport.height | ||
}; | ||
var dimensions = { | ||
scale: scale, | ||
visualViewport: visualViewport, | ||
isLegacy: isLegacy | ||
}; | ||
postMessage(dimensions); | ||
}); | ||
postSize(); | ||
if (isLegacy) { | ||
context.warn('VisualViewport API is unavailable.'); | ||
window.onresize = postSize; | ||
} else { | ||
window.visualViewport.onresize = postSize; | ||
} | ||
} |