44
55//! A web browser with UI powered by Dioxus Native and content rendering powered by Blitz
66
7+ use std:: cell:: RefCell ;
78use std:: rc:: Rc ;
89use std:: sync:: { Arc , atomic:: AtomicUsize , atomic:: Ordering as Ao } ;
910
1011use blitz_traits:: shell:: ShellProvider ;
1112use dioxus_core:: Task ;
12- use dioxus_native:: { SubDocumentAttr , prelude:: * } ;
13+ use dioxus_native:: { NodeHandle , SubDocumentAttr , prelude:: * } ;
1314
1415use blitz_dom:: { DocumentConfig , FontContext } ;
1516use blitz_html:: { HtmlDocument , HtmlProvider } ;
@@ -40,7 +41,11 @@ fn use_sync_store<T: Send + Sync + 'static>(value: impl FnOnce() -> T) -> SyncSt
4041fn app ( ) -> Element {
4142 let home_url = use_hook ( || Url :: parse ( "https://html.duckduckgo.com" ) . unwrap ( ) ) ;
4243
44+ let mut url_input_handle = use_signal ( || None ) ;
45+ let mut webview_node_handle: Signal < Option < NodeHandle > > = use_signal ( || None ) ;
4346 let mut url_input_value = use_signal ( || home_url. to_string ( ) ) ;
47+ let mut is_focussed = use_signal ( || false ) ;
48+ let block_mouse_up = use_hook ( || Rc :: new ( RefCell :: new ( false ) ) ) ;
4449 let mut history: SyncStore < History > = use_sync_store ( || History :: new ( home_url. clone ( ) ) ) ;
4550
4651 let net_provider = use_context :: < Arc < StdNetProvider > > ( ) ;
@@ -63,6 +68,21 @@ fn app() -> Element {
6368 let open_action =
6469 use_callback ( move |_| open_in_external_browser ( & history. current_url ( ) . read ( ) ) ) ;
6570
71+ let devtools_action = use_callback ( move |_| {
72+ if let Some ( handle) = webview_node_handle ( ) {
73+ let node_id = handle. node_id ( ) ;
74+ let mut doc = handle. doc_mut ( ) ;
75+ if let Some ( sub_doc) = doc
76+ . get_node_mut ( node_id)
77+ . and_then ( |node| node. element_data_mut ( ) )
78+ . and_then ( |el| el. sub_doc_data_mut ( ) )
79+ {
80+ let mut sub_doc = sub_doc. inner_mut ( ) ;
81+ sub_doc. devtools_mut ( ) . toggle_highlight_hover ( ) ;
82+ }
83+ }
84+ } ) ;
85+
6686 rsx ! (
6787 div { id: "frame" ,
6888 title { "Blitz Browser" }
@@ -79,6 +99,40 @@ fn app() -> Element {
7999 "type" : "text" ,
80100 name: "url" ,
81101 value: url_input_value( ) ,
102+ onmounted: move |evt: Event <MountedData >| {
103+ let node_handle = evt. downcast:: <NodeHandle >( ) . unwrap( ) ;
104+ * url_input_handle. write( ) = Some ( node_handle. clone( ) ) ;
105+ } ,
106+ onblur: move |_evt| {
107+ * is_focussed. write( ) = false ;
108+ } ,
109+ onfocus: move |_evt| {
110+ * is_focussed. write( ) = true ;
111+ if let Some ( handle) = url_input_handle( ) {
112+ let node_id = handle. node_id( ) ;
113+ let mut doc = handle. doc_mut( ) ;
114+ doc. with_text_input( node_id, |mut driver| driver. select_all( ) ) ;
115+ }
116+ } ,
117+ onmousedown: {
118+ let block_mouse_up = block_mouse_up. clone( ) ;
119+ move |_evt| {
120+ * block_mouse_up. borrow_mut( ) = !is_focussed( ) ;
121+ }
122+ } ,
123+ onmousemove: {
124+ let block_mouse_up = block_mouse_up. clone( ) ;
125+ move |evt| {
126+ if * block_mouse_up. borrow( ) {
127+ evt. prevent_default( ) ;
128+ }
129+ }
130+ } ,
131+ onmouseup: move |evt| {
132+ if * block_mouse_up. borrow( ) {
133+ evt. prevent_default( ) ;
134+ }
135+ } ,
82136 onkeydown: move |evt| {
83137 if evt. key( ) == Key :: Enter {
84138 evt. prevent_default( ) ;
@@ -93,11 +147,18 @@ fn app() -> Element {
93147 oninput: move |evt| { * url_input_value. write( ) = evt. value( ) } ,
94148 }
95149 IconButton { icon: icons:: EXTERNAL_LINK_ICON , action: open_action }
96- IconButton { icon: icons:: MENU_ICON }
150+ IconButton { icon: icons:: MENU_ICON , action : devtools_action }
97151 }
98152
99153 // Web content
100- web-view { class: "webview" , "__webview_document" : content_doc( ) }
154+ web-view {
155+ class: "webview" ,
156+ "__webview_document" : content_doc( ) ,
157+ onmounted: move |evt: Event <MountedData >| {
158+ let node_handle = evt. downcast:: <NodeHandle >( ) . unwrap( ) ;
159+ * webview_node_handle. write( ) = Some ( node_handle. clone( ) ) ;
160+ } ,
161+ }
101162 }
102163 )
103164}
0 commit comments