Skip to content

Commit

Permalink
feat: new DOM HandleVisualViewportFeature
Browse files Browse the repository at this point in the history
This feature uses the new VisualViewport API, and requires a recent
browser.
  • Loading branch information
jsamr committed Sep 25, 2020
1 parent 6da2358 commit 0577cbf
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 0 deletions.
57 changes: 57 additions & 0 deletions packages/core/src/features/HandleVisualViewportFeature.ts
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 packages/core/src/features/HandleVisualViewportFeature.webjs
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;
}
}

0 comments on commit 0577cbf

Please sign in to comment.