mirror of
https://github.com/servo/servo.git
synced 2025-08-03 04:30:10 +01:00
Auto merge of #6219 - zmike:favicons_and_stringlOWWW-MY-HEAD, r=pcwalton
Getting these down to the embedding API level required that I redo the bindings generator again, so this is more commits than anticipated. @mbrubeck @Manishearth @pcwalton but NOT @larsbergstrom so don't even look at this. <!-- Reviewable:start --> [<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/6219) <!-- Reviewable:end -->
This commit is contained in:
commit
b0f3417cff
26 changed files with 182 additions and 62 deletions
|
@ -454,6 +454,14 @@ impl<Window: WindowMethods> IOCompositor<Window> {
|
|||
self.composite_if_necessary(CompositingReason::Headless);
|
||||
}
|
||||
|
||||
(Msg::NewFavicon(url), ShutdownState::NotShuttingDown) => {
|
||||
self.window.set_favicon(url);
|
||||
}
|
||||
|
||||
(Msg::HeadParsed, ShutdownState::NotShuttingDown) => {
|
||||
self.window.head_parsed();
|
||||
}
|
||||
|
||||
// When we are shutting_down, we need to avoid performing operations
|
||||
// such as Paint that may crash because we have begun tearing down
|
||||
// the rest of our resources.
|
||||
|
|
|
@ -180,6 +180,10 @@ pub enum Msg {
|
|||
ViewportConstrained(PipelineId, ViewportConstraints),
|
||||
/// A reply to the compositor asking if the output image is stable.
|
||||
IsReadyToSaveImageReply(bool),
|
||||
/// A favicon was detected
|
||||
NewFavicon(Url),
|
||||
/// <head> tag finished parsing
|
||||
HeadParsed,
|
||||
}
|
||||
|
||||
impl Debug for Msg {
|
||||
|
@ -206,6 +210,8 @@ impl Debug for Msg {
|
|||
Msg::PaintTaskExited(..) => write!(f, "PaintTaskExited"),
|
||||
Msg::ViewportConstrained(..) => write!(f, "ViewportConstrained"),
|
||||
Msg::IsReadyToSaveImageReply(..) => write!(f, "IsReadyToSaveImageReply"),
|
||||
Msg::NewFavicon(..) => write!(f, "NewFavicon"),
|
||||
Msg::HeadParsed => write!(f, "HeadParsed"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -468,6 +468,14 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
|
|||
debug!("constellation got remove iframe message");
|
||||
self.handle_remove_iframe_msg(containing_pipeline_id, subpage_id);
|
||||
}
|
||||
ConstellationMsg::NewFavicon(url) => {
|
||||
debug!("constellation got new favicon message");
|
||||
self.compositor_proxy.send(CompositorMsg::NewFavicon(url));
|
||||
}
|
||||
ConstellationMsg::HeadParsed => {
|
||||
debug!("constellation got head parsed message");
|
||||
self.compositor_proxy.send(CompositorMsg::HeadParsed);
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
|
|
|
@ -109,6 +109,8 @@ impl CompositorEventListener for NullCompositor {
|
|||
Msg::CreatePng(..) |
|
||||
Msg::PaintTaskExited(..) |
|
||||
Msg::IsReadyToSaveImageReply(..) => {}
|
||||
Msg::NewFavicon(..) => {}
|
||||
Msg::HeadParsed => {}
|
||||
}
|
||||
true
|
||||
}
|
||||
|
|
|
@ -110,6 +110,8 @@ pub trait WindowMethods {
|
|||
fn load_end(&self, back: bool, forward: bool);
|
||||
/// Called when the browser encounters an error while loading a URL
|
||||
fn load_error(&self, code: NetError, url: String);
|
||||
/// Called when the <head> tag has finished parsing
|
||||
fn head_parsed(&self);
|
||||
|
||||
/// Returns the hidpi factor of the monitor.
|
||||
fn hidpi_factor(&self) -> ScaleFactor<ScreenPx, DevicePixel, f32>;
|
||||
|
@ -138,4 +140,7 @@ pub trait WindowMethods {
|
|||
|
||||
/// Does this window support a clipboard
|
||||
fn supports_clipboard(&self) -> bool;
|
||||
|
||||
/// Add a favicon
|
||||
fn set_favicon(&self, url: Url);
|
||||
}
|
||||
|
|
|
@ -248,6 +248,10 @@ pub enum Msg {
|
|||
IsReadyToSaveImage(HashMap<PipelineId, Epoch>),
|
||||
/// Notification that this iframe should be removed.
|
||||
RemoveIFrame(PipelineId, SubpageId),
|
||||
/// Favicon detected
|
||||
NewFavicon(Url),
|
||||
/// <head> tag finished parsing
|
||||
HeadParsed,
|
||||
}
|
||||
|
||||
#[derive(Clone, Eq, PartialEq)]
|
||||
|
|
|
@ -17,6 +17,8 @@ use dom::htmlelement::{HTMLElement, HTMLElementTypeId};
|
|||
use dom::node::{Node, NodeTypeId, window_from_node};
|
||||
use dom::virtualmethods::VirtualMethods;
|
||||
use dom::window::WindowHelpers;
|
||||
use msg::constellation_msg::ConstellationChan;
|
||||
use msg::constellation_msg::Msg as ConstellationMsg;
|
||||
|
||||
use cssparser::RGBA;
|
||||
use util::str::{self, DOMString};
|
||||
|
@ -107,6 +109,9 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLBodyElement> {
|
|||
let window = window_from_node(*self).root();
|
||||
let document = window.r().Document().root();
|
||||
document.r().set_reflow_timeout(time::precise_time_ns() + INITIAL_REFLOW_DELAY);
|
||||
let ConstellationChan(ref chan) = window.r().constellation_chan();
|
||||
let event = ConstellationMsg::HeadParsed;
|
||||
chan.send(event).unwrap();
|
||||
}
|
||||
|
||||
fn after_set_attr(&self, attr: JSRef<Attr>) {
|
||||
|
|
|
@ -25,6 +25,8 @@ use dom::node::{Node, NodeHelpers, NodeTypeId, window_from_node};
|
|||
use dom::virtualmethods::VirtualMethods;
|
||||
use dom::window::WindowHelpers;
|
||||
use layout_interface::{LayoutChan, Msg};
|
||||
use msg::constellation_msg::ConstellationChan;
|
||||
use msg::constellation_msg::Msg as ConstellationMsg;
|
||||
use script_traits::StylesheetLoadResponder;
|
||||
use util::str::{DOMString, HTML_SPACE_CHARACTERS};
|
||||
use style::media_queries::parse_media_query_list;
|
||||
|
@ -85,6 +87,19 @@ fn is_stylesheet(value: &Option<String>) -> bool {
|
|||
}
|
||||
}
|
||||
|
||||
/// Favicon spec usage in accordance with CEF implementation:
|
||||
/// only url of icon is required/used
|
||||
/// https://html.spec.whatwg.org/multipage/#rel-icon
|
||||
fn is_favicon(value: &Option<String>) -> bool {
|
||||
match *value {
|
||||
Some(ref value) => {
|
||||
value.split(HTML_SPACE_CHARACTERS)
|
||||
.any(|s| s.eq_ignore_ascii_case("icon"))
|
||||
},
|
||||
None => false,
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> VirtualMethods for JSRef<'a, HTMLLinkElement> {
|
||||
fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> {
|
||||
let htmlelement: &JSRef<HTMLElement> = HTMLElementCast::from_borrowed_ref(self);
|
||||
|
@ -105,7 +120,14 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLLinkElement> {
|
|||
let rel = get_attr(element, &atom!("rel"));
|
||||
|
||||
match (rel, attr.local_name()) {
|
||||
(ref rel, &atom!("href")) | (ref rel, &atom!("media")) => {
|
||||
(ref rel, &atom!("href")) => {
|
||||
if is_stylesheet(rel) {
|
||||
self.handle_stylesheet_url(&attr.value());
|
||||
} else if is_favicon(rel) {
|
||||
self.handle_favicon_url(&attr.value());
|
||||
}
|
||||
}
|
||||
(ref rel, &atom!("media")) => {
|
||||
if is_stylesheet(rel) {
|
||||
self.handle_stylesheet_url(&attr.value());
|
||||
}
|
||||
|
@ -136,6 +158,9 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLLinkElement> {
|
|||
(ref rel, Some(ref href)) if is_stylesheet(rel) => {
|
||||
self.handle_stylesheet_url(href);
|
||||
}
|
||||
(ref rel, Some(ref href)) if is_favicon(rel) => {
|
||||
self.handle_favicon_url(href);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
@ -144,6 +169,7 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLLinkElement> {
|
|||
|
||||
trait PrivateHTMLLinkElementHelpers {
|
||||
fn handle_stylesheet_url(self, href: &str);
|
||||
fn handle_favicon_url(self, href: &str);
|
||||
}
|
||||
|
||||
impl<'a> PrivateHTMLLinkElementHelpers for JSRef<'a, HTMLLinkElement> {
|
||||
|
@ -174,6 +200,19 @@ impl<'a> PrivateHTMLLinkElementHelpers for JSRef<'a, HTMLLinkElement> {
|
|||
Err(e) => debug!("Parsing url {} failed: {}", href, e)
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_favicon_url(self, href: &str) {
|
||||
let window = window_from_node(self).root();
|
||||
let window = window.r();
|
||||
match UrlParser::new().base_url(&window.get_url()).parse(href) {
|
||||
Ok(url) => {
|
||||
let ConstellationChan(ref chan) = window.constellation_chan();
|
||||
let event = ConstellationMsg::NewFavicon(url.clone());
|
||||
chan.send(event).unwrap();
|
||||
}
|
||||
Err(e) => debug!("Parsing url {} failed: {}", href, e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> HTMLLinkElementMethods for JSRef<'a, HTMLLinkElement> {
|
||||
|
|
|
@ -111,6 +111,8 @@ pub struct ServoCefBrowser {
|
|||
pub forward: Cell<bool>,
|
||||
/// whether the browser is loading
|
||||
pub loading: Cell<bool>,
|
||||
/// a vec of favicon urls for the current page
|
||||
pub favicons: RefCell<Vec<String>>,
|
||||
/// the display system window handle: only to be used with host.get_window_handle()
|
||||
window_handle: cef_window_handle_t,
|
||||
|
||||
|
@ -154,6 +156,7 @@ impl ServoCefBrowser {
|
|||
back: Cell::new(false),
|
||||
forward: Cell::new(false),
|
||||
loading: Cell::new(false),
|
||||
favicons: RefCell::new(vec!()),
|
||||
window_handle: window_handle,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -174,7 +174,7 @@ pub struct _cef_browser_t {
|
|||
// Returns the names of all existing frames.
|
||||
//
|
||||
pub get_frame_names: Option<extern "C" fn(this: *mut cef_browser_t,
|
||||
names: types::cef_string_list_t) -> ()>,
|
||||
names: &types::cef_string_list_t) -> ()>,
|
||||
|
||||
//
|
||||
// Send a message to the specified |target_process|. Returns true (1) if the
|
||||
|
@ -567,7 +567,7 @@ impl CefBrowser {
|
|||
//
|
||||
// Returns the names of all existing frames.
|
||||
//
|
||||
pub fn get_frame_names(&self, names: Vec<String>) -> () {
|
||||
pub fn get_frame_names(&self, names: &Vec<String>) -> () {
|
||||
if self.c_object.is_null() ||
|
||||
self.c_object as usize == mem::POST_DROP_USIZE {
|
||||
panic!("called a CEF method on a null object")
|
||||
|
@ -647,7 +647,7 @@ pub struct _cef_run_file_dialog_callback_t {
|
|||
pub on_file_dialog_dismissed: Option<extern "C" fn(
|
||||
this: *mut cef_run_file_dialog_callback_t,
|
||||
selected_accept_filter: libc::c_int,
|
||||
file_paths: types::cef_string_list_t) -> ()>,
|
||||
file_paths: &types::cef_string_list_t) -> ()>,
|
||||
|
||||
//
|
||||
// The reference count. This will only be present for Rust instances!
|
||||
|
@ -742,7 +742,7 @@ impl CefRunFileDialogCallback {
|
|||
// dialog mode. If the selection was cancelled |file_paths| will be NULL.
|
||||
//
|
||||
pub fn on_file_dialog_dismissed(&self, selected_accept_filter: libc::c_int,
|
||||
file_paths: Vec<String>) -> () {
|
||||
file_paths: &Vec<String>) -> () {
|
||||
if self.c_object.is_null() ||
|
||||
self.c_object as usize == mem::POST_DROP_USIZE {
|
||||
panic!("called a CEF method on a null object")
|
||||
|
@ -1047,7 +1047,7 @@ pub struct _cef_browser_host_t {
|
|||
pub run_file_dialog: Option<extern "C" fn(this: *mut cef_browser_host_t,
|
||||
mode: types::cef_file_dialog_mode_t, title: *const types::cef_string_t,
|
||||
default_file_path: *const types::cef_string_t,
|
||||
accept_filters: types::cef_string_list_t,
|
||||
accept_filters: &types::cef_string_list_t,
|
||||
selected_accept_filter: libc::c_int,
|
||||
callback: *mut interfaces::cef_run_file_dialog_callback_t) -> ()>,
|
||||
|
||||
|
@ -1606,7 +1606,7 @@ impl CefBrowserHost {
|
|||
// will be initiated asynchronously on the UI thread.
|
||||
//
|
||||
pub fn run_file_dialog(&self, mode: types::cef_file_dialog_mode_t,
|
||||
title: &[u16], default_file_path: &[u16], accept_filters: Vec<String>,
|
||||
title: &[u16], default_file_path: &[u16], accept_filters: &Vec<String>,
|
||||
selected_accept_filter: libc::c_int,
|
||||
callback: interfaces::CefRunFileDialogCallback) -> () {
|
||||
if self.c_object.is_null() ||
|
||||
|
|
|
@ -95,7 +95,8 @@ pub struct _cef_browser_process_handler_t {
|
|||
this: *mut cef_browser_process_handler_t) -> *mut interfaces::cef_print_handler_t>,
|
||||
|
||||
//
|
||||
// Called when the application should call cef_do_message_loop_work()
|
||||
// Called when the application should call cef_do_message_loop_work(). May be
|
||||
// called from a thread.
|
||||
//
|
||||
pub on_work_available: Option<extern "C" fn(
|
||||
this: *mut cef_browser_process_handler_t) -> ()>,
|
||||
|
@ -261,7 +262,8 @@ impl CefBrowserProcessHandler {
|
|||
}
|
||||
|
||||
//
|
||||
// Called when the application should call cef_do_message_loop_work()
|
||||
// Called when the application should call cef_do_message_loop_work(). May be
|
||||
// called from a thread.
|
||||
//
|
||||
pub fn on_work_available(&self) -> () {
|
||||
if self.c_object.is_null() ||
|
||||
|
|
|
@ -109,7 +109,7 @@ pub struct _cef_command_line_t {
|
|||
// array: { program, [(--|-|/)switch[=value]]*, [--], [argument]* }
|
||||
//
|
||||
pub get_argv: Option<extern "C" fn(this: *mut cef_command_line_t,
|
||||
argv: types::cef_string_list_t) -> ()>,
|
||||
argv: &types::cef_string_list_t) -> ()>,
|
||||
|
||||
//
|
||||
// Constructs and returns the represented command line string. Use this
|
||||
|
@ -183,7 +183,7 @@ pub struct _cef_command_line_t {
|
|||
// Get the remaining command line arguments.
|
||||
//
|
||||
pub get_arguments: Option<extern "C" fn(this: *mut cef_command_line_t,
|
||||
arguments: types::cef_string_list_t) -> ()>,
|
||||
arguments: &types::cef_string_list_t) -> ()>,
|
||||
|
||||
//
|
||||
// Add an argument to the end of the command line.
|
||||
|
@ -392,7 +392,7 @@ impl CefCommandLine {
|
|||
// Retrieve the original command line string as a vector of strings. The argv
|
||||
// array: { program, [(--|-|/)switch[=value]]*, [--], [argument]* }
|
||||
//
|
||||
pub fn get_argv(&self, argv: Vec<String>) -> () {
|
||||
pub fn get_argv(&self, argv: &Vec<String>) -> () {
|
||||
if self.c_object.is_null() ||
|
||||
self.c_object as usize == mem::POST_DROP_USIZE {
|
||||
panic!("called a CEF method on a null object")
|
||||
|
@ -572,7 +572,7 @@ impl CefCommandLine {
|
|||
//
|
||||
// Get the remaining command line arguments.
|
||||
//
|
||||
pub fn get_arguments(&self, arguments: Vec<String>) -> () {
|
||||
pub fn get_arguments(&self, arguments: &Vec<String>) -> () {
|
||||
if self.c_object.is_null() ||
|
||||
self.c_object as usize == mem::POST_DROP_USIZE {
|
||||
panic!("called a CEF method on a null object")
|
||||
|
|
|
@ -403,7 +403,7 @@ pub struct _cef_context_menu_params_t {
|
|||
//
|
||||
pub get_dictionary_suggestions: Option<extern "C" fn(
|
||||
this: *mut cef_context_menu_params_t,
|
||||
suggestions: types::cef_string_list_t) -> libc::c_int>,
|
||||
suggestions: &types::cef_string_list_t) -> libc::c_int>,
|
||||
|
||||
//
|
||||
// Returns true (1) if the context menu was invoked on an editable node.
|
||||
|
@ -746,7 +746,7 @@ impl CefContextMenuParams {
|
|||
// is one.
|
||||
//
|
||||
pub fn get_dictionary_suggestions(&self,
|
||||
suggestions: Vec<String>) -> libc::c_int {
|
||||
suggestions: &Vec<String>) -> libc::c_int {
|
||||
if self.c_object.is_null() ||
|
||||
self.c_object as usize == mem::POST_DROP_USIZE {
|
||||
panic!("called a CEF method on a null object")
|
||||
|
|
|
@ -64,7 +64,7 @@ pub struct _cef_cookie_manager_t {
|
|||
// Must be called before any cookies are accessed.
|
||||
//
|
||||
pub set_supported_schemes: Option<extern "C" fn(
|
||||
this: *mut cef_cookie_manager_t, schemes: types::cef_string_list_t,
|
||||
this: *mut cef_cookie_manager_t, schemes: &types::cef_string_list_t,
|
||||
callback: *mut interfaces::cef_completion_callback_t) -> ()>,
|
||||
|
||||
//
|
||||
|
@ -227,7 +227,7 @@ impl CefCookieManager {
|
|||
// executed asnychronously on the IO thread after the change has been applied.
|
||||
// Must be called before any cookies are accessed.
|
||||
//
|
||||
pub fn set_supported_schemes(&self, schemes: Vec<String>,
|
||||
pub fn set_supported_schemes(&self, schemes: &Vec<String>,
|
||||
callback: interfaces::CefCompletionCallback) -> () {
|
||||
if self.c_object.is_null() ||
|
||||
self.c_object as usize == mem::POST_DROP_USIZE {
|
||||
|
|
|
@ -65,7 +65,7 @@ pub struct _cef_file_dialog_callback_t {
|
|||
//
|
||||
pub cont: Option<extern "C" fn(this: *mut cef_file_dialog_callback_t,
|
||||
selected_accept_filter: libc::c_int,
|
||||
file_paths: types::cef_string_list_t) -> ()>,
|
||||
file_paths: &types::cef_string_list_t) -> ()>,
|
||||
|
||||
//
|
||||
// Cancel the file selection.
|
||||
|
@ -165,7 +165,7 @@ impl CefFileDialogCallback {
|
|||
// value is treated the same as calling cancel().
|
||||
//
|
||||
pub fn cont(&self, selected_accept_filter: libc::c_int,
|
||||
file_paths: Vec<String>) -> () {
|
||||
file_paths: &Vec<String>) -> () {
|
||||
if self.c_object.is_null() ||
|
||||
self.c_object as usize == mem::POST_DROP_USIZE {
|
||||
panic!("called a CEF method on a null object")
|
||||
|
@ -251,7 +251,7 @@ pub struct _cef_dialog_handler_t {
|
|||
browser: *mut interfaces::cef_browser_t,
|
||||
mode: types::cef_file_dialog_mode_t, title: *const types::cef_string_t,
|
||||
default_file_path: *const types::cef_string_t,
|
||||
accept_filters: types::cef_string_list_t,
|
||||
accept_filters: &types::cef_string_list_t,
|
||||
selected_accept_filter: libc::c_int,
|
||||
callback: *mut interfaces::cef_file_dialog_callback_t) -> libc::c_int>,
|
||||
|
||||
|
@ -357,7 +357,7 @@ impl CefDialogHandler {
|
|||
//
|
||||
pub fn on_file_dialog(&self, browser: interfaces::CefBrowser,
|
||||
mode: types::cef_file_dialog_mode_t, title: &[u16],
|
||||
default_file_path: &[u16], accept_filters: Vec<String>,
|
||||
default_file_path: &[u16], accept_filters: &Vec<String>,
|
||||
selected_accept_filter: libc::c_int,
|
||||
callback: interfaces::CefFileDialogCallback) -> libc::c_int {
|
||||
if self.c_object.is_null() ||
|
||||
|
|
|
@ -77,7 +77,7 @@ pub struct _cef_display_handler_t {
|
|||
//
|
||||
pub on_favicon_urlchange: Option<extern "C" fn(
|
||||
this: *mut cef_display_handler_t, browser: *mut interfaces::cef_browser_t,
|
||||
icon_urls: types::cef_string_list_t) -> ()>,
|
||||
icon_urls: &types::cef_string_list_t) -> ()>,
|
||||
|
||||
//
|
||||
// Called when the browser is about to display a tooltip. |text| contains the
|
||||
|
@ -234,7 +234,7 @@ impl CefDisplayHandler {
|
|||
// Called when the page icon changes.
|
||||
//
|
||||
pub fn on_favicon_urlchange(&self, browser: interfaces::CefBrowser,
|
||||
icon_urls: Vec<String>) -> () {
|
||||
icon_urls: &Vec<String>) -> () {
|
||||
if self.c_object.is_null() ||
|
||||
self.c_object as usize == mem::POST_DROP_USIZE {
|
||||
panic!("called a CEF method on a null object")
|
||||
|
|
|
@ -149,7 +149,7 @@ pub struct _cef_drag_data_t {
|
|||
// window.
|
||||
//
|
||||
pub get_file_names: Option<extern "C" fn(this: *mut cef_drag_data_t,
|
||||
names: types::cef_string_list_t) -> libc::c_int>,
|
||||
names: &types::cef_string_list_t) -> libc::c_int>,
|
||||
|
||||
//
|
||||
// Set the link URL that is being dragged.
|
||||
|
@ -499,7 +499,7 @@ impl CefDragData {
|
|||
// Retrieve the list of file names that are being dragged into the browser
|
||||
// window.
|
||||
//
|
||||
pub fn get_file_names(&self, names: Vec<String>) -> libc::c_int {
|
||||
pub fn get_file_names(&self, names: &Vec<String>) -> libc::c_int {
|
||||
if self.c_object.is_null() ||
|
||||
self.c_object as usize == mem::POST_DROP_USIZE {
|
||||
panic!("called a CEF method on a null object")
|
||||
|
|
|
@ -97,20 +97,20 @@ pub struct _cef_sslcert_principal_t {
|
|||
//
|
||||
pub get_street_addresses: Option<extern "C" fn(
|
||||
this: *mut cef_sslcert_principal_t,
|
||||
addresses: types::cef_string_list_t) -> ()>,
|
||||
addresses: &types::cef_string_list_t) -> ()>,
|
||||
|
||||
//
|
||||
// Retrieve the list of organization names.
|
||||
//
|
||||
pub get_organization_names: Option<extern "C" fn(
|
||||
this: *mut cef_sslcert_principal_t, names: types::cef_string_list_t) -> (
|
||||
this: *mut cef_sslcert_principal_t, names: &types::cef_string_list_t) -> (
|
||||
)>,
|
||||
|
||||
//
|
||||
// Retrieve the list of organization unit names.
|
||||
//
|
||||
pub get_organization_unit_names: Option<extern "C" fn(
|
||||
this: *mut cef_sslcert_principal_t, names: types::cef_string_list_t) -> (
|
||||
this: *mut cef_sslcert_principal_t, names: &types::cef_string_list_t) -> (
|
||||
)>,
|
||||
|
||||
//
|
||||
|
@ -118,7 +118,7 @@ pub struct _cef_sslcert_principal_t {
|
|||
//
|
||||
pub get_domain_components: Option<extern "C" fn(
|
||||
this: *mut cef_sslcert_principal_t,
|
||||
components: types::cef_string_list_t) -> ()>,
|
||||
components: &types::cef_string_list_t) -> ()>,
|
||||
|
||||
//
|
||||
// The reference count. This will only be present for Rust instances!
|
||||
|
@ -288,7 +288,7 @@ impl CefSSLCertPrincipal {
|
|||
//
|
||||
// Retrieve the list of street addresses.
|
||||
//
|
||||
pub fn get_street_addresses(&self, addresses: Vec<String>) -> () {
|
||||
pub fn get_street_addresses(&self, addresses: &Vec<String>) -> () {
|
||||
if self.c_object.is_null() ||
|
||||
self.c_object as usize == mem::POST_DROP_USIZE {
|
||||
panic!("called a CEF method on a null object")
|
||||
|
@ -304,7 +304,7 @@ impl CefSSLCertPrincipal {
|
|||
//
|
||||
// Retrieve the list of organization names.
|
||||
//
|
||||
pub fn get_organization_names(&self, names: Vec<String>) -> () {
|
||||
pub fn get_organization_names(&self, names: &Vec<String>) -> () {
|
||||
if self.c_object.is_null() ||
|
||||
self.c_object as usize == mem::POST_DROP_USIZE {
|
||||
panic!("called a CEF method on a null object")
|
||||
|
@ -320,7 +320,7 @@ impl CefSSLCertPrincipal {
|
|||
//
|
||||
// Retrieve the list of organization unit names.
|
||||
//
|
||||
pub fn get_organization_unit_names(&self, names: Vec<String>) -> () {
|
||||
pub fn get_organization_unit_names(&self, names: &Vec<String>) -> () {
|
||||
if self.c_object.is_null() ||
|
||||
self.c_object as usize == mem::POST_DROP_USIZE {
|
||||
panic!("called a CEF method on a null object")
|
||||
|
@ -336,7 +336,7 @@ impl CefSSLCertPrincipal {
|
|||
//
|
||||
// Retrieve the list of domain components.
|
||||
//
|
||||
pub fn get_domain_components(&self, components: Vec<String>) -> () {
|
||||
pub fn get_domain_components(&self, components: &Vec<String>) -> () {
|
||||
if self.c_object.is_null() ||
|
||||
self.c_object as usize == mem::POST_DROP_USIZE {
|
||||
panic!("called a CEF method on a null object")
|
||||
|
|
|
@ -1364,7 +1364,7 @@ pub struct _cef_v8value_t {
|
|||
// based keys will also be returned as strings.
|
||||
//
|
||||
pub get_keys: Option<extern "C" fn(this: *mut cef_v8value_t,
|
||||
keys: types::cef_string_list_t) -> libc::c_int>,
|
||||
keys: &types::cef_string_list_t) -> libc::c_int>,
|
||||
|
||||
//
|
||||
// Sets the user data for this object and returns true (1) on success. Returns
|
||||
|
@ -2117,7 +2117,7 @@ impl CefV8Value {
|
|||
// Read the keys for the object's values into the specified vector. Integer-
|
||||
// based keys will also be returned as strings.
|
||||
//
|
||||
pub fn get_keys(&self, keys: Vec<String>) -> libc::c_int {
|
||||
pub fn get_keys(&self, keys: &Vec<String>) -> libc::c_int {
|
||||
if self.c_object.is_null() ||
|
||||
self.c_object as usize == mem::POST_DROP_USIZE {
|
||||
panic!("called a CEF method on a null object")
|
||||
|
|
|
@ -1099,7 +1099,7 @@ pub struct _cef_dictionary_value_t {
|
|||
// Reads all keys for this dictionary into the specified vector.
|
||||
//
|
||||
pub get_keys: Option<extern "C" fn(this: *mut cef_dictionary_value_t,
|
||||
keys: types::cef_string_list_t) -> libc::c_int>,
|
||||
keys: &types::cef_string_list_t) -> libc::c_int>,
|
||||
|
||||
//
|
||||
// Removes the value at the specified key. Returns true (1) is the value was
|
||||
|
@ -1489,7 +1489,7 @@ impl CefDictionaryValue {
|
|||
//
|
||||
// Reads all keys for this dictionary into the specified vector.
|
||||
//
|
||||
pub fn get_keys(&self, keys: Vec<String>) -> libc::c_int {
|
||||
pub fn get_keys(&self, keys: &Vec<String>) -> libc::c_int {
|
||||
if self.c_object.is_null() ||
|
||||
self.c_object as usize == mem::POST_DROP_USIZE {
|
||||
panic!("called a CEF method on a null object")
|
||||
|
|
|
@ -4,12 +4,14 @@
|
|||
|
||||
use libc::{c_int};
|
||||
use std::mem;
|
||||
use string::{cef_string_userfree_utf16_alloc,cef_string_userfree_utf16_free,cef_string_utf16_set};
|
||||
use std::slice;
|
||||
use string::cef_string_utf16_set;
|
||||
use types::{cef_string_list_t,cef_string_t};
|
||||
|
||||
use rustc_unicode::str::Utf16Encoder;
|
||||
|
||||
fn string_list_to_vec(lt: *mut cef_string_list_t) -> *mut Vec<*mut cef_string_t> {
|
||||
lt as *mut Vec<*mut cef_string_t>
|
||||
fn string_list_to_vec(lt: *mut cef_string_list_t) -> *mut Vec<String> {
|
||||
lt as *mut Vec<String>
|
||||
}
|
||||
|
||||
//cef_string_list
|
||||
|
@ -17,7 +19,7 @@ fn string_list_to_vec(lt: *mut cef_string_list_t) -> *mut Vec<*mut cef_string_t>
|
|||
#[no_mangle]
|
||||
pub extern "C" fn cef_string_list_alloc() -> *mut cef_string_list_t {
|
||||
unsafe {
|
||||
let lt: Box<Vec<*mut cef_string_t>> = box vec!();
|
||||
let lt: Box<Vec<String>> = box vec!();
|
||||
mem::transmute(lt)
|
||||
}
|
||||
}
|
||||
|
@ -36,9 +38,7 @@ pub extern "C" fn cef_string_list_append(lt: *mut cef_string_list_t, value: *con
|
|||
unsafe {
|
||||
if lt.is_null() { return; }
|
||||
let v = string_list_to_vec(lt);
|
||||
let cs = cef_string_userfree_utf16_alloc();
|
||||
cef_string_utf16_set(mem::transmute((*value).str), (*value).length, cs, 1);
|
||||
(*v).push(cs);
|
||||
(*v).push(String::from_utf16(slice::from_raw_parts((*value).str, (*value).length as usize)).unwrap());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -48,8 +48,9 @@ pub extern "C" fn cef_string_list_value(lt: *mut cef_string_list_t, index: c_int
|
|||
if index < 0 || lt.is_null() { return 0; }
|
||||
let v = string_list_to_vec(lt);
|
||||
if index as usize > (*v).len() - 1 { return 0; }
|
||||
let cs = (*v)[index as usize];
|
||||
cef_string_utf16_set(mem::transmute((*cs).str), (*cs).length, value, 1)
|
||||
let ref string = (*v)[index as usize];
|
||||
let utf16_chars: Vec<u16> = Utf16Encoder::new(string.chars()).collect();
|
||||
cef_string_utf16_set(mem::transmute(utf16_chars.as_ptr()), utf16_chars.len() as u64, value, 1)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -58,12 +59,7 @@ pub extern "C" fn cef_string_list_clear(lt: *mut cef_string_list_t) {
|
|||
unsafe {
|
||||
if lt.is_null() { return; }
|
||||
let v = string_list_to_vec(lt);
|
||||
if (*v).len() == 0 { return; }
|
||||
let mut cs;
|
||||
while (*v).len() != 0 {
|
||||
cs = (*v).pop();
|
||||
cef_string_userfree_utf16_free(cs.unwrap());
|
||||
}
|
||||
(*v).clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -71,7 +67,7 @@ pub extern "C" fn cef_string_list_clear(lt: *mut cef_string_list_t) {
|
|||
pub extern "C" fn cef_string_list_free(lt: *mut cef_string_list_t) {
|
||||
unsafe {
|
||||
if lt.is_null() { return; }
|
||||
let v: Box<Vec<*mut cef_string_t>> = mem::transmute(lt);
|
||||
let v: Box<Vec<String>> = mem::transmute(lt);
|
||||
cef_string_list_clear(lt);
|
||||
drop(v);
|
||||
}
|
||||
|
@ -82,10 +78,7 @@ pub extern "C" fn cef_string_list_copy(lt: *mut cef_string_list_t) -> *mut cef_s
|
|||
unsafe {
|
||||
if lt.is_null() { return 0 as *mut cef_string_list_t; }
|
||||
let v = string_list_to_vec(lt);
|
||||
let lt2 = cef_string_list_alloc();
|
||||
for cs in (*v).iter() {
|
||||
cef_string_list_append(lt2, mem::transmute((*cs)));
|
||||
}
|
||||
lt2
|
||||
let copy = (*v).clone();
|
||||
mem::transmute(box copy)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ pub use self::cef_rect as cef_rect_t;
|
|||
|
||||
pub enum cef_string_map_t {}
|
||||
pub enum cef_string_multimap_t {}
|
||||
pub enum cef_string_list_t {}
|
||||
pub type cef_string_list_t = Vec<String>;
|
||||
pub enum cef_text_input_context_t {}
|
||||
pub enum cef_event_handle_t {}
|
||||
|
||||
|
|
|
@ -316,8 +316,16 @@ impl WindowMethods for Window {
|
|||
}
|
||||
}
|
||||
|
||||
fn set_favicon(&self, url: Url) {
|
||||
let browser = self.cef_browser.borrow();
|
||||
let browser = match *browser {
|
||||
None => return,
|
||||
Some(ref browser) => browser,
|
||||
};
|
||||
browser.downcast().favicons.borrow_mut().push(url.to_string().clone());
|
||||
}
|
||||
|
||||
fn load_start(&self, back: bool, forward: bool) {
|
||||
// FIXME(pcwalton): The status code 200 is a lie.
|
||||
let browser = self.cef_browser.borrow();
|
||||
let browser = match *browser {
|
||||
None => return,
|
||||
|
@ -326,6 +334,7 @@ impl WindowMethods for Window {
|
|||
browser.downcast().loading.set(true);
|
||||
browser.downcast().back.set(back);
|
||||
browser.downcast().forward.set(forward);
|
||||
browser.downcast().favicons.borrow_mut().clear();
|
||||
if check_ptr_exist!(browser.get_host().get_client(), get_load_handler) &&
|
||||
check_ptr_exist!(browser.get_host().get_client().get_load_handler(), on_loading_state_change) {
|
||||
browser.get_host()
|
||||
|
@ -378,6 +387,18 @@ impl WindowMethods for Window {
|
|||
}
|
||||
}
|
||||
|
||||
fn head_parsed(&self) {
|
||||
let browser = self.cef_browser.borrow();
|
||||
let browser = match *browser {
|
||||
None => return,
|
||||
Some(ref browser) => browser,
|
||||
};
|
||||
if check_ptr_exist!(browser.get_host().get_client(), get_display_handler) &&
|
||||
check_ptr_exist!(browser.get_host().get_client().get_display_handler(), on_favicon_urlchange) {
|
||||
browser.get_host().get_client().get_display_handler().on_favicon_urlchange((*browser).clone(), &browser.downcast().favicons.borrow());
|
||||
}
|
||||
}
|
||||
|
||||
fn set_page_title(&self, string: Option<String>) {
|
||||
let browser = self.cef_browser.borrow();
|
||||
let browser = match *browser {
|
||||
|
|
|
@ -135,7 +135,6 @@ cef_noop_wrapper!(*mut cef_jsdialog_handler_t);
|
|||
cef_noop_wrapper!(*mut cef_keyboard_handler_t);
|
||||
cef_noop_wrapper!(*mut cef_load_handler_t);
|
||||
cef_noop_wrapper!(*mut cef_request_handler_t);
|
||||
cef_noop_wrapper!(*mut cef_string_list_t);
|
||||
cef_noop_wrapper!(*mut cef_string_utf16);
|
||||
cef_noop_wrapper!(c_int);
|
||||
cef_noop_wrapper!(CefApp);
|
||||
|
@ -185,10 +184,10 @@ cef_noop_wrapper!(f64);
|
|||
cef_noop_wrapper!(i64);
|
||||
cef_noop_wrapper!(u32);
|
||||
cef_noop_wrapper!(u64);
|
||||
cef_noop_wrapper!(cef_string_list_t);
|
||||
|
||||
cef_unimplemented_wrapper!(*const *mut cef_v8value_t, *const CefV8Value);
|
||||
cef_unimplemented_wrapper!(*mut *mut cef_post_data_element_t, *mut CefPostDataElement);
|
||||
cef_unimplemented_wrapper!(cef_string_list_t, Vec<String>);
|
||||
cef_unimplemented_wrapper!(cef_string_map_t, HashMap<String,String>);
|
||||
cef_unimplemented_wrapper!(cef_string_multimap_t, HashMap<String,Vec<String>>);
|
||||
cef_unimplemented_wrapper!(cef_string_t, String);
|
||||
|
@ -293,3 +292,11 @@ impl<'a> CefWrap<cef_string_t> for &'a mut String {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> CefWrap<&'a cef_string_list_t> for &'a cef_string_list_t {
|
||||
fn to_c(stringlist: &'a cef_string_list_t) -> &'a cef_string_list_t {
|
||||
stringlist
|
||||
}
|
||||
unsafe fn to_rust(_: &'a cef_string_list_t) -> &'a cef_string_list_t {
|
||||
panic!("unimplemented CEF type conversion: cef_string_t");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -515,6 +515,9 @@ impl WindowMethods for Window {
|
|||
fn load_error(&self, _: NetError, _: String) {
|
||||
}
|
||||
|
||||
fn head_parsed(&self) {
|
||||
}
|
||||
|
||||
/// Has no effect on Android.
|
||||
fn set_cursor(&self, c: Cursor) {
|
||||
use glutin::MouseCursor;
|
||||
|
@ -559,6 +562,9 @@ impl WindowMethods for Window {
|
|||
self.window.set_cursor(glutin_cursor);
|
||||
}
|
||||
|
||||
fn set_favicon(&self, _: Url) {
|
||||
}
|
||||
|
||||
fn prepare_for_composite(&self, _width: usize, _height: usize) -> bool {
|
||||
true
|
||||
}
|
||||
|
@ -703,10 +709,15 @@ impl WindowMethods for Window {
|
|||
}
|
||||
fn load_error(&self, _: NetError, _: String) {
|
||||
}
|
||||
fn head_parsed(&self) {
|
||||
}
|
||||
|
||||
fn set_cursor(&self, _: Cursor) {
|
||||
}
|
||||
|
||||
fn set_favicon(&self, _: Url) {
|
||||
}
|
||||
|
||||
fn prepare_for_composite(&self, _width: usize, _height: usize) -> bool {
|
||||
true
|
||||
}
|
||||
|
|
|
@ -812,6 +812,9 @@ impl WindowMethods for Window {
|
|||
fn load_error(&self, _: NetError, _: String) {
|
||||
}
|
||||
|
||||
fn head_parsed(&self) {
|
||||
}
|
||||
|
||||
fn hidpi_factor(&self) -> ScaleFactor<ScreenPx, DevicePixel, f32> {
|
||||
ScaleFactor::new(1.0)
|
||||
}
|
||||
|
@ -838,6 +841,9 @@ impl WindowMethods for Window {
|
|||
fn set_cursor(&self, _: Cursor) {
|
||||
}
|
||||
|
||||
fn set_favicon(&self, _: Url) {
|
||||
}
|
||||
|
||||
fn prepare_for_composite(&self, _width: usize, _height: usize) -> bool {
|
||||
true
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue