Packages
floki
0.9.0
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.ex
defmodule Floki.Selector do
@moduledoc """
Represents a CSS selector. It also have functions to match nodes with a given selector.
"""
alias Floki.Selector
alias Floki.AttributeSelector
defstruct id: nil, type: nil, classes: [], attributes: [], combinator: nil
@doc """
Returns if a given node matches with a given selector.
"""
def match?(_node, %Selector{id: nil, type: nil, classes: [], attributes: []}) do
false
end
def match?(nil, _selector), do: false
def match?({:comment, _comment}, _selector), do: false
def match?({:pi, _xml, _xml_attrs}, _selector), do: false
def match?(html_node, selector) do
id_match?(html_node, selector.id)
&& type_match?(html_node, selector.type)
&& classes_matches?(html_node, selector.classes)
&& attributes_matches?(html_node, selector.attributes)
end
defp id_match?(_node, nil), do: true
defp id_match?({_, [], _}, _), do: false
defp id_match?({_, attributes, _}, id) do
Enum.any? attributes, fn(attribute) ->
case attribute do
{"id", ^id} -> true
_ -> false
end
end
end
defp type_match?(_node, nil), do: true
defp type_match?({type, _, _}, type), do: true
defp type_match?({_type, _, _}, "*"), do: true
defp type_match?(_, _), do: false
defp classes_matches?(_node, []), do: true
defp classes_matches?({_, [], _}, _), do: false
defp classes_matches?({_, attributes, _}, classes) do
Enum.all? classes, fn(class) ->
selector = %AttributeSelector{match_type: :includes,
attribute: "class",
value: class}
AttributeSelector.match?(attributes, selector)
end
end
defp attributes_matches?(_node, []), do: true
defp attributes_matches?({_, [], _}, _), do: false
defp attributes_matches?({_, attributes, _}, attributes_selectors) do
Enum.all? attributes_selectors, fn(attribute_selector) ->
AttributeSelector.match?(attributes, attribute_selector)
end
end
end