Product
Socket Now Supports uv.lock Files
Socket now supports uv.lock files to ensure consistent, secure dependency resolution for Python projects and enhance supply chain security.
@formidable-webview/webshell
Advanced tools
🚀 A Higher-order component to handle WebView DOM events in React Native
:warning: This library is in early development.
Webshell is:
WebView
DOM events in react-native
. It
provides an abstraction layer over the message
system
embedded in
react-native-webview
.WebView
) DOM.Here are examples of features shipped with this library:
linkPressFeature
);dimensionsFeature
);And you can, of course, implement any feature you'd like.
It uses WebView#injectedJavascript
prop to inject javascript “features” (snippets) responsible
for communicating information to the Webshell
controller.
npm install @formidable-webview/webshell
This library is fairly easy to use. Just create a shell by invoking makeShell
function with a WebView
component and the assembled features you wish the
shell to implement. Each feature can be assembled with options, which alter
their behavior. For example, the linkPressFeature
default behavior prevents
click events on anchors to propagate, effectively disallowing redirects. You
can, however, change this behavior to let redirects happen while still being
notified by setting preventDefault
option to false
.
// integration/basic.tsx
import React, { useCallback } from 'react';
import { Linking } from 'react-native';
import makeWebshell, {
linkPressFeature,
dimensionsFeature,
DimensionsObject
} from '@formidable-webview/webshell';
import WebView from 'react-native-webview';
const Webshell = makeWebshell(
WebView,
linkPressFeature.assemble({ preventDefault: true }),
dimensionsFeature.assemble({ tagName: 'table' })
);
export default function EnhancedWebView(webViewProps) {
const onLinkPress = useCallback((url: string) => Linking.openURL(url), []);
const onDimensions = useCallback(
({ width, height }: DimensionsObject) => console.info(width, height),
[]
);
const onShellError = useCallback(
// featureIdentifier == linkPressFeature.identifier
(featureIdentifier, errorMessage) => {
if (featureIdentifier === linkPressFeature.identifier) {
// Handle linkPress error
console.error(errorMessage);
} else if (featureIdentifier === dimensionsFeature.identifier) {
// Handle dimensions error
console.error(errorMessage);
}
},
[]
);
return (
<Webshell
onLinkPress={onLinkPress}
onDimensions={onDimensions}
onShellError={onShellError}
webViewProps={webViewProps}
/>
);
}
To have a good sense on how to implement features, we will take a look at the
linkPressFeature
implementation. The implementation is in typescript, which
is convenient to communicate the different types implied in a feature. There
are four important areas to specify in a feature:
linkPressScript
.LinkPressOptions
Webshell
? → onLinkPress
string
// src/features/link-press.ts
import linkPressScript from './link-press.webjs';
import { makeFeature } from '../make-feature';
import type { Feature } from '../types';
/**
* An object describing customization for the linkPress feature.
*
* @public
*/
export interface LinkPressOptions {
/**
* Prevent click events on anchors to propagate.
*
* @defaultValue true
*/
preventDefault?: boolean;
}
/**
* This feature allows to intercept clicks on anchors (`<a>`). By default, it
* will prevent the click from propagating. But you can disable this option.
*
* @public
*/
export const linkPressFeature: Feature<
LinkPressOptions,
'onLinkPress',
string
> = makeFeature({
script: linkPressScript,
eventHandlerName: 'onLinkPress',
identifier: 'org.webshell.linkPress'
});
:warning: Please note that you will need to replace
import ... from
.
The behavior in the DOM is implemented in the following file (please note that the extension is arbitrary, see the tooling section):
// src/features/link-press.webjs
function linkPressFeature(arg) {
var postMessage = arg.postMessage;
var options = arg.options || {};
var preventDefault = options.preventDefault !== false;
function findParent(tagname, el) {
while (el) {
if ((el.nodeName || el.tagName).toLowerCase() === tagname.toLowerCase()) {
return el;
}
el = el.parentNode;
}
return null;
}
function interceptClickEvent(e) {
var href;
var target = e.target || e.srcElement;
var anchor = findParent('a', target);
if (anchor) {
href = anchor.getAttribute('href');
preventDefault && e.preventDefault();
postMessage(href);
}
}
document.addEventListener('click', interceptClickEvent);
}
Every DOM script top declaration must be a function taking one argument. The shape of this argument is depicted in WebjsContext definition. For wide compatibility purposes, it is recommended to
See the tooling section for more details on how to achieve this.
The API reference is build with the amazing @microsoft/api-extractor utility. Read the API here: doc/webshell.md.
The original idea behind this project was to perform code quality control over
scripts injected into WebViews
, because they are parts of the codebase. To
achieve that purpose, we are using babel and eslint original plugins.
The most important thing is to use Babel Inline
Import with webjs
or whichever extension you are using for your WebView
scripts, see
babel.config.js file. This plugin will allow you to import
scripts as strings instead of compiling the module!
We are using the overrides
feature to target webjs
files with specific
options:
WebView
backends.See our .eslintrc.js file.
Jest will use our babel config file if babel-jest
is installed. The most
important aspect of our jest setup is that it has two configurations:
react-native
preset,
core.jest.config.js;jsdom
testing environment,
web.jest.config.js.To run jest with multiple configurations, you just need to set the projects attribute as an array of config files.
The last thing you need to do is associate Javascript syntax with the custom extension you have chosen in your text editor. From now-on, you will have a full featured QC in those scripts!
FAQs
🔥 Craft Robust React Native WebView-based components with ease.
The npm package @formidable-webview/webshell receives a total of 7,484 weekly downloads. As such, @formidable-webview/webshell popularity was classified as popular.
We found that @formidable-webview/webshell demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Product
Socket now supports uv.lock files to ensure consistent, secure dependency resolution for Python projects and enhance supply chain security.
Research
Security News
Socket researchers have discovered multiple malicious npm packages targeting Solana private keys, abusing Gmail to exfiltrate the data and drain Solana wallets.
Security News
PEP 770 proposes adding SBOM support to Python packages to improve transparency and catch hidden non-Python dependencies that security tools often miss.