leptris 1.9.222.0 → 1.9.222.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/leptris/html.rb +47 -0
- data/lib/leptris/vendor/aarch64-linux-musl/libleptris.so +0 -0
- data/lib/leptris/version.rb +1 -1
- data/lib/leptris/xml/document.rb +10 -0
- data/lib/leptris/xml/element.rb +7 -0
- data/lib/leptris/xml/html_serialize.rb +97 -0
- data/lib/leptris/xml.rb +1 -0
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: cf0ea790ec16e127a73ad58973fe745a6bd2c571cc410b6cb362e67491e985b0
|
|
4
|
+
data.tar.gz: a357e60e6bef11e695bc44ab3f20e6017acb015802aec4b263aca6453204085e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b08936fcefef29f5f550d59b67f563c76b116aa703037cd921402fd9eb7d162d16d865a9977c20ab0386a85daa7422fd5a25f803a94bec3c3e0a959610ddd9cc
|
|
7
|
+
data.tar.gz: da92ef6e730969414e48d33ee23f3b8e845bcad7413fdf78ef9a436188741503cfc050f123a61394de67ea51ce29d2aa43554599807d863642be534b800ce3d9
|
data/lib/leptris/html.rb
CHANGED
|
@@ -10,9 +10,15 @@
|
|
|
10
10
|
# Leptris::HTML(html) # the html4 lane (Nokogiri::HTML parity)
|
|
11
11
|
# Leptris::HTML5.parse(html) # the WHATWG engine (html5lib zero reds)
|
|
12
12
|
# Leptris::HTML4.parse(html) # explicit html4 lane
|
|
13
|
+
# Leptris::HTML5.create # fresh document, <!DOCTYPE html> preset
|
|
13
14
|
#
|
|
14
15
|
# These are pure delegates — no parallel class hierarchy, no second
|
|
15
16
|
# wrapper cache; identity and the whole XML surface carry over.
|
|
17
|
+
# Construction flows through the same face as XML (create_element,
|
|
18
|
+
# add_child, root=, set_doctype) — `create` presets the doctype so a
|
|
19
|
+
# programmatically built document serializes with it; pair with
|
|
20
|
+
# `to_xml(no_decl: true)` for declaration-free HTML output (void
|
|
21
|
+
# elements serialize with the HTML5-legal trailing slash).
|
|
16
22
|
module Leptris
|
|
17
23
|
module HTML
|
|
18
24
|
module_function
|
|
@@ -22,6 +28,37 @@ module Leptris
|
|
|
22
28
|
def parse(html)
|
|
23
29
|
Leptris::XML.parse_html(html, mode: :html4)
|
|
24
30
|
end
|
|
31
|
+
|
|
32
|
+
# Fresh document with the HTML 4.01 Transitional doctype preset
|
|
33
|
+
# (Nokogiri::HTML::Builder's .doc carries the same). Pass
|
|
34
|
+
# +doctype: nil+ for a bare document.
|
|
35
|
+
def create(doctype: :transitional, skeleton: true)
|
|
36
|
+
create_document(doctype, skeleton: skeleton)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def create_document(doctype, skeleton: true)
|
|
40
|
+
doc = Leptris::XML::Document.create
|
|
41
|
+
case doctype
|
|
42
|
+
when :html5, true
|
|
43
|
+
doc.set_doctype("html")
|
|
44
|
+
when :transitional
|
|
45
|
+
doc.set_doctype(
|
|
46
|
+
"HTML",
|
|
47
|
+
public_id: "-//W3C//DTD HTML 4.01 Transitional//EN",
|
|
48
|
+
system_id: "http://www.w3.org/TR/html4/loose.dtd")
|
|
49
|
+
when nil, false then nil
|
|
50
|
+
else raise ArgumentError,
|
|
51
|
+
"doctype must be :html5, :transitional, nil, or false, got #{doctype.inspect}"
|
|
52
|
+
end
|
|
53
|
+
return doc unless skeleton
|
|
54
|
+
html = doc.create_element("html")
|
|
55
|
+
head = doc.create_element("head")
|
|
56
|
+
body = doc.create_element("body")
|
|
57
|
+
html.add_child(head)
|
|
58
|
+
html.add_child(body)
|
|
59
|
+
doc.root = html
|
|
60
|
+
doc
|
|
61
|
+
end
|
|
25
62
|
end
|
|
26
63
|
|
|
27
64
|
module HTML4
|
|
@@ -30,6 +67,10 @@ module Leptris
|
|
|
30
67
|
def parse(html)
|
|
31
68
|
Leptris::XML.parse_html(html, mode: :html4)
|
|
32
69
|
end
|
|
70
|
+
|
|
71
|
+
def create(doctype: :transitional, skeleton: true)
|
|
72
|
+
Leptris::HTML.create_document(doctype, skeleton: skeleton)
|
|
73
|
+
end
|
|
33
74
|
end
|
|
34
75
|
|
|
35
76
|
module HTML5
|
|
@@ -41,5 +82,11 @@ module Leptris
|
|
|
41
82
|
def parse(html)
|
|
42
83
|
Leptris::XML.parse_html(html, mode: :whatwg)
|
|
43
84
|
end
|
|
85
|
+
|
|
86
|
+
# Fresh document with the HTML5 doctype (`<!DOCTYPE html>`)
|
|
87
|
+
# preset; pass +doctype: nil+ for a bare document.
|
|
88
|
+
def create(doctype: :html5, skeleton: true)
|
|
89
|
+
Leptris::HTML.create_document(doctype, skeleton: skeleton)
|
|
90
|
+
end
|
|
44
91
|
end
|
|
45
92
|
end
|
|
Binary file
|
data/lib/leptris/version.rb
CHANGED
data/lib/leptris/xml/document.rb
CHANGED
|
@@ -474,6 +474,16 @@ class Leptris::XML::Document
|
|
|
474
474
|
alias_method :to_s, :to_xml
|
|
475
475
|
alias_method :serialize, :to_xml
|
|
476
476
|
|
|
477
|
+
# HTML5 serialization (#309): void elements without a trailing
|
|
478
|
+
# slash (`<br>`), script/style content as raw text, text/attr
|
|
479
|
+
# entity escaping per HTML rules, the DOCTYPE emitted first.
|
|
480
|
+
# Walks the tree in Ruby — the engine-side serialization mode is
|
|
481
|
+
# the perf headroom this face gates on.
|
|
482
|
+
def to_html
|
|
483
|
+
raise Leptris::XML::UseAfterFreeError if @freed.state == :freed
|
|
484
|
+
Leptris::XML::HTMLSerialize.document(self)
|
|
485
|
+
end
|
|
486
|
+
|
|
477
487
|
def save(path, **opts)
|
|
478
488
|
opts_struct, _encoding_anchor = Leptris::XML::Serialization.build_options(
|
|
479
489
|
indent: opts.fetch(:indent, 0),
|
data/lib/leptris/xml/element.rb
CHANGED
|
@@ -756,6 +756,13 @@ class Leptris::XML::Element < Leptris::XML::Node
|
|
|
756
756
|
indent: indent, no_decl: no_decl, encoding: encoding)
|
|
757
757
|
end
|
|
758
758
|
|
|
759
|
+
# HTML5 serialization of this element subtree (#309 — see
|
|
760
|
+
# Document#to_html for the semantics).
|
|
761
|
+
def to_html
|
|
762
|
+
ensure_alive!
|
|
763
|
+
Leptris::XML::HTMLSerialize.element(self)
|
|
764
|
+
end
|
|
765
|
+
|
|
759
766
|
def canonicalize(version = Leptris::XML::FFI::C14N_1_0,
|
|
760
767
|
inclusive_namespaces = nil,
|
|
761
768
|
with_comments: false,
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# The HTML5 tree serializer (#309): Ruby-level walk emitting
|
|
4
|
+
# HTML serialization semantics the XML face can't express —
|
|
5
|
+
#
|
|
6
|
+
# - VOID elements (br, meta, img, …) emit without the trailing
|
|
7
|
+
# slash and without a closing tag (`<br>`, `<meta charset="utf-8">`)
|
|
8
|
+
# - script/style content is RAW TEXT — emitted verbatim, never
|
|
9
|
+
# entity-escaped (`a > b` stays `a > b` inside `<style>`)
|
|
10
|
+
# - childless non-void elements get explicit closing tags
|
|
11
|
+
# (`<div></div>`, never `<div/>`)
|
|
12
|
+
# - text escapes &, <, > (and U+00A0 as ); attributes escape
|
|
13
|
+
# &, ", <, >
|
|
14
|
+
#
|
|
15
|
+
# `Document#to_html` / `Element#to_html` are one-line delegates.
|
|
16
|
+
# The walk is Ruby-level by design for now — the engine-side
|
|
17
|
+
# serialization mode (raw-text + void handling in C) is the
|
|
18
|
+
# perf headroom this face gates on.
|
|
19
|
+
module Leptris::XML::HTMLSerialize
|
|
20
|
+
VOID = %w[
|
|
21
|
+
area base br col embed hr img input link meta param source
|
|
22
|
+
track wbr
|
|
23
|
+
].freeze
|
|
24
|
+
RAW_TEXT = %w[script style].freeze
|
|
25
|
+
|
|
26
|
+
def self.document(doc)
|
|
27
|
+
out = +""
|
|
28
|
+
if (dt = doc.doctype)
|
|
29
|
+
out << "<!DOCTYPE" << " #{dt.name}"
|
|
30
|
+
out << " PUBLIC \"#{dt.public_id}\"" if dt.public_id
|
|
31
|
+
out << " \"#{dt.system_id}\"" if dt.system_id
|
|
32
|
+
out << ">"
|
|
33
|
+
end
|
|
34
|
+
doc.children.each { |child| node(child, out) }
|
|
35
|
+
out
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def self.element(element)
|
|
39
|
+
out = +""
|
|
40
|
+
node(element, out)
|
|
41
|
+
out
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def self.node(node, out)
|
|
45
|
+
case node
|
|
46
|
+
when Leptris::XML::Element then element_node(node, out)
|
|
47
|
+
when Leptris::XML::Comment then out << "<!--" << node.content.to_s << "-->"
|
|
48
|
+
when Leptris::XML::CDATA
|
|
49
|
+
# HTML5: CDATA sections in HTML serialize as bogus comments.
|
|
50
|
+
out << "<!--[CDATA[" << node.content.to_s << "]]-->"
|
|
51
|
+
when Leptris::XML::ProcessingInstruction
|
|
52
|
+
# HTML5: PIs serialize as bogus comments (?> is not a thing).
|
|
53
|
+
out << "<?" << node.target.to_s
|
|
54
|
+
out << " " << node.data.to_s unless node.data.to_s.empty?
|
|
55
|
+
out << ">"
|
|
56
|
+
when Leptris::XML::Text then text(node, out)
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def self.element_node(el, out)
|
|
61
|
+
name = el.name
|
|
62
|
+
out << "<" << name
|
|
63
|
+
el.attributes.each do |attr_name, attr|
|
|
64
|
+
out << " " << attr_name << "=\"" << escape_attr(attr.value) << "\""
|
|
65
|
+
end
|
|
66
|
+
out << ">"
|
|
67
|
+
return if VOID.include?(name)
|
|
68
|
+
|
|
69
|
+
if RAW_TEXT.include?(name)
|
|
70
|
+
# Raw text: the element's text content verbatim — no entity
|
|
71
|
+
# escaping (CSS child selectors, JS comparisons survive).
|
|
72
|
+
el.children.each do |child|
|
|
73
|
+
out << child.content.to_s if child.is_a?(Leptris::XML::Text)
|
|
74
|
+
end
|
|
75
|
+
else
|
|
76
|
+
el.children.each { |child| node(child, out) }
|
|
77
|
+
end
|
|
78
|
+
out << "</" << name << ">"
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def self.text(node, out)
|
|
82
|
+
parent_raw = node.parent && RAW_TEXT.include?(node.parent.name)
|
|
83
|
+
s = node.content.to_s
|
|
84
|
+
out << (parent_raw ? s : escape_text(s))
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def self.escape_text(s)
|
|
88
|
+
s.gsub("&", "&").gsub("<", "<").gsub(">", ">")
|
|
89
|
+
.gsub("\u00A0", " ")
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def self.escape_attr(s)
|
|
93
|
+
s.to_s.gsub("&", "&").gsub("\"", """)
|
|
94
|
+
.gsub("<", "<").gsub(">", ">")
|
|
95
|
+
.gsub("\u00A0", " ")
|
|
96
|
+
end
|
|
97
|
+
end
|
data/lib/leptris/xml.rb
CHANGED
|
@@ -21,6 +21,7 @@ module Leptris
|
|
|
21
21
|
autoload :CssToXPath, "leptris/xml/css_to_xpath"
|
|
22
22
|
autoload :CStringArray, "leptris/xml/c_string_array"
|
|
23
23
|
autoload :Serialization, "leptris/xml/serialization"
|
|
24
|
+
autoload :HTMLSerialize, "leptris/xml/html_serialize"
|
|
24
25
|
autoload :SAX, "leptris/xml/sax"
|
|
25
26
|
autoload :XPath, "leptris/xml/xpath"
|
|
26
27
|
autoload :EvaluationContext, "leptris/xml/evaluation_context"
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: leptris
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.9.222.
|
|
4
|
+
version: 1.9.222.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose Inc.
|
|
@@ -179,6 +179,7 @@ files:
|
|
|
179
179
|
- lib/leptris/xml/entity_reference.rb
|
|
180
180
|
- lib/leptris/xml/evaluation_context.rb
|
|
181
181
|
- lib/leptris/xml/ffi.rb
|
|
182
|
+
- lib/leptris/xml/html_serialize.rb
|
|
182
183
|
- lib/leptris/xml/iteration_scope.rb
|
|
183
184
|
- lib/leptris/xml/iterparse.rb
|
|
184
185
|
- lib/leptris/xml/namespace.rb
|