Drafter.Style.StylesheetLoader (drafter v0.3.2)

Copy Markdown View Source

Loads and caches the stylesheet an app renders against.

A singleton GenServer registered under this module's name. It assembles an app's stylesheet from the built-in widget defaults, the app's CSS file and the app's inline rules, and holds the result so that later renders do not re-read the file.

How an app declares its styles

An app module may export either or both of:

  • __css_path__/0 — path to a CSS file, parsed by Drafter.Style.CSSParser. Returning nil contributes nothing.
  • __inline_styles__/0 — map of %{selector => style} added rule by rule.

A file is layered over the defaults and inline rules over the file, so an inline rule wins a specificity tie against a rule from the CSS file. An app exporting only __inline_styles__/0 skips the file step entirely.

Caching

Results are cached per app module and per file path, and only clear_cache/0 discards them. Editing a CSS file after it has been loaded has no effect until the cache is cleared.

load_inline/1 neither reads the cache nor writes to it.

Summary

Types

Cache key: an app module's assembled sheet, or one parsed CSS file.

Functions

Returns a specification to start this module under a supervisor.

Discard every cached stylesheet, so the next load re-reads and re-parses.

Parse the CSS file at file_path on its own, with no default rules merged in.

The default stylesheet with styles added on top.

The stylesheet for app_module, as {:ok, stylesheet}.

Start the loader, registered under this module's name.

Types

stylesheet_key()

@type stylesheet_key() :: {:app, module()} | {:file, String.t()}

Cache key: an app module's assembled sheet, or one parsed CSS file.

Functions

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

clear_cache()

@spec clear_cache() :: :ok

Discard every cached stylesheet, so the next load re-reads and re-parses.

Clears both the per-app and the per-file entries. Does not clear the built-in defaults, which Drafter.Style.WidgetStyles.clear_cache/0 handles.

load_from_file(file_path)

@spec load_from_file(Path.t()) ::
  {:ok, Drafter.Style.Stylesheet.t()} | {:error, String.t()}

Parse the CSS file at file_path on its own, with no default rules merged in.

Returns {:ok, stylesheet}, or {:error, reason} when the file cannot be read or parsed. Successful results are cached per path until clear_cache/0; a failure is not cached and is retried on the next call.

load_inline(styles)

@spec load_inline(map()) :: Drafter.Style.Stylesheet.t()

The default stylesheet with styles added on top.

styles maps a selector — a string such as "button:focus", or a widget-type atom — to a map of style properties. Rules are added in map iteration order and the result is not cached. Runs in the calling process, so the loader need not be running.

Returns the stylesheet itself, not an {:ok, _} tuple.

load_stylesheet(app_module)

@spec load_stylesheet(module()) :: {:ok, Drafter.Style.Stylesheet.t()}

The stylesheet for app_module, as {:ok, stylesheet}.

Built from Drafter.Style.WidgetStyles.default_stylesheet/0, then the CSS file named by the app's __css_path__/0 if it exports one, then the rules of its __inline_styles__/0 if it exports one, each layer added after the last. An app exporting neither gets the default stylesheet alone.

A CSS file that cannot be read or parsed contributes nothing. The result is cached per app module until clear_cache/0, so later edits to the CSS file are not picked up.

Never returns an error: an app that cannot be loaded from still yields the default stylesheet.

start_link(opts \\ [])

@spec start_link(keyword()) :: GenServer.on_start()

Start the loader, registered under this module's name.

opts are passed to init/1, which ignores them. Starting a second one fails with {:error, {:already_started, pid}}.