Skip to content

Commit a49d9d7

Browse files
committed
Put files in /addon and only reexport from /app
1 parent 4d729b6 commit a49d9d7

6 files changed

Lines changed: 187 additions & 184 deletions

File tree

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// When using `ember serve` when fastboot addon is installed the application
2+
// output will already be rendered to the DOM when the actual JavaScript
3+
// loads. Ember does not automatically clear its `rootElement` so this
4+
// leads to the "double" applications being visible at once (only the
5+
// "bottom" one is running via JS and is interactive).
6+
//
7+
// This removes any pre-rendered ember-view elements, so that the booting
8+
// application will replace the pre-rendered output
9+
10+
export default {
11+
name: "clear-double-boot",
12+
13+
initialize: function(instance) {
14+
if (typeof FastBoot === 'undefined') {
15+
var originalDidCreateRootView = instance.didCreateRootView;
16+
17+
instance.didCreateRootView = function() {
18+
let elements = document.querySelectorAll(instance.rootElement + ' .ember-view');
19+
for (let i = 0; i < elements.length; i++) {
20+
let element = elements[i];
21+
element.parentNode.removeChild(element);
22+
}
23+
24+
originalDidCreateRootView.apply(instance, arguments);
25+
};
26+
}
27+
}
28+
}

addon/locations/none.js

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import { computed, get } from '@ember/object';
2+
import { bool, readOnly } from '@ember/object/computed';
3+
import { inject as service } from '@ember/service';
4+
import { getOwner } from '@ember/application'
5+
import NoneLocation from '@ember/routing/none-location'
6+
7+
const TEMPORARY_REDIRECT_CODE = 307;
8+
9+
export default NoneLocation.extend({
10+
implementation: 'fastboot',
11+
fastboot: service(),
12+
13+
_config: computed(function () {
14+
return getOwner(this).resolveRegistration('config:environment');
15+
}),
16+
17+
_fastbootHeadersEnabled: bool('_config.fastboot.fastbootHeaders'),
18+
19+
_redirectCode: computed(function () {
20+
return get(this, '_config.fastboot.redirectCode') || TEMPORARY_REDIRECT_CODE;
21+
}),
22+
23+
_response: readOnly('fastboot.response'),
24+
_request: readOnly('fastboot.request'),
25+
26+
setURL(path) {
27+
if (get(this, 'fastboot.isFastBoot')) {
28+
let response = get(this, '_response');
29+
let currentPath = get(this, 'path');
30+
let isInitialPath = !currentPath || currentPath.length === 0;
31+
32+
if (!isInitialPath) {
33+
path = this.formatURL(path);
34+
let isTransitioning = currentPath !== path;
35+
36+
if (isTransitioning) {
37+
let host = get(this, '_request.host');
38+
let redirectURL = `//${host}${path}`;
39+
40+
response.statusCode = this.get('_redirectCode');
41+
response.headers.set('location', redirectURL);
42+
}
43+
}
44+
45+
// for testing and debugging
46+
if (get(this, '_fastbootHeadersEnabled')) {
47+
response.headers.set('x-fastboot-path', path);
48+
}
49+
}
50+
51+
this._super(...arguments);
52+
}
53+
});

