clapton 0.0.19 → 0.0.21

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,584 @@
1
+ const htmlAttributes = (params) => {
2
+ const customDataAttributes = params.data || {};
3
+ const others = Object.keys(params).filter(key => key !== "data");
4
+ const flattenDataAttributes = (data, prefix = "data") => {
5
+ return Object.keys(data).reduce((acc, key) => {
6
+ const value = data[key];
7
+ if (typeof value === "object" && value !== null) {
8
+ acc.push(...flattenDataAttributes(value, `${prefix}-${key}`));
9
+ }
10
+ else {
11
+ acc.push(`${prefix}-${key}='${escapeHtml(value)}'`);
12
+ }
13
+ return acc;
14
+ }, []);
15
+ };
16
+ return [
17
+ others.map(key => {
18
+ if (key === "disabled") {
19
+ if (params[key] === false) {
20
+ return "";
21
+ }
22
+ else {
23
+ return `${key}`;
24
+ }
25
+ }
26
+ return `${key}='${escapeHtml(params[key])}'`;
27
+ }).join(" "),
28
+ flattenDataAttributes(customDataAttributes).join(" ")
29
+ ].filter(Boolean).join(" ");
30
+ };
31
+ const escapeHtml = (unsafe) => {
32
+ if (typeof unsafe !== "string") {
33
+ return "";
34
+ }
35
+ return unsafe
36
+ .replace(/&/g, "&")
37
+ .replace(/</g, "&lt;")
38
+ .replace(/>/g, "&gt;")
39
+ .replace(/"/g, "&quot;")
40
+ .replace(/'/g, "&#039;");
41
+ };
42
+
43
+ class BlockQuote {
44
+ constructor(attributes = {}) {
45
+ this.children = [];
46
+ this.attributes = attributes;
47
+ }
48
+ get renderWrapper() {
49
+ return `<blockquote ${htmlAttributes(this.attributes)}>${this.children.map(child => child.renderWrapper).join("")}</blockquote>`;
50
+ }
51
+ add(child) {
52
+ this.children.push(child);
53
+ return this;
54
+ }
55
+ }
56
+
57
+ class Box {
58
+ constructor(attributes = {}) {
59
+ this.children = [];
60
+ this.attributes = attributes;
61
+ }
62
+ add(child) {
63
+ this.children.push(child);
64
+ return this;
65
+ }
66
+ get renderWrapper() {
67
+ return `<div ${htmlAttributes(this.attributes)}>${this.children.map(child => child.renderWrapper).join("")}</div>`;
68
+ }
69
+ add_action(eventType, stateName, fnName, options = {}) {
70
+ this.attributes["data-action"] = `${this.attributes["data-action"] || ""} ${eventType}->${stateName}#${fnName}@${options.debounce || 0}`;
71
+ return this;
72
+ }
73
+ }
74
+
75
+ class Button {
76
+ constructor(attributes = {}) {
77
+ this.attributes = attributes;
78
+ this.children = [];
79
+ }
80
+ add(child) {
81
+ this.children.push(child);
82
+ return this;
83
+ }
84
+ get renderWrapper() {
85
+ return `<button ${htmlAttributes(this.attributes)}>${this.children.map(child => child.renderWrapper).join("")}</button>`;
86
+ }
87
+ add_action(event, klass, fn, options = {}) {
88
+ this.attributes["data-action"] = `${this.attributes["data-action"] || ""} ${event}->${klass}#${fn}@${options.debounce || 0}`;
89
+ return this;
90
+ }
91
+ }
92
+
93
+ class Bold {
94
+ constructor(attributes = {}) {
95
+ this.children = [];
96
+ this.attributes = attributes;
97
+ }
98
+ get renderWrapper() {
99
+ return `<strong ${htmlAttributes(this.attributes)}>${this.children.map(child => child.renderWrapper).join("")}</strong>`;
100
+ }
101
+ add(child) {
102
+ this.children.push(child);
103
+ return this;
104
+ }
105
+ }
106
+
107
+ class Checkbox {
108
+ constructor(state, attribute, attributes = {}) {
109
+ this.state = state;
110
+ this.attributes = attributes;
111
+ this.attribute = attribute;
112
+ this.attributes["data-attribute"] = attribute;
113
+ }
114
+ get renderWrapper() {
115
+ return `<input type='checkbox' ${htmlAttributes(this.attributes)} value='${this.state[this.attribute] || ""}'/>`;
116
+ }
117
+ add_action(event, klass, fn, options = {}) {
118
+ this.attributes["data-action"] = `${this.attributes["data-action"] || ""} ${event}->${klass}#${fn}@${options.debounce || 0}`;
119
+ return this;
120
+ }
121
+ }
122
+
123
+ class Code {
124
+ constructor(attributes = {}) {
125
+ this.children = [];
126
+ this.attributes = attributes;
127
+ }
128
+ get renderWrapper() {
129
+ return `<code ${htmlAttributes(this.attributes)}>${this.children.map(child => child.renderWrapper).join("")}</code>`;
130
+ }
131
+ add(child) {
132
+ this.children.push(child);
133
+ return this;
134
+ }
135
+ }
136
+
137
+ class DateTimeField {
138
+ constructor(state, attribute, attributes = {}) {
139
+ this.attributes = {};
140
+ this.state = state;
141
+ this.attribute = attribute;
142
+ this.attributes = attributes;
143
+ this.attributes["data-attribute"] = attribute;
144
+ }
145
+ get renderWrapper() {
146
+ const value = this.state[this.attribute] ? this.datetime_local_value(this.state[this.attribute]) : "";
147
+ return `<input type='datetime-local' ${htmlAttributes(this.attributes)} value='${value}'/>`;
148
+ }
149
+ add_action(event, klass, fn, options = {}) {
150
+ this.attributes["data-action"] = `${this.attributes["data-action"] || ""} ${event}->${klass}#${fn}@${options.debounce || 0}`;
151
+ return this;
152
+ }
153
+ datetime_local_value(value) {
154
+ if (!value) {
155
+ return "";
156
+ }
157
+ const date = new Date(value);
158
+ date.setMinutes(date.getMinutes() - date.getTimezoneOffset());
159
+ let month = date.getMonth() + 1;
160
+ let day = date.getDate();
161
+ let hours = date.getHours();
162
+ let minutes = date.getMinutes();
163
+ if (month < 10) {
164
+ month = `0${month}`;
165
+ }
166
+ if (day < 10) {
167
+ day = `0${day}`;
168
+ }
169
+ if (hours < 10) {
170
+ hours = `0${hours}`;
171
+ }
172
+ if (minutes < 10) {
173
+ minutes = `0${minutes}`;
174
+ }
175
+ return `${date.getFullYear()}-${month}-${day}T${hours}:${minutes}`;
176
+ }
177
+ }
178
+
179
+ class Element {
180
+ constructor(type, attributes = {}) {
181
+ this.children = [];
182
+ this.type = type;
183
+ this.attributes = attributes;
184
+ }
185
+ get renderWrapper() {
186
+ return `<${this.type} ${htmlAttributes(this.attributes)}>${this.children.map(child => child.renderWrapper).join("")}</${this.type}>`;
187
+ }
188
+ add(child) {
189
+ this.children.push(child);
190
+ return this;
191
+ }
192
+ }
193
+
194
+ class Embed {
195
+ constructor(html) {
196
+ this.html = html;
197
+ }
198
+ get renderWrapper() {
199
+ return this.html;
200
+ }
201
+ }
202
+
203
+ class Emphasis {
204
+ constructor(attributes = {}) {
205
+ this.children = [];
206
+ this.attributes = attributes;
207
+ }
208
+ get renderWrapper() {
209
+ return `<em ${htmlAttributes(this.attributes)}>${this.children.map(child => child.renderWrapper).join("")}</em>`;
210
+ }
211
+ add(child) {
212
+ this.children.push(child);
213
+ return this;
214
+ }
215
+ }
216
+
217
+ class Form {
218
+ constructor(attributes = {}) {
219
+ this.children = [];
220
+ this.attributes = attributes;
221
+ }
222
+ get renderWrapper() {
223
+ return `<form ${htmlAttributes(this.attributes)}>${this.children.map(child => child.renderWrapper).join("")}</form>`;
224
+ }
225
+ add(child) {
226
+ this.children.push(child);
227
+ return this;
228
+ }
229
+ }
230
+
231
+ class Heading {
232
+ constructor(level, attributes = {}) {
233
+ this.children = [];
234
+ this.level = level;
235
+ this.attributes = attributes;
236
+ }
237
+ get renderWrapper() {
238
+ return `<h${this.level} ${htmlAttributes(this.attributes)}>${this.children.map(child => child.renderWrapper).join("")}</h${this.level}>`;
239
+ }
240
+ add(child) {
241
+ this.children.push(child);
242
+ return this;
243
+ }
244
+ }
245
+
246
+ class Image {
247
+ constructor(src, alt, attributes = {}) {
248
+ this.children = [];
249
+ this.attributes = attributes;
250
+ this.src = src;
251
+ this.alt = alt;
252
+ }
253
+ get renderWrapper() {
254
+ return `<img src='${this.src}' alt='${this.alt}' ${htmlAttributes(this.attributes)}/>`;
255
+ }
256
+ }
257
+
258
+ class Link {
259
+ constructor(href, attributes = {}) {
260
+ this.children = [];
261
+ this.attributes = attributes;
262
+ this.href = href;
263
+ }
264
+ get renderWrapper() {
265
+ return `<a href='${this.href}' ${htmlAttributes(this.attributes)}>${this.children.map(child => child.renderWrapper).join("")}</a>`;
266
+ }
267
+ add(child) {
268
+ this.children.push(child);
269
+ return this;
270
+ }
271
+ }
272
+
273
+ class ListItem {
274
+ constructor(attributes = {}) {
275
+ this.children = [];
276
+ this.attributes = attributes;
277
+ }
278
+ add(child) {
279
+ this.children.push(child);
280
+ return this;
281
+ }
282
+ get renderWrapper() {
283
+ return `<li ${htmlAttributes(this.attributes)}>${this.children.map(child => child.renderWrapper).join("")}</li>`;
284
+ }
285
+ }
286
+
287
+ class List {
288
+ constructor(attributes = {}) {
289
+ this.children = [];
290
+ this.attributes = attributes;
291
+ }
292
+ add(child) {
293
+ this.children.push(child);
294
+ return this;
295
+ }
296
+ get renderWrapper() {
297
+ return `<ul ${htmlAttributes(this.attributes)}>${this.children.map(child => child.renderWrapper).join("")}</ul>`;
298
+ }
299
+ }
300
+
301
+ class OrderedList {
302
+ constructor(attributes = {}) {
303
+ this.children = [];
304
+ this.attributes = attributes;
305
+ }
306
+ add(child) {
307
+ this.children.push(child);
308
+ return this;
309
+ }
310
+ get renderWrapper() {
311
+ return `<ol ${htmlAttributes(this.attributes)}>${this.children.map(child => child.renderWrapper).join("")}</ol>`;
312
+ }
313
+ }
314
+
315
+ class Paragraph {
316
+ constructor(attributes = {}) {
317
+ this.children = [];
318
+ this.attributes = attributes;
319
+ }
320
+ get renderWrapper() {
321
+ return `<p ${htmlAttributes(this.attributes)}>${this.children.map(child => child.renderWrapper).join("")}</p>`;
322
+ }
323
+ add(child) {
324
+ this.children.push(child);
325
+ return this;
326
+ }
327
+ }
328
+
329
+ class Quote {
330
+ constructor(attributes = {}) {
331
+ this.children = [];
332
+ this.attributes = attributes;
333
+ }
334
+ get renderWrapper() {
335
+ return `<q ${htmlAttributes(this.attributes)}>${this.children.map(child => child.renderWrapper).join("")}</q>`;
336
+ }
337
+ add(child) {
338
+ this.children.push(child);
339
+ return this;
340
+ }
341
+ }
342
+
343
+ class RadioButton {
344
+ constructor(state, attribute, attributes = {}) {
345
+ this.state = state;
346
+ this.attributes = attributes;
347
+ this.attribute = attribute;
348
+ this.attributes["data-attribute"] = attribute;
349
+ }
350
+ get renderWrapper() {
351
+ return `<input type='radio' ${htmlAttributes(this.attributes)} value='${this.state[this.attribute] || ""}'/>`;
352
+ }
353
+ add_action(event, klass, fn, options = {}) {
354
+ this.attributes["data-action"] = `${this.attributes["data-action"] || ""} ${event}->${klass}#${fn}@${options.debounce || 0}`;
355
+ return this;
356
+ }
357
+ }
358
+
359
+ class Select {
360
+ constructor(options = [], state, attribute, attributes = {}) {
361
+ this.children = [];
362
+ this.options = options;
363
+ this.state = state;
364
+ this.attribute = attribute;
365
+ this.attributes = attributes;
366
+ }
367
+ get renderWrapper() {
368
+ return `<select ${htmlAttributes(this.attributes)}>${this.options.map(option => `<option value='${option.value}'${option.value === this.state[this.attribute] ? " selected" : ""}>${option.text}</option>`).join("")}${this.children.map(child => child.renderWrapper).join("")}</select>`;
369
+ }
370
+ }
371
+
372
+ class Span {
373
+ constructor(attributes = {}) {
374
+ this.children = [];
375
+ this.attributes = attributes;
376
+ }
377
+ get renderWrapper() {
378
+ return `<span ${htmlAttributes(this.attributes)}>${this.children.map(child => child.renderWrapper).join("")}</span>`;
379
+ }
380
+ add(child) {
381
+ this.children.push(child);
382
+ return this;
383
+ }
384
+ }
385
+
386
+ class Component {
387
+ constructor(state = {}, id = Math.random().toString(36).substring(2, 10), errors = []) {
388
+ this._state = state;
389
+ this.id = id;
390
+ this._errors = errors;
391
+ }
392
+ get render() {
393
+ return new Box({});
394
+ }
395
+ get renderWrapper() {
396
+ const root = this.render;
397
+ if (root.attributes) {
398
+ root.attributes = { ...root.attributes, data: { ...root.attributes.data, component: this.constructor.name, state: JSON.stringify(this._state), id: this.id, errors: this._errors } };
399
+ }
400
+ else {
401
+ root.attributes = { data: { component: this.constructor.name, state: JSON.stringify(this._state), id: this.id, errors: this._errors } };
402
+ }
403
+ return root.renderWrapper;
404
+ }
405
+ }
406
+
407
+ class TextField {
408
+ constructor(state, attribute, attributes = {}) {
409
+ this.state = state;
410
+ this.attributes = attributes;
411
+ this.attribute = attribute;
412
+ this.attributes["data-attribute"] = attribute;
413
+ }
414
+ get renderWrapper() {
415
+ return `<input type='text' ${htmlAttributes(this.attributes)} value='${this.state[this.attribute] || ""}'/>`;
416
+ }
417
+ add_action(event, klass, fn, options = {}) {
418
+ this.attributes["data-action"] = `${this.attributes["data-action"] || ""} ${event}->${klass}#${fn}@${options.debounce || 0}`;
419
+ return this;
420
+ }
421
+ }
422
+
423
+ class Text {
424
+ constructor(value) {
425
+ this.value = value;
426
+ }
427
+ get renderWrapper() {
428
+ return this.value;
429
+ }
430
+ }
431
+
432
+ class TextArea {
433
+ constructor(state, attribute, attributes = {}) {
434
+ this.state = state;
435
+ this.attributes = attributes;
436
+ this.attribute = attribute;
437
+ this.attributes["data-attribute"] = attribute;
438
+ }
439
+ get renderWrapper() {
440
+ return `<textarea ${htmlAttributes(this.attributes)}>${this.state[this.attribute] || ""}</textarea>`;
441
+ }
442
+ add_action(event, klass, fn, options = {}) {
443
+ this.attributes["data-action"] = `${this.attributes["data-action"] || ""} ${event}->${klass}#${fn}@${options.debounce || 0}`;
444
+ return this;
445
+ }
446
+ }
447
+
448
+ const Clapton = {
449
+ Box, Component, Text, TextField, Button, DateTimeField, BlockQuote, Checkbox, Code, Element, Emphasis, Form, Heading, Image, Link, List, ListItem, OrderedList, Paragraph, Quote, RadioButton, Select, Span, Embed, Bold, TextArea
450
+ };
451
+
452
+ const bq = (...props) => {
453
+ return new Clapton.BlockQuote(...props);
454
+ };
455
+ const box = (...props) => {
456
+ return new Clapton.Box(...props);
457
+ };
458
+ const b = (...props) => {
459
+ return new Clapton.Bold(...props);
460
+ };
461
+ const button = (...props) => {
462
+ return new Clapton.Button(...props);
463
+ };
464
+ const check = (...props) => {
465
+ return new Clapton.Checkbox(props[0], props[1], props[2]);
466
+ };
467
+ const code = (...props) => {
468
+ return new Clapton.Code(...props);
469
+ };
470
+ const datetime = (...props) => {
471
+ return new Clapton.DateTimeField(props[0], props[1], props[2]);
472
+ };
473
+ const el = (...props) => {
474
+ return new Clapton.Element(props[0], props[1]);
475
+ };
476
+ const embed = (...props) => {
477
+ return new Clapton.Embed(props[0]);
478
+ };
479
+ const em = (...props) => {
480
+ return new Clapton.Emphasis(...props);
481
+ };
482
+ const form = (...props) => {
483
+ return new Clapton.Form(...props);
484
+ };
485
+ const h = (...props) => {
486
+ return new Clapton.Heading(props[0], props[1]);
487
+ };
488
+ const img = (...props) => {
489
+ return new Clapton.Image(props[0], props[1], props[2]);
490
+ };
491
+ const a = (...props) => {
492
+ return new Clapton.Link(props[0], props[1]);
493
+ };
494
+ const li = (...props) => {
495
+ return new Clapton.ListItem(...props);
496
+ };
497
+ const ul = (...props) => {
498
+ return new Clapton.List(...props);
499
+ };
500
+ const ol = (...props) => {
501
+ return new Clapton.OrderedList(...props);
502
+ };
503
+ const p = (...props) => {
504
+ return new Clapton.Paragraph(...props);
505
+ };
506
+ const q = (...props) => {
507
+ return new Clapton.Quote(...props);
508
+ };
509
+ const radio = (...props) => {
510
+ return new Clapton.RadioButton(props[0], props[1], props[2]);
511
+ };
512
+ const select = (...props) => {
513
+ return new Clapton.Select(props[0], props[1], props[2]);
514
+ };
515
+ const span = (...props) => {
516
+ return new Clapton.Span(...props);
517
+ };
518
+ const textarea = (...props) => {
519
+ return new Clapton.TextArea(props[0], props[1], props[2]);
520
+ };
521
+ const input = (...props) => {
522
+ return new Clapton.TextField(props[0], props[1], props[2]);
523
+ };
524
+ const text = (...props) => {
525
+ return new Clapton.Text(props[0]);
526
+ };
527
+ const c = (name, ...props) => {
528
+ switch (name) {
529
+ case "bq":
530
+ return bq(...props);
531
+ case "box":
532
+ return box(...props);
533
+ case "b":
534
+ return b(...props);
535
+ case "button":
536
+ return button(...props);
537
+ case "check":
538
+ return check(...props);
539
+ case "code":
540
+ return code(...props);
541
+ case "datetime":
542
+ return datetime(...props);
543
+ case "el":
544
+ return el(...props);
545
+ case "embed":
546
+ return embed(...props);
547
+ case "em":
548
+ return em(...props);
549
+ case "form":
550
+ return form(...props);
551
+ case "h":
552
+ return h(...props);
553
+ case "img":
554
+ return img(...props);
555
+ case "a":
556
+ return a(...props);
557
+ case "li":
558
+ return li(...props);
559
+ case "ul":
560
+ return ul(...props);
561
+ case "ol":
562
+ return ol(...props);
563
+ case "p":
564
+ return p(...props);
565
+ case "q":
566
+ return q(...props);
567
+ case "radio":
568
+ return radio(...props);
569
+ case "select":
570
+ return select(...props);
571
+ case "span":
572
+ return span(...props);
573
+ case "textarea":
574
+ return textarea(...props);
575
+ case "input":
576
+ return input(...props);
577
+ case "text":
578
+ return text(...props);
579
+ default:
580
+ return new Clapton.Component(...props);
581
+ }
582
+ };
583
+
584
+ export { c };
@@ -1448,3 +1448,12 @@ document.addEventListener("DOMContentLoaded", async () => {
1448
1448
  const event = new Event('clapton:render');
1449
1449
  document.dispatchEvent(event);
1450
1450
  });
1451
+ window.addEventListener('beforeunload', () => {
1452
+ sessionStorage.setItem('scrollPosition', window.scrollY.toString());
1453
+ });
1454
+ document.addEventListener("clapton:render", () => {
1455
+ const scrollPosition = sessionStorage.getItem('scrollPosition');
1456
+ if (scrollPosition) {
1457
+ window.scrollTo(0, parseInt(scrollPosition));
1458
+ }
1459
+ });