Skip to content

Commit e954d77

Browse files
authored
Fix offline leaflet (#2420)
Fixes #2419 by downloading leaflet images. Also changed the path where the libraries are downloaded to avoid not downloading files with same name. --------- Signed-off-by: George Araujo <[email protected]>
1 parent 0a80d5e commit e954d77

9 files changed

+147
-61
lines changed

_config.yml

+23-4
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,8 @@ enable_video_embedding: false # enables video embedding for bibtex entries. If f
418418
# -----------------------------------------------------------------------------
419419

420420
# Add the url, version and integrity hash of the libraries you use in your site.
421+
# The integrity hash is used to ensure that the library is not tampered with.
422+
# Integrity hashes not provided by the libraries were generated using https://www.srihash.org/
421423
third_party_libraries:
422424
download: false # if true, download the versions of the libraries specified below and use the downloaded files
423425
bootstrap-table:
@@ -429,6 +431,8 @@ third_party_libraries:
429431
js: "https://cdn.jsdelivr.net/npm/bootstrap-table@{{version}}/dist/bootstrap-table.min.js"
430432
version: "1.22.4"
431433
chartjs:
434+
integrity:
435+
js: "sha256-0q+JdOlScWOHcunpUk21uab1jW7C1deBQARHtKMcaB4="
432436
url:
433437
js: "https://cdn.jsdelivr.net/npm/chart.js@{{version}}/dist/chart.umd.min.js"
434438
version: "4.4.1"
@@ -476,9 +480,14 @@ third_party_libraries:
476480
js: https://cdn.jsdelivr.net/npm/imagesloaded@{{version}}/imagesloaded.pkgd.min.js
477481
version: "5.0.0"
478482
img-comparison-slider:
483+
integrity:
484+
css: "sha256-3qTIuuUWIFnnU3LpQMjqiXc0p09rvd0dmj+WkpQXSR8="
485+
js: "sha256-EXHg3x1K4oIWdyohPeKX2ZS++Wxt/FRPH7Nl01nat1o="
486+
map: "sha256-3wfqS2WU5kGA/ePcgFzJXl5oSN1QsgZI4/edprTgX8w="
479487
url:
480488
css: "https://cdn.jsdelivr.net/npm/img-comparison-slider@{{version}}/dist/styles.min.css"
481489
js: "https://cdn.jsdelivr.net/npm/img-comparison-slider@{{version}}/dist/index.min.js"
490+
map: "https://cdn.jsdelivr.net/npm/img-comparison-slider@{{version}}/dist/index.js.map"
482491
version: "8.0.6"
483492
jquery:
484493
integrity:
@@ -488,15 +497,20 @@ third_party_libraries:
488497
version: "3.6.0"
489498
leaflet:
490499
integrity:
491-
css: "sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY="
492-
js: "sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo="
500+
css: "sha256-q9ba7o845pMPFU+zcAll8rv+gC+fSovKsOoNQ6cynuQ="
501+
js: "sha256-MgH13bFTTNqsnuEoqNPBLDaqxjGH+lCpqrukmXc8Ppg="
493502
js_map: "sha256-YAoQ3FzREN4GmVENMir8vgHHypC0xfSK3CAxTHCqx1M="
503+
local:
504+
images: "images/"
494505
url:
495-
css: "https://cdn.jsdelivr.net/npm/leaflet@{{version}}/dist/leaflet.css"
496-
js: "https://cdn.jsdelivr.net/npm/leaflet@{{version}}/dist/leaflet.js"
506+
css: "https://cdn.jsdelivr.net/npm/leaflet@{{version}}/dist/leaflet.min.css"
507+
images: "https://cdn.jsdelivr.net/npm/leaflet@{{version}}/dist/images/"
508+
js: "https://cdn.jsdelivr.net/npm/leaflet@{{version}}/dist/leaflet.min.js"
497509
js_map: "https://cdn.jsdelivr.net/npm/leaflet@{{version}}/dist/leaflet.js.map"
498510
version: "1.9.4"
499511
mathjax:
512+
integrity:
513+
js: "sha256-rjmgmaB99riUNcdlrDtcAiwtLIojSxNyUFdl+Qh+rB4="
500514
local:
501515
fonts: "output/chtml/fonts/woff-v2/"
502516
url:
@@ -538,6 +552,9 @@ third_party_libraries:
538552
js: "https://cdnjs.cloudflare.com/polyfill/v{{version}}/polyfill.min.js?features=es6"
539553
version: "3"
540554
pseudocode:
555+
integrity:
556+
css: "sha256-VwMV//xgBPDyRFVSOshhRhzJRDyBmIACniLPpeXNUdc="
557+
js: "sha256-aVkDxqyzrB+ExUsOY9PdyelkDhn/DfrjWu08aVpqNlo="
541558
url:
542559
css: "https://cdn.jsdelivr.net/npm/pseudocode@{{version}}/build/pseudocode.min.css"
543560
js: "https://cdn.jsdelivr.net/npm/pseudocode@{{version}}/build/pseudocode.min.js"
@@ -546,9 +563,11 @@ third_party_libraries:
546563
integrity:
547564
css: "sha256-yUoNxsvX+Vo8Trj3lZ/Y5ZBf8HlBFsB6Xwm7rH75/9E="
548565
js: "sha256-BPrwikijIybg9OQC5SYFFqhBjERYOn97tCureFgYH1E="
566+
map: "sha256-lbF5CsospW93otqvWOIbbhj80CjazrZXvamD7nC7TBI="
549567
url:
550568
css: "https://cdn.jsdelivr.net/npm/swiper@{{version}}/swiper-bundle.min.css"
551569
js: "https://cdn.jsdelivr.net/npm/swiper@{{version}}/swiper-element-bundle.min.js"
570+
map: "https://cdn.jsdelivr.net/npm/swiper@{{version}}/swiper-element-bundle.min.js.map"
552571
version: "11.0.5"
553572
swiper-map:
554573
integrity:

_includes/head.liquid

+3
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
defer
5353
rel="stylesheet"
5454
href="{{ site.third_party_libraries.pseudocode.url.css }}"
55+
integrity="{{ site.third_party_libraries.pseudocode.integrity.css }}"
5556
crossorigin="anonymous"
5657
>
5758
{% endif %}
@@ -127,6 +128,8 @@
127128
defer
128129
rel="stylesheet"
129130
href="{{ site.third_party_libraries.img-comparison-slider.url.css }}"
131+
integrity="{{ site.third_party_libraries.img-comparison-slider.integrity.css }}"
132+
crossorigin="anonymous"
130133
>
131134
{% endif %}
132135
<!-- Image slider -->

_includes/scripts/chartjs.liquid

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
{% if page.chart and page.chart.chartjs %}
2-
<script defer src="{{ site.third_party_libraries.chartjs.url.js }}"></script>
2+
<script
3+
defer
4+
src="{{ site.third_party_libraries.chartjs.url.js }}"
5+
integrity="{{ site.third_party_libraries.chartjs.integrity.js }}"
6+
crossorigin="anonymous"
7+
></script>
38
<script>
49
$(document).ready(function () {
510
var $canvas = null,

_includes/scripts/imageLayouts.liquid

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
{% if page.images %}
22
{% if page.images.compare %}
3-
<script defer src="{{ site.third_party_libraries.img-comparison-slider.url.js }}"></script>
3+
<script
4+
defer
5+
src="{{ site.third_party_libraries.img-comparison-slider.url.js }}"
6+
integrity="{{ site.third_party_libraries.img-comparison-slider.integrity.js }}"
7+
crossorigin="anonymous"
8+
></script>
49
{% endif %}
510
{% if page.images.slider %}
611
<script

_includes/scripts/leaflet.liquid

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<script
33
src="{{ site.third_party_libraries.leaflet.url.js }}"
44
integrity="{{ site.third_party_libraries.leaflet.integrity.js }}"
5-
crossorigin=""
5+
crossorigin="anonymous"
66
></script>
77
<script>
88
/* Create leaflet map as another node and hide the code block, appending the leaflet node after it */

_includes/scripts/mathjax.liquid

+7-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,13 @@
1313
type="text/javascript"
1414
id="MathJax-script"
1515
src="{{ site.third_party_libraries.mathjax.url.js }}"
16+
integrity="{{ site.third_party_libraries.mathjax.integrity.js }}"
17+
crossorigin="anonymous"
18+
></script>
19+
<script
20+
defer
21+
src="{{ site.third_party_libraries.polyfill.url.js }}"
22+
crossorigin="anonymous"
1623
></script>
17-
<script defer src="{{ site.third_party_libraries.polyfill.url.js }}"></script>
1824
{% endunless %}
1925
{% endif %}

_includes/scripts/pseudocode.liquid

+4
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,14 @@
2020
type="text/javascript"
2121
id="MathJax-script"
2222
src="{{ site.third_party_libraries.mathjax.url.js }}"
23+
integrity="{{ site.third_party_libraries.mathjax.integrity.js }}"
24+
crossorigin="anonymous"
2325
></script>
2426
<script
2527
type="text/javascript"
2628
src="{{ site.third_party_libraries.pseudocode.url.js }}"
29+
integrity="{{ site.third_party_libraries.pseudocode.integrity.js }}"
30+
crossorigin="anonymous"
2731
></script>
2832
<script>
2933
document.onreadystatechange = () => {

_includes/scripts/tikzjax.liquid

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
11
{% if page.tikzjax %}
2-
<script defer src="https://tikzjax.com/v1/tikzjax.js"></script>
2+
<script
3+
defer
4+
src="https://tikzjax.com/v1/tikzjax.js"
5+
integrity="sha256-f4Ln8BLwo8WdQPYX6W/2l0/YvKVk+mgIVe32uEf6zU4="
6+
crossorigin="anonymous"
7+
></script>
38
{% endif %}

_plugins/download-3rd-party.rb

+91-52
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,54 @@
66
require 'open-uri'
77
require 'uri'
88

9+
font_file_types = ['otf', 'ttf', 'woff', 'woff2']
10+
image_file_types = ['.gif', '.jpg', '.jpeg', '.png', '.webp']
11+
12+
def download_and_change_rule_set_url(rule_set, rule, dest, dirname, config, file_types)
13+
# check if the rule has a url
14+
if rule_set[rule].include?('url(')
15+
# get the file url
16+
url = rule_set[rule].split('url(').last.split(')').first
17+
18+
# remove quotes from the url
19+
if url.start_with?('"') || url.start_with?("'")
20+
url = url[1..-2]
21+
end
22+
23+
file_name = url.split('/').last.split('?').first
24+
25+
# verify if the file is of the correct type
26+
if file_name.end_with?(*file_types)
27+
# fix the url if it is not an absolute url
28+
unless url.start_with?('https://')
29+
url = URI.join(url, url).to_s
30+
end
31+
32+
# download the file
33+
download_file(url, File.join(dest, file_name))
34+
35+
# change the url to the local file, considering baseurl
36+
previous_rule = rule_set[rule]
37+
if config['baseurl']
38+
# add rest of the src attribute if it exists
39+
if rule_set[rule].split(' ').length > 1
40+
rule_set[rule] = "url(#{File.join(config['baseurl'], 'assets', 'libs', dirname, file_name)}) #{rule_set[rule].split(' ').last}"
41+
else
42+
rule_set[rule] = "url(#{File.join(config['baseurl'], 'assets', 'libs', dirname, file_name)})"
43+
end
44+
else
45+
# add rest of the src attribute if it exists
46+
if rule_set[rule].split(' ').length > 1
47+
rule_set[rule] = "url(#{File.join('/assets', 'libs', dirname, file_name)}) #{rule_set[rule].split(' ').last}"
48+
else
49+
rule_set[rule] = "url(#{File.join('/assets', 'libs', dirname, file_name)})"
50+
end
51+
end
52+
puts "Changed #{previous_rule} to #{rule_set[rule]}"
53+
end
54+
end
55+
end
56+
957
def download_file(url, dest)
1058
# only try to download the file if url doesn't start with | for security reasons
1159
if url.start_with?('|')
@@ -34,7 +82,7 @@ def download_file(url, dest)
3482
end
3583
end
3684

37-
def download_fonts(url, dest)
85+
def download_fonts(url, dest, file_types)
3886
# only try to download the file if url doesn't start with | for security reasons
3987
if url.start_with?('|')
4088
return
@@ -50,15 +98,39 @@ def download_fonts(url, dest)
5098
file_name = link['href'].split('/').last.split('?').first
5199

52100
# verify if the file is a font file
53-
if file_name.end_with?('.woff', '.woff2', '.ttf', '.otf')
101+
if file_name.end_with?(*file_types)
54102
# download the file and change the url to the local file
55103
download_file(URI.join(url, link['href']).to_s, File.join(dest, file_name))
56104
end
57105
end
58106
end
59107
end
60108

61-
def download_fonts_from_css(config, url, dest)
109+
def download_images(url, dest, file_types)
110+
# only try to download the file if url doesn't start with | for security reasons
111+
if url.start_with?('|')
112+
return
113+
end
114+
115+
# only download images if the directory doesn't exist or is empty
116+
unless File.directory?(dest) && !Dir.empty?(dest)
117+
puts "Downloading images from #{url} to #{dest}"
118+
# get available fonts from the url
119+
doc = Nokogiri::HTML(URI.open(url, "User-Agent" => "Ruby/#{RUBY_VERSION}"))
120+
doc.xpath('/html/body/div/div[3]/table/tbody/tr/td[1]/a').each do |link|
121+
# get the file name from the url
122+
file_name = link['href'].split('/').last.split('?').first
123+
124+
# verify if the file is a font file
125+
if file_name.end_with?(*file_types)
126+
# download the file and change the url to the local file
127+
download_file(URI.join(url, link['href']).to_s, File.join(dest, file_name))
128+
end
129+
end
130+
end
131+
end
132+
133+
def download_fonts_from_css(config, url, dest, lib_name, file_types)
62134
# only try to download the file if url doesn't start with | for security reasons
63135
if url.start_with?('|')
64136
return
@@ -83,48 +155,11 @@ def download_fonts_from_css(config, url, dest)
83155
# get the font-face rules
84156
css.each_rule_set do |rule_set|
85157
# check if the rule set has a url
86-
if rule_set['src'].include?('url(')
87-
# get the font file url
88-
font_url = rule_set['src'].split('url(').last.split(')').first
89-
90-
# remove quotes from the url
91-
if font_url.start_with?('"') || font_url.start_with?("'")
92-
font_url = font_url[1..-2]
93-
end
94-
95-
font_file_name = font_url.split('/').last.split('?').first
96-
97-
# verify if the file is a font file
98-
if font_file_name.end_with?('.woff', '.woff2', '.ttf', '.otf')
99-
# fix the font url if it is not an absolute url
100-
unless font_url.start_with?('https://')
101-
font_url = URI.join(url, font_url).to_s
102-
end
103-
104-
# download the file
105-
download_file(font_url, File.join(dest, 'fonts', font_file_name))
106-
107-
# change the font url to the local file, considering baseurl
108-
if config['baseurl']
109-
# add rest of the src attribute if it exists
110-
if rule_set['src'].split(' ').length > 1
111-
rule_set['src'] = "url(#{File.join(config['baseurl'], 'assets', 'libs', 'fonts', font_file_name)}) #{rule_set['src'].split(' ').last}"
112-
else
113-
rule_set['src'] = "url(#{File.join(config['baseurl'], 'assets', 'libs', 'fonts', font_file_name)})"
114-
end
115-
else
116-
# add rest of the src attribute if it exists
117-
if rule_set['src'].split(' ').length > 1
118-
rule_set['src'] = "url(#{File.join('/assets', 'libs', 'fonts', font_file_name)}) #{rule_set['src'].split(' ').last}"
119-
else
120-
rule_set['src'] = "url(#{File.join('/assets', 'libs', 'fonts', font_file_name)})"
121-
end
122-
end
123-
end
124-
end
158+
download_and_change_rule_set_url(rule_set, 'src', File.join(dest, 'fonts'), File.join(lib_name, 'fonts'), config, file_types)
125159
end
126160

127161
# save the modified css file
162+
puts "Saving modified css file to #{File.join(dest, file_name)}"
128163
File.write(File.join(dest, file_name), css.to_s)
129164
end
130165

@@ -164,13 +199,13 @@ def download_fonts_from_css(config, url, dest)
164199
# get the file name from the url
165200
file_name = url2.split('/').last.split('?').first
166201
# download the file and change the url to the local file
167-
dest = File.join(site.source, 'assets', 'libs', file_name)
202+
dest = File.join(site.source, 'assets', 'libs', key, file_name)
168203
download_file(url2, dest)
169204
# change the url to the local file, considering baseurl
170205
if site.config['baseurl']
171-
site.config['third_party_libraries'][key]['url'][type][type2] = File.join(site.config['baseurl'], 'assets', 'libs', file_name)
206+
site.config['third_party_libraries'][key]['url'][type][type2] = File.join(site.config['baseurl'], 'assets', 'libs', key, file_name)
172207
else
173-
site.config['third_party_libraries'][key]['url'][type][type2] = File.join('/assets', 'libs', file_name)
208+
site.config['third_party_libraries'][key]['url'][type][type2] = File.join('/assets', 'libs', key, file_name)
174209
end
175210
end
176211

@@ -181,29 +216,33 @@ def download_fonts_from_css(config, url, dest)
181216

182217
if file_name.end_with?('css')
183218
# if the file is a css file, download the css file, the fonts from it, and change information on the css file
184-
file_name = download_fonts_from_css(site.config, url, File.join(site.source, 'assets', 'libs'))
219+
file_name = download_fonts_from_css(site.config, url, File.join(site.source, 'assets', 'libs', key), key, font_file_types)
185220
# change the url to the local file, considering baseurl
186221
if site.config['baseurl']
187-
site.config['third_party_libraries'][key]['url'][type] = File.join(site.config['baseurl'], 'assets', 'libs', file_name)
222+
site.config['third_party_libraries'][key]['url'][type] = File.join(site.config['baseurl'], 'assets', 'libs', key, file_name)
188223
else
189-
site.config['third_party_libraries'][key]['url'][type] = File.join('/assets', 'libs', file_name)
224+
site.config['third_party_libraries'][key]['url'][type] = File.join('/assets', 'libs', key, file_name)
190225
end
191226
else
192227
# download the font files and change the url to the local file
193-
download_fonts(url, File.join(site.source, 'assets', 'libs', site.config['third_party_libraries'][key]['local']['fonts']))
228+
download_fonts(url, File.join(site.source, 'assets', 'libs', key, site.config['third_party_libraries'][key]['local'][type]), font_file_types)
194229
end
195230

231+
elsif type == 'images'
232+
# download the font files and change the url to the local file
233+
download_images(url, File.join(site.source, 'assets', 'libs', key, site.config['third_party_libraries'][key]['local'][type]), image_file_types)
234+
196235
else
197236
# get the file name from the url
198237
file_name = url.split('/').last.split('?').first
199238
# download the file and change the url to the local file
200-
dest = File.join(site.source, 'assets', 'libs', file_name)
239+
dest = File.join(site.source, 'assets', 'libs', key, file_name)
201240
download_file(url, dest)
202241
# change the url to the local file, considering baseurl
203242
if site.config['baseurl']
204-
site.config['third_party_libraries'][key]['url'][type] = File.join(site.config['baseurl'], 'assets', 'libs', file_name)
243+
site.config['third_party_libraries'][key]['url'][type] = File.join(site.config['baseurl'], 'assets', 'libs', key, file_name)
205244
else
206-
site.config['third_party_libraries'][key]['url'][type] = File.join('/assets', 'libs', file_name)
245+
site.config['third_party_libraries'][key]['url'][type] = File.join('/assets', 'libs', key, file_name)
207246
end
208247
end
209248
end

0 commit comments

Comments
 (0)