bigpipe-util 0.1.2 → 0.2.0
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 +26 -0
- package/README.md +0 -4
- package/package.json +1 -1
- package/src/ServerJS.js +0 -2
- package/src/async/AsyncDOM.js +5 -0
- package/src/async/AsyncRequest.js +22 -2
- package/src/core/Dialog.js +22 -10
package/CHANGELOG.md
CHANGED
|
@@ -13,3 +13,29 @@ Updates should follow the [Keep a CHANGELOG](http://keepachangelog.com/) princip
|
|
|
13
13
|
|
|
14
14
|
### Added
|
|
15
15
|
- Dialogs support.
|
|
16
|
+
|
|
17
|
+
## v0.1.3 - 2022-04-27
|
|
18
|
+
|
|
19
|
+
### Added
|
|
20
|
+
- Method to close only current dialog
|
|
21
|
+
|
|
22
|
+
### Fixed
|
|
23
|
+
- Dialog z-index
|
|
24
|
+
|
|
25
|
+
## v0.1.4 - 2022-05-06
|
|
26
|
+
|
|
27
|
+
### Added
|
|
28
|
+
- Async requests counter
|
|
29
|
+
- Support for extra arguments in dialog controller
|
|
30
|
+
|
|
31
|
+
### Fixed
|
|
32
|
+
- Arguments for non-method require calls
|
|
33
|
+
|
|
34
|
+
## v0.2.0 - 2022-05-17
|
|
35
|
+
|
|
36
|
+
### Added
|
|
37
|
+
- Shield to prevent "JSON Hijacking"
|
|
38
|
+
- Invalid node checking for AsyncDOM
|
|
39
|
+
|
|
40
|
+
### Fixed
|
|
41
|
+
- Backdrop for 2+ opened dialogs
|
package/README.md
CHANGED
|
@@ -106,10 +106,6 @@ if (OH_NOES_WE_NEED_TO_CANCEL_RIGHT_NOW_OR_ELSE) {
|
|
|
106
106
|
rel="dialog">Open Modal</a>
|
|
107
107
|
```
|
|
108
108
|
|
|
109
|
-
## Credits
|
|
110
|
-
|
|
111
|
-
- [Richard Dobroň][link-author]
|
|
112
|
-
|
|
113
109
|
## Inspiration
|
|
114
110
|
|
|
115
111
|
BigPipe is inspired by the concept behind Facebook's BigPipe. For more details
|
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.
|
|
4
|
+
"version": "0.2.0",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"bigpipe",
|
|
7
7
|
"xhr",
|
package/src/ServerJS.js
CHANGED
package/src/async/AsyncDOM.js
CHANGED
|
@@ -15,6 +15,11 @@ export default class AsyncDOM {
|
|
|
15
15
|
node = (node || document.documentElement).querySelector(selector);
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
+
if (!node) {
|
|
19
|
+
console.error(`Selector '${selector}' does not match anything!`)
|
|
20
|
+
continue;
|
|
21
|
+
}
|
|
22
|
+
|
|
18
23
|
switch (type) {
|
|
19
24
|
case "eval":
|
|
20
25
|
(new Function(content)).apply(node);
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import emptyFunction from "fbjs/lib/emptyFunction";
|
|
2
2
|
import AsyncResponse from "./AsyncResponse";
|
|
3
3
|
|
|
4
|
+
let requests = 0;
|
|
5
|
+
|
|
4
6
|
function serialize(obj, prefix) {
|
|
5
7
|
const str = [];
|
|
6
8
|
for(const p in obj) {
|
|
@@ -119,6 +121,17 @@ AsyncRequest.prototype.abort = function () {
|
|
|
119
121
|
}
|
|
120
122
|
};
|
|
121
123
|
|
|
124
|
+
AsyncRequest.prototype._unshieldResponseText = function (text) {
|
|
125
|
+
const shield = "for (;;);";
|
|
126
|
+
const shieldLength = shield.length;
|
|
127
|
+
|
|
128
|
+
if (text.length <= shieldLength) {
|
|
129
|
+
throw new Error("Response too short on async to " + this.getURI());
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return text.substring(shieldLength);
|
|
133
|
+
};
|
|
134
|
+
|
|
122
135
|
AsyncRequest.prototype.send = function () {
|
|
123
136
|
const {uri, method} = this;
|
|
124
137
|
let { data } = this;
|
|
@@ -138,7 +151,8 @@ AsyncRequest.prototype.send = function () {
|
|
|
138
151
|
if (this.status >= 200 && this.status < 400) {
|
|
139
152
|
let response;
|
|
140
153
|
try {
|
|
141
|
-
|
|
154
|
+
const safeJson = self._unshieldResponseText(this.responseText);
|
|
155
|
+
response = eval("(" + safeJson + ")");
|
|
142
156
|
} catch (e) {
|
|
143
157
|
throw new Error("Failed to handle response: " + e.message + "\n" + this.responseText);
|
|
144
158
|
}
|
|
@@ -152,7 +166,13 @@ AsyncRequest.prototype.send = function () {
|
|
|
152
166
|
};
|
|
153
167
|
|
|
154
168
|
request.setRequestHeader("X-Requested-With", "XMLHttpRequest");
|
|
155
|
-
|
|
169
|
+
|
|
170
|
+
requests++;
|
|
171
|
+
|
|
172
|
+
if (this.data instanceof FormData) {
|
|
173
|
+
this.data.append('__req', requests);
|
|
174
|
+
} else {
|
|
175
|
+
data.__req = requests;
|
|
156
176
|
data = serialize(data);
|
|
157
177
|
|
|
158
178
|
if (method === "POST") {
|
package/src/core/Dialog.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import Modal from "modal-vanilla/lib/modal";
|
|
2
2
|
import DOM from "./DOM";
|
|
3
3
|
|
|
4
|
+
const DEFAULT_Z_INDEX = 1040;
|
|
5
|
+
|
|
4
6
|
const stack = [];
|
|
5
7
|
let modalId = 1;
|
|
6
|
-
let zIndex
|
|
8
|
+
let zIndex;
|
|
7
9
|
let originalBodyPad = null;
|
|
8
10
|
|
|
9
11
|
export default class Dialog {
|
|
@@ -11,7 +13,15 @@ export default class Dialog {
|
|
|
11
13
|
stack.forEach((dialog) => dialog.hide())
|
|
12
14
|
}
|
|
13
15
|
|
|
14
|
-
|
|
16
|
+
closeCurrent() {
|
|
17
|
+
const dialog = stack[stack.length - 1];
|
|
18
|
+
|
|
19
|
+
if (dialog) {
|
|
20
|
+
dialog.hide();
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
render(options, args) {
|
|
15
25
|
DOM.appendContent(document.body, this._makeDialog(options.content));
|
|
16
26
|
|
|
17
27
|
modalId++;
|
|
@@ -22,12 +32,12 @@ export default class Dialog {
|
|
|
22
32
|
backdrop: options.backdrop ?? true,
|
|
23
33
|
transition: options.transition ?? 0,
|
|
24
34
|
backdropTransition: options.backdropTransition ?? 0,
|
|
25
|
-
}, options.controller);
|
|
35
|
+
}, options.controller, args);
|
|
26
36
|
|
|
27
37
|
stack.push(_dialog);
|
|
28
38
|
}
|
|
29
39
|
|
|
30
|
-
showFromModel(model) {
|
|
40
|
+
showFromModel(model, args) {
|
|
31
41
|
const _dialog = this._show({
|
|
32
42
|
title: model.title || '',
|
|
33
43
|
content: model.body,
|
|
@@ -36,12 +46,12 @@ export default class Dialog {
|
|
|
36
46
|
backdrop: model.backdrop ?? true,
|
|
37
47
|
transition: model.transition ?? 0,
|
|
38
48
|
backdropTransition: model.backdropTransition ?? 0,
|
|
39
|
-
}, model.controller);
|
|
49
|
+
}, model.controller, args);
|
|
40
50
|
|
|
41
51
|
stack.push(_dialog);
|
|
42
52
|
}
|
|
43
53
|
|
|
44
|
-
_show(options, controller) {
|
|
54
|
+
_show(options, controller, args) {
|
|
45
55
|
if (originalBodyPad === null) {
|
|
46
56
|
originalBodyPad = document.body.style.paddingRight;
|
|
47
57
|
}
|
|
@@ -49,13 +59,13 @@ export default class Dialog {
|
|
|
49
59
|
const _modal = new Modal(options);
|
|
50
60
|
|
|
51
61
|
if (controller) {
|
|
52
|
-
(new (window.require(controller))(_modal));
|
|
62
|
+
(new (window.require(controller))(_modal, ...args));
|
|
53
63
|
}
|
|
54
64
|
|
|
55
65
|
const self = this;
|
|
56
66
|
|
|
57
67
|
return _modal.on('shown', function ({el}) {
|
|
58
|
-
zIndex = 10 * stack.length;
|
|
68
|
+
zIndex = DEFAULT_Z_INDEX + (10 * stack.length);
|
|
59
69
|
el.style.zIndex = zIndex;
|
|
60
70
|
setTimeout(() => document.querySelector('.modal-backdrop').style.zIndex = zIndex - 1);
|
|
61
71
|
}).on('showBackdrop', this._fixBackdrop).on('hidden', function ({el}) {
|
|
@@ -73,15 +83,17 @@ export default class Dialog {
|
|
|
73
83
|
}).show();
|
|
74
84
|
}
|
|
75
85
|
|
|
76
|
-
_fixBackdrop(
|
|
86
|
+
_fixBackdrop() {
|
|
77
87
|
const backdrops = document.querySelectorAll('.modal-backdrop');
|
|
88
|
+
let shown = false;
|
|
78
89
|
|
|
79
90
|
backdrops.forEach((backdrop, index) => {
|
|
80
|
-
if (index > 0 && index === backdrops.length - 1) {
|
|
91
|
+
if (shown || index > 0 && index === backdrops.length - 1) {
|
|
81
92
|
backdrop.style.display = 'none';
|
|
82
93
|
} else {
|
|
83
94
|
backdrop.style.zIndex = zIndex - 1;
|
|
84
95
|
backdrop.style.display = '';
|
|
96
|
+
shown = true;
|
|
85
97
|
}
|
|
86
98
|
});
|
|
87
99
|
}
|