Make LayoutNodeHelpers::text_content return a cow

This commit is contained in:
Anthony Ramine 2020-03-31 14:58:56 +02:00
parent 409bd3d989
commit 6fe294fa5b
7 changed files with 32 additions and 19 deletions

View file

@ -130,7 +130,7 @@ where
});
}
TextContent::Text(self.node_text_content().into_boxed_str())
TextContent::Text(self.node_text_content().into_owned().into_boxed_str())
}
fn restyle_damage(self) -> RestyleDamage {

View file

@ -17,6 +17,7 @@ use script_layout_interface::wrapper_traits::{
};
use script_layout_interface::HTMLCanvasDataSource;
use servo_arc::Arc as ServoArc;
use std::borrow::Cow;
use std::marker::PhantomData as marker;
use std::sync::{Arc, Mutex};
use style::dom::{OpaqueNode, TNode};
@ -59,7 +60,12 @@ pub(super) trait TraversalHandler<'dom, Node>
where
Node: 'dom,
{
fn handle_text(&mut self, node: Node, text: String, parent_style: &ServoArc<ComputedValues>);
fn handle_text(
&mut self,
node: Node,
text: Cow<'dom, str>,
parent_style: &ServoArc<ComputedValues>,
);
/// Or pseudo-element
fn handle_element(
@ -166,7 +172,7 @@ fn traverse_pseudo_element_contents<'dom, Node>(
for item in items {
match item {
PseudoElementContentItem::Text(text) => {
handler.handle_text(node, text, pseudo_element_style)
handler.handle_text(node, text.into(), pseudo_element_style)
},
PseudoElementContentItem::Replaced(contents) => {
let item_style = anonymous_style.get_or_insert_with(|| {
@ -351,7 +357,7 @@ impl Drop for BoxSlot<'_> {
pub(crate) trait NodeExt<'dom>: 'dom + Copy + LayoutNode<'dom> + Send + Sync {
fn is_element(self) -> bool;
fn as_text(self) -> Option<String>;
fn as_text(self) -> Option<Cow<'dom, str>>;
/// Returns the image if its loaded, and its size in image pixels
/// adjusted for `image_density`.
@ -378,7 +384,7 @@ where
self.to_threadsafe().as_element().is_some()
}
fn as_text(self) -> Option<String> {
fn as_text(self) -> Option<Cow<'dom, str>> {
if self.is_text_node() {
Some(self.to_threadsafe().node_text_content())
} else {

View file

@ -16,6 +16,7 @@ use crate::style_ext::{ComputedValuesExt, DisplayGeneratingBox, DisplayInside, D
use rayon::iter::{IntoParallelIterator, ParallelIterator};
use rayon_croissant::ParallelIteratorExt;
use servo_arc::Arc;
use std::borrow::Cow;
use std::convert::{TryFrom, TryInto};
use style::properties::ComputedValues;
use style::selector_parser::PseudoElement;
@ -286,7 +287,12 @@ where
}
}
fn handle_text(&mut self, node: Node, input: String, parent_style: &Arc<ComputedValues>) {
fn handle_text(
&mut self,
node: Node,
input: Cow<'dom, str>,
parent_style: &Arc<ComputedValues>,
) {
let (leading_whitespace, mut input) = self.handle_leading_whitespace(&input);
if leading_whitespace || !input.is_empty() {
// This text node should be pushed either to the next ongoing

View file

@ -67,6 +67,7 @@ use selectors::sink::Push;
use servo_arc::{Arc, ArcBorrow};
use servo_atoms::Atom;
use servo_url::ServoUrl;
use std::borrow::Cow;
use std::fmt;
use std::fmt::Debug;
use std::hash::{Hash, Hasher};
@ -1110,9 +1111,8 @@ impl<'ln> ThreadSafeLayoutNode<'ln> for ServoThreadSafeLayoutNode<'ln> {
self.node
}
fn node_text_content(&self) -> String {
let this = unsafe { self.get_jsmanaged() };
return this.text_content();
fn node_text_content(self) -> Cow<'ln, str> {
unsafe { self.get_jsmanaged().text_content() }
}
fn selection(&self) -> Option<Range<ByteIndex>> {

View file

@ -67,6 +67,7 @@ use selectors::sink::Push;
use servo_arc::{Arc, ArcBorrow};
use servo_atoms::Atom;
use servo_url::ServoUrl;
use std::borrow::Cow;
use std::fmt;
use std::fmt::Debug;
use std::hash::{Hash, Hasher};
@ -1117,9 +1118,8 @@ impl<'ln> ThreadSafeLayoutNode<'ln> for ServoThreadSafeLayoutNode<'ln> {
self.node
}
fn node_text_content(&self) -> String {
let this = unsafe { self.get_jsmanaged() };
return this.text_content();
fn node_text_content(self) -> Cow<'ln, str> {
unsafe { self.get_jsmanaged().text_content() }
}
fn selection(&self) -> Option<Range<ByteIndex>> {

View file

@ -87,7 +87,7 @@ use servo_arc::Arc;
use servo_atoms::Atom;
use servo_url::ServoUrl;
use smallvec::SmallVec;
use std::borrow::ToOwned;
use std::borrow::Cow;
use std::cell::{Cell, UnsafeCell};
use std::cmp;
use std::default::Default;
@ -1326,7 +1326,7 @@ pub trait LayoutNodeHelpers<'dom> {
unsafe fn init_style_and_layout_data(self, _: OpaqueStyleAndLayoutData);
unsafe fn take_style_and_layout_data(self) -> OpaqueStyleAndLayoutData;
fn text_content(self) -> String;
fn text_content(self) -> Cow<'dom, str>;
fn selection(self) -> Option<Range<usize>>;
fn image_url(self) -> Option<ServoUrl>;
fn image_density(self) -> Option<f64>;
@ -1456,17 +1456,17 @@ impl<'dom> LayoutNodeHelpers<'dom> for LayoutDom<'dom, Node> {
val
}
fn text_content(self) -> String {
fn text_content(self) -> Cow<'dom, str> {
if let Some(text) = self.downcast::<Text>() {
return text.upcast().data_for_layout().to_owned();
return text.upcast().data_for_layout().into();
}
if let Some(input) = self.downcast::<HTMLInputElement>() {
return input.value_for_layout().into_owned();
return input.value_for_layout();
}
if let Some(area) = self.downcast::<HTMLTextAreaElement>() {
return area.value_for_layout();
return area.value_for_layout().into();
}
panic!("not text!")

View file

@ -17,6 +17,7 @@ use net_traits::image::base::{Image, ImageMetadata};
use range::Range;
use servo_arc::Arc;
use servo_url::ServoUrl;
use std::borrow::Cow;
use std::fmt::Debug;
use std::sync::Arc as StdArc;
use style::attr::AttrValue;
@ -262,7 +263,7 @@ pub trait ThreadSafeLayoutNode<'dom>:
/// data flags, and we have this annoying trait separation between script and layout :-(
unsafe fn unsafe_get(self) -> Self::ConcreteNode;
fn node_text_content(&self) -> String;
fn node_text_content(self) -> Cow<'dom, str>;
/// If the insertion point is within this node, returns it. Otherwise, returns `None`.
fn selection(&self) -> Option<Range<ByteIndex>>;