squoosh 0.2.1 → 0.3.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 65d794e4fa97573f5ffe9fbc8339df1fcd8ef91908d743be565345a0e5a7b92f
4
- data.tar.gz: 857fb11296b5e4a3989a06d660e44a4c6536780f21d85092e2ab5b11f82bcceb
3
+ metadata.gz: 315473e08078ff495007f1bfddbdcff65fa705e9a0b1184b94d048278fbbc1f3
4
+ data.tar.gz: 5459f4ed5ed7803fe14e4f597180bcfee3de40e234f2d3e5792c2a1f31a456a1
5
5
  SHA512:
6
- metadata.gz: 6487482bb47b8c43b7215ca3d901128fe39abc33044c7ac9cd0d8b2b9f09ac90f9b9ff1d7750bea6ea907b31c4044b0c05e19231871bb9306cb54b508de0dd34
7
- data.tar.gz: 3693641100489cc0128c5f0569eca44607ddac2c126b265b0a837653b6e847e04887034dea3a648049a3841e8d6e368f9d628e375b16eb33c22402328c42d0b2
6
+ metadata.gz: f52727e43f40846d4f2c3e29b0ba8a1d7414908049f7d8e3b82d8f85e32e5842fe573290a5977362992d5e0608b3097844479ba6d72c924a84df4b897bfaa05e
7
+ data.tar.gz: b468345836215f88ae14a6a6d769a9d57dc796cc3746725ae61f56ad3ad328e5da88713612e99fc29bc9f9aadd3119a47a24c75c1da6dc1a6e480ff65789734b
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2016, 2018 Stephen Checkoway
3
+ Copyright (c) 2016, 2018, 2019 Stephen Checkoway
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -54,7 +54,7 @@ Or install it yourself as:
54
54
  ## Usage
55
55
 
56
56
  You can read the documentation
