feat: unify webview source into WebviewSource enum with dynamic reload (#22)

Unify CefWebviewUri and InlineHtml into a single WebviewSource enum component, eliminating the dual-component inconsistency where both existed on the same entity
Add ResolvedWebviewUri internal component as a resolution layer between user-facing source and CEF
Support dynamic reload: mutating WebviewSource at runtime automatically navigates the existing browser via browsers.navigate() without recreation
Inline HTML is served via cef://localhost/__inline__/{id} with automatic cleanup on entity despawn
This commit is contained in:
elm
2026-02-12 15:26:47 +09:00
committed by GitHub
parent a6fec33006
commit 1b1da6665c
22 changed files with 249 additions and 54 deletions

View File

@@ -51,7 +51,7 @@ fn spawn_webview(
mut materials: ResMut<Assets<WebviewExtendStandardMaterial>>,
) {
commands.spawn((
CefWebviewUri::local("brp.html"),
WebviewSource::local("brp.html"),
Mesh3d(meshes.add(Plane3d::new(Vec3::Z, Vec2::ONE))),
MeshMaterial3d(materials.add(WebviewExtendStandardMaterial {
base: StandardMaterial {
@@ -72,7 +72,7 @@ fn ime(mut windows: Query<&mut bevy::prelude::Window>) {
fn show_devtool(
mut commands: Commands,
webviews: Query<Entity, With<CefWebviewUri>>,
webviews: Query<Entity, With<WebviewSource>>,
mut initialized: Local<bool>,
) {
if *initialized {

View File

@@ -33,7 +33,7 @@ fn spawn_webview(
asset_server: Res<AssetServer>,
) {
commands.spawn((
CefWebviewUri::new("https://github.com/not-elm/bevy_cef"),
WebviewSource::new("https://github.com/not-elm/bevy_cef"),
Mesh3d(meshes.add(Plane3d::new(Vec3::Z, Vec2::ONE))),
MeshMaterial3d(materials.add(WebviewExtendedMaterial {
extension: CustomExtension {

View File

@@ -49,7 +49,7 @@ fn spawn_webview(
) {
commands.spawn((
DebugWebview,
CefWebviewUri::new("https://github.com/not-elm/bevy_cef"),
WebviewSource::new("https://github.com/not-elm/bevy_cef"),
Mesh3d(meshes.add(Plane3d::new(Vec3::Z, Vec2::ONE))),
MeshMaterial3d(materials.add(WebviewExtendStandardMaterial {
base: StandardMaterial {

View File

@@ -64,7 +64,7 @@ fn spawn_webview(
mut materials: ResMut<Assets<WebviewExtendStandardMaterial>>,
) {
commands.spawn((
CefWebviewUri::local("extensions.html"),
WebviewSource::local("extensions.html"),
Mesh3d(meshes.add(Plane3d::new(Vec3::Z, Vec2::ONE))),
MeshMaterial3d(materials.add(WebviewExtendStandardMaterial::default())),
));

View File

@@ -40,7 +40,7 @@ fn spawn_webview(
) {
commands.spawn((
DebugWebview,
CefWebviewUri::local("host_emit.html"),
WebviewSource::local("host_emit.html"),
Mesh3d(meshes.add(Plane3d::new(Vec3::Z, Vec2::ONE))),
MeshMaterial3d(materials.add(WebviewExtendStandardMaterial::default())),
));

67
examples/inline_html.rs Normal file
View File

@@ -0,0 +1,67 @@
//! Demonstrates rendering inline HTML content directly without an external URL or asset file.
use bevy::prelude::*;
use bevy_cef::prelude::*;
fn main() {
App::new()
.add_plugins((DefaultPlugins, CefPlugin::default()))
.add_systems(
Startup,
(spawn_camera, spawn_directional_light, spawn_webview),
)
.run();
}
fn spawn_camera(mut commands: Commands) {
commands.spawn((
Camera3d::default(),
Transform::from_translation(Vec3::new(0., 0., 3.)).looking_at(Vec3::ZERO, Vec3::Y),
));
}
fn spawn_directional_light(mut commands: Commands) {
commands.spawn((
DirectionalLight::default(),
Transform::from_translation(Vec3::new(1., 1., 1.)).looking_at(Vec3::ZERO, Vec3::Y),
));
}
fn spawn_webview(
mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<WebviewExtendStandardMaterial>>,
) {
commands.spawn((
WebviewSource::inline(
r#"<!DOCTYPE html>
<html>
<head>
<style>
body {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
font-family: system-ui, sans-serif;
color: white;
}
.container { text-align: center; }
h1 { font-size: 3rem; margin-bottom: 0.5rem; }
p { font-size: 1.2rem; opacity: 0.8; }
</style>
</head>
<body>
<div class="container">
<h1>Inline HTML</h1>
<p>This content is rendered from a Rust string.</p>
</div>
</body>
</html>"#,
),
Mesh3d(meshes.add(Plane3d::new(Vec3::Z, Vec2::ONE))),
MeshMaterial3d(materials.add(WebviewExtendStandardMaterial::default())),
));
}

View File

@@ -48,7 +48,7 @@ fn spawn_webview(
mut materials: ResMut<Assets<WebviewExtendStandardMaterial>>,
) {
commands.spawn((
CefWebviewUri::local("js_emit.html"),
WebviewSource::local("js_emit.html"),
Mesh3d(meshes.add(Plane3d::new(Vec3::Z, Vec2::ONE))),
MeshMaterial3d(materials.add(WebviewExtendStandardMaterial::default())),
));

View File

@@ -50,7 +50,7 @@ fn spawn_webview(
) {
commands.spawn((
DebugWebview,
CefWebviewUri::new("https://github.com/not-elm/bevy_cef"),
WebviewSource::new("https://github.com/not-elm/bevy_cef"),
Mesh3d(meshes.add(Plane3d::new(Vec3::Z, Vec2::ONE))),
MeshMaterial3d(materials.add(WebviewExtendStandardMaterial::default())),
));

View File

@@ -35,7 +35,7 @@ fn spawn_webview(
mut materials: ResMut<Assets<WebviewExtendStandardMaterial>>,
) {
commands.spawn((
CefWebviewUri::new("https://github.com/not-elm/bevy_cef"),
WebviewSource::new("https://github.com/not-elm/bevy_cef"),
Mesh3d(meshes.add(Plane3d::new(Vec3::Z, Vec2::ONE))),
MeshMaterial3d(materials.add(WebviewExtendStandardMaterial::default())),
// Here, we add a simple script to show an alert.

View File

@@ -33,7 +33,7 @@ fn spawn_webview(
mut materials: ResMut<Assets<WebviewExtendStandardMaterial>>,
) {
commands.spawn((
CefWebviewUri::new("https://github.com/not-elm/bevy_cef"),
WebviewSource::new("https://github.com/not-elm/bevy_cef"),
Mesh3d(meshes.add(Plane3d::new(Vec3::Z, Vec2::ONE))),
MeshMaterial3d(materials.add(WebviewExtendStandardMaterial::default())),
));

View File

@@ -16,7 +16,7 @@ fn spawn_camera_2d(mut commands: Commands) {
fn spawn_sprite_webview(mut commands: Commands, mut images: ResMut<Assets<Image>>) {
commands.spawn((
CefWebviewUri::new("https://github.com/not-elm/bevy_cef"),
WebviewSource::new("https://github.com/not-elm/bevy_cef"),
Pickable::default(),
Sprite {
image: images.add(Image::default()),

View File

@@ -35,7 +35,7 @@ fn spawn_webview(
mut materials: ResMut<Assets<WebviewExtendStandardMaterial>>,
) {
commands.spawn((
CefWebviewUri("https://bevy.org/".to_string()),
WebviewSource::new("https://bevy.org/"),
Mesh3d(meshes.add(Plane3d::new(Vec3::Z, Vec2::ONE))),
MeshMaterial3d(materials.add(WebviewExtendStandardMaterial::default())),
));