Skip to content

Commit

Permalink
Adjust #[cfg] etc. to make new <pre> work without CSS.
Browse files Browse the repository at this point in the history
  • Loading branch information
jugglerchris committed Oct 12, 2024
1 parent ace8cac commit 15229ce
Show file tree
Hide file tree
Showing 4 changed files with 155 additions and 155 deletions.
146 changes: 3 additions & 143 deletions src/css.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ use crate::{
Handle,
NodeData::{self, Comment, Document, Element},
},
tree_map_reduce, Colour, Result, TreeMapResult,
tree_map_reduce, Colour, ComputedStyle, Result, Specificity, StyleOrigin, TreeMapResult,
WhiteSpace,
};

use self::parser::Importance;
Expand All @@ -25,43 +26,6 @@ pub(crate) enum SelectorComponent {
CombDescendant,
}

#[derive(Debug, Copy, Clone, PartialEq, Eq, Default)]
pub(crate) struct Specificity {
inline: bool,
id: u16,
class: u16,
typ: u16,
}

impl Specificity {
fn inline() -> Self {
Specificity {
inline: true,
id: 0,
class: 0,
typ: 0,
}
}
}

impl PartialOrd for Specificity {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
match self.inline.partial_cmp(&other.inline) {
Some(core::cmp::Ordering::Equal) => {}
ord => return ord,
}
match self.id.partial_cmp(&other.id) {
Some(core::cmp::Ordering::Equal) => {}
ord => return ord,
}
match self.class.partial_cmp(&other.class) {
Some(core::cmp::Ordering::Equal) => {}
ord => return ord,
}
self.typ.partial_cmp(&other.typ)
}
}

