Rename the component content special attribute children for consistency with React

This commit is contained in:
Keavon Chambers 2021-02-14 14:30:18 -08:00
parent 61823a044d
commit 283ea5acd7
12 changed files with 33 additions and 33 deletions

View file

@ -17,13 +17,13 @@ Layout is controlled using predefined attributes, such as `width`, `height`, `x-
## Component lifetime
The children of a component are passed to it as a `content` attribute. For example, looking at the row component:
The children of a component are passed to it as a `children` attribute. For example, looking at the row component:
```xml
<row content="INNER_XML: (Layout) = [[]]">
<row children="INNER_XML: (Layout) = [[]]">
{{INNER_XML}}
</row>
```
The `content` attribute defines a new variable `INNER_XML` of type `Layout` which can contain more XML layout structure. It has a default value of `[[]]` which refers to an empty layout— XML syntax (for the `Layout` data type) written in a tag's attribute is wrapped in ``[[`` (opening) and `]]` (closing) symbols. In this case the `INNER_XML` variable defaults to empty XML, however it is not stricly useful here because the `content` attribute will always have its value replaced by whatever exists between opening and closing tags when this component is called from elsewhere.
The `children` attribute defines a new variable `INNER_XML` of type `Layout` which can contain more XML layout structure. It has a default value of `[[]]` which refers to an empty layout— XML syntax (for the `Layout` data type) written in a tag's attribute is wrapped in ``[[`` (opening) and `]]` (closing) symbols. In this case the `INNER_XML` variable defaults to empty XML, however it is not strictly useful here because the `children` attribute will always have its value replaced by whatever exists between opening and closing tags when this component is called from elsewhere.
This is then expanded in the body of the row: `{{INNER_XML}}`.

View file

@ -1,3 +1,3 @@
<box content="INNER_XML: (Layout) = [[]]" :fill="FILL: (Color) = ['middlegray']" :round="ROUND: (AbsolutePx | AbsolutePx, AbsolutePx, AbsolutePx, AbsolutePx) = 0px" :border-thickness="BORDER_THICKNESS: (AbsolutePx) = 0px" :border-color="BORDER_COLOR: (Color) = ['black']">
<box children="INNER_XML: (Layout) = [[]]" :fill="FILL: (Color) = ['middlegray']" :round="ROUND: (AbsolutePx | AbsolutePx, AbsolutePx, AbsolutePx, AbsolutePx) = 0px" :border-thickness="BORDER_THICKNESS: (AbsolutePx) = 0px" :border-color="BORDER_COLOR: (Color) = ['black']">
{{INNER_XML}}
</box>

View file

@ -1,3 +1,3 @@
<col content="INNER_XML: (Layout) = [[]]">
<col children="INNER_XML: (Layout) = [[]]">
{{INNER_XML}}
</col>

View file

@ -1,3 +1,3 @@
<icon content="INNER_XML: (Layout) = [[]]" :svg="SVG_SOURCE: (TemplateString) = ``" :style="SVG_STYLE: (TemplateString) = ``">
<icon children="INNER_XML: (Layout) = [[]]" :svg="SVG_SOURCE: (TemplateString) = ``" :style="SVG_STYLE: (TemplateString) = ``">
{{INNER_XML}}
</icon>

View file

@ -1,3 +1,3 @@
<if content="INNER_XML: (Layout) = [[]]" :a="CONDITION_A: (Integer | Decimal | AbsolutePx | Percent | PercentRemainder | Inner | Width | Height | TemplateString | Color | Bool | None) = true" :b="CONDITION_B: (Integer | Decimal | AbsolutePx | Percent | PercentRemainder | Inner | Width | Height | TemplateString | Color | Bool | None) = true">
<if children="INNER_XML: (Layout) = [[]]" :a="CONDITION_A: (Integer | Decimal | AbsolutePx | Percent | PercentRemainder | Inner | Width | Height | TemplateString | Color | Bool | None) = true" :b="CONDITION_B: (Integer | Decimal | AbsolutePx | Percent | PercentRemainder | Inner | Width | Height | TemplateString | Color | Bool | None) = true">
{{RESULT}}
</if>

View file

@ -1,4 +1,4 @@
<input:checkbox-with-dropdown content="OPTION_LIST: (Layout) = [[]]" :disabled="DISABLED: (Bool) = false" :checked="CHECKED: (Bool) = false" :selected-index="SELECTED_INDEX: (Integer) = 0">
<input:checkbox-with-dropdown children="OPTION_LIST: (Layout) = [[]]" :disabled="DISABLED: (Bool) = false" :checked="CHECKED: (Bool) = false" :selected-index="SELECTED_INDEX: (Integer) = 0">
<!-- Checkbox -->
<col width="height" height="100%">
<box width="100%" height="100%" x-align="50%" y-align="50%" :round="4px, 0px, 0px, 4px" :fill="['accent']">

View file

@ -1,4 +1,4 @@
<input:dropdown content="OPTION_LIST: (TemplateString) = ``" :selected-index="SELECTED_INDEX: (Integer) = 0" :disabled="DISABLED: (Bool) = false">
<input:dropdown children="OPTION_LIST: (TemplateString) = ``" :selected-index="SELECTED_INDEX: (Integer) = 0" :disabled="DISABLED: (Bool) = false">
<box width="100%" :round="4px">
<!-- Current selection text -->
<col width="100%" height="24px">

View file

@ -1,3 +1,3 @@
<row content="INNER_XML: (Layout) = [[]]">
<row children="INNER_XML: (Layout) = [[]]">
{{INNER_XML}}
</row>

View file

@ -1 +1 @@
<text content="TEXT_STRING: (TemplateString) = `MISSING TEXT CONTENT`" :color="COLOR: (Color) = ['middlegray']" :size="SIZE: (AbsolutePx) = 12px"></text>
<text children="TEXT_STRING: (TemplateString) = `MISSING TEXT CONTENT`" :color="COLOR: (Color) = ['middlegray']" :size="SIZE: (AbsolutePx) = 12px"></text>

View file

@ -85,7 +85,7 @@ impl Application {
// Main window in the XML layout language
let mut main_window_layout = LayoutSystem::new();
main_window_layout.add_window(("window", "main"));
main_window_layout.add_window(("window", "main"), (1920, 1080));
Self {
surface,

View file

@ -9,9 +9,9 @@ pub struct FlatComponent {
pub child_components: Vec<LayoutComponentTag>,
}
/// A component in its final processed form (after parsing its XML file), with information on its definition with a list of child components with their own children in their `content` attributes
/// A component in its final processed form (after parsing its XML file), with information on its definition with a list of child components with their own children in their `children` attributes
impl FlatComponent {
// Construct a layout component which stores its own root-level component definition (with prop definitions, etc.) and a flat list of its direct child tags, each with an AST in their `content` attribute
// Construct a layout component which stores its own root-level component definition (with prop definitions, etc.) and a flat list of its direct child tags, each with an AST in their `children` attribute
pub fn new(own_info: LayoutComponentDefinition, child_components: Vec<LayoutComponentTag>) -> FlatComponent {
Self { own_info, child_components }
}
@ -99,7 +99,7 @@ impl LayoutComponentDefinition {
// ====================================================================================================
/// Abstract representation of a tag inside an abstract component with attributes and descendant content
/// Abstract representation of a tag inside an abstract component with attributes and children
#[derive(Debug, Clone, PartialEq)]
pub struct LayoutComponentTag {
/// Namespace and name of the tag's referenced component
@ -108,8 +108,8 @@ pub struct LayoutComponentTag {
pub layout: LayoutAttributes,
/// Props on this tag, which are prefixed with ':'
pub props: Vec<Prop>,
/// The special content attribute, containing the inner elements of this tag
pub content: Option<Vec<NodeTree>>,
/// The special `children` attribute, containing the inner elements of this tag
pub children: Option<Vec<NodeTree>>,
}
impl LayoutComponentTag {
@ -118,14 +118,14 @@ impl LayoutComponentTag {
Self {
name,
layout: Default::default(),
content: None,
children: None,
props: Vec::new(),
}
}
/// Provide a sequence of ASTs for this component's content attribute
pub fn set_content(&mut self, content: Vec<NodeTree>) {
self.content = Some(content);
/// Provide a sequence of ASTs for this component's special `children` attribute
pub fn set_children(&mut self, children: Vec<NodeTree>) {
self.children = Some(children);
}
/// Add an XML tag attribute to this component (either a layout engine setting, a prop, or an event handler binding)
@ -170,8 +170,8 @@ impl LayoutComponentTag {
/// Print the layout tag (for debugging)
pub fn debug_print(&self) {
println!("Tag Node: {:#?}", self);
if let Some(ref content) = self.content {
for child in content {
if let Some(ref children) = self.children {
for child in children {
for node in child.descendants() {
println!("> Descendant Node: {:#?}", node);
}

View file

@ -24,7 +24,7 @@ impl<'a> LayoutSystem<'a> {
}
/// Load and construct a new window from a layout component
pub fn add_window(&'a mut self, name: (&str, &str)) {
pub fn add_window(&'a mut self, name: (&str, &str), window_size: (u32, u32)) {
// Preload the component and its dependencies
self.preload_component(name)
.expect(&format!("Failure loading layout component '{}'", Self::component_name(name))[..]);
@ -33,7 +33,7 @@ impl<'a> LayoutSystem<'a> {
let window_root_component_name = Self::component_name(name);
// Construct the window and save it
let new_window = WindowDom::new(&window_root_component_name[..], (1920, 1080), &self.loaded_components);
let new_window = WindowDom::new(&window_root_component_name[..], window_size, &self.loaded_components);
self.windows.push(new_window);
}
@ -117,9 +117,9 @@ impl<'a> LayoutSystem<'a> {
}
}
// Explore the tree of `content` children
if let Some(ref content) = tag.content {
for child_node in content.iter() {
// Explore the tree of the `children` elements stored in this component
if let Some(ref children) = tag.children {
for child_node in children.iter() {
for descendant in child_node.descendants() {
match &*descendant.borrow() {
LayoutComponentNode::Tag(component_tag) => self.explore_component_tag(component_tag, already_loaded_layouts),
@ -144,7 +144,7 @@ impl<'a> LayoutSystem<'a> {
Ok(Self::node_tree_from_node_or_def_tree(&parsed_tree))
}
/// Flatten a full XML component AST into a vector of the immediate children and put the descendants of those nodes into `content` attributes
/// Flatten a full XML component AST into a vector of the immediate children and put the descendants of those nodes into `children` attributes
fn flatten_component_tree(tree: &mut NodeOrDefTree) -> FlatComponent {
let own_info = match &*tree.borrow() {
LayoutComponentNodeOrDefinition::LayoutComponentDefinition(definition) => definition.clone(),
@ -152,11 +152,11 @@ impl<'a> LayoutSystem<'a> {
LayoutComponentNodeOrDefinition::LayoutComponentNode(LayoutComponentNode::Text(_)) => panic!("Text node found in place of component definition"),
};
// Turn all the tag nodes (but not text nodes) into a list of flat child components (with their descendant trees in their `content` attributes)
// Turn all the tag nodes (but not text nodes) into a list of flat child components (with their descendant trees in their `children` attributes)
let child_components = tree
// Get the direct children from this tree node
.children()
// Clone each child abstract tag node (ignoring text nodes) with each of their descendants added to their `content` attribute variable
// Clone each child abstract tag node (ignoring text nodes) with each of their descendants added to their `children` attribute variable
.filter_map(|child_node| {
// Filter out text nodes because they make no sense as child components
let mut cloned_tag = match &*child_node.borrow() {
@ -165,14 +165,14 @@ impl<'a> LayoutSystem<'a> {
LayoutComponentNodeOrDefinition::LayoutComponentDefinition(_) => panic!("Component definition found in place of tag node"),
};
// Clone the tree for this child as `LayoutComponentNode`s and turn its children into a vector, then set that vector as the content attribute
// Clone the tree for this child as `LayoutComponentNode`s and turn its children into a vector, then set that vector as the `children` attribute
let node_within_root = Self::node_tree_from_node_or_def_tree(&child_node);
let children = node_within_root.children().map(|mut child| {
// Child must be detached in order to live on its own in the vector, otherwise it will be cleaned up when its (former) parent is dropped
child.detach();
child
}).collect::<Vec<_>>();
cloned_tag.set_content(children);
cloned_tag.set_children(children);
// Return this `LayoutComponentTag` within the component's root definition tag
Some(cloned_tag)