Skip to content

Commit

Permalink
Use html5ever for HTML parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
kmcallister committed Oct 16, 2014
1 parent 3fbb25c commit 9da7679
Show file tree
Hide file tree
Showing 13 changed files with 747 additions and 117 deletions.
60 changes: 28 additions & 32 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions components/script/Cargo.toml
Expand Up @@ -42,8 +42,9 @@ git = "https://github.com/servo/rust-cssparser"
[dependencies.geom]
git = "https://github.com/servo/rust-geom"

[dependencies.hubbub]
git = "https://github.com/servo/rust-hubbub"
[dependencies.html5ever]
git = "https://github.com/servo/html5ever"
branch = "servo"

[dependencies.encoding]
git = "https://github.com/lifthrasiir/rust-encoding"
Expand Down
15 changes: 12 additions & 3 deletions components/script/dom/bindings/trace.rs
Expand Up @@ -42,7 +42,6 @@ use std::collections::hashmap::HashMap;
use collections::hash::Hash;
use style::PropertyDeclarationBlock;
use std::comm::{Receiver, Sender};
use hubbub::hubbub::QuirksMode;
use string_cache::{Atom, Namespace};
use js::rust::Cx;
use http::headers::response::HeaderCollection as ResponseHeaderCollection;
Expand All @@ -55,7 +54,9 @@ use servo_msg::constellation_msg::ConstellationChan;
use servo_util::smallvec::{SmallVec1, SmallVec};
use servo_util::str::LengthOrPercentageOrAuto;
use layout_interface::{LayoutRPC, LayoutChan};
use dom::node::{Node, TrustedNodeAddress};
use dom::bindings::utils::WindowProxyHandler;
use html5ever::tree_builder::QuirksMode;

