Packages
floki
0.19.1
0.38.4
0.38.3
0.38.2
0.38.1
0.38.0
0.37.1
0.37.0
0.36.3
0.36.2
0.36.1
0.36.0
0.35.4
0.35.3
0.35.2
0.35.1
0.35.0
0.34.3
0.34.2
0.34.1
0.34.0
0.33.1
0.33.0
0.32.1
0.32.0
0.31.0
0.30.1
0.30.0
0.29.0
0.28.0
0.27.0
0.26.0
0.25.0
0.24.0
0.23.1
0.23.0
0.22.0
0.21.0
0.20.4
0.20.3
0.20.2
0.20.1
0.20.0
0.19.3
0.19.2
0.19.1
0.19.0
0.18.1
0.18.0
0.17.2
0.17.1
0.17.0
0.16.0
0.15.0
0.14.0
0.13.2
0.13.1
0.13.0
0.12.1
0.12.0
0.11.0
0.10.1
0.10.0
0.9.0
0.8.1
0.8.0
0.7.2
0.7.1
0.7.0
0.6.1
0.6.0
0.5.0
0.4.1
0.4.0
0.3.3
0.3.2
0.3.1
0.3.0
0.2.1
0.2.0
0.1.1
0.1.0
0.0.5
0.0.4
0.0.3
0.0.2
0.0.1
Floki is a simple HTML parser that enables search for nodes using CSS selectors.
Current section
Files
Jump to
Current section
Files
lib/floki/selector/attribute_selector.ex
defmodule Floki.Selector.AttributeSelector do
@moduledoc false
# It is very similar to the `Selector` module, but is specialized in attributes
# and attribute selectors.
alias Floki.Selector.AttributeSelector
defstruct match_type: nil, attribute: nil, value: nil
defimpl String.Chars do
def to_string(selector) do
"[#{selector.attribute}#{type(selector.match_type)}'#{selector.value}']"
end
defp type(match_type) do
case match_type do
:equal -> "="
:includes -> "~="
:dash_match -> "|="
:prefix_match -> "^="
:sufix_match -> "$="
:substring_match -> "*="
_ -> ""
end
end
end
# Returns if attributes of a node matches with a given attribute selector.
def match?(attributes, s = %AttributeSelector{match_type: nil, value: nil}) do
attribute_present?(s.attribute, attributes)
end
def match?(attributes, s = %AttributeSelector{match_type: :equal}) do
get_value(s.attribute, attributes) == s.value
end
def match?(attributes, s = %AttributeSelector{match_type: :includes}) do
value = get_value(s.attribute, attributes)
whitespace_values = String.split(value, " ")
Enum.any?(whitespace_values, fn v -> v == s.value end)
end
def match?(attributes, s = %AttributeSelector{match_type: :dash_match}) do
value = get_value(s.attribute, attributes)
value == s.value || String.starts_with?(value, "#{s.value}-")
end
def match?(attributes, s = %AttributeSelector{match_type: :prefix_match}) do
s.attribute |> get_value(attributes) |> String.starts_with?(s.value)
end
def match?(attributes, s = %AttributeSelector{match_type: :sufix_match}) do
s.attribute |> get_value(attributes) |> String.ends_with?(s.value)
end
def match?(attributes, s = %AttributeSelector{match_type: :substring_match}) do
s.attribute |> get_value(attributes) |> String.contains?(s.value)
end
defp get_value(attr_name, attributes) do
{_attr_name, value} =
Enum.find(attributes, {attr_name, ""}, fn {k, _v} ->
k == attr_name
end)
value
end
defp attribute_present?(name, attributes) do
Enum.any?(attributes, fn {k, _v} -> k == name end)
end
end