Current section

86 Versions

Jump to

Compare versions

9 files changed
+134 additions
-93 deletions
  @@ -15,9 +15,9 @@ Documentation is a very important portion of software. We want to always improve
15 15 ### Ideas
16 16
17 17 To contribute with ideas, you can [open issues](https://github.com/philss/floki/issues/new) using Github. Please write a clear description of
18 - what you want to propouse, along with a motivation and examples.
18 + what you want to propose, along with a motivation and examples.
19 19
20 - This can make the project very rich, even if your propouse is not accepted. It worth the discussion and possible implementations.
20 + This can make the project very rich, even if your proposal is not accepted. It worth the discussion and possible implementations.
21 21
22 22 ### Code
  @@ -60,13 +60,15 @@ Add Floki to your `mix.exs`:
60 60 ```elixir
61 61 defp deps do
62 62 [
63 - {:floki, "~> 0.26.0"}
63 + {:floki, "~> 0.27.0"}
64 64 ]
65 65 end
66 66 ```
67 67
68 68 After that, run `mix deps.get`.
69 69
70 + You can check the [change log](https://github.com/philss/floki/blob/master/CHANGELOG.md) for changes.
71 +
70 72 ## Dependencies
71 73
72 74 Floki needs the `leex` module in order to compile.
  @@ -113,7 +115,7 @@ After Rust is set up, you need to add `html5ever` NIF to your dependency list:
113 115 ```elixir
114 116 defp deps do
115 117 [
116 - {:floki, "~> 0.26.0"},
118 + {:floki, "~> 0.27.0"},
117 119 {:html5ever, "~> 0.7.0"}
118 120 ]
119 121 end
  @@ -145,7 +147,7 @@ First, add `fast_html` to your dependencies:
145 147 ```elixir
146 148 defp deps do
147 149 [
148 - {:floki, "~> 0.26.0"},
150 + {:floki, "~> 0.27.0"},
149 151 {:fast_html, "~> 1.0"}
150 152 ]
151 153 end
  @@ -32,4 +32,4 @@
32 32 {<<"optional">>,false},
33 33 {<<"repository">>,<<"hexpm">>},
34 34 {<<"requirement">>,<<"~> 0.5.0">>}]]}.
35 - {<<"version">>,<<"0.26.0">>}.
35 + {<<"version">>,<<"0.27.0">>}.
  @@ -61,11 +61,13 @@ defmodule Floki do
61 61 inside a list.
62 62 """
63 63
64 + @type html_declaration :: {:pi, String.t(), [html_attribute()]}
64 65 @type html_comment :: {:comment, String.t()}
65 66 @type html_doctype :: {:doctype, String.t(), String.t(), String.t()}
66 67 @type html_attribute :: {String.t(), String.t()}
67 68 @type html_tag :: {String.t(), [html_attribute()], [html_tag() | String.t() | html_comment()]}
68 - @type html_tree :: [html_comment() | html_doctype() | html_tag()]
69 + @type html_node :: html_comment() | html_doctype() | html_tag() | html_declaration()
70 + @type html_tree :: [html_node()]
69 71
70 72 @doc """
71 73 Parses a HTML Document from a String.
  @@ -166,13 +168,13 @@ defmodule Floki do
166 168
167 169 ## Examples
168 170
169 - iex> Floki.raw_html({:div, [class: "wrapper"], ["my content"]})
171 + iex> Floki.raw_html({"div", [{"class", "wrapper"}], ["my content"]})
170 172 ~s(<div class="wrapper">my content</div>)
171 173
172 - iex> Floki.raw_html({:div, [class: "wrapper"], ["10 > 5"]}, encode: true)
174 + iex> Floki.raw_html({"div", [{"class", "wrapper"}], ["10 > 5"]}, encode: true)
173 175 ~s(<div class="wrapper">10 &gt; 5</div>)
174 176
175 - iex> Floki.raw_html({:div, [class: "wrapper"], ["10 > 5"]}, encode: false)
177 + iex> Floki.raw_html({"div", [{"class", "wrapper"}], ["10 > 5"]}, encode: false)
176 178 ~s(<div class="wrapper">10 > 5</div>)
177 179 """
178 180
  @@ -326,7 +328,8 @@ defmodule Floki do
326 328 Traverses and updates a HTML tree structure.
327 329
328 330 This function returns a new tree structure that is the result of applying the
329 - given `fun` on all nodes.
331 + given `fun` on all nodes. The tree is traversed in a post-walk fashion, where
332 + the children are traversed before the parent.
330 333
331 334 The function `fun` receives a tuple with `{name, attributes, children}`, and
332 335 should either return a similar tuple or `nil` to delete the current node.
  @@ -347,7 +350,7 @@ defmodule Floki do
347 350 {"div", [], []}
348 351 """
349 352
350 - @spec traverse_and_update(html_tree(), (html_tag() -> html_tag() | nil)) :: html_tree()
353 + @spec traverse_and_update(html_tree(), (html_node() -> html_node() | nil)) :: html_tree()
351 354
352 355 defdelegate traverse_and_update(html_tree, fun), to: Floki.Traversal
353 356
  @@ -355,7 +358,9 @@ defmodule Floki do
