mirror of
https://github.com/servo/servo.git
synced 2025-08-03 20:50:07 +01:00
Resvoled merge conflict
This commit is contained in:
commit
1511d7a2ad
143 changed files with 1834 additions and 2075 deletions
|
@ -5427,6 +5427,12 @@ impl ${name}Cast {
|
|||
unsafe { derived.transmute_borrowed() }
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
#[allow(unrooted_must_root)]
|
||||
pub fn from_layout_js<T: ${fromBound}+Reflectable>(derived: &LayoutJS<T>) -> LayoutJS<${name}> {
|
||||
unsafe { derived.transmute_copy() }
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn from_temporary<T: ${fromBound}+Reflectable>(derived: Temporary<T>) -> Temporary<${name}> {
|
||||
unsafe { derived.transmute() }
|
||||
|
|
|
@ -71,10 +71,9 @@ pub type Fallible<T> = Result<T, Error>;
|
|||
/// return `()`.
|
||||
pub type ErrorResult = Fallible<()>;
|
||||
|
||||
/// Set a pending DOM exception for the given `result` on `cx`.
|
||||
/// Set a pending exception for the given `result` on `cx`.
|
||||
pub fn throw_dom_exception(cx: *mut JSContext, global: GlobalRef,
|
||||
result: Error) {
|
||||
assert!(unsafe { JS_IsExceptionPending(cx) } == 0);
|
||||
let code = match result {
|
||||
Error::IndexSize => DOMErrorName::IndexSizeError,
|
||||
Error::NotFound => DOMErrorName::NotFoundError,
|
||||
|
@ -93,11 +92,17 @@ pub fn throw_dom_exception(cx: *mut JSContext, global: GlobalRef,
|
|||
Error::DataClone => DOMErrorName::DataCloneError,
|
||||
Error::NoModificationAllowed => DOMErrorName::NoModificationAllowedError,
|
||||
Error::Type(message) => {
|
||||
assert!(unsafe { JS_IsExceptionPending(cx) } == 0);
|
||||
throw_type_error(cx, &message);
|
||||
return;
|
||||
}
|
||||
Error::JSFailed => panic!(),
|
||||
Error::JSFailed => {
|
||||
assert!(unsafe { JS_IsExceptionPending(cx) } == 1);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
assert!(unsafe { JS_IsExceptionPending(cx) } == 0);
|
||||
let exception = DOMException::new(global, code).root();
|
||||
let thrown = exception.to_jsval(cx);
|
||||
unsafe {
|
||||
|
|
|
@ -7,14 +7,17 @@
|
|||
use dom::bindings::codegen::PrototypeList;
|
||||
use dom::bindings::codegen::PrototypeList::MAX_PROTO_CHAIN_LENGTH;
|
||||
use dom::bindings::conversions::{native_from_reflector_jsmanaged, is_dom_class};
|
||||
use dom::bindings::error::throw_type_error;
|
||||
use dom::bindings::error::{Error, ErrorResult, Fallible, throw_type_error};
|
||||
use dom::bindings::global::GlobalRef;
|
||||
use dom::bindings::js::{Temporary, Root};
|
||||
use dom::browsercontext;
|
||||
use dom::window;
|
||||
use util::namespace;
|
||||
use util::str::DOMString;
|
||||
|
||||
use libc;
|
||||
use libc::c_uint;
|
||||
use std::borrow::ToOwned;
|
||||
use std::boxed;
|
||||
use std::cell::Cell;
|
||||
use std::ffi::CString;
|
||||
|
@ -43,6 +46,7 @@ use js::rust::with_compartment;
|
|||
use js::{JSPROP_ENUMERATE, JSPROP_READONLY, JSPROP_PERMANENT};
|
||||
use js::JSFUN_CONSTRUCTOR;
|
||||
use js;
|
||||
use string_cache::{Atom, Namespace};
|
||||
|
||||
/// Proxy handler for a WindowProxy.
|
||||
pub struct WindowProxyHandler(pub *const libc::c_void);
|
||||
|
@ -604,6 +608,68 @@ pub unsafe fn delete_property_by_id(cx: *mut JSContext, object: *mut JSObject,
|
|||
return true;
|
||||
}
|
||||
|
||||
/// Validate a qualified name. See https://dom.spec.whatwg.org/#validate for details.
|
||||
pub fn validate_qualified_name(qualified_name: &str) -> ErrorResult {
|
||||
match xml_name_type(qualified_name) {
|
||||
XMLName::InvalidXMLName => {
|
||||
// Step 1.
|
||||
return Err(Error::InvalidCharacter);
|
||||
},
|
||||
XMLName::Name => {
|
||||
// Step 2.
|
||||
return Err(Error::Namespace);
|
||||
},
|
||||
XMLName::QName => Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// Validate a namespace and qualified name and extract their parts.
|
||||
/// See https://dom.spec.whatwg.org/#validate-and-extract for details.
|
||||
pub fn validate_and_extract(namespace: Option<DOMString>, qualified_name: &str)
|
||||
-> Fallible<(Namespace, Option<DOMString>, Atom)> {
|
||||
// Step 1.
|
||||
let namespace = namespace::from_domstring(namespace);
|
||||
|
||||
// Step 2.
|
||||
try!(validate_qualified_name(qualified_name));
|
||||
|
||||
let (prefix, local_name) = if qualified_name.contains(":") {
|
||||
// Step 5.
|
||||
let mut parts = qualified_name.splitn(1, ':');
|
||||
let prefix = parts.next().unwrap();
|
||||
debug_assert!(!prefix.is_empty());
|
||||
let local_name = parts.next().unwrap();
|
||||
debug_assert!(!local_name.contains(":"));
|
||||
(Some(prefix), local_name)
|
||||
} else {
|
||||
(None, qualified_name)
|
||||
};
|
||||
|
||||
match (namespace, prefix) {
|
||||
(ns!(""), Some(_)) => {
|
||||
// Step 6.
|
||||
Err(Error::Namespace)
|
||||
},
|
||||
(ref ns, Some("xml")) if ns != &ns!(XML) => {
|
||||
// Step 7.
|
||||
Err(Error::Namespace)
|
||||
},
|
||||
(ref ns, p) if ns != &ns!(XMLNS) &&
|
||||
(qualified_name == "xmlns" || p == Some("xmlns")) => {
|
||||
// Step 8.
|
||||
Err(Error::Namespace)
|
||||
},
|
||||
(ns!(XMLNS), p) if qualified_name != "xmlns" && p != Some("xmlns") => {
|
||||
// Step 9.
|
||||
Err(Error::Namespace)
|
||||
},
|
||||
(ns, p) => {
|
||||
// Step 10.
|
||||
Ok((ns, p.map(|s| s.to_owned()), Atom::from_slice(local_name)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Results of `xml_name_type`.
|
||||
#[derive(PartialEq)]
|
||||
#[allow(missing_docs)]
|
||||
|
|
|
@ -53,6 +53,7 @@ pub struct CanvasRenderingContext2D {
|
|||
image_smoothing_enabled: Cell<bool>,
|
||||
stroke_color: Cell<RGBA>,
|
||||
line_width: Cell<f64>,
|
||||
miter_limit: Cell<f64>,
|
||||
fill_color: Cell<RGBA>,
|
||||
transform: Cell<Matrix2D<f32>>,
|
||||
}
|
||||
|
@ -75,6 +76,7 @@ impl CanvasRenderingContext2D {
|
|||
image_smoothing_enabled: Cell::new(true),
|
||||
stroke_color: Cell::new(black),
|
||||
line_width: Cell::new(1.0),
|
||||
miter_limit: Cell::new(10.0),
|
||||
fill_color: Cell::new(black),
|
||||
transform: Cell::new(Matrix2D::identity()),
|
||||
}
|
||||
|
@ -258,6 +260,18 @@ impl CanvasRenderingContext2D {
|
|||
_ => panic!("Image Cache: Unknown Result")
|
||||
}
|
||||
}
|
||||
|
||||
fn create_drawable_rect(&self, x: f64, y: f64, w: f64, h: f64) -> Option<Rect<f32>> {
|
||||
if !([x, y, w, h].iter().all(|val| val.is_finite())) {
|
||||
return None;
|
||||
}
|
||||
|
||||
if w == 0.0 && h == 0.0 {
|
||||
return None;
|
||||
}
|
||||
|
||||
Some(Rect(Point2D(x as f32, y as f32), Size2D(w as f32, h as f32)))
|
||||
}
|
||||
}
|
||||
|
||||
pub trait CanvasRenderingContext2DHelpers {
|
||||
|
@ -358,33 +372,21 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D>
|
|||
}
|
||||
|
||||
fn FillRect(self, x: f64, y: f64, width: f64, height: f64) {
|
||||
if !(x.is_finite() && y.is_finite() &&
|
||||
width.is_finite() && height.is_finite()) {
|
||||
return;
|
||||
if let Some(rect) = self.create_drawable_rect(x, y, width, height) {
|
||||
self.renderer.send(CanvasMsg::FillRect(rect)).unwrap();
|
||||
}
|
||||
|
||||
let rect = Rect(Point2D(x as f32, y as f32), Size2D(width as f32, height as f32));
|
||||
self.renderer.send(CanvasMsg::FillRect(rect)).unwrap();
|
||||
}
|
||||
|
||||
fn ClearRect(self, x: f64, y: f64, width: f64, height: f64) {
|
||||
if !(x.is_finite() && y.is_finite() &&
|
||||
width.is_finite() && height.is_finite()) {
|
||||
return;
|
||||
if let Some(rect) = self.create_drawable_rect(x, y, width, height) {
|
||||
self.renderer.send(CanvasMsg::ClearRect(rect)).unwrap();
|
||||
}
|
||||
|
||||
let rect = Rect(Point2D(x as f32, y as f32), Size2D(width as f32, height as f32));
|
||||
self.renderer.send(CanvasMsg::ClearRect(rect)).unwrap();
|
||||
}
|
||||
|
||||
fn StrokeRect(self, x: f64, y: f64, width: f64, height: f64) {
|
||||
if !(x.is_finite() && y.is_finite() &&
|
||||
width.is_finite() && height.is_finite()) {
|
||||
return;
|
||||
if let Some(rect) = self.create_drawable_rect(x, y, width, height) {
|
||||
self.renderer.send(CanvasMsg::StrokeRect(rect)).unwrap();
|
||||
}
|
||||
|
||||
let rect = Rect(Point2D(x as f32, y as f32), Size2D(width as f32, height as f32));
|
||||
self.renderer.send(CanvasMsg::StrokeRect(rect)).unwrap();
|
||||
}
|
||||
|
||||
fn BeginPath(self) {
|
||||
|
@ -816,6 +818,19 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D>
|
|||
self.line_width.set(width);
|
||||
self.renderer.send(CanvasMsg::SetLineWidth(width as f32)).unwrap()
|
||||
}
|
||||
|
||||
fn MiterLimit(self) -> f64 {
|
||||
self.miter_limit.get()
|
||||
}
|
||||
|
||||
fn SetMiterLimit(self, limit: f64) {
|
||||
if !limit.is_finite() || limit <= 0.0 {
|
||||
return;
|
||||
}
|
||||
|
||||
self.miter_limit.set(limit);
|
||||
self.renderer.send(CanvasMsg::SetMiterLimit(limit as f32)).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
#[unsafe_destructor]
|
||||
|
|
|
@ -6,11 +6,13 @@
|
|||
|
||||
use dom::bindings::cell::DOMRefCell;
|
||||
use dom::bindings::codegen::Bindings::CharacterDataBinding::CharacterDataMethods;
|
||||
use dom::bindings::codegen::InheritTypes::{CharacterDataDerived, NodeCast};
|
||||
use dom::bindings::codegen::InheritTypes::{CharacterDataDerived, ElementCast};
|
||||
use dom::bindings::codegen::InheritTypes::NodeCast;
|
||||
use dom::bindings::error::{Fallible, ErrorResult};
|
||||
use dom::bindings::error::Error::IndexSize;
|
||||
use dom::bindings::js::JSRef;
|
||||
use dom::bindings::js::{JSRef, LayoutJS, Temporary};
|
||||
use dom::document::Document;
|
||||
use dom::element::Element;
|
||||
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
||||
use dom::node::{Node, NodeHelpers, NodeTypeId};
|
||||
|
||||
|
@ -18,6 +20,7 @@ use util::str::DOMString;
|
|||
|
||||
use std::borrow::ToOwned;
|
||||
use std::cell::Ref;
|
||||
use std::cmp;
|
||||
|
||||
#[dom_struct]
|
||||
pub struct CharacterData {
|
||||
|
@ -43,67 +46,59 @@ impl CharacterData {
|
|||
data: DOMRefCell::new(data),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn node<'a>(&'a self) -> &'a Node {
|
||||
&self.node
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn data(&self) -> Ref<DOMString> {
|
||||
self.data.borrow()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_data(&self, data: DOMString) {
|
||||
*self.data.borrow_mut() = data;
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[allow(unsafe_code)]
|
||||
pub unsafe fn data_for_layout<'a>(&'a self) -> &'a str {
|
||||
self.data.borrow_for_layout().as_slice()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
impl<'a> CharacterDataMethods for JSRef<'a, CharacterData> {
|
||||
// https://dom.spec.whatwg.org/#dom-characterdata-data
|
||||
fn Data(self) -> DOMString {
|
||||
// FIXME(https://github.com/rust-lang/rust/issues/23338)
|
||||
let data = self.data.borrow();
|
||||
data.clone()
|
||||
}
|
||||
|
||||
fn SetData(self, arg: DOMString) -> ErrorResult {
|
||||
*self.data.borrow_mut() = arg;
|
||||
Ok(())
|
||||
// https://dom.spec.whatwg.org/#dom-characterdata-data
|
||||
fn SetData(self, data: DOMString) {
|
||||
*self.data.borrow_mut() = data;
|
||||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#dom-characterdata-length
|
||||
fn Length(self) -> u32 {
|
||||
// FIXME(https://github.com/rust-lang/rust/issues/23338)
|
||||
let data = self.data.borrow();
|
||||
data.chars().count() as u32
|
||||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#dom-characterdata-substringdata
|
||||
fn SubstringData(self, offset: u32, count: u32) -> Fallible<DOMString> {
|
||||
// FIXME(https://github.com/rust-lang/rust/issues/23338)
|
||||
let data = self.data.borrow();
|
||||
Ok(data.slice_chars(offset as usize, (offset + count) as usize).to_owned())
|
||||
// Step 1.
|
||||
let len = data.chars().count();
|
||||
if len > offset as usize {
|
||||
// Step 2.
|
||||
return Err(IndexSize);
|
||||
}
|
||||
// Step 3.
|
||||
let end = cmp::min((offset + count) as usize, len);
|
||||
// Step 4.
|
||||
Ok(data.slice_chars(offset as usize, end).to_owned())
|
||||
}
|
||||
|
||||
fn AppendData(self, arg: DOMString) -> ErrorResult {
|
||||
self.data.borrow_mut().push_str(arg.as_slice());
|
||||
Ok(())
|
||||
// https://dom.spec.whatwg.org/#dom-characterdata-appenddata
|
||||
fn AppendData(self, data: DOMString) {
|
||||
self.data.borrow_mut().push_str(&data);
|
||||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#dom-characterdata-insertdata
|
||||
fn InsertData(self, offset: u32, arg: DOMString) -> ErrorResult {
|
||||
self.ReplaceData(offset, 0, arg)
|
||||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#dom-characterdata-deletedata
|
||||
fn DeleteData(self, offset: u32, count: u32) -> ErrorResult {
|
||||
self.ReplaceData(offset, count, "".to_owned())
|
||||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#dom-characterdata-replacedata
|
||||
fn ReplaceData(self, offset: u32, count: u32, arg: DOMString) -> ErrorResult {
|
||||
let length = self.data.borrow().chars().count() as u32;
|
||||
if offset > length {
|
||||
|
@ -127,5 +122,40 @@ impl<'a> CharacterDataMethods for JSRef<'a, CharacterData> {
|
|||
let node: JSRef<Node> = NodeCast::from_ref(self);
|
||||
node.remove_self();
|
||||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#dom-nondocumenttypechildnode-previouselementsibling
|
||||
fn GetPreviousElementSibling(self) -> Option<Temporary<Element>> {
|
||||
NodeCast::from_ref(self).preceding_siblings()
|
||||
.filter_map(ElementCast::to_temporary).next()
|
||||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#dom-nondocumenttypechildnode-nextelementsibling
|
||||
fn GetNextElementSibling(self) -> Option<Temporary<Element>> {
|
||||
NodeCast::from_ref(self).following_siblings()
|
||||
.filter_map(ElementCast::to_temporary).next()
|
||||
}
|
||||
}
|
||||
|
||||
pub trait CharacterDataHelpers<'a> {
|
||||
fn data(self) -> Ref<'a, DOMString>;
|
||||
}
|
||||
|
||||
impl<'a> CharacterDataHelpers<'a> for JSRef<'a, CharacterData> {
|
||||
#[inline]
|
||||
fn data(self) -> Ref<'a, DOMString> {
|
||||
self.extended_deref().data.borrow()
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(unsafe_code)]
|
||||
pub trait LayoutCharacterDataHelpers {
|
||||
unsafe fn data_for_layout<'a>(&'a self) -> &'a str;
|
||||
}
|
||||
|
||||
#[allow(unsafe_code)]
|
||||
impl LayoutCharacterDataHelpers for LayoutJS<CharacterData> {
|
||||
#[inline]
|
||||
unsafe fn data_for_layout<'a>(&'a self) -> &'a str {
|
||||
&(*self.unsafe_get()).data.borrow_for_layout()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,10 +42,5 @@ impl Comment {
|
|||
let document = global.as_window().Document().root();
|
||||
Ok(Comment::new(data, document.r()))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn characterdata<'a>(&'a self) -> &'a CharacterData {
|
||||
&self.characterdata
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -18,23 +18,24 @@ use dom::bindings::codegen::InheritTypes::{EventTargetCast, HTMLAnchorElementCas
|
|||
use dom::bindings::codegen::InheritTypes::{HTMLAnchorElementDerived, HTMLAppletElementDerived};
|
||||
use dom::bindings::codegen::InheritTypes::{HTMLAreaElementDerived, HTMLEmbedElementDerived};
|
||||
use dom::bindings::codegen::InheritTypes::{HTMLFormElementDerived, HTMLImageElementDerived};
|
||||
use dom::bindings::codegen::InheritTypes::{HTMLScriptElementDerived};
|
||||
use dom::bindings::codegen::InheritTypes::{HTMLScriptElementDerived, CharacterDataCast};
|
||||
use dom::bindings::error::{ErrorResult, Fallible};
|
||||
use dom::bindings::error::Error::{NotSupported, InvalidCharacter, Security};
|
||||
use dom::bindings::error::Error::{HierarchyRequest, Namespace};
|
||||
use dom::bindings::error::Error::HierarchyRequest;
|
||||
use dom::bindings::global::GlobalRef;
|
||||
use dom::bindings::js::{MutNullableJS, JS, JSRef, LayoutJS, Temporary, TemporaryPushable};
|
||||
use dom::bindings::js::{OptionalRootable, RootedReference};
|
||||
use dom::bindings::refcounted::Trusted;
|
||||
use dom::bindings::utils::reflect_dom_object;
|
||||
use dom::bindings::utils::xml_name_type;
|
||||
use dom::bindings::utils::XMLName::{QName, Name, InvalidXMLName};
|
||||
use dom::bindings::utils::{xml_name_type, validate_and_extract};
|
||||
use dom::bindings::utils::XMLName::InvalidXMLName;
|
||||
use dom::characterdata::CharacterDataHelpers;
|
||||
use dom::comment::Comment;
|
||||
use dom::customevent::CustomEvent;
|
||||
use dom::documentfragment::DocumentFragment;
|
||||
use dom::documenttype::DocumentType;
|
||||
use dom::domimplementation::DOMImplementation;
|
||||
use dom::element::{Element, ElementCreator, AttributeHandlers, get_attribute_parts};
|
||||
use dom::element::{Element, ElementCreator, AttributeHandlers};
|
||||
use dom::element::{ElementTypeId, ActivationElementHelpers};
|
||||
use dom::event::{Event, EventBubbles, EventCancelable, EventHelpers};
|
||||
use dom::eventtarget::{EventTarget, EventTargetTypeId, EventTargetHelpers};
|
||||
|
@ -67,7 +68,7 @@ use net_traits::CookieSource::NonHTTP;
|
|||
use net_traits::ControlMsg::{SetCookiesForUrl, GetCookiesForUrl};
|
||||
use script_task::Runnable;
|
||||
use script_traits::{MouseButton, UntrustedNodeAddress};
|
||||
use util::{opts, namespace};
|
||||
use util::opts;
|
||||
use util::str::{DOMString, split_html_space_chars};
|
||||
use layout_interface::{ReflowGoal, ReflowQueryType};
|
||||
|
||||
|
@ -975,45 +976,10 @@ impl<'a> DocumentMethods for JSRef<'a, Document> {
|
|||
fn CreateElementNS(self,
|
||||
namespace: Option<DOMString>,
|
||||
qualified_name: DOMString) -> Fallible<Temporary<Element>> {
|
||||
let ns = namespace::from_domstring(namespace);
|
||||
match xml_name_type(&qualified_name) {
|
||||
InvalidXMLName => {
|
||||
debug!("Not a valid element name");
|
||||
return Err(InvalidCharacter);
|
||||
},
|
||||
Name => {
|
||||
debug!("Not a valid qualified element name");
|
||||
return Err(Namespace);
|
||||
},
|
||||
QName => {}
|
||||
}
|
||||
|
||||
let (prefix_from_qname, local_name_from_qname) = get_attribute_parts(&qualified_name);
|
||||
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");
|
||||
return Err(Namespace);
|
||||
},
|
||||
// throw if prefix is "xml" and namespace is not the XML namespace
|
||||
(_, Some(ref prefix), _) if "xml" == *prefix && ns != ns!(XML) => {
|
||||
debug!("Namespace must be the xml namespace if the prefix is 'xml'");
|
||||
return Err(Namespace);
|
||||
},
|
||||
// throw if namespace is the XMLNS namespace and neither qualifiedName nor prefix is
|
||||
// "xmlns"
|
||||
(&ns!(XMLNS), Some(ref prefix), _) if "xmlns" == *prefix => {},
|
||||
(&ns!(XMLNS), _, "xmlns") => {},
|
||||
(&ns!(XMLNS), _, _) => {
|
||||
debug!("The prefix or the qualified name must be 'xmlns' if namespace is the XMLNS namespace ");
|
||||
return Err(Namespace);
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
|
||||
let name = QualName::new(ns, Atom::from_slice(local_name_from_qname));
|
||||
Ok(Element::create(name, prefix_from_qname.map(|s| s.to_owned()), self,
|
||||
ElementCreator::ScriptCreated))
|
||||
let (namespace, prefix, local_name) =
|
||||
try!(validate_and_extract(namespace, &qualified_name));
|
||||
let name = QualName::new(namespace, local_name);
|
||||
Ok(Element::create(name, prefix, self, ElementCreator::ScriptCreated))
|
||||
}
|
||||
|
||||
// http://dom.spec.whatwg.org/#dom-document-createattribute
|
||||
|
@ -1032,6 +998,18 @@ impl<'a> DocumentMethods for JSRef<'a, Document> {
|
|||
Ok(Attr::new(window.r(), name, value, l_name, ns!(""), None, None))
|
||||
}
|
||||
|
||||
// http://dom.spec.whatwg.org/#dom-document-createattributens
|
||||
fn CreateAttributeNS(self, namespace: Option<DOMString>, qualified_name: DOMString)
|
||||
-> Fallible<Temporary<Attr>> {
|
||||
let (namespace, prefix, local_name) =
|
||||
try!(validate_and_extract(namespace, &qualified_name));
|
||||
let window = self.window.root();
|
||||
let value = AttrValue::String("".to_owned());
|
||||
let qualified_name = Atom::from_slice(&qualified_name);
|
||||
Ok(Attr::new(window.r(), local_name, value, qualified_name,
|
||||
namespace, prefix, None))
|
||||
}
|
||||
|
||||
// http://dom.spec.whatwg.org/#dom-document-createdocumentfragment
|
||||
fn CreateDocumentFragment(self) -> Temporary<DocumentFragment> {
|
||||
DocumentFragment::new(self)
|
||||
|
@ -1148,7 +1126,7 @@ impl<'a> DocumentMethods for JSRef<'a, Document> {
|
|||
for child in title_element.children() {
|
||||
let child = child.root();
|
||||
if let Some(text) = TextCast::to_ref(child.r()) {
|
||||
title.push_str(&text.characterdata().data());
|
||||
title.push_str(&CharacterDataCast::from_ref(text).data());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,12 +8,10 @@ use dom::bindings::codegen::Bindings::DOMImplementationBinding::DOMImplementatio
|
|||
use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
|
||||
use dom::bindings::codegen::InheritTypes::NodeCast;
|
||||
use dom::bindings::error::Fallible;
|
||||
use dom::bindings::error::Error::{InvalidCharacter, Namespace};
|
||||
use dom::bindings::global::GlobalRef;
|
||||
use dom::bindings::js::{JS, JSRef, Root, Temporary, OptionalRootable};
|
||||
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
||||
use dom::bindings::utils::xml_name_type;
|
||||
use dom::bindings::utils::XMLName::{QName, Name, InvalidXMLName};
|
||||
use dom::bindings::utils::validate_qualified_name;
|
||||
use dom::document::{Document, DocumentHelpers, IsHTMLDocument};
|
||||
use dom::document::DocumentSource;
|
||||
use dom::documenttype::DocumentType;
|
||||
|
@ -52,18 +50,11 @@ impl DOMImplementation {
|
|||
// http://dom.spec.whatwg.org/#domimplementation
|
||||
impl<'a> DOMImplementationMethods for JSRef<'a, DOMImplementation> {
|
||||
// http://dom.spec.whatwg.org/#dom-domimplementation-createdocumenttype
|
||||
fn CreateDocumentType(self, qname: DOMString, pubid: DOMString, sysid: DOMString) -> Fallible<Temporary<DocumentType>> {
|
||||
match xml_name_type(&qname) {
|
||||
// Step 1.
|
||||
InvalidXMLName => Err(InvalidCharacter),
|
||||
// Step 2.
|
||||
Name => Err(Namespace),
|
||||
// Step 3.
|
||||
QName => {
|
||||
let document = self.document.root();
|
||||
Ok(DocumentType::new(qname, Some(pubid), Some(sysid), document.r()))
|
||||
}
|
||||
}
|
||||
fn CreateDocumentType(self, qualified_name: DOMString, pubid: DOMString, sysid: DOMString)
|
||||
-> Fallible<Temporary<DocumentType>> {
|
||||
try!(validate_qualified_name(&qualified_name));
|
||||
let document = self.document.root();
|
||||
Ok(DocumentType::new(qualified_name, Some(pubid), Some(sysid), document.r()))
|
||||
}
|
||||
|
||||
// http://dom.spec.whatwg.org/#dom-domimplementation-createdocument
|
||||
|
|
|
@ -24,14 +24,13 @@ use dom::bindings::codegen::InheritTypes::{HTMLTableRowElementDerived, HTMLTextA
|
|||
use dom::bindings::codegen::InheritTypes::{HTMLTableSectionElementDerived, NodeCast};
|
||||
use dom::bindings::codegen::InheritTypes::HTMLAnchorElementCast;
|
||||
use dom::bindings::error::{ErrorResult, Fallible};
|
||||
use dom::bindings::error::Error;
|
||||
use dom::bindings::error::Error::{InvalidCharacter, Syntax};
|
||||
use dom::bindings::error::Error::NoModificationAllowed;
|
||||
use dom::bindings::js::{MutNullableJS, JS, JSRef, LayoutJS, Temporary, TemporaryPushable};
|
||||
use dom::bindings::js::{OptionalRootable, RootedReference};
|
||||
use dom::bindings::trace::RootedVec;
|
||||
use dom::bindings::utils::xml_name_type;
|
||||
use dom::bindings::utils::XMLName::{QName, Name, InvalidXMLName};
|
||||
use dom::bindings::utils::{xml_name_type, validate_and_extract};
|
||||
use dom::bindings::utils::XMLName::InvalidXMLName;
|
||||
use dom::create::create_element;
|
||||
use dom::domrect::DOMRect;
|
||||
use dom::domrectlist::DOMRectList;
|
||||
|
@ -1037,58 +1036,14 @@ impl<'a> ElementMethods for JSRef<'a, Element> {
|
|||
|
||||
// http://dom.spec.whatwg.org/#dom-element-setattributens
|
||||
fn SetAttributeNS(self,
|
||||
namespace_url: Option<DOMString>,
|
||||
name: DOMString,
|
||||
namespace: Option<DOMString>,
|
||||
qualified_name: DOMString,
|
||||
value: DOMString) -> ErrorResult {
|
||||
// Step 1.
|
||||
let namespace = namespace::from_domstring(namespace_url);
|
||||
|
||||
let name_type = xml_name_type(&name);
|
||||
match name_type {
|
||||
// Step 2.
|
||||
InvalidXMLName => return Err(InvalidCharacter),
|
||||
// Step 3.
|
||||
Name => return Err(Error::Namespace),
|
||||
QName => {}
|
||||
}
|
||||
|
||||
// Step 4.
|
||||
let (prefix, local_name) = get_attribute_parts(&name);
|
||||
|
||||
if let Some(ref prefix_str) = prefix {
|
||||
// Step 5.
|
||||
if namespace == ns!("") {
|
||||
return Err(Error::Namespace);
|
||||
}
|
||||
|
||||
// Step 6.
|
||||
if "xml" == *prefix_str && namespace != ns!(XML) {
|
||||
return Err(Error::Namespace);
|
||||
}
|
||||
|
||||
// Step 7b.
|
||||
if "xmlns" == *prefix_str && namespace != ns!(XMLNS) {
|
||||
return Err(Error::Namespace);
|
||||
}
|
||||
}
|
||||
|
||||
let name = Atom::from_slice(&name);
|
||||
let local_name = Atom::from_slice(local_name);
|
||||
let xmlns = atom!("xmlns");
|
||||
|
||||
// Step 7a.
|
||||
if xmlns == name && namespace != ns!(XMLNS) {
|
||||
return Err(Error::Namespace);
|
||||
}
|
||||
|
||||
// Step 8.
|
||||
if namespace == ns!(XMLNS) && xmlns != name && Some("xmlns") != prefix {
|
||||
return Err(Error::Namespace);
|
||||
}
|
||||
|
||||
// Step 9.
|
||||
let (namespace, prefix, local_name) =
|
||||
try!(validate_and_extract(namespace, &qualified_name));
|
||||
let qualified_name = Atom::from_slice(&qualified_name);
|
||||
let value = self.parse_attribute(&namespace, &local_name, value);
|
||||
self.do_set_attribute(local_name.clone(), value, name,
|
||||
self.do_set_attribute(local_name.clone(), value, qualified_name,
|
||||
namespace.clone(), prefix.map(|s| s.to_owned()),
|
||||
|attr| {
|
||||
*attr.local_name() == local_name &&
|
||||
|
@ -1223,6 +1178,18 @@ impl<'a> ElementMethods for JSRef<'a, Element> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#dom-nondocumenttypechildnode-previouselementsibling
|
||||
fn GetPreviousElementSibling(self) -> Option<Temporary<Element>> {
|
||||
NodeCast::from_ref(self).preceding_siblings()
|
||||
.filter_map(ElementCast::to_temporary).next()
|
||||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#dom-nondocumenttypechildnode-nextelementsibling
|
||||
fn GetNextElementSibling(self) -> Option<Temporary<Element>> {
|
||||
NodeCast::from_ref(self).following_siblings()
|
||||
.filter_map(ElementCast::to_temporary).next()
|
||||
}
|
||||
|
||||
// http://dom.spec.whatwg.org/#dom-parentnode-children
|
||||
fn Children(self) -> Temporary<HTMLCollection> {
|
||||
let window = window_from_node(self).root();
|
||||
|
@ -1293,17 +1260,6 @@ impl<'a> ElementMethods for JSRef<'a, Element> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn get_attribute_parts<'a>(name: &'a str) -> (Option<&'a str>, &'a str) {
|
||||
//FIXME: Throw for XML-invalid names
|
||||
//FIXME: Throw for XMLNS-invalid names
|
||||
if name.contains(":") {
|
||||
let mut parts = name.splitn(1, ':');
|
||||
(Some(parts.next().unwrap()), parts.next().unwrap())
|
||||
} else {
|
||||
(None, name)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> VirtualMethods for JSRef<'a, Element> {
|
||||
fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> {
|
||||
let node: &JSRef<Node> = NodeCast::from_borrowed_ref(self);
|
||||
|
|
|
@ -524,8 +524,7 @@ impl<'a> HTMLScriptElementMethods for JSRef<'a, HTMLScriptElement> {
|
|||
|
||||
// http://www.whatwg.org/html/#dom-script-text
|
||||
fn Text(self) -> DOMString {
|
||||
let node: JSRef<Node> = NodeCast::from_ref(self);
|
||||
Node::collect_text_contents(node.children().map(|c| c.root()).map(|c| c.get_unsound_ref_forever()))
|
||||
Node::collect_text_contents(NodeCast::from_ref(self).children())
|
||||
}
|
||||
|
||||
// http://www.whatwg.org/html/#dom-script-text
|
||||
|
|
|
@ -6,8 +6,9 @@ use dom::bindings::codegen::Bindings::HTMLTitleElementBinding;
|
|||
use dom::bindings::codegen::Bindings::HTMLTitleElementBinding::HTMLTitleElementMethods;
|
||||
use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
|
||||
use dom::bindings::codegen::InheritTypes::{HTMLElementCast, HTMLTitleElementDerived, NodeCast};
|
||||
use dom::bindings::codegen::InheritTypes::{TextCast};
|
||||
use dom::bindings::codegen::InheritTypes::{CharacterDataCast, TextCast};
|
||||
use dom::bindings::js::{JSRef, Temporary};
|
||||
use dom::characterdata::CharacterDataHelpers;
|
||||
use dom::document::{Document, DocumentHelpers};
|
||||
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
||||
use dom::element::ElementTypeId;
|
||||
|
@ -51,7 +52,7 @@ impl<'a> HTMLTitleElementMethods for JSRef<'a, HTMLTitleElement> {
|
|||
let child = child.root();
|
||||
let text: Option<JSRef<Text>> = TextCast::to_ref(child.r());
|
||||
match text {
|
||||
Some(text) => content.push_str(text.characterdata().data().as_slice()),
|
||||
Some(text) => content.push_str(&CharacterDataCast::from_ref(text).data()),
|
||||
None => (),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -315,6 +315,7 @@ pub mod servohtmlparser;
|
|||
pub mod storage;
|
||||
pub mod storageevent;
|
||||
pub mod text;
|
||||
pub mod textdecoder;
|
||||
pub mod textencoder;
|
||||
pub mod treewalker;
|
||||
pub mod uievent;
|
||||
|
|
|
@ -13,12 +13,11 @@ use dom::bindings::codegen::Bindings::NamedNodeMapBinding::NamedNodeMapMethods;
|
|||
use dom::bindings::codegen::Bindings::NodeBinding::{NodeConstants, NodeMethods};
|
||||
use dom::bindings::codegen::Bindings::NodeListBinding::NodeListMethods;
|
||||
use dom::bindings::codegen::Bindings::ProcessingInstructionBinding::ProcessingInstructionMethods;
|
||||
use dom::bindings::codegen::InheritTypes::{CommentCast, DocumentCast, DocumentTypeCast};
|
||||
use dom::bindings::codegen::InheritTypes::{ElementCast, TextCast, NodeCast, ElementDerived};
|
||||
use dom::bindings::codegen::InheritTypes::{CharacterDataCast, NodeBase, NodeDerived};
|
||||
use dom::bindings::codegen::InheritTypes::{ProcessingInstructionCast, EventTargetCast};
|
||||
use dom::bindings::codegen::InheritTypes::{CharacterDataCast, DocumentCast, DocumentTypeCast};
|
||||
use dom::bindings::codegen::InheritTypes::{ElementCast, NodeCast, ElementDerived, EventTargetCast};
|
||||
use dom::bindings::codegen::InheritTypes::{HTMLLegendElementDerived, HTMLFieldSetElementDerived};
|
||||
use dom::bindings::codegen::InheritTypes::HTMLOptGroupElementDerived;
|
||||
use dom::bindings::codegen::InheritTypes::{HTMLOptGroupElementDerived, NodeBase, NodeDerived};
|
||||
use dom::bindings::codegen::InheritTypes::{ProcessingInstructionCast, TextCast};
|
||||
use dom::bindings::conversions;
|
||||
use dom::bindings::error::Fallible;
|
||||
use dom::bindings::error::Error::{NotFound, HierarchyRequest, Syntax};
|
||||
|
@ -29,7 +28,7 @@ use dom::bindings::js::{ResultRootable, OptionalRootable, MutNullableJS};
|
|||
use dom::bindings::trace::JSTraceable;
|
||||
use dom::bindings::trace::RootedVec;
|
||||
use dom::bindings::utils::{Reflectable, reflect_dom_object};
|
||||
use dom::characterdata::CharacterData;
|
||||
use dom::characterdata::{CharacterData, CharacterDataHelpers};
|
||||
use dom::comment::Comment;
|
||||
use dom::document::{Document, DocumentHelpers, IsHTMLDocument, DocumentSource};
|
||||
use dom::documentfragment::DocumentFragment;
|
||||
|
@ -415,6 +414,7 @@ pub trait NodeHelpers<'a> {
|
|||
fn rev_children(self) -> ReverseChildrenIterator;
|
||||
fn child_elements(self) -> ChildElementIterator;
|
||||
fn following_siblings(self) -> NodeSiblingIterator;
|
||||
fn preceding_siblings(self) -> ReverseChildrenIterator;
|
||||
fn is_in_doc(self) -> bool;
|
||||
fn is_inclusive_ancestor_of(self, parent: JSRef<Node>) -> bool;
|
||||
fn is_parent_of(self, child: JSRef<Node>) -> bool;
|
||||
|
@ -764,6 +764,12 @@ impl<'a> NodeHelpers<'a> for JSRef<'a, Node> {
|
|||
}
|
||||
}
|
||||
|
||||
fn preceding_siblings(self) -> ReverseChildrenIterator {
|
||||
ReverseChildrenIterator {
|
||||
current: self.prev_sibling(),
|
||||
}
|
||||
}
|
||||
|
||||
fn is_parent_of(self, child: JSRef<Node>) -> bool {
|
||||
match child.parent_node() {
|
||||
Some(ref parent) if parent == &Temporary::from_rooted(self) => true,
|
||||
|
@ -1594,8 +1600,8 @@ impl Node {
|
|||
NodeCast::from_temporary(doc_fragment)
|
||||
},
|
||||
NodeTypeId::Comment => {
|
||||
let comment: JSRef<Comment> = CommentCast::to_ref(node).unwrap();
|
||||
let comment = Comment::new(comment.characterdata().data().clone(), document.r());
|
||||
let cdata = CharacterDataCast::to_ref(node).unwrap();
|
||||
let comment = Comment::new(cdata.Data(), document.r());
|
||||
NodeCast::from_temporary(comment)
|
||||
},
|
||||
NodeTypeId::Document => {
|
||||
|
@ -1622,14 +1628,14 @@ impl Node {
|
|||
NodeCast::from_temporary(element)
|
||||
},
|
||||
NodeTypeId::Text => {
|
||||
let text: JSRef<Text> = TextCast::to_ref(node).unwrap();
|
||||
let text = Text::new(text.characterdata().data().clone(), document.r());
|
||||
let cdata = CharacterDataCast::to_ref(node).unwrap();
|
||||
let text = Text::new(cdata.Data(), document.r());
|
||||
NodeCast::from_temporary(text)
|
||||
},
|
||||
NodeTypeId::ProcessingInstruction => {
|
||||
let pi: JSRef<ProcessingInstruction> = ProcessingInstructionCast::to_ref(node).unwrap();
|
||||
let pi = ProcessingInstruction::new(pi.target().clone(),
|
||||
pi.characterdata().data().clone(), document.r());
|
||||
CharacterDataCast::from_ref(pi).Data(), document.r());
|
||||
NodeCast::from_temporary(pi)
|
||||
},
|
||||
}.root();
|
||||
|
@ -1683,12 +1689,13 @@ impl Node {
|
|||
Temporary::from_rooted(copy.r())
|
||||
}
|
||||
|
||||
pub fn collect_text_contents<'a, T: Iterator<Item=JSRef<'a, Node>>>(iterator: T) -> String {
|
||||
pub fn collect_text_contents<T: Iterator<Item=Temporary<Node>>>(iterator: T) -> String {
|
||||
let mut content = String::new();
|
||||
for node in iterator {
|
||||
let text: Option<JSRef<Text>> = TextCast::to_ref(node);
|
||||
let node = node.root();
|
||||
let text = TextCast::to_ref(node.r());
|
||||
match text {
|
||||
Some(text) => content.push_str(text.characterdata().data().as_slice()),
|
||||
Some(text) => content.push_str(&CharacterDataCast::from_ref(text).Data()),
|
||||
None => (),
|
||||
}
|
||||
}
|
||||
|
@ -1834,7 +1841,8 @@ impl<'a> NodeMethods for JSRef<'a, Node> {
|
|||
match self.type_id {
|
||||
NodeTypeId::DocumentFragment |
|
||||
NodeTypeId::Element(..) => {
|
||||
let content = Node::collect_text_contents(self.traverse_preorder());
|
||||
let content = Node::collect_text_contents(
|
||||
self.traverse_preorder().map(Temporary::from_rooted));
|
||||
Some(content)
|
||||
}
|
||||
NodeTypeId::Comment |
|
||||
|
@ -1871,7 +1879,7 @@ impl<'a> NodeMethods for JSRef<'a, Node> {
|
|||
NodeTypeId::Text |
|
||||
NodeTypeId::ProcessingInstruction => {
|
||||
let characterdata: JSRef<CharacterData> = CharacterDataCast::to_ref(self).unwrap();
|
||||
characterdata.set_data(value);
|
||||
characterdata.SetData(value);
|
||||
|
||||
// Notify the document that the content of this node is different
|
||||
let document = self.owner_doc().root();
|
||||
|
@ -2114,7 +2122,7 @@ impl<'a> NodeMethods for JSRef<'a, Node> {
|
|||
let pi: JSRef<ProcessingInstruction> = ProcessingInstructionCast::to_ref(node).unwrap();
|
||||
let other_pi: JSRef<ProcessingInstruction> = ProcessingInstructionCast::to_ref(other).unwrap();
|
||||
(*pi.target() == *other_pi.target()) &&
|
||||
(*pi.characterdata().data() == *other_pi.characterdata().data())
|
||||
(*CharacterDataCast::from_ref(pi).data() == *CharacterDataCast::from_ref(other_pi).data())
|
||||
}
|
||||
fn is_equal_characterdata(node: JSRef<Node>, other: JSRef<Node>) -> bool {
|
||||
let characterdata: JSRef<CharacterData> = CharacterDataCast::to_ref(node).unwrap();
|
||||
|
|
|
@ -38,10 +38,6 @@ impl ProcessingInstruction {
|
|||
document, ProcessingInstructionBinding::Wrap)
|
||||
}
|
||||
|
||||
pub fn characterdata<'a>(&'a self) -> &'a CharacterData {
|
||||
&self.characterdata
|
||||
}
|
||||
|
||||
pub fn target<'a>(&'a self) -> &'a DOMString {
|
||||
&self.target
|
||||
}
|
||||
|
|
|
@ -42,10 +42,5 @@ impl Text {
|
|||
let document = global.as_window().Document().root();
|
||||
Ok(Text::new(text, document.r()))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn characterdata<'a>(&'a self) -> &'a CharacterData {
|
||||
&self.characterdata
|
||||
}
|
||||
}
|
||||
|
||||
|
|
99
components/script/dom/textdecoder.rs
Normal file
99
components/script/dom/textdecoder.rs
Normal file
|
@ -0,0 +1,99 @@
|
|||
/* 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 http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use dom::bindings::codegen::Bindings::TextDecoderBinding;
|
||||
use dom::bindings::codegen::Bindings::TextDecoderBinding::TextDecoderMethods;
|
||||
use dom::bindings::error::{Error, Fallible};
|
||||
use dom::bindings::global::GlobalRef;
|
||||
use dom::bindings::js::{JSRef, Temporary};
|
||||
use dom::bindings::str::USVString;
|
||||
use dom::bindings::trace::JSTraceable;
|
||||
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
||||
|
||||
use util::str::DOMString;
|
||||
|
||||
use encoding::Encoding;
|
||||
use encoding::types::{EncodingRef, DecoderTrap};
|
||||
use encoding::label::encoding_from_whatwg_label;
|
||||
use js::jsapi::{JSContext, JSObject};
|
||||
use js::jsfriendapi::bindgen::JS_GetObjectAsArrayBufferView;
|
||||
|
||||
use std::borrow::ToOwned;
|
||||
use std::ptr;
|
||||
use std::slice;
|
||||
|
||||
#[dom_struct]
|
||||
pub struct TextDecoder {
|
||||
reflector_: Reflector,
|
||||
encoding: EncodingRef,
|
||||
fatal: bool,
|
||||
}
|
||||
|
||||
impl TextDecoder {
|
||||
fn new_inherited(encoding: EncodingRef, fatal: bool) -> TextDecoder {
|
||||
TextDecoder {
|
||||
reflector_: Reflector::new(),
|
||||
encoding: encoding,
|
||||
fatal: fatal,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new(global: GlobalRef, encoding: EncodingRef, fatal: bool) -> Temporary<TextDecoder> {
|
||||
reflect_dom_object(box TextDecoder::new_inherited(encoding, fatal),
|
||||
global,
|
||||
TextDecoderBinding::Wrap)
|
||||
}
|
||||
|
||||
/// https://encoding.spec.whatwg.org/#dom-textdecoder
|
||||
pub fn Constructor(global: GlobalRef,
|
||||
label: DOMString,
|
||||
options: &TextDecoderBinding::TextDecoderOptions)
|
||||
-> Fallible<Temporary<TextDecoder>> {
|
||||
let encoding = match encoding_from_whatwg_label(&label) {
|
||||
Some(enc) => enc,
|
||||
// FIXME: Should throw a RangeError as per spec
|
||||
None => return Err(Error::Syntax),
|
||||
};
|
||||
Ok(TextDecoder::new(global, encoding, options.fatal))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> TextDecoderMethods for JSRef<'a, TextDecoder> {
|
||||
fn Encoding(self) -> DOMString {
|
||||
self.encoding.whatwg_name().unwrap().to_owned()
|
||||
}
|
||||
|
||||
fn Fatal(self) -> bool {
|
||||
self.fatal
|
||||
}
|
||||
|
||||
#[allow(unsafe_code)]
|
||||
fn Decode(self, cx: *mut JSContext, input: Option<*mut JSObject>)
|
||||
-> Fallible<USVString> {
|
||||
let input = match input {
|
||||
Some(input) => input,
|
||||
None => return Ok(USVString("".to_owned())),
|
||||
};
|
||||
|
||||
let mut length = 0;
|
||||
let mut data = ptr::null_mut();
|
||||
if unsafe { JS_GetObjectAsArrayBufferView(cx, input, &mut length, &mut data).is_null() } {
|
||||
return Err(Error::Type("Argument to TextDecoder.decode is not an ArrayBufferView".to_owned()));
|
||||
}
|
||||
|
||||
let buffer = unsafe {
|
||||
slice::from_raw_parts(data as *const _, length as usize)
|
||||
};
|
||||
let trap = if self.fatal {
|
||||
DecoderTrap::Strict
|
||||
} else {
|
||||
DecoderTrap::Replace
|
||||
};
|
||||
match self.encoding.decode(buffer, trap) {
|
||||
Ok(s) => Ok(USVString(s)),
|
||||
Err(_) => Err(Error::Type("Decoding failed".to_owned())),
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -136,7 +136,7 @@ interface CanvasDrawingStyles {
|
|||
attribute unrestricted double lineWidth; // (default 1)
|
||||
//attribute DOMString lineCap; // "butt", "round", "square" (default "butt")
|
||||
//attribute DOMString lineJoin; // "round", "bevel", "miter" (default "miter")
|
||||
//attribute unrestricted double miterLimit; // (default 10)
|
||||
attribute unrestricted double miterLimit; // (default 10)
|
||||
|
||||
// dashed lines
|
||||
//void setLineDash(sequence<unrestricted double> segments); // default empty
|
||||
|
|
|
@ -11,11 +11,10 @@
|
|||
*/
|
||||
|
||||
interface CharacterData : Node {
|
||||
[TreatNullAs=EmptyString,SetterThrows] attribute DOMString data;
|
||||
[TreatNullAs=EmptyString] attribute DOMString data;
|
||||
readonly attribute unsigned long length;
|
||||
[Throws]
|
||||
DOMString substringData(unsigned long offset, unsigned long count);
|
||||
[Throws]
|
||||
void appendData(DOMString data);
|
||||
[Throws]
|
||||
void insertData(unsigned long offset, DOMString data);
|
||||
|
@ -26,3 +25,4 @@ interface CharacterData : Node {
|
|||
};
|
||||
|
||||
CharacterData implements ChildNode;
|
||||
CharacterData implements NonDocumentTypeChildNode;
|
||||
|
|
|
@ -16,10 +16,10 @@ interface ChildNode {
|
|||
void remove();
|
||||
};
|
||||
|
||||
// [NoInterfaceObject]
|
||||
// interface NonDocumentTypeChildNode {
|
||||
// [Pure]
|
||||
// readonly attribute Element? previousElementSibling;
|
||||
// [Pure]
|
||||
// readonly attribute Element? nextElementSibling;
|
||||
// };
|
||||
[NoInterfaceObject]
|
||||
interface NonDocumentTypeChildNode {
|
||||
[Pure]
|
||||
readonly attribute Element? previousElementSibling;
|
||||
[Pure]
|
||||
readonly attribute Element? nextElementSibling;
|
||||
};
|
||||
|
|
|
@ -27,27 +27,33 @@ interface Document : Node {
|
|||
HTMLCollection getElementsByClassName(DOMString classNames);
|
||||
Element? getElementById(DOMString elementId);
|
||||
|
||||
[Throws]
|
||||
[NewObject, Throws]
|
||||
Element createElement(DOMString localName);
|
||||
[Throws]
|
||||
[NewObject, Throws]
|
||||
Element createElementNS(DOMString? namespace, DOMString qualifiedName);
|
||||
[NewObject]
|
||||
DocumentFragment createDocumentFragment();
|
||||
[NewObject]
|
||||
Text createTextNode(DOMString data);
|
||||
[NewObject]
|
||||
Comment createComment(DOMString data);
|
||||
[Throws]
|
||||
[NewObject, Throws]
|
||||
ProcessingInstruction createProcessingInstruction(DOMString target, DOMString data);
|
||||
|
||||
[Throws]
|
||||
Attr createAttribute(DOMString localName);
|
||||
|
||||
[Throws]
|
||||
[NewObject, Throws]
|
||||
Node importNode(Node node, optional boolean deep = false);
|
||||
[Throws]
|
||||
Node adoptNode(Node node);
|
||||
|
||||
[Throws]
|
||||
[NewObject, Throws]
|
||||
Attr createAttribute(DOMString localName);
|
||||
[NewObject, Throws]
|
||||
Attr createAttributeNS(DOMString? namespace, DOMString localName);
|
||||
|
||||
[NewObject, Throws]
|
||||
Event createEvent(DOMString interface_);
|
||||
|
||||
[NewObject]
|
||||
Range createRange();
|
||||
|
||||
// NodeFilter.SHOW_ALL = 0xFFFFFFFF
|
||||
|
|
|
@ -70,4 +70,5 @@ partial interface Element {
|
|||
};
|
||||
|
||||
Element implements ChildNode;
|
||||
Element implements NonDocumentTypeChildNode;
|
||||
Element implements ParentNode;
|
||||
|
|
21
components/script/dom/webidls/TextDecoder.webidl
Normal file
21
components/script/dom/webidls/TextDecoder.webidl
Normal file
|
@ -0,0 +1,21 @@
|
|||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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 http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
// https://encoding.spec.whatwg.org/#interface-textdecoder
|
||||
dictionary TextDecoderOptions {
|
||||
boolean fatal = false;
|
||||
//boolean ignoreBOM = false;
|
||||
};
|
||||
|
||||
[Constructor(optional DOMString label = "utf-8", optional TextDecoderOptions options)/*,
|
||||
Exposed=Window,Worker*/]
|
||||
interface TextDecoder {
|
||||
readonly attribute DOMString encoding;
|
||||
readonly attribute boolean fatal;
|
||||
//readonly attribute boolean ignoreBOM;
|
||||
//USVString decode(optional BufferSource input, optional TextDecodeOptions options);
|
||||
[Throws]
|
||||
USVString decode(optional object input);
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue