package cascade

  1. Overview
  2. Docs
On This Page
  1. Query functions
Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source

Module Cascade_diff.Tree_diffSource

CSS tree difference analysis for structural comparison.

Sourcetype declaration = {
  1. property_name : string;
  2. expected_value : string;
  3. actual_value : string;
}

Declaration diff information.

Sourcetype rule_diff =
  1. | Added of {
    1. selector : string;
    2. declarations : Cascade.Css.declaration list;
    }
  2. | Removed of {
    1. selector : string;
    2. declarations : Cascade.Css.declaration list;
    }
  3. | Content_changed of {
    1. selector : string;
    2. old_declarations : Cascade.Css.declaration list;
    3. new_declarations : Cascade.Css.declaration list;
    4. property_changes : declaration list;
    5. added_properties : string list;
    6. removed_properties : string list;
    }
  4. | Selector_changed of {
    1. old_selector : string;
    2. new_selector : string;
    3. declarations : Cascade.Css.declaration list;
    }
  5. | Reordered of {
    1. selector : string;
    2. expected_pos : int;
    3. actual_pos : int;
    4. swapped_with : string option;
      (*

      When only declaration order changed inside the rule, positions may be irrelevant; in that case old_declarations/new_declarations carry the before/after declarations to allow detailed pretty-printing.

      *)
    5. old_declarations : Cascade.Css.declaration list option;
    6. new_declarations : Cascade.Css.declaration list option;
    }
  6. | Rearranged of {
    1. selector : string;
    2. declarations : Cascade.Css.declaration list;
    }
    (*

    Every declaration the selector carries survives on both sides, spread differently over the rules that write it. An element that also matches an overlapping selector can resolve differently, since which rule carries a declaration decides where it sits relative to the other selector's rules.

    *)
  7. | Regrouped of {
    1. from_selectors : string list;
    2. to_selectors : string list;
    }
    (*

    A comma group merged or split across rules with identical declarations: the same selectors survive, only the grouping differs. from_selectors/to_selectors are the rule selectors in expected and actual.

    *)

Individual rule changes.

Sourcetype container_info = {
  1. container_type : [ `Media | `Layer | `Supports | `Container | `Property | `Nesting | `At_rule ];
  2. condition : string;
  3. rules : Cascade.Css.statement list;
}

Container rule information. `At_rule covers the at-rules that carry no selector and no condition of their own (@page, @font-face, @counter-style, @scope, @starting-style, ...); their condition is the at-rule text up to the block.

Sourcetype container_diff =
  1. | Added of container_info
  2. | Removed of container_info
  3. | Modified of {
    1. info : container_info;
    2. actual_rules : Cascade.Css.statement list;
    3. rule_changes : rule_diff list;
    4. container_changes : container_diff list;
    }
  4. | Reordered of {
    1. info : container_info;
    2. expected_pos : int;
    3. actual_pos : int;
    }
  5. | Block_structure_changed of {
    1. container_type : [ `Media | `Layer | `Supports | `Container | `Property | `Nesting | `At_rule ];
    2. condition : string;
    3. expected_blocks : (int * Cascade.Css.statement list) list;
      (*

      (position, rules) for each block in expected

      *)
    4. actual_blocks : (int * Cascade.Css.statement list) list;
      (*

      (position, rules) for each block in actual

      *)
    }

Container changes.

Sourcetype layer_order_diff = {
  1. expected_order : string list;
  2. actual_order : string list;
  3. swapped : (string * string) list;
}

The cascade layer order the two sheets declare, when they declare it differently. Layers are named by the dotted paths of Cascade.Resolve.layer_order, weakest first, restricted to the layers both sheets declare: one side declaring a layer the other does not is reported as the @layer block that came or went, not as an order change.

swapped holds the pairs (weaker, stronger) that expected_order declares in that order and actual_order the other way round - the layers whose conflicts the two sheets resolve differently. It is never empty.

The order compared is the sheet's own, so a layer declared inside a conditional group is not part of it, as in Cascade.Resolve.layer_order.

Sourcetype t = {
  1. rules : rule_diff list;
  2. containers : container_diff list;
  3. layer_order : layer_order_diff option;
}

Structured CSS differences.

Sourceval is_empty : t -> bool

is_empty d returns true if d contains no differences.

Sourceval reorder_is_significant : Cascade.Css.declaration list -> Cascade.Css.declaration list -> bool

reorder_is_significant d1 d2 is true when reordering the declarations changes the cascade, i.e. two overlapping declarations swap relative order. A reorder of disjoint declarations is no difference.

Sourceval diff : expected:Cascade.Css.t -> actual:Cascade.Css.t -> t

diff ~expected ~actual computes structural differences between two CSS ASTs.

Sourceval pp : ?expected:string -> ?actual:string -> ?color:bool -> ?depth:int -> Buffer.t -> t -> unit

pp ?expected ?actual ?color ?depth buf t pretty-prints a tree diff with optional labels. Default labels are "Expected" and "Actual". color (default false) wraps diff markers in ANSI escapes; the printer writes into a buffer, so the caller decides whether the destination supports colour.

depth bounds how many tree levels are rendered, the top-level entries being level 1 (default: unbounded). A node whose children are cut off is followed by a "... N more lines" marker, so the report never reads as if the elided subtree were empty.

Sourceval pp_rule_diff_simple : Buffer.t -> rule_diff -> unit

pp_rule_diff_simple buf rule pretty-prints a rule diff in a simple format suitable for tests.

Query functions

Sourceval single_rule_diff : t -> rule_diff option

single_rule_diff diff returns Some rule if diff contains exactly one rule change, None otherwise.

Sourceval count_containers_by_type : [ `At_rule | `Container | `Layer | `Media | `Nesting | `Property | `Supports ] -> t -> int

count_containers_by_type container_type diff counts containers of the given type in diff.

Sourceval has_container_added_of_type : [ `At_rule | `Container | `Layer | `Media | `Nesting | `Property | `Supports ] -> t -> bool

has_container_added_of_type container_type diff returns true if diff contains added containers of the given type.

Sourceval has_container_removed_of_type : [ `At_rule | `Container | `Layer | `Media | `Nesting | `Property | `Supports ] -> t -> bool

has_container_removed_of_type container_type diff returns true if diff contains removed containers of the given type.