use std::{
cell::RefCell,
collections::HashMap,
mem::replace,
ops::{Deref, DerefMut},
rc::{Rc, Weak},
sync::Arc,
};
use crate::{chvalid::XmlCharValid, dom::node::NodeStrongRef};
use super::{
DOMException, NodeType, check_no_modification_allowed_err,
document::{Document, DocumentRef},
node::{Node, NodeConnection, NodeRef, NodeWeakRef},
user_data::{DOMUserData, OperationType, UserDataHandler},
};
pub trait CharacterData: Node {
fn data(&self) -> String;
fn set_data(&mut self, data: impl Into<String>) -> Result<(), DOMException>;
fn length(&self) -> usize {
self.data().len()
}
fn substring_data(&self, offset: usize, count: usize) -> Result<String, DOMException> {
let data = self.data();
let end = data.len().min(offset + count);
if !data.is_char_boundary(offset) || !data.is_char_boundary(end) {
return Err(DOMException::IndexSizeErr);
}
Ok(data[offset..end].to_owned())
}
fn append_data(&mut self, arg: &str) -> Result<(), DOMException> {
check_no_modification_allowed_err(self)?;
let mut data = self.data();
data.push_str(arg);
self.set_data(data)
}
fn insert_data(&mut self, offset: usize, arg: &str) -> Result<(), DOMException> {
check_no_modification_allowed_err(self)?;
let mut data = self.data();
if !data.is_char_boundary(offset) {
return Err(DOMException::IndexSizeErr);
}
data.insert_str(offset, arg);
self.set_data(data)
}
fn delete_data(&mut self, offset: usize, count: usize) -> Result<(), DOMException> {
check_no_modification_allowed_err(self)?;
let mut data = self.data();
let end = data.len().min(offset + count);
if !data.is_char_boundary(offset) || !data.is_char_boundary(end) {
return Err(DOMException::IndexSizeErr);
}
data.drain(offset..end);
self.set_data(data)
}
fn replace_data(&mut self, offset: usize, count: usize, arg: &str) -> Result<(), DOMException> {
check_no_modification_allowed_err(self)?;
let mut data = self.data();
let end = data.len().min(offset + count);
if !data.is_char_boundary(offset) || !data.is_char_boundary(end) {
return Err(DOMException::IndexSizeErr);
}
data.replace_range(offset..end, arg);
self.set_data(data)
}
}
pub struct Text {
parent_node: Option<NodeWeakRef>,
previous_sibling: Option<NodeWeakRef>,
next_sibling: Option<NodeStrongRef>,
owner_document: Weak<RefCell<Document>>,
data: String,
user_data: Option<HashMap<String, (DOMUserData, Option<Arc<dyn UserDataHandler>>)>>,
flag: u16,
}
impl Text {
pub fn owner_document(&self) -> Option<DocumentRef> {
self.owner_document.upgrade().map(From::from)
}
fn adopted_to(&mut self, new_doc: DocumentRef) {
self.owner_document = Rc::downgrade(&new_doc.0);
}
}
#[derive(Clone)]
pub struct TextRef(pub(super) Rc<RefCell<Text>>, pub(super) DocumentRef);
impl TextRef {
pub fn split_text(&mut self, offset: usize) -> Result<TextRef, DOMException> {
check_no_modification_allowed_err(self)?;
if !self.0.borrow().data.is_char_boundary(offset) {
return Err(DOMException::IndexSizeErr);
}
let back = self.0.borrow_mut().data.split_off(offset);
let res = Self::from_doc(self.owner_document().expect("Internal Error"), back);
if let Some(mut parent) = self.parent_node() {
parent
.insert_before(res.clone().into(), self.next_sibling())
.ok();
}
Ok(res)
}
pub fn replace_whole_text(&mut self, content: &str) -> Result<Option<TextRef>, DOMException> {
fn has_text_only_children(node: Option<NodeRef>) -> bool {
let Some(child) = node else {
return false;
};
let mut child = child.first_child();
while let Some(ch) = child {
match ch.node_type() {
NodeType::EntityReference => {
if !has_text_only_children(Some(ch.clone())) {
return false;
}
}
NodeType::CDATASection | NodeType::Text => {}
_ => return false,
}
child = ch.next_sibling();
}
true
}
fn can_modify_prev(node: NodeRef) -> bool {
let mut text_last_child = false;
let mut prev = node.previous_sibling();
while let Some(pre) = prev {
match pre.node_type() {
NodeType::EntityReference => {
let mut last_child = pre.last_child();
if last_child.is_none() {
return false;
}
while let Some(child) = last_child {
match child.node_type() {
NodeType::CDATASection | NodeType::Text => {
text_last_child = true;
}
NodeType::EntityReference => {
if !can_modify_prev(child.clone()) {
return false;
}
text_last_child = true;
}
_ => return !text_last_child,
}
last_child = child.previous_sibling();
}
}
NodeType::CDATASection | NodeType::Text => {}
_ => return true,
}
prev = pre.previous_sibling();
}
true
}
fn can_modify_next(node: NodeRef) -> bool {
let mut text_first_child = false;
let mut next = node.next_sibling();
while let Some(nxt) = next {
match nxt.node_type() {
NodeType::EntityReference => {
let mut first_child = nxt.first_child();
if first_child.is_none() {
return false;
}
while let Some(child) = first_child {
match child.node_type() {
NodeType::CDATASection | NodeType::Text => {
text_first_child = true;
}
NodeType::EntityReference => {
if !can_modify_next(child.clone()) {
return false;
}
text_first_child = true;
}
_ => return !text_first_child,
}
first_child = child.next_sibling();
}
}
NodeType::CDATASection | NodeType::Text => {}
_ => return true,
}
next = nxt.next_sibling();
}
true
}
let parent = self.parent_node();
if content.is_empty() {
if let Some(mut parent) = parent {
parent.remove_child(self.clone().into())?;
}
return Ok(None);
}
if !can_modify_prev(self.clone().into()) || !can_modify_next(self.clone().into()) {
return Err(DOMException::NoModificationAllowedErr);
}
self.set_data(content)?;
let mut prev = self.previous_sibling();
while let Some(mut pre) = prev {
match pre.node_type() {
NodeType::CDATASection | NodeType::Text => {
pre.disconnect_parent_and_sibling();
prev = self.previous_sibling();
}
NodeType::EntityReference if has_text_only_children(Some(pre.clone())) => {
pre.disconnect_parent_and_sibling();
prev = self.previous_sibling();
}
_ => break,
}
}
let mut next = self.next_sibling();
while let Some(mut nxt) = next {
match nxt.node_type() {
NodeType::CDATASection | NodeType::Text => {
nxt.disconnect_parent_and_sibling();
next = self.next_sibling();
}
NodeType::EntityReference if has_text_only_children(Some(nxt.clone())) => {
nxt.disconnect_parent_and_sibling();
next = self.next_sibling();
}
_ => break,
}
}
Ok(Some(self.clone()))
}
pub fn is_element_content_whitespace(&self) -> bool {
self.0.borrow().data.chars().all(|c| c.is_xml_blank_char())
}
pub fn whole_text(&self) -> String {
fn whole_text_forward(
mut node: Option<NodeRef>,
buf: &mut String,
parent: Option<NodeRef>,
) -> bool {
while let Some(cur) = node {
match &cur {
NodeRef::EntityReference(entref) => {
if whole_text_forward(entref.first_child(), buf, Some(cur.clone())) {
return true;
}
}
NodeRef::CDATASection(cdata) => {
buf.push_str(&cdata.0.borrow().data);
}
NodeRef::Text(text) => {
buf.push_str(&text.0.borrow().data);
}
_ => return true,
}
node = cur.next_sibling();
}
if let Some(parent) = parent.filter(|par| par.node_type() == NodeType::EntityReference)
{
whole_text_forward(parent.next_sibling(), buf, parent.parent_node());
return true;
}
false
}
fn whole_text_backward(
mut node: Option<NodeRef>,
buf: &mut String,
parent: Option<NodeRef>,
) -> bool {
while let Some(cur) = node {
match &cur {
NodeRef::EntityReference(entref) => {
if whole_text_backward(entref.last_child(), buf, Some(cur.clone())) {
return true;
}
}
NodeRef::CDATASection(cdata) => {
buf.insert_str(0, &cdata.0.borrow().data);
}
NodeRef::Text(text) => {
buf.insert_str(0, &text.0.borrow().data);
}
_ => return true,
}
node = cur.previous_sibling();
}
if let Some(parent) = parent.filter(|par| par.node_type() == NodeType::EntityReference)
{
whole_text_backward(parent.previous_sibling(), buf, parent.parent_node());
return true;
}
false
}
let mut buf = self.0.borrow().data.clone();
whole_text_backward(self.previous_sibling(), &mut buf, self.parent_node());
whole_text_forward(self.next_sibling(), &mut buf, self.parent_node());
buf
}
pub(super) fn from_doc(doc: DocumentRef, data: String) -> Self {
Self(
Rc::new(RefCell::new(Text {
parent_node: None,
previous_sibling: None,
next_sibling: None,
owner_document: Rc::downgrade(&doc.0),
data,
user_data: None,
flag: 0,
})),
doc,
)
}
}
impl Node for TextRef {
fn node_name(&self) -> Rc<str> {
"#text".into()
}
fn node_value(&self) -> Option<Rc<str>> {
Some(self.0.borrow().data.as_str().into())
}
fn set_node_value(&mut self, value: impl Into<String>) -> Result<(), DOMException> {
self.set_data(value)?;
Ok(())
}
fn node_type(&self) -> NodeType {
NodeType::Text
}
fn parent_node(&self) -> Option<NodeRef> {
self.0
.borrow()
.parent_node
.as_ref()
.and_then(|par| par.upgrade())
}
fn previous_sibling(&self) -> Option<NodeRef> {
self.0
.borrow()
.previous_sibling
.as_ref()
.and_then(|prev| prev.upgrade())
}
fn next_sibling(&self) -> Option<NodeRef> {
self.0.borrow().next_sibling.clone().map(From::from)
}
fn owner_document(&self) -> Option<DocumentRef> {
Some(self.1.clone())
}
fn clone_node(&self, _deep: bool) -> NodeRef {
let text = TextRef(
Rc::new(RefCell::new(Text {
parent_node: None,
previous_sibling: None,
next_sibling: None,
owner_document: self.0.borrow().owner_document.clone(),
data: self.0.borrow().data.clone(),
user_data: None,
flag: 0,
})),
self.1.clone(),
);
self.handle_user_data(OperationType::NodeCloned, Some(text.clone().into()));
text.into()
}
fn text_content(&self) -> Option<String> {
self.node_value().map(|value| value.to_string())
}
fn set_text_content(&mut self, text: impl Into<String>) -> Result<(), DOMException> {
self.0.borrow_mut().data = text.into();
Ok(())
}
fn is_same_node(&self, other: &NodeRef) -> bool {
let NodeRef::Text(other) = other else {
return false;
};
Rc::ptr_eq(&self.0, &other.0)
}
fn set_user_data(
&mut self,
key: impl Into<String>,
data: DOMUserData,
handler: Option<Arc<dyn UserDataHandler>>,
) -> Option<DOMUserData> {
self.0
.borrow_mut()
.user_data
.get_or_insert_default()
.insert(key.into(), (data, handler))
.map(|v| v.0)
}
fn get_user_data(&self, key: &str) -> Option<DOMUserData> {
self.0
.borrow()
.user_data
.as_ref()
.and_then(|user_data| user_data.get(key))
.map(|v| v.0.clone())
}
fn is_read_only(&self) -> bool {
self.0.borrow().flag & 1 != 0
}
}
impl CharacterData for TextRef {
fn data(&self) -> String {
self.0.borrow().data.clone()
}
fn set_data(&mut self, data: impl Into<String>) -> Result<(), DOMException> {
check_no_modification_allowed_err(self)?;
self.0.borrow_mut().data = data.into();
Ok(())
}
}
impl NodeConnection for TextRef {
fn set_parent_node(&mut self, new_parent: Option<NodeRef>) -> Option<NodeRef> {
replace(
&mut self.0.borrow_mut().parent_node,
new_parent.map(|par| par.downgrade()),
)
.and_then(|old| old.upgrade())
}
fn set_first_child(&mut self, _: Option<NodeRef>) -> Option<NodeRef> {
None
}
fn set_last_child(&mut self, _: Option<NodeRef>) -> Option<NodeRef> {
None
}
fn set_previous_sibling(&mut self, new_sibling: Option<NodeRef>) -> Option<NodeRef> {
replace(
&mut self.0.borrow_mut().previous_sibling,
new_sibling.map(|sib| sib.downgrade()),
)
.and_then(|old| old.upgrade())
}
fn set_next_sibling(&mut self, new_sibling: Option<NodeRef>) -> Option<NodeRef> {
replace(
&mut self.0.borrow_mut().next_sibling,
new_sibling.map(From::from),
)
.map(From::from)
}
fn set_owner_document(&mut self, new_doc: DocumentRef) -> Option<DocumentRef> {
self.0.borrow_mut().owner_document = Rc::downgrade(&new_doc.0);
Some(replace(&mut self.1, new_doc))
}
fn set_read_only(&mut self) {
self.0.borrow_mut().flag |= 0b01;
}
fn unset_read_only(&mut self) {
self.0.borrow_mut().flag &= !0b01;
}
fn adopted_to(&mut self, new_doc: DocumentRef) {
self.0.borrow_mut().adopted_to(new_doc);
if let Some(user_data) = self.0.borrow().user_data.as_ref() {
for (key, value) in user_data.iter() {
if let Some(handler) = value.1.clone() {
handler.handle(
OperationType::NodeAdopted,
key.as_str(),
value.0.clone(),
self.clone().into(),
None,
);
}
}
}
}
fn handle_user_data(&self, operation: OperationType, dst: Option<NodeRef>) {
if let Some(user_data) = self.0.borrow().user_data.as_ref() {
for (key, value) in user_data.iter() {
if let Some(handler) = value.1.clone() {
handler.handle(
operation,
key.as_str(),
value.0.clone(),
self.clone().into(),
dst.clone(),
);
}
}
}
}
}
impl From<TextRef> for NodeRef {
fn from(value: TextRef) -> Self {
NodeRef::Text(value)
}
}
impl From<Rc<RefCell<Text>>> for TextRef {
fn from(value: Rc<RefCell<Text>>) -> Self {
let doc = value.borrow().owner_document().unwrap();
Self(value, doc)
}
}
pub struct Comment {
parent_node: Option<NodeWeakRef>,
previous_sibling: Option<NodeWeakRef>,
next_sibling: Option<NodeStrongRef>,
owner_document: Weak<RefCell<Document>>,
data: String,
user_data: Option<HashMap<String, (DOMUserData, Option<Arc<dyn UserDataHandler>>)>>,
flag: u16,
}
impl Comment {
pub fn owner_document(&self) -> Option<DocumentRef> {
self.owner_document.upgrade().map(From::from)
}
fn adopted_to(&mut self, new_doc: DocumentRef) {
self.owner_document = Rc::downgrade(&new_doc.0);
}
}
#[derive(Clone)]
pub struct CommentRef(pub(super) Rc<RefCell<Comment>>, pub(super) DocumentRef);
impl CommentRef {
pub(super) fn from_doc(doc: DocumentRef, data: String) -> Self {
Self(
Rc::new(RefCell::new(Comment {
parent_node: None,
previous_sibling: None,
next_sibling: None,
owner_document: Rc::downgrade(&doc.0),
data,
user_data: None,
flag: 0,
})),
doc,
)
}
}
impl Node for CommentRef {
fn node_name(&self) -> Rc<str> {
"#comment".into()
}
fn node_value(&self) -> Option<Rc<str>> {
Some(self.0.borrow().data.as_str().into())
}
fn set_node_value(&mut self, value: impl Into<String>) -> Result<(), DOMException> {
self.set_data(value)?;
Ok(())
}
fn node_type(&self) -> NodeType {
NodeType::Comment
}
fn parent_node(&self) -> Option<NodeRef> {
self.0
.borrow()
.parent_node
.as_ref()
.and_then(|par| par.upgrade())
}
fn previous_sibling(&self) -> Option<NodeRef> {
self.0
.borrow()
.previous_sibling
.as_ref()
.and_then(|prev| prev.upgrade())
}
fn next_sibling(&self) -> Option<NodeRef> {
self.0.borrow().next_sibling.clone().map(From::from)
}
fn owner_document(&self) -> Option<DocumentRef> {
Some(self.1.clone())
}
fn clone_node(&self, _deep: bool) -> NodeRef {
let text = CommentRef(
Rc::new(RefCell::new(Comment {
parent_node: None,
previous_sibling: None,
next_sibling: None,
owner_document: self.0.borrow().owner_document.clone(),
data: self.0.borrow().data.clone(),
user_data: None,
flag: 0,
})),
self.1.clone(),
);
self.handle_user_data(OperationType::NodeCloned, Some(text.clone().into()));
text.into()
}
fn text_content(&self) -> Option<String> {
self.node_value().map(|value| value.to_string())
}
fn set_text_content(&mut self, text: impl Into<String>) -> Result<(), DOMException> {
self.0.borrow_mut().data = text.into();
Ok(())
}
fn is_same_node(&self, other: &NodeRef) -> bool {
let NodeRef::Comment(other) = other else {
return false;
};
Rc::ptr_eq(&self.0, &other.0)
}
fn set_user_data(
&mut self,
key: impl Into<String>,
data: DOMUserData,
handler: Option<Arc<dyn UserDataHandler>>,
) -> Option<DOMUserData> {
self.0
.borrow_mut()
.user_data
.get_or_insert_default()
.insert(key.into(), (data, handler))
.map(|v| v.0)
}
fn get_user_data(&self, key: &str) -> Option<DOMUserData> {
self.0
.borrow()
.user_data
.as_ref()
.and_then(|user_data| user_data.get(key))
.map(|v| v.0.clone())
}
fn is_read_only(&self) -> bool {
self.0.borrow().flag & 1 != 0
}
}
impl NodeConnection for CommentRef {
fn set_parent_node(&mut self, new_parent: Option<NodeRef>) -> Option<NodeRef> {
replace(
&mut self.0.borrow_mut().parent_node,
new_parent.map(|par| par.downgrade()),
)
.and_then(|old| old.upgrade())
}
fn set_first_child(&mut self, _: Option<NodeRef>) -> Option<NodeRef> {
None
}
fn set_last_child(&mut self, _: Option<NodeRef>) -> Option<NodeRef> {
None
}
fn set_previous_sibling(&mut self, new_sibling: Option<NodeRef>) -> Option<NodeRef> {
replace(
&mut self.0.borrow_mut().previous_sibling,
new_sibling.map(|sib| sib.downgrade()),
)
.and_then(|old| old.upgrade())
}
fn set_next_sibling(&mut self, new_sibling: Option<NodeRef>) -> Option<NodeRef> {
replace(
&mut self.0.borrow_mut().next_sibling,
new_sibling.map(From::from),
)
.map(From::from)
}
fn set_owner_document(&mut self, new_doc: DocumentRef) -> Option<DocumentRef> {
self.0.borrow_mut().owner_document = Rc::downgrade(&new_doc.0);
Some(replace(&mut self.1, new_doc))
}
fn set_read_only(&mut self) {
self.0.borrow_mut().flag |= 0b01;
}
fn unset_read_only(&mut self) {
self.0.borrow_mut().flag &= !0b01;
}
fn adopted_to(&mut self, new_doc: DocumentRef) {
self.0.borrow_mut().adopted_to(new_doc);
if let Some(user_data) = self.0.borrow().user_data.as_ref() {
for (key, value) in user_data.iter() {
if let Some(handler) = value.1.clone() {
handler.handle(
OperationType::NodeAdopted,
key.as_str(),
value.0.clone(),
self.clone().into(),
None,
);
}
}
}
}
fn handle_user_data(&self, operation: OperationType, dst: Option<NodeRef>) {
if let Some(user_data) = self.0.borrow().user_data.as_ref() {
for (key, value) in user_data.iter() {
if let Some(handler) = value.1.clone() {
handler.handle(
operation,
key.as_str(),
value.0.clone(),
self.clone().into(),
dst.clone(),
);
}
}
}
}
}
impl CharacterData for CommentRef {
fn data(&self) -> String {
self.0.borrow().data.clone()
}
fn set_data(&mut self, data: impl Into<String>) -> Result<(), DOMException> {
check_no_modification_allowed_err(self)?;
self.0.borrow_mut().data = data.into();
Ok(())
}
}
impl From<CommentRef> for NodeRef {
fn from(value: CommentRef) -> Self {
NodeRef::Comment(value)
}
}
impl From<Rc<RefCell<Comment>>> for CommentRef {
fn from(value: Rc<RefCell<Comment>>) -> Self {
let doc = value.borrow().owner_document().unwrap();
Self(value, doc)
}
}
pub struct CDATASection(Text);
impl Deref for CDATASection {
type Target = Text;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl DerefMut for CDATASection {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
#[derive(Clone)]
pub struct CDATASectionRef(pub(super) Rc<RefCell<CDATASection>>, pub(super) DocumentRef);
impl CDATASectionRef {
pub(super) fn from_doc(doc: DocumentRef, data: String) -> Self {
Self(
Rc::new(RefCell::new(CDATASection(Text {
parent_node: None,
previous_sibling: None,
next_sibling: None,
owner_document: Rc::downgrade(&doc.0),
data,
user_data: None,
flag: 0,
}))),
doc,
)
}
}
impl Node for CDATASectionRef {
fn node_name(&self) -> Rc<str> {
"#cdata-section".into()
}
fn node_value(&self) -> Option<Rc<str>> {
Some(self.0.borrow().data.as_str().into())
}
fn set_node_value(&mut self, value: impl Into<String>) -> Result<(), DOMException> {
self.set_data(value)?;
Ok(())
}
fn node_type(&self) -> NodeType {
NodeType::CDATASection
}
fn parent_node(&self) -> Option<NodeRef> {
self.0
.borrow()
.parent_node
.as_ref()
.and_then(|par| par.upgrade())
}
fn previous_sibling(&self) -> Option<NodeRef> {
self.0
.borrow()
.previous_sibling
.as_ref()
.and_then(|prev| prev.upgrade())
}
fn next_sibling(&self) -> Option<NodeRef> {
self.0.borrow().next_sibling.clone().map(From::from)
}
fn owner_document(&self) -> Option<DocumentRef> {
Some(self.1.clone())
}
fn clone_node(&self, _deep: bool) -> NodeRef {
let text = CDATASectionRef(
Rc::new(RefCell::new(CDATASection(Text {
parent_node: None,
previous_sibling: None,
next_sibling: None,
owner_document: self.0.borrow().owner_document.clone(),
data: self.0.borrow().data.clone(),
user_data: None,
flag: 0,
}))),
self.1.clone(),
);
self.handle_user_data(OperationType::NodeCloned, Some(text.clone().into()));
text.into()
}
fn text_content(&self) -> Option<String> {
self.node_value().map(|value| value.to_string())
}
fn set_text_content(&mut self, text: impl Into<String>) -> Result<(), DOMException> {
self.0.borrow_mut().data = text.into();
Ok(())
}
fn is_same_node(&self, other: &NodeRef) -> bool {
let NodeRef::CDATASection(other) = other else {
return false;
};
Rc::ptr_eq(&self.0, &other.0)
}
fn set_user_data(
&mut self,
key: impl Into<String>,
data: DOMUserData,
handler: Option<Arc<dyn UserDataHandler>>,
) -> Option<DOMUserData> {
self.0
.borrow_mut()
.user_data
.get_or_insert_default()
.insert(key.into(), (data, handler))
.map(|v| v.0)
}
fn get_user_data(&self, key: &str) -> Option<DOMUserData> {
self.0
.borrow()
.user_data
.as_ref()
.and_then(|user_data| user_data.get(key))
.map(|v| v.0.clone())
}
fn is_read_only(&self) -> bool {
self.0.borrow().0.flag & 1 != 0
}
}
impl NodeConnection for CDATASectionRef {
fn set_parent_node(&mut self, new_parent: Option<NodeRef>) -> Option<NodeRef> {
replace(
&mut self.0.borrow_mut().parent_node,
new_parent.map(|par| par.downgrade()),
)
.and_then(|old| old.upgrade())
}
fn set_first_child(&mut self, _: Option<NodeRef>) -> Option<NodeRef> {
None
}
fn set_last_child(&mut self, _: Option<NodeRef>) -> Option<NodeRef> {
None
}
fn set_previous_sibling(&mut self, new_sibling: Option<NodeRef>) -> Option<NodeRef> {
replace(
&mut self.0.borrow_mut().previous_sibling,
new_sibling.map(|sib| sib.downgrade()),
)
.and_then(|old| old.upgrade())
}
fn set_next_sibling(&mut self, new_sibling: Option<NodeRef>) -> Option<NodeRef> {
replace(
&mut self.0.borrow_mut().next_sibling,
new_sibling.map(From::from),
)
.map(From::from)
}
fn set_owner_document(&mut self, new_doc: DocumentRef) -> Option<DocumentRef> {
self.0.borrow_mut().owner_document = Rc::downgrade(&new_doc.0);
Some(replace(&mut self.1, new_doc))
}
fn set_read_only(&mut self) {
self.0.borrow_mut().0.flag |= 0b01;
}
fn unset_read_only(&mut self) {
self.0.borrow_mut().0.flag &= !0b01;
}
fn adopted_to(&mut self, new_doc: DocumentRef) {
self.0.borrow_mut().adopted_to(new_doc);
if let Some(user_data) = self.0.borrow().user_data.as_ref() {
for (key, value) in user_data.iter() {
if let Some(handler) = value.1.clone() {
handler.handle(
OperationType::NodeAdopted,
key.as_str(),
value.0.clone(),
self.clone().into(),
None,
);
}
}
}
}
fn handle_user_data(&self, operation: OperationType, dst: Option<NodeRef>) {
if let Some(user_data) = self.0.borrow().user_data.as_ref() {
for (key, value) in user_data.iter() {
if let Some(handler) = value.1.clone() {
handler.handle(
operation,
key.as_str(),
value.0.clone(),
self.clone().into(),
dst.clone(),
);
}
}
}
}
}
impl CharacterData for CDATASectionRef {
fn data(&self) -> String {
self.0.borrow().data.clone()
}
fn set_data(&mut self, data: impl Into<String>) -> Result<(), DOMException> {
check_no_modification_allowed_err(self)?;
self.0.borrow_mut().data = data.into();
Ok(())
}
}
impl From<CDATASectionRef> for NodeRef {
fn from(value: CDATASectionRef) -> Self {
NodeRef::CDATASection(value)
}
}
impl From<Rc<RefCell<CDATASection>>> for CDATASectionRef {
fn from(value: Rc<RefCell<CDATASection>>) -> Self {
let doc = value.borrow().owner_document().unwrap();
Self(value, doc)
}
}