#[derive(Debug, Clone, PartialEq)]
pub(crate) struct Selector {
// List of components, right first so we match from the leaf.
Expand Down Expand Up @@ -185,110 +149,6 @@ pub(crate) struct StyleDecl {
importance: Importance,
}

#[derive(Debug, Copy, Clone, PartialEq, Eq, Default, PartialOrd)]
pub(crate) enum StyleOrigin {
#[default]
None,
Agent,
User,
Author,
}

#[derive(Clone, Copy, Debug)]
pub(crate) struct WithSpec<T: Copy + Clone> {
val: Option<T>,
origin: StyleOrigin,
specificity: Specificity,
important: bool,
}
impl<T: Copy + Clone> WithSpec<T> {
pub(crate) fn maybe_update(
&mut self,
important: bool,
origin: StyleOrigin,
specificity: Specificity,
val: T,
) {
if self.val.is_some() {
// We already have a value, so need to check.
if self.important && !important {
// important takes priority over not important.
return;
}
// importance is the same. Next is checking the origin.
{
use StyleOrigin::*;
match (self.origin, origin) {
(Agent, Agent) | (User, User) | (Author, Author) => {
// They're the same so continue the comparison
}
(mine, theirs) => {
if (important && theirs > mine) || (!important && mine > theirs) {
return;
}
}
}
}
// We're now from the same origin an importance
if specificity < self.specificity {
return;
}
}
self.val = Some(val);
self.origin = origin;
self.specificity = specificity;
self.important = important;
}

pub fn val(&self) -> Option<T> {
self.val
}
}

impl<T: Copy + Clone> Default for WithSpec<T> {
fn default() -> Self {
WithSpec {
val: None,
origin: StyleOrigin::None,
specificity: Default::default(),
important: false,
}
}
}

#[derive(Debug, Copy, Clone, Default, PartialEq)]
pub(crate) enum WhiteSpace {
#[default]
Normal,
// NoWrap,
Pre,
PreWrap,
// PreLine,
// BreakSpaces,
}

impl WhiteSpace {
pub fn preserve_whitespace(&self) -> bool {
match self {
WhiteSpace::Normal => false,
WhiteSpace::Pre | WhiteSpace::PreWrap => true,
}
}
}

#[derive(Debug, Copy, Clone, Default)]
pub(crate) struct ComputedStyle {
/// The computed foreground colour, if any
pub(crate) colour: WithSpec<Colour>,
/// The specificity for colour
/// The computed background colour, if any
pub(crate) bg_colour: WithSpec<Colour>,
/// If set, indicates whether `display: none` or something equivalent applies
pub(crate) display_none: WithSpec<bool>,
/// The CSS white-space property
pub(crate) white_space: WithSpec<WhiteSpace>,
}

#[derive(Debug, Clone)]
struct Ruleset {
selector: Selector,
Expand Down Expand Up @@ -643,7 +503,7 @@ pub(crate) fn dom_to_stylesheet<T: Write>(handle: Handle, err_out: &mut T) -> Re

#[cfg(test)]
mod tests {
use crate::css::Specificity;
use crate::Specificity;

use super::parser::parse_selector;

Expand Down
160 changes: 150 additions & 10 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,14 +64,6 @@ mod macros;
pub mod css;
pub mod render;

#[cfg(feature = "css")]
use css::ComputedStyle;

#[cfg(not(feature = "css"))]
#[derive(Copy, Clone, Debug, Default)]
struct ComputedStyle;

use css::WhiteSpace;
use render::text_renderer::{
RenderLine, RenderOptions, RichAnnotation, SubRenderer, TaggedLine, TextRenderer,
};
Expand All @@ -97,6 +89,27 @@ use std::io;
use std::io::Write;
use std::iter::{once, repeat};

#[derive(Debug, Copy, Clone, Default, PartialEq)]
pub(crate) enum WhiteSpace {
#[default]
Normal,
// NoWrap,
Pre,
#[allow(unused)]
PreWrap,
// PreLine,
// BreakSpaces,
}

impl WhiteSpace {
pub fn preserve_whitespace(&self) -> bool {
match self {
WhiteSpace::Normal => false,
WhiteSpace::Pre | WhiteSpace::PreWrap => true,
}
}
}

/// An RGB colour value
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct Colour {
Expand All @@ -108,6 +121,132 @@ pub struct Colour {
pub b: u8,
}

#[derive(Debug, Copy, Clone, PartialEq, Eq, Default, PartialOrd)]
pub(crate) enum StyleOrigin {
#[default]
None,
Agent,
#[allow(unused)]
User,
#[allow(unused)]
Author,
}

#[derive(Debug, Copy, Clone, PartialEq, Eq, Default)]
pub(crate) struct Specificity {
inline: bool,
id: u16,
class: u16,
typ: u16,
}

impl Specificity {
#[cfg(feature = "css")]
fn inline() -> Self {
Specificity {
inline: true,
id: 0,
class: 0,
typ: 0,
}
}
}

impl PartialOrd for Specificity {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
match self.inline.partial_cmp(&other.inline) {
Some(core::cmp::Ordering::Equal) => {}
ord => return ord,
}
match self.id.partial_cmp(&other.id) {
Some(core::cmp::Ordering::Equal) => {}
ord => return ord,
}
match self.class.partial_cmp(&other.class) {
Some(core::cmp::Ordering::Equal) => {}
ord => return ord,
}
self.typ.partial_cmp(&other.typ)
}
}

#[derive(Clone, Copy, Debug)]
pub(crate) struct WithSpec<T: Copy + Clone> {
val: Option<T>,
origin: StyleOrigin,
specificity: Specificity,
important: bool,
}
impl<T: Copy + Clone> WithSpec<T> {
pub(crate) fn maybe_update(
&mut self,
important: bool,
origin: StyleOrigin,
specificity: Specificity,
val: T,
) {
if self.val.is_some() {
// We already have a value, so need to check.
if self.important && !important {
// important takes priority over not important.
return;
}
// importance is the same. Next is checking the origin.
{
use StyleOrigin::*;
match (self.origin, origin) {
(Agent, Agent) | (User, User) | (Author, Author) => {
// They're the same so continue the comparison
}
(mine, theirs) => {
if (important && theirs > mine) || (!important && mine > theirs) {
return;
}
}
}
}
// We're now from the same origin an importance
if specificity < self.specificity {
return;
}
}
self.val = Some(val);
self.origin = origin;
self.specificity = specificity;
self.important = important;
}

pub fn val(&self) -> Option<T> {
self.val
}
}

impl<T: Copy + Clone> Default for WithSpec<T> {
fn default() -> Self {
WithSpec {
val: None,
origin: StyleOrigin::None,
specificity: Default::default(),
important: false,
}
}
}

#[derive(Debug, Copy, Clone, Default)]
pub(crate) struct ComputedStyle {
#[cfg(feature = "css")]
/// The computed foreground colour, if any
pub(crate) colour: WithSpec<Colour>,
#[cfg(feature = "css")]
/// The computed background colour, if any
pub(crate) bg_colour: WithSpec<Colour>,
#[cfg(feature = "css")]
/// If set, indicates whether `display: none` or something equivalent applies
pub(crate) display_none: WithSpec<bool>,
/// The CSS white-space property
pub(crate) white_space: WithSpec<WhiteSpace>,
}

/// Errors from reading or rendering HTML
#[derive(thiserror::Error, Debug)]
#[non_exhaustive]
Expand Down Expand Up @@ -1333,7 +1472,7 @@ fn process_dom_node<'a, T: Write>(
let mut computed = computed;
computed.white_space.maybe_update(
false,
css::StyleOrigin::Agent,
StyleOrigin::Agent,
Default::default(),
WhiteSpace::Pre,
);
Expand Down Expand Up @@ -1500,12 +1639,13 @@ impl PushedStyleInfo {
fn apply<D: TextDecorator>(render: &mut TextRenderer<D>, style: &ComputedStyle) -> Self {
#[allow(unused_mut)]
let mut result: PushedStyleInfo = Default::default();
#[cfg(feature = "css")]
{
#[cfg(feature = "css")]
if let Some(col) = style.colour.val() {
render.push_colour(col);
result.colour = true;
}
#[cfg(feature = "css")]
if let Some(col) = style.bg_colour.val() {
render.push_bgcolour(col);
result.bgcolour = true;
Expand Down
2 changes: 1 addition & 1 deletion src/render/mod.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
//! Module containing the `Renderer` interface for constructing a
//! particular text output.
use crate::css::WhiteSpace;
use crate::Colour;
use crate::Error;
use crate::WhiteSpace;

pub(crate) mod text_renderer;

Expand Down
2 changes: 1 addition & 1 deletion src/render/text_renderer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
//! This module implements helpers and concrete types for rendering from HTML
//! into different text formats.
use crate::css::WhiteSpace;
use crate::Colour;
use crate::Error;
use crate::WhiteSpace;

use super::Renderer;
use std::cell::Cell;
Expand Down

0 comments on commit 15229ce

Please sign in to comment.