57
- [here](https://www.rubydoc.info/github/stevecheckoway/squoosh/v0.2.0).
57
+ [here](https://www.rubydoc.info/github/stevecheckoway/squoosh/).
58
58
 
59
59
  The three basic minification functions are
60
60
 
@@ -70,14 +70,20 @@ significantly speed up minifying HTML with repeated scripts and style sheets.
70
70
  Create a `_plugins/squoosh.rb` file with the contents
71
71
 
72
72
  ```ruby
73
- require 'squoosh'
74
-
75
- Jekyll::Hooks.register [:documents, :pages], :post_render, priority: :high do |doc|
76
- case File.extname(doc.destination('./'))
77
- when '.html', '.htm'
78
- doc.output = Squoosh::minify_html doc.output
79
- when '.js'
80
- doc.output = Squoosh::minify_js doc.output
73
+ # frozen_string_literal: true
74
+
75
+ if Jekyll.env == 'deploy'
76
+ require 'squoosh'
77
+
78
+ squoosher = Squoosh::Squoosher.new
79
+ Jekyll::Hooks.register(%i[documents pages],
80
+ :post_render, priority: :high) do |doc|
81
+ case File.extname(doc.destination('./'))
82
+ when '.html', '.htm'
83
+ doc.output = squoosher.minify_html(doc.output)
84
+ when '.js'
85
+ doc.output = squoosher.minify_js(doc.output)
86
+ end
81
87
  end
82
88
  end
83
89
  ```
@@ -74,6 +74,7 @@ module Squoosh
74
74
  end
75
75
  @options = DEFAULT_OPTIONS.merge(options)
76
76
  @js_cache = {}
77
+ @inline_script_cache = {}
77
78
  @css_cache = {}
78
79
  end
79
80
 
@@ -111,8 +112,7 @@ module Squoosh
111
112
  # @param content [String] the JavaScript to minify
112
113
  # @return [String] the minified JavaScript
113
114
  def minify_js(content)
114
- @js_cache[content] ||= \
115
- Uglifier.compile(content, @options[:uglifier_options])
115
+ @js_cache[content] ||= uglify(content, @options[:uglifier_options])
116
116
  end
117
117
 
118
118
  # Element kinds
@@ -124,6 +124,13 @@ module Squoosh
124
124
  private_constant :VOID_ELEMENTS, :RAW_TEXT_ELEMENTS
125
125
  private_constant :ESCAPABLE_RAW_TEXT_ELEMENTS, :FOREIGN_ELEMENTS
126
126
 
127
+ INLINE_SCRIPT_OPTIONS = {
128
+ output: {
129
+ inline_script: true
130
+ }
131
+ }.freeze
132
+ private_constant :INLINE_SCRIPT_OPTIONS
133
+
127
134
  private
128
135
 
129
136
  def void_element?(node)
@@ -228,13 +235,31 @@ module Squoosh
228
235
  ).freeze
229
236
  private_constant :EVENT_HANDLERS_XPATH
230
237
 
238
+ def uglify(content, options)
239
+ js = Uglifier.compile(content, options)
240
+ js.chomp!(';')
241
+ js
242
+ end
243
+
244
+ def compress_script(content)
245
+ @inline_script_cache[content] ||= begin
246
+ options = @options[:uglifier_options].merge(INLINE_SCRIPT_OPTIONS)
247
+ uglify(content, options)
248
+ end
249
+ end
250
+
251
+ def compress_event_handler(content)
252
+ @event_handler_cache[content] ||= \
253
+ Uglifier.compile(content, @options[:uglifier_options])
254
+ end
255
+
231
256
  def compress_javascript(doc)
232
257
  # Compress script elements.
233
258
  doc.xpath('//script[not(ancestor::math or ancestor::svg)]').each do |node|
234
259
  type = node['type']&.downcase
235
260
  next unless type.nil? || type == 'text/javascript'
236
261
 
237
- node.content = minify_js node.content
262
+ node.content = compress_script(node.content)
238
263
  end
239
264
  # Compress event handlers.
240
265
  doc.xpath(EVENT_HANDLERS_XPATH).each do |attr|
@@ -272,15 +297,7 @@ module Squoosh
272
297
  end
273
298
  elsif node.element? &&
274
299
  (node.name == 'pre' || node.name == 'textarea')
275
- # Remove leading newline in pre and textarea tags unless there are two
276
- # in a row.
277
- if node.children[0]&.text?
278
- content = node.children[0].content
279
- if content.sub!(/\A\r\n?([^\r]|\z)/, '\1') ||
280
- content.sub!(/\A\n([^\n]|\z)/, '\1')
281
- node.children[0].content = content
282
- end
283
- end
300
+ # Leave the contents of these nodes alone.
284
301
  elsif normal_element?(node) || node.name == 'title'
285
302
  # Compress spaces in normal elements and title.
286
303
  node.children.each { |c| compress_spaces c }
@@ -347,13 +364,23 @@ module Squoosh
347
364
  end
348
365
 
349
366
  # Close start tag.
350
- if node_is_self_closing? node
367
+ if self_closing? node
351
368
  output << ' ' if last_attr_unquoted
352
369
  output << '/'
353
370
  end
354
371
  output << '>'
355
372
  end
356
373
 
374
+ # If pre or textarea start with a newline, double it because the HTML
375
+ # parser strips leading newlines.
376
+ if (node.name == 'pre' || node.name == 'textarea') &&
377
+ !node.children.empty?
378
+ first_child = node.children[0]
379
+ if first_child.text? && first_child.content.start_with?("\n")
380
+ output << "\n"
381
+ end
382
+ end
383
+
357
384
  # Add content.
358
385
  output << node.children.map { |c| stringify_node c }.join
359
386
 
@@ -362,7 +389,11 @@ module Squoosh
362
389
  output.string
363
390
  end
364
391
 
365
- def node_is_self_closing?(node)
392
+ def self_closing?(node)
393
+ # If we're not omitting end tags, then don't mark foreign elements as
394
+ # self closing.
395
+ return false unless @options[:omit_tags]
396
+
366
397
  foreign_element?(node) && node.children.empty?
367
398
  end
368
399
 
@@ -436,7 +467,7 @@ module Squoosh
436
467
  end
437
468
 
438
469
  def omit_end_tag?(node)
439
- return true if void_element? node
470
+ return true if void_element?(node) || self_closing?(node)
440
471
  return false unless @options[:omit_tags]
441
472
  return false if node.parent.name == 'noscript'
442
473
 
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Squoosh
4
4
  # The version of squoosh.
5
- VERSION = '0.2.1'
5
+ VERSION = '0.3.0'
6
6
  end
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.2.1
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stephen Checkoway
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-03-28 00:00:00.000000000 Z
11
+ date: 2019-08-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -114,14 +114,14 @@ dependencies:
114
114
  requirements:
115
115
  - - "~>"
116
116
  - !ruby/object:Gem::Version
117
- version: '2.0'
117
+ version: '2.1'
118
118
  type: :runtime
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
122
  - - "~>"
123
123
  - !ruby/object:Gem::Version
124
- version: '2.0'
124
+ version: '2.1'
125
125
  - !ruby/object:Gem::Dependency
126
126
  name: uglifier
127
127
  requirement: !ruby/object:Gem::Requirement