mirror of
https://github.com/servo/servo.git
synced 2025-08-06 14:10:11 +01:00
Add mozbrowser events for location + title change.
This commit is contained in:
parent
da2231a8fa
commit
7163a3c580
6 changed files with 83 additions and 23 deletions
|
@ -606,6 +606,10 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
|
||||||
script_chan.send(ConstellationControlMsg::UpdateSubpageId(parent_pipeline_id,
|
script_chan.send(ConstellationControlMsg::UpdateSubpageId(parent_pipeline_id,
|
||||||
subpage_id,
|
subpage_id,
|
||||||
new_subpage_id)).unwrap();
|
new_subpage_id)).unwrap();
|
||||||
|
|
||||||
|
// If this is an iframe, send a mozbrowser location change event.
|
||||||
|
// This is the result of a back/forward navigation.
|
||||||
|
self.trigger_mozbrowserlocationchange(next_pipeline_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -637,7 +641,7 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_mozbrowser_event_msg(&mut self,
|
fn handle_mozbrowser_event_msg(&mut self,
|
||||||
pipeline_id: PipelineId,
|
containing_pipeline_id: PipelineId,
|
||||||
subpage_id: SubpageId,
|
subpage_id: SubpageId,
|
||||||
event_name: String,
|
event_name: String,
|
||||||
event_detail: Option<String>) {
|
event_detail: Option<String>) {
|
||||||
|
@ -645,13 +649,8 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
|
||||||
|
|
||||||
// Find the script channel for the given parent pipeline,
|
// Find the script channel for the given parent pipeline,
|
||||||
// and pass the event to that script task.
|
// and pass the event to that script task.
|
||||||
let pipeline = self.pipeline(pipeline_id);
|
let pipeline = self.pipeline(containing_pipeline_id);
|
||||||
let ScriptControlChan(ref script_channel) = pipeline.script_chan;
|
pipeline.trigger_mozbrowser_event(subpage_id, event_name, event_detail);
|
||||||
let event = ConstellationControlMsg::MozBrowserEvent(pipeline_id,
|
|
||||||
subpage_id,
|
|
||||||
event_name,
|
|
||||||
event_detail);
|
|
||||||
script_channel.send(event).unwrap();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_or_replace_pipeline_in_frame_tree(&mut self, frame_change: FrameChange) {
|
fn add_or_replace_pipeline_in_frame_tree(&mut self, frame_change: FrameChange) {
|
||||||
|
@ -692,6 +691,10 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
|
||||||
// Build frame tree and send permission
|
// Build frame tree and send permission
|
||||||
self.send_frame_tree_and_grant_paint_permission();
|
self.send_frame_tree_and_grant_paint_permission();
|
||||||
|
|
||||||
|
// If this is an iframe, send a mozbrowser location change event.
|
||||||
|
// This is the result of a link being clicked and a navigation completing.
|
||||||
|
self.trigger_mozbrowserlocationchange(frame_change.new_pipeline_id);
|
||||||
|
|
||||||
// Remove any evicted frames
|
// Remove any evicted frames
|
||||||
if let Some(evicted_frames) = evicted_frames {
|
if let Some(evicted_frames) = evicted_frames {
|
||||||
for pipeline_id in &evicted_frames {
|
for pipeline_id in &evicted_frames {
|
||||||
|
@ -862,6 +865,28 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://developer.mozilla.org/en-US/docs/Web/Events/mozbrowserlocationchange
|
||||||
|
fn trigger_mozbrowserlocationchange(&self, pipeline_id: PipelineId) {
|
||||||
|
if opts::experimental_enabled() {
|
||||||
|
// Work around borrow checker
|
||||||
|
let event_info = {
|
||||||
|
let pipeline = self.pipeline(pipeline_id);
|
||||||
|
|
||||||
|
pipeline.parent_info.map(|(containing_pipeline_id, subpage_id)| {
|
||||||
|
(containing_pipeline_id, subpage_id, pipeline.url.serialize())
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
// If this is an iframe, then send the event with new url
|
||||||
|
if let Some((containing_pipeline_id, subpage_id, url)) = event_info {
|
||||||
|
let parent_pipeline = self.pipeline(containing_pipeline_id);
|
||||||
|
parent_pipeline.trigger_mozbrowser_event(subpage_id,
|
||||||
|
"mozbrowserlocationchange".to_owned(),
|
||||||
|
Some(url));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn pipeline_is_in_current_frame(&self, pipeline_id: PipelineId) -> bool {
|
fn pipeline_is_in_current_frame(&self, pipeline_id: PipelineId) -> bool {
|
||||||
self.current_frame_tree_iter(self.root_frame_id)
|
self.current_frame_tree_iter(self.root_frame_id)
|
||||||
.any(|current_frame| current_frame.current == pipeline_id)
|
.any(|current_frame| current_frame.current == pipeline_id)
|
||||||
|
|
|
@ -24,6 +24,7 @@ use profile::time::TimeProfilerChan;
|
||||||
use std::sync::mpsc::{Receiver, channel};
|
use std::sync::mpsc::{Receiver, channel};
|
||||||
use url::Url;
|
use url::Url;
|
||||||
use util::geometry::{PagePx, ViewportPx};
|
use util::geometry::{PagePx, ViewportPx};
|
||||||
|
use util::opts;
|
||||||
|
|
||||||
/// A uniquely-identifiable pipeline of script task, layout task, and paint task.
|
/// A uniquely-identifiable pipeline of script task, layout task, and paint task.
|
||||||
pub struct Pipeline {
|
pub struct Pipeline {
|
||||||
|
@ -244,4 +245,18 @@ impl Pipeline {
|
||||||
pub fn add_child(&mut self, frame_id: FrameId) {
|
pub fn add_child(&mut self, frame_id: FrameId) {
|
||||||
self.children.push(frame_id);
|
self.children.push(frame_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn trigger_mozbrowser_event(&self,
|
||||||
|
subpage_id: SubpageId,
|
||||||
|
event_name: String,
|
||||||
|
event_detail: Option<String>) {
|
||||||
|
assert!(opts::experimental_enabled());
|
||||||
|
|
||||||
|
let ScriptControlChan(ref script_channel) = self.script_chan;
|
||||||
|
let event = ConstellationControlMsg::MozBrowserEvent(self.id,
|
||||||
|
subpage_id,
|
||||||
|
event_name,
|
||||||
|
event_detail);
|
||||||
|
script_channel.send(event).unwrap();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -213,6 +213,7 @@ pub trait DocumentHelpers<'a> {
|
||||||
fn begin_focus_transaction(self);
|
fn begin_focus_transaction(self);
|
||||||
fn request_focus(self, elem: JSRef<Element>);
|
fn request_focus(self, elem: JSRef<Element>);
|
||||||
fn commit_focus_transaction(self);
|
fn commit_focus_transaction(self);
|
||||||
|
fn title_changed(self);
|
||||||
fn send_title_to_compositor(self);
|
fn send_title_to_compositor(self);
|
||||||
fn dirty_all_nodes(self);
|
fn dirty_all_nodes(self);
|
||||||
fn handle_click_event(self, js_runtime: *mut JSRuntime, _button: uint, point: Point2D<f32>);
|
fn handle_click_event(self, js_runtime: *mut JSRuntime, _button: uint, point: Point2D<f32>);
|
||||||
|
@ -222,6 +223,7 @@ pub trait DocumentHelpers<'a> {
|
||||||
fn handle_mouse_move_event(self, js_runtime: *mut JSRuntime, point: Point2D<f32>,
|
fn handle_mouse_move_event(self, js_runtime: *mut JSRuntime, point: Point2D<f32>,
|
||||||
prev_mouse_over_targets: &mut Vec<JS<Node>>) -> bool;
|
prev_mouse_over_targets: &mut Vec<JS<Node>>) -> bool;
|
||||||
fn set_current_script(self, script: Option<JSRef<HTMLScriptElement>>);
|
fn set_current_script(self, script: Option<JSRef<HTMLScriptElement>>);
|
||||||
|
fn trigger_mozbrowser_event(self, event_name: String, event_detail: Option<String>);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> DocumentHelpers<'a> for JSRef<'a, Document> {
|
impl<'a> DocumentHelpers<'a> for JSRef<'a, Document> {
|
||||||
|
@ -453,6 +455,14 @@ impl<'a> DocumentHelpers<'a> for JSRef<'a, Document> {
|
||||||
self.focused.assign(self.possibly_focused.get());
|
self.focused.assign(self.possibly_focused.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Handles any updates when the document's title has changed.
|
||||||
|
fn title_changed(self) {
|
||||||
|
// https://developer.mozilla.org/en-US/docs/Web/Events/mozbrowsertitlechange
|
||||||
|
self.trigger_mozbrowser_event("mozbrowsertitlechange".to_owned(), Some(self.Title()));
|
||||||
|
|
||||||
|
self.send_title_to_compositor();
|
||||||
|
}
|
||||||
|
|
||||||
/// Sends this document's title to the compositor.
|
/// Sends this document's title to the compositor.
|
||||||
fn send_title_to_compositor(self) {
|
fn send_title_to_compositor(self) {
|
||||||
let window = self.window().root();
|
let window = self.window().root();
|
||||||
|
@ -672,6 +682,21 @@ impl<'a> DocumentHelpers<'a> for JSRef<'a, Document> {
|
||||||
fn set_current_script(self, script: Option<JSRef<HTMLScriptElement>>) {
|
fn set_current_script(self, script: Option<JSRef<HTMLScriptElement>>) {
|
||||||
self.current_script.assign(script);
|
self.current_script.assign(script);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn trigger_mozbrowser_event(self, event_name: String, event_detail: Option<String>) {
|
||||||
|
if opts::experimental_enabled() {
|
||||||
|
let window = self.window.root();
|
||||||
|
|
||||||
|
if let Some((containing_pipeline_id, subpage_id)) = window.r().parent_info() {
|
||||||
|
let ConstellationChan(ref chan) = window.r().constellation_chan();
|
||||||
|
let event = ConstellationMsg::MozBrowserEvent(containing_pipeline_id,
|
||||||
|
subpage_id,
|
||||||
|
event_name,
|
||||||
|
event_detail);
|
||||||
|
chan.send(event).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq)]
|
#[derive(PartialEq)]
|
||||||
|
@ -1438,19 +1463,8 @@ impl DocumentProgressHandler {
|
||||||
event.r().fire(target);
|
event.r().fire(target);
|
||||||
});
|
});
|
||||||
|
|
||||||
if opts::experimental_enabled() {
|
|
||||||
// If this is a child frame, and experimental mode is enabled,
|
|
||||||
// send the mozbrowserloadend event. For details, see
|
|
||||||
// https://developer.mozilla.org/en-US/docs/Web/Events/mozbrowserloadend
|
// https://developer.mozilla.org/en-US/docs/Web/Events/mozbrowserloadend
|
||||||
if let Some((containing_pipeline_id, subpage_id)) = window_ref.parent_info() {
|
document.r().trigger_mozbrowser_event("mozbrowserloadend".to_owned(), None);
|
||||||
let ConstellationChan(ref chan) = window_ref.constellation_chan();
|
|
||||||
let event = ConstellationMsg::MozBrowserEvent(containing_pipeline_id,
|
|
||||||
subpage_id,
|
|
||||||
"mozbrowserloadend".to_owned(),
|
|
||||||
None);
|
|
||||||
chan.send(event).unwrap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
window_ref.reflow(ReflowGoal::ForDisplay,
|
window_ref.reflow(ReflowGoal::ForDisplay,
|
||||||
ReflowQueryType::NoQuery,
|
ReflowQueryType::NoQuery,
|
||||||
|
|
|
@ -78,7 +78,7 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLTitleElement> {
|
||||||
let node: JSRef<Node> = NodeCast::from_ref(*self);
|
let node: JSRef<Node> = NodeCast::from_ref(*self);
|
||||||
if node.is_in_doc() {
|
if node.is_in_doc() {
|
||||||
let document = node.owner_doc().root();
|
let document = node.owner_doc().root();
|
||||||
document.r().send_title_to_compositor();
|
document.r().title_changed();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,7 +86,7 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLTitleElement> {
|
||||||
let node: JSRef<Node> = NodeCast::from_ref(*self);
|
let node: JSRef<Node> = NodeCast::from_ref(*self);
|
||||||
if is_in_doc {
|
if is_in_doc {
|
||||||
let document = node.owner_doc().root();
|
let document = node.owner_doc().root();
|
||||||
document.r().send_title_to_compositor()
|
document.r().title_changed();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -761,6 +761,11 @@ impl<'a> WindowHelpers for JSRef<'a, Window> {
|
||||||
|
|
||||||
fn thaw(self) {
|
fn thaw(self) {
|
||||||
self.timers.resume();
|
self.timers.resume();
|
||||||
|
|
||||||
|
// Push the document title to the compositor since we are
|
||||||
|
// activating this document due to a navigation.
|
||||||
|
let document = self.Document().root();
|
||||||
|
document.r().title_changed();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn freeze(self) {
|
fn freeze(self) {
|
||||||
|
|
|
@ -381,6 +381,7 @@ impl Window {
|
||||||
VirtualKeyCode::Semicolon => Ok(Key::Semicolon),
|
VirtualKeyCode::Semicolon => Ok(Key::Semicolon),
|
||||||
VirtualKeyCode::Slash => Ok(Key::Slash),
|
VirtualKeyCode::Slash => Ok(Key::Slash),
|
||||||
VirtualKeyCode::Tab => Ok(Key::Tab),
|
VirtualKeyCode::Tab => Ok(Key::Tab),
|
||||||
|
VirtualKeyCode::Subtract => Ok(Key::Minus),
|
||||||
|
|
||||||
_ => Err(()),
|
_ => Err(()),
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue