Current section

86 Versions

Jump to

Compare versions

7 files changed
+26 additions
-17 deletions
  @@ -27,4 +27,4 @@
27 27 {<<"name">>,<<"mochiweb">>},
28 28 {<<"optional">>,false},
29 29 {<<"requirement">>,<<"~> 2.15">>}]]}.
30 - {<<"version">>,<<"0.17.0">>}.
30 + {<<"version">>,<<"0.17.1">>}.
  @@ -58,12 +58,8 @@ defmodule Floki.Finder do
58 58
59 59 defp get_selectors(selector_as_string) do
60 60 selector_as_string
61 - |> String.split(~r/,(?![^(]*\))/i)
62 - |> Enum.map(fn(s) ->
63 - tokens = SelectorTokenizer.tokenize(s)
64 -
65 - SelectorParser.parse(tokens)
66 - end)
61 + |> SelectorTokenizer.tokenize()
62 + |> SelectorParser.parse()
67 63 end
68 64
69 65 defp get_matches_for_selectors(tree, html_node, selectors) do
  @@ -97,8 +97,10 @@ defmodule Floki.HTMLTree do
97 97 defp get_ids_for_delete_stack(_), do: []
98 98
99 99 defp build_tree(tree, [], _, []), do: tree
100 + defp build_tree(tree, [{:pi, _, _} | children], parent_id, stack), do: build_tree(tree, children, parent_id, stack)
100 101 defp build_tree(tree, [{tag, attrs, child_children} | children], parent_id, stack) do
101 102 new_id = IDSeeder.seed(tree.node_ids)
103 +
102 104 new_node = %HTMLNode{type: tag,
103 105 attributes: attrs,
104 106 node_id: new_id,
  @@ -106,7 +108,7 @@ defmodule Floki.HTMLTree do
106 108
107 109 nodes = put_new_node(tree.nodes, new_node)
108 110
109 - build_tree(%{tree | nodes: nodes, node_ids: [new_id | tree.node_ids]},
111 + build_tree(%{tree | nodes: nodes, node_ids: [new_id | tree.node_ids]},
110 112 child_children, new_id, [{parent_id, children} | stack])
111 113 end
112 114 defp build_tree(tree, [{:comment, comment} | children], parent_id, stack) do
  @@ -43,6 +43,7 @@ defmodule Floki.Selector do
43 43
44 44 defp id_match?(_node, nil), do: true
45 45 defp id_match?(%HTMLNode{attributes: []}, _), do: false
46 + defp id_match?(%HTMLNode{type: :pi}, _), do: false
46 47 defp id_match?(%HTMLNode{attributes: attributes}, id) do
47 48 Enum.any? attributes, fn(attribute) ->
48 49 case attribute do
  @@ -72,6 +73,7 @@ defmodule Floki.Selector do
72 73 tp == type
73 74 [tp] ->
74 75 tp == type
76 + _ -> false
75 77 end
76 78 end
77 79 defp type_match?(_, _), do: false
  @@ -9,18 +9,27 @@ defmodule Floki.SelectorParser do
9 9
10 10 @attr_match_types [:equal, :dash_match, :includes, :prefix_match, :sufix_match, :substring_match]
11 11
12 - # Returns a `Selector` struct with the parsed selector.
13 - # Note that this parser does not deal with groups of selectors.
12 + # Returns a list of `Selector` structs with the parsed selectors.
14 13
15 14 def parse(selector) when is_binary(selector) do
16 15 token_list = SelectorTokenizer.tokenize(selector)
17 16 parse(token_list)
18 17 end
19 18 def parse(tokens) do
20 - do_parse(tokens, %Selector{})
19 + do_parse_all(tokens, [])
21 20 end
22 21
23 - defp do_parse([], selector), do: selector
22 + defp do_parse_all([], selectors) do
23 + Enum.reverse(selectors)
24 + end
25 +
26 + defp do_parse_all(tokens, selectors) do
27 + {selector, remaining_tokens} = do_parse(tokens, %Selector{})
28 + do_parse_all(remaining_tokens, [selector | selectors])
29 + end
30 +
31 + defp do_parse([], selector), do: {selector, []}
32 + defp do_parse([{:comma, _}| t], selector), do: {selector, t}
24 33 defp do_parse([{:identifier, _, namespace}, {:namespace_pipe, _} | t], selector) do
25 34 do_parse(t, %{selector | namespace: to_string(namespace)})
26 35 end
  @@ -133,9 +142,9 @@ defmodule Floki.SelectorParser do
133 142 end
134 143 defp consume_combinator([], combinator), do: {[], combinator}
135 144 defp consume_combinator(tokens, combinator) do
136 - selector = parse(tokens)
145 + {selector, remaining_tokens} = do_parse(tokens, %Selector{})
137 146
138 - {[], %{combinator | selector: selector}}
147 + {remaining_tokens, %{combinator | selector: selector}}
139 148 end
140 149
141 150 defp do_parse_pseudo_not([{:close_parentesis, _} | t], pseudo_class) do
  @@ -159,7 +168,7 @@ defmodule Floki.SelectorParser do
159 168 do_parse_pseudo_not(t, pseudo_not_selector, pseudo_class)
160 169 end
161 170 defp do_parse_pseudo_not([next_token | t], pseudo_not_selector, pseudo_class) do
162 - pseudo_not_selector = do_parse([next_token], pseudo_not_selector)
171 + {pseudo_not_selector, _} = do_parse([next_token], pseudo_not_selector)
163 172 do_parse_pseudo_not(t, pseudo_not_selector, pseudo_class)
164 173 end
Loading more files…