mirror of
https://github.com/servo/servo.git
synced 2025-08-06 22:15:33 +01:00
commit
11873117a1
6 changed files with 104 additions and 25 deletions
|
@ -4,6 +4,8 @@
|
||||||
|
|
||||||
use compositing::{CompositorChan, SetLayoutRenderChans};
|
use compositing::{CompositorChan, SetLayoutRenderChans};
|
||||||
|
|
||||||
|
use extra::net::url;
|
||||||
|
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::comm;
|
use std::comm;
|
||||||
use std::comm::Port;
|
use std::comm::Port;
|
||||||
|
@ -60,19 +62,20 @@ impl NavigationContext {
|
||||||
pub fn back(&mut self) -> uint {
|
pub fn back(&mut self) -> uint {
|
||||||
self.next.push(self.current.get());
|
self.next.push(self.current.get());
|
||||||
self.current = Some(self.previous.pop());
|
self.current = Some(self.previous.pop());
|
||||||
debug!("previous: %? next: %? current: %?", self.previous, self.next, self.current);
|
debug!("previous: %? next: %? current: %u", self.previous, self.next, self.current.get());
|
||||||
self.current.get()
|
self.current.get()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn forward(&mut self) -> uint {
|
pub fn forward(&mut self) -> uint {
|
||||||
self.previous.push(self.current.get());
|
self.previous.push(self.current.get());
|
||||||
self.current = Some(self.next.pop());
|
self.current = Some(self.next.pop());
|
||||||
debug!("previous: %? next: %? current: %?", self.previous, self.next, self.current);
|
debug!("previous: %? next: %? current: %u", self.previous, self.next, self.current.get());
|
||||||
self.current.get()
|
self.current.get()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Navigates to a new id, returning all id's evicted from next
|
/// Navigates to a new id, returning all id's evicted from next
|
||||||
pub fn navigate(&mut self, id: uint) -> ~[uint] {
|
pub fn navigate(&mut self, id: uint) -> ~[uint] {
|
||||||
|
debug!("navigating to %u", id);
|
||||||
let evicted = replace(&mut self.next, ~[]);
|
let evicted = replace(&mut self.next, ~[]);
|
||||||
do self.current.mutate_default(id) |cur_id| {
|
do self.current.mutate_default(id) |cur_id| {
|
||||||
self.previous.push(cur_id);
|
self.previous.push(cur_id);
|
||||||
|
@ -143,6 +146,7 @@ impl Constellation {
|
||||||
match request {
|
match request {
|
||||||
// Load a new page, usually either from a mouse click or typed url
|
// Load a new page, usually either from a mouse click or typed url
|
||||||
LoadUrlMsg(url) => {
|
LoadUrlMsg(url) => {
|
||||||
|
debug!("received message to load %s", url::to_str(&url));
|
||||||
let pipeline_id = self.get_next_id();
|
let pipeline_id = self.get_next_id();
|
||||||
let mut pipeline = Pipeline::create(pipeline_id,
|
let mut pipeline = Pipeline::create(pipeline_id,
|
||||||
self.chan.clone(),
|
self.chan.clone(),
|
||||||
|
@ -180,7 +184,6 @@ impl Constellation {
|
||||||
self.navigation_context.back()
|
self.navigation_context.back()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
debug!("navigating to pipeline %u", destination_id);
|
|
||||||
let mut pipeline = self.pipelines.pop(&destination_id).unwrap();
|
let mut pipeline = self.pipelines.pop(&destination_id).unwrap();
|
||||||
pipeline.navigation_type = Some(constellation_msg::Navigate);
|
pipeline.navigation_type = Some(constellation_msg::Navigate);
|
||||||
pipeline.reload();
|
pipeline.reload();
|
||||||
|
@ -234,7 +237,8 @@ impl Constellation {
|
||||||
for current_painter.iter().advance |id| {
|
for current_painter.iter().advance |id| {
|
||||||
self.pipelines.get(id).render_chan.send(PaintPermissionRevoked);
|
self.pipelines.get(id).render_chan.send(PaintPermissionRevoked);
|
||||||
}
|
}
|
||||||
let id = self.next_painter.get();
|
let id = replace(&mut self.next_painter, None);
|
||||||
|
let id = id.expect("constellation: called update painter when there was no next painter");
|
||||||
let pipeline = self.pipelines.get(&id);
|
let pipeline = self.pipelines.get(&id);
|
||||||
self.compositor_chan.send(SetLayoutRenderChans(pipeline.layout_chan.clone(),
|
self.compositor_chan.send(SetLayoutRenderChans(pipeline.layout_chan.clone(),
|
||||||
pipeline.render_chan.clone(),
|
pipeline.render_chan.clone(),
|
||||||
|
@ -247,7 +251,6 @@ impl Constellation {
|
||||||
let pipeline = self.pipelines.get(&id);
|
let pipeline = self.pipelines.get(&id);
|
||||||
pipeline.render_chan.send(PaintPermissionGranted);
|
pipeline.render_chan.send(PaintPermissionGranted);
|
||||||
self.current_painter = Some(id);
|
self.current_painter = Some(id);
|
||||||
self.next_painter = None;
|
|
||||||
// Don't navigate on Navigate type, because that is handled by forward/back
|
// Don't navigate on Navigate type, because that is handled by forward/back
|
||||||
match pipeline.navigation_type.get() {
|
match pipeline.navigation_type.get() {
|
||||||
constellation_msg::Load => {
|
constellation_msg::Load => {
|
||||||
|
|
|
@ -6,8 +6,10 @@ use dom::bindings::node::unwrap;
|
||||||
use dom::bindings::utils::jsval_to_str;
|
use dom::bindings::utils::jsval_to_str;
|
||||||
use dom::bindings::utils::{domstring_to_jsval, WrapNewBindingObject};
|
use dom::bindings::utils::{domstring_to_jsval, WrapNewBindingObject};
|
||||||
use dom::bindings::utils::{str, CacheableWrapper, DOM_OBJECT_SLOT, DOMString};
|
use dom::bindings::utils::{str, CacheableWrapper, DOM_OBJECT_SLOT, DOMString};
|
||||||
use dom::element::*;
|
use dom::element::Element;
|
||||||
use dom::node::{AbstractNode, Element, ElementNodeTypeId, ScriptView};
|
use dom::element::{HTMLImageElementTypeId, HTMLHeadElementTypeId, HTMLScriptElementTypeId,
|
||||||
|
HTMLDivElementTypeId};
|
||||||
|
use dom::node::{AbstractNode, ScriptView, ElementNodeTypeId};
|
||||||
use layout_interface::{ContentBoxQuery, ContentBoxResponse};
|
use layout_interface::{ContentBoxQuery, ContentBoxResponse};
|
||||||
use script_task::task_from_context;
|
use script_task::task_from_context;
|
||||||
use super::utils;
|
use super::utils;
|
||||||
|
|
|
@ -8,6 +8,7 @@ use dom::bindings::utils::DOMString;
|
||||||
use dom::clientrect::ClientRect;
|
use dom::clientrect::ClientRect;
|
||||||
use dom::clientrectlist::ClientRectList;
|
use dom::clientrectlist::ClientRectList;
|
||||||
use dom::node::{ElementNodeTypeId, Node, ScriptView};
|
use dom::node::{ElementNodeTypeId, Node, ScriptView};
|
||||||
|
use html::hubbub_html_parser::HtmlParserResult;
|
||||||
use layout_interface::{ContentBoxQuery, ContentBoxResponse, ContentBoxesQuery};
|
use layout_interface::{ContentBoxQuery, ContentBoxResponse, ContentBoxesQuery};
|
||||||
use layout_interface::{ContentBoxesResponse};
|
use layout_interface::{ContentBoxesResponse};
|
||||||
|
|
||||||
|
@ -37,6 +38,7 @@ pub enum ElementTypeId {
|
||||||
HTMLHeadElementTypeId,
|
HTMLHeadElementTypeId,
|
||||||
HTMLHeadingElementTypeId,
|
HTMLHeadingElementTypeId,
|
||||||
HTMLHtmlElementTypeId,
|
HTMLHtmlElementTypeId,
|
||||||
|
HTMLIframeElementTypeId,
|
||||||
HTMLImageElementTypeId,
|
HTMLImageElementTypeId,
|
||||||
HTMLInputElementTypeId,
|
HTMLInputElementTypeId,
|
||||||
HTMLItalicElementTypeId,
|
HTMLItalicElementTypeId,
|
||||||
|
@ -107,6 +109,12 @@ pub struct HTMLHeadingElement {
|
||||||
level: HeadingLevel,
|
level: HeadingLevel,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct HTMLIframeElement {
|
||||||
|
parent: Element,
|
||||||
|
frame: Option<Url>,
|
||||||
|
parse_result: Option<Port<HtmlParserResult>>
|
||||||
|
}
|
||||||
|
|
||||||
pub struct HTMLImageElement {
|
pub struct HTMLImageElement {
|
||||||
parent: Element,
|
parent: Element,
|
||||||
image: Option<Url>,
|
image: Option<Url>,
|
||||||
|
|
|
@ -10,7 +10,7 @@ use dom::bindings::utils::WrapperCache;
|
||||||
use dom::bindings;
|
use dom::bindings;
|
||||||
use dom::characterdata::CharacterData;
|
use dom::characterdata::CharacterData;
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::element::{Element, ElementTypeId, HTMLImageElement, HTMLImageElementTypeId};
|
use dom::element::{Element, ElementTypeId, HTMLImageElement, HTMLImageElementTypeId, HTMLIframeElementTypeId, HTMLIframeElement};
|
||||||
use dom::element::{HTMLStyleElementTypeId};
|
use dom::element::{HTMLStyleElementTypeId};
|
||||||
use script_task::global_script_context;
|
use script_task::global_script_context;
|
||||||
|
|
||||||
|
@ -340,6 +340,24 @@ impl<View> AbstractNode<View> {
|
||||||
self.transmute_mut(f)
|
self.transmute_mut(f)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_iframe_element(self) -> bool {
|
||||||
|
self.type_id() == ElementNodeTypeId(HTMLIframeElementTypeId)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_imm_iframe_element<R>(self, f: &fn(&HTMLIframeElement) -> R) -> R {
|
||||||
|
if !self.is_iframe_element() {
|
||||||
|
fail!(~"node is not an iframe element");
|
||||||
|
}
|
||||||
|
self.transmute(f)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_mut_iframe_element<R>(self, f: &fn(&mut HTMLIframeElement) -> R) -> R {
|
||||||
|
if !self.is_iframe_element() {
|
||||||
|
fail!(~"node is not an iframe element");
|
||||||
|
}
|
||||||
|
self.transmute_mut(f)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn is_style_element(self) -> bool {
|
pub fn is_style_element(self) -> bool {
|
||||||
self.type_id() == ElementNodeTypeId(HTMLStyleElementTypeId)
|
self.type_id() == ElementNodeTypeId(HTMLStyleElementTypeId)
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,33 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use dom::element::*;
|
use dom::element::{HTMLAnchorElementTypeId, HTMLAsideElementTypeId, HTMLBRElementTypeId,
|
||||||
use dom::node::{AbstractNode, Comment, Doctype, Element, ElementNodeTypeId, Node, ScriptView};
|
HTMLBodyElementTypeId, HTMLBoldElementTypeId, HTMLDivElementTypeId,
|
||||||
|
HTMLFontElementTypeId, HTMLFormElementTypeId, HTMLHRElementTypeId,
|
||||||
|
HTMLHeadElementTypeId, HTMLHtmlElementTypeId,
|
||||||
|
HTMLImageElementTypeId, HTMLIframeElementTypeId, HTMLInputElementTypeId,
|
||||||
|
HTMLItalicElementTypeId, HTMLLinkElementTypeId, HTMLListItemElementTypeId,
|
||||||
|
HTMLMetaElementTypeId, HTMLOListElementTypeId, HTMLOptionElementTypeId,
|
||||||
|
HTMLParagraphElementTypeId, HTMLScriptElementTypeId,
|
||||||
|
HTMLSectionElementTypeId, HTMLSelectElementTypeId, HTMLSmallElementTypeId,
|
||||||
|
HTMLSpanElementTypeId, HTMLStyleElementTypeId, HTMLTableBodyElementTypeId,
|
||||||
|
HTMLTableCellElementTypeId, HTMLTableElementTypeId,
|
||||||
|
HTMLTableRowElementTypeId, HTMLTitleElementTypeId, HTMLUListElementTypeId,
|
||||||
|
UnknownElementTypeId};
|
||||||
|
use dom::element::{HTMLAnchorElement, HTMLAsideElement, HTMLBRElement, HTMLBodyElement,
|
||||||
|
HTMLBoldElement, HTMLDivElement, HTMLFontElement, HTMLFormElement,
|
||||||
|
HTMLHRElement, HTMLHeadElement, HTMLHeadingElement, HTMLHtmlElement,
|
||||||
|
HTMLInputElement, HTMLImageElement, HTMLIframeElement,
|
||||||
|
HTMLItalicElement, HTMLLinkElement, HTMLListItemElement, HTMLMetaElement,
|
||||||
|
HTMLOListElement, HTMLOptionElement, HTMLParagraphElement,
|
||||||
|
HTMLScriptElement, HTMLSectionElement, HTMLSelectElement, HTMLSmallElement,
|
||||||
|
HTMLSpanElement, HTMLStyleElement, HTMLTableBodyElement,
|
||||||
|
HTMLTableCellElement, HTMLTableElement, HTMLTableRowElement,
|
||||||
|
HTMLTitleElement, HTMLUListElement};
|
||||||
|
use dom::element::{HTMLHeadingElementTypeId, Heading1, Heading2, Heading3, Heading4, Heading5,
|
||||||
|
Heading6};
|
||||||
|
use dom::element::{Element, Attr};
|
||||||
|
use dom::node::{AbstractNode, Comment, Doctype, ElementNodeTypeId, Node, ScriptView};
|
||||||
use dom::node::{Text};
|
use dom::node::{Text};
|
||||||
use html::cssparse::{InlineProvenance, StylesheetProvenance, UrlProvenance, spawn_css_parser};
|
use html::cssparse::{InlineProvenance, StylesheetProvenance, UrlProvenance, spawn_css_parser};
|
||||||
use newcss::stylesheet::Stylesheet;
|
use newcss::stylesheet::Stylesheet;
|
||||||
|
@ -52,7 +77,7 @@ enum JSMessage {
|
||||||
JSTaskExit
|
JSTaskExit
|
||||||
}
|
}
|
||||||
|
|
||||||
struct HtmlParserResult {
|
pub struct HtmlParserResult {
|
||||||
root: AbstractNode<ScriptView>,
|
root: AbstractNode<ScriptView>,
|
||||||
style_port: Port<Option<Stylesheet>>,
|
style_port: Port<Option<Stylesheet>>,
|
||||||
js_port: Port<JSResult>,
|
js_port: Port<JSResult>,
|
||||||
|
@ -194,6 +219,8 @@ fn build_element_from_tag(tag: &str) -> AbstractNode<ScriptView> {
|
||||||
handle_element!(tag, "ul", HTMLUListElementTypeId, HTMLUListElement, []);
|
handle_element!(tag, "ul", HTMLUListElementTypeId, HTMLUListElement, []);
|
||||||
|
|
||||||
handle_element!(tag, "img", HTMLImageElementTypeId, HTMLImageElement, [(image: None)]);
|
handle_element!(tag, "img", HTMLImageElementTypeId, HTMLImageElement, [(image: None)]);
|
||||||
|
handle_element!(tag, "iframe", HTMLIframeElementTypeId, HTMLIframeElement,
|
||||||
|
[(frame: None), (parse_result: None)]);
|
||||||
|
|
||||||
handle_element!(tag, "h1", HTMLHeadingElementTypeId, HTMLHeadingElement, [(level: Heading1)]);
|
handle_element!(tag, "h1", HTMLHeadingElementTypeId, HTMLHeadingElement, [(level: Heading1)]);
|
||||||
handle_element!(tag, "h2", HTMLHeadingElementTypeId, HTMLHeadingElement, [(level: Heading2)]);
|
handle_element!(tag, "h2", HTMLHeadingElementTypeId, HTMLHeadingElement, [(level: Heading2)]);
|
||||||
|
@ -213,6 +240,7 @@ pub fn parse_html(url: Url,
|
||||||
image_cache_task: ImageCacheTask) -> HtmlParserResult {
|
image_cache_task: ImageCacheTask) -> HtmlParserResult {
|
||||||
// Spawn a CSS parser to receive links to CSS style sheets.
|
// Spawn a CSS parser to receive links to CSS style sheets.
|
||||||
let resource_task2 = resource_task.clone();
|
let resource_task2 = resource_task.clone();
|
||||||
|
let resource_task3 = resource_task.clone();
|
||||||
|
|
||||||
let (stylesheet_port, stylesheet_chan) = comm::stream();
|
let (stylesheet_port, stylesheet_chan) = comm::stream();
|
||||||
let stylesheet_chan = Cell::new(stylesheet_chan);
|
let stylesheet_chan = Cell::new(stylesheet_chan);
|
||||||
|
@ -314,6 +342,29 @@ pub fn parse_html(url: Url,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
ElementNodeTypeId(HTMLIframeElementTypeId) => {
|
||||||
|
do node.with_mut_iframe_element |iframe_element| {
|
||||||
|
let src_opt = iframe_element.parent.get_attr("src").map(|x| x.to_str());
|
||||||
|
match src_opt {
|
||||||
|
None => {}
|
||||||
|
Some(src) => {
|
||||||
|
let iframe_url = make_url(src, Some(url2.clone()));
|
||||||
|
iframe_element.frame = Some(iframe_url.clone());
|
||||||
|
let (parse_port, parse_chan) = comm::stream();
|
||||||
|
iframe_element.parse_result = Some(parse_port);
|
||||||
|
let image_cache_task2 = Cell::new(image_cache_task.clone());
|
||||||
|
let resource_task3 = Cell::new(resource_task3.clone());
|
||||||
|
let iframe_url = Cell::new(iframe_url);
|
||||||
|
do task::spawn {
|
||||||
|
let result = parse_html(iframe_url.take(),
|
||||||
|
resource_task3.take(),
|
||||||
|
image_cache_task2.take());
|
||||||
|
parse_chan.send(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
ElementNodeTypeId(HTMLImageElementTypeId) => {
|
ElementNodeTypeId(HTMLImageElementTypeId) => {
|
||||||
do node.with_mut_image_element |image_element| {
|
do node.with_mut_image_element |image_element| {
|
||||||
let src_opt = image_element.parent.get_attr("src").map(|x| x.to_str());
|
let src_opt = image_element.parent.get_attr("src").map(|x| x.to_str());
|
||||||
|
|
|
@ -595,7 +595,7 @@ impl ScriptTask {
|
||||||
match self.query_layout(HitTestQuery(root, point, chan), port) {
|
match self.query_layout(HitTestQuery(root, point, chan), port) {
|
||||||
Ok(node) => match node {
|
Ok(node) => match node {
|
||||||
HitTestResponse(node) => {
|
HitTestResponse(node) => {
|
||||||
debug!("clicked on %?", node.debug_str());
|
debug!("clicked on %s", node.debug_str());
|
||||||
let mut node = node;
|
let mut node = node;
|
||||||
// traverse node generations until a node that is an element is found
|
// traverse node generations until a node that is an element is found
|
||||||
while !node.is_element() {
|
while !node.is_element() {
|
||||||
|
@ -608,9 +608,8 @@ impl ScriptTask {
|
||||||
}
|
}
|
||||||
if node.is_element() {
|
if node.is_element() {
|
||||||
do node.with_imm_element |element| {
|
do node.with_imm_element |element| {
|
||||||
match element.tag_name {
|
if "a" == element.tag_name {
|
||||||
~"a" => self.load_url_from_element(element),
|
self.load_url_from_element(element)
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -628,16 +627,14 @@ impl ScriptTask {
|
||||||
|
|
||||||
priv fn load_url_from_element(&self, element: &Element) {
|
priv fn load_url_from_element(&self, element: &Element) {
|
||||||
// if the node's element is "a," load url from href attr
|
// if the node's element is "a," load url from href attr
|
||||||
for element.attrs.iter().advance |attr| {
|
let href = element.get_attr("href");
|
||||||
if attr.name == ~"href" {
|
for href.iter().advance |href| {
|
||||||
debug!("clicked on link to %?", attr.value);
|
debug!("clicked on link to %s", *href);
|
||||||
let current_url = match self.root_frame {
|
let current_url = do self.root_frame.map |frame| {
|
||||||
Some(ref frame) => Some(frame.url.clone()),
|
frame.url.clone()
|
||||||
None => None
|
};
|
||||||
};
|
let url = make_url(href.to_owned(), current_url);
|
||||||
let url = make_url(attr.value.clone(), current_url);
|
self.constellation_chan.send(LoadUrlMsg(url));
|
||||||
self.constellation_chan.send(LoadUrlMsg(url));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue