jekyll-pwa-plugin 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. checksums.yaml +7 -0
  2. data/lib/jekyll-pwa-plugin.rb +159 -0
  3. metadata +45 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 5d00791acb3f062e7183e0a5c84c173cb1e5dbf1
4
+ data.tar.gz: f37c8e7c126215fcc5e579b0160519140c0f6232
5
+ SHA512:
6
+ metadata.gz: eead320aafa5338e9d090b16e1ec2d636f9bff5fe0fa7918badf73bc4e24bf874b85a64f5c192f14a634b837e5c3ffbf5b6bed173440c940bf7c978cd9fa0c83
7
+ data.tar.gz: fc2a2c38e9e8b21c20f87b39612afc806ebed86245828bfed0c372a1b3808de1aebfda740eb9dfb9e5ecc24ac7c2d6ca070222703d08bbf11a609d61b882d28a
@@ -0,0 +1,159 @@
1
+ class SWHelper
2
+ def initialize(site, config)
3
+ @site = site
4
+ @config = config
5
+ @sw_filename = @config['sw_filename'] || 'service-worker'
6
+ end
7
+
8
+ def write_sw_register()
9
+ sw_register_filename = 'sw-register.js'
10
+ sw_register_file = File.new(File.join(@site.dest, sw_register_filename), 'w')
11
+ # add build version in url params
12
+ sw_register_file.puts(
13
+ <<-SCRIPT
14
+ navigator.serviceWorker
15
+ && navigator.serviceWorker.register('/#{@sw_filename}?v=#{@site.time.to_i.to_s}');
16
+ SCRIPT
17
+ )
18
+ sw_register_file.close
19
+ end
20
+
21
+ def generate_workbox_precache()
22
+ directory = @config['precache_glob_directory'] || '/'
23
+ directory = File.join(@site.dest, directory)
24
+ patterns = @config['precache_glob_patterns'] || ['**/*.{html,js,css,eot,svg,ttf,woff}']
25
+ ignores = @config['precache_glob_ignores'] || []
26
+ recent_posts_num = @config['precache_recent_posts_num']
27
+
28
+ # according to workbox precache {url: 'main.js', revision: 'xxxx'}
29
+ @precache_list = []
30
+
31
+ # find precache files with glob
32
+ precache_files = []
33
+ patterns.each do |pattern|
34
+ Dir.glob(File.join(directory, pattern)) do |filepath|
35
+ precache_files.push(filepath)
36
+ end
37
+ end
38
+ precache_files = precache_files.uniq
39
+
40
+ # precache recent n posts
41
+ posts_path_url_map = {}
42
+ if recent_posts_num
43
+ precache_files.concat(
44
+ @site.posts.docs
45
+ .reverse.take(recent_posts_num)
46
+ .map do |post|
47
+ posts_path_url_map[post.path] = post.url
48
+ post.path
49
+ end
50
+ )
51
+ end
52
+
53
+ # filter with ignores
54
+ ignores.each do |pattern|
55
+ Dir.glob(File.join(directory, pattern)) do |ignored_filepath|
56
+ precache_files.delete(ignored_filepath)
57
+ end
58
+ end
59
+
60
+ # generate md5 for each precache file
61
+ md5 = Digest::MD5.new
62
+ precache_files.each do |filepath|
63
+ md5.reset
64
+ md5 << File.read(filepath)
65
+ if posts_path_url_map[filepath]
66
+ url = posts_path_url_map[filepath]
67
+ else
68
+ url = filepath.sub(@site.dest, '')
69
+ end
70
+ @precache_list.push({
71
+ url: @site.baseurl + url,
72
+ revision: md5.hexdigest
73
+ })
74
+ end
75
+ end
76
+
77
+ def write_sw()
78
+ cache_name = @config['cache_name'] || 'workbox'
79
+ precache_channel_name = @config['precache_channel_name'] || 'sw-precache'
80
+ runtime_cache = @config['runtime_cache'] || []
81
+
82
+ # generate precache list
83
+ precache_list_str = @precache_list.map do |precache_item|
84
+ precache_item.to_json
85
+ end
86
+ .join(",")
87
+
88
+ # generate runtime cache route
89
+ runtime_cache_str = runtime_cache.map do |runtime_item|
90
+ <<-SCRIPT
91
+ workboxSW.router.registerRoute(#{runtime_item['route']},
92
+ workboxSW.strategies.#{runtime_item['strategy'] || 'networkFirst'}());
93
+ SCRIPT
94
+ end
95
+ .join("\n")
96
+
97
+ # write service-worker.js
98
+ sw_file = File.new(File.join(@site.dest, @sw_filename), 'w')
99
+ sw_file.puts(
100
+ <<-SCRIPT
101
+ importScripts('#{@site.baseurl}/js/broadcast-channel-polyfill.js');
102
+ importScripts('#{@site.baseurl}/js/workbox-sw.dev.v2.1.1.js');
103
+
104
+ const workboxSW = new WorkboxSW({
105
+ cacheId: '#{cache_name}',
106
+ ignoreUrlParametersMatching: [/^utm_/],
107
+ skipWaiting: true,
108
+ clientsClaim: true,
109
+ precacheChannelName: '#{precache_channel_name}'
110
+ });
111
+
112
+ workboxSW.precache([#{precache_list_str}]);
113
+ #{runtime_cache_str}
114
+ SCRIPT
115
+ )
116
+ sw_file.close
117
+ end
118
+
119
+ def self.insert_sw_register_into_body(page)
120
+ page.output = page.output.sub('</body>',
121
+ <<-SCRIPT
122
+ <script>
123
+ window.onload = function () {
124
+ var script = document.createElement('script');
125
+ var firstScript = document.getElementsByTagName('script')[0];
126
+ script.type = 'text/javascript';
127
+ script.async = true;
128
+ script.src = '#{page.site.baseurl}/sw-register.js?v=' + Date.now();
129
+ firstScript.parentNode.insertBefore(script, firstScript);
130
+ };
131
+ </script>
132
+ </body>
133
+ SCRIPT
134
+ )
135
+ end
136
+ end
137
+
138
+ module Jekyll
139
+
140
+ Hooks.register :pages, :post_render do |page|
141
+ # append <script> for sw-register.js in <body>
142
+ SWHelper.insert_sw_register_into_body(page)
143
+ end
144
+
145
+ Hooks.register :documents, :post_render do |document|
146
+ # append <script> for sw-register.js in <body>
147
+ SWHelper.insert_sw_register_into_body(document)
148
+ end
149
+
150
+ Hooks.register :site, :post_write do |site|
151
+ pwa_config = site.config['pwa'] || {}
152
+ sw_helper = SWHelper.new(site, pwa_config)
153
+
154
+ sw_helper.write_sw_register()
155
+ sw_helper.generate_workbox_precache()
156
+ sw_helper.write_sw()
157
+ end
158
+
159
+ end
metadata ADDED
@@ -0,0 +1,45 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jekyll-pwa-plugin
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Pan Yuqi
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-11-08 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: This plugin provides PWA support for Jekyll. Generate a service worker
14
+ and provides precache with Google Workbox.
15
+ email: pyqiverson@gmail.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - lib/jekyll-pwa-plugin.rb
21
+ homepage: http://rubygems.org/gems/jekyll-pwa-plugin
22
+ licenses:
23
+ - MIT
24
+ metadata: {}
25
+ post_install_message:
26
+ rdoc_options: []
27
+ require_paths:
28
+ - lib
29
+ required_ruby_version: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ required_rubygems_version: !ruby/object:Gem::Requirement
35
+ requirements:
36
+ - - ">="
37
+ - !ruby/object:Gem::Version
38
+ version: '0'
39
+ requirements: []
40
+ rubyforge_project:
41
+ rubygems_version: 2.6.12
42
+ signing_key:
43
+ specification_version: 4
44
+ summary: PWA support for Jekyll.
45
+ test_files: []