addon/services/fastboot.js

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
/* global FastBoot */
2+
import { deprecate } from '@ember/application/deprecations';
3+
import { computed, get } from '@ember/object';
4+
import { deprecatingAlias, readOnly } from '@ember/object/computed';
5+
import { assert } from '@ember/debug';
6+
import EObject from '@ember/object';
7+
import Service from '@ember/service';
8+
9+
const RequestObject = EObject.extend({
10+
init() {
11+
this._super(...arguments);
12+
13+
let request = this.request;
14+
delete this.request;
15+
16+
this.method = request.method;
17+
this.body = request.body;
18+
this.cookies = request.cookies;
19+
this.headers = request.headers;
20+
this.queryParams = request.queryParams;
21+
this.path = request.path;
22+
this.protocol = request.protocol;
23+
this._host = function() {
24+
return request.host();
25+
};
26+
},
27+
28+
host: computed(function() {
29+
return this._host();
30+
})
31+
});
32+
33+
const Shoebox = EObject.extend({
34+
put(key, value) {
35+
assert('shoebox.put is only invoked from the FastBoot rendered application', this.get('fastboot.isFastBoot'));
36+
assert('the provided key is a string', typeof key === 'string');
37+
38+
let fastbootInfo = this.get('fastboot._fastbootInfo');
39+
if (!fastbootInfo.shoebox) { fastbootInfo.shoebox = {}; }
40+
41+
fastbootInfo.shoebox[key] = value;
42+
},
43+
44+
retrieve(key) {
45+
if (this.get('fastboot.isFastBoot')) {
46+
let shoebox = this.get('fastboot._fastbootInfo.shoebox');
47+
if (!shoebox) { return; }
48+
49+
return shoebox[key];
50+
}
51+
52+
let shoeboxItem = this.get(key);
53+
if (shoeboxItem) { return shoeboxItem; }
54+
55+
let el = document.querySelector(`#shoebox-${key}`);
56+
if (!el) { return; }
57+
let valueString = el.textContent;
58+
if (!valueString) { return; }
59+
60+
shoeboxItem = JSON.parse(valueString);
61+
this.set(key, shoeboxItem);
62+
63+
return shoeboxItem;
64+
}
65+
});
66+
67+
const FastBootService = Service.extend({
68+
cookies: deprecatingAlias('request.cookies', { id: 'fastboot.cookies-to-request', until: '0.9.9' }),
69+
headers: deprecatingAlias('request.headers', { id: 'fastboot.headers-to-request', until: '0.9.9' }),
70+
isFastBoot: typeof FastBoot !== 'undefined',
71+
72+
init() {
73+
this._super(...arguments);
74+
75+
let shoebox = Shoebox.create({ fastboot: this });
76+
this.set('shoebox', shoebox);
77+
},
78+
79+
host: computed(function() {
80+
deprecate(
81+
'Usage of fastboot service\'s `host` property is deprecated. Please use `request.host` instead.',
82+
false,
83+
{ id: 'fastboot.host-to-request', until: '0.9.9' }
84+
);
85+
86+
return this._fastbootInfo.request.host();
87+
}),
88+
89+
response: readOnly('_fastbootInfo.response'),
90+
metadata: readOnly('_fastbootInfo.metadata'),
91+
92+
request: computed(function() {
93+
if (!this.isFastBoot) return null;
94+
return RequestObject.create({ request: get(this, '_fastbootInfo.request') });
95+
}),
96+
97+
deferRendering(promise) {
98+
assert('deferRendering requires a promise or thennable object', typeof promise.then === 'function');
99+
this._fastbootInfo.deferRendering(promise);
100+
}
101+
});
102+
103+
export default FastBootService;
Lines changed: 1 addition & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1 @@
1-
// When using `ember serve` when fastboot addon is installed the application
2-
// output will already be rendered to the DOM when the actual JavaScript
3-
// loads. Ember does not automatically clear its `rootElement` so this
4-
// leads to the "double" applications being visible at once (only the
5-
// "bottom" one is running via JS and is interactive).
6-
//
7-
// This removes any pre-rendered ember-view elements, so that the booting
8-
// application will replace the pre-rendered output
9-
10-
export default {
11-
name: "clear-double-boot",
12-
13-
initialize: function(instance) {
14-
if (typeof FastBoot === 'undefined') {
15-
var originalDidCreateRootView = instance.didCreateRootView;
16-
17-
instance.didCreateRootView = function() {
18-
let elements = document.querySelectorAll(instance.rootElement + ' .ember-view');
19-
for (let i = 0; i < elements.length; i++) {
20-
let element = elements[i];
21-
element.parentNode.removeChild(element);
22-
}
23-
24-
originalDidCreateRootView.apply(instance, arguments);
25-
};
26-
}
27-
}
28-
}
1+
export { default } from 'ember-cli-fastboot/instance-initializers/clear-double-boot';

app/locations/none.js

Lines changed: 1 addition & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1 @@
1-
import { computed, get } from '@ember/object';
2-
import { bool, readOnly } from '@ember/object/computed';
3-
import { inject as service } from '@ember/service';
4-
import { getOwner } from '@ember/application'
5-
import NoneLocation from '@ember/routing/none-location'
6-
7-
const TEMPORARY_REDIRECT_CODE = 307;
8-
9-
export default NoneLocation.extend({
10-
implementation: 'fastboot',
11-
fastboot: service(),
12-
13-
_config: computed(function () {
14-
return getOwner(this).resolveRegistration('config:environment');
15-
}),
16-
17-
_fastbootHeadersEnabled: bool('_config.fastboot.fastbootHeaders'),
18-
19-
_redirectCode: computed(function () {
20-
return get(this, '_config.fastboot.redirectCode') || TEMPORARY_REDIRECT_CODE;
21-
}),
22-
23-
_response: readOnly('fastboot.response'),
24-
_request: readOnly('fastboot.request'),
25-
26-
setURL(path) {
27-
if (get(this, 'fastboot.isFastBoot')) {
28-
let response = get(this, '_response');
29-
let currentPath = get(this, 'path');
30-
let isInitialPath = !currentPath || currentPath.length === 0;
31-
32-
if (!isInitialPath) {
33-
path = this.formatURL(path);
34-
let isTransitioning = currentPath !== path;
35-
36-
if (isTransitioning) {
37-
let host = get(this, '_request.host');
38-
let redirectURL = `//${host}${path}`;
39-
40-
response.statusCode = this.get('_redirectCode');
41-
response.headers.set('location', redirectURL);
42-
}
43-
}
44-
45-
// for testing and debugging
46-
if(get(this, '_fastbootHeadersEnabled')) {
47-
response.headers.set('x-fastboot-path', path);
48-
}
49-
}
50-
51-
this._super(...arguments);
52-
}
53-
});
1+
export { default } from 'ember-cli-fastboot/locations/none';

