Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow custom elements #74

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 66 additions & 48 deletions lib/htmlbeautifier/html_parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,58 +5,76 @@
module HtmlBeautifier
class HtmlParser < Parser
ELEMENT_CONTENT = %r{ (?:<%.*?%>|[^>])* }mx
HTML_VOID_ELEMENTS = %r{(?:
area | base | br | col | command | embed | hr | img | input | keygen |
link | meta | param | source | track | wbr
)}mix
HTML_BLOCK_ELEMENTS = %r{(?:
address | article | aside | audio | blockquote | canvas | dd | details |
dir | div | dl | dt | fieldset | figcaption | figure | footer | form |
h1 | h2 | h3 | h4 | h5 | h6 | header | hr | li | menu | noframes |
noscript | ol | p | pre | section | table | tbody | td | tfoot | th |
thead | tr | ul | video
)}mix

MAPPINGS = [
[%r{(<%-?=?)(.*?)(-?%>)}om,
:embed],
[%r{<!--\[.*?\]>}om,
:open_ie_cc],
[%r{<!\[.*?\]-->}om,
:close_ie_cc],
[%r{<!--.*?-->}om,
:standalone_element],
[%r{<!.*?>}om,
:standalone_element],
[%r{(<script#{ELEMENT_CONTENT}>)(.*?)(</script>)}omi,
:foreign_block],
[%r{(<style#{ELEMENT_CONTENT}>)(.*?)(</style>)}omi,
:foreign_block],
[%r{(<pre#{ELEMENT_CONTENT}>)(.*?)(</pre>)}omi,
:preformatted_block],
[%r{(<textarea#{ELEMENT_CONTENT}>)(.*?)(</textarea>)}omi,
:preformatted_block],
[%r{<#{HTML_VOID_ELEMENTS}(?: #{ELEMENT_CONTENT})?/?>}om,
:standalone_element],
[%r{</#{HTML_BLOCK_ELEMENTS}>}om,
:close_block_element],
[%r{<#{HTML_BLOCK_ELEMENTS}(?: #{ELEMENT_CONTENT})?>}om,
:open_block_element],
[%r{</#{ELEMENT_CONTENT}>}om,
:close_element],
[%r{<#{ELEMENT_CONTENT}[^/]>}om,
:open_element],
[%r{<[\w\-]+(?: #{ELEMENT_CONTENT})?/>}om,
:standalone_element],
[%r{(\s*\r?\n\s*)+}om,
:new_lines],
[%r{[^<\n]+},
:text]
HTML_VOID_ELEMENTS = %w[
area base br col command embed hr img input keygen
link meta param source track wbr
]
HTML_BLOCK_ELEMENTS = %w[
address article aside audio blockquote canvas dd details
dir div dl dt fieldset figcaption figure footer form
h1 h2 h3 h4 h5 h6 header hr li menu noframes
noscript ol p pre section table tbody td tfoot th
thead tr ul video
].freeze

def self.void_elements
@void_elements ||= HTML_VOID_ELEMENTS.dup
end

def self.block_elements
@block_elements ||= HTML_BLOCK_ELEMENTS.dup
end

def self.void_elements_regexp
%r{(?:#{void_elements.join("|")})}mix
end

def self.block_elements_regexp
%r{(?:#{block_elements.join("|")})}mix
end

def self.mappings
[
[%r{(<%-?=?)(.*?)(-?%>)}om,
:embed],
[%r{<!--\[.*?\]>}om,
:open_ie_cc],
[%r{<!\[.*?\]-->}om,
:close_ie_cc],
[%r{<!--.*?-->}om,
:standalone_element],
[%r{<!.*?>}om,
:standalone_element],
[%r{(<script#{ELEMENT_CONTENT}>)(.*?)(</script>)}omi,
:foreign_block],
[%r{(<style#{ELEMENT_CONTENT}>)(.*?)(</style>)}omi,
:foreign_block],
[%r{(<pre#{ELEMENT_CONTENT}>)(.*?)(</pre>)}omi,
:preformatted_block],
[%r{(<textarea#{ELEMENT_CONTENT}>)(.*?)(</textarea>)}omi,
:preformatted_block],
[%r{<#{void_elements_regexp}(?: #{ELEMENT_CONTENT})?/?>}om,
:standalone_element],
[%r{</#{block_elements_regexp}>}om,
:close_block_element],
[%r{<#{block_elements_regexp}(?: #{ELEMENT_CONTENT})?>}om,
:open_block_element],
[%r{</#{ELEMENT_CONTENT}>}om,
:close_element],
[%r{<#{ELEMENT_CONTENT}[^/]>}om,
:open_element],
[%r{<[\w\-]+(?: #{ELEMENT_CONTENT})?/>}om,
:standalone_element],
[%r{(\s*\r?\n\s*)+}om,
:new_lines],
[%r{[^<\n]+},
:text]
]
end

def initialize
super do |p|
MAPPINGS.each do |regexp, method|
self.class.mappings.each do |regexp, method|
p.map regexp, method
end
end
Expand Down
20 changes: 20 additions & 0 deletions spec/behavior_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

require "htmlbeautifier"

HtmlBeautifier::HtmlParser.block_elements << "turbo-frame"

describe HtmlBeautifier do
it "ignores HTML fragments in embedded ERB" do
source = code <<~HTML
Expand Down Expand Up @@ -465,6 +467,24 @@
expect(described_class.beautify(source)).to eq(expected)
end

it "detects and add new lines ot custom block elements" do
source = code <<~HTML
<main><turbo-frame id="content" target="_top">
<div class="card"></div></turbo-frame>


</main>
HTML
expected = code <<~HTML
<main>
<turbo-frame id="content" target="_top">
<div class="card"></div>
</turbo-frame>
</main>
HTML
expect(described_class.beautify(source)).to eq(expected)
end

it "does not modify content of <textarea>" do
source = code <<~HTML
<div>
Expand Down