squoosh 0.4.0 → 0.4.2
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/README.md +2 -2
- data/lib/squoosh/version.rb +1 -1
- data/lib/squoosh.rb +105 -103
- metadata +80 -13
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 45427ad6b7b51207967217770bff4da6dce268769f51117d031a330ca0eeed8f
|
|
4
|
+
data.tar.gz: 9d732e5924249a0cc4cd4b3c0540dfb15839b30a9ab3186cca659bd756b3a03c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c4cd2bbc234b4e65955d1ee4a59ab0fcf512875498b1369d4b536f16f9e590ee009a3971639abd37261325c2155e84cb936ffa8947c872088e2745ea7390e57c
|
|
7
|
+
data.tar.gz: 71d98388a6031b518903874fe19dfce2063e015ce986cd462666ebb5a34f9c292d66398b7729ff07eb17d04b1221c7bf88cc2622161de23036f6cd5417edf93b
|
data/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
[](https://github.com/stevecheckoway/squoosh/actions)
|
|
3
3
|
[](https://coveralls.io/github/stevecheckoway/squoosh?branch=main)
|
|
5
5
|
|
|
6
6
|
# Squoosh
|
|
7
7
|
|
data/lib/squoosh/version.rb
CHANGED
data/lib/squoosh.rb
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
4
|
-
require
|
|
5
|
-
require
|
|
6
|
-
require
|
|
7
|
-
require 'uglifier'
|
|
3
|
+
require "squoosh/version"
|
|
4
|
+
require "nokogiri"
|
|
5
|
+
require "sassc"
|
|
6
|
+
require "uglifier"
|
|
8
7
|
|
|
9
8
|
# @author Stephen Checkoway <s@pahtak.org>
|
|
10
9
|
# Minify HTML, JavaScript, and CSS.
|
|
@@ -67,7 +66,7 @@ module Squoosh
|
|
|
67
66
|
#
|
|
68
67
|
# @param options [Hash] options to override the default options
|
|
69
68
|
def initialize(options = {})
|
|
70
|
-
options.
|
|
69
|
+
options.each_key do |key|
|
|
71
70
|
unless DEFAULT_OPTIONS.include?(key)
|
|
72
71
|
raise ArgumentError, "Invalid option `#{key}'"
|
|
73
72
|
end
|
|
@@ -87,7 +86,7 @@ module Squoosh
|
|
|
87
86
|
# @return [String] the minified HTML
|
|
88
87
|
def minify_html(content)
|
|
89
88
|
doc = Nokogiri.HTML5(content)
|
|
90
|
-
return content unless doc
|
|
89
|
+
return content unless doc.internal_subset&.html5_dtd?
|
|
91
90
|
|
|
92
91
|
remove_comments(doc) if @options[:remove_comments]
|
|
93
92
|
compress_javascript(doc) if @options[:minify_javascript]
|
|
@@ -117,12 +116,11 @@ module Squoosh
|
|
|
117
116
|
|
|
118
117
|
# Element kinds
|
|
119
118
|
VOID_ELEMENTS = Set.new(%w[area base br col embed hr img input
|
|
120
|
-
|
|
119
|
+
keygen link meta param source track wbr]).freeze
|
|
121
120
|
RAW_TEXT_ELEMENTS = Set.new(%w[script style]).freeze
|
|
122
121
|
ESCAPABLE_RAW_TEXT_ELEMENTS = Set.new(%w[textarea title]).freeze
|
|
123
|
-
FOREIGN_ELEMENTS = Set.new(%w[math svg]).freeze
|
|
124
122
|
private_constant :VOID_ELEMENTS, :RAW_TEXT_ELEMENTS
|
|
125
|
-
private_constant :ESCAPABLE_RAW_TEXT_ELEMENTS
|
|
123
|
+
private_constant :ESCAPABLE_RAW_TEXT_ELEMENTS
|
|
126
124
|
|
|
127
125
|
INLINE_SCRIPT_OPTIONS = {
|
|
128
126
|
output: {
|
|
@@ -146,7 +144,8 @@ module Squoosh
|
|
|
146
144
|
end
|
|
147
145
|
|
|
148
146
|
def foreign_element?(node)
|
|
149
|
-
|
|
147
|
+
return false unless node.type == Nokogiri::XML::Node::ELEMENT_NODE
|
|
148
|
+
!node.namespace.nil? && node.namespace.href != "http://www.w3.org/1999/xhtml"
|
|
150
149
|
end
|
|
151
150
|
|
|
152
151
|
def normal_element?(node)
|
|
@@ -166,13 +165,13 @@ module Squoosh
|
|
|
166
165
|
end
|
|
167
166
|
|
|
168
167
|
PHRASING_CONTENT = Set.new(%w[a abbr area audio b bdi bdo br button canvas
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
168
|
+
cite code data datalist del dfn em embed i
|
|
169
|
+
iframe img input ins kbd keygen label link
|
|
170
|
+
map mark math meta meter noscript object
|
|
171
|
+
output picture progress q ruby s samp script
|
|
172
|
+
select slot small span strong sub sup svg
|
|
173
|
+
template textarea time u var video
|
|
174
|
+
wbr]).freeze
|
|
176
175
|
private_constant :PHRASING_CONTENT
|
|
177
176
|
|
|
178
177
|
def phrasing_content?(node)
|
|
@@ -181,7 +180,7 @@ module Squoosh
|
|
|
181
180
|
end
|
|
182
181
|
|
|
183
182
|
def remove_comments(doc)
|
|
184
|
-
doc.xpath(
|
|
183
|
+
doc.xpath("//comment()").each do |node|
|
|
185
184
|
next if preserve_comment?(node)
|
|
186
185
|
|
|
187
186
|
prev_node = node.previous_sibling
|
|
@@ -197,8 +196,8 @@ module Squoosh
|
|
|
197
196
|
|
|
198
197
|
def preserve_comment?(node)
|
|
199
198
|
content = node.content
|
|
200
|
-
return true if content.start_with?
|
|
201
|
-
return true if /\A\s
|
|
199
|
+
return true if content.start_with? "[if "
|
|
200
|
+
return true if /\A\s*!/.match?(content)
|
|
202
201
|
|
|
203
202
|
# Support other retained comments?
|
|
204
203
|
false
|
|
@@ -209,37 +208,37 @@ module Squoosh
|
|
|
209
208
|
# Select all attribute nodes whose names start with "on";
|
|
210
209
|
'//@*[starts-with(name(),"on")]' +
|
|
211
210
|
# and are not descendants of foreign elements
|
|
212
|
-
|
|
211
|
+
"[not(ancestor::math or ancestor::svg)]" +
|
|
213
212
|
# and
|
|
214
|
-
|
|
213
|
+
"[" +
|
|
215
214
|
# whose names are any of
|
|
216
215
|
%w[abort cancel canplay canplaythrough change click close contextmenu
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
216
|
+
cuechange dblclick drag dragend dragenter dragexit dragleave
|
|
217
|
+
dragover dragstart drop durationchange emptied ended input invalid
|
|
218
|
+
keydown keypress keyup loadeddata loadedmetadata loadend loadstart
|
|
219
|
+
mousedown mouseenter mouseleave mousemove mouseout mouseover
|
|
220
|
+
mouseup wheel pause play playing progress ratechange reset seeked
|
|
221
|
+
seeking select show stalled submit suspend timeupdate toggle
|
|
222
|
+
volumechange waiting cut copy paste blur error focus load resize
|
|
223
|
+
scroll].map { |n| "name()=\"on#{n}\"" }.join(" or ") +
|
|
225
224
|
# or whose parent is body or frameset
|
|
226
|
-
|
|
225
|
+
" or (parent::body or parent::frameset)" +
|
|
227
226
|
# and
|
|
228
|
-
|
|
227
|
+
" and (" +
|
|
229
228
|
# whose names are any of
|
|
230
229
|
%w[afterprint beforeprint beforeunload hashchange languagechange
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
230
|
+
message offline online pagehide pageshow popstate
|
|
231
|
+
rejectionhandled storage unhandledrejection
|
|
232
|
+
unload].map { |n| "name()=\"on#{n}\"" }.join(" or ") +
|
|
233
|
+
")" \
|
|
234
|
+
"]"
|
|
236
235
|
).freeze
|
|
237
236
|
# rubocop:enable Style/StringConcatenation
|
|
238
237
|
private_constant :EVENT_HANDLERS_XPATH
|
|
239
238
|
|
|
240
239
|
def uglify(content, options)
|
|
241
240
|
js = Uglifier.compile(content, options)
|
|
242
|
-
js.chomp!(
|
|
241
|
+
js.chomp!(";")
|
|
243
242
|
js
|
|
244
243
|
end
|
|
245
244
|
|
|
@@ -252,9 +251,9 @@ module Squoosh
|
|
|
252
251
|
|
|
253
252
|
def compress_javascript(doc)
|
|
254
253
|
# Compress script elements.
|
|
255
|
-
doc.xpath(
|
|
256
|
-
type = node[
|
|
257
|
-
next unless type.nil? || type ==
|
|
254
|
+
doc.xpath("//script[not(ancestor::math or ancestor::svg)]").each do |node|
|
|
255
|
+
type = node["type"]&.downcase
|
|
256
|
+
next unless type.nil? || type == "text/javascript"
|
|
258
257
|
|
|
259
258
|
node.content = compress_script(node.content)
|
|
260
259
|
end
|
|
@@ -266,14 +265,14 @@ module Squoosh
|
|
|
266
265
|
|
|
267
266
|
def compress_css(doc)
|
|
268
267
|
# Compress style elements.
|
|
269
|
-
doc.xpath(
|
|
270
|
-
type = node[
|
|
271
|
-
next unless type.nil? || type ==
|
|
268
|
+
doc.xpath("//style[not(ancestor::math or ancestor::svg)]").each do |node|
|
|
269
|
+
type = node["type"]&.downcase
|
|
270
|
+
next unless type.nil? || type == "text/css" || type.empty?
|
|
272
271
|
|
|
273
272
|
node.content = minify_css node.content
|
|
274
273
|
end
|
|
275
274
|
# Compress style attributes
|
|
276
|
-
doc.xpath(
|
|
275
|
+
doc.xpath("//@style[not(ancestor::math or ancestor::svg)]").each do |node|
|
|
277
276
|
elm_type = node.parent.name
|
|
278
277
|
css = "#{elm_type}{#{node.content}}"
|
|
279
278
|
node.content = minify_css(css)[elm_type.length + 1..-2]
|
|
@@ -287,15 +286,15 @@ module Squoosh
|
|
|
287
286
|
node.unlink
|
|
288
287
|
else
|
|
289
288
|
content = node.content
|
|
290
|
-
content.gsub!(/[ \t\n\r\f]+/,
|
|
289
|
+
content.gsub!(/[ \t\n\r\f]+/, " ")
|
|
291
290
|
content.lstrip! if trim_left? node
|
|
292
291
|
content.rstrip! if trim_right? node
|
|
293
292
|
node.content = content
|
|
294
293
|
end
|
|
295
294
|
elsif node.element? &&
|
|
296
|
-
|
|
295
|
+
(node.name == "pre" || node.name == "textarea")
|
|
297
296
|
# Leave the contents of these nodes alone.
|
|
298
|
-
elsif normal_element?(node) || node.name ==
|
|
297
|
+
elsif normal_element?(node) || node.name == "title"
|
|
299
298
|
# Compress spaces in normal elements and title.
|
|
300
299
|
node.children.each { |c| compress_spaces c }
|
|
301
300
|
end
|
|
@@ -317,18 +316,18 @@ module Squoosh
|
|
|
317
316
|
prev_elm = node.previous_element
|
|
318
317
|
return !phrasing_content?(node.parent) if prev_elm.nil?
|
|
319
318
|
|
|
320
|
-
prev_elm.name ==
|
|
319
|
+
prev_elm.name == "br"
|
|
321
320
|
end
|
|
322
321
|
|
|
323
322
|
def trim_right?(node)
|
|
324
323
|
next_elm = node.next_element
|
|
325
324
|
return !phrasing_content?(node.parent) if next_elm.nil?
|
|
326
325
|
|
|
327
|
-
next_elm.name ==
|
|
326
|
+
next_elm.name == "br"
|
|
328
327
|
end
|
|
329
328
|
|
|
330
329
|
def stringify_node(node)
|
|
331
|
-
return node.to_html(encoding:
|
|
330
|
+
return node.to_html(encoding: "UTF-8") unless node.element?
|
|
332
331
|
|
|
333
332
|
output = StringIO.new
|
|
334
333
|
# Add start tag. 8.1.2.1
|
|
@@ -345,10 +344,10 @@ module Squoosh
|
|
|
345
344
|
# some cases.
|
|
346
345
|
# value = (attr.value || '')
|
|
347
346
|
# value.gsub!(/&([a-zA-Z0-9]+;|#[0-9]+|#[xX][a-fA-F0-9]+)/, '&\1')
|
|
348
|
-
value = (attr.value ||
|
|
347
|
+
value = (attr.value || "").gsub("&", "&")
|
|
349
348
|
if value.empty?
|
|
350
349
|
output << " #{name}"
|
|
351
|
-
elsif
|
|
350
|
+
elsif !/[\t\n\f\r "'`=<>]/.match?(value)
|
|
352
351
|
last_attr_unquoted = true
|
|
353
352
|
output << " #{name}=#{value}"
|
|
354
353
|
elsif !value.include?('"')
|
|
@@ -357,22 +356,22 @@ module Squoosh
|
|
|
357
356
|
output << " #{name}='#{value}'"
|
|
358
357
|
else
|
|
359
358
|
# Contains both ' and ".
|
|
360
|
-
output << " #{name}=\"#{value.gsub('"',
|
|
359
|
+
output << " #{name}=\"#{value.gsub('"', """)}\""
|
|
361
360
|
end
|
|
362
361
|
end
|
|
363
362
|
|
|
364
363
|
# Close start tag.
|
|
365
364
|
if self_closing? node
|
|
366
|
-
output <<
|
|
367
|
-
output <<
|
|
365
|
+
output << " " if last_attr_unquoted
|
|
366
|
+
output << "/"
|
|
368
367
|
end
|
|
369
|
-
output <<
|
|
368
|
+
output << ">"
|
|
370
369
|
end
|
|
371
370
|
|
|
372
371
|
# If pre or textarea start with a newline, double it because the HTML
|
|
373
372
|
# parser strips leading newlines.
|
|
374
|
-
if (node.name ==
|
|
375
|
-
|
|
373
|
+
if (node.name == "pre" || node.name == "textarea") &&
|
|
374
|
+
!node.children.empty?
|
|
376
375
|
first_child = node.children[0]
|
|
377
376
|
if first_child.text? && first_child.content.start_with?("\n")
|
|
378
377
|
output << "\n"
|
|
@@ -387,22 +386,27 @@ module Squoosh
|
|
|
387
386
|
output.string
|
|
388
387
|
end
|
|
389
388
|
|
|
389
|
+
XML_NAMESPACE = "http://www.w3.org/XML/1998/namespace"
|
|
390
|
+
XMLNS_NAMESPACE = "http://www.w3.org/2000/xmlns/"
|
|
391
|
+
XLINK_NAMESPACE = "http://www.w3.org/1999/xlink"
|
|
392
|
+
private_constant :XML_NAMESPACE, :XMLNS_NAMESPACE, :XLINK_NAMESPACE
|
|
393
|
+
|
|
390
394
|
def qualified_attribute_name(attr)
|
|
391
395
|
ns = attr.namespace
|
|
392
396
|
return attr.name if ns.nil?
|
|
393
397
|
|
|
394
398
|
uri = ns.href
|
|
395
|
-
if uri ==
|
|
399
|
+
if uri == XML_NAMESPACE
|
|
396
400
|
"xml:#{attr.name}"
|
|
397
|
-
elsif uri ==
|
|
398
|
-
|
|
399
|
-
elsif uri ==
|
|
401
|
+
elsif uri == XMLNS_NAMESPACE && attr.name == "xmlns"
|
|
402
|
+
"xmlns"
|
|
403
|
+
elsif uri == XMLNS_NAMESPACE
|
|
400
404
|
"xmlns:#{attr.name}"
|
|
401
|
-
elsif uri ==
|
|
405
|
+
elsif uri == XLINK_NAMESPACE
|
|
402
406
|
"xlink:#{attr.name}"
|
|
403
407
|
else
|
|
404
408
|
# :nocov:
|
|
405
|
-
raise
|
|
409
|
+
raise "Unreachable!"
|
|
406
410
|
# :nocov:
|
|
407
411
|
end
|
|
408
412
|
end
|
|
@@ -467,17 +471,17 @@ module Squoosh
|
|
|
467
471
|
return false unless node.attributes.empty?
|
|
468
472
|
|
|
469
473
|
case node.name
|
|
470
|
-
when
|
|
474
|
+
when "html"
|
|
471
475
|
# An html element's start tag may be omitted if the first thing inside
|
|
472
476
|
# the html element is not a comment.
|
|
473
477
|
return node.children.empty? || !node.children[0].comment?
|
|
474
478
|
|
|
475
|
-
when
|
|
479
|
+
when "head"
|
|
476
480
|
# A head element's start tag may be omitted if the element is empty,
|
|
477
481
|
# or if the first thing inside the head element is an element.
|
|
478
482
|
return node.children.empty? || node.children[0].element?
|
|
479
483
|
|
|
480
|
-
when
|
|
484
|
+
when "body"
|
|
481
485
|
# A body element's start tag may be omitted if the element is empty,
|
|
482
486
|
# or if the first thing inside the body element is not a space
|
|
483
487
|
# character or a comment, except if the first thing inside the body
|
|
@@ -485,32 +489,32 @@ module Squoosh
|
|
|
485
489
|
return true if node.children.empty?
|
|
486
490
|
|
|
487
491
|
c = node.children[0]
|
|
488
|
-
return !c.content.start_with?(
|
|
492
|
+
return !c.content.start_with?(" ") if c.text?
|
|
489
493
|
return false if c.comment?
|
|
490
494
|
|
|
491
495
|
return !c.element? ||
|
|
492
|
-
|
|
496
|
+
!%w[meta link script style template].include?(c.name)
|
|
493
497
|
|
|
494
|
-
when
|
|
498
|
+
when "colgroup"
|
|
495
499
|
# A colgroup element's start tag may be omitted if the first thing
|
|
496
500
|
# inside the colgroup element is a col element, and if the element is
|
|
497
501
|
# not immediately preceded by another colgroup element whose end tag
|
|
498
502
|
# has been omitted. (It can't be omitted if the element is empty.)
|
|
499
503
|
child = first_child_content_node(node)
|
|
500
|
-
return false if child.nil? || !child.element? || child.name !=
|
|
504
|
+
return false if child.nil? || !child.element? || child.name != "col"
|
|
501
505
|
|
|
502
506
|
prev_node = previous_sibling_content_node(node)
|
|
503
507
|
return !(prev_node&.element? &&
|
|
504
|
-
prev_node.name ==
|
|
508
|
+
prev_node.name == "colgroup" &&
|
|
505
509
|
omit_end_tag?(prev_node))
|
|
506
510
|
|
|
507
|
-
when
|
|
511
|
+
when "tbody"
|
|
508
512
|
# A tbody element's start tag may be omitted if the first thing inside
|
|
509
513
|
# the tbody element is a tr element, and if the element is not
|
|
510
514
|
# immediately preceded by a tbody, thead, or tfoot element whose end
|
|
511
515
|
# tag has been omitted. (It can't be omitted if the element is empty.)
|
|
512
516
|
child = first_child_content_node(node)
|
|
513
|
-
return false if child.nil? || !child.element? || child.name !=
|
|
517
|
+
return false if child.nil? || !child.element? || child.name != "tr"
|
|
514
518
|
|
|
515
519
|
prev_node = previous_sibling_content_node(node)
|
|
516
520
|
return !(prev_node&.element? &&
|
|
@@ -523,45 +527,44 @@ module Squoosh
|
|
|
523
527
|
def omit_end_tag?(node)
|
|
524
528
|
return true if void_element?(node) || self_closing?(node)
|
|
525
529
|
return false unless @options[:omit_tags]
|
|
526
|
-
return false if node.parent.name == 'noscript'
|
|
527
530
|
|
|
528
531
|
next_node = node.next_sibling
|
|
529
532
|
case node.name
|
|
530
|
-
when
|
|
533
|
+
when "html"
|
|
531
534
|
# An html element's end tag may be omitted if the html element is not
|
|
532
535
|
# immediately followed by a comment.
|
|
533
536
|
return next_node.nil? || !next_node.comment?
|
|
534
537
|
|
|
535
|
-
when
|
|
538
|
+
when "head"
|
|
536
539
|
# A head element's end tag may be omitted if the head element is not
|
|
537
540
|
# immediately followed by a space character or a comment.
|
|
538
541
|
return next_node.nil? ||
|
|
539
|
-
|
|
540
|
-
|
|
542
|
+
(next_node.text? && !next_node.content.start_with?(" ")) ||
|
|
543
|
+
!next_node.comment?
|
|
541
544
|
|
|
542
|
-
when
|
|
545
|
+
when "body"
|
|
543
546
|
# A body element's end tag may be omitted if the body element is not
|
|
544
547
|
# immediately followed by a comment.
|
|
545
548
|
return next_node.nil? || !next_node.comment?
|
|
546
549
|
|
|
547
|
-
when
|
|
550
|
+
when "li"
|
|
548
551
|
# An li element's end tag may be omitted if the li element is
|
|
549
552
|
# immediately followed by another li element or if there is no more
|
|
550
553
|
# content in the parent element.
|
|
551
|
-
return next_sibling_is_nil_or_one_of?(node, [
|
|
554
|
+
return next_sibling_is_nil_or_one_of?(node, ["li"])
|
|
552
555
|
|
|
553
|
-
when
|
|
556
|
+
when "dt"
|
|
554
557
|
# A dt element's end tag may be omitted if the dt element is immediately
|
|
555
558
|
# followed by another dt element or a dd element.
|
|
556
559
|
return next_sibling_is_one_of?(node, %w[dt dd])
|
|
557
560
|
|
|
558
|
-
when
|
|
561
|
+
when "dd"
|
|
559
562
|
# A dd element's end tag may be omitted if the dd element is immediately
|
|
560
563
|
# followed by another dd element or a dt element, or if there is no more
|
|
561
564
|
# content in the parent element.
|
|
562
565
|
return next_sibling_is_nil_or_one_of?(node, %w[dt dd])
|
|
563
566
|
|
|
564
|
-
when
|
|
567
|
+
when "p"
|
|
565
568
|
# A p element's end tag can be omitted if the p element is immediately
|
|
566
569
|
# followed by an address, article, aside, blockquote, details, div,
|
|
567
570
|
# dl, fieldset, figcaption, figure, footer, form, h1, h2, h3, h4, h5,
|
|
@@ -578,12 +581,11 @@ module Squoosh
|
|
|
578
581
|
ol p pre section table ul
|
|
579
582
|
]
|
|
580
583
|
)
|
|
584
|
+
return false if parent_contains_more_content?(node)
|
|
581
585
|
return false if foreign_element?(node.parent)
|
|
586
|
+
return !%(a audio del ins map noscript video).include?(node.parent.name)
|
|
582
587
|
|
|
583
|
-
|
|
584
|
-
!%(a audio del ins map noscript video).include?(node.parent.name)
|
|
585
|
-
|
|
586
|
-
when 'rb', 'rt', 'rp'
|
|
588
|
+
when "rb", "rt", "rp"
|
|
587
589
|
# An rb element's end tag may be omitted if the rb element is
|
|
588
590
|
# immediately followed by an rb, rt, rtc or rp element, or if there is
|
|
589
591
|
# no more content in the parent element.
|
|
@@ -597,56 +599,56 @@ module Squoosh
|
|
|
597
599
|
# no more content in the parent element.
|
|
598
600
|
return next_sibling_is_nil_or_one_of?(node, %w[rb rt rtc rp])
|
|
599
601
|
|
|
600
|
-
when
|
|
602
|
+
when "rtc"
|
|
601
603
|
# An rtc element's end tag may be omitted if the rtc element is
|
|
602
604
|
# immediately followed by an rb, rtc or rp element, or if there is no
|
|
603
605
|
# more content in the parent element.
|
|
604
606
|
return next_sibling_is_nil_or_one_of?(node, %w[rb rtc rp])
|
|
605
607
|
|
|
606
|
-
when
|
|
608
|
+
when "optgroup"
|
|
607
609
|
# An optgroup element's end tag may be omitted if the optgroup element
|
|
608
610
|
# is immediately followed by another optgroup element, or if there is
|
|
609
611
|
# no more content in the parent element.
|
|
610
|
-
return next_sibling_is_nil_or_one_of?(node, [
|
|
612
|
+
return next_sibling_is_nil_or_one_of?(node, ["optgroup"])
|
|
611
613
|
|
|
612
|
-
when
|
|
614
|
+
when "option"
|
|
613
615
|
# An option element's end tag may be omitted if the option element is
|
|
614
616
|
# immediately followed by another option element, or if it is
|
|
615
617
|
# immediately followed by an optgroup element, or if there is no more
|
|
616
618
|
# content in the parent element.
|
|
617
619
|
return next_sibling_is_nil_or_one_of?(node, %w[option optgroup])
|
|
618
620
|
|
|
619
|
-
when
|
|
621
|
+
when "colgroup"
|
|
620
622
|
# A colgroup element's end tag may be omitted if the colgroup element is
|
|
621
623
|
# not immediately followed by a space character or a comment.
|
|
622
624
|
return true if next_node.nil?
|
|
623
|
-
return !next_node.content.start_with?(
|
|
625
|
+
return !next_node.content.start_with?(" ") if next_node.text?
|
|
624
626
|
|
|
625
627
|
return !next_node.comment?
|
|
626
628
|
|
|
627
|
-
when
|
|
629
|
+
when "thead"
|
|
628
630
|
# A thead element's end tag may be omitted if the thead element is
|
|
629
631
|
# immediately followed by a tbody or tfoot element.
|
|
630
632
|
return next_sibling_is_one_of?(node, %w[tbody tfoot])
|
|
631
633
|
|
|
632
|
-
when
|
|
634
|
+
when "tbody"
|
|
633
635
|
# A tbody element's end tag may be omitted if the tbody element is
|
|
634
636
|
# immediately followed by a tbody or tfoot element, or if there is no
|
|
635
637
|
# more content in the parent element.
|
|
636
638
|
return next_sibling_is_nil_or_one_of?(node, %w[tbody tfoot])
|
|
637
639
|
|
|
638
|
-
when
|
|
640
|
+
when "tfoot"
|
|
639
641
|
# A tfoot element's end tag can be omitted if there is no more content
|
|
640
642
|
# in the parent element.
|
|
641
643
|
return !parent_contains_more_content?(node)
|
|
642
644
|
|
|
643
|
-
when
|
|
645
|
+
when "tr"
|
|
644
646
|
# A tr element's end tag may be omitted if the tr element is immediately
|
|
645
647
|
# followed by another tr element, or if there is no more content in the
|
|
646
648
|
# parent element.
|
|
647
|
-
return next_sibling_is_nil_or_one_of?(node, [
|
|
649
|
+
return next_sibling_is_nil_or_one_of?(node, ["tr"])
|
|
648
650
|
|
|
649
|
-
when
|
|
651
|
+
when "td", "th"
|
|
650
652
|
# A td element's end tag may be omitted if the td element is immediately
|
|
651
653
|
# followed by a td or th element, or if there is no more content in the
|
|
652
654
|
# parent element.
|
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: squoosh
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.4.
|
|
4
|
+
version: 0.4.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Stephen Checkoway
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: bundler
|
|
@@ -25,7 +24,35 @@ dependencies:
|
|
|
25
24
|
- !ruby/object:Gem::Version
|
|
26
25
|
version: '0'
|
|
27
26
|
- !ruby/object:Gem::Dependency
|
|
28
|
-
name:
|
|
27
|
+
name: minitest
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - ">="
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '0'
|
|
33
|
+
type: :development
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - ">="
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: '0'
|
|
40
|
+
- !ruby/object:Gem::Dependency
|
|
41
|
+
name: minitest-proveit
|
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
|
43
|
+
requirements:
|
|
44
|
+
- - ">="
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: '0'
|
|
47
|
+
type: :development
|
|
48
|
+
prerelease: false
|
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - ">="
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: '0'
|
|
54
|
+
- !ruby/object:Gem::Dependency
|
|
55
|
+
name: minitest-reporters
|
|
29
56
|
requirement: !ruby/object:Gem::Requirement
|
|
30
57
|
requirements:
|
|
31
58
|
- - ">="
|
|
@@ -39,7 +66,7 @@ dependencies:
|
|
|
39
66
|
- !ruby/object:Gem::Version
|
|
40
67
|
version: '0'
|
|
41
68
|
- !ruby/object:Gem::Dependency
|
|
42
|
-
name:
|
|
69
|
+
name: rake
|
|
43
70
|
requirement: !ruby/object:Gem::Requirement
|
|
44
71
|
requirements:
|
|
45
72
|
- - ">="
|
|
@@ -66,6 +93,34 @@ dependencies:
|
|
|
66
93
|
- - ">="
|
|
67
94
|
- !ruby/object:Gem::Version
|
|
68
95
|
version: '0'
|
|
96
|
+
- !ruby/object:Gem::Dependency
|
|
97
|
+
name: rubocop-minitest
|
|
98
|
+
requirement: !ruby/object:Gem::Requirement
|
|
99
|
+
requirements:
|
|
100
|
+
- - ">="
|
|
101
|
+
- !ruby/object:Gem::Version
|
|
102
|
+
version: '0'
|
|
103
|
+
type: :development
|
|
104
|
+
prerelease: false
|
|
105
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
106
|
+
requirements:
|
|
107
|
+
- - ">="
|
|
108
|
+
- !ruby/object:Gem::Version
|
|
109
|
+
version: '0'
|
|
110
|
+
- !ruby/object:Gem::Dependency
|
|
111
|
+
name: rubocop-rake
|
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
|
113
|
+
requirements:
|
|
114
|
+
- - ">="
|
|
115
|
+
- !ruby/object:Gem::Version
|
|
116
|
+
version: '0'
|
|
117
|
+
type: :development
|
|
118
|
+
prerelease: false
|
|
119
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
120
|
+
requirements:
|
|
121
|
+
- - ">="
|
|
122
|
+
- !ruby/object:Gem::Version
|
|
123
|
+
version: '0'
|
|
69
124
|
- !ruby/object:Gem::Dependency
|
|
70
125
|
name: simplecov
|
|
71
126
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -94,6 +149,20 @@ dependencies:
|
|
|
94
149
|
- - ">="
|
|
95
150
|
- !ruby/object:Gem::Version
|
|
96
151
|
version: '0'
|
|
152
|
+
- !ruby/object:Gem::Dependency
|
|
153
|
+
name: standard
|
|
154
|
+
requirement: !ruby/object:Gem::Requirement
|
|
155
|
+
requirements:
|
|
156
|
+
- - ">="
|
|
157
|
+
- !ruby/object:Gem::Version
|
|
158
|
+
version: '0'
|
|
159
|
+
type: :development
|
|
160
|
+
prerelease: false
|
|
161
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
162
|
+
requirements:
|
|
163
|
+
- - ">="
|
|
164
|
+
- !ruby/object:Gem::Version
|
|
165
|
+
version: '0'
|
|
97
166
|
- !ruby/object:Gem::Dependency
|
|
98
167
|
name: yard
|
|
99
168
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -114,14 +183,14 @@ dependencies:
|
|
|
114
183
|
requirements:
|
|
115
184
|
- - "~>"
|
|
116
185
|
- !ruby/object:Gem::Version
|
|
117
|
-
version: '1.
|
|
186
|
+
version: '1.16'
|
|
118
187
|
type: :runtime
|
|
119
188
|
prerelease: false
|
|
120
189
|
version_requirements: !ruby/object:Gem::Requirement
|
|
121
190
|
requirements:
|
|
122
191
|
- - "~>"
|
|
123
192
|
- !ruby/object:Gem::Version
|
|
124
|
-
version: '1.
|
|
193
|
+
version: '1.16'
|
|
125
194
|
- !ruby/object:Gem::Dependency
|
|
126
195
|
name: sassc
|
|
127
196
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -150,7 +219,6 @@ dependencies:
|
|
|
150
219
|
- - "~>"
|
|
151
220
|
- !ruby/object:Gem::Version
|
|
152
221
|
version: '4.1'
|
|
153
|
-
description:
|
|
154
222
|
email:
|
|
155
223
|
- s@pahtak.org
|
|
156
224
|
executables: []
|
|
@@ -169,7 +237,7 @@ metadata:
|
|
|
169
237
|
changelog_uri: https://github.com/stevecheckoway/squoosh/blob/master/CHANGELOG.md
|
|
170
238
|
homepage_uri: https://github.com/stevecheckoway/squoosh
|
|
171
239
|
source_code_uri: https://github.com/stevecheckoway/squoosh
|
|
172
|
-
|
|
240
|
+
rubygems_mfa_required: 'true'
|
|
173
241
|
rdoc_options: []
|
|
174
242
|
require_paths:
|
|
175
243
|
- lib
|
|
@@ -177,18 +245,17 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
177
245
|
requirements:
|
|
178
246
|
- - ">="
|
|
179
247
|
- !ruby/object:Gem::Version
|
|
180
|
-
version: '
|
|
248
|
+
version: '3.1'
|
|
181
249
|
- - "<"
|
|
182
250
|
- !ruby/object:Gem::Version
|
|
183
|
-
version: '
|
|
251
|
+
version: '5.0'
|
|
184
252
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
185
253
|
requirements:
|
|
186
254
|
- - ">="
|
|
187
255
|
- !ruby/object:Gem::Version
|
|
188
256
|
version: '0'
|
|
189
257
|
requirements: []
|
|
190
|
-
rubygems_version: 3.
|
|
191
|
-
signing_key:
|
|
258
|
+
rubygems_version: 3.7.2
|
|
192
259
|
specification_version: 4
|
|
193
260
|
summary: Minify HTML/CSS/JavaScript files.
|
|
194
261
|
test_files: []
|