cssom

package
v0.0.0-...-ada8b72 Latest Latest
Warning

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

Go to latest
Published: Nov 15, 2023 License: BSD-3-Clause Imports: 12 Imported by: 0

Documentation

Overview

Package cssom provides functionality for CSS styling.

Status

This is a very first draft. It is unstable and the API will change without notice. Please be patient.

Overview

HTMLbook is the core DOM of our documents. Background for this decision can be found under https://www.balisage.net/Proceedings/vol10/print/Kleinfeld01/BalisageVol10-Kleinfeld01.html and http://radar.oreilly.com/2013/09/html5-is-the-future-of-book-authorship.html For an in-depth description of HTMLbook please refer to https://oreillymedia.github.io/HTMLBook/.

We strive to separate content from presentation. In typesetting, this is probably an impossible claim, but we'll try anyway. Presentation is governed with CSS (Cascading Style Sheets). CSS uses a box model more complex than TeX's, which is well described here:

https://developer.mozilla.org/en-US/docs/Learn/CSS/Introduction_to_CSS/Box_model

If you think about it: a typesetter using the HTML/CSS box model is effectively a browser with output type PDF. Browsers are large and complex pieces of code, a fact that implies that we should seek out where to reduce complexity.

A good explanation of styling may be found in

https://hacks.mozilla.org/2017/08/inside-a-super-fast-css-engine-quantum-css-aka-stylo/

CSSOM is the "CSS Object Model", similar to the DOM for HTML. There is not very much open source Go code around for supporting us in implementing a styling engine, except the great work of https://godoc.org/github.com/andybalholm/cascadia. Therefore we will have to compromise on many feature in order to complete this in a realistic time frame.

This package relies on just one non-standard external library: cascadia. CSS handling is de-coupled by introducing appropriate interfaces StyleSheet and Rule. Concrete implementations may be found in sub-packages of package style.

Further to consider:

https://godoc.org/github.com/ericchiang/css
https://golanglibs.com/search?q=css+parser&sort=top
https://www.mediaevent.de/xhtml/style.html

The styling component is difficult to document/describe without diagrams. Think about documenting with https://github.com/robertkrimen/godocdown.

___________________________________________________________________________

License

Governed by a 3-Clause BSD license. License file may be found in the root folder of this module.

Copyright © 2017–2022 Norbert Pillmayer <norbert@pillmayer.com>

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type CSSOM

type CSSOM struct {
	// contains filtered or unexported fields
}

CSSOM is the "CSS Object Model", similar to the DOM for HTML. Our CSSOM consists of a set of stylesheets, each relevant for a sub-tree of the HTML parse tree. This sub-tree is called the "scope" of the stylesheet. Sub-trees are identified through the top node.

Stylesheets are wrapped into an internal rules tree.

func NewCSSOM

func NewCSSOM(additionalProperties []style.KeyValue) CSSOM

NewCSSOM creates an empty CSSOM. Clients are allowed to supply a map of additional/custom CSS property values. These may override values of the default ("user-agent") style sheet, or introduce completely new styling properties.

func (CSSOM) AddStylesForScope

func (cssom CSSOM) AddStylesForScope(scope *html.Node, css StyleSheet, source PropertySource) error

AddStylesForScope includes a stylesheet to a CSSOM and sets the scope for the stylesheet. If a stylesheet for the scope already exists, the styles are merged. css may be nil. If scope is nil then scope is the root (i.e., top-level content element) of a future document.

The stylsheet may not be nil. source hints to where the stylesheet comes from. Its value will affect the calculation of specifity for rules of this stylesheet.

Inline-styles will be handled on the fly, generating "mini-stylesheets" while walking the HTML parse tree. For `<style>`-elements, clients have to extract the styles in advance and wrap them into stylesheets.

func (CSSOM) RegisterCompoundSplitter

func (cssom CSSOM) RegisterCompoundSplitter(splitter CompoundPropertiesSplitter)

RegisterCompoundSplitter allows clients to handle additional compound properties. See type CompoundPropertiesSplitter.

func (CSSOM) Style

func (cssom CSSOM) Style(dom *html.Node) (*tree.Node[*styledtree.StyNode], error)

Style gets things rolling. It styles an HTML parse tree, referred to by the root node, and returns a tree of styled nodes. For an explanation what's going on here, refer to https://hacks.mozilla.org/2017/08/inside-a-super-fast-css-engine-quantum-css-aka-stylo/ and https://limpet.net/mbrubeck/2014/08/23/toy-layout-engine-4-style.html

If either dom or creator are nil, no tree is returned (but an error).

type CompoundPropertiesSplitter

type CompoundPropertiesSplitter func(string, style.Property) ([]style.KeyValue, error)

CompoundPropertiesSplitter splits compound properties into atomic properties. Compunt properties are properties which abbreviate the setting of more fine grained propertes. An example is

padding: 10px 20px

which sets the following detail properties:

padding-top:    10px
padding-right:  20px
padding-bottom: 10px
padding-left:   20px

Standard CSS compound properties are known by default, but clients are allowed to extend the set of compound properties.

type PropertySource

type PropertySource uint8

PropertySource denotes where CSS properties come from and therewith determines the specifity of properties. Properties may be defined at different places in HTML: as a sytlesheet reference link, within a <script> element in the HTML file, or in an attribute value.

PropertySource affects the specifity of rules: attribute values bind the closest, then come script elements within the HTML source, then external style sheets and finally global (user-agent level) default properties.

const (
	Global    PropertySource = iota + 1 // "browser" globals
	Author                              // CSS author (stylesheet link)
	Script                              // <script> element
	Attribute                           // in an element's attribute(s)
)

Values for property sources, used when adding style sheets.

type Rule

type Rule interface {
	Selector() string            // the prelude / selectors of the rule
	Properties() []string        // property keys, e.g. "margin-top"
	Value(string) style.Property // property value for key, e.g. "15px"
	IsImportant(string) bool     // is property key marked as important?
}

Rule is the type stylesheets consists of.

See interface StyleSheet.

type StyleSheet

type StyleSheet interface {
	AppendRules(StyleSheet) // append rules from another stylesheet
	Empty() bool            // does this stylesheet contain any rules?
	Rules() []Rule          // all the rules of a stylesheet
}

StyleSheet is an interface to abstract away a stylesheet-implementation. In order to de-couple implementations of CSS-stylesheets from the construction of the styled node tree, we introduce an interface for CSS stylesheets. Clients for the styling engine will have to provide a concrete implementation of this interface (e.g., see package douceuradapter).

Having this interface imposes a performance hit. However, this implementation of CSS-styling will never trade modularity and clarity for performance. Clients in need for a production grade browser engine (where performance is key) should opt for headless versions of the main browser projects.

See interface Rule.

Directories

Path Synopsis
Package douceuradapter is a concrete implementation of interface cssom.StyleSheet.
Package douceuradapter is a concrete implementation of interface cssom.StyleSheet.

Jump to

Keyboard shortcuts

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