Skip to content

Commit

Permalink
refactor!: Rename Role::InlineTextBox to TextRun (#473)
Browse files Browse the repository at this point in the history
  • Loading branch information
mwcampbell authored Oct 26, 2024
1 parent ef3b003 commit 29fa341
Show file tree
Hide file tree
Showing 9 changed files with 49 additions and 59 deletions.
16 changes: 8 additions & 8 deletions common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ pub use geometry::{Affine, Point, Rect, Size, Vec2};
pub enum Role {
#[default]
Unknown,
InlineTextBox,
TextRun,
Cell,
Label,
Image,
Expand Down Expand Up @@ -665,7 +665,7 @@ pub struct CustomAction {
#[cfg_attr(feature = "serde", serde(deny_unknown_fields))]
#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
pub struct TextPosition {
/// The node's role must be [`Role::InlineTextBox`].
/// The node's role must be [`Role::TextRun`].
pub node: NodeId,
/// The index of an item in [`Node::character_lengths`], or the length
/// of that slice if the position is at the end of the line.
Expand Down Expand Up @@ -1438,7 +1438,7 @@ flag_methods! {
/// is in touch exploration mode, e.g. a virtual keyboard normally
/// behaves this way.
(TouchTransparent, is_touch_transparent, set_touch_transparent, clear_touch_transparent),
/// Use for a textbox that allows focus/selection but not input.
/// Use for a text widget that allows focus/selection but not input.
(ReadOnly, is_read_only, set_read_only, clear_read_only),
/// Use for a control or group of controls that disallows input.
(Disabled, is_disabled, set_disabled, clear_disabled),
Expand Down Expand Up @@ -1629,7 +1629,7 @@ text_decoration_property_methods! {
}

length_slice_property_methods! {
/// For inline text. The length (non-inclusive) of each character
/// For text runs, the length (non-inclusive) of each character
/// in UTF-8 code units (bytes). The sum of these lengths must equal
/// the length of [`value`], also in bytes.
///
Expand All @@ -1639,7 +1639,7 @@ length_slice_property_methods! {
/// the lengths of the characters from the text itself; this information
/// must be provided by the text editing implementation.
///
/// If this node is the last text box in a line that ends with a hard
/// If this node is the last text run in a line that ends with a hard
/// line break, that line break should be included at the end of this
/// node's value as either a CRLF or LF; in both cases, the line break
/// should be counted as a single character for the sake of this slice.
Expand All @@ -1649,7 +1649,7 @@ length_slice_property_methods! {
/// [`value`]: Node::value
(CharacterLengths, character_lengths, set_character_lengths, clear_character_lengths),

/// For inline text. The length of each word in characters, as defined
/// For text runs, the length of each word in characters, as defined
/// in [`character_lengths`]. The sum of these lengths must equal
/// the length of [`character_lengths`].
///
Expand All @@ -1675,7 +1675,7 @@ length_slice_property_methods! {
}

coord_slice_property_methods! {
/// For inline text. This is the position of each character within
/// For text runs, this is the position of each character within
/// the node's bounding box, in the direction given by
/// [`text_direction`], in the coordinate space of this node.
///
Expand All @@ -1693,7 +1693,7 @@ coord_slice_property_methods! {
/// [`character_lengths`]: Node::character_lengths
(CharacterPositions, character_positions, set_character_positions, clear_character_positions),

/// For inline text. This is the advance width of each character,
/// For text runs, this is the advance width of each character,
/// in the direction given by [`text_direction`], in the coordinate
/// space of this node.
///
Expand Down
2 changes: 1 addition & 1 deletion consumer/src/filters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ pub fn common_filter(node: &Node) -> FilterResult {
}

let role = node.role();
if role == Role::GenericContainer || role == Role::InlineTextBox {
if role == Role::GenericContainer || role == Role::TextRun {
return FilterResult::ExcludeNode;
}

Expand Down
78 changes: 34 additions & 44 deletions consumer/src/text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ pub(crate) struct InnerPosition<'a> {
impl<'a> InnerPosition<'a> {
fn upgrade(tree_state: &'a TreeState, weak: WeakPosition) -> Option<Self> {
let node = tree_state.node_by_id(weak.node)?;
if node.role() != Role::InlineTextBox {
if node.role() != Role::TextRun {
return None;
}
let character_index = weak.character_index;
Expand All @@ -34,7 +34,7 @@ impl<'a> InnerPosition<'a> {

fn clamped_upgrade(tree_state: &'a TreeState, weak: WeakPosition) -> Option<Self> {
let node = tree_state.node_by_id(weak.node)?;
if node.role() != Role::InlineTextBox {
if node.role() != Role::TextRun {
return None;
}
let character_index = weak
Expand All @@ -57,47 +57,37 @@ impl<'a> InnerPosition<'a> {
false
}

fn is_box_start(&self) -> bool {
fn is_run_start(&self) -> bool {
self.character_index == 0
}

fn is_line_start(&self) -> bool {
self.is_box_start() && self.node.data().previous_on_line().is_none()
self.is_run_start() && self.node.data().previous_on_line().is_none()
}

fn is_box_end(&self) -> bool {
fn is_run_end(&self) -> bool {
self.character_index == self.node.data().character_lengths().len()
}

fn is_line_end(&self) -> bool {
self.is_box_end() && self.node.data().next_on_line().is_none()
self.is_run_end() && self.node.data().next_on_line().is_none()
}

fn is_paragraph_end(&self) -> bool {
self.is_line_end() && self.node.data().value().unwrap().ends_with('\n')
}

fn is_document_start(&self, root_node: &Node) -> bool {
self.is_box_start()
&& self
.node
.preceding_inline_text_boxes(root_node)
.next()
.is_none()
self.is_run_start() && self.node.preceding_text_runs(root_node).next().is_none()
}

fn is_document_end(&self, root_node: &Node) -> bool {
self.is_box_end()
&& self
.node
.following_inline_text_boxes(root_node)
.next()
.is_none()
self.is_run_end() && self.node.following_text_runs(root_node).next().is_none()
}

fn biased_to_start(&self, root_node: &Node) -> Self {
if self.is_box_end() {
if let Some(node) = self.node.following_inline_text_boxes(root_node).next() {
if self.is_run_end() {
if let Some(node) = self.node.following_text_runs(root_node).next() {
return Self {
node,
character_index: 0,
Expand All @@ -108,8 +98,8 @@ impl<'a> InnerPosition<'a> {
}

fn biased_to_end(&self, root_node: &Node) -> Self {
if self.is_box_start() {
if let Some(node) = self.node.preceding_inline_text_boxes(root_node).next() {
if self.is_run_start() {
if let Some(node) = self.node.preceding_text_runs(root_node).next() {
return Self {
node,
character_index: node.data().character_lengths().len(),
Expand Down Expand Up @@ -250,7 +240,7 @@ impl<'a> Position<'a> {

pub fn to_global_usv_index(&self) -> usize {
let mut total_length = 0usize;
for node in self.root_node.inline_text_boxes() {
for node in self.root_node.text_runs() {
let node_text = node.data().value().unwrap();
if node.id() == self.inner.node.id() {
let character_lengths = node.data().character_lengths();
Expand All @@ -268,7 +258,7 @@ impl<'a> Position<'a> {

pub fn to_global_utf16_index(&self) -> usize {
let mut total_length = 0usize;
for node in self.root_node.inline_text_boxes() {
for node in self.root_node.text_runs() {
let node_text = node.data().value().unwrap();
if node.id() == self.inner.node.id() {
let character_lengths = node.data().character_lengths();
Expand Down Expand Up @@ -545,7 +535,7 @@ impl<'a> Range<'a> {
if start.node.id() == end.node.id() {
return None;
}
for node in start.node.following_inline_text_boxes(&self.node) {
for node in start.node.following_text_runs(&self.node) {
if let Some(result) = f(&node) {
return Some(result);
}
Expand Down Expand Up @@ -796,7 +786,7 @@ impl WeakRange {
}

fn text_node_filter(root_id: NodeId, node: &Node) -> FilterResult {
if node.id() == root_id || node.role() == Role::InlineTextBox {
if node.id() == root_id || node.role() == Role::TextRun {
FilterResult::Include
} else {
FilterResult::ExcludeNode
Expand Down Expand Up @@ -844,22 +834,22 @@ fn character_index_at_point(node: &Node, point: Point) -> usize {
}

impl<'a> Node<'a> {
fn inline_text_boxes(
fn text_runs(
&self,
) -> impl DoubleEndedIterator<Item = Node<'a>> + FusedIterator<Item = Node<'a>> + 'a {
let id = self.id();
self.filtered_children(move |node| text_node_filter(id, node))
}

fn following_inline_text_boxes(
fn following_text_runs(
&self,
root_node: &Node,
) -> impl DoubleEndedIterator<Item = Node<'a>> + FusedIterator<Item = Node<'a>> + 'a {
let id = root_node.id();
self.following_filtered_siblings(move |node| text_node_filter(id, node))
}

fn preceding_inline_text_boxes(
fn preceding_text_runs(
&self,
root_node: &Node,
) -> impl DoubleEndedIterator<Item = Node<'a>> + FusedIterator<Item = Node<'a>> + 'a {
Expand All @@ -870,19 +860,19 @@ impl<'a> Node<'a> {
pub fn supports_text_ranges(&self) -> bool {
(self.is_text_input()
|| matches!(self.role(), Role::Label | Role::Document | Role::Terminal))
&& self.inline_text_boxes().next().is_some()
&& self.text_runs().next().is_some()
}

fn document_start(&self) -> InnerPosition<'a> {
let node = self.inline_text_boxes().next().unwrap();
let node = self.text_runs().next().unwrap();
InnerPosition {
node,
character_index: 0,
}
}

fn document_end(&self) -> InnerPosition<'a> {
let node = self.inline_text_boxes().next_back().unwrap();
let node = self.text_runs().next_back().unwrap();
InnerPosition {
node,
character_index: node.data().character_lengths().len(),
Expand Down Expand Up @@ -922,7 +912,7 @@ impl<'a> Node<'a> {
pub fn text_position_at_point(&self, point: Point) -> Position {
let id = self.id();
if let Some((node, point)) = self.hit_test(point, &move |node| text_node_filter(id, node)) {
if node.role() == Role::InlineTextBox {
if node.role() == Role::TextRun {
let pos = InnerPosition {
node,
character_index: character_index_at_point(&node, point),
Expand All @@ -935,9 +925,9 @@ impl<'a> Node<'a> {
}

// The following tests can assume that the point is not within
// any inline text box.
// any text run.

if let Some(node) = self.inline_text_boxes().next() {
if let Some(node) = self.text_runs().next() {
if let Some(rect) = node.bounding_box_in_coordinate_space(self) {
let origin = rect.origin();
if point.x < origin.x || point.y < origin.y {
Expand All @@ -949,7 +939,7 @@ impl<'a> Node<'a> {
}
}

for node in self.inline_text_boxes().rev() {
for node in self.text_runs().rev() {
if let Some(rect) = node.bounding_box_in_coordinate_space(self) {
if let Some(direction) = node.data().text_direction() {
let is_past_end = match direction {
Expand Down Expand Up @@ -1013,7 +1003,7 @@ impl<'a> Node<'a> {

pub fn text_position_from_global_usv_index(&self, index: usize) -> Option<Position> {
let mut total_length = 0usize;
for node in self.inline_text_boxes() {
for node in self.text_runs() {
let node_text = node.data().value().unwrap();
let node_text_length = node_text.chars().count();
let new_total_length = total_length + node_text_length;
Expand Down Expand Up @@ -1055,7 +1045,7 @@ impl<'a> Node<'a> {

pub fn text_position_from_global_utf16_index(&self, index: usize) -> Option<Position> {
let mut total_length = 0usize;
for node in self.inline_text_boxes() {
for node in self.text_runs() {
let node_text = node.data().value().unwrap();
let node_text_length = node_text.chars().map(char::len_utf16).sum::<usize>();
let new_total_length = total_length + node_text_length;
Expand Down Expand Up @@ -1135,7 +1125,7 @@ mod tests {
builder.build()
}),
(NodeId(2), {
let mut builder = NodeBuilder::new(Role::InlineTextBox);
let mut builder = NodeBuilder::new(Role::TextRun);
builder.set_bounds(Rect {
x0: 12.0,
y0: 33.666664123535156,
Expand Down Expand Up @@ -1170,7 +1160,7 @@ mod tests {
builder.build()
}),
(NodeId(3), {
let mut builder = NodeBuilder::new(Role::InlineTextBox);
let mut builder = NodeBuilder::new(Role::TextRun);
builder.set_bounds(Rect {
x0: 12.0,
y0: 48.33333206176758,
Expand All @@ -1195,7 +1185,7 @@ mod tests {
builder.build()
}),
(NodeId(4), {
let mut builder = NodeBuilder::new(Role::InlineTextBox);
let mut builder = NodeBuilder::new(Role::TextRun);
builder.set_bounds(Rect {
x0: 12.0,
y0: 63.0,
Expand All @@ -1221,7 +1211,7 @@ mod tests {
builder.build()
}),
(NodeId(5), {
let mut builder = NodeBuilder::new(Role::InlineTextBox);
let mut builder = NodeBuilder::new(Role::TextRun);
builder.set_bounds(Rect {
x0: 12.0,
y0: 77.66666412353516,
Expand All @@ -1237,7 +1227,7 @@ mod tests {
builder.build()
}),
(NodeId(6), {
let mut builder = NodeBuilder::new(Role::InlineTextBox);
let mut builder = NodeBuilder::new(Role::TextRun);
builder.set_bounds(Rect {
x0: 12.0,
y0: 92.33332824707031,
Expand Down Expand Up @@ -1267,7 +1257,7 @@ mod tests {
builder.build()
}),
(NodeId(7), {
let mut builder = NodeBuilder::new(Role::InlineTextBox);
let mut builder = NodeBuilder::new(Role::TextRun);
builder.set_bounds(Rect {
x0: 12.0,
y0: 107.0,
Expand Down
2 changes: 1 addition & 1 deletion platforms/atspi-common/src/adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ impl<'a> AdapterChangeHandler<'a> {
}

fn emit_text_change_if_needed(&mut self, old_node: &Node, new_node: &Node) {
if let Role::InlineTextBox | Role::GenericContainer = new_node.role() {
if let Role::TextRun | Role::GenericContainer = new_node.role() {
if let (Some(old_parent), Some(new_parent)) = (
old_node.filtered_parent(&filter),
new_node.filtered_parent(&filter),
Expand Down
2 changes: 1 addition & 1 deletion platforms/atspi-common/src/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ impl<'a> NodeWrapper<'a> {
Role::Iframe | Role::IframePresentational => AtspiRole::InternalFrame,
// TODO: If there are unignored children, then it should be AtspiRole::ImageMap.
Role::Image => AtspiRole::Image,
Role::InlineTextBox => AtspiRole::Static,
Role::TextRun => AtspiRole::Static,
Role::Legend => AtspiRole::Label,
// Layout table objects are treated the same as `Role::GenericContainer`.
Role::LayoutTable => AtspiRole::Section,
Expand Down
2 changes: 1 addition & 1 deletion platforms/macos/src/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ impl EventGenerator {
}

fn insert_text_change_if_needed(&mut self, node: &Node) {
if node.role() != Role::InlineTextBox {
if node.role() != Role::TextRun {
return;
}
if let Some(node) = node.filtered_parent(&filter) {
Expand Down
2 changes: 1 addition & 1 deletion platforms/macos/src/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ fn ns_role(node: &Node) -> &'static NSAccessibilityRole {
unsafe {
match role {
Role::Unknown => NSAccessibilityUnknownRole,
Role::InlineTextBox => NSAccessibilityUnknownRole,
Role::TextRun => NSAccessibilityUnknownRole,
Role::Cell => NSAccessibilityCellRole,
Role::Label => NSAccessibilityStaticTextRole,
Role::Image => NSAccessibilityImageRole,
Expand Down
2 changes: 1 addition & 1 deletion platforms/windows/src/adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ impl AdapterChangeHandler<'_> {
}

fn insert_text_change_if_needed(&mut self, node: &Node) {
if node.role() != Role::InlineTextBox {
if node.role() != Role::TextRun {
return;
}
if let Some(node) = node.filtered_parent(&filter) {
Expand Down
Loading

0 comments on commit 29fa341

Please sign in to comment.