-
Notifications
You must be signed in to change notification settings - Fork 71
/
result.js
125 lines (102 loc) · 3.03 KB
/
result.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
'use strict';
const SimpleDOM = require('simple-dom');
const HTMLSerializer = new SimpleDOM.HTMLSerializer(SimpleDOM.voidMap);
/**
* Represents the rendered result of visiting an Ember app at a particular URL.
* A `Result` object is returned from calling {@link FastBoot}'s `visit()`
* method.
*/
class Result {
constructor(options) {
this.instanceBooted = false;
this.instanceDestroyed = false;
this._doc = options.doc;
this._html = options.html;
this._fastbootInfo = options.fastbootInfo;
}
/**
* Returns the HTML representation of the rendered route, inserted
* into the application's `index.html`.
*
* @returns {Promise<String>} the application's DOM serialized to HTML
*/
html() {
let response = this._fastbootInfo.response;
let statusCode = response && this._fastbootInfo.response.statusCode;
if (statusCode === 204) {
this._html = '';
this._head = '';
this._body = '';
} else if (statusCode >= 300 && statusCode <= 399) {
let location = response.headers.get('location');
this._html = '<body><!-- EMBER_CLI_FASTBOOT_BODY --></body>';
this._head = '';
this._body = '';
if (location) {
this._body = `<h1>Redirecting to <a href="${location}">${location}</a></h1>`;
}
}
return Promise.resolve(insertIntoIndexHTML(this._html, this._head, this._body));
}
/**
* Returns the serialized representation of DOM HEAD and DOM BODY
*
* @returns {Object} serialized version of DOM
*/
domContents() {
return {
head: this._head,
body: this._body
};
}
/**
* @private
*
* Called once the Result has finished being constructed and the application
* instance has finished rendering. Once `finalize()` is called, state is
* gathered from the completed application instance and statically copied
* to this Result instance.
*/
_finalize() {
if (this.finalized) {
throw new Error("Results cannot be finalized more than once");
}
// Grab some metadata from the sandboxed application instance
// and copy it to this Result object.
let instance = this.instance;
if (instance) {
this._finalizeMetadata(instance);
}
this._finalizeHTML();
this.finalized = true;
return this;
}
_finalizeMetadata(instance) {
if (this.instanceBooted) {
this.url = instance.getURL();
}
let response = this._fastbootInfo.response;
if (response) {
this.headers = response.headers;
this.statusCode = response.statusCode;
}
}
_finalizeHTML() {
let head = this._doc.head;
let body = this._doc.body;
if (head) {
head = HTMLSerializer.serializeChildren(head);
}
body = HTMLSerializer.serializeChildren(body);
this._head = head;
this._body = body;
}
}
function insertIntoIndexHTML(html, head, body) {
html = html.replace("<!-- EMBER_CLI_FASTBOOT_BODY -->", body);
if (head) {
html = html.replace("<!-- EMBER_CLI_FASTBOOT_HEAD -->", head);
}
return html;
}
module.exports = Result;