355 358 Traverses and updates a HTML tree structure with an accumulator.
356 359
357 360 This function returns a new tree structure and the final value of accumulator
358 - which are the result of applying the given `fun` on all nodes.
361 + which are the result of applying the given `fun` on all nodes. The tree is
362 + traversed in a post-walk fashion, where the children are traversed before
363 + the parent.
359 364
360 365 The function `fun` receives a tuple with `{name, attributes, children}` and
361 366 an accumulator, and should return a 2-tuple like `{new_node, new_acc}`, where
  @@ -383,12 +388,12 @@ defmodule Floki do
383 388 {{"div", [], []}, [deleted: 1]}
384 389 """
385 390
386 - @type traverse_acc :: any()
387 391 @spec traverse_and_update(
388 392 html_tree(),
389 - traverse_acc(),
390 - (html_tag(), traverse_acc() -> {html_tag() | nil, traverse_acc()})
391 - ) :: {html_tree(), traverse_acc()}
393 + traverse_acc,
394 + (html_node(), traverse_acc -> {html_node() | nil, traverse_acc})
395 + ) :: {html_node(), traverse_acc}
396 + when traverse_acc: any()
392 397
393 398 defdelegate traverse_and_update(html_tree, acc, fun), to: Floki.Traversal
394 399
  @@ -454,8 +459,10 @@ defmodule Floki do
454 459 @doc """
455 460 Returns the direct child nodes of a HTML tree.
456 461
457 - By default, it will also include all texts. You can disable this behaviour
458 - by using the option `include_text` to `false`
462 + By default, it will also include all texts. You can disable
463 + this behaviour by using the option `include_text` to `false`.
464 +
465 + If the given node is not an HTML tag, then it returns nil.
459 466
460 467 ## Examples
461 468
  @@ -465,9 +472,12 @@ defmodule Floki do
465 472 iex> Floki.children({"div", [], ["text", {"span", [], []}]}, include_text: false)
466 473 [{"span", [], []}]
467 474
475 + iex> Floki.children({:comment, "comment"})
476 + nil
477 +
468 478 """
469 479
470 - @spec children(html_tree, Keyword.t()) :: html_tree
480 + @spec children(html_tree, Keyword.t()) :: html_tree | nil
471 481
472 482 def children(html, opts \\ [include_text: true]) do
473 483 case html do
  @@ -537,14 +547,18 @@ defmodule Floki do
537 547 Enum.reduce(
538 548 elements,
539 549 [],
540 - fn {_, attributes, _}, acc ->
541 - case attribute_match?(attributes, attr_name) do
542 - {_attr_name, value} ->
543 - [value | acc]
550 + fn
551 + {_, attributes, _}, acc ->
552 + case attribute_match?(attributes, attr_name) do
553 + {_attr_name, value} ->
554 + [value | acc]
544 555
545 - _ ->
546 - acc
547 - end
556 + _ ->
557 + acc
558 + end
559 +
560 + _, acc ->
561 + acc
548 562 end
549 563 )
550 564
  @@ -591,6 +605,9 @@ defmodule Floki do
591 605 iex> Floki.filter_out({"div", [], [{:comment, "comment"}, " text"]}, :comment)
592 606 {"div", [], [" text"]}
593 607
608 + iex> Floki.filter_out({"div", [], ["text"]}, :text)
609 + {"div", [], []}
610 +
594 611 """
595 612
596 613 @spec filter_out(binary | html_tree, FilterOut.selector()) :: list
  @@ -6,12 +6,12 @@ defmodule Floki.FilterOut do
6 6 # Helper functions for filtering out a specific element from the tree.
7 7
8 8 @type html_tree :: tuple | list
9 - @type selector :: :comment | Finder.selector()
9 + @type selector :: :comment | :text | Finder.selector()
10 10
11 11 @spec filter_out(html_tree, selector) :: tuple | list
12 12
13 - def filter_out(html_tree, :comment) do
14 - mapper(html_tree, :comment)
13 + def filter_out(html_tree, type) when type in [:text, :comment] do
14 + mapper(html_tree, type)
15 15 end
16 16
17 17 def filter_out(html_tree, selector) do
  @@ -49,6 +49,7 @@ defmodule Floki.FilterOut do
49 49
50 50 defp filter({nodetext, _, _}, selector) when nodetext === selector, do: false
51 51 defp filter({nodetext, _}, selector) when nodetext === selector, do: false
52 + defp filter(text, :text) when is_binary(text), do: false
52 53 defp filter(_, _), do: true
53 54
54 55 defp mapper(nodes, selector) when is_list(nodes) do
Loading more files…