impl<T: Reflectable> JSTraceable for JS<T> {
fn trace(&self, trc: *mut JSTracer) {
Expand Down Expand Up @@ -207,6 +208,7 @@ untraceable!(ConstellationChan)
untraceable!(LayoutChan)
untraceable!(WindowProxyHandler)
untraceable!(UntrustedNodeAddress)
untraceable!(LengthOrPercentageOrAuto)

impl<'a> JSTraceable for &'a str {
#[inline]
Expand Down Expand Up @@ -236,5 +238,12 @@ impl JSTraceable for Box<LayoutRPC+'static> {
}
}

untraceable!(LengthOrPercentageOrAuto)

impl JSTraceable for TrustedNodeAddress {
fn trace(&self, s: *mut JSTracer) {
let TrustedNodeAddress(addr) = *self;
let node = addr as *const Node;
unsafe {
JS::from_raw(node).trace(s)
}
}
}
21 changes: 11 additions & 10 deletions components/script/dom/document.rs
Expand Up @@ -52,12 +52,12 @@ use dom::range::Range;
use dom::treewalker::TreeWalker;
use dom::uievent::UIEvent;
use dom::window::{Window, WindowHelpers};
use html::hubbub_html_parser::build_element_from_tag;
use hubbub::hubbub::{QuirksMode, NoQuirks, LimitedQuirks, FullQuirks};
use parse::html::build_element_from_tag;
use servo_util::namespace;
use servo_util::str::{DOMString, split_html_space_chars};

use string_cache::Atom;
use html5ever::tree_builder::{QuirksMode, NoQuirks, LimitedQuirks, Quirks};
use string_cache::{Atom, QualName};
use url::Url;

use std::collections::hashmap::HashMap;
Expand Down Expand Up @@ -426,7 +426,7 @@ impl<'a> DocumentMethods for JSRef<'a, Document> {
fn CompatMode(self) -> DOMString {
match self.quirks_mode.get() {
LimitedQuirks | NoQuirks => "CSS1Compat".to_string(),
FullQuirks => "BackCompat".to_string()
Quirks => "BackCompat".to_string()
}
}

Expand Down Expand Up @@ -492,7 +492,8 @@ impl<'a> DocumentMethods for JSRef<'a, Document> {
return Err(InvalidCharacter);
}
let local_name = local_name.as_slice().to_ascii_lower();
Ok(build_element_from_tag(local_name, ns!(HTML), None, self))
let name = QualName::new(ns!(HTML), Atom::from_slice(local_name.as_slice()));
Ok(build_element_from_tag(name, None, self))
}

// http://dom.spec.whatwg.org/#dom-document-createelementns
Expand All @@ -512,9 +513,9 @@ impl<'a> DocumentMethods for JSRef<'a, Document> {
QName => {}
}

let (prefix_from_qname,
local_name_from_qname) = get_attribute_parts(qualified_name.as_slice());
match (&ns, prefix_from_qname.clone(), local_name_from_qname.as_slice()) {
let (prefix_from_qname, local_name_from_qname)
= get_attribute_parts(qualified_name.as_slice());
match (&ns, prefix_from_qname, local_name_from_qname) {
// throw if prefix is not null and namespace is null
(&ns!(""), Some(_), _) => {
debug!("Namespace can't be null with a non-null prefix");
Expand All @@ -536,8 +537,8 @@ impl<'a> DocumentMethods for JSRef<'a, Document> {
}

if ns == ns!(HTML) {
Ok(build_element_from_tag(local_name_from_qname.to_string(), ns,
prefix_from_qname.map(|s| s.to_string()), self))
let name = QualName::new(ns!(HTML), Atom::from_slice(local_name_from_qname));
Ok(build_element_from_tag(name, prefix_from_qname.map(|s| s.to_string()), self))
} else {
Ok(Element::new(local_name_from_qname.to_string(), ns,
prefix_from_qname.map(|s| s.to_string()), self))
Expand Down
22 changes: 13 additions & 9 deletions components/script/dom/element.rs
Expand Up @@ -42,7 +42,7 @@ use servo_util::str::{DOMString, LengthOrPercentageOrAuto};
use std::ascii::StrAsciiExt;
use std::default::Default;
use std::mem;
use string_cache::{Atom, Namespace};
use string_cache::{Atom, Namespace, QualName};
use url::UrlParser;

#[dom_struct]
Expand Down Expand Up @@ -397,9 +397,8 @@ pub trait AttributeHandlers {
fn get_attributes(self, local_name: &Atom)
-> Vec<Temporary<Attr>>;
fn set_attribute_from_parser(self,
local_name: Atom,
name: QualName,
value: DOMString,
namespace: Namespace,
prefix: Option<DOMString>);
fn set_attribute(self, name: &Atom, value: AttrValue);
fn do_set_attribute(self, local_name: Atom, value: AttrValue,
Expand Down Expand Up @@ -445,19 +444,24 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> {
}

fn set_attribute_from_parser(self,
local_name: Atom,
qname: QualName,
value: DOMString,
namespace: Namespace,
prefix: Option<DOMString>) {
// Don't set if the attribute already exists, so we can handle add_attrs_if_missing
if self.attrs.borrow().iter().map(|attr| attr.root())
.any(|a| *a.local_name() == qname.local && *a.namespace() == qname.ns) {
return;
}

let name = match prefix {
None => local_name.clone(),
None => qname.local.clone(),
Some(ref prefix) => {
let name = format!("{:s}:{:s}", *prefix, local_name.as_slice());
let name = format!("{:s}:{:s}", *prefix, qname.local.as_slice());
Atom::from_slice(name.as_slice())
},
};
let value = self.parse_attribute(&namespace, &local_name, value);
self.do_set_attribute(local_name, value, name, namespace, prefix, |_| false)
let value = self.parse_attribute(&qname.ns, &qname.local, value);
self.do_set_attribute(qname.local, value, name, qname.ns, prefix, |_| false)
}

fn set_attribute(self, name: &Atom, value: AttrValue) {
Expand Down
22 changes: 17 additions & 5 deletions components/script/dom/node.rs
Expand Up @@ -44,9 +44,9 @@ use dom::text::Text;
use dom::virtualmethods::{VirtualMethods, vtable_for};
use dom::window::Window;
use geom::rect::Rect;
use html::hubbub_html_parser::build_element_from_tag;
use parse::html::build_element_from_tag;
use layout_interface::{ContentBoxResponse, ContentBoxesResponse, LayoutRPC,
LayoutChan, ReapLayoutDataMsg, TrustedNodeAddress};
LayoutChan, ReapLayoutDataMsg};
use devtools_traits::NodeInfo;
use script_traits::UntrustedNodeAddress;
use servo_util::geometry::Au;
Expand All @@ -56,7 +56,7 @@ use style::{parse_selector_list_from_str, matches};
use js::jsapi::{JSContext, JSObject, JSTracer, JSRuntime};
use js::jsfriendapi;
use libc;
use libc::uintptr_t;
use libc::{uintptr_t, c_void};
use std::cell::{Cell, RefCell, Ref, RefMut};
use std::default::Default;
use std::iter::{Map, Filter};
Expand All @@ -65,6 +65,7 @@ use style;
use style::ComputedValues;
use sync::Arc;
use uuid;
use string_cache::QualName;

//
// The basic Node structure
Expand Down Expand Up @@ -1530,8 +1531,12 @@ impl Node {
},
ElementNodeTypeId(..) => {
let element: JSRef<Element> = ElementCast::to_ref(node).unwrap();
let element = build_element_from_tag(element.local_name().as_slice().to_string(),
element.namespace().clone(), Some(element.prefix().as_slice().to_string()), *document);
let name = QualName {
ns: element.namespace().clone(),
local: element.local_name().clone()
};
let element = build_element_from_tag(name,
Some(element.prefix().as_slice().to_string()), *document);
NodeCast::from_temporary(element)
},
TextNodeTypeId => {
Expand Down Expand Up @@ -2159,6 +2164,13 @@ impl Reflectable for Node {
}
}

/// The address of a node known to be valid. These are sent from script to layout,
/// and are also used in the HTML parser interface.

#[allow(raw_pointer_deriving)]
#[deriving(Clone, PartialEq, Eq)]
pub struct TrustedNodeAddress(pub *const c_void);

pub fn document_from_node<T: NodeBase+Reflectable>(derived: JSRef<T>) -> Temporary<Document> {
let node: JSRef<Node> = NodeCast::from_ref(derived);
node.owner_doc()
Expand Down

0 comments on commit 9da7679

Please sign in to comment.