abqari 1.1.0 → 1.1.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/CHANGELOG.md +106 -1
- data/README.md +7 -5
- data/app/views/partials/_contact_button.html.erb +6 -2
- data/app/views/partials/_head.html.erb +6 -2
- data/lib/abqari/asset_pipeline.rb +18 -0
- data/lib/abqari/minifier.rb +54 -14
- data/lib/abqari/renderer.rb +5 -1
- data/lib/abqari/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: fd411b1e1b18a824d5cee74ee6e557c7135fc973f6fc9edb4f4c806edff7cadf
|
|
4
|
+
data.tar.gz: bb34137c4de0ffb733d1b911f6e523df2cde7b933d196e07d0e4ca4a4fb91460
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b1c8ea8aa8cad1f13f9dc3eddd81fbbedf891d024b6998f8a1f7aacf7c45c66ce783bea05174d983973c46eac5318372addd0d8b590e29871723f29f1d71a40c
|
|
7
|
+
data.tar.gz: 2820827176cec3ecaaf08ad2ceb70c15b506435368154e24d2afc7ea544f2fe959613da696e2bb05eb81eff3011d4c37e07081565e1c4fa2ae2e901073b4e5c8
|
data/CHANGELOG.md
CHANGED
|
@@ -9,6 +9,109 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
9
9
|
|
|
10
10
|
_Nothing yet._
|
|
11
11
|
|
|
12
|
+
## [1.1.2] — 2026-10-09
|
|
13
|
+
|
|
14
|
+
### Fixed
|
|
15
|
+
|
|
16
|
+
- **Changing `fonts:` and re-running `bin/fetch-fonts` didn't reach
|
|
17
|
+
returning visitors; they kept the old fonts for up to a year.** The
|
|
18
|
+
head linked the font stylesheet at a fixed `/assets/fonts/fonts.css`,
|
|
19
|
+
and the generated `_headers` serves all of `/assets/*` with
|
|
20
|
+
`Cache-Control: public, max-age=31536000, immutable`, so a browser
|
|
21
|
+
that had cached the old file never asked for it again. The new
|
|
22
|
+
families fell back to system fonts. It hid because a first visit, a
|
|
23
|
+
hard reload, and the dev server (which doesn't apply `_headers`) all
|
|
24
|
+
show the new fonts; only returning visitors on a host that honours
|
|
25
|
+
`_headers` were stuck. `syntax.css` had the same bug before the CSS
|
|
26
|
+
bundle.
|
|
27
|
+
|
|
28
|
+
`vendor/fonts/fonts.css` now goes through the asset pipeline and is
|
|
29
|
+
linked as `/assets/fonts/fonts.<hash>.css`, minified in production,
|
|
30
|
+
so a re-fetch changes the URL. Dev-server rebuilds now re-render
|
|
31
|
+
every page after a re-fetch, because every head carries the hash.
|
|
32
|
+
The head no longer emits the link when `fonts:` is set but
|
|
33
|
+
`bin/fetch-fonts` hasn't run; it used to link a stylesheet that
|
|
34
|
+
404'd.
|
|
35
|
+
|
|
36
|
+
If your site overrides `_head.html.erb`, change its font link to
|
|
37
|
+
`<%= asset_path('fonts/fonts.css') %>`. The unhashed copy still ships
|
|
38
|
+
at `/assets/fonts/fonts.css`, so an overridden head keeps working,
|
|
39
|
+
but it keeps the stale-cache problem.
|
|
40
|
+
|
|
41
|
+
## [1.1.1] — 2026-08-11
|
|
42
|
+
|
|
43
|
+
Bug-fix release, all of it found while building a site against the
|
|
44
|
+
published 1.1.0 gem.
|
|
45
|
+
|
|
46
|
+
Upgrade if you minify (the default in production): a tag name written
|
|
47
|
+
inside an HTML comment could silently delete everything between that
|
|
48
|
+
comment and the next one, and layouts carry explanatory comments as a
|
|
49
|
+
matter of course. Upgrade too if you use the contact button — it never
|
|
50
|
+
worked at all.
|
|
51
|
+
|
|
52
|
+
### Fixed
|
|
53
|
+
|
|
54
|
+
- **A tag name written inside an HTML comment silently deleted page
|
|
55
|
+
content — production builds only.** `Minifier.minify` stashed
|
|
56
|
+
`<pre>` / `<textarea>` / `<script>` / `<style>` blocks *before* it
|
|
57
|
+
stripped comments, so ordinary explanatory prose in a layout or
|
|
58
|
+
partial — `<!-- see the <script> tag below -->` — opened a
|
|
59
|
+
"preserved" region at the comment's own text. That region ran to the
|
|
60
|
+
next genuine `</script>` further down the document, swallowing the
|
|
61
|
+
comment's `-->` on the way; the orphaned `<!--` then paired with some
|
|
62
|
+
later `-->`, and the comment pass deleted the placeholder along with
|
|
63
|
+
everything between the two. Pages shipped with an empty `<main>`
|
|
64
|
+
against a green build, and only in production, because dev doesn't
|
|
65
|
+
minify.
|
|
66
|
+
|
|
67
|
+
Comments and preserved blocks are now matched in one ordered
|
|
68
|
+
left-to-right pass, so whichever construct starts first consumes the
|
|
69
|
+
other and tag-like text inside a comment can't open a region. This is
|
|
70
|
+
the same single-pass discipline (and the same failure class) as the
|
|
71
|
+
CSS minifier's comment/string handling. Conditional comments
|
|
72
|
+
(`<!--[if …]>`) are stashed rather than stripped, so they now survive
|
|
73
|
+
verbatim instead of having their contents whitespace-collapsed.
|
|
74
|
+
|
|
75
|
+
- **A document beginning or ending with a `<pre>` / `<script>` /
|
|
76
|
+
`<style>` block leaked the minifier's internal placeholder.** The
|
|
77
|
+
final trim used `String#strip`, which removes NUL bytes as well as
|
|
78
|
+
whitespace, truncating the stash sentinel so the placeholder never
|
|
79
|
+
matched on restore and shipped as literal `ABQARI_PRESERVED_0` text.
|
|
80
|
+
Real pages end in `</html>`, which is why this stayed hidden. Both
|
|
81
|
+
the HTML and CSS minifiers now trim whitespace only.
|
|
82
|
+
|
|
83
|
+
- **The contact button did nothing when clicked.** `contact-button.js`
|
|
84
|
+
delegates on `.contact-button[data-user][data-domain]`, but the
|
|
85
|
+
partial only ever emitted the styling classes (`btn
|
|
86
|
+
btn-outline-secondary`, or whatever `css_class:` was set to) — the
|
|
87
|
+
wrapper's `.contact-button-wrapper` is a different class token, so
|
|
88
|
+
the selector matched nothing on every site that enabled the button.
|
|
89
|
+
No console error; the button just sat there. `.contact-button` is now
|
|
90
|
+
emitted as a styling-free JS hook alongside `css_class:`, so
|
|
91
|
+
overriding the variant can't break the handler.
|
|
92
|
+
|
|
93
|
+
- **`contact.subject:` rendered a malformed `data-subject` attribute.**
|
|
94
|
+
`_contact_button.html.erb` built the whole attribute as a Ruby string
|
|
95
|
+
and emitted it through `<%= %>`, which auto-escapes under Erubi — so
|
|
96
|
+
the attribute's own quote characters came out as entities
|
|
97
|
+
(`data-subject="Project enquiry"`) and the subject would
|
|
98
|
+
not have reached `contact-button.js` even once the click handler
|
|
99
|
+
fired. The attribute name and quotes are now literal template text;
|
|
100
|
+
only the value passes through the escape.
|
|
101
|
+
|
|
102
|
+
### Changed
|
|
103
|
+
|
|
104
|
+
- `Minifier::PRESERVE_REGEX` and `Minifier::COMMENT_REGEX` are gone,
|
|
105
|
+
replaced by the single `Minifier::HTML_TOKEN_REGEX`. Both were
|
|
106
|
+
internal to `minify` and nothing outside the engine has reason to
|
|
107
|
+
reference them; they're called out because 1.1.0 is on RubyGems and
|
|
108
|
+
removing a public constant is technically breaking. `PRESERVE_TAGS`
|
|
109
|
+
is unchanged.
|
|
110
|
+
|
|
111
|
+
- `test/low_priority_hardening_test.rb` no longer relies on
|
|
112
|
+
`Object#stub`. Minitest 6 dropped `minitest/mock` from the default
|
|
113
|
+
install, so that test errored on every run of the suite.
|
|
114
|
+
|
|
12
115
|
## [1.1.0] — 2026-08-06
|
|
13
116
|
|
|
14
117
|
First public release on RubyGems. 1.0.0 below was tagged in git but
|
|
@@ -884,6 +987,8 @@ run a real working author / publisher site.
|
|
|
884
987
|
commonmarker ≥ 2.4 ships precompiled 4.0 binaries, which is what
|
|
885
988
|
the `~> 2.4` floor bought.
|
|
886
989
|
|
|
887
|
-
[Unreleased]: https://github.com/grantrayner/abqari/compare/v1.1.
|
|
990
|
+
[Unreleased]: https://github.com/grantrayner/abqari/compare/v1.1.2...HEAD
|
|
991
|
+
[1.1.2]: https://github.com/grantrayner/abqari/compare/v1.1.1...v1.1.2
|
|
992
|
+
[1.1.1]: https://github.com/grantrayner/abqari/compare/v1.1.0...v1.1.1
|
|
888
993
|
[1.1.0]: https://github.com/grantrayner/abqari/compare/v1.0.0...v1.1.0
|
|
889
994
|
[1.0.0]: https://github.com/grantrayner/abqari/releases/tag/v1.0.0
|
data/README.md
CHANGED
|
@@ -11,7 +11,7 @@ optional overrides), while the engine — layouts, themes, helpers, asset
|
|
|
11
11
|
pipeline — lives in the dependency. Forking the engine is also
|
|
12
12
|
supported for users who want to own all the code.
|
|
13
13
|
|
|
14
|
-
> **Status:** v1.1.
|
|
14
|
+
> **Status:** v1.1.2 — see
|
|
15
15
|
> [CHANGELOG.md](https://github.com/grantrayner/abqari/blob/main/CHANGELOG.md).
|
|
16
16
|
> Distributed via RubyGems (`gem install abqari`) and as a Bundler
|
|
17
17
|
> path/git source. The API follows [semver](https://semver.org/) from
|
|
@@ -174,7 +174,7 @@ Test that it worked:
|
|
|
174
174
|
abqari version
|
|
175
175
|
```
|
|
176
176
|
|
|
177
|
-
You should see a version number, e.g. `abqari 1.1.
|
|
177
|
+
You should see a version number, e.g. `abqari 1.1.2`. If you get
|
|
178
178
|
`command not found`, see [Troubleshooting](#troubleshooting) below.
|
|
179
179
|
|
|
180
180
|
### Step 3 — Create your first site
|
|
@@ -470,7 +470,7 @@ end
|
|
|
470
470
|
Or — pin to a git ref while tracking pre-release work:
|
|
471
471
|
|
|
472
472
|
```ruby
|
|
473
|
-
gem 'abqari', git: 'https://github.com/grantrayner/abqari.git', tag: 'v1.1.
|
|
473
|
+
gem 'abqari', git: 'https://github.com/grantrayner/abqari.git', tag: 'v1.1.2'
|
|
474
474
|
```
|
|
475
475
|
|
|
476
476
|
Install the libvips C library once (hard dep for the image pipeline):
|
|
@@ -1629,7 +1629,9 @@ Then run once:
|
|
|
1629
1629
|
bin/fetch-fonts
|
|
1630
1630
|
```
|
|
1631
1631
|
|
|
1632
|
-
Abqari downloads the woff2 files to `vendor/fonts/`, generates a `fonts.css` with rewritten URLs, and serves everything from `/assets/fonts/` at build time. The
|
|
1632
|
+
Abqari downloads the woff2 files to `vendor/fonts/`, generates a `fonts.css` with rewritten URLs, and serves everything from `/assets/fonts/` at build time. The stylesheet is fingerprinted like any other asset (`/assets/fonts/fonts.<hash>.css`), so changing `fonts:` and re-running `bin/fetch-fonts` busts the immutable cache. The head partial links it whenever `fonts:` is configured and the fetch has run.
|
|
1633
|
+
|
|
1634
|
+
If you override the head partial, link the stylesheet with `<%= asset_path('fonts/fonts.css') %>`. An unhashed copy still ships at `/assets/fonts/fonts.css`, but `_headers` caches it for a year, so returning visitors won't see font changes.
|
|
1633
1635
|
|
|
1634
1636
|
## Icons
|
|
1635
1637
|
|
|
@@ -2550,7 +2552,7 @@ taking a feature release. To track a fork or an unreleased branch
|
|
|
2550
2552
|
instead, swap the line for a git source:
|
|
2551
2553
|
|
|
2552
2554
|
```ruby
|
|
2553
|
-
gem 'abqari', git: 'https://github.com/grantrayner/abqari.git', tag: 'v1.1.
|
|
2555
|
+
gem 'abqari', git: 'https://github.com/grantrayner/abqari.git', tag: 'v1.1.2'
|
|
2554
2556
|
```
|
|
2555
2557
|
|
|
2556
2558
|
The cadence: read [CHANGELOG.md](https://github.com/grantrayner/abqari/blob/main/CHANGELOG.md) before each upgrade,
|
|
@@ -15,6 +15,10 @@
|
|
|
15
15
|
Place anywhere by calling `<%%= render 'partials/contact_button' %%>`
|
|
16
16
|
from any layout. Already wired into the default about layout.
|
|
17
17
|
|
|
18
|
+
`.contact-button` is the JS hook contact-button.js delegates on. It's
|
|
19
|
+
always emitted and carries no styling, so `css_class:` can be anything
|
|
20
|
+
without breaking the click handler — keep the two roles separate.
|
|
21
|
+
|
|
18
22
|
Default styling: `.btn .btn-outline-secondary` from _common.css.
|
|
19
23
|
Override with `css_class:` to swap the variant — e.g.
|
|
20
24
|
<%%= render 'partials/contact_button', css_class: 'btn btn-success' %%>
|
|
@@ -31,10 +35,10 @@
|
|
|
31
35
|
<% subject = cfg['subject'] %>
|
|
32
36
|
<% button_class = defined?(css_class) ? css_class.to_s : 'btn btn-outline-secondary' %>
|
|
33
37
|
<p class="contact-button-wrapper">
|
|
34
|
-
<button type="button" class="<%= button_class %>"
|
|
38
|
+
<button type="button" class="contact-button <%= button_class %>"
|
|
35
39
|
data-user="<%= user %>"
|
|
36
40
|
data-domain="<%= domain %>"
|
|
37
|
-
|
|
41
|
+
<% if subject %>data-subject="<%= subject %>"<% end %>>
|
|
38
42
|
<%= label %>
|
|
39
43
|
</button>
|
|
40
44
|
</p>
|
|
@@ -367,8 +367,12 @@
|
|
|
367
367
|
<% Array(site.config['fonts_preload']).each do |path| %>
|
|
368
368
|
<link rel="preload" href="<%= sanitized_url(path) %>" as="font" type="font/woff2" crossorigin>
|
|
369
369
|
<% end %>
|
|
370
|
-
|
|
371
|
-
|
|
370
|
+
<%# Fingerprinted, never the fixed `/assets/fonts/fonts.css` — that
|
|
371
|
+
URL is cached `immutable`, so a re-fetch never reached returning
|
|
372
|
+
visitors. No link until `bin/fetch-fonts` has run. %>
|
|
373
|
+
<% fonts_css = Array(site.config['fonts']).any? && optional_asset_path('fonts/fonts.css') %>
|
|
374
|
+
<% if fonts_css %>
|
|
375
|
+
<link rel="stylesheet" href="<%= fonts_css %>">
|
|
372
376
|
<% end %>
|
|
373
377
|
<%# Render-blocking CSS ships as ONE fingerprinted bundle (syntax +
|
|
374
378
|
_common + theme app.css + site.css, same cascade order as the
|
|
@@ -8,6 +8,7 @@ module Abqari
|
|
|
8
8
|
OUTPUT_SUBDIR = 'assets'
|
|
9
9
|
HASH_LENGTH = 10
|
|
10
10
|
BUNDLE_LOGICAL = 'css/bundle.css'
|
|
11
|
+
FONTS_LOGICAL = 'fonts/fonts.css'
|
|
11
12
|
# A theme name is a directory name under themes/ and nothing more.
|
|
12
13
|
# The strict pattern is load-bearing: the name is joined into
|
|
13
14
|
# filesystem paths in several places (here, ArtifactWriter,
|
|
@@ -55,6 +56,7 @@ module Abqari
|
|
|
55
56
|
[engine_app_assets, site_app_assets].uniq.each do |dir|
|
|
56
57
|
process_dir(dir) if dir && Dir.exist?(dir)
|
|
57
58
|
end
|
|
59
|
+
process_font_stylesheet
|
|
58
60
|
build_css_bundle
|
|
59
61
|
end
|
|
60
62
|
|
|
@@ -172,6 +174,22 @@ module Abqari
|
|
|
172
174
|
@paths[logical] = "/#{OUTPUT_SUBDIR}/#{fingerprinted}"
|
|
173
175
|
end
|
|
174
176
|
|
|
177
|
+
# The `bin/fetch-fonts` stylesheet gets a content hash like any
|
|
178
|
+
# other asset. At its old fixed URL it sat under the `/assets/*
|
|
179
|
+
# immutable` cache rule, so a site that changed `fonts:` and
|
|
180
|
+
# re-fetched kept serving returning visitors the old `@font-face`
|
|
181
|
+
# rules for a year. Its woff2 `url()`s are root-absolute, so the
|
|
182
|
+
# renamed file still resolves them. ArtifactWriter#copy_fonts keeps
|
|
183
|
+
# shipping the unhashed copy for sites that override the head.
|
|
184
|
+
def process_font_stylesheet
|
|
185
|
+
source = File.join(@site.site_root, 'vendor', 'fonts', 'fonts.css')
|
|
186
|
+
return unless File.file?(source)
|
|
187
|
+
return if @site.external_symlink?(source)
|
|
188
|
+
|
|
189
|
+
write_asset(FONTS_LOGICAL, processed_content(source, FONTS_LOGICAL))
|
|
190
|
+
@sources[FONTS_LOGICAL] = source
|
|
191
|
+
end
|
|
192
|
+
|
|
175
193
|
def processed_content(entry, logical)
|
|
176
194
|
raw = File.binread(entry)
|
|
177
195
|
kind = MINIFY_KINDS[File.extname(logical)]
|
data/lib/abqari/minifier.rb
CHANGED
|
@@ -6,20 +6,46 @@ module Abqari
|
|
|
6
6
|
# <pre>, <textarea>, <script>, and <style> blocks where whitespace matters.
|
|
7
7
|
module Minifier
|
|
8
8
|
PRESERVE_TAGS = %w[pre textarea script style].freeze
|
|
9
|
-
PRESERVE_REGEX = /<(#{PRESERVE_TAGS.join('|')})\b[^>]*>.*?<\/\1>/im.freeze
|
|
10
9
|
PLACEHOLDER = "\x00ABQARI_PRESERVED_%d\x00"
|
|
11
|
-
|
|
10
|
+
|
|
11
|
+
# Comments and preserved blocks are recognised in ONE left-to-right
|
|
12
|
+
# pass, via ordered alternation, so whichever construct STARTS first
|
|
13
|
+
# consumes the other — the same single-pass discipline (and for the
|
|
14
|
+
# same reason) as CSS_TOKEN_REGEX below.
|
|
15
|
+
#
|
|
16
|
+
# Stashing preserved blocks first and stripping comments afterwards
|
|
17
|
+
# is what this replaced, and it was wrong: a tag-like string written
|
|
18
|
+
# inside a comment — `<!-- see the <script> tag -->` in a layout —
|
|
19
|
+
# opened a preserved region at the `<script>` text, which then ran
|
|
20
|
+
# to the next GENUINE `</script>` further down the document,
|
|
21
|
+
# swallowing the comment's own `-->` on the way. The orphaned `<!--`
|
|
22
|
+
# then paired with some later `-->`, and the comment pass deleted
|
|
23
|
+
# the placeholder and everything between. Pages came out with an
|
|
24
|
+
# empty `<main>`, in production builds only (dev doesn't minify).
|
|
25
|
+
#
|
|
26
|
+
# Comments matched here are dropped, except conditional comments
|
|
27
|
+
# (`<!--[if …]>`), which are stashed so they survive verbatim.
|
|
28
|
+
HTML_TOKEN_REGEX = %r{
|
|
29
|
+
(?<comment><!--.*?-->)
|
|
30
|
+
|
|
|
31
|
+
(?<preserved><(?<tag>#{PRESERVE_TAGS.join('|')})\b[^>]*>.*?</\k<tag>>)
|
|
32
|
+
}imx.freeze
|
|
33
|
+
CONDITIONAL_COMMENT_REGEX = /\A<!--\[if/i.freeze
|
|
12
34
|
|
|
13
35
|
def self.minify(html)
|
|
14
36
|
preserved = []
|
|
15
37
|
|
|
16
|
-
protected_html = html.gsub(
|
|
17
|
-
|
|
18
|
-
|
|
38
|
+
protected_html = html.gsub(HTML_TOKEN_REGEX) do
|
|
39
|
+
match = ::Regexp.last_match
|
|
40
|
+
if match[:comment] && !match[:comment].match?(CONDITIONAL_COMMENT_REGEX)
|
|
41
|
+
''
|
|
42
|
+
else
|
|
43
|
+
preserved << match[0]
|
|
44
|
+
format(PLACEHOLDER, preserved.length - 1)
|
|
45
|
+
end
|
|
19
46
|
end
|
|
20
47
|
|
|
21
48
|
minified = protected_html
|
|
22
|
-
.gsub(COMMENT_REGEX, '')
|
|
23
49
|
# Collapse inter-tag whitespace to a SINGLE space, not
|
|
24
50
|
# nothing. `<em>a</em> <strong>b</strong>` must stay
|
|
25
51
|
# "a b" — deleting the space renders "ab". The size win
|
|
@@ -29,12 +55,28 @@ module Abqari
|
|
|
29
55
|
# significant whitespace inside them is untouched.)
|
|
30
56
|
.gsub(/>\s+</, '> <')
|
|
31
57
|
.gsub(/\s{2,}/, ' ')
|
|
32
|
-
|
|
58
|
+
minified = trim(minified)
|
|
33
59
|
|
|
34
|
-
minified
|
|
35
|
-
|
|
36
|
-
|
|
60
|
+
restore(minified, preserved)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# `String#strip` also removes NUL bytes, which would bite the
|
|
64
|
+
# PLACEHOLDER's trailing \x00 whenever a document starts or ends
|
|
65
|
+
# with a preserved block — the placeholder then fails to match on
|
|
66
|
+
# restore and ships to the browser as literal
|
|
67
|
+
# "\x00ABQARI_PRESERVED_0" text. `\s` in a Ruby regex is whitespace
|
|
68
|
+
# only, so trimming this way leaves the sentinels intact.
|
|
69
|
+
TRIM_REGEX = /\A\s+|\s+\z/.freeze
|
|
70
|
+
PLACEHOLDER_REGEX = /\x00ABQARI_PRESERVED_(\d+)\x00/.freeze
|
|
71
|
+
|
|
72
|
+
def self.trim(text)
|
|
73
|
+
text.gsub(TRIM_REGEX, '')
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def self.restore(text, preserved)
|
|
77
|
+
text.gsub(PLACEHOLDER_REGEX) { preserved[::Regexp.last_match(1).to_i] }
|
|
37
78
|
end
|
|
79
|
+
private_class_method :trim, :restore
|
|
38
80
|
|
|
39
81
|
# Comments and quoted strings are recognised in ONE left-to-right
|
|
40
82
|
# pass, via ordered alternation, so whichever construct STARTS first
|
|
@@ -81,11 +123,9 @@ module Abqari
|
|
|
81
123
|
.gsub(/\s+/, ' ')
|
|
82
124
|
.gsub(/\s*([{};,>])\s*/, '\1')
|
|
83
125
|
.gsub(';}', '}')
|
|
84
|
-
|
|
126
|
+
minified = trim(minified)
|
|
85
127
|
|
|
86
|
-
minified
|
|
87
|
-
preserved[::Regexp.last_match(1).to_i]
|
|
88
|
-
end
|
|
128
|
+
restore(minified, preserved)
|
|
89
129
|
end
|
|
90
130
|
|
|
91
131
|
JS_LINE_COMMENT_REGEX = %r{^[ \t]*//.*$}.freeze
|
data/lib/abqari/renderer.rb
CHANGED
|
@@ -48,13 +48,17 @@ module Abqari
|
|
|
48
48
|
# `compute_shared_deps_mtime` time so we only walk the active
|
|
49
49
|
# theme's directory, not every theme that happens to ship with
|
|
50
50
|
# the gem.
|
|
51
|
+
#
|
|
52
|
+
# `vendor/fonts/fonts.css` is here because every page's head links
|
|
53
|
+
# it by content hash; a re-fetch must re-render them all.
|
|
51
54
|
GLOBAL_DEP_GLOBS = [
|
|
52
55
|
'app/views/partials/**/*',
|
|
53
56
|
'app/icons/**/*',
|
|
54
57
|
'app/assets/**/*',
|
|
55
58
|
'lib/**/*',
|
|
56
59
|
'config/**/*',
|
|
57
|
-
'data/**/*'
|
|
60
|
+
'data/**/*',
|
|
61
|
+
'vendor/fonts/fonts.css'
|
|
58
62
|
].freeze
|
|
59
63
|
|
|
60
64
|
# The renderer only needs the frontmatter block (no body), but
|
data/lib/abqari/version.rb
CHANGED