app/services/fastboot.js

Lines changed: 1 addition & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -1,103 +1 @@
1-
/* global FastBoot */
2-
import { deprecate } from '@ember/application/deprecations';
3-
import { computed, get } from '@ember/object';
4-
import { deprecatingAlias, readOnly } from '@ember/object/computed';
5-
import { assert } from '@ember/debug';
6-
import EObject from '@ember/object';
7-
import Service from '@ember/service';
8-
9-
const RequestObject = EObject.extend({
10-
init() {
11-
this._super(...arguments);
12-
13-
let request = this.request;
14-
delete this.request;
15-
16-
this.method = request.method;
17-
this.body = request.body;
18-
this.cookies = request.cookies;
19-
this.headers = request.headers;
20-
this.queryParams = request.queryParams;
21-
this.path = request.path;
22-
this.protocol = request.protocol;
23-
this._host = function() {
24-
return request.host();
25-
};
26-
},
27-
28-
host: computed(function() {
29-
return this._host();
30-
})
31-
});
32-
33-
const Shoebox = EObject.extend({
34-
put(key, value) {
35-
assert('shoebox.put is only invoked from the FastBoot rendered application', this.get('fastboot.isFastBoot'));
36-
assert('the provided key is a string', typeof key === 'string');
37-
38-
let fastbootInfo = this.get('fastboot._fastbootInfo');
39-
if (!fastbootInfo.shoebox) { fastbootInfo.shoebox = {}; }
40-
41-
fastbootInfo.shoebox[key] = value;
42-
},
43-
44-
retrieve(key) {
45-
if (this.get('fastboot.isFastBoot')) {
46-
let shoebox = this.get('fastboot._fastbootInfo.shoebox');
47-
if (!shoebox) { return; }
48-
49-
return shoebox[key];
50-
}
51-
52-
let shoeboxItem = this.get(key);
53-
if (shoeboxItem) { return shoeboxItem; }
54-
55-
let el = document.querySelector(`#shoebox-${key}`);
56-
if (!el) { return; }
57-
let valueString = el.textContent;
58-
if (!valueString) { return; }
59-
60-
shoeboxItem = JSON.parse(valueString);
61-
this.set(key, shoeboxItem);
62-
63-
return shoeboxItem;
64-
}
65-
});
66-
67-
const FastBootService = Service.extend({
68-
cookies: deprecatingAlias('request.cookies', { id: 'fastboot.cookies-to-request', until: '0.9.9' }),
69-
headers: deprecatingAlias('request.headers', { id: 'fastboot.headers-to-request', until: '0.9.9' }),
70-
isFastBoot: typeof FastBoot !== 'undefined',
71-
72-
init() {
73-
this._super(...arguments);
74-
75-
let shoebox = Shoebox.create({ fastboot: this });
76-
this.set('shoebox', shoebox);
77-
},
78-
79-
host: computed(function() {
80-
deprecate(
81-
'Usage of fastboot service\'s `host` property is deprecated. Please use `request.host` instead.',
82-
false,
83-
{ id: 'fastboot.host-to-request', until: '0.9.9' }
84-
);
85-
86-
return this._fastbootInfo.request.host();
87-
}),
88-
89-
response: readOnly('_fastbootInfo.response'),
90-
metadata: readOnly('_fastbootInfo.metadata'),
91-
92-
request: computed(function() {
93-
if (!this.isFastBoot) return null;
94-
return RequestObject.create({ request: get(this, '_fastbootInfo.request') });
95-
}),
96-
97-
deferRendering(promise) {
98-
assert('deferRendering requires a promise or thennable object', typeof promise.then === 'function');
99-
this._fastbootInfo.deferRendering(promise);
100-
}
101-
});
102-
103-
export default FastBootService;
1+
export { default } from 'ember-cli-fastboot/services/fastboot';

0 commit comments

Comments
 (0)