defmodule OeditusCredo.Check.Warning.InlineJavascript do
use Credo.Check,
base_priority: :normal,
category: :warning,
explanations: [
check: """
Avoid inline JavaScript event handlers in LiveView templates.
Use phx-* bindings instead of onclick, onchange, etc.
Bad:
Good:
""",
params: []
]
@inline_js_attrs ["onclick", "onchange", "onkeyup", "onkeydown", "onsubmit", "onload"]
@doc false
@impl true
def run(%SourceFile{} = source_file, params) do
issue_meta = IssueMeta.for(source_file, params)
if heex_file?(source_file) do
source_file
|> Credo.Code.to_lines()
|> check_for_inline_js(issue_meta)
else
[]
end
end
defp heex_file?(%SourceFile{filename: filename}) do
String.ends_with?(filename, [".heex", ".leex"])
end
defp check_for_inline_js(lines, issue_meta) do
lines
|> Enum.with_index(1)
|> Enum.flat_map(fn {{_, line}, line_no} ->
if has_inline_js?(line) do
[issue_for(issue_meta, line_no)]
else
[]
end
end)
end
defp has_inline_js?(line) do
Enum.any?(@inline_js_attrs, fn attr ->
String.contains?(line, attr <> "=")
end)
end
defp issue_for(issue_meta, line_no) do
format_issue(
issue_meta,
message: "Use phx-* bindings instead of inline JavaScript event handlers",
trigger: "onclick",
line_no: line_no
)
end
end