cradova 2.2.3 → 2.3.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/README.md +276 -110
- package/dist/index.js +239 -222
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -49,11 +49,12 @@ Cradova follows the [VJS specification](https://github.com/fridaycandour/cradova
|
|
|
49
49
|
|
|
50
50
|
Cradova is aimed to be fast and simple with and fewer abstractions and yet easily composable.
|
|
51
51
|
|
|
52
|
-
Cradova
|
|
52
|
+
Cradova is not built on visual DOM or diff algorithms.
|
|
53
|
+
Instead, State management is done more elegantly with a simple predictive model, simple and easy with all the speed.
|
|
53
54
|
|
|
54
|
-
|
|
55
|
+
## Is this a big benefit?
|
|
55
56
|
|
|
56
|
-
Undoubtedly, this provides a significant advantage. You can experience it firsthand and decide
|
|
57
|
+
Undoubtedly, this provides a significant advantage. You can experience it firsthand and decide.
|
|
57
58
|
|
|
58
59
|
Cradova has already been utilized in multiple production projects, and we will continuously update this page to showcase our advancements as we keep improving.
|
|
59
60
|
|
|
@@ -83,12 +84,10 @@ npm i cradova
|
|
|
83
84
|
|
|
84
85
|
Many aspects of Cradova are not reflected in the following example. More functionality will be entailed in future docs.
|
|
85
86
|
|
|
86
|
-
|
|
87
|
+
## A basic component in Cradova:
|
|
87
88
|
|
|
88
89
|
```js
|
|
89
|
-
|
|
90
|
-
// this gives your app more performance gain.
|
|
91
|
-
import _, { h1 } from "cradova";
|
|
90
|
+
import { div, h1 } from "cradova";
|
|
92
91
|
|
|
93
92
|
function Hello(name) {
|
|
94
93
|
return h1("Hello " + name, {
|
|
@@ -99,88 +98,56 @@ function Hello(name) {
|
|
|
99
98
|
});
|
|
100
99
|
}
|
|
101
100
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
const html = _(Hello("peter"), Hello("joe"));
|
|
101
|
+
const html = div(Hello("peter"), Hello("joe"));
|
|
105
102
|
|
|
106
103
|
document.body.append(html);
|
|
107
104
|
```
|
|
108
105
|
|
|
109
|
-
|
|
110
|
-
// regular example
|
|
111
|
-
import _ from "cradova";
|
|
112
|
-
|
|
113
|
-
function Hello(name) {
|
|
114
|
-
return _("h1", "Hello " + name);
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
const html = _(Hello("peter"), Hello("joe"));
|
|
118
|
-
|
|
119
|
-
document.body.append(html);
|
|
120
|
-
```
|
|
106
|
+
## working with state:
|
|
121
107
|
|
|
122
|
-
|
|
108
|
+
this a collection of basic examples
|
|
109
|
+
you can choose any that best suite what problem you want to solve
|
|
123
110
|
|
|
124
111
|
```js
|
|
125
|
-
import _, {
|
|
112
|
+
import _, {
|
|
113
|
+
button,
|
|
114
|
+
createSignal,
|
|
115
|
+
Ref,
|
|
116
|
+
reference,
|
|
117
|
+
h1,
|
|
118
|
+
br,
|
|
119
|
+
div,
|
|
120
|
+
} from "../dist/index.js";
|
|
126
121
|
|
|
127
|
-
function
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
}
|
|
133
|
-
this.updateState(await name)
|
|
122
|
+
function Hello(name) {
|
|
123
|
+
return h1("Hello " + name, {
|
|
124
|
+
className: "title",
|
|
125
|
+
style: {
|
|
126
|
+
color: "grey",
|
|
127
|
+
},
|
|
134
128
|
});
|
|
135
|
-
// effects can be used to make api calls needed for the page
|
|
136
|
-
return _("div", "Hello " + name);
|
|
137
129
|
}
|
|
138
130
|
|
|
131
|
+
const html = div(Hello("peter"), Hello("joe"));
|
|
132
|
+
|
|
133
|
+
// reference (not state)
|
|
134
|
+
|
|
135
|
+
function typingExample() {
|
|
136
|
+
const re = new reference();
|
|
137
|
+
return _(
|
|
138
|
+
"div",
|
|
139
|
+
input({
|
|
140
|
+
oninput() {
|
|
141
|
+
re.text.innerText = this.value;
|
|
142
|
+
},
|
|
143
|
+
placeholder: "typing simulation",
|
|
144
|
+
}),
|
|
145
|
+
p(" no thing typed yet!", { reference: re.bindAs("text") })
|
|
146
|
+
);
|
|
147
|
+
}
|
|
139
148
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
when using router and screens
|
|
143
|
-
|
|
144
|
-
cradova will create a div with data-cra-id=cradova-app-wrapper
|
|
145
|
-
|
|
146
|
-
if it already exist cradova will use it instead
|
|
147
|
-
|
|
148
|
-
so if you want to use your own mount point then create a div with data-cra-id="cradova-app-wrapper"
|
|
149
|
-
|
|
150
|
-
*/
|
|
151
|
-
|
|
152
|
-
const home = new Screen({
|
|
153
|
-
name: "hello page", // page title
|
|
154
|
-
template: HelloMessage,
|
|
155
|
-
...
|
|
156
|
-
});
|
|
157
|
-
|
|
158
|
-
Router.route("/", home);
|
|
159
|
-
|
|
160
|
-
// navigates to that page
|
|
161
|
-
// Router.navigate("/home", data, force);
|
|
162
|
-
// get the page ready in the background
|
|
163
|
-
// Router.packageScreen("/home");
|
|
164
|
-
// get route params for this page
|
|
165
|
-
// Router.getParams();
|
|
166
|
-
|
|
167
|
-
```
|
|
168
|
-
|
|
169
|
-
## State management
|
|
170
|
-
|
|
171
|
-
```js
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
// element can have this.updateState when the shouldUpdate props is true
|
|
175
|
-
|
|
176
|
-
// Ref components
|
|
177
|
-
|
|
178
|
-
// state can be managed from a store when using createSignal or simpleStores
|
|
179
|
-
// this method is not yet documented
|
|
180
|
-
|
|
181
|
-
import _, { Ref } from "cradova";
|
|
182
|
-
|
|
183
|
-
// simple count
|
|
149
|
+
// setting shouldUpdate to true
|
|
150
|
+
// gives you this.updateState binding
|
|
184
151
|
|
|
185
152
|
function counter() {
|
|
186
153
|
let num = 0;
|
|
@@ -193,32 +160,42 @@ function counter() {
|
|
|
193
160
|
});
|
|
194
161
|
}
|
|
195
162
|
|
|
163
|
+
// Another example with data- attribute
|
|
164
|
+
|
|
196
165
|
function dataCounter() {
|
|
197
166
|
return _("h1| 0", {
|
|
198
167
|
shouldUpdate: true,
|
|
199
168
|
"data-num": "0",
|
|
200
169
|
onclick() {
|
|
201
|
-
|
|
202
|
-
this.updateState({ text: num,
|
|
170
|
+
const num = this.getAttribute("data-num") * 1 + 1;
|
|
171
|
+
this.updateState({ text: num, "data-num": num });
|
|
203
172
|
},
|
|
204
173
|
});
|
|
205
174
|
}
|
|
206
175
|
|
|
207
|
-
|
|
208
|
-
|
|
176
|
+
// hello message
|
|
177
|
+
|
|
178
|
+
function HelloMessage() {
|
|
179
|
+
return div({
|
|
209
180
|
shouldUpdate: true,
|
|
210
|
-
text: "
|
|
181
|
+
text: "Click to get a greeting",
|
|
211
182
|
onclick() {
|
|
212
183
|
const name = prompt("what are your names");
|
|
213
|
-
this.updateState({
|
|
184
|
+
this.updateState({
|
|
185
|
+
text: name ? "hello " + name : "Click to get a greeting",
|
|
186
|
+
});
|
|
214
187
|
},
|
|
215
188
|
});
|
|
216
189
|
}
|
|
217
190
|
|
|
218
|
-
|
|
191
|
+
// using cradova Ref
|
|
192
|
+
|
|
193
|
+
const nameRef = new Ref(function (name) {
|
|
219
194
|
const self = this;
|
|
220
195
|
return _("div.foo#bar", {
|
|
221
|
-
text:
|
|
196
|
+
text: name
|
|
197
|
+
? "hello " + (name || " user 2")
|
|
198
|
+
: "Click to get a second greeting",
|
|
222
199
|
onclick() {
|
|
223
200
|
const name = prompt();
|
|
224
201
|
self.updateState(name);
|
|
@@ -226,62 +203,251 @@ const nameRef = new Ref(function ( name ) {
|
|
|
226
203
|
});
|
|
227
204
|
});
|
|
228
205
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
206
|
+
function App() {
|
|
207
|
+
return div(counter, dataCounter, HelloMessage, br, nameRef);
|
|
208
|
+
}
|
|
232
209
|
|
|
233
|
-
|
|
210
|
+
// add your app to the DOM
|
|
234
211
|
|
|
235
|
-
|
|
212
|
+
document.body.append(App());
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
## Simple Todo list
|
|
216
|
+
|
|
217
|
+
Let's see a simple TodoList example
|
|
218
|
+
|
|
219
|
+
```js
|
|
220
|
+
import _, {
|
|
221
|
+
button,
|
|
222
|
+
createSignal,
|
|
223
|
+
css,
|
|
224
|
+
div,
|
|
225
|
+
input,
|
|
226
|
+
main,
|
|
227
|
+
p,
|
|
228
|
+
Ref,
|
|
229
|
+
reference,
|
|
230
|
+
} from "../dist/index.js";
|
|
231
|
+
|
|
232
|
+
function TodoList() {
|
|
233
|
+
// can be used to hold multiple references
|
|
234
|
+
const referenceSet = new reference();
|
|
235
|
+
|
|
236
|
+
// creating a store
|
|
237
|
+
const todoStore = new createSignal([
|
|
238
|
+
"take bath",
|
|
239
|
+
"code code code",
|
|
240
|
+
"take a break",
|
|
241
|
+
]);
|
|
242
|
+
|
|
243
|
+
// create actions
|
|
244
|
+
todoStore.createAction("add-todo", function (todo) {
|
|
245
|
+
this.set([...this.value, todo]);
|
|
246
|
+
});
|
|
236
247
|
|
|
248
|
+
todoStore.createAction("remove-todo", function (todo) {
|
|
249
|
+
const ind = this.value.indexOf(todo);
|
|
250
|
+
this.value.splice(ind, 1);
|
|
251
|
+
this.set(this.value);
|
|
252
|
+
});
|
|
237
253
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
254
|
+
// bind Ref to Signal
|
|
255
|
+
todoStore.bindRef(todoList);
|
|
256
|
+
|
|
257
|
+
// markup
|
|
258
|
+
return main(
|
|
259
|
+
_`|Todo List`,
|
|
260
|
+
div(
|
|
261
|
+
input({
|
|
262
|
+
placeholder: "type in todo",
|
|
263
|
+
reference: referenceSet.bindAs("todoInput"),
|
|
264
|
+
}),
|
|
265
|
+
button("Add todo", {
|
|
266
|
+
onclick() {
|
|
267
|
+
todoStore.fireAction("add-todo", referenceSet.todoInput.value);
|
|
268
|
+
referenceSet.todoInput.value = "";
|
|
269
|
+
},
|
|
270
|
+
})
|
|
271
|
+
),
|
|
272
|
+
todoList.render
|
|
244
273
|
);
|
|
245
274
|
}
|
|
246
275
|
|
|
276
|
+
const todoList = new Ref(function () {
|
|
277
|
+
const self = this;
|
|
278
|
+
return div(
|
|
279
|
+
self.Signal.value.map((item) =>
|
|
280
|
+
p(item, {
|
|
281
|
+
title: "click to remove",
|
|
282
|
+
onclick() {
|
|
283
|
+
self.Signal.fireAction("remove-todo", item);
|
|
284
|
+
},
|
|
285
|
+
})
|
|
286
|
+
)
|
|
287
|
+
);
|
|
288
|
+
});
|
|
289
|
+
|
|
290
|
+
document.body.appendChild(TodoList());
|
|
291
|
+
|
|
292
|
+
css`
|
|
293
|
+
body {
|
|
294
|
+
box-sizing: border-box;
|
|
295
|
+
display: flex;
|
|
296
|
+
}
|
|
297
|
+
main {
|
|
298
|
+
margin: auto;
|
|
299
|
+
}
|
|
300
|
+
main > p {
|
|
301
|
+
font-size: 2rem;
|
|
302
|
+
}
|
|
303
|
+
`;
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
## working with screen and Router:
|
|
307
|
+
|
|
308
|
+
unlike just appending stuff to the DOM,
|
|
309
|
+
a better to build apps is to use a routing system.
|
|
310
|
+
|
|
311
|
+
Cradova Router is a module that allows you do the following:
|
|
312
|
+
|
|
313
|
+
Create specified routes in you application
|
|
314
|
+
help you orchestrate navigation
|
|
315
|
+
render a screen on a route
|
|
316
|
+
pre-render a screen in the background if you want to.
|
|
317
|
+
listen to Navigation changes
|
|
318
|
+
create error boundary at screen level.
|
|
319
|
+
persist rendered screens by default
|
|
320
|
+
allow parallel screen rendering for every unique route scheme
|
|
321
|
+
|
|
322
|
+
let's try an example.
|
|
323
|
+
|
|
324
|
+
```js
|
|
325
|
+
import _, { Screen, Router } from "cradova";
|
|
326
|
+
|
|
327
|
+
// Ref can be used as screens
|
|
328
|
+
|
|
329
|
+
const template = new Ref(function (name) {
|
|
330
|
+
// an effect run once after screen renders
|
|
331
|
+
const self = this;
|
|
332
|
+
self.effect(() => {
|
|
333
|
+
const name = new Promise((res) => {
|
|
334
|
+
res("john doe");
|
|
335
|
+
});
|
|
336
|
+
setTimeout(async () => {
|
|
337
|
+
self.updateState(await name);
|
|
338
|
+
}, 1000);
|
|
339
|
+
});
|
|
340
|
+
// effects can be used to make api calls needed for the page
|
|
341
|
+
return _("div", name ? ">>>>>>>> Hello " + name : " loading...");
|
|
342
|
+
});
|
|
343
|
+
|
|
247
344
|
const home = new Screen({
|
|
248
345
|
name: "home page", // page title
|
|
249
|
-
template
|
|
250
|
-
|
|
346
|
+
template,
|
|
347
|
+
});
|
|
348
|
+
|
|
349
|
+
// in your routes.ts file
|
|
350
|
+
Router.BrowserRoutes({
|
|
351
|
+
"/home": home,
|
|
352
|
+
"/lazy-loaded-home": async () => await import("./home"),
|
|
251
353
|
});
|
|
354
|
+
// creates these routes
|
|
252
355
|
|
|
253
|
-
|
|
356
|
+
Router.packageScreen("/home", data);
|
|
357
|
+
// get the page ready in the background
|
|
358
|
+
|
|
359
|
+
Router.navigate("/home", data);
|
|
360
|
+
// navigates to that page
|
|
254
361
|
|
|
255
|
-
|
|
362
|
+
Router.getParams();
|
|
363
|
+
// get route params for this current page
|
|
364
|
+
|
|
365
|
+
Router.onPageEvent((lastRoute, newRoute) => {
|
|
366
|
+
console.log(lastRoute, newRoute);
|
|
367
|
+
});
|
|
368
|
+
// listen for navigation changes
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
### More info
|
|
372
|
+
|
|
373
|
+
---
|
|
374
|
+
|
|
375
|
+
More info on cradova Router
|
|
376
|
+
|
|
377
|
+
---
|
|
378
|
+
|
|
379
|
+
Every cradova app mounts on a div with attribute data-wrapper="app"
|
|
380
|
+
|
|
381
|
+
if it already exist cradova will use it instead.
|
|
382
|
+
|
|
383
|
+
cradova will create a div with data-wrapper="app" if it doesn't exists already.
|
|
384
|
+
|
|
385
|
+
so if you want to use your own mount point then create a div with data-wrapper="app".
|
|
386
|
+
|
|
387
|
+
---
|
|
388
|
+
|
|
389
|
+
More info on cradova screens
|
|
390
|
+
|
|
391
|
+
---
|
|
256
392
|
|
|
257
393
|
screens are rendered once by default to hack
|
|
258
394
|
responsiveness making your app work fast as user navigates.
|
|
259
395
|
|
|
260
396
|
this behavior can be override
|
|
261
397
|
by passing
|
|
262
|
-
|
|
398
|
+
persist: false
|
|
263
399
|
in the constructor
|
|
264
400
|
|
|
265
|
-
|
|
266
401
|
Cradova screens has
|
|
267
402
|
onActivate() and
|
|
268
|
-
onDeactivate() methods
|
|
403
|
+
onDeactivate() methods which is also available in the
|
|
404
|
+
component function on the this variable bound to it.
|
|
269
405
|
|
|
270
|
-
|
|
271
|
-
circle for each in your app
|
|
406
|
+
this allow you manage rendering
|
|
407
|
+
circle for each screen in your app
|
|
272
408
|
|
|
273
|
-
|
|
409
|
+
---
|
|
274
410
|
|
|
275
|
-
|
|
276
|
-
|
|
411
|
+
More info on cradova Ref
|
|
412
|
+
|
|
413
|
+
---
|
|
414
|
+
|
|
415
|
+
Refs are dynamic components, they have simple abstractions like:
|
|
416
|
+
|
|
417
|
+
- Effects
|
|
418
|
+
- stash
|
|
419
|
+
- preRender
|
|
420
|
+
- updateState
|
|
421
|
+
|
|
422
|
+
these behaviors allow you manage rendering
|
|
423
|
+
circle for refs in your app
|
|
424
|
+
|
|
425
|
+
---
|
|
426
|
+
|
|
427
|
+
More info on cradova createSignal
|
|
428
|
+
|
|
429
|
+
---
|
|
430
|
+
|
|
431
|
+
Cradova Signals allows you to create powerful data stores.
|
|
432
|
+
|
|
433
|
+
with ability to:
|
|
434
|
+
|
|
435
|
+
- create store
|
|
436
|
+
- create actions and fire them
|
|
437
|
+
- bind a Ref
|
|
438
|
+
- listen to changes
|
|
439
|
+
- persist changes to localStorage
|
|
440
|
+
- update a cradova Ref and bindings automatically
|
|
441
|
+
|
|
442
|
+
With these simple and easy abstractions, you can use datastores with powerful convenience.
|
|
277
443
|
|
|
278
444
|
## Documentation
|
|
279
445
|
|
|
280
|
-
At the moment, we're in the process of creating documentation for Cradova, and we have limited resources. If you're interested in lending a hand, we invite you to join our community, gain firsthand experience, and contribute to the advancement of Cradova.
|
|
446
|
+
At the moment, we're in the process of creating a documentation website for Cradova, and we have limited resources. If you're interested in lending a hand, we invite you to join our community, gain firsthand experience, and contribute to the advancement of Cradova.
|
|
281
447
|
|
|
282
448
|
## Getting Help
|
|
283
449
|
|
|
284
|
-
To get further insights and help on Cradova, visit our
|
|
450
|
+
To get further insights and help on Cradova, visit our [Discord](https://discord.gg/b7fvMg38) and [Telegram](https://t.me/cradovaframework) Community Chats.
|
|
285
451
|
|
|
286
452
|
## Contributing
|
|
287
453
|
|
package/dist/index.js
CHANGED
|
@@ -1,135 +1,56 @@
|
|
|
1
1
|
// lib/utils/init.ts
|
|
2
2
|
var Init = function() {
|
|
3
|
-
if (!document.querySelector("[data-
|
|
3
|
+
if (!document.querySelector("[data-wrapper=app]")) {
|
|
4
4
|
const Wrapper = document.createElement("div");
|
|
5
|
-
Wrapper.setAttribute("data-
|
|
5
|
+
Wrapper.setAttribute("data-wrapper", "app");
|
|
6
6
|
document.body.appendChild(Wrapper);
|
|
7
7
|
}
|
|
8
8
|
};
|
|
9
9
|
|
|
10
|
-
// lib/utils/
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
10
|
+
// lib/utils/fns.ts
|
|
11
|
+
var isNode = (node) => typeof node === "object" && typeof node.nodeType === "number";
|
|
12
|
+
var cradovaEvent = class {
|
|
13
|
+
constructor() {
|
|
14
|
+
this.listeners = {};
|
|
15
|
+
}
|
|
16
|
+
addEventListener(eventName, callback) {
|
|
17
|
+
if (!this.listeners[eventName]) {
|
|
18
|
+
this.listeners[eventName] = [];
|
|
16
19
|
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
throw new Error(
|
|
25
|
-
"\u2718 Cradova err : " + k + " is not a valid css style property"
|
|
26
|
-
);
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
continue;
|
|
30
|
-
}
|
|
31
|
-
if (typeof element[key] === "function") {
|
|
32
|
-
if (key.startsWith("on")) {
|
|
33
|
-
element[key] = state[key];
|
|
34
|
-
} else {
|
|
35
|
-
element[key].apply(element);
|
|
36
|
-
}
|
|
37
|
-
continue;
|
|
38
|
-
}
|
|
39
|
-
if (key === "text") {
|
|
40
|
-
element.innerText = state[key];
|
|
41
|
-
continue;
|
|
42
|
-
}
|
|
43
|
-
if (key === "remove") {
|
|
44
|
-
if (element.parentElement) {
|
|
45
|
-
element.parentElement?.removeChild(element);
|
|
46
|
-
} else {
|
|
47
|
-
element.remove();
|
|
48
|
-
}
|
|
49
|
-
continue;
|
|
50
|
-
}
|
|
51
|
-
if (key.includes("$")) {
|
|
52
|
-
element.setAttribute("data-" + key.split("$")[1], state[key]);
|
|
53
|
-
continue;
|
|
54
|
-
}
|
|
55
|
-
if (key === "tree") {
|
|
56
|
-
element.innerHTML = "";
|
|
57
|
-
element.appendChild(frag(state[key]));
|
|
58
|
-
continue;
|
|
59
|
-
}
|
|
60
|
-
try {
|
|
61
|
-
if (typeof element[key] !== "undefined") {
|
|
62
|
-
element[key] = state[key];
|
|
63
|
-
} else {
|
|
64
|
-
element[key] = state[key];
|
|
65
|
-
if (key !== "for" && key !== "text" && key !== "class" && key !== "tabindex" && key !== "disabled" && !key.includes("aria")) {
|
|
66
|
-
console.error(" \u2718 Cradova err: invalid html attribute " + key);
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
} catch (error) {
|
|
70
|
-
console.error(" \u2718 Cradova err: Cradova got ", state);
|
|
71
|
-
console.error(" \u2718 Cradova err: ", error);
|
|
72
|
-
}
|
|
20
|
+
this.listeners[eventName].push(callback);
|
|
21
|
+
}
|
|
22
|
+
removeEventListener(eventName, callback) {
|
|
23
|
+
if (this.listeners[eventName]) {
|
|
24
|
+
const index = this.listeners[eventName].indexOf(callback);
|
|
25
|
+
if (index !== -1) {
|
|
26
|
+
this.listeners[eventName].splice(index, 1);
|
|
73
27
|
}
|
|
74
|
-
} else {
|
|
75
|
-
throw new TypeError(" \u2718 Cradova err: invalid state object" + state);
|
|
76
28
|
}
|
|
77
29
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
}
|
|
84
|
-
let updated = void 0;
|
|
85
|
-
if (typeof state === "undefined" && typeof stateID === "object" && !ele) {
|
|
86
|
-
for (const [id, eachState] of Object.entries(stateID)) {
|
|
87
|
-
const elements = document.querySelectorAll(
|
|
88
|
-
"[data-cra-id=" + id + "]"
|
|
89
|
-
);
|
|
90
|
-
updated = elements.length === 1 ? elements[0] : elements;
|
|
91
|
-
cradovaDispatchTrack(elements, eachState);
|
|
92
|
-
}
|
|
93
|
-
} else {
|
|
94
|
-
if (typeof stateID === "string") {
|
|
95
|
-
const elements = document.querySelectorAll(
|
|
96
|
-
"[data-cra-id=" + stateID + "]"
|
|
97
|
-
);
|
|
98
|
-
if (elements.length) {
|
|
99
|
-
updated = elements.length === 1 ? elements[0] : elements;
|
|
100
|
-
if (!state?.cradovaDispatchTrackBreak) {
|
|
101
|
-
cradovaDispatchTrack(elements, state);
|
|
102
|
-
}
|
|
30
|
+
dispatchEvent(eventName, eventArgs) {
|
|
31
|
+
const eventListeners = this.listeners[eventName];
|
|
32
|
+
if (eventListeners) {
|
|
33
|
+
for (let i2 = 0; i2 < eventListeners.length; i2++) {
|
|
34
|
+
eventListeners[i2](eventArgs);
|
|
103
35
|
}
|
|
104
36
|
}
|
|
105
|
-
if (ele) {
|
|
106
|
-
cradovaDispatchTrack([ele], state);
|
|
107
|
-
}
|
|
108
37
|
}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
// lib/utils/fns.ts
|
|
113
|
-
var isNode = (node) => typeof node === "object" && typeof node.nodeType === "number";
|
|
114
|
-
var cradovaAftermountEvent = new CustomEvent("cradova-aftermount");
|
|
115
|
-
function uuid() {
|
|
116
|
-
let t = Date.now ? +Date.now() : +new Date();
|
|
117
|
-
return "cradova-id-xxxxxx".replace(/[x]/g, function(e) {
|
|
118
|
-
const r = (t + 16 * Math.random()) % 16 | 0;
|
|
119
|
-
return ("x" === e ? r : 7 & r | 8).toString(16);
|
|
120
|
-
});
|
|
121
|
-
}
|
|
38
|
+
};
|
|
39
|
+
var CradovaEvent = new cradovaEvent();
|
|
122
40
|
function Rhoda(l) {
|
|
123
41
|
const fg = new DocumentFragment();
|
|
124
42
|
for (let ch of l) {
|
|
125
43
|
if (Array.isArray(ch)) {
|
|
126
44
|
fg.appendChild(Rhoda(ch));
|
|
127
45
|
} else {
|
|
128
|
-
if (
|
|
129
|
-
ch = ch();
|
|
46
|
+
if (ch?.render) {
|
|
47
|
+
ch = ch.render();
|
|
130
48
|
}
|
|
131
49
|
if (typeof ch === "function") {
|
|
132
50
|
ch = ch();
|
|
51
|
+
if (typeof ch === "function") {
|
|
52
|
+
ch = ch();
|
|
53
|
+
}
|
|
133
54
|
}
|
|
134
55
|
if (typeof ch === "string" || typeof ch === "number") {
|
|
135
56
|
fg.appendChild(document.createTextNode(ch));
|
|
@@ -148,45 +69,20 @@ function Rhoda(l) {
|
|
|
148
69
|
}
|
|
149
70
|
return fg;
|
|
150
71
|
}
|
|
151
|
-
function css(identifier
|
|
152
|
-
if (
|
|
72
|
+
function css(identifier) {
|
|
73
|
+
if (Array.isArray(identifier)) {
|
|
74
|
+
identifier = identifier[0];
|
|
75
|
+
}
|
|
76
|
+
if (typeof identifier === "string") {
|
|
153
77
|
let styTag = document.querySelector("style");
|
|
154
78
|
if (styTag !== null) {
|
|
155
|
-
identifier
|
|
156
|
-
styTag.textContent = identifier;
|
|
79
|
+
styTag.textContent = identifier + styTag.textContent;
|
|
157
80
|
return;
|
|
158
81
|
}
|
|
159
82
|
styTag = document.createElement("style");
|
|
160
83
|
styTag.textContent = identifier;
|
|
161
84
|
document.head.appendChild(styTag);
|
|
162
|
-
return;
|
|
163
|
-
}
|
|
164
|
-
if (!properties) {
|
|
165
|
-
return;
|
|
166
|
-
}
|
|
167
|
-
const styS = "" + identifier + `{
|
|
168
|
-
`;
|
|
169
|
-
const styE = `}
|
|
170
|
-
`;
|
|
171
|
-
let style2 = "", totalStyle = "";
|
|
172
|
-
for (const [k, v] of Object.entries(properties)) {
|
|
173
|
-
style2 += "" + k + ": " + v + `;
|
|
174
|
-
`;
|
|
175
|
-
}
|
|
176
|
-
let styleTag = document.querySelector("style");
|
|
177
|
-
if (styleTag !== null) {
|
|
178
|
-
totalStyle += styleTag.innerHTML;
|
|
179
|
-
totalStyle += styS + style2 + styE;
|
|
180
|
-
styleTag.innerHTML = totalStyle;
|
|
181
|
-
return;
|
|
182
85
|
}
|
|
183
|
-
styleTag = document.createElement("style");
|
|
184
|
-
totalStyle += styleTag.innerHTML + `
|
|
185
|
-
|
|
186
|
-
`;
|
|
187
|
-
totalStyle += styS + style2 + styE;
|
|
188
|
-
styleTag.innerHTML = totalStyle;
|
|
189
|
-
document.head.appendChild(styleTag);
|
|
190
86
|
}
|
|
191
87
|
function assert(condition, ...elements) {
|
|
192
88
|
if (condition) {
|
|
@@ -210,28 +106,28 @@ function assertOr(condition, ifTrue, ifFalse) {
|
|
|
210
106
|
}
|
|
211
107
|
var Ref = class {
|
|
212
108
|
constructor(component) {
|
|
213
|
-
this.stateID = uuid();
|
|
214
109
|
this.effects = [];
|
|
215
110
|
this.effectuate = null;
|
|
216
111
|
this.rendered = false;
|
|
217
112
|
this.published = false;
|
|
218
113
|
this.hasFirstStateUpdateRun = false;
|
|
219
114
|
this.preRendered = null;
|
|
115
|
+
this.reference = new reference();
|
|
220
116
|
this.component = component.bind(this);
|
|
221
117
|
}
|
|
222
118
|
preRender(data2) {
|
|
223
119
|
const chtml = this.component(data2);
|
|
224
120
|
if (chtml instanceof HTMLElement) {
|
|
225
|
-
chtml.setAttribute("data-cra-id", this.stateID);
|
|
226
121
|
this.preRendered = chtml;
|
|
227
122
|
} else {
|
|
228
|
-
this.preRendered = chtml(
|
|
123
|
+
this.preRendered = chtml();
|
|
229
124
|
}
|
|
230
|
-
if (
|
|
125
|
+
if (!this.preRendered) {
|
|
231
126
|
throw new Error(
|
|
232
|
-
" \u2718 Cradova err : Invalid component type for cradova Ref
|
|
127
|
+
" \u2718 Cradova err : Invalid component type for cradova Ref got - " + this.preRendered
|
|
233
128
|
);
|
|
234
129
|
}
|
|
130
|
+
this.reference._appendDomForce("reference", this.preRendered);
|
|
235
131
|
}
|
|
236
132
|
destroyPreRendered() {
|
|
237
133
|
this.preRendered = null;
|
|
@@ -244,12 +140,11 @@ var Ref = class {
|
|
|
244
140
|
if (!this.preRendered) {
|
|
245
141
|
const chtml = this.component(data2);
|
|
246
142
|
if (chtml instanceof HTMLElement) {
|
|
247
|
-
chtml.setAttribute("data-cra-id", this.stateID);
|
|
248
143
|
element = chtml;
|
|
249
144
|
} else {
|
|
250
|
-
element = chtml(
|
|
145
|
+
element = chtml();
|
|
251
146
|
}
|
|
252
|
-
if (
|
|
147
|
+
if (!element) {
|
|
253
148
|
throw new Error(
|
|
254
149
|
" \u2718 Cradova err : Invalid component type for cradova Ref, got - " + element
|
|
255
150
|
);
|
|
@@ -260,21 +155,23 @@ var Ref = class {
|
|
|
260
155
|
}
|
|
261
156
|
const av = async () => {
|
|
262
157
|
await this.effector.apply(this);
|
|
263
|
-
|
|
158
|
+
CradovaEvent.removeEventListener("cradovaAftermountEvent", av);
|
|
264
159
|
};
|
|
265
|
-
|
|
160
|
+
CradovaEvent.addEventListener("cradovaAftermountEvent", av);
|
|
266
161
|
this.effector();
|
|
267
162
|
this.published = true;
|
|
268
163
|
this.rendered = true;
|
|
269
164
|
if (!element) {
|
|
270
165
|
element = this.preRendered;
|
|
271
166
|
}
|
|
167
|
+
this.reference._appendDomForce("reference", element);
|
|
272
168
|
return element;
|
|
273
169
|
}
|
|
274
170
|
instance() {
|
|
275
|
-
return
|
|
276
|
-
|
|
277
|
-
|
|
171
|
+
return this.reference.reference;
|
|
172
|
+
}
|
|
173
|
+
_setExtra(Extra) {
|
|
174
|
+
this.Signal = Extra;
|
|
278
175
|
}
|
|
279
176
|
effect(fn) {
|
|
280
177
|
if (!this.rendered) {
|
|
@@ -320,34 +217,38 @@ var Ref = class {
|
|
|
320
217
|
return;
|
|
321
218
|
}
|
|
322
219
|
this.published = false;
|
|
323
|
-
|
|
324
|
-
cradovaDispatchTrackBreak: true
|
|
325
|
-
});
|
|
326
|
-
if (!guy) {
|
|
220
|
+
if (!this.reference.reference) {
|
|
327
221
|
return;
|
|
328
222
|
}
|
|
329
223
|
const chtml = this.component(data2);
|
|
330
224
|
let element;
|
|
331
225
|
if (chtml instanceof HTMLElement) {
|
|
332
|
-
chtml.setAttribute("data-cra-id", this.stateID);
|
|
333
226
|
element = chtml;
|
|
334
227
|
} else {
|
|
335
|
-
element = chtml(
|
|
228
|
+
element = chtml();
|
|
229
|
+
}
|
|
230
|
+
if (!element) {
|
|
231
|
+
throw new Error(
|
|
232
|
+
" \u2718 Cradova err : Invalid component type for cradova Ref, got - " + element
|
|
233
|
+
);
|
|
336
234
|
}
|
|
337
235
|
try {
|
|
338
|
-
|
|
339
|
-
if (
|
|
340
|
-
|
|
236
|
+
this.reference.reference.insertAdjacentElement("beforebegin", element);
|
|
237
|
+
if (this.reference.reference.parentElement) {
|
|
238
|
+
this.reference.reference.parentElement.removeChild(
|
|
239
|
+
this.reference.reference
|
|
240
|
+
);
|
|
341
241
|
} else {
|
|
342
|
-
|
|
242
|
+
this.reference.reference.remove();
|
|
343
243
|
}
|
|
244
|
+
this.reference._appendDomForce("reference", element);
|
|
344
245
|
} catch (e0) {
|
|
345
246
|
console.error(e0);
|
|
346
247
|
}
|
|
347
248
|
this.published = true;
|
|
348
249
|
}
|
|
349
250
|
remove() {
|
|
350
|
-
|
|
251
|
+
this.reference.reference.remove();
|
|
351
252
|
}
|
|
352
253
|
};
|
|
353
254
|
var frag = function(children) {
|
|
@@ -368,10 +269,8 @@ var frag = function(children) {
|
|
|
368
269
|
par.appendChild(document.createTextNode(a2));
|
|
369
270
|
continue;
|
|
370
271
|
}
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
throw new TypeError(" \u2718 Cradova err: invalid element");
|
|
374
|
-
}
|
|
272
|
+
console.error(" \u2718 Cradova err: wrong element type" + a2);
|
|
273
|
+
throw new TypeError(" \u2718 Cradova err: invalid element");
|
|
375
274
|
}
|
|
376
275
|
return par;
|
|
377
276
|
};
|
|
@@ -410,6 +309,121 @@ var lazy = class {
|
|
|
410
309
|
this.content = this.content.default;
|
|
411
310
|
}
|
|
412
311
|
};
|
|
312
|
+
var reference = class {
|
|
313
|
+
bindAs(name) {
|
|
314
|
+
return [this, name];
|
|
315
|
+
}
|
|
316
|
+
_appendDom(name, Element) {
|
|
317
|
+
if (!Object.hasOwnProperty.call(this, name)) {
|
|
318
|
+
this[name] = Element;
|
|
319
|
+
} else {
|
|
320
|
+
if (Array.isArray(this[name])) {
|
|
321
|
+
this[name].push(Element);
|
|
322
|
+
} else {
|
|
323
|
+
this[name] = [this[name], Element];
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
_appendDomForce(name, Element) {
|
|
328
|
+
this[name] = Element;
|
|
329
|
+
}
|
|
330
|
+
};
|
|
331
|
+
|
|
332
|
+
// lib/utils/track.ts
|
|
333
|
+
function cradovaDispatchTrack(nodes, state) {
|
|
334
|
+
for (let i2 = 0; i2 < nodes.length; i2++) {
|
|
335
|
+
const element = nodes[i2];
|
|
336
|
+
if (!element) {
|
|
337
|
+
continue;
|
|
338
|
+
}
|
|
339
|
+
if (typeof state === "object" && !Array.isArray(state)) {
|
|
340
|
+
for (const key in state) {
|
|
341
|
+
if (key === "style") {
|
|
342
|
+
for (const [k, v] of Object.entries(state[key])) {
|
|
343
|
+
if (typeof element.style[k] !== "undefined" && k !== "src") {
|
|
344
|
+
element.style[k] = v;
|
|
345
|
+
} else {
|
|
346
|
+
throw new Error(
|
|
347
|
+
"\u2718 Cradova err : " + k + " is not a valid css style property"
|
|
348
|
+
);
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
continue;
|
|
352
|
+
}
|
|
353
|
+
if (typeof element[key] === "function") {
|
|
354
|
+
if (key.startsWith("on")) {
|
|
355
|
+
element[key] = state[key];
|
|
356
|
+
} else {
|
|
357
|
+
element[key].apply(element);
|
|
358
|
+
}
|
|
359
|
+
continue;
|
|
360
|
+
}
|
|
361
|
+
if (key === "text") {
|
|
362
|
+
element.innerText = state[key];
|
|
363
|
+
continue;
|
|
364
|
+
}
|
|
365
|
+
if (key === "tree") {
|
|
366
|
+
element.innerHTML = "";
|
|
367
|
+
element.appendChild(frag(state[key]));
|
|
368
|
+
continue;
|
|
369
|
+
}
|
|
370
|
+
try {
|
|
371
|
+
if (typeof element[key] !== "undefined") {
|
|
372
|
+
element[key] = state[key];
|
|
373
|
+
} else {
|
|
374
|
+
if (key.includes("data-")) {
|
|
375
|
+
element.setAttribute(key, state[key]);
|
|
376
|
+
continue;
|
|
377
|
+
} else {
|
|
378
|
+
element[key] = state[key];
|
|
379
|
+
}
|
|
380
|
+
if (key !== "for" && key !== "text" && key !== "class" && key !== "tabindex" && key !== "disabled" && !key.includes("aria")) {
|
|
381
|
+
console.error(" \u2718 Cradova err: invalid html attribute " + key);
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
} catch (error) {
|
|
385
|
+
console.error(" \u2718 Cradova err: Cradova got ", state);
|
|
386
|
+
console.error(" \u2718 Cradova err: ", error);
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
} else {
|
|
390
|
+
console.log(nodes, state);
|
|
391
|
+
throw new TypeError(" \u2718 Cradova err: invalid state object" + state);
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
function dispatch(stateID, state) {
|
|
396
|
+
if (stateID instanceof HTMLElement) {
|
|
397
|
+
cradovaDispatchTrack([stateID], state);
|
|
398
|
+
}
|
|
399
|
+
let ele;
|
|
400
|
+
let updated = void 0;
|
|
401
|
+
if (typeof state === "undefined" && typeof stateID === "object" && !ele) {
|
|
402
|
+
for (const [id, eachState] of Object.entries(stateID)) {
|
|
403
|
+
const elements = document.querySelectorAll(
|
|
404
|
+
"[data-cra-id=" + id + "]"
|
|
405
|
+
);
|
|
406
|
+
updated = elements.length === 1 ? elements[0] : elements;
|
|
407
|
+
cradovaDispatchTrack(elements, eachState);
|
|
408
|
+
}
|
|
409
|
+
} else {
|
|
410
|
+
if (typeof stateID === "string") {
|
|
411
|
+
const elements = document.querySelectorAll(
|
|
412
|
+
"[data-cra-id=" + stateID + "]"
|
|
413
|
+
);
|
|
414
|
+
if (elements.length) {
|
|
415
|
+
updated = elements.length === 1 ? elements[0] : elements;
|
|
416
|
+
if (!state?.cradovaDispatchTrackBreak) {
|
|
417
|
+
cradovaDispatchTrack(elements, state);
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
if (ele) {
|
|
422
|
+
cradovaDispatchTrack([ele], state);
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
return updated;
|
|
426
|
+
}
|
|
413
427
|
|
|
414
428
|
// lib/utils/createSignal.ts
|
|
415
429
|
var createSignal = class {
|
|
@@ -474,9 +488,9 @@ var createSignal = class {
|
|
|
474
488
|
this.actions[key] = action;
|
|
475
489
|
} else {
|
|
476
490
|
if (typeof key === "object" && !action) {
|
|
477
|
-
for (const [nam,
|
|
478
|
-
if (typeof nam === "string" && typeof
|
|
479
|
-
this.actions[nam] =
|
|
491
|
+
for (const [nam, act] of Object.entries(key)) {
|
|
492
|
+
if (typeof nam === "string" && typeof action === "function") {
|
|
493
|
+
this.actions[nam] = act;
|
|
480
494
|
} else {
|
|
481
495
|
throw new Error(`\u2718 Cradova err : can't create action ${nam}`);
|
|
482
496
|
}
|
|
@@ -487,14 +501,13 @@ var createSignal = class {
|
|
|
487
501
|
}
|
|
488
502
|
}
|
|
489
503
|
fireAction(key, data2) {
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
this.
|
|
504
|
+
this._updateState(key, data2);
|
|
505
|
+
if (this.actions[key] && this.actions[key].updateState) {
|
|
506
|
+
this.actions[key].updateState(data2);
|
|
493
507
|
return;
|
|
494
508
|
} else {
|
|
495
509
|
if (typeof this.actions[key] === "function") {
|
|
496
|
-
this.actions[key](this
|
|
497
|
-
this._updateState(key, data2);
|
|
510
|
+
this.actions[key].bind(this)(data2);
|
|
498
511
|
return;
|
|
499
512
|
}
|
|
500
513
|
}
|
|
@@ -550,13 +563,20 @@ var createSignal = class {
|
|
|
550
563
|
ent.ref.updateState(this.value[ent._signalProperty]);
|
|
551
564
|
continue;
|
|
552
565
|
}
|
|
566
|
+
if (!ent._element_property && !ent._signalProperty) {
|
|
567
|
+
ent.ref.updateState(this.value);
|
|
568
|
+
continue;
|
|
569
|
+
}
|
|
553
570
|
}
|
|
554
571
|
}
|
|
555
572
|
}
|
|
556
|
-
bindRef(ref, binding) {
|
|
573
|
+
bindRef(ref, binding = { signalProperty: "", _element_property: "" }) {
|
|
557
574
|
if (ref.render) {
|
|
558
575
|
ref.render = ref.render.bind(ref, this.value);
|
|
559
576
|
}
|
|
577
|
+
if (ref._setExtra) {
|
|
578
|
+
ref._setExtra(this);
|
|
579
|
+
}
|
|
560
580
|
if (ref && ref.updateState) {
|
|
561
581
|
this.ref.push({
|
|
562
582
|
ref,
|
|
@@ -591,6 +611,12 @@ RouterBox["pageHide"] = null;
|
|
|
591
611
|
RouterBox["errorHandler"] = null;
|
|
592
612
|
RouterBox["params"] = {};
|
|
593
613
|
RouterBox["routes"] = {};
|
|
614
|
+
RouterBox["pageevents"] = [];
|
|
615
|
+
RouterBox["start_pageevents"] = function(lastR, newR) {
|
|
616
|
+
for (let ci = 0; ci < RouterBox["pageevents"].length; ci++) {
|
|
617
|
+
RouterBox["pageevents"][ci](lastR, newR);
|
|
618
|
+
}
|
|
619
|
+
};
|
|
594
620
|
var checker = (url) => {
|
|
595
621
|
if (RouterBox.routes[url]) {
|
|
596
622
|
return [RouterBox.routes[url], { path: url }];
|
|
@@ -686,11 +712,12 @@ Router.navigate = function(href, data2 = null, force = false) {
|
|
|
686
712
|
force = true;
|
|
687
713
|
data2 = null;
|
|
688
714
|
}
|
|
689
|
-
let route = null, params
|
|
715
|
+
let route = null, params;
|
|
690
716
|
if (href.includes("://")) {
|
|
691
717
|
window.location.href = href;
|
|
692
718
|
} else {
|
|
693
|
-
|
|
719
|
+
const lastR = window.location.pathname;
|
|
720
|
+
if (href === lastR) {
|
|
694
721
|
return;
|
|
695
722
|
}
|
|
696
723
|
[route, params] = checker(href);
|
|
@@ -699,11 +726,10 @@ Router.navigate = function(href, data2 = null, force = false) {
|
|
|
699
726
|
RouterBox.params.params = params;
|
|
700
727
|
route._paramData = params;
|
|
701
728
|
RouterBox.params.data = data2 || null;
|
|
702
|
-
|
|
703
|
-
RouterBox["pageHide"] && RouterBox["pageHide"](href + " :navigated");
|
|
704
|
-
window.history.pushState({}, "", link2);
|
|
729
|
+
window.history.pushState({}, "", href);
|
|
705
730
|
}
|
|
706
731
|
RouterBox.router(null, force);
|
|
732
|
+
RouterBox["start_pageevents"](lastR, href);
|
|
707
733
|
}
|
|
708
734
|
};
|
|
709
735
|
RouterBox.router = async function(e, force = false) {
|
|
@@ -755,7 +781,6 @@ RouterBox.router = async function(e, force = false) {
|
|
|
755
781
|
RouterBox["lastNavigatedRouteController"] && RouterBox["lastNavigatedRouteController"]._deActivate();
|
|
756
782
|
RouterBox["lastNavigatedRoute"] = url;
|
|
757
783
|
RouterBox["lastNavigatedRouteController"] = route;
|
|
758
|
-
RouterBox["pageShow"] && RouterBox["pageShow"](url);
|
|
759
784
|
} catch (error) {
|
|
760
785
|
let errorHandler;
|
|
761
786
|
if (RouterBox.routes[RouterBox.params.params._path]) {
|
|
@@ -768,33 +793,18 @@ RouterBox.router = async function(e, force = false) {
|
|
|
768
793
|
} else {
|
|
769
794
|
if (RouterBox.routes["/404"]) {
|
|
770
795
|
RouterBox.routes["/404"].controller();
|
|
771
|
-
} else {
|
|
772
|
-
if (Object.keys(RouterBox.routes).length > 0) {
|
|
773
|
-
console.error(
|
|
774
|
-
" \u2718 Cradova err: route '" + url + "' does not exist and no '/404' route given!"
|
|
775
|
-
);
|
|
776
|
-
}
|
|
777
796
|
}
|
|
778
797
|
}
|
|
779
798
|
};
|
|
780
|
-
Router["
|
|
799
|
+
Router["onPageEvent"] = function(callback) {
|
|
781
800
|
if (typeof callback === "function") {
|
|
782
|
-
RouterBox["
|
|
801
|
+
RouterBox["pageevents"].push(callback);
|
|
783
802
|
} else {
|
|
784
803
|
throw new Error(
|
|
785
804
|
" \u2718 Cradova err: callback for pageShow event is not a function"
|
|
786
805
|
);
|
|
787
806
|
}
|
|
788
807
|
};
|
|
789
|
-
Router["onPageHide"] = function(callback) {
|
|
790
|
-
if (typeof callback === "function") {
|
|
791
|
-
RouterBox["pageHide"] = callback;
|
|
792
|
-
} else {
|
|
793
|
-
throw new Error(
|
|
794
|
-
" \u2718 Cradova err: callback for pageHide event is not a function"
|
|
795
|
-
);
|
|
796
|
-
}
|
|
797
|
-
};
|
|
798
808
|
Router.packageScreen = async function(path, data2 = {}) {
|
|
799
809
|
if (!RouterBox.routes[path]) {
|
|
800
810
|
console.error(" \u2718 Cradova err: no screen with path " + path);
|
|
@@ -827,13 +837,16 @@ Router.mount = () => {
|
|
|
827
837
|
});
|
|
828
838
|
};
|
|
829
839
|
|
|
830
|
-
// lib/utils/
|
|
840
|
+
// lib/utils/elements.ts
|
|
831
841
|
var makeElement = (element, ...ElementChildrenAndPropertyList) => {
|
|
832
842
|
let beforeMount = null;
|
|
833
843
|
let props = null, text = null;
|
|
834
844
|
if (ElementChildrenAndPropertyList.length) {
|
|
835
845
|
for (let i2 = 0; i2 < ElementChildrenAndPropertyList.length; i2++) {
|
|
836
846
|
let child = ElementChildrenAndPropertyList[i2];
|
|
847
|
+
if (child?.render) {
|
|
848
|
+
child = child.render();
|
|
849
|
+
}
|
|
837
850
|
if (typeof child === "function") {
|
|
838
851
|
child = child();
|
|
839
852
|
if (typeof child === "function") {
|
|
@@ -917,16 +930,21 @@ var makeElement = (element, ...ElementChildrenAndPropertyList) => {
|
|
|
917
930
|
});
|
|
918
931
|
continue;
|
|
919
932
|
}
|
|
933
|
+
if (prop == "reference" && Array.isArray(props[prop]) && props[prop][0] instanceof reference) {
|
|
934
|
+
element.updateState = dispatch.bind(null, element);
|
|
935
|
+
props[prop][0]._appendDom(props[prop][1], element);
|
|
936
|
+
continue;
|
|
937
|
+
}
|
|
920
938
|
if (prop === "shouldUpdate" && props[prop] === true) {
|
|
921
939
|
element.updateState = dispatch.bind(void 0, element);
|
|
922
940
|
continue;
|
|
923
941
|
}
|
|
924
942
|
if (prop === "afterMount" && typeof props["afterMount"] === "function") {
|
|
925
|
-
const
|
|
943
|
+
const avi = () => {
|
|
926
944
|
props["afterMount"].apply(element);
|
|
927
|
-
|
|
945
|
+
CradovaEvent.removeEventListener("cradovaAftermountEvent", avi);
|
|
928
946
|
};
|
|
929
|
-
|
|
947
|
+
CradovaEvent.addEventListener("cradovaAftermountEvent", avi);
|
|
930
948
|
continue;
|
|
931
949
|
}
|
|
932
950
|
try {
|
|
@@ -958,7 +976,7 @@ var makeElement = (element, ...ElementChildrenAndPropertyList) => {
|
|
|
958
976
|
if (typeof beforeMount === "function") {
|
|
959
977
|
beforeMount.apply(element);
|
|
960
978
|
}
|
|
961
|
-
if (element.tagName === "A") {
|
|
979
|
+
if (element.tagName === "A" && window) {
|
|
962
980
|
if (element.href.includes(window.location.origin)) {
|
|
963
981
|
element.addEventListener("click", (e) => {
|
|
964
982
|
e.preventDefault();
|
|
@@ -969,10 +987,10 @@ var makeElement = (element, ...ElementChildrenAndPropertyList) => {
|
|
|
969
987
|
return element;
|
|
970
988
|
};
|
|
971
989
|
var cra = (element_initials) => {
|
|
972
|
-
return (...
|
|
990
|
+
return (...initials) => {
|
|
973
991
|
return makeElement(
|
|
974
992
|
document.createElement(element_initials),
|
|
975
|
-
...
|
|
993
|
+
...initials
|
|
976
994
|
);
|
|
977
995
|
};
|
|
978
996
|
};
|
|
@@ -1160,12 +1178,6 @@ var Screen = class {
|
|
|
1160
1178
|
this._params = null;
|
|
1161
1179
|
this._delegatedRoutesCount = -1;
|
|
1162
1180
|
const { template: template2, name, persist, renderInParallel, transition } = cradova_screen_initials;
|
|
1163
|
-
if (typeof template2 !== "function") {
|
|
1164
|
-
console.error(" \u2718 Cradova err: expected a screen but got ", template2);
|
|
1165
|
-
throw new Error(
|
|
1166
|
-
" \u2718 Cradova err: only functions that returns a cradova element is valid as screen"
|
|
1167
|
-
);
|
|
1168
|
-
}
|
|
1169
1181
|
this._html = template2;
|
|
1170
1182
|
this._name = name;
|
|
1171
1183
|
this._transition = transition || "";
|
|
@@ -1201,6 +1213,10 @@ var Screen = class {
|
|
|
1201
1213
|
this.errorHandler = errorHandler;
|
|
1202
1214
|
}
|
|
1203
1215
|
async _package() {
|
|
1216
|
+
if (this._html.render) {
|
|
1217
|
+
this._template.innerHTML = "";
|
|
1218
|
+
this._template.appendChild(this._html.render(this._data));
|
|
1219
|
+
}
|
|
1204
1220
|
if (typeof this._html === "function") {
|
|
1205
1221
|
let fuc = await this._html.apply(this, this._data);
|
|
1206
1222
|
if (typeof fuc === "function") {
|
|
@@ -1227,8 +1243,9 @@ var Screen = class {
|
|
|
1227
1243
|
}
|
|
1228
1244
|
}
|
|
1229
1245
|
if (!this._template.firstChild) {
|
|
1246
|
+
console.error(" \u2718 Cradova err: expected a screen but got ", this._html);
|
|
1230
1247
|
throw new Error(
|
|
1231
|
-
" \u2718 Cradova err:
|
|
1248
|
+
" \u2718 Cradova err: only functions that returns a cradova element is valid as screen"
|
|
1232
1249
|
);
|
|
1233
1250
|
}
|
|
1234
1251
|
if (this._secondaryChildren.length) {
|
|
@@ -1265,10 +1282,10 @@ var Screen = class {
|
|
|
1265
1282
|
await this._package();
|
|
1266
1283
|
}
|
|
1267
1284
|
}
|
|
1268
|
-
const doc = document.querySelector("[data-
|
|
1285
|
+
const doc = document.querySelector("[data-wrapper=app]");
|
|
1269
1286
|
if (!doc) {
|
|
1270
1287
|
throw new Error(
|
|
1271
|
-
" \u2718 Cradova err: Unable to render, cannot find cradova root <div data-
|
|
1288
|
+
" \u2718 Cradova err: Unable to render, cannot find cradova root <div data-wrapper='app'> ... </div>"
|
|
1272
1289
|
);
|
|
1273
1290
|
}
|
|
1274
1291
|
if (this._transition) {
|
|
@@ -1280,8 +1297,10 @@ var Screen = class {
|
|
|
1280
1297
|
if (this._callBack) {
|
|
1281
1298
|
await this._callBack();
|
|
1282
1299
|
}
|
|
1283
|
-
|
|
1284
|
-
window
|
|
1300
|
+
CradovaEvent.dispatchEvent("cradovaAftermountEvent");
|
|
1301
|
+
if (window) {
|
|
1302
|
+
window.scrollTo(0, 0);
|
|
1303
|
+
}
|
|
1285
1304
|
}
|
|
1286
1305
|
};
|
|
1287
1306
|
|
|
@@ -1344,9 +1363,6 @@ var make = function(txx) {
|
|
|
1344
1363
|
return [tag || "DIV", IDs[0], classes.join(" "), innerValue];
|
|
1345
1364
|
};
|
|
1346
1365
|
var _2 = (...element_initials) => {
|
|
1347
|
-
if (typeof element_initials[0] !== "string") {
|
|
1348
|
-
return frag(element_initials);
|
|
1349
|
-
}
|
|
1350
1366
|
const initials = make(element_initials.shift());
|
|
1351
1367
|
let props = void 0;
|
|
1352
1368
|
let element;
|
|
@@ -1382,6 +1398,7 @@ Init();
|
|
|
1382
1398
|
var lib_default = _2;
|
|
1383
1399
|
export {
|
|
1384
1400
|
Ajax,
|
|
1401
|
+
CradovaEvent,
|
|
1385
1402
|
Ref,
|
|
1386
1403
|
Router,
|
|
1387
1404
|
Screen,
|
|
@@ -1408,7 +1425,6 @@ export {
|
|
|
1408
1425
|
code,
|
|
1409
1426
|
col,
|
|
1410
1427
|
colgroup,
|
|
1411
|
-
cradovaAftermountEvent,
|
|
1412
1428
|
createSignal,
|
|
1413
1429
|
css,
|
|
1414
1430
|
data,
|
|
@@ -1472,6 +1488,7 @@ export {
|
|
|
1472
1488
|
pre,
|
|
1473
1489
|
progress,
|
|
1474
1490
|
q,
|
|
1491
|
+
reference,
|
|
1475
1492
|
rp,
|
|
1476
1493
|
rt,
|
|
1477
1494
|
ruby,
|