forked from servo/servo
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Basic tab strip for the minibrowser (servo#33100)
This implements a simple tab system for servoshell: - The egui part uses the built-in SelectableLabels components and display the full tab title on hover. - WebView structs now hold all the state for each WebView. When we need "global" state, we return the focused WebView state, eg. for the load status since it's still global in the UI. - New keyboard shortcut: [Cmd-or-Ctrl]+[W] to close the current tab. - New keyboard shortcut: [Cmd-or-Ctrl]+[T] to create a new tab. - The new tab content is loaded from the 'servo:newtab' url using a couple of custom protocol handlers. Signed-off-by: webbeef <[email protected]>
- Loading branch information
Showing
14 changed files
with
454 additions
and
71 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
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
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
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
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
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
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
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,108 @@ | ||
/* This Source Code Form is subject to the terms of the Mozilla Public | ||
* License, v. 2.0. If a copy of the MPL was not distributed with this | ||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */ | ||
|
||
//! This protocol handler loads files from the <resources_dir_path()>/protocol/resource directory, | ||
//! sanitizing the path to prevent path escape attacks. | ||
//! For security reasons, loads are only allowed if the referrer has a 'resource' or | ||
//! 'servo' scheme. | ||
use std::fs::File; | ||
use std::future::Future; | ||
use std::io::BufReader; | ||
use std::pin::Pin; | ||
|
||
use headers::{ContentType, HeaderMapExt}; | ||
use net::fetch::methods::{DoneChannel, FetchContext}; | ||
use net::filemanager_thread::FILE_CHUNK_SIZE; | ||
use net::protocols::ProtocolHandler; | ||
use net_traits::filemanager_thread::RelativePos; | ||
use net_traits::request::Request; | ||
use net_traits::response::{Response, ResponseBody}; | ||
use net_traits::ResourceFetchTiming; | ||
use tokio::sync::mpsc::unbounded_channel; | ||
|
||
#[derive(Default)] | ||
pub struct ResourceProtocolHander {} | ||
|
||
impl ResourceProtocolHander { | ||
pub fn response_for_path( | ||
request: &mut Request, | ||
done_chan: &mut DoneChannel, | ||
context: &FetchContext, | ||
path: &str, | ||
) -> Pin<Box<dyn Future<Output = Response> + Send>> { | ||
if path.contains("..") || !path.starts_with("/") { | ||
return Box::pin(std::future::ready(Response::network_internal_error( | ||
"Invalid path", | ||
))); | ||
} | ||
|
||
let path = if let Some(path) = path.strip_prefix("/") { | ||
path | ||
} else { | ||
return Box::pin(std::future::ready(Response::network_internal_error( | ||
"Invalid path", | ||
))); | ||
}; | ||
|
||
let file_path = crate::resources::resources_dir_path() | ||
.join("resource_protocol") | ||
.join(path); | ||
|
||
if !file_path.exists() || file_path.is_dir() { | ||
return Box::pin(std::future::ready(Response::network_internal_error( | ||
"Invalid path", | ||
))); | ||
} | ||
|
||
let response = if let Ok(file) = File::open(file_path.clone()) { | ||
let mut response = Response::new( | ||
request.current_url(), | ||
ResourceFetchTiming::new(request.timing_type()), | ||
); | ||
let reader = BufReader::with_capacity(FILE_CHUNK_SIZE, file); | ||
|
||
// Set Content-Type header. | ||
let mime = mime_guess::from_path(file_path).first_or_octet_stream(); | ||
response.headers.typed_insert(ContentType::from(mime)); | ||
|
||
// Setup channel to receive cross-thread messages about the file fetch | ||
// operation. | ||
let (mut done_sender, done_receiver) = unbounded_channel(); | ||
*done_chan = Some((done_sender.clone(), done_receiver)); | ||
|
||
*response.body.lock().unwrap() = ResponseBody::Receiving(vec![]); | ||
|
||
context.filemanager.lock().unwrap().fetch_file_in_chunks( | ||
&mut done_sender, | ||
reader, | ||
response.body.clone(), | ||
context.cancellation_listener.clone(), | ||
RelativePos::full_range(), | ||
); | ||
|
||
response | ||
} else { | ||
Response::network_internal_error("Opening file failed") | ||
}; | ||
|
||
Box::pin(std::future::ready(response)) | ||
} | ||
} | ||
|
||
impl ProtocolHandler for ResourceProtocolHander { | ||
fn load( | ||
&self, | ||
request: &mut Request, | ||
done_chan: &mut DoneChannel, | ||
context: &FetchContext, | ||
) -> Pin<Box<dyn Future<Output = Response> + Send>> { | ||
let url = request.current_url(); | ||
|
||
// TODO: Check referrer. | ||
// We unexpectedly get `NoReferrer` for all requests from the newtab page. | ||
|
||
Self::response_for_path(request, done_chan, context, url.path()) | ||
} | ||
} |
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,43 @@ | ||
/* This Source Code Form is subject to the terms of the Mozilla Public | ||
* License, v. 2.0. If a copy of the MPL was not distributed with this | ||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */ | ||
|
||
//! Loads resources using a mapping from well-known shortcuts to resource: urls. | ||
//! Recognized shorcuts: | ||
//! - servo:newtab | ||
use std::future::Future; | ||
use std::pin::Pin; | ||
|
||
use net::fetch::methods::{DoneChannel, FetchContext}; | ||
use net::protocols::ProtocolHandler; | ||
use net_traits::request::Request; | ||
use net_traits::response::Response; | ||
|
||
use crate::desktop::protocols::resource::ResourceProtocolHander; | ||
|
||
#[derive(Default)] | ||
pub struct ServoProtocolHander {} | ||
|
||
impl ProtocolHandler for ServoProtocolHander { | ||
fn load( | ||
&self, | ||
request: &mut Request, | ||
done_chan: &mut DoneChannel, | ||
context: &FetchContext, | ||
) -> Pin<Box<dyn Future<Output = Response> + Send>> { | ||
let url = request.current_url(); | ||
|
||
match url.path() { | ||
"newtab" => ResourceProtocolHander::response_for_path( | ||
request, | ||
done_chan, | ||
context, | ||
"/newtab.html", | ||
), | ||
_ => Box::pin(std::future::ready(Response::network_internal_error( | ||
"Invalid shortcut", | ||
))), | ||
} | ||
} | ||
} |
Oops, something went wrong.