squoosh 0.3.1 → 0.3.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 +5 -3
- data/lib/squoosh.rb +106 -67
- data/lib/squoosh/version.rb +1 -1
- metadata +22 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8ad27922ec33d0ecfea5e58f69ce3a39ea9b1a62732e8a4db9725443dbdbe97b
|
4
|
+
data.tar.gz: 7dc0576cdd2206091677ee36ea6b836ad537ee5527e83309b649314c51100ddf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 24d38fd5136f531d5ac21aec36fb71b031803f52a6786f313eb5d5aa31469d5fd6cae4d3a873ede1c7404758053e639ec792b1c1d315caaa6470c35443f99897
|
7
|
+
data.tar.gz: 8dac02921bebd2bc963352ce9173dc53b6eae041de2ccc44d4a3fecd8e89de02f3a854cfa91ff24f833f87519675b2f699f41cd3e36ace652110f1323bedc531
|
data/README.md
CHANGED
@@ -1,10 +1,12 @@
|
|
1
|
+
[](https://travis-ci.org/stevecheckoway/squoosh)
|
3
|
+
[](https://coveralls.io/github/stevecheckoway/squoosh?branch=master)
|
5
|
+
|
1
6
|
# Squoosh
|
2
7
|
|
3
8
|
Minifies HTML, JavaScript, and CSS, including inline JavaScript and CSS.
|
4
9
|
|
5
|
-
[](https://travis-ci.org/stevecheckoway/squoosh)
|
7
|
-
|
8
10
|
CSS minification is handled by [Sassc](http://www.rubydoc.info/gems/sassc)
|
9
11
|
whereas JavaScript minification is handled by
|
10
12
|
[Uglifier](http://www.rubydoc.info/gems/uglifier) which requires node.js.
|
data/lib/squoosh.rb
CHANGED
@@ -204,6 +204,7 @@ module Squoosh
|
|
204
204
|
false
|
205
205
|
end
|
206
206
|
|
207
|
+
# rubocop:disable Style/StringConcatenation
|
207
208
|
EVENT_HANDLERS_XPATH = (
|
208
209
|
# Select all attribute nodes whose names start with "on";
|
209
210
|
'//@*[starts-with(name(),"on")]' +
|
@@ -233,6 +234,7 @@ module Squoosh
|
|
233
234
|
')' \
|
234
235
|
']'
|
235
236
|
).freeze
|
237
|
+
# rubocop:enable Style/StringConcatenation
|
236
238
|
private_constant :EVENT_HANDLERS_XPATH
|
237
239
|
|
238
240
|
def uglify(content, options)
|
@@ -345,7 +347,7 @@ module Squoosh
|
|
345
347
|
# value.gsub!(/&([a-zA-Z0-9]+;|#[0-9]+|#[xX][a-fA-F0-9]+)/, '&\1')
|
346
348
|
value = (attr.value || '').gsub('&', '&')
|
347
349
|
if value.empty?
|
348
|
-
output <<
|
350
|
+
output << " #{name}"
|
349
351
|
elsif /[\t\n\f\r "'`=<>]/ !~ value
|
350
352
|
last_attr_unquoted = true
|
351
353
|
output << " #{name}=#{value}"
|
@@ -391,15 +393,17 @@ module Squoosh
|
|
391
393
|
|
392
394
|
uri = ns.href
|
393
395
|
if uri == Nokogiri::HTML5::XML_NAMESPACE
|
394
|
-
|
396
|
+
"xml:#{attr.name}"
|
395
397
|
elsif uri == Nokogiri::HTML5::XMLNS_NAMESPACE && attr.name == 'xmlns'
|
396
398
|
'xmlns'
|
397
399
|
elsif uri == Nokogiri::HTML5::XMLNS_NAMESPACE
|
398
|
-
|
400
|
+
"xmlns:#{attr.name}"
|
399
401
|
elsif uri == Nokogiri::HTML5::XLINK_NAMESPACE
|
400
|
-
|
402
|
+
"xlink:#{attr.name}"
|
401
403
|
else
|
404
|
+
# :nocov:
|
402
405
|
raise 'Unreachable!'
|
406
|
+
# :nocov:
|
403
407
|
end
|
404
408
|
end
|
405
409
|
|
@@ -411,6 +415,53 @@ module Squoosh
|
|
411
415
|
foreign_element?(node) && node.children.empty?
|
412
416
|
end
|
413
417
|
|
418
|
+
def content_node?(node)
|
419
|
+
# Inter-element whitespace, comment nodes, and processing instruction
|
420
|
+
# nodes must be ignored when establishing whether an element's contents
|
421
|
+
# match the element's content model or not, and must be ignored when
|
422
|
+
# following algorithms that define document and element semantics.
|
423
|
+
!(node.comment? ||
|
424
|
+
node.processing_instruction? ||
|
425
|
+
inter_element_whitespace?(node))
|
426
|
+
end
|
427
|
+
|
428
|
+
def previous_sibling_content_node(node)
|
429
|
+
while (node = node.previous_sibling)
|
430
|
+
return node if content_node?(node)
|
431
|
+
end
|
432
|
+
nil
|
433
|
+
end
|
434
|
+
|
435
|
+
def next_sibling_content_node(node)
|
436
|
+
while (node = node.next_sibling)
|
437
|
+
return node if content_node?(node)
|
438
|
+
end
|
439
|
+
nil
|
440
|
+
end
|
441
|
+
|
442
|
+
def first_child_content_node(node)
|
443
|
+
return nil if node.children.empty?
|
444
|
+
|
445
|
+
node = node.children[0]
|
446
|
+
return node if content_node?(node)
|
447
|
+
|
448
|
+
next_sibling_content_node(node)
|
449
|
+
end
|
450
|
+
|
451
|
+
def next_sibling_is_nil_or_one_of?(node, elements)
|
452
|
+
node = next_sibling_content_node(node)
|
453
|
+
node.nil? || (node.element? && elements.include?(node.name))
|
454
|
+
end
|
455
|
+
|
456
|
+
def next_sibling_is_one_of?(node, elements)
|
457
|
+
node = next_sibling_content_node(node)
|
458
|
+
node&.element? && elements.include?(node.name)
|
459
|
+
end
|
460
|
+
|
461
|
+
def parent_contains_more_content?(node)
|
462
|
+
!next_sibling_content_node(node).nil?
|
463
|
+
end
|
464
|
+
|
414
465
|
def omit_start_tag?(node)
|
415
466
|
return false unless @options[:omit_tags]
|
416
467
|
return false unless node.attributes.empty?
|
@@ -445,37 +496,26 @@ module Squoosh
|
|
445
496
|
# inside the colgroup element is a col element, and if the element is
|
446
497
|
# not immediately preceded by another colgroup element whose end tag
|
447
498
|
# has been omitted. (It can't be omitted if the element is empty.)
|
448
|
-
|
449
|
-
return false
|
499
|
+
child = first_child_content_node(node)
|
500
|
+
return false if child.nil? || !child.element? || child.name != 'col'
|
450
501
|
|
451
|
-
|
452
|
-
return
|
453
|
-
|
454
|
-
|
502
|
+
prev_node = previous_sibling_content_node(node)
|
503
|
+
return !(prev_node&.element? &&
|
504
|
+
prev_node.name == 'colgroup' &&
|
505
|
+
omit_end_tag?(prev_node))
|
455
506
|
|
456
507
|
when 'tbody'
|
457
508
|
# A tbody element's start tag may be omitted if the first thing inside
|
458
509
|
# the tbody element is a tr element, and if the element is not
|
459
510
|
# immediately preceded by a tbody, thead, or tfoot element whose end
|
460
511
|
# tag has been omitted. (It can't be omitted if the element is empty.)
|
461
|
-
|
462
|
-
return false
|
512
|
+
child = first_child_content_node(node)
|
513
|
+
return false if child.nil? || !child.element? || child.name != 'tr'
|
463
514
|
|
464
|
-
|
465
|
-
return
|
466
|
-
|
467
|
-
|
468
|
-
end
|
469
|
-
false
|
470
|
-
end
|
471
|
-
|
472
|
-
def parent_contains_more_content?(node)
|
473
|
-
while (node = node.next_sibling)
|
474
|
-
next if node.comment?
|
475
|
-
next if node.processing_instruction?
|
476
|
-
next if inter_element_whitespace? node
|
477
|
-
|
478
|
-
return true
|
515
|
+
prev_node = previous_sibling_content_node(node)
|
516
|
+
return !(prev_node&.element? &&
|
517
|
+
%w[tbody thead tfoot].include?(prev_node.name) &&
|
518
|
+
omit_end_tag?(prev_node))
|
479
519
|
end
|
480
520
|
false
|
481
521
|
end
|
@@ -486,7 +526,6 @@ module Squoosh
|
|
486
526
|
return false if node.parent.name == 'noscript'
|
487
527
|
|
488
528
|
next_node = node.next_sibling
|
489
|
-
next_elm = node.next_element
|
490
529
|
case node.name
|
491
530
|
when 'html'
|
492
531
|
# An html element's end tag may be omitted if the html element is not
|
@@ -509,33 +548,40 @@ module Squoosh
|
|
509
548
|
# An li element's end tag may be omitted if the li element is
|
510
549
|
# immediately followed by another li element or if there is no more
|
511
550
|
# content in the parent element.
|
512
|
-
return
|
551
|
+
return next_sibling_is_nil_or_one_of?(node, ['li'])
|
513
552
|
|
514
553
|
when 'dt'
|
515
554
|
# A dt element's end tag may be omitted if the dt element is immediately
|
516
555
|
# followed by another dt element or a dd element.
|
517
|
-
return %w[dt dd]
|
556
|
+
return next_sibling_is_one_of?(node, %w[dt dd])
|
518
557
|
|
519
558
|
when 'dd'
|
520
559
|
# A dd element's end tag may be omitted if the dd element is immediately
|
521
560
|
# followed by another dd element or a dt element, or if there is no more
|
522
561
|
# content in the parent element.
|
523
|
-
return %w[dt dd]
|
524
|
-
!parent_contains_more_content?(node)
|
562
|
+
return next_sibling_is_nil_or_one_of?(node, %w[dt dd])
|
525
563
|
|
526
564
|
when 'p'
|
527
|
-
# A p element's end tag
|
528
|
-
# followed by an address, article, aside, blockquote,
|
529
|
-
# fieldset, footer, form, h1, h2, h3, h4, h5,
|
530
|
-
# main, nav, ol, p, pre, section, table,
|
531
|
-
# is no more content in the parent element
|
532
|
-
# not an a
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
565
|
+
# A p element's end tag can be omitted if the p element is immediately
|
566
|
+
# followed by an address, article, aside, blockquote, details, div,
|
567
|
+
# dl, fieldset, figcaption, figure, footer, form, h1, h2, h3, h4, h5,
|
568
|
+
# h6, header, hgroup, hr, main, menu, nav, ol, p, pre, section, table,
|
569
|
+
# or ul element, or if there is no more content in the parent element
|
570
|
+
# and the parent element is an HTML element that is not an a, audio,
|
571
|
+
# del, ins, map, noscript, or video element, or an autonomous custom
|
572
|
+
# element.
|
573
|
+
return true if next_sibling_is_one_of?(
|
574
|
+
node,
|
575
|
+
%w[
|
576
|
+
address article aside blockquote details div dl fieldset figcaption
|
577
|
+
figure footer form h1 h2 h3 h4 h5 h6 header hgroup hr main menu nav
|
578
|
+
ol p pre section table ul
|
579
|
+
]
|
580
|
+
)
|
581
|
+
return false if foreign_element?(node.parent)
|
582
|
+
|
583
|
+
return !parent_contains_more_content?(node) &&
|
584
|
+
!%(a audio del ins map noscript video).include?(node.parent.name)
|
539
585
|
|
540
586
|
when 'rb', 'rt', 'rp'
|
541
587
|
# An rb element's end tag may be omitted if the rb element is
|
@@ -549,62 +595,56 @@ module Squoosh
|
|
549
595
|
# An rp element's end tag may be omitted if the rp element is
|
550
596
|
# immediately followed by an rb, rt, rtc or rp element, or if there is
|
551
597
|
# no more content in the parent element.
|
552
|
-
return %w[rb rt rtc rp]
|
553
|
-
|
598
|
+
return next_sibling_is_nil_or_one_of?(node, %w[rb rt rtc rp])
|
599
|
+
|
554
600
|
when 'rtc'
|
555
601
|
# An rtc element's end tag may be omitted if the rtc element is
|
556
602
|
# immediately followed by an rb, rtc or rp element, or if there is no
|
557
603
|
# more content in the parent element.
|
558
|
-
return %w[rb rtc rp]
|
559
|
-
!parent_contains_more_content?(node)
|
604
|
+
return next_sibling_is_nil_or_one_of?(node, %w[rb rtc rp])
|
560
605
|
|
561
606
|
when 'optgroup'
|
562
607
|
# An optgroup element's end tag may be omitted if the optgroup element
|
563
608
|
# is immediately followed by another optgroup element, or if there is
|
564
609
|
# no more content in the parent element.
|
565
|
-
return
|
566
|
-
!parent_contains_more_content?(node)
|
610
|
+
return next_sibling_is_nil_or_one_of?(node, ['optgroup'])
|
567
611
|
|
568
612
|
when 'option'
|
569
613
|
# An option element's end tag may be omitted if the option element is
|
570
614
|
# immediately followed by another option element, or if it is
|
571
615
|
# immediately followed by an optgroup element, or if there is no more
|
572
616
|
# content in the parent element.
|
573
|
-
return %w[option optgroup]
|
574
|
-
!parent_contains_more_content?(node)
|
617
|
+
return next_sibling_is_nil_or_one_of?(node, %w[option optgroup])
|
575
618
|
|
576
619
|
when 'colgroup'
|
577
620
|
# A colgroup element's end tag may be omitted if the colgroup element is
|
578
621
|
# not immediately followed by a space character or a comment.
|
579
|
-
return next_node.nil?
|
580
|
-
|
581
|
-
|
622
|
+
return true if next_node.nil?
|
623
|
+
return !next_node.content.start_with?(' ') if next_node.text?
|
624
|
+
|
625
|
+
return !next_node.comment?
|
582
626
|
|
583
627
|
when 'thead'
|
584
628
|
# A thead element's end tag may be omitted if the thead element is
|
585
629
|
# immediately followed by a tbody or tfoot element.
|
586
|
-
return %w[tbody tfoot]
|
630
|
+
return next_sibling_is_one_of?(node, %w[tbody tfoot])
|
587
631
|
|
588
632
|
when 'tbody'
|
589
633
|
# A tbody element's end tag may be omitted if the tbody element is
|
590
634
|
# immediately followed by a tbody or tfoot element, or if there is no
|
591
635
|
# more content in the parent element.
|
592
|
-
return %w[tbody tfoot]
|
593
|
-
!parent_contains_more_content?(node)
|
636
|
+
return next_sibling_is_nil_or_one_of?(node, %w[tbody tfoot])
|
594
637
|
|
595
638
|
when 'tfoot'
|
596
|
-
# A tfoot element's end tag
|
597
|
-
#
|
598
|
-
|
599
|
-
return next_elm&.name == 'tbody' ||
|
600
|
-
!parent_contains_more_content?(node)
|
639
|
+
# A tfoot element's end tag can be omitted if there is no more content
|
640
|
+
# in the parent element.
|
641
|
+
return !parent_contains_more_content?(node)
|
601
642
|
|
602
643
|
when 'tr'
|
603
644
|
# A tr element's end tag may be omitted if the tr element is immediately
|
604
645
|
# followed by another tr element, or if there is no more content in the
|
605
646
|
# parent element.
|
606
|
-
return
|
607
|
-
!parent_contains_more_content?(node)
|
647
|
+
return next_sibling_is_nil_or_one_of?(node, ['tr'])
|
608
648
|
|
609
649
|
when 'td', 'th'
|
610
650
|
# A td element's end tag may be omitted if the td element is immediately
|
@@ -614,8 +654,7 @@ module Squoosh
|
|
614
654
|
# A th element's end tag may be omitted if the th element is immediately
|
615
655
|
# followed by a td or th element, or if there is no more content in the
|
616
656
|
# parent element.
|
617
|
-
return %w[td th]
|
618
|
-
!parent_contains_more_content?(node)
|
657
|
+
return next_sibling_is_nil_or_one_of?(node, %w[td th])
|
619
658
|
end
|
620
659
|
false
|
621
660
|
end
|
data/lib/squoosh/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: squoosh
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stephen Checkoway
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-08-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -24,6 +24,20 @@ dependencies:
|
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: coveralls
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: rake
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -136,7 +150,7 @@ dependencies:
|
|
136
150
|
- - "~>"
|
137
151
|
- !ruby/object:Gem::Version
|
138
152
|
version: '4.1'
|
139
|
-
description:
|
153
|
+
description:
|
140
154
|
email:
|
141
155
|
- s@pahtak.org
|
142
156
|
executables: []
|
@@ -155,7 +169,7 @@ metadata:
|
|
155
169
|
changelog_uri: https://github.com/stevecheckoway/squoosh/blob/master/CHANGELOG.md
|
156
170
|
homepage_uri: https://github.com/stevecheckoway/squoosh
|
157
171
|
source_code_uri: https://github.com/stevecheckoway/squoosh
|
158
|
-
post_install_message:
|
172
|
+
post_install_message:
|
159
173
|
rdoc_options: []
|
160
174
|
require_paths:
|
161
175
|
- lib
|
@@ -163,15 +177,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
163
177
|
requirements:
|
164
178
|
- - "~>"
|
165
179
|
- !ruby/object:Gem::Version
|
166
|
-
version: '2.
|
180
|
+
version: '2.5'
|
167
181
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
168
182
|
requirements:
|
169
183
|
- - ">="
|
170
184
|
- !ruby/object:Gem::Version
|
171
185
|
version: '0'
|
172
186
|
requirements: []
|
173
|
-
rubygems_version: 3.
|
174
|
-
signing_key:
|
187
|
+
rubygems_version: 3.1.2
|
188
|
+
signing_key:
|
175
189
|
specification_version: 4
|
176
190
|
summary: Minify HTML/CSS/JavaScript files.
|
177
191
|
test_files: []
|