///|
pub(all) enum SemanticsRole {
None
Text
Link
Heading
Navigation
Main
Button
Checkbox
TextField
List
ListItem
Grid
ScrollView
Switch
Radio
Slider
Progress
Tab
Dialog
Tooltip
Menu
ButtonGroup
Form
FormField
Tree
TreeItem
Group
WebView
Image
Alert
Status
ComboBox
Option
Table
Row
Cell
Separator
} derive(Eq, Debug, ToJson)
///|
pub extend SemanticsRole with Debug::{to_repr}
///|
pub extend SemanticsRole with Eq::{not_equal, equal}
///|
pub extend SemanticsRole with ToJson::{to_json}
///|
/// A stable application-owned identifier for one effective semantic boundary.
///
/// Values are exact and case-sensitive. Parsing rejects empty values, values
/// longer than 255 UTF-8 bytes, and values containing Unicode whitespace or
/// control characters.
pub struct SemanticId {
priv value : String
} derive(Eq, Compare, Hash, Debug)
///|
pub extend SemanticId with Debug::{to_repr}
///|
pub extend SemanticId with Eq::{not_equal, equal}
///|
pub extend SemanticId with ToJson::{to_json}
///|
pub extend SemanticId with Compare::{op_lt, op_le, op_ge, compare, op_gt}
///|
pub extend SemanticId with Hash::{hash, hash_combine}
///|
fn semantic_id_code_unit_is_forbidden(code_unit : UInt16) -> Bool {
let value = code_unit.to_int()
value <= 0x1F ||
(value >= 0x7F && value <= 0x9F) ||
value == 0x20 ||
value == 0xA0 ||
value == 0x1680 ||
(value >= 0x2000 && value <= 0x200A) ||
value == 0x2028 ||
value == 0x2029 ||
value == 0x202F ||
value == 0x205F ||
value == 0x3000
}
///|
/// Parses and validates a stable semantic identifier.
pub fn SemanticId::parse(value : String) -> SemanticId? {
let byte_length = @utf8.encode(value[:], bom=false).length()
if byte_length == 0 || byte_length > 255 {
return None
}
for code_unit in value.code_units() {
if semantic_id_code_unit_is_forbidden(code_unit) {
return None
}
}
Some({ value, })
}
///|
/// Parses and validates a stable semantic identifier declared in UI code,
/// aborting the process when the value is not a legal `SemanticId`.
///
/// UI code declares these identifiers as literals, so an invalid literal is a
/// programming error that must surface at the first view construction instead
/// of being silently dropped. Use `SemanticId::parse` for values that
/// originate outside the program.
pub fn SemanticId::new(value : String) -> SemanticId {
match SemanticId::parse(value) {
Some(id) => id
None =>
abort(
"invalid semantic_id \{value}: expected 1-255 UTF-8 bytes without whitespace or control characters",
)
}
}
///|
/// Returns the exact, non-normalized identifier value.
pub fn SemanticId::value(self : SemanticId) -> String {
self.value
}
///|
pub impl ToJson for SemanticId with fn to_json(self : SemanticId) -> Json {
self.value.to_json()
}
///|
/// Runtime-session-local identity for one committed semantics node.
pub struct SemanticsNodeId {
priv value : UInt64
} derive(Eq, Compare, Hash, Debug)
///|
pub extend SemanticsNodeId with Debug::{to_repr}
///|
pub extend SemanticsNodeId with Eq::{not_equal, equal}
///|
pub extend SemanticsNodeId with ToJson::{to_json}
///|
pub extend SemanticsNodeId with Compare::{op_lt, op_le, op_ge, compare, op_gt}
///|
pub extend SemanticsNodeId with Hash::{hash, hash_combine}
///|
pub fn SemanticsNodeId::new(value : UInt64) -> SemanticsNodeId {
{ value, }
}
///|
pub fn SemanticsNodeId::value(self : SemanticsNodeId) -> UInt64 {
self.value
}
///|
/// Returns the lossless decimal wire representation.
pub fn SemanticsNodeId::to_wire(self : SemanticsNodeId) -> String {
self.value.to_string(radix=10)
}
///|
pub impl ToJson for SemanticsNodeId with fn to_json(self : SemanticsNodeId) -> Json {
self.to_wire().to_json()
}
///|
/// Version of one runtime's atomically committed public semantics snapshot.
pub struct SemanticsGeneration {
priv value : UInt64
} derive(Eq, Compare, Hash, Debug)
///|
pub extend SemanticsGeneration with Debug::{to_repr}
///|
pub extend SemanticsGeneration with Eq::{not_equal, equal}
///|
pub extend SemanticsGeneration with ToJson::{to_json}
///|
pub extend SemanticsGeneration with Compare::{
op_lt,
op_le,
op_ge,
compare,
op_gt,
}
///|
pub extend SemanticsGeneration with Hash::{hash, hash_combine}
///|
pub fn SemanticsGeneration::new(value : UInt64) -> SemanticsGeneration {
{ value, }
}
///|
pub fn SemanticsGeneration::value(self : SemanticsGeneration) -> UInt64 {
self.value
}
///|
/// Returns the lossless decimal wire representation.
pub fn SemanticsGeneration::to_wire(self : SemanticsGeneration) -> String {
self.value.to_string(radix=10)
}
///|
pub impl ToJson for SemanticsGeneration with fn to_json(
self : SemanticsGeneration,
) -> Json {
self.to_wire().to_json()
}
///|
/// A payload-free semantic capability advertised by a committed node.
pub(all) enum SemanticsActionKind {
Activate
Focus
SetText
Submit
Scroll
Select
Expand
Collapse
Dismiss
Increment
Decrement
SetNumericValue
SetSelection
ShowMenu
} derive(Eq, Debug, ToJson)
///|
pub extend SemanticsActionKind with Debug::{to_repr}
///|
pub extend SemanticsActionKind with Eq::{not_equal, equal}
///|
pub extend SemanticsActionKind with ToJson::{to_json}
///|
pub(all) enum SemanticsScrollDirection {
Forward
Backward
Up
Down
Left
Right
} derive(Eq, Debug, ToJson)
///|
pub extend SemanticsScrollDirection with Debug::{to_repr}
///|
pub extend SemanticsScrollDirection with Eq::{not_equal, equal}
///|
pub extend SemanticsScrollDirection with ToJson::{to_json}
///|
/// A typed semantic invocation. Payload requirements are encoded by the
/// constructor rather than represented by an optional side channel.
pub(all) enum SemanticsAction {
Activate
Focus
SetText(String)
Submit
Scroll(SemanticsScrollDirection)
Select
Expand
Collapse
Dismiss
Increment
Decrement
SetNumericValue(Double)
SetSelection(TextRange)
ShowMenu
} derive(Eq, Debug, ToJson)
///|
pub extend SemanticsAction with Debug::{to_repr}
///|
pub extend SemanticsAction with Eq::{not_equal, equal}
///|
pub extend SemanticsAction with ToJson::{to_json}
///|
pub fn SemanticsAction::kind(self : SemanticsAction) -> SemanticsActionKind {
match self {
Activate => Activate
Focus => Focus
SetText(_) => SetText
Submit => Submit
Scroll(_) => Scroll
Select => Select
Expand => Expand
Collapse => Collapse
Dismiss => Dismiss
Increment => Increment
Decrement => Decrement
SetNumericValue(_) => SetNumericValue
SetSelection(_) => SetSelection
ShowMenu => ShowMenu
}
}
///|
pub(all) enum SemanticsCheckedState {
Unchecked
Checked
Mixed
} derive(Eq, Debug, ToJson)
///|
pub extend SemanticsCheckedState with Debug::{to_repr}
///|
pub extend SemanticsCheckedState with Eq::{not_equal, equal}
///|
pub extend SemanticsCheckedState with ToJson::{to_json}
///|
pub(all) enum SemanticsLive {
Off
Polite
Assertive
} derive(Eq, Debug, ToJson)
///|
pub extend SemanticsLive with Debug::{to_repr}
///|
pub extend SemanticsLive with Eq::{not_equal, equal}
///|
pub extend SemanticsLive with ToJson::{to_json}
///|
pub(all) struct SemanticsNumericValue {
current : Double?
min : Double?
max : Double?
step : Double?
value_text : String?
} derive(Eq, Debug, ToJson)
///|
pub extend SemanticsNumericValue with Debug::{to_repr}
///|
pub extend SemanticsNumericValue with Eq::{not_equal, equal}
///|
pub extend SemanticsNumericValue with ToJson::{to_json}
///|
pub fn SemanticsNumericValue::new(
current? : Double,
min? : Double,
max? : Double,
step? : Double,
value_text? : String,
) -> SemanticsNumericValue {
{ current, min, max, step, value_text, }
}
///|
pub(all) struct SemanticsTextValue {
selection : TextRange?
caret : Int?
editable : Bool
} derive(Eq, Debug, ToJson)
///|
pub extend SemanticsTextValue with Debug::{to_repr}
///|
pub extend SemanticsTextValue with Eq::{not_equal, equal}
///|
pub extend SemanticsTextValue with ToJson::{to_json}
///|
pub fn SemanticsTextValue::new(
selection? : TextRange,
caret? : Int,
editable? : Bool = false,
) -> SemanticsTextValue {
{ selection, caret, editable, }
}
///|
pub(all) struct SemanticsCollectionInfo {
row_index : Int?
row_count : Int?
row_span : Int?
column_index : Int?
column_count : Int?
column_span : Int?
set_size : Int?
set_position : Int?
} derive(Eq, Debug, ToJson)
///|
pub extend SemanticsCollectionInfo with Debug::{to_repr}
///|
pub extend SemanticsCollectionInfo with Eq::{not_equal, equal}
///|
pub extend SemanticsCollectionInfo with ToJson::{to_json}
///|
pub fn SemanticsCollectionInfo::new(
row_index? : Int,
row_count? : Int,
row_span? : Int,
column_index? : Int,
column_count? : Int,
column_span? : Int,
set_size? : Int,
set_position? : Int,
) -> SemanticsCollectionInfo {
{
row_index,
row_count,
row_span,
column_index,
column_count,
column_span,
set_size,
set_position,
}
}
///|
/// Relations declared by views use application-stable semantic IDs.
pub(all) struct SemanticsRelationsDeclaration {
labelled_by : Array[SemanticId]
described_by : Array[SemanticId]
controls : Array[SemanticId]
error_message : Array[SemanticId]
active_descendant : Array[SemanticId]
} derive(Eq, Debug, ToJson)
///|
pub extend SemanticsRelationsDeclaration with Debug::{to_repr}
///|
pub extend SemanticsRelationsDeclaration with Eq::{not_equal, equal}
///|
pub extend SemanticsRelationsDeclaration with ToJson::{to_json}
///|
pub fn SemanticsRelationsDeclaration::new(
labelled_by? : Array[SemanticId] = [],
described_by? : Array[SemanticId] = [],
controls? : Array[SemanticId] = [],
error_message? : Array[SemanticId] = [],
active_descendant? : Array[SemanticId] = [],
) -> SemanticsRelationsDeclaration {
{ labelled_by, described_by, controls, error_message, active_descendant, }
}
///|
pub(all) enum SemanticsRelationKind {
LabelledBy
DescribedBy
Controls
ErrorMessage
ActiveDescendant
} derive(Eq, Debug, ToJson)
///|
pub extend SemanticsRelationKind with Debug::{to_repr}
///|
pub extend SemanticsRelationKind with Eq::{not_equal, equal}
///|
pub extend SemanticsRelationKind with ToJson::{to_json}
///|
/// Relations in a committed snapshot contain only resolved runtime node IDs.
pub(all) struct SemanticsRelations {
labelled_by : Array[SemanticsNodeId]
described_by : Array[SemanticsNodeId]
controls : Array[SemanticsNodeId]
error_message : Array[SemanticsNodeId]
active_descendant : Array[SemanticsNodeId]
} derive(Eq, Debug, ToJson)
///|
pub extend SemanticsRelations with Debug::{to_repr}
///|
pub extend SemanticsRelations with Eq::{not_equal, equal}
///|
pub extend SemanticsRelations with ToJson::{to_json}
///|
pub fn SemanticsRelations::empty() -> SemanticsRelations {
{
labelled_by: [],
described_by: [],
controls: [],
error_message: [],
active_descendant: [],
}
}
///|
/// Controls how one view declaration contributes to the effective semantics
/// tree.
pub(all) enum SemanticsComposition {
Transparent
Boundary
MergeDescendants
Hidden
} derive(Eq, Debug, ToJson)
///|
pub extend SemanticsComposition with Debug::{to_repr}
///|
pub extend SemanticsComposition with Eq::{not_equal, equal}
///|
pub extend SemanticsComposition with ToJson::{to_json}
///|
/// Selects either an application-owned stable ID, a session-local committed
/// node ID, or a stepwise walk of the committed semantics hierarchy.
pub(all) enum SemanticsTarget {
BySemanticId(SemanticId)
ByNodeId(SemanticsNodeId)
ByPath(Array[SemanticsPathSegment])
} derive(Eq, Debug, ToJson)
///|
pub extend SemanticsTarget with Debug::{to_repr}
///|
pub extend SemanticsTarget with Eq::{not_equal, equal}
///|
pub extend SemanticsTarget with ToJson::{to_json}
///|
/// One step of a `ByPath` walk, resolved from the committed semantics tree.
///
/// A step selects the `index`-th child of the current node whose effective
/// values satisfy every supplied filter; an absent filter matches anything.
/// `SemanticsRole::None` cannot be filtered on, because its absence already
/// means "no role filter" — filter on `label` or `value` for those nodes.
///
/// A step that supplies no filter at all addresses a position rather than a
/// node. The wire decoder rejects such a step, and runtime resolution treats
/// it as no match, so an agent cannot request one.
pub(all) struct SemanticsPathSegment {
index : Int
role : SemanticsRole?
label : String?
value : String?
semantic_id : SemanticId?
} derive(Eq, Debug, ToJson)
///|
pub extend SemanticsPathSegment with Debug::{to_repr}
///|
pub extend SemanticsPathSegment with Eq::{not_equal, equal}
///|
pub extend SemanticsPathSegment with ToJson::{to_json}
///|
pub(all) struct SemanticsState {
focused : Bool
disabled : Bool
selected : Bool
pressed : Bool
checked : SemanticsCheckedState?
expanded : Bool
invalid : Bool
required : Bool
read_only : Bool
busy : Bool
multiline : Bool
password : Bool
modal : Bool
} derive(Eq, Debug, ToJson)
///|
pub extend SemanticsState with Debug::{to_repr}
///|
pub extend SemanticsState with Eq::{not_equal, equal}
///|
pub extend SemanticsState with ToJson::{to_json}
///|
pub(all) struct SemanticsNode {
node_id : SemanticsNodeId
semantic_id : SemanticId?
role : SemanticsRole
level : Int?
url : String
label : String
value : String
description : String
state : SemanticsState
numeric : SemanticsNumericValue?
text : SemanticsTextValue?
collection : SemanticsCollectionInfo?
relations : SemanticsRelations
live : SemanticsLive
live_atomic : Bool
actions : Array[SemanticsActionKind]
focus_order : Int?
frame : Rect
children : Array[SemanticsNodeId]
} derive(Eq, Debug, ToJson)
///|
pub extend SemanticsNode with Debug::{to_repr}
///|
pub extend SemanticsNode with Eq::{not_equal, equal}
///|
pub extend SemanticsNode with ToJson::{to_json}
///|
pub fn SemanticsState::default() -> SemanticsState {
{
focused: false,
disabled: false,
selected: false,
pressed: false,
checked: None,
expanded: false,
invalid: false,
required: false,
read_only: false,
busy: false,
multiline: false,
password: false,
modal: false,
}
}
///|
pub(all) enum ScrollAlignment {
Start
Center
End
Nearest
} derive(Eq, Debug, ToJson)
///|
pub extend ScrollAlignment with Debug::{to_repr}
///|
pub extend ScrollAlignment with Eq::{not_equal, equal}
///|
pub extend ScrollAlignment with ToJson::{to_json}