bigpipe-util 0.2.10 → 0.2.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -1
- package/README.md +3 -3
- package/bigpipe.svg +3 -3
- package/package.json +1 -1
- package/src/BigPipe.js +170 -0
- package/src/Pagelet.js +131 -0
- package/src/Primer.js +11 -2
- package/src/ServerJS.js +1 -1
- package/src/async/AsyncDOM.js +2 -1
- package/src/async/AsyncRequest.js +8 -4
- package/src/core/replaceTransportMarkers.js +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,10 +4,19 @@ All notable changes to `bigpipe-util` will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
Updates should follow the [Keep a CHANGELOG](http://keepachangelog.com/) principles.
|
|
6
6
|
|
|
7
|
+
## v0.2.12 - 2026-01-12
|
|
8
|
+
### Added
|
|
9
|
+
- Added `Pagelet.js`, `BigPipe.js`
|
|
10
|
+
|
|
11
|
+
## v0.2.11 - 2025-12-27
|
|
12
|
+
### Added
|
|
13
|
+
- Added `incrementRequests` method to AsyncRequest.js
|
|
14
|
+
- Added submitter to form data in onSubmit handler
|
|
15
|
+
|
|
7
16
|
## v0.2.10 - 2025-05-15
|
|
8
|
-
- Added `onAfterLoad.js`, `waitForLoad.js`
|
|
9
17
|
|
|
10
18
|
### Added
|
|
19
|
+
- Added `onAfterLoad.js`, `waitForLoad.js`
|
|
11
20
|
- Added `timeout` to open dialog with a delay in method `showFromModel`
|
|
12
21
|
|
|
13
22
|
## v0.2.8 - 2025-05-02
|
package/README.md
CHANGED
|
@@ -42,11 +42,11 @@ window.require = (modulePath) => {
|
|
|
42
42
|
### 4. Add these lines to the page footer:
|
|
43
43
|
```html
|
|
44
44
|
<script>
|
|
45
|
-
(new (require("bigpipe-util/ServerJS"))).handle(<?=json_encode(\dobron\BigPipe\BigPipe::jsmods())?>);
|
|
45
|
+
(new (require("bigpipe-util/src/ServerJS"))).handle(<?=json_encode(\dobron\BigPipe\BigPipe::jsmods())?>);
|
|
46
46
|
</script>
|
|
47
47
|
```
|
|
48
48
|
|
|
49
|
-
## Request API
|
|
49
|
+
## 🛜 Request API
|
|
50
50
|
|
|
51
51
|
```javascript
|
|
52
52
|
import AsyncRequest from 'bigpipe-util/src/AsyncRequest';
|
|
@@ -119,6 +119,6 @@ We welcome contributions! If you'd like to help improve this project, feel free
|
|
|
119
119
|
|
|
120
120
|
## 📜 License
|
|
121
121
|
|
|
122
|
-
The MIT License (MIT). Please see [License File](LICENSE
|
|
122
|
+
The MIT License (MIT). Please see [License File](LICENSE) for more information.
|
|
123
123
|
|
|
124
124
|
[blog]: https://www.facebook.com/notes/facebook-engineering/bigpipe-pipelining-web-pages-for-high-performance/389414033919
|
package/bigpipe.svg
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
<svg width="254.23999568394254" height="64.8" viewBox="0 0 254.23999568394254 64.8" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
-
<g transform="matrix(3.0856473041983374,0,0,3.0856473041983374,-6.171373325690784,-6.1698442238608315)" fill="#
|
|
2
|
+
<g transform="matrix(3.0856473041983374,0,0,3.0856473041983374,-6.171373325690784,-6.1698442238608315)" fill="#478be6">
|
|
3
3
|
<g xmlns="http://www.w3.org/2000/svg">
|
|
4
4
|
<path d="M2.2427,8.9287a.5.5,0,0,1,0-.8574l10-6a.4971.4971,0,0,1,.5146,0l10,6a.5.5,0,0,1,0,.8574l-10,6a.5.5,0,0,1-.5146,0Zm20,3.1426L12.5,17.917,2.7573,12.0713a.5.5,0,0,0-.5146.8574l10,6a.5.5,0,0,0,.5146,0l10-6a.5.5,0,0,0-.5146-.8574Zm0,4L12.5,21.917,2.7573,16.0713a.5.5,0,0,0-.5146.8574l10,6a.5.5,0,0,0,.5146,0l10-6a.5.5,0,0,0-.5146-.8574Z"></path>
|
|
5
5
|
</g>
|
|
6
6
|
</g>
|
|
7
|
-
<g transform="matrix(2.500000066227385,0,0,2.500000066227385,81.99999920527138,0.49999675485814166)" fill="#
|
|
7
|
+
<g transform="matrix(2.500000066227385,0,0,2.500000066227385,81.99999920527138,0.49999675485814166)" fill="#478be6">
|
|
8
8
|
<path d="M8.92 12.24 c1.48 0.4 2.88 1.72 2.88 3.66 c0 2.54 -1.6 4.1 -5.08 4.1 l-5.52 0 l0 -14 l5.22 0 c2.9 0 4.36 1.64 4.36 3.52 c0 1.48 -0.96 2.32 -1.86 2.72 z M6.14 8.56 l-2.02 0 l0 2.82 l2.02 0 c1.24 0 1.74 -0.58 1.74 -1.42 c0 -0.9 -0.58 -1.4 -1.74 -1.4 z M6.56 17.44 c1.6 0 2.32 -0.66 2.32 -1.9 c0 -1.06 -0.72 -1.8 -2.44 -1.8 l-2.32 0 l0 3.7 l2.44 0 z M16.62 6 l0 14 l-2.92 0 l0 -14 l2.92 0 z M32.2 12.559999999999999 c0.62 4.7 -2.44 7.64 -6.22 7.64 c-3.98 0 -7.26 -2.94 -7.26 -7.2 s3.36 -7.2 7.26 -7.2 c1.86 0 3.5 0.6 4.7 1.66 l-1.76 1.98 c-0.74 -0.52 -1.74 -0.9 -2.76 -0.9 c-2.54 0 -4.4 1.86 -4.4 4.46 s1.8 4.46 4.22 4.46 c1.84 0 3.12 -0.66 3.52 -2.42 l-3.3 0 l0 -2.48 l6 0 z"></path>
|
|
9
9
|
</g>
|
|
10
|
-
<g transform="matrix(2.5714285714285716,0,0,2.5714285714285716,166.91428559167045,-0.4285714285714306)" fill="#
|
|
10
|
+
<g transform="matrix(2.5714285714285716,0,0,2.5714285714285716,166.91428559167045,-0.4285714285714306)" fill="#478be6">
|
|
11
11
|
<path d="M5.46 6 c3.14 0 4.8 1.94 4.8 4.3 c0 2.42 -1.66 4.34 -4.8 4.34 l-3.68 0 l0 5.36 l-0.58 0 l0 -14 l4.26 0 z M5.54 14.04 c2.52 0 4.14 -1.46 4.14 -3.74 c0 -2.32 -1.62 -3.72 -4.14 -3.72 l-3.76 0 l0 7.46 l3.76 0 z M12.74 6 l0 14 l-0.58 0 l0 -14 l0.58 0 z M19.400000000000002 6 c3.14 0 4.8 1.94 4.8 4.3 c0 2.42 -1.66 4.34 -4.8 4.34 l-3.68 0 l0 5.36 l-0.58 0 l0 -14 l4.26 0 z M19.48 14.04 c2.52 0 4.14 -1.46 4.14 -3.74 c0 -2.32 -1.62 -3.72 -4.14 -3.72 l-3.76 0 l0 7.46 l3.76 0 z M26.680000000000003 19.42 l7.28 0 l0 0.58 l-7.68 0 l-0.18 0 l0 -14 l0.58 0 l7.1 0 l0 0.58 l-7.1 0 l0 6.1 l5.66 0 l0 0.58 l-5.66 0 l0 6.16 z"></path>
|
|
12
12
|
</g>
|
|
13
13
|
</svg>
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bigpipe-util",
|
|
3
3
|
"description": "This library currently implements small part of Facebook BigPipe so far, but the advantage is to efficiently insert/replace content and work with the DOM. It is also possible to easily call JavaScript modules from PHP.",
|
|
4
|
-
"version": "0.2.
|
|
4
|
+
"version": "0.2.12",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"bigpipe",
|
|
7
7
|
"xhr",
|
package/src/BigPipe.js
ADDED
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
export const BIGPIPE_PHASE = Object.freeze({
|
|
2
|
+
WAITING: 0,
|
|
3
|
+
READY_FOR_JS: 1,
|
|
4
|
+
LOADING_JS: 2,
|
|
5
|
+
COMPLETE: 3
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
export const RESOURCE_PHASE = Object.freeze({
|
|
9
|
+
PENDING: 0,
|
|
10
|
+
LOADING: 1,
|
|
11
|
+
LOADED: 2
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
let instance = null;
|
|
15
|
+
|
|
16
|
+
export default class BigPipe {
|
|
17
|
+
pageletResources = new Map();
|
|
18
|
+
pagelets = new Map();
|
|
19
|
+
phase = BIGPIPE_PHASE.WAITING;
|
|
20
|
+
|
|
21
|
+
constructor() {
|
|
22
|
+
if (instance) {
|
|
23
|
+
return instance;
|
|
24
|
+
}
|
|
25
|
+
instance = this;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
onPageletArrive(pageletData) {
|
|
29
|
+
const Pagelet = require("./Pagelet").default;
|
|
30
|
+
|
|
31
|
+
if (pageletData.is_last) {
|
|
32
|
+
this.setPhase(BIGPIPE_PHASE.READY_FOR_JS);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const pagelet = new Pagelet(pageletData);
|
|
36
|
+
this.registerPagelet(pagelet);
|
|
37
|
+
pagelet.start();
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
fileLoaded(filename) {
|
|
41
|
+
const resource = this.pageletResources.get(filename);
|
|
42
|
+
if (resource) {
|
|
43
|
+
resource.onComplete();
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
registerPagelet(pagelet) {
|
|
48
|
+
this.pagelets.set(pagelet.id, pagelet);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
areAllPageletsReady() {
|
|
52
|
+
if (this.pagelets.size === 0) {
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return Array.from(this.pagelets.values()).every(
|
|
57
|
+
pagelet => pagelet.phase >= 3
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
pageletDisplayed() {
|
|
62
|
+
if (!this.areAllPageletsReady()) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (this.phase === BIGPIPE_PHASE.READY_FOR_JS) {
|
|
67
|
+
this.loadJSResources();
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
setPhase(newPhase) {
|
|
72
|
+
this.phase = newPhase;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
loadJSResources() {
|
|
76
|
+
this.setPhase(BIGPIPE_PHASE.LOADING_JS);
|
|
77
|
+
|
|
78
|
+
const jsResources = this.getResourcesByType('js');
|
|
79
|
+
|
|
80
|
+
jsResources.forEach(resource => {
|
|
81
|
+
resource.startLoading();
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
this.notifyPageletsWithoutResources();
|
|
85
|
+
|
|
86
|
+
if (jsResources.length === 0) {
|
|
87
|
+
this.notifyAllPagelets();
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
getResourcesByType(type) {
|
|
92
|
+
return Array.from(this.pageletResources.values())
|
|
93
|
+
.filter(resource => resource.type === type);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
notifyPageletsWithoutResources() {
|
|
97
|
+
this.pagelets.forEach(pagelet => {
|
|
98
|
+
if (pagelet.jsResources.size === 0) {
|
|
99
|
+
pagelet.onJsFinished();
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
notifyAllPagelets() {
|
|
105
|
+
this.pagelets.forEach(pagelet => {
|
|
106
|
+
pagelet.onJsFinished();
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
extractFilename(filePath) {
|
|
111
|
+
const match = /([^/]+)$/.exec(filePath);
|
|
112
|
+
return match ? match[1] : filePath;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
pageletResourceFactory(file, type) {
|
|
116
|
+
const name = this.extractFilename(file);
|
|
117
|
+
|
|
118
|
+
let resource = this.pageletResources.get(name);
|
|
119
|
+
if (!resource) {
|
|
120
|
+
resource = this.createResource(file, name, type);
|
|
121
|
+
this.pageletResources.set(name, resource);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return resource;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
createResource(file, name, type) {
|
|
128
|
+
const self = this;
|
|
129
|
+
|
|
130
|
+
return {
|
|
131
|
+
file,
|
|
132
|
+
name,
|
|
133
|
+
type,
|
|
134
|
+
phase: RESOURCE_PHASE.PENDING,
|
|
135
|
+
callbacks: [],
|
|
136
|
+
|
|
137
|
+
startLoading() {
|
|
138
|
+
if (this.phase !== RESOURCE_PHASE.PENDING) {
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
this.phase = RESOURCE_PHASE.LOADING;
|
|
143
|
+
|
|
144
|
+
if (type === 'css') {
|
|
145
|
+
const link = document.createElement('link');
|
|
146
|
+
link.rel = 'stylesheet';
|
|
147
|
+
link.href = file;
|
|
148
|
+
link.onload = () => self.fileLoaded(name);
|
|
149
|
+
link.onerror = () => self.fileLoaded(name);
|
|
150
|
+
document.head.appendChild(link);
|
|
151
|
+
} else if (type === 'js') {
|
|
152
|
+
const script = document.createElement('script');
|
|
153
|
+
script.src = file;
|
|
154
|
+
script.onload = () => self.fileLoaded(name);
|
|
155
|
+
script.onerror = () => self.fileLoaded(name);
|
|
156
|
+
document.body.appendChild(script);
|
|
157
|
+
}
|
|
158
|
+
},
|
|
159
|
+
|
|
160
|
+
onComplete() {
|
|
161
|
+
this.phase = RESOURCE_PHASE.LOADED;
|
|
162
|
+
this.callbacks.forEach(callback => callback(this));
|
|
163
|
+
},
|
|
164
|
+
|
|
165
|
+
attachToPagelet(callback) {
|
|
166
|
+
this.callbacks.push(callback);
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
}
|
package/src/Pagelet.js
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import BigPipe, { RESOURCE_PHASE } from "./BigPipe";
|
|
2
|
+
import ServerJS from "./ServerJS";
|
|
3
|
+
import AsyncDOM from "./async/AsyncDOM";
|
|
4
|
+
|
|
5
|
+
const serverJS = new ServerJS();
|
|
6
|
+
const asyncDOM = new AsyncDOM();
|
|
7
|
+
const bigPipe = new BigPipe();
|
|
8
|
+
|
|
9
|
+
export const PAGELET_PHASE = Object.freeze({
|
|
10
|
+
ARRIVE_START: 0,
|
|
11
|
+
LOADING_CSS: 1,
|
|
12
|
+
DISPLAY_START: 2,
|
|
13
|
+
DISPLAY_END: 3,
|
|
14
|
+
ARRIVE_END: 4
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
function areAllResourcesLoaded(resources) {
|
|
18
|
+
if (resources.size === 0) {
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
21
|
+
return Array.from(resources.values()).every(
|
|
22
|
+
resource => resource.phase === RESOURCE_PHASE.LOADED
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export default class Pagelet {
|
|
27
|
+
cssResources = new Map();
|
|
28
|
+
|
|
29
|
+
jsResources = new Map();
|
|
30
|
+
|
|
31
|
+
id = "";
|
|
32
|
+
|
|
33
|
+
phase = PAGELET_PHASE.ARRIVE_START;
|
|
34
|
+
|
|
35
|
+
constructor(pageletData) {
|
|
36
|
+
this.bigPipe = bigPipe;
|
|
37
|
+
this.id = pageletData.id;
|
|
38
|
+
this.phase = PAGELET_PHASE.ARRIVE_START;
|
|
39
|
+
this.domops = pageletData.domops;
|
|
40
|
+
this.jsmods = pageletData.jsmods;
|
|
41
|
+
this.css = pageletData.css;
|
|
42
|
+
this.js = pageletData.js;
|
|
43
|
+
this.cssResources = new Map();
|
|
44
|
+
this.jsResources = new Map();
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
isComplete() {
|
|
48
|
+
return this.phase === PAGELET_PHASE.ARRIVE_END;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
setPhase(phase) {
|
|
52
|
+
this.phase = phase;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
start() {
|
|
56
|
+
if (this.phase !== PAGELET_PHASE.ARRIVE_START) {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (this.css.length > 0) {
|
|
61
|
+
this.css.forEach((cssFile) => {
|
|
62
|
+
const cssResource = this.bigPipe.pageletResourceFactory(cssFile, 'css');
|
|
63
|
+
this.attachCssResource(cssResource);
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (this.js.length > 0) {
|
|
68
|
+
this.js.forEach((jsFile) => {
|
|
69
|
+
const jsResource = this.bigPipe.pageletResourceFactory(jsFile, 'js');
|
|
70
|
+
this.attachJsResource(jsResource);
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (this.cssResources.size > 0) {
|
|
75
|
+
this.setPhase(PAGELET_PHASE.LOADING_CSS);
|
|
76
|
+
this.cssResources.forEach((resource) => {
|
|
77
|
+
resource.startLoading();
|
|
78
|
+
});
|
|
79
|
+
} else {
|
|
80
|
+
this.setContent();
|
|
81
|
+
this.onJsFinished();
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
attachCssResource(resource) {
|
|
86
|
+
resource.attachToPagelet(() => this.onCssFinished(resource));
|
|
87
|
+
this.cssResources.set(resource.file, resource);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
attachJsResource(resource) {
|
|
91
|
+
resource.attachToPagelet(() => this.onJsFinished());
|
|
92
|
+
this.jsResources.set(resource.file, resource);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
onJsFinished() {
|
|
96
|
+
if (this.isComplete()) {
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (!areAllResourcesLoaded(this.jsResources)) {
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
this.processJsMods();
|
|
105
|
+
|
|
106
|
+
this.setPhase(PAGELET_PHASE.ARRIVE_END);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
processJsMods() {
|
|
110
|
+
serverJS.handle(this.jsmods);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
onCssFinished() {
|
|
114
|
+
if (!areAllResourcesLoaded(this.cssResources)) {
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
this.setContent();
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
setContent() {
|
|
122
|
+
this.setPhase(PAGELET_PHASE.DISPLAY_START);
|
|
123
|
+
|
|
124
|
+
if (this.domops) {
|
|
125
|
+
asyncDOM.invoke(this.domops);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
this.setPhase(PAGELET_PHASE.DISPLAY_END);
|
|
129
|
+
this.bigPipe.pageletDisplayed(this);
|
|
130
|
+
}
|
|
131
|
+
}
|
package/src/Primer.js
CHANGED
|
@@ -83,13 +83,18 @@ export default function Primer() {
|
|
|
83
83
|
eventTarget.getAttribute("rel") === "async") {
|
|
84
84
|
event.preventDefault();
|
|
85
85
|
|
|
86
|
+
const formData = new FormData(eventTarget);
|
|
86
87
|
const submitter = event.submitter || eventTarget.querySelector("button[type='submit']");
|
|
87
88
|
const activeControls = eventTarget.querySelectorAll("input:not([readonly]),select:not([readonly]),textarea:not([readonly])");
|
|
88
89
|
|
|
90
|
+
if (submitter.name) {
|
|
91
|
+
formData.append(submitter.name, submitter.value);
|
|
92
|
+
}
|
|
93
|
+
|
|
89
94
|
(new AsyncRequest(eventTarget.getAttribute("ajaxify") || eventTarget.getAttribute("action")))
|
|
90
95
|
.setMethod(eventTarget.method || "POST")
|
|
91
96
|
.setRelative(eventTarget)
|
|
92
|
-
.setData(
|
|
97
|
+
.setData(formData)
|
|
93
98
|
.setInitialHandler(function () {
|
|
94
99
|
eventTarget.classList.add("async-saving");
|
|
95
100
|
|
|
@@ -131,12 +136,16 @@ export default function Primer() {
|
|
|
131
136
|
}
|
|
132
137
|
})
|
|
133
138
|
.setErrorHandler(function () {
|
|
134
|
-
eventTarget.classList.
|
|
139
|
+
eventTarget.classList.remove("async-saving");
|
|
135
140
|
|
|
136
141
|
activeControls.forEach(function (control) {
|
|
137
142
|
control.removeAttribute("readonly");
|
|
138
143
|
});
|
|
139
144
|
|
|
145
|
+
if (submitter) {
|
|
146
|
+
submitter.disabled = false;
|
|
147
|
+
}
|
|
148
|
+
|
|
140
149
|
if (eventTarget) {
|
|
141
150
|
const loader = eventTarget.querySelector(".small-loader");
|
|
142
151
|
|
package/src/ServerJS.js
CHANGED
package/src/async/AsyncDOM.js
CHANGED
|
@@ -11,7 +11,7 @@ export default class AsyncDOM {
|
|
|
11
11
|
node = (node || document.documentElement).querySelector(selector);
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
if (!node) {
|
|
14
|
+
if (__DEV__ && !node) {
|
|
15
15
|
console.error(`Selector '${selector}' does not match anything!`)
|
|
16
16
|
continue;
|
|
17
17
|
}
|
|
@@ -46,6 +46,7 @@ export default class AsyncDOM {
|
|
|
46
46
|
break;
|
|
47
47
|
case "replace":
|
|
48
48
|
DOM.replace(node, content.__html);
|
|
49
|
+
break;
|
|
49
50
|
}
|
|
50
51
|
}
|
|
51
52
|
}
|
|
@@ -3,6 +3,10 @@ import AsyncResponse from "./AsyncResponse";
|
|
|
3
3
|
|
|
4
4
|
let requests = 0;
|
|
5
5
|
|
|
6
|
+
export function incrementRequests() {
|
|
7
|
+
return requests++;
|
|
8
|
+
}
|
|
9
|
+
|
|
6
10
|
function serialize(obj, prefix) {
|
|
7
11
|
const str = [];
|
|
8
12
|
for(const p in obj) {
|
|
@@ -150,7 +154,7 @@ export default class AsyncRequest {
|
|
|
150
154
|
const handler = this.getHandler();
|
|
151
155
|
const errorHandler = this.getErrorHandler();
|
|
152
156
|
const initialHandler = this.getInitialHandler();
|
|
153
|
-
const
|
|
157
|
+
const finallyHandler = this.getFinallyHandler();
|
|
154
158
|
|
|
155
159
|
initialHandler();
|
|
156
160
|
|
|
@@ -164,7 +168,7 @@ export default class AsyncRequest {
|
|
|
164
168
|
let response;
|
|
165
169
|
try {
|
|
166
170
|
const safeJson = self._unshieldResponseText(this.responseText);
|
|
167
|
-
response =
|
|
171
|
+
response = JSON.parse(safeJson);
|
|
168
172
|
} catch (e) {
|
|
169
173
|
throw new Error("Failed to handle response: " + e.message + "\n" + this.responseText);
|
|
170
174
|
}
|
|
@@ -176,12 +180,12 @@ export default class AsyncRequest {
|
|
|
176
180
|
errorHandler(this);
|
|
177
181
|
}
|
|
178
182
|
|
|
179
|
-
|
|
183
|
+
finallyHandler(this);
|
|
180
184
|
}
|
|
181
185
|
|
|
182
186
|
request.setRequestHeader("X-Requested-With", "XMLHttpRequest");
|
|
183
187
|
|
|
184
|
-
|
|
188
|
+
incrementRequests();
|
|
185
189
|
|
|
186
190
|
if (data instanceof FormData) {
|
|
187
191
|
data.append('__req', requests);
|
|
@@ -18,7 +18,7 @@ export default function replaceTransportMarkers(markerValue, markers, key) {
|
|
|
18
18
|
} else if (marker.__set) {
|
|
19
19
|
markers[key] = new Set(marker.__set);
|
|
20
20
|
} else {
|
|
21
|
-
for (
|
|
21
|
+
for (const value in marker) {
|
|
22
22
|
replaceTransportMarkers(markerValue, marker, value);
|
|
23
23
|
}
|
|
24
24
|
}
|