htmlcheck

package
v0.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 6, 2026 License: MIT Imports: 10 Imported by: 0

Documentation

Overview

Package htmlcheck implements the email-client compatibility report served at GET /api/v1/message/{id}/html_check.

Contract: takes an HTML body, returns an HtmlCheckReport with per-rule "issues" (lines + affected clients) and per-family support statistics weighted by market share.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type CategoryCounts

type CategoryCounts struct {
	Desktop int `json:"desktop"`
	Mobile  int `json:"mobile"`
	Web     int `json:"web"`
}

CategoryCounts is the {desktop, mobile, web} triple used both for version counts and per-category support percents.

type Client

type Client struct {
	Family   string `json:"family"   yaml:"family"`
	Platform string `json:"platform" yaml:"platform"`
	Category string `json:"category" yaml:"category"`
	Support  string `json:"support"  yaml:"support"` // yes | no | partial
	//nolint:tagliatelle // embedded yaml data uses snake_case keys
	NoteNumbers []int    `json:"note_numbers,omitempty" yaml:"note_numbers"`
	Versions    Versions `json:"versions"               yaml:"versions"`

	// Filled in at response time:
	DisplayName string `json:"display_name,omitempty" yaml:"-"`
	FamilyGroup string `json:"family_group,omitempty" yaml:"-"`
}

Client is one mail-client/version row inside a rule's clients[]. The JSON shape (PascalCase-ish, snake_case keys) is what the SPA's HtmlCheckClient interface expects, so it's preserved exactly.

type FamilyReport

type FamilyReport struct {
	Family             string         `json:"family"`
	Label              string         `json:"label"`
	MarketShare        int            `json:"market_share"`
	SupportPercent     int            `json:"support_percent"`
	SupportPerCategory CategoryCounts `json:"support_per_category"`
	VersionCounts      CategoryCounts `json:"version_counts"`
}

FamilyReport mirrors HtmlCheckFamily on the SPA side.

type Issue

type Issue struct {
	RuleName      string            `json:"rule_name"`
	URL           string            `json:"url,omitempty"`
	ErrorLines    []int             `json:"error_lines"`
	Clients       []Client          `json:"clients"`
	NumberedNotes map[string]string `json:"numbered_notes"`
}

Issue is the per-rule report row the API returns. Builds during validation; merges multiple matches into one entry per rule.

type Report

type Report struct {
	Status               string         `json:"status"`
	MarketSupportPercent float64        `json:"market_support_percent"`
	Families             []FamilyReport `json:"families"`
	Issues               []Issue        `json:"issues"`
}

Report is the top-level shape returned by Service.Call.

func Run

func Run(htmlBody string) Report

Run is the package entrypoint: HTML body → Report.

Empty body returns {status: "no_html"}; everything else attempts a success report. Five-stage pipeline:

  1. Validate — run HTML XPath rules + inline-CSS rules; collect (line, rule) tuples.
  2. Group — merge multiple matches of the same rule into one Issue with a sorted ErrorLines list.
  3. Decorate — fill in client display names + family groups.
  4. Aggregate — compute per-family per-category support %.
  5. Roll up — market-share-weighted overall %.

type Rule

type Rule struct {
	Title         string            `yaml:"title"`
	ParserKey     string            `yaml:"parser_key"`  //nolint:tagliatelle // embedded yaml uses snake_case
	ParserType    string            `yaml:"parser_type"` //nolint:tagliatelle // embedded yaml uses snake_case
	URL           string            `yaml:"url"`
	Clients       []Client          `yaml:"clients"`
	NumberedNotes map[string]string `yaml:"numbered_notes"` //nolint:tagliatelle // embedded yaml uses snake_case
}

Rule is a single entry from html.yml or css.yml. ParserType selects the matching strategy; ParserKey is its argument.

type Versions

type Versions struct {
	Yes     []string `json:"yes,omitempty"     yaml:"yes"`
	No      []string `json:"no,omitempty"      yaml:"no"`
	Partial []string `json:"partial,omitempty" yaml:"partial"`
}

Versions is the {yes:[], no:[], partial:[]} block on each client.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL