1 | 'use strict';
|
2 |
|
3 | const ServiceWorkerBuilder = require('./lib/service-worker-builder');
|
4 | const InlineRegistration = require('./lib/inline-registration');
|
5 | const mergeTrees = require('broccoli-merge-trees');
|
6 | const writeFile = require('broccoli-file-creator');
|
7 | const hashForDep = require('hash-for-dep');
|
8 | const addonUtils = require('./lib/addon-utils');
|
9 | const IndexFile = require('./lib/index-file');
|
10 |
|
11 | module.exports = {
|
12 | name: 'ember-service-worker',
|
13 |
|
14 | included(app) {
|
15 | if (this._super.included) {
|
16 | this._super.included.apply(this, arguments);
|
17 | }
|
18 |
|
19 |
|
20 | this.app = app;
|
21 | this.app.options = this.app.options || {};
|
22 | let options = this.app.options['ember-service-worker'] = this.app.options['ember-service-worker'] || {}
|
23 | options.serviceWorkerFilename = options.serviceWorkerFilename || 'sw.js';
|
24 |
|
25 | this.app.options.fingerprint = this.app.options.fingerprint || {};
|
26 | this.app.options.fingerprint.exclude = this.app.options.fingerprint.exclude || [];
|
27 | this.app.options.fingerprint.exclude.push(options.serviceWorkerFilename);
|
28 |
|
29 | options.registrationStrategy = options.registrationStrategy || 'default';
|
30 |
|
31 | if (options.enabled === undefined) {
|
32 | options.enabled = this.app.env !== 'test';
|
33 | }
|
34 |
|
35 | if (process.env.SW_DISABLED) {
|
36 | options.enabled = false;
|
37 | }
|
38 |
|
39 | if (options.registrationStrategy === 'after-ember' && options.enabled !== false) {
|
40 | app.import('vendor/ember-service-worker/load-registration-script.js');
|
41 | }
|
42 | },
|
43 |
|
44 | treeForVendor() {
|
45 | return writeFile('ember-service-worker/load-registration-script.js', `
|
46 | (function() {
|
47 | if (typeof FastBoot === 'undefined') {
|
48 | var script = document.createElement('script')
|
49 | script.src = '${this._getRootURL()}sw-registration.js';
|
50 | document.body.appendChild(script);
|
51 | }
|
52 | })();
|
53 | `);
|
54 | },
|
55 |
|
56 | postprocessTree(type, appTree) {
|
57 | let options = this._getOptions();
|
58 |
|
59 | if (type !== 'all' || options.enabled === false) {
|
60 | return appTree;
|
61 | }
|
62 |
|
63 | let plugins = this._findPluginsFor(this.project);
|
64 |
|
65 |
|
66 |
|
67 | plugins = [this].concat(plugins, this.project);
|
68 |
|
69 | let serviceWorkerBuilder = new ServiceWorkerBuilder({
|
70 | app: this,
|
71 | appTree,
|
72 | minifyJS: this.app.options.minifyJS,
|
73 | fingerprint: this.app.options.fingerprint.enabled,
|
74 | plugins,
|
75 | rootURL: this._getRootURL(),
|
76 | sourcemaps: this.app.options.sourcemaps,
|
77 | registrationDistPath: options.registrationDistPath,
|
78 | serviceWorkerFilename: options.serviceWorkerFilename
|
79 | });
|
80 |
|
81 | let serviceWorkerTree = serviceWorkerBuilder.build('service-worker');
|
82 | let serviceWorkerRegistrationTree =
|
83 | serviceWorkerBuilder.build('service-worker-registration');
|
84 |
|
85 | if (options.registrationStrategy === 'inline') {
|
86 | serviceWorkerRegistrationTree = new InlineRegistration([appTree, serviceWorkerRegistrationTree], options);
|
87 | }
|
88 |
|
89 | return mergeTrees([
|
90 | appTree,
|
91 | serviceWorkerTree,
|
92 | serviceWorkerRegistrationTree
|
93 | ], { overwrite: true });
|
94 | },
|
95 |
|
96 | contentFor(type, config) {
|
97 | let options = this._getOptions();
|
98 |
|
99 | if (options.enabled === false) {
|
100 | return;
|
101 | }
|
102 |
|
103 | let registrationDistPath = options.registrationDistPath;
|
104 | let srcPath = 'sw-registration.js';
|
105 |
|
106 | if (registrationDistPath) {
|
107 | srcPath = `${registrationDistPath}/${srcPath}`;
|
108 | }
|
109 |
|
110 | if (type === 'body-footer') {
|
111 | if (options.registrationStrategy === 'default') {
|
112 | return `<script src="${this._getRootURL()}${srcPath}"></script>`;
|
113 | }
|
114 |
|
115 | if (options.registrationStrategy === 'inline') {
|
116 | return `<!-- ESW_INLINE_PLACEHOLDER -->`;
|
117 | }
|
118 | }
|
119 |
|
120 | if (type === 'head-footer' && options.registrationStrategy === 'async') {
|
121 | return `<script async src="${this._getRootURL()}${srcPath}"></script>`;
|
122 | }
|
123 | },
|
124 |
|
125 | treeForServiceWorker(swTree, appTree) {
|
126 | var options = this._getOptions();
|
127 | options.projectVersion = this.project.pkg.version;
|
128 |
|
129 | try {
|
130 | options.projectRevision = hashForDep(this.project.root);
|
131 | } catch (e) {
|
132 | options.projectRevision = '0';
|
133 | }
|
134 |
|
135 | var indexFile = new IndexFile([appTree], options);
|
136 |
|
137 | return mergeTrees([swTree, indexFile]);
|
138 | },
|
139 |
|
140 | _getRootURL() {
|
141 | if (this._projectRootURL) {
|
142 | return this._projectRootURL;
|
143 | }
|
144 |
|
145 | let options = this._getOptions();
|
146 | let config = this._getConfig();
|
147 | let rootURL = options.rootUrl || config.rootURL || config.baseURL || '/';
|
148 |
|
149 | return this._projectRootURL = rootURL;
|
150 | },
|
151 |
|
152 | _getOptions() {
|
153 | return this.app.options['ember-service-worker'];
|
154 | },
|
155 |
|
156 | _getConfig() {
|
157 | return this.project.config(this.app.env);
|
158 | },
|
159 |
|
160 | _findPluginsFor(project) {
|
161 | let addons = project.addons || [];
|
162 | return addonUtils.filterByKeyword(addons, 'ember-service-worker-plugin');
|
163 | }
|
164 | };
|