Combo.SafeHTML (combo v0.8.0)

View Source

Provides HTML safety utilities.

Its main functionality is to provide convenience functions for:

  • escaping HTML as iodata.
  • marking escaped HTML as safe tuple.
  • converting escaped iodata or safe tuple into string.
  • ...

Summary

Types

Guaranteed to be safe.

May be safe or unsafe. To use it safely, conversion is required.

Functions

Escapes given string for use as HTML content.

Escapes a term as the key of an attribute.

Escapes a term as the value of an attribute.

Escapes an enumerable of attributes, returning iodata.

Converts a safe into a string.

Converts arbitrary data into escaped iodata.

Converts unsafe into safe.

Types

safe()

@type safe() :: {:safe, iodata()}

Guaranteed to be safe.

unsafe()

@type unsafe() :: Combo.SafeHTML.Safe.t()

May be safe or unsafe. To use it safely, conversion is required.

Functions

escape(string)

@spec escape(String.t()) :: String.t()

Escapes given string for use as HTML content.

Examples

iex> escape("hello")
"hello"

iex> escape("<hello>")
[[[], "&lt;"], "hello", "&gt;"]

escape_attr_key(term)

@spec escape_attr_key(term()) :: iodata()

Escapes a term as the key of an attribute.

escape_attr_value(term)

@spec escape_attr_value(term()) :: iodata()

Escapes a term as the value of an attribute.

escape_attrs(list_or_map)

@spec escape_attrs([{term(), term()}] | map()) :: iodata()

Escapes an enumerable of attributes, returning iodata.

The attributes are rendered in the given order. Note if a map is given, the key ordering is not guaranteed.

The keys and values can be of any shape, as long as they implement the Combo.SafeHTML.Safe protocol.

Additionally, there are values which have special meanings when they are used as the values of tag attributes:

  • if a value is true, the attribute is treated as boolean attribute, and it will be rendered with no value at all.

  • if a value is false or nil, the attribute is treated as boolean attribute, and it won't be rendered at all.

Examples

iex> IO.iodata_to_binary escape_attrs(title: "the title", id: "the id")
" title=\"the title\" id=\"the id\""

iex> IO.iodata_to_binary escape_attrs(selected: true)
" selected"

iex> IO.iodata_to_binary escape_attrs(hidden: false)
""

safe_to_string(safe)

@spec safe_to_string(safe()) :: String.t()

Converts a safe into a string.

Fails if the result is not safe. In such cases, you can invoke to_safe/1 or raw/1 accordingly.

You can combine to_safe/1 and safe_to_string/1 to convert a data structure to an escaped string:

data |> to_safe() |> safe_to_string()

to_iodata(data)

@spec to_iodata(term()) :: iodata()

Converts arbitrary data into escaped iodata.

Examples

iex> to_iodata("<hello>")
[[[], "&lt;"], "hello", "&gt;"]

iex> to_iodata(~c"<hello>")
["&lt;", 104, 101, 108, 108, 111, "&gt;"]

iex> to_iodata(1)
"1"

iex> to_iodata({:safe, "<hello>"})
"<hello>"

to_safe(safe)

@spec to_safe(unsafe()) :: safe()

Converts unsafe into safe.

Examples

iex> to_safe("<hello>")
{:safe, [[[], "&lt;"], "hello", "&gt;"]}

iex> to_safe(~c"<hello>")
{:safe, ["&lt;", 104, 101, 108, 108, 111, "&gt;"]}

iex> to_safe(1)
{:safe, "1"}

iex> to_safe({:safe, "<hello>"})
{:safe, "<hello>"}