statebus 6.1.22 → 7.0.2
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/{client.js → clients.js} +184 -130
- package/extras/tests.js +292 -412
- package/package.json +10 -3
- package/{server.js → servers.js} +285 -333
- package/statebus.js +297 -620
- package/extras/coffee.js +0 -12
- package/extras/dash.coffee +0 -302
- package/extras/diffsync.js +0 -1462
- package/extras/getCaretCoordinates.js +0 -141
- package/extras/react.js +0 -18147
- package/extras/sockjs.js +0 -27
package/{client.js → clients.js}
RENAMED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
var websocket_prefix = (clientjs_option('websocket_path')
|
|
3
3
|
|| '_connect_to_statebus_')
|
|
4
4
|
|
|
5
|
+
// Todo: remove this global
|
|
5
6
|
window.dom = window.dom || new Proxy({}, {
|
|
6
7
|
get: function (o, k) { return o[k] },
|
|
7
8
|
set: function (o, k, v) {
|
|
@@ -42,7 +43,7 @@
|
|
|
42
43
|
// return new SockJS(url + '/' + websocket_prefix)
|
|
43
44
|
}
|
|
44
45
|
function client_creds (server_url) {
|
|
45
|
-
var me = bus.
|
|
46
|
+
var me = bus.get('ls/me')
|
|
46
47
|
bus.log('connect: me is', me)
|
|
47
48
|
if (!me.client) {
|
|
48
49
|
// Create a client id if we have none yet.
|
|
@@ -51,19 +52,20 @@
|
|
|
51
52
|
me.client = c || (Math.random().toString(36).substring(2)
|
|
52
53
|
+ Math.random().toString(36).substring(2)
|
|
53
54
|
+ Math.random().toString(36).substring(2))
|
|
54
|
-
bus.
|
|
55
|
+
bus.set(me)
|
|
55
56
|
}
|
|
56
57
|
|
|
57
58
|
set_cookie('client', me.client)
|
|
58
59
|
return {clientid: me.client}
|
|
59
60
|
}
|
|
60
61
|
|
|
61
|
-
function
|
|
62
|
+
function http_mount (prefix, url) {
|
|
62
63
|
var preprefix = prefix.slice(0,-1)
|
|
63
64
|
var has_prefix = new RegExp('^' + preprefix)
|
|
64
65
|
var is_absolute = /^https?:\/\//
|
|
65
66
|
var subscriptions = {}
|
|
66
|
-
|
|
67
|
+
var put_counter = 0
|
|
68
|
+
|
|
67
69
|
function add_prefix (key) {
|
|
68
70
|
return is_absolute.test(key) ? key : preprefix + key }
|
|
69
71
|
function rem_prefix (key) {
|
|
@@ -73,24 +75,66 @@
|
|
|
73
75
|
function rem_prefixes (obj) {
|
|
74
76
|
return bus.translate_keys(bus.clone(obj), rem_prefix) }
|
|
75
77
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
+
var puts = new Map()
|
|
79
|
+
function enqueue_put (url, body) {
|
|
80
|
+
var id = put_counter++
|
|
81
|
+
puts.set(id, {url: url, body: body, id: id})
|
|
82
|
+
send_put(id)
|
|
83
|
+
}
|
|
84
|
+
function send_put (id) {
|
|
85
|
+
try {
|
|
86
|
+
puts.get(id).status = 'sending'
|
|
87
|
+
braid_fetch(
|
|
88
|
+
puts.get(id).url,
|
|
89
|
+
{
|
|
90
|
+
method: 'put',
|
|
91
|
+
headers: {
|
|
92
|
+
'content-type': 'application/json',
|
|
93
|
+
'put-order': id,
|
|
94
|
+
},
|
|
95
|
+
body: puts.get(id).body
|
|
96
|
+
}
|
|
97
|
+
).then(function (res) {
|
|
98
|
+
if (res.status !== 200)
|
|
99
|
+
console.error('Server gave error on PUT:',
|
|
100
|
+
e, 'for', puts.get(id).body)
|
|
101
|
+
puts.delete(id)
|
|
102
|
+
}).catch(function (e) {
|
|
103
|
+
console.error('Error on PUT, waiting...', puts.get(id).url)
|
|
104
|
+
puts.get(id).status = 'waiting'
|
|
105
|
+
})
|
|
106
|
+
} catch (e) {
|
|
107
|
+
console.error('Error on PUT, waiting...', puts.get(id).url)
|
|
108
|
+
puts.get(id).status = 'waiting'
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
function retry_put (id) {
|
|
112
|
+
setTimeout(function () {send_put(id)}, 1000)
|
|
113
|
+
}
|
|
114
|
+
function send_all_puts () {
|
|
115
|
+
for (var id of puts.keys())
|
|
116
|
+
if (puts.get(id).status === 'waiting') {
|
|
117
|
+
console.log('Sending waiting put', id)
|
|
118
|
+
send_put(id)
|
|
119
|
+
}
|
|
120
|
+
}
|
|
78
121
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
// if (t.parents) x.parents = t.parents
|
|
82
|
-
// if (t.patch) x.patch = t.patch
|
|
83
|
-
// if (t.patch) x.save = rem_prefix(x.save.key)
|
|
122
|
+
bus(prefix).to_set = function (obj, t) {
|
|
123
|
+
bus.set.fire(obj)
|
|
84
124
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
125
|
+
var put = {
|
|
126
|
+
url: url + rem_prefix(obj.key),
|
|
127
|
+
body: JSON.stringify(obj.val)
|
|
128
|
+
}
|
|
129
|
+
if (t.version) put.version = t.version
|
|
130
|
+
if (t.parents) put.parents = t.parents
|
|
131
|
+
if (t.patch) put.patch = t.patch
|
|
132
|
+
var put_id = put_counter++
|
|
133
|
+
puts.set(put_id, put)
|
|
134
|
+
send_put(put_id)
|
|
91
135
|
}
|
|
92
136
|
|
|
93
|
-
bus(prefix).
|
|
137
|
+
bus(prefix).to_get = function (key, t) {
|
|
94
138
|
// Subscription can be in states:
|
|
95
139
|
// - connecting
|
|
96
140
|
// - connected
|
|
@@ -98,13 +142,13 @@
|
|
|
98
142
|
// - reconnecting
|
|
99
143
|
// - aborted
|
|
100
144
|
|
|
101
|
-
// If we have an outstanding
|
|
145
|
+
// If we have an outstanding get running, then let's tell it to
|
|
102
146
|
// re-activate!
|
|
103
147
|
if (subscriptions[key]) {
|
|
104
148
|
// We should only be here if an existing subscription was
|
|
105
149
|
// aborted, but hasn't cleared yet.
|
|
106
150
|
console.assert(subscriptions[key].status === 'aborted',
|
|
107
|
-
'
|
|
151
|
+
'Regetting a subscription of status '
|
|
108
152
|
+ subscriptions[key].status)
|
|
109
153
|
|
|
110
154
|
console.trace('foo')
|
|
@@ -140,6 +184,7 @@
|
|
|
140
184
|
'color: blue')
|
|
141
185
|
reconnect_attempts = 0
|
|
142
186
|
subscriptions[key].status = 'connected'
|
|
187
|
+
send_all_puts()
|
|
143
188
|
}
|
|
144
189
|
|
|
145
190
|
// Return the update
|
|
@@ -149,7 +194,7 @@
|
|
|
149
194
|
})
|
|
150
195
|
}).catch( function (e) {
|
|
151
196
|
if (subscriptions[key].status === 'aborted') {
|
|
152
|
-
// Then this
|
|
197
|
+
// Then this get is over and done with!
|
|
153
198
|
delete subscriptions[key]
|
|
154
199
|
return
|
|
155
200
|
}
|
|
@@ -179,37 +224,30 @@
|
|
|
179
224
|
function localstorage_client (prefix) {
|
|
180
225
|
try { localStorage } catch (e) { return }
|
|
181
226
|
|
|
182
|
-
//
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
var bus = this
|
|
186
|
-
bus.log(this)
|
|
227
|
+
// Sets are queued up, to store values with a delay, in batch
|
|
228
|
+
var sets_are_pending = false
|
|
229
|
+
var pending_sets = {}
|
|
187
230
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
function save_the_pending_saves() {
|
|
194
|
-
bus.log('localstore: saving', pending_saves)
|
|
195
|
-
for (var k in pending_saves)
|
|
196
|
-
localStorage.setItem(k, JSON.stringify(pending_saves[k]))
|
|
197
|
-
saves_are_pending = false
|
|
231
|
+
function set_the_pending_sets() {
|
|
232
|
+
bus.log('localstore: saving', pending_sets)
|
|
233
|
+
for (var k in pending_sets)
|
|
234
|
+
localStorage.setItem(k, JSON.stringify(pending_sets[k]))
|
|
235
|
+
sets_are_pending = false
|
|
198
236
|
}
|
|
199
237
|
|
|
200
|
-
bus(prefix).
|
|
238
|
+
bus(prefix).to_get = function (key) {
|
|
201
239
|
var result = localStorage.getItem(key)
|
|
202
240
|
return result ? JSON.parse(result) : {key: key}
|
|
203
241
|
}
|
|
204
|
-
bus(prefix).
|
|
242
|
+
bus(prefix).to_set = function (obj) {
|
|
205
243
|
// Do I need to make this recurse into the object?
|
|
206
|
-
bus.log('localStore:
|
|
207
|
-
|
|
208
|
-
if (!
|
|
209
|
-
setTimeout(
|
|
210
|
-
|
|
244
|
+
bus.log('localStore: on_set:', obj.key)
|
|
245
|
+
pending_sets[obj.key] = obj
|
|
246
|
+
if (!sets_are_pending) {
|
|
247
|
+
setTimeout(set_the_pending_sets, 50)
|
|
248
|
+
sets_are_pending = true
|
|
211
249
|
}
|
|
212
|
-
bus.
|
|
250
|
+
bus.set.fire(obj)
|
|
213
251
|
return obj
|
|
214
252
|
}
|
|
215
253
|
bus(prefix).to_delete = function (key) { localStorage.removeItem(key) }
|
|
@@ -218,6 +256,7 @@
|
|
|
218
256
|
// Hm... this update stuff doesn't seem to work on file:/// urls in chrome
|
|
219
257
|
function update (event) {
|
|
220
258
|
bus.log('Got a localstorage update', event)
|
|
259
|
+
bus.dirty(event.key)
|
|
221
260
|
//this.get(event.key.substr('statebus '.length))
|
|
222
261
|
}
|
|
223
262
|
if (window.addEventListener) window.addEventListener("storage", update, false)
|
|
@@ -242,39 +281,16 @@
|
|
|
242
281
|
data = (data && JSON.parse(data)) || {key : key}
|
|
243
282
|
// Then I would need to:
|
|
244
283
|
// - Change the key prefix
|
|
245
|
-
// -
|
|
284
|
+
// - Set this into the cache
|
|
246
285
|
|
|
247
|
-
bus(prefix).
|
|
286
|
+
bus(prefix).to_set = function (obj) {
|
|
248
287
|
window.history.replaceState(
|
|
249
288
|
'',
|
|
250
289
|
'',
|
|
251
290
|
document.location.origin
|
|
252
291
|
+ document.location.pathname
|
|
253
292
|
+ escape('?'+key+'='+JSON.stringify(obj)))
|
|
254
|
-
bus.
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
function live_reload_from (prefix) {
|
|
259
|
-
if (!window.live_reload_initialized) {
|
|
260
|
-
var first_time = true
|
|
261
|
-
this(function () {
|
|
262
|
-
var re = new RegExp(".*/" + prefix + "/(.*)")
|
|
263
|
-
var file = window.location.href.match(re)[1]
|
|
264
|
-
var code = bus.fetch('/code/invisible.college/' + file).code
|
|
265
|
-
if (!code) return
|
|
266
|
-
if (first_time) {first_time = false; return}
|
|
267
|
-
var old_scroll_position = window.pageYOffset
|
|
268
|
-
document.body.innerHTML = code
|
|
269
|
-
var i = 0
|
|
270
|
-
var d = 100
|
|
271
|
-
var interval = setInterval(function () {
|
|
272
|
-
if (i > 500) clearInterval(interval)
|
|
273
|
-
i += d
|
|
274
|
-
window.scrollTo(0, old_scroll_position)
|
|
275
|
-
}, d)
|
|
276
|
-
})
|
|
277
|
-
window.live_reload_initialized = true
|
|
293
|
+
bus.set.fire(obj)
|
|
278
294
|
}
|
|
279
295
|
}
|
|
280
296
|
|
|
@@ -282,30 +298,40 @@
|
|
|
282
298
|
// ****************
|
|
283
299
|
// Wrapper for React Components
|
|
284
300
|
|
|
301
|
+
function react_version () {
|
|
302
|
+
if (!window.React) return undefined;
|
|
303
|
+
return Number(window.React.version.split('.')[0])
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
// Newer React requires createReactClass as a separate libary
|
|
307
|
+
if (window.React && !React.createClass && window.createReactClass)
|
|
308
|
+
React.createClass = createReactClass
|
|
309
|
+
|
|
285
310
|
// XXX Currently assumes there's a statebus named "bus" in global
|
|
286
311
|
// XXX scope.
|
|
287
312
|
|
|
288
313
|
var components = {} // Indexed by 'component/0', 'component/1', etc.
|
|
289
314
|
var components_count = 0
|
|
290
315
|
var dirty_components = {}
|
|
291
|
-
function
|
|
316
|
+
function create_react_class(component) {
|
|
292
317
|
function wrap(name, new_func) {
|
|
293
318
|
var old_func = component[name]
|
|
294
319
|
component[name] = function wrapper () { return new_func.bind(this)(old_func) }
|
|
295
320
|
}
|
|
296
321
|
|
|
297
322
|
// Register the component's basic info
|
|
298
|
-
wrap('
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
323
|
+
wrap((react_version() >= 16 ? 'UNSAFE_' : '') + 'componentWillMount',
|
|
324
|
+
function new_cwm (orig_func) {
|
|
325
|
+
// if (component.displayName === undefined)
|
|
326
|
+
// throw 'Component needs a displayName'
|
|
327
|
+
//this.name = component.displayName.toLowerCase().replace(' ', '_')
|
|
302
328
|
this.key = 'component/' + components_count++
|
|
303
329
|
components[this.key] = this
|
|
304
330
|
|
|
305
331
|
function add_shortcut (obj, shortcut_name, to_key) {
|
|
306
332
|
delete obj[shortcut_name]
|
|
307
333
|
Object.defineProperty(obj, shortcut_name, {
|
|
308
|
-
get: function () { return bus.
|
|
334
|
+
get: function () { return bus.get(to_key) },
|
|
309
335
|
configurable: true })
|
|
310
336
|
}
|
|
311
337
|
add_shortcut(this, 'local', this.key)
|
|
@@ -326,7 +352,7 @@
|
|
|
326
352
|
&& typeof this.props[k] === 'object'
|
|
327
353
|
&& this.props[k].key)
|
|
328
354
|
|
|
329
|
-
bus.
|
|
355
|
+
bus.get(this.props[k].key)
|
|
330
356
|
|
|
331
357
|
// Call the renderer!
|
|
332
358
|
return orig_render.apply(this, arguments)
|
|
@@ -397,17 +423,12 @@
|
|
|
397
423
|
props['data-key'] = props.key
|
|
398
424
|
props['data-widget'] = component.displayName
|
|
399
425
|
|
|
400
|
-
return
|
|
401
|
-
? React.createElement(react_class, props, children)
|
|
402
|
-
: react_class(props, children))
|
|
426
|
+
return React.createElement(react_class, props, children)
|
|
403
427
|
}
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
result.prototype = react_class.prototype
|
|
428
|
+
Object.defineProperty(result, 'name',
|
|
429
|
+
{value: component.displayName, writable: false})
|
|
407
430
|
return result
|
|
408
431
|
}
|
|
409
|
-
window.React_View = React_View
|
|
410
|
-
if (window.statebus) window.statebus.create_react_class = window.statebus.createReactClass = React_View
|
|
411
432
|
|
|
412
433
|
// *****************
|
|
413
434
|
// Re-rendering react components
|
|
@@ -442,7 +463,7 @@
|
|
|
442
463
|
|
|
443
464
|
function make_client_statebus_maker () {
|
|
444
465
|
var extra_stuff = ['localstorage_client make_websocket client_creds',
|
|
445
|
-
'url_store components
|
|
466
|
+
'url_store components'].join(' ').split(' ')
|
|
446
467
|
if (window.statebus) {
|
|
447
468
|
var orig_statebus = statebus
|
|
448
469
|
window.statebus = function make_client_bus () {
|
|
@@ -463,17 +484,17 @@
|
|
|
463
484
|
if (statebus_dir) statebus_dir = statebus_dir[1] + '/'
|
|
464
485
|
else statebus_dir = ''
|
|
465
486
|
|
|
466
|
-
var js_urls = {
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
}
|
|
472
|
-
if (statebus_dir == 'https://stateb.us/')
|
|
473
|
-
|
|
487
|
+
// var js_urls = {
|
|
488
|
+
// react: statebus_dir + 'extras/react.js',
|
|
489
|
+
// sockjs: statebus_dir + 'extras/sockjs.js',
|
|
490
|
+
// coffee: statebus_dir + 'extras/coffee.js',
|
|
491
|
+
// statebus: statebus_dir + 'statebus.js'
|
|
492
|
+
// }
|
|
493
|
+
// if (statebus_dir == 'https://stateb.us/')
|
|
494
|
+
// js_urls.statebus = statebus_dir + 'statebus4.js'
|
|
474
495
|
|
|
475
|
-
for (var name in js_urls)
|
|
476
|
-
|
|
496
|
+
// for (var name in js_urls)
|
|
497
|
+
// document.write('<script src="' + js_urls[name] + '" charset="utf-8"></script>')
|
|
477
498
|
|
|
478
499
|
document.addEventListener('DOMContentLoaded', scripts_ready, false)
|
|
479
500
|
}
|
|
@@ -484,56 +505,52 @@
|
|
|
484
505
|
function clientjs_option (option_name) {
|
|
485
506
|
// This function must be copy/paste synchronized with statebus.js. Be
|
|
486
507
|
// sure to clone all edits there.
|
|
487
|
-
var script_elem = (
|
|
488
|
-
document.querySelector('script[src*="/client"][src$=".js"]') ||
|
|
489
|
-
document.querySelector('script[src^="client"][src$=".js"]'))
|
|
508
|
+
var script_elem = document.querySelector('script[src$="statebus/client.js"]')
|
|
490
509
|
return script_elem && script_elem.getAttribute(option_name)
|
|
491
510
|
}
|
|
492
511
|
var loaded_from_file_url = window.location.href.match(/^file:\/\//)
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
window.
|
|
512
|
+
|
|
513
|
+
// Todo: remove this global
|
|
514
|
+
window.statebus_server = clientjs_option('server')
|
|
496
515
|
var react_render
|
|
497
516
|
function scripts_ready () {
|
|
498
|
-
react_render =
|
|
499
|
-
make_client_statebus_maker()
|
|
517
|
+
react_render = ReactDOM.render
|
|
518
|
+
// make_client_statebus_maker()
|
|
500
519
|
window.bus = window.statebus()
|
|
501
520
|
bus.label = 'bus'
|
|
502
|
-
if (clientjs_option('braid_mode'))
|
|
503
|
-
bus.state = bus.braid_proxy()
|
|
504
|
-
else
|
|
505
|
-
window.sb = bus.sb
|
|
506
|
-
statebus.widget = React_View
|
|
507
|
-
statebus.create_react_class = React_View
|
|
508
|
-
statebus.createReactClass = React_View
|
|
509
|
-
|
|
510
|
-
improve_react()
|
|
511
|
-
window.ignore_flashbacks = false
|
|
512
|
-
if (statebus_server !== 'none') {
|
|
513
|
-
if (clientjs_option('braid_mode')) {
|
|
514
|
-
console.log('Using Braid-HTTP!')
|
|
515
|
-
braid_http_mount ('/*', statebus_server)
|
|
516
|
-
} else {
|
|
517
|
-
bus.net_mount ('/*', statebus_server)
|
|
518
|
-
}
|
|
519
|
-
}
|
|
520
521
|
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
522
|
+
statebus.create_react_class = create_react_class
|
|
523
|
+
statebus.createReactClass = create_react_class
|
|
524
|
+
|
|
525
|
+
// improve_react()
|
|
526
|
+
statebus.ignore_flashbacks = false
|
|
527
|
+
bus.libs = {}
|
|
528
|
+
bus.libs.http_out = http_mount
|
|
529
|
+
bus.libs.react_class = create_react_class
|
|
530
|
+
bus.libs.input = make_better_input_17()
|
|
531
|
+
bus.libs.localstorage = localstorage_client
|
|
532
|
+
|
|
533
|
+
// if (statebus_server !== 'none') {
|
|
534
|
+
// if (clientjs_option('braid_mode')) {
|
|
535
|
+
// console.log('Using Braid-HTTP!')
|
|
536
|
+
// http_mount ('/*', statebus_server)
|
|
537
|
+
// } else {
|
|
538
|
+
// bus.ws_mount ('/*', statebus_server)
|
|
539
|
+
// }
|
|
540
|
+
// }
|
|
541
|
+
|
|
525
542
|
bus.net_automount()
|
|
526
543
|
|
|
527
544
|
// This /new/* code is deprecated
|
|
528
545
|
if (!clientjs_option('braid_mode')) {
|
|
529
|
-
bus('/new/*').
|
|
546
|
+
bus('/new/*').to_set = function (o) {
|
|
530
547
|
if (o.key.split('/').length > 3) return
|
|
531
548
|
|
|
532
549
|
var old_key = o.key
|
|
533
550
|
o.key = old_key + '/' + Math.random().toString(36).substring(2,12)
|
|
534
551
|
statebus.cache[o.key] = o
|
|
535
552
|
delete statebus.cache[old_key]
|
|
536
|
-
bus.
|
|
553
|
+
bus.set(o)
|
|
537
554
|
}
|
|
538
555
|
}
|
|
539
556
|
|
|
@@ -543,6 +560,17 @@
|
|
|
543
560
|
statebus.load_client_code = load_client_code
|
|
544
561
|
statebus.load_widgets = load_widgets
|
|
545
562
|
|
|
563
|
+
if (clientjs_option('globals')) {
|
|
564
|
+
// Setup globals
|
|
565
|
+
var globals = ['get', 'set', 'state']
|
|
566
|
+
|
|
567
|
+
for (var i=0; i<globals.length; i++) {
|
|
568
|
+
console.log('globalizing', globals[i], 'as',
|
|
569
|
+
eval('bus.' + globals[i]))
|
|
570
|
+
window[globals[i]] = eval('bus.' + globals[i])
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
|
|
546
574
|
document.addEventListener('DOMContentLoaded', function () {
|
|
547
575
|
if (window.statebus_ready)
|
|
548
576
|
for (var i=0; i<statebus_ready.length; i++)
|
|
@@ -662,7 +690,7 @@
|
|
|
662
690
|
for (var i=0; i<arguments.length; i++) {
|
|
663
691
|
args.push(arguments[i])
|
|
664
692
|
if (arguments[i].state)
|
|
665
|
-
args[i].src = 'data:;base64,' +
|
|
693
|
+
args[i].src = 'data:;base64,' + bus.get(args[i].state)._
|
|
666
694
|
}
|
|
667
695
|
return og_img.apply(this, args)
|
|
668
696
|
}
|
|
@@ -694,12 +722,38 @@
|
|
|
694
722
|
}
|
|
695
723
|
|
|
696
724
|
|
|
725
|
+
// This one is for react v17+
|
|
726
|
+
function make_better_input_17 () {
|
|
727
|
+
return createReactClass({
|
|
728
|
+
getInitialState: function() {
|
|
729
|
+
return {value: this.props.value}
|
|
730
|
+
},
|
|
731
|
+
UNSAVE_componentWillReceiveProps: function(new_props) {
|
|
732
|
+
this.setState({value: new_props.value})
|
|
733
|
+
},
|
|
734
|
+
onChange: function(e) {
|
|
735
|
+
this.props.onChange && this.props.onChange(e)
|
|
736
|
+
if (this.props.value)
|
|
737
|
+
this.setState({value: e.target.value})
|
|
738
|
+
},
|
|
739
|
+
render: function() {
|
|
740
|
+
var new_props = {}
|
|
741
|
+
for (var k in this.props)
|
|
742
|
+
if (this.props.hasOwnProperty(k))
|
|
743
|
+
new_props[k] = this.props[k]
|
|
744
|
+
if (this.state.value) new_props.value = this.state.value
|
|
745
|
+
new_props.onChange = this.onChange
|
|
746
|
+
return React.createElement('input', new_props)
|
|
747
|
+
}
|
|
748
|
+
})
|
|
749
|
+
}
|
|
750
|
+
|
|
697
751
|
// Load the components
|
|
698
752
|
var users_widgets = {}
|
|
699
753
|
function make_component(name, func) {
|
|
700
754
|
// Define the component
|
|
701
755
|
|
|
702
|
-
window[name] = users_widgets[name] =
|
|
756
|
+
window[name] = users_widgets[name] = statebus.create_react_class({
|
|
703
757
|
displayName: name,
|
|
704
758
|
render: function () {
|
|
705
759
|
var args = []
|