mirror of
https://github.com/DioxusLabs/dioxus
synced 2025-01-04 16:58:51 +00:00
67a6fa9eb8
* work on seperating tree struture from realdom * intial update to new mutations * handle height * update to taffy 0.2 * add as_varient functions to OwnedAttributeValue * make get node parent mut optionally return a parent * work on upward pass * add more code for parrellel passes * make resolve passes public * more work on parallel passes * fix deadlock and add more tests * move height into the tree instead of the realdom * make passes exicute in parallel instead of executing invidual passes in parellel * fix some warnings * add up dependant test * clean up examples * work on intigrating state with passes * update to new mutations * work on implementing macro * make the macro compile * more progress on macro * mark cloned nodes as dirty * update persistant_iterator utility * fix mask generation * update tui with new mutations * more progress updating tui * some basic tui examples working * don't push template nodes onto the stack * update hover example * update benchmark * update more examples * fix root node layout * ignore out of bounds renders * update color picker example * update all events example * update remaining examples * update tests * tests passing * move persistant iterator test * update examples * fix gaps in layout * fix formatting * fix memory leak
803 lines
22 KiB
Rust
803 lines
22 KiB
Rust
/*
|
|
- [ ] pub display: Display,
|
|
- [x] pub position_type: PositionType, --> kinda, taffy doesnt support everything
|
|
- [ ] pub direction: Direction,
|
|
|
|
- [x] pub flex_direction: FlexDirection,
|
|
- [x] pub flex_wrap: FlexWrap,
|
|
- [x] pub flex_grow: f32,
|
|
- [x] pub flex_shrink: f32,
|
|
- [x] pub flex_basis: Dimension,
|
|
|
|
- [x] pub overflow: Overflow, ---> kinda implemented... taffy doesnt have support for directional overflow
|
|
|
|
- [x] pub align_items: AlignItems,
|
|
- [x] pub align_self: AlignSelf,
|
|
- [x] pub align_content: AlignContent,
|
|
|
|
- [x] pub margin: Rect<Dimension>,
|
|
- [x] pub padding: Rect<Dimension>,
|
|
|
|
- [x] pub justify_content: JustifyContent,
|
|
- [ ] pub position: Rect<Dimension>,
|
|
- [x] pub border: Rect<Dimension>,
|
|
|
|
- [ ] pub size: Size<Dimension>, ----> ??? seems to only be relevant for input?
|
|
- [ ] pub min_size: Size<Dimension>,
|
|
- [ ] pub max_size: Size<Dimension>,
|
|
|
|
- [ ] pub aspect_ratio: Number,
|
|
*/
|
|
|
|
use dioxus_native_core::{
|
|
layout_attributes::parse_value,
|
|
node::OwnedAttributeView,
|
|
node_ref::{AttributeMask, NodeMask, NodeView},
|
|
state::ParentDepState,
|
|
};
|
|
use dioxus_native_core_macro::sorted_str_slice;
|
|
use taffy::prelude::*;
|
|
|
|
use crate::style::{RinkColor, RinkStyle};
|
|
|
|
#[derive(Default, Clone, PartialEq, Debug)]
|
|
pub struct StyleModifier {
|
|
pub core: RinkStyle,
|
|
pub modifier: TuiModifier,
|
|
}
|
|
|
|
impl ParentDepState for StyleModifier {
|
|
type Ctx = ();
|
|
type DepState = (Self,);
|
|
// todo: seperate each attribute into it's own class
|
|
const NODE_MASK: NodeMask =
|
|
NodeMask::new_with_attrs(AttributeMask::Static(SORTED_STYLE_ATTRS)).with_element();
|
|
|
|
fn reduce(&mut self, node: NodeView, parent: Option<(&Self,)>, _: &Self::Ctx) -> bool {
|
|
let mut new = StyleModifier::default();
|
|
if parent.is_some() {
|
|
new.core.fg = None;
|
|
}
|
|
|
|
// handle text modifier elements
|
|
if node.namespace().is_none() {
|
|
if let Some(tag) = node.tag() {
|
|
match tag {
|
|
"b" => apply_style_attributes("font-weight", "bold", &mut new),
|
|
"strong" => apply_style_attributes("font-weight", "bold", &mut new),
|
|
"u" => apply_style_attributes("text-decoration", "underline", &mut new),
|
|
"ins" => apply_style_attributes("text-decoration", "underline", &mut new),
|
|
"del" => apply_style_attributes("text-decoration", "line-through", &mut new),
|
|
"i" => apply_style_attributes("font-style", "italic", &mut new),
|
|
"em" => apply_style_attributes("font-style", "italic", &mut new),
|
|
"mark" => {
|
|
apply_style_attributes("background-color", "rgba(241, 231, 64, 50%)", self)
|
|
}
|
|
_ => (),
|
|
}
|
|
}
|
|
}
|
|
|
|
// gather up all the styles from the attribute list
|
|
if let Some(attrs) = node.attributes() {
|
|
for OwnedAttributeView {
|
|
attribute, value, ..
|
|
} in attrs
|
|
{
|
|
if let Some(text) = value.as_text() {
|
|
apply_style_attributes(&attribute.name, text, &mut new);
|
|
}
|
|
}
|
|
}
|
|
|
|
// keep the text styling from the parent element
|
|
if let Some((parent,)) = parent {
|
|
let mut new_style = new.core.merge(parent.core);
|
|
new_style.bg = new.core.bg;
|
|
new.core = new_style;
|
|
}
|
|
if &mut new != self {
|
|
*self = new;
|
|
true
|
|
} else {
|
|
false
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Default, Clone, PartialEq, Debug)]
|
|
pub struct TuiModifier {
|
|
pub borders: Borders,
|
|
}
|
|
|
|
#[derive(Default, Clone, PartialEq, Debug)]
|
|
pub struct Borders {
|
|
pub top: BorderEdge,
|
|
pub right: BorderEdge,
|
|
pub bottom: BorderEdge,
|
|
pub left: BorderEdge,
|
|
}
|
|
|
|
impl Borders {
|
|
fn slice(&mut self) -> [&mut BorderEdge; 4] {
|
|
[
|
|
&mut self.top,
|
|
&mut self.right,
|
|
&mut self.bottom,
|
|
&mut self.left,
|
|
]
|
|
}
|
|
}
|
|
|
|
#[derive(Clone, PartialEq, Debug)]
|
|
pub struct BorderEdge {
|
|
pub color: Option<RinkColor>,
|
|
pub style: BorderStyle,
|
|
pub width: Dimension,
|
|
pub radius: Dimension,
|
|
}
|
|
|
|
impl Default for BorderEdge {
|
|
fn default() -> Self {
|
|
Self {
|
|
color: None,
|
|
style: BorderStyle::None,
|
|
width: Dimension::Points(0.0),
|
|
radius: Dimension::Points(0.0),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
|
pub enum BorderStyle {
|
|
Dotted,
|
|
Dashed,
|
|
Solid,
|
|
Double,
|
|
Groove,
|
|
Ridge,
|
|
Inset,
|
|
Outset,
|
|
Hidden,
|
|
None,
|
|
}
|
|
|
|
impl BorderStyle {
|
|
pub fn symbol_set(&self) -> Option<tui::symbols::line::Set> {
|
|
use tui::symbols::line::*;
|
|
const DASHED: Set = Set {
|
|
horizontal: "╌",
|
|
vertical: "╎",
|
|
..NORMAL
|
|
};
|
|
const DOTTED: Set = Set {
|
|
horizontal: "┈",
|
|
vertical: "┊",
|
|
..NORMAL
|
|
};
|
|
match self {
|
|
BorderStyle::Dotted => Some(DOTTED),
|
|
BorderStyle::Dashed => Some(DASHED),
|
|
BorderStyle::Solid => Some(NORMAL),
|
|
BorderStyle::Double => Some(DOUBLE),
|
|
BorderStyle::Groove => Some(NORMAL),
|
|
BorderStyle::Ridge => Some(NORMAL),
|
|
BorderStyle::Inset => Some(NORMAL),
|
|
BorderStyle::Outset => Some(NORMAL),
|
|
BorderStyle::Hidden => None,
|
|
BorderStyle::None => None,
|
|
}
|
|
}
|
|
}
|
|
|
|
/// applies the entire html namespace defined in dioxus-html
|
|
pub fn apply_style_attributes(
|
|
//
|
|
name: &str,
|
|
value: &str,
|
|
style: &mut StyleModifier,
|
|
) {
|
|
match name {
|
|
"animation"
|
|
| "animation-delay"
|
|
| "animation-direction"
|
|
| "animation-duration"
|
|
| "animation-fill-mode"
|
|
| "animation-iteration-count"
|
|
| "animation-name"
|
|
| "animation-play-state"
|
|
| "animation-timing-function" => apply_animation(name, value, style),
|
|
|
|
"backface-visibility" => {}
|
|
|
|
"background"
|
|
| "background-attachment"
|
|
| "background-clip"
|
|
| "background-color"
|
|
| "background-image"
|
|
| "background-origin"
|
|
| "background-position"
|
|
| "background-repeat"
|
|
| "background-size" => apply_background(name, value, style),
|
|
|
|
"border"
|
|
| "border-bottom"
|
|
| "border-bottom-color"
|
|
| "border-bottom-left-radius"
|
|
| "border-bottom-right-radius"
|
|
| "border-bottom-style"
|
|
| "border-bottom-width"
|
|
| "border-collapse"
|
|
| "border-color"
|
|
| "border-image"
|
|
| "border-image-outset"
|
|
| "border-image-repeat"
|
|
| "border-image-slice"
|
|
| "border-image-source"
|
|
| "border-image-width"
|
|
| "border-left"
|
|
| "border-left-color"
|
|
| "border-left-style"
|
|
| "border-left-width"
|
|
| "border-radius"
|
|
| "border-right"
|
|
| "border-right-color"
|
|
| "border-right-style"
|
|
| "border-right-width"
|
|
| "border-spacing"
|
|
| "border-style"
|
|
| "border-top"
|
|
| "border-top-color"
|
|
| "border-top-left-radius"
|
|
| "border-top-right-radius"
|
|
| "border-top-style"
|
|
| "border-top-width"
|
|
| "border-width" => apply_border(name, value, style),
|
|
|
|
"bottom" => {}
|
|
"box-shadow" => {}
|
|
"box-sizing" => {}
|
|
"caption-side" => {}
|
|
"clear" => {}
|
|
"clip" => {}
|
|
|
|
"color" => {
|
|
if let Ok(c) = value.parse() {
|
|
style.core.fg.replace(c);
|
|
}
|
|
}
|
|
|
|
"columns" => {}
|
|
|
|
"content" => {}
|
|
"counter-increment" => {}
|
|
"counter-reset" => {}
|
|
|
|
"cursor" => {}
|
|
|
|
"empty-cells" => {}
|
|
|
|
"float" => {}
|
|
|
|
"font" | "font-family" | "font-size" | "font-size-adjust" | "font-stretch"
|
|
| "font-style" | "font-variant" | "font-weight" => apply_font(name, value, style),
|
|
|
|
"letter-spacing" => {}
|
|
"line-height" => {}
|
|
|
|
"list-style" | "list-style-image" | "list-style-position" | "list-style-type" => {}
|
|
|
|
"opacity" => {}
|
|
"order" => {}
|
|
"outline" => {}
|
|
|
|
"outline-color" | "outline-offset" | "outline-style" | "outline-width" => {}
|
|
|
|
"page-break-after" | "page-break-before" | "page-break-inside" => {}
|
|
|
|
"perspective" | "perspective-origin" => {}
|
|
|
|
"pointer-events" => {}
|
|
|
|
"quotes" => {}
|
|
"resize" => {}
|
|
"tab-size" => {}
|
|
"table-layout" => {}
|
|
|
|
"text-align"
|
|
| "text-align-last"
|
|
| "text-decoration"
|
|
| "text-decoration-color"
|
|
| "text-decoration-line"
|
|
| "text-decoration-style"
|
|
| "text-indent"
|
|
| "text-justify"
|
|
| "text-overflow"
|
|
| "text-shadow"
|
|
| "text-transform" => apply_text(name, value, style),
|
|
|
|
"transition"
|
|
| "transition-delay"
|
|
| "transition-duration"
|
|
| "transition-property"
|
|
| "transition-timing-function" => apply_transition(name, value, style),
|
|
|
|
"visibility" => {}
|
|
"white-space" => {}
|
|
_ => {}
|
|
}
|
|
}
|
|
|
|
fn apply_background(name: &str, value: &str, style: &mut StyleModifier) {
|
|
match name {
|
|
"background-color" => {
|
|
if let Ok(c) = value.parse() {
|
|
style.core.bg.replace(c);
|
|
}
|
|
}
|
|
"background" => {}
|
|
"background-attachment" => {}
|
|
"background-clip" => {}
|
|
"background-image" => {}
|
|
"background-origin" => {}
|
|
"background-position" => {}
|
|
"background-repeat" => {}
|
|
"background-size" => {}
|
|
_ => {}
|
|
}
|
|
}
|
|
|
|
fn apply_border(name: &str, value: &str, style: &mut StyleModifier) {
|
|
fn parse_border_style(v: &str) -> BorderStyle {
|
|
match v {
|
|
"dotted" => BorderStyle::Dotted,
|
|
"dashed" => BorderStyle::Dashed,
|
|
"solid" => BorderStyle::Solid,
|
|
"double" => BorderStyle::Double,
|
|
"groove" => BorderStyle::Groove,
|
|
"ridge" => BorderStyle::Ridge,
|
|
"inset" => BorderStyle::Inset,
|
|
"outset" => BorderStyle::Outset,
|
|
"none" => BorderStyle::None,
|
|
"hidden" => BorderStyle::Hidden,
|
|
_ => todo!(),
|
|
}
|
|
}
|
|
match name {
|
|
"border" => {}
|
|
"border-bottom" => {}
|
|
"border-bottom-color" => {
|
|
if let Ok(c) = value.parse() {
|
|
style.modifier.borders.bottom.color = Some(c);
|
|
}
|
|
}
|
|
"border-bottom-left-radius" => {
|
|
if let Some(v) = parse_value(value) {
|
|
style.modifier.borders.left.radius = v;
|
|
}
|
|
}
|
|
"border-bottom-right-radius" => {
|
|
if let Some(v) = parse_value(value) {
|
|
style.modifier.borders.right.radius = v;
|
|
}
|
|
}
|
|
"border-bottom-style" => style.modifier.borders.bottom.style = parse_border_style(value),
|
|
"border-bottom-width" => {
|
|
if let Some(v) = parse_value(value) {
|
|
style.modifier.borders.bottom.width = v;
|
|
}
|
|
}
|
|
"border-collapse" => {}
|
|
"border-color" => {
|
|
let values: Vec<_> = value.split(' ').collect();
|
|
if values.len() == 1 {
|
|
if let Ok(c) = values[0].parse() {
|
|
style
|
|
.modifier
|
|
.borders
|
|
.slice()
|
|
.iter_mut()
|
|
.for_each(|b| b.color = Some(c));
|
|
}
|
|
} else {
|
|
for (v, b) in values
|
|
.into_iter()
|
|
.zip(style.modifier.borders.slice().iter_mut())
|
|
{
|
|
if let Ok(c) = v.parse() {
|
|
b.color = Some(c);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
"border-image" => {}
|
|
"border-image-outset" => {}
|
|
"border-image-repeat" => {}
|
|
"border-image-slice" => {}
|
|
"border-image-source" => {}
|
|
"border-image-width" => {}
|
|
"border-left" => {}
|
|
"border-left-color" => {
|
|
if let Ok(c) = value.parse() {
|
|
style.modifier.borders.left.color = Some(c);
|
|
}
|
|
}
|
|
"border-left-style" => style.modifier.borders.left.style = parse_border_style(value),
|
|
"border-left-width" => {
|
|
if let Some(v) = parse_value(value) {
|
|
style.modifier.borders.left.width = v;
|
|
}
|
|
}
|
|
"border-radius" => {
|
|
let values: Vec<_> = value.split(' ').collect();
|
|
if values.len() == 1 {
|
|
if let Some(r) = parse_value(values[0]) {
|
|
style
|
|
.modifier
|
|
.borders
|
|
.slice()
|
|
.iter_mut()
|
|
.for_each(|b| b.radius = r);
|
|
}
|
|
} else {
|
|
for (v, b) in values
|
|
.into_iter()
|
|
.zip(style.modifier.borders.slice().iter_mut())
|
|
{
|
|
if let Some(r) = parse_value(v) {
|
|
b.radius = r;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
"border-right" => {}
|
|
"border-right-color" => {
|
|
if let Ok(c) = value.parse() {
|
|
style.modifier.borders.right.color = Some(c);
|
|
}
|
|
}
|
|
"border-right-style" => style.modifier.borders.right.style = parse_border_style(value),
|
|
"border-right-width" => {
|
|
if let Some(v) = parse_value(value) {
|
|
style.modifier.borders.right.width = v;
|
|
}
|
|
}
|
|
"border-spacing" => {}
|
|
"border-style" => {
|
|
let values: Vec<_> = value.split(' ').collect();
|
|
if values.len() == 1 {
|
|
let border_style = parse_border_style(values[0]);
|
|
style
|
|
.modifier
|
|
.borders
|
|
.slice()
|
|
.iter_mut()
|
|
.for_each(|b| b.style = border_style);
|
|
} else {
|
|
for (v, b) in values
|
|
.into_iter()
|
|
.zip(style.modifier.borders.slice().iter_mut())
|
|
{
|
|
b.style = parse_border_style(v);
|
|
}
|
|
}
|
|
}
|
|
"border-top" => {}
|
|
"border-top-color" => {
|
|
if let Ok(c) = value.parse() {
|
|
style.modifier.borders.top.color = Some(c);
|
|
}
|
|
}
|
|
"border-top-left-radius" => {
|
|
if let Some(v) = parse_value(value) {
|
|
style.modifier.borders.left.radius = v;
|
|
}
|
|
}
|
|
"border-top-right-radius" => {
|
|
if let Some(v) = parse_value(value) {
|
|
style.modifier.borders.right.radius = v;
|
|
}
|
|
}
|
|
"border-top-style" => style.modifier.borders.top.style = parse_border_style(value),
|
|
"border-top-width" => {
|
|
if let Some(v) = parse_value(value) {
|
|
style.modifier.borders.top.width = v;
|
|
}
|
|
}
|
|
"border-width" => {
|
|
let values: Vec<_> = value.split(' ').collect();
|
|
if values.len() == 1 {
|
|
if let Some(w) = parse_value(values[0]) {
|
|
style
|
|
.modifier
|
|
.borders
|
|
.slice()
|
|
.iter_mut()
|
|
.for_each(|b| b.width = w);
|
|
}
|
|
} else {
|
|
for (v, width) in values
|
|
.into_iter()
|
|
.zip(style.modifier.borders.slice().iter_mut())
|
|
{
|
|
if let Some(w) = parse_value(v) {
|
|
width.width = w;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
_ => (),
|
|
}
|
|
}
|
|
|
|
fn apply_animation(name: &str, _value: &str, _style: &mut StyleModifier) {
|
|
match name {
|
|
"animation" => {}
|
|
"animation-delay" => {}
|
|
"animation-direction =>{}" => {}
|
|
"animation-duration" => {}
|
|
"animation-fill-mode" => {}
|
|
"animation-itera =>{}tion-count" => {}
|
|
"animation-name" => {}
|
|
"animation-play-state" => {}
|
|
"animation-timing-function" => {}
|
|
_ => {}
|
|
}
|
|
}
|
|
|
|
fn apply_font(name: &str, value: &str, style: &mut StyleModifier) {
|
|
use tui::style::Modifier;
|
|
match name {
|
|
"font" => (),
|
|
"font-family" => (),
|
|
"font-size" => (),
|
|
"font-size-adjust" => (),
|
|
"font-stretch" => (),
|
|
"font-style" => match value {
|
|
"italic" => style.core = style.core.add_modifier(Modifier::ITALIC),
|
|
"oblique" => style.core = style.core.add_modifier(Modifier::ITALIC),
|
|
_ => (),
|
|
},
|
|
"font-variant" => todo!(),
|
|
"font-weight" => match value {
|
|
"bold" => style.core = style.core.add_modifier(Modifier::BOLD),
|
|
"normal" => style.core = style.core.remove_modifier(Modifier::BOLD),
|
|
_ => (),
|
|
},
|
|
_ => (),
|
|
}
|
|
}
|
|
|
|
fn apply_text(name: &str, value: &str, style: &mut StyleModifier) {
|
|
use tui::style::Modifier;
|
|
|
|
match name {
|
|
"text-align" => todo!(),
|
|
"text-align-last" => todo!(),
|
|
"text-decoration" | "text-decoration-line" => {
|
|
for v in value.split(' ') {
|
|
match v {
|
|
"line-through" => style.core = style.core.add_modifier(Modifier::CROSSED_OUT),
|
|
"underline" => style.core = style.core.add_modifier(Modifier::UNDERLINED),
|
|
_ => (),
|
|
}
|
|
}
|
|
}
|
|
"text-decoration-color" => todo!(),
|
|
"text-decoration-style" => todo!(),
|
|
"text-indent" => todo!(),
|
|
"text-justify" => todo!(),
|
|
"text-overflow" => todo!(),
|
|
"text-shadow" => todo!(),
|
|
"text-transform" => todo!(),
|
|
_ => todo!(),
|
|
}
|
|
}
|
|
|
|
fn apply_transition(_name: &str, _value: &str, _style: &mut StyleModifier) {
|
|
todo!()
|
|
}
|
|
|
|
const SORTED_STYLE_ATTRS: &[&str] = &sorted_str_slice!([
|
|
"animation",
|
|
"animation-delay",
|
|
"animation-direction",
|
|
"animation-duration",
|
|
"animation-fill-mode",
|
|
"animation-iteration-count",
|
|
"animation-name",
|
|
"animation-play-state",
|
|
"animation-timing-function",
|
|
"backface-visibility",
|
|
"background",
|
|
"background-attachment",
|
|
"background-clip",
|
|
"background-color",
|
|
"background-image",
|
|
"background-origin",
|
|
"background-position",
|
|
"background-repeat",
|
|
"background-size",
|
|
"border",
|
|
"border-bottom",
|
|
"border-bottom-color",
|
|
"border-bottom-left-radius",
|
|
"border-bottom-right-radius",
|
|
"border-bottom-style",
|
|
"border-bottom-width",
|
|
"border-collapse",
|
|
"border-color",
|
|
"border-image",
|
|
"border-image-outset",
|
|
"border-image-repeat",
|
|
"border-image-slice",
|
|
"border-image-source",
|
|
"border-image-width",
|
|
"border-left",
|
|
"border-left-color",
|
|
"border-left-style",
|
|
"border-left-width",
|
|
"border-radius",
|
|
"border-right",
|
|
"border-right-color",
|
|
"border-right-style",
|
|
"border-right-width",
|
|
"border-spacing",
|
|
"border-style",
|
|
"border-top",
|
|
"border-top-color",
|
|
"border-top-left-radius",
|
|
"border-top-right-radius",
|
|
"border-top-style",
|
|
"border-top-width",
|
|
"border-width",
|
|
"bottom",
|
|
"box-shadow",
|
|
"box-sizing",
|
|
"caption-side",
|
|
"clear",
|
|
"clip",
|
|
"color",
|
|
"columns",
|
|
"content",
|
|
"counter-increment",
|
|
"counter-reset",
|
|
"cursor",
|
|
"empty-cells",
|
|
"float",
|
|
"font",
|
|
"font-family",
|
|
"font-size",
|
|
"font-size-adjust",
|
|
"font-stretch",
|
|
"font-style",
|
|
"font-variant",
|
|
"font-weight",
|
|
"letter-spacing",
|
|
"line-height",
|
|
"list-style",
|
|
"list-style-image",
|
|
"list-style-position",
|
|
"list-style-type",
|
|
"opacity",
|
|
"order",
|
|
"outline",
|
|
"outline-color",
|
|
"outline-offset",
|
|
"outline-style",
|
|
"outline-width",
|
|
"page-break-after",
|
|
"page-break-before",
|
|
"page-break-inside",
|
|
"perspective",
|
|
"perspective-origin",
|
|
"pointer-events",
|
|
"quotes",
|
|
"resize",
|
|
"tab-size",
|
|
"table-layout",
|
|
"text-align",
|
|
"text-align-last",
|
|
"text-decoration",
|
|
"text-decoration-color",
|
|
"text-decoration-line",
|
|
"text-decoration-style",
|
|
"text-indent",
|
|
"text-justify",
|
|
"text-overflow",
|
|
"text-shadow",
|
|
"text-transform",
|
|
"transition",
|
|
"transition-delay",
|
|
"transition-duration",
|
|
"transition-property",
|
|
"transition-timing-function",
|
|
"visibility",
|
|
"white-space",
|
|
"background-color",
|
|
"background",
|
|
"background-attachment",
|
|
"background-clip",
|
|
"background-image",
|
|
"background-origin",
|
|
"background-position",
|
|
"background-repeat",
|
|
"background-size",
|
|
"dotted",
|
|
"dashed",
|
|
"solid",
|
|
"double",
|
|
"groove",
|
|
"ridge",
|
|
"inset",
|
|
"outset",
|
|
"none",
|
|
"hidden",
|
|
"border",
|
|
"border-bottom",
|
|
"border-bottom-color",
|
|
"border-bottom-left-radius",
|
|
"border-bottom-right-radius",
|
|
"border-bottom-style",
|
|
"border-bottom-width",
|
|
"border-collapse",
|
|
"border-color",
|
|
"border-image",
|
|
"border-image-outset",
|
|
"border-image-repeat",
|
|
"border-image-slice",
|
|
"border-image-source",
|
|
"border-image-width",
|
|
"border-left",
|
|
"border-left-color",
|
|
"border-left-style",
|
|
"border-left-width",
|
|
"border-radius",
|
|
"border-right",
|
|
"border-right-color",
|
|
"border-right-style",
|
|
"border-right-width",
|
|
"border-spacing",
|
|
"border-style",
|
|
"border-top",
|
|
"border-top-color",
|
|
"border-top-left-radius",
|
|
"border-top-right-radius",
|
|
"border-top-style",
|
|
"border-top-width",
|
|
"border-width",
|
|
"animation",
|
|
"animation-delay",
|
|
"animation-direction",
|
|
"animation-duration",
|
|
"animation-fill-mode",
|
|
"animation-itera ",
|
|
"animation-name",
|
|
"animation-play-state",
|
|
"animation-timing-function",
|
|
"font",
|
|
"font-family",
|
|
"font-size",
|
|
"font-size-adjust",
|
|
"font-stretch",
|
|
"font-style",
|
|
"italic",
|
|
"oblique",
|
|
"font-variant",
|
|
"font-weight",
|
|
"bold",
|
|
"normal",
|
|
"text-align",
|
|
"text-align-last",
|
|
"text-decoration",
|
|
"text-decoration-line",
|
|
"line-through",
|
|
"underline",
|
|
"text-decoration-color",
|
|
"text-decoration-style",
|
|
"text-indent",
|
|
"text-justify",
|
|
"text-overflow",
|
|
"text-shadow",
|
|
"text-transform"
|
|
]);
|